From 1ca6bc647dcecfbd22beb5c8991f06545bf7614e Mon Sep 17 00:00:00 2001 From: azv Date: Fri, 26 Apr 2019 10:31:10 +0300 Subject: [PATCH] Refactor Boolean operations in FeaturesPlugin. --- src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp | 426 ++++++++++++++++++ src/FeaturesPlugin/FeaturesPlugin_Boolean.h | 107 +++++ .../FeaturesPlugin_BooleanCommon.cpp | 341 ++------------ .../FeaturesPlugin_BooleanCut.cpp | 290 ++---------- .../FeaturesPlugin_BooleanFill.cpp | 242 ++-------- .../FeaturesPlugin_BooleanFuse.cpp | 6 +- .../FeaturesPlugin_BooleanSmash.cpp | 6 +- .../FeaturesPlugin_CompositeBoolean.cpp | 10 +- .../FeaturesPlugin_Partition.cpp | 7 +- src/FeaturesPlugin/FeaturesPlugin_Union.cpp | 2 +- src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp | 14 +- src/GeomAlgoAPI/GeomAlgoAPI_Boolean.h | 17 +- src/GeomAlgoAPI/GeomAlgoAPI_Tools.h | 7 + 13 files changed, 677 insertions(+), 798 deletions(-) diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp index b768b90af..d466d1a13 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp @@ -30,11 +30,13 @@ #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -68,6 +70,48 @@ FeaturesPlugin_Boolean::OperationType FeaturesPlugin_Boolean::operationType() return myOperationType; } +//================================================================================================= +void FeaturesPlugin_Boolean::parentForShape(const GeomShapePtr& theShape, + const ResultPtr& theContext, + ObjectHierarchy& theShapesHierarchy) +{ + ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(theContext); + if (aResCompSolidPtr.get()) { + std::shared_ptr aContextShape = aResCompSolidPtr->shape(); + if (aContextShape->shapeType() <= GeomAPI_Shape::COMPSOLID) { + theShapesHierarchy.AddParent(theShape, aContextShape); + parentForShape(aContextShape, aResCompSolidPtr, theShapesHierarchy); + } + } +} + +bool FeaturesPlugin_Boolean::processAttribute(const std::string& theAttributeName, + ObjectHierarchy& theObjects, + ListOfShape& thePlanesList) +{ + AttributeSelectionListPtr anObjectsSelList = selectionList(theAttributeName); + for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) { + AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex); + GeomShapePtr anObject = anObjectAttr->value(); + if (!anObject.get()) { + // It could be a construction plane. + ResultPtr aContext = anObjectAttr->context(); + anObject = anObjectAttr->context()->shape(); + if (anObject.get()) { + thePlanesList.push_back(anObject); + continue; + } else + return false; + } + + theObjects.AddObject(anObject); + + ResultPtr aContext = anObjectAttr->context(); + parentForShape(anObject, aContext, theObjects); + } + return true; +} + //================================================================================================= void FeaturesPlugin_Boolean::loadNamingDS(std::shared_ptr theResultBody, const std::shared_ptr theBaseShape, @@ -100,3 +144,385 @@ void FeaturesPlugin_Boolean::loadNamingDS(std::shared_ptr t theResultBody->loadDeletedShapes(theMakeShape, *anIter, GeomAPI_Shape::FACE); } } + +//================================================================================================= +bool FeaturesPlugin_Boolean::processObject( + const GeomAlgoAPI_Tools::BOPType theBooleanType, + const GeomShapePtr& theObject, + const ListOfShape& theTools, + const ListOfShape& thePlanes, + int& theResultIndex, + std::vector& theResultBaseAlgoList, + ListOfShape& theResultShapesList) +{ + ListOfShape aListWithObject; + aListWithObject.push_back(theObject); + std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); + std::shared_ptr aBoolAlgo; + GeomShapePtr aResShape; + + std::list > aBoundingPoints = + GeomAlgoAPI_ShapeTools::getBoundingBox(aListWithObject, 1.0); + + // Resize planes. + ListOfShape aToolsWithPlanes = theTools; + for (ListOfShape::const_iterator anIt = thePlanes.begin(); anIt != thePlanes.end(); ++anIt) { + GeomShapePtr aPlane = *anIt; + GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints); + std::shared_ptr aMkShCustom( + new GeomAlgoAPI_MakeShapeCustom); + aMkShCustom->addModified(aPlane, aTool); + aMakeShapeList->appendAlgo(aMkShCustom); + aToolsWithPlanes.push_back(aTool); + } + + if (theBooleanType == GeomAlgoAPI_Tools::BOOL_PARTITION) + aBoolAlgo.reset(new GeomAlgoAPI_Partition(aListWithObject, aToolsWithPlanes)); + else + aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aListWithObject, + aToolsWithPlanes, + theBooleanType)); + + // Checking that the algorithm worked properly. + std::string anError; + if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aBoolAlgo, getKind(), anError)) { + setError(anError); + return false; + } + + aResShape = aBoolAlgo->shape(); + if (aResShape.get() && aResShape->shapeType() == GeomAPI_Shape::COMPOUND) { + int aSubResultsNb = 0; + GeomAPI_ShapeIterator anIt(aResShape); + for (; anIt.more(); anIt.next()) + ++aSubResultsNb; + + if (aSubResultsNb == 1) { + anIt.init(aResShape); + if (anIt.more()) + aResShape = anIt.current(); + } + } + + aMakeShapeList->appendAlgo(aBoolAlgo); + + GeomAPI_ShapeIterator aShapeIt(aResShape); + if (aShapeIt.more() || aResShape->shapeType() == GeomAPI_Shape::VERTEX) { + std::shared_ptr aResultBody = + document()->createBody(data(), theResultIndex); + + ListOfShape aUsedTools = theTools; + aUsedTools.insert(aUsedTools.end(), thePlanes.begin(), thePlanes.end()); + + FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, + aListWithObject, + aUsedTools, + aMakeShapeList, + aResShape); + setResult(aResultBody, theResultIndex); + ++theResultIndex; + + FeaturesPlugin_Tools::ResultBaseAlgo aRBA; + aRBA.resultBody = aResultBody; + aRBA.baseShape = theObject; + aRBA.makeShape = aMakeShapeList; + theResultBaseAlgoList.push_back(aRBA); + theResultShapesList.push_back(aResShape); + } + return true; +} + +//================================================================================================= +bool FeaturesPlugin_Boolean::processCompsolid( + const GeomAlgoAPI_Tools::BOPType theBooleanType, + const ObjectHierarchy& theCompsolidHierarchy, + const GeomShapePtr& theCompsolid, + const ListOfShape& theTools, + const ListOfShape& thePlanes, + int& theResultIndex, + std::vector& theResultBaseAlgoList, + ListOfShape& theResultShapesList) +{ + ListOfShape aUsedInOperationSolids; + ListOfShape aNotUsedSolids; + theCompsolidHierarchy.SplitCompound(theCompsolid, aUsedInOperationSolids, aNotUsedSolids); + + std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); + + std::list > aBoundingPoints = + GeomAlgoAPI_ShapeTools::getBoundingBox(aUsedInOperationSolids, 1.0); + + // Resize planes. + ListOfShape aToolsWithPlanes = theTools; + for (ListOfShape::const_iterator anIt = thePlanes.begin(); anIt != thePlanes.end(); ++anIt) + { + GeomShapePtr aPlane = *anIt; + GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints); + std::shared_ptr aMkShCustom( + new GeomAlgoAPI_MakeShapeCustom); + aMkShCustom->addModified(aPlane, aTool); + aMakeShapeList->appendAlgo(aMkShCustom); + aToolsWithPlanes.push_back(aTool); + } + + std::shared_ptr aBoolAlgo; + if (theBooleanType == GeomAlgoAPI_Tools::BOOL_PARTITION) + aBoolAlgo.reset(new GeomAlgoAPI_Partition(aUsedInOperationSolids, aToolsWithPlanes)); + else + aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aUsedInOperationSolids, + aToolsWithPlanes, + theBooleanType)); + + // Checking that the algorithm worked properly. + std::string anError; + if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aBoolAlgo, getKind(), anError)) { + setError(anError); + return false; + } + + aMakeShapeList->appendAlgo(aBoolAlgo); + GeomShapePtr aResultShape = aBoolAlgo->shape(); + + // Add result to not used solids from compsolid. + if (!aNotUsedSolids.empty()) { + ListOfShape aShapesToAdd = aNotUsedSolids; + aShapesToAdd.push_back(aBoolAlgo->shape()); + std::shared_ptr aFillerAlgo( + new GeomAlgoAPI_PaveFiller(aShapesToAdd, true)); + if (!aFillerAlgo->isDone()) { + std::string aFeatureError = "Error: PaveFiller algorithm failed."; + setError(aFeatureError); + return false; + } + + aMakeShapeList->appendAlgo(aFillerAlgo); + aResultShape = aFillerAlgo->shape(); + } + + GeomAPI_ShapeIterator aShapeIt(aResultShape); + if (aShapeIt.more() || aResultShape->shapeType() == GeomAPI_Shape::VERTEX) + { + std::shared_ptr aResultBody = + document()->createBody(data(), theResultIndex); + + ListOfShape aCompSolidList; + aCompSolidList.push_back(theCompsolid); + + ListOfShape aUsedTools = theTools; + aUsedTools.insert(aUsedTools.end(), thePlanes.begin(), thePlanes.end()); + + FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, + aCompSolidList, + aUsedTools, + aMakeShapeList, + aResultShape); + setResult(aResultBody, theResultIndex); + ++theResultIndex; + + FeaturesPlugin_Tools::ResultBaseAlgo aRBA; + aRBA.resultBody = aResultBody; + aRBA.baseShape = theCompsolid; + aRBA.makeShape = aMakeShapeList; + theResultBaseAlgoList.push_back(aRBA); + theResultShapesList.push_back(aResultShape); + } + return true; +} + +//================================================================================================= +bool FeaturesPlugin_Boolean::processCompound( + const GeomAlgoAPI_Tools::BOPType theBooleanType, + const ObjectHierarchy& theCompoundHierarchy, + const GeomShapePtr& theCompound, + const ListOfShape& theTools, + int& theResultIndex, + std::vector& theResultBaseAlgoList, + ListOfShape& theResultShapesList) +{ + ListOfShape aUsedInOperationShapes; + ListOfShape aNotUsedShapes; + theCompoundHierarchy.SplitCompound(theCompound, aUsedInOperationShapes, aNotUsedShapes); + + std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); + std::shared_ptr aBoolAlgo( + new GeomAlgoAPI_Boolean(aUsedInOperationShapes, + theTools, + theBooleanType)); + + // Checking that the algorithm worked properly. + std::string anError; + if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aBoolAlgo, getKind(), anError)) { + setError(anError); + return false; + } + + aMakeShapeList->appendAlgo(aBoolAlgo); + GeomShapePtr aResultShape = aBoolAlgo->shape(); + + // Add result to not used shape from compound. + if (!aNotUsedShapes.empty()) { + ListOfShape aShapesForResult = aNotUsedShapes; + if (aResultShape->shapeType() == GeomAPI_Shape::COMPOUND) { + for (GeomAPI_ShapeIterator aResultIt(aResultShape); aResultIt.more(); aResultIt.next()) { + aShapesForResult.push_back(aResultIt.current()); + } + } + else { + aShapesForResult.push_back(aResultShape); + } + + if (aShapesForResult.size() == 1) { + aResultShape = aShapesForResult.front(); + } + else { + aResultShape = GeomAlgoAPI_CompoundBuilder::compound(aShapesForResult); + } + } + + GeomAPI_ShapeIterator aShapeIt(aResultShape); + if (aShapeIt.more() || aResultShape->shapeType() == GeomAPI_Shape::VERTEX) { + std::shared_ptr aResultBody = + document()->createBody(data(), theResultIndex); + + ListOfShape aCompoundList; + aCompoundList.push_back(theCompound); + FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, + aCompoundList, + theTools, + aMakeShapeList, + aResultShape); + setResult(aResultBody, theResultIndex); + ++theResultIndex; + + FeaturesPlugin_Tools::ResultBaseAlgo aRBA; + aRBA.resultBody = aResultBody; + aRBA.baseShape = theCompound; + aRBA.makeShape = aMakeShapeList; + theResultBaseAlgoList.push_back(aRBA); + theResultShapesList.push_back(aResultShape); + } + return true; +} + +//================================================================================================= + +void FeaturesPlugin_Boolean::ObjectHierarchy::AddObject(const GeomShapePtr& theObject) +{ + myObjects.push_back(theObject); +} + +void FeaturesPlugin_Boolean::ObjectHierarchy::AddParent(const GeomShapePtr& theShape, + const GeomShapePtr& theParent) +{ + myParent[theShape] = theParent; + mySubshapes[theParent].push_back(theShape); +} + +GeomShapePtr FeaturesPlugin_Boolean::ObjectHierarchy::Parent(const GeomShapePtr& theShape, + bool theMarkProcessed) +{ + MapShapeToParent::const_iterator aFound = myParent.find(theShape); + GeomShapePtr aParent; + if (aFound != myParent.end()) { + aParent = aFound->second; + if (theMarkProcessed) { + // mark the parent and all its subs as processed by Boolean algorithm + myProcessedObjects.insert(aParent); + const ListOfShape& aSubs = mySubshapes[aParent]; + for (ListOfShape::const_iterator anIt = aSubs.begin(); anIt != aSubs.end(); ++anIt) + myProcessedObjects.insert(*anIt); + } + } + return aParent; +} + +void FeaturesPlugin_Boolean::ObjectHierarchy::SplitCompound(const GeomShapePtr& theCompShape, + ListOfShape& theUsed, + ListOfShape& theNotUsed) const +{ + theUsed.clear(); + theNotUsed.clear(); + + const ListOfShape& aSubs = mySubshapes.find(theCompShape)->second; + SetOfShape aSubsSet; + aSubsSet.insert(aSubs.begin(), aSubs.end()); + + for (GeomAPI_ShapeExplorer anExp(theCompShape, GeomAPI_Shape::SOLID); + anExp.more(); anExp.next()) { + GeomShapePtr aCurrent = anExp.current(); + if (aSubsSet.find(aCurrent) == aSubsSet.end()) + theNotUsed.push_back(aCurrent); + else + theUsed.push_back(aCurrent); + } +} + +bool FeaturesPlugin_Boolean::ObjectHierarchy::IsEmpty() const +{ + return myObjects.empty(); +} + +FeaturesPlugin_Boolean::ObjectHierarchy::Iterator FeaturesPlugin_Boolean::ObjectHierarchy::Begin() +{ + return Iterator(this); +} + +FeaturesPlugin_Boolean::ObjectHierarchy::Iterator FeaturesPlugin_Boolean::ObjectHierarchy::End() +{ + return Iterator(this, false); +} + +FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::Iterator( + FeaturesPlugin_Boolean::ObjectHierarchy* theHierarchy, bool isBegin) + : myHierarchy(theHierarchy) +{ + if (isBegin) { + myObject = myHierarchy->myObjects.begin(); + SkipAlreadyProcessed(); + } else + myObject = myHierarchy->myObjects.end(); +} + +void FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::SkipAlreadyProcessed() +{ + while (myObject != myHierarchy->myObjects.end() && + myHierarchy->myProcessedObjects.find(*myObject) != myHierarchy->myProcessedObjects.end()) + ++myObject; +} + +bool FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::operator==(const Iterator& theOther) const +{ + return myObject == theOther.myObject; +} + +bool FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::operator!=(const Iterator& theOther) const +{ + return !operator==(theOther); +} + +FeaturesPlugin_Boolean::ObjectHierarchy::Iterator& +FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::operator++() +{ + ++myObject; + SkipAlreadyProcessed(); + return *this; +} + +FeaturesPlugin_Boolean::ObjectHierarchy::Iterator +FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::operator++(int) +{ + Iterator aCurrent; + aCurrent.myHierarchy = myHierarchy; + aCurrent.myObject = myObject; + + // increase iterator + operator++(); + + return aCurrent; +} + +GeomShapePtr FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::operator*() const +{ + myHierarchy->myProcessedObjects.insert(*myObject); + return *myObject; +} diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.h b/src/FeaturesPlugin/FeaturesPlugin_Boolean.h index 38c8a57ee..63185b172 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.h @@ -21,11 +21,15 @@ #define FeaturesPlugin_Boolean_H_ #include "FeaturesPlugin.h" +#include "FeaturesPlugin_Tools.h" #include +#include #include +class ModelAPI_Result; + /// \class FeaturesPlugin_Boolean /// \ingroup Plugins /// \brief Feature for applying of Boolean operations on Solids. @@ -73,6 +77,109 @@ protected: const std::shared_ptr theResultShape, const GeomMakeShapePtr& theMakeShape); + + /// Auxiliary class to store hierarchy of Boolean operation objects/tools + /// and their parent shapes (compounds or compsolids) + class ObjectHierarchy { + typedef std::map MapShapeToSubshapes; + typedef std::map MapShapeToParent; + typedef std::set SetOfShape; + + ListOfShape myObjects; + MapShapeToParent myParent; + MapShapeToSubshapes mySubshapes; + + SetOfShape myProcessedObjects; + + public: + /// Add object of Boolean opration + void AddObject(const GeomShapePtr& theObject); + + /// Maps shape and its parent + void AddParent(const GeomShapePtr& theShape, const GeomShapePtr& theParent); + + /// Return parent shape for the given, or empty if it is a high-level shape. + /// By default, the parent and all its subshapes are marked as processed for further skip. + GeomShapePtr Parent(const GeomShapePtr& theShape, bool theMarkProcessed = true); + + /// Split compound/compsolid shape for subshapes selected for Boolean operation and the other. + void SplitCompound(const GeomShapePtr& theCompShape, + ListOfShape& theUsed, + ListOfShape& theNotUsed) const; + + /// Return \c true if there is no object in hierarchy + bool IsEmpty() const; + + /// Return list of objects + const ListOfShape& Objects() const { return myObjects; } + + public: + class Iterator { + friend class ObjectHierarchy; + + ObjectHierarchy* myHierarchy; + ListOfShape::iterator myObject; + + Iterator() {} + Iterator(ObjectHierarchy* theHierarchy, bool isBegin = true); + + void SkipAlreadyProcessed(); + + public: + bool operator==(const Iterator&) const; + bool operator!=(const Iterator&) const; + + Iterator& operator++(); + Iterator operator++(int); + + GeomShapePtr operator*() const; + }; + + Iterator Begin(); + Iterator End(); + }; + + /// Process SelectionList attribute and fill the objects hierarchy. + bool processAttribute(const std::string& theAttributeName, + ObjectHierarchy& theObjects, + ListOfShape& thePlanesList); + + /// Perform Boolean operation of the object with the tools + /// \return \c false if something went wrong + bool processObject(const GeomAlgoAPI_Tools::BOPType theBooleanType, + const GeomShapePtr& theObject, + const ListOfShape& theTools, + const ListOfShape& thePlanes, + int& theResultIndex, + std::vector& theResultBaseAlgoList, + ListOfShape& theResultShapesList); + + /// Perform Boolean operation of the Compsolid with the tools + /// \return \c false if something went wrong + bool processCompsolid(const GeomAlgoAPI_Tools::BOPType theBooleanType, + const ObjectHierarchy& theCompsolidHierarchy, + const GeomShapePtr& theCompsolid, + const ListOfShape& theTools, + const ListOfShape& thePlanes, + int& theResultIndex, + std::vector& theResultBaseAlgoList, + ListOfShape& theResultShapesList); + + /// Perform Boolean operation of the Compound with the tools + /// \return \c false if something went wrong + bool processCompound(const GeomAlgoAPI_Tools::BOPType theBooleanType, + const ObjectHierarchy& theCompoundHierarchy, + const GeomShapePtr& theCompound, + const ListOfShape& theTools, + int& theResultIndex, + std::vector& theResultBaseAlgoList, + ListOfShape& theResultShapesList); + +private: + void parentForShape(const GeomShapePtr& theShape, + const std::shared_ptr& theContext, + ObjectHierarchy& theShapesHierarchy); + private: OperationType myOperationType; }; diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp index eb23d0bab..af2d556f1 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp @@ -19,8 +19,6 @@ #include "FeaturesPlugin_BooleanCommon.h" -#include "FeaturesPlugin_Tools.h" - #include #include #include @@ -56,9 +54,8 @@ void FeaturesPlugin_BooleanCommon::initAttributes() //================================================================================================== void FeaturesPlugin_BooleanCommon::execute() { - ListOfShape anObjects, aTools, aPlanes; - std::map, ListOfShape> aCompSolidsObjects; - std::map, ListOfShape> aCompoundObjects; + ListOfShape aPlanes; + ObjectHierarchy anObjects, aTools; bool isSimpleMode = false; @@ -69,59 +66,17 @@ void FeaturesPlugin_BooleanCommon::execute() } // Getting objects. - AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECT_LIST_ID()); - for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) { - AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex); - std::shared_ptr anObject = anObjectAttr->value(); - if (!anObject.get()) { - return; - } - ResultPtr aContext = anObjectAttr->context(); - ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext); - if (!isSimpleMode - && aResCompSolidPtr.get()) - { - std::shared_ptr aContextShape = aResCompSolidPtr->shape(); - GeomAPI_Shape::ShapeType aShapeType = aResCompSolidPtr->shape()->shapeType(); - std::map, ListOfShape>& aMap = - aShapeType == GeomAPI_Shape::COMPSOLID ? aCompSolidsObjects : aCompoundObjects; - - std::map, ListOfShape>::iterator - anIt = aMap.begin(); - for (; anIt != aMap.end(); anIt++) { - if (anIt->first->isEqual(aContextShape)) { - aMap[anIt->first].push_back(anObject); - break; - } - } - if (anIt == aMap.end()) { - aMap[aContextShape].push_back(anObject); - } - - } - else { - anObjects.push_back(anObject); - } - } + if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes)) + return; + // Planes are not supported as objects of COMMON operation + aPlanes.clear(); // Getting tools. - if (!isSimpleMode) { - AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Boolean::TOOL_LIST_ID()); - for (int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) { - AttributeSelectionPtr aToolAttr = aToolsSelList->value(aToolsIndex); - GeomShapePtr aTool = aToolAttr->value(); - if (!aTool.get()) { - // It could be a construction plane. - ResultPtr aContext = aToolAttr->context(); - aPlanes.push_back(aToolAttr->context()->shape()); - } else { - aTools.push_back(aTool); - } - } - } + if (!isSimpleMode && + !processAttribute(TOOL_LIST_ID(), aTools, aPlanes)) + return; - if ((anObjects.empty() && aCompSolidsObjects.empty() && aCompoundObjects.empty()) - || (!isSimpleMode && aTools.empty() && aPlanes.empty())) { + if (anObjects.IsEmpty() || (!isSimpleMode && aTools.IsEmpty() && aPlanes.empty())) { std::string aFeatureError = "Error: Not enough objects for boolean operation."; setError(aFeatureError); return; @@ -133,15 +88,14 @@ void FeaturesPlugin_BooleanCommon::execute() std::vector aResultBaseAlgoList; ListOfShape aResultShapesList; - if (isSimpleMode) - { - ListOfShape::iterator anObjectsIt = anObjects.begin(); + if (isSimpleMode) { + ObjectHierarchy::Iterator anObjectsIt = anObjects.Begin(); GeomShapePtr aShape = *anObjectsIt; - for (++anObjectsIt; anObjectsIt != anObjects.end(); ++anObjectsIt) { + for (++anObjectsIt; anObjectsIt != anObjects.End(); ++anObjectsIt) { std::shared_ptr aCommonAlgo( new GeomAlgoAPI_Boolean(aShape, *anObjectsIt, - GeomAlgoAPI_Boolean::BOOL_COMMON)); + GeomAlgoAPI_Tools::BOOL_COMMON)); if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCommonAlgo, getKind(), anError)) { setError(anError); @@ -157,18 +111,19 @@ void FeaturesPlugin_BooleanCommon::execute() std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); - ListOfShape anEmptyTools; + ListOfShape anObjectList = anObjects.Objects(); + ListOfShape aToolsList; FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, - anObjects, - anEmptyTools, + anObjectList, + aToolsList, aMakeShapeList, aShape); - GeomShapePtr aBaseShape = anObjects.front(); - anObjects.pop_front(); + GeomShapePtr aBaseShape = anObjectList.front(); + anObjectList.pop_front(); setResult(aResultBody, aResultIndex); aResultIndex++; - aTools = anObjects; + aToolsList = anObjectList; FeaturesPlugin_Tools::ResultBaseAlgo aRBA; aRBA.resultBody = aResultBody; aRBA.baseShape = aBaseShape; @@ -177,245 +132,43 @@ void FeaturesPlugin_BooleanCommon::execute() aResultShapesList.push_back(aShape); } } else { - for (ListOfShape::iterator anObjectsIt = anObjects.begin(); - anObjectsIt != anObjects.end(); + bool isOk = true; + for (ObjectHierarchy::Iterator anObjectsIt = anObjects.Begin(); + anObjectsIt != anObjects.End() && isOk; ++anObjectsIt) { - std::shared_ptr anObject = *anObjectsIt; - ListOfShape aListWithObject; - aListWithObject.push_back(anObject); - std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); - std::shared_ptr aBoolAlgo; - GeomShapePtr aResShape; - - std::list > aBoundingPoints = - GeomAlgoAPI_ShapeTools::getBoundingBox(aListWithObject, 1.0); - - // Resize planes. - ListOfShape aToolsWithPlanes = aTools; - for (ListOfShape::const_iterator anIt = aPlanes.cbegin(); - anIt != aPlanes.cend(); - ++anIt) { - GeomShapePtr aPlane = *anIt; - GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints); - std::shared_ptr aMkShCustom( - new GeomAlgoAPI_MakeShapeCustom); - aMkShCustom->addModified(aPlane, aTool); - aMakeShapeList->appendAlgo(aMkShCustom); - aToolsWithPlanes.push_back(aTool); - } - - aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aListWithObject, - aToolsWithPlanes, - GeomAlgoAPI_Boolean::BOOL_COMMON)); - aResShape = aBoolAlgo->shape(); - - // Checking that the algorithm worked properly. - if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aBoolAlgo, getKind(), anError)) { - setError(anError); - return; - } - - aMakeShapeList->appendAlgo(aBoolAlgo); - - GeomAPI_ShapeIterator aShapeIt(aResShape); - if (aShapeIt.more() || aResShape->shapeType() == GeomAPI_Shape::VERTEX) { - std::shared_ptr aResultBody = - document()->createBody(data(), aResultIndex); - ListOfShape anObjectList; - anObjectList.push_back(anObject); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, - anObjectList, - aTools, - aMakeShapeList, - aResShape); - setResult(aResultBody, aResultIndex); - aResultIndex++; - - FeaturesPlugin_Tools::ResultBaseAlgo aRBA; - aRBA.resultBody = aResultBody; - aRBA.baseShape = anObject; - aRBA.makeShape = aMakeShapeList; - aResultBaseAlgoList.push_back(aRBA); - aResultShapesList.push_back(aResShape); - } - } - - // Compsolids handling - for (std::map, ListOfShape>::iterator - anIt = aCompSolidsObjects.begin(); - anIt != aCompSolidsObjects.end(); - ++anIt) - { - std::shared_ptr aCompSolid = anIt->first; - ListOfShape& aUsedInOperationSolids = anIt->second; - - // Collecting solids from compsolids which will not be modified in boolean operation. - ListOfShape aNotUsedSolids; - for (GeomAPI_ShapeExplorer anExp(aCompSolid, GeomAPI_Shape::SOLID); - anExp.more(); - anExp.next()) - { - std::shared_ptr aSolidInCompSolid = anExp.current(); - ListOfShape::iterator aUsedIt = aUsedInOperationSolids.begin(); - for (; aUsedIt != aUsedInOperationSolids.end(); aUsedIt++) { - if (aSolidInCompSolid->isEqual(*aUsedIt)) { - break; - } + GeomShapePtr anObject = *anObjectsIt; + GeomShapePtr aParent = anObjects.Parent(anObject); + + if (aParent) { + GeomAPI_Shape::ShapeType aShapeType = aParent->shapeType(); + if (aShapeType == GeomAPI_Shape::COMPOUND) { + // Compound handling + isOk = processCompound(GeomAlgoAPI_Tools::BOOL_COMMON, + anObjects, aParent, aTools.Objects(), + aResultIndex, aResultBaseAlgoList, aResultShapesList); } - if (aUsedIt == aUsedInOperationSolids.end()) { - aNotUsedSolids.push_back(aSolidInCompSolid); + else if (aShapeType == GeomAPI_Shape::COMPSOLID) { + // Compsolid handling + isOk = processCompsolid(GeomAlgoAPI_Tools::BOOL_COMMON, + anObjects, aParent, aTools.Objects(), ListOfShape(), + aResultIndex, aResultBaseAlgoList, aResultShapesList); } - } - - std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); - std::shared_ptr aCommonAlgo( - new GeomAlgoAPI_Boolean(aUsedInOperationSolids, - aTools, - GeomAlgoAPI_Boolean::BOOL_COMMON)); - - // Checking that the algorithm worked properly. - if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCommonAlgo, getKind(), anError)) { - setError(anError); - return; - } - - aMakeShapeList->appendAlgo(aCommonAlgo); - GeomShapePtr aResultShape = aCommonAlgo->shape(); - - // Add result to not used solids from compsolid. - if (!aNotUsedSolids.empty()) { - ListOfShape aShapesToAdd = aNotUsedSolids; - aShapesToAdd.push_back(aCommonAlgo->shape()); - std::shared_ptr aFillerAlgo( - new GeomAlgoAPI_PaveFiller(aShapesToAdd, true)); - if (!aFillerAlgo->isDone()) { - std::string aFeatureError = "Error: PaveFiller algorithm failed."; - setError(aFeatureError); - return; - } - - aMakeShapeList->appendAlgo(aFillerAlgo); - aResultShape = aFillerAlgo->shape(); - } - - GeomAPI_ShapeIterator aShapeIt(aResultShape); - if (aShapeIt.more() || aResultShape->shapeType() == GeomAPI_Shape::VERTEX) - { - std::shared_ptr aResultBody = - document()->createBody(data(), aResultIndex); - - ListOfShape aCompSolidList; - aCompSolidList.push_back(aCompSolid); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, - aCompSolidList, - aTools, - aMakeShapeList, - aResultShape); - setResult(aResultBody, aResultIndex); - aResultIndex++; - - FeaturesPlugin_Tools::ResultBaseAlgo aRBA; - aRBA.resultBody = aResultBody; - aRBA.baseShape = aCompSolid; - aRBA.makeShape = aMakeShapeList; - aResultBaseAlgoList.push_back(aRBA); - aResultShapesList.push_back(aResultShape); - } - } - - // Compounds handling - for (std::map, ListOfShape>::iterator - anIt = aCompoundObjects.begin(); - anIt != aCompoundObjects.end(); - ++anIt) - { - std::shared_ptr aCompound = anIt->first; - ListOfShape& aUsedInOperationShapes = anIt->second; - - // Collecting shapes from compound which will not be modified in boolean operation. - ListOfShape aNotUsedShapes; - for (GeomAPI_ShapeIterator aCompIt(aCompound); - aCompIt.more(); - aCompIt.next()) - { - std::shared_ptr aShapeInCompound = aCompIt.current(); - ListOfShape::iterator aUsedIt = aUsedInOperationShapes.begin(); - for (; aUsedIt != aUsedInOperationShapes.end(); aUsedIt++) { - if (aShapeInCompound->isEqual(*aUsedIt)) { - break; - } - } - if (aUsedIt == aUsedInOperationShapes.end()) { - aNotUsedShapes.push_back(aShapeInCompound); - } - } - - std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); - std::shared_ptr aCommonAlgo( - new GeomAlgoAPI_Boolean(aUsedInOperationShapes, - aTools, - GeomAlgoAPI_Boolean::BOOL_COMMON)); - - // Checking that the algorithm worked properly. - if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCommonAlgo, getKind(), anError)) { - setError(anError); - return; - } - - aMakeShapeList->appendAlgo(aCommonAlgo); - GeomShapePtr aResultShape = aCommonAlgo->shape(); - - // Add result to not used shape from compound. - if (!aNotUsedShapes.empty()) { - ListOfShape aShapesForResult = aNotUsedShapes; - if (aResultShape->shapeType() == GeomAPI_Shape::COMPOUND) { - for (GeomAPI_ShapeIterator aResultIt(aResultShape); aResultIt.more(); aResultIt.next()) { - aShapesForResult.push_back(aResultIt.current()); - } - } - else { - aShapesForResult.push_back(aResultShape); - } - - if (aShapesForResult.size() == 1) { - aResultShape = aShapesForResult.front(); - } - else { - aResultShape = GeomAlgoAPI_CompoundBuilder::compound(aShapesForResult); - } - } - - GeomAPI_ShapeIterator aShapeIt(aResultShape); - if (aShapeIt.more() || aResultShape->shapeType() == GeomAPI_Shape::VERTEX) { - std::shared_ptr aResultBody = - document()->createBody(data(), aResultIndex); - - ListOfShape aCompoundList; - aCompoundList.push_back(aCompound); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, - aCompoundList, - aTools, - aMakeShapeList, - aResultShape); - setResult(aResultBody, aResultIndex); - aResultIndex++; - - FeaturesPlugin_Tools::ResultBaseAlgo aRBA; - aRBA.resultBody = aResultBody; - aRBA.baseShape = aCompound; - aRBA.makeShape = aMakeShapeList; - aResultBaseAlgoList.push_back(aRBA); - aResultShapesList.push_back(aResultShape); + } else { + // process object as is + isOk = processObject(GeomAlgoAPI_Tools::BOOL_COMMON, + anObject, aTools.Objects(), aPlanes, + aResultIndex, aResultBaseAlgoList, aResultShapesList); } } - } // Store deleted shapes after all results has been proceeded. This is to avoid issue when in one // result shape has been deleted, but in another it was modified or stayed. GeomShapePtr aResultShapesCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList); - FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList, aTools, aResultShapesCompound); + FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList, + aTools.Objects(), + aResultShapesCompound); // remove the rest results if there were produced in the previous pass removeResults(aResultIndex); diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp index 04b9020ba..be93d26ec 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp @@ -44,59 +44,17 @@ FeaturesPlugin_BooleanCut::FeaturesPlugin_BooleanCut() //================================================================================================== void FeaturesPlugin_BooleanCut::execute() { - ListOfShape anObjects, aTools; - std::map, ListOfShape> aCompSolidsObjects; - std::map, ListOfShape> aCompoundObjects; + ObjectHierarchy anObjects, aTools; + ListOfShape aPlanes; - // Getting objects. - AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECT_LIST_ID()); - for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) { - AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex); - std::shared_ptr anObject = anObjectAttr->value(); - if(!anObject.get()) { - return; - } - ResultPtr aContext = anObjectAttr->context(); - ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext); - if (aResCompSolidPtr.get()) - { - std::shared_ptr aContextShape = aResCompSolidPtr->shape(); - GeomAPI_Shape::ShapeType aShapeType = aResCompSolidPtr->shape()->shapeType(); - std::map, ListOfShape>& aMap = - aShapeType == GeomAPI_Shape::COMPSOLID ? aCompSolidsObjects : aCompoundObjects; - - std::map, ListOfShape>::iterator - anIt = aMap.begin(); - for (; anIt != aMap.end(); anIt++) { - if (anIt->first->isEqual(aContextShape)) { - aMap[anIt->first].push_back(anObject); - break; - } - } - if (anIt == aMap.end()) { - aMap[aContextShape].push_back(anObject); - } - - } else { - anObjects.push_back(anObject); - } - } - - // Getting tools. - AttributeSelectionListPtr aToolsSelList = selectionList(TOOL_LIST_ID()); - for(int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) { - AttributeSelectionPtr aToolAttr = aToolsSelList->value(aToolsIndex); - GeomShapePtr aTool = aToolAttr->value(); - if(!aTool.get()) { - return; - } - aTools.push_back(aTool); - } + // Getting objects and tools + if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes) || + !processAttribute(TOOL_LIST_ID(), aTools, aPlanes)) + return; int aResultIndex = 0; - if((anObjects.empty() && aCompSolidsObjects.empty() && aCompoundObjects.empty()) - || aTools.empty()) { + if(anObjects.IsEmpty() || aTools.IsEmpty()) { std::string aFeatureError = "Error: Not enough objects for boolean operation."; setError(aFeatureError); return; @@ -107,221 +65,41 @@ void FeaturesPlugin_BooleanCut::execute() std::string anError; // For solids cut each object with all tools. - for(ListOfShape::iterator anObjectsIt = anObjects.begin(); - anObjectsIt != anObjects.end(); - ++anObjectsIt) { - std::shared_ptr anObject = *anObjectsIt; - std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); - std::shared_ptr aCutAlgo( - new GeomAlgoAPI_Boolean(anObject, - aTools, - GeomAlgoAPI_Boolean::BOOL_CUT)); - GeomShapePtr aResShape = aCutAlgo->shape(); - - // Checking that the algorithm worked properly. - if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCutAlgo, getKind(), anError)) { - setError(anError); - return; - } - - aMakeShapeList->appendAlgo(aCutAlgo); - - GeomAPI_ShapeIterator aShapeIt(aResShape); - if (aShapeIt.more() || aResShape->shapeType() == GeomAPI_Shape::VERTEX) - { - std::shared_ptr aResultBody = - document()->createBody(data(), aResultIndex); - - ListOfShape anObjectList; - anObjectList.push_back(anObject); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, - anObjectList, - aTools, - aMakeShapeList, - aResShape); - setResult(aResultBody, aResultIndex); - aResultIndex++; - - FeaturesPlugin_Tools::ResultBaseAlgo aRBA; - aRBA.resultBody = aResultBody; - aRBA.baseShape = anObject; - aRBA.makeShape = aMakeShapeList; - aResultBaseAlgoList.push_back(aRBA); - aResultShapesList.push_back(aResShape); - } - } - - // Compsolids handling - for (std::map, ListOfShape>::iterator - anIt = aCompSolidsObjects.begin(); - anIt != aCompSolidsObjects.end(); - ++anIt) - { - std::shared_ptr aCompSolid = anIt->first; - ListOfShape& aUsedInOperationSolids = anIt->second; - - // Collecting solids from compsolids which will not be modified in boolean operation. - ListOfShape aNotUsedSolids; - for(GeomAPI_ShapeExplorer anExp(aCompSolid, GeomAPI_Shape::SOLID); - anExp.more(); - anExp.next()) - { - std::shared_ptr aSolidInCompSolid = anExp.current(); - ListOfShape::iterator aUsedIt = aUsedInOperationSolids.begin(); - for (; aUsedIt != aUsedInOperationSolids.end(); aUsedIt++) { - if (aSolidInCompSolid->isEqual(*aUsedIt)) { - break; - } - } - if (aUsedIt == aUsedInOperationSolids.end()) { - aNotUsedSolids.push_back(aSolidInCompSolid); - } - } - - std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); - std::shared_ptr aCutAlgo( - new GeomAlgoAPI_Boolean(aUsedInOperationSolids, - aTools, - GeomAlgoAPI_Boolean::BOOL_CUT)); - - // Checking that the algorithm worked properly. - if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCutAlgo, getKind(), anError)) { - setError(anError); - return; - } - - aMakeShapeList->appendAlgo(aCutAlgo); - GeomShapePtr aResultShape = aCutAlgo->shape(); - - // Add result to not used solids from compsolid. - if(!aNotUsedSolids.empty()) { - ListOfShape aShapesToAdd = aNotUsedSolids; - aShapesToAdd.push_back(aCutAlgo->shape()); - std::shared_ptr aFillerAlgo( - new GeomAlgoAPI_PaveFiller(aShapesToAdd, true)); - if(!aFillerAlgo->isDone()) { - std::string aFeatureError = "Error: PaveFiller algorithm failed."; - setError(aFeatureError); - return; - } - - aMakeShapeList->appendAlgo(aFillerAlgo); - aResultShape = aFillerAlgo->shape(); - } - - GeomAPI_ShapeIterator aShapeIt(aResultShape); - if (aShapeIt.more() || aResultShape->shapeType() == GeomAPI_Shape::VERTEX) - { - std::shared_ptr aResultBody = - document()->createBody(data(), aResultIndex); - - ListOfShape anObjectList; - anObjectList.push_back(aCompSolid); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, - anObjectList, - aTools, - aMakeShapeList, - aResultShape); - setResult(aResultBody, aResultIndex); - aResultIndex++; - - FeaturesPlugin_Tools::ResultBaseAlgo aRBA; - aRBA.resultBody = aResultBody; - aRBA.baseShape = aCompSolid; - aRBA.makeShape = aMakeShapeList; - aResultBaseAlgoList.push_back(aRBA); - aResultShapesList.push_back(aResultShape); - } - } - - // Compounds handling - for (std::map, ListOfShape>::iterator - anIt = aCompoundObjects.begin(); - anIt != aCompoundObjects.end(); - ++anIt) - { - std::shared_ptr aCompound = anIt->first; - ListOfShape& aUsedInOperationShapes = anIt->second; - - // Collecting shapes from compound which will not be modified in boolean operation. - ListOfShape aNotUsedShapes; - for (GeomAPI_ShapeIterator aCompIt(aCompound); - aCompIt.more(); - aCompIt.next()) - { - std::shared_ptr aShapeInCompound = aCompIt.current(); - ListOfShape::iterator aUsedIt = aUsedInOperationShapes.begin(); - for (; aUsedIt != aUsedInOperationShapes.end(); aUsedIt++) { - if (aShapeInCompound->isEqual(*aUsedIt)) { - break; - } - } - if (aUsedIt == aUsedInOperationShapes.end()) { - aNotUsedShapes.push_back(aShapeInCompound); + bool isOk = true; + for (ObjectHierarchy::Iterator anObjectsIt = anObjects.Begin(); + anObjectsIt != anObjects.End() && isOk; + ++anObjectsIt) { + GeomShapePtr anObject = *anObjectsIt; + GeomShapePtr aParent = anObjects.Parent(anObject); + + if (aParent) { + GeomAPI_Shape::ShapeType aShapeType = aParent->shapeType(); + if (aShapeType == GeomAPI_Shape::COMPOUND) { + // Compound handling + isOk = processCompound(GeomAlgoAPI_Tools::BOOL_CUT, + anObjects, aParent, aTools.Objects(), + aResultIndex, aResultBaseAlgoList, aResultShapesList); } - } - - std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); - std::shared_ptr aCutAlgo( - new GeomAlgoAPI_Boolean(aUsedInOperationShapes, - aTools, - GeomAlgoAPI_Boolean::BOOL_CUT)); - - // Checking that the algorithm worked properly. - if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCutAlgo, getKind(), anError)) { - setError(anError); - return; - } - - aMakeShapeList->appendAlgo(aCutAlgo); - GeomShapePtr aResultShape = aCutAlgo->shape(); - - // Add result to not used shape from compound. - if (!aNotUsedShapes.empty()) { - ListOfShape aShapesForResult = aNotUsedShapes; - if (aResultShape->shapeType() == GeomAPI_Shape::COMPOUND) { - for (GeomAPI_ShapeIterator aResultIt(aResultShape); aResultIt.more(); aResultIt.next()) { - aShapesForResult.push_back(aResultIt.current()); - } - } else { - aShapesForResult.push_back(aResultShape); + else if (aShapeType == GeomAPI_Shape::COMPSOLID) { + // Compsolid handling + isOk = processCompsolid(GeomAlgoAPI_Tools::BOOL_CUT, + anObjects, aParent, aTools.Objects(), ListOfShape(), + aResultIndex, aResultBaseAlgoList, aResultShapesList); } - - if (aShapesForResult.size() == 1) { - aResultShape = aShapesForResult.front(); - } else { - aResultShape = GeomAlgoAPI_CompoundBuilder::compound(aShapesForResult); - } - } - - GeomAPI_ShapeIterator aShapeIt(aResultShape); - if (aShapeIt.more() || aResultShape->shapeType() == GeomAPI_Shape::VERTEX) { - std::shared_ptr aResultBody = - document()->createBody(data(), aResultIndex); - - ListOfShape anObjectList; - anObjectList.push_back(aCompound); - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, - anObjectList, - aTools, - aMakeShapeList, - aResultShape); - setResult(aResultBody, aResultIndex); - aResultIndex++; - - FeaturesPlugin_Tools::ResultBaseAlgo aRBA; - aRBA.resultBody = aResultBody; - aRBA.baseShape = aCompound; - aRBA.makeShape = aMakeShapeList; - aResultBaseAlgoList.push_back(aRBA); - aResultShapesList.push_back(aResultShape); + } else { + // process object as is + isOk = processObject(GeomAlgoAPI_Tools::BOOL_CUT, + anObject, aTools.Objects(), aPlanes, + aResultIndex, aResultBaseAlgoList, aResultShapesList); } } // Store deleted shapes after all results has been proceeded. This is to avoid issue when in one // result shape has been deleted, but in another it was modified or stayed. GeomShapePtr aResultShapesCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList); - FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList, aTools, aResultShapesCompound); + FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList, + aTools.Objects(), + aResultShapesCompound); // remove the rest results if there were produced in the previous pass removeResults(aResultIndex); diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp index 92d513e5c..a907823ad 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp @@ -50,58 +50,22 @@ FeaturesPlugin_BooleanFill::FeaturesPlugin_BooleanFill() void FeaturesPlugin_BooleanFill::execute() { std::string anError; - ListOfShape anObjects, aTools, anEdgesAndFaces, aPlanes; - std::map, ListOfShape> aCompSolidsObjects; + ObjectHierarchy anObjects, aTools; + ListOfShape aPlanes; // Getting objects. - AttributeSelectionListPtr anObjectsSelList = - selectionList(FeaturesPlugin_Boolean::OBJECT_LIST_ID()); - for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) { - AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex); - std::shared_ptr anObject = anObjectAttr->value(); - if(!anObject.get()) { - return; - } - ResultPtr aContext = anObjectAttr->context(); - ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext); - if(aResCompSolidPtr.get() - && aResCompSolidPtr->shape()->shapeType() == GeomAPI_Shape::COMPSOLID) { - std::shared_ptr aContextShape = aResCompSolidPtr->shape(); - std::map, ListOfShape>::iterator - anIt = aCompSolidsObjects.begin(); - for(; anIt != aCompSolidsObjects.end(); anIt++) { - if(anIt->first->isEqual(aContextShape)) { - aCompSolidsObjects[anIt->first].push_back(anObject); - break; - } - } - if(anIt == aCompSolidsObjects.end()) { - aCompSolidsObjects[aContextShape].push_back(anObject); - } - } else { - anObjects.push_back(anObject); - } - } + if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes)) + return; + // Planes are not supported as objects of FILL operation + aPlanes.clear(); // Getting tools. - AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Boolean::TOOL_LIST_ID()); - for(int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) { - AttributeSelectionPtr aToolAttr = aToolsSelList->value(aToolsIndex); - GeomShapePtr aTool = aToolAttr->value(); - if(!aTool.get()) { - // It could be a construction plane. - ResultPtr aContext = aToolAttr->context(); - aPlanes.push_back(aToolAttr->context()->shape()); - } - else { - aTools.push_back(aTool); - } - } + if (!processAttribute(TOOL_LIST_ID(), aTools, aPlanes)) + return; int aResultIndex = 0; - if ((anObjects.empty() && aCompSolidsObjects.empty()) - || (aTools.empty() && aPlanes.empty())) { + if (anObjects.IsEmpty() || (aTools.IsEmpty() && aPlanes.empty())) { std::string aFeatureError = "Error: Not enough objects for boolean operation."; setError(aFeatureError); return; @@ -111,178 +75,34 @@ void FeaturesPlugin_BooleanFill::execute() ListOfShape aResultShapesList; // For solids cut each object with all tools. - for(ListOfShape::iterator - anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) { - std::shared_ptr anObject = *anObjectsIt; - ListOfShape aListWithObject; - aListWithObject.push_back(anObject); - std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); - std::shared_ptr aBoolAlgo; - GeomShapePtr aResShape; - - std::list > aBoundingPoints = - GeomAlgoAPI_ShapeTools::getBoundingBox(aListWithObject, 1.0); - - // Resize planes. - ListOfShape aToolsWithPlanes = aTools; - for(ListOfShape::const_iterator anIt = aPlanes.cbegin(); - anIt != aPlanes.cend(); - ++anIt) - { - GeomShapePtr aPlane = *anIt; - GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints); - std::shared_ptr aMkShCustom( - new GeomAlgoAPI_MakeShapeCustom); - aMkShCustom->addModified(aPlane, aTool); - aMakeShapeList->appendAlgo(aMkShCustom); - aToolsWithPlanes.push_back(aTool); - } - - aBoolAlgo.reset(new GeomAlgoAPI_Partition(aListWithObject, aToolsWithPlanes)); - aResShape = aBoolAlgo->shape(); - if (aResShape.get() && aResShape->shapeType() == GeomAPI_Shape::COMPOUND) { - int aSubResultsNb = 0; - GeomAPI_ShapeIterator anIt(aResShape); - for(; anIt.more(); anIt.next()) { - ++aSubResultsNb; - } - if(aSubResultsNb == 1) { - anIt.init(aResShape); - if(anIt.more()) { - aResShape = anIt.current(); - } - } - } - - // Checking that the algorithm worked properly. - if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aBoolAlgo, getKind(), anError)) { - setError(anError); - return; - } - - aMakeShapeList->appendAlgo(aBoolAlgo); - - std::shared_ptr aResultBody = - document()->createBody(data(), aResultIndex); - - // tools should be added to the list to fulfill the correct history of modification - aListWithObject.insert(aListWithObject.end(), aTools.begin(), aTools.end()); - - ListOfShape aUsedTools = aTools; - aUsedTools.insert(aUsedTools.end(), aPlanes.begin(), aPlanes.end()); - - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aListWithObject, aUsedTools, - aMakeShapeList, aResShape); - setResult(aResultBody, aResultIndex); - aResultIndex++; - - FeaturesPlugin_Tools::ResultBaseAlgo aRBA; - aRBA.resultBody = aResultBody; - aRBA.baseShape = anObject; - aRBA.makeShape = aMakeShapeList; - aResultBaseAlgoList.push_back(aRBA); - aResultShapesList.push_back(aResShape); - } - - // Compsolids handling - for(std::map, ListOfShape>::iterator - anIt = aCompSolidsObjects.begin(); - anIt != aCompSolidsObjects.end(); anIt++) { - std::shared_ptr aCompSolid = anIt->first; - ListOfShape& aUsedInOperationSolids = anIt->second; - - // Collecting solids from compsolids which will not be modified in boolean operation. - ListOfShape aNotUsedSolids; - for(GeomAPI_ShapeExplorer - anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) { - std::shared_ptr aSolidInCompSolid = anExp.current(); - ListOfShape::iterator anIt = aUsedInOperationSolids.begin(); - for(; anIt != aUsedInOperationSolids.end(); anIt++) { - if(aSolidInCompSolid->isEqual(*anIt)) { - break; - } - } - if(anIt == aUsedInOperationSolids.end()) { - aNotUsedSolids.push_back(aSolidInCompSolid); - } - } - - std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); - std::shared_ptr aBoolAlgo; - - std::list > aBoundingPoints = - GeomAlgoAPI_ShapeTools::getBoundingBox(aUsedInOperationSolids, 1.0); - - // Resize planes. - ListOfShape aToolsWithPlanes = aTools; - for(ListOfShape::const_iterator anIt = aPlanes.cbegin(); - anIt != aPlanes.cend(); - ++anIt) - { - GeomShapePtr aPlane = *anIt; - GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints); - std::shared_ptr aMkShCustom( - new GeomAlgoAPI_MakeShapeCustom); - aMkShCustom->addModified(aPlane, aTool); - aMakeShapeList->appendAlgo(aMkShCustom); - aToolsWithPlanes.push_back(aTool); - } - - aBoolAlgo.reset(new GeomAlgoAPI_Partition(aUsedInOperationSolids, aToolsWithPlanes)); - - // Checking that the algorithm worked properly. - if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aBoolAlgo, getKind(), anError)) { - setError(anError); - return; - } - - aMakeShapeList->appendAlgo(aBoolAlgo); - GeomShapePtr aResultShape = aBoolAlgo->shape(); - - // Add result to not used solids from compsolid. - if(!aNotUsedSolids.empty()) { - ListOfShape aShapesToAdd = aNotUsedSolids; - aShapesToAdd.push_back(aBoolAlgo->shape()); - std::shared_ptr aFillerAlgo( - new GeomAlgoAPI_PaveFiller(aShapesToAdd, true)); - if(!aFillerAlgo->isDone()) { - std::string aFeatureError = "Error: PaveFiller algorithm failed."; - setError(aFeatureError); - return; - } - - aMakeShapeList->appendAlgo(aFillerAlgo); - aResultShape = aFillerAlgo->shape(); + bool isOk = true; + for (ObjectHierarchy::Iterator anObjectsIt = anObjects.Begin(); + anObjectsIt != anObjects.End() && isOk; + ++anObjectsIt) { + GeomShapePtr anObject = *anObjectsIt; + GeomShapePtr aParent = anObjects.Parent(anObject, false); + + if (aParent && aParent->shapeType() == GeomAPI_Shape::COMPSOLID) { + // get parent once again to mark it and the subs as processed + aParent = anObjects.Parent(anObject); + // compsolid handling + isOk = processCompsolid(GeomAlgoAPI_Tools::BOOL_PARTITION, + anObjects, aParent, aTools.Objects(), aPlanes, + aResultIndex, aResultBaseAlgoList, aResultShapesList); + } else { + // process object as is + isOk = processObject(GeomAlgoAPI_Tools::BOOL_PARTITION, + anObject, aTools.Objects(), aPlanes, + aResultIndex, aResultBaseAlgoList, aResultShapesList); } - - std::shared_ptr aResultBody = - document()->createBody(data(), aResultIndex); - - ListOfShape aUsedTools = aTools; - aUsedTools.insert(aUsedTools.end(), aPlanes.begin(), aPlanes.end()); - - ListOfShape aBaseShapes; - aBaseShapes.push_back(aCompSolid); - // tools should be added to the list to fulfill the correct history of modification - aBaseShapes.insert(aBaseShapes.end(), aTools.begin(), aTools.end()); - - FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapes, aUsedTools, - aMakeShapeList, aResultShape); - setResult(aResultBody, aResultIndex); - aResultIndex++; - - FeaturesPlugin_Tools::ResultBaseAlgo aRBA; - aRBA.resultBody = aResultBody; - aRBA.baseShape = aCompSolid; - aRBA.makeShape = aMakeShapeList; - aResultBaseAlgoList.push_back(aRBA); - aResultShapesList.push_back(aResultShape); } // Store deleted shapes after all results has been proceeded. This is to avoid issue when in one // result shape has been deleted, but in another it was modified or stayed. GeomShapePtr aResultShapesCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList); - FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList, aTools, aResultShapesCompound); + FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList, + aTools.Objects(), + aResultShapesCompound); // remove the rest results if there were produced in the previous pass removeResults(aResultIndex); diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp index 176e8b6fe..cd9fae738 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp @@ -174,7 +174,7 @@ void FeaturesPlugin_BooleanFuse::execute() GeomShapePtr aCuttedEdgesAndFaces; if (!anEdgesAndFaces.empty()) { std::shared_ptr aCutAlgo(new GeomAlgoAPI_Boolean(anEdgesAndFaces, - anOriginalShapes, GeomAlgoAPI_Boolean::BOOL_CUT)); + anOriginalShapes, GeomAlgoAPI_Tools::BOOL_CUT)); if (aCutAlgo->isDone()) { aCuttedEdgesAndFaces = aCutAlgo->shape(); aMakeShapeList->appendAlgo(aCutAlgo); @@ -191,7 +191,7 @@ void FeaturesPlugin_BooleanFuse::execute() ListOfShape aOneObjectList; aOneObjectList.push_back(*anIt); std::shared_ptr aCutAlgo( - new GeomAlgoAPI_Boolean(aOneObjectList, aShapesToAdd, GeomAlgoAPI_Boolean::BOOL_CUT)); + new GeomAlgoAPI_Boolean(aOneObjectList, aShapesToAdd, GeomAlgoAPI_Tools::BOOL_CUT)); if (GeomAlgoAPI_ShapeTools::volume(aCutAlgo->shape()) > 1.e-27) { aSolidsToFuse.push_back(aCutAlgo->shape()); @@ -216,7 +216,7 @@ void FeaturesPlugin_BooleanFuse::execute() } else if ((anObjects.size() + aTools.size()) > 1) { std::shared_ptr aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects, aTools, - GeomAlgoAPI_Boolean::BOOL_FUSE)); + GeomAlgoAPI_Tools::BOOL_FUSE)); // Checking that the algorithm worked properly. if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aFuseAlgo, getKind(), anError)) { diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanSmash.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanSmash.cpp index 9c8bb1e57..c3b8243ae 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanSmash.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanSmash.cpp @@ -154,7 +154,7 @@ void FeaturesPlugin_BooleanSmash::execute() std::shared_ptr anObjectsCutAlgo( new GeomAlgoAPI_Boolean(aShapesToSmash, aShapesToAdd, - GeomAlgoAPI_Boolean::BOOL_CUT)); + GeomAlgoAPI_Tools::BOOL_CUT)); if (GeomAlgoAPI_ShapeTools::volume(anObjectsCutAlgo->shape()) > 1.e-27) { aShapesToSmash.clear(); @@ -166,7 +166,7 @@ void FeaturesPlugin_BooleanSmash::execute() std::shared_ptr aToolsCutAlgo( new GeomAlgoAPI_Boolean(aTools, aShapesToAdd, - GeomAlgoAPI_Boolean::BOOL_CUT)); + GeomAlgoAPI_Tools::BOOL_CUT)); if (GeomAlgoAPI_ShapeTools::volume(aToolsCutAlgo->shape()) > 1.e-27) { aTools.clear(); @@ -179,7 +179,7 @@ void FeaturesPlugin_BooleanSmash::execute() std::shared_ptr aBoolAlgo( new GeomAlgoAPI_Boolean(aShapesToSmash, aTools, - GeomAlgoAPI_Boolean::BOOL_CUT)); + GeomAlgoAPI_Tools::BOOL_CUT)); // Checking that the algorithm worked properly. if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aBoolAlgo, getKind(), anError)) { diff --git a/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp index 4692110f4..d10c82d85 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp @@ -173,7 +173,7 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, aListWithObject.push_back(anObject); std::shared_ptr aBoolAlgo(new GeomAlgoAPI_Boolean(aListWithObject, theTools, - GeomAlgoAPI_Boolean::BOOL_CUT)); + GeomAlgoAPI_Tools::BOOL_CUT)); // Checking that the algorithm worked properly. if(!aBoolAlgo->isDone() || aBoolAlgo->shape()->isNull() || !aBoolAlgo->isValid()) { @@ -213,7 +213,7 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, std::shared_ptr aBoolAlgo(new GeomAlgoAPI_Boolean(aUsedShapes, theTools, - GeomAlgoAPI_Boolean::BOOL_CUT)); + GeomAlgoAPI_Tools::BOOL_CUT)); // Checking that the algorithm worked properly. if(!aBoolAlgo->isDone() || aBoolAlgo->shape()->isNull() || !aBoolAlgo->isValid()) { @@ -307,7 +307,7 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, if(!anEdgesAndFaces.empty() && !aCutTools.empty()) { std::shared_ptr aCutAlgo(new GeomAlgoAPI_Boolean(anEdgesAndFaces, aCutTools, - GeomAlgoAPI_Boolean::BOOL_CUT)); + GeomAlgoAPI_Tools::BOOL_CUT)); if(aCutAlgo->isDone() && !aCutAlgo->shape()->isNull() && aCutAlgo->isValid()) { anEdgesAndFaces.clear(); anEdgesAndFaces.push_back(aCutAlgo->shape()); @@ -319,7 +319,7 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, if(!aShapesToAdd.empty()) { std::shared_ptr aCutAlgo(new GeomAlgoAPI_Boolean(aSolidsToFuse, aShapesToAdd, - GeomAlgoAPI_Boolean::BOOL_CUT)); + GeomAlgoAPI_Tools::BOOL_CUT)); if(aCutAlgo->isDone() && GeomAlgoAPI_ShapeTools::volume(aCutAlgo->shape()) > 1.e-27) { aSolidsToFuse.clear(); aSolidsToFuse.push_back(aCutAlgo->shape()); @@ -339,7 +339,7 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, std::shared_ptr aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects, aTools, - GeomAlgoAPI_Boolean::BOOL_FUSE)); + GeomAlgoAPI_Tools::BOOL_FUSE)); // Checking that the algorithm worked properly. if(!aFuseAlgo->isDone() || aFuseAlgo->shape()->isNull() || !aFuseAlgo->isValid()) { diff --git a/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp b/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp index f572664a2..7c29a3efe 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Partition.cpp @@ -49,11 +49,6 @@ typedef std::list > CompsolidSubs; -static GeomShapePtr findBase(const GeomShapePtr theObjectShape, - const GeomShapePtr theResultShape, - const GeomAPI_Shape::ShapeType theShapeType, - const std::shared_ptr theMakeShape); - static void pullObjectsAndPlanes(const AttributeSelectionListPtr& theSelectedList, CompsolidSubs& theObjects, ListOfShape& thePlanes); @@ -323,7 +318,7 @@ static bool cutSubs(const GeomShapePtr& theFirstArgument, // cut from current list of solids aCutAlgo.reset( - new GeomAlgoAPI_Boolean(aUIt->second, theTools, GeomAlgoAPI_Boolean::BOOL_CUT)); + new GeomAlgoAPI_Boolean(aUIt->second, theTools, GeomAlgoAPI_Tools::BOOL_CUT)); if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCutAlgo, "", theError)) return false; theMakeShapeList->appendAlgo(aCutAlgo); diff --git a/src/FeaturesPlugin/FeaturesPlugin_Union.cpp b/src/FeaturesPlugin/FeaturesPlugin_Union.cpp index 1a33cb12a..8daf2723e 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Union.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Union.cpp @@ -116,7 +116,7 @@ void FeaturesPlugin_Union::execute() aTools.splice(aTools.begin(), anObjects, anObjects.begin()); anAlgo.reset(new GeomAlgoAPI_Boolean(anObjects, aTools, - GeomAlgoAPI_Boolean::BOOL_FUSE)); + GeomAlgoAPI_Tools::BOOL_FUSE)); } else { anAlgo.reset(new GeomAlgoAPI_UnifySameDomain(anObjects)); } diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp index ef984332f..4b668f5d9 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp @@ -30,7 +30,7 @@ //================================================================================================= GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const GeomShapePtr theObject, const GeomShapePtr theTool, - const OperationType theOperationType) + const GeomAlgoAPI_Tools::BOPType theOperationType) { ListOfShape aListWithObject, aListWithTool; aListWithObject.push_back(theObject); @@ -41,7 +41,7 @@ GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const GeomShapePtr theObject, //================================================================================================= GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const GeomShapePtr theObject, const ListOfShape& theTools, - const OperationType theOperationType) + const GeomAlgoAPI_Tools::BOPType theOperationType) { ListOfShape aListWithObject; aListWithObject.push_back(theObject); @@ -51,7 +51,7 @@ GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const GeomShapePtr theObject, //================================================================================================= GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const ListOfShape& theObjects, const ListOfShape& theTools, - const OperationType theOperationType) + const GeomAlgoAPI_Tools::BOPType theOperationType) { build(theObjects, theTools, theOperationType); } @@ -60,7 +60,7 @@ GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const ListOfShape& theObjects, //================================================================================================= void GeomAlgoAPI_Boolean::build(const ListOfShape& theObjects, const ListOfShape& theTools, - const OperationType theOperationType) + const GeomAlgoAPI_Tools::BOPType theOperationType) { if(theObjects.empty() || theTools.empty()) { return; @@ -85,15 +85,15 @@ void GeomAlgoAPI_Boolean::build(const ListOfShape& theObjects, // Creating boolean operation. BOPAlgo_BOP* aBuilder = new BOPAlgo_BOP(); switch (theOperationType) { - case BOOL_CUT: { + case GeomAlgoAPI_Tools::BOOL_CUT: { aBuilder->SetOperation(BOPAlgo_CUT); break; } - case BOOL_FUSE: { + case GeomAlgoAPI_Tools::BOOL_FUSE: { aBuilder->SetOperation(BOPAlgo_FUSE); break; } - case BOOL_COMMON: { + case GeomAlgoAPI_Tools::BOOL_COMMON: { aBuilder->SetOperation(BOPAlgo_COMMON); break; } diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.h b/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.h index d5a08376c..32224162b 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.h @@ -22,6 +22,7 @@ #include #include +#include #include @@ -30,31 +31,23 @@ /// \brief Allows to perform of boolean operations class GeomAlgoAPI_Boolean : public GeomAlgoAPI_MakeShape { -public: - /// Type of booelan operation - enum OperationType { - BOOL_CUT, ///< Cut objects - BOOL_FUSE, ///< Fuse objects - BOOL_COMMON ///< Take common part of objects - }; - public: /// Constructor. GEOMALGOAPI_EXPORT GeomAlgoAPI_Boolean(const GeomShapePtr theObject, const GeomShapePtr theTool, - const OperationType theOperationType); + const GeomAlgoAPI_Tools::BOPType theOperationType); /// Constructor. GEOMALGOAPI_EXPORT GeomAlgoAPI_Boolean(const GeomShapePtr theObject, const ListOfShape& theTools, - const OperationType theOperationType); + const GeomAlgoAPI_Tools::BOPType theOperationType); /// Constructor. GEOMALGOAPI_EXPORT GeomAlgoAPI_Boolean(const ListOfShape& theObjects, const ListOfShape& theTools, - const OperationType theOperationType); + const GeomAlgoAPI_Tools::BOPType theOperationType); /// Redefinition of the generic method for the Fuse problem: OCCT 30481 GEOMALGOAPI_EXPORT virtual void modified(const GeomShapePtr theOldShape, @@ -64,7 +57,7 @@ private: /// Builds resulting shape. void build(const ListOfShape& theObjects, const ListOfShape& theTools, - const OperationType theOperationType); + const GeomAlgoAPI_Tools::BOPType theOperationType); }; #endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Tools.h b/src/GeomAlgoAPI/GeomAlgoAPI_Tools.h index 2cb26c75b..a9a57baf4 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Tools.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Tools.h @@ -28,6 +28,13 @@ class GeomAlgoAPI_MakeShape; namespace GeomAlgoAPI_Tools { +/// Type of booelan operation +enum BOPType { + BOOL_CUT, ///< Cut objects + BOOL_FUSE, ///< Fuse objects + BOOL_COMMON, ///< Take common part of objects + BOOL_PARTITION ///< Parition operation +}; /** \class Localizer * \ingroup DataAlgo -- 2.39.2