0023863: Wrong distance value between circle and cylinder
authorazv <azv@opencascade.com>
Thu, 26 Sep 2013 16:13:17 +0000 (20:13 +0400)
committerbugmaster <bugmaster@opencascade.com>
Thu, 26 Sep 2013 16:14:12 +0000 (20:14 +0400)
The verification of intersection of a circle and a cylinder was added to the calculation of extrema
Test cases for issue CR23863

src/Extrema/Extrema_ExtElCS.cxx
tests/bugs/moddata_3/bug23863 [new file with mode: 0755]

index e3acae6..de86222 100755 (executable)
@@ -314,48 +314,72 @@ void Extrema_ExtElCS::Perform(const gp_Circ& C,
       Standard_Real    aTolConf = Precision::Confusion();
       Standard_Real    aCylRad  = S.Radius();
 
+      // Check whether two objects have intersection points
+      IntAna_Quadric aCylQuad(S);
+      IntAna_IntConicQuad aCircCylInter(C, aCylQuad);
+      Standard_Integer aNbInter = aCircCylInter.NbPoints();
+      if (!aCircCylInter.IsDone())
+        aNbInter = 0;
+
       // Compute the extremas.
-      myNbExt  =     2*aNbExt;
+      myNbExt  =     2*aNbExt + aNbInter;
       mySqDist  = new TColStd_HArray1OfReal(1, myNbExt);
       myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
       myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
 
       for (i = 1; i <= aNbExt; i++) {
-       Extrema_POnCurv aPOnAxis;
-       Extrema_POnCurv aPOnCirc;
-       Standard_Real   aSqDist = anExtC.SquareDistance(i);
-       Standard_Real   aDist = sqrt (aSqDist);
+        Extrema_POnCurv aPOnAxis;
+        Extrema_POnCurv aPOnCirc;
+        Standard_Real   aSqDist = anExtC.SquareDistance(i);
+        Standard_Real   aDist = sqrt (aSqDist);
+
+        anExtC.Points(i, aPOnAxis, aPOnCirc);
+
+        if (aSqDist <= (aTolConf * aTolConf)) {
+          myNbExt -= 2;
+          continue;
+        }
+
+        gp_Dir aDir(aPOnAxis.Value().XYZ().Subtracted(aPOnCirc.Value().XYZ()));
+        Standard_Real aShift[2] = { aDist + aCylRad, aDist - aCylRad };
+        Standard_Integer j;
 
-       anExtC.Points(i, aPOnAxis, aPOnCirc);
+        for (j = 0; j < 2; j++) {
+          gp_Vec aVec(aDir);
+          gp_Pnt aPntOnCyl;
 
-       if (aSqDist <= (aTolConf * aTolConf) || aCenter.IsEqual(aPOnAxis.Value(), aTolConf)) {
-         myNbExt -= 2;
-         continue;
-       }
+          aVec.Multiply(aShift[j]);
+          aPntOnCyl = aPOnCirc.Value().Translated(aVec);
 
-       gp_Dir           aDir(aPOnAxis.Value().XYZ().
-                             Subtracted(aPOnCirc.Value().XYZ()));
-       Standard_Real    aShift[2] = { aDist + aCylRad, aDist - aCylRad };
-       Standard_Integer j;
+          Standard_Real aU;
+          Standard_Real aV;
 
-       for (j = 0; j < 2; j++) {
-         gp_Vec aVec(aDir);
-         gp_Pnt aPntOnCyl;
+          ElSLib::Parameters(S, aPntOnCyl, aU, aV);
 
-         aVec.Multiply(aShift[j]);
-         aPntOnCyl = aPOnCirc.Value().Translated(aVec);
+          Extrema_POnSurf aPOnSurf(aU, aV, aPntOnCyl);
 
-         Standard_Real aU;
-         Standard_Real aV;
+          myPoint1->SetValue(aCurI, aPOnCirc);
+          myPoint2->SetValue(aCurI, aPOnSurf);
+          mySqDist->SetValue(aCurI++, aShift[j] * aShift[j]);
+        }
+      }
+
+      // Adding intersection points to the list of extremas
+      for (i=1; i<=aNbInter; i++)
+      {
+        Standard_Real aU;
+        Standard_Real aV;
 
-         ElSLib::Parameters(S, aPntOnCyl, aU, aV);
+        gp_Pnt aInterPnt = aCircCylInter.Point(i);
 
-         Extrema_POnSurf aPOnSurf(aU, aV, aPntOnCyl);
+        aU = ElCLib::Parameter(C, aInterPnt);
+        Extrema_POnCurv aPOnCirc(aU, aInterPnt);
 
-         myPoint1->SetValue(aCurI, aPOnCirc);
-         myPoint2->SetValue(aCurI, aPOnSurf);
-         mySqDist->SetValue(aCurI++, aShift[j] * aShift[j]);
-       }
+        ElSLib::Parameters(S, aInterPnt, aU, aV);
+        Extrema_POnSurf aPOnCyl(aU, aV, aInterPnt);
+        myPoint1->SetValue(aCurI, aPOnCirc);
+        myPoint2->SetValue(aCurI, aPOnCyl);
+        mySqDist->SetValue(aCurI++, 0.0);
       }
     }
 
diff --git a/tests/bugs/moddata_3/bug23863 b/tests/bugs/moddata_3/bug23863
new file mode 100755 (executable)
index 0000000..6abaafb
--- /dev/null
@@ -0,0 +1,38 @@
+puts "================"
+puts "OCC23863"
+puts "================"
+puts ""
+#######################################################################
+# Wrong distance value between circle and cylinder
+#######################################################################
+
+pcylinder b1 10 10
+explode b1 f
+copy b1_1 b1
+circle b2 0 10 10 1 0 0 5
+mkedge b2 b2
+
+distmini d b1 b2
+
+regexp {([-0-9.+eE]+)$} [dump d_val] full dist
+regexp { +Vertex +: +Min +[-0-9.+eE]+ +Max +([-0-9.+eE]+)} [ maxtolerance d ] full toler
+set good_dist 0
+if { [expr abs( ${dist} - ${good_dist} )] > ${toler} } {
+    puts "Faulty : the distanse is ${dist}. It is bad value"
+}
+
+regexp { +Point 3D : +([-0-9.+eE]+), +([-0-9.+eE]+), +([-0-9.+eE]+)} [ dump d ] full x y z
+set good_x 0
+set good_y 10
+set good_z 5
+if { [expr abs( ${x} - ${good_x} )] > ${toler} } {
+    puts "Faulty : the x coordinate of the point is ${x}. It is bad value"
+}
+if { [expr abs( ${y} - ${good_y} )] > ${toler} } {
+    puts "Faulty : the y coordinate of the point is ${y}. It is bad value"
+}
+if { [expr abs( ${z} - ${good_z} )] > ${toler} } {
+    puts "Faulty : the z coordinate of the point is ${z}. It is bad value"
+}
+
+set 2dviewer 1