Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/opencascade/Approx_BSplComputeLine.gxx is written in an unsupported language. File is not indexed.

0001 // Copyright (c) 1995-1999 Matra Datavision
0002 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014 
0015 #include <stdio.h>
0016 
0017 #include <Approx_ParametrizationType.hxx>
0018 #include <TColStd_Array1OfReal.hxx>
0019 #include <TColgp_Array1OfPnt.hxx>
0020 #include <TColgp_Array1OfPnt2d.hxx>
0021 #include <gp_Pnt.hxx>
0022 #include <gp_Pnt2d.hxx>
0023 #include <gp_Vec.hxx>
0024 #include <gp_Vec2d.hxx>
0025 #include <TColgp_Array1OfVec.hxx>
0026 #include <TColgp_Array1OfVec2d.hxx>
0027 #include <AppParCurves_Constraint.hxx>
0028 #include <AppParCurves_HArray1OfConstraintCouple.hxx>
0029 #include <AppParCurves_MultiPoint.hxx>
0030 #include <Precision.hxx>
0031 #include <math_IntegerVector.hxx>
0032 #include <math_Gauss.hxx>
0033 #include <math_Uzawa.hxx>
0034 #include <AppParCurves_ConstraintCouple.hxx>
0035 #include Approx_BSpParLeastSquareOfMyBSplGradient_hxx
0036 
0037 #if defined(OCCT_DEBUG) && defined( DRAW ) && !defined( WNT )
0038 
0039 static Standard_Boolean mydebug = Standard_False;
0040 
0041 #include <Draw.hxx>
0042 #include <Draw_Appli.hxx>
0043 #include <DrawTrSurf.hxx>
0044 #include <Draw_Text2D.hxx>
0045 #include <Draw_Text3D.hxx>
0046 #include <TColStd_Array1OfInteger.hxx>
0047 #include <Geom_BSplineCurve.hxx>
0048 #include <Geom2d_BSplineCurve.hxx>
0049 #include <Geom_Line.hxx>
0050 #include <Geom2d_Line.hxx>
0051 #include <Geom_TrimmedCurve.hxx>
0052 #include <Geom2d_TrimmedCurve.hxx>
0053 
0054 
0055 static void DUMP(const MultiLine& Line)
0056 {
0057   Standard_Integer i, j, nbP2d, nbP3d, firstP, lastP;
0058   firstP = LineTool::FirstPoint(Line);
0059   lastP = LineTool::LastPoint(Line);
0060 
0061   nbP3d = LineTool::NbP3d(Line);
0062   nbP2d = LineTool::NbP2d(Line);
0063   Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
0064   if (nbP3d == 0) mynbP3d = 1;
0065   if (nbP2d == 0) mynbP2d = 1;
0066 
0067   TColgp_Array1OfPnt tabP(1, mynbP3d);
0068   TColgp_Array1OfPnt2d tabP2d(1, mynbP2d);
0069   TColgp_Array1OfVec TabV(1, mynbP3d);
0070   TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
0071   Standard_Boolean Ok;
0072   Handle(Geom_Line) L3d;
0073   Handle(Geom2d_Line) L2d;
0074   Handle(Geom_TrimmedCurve) L3dt;
0075   Handle(Geom2d_TrimmedCurve) L2dt;
0076   Handle(Draw_Text2D) T2D;
0077   Handle(Draw_Text3D) T3D;
0078 
0079   char solname[100];
0080   char mytext[10];
0081 
0082   for (i = firstP; i <= lastP; i++) {
0083     if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i, tabP, tabP2d);
0084     else if (nbP2d != 0)          LineTool::Value(Line, i, tabP2d);
0085     else if (nbP3d != 0)          LineTool::Value(Line, i, tabP);
0086 
0087     for (j = 1; j <= nbP3d; j++) {
0088       sprintf(solname, "%s%i%s_%i", "p", j, "3d", i);
0089       char* Temp = solname;
0090       DrawTrSurf::Set(Temp, tabP(j));
0091       //      DrawTrSurf::Set(solname, tabP(j));
0092       if (i == firstP || i == lastP) {
0093         sprintf(mytext, "%s%i", " ", i);
0094         T3D = new Draw_Text3D(tabP(j), mytext, Draw_vert);
0095         dout << T3D;
0096       }
0097     }
0098     for (j = 1; j <= nbP2d; j++) {
0099       sprintf(solname, "%s%i%s_%i", "p", j, "2d", i);
0100       char* Temp = solname;
0101       DrawTrSurf::Set(Temp, tabP2d(j));
0102       //      DrawTrSurf::Set(solname, tabP2d(j));
0103       if (i == firstP || i == lastP) {
0104         sprintf(mytext, "%s%i", " ", i);
0105         T2D = new Draw_Text2D(tabP2d(j), mytext, Draw_vert);
0106         dout << T2D;
0107       }
0108     }
0109 
0110     // le cas des tangentes aux extremites:
0111     if (i == firstP || i == lastP) {
0112       if (nbP3d != 0 && nbP2d != 0)
0113         Ok = LineTool::Tangency(Line, i, TabV, TabV2d);
0114       else if (nbP2d != 0)
0115         Ok = LineTool::Tangency(Line, i, TabV2d);
0116       else if (nbP3d != 0)
0117         Ok = LineTool::Tangency(Line, i, TabV);
0118 
0119       if (Ok) {
0120         for (j = 1; j <= nbP3d; j++) {
0121           sprintf(solname, "%s%i%s_%i", "t", j, "3d", i);
0122           L3d = new Geom_Line(tabP(j), gp_Dir(TabV(j)));
0123           L3dt = new Geom_TrimmedCurve(L3d, 0.0, 0.3);
0124           char* Temp = solname;
0125           DrawTrSurf::Set(Temp, L3dt);
0126           //      DrawTrSurf::Set(solname, L3dt);
0127         }
0128         for (j = 1; j <= nbP2d; j++) {
0129           sprintf(solname, "%s%i%s_%i", "t", j, "2d", i);
0130           L2d = new Geom2d_Line(tabP2d(j), gp_Dir2d(TabV2d(j)));
0131           L2dt = new Geom2d_TrimmedCurve(L2d, 0.0, 0.3);
0132           char* Temp = solname;
0133           DrawTrSurf::Set(Temp, L2dt);
0134           //      DrawTrSurf::Set(solname, L2dt);
0135         }
0136       }
0137     }
0138   }
0139   dout.Flush();
0140 }
0141 
0142 
0143 static void DUMP(const AppParCurves_MultiBSpCurve& C)
0144 {
0145   static Standard_Integer nbappel = 0;
0146   Standard_Integer i, j, nbP2d, nbP3d;
0147   Standard_Integer nbpoles = C.NbPoles();
0148   Standard_Integer deg = C.Degree();
0149   const TColStd_Array1OfReal& Knots = C.Knots();
0150   const TColStd_Array1OfInteger& Mults = C.Multiplicities();
0151 
0152   Handle(Geom_BSplineCurve) BSp;
0153   Handle(Geom2d_BSplineCurve) BSp2d;
0154 
0155   TColgp_Array1OfPnt tabPoles(1, nbpoles);
0156   TColgp_Array1OfPnt2d tabPoles2d(1, nbpoles);
0157   char solname[100];
0158 
0159   nbappel++;
0160   for (i = 1; i <= C.NbCurves(); i++) {
0161     if (C.Dimension(i) == 3) {
0162       C.Curve(i, tabPoles);
0163       BSp = new Geom_BSplineCurve(tabPoles, Knots, Mults, deg);
0164       sprintf(solname, "%s%i%s_%i", "c", i, "3d", nbappel);
0165       char* Temp = solname;
0166       DrawTrSurf::Set(Temp, BSp);
0167       //      DrawTrSurf::Set(solname, BSp);
0168     }
0169     else {
0170       C.Curve(i, tabPoles2d);
0171       BSp2d = new Geom2d_BSplineCurve(tabPoles2d, Knots, Mults, deg);
0172       sprintf(solname, "%s%i%s_%i", "c", i, "2d", nbappel);
0173       char* Temp = solname;
0174       DrawTrSurf::Set(Temp, BSp2d);
0175       //      DrawTrSurf::Set(solname, BSp2d);
0176     }
0177   }
0178   dout.Flush();
0179 }
0180 
0181 
0182 #endif
0183 
0184 
0185 
0186 
0187 //=======================================================================
0188 //function : FirstTangencyVector
0189 //purpose  : 
0190 //=======================================================================
0191 void Approx_BSplComputeLine::FirstTangencyVector(const MultiLine&  Line,
0192   const Standard_Integer index,
0193   math_Vector&           V)
0194   const {
0195 
0196   Standard_Integer i, j, nbP2d, nbP3d;
0197   nbP3d = LineTool::NbP3d(Line);
0198   nbP2d = LineTool::NbP2d(Line);
0199   Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
0200   if (nbP3d == 0) mynbP3d = 1;
0201   if (nbP2d == 0) mynbP2d = 1;
0202   Standard_Boolean Ok = Standard_False;
0203   TColgp_Array1OfVec TabV(1, mynbP3d);
0204   TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
0205 
0206   if (nbP3d != 0 && nbP2d != 0)
0207     Ok = LineTool::Tangency(Line, index, TabV, TabV2d);
0208   else if (nbP2d != 0)
0209     Ok = LineTool::Tangency(Line, index, TabV2d);
0210   else if (nbP3d != 0)
0211     Ok = LineTool::Tangency(Line, index, TabV);
0212 
0213   if (Ok) {
0214     if (nbP3d != 0) {
0215       j = 1;
0216       for (i = TabV.Lower(); i <= TabV.Upper(); i++) {
0217         V(j) = TabV(i).X();
0218         V(j + 1) = TabV(i).Y();
0219         V(j + 2) = TabV(i).Z();
0220         j += 3;
0221       }
0222     }
0223     if (nbP2d != 0) {
0224       j = nbP3d * 3 + 1;
0225       for (i = TabV2d.Lower(); i <= TabV2d.Upper(); i++) {
0226         V(j) = TabV2d(i).X();
0227         V(j + 1) = TabV2d(i).Y();
0228         j += 2;
0229       }
0230     }
0231   }
0232   else {
0233 
0234     // recherche d un vecteur tangent par construction d une parabole:
0235     AppParCurves_Constraint firstC, lastC;
0236     firstC = lastC = AppParCurves_PassPoint;
0237     Standard_Integer nbpoles = 3;
0238     math_Vector mypar(index, index + 2);
0239     Parameters(Line, index, index + 2, mypar);
0240     Approx_BSpParLeastSquareOfMyBSplGradient
0241       LSQ(Line, index, index + 2, firstC, lastC, mypar, nbpoles);
0242     AppParCurves_MultiCurve C = LSQ.BezierValue();
0243 
0244     gp_Pnt myP;
0245     gp_Vec myV;
0246     gp_Pnt2d myP2d;
0247     gp_Vec2d myV2d;
0248     j = 1;
0249     for (i = 1; i <= nbP3d; i++) {
0250       C.D1(i, 0.0, myP, myV);
0251       V(j) = myV.X();
0252       V(j + 1) = myV.Y();
0253       V(j + 2) = myV.Z();
0254       j += 3;
0255     }
0256     j = nbP3d * 3 + 1;
0257     for (i = nbP3d + 1; i <= nbP3d + nbP2d; i++) {
0258       C.D1(i, 0.0, myP2d, myV2d);
0259       V(j) = myV2d.X();
0260       V(j + 1) = myV2d.Y();
0261       j += 2;
0262     }
0263   }
0264 
0265 }
0266 
0267 
0268 //=======================================================================
0269 //function : LastTangencyVector
0270 //purpose  : 
0271 //=======================================================================
0272 void Approx_BSplComputeLine::LastTangencyVector(const MultiLine&       Line,
0273   const Standard_Integer index,
0274   math_Vector&           V)
0275   const {
0276   Standard_Integer i, j, nbP2d, nbP3d;
0277   nbP3d = LineTool::NbP3d(Line);
0278   nbP2d = LineTool::NbP2d(Line);
0279   Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
0280   if (nbP3d == 0) mynbP3d = 1;
0281   if (nbP2d == 0) mynbP2d = 1;
0282   Standard_Boolean Ok = Standard_False;
0283   TColgp_Array1OfVec TabV(1, mynbP3d);
0284   TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
0285 
0286 
0287   if (nbP3d != 0 && nbP2d != 0)
0288     Ok = LineTool::Tangency(Line, index, TabV, TabV2d);
0289   else if (nbP2d != 0)
0290     Ok = LineTool::Tangency(Line, index, TabV2d);
0291   else if (nbP3d != 0)
0292     Ok = LineTool::Tangency(Line, index, TabV);
0293 
0294   if (Ok) {
0295     if (nbP3d != 0) {
0296       j = 1;
0297       for (i = TabV.Lower(); i <= TabV.Upper(); i++) {
0298         V(j) = TabV(i).X();
0299         V(j + 1) = TabV(i).Y();
0300         V(j + 2) = TabV(i).Z();
0301         j += 3;
0302       }
0303     }
0304     if (nbP2d != 0) {
0305       j = nbP3d * 3 + 1;
0306       for (i = TabV2d.Lower(); i <= TabV2d.Upper(); i++) {
0307         V(j) = TabV2d(i).X();
0308         V(j + 1) = TabV2d(i).Y();
0309         j += 2;
0310       }
0311     }
0312   }
0313   else {
0314 
0315     // recherche d un vecteur tangent par construction d une parabole:
0316     AppParCurves_Constraint firstC, lastC;
0317     firstC = lastC = AppParCurves_PassPoint;
0318     Standard_Integer nbpoles = 3;
0319     math_Vector mypar(index - 2, index);
0320     Parameters(Line, index - 2, index, mypar);
0321     Approx_BSpParLeastSquareOfMyBSplGradient
0322       LSQ(Line, index - 2, index, firstC, lastC, mypar, nbpoles);
0323     AppParCurves_MultiCurve C = LSQ.BezierValue();
0324 
0325     gp_Pnt myP;
0326     gp_Vec myV;
0327     gp_Pnt2d myP2d;
0328     gp_Vec2d myV2d;
0329     j = 1;
0330     for (i = 1; i <= nbP3d; i++) {
0331       C.D1(i, 1.0, myP, myV);
0332       V(j) = myV.X();
0333       V(j + 1) = myV.Y();
0334       V(j + 2) = myV.Z();
0335       j += 3;
0336     }
0337     j = nbP3d * 3 + 1;
0338     for (i = nbP3d + 1; i <= nbP3d + nbP2d; i++) {
0339       C.D1(i, 1.0, myP2d, myV2d);
0340       V(j) = myV2d.X();
0341       V(j + 1) = myV2d.Y();
0342       j += 2;
0343     }
0344   }
0345 
0346 }
0347 
0348 
0349 
0350 //=======================================================================
0351 //function : SearchFirstLambda
0352 //purpose  : 
0353 //=======================================================================
0354 Standard_Real Approx_BSplComputeLine::
0355 SearchFirstLambda(const MultiLine&            Line,
0356   const math_Vector&          aPar,
0357   const TColStd_Array1OfReal& Theknots,
0358   const math_Vector&          V,
0359   const Standard_Integer      index) const {
0360 
0361   // dq/dw = lambda* V = (p2-p1)/(u2-u1)
0362 
0363   Standard_Integer nbP2d, nbP3d;
0364   gp_Pnt P1, P2;
0365   gp_Pnt2d P12d, P22d;
0366   nbP3d = LineTool::NbP3d(Line);
0367   nbP2d = LineTool::NbP2d(Line);
0368   Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
0369   if (nbP3d == 0) mynbP3d = 1;
0370   if (nbP2d == 0) mynbP2d = 1;
0371   TColgp_Array1OfPnt tabP1(1, mynbP3d), tabP2(1, mynbP3d);
0372   TColgp_Array1OfPnt2d tabP12d(1, mynbP2d), tabP22d(1, mynbP2d);
0373 
0374 
0375   if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index, tabP1, tabP12d);
0376   else if (nbP2d != 0)          LineTool::Value(Line, index, tabP12d);
0377   else if (nbP3d != 0)          LineTool::Value(Line, index, tabP1);
0378 
0379   if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index + 1, tabP2, tabP22d);
0380   else if (nbP2d != 0)          LineTool::Value(Line, index + 1, tabP22d);
0381   else if (nbP3d != 0)          LineTool::Value(Line, index + 1, tabP2);
0382 
0383 
0384   Standard_Real U1 = aPar(index), U2 = aPar(index + 1);
0385   Standard_Real lambda, S;
0386   Standard_Integer low = V.Lower();
0387   Standard_Integer nbknots = Theknots.Length();
0388 
0389   if (nbP3d != 0) {
0390     P1 = tabP1(1);
0391     P2 = tabP2(1);
0392     gp_Vec P1P2(P1, P2), myV;
0393     myV.SetCoord(V(low), V(low + 1), V(low + 2));
0394     lambda = (P1P2.Magnitude()) / (myV.Magnitude()*(U2 - U1));
0395     S = (P1P2.Dot(myV) > 0.0) ? 1.0 : -1.0;
0396   }
0397   else {
0398     P12d = tabP12d(1);
0399     P22d = tabP22d(1);
0400     gp_Vec2d P1P2(P12d, P22d), myV;
0401     myV.SetCoord(V(low), V(low + 1));
0402     lambda = (P1P2.Magnitude()) / (myV.Magnitude()*(U2 - U1));
0403     S = (P1P2.Dot(myV) > 0.0) ? 1.0 : -1.0;
0404   }
0405   return ((S*lambda)*(Theknots(2) - Theknots(1)) / (Theknots(nbknots) - Theknots(1)));
0406 
0407 }
0408 
0409 
0410 //=======================================================================
0411 //function : SearchLastLambda
0412 //purpose  : 
0413 //=======================================================================
0414 Standard_Real Approx_BSplComputeLine::
0415 SearchLastLambda(const MultiLine&            Line,
0416   const math_Vector&          aPar,
0417   const TColStd_Array1OfReal& Theknots,
0418   const math_Vector&          V,
0419   const Standard_Integer      index) const
0420 
0421 {
0422   // dq/dw = lambda* V = (p2-p1)/(u2-u1)
0423 
0424   Standard_Integer nbP2d, nbP3d;
0425   gp_Pnt P1, P2;
0426   gp_Pnt2d P12d, P22d;
0427   nbP3d = LineTool::NbP3d(Line);
0428   nbP2d = LineTool::NbP2d(Line);
0429   Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
0430   if (nbP3d == 0) mynbP3d = 1;
0431   if (nbP2d == 0) mynbP2d = 1;
0432   TColgp_Array1OfPnt tabP(1, mynbP3d), tabP2(1, mynbP3d);
0433   TColgp_Array1OfPnt2d tabP2d(1, mynbP2d), tabP22d(1, mynbP2d);
0434 
0435   if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index - 1, tabP, tabP2d);
0436   else if (nbP2d != 0)          LineTool::Value(Line, index - 1, tabP2d);
0437   else if (nbP3d != 0)          LineTool::Value(Line, index - 1, tabP);
0438 
0439   if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index, tabP2, tabP22d);
0440   else if (nbP2d != 0)          LineTool::Value(Line, index, tabP22d);
0441   else if (nbP3d != 0)          LineTool::Value(Line, index, tabP2);
0442 
0443 
0444   Standard_Real U1 = aPar(index - 1), U2 = aPar(index);
0445   Standard_Real lambda, S;
0446   Standard_Integer low = V.Lower();
0447   Standard_Integer nbknots = Theknots.Length();
0448   if (nbP3d != 0) {
0449     P1 = tabP(1);
0450     P2 = tabP2(1);
0451     gp_Vec P1P2(P1, P2), myV;
0452     myV.SetCoord(V(low), V(low + 1), V(low + 2));
0453     lambda = (P1P2.Magnitude()) / (myV.Magnitude()*(U2 - U1));
0454     S = (P1P2.Dot(myV) > 0.0) ? 1.0 : -1.0;
0455   }
0456   else {
0457     P12d = tabP2d(1);
0458     P22d = tabP22d(1);
0459     gp_Vec2d P1P2(P12d, P22d), myV;
0460     myV.SetCoord(V(low), V(low + 1));
0461     lambda = (P1P2.Magnitude()) / (myV.Magnitude()*(U2 - U1));
0462     S = (P1P2.Dot(myV) > 0.0) ? 1.0 : -1.0;
0463   }
0464 
0465   return ((S*lambda)*(Theknots(nbknots) - Theknots(nbknots - 1))
0466     / (Theknots(nbknots) - Theknots(1)));
0467 }
0468 
0469 
0470 
0471 //=======================================================================
0472 //function : Approx_BSplComputeLine
0473 //purpose  : 
0474 //=======================================================================
0475 Approx_BSplComputeLine::Approx_BSplComputeLine
0476 (const MultiLine& Line,
0477   const math_Vector& Parameters,
0478   const Standard_Integer degreemin,
0479   const Standard_Integer degreemax,
0480   const Standard_Real Tolerance3d,
0481   const Standard_Real Tolerance2d,
0482   const Standard_Integer NbIterations,
0483   const Standard_Boolean cutting,
0484   const Standard_Boolean Squares)
0485 {
0486   myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(),
0487     Parameters.Upper());
0488   for (Standard_Integer i = Parameters.Lower(); i <= Parameters.Upper(); i++) {
0489     myfirstParam->SetValue(i, Parameters(i));
0490   }
0491   myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
0492   Par = Approx_IsoParametric;
0493   myPeriodic = Standard_False;
0494   mydegremin = degreemin;
0495   mydegremax = degreemax;
0496   mytol3d = Tolerance3d;
0497   mytol2d = Tolerance2d;
0498   mysquares = Squares;
0499   mycut = cutting;
0500   myitermax = NbIterations;
0501   alldone = Standard_False;
0502   mycont = -1;
0503   myfirstC = AppParCurves_TangencyPoint;
0504   mylastC = AppParCurves_TangencyPoint;
0505   myhasknots = Standard_False;
0506   myhasmults = Standard_False;
0507   currenttol3d = currenttol2d = RealLast();
0508   tolreached = Standard_False;
0509   Perform(Line);
0510 }
0511 
0512 
0513 //=======================================================================
0514 //function : Approx_BSplComputeLine
0515 //purpose  : 
0516 //=======================================================================
0517 Approx_BSplComputeLine::Approx_BSplComputeLine
0518 (const math_Vector& Parameters,
0519   const Standard_Integer degreemin,
0520   const Standard_Integer degreemax,
0521   const Standard_Real Tolerance3d,
0522   const Standard_Real Tolerance2d,
0523   const Standard_Integer NbIterations,
0524   const Standard_Boolean cutting,
0525   const Standard_Boolean Squares)
0526 {
0527   myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(),
0528     Parameters.Upper());
0529   for (Standard_Integer i = Parameters.Lower(); i <= Parameters.Upper(); i++) {
0530     myfirstParam->SetValue(i, Parameters(i));
0531   }
0532   myfirstC = AppParCurves_TangencyPoint;
0533   mylastC = AppParCurves_TangencyPoint;
0534   myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
0535   Par = Approx_IsoParametric;
0536   myPeriodic = Standard_False;
0537   mydegremin = degreemin;
0538   mydegremax = degreemax;
0539   mytol3d = Tolerance3d;
0540   mytol2d = Tolerance2d;
0541   mysquares = Squares;
0542   mycut = cutting;
0543   myitermax = NbIterations;
0544   alldone = Standard_False;
0545   myhasknots = Standard_False;
0546   myhasmults = Standard_False;
0547   mycont = -1;
0548   currenttol3d = currenttol2d = RealLast();
0549   tolreached = Standard_False;
0550 }
0551 
0552 //=======================================================================
0553 //function : Approx_BSplComputeLine
0554 //purpose  : 
0555 //=======================================================================
0556 Approx_BSplComputeLine::Approx_BSplComputeLine
0557 (const Standard_Integer degreemin,
0558   const Standard_Integer degreemax,
0559   const Standard_Real Tolerance3d,
0560   const Standard_Real Tolerance2d,
0561   const Standard_Integer NbIterations,
0562   const Standard_Boolean cutting,
0563   const Approx_ParametrizationType parametrization,
0564   const Standard_Boolean Squares)
0565 {
0566   myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
0567   Par = parametrization;
0568   myPeriodic = Standard_False;
0569   mydegremin = degreemin;
0570   mydegremax = degreemax;
0571   mytol3d = Tolerance3d;
0572   mytol2d = Tolerance2d;
0573   mysquares = Squares;
0574   mycut = cutting;
0575   myitermax = NbIterations;
0576   myfirstC = AppParCurves_TangencyPoint;
0577   mylastC = AppParCurves_TangencyPoint;
0578   alldone = Standard_False;
0579   myhasknots = Standard_False;
0580   myhasmults = Standard_False;
0581   mycont = -1;
0582   currenttol3d = currenttol2d = RealLast();
0583   tolreached = Standard_False;
0584 }
0585 
0586 
0587 //=======================================================================
0588 //function : Approx_BSplComputeLine
0589 //purpose  : 
0590 //=======================================================================
0591 Approx_BSplComputeLine::Approx_BSplComputeLine
0592 (const MultiLine& Line,
0593   const Standard_Integer degreemin,
0594   const Standard_Integer degreemax,
0595   const Standard_Real Tolerance3d,
0596   const Standard_Real Tolerance2d,
0597   const Standard_Integer NbIterations,
0598   const Standard_Boolean cutting,
0599   const Approx_ParametrizationType parametrization,
0600   const Standard_Boolean Squares)
0601 {
0602   myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
0603   alldone = Standard_False;
0604   mydegremin = degreemin;
0605   mydegremax = degreemax;
0606   mytol3d = Tolerance3d;
0607   mytol2d = Tolerance2d;
0608   mysquares = Squares;
0609   mycut = cutting;
0610   myitermax = NbIterations;
0611   Par = parametrization;
0612   myPeriodic = Standard_False;
0613   myfirstC = AppParCurves_TangencyPoint;
0614   mylastC = AppParCurves_TangencyPoint;
0615   myhasknots = Standard_False;
0616   myhasmults = Standard_False;
0617   mycont = -1;
0618   currenttol3d = currenttol2d = RealLast();
0619   tolreached = Standard_False;
0620   Perform(Line);
0621 }
0622 
0623 
0624 
0625 //=======================================================================
0626 //function : Perform
0627 //purpose  : 
0628 //=======================================================================
0629 void Approx_BSplComputeLine::Perform(const MultiLine& Line)
0630 {
0631 
0632 #if defined(OCCT_DEBUG) && defined( DRAW ) && !defined( WNT )
0633   if (mydebug) DUMP(Line);
0634 #endif
0635 
0636   Standard_Integer i, Thefirstpt, Thelastpt;
0637   Standard_Boolean Finish = Standard_False, begin = Standard_True;
0638 
0639   // recherche des vraies contraintes donnees par la Line:
0640   FindRealConstraints(Line);
0641 
0642   Thefirstpt = LineTool::FirstPoint(Line);
0643   Thelastpt = LineTool::LastPoint(Line);
0644   Standard_Integer myfirstpt = Thefirstpt;
0645   Standard_Integer mylastpt = Thelastpt;
0646 
0647   AppParCurves_ConstraintCouple myCouple1(myfirstpt, realfirstC);
0648   AppParCurves_ConstraintCouple myCouple2(mylastpt, reallastC);
0649   myConstraints->SetValue(1, myCouple1);
0650   myConstraints->SetValue(2, myCouple2);
0651 
0652   math_Vector TheParam(Thefirstpt, Thelastpt, 0.0);
0653   if (myfirstParam.IsNull()) {
0654     Parameters(Line, Thefirstpt, Thelastpt, TheParam);
0655   }
0656   else {
0657     for (i = myfirstParam->Lower(); i <= myfirstParam->Upper(); i++) {
0658       TheParam(i + Thefirstpt - 1) = myfirstParam->Value(i);
0659     }
0660   }
0661 
0662   myParameters = new TColStd_HArray1OfReal(TheParam.Lower(), TheParam.Upper());
0663   for (i = TheParam.Lower(); i <= TheParam.Upper(); i++) {
0664     myParameters->SetValue(i, TheParam(i));
0665   }
0666   Standard_Integer nbknots = 2;
0667   Standard_Real l;
0668   alldone = Standard_False;
0669 
0670   if (!mycut) {
0671 
0672     // cas ou on ne desire pas de noeuds supplementaires.
0673     // ==================================================
0674 
0675     if (!myhasknots) {
0676       TColStd_Array1OfReal theknots(1, 2);
0677       TColStd_Array1OfInteger themults(1, 2);
0678       theknots(1) = 0.0;
0679       theknots(2) = 1.0;
0680       alldone = Compute(Line, myfirstpt, mylastpt, TheParam, theknots, themults);
0681     }
0682     else {
0683       if (!myhasmults) {
0684         TColStd_Array1OfInteger themults(1, myknots->Length());
0685         alldone = Compute(Line, myfirstpt, mylastpt, TheParam,
0686           myknots->Array1(), themults);
0687       }
0688       else {
0689         alldone = Compute(Line, myfirstpt, mylastpt, TheParam,
0690           myknots->Array1(), mymults->ChangeArray1());
0691       }
0692     }
0693   }
0694   else {
0695 
0696     // cas ou on va iterer a partir de noeuds donnes par l''utilisateur 
0697     // ou a partir d''une bezier.
0698     // ================================================================
0699 
0700     while (!Finish) {
0701 
0702       currenttol3d = currenttol2d = RealLast();
0703 
0704       if (myhasknots && begin) {
0705 
0706         if (!myhasmults) {
0707 
0708           // 1er cas: l''utilisateur donne des noeuds de depart mais
0709           // a nous de fixer  les multiplicites  en  fonction  de  la 
0710           // continuite desiree.
0711           // ========================================================
0712 
0713           TColStd_Array1OfInteger TheMults(1, myknots->Length());
0714           alldone = Compute(Line, myfirstpt, mylastpt, TheParam,
0715             myknots->Array1(), TheMults);
0716         }
0717         else {
0718 
0719           // 2eme cas: l''utilisateur donne des noeuds de depart 
0720           // avec leurs multiplicites.
0721           // ===================================================
0722 
0723           alldone = Compute(Line, myfirstpt, mylastpt, TheParam,
0724             myknots->Array1(), mymults->ChangeArray1());
0725         }
0726         begin = Standard_False;
0727       }
0728 
0729       else {
0730 
0731         // 3eme cas: l''utilisateur ne donne aucun noeuds de depart
0732         // ========================================================
0733 
0734         TColStd_Array1OfReal Theknots(1, nbknots);
0735         TColStd_Array1OfInteger TheMults(1, nbknots);
0736         Theknots(1) = 0.0;
0737         Theknots(nbknots) = 1.0;
0738         for (i = 2; i <= nbknots - 1; i++) {
0739 
0740           l = (mylastpt - myfirstpt)*Standard_Real(i - 1)
0741             / Standard_Real(nbknots - 1);
0742           Standard_Integer ll = (Standard_Integer)(l);
0743           Standard_Real a = l - ll;
0744           Standard_Real p1 = TheParam(ll + myfirstpt);
0745           Standard_Real p2 = TheParam(ll + 1 + myfirstpt);
0746           Theknots(i) = (1. - a)*p1 + a*p2;
0747         }
0748 
0749         alldone = Compute(Line, myfirstpt, mylastpt, TheParam, Theknots, TheMults);
0750 
0751       }
0752 
0753       if (!alldone) nbknots++;
0754       else Finish = Standard_True;
0755     }
0756   }
0757 
0758 #if defined(OCCT_DEBUG) && defined( DRAW ) && !defined( WNT )
0759   if (mydebug) DUMP(TheMultiBSpCurve);
0760 #endif
0761 
0762 }
0763 
0764 
0765 
0766 
0767 //=======================================================================
0768 //function : Parameters
0769 //purpose  : 
0770 //=======================================================================
0771 const TColStd_Array1OfReal& Approx_BSplComputeLine::Parameters() const
0772 {
0773   return myParameters->Array1();
0774 }
0775 
0776 
0777 
0778 //=======================================================================
0779 //function : Value
0780 //purpose  : 
0781 //=======================================================================
0782 const AppParCurves_MultiBSpCurve& Approx_BSplComputeLine::Value() const
0783 {
0784   return TheMultiBSpCurve;
0785 }
0786 
0787 //=======================================================================
0788 //function : ChangeValue
0789 //purpose  : 
0790 //=======================================================================
0791 AppParCurves_MultiBSpCurve& Approx_BSplComputeLine::ChangeValue()
0792 {
0793   return TheMultiBSpCurve;
0794 }
0795 
0796 //=======================================================================
0797 //function : Parameters
0798 //purpose  : 
0799 //=======================================================================
0800 
0801 void Approx_BSplComputeLine::Parameters(const MultiLine& Line,
0802   const Standard_Integer firstP,
0803   const Standard_Integer lastP,
0804   math_Vector& TheParameters) const
0805 {
0806   Standard_Integer i, j, nbP2d, nbP3d;
0807   Standard_Real dist;
0808   const Standard_Integer aNbp = lastP - firstP + 1;
0809 
0810 
0811   // The first parameter should always be zero according to all the logic below,
0812   // so division by any value will give zero anyway, so it should never be scaled
0813   // to avoid case when there is only one parameter in the array thus division by zero happens.
0814   TheParameters(firstP) = 0.0;
0815   if (aNbp == 2) {
0816     TheParameters(lastP) = 1.0;
0817   }
0818   else if (Par == Approx_ChordLength || Par == Approx_Centripetal)
0819   {
0820     nbP3d = LineTool::NbP3d(Line);
0821     nbP2d = LineTool::NbP2d(Line);
0822     Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
0823     if (nbP3d == 0) mynbP3d = 1;
0824     if (nbP2d == 0) mynbP2d = 1;
0825 
0826     dist = 0.0;
0827     TColgp_Array1OfPnt tabP(1, mynbP3d);
0828     TColgp_Array1OfPnt tabPP(1, mynbP3d);
0829     TColgp_Array1OfPnt2d tabP2d(1, mynbP2d);
0830     TColgp_Array1OfPnt2d tabPP2d(1, mynbP2d);
0831 
0832     for (i = firstP + 1; i <= lastP; i++)
0833     {
0834       if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i - 1, tabP, tabP2d);
0835       else if (nbP2d != 0)          LineTool::Value(Line, i - 1, tabP2d);
0836       else if (nbP3d != 0)          LineTool::Value(Line, i - 1, tabP);
0837 
0838       if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i, tabPP, tabPP2d);
0839       else if (nbP2d != 0)          LineTool::Value(Line, i, tabPP2d);
0840       else if (nbP3d != 0)          LineTool::Value(Line, i, tabPP);
0841       dist = 0.0;
0842       for (j = 1; j <= nbP3d; j++)
0843       {
0844         const gp_Pnt &aP1 = tabP(j),
0845           &aP2 = tabPP(j);
0846         dist += aP2.SquareDistance(aP1);
0847       }
0848       for (j = 1; j <= nbP2d; j++)
0849       {
0850         const gp_Pnt2d &aP12d = tabP2d(j),
0851           &aP22d = tabPP2d(j);
0852 
0853         dist += aP22d.SquareDistance(aP12d);
0854       }
0855 
0856       dist = Sqrt(dist);
0857       if (Par == Approx_ChordLength)
0858       {
0859         TheParameters(i) = TheParameters(i - 1) + dist;
0860       }
0861       else
0862       {// Par == Approx_Centripetal
0863         TheParameters(i) = TheParameters(i - 1) + Sqrt(dist);
0864       }
0865     }
0866     for (i = firstP + 1; i <= lastP; i++) TheParameters(i) /= TheParameters(lastP);
0867   }
0868   else {
0869     for (i = firstP + 1; i <= lastP; i++) {
0870       TheParameters(i) = (Standard_Real(i) - firstP) /
0871         (Standard_Real(lastP - Standard_Real(firstP)));
0872     }
0873   }
0874 }
0875 
0876 
0877 //=======================================================================
0878 //function : Compute
0879 //purpose  : 
0880 //=======================================================================
0881 Standard_Boolean Approx_BSplComputeLine::Compute(const MultiLine& Line,
0882   const Standard_Integer fpt,
0883   const Standard_Integer lpt,
0884   math_Vector&     Para,
0885   const TColStd_Array1OfReal& Knots,
0886   TColStd_Array1OfInteger& Mults)
0887 {
0888   Standard_Integer i, deg, nbpoles, multinter;
0889   Standard_Boolean mydone;
0890   Standard_Real Fv, TheTol3d, TheTol2d, l1, l2;
0891   Standard_Integer nbp = lpt - fpt + 1;
0892   mylambda1 = 0.0;
0893   mylambda2 = 0.0;
0894 
0895   math_Vector aParams(Para.Lower(), Para.Upper());
0896 
0897   for (deg = mydegremin; deg <= mydegremax; deg++) {
0898 
0899     aParams = Para;
0900 
0901     if (!myhasmults) {
0902       Mults(Mults.Lower()) = deg + 1;
0903       Mults(Mults.Upper()) = deg + 1;
0904       nbpoles = deg + 1;
0905       if (mycont == -1) multinter = 1;
0906       else multinter = Max(1, deg - mycont);
0907       for (i = Mults.Lower() + 1; i <= Mults.Upper() - 1; i++) {
0908         Mults(i) = multinter;
0909         nbpoles += multinter;
0910       }
0911     }
0912     else {
0913       nbpoles = -deg - 1;
0914       for (i = Mults.Lower(); i <= Mults.Upper(); i++) {
0915         nbpoles += Mults.Value(i);
0916       }
0917     }
0918 
0919     Standard_Integer nbpolestocompare = nbpoles;
0920     if (realfirstC == AppParCurves_TangencyPoint) nbpolestocompare++;
0921     if (reallastC == AppParCurves_TangencyPoint) nbpolestocompare++;
0922     if (realfirstC == AppParCurves_CurvaturePoint) nbpolestocompare++;
0923     if (reallastC == AppParCurves_CurvaturePoint) nbpolestocompare++;
0924     if (nbpolestocompare > nbp) {
0925       Interpol(Line);
0926       tolreached = Standard_True;
0927       return Standard_True;
0928     }
0929 
0930     AppParCurves_MultiBSpCurve mySCU(nbpoles);
0931 
0932     if (mysquares) {
0933       Approx_BSpParLeastSquareOfMyBSplGradient SQ(Line, Knots, Mults, fpt, lpt,
0934         realfirstC, reallastC, aParams, nbpoles);
0935       mydone = SQ.IsDone();
0936       if (mydone) {
0937         mySCU = SQ.BSplineValue();
0938         SQ.Error(Fv, TheTol3d, TheTol2d);
0939       }
0940       else continue;
0941     }
0942     else {
0943       if (nbpoles != deg + 1) {
0944 
0945         if (deg == mydegremin && (realfirstC >= AppParCurves_TangencyPoint ||
0946           reallastC >= AppParCurves_TangencyPoint)) {
0947           Approx_BSpParLeastSquareOfMyBSplGradient
0948             thefitt(Line, Knots, Mults, fpt, lpt, realfirstC, reallastC, aParams, nbpoles);
0949           mylambda1 = thefitt.FirstLambda()*deg;
0950           mylambda2 = thefitt.LastLambda()*deg;
0951 
0952         }
0953         l1 = mylambda1 / deg;
0954         l2 = mylambda2 / deg;
0955 
0956         Approx_MyBSplGradient GRAD(Line, fpt, lpt, myConstraints,
0957           aParams, Knots, Mults, deg, mytol3d,
0958           mytol2d, myitermax, l1, l2);
0959 
0960         mydone = GRAD.IsDone();
0961         if (mydone) {
0962           mySCU = GRAD.Value();
0963           TheTol3d = GRAD.MaxError3d();
0964           TheTol2d = GRAD.MaxError2d();
0965         }
0966         else continue;
0967       }
0968       else {
0969         Approx_MyGradientbis GRAD2(Line, fpt, lpt, myConstraints,
0970           aParams, deg, mytol3d,
0971           mytol2d, myitermax);
0972         mydone = GRAD2.IsDone();
0973         if (mydone) {
0974           if (GRAD2.Value().NbCurves() == 0)
0975             continue;
0976           mySCU = AppParCurves_MultiBSpCurve(GRAD2.Value(), Knots, Mults);
0977           TheTol3d = GRAD2.MaxError3d();
0978           TheTol2d = GRAD2.MaxError2d();
0979         }
0980         else continue;
0981       }
0982     }
0983     Standard_Boolean save = Standard_True;
0984 
0985     for (i = aParams.Lower(); i <= aParams.Upper(); i++) {
0986       if (aParams(i) <= -0.000001 || aParams(i) >= 1.000001) {
0987         save = Standard_False;
0988         break;
0989       }
0990     }
0991 
0992     if (mydone) {
0993       if (TheTol3d <= mytol3d && TheTol2d <= mytol2d) {
0994         // Stockage de la multicurve approximee.
0995         tolreached = Standard_True;
0996         TheMultiBSpCurve = mySCU;
0997         currenttol3d = TheTol3d;
0998         currenttol2d = TheTol2d;
0999         if (save) {
1000           for (i = aParams.Lower(); i <= aParams.Upper(); i++) {
1001             myParameters->SetValue(i, aParams(i));
1002           }
1003         }
1004         return Standard_True;
1005       }
1006     }
1007 
1008     if (TheTol3d <= currenttol3d && TheTol2d <= currenttol2d) {
1009       TheMultiBSpCurve = mySCU;
1010       currenttol3d = TheTol3d;
1011       currenttol2d = TheTol2d;
1012       if (save) {
1013         for (i = aParams.Lower(); i <= aParams.Upper(); i++) {
1014           myParameters->SetValue(i, aParams(i));
1015         }
1016       }
1017     }
1018 
1019   }
1020 
1021   return Standard_False;
1022 }
1023 
1024 
1025 
1026 //=======================================================================
1027 //function : SetParameters
1028 //purpose  : 
1029 //=======================================================================
1030 void Approx_BSplComputeLine::SetParameters(const math_Vector& ThePar)
1031 {
1032   myfirstParam = new TColStd_HArray1OfReal(ThePar.Lower(),
1033     ThePar.Upper());
1034   for (Standard_Integer i = ThePar.Lower(); i <= ThePar.Upper(); i++) {
1035     myfirstParam->SetValue(i, ThePar(i));
1036   }
1037 }
1038 
1039 
1040 //=======================================================================
1041 //function : SetKnots
1042 //purpose  : 
1043 //=======================================================================
1044 void Approx_BSplComputeLine::SetKnots(const TColStd_Array1OfReal& Knots)
1045 {
1046   myhasknots = Standard_True;
1047   myknots = new TColStd_HArray1OfReal(Knots.Lower(), Knots.Upper());
1048   for (Standard_Integer i = Knots.Lower(); i <= Knots.Upper(); i++) {
1049     myknots->SetValue(i, Knots(i));
1050   }
1051 }
1052 
1053 
1054 //=======================================================================
1055 //function : SetKnotsAndMultiplicities
1056 //purpose  : 
1057 //=======================================================================
1058 void Approx_BSplComputeLine::SetKnotsAndMultiplicities
1059 (const TColStd_Array1OfReal&    Knots,
1060   const TColStd_Array1OfInteger& Mults)
1061 {
1062   myhasknots = Standard_True;
1063   myhasmults = Standard_True;
1064   Standard_Integer i;
1065   myknots = new TColStd_HArray1OfReal(Knots.Lower(), Knots.Upper());
1066   for (i = Knots.Lower(); i <= Knots.Upper(); i++) {
1067     myknots->SetValue(i, Knots(i));
1068   }
1069   mymults = new TColStd_HArray1OfInteger(Mults.Lower(), Mults.Upper());
1070   for (i = Mults.Lower(); i <= Mults.Upper(); i++) {
1071     mymults->SetValue(i, Mults(i));
1072   }
1073 }
1074 
1075 //=======================================================================
1076 //function : Init
1077 //purpose  : 
1078 //=======================================================================
1079 void Approx_BSplComputeLine::Init(const Standard_Integer degreemin,
1080   const Standard_Integer degreemax,
1081   const Standard_Real Tolerance3d,
1082   const Standard_Real Tolerance2d,
1083   const Standard_Integer NbIterations,
1084   const Standard_Boolean cutting,
1085   const Approx_ParametrizationType parametrization,
1086   const Standard_Boolean Squares)
1087 {
1088   mydegremin = degreemin;
1089   mydegremax = degreemax;
1090   mytol3d = Tolerance3d;
1091   mytol2d = Tolerance2d;
1092   Par = parametrization;
1093   mysquares = Squares;
1094   mycut = cutting;
1095   myitermax = NbIterations;
1096 }
1097 
1098 
1099 
1100 //=======================================================================
1101 //function : SetDegrees
1102 //purpose  : 
1103 //=======================================================================
1104 void Approx_BSplComputeLine::SetDegrees(const Standard_Integer degreemin,
1105   const Standard_Integer degreemax)
1106 {
1107   mydegremin = degreemin;
1108   mydegremax = degreemax;
1109 }
1110 
1111 
1112 //=======================================================================
1113 //function : SetTolerances
1114 //purpose  : 
1115 //=======================================================================
1116 void Approx_BSplComputeLine::SetTolerances(const Standard_Real Tolerance3d,
1117   const Standard_Real Tolerance2d)
1118 {
1119   mytol3d = Tolerance3d;
1120   mytol2d = Tolerance2d;
1121 }
1122 
1123 
1124 //=======================================================================
1125 //function : SetConstraints
1126 //purpose  : 
1127 //=======================================================================
1128 void Approx_BSplComputeLine::SetConstraints(const AppParCurves_Constraint FirstC,
1129   const AppParCurves_Constraint LastC)
1130 {
1131   myfirstC = FirstC;
1132   mylastC = LastC;
1133 }
1134 
1135 //=======================================================================
1136 //function : SetPeriodic
1137 //purpose  : 
1138 //=======================================================================
1139 void Approx_BSplComputeLine::SetPeriodic(const Standard_Boolean thePeriodic)
1140 {
1141   myPeriodic = thePeriodic;
1142 }
1143 
1144 
1145 //=======================================================================
1146 //function : IsAllApproximated
1147 //purpose  : 
1148 //=======================================================================
1149 Standard_Boolean Approx_BSplComputeLine::IsAllApproximated() const
1150 {
1151   return alldone;
1152 }
1153 
1154 //=======================================================================
1155 //function : IsToleranceReached
1156 //purpose  : 
1157 //=======================================================================
1158 Standard_Boolean Approx_BSplComputeLine::IsToleranceReached() const
1159 {
1160   return tolreached;
1161 }
1162 
1163 //=======================================================================
1164 //function : Error
1165 //purpose  : 
1166 //=======================================================================
1167 void Approx_BSplComputeLine::Error(Standard_Real& tol3d,
1168   Standard_Real& tol2d) const
1169 {
1170   tol3d = currenttol3d;
1171   tol2d = currenttol2d;
1172 }
1173 
1174 
1175 
1176 //=======================================================================
1177 //function : SetContinuity
1178 //purpose  : 
1179 //=======================================================================
1180 void Approx_BSplComputeLine::SetContinuity(const Standard_Integer C)
1181 {
1182   mycont = C;
1183 }
1184 
1185 
1186 
1187 //=======================================================================
1188 //function : FindRealConstraints
1189 //purpose  : 
1190 //=======================================================================
1191 void Approx_BSplComputeLine::FindRealConstraints(const MultiLine& Line)
1192 {
1193   realfirstC = myfirstC;
1194   reallastC = mylastC;
1195   Standard_Integer nbP2d, nbP3d;
1196   nbP3d = LineTool::NbP3d(Line);
1197   nbP2d = LineTool::NbP2d(Line);
1198   Standard_Boolean Ok = Standard_False;
1199   TColgp_Array1OfVec TabV(1, Max(1, nbP3d));
1200   TColgp_Array1OfVec2d TabV2d(1, Max(1, nbP2d));
1201   Standard_Integer Thefirstpt = LineTool::FirstPoint(Line);
1202   Standard_Integer Thelastpt = LineTool::LastPoint(Line);
1203 
1204   if (myfirstC >= AppParCurves_TangencyPoint) {
1205 
1206     if (nbP3d != 0 && nbP2d != 0)
1207       Ok = LineTool::Tangency(Line, Thefirstpt, TabV, TabV2d);
1208     else if (nbP2d != 0)
1209       Ok = LineTool::Tangency(Line, Thefirstpt, TabV2d);
1210     else if (nbP3d != 0)
1211       Ok = LineTool::Tangency(Line, Thefirstpt, TabV);
1212 
1213     realfirstC = AppParCurves_PassPoint;
1214     if (Ok) {
1215       realfirstC = AppParCurves_TangencyPoint;
1216       if (myfirstC == AppParCurves_CurvaturePoint) {
1217         if (nbP3d != 0 && nbP2d != 0)
1218           Ok = LineTool::Tangency(Line, Thefirstpt, TabV, TabV2d);
1219         else if (nbP2d != 0)
1220           Ok = LineTool::Tangency(Line, Thefirstpt, TabV2d);
1221         else if (nbP3d != 0)
1222           Ok = LineTool::Tangency(Line, Thefirstpt, TabV);
1223         if (Ok) {
1224           realfirstC = AppParCurves_CurvaturePoint;
1225         }
1226       }
1227     }
1228   }
1229 
1230 
1231   if (mylastC >= AppParCurves_TangencyPoint) {
1232 
1233     if (nbP3d != 0 && nbP2d != 0)
1234       Ok = LineTool::Tangency(Line, Thelastpt, TabV, TabV2d);
1235     else if (nbP2d != 0)
1236       Ok = LineTool::Tangency(Line, Thelastpt, TabV2d);
1237     else if (nbP3d != 0)
1238       Ok = LineTool::Tangency(Line, Thelastpt, TabV);
1239 
1240     reallastC = AppParCurves_PassPoint;
1241     if (Ok) {
1242       reallastC = AppParCurves_TangencyPoint;
1243       if (mylastC == AppParCurves_CurvaturePoint) {
1244         if (nbP3d != 0 && nbP2d != 0)
1245           Ok = LineTool::Tangency(Line, Thelastpt, TabV, TabV2d);
1246         else if (nbP2d != 0)
1247           Ok = LineTool::Tangency(Line, Thelastpt, TabV2d);
1248         else if (nbP3d != 0)
1249           Ok = LineTool::Tangency(Line, Thelastpt, TabV);
1250         if (Ok) {
1251           reallastC = AppParCurves_CurvaturePoint;
1252         }
1253       }
1254     }
1255   }
1256 
1257 }
1258 
1259 
1260 
1261 
1262 //=======================================================================
1263 //function : Interpol
1264 //purpose  : 
1265 //=======================================================================
1266 void Approx_BSplComputeLine::Interpol(const MultiLine& Line)
1267 {
1268   Standard_Integer i, Thefirstpt, Thelastpt, deg = 3;
1269   mycont = 2;
1270   Thefirstpt = LineTool::FirstPoint(Line);
1271   Thelastpt = LineTool::LastPoint(Line);
1272   math_Vector TheParam(Thefirstpt, Thelastpt, 0.0);
1273   //Par = Approx_ChordLength;
1274   if (myfirstParam.IsNull()) {
1275     Parameters(Line, Thefirstpt, Thelastpt, TheParam);
1276   }
1277   else {
1278     for (i = myfirstParam->Lower(); i <= myfirstParam->Upper(); i++) {
1279       TheParam(i + Thefirstpt - 1) = myfirstParam->Value(i);
1280     }
1281   }
1282   AppParCurves_Constraint Cons = AppParCurves_TangencyPoint;
1283   Standard_Real lambda1, lambda2;
1284   Standard_Real Fv;
1285 
1286   // Recherche du nombre de noeuds.
1287   Standard_Integer nbknots, nbpoles, nbpoints;
1288   nbpoints = Thelastpt - Thefirstpt + 1;
1289 
1290   if (nbpoints == 2) {
1291     Cons = AppParCurves_NoConstraint;
1292     Standard_Integer mydeg = 1;
1293     Approx_BSpParLeastSquareOfMyBSplGradient
1294       LSQ(Line, Thefirstpt, Thelastpt, Cons, Cons, TheParam, mydeg + 1);
1295     alldone = LSQ.IsDone();
1296     TColStd_Array1OfReal TheKnots(1, 2);
1297     TColStd_Array1OfInteger TheMults(1, 2);
1298     TheKnots(1) = TheParam(Thefirstpt);  TheKnots(2) = TheParam(Thelastpt);
1299     TheMults(1) = TheMults(2) = mydeg + 1;
1300     TheMultiBSpCurve =
1301       AppParCurves_MultiBSpCurve(LSQ.BezierValue(), TheKnots, TheMults);
1302     LSQ.Error(Fv, currenttol3d, currenttol2d);
1303 
1304   }
1305   else {
1306     nbpoles = nbpoints + 2;
1307     nbknots = nbpoints;
1308 
1309     // Resolution:
1310     TColStd_Array1OfReal Theknots(1, nbknots);
1311     Theknots(1) = TheParam(Thefirstpt);
1312     Theknots(nbknots) = TheParam(Thelastpt);
1313     TColStd_Array1OfInteger TheMults(1, nbknots);
1314     TheMults(1) = deg + 1;
1315     TheMults(nbknots) = deg + 1;
1316 
1317     Standard_Integer low = TheParam.Lower();
1318     for (i = 2; i <= nbknots - 1; i++) {
1319       Theknots(i) = TheParam(i + low - 1);
1320       TheMults(i) = 1;
1321     }
1322 
1323 
1324     Standard_Integer nbP = 3 * LineTool::NbP3d(Line) + 2 * LineTool::NbP2d(Line);
1325     math_Vector V1(1, nbP), V2(1, nbP);
1326 
1327     if (nbpoints == 3 || nbpoints == 4) {
1328       FirstTangencyVector(Line, Thefirstpt, V1);
1329       lambda1 = SearchFirstLambda(Line, TheParam, Theknots, V1, Thefirstpt);
1330 
1331       LastTangencyVector(Line, Thelastpt, V2);
1332       lambda2 = SearchLastLambda(Line, TheParam, Theknots, V2, Thelastpt);
1333 
1334       lambda1 = lambda1 / deg;
1335       lambda2 = lambda2 / deg;
1336     }
1337     else {
1338       Standard_Integer nnpol, nnp = Min(nbpoints, 9);
1339       nnpol = nnp;
1340       Standard_Integer lastp = Min(Thelastpt, Thefirstpt + nnp - 1);
1341       Standard_Real U;
1342       Approx_BSpParLeastSquareOfMyBSplGradient
1343         SQ1(Line, Thefirstpt, lastp, Cons, Cons, nnpol);
1344 
1345       math_Vector P1(Thefirstpt, lastp);
1346       for (i = Thefirstpt; i <= lastp; i++) P1(i) = TheParam(i);
1347       SQ1.Perform(P1);
1348       const AppParCurves_MultiCurve& C1 = SQ1.BezierValue();
1349       U = 0.0;
1350       TangencyVector(Line, C1, U, V1);
1351 
1352       Standard_Integer firstp = Max(Thefirstpt, Thelastpt - nnp + 1);
1353 
1354       if (firstp == Thefirstpt && lastp == Thelastpt) {
1355         U = 1.0;
1356         TangencyVector(Line, C1, U, V2);
1357       }
1358       else {
1359         Approx_BSpParLeastSquareOfMyBSplGradient
1360           SQ2(Line, firstp, Thelastpt, Cons, Cons, nnpol);
1361 
1362         math_Vector P2(firstp, Thelastpt);
1363         for (i = firstp; i <= Thelastpt; i++) P2(i) = TheParam(i);
1364         SQ2.Perform(P2);
1365         const AppParCurves_MultiCurve& C2 = SQ2.BezierValue();
1366         U = 1.0;
1367         TangencyVector(Line, C2, U, V2);
1368       }
1369 
1370     
1371       lambda1 = 1. / deg;
1372       lambda1 = lambda1*(Theknots(2) - Theknots(1))
1373         / (Theknots(nbknots) - Theknots(1));
1374       lambda2 = 1. / deg;
1375       lambda2 = lambda2*(Theknots(nbknots) - Theknots(nbknots - 1))
1376         / (Theknots(nbknots) - Theknots(1));
1377 
1378     }
1379 
1380     if (myPeriodic)
1381     {
1382       V1 = 0.5 * (V1 + V2);
1383       V2 = V1;
1384     }
1385 
1386     Approx_BSpParLeastSquareOfMyBSplGradient
1387       SQ(Line, Theknots, TheMults, Thefirstpt, Thelastpt,
1388         Cons, Cons, nbpoles);
1389 
1390     SQ.Perform(TheParam, V1, V2, lambda1, lambda2);
1391     alldone = SQ.IsDone();
1392     TheMultiBSpCurve = SQ.BSplineValue();
1393     SQ.Error(Fv, currenttol3d, currenttol2d);
1394     tolreached = Standard_True;
1395   }
1396   myParameters = new TColStd_HArray1OfReal(TheParam.Lower(), TheParam.Upper());
1397   for (i = TheParam.Lower(); i <= TheParam.Upper(); i++) {
1398     myParameters->SetValue(i, TheParam(i));
1399   }
1400 }
1401 
1402 
1403 //=======================================================================
1404 //function : TangencyVector
1405 //purpose  : 
1406 //=======================================================================
1407 void Approx_BSplComputeLine::TangencyVector(
1408   const MultiLine&               Line,
1409   const AppParCurves_MultiCurve& C,
1410   const Standard_Real            U,
1411   math_Vector&                   V) const
1412 {
1413 
1414   Standard_Integer i, j, nbP2d, nbP3d;
1415   nbP3d = LineTool::NbP3d(Line);
1416   nbP2d = LineTool::NbP2d(Line);
1417 
1418   gp_Pnt myP;
1419   gp_Vec myV;
1420   gp_Pnt2d myP2d;
1421   gp_Vec2d myV2d;
1422   j = 1;
1423   for (i = 1; i <= nbP3d; i++) {
1424     C.D1(i, U, myP, myV);
1425     V(j) = myV.X();
1426     V(j + 1) = myV.Y();
1427     V(j + 2) = myV.Z();
1428     j += 3;
1429   }
1430   j = nbP3d * 3 + 1;
1431   for (i = nbP3d + 1; i <= nbP3d + nbP2d; i++) {
1432     C.D1(i, U, myP2d, myV2d);
1433     V(j) = myV2d.X();
1434     V(j + 1) = myV2d.Y();
1435     j += 2;
1436   }
1437 
1438 }
1439