0024890: Result of uniform scaling is invalid
authorifv <ifv@opencascade.com>
Thu, 29 Oct 2015 12:39:20 +0000 (15:39 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 19 Nov 2015 11:15:15 +0000 (14:15 +0300)
Test case for issue CR24890

src/BRepBuilderAPI/BRepBuilderAPI_NurbsConvert.cxx
src/BRepBuilderAPI/BRepBuilderAPI_NurbsConvert.hxx
src/BRepOffsetAPI/BRepOffsetAPI_DraftAngle.cxx
src/BRepOffsetAPI/BRepOffsetAPI_DraftAngle.hxx
src/BRepTools/BRepTools.cxx
src/BRepTools/BRepTools.hxx
src/BRepTools/BRepTools_NurbsConvertModification.cxx
src/BRepTools/BRepTools_NurbsConvertModification.hxx
src/Draft/Draft_Modification.cxx
tests/bugs/modalg_6/bug24890 [new file with mode: 0755]

index 9d9550b..a130f82 100644 (file)
@@ -61,7 +61,138 @@ void BRepBuilderAPI_NurbsConvert::Perform(const TopoDS_Shape& S,
   Handle(BRepTools_NurbsConvertModification) theModif = 
     Handle(BRepTools_NurbsConvertModification)::DownCast(myModification);
   DoModif(S,myModification);
+  CorrectVertexTol();
 }
 
 
+//=======================================================================
+//function : CorrectVertexTol
+//purpose  : 
+//=======================================================================
+
+void BRepBuilderAPI_NurbsConvert::CorrectVertexTol()
+{
+  TopTools_MapOfShape anInitVertices;
+  TopExp_Explorer anExp(myInitialShape, TopAbs_VERTEX);
+  for(; anExp.More(); anExp.Next())
+  {
+    anInitVertices.Add(anExp.Current());
+  }
+  //
+  Handle(BRepTools_NurbsConvertModification) aModif = 
+    Handle(BRepTools_NurbsConvertModification)::DownCast(myModification);
 
+  BRep_Builder aBB;
+  myVtxToReplace.Clear();
+  TopTools_ListIteratorOfListOfShape anEIter(aModif->GetUpdatedEdges());
+  for(; anEIter.More(); anEIter.Next())
+  {
+    const TopoDS_Shape& anE = anEIter.Value();
+    //
+    Standard_Real anETol = BRep_Tool::Tolerance(TopoDS::Edge(anE));
+    TopoDS_Iterator anIter(anE);
+    for(; anIter.More(); anIter.Next())
+    {
+      const TopoDS_Vertex& aVtx = TopoDS::Vertex(anIter.Value());
+      if(anInitVertices.Contains(aVtx))
+      {
+        if(myVtxToReplace.IsBound(aVtx))
+        {
+          aBB.UpdateVertex(TopoDS::Vertex(myVtxToReplace(aVtx)), anETol + Epsilon(anETol));
+        }
+        else
+        {
+          Standard_Real aVTol = BRep_Tool::Tolerance(aVtx);
+          if(aVTol < anETol)
+          {
+            TopoDS_Vertex aNewVtx;
+            gp_Pnt aVPnt = BRep_Tool::Pnt(aVtx);
+            aBB.MakeVertex(aNewVtx, aVPnt,anETol + Epsilon(anETol));
+            aNewVtx.Orientation(aVtx.Orientation());
+            myVtxToReplace.Bind(aVtx, aNewVtx);
+          }
+        }
+      }
+      else
+      {
+        aBB.UpdateVertex(aVtx, anETol + Epsilon(anETol));
+      }
+    }
+  }
+  //
+  if(myVtxToReplace.IsEmpty())
+  {
+    return;
+  }
+  //
+  mySubs.Clear();
+  TopTools_DataMapIteratorOfDataMapOfShapeShape anIter(myVtxToReplace);
+  for(; anIter.More(); anIter.Next())
+  {
+    mySubs.Replace(anIter.Key(), anIter.Value());
+  }
+  mySubs.Apply( myShape );
+  myShape = mySubs.Value(myShape);
+  //
+}
+
+//=======================================================================
+//function : ModifiedShape
+//purpose  : 
+//=======================================================================
+
+TopoDS_Shape BRepBuilderAPI_NurbsConvert::ModifiedShape
+                                           (const TopoDS_Shape& S) const
+{
+ if(S.ShapeType() == TopAbs_VERTEX)
+ {
+   if(myVtxToReplace.IsBound(S))
+   {
+     return myVtxToReplace(S);
+   }
+ }
+ if(myVtxToReplace.IsEmpty())
+ {
+  return myModifier.ModifiedShape(S);
+ }
+ else
+ {
+   const TopoDS_Shape& aNS = myModifier.ModifiedShape(S);
+   return mySubs.Value(aNS);
+ }
+}
+
+//=======================================================================
+//function : Modified
+//purpose  : 
+//=======================================================================
+
+const TopTools_ListOfShape& BRepBuilderAPI_NurbsConvert::Modified
+                                                  (const TopoDS_Shape& F)
+{
+  myGenerated.Clear();
+  if(F.ShapeType() == TopAbs_VERTEX)
+  {
+    if(myVtxToReplace.IsBound(F))
+    {
+      myGenerated.Append(myVtxToReplace(F));
+    }
+    else
+    {
+      myGenerated.Append(myModifier.ModifiedShape(F));
+    }
+  }
+  else
+  {
+    if(myVtxToReplace.IsEmpty())
+    {
+      myGenerated.Append(myModifier.ModifiedShape(F));
+    }
+    else
+    {
+      const TopoDS_Shape& aNS = myModifier.ModifiedShape(F);
+      myGenerated.Append(mySubs.Value(aNS));
+    }
+  }
+  return myGenerated;
+}
index faf5151..b439d77 100644 (file)
@@ -23,6 +23,9 @@
 
 #include <BRepBuilderAPI_ModifyShape.hxx>
 #include <Standard_Boolean.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
+#include <BRepTools_ReShape.hxx>
+
 class TopoDS_Shape;
 
 
@@ -66,6 +69,17 @@ public:
   Standard_EXPORT void Perform (const TopoDS_Shape& S, const Standard_Boolean Copy = Standard_False);
 
 
+  //! Returns the list  of shapes modified from the shape
+  //! <S>.
+  Standard_EXPORT virtual const TopTools_ListOfShape& Modified (const TopoDS_Shape& S);
+  
+  //! Returns the modified shape corresponding to <S>.
+  //! S can correspond to the entire initial shape or to its subshape.
+  //! Exceptions
+  //! Standard_NoSuchObject if S is not the initial shape or
+  //! a subshape of the initial shape to which the
+  //! transformation has been applied. 
+  Standard_EXPORT virtual TopoDS_Shape ModifiedShape (const TopoDS_Shape& S) const;
 
 
 protected:
@@ -76,9 +90,10 @@ protected:
 
 private:
 
+  Standard_EXPORT void CorrectVertexTol();
 
-
-
+  TopTools_DataMapOfShapeShape myVtxToReplace;
+  BRepTools_ReShape mySubs;
 
 };
 
index d2522e8..bac073c 100644 (file)
@@ -200,7 +200,7 @@ const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::ModifiedFaces() const
 }
 
 //=======================================================================
-//function : ModifiedFaces
+//function : Generated
 //purpose  : 
 //=======================================================================
 
@@ -216,15 +216,21 @@ const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Generated(const TopoDS_Sha
     Standard_Real        Tol;
     Standard_Boolean     RW,RF;
     if (DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) {
-      myGenerated.Append(ModifiedShape (S));
+      if(myVtxToReplace.IsEmpty())
+      {
+        myGenerated.Append(ModifiedShape (S));
+      }
+      else
+      {
+        myGenerated.Append(mySubs.Value(ModifiedShape (S)));
+      }
     }
   }
   return myGenerated;
 }
 
 //=======================================================================
-//function : ModifiedFaces
+//function : Modified
 //purpose  : 
 //=======================================================================
 
@@ -242,9 +248,16 @@ const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Modified(const TopoDS_Shap
     
     if (!DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) {
       // Ce n est pas une generation => peut etre une  modif
-      myGenerated.Append(ModifiedShape (S));
+      if(myVtxToReplace.IsEmpty())
+      {
+        myGenerated.Append(ModifiedShape (S));
+      }
+      else
+      {
+        myGenerated.Append(mySubs.Value(ModifiedShape (S)));
+      }
       if (myGenerated.Extent() == 1 && myGenerated.First().IsSame(S)) {
-       myGenerated.Clear();
+             myGenerated.Clear();
       }
     }
   }
@@ -266,7 +279,15 @@ TopoDS_Shape BRepOffsetAPI_DraftAngle::ModifiedShape
       return myVtxToReplace(S);
     }
   }
-  return myModifier.ModifiedShape(S);
+  if(myVtxToReplace.IsEmpty())
+  {
+    return myModifier.ModifiedShape(S);
+  }
+  else
+  {
+    const TopoDS_Shape& aNS = myModifier.ModifiedShape(S);
+    return mySubs.Value(aNS);
+  }
 }
 
 //=======================================================================
@@ -943,6 +964,7 @@ void BRepOffsetAPI_DraftAngle::CorrectVertexTol()
             TopoDS_Vertex aNewVtx;
             gp_Pnt aVPnt = BRep_Tool::Pnt(aVtx);
             aBB.MakeVertex(aNewVtx, aVPnt,anETol + Epsilon(anETol));
+            aNewVtx.Orientation(aVtx.Orientation());
             myVtxToReplace.Bind(aVtx, aNewVtx);
           }
         }
@@ -959,20 +981,13 @@ void BRepOffsetAPI_DraftAngle::CorrectVertexTol()
     return;
   }
   //
-  BRepTools_Substitution aSub;
+  mySubs.Clear();
   TopTools_DataMapIteratorOfDataMapOfShapeShape anIter(myVtxToReplace);
   for(; anIter.More(); anIter.Next())
   {
-    TopTools_ListOfShape aSubVtx;
-    aSubVtx.Append(anIter.Value());
-    aSub.Substitute(anIter.Key(), aSubVtx);
-  }
-  aSub.Build( myShape );
-  if (aSub.IsCopied( myShape ))
-  {
-    const TopTools_ListOfShape& listSh = aSub.Copy( myShape );
-    if (! listSh.IsEmpty())
-      myShape = listSh.First();
+    mySubs.Replace(anIter.Key(), anIter.Value());
   }
+  mySubs.Apply( myShape );
+  myShape = mySubs.Value(myShape);
   //
 }
index 223596c..6955c6f 100644 (file)
@@ -27,6 +27,8 @@
 #include <Standard_Real.hxx>
 #include <Standard_Boolean.hxx>
 #include <Draft_ErrorStatus.hxx>
+#include <BRepTools_ReShape.hxx>
+
 class StdFail_NotDone;
 class Standard_NullObject;
 class Standard_NoSuchObject;
@@ -208,7 +210,7 @@ private:
   Standard_EXPORT void CorrectVertexTol();
 
   TopTools_DataMapOfShapeShape myVtxToReplace;
-
+  BRepTools_ReShape mySubs;
 };
 
 
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;
+
+}
 
 
index 9ef08d9..cc49cc1 100644 (file)
@@ -52,6 +52,9 @@ class BRepTools_Substitution;
 class BRepTools_Quilt;
 class BRepTools_ShapeSet;
 class BRepTools_ReShape;
+class Geom_Curve;
+class Geom2d_Curve;
+class Geom_Surface;
 
 
 //! The BRepTools package provides  utilities for BRep
@@ -201,6 +204,18 @@ public:
   //! <B> is used to build the shape.
   Standard_EXPORT static Standard_Boolean Read (TopoDS_Shape& Sh, const Standard_CString File, const BRep_Builder& B, const Handle(Message_ProgressIndicator)& PR = NULL);
 
+  //! Evals real tolerance of edge  <theE>.
+  //! <theC3d>, <theC2d>, <theS>, <theF>, <theL> are
+  //! correspondently 3d curve of edge, 2d curve on surface <theS> and
+  //! rang of edge
+  //! If calculated tolerance is more then current edge tolerance, edge is updated.
+  //! Method returns actual tolerance of edge
+  Standard_EXPORT static Standard_Real EvalAndUpdateTol(const TopoDS_Edge& theE, 
+                                                        const Handle(Geom_Curve)& theC3d, 
+                                                        const Handle(Geom2d_Curve) theC2d, 
+                                                        const Handle(Geom_Surface)& theS,
+                                                        const Standard_Real theF,
+                                                        const Standard_Real theL);
 
 
 
index ac076c3..a94c307 100644 (file)
@@ -67,7 +67,8 @@
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
-
+#include <BRep_Builder.hxx>
+//
 static void GeomLib_ChangeUBounds(Handle(Geom_BSplineSurface)& aSurface,
                   const Standard_Real newU1,
                   const Standard_Real newU2)
@@ -415,6 +416,12 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
             (st == STANDARD_TYPE(Geom2d_BezierCurve))) {
           if(isConvert2d) {
             Curve2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
+            Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
+            if(newTol > Tol)
+            {
+              Tol = newTol;
+              myUpdatedEdges.Append(newE);
+            }
             return Standard_True;
           }
           return Standard_False;
@@ -457,9 +464,21 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
       ProjLib_ComputeApprox ProjOnCurve(G3dAHC,GAHS,Tol);
       if(ProjOnCurve.BSpline().IsNull()) {
         Curve2d = Geom2dConvert::CurveToBSplineCurve(ProjOnCurve.Bezier());
+        Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
+        if(newTol > Tol)
+        {
+          Tol = newTol;
+          myUpdatedEdges.Append(newE);
+        }
         return Standard_True;
       }
       Curve2d = ProjOnCurve.BSpline();
+      Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
+      if(newTol > Tol)
+      {
+        Tol = newTol;
+        myUpdatedEdges.Append(newE);
+      }
       return Standard_True;
     }
     GeomAdaptor_Surface GAS(S,Uinf-u,Usup+u,Vinf-v,Vsup+v);
@@ -470,10 +489,22 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
 
     if(ProjOnCurve.IsDone()) {
       Curve2d = ProjOnCurve.BSpline();
+      Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
+      if(newTol > Tol)
+      {
+        Tol = newTol;
+        myUpdatedEdges.Append(newE);
+      }
       return Standard_True;
     }
     else {
       Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
+      Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
+      if(newTol > Tol)
+      {
+        Tol = newTol;
+        myUpdatedEdges.Append(newE);
+      }
       return Standard_True;
     }
   }
@@ -506,6 +537,19 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
       if(C3d.IsNull()) {
          if(isConvert2d) {
            Curve2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
+
+           Handle(Geom_Surface) S;
+           if(newF.IsNull())
+             S = BRep_Tool::Surface(F);
+           else
+             S = BRep_Tool::Surface(newF);
+           //
+           Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
+           if(newTol > Tol)
+           {
+             Tol = newTol;
+             myUpdatedEdges.Append(newE);
+           }
            return Standard_True;
          }
         return Standard_False;
@@ -525,6 +569,12 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
             (st == STANDARD_TYPE(Geom2d_BezierCurve))) {
           if(isConvert2d) {
             Curve2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
+            Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
+            if(newTol > Tol)
+            {
+              Tol = newTol;
+              myUpdatedEdges.Append(newE);
+            }
             return Standard_True;
           }
           return Standard_False;
@@ -566,10 +616,22 @@ Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
       if(ProjOnCurve.IsDone()) {
         Curve2d = ProjOnCurve.BSpline();
         mylcu.Append(ProjOnCurve.Curve2d());
+        Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
+        if(newTol > Tol)
+        {
+          Tol = newTol;
+          myUpdatedEdges.Append(newE);
+        }
         return Standard_True;
       }
       else {
         Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
+        Standard_Real newTol = BRepTools::EvalAndUpdateTol(newE, C3d, Curve2d, S, f3d, l3d);
+        if(newTol > Tol)
+        {
+          Tol = newTol;
+          myUpdatedEdges.Append(newE);
+        }
         mylcu.Append(C2dBis);
         return Standard_True;
       }
@@ -643,3 +705,12 @@ GeomAbs_Shape BRepTools_NurbsConvertModification::Continuity
 }
 
 
+//=======================================================================
+//function : GetUpdatedEdges
+//purpose  : 
+//=======================================================================
+const TopTools_ListOfShape& 
+        BRepTools_NurbsConvertModification::GetUpdatedEdges() const
+{
+  return myUpdatedEdges;
+}
\ No newline at end of file
index 295c4fd..35962ac 100644 (file)
@@ -102,6 +102,7 @@ public:
   //! (resp. <F2>).
   Standard_EXPORT GeomAbs_Shape Continuity (const TopoDS_Edge& E, const TopoDS_Face& F1, const TopoDS_Face& F2, const TopoDS_Edge& NewE, const TopoDS_Face& NewF1, const TopoDS_Face& NewF2);
 
+  Standard_EXPORT const TopTools_ListOfShape& GetUpdatedEdges() const;
 
 
 
@@ -118,6 +119,7 @@ private:
   TopTools_ListOfShape myled;
   TColStd_ListOfTransient mylcu;
   TColStd_IndexedDataMapOfTransientTransient myMap;
+  TopTools_ListOfShape myUpdatedEdges;
 
 
 };
index 85b3aa2..0c2b6cd 100644 (file)
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <GeomLib_CheckCurveOnSurface.hxx>
-#include <BRepLib.hxx>
-//
-static Standard_Real EvalTol(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 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())
-  {
-    return 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;
-        }
-      }
-
-      dmax = 1.2 * Sqrt(dmax);
-      return dmax;
-    }
-    else
-    {
-      return 0.;
-    }
-  }
-}
 
 //=======================================================================
 //function : Draft_Modification
@@ -539,13 +461,7 @@ Standard_Boolean Draft_Modification::NewCurve2d(const TopoDS_Edge& E,
   }
   //
   Handle(Geom_Curve) aC3d = BRep_Tool::Curve(NewE, Fp, Lp);
-  Standard_Real newtol = EvalTol(aC3d, C, SB, Fp, Lp);
-  if(newtol > Tol)
-  {
-    Tol = newtol;
-    BRep_Builder B;
-    B.UpdateEdge(NewE, newtol);
-  }
+  Tol = BRepTools::EvalAndUpdateTol(NewE,aC3d, C, SB, Fp, Lp);
   return Standard_True;
 }
 
diff --git a/tests/bugs/modalg_6/bug24890 b/tests/bugs/modalg_6/bug24890
new file mode 100755 (executable)
index 0000000..9e4ef1b
--- /dev/null
@@ -0,0 +1,15 @@
+puts "============"
+puts "OCC24890"
+puts "============"
+puts ""
+##############################################################
+## Result of uniform scaling is invalid
+##############################################################
+
+restore [locate_data_file bug24890_f0.brep] f0
+
+nurbsconvert result f0
+
+checkshape result
+
+set 3dviewer 1