Keep faces colors on boolean operations
This commit is contained in:
parent
b92f2117d1
commit
8c3f97c98e
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <BRepAlgoAPI_BooleanOperation.hxx>
|
||||
#include <memory>
|
||||
#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<BRepAlgoAPI_BooleanOperation> 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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include <App/PropertyLinks.h>
|
||||
#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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
//@}
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
//@}
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
//@}
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
//@}
|
||||
};
|
||||
|
||||
|
|
|
@ -24,9 +24,15 @@
|
|||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <BRepAlgoAPI_BooleanOperation.hxx>
|
||||
# include <TopExp.hxx>
|
||||
# include <TopTools_IndexedMapOfShape.hxx>
|
||||
# include <TopTools_ListOfShape.hxx>
|
||||
# include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
#endif
|
||||
|
||||
#include "ViewProviderBoolean.h"
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Mod/Part/App/FeaturePartBoolean.h>
|
||||
#include <Mod/Part/App/FeaturePartFuse.h>
|
||||
|
@ -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<App::Color>& colBase,
|
||||
std::vector<App::Color>& 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<Part::Boolean*>(getObject());
|
||||
Part::Feature* objBase = dynamic_cast<Part::Feature*>(objBool->Base.getValue());
|
||||
Part::Feature* objTool = dynamic_cast<Part::Feature*>(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<App::Color> colBase = static_cast<PartGui::ViewProviderPart*>(vpBase)->DiffuseColor.getValues();
|
||||
std::vector<App::Color> colTool = static_cast<PartGui::ViewProviderPart*>(vpTool)->DiffuseColor.getValues();
|
||||
std::vector<App::Color> 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)
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ public:
|
|||
/// grouping handling
|
||||
std::vector<App::DocumentObject*> claimChildren(void) const;
|
||||
QIcon getIcon(void) const;
|
||||
void updateData(const App::Property*);
|
||||
};
|
||||
|
||||
/// ViewProvider for the MultiFuse feature
|
||||
|
|
Loading…
Reference in New Issue
Block a user