diff --git a/src/Mod/PartDesign/App/FeatureFace.cpp b/src/Mod/PartDesign/App/FeatureFace.cpp index 5bf37da33..55030f6c9 100644 --- a/src/Mod/PartDesign/App/FeatureFace.cpp +++ b/src/Mod/PartDesign/App/FeatureFace.cpp @@ -42,7 +42,6 @@ #endif #include -#include #include "FeatureFace.h" diff --git a/src/Mod/PartDesign/App/FeatureGroove.cpp b/src/Mod/PartDesign/App/FeatureGroove.cpp index 40309d496..176f22324 100644 --- a/src/Mod/PartDesign/App/FeatureGroove.cpp +++ b/src/Mod/PartDesign/App/FeatureGroove.cpp @@ -26,19 +26,18 @@ # include # include # include -# include # include # include # include # include # include # include +# include #endif #include #include #include -#include #include "FeatureGroove.h" @@ -71,35 +70,26 @@ short Groove::mustExecute() const App::DocumentObjectExecReturn *Groove::execute(void) { - App::DocumentObject* link = Sketch.getValue(); - if (!link) - return new App::DocumentObjectExecReturn("No sketch linked"); - if (!link->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) - return new App::DocumentObjectExecReturn("Linked object is not a Sketch or Part2DObject"); - - Part::Part2DObject* pcSketch=static_cast(link); - - TopoDS_Shape shape = pcSketch->Shape.getShape()._Shape; - if (shape.IsNull()) - return new App::DocumentObjectExecReturn("Linked shape object is empty"); - - // this is a workaround for an obscure OCC bug which leads to empty tessellations - // for some faces. Making an explicit copy of the linked shape seems to fix it. - // The error only happens when re-computing the shape. - if (!this->Shape.getValue().IsNull()) { - BRepBuilderAPI_Copy copy(shape); - shape = copy.Shape(); - if (shape.IsNull()) - return new App::DocumentObjectExecReturn("Linked shape object is empty"); - } - - TopExp_Explorer ex; + // Validate parameters + double angle = Angle.getValue(); + if (angle < Precision::Confusion()) + return new App::DocumentObjectExecReturn("Angle of groove too small"); + if (angle > 360.0) + return new App::DocumentObjectExecReturn("Angle of groove too large"); + + angle = Base::toRadians(angle); + // Reverse angle if selected + if (Reversed.getValue() && !Midplane.getValue()) + angle *= (-1.0); + + Part::Part2DObject* pcSketch = 0; std::vector wires; - for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { - wires.push_back(TopoDS::Wire(ex.Current())); + try { + pcSketch = getVerifiedSketch(); + wires = getSketchWires(); + } catch (const Base::Exception& e) { + return new App::DocumentObjectExecReturn(e.what()); } - if (wires.empty()) // there can be several wires - return new App::DocumentObjectExecReturn("Linked shape object is not a wire"); // get the Sketch plane Base::Placement SketchPlm = pcSketch->Placement.getValue(); @@ -163,17 +153,16 @@ App::DocumentObjectExecReturn *Groove::execute(void) pnt.Transform(invObjLoc.Transformation()); dir.Transform(invObjLoc.Transformation()); - // Reverse angle if selected - double angle = Base::toRadians(Angle.getValue()); - if (Reversed.getValue() && !Midplane.getValue()) - angle *= (-1.0); - try { // revolve the face to a solid BRepPrimAPI_MakeRevol RevolMaker(aFace.Moved(invObjLoc), gp_Ax1(pnt, dir), angle); if (RevolMaker.IsDone()) { TopoDS_Shape result = RevolMaker.Shape(); + + // 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(); diff --git a/src/Mod/PartDesign/App/FeatureHole.cpp b/src/Mod/PartDesign/App/FeatureHole.cpp index c16d6a7f7..55d296bc5 100644 --- a/src/Mod/PartDesign/App/FeatureHole.cpp +++ b/src/Mod/PartDesign/App/FeatureHole.cpp @@ -42,7 +42,6 @@ #endif #include -#include #include "FeatureHole.h" diff --git a/src/Mod/PartDesign/App/FeaturePad.cpp b/src/Mod/PartDesign/App/FeaturePad.cpp index ae037197b..77823eab5 100644 --- a/src/Mod/PartDesign/App/FeaturePad.cpp +++ b/src/Mod/PartDesign/App/FeaturePad.cpp @@ -27,7 +27,6 @@ # include # include # include -# include # include # include # include @@ -42,7 +41,6 @@ #endif #include -#include #include #include "FeaturePad.h" @@ -75,47 +73,31 @@ short Pad::mustExecute() const App::DocumentObjectExecReturn *Pad::execute(void) { + // Validate parameters double L = Length.getValue(); - if (L < Precision::Confusion()) + if ((std::string(Type.getValueAsString()) == "Length") && (L < Precision::Confusion())) return new App::DocumentObjectExecReturn("Length of pad too small"); double L2 = Length2.getValue(); if ((std::string(Type.getValueAsString()) == "TwoLengths") && (L < Precision::Confusion())) return new App::DocumentObjectExecReturn("Second length of pad too small"); - App::DocumentObject* link = Sketch.getValue(); - if (!link) - return new App::DocumentObjectExecReturn("No sketch linked"); - if (!link->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) - return new App::DocumentObjectExecReturn("Linked object is not a Sketch or Part2DObject"); - TopoDS_Shape shape = static_cast(link)->Shape.getShape()._Shape; - if (shape.IsNull()) - return new App::DocumentObjectExecReturn("Linked shape object is empty"); - - // this is a workaround for an obscure OCC bug which leads to empty tessellations - // for some faces. Making an explicit copy of the linked shape seems to fix it. - // The error almost happens when re-computing the shape but sometimes also for the - // first time - BRepBuilderAPI_Copy copy(shape); - shape = copy.Shape(); - if (shape.IsNull()) - return new App::DocumentObjectExecReturn("Linked shape object is empty"); - - TopExp_Explorer ex; + Part::Part2DObject* pcSketch = 0; std::vector wires; - for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { - wires.push_back(TopoDS::Wire(ex.Current())); + try { + pcSketch = getVerifiedSketch(); + wires = getSketchWires(); + } catch (const Base::Exception& e) { + return new App::DocumentObjectExecReturn(e.what()); } - if (/*shape.ShapeType() != TopAbs_WIRE*/wires.empty()) // there can be several wires - return new App::DocumentObjectExecReturn("Linked shape object is not a wire"); // get the Sketch plane - Base::Placement SketchPos = static_cast(link)->Placement.getValue(); + Base::Placement SketchPos = pcSketch->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 = static_cast(link)->Support.getValue(); + App::DocumentObject* SupportLink = pcSketch->Support.getValue(); Part::Feature *SupportObject = 0; if (SupportLink && SupportLink->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) SupportObject = static_cast(SupportLink); @@ -294,13 +276,13 @@ App::DocumentObjectExecReturn *Pad::execute(void) BRepAlgoAPI_Fuse mkFuse(support.Moved(invObjLoc), prism); // Let's check if the fusion has been successful if (!mkFuse.IsDone()) - return new App::DocumentObjectExecReturn("Fusion with support failed"); + return new App::DocumentObjectExecReturn("Pad: Fusion with support failed"); TopoDS_Shape result = mkFuse.Shape(); // we have to get the solids (fuse create seldomly compounds) TopoDS_Shape solRes = this->getSolid(result); // lets check if the result is a solid if (solRes.IsNull()) - return new App::DocumentObjectExecReturn("Resulting shape is not a solid"); + return new App::DocumentObjectExecReturn("Pad: Resulting shape is not a solid"); this->Shape.setValue(solRes); } else { diff --git a/src/Mod/PartDesign/App/FeaturePocket.cpp b/src/Mod/PartDesign/App/FeaturePocket.cpp index 074c7b00f..f80b1d26f 100644 --- a/src/Mod/PartDesign/App/FeaturePocket.cpp +++ b/src/Mod/PartDesign/App/FeaturePocket.cpp @@ -31,7 +31,6 @@ # include # include # include -# include # include # include # include @@ -46,7 +45,6 @@ #endif #include -#include #include #include "FeaturePocket.h" @@ -77,40 +75,28 @@ short Pocket::mustExecute() const App::DocumentObjectExecReturn *Pocket::execute(void) { - App::DocumentObject* link = Sketch.getValue(); - if (!link) - return new App::DocumentObjectExecReturn("No sketch linked"); - if (!link->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) - return new App::DocumentObjectExecReturn("Linked object is not a Sketch or Part2DObject"); - TopoDS_Shape shape = static_cast(link)->Shape.getShape()._Shape; - if (shape.IsNull()) - return new App::DocumentObjectExecReturn("Linked shape object is empty"); - - // this is a workaround for an obscure OCC bug which leads to empty tessellations - // for some faces. Making an explicit copy of the linked shape seems to fix it. - // The error almost happens when re-computing the shape but sometimes also for the - // first time - BRepBuilderAPI_Copy copy(shape); - shape = copy.Shape(); - if (shape.IsNull()) - return new App::DocumentObjectExecReturn("Linked shape object is empty"); - - TopExp_Explorer ex; + // Validate parameters + double L = Length.getValue(); + if ((std::string(Type.getValueAsString()) == "Length") && (L < Precision::Confusion())) + return new App::DocumentObjectExecReturn("Pocket: Length of pocket too small"); + + Part::Part2DObject* pcSketch = 0; std::vector wires; - for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { - wires.push_back(TopoDS::Wire(ex.Current())); + try { + pcSketch = getVerifiedSketch(); + wires = getSketchWires(); + } catch (const Base::Exception& e) { + return new App::DocumentObjectExecReturn(e.what()); } - if (wires.empty()) // there can be several wires - return new App::DocumentObjectExecReturn("Linked shape object is not a wire"); // get the Sketch plane - Base::Placement SketchPos = static_cast(link)->Placement.getValue(); + Base::Placement SketchPos = pcSketch->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 = static_cast(link)->Support.getValue(); + App::DocumentObject* SupportLink = pcSketch->Support.getValue(); Part::Feature *SupportObject = 0; if (SupportLink && SupportLink->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) SupportObject = static_cast(SupportLink); diff --git a/src/Mod/PartDesign/App/FeatureRevolution.cpp b/src/Mod/PartDesign/App/FeatureRevolution.cpp index 30501df24..fd067739c 100644 --- a/src/Mod/PartDesign/App/FeatureRevolution.cpp +++ b/src/Mod/PartDesign/App/FeatureRevolution.cpp @@ -26,19 +26,18 @@ # include # include # include -# include # include # include # include # include # include # include +# include #endif #include #include #include -#include #include "FeatureRevolution.h" @@ -71,35 +70,21 @@ short Revolution::mustExecute() const App::DocumentObjectExecReturn *Revolution::execute(void) { - App::DocumentObject* link = Sketch.getValue(); - if (!link) - return new App::DocumentObjectExecReturn("No sketch linked"); - if (!link->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) - return new App::DocumentObjectExecReturn("Linked object is not a Sketch or Part2DObject"); - - Part::Part2DObject* pcSketch=static_cast(link); - - TopoDS_Shape shape = pcSketch->Shape.getShape()._Shape; - if (shape.IsNull()) - return new App::DocumentObjectExecReturn("Linked shape object is empty"); - - // this is a workaround for an obscure OCC bug which leads to empty tessellations - // for some faces. Making an explicit copy of the linked shape seems to fix it. - // The error only happens when re-computing the shape. - if (!this->Shape.getValue().IsNull()) { - BRepBuilderAPI_Copy copy(shape); - shape = copy.Shape(); - if (shape.IsNull()) - return new App::DocumentObjectExecReturn("Linked shape object is empty"); - } - - TopExp_Explorer ex; + // Validate parameters + double a = Angle.getValue(); + if (a < Precision::Confusion()) + return new App::DocumentObjectExecReturn("Angle of groove too small"); + if (a > 360.0) + return new App::DocumentObjectExecReturn("Angle of groove too large"); + + Part::Part2DObject* pcSketch = 0; std::vector wires; - for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { - wires.push_back(TopoDS::Wire(ex.Current())); + try { + pcSketch = getVerifiedSketch(); + wires = getSketchWires(); + } catch (const Base::Exception& e) { + return new App::DocumentObjectExecReturn(e.what()); } - if (wires.empty()) // there can be several wires - return new App::DocumentObjectExecReturn("Linked shape object is not a wire"); // get the Sketch plane Base::Placement SketchPlm = pcSketch->Placement.getValue(); @@ -174,6 +159,9 @@ App::DocumentObjectExecReturn *Revolution::execute(void) if (RevolMaker.IsDone()) { TopoDS_Shape result = RevolMaker.Shape(); + // set the additive shape property for later usage in e.g. pattern + 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(); diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.cpp b/src/Mod/PartDesign/App/FeatureSketchBased.cpp index 1cb4ef1a4..e5f0eb6f3 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.cpp +++ b/src/Mod/PartDesign/App/FeatureSketchBased.cpp @@ -26,6 +26,7 @@ # include # include # include +# include # include # include # include @@ -100,6 +101,41 @@ void SketchBased::positionBySketch(void) } } +Part::Part2DObject* SketchBased::getVerifiedSketch() 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"); + return static_cast(result); +} + +std::vector SketchBased::getSketchWires() const { + std::vector result; + + TopoDS_Shape shape = getVerifiedSketch()->Shape.getShape()._Shape; + if (shape.IsNull()) + throw Base::Exception("Linked shape object is empty"); + + // this is a workaround for an obscure OCC bug which leads to empty tessellations + // for some faces. Making an explicit copy of the linked shape seems to fix it. + // The error almost happens when re-computing the shape but sometimes also for the + // first time + BRepBuilderAPI_Copy copy(shape); + shape = copy.Shape(); + if (shape.IsNull()) + throw Base::Exception("Linked shape object is empty"); + + TopExp_Explorer ex; + for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { + result.push_back(TopoDS::Wire(ex.Current())); + } + if (result.empty()) // there can be several wires + throw Base::Exception("Linked shape object is not a wire"); + + 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 8c75d9724..515e7a523 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.h +++ b/src/Mod/PartDesign/App/FeatureSketchBased.h @@ -25,6 +25,7 @@ #define PARTDESIGN_SketchBased_H #include +#include #include "Feature.h" class TopoDS_Face; @@ -54,6 +55,10 @@ public: */ void positionBySketch(void); + /// Verifies the linked Sketch object + Part::Part2DObject* getVerifiedSketch() const; + /// Returns the wires the sketch is composed of + std::vector getSketchWires() const; /// retrieves the number of axes in the linked sketch (defined as construction lines) int getSketchAxisCount(void) const;