Salome HOME
Task 3.2. Concealment into multi-level Compounds
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_BooleanFuse.cpp
index 53c8d66f74edf23cc21c71b791f58bc2c7c7bd75..84df36d061a8ef547e4d8daed7d064d5ee205a78 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_AttributeBoolean.h>
+#include <ModelAPI_AttributeInteger.h>
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_AttributeString.h>
 #include <ModelAPI_Session.h>
 #include <GeomAlgoAPI_Boolean.h>
 #include <GeomAlgoAPI_MakeShapeList.h>
 #include <GeomAlgoAPI_PaveFiller.h>
+#include <GeomAlgoAPI_ShapeBuilder.h>
 #include <GeomAlgoAPI_ShapeTools.h>
 #include <GeomAlgoAPI_Tools.h>
 #include <GeomAlgoAPI_UnifySameDomain.h>
+
 #include <GeomAPI_ShapeExplorer.h>
+#include <GeomAPI_ShapeIterator.h>
+
+static const int THE_FUSE_VERSION_1 = 20190506;
 
 //==================================================================================================
 FeaturesPlugin_BooleanFuse::FeaturesPlugin_BooleanFuse()
@@ -55,6 +61,17 @@ void FeaturesPlugin_BooleanFuse::initAttributes()
 
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), OBJECT_LIST_ID());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TOOL_LIST_ID());
+
+  AttributePtr aVerAttr = data()->addAttribute(VERSION_ID(), ModelAPI_AttributeInteger::typeId());
+  aVerAttr->setIsArgument(false);
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), VERSION_ID());
+  if (!integer(VERSION_ID())->isInitialized() &&
+      !selectionList(OBJECT_LIST_ID())->isInitialized() &&
+      !selectionList(TOOL_LIST_ID())->isInitialized()) {
+    // this is a newly created feature (not read from file),
+    // so, initialize the latest version
+    integer(VERSION_ID())->setValue(THE_FUSE_VERSION_1);
+  }
 }
 
 //==================================================================================================
@@ -62,7 +79,7 @@ void FeaturesPlugin_BooleanFuse::execute()
 {
   std::string anError;
   ObjectHierarchy anObjectsHierarchy, aToolsHierarchy;
-  ListOfShape aPlanes, anEdgesAndFaces;
+  ListOfShape aPlanes;
 
   bool isSimpleCreation = false;
 
@@ -74,16 +91,20 @@ void FeaturesPlugin_BooleanFuse::execute()
   }
 
   // Getting objects.
-  if (!processAttribute(OBJECT_LIST_ID(), anObjectsHierarchy, aPlanes, anEdgesAndFaces))
+  if (!processAttribute(OBJECT_LIST_ID(), anObjectsHierarchy, aPlanes))
     return;
 
   // Getting tools.
   if (!isSimpleCreation &&
-      !processAttribute(TOOL_LIST_ID(), aToolsHierarchy, aPlanes, anEdgesAndFaces))
+      !processAttribute(TOOL_LIST_ID(), aToolsHierarchy, aPlanes))
     return;
 
-  ListOfShape anObjects = anObjectsHierarchy.Objects();
-  ListOfShape aTools = aToolsHierarchy.Objects();
+  ListOfShape anObjects, aTools, anEdgesAndFaces;
+  // all objects except edges and faces
+  anObjectsHierarchy.ObjectsByType(anEdgesAndFaces, anObjects,
+                                   GeomAPI_Shape::FACE, GeomAPI_Shape::EDGE);
+  aToolsHierarchy.ObjectsByType(anEdgesAndFaces, aTools,
+                                GeomAPI_Shape::FACE, GeomAPI_Shape::EDGE);
 
   if ((anObjects.size() + aTools.size() + anEdgesAndFaces.size()) < 2) {
     std::string aFeatureError = "Error: Not enough objects for boolean operation.";
@@ -91,6 +112,9 @@ void FeaturesPlugin_BooleanFuse::execute()
     return;
   }
 
+  // version of FUSE feature
+  int aFuseVersion = version();
+
   // Collecting all solids which will be fused.
   ListOfShape aSolidsToFuse;
   aSolidsToFuse.insert(aSolidsToFuse.end(), anObjects.begin(), anObjects.end());
@@ -106,6 +130,9 @@ void FeaturesPlugin_BooleanFuse::execute()
     GeomShapePtr aParent = anObjectsHierarchy.Parent(anObject, false);
 
     if (aParent && aParent->shapeType() == GeomAPI_Shape::COMPSOLID) {
+      // mark all subs of this parent as precessed to avoid handling twice
+      aParent = anObjectsHierarchy.Parent(anObject);
+
       ListOfShape aUsed, aNotUsed;
       anObjectsHierarchy.SplitCompound(aParent, aUsed, aNotUsed);
       aShapesToAdd.insert(aShapesToAdd.end(), aNotUsed.begin(), aNotUsed.end());
@@ -214,6 +241,12 @@ void FeaturesPlugin_BooleanFuse::execute()
     aMakeShapeList->appendAlgo(aUnifyAlgo);
   }
 
+  if (aFuseVersion == THE_FUSE_VERSION_1) {
+    // merge hierarchies of compounds containing objects and tools
+    // and append the result of the FUSE operation
+    aShape = keepUnusedSubsOfCompound(aShape, anObjectsHierarchy, aToolsHierarchy, aMakeShapeList);
+  }
+
   int aResultIndex = 0;
 
   ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);