Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/opencascade/AppParCurves_LeastSquare.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 // lpa, le 27/07/91
0016 // pmn, 30/10/98 : Protection dans les cas surcontraint -> "isready"
0017 
0018 // Approximation d une MultiLine de points decrite par le tool MLineTool.
0019 // Ce programme utilise les moindres carres pour le cas suivant:
0020 // passage et tangences aux extremites.
0021 
0022 
0023 #define No_Standard_RangeError
0024 #define No_Standard_OutOfRange
0025 #define No_Standard_DimensionError
0026 
0027 #include <math_Householder.hxx>
0028 #include <math_Crout.hxx>
0029 #include <AppParCurves.hxx>
0030 #include <gp_Pnt.hxx>
0031 #include <gp_Pnt2d.hxx>
0032 #include <gp_Vec.hxx>
0033 #include <gp_Vec2d.hxx>
0034 #include <TColgp_Array1OfPnt.hxx>
0035 #include <TColgp_Array1OfPnt2d.hxx>
0036 #include <TColgp_Array1OfVec.hxx>
0037 #include <TColgp_Array1OfVec2d.hxx>
0038 #include <TColStd_Array1OfInteger.hxx>
0039 #include <TColStd_Array1OfReal.hxx>
0040 #include <AppParCurves_Constraint.hxx>
0041 #include <AppParCurves_MultiPoint.hxx>
0042 #include <StdFail_NotDone.hxx>
0043 #include <Standard_NoSuchObject.hxx>
0044 #include <TColStd_Array1OfReal.hxx>
0045 #include <math_Recipes.hxx>
0046 #include <math_Crout.hxx>
0047 
0048 
0049 
0050 static int FlatLength(const TColStd_Array1OfInteger& Mults) {
0051   
0052   Standard_Integer sum = 0;
0053   for (Standard_Integer i = Mults.Lower(); i <= Mults.Upper(); i++) {
0054     sum += Mults.Value(i);
0055   }
0056   return sum;
0057 }
0058 
0059 //=======================================================================
0060 //function : CheckTangents
0061 //purpose  : Checks if theArrTg3d and theArrTg2d have direction
0062 //            corresponded to the direction between theArrPt1 and theArrPt2.
0063 //            If it is not then reverses tangent vectors.
0064 //              theArrPt1 (as same as theArrPt2) is sub-set of all 3D-points in
0065 //            one multy-point (multy-point is union of sets of 2D- and 3D-points).
0066 //
0067 //ATTENTION!!!
0068 //              The property of correlation between Tg3d and Tg2d is used here.
0069 //            Therefore, only 3D-coinciding is checked.
0070 //=======================================================================
0071 static void CheckTangents(const TColgp_Array1OfPnt& theArrPt1,
0072                           const TColgp_Array1OfPnt& theArrPt2,
0073                           TColgp_Array1OfVec& theArrTg3d,
0074                           TColgp_Array1OfVec2d& theArrTg2d)
0075 {
0076   if(theArrPt1.Lower() != theArrPt2.Lower())
0077     return;
0078 
0079   if(theArrPt1.Upper() != theArrPt2.Upper())
0080     return;
0081 
0082   if(theArrTg3d.Length() != theArrPt1.Length())
0083     return;
0084 
0085   Standard_Boolean isToChangeDir = Standard_False;
0086 
0087   for(Standard_Integer i = theArrPt1.Lower(); i <= theArrPt1.Upper(); i++)
0088   {
0089     const gp_Vec aV1(theArrPt1(i), theArrPt2(i));
0090     const gp_Vec& aV2 = theArrTg3d(i);
0091 
0092     if(aV1.Dot(aV2) < 0.0)
0093     {
0094       isToChangeDir = Standard_True;
0095       break;
0096     }
0097   }
0098 
0099   if(!isToChangeDir)
0100     return;
0101 
0102   //Change directions for every 2D- and 3D-tangents
0103 
0104   for(Standard_Integer i = theArrTg3d.Lower(); i <= theArrTg3d.Upper(); i++)
0105   {
0106     theArrTg3d(i).Reverse();
0107   }
0108 
0109   for(Standard_Integer i = theArrTg2d.Lower(); i <= theArrTg2d.Upper(); i++)
0110   {
0111     theArrTg2d(i).Reverse();
0112   }
0113 }
0114 
0115 //=======================================================================
0116 //function : CheckTangents
0117 //purpose  : Checks if theArrTg2d have direction
0118 //            corresponded to the direction between theArrPt1 and theArrPt2.
0119 //            If it is not then reverses tangent vector.
0120 //              theArrPt1 (as same as theArrPt2) is sub-set of all 2D-points in
0121 //            one multy-point (multy-point is union of sets of 2D- and 3D-points).
0122 //=======================================================================
0123 static void CheckTangents(const TColgp_Array1OfPnt2d& theArrPt1,
0124                           const TColgp_Array1OfPnt2d& theArrPt2,
0125                           TColgp_Array1OfVec2d& theArrTg2d)
0126 {
0127   if(theArrPt1.Lower() != theArrPt2.Lower())
0128     return;
0129 
0130   if(theArrPt1.Upper() != theArrPt2.Upper())
0131     return;
0132 
0133   for(Standard_Integer i = theArrPt1.Lower(); i <= theArrPt1.Upper(); i++)
0134   {
0135     const gp_Vec2d  aV1(theArrPt1(i), theArrPt2(i));
0136     const gp_Vec2d& aV2 = theArrTg2d(i);
0137 
0138     if(aV1.Dot(aV2) < 0.0)
0139     {
0140       theArrTg2d(i).Reverse();
0141     }
0142   }
0143 }
0144 
0145 
0146 AppParCurves_LeastSquare::
0147   AppParCurves_LeastSquare(const MultiLine&    SSP,
0148                const Standard_Integer          FirstPoint,
0149                const Standard_Integer          LastPoint,
0150                const AppParCurves_Constraint   FirstCons,
0151                const AppParCurves_Constraint   LastCons,
0152                const math_Vector&              Parameters,
0153                const Standard_Integer          NbPol):
0154                SCU(NbPol),
0155                mypoles(1, NbPol,
0156                    1, NbBColumns(SSP)),
0157                A(FirstPoint, LastPoint, 1, NbPol),
0158                DA(FirstPoint, LastPoint, 1, NbPol),
0159                B2(TheFirstPoint(FirstCons, FirstPoint), 
0160                   Max(TheFirstPoint(FirstCons, FirstPoint),
0161                       TheLastPoint(LastCons, LastPoint)),
0162                   1, NbBColumns(SSP)),
0163                mypoints(FirstPoint, LastPoint, 1, NbBColumns(SSP)),
0164                Vflatknots(1, 1),
0165                Vec1t(1, NbBColumns(SSP)),
0166                Vec1c(1, NbBColumns(SSP)),
0167                Vec2t(1, NbBColumns(SSP)),
0168                Vec2c(1, NbBColumns(SSP)),
0169                theError(FirstPoint, LastPoint, 
0170                         1, ToolLine::NbP3d(SSP)+ToolLine::NbP2d(SSP), 0.0),
0171                myindex(FirstPoint, LastPoint, 0),
0172                nbpoles(NbPol)
0173 {
0174   FirstConstraint = FirstCons;  
0175   LastConstraint  = LastCons;
0176   Init(SSP, FirstPoint, LastPoint);
0177   Perform(Parameters);          
0178 }
0179 
0180 
0181 
0182 AppParCurves_LeastSquare::
0183   AppParCurves_LeastSquare(const MultiLine&              SSP,
0184                            const Standard_Integer        FirstPoint,
0185                            const Standard_Integer        LastPoint,
0186                            const AppParCurves_Constraint FirstCons,
0187                            const AppParCurves_Constraint LastCons,
0188                            const Standard_Integer        NbPol):
0189                SCU(NbPol),
0190                mypoles(1, NbPol,
0191                    1, NbBColumns(SSP)),
0192                A(FirstPoint, LastPoint, 1, NbPol),
0193                DA(FirstPoint, LastPoint, 1, NbPol), 
0194                B2(TheFirstPoint(FirstCons, FirstPoint), 
0195                   Max(TheFirstPoint(FirstCons, FirstPoint),
0196                       TheLastPoint(LastCons, LastPoint)),
0197                   1, NbBColumns(SSP)),
0198                mypoints(FirstPoint, LastPoint, 1, NbBColumns(SSP)),
0199                Vflatknots(1, 1),
0200                Vec1t(1, NbBColumns(SSP)),
0201                Vec1c(1, NbBColumns(SSP)),
0202                Vec2t(1, NbBColumns(SSP)),
0203                Vec2c(1, NbBColumns(SSP)),
0204                theError(FirstPoint, LastPoint, 
0205                         1, ToolLine::NbP3d(SSP)+ToolLine::NbP2d(SSP), 0.0),
0206                myindex(FirstPoint, LastPoint, 0),
0207                nbpoles(NbPol)
0208 {
0209   FirstConstraint = FirstCons;  
0210   LastConstraint  = LastCons;
0211   Init(SSP, FirstPoint, LastPoint);
0212 }
0213 
0214 
0215 AppParCurves_LeastSquare::
0216   AppParCurves_LeastSquare(const MultiLine&       SSP,
0217                const TColStd_Array1OfReal&        Knots,
0218                const TColStd_Array1OfInteger&     Mults,
0219                const Standard_Integer             FirstPoint,
0220                const Standard_Integer             LastPoint,
0221                const AppParCurves_Constraint      FirstCons,
0222                const AppParCurves_Constraint      LastCons,
0223                const math_Vector&                 Parameters,
0224                const Standard_Integer             NbPol):
0225                SCU(NbPol),
0226                mypoles(1, NbPol,
0227                    1, NbBColumns(SSP)),
0228                A(FirstPoint, LastPoint, 1, NbPol),
0229                DA(FirstPoint, LastPoint, 1, NbPol),
0230                B2(TheFirstPoint(FirstCons, FirstPoint), 
0231                   Max(TheFirstPoint(FirstCons, FirstPoint),
0232                       TheLastPoint(LastCons, LastPoint)),
0233                   1, NbBColumns(SSP)),
0234                mypoints(FirstPoint, LastPoint, 1, NbBColumns(SSP)),
0235                Vflatknots(1, FlatLength(Mults)),
0236                Vec1t(1, NbBColumns(SSP)),
0237                Vec1c(1, NbBColumns(SSP)),
0238                Vec2t(1, NbBColumns(SSP)),
0239                Vec2c(1, NbBColumns(SSP)),
0240                theError(FirstPoint, LastPoint, 
0241                         1, ToolLine::NbP3d(SSP)+ToolLine::NbP2d(SSP), 0.0),
0242                myindex(FirstPoint, LastPoint, 0),
0243                nbpoles(NbPol)
0244 {
0245   FirstConstraint = FirstCons;  
0246   LastConstraint  = LastCons;
0247   myknots = new TColStd_HArray1OfReal(Knots.Lower(), Knots.Upper());
0248   myknots->ChangeArray1() = Knots;
0249   mymults = new TColStd_HArray1OfInteger(Mults.Lower(), Mults.Upper());
0250   mymults->ChangeArray1() = Mults;
0251   SCU.SetKnots(Knots);
0252   SCU.SetMultiplicities(Mults);
0253   Init(SSP, FirstPoint, LastPoint);
0254   Perform(Parameters);          
0255 }
0256 
0257 
0258 
0259 AppParCurves_LeastSquare::
0260   AppParCurves_LeastSquare(const MultiLine&               SSP,
0261                            const TColStd_Array1OfReal&    Knots,
0262                            const TColStd_Array1OfInteger& Mults,
0263                            const Standard_Integer         FirstPoint,
0264                            const Standard_Integer         LastPoint,
0265                            const AppParCurves_Constraint  FirstCons,
0266                            const AppParCurves_Constraint  LastCons,
0267                            const Standard_Integer         NbPol):
0268                SCU(NbPol),
0269                mypoles(1, NbPol,
0270                    1, NbBColumns(SSP)),
0271                A(FirstPoint, LastPoint, 1, NbPol),
0272                DA(FirstPoint, LastPoint, 1, NbPol),
0273                B2(TheFirstPoint(FirstCons, FirstPoint), 
0274                   Max(TheFirstPoint(FirstCons, FirstPoint),
0275                       TheLastPoint(LastCons, LastPoint)),
0276                   1, NbBColumns(SSP)),
0277                mypoints(FirstPoint, LastPoint, 1, NbBColumns(SSP)),
0278                Vflatknots(1, FlatLength(Mults)),
0279                Vec1t(1, NbBColumns(SSP)),
0280                Vec1c(1, NbBColumns(SSP)),
0281                Vec2t(1, NbBColumns(SSP)),
0282                Vec2c(1, NbBColumns(SSP)),
0283                theError(FirstPoint, LastPoint, 
0284                         1, ToolLine::NbP3d(SSP)+ToolLine::NbP2d(SSP), 0.0),
0285                myindex(FirstPoint, LastPoint, 0),
0286                nbpoles(NbPol)
0287 {
0288   myknots = new TColStd_HArray1OfReal(Knots.Lower(), Knots.Upper());
0289   myknots->ChangeArray1() = Knots;
0290   mymults = new TColStd_HArray1OfInteger(Mults.Lower(), Mults.Upper());
0291   mymults->ChangeArray1() = Mults;
0292   SCU.SetKnots(Knots);
0293   SCU.SetMultiplicities(Mults);
0294   FirstConstraint = FirstCons;  
0295   LastConstraint  = LastCons;
0296   Init(SSP, FirstPoint, LastPoint);
0297 }
0298 
0299 
0300 
0301 void AppParCurves_LeastSquare::Init(const MultiLine& SSP, 
0302                                     const Standard_Integer FirstPoint,
0303                                     const Standard_Integer LastPoint)
0304 {
0305   // Variable de controle
0306   iscalculated = Standard_False;
0307   isready = Standard_True;
0308 
0309   myfirstp = FirstPoint;
0310   mylastp = LastPoint;
0311   FirstP = TheFirstPoint(FirstConstraint, myfirstp);
0312   LastP  = TheLastPoint(LastConstraint, mylastp);
0313 
0314   // Reperage des contraintes aux extremites:
0315   // ========================================
0316   Standard_Integer i, j, k, i2;
0317 
0318   nbP2d = ToolLine::NbP2d(SSP);
0319   nbP   = ToolLine::NbP3d(SSP);
0320   gp_Pnt Poi;
0321   gp_Pnt2d Poi2d;
0322 //  gp_Vec V3d;
0323 //  gp_Vec2d V2d;
0324   Standard_Integer mynbP2d = nbP2d, mynbP = nbP;
0325   if (nbP2d == 0) mynbP2d = 1;
0326   if (nbP == 0) mynbP = 1;
0327   TColgp_Array1OfPnt TabP(1, mynbP);
0328   TColgp_Array1OfPnt2d TabP2d(1, mynbP2d);
0329   TColgp_Array1OfVec TabV(1, mynbP);
0330   TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
0331 
0332 
0333   deg = nbpoles-1;
0334 
0335   if (!mymults.IsNull()) {
0336     Standard_Integer sum = 0;
0337     for (i = mymults->Lower(); i <= mymults->Upper(); i++) {
0338       sum += mymults->Value(i);
0339     }
0340     deg = sum -nbpoles-1;
0341     k = 1;
0342     Standard_Real val;
0343     for (i = myknots->Lower(); i <= myknots->Upper(); i++) {
0344       for (j = 1; j <= mymults->Value(i); j++) {
0345         val = myknots->Value(i);
0346         Vflatknots(k) = val;
0347         k++;
0348       }
0349     }
0350   }
0351 
0352 
0353   Affect(SSP, FirstPoint, FirstConstraint, Vec1t, Vec1c);
0354 
0355   Affect(SSP, LastPoint, LastConstraint, Vec2t, Vec2c);
0356 
0357   for (j = myfirstp; j <= mylastp; j++) {
0358     i2 = 1;
0359     if (nbP != 0 && nbP2d != 0) ToolLine::Value(SSP, j, TabP,TabP2d);
0360     else if (nbP2d != 0)        ToolLine::Value(SSP, j, TabP2d);
0361     else                        ToolLine::Value(SSP, j, TabP);
0362     for (i = 1; i <= nbP; i++) {
0363       (TabP(i)).Coord(mypoints(j,i2),mypoints(j,i2+1),mypoints(j,i2+2));
0364       i2 += 3;
0365     }
0366     for (i = 1;i <= nbP2d; i++) {
0367       (TabP2d(i)).Coord(mypoints(j, i2), mypoints(j, i2+1));
0368       i2 += 2;
0369     }
0370   }
0371 
0372   AppParCurves_MultiPoint Pole1(nbP, nbP2d), PoleN(nbP, nbP2d);
0373 
0374   if (FirstConstraint == AppParCurves_PassPoint ||
0375       FirstConstraint == AppParCurves_TangencyPoint ||
0376       FirstConstraint == AppParCurves_CurvaturePoint) {
0377     i2 = 1;
0378     for (i = 1; i <= nbP; i++) {
0379       Poi.SetCoord(mypoints(myfirstp, i2), 
0380                    mypoints(myfirstp, i2+1), 
0381                    mypoints(myfirstp, i2+2));
0382       Pole1.SetPoint(i, Poi);
0383       i2 += 3;
0384     }
0385     for (i = 1; i <= nbP2d; i++) {
0386       Poi2d.SetCoord(mypoints(myfirstp, i2), mypoints(myfirstp, i2+1));
0387       Pole1.SetPoint2d(i+nbP, Poi2d);
0388       i2 += 2;
0389     }
0390     for (i = 1; i <= mypoles.ColNumber(); i++)
0391       mypoles(1, i) = mypoints(myfirstp, i);
0392   }
0393   
0394 
0395 
0396   if (LastConstraint == AppParCurves_PassPoint ||
0397       LastConstraint == AppParCurves_TangencyPoint ||
0398       FirstConstraint == AppParCurves_CurvaturePoint) {
0399     i2 = 1;
0400     for (i = 1; i <= nbP; i++) {
0401       Poi.SetCoord(mypoints(mylastp, i2), 
0402                    mypoints(mylastp, i2+1), 
0403                    mypoints(mylastp, i2+2));
0404       PoleN.SetPoint(i, Poi);
0405       i2 += 3;
0406     }
0407     for (i = 1; i <= nbP2d; i++) {
0408       Poi2d.SetCoord(mypoints(mylastp, i2), 
0409                      mypoints(mylastp, i2+1));
0410       PoleN.SetPoint2d(i+nbP, Poi2d);
0411       i2 += 2;
0412     }
0413     
0414     for (i = 1; i <= mypoles.ColNumber(); i++)
0415       mypoles(nbpoles, i) = mypoints(mylastp, i);
0416   }
0417 
0418 
0419   if (FirstConstraint == AppParCurves_NoConstraint) { 
0420     resinit = 1;
0421     SCU.SetValue(1, Pole1);
0422     if (LastConstraint == AppParCurves_NoConstraint) {
0423       resfin = nbpoles;
0424     }
0425     else if (LastConstraint == AppParCurves_PassPoint) {
0426       resfin = nbpoles-1;
0427       SCU.SetValue(nbpoles, PoleN);
0428     }
0429     else if (LastConstraint == AppParCurves_TangencyPoint) {
0430       resfin = nbpoles-2;
0431       SCU.SetValue(nbpoles, PoleN);
0432     }
0433     else if (LastConstraint == AppParCurves_CurvaturePoint) {
0434       resfin = nbpoles-3;
0435       SCU.SetValue(nbpoles, PoleN);
0436     }
0437   }
0438   else if (FirstConstraint == AppParCurves_PassPoint) {
0439     resinit = 2;
0440     SCU.SetValue(1, Pole1);
0441     if (LastConstraint == AppParCurves_NoConstraint) {
0442       resfin = nbpoles;
0443     }
0444     else if (LastConstraint == AppParCurves_PassPoint) {
0445       resfin = nbpoles-1;
0446       SCU.SetValue(nbpoles, PoleN);
0447     }
0448     else if (LastConstraint == AppParCurves_TangencyPoint) {
0449       resfin = nbpoles-2;
0450       SCU.SetValue(nbpoles, PoleN);
0451     }
0452     else if (LastConstraint == AppParCurves_CurvaturePoint) {
0453       resfin = nbpoles-3;
0454       SCU.SetValue(nbpoles, PoleN);
0455     }
0456   }
0457   else if (FirstConstraint == AppParCurves_TangencyPoint) {
0458     resinit = 3;
0459     SCU.SetValue(1, Pole1);
0460     if (LastConstraint == AppParCurves_NoConstraint) {
0461       resfin = nbpoles;
0462     }
0463     if (LastConstraint == AppParCurves_PassPoint) {
0464       resfin = nbpoles-1;
0465       SCU.SetValue(nbpoles, PoleN);
0466     }
0467     if (LastConstraint == AppParCurves_TangencyPoint) {
0468       resfin = nbpoles-2;
0469       SCU.SetValue(nbpoles, PoleN);
0470     }
0471     else if (LastConstraint == AppParCurves_CurvaturePoint) {
0472       resfin = nbpoles-3;
0473       SCU.SetValue(nbpoles, PoleN);
0474     }
0475   }
0476   else if (FirstConstraint == AppParCurves_CurvaturePoint) {
0477     resinit = 4;
0478     SCU.SetValue(1, Pole1);
0479     if (LastConstraint == AppParCurves_NoConstraint) {
0480       resfin = nbpoles;
0481     }
0482     if (LastConstraint == AppParCurves_PassPoint) {
0483       resfin = nbpoles-1;
0484       SCU.SetValue(nbpoles, PoleN);
0485     }
0486     if (LastConstraint == AppParCurves_TangencyPoint) {
0487       resfin = nbpoles-2;
0488       SCU.SetValue(nbpoles, PoleN);
0489     }
0490     else if (LastConstraint == AppParCurves_CurvaturePoint) {
0491       resfin = nbpoles-3;
0492       SCU.SetValue(nbpoles, PoleN);
0493     }
0494   }
0495 
0496   Standard_Integer Nincx = resfin-resinit+1;
0497   if  (Nincx<1) { //Impossible d'aller plus loin
0498     isready = Standard_False;
0499     return;
0500   } 
0501   Standard_Integer Neq = LastP-FirstP+1;
0502   
0503   NA = 3*nbP+2*nbP2d;
0504   Nlignes = NA*Neq;
0505   Ninc = NA*Nincx;
0506   if (FirstConstraint >= AppParCurves_TangencyPoint) Ninc++;
0507   if (LastConstraint >= AppParCurves_TangencyPoint) Ninc++;
0508 }
0509 
0510 
0511 
0512 
0513 void AppParCurves_LeastSquare::Perform(const math_Vector& Parameters) {
0514 
0515   done = Standard_False;
0516   if (!isready) {
0517     return;
0518   }
0519   Standard_Integer i, j, k, Ci, i2, k1, k2;
0520   Standard_Integer nbpol1 = nbpoles-1, Ninc1 = Ninc-1;
0521   Standard_Real AD1, A0;
0522 //  gp_Pnt Pt;
0523 //  gp_Pnt2d Pt2d;
0524   iscalculated = Standard_False;
0525 
0526   // calcul de la matrice A et DA des fonctions d approximation:
0527   ComputeFunction(Parameters);
0528 
0529   if (FirstConstraint != AppParCurves_TangencyPoint && 
0530       LastConstraint != AppParCurves_TangencyPoint) { 
0531     if (FirstConstraint == AppParCurves_NoConstraint) { 
0532       if (LastConstraint == AppParCurves_NoConstraint ) {
0533         
0534         math_Householder HouResol(A, mypoints); 
0535         if (!(HouResol.IsDone())) {
0536           done = Standard_False;
0537           return;
0538         }
0539         done = Standard_True;
0540         mypoles = HouResol.AllValues();
0541         return;
0542         
0543       }
0544       else {
0545         for (j = FirstP; j <= LastP; j++) {
0546           AD1 = A(j, nbpoles);
0547           for (i = 1; i <= B2.ColNumber(); i++) {
0548             B2(j, i) = mypoints(j,i) - AD1*mypoles(nbpoles, i);
0549           }
0550         }
0551       }
0552     }
0553     else if (FirstConstraint == AppParCurves_PassPoint) {
0554       if (LastConstraint == AppParCurves_NoConstraint) {
0555         for (j = FirstP; j <= LastP; j++) {
0556           A0 = A(j, 1);
0557           for (i = 1; i <= B2.ColNumber(); i++) {
0558             B2(j, i) =  mypoints(j, i)- A0*mypoles(1, i);
0559           }
0560         }
0561       }
0562       else if (LastConstraint == AppParCurves_PassPoint) {
0563         for (j = FirstP; j <= LastP; j++) {
0564           A0 = A(j, 1);
0565           AD1 = A(j, nbpoles);
0566           for (i = 1; i <= B2.ColNumber(); i++) {
0567             B2(j, i) = mypoints(j, i) - A0 * mypoles(1, i) 
0568                                   - AD1* mypoles(nbpoles, i);
0569           }
0570         }
0571       }
0572     }
0573 
0574     // resolution:
0575 
0576     Standard_Integer Nincx = resfin-resinit+1;
0577     if (Nincx < 1) { 
0578       done = Standard_True;
0579       return;
0580     }
0581     math_IntegerVector Index(1, Nincx);
0582     SearchIndex(Index);
0583     math_Matrix mytab(resinit, resfin, 1, B2.ColNumber(),0.0);
0584     math_Vector TheAA(1, Index(Nincx), 0.0);
0585     math_Vector myTABB(1, Nincx, 0.0);
0586     
0587     MakeTAA(TheAA, mytab);
0588     DACTCL_Decompose(TheAA, Index);
0589     
0590     Standard_Integer kk2;
0591     for (j = 1; j <= B2.ColNumber(); j++) {
0592       kk2 = 1;
0593       for (i = resinit; i <= resfin; i++) {
0594         myTABB(kk2) = mytab(i, j);
0595         kk2++;
0596       }
0597       DACTCL_Solve(TheAA, myTABB, Index);
0598       
0599       i2 = 1;
0600       for (k = resinit; k <= resfin; k++) {
0601         mypoles(k, j)  = myTABB.Value(i2);
0602         i2++;
0603       }
0604     }
0605     done = Standard_True;
0606   }
0607 
0608   // ===========================================================
0609   // cas de tangence:
0610   // ===========================================================
0611 
0612   Standard_Integer Nincx = resfin-resinit+1;
0613   Standard_Integer deport = 0, Nincx2 = 2*Nincx;
0614   
0615   math_IntegerVector InternalIndex(1, Nincx);
0616   SearchIndex(InternalIndex);
0617   math_IntegerVector Index(1, Ninc);
0618   
0619   Standard_Integer l = 1;
0620   if (resinit <= resfin) {
0621     for (j = 0; j <= NA-1; j++) {
0622       deport = j*InternalIndex(Nincx);
0623       for (i = 1; i <= Nincx; i++) {
0624         Index(l) = InternalIndex(i) + deport;
0625         l++;
0626       }
0627     }
0628   }
0629       
0630   if (resinit > resfin) Index(1) = 1;
0631   if (Ninc1 > 1) {
0632     if (FirstConstraint >= AppParCurves_TangencyPoint &&
0633         LastConstraint >= AppParCurves_TangencyPoint) 
0634       Index(Ninc1) = Index(Ninc1 - 1) + Ninc1;
0635   }
0636   if (FirstConstraint >= AppParCurves_TangencyPoint ||
0637       LastConstraint >= AppParCurves_TangencyPoint) 
0638     Index(Ninc) = Index(Ninc-1) + Ninc;
0639   
0640 
0641   math_Vector TheA(1, Index(Ninc), 0.0);
0642   math_Vector myTAB(1, Ninc, 0.0);
0643   
0644   MakeTAA(TheA, myTAB);
0645   
0646   Standard_Integer Error = DACTCL_Decompose(TheA, Index);
0647   Error = DACTCL_Solve(TheA, myTAB, Index);
0648   
0649   if (!Error) done = Standard_True;
0650   
0651   if (FirstConstraint >= AppParCurves_TangencyPoint &&
0652       LastConstraint >= AppParCurves_TangencyPoint) {
0653     lambda1 = myTAB.Value(Ninc1);
0654     lambda2 = myTAB.Value(Ninc);
0655   }
0656   else if (FirstConstraint >= AppParCurves_TangencyPoint)
0657     lambda1 = myTAB.Value(Ninc);
0658   else if (LastConstraint >= AppParCurves_TangencyPoint)
0659     lambda2 = myTAB.Value(Ninc);
0660 
0661 
0662   
0663   // Les resultats sont stockes dans mypoles.
0664   //=========================================
0665   k = 1;
0666   i2 = 1;
0667   for (Ci = 1; Ci <= nbP; Ci++) {
0668     k1 = k+1; k2 = k+2;
0669     for (j = resinit; j <= resfin; j++) {
0670       mypoles(j, k)  = myTAB.Value(i2);
0671       mypoles(j, k1) = myTAB.Value(i2+Nincx);
0672       mypoles(j, k2) = myTAB.Value(i2+Nincx2);
0673       i2++;
0674     }
0675     
0676     if (FirstConstraint >= AppParCurves_TangencyPoint) {
0677       mypoles(2, k)        = mypoints(myfirstp, k)   + lambda1*Vec1t(k);
0678       mypoles(2, k1)       = mypoints(myfirstp, k1)  + lambda1*Vec1t(k1);
0679       mypoles(2, k2)       = mypoints(myfirstp, k2)  + lambda1*Vec1t(k2);
0680     }
0681     if (LastConstraint >= AppParCurves_TangencyPoint) {
0682       mypoles(nbpol1, k)   = mypoints(mylastp,  k)   - lambda2*Vec2t(k);
0683       mypoles(nbpol1, k1)  = mypoints(mylastp,  k1)  - lambda2*Vec2t(k1);
0684       mypoles(nbpol1, k2)  = mypoints(mylastp,  k2)  - lambda2*Vec2t(k2);
0685     }
0686     k += 3; i2 += Nincx2;
0687   }
0688 
0689   for (Ci = 1; Ci <= nbP2d; Ci++) {
0690     k1 = k+1; k2 = k+2;
0691     for (j = resinit; j <= resfin; j++) {
0692       mypoles(j, k)  = myTAB.Value(i2);
0693       mypoles(j, k1) = myTAB.Value(i2+Nincx);
0694       i2++;
0695     }
0696     if (FirstConstraint >= AppParCurves_TangencyPoint) {
0697       mypoles(2, k)       = mypoints(myfirstp, k)  + lambda1*Vec1t(k);
0698       mypoles(2, k1)      = mypoints(myfirstp, k1) + lambda1*Vec1t(k1);
0699     }
0700     if (LastConstraint >= AppParCurves_TangencyPoint) {
0701       mypoles(nbpol1, k)  = mypoints(mylastp,  k)  - lambda2*Vec2t(k);
0702       mypoles(nbpol1, k1) = mypoints(mylastp,  k1) - lambda2*Vec2t(k1);
0703     }
0704     k += 2; i2 += Nincx;
0705   }
0706   
0707 }
0708 
0709 void AppParCurves_LeastSquare::Perform(const math_Vector&  Parameters,
0710                                        const math_Vector&  V1t,
0711                                        const math_Vector&  V2t,
0712                                        const Standard_Real l1,
0713                                        const Standard_Real l2) 
0714 {
0715   done = Standard_False;
0716   if (!isready) {
0717     return;
0718   }
0719   Standard_Integer i, lower1 = V1t.Lower(), lower2 = V2t.Lower();
0720   resinit = 3; resfin = nbpoles-2;
0721   Standard_Integer Nincx = resfin-resinit+1;
0722   Ninc = NA*Nincx + 2;
0723   FirstConstraint = AppParCurves_TangencyPoint;
0724   LastConstraint = AppParCurves_TangencyPoint;
0725   for (i = 1; i <= Vec1t.Upper(); i++) {
0726     Vec1t(i) = V1t(i+lower1-1);
0727     Vec2t(i) = V2t(i+lower2-1);
0728   }
0729   Perform (Parameters, l1, l2);
0730 }
0731 
0732 
0733 void AppParCurves_LeastSquare::Perform(const math_Vector&  Parameters,
0734                                        const math_Vector&  V1t,
0735                                        const math_Vector&  V2t,
0736                                        const math_Vector&  V1c,
0737                                        const math_Vector&  V2c,
0738                                        const Standard_Real l1,
0739                                        const Standard_Real l2) {
0740   done = Standard_False;
0741   if (!isready) {
0742     return;
0743   }
0744   Standard_Integer i, lower1 = V1t.Lower(), lower2 = V2t.Lower();
0745   Standard_Integer lowc1 = V1c.Lower(), lowc2 = V2c.Lower();
0746   resinit = 4; resfin = nbpoles-3;
0747   Standard_Integer Nincx = resfin-resinit+1;
0748   Ninc = NA*Nincx + 2;
0749   FirstConstraint = AppParCurves_CurvaturePoint;
0750   LastConstraint = AppParCurves_CurvaturePoint;
0751 
0752   for (i = 1; i <= Vec1t.Upper(); i++) {
0753     Vec1t(i) = V1t(i+lower1-1);
0754     Vec2t(i) = V2t(i+lower2-1);
0755     Vec1c(i) = V1c(i+lowc1-1);
0756     Vec2c(i) = V2c(i+lowc2-1);
0757   }
0758   Perform (Parameters, l1, l2);
0759 }
0760 
0761 
0762 
0763 void AppParCurves_LeastSquare::Perform(const math_Vector&  Parameters,
0764                                        const Standard_Real l1,
0765                                        const Standard_Real l2) {
0766   done = Standard_False;
0767   if (!isready) {
0768     return;
0769   }
0770   if (FirstConstraint < AppParCurves_TangencyPoint &&
0771       LastConstraint  < AppParCurves_TangencyPoint) {
0772     Perform(Parameters);
0773     return;
0774   }
0775   iscalculated = Standard_False;
0776 
0777   lambda1 = l1;
0778   lambda2 = l2;
0779   Standard_Integer i, j, k, i2;
0780   Standard_Real AD0, AD1, AD2, A0, A1, A2;
0781 //  gp_Pnt Pt, P1, P2;
0782 //  gp_Pnt2d Pt2d, P12d, P22d;
0783   Standard_Real l11 = deg*l1, l22 = deg*l2;
0784 
0785   ComputeFunction(Parameters);
0786 
0787   if (FirstConstraint >= AppParCurves_TangencyPoint) {
0788     for (i = 1; i <= mypoles.ColNumber(); i++)
0789       mypoles(2, i) = mypoints(myfirstp, i) + l1*Vec1t(i);
0790   }
0791 
0792 
0793   if (FirstConstraint == AppParCurves_CurvaturePoint) {
0794     for (i = 1; i <= mypoles.ColNumber(); i++)
0795       mypoles(3, i) = 2*mypoles(2, i)-mypoles(1, i) 
0796                   + l11*l11*Vec1c(i)/(deg*(deg-1));
0797   }
0798 
0799 
0800   if (LastConstraint >= AppParCurves_TangencyPoint) {
0801     for (i = 1; i <= mypoles.ColNumber(); i++)
0802       mypoles(nbpoles-1, i) = mypoints(mylastp, i) - l2*Vec2t(i);
0803   }
0804 
0805 
0806   if (LastConstraint == AppParCurves_CurvaturePoint) {
0807     for (i = 1; i <= mypoles.ColNumber(); i++)
0808       mypoles(nbpoles-2, i) = 2*mypoles(nbpoles-1, i) - mypoles(nbpoles, i)
0809                           + l22*l22*Vec2c(i)/(deg*(deg-1));
0810   }
0811 
0812   if (resinit > resfin) {
0813     done = Standard_True;
0814     return;
0815   }
0816 
0817   if (FirstConstraint == AppParCurves_NoConstraint) { 
0818     if (LastConstraint == AppParCurves_TangencyPoint) {
0819       for (j = FirstP; j <= LastP; j++) {
0820         AD0 = A(j, nbpoles);  AD1 = A(j, nbpoles-1); 
0821         for (i = 1; i <= B2.ColNumber(); i++) {
0822           B2(j, i) = mypoints(j, i) - AD0 * mypoles(nbpoles, i)
0823                                 - AD1 * mypoles(nbpoles-1, i);
0824         }
0825       }
0826     }
0827     if (LastConstraint == AppParCurves_CurvaturePoint) {
0828       for (j = FirstP; j <= LastP; j++) {
0829         AD0 = A(j, nbpoles);  AD1 = A(j, nbpoles-1); AD2 = A(j, nbpoles-2);
0830         for (i = 1; i <= B2.ColNumber(); i++) {
0831           B2(j, i) = mypoints(j, i) - AD0 * mypoles(nbpoles, i)
0832                                 - AD1 * mypoles(nbpoles-1, i)
0833                                 - AD2 * mypoles(nbpoles-2, i);
0834         }
0835       }
0836     }
0837   }
0838   else if (FirstConstraint == AppParCurves_PassPoint) {
0839     if (LastConstraint == AppParCurves_TangencyPoint) {
0840       for (j = FirstP; j <= LastP; j++) {
0841         A0 = A(j, 1);
0842         AD0 = A(j, nbpoles);  AD1 = A(j, nbpoles-1);
0843         for (i = 1; i <= B2.ColNumber(); i++) {
0844           B2(j, i) = mypoints(j, i) - A0  * mypoles(1, i) 
0845                                 - AD0 * mypoles(nbpoles, i)
0846                                 - AD1 * mypoles(nbpoles-1, i);
0847         }
0848       }
0849     }
0850     if (LastConstraint == AppParCurves_CurvaturePoint) {
0851       for (j = FirstP; j <= LastP; j++) {
0852         A0 = A(j, 1);
0853         AD0 = A(j, nbpoles);  AD1 = A(j, nbpoles-1); AD2 = A(j, nbpoles-2);
0854         for (i = 1; i <= B2.ColNumber(); i++) {
0855           B2(j, i) = mypoints(j, i) - A0  * mypoles(1, i) 
0856                                 - AD0 * mypoles(nbpoles, i)
0857                                 - AD1 * mypoles(nbpoles-1, i)
0858                                 - AD2 * mypoles(nbpoles-2, i);
0859         }
0860       }
0861     }
0862   }
0863   else if (FirstConstraint == AppParCurves_TangencyPoint) {
0864     if (LastConstraint == AppParCurves_NoConstraint) {
0865       for (j = FirstP; j <= LastP; j++) {
0866         A0 = A(j, 1); A1 = A(j, 2);
0867         for (i = 1; i <= B2.ColNumber(); i++) {
0868           B2(j, i) = mypoints(j, i) - A0  * mypoles(1, i) 
0869                                     - A1  * mypoles(2, i);
0870         }
0871       }
0872     }
0873     else if (LastConstraint == AppParCurves_PassPoint) {
0874       for (j = FirstP; j <= LastP; j++) {
0875         A0 = A(j, 1);  AD0 = A(j, nbpoles); A1 = A(j, 2);
0876         for (i = 1; i <= B2.ColNumber(); i++) {
0877           B2(j, i) = mypoints(j, i) - A0  * mypoles(1, i) 
0878                                     - AD0 * mypoles(nbpoles, i)
0879                                     - A1  * mypoles(2, i);
0880         }
0881       }
0882     }
0883     else if (LastConstraint == AppParCurves_TangencyPoint) {
0884       for (j = FirstP; j <= LastP; j++) {
0885         A0 = A(j, 1);  AD0 = A(j, nbpoles); A1 = A(j, 2); AD1 = A(j, nbpoles-1);
0886         for (i = 1; i <= B2.ColNumber(); i++) {
0887           B2(j, i) = mypoints(j, i) - A0  * mypoles(1, i) 
0888                                     - AD0 * mypoles(nbpoles, i)
0889                                     - A1  * mypoles(2, i)
0890                                     - AD1 * mypoles(nbpoles-1, i);
0891         }
0892       }
0893     }
0894   }
0895   else if (FirstConstraint == AppParCurves_CurvaturePoint) {
0896     if (LastConstraint == AppParCurves_NoConstraint) {
0897       for (j = FirstP; j <= LastP; j++) {
0898         A0 = A(j, 1);  A1 = A(j, 2);  A2 = A(j, 3);
0899         for (i = 1; i <= B2.ColNumber(); i++) {
0900           B2(j, i) = mypoints(j, i) - A0 * mypoles(1, i)
0901                                 - A1 * mypoles(2, i)
0902                                 - A2 * mypoles(3, i);
0903         }
0904       }
0905     }
0906     else if (LastConstraint == AppParCurves_PassPoint) {
0907       for (j = FirstP; j <= LastP; j++) {
0908         A0 = A(j, 1);  A1 = A(j, 2);  A2 = A(j, 3);  AD0 = A(j, nbpoles);
0909         for (i = 1; i <= B2.ColNumber(); i++) {
0910           B2(j, i) = mypoints(j, i) - A0  * mypoles(1, i)
0911                                 - A1  * mypoles(2, i)
0912                                 - A2  * mypoles(3, i)
0913                                 - AD0 * mypoles(nbpoles, i);
0914         }
0915       }
0916     }
0917     else if (LastConstraint == AppParCurves_TangencyPoint) {
0918       for (j = FirstP; j <= LastP; j++) {
0919         A0 = A(j, 1);     A1 = A(j, 2);   A2 = A(j, 3);
0920         AD0 = A(j, nbpoles);  AD1 = A(j, nbpoles-1);
0921         for (i = 1; i <= B2.ColNumber(); i++) {
0922           B2(j, i) = mypoints(j, i) - A0  * mypoles(1, i) 
0923                                 - A1  * mypoles(2, i)
0924                                 - A2  * mypoles(3, i)
0925                                 - AD0 * mypoles(nbpoles, i)
0926                                 - AD1 * mypoles(nbpoles-1, i);
0927         }
0928       }
0929     }
0930     else if (LastConstraint == AppParCurves_CurvaturePoint) {
0931       for (j = FirstP; j <= LastP; j++) {
0932         A0 = A(j, 1);     A1 = A(j, 2);   A2 = A(j, 3);
0933         AD0 = A(j, nbpoles);  AD1 = A(j, nbpoles-1); AD2 = A(j, nbpoles-2);
0934         for (i = 1; i <= B2.ColNumber(); i++) {
0935           B2(j, i) = mypoints(j, i) - A0  * mypoles(1, i) 
0936                                 - A1  * mypoles(2, i)
0937                                 - A2  * mypoles(3, i)
0938                                 - AD0 * mypoles(nbpoles, i)
0939                                 - AD1 * mypoles(nbpoles-1, i)
0940                                 - AD2 * mypoles(nbpoles-2, i);
0941         }
0942       }
0943     }
0944   }
0945   
0946   Standard_Integer Nincx = resfin-resinit+1;
0947 
0948   math_Matrix mytab(resinit, resfin, 1, B2.ColNumber(),0.0);
0949   math_IntegerVector Index(1, Nincx);
0950   SearchIndex(Index);
0951   math_Vector AA(1, Index(Nincx), 0.0);
0952   MakeTAA(AA, mytab);
0953 
0954   math_Vector myTABB(1, Nincx, 0.0);
0955 
0956   DACTCL_Decompose(AA, Index);
0957   
0958   Standard_Integer kk2;
0959   for (j = 1; j <= B2.ColNumber(); j++) {
0960     kk2 = 1;
0961     for (i = resinit; i <= resfin; i++) {
0962       myTABB(kk2) = mytab(i, j);
0963       kk2++;
0964     }
0965     
0966     DACTCL_Solve(AA, myTABB, Index);
0967     
0968     i2 = 1;
0969     for (k = resinit; k <= resfin; k++) {
0970       mypoles(k, j)  = myTABB.Value(i2);
0971       i2++;
0972     }
0973 
0974   }
0975   
0976   done = Standard_True;
0977 
0978 }
0979 
0980 
0981 
0982 //=======================================================================
0983 //function : Affect
0984 //purpose  :    Index is an ID of the point in MultiLine. Every point is set of
0985 //            several 3D- and 2D-points. E.g. every points of Walking-line,
0986 //            obtained in intersection algorithm, is set of one 3D points
0987 //            (nbP == 1) and two 2D-points (nbP2d == 2).
0988 //=======================================================================
0989 void AppParCurves_LeastSquare::Affect(const MultiLine& SSP,
0990                                       const Standard_Integer Index,
0991                                       AppParCurves_Constraint& Cons,
0992                                       math_Vector& Vt,
0993                                       math_Vector& Vc)
0994 {
0995   // Vt: vector of tangent, Vc: vector of curvature.
0996 
0997   if (Cons >= AppParCurves_TangencyPoint) {
0998     Standard_Integer i, i2 = 1;
0999     Standard_Boolean Ok;
1000     Standard_Integer mynbP2d = nbP2d, mynbP = nbP;
1001     if (nbP2d == 0) mynbP2d = 1;
1002     if (nbP == 0) mynbP = 1;
1003     TColgp_Array1OfVec TabV(1, mynbP);
1004     TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
1005     
1006     if (Cons == AppParCurves_CurvaturePoint)
1007     {
1008       if (nbP != 0 && nbP2d != 0)
1009       {
1010         Ok = ToolLine::Curvature(SSP, Index,TabV,TabV2d);
1011         if (!Ok) { Cons = AppParCurves_TangencyPoint;}
1012       }
1013       else if (nbP2d != 0)
1014       {
1015         Ok = ToolLine::Curvature(SSP, Index, TabV2d);
1016         if (!Ok) { Cons = AppParCurves_TangencyPoint;}
1017       }
1018       else {
1019         Ok = ToolLine::Curvature(SSP, Index, TabV);
1020         if (!Ok) { Cons = AppParCurves_TangencyPoint;}
1021       }
1022       if (Ok) {
1023         for (i = 1; i <= nbP; i++) {
1024           (TabV(i)).Coord(Vc(i2), Vc(i2+1), Vc(i2+2));
1025           i2 += 3;
1026         }
1027 
1028         for (i = 1; i <= nbP2d; i++) {
1029           (TabV2d(i)).Coord(Vc(i2), Vc(i2+1));
1030           i2 += 2;
1031         }
1032       }
1033     }
1034 
1035     i2 = 1;
1036     if (Cons >= AppParCurves_TangencyPoint) {
1037       if (nbP != 0 && nbP2d != 0) {
1038         Ok = ToolLine::Tangency(SSP, Index, TabV, TabV2d);
1039         if (!Ok) { Cons = AppParCurves_PassPoint;}
1040       }
1041       else if (nbP2d != 0) {
1042         Ok = ToolLine::Tangency(SSP, Index, TabV2d);
1043         if (!Ok) { Cons = AppParCurves_PassPoint;}
1044       }
1045       else {
1046         Ok = ToolLine::Tangency(SSP, Index, TabV);
1047         if (!Ok) { Cons = AppParCurves_PassPoint;}
1048       }
1049 
1050       if (Ok)
1051       {
1052         TColgp_Array1OfPnt anArrPts3d1(1, mynbP), anArrPts3d2(1, mynbP);
1053 
1054         if(nbP != 0)
1055         {
1056           if(Index < ToolLine::LastPoint(SSP))
1057           {
1058             ToolLine::Value(SSP, Index, anArrPts3d1);
1059             ToolLine::Value(SSP, Index+1, anArrPts3d2);
1060           }
1061           else
1062           {// (Index == ToolLine::LastPoint(theML))
1063             ToolLine::Value(SSP, Index-1, anArrPts3d1);
1064             ToolLine::Value(SSP, Index, anArrPts3d2);
1065           }
1066 
1067           CheckTangents(anArrPts3d1, anArrPts3d2, TabV, TabV2d);
1068         }
1069         else if(nbP2d != 0)
1070         {
1071           TColgp_Array1OfPnt2d anArrPts2d1(1, mynbP2d), anArrPts2d2(1, mynbP2d);
1072 
1073           if(Index < ToolLine::LastPoint(SSP))
1074           {
1075             ToolLine::Value(SSP, Index, anArrPts3d1, anArrPts2d1);
1076             ToolLine::Value(SSP, Index+1, anArrPts3d2, anArrPts2d2);
1077           }
1078           else
1079           {// (Index == ToolLine::LastPoint(theML))
1080             ToolLine::Value(SSP, Index-1, anArrPts3d1, anArrPts2d1);
1081             ToolLine::Value(SSP, Index, anArrPts3d2, anArrPts2d2);
1082           }
1083 
1084           CheckTangents(anArrPts2d1, anArrPts2d2, TabV2d);
1085         }
1086 
1087         for (i = 1; i <= nbP; i++) {
1088           (TabV(i)).Coord(Vt(i2), Vt(i2+1), Vt(i2+2));
1089           i2 += 3;
1090         }
1091 
1092         for (i = 1; i <= nbP2d; i++) {
1093           (TabV2d(i)).Coord(Vt(i2), Vt(i2+1));
1094           i2 += 2;
1095         }
1096       }
1097     }
1098   }
1099 }
1100 
1101 
1102 
1103 Standard_Integer AppParCurves_LeastSquare::NbBColumns(
1104                                      const MultiLine& SSP) const
1105 {
1106   Standard_Integer BCol;
1107   BCol = (ToolLine::NbP3d(SSP))*3 +
1108          (ToolLine::NbP2d(SSP))*2;
1109   return BCol;
1110 }
1111 
1112 
1113 void AppParCurves_LeastSquare::Error(Standard_Real& F, 
1114                                      Standard_Real& MaxE3d,
1115                                      Standard_Real& MaxE2d)
1116 {
1117 
1118   if (!done) {throw StdFail_NotDone();}
1119   Standard_Integer i, j, k, i2, indexdeb, indexfin;
1120   Standard_Integer i21, i22;
1121   Standard_Real AA, BB, CC, Fi, FX, FY, FZ, AIJ;
1122   MaxE3d = MaxE2d = 0.0;
1123   F = 0.0;
1124   i2 = 1;
1125   math_Vector Px(1, nbpoles), Py(1, nbpoles), Pz(1, nbpoles);
1126 
1127   for (k = 1 ; k <= nbP+nbP2d; k++) {
1128     i21 = i2+1; i22 = i2+2;
1129     for (i = 1; i <= nbpoles; i++) {
1130       Px(i) = mypoles(i, i2);
1131       Py(i) = mypoles(i, i21);
1132       if (k <= nbP) Pz(i) = mypoles(i, i22);
1133     }
1134     for (i = FirstP; i <= LastP; i++) {
1135       AA = 0.0; BB = 0.0; CC = 0.0;
1136       indexdeb = myindex(i) + 1;
1137       indexfin = indexdeb + deg;
1138       for (j = indexdeb; j <= indexfin; j++) {
1139         AIJ = A(i, j);
1140         AA += AIJ*Px(j);
1141         BB += AIJ*Py(j);
1142         if (k <= nbP) CC += AIJ*Pz(j);
1143       }
1144       FX = AA-mypoints(i, i2);
1145       FY = BB-mypoints(i, i21);
1146       Fi= FX*FX + FY*FY;
1147       if (k <= nbP) {
1148         FZ = CC-mypoints(i, i22);
1149         Fi += FZ*FZ;
1150         if (Fi > MaxE3d) MaxE3d = Fi;
1151       }
1152       else {
1153         if (Fi > MaxE2d) MaxE2d = Fi;
1154       }
1155       theError(i, k) = Fi;
1156       F += Fi;
1157     }
1158     if (k <= nbP) i2 += 3;
1159     else i2 += 2;
1160   }
1161   MaxE3d = Sqrt(MaxE3d);
1162   MaxE2d = Sqrt(MaxE2d);
1163 }
1164 
1165 
1166 void AppParCurves_LeastSquare::ErrorGradient(math_Vector& Grad, 
1167                                              Standard_Real& F, 
1168                                              Standard_Real& MaxE3d,
1169                                              Standard_Real& MaxE2d)
1170 {
1171   if (!done) {throw StdFail_NotDone();}
1172   Standard_Integer i, j, k, i2, indexdeb, indexfin;
1173   Standard_Real AA, BB, CC, Fi, FX, FY, FZ, AIJ;
1174 //  Standard_Real DAIJ, DAA, DBB, DCC, Gr, gr1= 0.0, gr2= 0.0;
1175   Standard_Real DAIJ, DAA, DBB, DCC, Gr;
1176   MaxE3d = MaxE2d = 0.0;
1177 //  Standard_Integer i21, i22, diff = (deg-1);
1178   Standard_Integer i21, i22;
1179   F = 0.0;
1180   i2 = 1;
1181   math_Vector Px(1, nbpoles), Py(1, nbpoles), Pz(1, nbpoles);
1182 
1183   for (k = Grad.Lower(); k <= Grad.Upper(); k++) Grad(k) = 0.0;
1184 
1185   for (k = 1 ; k <= nbP+nbP2d; k++) {
1186     i21 = i2+1; i22 = i2+2;
1187     for (i = 1; i <= nbpoles; i++) {
1188       Px(i) = mypoles(i, i2);
1189       Py(i) = mypoles(i, i21);
1190       if (k <= nbP) Pz(i) = mypoles(i, i22);
1191     }
1192     for (i = FirstP; i <= LastP; i++) {
1193       AA = 0.0; BB = 0.0; CC = 0.0; DAA = 0.0; DBB = 0.0; DCC = 0.0;
1194       indexdeb = myindex(i) + 1;
1195       indexfin = indexdeb + deg;
1196       for (j = indexdeb; j <= indexfin; j++) {
1197         AIJ = A(i, j); DAIJ = DA(i, j);
1198         AA += AIJ*Px(j); DAA += DAIJ*Px(j);
1199         BB += AIJ*Py(j); DBB += DAIJ*Py(j);
1200         if (k <= nbP) {
1201           CC += AIJ*Pz(j);
1202           DCC += DAIJ*Pz(j);
1203         }
1204       }
1205       FX = AA-mypoints(i, i2);
1206       FY = BB-mypoints(i, i2+1);
1207       Fi = FX*FX + FY*FY;
1208       Gr = 2.0*(DAA*FX + DBB*FY);
1209 
1210       if (k <= nbP) {
1211         FZ = CC-mypoints(i, i2+2);
1212         Fi += FZ*FZ;
1213         Gr += 2.0*DCC*FZ;
1214         if (Fi > MaxE3d) MaxE3d = Fi;
1215       }
1216       else {
1217         if (Fi > MaxE2d) MaxE2d = Fi;
1218       }
1219       theError(i, k) = Fi;
1220       Grad(i) += Gr;
1221       F += Fi;
1222     }
1223     if (k <= nbP) i2 += 3;
1224     else i2 += 2;
1225   }
1226   MaxE3d = Sqrt(MaxE3d);
1227   MaxE2d = Sqrt(MaxE2d);
1228 
1229 }
1230 
1231 
1232 const math_Matrix& AppParCurves_LeastSquare::Distance()
1233 {
1234   if (!iscalculated) {
1235     for (Standard_Integer i = myfirstp; i <= mylastp; i++) {
1236       for (Standard_Integer  j = 1; j <= nbP+nbP2d; j++) {
1237         theError(i, j) = Sqrt(theError(i, j));
1238       }
1239     }
1240     iscalculated = Standard_True;
1241   }
1242   return theError;
1243 }
1244 
1245 
1246 Standard_Real AppParCurves_LeastSquare::FirstLambda() const
1247 {
1248   return lambda1;
1249 }
1250 
1251 Standard_Real AppParCurves_LeastSquare::LastLambda() const
1252 {
1253   return lambda2;
1254 }
1255 
1256 
1257 
1258 Standard_Boolean AppParCurves_LeastSquare::IsDone() const
1259 {
1260   return done;
1261 }
1262 
1263 
1264 AppParCurves_MultiCurve AppParCurves_LeastSquare::BezierValue() 
1265 {
1266   if (!myknots.IsNull()) throw Standard_NoSuchObject();
1267   return (AppParCurves_MultiCurve)(BSplineValue());
1268 }
1269 
1270 
1271 const AppParCurves_MultiBSpCurve& AppParCurves_LeastSquare::BSplineValue() 
1272 {
1273   if (!done) {throw StdFail_NotDone();}
1274 
1275   Standard_Integer i, j, j2, npoints = nbP+nbP2d;
1276   gp_Pnt Pt;
1277   gp_Pnt2d Pt2d;
1278   Standard_Integer ideb = resinit, ifin = resfin;
1279   if (ideb >= 2) ideb = 2;
1280   if (ifin <= nbpoles-1) ifin = nbpoles-1;
1281 
1282   // On met le resultat dans les curves correspondantes
1283   for (i = ideb; i <= ifin; i++) {
1284     j2 = 1;
1285     AppParCurves_MultiPoint MPole(nbP, nbP2d);
1286     for (j = 1; j <= nbP; j++) {
1287       Pt.SetCoord(mypoles(i, j2), mypoles(i, j2+1), mypoles(i,j2+2));
1288       MPole.SetPoint(j, Pt);
1289       j2 += 3;
1290     }
1291     for (j = nbP+1;j <= npoints; j++) {
1292       Pt2d.SetCoord(mypoles(i, j2), mypoles(i, j2+1));
1293       MPole.SetPoint2d(j, Pt2d);
1294       j2 += 2;
1295     }
1296     SCU.SetValue(i, MPole);
1297   }
1298   return SCU;
1299 }
1300 
1301 
1302 
1303 const math_Matrix& AppParCurves_LeastSquare::FunctionMatrix() const
1304 {
1305   if (!done) {throw StdFail_NotDone();}
1306   return A;
1307 }
1308 
1309 
1310 const math_Matrix& AppParCurves_LeastSquare::DerivativeFunctionMatrix() const
1311 {
1312   if (!done) {throw StdFail_NotDone();}
1313   return DA;
1314 }
1315 
1316 
1317 
1318 
1319 Standard_Integer AppParCurves_LeastSquare::
1320                  TheFirstPoint(const AppParCurves_Constraint FirstCons, 
1321                                const Standard_Integer        FirstPoint) const
1322 {
1323   if (FirstCons == AppParCurves_NoConstraint) 
1324     return FirstPoint;
1325   else 
1326     return FirstPoint + 1;
1327 }
1328 
1329 
1330 
1331 Standard_Integer AppParCurves_LeastSquare::
1332                  TheLastPoint(const AppParCurves_Constraint LastCons,
1333                               const Standard_Integer LastPoint) const
1334 {
1335   if (LastCons == AppParCurves_NoConstraint)
1336     return LastPoint;
1337   else 
1338     return LastPoint - 1;
1339 }
1340 
1341 
1342 void AppParCurves_LeastSquare::ComputeFunction(const math_Vector& Parameters) 
1343 {
1344   if (myknots.IsNull()) {
1345     AppParCurves::Bernstein(nbpoles, Parameters, A, DA);  
1346   }
1347   else {
1348     AppParCurves::SplineFunction(nbpoles, deg, Parameters,
1349                                  Vflatknots, A, DA, myindex);
1350   }
1351 }
1352 
1353 
1354 
1355 const math_Matrix& AppParCurves_LeastSquare::Points() const
1356 {
1357   return mypoints;
1358 }
1359 
1360 const math_Matrix& AppParCurves_LeastSquare::Poles() const
1361 {
1362   return mypoles;
1363 }
1364 
1365 
1366 
1367 const math_IntegerVector& AppParCurves_LeastSquare::KIndex() const
1368 {
1369   return myindex;
1370 }
1371 
1372 
1373 
1374 
1375 void AppParCurves_LeastSquare::MakeTAA(math_Vector& TheA,
1376                                        math_Vector& myTAB)
1377 {
1378   Standard_Integer i, j, k, Ci, i2, i21, i22;
1379   Standard_Real xx = 0.0, yy = 0.0;
1380 
1381   Standard_Integer Nincx = resfin-resinit+1;
1382   Standard_Integer Nrow, Neq = LastP-FirstP+1;
1383 
1384   Standard_Integer Ninc1;
1385 
1386   if (FirstConstraint >= AppParCurves_TangencyPoint &&
1387       LastConstraint >= AppParCurves_TangencyPoint)  {
1388     Ninc1 = Ninc-1;
1389   }
1390   else Ninc1 = Ninc;
1391 
1392   Standard_Integer myfirst = A.LowerRow();
1393   Standard_Integer ix, iy, iz;
1394   Standard_Integer mylast = myfirst+Nlignes-1;
1395   Standard_Integer k1;
1396   Standard_Real taf1 = 0.0, taf2 = 0.0, taf3 = 0.0, 
1397   tab1 = 0.0, tab2 = 0.0;
1398   Standard_Integer nb, inc, jinit, jfin, u;
1399   Standard_Integer indexdeb, indexfin;
1400   Standard_Integer NA1 = NA-1;
1401   Standard_Real v1=0, v2=0, b;
1402   Standard_Real Ai2, Aid, Akj;
1403   math_Vector  myB(myfirst, mylast, 0.0),
1404                myV1(myfirst, mylast, 0.0), 
1405                myV2(myfirst, mylast, 0.0);
1406   math_Vector TheV1(1, Ninc, 0.0), TheV2(1, Ninc, 0.0);
1407 
1408 
1409   for (i = FirstP; i <= LastP; i++) {
1410     Ai2 = A(i, 2);
1411     Aid = A(i, nbpoles-1);
1412     if (FirstConstraint >= AppParCurves_PassPoint) xx = A(i, 1);
1413     if (FirstConstraint >= AppParCurves_TangencyPoint) xx += Ai2;
1414     if (LastConstraint >= AppParCurves_PassPoint) yy = A(i, nbpoles);
1415     if (LastConstraint >= AppParCurves_TangencyPoint) yy += Aid;
1416     i2 = 1;
1417     Nrow = myfirst-FirstP;
1418     for (Ci = 1; Ci <= nbP; Ci++) {
1419       i21 = i2+1; i22 = i2+2;
1420       ix = i+Nrow; iy = ix+Neq; iz = iy+Neq;
1421       if (FirstConstraint >= AppParCurves_TangencyPoint) {
1422         myV1(ix) =  Ai2*Vec1t(i2);
1423         myV1(iy) =  Ai2*Vec1t(i21);
1424         myV1(iz) =  Ai2*Vec1t(i22);
1425       }
1426       if (LastConstraint >= AppParCurves_TangencyPoint) {
1427         myV2(ix) = -Aid*Vec2t(i2);
1428         myV2(iy) = -Aid*Vec2t(i21);
1429         myV2(iz) = -Aid*Vec2t(i22);
1430       }
1431       myB(ix)  = mypoints(i, i2)  - xx*mypoints(myfirstp, i2) 
1432                                   - yy*mypoints(mylastp,  i2);
1433       myB(iy)  = mypoints(i, i21) - xx*mypoints(myfirstp, i21) 
1434                                   - yy*mypoints(mylastp,  i21);
1435       myB(iz)  = mypoints(i, i22) - xx*mypoints(myfirstp, i22) 
1436                                   - yy*mypoints(mylastp,  i22);
1437       i2 += 3;
1438       Nrow = Nrow + 3*Neq;
1439     }   
1440     
1441     for (Ci = 1; Ci <= nbP2d; Ci++) {
1442       i21 = i2+1; i22 = i2+2;
1443       ix = i+Nrow; iy = ix+Neq;
1444       if (FirstConstraint >= AppParCurves_TangencyPoint) {
1445         myV1(ix) =  Ai2*Vec1t(i2);
1446         myV1(iy) =  Ai2*Vec1t(i21);
1447       }
1448       if (LastConstraint >= AppParCurves_TangencyPoint) {
1449         myV2(ix) = -Aid*Vec2t(i2);
1450         myV2(iy) = -Aid*Vec2t(i21);
1451       }
1452       myB(ix)  = mypoints(i, i2)  - xx*mypoints(myfirstp, i2) 
1453                                   - yy*mypoints(mylastp,  i2);
1454       myB(iy)  = mypoints(i, i21) - xx*mypoints(myfirstp, i21) 
1455                                   - yy*mypoints(mylastp,  i21);
1456       Nrow = Nrow + 2*Neq;
1457       i2 += 2;
1458     }
1459   } 
1460   
1461   
1462   
1463   // Construction de TA*A et TA*B:
1464   
1465   for (k = FirstP; k <= LastP; k++) {
1466     indexdeb = myindex(k)+1;
1467     indexfin = indexdeb + deg; 
1468     jinit = Max(resinit, indexdeb);
1469     jfin = Min(resfin, indexfin);
1470     k1 = k + myfirst - FirstP;
1471     for (i = 0; i <= NA1; i++) {
1472       nb = i*Neq + k1;
1473       if (FirstConstraint >= AppParCurves_TangencyPoint)
1474         v1 = myV1(nb); 
1475       if (LastConstraint >= AppParCurves_TangencyPoint)
1476         v2 = myV2(nb); 
1477       b = myB(nb);
1478       inc = i*Nincx-resinit+1;
1479       for (j = jinit; j <= jfin; j++) {
1480         Akj = A(k, j);
1481         u = j+inc;
1482         if (FirstConstraint >= AppParCurves_TangencyPoint)
1483           TheV1(u) += Akj*v1;
1484         if (LastConstraint >= AppParCurves_TangencyPoint)
1485           TheV2(u) += Akj*v2;
1486         myTAB(u) += Akj*b;
1487       }
1488       if (FirstConstraint >= AppParCurves_TangencyPoint) {
1489         taf1 += v1*v1; 
1490         tab1 += v1*b;
1491       }
1492       if (LastConstraint >= AppParCurves_TangencyPoint) {
1493         taf2 += v2*v2;
1494         tab2 += v2*b;
1495       }
1496       if (FirstConstraint >= AppParCurves_TangencyPoint && 
1497           LastConstraint >= AppParCurves_TangencyPoint) {
1498         taf3 += v1*v2;
1499       }
1500     }
1501   }
1502   
1503 
1504   if (FirstConstraint >= AppParCurves_TangencyPoint) {
1505     TheV1(Ninc1) = taf1;
1506     myTAB(Ninc1) = tab1;
1507   }
1508   if (LastConstraint >= AppParCurves_TangencyPoint) {
1509     TheV2(Ninc)  = taf2;
1510     myTAB(Ninc)  = tab2;
1511   }
1512   if (FirstConstraint >= AppParCurves_TangencyPoint && 
1513       LastConstraint >= AppParCurves_TangencyPoint) {
1514     TheV2(Ninc1) = taf3;
1515   }
1516 
1517   
1518   if (resinit <= resfin) {
1519     math_IntegerVector Index(1, Nincx);
1520     SearchIndex(Index);
1521     math_Vector AA(1, Index(Nincx));
1522     MakeTAA(AA);
1523     
1524     Standard_Integer kk = 1;
1525     for (k = 1; k <= NA; k++)   {
1526       for(i = 1; i <= AA.Length(); i++) {
1527         TheA(kk) = AA(i);
1528         kk++;
1529       }
1530     }
1531   }
1532   
1533   Standard_Integer length = TheA.Length();
1534   
1535   if (FirstConstraint >= AppParCurves_TangencyPoint && 
1536       LastConstraint >= AppParCurves_TangencyPoint) {
1537     for (j = 1; j <= Ninc1; j++) 
1538       TheA(length- 2*Ninc+j+1) = TheV1(j);
1539     for (j = 1; j <= Ninc; j++) 
1540       TheA(length- Ninc+j) = TheV2(j);
1541   }
1542 
1543 
1544   else if (FirstConstraint >= AppParCurves_TangencyPoint) {
1545     for (j = 1; j <= Ninc; j++) 
1546       TheA(length- Ninc+j) = TheV1(j);
1547   }
1548 
1549   else if (LastConstraint >= AppParCurves_TangencyPoint) {
1550     for (j = 1; j <= Ninc; j++) 
1551       TheA(length- Ninc+j) = TheV2(j);
1552   }
1553 }
1554 
1555 
1556 
1557 
1558 void AppParCurves_LeastSquare::MakeTAA(math_Vector& AA,
1559                                        math_Matrix& myTAB)
1560 {
1561   Standard_Integer i, j, k;
1562   Standard_Integer indexdeb, indexfin, jinit, jfin;
1563   Standard_Integer iinit, ifin;
1564   Standard_Real Akj;
1565   math_Matrix TheA(resinit, resfin, resinit, resfin);
1566   TheA.Init(0.0);
1567 
1568   for (k = FirstP ; k <= LastP; k++) {
1569     indexdeb = myindex(k)+1;
1570     indexfin = indexdeb + deg;
1571     jinit = Max(resinit, indexdeb);
1572     jfin = Min(resfin, indexfin);
1573     for (i = jinit; i <= jfin; i++) {
1574       Akj = A(k, i);
1575       for (j = jinit; j <= i; j++) {
1576         TheA(i, j) += A(k, j) * Akj;
1577       }
1578       for (j = 1; j <= B2.ColNumber(); j++) {
1579         myTAB(i, j) += Akj*B2(k, j);
1580       }
1581     }
1582   }
1583 
1584   Standard_Integer len;
1585   if (!myknots.IsNull()) len = myknots->Length();
1586   else len = 2;
1587   Standard_Integer d, i2 = 1;
1588   iinit = resinit;
1589   jinit = resinit;
1590   ifin = Min(resfin, deg+1);
1591   for (k = 2; k <= len; k++) {
1592     for (i = iinit; i <= ifin; i++) {
1593       for (j = jinit; j <= i; j++) {
1594         AA(i2) = TheA(i, j);
1595         i2++;
1596       }
1597     }
1598     if (!mymults.IsNull()) {
1599       iinit = ifin+1;
1600       d = ifin + mymults->Value(k);
1601       ifin = Min(d, resfin);
1602       jinit = Max(resinit, d - deg);
1603     }
1604   }
1605 }
1606 
1607 
1608 void AppParCurves_LeastSquare::MakeTAA(math_Vector& AA)
1609 {
1610   Standard_Integer i, j, k;
1611   Standard_Integer indexdeb, indexfin, jinit, jfin;
1612   Standard_Integer iinit, ifin;
1613   Standard_Real Akj;
1614   math_Matrix TheA(resinit, resfin, resinit, resfin, 0.0);
1615 
1616 
1617   for (k = FirstP ; k <= LastP; k++) {
1618     indexdeb = myindex(k)+1;
1619     indexfin = indexdeb + deg;
1620     jinit = Max(resinit, indexdeb);
1621     jfin = Min(resfin, indexfin);
1622     for (i = jinit; i <= jfin; i++) {
1623       Akj = A(k, i);
1624       for (j = jinit; j <= i; j++) {
1625         TheA(i, j) += A(k, j) * Akj;
1626       }
1627     }
1628   }
1629 
1630   
1631   Standard_Integer i2 = 1;
1632   iinit = resinit;
1633   jinit = resinit;
1634   ifin = Min(resfin, deg+1);
1635   Standard_Integer len, d;
1636   if (!myknots.IsNull()) len = myknots->Length();
1637   else len = 2;
1638   for (k = 2; k <= len; k++) {
1639     for (i = iinit; i <= ifin; i++) {
1640       for (j = jinit; j <= i; j++) {
1641         AA(i2) = TheA(i, j);
1642         i2++;
1643       }
1644     }
1645     if (!mymults.IsNull()) {
1646       iinit = ifin+1;
1647       d = ifin + mymults->Value(k);
1648       ifin = Min(d, resfin);
1649       jinit = Max(resinit, d - deg);
1650     }
1651   }
1652   
1653 }
1654 
1655 
1656 
1657 void AppParCurves_LeastSquare::SearchIndex(math_IntegerVector& Index)
1658 {
1659   Standard_Integer iinit, jinit, ifin;
1660   Standard_Integer i, j, k, d, i2 = 1;
1661   Standard_Integer len;
1662   Standard_Integer Nincx = resfin-resinit+1;
1663   Index(1) = 1;
1664 
1665   if (myknots.IsNull()) {
1666     if (resinit <= resfin) {
1667       Standard_Integer l = 1;
1668       for (i = 2; i <= Nincx; i++) {
1669         l++;
1670         Index(l) = Index(l-1)+i;
1671       }
1672     }
1673     
1674   }
1675   else {
1676     iinit = resinit;
1677     jinit = resinit;
1678     ifin = Min(resfin, deg+1);
1679     len = myknots->Length();
1680     
1681     for (k = 2; k <= len; k++) {
1682       for (i = iinit; i <= ifin; i++) {
1683         for (j = jinit; j <= i; j++) {
1684           if (i2 != 1) 
1685             Index(i2) = Index(i2-1) + i-jinit+1;
1686         }
1687         i2++;
1688       }
1689       iinit = ifin+1;
1690       d = ifin + mymults->Value(k);
1691       ifin = Min(d, resfin);
1692       jinit = Max(resinit, d - deg);
1693     }
1694   }
1695 }