0029179: Result of Boolean common depends on an order of arguments
authornbv <nbv@opencascade.com>
Thu, 7 Dec 2017 08:28:20 +0000 (11:28 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 14 Dec 2017 14:44:27 +0000 (17:44 +0300)
Usage of Bnd_Box-filtering is eliminated while putting a (definitely) common vertex between two faces on the intersection curve.

Algorithm of putting not-common (ON/IN) vertices has not been changed.

src/BOPAlgo/BOPAlgo_PaveFiller.hxx
src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
src/BOPDS/BOPDS_DS.cxx
src/BOPDS/BOPDS_DS.hxx
src/BOPTools/BOPTools_AlgoTools.cxx
tests/bugs/modalg_6/bug26938_1
tests/bugs/modalg_6/bug26938_2
tests/bugs/modalg_6/bug26938_3
tests/bugs/modalg_6/bug26938_4
tests/bugs/modalg_7/bug29179 [new file with mode: 0644]

index 3eb8b81..6bde207 100644 (file)
@@ -254,15 +254,16 @@ protected:
   Standard_EXPORT Standard_Boolean IsExistingVertex (const gp_Pnt& theP, const Standard_Real theTol, const TColStd_MapOfInteger& theMVOn) const;
   
 
-  //! Checks and puts paves from <theMVOn> on the curve <theNC>.
-  Standard_EXPORT void PutPavesOnCurve (const TColStd_MapOfInteger& theMVOn, 
-                                BOPDS_Curve& theNC, 
-                                const Standard_Integer nF1, 
-                                const Standard_Integer nF2, 
-                                const TColStd_MapOfInteger& theMI, 
-                                const TColStd_MapOfInteger& theMVEF, 
-                                TColStd_DataMapOfIntegerReal& theMVTol,
-                                TColStd_DataMapOfIntegerListOfInteger& aDMVLV);
+  //! Checks and puts paves from <theMVOnIn> on the curve <theNC>.
+  //! At that, common (from theMVCommon) and not common vertices
+  //! are processed differently.
+  Standard_EXPORT void PutPavesOnCurve(const TColStd_MapOfInteger& theMVOnIn,
+                                       const TColStd_MapOfInteger& theMVCommon,
+                                       BOPDS_Curve& theNC,
+                                       const TColStd_MapOfInteger& theMI,
+                                       const TColStd_MapOfInteger& theMVEF,
+                                       TColStd_DataMapOfIntegerReal& theMVTol,
+                                       TColStd_DataMapOfIntegerListOfInteger& theDMVLV);
 
   Standard_EXPORT void FilterPavesOnCurves(const BOPDS_VectorOfCurve& theVNC);
 
index 654c907..ce4e2b9 100644 (file)
@@ -391,7 +391,7 @@ void BOPAlgo_PaveFiller::MakeBlocks()
     NCollection_BaseAllocator::CommonBaseAllocator();
   //
   TColStd_ListOfInteger aLSE(aAllocator), aLBV(aAllocator);
-  TColStd_MapOfInteger aMVOnIn(100, aAllocator),
+  TColStd_MapOfInteger aMVOnIn(100, aAllocator), aMVCommon(100, aAllocator),
                       aMVStick(100,aAllocator), aMVEF(100, aAllocator),
                       aMI(100, aAllocator), aMVBounds(100, aAllocator);
   BOPDS_IndexedMapOfPaveBlock aMPBOnIn(100, aAllocator);
@@ -432,13 +432,14 @@ void BOPAlgo_PaveFiller::MakeBlocks()
     BOPDS_FaceInfo& aFI2 = myDS->ChangeFaceInfo(nF2);
     //
     aMVOnIn.Clear();
+    aMVCommon.Clear();
     aMPBOnIn.Clear();
     aMPBCommon.Clear();
     aDMBV.Clear();
     aMVTol.Clear();
     aLSE.Clear();
     //
-    myDS->SubShapesOnIn(nF1, nF2, aMVOnIn, aMPBOnIn, aMPBCommon);
+    myDS->SubShapesOnIn(nF1, nF2, aMVOnIn, aMVCommon, aMPBOnIn, aMPBCommon);
     myDS->SharedEdges(nF1, nF2, aLSE, aAllocator);
     //
     Standard_Boolean bHasRealSectionEdge = Standard_False;
@@ -470,7 +471,13 @@ void BOPAlgo_PaveFiller::MakeBlocks()
       // DEBt
       aNC.InitPaveBlock1();
       //
-      PutPavesOnCurve(aMVOnIn, aNC, nF1, nF2, aMI, aMVEF, aMVTol, aDMVLV);
+      // In order to avoid problems connected with
+      // extending tolerance of vertex while putting
+      // (e.g. see "bugs modalg_6 bug26789_1" test case),
+      // all not-common vertices will be checked by
+      // BndBoxes before putting. For common-vertices,
+      // filtering by BndBoxes is not necessary.
+      PutPavesOnCurve(aMVOnIn, aMVCommon, aNC, aMI, aMVEF, aMVTol, aDMVLV);
     }
 
     // if some E-F vertex was put on a curve due to large E-F intersection range,
@@ -706,6 +713,7 @@ void BOPAlgo_PaveFiller::MakeBlocks()
   aMVStick.Clear();
   aMPBOnIn.Clear();
   aMVOnIn.Clear();
+  aMVCommon.Clear();
   aDMExEdges.Clear();
   aMI.Clear();
   aDMNewSD.Clear();
@@ -1570,57 +1578,54 @@ void BOPAlgo_PaveFiller::PutBoundPaveOnCurve(const TopoDS_Face& aF1,
 //function : PutPavesOnCurve
 //purpose  : 
 //=======================================================================
-void BOPAlgo_PaveFiller::PutPavesOnCurve
-  (const TColStd_MapOfInteger& aMVOnIn,
-   BOPDS_Curve& aNC,
-   const Standard_Integer nF1,
-   const Standard_Integer nF2,
-   const TColStd_MapOfInteger& aMI,
-   const TColStd_MapOfInteger& aMVEF,
-   TColStd_DataMapOfIntegerReal& aMVTol,
-   TColStd_DataMapOfIntegerListOfInteger& aDMVLV)
+void BOPAlgo_PaveFiller::PutPavesOnCurve(const TColStd_MapOfInteger& theMVOnIn,
+                                         const TColStd_MapOfInteger& theMVCommon,
+                                         BOPDS_Curve& theNC,
+                                         const TColStd_MapOfInteger& theMI,
+                                         const TColStd_MapOfInteger& theMVEF,
+                                         TColStd_DataMapOfIntegerReal& theMVTol,
+                                         TColStd_DataMapOfIntegerListOfInteger& theDMVLV)
 {
-  Standard_Boolean bInBothFaces;
   Standard_Integer nV;
   TColStd_MapIteratorOfMapOfInteger aIt;
   //
-  const Bnd_Box& aBoxC=aNC.Box();
-  Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
+  const Bnd_Box& aBoxC = theNC.Box();
+  const Standard_Real aTolR3D = Max(theNC.Tolerance(), theNC.TangentialTolerance());
   //
   //Put EF vertices first
-  aIt.Initialize(aMVEF);
-  for (; aIt.More(); aIt.Next()) {
-    nV=aIt.Value();
-    PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, aDMVLV, 2);
+  aIt.Initialize(theMVEF);
+  for (; aIt.More(); aIt.Next())
+  {
+    nV = aIt.Value();
+    PutPaveOnCurve(nV, aTolR3D, theNC, theMI, theMVTol, theDMVLV, 2);
   }
+
   //Put all other vertices
-  aIt.Initialize(aMVOnIn);
-  for (; aIt.More(); aIt.Next()) {
-    nV=aIt.Value();
-    if (aMVEF.Contains(nV)) {
-      continue;
-    }
-    //
-    const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
-    const Bnd_Box& aBoxV=aSIV.Box();
-    //
-    if (aBoxC.IsOut(aBoxV)){
+  aIt.Initialize(theMVOnIn);
+  for (; aIt.More(); aIt.Next())
+  {
+    nV = aIt.Value();
+    if (theMVEF.Contains(nV))
+    {
       continue;
     }
-    if (!myDS->IsNewShape(nV)) {
-      const BOPDS_FaceInfo& aFI1 = myDS->FaceInfo(nF1);
-      const BOPDS_FaceInfo& aFI2 = myDS->FaceInfo(nF2);
+
+    if (!theMVCommon.Contains(nV))
+    {
+      const BOPDS_ShapeInfo& aSIV = myDS->ShapeInfo(nV);
+      const Bnd_Box& aBoxV = aSIV.Box();
       //
-      bInBothFaces = (aFI1.VerticesOn().Contains(nV) ||
-                      aFI1.VerticesIn().Contains(nV))&&
-                     (aFI2.VerticesOn().Contains(nV) ||
-                      aFI2.VerticesIn().Contains(nV));
-      if (!bInBothFaces) {
+      if (aBoxC.IsOut(aBoxV))
+      {
+        continue;
+      }
+      if (!myDS->IsNewShape(nV))
+      {
         continue;
       }
     }
     //
-    PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, aDMVLV, 1);
+    PutPaveOnCurve(nV, aTolR3D, theNC, theMI, theMVTol, theDMVLV, 1);
   }
 }
 
index aeb49a0..d7d3aa3 100644 (file)
@@ -1453,56 +1453,71 @@ void BOPDS_DS::AloneVertices(const Standard_Integer theI,
 //function : VerticesOnIn
 //purpose  : 
 //=======================================================================
-void BOPDS_DS::SubShapesOnIn
-  (const Standard_Integer nF1,
-   const Standard_Integer nF2,
-   TColStd_MapOfInteger& theMVOnIn,
-   BOPDS_IndexedMapOfPaveBlock& thePBOnIn,
-   BOPDS_MapOfPaveBlock& theCommonPB)const
+void BOPDS_DS::SubShapesOnIn(const Standard_Integer theNF1,
+                             const Standard_Integer theNF2,
+                             TColStd_MapOfInteger& theMVOnIn,
+                             TColStd_MapOfInteger& theMVCommon,
+                             BOPDS_IndexedMapOfPaveBlock& thePBOnIn,
+                             BOPDS_MapOfPaveBlock& theCommonPB)const
 {
   Standard_Integer i, j, nV, nV1, nV2, aNbPB;
   TColStd_MapIteratorOfMapOfInteger aIt;
   BOPDS_IndexedMapOfPaveBlock pMPB[4];
   //
-  const BOPDS_FaceInfo& aFI1=FaceInfo(nF1);
-  const BOPDS_FaceInfo& aFI2=FaceInfo(nF2);
+  const BOPDS_FaceInfo& aFI1 = FaceInfo(theNF1);
+  const BOPDS_FaceInfo& aFI2 = FaceInfo(theNF2);
   //
-  pMPB[0]=aFI1.PaveBlocksOn();
-  pMPB[1]=aFI1.PaveBlocksIn();
-  pMPB[2]=aFI2.PaveBlocksOn();
-  pMPB[3]=aFI2.PaveBlocksIn();
+  pMPB[0] = aFI1.PaveBlocksOn();
+  pMPB[1] = aFI1.PaveBlocksIn();
+  pMPB[2] = aFI2.PaveBlocksOn();
+  pMPB[3] = aFI2.PaveBlocksIn();
   //
-  for (i=0; i<4; ++i) {
+  for (i = 0; i < 4; ++i)
+  {
     aNbPB = pMPB[i].Extent();
-    for (j = 1; j <= aNbPB; ++j) {
+    for (j = 1; j <= aNbPB; ++j)
+    {
       const Handle(BOPDS_PaveBlock)& aPB = pMPB[i](j);
       thePBOnIn.Add(aPB);
       aPB->Indices(nV1, nV2);
+
       theMVOnIn.Add(nV1);
       theMVOnIn.Add(nV2);
-      if (i < 2) {
+
+      if (i < 2)
+      {
         if (pMPB[2].Contains(aPB) || pMPB[3].Contains(aPB))
+        {
           theCommonPB.Add(aPB);
+          theMVCommon.Add(nV1);
+          theMVCommon.Add(nV2);
+        }
       }
     }
   }
   //
-  const TColStd_MapOfInteger& aMVOn1=aFI1.VerticesOn();
-  const TColStd_MapOfInteger& aMVIn1=aFI1.VerticesIn();
-  const TColStd_MapOfInteger& aMVOn2=aFI2.VerticesOn();
-  const TColStd_MapOfInteger& aMVIn2=aFI2.VerticesIn();
+  const TColStd_MapOfInteger& aMVOn1 = aFI1.VerticesOn();
+  const TColStd_MapOfInteger& aMVIn1 = aFI1.VerticesIn();
+  const TColStd_MapOfInteger& aMVOn2 = aFI2.VerticesOn();
+  const TColStd_MapOfInteger& aMVIn2 = aFI2.VerticesIn();
   //
-  for (i=0; i<2; ++i) {
-    const TColStd_MapOfInteger& aMV1=(!i) ? aMVOn1 : aMVIn1;
+  for (i = 0; i < 2; ++i)
+  {
+    const TColStd_MapOfInteger& aMV1 = (!i) ? aMVOn1 : aMVIn1;
     aIt.Initialize(aMV1);
-    for (; aIt.More(); aIt.Next()) {
-      nV=aIt.Value();
-      if (aMVOn2.Contains(nV) || aMVIn2.Contains(nV)) {
+    for (; aIt.More(); aIt.Next())
+    {
+      nV = aIt.Value();
+      if (aMVOn2.Contains(nV) || aMVIn2.Contains(nV))
+      {
         theMVOnIn.Add(nV);
+
+        // Vertex taken from the 1st face is in the 2nd one.
+        theMVCommon.Add(nV);
       }
     }
   }
-} 
+}
 //=======================================================================
 //function : SharedEdges
 //purpose  : 
index 3dbea3e..2201d5f 100644 (file)
@@ -304,15 +304,17 @@ Standard_EXPORT virtual ~BOPDS_DS();
   Standard_EXPORT void RefineFaceInfoOn();
   
 
-  //! Returns information about ON/IN subshapes of the given faces.
+  //! Returns information about ON/IN sub-shapes of the given faces.
   //! @param theMVOnIn  the indices of ON/IN vertices from both faces
+  //! @param theMVCommon the indices of common vertices for both faces
   //! @param thePBOnIn  all On/In pave blocks from both faces
   //! @param theCommonPB  the common pave blocks (that are shared by both faces).
-  Standard_EXPORT void SubShapesOnIn (const Standard_Integer theF1,
-                                      const Standard_Integer theF2,
-                                      TColStd_MapOfInteger& theMVOnIn,
-                                      BOPDS_IndexedMapOfPaveBlock& thePBOnIn,
-                                      BOPDS_MapOfPaveBlock& theCommonPB) const;
+  Standard_EXPORT void SubShapesOnIn(const Standard_Integer theNF1,
+                                     const Standard_Integer theNF2,
+                                     TColStd_MapOfInteger& theMVOnIn,
+                                     TColStd_MapOfInteger& theMVCommon,
+                                     BOPDS_IndexedMapOfPaveBlock& thePBOnIn,
+                                     BOPDS_MapOfPaveBlock& theCommonPB) const;
   
 
   //! Returns the indices of edges that are  shared
index d6b7432..b971dec 100644 (file)
@@ -645,10 +645,14 @@ TopAbs_State BOPTools_AlgoTools::ComputeState
   }
   // !!<- process edges that are all on theRef
   if (!aE1.IsNull()) {
-    BOPTools_AlgoTools3D::PointNearEdge(aE1, theF, 
-                                        aP2D, aP3D, theContext);
-    aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, 
-                                            theContext);
+    const Standard_Integer anErrID = BOPTools_AlgoTools3D::PointNearEdge(aE1, theF,
+                                                                         aP2D, aP3D,
+                                                                         theContext);
+    if(anErrID == 0)
+    {
+      aState = BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
+                                                theContext);
+    }
   }
   //
   return aState;
index b4c2323..e6f8ea3 100644 (file)
@@ -1,7 +1,3 @@
-puts "TODO OCC28802 Linux: Faulty shapes in variables faulty_1 to"
-puts "TODO OCC28802 Linux: Error : The area of result shape is"
-puts "TODO OCC28802 Linux: Error : The result of General Fuse operation is self-interfered shape"
-
 puts "=========="
 puts "OCC26938  "
 puts "=========="
@@ -27,4 +23,6 @@ if { [regexp "This shape seems to be OK" ${info}] != 1 } {
     puts "Error : The result of General Fuse operation is self-interfered shape"
 }
 
+checknbshapes result -solid 1 -shell 1 -t -m "Result"
+
 checkview -display result -2d -path ${imagedir}/${test_image}.png
index fb52837..bf13883 100644 (file)
@@ -1,6 +1,3 @@
-puts "TODO OCC28802 Linux: Error : The command is not valid. The area is 0"
-puts "TODO OCC28802 Linux: Error : The area of result shape is 0"
-
 puts "=========="
 puts "OCC26938  "
 puts "=========="
@@ -26,4 +23,6 @@ if { [regexp "This shape seems to be OK" ${info}] != 1 } {
     puts "Error : The result of General Fuse operation is self-interfered shape"
 }
 
+checknbshapes result -solid 1 -shell 1 -t -m "Result"
+
 checkview -display result -2d -path ${imagedir}/${test_image}.png
index da850d7..42ced6a 100644 (file)
@@ -1,6 +1,6 @@
-puts "TODO OCC28802 Linux: Error : The area of result shape is"
-puts "TODO OCC24694 Windows: Error : The result of cut operation is self-interfered shape"
-
+puts "TODO OCC24694 All: Error : The result of cut operation is self-interfered shape"
+puts "TODO OCC24694 ALL: Result is WRONG because number of SHELL entities in shape \"result\" is 2"
+puts "TODO OCC24694 ALL: Result is WRONG because number of SOLID entities in shape \"result\" is 2"
 puts "=========="
 puts "OCC26938  "
 puts "=========="
@@ -26,4 +26,6 @@ if { [regexp "This shape seems to be OK" ${info}] != 1 } {
     puts "Error : The result of cut operation is self-interfered shape"
 }
 
+checknbshapes result -solid 3 -shell 3 -t -m "Result"
+
 checkview -display result -2d -path ${imagedir}/${test_image}.png
index 83ce69c..2ac0009 100644 (file)
@@ -1,4 +1,7 @@
 puts "TODO OCC24694 ALL: Error : The result of cut operation is self-interfered shape"
+puts "TODO OCC24694 ALL: Result is WRONG because number of SHELL entities in shape \"result\" is 2"
+puts "TODO OCC24694 ALL: Result is WRONG because number of SOLID entities in shape \"result\" is 2"
+
 puts "=========="
 puts "OCC26938  "
 puts "=========="
@@ -24,4 +27,6 @@ if { [regexp "This shape seems to be OK" ${info}] != 1 } {
     puts "Error : The result of cut operation is self-interfered shape"
 }
 
+checknbshapes result -solid 3 -shell 3 -t -m "Result"
+
 checkview -display result -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_7/bug29179 b/tests/bugs/modalg_7/bug29179
new file mode 100644 (file)
index 0000000..251a4f4
--- /dev/null
@@ -0,0 +1,50 @@
+puts "========"
+puts "OCC29179"
+puts "========"
+puts ""
+#################################################
+# Result of Boolean common depends on an order of arguments
+#################################################
+
+restore [locate_data_file bug26938.brep] a
+explode a
+
+bcommon res1 a_1 a_2
+
+restore [locate_data_file bug26938.brep] a
+explode a
+
+bcommon res2 a_2 a_1
+
+checkview -display res1 -2d -path ${imagedir}/${test_image}_1.png
+checkview -display res2 -2d -path ${imagedir}/${test_image}_2.png
+
+checkshape res1
+checkshape res2
+
+if {[regexp "Faulties" [bopargcheck res1]]} {
+  puts "Error: bopargcheck has found some faulties in res1"
+}
+
+if {[regexp "Faulties" [bopargcheck res2]]} {
+  puts "Error: bopargcheck has found some faulties in res2"
+}
+
+checkprops res1 -v 4.93528e+008
+checkprops res2 -v 4.93528e+008
+
+set nbshapes_expected "
+Number of shapes in .*
+ VERTEX : 5
+ EDGE : 7
+ WIRE : 4
+ FACE : 4
+ SHELL : 1
+ SOLID : 1
+ COMPSOLID : 0
+ COMPOUND : 1
+ SHAPE : 23
+"
+
+checknbshapes res1 -ref ${nbshapes_expected} -t -m "1st COMMON"
+checknbshapes res2 -ref ${nbshapes_expected} -t -m "2nd COMMON"