6c40c6d163d3571dcef8c2d52e7d803425547633
[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       { 
337         imin = imax;    
338         imax = imin+nbpntbez;
339         OtherInter = Standard_True;
340         if((indicemax-imax)<(nbpntbez/2))
341         {
342           imax = indicemax;
343         }
344         imax = CorrectFinishIdx(imin, imax, theline);
345       }
346     }
347   }
348   while(OtherInter);
349   if(myApproxBez) { 
350     myBezToBSpl.Perform();
351   }
352 }
353
354 void ApproxInt_Approx::Perform(const ThePSurface& Surf1,
355                                const ThePSurface& Surf2,
356                                const Handle(TheWLine)& theline,
357                                const Standard_Boolean ApproxXYZ,
358                                const Standard_Boolean ApproxU1V1,
359                                const Standard_Boolean ApproxU2V2,
360                                const Standard_Integer indicemin,
361                                const Standard_Integer indicemax) {
362   myMinFactorXYZ = 0.0;
363   myMinFactorUV  = 0.0;
364   myTolReached3d = myTolReached2d = 0.;
365
366   GeomAbs_SurfaceType typeS1 = ThePSurfaceTool::GetType(Surf1);
367   GeomAbs_SurfaceType typeS2 = ThePSurfaceTool::GetType(Surf2);
368   if ((typeS1 != GeomAbs_Plane    &&
369        typeS1 != GeomAbs_Cylinder &&
370        typeS1 != GeomAbs_Sphere   &&
371        typeS1 != GeomAbs_Cone) 
372       &&
373       (typeS2 != GeomAbs_Plane    &&
374        typeS2 != GeomAbs_Cylinder &&
375        typeS2 != GeomAbs_Sphere   &&
376        typeS2 != GeomAbs_Cone)) { 
377     
378     //------------------------------------------------------------
379     //-- Construction du SvSurfaces
380     //------------------------------------------------------------
381     ApproxInt_ThePrmPrmSvSurfaces myPrmPrmSvSurfaces(Surf1,Surf2);
382     //------------------------------------------------------------
383     //-- Construction de la MultiLine
384     //------------------------------------------------------------
385     Standard_Integer nbpntbez = indicemax-indicemin;
386     Standard_Integer nbpntmax = myNbPntMax;
387     Standard_Boolean OtherInter = Standard_False;
388     
389     if(nbpntbez < LimRajout) 
390       myApproxBez = Standard_False;
391     else 
392       myApproxBez = Standard_True;
393     
394     Standard_Address ptrsvsurf = NULL;
395     Standard_Boolean cut = Standard_True;
396     if(nbpntbez < LimRajout) {   
397       cut = Standard_False;
398       //-- cout<<" ApproxInt : Nb de points = "<<nbpntbez<<" Pas de rajout "<<endl;
399     }
400     ptrsvsurf = &myPrmPrmSvSurfaces;
401     
402
403     if(myApproxBez) { 
404       myBezToBSpl.Reset();
405       Standard_Integer nbi = (indicemax-indicemin)/nbpntmax;
406       if(nbi>1)  { 
407         nbpntbez = (indicemax-indicemin)/nbi;
408       }
409     }
410     Standard_Integer imin = indicemin;
411     Standard_Integer imax = imin + nbpntbez;
412     myTolReached = Standard_True;
413
414
415     Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v;
416     if(ApproxXYZ) { 
417       ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az);
418     }
419     else { 
420       Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;;
421     }
422     if(ApproxU1V1) { 
423       Standard_Real UVResRatio = ThePSurfaceTool::UResolution(Surf1,1.)/
424                                  ThePSurfaceTool::VResolution(Surf1,1.);
425       ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True,UVResRatio);
426     }
427     else { 
428       U1o=V1o=0.0; A1u=A1v=1.0;
429     }      
430     if(ApproxU2V2) { 
431       Standard_Real UVResRatio = ThePSurfaceTool::UResolution(Surf2,1.)/
432                                  ThePSurfaceTool::VResolution(Surf2,1.);
433       ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False,UVResRatio);
434     }
435     else { 
436       U2o=V2o=0.0; A2u=A2v=1.0;
437     }
438
439 //-deb-  cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax    << endl ; 
440 //-deb-  cout << "ApproxInt_Approx -- Tol3D    = " << myTol3d       << endl ; 
441 //-deb-  cout << "ApproxInt_Approx -- Tol2D    = " << myTol2d       << endl ; 
442 //-deb-  cout << "ApproxInt_Approx -- RelTol   = " << (myRelativeTol ? "RELATIVE" : "ABSOLUTE") << endl ; 
443 //-deb-  cout << "ApproxInt_Approx -- Xo = " << Xo << " Yo = " << Yo << " Zo = " << Zo << endl ;
444 //-deb-  cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ; 
445 //-deb-  cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ; 
446 //-deb-  cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ; 
447     
448     
449     Standard_Real A3d = MINABS3(Ax,Ay,Az);
450     if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) { 
451       myMinFactorXYZ = A3d;
452     }
453     
454     Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v);
455     if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) { 
456       myMinFactorUV = A2d;
457     }
458     
459
460     Approx_ParametrizationType parametrization;
461     myComputeLineBezier.Parametrization(parametrization);
462
463     if(myRelativeTol==Standard_False) { 
464       myComputeLine.Init(myDegMin,
465                          myDegMax,
466                          myTol3d*myMinFactorXYZ,
467                          myTol2d*myMinFactorUV,
468                          myNbIterMax,
469                          cut,
470                          parametrization);
471       myComputeLineBezier.Init(myDegMin,
472                                myDegMax,
473                                myTol3d*myMinFactorXYZ,
474                                myTol2d*myMinFactorUV,
475                                myNbIterMax,
476                                cut,
477                                parametrization);
478     }
479     else { 
480       myComputeLine.Init(myDegMin,
481                          myDegMax,
482                          myTol3d,
483                          myTol2d,
484                          myNbIterMax,
485                          cut,
486                          parametrization);
487       myComputeLineBezier.Init(myDegMin,
488                                myDegMax,
489                                myTol3d,
490                                myTol2d,
491                                myNbIterMax,
492                                cut,
493                                parametrization);
494     }     
495
496
497
498     
499     do {
500       ApproxInt_TheMultiLine myMultiLine(theline,
501                                          ptrsvsurf,
502                                          ((ApproxXYZ)? 1 : 0),
503                                          ((ApproxU1V1)? 1: 0) + ((ApproxU2V2)? 1: 0),
504                                          Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v,
505                                          ApproxU1V1,
506                                          imin,
507                                          imax);
508       
509       if(myApproxBez) { 
510         myComputeLineBezier.Perform(myMultiLine);
511         if (myComputeLineBezier.NbMultiCurves() == 0)
512           return;
513         myTolReached&=myComputeLineBezier.IsToleranceReached();
514       }
515       else { 
516         myComputeLine.Perform(myMultiLine);
517       }
518       UpdateTolReached();
519       
520       Standard_Integer indice3d,indice2d1,indice2d2;
521       indice3d = 1; 
522       indice2d1= 2;
523       indice2d2= 3;
524       if(!ApproxXYZ)  { indice2d1--; indice2d2--; } 
525       if(!ApproxU1V1) { indice2d2--; } 
526       if(ApproxXYZ) { 
527         Standard_Real ax,bx,ay,by,az,bz;
528         ax = 1.0/Ax;   bx = -Xo*ax;
529         ay = 1.0/Ay;   by = -Yo*ay;
530         az = 1.0/Az;   bz = -Zo*az;
531         if(myApproxBez) { 
532           for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
533             myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
534           }
535         }
536         else { 
537           myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
538         }
539       }
540       if(ApproxU1V1) { 
541         Standard_Real ax,bx,ay,by;
542         ax = 1.0/A1u;   bx = -U1o*ax;
543         ay = 1.0/A1v;   by = -V1o*ay;
544         if(myApproxBez) { 
545           for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
546             myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
547           }
548         }
549         else { 
550           myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
551         }
552       }
553       if(ApproxU2V2) { 
554         Standard_Real ax,bx,ay,by;
555         ax = 1.0/A2u;   bx = -U2o*ax;
556         ay = 1.0/A2v;   by = -V2o*ay;
557         if(myApproxBez) { 
558           for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
559             myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
560           }
561         }
562         else { 
563           myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
564         }
565       }
566       OtherInter = Standard_False;
567       if(myApproxBez) { 
568         for(Standard_Integer nbmc = 1; 
569           nbmc <= myComputeLineBezier.NbMultiCurves() ;
570           nbmc++) { 
571           myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
572         }
573         if(imax<indicemax)
574         {
575           imin = imax;
576           imax = imin+nbpntbez;
577           OtherInter = Standard_True;
578           if((indicemax-imax)<(nbpntbez/2))
579           {
580             imax = indicemax;
581           }
582           imax = CorrectFinishIdx(imin, imax, theline);
583         }
584       }
585     }
586     while(OtherInter);
587     if(myApproxBez) { 
588       myBezToBSpl.Perform();
589     }
590
591   }
592   else { 
593     IntSurf_Quadric Quad;
594     Standard_Boolean SecondIsImplicit=Standard_False;
595     switch (typeS1) {
596       
597     case GeomAbs_Plane:
598       Quad.SetValue(ThePSurfaceTool::Plane(Surf1));
599       break;
600       
601     case GeomAbs_Cylinder:
602       Quad.SetValue(ThePSurfaceTool::Cylinder(Surf1));
603       break;
604       
605     case GeomAbs_Sphere:
606       Quad.SetValue(ThePSurfaceTool::Sphere(Surf1));
607       break;
608       
609     case GeomAbs_Cone:
610       Quad.SetValue(ThePSurfaceTool::Cone(Surf1));
611       break;
612
613     default:
614       {
615         SecondIsImplicit = Standard_True;
616         switch (typeS2) {
617         case GeomAbs_Plane:
618           Quad.SetValue(ThePSurfaceTool::Plane(Surf2));
619           break;
620           
621         case GeomAbs_Cylinder:
622           Quad.SetValue(ThePSurfaceTool::Cylinder(Surf2));
623           break;
624           
625         case GeomAbs_Sphere:
626           Quad.SetValue(ThePSurfaceTool::Sphere(Surf2));
627           break;
628           
629         case GeomAbs_Cone:
630           Quad.SetValue(ThePSurfaceTool::Cone(Surf2));
631           break;
632           
633         default:
634           break;
635         }
636       }
637       break;
638     } 
639     if(SecondIsImplicit) {
640       Perform(Surf1,Quad,theline,ApproxXYZ,ApproxU1V1,ApproxU2V2,indicemin,indicemax);
641     }
642     else {
643       Perform(Quad,Surf2,theline,ApproxXYZ,ApproxU1V1,ApproxU2V2,indicemin,indicemax);
644     }
645   }
646 }
647 //--------------------------------------------------------------------------------
648 void ApproxInt_Approx::SetParameters(const Standard_Real     Tol3d,
649                                      const Standard_Real     Tol2d,
650                                      const Standard_Integer  DegMin,
651                                      const Standard_Integer  DegMax,
652                                      const Standard_Integer  NbIterMax,
653                                      const Standard_Boolean  ApproxWithTangency,
654                                      const Approx_ParametrizationType Parametrization) {
655   myWithTangency = ApproxWithTangency;
656   myTol3d        = Tol3d / RatioTol;
657   myTol2d        = Tol2d / RatioTol;
658   myDegMin       = DegMin;
659   myDegMax       = DegMax;
660   myNbIterMax    = NbIterMax;
661   myComputeLine.Init(myDegMin,
662                      myDegMax,
663                      myTol3d,
664                      myTol2d,
665                      myNbIterMax,
666                      Standard_True,
667                      Parametrization);
668
669   if(!ApproxWithTangency) { 
670     myComputeLine.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint);
671   }
672   myComputeLineBezier.Init(myDegMin,
673                            myDegMax,
674                            myTol3d,
675                            myTol2d,
676                            myNbIterMax,
677                            Standard_True,
678                            Parametrization);
679   if(!ApproxWithTangency) { 
680     myComputeLineBezier.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint);
681   }
682   myApproxBez = Standard_True;
683 }
684
685 void ApproxInt_Approx::SetParameters(const Standard_Real     Tol3d,
686                                      const Standard_Real     Tol2d,
687                                      const Standard_Boolean  RelativeTol,
688                                      const Standard_Integer  DegMin,
689                                      const Standard_Integer  DegMax,
690                                      const Standard_Integer  NbIterMax,
691                                      const Standard_Integer  NbPntMax,
692                                      const Standard_Boolean  ApproxWithTangency,
693                                      const Approx_ParametrizationType Parametrization) 
694 {
695   myNbPntMax = NbPntMax ;
696   myRelativeTol = RelativeTol ;
697   SetParameters (Tol3d, Tol2d, DegMin, DegMax, NbIterMax, ApproxWithTangency, Parametrization) ;
698 }
699
700 //--------------------------------------------------------------------------------
701 void ApproxInt_Approx::Perform(const ThePSurface& PSurf,
702                                const TheISurface& ISurf,
703                                const Handle(TheWLine)& theline,
704                                const Standard_Boolean ApproxXYZ,
705                                const Standard_Boolean ApproxU1V1,
706                                const Standard_Boolean ApproxU2V2,
707                                const Standard_Integer indicemin,
708                                const Standard_Integer indicemax)
709 {
710   myMinFactorXYZ = 0.0;
711   myMinFactorUV  = 0.0;
712   myTolReached3d = myTolReached2d = 0.;
713   
714   ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces(PSurf,ISurf);
715   Standard_Integer nbpntbez = indicemax-indicemin;
716   Standard_Integer nbpntmax = myNbPntMax;
717   Standard_Boolean OtherInter = Standard_False;
718   if(nbpntbez < LimRajout) 
719     myApproxBez = Standard_False;
720   else 
721     myApproxBez = Standard_True;
722   
723   Standard_Address ptrsvsurf = NULL;
724   Standard_Boolean cut = Standard_True;
725   if(nbpntbez < LimRajout) {   
726     cut = Standard_False;
727     //-- cout<<" ApproxInt : Nb de points = "<<nbpntbez<<" Pas de rajout "<<endl;
728   }
729
730
731   Approx_ParametrizationType parametrization;
732   myComputeLineBezier.Parametrization(parametrization);
733
734
735   ptrsvsurf = &myImpPrmSvSurfaces;  
736   myComputeLine.Init(myDegMin,
737                      myDegMax,
738                      myTol3d,
739                      myTol2d,
740                      myNbIterMax,
741                      cut,
742                      parametrization);
743
744   myComputeLineBezier.Init(myDegMin,
745                            myDegMax,
746                            myTol3d,
747                            myTol2d,
748                            myNbIterMax,
749                            cut,
750                            parametrization);
751   if(myApproxBez) { 
752     myBezToBSpl.Reset();
753     Standard_Integer nbi = (indicemax-indicemin)/nbpntmax;
754     if(nbi>1)  { 
755       nbpntbez = (indicemax-indicemin)/nbi;
756     }
757   }
758   Standard_Integer imin = indicemin;
759   Standard_Integer imax = imin + nbpntbez;
760   myTolReached = Standard_True;
761   Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v;
762   if(ApproxXYZ) { 
763     ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az);
764   }
765   else { 
766     Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;;
767   }
768   if(ApproxU1V1) { 
769     Standard_Real UVResRatio = ThePSurfaceTool::UResolution(PSurf,1.)/
770                                ThePSurfaceTool::VResolution(PSurf,1.);
771     ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True,UVResRatio);
772   }
773   else { 
774     U1o=V1o=0.0; A1u=A1v=1.0;
775   }
776   if(ApproxU2V2) { 
777     ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False);
778   }
779   else { 
780     U2o=V2o=0.0; A2u=A2v=1.0;
781   }
782   
783   //-deb-  cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax    << endl ; 
784   //-deb-  cout << "ApproxInt_Approx -- Tol3D    = " << myTol3d       << endl ; 
785   //-deb-  cout << "ApproxInt_Approx -- Tol2D    = " << myTol2d       << endl ; 
786   //-deb-  cout << "ApproxInt_Approx -- RelTol   = " << (myRelativeTol ? "RELATIVE" : "ABSOLUTE") << endl ; 
787   //-deb-  cout << "ApproxInt_Approx -- Xo = " << Xo << " Yo = " << Yo << " Zo = " << Zo << endl ;
788   //-deb-  cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ; 
789   //-deb-  cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ; 
790   //-deb-  cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ; 
791   
792   
793   Standard_Real A3d = MINABS3(Ax,Ay,Az);
794   if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) { 
795     myMinFactorXYZ = A3d;
796   }
797   
798   Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v);
799   if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) { 
800     myMinFactorUV = A2d;
801   }
802   
803   myComputeLineBezier.Parametrization(parametrization);
804
805   if(myRelativeTol==Standard_False) { 
806     myComputeLine.Init(myDegMin,
807                        myDegMax,
808                        myTol3d*myMinFactorXYZ,
809                        myTol2d*myMinFactorUV,
810                        myNbIterMax,
811                        cut,
812                        parametrization);
813     myComputeLineBezier.Init(myDegMin,
814                              myDegMax,
815                              myTol3d*myMinFactorXYZ,
816                              myTol2d*myMinFactorUV,
817                              myNbIterMax,
818                              cut,
819                              parametrization);
820   }
821   else { 
822     myComputeLine.Init(myDegMin,
823                        myDegMax,
824                        myTol3d,
825                        myTol2d,
826                        myNbIterMax,
827                        cut,
828                        parametrization);
829     myComputeLineBezier.Init(myDegMin,
830                              myDegMax,
831                              myTol3d,
832                              myTol2d,
833                              myNbIterMax,
834                              cut,
835                              parametrization);
836   }     
837   
838   
839   do {
840     
841     ApproxInt_TheMultiLine myMultiLine(theline,
842                                        ptrsvsurf,
843                                        ((ApproxXYZ)? 1 : 0),
844                                        ((ApproxU1V1)? 1: 0) + ((ApproxU2V2)? 1: 0),
845                                        Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v,
846                                        ApproxU1V1,
847                                        imin,
848                                        imax);
849     if(myApproxBez) { 
850       myComputeLineBezier.Perform(myMultiLine);
851       if (myComputeLineBezier.NbMultiCurves() == 0)
852         return;
853       myTolReached&=myComputeLineBezier.IsToleranceReached();
854     }
855     else { 
856       myComputeLine.Perform(myMultiLine);
857     }
858     UpdateTolReached();
859     Standard_Integer indice3d,indice2d1,indice2d2;
860     indice3d = 1; 
861     indice2d1= 2;
862     indice2d2= 3;
863     if(!ApproxXYZ)  { indice2d1--; indice2d2--; } 
864     if(!ApproxU1V1) { indice2d2--; } 
865     if(ApproxXYZ) { 
866       Standard_Real ax,bx,ay,by,az,bz;
867       ax = 1.0/Ax;   bx = -Xo*ax;
868       ay = 1.0/Ay;   by = -Yo*ay;
869       az = 1.0/Az;   bz = -Zo*az;
870       if(myApproxBez) { 
871         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
872           myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
873         }
874       }
875       else { 
876         myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
877       }
878     }
879     if(ApproxU1V1) { 
880       Standard_Real ax,bx,ay,by;
881       ax = 1.0/A1u;   bx = -U1o*ax;
882       ay = 1.0/A1v;   by = -V1o*ay;
883       if(myApproxBez) { 
884         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
885           myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
886         }
887       }
888       else { 
889         myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
890       }
891     }
892     if(ApproxU2V2) { 
893       Standard_Real ax,bx,ay,by;
894       ax = 1.0/A2u;   bx = -U2o*ax;
895       ay = 1.0/A2v;   by = -V2o*ay;
896       if(myApproxBez) { 
897         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
898           myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
899         }
900       }
901       else { 
902         myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
903       }
904     }
905     OtherInter = Standard_False;
906     if(myApproxBez) { 
907       for(Standard_Integer nbmc = 1; 
908           nbmc <= myComputeLineBezier.NbMultiCurves() ;
909           nbmc++) { 
910         myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
911       }
912       if(imax<indicemax)
913       {
914         imin = imax;
915         imax = imin+nbpntbez;
916         OtherInter = Standard_True;
917         if((indicemax-imax)<(nbpntbez/2))
918         {
919           imax = indicemax;
920         }
921         imax = CorrectFinishIdx(imin, imax, theline);
922       }
923     }
924   }
925   while(OtherInter);
926   if(myApproxBez) { 
927     myBezToBSpl.Perform();
928   }
929 }
930 //--------------------------------------------------------------------------------
931 void ApproxInt_Approx::Perform(const TheISurface& ISurf,
932                                const ThePSurface& PSurf,
933                                const Handle(TheWLine)& theline,
934                                const Standard_Boolean ApproxXYZ,
935                                const Standard_Boolean ApproxU1V1,
936                                const Standard_Boolean ApproxU2V2,
937                                const Standard_Integer indicemin,
938                                const Standard_Integer indicemax)
939 {
940
941   myMinFactorXYZ = 0.0;
942   myMinFactorUV  = 0.0;
943   myTolReached3d = myTolReached2d = 0.;
944   
945   ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces(ISurf,PSurf);
946   Standard_Integer nbpntbez = indicemax-indicemin;
947   
948   Standard_Boolean cut = Standard_True;
949   if(nbpntbez < LimRajout) 
950     myApproxBez = Standard_False;
951   else 
952     myApproxBez = Standard_True;
953   
954   if(nbpntbez < LimRajout) {   
955     cut = Standard_False;
956     //-- cout<<" ApproxInt : Nb de points = "<<nbpntbez<<" Pas de rajout "<<endl;
957   }
958   Standard_Address ptrsvsurf = &myImpPrmSvSurfaces;
959   
960   if(nbpntbez < LimRajout) myApproxBez = Standard_False;
961   
962   Standard_Integer nbpntmax = myNbPntMax;
963   Standard_Boolean OtherInter = Standard_False;
964   if(myApproxBez) { 
965     myBezToBSpl.Reset();
966     Standard_Integer nbi = (indicemax-indicemin)/nbpntmax;
967     if(nbi>1)  { 
968       nbpntbez = (indicemax-indicemin)/nbi;
969     }
970   }
971   Standard_Integer imin = indicemin;
972   Standard_Integer imax = imin + nbpntbez;
973   myTolReached = Standard_True;
974   
975   Standard_Real Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v;
976   if(ApproxXYZ) { 
977     ComputeTrsf3d(theline,Xo,Ax,Yo,Ay,Zo,Az);
978   }
979   else { 
980     Xo=Yo=Zo=0.0; Ax=Ay=Az=1.0;;
981   }
982   if(ApproxU1V1) { 
983     ComputeTrsf2d(theline,U1o,A1u,V1o,A1v,Standard_True);
984   }
985   else { 
986     U1o=V1o=0.0; A1u=A1v=1.0;
987   }
988   if(ApproxU2V2) { 
989     Standard_Real UVResRatio = ThePSurfaceTool::UResolution(PSurf,1.)/
990                                ThePSurfaceTool::VResolution(PSurf,1.);
991     ComputeTrsf2d(theline,U2o,A2u,V2o,A2v,Standard_False,UVResRatio);
992   }
993   else { 
994     U2o=V2o=0.0; A2u=A2v=1.0;
995   }
996   
997   //-deb-  cout << "ApproxInt_Approx -- NbPntMax = " << myNbPntMax    << endl ; 
998   //-deb-  cout << "ApproxInt_Approx -- Tol3D    = " << myTol3d       << endl ; 
999   //-deb-  cout << "ApproxInt_Approx -- Tol2D    = " << myTol2d       << endl ; 
1000   //-deb-  cout << "ApproxInt_Approx -- RelTol   = " << (myRelativeTol ? "RELATIVE" : "ABSOLUTE") << endl ; 
1001   //-deb-  cout << "ApproxInt_Approx -- Xo = " << Xo << " Yo = " << Yo << " Zo = " << Zo << endl ;
1002   //-deb-  cout << "ApproxInt_Approx -- Ax = " << Ax << " Ay = " << Ay << " Az = " << Az << endl ; 
1003   //-deb-  cout << "ApproxInt_Approx -- U1o = " << U1o << " V1o = " << V1o << " A1u = " << A1u << " A1v = " << A1v << endl ; 
1004   //-deb-  cout << "ApproxInt_Approx -- U2o = " << U2o << " V2o = " << V2o << " A2u = " << A2u << " A2v = " << A2v << endl ; 
1005   
1006   
1007   Standard_Real A3d = MINABS3(Ax,Ay,Az);
1008   if((A3d < myMinFactorXYZ) || (myMinFactorXYZ == 0.0)) { 
1009     myMinFactorXYZ = A3d;
1010   }
1011   
1012   Standard_Real A2d = MINABS4(A1u,A1v,A2u,A2v);
1013   if((A2d < myMinFactorUV) || (myMinFactorUV == 0.0)) { 
1014     myMinFactorUV = A2d;
1015   }
1016
1017   Approx_ParametrizationType parametrization;
1018   myComputeLineBezier.Parametrization(parametrization);
1019   
1020   
1021   if(myRelativeTol==Standard_False) { 
1022     myComputeLine.Init(myDegMin,
1023                        myDegMax,
1024                        myTol3d*myMinFactorXYZ,
1025                        myTol2d*myMinFactorUV,
1026                        myNbIterMax,
1027                        cut,
1028                        parametrization);
1029     myComputeLineBezier.Init(myDegMin,
1030                              myDegMax,
1031                              myTol3d*myMinFactorXYZ,
1032                              myTol2d*myMinFactorUV,
1033                              myNbIterMax,
1034                              cut,
1035                              parametrization);
1036   }
1037   else { 
1038     myComputeLine.Init(myDegMin,
1039                        myDegMax,
1040                        myTol3d,
1041                        myTol2d,
1042                        myNbIterMax,
1043                        cut,
1044                        parametrization);
1045     myComputeLineBezier.Init(myDegMin,
1046                              myDegMax,
1047                              myTol3d,
1048                              myTol2d,
1049                              myNbIterMax,
1050                              cut,
1051                              parametrization);
1052   }     
1053   
1054   
1055   
1056   do {
1057     
1058     ApproxInt_TheMultiLine myMultiLine(theline,
1059                                        ptrsvsurf,
1060                                        ((ApproxXYZ)? 1 : 0),
1061                                        ((ApproxU1V1)? 1: 0) + ((ApproxU2V2)? 1: 0),
1062                                        Xo,Ax,Yo,Ay,Zo,Az,U1o,A1u,V1o,A1v,U2o,A2u,V2o,A2v,
1063                                        ApproxU1V1,
1064                                        imin,
1065                                        imax);
1066     if(myApproxBez) { 
1067       myComputeLineBezier.Perform(myMultiLine);
1068
1069 #ifdef OCCT_DEBUG
1070       //myMultiLine.Dump();
1071 #endif
1072
1073       if (myComputeLineBezier.NbMultiCurves() == 0)
1074         return;
1075       myTolReached&=myComputeLineBezier.IsToleranceReached();
1076     }
1077     else { 
1078       myComputeLine.Perform(myMultiLine);
1079     }
1080     UpdateTolReached();
1081     
1082     Standard_Integer indice3d,indice2d1,indice2d2;
1083     indice3d = 1; 
1084     indice2d1= 2;
1085     indice2d2= 3;
1086     if(!ApproxXYZ)  { indice2d1--; indice2d2--; } 
1087     if(!ApproxU1V1) { indice2d2--; } 
1088     if(ApproxXYZ) { 
1089       Standard_Real ax,bx,ay,by,az,bz;
1090       ax = 1.0/Ax;   bx = -Xo*ax;
1091       ay = 1.0/Ay;   by = -Yo*ay;
1092       az = 1.0/Az;   bz = -Zo*az;
1093       if(myApproxBez) { 
1094         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
1095           myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
1096         }
1097       }
1098       else { 
1099         myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
1100       }
1101     }
1102     if(ApproxU1V1) { 
1103       Standard_Real ax,bx,ay,by;
1104       ax = 1.0/A1u;   bx = -U1o*ax;
1105       ay = 1.0/A1v;   by = -V1o*ay;
1106       if(myApproxBez) { 
1107         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
1108           myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
1109         }
1110       }
1111       else { 
1112         myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
1113       }
1114     }
1115     if(ApproxU2V2) { 
1116       Standard_Real ax,bx,ay,by;
1117       ax = 1.0/A2u;   bx = -U2o*ax;
1118       ay = 1.0/A2v;   by = -V2o*ay;
1119       if(myApproxBez) { 
1120         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--) { 
1121           myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
1122         }
1123       }
1124       else { 
1125         myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
1126       }
1127     }
1128     OtherInter = Standard_False;
1129     if(myApproxBez)
1130     {
1131       for(Standard_Integer nbmc = 1;
1132         nbmc <= myComputeLineBezier.NbMultiCurves() ;
1133         nbmc++)
1134       { 
1135           myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
1136       }
1137       if(imax<indicemax)
1138       {
1139         imin = imax;
1140         imax = imin+nbpntbez;
1141         OtherInter = Standard_True;
1142         if((indicemax-imax)<(nbpntbez/2))
1143         {
1144           imax = indicemax;
1145         }
1146         imax = CorrectFinishIdx(imin, imax, theline);
1147       }
1148     }
1149   }
1150   while(OtherInter); 
1151   if(myApproxBez) { 
1152     myBezToBSpl.Perform();
1153   }
1154 }
1155 //--------------------------------------------------------------------------------
1156 Standard_Integer ApproxInt_Approx::NbMultiCurves() const { 
1157   //  return(myComputeLine.NbMultiCurves());
1158   return 1;
1159 }
1160 //--------------------------------------------------------------------------------
1161 void ApproxInt_Approx::UpdateTolReached() {
1162
1163   if (myApproxBez) {
1164     Standard_Integer ICur ;
1165     Standard_Integer NbCurves = myComputeLineBezier.NbMultiCurves() ;
1166     for (ICur = 1 ; ICur <= NbCurves ; ICur++) {
1167       Standard_Real Tol3D, Tol2D ;
1168       myComputeLineBezier.Error (ICur, Tol3D, Tol2D) ;
1169       myTolReached3d = Max(myTolReached3d, Tol3D);
1170       myTolReached2d = Max(myTolReached2d, Tol2D);
1171     }
1172   } else {
1173     myComputeLine.Error (myTolReached3d, myTolReached2d);
1174   }
1175 }
1176 //--------------------------------------------------------------------------------
1177 Standard_Real ApproxInt_Approx::TolReached3d() const { 
1178
1179   Standard_Real TheTol3D = RatioTol * myTolReached3d ;
1180   //modified by NIZNHY-PKV Mon Aug 27 14:21:33 2007f
1181   //if (myMinFactorXYZ)
1182   //TheTol3D = TheTol3D / myMinFactorXYZ ;
1183   if (myMinFactorXYZ>1.5e-7) {
1184     TheTol3D = TheTol3D / myMinFactorXYZ ;
1185   }
1186   //modified by NIZNHY-PKV Mon Aug 27 14:21:50 2007t
1187   return TheTol3D ;
1188 }
1189 //--------------------------------------------------------------------------------
1190 Standard_Real ApproxInt_Approx::TolReached2d() const {
1191
1192   Standard_Real TheTol2D = RatioTol * myTolReached2d ;
1193   //modified by NIZNHY-PKV Mon Aug 27 14:20:50 2007f
1194   //if (myMinFactorUV)
1195   //TheTol2D = TheTol2D / myMinFactorUV ;
1196   if (myMinFactorUV>1.5e-7) {
1197     TheTol2D = TheTol2D / myMinFactorUV ;
1198   }
1199   //modified by NIZNHY-PKV Mon Aug 27 14:20:55 2007t
1200   return TheTol2D ;
1201 }
1202 //--------------------------------------------------------------------------------
1203 Standard_Boolean ApproxInt_Approx::IsDone() const { 
1204   if(myApproxBez) { 
1205     return(myComputeLineBezier.NbMultiCurves() > 0);
1206                            //-- Lorsque la tolerance n est pas atteinte et qu il 
1207                            //-- faudrait rajouter des points sur la ligne
1208                            //-- les approx sortent avec la meilleure tolerance
1209                            //-- atteinte.  ( Pas de rajout de points ds cette version)
1210     //-- return(myTolReached);
1211   }
1212   else { 
1213     return(myComputeLine.IsToleranceReached());
1214   }
1215 }
1216 //--------------------------------------------------------------------------------
1217 const AppParCurves_MultiBSpCurve& ApproxInt_Approx::Value(const Standard_Integer ) const { 
1218   if(myApproxBez) { 
1219     return(myBezToBSpl.Value());
1220   }
1221   else { 
1222     return(myComputeLine.Value());
1223   }
1224 }
1225 //--------------------------------------------------------------------------------
1226 Standard_Integer ApproxInt_Approx::CorrectFinishIdx(const Standard_Integer theMinIdx,
1227                                                     const Standard_Integer theMaxIdx,
1228                                                     const Handle(TheWLine)& theline)
1229 {
1230   const Standard_Real aNullCoeff = 1.0e-16;
1231   Standard_Real aLimitMaxCoeff = 1.0 / 2500.0;
1232   Standard_Real aDist = theline->Point(theMinIdx).Value().SquareDistance(
1233                         theline->Point(theMinIdx + 1).Value());
1234
1235   for(Standard_Integer anIdx = theMinIdx + 1; anIdx < theMaxIdx - 1; anIdx++)
1236   {
1237     Standard_Real aNextDist = theline->Point(anIdx).Value().SquareDistance(
1238                               theline->Point(anIdx + 1).Value());
1239     Standard_Real aCoeff = Min (aNextDist, aDist) / Max (aNextDist, aDist);
1240
1241     //
1242     if (aCoeff < aLimitMaxCoeff &&        // Base criteria.
1243         aNextDist > aDist &&              // Step increasing.
1244         aNextDist > aNullCoeff &&         // Avoid separation in case of too small step.
1245         aDist > aNullCoeff)               // Usually found when purger not invoked (blend).
1246     {
1247       return anIdx;
1248     }
1249     aDist = aNextDist;
1250   }
1251   return theMaxIdx;
1252 }