Salome HOME
[bos #24758] EDF 24017 - Problems with ExtrusionCut. Corrected also ExtrusionFuse...
authorjfa <jfa@opencascade.com>
Tue, 12 Oct 2021 08:32:11 +0000 (11:32 +0300)
committerjfa <jfa@opencascade.com>
Tue, 12 Oct 2021 08:32:11 +0000 (11:32 +0300)
src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp
src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.h

index bf5293d83a0c3695653c13386790360dbfea3593..199fb3c6e8d221aefe19c8d0764bca0a816fe1ff 100644 (file)
@@ -199,6 +199,32 @@ bool FeaturesPlugin_CompositeBoolean::cutRecursiveCompound(const GeomShapePtr th
   return false; // no cuts
 }
 
+//=================================================================================================
+void FeaturesPlugin_CompositeBoolean::addSubShapes (const GeomShapePtr theCompound,
+                                                    const ListOfShape& theSubShapesToAvoid,
+                                                    ListOfShape& theSubShapesToAdd) {
+  for (GeomAPI_ShapeIterator aCompoundIt (theCompound);
+       aCompoundIt.more();
+       aCompoundIt.next()) {
+    GeomShapePtr aCompoundSS = aCompoundIt.current();
+    ListOfShape::const_iterator aUseIt = theSubShapesToAvoid.cbegin();
+    for (; aUseIt != theSubShapesToAvoid.cend(); aUseIt++) {
+      if (aCompoundSS->isEqual(*aUseIt)) {
+        break;
+      }
+    }
+    if (aUseIt == theSubShapesToAvoid.cend()) {
+      if (aCompoundSS->shapeType() == GeomAPI_Shape::COMPSOLID ||
+          aCompoundSS->shapeType() == GeomAPI_Shape::COMPOUND) {
+        addSubShapes(aCompoundSS, theSubShapesToAvoid, theSubShapesToAdd);
+      }
+      else {
+        theSubShapesToAdd.push_back(aCompoundSS);
+      }
+    }
+  }
+}
+
 //=================================================================================================
 bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
                                                   ListOfShape& theObjects,
@@ -239,10 +265,8 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
     ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
     if(aResCompSolidPtr.get()) {
       ResultBodyPtr aResRootPtr = ModelAPI_Tools::bodyOwner(aContext, true);
-      if (!aCompoundsMap.isBound(aResRootPtr->shape()) || myOperationType != BOOL_CUT) {
+      if (!aCompoundsMap.isBound(aResRootPtr->shape())) {
         // Compsolid or a simple (one-level) compound
-        // Or not CUT
-        // TODO: correct FUSE for complex compounds?
         GeomShapePtr aContextShape = aResCompSolidPtr->shape();
         std::map<GeomShapePtr, ListOfShape>::iterator anIt = aCompSolidsObjects.begin();
         for(; anIt != aCompSolidsObjects.end(); anIt++) {
@@ -386,6 +410,7 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
       theObjects.insert(theObjects.end(), anEdgesAndFaces.begin(), anEdgesAndFaces.end());
       theObjects.insert(theObjects.end(), anObjects.begin(), anObjects.end());
       theObjects.insert(theObjects.end(), aCompSolids.begin(), aCompSolids.end());
+      theObjects.insert(theObjects.end(), aCompounds.begin(), aCompounds.end());
 
       // Filter edges and faces in tools.
       ListOfShape aTools;
@@ -398,7 +423,7 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
         }
       }
 
-      if((anObjects.size() + aTools.size() +
+      if((anObjects.size() + aTools.size() + aCompounds.size() +
           aCompSolidsObjects.size() + anEdgesAndFaces.size()) < 2) {
         myFeature->setError("Error: Not enough objects for boolean operation.");
         return false;
@@ -409,31 +434,23 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
       aSolidsToFuse.insert(aSolidsToFuse.end(), anObjects.begin(), anObjects.end());
       aSolidsToFuse.insert(aSolidsToFuse.end(), aTools.begin(), aTools.end());
 
-      // Collecting solids from compsolids which will not be
+      // Collecting solids and compsolids from compounds which will not be
       // modified in boolean operation and will be added to result.
       ListOfShape aShapesToAdd;
-      for(std::map<GeomShapePtr, ListOfShape>::iterator anIt = aCompSolidsObjects.begin();
-          anIt != aCompSolidsObjects.end(); anIt++) {
+      for (ListOfShape::iterator anIt = aCompounds.begin();
+           anIt != aCompounds.end(); anIt++) {
+        GeomShapePtr aCompound = (*anIt);
+        addSubShapes(aCompound, anObjects, aShapesToAdd);
+      }
+
+      // Collecting solids from compsolids which will not be
+      // modified in boolean operation and will be added to result.
+      for (std::map<GeomShapePtr, ListOfShape>::iterator anIt = aCompSolidsObjects.begin();
+           anIt != aCompSolidsObjects.end(); anIt++) {
         GeomShapePtr aCompSolid = anIt->first;
         ListOfShape& aUsedShapes = anIt->second;
-        aSolidsToFuse.insert(aSolidsToFuse.end(), aUsedShapes.begin(), aUsedShapes.end());
-
-        // Collect solids from compsolid which will not be modified in boolean operation.
-        for (GeomAPI_ShapeIterator aCompSolidIt(aCompSolid);
-             aCompSolidIt.more();
-             aCompSolidIt.next())
-        {
-          GeomShapePtr aSolidInCompSolid = aCompSolidIt.current();
-          ListOfShape::iterator aUseIt = aUsedShapes.begin();
-          for(; aUseIt != aUsedShapes.end(); aUseIt++) {
-            if(aSolidInCompSolid->isEqual(*aUseIt)) {
-              break;
-            }
-          }
-          if(aUseIt == aUsedShapes.end()) {
-            aShapesToAdd.push_back(aSolidInCompSolid);
-          }
-        }
+        aSolidsToFuse.insert(aSolidsToFuse.end(), aUsedShapes.begin(), aUsedShapes.end()); //???
+        addSubShapes(aCompSolid, aUsedShapes, aShapesToAdd);
       }
 
       // Cut edges and faces(if we have any) with solids.
index bbcd26eb7cfd18c8eb163e5b1da495b7f841dd6d..3b91a61fad3f757fbac7f0cbc50054757c151462 100644 (file)
@@ -95,7 +95,8 @@ protected:
                           const GeomShapePtr theResultShapesCompound);
 
 private:
-  /// Makes cut operation recursively. Called from makeBoolean().
+  /// Makes cut operation recursively.
+  /// Called from makeBoolean().
   /// \param[in] theCompound the shape to be cut.
   /// \param[in] theTools list of tools.
   /// \param[out] theMakeShapeList list of according algos.
@@ -106,6 +107,16 @@ private:
                              std::shared_ptr<GeomAlgoAPI_MakeShapeList>& theMakeShapeList,
                              GeomShapePtr& theResult);
 
+  /// Add subshapes of \a theCompound to \a theSubShapesToAdd list,
+  /// except ones from \a theSubShapesToAvoid.
+  /// Called from makeBoolean().
+  /// \param[in] theCompound the shape to collect sub-shapes of.
+  /// \param[in] theSubShapesToAvoid list of shapes that should not be added to the result.
+  /// \param[out] theSubShapesToAdd list of found sub-shapes.
+  void addSubShapes (const GeomShapePtr theCompound,
+                     const ListOfShape& theSubShapesToAvoid,
+                     ListOfShape& theSubShapesToAdd);
+
 protected:
   ModelAPI_Feature* myFeature;
   OperationType myOperationType;