From f1067fb269ba33446679b0cce28bc92a1f84f9ee Mon Sep 17 00:00:00 2001 From: azv Date: Mon, 6 May 2019 11:47:49 +0300 Subject: [PATCH] Fix regressions related to treating edges and faces in Boolean operations. --- src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp | 34 ++++++++++++++----- src/FeaturesPlugin/FeaturesPlugin_Boolean.h | 7 ++-- .../FeaturesPlugin_BooleanCommon.cpp | 6 ++-- .../FeaturesPlugin_BooleanCut.cpp | 6 ++-- .../FeaturesPlugin_BooleanFill.cpp | 6 ++-- .../FeaturesPlugin_BooleanFuse.cpp | 22 +++++++----- 6 files changed, 54 insertions(+), 27 deletions(-) diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp index 2220e4f06..7f9ce37ac 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp @@ -87,8 +87,7 @@ void FeaturesPlugin_Boolean::parentForShape(const GeomShapePtr& theShape, bool FeaturesPlugin_Boolean::processAttribute(const std::string& theAttributeName, ObjectHierarchy& theObjects, - ListOfShape& thePlanesList, - ListOfShape& theEdgesAndFaces) + ListOfShape& thePlanesList) { AttributeSelectionListPtr anObjectsSelList = selectionList(theAttributeName); for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) { @@ -105,12 +104,6 @@ bool FeaturesPlugin_Boolean::processAttribute(const std::string& theAttributeNam return false; } - if (anObject->shapeType() == GeomAPI_Shape::EDGE || - anObject->shapeType() == GeomAPI_Shape::FACE) { - theEdgesAndFaces.push_back(anObject); - continue; - } - theObjects.AddObject(anObject); ResultPtr aContext = anObjectAttr->context(); @@ -448,6 +441,31 @@ GeomShapePtr FeaturesPlugin_Boolean::ObjectHierarchy::Parent(const GeomShapePtr& return aParent; } +void FeaturesPlugin_Boolean::ObjectHierarchy::ObjectsByType( + ListOfShape& theShapesByType, + ListOfShape& theOtherShapes, + const GeomAPI_Shape::ShapeType theMinType, + const GeomAPI_Shape::ShapeType theMaxType) const +{ + if (theMinType > theMaxType) + return ObjectsByType(theShapesByType, theOtherShapes, theMaxType, theMinType); + + // no need to select objects if whole range is specified + if (theMinType == GeomAPI_Shape::COMPOUND && theMaxType == GeomAPI_Shape::SHAPE) { + theShapesByType.insert(theShapesByType.end(), myObjects.begin(), myObjects.end()); + return; + } + + for (ListOfShape::const_iterator anIt = myObjects.begin(); anIt != myObjects.end(); ++anIt) { + GeomAPI_Shape::ShapeType aType = (*anIt)->shapeType(); + if (aType >= theMinType && aType <= theMaxType) + theShapesByType.push_back(*anIt); + else + theOtherShapes.push_back(*anIt); + } +} + + void FeaturesPlugin_Boolean::ObjectHierarchy::SplitCompound(const GeomShapePtr& theCompShape, ListOfShape& theUsed, ListOfShape& theNotUsed) const diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.h b/src/FeaturesPlugin/FeaturesPlugin_Boolean.h index 14edc73b3..a72c3efe9 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.h @@ -112,6 +112,10 @@ protected: /// Return list of objects const ListOfShape& Objects() const { return myObjects; } + /// Separate objects of the given range of types and all other objects + void ObjectsByType(ListOfShape& theShapesByType, ListOfShape& theOtherShapes, + const GeomAPI_Shape::ShapeType theMinType = GeomAPI_Shape::COMPOUND, + const GeomAPI_Shape::ShapeType theMaxType = GeomAPI_Shape::SHAPE) const; public: class Iterator { @@ -142,8 +146,7 @@ protected: /// Process SelectionList attribute and fill the objects hierarchy. bool processAttribute(const std::string& theAttributeName, ObjectHierarchy& theObjects, - ListOfShape& thePlanesList, - ListOfShape& theEdgesAndFaces); + ListOfShape& thePlanesList); /// Perform Boolean operation of the object with the tools /// \return \c false if something went wrong diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp index 8506bc005..af2d556f1 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp @@ -54,7 +54,7 @@ void FeaturesPlugin_BooleanCommon::initAttributes() //================================================================================================== void FeaturesPlugin_BooleanCommon::execute() { - ListOfShape aPlanes, anEdgesAndFaces; + ListOfShape aPlanes; ObjectHierarchy anObjects, aTools; bool isSimpleMode = false; @@ -66,14 +66,14 @@ void FeaturesPlugin_BooleanCommon::execute() } // Getting objects. - if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes, anEdgesAndFaces)) + if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes)) return; // Planes are not supported as objects of COMMON operation aPlanes.clear(); // Getting tools. if (!isSimpleMode && - !processAttribute(TOOL_LIST_ID(), aTools, aPlanes, anEdgesAndFaces)) + !processAttribute(TOOL_LIST_ID(), aTools, aPlanes)) return; if (anObjects.IsEmpty() || (!isSimpleMode && aTools.IsEmpty() && aPlanes.empty())) { diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp index e6ba621a4..be93d26ec 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp @@ -45,11 +45,11 @@ FeaturesPlugin_BooleanCut::FeaturesPlugin_BooleanCut() void FeaturesPlugin_BooleanCut::execute() { ObjectHierarchy anObjects, aTools; - ListOfShape aPlanes, anEdgesAndFaces; + ListOfShape aPlanes; // Getting objects and tools - if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes, anEdgesAndFaces) || - !processAttribute(TOOL_LIST_ID(), aTools, aPlanes, anEdgesAndFaces)) + if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes) || + !processAttribute(TOOL_LIST_ID(), aTools, aPlanes)) return; int aResultIndex = 0; diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp index 1088fd820..a907823ad 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp @@ -51,16 +51,16 @@ void FeaturesPlugin_BooleanFill::execute() { std::string anError; ObjectHierarchy anObjects, aTools; - ListOfShape aPlanes, anEdgesAndFaces; + ListOfShape aPlanes; // Getting objects. - if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes, anEdgesAndFaces)) + if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes)) return; // Planes are not supported as objects of FILL operation aPlanes.clear(); // Getting tools. - if (!processAttribute(TOOL_LIST_ID(), aTools, aPlanes, anEdgesAndFaces)) + if (!processAttribute(TOOL_LIST_ID(), aTools, aPlanes)) return; int aResultIndex = 0; diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp index 83fb86895..497d529e4 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp @@ -62,7 +62,7 @@ void FeaturesPlugin_BooleanFuse::execute() { std::string anError; ObjectHierarchy anObjectsHierarchy, aToolsHierarchy; - ListOfShape aPlanes, anEdgesAndFaces; + ListOfShape aPlanes; bool isSimpleCreation = false; @@ -74,16 +74,20 @@ void FeaturesPlugin_BooleanFuse::execute() } // Getting objects. - if (!processAttribute(OBJECT_LIST_ID(), anObjectsHierarchy, aPlanes, anEdgesAndFaces)) + if (!processAttribute(OBJECT_LIST_ID(), anObjectsHierarchy, aPlanes)) return; // Getting tools. if (!isSimpleCreation && - !processAttribute(TOOL_LIST_ID(), aToolsHierarchy, aPlanes, anEdgesAndFaces)) + !processAttribute(TOOL_LIST_ID(), aToolsHierarchy, aPlanes)) return; - ListOfShape anObjects = anObjectsHierarchy.Objects(); - ListOfShape aTools = aToolsHierarchy.Objects(); + ListOfShape anObjects, aTools, anEdgesAndFaces; + // all objects except edges and faces + anObjectsHierarchy.ObjectsByType(anEdgesAndFaces, anObjects, + GeomAPI_Shape::FACE, GeomAPI_Shape::EDGE); + aToolsHierarchy.ObjectsByType(anEdgesAndFaces, aTools, + GeomAPI_Shape::FACE, GeomAPI_Shape::EDGE); if ((anObjects.size() + aTools.size() + anEdgesAndFaces.size()) < 2) { std::string aFeatureError = "Error: Not enough objects for boolean operation."; @@ -106,6 +110,9 @@ void FeaturesPlugin_BooleanFuse::execute() GeomShapePtr aParent = anObjectsHierarchy.Parent(anObject, false); if (aParent && aParent->shapeType() == GeomAPI_Shape::COMPSOLID) { + // mark all subs of this parent as precessed to avoid handling twice + aParent = anObjectsHierarchy.Parent(anObject); + ListOfShape aUsed, aNotUsed; anObjectsHierarchy.SplitCompound(aParent, aUsed, aNotUsed); aShapesToAdd.insert(aShapesToAdd.end(), aNotUsed.begin(), aNotUsed.end()); @@ -126,6 +133,8 @@ void FeaturesPlugin_BooleanFuse::execute() aMakeShapeList->appendAlgo(aCutAlgo); } } + anOriginalShapes.insert(anOriginalShapes.end(), anEdgesAndFaces.begin(), + anEdgesAndFaces.end()); // If we have compsolids then cut with not used solids all others. if (!aShapesToAdd.empty()) { @@ -144,9 +153,6 @@ void FeaturesPlugin_BooleanFuse::execute() } } - anOriginalShapes.insert(anOriginalShapes.end(), anEdgesAndFaces.begin(), - anEdgesAndFaces.end()); - if (!aSolidsToFuse.empty()) { anObjects.clear(); anObjects.push_back(aSolidsToFuse.back()); -- 2.39.2