0030386: Modeling Algorithms - Unable to perform Cut operation
authoremv <emv@opencascade.com>
Fri, 21 Feb 2020 15:19:03 +0000 (18:19 +0300)
committerbugmaster <bugmaster@opencascade.com>
Wed, 4 Mar 2020 16:17:16 +0000 (19:17 +0300)
Get rid of requirement for the arguments of Boolean operations of type CUT and COMMON to be one-dimensional shape. For FUSE operation this requirement is kept.

18 files changed:
dox/dev_guides/upgrade/upgrade.md
src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx
src/BOPAlgo/BOPAlgo_BOP.cxx
src/BOPAlgo/BOPAlgo_Builder.cxx
src/BOPAlgo/BOPAlgo_Builder_3.cxx
src/BOPAlgo/BOPAlgo_CellsBuilder.cxx
src/BOPAlgo/BOPAlgo_MakeConnected.cxx
src/BOPAlgo/BOPAlgo_MakerVolume.cxx
src/BOPAlgo/BOPAlgo_RemoveFeatures.cxx
src/BOPAlgo/BOPAlgo_Tools.cxx
src/BOPAlgo/BOPAlgo_Tools.hxx
src/BOPTools/BOPTools_AlgoTools.hxx
src/BOPTools/BOPTools_AlgoTools_2.cxx
tests/bugs/modalg_7/bug30386_1 [new file with mode: 0644]
tests/bugs/modalg_7/bug30386_2 [new file with mode: 0644]
tests/bugs/modalg_7/bug30386_3 [new file with mode: 0644]
tests/bugs/modalg_7/bug30386_4 [new file with mode: 0644]
tests/bugs/modalg_7/bug30386_5 [new file with mode: 0644]

index 2ee0ba2..5ea184c 100644 (file)
@@ -1892,3 +1892,13 @@ Enumeration BRepOffset_Type is renamed to ChFiDS_TypeOfConcavity.
 @subsection upgrade_750_sensitiveEntity Select3D_SensitiveEntity interface change
 
 The method Select3D_SensitiveEntity::NbSubElements() has been changed to be constant. Select3D_SensitiveEntity subclasses at application level should be updated accordingly.
+
+
+@subsection upgrade_750_Booleans Changes in Boolean operations algorithm
+
+* TreatCompound method has been moved from *BOPAlgo_Tools* to *BOPTools_AlgoTools*. Additionally, the map parameter became optional:
+~~~~
+void BOPTools_AlgoTools::TreatCompound (const TopoDS_Shape& theS,
+                                        TopTools_ListOfShape& theLS,
+                                        TopTools_MapOfShape* theMap = NULL);
+~~~~
index 29c3535..4cc6e17 100644 (file)
@@ -305,30 +305,27 @@ void BOPAlgo_ArgumentAnalyzer::TestTypes()
       return;
     }
     //
-    Standard_Integer aDim1, aDim2;
-    Standard_Boolean bBadTypes = Standard_False;
-    //
-    aDim1 = BOPTools_AlgoTools::Dimension(myShape1);
-    aDim2 = BOPTools_AlgoTools::Dimension(myShape2);
-    if (aDim1 < aDim2) {
-      if (myOperation == BOPAlgo_FUSE ||
-          myOperation == BOPAlgo_CUT21) {
-        bBadTypes = Standard_True;
-      }
-    }
-    else if (aDim1 > aDim2) {
-      if (myOperation == BOPAlgo_FUSE ||
-          myOperation == BOPAlgo_CUT) {
-        bBadTypes = Standard_True;
+    if (myOperation != BOPAlgo_UNKNOWN &&
+        myOperation != BOPAlgo_COMMON)
+    {
+      Standard_Integer iDimMin[2], iDimMax[2];
+      BOPTools_AlgoTools::Dimensions(myShape1, iDimMin[0], iDimMax[0]);
+      BOPTools_AlgoTools::Dimensions(myShape2, iDimMin[1], iDimMax[1]);
+
+      Standard_Boolean bBadTypes =
+        ((myOperation == BOPAlgo_FUSE) &&
+           (iDimMin[0] != iDimMax[0] || iDimMin[1] != iDimMax[1] || iDimMin[0] != iDimMin[1])) ||
+        ((myOperation == BOPAlgo_CUT)   && (iDimMax[0] > iDimMin[1])) ||
+        ((myOperation == BOPAlgo_CUT21) && (iDimMin[0] < iDimMax[1]));
+
+      if (bBadTypes) {
+        BOPAlgo_CheckResult aResult;
+        aResult.SetShape1(myShape1);
+        aResult.SetShape2(myShape2);
+        aResult.SetCheckStatus(BOPAlgo_BadType);
+        myResult.Append(aResult);
       }
     }
-    if (bBadTypes) {
-      BOPAlgo_CheckResult aResult;
-      aResult.SetShape1(myShape1);
-      aResult.SetShape2(myShape2);
-      aResult.SetCheckStatus(BOPAlgo_BadType);
-      myResult.Append(aResult);
-    }
   }
 }
 //=======================================================================
index bffec87..a6f49f2 100644 (file)
@@ -122,7 +122,7 @@ BOPAlgo_Operation BOPAlgo_BOP::Operation()const
 //=======================================================================
 void BOPAlgo_BOP::CheckData()
 {
-  Standard_Integer i, j, iDim, aNbArgs, aNbTools;
+  Standard_Integer i, j, aNbArgs, aNbTools;
   Standard_Boolean bFuse;
   TopTools_ListIteratorOfListOfShape aItLS;
   //
@@ -164,7 +164,8 @@ void BOPAlgo_BOP::CheckData()
   //            or equal to the MAXIMAL dimension of the TOOLS;
   // 4. COMMON: The arguments and tools could have any dimensions.
   //
-  Standard_Integer iDimMin[2] = { 0, 0 }, iDimMax[2] = { 0, 0 };
+  Standard_Integer iDimMin[2] = { 3, 3 },
+                   iDimMax[2] = { 0, 0 };
   Standard_Boolean bHasValid[2] = {Standard_False, Standard_False};
   //
   for (i=0; i<2; ++i) {
@@ -173,38 +174,27 @@ void BOPAlgo_BOP::CheckData()
     for (j=0; aItLS.More(); aItLS.Next(), ++j) {
       const TopoDS_Shape& aS=aItLS.Value();
       Standard_Boolean bIsEmpty = BOPTools_AlgoTools3D::IsEmptyShape(aS);
-      if (bIsEmpty) {
+      if (bIsEmpty)
+      {
         AddWarning(new BOPAlgo_AlertEmptyShape (aS));
         continue;
       }
-      //
-      iDim = BOPTools_AlgoTools::Dimension(aS);
-      if (iDim < 0) {
+
+      Standard_Integer iDMin, iDMax;
+      BOPTools_AlgoTools::Dimensions(aS, iDMin, iDMax);
+
+      if (iDMin < iDimMin[i])
+        iDimMin[i] = iDMin;
+      if (iDMax > iDimMax[i])
+        iDimMax[i] = iDMax;
+
+      if (bFuse && (iDimMin[i] != iDimMax[i]))
+      {
         // non-homogeneous argument
         AddError (new BOPAlgo_AlertBOPNotAllowed);
         return;
       }
-      //
       bHasValid[i] = Standard_True;
-      //
-      if (!j) {
-        iDimMin[i] = iDim;
-        iDimMax[i] = iDim;
-        continue;
-      }
-      //
-      if (iDim < iDimMin[i]) {
-        iDimMin[i] = iDim;
-      }
-      else if (iDim > iDimMax[i]) {
-        iDimMax[i] = iDim;
-      }
-      //
-      if (bFuse && (iDimMin[i] != iDimMax[i])) {
-        // non-homogeneous argument
-        AddError (new BOPAlgo_AlertBOPNotAllowed);
-        return;
-      }
     }
   }
   //
@@ -222,7 +212,7 @@ void BOPAlgo_BOP::CheckData()
   if (bHasValid[0] || bHasValid[1])
   {
     // In case of all empty shapes in one of the groups
-    // this group aquires the dimension of other group
+    // this group acquires the dimension of other group
     myDims[0] = bHasValid[0] ? iDimMin[0] : iDimMin[1];
     myDims[1] = bHasValid[1] ? iDimMin[1] : iDimMin[0];
   }
@@ -583,12 +573,17 @@ void BOPAlgo_BOP::BuildRC()
     aItLS.Initialize(aLS);
     for (; aItLS.More(); aItLS.Next()) {
       const TopoDS_Shape& aS = aItLS.Value();
-      iDim = BOPTools_AlgoTools::Dimension(aS);
-      if (iDim < 0) {
-        continue;
+      TopTools_ListOfShape aList;
+      BOPTools_AlgoTools::TreatCompound (aS, aList);
+      for (TopTools_ListOfShape::Iterator itList (aList); itList.More(); itList.Next())
+      {
+        const TopoDS_Shape& aSS = itList.Value();
+        iDim = BOPTools_AlgoTools::Dimension (aSS);
+        if (iDim < 0)
+          continue;
+        aType = TypeToExplore (iDim);
+        TopExp::MapShapes (aSS, aType, aMS);
       }
-      aType = TypeToExplore(iDim);
-      TopExp::MapShapes(aS, aType, aMS);
     }
   }
   //
@@ -930,7 +925,7 @@ void BOPAlgo_BOP::BuildShape()
     for (; aItLS.More(); aItLS.Next())
     {
       const TopoDS_Shape& aS = aItLS.Value();
-      BOPAlgo_Tools::TreatCompound(aS, aMInpFence, aLSNonCont);
+      BOPTools_AlgoTools::TreatCompound(aS, aLSNonCont, &aMInpFence);
     }
   }
 
index 73b095a..875546f 100644 (file)
@@ -441,7 +441,7 @@ void BOPAlgo_Builder::BuildBOP(const TopTools_ListOfShape& theObjects,
       {
         TopTools_ListOfShape aLS;
         TopTools_MapOfShape aMFence;
-        BOPAlgo_Tools::TreatCompound(aS, aMFence, aLS);
+        BOPTools_AlgoTools::TreatCompound(aS, aLS, &aMFence);
 
         TopTools_ListOfShape::Iterator it(aLS);
         for (; it.More(); it.Next())
index 52aac55..040ce7b 100644 (file)
@@ -550,7 +550,7 @@ void BOPAlgo_Builder::FillInternalShapes()
   aIt.Initialize(aArguments);
   for (; aIt.More(); aIt.Next()) {
     const TopoDS_Shape& aS=aIt.Value();
-    BOPAlgo_Tools::TreatCompound(aS, aMFence, aLSC);
+    BOPTools_AlgoTools::TreatCompound(aS, aLSC, &aMFence);
   }
   aIt.Initialize(aLSC);
   for (; aIt.More(); aIt.Next()) {
index 8b7a54b..83e87b2 100644 (file)
@@ -141,44 +141,50 @@ void BOPAlgo_CellsBuilder::IndexParts()
   TopTools_ListIteratorOfListOfShape aIt(myArguments);
   for (; aIt.More(); aIt.Next()) {
     const TopoDS_Shape& aS = aIt.Value();
-    //
-    Standard_Integer iDim = BOPTools_AlgoTools::Dimension(aS);
-    aMDims.Add(iDim);
-    TopAbs_ShapeEnum aType = TypeToExplore(iDim);
-    //
-    TopExp_Explorer aExp(aS, aType);
-    for (; aExp.More(); aExp.Next()) {
-      const TopoDS_Shape& aST = aExp.Current();
-      const TopTools_ListOfShape* pLSIm = myImages.Seek(aST);
-      if (!pLSIm) {
-        TopTools_ListOfShape* pLS = myIndex.ChangeSeek(aST);
-        if (!pLS) {
-          pLS = &myIndex(myIndex.Add(aST, TopTools_ListOfShape()));
-        }
-        pLS->Append(aS);
-        //
-        if (aMFence.Add(aST)) {
-          aBB.Add(anAllParts, aST);
-        }
-        //
-        continue;
-      }
-      //
-      TopTools_ListIteratorOfListOfShape aItIm(*pLSIm);
-      for (; aItIm.More(); aItIm.Next()) {
-        const TopoDS_Shape& aSTIm = aItIm.Value();
-        //
-        TopTools_ListOfShape* pLS = myIndex.ChangeSeek(aSTIm);
-        if (!pLS) {
-          pLS = &myIndex(myIndex.Add(aSTIm, TopTools_ListOfShape()));
+
+    TopTools_ListOfShape aLSubS;
+    BOPTools_AlgoTools::TreatCompound (aS, aLSubS);
+    for (TopTools_ListOfShape::Iterator itSub (aLSubS); itSub.More(); itSub.Next())
+    {
+      const TopoDS_Shape& aSS = itSub.Value();
+      Standard_Integer iDim = BOPTools_AlgoTools::Dimension (aSS);
+      aMDims.Add(iDim);
+      TopAbs_ShapeEnum aType = TypeToExplore (iDim);
+      TopExp_Explorer aExp (aSS, aType);
+      for (; aExp.More(); aExp.Next())
+      {
+        const TopoDS_Shape& aST = aExp.Current();
+        const TopTools_ListOfShape* pLSIm = myImages.Seek(aST);
+        if (!pLSIm) {
+          TopTools_ListOfShape* pLS = myIndex.ChangeSeek(aST);
+          if (!pLS) {
+            pLS = &myIndex(myIndex.Add(aST, TopTools_ListOfShape()));
+          }
+          pLS->Append(aS);
+          //
+          if (aMFence.Add(aST)) {
+            aBB.Add(anAllParts, aST);
+          }
+          //
+          continue;
         }
-        pLS->Append(aS);
         //
-        if (aMFence.Add(aSTIm)) {
-          aBB.Add(anAllParts, aSTIm);
-        }
-      } // for (; aItIm.More(); aItIm.Next()) {
-    } // for (; aExp.More(); aExp.Next()) {
+        TopTools_ListIteratorOfListOfShape aItIm(*pLSIm);
+        for (; aItIm.More(); aItIm.Next()) {
+          const TopoDS_Shape& aSTIm = aItIm.Value();
+          //
+          TopTools_ListOfShape* pLS = myIndex.ChangeSeek(aSTIm);
+          if (!pLS) {
+            pLS = &myIndex(myIndex.Add(aSTIm, TopTools_ListOfShape()));
+          }
+          pLS->Append(aS);
+          //
+          if (aMFence.Add(aSTIm)) {
+            aBB.Add(anAllParts, aSTIm);
+          }
+        } // for (; aItIm.More(); aItIm.Next()) {
+      } // for (; aExp.More(); aExp.Next()) {
+    } // for (; itSub.More(); itSub.Next())
   } // for (; aIt.More(); aIt.Next()) {
   //
   myAllParts = anAllParts;
index cd8ae8e..7709b8c 100644 (file)
@@ -75,7 +75,7 @@ void BOPAlgo_MakeConnected::CheckData()
 
   TopTools_ListIteratorOfListOfShape itLA(myArguments);
   for (; itLA.More(); itLA.Next())
-    BOPAlgo_Tools::TreatCompound(itLA.Value(), aMFence, aLA);
+    BOPTools_AlgoTools::TreatCompound(itLA.Value(), aLA, &aMFence);
 
   if (aLA.IsEmpty())
   {
@@ -197,7 +197,7 @@ void BOPAlgo_MakeConnected::AssociateMaterials()
   // Extract all non-compound shapes from the result
   TopTools_ListOfShape aLShapes;
   TopTools_MapOfShape aMFence;
-  BOPAlgo_Tools::TreatCompound(myShape, aMFence, aLShapes);
+  BOPTools_AlgoTools::TreatCompound(myShape, aLShapes, &aMFence);
 
   if (aLShapes.IsEmpty())
     return;
index 0e7b0b2..c8e1810 100644 (file)
@@ -342,7 +342,7 @@ void BOPAlgo_MakerVolume::FillInternalShapes(const TopTools_ListOfShape& theLSR)
 
   TopTools_ListOfShape::Iterator itLA(myDS->Arguments());
   for (; itLA.More(); itLA.Next())
-    BOPAlgo_Tools::TreatCompound(itLA.Value(), aMFence, aLSC);
+    BOPTools_AlgoTools::TreatCompound(itLA.Value(), aLSC, &aMFence);
 
   // Get only edges and vertices from arguments
   TopTools_ListOfShape aLVE;
index 066d2b0..3ae8e5b 100644 (file)
@@ -181,7 +181,7 @@ void BOPAlgo_RemoveFeatures::CheckData()
     TopTools_ListOfShape aShapes;
     TopTools_MapOfShape aMFence;
     // Extract all shapes from the compound
-    BOPAlgo_Tools::TreatCompound(myInputShape, aMFence, aShapes);
+    BOPTools_AlgoTools::TreatCompound(myInputShape, aShapes, &aMFence);
     if (aShapes.IsEmpty())
     {
       // Add error of empty input shape
index 714708a..82ac4b0 100644 (file)
@@ -1104,29 +1104,6 @@ void BOPAlgo_Tools::IntersectVertices(const TopTools_IndexedDataMapOfShapeReal&
 }
 
 //=======================================================================
-//function : TreatCompound
-//purpose  : 
-//=======================================================================
-void BOPAlgo_Tools::TreatCompound(const TopoDS_Shape& theS,
-                                  TopTools_MapOfShape& aMFence,
-                                  TopTools_ListOfShape& theLS)
-{
-  TopAbs_ShapeEnum aType = theS.ShapeType();
-  if (aType != TopAbs_COMPOUND)
-  {
-    if (aMFence.Add(theS))
-      theLS.Append(theS);
-    return;
-  }
-  TopoDS_Iterator aIt(theS);
-  for (; aIt.More(); aIt.Next())
-  {
-    const TopoDS_Shape& aS = aIt.Value();
-    TreatCompound(aS, aMFence, theLS);
-  }
-}
-
-//=======================================================================
 // Classification of the faces relatively solids
 //=======================================================================
 
index 1185394..e3d9a87 100644 (file)
@@ -165,13 +165,6 @@ public:
                                                 const Standard_Real theFuzzyValue,
                                                 TopTools_ListOfListOfShape& theChains);
 
-  //! Collect in the output list recursively all non-compound subshapes of the first level
-  //! of the given shape theS. If a shape presents in the map theMFence it is skipped.
-  //! All shapes put in the output are also added into theMFence.
-  Standard_EXPORT static void TreatCompound(const TopoDS_Shape& theS,
-                                            TopTools_MapOfShape& theMFence,
-                                            TopTools_ListOfShape& theLS);
-
   //! Classifies the faces <theFaces> relatively solids <theSolids>.
   //! The IN faces for solids are stored into output data map <theInParts>.
   //!
index 18576d0..77ad5e9 100644 (file)
@@ -32,6 +32,7 @@
 #include <TopAbs_ShapeEnum.hxx>
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
 #include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
 #include <TopTools_ListOfListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <Precision.hxx>
@@ -552,9 +553,22 @@ public: //! @name Other methods
                                                           const TopoDS_Edge& aE,
                                                           const Handle(IntTools_Context)& aContext);
 
-  //! Retutns dimension of the shape <theS>.
+  //! Returns the min and max dimensions of the shape <theS>.
+  Standard_EXPORT static void Dimensions (const TopoDS_Shape& theS,
+                                          Standard_Integer& theDMin,
+                                          Standard_Integer& theDMax);
+
+  //! Returns dimension of the shape <theS>.
+  //! If the shape contains elements of different dimension, -1 is returned.
   Standard_EXPORT static Standard_Integer Dimension(const TopoDS_Shape& theS);
 
+  //! Collects in the output list recursively all non-compound sub-shapes of the first level
+  //! of the given shape theS. The optional map theMap is used to avoid the duplicates in the
+  //! output list, so it will also contain all non-compound sub-shapes.
+  Standard_EXPORT static void TreatCompound (const TopoDS_Shape& theS,
+                                             TopTools_ListOfShape& theList,
+                                             TopTools_MapOfShape* theMap = NULL);
+
   //! Returns true if the  shell <theShell> is open
   Standard_EXPORT static Standard_Boolean IsOpenShell(const TopoDS_Shell& theShell);
 
index 9ed2175..4fd77e5 100644 (file)
 #include <TopoDS_Solid.hxx>
 #include <TopoDS_Vertex.hxx>
 
-static
-  void TreatCompound(const TopoDS_Shape& theC1, 
-                     TopTools_ListOfShape& theLSX);
-
 //=======================================================================
 // function: UpdateVertex
 // purpose: 
@@ -437,103 +433,101 @@ void BOPTools_AlgoTools::CorrectRange(const TopoDS_Edge& aE,
     }
   }
 }
+
+namespace
+{
+
 //=======================================================================
-//function : Dimension
+//function : dimension
+//purpose  : returns dimension of elementary shape
+//=======================================================================
+static Standard_Integer dimension (const TopoDS_Shape& theS)
+{
+  switch (theS.ShapeType())
+  {
+    case TopAbs_VERTEX:
+      return 0;
+    case TopAbs_EDGE:
+    case TopAbs_WIRE:
+      return 1;
+    case TopAbs_FACE:
+    case TopAbs_SHELL:
+      return 2;
+    case TopAbs_SOLID:
+    case TopAbs_COMPSOLID:
+      return 3;
+    default:
+      return -1;
+  }
+}
+
+}
+
+//=======================================================================
+//function : Dimensions
 //purpose  : 
 //=======================================================================
-Standard_Integer BOPTools_AlgoTools::Dimension(const TopoDS_Shape& theS)
+void BOPTools_AlgoTools::Dimensions (const TopoDS_Shape& theS,
+                                     Standard_Integer& theDMin,
+                                     Standard_Integer& theDMax)
 {
-  Standard_Integer i, iRet, iRx0 = 0, iRx = 0;
-  TopAbs_ShapeEnum aTS;
+  theDMin = theDMax = dimension (theS);
+  if (theDMax >= 0)
+    return;
+
   TopTools_ListOfShape aLS;
-  TopTools_ListIteratorOfListOfShape aIt;
-  //
-  aTS=theS.ShapeType();
-  if (aTS!=TopAbs_COMPOUND) {
-    switch (aTS) {
-      case TopAbs_EDGE:
-      case TopAbs_WIRE:
-        iRet=1;
-        break;
-      case TopAbs_FACE:
-      case TopAbs_SHELL:
-        iRet=2;
-        break;
-      case TopAbs_SOLID:
-      case TopAbs_COMPSOLID:
-        iRet=3;
-        break;
-      default:
-        iRet=0;
-    }
-    return iRet;
-  }
-  //
-  iRet=-1;
-  TreatCompound(theS, aLS);
-  if(aLS.IsEmpty()) {
-    iRet = -2; //empty compound
-    return iRet;
+  TopTools_MapOfShape aMFence;
+  TreatCompound (theS, aLS, &aMFence);
+  if (aLS.IsEmpty())
+  {
+    // empty shape
+    theDMin = theDMax = -1;
+    return;
   }
-  aIt.Initialize(aLS);
-  for (i=0; aIt.More(); aIt.Next()) {
-    const TopoDS_Shape& aSx=aIt.Value(); 
-    iRx=Dimension(aSx);
-    if (!i) {
-      iRx0=iRx;
-      i=1;
-      continue;
-    }
-    if (iRx!=iRx0) {
-      return iRet;// -1
-    }
+
+  theDMin = 3;
+  theDMax = 0;
+  for (TopTools_ListOfShape::Iterator it (aLS); it.More(); it.Next())
+  {
+    Standard_Integer aDim = dimension (it.Value());
+    if (aDim < theDMin)
+      theDMin = aDim;
+    if (aDim > theDMax)
+      theDMax = aDim;
   }
-  return iRx;
+}
+
+//=======================================================================
+//function : Dimension
+//purpose  : 
+//=======================================================================
+Standard_Integer BOPTools_AlgoTools::Dimension(const TopoDS_Shape& theS)
+{
+  Standard_Integer aDMin, aDMax;
+  Dimensions (theS, aDMin, aDMax);
+  return (aDMin == aDMax) ? aDMin : -1;
 }
 
 //=======================================================================
 //function : TreatCompound
 //purpose  : 
 //=======================================================================
-void TreatCompound(const TopoDS_Shape& theC1, 
-                   TopTools_ListOfShape& theLSX)
+void BOPTools_AlgoTools::TreatCompound (const TopoDS_Shape& theS,
+                                        TopTools_ListOfShape& theLS,
+                                        TopTools_MapOfShape* theMFence)
 {
-  Standard_Integer aNbC1;
-  TopAbs_ShapeEnum aType;
-  TopTools_ListOfShape aLC, aLC1;
-  TopTools_ListIteratorOfListOfShape aIt, aIt1;
-  TopoDS_Iterator aItC;
-  //
-  aLC.Append (theC1);
-  for(;;) {
-    aLC1.Clear();
-    aIt.Initialize(aLC);
-    for (; aIt.More(); aIt.Next()) {
-      const TopoDS_Shape& aC=aIt.Value(); //C is compound
-      //
-      aItC.Initialize(aC);
-      for (; aItC.More(); aItC.Next()) {
-        const TopoDS_Shape& aS=aItC.Value();
-        aType=aS.ShapeType();
-        if (aType==TopAbs_COMPOUND) {
-          aLC1.Append(aS);
-        }
-        else {
-          theLSX.Append(aS);
-        }
-      }
-    }
-    //
-    aNbC1=aLC1.Extent();
-    if (!aNbC1) {
-      break;
-    }
-    //
-    aLC.Clear();
-    aIt.Initialize(aLC1);
-    for (; aIt.More(); aIt.Next()) {
-      const TopoDS_Shape& aSC=aIt.Value();
-      aLC.Append(aSC);
+  TopAbs_ShapeEnum aType = theS.ShapeType();
+  if (aType != TopAbs_COMPOUND)
+  {
+    if (!theMFence || theMFence->Add (theS))
+    {
+      theLS.Append (theS);
     }
-  }// while(1)
+    return;
+  }
+
+  for (TopoDS_Iterator it (theS); it.More(); it.Next())
+  {
+    TreatCompound (it.Value(), theLS, theMFence);
+  }
 }
diff --git a/tests/bugs/modalg_7/bug30386_1 b/tests/bugs/modalg_7/bug30386_1
new file mode 100644 (file)
index 0000000..fe67c50
--- /dev/null
@@ -0,0 +1,30 @@
+puts "======================================================="
+puts "0030386: Modeling Algorithms - Unable to perform Cut operation"
+puts "======================================================="
+puts ""
+
+restore [locate_data_file bug30386_shapes.brep] s
+explode s
+bclearobjects
+bcleartools
+baddobjects s_1
+baddtools s_2
+bfillds
+
+bbop r0 0
+bbop r2 2
+
+foreach r {r0 r2} {
+  checkshape $r
+  if {![regexp "OK" [bopcheck $r]]} {
+    puts "Error: the $r is a self-interfering shape"
+  }
+}
+
+checknbshapes r0 -wire 6 -face 6 -shell 0 -solid 0 -t
+checkprops r0 -s 1.0852
+
+checknbshapes r2 -wire 546 -face 533 -shell 12 -solid 12 -t 
+checkprops r2 -s 223.275 -v 123.21
+
+checkview -display r2 -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_7/bug30386_2 b/tests/bugs/modalg_7/bug30386_2
new file mode 100644 (file)
index 0000000..05f1034
--- /dev/null
@@ -0,0 +1,18 @@
+puts "REQUIRED All: Error: Boolean operation of the given type is not allowed on the given inputs"
+
+puts "======================================================="
+puts "0030386: Modeling Algorithms - Unable to perform Cut operation"
+puts "======================================================="
+puts ""
+
+restore [locate_data_file bug30386_shapes.brep] s
+explode s
+# just to avoid intersection
+ttranslate s_2 10 0 0
+bclearobjects
+bcleartools
+baddobjects s_1
+baddtools s_2
+bfillds
+# try to perform fuse operation - error is expected
+bbop r1 1
diff --git a/tests/bugs/modalg_7/bug30386_3 b/tests/bugs/modalg_7/bug30386_3
new file mode 100644 (file)
index 0000000..2e0219f
--- /dev/null
@@ -0,0 +1,18 @@
+puts "REQUIRED All: Error: Boolean operation of the given type is not allowed on the given inputs"
+
+puts "======================================================="
+puts "0030386: Modeling Algorithms - Unable to perform Cut operation"
+puts "======================================================="
+puts ""
+
+restore [locate_data_file bug30386_shapes.brep] s
+explode s
+# just to avoid intersection
+ttranslate s_2 10 0 0
+bclearobjects
+bcleartools
+baddobjects s_1
+baddtools s_2
+bfillds
+# try to perform CUT21 operation - error is expected
+bbop r3 3
diff --git a/tests/bugs/modalg_7/bug30386_4 b/tests/bugs/modalg_7/bug30386_4
new file mode 100644 (file)
index 0000000..3592a34
--- /dev/null
@@ -0,0 +1,50 @@
+puts "======================================================="
+puts "0030386: Modeling Algorithms - Unable to perform Cut operation"
+puts "======================================================="
+puts ""
+
+# prepare the first argument - compound of mutlti-dimensional shapes
+vertex v 0 0 2
+line l 5 5 0 0 0 1
+mkedge e l -10 10
+plane p 0 0 1 0 0 1
+mkface f p -15 15 -15 15
+box b 8 8 8 5 5 5
+bclearobjects
+bcleartools
+baddobjects v e f b
+bfillds
+bbuild s1
+
+# second argument - solid
+box s2 10 10 10
+
+bclearobjects
+bcleartools
+baddobjects s1
+baddtools s2
+bfillds
+
+# it is allowed to perform only CUT and COMMON operations
+bbop r0 0
+bbop r2 2
+
+
+foreach r {r0 r2} {
+  checkshape $r
+  if {![regexp "OK" [bopcheck $r]]} {
+    puts "Error: the $r is a self-interfering shape"
+  }
+}
+
+checknbshapes r0 -vertex 16 -edge 18 -wire 7 -face 7 -shell 1 -solid 1 -t
+checkprops r0 -s 124
+explode r0 so
+checkprops r0_1 -v 8
+
+checknbshapes r2 -vertex 24 -edge 30 -wire 11 -face 10 -shell 1 -solid 1 -t 
+checkprops r2 -s 950
+explode r2 so
+checkprops r2_1 -v 117
+
+checkview -display r2 -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_7/bug30386_5 b/tests/bugs/modalg_7/bug30386_5
new file mode 100644 (file)
index 0000000..6f57cda
--- /dev/null
@@ -0,0 +1,46 @@
+puts "REQUIRED All: Error: Boolean operation of the given type is not allowed on the given inputs"
+
+puts "======================================================="
+puts "0030386: Modeling Algorithms - Unable to perform Cut operation"
+puts "======================================================="
+puts ""
+
+# prepare the first argument - compound of mutlti-dimensional shapes
+vertex v 0 0 2
+line l 5 5 0 0 0 1
+mkedge e l -10 10
+plane p 0 0 1 0 0 1
+mkface f p -15 15 -15 15
+box b 8 8 8 5 5 5
+bclearobjects
+bcleartools
+baddobjects v e f b
+bfillds
+bbuild s1
+
+# second argument - compound of solid and face
+box b2 10 10 10
+bclearobjects
+bcleartools
+baddobjects f
+baddtools b2
+bfillds
+bbuild s2
+
+# only common operation should be allowed
+
+bclearobjects
+bcleartools
+baddobjects s1
+baddtools s2
+bfillds
+
+if {[regexp "Error: Boolean operation of the given type is not allowed on the given inputs" [bbop r 0]]} {
+  puts "Error: COMMON Operation must be allowed on any types of arguments"
+}
+
+foreach i {1 2 3} {
+  if {![regexp "Error: Boolean operation of the given type is not allowed on the given inputs" [bbop r $i]]} {
+    puts "Error: Operation must not be allowed"
+  }
+}