0026431: Can't cut a sphere from a cylinder
[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 under
7 // the terms of the GNU Lesser General Public License 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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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         if (MyStatus == Approx_PointsAdded) {
622           // Appel recursif du decoupage:
623           GoUp = Standard_True;
624
625           MultiLine OtherLine =LineTool::MakeMLBetween(Line, myfirstpt, 
626                                                        mylastpt, nbp-1);
627           
628           Standard_Integer nbpdsotherligne = LineTool::FirstPoint(OtherLine)
629             -LineTool::LastPoint(OtherLine);
630
631           //-- Si MakeML a echoue   on retourne une ligne vide
632           if ((nbpdsotherligne == 0) || myMultiLineNb >= 3)
633           {
634             //-- cout<<" ** ApproxComputeLine MakeML Echec ** LBR lbr "<<endl;
635             if (myfirstpt == mylastpt) break;  // Pour etre sur de ne pas 
636             // planter la station !!
637             myCouple1.SetIndex(myfirstpt);
638             myCouple2.SetIndex(mylastpt);
639             myConstraints->SetValue(1, myCouple1);
640             myConstraints->SetValue(2, myCouple2);
641
642             math_Vector Param(myfirstpt, mylastpt);
643             Approx_ParametrizationType SavePar = Par;
644             Par = Approx_IsoParametric;
645             Parameters(Line, myfirstpt, mylastpt, Param);
646             TheMultiCurve = AppParCurves_MultiCurve();
647             Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d);
648
649             if (!Ok) {
650               Standard_Real tt3d = currenttol3d, tt2d = currenttol2d;
651               Handle(TColStd_HArray1OfReal) saveParameters = myParameters;
652               AppParCurves_MultiCurve saveMultiCurve = TheMultiCurve;
653
654               if(SavePar != Approx_IsoParametric)
655                 Par = SavePar;
656               else
657                 Par = Approx_ChordLength;
658
659               Parameters(Line, myfirstpt, mylastpt, Param);
660               Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d);
661               
662               if (!Ok && tt3d <= currenttol3d && tt2d <= currenttol2d) {
663                 currenttol3d = tt3d; currenttol2d = tt2d;
664                 myParameters = saveParameters;
665                 TheMultiCurve = saveMultiCurve;
666               }
667             }
668             Par = SavePar;
669
670             oldlastpt = mylastpt;
671             if (!Ok) {
672               tolreached = Standard_False;
673               if (TheMultiCurve.NbCurves() == 0) {
674                 myMultiCurves.Clear();
675                 return;
676               }
677 #ifdef OCCT_DEBUG
678       if (mydebug) DUMP(TheMultiCurve);
679 #endif
680               myMultiCurves.Append(TheMultiCurve);
681               Tolers3d.Append(currenttol3d);
682               Tolers2d.Append(currenttol2d);
683               
684               Handle(TColStd_HArray1OfReal) ThePar = new TColStd_HArray1OfReal(myfirstpt, oldlastpt);
685               for (i = myfirstpt; i <= oldlastpt; i++) {
686                 ThePar->SetValue(i, myParameters->Value(i));
687               }
688               myPar.Append(ThePar);
689             } 
690             myfirstpt = oldlastpt;
691             mylastpt = Thelastpt;
692             
693           }
694           else
695           {
696             myIsClear = Standard_True;
697             ++myMultiLineNb;
698             Perform(OtherLine);
699             myfirstpt = mylastpt;
700             mylastpt = Thelastpt;
701           }
702         }
703         
704         if  (MyStatus == Approx_NoPointsAdded && !begin) {
705           // On rend la meilleure approximation obtenue precedemment.
706           // ========================================================
707           GoUp = Standard_True;
708           tolreached = Standard_False;
709           if (TheMultiCurve.NbCurves() == 0) {
710             myMultiCurves.Clear();
711             return;
712           }
713 #ifdef OCCT_DEBUG
714       if (mydebug) DUMP(TheMultiCurve);
715 #endif
716           myMultiCurves.Append(TheMultiCurve);
717           Tolers3d.Append(currenttol3d);
718           Tolers2d.Append(currenttol2d);
719
720           Handle(TColStd_HArray1OfReal) ThePar = new TColStd_HArray1OfReal(myfirstpt, oldlastpt);
721           for (i = myfirstpt; i <= oldlastpt; i++) {
722             ThePar->SetValue(i, myParameters->Value(i));
723           }
724           myPar.Append(ThePar);
725
726           myfirstpt = oldlastpt;
727           mylastpt = Thelastpt;
728         }
729         
730         else if (MyStatus == Approx_NoApproximation) {
731           // On ne fait pas d approximation entre myfirstpt et mylastpt.
732           // ===========================================================
733           // On stocke pour pouvoir en informer l utilisateur.
734           GoUp = Standard_True;
735           myfirstpt = mylastpt;
736           mylastpt = Thelastpt;
737         }
738       }
739       
740       if (myfirstpt == Thelastpt) {
741         Finish = Standard_True;
742         alldone = Standard_True;
743         return;
744       }
745       if (!GoUp) {
746         if (myfirstpt == mylastpt) break;  // Pour etre sur de ne pas 
747                                            // planter la station !!
748         myCouple1.SetIndex(myfirstpt);
749         myCouple2.SetIndex(mylastpt);
750         myConstraints->SetValue(1, myCouple1);
751         myConstraints->SetValue(2, myCouple2);
752         
753         // Calcul des parametres sur ce nouvel intervalle.
754         // On recupere les parametres initiaux lors du decoupage.
755
756         math_Vector Param(myfirstpt, mylastpt);
757         if (begin) {
758           if(myfirstParam.IsNull()) {
759             Parameters(Line, myfirstpt, mylastpt, Param);
760           }
761           else {
762             for (i = myfirstParam->Lower(); i <= myfirstParam->Upper(); i++) {
763               Param(i) = myfirstParam->Value(i);
764             }
765             myfirstParam.Nullify();
766           }
767           TheParam = Param;
768           begin = Standard_False;
769         }
770         else {
771           Standard_Real pfirst = TheParam.Value(myfirstpt);
772           Standard_Real plast = TheParam.Value(mylastpt);
773           for (i = myfirstpt; i <= mylastpt; i++) {
774             Param(i) = (TheParam.Value(i)-pfirst)/(plast-pfirst);
775           }
776         }
777
778         TheMultiCurve = AppParCurves_MultiCurve();
779         Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d);
780
781       }
782     }
783   }
784 }
785
786
787
788 const TColStd_Array1OfReal& Approx_ComputeLine::Parameters(const Standard_Integer Index) const
789 {
790   return (myPar.Value(Index))->Array1();
791 }
792
793
794 Standard_Integer Approx_ComputeLine::NbMultiCurves()const
795 {
796   return myMultiCurves.Length();
797 }
798
799 AppParCurves_MultiCurve& Approx_ComputeLine::ChangeValue(const Standard_Integer Index)
800 {
801   return myMultiCurves.ChangeValue(Index);
802 }
803
804
805 const AppParCurves_MultiCurve& Approx_ComputeLine::Value(const Standard_Integer Index)
806 const
807 {
808   return myMultiCurves.Value(Index);
809 }
810
811
812 const AppParCurves_MultiBSpCurve& Approx_ComputeLine::SplineValue()
813 {
814   Approx_MCurvesToBSpCurve Trans;
815   Trans.Perform(myMultiCurves);
816   myspline = Trans.Value();
817   return myspline;
818 }
819
820
821
822
823
824 void Approx_ComputeLine::Parameters(const MultiLine& Line, 
825                                const Standard_Integer firstP,
826                                const Standard_Integer lastP,
827                                math_Vector& TheParameters) const
828 {
829   Standard_Integer i, j, nbP2d, nbP3d;
830   Standard_Real dist;
831   gp_Pnt P1, P2;
832   gp_Pnt2d P12d, P22d;
833
834   if (Par == Approx_ChordLength || Par == Approx_Centripetal) {
835     nbP3d = LineTool::NbP3d(Line);
836     nbP2d = LineTool::NbP2d(Line);
837     Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
838     if (nbP3d == 0) mynbP3d = 1;
839     if (nbP2d == 0) mynbP2d = 1;
840
841     TheParameters(firstP) = 0.0;
842     dist = 0.0;
843     TColgp_Array1OfPnt tabP(1, mynbP3d);
844     TColgp_Array1OfPnt tabPP(1, mynbP3d);
845     TColgp_Array1OfPnt2d tabP2d(1, mynbP2d);
846     TColgp_Array1OfPnt2d tabPP2d(1, mynbP2d);
847
848     for (i = firstP+1; i <= lastP; i++) {
849       if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i-1, tabP, tabP2d);
850       else if (nbP2d != 0)          LineTool::Value(Line, i-1, tabP2d);
851       else if (nbP3d != 0)          LineTool::Value(Line, i-1, tabP);
852
853       if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i, tabPP, tabPP2d);
854       else if (nbP2d != 0)          LineTool::Value(Line, i, tabPP2d);
855       else if (nbP3d != 0)          LineTool::Value(Line, i, tabPP);
856       dist = 0;
857       for (j = 1; j <= nbP3d; j++) {
858         P1 = tabP(j);
859         P2 = tabPP(j);
860         dist += P2.Distance(P1);
861       }
862       for (j = 1; j <= nbP2d; j++) {
863         P12d = tabP2d(j);
864         P22d = tabPP2d(j);
865         dist += P22d.Distance(P12d);
866       }
867       if(Par == Approx_ChordLength)
868         TheParameters(i) = TheParameters(i-1) + dist;
869       else {// Par == Approx_Centripetal
870         TheParameters(i) = TheParameters(i-1) + Sqrt(dist);
871       }
872     }
873     for (i = firstP; i <= lastP; i++) TheParameters(i) /= TheParameters(lastP);
874   }
875   else {
876     for (i = firstP; i <= lastP; i++) {
877       TheParameters(i) = (Standard_Real(i)-firstP)/
878                          (Standard_Real(lastP)-Standard_Real(firstP));
879     }
880   }
881 }  
882
883
884 Standard_Boolean Approx_ComputeLine::Compute(const MultiLine& Line,
885                                              const Standard_Integer fpt,
886                                              const Standard_Integer lpt,
887                                              math_Vector&     Para,
888                                              Standard_Real&   TheTol3d,
889                                              Standard_Real&   TheTol2d)
890 {
891   
892   Standard_Integer deg, i;
893   Standard_Boolean mydone;
894   Standard_Real Fv;
895   Standard_Integer nbp = lpt-fpt+1;
896
897   math_Vector ParSav(Para.Lower(), Para.Upper());
898   for (i = Para.Lower(); i <= Para.Upper(); i++) {
899     ParSav(i) = Para(i);
900   }
901   Standard_Integer Mdegmax = mydegremax;
902   if(nbp < Mdegmax+5 && mycut) { 
903     Mdegmax = nbp - 5;
904   }
905   if(Mdegmax < mydegremin)  { 
906     Mdegmax = mydegremin;
907   }
908   
909   currenttol3d = currenttol2d = RealLast();
910   for (deg = Min(nbp-1,mydegremin); deg <= Mdegmax; deg++) {
911     AppParCurves_MultiCurve mySCU(deg+1);
912     if (mysquares) {
913       Approx_ParLeastSquareOfMyGradient SQ(Line, fpt, lpt, 
914                                            myfirstC, mylastC, Para, deg+1);
915       mydone = SQ.IsDone();
916       mySCU = SQ.BezierValue();
917       SQ.Error(Fv, TheTol3d, TheTol2d);
918     }
919     else {
920       Approx_MyGradient GRAD(Line, fpt, lpt, myConstraints, 
921                              Para, deg, mytol3d, mytol2d, myitermax);
922       mydone = GRAD.IsDone();
923       mySCU = GRAD.Value();
924       if (mySCU.NbCurves() == 0)
925         continue;
926       TheTol3d = GRAD.MaxError3d();
927       TheTol2d = GRAD.MaxError2d();
928     }      
929     Standard_Real uu1 = Para(Para.Lower()), uu2;
930     Standard_Boolean restau = Standard_False;
931     for ( i = Para.Lower()+1; i <= Para.Upper(); i++) {
932       uu2 =  Para(i);
933       if (uu2 <= uu1) {
934         restau = Standard_True;
935 //      cout << "restau = Standard_True" << endl;
936         break;
937       }
938       uu1 = uu2;
939     }
940     if (restau) {
941       for (i = Para.Lower(); i <= Para.Upper(); i++) {
942         Para(i) = ParSav(i);
943       }
944     }
945     if (mydone) {
946       if (TheTol3d <= mytol3d && TheTol2d <= mytol2d) {
947         // Stockage de la multicurve approximee.
948         tolreached = Standard_True;
949 #ifdef OCCT_DEBUG
950       if (mydebug) DUMP(mySCU);
951 #endif
952         myMultiCurves.Append(mySCU);
953         // Stockage des parametres de la partie de MultiLine approximee:
954         // A ameliorer !! (bq trop de recopies)
955         Handle(TColStd_HArray1OfReal) ThePar = 
956           new TColStd_HArray1OfReal(Para.Lower(), Para.Upper());
957         for (i = Para.Lower(); i <= Para.Upper(); i++) {
958           ThePar->SetValue(i, Para(i));
959         }
960         myPar.Append(ThePar);
961         Tolers3d.Append(TheTol3d);
962         Tolers2d.Append(TheTol2d);
963         return Standard_True;
964       }
965     }
966
967     if (TheTol3d <= currenttol3d && TheTol2d <= currenttol2d) {
968       TheMultiCurve = mySCU;
969       currenttol3d = TheTol3d;
970       currenttol2d = TheTol2d;
971       myParameters = new TColStd_HArray1OfReal(Para.Lower(), Para.Upper());
972       for (i = Para.Lower(); i <= Para.Upper(); i++) {
973         myParameters->SetValue(i, Para(i));
974       }
975     }
976
977   }
978
979   return Standard_False;
980 }
981
982
983
984
985 Standard_Boolean  Approx_ComputeLine::ComputeCurve(const MultiLine& Line,
986                                       const Standard_Integer firstpt,
987                                       const Standard_Integer lastpt)
988 {
989   Standard_Integer i, j, nbP3d, nbP2d, deg;
990   gp_Vec V13d, V23d;
991   gp_Vec2d V12d, V22d;
992   gp_Pnt P1, P2;
993   gp_Pnt2d P12d, P22d;
994   Standard_Boolean Tangent1, Tangent2, mydone= Standard_False;
995 #ifdef OCCT_DEBUG
996   Standard_Boolean Parallel;
997 #endif
998   Standard_Integer myfirstpt = firstpt, mylastpt = lastpt;
999   Standard_Integer nbp = lastpt-firstpt+1, Kopt = 0;
1000   math_Vector Para(firstpt, lastpt);
1001
1002   Parameters(Line, firstpt, lastpt, Para);
1003
1004   nbP3d = LineTool::NbP3d(Line);
1005   nbP2d = LineTool::NbP2d(Line);
1006   Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
1007   if (nbP3d == 0) mynbP3d = 1 ;
1008   if (nbP2d == 0) mynbP2d = 1 ;
1009
1010
1011   TColgp_Array1OfVec tabV1(1, mynbP3d), tabV2(1, mynbP3d);
1012   TColgp_Array1OfPnt tabP1(1, mynbP3d), tabP2(1, mynbP3d), tabP(1, mynbP3d);
1013   TColgp_Array1OfVec2d tabV12d(1, mynbP2d), tabV22d(1, mynbP2d);
1014   TColgp_Array1OfPnt2d tabP12d(1, mynbP2d), tabP22d(1, mynbP2d), tabP2d(1, mynbP2d);
1015
1016   if (nbP3d != 0 && nbP2d != 0) {
1017     LineTool::Value(Line, myfirstpt,tabP1,tabP12d);
1018     LineTool::Value(Line, mylastpt,tabP2,tabP22d);
1019     Tangent1 = LineTool::Tangency(Line, myfirstpt,tabV1,tabV12d);
1020     Tangent2 = LineTool::Tangency(Line, mylastpt,tabV2,tabV22d);
1021   }
1022   else if (nbP2d != 0) {
1023     LineTool::Value(Line, myfirstpt,tabP12d);
1024     LineTool::Value(Line, mylastpt,tabP22d);
1025     Tangent1 = LineTool::Tangency(Line, myfirstpt, tabV12d);
1026     Tangent2 = LineTool::Tangency(Line, mylastpt, tabV22d);
1027   }
1028   else {
1029     LineTool::Value(Line, myfirstpt,tabP1);
1030     LineTool::Value(Line, mylastpt,tabP2);
1031     Tangent1 = LineTool::Tangency(Line, myfirstpt, tabV1);
1032     Tangent2 = LineTool::Tangency(Line, mylastpt, tabV2);
1033   }
1034
1035   if (Tangent1) Kopt++;  
1036   if (Tangent2) Kopt++;
1037
1038
1039   if (nbp == 2) {
1040     // S il n y a que 2 points, on verifie quand meme que les tangentes sont 
1041     // alignees.
1042 #ifdef OCCT_DEBUG
1043     Parallel = Standard_True;
1044 #endif
1045     if (Tangent1) {
1046       for (i = 1; i <= nbP3d; i++) {
1047         gp_Vec PVec(tabP1(i), tabP2(i));
1048         V13d = tabV1(i);
1049         if (!PVec.IsParallel(V13d, Precision::Angular())) {
1050 #ifdef OCCT_DEBUG
1051           Parallel = Standard_False;
1052 #endif
1053           break;
1054         }
1055       }
1056       for (i = 1; i <= nbP2d; i++) {
1057         gp_Vec2d PVec2d(tabP12d(i), tabP22d(i));
1058         V12d = tabV12d(i);
1059         if (!PVec2d.IsParallel(V12d, Precision::Angular())) {
1060 #ifdef OCCT_DEBUG
1061           Parallel = Standard_False;
1062 #endif
1063           break;
1064         }
1065       }
1066     }   
1067
1068     if (Tangent2) {
1069       for (i = 1; i <= nbP3d; i++) {
1070         gp_Vec PVec(tabP1(i), tabP2(i));
1071         V23d = tabV2(i);
1072         if (!PVec.IsParallel(V23d, Precision::Angular())) {
1073 #ifdef OCCT_DEBUG
1074           Parallel = Standard_False;
1075 #endif
1076           break;
1077         }
1078       }
1079       for (i = 1; i <= nbP2d; i++) {
1080         gp_Vec2d PVec2d(tabP12d(i), tabP22d(i));
1081         V22d = tabV22d(i);
1082         if (!PVec2d.IsParallel(V22d, Precision::Angular())) {
1083 #ifdef OCCT_DEBUG
1084           Parallel = Standard_False;
1085 #endif
1086           break;
1087         }
1088       }
1089     }
1090
1091 #ifdef OCCT_DEBUG
1092     if (!Parallel) {
1093       if (mydebug) cout <<"droite mais tangentes pas vraiment paralleles!!"<< endl;
1094     }
1095 #endif
1096     AppParCurves_MultiCurve mySCU(mydegremin+1);
1097     if (nbP3d != 0 && nbP2d != 0) {
1098       AppParCurves_MultiPoint MPole1(tabP1, tabP12d);
1099       AppParCurves_MultiPoint MPole2(tabP2, tabP22d);
1100       mySCU.SetValue(1, MPole1);
1101       mySCU.SetValue(mydegremin+1, MPole2);
1102       for (i = 2; i <= mydegremin; i++) {
1103         for (j = 1; j<= nbP3d; j++) {
1104           P1 = tabP1(j);
1105           P2 = tabP2(j);
1106           tabP(j).SetXYZ(P1.XYZ()+(i-1)*(P2.XYZ()-P1.XYZ())/mydegremin);
1107         }
1108         for (j = 1; j<= nbP2d; j++) {
1109           P12d = tabP12d(j);
1110           P22d = tabP22d(j);
1111           tabP2d(j).SetXY(P12d.XY()+(i-1)*(P22d.XY()-P12d.XY())/mydegremin);
1112         }
1113         AppParCurves_MultiPoint MPole(tabP, tabP2d);
1114         mySCU.SetValue(i, MPole);
1115       }
1116
1117     }
1118     else if (nbP3d != 0) {
1119       AppParCurves_MultiPoint MPole1(tabP1);
1120       AppParCurves_MultiPoint MPole2(tabP2);
1121       mySCU.SetValue(1, MPole1);
1122       mySCU.SetValue(mydegremin+1, MPole2);
1123       for (i = 2; i <= mydegremin; i++) {
1124         for (j = 1; j<= nbP3d; j++) {
1125           P1 = tabP1(j);
1126           P2 = tabP2(j);
1127           tabP(j).SetXYZ(P1.XYZ()+(i-1)*(P2.XYZ()-P1.XYZ())/mydegremin);
1128         }
1129         AppParCurves_MultiPoint MPole(tabP);
1130         mySCU.SetValue(i, MPole);
1131       }
1132     }
1133     else if (nbP2d != 0) {
1134       AppParCurves_MultiPoint MPole1(tabP12d);
1135       AppParCurves_MultiPoint MPole2(tabP22d);
1136       mySCU.SetValue(1, MPole1);
1137       mySCU.SetValue(mydegremin+1, MPole2);
1138       for (i = 2; i <= mydegremin; i++) {
1139         for (j = 1; j<= nbP2d; j++) {
1140           P12d = tabP12d(j);
1141           P22d = tabP22d(j);
1142           tabP2d(j).SetXY(P12d.XY()+(i-1)*(P22d.XY()-P12d.XY())/mydegremin);
1143         }
1144         AppParCurves_MultiPoint MPole(tabP2d);
1145         mySCU.SetValue(i, MPole);
1146       }
1147     }
1148     mydone = Standard_True;
1149     // Stockage de la multicurve approximee.
1150     tolreached = Standard_True;
1151 #ifdef OCCT_DEBUG
1152       if (mydebug) DUMP(mySCU);
1153 #endif
1154     myMultiCurves.Append(mySCU);
1155     Handle(TColStd_HArray1OfReal) ThePar = new TColStd_HArray1OfReal(Para.Lower(), Para.Upper());
1156     for (i = Para.Lower(); i <= Para.Upper(); i++) {
1157       ThePar->SetValue(i, Para(i));
1158     }
1159     myPar.Append(ThePar);
1160     Tolers3d.Append(Precision::Confusion());
1161     Tolers2d.Append(Precision::PConfusion());
1162     return mydone;
1163   }
1164
1165   // avec les tangentes.
1166   deg = nbp+1;
1167   AppParCurves_MultiCurve mySCU(deg+1);
1168   AppParCurves_Constraint Cons = AppParCurves_TangencyPoint;
1169   Standard_Real lambda1, lambda2;
1170   math_Vector V1(1, nbP3d*3+nbP2d*2);
1171   math_Vector V2(1, nbP3d*3+nbP2d*2);
1172   FirstTangencyVector(Line, myfirstpt, V1);
1173   lambda1 = SearchFirstLambda(Line, Para, V1, myfirstpt);
1174   
1175   LastTangencyVector(Line, mylastpt, V2);
1176   lambda2 = SearchLastLambda(Line, Para, V2, mylastpt);
1177   
1178   Approx_ParLeastSquareOfMyGradient 
1179     LSQ(Line, myfirstpt, mylastpt, 
1180         Cons, Cons, Para, deg+1);
1181   
1182   lambda1 = lambda1/deg;
1183   lambda2 = lambda2/deg;
1184   LSQ.Perform(Para, V1, V2, lambda1, lambda2);
1185   mydone = LSQ.IsDone();
1186   mySCU = LSQ.BezierValue();
1187   
1188   if (mydone) {
1189     Standard_Real Fv, TheTol3d, TheTol2d;
1190     LSQ.Error(Fv, TheTol3d, TheTol2d);  
1191
1192     // Stockage de la multicurve approximee.
1193     tolreached = Standard_True;
1194 #ifdef OCCT_DEBUG
1195       if (mydebug) DUMP(mySCU);
1196 #endif
1197     myMultiCurves.Append(mySCU);
1198     Handle(TColStd_HArray1OfReal) ThePar = 
1199       new TColStd_HArray1OfReal(Para.Lower(), Para.Upper());
1200     for (i = Para.Lower(); i <= Para.Upper(); i++) {
1201       ThePar->SetValue(i, Para(i));
1202     }
1203     myPar.Append(ThePar);
1204     Tolers3d.Append(TheTol3d);
1205     Tolers2d.Append(TheTol2d);
1206     return Standard_True;
1207   }
1208   return mydone;
1209 }
1210
1211
1212
1213 void Approx_ComputeLine::Init(const Standard_Integer degreemin,
1214                               const Standard_Integer degreemax,
1215                               const Standard_Real Tolerance3d,
1216                               const Standard_Real Tolerance2d,
1217                               const Standard_Integer NbIterations,
1218                               const Standard_Boolean cutting,
1219                               const Approx_ParametrizationType parametrization,
1220                               const Standard_Boolean Squares)
1221 {
1222   mydegremin = degreemin;
1223   mydegremax = degreemax;
1224   mytol3d = Tolerance3d;
1225   mytol2d = Tolerance2d;
1226   Par = parametrization;
1227   mysquares = Squares;
1228   mycut = cutting;
1229   myitermax = NbIterations;
1230 }
1231
1232
1233
1234 void Approx_ComputeLine::SetDegrees(const Standard_Integer degreemin,
1235                                     const Standard_Integer degreemax)
1236 {
1237   mydegremin = degreemin;
1238   mydegremax = degreemax;
1239 }
1240
1241
1242 void Approx_ComputeLine::SetTolerances(const Standard_Real Tolerance3d,
1243                                        const Standard_Real Tolerance2d)
1244 {
1245   mytol3d = Tolerance3d;
1246   mytol2d = Tolerance2d;
1247 }
1248
1249
1250 void Approx_ComputeLine::SetConstraints(const AppParCurves_Constraint FirstC,
1251                                         const AppParCurves_Constraint LastC)
1252 {
1253   myfirstC = FirstC;
1254   mylastC = LastC;
1255 }
1256
1257
1258
1259 Standard_Boolean Approx_ComputeLine::IsAllApproximated()
1260 const {
1261   return alldone;
1262 }
1263
1264 Standard_Boolean Approx_ComputeLine::IsToleranceReached()
1265 const {
1266   return tolreached;
1267 }
1268
1269 void Approx_ComputeLine::Error(const Standard_Integer Index,
1270                                Standard_Real& tol3d,
1271                                Standard_Real& tol2d) const
1272 {
1273   tol3d = Tolers3d.Value(Index);
1274   tol2d = Tolers2d.Value(Index);
1275 }
1276
1277 Approx_ParametrizationType Approx_ComputeLine::Parametrization() const
1278 {
1279   return Par;
1280 }