0030621: Implementation of building U-periodical surfaces.
authorifv <ifv@opencascade.com>
Fri, 29 Mar 2019 12:20:27 +0000 (15:20 +0300)
committerbugmaster <bugmaster@opencascade.com>
Tue, 23 Apr 2019 15:12:16 +0000 (18:12 +0300)
draw_test_harness.md - description of new options in Draw commands

AppDef_BSplineCompute.hxx, BRepApprox_TheComputeLineOfApprox.hxx, GeomInt_TheComputeLineOfWLApprox.hxx, Approx_BSplComputeLine.gxx - implementation of method SetPeriodic(...) and implementation periodic boundary conditions for multiline in order to get periodic multicurve.

GeomAPI_PointsToBSplineSurface.hxx, GeomAPI_PointsToBSplineSurface.cxx - adding new parameter for methods Init(...) and Interpolate(...), implementation of building periodic tangents for first and last AppDef_MultiPointConstraint of multiline for U direction of surface.

GeometryTest_APICommands.cxx - implementation of new functionality in Draw command surfapp and surfint

GeomFill_NSections.cxx
Fixing problem with bugs modalg_3 bug606_2

13 files changed:
dox/user_guides/draw_test_harness/draw_test_harness.md
src/AppDef/AppDef_BSplineCompute.hxx
src/Approx/Approx_BSplComputeLine.gxx
src/BRepApprox/BRepApprox_TheComputeLineOfApprox.hxx
src/GeomAPI/GeomAPI_PointsToBSplineSurface.cxx
src/GeomAPI/GeomAPI_PointsToBSplineSurface.hxx
src/GeomFill/GeomFill_NSections.cxx
src/GeomInt/GeomInt_TheComputeLineOfWLApprox.hxx
src/GeometryTest/GeometryTest_APICommands.cxx
src/QABugs/QABugs_17.cxx
tests/bugs/modalg_6/bug26841_1
tests/bugs/modalg_7/bug30621 [new file with mode: 0644]
tests/lowalgos/intss/bug24418_2

index 78447f5..8edd0ea 100644 (file)
@@ -1,4 +1,4 @@
-Draw Test Harness  {#occt_user_guides__test_harness}
+\feffDraw Test Harness  {#occt_user_guides__test_harness}
 ===============================
 
 @tableofcontents
@@ -5593,7 +5593,8 @@ Draw provides command to create curves and surfaces by approximation.
 
 * **2dapprox** fits a curve through 2d points; 
 * **appro** fits a curve through 3d points;
-* **surfapp** and **grilapp** fit a surface through 3d points;
+* **surfapp** and **grilapp** fit a surface through 3d points by approximation;
+* **surfint** fit a surface through 3d points by interpolation;
 * **2dinterpolate** interpolates a curve. 
 
 @subsubsection occt_draw_6_8_1   appro, dapprox
@@ -5614,17 +5615,28 @@ Let us pick points and they will be fitted
 2dapprox c 10 
 ~~~~~
 
-@subsubsection occt_draw_6_8_2  surfapp, grilapp
+@subsubsection occt_draw_6_8_2  surfapp, grilapp, surfint
 
 
 Syntax: 
 ~~~~~
 surfapp name nbupoints nbvpoints x y z .... 
+or
+surfapp name nbupoints nbvpoints surf [periodic_flag = 0]
 grilapp name nbupoints nbvpoints xo dx yo dy z11 z12 ... 
+surfint name surf nbupoints nbvpoints [periodic_flag = 0]
 ~~~~~
 
 * **surfapp** fits a surface through an array of u and v points, nbupoints*nbvpoints. 
 * **grilapp** has the same function, but the x,y coordinates of the points are on a grid starting at x0,y0 with steps dx,dy. 
+* **surfapp** can take array of points from other input surface, if alternative syntax
+**surfapp** name nbupoints nbvpoints surf [periodic_flag = 0]
+is used.
+Both command use for fitting approximation algorithm.
+**surfint** uses interpolation algorithm and can take array of point only from other input surface.
+Optional parameter **periodic_flag** allows to get correct periodical surfaces in U direction.
+U direction of result surface corresponds colums of initial array of points.
+If **periodic_flag** = 1, algorithm uses first row of array as last row and builds periodical surface.
 
 **Example:** 
 ~~~~~
index ebbdf3f..0b3fe1a 100644 (file)
@@ -117,6 +117,12 @@ public:
   //! changes the first and the last constraint points.
   Standard_EXPORT void SetConstraints (const AppParCurves_Constraint firstC, const AppParCurves_Constraint lastC);
   
+  //! Sets periodic flag.
+  //! If thePeriodic = Standard_True, algorith tries to build periodic
+  //! multicurve using corresponding C1 boundary condition for first and last multipoints.
+  //! Multiline must be closed.
+  Standard_EXPORT void SetPeriodic(const Standard_Boolean thePeriodic);
+
   //! returns False if at a moment of the approximation,
   //! the status NoApproximation has been sent by the user
   //! when more points were needed.
@@ -199,6 +205,7 @@ private:
   Standard_Integer mycont;
   Standard_Real mylambda1;
   Standard_Real mylambda2;
+  Standard_Boolean myPeriodic;
 
 
 };
index 5d9b516..75315e8 100644 (file)
@@ -56,14 +56,14 @@ static void DUMP(const MultiLine& Line)
 {
   Standard_Integer i, j, nbP2d, nbP3d, firstP, lastP;
   firstP = LineTool::FirstPoint(Line);
-  lastP  = LineTool::LastPoint(Line);
+  lastP = LineTool::LastPoint(Line);
 
   nbP3d = LineTool::NbP3d(Line);
   nbP2d = LineTool::NbP2d(Line);
-  Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
+  Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
   if (nbP3d == 0) mynbP3d = 1;
   if (nbP2d == 0) mynbP2d = 1;
-  
+
   TColgp_Array1OfPnt tabP(1, mynbP3d);
   TColgp_Array1OfPnt2d tabP2d(1, mynbP2d);
   TColgp_Array1OfVec TabV(1, mynbP3d);
@@ -83,56 +83,56 @@ static void DUMP(const MultiLine& Line)
     if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i, tabP, tabP2d);
     else if (nbP2d != 0)          LineTool::Value(Line, i, tabP2d);
     else if (nbP3d != 0)          LineTool::Value(Line, i, tabP);
-    
+
     for (j = 1; j <= nbP3d; j++) {
       sprintf(solname, "%s%i%s_%i", "p", j, "3d", i);
-      char* Temp = solname ;
+      char* Temp = solname;
       DrawTrSurf::Set(Temp, tabP(j));
-//      DrawTrSurf::Set(solname, tabP(j));
+      //      DrawTrSurf::Set(solname, tabP(j));
       if (i == firstP || i == lastP) {
-       sprintf(mytext, "%s%i", " ", i);
-       T3D = new Draw_Text3D(tabP(j), mytext, Draw_vert);
-       dout << T3D;
+        sprintf(mytext, "%s%i", " ", i);
+        T3D = new Draw_Text3D(tabP(j), mytext, Draw_vert);
+        dout << T3D;
       }
     }
     for (j = 1; j <= nbP2d; j++) {
       sprintf(solname, "%s%i%s_%i", "p", j, "2d", i);
-      char* Temp = solname ;
+      char* Temp = solname;
       DrawTrSurf::Set(Temp, tabP2d(j));
-//      DrawTrSurf::Set(solname, tabP2d(j));
+      //      DrawTrSurf::Set(solname, tabP2d(j));
       if (i == firstP || i == lastP) {
-       sprintf(mytext, "%s%i", " ", i);
-       T2D = new Draw_Text2D(tabP2d(j), mytext, Draw_vert);
-       dout << T2D;
+        sprintf(mytext, "%s%i", " ", i);
+        T2D = new Draw_Text2D(tabP2d(j), mytext, Draw_vert);
+        dout << T2D;
       }
     }
 
     // le cas des tangentes aux extremites:
     if (i == firstP || i == lastP) {
       if (nbP3d != 0 && nbP2d != 0)
-       Ok = LineTool::Tangency(Line, i, TabV, TabV2d);
+        Ok = LineTool::Tangency(Line, i, TabV, TabV2d);
       else if (nbP2d != 0)
-       Ok = LineTool::Tangency(Line, i, TabV2d);
+        Ok = LineTool::Tangency(Line, i, TabV2d);
       else if (nbP3d != 0)
-       Ok = LineTool::Tangency(Line, i, TabV);
-      
+        Ok = LineTool::Tangency(Line, i, TabV);
+
       if (Ok) {
-       for (j = 1; j <= nbP3d; j++) {
-         sprintf(solname, "%s%i%s_%i", "t", j, "3d", i);
-         L3d = new Geom_Line (tabP(j), gp_Dir(TabV(j)));
-         L3dt = new Geom_TrimmedCurve(L3d, 0.0, 0.3);
-         char* Temp = solname ;
-         DrawTrSurf::Set(Temp, L3dt);
-//       DrawTrSurf::Set(solname, L3dt);
-       }
-       for (j = 1; j <= nbP2d; j++) {
-         sprintf(solname, "%s%i%s_%i", "t", j, "2d", i);
-         L2d = new Geom2d_Line (tabP2d(j), gp_Dir2d(TabV2d(j)));
-         L2dt = new Geom2d_TrimmedCurve(L2d, 0.0, 0.3);
-         char* Temp = solname ;
-         DrawTrSurf::Set(Temp, L2dt);
-//       DrawTrSurf::Set(solname, L2dt);
-       }
+        for (j = 1; j <= nbP3d; j++) {
+          sprintf(solname, "%s%i%s_%i", "t", j, "3d", i);
+          L3d = new Geom_Line(tabP(j), gp_Dir(TabV(j)));
+          L3dt = new Geom_TrimmedCurve(L3d, 0.0, 0.3);
+          char* Temp = solname;
+          DrawTrSurf::Set(Temp, L3dt);
+          //     DrawTrSurf::Set(solname, L3dt);
+        }
+        for (j = 1; j <= nbP2d; j++) {
+          sprintf(solname, "%s%i%s_%i", "t", j, "2d", i);
+          L2d = new Geom2d_Line(tabP2d(j), gp_Dir2d(TabV2d(j)));
+          L2dt = new Geom2d_TrimmedCurve(L2d, 0.0, 0.3);
+          char* Temp = solname;
+          DrawTrSurf::Set(Temp, L2dt);
+          //     DrawTrSurf::Set(solname, L2dt);
+        }
       }
     }
   }
@@ -162,17 +162,17 @@ static void DUMP(const AppParCurves_MultiBSpCurve& C)
       C.Curve(i, tabPoles);
       BSp = new Geom_BSplineCurve(tabPoles, Knots, Mults, deg);
       sprintf(solname, "%s%i%s_%i", "c", i, "3d", nbappel);
-      char* Temp = solname ;
+      char* Temp = solname;
       DrawTrSurf::Set(Temp, BSp);
-//      DrawTrSurf::Set(solname, BSp);
+      //      DrawTrSurf::Set(solname, BSp);
     }
     else {
       C.Curve(i, tabPoles2d);
       BSp2d = new Geom2d_BSplineCurve(tabPoles2d, Knots, Mults, deg);
       sprintf(solname, "%s%i%s_%i", "c", i, "2d", nbappel);
-      char* Temp = solname ;
+      char* Temp = solname;
       DrawTrSurf::Set(Temp, BSp2d);
-//      DrawTrSurf::Set(solname, BSp2d);
+      //      DrawTrSurf::Set(solname, BSp2d);
     }
   }
   dout.Flush();
@@ -188,21 +188,21 @@ static void DUMP(const AppParCurves_MultiBSpCurve& C)
 //function : FirstTangencyVector
 //purpose  : 
 //=======================================================================
-void Approx_BSplComputeLine::FirstTangencyVector(const MultiLine&       Line,
-                                                const Standard_Integer index,
-                                                math_Vector&           V)
-const {
+void Approx_BSplComputeLine::FirstTangencyVector(const MultiLine&  Line,
+  const Standard_Integer index,
+  math_Vector&           V)
+  const {
 
   Standard_Integer i, j, nbP2d, nbP3d;
   nbP3d = LineTool::NbP3d(Line);
   nbP2d = LineTool::NbP2d(Line);
-  Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
+  Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
   if (nbP3d == 0) mynbP3d = 1;
   if (nbP2d == 0) mynbP2d = 1;
-  Standard_Boolean Ok=Standard_False;
+  Standard_Boolean Ok = Standard_False;
   TColgp_Array1OfVec TabV(1, mynbP3d);
   TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
+
   if (nbP3d != 0 && nbP2d != 0)
     Ok = LineTool::Tangency(Line, index, TabV, TabV2d);
   else if (nbP2d != 0)
@@ -214,18 +214,18 @@ const {
     if (nbP3d != 0) {
       j = 1;
       for (i = TabV.Lower(); i <= TabV.Upper(); i++) {
-       V(j)   = TabV(i).X();
-       V(j+1) = TabV(i).Y();
-       V(j+2) = TabV(i).Z();
-       j += 3;
+        V(j) = TabV(i).X();
+        V(j + 1) = TabV(i).Y();
+        V(j + 2) = TabV(i).Z();
+        j += 3;
       }
     }
     if (nbP2d != 0) {
-      j = nbP3d*3+1;
+      j = nbP3d * 3 + 1;
       for (i = TabV2d.Lower(); i <= TabV2d.Upper(); i++) {
-       V(j)   = TabV2d(i).X();
-       V(j+1) = TabV2d(i).Y();
-       j += 2;
+        V(j) = TabV2d(i).X();
+        V(j + 1) = TabV2d(i).Y();
+        j += 2;
       }
     }
   }
@@ -235,12 +235,12 @@ const {
     AppParCurves_Constraint firstC, lastC;
     firstC = lastC = AppParCurves_PassPoint;
     Standard_Integer nbpoles = 3;
-    math_Vector mypar(index, index+2);
-    Parameters(Line, index, index+2, mypar);
-    Approx_BSpParLeastSquareOfMyBSplGradient 
-      LSQ(Line, index, index+2, firstC, lastC, mypar, nbpoles);
+    math_Vector mypar(index, index + 2);
+    Parameters(Line, index, index + 2, mypar);
+    Approx_BSpParLeastSquareOfMyBSplGradient
+      LSQ(Line, index, index + 2, firstC, lastC, mypar, nbpoles);
     AppParCurves_MultiCurve C = LSQ.BezierValue();
-    
+
     gp_Pnt myP;
     gp_Vec myV;
     gp_Pnt2d myP2d;
@@ -248,16 +248,16 @@ const {
     j = 1;
     for (i = 1; i <= nbP3d; i++) {
       C.D1(i, 0.0, myP, myV);
-      V(j)   = myV.X();
-      V(j+1) = myV.Y();
-      V(j+2) = myV.Z();
+      V(j) = myV.X();
+      V(j + 1) = myV.Y();
+      V(j + 2) = myV.Z();
       j += 3;
     }
-    j = nbP3d*3+1;
-    for (i = nbP3d+1; i <= nbP3d+nbP2d; i++) {
+    j = nbP3d * 3 + 1;
+    for (i = nbP3d + 1; i <= nbP3d + nbP2d; i++) {
       C.D1(i, 0.0, myP2d, myV2d);
-      V(j)   = myV2d.X();
-      V(j+1) = myV2d.Y();
+      V(j) = myV2d.X();
+      V(j + 1) = myV2d.Y();
       j += 2;
     }
   }
@@ -270,20 +270,20 @@ const {
 //purpose  : 
 //=======================================================================
 void Approx_BSplComputeLine::LastTangencyVector(const MultiLine&       Line,
-                                               const Standard_Integer index,
-                                               math_Vector&           V)
-const {
+  const Standard_Integer index,
+  math_Vector&           V)
+  const {
   Standard_Integer i, j, nbP2d, nbP3d;
   nbP3d = LineTool::NbP3d(Line);
   nbP2d = LineTool::NbP2d(Line);
-  Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
+  Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
   if (nbP3d == 0) mynbP3d = 1;
   if (nbP2d == 0) mynbP2d = 1;
-  Standard_Boolean Ok=Standard_False;
+  Standard_Boolean Ok = Standard_False;
   TColgp_Array1OfVec TabV(1, mynbP3d);
   TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
 
+
   if (nbP3d != 0 && nbP2d != 0)
     Ok = LineTool::Tangency(Line, index, TabV, TabV2d);
   else if (nbP2d != 0)
@@ -295,18 +295,18 @@ const {
     if (nbP3d != 0) {
       j = 1;
       for (i = TabV.Lower(); i <= TabV.Upper(); i++) {
-       V(j)   = TabV(i).X();
-       V(j+1) = TabV(i).Y();
-       V(j+2) = TabV(i).Z();
-       j += 3;
+        V(j) = TabV(i).X();
+        V(j + 1) = TabV(i).Y();
+        V(j + 2) = TabV(i).Z();
+        j += 3;
       }
     }
     if (nbP2d != 0) {
-      j = nbP3d*3+1;
+      j = nbP3d * 3 + 1;
       for (i = TabV2d.Lower(); i <= TabV2d.Upper(); i++) {
-       V(j)   = TabV2d(i).X();
-       V(j+1) = TabV2d(i).Y();
-       j += 2;
+        V(j) = TabV2d(i).X();
+        V(j + 1) = TabV2d(i).Y();
+        j += 2;
       }
     }
   }
@@ -316,12 +316,12 @@ const {
     AppParCurves_Constraint firstC, lastC;
     firstC = lastC = AppParCurves_PassPoint;
     Standard_Integer nbpoles = 3;
-    math_Vector mypar(index-2, index);
-    Parameters(Line, index-2, index, mypar);
-    Approx_BSpParLeastSquareOfMyBSplGradient 
-      LSQ(Line, index-2, index, firstC, lastC, mypar, nbpoles);
+    math_Vector mypar(index - 2, index);
+    Parameters(Line, index - 2, index, mypar);
+    Approx_BSpParLeastSquareOfMyBSplGradient
+      LSQ(Line, index - 2, index, firstC, lastC, mypar, nbpoles);
     AppParCurves_MultiCurve C = LSQ.BezierValue();
-    
+
     gp_Pnt myP;
     gp_Vec myV;
     gp_Pnt2d myP2d;
@@ -329,16 +329,16 @@ const {
     j = 1;
     for (i = 1; i <= nbP3d; i++) {
       C.D1(i, 1.0, myP, myV);
-      V(j)   = myV.X();
-      V(j+1) = myV.Y();
-      V(j+2) = myV.Z();
+      V(j) = myV.X();
+      V(j + 1) = myV.Y();
+      V(j + 2) = myV.Z();
       j += 3;
     }
-    j = nbP3d*3+1;
-    for (i = nbP3d+1; i <= nbP3d+nbP2d; i++) {
+    j = nbP3d * 3 + 1;
+    for (i = nbP3d + 1; i <= nbP3d + nbP2d; i++) {
       C.D1(i, 1.0, myP2d, myV2d);
-      V(j)   = myV2d.X();
-      V(j+1) = myV2d.Y();
+      V(j) = myV2d.X();
+      V(j + 1) = myV2d.Y();
       j += 2;
     }
   }
@@ -352,57 +352,57 @@ const {
 //purpose  : 
 //=======================================================================
 Standard_Real Approx_BSplComputeLine::
-  SearchFirstLambda(const MultiLine&            Line, 
-                   const math_Vector&          aPar,
-                   const TColStd_Array1OfReal& Theknots,
-                   const math_Vector&          V,
-                   const Standard_Integer      index) const {
+SearchFirstLambda(const MultiLine&            Line,
+  const math_Vector&          aPar,
+  const TColStd_Array1OfReal& Theknots,
+  const math_Vector&          V,
+  const Standard_Integer      index) const {
 
   // dq/dw = lambda* V = (p2-p1)/(u2-u1)
-  
+
   Standard_Integer nbP2d, nbP3d;
   gp_Pnt P1, P2;
   gp_Pnt2d P12d, P22d;
   nbP3d = LineTool::NbP3d(Line);
   nbP2d = LineTool::NbP2d(Line);
-  Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
+  Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
   if (nbP3d == 0) mynbP3d = 1;
   if (nbP2d == 0) mynbP2d = 1;
   TColgp_Array1OfPnt tabP1(1, mynbP3d), tabP2(1, mynbP3d);
   TColgp_Array1OfPnt2d tabP12d(1, mynbP2d), tabP22d(1, mynbP2d);
+
 
   if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index, tabP1, tabP12d);
   else if (nbP2d != 0)          LineTool::Value(Line, index, tabP12d);
   else if (nbP3d != 0)          LineTool::Value(Line, index, tabP1);
 
-  if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index+1, tabP2, tabP22d);
-  else if (nbP2d != 0)          LineTool::Value(Line, index+1, tabP22d);
-  else if (nbP3d != 0)          LineTool::Value(Line, index+1, tabP2);
-                                    
+  if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index + 1, tabP2, tabP22d);
+  else if (nbP2d != 0)          LineTool::Value(Line, index + 1, tabP22d);
+  else if (nbP3d != 0)          LineTool::Value(Line, index + 1, tabP2);
+
 
-  Standard_Real U1 = aPar(index), U2 = aPar(index+1);
-  Standard_Real lambda, S;                                       
+  Standard_Real U1 = aPar(index), U2 = aPar(index + 1);
+  Standard_Real lambda, S;
   Standard_Integer low = V.Lower();
   Standard_Integer nbknots = Theknots.Length();
+
   if (nbP3d != 0) {
     P1 = tabP1(1);
     P2 = tabP2(1);
     gp_Vec P1P2(P1, P2), myV;
-    myV.SetCoord(V(low), V(low+1), V(low+2));
-    lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1));
-    S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0;
+    myV.SetCoord(V(low), V(low + 1), V(low + 2));
+    lambda = (P1P2.Magnitude()) / (myV.Magnitude()*(U2 - U1));
+    S = (P1P2.Dot(myV) > 0.0) ? 1.0 : -1.0;
   }
   else {
     P12d = tabP12d(1);
     P22d = tabP22d(1);
     gp_Vec2d P1P2(P12d, P22d), myV;
-    myV.SetCoord(V(low), V(low+1));
-    lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1));
-    S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0;
+    myV.SetCoord(V(low), V(low + 1));
+    lambda = (P1P2.Magnitude()) / (myV.Magnitude()*(U2 - U1));
+    S = (P1P2.Dot(myV) > 0.0) ? 1.0 : -1.0;
   }
-  return ((S*lambda)*(Theknots(2)-Theknots(1))/(Theknots(nbknots)-Theknots(1)));
+  return ((S*lambda)*(Theknots(2) - Theknots(1)) / (Theknots(nbknots) - Theknots(1)));
 
 }
 
@@ -412,36 +412,36 @@ Standard_Real Approx_BSplComputeLine::
 //purpose  : 
 //=======================================================================
 Standard_Real Approx_BSplComputeLine::
-  SearchLastLambda(const MultiLine&            Line, 
-                  const math_Vector&          aPar,
-                  const TColStd_Array1OfReal& Theknots,
-                  const math_Vector&          V,
-                  const Standard_Integer      index) const
+SearchLastLambda(const MultiLine&            Line,
+  const math_Vector&          aPar,
+  const TColStd_Array1OfReal& Theknots,
+  const math_Vector&          V,
+  const Standard_Integer      index) const
 
 {
   // dq/dw = lambda* V = (p2-p1)/(u2-u1)
-  
+
   Standard_Integer nbP2d, nbP3d;
   gp_Pnt P1, P2;
   gp_Pnt2d P12d, P22d;
   nbP3d = LineTool::NbP3d(Line);
   nbP2d = LineTool::NbP2d(Line);
-  Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
+  Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
   if (nbP3d == 0) mynbP3d = 1;
   if (nbP2d == 0) mynbP2d = 1;
   TColgp_Array1OfPnt tabP(1, mynbP3d), tabP2(1, mynbP3d);
   TColgp_Array1OfPnt2d tabP2d(1, mynbP2d), tabP22d(1, mynbP2d);
-  if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index-1, tabP, tabP2d);
-  else if (nbP2d != 0)          LineTool::Value(Line, index-1, tabP2d);
-  else if (nbP3d != 0)          LineTool::Value(Line, index-1, tabP);
+
+  if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index - 1, tabP, tabP2d);
+  else if (nbP2d != 0)          LineTool::Value(Line, index - 1, tabP2d);
+  else if (nbP3d != 0)          LineTool::Value(Line, index - 1, tabP);
 
   if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index, tabP2, tabP22d);
   else if (nbP2d != 0)          LineTool::Value(Line, index, tabP22d);
   else if (nbP3d != 0)          LineTool::Value(Line, index, tabP2);
 
 
-  Standard_Real U1 = aPar(index-1), U2 = aPar(index);
+  Standard_Real U1 = aPar(index - 1), U2 = aPar(index);
   Standard_Real lambda, S;
   Standard_Integer low = V.Lower();
   Standard_Integer nbknots = Theknots.Length();
@@ -449,21 +449,21 @@ Standard_Real Approx_BSplComputeLine::
     P1 = tabP(1);
     P2 = tabP2(1);
     gp_Vec P1P2(P1, P2), myV;
-    myV.SetCoord(V(low), V(low+1), V(low+2));
-    lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1));
-    S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0;
+    myV.SetCoord(V(low), V(low + 1), V(low + 2));
+    lambda = (P1P2.Magnitude()) / (myV.Magnitude()*(U2 - U1));
+    S = (P1P2.Dot(myV) > 0.0) ? 1.0 : -1.0;
   }
   else {
     P12d = tabP2d(1);
     P22d = tabP22d(1);
     gp_Vec2d P1P2(P12d, P22d), myV;
-    myV.SetCoord(V(low), V(low+1));
-    lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1));
-    S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0;
+    myV.SetCoord(V(low), V(low + 1));
+    lambda = (P1P2.Magnitude()) / (myV.Magnitude()*(U2 - U1));
+    S = (P1P2.Dot(myV) > 0.0) ? 1.0 : -1.0;
   }
 
-  return ((S*lambda)*(Theknots(nbknots)-Theknots(nbknots-1))
-         /(Theknots(nbknots)-Theknots(1)));
+  return ((S*lambda)*(Theknots(nbknots) - Theknots(nbknots - 1))
+    / (Theknots(nbknots) - Theknots(1)));
 }
 
 
@@ -473,23 +473,24 @@ Standard_Real Approx_BSplComputeLine::
 //purpose  : 
 //=======================================================================
 Approx_BSplComputeLine::Approx_BSplComputeLine
-                    (const MultiLine& Line,
-                    const math_Vector& Parameters,
-                    const Standard_Integer degreemin,
-                    const Standard_Integer degreemax,
-                    const Standard_Real Tolerance3d,
-                    const Standard_Real Tolerance2d,
-                    const Standard_Integer NbIterations,
-                    const Standard_Boolean cutting,
-                    const Standard_Boolean Squares)
+(const MultiLine& Line,
+  const math_Vector& Parameters,
+  const Standard_Integer degreemin,
+  const Standard_Integer degreemax,
+  const Standard_Real Tolerance3d,
+  const Standard_Real Tolerance2d,
+  const Standard_Integer NbIterations,
+  const Standard_Boolean cutting,
+  const Standard_Boolean Squares)
 {
-  myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(), 
-                                          Parameters.Upper());
+  myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(),
+    Parameters.Upper());
   for (Standard_Integer i = Parameters.Lower(); i <= Parameters.Upper(); i++) {
     myfirstParam->SetValue(i, Parameters(i));
   }
   myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
   Par = Approx_IsoParametric;
+  myPeriodic = Standard_False;
   mydegremin = degreemin;
   mydegremax = degreemax;
   mytol3d = Tolerance3d;
@@ -514,17 +515,17 @@ Approx_BSplComputeLine::Approx_BSplComputeLine
 //purpose  : 
 //=======================================================================
 Approx_BSplComputeLine::Approx_BSplComputeLine
-                    (const math_Vector& Parameters,
-                    const Standard_Integer degreemin,
-                    const Standard_Integer degreemax,
-                    const Standard_Real Tolerance3d,
-                    const Standard_Real Tolerance2d,
-                    const Standard_Integer NbIterations,
-                    const Standard_Boolean cutting,
-                    const Standard_Boolean Squares)
+(const math_Vector& Parameters,
+  const Standard_Integer degreemin,
+  const Standard_Integer degreemax,
+  const Standard_Real Tolerance3d,
+  const Standard_Real Tolerance2d,
+  const Standard_Integer NbIterations,
+  const Standard_Boolean cutting,
+  const Standard_Boolean Squares)
 {
-  myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(), 
-                                          Parameters.Upper());
+  myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(),
+    Parameters.Upper());
   for (Standard_Integer i = Parameters.Lower(); i <= Parameters.Upper(); i++) {
     myfirstParam->SetValue(i, Parameters(i));
   }
@@ -532,6 +533,7 @@ Approx_BSplComputeLine::Approx_BSplComputeLine
   mylastC = AppParCurves_TangencyPoint;
   myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
   Par = Approx_IsoParametric;
+  myPeriodic = Standard_False;
   mydegremin = degreemin;
   mydegremax = degreemax;
   mytol3d = Tolerance3d;
@@ -552,17 +554,18 @@ Approx_BSplComputeLine::Approx_BSplComputeLine
 //purpose  : 
 //=======================================================================
 Approx_BSplComputeLine::Approx_BSplComputeLine
-                    (const Standard_Integer degreemin,
-                    const Standard_Integer degreemax,
-                    const Standard_Real Tolerance3d,
-                    const Standard_Real Tolerance2d,
-                    const Standard_Integer NbIterations,
-                    const Standard_Boolean cutting,
-                    const Approx_ParametrizationType parametrization,
-                    const Standard_Boolean Squares)
+(const Standard_Integer degreemin,
+  const Standard_Integer degreemax,
+  const Standard_Real Tolerance3d,
+  const Standard_Real Tolerance2d,
+  const Standard_Integer NbIterations,
+  const Standard_Boolean cutting,
+  const Approx_ParametrizationType parametrization,
+  const Standard_Boolean Squares)
 {
   myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
   Par = parametrization;
+  myPeriodic = Standard_False;
   mydegremin = degreemin;
   mydegremax = degreemax;
   mytol3d = Tolerance3d;
@@ -586,15 +589,15 @@ Approx_BSplComputeLine::Approx_BSplComputeLine
 //purpose  : 
 //=======================================================================
 Approx_BSplComputeLine::Approx_BSplComputeLine
-                    (const MultiLine& Line,
-                    const Standard_Integer degreemin,
-                    const Standard_Integer degreemax,
-                    const Standard_Real Tolerance3d,
-                    const Standard_Real Tolerance2d,
-                    const Standard_Integer NbIterations,
-                    const Standard_Boolean cutting,
-                    const Approx_ParametrizationType parametrization,
-                    const Standard_Boolean Squares)
+(const MultiLine& Line,
+  const Standard_Integer degreemin,
+  const Standard_Integer degreemax,
+  const Standard_Real Tolerance3d,
+  const Standard_Real Tolerance2d,
+  const Standard_Integer NbIterations,
+  const Standard_Boolean cutting,
+  const Approx_ParametrizationType parametrization,
+  const Standard_Boolean Squares)
 {
   myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
   alldone = Standard_False;
@@ -606,6 +609,7 @@ Approx_BSplComputeLine::Approx_BSplComputeLine
   mycut = cutting;
   myitermax = NbIterations;
   Par = parametrization;
+  myPeriodic = Standard_False;
   myfirstC = AppParCurves_TangencyPoint;
   mylastC = AppParCurves_TangencyPoint;
   myhasknots = Standard_False;
@@ -628,16 +632,16 @@ void Approx_BSplComputeLine::Perform(const MultiLine& Line)
 #if defined(OCCT_DEBUG) && defined( DRAW ) && !defined( WNT )
   if (mydebug) DUMP(Line);
 #endif
-    
+
   Standard_Integer i, Thefirstpt, Thelastpt;
   Standard_Boolean Finish = Standard_False, begin = Standard_True;
-  
+
   // recherche des vraies contraintes donnees par la Line:
   FindRealConstraints(Line);
 
   Thefirstpt = LineTool::FirstPoint(Line);
-  Thelastpt  = LineTool::LastPoint(Line);
-  Standard_Integer myfirstpt = Thefirstpt; 
+  Thelastpt = LineTool::LastPoint(Line);
+  Standard_Integer myfirstpt = Thefirstpt;
   Standard_Integer mylastpt = Thelastpt;
 
   AppParCurves_ConstraintCouple myCouple1(myfirstpt, realfirstC);
@@ -646,17 +650,17 @@ void Approx_BSplComputeLine::Perform(const MultiLine& Line)
   myConstraints->SetValue(2, myCouple2);
 
   math_Vector TheParam(Thefirstpt, Thelastpt, 0.0);
-  if(myfirstParam.IsNull()) {
+  if (myfirstParam.IsNull()) {
     Parameters(Line, Thefirstpt, Thelastpt, TheParam);
   }
   else {
     for (i = myfirstParam->Lower(); i <= myfirstParam->Upper(); i++) {
-      TheParam(i+Thefirstpt-1) = myfirstParam->Value(i);
+      TheParam(i + Thefirstpt - 1) = myfirstParam->Value(i);
     }
   }
 
   myParameters = new TColStd_HArray1OfReal(TheParam.Lower(), TheParam.Upper());
-  for ( i = TheParam.Lower(); i <= TheParam.Upper(); i++) {
+  for (i = TheParam.Lower(); i <= TheParam.Upper(); i++) {
     myParameters->SetValue(i, TheParam(i));
   }
   Standard_Integer nbknots = 2;
@@ -677,13 +681,13 @@ void Approx_BSplComputeLine::Perform(const MultiLine& Line)
     }
     else {
       if (!myhasmults) {
-       TColStd_Array1OfInteger themults(1, myknots->Length());
-       alldone = Compute(Line, myfirstpt, mylastpt, TheParam, 
-                         myknots->Array1(), themults);
+        TColStd_Array1OfInteger themults(1, myknots->Length());
+        alldone = Compute(Line, myfirstpt, mylastpt, TheParam,
+          myknots->Array1(), themults);
       }
       else {
-       alldone = Compute(Line, myfirstpt, mylastpt, TheParam, 
-                         myknots->Array1(), mymults->ChangeArray1());
+        alldone = Compute(Line, myfirstpt, mylastpt, TheParam,
+          myknots->Array1(), mymults->ChangeArray1());
       }
     }
   }
@@ -699,53 +703,53 @@ void Approx_BSplComputeLine::Perform(const MultiLine& Line)
 
       if (myhasknots && begin) {
 
-       if (!myhasmults) {
+        if (!myhasmults) {
 
-         // 1er cas: l''utilisateur donne des noeuds de depart mais
-         // a nous de fixer  les multiplicites  en  fonction  de  la 
-         // continuite desiree.
-         // ========================================================
+          // 1er cas: l''utilisateur donne des noeuds de depart mais
+          // a nous de fixer  les multiplicites  en  fonction  de  la 
+          // continuite desiree.
+          // ========================================================
 
-         TColStd_Array1OfInteger TheMults(1, myknots->Length());
-         alldone = Compute(Line, myfirstpt, mylastpt, TheParam, 
-                      myknots->Array1(), TheMults);
-       }
-       else {
+          TColStd_Array1OfInteger TheMults(1, myknots->Length());
+          alldone = Compute(Line, myfirstpt, mylastpt, TheParam,
+            myknots->Array1(), TheMults);
+        }
+        else {
 
-         // 2eme cas: l''utilisateur donne des noeuds de depart 
-         // avec leurs multiplicites.
-         // ===================================================
+          // 2eme cas: l''utilisateur donne des noeuds de depart 
+          // avec leurs multiplicites.
+          // ===================================================
 
-         alldone = Compute(Line, myfirstpt, mylastpt, TheParam, 
-                      myknots->Array1(), mymults->ChangeArray1());
-       }
-       begin = Standard_False;
+          alldone = Compute(Line, myfirstpt, mylastpt, TheParam,
+            myknots->Array1(), mymults->ChangeArray1());
+        }
+        begin = Standard_False;
       }
 
       else {
-       
-       // 3eme cas: l''utilisateur ne donne aucun noeuds de depart
-       // ========================================================
-
-       TColStd_Array1OfReal Theknots(1, nbknots);
-       TColStd_Array1OfInteger TheMults(1, nbknots);
-       Theknots(1) = 0.0;
-       Theknots(nbknots) = 1.0;
-       for (i = 2; i <= nbknots-1; i++) {
-         
-         l = (mylastpt-myfirstpt)*Standard_Real(i-1)
-                             /Standard_Real(nbknots-1);
-         Standard_Integer ll = (Standard_Integer)(l);
-         Standard_Real a = l - ll;
-         Standard_Real p1 = TheParam(ll + myfirstpt);
-         Standard_Real p2 = TheParam(ll + 1 + myfirstpt);
-         Theknots(i) = (1.-a)*p1 + a*p2;
-       }
-       
-       alldone = Compute(Line, myfirstpt, mylastpt, TheParam, Theknots, TheMults);
-       
+
+        // 3eme cas: l''utilisateur ne donne aucun noeuds de depart
+        // ========================================================
+
+        TColStd_Array1OfReal Theknots(1, nbknots);
+        TColStd_Array1OfInteger TheMults(1, nbknots);
+        Theknots(1) = 0.0;
+        Theknots(nbknots) = 1.0;
+        for (i = 2; i <= nbknots - 1; i++) {
+
+          l = (mylastpt - myfirstpt)*Standard_Real(i - 1)
+            / Standard_Real(nbknots - 1);
+          Standard_Integer ll = (Standard_Integer)(l);
+          Standard_Real a = l - ll;
+          Standard_Real p1 = TheParam(ll + myfirstpt);
+          Standard_Real p2 = TheParam(ll + 1 + myfirstpt);
+          Theknots(i) = (1. - a)*p1 + a*p2;
+        }
+
+        alldone = Compute(Line, myfirstpt, mylastpt, TheParam, Theknots, TheMults);
+
       }
-      
+
       if (!alldone) nbknots++;
       else Finish = Standard_True;
     }
@@ -777,7 +781,7 @@ const TColStd_Array1OfReal& Approx_BSplComputeLine::Parameters() const
 //=======================================================================
 const AppParCurves_MultiBSpCurve& Approx_BSplComputeLine::Value() const
 {
-  return TheMultiBSpCurve; 
+  return TheMultiBSpCurve;
 }
 
 //=======================================================================
@@ -786,7 +790,7 @@ const AppParCurves_MultiBSpCurve& Approx_BSplComputeLine::Value() const
 //=======================================================================
 AppParCurves_MultiBSpCurve& Approx_BSplComputeLine::ChangeValue()
 {
-  return TheMultiBSpCurve; 
+  return TheMultiBSpCurve;
 }
 
 //=======================================================================
@@ -794,27 +798,27 @@ AppParCurves_MultiBSpCurve& Approx_BSplComputeLine::ChangeValue()
 //purpose  : 
 //=======================================================================
 
-void Approx_BSplComputeLine::Parameters(const MultiLine& Line, 
-                              const Standard_Integer firstP,
-                              const Standard_Integer lastP,
-                              math_Vector& TheParameters) const
+void Approx_BSplComputeLine::Parameters(const MultiLine& Line,
+  const Standard_Integer firstP,
+  const Standard_Integer lastP,
+  math_Vector& TheParameters) const
 {
   Standard_Integer i, j, nbP2d, nbP3d;
   Standard_Real dist;
   const Standard_Integer aNbp = lastP - firstP + 1;
 
-  
+
   if (aNbp == 2) {
     TheParameters(firstP) = 0.0;
-    TheParameters(lastP)  = 1.0;
+    TheParameters(lastP) = 1.0;
   }
-  else if(Par == Approx_ChordLength || Par == Approx_Centripetal)
+  else if (Par == Approx_ChordLength || Par == Approx_Centripetal)
   {
     nbP3d = LineTool::NbP3d(Line);
     nbP2d = LineTool::NbP2d(Line);
     Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
-    if(nbP3d == 0) mynbP3d = 1;
-    if(nbP2d == 0) mynbP2d = 1;
+    if (nbP3d == 0) mynbP3d = 1;
+    if (nbP2d == 0) mynbP2d = 1;
 
     TheParameters(firstP) = 0.0;
     dist = 0.0;
@@ -823,32 +827,32 @@ void Approx_BSplComputeLine::Parameters(const MultiLine& Line,
     TColgp_Array1OfPnt2d tabP2d(1, mynbP2d);
     TColgp_Array1OfPnt2d tabPP2d(1, mynbP2d);
 
-    for(i = firstP + 1; i <= lastP; i++)
+    for (i = firstP + 1; i <= lastP; i++)
     {
-      if(nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i - 1, tabP, tabP2d);
-      else if(nbP2d != 0)          LineTool::Value(Line, i - 1, tabP2d);
-      else if(nbP3d != 0)          LineTool::Value(Line, i - 1, tabP);
+      if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i - 1, tabP, tabP2d);
+      else if (nbP2d != 0)          LineTool::Value(Line, i - 1, tabP2d);
+      else if (nbP3d != 0)          LineTool::Value(Line, i - 1, tabP);
 
-      if(nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i, tabPP, tabPP2d);
-      else if(nbP2d != 0)          LineTool::Value(Line, i, tabPP2d);
-      else if(nbP3d != 0)          LineTool::Value(Line, i, tabPP);
+      if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i, tabPP, tabPP2d);
+      else if (nbP2d != 0)          LineTool::Value(Line, i, tabPP2d);
+      else if (nbP3d != 0)          LineTool::Value(Line, i, tabPP);
       dist = 0.0;
-      for(j = 1; j <= nbP3d; j++)
+      for (j = 1; j <= nbP3d; j++)
       {
         const gp_Pnt &aP1 = tabP(j),
-                     &aP2 = tabPP(j);
+          &aP2 = tabPP(j);
         dist += aP2.SquareDistance(aP1);
       }
-      for(j = 1; j <= nbP2d; j++)
+      for (j = 1; j <= nbP2d; j++)
       {
         const gp_Pnt2d &aP12d = tabP2d(j),
-                       &aP22d = tabPP2d(j);
+          &aP22d = tabPP2d(j);
 
         dist += aP22d.SquareDistance(aP12d);
       }
 
       dist = Sqrt(dist);
-      if(Par == Approx_ChordLength)
+      if (Par == Approx_ChordLength)
       {
         TheParameters(i) = TheParameters(i - 1) + dist;
       }
@@ -857,15 +861,15 @@ void Approx_BSplComputeLine::Parameters(const MultiLine& Line,
         TheParameters(i) = TheParameters(i - 1) + Sqrt(dist);
       }
     }
-    for(i = firstP; i <= lastP; i++) TheParameters(i) /= TheParameters(lastP);
+    for (i = firstP; i <= lastP; i++) TheParameters(i) /= TheParameters(lastP);
   }
   else {
     for (i = firstP; i <= lastP; i++) {
-      TheParameters(i) = (Standard_Real(i)-firstP)/
-                        (Standard_Real(lastP)-Standard_Real(firstP));
+      TheParameters(i) = (Standard_Real(i) - firstP) /
+        (Standard_Real(lastP - Standard_Real(firstP)));
     }
   }
-}  
+}
 
 
 //=======================================================================
@@ -873,16 +877,16 @@ void Approx_BSplComputeLine::Parameters(const MultiLine& Line,
 //purpose  : 
 //=======================================================================
 Standard_Boolean Approx_BSplComputeLine::Compute(const MultiLine& Line,
-                                            const Standard_Integer fpt,
-                                            const Standard_Integer lpt,
-                                             math_Vector&     Para,
-                                            const TColStd_Array1OfReal& Knots,
-                                            TColStd_Array1OfInteger& Mults)
+  const Standard_Integer fpt,
+  const Standard_Integer lpt,
+  math_Vector&     Para,
+  const TColStd_Array1OfReal& Knots,
+  TColStd_Array1OfInteger& Mults)
 {
   Standard_Integer i, deg, nbpoles, multinter;
   Standard_Boolean mydone;
   Standard_Real Fv, TheTol3d, TheTol2d, l1, l2;
-  Standard_Integer nbp = lpt-fpt+1;
+  Standard_Integer nbp = lpt - fpt + 1;
   mylambda1 = 0.0;
   mylambda2 = 0.0;
 
@@ -893,27 +897,27 @@ Standard_Boolean Approx_BSplComputeLine::Compute(const MultiLine& Line,
     aParams = Para;
 
     if (!myhasmults) {
-      Mults(Mults.Lower()) = deg+1;
-      Mults(Mults.Upper()) = deg+1;
-      nbpoles = deg+1;
+      Mults(Mults.Lower()) = deg + 1;
+      Mults(Mults.Upper()) = deg + 1;
+      nbpoles = deg + 1;
       if (mycont == -1) multinter = 1;
-      else multinter = Max(1, deg-mycont);
-      for (i = Mults.Lower()+1; i <= Mults.Upper()-1; i++) {
-       Mults(i) = multinter;
-       nbpoles += multinter;
+      else multinter = Max(1, deg - mycont);
+      for (i = Mults.Lower() + 1; i <= Mults.Upper() - 1; i++) {
+        Mults(i) = multinter;
+        nbpoles += multinter;
       }
     }
     else {
-      nbpoles = -deg-1;
+      nbpoles = -deg - 1;
       for (i = Mults.Lower(); i <= Mults.Upper(); i++) {
-       nbpoles += Mults.Value(i);
+        nbpoles += Mults.Value(i);
       }
     }
 
     Standard_Integer nbpolestocompare = nbpoles;
     if (realfirstC == AppParCurves_TangencyPoint) nbpolestocompare++;
-    if (reallastC == AppParCurves_CurvaturePoint) nbpolestocompare++;
-    if (realfirstC == AppParCurves_TangencyPoint) nbpolestocompare++;
+    if (reallastC == AppParCurves_TangencyPoint) nbpolestocompare++;
+    if (realfirstC == AppParCurves_CurvaturePoint) nbpolestocompare++;
     if (reallastC == AppParCurves_CurvaturePoint) nbpolestocompare++;
     if (nbpolestocompare > nbp) {
       Interpol(Line);
@@ -924,89 +928,89 @@ Standard_Boolean Approx_BSplComputeLine::Compute(const MultiLine& Line,
     AppParCurves_MultiBSpCurve mySCU(nbpoles);
 
     if (mysquares) {
-      Approx_BSpParLeastSquareOfMyBSplGradient SQ(Line,Knots,Mults,fpt,lpt, 
-                                          realfirstC, reallastC, aParams, nbpoles);
+      Approx_BSpParLeastSquareOfMyBSplGradient SQ(Line, Knots, Mults, fpt, lpt,
+        realfirstC, reallastC, aParams, nbpoles);
       mydone = SQ.IsDone();
-      if(mydone) {
-       mySCU = SQ.BSplineValue();
-       SQ.Error(Fv, TheTol3d, TheTol2d);
+      if (mydone) {
+        mySCU = SQ.BSplineValue();
+        SQ.Error(Fv, TheTol3d, TheTol2d);
       }
       else continue;
     }
     else {
-      if (nbpoles != deg+1) {
-
-       if (deg == mydegremin && (realfirstC >= AppParCurves_TangencyPoint ||
-                                 reallastC >= AppParCurves_TangencyPoint)) {
-         Approx_BSpParLeastSquareOfMyBSplGradient 
-           thefitt(Line,Knots,Mults, fpt,lpt,realfirstC,reallastC, aParams, nbpoles);
-         mylambda1 = thefitt.FirstLambda()*deg;
-         mylambda2 = thefitt.LastLambda()*deg;
-        
-       }
-       l1 = mylambda1/deg;
-       l2 = mylambda2/deg;
-
-       Approx_MyBSplGradient GRAD(Line, fpt, lpt, myConstraints, 
-                                  aParams, Knots, Mults, deg, mytol3d, 
-                                  mytol2d, myitermax, l1, l2);
-
-       mydone = GRAD.IsDone();
-       if(mydone) {
-         mySCU = GRAD.Value();
-         TheTol3d = GRAD.MaxError3d();
-         TheTol2d = GRAD.MaxError2d();
-       }
-       else continue;
+      if (nbpoles != deg + 1) {
+
+        if (deg == mydegremin && (realfirstC >= AppParCurves_TangencyPoint ||
+          reallastC >= AppParCurves_TangencyPoint)) {
+          Approx_BSpParLeastSquareOfMyBSplGradient
+            thefitt(Line, Knots, Mults, fpt, lpt, realfirstC, reallastC, aParams, nbpoles);
+          mylambda1 = thefitt.FirstLambda()*deg;
+          mylambda2 = thefitt.LastLambda()*deg;
+
+        }
+        l1 = mylambda1 / deg;
+        l2 = mylambda2 / deg;
+
+        Approx_MyBSplGradient GRAD(Line, fpt, lpt, myConstraints,
+          aParams, Knots, Mults, deg, mytol3d,
+          mytol2d, myitermax, l1, l2);
+
+        mydone = GRAD.IsDone();
+        if (mydone) {
+          mySCU = GRAD.Value();
+          TheTol3d = GRAD.MaxError3d();
+          TheTol2d = GRAD.MaxError2d();
+        }
+        else continue;
       }
       else {
-       Approx_MyGradientbis GRAD2(Line, fpt, lpt, myConstraints, 
-                                  aParams, deg, mytol3d, 
-                                  mytol2d, myitermax);
-       mydone = GRAD2.IsDone();
-       if(mydone) {
-         if (GRAD2.Value().NbCurves() == 0)
-           continue;
-         mySCU = AppParCurves_MultiBSpCurve (GRAD2.Value(), Knots, Mults);
-         TheTol3d = GRAD2.MaxError3d();
-         TheTol2d = GRAD2.MaxError2d();
-       }
-       else continue;
+        Approx_MyGradientbis GRAD2(Line, fpt, lpt, myConstraints,
+          aParams, deg, mytol3d,
+          mytol2d, myitermax);
+        mydone = GRAD2.IsDone();
+        if (mydone) {
+          if (GRAD2.Value().NbCurves() == 0)
+            continue;
+          mySCU = AppParCurves_MultiBSpCurve(GRAD2.Value(), Knots, Mults);
+          TheTol3d = GRAD2.MaxError3d();
+          TheTol2d = GRAD2.MaxError2d();
+        }
+        else continue;
       }
-    }  
+    }
     Standard_Boolean save = Standard_True;
-    
+
     for (i = aParams.Lower(); i <= aParams.Upper(); i++) {
       if (aParams(i) <= -0.000001 || aParams(i) >= 1.000001) {
-       save = Standard_False;
-       break;
+        save = Standard_False;
+        break;
       }
     }
-    
+
     if (mydone) {
       if (TheTol3d <= mytol3d && TheTol2d <= mytol2d) {
-       // Stockage de la multicurve approximee.
-       tolreached = Standard_True;
-       TheMultiBSpCurve = mySCU;
-       currenttol3d = TheTol3d;
-       currenttol2d = TheTol2d;
-       if (save) {
-         for (i = aParams.Lower(); i <= aParams.Upper(); i++) {
-           myParameters->SetValue(i, aParams(i));
-         }
-       }
-       return Standard_True;
+        // Stockage de la multicurve approximee.
+        tolreached = Standard_True;
+        TheMultiBSpCurve = mySCU;
+        currenttol3d = TheTol3d;
+        currenttol2d = TheTol2d;
+        if (save) {
+          for (i = aParams.Lower(); i <= aParams.Upper(); i++) {
+            myParameters->SetValue(i, aParams(i));
+          }
+        }
+        return Standard_True;
       }
     }
 
-    if (TheTol3d <= currenttol3d && TheTol2d <= currenttol2d) {  
+    if (TheTol3d <= currenttol3d && TheTol2d <= currenttol2d) {
       TheMultiBSpCurve = mySCU;
       currenttol3d = TheTol3d;
       currenttol2d = TheTol2d;
       if (save) {
-       for (i = aParams.Lower(); i <= aParams.Upper(); i++) {
-         myParameters->SetValue(i, aParams(i));
-       }
+        for (i = aParams.Lower(); i <= aParams.Upper(); i++) {
+          myParameters->SetValue(i, aParams(i));
+        }
       }
     }
 
@@ -1022,9 +1026,9 @@ Standard_Boolean Approx_BSplComputeLine::Compute(const MultiLine& Line,
 //purpose  : 
 //=======================================================================
 void Approx_BSplComputeLine::SetParameters(const math_Vector& ThePar)
-{ 
-  myfirstParam = new TColStd_HArray1OfReal(ThePar.Lower(), 
-                                          ThePar.Upper());
+{
+  myfirstParam = new TColStd_HArray1OfReal(ThePar.Lower(),
+    ThePar.Upper());
   for (Standard_Integer i = ThePar.Lower(); i <= ThePar.Upper(); i++) {
     myfirstParam->SetValue(i, ThePar(i));
   }
@@ -1050,8 +1054,8 @@ void Approx_BSplComputeLine::SetKnots(const TColStd_Array1OfReal& Knots)
 //purpose  : 
 //=======================================================================
 void Approx_BSplComputeLine::SetKnotsAndMultiplicities
-  (const TColStd_Array1OfReal&    Knots,
-   const TColStd_Array1OfInteger& Mults)
+(const TColStd_Array1OfReal&    Knots,
+  const TColStd_Array1OfInteger& Mults)
 {
   myhasknots = Standard_True;
   myhasmults = Standard_True;
@@ -1071,13 +1075,13 @@ void Approx_BSplComputeLine::SetKnotsAndMultiplicities
 //purpose  : 
 //=======================================================================
 void Approx_BSplComputeLine::Init(const Standard_Integer degreemin,
-                             const Standard_Integer degreemax,
-                             const Standard_Real Tolerance3d,
-                             const Standard_Real Tolerance2d,
-                             const Standard_Integer NbIterations,
-                             const Standard_Boolean cutting,
-                             const Approx_ParametrizationType parametrization,
-                             const Standard_Boolean Squares)
+  const Standard_Integer degreemax,
+  const Standard_Real Tolerance3d,
+  const Standard_Real Tolerance2d,
+  const Standard_Integer NbIterations,
+  const Standard_Boolean cutting,
+  const Approx_ParametrizationType parametrization,
+  const Standard_Boolean Squares)
 {
   mydegremin = degreemin;
   mydegremax = degreemax;
@@ -1096,7 +1100,7 @@ void Approx_BSplComputeLine::Init(const Standard_Integer degreemin,
 //purpose  : 
 //=======================================================================
 void Approx_BSplComputeLine::SetDegrees(const Standard_Integer degreemin,
-                                   const Standard_Integer degreemax)
+  const Standard_Integer degreemax)
 {
   mydegremin = degreemin;
   mydegremax = degreemax;
@@ -1108,7 +1112,7 @@ void Approx_BSplComputeLine::SetDegrees(const Standard_Integer degreemin,
 //purpose  : 
 //=======================================================================
 void Approx_BSplComputeLine::SetTolerances(const Standard_Real Tolerance3d,
-                                      const Standard_Real Tolerance2d)
+  const Standard_Real Tolerance2d)
 {
   mytol3d = Tolerance3d;
   mytol2d = Tolerance2d;
@@ -1120,19 +1124,27 @@ void Approx_BSplComputeLine::SetTolerances(const Standard_Real Tolerance3d,
 //purpose  : 
 //=======================================================================
 void Approx_BSplComputeLine::SetConstraints(const AppParCurves_Constraint FirstC,
-                                       const AppParCurves_Constraint LastC)
+  const AppParCurves_Constraint LastC)
 {
   myfirstC = FirstC;
   mylastC = LastC;
 }
 
+//=======================================================================
+//function : SetPeriodic
+//purpose  : 
+//=======================================================================
+void Approx_BSplComputeLine::SetPeriodic(const Standard_Boolean thePeriodic)
+{
+  myPeriodic = thePeriodic;
+}
 
 
 //=======================================================================
 //function : IsAllApproximated
 //purpose  : 
 //=======================================================================
-Standard_Boolean Approx_BSplComputeLine::IsAllApproximated() const 
+Standard_Boolean Approx_BSplComputeLine::IsAllApproximated() const
 {
   return alldone;
 }
@@ -1141,7 +1153,7 @@ Standard_Boolean Approx_BSplComputeLine::IsAllApproximated() const
 //function : IsToleranceReached
 //purpose  : 
 //=======================================================================
-Standard_Boolean Approx_BSplComputeLine::IsToleranceReached() const 
+Standard_Boolean Approx_BSplComputeLine::IsToleranceReached() const
 {
   return tolreached;
 }
@@ -1151,7 +1163,7 @@ Standard_Boolean Approx_BSplComputeLine::IsToleranceReached() const
 //purpose  : 
 //=======================================================================
 void Approx_BSplComputeLine::Error(Standard_Real& tol3d,
-                                  Standard_Real& tol2d) const
+  Standard_Real& tol2d) const
 {
   tol3d = currenttol3d;
   tol2d = currenttol2d;
@@ -1181,14 +1193,14 @@ void Approx_BSplComputeLine::FindRealConstraints(const MultiLine& Line)
   Standard_Integer nbP2d, nbP3d;
   nbP3d = LineTool::NbP3d(Line);
   nbP2d = LineTool::NbP2d(Line);
-  Standard_Boolean Ok=Standard_False;
+  Standard_Boolean Ok = Standard_False;
   TColgp_Array1OfVec TabV(1, Max(1, nbP3d));
   TColgp_Array1OfVec2d TabV2d(1, Max(1, nbP2d));
   Standard_Integer Thefirstpt = LineTool::FirstPoint(Line);
-  Standard_Integer Thelastpt  = LineTool::LastPoint(Line);
+  Standard_Integer Thelastpt = LineTool::LastPoint(Line);
 
   if (myfirstC >= AppParCurves_TangencyPoint) {
-    
+
     if (nbP3d != 0 && nbP2d != 0)
       Ok = LineTool::Tangency(Line, Thefirstpt, TabV, TabV2d);
     else if (nbP2d != 0)
@@ -1200,22 +1212,22 @@ void Approx_BSplComputeLine::FindRealConstraints(const MultiLine& Line)
     if (Ok) {
       realfirstC = AppParCurves_TangencyPoint;
       if (myfirstC == AppParCurves_CurvaturePoint) {
-       if (nbP3d != 0 && nbP2d != 0)
-         Ok = LineTool::Tangency(Line, Thefirstpt, TabV, TabV2d);
-       else if (nbP2d != 0)
-         Ok = LineTool::Tangency(Line, Thefirstpt, TabV2d);
-       else if (nbP3d != 0)
-         Ok = LineTool::Tangency(Line, Thefirstpt, TabV);
-       if (Ok) {
-         realfirstC = AppParCurves_CurvaturePoint;
-       }
+        if (nbP3d != 0 && nbP2d != 0)
+          Ok = LineTool::Tangency(Line, Thefirstpt, TabV, TabV2d);
+        else if (nbP2d != 0)
+          Ok = LineTool::Tangency(Line, Thefirstpt, TabV2d);
+        else if (nbP3d != 0)
+          Ok = LineTool::Tangency(Line, Thefirstpt, TabV);
+        if (Ok) {
+          realfirstC = AppParCurves_CurvaturePoint;
+        }
       }
     }
   }
 
 
   if (mylastC >= AppParCurves_TangencyPoint) {
-    
+
     if (nbP3d != 0 && nbP2d != 0)
       Ok = LineTool::Tangency(Line, Thelastpt, TabV, TabV2d);
     else if (nbP2d != 0)
@@ -1227,15 +1239,15 @@ void Approx_BSplComputeLine::FindRealConstraints(const MultiLine& Line)
     if (Ok) {
       reallastC = AppParCurves_TangencyPoint;
       if (mylastC == AppParCurves_CurvaturePoint) {
-       if (nbP3d != 0 && nbP2d != 0)
-         Ok = LineTool::Tangency(Line, Thelastpt, TabV, TabV2d);
-       else if (nbP2d != 0)
-         Ok = LineTool::Tangency(Line, Thelastpt, TabV2d);
-       else if (nbP3d != 0)
-         Ok = LineTool::Tangency(Line, Thelastpt, TabV);
-       if (Ok) {
-         reallastC = AppParCurves_CurvaturePoint;
-       }
+        if (nbP3d != 0 && nbP2d != 0)
+          Ok = LineTool::Tangency(Line, Thelastpt, TabV, TabV2d);
+        else if (nbP2d != 0)
+          Ok = LineTool::Tangency(Line, Thelastpt, TabV2d);
+        else if (nbP3d != 0)
+          Ok = LineTool::Tangency(Line, Thelastpt, TabV);
+        if (Ok) {
+          reallastC = AppParCurves_CurvaturePoint;
+        }
       }
     }
   }
@@ -1249,20 +1261,20 @@ void Approx_BSplComputeLine::FindRealConstraints(const MultiLine& Line)
 //function : Interpol
 //purpose  : 
 //=======================================================================
-void Approx_BSplComputeLine::Interpol(const MultiLine& Line) 
+void Approx_BSplComputeLine::Interpol(const MultiLine& Line)
 {
   Standard_Integer i, Thefirstpt, Thelastpt, deg = 3;
   mycont = 2;
   Thefirstpt = LineTool::FirstPoint(Line);
-  Thelastpt  = LineTool::LastPoint(Line);
+  Thelastpt = LineTool::LastPoint(Line);
   math_Vector TheParam(Thefirstpt, Thelastpt, 0.0);
   //Par = Approx_ChordLength;
-  if(myfirstParam.IsNull()) {
+  if (myfirstParam.IsNull()) {
     Parameters(Line, Thefirstpt, Thelastpt, TheParam);
   }
   else {
     for (i = myfirstParam->Lower(); i <= myfirstParam->Upper(); i++) {
-      TheParam(i+Thefirstpt-1) = myfirstParam->Value(i);
+      TheParam(i + Thefirstpt - 1) = myfirstParam->Value(i);
     }
   }
   AppParCurves_Constraint Cons = AppParCurves_TangencyPoint;
@@ -1276,98 +1288,103 @@ void Approx_BSplComputeLine::Interpol(const MultiLine& Line)
   if (nbpoints == 2) {
     Cons = AppParCurves_NoConstraint;
     Standard_Integer mydeg = 1;
-    Approx_BSpParLeastSquareOfMyBSplGradient 
-      LSQ(Line, Thefirstpt, Thelastpt, Cons, Cons, TheParam, mydeg+1);
+    Approx_BSpParLeastSquareOfMyBSplGradient
+      LSQ(Line, Thefirstpt, Thelastpt, Cons, Cons, TheParam, mydeg + 1);
     alldone = LSQ.IsDone();
     TColStd_Array1OfReal TheKnots(1, 2);
     TColStd_Array1OfInteger TheMults(1, 2);
     TheKnots(1) = TheParam(Thefirstpt);  TheKnots(2) = TheParam(Thelastpt);
-    TheMults(1) = TheMults(2) = mydeg+1;
-    TheMultiBSpCurve = 
-      AppParCurves_MultiBSpCurve (LSQ.BezierValue(),TheKnots,TheMults);
+    TheMults(1) = TheMults(2) = mydeg + 1;
+    TheMultiBSpCurve =
+      AppParCurves_MultiBSpCurve(LSQ.BezierValue(), TheKnots, TheMults);
     LSQ.Error(Fv, currenttol3d, currenttol2d);
 
   }
   else {
     nbpoles = nbpoints + 2;
     nbknots = nbpoints;
-    
+
     // Resolution:
     TColStd_Array1OfReal Theknots(1, nbknots);
-    Theknots(1) = TheParam(Thefirstpt);  
+    Theknots(1) = TheParam(Thefirstpt);
     Theknots(nbknots) = TheParam(Thelastpt);
     TColStd_Array1OfInteger TheMults(1, nbknots);
-    TheMults(1) = deg+1;
-    TheMults(nbknots) = deg+1;
-    
+    TheMults(1) = deg + 1;
+    TheMults(nbknots) = deg + 1;
+
     Standard_Integer low = TheParam.Lower();
-    for (i = 2; i <= nbknots-1; i++) {
-      Theknots(i) = TheParam(i+low-1);
-      TheMults(i) = 1;  
+    for (i = 2; i <= nbknots - 1; i++) {
+      Theknots(i) = TheParam(i + low - 1);
+      TheMults(i) = 1;
     }
 
 
-    Standard_Integer nbP = 3*LineTool::NbP3d(Line)+ 2*LineTool::NbP2d(Line);
+    Standard_Integer nbP = 3 * LineTool::NbP3d(Line) + 2 * LineTool::NbP2d(Line);
     math_Vector V1(1, nbP), V2(1, nbP);
 
     if (nbpoints == 3 || nbpoints == 4) {
       FirstTangencyVector(Line, Thefirstpt, V1);
       lambda1 = SearchFirstLambda(Line, TheParam, Theknots, V1, Thefirstpt);
-      
+
       LastTangencyVector(Line, Thelastpt, V2);
       lambda2 = SearchLastLambda(Line, TheParam, Theknots, V2, Thelastpt);
-    }
 
+      lambda1 = lambda1 / deg;
+      lambda2 = lambda2 / deg;
+    }
     else {
       Standard_Integer nnpol, nnp = Min(nbpoints, 9);
       nnpol = nnp;
-      Standard_Integer lastp = Min(Thelastpt, Thefirstpt + nnp-1);
+      Standard_Integer lastp = Min(Thelastpt, Thefirstpt + nnp - 1);
       Standard_Real U;
-      Approx_BSpParLeastSquareOfMyBSplGradient 
-       SQ1(Line, Thefirstpt, lastp, Cons, Cons, nnpol);
-      
+      Approx_BSpParLeastSquareOfMyBSplGradient
+        SQ1(Line, Thefirstpt, lastp, Cons, Cons, nnpol);
+
       math_Vector P1(Thefirstpt, lastp);
-      for (i=Thefirstpt; i <=lastp; i++) P1(i) = TheParam(i);
+      for (i = Thefirstpt; i <= lastp; i++) P1(i) = TheParam(i);
       SQ1.Perform(P1);
       const AppParCurves_MultiCurve& C1 = SQ1.BezierValue();
       U = 0.0;
       TangencyVector(Line, C1, U, V1);
-      
-      Standard_Integer firstp = Max(Thefirstpt, Thelastpt - nnp+1);
-      
-      
+
+      Standard_Integer firstp = Max(Thefirstpt, Thelastpt - nnp + 1);
+
       if (firstp == Thefirstpt && lastp == Thelastpt) {
-       U = 1.0;
-       TangencyVector (Line, C1, U, V2);
+        U = 1.0;
+        TangencyVector(Line, C1, U, V2);
       }
       else {
-       Approx_BSpParLeastSquareOfMyBSplGradient 
-         SQ2(Line, firstp, Thelastpt, Cons, Cons, nnpol);
-       
-       math_Vector P2(firstp, Thelastpt);
-       for (i=firstp; i <=Thelastpt; i++) P2(i) = TheParam(i);
-       SQ2.Perform(P2);
-       const AppParCurves_MultiCurve& C2 = SQ2.BezierValue();
-       U = 1.0;
-       TangencyVector(Line, C2, U, V2);
+        Approx_BSpParLeastSquareOfMyBSplGradient
+          SQ2(Line, firstp, Thelastpt, Cons, Cons, nnpol);
+
+        math_Vector P2(firstp, Thelastpt);
+        for (i = firstp; i <= Thelastpt; i++) P2(i) = TheParam(i);
+        SQ2.Perform(P2);
+        const AppParCurves_MultiCurve& C2 = SQ2.BezierValue();
+        U = 1.0;
+        TangencyVector(Line, C2, U, V2);
       }
-      
-      
-      lambda1 = 1./deg;
-      lambda1 = lambda1*(Theknots(2)-Theknots(1))
-       /(Theknots(nbknots)-Theknots(1));
-      lambda2 = 1./deg;
-      lambda2 = lambda2*(Theknots(nbknots)-Theknots(nbknots-1))
-       /(Theknots(nbknots)-Theknots(1));
-      
-    }
 
-    Approx_BSpParLeastSquareOfMyBSplGradient 
-      SQ(Line, Theknots,TheMults,Thefirstpt, Thelastpt, 
-        Cons, Cons, nbpoles);
     
-    lambda1 = lambda1/deg;
-    lambda2 = lambda2/deg;
+      lambda1 = 1. / deg;
+      lambda1 = lambda1*(Theknots(2) - Theknots(1))
+        / (Theknots(nbknots) - Theknots(1));
+      lambda2 = 1. / deg;
+      lambda2 = lambda2*(Theknots(nbknots) - Theknots(nbknots - 1))
+        / (Theknots(nbknots) - Theknots(1));
+
+    }
+
+    if (myPeriodic)
+    {
+      V1 = 0.5 * (V1 + V2);
+      V2 = V1;
+    }
+
+    Approx_BSpParLeastSquareOfMyBSplGradient
+      SQ(Line, Theknots, TheMults, Thefirstpt, Thelastpt,
+        Cons, Cons, nbpoles);
+
     SQ.Perform(TheParam, V1, V2, lambda1, lambda2);
     alldone = SQ.IsDone();
     TheMultiBSpCurve = SQ.BSplineValue();
@@ -1386,16 +1403,16 @@ void Approx_BSplComputeLine::Interpol(const MultiLine& Line)
 //purpose  : 
 //=======================================================================
 void Approx_BSplComputeLine::TangencyVector(
-       const MultiLine&               Line,
-       const AppParCurves_MultiCurve& C,
-       const Standard_Real            U,
-       math_Vector&                   V) const 
+  const MultiLine&               Line,
+  const AppParCurves_MultiCurve& C,
+  const Standard_Real            U,
+  math_Vector&                   V) const
 {
 
   Standard_Integer i, j, nbP2d, nbP3d;
   nbP3d = LineTool::NbP3d(Line);
   nbP2d = LineTool::NbP2d(Line);
-    
+
   gp_Pnt myP;
   gp_Vec myV;
   gp_Pnt2d myP2d;
@@ -1403,16 +1420,16 @@ void Approx_BSplComputeLine::TangencyVector(
   j = 1;
   for (i = 1; i <= nbP3d; i++) {
     C.D1(i, U, myP, myV);
-    V(j)   = myV.X();
-    V(j+1) = myV.Y();
-    V(j+2) = myV.Z();
+    V(j) = myV.X();
+    V(j + 1) = myV.Y();
+    V(j + 2) = myV.Z();
     j += 3;
   }
-  j = nbP3d*3+1;
-  for (i = nbP3d+1; i <= nbP3d+nbP2d; i++) {
+  j = nbP3d * 3 + 1;
+  for (i = nbP3d + 1; i <= nbP3d + nbP2d; i++) {
     C.D1(i, U, myP2d, myV2d);
-    V(j)   = myV2d.X();
-    V(j+1) = myV2d.Y();
+    V(j) = myV2d.X();
+    V(j + 1) = myV2d.Y();
     j += 2;
   }
 
index 9e87875..75d5c30 100644 (file)
@@ -117,6 +117,12 @@ public:
   //! changes the first and the last constraint points.
   Standard_EXPORT void SetConstraints (const AppParCurves_Constraint firstC, const AppParCurves_Constraint lastC);
   
+  //! Sets periodic flag.
+  //! If thePeriodic = Standard_True, algorith tries to build periodic
+  //! multicurve using corresponding C1 boundary condition for first and last multipoints.
+  //! Multiline must be closed.
+  Standard_EXPORT void SetPeriodic(const Standard_Boolean thePeriodic);
+
   //! returns False if at a moment of the approximation,
   //! the status NoApproximation has been sent by the user
   //! when more points were needed.
@@ -199,6 +205,7 @@ private:
   Standard_Integer mycont;
   Standard_Real mylambda1;
   Standard_Real mylambda2;
+  Standard_Boolean myPeriodic;
 
 
 };
index c016aa1..c1a2c35 100644 (file)
 #include <Precision.hxx>
 #include <StdFail_NotDone.hxx>
 #include <TColgp_Array1OfPnt.hxx>
+#include <AppDef_BSpParLeastSquareOfMyBSplGradientOfBSplineCompute.hxx>
+
+static void BuildParameters(const AppDef_MultiLine& theLine,
+  const Approx_ParametrizationType theParT,
+  TColStd_Array1OfReal&  thePars)
+{
+  Standard_Integer i, j, nbP3d = theLine.NbPoints();
+  Standard_Real dist;
+  Standard_Integer firstP = 1, lastP = theLine.NbMultiPoints();
+  const Standard_Integer aNbp = lastP - firstP + 1;
+
+
+  if (aNbp == 2) {
+    thePars(firstP) = 0.0;
+    thePars(lastP) = 1.0;
+  }
+  else if (theParT == Approx_ChordLength || theParT == Approx_Centripetal)
+  {
+
+    thePars(firstP) = 0.0;
+    dist = 0.0;
+
+    for (i = firstP + 1; i <= lastP; i++)
+    {
+      AppDef_MultiPointConstraint aMPC = theLine.Value(i - 1);
+      AppDef_MultiPointConstraint aMPC1 = theLine.Value(i);
+
+      dist = 0.0;
+      for (j = 1; j <= nbP3d; j++)
+      {
+        const gp_Pnt &aP1 = aMPC.Point(j),
+                     &aP2 = aMPC1.Point(j);
+        dist += aP2.SquareDistance(aP1);
+      }
+
+      dist = Sqrt(dist);
+      if (theParT == Approx_ChordLength)
+      {
+        thePars(i) = thePars(i - 1) + dist;
+      }
+      else
+      {// Par == Approx_Centripetal
+        thePars(i) = thePars(i - 1) + Sqrt(dist);
+      }
+    }
+    for (i = firstP; i <= lastP; i++) thePars(i) /= thePars(lastP);
+  }
+  else {
+    for (i = firstP; i <= lastP; i++) {
+      thePars(i) = (Standard_Real(i) - firstP) /
+        (Standard_Real(lastP - Standard_Real(firstP)));
+    }
+  }
+
+}
+
+static void BuildPeriodicTangent(const AppDef_MultiLine& theLine,
+  const TColStd_Array1OfReal&  thePars,
+  math_Vector& theTang)
+{
+  Standard_Integer firstpt = 1, lastpt = theLine.NbMultiPoints();
+  Standard_Integer nbpoints = lastpt - firstpt + 1;
+  //
+  if (nbpoints <= 2)
+  {
+    return;
+  }
+  //
+  Standard_Integer i, nnpol, nnp = Min(nbpoints, 9);
+  nnpol = nnp;
+  Standard_Integer lastp = Min(lastpt, firstpt + nnp - 1);
+  Standard_Real U;
+  AppParCurves_Constraint Cons = AppParCurves_TangencyPoint;
+  if (nnp <= 4)
+  {
+    Cons = AppParCurves_PassPoint;
+  }
+  Standard_Integer nbP = 3 * theLine.NbPoints();
+  math_Vector V1(1, nbP), V2(1, nbP);
+  math_Vector P1(firstpt, lastp);
+  //
+  for (i = firstpt; i <= lastp; i++)
+  {
+    P1(i) = thePars(i);
+  }
+  AppDef_BSpParLeastSquareOfMyBSplGradientOfBSplineCompute SQ1(theLine, firstpt, lastp, Cons, Cons, nnpol);
+  SQ1.Perform(P1);
+  const AppParCurves_MultiCurve& C1 = SQ1.BezierValue();
+  U = 0.0;
+  Standard_Integer  j, nbP3d = theLine.NbPoints();
+
+  gp_Pnt aP;
+  gp_Vec aV;
+  j = 1;
+  for (i = 1; i <= nbP3d; i++) {
+    C1.D1(i, U, aP, aV);
+    V1(j) = aV.X();
+    V1(j + 1) = aV.Y();
+    V1(j + 2) = aV.Z();
+    j += 3;
+  }
+
+  Standard_Integer firstp = Max(firstpt, lastpt - nnp + 1);
+
+  if (firstp == firstpt && lastp == lastpt) {
+    U = 1.0;
+    j = 1;
+    for (i = 1; i <= nbP3d; i++) {
+      C1.D1(i, U, aP, aV);
+      V2(j) = aV.X();
+      V2(j + 1) = aV.Y();
+      V2(j + 2) = aV.Z();
+      j += 3;
+    }
+  }
+  else {
+    AppDef_BSpParLeastSquareOfMyBSplGradientOfBSplineCompute
+      SQ2(theLine, firstp, lastpt, Cons, Cons, nnpol);
+
+    math_Vector P2(firstp, lastpt);
+    for (i = firstp; i <= lastpt; i++) P2(i) = thePars(i);
+    SQ2.Perform(P2);
+
+    const AppParCurves_MultiCurve& C2 = SQ2.BezierValue();
+    U = 1.0;
+    j = 1;
+    for (i = 1; i <= nbP3d; i++) {
+      C2.D1(i, U, aP, aV);
+      V2(j) = aV.X();
+      V2(j + 1) = aV.Y();
+      V2(j + 2) = aV.Z();
+      j += 3;
+    }
+  }
+
+  theTang = 0.5*(V1 + V2);
+
+}
 
 //=======================================================================
 //function : GeomAPI_PointsToBSplineSurface
@@ -125,9 +264,10 @@ GeomAPI_PointsToBSplineSurface::GeomAPI_PointsToBSplineSurface
 //purpose  : 
 //=======================================================================
 
-void GeomAPI_PointsToBSplineSurface::Interpolate(const TColgp_Array2OfPnt& Points)
+void GeomAPI_PointsToBSplineSurface::Interpolate(const TColgp_Array2OfPnt& Points,
+                                                 const Standard_Boolean thePeriodic)
 {
-  Interpolate(Points, Approx_ChordLength);
+  Interpolate(Points, Approx_ChordLength, thePeriodic);
 }
 
 //=======================================================================
@@ -136,13 +276,14 @@ void GeomAPI_PointsToBSplineSurface::Interpolate(const TColgp_Array2OfPnt& Point
 //=======================================================================
 
 void GeomAPI_PointsToBSplineSurface::Interpolate(const TColgp_Array2OfPnt& Points,
-                                                const Approx_ParametrizationType ParType)
+                                          const Approx_ParametrizationType ParType,
+                                          const Standard_Boolean thePeriodic)
 {
   Standard_Integer DegMin, DegMax;
   DegMin = DegMax = 3;
   GeomAbs_Shape CC  = GeomAbs_C2;
   Standard_Real Tol3d = -1.0;
-  Init(Points, ParType, DegMin, DegMax, CC, Tol3d);
+  Init(Points, ParType, DegMin, DegMax, CC, Tol3d, thePeriodic);
 }
 
 
@@ -165,11 +306,12 @@ void GeomAPI_PointsToBSplineSurface::Init(const TColgp_Array2OfPnt& Points,
 //=======================================================================
 
 void GeomAPI_PointsToBSplineSurface::Init(const TColgp_Array2OfPnt& Points,
-                                         const Approx_ParametrizationType ParType,
-                                         const Standard_Integer DegMin, 
-                                         const Standard_Integer DegMax, 
-                                         const GeomAbs_Shape Continuity,
-                                         const Standard_Real Tol3D)
+            const Approx_ParametrizationType ParType,
+            const Standard_Integer DegMin, 
+            const Standard_Integer DegMax, 
+            const GeomAbs_Shape Continuity,
+            const Standard_Real Tol3D,
+            const Standard_Boolean thePeriodic)
 {
   Standard_Integer Imin = Points.LowerRow();
   Standard_Integer Imax = Points.UpperRow();
@@ -178,19 +320,30 @@ void GeomAPI_PointsToBSplineSurface::Init(const TColgp_Array2OfPnt& Points,
 
   Standard_Real Tol2D = Tol3D;
 
-  // first approximate the V isos:
+  // first approximate the U isos:
+  Standard_Integer add = 1;
+  if (thePeriodic)
+  {
+    add = 2;
+  }
   AppDef_MultiLine Line(Jmax-Jmin+1);
   Standard_Integer i, j;
-//  Standard_Real X, Y;
 
   for (j = Jmin; j <= Jmax; j++) {
-    AppDef_MultiPointConstraint MP(Imax-Imin+1, 0);
+    AppDef_MultiPointConstraint MP(Imax-Imin+add, 0);
     for (i = Imin; i <= Imax; i++) {
       MP.SetPoint(i, Points(i,j));
     }
+    if (thePeriodic)
+    {
+      MP.SetPoint(Imax+1, Points(1, j));
+    }
     Line.SetValue(j, MP);
   }
 
+
+
+
   Standard_Integer nbit = 2;
   Standard_Boolean UseSquares = Standard_False;
   if(Tol3D <= 1.e-3) UseSquares = Standard_True;
@@ -229,7 +382,7 @@ void GeomAPI_PointsToBSplineSurface::Init(const TColgp_Array2OfPnt& Points,
   const TColStd_Array1OfInteger& VMults = TheCurve.Multiplicities();
   
 
-  Standard_Integer nbisosu = Imax-Imin+1;
+  Standard_Integer nbisosu = Imax-Imin+add;
   AppDef_MultiLine Line2(nbisosu);
 
   for (i = 1; i <= nbisosu; i++) {
@@ -247,9 +400,43 @@ void GeomAPI_PointsToBSplineSurface::Init(const TColgp_Array2OfPnt& Points,
   AppDef_BSplineCompute TheComputer2
     (DegMin,DegMax,Tol3D,Tol2D,nbit,Standard_True,ParType,UseSquares);
   if (Tol3D <= 0.0) {
+    if (thePeriodic)
+    {
+      TheComputer2.SetPeriodic(thePeriodic);
+    }
     TheComputer2.Interpol(Line2);
   }
   else {
+    if (thePeriodic && Line2.NbMultiPoints() > 2)
+    {
+      TheComputer2.SetPeriodic(thePeriodic);
+      //
+      TColStd_Array1OfReal aPars(1, Line2.NbMultiPoints());
+      BuildParameters(Line2, ParType, aPars);
+      math_Vector aTang(1, 3 * Poles.Upper());
+      BuildPeriodicTangent(Line2, aPars, aTang);
+      Standard_Integer ind = 1;
+      TheCurve.Curve(ind, Poles);
+      AppDef_MultiPointConstraint MP1(Poles.Upper(), 0);
+      for (j = 1; j <= Poles.Upper(); j++) {
+        MP1.SetPoint(j, Poles(j));
+        Standard_Integer k = 3 * (j - 1);
+        gp_Vec aT(aTang(k + 1), aTang(k + 2), aTang(k + 3));
+        MP1.SetTang(j, aT);
+      }
+      Line2.SetValue(ind, MP1);
+      //
+      ind = Line2.NbMultiPoints();
+      TheCurve.Curve(ind, Poles);
+      AppDef_MultiPointConstraint MP2(Poles.Upper(), 0);
+      for (j = 1; j <= Poles.Upper(); j++) {
+        MP2.SetPoint(j, Poles(j));
+        Standard_Integer k = 3 * (j - 1);
+        gp_Vec aT(aTang(k + 1), aTang(k + 2), aTang(k + 3));
+        MP2.SetTang(j, aT);
+      }
+      Line2.SetValue(ind, MP2);
+    }
     TheComputer2.Perform(Line2);
   }
   
@@ -273,6 +460,10 @@ void GeomAPI_PointsToBSplineSurface::Init(const TColgp_Array2OfPnt& Points,
 
   mySurface = new Geom_BSplineSurface(ThePoles, UKnots, VKnots, UMults, VMults,
                                      UDegree, VDegree);
+  if (thePeriodic && Line2.NbMultiPoints() > 2)
+  {
+    mySurface->SetUPeriodic();
+  }
 
   myIsDone = Standard_True;
 }
@@ -299,7 +490,7 @@ void GeomAPI_PointsToBSplineSurface::Init(const TColgp_Array2OfPnt& Points,
   Standard_Integer nbit = 2;
   if(Tol3D <= 1.e-3) nbit = 0;
 
-  // first approximate the V isos:
+  // first approximate the U isos:
   Standard_Integer NbPointJ = Jmax-Jmin+1;
   Standard_Integer NbPointI = Imax-Imin+1;
   Standard_Integer i, j;
@@ -485,7 +676,7 @@ void GeomAPI_PointsToBSplineSurface::Init(const TColStd_Array2OfReal& ZPoints,
 
   Standard_Real Tol2D = Tol3D;
 
-  // first approximate the V isos:
+  // first approximate the U isos:
   AppDef_MultiLine Line(Jmax-Jmin+1);
   math_Vector Param(Jmin, Jmax);
   Standard_Integer i, j;
index 21e9cee..284cb84 100644 (file)
@@ -41,7 +41,37 @@ class StdFail_NotDone;
 //! -   defining the data of the BSpline surface to be built,
 //! -   implementing the approximation algorithm
 //! or the interpolation algorithm, and consulting the results.
-class GeomAPI_PointsToBSplineSurface 
+//! In fact, class contains 3 algorithms, 2 for approximation and 1
+//! for interpolation.
+//! First approximation algorithm is based on usual least square criterium:
+//! minimization of square distance between samplimg points and result surface.
+//! Second approximation algorithm uses least square criterium and additional 
+//! minimization of some local characteristic of surface (first, second and third
+//! partial derivative), which allows managing shape of surface. 
+//! Interpolation algorithm produces surface, which passes through sampling points.
+//!
+//! There is accordance between parametrization of result surface S(U, V) and
+//! indexes of array Points(i, j): first index corresponds U parameter of surface, 
+//! second - V parameter of surface.
+//! So, points of any j-th column Points(*, j) represent any V isoline of surface,
+//! points of any i-th row Point(i, *) represent any U isoline of surface.
+//! 
+//! For each sampling point parameters U, V are calculated according to 
+//! type of parametrization, which can be Approx_ChordLength, Approx_Centripetal 
+//! or Approx_IsoParametric. Default value is Approx_ChordLength.
+//! For ChordLength parametrisation U(i) = U(i-1) + P(i).Distance(P(i-1)),
+//! For Centripetal type  U(i) = U(i-1) + Sqrt(P(i).Distance(P(i-1))).
+//! Centripetal type can get better result for irregular distances between points.
+//!
+//! Approximation and interpolation algorithms can build periodical surface along U
+//! direction, which corresponds colums of array Points(i, j), 
+//! if corresponding parameter (thePeriodic, see comments below) of called 
+//! methods is set to True. Algorithm uses first row Points(1, *) as periodic boundary,
+//! so to avoid getting wrong surface it is necessary to keep distance between 
+//! corresponding points of first and last rows of Points:
+//! Points(1, *) != Points(Upper, *).
+
+class GeomAPI_PointsToBSplineSurface
 {
 public:
 
@@ -63,8 +93,11 @@ public:
   //! 1- his degree will be in the range [Degmin,Degmax]
   //! 2- his  continuity will be  at  least <Continuity>
   //! 3- the distance from the point <Points> to the
-  //! BSpline will be lower to Tol3D
-  Standard_EXPORT GeomAPI_PointsToBSplineSurface(const TColgp_Array2OfPnt& Points, const Standard_Integer DegMin = 3, const Standard_Integer DegMax = 8, const GeomAbs_Shape Continuity = GeomAbs_C2, const Standard_Real Tol3D = 1.0e-3);
+  //! BSpline will be lower to Tol3D.
+
+  Standard_EXPORT GeomAPI_PointsToBSplineSurface(const TColgp_Array2OfPnt& Points, 
+    const Standard_Integer DegMin = 3, const Standard_Integer DegMax = 8, 
+    const GeomAbs_Shape Continuity = GeomAbs_C2, const Standard_Real Tol3D = 1.0e-3);
   
   //! Approximates  a BSpline  Surface passing  through  an
   //! array of  Points.  The resulting BSpline will  have
@@ -72,14 +105,22 @@ public:
   //! 1- his degree will be in the range [Degmin,Degmax]
   //! 2- his  continuity will be  at  least <Continuity>
   //! 3- the distance from the point <Points> to the
-  //! BSpline will be lower to Tol3D
-  Standard_EXPORT GeomAPI_PointsToBSplineSurface(const TColgp_Array2OfPnt& Points, const Approx_ParametrizationType ParType, const Standard_Integer DegMin = 3, const Standard_Integer DegMax = 8, const GeomAbs_Shape Continuity = GeomAbs_C2, const Standard_Real Tol3D = 1.0e-3);
+  //! BSpline will be lower to Tol3D.
+
+  Standard_EXPORT GeomAPI_PointsToBSplineSurface(const TColgp_Array2OfPnt& Points, 
+    const Approx_ParametrizationType ParType, 
+    const Standard_Integer DegMin = 3, const Standard_Integer DegMax = 8, 
+    const GeomAbs_Shape Continuity = GeomAbs_C2, const Standard_Real Tol3D = 1.0e-3);
   
   //! Approximates  a BSpline  Surface passing  through  an
   //! array of  points using variational smoothing algorithm,
   //! which tries to minimize additional criterium:
-  //! Weight1*CurveLength + Weight2*Curvature + Weight3*Torsion
-  Standard_EXPORT GeomAPI_PointsToBSplineSurface(const TColgp_Array2OfPnt& Points, const Standard_Real Weight1, const Standard_Real Weight2, const Standard_Real Weight3, const Standard_Integer DegMax = 8, const GeomAbs_Shape Continuity = GeomAbs_C2, const Standard_Real Tol3D = 1.0e-3);
+  //! Weight1*CurveLength + Weight2*Curvature + Weight3*Torsion.
+
+  Standard_EXPORT GeomAPI_PointsToBSplineSurface(const TColgp_Array2OfPnt& Points, 
+    const Standard_Real Weight1, const Standard_Real Weight2, const Standard_Real Weight3, 
+    const Standard_Integer DegMax = 8, const GeomAbs_Shape Continuity = GeomAbs_C2, 
+    const Standard_Real Tol3D = 1.0e-3);
   
   //! Approximates  a BSpline  Surface passing  through  an
   //! array of  Points.
@@ -97,7 +138,12 @@ public:
   //! BSpline will be lower to Tol3D
   //! 4- the parametrization of the surface will verify:
   //! S->Value( U, V) = gp_Pnt( U, V, Z(U,V) );
-  Standard_EXPORT GeomAPI_PointsToBSplineSurface(const TColStd_Array2OfReal& ZPoints, const Standard_Real X0, const Standard_Real dX, const Standard_Real Y0, const Standard_Real dY, const Standard_Integer DegMin = 3, const Standard_Integer DegMax = 8, const GeomAbs_Shape Continuity = GeomAbs_C2, const Standard_Real Tol3D = 1.0e-3);
+
+  Standard_EXPORT GeomAPI_PointsToBSplineSurface(const TColStd_Array2OfReal& ZPoints, 
+    const Standard_Real X0, const Standard_Real dX, 
+    const Standard_Real Y0, const Standard_Real dY,
+    const Standard_Integer DegMin = 3, const Standard_Integer DegMax = 8, 
+    const GeomAbs_Shape Continuity = GeomAbs_C2, const Standard_Real Tol3D = 1.0e-3);
   
   //! Approximates  a BSpline Surface passing  through  an
   //! array of  Point.  The resulting BSpline will  have
@@ -105,22 +151,29 @@ public:
   //! 1- his degree will be in the range [Degmin,Degmax]
   //! 2- his  continuity will be  at  least <Continuity>
   //! 3- the distance from the point <Points> to the
-  //! BSpline will be lower to Tol3D
-  Standard_EXPORT void Init (const TColgp_Array2OfPnt& Points, const Standard_Integer DegMin = 3, const Standard_Integer DegMax = 8, const GeomAbs_Shape Continuity = GeomAbs_C2, const Standard_Real Tol3D = 1.0e-3);
+  //! BSpline will be lower to Tol3D.
+
+  Standard_EXPORT void Init (const TColgp_Array2OfPnt& Points, 
+    const Standard_Integer DegMin = 3, const Standard_Integer DegMax = 8, 
+    const GeomAbs_Shape Continuity = GeomAbs_C2, const Standard_Real Tol3D = 1.0e-3);
   
   //! Interpolates  a BSpline Surface passing  through  an
   //! array of  Point.  The resulting BSpline will  have
   //! the following properties:
   //! 1- his degree will be 3.
   //! 2- his  continuity will be  C2.
-  Standard_EXPORT void Interpolate (const TColgp_Array2OfPnt& Points);
+
+  Standard_EXPORT void Interpolate (const TColgp_Array2OfPnt& Points,  
+                                    const Standard_Boolean thePeriodic = Standard_False);
   
   //! Interpolates  a BSpline Surface passing  through  an
   //! array of  Point.  The resulting BSpline will  have
   //! the following properties:
   //! 1- his degree will be 3.
   //! 2- his  continuity will be  C2.
-  Standard_EXPORT void Interpolate (const TColgp_Array2OfPnt& Points, const Approx_ParametrizationType ParType);
+
+  Standard_EXPORT void Interpolate (const TColgp_Array2OfPnt& Points, const Approx_ParametrizationType ParType,
+                                    const Standard_Boolean thePeriodic = Standard_False);
   
   //! Approximates  a BSpline  Surface passing  through  an
   //! array of  Points.
@@ -138,7 +191,12 @@ public:
   //! BSpline will be lower to Tol3D
   //! 4- the parametrization of the surface will verify:
   //! S->Value( U, V) = gp_Pnt( U, V, Z(U,V) );
-  Standard_EXPORT void Init (const TColStd_Array2OfReal& ZPoints, const Standard_Real X0, const Standard_Real dX, const Standard_Real Y0, const Standard_Real dY, const Standard_Integer DegMin = 3, const Standard_Integer DegMax = 8, const GeomAbs_Shape Continuity = GeomAbs_C2, const Standard_Real Tol3D = 1.0e-3);
+
+  Standard_EXPORT void Init (const TColStd_Array2OfReal& ZPoints, 
+    const Standard_Real X0, const Standard_Real dX, 
+    const Standard_Real Y0, const Standard_Real dY, 
+    const Standard_Integer DegMin = 3, const Standard_Integer DegMax = 8, 
+    const GeomAbs_Shape Continuity = GeomAbs_C2, const Standard_Real Tol3D = 1.0e-3);
   
   //! Interpolates  a BSpline  Surface passing  through  an
   //! array of  Points.
@@ -154,7 +212,9 @@ public:
   //! 2- his  continuity will be  C2.
   //! 4- the parametrization of the surface will verify:
   //! S->Value( U, V) = gp_Pnt( U, V, Z(U,V) );
-  Standard_EXPORT void Interpolate (const TColStd_Array2OfReal& ZPoints, const Standard_Real X0, const Standard_Real dX, const Standard_Real Y0, const Standard_Real dY);
+
+  Standard_EXPORT void Interpolate (const TColStd_Array2OfReal& ZPoints, 
+    const Standard_Real X0, const Standard_Real dX, const Standard_Real Y0, const Standard_Real dY);
   
   //! Approximates  a BSpline Surface passing  through  an
   //! array of  Point.  The resulting BSpline will  have
@@ -162,18 +222,27 @@ public:
   //! 1- his degree will be in the range [Degmin,Degmax]
   //! 2- his  continuity will be  at  least <Continuity>
   //! 3- the distance from the point <Points> to the
-  //! BSpline will be lower to Tol3D
-  Standard_EXPORT void Init (const TColgp_Array2OfPnt& Points, const Approx_ParametrizationType ParType, const Standard_Integer DegMin = 3, const Standard_Integer DegMax = 8, const GeomAbs_Shape Continuity = GeomAbs_C2, const Standard_Real Tol3D = 1.0e-3);
+  //! BSpline will be lower to Tol3D.
+
+  Standard_EXPORT void Init (const TColgp_Array2OfPnt& Points, 
+    const Approx_ParametrizationType ParType, 
+    const Standard_Integer DegMin = 3, const Standard_Integer DegMax = 8,
+    const GeomAbs_Shape Continuity = GeomAbs_C2, 
+    const Standard_Real Tol3D = 1.0e-3, const Standard_Boolean thePeriodic = Standard_False);
   
   //! Approximates  a BSpline Surface passing  through  an
   //! array of  point using variational smoothing algorithm,
   //! which tries to minimize additional criterium:
-  //! Weight1*CurveLength + Weight2*Curvature + Weight3*Torsion
-  Standard_EXPORT void Init (const TColgp_Array2OfPnt& Points, const Standard_Real Weight1, const Standard_Real Weight2, const Standard_Real Weight3, const Standard_Integer DegMax = 8, const GeomAbs_Shape Continuity = GeomAbs_C2, const Standard_Real Tol3D = 1.0e-3);
+  //! Weight1*CurveLength + Weight2*Curvature + Weight3*Torsion.
+
+  Standard_EXPORT void Init (const TColgp_Array2OfPnt& Points, 
+    const Standard_Real Weight1, const Standard_Real Weight2, const Standard_Real Weight3, 
+    const Standard_Integer DegMax = 8, 
+    const GeomAbs_Shape Continuity = GeomAbs_C2, const Standard_Real Tol3D = 1.0e-3);
   
   //! Returns the approximate BSpline Surface
   Standard_EXPORT const Handle(Geom_BSplineSurface)& Surface() const;
-Standard_EXPORT operator Handle(Geom_BSplineSurface)() const;
+  Standard_EXPORT operator Handle(Geom_BSplineSurface)() const;
   
   Standard_EXPORT Standard_Boolean IsDone() const;
 
index 07a69e3..a4a1c67 100644 (file)
@@ -590,6 +590,7 @@ GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
     Standard_Integer nbIt = 0, degmin = 2, degmax = 6;
     Standard_Boolean knownP = Nbpar > 0;
     GeomFill_AppSurf anApprox(degmin, degmax, myPres3d, myPres3d, nbIt, knownP);
+    anApprox.SetContinuity(GeomAbs_C1);
     Standard_Boolean SpApprox = Standard_True;
     anApprox.Perform(line, section, SpApprox);
 
index b3a6e97..57d1b07 100644 (file)
@@ -116,7 +116,13 @@ public:
   
   //! changes the first and the last constraint points.
   Standard_EXPORT void SetConstraints (const AppParCurves_Constraint firstC, const AppParCurves_Constraint lastC);
-  
+
+  //! Sets periodic flag.
+  //! If thePeriodic = Standard_True, algorith tries to build periodic
+  //! multicurve using corresponding C1 boundary condition for first and last multipoints.
+  //! Multiline must be closed.
+  Standard_EXPORT void SetPeriodic(const Standard_Boolean thePeriodic);
+
   //! returns False if at a moment of the approximation,
   //! the status NoApproximation has been sent by the user
   //! when more points were needed.
@@ -199,6 +205,7 @@ private:
   Standard_Integer mycont;
   Standard_Real mylambda1;
   Standard_Real mylambda2;
+  Standard_Boolean myPeriodic;
 
 
 };
index 9a0918c..5bca777 100644 (file)
@@ -286,50 +286,176 @@ static Standard_Integer grilapp(Draw_Interpretor& di, Standard_Integer n, const
 
 static Standard_Integer surfapp(Draw_Interpretor& di, Standard_Integer n, const char** a)
 {
-  if ( n < 5 ) return 1;
+  if (n < 5) return 1;
 
-  Standard_Integer i,j;
+  Standard_Integer i, j;
   Standard_Integer Nu = Draw::Atoi(a[2]);
   Standard_Integer Nv = Draw::Atoi(a[3]);
-  TColgp_Array2OfPnt Points (1, Nu, 1, Nv);
+  TColgp_Array2OfPnt Points(1, Nu, 1, Nv);
+  Standard_Boolean IsPeriodic = Standard_False;
+  Standard_Boolean RemoveLast = Standard_False;
 
-  if ( n == 5) {
+  if (n >= 5 && n <= 6) {
     Handle(Geom_Surface) Surf = DrawTrSurf::GetSurface(a[4]);
-    if ( Surf.IsNull()) return 1;
+    if (Surf.IsNull()) return 1;
 
     Standard_Real U, V, U1, V1, U2, V2;
-    Surf->Bounds( U1, U2, V1, V2);
-    for ( j = 1; j <= Nv; j++) {
-      V = V1 + (j-1) * (V2-V1) / (Nv-1);
-      for ( i = 1; i <= Nu; i++) {
-       U = U1 + (i-1) * (U2-U1) / (Nu-1);
-       Points(i,j) = Surf->Value(U,V);
+    Surf->Bounds(U1, U2, V1, V2);
+    for (j = 1; j <= Nv; j++) {
+      V = V1 + (j - 1) * (V2 - V1) / (Nv - 1);
+      for (i = 1; i <= Nu; i++) {
+        U = U1 + (i - 1) * (U2 - U1) / (Nu - 1);
+        Points(i, j) = Surf->Value(U, V);
       }
-    } 
+    }
+    if (n == 6)
+    {
+      Standard_Integer ip = Draw::Atoi(a[5]);
+      if (ip > 0) IsPeriodic = Standard_True;
+    }
+    if (IsPeriodic)
+    {
+      for (j = 1; j <= Nv; j++)
+      {
+        Standard_Real d = Points(1, j).Distance(Points(Nu, j));
+        if (d <= Precision::Confusion())
+        {
+          RemoveLast = Standard_True;
+          break;
+        }
+      }
+    }
   }
-  else if ( n >= 16) {
+  else if (n >= 16) {
     Standard_Integer Count = 4;
-    for ( j = 1; j <= Nv; j++) {
-      for ( i = 1; i <= Nu; i++) {
-       if ( Count > n) return 1;
-       Points(i,j) = gp_Pnt(Draw::Atof(a[Count]),Draw::Atof(a[Count+1]),Draw::Atof(a[Count+2]));
-       Count += 3;
+    for (j = 1; j <= Nv; j++) {
+      for (i = 1; i <= Nu; i++) {
+        if (Count > n) return 1;
+        Points(i, j) = gp_Pnt(Draw::Atof(a[Count]), Draw::Atof(a[Count + 1]), Draw::Atof(a[Count + 2]));
+        Count += 3;
       }
     }
   }
   char name[100];
   Standard_Integer Count = 1;
-  for ( j = 1; j <= Nv; j++) {
-    for ( i = 1; i <= Nu; i++) {
-      Sprintf(name,"point_%d",Count++);
+  for (j = 1; j <= Nv; j++) {
+    for (i = 1; i <= Nu; i++) {
+      Sprintf(name, "point_%d", Count++);
       char* temp = name; // portage WNT
-      DrawTrSurf::Set(temp,Points(i,j));
+      DrawTrSurf::Set(temp, Points(i, j));
     }
-  } 
+  }
+
+  GeomAPI_PointsToBSplineSurface anApprox;
+  if (RemoveLast)
+  {
+    TColgp_Array2OfPnt Points1(1, Nu - 1, 1, Nv);
+    for (j = 1; j <= Nv; j++)
+    {
+      for (i = 1; i <= Nu - 1; i++) {
+        Points1(i, j) = Points(i, j);
+      }
+    }
+    anApprox.Init(Points1, Approx_ChordLength, 3, 8, GeomAbs_C2, 1.e-3, IsPeriodic);
+  }
+  else
+  {
+    anApprox.Init(Points, Approx_ChordLength, 3, 8, GeomAbs_C2, 1.e-3, IsPeriodic);
+  }
+
+  if (anApprox.IsDone())
+  {
+    Handle(Geom_BSplineSurface) S = anApprox.Surface();
+    DrawTrSurf::Set(a[1], S);
+    di << a[1];
+  }
+
+  return 0;
+}
+
+//=======================================================================
+//function : surfint
+//purpose  : 
+//=======================================================================
+
+static Standard_Integer surfint(Draw_Interpretor& di, Standard_Integer n, const char** a)
+{
+  if (n < 5) return 1;
+
+  Handle(Geom_Surface) Surf = DrawTrSurf::GetSurface(a[2]);
+  if (Surf.IsNull()) return 1;
+  Standard_Integer i, j;
+  Standard_Integer Nu = Draw::Atoi(a[3]);
+  Standard_Integer Nv = Draw::Atoi(a[4]);
+  TColgp_Array2OfPnt Points(1, Nu, 1, Nv);
+
+  Standard_Real U, V, U1, V1, U2, V2;
+  Surf->Bounds(U1, U2, V1, V2);
+  for (j = 1; j <= Nv; j++) {
+    V = V1 + (j - 1) * (V2 - V1) / (Nv - 1);
+    for (i = 1; i <= Nu; i++) {
+      U = U1 + (i - 1) * (U2 - U1) / (Nu - 1);
+      Points(i, j) = Surf->Value(U, V);
+    }
+  }
+
+  char name[100];
+  Standard_Integer Count = 1;
+  for (j = 1; j <= Nv; j++) {
+    for (i = 1; i <= Nu; i++) {
+      Sprintf(name, "point_%d", Count++);
+      char* temp = name; // portage WNT
+      DrawTrSurf::Set(temp, Points(i, j));
+    }
+  }
+
+  Standard_Boolean IsPeriodic = Standard_False;
+  if (n > 5)
+  {
+    Standard_Integer ip = Draw::Atoi(a[5]);
+    if (ip > 0) IsPeriodic = Standard_True;
+  }
+  Standard_Boolean RemoveLast = Standard_False;
+  if (IsPeriodic)
+  {
+    for (j = 1; j <= Nv; j++)
+    {
+      Standard_Real d = Points(1, j).Distance(Points(Nu, j));
+      if (d <= Precision::Confusion())
+      {
+        RemoveLast = Standard_True;
+        break;
+      }
+    }
+  }
+  const Approx_ParametrizationType ParType = Approx_ChordLength;
+  GeomAPI_PointsToBSplineSurface anApprox;
+  if (RemoveLast)
+  {
+    TColgp_Array2OfPnt Points1(1, Nu-1, 1, Nv);
+    for (j = 1; j <= Nv; j++)
+    {
+      for (i = 1; i <= Nu-1; i++) {
+        Points1(i, j) = Points(i, j);
+      }
+    }
+    anApprox.Interpolate(Points1, ParType, IsPeriodic);
+  }
+  else
+  {
+    anApprox.Interpolate(Points, ParType, IsPeriodic);
+  }
+  if (anApprox.IsDone())
+  {
+    Handle(Geom_BSplineSurface) S = anApprox.Surface();
+    DrawTrSurf::Set(a[1], S);
+    di << a[1];
+  }
+  else
+  {
+    di << "Interpolation not done \n";
+  }
 
-  Handle(Geom_BSplineSurface) S = GeomAPI_PointsToBSplineSurface(Points);
-  DrawTrSurf::Set(a[1],S);
-  di << a[1];
 
   return 0;
 }
@@ -634,6 +760,11 @@ void GeometryTest::APICommands(Draw_Interpretor& theCommands)
   theCommands.Add("surfapp","surfapp result nbupoint nbvpoint x y z ....",
                  __FILE__,
                  surfapp);
+
+  theCommands.Add("surfint", "surfint result surf nbupoint nbvpoint [uperiodic]",
+    __FILE__,
+    surfint);
+
   theCommands.Add("grilapp",
        "grilapp result nbupoint nbvpoint X0 dX Y0 dY z11 z12 .. z1nu ....  ",
         __FILE__,grilapp);
index ecab6d4..db12430 100644 (file)
@@ -779,7 +779,6 @@ static Standard_Integer OCC606 ( Draw_Interpretor& di, Standard_Integer n, const
     {
       OCC_CATCH_SIGNALS
         GeomFill_NSections b_surface1(n_curves1, np);
-      b_surface1.ComputeSurface();
       Handle(Geom_BSplineSurface) result_surf1 = b_surface1.BSplineSurface();
       if (!result_surf1.IsNull())
       {
index c937fea..d6835f5 100644 (file)
@@ -34,7 +34,7 @@ checknbshapes result -ref ${nbshapes_expected} -t -m "SECTION"
 regexp {Tolerance +MAX=([-0-9.+eE]+)} [tolerance result] full MaxTolerance
 puts "MaxTolerance=$MaxTolerance"
 
-set expected_MaxTolerance 4.8861510463442802e-005
+set expected_MaxTolerance 5.0e-006
 set tol_abs_MaxTolerance 0.0
 set tol_rel_MaxTolerance 0.01
 checkreal "MaxTolerance" ${MaxTolerance} ${expected_MaxTolerance} ${tol_abs_MaxTolerance} ${tol_rel_MaxTolerance}
diff --git a/tests/bugs/modalg_7/bug30621 b/tests/bugs/modalg_7/bug30621
new file mode 100644 (file)
index 0000000..db45991
--- /dev/null
@@ -0,0 +1,30 @@
+puts "========"
+puts "OCC30621"
+puts "========"
+puts "Implementation of building periodical surfaces by GeomAPI_PointsToBSplineSurface"
+puts "========"
+
+cylinder cc 1
+trimv cc cc 0 1
+surfint ri cc 11 3 1
+surfapp ra 11 3 cc 1
+
+if { [regexp "Continuity Status : C1" [surfaceCcontinuity 1 ri 0 .5 ri 1 .5]] == 1 } {
+   puts "OK : Good result of interpolation"
+
+} else {
+   puts "Error : periodic interpolation fails"
+
+}  
+if { [regexp "Continuity Status : C1" [surfaceCcontinuity 1 ra 0 .5 ra 1 .5]] == 1 } {
+   puts "OK : Good result of approximation"
+
+} else {
+   puts "Error : periodic approximation fails"
+
+}  
+checkview -display ri -with ra -2d -path ${imagedir}/${test_image}.png 
index c3c8001..586ba44 100644 (file)
@@ -1,4 +1,4 @@
-puts "TODO OCC24418 ALL: Error in ii_1: T="
+##puts "TODO OCC24418 ALL: Error in ii_1: T="
 
 puts "========"
 puts "OCC24418"