]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Porting boolean feature to new GeomAlgoAPI_CellsBuilder which uses OCCT BOPAlgo_Cells...
authordbv <dbv@opencascade.com>
Thu, 14 Jan 2016 15:43:27 +0000 (18:43 +0300)
committerdbv <dbv@opencascade.com>
Thu, 14 Jan 2016 15:45:01 +0000 (18:45 +0300)
src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI.i
src/GeomAlgoAPI/GeomAlgoAPI_CellsBuilder.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_CellsBuilder.h [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h
src/GeomAlgoAPI/GeomAlgoAPI_swig.h

index ee767710c25ee08f8ba61412e5e966ed32a43bd5..85ef28c97912de1c7ab30c515d6a6813d98066de 100644 (file)
@@ -17,6 +17,7 @@
 #include <ModelAPI_Tools.h>
 
 #include <GeomAlgoAPI_Boolean.h>
+#include <GeomAlgoAPI_CellsBuilder.h>
 #include <GeomAlgoAPI_MakeShapeList.h>
 #include <GeomAlgoAPI_PaveFiller.h>
 #include <GeomAlgoAPI_ShapeTools.h>
@@ -34,15 +35,13 @@ void FeaturesPlugin_Boolean::initAttributes()
 {
   data()->addAttribute(FeaturesPlugin_Boolean::TYPE_ID(), ModelAPI_AttributeInteger::typeId());
 
-  AttributeSelectionListPtr aSelection = 
+  AttributeSelectionListPtr aSelection =
     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
     FeaturesPlugin_Boolean::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
-  // extrusion works with faces always
   aSelection->setSelectionType("SOLID");
 
   aSelection = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
     FeaturesPlugin_Boolean::TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
-  // extrusion works with faces always
   aSelection->setSelectionType("SOLID");
 
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), OBJECT_LIST_ID());
@@ -67,11 +66,11 @@ std::shared_ptr<GeomAPI_Shape> FeaturesPlugin_Boolean::getShape(const std::strin
 void FeaturesPlugin_Boolean::execute()
 {
   // Getting operation type.
-  std::shared_ptr<ModelAPI_AttributeInteger> aTypeAttr = std::dynamic_pointer_cast<
+  std::shared_ptr<ModelAPI_AttributeInteger> anOperationTypeAttr = std::dynamic_pointer_cast<
       ModelAPI_AttributeInteger>(data()->attribute(FeaturesPlugin_Boolean::TYPE_ID()));
-  if (!aTypeAttr)
+  if (!anOperationTypeAttr)
     return;
-  GeomAlgoAPI_Boolean::OperationType aType = (GeomAlgoAPI_Boolean::OperationType)aTypeAttr->value();
+  GeomAlgoAPI_Boolean::OperationType anOperationType = (GeomAlgoAPI_Boolean::OperationType)anOperationTypeAttr->value();
 
   ListOfShape anObjects, aTools;
   std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape> aCompSolidsObjects;
@@ -116,11 +115,11 @@ void FeaturesPlugin_Boolean::execute()
 
   int aResultIndex = 0;
 
-  switch(aType) {
+  switch(anOperationType) {
     case GeomAlgoAPI_Boolean::BOOL_CUT:
     case GeomAlgoAPI_Boolean::BOOL_COMMON:{
       if((anObjects.empty() && aCompSolidsObjects.empty()) || aTools.empty()) {
-        std::string aFeatureError = "Not enough objects for boolean operation";
+        std::string aFeatureError = "Error: not enough objects for boolean operation.";
         setError(aFeatureError);
         return;
       }
@@ -130,21 +129,21 @@ void FeaturesPlugin_Boolean::execute()
         std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
         ListOfShape aListWithObject;
         aListWithObject.push_back(anObject);
-        GeomAlgoAPI_Boolean aBoolAlgo(aListWithObject, aTools, aType);
+        GeomAlgoAPI_Boolean aBoolAlgo(aListWithObject, aTools, anOperationType);
 
         // Checking that the algorithm worked properly.
         if(!aBoolAlgo.isDone()) {
-          static const std::string aFeatureError = "Boolean algorithm failed";
+          static const std::string aFeatureError = "Error: boolean algorithm failed.";
           setError(aFeatureError);
           return;
         }
         if(aBoolAlgo.shape()->isNull()) {
-          static const std::string aShapeError = "Resulting shape is Null";
+          static const std::string aShapeError = "Error: resulting shape is Null.";
           setError(aShapeError);
           return;
         }
         if(!aBoolAlgo.isValid()) {
-          std::string aFeatureError = "Warning: resulting shape is not valid";
+          std::string aFeatureError = "Error: resulting shape is not valid.";
           setError(aFeatureError);
           return;
         }
@@ -158,66 +157,76 @@ void FeaturesPlugin_Boolean::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(anOperationType == 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, aType));
+        aCellsBuilder.removeInternalBoundaries();
 
         // Checking that the algorithm worked properly.
-        if(!aBoolAlgo->isDone()) {
-          static const std::string aFeatureError = "Boolean algorithm failed";
+        if(!aCellsBuilder.isDone()) {
+          static const std::string aFeatureError = "Error: cells builder algorithm failed.";
           setError(aFeatureError);
           return;
         }
-        if(aBoolAlgo->shape()->isNull()) {
-          static const std::string aShapeError = "Resulting shape is Null";
+        if(aCellsBuilder.shape()->isNull()) {
+          static const std::string aShapeError = "Error: resulting shape is Null.";
           setError(aShapeError);
           return;
         }
-        if(!aBoolAlgo->isValid()) {
-          std::string aFeatureError = "Warning: resulting shape is not valid";
-          setError(aFeatureError);
-          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.isValid()) {
+          std::string aFeatureError = "Error: resulting shape is not valid.";
           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, aCompSolid, aTools, aFillerAlgo->shape(), aMakeShapeList, aMapOfShapes);
+          loadNamingDS(aResultBody, aCompSolid, aTools, aCellsBuilder.shape(), aCellsBuilder, *(aCellsBuilder.mapOfSubShapes()));
           setResult(aResultBody, aResultIndex);
           aResultIndex++;
         }
@@ -226,122 +235,98 @@ void FeaturesPlugin_Boolean::execute()
     }
     case GeomAlgoAPI_Boolean::BOOL_FUSE: {
       if((anObjects.size() + aTools.size() + aCompSolidsObjects.size()) < 2) {
-        std::string aFeatureError = "Not enough objects for boolean operation";
+        std::string aFeatureError = "Error: not enough objects for boolean operation.";
         setError(aFeatureError);
         return;
       }
 
-      // 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());
-
-      // 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, aType));
+      // 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()) {
-        static const std::string aFeatureError = "Boolean algorithm failed";
+      if(!aCellsBuilder.isDone()) {
+        static const std::string aFeatureError = "Error: cells builder algorithm failed.";
         setError(aFeatureError);
         return;
       }
-      if(aFuseAlgo->shape()->isNull()) {
-        static const std::string aShapeError = "Resulting shape is Null";
+      if(aCellsBuilder.shape()->isNull()) {
+        static const std::string aShapeError = "Error: resulting shape is Null.";
         setError(aShapeError);
         return;
       }
-      if(!aFuseAlgo->isValid()) {
-        std::string aFeatureError = "Warning: resulting shape is not valid";
+      if(!aCellsBuilder.isValid()) {
+        std::string aFeatureError = "Error: resulting shape is not valid.";
         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, anArguments.front(), anArguments, aCellsBuilder.shape(), aCellsBuilder, *(aCellsBuilder.mapOfSubShapes()));
+        setResult(aResultBody, aResultIndex);
+        aResultIndex++;
       }
-
-      std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
-      loadNamingDS(aResultBody, anOriginalSolids.front(), anOriginalSolids, aShape, aMakeShapeList, aMapOfShapes);
-      setResult(aResultBody, aResultIndex);
-      aResultIndex++;
       break;
     }
     default: {
-      std::string anOperationError = "Error: wrong type of operation";
+      std::string anOperationError = "Error: wrong type of operation.";
       setError(anOperationError);
       return;
     }
index 24c17e62d685f5b36d7defc685334f5afc6feb1f..36ea061da99dc681686c2e43ab15aa767e1cbf40 100644 (file)
@@ -34,6 +34,7 @@ SET(PROJECT_HEADERS
     GeomAlgoAPI_ShapeTools.h
     GeomAlgoAPI_Partition.h
     GeomAlgoAPI_PaveFiller.h
+    GeomAlgoAPI_CellsBuilder.h
 )
 
 SET(PROJECT_SOURCES
@@ -64,6 +65,7 @@ SET(PROJECT_SOURCES
     GeomAlgoAPI_ShapeTools.cpp
     GeomAlgoAPI_Partition.cpp
     GeomAlgoAPI_PaveFiller.cpp
+    GeomAlgoAPI_CellsBuilder.cpp
 )
 
 SET(PROJECT_LIBRARIES
@@ -72,8 +74,8 @@ SET(PROJECT_LIBRARIES
     ModelAPI
     ${CAS_OCAF}
     ${CAS_SHAPE}
-    ${CAS_TKBO} 
-    ${CAS_TKBool} 
+    ${CAS_TKBO}
+    ${CAS_TKBool}
     ${CAS_TKBRep}
     ${CAS_TKCAF}
     ${CAS_TKCAF}
index 86addb6d2af1f326c52ddfe8b62f2872cb07303a..88037c60aec2ae2db86cc6fed8556d13f8d8744b 100644 (file)
@@ -40,8 +40,9 @@
 %include "GeomAlgoAPI_Tools.h"
 %include "GeomAlgoAPI_Transform.h"
 %include "GeomAlgoAPI_PaveFiller.h"
+%include "GeomAlgoAPI_CellsBuilder.h"
 
 %typemap(out) std::list< std::shared_ptr< GeomAPI_Shape > >::value_type & {
   $result = SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr<GeomAPI_Shape>(*$1)), $descriptor(std::shared_ptr<GeomAPI_Shape> *), SWIG_POINTER_OWN | 0 );
 }
-%template(ShapeList) std::list<std::shared_ptr<GeomAPI_Shape> >;
\ No newline at end of file
+%template(ShapeList) std::list<std::shared_ptr<GeomAPI_Shape> >;
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_CellsBuilder.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_CellsBuilder.cpp
new file mode 100644 (file)
index 0000000..fde58c6
--- /dev/null
@@ -0,0 +1,167 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_CellsBuilder.h
+// Created:     11 December 2015
+// Author:      Dmitry Bobylev
+
+#include "GeomAlgoAPI_CellsBuilder.h"
+
+#include <GeomAlgoAPI_ShapeTools.h>
+
+#include <BOPAlgo_CellsBuilder.hxx>
+#include <TopoDS_Builder.hxx>
+
+#define MY_CELLSBUILDER implPtr<BOPAlgo_CellsBuilder>()
+
+/// \brief Converts std::list<GeomAPI_Shape> to NCollection_List<TopoDS_Shape>.
+/// \param[in] theStdListOfShape std::list.
+/// \param[out] theNCollectionListOfShape NCollection_List. Will be cleared before converting.
+static void stdListToNCollectionList(const ListOfShape& theStdListOfShape,
+                                     NCollection_List<TopoDS_Shape>& theNCollectionListOfShape);
+
+//=================================================================================================
+GeomAlgoAPI_CellsBuilder::GeomAlgoAPI_CellsBuilder()
+: GeomAlgoAPI_MakeShape(new BOPAlgo_CellsBuilder(), OCCT_BOPAlgo_Builder)
+{
+}
+
+//=================================================================================================
+void GeomAlgoAPI_CellsBuilder::setArguments(const ListOfShape &theLS)
+{
+  NCollection_List<TopoDS_Shape> aLS;
+  stdListToNCollectionList(theLS, aLS);
+
+  MY_CELLSBUILDER->SetArguments(aLS);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_CellsBuilder::setFuzzyValue(const double theFuzz)
+{
+  MY_CELLSBUILDER->SetFuzzyValue(theFuzz);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_CellsBuilder::setRunParallel(const bool theFlag)
+{
+  MY_CELLSBUILDER->SetRunParallel(theFlag);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_CellsBuilder::perform()
+{
+  MY_CELLSBUILDER->Perform();
+}
+
+//=================================================================================================
+void GeomAlgoAPI_CellsBuilder::clear()
+{
+  MY_CELLSBUILDER->Clear();
+}
+
+//=================================================================================================
+void GeomAlgoAPI_CellsBuilder::addToResult(const ListOfShape& theLSToTake,
+                                           const ListOfShape& theLSToAvoid,
+                                           const int theMaterial,
+                                           const bool theUpdate)
+{
+  NCollection_List<TopoDS_Shape> aLSToTake, aLSToAvoid;
+  stdListToNCollectionList(theLSToTake, aLSToTake);
+  stdListToNCollectionList(theLSToAvoid, aLSToAvoid);
+
+  MY_CELLSBUILDER->AddToResult(aLSToTake, aLSToAvoid, theMaterial, theUpdate);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_CellsBuilder::addAllToResult(const int theMaterial,
+                                              const bool theUpdate)
+{
+  MY_CELLSBUILDER->AddAllToResult(theMaterial, theUpdate);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_CellsBuilder::removeFromResult(const ListOfShape& theLSToTake,
+                                                const ListOfShape& theLSToAvoid)
+{
+  NCollection_List<TopoDS_Shape> aLSToTake, aLSToAvoid;
+  stdListToNCollectionList(theLSToTake, aLSToTake);
+  stdListToNCollectionList(theLSToAvoid, aLSToAvoid);
+
+  MY_CELLSBUILDER->RemoveFromResult(aLSToTake, aLSToAvoid);
+}
+
+//=================================================================================================
+void GeomAlgoAPI_CellsBuilder::removeAllFromResult()
+{
+  MY_CELLSBUILDER->RemoveAllFromResult();
+}
+
+//=================================================================================================
+void GeomAlgoAPI_CellsBuilder::removeInternalBoundaries()
+{
+  MY_CELLSBUILDER->RemoveInternalBoundaries();
+}
+
+//=================================================================================================
+const std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_CellsBuilder::getAllParts() const
+{
+  const TopoDS_Shape aShape = MY_CELLSBUILDER->GetAllParts();
+  std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape());
+  aGeomShape->setImpl(new TopoDS_Shape(aShape));
+  return aGeomShape;
+}
+
+//=================================================================================================
+void GeomAlgoAPI_CellsBuilder::makeContainers()
+{
+  MY_CELLSBUILDER->MakeContainers();
+}
+
+//=================================================================================================
+bool GeomAlgoAPI_CellsBuilder::isDone() const
+{
+  return MY_CELLSBUILDER->ErrorStatus() == 0;
+}
+
+//=================================================================================================
+GEOMALGOAPI_EXPORT const std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_CellsBuilder::shape() const
+{
+  std::shared_ptr<GeomAPI_Shape> aResShape(new GeomAPI_Shape());
+  TopoDS_Shape aShape = MY_CELLSBUILDER->Shape();
+
+  if(aShape.ShapeType() == TopAbs_COMPOUND) {
+    std::shared_ptr<GeomAPI_Shape> aCompound(new GeomAPI_Shape);
+    aCompound->setImpl(new TopoDS_Shape(aShape));
+    ListOfShape aCompSolids, aFreeSolids;
+    GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids);
+    if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) {
+      aShape = aCompSolids.front()->impl<TopoDS_Shape>();
+    } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) {
+      TopoDS_Compound aResultComp;
+      TopoDS_Builder aBuilder;
+      aBuilder.MakeCompound(aResultComp);
+      for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) {
+        aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
+      }
+      for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) {
+        aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
+      }
+      aShape = aResultComp;
+    }
+  }
+
+  aResShape->setImpl(new TopoDS_Shape(aShape));
+  const_cast<GeomAlgoAPI_CellsBuilder*>(this)->setShape(aResShape);
+
+  return GeomAlgoAPI_MakeShape::shape();
+}
+
+//=================================================================================================
+void stdListToNCollectionList(const ListOfShape& theStdListOfShape,
+                              NCollection_List<TopoDS_Shape>& theNCollectionListOfShape)
+{
+  theNCollectionListOfShape.Clear();
+  for(ListOfShape::const_iterator anIt = theStdListOfShape.cbegin(); anIt != theStdListOfShape.cend(); anIt++) {
+    const TopoDS_Shape aShape = (*anIt)->impl<TopoDS_Shape>();
+    theNCollectionListOfShape.Append(aShape);
+  }
+}
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_CellsBuilder.h b/src/GeomAlgoAPI/GeomAlgoAPI_CellsBuilder.h
new file mode 100644 (file)
index 0000000..e758139
--- /dev/null
@@ -0,0 +1,94 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_CellsBuilder.h
+// Created:     11 December 2015
+// Author:      Dmitry Bobylev
+
+#ifndef GeomAlgoAPI_CellsBuilder_H_
+#define GeomAlgoAPI_CellsBuilder_H_
+
+#include <GeomAlgoAPI.h>
+
+#include <GeomAlgoAPI_MakeShape.h>
+
+#include <memory>
+
+/// \class GeomAlgoAPI_CellsBuilder
+/// \ingroup DataAlgo
+/// \brief The purpose of this algorithm is to provide the result with the content of:
+///        1. Cells (parts) defined by the user;
+///        2. Internal boundaries defined by the user.
+class GeomAlgoAPI_CellsBuilder : public GeomAlgoAPI_MakeShape
+{
+public:
+  /// Default empty constructor.
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_CellsBuilder();
+
+  /// \brief Sets arguments for the algorithm.
+  /// \param[in] theLS list of shape.
+  GEOMALGOAPI_EXPORT void setArguments(const ListOfShape &theLS);
+
+  /// Sets the additional tolerance.
+  /// \param[in] theFuzz fuzz value.
+  GEOMALGOAPI_EXPORT void setFuzzyValue(const double theFuzz);
+
+  /// \brief Sets the flag of parallel processing. If \p theFlag is true the parallel processing is switched on,
+  /// if \p theFlag is false the parallel processing is switched off.
+  /// \param[in] theFlag flag value.
+  GEOMALGOAPI_EXPORT void setRunParallel(const bool theFlag);
+
+  /// \brief Make cells from the arguments.
+  GEOMALGOAPI_EXPORT void perform();
+
+  /// Clears the contents.
+  GEOMALGOAPI_EXPORT void clear();
+
+  /// \brief Adding the parts to result.
+  /// The parts are defined by two lists of shapes. To be taken into result the part must be IN
+  /// for all shapes from the list \p theLSToTake and must be OUT of all shapes from the list \p theLSToAvoid.
+  /// To remove internal boundaries between any cells in the result \p theMaterial variable should be used.
+  /// The boundaries between cells with the same material will be removed. Default value is 0.
+  /// Thus, to remove any boundary the value of this variable should not be equal to 0.
+  /// \param[in] theLSToTake defines the arguments which parts should be taken into result.
+  /// \param[in] theLSToAvoid defines the arguments which parts should not be taken into result.
+  /// \param[in] theMaterial material id.
+  /// \param[in] theUpdate defines whether to remove boundaries now or not.
+  GEOMALGOAPI_EXPORT void addToResult(const ListOfShape& theLSToTake,
+                                      const ListOfShape& theLSToAvoid,
+                                      const int theMaterial = 0,
+                                      const bool theUpdate = false);
+
+  /// \brief Add all split parts to result
+  /// \param[in] theMaterial defines the removal of internal boundaries.
+  /// \param[in] theUpdate defines whether to remove boundaries now or not.
+  GEOMALGOAPI_EXPORT void addAllToResult(const int theMaterial = 0,
+                                         const bool theUpdate = false);
+
+  /// \brief Removing the parts from result.
+  /// The parts are defined by two lists of shapes. To be removed from the result the part must be IN
+  /// for all shapes from the list \p theLSToTake and must be OUT of all shapes from the list \p theLSToAvoid.
+  /// \param[in] theLSToTake defines the arguments which parts should be removed from result.
+  /// \param[in] theLSToAvoid defines the arguments which parts should not be removed from result.
+  GEOMALGOAPI_EXPORT void removeFromResult(const ListOfShape& theLSToTake,
+                                           const ListOfShape& theLSToAvoid);
+
+  /// Remove all parts from result.
+  GEOMALGOAPI_EXPORT void removeAllFromResult();
+
+  /// Removes internal boundaries between cells with the same material.
+  GEOMALGOAPI_EXPORT void removeInternalBoundaries();
+
+  /// Get all split parts.
+  GEOMALGOAPI_EXPORT const std::shared_ptr<GeomAPI_Shape> getAllParts() const;
+
+  /// Makes the Containers of proper type from the parts added to result.
+  GEOMALGOAPI_EXPORT void makeContainers();
+
+  /// \return status of builder.
+  GEOMALGOAPI_EXPORT bool isDone() const;
+
+  /// \return a shape built by the shape construction algorithm.
+  GEOMALGOAPI_EXPORT const std::shared_ptr<GeomAPI_Shape> shape() const;
+};
+
+#endif
\ No newline at end of file
index de201f61c10e071b8c92d7f475d13483bd123061..dcdbe50a6ee8d5c77bc3ee694e4f965d88628a30 100644 (file)
@@ -7,8 +7,7 @@
 #include <GeomAlgoAPI_ShapeTools.h>
 
 #include <GeomAlgoAPI_CompoundBuilder.h>
-
-#include <gp_Pln.hxx>
+#include <GeomAPI_ShapeExplorer.h>
 
 #include <Bnd_Box.hxx>
 #include <BOPTools.hxx>
 #include <Geom_Plane.hxx>
 #include <GeomLib_IsPlanarSurface.hxx>
 #include <GeomLib_Tool.hxx>
+#include <gp_Pln.hxx>
 #include <GProp_GProps.hxx>
 #include <IntAna_IntConicQuad.hxx>
 #include <IntAna_Quadric.hxx>
 #include <NCollection_Vector.hxx>
 #include <TCollection_AsciiString.hxx>
+#include <TopExp_Explorer.hxx>
 #include <TopoDS_Builder.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Shell.hxx>
 #include <TopoDS.hxx>
-#include <TopExp_Explorer.hxx>
 
 
 //=================================================================================================
@@ -288,3 +288,22 @@ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::fitPlaneToBox(const std::
 
   return aResultShape;
 }
+
+//=================================================================================================
+void GeomAlgoAPI_ShapeTools::getSolidsInCompSolid(const std::shared_ptr<GeomAPI_Shape> theCompSolid,
+                                                  const ListOfShape& theSolidsToAvoid,
+                                                  ListOfShape& theSolidsInCompSolid)
+{
+  for(GeomAPI_ShapeExplorer anExp(theCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
+    std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
+    ListOfShape::const_iterator anIt = theSolidsToAvoid.begin();
+    for(; anIt != theSolidsToAvoid.end(); anIt++) {
+      if(aSolidInCompSolid->isEqual(*anIt)) {
+        break;
+      }
+    }
+    if(anIt == theSolidsToAvoid.end()) {
+      theSolidsInCompSolid.push_back(aSolidInCompSolid);
+    }
+  }
+}
index d361eb927b34cd9aaefcd4b38fb4b1ef044f9813..c20589487240c23ac3b5a9af2b56338e05a3caec 100644 (file)
 
 #include <map>
 
-/** \class GeomAlgoAPI_ShapeTools
- *  \ingroup DataAlgo
- *  \brief Useful tools for working with shapes.
- */
-class GEOMALGOAPI_EXPORT GeomAlgoAPI_ShapeTools
+/// \namespace GeomAlgoAPI_ShapeTools
+/// \ingroup DataAlgo
+/// \brief Useful tools for working with shapes.
+namespace GeomAlgoAPI_ShapeTools
 {
-public:
   /// \return the total volume of the solids of the current shape or 0.0 if it can be computed.
-  static double volume(const std::shared_ptr<GeomAPI_Shape> theShape);
+  GEOMALGOAPI_EXPORT double volume(const std::shared_ptr<GeomAPI_Shape> theShape);
 
   /// \return the centre of mass of the current face. The coordinates returned for the center of mass
   /// are expressed in the absolute Cartesian coordinate system. (This function works only for surfaces).
-  static std::shared_ptr<GeomAPI_Pnt> centreOfMass(const std::shared_ptr<GeomAPI_Shape> theShape);
-
-  /** \brief Combines faces with common edges to shells, or solids to compsolids.
-   *  \param[in] theCompound compound of shapes.
-   *  \param[in] theType type of combine.
-   *  \param[out] theCombinedShapes resulting shapes.
-   *  \param[out] theFreeShapes shapes that does not have common subshapes.
-   */
-  static void combineShapes(const std::shared_ptr<GeomAPI_Shape> theCompound,
-                            const GeomAPI_Shape::ShapeType theType,
-                            ListOfShape& theCombinedShapes,
-                            ListOfShape& theFreeShapes);
-
-  /** \brief Calculates bounding box for theShapes
-   *  \return list of eight points.
-   *  \param[in] theShapes list of shapes.
-   *  \param[in] theEnlarge enlarges bounding box size.
-   */
-  static std::list<std::shared_ptr<GeomAPI_Pnt> > getBoundingBox(const ListOfShape& theShapes, const double theEnlarge = 0.0);
-
-  /**
-   * Returns infinite plane received from theFace plane.
-   */
-  static std::shared_ptr<GeomAPI_Shape> faceToInfinitePlane(const std::shared_ptr<GeomAPI_Shape> theFace);
-
-  /** \brief Enlarges or reduces plane to fit bounding box.
-   *  \return plane that fits to bounding box.
-   *  \param[in] thePlane base plane.
-   *  \param[in] thePoints bounding box points (shoud be eight).
-   */
-  static std::shared_ptr<GeomAPI_Shape> fitPlaneToBox(const std::shared_ptr<GeomAPI_Shape> thePlane,
-                                                      const std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints);
-
-};
+  GEOMALGOAPI_EXPORT std::shared_ptr<GeomAPI_Pnt> centreOfMass(const std::shared_ptr<GeomAPI_Shape> theShape);
+
+  /// \brief Combines faces with common edges to shells, or solids to compsolids.
+  /// \param[in] theCompound compound of shapes.
+  /// \param[in] theType type of combine.
+  /// \param[out] theCombinedShapes resulting shapes.
+  /// \param[out] theFreeShapes shapes that does not have common subshapes.
+  GEOMALGOAPI_EXPORT void combineShapes(const std::shared_ptr<GeomAPI_Shape> theCompound,
+                                        const GeomAPI_Shape::ShapeType theType,
+                                        ListOfShape& theCombinedShapes,
+                                        ListOfShape& theFreeShapes);
+
+  /// \brief Calculates bounding box for theShapes
+  /// \return list of eight points.
+  /// \param[in] theShapes list of shapes.
+  /// \param[in] theEnlarge enlarges bounding box size.
+  GEOMALGOAPI_EXPORT std::list<std::shared_ptr<GeomAPI_Pnt> > getBoundingBox(const ListOfShape& theShapes, const double theEnlarge = 0.0);
+
+  /// \return infinite plane received from theFace plane.
+  /// \param[in] theFace base face.
+  GEOMALGOAPI_EXPORT std::shared_ptr<GeomAPI_Shape> faceToInfinitePlane(const std::shared_ptr<GeomAPI_Shape> theFace);
+
+  /// \brief Enlarges or reduces plane to fit bounding box.
+  /// \return plane that fits to bounding box.
+  /// \param[in] thePlane base plane.
+  /// \param[in] thePoints bounding box points (shoud be eight).
+  GEOMALGOAPI_EXPORT std::shared_ptr<GeomAPI_Shape> fitPlaneToBox(const std::shared_ptr<GeomAPI_Shape> thePlane,
+                                                                  const std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints);
+
+  /// \brief Get list of solids from theCompSolid which is not present in theSolidsToAvoid list.
+  /// \param[in] theCompSolid compsolid.
+  /// \param[in] theSolidsToAvoid list of solids to avoid.
+  /// \param[out] theSolidsInCompSolid list of solids in compsolid. Note: list not cleared before adding.
+  GEOMALGOAPI_EXPORT void getSolidsInCompSolid(const std::shared_ptr<GeomAPI_Shape> theCompSolid,
+                                               const ListOfShape& theSolidsToAvoid,
+                                               ListOfShape& theSolidsInCompSolid);
+}
 
 #endif
index 164f8ec61783d4325a54ecaa18549daa68f056b6..d6c800bdbfa8519b034fe639b55a6ea7e55e26c5 100644 (file)
@@ -34,6 +34,7 @@
   #include "GeomAlgoAPI_Tools.h"
   #include "GeomAlgoAPI_Transform.h"
   #include "GeomAlgoAPI_PaveFiller.h"
+  #include "GeomAlgoAPI_CellsBuilder.h"
 
   #include <memory>
   #include <string>