PartDesign: Body rework - add BaseFeature property and make Tip always point to solid
This commit is contained in:
committed by
Stefan Tröger
parent
37320a0bfa
commit
8c5d514b18
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user