0024428: Implementation of LGPL license
[occt.git] / src / Approx / Approx_ComputeLine.gxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and / or modify it
7 // under the terms of the GNU Lesser General Public version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <Approx_ParametrizationType.hxx>
16 #include Approx_ParLeastSquareOfMyGradient_hxx
17 #include <TColStd_Array1OfReal.hxx>
18 #include <TColgp_Array1OfPnt.hxx>
19 #include <TColgp_Array1OfPnt2d.hxx>
20 #include <gp_Pnt.hxx>
21 #include <gp_Pnt2d.hxx>
22 #include <gp_Vec.hxx>
23 #include <gp_Vec2d.hxx>
24 #include <TColgp_Array1OfVec.hxx>
25 #include <TColgp_Array1OfVec2d.hxx>
26 #include <AppParCurves_Constraint.hxx>
27 #include <AppParCurves_HArray1OfConstraintCouple.hxx>
28 #include <AppParCurves_MultiPoint.hxx>
29 #include <Precision.hxx>
30 #include <math_IntegerVector.hxx>
31 #include <math_Gauss.hxx>
32 #include <math_Uzawa.hxx>
33 #include <Approx_MCurvesToBSpCurve.hxx>
34 #include <AppParCurves_ConstraintCouple.hxx>
35
36 #include <stdio.h>
37
38 #ifdef DEB
39 static Standard_Boolean mydebug = Standard_False;
40
41 #include <Geom_BezierCurve.hxx>
42 #include <Geom2d_BezierCurve.hxx>
43 #ifdef DRAW
44 #include <DrawTrSurf.hxx>
45 #include <Draw.hxx>
46 #include <Draw_Appli.hxx>
47 #endif
48 static void DUMP(const MultiLine& Line)
49 {
50   Standard_Integer i, j, nbP2d, nbP3d, firstP, lastP;
51   gp_Pnt P1;
52   gp_Pnt2d P12d;
53
54   firstP = LineTool::FirstPoint(Line);
55   lastP  = LineTool::LastPoint(Line);
56
57   nbP3d = LineTool::NbP3d(Line);
58   nbP2d = LineTool::NbP2d(Line);
59   Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
60   if (nbP3d == 0) mynbP3d = 1;
61   if (nbP2d == 0) mynbP2d = 1;
62   
63   TColgp_Array1OfPnt tabP(1, mynbP3d);
64   TColgp_Array1OfPnt2d tabP2d(1, mynbP2d);
65   
66   cout <<"DUMP de la MultiLine entre "<<firstP <<" et "<<lastP<<": "<<endl;
67   for (i = firstP; i <= lastP; i++) {
68     if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i, tabP, tabP2d);
69     else if (nbP2d != 0)          LineTool::Value(Line, i, tabP2d);
70     else if (nbP3d != 0)          LineTool::Value(Line, i, tabP);
71     
72     cout << "point "<<i<<":"<< endl;
73     for (j = 1; j <= nbP3d; j++) {
74       P1 = tabP(j);
75       cout <<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl;
76     }
77     for (j = 1; j <= nbP2d; j++) {
78       P12d = tabP2d(j);
79       cout <<P12d.X()<<" "<<P12d.Y()<<endl;
80     }
81   }
82
83 }
84
85
86 static void DUMP(const AppParCurves_MultiCurve& C) {
87   static Standard_Integer nbappel = 0;
88   Standard_Integer i;
89   Standard_Integer nbpoles = C.NbPoles();
90
91   Handle(Geom_BezierCurve) BSp;
92   Handle(Geom2d_BezierCurve) BSp2d;
93
94   TColgp_Array1OfPnt tabPoles(1, nbpoles);
95   TColgp_Array1OfPnt2d tabPoles2d(1, nbpoles);
96   char solname[100];
97
98   nbappel++;
99   for (i = 1; i <= C.NbCurves(); i++) {
100     if (C.Dimension(i) == 3) {
101       C.Curve(i, tabPoles);
102       BSp = new Geom_BezierCurve(tabPoles);
103       sprintf(solname, "%s%i%s_%i", "c", i, "3d", nbappel);
104 #ifdef DRAW
105       char* Temp = solname;
106       DrawTrSurf::Set(Temp, BSp);
107 //      DrawTrSurf::Set(solname, BSp);
108 #endif
109     }
110     else {
111       C.Curve(i, tabPoles2d);
112       BSp2d = new Geom2d_BezierCurve(tabPoles2d);
113       sprintf(solname, "%s%i%s_%i", "c", i, "2d", nbappel);
114 #ifdef DRAW
115       char* Temp = solname;
116       DrawTrSurf::Set(Temp, BSp2d);
117 //      DrawTrSurf::Set(solname, BSp2d);
118 #endif
119     }
120   }
121 #ifdef DRAW
122   dout.Flush();
123 #endif
124 }
125
126
127 #endif
128
129 void Approx_ComputeLine::FirstTangencyVector(const MultiLine&       Line,
130                                              const Standard_Integer index,
131                                              math_Vector&           V) const 
132 {
133
134   Standard_Integer i, j, nbP2d, nbP3d;
135   nbP3d = LineTool::NbP3d(Line);
136   nbP2d = LineTool::NbP2d(Line);
137   Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
138   if (nbP3d == 0) mynbP3d = 1;
139   if (nbP2d == 0) mynbP2d = 1;
140   Standard_Boolean Ok=Standard_False;
141   TColgp_Array1OfVec TabV(1, mynbP3d);
142   TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
143  
144   if (nbP3d != 0 && nbP2d != 0)
145     Ok = LineTool::Tangency(Line, index, TabV, TabV2d);
146   else if (nbP2d != 0)
147     Ok = LineTool::Tangency(Line, index, TabV2d);
148   else if (nbP3d != 0)
149     Ok = LineTool::Tangency(Line, index, TabV);
150
151   if (Ok) {
152     if (nbP3d != 0) {
153       j = 1;
154       for (i = TabV.Lower(); i <= TabV.Upper(); i++) {
155         V(j)   = TabV(i).X();
156         V(j+1) = TabV(i).Y();
157         V(j+2) = TabV(i).Z();
158         j += 3;
159       }
160     }
161     if (nbP2d != 0) {
162       j = nbP3d*3+1;
163       for (i = TabV2d.Lower(); i <= TabV2d.Upper(); i++) {
164         V(j)   = TabV2d(i).X();
165         V(j+1) = TabV2d(i).Y();
166         j += 2;
167       }
168     }
169   }
170   else {
171
172     // recherche d un vecteur tangent par construction d une parabole:
173     AppParCurves_Constraint firstC, lastC;
174     firstC = lastC = AppParCurves_PassPoint;
175     Standard_Integer nbpoles = 3;
176     math_Vector mypar(index, index+2);
177     Parameters(Line, index, index+2, mypar);
178     Approx_ParLeastSquareOfMyGradient 
179       LSQ(Line, index, index+2, firstC, lastC, mypar, nbpoles);
180     AppParCurves_MultiCurve C = LSQ.BezierValue();
181     
182     gp_Pnt myP;
183     gp_Vec myV;
184     gp_Pnt2d myP2d;
185     gp_Vec2d myV2d;
186     j = 1;
187     for (i = 1; i <= nbP3d; i++) {
188       C.D1(i, 0.0, myP, myV);
189       V(j)   = myV.X();
190       V(j+1) = myV.Y();
191       V(j+2) = myV.Z();
192       j += 3;
193     }
194     j = nbP3d*3+1;
195     for (i = nbP3d+1; i <= nbP3d+nbP2d; i++) {
196       C.D1(i, 0.0, myP2d, myV2d);
197       V(j)   = myV2d.X();
198       V(j+1) = myV2d.Y();
199       j += 2;
200     }
201   }
202 }
203
204
205 void Approx_ComputeLine::LastTangencyVector(const MultiLine&       Line,
206                                             const Standard_Integer index,
207                                             math_Vector&           V) const
208 {
209   Standard_Integer i, j, nbP2d, nbP3d;
210   nbP3d = LineTool::NbP3d(Line);
211   nbP2d = LineTool::NbP2d(Line);
212   Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
213   if (nbP3d == 0) mynbP3d = 1;
214   if (nbP2d == 0) mynbP2d = 1;
215   Standard_Boolean Ok=Standard_False;
216   TColgp_Array1OfVec TabV(1, mynbP3d);
217   TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
218
219  
220   if (nbP3d != 0 && nbP2d != 0)
221     Ok = LineTool::Tangency(Line, index, TabV, TabV2d);
222   else if (nbP2d != 0)
223     Ok = LineTool::Tangency(Line, index, TabV2d);
224   else if (nbP3d != 0)
225     Ok = LineTool::Tangency(Line, index, TabV);
226
227   if (Ok) {
228     if (nbP3d != 0) {
229       j = 1;
230       for (i = TabV.Lower(); i <= TabV.Upper(); i++) {
231         V(j)   = TabV(i).X();
232         V(j+1) = TabV(i).Y();
233         V(j+2) = TabV(i).Z();
234         j += 3;
235       }
236     }
237     if (nbP2d != 0) {
238       j = nbP3d*3+1;
239       for (i = TabV2d.Lower(); i <= TabV2d.Upper(); i++) {
240         V(j)   = TabV2d(i).X();
241         V(j+1) = TabV2d(i).Y();
242         j += 2;
243       }
244     }
245   }
246   else {
247
248     // recherche d un vecteur tangent par construction d une parabole:
249     AppParCurves_Constraint firstC, lastC;
250     firstC = lastC = AppParCurves_PassPoint;
251     Standard_Integer nbpoles = 3;
252     math_Vector mypar(index-2, index);
253     Parameters(Line, index-2, index, mypar);
254     Approx_ParLeastSquareOfMyGradient 
255       LSQ(Line, index-2, index, firstC, lastC, mypar, nbpoles);
256     AppParCurves_MultiCurve C = LSQ.BezierValue();
257     
258     gp_Pnt myP;
259     gp_Vec myV;
260     gp_Pnt2d myP2d;
261     gp_Vec2d myV2d;
262     j = 1;
263     for (i = 1; i <= nbP3d; i++) {
264       C.D1(i, 1.0, myP, myV);
265       V(j)   = myV.X();
266       V(j+1) = myV.Y();
267       V(j+2) = myV.Z();
268       j += 3;
269     }
270     j = nbP3d*3+1;
271     for (i = nbP3d+1; i <= nbP3d+nbP2d; i++) {
272       C.D1(i, 1.0, myP2d, myV2d);
273       V(j)   = myV2d.X();
274       V(j+1) = myV2d.Y();
275       j += 2;
276     }
277   }
278
279 }
280
281
282
283 Standard_Real Approx_ComputeLine::
284   SearchFirstLambda(const MultiLine&            Line, 
285                     const math_Vector&          TheParam,
286                     const math_Vector&          V,
287                     const Standard_Integer      index) const 
288 {
289
290   // dq/dw = lambda* V = (p2-p1)/(u2-u1)
291   
292   Standard_Integer nbP2d, nbP3d;
293   gp_Pnt P1, P2;
294   gp_Pnt2d P12d, P22d;
295   nbP3d = LineTool::NbP3d(Line);
296   nbP2d = LineTool::NbP2d(Line);
297   Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
298   if (nbP3d == 0) mynbP3d = 1;
299   if (nbP2d == 0) mynbP2d = 1;
300   TColgp_Array1OfPnt tabP1(1, mynbP3d), tabP2(1, mynbP3d);
301   TColgp_Array1OfPnt2d tabP12d(1, mynbP2d), tabP22d(1, mynbP2d);
302  
303
304   if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index, tabP1, tabP12d);
305   else if (nbP2d != 0)          LineTool::Value(Line, index, tabP12d);
306   else if (nbP3d != 0)          LineTool::Value(Line, index, tabP1);
307
308   if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index+1, tabP2, tabP22d);
309   else if (nbP2d != 0)          LineTool::Value(Line, index+1, tabP22d);
310   else if (nbP3d != 0)          LineTool::Value(Line, index+1, tabP2);
311                                      
312
313   Standard_Real U1 = TheParam(index), U2 = TheParam(index+1);
314   Standard_Real lambda, S;                                        
315   Standard_Integer low = V.Lower();
316  
317   if (nbP3d != 0) {
318     P1 = tabP1(1);
319     P2 = tabP2(1);
320     gp_Vec P1P2(P1, P2), myV;
321     myV.SetCoord(V(low), V(low+1), V(low+2));
322     lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1));
323     S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0;
324   }
325   else {
326     P12d = tabP12d(1);
327     P22d = tabP22d(1);
328     gp_Vec2d P1P2(P12d, P22d), myV;
329     myV.SetCoord(V(low), V(low+1));
330     lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1));
331     S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0;
332   }
333   return (S*lambda);
334
335 }
336
337
338 Standard_Real Approx_ComputeLine::
339  SearchLastLambda(const MultiLine&            Line, 
340                   const math_Vector&          TheParam,
341                   const math_Vector&          V,
342                   const Standard_Integer      index) const
343 {
344   // dq/dw = lambda* V = (p2-p1)/(u2-u1)
345   
346   Standard_Integer nbP2d, nbP3d;
347   gp_Pnt P1, P2;
348   gp_Pnt2d P12d, P22d;
349   nbP3d = LineTool::NbP3d(Line);
350   nbP2d = LineTool::NbP2d(Line);
351   Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
352   if (nbP3d == 0) mynbP3d = 1;
353   if (nbP2d == 0) mynbP2d = 1;
354   TColgp_Array1OfPnt tabP(1, mynbP3d), tabP2(1, mynbP3d);
355   TColgp_Array1OfPnt2d tabP2d(1, mynbP2d), tabP22d(1, mynbP2d);
356  
357   if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index-1, tabP, tabP2d);
358   else if (nbP2d != 0)          LineTool::Value(Line, index-1, tabP2d);
359   else if (nbP3d != 0)          LineTool::Value(Line, index-1, tabP);
360
361   if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index, tabP2, tabP22d);
362   else if (nbP2d != 0)          LineTool::Value(Line, index, tabP22d);
363   else if (nbP3d != 0)          LineTool::Value(Line, index, tabP2);
364
365
366   Standard_Real U1 = TheParam(index-1), U2 = TheParam(index);
367   Standard_Real lambda, S;
368   Standard_Integer low = V.Lower();
369
370   if (nbP3d != 0) {
371     P1 = tabP(1);
372     P2 = tabP2(1);
373     gp_Vec P1P2(P1, P2), myV;
374     myV.SetCoord(V(low), V(low+1), V(low+2));
375     lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1));
376     S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0;
377   }
378   else {
379     P12d = tabP2d(1);
380     P22d = tabP22d(1);
381     gp_Vec2d P1P2(P12d, P22d), myV;
382     myV.SetCoord(V(low), V(low+1));
383     lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1));
384     S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0;
385   }
386
387   return (S*lambda);
388 }
389
390
391
392 Approx_ComputeLine::Approx_ComputeLine
393                     (const MultiLine& Line,
394                      const math_Vector& Parameters,
395                      const Standard_Integer degreemin,
396                      const Standard_Integer degreemax,
397                      const Standard_Real Tolerance3d,
398                      const Standard_Real Tolerance2d,
399                      const Standard_Integer NbIterations,
400                      const Standard_Boolean cutting,
401                      const Standard_Boolean Squares)
402 : myMultiLineNb (0),
403   myIsClear (Standard_False)
404 {
405   myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(), 
406                                            Parameters.Upper());
407   for (Standard_Integer i = Parameters.Lower(); i <= Parameters.Upper(); i++) {
408     myfirstParam->SetValue(i, Parameters(i));
409   }
410   myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
411   Par = Approx_IsoParametric;
412   mydegremin = degreemin;
413   mydegremax = degreemax;
414   mytol3d = Tolerance3d;
415   mytol2d = Tolerance2d;
416   mysquares = Squares;
417   mycut = cutting;
418   myitermax = NbIterations;
419   alldone = Standard_False;
420   myfirstC = AppParCurves_TangencyPoint;
421   mylastC = AppParCurves_TangencyPoint;
422   Perform(Line);
423 }
424
425
426 Approx_ComputeLine::Approx_ComputeLine
427                     (const math_Vector& Parameters,
428                      const Standard_Integer degreemin,
429                      const Standard_Integer degreemax,
430                      const Standard_Real Tolerance3d,
431                      const Standard_Real Tolerance2d,
432                      const Standard_Integer NbIterations,
433                      const Standard_Boolean cutting,
434                      const Standard_Boolean Squares)
435 : myMultiLineNb (0),
436   myIsClear (Standard_False)
437 {
438   myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(), 
439                                            Parameters.Upper());
440   for (Standard_Integer i = Parameters.Lower(); i <= Parameters.Upper(); i++) {
441     myfirstParam->SetValue(i, Parameters(i));
442   }
443   myfirstC = AppParCurves_TangencyPoint;
444   mylastC = AppParCurves_TangencyPoint;
445   myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
446   Par = Approx_IsoParametric;
447   mydegremin = degreemin;
448   mydegremax = degreemax;
449   mytol3d = Tolerance3d;
450   mytol2d = Tolerance2d;
451   mysquares = Squares;
452   mycut = cutting;
453   myitermax = NbIterations;
454   alldone = Standard_False;
455 }
456
457 Approx_ComputeLine::Approx_ComputeLine
458                     (const Standard_Integer degreemin,
459                      const Standard_Integer degreemax,
460                      const Standard_Real Tolerance3d,
461                      const Standard_Real Tolerance2d,
462                      const Standard_Integer NbIterations,
463                      const Standard_Boolean cutting,
464                      const Approx_ParametrizationType parametrization,
465                      const Standard_Boolean Squares)
466 : myMultiLineNb (0),
467   myIsClear (Standard_False)
468 {
469   myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
470   Par = parametrization;
471   mydegremin = degreemin;
472   mydegremax = degreemax;
473   mytol3d = Tolerance3d;
474   mytol2d = Tolerance2d;
475   mysquares = Squares;
476   mycut = cutting;
477   myitermax = NbIterations;
478   myfirstC = AppParCurves_TangencyPoint;
479   mylastC = AppParCurves_TangencyPoint;
480   alldone = Standard_False;
481 }
482
483
484 Approx_ComputeLine::Approx_ComputeLine
485                     (const MultiLine& Line,
486                      const Standard_Integer degreemin,
487                      const Standard_Integer degreemax,
488                      const Standard_Real Tolerance3d,
489                      const Standard_Real Tolerance2d,
490                      const Standard_Integer NbIterations,
491                      const Standard_Boolean cutting,
492                      const Approx_ParametrizationType parametrization,
493                      const Standard_Boolean Squares)
494 : myMultiLineNb (0),
495   myIsClear (Standard_False)
496 {
497   myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
498   alldone = Standard_False;
499   mydegremin = degreemin;
500   mydegremax = degreemax;
501   mytol3d = Tolerance3d;
502   mytol2d = Tolerance2d;
503   mysquares = Squares;
504   mycut = cutting;
505   myitermax = NbIterations;
506   Par = parametrization;
507   myfirstC = AppParCurves_TangencyPoint;
508   mylastC = AppParCurves_TangencyPoint;
509
510   Perform(Line);
511 }
512
513
514
515 void Approx_ComputeLine::Perform(const MultiLine& Line)
516 {
517 #ifdef DEB
518   if (mydebug) DUMP(Line);
519 #endif
520   if (!myIsClear)
521   {
522     myMultiCurves.Clear();
523     myPar.Clear();
524     Tolers3d.Clear();
525     Tolers2d.Clear();
526     myMultiLineNb = 0;
527   }
528   else myIsClear = Standard_False;
529
530   Standard_Integer i, nbp, Thefirstpt, Thelastpt, oldlastpt;
531   Standard_Boolean Finish = Standard_False,
532           begin = Standard_True, Ok = Standard_False, 
533           GoUp = Standard_False, Interpol;
534   Standard_Real thetol3d, thetol2d;
535   Approx_Status MyStatus;
536 //  gp_Vec V13d, V23d;
537 //  gp_Vec2d V2d;
538   Thefirstpt = LineTool::FirstPoint(Line);
539   Thelastpt  = LineTool::LastPoint(Line);
540   Standard_Integer myfirstpt = Thefirstpt; 
541   Standard_Integer mylastpt = Thelastpt;
542
543   AppParCurves_ConstraintCouple myCouple1(myfirstpt, myfirstC);
544   AppParCurves_ConstraintCouple myCouple2(mylastpt, mylastC);
545   myConstraints->SetValue(1, myCouple1);
546   myConstraints->SetValue(2, myCouple2);
547
548   math_Vector TheParam(Thefirstpt, Thelastpt);
549
550
551   if (!mycut) {
552     if(myfirstParam.IsNull()) {
553       Parameters(Line, Thefirstpt, Thelastpt, TheParam);
554     }
555     else {
556       for (i = myfirstParam->Lower(); i <= myfirstParam->Upper(); i++) {
557         TheParam(i+Thefirstpt-1) = myfirstParam->Value(i);
558       }
559     }
560     TheMultiCurve = AppParCurves_MultiCurve();
561     alldone = Compute(Line, myfirstpt, mylastpt, TheParam, thetol3d, thetol2d);
562     if(!alldone && TheMultiCurve.NbCurves() > 0) {
563 #ifdef DEB 
564       if (mydebug) DUMP(TheMultiCurve);
565 #endif
566       myMultiCurves.Append(TheMultiCurve);
567       Tolers3d.Append(currenttol3d);
568       Tolers2d.Append(currenttol2d);
569       Handle(TColStd_HArray1OfReal) ThePar = new TColStd_HArray1OfReal(myfirstpt, mylastpt);
570       for (i = myfirstpt; i <= mylastpt; i++) {
571         ThePar->SetValue(i, myParameters->Value(i));
572       }
573       myPar.Append(ThePar);
574     }
575   }
576   else {
577     while (!Finish) {
578       oldlastpt = mylastpt;
579       // Gestion du decoupage de la multiline pour approximer:
580       if(!begin) {
581         if (!GoUp) {
582           if (Ok) {
583             // Calcul de la partie a approximer.
584             myfirstpt = mylastpt;
585             mylastpt  = Thelastpt;
586             if (myfirstpt == Thelastpt) {
587               Finish = Standard_True;
588               alldone = Standard_True;
589               return;
590             }
591           }
592           else {
593             nbp = mylastpt - myfirstpt + 1;
594             MyStatus = LineTool::WhatStatus(Line, myfirstpt, mylastpt);
595             if (MyStatus == Approx_NoPointsAdded && nbp <= mydegremax+1) {
596               Interpol = ComputeCurve(Line, myfirstpt, mylastpt);
597               if (Interpol) {
598                 if (mylastpt == Thelastpt) {
599                   Finish = Standard_True;
600                   alldone = Standard_True;
601                   return;
602                 }
603               }
604             }
605             mylastpt = Standard_Integer((myfirstpt + mylastpt)/2);
606           }
607         }
608         GoUp = Standard_False;
609       }
610       
611       // Verification du nombre de points restants par rapport au degre
612       // demande.
613       // ==============================================================
614       nbp = mylastpt - myfirstpt + 1;
615       MyStatus = LineTool::WhatStatus(Line, myfirstpt, mylastpt);
616       if (nbp <= mydegremax+5 ) {
617         // Rajout necessaire de points si possible.
618         // ========================================
619         GoUp = Standard_False;
620         Ok = Standard_True;
621         Standard_Boolean FailOnPointsAdded = Standard_False;
622         if (MyStatus == Approx_PointsAdded) {
623           // Appel recursif du decoupage:
624           GoUp = Standard_True;
625
626           MultiLine OtherLine =LineTool::MakeMLBetween(Line, myfirstpt, 
627                                                        mylastpt, nbp-1);
628           
629           Standard_Integer nbpdsotherligne = LineTool::FirstPoint(OtherLine)
630             -LineTool::LastPoint(OtherLine);
631
632           //-- Si MakeML a echoue   on retourne une ligne vide
633           if ((nbpdsotherligne == 0) || myMultiLineNb >= 3)
634           {
635             FailOnPointsAdded = Standard_True; 
636             //-- cout<<" ** ApproxComputeLine MakeML Echec ** LBR lbr "<<endl;
637             if (myfirstpt == mylastpt) break;  // Pour etre sur de ne pas 
638             // planter la station !!
639             myCouple1.SetIndex(myfirstpt);
640             myCouple2.SetIndex(mylastpt);
641             myConstraints->SetValue(1, myCouple1);
642             myConstraints->SetValue(2, myCouple2);
643
644             math_Vector Param(myfirstpt, mylastpt);
645             Approx_ParametrizationType SavePar = Par;
646             Par = Approx_IsoParametric;
647             Parameters(Line, myfirstpt, mylastpt, Param);
648             TheMultiCurve = AppParCurves_MultiCurve();
649             Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d);
650
651             if (!Ok) {
652               Standard_Real tt3d = currenttol3d, tt2d = currenttol2d;
653               Handle(TColStd_HArray1OfReal) saveParameters = myParameters;
654               AppParCurves_MultiCurve saveMultiCurve = TheMultiCurve;
655
656               if(SavePar != Approx_IsoParametric)
657                 Par = SavePar;
658               else
659                 Par = Approx_ChordLength;
660
661               Parameters(Line, myfirstpt, mylastpt, Param);
662               Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d);
663               
664               if (!Ok && tt3d <= currenttol3d && tt2d <= currenttol2d) {
665                 currenttol3d = tt3d; currenttol2d = tt2d;
666                 myParameters = saveParameters;
667                 TheMultiCurve = saveMultiCurve;
668               }
669             }
670             Par = SavePar;
671
672             oldlastpt = mylastpt;
673             if (!Ok) {
674               tolreached = Standard_False;
675               if (TheMultiCurve.NbCurves() == 0) {
676                 myMultiCurves.Clear();
677                 return;
678               }
679 #ifdef DEB 
680       if (mydebug) DUMP(TheMultiCurve);
681 #endif
682               myMultiCurves.Append(TheMultiCurve);
683               Tolers3d.Append(currenttol3d);
684               Tolers2d.Append(currenttol2d);
685               
686               Handle(TColStd_HArray1OfReal) ThePar = new TColStd_HArray1OfReal(myfirstpt, oldlastpt);
687               for (i = myfirstpt; i <= oldlastpt; i++) {
688                 ThePar->SetValue(i, myParameters->Value(i));
689               }
690               myPar.Append(ThePar);
691             } 
692             myfirstpt = oldlastpt;
693             mylastpt = Thelastpt;
694             
695           }
696           else
697           {
698             myIsClear = Standard_True;
699             ++myMultiLineNb;
700             Perform(OtherLine);
701             myfirstpt = mylastpt;
702             mylastpt = Thelastpt;
703           }
704         }
705         
706         if  (MyStatus == Approx_NoPointsAdded && !begin) {
707           // On rend la meilleure approximation obtenue precedemment.
708           // ========================================================
709           GoUp = Standard_True;
710           tolreached = Standard_False;
711           if (TheMultiCurve.NbCurves() == 0) {
712             myMultiCurves.Clear();
713             return;
714           }
715 #ifdef DEB 
716       if (mydebug) DUMP(TheMultiCurve);
717 #endif
718           myMultiCurves.Append(TheMultiCurve);
719           Tolers3d.Append(currenttol3d);
720           Tolers2d.Append(currenttol2d);
721
722           Handle(TColStd_HArray1OfReal) ThePar = new TColStd_HArray1OfReal(myfirstpt, oldlastpt);
723           for (i = myfirstpt; i <= oldlastpt; i++) {
724             ThePar->SetValue(i, myParameters->Value(i));
725           }
726           myPar.Append(ThePar);
727
728           myfirstpt = oldlastpt;
729           mylastpt = Thelastpt;
730         }
731         
732         else if (MyStatus == Approx_NoApproximation) {
733           // On ne fait pas d approximation entre myfirstpt et mylastpt.
734           // ===========================================================
735           // On stocke pour pouvoir en informer l utilisateur.
736           GoUp = Standard_True;
737           myfirstpt = mylastpt;
738           mylastpt = Thelastpt;
739         }
740       }
741       
742       if (myfirstpt == Thelastpt) {
743         Finish = Standard_True;
744         alldone = Standard_True;
745         return;
746       }
747       if (!GoUp) {
748         if (myfirstpt == mylastpt) break;  // Pour etre sur de ne pas 
749                                            // planter la station !!
750         myCouple1.SetIndex(myfirstpt);
751         myCouple2.SetIndex(mylastpt);
752         myConstraints->SetValue(1, myCouple1);
753         myConstraints->SetValue(2, myCouple2);
754         
755         // Calcul des parametres sur ce nouvel intervalle.
756         // On recupere les parametres initiaux lors du decoupage.
757
758         math_Vector Param(myfirstpt, mylastpt);
759         if (begin) {
760           if(myfirstParam.IsNull()) {
761             Parameters(Line, myfirstpt, mylastpt, Param);
762           }
763           else {
764             for (i = myfirstParam->Lower(); i <= myfirstParam->Upper(); i++) {
765               Param(i) = myfirstParam->Value(i);
766             }
767             myfirstParam.Nullify();
768           }
769           TheParam = Param;
770           begin = Standard_False;
771         }
772         else {
773           Standard_Real pfirst = TheParam.Value(myfirstpt);
774           Standard_Real plast = TheParam.Value(mylastpt);
775           for (i = myfirstpt; i <= mylastpt; i++) {
776             Param(i) = (TheParam.Value(i)-pfirst)/(plast-pfirst);
777           }
778         }
779
780         TheMultiCurve = AppParCurves_MultiCurve();
781         Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d);
782
783       }
784     }
785   }
786 }
787
788
789
790 const TColStd_Array1OfReal& Approx_ComputeLine::Parameters(const Standard_Integer Index) const
791 {
792   return (myPar.Value(Index))->Array1();
793 }
794
795
796 Standard_Integer Approx_ComputeLine::NbMultiCurves()const
797 {
798   return myMultiCurves.Length();
799 }
800
801 AppParCurves_MultiCurve& Approx_ComputeLine::ChangeValue(const Standard_Integer Index)
802 {
803   return myMultiCurves.ChangeValue(Index);
804 }
805
806
807 const AppParCurves_MultiCurve& Approx_ComputeLine::Value(const Standard_Integer Index)
808 const
809 {
810   return myMultiCurves.Value(Index);
811 }
812
813
814 const AppParCurves_MultiBSpCurve& Approx_ComputeLine::SplineValue()
815 {
816   Approx_MCurvesToBSpCurve Trans;
817   Trans.Perform(myMultiCurves);
818   myspline = Trans.Value();
819   return myspline;
820 }
821
822
823
824
825
826 void Approx_ComputeLine::Parameters(const MultiLine& Line, 
827                                const Standard_Integer firstP,
828                                const Standard_Integer lastP,
829                                math_Vector& TheParameters) const
830 {
831   Standard_Integer i, j, Nbp, nbP2d, nbP3d;
832   Standard_Real dist;
833   gp_Pnt P1, P2;
834   gp_Pnt2d P12d, P22d;
835   Nbp = lastP-firstP+1;
836
837   if (Par == Approx_ChordLength || Par == Approx_Centripetal) {
838     nbP3d = LineTool::NbP3d(Line);
839     nbP2d = LineTool::NbP2d(Line);
840     Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
841     if (nbP3d == 0) mynbP3d = 1;
842     if (nbP2d == 0) mynbP2d = 1;
843
844     TheParameters(firstP) = 0.0;
845     dist = 0.0;
846     TColgp_Array1OfPnt tabP(1, mynbP3d);
847     TColgp_Array1OfPnt tabPP(1, mynbP3d);
848     TColgp_Array1OfPnt2d tabP2d(1, mynbP2d);
849     TColgp_Array1OfPnt2d tabPP2d(1, mynbP2d);
850
851     for (i = firstP+1; i <= lastP; i++) {
852       if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i-1, tabP, tabP2d);
853       else if (nbP2d != 0)          LineTool::Value(Line, i-1, tabP2d);
854       else if (nbP3d != 0)          LineTool::Value(Line, i-1, tabP);
855
856       if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i, tabPP, tabPP2d);
857       else if (nbP2d != 0)          LineTool::Value(Line, i, tabPP2d);
858       else if (nbP3d != 0)          LineTool::Value(Line, i, tabPP);
859       dist = 0;
860       for (j = 1; j <= nbP3d; j++) {
861         P1 = tabP(j);
862         P2 = tabPP(j);
863         dist += P2.Distance(P1);
864       }
865       for (j = 1; j <= nbP2d; j++) {
866         P12d = tabP2d(j);
867         P22d = tabPP2d(j);
868         dist += P22d.Distance(P12d);
869       }
870       if(Par == Approx_ChordLength)
871         TheParameters(i) = TheParameters(i-1) + dist;
872       else {// Par == Approx_Centripetal
873         TheParameters(i) = TheParameters(i-1) + Sqrt(dist);
874       }
875     }
876     for (i = firstP; i <= lastP; i++) TheParameters(i) /= TheParameters(lastP);
877   }
878   else {
879     for (i = firstP; i <= lastP; i++) {
880       TheParameters(i) = (Standard_Real(i)-firstP)/
881                          (Standard_Real(lastP)-Standard_Real(firstP));
882     }
883   }
884 }  
885
886
887 Standard_Boolean Approx_ComputeLine::Compute(const MultiLine& Line,
888                                              const Standard_Integer fpt,
889                                              const Standard_Integer lpt,
890                                              math_Vector&     Para,
891                                              Standard_Real&   TheTol3d,
892                                              Standard_Real&   TheTol2d)
893 {
894   
895   Standard_Integer deg, i;
896   Standard_Boolean mydone;
897   Standard_Real Fv;
898   Standard_Integer nbp = lpt-fpt+1;
899
900   math_Vector ParSav(Para.Lower(), Para.Upper());
901   for (i = Para.Lower(); i <= Para.Upper(); i++) {
902     ParSav(i) = Para(i);
903   }
904   Standard_Integer Mdegmax = mydegremax;
905   if(nbp < Mdegmax+5 && mycut) { 
906     Mdegmax = nbp - 5;
907   }
908   if(Mdegmax < mydegremin)  { 
909     Mdegmax = mydegremin;
910   }
911   
912   currenttol3d = currenttol2d = RealLast();
913   for (deg = Min(nbp-1,mydegremin); deg <= Mdegmax; deg++) {
914     AppParCurves_MultiCurve mySCU(deg+1);
915     if (mysquares) {
916       Approx_ParLeastSquareOfMyGradient SQ(Line, fpt, lpt, 
917                                            myfirstC, mylastC, Para, deg+1);
918       mydone = SQ.IsDone();
919       mySCU = SQ.BezierValue();
920       SQ.Error(Fv, TheTol3d, TheTol2d);
921     }
922     else {
923       Approx_MyGradient GRAD(Line, fpt, lpt, myConstraints, 
924                              Para, deg, mytol3d, mytol2d, myitermax);
925       mydone = GRAD.IsDone();
926       mySCU = GRAD.Value();
927       if (mySCU.NbCurves() == 0)
928         continue;
929       TheTol3d = GRAD.MaxError3d();
930       TheTol2d = GRAD.MaxError2d();
931     }      
932     Standard_Real uu1 = Para(Para.Lower()), uu2;
933     Standard_Boolean restau = Standard_False;
934     for ( i = Para.Lower()+1; i <= Para.Upper(); i++) {
935       uu2 =  Para(i);
936       if (uu2 <= uu1) {
937         restau = Standard_True;
938 //      cout << "restau = Standard_True" << endl;
939         break;
940       }
941       uu1 = uu2;
942     }
943     if (restau) {
944       for (i = Para.Lower(); i <= Para.Upper(); i++) {
945         Para(i) = ParSav(i);
946       }
947     }
948     if (mydone) {
949       if (TheTol3d <= mytol3d && TheTol2d <= mytol2d) {
950         // Stockage de la multicurve approximee.
951         tolreached = Standard_True;
952 #ifdef DEB 
953       if (mydebug) DUMP(mySCU);
954 #endif
955         myMultiCurves.Append(mySCU);
956         // Stockage des parametres de la partie de MultiLine approximee:
957         // A ameliorer !! (bq trop de recopies)
958         Handle(TColStd_HArray1OfReal) ThePar = 
959           new TColStd_HArray1OfReal(Para.Lower(), Para.Upper());
960         for (i = Para.Lower(); i <= Para.Upper(); i++) {
961           ThePar->SetValue(i, Para(i));
962         }
963         myPar.Append(ThePar);
964         Tolers3d.Append(TheTol3d);
965         Tolers2d.Append(TheTol2d);
966         return Standard_True;
967       }
968     }
969
970     if (TheTol3d <= currenttol3d && TheTol2d <= currenttol2d) {
971       TheMultiCurve = mySCU;
972       currenttol3d = TheTol3d;
973       currenttol2d = TheTol2d;
974       myParameters = new TColStd_HArray1OfReal(Para.Lower(), Para.Upper());
975       for (i = Para.Lower(); i <= Para.Upper(); i++) {
976         myParameters->SetValue(i, Para(i));
977       }
978     }
979
980   }
981
982   return Standard_False;
983 }
984
985
986
987
988 Standard_Boolean  Approx_ComputeLine::ComputeCurve(const MultiLine& Line,
989                                       const Standard_Integer firstpt,
990                                       const Standard_Integer lastpt)
991 {
992   Standard_Integer i, j, nbP3d, nbP2d, deg;
993   gp_Vec V13d, V23d;
994   gp_Vec2d V12d, V22d;
995   gp_Pnt P1, P2;
996   gp_Pnt2d P12d, P22d;
997   Standard_Boolean Tangent1, Tangent2, Parallel, mydone= Standard_False;
998   Standard_Integer myfirstpt = firstpt, mylastpt = lastpt;
999   Standard_Integer nbp = lastpt-firstpt+1, Kopt = 0;
1000   AppParCurves_Constraint FirstC, LastC;
1001   FirstC = AppParCurves_PassPoint;
1002   LastC = AppParCurves_PassPoint;
1003   math_Vector Para(firstpt, lastpt);
1004
1005   Parameters(Line, firstpt, lastpt, Para);
1006
1007   nbP3d = LineTool::NbP3d(Line);
1008   nbP2d = LineTool::NbP2d(Line);
1009   Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
1010   if (nbP3d == 0) mynbP3d = 1 ;
1011   if (nbP2d == 0) mynbP2d = 1 ;
1012
1013
1014   TColgp_Array1OfVec tabV1(1, mynbP3d), tabV2(1, mynbP3d);
1015   TColgp_Array1OfPnt tabP1(1, mynbP3d), tabP2(1, mynbP3d), tabP(1, mynbP3d);
1016   TColgp_Array1OfVec2d tabV12d(1, mynbP2d), tabV22d(1, mynbP2d);
1017   TColgp_Array1OfPnt2d tabP12d(1, mynbP2d), tabP22d(1, mynbP2d), tabP2d(1, mynbP2d);
1018
1019   if (nbP3d != 0 && nbP2d != 0) {
1020     LineTool::Value(Line, myfirstpt,tabP1,tabP12d);
1021     LineTool::Value(Line, mylastpt,tabP2,tabP22d);
1022     Tangent1 = LineTool::Tangency(Line, myfirstpt,tabV1,tabV12d);
1023     Tangent2 = LineTool::Tangency(Line, mylastpt,tabV2,tabV22d);
1024   }
1025   else if (nbP2d != 0) {
1026     LineTool::Value(Line, myfirstpt,tabP12d);
1027     LineTool::Value(Line, mylastpt,tabP22d);
1028     Tangent1 = LineTool::Tangency(Line, myfirstpt, tabV12d);
1029     Tangent2 = LineTool::Tangency(Line, mylastpt, tabV22d);
1030   }
1031   else {
1032     LineTool::Value(Line, myfirstpt,tabP1);
1033     LineTool::Value(Line, mylastpt,tabP2);
1034     Tangent1 = LineTool::Tangency(Line, myfirstpt, tabV1);
1035     Tangent2 = LineTool::Tangency(Line, mylastpt, tabV2);
1036   }
1037
1038   if (Tangent1) Kopt++;  
1039   if (Tangent2) Kopt++;
1040
1041
1042   if (nbp == 2) {
1043     // S il n y a que 2 points, on verifie quand meme que les tangentes sont 
1044     // alignees.
1045     Parallel = Standard_True;
1046     if (Tangent1) {
1047       for (i = 1; i <= nbP3d; i++) {
1048         gp_Vec PVec(tabP1(i), tabP2(i));
1049         V13d = tabV1(i);
1050         if (!PVec.IsParallel(V13d, Precision::Angular())) {
1051           Parallel = Standard_False;
1052           break;
1053         }
1054       }
1055       for (i = 1; i <= nbP2d; i++) {
1056         gp_Vec2d PVec2d(tabP12d(i), tabP22d(i));
1057         V12d = tabV12d(i);
1058         if (!PVec2d.IsParallel(V12d, Precision::Angular())) {
1059           Parallel = Standard_False;
1060           break;
1061         }
1062       }
1063     }   
1064
1065     if (Tangent2) {
1066       for (i = 1; i <= nbP3d; i++) {
1067         gp_Vec PVec(tabP1(i), tabP2(i));
1068         V23d = tabV2(i);
1069         if (!PVec.IsParallel(V23d, Precision::Angular())) {
1070           Parallel = Standard_False;
1071           break;
1072         }
1073       }
1074       for (i = 1; i <= nbP2d; i++) {
1075         gp_Vec2d PVec2d(tabP12d(i), tabP22d(i));
1076         V22d = tabV22d(i);
1077         if (!PVec2d.IsParallel(V22d, Precision::Angular())) {
1078           Parallel = Standard_False;
1079           break;
1080         }
1081       }
1082     }
1083
1084 #ifdef DEB
1085     if (!Parallel) {
1086       if (mydebug) cout <<"droite mais tangentes pas vraiment paralleles!!"<< endl;
1087     }
1088 #endif
1089     AppParCurves_MultiCurve mySCU(mydegremin+1);
1090     if (nbP3d != 0 && nbP2d != 0) {
1091       AppParCurves_MultiPoint MPole1(tabP1, tabP12d);
1092       AppParCurves_MultiPoint MPole2(tabP2, tabP22d);
1093       mySCU.SetValue(1, MPole1);
1094       mySCU.SetValue(mydegremin+1, MPole2);
1095       for (i = 2; i <= mydegremin; i++) {
1096         for (j = 1; j<= nbP3d; j++) {
1097           P1 = tabP1(j);
1098           P2 = tabP2(j);
1099           tabP(j).SetXYZ(P1.XYZ()+(i-1)*(P2.XYZ()-P1.XYZ())/mydegremin);
1100         }
1101         for (j = 1; j<= nbP2d; j++) {
1102           P12d = tabP12d(j);
1103           P22d = tabP22d(j);
1104           tabP2d(j).SetXY(P12d.XY()+(i-1)*(P22d.XY()-P12d.XY())/mydegremin);
1105         }
1106         AppParCurves_MultiPoint MPole(tabP, tabP2d);
1107         mySCU.SetValue(i, MPole);
1108       }
1109
1110     }
1111     else if (nbP3d != 0) {
1112       AppParCurves_MultiPoint MPole1(tabP1);
1113       AppParCurves_MultiPoint MPole2(tabP2);
1114       mySCU.SetValue(1, MPole1);
1115       mySCU.SetValue(mydegremin+1, MPole2);
1116       for (i = 2; i <= mydegremin; i++) {
1117         for (j = 1; j<= nbP3d; j++) {
1118           P1 = tabP1(j);
1119           P2 = tabP2(j);
1120           tabP(j).SetXYZ(P1.XYZ()+(i-1)*(P2.XYZ()-P1.XYZ())/mydegremin);
1121         }
1122         AppParCurves_MultiPoint MPole(tabP);
1123         mySCU.SetValue(i, MPole);
1124       }
1125     }
1126     else if (nbP2d != 0) {
1127       AppParCurves_MultiPoint MPole1(tabP12d);
1128       AppParCurves_MultiPoint MPole2(tabP22d);
1129       mySCU.SetValue(1, MPole1);
1130       mySCU.SetValue(mydegremin+1, MPole2);
1131       for (i = 2; i <= mydegremin; i++) {
1132         for (j = 1; j<= nbP2d; j++) {
1133           P12d = tabP12d(j);
1134           P22d = tabP22d(j);
1135           tabP2d(j).SetXY(P12d.XY()+(i-1)*(P22d.XY()-P12d.XY())/mydegremin);
1136         }
1137         AppParCurves_MultiPoint MPole(tabP2d);
1138         mySCU.SetValue(i, MPole);
1139       }
1140     }
1141     mydone = Standard_True;
1142     // Stockage de la multicurve approximee.
1143     tolreached = Standard_True;
1144 #ifdef DEB 
1145       if (mydebug) DUMP(mySCU);
1146 #endif
1147     myMultiCurves.Append(mySCU);
1148     Handle(TColStd_HArray1OfReal) ThePar = new TColStd_HArray1OfReal(Para.Lower(), Para.Upper());
1149     for (i = Para.Lower(); i <= Para.Upper(); i++) {
1150       ThePar->SetValue(i, Para(i));
1151     }
1152     myPar.Append(ThePar);
1153     Tolers3d.Append(Precision::Confusion());
1154     Tolers2d.Append(Precision::PConfusion());
1155     return mydone;
1156   }
1157
1158   // avec les tangentes.
1159   deg = nbp+1;
1160   AppParCurves_MultiCurve mySCU(deg+1);
1161   AppParCurves_Constraint Cons = AppParCurves_TangencyPoint;
1162   Standard_Real lambda1, lambda2;
1163   math_Vector V1(1, nbP3d*3+nbP2d*2);
1164   math_Vector V2(1, nbP3d*3+nbP2d*2);
1165   FirstTangencyVector(Line, myfirstpt, V1);
1166   lambda1 = SearchFirstLambda(Line, Para, V1, myfirstpt);
1167   
1168   LastTangencyVector(Line, mylastpt, V2);
1169   lambda2 = SearchLastLambda(Line, Para, V2, mylastpt);
1170   
1171   Approx_ParLeastSquareOfMyGradient 
1172     LSQ(Line, myfirstpt, mylastpt, 
1173         Cons, Cons, Para, deg+1);
1174   
1175   lambda1 = lambda1/deg;
1176   lambda2 = lambda2/deg;
1177   LSQ.Perform(Para, V1, V2, lambda1, lambda2);
1178   mydone = LSQ.IsDone();
1179   mySCU = LSQ.BezierValue();
1180   
1181   if (mydone) {
1182     Standard_Real Fv, TheTol3d, TheTol2d;
1183     LSQ.Error(Fv, TheTol3d, TheTol2d);  
1184
1185     // Stockage de la multicurve approximee.
1186     tolreached = Standard_True;
1187 #ifdef DEB 
1188       if (mydebug) DUMP(mySCU);
1189 #endif
1190     myMultiCurves.Append(mySCU);
1191     Handle(TColStd_HArray1OfReal) ThePar = 
1192       new TColStd_HArray1OfReal(Para.Lower(), Para.Upper());
1193     for (i = Para.Lower(); i <= Para.Upper(); i++) {
1194       ThePar->SetValue(i, Para(i));
1195     }
1196     myPar.Append(ThePar);
1197     Tolers3d.Append(TheTol3d);
1198     Tolers2d.Append(TheTol2d);
1199     return Standard_True;
1200   }
1201   return mydone;
1202 }
1203
1204
1205
1206 void Approx_ComputeLine::Init(const Standard_Integer degreemin,
1207                               const Standard_Integer degreemax,
1208                               const Standard_Real Tolerance3d,
1209                               const Standard_Real Tolerance2d,
1210                               const Standard_Integer NbIterations,
1211                               const Standard_Boolean cutting,
1212                               const Approx_ParametrizationType parametrization,
1213                               const Standard_Boolean Squares)
1214 {
1215   mydegremin = degreemin;
1216   mydegremax = degreemax;
1217   mytol3d = Tolerance3d;
1218   mytol2d = Tolerance2d;
1219   Par = parametrization;
1220   mysquares = Squares;
1221   mycut = cutting;
1222   myitermax = NbIterations;
1223 }
1224
1225
1226
1227 void Approx_ComputeLine::SetDegrees(const Standard_Integer degreemin,
1228                                     const Standard_Integer degreemax)
1229 {
1230   mydegremin = degreemin;
1231   mydegremax = degreemax;
1232 }
1233
1234
1235 void Approx_ComputeLine::SetTolerances(const Standard_Real Tolerance3d,
1236                                        const Standard_Real Tolerance2d)
1237 {
1238   mytol3d = Tolerance3d;
1239   mytol2d = Tolerance2d;
1240 }
1241
1242
1243 void Approx_ComputeLine::SetConstraints(const AppParCurves_Constraint FirstC,
1244                                         const AppParCurves_Constraint LastC)
1245 {
1246   myfirstC = FirstC;
1247   mylastC = LastC;
1248 }
1249
1250
1251
1252 Standard_Boolean Approx_ComputeLine::IsAllApproximated()
1253 const {
1254   return alldone;
1255 }
1256
1257 Standard_Boolean Approx_ComputeLine::IsToleranceReached()
1258 const {
1259   return tolreached;
1260 }
1261
1262 void Approx_ComputeLine::Error(const Standard_Integer Index,
1263                                Standard_Real& tol3d,
1264                                Standard_Real& tol2d) const
1265 {
1266   tol3d = Tolers3d.Value(Index);
1267   tol2d = Tolers2d.Value(Index);
1268 }
1269
1270 void Approx_ComputeLine::Parametrization(Approx_ParametrizationType& partype) const
1271 {
1272   partype = Par;
1273 }