PartDesign: Body rework - add BaseFeature property and make Tip always point to solid

This commit is contained in:
Alexander Golubev
2015-08-06 20:46:26 +03:00
committed by Stefan Tröger
parent 37320a0bfa
commit 8c5d514b18
17 changed files with 470 additions and 416 deletions

View File

@@ -39,28 +39,15 @@ PROPERTY_SOURCE(Part::BodyBase, Part::Feature)
BodyBase::BodyBase()
{
ADD_PROPERTY(Model,(0));
ADD_PROPERTY(Tip ,(0));
}
short BodyBase::mustExecute() const
{
//if (Sketch.isTouched() ||
// Length.isTouched())
// return 1;
return 0;
}
App::DocumentObjectExecReturn *BodyBase::execute(void)
{
return App::DocumentObject::StdReturn;
ADD_PROPERTY(Model , (0) );
ADD_PROPERTY(Tip , (0) );
ADD_PROPERTY(BaseFeature , (0) );
}
const bool BodyBase::hasFeature(const App::DocumentObject* f) const
{
const std::vector<App::DocumentObject*> features = Model.getValues();
return std::find(features.begin(), features.end(), f) != features.end();
const std::vector<App::DocumentObject*> &features = Model.getValues();
return f == BaseFeature.getValue() || std::find(features.begin(), features.end(), f) != features.end();
}
BodyBase* BodyBase::findBodyOf(const App::DocumentObject* f)
@@ -78,15 +65,42 @@ BodyBase* BodyBase::findBodyOf(const App::DocumentObject* f)
return NULL;
}
const bool BodyBase::isAfterTip(const App::DocumentObject *f) const {
App::DocumentObject* tipFeature = Tip.getValue();
if (tipFeature == NULL)
return true;
const bool BodyBase::isAfter(const App::DocumentObject *feature, const App::DocumentObject* target) const {
assert (feature);
std::vector<App::DocumentObject*> features = Model.getValues();
std::vector<App::DocumentObject*>::const_iterator it = std::find(features.begin(), features.end(), f);
std::vector<App::DocumentObject*>::const_iterator tip = std::find(features.begin(), features.end(), tipFeature);
return (it > tip);
if (feature == target) {
return false;
}
if (!target || target == BaseFeature.getValue() ) {
return hasFeature (feature);
}
const std::vector<App::DocumentObject *> & features = Model.getValues();
auto featureIt = std::find(features.begin(), features.end(), feature);
auto targetIt = std::find(features.begin(), features.end(), target);
if (featureIt == features.end()) {
return false;
} else {
return featureIt > targetIt;
}
}
void BodyBase::onBeforeChange (const App::Property* prop) {
// If we are changing the base feature and tip point to it reset it
if ( prop == &BaseFeature && BaseFeature.getValue() == Tip.getValue() && BaseFeature.getValue() ) {
Tip.setValue( nullptr );
}
Part::Feature::onBeforeChange ( prop );
}
void BodyBase::onChanged (const App::Property* prop) {
// If the tip is zero and we are adding a base feature to the body set it to be the tip
if ( prop == &BaseFeature && !Tip.getValue() && BaseFeature.getValue() ) {
Tip.setValue( BaseFeature.getValue () );
}
Part::Feature::onChanged ( prop );
}
} /* Part */

View File

@@ -31,11 +31,11 @@
namespace Part
{
/** Base class of all body objects in FreeCAD
* A body is used, e.g. in PartDesign, to agregate
* some modeling features to one shape. As long as not
* in edit or active on a workbench, the body shows only the
* resulting shape to the outside (Tip link).
*/
* A body is used, e.g. in PartDesign, to agregate
* some modeling features to one shape. As long as not
* in edit or active on a workbench, the body shows only the
* resulting shape to the outside (Tip link).
*/
class PartExport BodyBase : public Part::Feature
{
PROPERTY_HEADER(Part::BodyBase);
@@ -43,41 +43,47 @@ class PartExport BodyBase : public Part::Feature
public:
BodyBase();
/// The list of features
App::PropertyLinkList Model;
/**
* The final feature of the body it is associated with.
* Note: tip may either point to the BaseFeature or to some feature inside the Model list.
* in case it points to the model the PartDesign::Body guaranties that it is a solid.
*/
App::PropertyLink Tip;
/** @name methods override feature */
//@{
/// recalculate the feature
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
/// returns the type name of the view provider
//const char* getViewProviderName(void) const {
// return "PartDesignGui::ViewProviderBodyBase";
//}
//@}
/**
* A base object of the body, serves as a base object for the first feature of the body.
* A Part::Feature link to make bodies be able based upon non-PartDesign Features.
*/
App::PropertyLink BaseFeature;
// These methods are located here to avoid a dependency of ViewProviderSketchObject on PartDesign
/// Remove the feature from the body
virtual void removeFeature(App::DocumentObject* feature){}
/// Return true if the feature belongs to this body
/// Return true if the feature belongs to this body or either the body is based on the feature
const bool hasFeature(const App::DocumentObject *f) const;
/// Return true if the feature belongs to the body and is located after the target
const bool isAfter(const App::DocumentObject *feature, const App::DocumentObject *target) const;
/**
* Return the solid feature before the given feature, or before the Tip feature
* That is, sketches and datum features are skipped
* If inclusive is true, start or the Tip is returned if it is a solid feature
*/
virtual App::DocumentObject *getPrevSolidFeature(App::DocumentObject *start = NULL, const bool inclusive = true)
{ return NULL; }
/// Return true if the feature is located after the current Tip feature
const bool isAfterTip(const App::DocumentObject *f) const;
/// Return the body which this feature belongs too, or NULL
* Return the body which this feature belongs too, or NULL.
* Note: Normally each PartDesign feature belongs to a single body,
* But if a body is based on the feature it also will be return...
* But there are could be more features based on the same body.
* TODO introduce a findBodiesOf() if needed (2015-08-04, Fat-Zer)
*/
static BodyBase* findBodyOf(const App::DocumentObject* f);
protected:
/// If BaseFeature is getting changed and Tip points to it resets the Tip
virtual void onBeforeChange (const App::Property* prop);
/// If BaseFeature is setted and Tip is null sets the Tip to it
virtual void onChanged (const App::Property* prop);
};
} //namespace Part

View File

@@ -71,7 +71,7 @@ public:
TopLoc_Location getLocation() const;
protected:
void onChanged(const App::Property* prop);
virtual void onChanged(const App::Property* prop);
/**
* Build a history of changes
* MakeShape: The operation that created the changes, e.g. BRepAlgoAPI_Common

View File

@@ -127,17 +127,15 @@ bool ViewProviderPart::doubleClicked(void)
bool ViewProviderPart::onDelete(const std::vector<std::string> &)
{
// TODO Why the heck it's here? (2015-08-05, Fat-Zer)
// Body feature housekeeping
Part::BodyBase* body = Part::BodyBase::findBodyOf(getObject());
if (body != NULL) {
body->removeFeature(getObject());
// Make the new Tip and the previous solid feature visible again
App::DocumentObject* tip = body->Tip.getValue();
App::DocumentObject* prev = body->getPrevSolidFeature();
if (tip != NULL) {
Gui::Application::Instance->getViewProvider(tip)->show();
if ((tip != prev) && (prev != NULL))
Gui::Application::Instance->getViewProvider(prev)->show();
}
}