0032934: Modelling Algorithms - BRepExtrema_DistShapeShape returns two solutions...
authorddzama <ddzama@opencascade.com>
Thu, 24 Nov 2022 13:24:14 +0000 (16:24 +0300)
committersmoskvin <smoskvin@opencascade.com>
Sun, 4 Dec 2022 10:39:35 +0000 (13:39 +0300)
distmini of two edges returns two solution points instead one.
Second unneeded solution point is the same as first.

The problem was in fact that second edge has continuity C0.
In this case additional extremas analysis performed in special procedure

PERFORM_C0

And second point found in this procedure.
Folowing code of

BRepExtrema_DistanceSS::Perform (variant for Edge/Edge)

we should this additional solution extremas set
to be object of test TRI_SOLUTION before pushing
into main list of solution.
This solves the problem.
Corresponding test and compound with edges has been created.

Additionally, in the function

PERFORM_C0

an obvious error has fixed.

src/BRepExtrema/BRepExtrema_DistanceSS.cxx
tests/bugs/modalg_7/bug32934 [new file with mode: 0644]

index e81108b79435cb4a479a28aa32528948fa4acfec..c287d05ba336dee9258904fb175c97a1fabbef16 100644 (file)
@@ -468,7 +468,14 @@ static void PERFORM_C0(const TopoDS_Edge& S1, const TopoDS_Edge& S2,
               if (fabs(Dstmin - sqrt(Ext.SquareDistance(ii))) < Eps)
               {
                 Pt = Ext.Point(ii);
-                if (TRI_SOLUTION(SeqSol2, Pt))
+                // Pt - point on the curve pCurvOther/Eother, but
+                // if iE == 0 -> Eother correspond to edge S2
+                // and to edge S1 in the opposite case.
+                // Therefore we should search Pt through previous solution points on Other curve (edge):
+                // if iE == 0 - on edge S2, namely through SeqSol2,
+                // else       - on edge S1, namely through SeqSol1.
+                const bool triSolutionResult = (iE == 0) ? TRI_SOLUTION(SeqSol2, Pt) : TRI_SOLUTION(SeqSol1, Pt);
+                if (triSolutionResult)
                 {
                   // Check if the parameter does not correspond to a vertex
                   const Standard_Real t = Ext.Parameter(ii);
@@ -869,9 +876,19 @@ void BRepExtrema_DistanceSS::Perform (const TopoDS_Edge& theS1,
 
   if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
   {
-    theSeqSolShape1.Append(seqSol1);
-    theSeqSolShape2.Append(seqSol2);
-    myModif = Standard_True;
+    BRepExtrema_SeqOfSolution::iterator anIt1 = seqSol1.begin();
+    BRepExtrema_SeqOfSolution::iterator anIt2 = seqSol2.begin();
+    for (; anIt1 != seqSol1.end() && anIt2 != seqSol2.end(); anIt1++, anIt2++)
+    {
+      gp_Pnt Pt1 = anIt1->Point();
+      gp_Pnt Pt2 = anIt2->Point();
+      if (TRI_SOLUTION(theSeqSolShape1, Pt1) || TRI_SOLUTION(theSeqSolShape2, Pt2))
+      {
+        theSeqSolShape1.Append(*anIt1);
+        theSeqSolShape2.Append(*anIt2);
+        myModif = Standard_True;
+      }
+    }
   }
 }
 
diff --git a/tests/bugs/modalg_7/bug32934 b/tests/bugs/modalg_7/bug32934
new file mode 100644 (file)
index 0000000..4613174
--- /dev/null
@@ -0,0 +1,25 @@
+puts "========"
+puts "OCC32934"
+puts "========"
+puts ""
+###############################################################################################
+# BRepExtrema_DistShapeShape BRepExtrema_DistShapeShape returns two solutions instead of one.
+###############################################################################################
+
+pload ALL
+restore [locate_data_file bug32934.brep] edges
+explode edges E
+
+distmini di edges_1 edges_2
+if { ([isdraw di2]) } {
+  puts "Error : result of distmini is wrong"
+} else {
+  checknbshapes di -vertex 1 -edge 0
+}
+
+distmini dii edges_2 edges_1
+if { ([isdraw dii2]) } {
+  puts "Error : result of distmini is wrong"
+} else {
+  checknbshapes dii -vertex 1 -edge 0
+}