]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Fix regressions related to treating edges and faces in Boolean operations.
authorazv <azv@opencascade.com>
Mon, 6 May 2019 08:47:49 +0000 (11:47 +0300)
committerazv <azv@opencascade.com>
Mon, 6 May 2019 08:47:49 +0000 (11:47 +0300)
src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp
src/FeaturesPlugin/FeaturesPlugin_Boolean.h
src/FeaturesPlugin/FeaturesPlugin_BooleanCommon.cpp
src/FeaturesPlugin/FeaturesPlugin_BooleanCut.cpp
src/FeaturesPlugin/FeaturesPlugin_BooleanFill.cpp
src/FeaturesPlugin/FeaturesPlugin_BooleanFuse.cpp

index 2220e4f06520d435f8435d8d2f03d44cfdab1a39..7f9ce37ac77b4a27d79d5d42dd71133c9edc666f 100644 (file)
@@ -87,8 +87,7 @@ void FeaturesPlugin_Boolean::parentForShape(const GeomShapePtr& theShape,
 
 bool FeaturesPlugin_Boolean::processAttribute(const std::string& theAttributeName,
                                               ObjectHierarchy& theObjects,
-                                              ListOfShape& thePlanesList,
-                                              ListOfShape& theEdgesAndFaces)
+                                              ListOfShape& thePlanesList)
 {
   AttributeSelectionListPtr anObjectsSelList = selectionList(theAttributeName);
   for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
@@ -105,12 +104,6 @@ bool FeaturesPlugin_Boolean::processAttribute(const std::string& theAttributeNam
         return false;
     }
 
-    if (anObject->shapeType() == GeomAPI_Shape::EDGE ||
-        anObject->shapeType() == GeomAPI_Shape::FACE) {
-      theEdgesAndFaces.push_back(anObject);
-      continue;
-    }
-
     theObjects.AddObject(anObject);
 
     ResultPtr aContext = anObjectAttr->context();
@@ -448,6 +441,31 @@ GeomShapePtr FeaturesPlugin_Boolean::ObjectHierarchy::Parent(const GeomShapePtr&
   return aParent;
 }
 
+void FeaturesPlugin_Boolean::ObjectHierarchy::ObjectsByType(
+    ListOfShape& theShapesByType,
+    ListOfShape& theOtherShapes,
+    const GeomAPI_Shape::ShapeType theMinType,
+    const GeomAPI_Shape::ShapeType theMaxType) const
+{
+  if (theMinType > theMaxType)
+    return ObjectsByType(theShapesByType, theOtherShapes, theMaxType, theMinType);
+
+  // no need to select objects if whole range is specified
+  if (theMinType == GeomAPI_Shape::COMPOUND && theMaxType == GeomAPI_Shape::SHAPE) {
+    theShapesByType.insert(theShapesByType.end(), myObjects.begin(), myObjects.end());
+    return;
+  }
+
+  for (ListOfShape::const_iterator anIt = myObjects.begin(); anIt != myObjects.end(); ++anIt) {
+    GeomAPI_Shape::ShapeType aType = (*anIt)->shapeType();
+    if (aType >= theMinType && aType <= theMaxType)
+      theShapesByType.push_back(*anIt);
+    else
+      theOtherShapes.push_back(*anIt);
+  }
+}
+
+
 void FeaturesPlugin_Boolean::ObjectHierarchy::SplitCompound(const GeomShapePtr& theCompShape,
                                                             ListOfShape& theUsed,
                                                             ListOfShape& theNotUsed) const
index 14edc73b33607e3b345e7971e7dd52238c86af2b..a72c3efe9e483319ed4ff29457625a4ae83b0a47 100644 (file)
@@ -112,6 +112,10 @@ protected:
 
     /// Return list of objects
     const ListOfShape& Objects() const { return myObjects; }
+    /// Separate objects of the given range of types and all other objects
+    void ObjectsByType(ListOfShape& theShapesByType, ListOfShape& theOtherShapes,
+        const GeomAPI_Shape::ShapeType theMinType = GeomAPI_Shape::COMPOUND,
+        const GeomAPI_Shape::ShapeType theMaxType = GeomAPI_Shape::SHAPE) const;
 
   public:
     class Iterator {
@@ -142,8 +146,7 @@ protected:
   /// Process SelectionList attribute and fill the objects hierarchy.
   bool processAttribute(const std::string& theAttributeName,
                         ObjectHierarchy& theObjects,
-                        ListOfShape& thePlanesList,
-                        ListOfShape& theEdgesAndFaces);
+                        ListOfShape& thePlanesList);
 
   /// Perform Boolean operation of the object with the tools
   /// \return \c false if something went wrong
index 8506bc005022065380d747a0d87702c92945d376..af2d556f18afdd568e4375bac1c22b7cf6850ffe 100644 (file)
@@ -54,7 +54,7 @@ void FeaturesPlugin_BooleanCommon::initAttributes()
 //==================================================================================================
 void FeaturesPlugin_BooleanCommon::execute()
 {
-  ListOfShape aPlanes, anEdgesAndFaces;
+  ListOfShape aPlanes;
   ObjectHierarchy anObjects, aTools;
 
   bool isSimpleMode = false;
@@ -66,14 +66,14 @@ void FeaturesPlugin_BooleanCommon::execute()
   }
 
   // Getting objects.
-  if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes, anEdgesAndFaces))
+  if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes))
     return;
   // Planes are not supported as objects of COMMON operation
   aPlanes.clear();
 
   // Getting tools.
   if (!isSimpleMode &&
-      !processAttribute(TOOL_LIST_ID(), aTools, aPlanes, anEdgesAndFaces))
+      !processAttribute(TOOL_LIST_ID(), aTools, aPlanes))
     return;
 
   if (anObjects.IsEmpty() || (!isSimpleMode && aTools.IsEmpty() && aPlanes.empty())) {
index e6ba621a43b6989a76370b3108d104f7160e4f29..be93d26ec8233e3e33dc7076135108b13e9ecbf1 100644 (file)
@@ -45,11 +45,11 @@ FeaturesPlugin_BooleanCut::FeaturesPlugin_BooleanCut()
 void FeaturesPlugin_BooleanCut::execute()
 {
   ObjectHierarchy anObjects, aTools;
-  ListOfShape aPlanes, anEdgesAndFaces;
+  ListOfShape aPlanes;
 
   // Getting objects and tools
-  if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes, anEdgesAndFaces) ||
-      !processAttribute(TOOL_LIST_ID(), aTools, aPlanes, anEdgesAndFaces))
+  if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes) ||
+      !processAttribute(TOOL_LIST_ID(), aTools, aPlanes))
     return;
 
   int aResultIndex = 0;
index 1088fd82005dc401997373589f68f069a37cb825..a907823addc16bb4173a6e1982dfd4722f82f9e4 100644 (file)
@@ -51,16 +51,16 @@ void FeaturesPlugin_BooleanFill::execute()
 {
   std::string anError;
   ObjectHierarchy anObjects, aTools;
-  ListOfShape aPlanes, anEdgesAndFaces;
+  ListOfShape aPlanes;
 
   // Getting objects.
-  if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes, anEdgesAndFaces))
+  if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes))
     return;
   // Planes are not supported as objects of FILL operation
   aPlanes.clear();
 
   // Getting tools.
-  if (!processAttribute(TOOL_LIST_ID(), aTools, aPlanes, anEdgesAndFaces))
+  if (!processAttribute(TOOL_LIST_ID(), aTools, aPlanes))
     return;
 
   int aResultIndex = 0;
index 83fb8689599f851811041b52eada5e2c1c6f58b1..497d529e43ad221c3941eac83a2529ac3fce4750 100644 (file)
@@ -62,7 +62,7 @@ void FeaturesPlugin_BooleanFuse::execute()
 {
   std::string anError;
   ObjectHierarchy anObjectsHierarchy, aToolsHierarchy;
-  ListOfShape aPlanes, anEdgesAndFaces;
+  ListOfShape aPlanes;
 
   bool isSimpleCreation = false;
 
@@ -74,16 +74,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.";
@@ -106,6 +110,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());
@@ -126,6 +133,8 @@ void FeaturesPlugin_BooleanFuse::execute()
       aMakeShapeList->appendAlgo(aCutAlgo);
     }
   }
+  anOriginalShapes.insert(anOriginalShapes.end(), anEdgesAndFaces.begin(),
+                          anEdgesAndFaces.end());
 
   // If we have compsolids then cut with not used solids all others.
   if (!aShapesToAdd.empty()) {
@@ -144,9 +153,6 @@ void FeaturesPlugin_BooleanFuse::execute()
     }
   }
 
-  anOriginalShapes.insert(anOriginalShapes.end(), anEdgesAndFaces.begin(),
-                          anEdgesAndFaces.end());
-
   if (!aSolidsToFuse.empty()) {
     anObjects.clear();
     anObjects.push_back(aSolidsToFuse.back());