0025555: Wrong result of classification of a point relative to solid
authorazv <azv@opencascade.com>
Thu, 11 Dec 2014 13:06:35 +0000 (16:06 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 11 Dec 2014 13:07:29 +0000 (16:07 +0300)
Implemented additional verification that the point found by Extrema is placed inside the face. This way turns off searching the additional inner point.

Test case for issue CR25555

src/BRepClass3d/BRepClass3d_SClassifier.cxx
src/BRepClass3d/BRepClass3d_SolidExplorer.cxx
tests/bugs/modalg_5/bug25555 [new file with mode: 0755]

index b205ac4..a53020f 100644 (file)
@@ -309,7 +309,7 @@ void BRepClass3d_SClassifier::Perform(BRepClass3d_SolidExplorer& SolidExplorer,
              if(Intersector3d.IsDone()) { 
                Standard_Integer i;
                for (i=1; i <= Intersector3d.NbPnt(); i++) { 
-                 if(Abs(Intersector3d.WParameter(i)) < Abs(parmin)) {
+                 if(Abs(Intersector3d.WParameter(i)) < Abs(parmin) - Precision::PConfusion()) {
  
                    parmin = Intersector3d.WParameter(i);
                    //  Modified by skv - Thu Sep  4 12:46:32 2003 OCC578 Begin
index 5043721..b9e132c 100644 (file)
@@ -251,6 +251,14 @@ Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace
     void *ptr = (void*)(myMapOfInter.Find(Face));
     if(ptr) { 
       const IntCurvesFace_Intersector& TheIntersector = (*((IntCurvesFace_Intersector *)ptr));
+      // Check if the point is already in the face
+      if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u_,v_))==TopAbs_IN) {
+        gp_Pnt aPnt;
+        surf->D1(u_, v_, aPnt, theVecD1U, theVecD1V);
+        if (aPnt.SquareDistance(APoint_) < Precision::Confusion() * Precision::Confusion())
+          return Standard_True;
+      }
+
       //-- Take 4 points in each Quarter of surface
       //-- -> Index : 1 -> 16
       //-- 
@@ -451,6 +459,9 @@ Standard_Integer BRepClass3d_SolidExplorer::OtherSegment(const gp_Pnt& P,
       //
       // Check if the point is on the face or the face is infinite.
       Standard_Integer anInfFlag = IsInfiniteUV(U1,V1,U2,V2);
+      // default values
+      _u = (U1 + U2) * 0.5;
+      _v = (V1 + V2) * 0.5;
 
       GeomAdaptor_Surface GA(BRep_Tool::Surface(face));
       Extrema_ExtPS Ext(P, GA, TolU, TolV);
@@ -510,6 +521,11 @@ Standard_Integer BRepClass3d_SolidExplorer::OtherSegment(const gp_Pnt& P,
           ptfound=Standard_True;
           return 0;
         }
+
+        // set the parameters found by extrema
+        aPx = Ext.Point(iNear);
+        aPx.Parameter(_u, _v);
+        APoint = aPx.Value();
       }
       //The point is not ON the face or surface. The face is restricted.
       // find point in a face not too far from a projection of P on face
diff --git a/tests/bugs/modalg_5/bug25555 b/tests/bugs/modalg_5/bug25555
new file mode 100755 (executable)
index 0000000..96ef6b1
--- /dev/null
@@ -0,0 +1,21 @@
+puts "============"
+puts "OCC25555"
+puts "============"
+puts ""
+############################################################################
+# Wrong result of classification of a point relative to solid
+############################################################################
+
+restore [locate_data_file bug25555_p] p
+restore [locate_data_file bug25555_z] z
+
+set cls1 [bclassify z p]
+if { [regexp {OUT} $cls1] } {
+    puts "OK : Good result of classification of a point relative to solid"
+} else {
+    puts "Error : Wrong result of classification of a point relative to solid"
+}
+
+smallview
+fit
+set only_screen_axo 1