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