From e5bdcc132270d5604090e39b64528e4ed934f833 Mon Sep 17 00:00:00 2001 From: jrheinlaender Date: Mon, 29 Oct 2012 16:09:54 +0100 Subject: [PATCH] PartDesign: avoid duplicate code in getting the support shape --- src/Mod/PartDesign/App/FeatureGroove.cpp | 48 ++++++++---------- src/Mod/PartDesign/App/FeaturePad.cpp | 35 ++++++------- src/Mod/PartDesign/App/FeaturePocket.cpp | 24 ++------- src/Mod/PartDesign/App/FeatureRevolution.cpp | 49 +++++++++---------- src/Mod/PartDesign/App/FeatureSketchBased.cpp | 20 ++++++++ src/Mod/PartDesign/App/FeatureSketchBased.h | 2 + 6 files changed, 87 insertions(+), 91 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureGroove.cpp b/src/Mod/PartDesign/App/FeatureGroove.cpp index 176f22324..503a0f24a 100644 --- a/src/Mod/PartDesign/App/FeatureGroove.cpp +++ b/src/Mod/PartDesign/App/FeatureGroove.cpp @@ -82,37 +82,39 @@ App::DocumentObjectExecReturn *Groove::execute(void) if (Reversed.getValue() && !Midplane.getValue()) angle *= (-1.0); - Part::Part2DObject* pcSketch = 0; + Part::Part2DObject* sketch = 0; std::vector wires; + TopoDS_Shape support; try { - pcSketch = getVerifiedSketch(); + sketch = getVerifiedSketch(); wires = getSketchWires(); + support = getSupportShape(); } catch (const Base::Exception& e) { return new App::DocumentObjectExecReturn(e.what()); } // get the Sketch plane - Base::Placement SketchPlm = pcSketch->Placement.getValue(); + Base::Placement SketchPlm = sketch->Placement.getValue(); // get reference axis App::DocumentObject *pcReferenceAxis = ReferenceAxis.getValue(); const std::vector &subReferenceAxis = ReferenceAxis.getSubValues(); - if (pcReferenceAxis && pcReferenceAxis == pcSketch) { + if (pcReferenceAxis && pcReferenceAxis == sketch) { bool hasValidAxis=false; Base::Axis axis; if (subReferenceAxis[0] == "V_Axis") { hasValidAxis = true; - axis = pcSketch->getAxis(Part::Part2DObject::V_Axis); + axis = sketch->getAxis(Part::Part2DObject::V_Axis); } else if (subReferenceAxis[0] == "H_Axis") { hasValidAxis = true; - axis = pcSketch->getAxis(Part::Part2DObject::H_Axis); + axis = sketch->getAxis(Part::Part2DObject::H_Axis); } else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0,4) == "Axis") { int AxId = std::atoi(subReferenceAxis[0].substr(4,4000).c_str()); - if (AxId >= 0 && AxId < pcSketch->getAxisCount()) { + if (AxId >= 0 && AxId < sketch->getAxisCount()) { hasValidAxis = true; - axis = pcSketch->getAxis(AxId); + axis = sketch->getAxis(AxId); } } if (hasValidAxis) { @@ -130,12 +132,6 @@ App::DocumentObjectExecReturn *Groove::execute(void) Base::Vector3f v = Axis.getValue(); gp_Dir dir(v.x,v.y,v.z); - // get the support of the Sketch if any - App::DocumentObject* pcSupport = pcSketch->Support.getValue(); - Part::Feature *SupportObject = 0; - if (pcSupport && pcSupport->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) - SupportObject = static_cast(pcSupport); - TopoDS_Shape aFace = makeFace(wires); if (aFace.IsNull()) return new App::DocumentObjectExecReturn("Creating a face from sketch failed"); @@ -163,20 +159,18 @@ App::DocumentObjectExecReturn *Groove::execute(void) // Set the subtractive shape property for later usage in e.g. pattern this->SubShape.setValue(result); - // if the sketch has a support fuse them to get one result object (PAD!) - if (SupportObject) { - const TopoDS_Shape& support = SupportObject->Shape.getValue(); - if (!support.IsNull() && support.ShapeType() == TopAbs_SOLID) { - // Let's call algorithm computing a fuse operation: - BRepAlgoAPI_Cut mkCut(support.Moved(invObjLoc), result); - // Let's check if the fusion has been successful - if (!mkCut.IsDone()) - throw Base::Exception("Cut out of support failed"); - result = mkCut.Shape(); - } - } + // cut out groove to get one result object + BRepAlgoAPI_Cut mkCut(support.Moved(invObjLoc), result); + // Let's check if the fusion has been successful + if (!mkCut.IsDone()) + throw Base::Exception("Cut out of support failed"); - this->Shape.setValue(result); + // we have to get the solids (fuse sometimes creates compounds) + TopoDS_Shape solRes = this->getSolid(mkCut.Shape()); + if (solRes.IsNull()) + return new App::DocumentObjectExecReturn("Resulting shape is not a solid"); + + this->Shape.setValue(solRes); } else return new App::DocumentObjectExecReturn("Could not revolve the sketch!"); diff --git a/src/Mod/PartDesign/App/FeaturePad.cpp b/src/Mod/PartDesign/App/FeaturePad.cpp index 77823eab5..4a62b3726 100644 --- a/src/Mod/PartDesign/App/FeaturePad.cpp +++ b/src/Mod/PartDesign/App/FeaturePad.cpp @@ -81,27 +81,29 @@ App::DocumentObjectExecReturn *Pad::execute(void) if ((std::string(Type.getValueAsString()) == "TwoLengths") && (L < Precision::Confusion())) return new App::DocumentObjectExecReturn("Second length of pad too small"); - Part::Part2DObject* pcSketch = 0; + Part::Part2DObject* sketch = 0; std::vector wires; try { - pcSketch = getVerifiedSketch(); + sketch = getVerifiedSketch(); wires = getSketchWires(); } catch (const Base::Exception& e) { return new App::DocumentObjectExecReturn(e.what()); } + TopoDS_Shape support; + try { + support = getSupportShape(); + } catch (const Base::Exception&) { + // ignore, because support isn't mandatory + support = TopoDS_Shape(); + } + // get the Sketch plane - Base::Placement SketchPos = pcSketch->Placement.getValue(); + Base::Placement SketchPos = sketch->Placement.getValue(); Base::Rotation SketchOrientation = SketchPos.getRotation(); Base::Vector3d SketchVector(0,0,1); SketchOrientation.multVec(SketchVector,SketchVector); - // get the support of the Sketch if any - App::DocumentObject* SupportLink = pcSketch->Support.getValue(); - Part::Feature *SupportObject = 0; - if (SupportLink && SupportLink->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) - SupportObject = static_cast(SupportLink); - TopoDS_Shape aFace = makeFace(wires); if (aFace.IsNull()) return new App::DocumentObjectExecReturn("Creating a face from sketch failed"); @@ -126,12 +128,8 @@ App::DocumentObjectExecReturn *Pad::execute(void) (std::string(Type.getValueAsString()) == "UpToFirst")) { // Check for valid support object - if (!SupportObject) - return new App::DocumentObjectExecReturn("Cannot extrude up to face: No support in Sketch!"); - - const TopoDS_Shape& support = SupportObject->Shape.getValue(); if (support.IsNull()) - return new App::DocumentObjectExecReturn("Cannot extrude up to face: Support shape is invalid"); + return new App::DocumentObjectExecReturn("Cannot extrude up to face: No valid support in Sketch"); TopExp_Explorer xp (support, TopAbs_SOLID); if (!xp.More()) return new App::DocumentObjectExecReturn("Cannot extrude up to face: Support shape is not a solid"); @@ -251,12 +249,11 @@ App::DocumentObjectExecReturn *Pad::execute(void) return new App::DocumentObjectExecReturn("Internal error: Unknown type for Pad feature"); } + // set the additive shape property for later usage in e.g. pattern + this->AddShape.setValue(prism); + // if the sketch has a support fuse them to get one result object (PAD!) - if (SupportObject) { - // set the additive shape property for later usage in e.g. pattern - this->AddShape.setValue(prism); - - const TopoDS_Shape& support = SupportObject->Shape.getValue(); + if (!support.IsNull()) { if (!isSolidChecked) { // we haven't checked for solid, yet if (!support.IsNull()) { diff --git a/src/Mod/PartDesign/App/FeaturePocket.cpp b/src/Mod/PartDesign/App/FeaturePocket.cpp index f80b1d26f..60ebcc559 100644 --- a/src/Mod/PartDesign/App/FeaturePocket.cpp +++ b/src/Mod/PartDesign/App/FeaturePocket.cpp @@ -80,37 +80,23 @@ App::DocumentObjectExecReturn *Pocket::execute(void) if ((std::string(Type.getValueAsString()) == "Length") && (L < Precision::Confusion())) return new App::DocumentObjectExecReturn("Pocket: Length of pocket too small"); - Part::Part2DObject* pcSketch = 0; + Part::Part2DObject* sketch = 0; std::vector wires; + TopoDS_Shape support; try { - pcSketch = getVerifiedSketch(); + sketch = getVerifiedSketch(); wires = getSketchWires(); + support = getSupportShape(); } catch (const Base::Exception& e) { return new App::DocumentObjectExecReturn(e.what()); } // get the Sketch plane - Base::Placement SketchPos = pcSketch->Placement.getValue(); + Base::Placement SketchPos = sketch->Placement.getValue(); Base::Rotation SketchOrientation = SketchPos.getRotation(); Base::Vector3d SketchVector(0,0,1); SketchOrientation.multVec(SketchVector,SketchVector); - // get the support of the Sketch if any - App::DocumentObject* SupportLink = pcSketch->Support.getValue(); - Part::Feature *SupportObject = 0; - if (SupportLink && SupportLink->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) - SupportObject = static_cast(SupportLink); - - if (!SupportObject) - return new App::DocumentObjectExecReturn("No support in Sketch!"); - - const TopoDS_Shape& support = SupportObject->Shape.getValue(); - if (support.IsNull()) - return new App::DocumentObjectExecReturn("Support shape is invalid"); - TopExp_Explorer xp (support, TopAbs_SOLID); - if (!xp.More()) - return new App::DocumentObjectExecReturn("Support shape is not a solid"); - TopoDS_Shape aFace = makeFace(wires); if (aFace.IsNull()) return new App::DocumentObjectExecReturn("Creating a face from sketch failed"); diff --git a/src/Mod/PartDesign/App/FeatureRevolution.cpp b/src/Mod/PartDesign/App/FeatureRevolution.cpp index fd067739c..7679ca24f 100644 --- a/src/Mod/PartDesign/App/FeatureRevolution.cpp +++ b/src/Mod/PartDesign/App/FeatureRevolution.cpp @@ -77,37 +77,45 @@ App::DocumentObjectExecReturn *Revolution::execute(void) if (a > 360.0) return new App::DocumentObjectExecReturn("Angle of groove too large"); - Part::Part2DObject* pcSketch = 0; + Part::Part2DObject* sketch = 0; std::vector wires; try { - pcSketch = getVerifiedSketch(); + sketch = getVerifiedSketch(); wires = getSketchWires(); } catch (const Base::Exception& e) { return new App::DocumentObjectExecReturn(e.what()); } + + TopoDS_Shape support; + try { + support = getSupportShape(); + } catch (const Base::Exception&) { + // ignore, because support isn't mandatory + support = TopoDS_Shape(); + } // get the Sketch plane - Base::Placement SketchPlm = pcSketch->Placement.getValue(); + Base::Placement SketchPlm = sketch->Placement.getValue(); // get reference axis App::DocumentObject *pcReferenceAxis = ReferenceAxis.getValue(); const std::vector &subReferenceAxis = ReferenceAxis.getSubValues(); - if (pcReferenceAxis && pcReferenceAxis == pcSketch) { + if (pcReferenceAxis && pcReferenceAxis == sketch) { bool hasValidAxis=false; Base::Axis axis; if (subReferenceAxis[0] == "V_Axis") { hasValidAxis = true; - axis = pcSketch->getAxis(Part::Part2DObject::V_Axis); + axis = sketch->getAxis(Part::Part2DObject::V_Axis); } else if (subReferenceAxis[0] == "H_Axis") { hasValidAxis = true; - axis = pcSketch->getAxis(Part::Part2DObject::H_Axis); + axis = sketch->getAxis(Part::Part2DObject::H_Axis); } else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0,4) == "Axis") { int AxId = std::atoi(subReferenceAxis[0].substr(4,4000).c_str()); - if (AxId >= 0 && AxId < pcSketch->getAxisCount()) { + if (AxId >= 0 && AxId < sketch->getAxisCount()) { hasValidAxis = true; - axis = pcSketch->getAxis(AxId); + axis = sketch->getAxis(AxId); } } if (hasValidAxis) { @@ -125,12 +133,6 @@ App::DocumentObjectExecReturn *Revolution::execute(void) Base::Vector3f v = Axis.getValue(); gp_Dir dir(v.x,v.y,v.z); - // get the support of the Sketch if any - App::DocumentObject* pcSupport = pcSketch->Support.getValue(); - Part::Feature *SupportObject = 0; - if (pcSupport && pcSupport->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) - SupportObject = static_cast(pcSupport); - TopoDS_Shape aFace = makeFace(wires); if (aFace.IsNull()) return new App::DocumentObjectExecReturn("Creating a face from sketch failed"); @@ -163,18 +165,13 @@ App::DocumentObjectExecReturn *Revolution::execute(void) this->AddShape.setValue(result); // if the sketch has a support fuse them to get one result object (PAD!) - if (SupportObject) { - const TopoDS_Shape& support = SupportObject->Shape.getValue(); - if (!support.IsNull() && support.ShapeType() == TopAbs_SOLID) { - // set the additive shape property for later usage in e.g. pattern - this->AddShape.setValue(result); - // Let's call algorithm computing a fuse operation: - BRepAlgoAPI_Fuse mkFuse(support.Moved(invObjLoc), result); - // Let's check if the fusion has been successful - if (!mkFuse.IsDone()) - throw Base::Exception("Fusion with support failed"); - result = mkFuse.Shape(); - } + if (!support.IsNull()) { + // Let's call algorithm computing a fuse operation: + BRepAlgoAPI_Fuse mkFuse(support.Moved(invObjLoc), result); + // Let's check if the fusion has been successful + if (!mkFuse.IsDone()) + throw Base::Exception("Fusion with support failed"); + result = mkFuse.Shape(); } this->Shape.setValue(result); diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.cpp b/src/Mod/PartDesign/App/FeatureSketchBased.cpp index e5f0eb6f3..25b978685 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.cpp +++ b/src/Mod/PartDesign/App/FeatureSketchBased.cpp @@ -136,6 +136,26 @@ std::vector SketchBased::getSketchWires() const { return result; } +const TopoDS_Shape& SketchBased::getSupportShape() const { + // get the support of the Sketch if any + App::DocumentObject* SupportLink = static_cast(Sketch.getValue())->Support.getValue(); + Part::Feature* SupportObject = NULL; + if (SupportLink && SupportLink->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) + SupportObject = static_cast(SupportLink); + + if (SupportObject == NULL) + throw Base::Exception("No support in Sketch!"); + + const TopoDS_Shape& result = SupportObject->Shape.getValue(); + if (result.IsNull()) + throw Base::Exception("Support shape is invalid"); + TopExp_Explorer xp (result, TopAbs_SOLID); + if (!xp.More()) + throw Base::Exception("Support shape is not a solid"); + + return result; +} + void SketchBased::onChanged(const App::Property* prop) { if (prop == &Sketch) { diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.h b/src/Mod/PartDesign/App/FeatureSketchBased.h index 515e7a523..c228000da 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.h +++ b/src/Mod/PartDesign/App/FeatureSketchBased.h @@ -59,6 +59,8 @@ public: Part::Part2DObject* getVerifiedSketch() const; /// Returns the wires the sketch is composed of std::vector getSketchWires() const; + /// Returns the sketch support shape (if any) + const TopoDS_Shape& getSupportShape() const; /// retrieves the number of axes in the linked sketch (defined as construction lines) int getSketchAxisCount(void) const;