X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FFeaturesPlugin%2FFeaturesPlugin_Boolean.cpp;h=d3fcd0ba506dd41acd7efc5474a7b9b8c8da09d3;hb=95375993f1f35e4716475c0b0c8e265c082c875d;hp=7f9ce37ac77b4a27d79d5d42dd71133c9edc666f;hpb=f1067fb269ba33446679b0cce28bc92a1f84f9ee;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp index 7f9ce37ac..d3fcd0ba5 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -70,48 +71,6 @@ 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, @@ -146,413 +105,37 @@ void FeaturesPlugin_Boolean::loadNamingDS(std::shared_ptr t } //================================================================================================= -bool FeaturesPlugin_Boolean::processObject( - const GeomAlgoAPI_Tools::BOPType theBooleanType, - const GeomShapePtr& theObject, +void FeaturesPlugin_Boolean::storeResult( + const ListOfShape& theObjects, const ListOfShape& theTools, - const ListOfShape& thePlanes, + const GeomShapePtr theResultShape, 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); - - // tools should be added to the list to fulfill the correct history of modification - aListWithObject.insert(aListWithObject.end(), theTools.begin(), theTools.end()); - - 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); - // tools should be added to the list to fulfill the correct history of modification - aCompSolidList.insert(aCompSolidList.end(), theTools.begin(), theTools.end()); - - 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::ObjectsByType( - ListOfShape& theShapesByType, - ListOfShape& theOtherShapes, - const GeomAPI_Shape::ShapeType theMinType, - const GeomAPI_Shape::ShapeType theMaxType) const + std::shared_ptr theMakeShapeList, + std::vector& theResultBaseAlgoList) { - 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()); + if (!theResultShape) 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 -{ - 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; + std::shared_ptr aResultBody = + document()->createBody(data(), theResultIndex); + + FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, + theObjects, + theTools, + theMakeShapeList, + theResultShape); + setResult(aResultBody, theResultIndex++); + + // merge algorithms + FeaturesPlugin_Tools::ResultBaseAlgo aRBA; + aRBA.resultBody = aResultBody; + aRBA.baseShape = theObjects.front(); + for (std::vector::iterator + aRBAIt = theResultBaseAlgoList.begin(); + aRBAIt != theResultBaseAlgoList.end(); ++aRBAIt) { + theMakeShapeList->appendAlgo(aRBAIt->makeShape); + } + aRBA.makeShape = theMakeShapeList; + theResultBaseAlgoList.clear(); + theResultBaseAlgoList.push_back(aRBA); }