diff --git a/src/Mod/Part/App/FeaturePartBoolean.cpp b/src/Mod/Part/App/FeaturePartBoolean.cpp index f21296a8b..7418db97a 100644 --- a/src/Mod/Part/App/FeaturePartBoolean.cpp +++ b/src/Mod/Part/App/FeaturePartBoolean.cpp @@ -23,6 +23,8 @@ #include "PreCompiled.h" #ifndef _PreComp_ +# include +#include #endif #include "FeaturePartBoolean.h" @@ -33,7 +35,7 @@ using namespace Part; PROPERTY_SOURCE_ABSTRACT(Part::Boolean, Part::Feature) -Boolean::Boolean(void) +Boolean::Boolean(void) : myBoolOp(0) { ADD_PROPERTY(Base,(0)); ADD_PROPERTY(Tool,(0)); @@ -66,13 +68,23 @@ App::DocumentObjectExecReturn *Boolean::execute(void) TopoDS_Shape BaseShape = base->Shape.getValue(); TopoDS_Shape ToolShape = tool->Shape.getValue(); - TopoDS_Shape resShape = runOperation(BaseShape, ToolShape); - if (resShape.IsNull()) + std::auto_ptr mkBool(makeOperation(BaseShape, ToolShape)); + if (!mkBool->IsDone()) { + return new App::DocumentObjectExecReturn("Boolean operation failed"); + } + const TopoDS_Shape& resShape = mkBool->Shape(); + if (resShape.IsNull()) { return new App::DocumentObjectExecReturn("Resulting shape is invalid"); + } + + // tmp. set boolean operation pointer + this->myBoolOp = mkBool.get(); this->Shape.setValue(resShape); + this->myBoolOp = 0; return App::DocumentObject::StdReturn; } catch (...) { + this->myBoolOp = 0; return new App::DocumentObjectExecReturn("A fatal error occurred when running boolean operation"); } } diff --git a/src/Mod/Part/App/FeaturePartBoolean.h b/src/Mod/Part/App/FeaturePartBoolean.h index 742af5098..13305dffe 100644 --- a/src/Mod/Part/App/FeaturePartBoolean.h +++ b/src/Mod/Part/App/FeaturePartBoolean.h @@ -27,6 +27,8 @@ #include #include "PartFeature.h" +class BRepAlgoAPI_BooleanOperation; + namespace Part { @@ -51,9 +53,13 @@ public: const char* getViewProviderName(void) const { return "PartGui::ViewProviderBoolean"; } + BRepAlgoAPI_BooleanOperation* getBooleanOperation() const { return myBoolOp; } protected: - virtual TopoDS_Shape runOperation(const TopoDS_Shape&, const TopoDS_Shape&) const = 0; + virtual BRepAlgoAPI_BooleanOperation* makeOperation(const TopoDS_Shape&, const TopoDS_Shape&) const = 0; + +private: + BRepAlgoAPI_BooleanOperation* myBoolOp; }; } diff --git a/src/Mod/Part/App/FeaturePartCommon.cpp b/src/Mod/Part/App/FeaturePartCommon.cpp index 828512bc3..1835cdfc1 100644 --- a/src/Mod/Part/App/FeaturePartCommon.cpp +++ b/src/Mod/Part/App/FeaturePartCommon.cpp @@ -41,14 +41,10 @@ Common::Common(void) { } -TopoDS_Shape Common::runOperation(const TopoDS_Shape& base, const TopoDS_Shape& tool) const +BRepAlgoAPI_BooleanOperation* Common::makeOperation(const TopoDS_Shape& base, const TopoDS_Shape& tool) const { // Let's call algorithm computing a section operation: - BRepAlgoAPI_Common mkCommon(base, tool); - // Let's check if the section has been successful - if (!mkCommon.IsDone()) - throw Base::Exception("Intersection failed"); - return mkCommon.Shape(); + return new BRepAlgoAPI_Common(base, tool); } // ---------------------------------------------------- diff --git a/src/Mod/Part/App/FeaturePartCommon.h b/src/Mod/Part/App/FeaturePartCommon.h index 295ec2e4f..19df8cdeb 100644 --- a/src/Mod/Part/App/FeaturePartCommon.h +++ b/src/Mod/Part/App/FeaturePartCommon.h @@ -41,7 +41,7 @@ public: //@{ /// recalculate the Feature protected: - TopoDS_Shape runOperation(const TopoDS_Shape&, const TopoDS_Shape&) const; + BRepAlgoAPI_BooleanOperation* makeOperation(const TopoDS_Shape&, const TopoDS_Shape&) const; //@} }; diff --git a/src/Mod/Part/App/FeaturePartCut.cpp b/src/Mod/Part/App/FeaturePartCut.cpp index 1d48c1783..6b6d792c5 100644 --- a/src/Mod/Part/App/FeaturePartCut.cpp +++ b/src/Mod/Part/App/FeaturePartCut.cpp @@ -40,12 +40,8 @@ Cut::Cut(void) { } -TopoDS_Shape Cut::runOperation(const TopoDS_Shape& base, const TopoDS_Shape& tool) const +BRepAlgoAPI_BooleanOperation* Cut::makeOperation(const TopoDS_Shape& base, const TopoDS_Shape& tool) const { // Let's call algorithm computing a cut operation: - BRepAlgoAPI_Cut mkCut(base, tool); - // Let's check if the cut has been successful - if (!mkCut.IsDone()) - throw Base::Exception("Cut failed"); - return mkCut.Shape(); + return new BRepAlgoAPI_Cut(base, tool); } diff --git a/src/Mod/Part/App/FeaturePartCut.h b/src/Mod/Part/App/FeaturePartCut.h index 63b0de61a..11187781c 100644 --- a/src/Mod/Part/App/FeaturePartCut.h +++ b/src/Mod/Part/App/FeaturePartCut.h @@ -42,7 +42,7 @@ public: //@{ /// recalculate the Feature protected: - TopoDS_Shape runOperation(const TopoDS_Shape&, const TopoDS_Shape&) const; + BRepAlgoAPI_BooleanOperation* makeOperation(const TopoDS_Shape&, const TopoDS_Shape&) const; //@} }; diff --git a/src/Mod/Part/App/FeaturePartFuse.cpp b/src/Mod/Part/App/FeaturePartFuse.cpp index d0f4a0e97..ea25450fc 100644 --- a/src/Mod/Part/App/FeaturePartFuse.cpp +++ b/src/Mod/Part/App/FeaturePartFuse.cpp @@ -41,14 +41,10 @@ Fuse::Fuse(void) { } -TopoDS_Shape Fuse::runOperation(const TopoDS_Shape& base, const TopoDS_Shape& tool) const +BRepAlgoAPI_BooleanOperation* Fuse::makeOperation(const TopoDS_Shape& base, const TopoDS_Shape& tool) const { // Let's call algorithm computing a fuse operation: - BRepAlgoAPI_Fuse mkFuse(base, tool); - // Let's check if the fusion has been successful - if (!mkFuse.IsDone()) - throw Base::Exception("Fusion failed"); - return mkFuse.Shape(); + return new BRepAlgoAPI_Fuse(base, tool); } // ---------------------------------------------------- diff --git a/src/Mod/Part/App/FeaturePartFuse.h b/src/Mod/Part/App/FeaturePartFuse.h index 251d7ec58..7e2e88d32 100644 --- a/src/Mod/Part/App/FeaturePartFuse.h +++ b/src/Mod/Part/App/FeaturePartFuse.h @@ -42,7 +42,7 @@ public: //@{ /// recalculate the Feature protected: - TopoDS_Shape runOperation(const TopoDS_Shape&, const TopoDS_Shape&) const; + BRepAlgoAPI_BooleanOperation* makeOperation(const TopoDS_Shape&, const TopoDS_Shape&) const; //@} }; diff --git a/src/Mod/Part/App/FeaturePartSection.cpp b/src/Mod/Part/App/FeaturePartSection.cpp index 6beb1eeef..55cd6da6e 100644 --- a/src/Mod/Part/App/FeaturePartSection.cpp +++ b/src/Mod/Part/App/FeaturePartSection.cpp @@ -39,12 +39,8 @@ Section::Section(void) { } -TopoDS_Shape Section::runOperation(const TopoDS_Shape& base, const TopoDS_Shape& tool) const +BRepAlgoAPI_BooleanOperation* Section::makeOperation(const TopoDS_Shape& base, const TopoDS_Shape& tool) const { // Let's call algorithm computing a section operation: - BRepAlgoAPI_Section mkSection(base, tool); - // Let's check if the section has been successful - if (!mkSection.IsDone()) - throw Base::Exception("Section failed"); - return mkSection.Shape(); + return new BRepAlgoAPI_Section(base, tool); } diff --git a/src/Mod/Part/App/FeaturePartSection.h b/src/Mod/Part/App/FeaturePartSection.h index 911c2a5b7..69ec64c92 100644 --- a/src/Mod/Part/App/FeaturePartSection.h +++ b/src/Mod/Part/App/FeaturePartSection.h @@ -42,7 +42,7 @@ public: //@{ /// recalculate the Feature protected: - TopoDS_Shape runOperation(const TopoDS_Shape&, const TopoDS_Shape&) const; + BRepAlgoAPI_BooleanOperation* makeOperation(const TopoDS_Shape&, const TopoDS_Shape&) const; //@} }; diff --git a/src/Mod/Part/Gui/ViewProviderBoolean.cpp b/src/Mod/Part/Gui/ViewProviderBoolean.cpp index 5857b2ef7..d35cd0dde 100644 --- a/src/Mod/Part/Gui/ViewProviderBoolean.cpp +++ b/src/Mod/Part/Gui/ViewProviderBoolean.cpp @@ -24,9 +24,15 @@ #include "PreCompiled.h" #ifndef _PreComp_ +# include +# include +# include +# include +# include #endif #include "ViewProviderBoolean.h" +#include #include #include #include @@ -71,6 +77,84 @@ QIcon ViewProviderBoolean::getIcon(void) const return ViewProviderPart::getIcon(); } +void findFaces(BRepAlgoAPI_BooleanOperation* mkBool, + const TopTools_IndexedMapOfShape& M1, + const TopTools_IndexedMapOfShape& M3, + const std::vector& colBase, + std::vector& colBool) +{ + for (int i=1; i<=M1.Extent(); i++) { + bool modified=false, generated=false; + TopTools_ListIteratorOfListOfShape it; + for (it.Initialize(mkBool->Modified(M1(i))); it.More(); it.Next()) { + modified = true; + for (int j=1; j<=M3.Extent(); j++) { + if (M3(j).IsPartner(it.Value())) { + colBool[j-1] = colBase[i-1]; + break; + } + } + } + + for (it.Initialize(mkBool->Generated(M1(i))); it.More(); it.Next()) { + generated = true; + for (int j=1; j<=M3.Extent(); j++) { + if (M3(j).IsPartner(it.Value())) { + colBool[j-1] = colBase[i-1]; + break; + } + } + } + + if (!modified && !generated && !mkBool->IsDeleted(M1(i))) { + for (int j=1; j<=M3.Extent(); j++) { + if (M3(j).IsPartner(M1(i))) { + colBool[j-1] = colBase[i-1]; + break; + } + } + } + } +} + +void ViewProviderBoolean::updateData(const App::Property* prop) +{ + PartGui::ViewProviderPart::updateData(prop); + if (prop->getTypeId() == Part::PropertyPartShape::getClassTypeId()) { + Part::Boolean* objBool = dynamic_cast(getObject()); + Part::Feature* objBase = dynamic_cast(objBool->Base.getValue()); + Part::Feature* objTool = dynamic_cast(objBool->Tool.getValue()); + + BRepAlgoAPI_BooleanOperation* mkBool = objBool->getBooleanOperation(); + if (mkBool && objBase && objTool) { + const TopoDS_Shape& baseShape = objBase->Shape.getValue(); + const TopoDS_Shape& toolShape = objTool->Shape.getValue(); + const TopoDS_Shape& boolShape = objBool->Shape.getValue(); + + TopTools_IndexedMapOfShape M1, M2, M3; + TopExp::MapShapes(baseShape, TopAbs_FACE, M1); + TopExp::MapShapes(toolShape, TopAbs_FACE, M2); + TopExp::MapShapes(boolShape, TopAbs_FACE, M3); + Gui::ViewProvider* vpBase = Gui::Application::Instance->getViewProvider(objBase); + Gui::ViewProvider* vpTool = Gui::Application::Instance->getViewProvider(objTool); + std::vector colBase = static_cast(vpBase)->DiffuseColor.getValues(); + std::vector colTool = static_cast(vpTool)->DiffuseColor.getValues(); + std::vector colBool; + colBool.resize(M3.Extent(), this->ShapeColor.getValue()); + bool applyColor=false; + if (colBase.size() == M1.Extent()) { + findFaces(mkBool, M1, M3, colBase, colBool); + applyColor = true; + } + if (colTool.size() == M2.Extent()) { + findFaces(mkBool, M2, M3, colTool, colBool); + applyColor = true; + } + if (applyColor) + this->DiffuseColor.setValues(colBool); + } + } +} PROPERTY_SOURCE(PartGui::ViewProviderMultiFuse,PartGui::ViewProviderPart) diff --git a/src/Mod/Part/Gui/ViewProviderBoolean.h b/src/Mod/Part/Gui/ViewProviderBoolean.h index 0fb245bb4..0a34127b1 100644 --- a/src/Mod/Part/Gui/ViewProviderBoolean.h +++ b/src/Mod/Part/Gui/ViewProviderBoolean.h @@ -42,6 +42,7 @@ public: /// grouping handling std::vector claimChildren(void) const; QIcon getIcon(void) const; + void updateData(const App::Property*); }; /// ViewProvider for the MultiFuse feature