0027079: Bad approximation of intersection curves with variable curvature
authorjgv <jgv@opencascade.com>
Mon, 20 Mar 2017 11:43:32 +0000 (14:43 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 16 Jun 2017 11:24:53 +0000 (14:24 +0300)
    1. Method Approx_ComputeLine::Perform is modified: now it contains also recursive calls after new line computation made by new method ApproxInt_MultiLine::MakeMLOneMorePoint.
    2. New method MakeMLOneMorePoint is added to ApproxInt_MultiLine: it builds new sub-line as a part of main line with new point added into the middle of the longest interval between existing points.
    3. Method ShapeConstruct_ProjectCurveOnSurface::ApproxPCurve is modified to avoid regressions: now it takes care of the set of initial points to be enough close to each other so that an interval between two adjacent points is less than half-period of the surface.
    4. Modification in ShapeConstruct_ProjectCurveOnSurface: correction of pcurves of edges which extremities are in the singularities of surface.

29 files changed:
dox/dev_guides/upgrade/upgrade.md
src/AppDef/AppDef_Compute.hxx
src/AppDef/AppDef_MyLineTool.cxx
src/AppDef/AppDef_MyLineTool.hxx
src/Approx/Approx_ComputeLine.gxx
src/ApproxInt/ApproxInt_Approx.gxx
src/ApproxInt/ApproxInt_ImpPrmSvSurfaces.gxx
src/ApproxInt/ApproxInt_MultiLine.gxx
src/ApproxInt/ApproxInt_MultiLineTool.lxx
src/ApproxInt/ApproxInt_PrmPrmSvSurfaces.gxx
src/ApproxInt/ApproxInt_SvSurfaces.hxx
src/BRepApprox/BRepApprox_TheComputeLineBezierOfApprox.hxx
src/BRepApprox/BRepApprox_TheImpPrmSvSurfacesOfApprox.hxx
src/BRepApprox/BRepApprox_TheMultiLineOfApprox.hxx
src/BRepApprox/BRepApprox_TheMultiLineToolOfApprox.hxx
src/BRepApprox/BRepApprox_ThePrmPrmSvSurfacesOfApprox.hxx
src/GeomInt/GeomInt_TheComputeLineBezierOfWLApprox.hxx
src/GeomInt/GeomInt_TheImpPrmSvSurfacesOfWLApprox.hxx
src/GeomInt/GeomInt_TheMultiLineOfWLApprox.hxx
src/GeomInt/GeomInt_TheMultiLineToolOfWLApprox.hxx
src/GeomInt/GeomInt_ThePrmPrmSvSurfacesOfWLApprox.hxx
src/LocOpe/LocOpe_WiresOnShape.cxx
src/ShapeAnalysis/ShapeAnalysis_Surface.cxx
src/ShapeAnalysis/ShapeAnalysis_Surface.hxx
src/ShapeConstruct/ShapeConstruct_ProjectCurveOnSurface.cxx
src/ShapeConstruct/ShapeConstruct_ProjectCurveOnSurface.hxx
src/ShapeFix/ShapeFix_Edge.cxx
tests/bugs/modalg_6/bug27079_1 [new file with mode: 0644]
tests/bugs/modalg_6/bug27079_2 [new file with mode: 0644]

index 6c317a4..35d1f6b 100644 (file)
@@ -1143,6 +1143,10 @@ The following obsolete features have been removed:
   - *NextStartingPointsResearch2*;
   - *TriangleComparePSP*;
   - *StartPointsCalcul*.
+* The method PerformAdvanced of the *ShapeConstruct_ProjectCurveOnSurface* class has been removed as unused.
+* The method Perform of the *ShapeConstruct_ProjectCurveOnSurface* class is modified:
+  - input arguments *continuity*, *maxdeg*, *nbinterval* have been removed as unused;
+  - input arguments *TolFirst*, *TolLast* have been added at the end of arguments' list.
 
 @subsection upgrade_occt720_correction_of_Offset_API Corrections in BRepOffset API
 
index a65bbd3..bf37a6f 100644 (file)
@@ -124,7 +124,6 @@ public:
 
 
 
-
 protected:
 
 
@@ -135,7 +134,13 @@ private:
 
   
   //! is internally used in the algorithm.
-  Standard_EXPORT Standard_Boolean Compute (const AppDef_MultiLine& Line, const Standard_Integer fpt, const Standard_Integer lpt, math_Vector& Para, Standard_Real& TheTol3d, Standard_Real& TheTol2d);
+  Standard_EXPORT Standard_Boolean Compute (const AppDef_MultiLine& Line,
+                                            const Standard_Integer fpt,
+                                            const Standard_Integer lpt,
+                                            math_Vector& Para,
+                                            Standard_Real& TheTol3d,
+                                            Standard_Real& TheTol2d,
+                                            Standard_Integer& indbad);
   
   //! is internally used in the algorithm.
   Standard_EXPORT Standard_Boolean ComputeCurve (const AppDef_MultiLine& Line, const Standard_Integer firspt, const Standard_Integer lastpt);
@@ -176,6 +181,7 @@ private:
   AppParCurves_Constraint myfirstC;
   AppParCurves_Constraint mylastC;
   Standard_Integer myMultiLineNb;
+  Standard_Integer myNbPlusOnePoint;
   Standard_Boolean myIsClear;
 
 
index 1e3aa57..93827b1 100644 (file)
@@ -59,9 +59,11 @@ void AppDef_MyLineTool::Value(const AppDef_MultiLine& ML,
                              TColgp_Array1OfPnt2d& tabPt2d)
 {
   AppDef_MultiPointConstraint MPC = ML.Value(MPointIndex);
-  Standard_Integer nbp2d = MPC.NbPoints2d(), low = tabPt2d.Lower();
+  Standard_Integer nbp3d = MPC.NbPoints();
+  Standard_Integer nbp2d = MPC.NbPoints2d();
+  Standard_Integer low = tabPt2d.Lower();
   for (Standard_Integer i = 1; i <= nbp2d; i++) {
-    tabPt2d(i+low-1) = MPC.Point2d(i);
+    tabPt2d(i+low-1) = MPC.Point2d(nbp3d+i);
   }
 }
 
@@ -102,10 +104,12 @@ Standard_Boolean AppDef_MyLineTool::Tangency(const AppDef_MultiLine& ML,
                                 TColgp_Array1OfVec2d& tabV2d)
 {
   AppDef_MultiPointConstraint MPC = ML.Value(MPointIndex);
-  if (MPC.IsTangencyPoint()) {
+  if (MPC.IsTangencyPoint())
+  {
+    Standard_Integer nbp3d = MPC.NbPoints();
     Standard_Integer nbp2d = MPC.NbPoints2d(), low = tabV2d.Lower();
     for (Standard_Integer i = 1; i <= nbp2d; i++) {
-      tabV2d(i+low-1) = MPC.Tang2d(i);
+      tabV2d(i+low-1) = MPC.Tang2d(nbp3d+i);
     }
     return Standard_True;
   }
@@ -142,6 +146,15 @@ AppDef_MultiLine& AppDef_MyLineTool::MakeMLBetween(const AppDef_MultiLine&,
   return *((AppDef_MultiLine*) 0);
 }
 
+Standard_Boolean AppDef_MyLineTool::MakeMLOneMorePoint(const AppDef_MultiLine& ,
+                                                       const Standard_Integer,
+                                                       const Standard_Integer,
+                                                       const Standard_Integer,
+                                                       AppDef_MultiLine&)
+{
+  return Standard_False;
+}
+
 Approx_Status AppDef_MyLineTool::WhatStatus(const AppDef_MultiLine&,
                                            const Standard_Integer,
                                            const Standard_Integer)
@@ -170,10 +183,12 @@ Standard_Boolean AppDef_MyLineTool::Curvature(const AppDef_MultiLine& ML,
                                 TColgp_Array1OfVec2d& tabV2d)
 {
   AppDef_MultiPointConstraint MPC = ML.Value(MPointIndex);
-  if (MPC.IsCurvaturePoint()) {
+  if (MPC.IsCurvaturePoint())
+  {
+    Standard_Integer nbp3d = MPC.NbPoints();
     Standard_Integer nbp2d = MPC.NbPoints2d(), low = tabV2d.Lower();
     for (Standard_Integer i = 1; i <= nbp2d; i++) {
-      tabV2d(i+low-1) = MPC.Curv2d(i);
+      tabV2d(i+low-1) = MPC.Curv2d(nbp3d+i);
     }
     return Standard_True;
   }
index 5e6881f..7f69177 100644 (file)
@@ -94,8 +94,18 @@ public:
   
   //! Is never called in the algorithms.
   //! Nothing is done.
-  Standard_EXPORT static AppDef_MultiLine& MakeMLBetween (const AppDef_MultiLine& ML, const Standard_Integer I1, const Standard_Integer I2, const Standard_Integer NbPMin);
+  Standard_EXPORT static AppDef_MultiLine& MakeMLBetween (const AppDef_MultiLine& ML,
+                                                          const Standard_Integer I1,
+                                                          const Standard_Integer I2,
+                                                          const Standard_Integer NbPMin);
 
+  //! Is never called in the algorithms.
+  //! Nothing is done.
+  Standard_EXPORT static  Standard_Boolean  MakeMLOneMorePoint (const AppDef_MultiLine& ML,
+                                                                const Standard_Integer I1,
+                                                                const Standard_Integer I2,
+                                                                const Standard_Integer indbad,
+                                                                AppDef_MultiLine& OtherLine);
 
 
 
index edc6086..229ac6e 100644 (file)
@@ -45,6 +45,7 @@ static Standard_Boolean mydebug = Standard_False;
 #include <Draw.hxx>
 #include <Draw_Appli.hxx>
 #endif
+
 static void DUMP(const MultiLine& Line)
 {
   Standard_Integer i, j, nbP2d, nbP3d, firstP, lastP;
@@ -82,7 +83,6 @@ static void DUMP(const MultiLine& Line)
 
 }
 
-
 static void DUMP(const AppParCurves_MultiCurve& C) {
   static Standard_Integer nbappel = 0;
   Standard_Integer i;
@@ -123,8 +123,258 @@ static void DUMP(const AppParCurves_MultiCurve& C) {
 #endif
 }
 
+#endif
+
+static Standard_Boolean CheckMultiCurve(const AppParCurves_MultiCurve& theMultiCurve,
+                                        const MultiLine& theLine,
+                                        const Standard_Integer theIndfirst,
+                                        const Standard_Integer theIndlast,
+                                        Standard_Integer& theIndbad)
+{
+  const Standard_Integer nbp3d = LineTool::NbP3d(theLine);
+  const Standard_Integer nbp2d = LineTool::NbP2d(theLine);
+  
+  if (nbp3d > 1) //only simple cases are analysed
+    return Standard_True;
+
+  const Standard_Real MinScalProd = -0.9;
+  const Standard_Real SqTol3d = Precision::SquareConfusion();
 
+  theIndbad = 0;
+  Standard_Integer indbads [4];
+  indbads[1] = indbads[2] = indbads[3] = 0;
+  
+  Standard_Integer NbCur = theMultiCurve.NbCurves();
+  Standard_Boolean LoopFound = Standard_False;
+
+  Standard_Integer aNbP3d = Max(nbp3d, 1);
+  Standard_Integer aNbP2d = Max(nbp2d, 1);
+  
+  TColgp_Array1OfPnt tabP(1, aNbP3d);
+  TColgp_Array1OfPnt2d tabP2d(1, aNbP2d);
+  
+#ifdef DRAW
+  char* name = new char[100];
+  Standard_Integer nbbc = 1;
+  Standard_Integer indc = 1;
 #endif
+  if (theMultiCurve.Dimension(1) == 3 /*myNbP3d == 1*/)
+  {
+    TColgp_Array1OfPnt aPoles(1, theMultiCurve.NbPoles());
+    theMultiCurve.Curve(1, aPoles);
+#ifdef DRAW
+    Handle(Geom_Curve) theBezier = new Geom_BezierCurve(aPoles);
+    sprintf(name, "bc3d_%d_%d", indc, nbbc);
+    DrawTrSurf::Set(name, theBezier);
+#endif
+    gp_Vec FirstVec, SecondVec;
+    Standard_Integer indp = 2;
+    while (indp <= aPoles.Upper())
+    {
+      FirstVec = gp_Vec(aPoles(1), aPoles(indp++));
+      Standard_Real aLength = FirstVec.Magnitude();
+      if (aLength > gp::Resolution())
+      {
+        FirstVec /= aLength;
+        break;
+      }
+    }
+    gp_Pnt MidPnt = aPoles(indp-1);
+    //for (Standard_Integer k = 3; k <= aPoles.Upper(); k++)
+    while (indp <= aPoles.Upper())
+    {
+      SecondVec = gp_Vec(MidPnt, aPoles(indp));
+      Standard_Real aLength = SecondVec.Magnitude();
+      if (aLength <= gp::Resolution())
+      {
+        indp++;
+        continue;
+      }
+      SecondVec /= aLength;
+      Standard_Real ScalProd = FirstVec * SecondVec;
+      if (ScalProd < MinScalProd)
+      {
+#ifdef DRAW
+        cout<<"ScalProd("<<indp-2<<","<<indp-1<<")-("<<indp-1<<","<<indp<<") = "<<ScalProd<<endl;
+#endif
+        LoopFound = Standard_True;
+        break;
+      }
+      FirstVec = SecondVec;
+      MidPnt = aPoles(indp);
+      indp++;
+    }
+    //Check: may be it is a real loop
+    if (LoopFound)
+    {
+      for (Standard_Integer FirstInd = theIndfirst;
+           FirstInd <= theIndlast - 2; FirstInd++)
+      {
+        LineTool::Value(theLine, FirstInd, tabP);
+        gp_Pnt FirstPnt = tabP(1);
+        for (Standard_Integer k = FirstInd+1; k < theIndlast; k++)
+        {
+          LineTool::Value(theLine, k, tabP);
+          gp_Pnt Pnt1 = tabP(1);
+          LineTool::Value(theLine, k+1, tabP);
+          gp_Pnt Pnt2 = tabP(1);
+          if (FirstPnt.SquareDistance(Pnt1) <= SqTol3d ||
+              FirstPnt.SquareDistance(Pnt2) <= SqTol3d)
+          {
+            LoopFound = Standard_False;
+            break;
+          }
+          gp_Vec Vec1(FirstPnt, Pnt1);
+          Vec1.Normalize();
+          gp_Vec Vec2(FirstPnt, Pnt2);
+          Vec2.Normalize();
+          Standard_Real ScalProd = Vec1 * Vec2;
+          if (ScalProd < MinScalProd)
+          {
+            LoopFound = Standard_False;
+            break;
+          }
+        }
+        if (LoopFound == Standard_False)
+          break;
+      }
+    }
+    if (LoopFound)
+    {
+      //search <indbad>
+      Standard_Real MaxSqDist = 0.;
+      for (Standard_Integer k = theIndfirst+1; k <= theIndlast; k++)
+      {
+        LineTool::Value(theLine, k-1, tabP);
+        gp_Pnt PrevPnt = tabP(1);
+        LineTool::Value(theLine, k, tabP);
+        gp_Pnt CurPnt  = tabP(1);
+        Standard_Real aSqDist = PrevPnt.SquareDistance(CurPnt);
+        if (aSqDist > MaxSqDist)
+        {
+          MaxSqDist = aSqDist;
+          indbads[1] = k;
+        }
+      }
+      for (Standard_Integer indcur = 2; indcur <= NbCur; indcur++)
+      {
+        MaxSqDist = 0.;
+        for (Standard_Integer k = theIndfirst+1; k <= theIndlast; k++)
+        {
+          LineTool::Value(theLine, k-1, tabP2d);
+          gp_Pnt2d PrevPnt = tabP2d(indcur-1);
+          LineTool::Value(theLine, k, tabP2d);
+          gp_Pnt2d CurPnt  = tabP2d(indcur-1);
+          Standard_Real aSqDist = PrevPnt.SquareDistance(CurPnt);
+          if (aSqDist > MaxSqDist)
+          {
+            MaxSqDist = aSqDist;
+            indbads[indcur] = k;
+          }
+        }
+      }
+    }
+  } //if (myNbP3d == 1)
+  else //2d case
+  {
+    TColgp_Array1OfPnt2d aPoles2d(1, theMultiCurve.NbPoles());
+    theMultiCurve.Curve(1, aPoles2d);
+#ifdef DRAW
+    Handle(Geom2d_Curve) theBezier2d = new Geom2d_BezierCurve(aPoles2d);
+    sprintf(name, "bc2d_%d_%d", indc, nbbc);
+    DrawTrSurf::Set(name, theBezier2d);
+#endif
+    gp_Vec2d FirstVec, SecondVec;
+    FirstVec = gp_Vec2d(aPoles2d(1), aPoles2d(2));
+    FirstVec.Normalize();
+    gp_Pnt2d MidPnt = aPoles2d(2);
+    for (Standard_Integer k = 3; k <= aPoles2d.Upper(); k++)
+    {
+      SecondVec = gp_Vec2d(MidPnt, aPoles2d(k));
+      SecondVec.Normalize();
+      Standard_Real ScalProd = FirstVec * SecondVec;
+      if (ScalProd < MinScalProd)
+      {
+#ifdef DRAW
+        cout<<"ScalProd("<<k-2<<","<<k-1<<")-("<<k-1<<","<<k<<") = "<<ScalProd<<endl;
+#endif
+        LoopFound = Standard_True;
+        break;
+      }
+      FirstVec = SecondVec;
+      MidPnt = aPoles2d(k);
+    }
+    //Check: may be it is a real loop
+    if (LoopFound)
+    {
+      for (Standard_Integer FirstInd = theIndfirst;
+           FirstInd <= theIndlast - 2; FirstInd++)
+      {
+        LineTool::Value(theLine, FirstInd, tabP2d);
+        gp_Pnt2d FirstPnt = tabP2d(1);
+        for (Standard_Integer k = FirstInd+1; k < theIndlast; k++)
+        {
+          LineTool::Value(theLine, k, tabP2d);
+          gp_Pnt2d Pnt1 = tabP2d(1);
+          LineTool::Value(theLine, k+1, tabP2d);
+          gp_Pnt2d Pnt2 = tabP2d(1);
+          if (FirstPnt.SquareDistance(Pnt1) <= SqTol3d ||
+              FirstPnt.SquareDistance(Pnt2) <= SqTol3d)
+          {
+            LoopFound = Standard_False;
+            break;
+          }
+          gp_Vec2d Vec1(FirstPnt, Pnt1);
+          Vec1.Normalize();
+          gp_Vec2d Vec2(FirstPnt, Pnt2);
+          Vec2.Normalize();
+          Standard_Real ScalProd = Vec1 * Vec2;
+          if (ScalProd < MinScalProd)
+          {
+            LoopFound = Standard_False;
+            break;
+          }
+        }
+        if (LoopFound == Standard_False)
+          break;
+      }
+    }
+    if (LoopFound)
+    {
+      //search <indbad>
+      for (Standard_Integer indcur = 1; indcur <= NbCur; indcur++)
+      {
+        Standard_Real MaxSqDist = 0.;
+        for (Standard_Integer k = theIndfirst+1; k <= theIndlast; k++)
+        {
+          LineTool::Value(theLine, k-1, tabP2d);
+          gp_Pnt2d PrevPnt = tabP2d(indcur);
+          LineTool::Value(theLine, k, tabP2d);
+          gp_Pnt2d CurPnt  = tabP2d(indcur);
+          Standard_Real aSqDist = PrevPnt.SquareDistance(CurPnt);
+          if (aSqDist > MaxSqDist)
+          {
+            MaxSqDist = aSqDist;
+            indbads[indcur] = k;
+          }
+        }
+      }
+    }
+  }
+
+  //Define <indbad>
+  if (indbads[1] != 0 && indbads[2] != 0)
+  {
+    if (indbads[1] != indbads[2])
+      LoopFound = Standard_False;
+    else if (indbads[3] != 0 && indbads[1] != indbads[3])
+      LoopFound = Standard_False;
+  }
+  if (LoopFound)
+    theIndbad = indbads[1];
+  
+  return (!LoopFound);
+}
 
 void Approx_ComputeLine::FirstTangencyVector(const MultiLine&       Line,
                                             const Standard_Integer index,
@@ -400,6 +650,7 @@ Approx_ComputeLine::Approx_ComputeLine
                     const Standard_Boolean cutting,
                     const Standard_Boolean Squares)
 : myMultiLineNb (0),
+  myNbPlusOnePoint (0),
   myIsClear (Standard_False)
 {
   myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(), 
@@ -433,6 +684,7 @@ Approx_ComputeLine::Approx_ComputeLine
                     const Standard_Boolean cutting,
                     const Standard_Boolean Squares)
 : myMultiLineNb (0),
+  myNbPlusOnePoint (0),
   myIsClear (Standard_False)
 {
   myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(), 
@@ -464,6 +716,7 @@ Approx_ComputeLine::Approx_ComputeLine
                     const Approx_ParametrizationType parametrization,
                     const Standard_Boolean Squares)
 : myMultiLineNb (0),
+  myNbPlusOnePoint (0),
   myIsClear (Standard_False)
 {
   myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
@@ -492,6 +745,7 @@ Approx_ComputeLine::Approx_ComputeLine
                     const Approx_ParametrizationType parametrization,
                     const Standard_Boolean Squares)
 : myMultiLineNb (0),
+  myNbPlusOnePoint (0),
   myIsClear (Standard_False)
 {
   myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
@@ -524,6 +778,7 @@ void Approx_ComputeLine::Perform(const MultiLine& Line)
     Tolers3d.Clear();
     Tolers2d.Clear();
     myMultiLineNb = 0;
+    //myNbPlusOnePoint = 0;
   }
   else myIsClear = Standard_False;
 
@@ -558,7 +813,22 @@ void Approx_ComputeLine::Perform(const MultiLine& Line)
       }
     }
     TheMultiCurve = AppParCurves_MultiCurve();
-    alldone = Compute(Line, myfirstpt, mylastpt, TheParam, thetol3d, thetol2d);
+    MultiLine anOtherLine0;
+    Standard_Boolean isOtherLine0Made = Standard_False;
+    Standard_Integer indbad = 0;
+    alldone = Compute(Line, myfirstpt, mylastpt, TheParam, thetol3d, thetol2d, indbad);
+    if (indbad != 0)
+    {
+      isOtherLine0Made = LineTool::MakeMLOneMorePoint(Line, myfirstpt, mylastpt, indbad, anOtherLine0);
+    }
+    if (isOtherLine0Made)
+    {
+      myIsClear = Standard_True;
+      //++myMultiLineNb;
+      myNbPlusOnePoint++;
+      Perform(anOtherLine0);
+      alldone = Standard_True;
+    }
     if(!alldone && TheMultiCurve.NbCurves() > 0) {
 #ifdef OCCT_DEBUG
       if (mydebug) DUMP(TheMultiCurve);
@@ -566,10 +836,13 @@ void Approx_ComputeLine::Perform(const MultiLine& Line)
       myMultiCurves.Append(TheMultiCurve);
       Tolers3d.Append(currenttol3d);
       Tolers2d.Append(currenttol2d);
-      Handle(TColStd_HArray1OfReal) ThePar = new TColStd_HArray1OfReal(myfirstpt, mylastpt);
-      for (i = myfirstpt; i <= mylastpt; i++) {
-       ThePar->SetValue(i, myParameters->Value(i));
-      }
+      Standard_Integer mylen = mylastpt-myfirstpt+1;
+      Standard_Integer myParLen = myParameters->Length();
+      Standard_Integer aLen = (myParLen > mylen)? myParLen : mylen;
+      Handle(TColStd_HArray1OfReal) ThePar =
+        new TColStd_HArray1OfReal(myfirstpt, myfirstpt+aLen-1);
+      for (i = 0; i < aLen; i++)
+        ThePar->SetValue(myfirstpt+i, myParameters->Value(myParameters->Lower()+i));
       myPar.Append(ThePar);
     }
   }
@@ -622,11 +895,9 @@ void Approx_ComputeLine::Perform(const MultiLine& Line)
          // Appel recursif du decoupage:
          GoUp = Standard_True;
 
-         MultiLine OtherLine =LineTool::MakeMLBetween(Line, myfirstpt, 
-                                                      mylastpt, nbp-1);
+         MultiLine anOtherLine1 = LineTool::MakeMLBetween(Line, myfirstpt, mylastpt, nbp-1);
          
-         Standard_Integer nbpdsotherligne = LineTool::FirstPoint(OtherLine)
-           -LineTool::LastPoint(OtherLine);
+         Standard_Integer nbpdsotherligne = LineTool::FirstPoint (anOtherLine1) - LineTool::LastPoint (anOtherLine1);
 
          //-- Si MakeML a echoue   on retourne une ligne vide
          if ((nbpdsotherligne == 0) || myMultiLineNb >= 3)
@@ -644,7 +915,23 @@ void Approx_ComputeLine::Perform(const MultiLine& Line)
            Par = Approx_IsoParametric;
            Parameters(Line, myfirstpt, mylastpt, Param);
            TheMultiCurve = AppParCurves_MultiCurve();
-           Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d);
+            MultiLine anOtherLine2;
+            Standard_Boolean isOtherLine2Made = Standard_False;
+            Standard_Integer indbad = 0;
+           Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d, indbad);
+            if (indbad != 0)
+            {
+              isOtherLine2Made = LineTool::MakeMLOneMorePoint(Line, myfirstpt, mylastpt, indbad, anOtherLine2);
+            }
+            if (isOtherLine2Made)
+            {
+              myIsClear = Standard_True;
+              //++myMultiLineNb;
+              myNbPlusOnePoint++;
+              Par = SavePar;
+              Perform(anOtherLine2);
+              Ok = Standard_True;
+            }
 
            if (!Ok) {
              Standard_Real tt3d = currenttol3d, tt2d = currenttol2d;
@@ -657,7 +944,21 @@ void Approx_ComputeLine::Perform(const MultiLine& Line)
                Par = Approx_ChordLength;
 
              Parameters(Line, myfirstpt, mylastpt, Param);
-             Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d);
+        isOtherLine2Made = Standard_False;
+              indbad = 0;
+             Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d, indbad);
+              if (indbad != 0)
+              {
+                isOtherLine2Made = LineTool::MakeMLOneMorePoint (Line, myfirstpt, mylastpt, indbad, anOtherLine2);
+              }
+              if (isOtherLine2Made)
+              {
+                myIsClear = Standard_True;
+                //++myMultiLineNb;
+                myNbPlusOnePoint++;
+                Perform (anOtherLine2);
+                Ok = Standard_True;
+              }
              
              if (!Ok && tt3d <= currenttol3d && tt2d <= currenttol2d) {
                currenttol3d = tt3d; currenttol2d = tt2d;
@@ -666,6 +967,12 @@ void Approx_ComputeLine::Perform(const MultiLine& Line)
              }
            }
            Par = SavePar;
+            if (myfirstpt == Thelastpt)
+            {
+              Finish = Standard_True;
+              alldone = Standard_True;
+              return;
+            }
 
            oldlastpt = mylastpt;
            if (!Ok) {
@@ -675,17 +982,40 @@ void Approx_ComputeLine::Perform(const MultiLine& Line)
                return;
              }
 #ifdef OCCT_DEBUG
-      if (mydebug) DUMP(TheMultiCurve);
+              if (mydebug) DUMP(TheMultiCurve);
 #endif
-             myMultiCurves.Append(TheMultiCurve);
-             Tolers3d.Append(currenttol3d);
-             Tolers2d.Append(currenttol2d);
-             
-             Handle(TColStd_HArray1OfReal) ThePar = new TColStd_HArray1OfReal(myfirstpt, oldlastpt);
-             for (i = myfirstpt; i <= oldlastpt; i++) {
-               ThePar->SetValue(i, myParameters->Value(i));
-             }
-             myPar.Append(ThePar);
+              MultiLine anOtherLine3;
+              Standard_Boolean isOtherLine3Made = Standard_False;
+              Standard_Integer indbad2 = 0;
+              if (!CheckMultiCurve(TheMultiCurve, Line,
+                                   myfirstpt, mylastpt,
+                                   indbad2))
+              {
+                isOtherLine3Made = LineTool::MakeMLOneMorePoint (Line, myfirstpt, mylastpt, indbad2, anOtherLine3);
+              }
+              if (isOtherLine3Made)
+              {
+                myIsClear = Standard_True;
+                //++myMultiLineNb;
+                myNbPlusOnePoint++;
+                Perform(anOtherLine3);
+                myfirstpt = mylastpt;
+                mylastpt = Thelastpt;
+              }
+              else
+              {
+                myMultiCurves.Append(TheMultiCurve);
+                Tolers3d.Append(currenttol3d);
+                Tolers2d.Append(currenttol2d);
+                Standard_Integer mylen = oldlastpt-myfirstpt+1;
+                Standard_Integer myParLen = myParameters->Length();
+                Standard_Integer aLen = (myParLen > mylen)? myParLen : mylen;
+                Handle(TColStd_HArray1OfReal) ThePar =
+                  new TColStd_HArray1OfReal(myfirstpt, myfirstpt+aLen-1);
+                for (i = 0; i < aLen; i++)
+                  ThePar->SetValue(myfirstpt+i, myParameters->Value(myParameters->Lower()+i));
+                myPar.Append(ThePar);
+              }
            } 
            myfirstpt = oldlastpt;
            mylastpt = Thelastpt;
@@ -695,7 +1025,7 @@ void Approx_ComputeLine::Perform(const MultiLine& Line)
          {
            myIsClear = Standard_True;
            ++myMultiLineNb;
-           Perform(OtherLine);
+           Perform(anOtherLine1);
            myfirstpt = mylastpt;
            mylastpt = Thelastpt;
          }
@@ -716,11 +1046,13 @@ void Approx_ComputeLine::Perform(const MultiLine& Line)
          myMultiCurves.Append(TheMultiCurve);
          Tolers3d.Append(currenttol3d);
          Tolers2d.Append(currenttol2d);
-
-         Handle(TColStd_HArray1OfReal) ThePar = new TColStd_HArray1OfReal(myfirstpt, oldlastpt);
-         for (i = myfirstpt; i <= oldlastpt; i++) {
-           ThePar->SetValue(i, myParameters->Value(i));
-         }
+          Standard_Integer mylen = oldlastpt-myfirstpt+1;
+          Standard_Integer myParLen = myParameters->Length();
+          Standard_Integer aLen = (myParLen > mylen)? myParLen : mylen;
+          Handle(TColStd_HArray1OfReal) ThePar =
+            new TColStd_HArray1OfReal(myfirstpt, myfirstpt+aLen-1);
+          for (i = 0; i < aLen; i++)
+            ThePar->SetValue(myfirstpt+i, myParameters->Value(myParameters->Lower()+i));
          myPar.Append(ThePar);
 
          myfirstpt = oldlastpt;
@@ -776,8 +1108,28 @@ void Approx_ComputeLine::Perform(const MultiLine& Line)
        }
 
        TheMultiCurve = AppParCurves_MultiCurve();
-       Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d);
-
+        MultiLine anOtherLine4;
+        Standard_Boolean isOtherLine4Made = Standard_False;
+        Standard_Integer indbad = 0;
+       Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d, indbad);
+        if (indbad != 0)
+        {
+          isOtherLine4Made = LineTool::MakeMLOneMorePoint (Line, myfirstpt, mylastpt, indbad, anOtherLine4);
+        }
+        if (isOtherLine4Made)
+        {
+          myIsClear = Standard_True;
+          //++myMultiLineNb;
+          myNbPlusOnePoint++;
+          Perform (anOtherLine4);
+          Ok = Standard_True;
+        }
+        if (myfirstpt == Thelastpt)
+        {
+          Finish = Standard_True;
+          alldone = Standard_True;
+          return;
+        }
       }
     }
   }
@@ -886,9 +1238,10 @@ Standard_Boolean Approx_ComputeLine::Compute(const MultiLine& Line,
                                             const Standard_Integer lpt,
                                              math_Vector&     Para,
                                             Standard_Real&   TheTol3d,
-                                            Standard_Real&   TheTol2d)
+                                            Standard_Real&   TheTol2d,
+                                             Standard_Integer& indbad)
 {
-  
+  indbad = 0;
   Standard_Integer deg, i;
   Standard_Boolean mydone;
   Standard_Real Fv;
@@ -947,20 +1300,30 @@ Standard_Boolean Approx_ComputeLine::Compute(const MultiLine& Line,
        // Stockage de la multicurve approximee.
        tolreached = Standard_True;
 #ifdef OCCT_DEBUG
-      if (mydebug) DUMP(mySCU);
+        if (mydebug) DUMP(mySCU);
 #endif
-       myMultiCurves.Append(mySCU);
-       // Stockage des parametres de la partie de MultiLine approximee:
-       // A ameliorer !! (bq trop de recopies)
-       Handle(TColStd_HArray1OfReal) ThePar = 
-         new TColStd_HArray1OfReal(Para.Lower(), Para.Upper());
-       for (i = Para.Lower(); i <= Para.Upper(); i++) {
-         ThePar->SetValue(i, Para(i));
-       }
-       myPar.Append(ThePar);
-       Tolers3d.Append(TheTol3d);
-       Tolers2d.Append(TheTol2d);
-       return Standard_True;
+        if (myNbPlusOnePoint != 0 &&
+            !CheckMultiCurve(mySCU, Line,
+                             fpt, lpt,
+                             indbad))
+        {
+          return Standard_False;
+        }
+        else
+        {
+          myMultiCurves.Append(mySCU);
+          // Stockage des parametres de la partie de MultiLine approximee:
+          // A ameliorer !! (bq trop de recopies)
+          Handle(TColStd_HArray1OfReal) ThePar = 
+            new TColStd_HArray1OfReal(Para.Lower(), Para.Upper());
+          for (i = Para.Lower(); i <= Para.Upper(); i++) {
+            ThePar->SetValue(i, Para(i));
+          }
+          myPar.Append(ThePar);
+          Tolers3d.Append(TheTol3d);
+          Tolers2d.Append(TheTol2d);
+          return Standard_True;
+        }
       }
     }
 
index a59c2cf..bbaa775 100644 (file)
@@ -557,8 +557,8 @@ void ApproxInt_Approx::buildKnots(const Handle(TheWLine)& theline,
 
   const ApproxInt_TheMultiLine aTestLine( theline, thePtrSVSurf,
                                           ((myData.ApproxXYZ)? 1 : 0),
-                                          ((myData.ApproxU1V1)? 1: 0) +
-                                                ((myData.ApproxU2V2)? 1: 0),
+                                          ((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0),
+                                          myData.ApproxU1V1, myData.ApproxU2V2,
                                           myData.Xo, myData.Yo, myData.Zo,
                                           myData.U1o, myData.V1o, myData.U2o, myData.V2o,
                                           myData.ApproxU1V1,
@@ -631,10 +631,11 @@ void ApproxInt_Approx::buildCurve(const Handle(TheWLine)& theline,
     imin = myKnots(kind);
     imax = myKnots(kind+1);
     ApproxInt_TheMultiLine myMultiLine(theline, thePtrSVSurf,
-      ((myData.ApproxXYZ)? 1 : 0),
-      ((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0),
-      myData.Xo, myData.Yo, myData.Zo, myData.U1o, myData.V1o,
-      myData.U2o, myData.V2o, myData.ApproxU1V1, imin, imax);
+                                       ((myData.ApproxXYZ)? 1 : 0),
+                                       ((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0),
+                                       myData.ApproxU1V1, myData.ApproxU2V2,
+                                       myData.Xo, myData.Yo, myData.Zo, myData.U1o, myData.V1o,
+                                       myData.U2o, myData.V2o, myData.ApproxU1V1, imin, imax);
 
     if(myData.myBezierApprox)
     {
@@ -716,4 +717,4 @@ void ApproxInt_Approx::buildCurve(const Handle(TheWLine)& theline,
   {
     myBezToBSpl.Perform();
   }
-}
\ No newline at end of file
+}
index 74eb09d..8501520 100644 (file)
@@ -14,6 +14,7 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <IntSurf_PntOn2S.hxx>
 #include <TColStd_Array1OfReal.hxx>
 #include <math_FunctionSetRoot.hxx>
 #include <StdFail_NotDone.hxx>
@@ -489,12 +490,10 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1,
     }
   }
 
-  Standard_Real aBornInf[2],aBornSup[2],aF[1],aX[2],aTolerance[2];
-  math_Vector BornInf(aBornInf,1,2),BornSup(aBornSup,1,2),F(aF,1,1),
-    X(aX,1,2),Tolerance(aTolerance,1,2);
-  Standard_Real aD[1][2];
-  math_Matrix D(aD,1, 1, 1, 2); 
-
+  math_Vector X(1,2);
+  math_Vector BornInf(1,2), BornSup(1,2), Tolerance(1,2);
+  //--- ThePSurfaceTool::GetResolution(aPSurf,Tolerance(1),Tolerance(2));
+  Tolerance(1) = 1.0e-8; Tolerance(2) = 1.0e-8;
   Standard_Real binfu,bsupu,binfv,bsupv;
   binfu = ThePSurfaceTool::FirstUParameter(aPSurf);
   binfv = ThePSurfaceTool::FirstVParameter(aPSurf);
@@ -502,124 +501,23 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1,
   bsupv = ThePSurfaceTool::LastVParameter(aPSurf);
   BornInf(1) = binfu; BornSup(1) = bsupu; 
   BornInf(2) = binfv; BornSup(2) = bsupv;
-
-  //--- ThePSurfaceTool::GetResolution(aPSurf,Tolerance(1),Tolerance(2));
-  Tolerance(1) = 1.0e-8; Tolerance(2) = 1.0e-8;
-
-  Standard_Real TranslationU=0.0;
-  Standard_Real TranslationV=0.0;
-
-  math_FunctionSetRoot  Rsnld(MyZerImpFunc);
-  Rsnld.SetTolerance(Tolerance);
-  if(MyImplicitFirst) { 
-    if(u2<binfu-0.0000000001) { 
-      if(ThePSurfaceTool::IsUPeriodic(aPSurf)) { 
-       Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf);
-       do {  TranslationU+=d; } while(u2+TranslationU < binfu);
-      }
-      else { 
-       MyIsTangent=MyIsTangentbis=Standard_False;
-       MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
-       return(Standard_False);
-      }
-    }
-    else if(u2>bsupu+0.0000000001) { 
-      if(ThePSurfaceTool::IsUPeriodic(aPSurf)) { 
-       Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf);
-       do { TranslationU-=d; } while(u2+TranslationU > bsupu);
-      }
-      else { 
-       MyIsTangent=MyIsTangentbis=Standard_False;
-       MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
-       return(Standard_False);
-      } 
-    }
-    if(v2<binfv-0.0000000001) { 
-      if(ThePSurfaceTool::IsVPeriodic(aPSurf)) { 
-       Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf);
-       do { TranslationV+=d; } while(v2+TranslationV < binfv);
-      }
-      else { 
-       MyIsTangent=MyIsTangentbis=Standard_False;
-       MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
-       return(Standard_False);
-      }
-    }
-    else if(v2>bsupv+0.0000000001) { 
-      if(ThePSurfaceTool::IsVPeriodic(aPSurf)) { 
-       Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf);
-       do { TranslationV-=d; } while(v2+TranslationV > bsupv);
-      }
-      else { 
-       MyIsTangent=MyIsTangentbis=Standard_False;
-       MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
-       return(Standard_False);
-      } 
-    }
-    X(1) = u2+TranslationU; 
-    X(2) = v2+TranslationV;
-  }
-  else { 
-    if(u1<binfu-0.0000000001) { 
-      if(ThePSurfaceTool::IsUPeriodic(aPSurf)) { 
-       Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf);
-       do {  TranslationU+=d;  } while(u1+TranslationU < binfu);
-      }
-      else { 
-       MyIsTangent=MyIsTangentbis=Standard_False;
-       MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
-       return(Standard_False);
-      }
-    }
-    else if(u1>bsupu+0.0000000001) { 
-      if(ThePSurfaceTool::IsUPeriodic(aPSurf)) { 
-       Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf);
-       do { TranslationU-=d; } while(u1+TranslationU > bsupu);
-      }
-      else { 
-       MyIsTangent=MyIsTangentbis=Standard_False;
-       MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
-       return(Standard_False);
-      } 
-    }
-    if(v1<binfv-0.0000000001) { 
-      if(ThePSurfaceTool::IsVPeriodic(aPSurf)) { 
-       Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf);
-       do { TranslationV+=d; } while(v1+TranslationV < binfv);
-      }
-      else { 
-       MyIsTangent=MyIsTangentbis=Standard_False;
-       MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
-       return(Standard_False);
-      }
-    }
-    else if(v1>bsupv+0.0000000001) { 
-      if(ThePSurfaceTool::IsVPeriodic(aPSurf)) { 
-       Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf);
-       do { TranslationV-=d; } while(v1+TranslationV > bsupv);
-      }
-      else { 
-       MyIsTangent=MyIsTangentbis=Standard_False;
-       MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
-       return(Standard_False);
-      } 
-    }
-    X(1) = u1+TranslationU;
-    X(2) = v1+TranslationV;
-  }
-  
-  //----------------------------------------------------
-  //Make a small step from boundaries in order to avoid
-  //finding "outboundaried" solution (Rsnld -> NotDone).
-  if(X(1)-0.0000000001 <= binfu) X(1)=X(1)+0.0000001;
-  if(X(1)+0.0000000001 >= bsupu) X(1)=X(1)-0.0000001;
-  if(X(2)-0.0000000001 <= binfv) X(2)=X(2)+0.0000001;
-  if(X(2)+0.0000000001 >= bsupv) X(2)=X(2)-0.0000001;
+  Standard_Real TranslationU = 0., TranslationV = 0.;
   
+  if (!FillInitialVectorOfSolution(u1, v1, u2, v2,
+                                   binfu, bsupu, binfv, bsupv,
+                                   X,
+                                   TranslationU, TranslationV))
+  {
+    MyIsTangent=MyIsTangentbis=Standard_False;
+    MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
+    return(Standard_False);
+  }
 
   Standard_Real PourTesterU = X(1);
   Standard_Real PourTesterV = X(2);
-  
+
+  math_FunctionSetRoot  Rsnld(MyZerImpFunc);
+  Rsnld.SetTolerance(Tolerance);
   Rsnld.Perform(MyZerImpFunc,X,BornInf,BornSup);
   if(Rsnld.IsDone()) { 
     MyHasBeenComputed = Standard_True;
@@ -826,9 +724,189 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1,
   }
 }
 
-//--------------------------------------------------------------------------------
+//=======================================================================
+//function : SeekPoint
+//purpose  :    Computes point on curve and
+//            parameters on the surfaces.
+//=======================================================================
+Standard_Boolean ApproxInt_ImpPrmSvSurfaces::SeekPoint(const Standard_Real u1,
+                                                       const Standard_Real v1,
+                                                       const Standard_Real u2,
+                                                       const Standard_Real v2,
+                                                       IntSurf_PntOn2S& Point) { 
+  gp_Pnt aP;
+  gp_Vec aT;
+  gp_Vec2d aTS1,aTS2;
+  const IntSurf_Quadric&  aQSurf = MyZerImpFunc.ISurface();
+  const ThePSurface&      aPSurf = MyZerImpFunc.PSurface();
 
+  math_Vector X(1,2);
+  math_Vector BornInf(1,2), BornSup(1,2), Tolerance(1,2);
+  //--- ThePSurfaceTool::GetResolution(aPSurf,Tolerance(1),Tolerance(2));
+  Tolerance(1) = 1.0e-8; Tolerance(2) = 1.0e-8;
+  Standard_Real binfu,bsupu,binfv,bsupv;
+  binfu = ThePSurfaceTool::FirstUParameter(aPSurf);
+  binfv = ThePSurfaceTool::FirstVParameter(aPSurf);
+  bsupu = ThePSurfaceTool::LastUParameter(aPSurf);
+  bsupv = ThePSurfaceTool::LastVParameter(aPSurf);
+  BornInf(1) = binfu; BornSup(1) = bsupu; 
+  BornInf(2) = binfv; BornSup(2) = bsupv;
+  Standard_Real TranslationU = 0., TranslationV = 0.;
+  
+  if (!FillInitialVectorOfSolution(u1, v1, u2, v2,
+                                   binfu, bsupu, binfv, bsupv,
+                                   X,
+                                   TranslationU, TranslationV))
+    return Standard_False;
+
+  Standard_Real NewU1, NewV1, NewU2, NewV2;
+  
+  math_FunctionSetRoot  Rsnld(MyZerImpFunc);
+  Rsnld.SetTolerance(Tolerance);
+  Rsnld.Perform(MyZerImpFunc,X,BornInf,BornSup);
+  if(Rsnld.IsDone()) { 
+    MyHasBeenComputed = Standard_True;
+    Rsnld.Root(X);
+  
+    MyPnt = ThePSurfaceTool::Value(aPSurf, X(1), X(2));
+    
+    if(MyImplicitFirst)
+    { 
+      NewU2 = X(1)-TranslationU;
+      NewV2 = X(2)-TranslationV;
+
+      aQSurf.Parameters(MyPnt, NewU1, NewV1);
+      //adjust U
+      if (aQSurf.TypeQuadric() != GeomAbs_Plane)
+      {
+        Standard_Real sign = (NewU1 > u1)? -1 : 1;
+        while (Abs(u1 - NewU1) > M_PI)
+          NewU1 += sign*(M_PI+M_PI);
+      }
+    }
+    else
+    {
+      NewU1 = X(1)-TranslationU;
+      NewV1 = X(2)-TranslationV;
+
+      aQSurf.Parameters(MyPnt, NewU2, NewV2);
+      //adjust U
+      if (aQSurf.TypeQuadric() != GeomAbs_Plane)
+      {
+        Standard_Real sign = (NewU2 > u2)? -1 : 1;
+        while (Abs(u2 - NewU2) > M_PI)
+          NewU2 += sign*(M_PI+M_PI);
+      }
+    }
+  }
+  else
+    return Standard_False;
+  
+  Point.SetValue(MyPnt, NewU1, NewV1, NewU2, NewV2);
+  return Standard_True;
+}
+//--------------------------------------------------------------------------------
 
+Standard_Boolean
+ApproxInt_ImpPrmSvSurfaces::FillInitialVectorOfSolution(const Standard_Real u1,
+                                                        const Standard_Real v1,
+                                                        const Standard_Real u2,
+                                                        const Standard_Real v2,
+                                                        const Standard_Real binfu,
+                                                        const Standard_Real bsupu,
+                                                        const Standard_Real binfv,
+                                                        const Standard_Real bsupv,
+                                                        math_Vector& X,
+                                                        Standard_Real& TranslationU,
+                                                        Standard_Real& TranslationV)
+{
+  const ThePSurface&      aPSurf = MyZerImpFunc.PSurface();
 
+  math_Vector F(1,1);
 
+  TranslationU = 0.0;
+  TranslationV = 0.0;
 
+  if(MyImplicitFirst) { 
+    if(u2<binfu-0.0000000001) { 
+      if(ThePSurfaceTool::IsUPeriodic(aPSurf)) { 
+       Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf);
+       do {  TranslationU+=d; } while(u2+TranslationU < binfu);
+      }
+      else 
+       return(Standard_False);
+    }
+    else if(u2>bsupu+0.0000000001) { 
+      if(ThePSurfaceTool::IsUPeriodic(aPSurf)) { 
+       Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf);
+       do { TranslationU-=d; } while(u2+TranslationU > bsupu);
+      }
+      else
+       return(Standard_False);
+    }
+    if(v2<binfv-0.0000000001) { 
+      if(ThePSurfaceTool::IsVPeriodic(aPSurf)) { 
+       Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf);
+       do { TranslationV+=d; } while(v2+TranslationV < binfv);
+      }
+      else
+       return(Standard_False);
+    }
+    else if(v2>bsupv+0.0000000001) { 
+      if(ThePSurfaceTool::IsVPeriodic(aPSurf)) { 
+       Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf);
+       do { TranslationV-=d; } while(v2+TranslationV > bsupv);
+      }
+      else
+       return(Standard_False);
+    }
+    X(1) = u2+TranslationU; 
+    X(2) = v2+TranslationV;
+  }
+  else { 
+    if(u1<binfu-0.0000000001) { 
+      if(ThePSurfaceTool::IsUPeriodic(aPSurf)) { 
+       Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf);
+       do {  TranslationU+=d;  } while(u1+TranslationU < binfu);
+      }
+      else
+       return(Standard_False);
+    }
+    else if(u1>bsupu+0.0000000001) { 
+      if(ThePSurfaceTool::IsUPeriodic(aPSurf)) { 
+       Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf);
+       do { TranslationU-=d; } while(u1+TranslationU > bsupu);
+      }
+      else
+       return(Standard_False);
+    }
+    if(v1<binfv-0.0000000001) { 
+      if(ThePSurfaceTool::IsVPeriodic(aPSurf)) { 
+       Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf);
+       do { TranslationV+=d; } while(v1+TranslationV < binfv);
+      }
+      else
+       return(Standard_False);
+    }
+    else if(v1>bsupv+0.0000000001) { 
+      if(ThePSurfaceTool::IsVPeriodic(aPSurf)) { 
+       Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf);
+       do { TranslationV-=d; } while(v1+TranslationV > bsupv);
+      }
+      else
+       return(Standard_False);
+    }
+    X(1) = u1+TranslationU;
+    X(2) = v1+TranslationV;
+  }
+  
+  //----------------------------------------------------
+  //Make a small step from boundaries in order to avoid
+  //finding "outboundaried" solution (Rsnld -> NotDone).
+  if(X(1)-0.0000000001 <= binfu) X(1)=X(1)+0.0000001;
+  if(X(1)+0.0000000001 >= bsupu) X(1)=X(1)-0.0000001;
+  if(X(2)-0.0000000001 <= binfv) X(2)=X(2)+0.0000001;
+  if(X(2)+0.0000000001 >= bsupv) X(2)=X(2)-0.0000001;
+  
+  return Standard_True;
+}
index d6f2e64..d19952f 100644 (file)
 #include <gp_Vec2d.hxx>
 #include <gp_Vec.hxx>
 #include <IntSurf_LineOn2S.hxx>
+#include <Precision.hxx>
+#include <math_Vector.hxx>
+
+#ifdef DRAW
+#include <DrawTrSurf.hxx>
+#endif
+
+//=======================================================================
+//function : Constructor
+//purpose  : 
+//=======================================================================
+ApproxInt_MultiLine::ApproxInt_MultiLine()
+{
+  PtrOnmySvSurfaces = NULL;
+  myLine = NULL;
+  indicemin = 0;
+  indicemax = 0;
+  nbp3d = 0;
+  nbp2d = 0;
+  myApproxU1V1 = Standard_False;
+  myApproxU2V2 = Standard_False;
+  p2donfirst = Standard_True;
+  Xo = 0.;
+  Yo = 0.;
+  Zo = 0.;
+  U1o = 0.;
+  V1o = 0.;
+  U2o = 0.;
+  V2o = 0.;
+}
 
 //=======================================================================
 //function : Constructor
@@ -30,6 +60,8 @@ ApproxInt_MultiLine::
                       const Standard_Address svsurf,
                       const Standard_Integer NbP3d,
                       const Standard_Integer NbP2d,
+                      const Standard_Boolean ApproxU1V1,
+                      const Standard_Boolean ApproxU2V2,
                       const Standard_Real xo,
                       const Standard_Real yo,
                       const Standard_Real zo,
@@ -44,6 +76,8 @@ ApproxInt_MultiLine::
                                                       indicemin(Min(IndMin, IndMax)),
                                                       indicemax(Max(IndMin, IndMax)),
                                                       nbp3d(NbP3d), nbp2d(NbP2d),
+                                                      myApproxU1V1(ApproxU1V1),
+                                                      myApproxU2V2(ApproxU2V2),
                                                       p2donfirst(P2DOnFirst),
                                                       Xo(xo), Yo(yo), Zo(zo),
                                                       U1o(u1o), V1o(v1o),
@@ -66,6 +100,8 @@ ApproxInt_MultiLine::
   ApproxInt_MultiLine(const Handle_TheLine& line,
                       const Standard_Integer NbP3d,
                       const Standard_Integer NbP2d,
+                      const Standard_Boolean ApproxU1V1,
+                      const Standard_Boolean ApproxU2V2,
                       const Standard_Real xo,
                       const Standard_Real yo,
                       const Standard_Real zo,
@@ -80,6 +116,8 @@ ApproxInt_MultiLine::
                                                       indicemin(Min(IndMin, IndMax)),
                                                       indicemax(Max(IndMin, IndMax)),
                                                       nbp3d(NbP3d), nbp2d(NbP2d),
+                                                      myApproxU1V1(ApproxU1V1),
+                                                      myApproxU2V2(ApproxU2V2),
                                                       p2donfirst(P2DOnFirst),
                                                       Xo(xo), Yo(yo), Zo(zo),
                                                       U1o(u1o), V1o(v1o),
@@ -95,26 +133,26 @@ ApproxInt_MultiLine::
 
 //--------------------------------------------------------------------------------
 Standard_Integer ApproxInt_MultiLine::FirstPoint() const { 
-  return(indicemin);
+  return indicemin;
 }
 //--------------------------------------------------------------------------------
 Standard_Integer ApproxInt_MultiLine::LastPoint() const { 
-  return(indicemax);
+  return indicemax;
 }
 //--------------------------------------------------------------------------------
 Approx_Status ApproxInt_MultiLine::WhatStatus() const { 
   if(PtrOnmySvSurfaces)
-    return(Approx_PointsAdded);
+    return Approx_PointsAdded;
   else 
-    return(Approx_NoPointsAdded);
+    return Approx_NoPointsAdded;
 }
 //--------------------------------------------------------------------------------
 Standard_Integer ApproxInt_MultiLine::NbP3d() const { 
-  return(nbp3d);
+  return nbp3d;
 }
 //--------------------------------------------------------------------------------
 Standard_Integer ApproxInt_MultiLine::NbP2d() const { 
-  return(nbp2d);
+  return nbp2d;
 }
 //================================================================================
 void ApproxInt_MultiLine::Value(const Standard_Integer  Index,
@@ -268,13 +306,14 @@ ApproxInt_MultiLine
     //-- cout<<"\n Erreur dans : ApproxInt_MultiLine  ApproxInt_MultiLine::MakeMLBetween "<<endl;
     Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S();
     Handle(TheLine) vide = new TheLine(vide1,Standard_False);
-    return(ApproxInt_MultiLine(vide,
-                              NULL,
-                              nbp3d,
-                              nbp2d,
-                              Xo,Yo,Zo,U1o,V1o,U2o,V2o,
-                              p2donfirst,
-                              1,1));
+    return (ApproxInt_MultiLine(vide,
+                                NULL,
+                                nbp3d,
+                                nbp2d,
+                                myApproxU1V1, myApproxU2V2,
+                                Xo,Yo,Zo,U1o,V1o,U2o,V2o,
+                                p2donfirst,
+                                1,1));
     //-- return(*this);
   }
 
@@ -525,15 +564,16 @@ ApproxInt_MultiLine
 
   if((temp->NbPnts() >= NbPntsToInsert + High - Low + 1) && (CodeErreur==0))
   {
-    return(ApproxInt_MultiLine( temp, 
-                                (High-Low>10)? PtrOnmySvSurfaces : NULL,
-                                nbp3d,
-                                nbp2d,
-                                Xo,Yo,Zo,
-                                U1o,V1o,
-                                U2o,V2o,
-                                p2donfirst,
-                                1,ResultPntOn2SLine->NbPoints()));
+    return (ApproxInt_MultiLine( temp, 
+                                 (High-Low>10)? PtrOnmySvSurfaces : NULL,
+                                 nbp3d,
+                                 nbp2d,
+                                 myApproxU1V1, myApproxU2V2,
+                                 Xo,Yo,Zo,
+                                 U1o,V1o,
+                                 U2o,V2o,
+                                 p2donfirst,
+                                 1,ResultPntOn2SLine->NbPoints()));
   }
   else
   {
@@ -541,16 +581,137 @@ ApproxInt_MultiLine
     //-- cout<<" Pas de Rajout de points ds1min =  "<<minds1<<" ds2min = "<<minds2<<endl;
     Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S();
     Handle(TheLine) vide = new TheLine(vide1,Standard_False);
-    return(ApproxInt_MultiLine( vide,
-                                NULL,
-                                nbp3d,
-                                nbp2d,
-                                Xo,Yo,Zo,
-                                U1o,V1o,
+    return (ApproxInt_MultiLine( vide,
+                                 NULL,
+                                 nbp3d,
+                                 nbp2d,
+                                 myApproxU1V1, myApproxU2V2,
+                                 Xo,Yo,Zo,
+                                 U1o,V1o,
                                 U2o,V2o,
-                                p2donfirst,
-                                1,1));
+                                 p2donfirst,
+                                 1,1));
+  }
+}
+
+//=======================================================================
+//function : MakeMLOneMorePoint
+//purpose  : 
+//=======================================================================
+Standard_Boolean
+  ApproxInt_MultiLine::MakeMLOneMorePoint(const Standard_Integer theLow,
+                                          const Standard_Integer theHigh,
+                                          const Standard_Integer theIndbad,
+                                          ApproxInt_MultiLine& theNewMultiLine) const
+{
+  Standard_Boolean OtherLineMade = Standard_False;
+  if(PtrOnmySvSurfaces==NULL)
+    return Standard_False;
+  
+  const Standard_Real SqTol3d = Precision::SquareConfusion();
+  math_Vector tolerance(1,2);
+  tolerance(1) = tolerance(2) = 1.e-8;
+  
+  Handle(IntSurf_LineOn2S) ResultPntOn2SLine = new IntSurf_LineOn2S();
+  for (Standard_Integer Indice = theLow; Indice <= theHigh; Indice++)
+    ResultPntOn2SLine->Add(myLine->Point(Indice));
+
+  //Insert new point between (theIndbad-1) and theIndbad
+  //Using <thePtrSVSurf> for Rsnld: it may be ImpPrm or PrmPrm
+  gp_Pnt PrevPnt = myLine->Point(theIndbad-1).Value();
+  gp_Pnt CurPnt  = myLine->Point(theIndbad).Value();
+  Standard_Real uprev1, vprev1, uprev2, vprev2, ucur1, vcur1, ucur2, vcur2;
+  myLine->Point(theIndbad-1).Parameters(uprev1, vprev1, uprev2, vprev2);
+  myLine->Point(theIndbad).Parameters(ucur1, vcur1, ucur2, vcur2);
+  Standard_Real umid1, vmid1, umid2, vmid2;
+  umid1 = (uprev1 + ucur1)/2;
+  vmid1 = (vprev1 + vcur1)/2;
+  umid2 = (uprev2 + ucur2)/2;
+  vmid2 = (vprev2 + vcur2)/2;
+  IntSurf_PntOn2S MidPoint;
+  Standard_Boolean IsNewPointInvalid = Standard_False;
+  IsNewPointInvalid =
+    myApproxU1V1 &&
+    Abs(ucur1 - umid1) <= tolerance(1) &&
+    Abs(vcur1 - vmid1) <= tolerance(2);
+  if (!IsNewPointInvalid)
+  {
+    IsNewPointInvalid =
+      myApproxU2V2 &&
+      Abs(ucur2 - umid2) <= tolerance(1) &&
+      Abs(vcur2 - vmid2) <= tolerance(2);
+    if (!IsNewPointInvalid &&
+        ((TheSvSurfaces *)PtrOnmySvSurfaces)->SeekPoint(umid1, vmid1, umid2, vmid2,
+                                                        MidPoint))
+    {
+      const gp_Pnt& NewPnt = MidPoint.Value();
+      Standard_Real SqDistNewPrev = NewPnt.SquareDistance(PrevPnt);
+      Standard_Real SqDistNewCur  = NewPnt.SquareDistance(CurPnt);
+      IsNewPointInvalid = (SqDistNewPrev <= SqTol3d ||
+                           SqDistNewCur  <= SqTol3d);
+      if (!IsNewPointInvalid)
+      {
+        Standard_Real unew1, vnew1, unew2, vnew2;
+        MidPoint.Parameters(unew1, vnew1, unew2, vnew2);
+        if (myApproxU1V1)
+        {
+          Standard_Real SqDistCurMid1 =
+            (ucur1 - umid1)*(ucur1 - umid1)+(vcur1 - vmid1)*(vcur1 - vmid1);
+          Standard_Real SqDistMidNew1 =
+            (umid1 - unew1)*(umid1 - unew1)+(vmid1 - vnew1)*(vmid1 - vnew1);
+          IsNewPointInvalid = (SqDistMidNew1 > SqDistCurMid1);
+        }
+        if (!IsNewPointInvalid)
+        {
+          if (myApproxU2V2)
+          {
+            Standard_Real SqDistCurMid2 =
+              (ucur2 - umid2)*(ucur2 - umid2)+(vcur2 - vmid2)*(vcur2 - vmid2);
+            Standard_Real SqDistMidNew2 =
+              (umid2 - unew2)*(umid2 - unew2)+(vmid2 - vnew2)*(vmid2 - vnew2);
+            IsNewPointInvalid = (SqDistMidNew2 > SqDistCurMid2);
+          }
+          if (!IsNewPointInvalid)
+          {
+            ResultPntOn2SLine->InsertBefore(theIndbad-theLow+1, MidPoint);
+            OtherLineMade = Standard_True;
+          }
+        }
+      }
+    }
+  }
+
+  if (!OtherLineMade)
+    return Standard_False;
+
+#ifdef DRAW
+  char* name = new char[100];
+  Standard_Integer indc = 1;
+  Standard_Boolean onfirst = Standard_True;
+  for (Standard_Integer i = 1; i <= ResultPntOn2SLine->NbPoints(); i++)
+  {
+    const IntSurf_PntOn2S& thePoint = ResultPntOn2SLine->Value(i);
+    gp_Pnt curPnt = thePoint.Value();
+    sprintf(name, "p%d_%d", indc, i);
+    DrawTrSurf::Set(name, curPnt);
+    gp_Pnt2d curPnt2d = thePoint.ValueOnSurface(onfirst);
+    sprintf(name, "pp%d_%d", indc, i);
+    DrawTrSurf::Set(name, curPnt2d);
   }
+#endif
+  Handle(TheLine) temp = new TheLine(ResultPntOn2SLine,Standard_False);
+  theNewMultiLine = ApproxInt_MultiLine( temp, 
+                                         PtrOnmySvSurfaces,
+                                         nbp3d,
+                                         nbp2d,
+                                         myApproxU1V1,
+                                         myApproxU2V2,
+                                         Xo,Yo,Zo,
+                                         U1o,V1o,
+                                         U2o,V2o,
+                                         p2donfirst,
+                                         1,ResultPntOn2SLine->NbPoints());
+  return Standard_True;
 }
 
 //=======================================================================
index a14a07e..c047e78 100644 (file)
@@ -115,6 +115,15 @@ inline TheMultiLine ApproxInt_MultiLineTool::MakeMLBetween(const TheMultiLine& M
   
   return(ML.MakeMLBetween(I1,I2,NbPMin));
 }
+//--------------------------------------------------------------------------------     
+inline Standard_Boolean ApproxInt_MultiLineTool::MakeMLOneMorePoint(const TheMultiLine& ML,
+                                                                    const Standard_Integer I1,
+                                                                    const Standard_Integer I2,
+                                                                    const Standard_Integer indbad,
+                                                                    TheMultiLine& OtherLine)
+{ 
+  return (ML.MakeMLOneMorePoint(I1,I2,indbad,OtherLine));
+}
 
 inline void ApproxInt_MultiLineTool::Dump(const TheMultiLine& ML)
 { 
index 74f6b8c..c4534f9 100644 (file)
@@ -34,7 +34,12 @@ ApproxInt_PrmPrmSvSurfaces::ApproxInt_PrmPrmSvSurfaces( const ThePSurface& Surf1
        MyIntersectionOn2S(Surf1,Surf2,TOLTANGENCY)
 { 
 }
-//--------------------------------------------------------------------------------
+
+//=======================================================================
+//function : Compute
+//purpose  :    Computes point on curve, 3D and 2D-tangents of a curve and
+//            parameters on the surfaces.
+//=======================================================================
 Standard_Boolean ApproxInt_PrmPrmSvSurfaces::Compute( Standard_Real& u1
                                                     ,Standard_Real& v1
                                                     ,Standard_Real& u2
@@ -221,6 +226,31 @@ void ApproxInt_PrmPrmSvSurfaces::Pnt(const Standard_Real u1,
   this->Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2);
   P=MyPnt;
 }
+
+//=======================================================================
+//function : SeekPoint
+//purpose  :    Computes point on curve and
+//            parameters on the surfaces.
+//=======================================================================
+Standard_Boolean ApproxInt_PrmPrmSvSurfaces::SeekPoint(const Standard_Real u1,
+                                                       const Standard_Real v1,
+                                                       const Standard_Real u2,
+                                                       const Standard_Real v2,
+                                                       IntSurf_PntOn2S& Point)
+{
+  gp_Pnt aP;
+  gp_Vec aT;
+  gp_Vec2d aTS1,aTS2;
+  Standard_Real tu1=u1;
+  Standard_Real tu2=u2;
+  Standard_Real tv1=v1;
+  Standard_Real tv2=v2;
+  if (!Compute(tu1,tv1,tu2,tv2,aP,aT,aTS1,aTS2))
+    return Standard_False;
+  
+  Point.SetValue(aP, tu1,tv1,tu2,tv2);
+  return Standard_True;
+}
 //--------------------------------------------------------------------------------
 Standard_Boolean ApproxInt_PrmPrmSvSurfaces::Tangency(const Standard_Real u1,
                                                      const Standard_Real v1,
index 825ba24..f2ad4fd 100644 (file)
@@ -26,7 +26,7 @@
 class gp_Pnt;
 class gp_Vec;
 class gp_Vec2d;
-
+class IntSurf_PntOn2S;
 
 
 class ApproxInt_SvSurfaces 
@@ -37,15 +37,37 @@ public:
 
   
   //! returns True if Tg,Tguv1 Tguv2 can be computed.
-  Standard_EXPORT virtual Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2, gp_Pnt& Pt, gp_Vec& Tg, gp_Vec2d& Tguv1, gp_Vec2d& Tguv2) = 0;
+  Standard_EXPORT virtual Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1,
+                                                    Standard_Real& u2, Standard_Real& v2,
+                                                    gp_Pnt& Pt,
+                                                    gp_Vec& Tg,
+                                                    gp_Vec2d& Tguv1,
+                                                    gp_Vec2d& Tguv2) = 0;
   
-  Standard_EXPORT virtual void Pnt (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Pnt& P) = 0;
+  Standard_EXPORT virtual void Pnt (const Standard_Real u1, const Standard_Real v1,
+                                    const Standard_Real u2, const Standard_Real v2,
+                                    gp_Pnt& P) = 0;
+
+  //! computes point on curve and parameters on the surfaces
+  Standard_EXPORT virtual Standard_Boolean SeekPoint(const Standard_Real u1, const Standard_Real v1,
+                                                     const Standard_Real u2, const Standard_Real v2,
+                                                     IntSurf_PntOn2S& Point) = 0;
   
-  Standard_EXPORT virtual Standard_Boolean Tangency (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec& Tg) = 0;
+  Standard_EXPORT virtual Standard_Boolean Tangency (const Standard_Real u1, const Standard_Real v1,
+                                                     const Standard_Real u2, const Standard_Real v2,
+                                                     gp_Vec& Tg) = 0;
   
-  Standard_EXPORT virtual Standard_Boolean TangencyOnSurf1 (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec2d& Tg) = 0;
+  Standard_EXPORT virtual Standard_Boolean TangencyOnSurf1 (const Standard_Real u1,
+                                                            const Standard_Real v1,
+                                                            const Standard_Real u2,
+                                                            const Standard_Real v2,
+                                                            gp_Vec2d& Tg) = 0;
   
-  Standard_EXPORT virtual Standard_Boolean TangencyOnSurf2 (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec2d& Tg) = 0;
+  Standard_EXPORT virtual Standard_Boolean TangencyOnSurf2 (const Standard_Real u1,
+                                                            const Standard_Real v1,
+                                                            const Standard_Real u2,
+                                                            const Standard_Real v2,
+                                                            gp_Vec2d& Tg) = 0;
   Standard_EXPORT virtual ~ApproxInt_SvSurfaces();
 
 
index 1e7f39c..a75b0ae 100644 (file)
@@ -132,7 +132,13 @@ private:
 
   
   //! is internally used in the algorithm.
-  Standard_EXPORT Standard_Boolean Compute (const BRepApprox_TheMultiLineOfApprox& Line, const Standard_Integer fpt, const Standard_Integer lpt, math_Vector& Para, Standard_Real& TheTol3d, Standard_Real& TheTol2d);
+  Standard_EXPORT Standard_Boolean Compute (const BRepApprox_TheMultiLineOfApprox& Line,
+                                            const Standard_Integer fpt,
+                                            const Standard_Integer lpt,
+                                            math_Vector& Para,
+                                            Standard_Real& TheTol3d,
+                                            Standard_Real& TheTol2d,
+                                            Standard_Integer& indbad);
   
   //! is internally used in the algorithm.
   Standard_EXPORT Standard_Boolean ComputeCurve (const BRepApprox_TheMultiLineOfApprox& Line, const Standard_Integer firspt, const Standard_Integer lastpt);
@@ -173,6 +179,7 @@ private:
   AppParCurves_Constraint myfirstC;
   AppParCurves_Constraint mylastC;
   Standard_Integer myMultiLineNb;
+  Standard_Integer myNbPlusOnePoint;
   Standard_Boolean myIsClear;
 
 
index d711bc0..4f2e336 100644 (file)
@@ -53,16 +53,34 @@ public:
   Standard_EXPORT BRepApprox_TheImpPrmSvSurfacesOfApprox(const IntSurf_Quadric& Surf1, const BRepAdaptor_Surface& Surf2);
   
   //! returns True if Tg,Tguv1 Tguv2 can be computed.
-  Standard_EXPORT Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2, gp_Pnt& Pt, gp_Vec& Tg, gp_Vec2d& Tguv1, gp_Vec2d& Tguv2);
+  Standard_EXPORT Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2,
+                                            gp_Pnt& Pt, gp_Vec& Tg, gp_Vec2d& Tguv1, gp_Vec2d& Tguv2);
   
   Standard_EXPORT void Pnt (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Pnt& P);
   
+  Standard_EXPORT Standard_Boolean SeekPoint(const Standard_Real u1,
+                                             const Standard_Real v1,
+                                             const Standard_Real u2,
+                                             const Standard_Real v2,
+                                             IntSurf_PntOn2S& Point);
+  
   Standard_EXPORT Standard_Boolean Tangency (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec& Tg);
   
   Standard_EXPORT Standard_Boolean TangencyOnSurf1 (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec2d& Tg);
   
   Standard_EXPORT Standard_Boolean TangencyOnSurf2 (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec2d& Tg);
 
+  Standard_Boolean FillInitialVectorOfSolution(const Standard_Real u1,
+                                               const Standard_Real v1,
+                                               const Standard_Real u2,
+                                               const Standard_Real v2,
+                                               const Standard_Real binfu,
+                                               const Standard_Real bsupu,
+                                               const Standard_Real binfv,
+                                               const Standard_Real bsupv,
+                                               math_Vector& X,
+                                               Standard_Real& TranslationU,
+                                               Standard_Real& TranslationV);
 
 
 
index 40d91b0..a8d89f4 100644 (file)
@@ -41,6 +41,8 @@ public:
 
   DEFINE_STANDARD_ALLOC
   
+  Standard_EXPORT BRepApprox_TheMultiLineOfApprox();
+  
   //! The class SvSurfaces is used when the approximation algorithm 
   //! needs some extra points on the line <line>. 
   //! A New line  is then created which shares the same surfaces and functions.
@@ -51,6 +53,8 @@ public:
                                                   const Standard_Address PtrSvSurfaces,
                                                   const Standard_Integer NbP3d,
                                                   const Standard_Integer NbP2d,
+                                                  const Standard_Boolean ApproxU1V1,
+                                                  const Standard_Boolean ApproxU2V2,
                                                   const Standard_Real xo,
                                                   const Standard_Real yo,
                                                   const Standard_Real zo,
@@ -66,6 +70,8 @@ public:
   Standard_EXPORT BRepApprox_TheMultiLineOfApprox(const Handle(BRepApprox_ApproxLine)& line,
                                                   const Standard_Integer NbP3d,
                                                   const Standard_Integer NbP2d,
+                                                  const Standard_Boolean ApproxU1V1,
+                                                  const Standard_Boolean ApproxU2V2,
                                                   const Standard_Real xo,
                                                   const Standard_Real yo,
                                                   const Standard_Real zo,
@@ -106,30 +112,42 @@ public:
   
   //! Returns the 3d and 2d points of the multipoint <MPointIndex>.
   Standard_EXPORT Standard_Boolean Tangency (const Standard_Integer MPointIndex, TColgp_Array1OfVec& tabV, TColgp_Array1OfVec2d& tabV2d) const;
+
+  //! Tries to make a sub-line between <Low> and <High> points of this line
+  //! by adding <NbPointsToInsert> new points
+  Standard_EXPORT BRepApprox_TheMultiLineOfApprox MakeMLBetween (const Standard_Integer Low,
+                                                                 const Standard_Integer High,
+                                                                 const Standard_Integer NbPointsToInsert) const;
   
-  Standard_EXPORT BRepApprox_TheMultiLineOfApprox MakeMLBetween (const Standard_Integer Low, const Standard_Integer High, const Standard_Integer NbPointsToInsert) const;
-  
+  //! Tries to make a sub-line between <Low> and <High> points of this line
+  //! by adding one more point between (indbad-1)-th and indbad-th points
+  Standard_EXPORT Standard_Boolean MakeMLOneMorePoint (const Standard_Integer Low,
+                                                       const Standard_Integer High,
+                                                       const Standard_Integer indbad,
+                                                       BRepApprox_TheMultiLineOfApprox& OtherLine) const;
+
   //! Dump of the current multi-line.
   Standard_EXPORT void Dump() const;
 
 protected:
-  BRepApprox_TheMultiLineOfApprox operator=(BRepApprox_TheMultiLineOfApprox&);
 
 private:
-  const Standard_Address PtrOnmySvSurfaces;
-  const Handle(BRepApprox_ApproxLine) myLine;
-  const Standard_Integer indicemin;
-  const Standard_Integer indicemax;
-  const Standard_Integer nbp3d;
-  const Standard_Integer nbp2d;
-  const Standard_Boolean p2donfirst;
-  const Standard_Real Xo;
-  const Standard_Real Yo;
-  const Standard_Real Zo;
-  const Standard_Real U1o;
-  const Standard_Real V1o;
-  const Standard_Real U2o;
-  const Standard_Real V2o;
+  Standard_Address PtrOnmySvSurfaces;
+  Handle(BRepApprox_ApproxLine) myLine;
+  Standard_Integer indicemin;
+  Standard_Integer indicemax;
+  Standard_Integer nbp3d;
+  Standard_Integer nbp2d;
+  Standard_Boolean myApproxU1V1;
+  Standard_Boolean myApproxU2V2;
+  Standard_Boolean p2donfirst;
+  Standard_Real Xo;
+  Standard_Real Yo;
+  Standard_Real Zo;
+  Standard_Real U1o;
+  Standard_Real V1o;
+  Standard_Real U2o;
+  Standard_Real V2o;
 
 };
 
index 4cceba1..1fcb02f 100644 (file)
@@ -92,6 +92,13 @@ public:
   //! Is called if WhatStatus returned "PointsAdded".
     static BRepApprox_TheMultiLineOfApprox MakeMLBetween (const BRepApprox_TheMultiLineOfApprox& ML, const Standard_Integer I1, const Standard_Integer I2, const Standard_Integer NbPMin);
   
+  //! Is called when the Bezier curve contains a loop
+    static Standard_Boolean MakeMLOneMorePoint (const BRepApprox_TheMultiLineOfApprox& ML,
+                                                const Standard_Integer I1,
+                                                const Standard_Integer I2,
+                                                const Standard_Integer indbad,
+                                                BRepApprox_TheMultiLineOfApprox& OtherLine);
+  
     static Approx_Status WhatStatus (const BRepApprox_TheMultiLineOfApprox& ML, const Standard_Integer I1, const Standard_Integer I2);
   
   //! Dump of the current multi-line.
index 76a35d6..97dcf4a 100644 (file)
@@ -50,10 +50,17 @@ public:
   Standard_EXPORT BRepApprox_ThePrmPrmSvSurfacesOfApprox(const BRepAdaptor_Surface& Surf1, const BRepAdaptor_Surface& Surf2);
   
   //! returns True if Tg,Tguv1 Tguv2 can be computed.
-  Standard_EXPORT Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2, gp_Pnt& Pt, gp_Vec& Tg, gp_Vec2d& Tguv1, gp_Vec2d& Tguv2);
+  Standard_EXPORT Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2,
+                                            gp_Pnt& Pt, gp_Vec& Tg, gp_Vec2d& Tguv1, gp_Vec2d& Tguv2);
   
   Standard_EXPORT void Pnt (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Pnt& P);
   
+  Standard_EXPORT Standard_Boolean SeekPoint(const Standard_Real u1,
+                                             const Standard_Real v1,
+                                             const Standard_Real u2,
+                                             const Standard_Real v2,
+                                             IntSurf_PntOn2S& Point);
+  
   Standard_EXPORT Standard_Boolean Tangency (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec& Tg);
   
   Standard_EXPORT Standard_Boolean TangencyOnSurf1 (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec2d& Tg);
index 7de0869..acc5e5d 100644 (file)
@@ -135,7 +135,13 @@ private:
 
   
   //! is internally used in the algorithm.
-  Standard_EXPORT Standard_Boolean Compute (const GeomInt_TheMultiLineOfWLApprox& Line, const Standard_Integer fpt, const Standard_Integer lpt, math_Vector& Para, Standard_Real& TheTol3d, Standard_Real& TheTol2d);
+  Standard_EXPORT Standard_Boolean Compute (const GeomInt_TheMultiLineOfWLApprox& Line,
+                                            const Standard_Integer fpt,
+                                            const Standard_Integer lpt,
+                                            math_Vector& Para,
+                                            Standard_Real& TheTol3d,
+                                            Standard_Real& TheTol2d,
+                                            Standard_Integer& indbad);
   
   //! is internally used in the algorithm.
   Standard_EXPORT Standard_Boolean ComputeCurve (const GeomInt_TheMultiLineOfWLApprox& Line, const Standard_Integer firspt, const Standard_Integer lastpt);
@@ -176,6 +182,7 @@ private:
   AppParCurves_Constraint myfirstC;
   AppParCurves_Constraint mylastC;
   Standard_Integer myMultiLineNb;
+  Standard_Integer myNbPlusOnePoint;
   Standard_Boolean myIsClear;
 
 
index 6fd664e..3d9bdff 100644 (file)
@@ -53,17 +53,34 @@ public:
   Standard_EXPORT GeomInt_TheImpPrmSvSurfacesOfWLApprox(const IntSurf_Quadric& Surf1, const Handle(Adaptor3d_HSurface)& Surf2);
   
   //! returns True if Tg,Tguv1 Tguv2 can be computed.
-  Standard_EXPORT Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2, gp_Pnt& Pt, gp_Vec& Tg, gp_Vec2d& Tguv1, gp_Vec2d& Tguv2);
+  Standard_EXPORT Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2,
+                                            gp_Pnt& Pt, gp_Vec& Tg, gp_Vec2d& Tguv1, gp_Vec2d& Tguv2);
   
   Standard_EXPORT void Pnt (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Pnt& P);
   
+  Standard_EXPORT Standard_Boolean SeekPoint(const Standard_Real u1,
+                                             const Standard_Real v1,
+                                             const Standard_Real u2,
+                                             const Standard_Real v2,
+                                             IntSurf_PntOn2S& Point);
+  
   Standard_EXPORT Standard_Boolean Tangency (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec& Tg);
   
   Standard_EXPORT Standard_Boolean TangencyOnSurf1 (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec2d& Tg);
   
   Standard_EXPORT Standard_Boolean TangencyOnSurf2 (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec2d& Tg);
 
-
+  Standard_Boolean FillInitialVectorOfSolution(const Standard_Real u1,
+                                               const Standard_Real v1,
+                                               const Standard_Real u2,
+                                               const Standard_Real v2,
+                                               const Standard_Real binfu,
+                                               const Standard_Real bsupu,
+                                               const Standard_Real binfv,
+                                               const Standard_Real bsupv,
+                                               math_Vector& X,
+                                               Standard_Real& TranslationU,
+                                               Standard_Real& TranslationV);
 
 
 protected:
index 78095b2..619598d 100644 (file)
@@ -41,6 +41,8 @@ public:
 
   DEFINE_STANDARD_ALLOC
 
+  Standard_EXPORT GeomInt_TheMultiLineOfWLApprox();
+  
   //! The class SvSurfaces is used when the approximation algorithm 
   //! needs some extra points on the line <line>. 
   //! A New line  is then created which shares the same surfaces and functions.
@@ -51,6 +53,8 @@ public:
                                                   const Standard_Address PtrSvSurfaces,
                                                   const Standard_Integer NbP3d,
                                                   const Standard_Integer NbP2d,
+                                                  const Standard_Boolean ApproxU1V1,
+                                                  const Standard_Boolean ApproxU2V2,
                                                   const Standard_Real xo,
                                                   const Standard_Real yo,
                                                   const Standard_Real zo,
@@ -66,6 +70,8 @@ public:
   Standard_EXPORT GeomInt_TheMultiLineOfWLApprox( const Handle(IntPatch_WLine)& line,
                                                   const Standard_Integer NbP3d,
                                                   const Standard_Integer NbP2d,
+                                                  const Standard_Boolean ApproxU1V1,
+                                                  const Standard_Boolean ApproxU2V2,
                                                   const Standard_Real xo,
                                                   const Standard_Real yo,
                                                   const Standard_Real zo,
@@ -112,8 +118,19 @@ public:
   //! Returns the 3d and 2d points of the multipoint <MPointIndex>.
   Standard_EXPORT Standard_Boolean Tangency (const Standard_Integer MPointIndex, TColgp_Array1OfVec& tabV, TColgp_Array1OfVec2d& tabV2d) const;
   
-  Standard_EXPORT GeomInt_TheMultiLineOfWLApprox MakeMLBetween (const Standard_Integer Low, const Standard_Integer High, const Standard_Integer NbPointsToInsert) const;
+  //! Tries to make a sub-line between <Low> and <High> points of this line
+  //! by adding <NbPointsToInsert> new points
+  Standard_EXPORT GeomInt_TheMultiLineOfWLApprox MakeMLBetween (const Standard_Integer Low,
+                                                                const Standard_Integer High,
+                                                                const Standard_Integer NbPointsToInsert) const;
   
+  //! Tries to make a sub-line between <Low> and <High> points of this line
+  //! by adding one more point between (indbad-1)-th and indbad-th points
+  Standard_EXPORT Standard_Boolean MakeMLOneMorePoint (const Standard_Integer Low,
+                                                       const Standard_Integer High,
+                                                       const Standard_Integer indbad,
+                                                       GeomInt_TheMultiLineOfWLApprox& OtherLine) const;
+
   //! Dump of the current multi-line.
   Standard_EXPORT void Dump() const;
 
@@ -121,23 +138,24 @@ public:
 
 
 protected:
-  GeomInt_TheMultiLineOfWLApprox operator=(GeomInt_TheMultiLineOfWLApprox&);
 
 private:
-  const Standard_Address PtrOnmySvSurfaces;
-  const Handle(IntPatch_WLine) myLine;
-  const Standard_Integer indicemin;
-  const Standard_Integer indicemax;
-  const Standard_Integer nbp3d;
-  const Standard_Integer nbp2d;
-  const Standard_Boolean p2donfirst;
-  const Standard_Real Xo;
-  const Standard_Real Yo;
-  const Standard_Real Zo;
-  const Standard_Real U1o;
-  const Standard_Real V1o;
-  const Standard_Real U2o;
-  const Standard_Real V2o;
+  Standard_Address PtrOnmySvSurfaces;
+  Handle(IntPatch_WLine) myLine;
+  Standard_Integer indicemin;
+  Standard_Integer indicemax;
+  Standard_Integer nbp3d;
+  Standard_Integer nbp2d;
+  Standard_Boolean myApproxU1V1;
+  Standard_Boolean myApproxU2V2;
+  Standard_Boolean p2donfirst;
+  Standard_Real Xo;
+  Standard_Real Yo;
+  Standard_Real Zo;
+  Standard_Real U1o;
+  Standard_Real V1o;
+  Standard_Real U2o;
+  Standard_Real V2o;
 
 
 };
index 565c1e2..3d6e8b0 100644 (file)
@@ -92,6 +92,13 @@ public:
   //! Is called if WhatStatus returned "PointsAdded".
     static GeomInt_TheMultiLineOfWLApprox MakeMLBetween (const GeomInt_TheMultiLineOfWLApprox& ML, const Standard_Integer I1, const Standard_Integer I2, const Standard_Integer NbPMin);
   
+  //! Is called when the Bezier curve contains a loop
+    static Standard_Boolean MakeMLOneMorePoint (const GeomInt_TheMultiLineOfWLApprox& ML,
+                                                const Standard_Integer I1,
+                                                const Standard_Integer I2,
+                                                const Standard_Integer indbad,
+                                                GeomInt_TheMultiLineOfWLApprox& OtherLine);
+  
     static Approx_Status WhatStatus (const GeomInt_TheMultiLineOfWLApprox& ML, const Standard_Integer I1, const Standard_Integer I2);
   
   //! Dump of the current multi-line.
index 1c7cfe9..5c292fe 100644 (file)
@@ -50,10 +50,17 @@ public:
   Standard_EXPORT GeomInt_ThePrmPrmSvSurfacesOfWLApprox(const Handle(Adaptor3d_HSurface)& Surf1, const Handle(Adaptor3d_HSurface)& Surf2);
   
   //! returns True if Tg,Tguv1 Tguv2 can be computed.
-  Standard_EXPORT Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2, gp_Pnt& Pt, gp_Vec& Tg, gp_Vec2d& Tguv1, gp_Vec2d& Tguv2);
+  Standard_EXPORT Standard_Boolean Compute (Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2,
+                                            gp_Pnt& Pt, gp_Vec& Tg, gp_Vec2d& Tguv1, gp_Vec2d& Tguv2);
   
   Standard_EXPORT void Pnt (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Pnt& P);
   
+  Standard_EXPORT Standard_Boolean SeekPoint(const Standard_Real u1,
+                                             const Standard_Real v1,
+                                             const Standard_Real u2,
+                                             const Standard_Real v2,
+                                             IntSurf_PntOn2S& Point);
+  
   Standard_EXPORT Standard_Boolean Tangency (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec& Tg);
   
   Standard_EXPORT Standard_Boolean TangencyOnSurf1 (const Standard_Real u1, const Standard_Real v1, const Standard_Real u2, const Standard_Real v2, gp_Vec2d& Tg);
index e6fb054..1174606 100644 (file)
@@ -803,12 +803,20 @@ void PutPCurve(const TopoDS_Edge& Edg,
 
   S = BRep_Tool::Surface(Fac);
 
+  Standard_Real TolFirst = -1, TolLast = -1;
+  TopoDS_Vertex V1, V2;
+  TopExp::Vertices(Edg, V1, V2);
+  if (!V1.IsNull())
+    TolFirst = BRep_Tool::Tolerance(V1);
+  if (!V2.IsNull())
+    TolLast = BRep_Tool::Tolerance(V2);
+  
   Standard_Real tol2d = Precision::Confusion();
   Handle(Geom2d_Curve) C2d;
   ShapeConstruct_ProjectCurveOnSurface aToolProj;
   aToolProj.Init(S, tol2d);
 
-  aToolProj.Perform(C,f,l, C2d);
+  aToolProj.Perform(C,f,l,C2d,TolFirst,TolLast);
   if (C2d.IsNull())
   {
     return;
@@ -819,7 +827,6 @@ void PutPCurve(const TopoDS_Edge& Edg,
   gp_Pnt PF,PL;
   S->D0(pf.X(),pf.Y(),PF);
   S->D0(pl.X(),pl.Y(),PL);
-  TopoDS_Vertex V1,V2;
   if (Edg.Orientation() == TopAbs_REVERSED) {
     V1 = TopExp::LastVertex(Edg);
     V1.Reverse();
index 8b46dde..6411b7a 100644 (file)
@@ -376,8 +376,8 @@ Standard_Boolean ShapeAnalysis_Surface::ProjectDegenerated(const gp_Pnt& P3d,
 //=======================================================================
 
 Standard_Boolean ShapeAnalysis_Surface::ProjectDegenerated(const Standard_Integer nbrPnt,
-                                                          const TColgp_Array1OfPnt& points,
-                                                          TColgp_Array1OfPnt2d& pnt2d,
+                                                          const TColgp_SequenceOfPnt& points,
+                                                          TColgp_SequenceOfPnt2d& pnt2d,
                                                           const Standard_Real preci,
                                                           const Standard_Boolean direct)
 {
index e4ac811..e41fa2e 100644 (file)
@@ -29,8 +29,8 @@
 #include <gp_Pnt2d.hxx>
 #include <Bnd_Box.hxx>
 #include <MMgt_TShared.hxx>
-#include <TColgp_Array1OfPnt.hxx>
-#include <TColgp_Array1OfPnt2d.hxx>
+#include <TColgp_SequenceOfPnt.hxx>
+#include <TColgp_SequenceOfPnt2d.hxx>
 class Geom_Surface;
 class GeomAdaptor_HSurface;
 class Geom_Curve;
@@ -82,7 +82,8 @@ public:
   //! Reads all the data from another Surface, without recomputing
   Standard_EXPORT void Init (const Handle(ShapeAnalysis_Surface)& other);
   
-  Standard_EXPORT void SetDomain (const Standard_Real U1, const Standard_Real U2, const Standard_Real V1, const Standard_Real V2);
+  Standard_EXPORT void SetDomain (const Standard_Real U1, const Standard_Real U2,
+                                  const Standard_Real V1, const Standard_Real V2);
   
   //! Returns a surface being analyzed
     const Handle(Geom_Surface)& Surface() const;
@@ -138,7 +139,14 @@ public:
   //! uisodeg: if the degenerated iso-line is U-iso (True) or
   //! V-iso (False).
   //! Returns False if <num> is out of range, else returns True.
-  Standard_EXPORT Standard_Boolean Singularity (const Standard_Integer num, Standard_Real& preci, gp_Pnt& P3d, gp_Pnt2d& firstP2d, gp_Pnt2d& lastP2d, Standard_Real& firstpar, Standard_Real& lastpar, Standard_Boolean& uisodeg);
+  Standard_EXPORT Standard_Boolean Singularity (const Standard_Integer num,
+                                                Standard_Real& preci,
+                                                gp_Pnt& P3d,
+                                                gp_Pnt2d& firstP2d,
+                                                gp_Pnt2d& lastP2d,
+                                                Standard_Real& firstpar,
+                                                Standard_Real& lastpar,
+                                                Standard_Boolean& uisodeg);
   
   //! Returns True if there is at least one surface boundary which
   //! is considered as degenerated with <preci> and distance
@@ -152,7 +160,13 @@ public:
   //! <preci> (like IsDegenerated).
   //! Returns characteristics of the first found boundary matching
   //! those criteria.
-  Standard_EXPORT Standard_Boolean DegeneratedValues (const gp_Pnt& P3d, const Standard_Real preci, gp_Pnt2d& firstP2d, gp_Pnt2d& lastP2d, Standard_Real& firstpar, Standard_Real& lastpar, const Standard_Boolean forward = Standard_True);
+  Standard_EXPORT Standard_Boolean DegeneratedValues (const gp_Pnt& P3d,
+                                                      const Standard_Real preci,
+                                                      gp_Pnt2d& firstP2d,
+                                                      gp_Pnt2d& lastP2d,
+                                                      Standard_Real& firstpar,
+                                                      Standard_Real& lastpar,
+                                                      const Standard_Boolean forward = Standard_True);
   
   //! Projects a point <P3d> on a singularity by computing
   //! one of the coordinates of preliminary computed <result>.
@@ -166,14 +180,20 @@ public:
   //! resolution (computed from <preci> by Geom_Adaptor).
   //! Then sets not yet computed <result>'s coordinate taking it
   //! from <neighbour> and returns True.
-  Standard_EXPORT Standard_Boolean ProjectDegenerated (const gp_Pnt& P3d, const Standard_Real preci, const gp_Pnt2d& neighbour, gp_Pnt2d& result);
+  Standard_EXPORT Standard_Boolean ProjectDegenerated (const gp_Pnt& P3d,
+                                                       const Standard_Real preci,
+                                                       const gp_Pnt2d& neighbour,
+                                                       gp_Pnt2d& result);
   
   //! Checks points at the beginning (direct is True) or end
   //! (direct is False) of array <points> to lie in singularity of
   //! surface, and if yes, adjusts the indeterminate 2d coordinate
   //! of these points by nearest point which is not in singularity.
   //! Returns True if some points were adjusted.
-  Standard_EXPORT Standard_Boolean ProjectDegenerated (const Standard_Integer nbrPnt, const TColgp_Array1OfPnt& points, TColgp_Array1OfPnt2d& pnt2d, const Standard_Real preci, const Standard_Boolean direct);
+  Standard_EXPORT Standard_Boolean ProjectDegenerated (const Standard_Integer nbrPnt,
+                                                       const TColgp_SequenceOfPnt& points,
+                                                       TColgp_SequenceOfPnt2d& pnt2d,
+                                                       const Standard_Real preci, const Standard_Boolean direct);
   
   //! Returns True if straight pcurve going from point p2d1 to p2d2
   //! is degenerate, i.e. lies in the singularity of the surface.
@@ -188,11 +208,15 @@ public:
   //! the Resolution computed from max distance in 3d
   //! (max3d < tol && max2d > ratio * Resolution(max3d))
   //! NOTE: <ratio> should be >1 (e.g. 10)
-  Standard_EXPORT Standard_Boolean IsDegenerated (const gp_Pnt2d& p2d1, const gp_Pnt2d& p2d2, const Standard_Real tol, const Standard_Real ratio);
+  Standard_EXPORT Standard_Boolean IsDegenerated (const gp_Pnt2d& p2d1,
+                                                  const gp_Pnt2d& p2d2,
+                                                  const Standard_Real tol,
+                                                  const Standard_Real ratio);
   
   //! Returns the bounds of the surface
   //! (from Bounds from Surface, but buffered)
-    void Bounds (Standard_Real& ufirst, Standard_Real& ulast, Standard_Real& vfirst, Standard_Real& vlast) const;
+    void Bounds (Standard_Real& ufirst, Standard_Real& ulast,
+                 Standard_Real& vfirst, Standard_Real& vlast) const;
   
   //! Computes bound isos (protected against exceptions)
   Standard_EXPORT void ComputeBoundIsos();
@@ -257,7 +281,10 @@ public:
   //! P3D is greater than <maxpreci>, that solution is considered
   //! as bad, and ValueOfUV() is used.
   //! If not succeded, calls ValueOfUV()
-  Standard_EXPORT gp_Pnt2d NextValueOfUV (const gp_Pnt2d& p2dPrev, const gp_Pnt& P3D, const Standard_Real preci, const Standard_Real maxpreci = -1.0);
+  Standard_EXPORT gp_Pnt2d NextValueOfUV (const gp_Pnt2d& p2dPrev,
+                                          const gp_Pnt& P3D,
+                                          const Standard_Real preci,
+                                          const Standard_Real maxpreci = -1.0);
   
   //! Tries a refinement of an already computed couple (U,V) by
   //! using projecting 3D point on iso-lines:
@@ -268,7 +295,10 @@ public:
   //! direction)
   //! Returns the best resulting distance between P3D and Value(U,V)
   //! in the case of success. Else, returns a very great value
-  Standard_EXPORT Standard_Real UVFromIso (const gp_Pnt& P3D, const Standard_Real preci, Standard_Real& U, Standard_Real& V);
+  Standard_EXPORT Standard_Real UVFromIso (const gp_Pnt& P3D,
+                                           const Standard_Real preci,
+                                           Standard_Real& U,
+                                           Standard_Real& V);
   
   //! Returns minimum value to consider the surface as U-closed
     Standard_Real UCloseVal() const;
@@ -349,7 +379,10 @@ private:
   Standard_EXPORT void ComputeBoxes();
 
   //! @return 0, 1 or 2.
-  Standard_EXPORT Standard_Integer SurfaceNewton (const gp_Pnt2d& p2dPrev, const gp_Pnt& P3D, const Standard_Real preci, gp_Pnt2d& sol);
+  Standard_EXPORT Standard_Integer SurfaceNewton (const gp_Pnt2d& p2dPrev,
+                                                  const gp_Pnt& P3D,
+                                                  const Standard_Real preci,
+                                                  gp_Pnt2d& sol);
 
   Standard_EXPORT void SortSingularities();
 
index 14e52f4..507a00b 100644 (file)
@@ -58,6 +58,7 @@
 #include <GeomAPI_PointsToBSpline.hxx>
 #include <GeomProjLib.hxx>
 #include <gp_Pnt2d.hxx>
+#include <ElCLib.hxx>
 #include <NCollection_Sequence.hxx>
 #include <Precision.hxx>
 #include <ProjLib_CompProjectedCurve.hxx>
 #include <Standard_Type.hxx>
 #include <TColgp_Array1OfPnt.hxx>
 #include <TColStd_Array1OfInteger.hxx>
+#include <IntRes2d_Domain.hxx>
+#include <IntCurve_IntConicConic.hxx>
 
 #include <algorithm>
 IMPLEMENT_STANDARD_RTTIEXT(ShapeConstruct_ProjectCurveOnSurface,MMgt_TShared)
 
 #define NCONTROL 23
 
+
+static void AdjustSecondPointToFirstPoint(const gp_Pnt2d& theFirstPoint,
+                                          gp_Pnt2d& theSecondPoint,
+                                          const Handle(Geom_Surface)& theSurf)
+{
+  if (theSurf->IsUPeriodic())
+  {
+    Standard_Real UPeriod = theSurf->UPeriod();
+    Standard_Real NewU = ElCLib::InPeriod(theSecondPoint.X(),
+                                          theFirstPoint.X() - UPeriod/2,
+                                          theFirstPoint.X() + UPeriod/2);
+    theSecondPoint.SetX(NewU);
+  }
+  if (theSurf->IsVPeriodic())
+  {
+    Standard_Real VPeriod = theSurf->VPeriod();
+    Standard_Real NewV = ElCLib::InPeriod(theSecondPoint.Y(),
+                                          theFirstPoint.Y() - VPeriod/2,
+                                          theFirstPoint.Y() + VPeriod/2);
+    theSecondPoint.SetY(NewV);
+  }
+}
+
+
 //=======================================================================
 //function : ShapeConstruct_ProjectCurveOnSurface
 //purpose  : 
@@ -167,29 +194,6 @@ ShapeConstruct_ProjectCurveOnSurface::ShapeConstruct_ProjectCurveOnSurface()
    return myAdjustOverDegen;
  }
 
-
-//=======================================================================
-//function : NbSurfIntervals
-//purpose  : work-around of bug in standard method 
-//           GeomAdaptor_Surface->NbIntervals() (PRO16346)
-//=======================================================================
-
-static Standard_Integer NbSurfIntervals(const Handle(GeomAdaptor_HSurface)& GAS, const GeomAbs_Shape cont)
-{
-  Standard_Integer NbU = 0;
-  if (GAS->GetType() == GeomAbs_SurfaceOfExtrusion) {
-    // extract the surface
-    Handle(Geom_SurfaceOfLinearExtrusion) surf = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(GAS->ChangeSurface().Surface());
-    // build a 3d adaptor curve
-    GeomAdaptor_Curve Adaptor3dCurve(surf->BasisCurve(), GAS->FirstUParameter(), GAS->LastUParameter());
-    if (Adaptor3dCurve.GetType() == GeomAbs_BSplineCurve)
-      NbU = Adaptor3dCurve.NbIntervals(cont);
-  }
-  if (NbU == 0)
-    NbU = GAS->NbUIntervals(cont);
-  return NbU * (GAS->NbVIntervals(cont));
-}
-
 //=======================================================================
 //function : Status
 //purpose  : 
@@ -208,9 +212,8 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::Perform (Handle(Geom_Curv
                                                                 const Standard_Real First,
                                                                 const Standard_Real Last,
                                                                 Handle(Geom2d_Curve)& c2d,
-                                                                const GeomAbs_Shape,
-                                                                const Standard_Integer,
-                                                                const Standard_Integer)
+                                                                const Standard_Real TolFirst,
+                                                                const Standard_Real TolLast)
 {
   myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
   //Standard_Boolean OK = Standard_True; //szv#4:S4163:12Mar99 not needed
@@ -251,7 +254,10 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::Perform (Handle(Geom_Curv
   if ( ! bspl.IsNull() ) {
     Standard_Integer nint = 0;
     for ( Standard_Integer i=1; i < bspl->NbKnots(); i++ )
-      if ( bspl->Knot(i+1) > First && bspl->Knot(i) < Last ) nint++;
+    {
+      if ( bspl->Knot(i+1) > First && bspl->Knot(i) < Last )
+        nint++;
+    }
     Standard_Integer minPnt = nint * ( bspl->Degree() + 1 );
     while ( nbPini < minPnt ) nbPini += NCONTROL - 1;
 #ifdef OCCT_DEBUG
@@ -263,8 +269,8 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::Perform (Handle(Geom_Curv
 //    $$$$    end :92 (big BSplineCurve C0)
   
   // this number should be "parametric dependent"
-  TColgp_Array1OfPnt points(1, nbPini);
-  TColStd_Array1OfReal params(1, nbPini);
+  TColgp_SequenceOfPnt points;
+  TColStd_SequenceOfReal params;
   NCollection_Sequence<Standard_Real> aKnotCoeffs;
   gp_Pnt p3d;
   Standard_Integer iPnt;
@@ -363,13 +369,15 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::Perform (Handle(Geom_Curv
     else                     t = First + (iPnt - 1) * deltaT;
 
     c3d->D0 (t, p3d);
-    points(iPnt) = p3d;
-    params(iPnt) = t;
+    points.Append(p3d);
+    params.Append(t);
   }
 
   //  CALCUL par approximation
-  TColgp_Array1OfPnt2d pnt2d(1, nbrPnt);
-  ApproxPCurve (nbrPnt,points,params,pnt2d,c2d); //szv#4:S4163:12Mar99 OK not needed
+  TColgp_SequenceOfPnt2d pnt2d;
+  ApproxPCurve (nbrPnt,c3d,TolFirst,TolLast,
+                points,params,pnt2d,c2d); //szv#4:S4163:12Mar99 OK not needed
+  nbPini = points.Length();
   if (!c2d.IsNull()) {
     myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE2);
     return Standard_True;
@@ -484,36 +492,6 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformByProjLib(Handle(G
 }
 
 //=======================================================================
-//function : PerformAdvanced
-//purpose  : 
-//=======================================================================
-
-Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(Geom_Curve)& c3d,
-                                                                       const Standard_Real First,
-                                                                       const Standard_Real Last,
-                                                                       Handle(Geom2d_Curve)& c2d)
-{
-  Standard_Boolean hasResult = Standard_False;
-  Standard_Integer nbintervals;
-  
-  Standard_Boolean isStandard = (mySurf->Adaptor3d()->GetType() != GeomAbs_Cylinder);
-// &&   (mySurf->Adaptor3d()->GetType() != GeomAbs_SurfaceOfRevolution);
-
-  if (isStandard) isStandard = !mySurf->HasSingularities(myPreci);
-  if (isStandard) {
-    Handle(GeomAdaptor_HSurface) GAS = mySurf->Adaptor3d();
-    Handle(GeomAdaptor_HCurve) GAC = new GeomAdaptor_HCurve (c3d,First,Last);
-    nbintervals = NbSurfIntervals(GAS, GeomAbs_C1);//+GAC->NbIntervals(GeomAbs_C3);
-    isStandard = (nbintervals < 2);
-  }
-  if (isStandard) {
-    hasResult = PerformByProjLib(c3d, First, Last, c2d);
-  }
-  if (!hasResult) hasResult = Perform (c3d, First, Last, c2d);
-  return hasResult;
-}
-
-//=======================================================================
 //function : ProjectAnalytic
 //purpose  : 
 //=======================================================================
@@ -665,9 +643,9 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
 //=======================================================================
 
  Handle(Geom2d_Curve) ShapeConstruct_ProjectCurveOnSurface::getLine(
-   const TColgp_Array1OfPnt& thepoints,
-   const TColStd_Array1OfReal& theparams,
-   TColgp_Array1OfPnt2d& thePnt2ds,
+   const TColgp_SequenceOfPnt& thepoints,
+   const TColStd_SequenceOfReal& theparams,
+   TColgp_SequenceOfPnt2d& thePnt2ds,
    Standard_Real theTol,
    Standard_Boolean &isRecompute,
    Standard_Boolean &isFromCashe) const 
@@ -703,7 +681,7 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
    for( ; i < 4; i +=3)
    {
      Standard_Integer j;
-     for (j = 0; j < myNbCashe; ++j)
+     for (j = 0; j < myNbCashe; j++)
      {
        if ( myCashe3d[j].SquareDistance (aP[i] ) < aTol2)
        {
@@ -715,27 +693,23 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
          break;
        }
      }
-
+     
      if (j >= myNbCashe)
-     {
        aP2d[i] = mySurf->ValueOfUV(aP[i], theTol);
-     }
-
+     
      Standard_Real aDist = mySurf->Gap();
      Standard_Real aCurDist = aDist * aDist;
-     if (aTol2 < aDist * aDist)
-     {
+     if( aTol2 < aDist * aDist)
        aTol2 = aCurDist;
-     }
    }
-
+   
    if ( isPeriodicU || isPeriodicV )
    {
      // Compute second and last but one c2d points.
      for(i = 1; i < 3; i++)
      {
        Standard_Integer j;
-       for (j = 0; j < myNbCashe; ++j)
+       for (j = 0; j < myNbCashe; j++)
        {
          if ( myCashe3d[j].SquareDistance (aP[i] ) < aTol2)
          {
@@ -745,18 +719,14 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
            break;
          }
        }
-
+       
        if (j >= myNbCashe)
-       {
          aP2d[i] = mySurf->ValueOfUV(aP[i], theTol);
-       }
-
+       
        Standard_Real aDist = mySurf->Gap();
        Standard_Real aCurDist = aDist * aDist;
-       if (aTol2 < aDist * aDist)
-       {
+       if( aTol2 < aDist * aDist)
          aTol2 = aCurDist;
-       }
      }
 
      if (isPeriodicU)
@@ -858,14 +828,22 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
 //=======================================================================
 
   Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::ApproxPCurve(const Standard_Integer nbrPnt,
-                                                                    const TColgp_Array1OfPnt& points,
-                                                                    const TColStd_Array1OfReal& params,
-                                                                    TColgp_Array1OfPnt2d& pnt2d,
-                                                                    Handle(Geom2d_Curve)& c2d) 
+                                                                      const Handle(Geom_Curve)& c3d,
+                                                                      const Standard_Real TolFirst,
+                                                                      const Standard_Real TolLast,
+                                                                      TColgp_SequenceOfPnt& points,
+                                                                      TColStd_SequenceOfReal& params,
+                                                                      TColgp_SequenceOfPnt2d& pnt2d,
+                                                                      Handle(Geom2d_Curve)& c2d) 
 {
   // for performance, first try to handle typical case when pcurve is straight
   Standard_Boolean isRecompute = Standard_False;
   Standard_Boolean isFromCasheLine = Standard_False;
+  for (Standard_Integer iseq = 1; iseq <= nbrPnt; iseq++)
+  {
+    gp_Pnt2d aP2d(0.,0.);
+    pnt2d.Append(aP2d);
+  }
   c2d = getLine(points, params, pnt2d, myPreci, isRecompute, isFromCasheLine);
   if(!c2d.IsNull())
   {
@@ -914,7 +892,6 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
   
   gp_Pnt p3d;
   gp_Pnt2d p2d;
-  Standard_Integer i;
   Standard_Real isoValue=0., isoPar1=0., isoPar2=0., tPar=0., tdeb,tfin;
   Standard_Real Cf, Cl, parf, parl; //szv#4:S4163:12Mar99 dist not needed
   
@@ -1007,29 +984,26 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
       ChangeCycle = Standard_True;
   //for( i = 1; i <= nbrPnt; i ++) {
   for(Standard_Integer ii=1; ii<=nbrPnt; ii++) {
-    if(ChangeCycle) //skl for OCC3430
-      i=nbrPnt-ii+1;
-    else
-      i=ii;
-    p3d = points(i);
+    const Standard_Integer aPntIndex = ChangeCycle ? (nbrPnt - ii + 1) : ii;
+    p3d = points (aPntIndex);
     if (isoParam) {
       
       if (isoPar2d3d) {
-       if (isoPar2 > isoPar1) tPar = params(i);
-       else                   tPar = t1 + t2 - params(i);
+       if (isoPar2 > isoPar1) tPar = params (aPntIndex);
+       else                   tPar = t1 + t2 - params(aPntIndex);
       } else if (!isAnalytic) {
        // projection to iso
-       if      (i==1)      tPar = isoPar1;
-       else if (i==nbrPnt) tPar = isoPar2;
+       if      (aPntIndex == 1)      tPar = isoPar1;
+       else if (aPntIndex == nbrPnt) tPar = isoPar2;
        else {
-         tPar = pout(i);
+         tPar = pout(aPntIndex);
          //:S4030  ShapeAnalysis_Curve().Project (cIso,p3d,myPreci,pt,tPar,Cf,Cl); //szv#4:S4163:12Mar99 `dist=` not needed
        }
       }
       
       if (!isoPar2d3d && isAnalytic) {
-       if      (i == 1)      p2d = valueP1;
-       else if (i == nbrPnt) p2d = valueP2;
+       if      (aPntIndex == 1)      p2d = valueP1;
+       else if (aPntIndex == nbrPnt) p2d = valueP2;
         else {
          p2d = mySurf->NextValueOfUV(p2d,p3d, myPreci, //%12 pdn 15.02.99 optimizing
                                      Precision::Confusion()+1000*gap); //:q1
@@ -1042,17 +1016,17 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
     }
     
     else {
-      if     ( (i == 1)      && p1OnIso)  p2d = valueP1;
-      else if( (i == nbrPnt) && p2OnIso)  p2d = valueP2;
+      if     ( (aPntIndex == 1)      && p1OnIso)  p2d = valueP1;
+      else if( (aPntIndex == nbrPnt) && p2OnIso)  p2d = valueP2;
       else  {// general case (not an iso)  mais attention aux singularites !
         // first and last points are already computed by getLine()
-        if ( (i == 1 || i == nbrPnt))
+        if (aPntIndex == 1 || aPntIndex == nbrPnt)
         {
           if (!isRecompute)
           {
-            p2d = pnt2d(i);
+            p2d = pnt2d (aPntIndex);
             gap = mySurf->Gap();
-            if (i == 1) {
+            if (aPntIndex == 1) {
               isFromCashe = isFromCasheLine;
               aSavedPoint = p2d;
             }
@@ -1067,7 +1041,7 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
               if ( myCashe3d[j].SquareDistance ( p3d ) < myPreci*myPreci )
               {
                 p2d = mySurf->NextValueOfUV (myCashe2d[j], p3d, myPreci, Precision::Confusion()+gap);
-                if (i == 1)
+                if (aPntIndex == 1)
                 {
                   isFromCashe = Standard_True;
                   aSavedPoint = myCashe2d[j];
@@ -1088,12 +1062,12 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
        gap = mySurf->Gap();
       }
     }
-    pnt2d (i) = p2d;
+    pnt2d (aPntIndex) = p2d;
     if ( ii > 1 ) {
       if(ChangeCycle)
-        p2d.SetXY ( 2. * p2d.XY() - pnt2d(i+1).XY() );
+        p2d.SetXY ( 2. * p2d.XY() - pnt2d(aPntIndex + 1).XY() );
       else
-        p2d.SetXY ( 2. * p2d.XY() - pnt2d(i-1).XY() );
+        p2d.SetXY ( 2. * p2d.XY() - pnt2d(aPntIndex - 1).XY() );
     }
   }
 
@@ -1102,6 +1076,37 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
     mySurf->ProjectDegenerated(nbrPnt,points,pnt2d,myPreci,Standard_True);
     mySurf->ProjectDegenerated(nbrPnt,points,pnt2d,myPreci,Standard_False);
   }
+
+  //Check the extremities of 3d curve for coinciding with singularities of surf
+  //Standard_Integer NbSing = mySurf->NbSingularities(Precision::Confusion());
+  gp_Pnt PointFirst = points.First(), PointLast = points.Last();
+  Standard_Real aTolFirst = (TolFirst == -1)? Precision::Confusion() : TolFirst;
+  Standard_Real aTolLast  = (TolLast == -1)?  Precision::Confusion() : TolLast;
+  for (Standard_Integer i = 1; ; i++)
+  {
+    Standard_Real aPreci, aFirstPar, aLastPar;
+    gp_Pnt aP3d;
+    gp_Pnt2d aFirstP2d, aLastP2d;
+    Standard_Boolean IsUiso;
+    if (!mySurf->Singularity(i, aPreci, aP3d, aFirstP2d, aLastP2d, aFirstPar, aLastPar, IsUiso))
+      break;
+    if (aPreci <= Precision::Confusion() &&
+        PointFirst.Distance(aP3d) <= aTolFirst)
+    {
+      CorrectExtremity(c3d, params, pnt2d,
+                       Standard_True, //first point
+                       aFirstP2d,
+                       IsUiso);
+    }
+    if (aPreci <= Precision::Confusion() &&
+        PointLast.Distance(aP3d) <= aTolLast)
+    {
+      CorrectExtremity(c3d, params, pnt2d,
+                       Standard_False, //last point
+                       aFirstP2d,
+                       IsUiso);
+    }
+  }
   
   //  attention aux singularites ... (hors cas iso qui les traite deja)
   //  if (!isoParam) {
@@ -1118,6 +1123,8 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
   Standard_Real Up = ul - uf;
   Standard_Real Vp = vl - vf;
   Standard_Real dist2d;
+  const Standard_Real TolOnUPeriod = Precision::Confusion() * Up;
+  const Standard_Real TolOnVPeriod = Precision::Confusion() * Vp;
 #ifdef OCCT_DEBUG
   if (mySurf->IsUClosed(myPreci) && mySurf->IsVClosed(myPreci)) {//#78 rln 12.03.99 S4135
     cout << "WARNING : Recadrage incertain sur U & VClosed" << endl;
@@ -1151,19 +1158,21 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
     
     //:97 abv 1 Feb 98: treat case when curve is whole out of surface bounds
     Standard_Real minX = firstX, maxX = firstX;
+    Standard_Boolean ToAdjust = Standard_False;
     
     // On decalle toujours le suivant
-    for (i = 2; i <= nbrPnt; i++) {
-      //      dist2d = pnt2d (i-1).Distance(pnt2d (i));
-      Standard_Real CurX = pnt2d (i).X();
+    for (Standard_Integer aPntIter = 2; aPntIter <= pnt2d.Length(); ++aPntIter)
+    {
+      //      dist2d = pnt2d (aPntIter - 1).Distance(pnt2d (aPntIter));
+      Standard_Real CurX = pnt2d (aPntIter).X();
       dist2d = Abs (CurX - prevX);
-      if (dist2d > ( Up / 2) ) {
-       if        (CurX > prevX + Up/2) {
-         while (CurX > prevX + Up/2) {  CurX -= Up;  pnt2d (i).SetX (CurX);  }
-       } else if (CurX < prevX - Up/2) {
-         while (CurX < prevX - Up/2) {  CurX += Up;  pnt2d (i).SetX (CurX);  }
-       }
-       
+      if (dist2d > ( Up / 2) )
+      {
+        InsertAdditionalPointOrAdjust(ToAdjust, 1, Up, TolOnUPeriod,
+                                      CurX, prevX,
+                                      c3d,
+                                      aPntIter,
+                                      points, params, pnt2d);
       }
       prevX = CurX;
       if ( minX > CurX ) minX = CurX;      //:97
@@ -1178,7 +1187,8 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
       if ( midX > ul ) shiftX = -Up;
       else if ( midX < uf ) shiftX = Up;
       if ( shiftX != 0. ) 
-        for ( i=1; i <= nbrPnt; i++ ) pnt2d(i).SetX ( pnt2d(i).X() + shiftX );
+        for (Standard_Integer aPntIter = 1; aPntIter <= pnt2d.Length(); ++aPntIter)
+          pnt2d (aPntIter).SetX ( pnt2d (aPntIter).X() + shiftX );
       }
   }
   // Si la surface est VCLosed, on recadre les points
@@ -1215,18 +1225,21 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
     
     //:97 abv 1 Feb 98: treat case when curve is whole out of surface bounds
     Standard_Real minY = firstY, maxY = firstY;
+    Standard_Boolean ToAdjust = Standard_False;
     
     // On decalle toujours le suivant
-    for (i = 2; i <= nbrPnt; i ++) {
+    for (Standard_Integer aPntIter = 2; aPntIter <= pnt2d.Length(); ++aPntIter)
+    {
       //      dist2d = pnt2d (i-1).Distance(pnt2d (i));
-      Standard_Real CurY = pnt2d (i).Y();
+      Standard_Real CurY = pnt2d (aPntIter).Y();
       dist2d = Abs (CurY - prevY);
-      if (dist2d > ( Vp / 2) ) {
-       if        (CurY > prevY + Vp/2) {
-         while (CurY > prevY + Vp/2) {  CurY -= Vp;  pnt2d (i).SetY (CurY);  }
-       } else if (CurY < prevY - Vp/2) {
-         while (CurY < prevY - Vp/2) {  CurY += Vp;  pnt2d (i).SetY (CurY);  }
-       }
+      if (dist2d > ( Vp / 2) )
+      {
+        InsertAdditionalPointOrAdjust(ToAdjust, 2, Vp, TolOnVPeriod,
+                                      CurY, prevY,
+                                      c3d,
+                                      aPntIter,
+                                      points, params, pnt2d);
       }
       prevY = CurY;
       if ( minY > CurY ) minY = CurY;      //:97
@@ -1241,16 +1254,17 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
       if ( midY > vl ) shiftY = -Vp;
       else if ( midY < vf ) shiftY = Vp;
       if ( shiftY != 0. ) 
-        for ( i=1; i <= nbrPnt; i++ ) pnt2d(i).SetY ( pnt2d(i).Y() + shiftY );
+        for (Standard_Integer aPntIter = 1; aPntIter <= pnt2d.Length(); ++aPntIter)
+          pnt2d(aPntIter).SetY ( pnt2d(aPntIter).Y() + shiftY );
       }
   }
   
   //#69 rln 01.03.99 S4135 bm2_sd_t4-A.stp entity 30
   //#78 rln 12.03.99 S4135
   if (mySurf->IsVClosed(myPreci) || mySurf->Surface()->IsKind (STANDARD_TYPE (Geom_SphericalSurface))) {
-    for (i = 2; i <= nbrPnt; i++) {
+    for (Standard_Integer aPntIter = 2; aPntIter <= pnt2d.Length(); ++aPntIter) {
       //#1 rln 11/02/98 ca_exhaust.stp entity #9869 dist2d = pnt2d (i-1).Distance(pnt2d (i));
-      dist2d = Abs (pnt2d(i).Y() - pnt2d(i - 1).Y());
+      dist2d = Abs (pnt2d (aPntIter).Y() - pnt2d (aPntIter - 1).Y());
       if (dist2d > ( Vp / 2) ) {
        // ATTENTION : il faut regarder ou le decalage se fait.
        // si plusieurs points sont decalles, il faut plusieurs passes
@@ -1266,10 +1280,10 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
        Standard_Boolean currOnLast  = Standard_False;
        
        //  .X ?  plutot .Y ,  non ?
-       Standard_Real distPrevVF = Abs(pnt2d (i-1).Y() - vf);
-       Standard_Real distPrevVL = Abs(pnt2d (i-1).Y() - vl);
-       Standard_Real distCurrVF = Abs(pnt2d (i).Y() - vf);
-       Standard_Real distCurrVL = Abs(pnt2d (i).Y() - vl);
+       Standard_Real distPrevVF = Abs(pnt2d (aPntIter - 1).Y() - vf);
+       Standard_Real distPrevVL = Abs(pnt2d (aPntIter - 1).Y() - vl);
+       Standard_Real distCurrVF = Abs(pnt2d (aPntIter).Y() - vf);
+       Standard_Real distCurrVL = Abs(pnt2d (aPntIter).Y() - vl);
        
        Standard_Real theMin = distPrevVF;
        prevOnFirst = Standard_True;
@@ -1293,28 +1307,28 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
        }
        //  Modifs RLN/Nijni  3-DEC-1997
        if (prevOnFirst) {
-         // on decalle le point (i-1) en V Last
-         gp_Pnt2d newPrev(pnt2d (i-1).X(), vf); // instead of  vl RLN/Nijni
-         pnt2d (i-1) = newPrev;
+         // on decalle le point (aPntIter - 1) en V Last
+         gp_Pnt2d newPrev(pnt2d (aPntIter - 1).X(), vf); // instead of  vl RLN/Nijni
+         pnt2d (aPntIter - 1) = newPrev;
        }
        else if (prevOnLast) {
-         // on decalle le point (i-1) en V first
-         gp_Pnt2d newPrev(pnt2d (i-1).X(), vl); // instead of  vf RLN/Nijni
-         pnt2d (i-1) = newPrev;
+         // on decalle le point (aPntIter - 1) en V first
+         gp_Pnt2d newPrev(pnt2d (aPntIter - 1).X(), vl); // instead of  vf RLN/Nijni
+         pnt2d (aPntIter - 1) = newPrev;
        }
        else if (currOnFirst) {
-         // on decalle le point (i) en V Last
-         gp_Pnt2d newCurr(pnt2d (i).X(),vf);  // instead of vl  RLN/Nijni
-         pnt2d (i) = newCurr;
+         // on decalle le point (aPntIter) en V Last
+         gp_Pnt2d newCurr(pnt2d (aPntIter).X(),vf);  // instead of vl  RLN/Nijni
+         pnt2d (aPntIter) = newCurr;
        }
        else if (currOnLast) {
-         // on decalle le point (i) en V First
-         gp_Pnt2d newCurr(pnt2d (i).X(), vl); // instead of vf  RLN/Nijni
-         pnt2d (i) = newCurr;
+         // on decalle le point (aPntIter) en V First
+         gp_Pnt2d newCurr(pnt2d (aPntIter).X(), vl); // instead of vf  RLN/Nijni
+         pnt2d (aPntIter) = newCurr;
        }
        // on verifie
 #ifdef OCCT_DEBUG
-       dist2d = pnt2d (i-1).Distance(pnt2d (i));
+       dist2d = pnt2d (aPntIter - 1).Distance(pnt2d (aPntIter));
        if (dist2d > ( Vp / 2) ) {
          cout << "Echec dans le recadrage" << endl;
        }
@@ -1348,7 +1362,7 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
        Standard_Integer OnBound=0, PrevOnBound=0;
        Standard_Integer ind; // svv #1
        Standard_Boolean start = Standard_True;
-       for ( ind=1; ind <= nbrPnt; ind++ ) {
+       for ( ind=1; ind <= pnt2d.Length(); ind++ ) {
          Standard_Real CurX = pnt2d(ind).X();
          // abv 16 Mar 00: trj3_s1-ug.stp #697: ignore points in singularity
          if ( mySurf->IsDegenerated ( points(ind), Precision::Confusion() ) )
@@ -1362,7 +1376,7 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
          PrevOnBound = OnBound;
        }
         // if found, adjust seam part
-        if ( ind <= nbrPnt ) {
+        if ( ind <= pnt2d.Length() ) {
          PrevX = ( myAdjustOverDegen ? uf : ul );
          Standard_Real dU = Up/2 + Precision::PConfusion();
          if ( PrevOnBound ) {
@@ -1375,7 +1389,7 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
          }
          else if ( OnBound ) {
            pnt2d(ind).SetX ( PrevX );
-           for ( Standard_Integer j=ind+1; j <= nbrPnt; j++ ) {
+           for ( Standard_Integer j=ind+1; j <= pnt2d.Length(); j++ ) {
              Standard_Real CurX = pnt2d(j).X();
              while ( CurX < PrevX - dU ) pnt2d(j).SetX ( CurX += Up );
              while ( CurX > PrevX + dU ) pnt2d(j).SetX ( CurX -= Up );
@@ -1393,7 +1407,7 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
        Standard_Integer OnBound=0, PrevOnBound=0;
        Standard_Integer ind; // svv #1
        Standard_Boolean start = Standard_True;
-       for ( ind=1; ind <= nbrPnt; ind++ ) {
+       for ( ind=1; ind <= pnt2d.Length(); ind++ ) {
          Standard_Real CurY = pnt2d(ind).Y();
          // abv 16 Mar 00: trj3_s1-ug.stp #697: ignore points in singularity
          if ( mySurf->IsDegenerated ( points(ind), Precision::Confusion() ) )
@@ -1407,7 +1421,7 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
          PrevOnBound = OnBound;
        }
         // if found, adjust seam part
-        if ( ind <= nbrPnt ) {
+        if ( ind <= pnt2d.Length() ) {
          PrevY = ( myAdjustOverDegen ? vf : vl );
          Standard_Real dV = Vp/2 + Precision::PConfusion();
          if ( PrevOnBound ) {
@@ -1420,7 +1434,7 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
          }
          else if ( OnBound ) {
            pnt2d(ind).SetY ( PrevY );
-           for ( Standard_Integer j=ind+1; j <= nbrPnt; j++ ) {
+           for ( Standard_Integer j=ind+1; j <= pnt2d.Length(); j++ ) {
              Standard_Real CurY = pnt2d(j).Y();
              while ( CurY < PrevY - dV ) pnt2d(j).SetY ( CurY += Vp );
              while ( CurY > PrevY + dV ) pnt2d(j).SetY ( CurY -= Vp );
@@ -1438,15 +1452,15 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(G
   //if(myCashe3d[0].Distance(points(1))>Precision::Confusion() &&
   //   myCashe3d[1].Distance(points(1))>Precision::Confusion()) {
     myCashe3d[0] = points(1);
-    myCashe3d[1] = points(nbrPnt);
+    myCashe3d[1] = points.Last();
     myCashe2d[0] = pnt2d(1);
-    myCashe2d[1] = pnt2d(nbrPnt);
+    myCashe2d[1] = pnt2d.Last();
   }
   else {
     myCashe3d[1] = points(1);
-    myCashe3d[0] = points(nbrPnt);
+    myCashe3d[0] = points.Last();
     myCashe2d[1] = pnt2d(1);
-    myCashe2d[0] = pnt2d(nbrPnt);
+    myCashe2d[0] = pnt2d.Last();
   }
   return isDone;
 }
@@ -1599,6 +1613,207 @@ Handle(Geom_Curve) ShapeConstruct_ProjectCurveOnSurface::InterpolateCurve3d(cons
   return C3d;
 }
 
+//============================================================================================
+//function : CorrectExtremity
+//purpose  : corrects first or last 2d point of future curve 
+//           in the case when it coincids with a singularity of surface
+//============================================================================================
+
+void ShapeConstruct_ProjectCurveOnSurface::CorrectExtremity(const Handle(Geom_Curve)& theC3d,
+                                                            const TColStd_SequenceOfReal& theParams,
+                                                            TColgp_SequenceOfPnt2d& thePnt2d,
+                                                            const Standard_Boolean theIsFirstPoint,
+                                                            const gp_Pnt2d& thePointOnIsoLine,
+                                                            const Standard_Boolean theIsUiso)
+{
+  Standard_Integer NbPnt = thePnt2d.Length();
+  Standard_Integer IndCoord = (theIsUiso)? 2 : 1;
+  Standard_Real SingularityCoord = thePointOnIsoLine.Coord(3-IndCoord);
+  gp_Pnt2d EndPoint = (theIsFirstPoint)? thePnt2d(1) : thePnt2d(NbPnt);
+  Standard_Real FinishCoord = EndPoint.Coord(3-IndCoord); //the constant coord of isoline
+  
+  gp_Dir2d aDir = (theIsUiso)? gp::DY2d() : gp::DX2d();
+  gp_Lin2d anIsoLine(EndPoint, aDir);
+  IntRes2d_Domain Dom1, Dom2;
+
+  Standard_Boolean IsPeriodic = (theIsUiso)?
+    mySurf->Surface()->IsVPeriodic() : mySurf->Surface()->IsUPeriodic();
+
+  gp_Pnt2d FirstPointOfLine, SecondPointOfLine;
+  Standard_Real FinishParam, FirstParam, SecondParam;
+
+  if (theIsFirstPoint)
+  {
+    FirstPointOfLine = thePnt2d(3);
+    SecondPointOfLine = thePnt2d(2);
+    FinishParam = theParams(1);
+    FirstParam = theParams(3);
+    SecondParam = theParams(2);
+  }
+  else //last point
+  {
+    FirstPointOfLine = thePnt2d(NbPnt-2);
+    SecondPointOfLine = thePnt2d(NbPnt-1);
+    FinishParam = theParams(NbPnt);
+    FirstParam = theParams(NbPnt-2);
+    SecondParam = theParams(NbPnt-1);
+  }
+
+  if (SingularityCoord > FinishCoord &&
+      SecondPointOfLine.Coord(3-IndCoord) > FinishCoord)
+    return; //the curve passes through the singularity, do nothing
+  if (SingularityCoord < FinishCoord &&
+      SecondPointOfLine.Coord(3-IndCoord) < FinishCoord)
+    return; //the curve passes through the singularity, do nothing
+  //Check correctness of <EndPoint>
+  {
+    const Standard_Real aPrevDist = Abs(SecondPointOfLine.Coord(IndCoord) - FirstPointOfLine.Coord(IndCoord));
+    const Standard_Real aCurDist  = Abs(EndPoint.Coord(IndCoord) - SecondPointOfLine.Coord(IndCoord));
+    if (aCurDist <= 2 * aPrevDist)
+      return;
+  }
+  
+  gp_Pnt2d FinishPoint = (theIsUiso)? gp_Pnt2d(FinishCoord, SecondPointOfLine.Y()) :
+    gp_Pnt2d(SecondPointOfLine.X(), FinishCoord); //first approximation of <FinishPoint>
+
+  for (;;)
+  {
+    if (Abs(SecondPointOfLine.Coord(3-IndCoord) - FinishCoord) <= 2*Precision::PConfusion())
+      break;
+
+    gp_Vec2d aVec(FirstPointOfLine, SecondPointOfLine);
+    Standard_Real aSqMagnitude = aVec.SquareMagnitude();
+    if (aSqMagnitude <= 1.e-32)
+      break;
+    aDir.SetCoord(aVec.X(), aVec.Y());
+    
+    gp_Lin2d aLine(FirstPointOfLine, aDir);
+    IntCurve_IntConicConic Intersector(anIsoLine, Dom1,
+                                       aLine,     Dom2,
+                                       1.e-10, 1.e-10);
+    if (Intersector.IsDone() && !Intersector.IsEmpty())
+    {
+      IntRes2d_IntersectionPoint IntPoint = Intersector.Point(1);
+      FinishPoint = IntPoint.Value();
+    }
+    else
+      FinishPoint = (theIsUiso)? gp_Pnt2d(FinishCoord, SecondPointOfLine.Y()) :
+        gp_Pnt2d(SecondPointOfLine.X(), FinishCoord);
+    
+    gp_Pnt2d PrevPoint = FirstPointOfLine;
+    FirstPointOfLine = SecondPointOfLine;
+    FirstParam = SecondParam;
+    SecondParam = (FirstParam + FinishParam)/2;
+    if (Abs(SecondParam - FirstParam) <= 2*Precision::PConfusion())
+      break;
+    gp_Pnt aP3d;
+    theC3d->D0(SecondParam, aP3d);
+    SecondPointOfLine = mySurf->NextValueOfUV(FirstPointOfLine, aP3d,
+                                              myPreci, Precision::Confusion());
+    if (IsPeriodic)
+      AdjustSecondPointToFirstPoint(FirstPointOfLine, SecondPointOfLine, mySurf->Surface());
+    
+    //Check <SecondPointOfLine> to be enough close to <FirstPointOfLine>
+    //because when a projected point is too close to singularity,
+    //the non-constant coordinate becomes random.
+    const Standard_Real aPrevDist = Abs(FirstPointOfLine.Coord(IndCoord) - PrevPoint.Coord(IndCoord));
+    const Standard_Real aCurDist  = Abs(SecondPointOfLine.Coord(IndCoord) - FirstPointOfLine.Coord(IndCoord));
+    if (aCurDist > 2 * aPrevDist)
+      break;
+  }
+
+  if (theIsFirstPoint)
+    thePnt2d(1) = FinishPoint;
+  else
+    thePnt2d(NbPnt) = FinishPoint;
+}
+
+//============================================================================================
+//function : InsertAdditionalPointOrAdjust
+//purpose  : If the current point is too far from the previous point 
+//           (more than half-period of surface), it can happen in two cases:
+//           1. Real current step on corresponding coordinate is small, all we need is adjust;
+//           2. Current step on corresponding coordinate is really bigger than half-period of
+//           surface in this parametric direction, so we must add additional point to exclude
+//           such big intervals between points in 2d space.
+//============================================================================================
+
+void ShapeConstruct_ProjectCurveOnSurface::
+InsertAdditionalPointOrAdjust(Standard_Boolean& ToAdjust,
+                              const Standard_Integer theIndCoord,
+                              const Standard_Real Period,
+                              const Standard_Real TolOnPeriod,
+                              Standard_Real& CurCoord,
+                              const Standard_Real prevCoord,
+                              const Handle(Geom_Curve)& c3d,
+                              Standard_Integer& theIndex,
+                              TColgp_SequenceOfPnt& points,
+                              TColStd_SequenceOfReal& params,
+                              TColgp_SequenceOfPnt2d& pnt2d)
+{
+  Standard_Real CorrectedCurCoord = ElCLib::InPeriod(CurCoord,
+                                                     prevCoord - Period/2,
+                                                     prevCoord + Period/2);
+  if (!ToAdjust)
+  {
+    Standard_Real CurPar = params(theIndex);
+    Standard_Real PrevPar = params(theIndex-1);
+    Standard_Real MidPar = (PrevPar + CurPar)/2;
+    gp_Pnt MidP3d;
+    c3d->D0(MidPar, MidP3d);
+    gp_Pnt2d MidP2d = mySurf->ValueOfUV(MidP3d, myPreci);
+    Standard_Real MidCoord = MidP2d.Coord(theIndCoord);
+    MidCoord = ElCLib::InPeriod(MidCoord, prevCoord - Period/2, prevCoord + Period/2);
+    Standard_Real FirstCoord = prevCoord, LastCoord = CorrectedCurCoord;
+    if (LastCoord < FirstCoord)
+    {Standard_Real tmp = FirstCoord; FirstCoord = LastCoord; LastCoord = tmp;}
+    if (LastCoord - FirstCoord <= TolOnPeriod)
+      ToAdjust = Standard_True;
+    else if (FirstCoord <= MidCoord && MidCoord <= LastCoord)
+      ToAdjust = Standard_True;
+    else //add mid point
+    {
+      //Standard_Real RefU = prevX;
+      Standard_Boolean Success = Standard_True;
+      Standard_Real FirstT = PrevPar; //params(i-1)
+      Standard_Real LastT  = CurPar;  //params(i)
+      MidCoord = MidP2d.Coord(theIndCoord);
+      while (Abs(MidCoord - prevCoord) >= Period/2 - TolOnPeriod ||
+             Abs(CurCoord - MidCoord) >= Period/2 - TolOnPeriod)
+      {
+        if (MidPar - FirstT <= Precision::PConfusion() ||
+            LastT - MidPar <= Precision::PConfusion())
+        {
+          Success = Standard_False;
+          break; //wrong choice
+        }
+        if (Abs(MidCoord - prevCoord) >= Period/2 - TolOnPeriod)
+          LastT = (FirstT + LastT)/2;
+        else
+          FirstT = (FirstT + LastT)/2;
+        MidPar = (FirstT + LastT)/2;
+        c3d->D0(MidPar, MidP3d);
+        MidP2d = mySurf->ValueOfUV(MidP3d, myPreci);
+        MidCoord = MidP2d.Coord(theIndCoord);
+      }
+      if (Success)
+      {
+        points.InsertBefore(theIndex, MidP3d);
+        params.InsertBefore(theIndex, MidPar);
+        pnt2d.InsertBefore(theIndex, MidP2d);
+        theIndex++;
+      }
+      else
+        ToAdjust = Standard_True; 
+    } //add mid point
+  } //if (!ToAdjust)
+  if (ToAdjust)
+  {
+    CurCoord = CorrectedCurCoord;
+    pnt2d(theIndex).SetCoord (theIndCoord, CurCoord);
+  }
+}
+
 //=======================================================================
 //function : CheckPoints
 //purpose  : 
@@ -1614,7 +1829,8 @@ Handle(Geom_Curve) ShapeConstruct_ProjectCurveOnSurface::InterpolateCurve3d(cons
 
   // will store 0 when the point is to be removed, 1 otherwise
   TColStd_Array1OfInteger tmpParam(firstElem, lastElem);
-  for (i = firstElem; i<=lastElem ; i++) tmpParam.SetValue(i,1);
+  for (i = firstElem; i<=lastElem ; i++)
+    tmpParam.SetValue(i,1);
   Standard_Real DistMin2 = RealLast();
   gp_Pnt Prev = points->Value (lastValid);
   gp_Pnt Curr;
@@ -1759,8 +1975,8 @@ Handle(Geom_Curve) ShapeConstruct_ProjectCurveOnSurface::InterpolateCurve3d(cons
 //:p9 abv 11 Mar 99: PRO7226 #489490: find nearest boundary instead of first one
 
  Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::IsAnIsoparametric(const Standard_Integer nbrPnt,
-                                                                         const TColgp_Array1OfPnt& points,
-                                                                         const TColStd_Array1OfReal& params,
+                                                                         const TColgp_SequenceOfPnt& points,
+                                                                         const TColStd_SequenceOfReal& params,
                                                                          Standard_Boolean& isoTypeU,
                                                                          Standard_Boolean& p1OnIso,
                                                                          gp_Pnt2d& valueP1,
index 0fc9b6c..6f2a46f 100644 (file)
 #include <MMgt_TShared.hxx>
 #include <ShapeExtend_Status.hxx>
 #include <GeomAbs_Shape.hxx>
-#include <TColgp_Array1OfPnt.hxx>
 #include <TColStd_Array1OfReal.hxx>
-#include <TColgp_Array1OfPnt2d.hxx>
 #include <TColgp_HArray1OfPnt2d.hxx>
-#include <TColStd_HArray1OfReal.hxx>
 #include <TColgp_HArray1OfPnt.hxx>
+#include <TColgp_SequenceOfPnt.hxx>
+#include <TColgp_SequenceOfPnt2d.hxx>
+#include <TColStd_SequenceOfReal.hxx>
 class ShapeAnalysis_Surface;
 class Geom_Surface;
 class Geom_Curve;
@@ -107,14 +107,17 @@ public:
   //! Computes the projection of 3d curve onto a surface using the
   //! specialized algorithm. Returns False if projector fails,
   //! otherwise, if pcurve computed successfully, returns True.
-  //! The continuity, maxdeg and nbinterval are parameters of call
-  //! to Approx_CurveOnSurface. If nbinterval is equal to -1
-  //! (default), this value is computed depending on source 3d curve
-  //! and surface. The output curve 2D is guaranteed to be same-parameter
+  //! The output curve 2D is guaranteed to be same-parameter
   //! with input curve 3D on the interval [First, Last]. If the output curve
   //! lies on a direct line the infinite line is returned, in the case
   //! same-parameter condition is satisfied.
-  Standard_EXPORT virtual Standard_Boolean Perform (Handle(Geom_Curve)& c3d, const Standard_Real First, const Standard_Real Last, Handle(Geom2d_Curve)& c2d, const GeomAbs_Shape continuity = GeomAbs_C1, const Standard_Integer maxdeg = 12, const Standard_Integer nbinterval = -1);
+  //! TolFirst and TolLast are the tolerances at the ends of input curve 3D.
+  Standard_EXPORT virtual Standard_Boolean Perform (Handle(Geom_Curve)& c3d,
+                                                    const Standard_Real First,
+                                                    const Standard_Real Last,
+                                                    Handle(Geom2d_Curve)& c2d,
+                                                    const Standard_Real TolFirst = -1,
+                                                    const Standard_Real TolLast  = -1);
   
   //! Computes the projection of 3d curve onto a surface using the
   //! standard algorithm from ProjLib. Returns False if standard
@@ -125,17 +128,14 @@ public:
   //! to Approx_CurveOnSurface. If nbinterval is equal to -1
   //! (default), this value is computed depending on source 3d curve
   //! and surface.
-  Standard_EXPORT Standard_Boolean PerformByProjLib (Handle(Geom_Curve)& c3d, const Standard_Real First, const Standard_Real Last, Handle(Geom2d_Curve)& c2d, const GeomAbs_Shape continuity = GeomAbs_C1, const Standard_Integer maxdeg = 12, const Standard_Integer nbinterval = -1);
+  Standard_EXPORT Standard_Boolean PerformByProjLib (Handle(Geom_Curve)& c3d,
+                                                     const Standard_Real First,
+                                                     const Standard_Real Last,
+                                                     Handle(Geom2d_Curve)& c2d,
+                                                     const GeomAbs_Shape continuity = GeomAbs_C1,
+                                                     const Standard_Integer maxdeg = 12,
+                                                     const Standard_Integer nbinterval = -1);
   
-  //! Computes the projection of 3d curve onto a surface using
-  //! either standard projector (method PerformByProjLib()) or
-  //! internal one (method Perform()). The selection is done by
-  //! analyzing the surface and 3d curve and is aimed to filter
-  //! the cases potentially dangerous for the standard projector.
-  //! If the standard projector fails, internal one is used.
-  Standard_EXPORT Standard_Boolean PerformAdvanced (Handle(Geom_Curve)& c3d, const Standard_Real First, const Standard_Real Last, Handle(Geom2d_Curve)& c2d);
-
-
 
 
   DEFINE_STANDARD_RTTIEXT(ShapeConstruct_ProjectCurveOnSurface,MMgt_TShared)
@@ -150,7 +150,12 @@ protected:
   //! points2d - 2d points lies on line in parametric space
   //! theTol - tolerance used for compare initial points 3d and
   //! 3d points obtained from line lying in parameric space of surface
-  Standard_EXPORT Handle(Geom2d_Curve) getLine (const TColgp_Array1OfPnt& points, const TColStd_Array1OfReal& params, TColgp_Array1OfPnt2d& points2d, const Standard_Real theTol, Standard_Boolean& IsRecompute, Standard_Boolean &isFromCashe) const;
+  Standard_EXPORT Handle(Geom2d_Curve) getLine (const TColgp_SequenceOfPnt& points,
+                                                const TColStd_SequenceOfReal& params,
+                                                TColgp_SequenceOfPnt2d& points2d,
+                                                const Standard_Real theTol,
+                                                Standard_Boolean& IsRecompute,
+                                                Standard_Boolean &isFromCashe) const;
 
   Handle(ShapeAnalysis_Surface) mySurf;
   Standard_Real myPreci;
@@ -167,9 +172,38 @@ private:
   
   Standard_EXPORT Handle(Geom2d_Curve) ProjectAnalytic (const Handle(Geom_Curve)& c3d) const;
   
-  Standard_EXPORT Standard_Boolean ApproxPCurve (const Standard_Integer nbrPnt, const TColgp_Array1OfPnt& points, const TColStd_Array1OfReal& params, TColgp_Array1OfPnt2d& points2d, Handle(Geom2d_Curve)& c2d);
-  
-  Standard_EXPORT Handle(Geom2d_Curve) InterpolatePCurve (const Standard_Integer nbrPnt, Handle(TColgp_HArray1OfPnt2d)& points2d, Handle(TColStd_HArray1OfReal)& params, const Handle(Geom_Curve)& orig) const;
+  Standard_EXPORT Standard_Boolean ApproxPCurve (const Standard_Integer nbrPnt,
+                                                 const Handle(Geom_Curve)& c3d,
+                                                 const Standard_Real TolFirst,
+                                                 const Standard_Real TolLast,
+                                                 TColgp_SequenceOfPnt& points,
+                                                 TColStd_SequenceOfReal& params,
+                                                 TColgp_SequenceOfPnt2d& points2d,
+                                                 Handle(Geom2d_Curve)& c2d);
+
+  Standard_EXPORT void CorrectExtremity(const Handle(Geom_Curve)& theC3d,
+                                        const TColStd_SequenceOfReal& theParams,
+                                        TColgp_SequenceOfPnt2d& thePnt2d,
+                                        const Standard_Boolean theIsFirstPoint,
+                                        const gp_Pnt2d& thePointOnIsoLine,
+                                        const Standard_Boolean theIsUiso);
+  
+  Standard_EXPORT void InsertAdditionalPointOrAdjust(Standard_Boolean& ToAdjust,
+                                                     const Standard_Integer theIndCoord,
+                                                     const Standard_Real Period,
+                                                     const Standard_Real TolOnPeriod,
+                                                     Standard_Real& CurCoord,
+                                                     const Standard_Real prevCoord,
+                                                     const Handle(Geom_Curve)& c3d,
+                                                     Standard_Integer& theIndex,
+                                                     TColgp_SequenceOfPnt& points,
+                                                     TColStd_SequenceOfReal& params,
+                                                     TColgp_SequenceOfPnt2d& pnt2d);
+  
+  Standard_EXPORT Handle(Geom2d_Curve) InterpolatePCurve (const Standard_Integer nbrPnt,
+                                                          Handle(TColgp_HArray1OfPnt2d)& points2d,
+                                                          Handle(TColStd_HArray1OfReal)& params,
+                                                          const Handle(Geom_Curve)& orig) const;
   
   Standard_EXPORT Handle(Geom2d_Curve) ApproximatePCurve (const Standard_Integer nbrPnt, Handle(TColgp_HArray1OfPnt2d)& points2d, Handle(TColStd_HArray1OfReal)& params, const Handle(Geom_Curve)& orig) const;
   
@@ -179,7 +213,19 @@ private:
   
   Standard_EXPORT void CheckPoints2d (Handle(TColgp_HArray1OfPnt2d)& points, Handle(TColStd_HArray1OfReal)& params, Standard_Real& preci) const;
   
-  Standard_EXPORT Standard_Boolean IsAnIsoparametric (const Standard_Integer nbrPnt, const TColgp_Array1OfPnt& points, const TColStd_Array1OfReal& params, Standard_Boolean& isoTypeU, Standard_Boolean& p1OnIso, gp_Pnt2d& valueP1, Standard_Boolean& p2OnIso, gp_Pnt2d& valueP2, Standard_Boolean& isoPar2d3d, Handle(Geom_Curve)& cIso, Standard_Real& t1, Standard_Real& t2, TColStd_Array1OfReal& pout) const;
+  Standard_EXPORT Standard_Boolean IsAnIsoparametric (const Standard_Integer nbrPnt,
+                                                      const TColgp_SequenceOfPnt& points,
+                                                      const TColStd_SequenceOfReal& params,
+                                                      Standard_Boolean& isoTypeU,
+                                                      Standard_Boolean& p1OnIso,
+                                                      gp_Pnt2d& valueP1,
+                                                      Standard_Boolean& p2OnIso,
+                                                      gp_Pnt2d& valueP2,
+                                                      Standard_Boolean& isoPar2d3d,
+                                                      Handle(Geom_Curve)& cIso,
+                                                      Standard_Real& t1,
+                                                      Standard_Real& t2,
+                                                      TColStd_Array1OfReal& pout) const;
 
 
 
index 830865f..34f43ba 100644 (file)
@@ -489,8 +489,16 @@ Standard_Boolean ShapeFix_Edge::FixAddPCurve (const TopoDS_Edge& edge,
     Handle(Geom2d_Curve) c2d;
     Standard_Real a1, b1;
     if ( ! sae.HasPCurve (edge, surf, location)) {
+      Standard_Real TolFirst = -1, TolLast = -1;
+      TopoDS_Vertex V1, V2;
+      TopExp::Vertices(edge, V1, V2);
+      if (!V1.IsNull())
+        TolFirst = BRep_Tool::Tolerance(V1);
+      if (!V2.IsNull())
+        TolLast = BRep_Tool::Tolerance(V2);
+      
       myProjector->Init ( sas, preci );
-      myProjector->Perform (c3d,First,Last,c2d);
+      myProjector->Perform (c3d,First,Last,c2d,TolFirst,TolLast);
       //  stat = 2 : reinterpoler la c3d ?
       if ( myProjector->Status ( ShapeExtend_DONE4 ) )
        myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE2);
diff --git a/tests/bugs/modalg_6/bug27079_1 b/tests/bugs/modalg_6/bug27079_1
new file mode 100644 (file)
index 0000000..121b0eb
--- /dev/null
@@ -0,0 +1,23 @@
+puts "============"
+puts "OCC27079"
+puts "============"
+puts ""
+##################################################################
+# Bad approximation of intersection curves with variable curvature
+##################################################################
+
+restore [locate_data_file bug27079_s1.draw] s1
+restore [locate_data_file bug27079_s2.draw] s2
+
+clpoles s2
+
+smallview
+donly s2
+fit
+
+intersect result s1 s2
+
+checklength result_1 -l 6.8873540591440428
+checklength result_2 -l 6.8873330997321212
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_6/bug27079_2 b/tests/bugs/modalg_6/bug27079_2
new file mode 100644 (file)
index 0000000..99ea9b7
--- /dev/null
@@ -0,0 +1,21 @@
+puts "============"
+puts "OCC27079"
+puts "============"
+puts ""
+##################################################################
+# Bad approximation of intersection curves with variable curvature
+##################################################################
+
+restore [locate_data_file bug27079_s3.draw] s3
+restore [locate_data_file bug27079_s4.draw] s4
+
+smallview
+donly s4
+fit
+
+intersect result s3 s4
+
+checklength result_1 -l 4.2844275555620923
+checklength result_2 -l 4.2844275531269931
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png