0031203: Test harness command "bsection" on the planar faces return only one vertex...
authorifv <ifv@opencascade.com>
Thu, 28 Nov 2019 12:22:53 +0000 (15:22 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 19 Dec 2019 13:45:54 +0000 (16:45 +0300)
BRepClass/BRepClass_FaceExplorer.cxx:
Protection against intersection of test ray with almost parallel edges is added.

SWDRAW/SWDRAW_ShapeFix.cxx: add tolerance as parameter in command checkfclass2d

tests/bugs/modalg_7/bug31203:
test case is added

src/BRepClass/BRepClass_FaceExplorer.cxx
src/SWDRAW/SWDRAW_ShapeFix.cxx
tests/bugs/modalg_7/bug31203 [new file with mode: 0644]

index b2255c4..1c9c706 100644 (file)
@@ -27,6 +27,7 @@
 #include <Precision.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Face.hxx>
+#include <Geom2dAPI_ProjectPointOnCurve.hxx>
 
 static const Standard_Real Probing_Start = 0.123;
 static const Standard_Real Probing_End = 0.7;
@@ -140,7 +141,7 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
                                                      gp_Lin2d& L,
                                                      Standard_Real& Par)
 {
-  TopExp_Explorer      anExpF(myFace,TopAbs_EDGE);
+  TopExp_Explorer      anExpF(myFace, TopAbs_EDGE);
   Standard_Integer     i;
   Standard_Real        aFPar;
   Standard_Real        aLPar;
@@ -153,7 +154,7 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
     if (i != myCurEdgeInd)
       continue;
 
-    const TopoDS_Shape       &aLocalShape   = anExpF.Current();
+    const TopoDS_Shape       &aLocalShape = anExpF.Current();
     const TopAbs_Orientation  anOrientation = aLocalShape.Orientation();
 
     if (anOrientation == TopAbs_FORWARD || anOrientation == TopAbs_REVERSED) {
@@ -162,27 +163,29 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
       aC2d = BRep_Tool::CurveOnSurface(anEdge, myFace, aFPar, aLPar);
 
       if (!aC2d.IsNull()) {
-       // Treatment of infinite cases.
-       if (Precision::IsNegativeInfinite(aFPar)) {
-         if (Precision::IsPositiveInfinite(aLPar)) {
-           aFPar = -1.;
-           aLPar =  1.;
-         } else {
-           aFPar = aLPar - 1.;
-         }
-       } else if (Precision::IsPositiveInfinite(aLPar))
-         aLPar = aFPar + 1.;
-
-       for (; myCurEdgePar < Probing_End ;myCurEdgePar += Probing_Step) {
-         aParamIn = myCurEdgePar*aFPar + (1. - myCurEdgePar)*aLPar;
+        // Treatment of infinite cases.
+        if (Precision::IsNegativeInfinite(aFPar)) {
+          if (Precision::IsPositiveInfinite(aLPar)) {
+            aFPar = -1.;
+            aLPar = 1.;
+          }
+          else {
+            aFPar = aLPar - 1.;
+          }
+        }
+        else if (Precision::IsPositiveInfinite(aLPar))
+          aLPar = aFPar + 1.;
+
+        for (; myCurEdgePar < Probing_End; myCurEdgePar += Probing_Step) {
+          aParamIn = myCurEdgePar*aFPar + (1. - myCurEdgePar)*aLPar;
 
           gp_Vec2d aTanVec;
-         aC2d->D1(aParamIn, aPOnC, aTanVec);
-         Par = aPOnC.SquareDistance(P);
+          aC2d->D1(aParamIn, aPOnC, aTanVec);
+          Par = aPOnC.SquareDistance(P);
 
-         if (Par > aTolParConf2) {
-           gp_Vec2d aLinVec(P, aPOnC);
-           gp_Dir2d aLinDir(aLinVec);
+          if (Par > aTolParConf2) {
+            gp_Vec2d aLinVec(P, aPOnC);
+            gp_Dir2d aLinDir(aLinVec);
 
             Standard_Real aTanMod = aTanVec.SquareMagnitude();
             if (aTanMod < aTolParConf2)
@@ -190,8 +193,10 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
             aTanVec /= Sqrt(aTanMod);
             Standard_Real aSinA = aTanVec.Crossed(aLinDir.XY());
             const Standard_Real SmallAngle = 0.001;
+            Standard_Boolean isSmallAngle = Standard_False;
             if (Abs(aSinA) < SmallAngle)
             {
+              isSmallAngle = Standard_True;
               // The line from the input point P to the current point on edge
               // is tangent to the edge curve. This condition is bad for classification.
               // Therefore try to go to another point in the hope that there will be 
@@ -201,28 +206,66 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
                 continue;
             }
 
-           L = gp_Lin2d(P, aLinDir);
-
-           // Check if ends of a curve lie on a line.
-           aC2d->D0(aFPar, aPOnC);
-
-           if (L.SquareDistance(aPOnC) > aTolParConf2) {
-             aC2d->D0(aLPar, aPOnC);
-
-             if (L.SquareDistance(aPOnC) > aTolParConf2) {
-               myCurEdgePar += Probing_Step;
-
-               if (myCurEdgePar >= Probing_End) {
-                 myCurEdgeInd++;
-                 myCurEdgePar = Probing_Start;
-               }
-
-               Par = Sqrt(Par);
-               return Standard_True;
-             }
-           }
-         }
-       }
+            L = gp_Lin2d(P, aLinDir);
+
+            // Check if ends of a curve lie on a line.
+            aC2d->D0(aFPar, aPOnC);
+            gp_Pnt2d aFPOnC = aPOnC;
+            if (L.SquareDistance(aPOnC) > aTolParConf2) {
+              aC2d->D0(aLPar, aPOnC);
+              if (L.SquareDistance(aPOnC) > aTolParConf2) {
+
+                if (isSmallAngle)
+                {
+                  //Try to find minimal distance between curve and line
+
+                  Geom2dAPI_ProjectPointOnCurve aProj;
+                  aProj.Init(P, aC2d, aFPar, aLPar);
+                  if (aProj.NbPoints() > 0)
+                  {
+                    gp_Pnt2d aLPOnC = aPOnC;
+                    Standard_Real aFDist = P.SquareDistance(aFPOnC);
+                    Standard_Real aLDist = P.SquareDistance(aLPOnC);
+                    Standard_Real aMinDist = aProj.LowerDistance();
+                    aMinDist *= aMinDist;
+                    aPOnC = aProj.NearestPoint();
+                    if (aMinDist > aFDist)
+                    {
+                      aMinDist = aFDist;
+                      aPOnC = aFPOnC;
+                    }
+                    //
+                    if (aMinDist > aLDist)
+                    {
+                      aMinDist = aLDist;
+                      aPOnC = aLPOnC;
+                    }
+                    //
+                    if (aMinDist < Par)
+                    {
+                      Par = aMinDist;
+                      if (Par < aTolParConf2)
+                      {
+                        continue;
+                      }
+                      aLinVec.SetXY((aPOnC.XY() - P.XY()));
+                      aLinDir.SetXY(aLinVec.XY());
+                      L = gp_Lin2d(P, aLinDir);
+                    }
+                  }
+                }
+                myCurEdgePar += Probing_Step;
+                if (myCurEdgePar >= Probing_End) {
+                  myCurEdgeInd++;
+                  myCurEdgePar = Probing_Start;
+                }
+
+                Par = Sqrt(Par);
+                return Standard_True;
+              }
+            }
+          }
+        }
       } // if (!aC2d.IsNull()) {
     } // if (anOrientation == TopAbs_FORWARD ...
 
@@ -233,7 +276,7 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
 
   // nothing found, return an horizontal line
   Par = RealLast();
-  L   = gp_Lin2d(P,gp_Dir2d(1,0));
+  L = gp_Lin2d(P, gp_Dir2d(1, 0));
 
   return Standard_False;
 }
index 3ec30f9..faf0c01 100644 (file)
@@ -746,9 +746,15 @@ static Standard_Integer checkfclass2d(Draw_Interpretor& di, Standard_Integer n,
     di<<"Invalid arguments\n";
     return 1;
   }
+  Standard_Real tol = Precision::Confusion();
+  if (n > 4)
+  {
+    tol = Atof(a[4]);
+  }
+
   TopoDS_Face aFace = TopoDS::Face(Sh1);
   gp_Pnt2d p2d(ucoord,vcoord);
-  BRepTopAdaptor_FClass2d f2d(aFace,Precision::Confusion());
+  BRepTopAdaptor_FClass2d f2d(aFace, tol);
   TopAbs_State stat = f2d.Perform(p2d);
   if(stat == TopAbs_OUT)
     di<<"Point is OUT\n";
@@ -864,7 +870,7 @@ static Standard_Integer connectedges(Draw_Interpretor& di, Standard_Integer n, c
                   __FILE__,fixsmallfaces,g);
   theCommands.Add ("checkoverlapedges","edge1 edge2 [toler domaindist]",
                   __FILE__,checkoverlapedges,g);
-  theCommands.Add ("checkfclass2d","face ucoord vcoord",
+  theCommands.Add ("checkfclass2d","face ucoord vcoord [tol]",
                   __FILE__,checkfclass2d,g);
   theCommands.Add ("connectedges","res shape [toler shared]",
                   __FILE__,connectedges,g);
diff --git a/tests/bugs/modalg_7/bug31203 b/tests/bugs/modalg_7/bug31203
new file mode 100644 (file)
index 0000000..6d6ceea
--- /dev/null
@@ -0,0 +1,14 @@
+puts "======================================================="
+puts "0031203: Test harness command bsection on the planar faces return only one vertex instead edge representing intersection line"
+puts "======================================================="
+puts ""
+
+pload MODELING
+
+restore [locate_data_file bug31203.brep] s 
+
+explode s
+bsection sec s_1 s_2
+
+checknbshapes sec -edge 1 -vertex 2
+