diff --git a/src/Mod/PartDesign/App/Feature.cpp b/src/Mod/PartDesign/App/Feature.cpp index fe589b6a4..80b210626 100644 --- a/src/Mod/PartDesign/App/Feature.cpp +++ b/src/Mod/PartDesign/App/Feature.cpp @@ -91,15 +91,26 @@ const gp_Pnt Feature::getPointFromFace(const TopoDS_Face& f) throw Base::Exception("getPointFromFace(): Not implemented yet for this case"); } -Part::Feature* Feature::getBaseObject() const { +Part::Feature* Feature::getBaseObject(bool silent) const { App::DocumentObject* BaseLink = BaseFeature.getValue(); - if (BaseLink == NULL) throw Base::Exception("Base property not set"); - Part::Feature* BaseObject = NULL; - if (BaseLink->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) - BaseObject = static_cast(BaseLink); + Part::Feature* BaseObject = nullptr; + const char *err = nullptr; - if (BaseObject == NULL) - throw Base::Exception("No base feature linked"); + if (BaseLink) { + if (BaseLink->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { + BaseObject = static_cast(BaseLink); + } + if (!BaseObject) { + err = "No base feature linked"; + } + } else { + err = "Base property not set"; + } + + // If the funtion not in silent mode throw the exception discribing the error + if (!silent && err) { + throw Base::Exception(err); + } return BaseObject; } diff --git a/src/Mod/PartDesign/App/Feature.h b/src/Mod/PartDesign/App/Feature.h index c9723389b..c43bcb6d5 100644 --- a/src/Mod/PartDesign/App/Feature.h +++ b/src/Mod/PartDesign/App/Feature.h @@ -56,8 +56,13 @@ public: /// Check whether the given feature is a datum feature static bool isDatum(const App::DocumentObject* feature); - /// Returns the BaseFeature property's object (if any) - virtual Part::Feature* getBaseObject() const; + /** + * Returns the BaseFeature property's object (if any) + * @param silent if couldn't determine the base feature and silent == true, + * silently return a nullptr, otherwice throw Base::Exception. + * Default is false. + */ + virtual Part::Feature* getBaseObject(bool silent=false) const; /// Returns the BaseFeature property's shape (if any) virtual const TopoDS_Shape& getBaseShape() const; /// Returns the BaseFeature property's TopoShape (if any) diff --git a/src/Mod/PartDesign/App/FeatureBoolean.cpp b/src/Mod/PartDesign/App/FeatureBoolean.cpp index ea7adc468..5f8531b3a 100644 --- a/src/Mod/PartDesign/App/FeatureBoolean.cpp +++ b/src/Mod/PartDesign/App/FeatureBoolean.cpp @@ -69,10 +69,9 @@ short Boolean::mustExecute() const App::DocumentObjectExecReturn *Boolean::execute(void) { // Check the parameters - const Part::Feature* baseFeature; - try { - baseFeature = getBaseObject(); - } catch (const Base::Exception&) { + const Part::Feature* baseFeature = this->getBaseObject(/* silent = */ true); + + if (!baseFeature) { return new App::DocumentObjectExecReturn("Cannot do boolean operation with invalid BaseFeature"); } diff --git a/src/Mod/PartDesign/App/FeatureDressUp.cpp b/src/Mod/PartDesign/App/FeatureDressUp.cpp index fba49cc21..022d0ca37 100644 --- a/src/Mod/PartDesign/App/FeatureDressUp.cpp +++ b/src/Mod/PartDesign/App/FeatureDressUp.cpp @@ -64,18 +64,30 @@ void DressUp::positionByBaseFeature(void) this->Placement.setValue(base->Placement.getValue()); } -Part::Feature *DressUp::getBaseObject() const +Part::Feature *DressUp::getBaseObject(bool silent) const { - try { - return Feature::getBaseObject(); - } catch (const Base::Exception &) { - App::DocumentObject* base = Base.getValue(); - if(!base) - throw Base::Exception("No Base object linked"); - if(!base->isDerivedFrom(Part::Feature::getClassTypeId())) - throw Base::Exception("Linked object is not a Part object"); - return static_cast(base); + Part::Feature *rv = Feature::getBaseObject(/* silent = */ true); + if (rv) { + return rv; } + + const char* err = nullptr; + App::DocumentObject* base = Base.getValue(); + if (base) { + if(base->isDerivedFrom(Part::Feature::getClassTypeId())) { + rv = static_cast(base); + } else { + err = "Linked object is not a Part object"; + } + } else { + err = "No Base object linked"; + } + + if (!silent && err) { + throw Base::Exception(err); + } + + return rv; } void DressUp::getContiniusEdges(Part::TopoShape TopShape, std::vector< std::string >& SubNames) { diff --git a/src/Mod/PartDesign/App/FeatureDressUp.h b/src/Mod/PartDesign/App/FeatureDressUp.h index 35a0155c3..735ed06fd 100644 --- a/src/Mod/PartDesign/App/FeatureDressUp.h +++ b/src/Mod/PartDesign/App/FeatureDressUp.h @@ -50,8 +50,11 @@ public: /** * Returns the BaseFeature property's object if it's set othervice returns Base's * feature property object otherviceeature property's object (if any) + * @param silent if couldn't determine the base feature and silent == true, + * silently return a nullptr, otherwice throw Base::Exception. + * Default is false. */ - virtual Part::Feature* getBaseObject() const; + virtual Part::Feature* getBaseObject(bool silent=false) const; /// extracts all edges from the subshapes (inkluding face edges) and furthermore adds /// all C0 continius edges to the vector void getContiniusEdges(Part::TopoShape, std::vector< std::string >&); diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.cpp b/src/Mod/PartDesign/App/FeatureSketchBased.cpp index 4b0aa05f8..9da0565a0 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.cpp +++ b/src/Mod/PartDesign/App/FeatureSketchBased.cpp @@ -123,11 +123,10 @@ short SketchBased::mustExecute() const void SketchBased::positionByPrevious(void) { - try{ - //use placement of base - Part::Feature* feat = getBaseObject(); + Part::Feature* feat = getBaseObject(/* silent = */ true); + if (feat) { this->Placement.setValue(feat->Placement.getValue()); - } catch (Base::Exception) { + } else { //no base. Use either Sketch support's placement, or sketch's placement itself. Part::Part2DObject *sketch = getVerifiedSketch(); App::DocumentObject* support = sketch->Support.getValue(); @@ -141,22 +140,31 @@ void SketchBased::positionByPrevious(void) void SketchBased::transformPlacement(const Base::Placement &transform) { - try{ - Part::Feature* feat = getBaseObject(); + Part::Feature* feat = getBaseObject(/* silent = */ true); + if (feat) { feat->transformPlacement(transform); - } catch (Base::Exception) { + } else { Part::Part2DObject *sketch = getVerifiedSketch(); sketch->transformPlacement(transform); } positionByPrevious(); } -Part::Part2DObject* SketchBased::getVerifiedSketch() const { +Part::Part2DObject* SketchBased::getVerifiedSketch(bool silent) const { App::DocumentObject* result = Sketch.getValue(); - if (!result) - throw Base::Exception("No sketch linked"); - if (!result->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) - throw Base::Exception("Linked object is not a Sketch or Part2DObject"); + const char* err = nullptr; + + if (!result) { + err = "No sketch linked"; + } else { + if (!result->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) + err = "Linked object is not a Sketch or Part2DObject"; + } + + if (!silent && err) { + throw Base::Exception (err); + } + return static_cast(result); } @@ -231,19 +239,39 @@ int SketchBased::getSketchAxisCount(void) const return sketch->getAxisCount(); } -Part::Feature *SketchBased::getBaseObject() const +Part::Feature *SketchBased::getBaseObject(bool silent) const { - try{ - return Feature::getBaseObject(); - } catch (Base::Exception) { - Part::Part2DObject* sketch = getVerifiedSketch(); - App::DocumentObject* spt = sketch->Support.getValue(); - if(!spt) - throw Base::Exception ("No base set, no sketch support either"); - if(!spt->isDerivedFrom(Part::Feature::getClassTypeId())) - throw Base::Exception ("No base set, sketch support is not Part::Feature"); - return static_cast(spt); + // Test the base's class feature. + Part::Feature *rv = Feature::getBaseObject(/* silent = */ true); + if (rv) { + return rv; } + + // getVerifiedSketch() may throw it's own exception if fail + Part::Part2DObject* sketch = getVerifiedSketch(silent); + + if (!sketch) { + return nullptr; + } + + const char* err = nullptr; + + App::DocumentObject* spt = sketch->Support.getValue(); + if (spt) { + if (spt->isDerivedFrom(Part::Feature::getClassTypeId())) { + rv = static_cast(spt); + } else { + err = "No base set, sketch support is not Part::Feature"; + } + } else { + err = "No base set, no sketch support either"; + } + + if (!silent && err) { + throw Base::Exception (err); + } + + return rv; } void SketchBased::onChanged(const App::Property* prop) diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.h b/src/Mod/PartDesign/App/FeatureSketchBased.h index 4f43d63c1..dd08067f4 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.h +++ b/src/Mod/PartDesign/App/FeatureSketchBased.h @@ -67,8 +67,13 @@ public: */ virtual void transformPlacement(const Base::Placement &transform); - /// Verifies the linked Sketch object - Part::Part2DObject* getVerifiedSketch() const; + /** + * Verifies the linked Sketch object + * @param silent if sketch property is malformed and the parameter is true + * silently returns nullptr, otherwice throw a Base::Exception. + * Default is false. + */ + Part::Part2DObject* getVerifiedSketch(bool silent=false) const; /// Returns the wires the sketch is composed of std::vector getSketchWires() const; /// Returns the face of the sketch support (if any) @@ -77,7 +82,7 @@ public: /// retrieves the number of axes in the linked sketch (defined as construction lines) int getSketchAxisCount(void) const; - virtual Part::Feature* getBaseObject() const; + virtual Part::Feature* getBaseObject(bool silent=false) const; protected: void onChanged(const App::Property* prop); diff --git a/src/Mod/PartDesign/Gui/Command.cpp b/src/Mod/PartDesign/Gui/Command.cpp index 5823f6456..acfd5eef4 100644 --- a/src/Mod/PartDesign/Gui/Command.cpp +++ b/src/Mod/PartDesign/Gui/Command.cpp @@ -1827,7 +1827,7 @@ void CmdPartDesignMirrored::activated(int iMsg) return; if(features.front()->isDerivedFrom(PartDesign::SketchBased::getClassTypeId())) { - Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); + Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(/* silent =*/ true); if (sketch) Gui::Command::doCommand(Doc,"App.activeDocument().%s.MirrorPlane = (App.activeDocument().%s, [\"V_Axis\"])", FeatName.c_str(), sketch->getNameInDocument()); @@ -1874,7 +1874,7 @@ void CmdPartDesignLinearPattern::activated(int iMsg) return; if(features.front()->isDerivedFrom(PartDesign::SketchBased::getClassTypeId())) { - Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); + Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(/* silent =*/ true); if (sketch) doCommand(Doc,"App.activeDocument().%s.Direction = (App.activeDocument().%s, [\"H_Axis\"])", FeatName.c_str(), sketch->getNameInDocument()); @@ -1923,7 +1923,7 @@ void CmdPartDesignPolarPattern::activated(int iMsg) return; if(features.front()->isDerivedFrom(PartDesign::SketchBased::getClassTypeId())) { - Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); + Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(/* silent =*/ true); if (sketch) doCommand(Doc,"App.activeDocument().%s.Axis = (App.activeDocument().%s, [\"N_Axis\"])", FeatName.c_str(), sketch->getNameInDocument()); diff --git a/src/Mod/PartDesign/Gui/TaskFeatureParameters.cpp b/src/Mod/PartDesign/Gui/TaskFeatureParameters.cpp index f25f3e02a..9755350b9 100644 --- a/src/Mod/PartDesign/Gui/TaskFeatureParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskFeatureParameters.cpp @@ -59,11 +59,11 @@ bool TaskDlgFeatureParameters::accept() { throw Base::Exception("Bad object processed in the feature dialog."); } - App::DocumentObject* support = static_cast(feature)->BaseFeature.getValue(); + App::DocumentObject* previous = static_cast(feature)->getBaseObject(/* silent = */ true ); - if (support) { + if (previous) { Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().hide(\"%s\")", - support->getNameInDocument()); + previous->getNameInDocument()); } Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); @@ -91,12 +91,7 @@ bool TaskDlgFeatureParameters::reject() // Find out previous feature we won't be able to do it after abort // (at least in the body case) - App::DocumentObject* previous; - try { - previous = feature->getBaseObject(); // throws on errors - } catch (const Base::Exception &ex) { - previous = 0; - } + App::DocumentObject* previous = feature->getBaseObject(/* silent = */ true ); // roll back the done things Gui::Command::abortCommand(); diff --git a/src/Mod/PartDesign/Gui/ViewProvider.cpp b/src/Mod/PartDesign/Gui/ViewProvider.cpp index 9377c36af..b9d39079e 100644 --- a/src/Mod/PartDesign/Gui/ViewProvider.cpp +++ b/src/Mod/PartDesign/Gui/ViewProvider.cpp @@ -167,14 +167,8 @@ void ViewProvider::updateData(const App::Property* prop) bool ViewProvider::onDelete(const std::vector &) { - App::DocumentObject* previous; PartDesign::Feature* feature = static_cast(getObject()); - - try { - previous = feature->getBaseObject(); - } catch (const Base::Exception &ex) { - previous = 0; - } + App::DocumentObject* previous = feature->getBaseObject(/* silent = */ true ); // Make the tip or the previous feature visiable again with preference to the previous one // if the feature was visiable itself