0030932: Modeling Algorithms - Invalid result on 2d curve on surface approximation
authoraml <aml@opencascade.com>
Fri, 13 Sep 2019 08:47:17 +0000 (11:47 +0300)
committerapn <apn@opencascade.com>
Tue, 22 Oct 2019 12:15:46 +0000 (15:15 +0300)
New method generating 3D curve is added when 2D curve is linear isoline.

12 files changed:
src/Approx/Approx_CurveOnSurface.cxx
src/Approx/Approx_CurveOnSurface.hxx
src/BRepAlgo/BRepAlgo_NormalProjection.cxx
src/BRepFill/BRepFill_Sweep.cxx
src/Draft/Draft_Modification_1.cxx
src/GeomInt/GeomInt_IntSS_1.cxx
src/GeomPlate/GeomPlate_BuildPlateSurface.cxx
src/GeomProjLib/GeomProjLib.cxx
src/GeometryTest/GeometryTest_CurveCommands.cxx
src/GeomliteTest/GeomliteTest_CurveCommands.cxx
src/ProjLib/ProjLib_ProjectedCurve.cxx
tests/bugs/moddata_3/bug30932 [new file with mode: 0644]

index 0c4fae4..9bc11d4 100644 (file)
 #include <Geom2d_BSplineCurve.hxx>
 #include <Geom2dAdaptor_HCurve.hxx>
 #include <Geom_BSplineCurve.hxx>
+#include <Geom_TrimmedCurve.hxx>
 #include <GeomAdaptor_HCurve.hxx>
 #include <GeomAdaptor_HSurface.hxx>
+#include <GeomConvert.hxx>
 #include <gp_Pnt.hxx>
 #include <gp_Vec.hxx>
 #include <Precision.hxx>
@@ -300,6 +302,10 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
   }
 }
 
+//=============================================================================
+//function : Approx_CurveOnSurface
+//purpose  : Constructor
+//=============================================================================
  Approx_CurveOnSurface::Approx_CurveOnSurface(const Handle(Adaptor2d_HCurve2d)& C2D,
                                              const Handle(Adaptor3d_HSurface)& Surf,
                                              const Standard_Real First,
@@ -310,14 +316,75 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
                                              const Standard_Integer MaxSegments, 
                                              const Standard_Boolean only3d, 
                                              const Standard_Boolean only2d)
+: myC2D(C2D),
+  mySurf(Surf),
+  myFirst(First),
+  myLast(Last),
+  myTol(Tol),
+  myIsDone(Standard_False),
+  myHasResult(Standard_False),
+  myError3d(0.0),
+  myError2dU(0.0),
+  myError2dV(0.0)
+ {
+   Perform(MaxSegments, MaxDegree, S, only3d, only2d);
+ }
+
+//=============================================================================
+//function : Approx_CurveOnSurface
+//purpose  : Constructor
+//=============================================================================
+ Approx_CurveOnSurface::Approx_CurveOnSurface(const Handle(Adaptor2d_HCurve2d)& theC2D,
+                                              const Handle(Adaptor3d_HSurface)& theSurf,
+                                              const Standard_Real               theFirst,
+                                              const Standard_Real               theLast,
+                                              const Standard_Real               theTol)
+: myC2D(theC2D),
+  mySurf(theSurf),
+  myFirst(theFirst),
+  myLast(theLast),
+  myTol(theTol),
+  myIsDone(Standard_False),
+  myHasResult(Standard_False),
+  myError3d(0.0),
+  myError2dU(0.0),
+  myError2dV(0.0)
+{
+}
+
+//=============================================================================
+//function : Perform
+//purpose  :
+//=============================================================================
+void Approx_CurveOnSurface::Perform(const Standard_Integer theMaxSegments,
+                                    const Standard_Integer theMaxDegree,
+                                    const GeomAbs_Shape    theContinuity,
+                                    const Standard_Boolean theOnly3d,
+                                    const Standard_Boolean theOnly2d)
 {
   myIsDone = Standard_False;
-  if(only3d && only2d) throw Standard_ConstructionError();
-  GeomAbs_Shape Order  = S;
+  myHasResult = Standard_False;
+  myError2dU = 0.0;
+  myError2dV = 0.0;
+  myError3d = 0.0;
 
-  Handle( Adaptor2d_HCurve2d ) TrimmedC2D = C2D->Trim( First, Last, Precision::PConfusion() );
+  if(theOnly3d && theOnly2d) throw Standard_ConstructionError();
+
+  Handle( Adaptor2d_HCurve2d ) TrimmedC2D = myC2D->Trim( myFirst, myLast, Precision::PConfusion() );
+
+  Standard_Boolean isU, isForward;
+  Standard_Real aParam;
+  if (theOnly3d && isIsoLine(TrimmedC2D, isU, aParam, isForward))
+  {
+    if (buildC3dOnIsoLine(TrimmedC2D, isU, aParam, isForward))
+    {
+      myIsDone = Standard_True;
+      myHasResult = Standard_True;
+      return;
+    }
+  }
 
-  Adaptor3d_CurveOnSurface COnS( TrimmedC2D, Surf );
+  Adaptor3d_CurveOnSurface COnS( TrimmedC2D, mySurf );
   Handle(Adaptor3d_HCurveOnSurface) HCOnS = new Adaptor3d_HCurveOnSurface();
   HCOnS->Set(COnS);
 
@@ -327,37 +394,34 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
   Handle(TColStd_HArray1OfReal) ThreeDTol;
 
   // create evaluators and choose appropriate one
-  Approx_CurveOnSurface_Eval3d Eval3dCvOnSurf (HCOnS,             First, Last);
-  Approx_CurveOnSurface_Eval2d Eval2dCvOnSurf (       TrimmedC2D, First, Last);
-  Approx_CurveOnSurface_Eval   EvalCvOnSurf   (HCOnS, TrimmedC2D, First, Last);
+  Approx_CurveOnSurface_Eval3d Eval3dCvOnSurf (HCOnS,             myFirst, myLast);
+  Approx_CurveOnSurface_Eval2d Eval2dCvOnSurf (       TrimmedC2D, myFirst, myLast);
+  Approx_CurveOnSurface_Eval   EvalCvOnSurf   (HCOnS, TrimmedC2D, myFirst, myLast);
   AdvApprox_EvaluatorFunction* EvalPtr;
-  if ( only3d ) EvalPtr = &Eval3dCvOnSurf;
-  else if ( only2d ) EvalPtr = &Eval2dCvOnSurf;
+  if ( theOnly3d ) EvalPtr = &Eval3dCvOnSurf;
+  else if ( theOnly2d ) EvalPtr = &Eval2dCvOnSurf;
   else EvalPtr = &EvalCvOnSurf;
 
   // Initialization for 2d approximation
-  if(!only3d) {
+  if(!theOnly3d) {
     Num1DSS = 2;
     OneDTol = new TColStd_HArray1OfReal(1,Num1DSS);
 
     Standard_Real TolU, TolV;
 
-    TolU = Surf->UResolution(Tol)/2;
-    TolV = Surf->VResolution(Tol)/2;
+    TolU = mySurf->UResolution(myTol)/2;
+    TolV = mySurf->VResolution(myTol)/2;
 
     OneDTol->SetValue(1,TolU);
     OneDTol->SetValue(2,TolV);
   }
   
-  if(!only2d) {
+  if(!theOnly2d) {
     Num3DSS=1;
     ThreeDTol = new TColStd_HArray1OfReal(1,Num3DSS);
-    ThreeDTol->Init(Tol/2);
+    ThreeDTol->Init(myTol/2);
   }
 
-  myError2dU = 0;
-  myError2dV = 0;
-  myError3d = 0;
 
   Standard_Integer NbInterv_C2 = HCOnS->NbIntervals(GeomAbs_C2);
   TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2 + 1);
@@ -369,8 +433,8 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
   AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3);
   AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS, 
                                     OneDTol, TwoDTolNul, ThreeDTol,
-                                    First, Last, Order,
-                                    MaxDegree, MaxSegments,
+                                    myFirst, myLast, theContinuity,
+                                    theMaxDegree, theMaxSegments,
                                     *EvalPtr, CutTool);
 
   myIsDone = aApprox.IsDone();
@@ -381,14 +445,14 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
     Handle(TColStd_HArray1OfInteger) Mults = aApprox.Multiplicities();
     Standard_Integer Degree = aApprox.Degree();
 
-    if(!only2d) 
+    if(!theOnly2d) 
       {
        TColgp_Array1OfPnt Poles(1,aApprox.NbPoles());
        aApprox.Poles(1,Poles);
        myCurve3d = new Geom_BSplineCurve(Poles, Knots->Array1(), Mults->Array1(), Degree);
        myError3d = aApprox.MaxError(3, 1);
       }
-    if(!only3d) 
+    if(!theOnly3d) 
       {
        TColgp_Array1OfPnt2d Poles2d(1,aApprox.NbPoles());
        TColStd_Array1OfReal Poles1dU(1,aApprox.NbPoles());
@@ -404,8 +468,6 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
       }
   }
   
-//    }
-
 }
 
  Standard_Boolean Approx_CurveOnSurface::IsDone() const
@@ -443,3 +505,161 @@ void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
   return myError2dV;
 }
 
+//=============================================================================
+//function : isIsoLine
+//purpose  :
+//=============================================================================
+Standard_Boolean Approx_CurveOnSurface::isIsoLine(const Handle(Adaptor2d_HCurve2d) theC2D,
+                                                  Standard_Boolean&                theIsU,
+                                                  Standard_Real&                   theParam,
+                                                  Standard_Boolean&                theIsForward) const
+{
+  // These variables are used to check line state (vertical or horizontal).
+  Standard_Boolean isAppropriateType = Standard_False;
+  gp_Pnt2d aLoc2d;
+  gp_Dir2d aDir2d;
+
+  // Test type.
+  const GeomAbs_CurveType aType = theC2D->GetType();
+  if (aType == GeomAbs_Line)
+  {
+    gp_Lin2d aLin2d = theC2D->Line();
+    aLoc2d = aLin2d.Location();
+    aDir2d = aLin2d.Direction();
+    isAppropriateType = Standard_True;
+  }
+  else if (aType == GeomAbs_BSplineCurve)
+  {
+    Handle(Geom2d_BSplineCurve) aBSpline2d = theC2D->BSpline();
+    if (aBSpline2d->Degree() != 1 || aBSpline2d->NbPoles() != 2)
+      return Standard_False; // Not a line or uneven parameterization.
+
+    aLoc2d = aBSpline2d->Pole(1);
+
+    // Vector should be non-degenerated.
+    gp_Vec2d aVec2d(aBSpline2d->Pole(1), aBSpline2d->Pole(2));
+    if (aVec2d.SquareMagnitude() < Precision::Confusion())
+      return Standard_False; // Degenerated spline.
+    aDir2d = aVec2d;
+
+    isAppropriateType = Standard_True;
+  }
+  else if (aType == GeomAbs_BezierCurve)
+  {
+    Handle(Geom2d_BezierCurve) aBezier2d = theC2D->Bezier();
+    if (aBezier2d->Degree() != 1 || aBezier2d->NbPoles() != 2)
+      return Standard_False; // Not a line or uneven parameterization.
+
+    aLoc2d = aBezier2d->Pole(1);
+
+    // Vector should be non-degenerated.
+    gp_Vec2d aVec2d(aBezier2d->Pole(1), aBezier2d->Pole(2));
+    if (aVec2d.SquareMagnitude() < Precision::Confusion())
+      return Standard_False; // Degenerated spline.
+    aDir2d = aVec2d;
+
+    isAppropriateType = Standard_True;
+  }
+
+  if (!isAppropriateType)
+    return Standard_False;
+
+  // Check line to be vertical or horizontal.
+  if (aDir2d.IsParallel(gp::DX2d(), Precision::Angular()))
+  {
+    // Horizontal line. V = const.
+    theIsU = Standard_False;
+    theParam = aLoc2d.Y();
+    theIsForward = aDir2d.Dot(gp::DX2d()) > 0.0;
+    return Standard_True;
+  }
+  else if (aDir2d.IsParallel(gp::DY2d(), Precision::Angular()))
+  {
+    // Vertical line. U = const.
+    theIsU = Standard_True;
+    theParam = aLoc2d.X();
+    theIsForward = aDir2d.Dot(gp::DY2d()) > 0.0;
+    return Standard_True;
+  }
+
+  return Standard_False;
+}
+
+#include <GeomLib.hxx>
+
+//=============================================================================
+//function : buildC3dOnIsoLine
+//purpose  :
+//=============================================================================
+Standard_Boolean Approx_CurveOnSurface::buildC3dOnIsoLine(const Handle(Adaptor2d_HCurve2d) theC2D,
+                                                          const Standard_Boolean           theIsU,
+                                                          const Standard_Real              theParam,
+                                                          const Standard_Boolean           theIsForward)
+{
+  // Convert adapter to the appropriate type.
+  Handle(GeomAdaptor_HSurface) aGeomAdapter = Handle(GeomAdaptor_HSurface)::DownCast(mySurf);
+  if (aGeomAdapter.IsNull())
+    return Standard_False;
+
+  if (mySurf->GetType() == GeomAbs_Sphere)
+    return Standard_False;
+
+  // Extract isoline
+  Handle(Geom_Surface) aSurf = aGeomAdapter->ChangeSurface().Surface();
+  Handle(Geom_Curve) aC3d;
+
+  gp_Pnt2d aF2d = theC2D->Value(theC2D->FirstParameter());
+  gp_Pnt2d aL2d = theC2D->Value(theC2D->LastParameter());
+
+  if (theIsU)
+  {
+    aC3d = aSurf->UIso(theParam);
+    aC3d = new Geom_TrimmedCurve(aC3d, aF2d.Y(), aL2d.Y());
+  }
+  else
+  {
+    aC3d = aSurf->VIso(theParam);
+    aC3d = new Geom_TrimmedCurve(aC3d, aF2d.X(), aL2d.X());
+  }
+
+  // Convert arbitrary curve type to the b-spline.
+  myCurve3d = GeomConvert::CurveToBSplineCurve(aC3d, Convert_QuasiAngular);
+  if (!theIsForward)
+    myCurve3d->Reverse();
+
+  // Rebuild parameterization for the 3d curve to have the same parameterization with
+  // a two-dimensional curve. 
+  TColStd_Array1OfReal aKnots = myCurve3d->Knots();
+  BSplCLib::Reparametrize(theC2D->FirstParameter(), theC2D->LastParameter(), aKnots);
+  myCurve3d->SetKnots(aKnots);
+
+  // Evaluate error.
+  myError3d = 0.0;
+
+  const Standard_Real aParF = myFirst;
+  const Standard_Real aParL = myLast;
+  const Standard_Integer aNbPnt = 23;
+  for(Standard_Integer anIdx = 0; anIdx <= aNbPnt; ++anIdx)
+  {
+    const Standard_Real aPar = aParF + ((aParL - aParF) * anIdx) / aNbPnt;
+
+    const gp_Pnt2d aPnt2d = theC2D->Value(aPar);
+
+    const gp_Pnt aPntC3D = myCurve3d->Value(aPar);
+    const gp_Pnt aPntC2D = mySurf->Value(aPnt2d.X(), aPnt2d.Y());
+
+    const Standard_Real aSqDeviation = aPntC3D.SquareDistance(aPntC2D);
+    myError3d = Max(aSqDeviation, myError3d);
+  }
+
+  myError3d = Sqrt(myError3d);
+
+  // Target tolerance is not obtained. This situation happens for isolines on the sphere.
+  // OCCT is unable to convert it keeping original parameterization, while the geometric
+  // form of the result is entirely identical. In that case, it is better to utilize
+  // a general-purpose approach. 
+  if (myError3d > myTol)
+    return Standard_False;
+
+  return Standard_True;
+}
index ce5cf4b..b14b41c 100644 (file)
@@ -40,9 +40,22 @@ public:
 
   DEFINE_STANDARD_ALLOC
 
-  
+  //! This constructor calls perform method. This constructor is deprecated.
+  Standard_DEPRECATED("This constructor is deprecated. Use other constructor and perform method instead.")
   Standard_EXPORT Approx_CurveOnSurface(const Handle(Adaptor2d_HCurve2d)& C2D, const Handle(Adaptor3d_HSurface)& Surf, const Standard_Real First, const Standard_Real Last, const Standard_Real Tol, const GeomAbs_Shape Continuity, const Standard_Integer MaxDegree, const Standard_Integer MaxSegments, const Standard_Boolean Only3d = Standard_False, const Standard_Boolean Only2d = Standard_False);
-  
+
+  //! This constructor does not call perform method.
+  //! @param theC2D   2D Curve to be approximated in 3D.
+  //! @param theSurf  Surface where 2D curve is located.
+  //! @param theFirst First parameter of resulting curve.
+  //! @param theFirst Last parameter of resulting curve.
+  //! @param theTol   Computation tolerance.
+  Standard_EXPORT Approx_CurveOnSurface(const Handle(Adaptor2d_HCurve2d)& theC2D,
+                                        const Handle(Adaptor3d_HSurface)& theSurf,
+                                        const Standard_Real               theFirst,
+                                        const Standard_Real               theLast,
+                                        const Standard_Real               theTol);
+
   Standard_EXPORT Standard_Boolean IsDone() const;
   
   Standard_EXPORT Standard_Boolean HasResult() const;
@@ -59,18 +72,64 @@ public:
   //! 2d Curve
   Standard_EXPORT Standard_Real MaxError2dV() const;
 
-
-
+  //! Constructs the 3d curve. Input parameters are ignored when the input curve is
+  //! U-isoline or V-isoline.
+  //! @param theMaxSegments Maximal number of segments in the resulting spline.
+  //! @param theMaxDegree   Maximal degree of the result.
+  //! @param theContinuity  Resulting continuity.
+  //! @param theOnly3d      Determines building only 3D curve.
+  //! @param theOnly2d      Determines building only 2D curve.
+  Standard_EXPORT void Perform(const Standard_Integer theMaxSegments, 
+                               const Standard_Integer theMaxDegree, 
+                               const GeomAbs_Shape    theContinuity,
+                               const Standard_Boolean theOnly3d = Standard_False,
+                               const Standard_Boolean theOnly2d = Standard_False);
 
 protected:
 
+  //! Checks whether the 2d curve is a isoline. It can be represented by b-spline, bezier,
+  //! or geometric line. This line should have natural parameterization.
+  //! @param theC2D       Trimmed curve to be checked.
+  //! @param theIsU       Flag indicating that line is u const.
+  //! @param theParam     Line parameter.
+  //! @param theIsForward Flag indicating forward parameterization on a isoline.
+  //! @return Standard_True when 2d curve is a line and Standard_False otherwise.
+  Standard_Boolean isIsoLine(const Handle(Adaptor2d_HCurve2d) theC2D,
+                             Standard_Boolean&                theIsU,
+                             Standard_Real&                   theParam,
+                             Standard_Boolean&                theIsForward) const;
+
+  //! Builds 3D curve for a isoline. This method takes corresponding isoline from
+  //! the input surface.
+  //! @param theC2D   Trimmed curve to be approximated.
+  //! @param theIsU   Flag indicating that line is u const.
+  //! @param theParam Line parameter.
+  //! @param theIsForward Flag indicating forward parameterization on a isoline.
+  //! @return Standard_True when 3d curve is built and Standard_False otherwise.
+  Standard_Boolean buildC3dOnIsoLine(const Handle(Adaptor2d_HCurve2d) theC2D,
+                                     const Standard_Boolean           theIsU,
+                                     const Standard_Real              theParam,
+                                     const Standard_Boolean           theIsForward);
 
+private:
+  Approx_CurveOnSurface& operator= (const Approx_CurveOnSurface&);
 
+private:
 
+  //! Input curve.
+  const Handle(Adaptor2d_HCurve2d) myC2D;
 
-private:
+  //! Input surface.
+  const Handle(Adaptor3d_HSurface) mySurf;
+
+  //! First parameter of the result.
+  const Standard_Real myFirst;
 
+  //! Last parameter of the result.
+  const Standard_Real myLast;
 
+  //! Tolerance.
+  Standard_Real myTol;
 
   Handle(Geom2d_BSplineCurve) myCurve2d;
   Handle(Geom_BSplineCurve) myCurve3d;
index 69cf292..2899cf6 100644 (file)
@@ -363,9 +363,8 @@ void BRepAlgo_NormalProjection::SetDefaultParams()
 #ifdef OCCT_DEBUG_CHRONO
            InitChron(chr_approx);
 #endif
-           Approx_CurveOnSurface appr(HPCur, hsur, Udeb, Ufin, myTol3d, 
-                                      myContinuity, myMaxDegree, myMaxSeg, 
-                                      Only3d, Only2d);
+           Approx_CurveOnSurface appr(HPCur, hsur, Udeb, Ufin, myTol3d);
+            appr.Perform(myMaxSeg, myMaxDegree, myContinuity, Only3d, Only2d);
 #ifdef OCCT_DEBUG_CHRONO
            ResultChron(chr_approx,t_approx);
            approx_count++;
index 1f2553b..0169c81 100644 (file)
@@ -330,8 +330,9 @@ static Standard_Boolean SameParameter(TopoDS_Edge&    E,
   if (!HasPCurves(E))
     {
       Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( Pcurv );
-      Approx_CurveOnSurface AppCurve(HC2d, S, HC2d->FirstParameter(), HC2d->LastParameter(),
-                                    Precision::Confusion(), GeomAbs_C1, 10, 10, Standard_True);
+      Approx_CurveOnSurface AppCurve(HC2d, S, HC2d->FirstParameter(), HC2d->LastParameter(), 
+                                     Precision::Confusion());
+      AppCurve.Perform(10, 10, GeomAbs_C1, Standard_True);
       if (AppCurve.IsDone() && AppCurve.HasResult())
        {
          C3d = AppCurve.Curve3d();
index 27ec179..d31e0c8 100644 (file)
@@ -2169,9 +2169,8 @@ static Standard_Real SmartParameter(Draft_EdgeInfo& Einf,
   Standard_Real Udeb, Ufin;
   ProjCurve.Bounds(1, Udeb, Ufin);
   Standard_Integer MaxSeg = 20 + HProjector->NbIntervals(GeomAbs_C3);
-  Approx_CurveOnSurface appr( HProjector, hsur2, Udeb, Ufin, Tol,
-    GeomAbs_C1, 10, MaxSeg, 
-    Standard_False, Standard_False );
+  Approx_CurveOnSurface appr(HProjector, hsur2, Udeb, Ufin, Tol);
+  appr.Perform(MaxSeg, 10, GeomAbs_C1, Standard_False, Standard_False);
   Einf.ChangeSecondPC() = appr.Curve2d();
   Einf.ChangeGeometry() = appr.Curve3d();
   Einf.SetNewGeometry( Standard_True );
index 5cac732..12a1dbc 100644 (file)
@@ -1031,9 +1031,8 @@ void GeomInt_IntSS::TreatRLine(const Handle(IntPatch_RLine)& theRL,
   //approximation of curve on surface.
   Standard_Integer aMaxDeg = 8;
   Standard_Integer aMaxSeg = 1000;
-  Approx_CurveOnSurface anApp(anAHC2d, aGAHS, tf, tl, Precision::Confusion(),
-                              GeomAbs_C1, aMaxDeg, aMaxSeg, 
-                              Standard_True, Standard_False);
+  Approx_CurveOnSurface anApp(anAHC2d, aGAHS, tf, tl, Precision::Confusion());
+  anApp.Perform(aMaxSeg, aMaxDeg, GeomAbs_C1, Standard_True, Standard_False);
   if(!anApp.HasResult())
     return;
 
index 4db59a6..6d730ef 100644 (file)
@@ -300,10 +300,9 @@ Handle(Geom2d_Curve)  GeomPlate_BuildPlateSurface::ProjectCurve(const Handle(Ada
    Projector.Bounds(1, Udeb, Ufin);
    
    MaxSeg = 20 + HProjector->NbIntervals(GeomAbs_C3);
-   Approx_CurveOnSurface appr(HProjector, hsur, Udeb, Ufin, myTol3d,
-                             Continuity, MaxDegree, MaxSeg, 
-                             Standard_False, Standard_True);
-   
+   Approx_CurveOnSurface appr(HProjector, hsur, Udeb, Ufin, myTol3d);
+   appr.Perform(MaxSeg, MaxDegree, Continuity, Standard_False, Standard_True);
+
    Curve2d = appr.Curve2d();
  }
 #if DRAW
index d8c61cd..4dd52f1 100644 (file)
@@ -340,8 +340,8 @@ Handle(Geom_Curve) GeomProjLib::Project( const Handle(Geom_Curve)& C,
     Standard_Real f,l;
     Proj.Bounds(1,f,l);
     Handle(Adaptor2d_HCurve2d) HC2d = Proj.Trim(f,l,TolU);
-    Approx_CurveOnSurface Approx(HC2d, HS, f, l, Tol,
-                                GeomAbs_C2,14,16,Standard_True);
+    Approx_CurveOnSurface Approx(HC2d, HS, f, l, Tol);
+    Approx.Perform(16, 14, GeomAbs_C2, Standard_True);
 
     // ici, on a toujours un type BSpline.
     if (Approx.IsDone() && Approx.HasResult())
index 9417582..8feb96c 100644 (file)
@@ -367,9 +367,8 @@ static Standard_Integer gproject(Draw_Interpretor& di, Standard_Integer n, const
         return 0;
         }
       else {
-        Approx_CurveOnSurface appr(HPCur, hsur, Udeb, Ufin, myTol3d, 
-                                  myContinuity, myMaxDegree, myMaxSeg, 
-                                  Only3d, Only2d);
+        Approx_CurveOnSurface appr(HPCur, hsur, Udeb, Ufin, myTol3d);
+        appr.Perform(myMaxSeg, myMaxDegree, myContinuity, Only3d, Only2d);
         if(!Only3d) {
          PCur2d = appr.Curve2d();
          di << " Error in 2d is " << appr.MaxError2dU()
index a9e411f..74a90ba 100644 (file)
@@ -1552,9 +1552,8 @@ static Standard_Integer approxcurveonsurf(Draw_Interpretor& di, Standard_Integer
   Handle(Geom2dAdaptor_HCurve) A2d = new (Geom2dAdaptor_HCurve)(curve2d);
   Handle(GeomAdaptor_HSurface) AS = new (GeomAdaptor_HSurface)(Surf);
 
-  Approx_CurveOnSurface App(A2d, AS, A2d->FirstParameter(), A2d->LastParameter(),
-                           Tol,  Continuity,  MaxDeg, MaxSeg,
-                           Standard_True, Standard_False);
+  Approx_CurveOnSurface App(A2d, AS, A2d->FirstParameter(), A2d->LastParameter(), Tol);
+  App.Perform(MaxSeg, MaxDeg, Continuity, Standard_True, Standard_False);
 
   if(App.HasResult()) {
     Handle(Geom_BSplineCurve) BSCurve = App.Curve3d(); 
index 136c1cf..2d5b2a8 100644 (file)
@@ -685,9 +685,8 @@ void ProjLib_ProjectedCurve::Perform(const Handle(Adaptor3d_HCurve)& C)
           MaxSeg = myMaxSegments;
         }
 
-        Approx_CurveOnSurface appr(HProjector, mySurface, Udeb, Ufin, 
-                                   myTolerance, Continuity, MaxDegree, MaxSeg, 
-                                   Only3d, Only2d);
+        Approx_CurveOnSurface appr(HProjector, mySurface, Udeb, Ufin, myTolerance);
+        appr.Perform(MaxSeg, MaxDegree, Continuity, Only3d, Only2d);
 
         Handle(Geom2d_BSplineCurve) aRes = appr.Curve2d();
 
diff --git a/tests/bugs/moddata_3/bug30932 b/tests/bugs/moddata_3/bug30932
new file mode 100644 (file)
index 0000000..9e362ca
--- /dev/null
@@ -0,0 +1,20 @@
+puts "================"
+puts "0030932: Modeling Algorithms - Invalid result on 2d curve on surface approximation"
+puts "================"
+puts ""
+
+# Prepare data.
+restore [locate_data_file bug30932_c2d] c2d
+restore [locate_data_file bug30932_sur] sur
+
+# Approximate.
+approxcurveonsurf res c2d sur
+
+# Length check.
+checklength res -l 150.02782767924231
+
+# Visual check.
+axo;
+don res;
+fit;
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png