0030880: Modeling Algorithms - Bug in BRepExtrema_ExtCF
authoremv <emv@opencascade.com>
Thu, 22 Aug 2019 10:54:53 +0000 (13:54 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 6 Sep 2019 16:23:19 +0000 (19:23 +0300)
Use the BRepTopAdaptor_FClass2d instead of BRepClass_FaceClassifier in BRepExtrema_ExtCF for classification of the found intersection points.

src/BRepExtrema/BRepExtrema_ExtCF.cxx
src/QABugs/QABugs_20.cxx
tests/bugs/modalg_7/bug30880_1 [new file with mode: 0644]
tests/bugs/modalg_7/bug30880_2 [new file with mode: 0644]

index 59d67b3..109ce32 100644 (file)
@@ -19,7 +19,7 @@
 #include <BRep_Tool.hxx>
 #include <BRepTools.hxx>
 #include <Geom_Curve.hxx>
-#include <BRepClass_FaceClassifier.hxx>
+#include <BRepTopAdaptor_FClass2d.hxx>
 #include <gp_Pnt2d.hxx>
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepAdaptor_HSurface.hxx>
@@ -94,8 +94,14 @@ void BRepExtrema_ExtCF::Perform(const TopoDS_Edge& E, const TopoDS_Face& F2)
   else
   {
     // Exploration of points and classification
-    BRepClass_FaceClassifier classifier;
-    const Standard_Real Tol = BRep_Tool::Tolerance(F2);
+    const Standard_Real Tol = BRep_Tool::Tolerance (F2);
+    BRepTopAdaptor_FClass2d classifier (F2, Tol);
+
+    // If the underlying surface of the face is periodic
+    // Extrema should return the point within the period,
+    // so there is no point to adjust it in classifier.
+    Standard_Boolean isAdjustPeriodic = Standard_False;
+
     Extrema_POnCurv P1;
     Extrema_POnSurf P2;
 
@@ -104,8 +110,7 @@ void BRepExtrema_ExtCF::Perform(const TopoDS_Edge& E, const TopoDS_Face& F2)
       myExtCS.Points(i, P1, P2);
       P2.Parameter(U1, U2);
       const gp_Pnt2d Puv(U1, U2);
-      classifier.Perform(F2, Puv, Tol);
-      const TopAbs_State state = classifier.State();
+      const TopAbs_State state = classifier.Perform (Puv, isAdjustPeriodic);
       if (state == TopAbs_ON || state == TopAbs_IN)
       {
         mySqDist.Append(myExtCS.SquareDistance(i));
index b9c898e..d2e0bd8 100644 (file)
@@ -3239,6 +3239,76 @@ static Standard_Integer OCC30869 (Draw_Interpretor& theDI, Standard_Integer theA
   return 0;
 }
 
+#include <BRepExtrema_ExtCF.hxx>
+//=======================================================================
+//function : OCC30880
+//purpose  :
+//=======================================================================
+static Standard_Integer OCC30880 (Draw_Interpretor& theDI, Standard_Integer theArgc, const char** theArgv)
+{
+  if (theArgc != 3)
+  {
+    theDI.PrintHelp (theArgv[0]);
+    return 1;
+  }
+
+  TopoDS_Shape anEdge = DBRep::Get (theArgv[1]);
+  if (anEdge.IsNull() || anEdge.ShapeType() != TopAbs_EDGE)
+  {
+    theDI << theArgv[1] << " is not an edge.\n";
+    return 1;
+  }
+
+  TopoDS_Shape aFace = DBRep::Get (theArgv[2]);
+  if (aFace.IsNull() || aFace.ShapeType() != TopAbs_FACE)
+  {
+    theDI << theArgv[2] << " is not a face.\n";
+    return 1;
+  }
+
+  BRepExtrema_ExtCF anExtCF (TopoDS::Edge (anEdge),
+                             TopoDS::Face (aFace));
+  if (!anExtCF.IsDone())
+  {
+    theDI << "Not done\n";
+    return 0;
+  }
+
+  if (!anExtCF.NbExt())
+  {
+    theDI << "No solutions\n";
+    return 0;
+  }
+
+  if (anExtCF.IsParallel())
+  {
+    theDI << "Infinite number of solutions, distance - " << Sqrt (anExtCF.SquareDistance (1)) << "\n";
+    return 0;
+  }
+
+  Standard_Real aDistMin = RealLast();
+  Standard_Integer aSolMin = -1;
+  // Look for the minimal solution
+  for (int i = 1; i <= anExtCF.NbExt(); ++i)
+  {
+    Standard_Real aDist = anExtCF.SquareDistance (i);
+    if (aDist < aDistMin)
+    {
+      aDistMin = aDist;
+      aSolMin = i;
+    }
+  }
+
+  if (aSolMin < 0)
+  {
+    theDI << "Failed\n";
+    return 0;
+  }
+
+  theDI << "Minimal distance - " << Sqrt (aDistMin) << "\n";
+  return 0;
+}
+
 #include <BRepPrimAPI_MakeBox.hxx>
 static Standard_Integer OCC30704(Draw_Interpretor& di, Standard_Integer, const char**)
 {
@@ -3328,6 +3398,10 @@ void QABugs::Commands_20(Draw_Interpretor& theCommands) {
                                "Usage: OCC30869 wire",
                    __FILE__, OCC30869, group);
 
+  theCommands.Add ("OCC30880", "Looks for extrema between edge and face.\n"
+                               "Usage: OCC30880 edge face",
+                   __FILE__, OCC30880, group);
+
   theCommands.Add("OCC30704", "OCC30704", __FILE__, OCC30704, group);
   theCommands.Add("OCC30704_1", "OCC30704_1", __FILE__, OCC30704_1, group);
 
diff --git a/tests/bugs/modalg_7/bug30880_1 b/tests/bugs/modalg_7/bug30880_1
new file mode 100644 (file)
index 0000000..0bf8006
--- /dev/null
@@ -0,0 +1,13 @@
+puts "========"
+puts "0030880: Bug in BRepExtrema_ExtCF"
+puts "========"
+puts ""
+
+pload QAcommands
+
+restore [locate_data_file bug30880_edge.brep] e
+restore [locate_data_file bug30880_face.brep] f
+
+if {![regexp "No solutions" [OCC30880 e f]]} {
+  puts "Error: Incorrect extrema solutions"
+}
diff --git a/tests/bugs/modalg_7/bug30880_2 b/tests/bugs/modalg_7/bug30880_2
new file mode 100644 (file)
index 0000000..c75dcb0
--- /dev/null
@@ -0,0 +1,10 @@
+puts "========"
+puts "0030880: Bug in BRepExtrema_ExtCF"
+puts "========"
+puts ""
+
+restore [locate_data_file bug30880_face.brep] f
+point p2d -0.0034857302428251678 0.016350559703980902
+if {![regexp "OUT" [b2dclassifx f p2d -tol 1.e-7]]} {
+  puts "Error: Incorrect classification of the point"
+}