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