0024890: Result of uniform scaling is invalid
[occt.git] / src / BRepTools / BRepTools.cxx
index f706f50..706708a 100644 (file)
@@ -62,7 +62,7 @@
 #include <TopoDS_Vertex.hxx>
 #include <TopoDS_Wire.hxx>
 #include <TopTools_SequenceOfShape.hxx>
-
+#include <GeomLib_CheckCurveOnSurface.hxx>
 #include <errno.h>
 //=======================================================================
 //function : UVBounds
@@ -948,5 +948,92 @@ Standard_Boolean BRepTools::IsReallyClosed(const TopoDS_Edge& E,
   return nbocc == 2;
 }
 
+//=======================================================================
+//function : EvalAndUpdateTol
+//purpose  : 
+//=======================================================================
+
+Standard_Real BRepTools::EvalAndUpdateTol(const TopoDS_Edge& theE, 
+                                 const Handle(Geom_Curve)& C3d, 
+                                 const Handle(Geom2d_Curve) C2d, 
+                                 const Handle(Geom_Surface)& S,
+                                 const Standard_Real f,
+                                 const Standard_Real l)
+{
+  Standard_Real newtol = 0.;
+  Standard_Real first = f, last = l;
+  //Set first, last to avoid ErrosStatus = 2 because of 
+  //too strong checking of limits in class CheckCurveOnSurface
+  //
+  if(!C3d->IsPeriodic())
+  {
+    first = Max(first, C3d->FirstParameter());
+    last = Min(last, C3d->LastParameter());
+  }
+  if(!C2d->IsPeriodic())
+  {
+    first = Max(first, C2d->FirstParameter());
+    last = Min(last, C2d->LastParameter());
+  }
+
+  GeomLib_CheckCurveOnSurface CT(C3d, S, first, last);
+  CT.Perform(C2d);
+  if(CT.IsDone())
+  {
+    newtol = CT.MaxDistance();
+  }
+  else
+  {
+    if(CT.ErrorStatus() == 3 || (CT.ErrorStatus() == 2 &&
+      (C3d->IsPeriodic() || C2d->IsPeriodic())))
+    {
+      //Try to estimate by sample points
+      Standard_Integer nbint = 22;
+      Standard_Real dt = (last - first) / nbint;
+      dt = Max(dt, Precision::Confusion());
+      Standard_Real d, dmax = 0.;
+      gp_Pnt2d aP2d;
+      gp_Pnt aPC, aPS;
+      Standard_Integer cnt = 0; 
+      Standard_Real t = first;
+      for(; t <= last; t += dt)
+      {
+        cnt++;
+        C2d->D0(t, aP2d);
+        C3d->D0(t, aPC);
+        S->D0(aP2d.X(), aP2d.Y(), aPS);
+        d = aPS.SquareDistance(aPC);
+        if(d > dmax)
+        {
+          dmax = d;
+        }
+      }
+      if(cnt < nbint + 1)
+      {
+        t = last;
+        C2d->D0(t, aP2d);
+        C3d->D0(t, aPC);
+        S->D0(aP2d.X(), aP2d.Y(), aPS);
+        d = aPS.SquareDistance(aPC);
+        if(d > dmax)
+        {
+          dmax = d;
+        }
+      }
+
+      newtol = 1.2 * Sqrt(dmax);
+    }
+  }
+  Standard_Real Tol = BRep_Tool::Tolerance(theE);
+  if(newtol > Tol)
+  {
+    Tol = newtol;
+    BRep_Builder B;
+    B.UpdateEdge(theE, Tol);
+  }
+
+  return Tol;
+
+}