X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FFeaturesPlugin%2FFeaturesPlugin_BooleanFill.cpp;h=cbab08a645a056ba516c868be9597e6f996c0c73;hb=4afb998c2356f5f6a415f6d7183b4427f97f3616;hp=56608a69204c0fd93da046b0fb4274fb2a29595c;hpb=9c5142243d3646995eae35e07c605fc01f2be9f9;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp b/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp index 56608a692..cbab08a64 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2021 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -12,14 +12,12 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or -// email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "FeaturesPlugin_BooleanFill.h" -#include "FeaturesPlugin_Tools.h" #include #include @@ -47,237 +45,85 @@ FeaturesPlugin_BooleanFill::FeaturesPlugin_BooleanFill() { } +//================================================================================================= +void FeaturesPlugin_BooleanFill::initAttributes() +{ + FeaturesPlugin_Boolean::initAttributes(); + initVersion(BOP_VERSION_9_4(), selectionList(OBJECT_LIST_ID()), selectionList(TOOL_LIST_ID())); +} + //================================================================================================= void FeaturesPlugin_BooleanFill::execute() { std::string anError; - ListOfShape anObjects, aTools, anEdgesAndFaces, aPlanes; - std::map, ListOfShape> aCompSolidsObjects; + GeomAPI_ShapeHierarchy 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.empty() || (aTools.empty() && aPlanes.empty())) { std::string aFeatureError = "Error: Not enough objects for boolean operation."; setError(aFeatureError); return; } - std::vector aResultBaseAlgoList; + std::vector aResultBaseAlgoList; 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 aMakeShapeList(new GeomAlgoAPI_MakeShapeList()); - std::shared_ptr aResultBody = - document()->createBody(data(), aResultIndex); - - 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); + GeomShapePtr aResultCompound; + if (data()->version() == BOP_VERSION_9_4()) { + // merge hierarchies of compounds containing objects and tools + aResultCompound = + keepUnusedSubsOfCompound(GeomShapePtr(), anObjects, aTools, aMakeShapeList); } - // 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(); + // For solids cut each object with all tools. + bool isOk = true; + for (GeomAPI_ShapeHierarchy::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, + aResultCompound); + } else { + // process object as is + isOk = processObject(GeomAlgoAPI_Tools::BOOL_PARTITION, + anObject, aTools.objects(), aPlanes, + aResultIndex, aResultBaseAlgoList, aResultShapesList, + aResultCompound); } - - 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); - 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); } + storeResult(anObjects.objects(), aTools.objects(), aResultCompound, aResultIndex, + aMakeShapeList, aResultBaseAlgoList); + // 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); + if (!aResultCompound) + aResultCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList); + ModelAPI_Tools::loadDeletedShapes(aResultBaseAlgoList, + aTools.objects(), + aResultCompound); // remove the rest results if there were produced in the previous pass removeResults(aResultIndex);