From: dbv Date: Fri, 15 Jan 2016 11:51:29 +0000 (+0300) Subject: Porting composite boolean features to new GeomAlgoAPI_CellsBuilder which uses OCCT... X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=refs%2Fheads%2FBR_GENERAL_BOOLEAN;p=modules%2Fshaper.git Porting composite boolean features to new GeomAlgoAPI_CellsBuilder which uses OCCT BOPAlgo_CellsBuilder. --- diff --git a/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp index b47952c5d..e6cb3c28a 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -187,7 +188,13 @@ void FeaturesPlugin_CompositeBoolean::execute() switch(myBooleanOperationType) { case GeomAlgoAPI_Boolean::BOOL_CUT: case GeomAlgoAPI_Boolean::BOOL_COMMON:{ - // Cut each object with all tools + if((anObjects.empty() && aCompSolidsObjects.empty()) || aTools.empty()) { + std::string aFeatureError = "Error: not enough objects for boolean operation."; + setError(aFeatureError); + return; + } + + // 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; @@ -196,7 +203,7 @@ void FeaturesPlugin_CompositeBoolean::execute() // Checking that the algorithm worked properly. if(!aBoolAlgo.isDone() || aBoolAlgo.shape()->isNull() || !aBoolAlgo.isValid()) { - setError("Boolean algorithm failed"); + setError("Error: boolean algorithm failed."); return; } @@ -210,55 +217,67 @@ void FeaturesPlugin_CompositeBoolean::execute() } // Compsolids handling + int aMaterialId = 1; 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; + ListOfShape aNotUsedInOperationSolids; + GeomAlgoAPI_ShapeTools::getSolidsInCompSolid(aCompSolid, aUsedInOperationSolids, aNotUsedInOperationSolids); + + // Collecting all solids from compsolid and tools, and setting them as arguments for builder. + ListOfShape anArguments; + anArguments.insert(anArguments.end(), aUsedInOperationSolids.begin(), aUsedInOperationSolids.end()); + anArguments.insert(anArguments.end(), aNotUsedInOperationSolids.begin(), aNotUsedInOperationSolids.end()); + anArguments.insert(anArguments.end(), aTools.begin(), aTools.end()); + + // Perform splitting into cells. + GeomAlgoAPI_CellsBuilder aCellsBuilder; + aCellsBuilder.setArguments(anArguments); + aCellsBuilder.setFuzzyValue(0.0); + aCellsBuilder.setRunParallel(false); + aCellsBuilder.perform(); + + // Taking not used solids in compsolid. + ListOfShape aLSToTake, aLSToAvoid; + for(ListOfShape::const_iterator anIt = aNotUsedInOperationSolids.cbegin(); anIt != aNotUsedInOperationSolids.cend(); anIt++) { + aLSToTake.clear(); aLSToAvoid.clear(); + aLSToTake.push_back(*anIt); + aCellsBuilder.addToResult(aLSToTake, aLSToAvoid, ++aMaterialId); + } + + // Taking result solids after boolean operation. + for(ListOfShape::const_iterator anIt = aUsedInOperationSolids.cbegin(); anIt != aUsedInOperationSolids.cend(); anIt++) { + aLSToTake.clear(); aLSToAvoid.clear(); + aLSToTake.push_back(*anIt); + if(myBooleanOperationType == GeomAlgoAPI_Boolean::BOOL_CUT) { + aLSToAvoid.insert(aLSToAvoid.end(), aTools.begin(), aTools.end()); + aCellsBuilder.addToResult(aLSToTake, aLSToAvoid); + } else { + for(ListOfShape::const_iterator aToolsIt = aTools.cbegin(); aToolsIt != aTools.cend(); aToolsIt++) { + aLSToTake.push_back(*aToolsIt); + aCellsBuilder.addToResult(aLSToTake, aLSToAvoid); } } - if(anIt == aUsedInOperationSolids.end()) { - aNotUsedSolids.push_back(aSolidInCompSolid); - } } - std::shared_ptr aBoolAlgo(new GeomAlgoAPI_Boolean(aUsedInOperationSolids, aTools, myBooleanOperationType)); + aCellsBuilder.removeInternalBoundaries(); // Checking that the algorithm worked properly. - if(!aBoolAlgo->isDone() || aBoolAlgo->shape()->isNull() || !aBoolAlgo->isValid()) { - setError("Boolean algorithm failed"); - return; - } - - GeomAlgoAPI_MakeShapeList aMakeShapeList; - aMakeShapeList.appendAlgo(aBoolAlgo); - GeomAPI_DataMapOfShapeShape aMapOfShapes; - aMapOfShapes.merge(aBoolAlgo->mapOfSubShapes()); - - // Add result to not used solids from compsolid. - ListOfShape aShapesToAdd = aNotUsedSolids; - aShapesToAdd.push_back(aBoolAlgo->shape()); - std::shared_ptr aFillerAlgo(new GeomAlgoAPI_PaveFiller(aShapesToAdd, true)); - if(!aFillerAlgo->isDone()) { - std::string aFeatureError = "PaveFiller algorithm failed"; + if(!aCellsBuilder.isDone() || aCellsBuilder.shape()->isNull() || !aCellsBuilder.isValid()) { + static const std::string aFeatureError = "Error: cells builder algorithm failed."; setError(aFeatureError); return; } - aMakeShapeList.appendAlgo(aFillerAlgo); - aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes()); + std::shared_ptr aResultShape = aCellsBuilder.shape(); - if(GeomAlgoAPI_ShapeTools::volume(aFillerAlgo->shape()) > 1.e-7) { + if(GeomAlgoAPI_ShapeTools::volume(aResultShape) > 1.e-7) { std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); - loadNamingDS(aResultBody, aShells, aSolidsAlgos, aCompSolid, aTools, aFillerAlgo->shape(), aMakeShapeList, aMapOfShapes); + loadNamingDS(aResultBody, aShells, aSolidsAlgos, aCompSolid, aTools, aResultShape, + aCellsBuilder, *(aCellsBuilder.mapOfSubShapes())); setResult(aResultBody, aResultIndex); aResultIndex++; } @@ -266,107 +285,90 @@ void FeaturesPlugin_CompositeBoolean::execute() break; } case GeomAlgoAPI_Boolean::BOOL_FUSE: { - // Collecting all solids which will be fused. - ListOfShape aSolidsToFuse; - aSolidsToFuse.insert(aSolidsToFuse.end(), anObjects.begin(), anObjects.end()); - aSolidsToFuse.insert(aSolidsToFuse.end(), aTools.begin(), aTools.end()); + if((anObjects.size() + aTools.size() + aCompSolidsObjects.size()) < 2) { + std::string aFeatureError = "Error: not enough objects for boolean operation."; + setError(aFeatureError); + return; + } - // Collecting solids from compsolids which will not be modified in boolean operation. - ListOfShape aNotUsedSolids; + // Adding solids from compsolids to list of solids which will be fused. + ListOfShape aUsedInOperationSolids, aNotUsedInOperationSolids; for(std::map, ListOfShape>::iterator anIt = aCompSolidsObjects.begin(); anIt != aCompSolidsObjects.end(); anIt++) { std::shared_ptr aCompSolid = anIt->first; - ListOfShape& aUsedInOperationSolids = anIt->second; - aSolidsToFuse.insert(aSolidsToFuse.end(), aUsedInOperationSolids.begin(), aUsedInOperationSolids.end()); + ListOfShape& aSolidsToAvoid = anIt->second; + aUsedInOperationSolids.insert(aUsedInOperationSolids.end(), aSolidsToAvoid.begin(), aSolidsToAvoid.end()); // Collect solids from compsolid which will not be modified in boolean operation. - 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); - } - } + GeomAlgoAPI_ShapeTools::getSolidsInCompSolid(aCompSolid, aSolidsToAvoid, aNotUsedInOperationSolids); } - ListOfShape anOriginalSolids = aSolidsToFuse; - anOriginalSolids.insert(anOriginalSolids.end(), aNotUsedSolids.begin(), aNotUsedSolids.end()); - GeomAlgoAPI_MakeShapeList aMakeShapeList; - GeomAPI_DataMapOfShapeShape aMapOfShapes; - - // If we have compsolids then cut with not used solids all others. - if(!aNotUsedSolids.empty()) { - aSolidsToFuse.clear(); - for(ListOfShape::iterator anIt = anOriginalSolids.begin(); anIt != anOriginalSolids.end(); anIt++) { - ListOfShape aOneObjectList; - aOneObjectList.push_back(*anIt); - std::shared_ptr aCutAlgo(new GeomAlgoAPI_Boolean(aOneObjectList, aNotUsedSolids, GeomAlgoAPI_Boolean::BOOL_CUT)); - - if(GeomAlgoAPI_ShapeTools::volume(aCutAlgo->shape()) > 1.e-7) { - aSolidsToFuse.push_back(aCutAlgo->shape()); - aMakeShapeList.appendAlgo(aCutAlgo); - aMapOfShapes.merge(aCutAlgo->mapOfSubShapes()); - } - } + // Collecting objects, tools and all solids from compsolid, and setting them as arguments for builder. + ListOfShape anArguments; + anArguments.insert(anArguments.end(), anObjects.begin(), anObjects.end()); + anArguments.insert(anArguments.end(), aTools.begin(), aTools.end()); + anArguments.insert(anArguments.end(), aUsedInOperationSolids.begin(), aUsedInOperationSolids.end()); + anArguments.insert(anArguments.end(), aNotUsedInOperationSolids.begin(), aNotUsedInOperationSolids.end()); + + // Perform splitting into cells. + GeomAlgoAPI_CellsBuilder aCellsBuilder; + aCellsBuilder.setArguments(anArguments); + aCellsBuilder.setFuzzyValue(0.0); + aCellsBuilder.setRunParallel(false); + aCellsBuilder.perform(); + + // Taking objects. + int aMaterialId = 1; + ListOfShape aLSToTake, aLSToAvoid; + for(ListOfShape::const_iterator anIt = anObjects.cbegin(); anIt != anObjects.cend(); anIt++) { + aLSToTake.clear(); + aLSToTake.push_back(*anIt); + aCellsBuilder.addToResult(aLSToTake, aNotUsedInOperationSolids, aMaterialId); } - anObjects.clear(); - anObjects.push_back(aSolidsToFuse.back()); - aSolidsToFuse.pop_back(); - aTools = aSolidsToFuse; + // Taking tools. + for(ListOfShape::const_iterator anIt = aTools.cbegin(); anIt != aTools.cend(); anIt++) { + aLSToTake.clear(); + aLSToTake.push_back(*anIt); + aCellsBuilder.addToResult(aLSToTake, aNotUsedInOperationSolids, aMaterialId); + } - // Fuse all objects and all tools. - std::shared_ptr aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects, aTools, myBooleanOperationType)); + // Taking used solids in compsolids. + for(ListOfShape::const_iterator anIt = aUsedInOperationSolids.cbegin(); anIt != aUsedInOperationSolids.cend(); anIt++) { + aLSToTake.clear(); + aLSToTake.push_back(*anIt); + aCellsBuilder.addToResult(aLSToTake, aNotUsedInOperationSolids, aMaterialId); + } + + // Taking not used solids in compsolid. + for(ListOfShape::const_iterator anIt = aNotUsedInOperationSolids.cbegin(); anIt != aNotUsedInOperationSolids.cend(); anIt++) { + aLSToTake.clear(); + aLSToTake.push_back(*anIt); + aCellsBuilder.addToResult(aLSToTake, aLSToAvoid, ++aMaterialId); + } + + aCellsBuilder.removeInternalBoundaries(); // Checking that the algorithm worked properly. - if(!aFuseAlgo->isDone() || aFuseAlgo->shape()->isNull() || !aFuseAlgo->isValid()) { - static const std::string aFeatureError = "Boolean algorithm failed"; + if(!aCellsBuilder.isDone() || aCellsBuilder.shape()->isNull() || !aCellsBuilder.isValid()) { + static const std::string aFeatureError = "Error: cells builder algorithm failed."; setError(aFeatureError); return; } - std::shared_ptr aShape = aFuseAlgo->shape(); - aMakeShapeList.appendAlgo(aFuseAlgo); - aMapOfShapes.merge(aFuseAlgo->mapOfSubShapes()); + std::shared_ptr aResultShape = aCellsBuilder.shape(); - // Add result to not used solids from compsolid (if we have any). - if(!aNotUsedSolids.empty()) { - aNotUsedSolids.push_back(aShape); - std::shared_ptr aFillerAlgo(new GeomAlgoAPI_PaveFiller(aNotUsedSolids, true)); - if(!aFillerAlgo->isDone()) { - std::string aFeatureError = "PaveFiller algorithm failed"; - setError(aFeatureError); - return; - } - if(aFillerAlgo->shape()->isNull()) { - static const std::string aShapeError = "Resulting shape is Null"; - setError(aShapeError); - return; - } - if(!aFillerAlgo->isValid()) { - std::string aFeatureError = "Warning: resulting shape is not valid"; - setError(aFeatureError); - return; - } - - aShape = aFillerAlgo->shape(); - aMakeShapeList.appendAlgo(aFillerAlgo); - aMapOfShapes.merge(aFillerAlgo->mapOfSubShapes()); + if(GeomAlgoAPI_ShapeTools::volume(aResultShape) > 1.e-7) { + std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); + loadNamingDS(aResultBody, aShells, aSolidsAlgos, anArguments.front(), anArguments, aResultShape, aCellsBuilder, *(aCellsBuilder.mapOfSubShapes())); + setResult(aResultBody, aResultIndex); + aResultIndex++; } - - std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); - loadNamingDS(aResultBody, aShells, aSolidsAlgos, anOriginalSolids.front(), anOriginalSolids, aShape, aMakeShapeList, aMapOfShapes); - setResult(aResultBody, aResultIndex); - aResultIndex++; break; } default: { - setError("Error: wrong type of boolean operation"); + std::string anOperationError = "Error: wrong type of operation."; + setError(anOperationError); return; } }