f1368cbdb2347ccaa41732d2bbe281c7f8853118
[occt.git] / src / ApproxInt / ApproxInt_Approx.gxx
1 // Created on: 1993-03-30
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22
23
24 #include <AppParCurves_Constraint.hxx>
25 #include <GeomAbs_SurfaceType.hxx>
26 #include <IntSurf_Quadric.hxx>
27 #include <gp_Trsf.hxx>
28 #include <gp_Trsf2d.hxx>
29 #include <IntSurf_PntOn2S.hxx>
30 #include <Precision.hxx>
31
32 const Standard_Integer LimRajout = 5;
33 const Standard_Integer NbPntMaxDecoupage = 30 ;
34 const Standard_Real RatioTol = 1.5 ;
35
36 static Standard_Real MINABS3(Standard_Real a, Standard_Real b,Standard_Real c) { 
37   if(a<0.0) a=-a;
38   if(b<0.0) b=-b;
39   if(c<0.0) c=-c;
40   if(a>c) a=c;
41   if(a>b) a=b;
42   return(a);
43 }
44
45 static Standard_Real MINABS4(Standard_Real a, Standard_Real b,Standard_Real c,Standard_Real d) { 
46   if(a<0.0) a=-a;
47   if(b<0.0) b=-b;
48   if(c<0.0) c=-c;
49   if(d<0.0) d=-d;
50   if(a>c) a=c;
51   if(a>b) a=b;
52   if(a>d) a=d;
53   return(a);
54 }
55
56 static void  ComputeTrsf3d(const Handle(TheWLine)& theline,
57                            Standard_Real& Xo, Standard_Real& Ax,
58                            Standard_Real& Yo, Standard_Real& Ay,
59                            Standard_Real& Zo, Standard_Real& Az) {
60  
61   Standard_Integer nbp = theline->NbPnts();
62   Standard_Real z0,z1,x0,x1,y0,y1;
63   z0=y0=x0=RealLast();
64   z1=y1=x1=RealFirst();
65   for(Standard_Integer i=1;i<=nbp;i++) { 
66     const gp_Pnt& P = theline->Point(i).Value();
67     Standard_Real  X = P.X();
68     Standard_Real  Y = P.Y();
69     Standard_Real  Z = P.Z();
70     if(X<x0) x0=X;
71     if(X>x1) x1=X;
72     if(Y<y0) y0=Y;
73     if(Y>y1) y1=Y;
74     if(Z<z0) z0=Z;
75     if(Z>z1) z1=Z;
76   }
77 //-deb-  cout << "ComputeTrsf3d -- NbPnt = " << nbp << endl ;
78 //-deb-  cout << "ComputeTrsf3d -- Xm = " << x0 << " Ym = " << y0 << " Zm = " << z0 << endl ;
79 //-deb-  cout << "ComputeTrsf3d -- XM = " << x1 << " YM = " << y1 << " ZM = " << z1 << endl ;
80   Standard_Real dx = x1-x0;
81   Standard_Real dy = y1-y0;
82   Standard_Real dz = z1-z0;
83   Standard_Real MaxD = dx; 
84   if(MaxD < dy) MaxD=dy;
85   if(MaxD < dz) MaxD=dz;
86   Standard_Real MaxDF = 0.01*MaxD;
87
88   //-- lbr le 22 fev99 : FPE 
89   if(MaxDF<1e-12) 
90     MaxDF=1.0;
91
92
93   if(dx > MaxDF) { Ax = 1.0 / dx;    Xo = -Ax * x0;  }
94   else {     Ax = 1.0/( MaxDF) ; Xo = -Ax*x0;   }
95   if(dy > MaxDF) { Ay = 1.0 / dy;    Yo = -Ay * y0;  }
96   else {     Ay = 1.0/( MaxDF); Yo = -Ay*y0;   }
97   if(dz > MaxDF) { Az = 1.0 / dz;    Zo = -Az * z0;     }
98   else {     Az = 1.0/(MaxDF); Zo = -Az*z0;   } 
99 }
100
101 static void  ComputeTrsf2d(const Handle(TheWLine)& theline,
102                            Standard_Real& Uo, Standard_Real& Au,
103                            Standard_Real& Vo, Standard_Real& Av,
104                            const Standard_Boolean onFirst,
105                            const Standard_Real UVResRatio = 1.) { 
106   Standard_Integer nbp = theline->NbPnts();
107   Standard_Real u0,u1,v0,v1;
108   u0 = v0 = RealLast();
109   u1 = v1 = RealFirst();
110   // pointer to a member-function
111   void (IntSurf_PntOn2S::* pfunc)(Standard_Real&,Standard_Real&) const;
112   if (onFirst)
113     pfunc = &IntSurf_PntOn2S::ParametersOnS1;
114   else
115     pfunc = &IntSurf_PntOn2S::ParametersOnS2;
116   for(Standard_Integer i=1;i<=nbp;i++) { 
117     const IntSurf_PntOn2S&  POn2S = theline->Point(i);
118     Standard_Real  U,V;
119     (POn2S.*pfunc)(U,V);
120     if(U<u0) u0=U;
121     if(U>u1) u1=U;
122     if(V<v0) v0=V;
123     if(V>v1) v1=V;
124   }
125
126   Standard_Real du = (u1-u0);
127   Standard_Real dv = (v1-v0);
128
129   if (UVResRatio > 1.)
130     du *= UVResRatio;
131   else if (UVResRatio < 1.)
132     dv /= UVResRatio;
133
134   Standard_Real MaxUV=du;
135   if(MaxUV<dv) MaxUV=dv;
136
137   Standard_Real MaxUVF=0.01*MaxUV;
138
139   //-- lbr le 22 fev 99 (FPE) 
140   if(MaxUVF<1e-12) 
141     MaxUVF=1.0;
142
143   if(du > MaxUVF) { Au = 1.0 / du;    Uo = -Au * u0;  }
144   else {     Au = 1.0/(MaxUVF); Uo = -Au*u0;  }
145   if(dv > MaxUVF) { Av = 1.0 / dv;    Vo = -Av * v0;  }
146   else {     Av = 1.0/(MaxUVF); Vo = -Av*v0;  }
147 }
148
149
150
151 ApproxInt_Approx::ApproxInt_Approx():
152        myComputeLine(4,
153                      8,
154                      0.001,
155                      0.001,
156                      5,
157                      Standard_True),
158        myComputeLineBezier(4,
159                            8,
160                            0.001,
161                            0.001,
162                            5,
163                            Standard_True)
164
165   myComputeLine.SetContinuity(2);
166   //-- myComputeLineBezier.SetContinuity(2);
167   myApproxBez = Standard_True;
168   
169   myRelativeTol = Standard_True ;
170   myNbPntMax = NbPntMaxDecoupage ;
171   myMinFactorXYZ = 0.0;
172   myMinFactorUV  = 0.0;
173   myTolReached3d = myTolReached2d = 0.;
174 }
175   
176
177 void ApproxInt_Approx::Perform(const Handle(TheWLine)& theline,
178                                const Standard_Boolean ApproxXYZ,
179                                const Standard_Boolean ApproxU1V1,
180                                const Standard_Boolean ApproxU2V2,
181                                const Standard_Integer indicemin,
182                                const Standard_Integer indicemax) { 
183   
184   myMinFactorXYZ = 0.0;
185   myMinFactorUV  = 0.0;
186   myTolReached3d = myTolReached2d = 0.;
187   
188   
189   Standard_Integer nbpntbez = indicemax-indicemin;
190   Standard_Integer nbpntmax = myNbPntMax;
191   Standard_Boolean OtherInter = Standard_False;
192   if(nbpntbez < LimRajout) 
193     myApproxBez = Standard_False;
194   else 
195     myApproxBez = Standard_True;
196   if(myApproxBez) {
197     myBezToBSpl.Reset();
198     Standard_Integer nbi = (indicemax-indicemin)/nbpntmax;
199     if(nbi>1)  { 
200       nbpntbez = (indicemax-indicemin)/nbi;
201     }
202   }
203   Standard_Integer imin = indicemin;
204   Standard_Integer imax = imin + nbpntbez;
205   myTolReached = Standard_True;
206   
207   Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v;
208   if(ApproxXYZ) { 
209     ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az);
210   }
211   else { 
212     Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;;
213   }
214   if(ApproxU1V1) { 
215     ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True);
216   }
217   else { 
218     U1o=V1o=0.0; A1u=A1v=1.0;
219   }
220   if(ApproxU2V2) { 
221     ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False);
222   }
223   else { 
224     U2o=V2o=0.0; A2u=A2v=1.0;
225   }
226   
227   //-deb-  cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax    << endl ; 
228   //-deb-  cout << "ApproxInt_Approx -- Tol3D    = " << myTol3d       << endl ; 
229   //-deb-  cout << "ApproxInt_Approx -- Tol2D    = " << myTol2d       << endl ; 
230   //-deb-  cout << "ApproxInt_Approx -- RelTol   = " << (myRelativeTol ? "RELATIVE" : "ABSOLUTE") << endl ; 
231   //-deb-  cout << "ApproxInt_Approx -- Xo = " << Xo << " Yo = " << Yo << " Zo = " << Zo << endl ;
232   //-deb-  cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ; 
233   //-deb-  cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ; 
234   //-deb-  cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ; 
235   
236   Standard_Real A3d = MINABS3(Ax,Ay,Az);
237   if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) { 
238     myMinFactorXYZ = A3d;
239   }
240   
241   Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v);
242   if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) { 
243     myMinFactorUV = A2d;
244   }
245   
246   Standard_Boolean cut=Standard_True;
247   Approx_ParametrizationType parametrization;
248   myComputeLineBezier.Parametrization(parametrization);
249
250   if(myRelativeTol==Standard_False) { 
251     
252     myComputeLine.Init(myDegMin,
253                        myDegMax,
254                        myTol3d*myMinFactorXYZ,
255                        myTol2d*myMinFactorUV,
256                        myNbIterMax,
257                        cut,
258                        parametrization);
259     myComputeLineBezier.Init(myDegMin,
260                              myDegMax,
261                              myTol3d*myMinFactorXYZ,
262                              myTol2d*myMinFactorUV,
263                              myNbIterMax,
264                              cut,
265                              parametrization);
266   }
267   
268   do {
269     ApproxInt_TheMultiLine myMultiLine(theline,
270                                        ((ApproxXYZ)? 1 : 0),
271                                        ((ApproxU1V1)? 1: 0) + ((ApproxU2V2)? 1: 0),
272                                        Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v,
273                                        ApproxU1V1,
274                                        imin,
275                                        imax);
276     
277     if(myApproxBez) { 
278       myComputeLineBezier.Perform(myMultiLine);
279       if (myComputeLineBezier.NbMultiCurves() == 0)
280         return;
281       myTolReached&=myComputeLineBezier.IsToleranceReached();
282     }
283     else { 
284       myComputeLine.Perform(myMultiLine);
285     }
286     UpdateTolReached();
287     
288     Standard_Integer indice3d,indice2d1,indice2d2;
289     indice3d = 1; 
290     indice2d1= 2;
291     indice2d2= 3;
292     if(!ApproxXYZ)  { indice2d1--; indice2d2--; } 
293     if(!ApproxU1V1) { indice2d2--; } 
294     if(ApproxXYZ) { 
295       Standard_Real ax,bx,ay,by,az,bz;
296       ax = 1.0/Ax;   bx = -Xo*ax;
297       ay = 1.0/Ay;   by = -Yo*ay;
298       az = 1.0/Az;   bz = -Zo*az;
299       if(myApproxBez) {
300         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
301           myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
302         }
303       }
304       else { 
305         myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
306       }
307     }
308     if(ApproxU1V1) { 
309       Standard_Real ax,bx,ay,by;
310       ax = 1.0/A1u;   bx = -U1o*ax;
311       ay = 1.0/A1v;   by = -V1o*ay;
312       if(myApproxBez) {
313         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
314           myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
315         }
316       }
317       else { 
318         myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
319       }
320     }
321     if(ApproxU2V2) { 
322       Standard_Real ax,bx,ay,by;
323       ax = 1.0/A2u;   bx = -U2o*ax;
324       ay = 1.0/A2v;   by = -V2o*ay;
325       if(myApproxBez) { 
326         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
327           myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
328         }
329       }
330       else { 
331         myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
332       }
333     }
334     
335     OtherInter = Standard_False;
336     if(myApproxBez) {
337       for(Standard_Integer nbmc = 1; 
338           nbmc <= myComputeLineBezier.NbMultiCurves() ;
339           nbmc++) { 
340         myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
341       }
342       if(imax<indicemax) { 
343         imin = imax;    
344         imax = imin+nbpntbez;
345         OtherInter = Standard_True;
346         if((indicemax-imax)<(nbpntbez/2)) { 
347           imax = indicemax;
348         }
349       }
350     }
351   }
352   while(OtherInter);
353   if(myApproxBez) { 
354     myBezToBSpl.Perform();
355   }
356 }
357
358 void ApproxInt_Approx::Perform(const ThePSurface& Surf1,
359                                const ThePSurface& Surf2,
360                                const Handle(TheWLine)& theline,
361                                const Standard_Boolean ApproxXYZ,
362                                const Standard_Boolean ApproxU1V1,
363                                const Standard_Boolean ApproxU2V2,
364                                const Standard_Integer indicemin,
365                                const Standard_Integer indicemax) {
366   myMinFactorXYZ = 0.0;
367   myMinFactorUV  = 0.0;
368   myTolReached3d = myTolReached2d = 0.;
369
370   GeomAbs_SurfaceType typeS1 = ThePSurfaceTool::GetType(Surf1);
371   GeomAbs_SurfaceType typeS2 = ThePSurfaceTool::GetType(Surf2);
372   if ((typeS1 != GeomAbs_Plane    &&
373        typeS1 != GeomAbs_Cylinder &&
374        typeS1 != GeomAbs_Sphere   &&
375        typeS1 != GeomAbs_Cone) 
376       &&
377       (typeS2 != GeomAbs_Plane    &&
378        typeS2 != GeomAbs_Cylinder &&
379        typeS2 != GeomAbs_Sphere   &&
380        typeS2 != GeomAbs_Cone)) { 
381     
382     //------------------------------------------------------------
383     //-- Construction du SvSurfaces
384     //------------------------------------------------------------
385     ApproxInt_ThePrmPrmSvSurfaces myPrmPrmSvSurfaces(Surf1,Surf2);
386     //------------------------------------------------------------
387     //-- Construction de la MultiLine
388     //------------------------------------------------------------
389     Standard_Integer nbpntbez = indicemax-indicemin;
390     Standard_Integer nbpntmax = myNbPntMax;
391     Standard_Boolean OtherInter = Standard_False;
392     
393     if(nbpntbez < LimRajout) 
394       myApproxBez = Standard_False;
395     else 
396       myApproxBez = Standard_True;
397     
398     Standard_Address ptrsvsurf = NULL;
399     Standard_Boolean cut = Standard_True;
400     if(nbpntbez < LimRajout) {   
401       cut = Standard_False;
402       //-- cout<<" ApproxInt : Nb de points = "<<nbpntbez<<" Pas de rajout "<<endl;
403     }
404     ptrsvsurf = &myPrmPrmSvSurfaces;
405     
406
407     if(myApproxBez) { 
408       myBezToBSpl.Reset();
409       Standard_Integer nbi = (indicemax-indicemin)/nbpntmax;
410       if(nbi>1)  { 
411         nbpntbez = (indicemax-indicemin)/nbi;
412       }
413     }
414     Standard_Integer imin = indicemin;
415     Standard_Integer imax = imin + nbpntbez;
416     myTolReached = Standard_True;
417
418
419     Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v;
420     if(ApproxXYZ) { 
421       ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az);
422     }
423     else { 
424       Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;;
425     }
426     if(ApproxU1V1) { 
427       Standard_Real UVResRatio = ThePSurfaceTool::UResolution(Surf1,1.)/
428                                  ThePSurfaceTool::VResolution(Surf1,1.);
429       ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True,UVResRatio);
430     }
431     else { 
432       U1o=V1o=0.0; A1u=A1v=1.0;
433     }      
434     if(ApproxU2V2) { 
435       Standard_Real UVResRatio = ThePSurfaceTool::UResolution(Surf2,1.)/
436                                  ThePSurfaceTool::VResolution(Surf2,1.);
437       ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False,UVResRatio);
438     }
439     else { 
440       U2o=V2o=0.0; A2u=A2v=1.0;
441     }
442
443 //-deb-  cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax    << endl ; 
444 //-deb-  cout << "ApproxInt_Approx -- Tol3D    = " << myTol3d       << endl ; 
445 //-deb-  cout << "ApproxInt_Approx -- Tol2D    = " << myTol2d       << endl ; 
446 //-deb-  cout << "ApproxInt_Approx -- RelTol   = " << (myRelativeTol ? "RELATIVE" : "ABSOLUTE") << endl ; 
447 //-deb-  cout << "ApproxInt_Approx -- Xo = " << Xo << " Yo = " << Yo << " Zo = " << Zo << endl ;
448 //-deb-  cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ; 
449 //-deb-  cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ; 
450 //-deb-  cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ; 
451     
452     
453     Standard_Real A3d = MINABS3(Ax,Ay,Az);
454     if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) { 
455       myMinFactorXYZ = A3d;
456     }
457     
458     Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v);
459     if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) { 
460       myMinFactorUV = A2d;
461     }
462     
463
464     Approx_ParametrizationType parametrization;
465     myComputeLineBezier.Parametrization(parametrization);
466
467     if(myRelativeTol==Standard_False) { 
468       myComputeLine.Init(myDegMin,
469                          myDegMax,
470                          myTol3d*myMinFactorXYZ,
471                          myTol2d*myMinFactorUV,
472                          myNbIterMax,
473                          cut,
474                          parametrization);
475       myComputeLineBezier.Init(myDegMin,
476                                myDegMax,
477                                myTol3d*myMinFactorXYZ,
478                                myTol2d*myMinFactorUV,
479                                myNbIterMax,
480                                cut,
481                                parametrization);
482     }
483     else { 
484       myComputeLine.Init(myDegMin,
485                          myDegMax,
486                          myTol3d,
487                          myTol2d,
488                          myNbIterMax,
489                          cut,
490                          parametrization);
491       myComputeLineBezier.Init(myDegMin,
492                                myDegMax,
493                                myTol3d,
494                                myTol2d,
495                                myNbIterMax,
496                                cut,
497                                parametrization);
498     }     
499
500
501
502     
503     do {
504       ApproxInt_TheMultiLine myMultiLine(theline,
505                                          ptrsvsurf,
506                                          ((ApproxXYZ)? 1 : 0),
507                                          ((ApproxU1V1)? 1: 0) + ((ApproxU2V2)? 1: 0),
508                                          Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v,
509                                          ApproxU1V1,
510                                          imin,
511                                          imax);
512       
513       if(myApproxBez) { 
514         myComputeLineBezier.Perform(myMultiLine);
515         if (myComputeLineBezier.NbMultiCurves() == 0)
516           return;
517         myTolReached&=myComputeLineBezier.IsToleranceReached();
518       }
519       else { 
520         myComputeLine.Perform(myMultiLine);
521       }
522       UpdateTolReached();
523       
524       Standard_Integer indice3d,indice2d1,indice2d2;
525       indice3d = 1; 
526       indice2d1= 2;
527       indice2d2= 3;
528       if(!ApproxXYZ)  { indice2d1--; indice2d2--; } 
529       if(!ApproxU1V1) { indice2d2--; } 
530       if(ApproxXYZ) { 
531         Standard_Real ax,bx,ay,by,az,bz;
532         ax = 1.0/Ax;   bx = -Xo*ax;
533         ay = 1.0/Ay;   by = -Yo*ay;
534         az = 1.0/Az;   bz = -Zo*az;
535         if(myApproxBez) { 
536           for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
537             myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
538           }
539         }
540         else { 
541           myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
542         }
543       }
544       if(ApproxU1V1) { 
545         Standard_Real ax,bx,ay,by;
546         ax = 1.0/A1u;   bx = -U1o*ax;
547         ay = 1.0/A1v;   by = -V1o*ay;
548         if(myApproxBez) { 
549           for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
550             myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
551           }
552         }
553         else { 
554           myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
555         }
556       }
557       if(ApproxU2V2) { 
558         Standard_Real ax,bx,ay,by;
559         ax = 1.0/A2u;   bx = -U2o*ax;
560         ay = 1.0/A2v;   by = -V2o*ay;
561         if(myApproxBez) { 
562           for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
563             myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
564           }
565         }
566         else { 
567           myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
568         }
569       }
570       OtherInter = Standard_False;
571       if(myApproxBez) { 
572         for(Standard_Integer nbmc = 1; 
573           nbmc <= myComputeLineBezier.NbMultiCurves() ;
574           nbmc++) { 
575           myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
576         }
577         if(imax<indicemax) { 
578           imin = imax;    
579           imax = imin+nbpntbez;
580           OtherInter = Standard_True;
581           if((indicemax-imax)<(nbpntbez/2)) { 
582             imax = indicemax;
583           }
584         }
585       }
586     }
587     while(OtherInter);
588     if(myApproxBez) { 
589       myBezToBSpl.Perform();
590     }
591
592   }
593   else { 
594     IntSurf_Quadric Quad;
595     Standard_Boolean SecondIsImplicit=Standard_False;
596     switch (typeS1) {
597       
598     case GeomAbs_Plane:
599       Quad.SetValue(ThePSurfaceTool::Plane(Surf1));
600       break;
601       
602     case GeomAbs_Cylinder:
603       Quad.SetValue(ThePSurfaceTool::Cylinder(Surf1));
604       break;
605       
606     case GeomAbs_Sphere:
607       Quad.SetValue(ThePSurfaceTool::Sphere(Surf1));
608       break;
609       
610     case GeomAbs_Cone:
611       Quad.SetValue(ThePSurfaceTool::Cone(Surf1));
612       break;
613
614     default:
615       {
616         SecondIsImplicit = Standard_True;
617         switch (typeS2) {
618         case GeomAbs_Plane:
619           Quad.SetValue(ThePSurfaceTool::Plane(Surf2));
620           break;
621           
622         case GeomAbs_Cylinder:
623           Quad.SetValue(ThePSurfaceTool::Cylinder(Surf2));
624           break;
625           
626         case GeomAbs_Sphere:
627           Quad.SetValue(ThePSurfaceTool::Sphere(Surf2));
628           break;
629           
630         case GeomAbs_Cone:
631           Quad.SetValue(ThePSurfaceTool::Cone(Surf2));
632           break;
633           
634         default:
635           break;
636         }
637       }
638       break;
639     } 
640     if(SecondIsImplicit) {
641       Perform(Surf1,Quad,theline,ApproxXYZ,ApproxU1V1,ApproxU2V2,indicemin,indicemax);
642     }
643     else {
644       Perform(Quad,Surf2,theline,ApproxXYZ,ApproxU1V1,ApproxU2V2,indicemin,indicemax);
645     }
646   }
647 }
648 //--------------------------------------------------------------------------------
649 void ApproxInt_Approx::SetParameters(const Standard_Real     Tol3d,
650                                      const Standard_Real     Tol2d,
651                                      const Standard_Integer  DegMin,
652                                      const Standard_Integer  DegMax,
653                                      const Standard_Integer  NbIterMax,
654                                      const Standard_Boolean  ApproxWithTangency,
655                                      const Approx_ParametrizationType Parametrization) {
656   myWithTangency = ApproxWithTangency;
657   myTol3d        = Tol3d / RatioTol;
658   myTol2d        = Tol2d / RatioTol;
659   myDegMin       = DegMin;
660   myDegMax       = DegMax;
661   myNbIterMax    = NbIterMax;
662   myComputeLine.Init(myDegMin,
663                      myDegMax,
664                      myTol3d,
665                      myTol2d,
666                      myNbIterMax,
667                      Standard_True,
668                      Parametrization);
669
670   if(!ApproxWithTangency) { 
671     myComputeLine.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint);
672   }
673   myComputeLineBezier.Init(myDegMin,
674                            myDegMax,
675                            myTol3d,
676                            myTol2d,
677                            myNbIterMax,
678                            Standard_True,
679                            Parametrization);
680   if(!ApproxWithTangency) { 
681     myComputeLineBezier.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint);
682   }
683   myApproxBez = Standard_True;
684 }
685
686 void ApproxInt_Approx::SetParameters(const Standard_Real     Tol3d,
687                                      const Standard_Real     Tol2d,
688                                      const Standard_Boolean  RelativeTol,
689                                      const Standard_Integer  DegMin,
690                                      const Standard_Integer  DegMax,
691                                      const Standard_Integer  NbIterMax,
692                                      const Standard_Integer  NbPntMax,
693                                      const Standard_Boolean  ApproxWithTangency,
694                                      const Approx_ParametrizationType Parametrization) 
695 {
696   myNbPntMax = NbPntMax ;
697   myRelativeTol = RelativeTol ;
698   SetParameters (Tol3d, Tol2d, DegMin, DegMax, NbIterMax, ApproxWithTangency, Parametrization) ;
699 }
700
701 //--------------------------------------------------------------------------------
702 void ApproxInt_Approx::Perform(const ThePSurface& PSurf,
703                                const TheISurface& ISurf,
704                                const Handle(TheWLine)& theline,
705                                const Standard_Boolean ApproxXYZ,
706                                const Standard_Boolean ApproxU1V1,
707                                const Standard_Boolean ApproxU2V2,
708                                const Standard_Integer indicemin,
709                                const Standard_Integer indicemax)
710 {
711   myMinFactorXYZ = 0.0;
712   myMinFactorUV  = 0.0;
713   myTolReached3d = myTolReached2d = 0.;
714   
715   ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces(PSurf,ISurf);
716   Standard_Integer nbpntbez = indicemax-indicemin;
717   Standard_Integer nbpntmax = myNbPntMax;
718   Standard_Boolean OtherInter = Standard_False;
719   if(nbpntbez < LimRajout) 
720     myApproxBez = Standard_False;
721   else 
722     myApproxBez = Standard_True;
723   
724   Standard_Address ptrsvsurf = NULL;
725   Standard_Boolean cut = Standard_True;
726   if(nbpntbez < LimRajout) {   
727     cut = Standard_False;
728     //-- cout<<" ApproxInt : Nb de points = "<<nbpntbez<<" Pas de rajout "<<endl;
729   }
730
731
732   Approx_ParametrizationType parametrization;
733   myComputeLineBezier.Parametrization(parametrization);
734
735
736   ptrsvsurf = &myImpPrmSvSurfaces;  
737   myComputeLine.Init(myDegMin,
738                      myDegMax,
739                      myTol3d,
740                      myTol2d,
741                      myNbIterMax,
742                      cut,
743                      parametrization);
744
745   myComputeLineBezier.Init(myDegMin,
746                            myDegMax,
747                            myTol3d,
748                            myTol2d,
749                            myNbIterMax,
750                            cut,
751                            parametrization);
752   if(myApproxBez) { 
753     myBezToBSpl.Reset();
754     Standard_Integer nbi = (indicemax-indicemin)/nbpntmax;
755     if(nbi>1)  { 
756       nbpntbez = (indicemax-indicemin)/nbi;
757     }
758   }
759   Standard_Integer imin = indicemin;
760   Standard_Integer imax = imin + nbpntbez;
761   myTolReached = Standard_True;
762   Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v;
763   if(ApproxXYZ) { 
764     ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az);
765   }
766   else { 
767     Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;;
768   }
769   if(ApproxU1V1) { 
770     Standard_Real UVResRatio = ThePSurfaceTool::UResolution(PSurf,1.)/
771                                ThePSurfaceTool::VResolution(PSurf,1.);
772     ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True,UVResRatio);
773   }
774   else { 
775     U1o=V1o=0.0; A1u=A1v=1.0;
776   }
777   if(ApproxU2V2) { 
778     ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False);
779   }
780   else { 
781     U2o=V2o=0.0; A2u=A2v=1.0;
782   }
783   
784   //-deb-  cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax    << endl ; 
785   //-deb-  cout << "ApproxInt_Approx -- Tol3D    = " << myTol3d       << endl ; 
786   //-deb-  cout << "ApproxInt_Approx -- Tol2D    = " << myTol2d       << endl ; 
787   //-deb-  cout << "ApproxInt_Approx -- RelTol   = " << (myRelativeTol ? "RELATIVE" : "ABSOLUTE") << endl ; 
788   //-deb-  cout << "ApproxInt_Approx -- Xo = " << Xo << " Yo = " << Yo << " Zo = " << Zo << endl ;
789   //-deb-  cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ; 
790   //-deb-  cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ; 
791   //-deb-  cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ; 
792   
793   
794   Standard_Real A3d = MINABS3(Ax,Ay,Az);
795   if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) { 
796     myMinFactorXYZ = A3d;
797   }
798   
799   Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v);
800   if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) { 
801     myMinFactorUV = A2d;
802   }
803   
804   myComputeLineBezier.Parametrization(parametrization);
805
806   if(myRelativeTol==Standard_False) { 
807     myComputeLine.Init(myDegMin,
808                        myDegMax,
809                        myTol3d*myMinFactorXYZ,
810                        myTol2d*myMinFactorUV,
811                        myNbIterMax,
812                        cut,
813                        parametrization);
814     myComputeLineBezier.Init(myDegMin,
815                              myDegMax,
816                              myTol3d*myMinFactorXYZ,
817                              myTol2d*myMinFactorUV,
818                              myNbIterMax,
819                              cut,
820                              parametrization);
821   }
822   else { 
823     myComputeLine.Init(myDegMin,
824                        myDegMax,
825                        myTol3d,
826                        myTol2d,
827                        myNbIterMax,
828                        cut,
829                        parametrization);
830     myComputeLineBezier.Init(myDegMin,
831                              myDegMax,
832                              myTol3d,
833                              myTol2d,
834                              myNbIterMax,
835                              cut,
836                              parametrization);
837   }     
838   
839   
840   do {
841     
842     ApproxInt_TheMultiLine myMultiLine(theline,
843                                        ptrsvsurf,
844                                        ((ApproxXYZ)? 1 : 0),
845                                        ((ApproxU1V1)? 1: 0) + ((ApproxU2V2)? 1: 0),
846                                        Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v,
847                                        ApproxU1V1,
848                                        imin,
849                                        imax);
850     if(myApproxBez) { 
851       myComputeLineBezier.Perform(myMultiLine);
852       if (myComputeLineBezier.NbMultiCurves() == 0)
853         return;
854       myTolReached&=myComputeLineBezier.IsToleranceReached();
855     }
856     else { 
857       myComputeLine.Perform(myMultiLine);
858     }
859     UpdateTolReached();
860     Standard_Integer indice3d,indice2d1,indice2d2;
861     indice3d = 1; 
862     indice2d1= 2;
863     indice2d2= 3;
864     if(!ApproxXYZ)  { indice2d1--; indice2d2--; } 
865     if(!ApproxU1V1) { indice2d2--; } 
866     if(ApproxXYZ) { 
867       Standard_Real ax,bx,ay,by,az,bz;
868       ax = 1.0/Ax;   bx = -Xo*ax;
869       ay = 1.0/Ay;   by = -Yo*ay;
870       az = 1.0/Az;   bz = -Zo*az;
871       if(myApproxBez) { 
872         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
873           myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
874         }
875       }
876       else { 
877         myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
878       }
879     }
880     if(ApproxU1V1) { 
881       Standard_Real ax,bx,ay,by;
882       ax = 1.0/A1u;   bx = -U1o*ax;
883       ay = 1.0/A1v;   by = -V1o*ay;
884       if(myApproxBez) { 
885         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
886           myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
887         }
888       }
889       else { 
890         myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
891       }
892     }
893     if(ApproxU2V2) { 
894       Standard_Real ax,bx,ay,by;
895       ax = 1.0/A2u;   bx = -U2o*ax;
896       ay = 1.0/A2v;   by = -V2o*ay;
897       if(myApproxBez) { 
898         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
899           myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
900         }
901       }
902       else { 
903         myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
904       }
905     }
906     OtherInter = Standard_False;
907     if(myApproxBez) { 
908       for(Standard_Integer nbmc = 1; 
909           nbmc <= myComputeLineBezier.NbMultiCurves() ;
910           nbmc++) { 
911         myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
912       }
913       if(imax<indicemax) { 
914         imin = imax;    
915         imax = imin+nbpntbez;
916         OtherInter = Standard_True;
917         if((indicemax-imax)<(nbpntbez/2)) { 
918           imax = indicemax;
919         }
920       }
921     }
922   }
923   while(OtherInter);
924   if(myApproxBez) { 
925     myBezToBSpl.Perform();
926   }
927 }
928 //--------------------------------------------------------------------------------
929 void ApproxInt_Approx::Perform(const TheISurface& ISurf,
930                                const ThePSurface& PSurf,
931                                const Handle(TheWLine)& theline,
932                                const Standard_Boolean ApproxXYZ,
933                                const Standard_Boolean ApproxU1V1,
934                                const Standard_Boolean ApproxU2V2,
935                                const Standard_Integer indicemin,
936                                const Standard_Integer indicemax)
937 {
938
939   myMinFactorXYZ = 0.0;
940   myMinFactorUV  = 0.0;
941   myTolReached3d = myTolReached2d = 0.;
942   
943   ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces(ISurf,PSurf);
944   Standard_Integer nbpntbez = indicemax-indicemin;
945   
946   Standard_Address ptrsvsurf = NULL;
947   Standard_Boolean cut = Standard_True;
948   if(nbpntbez < LimRajout) 
949     myApproxBez = Standard_False;
950   else 
951     myApproxBez = Standard_True;
952   
953   if(nbpntbez < LimRajout) {   
954     cut = Standard_False;
955     //-- cout<<" ApproxInt : Nb de points = "<<nbpntbez<<" Pas de rajout "<<endl;
956   }
957   ptrsvsurf = &myImpPrmSvSurfaces;
958   
959   if(nbpntbez < LimRajout) myApproxBez = Standard_False;
960   
961   Standard_Integer nbpntmax = myNbPntMax;
962   Standard_Boolean OtherInter = Standard_False;
963   if(myApproxBez) { 
964     myBezToBSpl.Reset();
965     Standard_Integer nbi = (indicemax-indicemin)/nbpntmax;
966     if(nbi>1)  { 
967       nbpntbez = (indicemax-indicemin)/nbi;
968     }
969   }
970   Standard_Integer imin = indicemin;
971   Standard_Integer imax = imin + nbpntbez;
972   myTolReached = Standard_True;
973   
974   Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v;
975   if(ApproxXYZ) { 
976     ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az);
977   }
978   else { 
979     Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;;
980   }
981   if(ApproxU1V1) { 
982     ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True);
983   }
984   else { 
985     U1o=V1o=0.0; A1u=A1v=1.0;
986   }
987   if(ApproxU2V2) { 
988     Standard_Real UVResRatio = ThePSurfaceTool::UResolution(PSurf,1.)/
989                                ThePSurfaceTool::VResolution(PSurf,1.);
990     ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False,UVResRatio);
991   }
992   else { 
993     U2o=V2o=0.0; A2u=A2v=1.0;
994   }
995   
996   //-deb-  cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax    << endl ; 
997   //-deb-  cout << "ApproxInt_Approx -- Tol3D    = " << myTol3d       << endl ; 
998   //-deb-  cout << "ApproxInt_Approx -- Tol2D    = " << myTol2d       << endl ; 
999   //-deb-  cout << "ApproxInt_Approx -- RelTol   = " << (myRelativeTol ? "RELATIVE" : "ABSOLUTE") << endl ; 
1000   //-deb-  cout << "ApproxInt_Approx -- Xo = " << Xo << " Yo = " << Yo << " Zo = " << Zo << endl ;
1001   //-deb-  cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ; 
1002   //-deb-  cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ; 
1003   //-deb-  cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ; 
1004   
1005   
1006   Standard_Real A3d = MINABS3(Ax,Ay,Az);
1007   if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) { 
1008     myMinFactorXYZ = A3d;
1009   }
1010   
1011   Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v);
1012   if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) { 
1013     myMinFactorUV = A2d;
1014   }
1015
1016   Approx_ParametrizationType parametrization;
1017   myComputeLineBezier.Parametrization(parametrization);
1018   
1019   
1020   if(myRelativeTol==Standard_False) { 
1021     myComputeLine.Init(myDegMin,
1022                        myDegMax,
1023                        myTol3d*myMinFactorXYZ,
1024                        myTol2d*myMinFactorUV,
1025                        myNbIterMax,
1026                        cut,
1027                        parametrization);
1028     myComputeLineBezier.Init(myDegMin,
1029                              myDegMax,
1030                              myTol3d*myMinFactorXYZ,
1031                              myTol2d*myMinFactorUV,
1032                              myNbIterMax,
1033                              cut,
1034                              parametrization);
1035   }
1036   else { 
1037     myComputeLine.Init(myDegMin,
1038                        myDegMax,
1039                        myTol3d,
1040                        myTol2d,
1041                        myNbIterMax,
1042                        cut,
1043                        parametrization);
1044     myComputeLineBezier.Init(myDegMin,
1045                              myDegMax,
1046                              myTol3d,
1047                              myTol2d,
1048                              myNbIterMax,
1049                              cut,
1050                              parametrization);
1051   }     
1052   
1053   
1054   
1055   do {
1056     
1057     ApproxInt_TheMultiLine myMultiLine(theline,
1058                                        ptrsvsurf,
1059                                        ((ApproxXYZ)? 1 : 0),
1060                                        ((ApproxU1V1)? 1: 0) + ((ApproxU2V2)? 1: 0),
1061                                        Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v,
1062                                        ApproxU1V1,
1063                                        imin,
1064                                        imax);
1065     if(myApproxBez) { 
1066       myComputeLineBezier.Perform(myMultiLine);
1067       if (myComputeLineBezier.NbMultiCurves() == 0)
1068         return;
1069       myTolReached&=myComputeLineBezier.IsToleranceReached();
1070     }
1071     else { 
1072       myComputeLine.Perform(myMultiLine);
1073     }
1074     UpdateTolReached();
1075     
1076     Standard_Integer indice3d,indice2d1,indice2d2;
1077     indice3d = 1; 
1078     indice2d1= 2;
1079     indice2d2= 3;
1080     if(!ApproxXYZ)  { indice2d1--; indice2d2--; } 
1081     if(!ApproxU1V1) { indice2d2--; } 
1082     if(ApproxXYZ) { 
1083       Standard_Real ax,bx,ay,by,az,bz;
1084       ax = 1.0/Ax;   bx = -Xo*ax;
1085       ay = 1.0/Ay;   by = -Yo*ay;
1086       az = 1.0/Az;   bz = -Zo*az;
1087       if(myApproxBez) { 
1088         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
1089           myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
1090         }
1091       }
1092       else { 
1093         myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
1094       }
1095     }
1096     if(ApproxU1V1) { 
1097       Standard_Real ax,bx,ay,by;
1098       ax = 1.0/A1u;   bx = -U1o*ax;
1099       ay = 1.0/A1v;   by = -V1o*ay;
1100       if(myApproxBez) { 
1101         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
1102           myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
1103         }
1104       }
1105       else { 
1106         myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
1107       }
1108     }
1109     if(ApproxU2V2) { 
1110       Standard_Real ax,bx,ay,by;
1111       ax = 1.0/A2u;   bx = -U2o*ax;
1112       ay = 1.0/A2v;   by = -V2o*ay;
1113       if(myApproxBez) { 
1114         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
1115           myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
1116         }
1117       }
1118       else { 
1119         myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
1120       }
1121     }
1122     OtherInter = Standard_False;
1123     if(myApproxBez) { 
1124       for(Standard_Integer nbmc = 1; 
1125           nbmc <= myComputeLineBezier.NbMultiCurves() ;
1126           nbmc++) { 
1127         myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
1128       }
1129       if(imax<indicemax) { 
1130         imin = imax;    
1131         imax = imin+nbpntbez;
1132         OtherInter = Standard_True;
1133         if((indicemax-imax)<(nbpntbez/2)) { 
1134           imax = indicemax;
1135         }
1136       }
1137     } 
1138   }
1139   while(OtherInter); 
1140   if(myApproxBez) { 
1141     myBezToBSpl.Perform();
1142   }
1143 }
1144 //--------------------------------------------------------------------------------
1145 Standard_Integer ApproxInt_Approx::NbMultiCurves() const { 
1146   //  return(myComputeLine.NbMultiCurves());
1147   return 1;
1148 }
1149 //--------------------------------------------------------------------------------
1150 void ApproxInt_Approx::UpdateTolReached() {
1151
1152   if (myApproxBez) {
1153     Standard_Integer ICur ;
1154     Standard_Integer NbCurves = myComputeLineBezier.NbMultiCurves() ;
1155     for (ICur = 1 ; ICur <= NbCurves ; ICur++) {
1156       Standard_Real Tol3D, Tol2D ;
1157       myComputeLineBezier.Error (ICur, Tol3D, Tol2D) ;
1158       myTolReached3d = Max(myTolReached3d, Tol3D);
1159       myTolReached2d = Max(myTolReached2d, Tol2D);
1160     }
1161   } else {
1162     myComputeLine.Error (myTolReached3d, myTolReached2d);
1163   }
1164 }
1165 //--------------------------------------------------------------------------------
1166 Standard_Real ApproxInt_Approx::TolReached3d() const { 
1167
1168   Standard_Real TheTol3D = RatioTol * myTolReached3d ;
1169   //modified by NIZNHY-PKV Mon Aug 27 14:21:33 2007f
1170   //if (myMinFactorXYZ)
1171   //TheTol3D = TheTol3D / myMinFactorXYZ ;
1172   if (myMinFactorXYZ>1.5e-7) {
1173     TheTol3D = TheTol3D / myMinFactorXYZ ;
1174   }
1175   //modified by NIZNHY-PKV Mon Aug 27 14:21:50 2007t
1176   return TheTol3D ;
1177 }
1178 //--------------------------------------------------------------------------------
1179 Standard_Real ApproxInt_Approx::TolReached2d() const {
1180
1181   Standard_Real TheTol2D = RatioTol * myTolReached2d ;
1182   //modified by NIZNHY-PKV Mon Aug 27 14:20:50 2007f
1183   //if (myMinFactorUV)
1184   //TheTol2D = TheTol2D / myMinFactorUV ;
1185   if (myMinFactorUV>1.5e-7) {
1186     TheTol2D = TheTol2D / myMinFactorUV ;
1187   }
1188   //modified by NIZNHY-PKV Mon Aug 27 14:20:55 2007t
1189   return TheTol2D ;
1190 }
1191 //--------------------------------------------------------------------------------
1192 Standard_Boolean ApproxInt_Approx::IsDone() const { 
1193   if(myApproxBez) { 
1194     return(myComputeLineBezier.NbMultiCurves() > 0);
1195                            //-- Lorsque la tolerance n est pas atteinte et qu il 
1196                            //-- faudrait rajouter des points sur la ligne
1197                            //-- les approx sortent avec la meilleure tolerance
1198                            //-- atteinte.  ( Pas de rajout de points ds cette version)
1199     //-- return(myTolReached);
1200   }
1201   else { 
1202     return(myComputeLine.IsToleranceReached());
1203   }
1204 }
1205 //--------------------------------------------------------------------------------
1206 const AppParCurves_MultiBSpCurve& ApproxInt_Approx::Value(const Standard_Integer ) const { 
1207   if(myApproxBez) { 
1208     return(myBezToBSpl.Value());
1209   }
1210   else { 
1211     return(myComputeLine.Value());
1212   }
1213 }