0027274: Regression vs 6.9.1: Wrong result of General Fuse operation on two cylinders
authoremv <emv@opencascade.com>
Thu, 17 Mar 2016 14:10:11 +0000 (17:10 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 24 Mar 2016 09:49:28 +0000 (12:49 +0300)
When reducing the tolerance values of the vertices put on section curves take into
account all section curves, not only those for which the tolerance have been reduced
(method void BOPAlgo_PaveFiller::CorrectToleranceOfSE()).
The new protection has been added to avoid reducing of tolerance values of vertices
to the values less than the tolerance values of edges containing these vertices.

Adjusting of test case bugs/modalg_5/bug25232_9

src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
tests/bugs/modalg_5/bug25232_9
tests/bugs/modalg_6/bug27274 [new file with mode: 0644]

index bc973bd..49e5ea2 100644 (file)
@@ -2517,57 +2517,117 @@ void BOPAlgo_PaveFiller::CorrectToleranceOfSE()
 {
   BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
   NCollection_IndexedDataMap<Standard_Integer,BOPDS_ListOfPaveBlock> aMVIPBs;
+  BOPCol_MapOfInteger aMVIToReduce;
   //
-  // iterate on all sections F-F
+  // 1. iterate on all sections F-F
   Standard_Integer aNb = aFFs.Extent(), i;
   for (i = 0; i < aNb; ++i) {
     const BOPDS_InterfFF& aFF = aFFs(i);
     Standard_Real aTolR3D = aFF.TolR3D();
     Standard_Real aTolReal = aFF.TolReal();
-    if (aTolReal < aTolR3D) {
-      // tolerance of intersection has been increased, so process this intersection
-      const BOPDS_VectorOfCurve& aVNC = aFF.Curves();
-      Standard_Integer aNbC = aVNC.Extent(), k;
-      for (k = 0; k < aNbC; ++k) {
-        const BOPDS_Curve& aNC = aVNC(k);
-        const BOPDS_ListOfPaveBlock& aLPB = aNC.PaveBlocks();
-        BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
-        for (; aItLPB.More(); aItLPB.Next()) {
-          const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
-          Standard_Integer nE;
-          if (!aPB->HasEdge(nE) || aPB->OriginalEdge() >= 0) {
-            continue;
-          }
+    Standard_Boolean bToReduce = aTolReal < aTolR3D;
+    // tolerance of intersection has been increased, so process this intersection
+    const BOPDS_VectorOfCurve& aVNC = aFF.Curves();
+    Standard_Integer aNbC = aVNC.Extent(), k;
+    for (k = 0; k < aNbC; ++k) {
+      const BOPDS_Curve& aNC = aVNC(k);
+      const BOPDS_ListOfPaveBlock& aLPB = aNC.PaveBlocks();
+      BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
+      for (; aItLPB.More(); aItLPB.Next()) {
+        const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
+        Standard_Integer nE;
+        if (!aPB->HasEdge(nE)) {
+          continue;
+        }
+        //
+        Standard_Boolean bIsReduced = Standard_False;
+        if (bToReduce && (aPB->OriginalEdge() < 0)) {
           const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
           Standard_Real aTolE = BRep_Tool::Tolerance(aE);
           if (aTolReal < aTolE) {
             // reduce edge tolerance
             reinterpret_cast<BRep_TEdge*>(aE.TShape().operator->())->Tolerance(aTolReal);
+            bIsReduced = Standard_True;
           }
-
-          // fill in the map vertex index - pave blocks
-          Handle(BOPDS_PaveBlock) aPBR = myDS->RealPaveBlock(aPB);
-          for (Standard_Integer j=0; j < 2; j++) {
-            Standard_Integer nV = (j == 0 ? aPBR->Pave1().Index() : aPBR->Pave2().Index());
-            BOPDS_ListOfPaveBlock *pPBList = aMVIPBs.ChangeSeek(nV);
-            if (!pPBList) {
-              pPBList = &aMVIPBs.ChangeFromIndex(aMVIPBs.Add(nV, BOPDS_ListOfPaveBlock()));
-            }
-            pPBList->Append(aPBR);
+        }
+        //
+        // fill in the map vertex index - pave blocks
+        for (Standard_Integer j=0; j < 2; j++) {
+          Standard_Integer nV = (j == 0 ? aPB->Pave1().Index() : aPB->Pave2().Index());
+          BOPDS_ListOfPaveBlock *pPBList = aMVIPBs.ChangeSeek(nV);
+          if (!pPBList) {
+            pPBList = &aMVIPBs.ChangeFromIndex(aMVIPBs.Add(nV, BOPDS_ListOfPaveBlock()));
+          }
+          pPBList->Append(aPB);
+          if (bIsReduced) {
+            aMVIToReduce.Add(nV);
+          }
+        }
+      }
+    }
+  }
+  //
+  if (aMVIToReduce.IsEmpty()) {
+    return;
+  }
+  //
+  // 2. try to reduce tolerances of connected vertices
+  // 2.1 find all other edges containing these connected vertices to avoid
+  //     reducing the tolerance to the value less than the tolerances of edges,
+  //     i.e. minimal tolerance for the vertex is the max tolerance of the
+  //     edges containing this vertex
+  BOPCol_DataMapOfIntegerReal aMVITol;
+  BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
+  aNb = aPBP.Extent();
+  for (i = 0; i < aNb; ++i) {
+    const BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
+    BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
+    for (; aItLPB.More(); aItLPB.Next()) {
+      const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
+      Standard_Integer nE;
+      if (!aPB->HasEdge(nE)) {
+        continue;
+      }
+      const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
+      Standard_Real aTolE = BRep_Tool::Tolerance(aE);
+      //
+      Standard_Integer nV[2];
+      aPB->Indices(nV[0], nV[1]);
+      //
+      for (Standard_Integer j = 0; j < 2; j++) {
+        if (aMVIToReduce.Contains(nV[j])) {
+          Standard_Real *aMaxTol = aMVITol.ChangeSeek(nV[j]);
+          if (!aMaxTol) {
+            aMVITol.Bind(nV[j], aTolE);
+          }
+          else if (aTolE > *aMaxTol) {
+            *aMaxTol = aTolE;
           }
         }
       }
     }
   }
-  // try to reduce tolerances of connected vertices
+  //
+  // 2.2 reduce tolerances if possible
   aNb = aMVIPBs.Extent();
   for (i = 1; i <= aNb; ++i) {
     Standard_Integer nV = aMVIPBs.FindKey(i);
+    if (!aMVIToReduce.Contains(nV)) {
+      continue;
+    }
+    //
     const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
-    gp_Pnt aP = BRep_Tool::Pnt(aV);
+    Standard_Real aTolV = BRep_Tool::Tolerance(aV);
+    Standard_Real aMaxTol = aMVITol.IsBound(nV) ? aMVITol.Find(nV) : 0.;
+    // it makes no sense to compute the real tolerance if it is
+    // impossible to reduce the tolerance at least 0.1% of the current value
+    if (aTolV - aMaxTol < 0.001 * aTolV) {
+      continue;
+    }
     //
     // compute the maximal distance from the vertex to the adjacent edges
-    Standard_Real aMaxTol = 0.;
+    gp_Pnt aP = BRep_Tool::Pnt(aV);
+    //
     const BOPDS_ListOfPaveBlock& aLPB = aMVIPBs.FindFromIndex(i);
     BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
     for (; aItLPB.More(); aItLPB.Next()) {
@@ -2583,7 +2643,7 @@ void BOPAlgo_PaveFiller::CorrectToleranceOfSE()
         aMaxTol = aDist;
       }
     }
-    Standard_Real aTolV = BRep_Tool::Tolerance(aV);
+    //
     if (aMaxTol < aTolV) {
       reinterpret_cast<BRep_TVertex*>(aV.TShape().operator->())->Tolerance(aMaxTol);
     }
index b900b2a..607bde3 100644 (file)
@@ -1,6 +1,3 @@
-puts "TODO OCC27014 ALL: Faulty shapes in variables faulty_1 to"
-puts "TODO OCC27014 ALL: Error :  is WRONG because number of .* entities in shape .* is"
-
 puts "============"
 puts "OCC25232"
 puts "============"
diff --git a/tests/bugs/modalg_6/bug27274 b/tests/bugs/modalg_6/bug27274
new file mode 100644 (file)
index 0000000..1900358
--- /dev/null
@@ -0,0 +1,36 @@
+puts "============"
+puts "OCC27274"
+puts "============"
+puts ""
+#######################################################################
+# Wrong result of General Fuse operation on two cylinders
+#######################################################################
+
+pcylinder b1 50 145
+tcopy b1 b2
+trotate b2 0 0 0 1 0 0 45
+
+bclearobjects
+bcleartools
+baddobjects b1
+baddtools b2
+bfillds
+bbuild result
+
+checkshape result
+
+set nbshapes_expected "
+ VERTEX    : 5
+ EDGE      : 11
+ WIRE      : 10
+ FACE      : 10
+ SHELL     : 3
+ SOLID     : 3
+ COMPSOLID : 0
+ COMPOUND  : 1
+ SHAPE     : 43
+"
+
+checknbshapes result -ref ${nbshapes_expected} -t
+
+checkprops result -s 154518
\ No newline at end of file