]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Porting composite boolean features to new GeomAlgoAPI_CellsBuilder which uses OCCT... BR_GENERAL_BOOLEAN
authordbv <dbv@opencascade.com>
Fri, 15 Jan 2016 11:51:29 +0000 (14:51 +0300)
committerdbv <dbv@opencascade.com>
Fri, 15 Jan 2016 11:51:29 +0000 (14:51 +0300)
src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp

index b47952c5dbbc97c950b8c92bc3d073e7e7038287..e6cb3c28ab8f80e450aeaf321e3722b957f2cb13 100644 (file)
@@ -14,6 +14,7 @@
 #include <ModelAPI_Tools.h>
 #include <ModelAPI_Validator.h>
 
+#include <GeomAlgoAPI_CellsBuilder.h>
 #include <GeomAlgoAPI_CompoundBuilder.h>
 #include <GeomAlgoAPI_MakeShapeList.h>
 #include <GeomAlgoAPI_MakeSweep.h>
@@ -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<GeomAPI_Shape> 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<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator anIt = aCompSolidsObjects.begin();
         anIt != aCompSolidsObjects.end(); anIt++) {
         std::shared_ptr<GeomAPI_Shape> 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<GeomAPI_Shape> 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<GeomAlgoAPI_Boolean> 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<GeomAlgoAPI_PaveFiller> 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<GeomAPI_Shape> aResultShape = aCellsBuilder.shape();
 
-        if(GeomAlgoAPI_ShapeTools::volume(aFillerAlgo->shape()) > 1.e-7) {
+        if(GeomAlgoAPI_ShapeTools::volume(aResultShape) > 1.e-7) {
           std::shared_ptr<ModelAPI_ResultBody> 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<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator anIt = aCompSolidsObjects.begin();
         anIt != aCompSolidsObjects.end(); anIt++) {
         std::shared_ptr<GeomAPI_Shape> 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<GeomAPI_Shape> 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<GeomAlgoAPI_Boolean> 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<GeomAlgoAPI_Boolean> 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<GeomAPI_Shape> aShape = aFuseAlgo->shape();
-      aMakeShapeList.appendAlgo(aFuseAlgo);
-      aMapOfShapes.merge(aFuseAlgo->mapOfSubShapes());
+      std::shared_ptr<GeomAPI_Shape> 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<GeomAlgoAPI_PaveFiller> 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<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
+        loadNamingDS(aResultBody, aShells, aSolidsAlgos, anArguments.front(), anArguments, aResultShape, aCellsBuilder, *(aCellsBuilder.mapOfSubShapes()));
+        setResult(aResultBody, aResultIndex);
+        aResultIndex++;
       }
-
-      std::shared_ptr<ModelAPI_ResultBody> 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;
     }
   }