0031492: BRepBuilderAPI_MakeFace crashes on a wire
authorjgv <jgv@opencascade.com>
Fri, 10 Apr 2020 08:52:37 +0000 (11:52 +0300)
committerjgv <jgv@opencascade.com>
Mon, 20 Apr 2020 17:36:27 +0000 (20:36 +0300)
Method BRepClass_Intersector::LocalGeometry is modified: check whether is tangent defined and check of infinite curvature is added.

src/BRepClass/BRepClass_Intersector.cxx
tests/bugs/modalg_7/bug31492 [new file with mode: 0644]

index a141f56..0f09a60 100644 (file)
 #include <TopExp.hxx>
 #include <TopoDS_Vertex.hxx>
 
+static
+void GetTangentAsChord(const Handle(Geom2d_Curve)& thePCurve,
+                       gp_Dir2d&                   theTangent,
+                       const Standard_Real         theParam,
+                       const Standard_Real         theFirst,
+                       const Standard_Real         theLast);
+
 static 
 void RefineTolerance(const TopoDS_Face& aF,
                      const Geom2dAdaptor_Curve& aC,
@@ -169,12 +176,21 @@ void  BRepClass_Intersector::LocalGeometry(const BRepClass_Edge& E,
                                            gp_Dir2d& Norm, 
                                            Standard_Real& C) const 
 {
-  Standard_Real f,l;
-  Geom2dLProp_CLProps2d Prop(BRep_Tool::CurveOnSurface(E.Edge(),E.Face(),f,l),
-    U,2,Precision::PConfusion());
-  Prop.Tangent(Tang);
-  C = Prop.Curvature();
-  if (C > Precision::PConfusion())
+  Standard_Real fpar, lpar;
+  Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(E.Edge(), E.Face(), fpar, lpar);
+  Geom2dLProp_CLProps2d Prop(aPCurve, U, 2, Precision::PConfusion());
+
+  C = 0.;
+  if (Prop.IsTangentDefined())
+  {
+    Prop.Tangent(Tang);
+    C = Prop.Curvature();
+  }
+  else
+    GetTangentAsChord(aPCurve, Tang, U, fpar, lpar);
+  
+  if (C > Precision::PConfusion() &&
+      !Precision::IsInfinite(C))
     Prop.Normal(Norm);
   else
     Norm.SetCoord(Tang.Y(),-Tang.X());
@@ -220,4 +236,31 @@ void RefineTolerance(const TopoDS_Face& aF,
   }
 }
 
+//=======================================================================
+//function : GetTangentAsChord
+//purpose  : 
+//=======================================================================
+void GetTangentAsChord(const Handle(Geom2d_Curve)& thePCurve,
+                       gp_Dir2d&                   theTangent,
+                       const Standard_Real         theParam,
+                       const Standard_Real         theFirst,
+                       const Standard_Real         theLast)
+{
+  Standard_Real Offset = 0.1*(theLast - theFirst);
+
+  if (theLast - theParam < Precision::PConfusion()) //theParam == theLast
+    Offset *= -1;
+  else if (theParam + Offset > theLast) //<theParam> is close to <theLast>
+    Offset = 0.5*(theLast - theParam);
 
+  gp_Pnt2d aPnt2d = thePCurve->Value(theParam);
+  gp_Pnt2d OffsetPnt2d = thePCurve->Value(theParam + Offset);
+
+  gp_Vec2d aChord(aPnt2d, OffsetPnt2d);
+  if (Offset < 0.)
+    aChord.Reverse();
+
+  Standard_Real SqLength = aChord.SquareMagnitude();
+  if (SqLength > Precision::SquarePConfusion())
+    theTangent = aChord;
+}
diff --git a/tests/bugs/modalg_7/bug31492 b/tests/bugs/modalg_7/bug31492
new file mode 100644 (file)
index 0000000..1326e58
--- /dev/null
@@ -0,0 +1,8 @@
+puts "==================================================="
+puts "OCC31492: BRepBuilderAPI_MakeFace crashes on a wire"
+puts "==================================================="
+puts ""
+
+brestore [locate_data_file bug31492.brep] a
+
+mkplane result a