0023248: Wrong result done by solid classifier algorithm for infinite point
[occt.git] / src / IntCurveSurface / IntCurveSurface_Inter.gxx
1 // Created on: 1993-04-09
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21 //#ifndef DEB
22 //#define No_Standard_RangeError
23 //#define No_Standard_OutOfRange
24 //#endif
25
26
27 #define  TOLTANGENCY         0.00000001
28 #define  TOLERANCE_ANGULAIRE 1.e-12//0.00000001
29 #define  TOLERANCE           0.00000001
30
31 #define NBSAMPLESONCIRCLE  32
32 #define NBSAMPLESONELLIPSE 32
33 #define NBSAMPLESONPARAB   16
34 #define NBSAMPLESONHYPR    32
35
36 #include <ElSLib.hxx>
37 #include <Intf_SectionPoint.hxx>
38 #include <Intf_TangentZone.hxx>
39 #include <Intf_Tool.hxx>
40 #include <math_FunctionSetRoot.hxx>
41 #include <IntCurveSurface_IntersectionPoint.hxx>
42 #include <IntCurveSurface_IntersectionSegment.hxx>
43 #include <IntAna_IntConicQuad.hxx>
44 #include <IntAna_Quadric.hxx>
45 #include <gp_Vec.hxx>
46 #include <gp_Dir.hxx>
47 #include <Precision.hxx>
48 #include <IntAna_IntLinTorus.hxx>
49
50 #include <GeomAbs_Shape.hxx>
51 #include <GeomAbs_CurveType.hxx>
52 #include <TColStd_Array1OfReal.hxx>
53 #include <TColgp_Array1OfPnt.hxx>
54 #include <gp_Pnt.hxx>
55 #include <gp_Pln.hxx>
56 #include <gp_Lin.hxx>
57 #include <GProp_PEquation.hxx>
58 #include <GProp_PGProps.hxx>
59 #include <GProp_PrincipalProps.hxx>
60 #include <Extrema_ExtElC.hxx>
61 #include <Extrema_POnCurv.hxx>
62
63
64
65 #include <ProjLib_Plane.hxx>
66 #include <IntAna2d_AnaIntersection.hxx>
67 #include <gp_Lin2d.hxx>
68 #include <IntAna2d_IntPoint.hxx>
69 #include <gp_Parab2d.hxx>
70 #include <IntAna2d_Conic.hxx>
71 #include <IntAna2d_AnaIntersection.hxx>
72 #include <gp_Hypr2d.hxx>
73 #include <Adaptor3d_HCurve.hxx>
74 #include <Adaptor3d_HSurface.hxx>
75
76
77 #include <TColgp_Array2OfPnt.hxx>
78 #include <TColStd_HArray1OfReal.hxx>
79 #include <Adaptor3d_TopolTool.hxx>
80 #include <ElCLib.hxx>
81
82 static 
83   void EstLimForInfExtr(const gp_Lin&   Line,
84                         const TheSurface& surface, 
85                         const Standard_Boolean IsOffSurf,
86                         const Standard_Integer nbsu, 
87                         const Standard_Boolean U1inf, 
88                         const Standard_Boolean U2inf, 
89                         const Standard_Boolean V1inf, 
90                         const Standard_Boolean V2inf, 
91                         Standard_Real& U1new, 
92                         Standard_Real& U2new, 
93                         Standard_Real& V1new, 
94                         Standard_Real& V2new, 
95                         Standard_Boolean& NoIntersection);
96
97 static 
98   void EstLimForInfRevl(const gp_Lin&   Line,
99                         const TheSurface& surface, 
100                         const Standard_Boolean U1inf, 
101                         const Standard_Boolean U2inf, 
102                         const Standard_Boolean V1inf, 
103                         const Standard_Boolean V2inf, 
104                         Standard_Real& U1new, 
105                         Standard_Real& U2new, 
106                         Standard_Real& V1new, 
107                         Standard_Real& V2new, 
108                         Standard_Boolean& NoIntersection);
109
110 static 
111   void EstLimForInfOffs(const gp_Lin&   Line,
112                         const TheSurface& surface, 
113                         const Standard_Integer nbsu, 
114                         const Standard_Boolean U1inf, 
115                         const Standard_Boolean U2inf, 
116                         const Standard_Boolean V1inf, 
117                         const Standard_Boolean V2inf, 
118                         Standard_Real& U1new, 
119                         Standard_Real& U2new, 
120                         Standard_Real& V1new, 
121                         Standard_Real& V2new, 
122                         Standard_Boolean& NoIntersection);
123
124 static
125   void EstLimForInfSurf(Standard_Real& U1new, 
126                         Standard_Real& U2new, 
127                         Standard_Real& V1new, 
128                         Standard_Real& V2new);
129
130 static
131   void SectionPointToParameters(const Intf_SectionPoint& Sp,
132                                 const IntCurveSurface_ThePolyhedron& Surf,
133                                 const IntCurveSurface_ThePolygon&    Curv,
134                                 Standard_Real& u,
135                                 Standard_Real& v,
136                                 Standard_Real& w);
137
138 static 
139   void IntCurveSurface_ComputeTransitions(const TheCurve& curve,
140                                           const Standard_Real w,
141                                           IntCurveSurface_TransitionOnCurve&   TransOnCurve,
142                                           const TheSurface& surface,
143                                           const Standard_Real u,
144                                           const Standard_Real v);
145
146 static 
147   void IntCurveSurface_ComputeParamsOnQuadric(const TheSurface& surface,
148                                               const gp_Pnt& P,
149                                               Standard_Real& u,
150                                               Standard_Real& v);
151
152 static 
153   Standard_Boolean DoTrim(const TheCurve& curve,
154                           const TheSurface& surface);
155 static
156   void DoCurve(const TheCurve& curve,
157                Bnd_Box&  boxCurve);
158
159 static
160   void DoCommon(TColStd_Array1OfReal& Coords,
161                 Standard_Real&        Cmin,
162                 Standard_Real&        Cmax);
163
164 static 
165   void DoCommonBox(const Bnd_Box&        boxSurface,
166                    const Bnd_Box&        boxCurve,
167                    TColStd_Array1OfReal& X,
168                    TColStd_Array1OfReal& Y,
169                    TColStd_Array1OfReal& Z);
170
171 static 
172   void ProjectIntersectAndEstLim(const gp_Lin&        theLine,
173                                  const gp_Pln&        thePln,
174                                  const ProjLib_Plane& theBasCurvProj,
175                                  Standard_Real&       theVmin,
176                                  Standard_Real&       theVmax,
177                                  Standard_Boolean&    theNoIntersection);
178
179 //=======================================================================
180 //function : IntCurveSurface_Inter
181 //purpose  : 
182 //=======================================================================
183 IntCurveSurface_Inter::IntCurveSurface_Inter() 
184
185 }
186 //=======================================================================
187 //function : DoSurface
188 //purpose  : 
189 //=======================================================================
190 void IntCurveSurface_Inter::DoSurface(const TheSurface&   surface,
191                                       const Standard_Real u0,
192                                       const Standard_Real u1,
193                                       const Standard_Real v0,
194                                       const Standard_Real v1,
195                                       TColgp_Array2OfPnt& pntsOnSurface,
196                                       Bnd_Box&            boxSurface,
197                                       Standard_Real&      gap)
198 {
199   Standard_Integer iU = 0, iV = 0;
200   Standard_Real U = 0., V = 0;
201 // modified by NIZHNY-MKK  Mon Oct  3 17:38:45 2005
202 //   Standard_Real dU = fabs(u1-u0)/50., dV = fabs(v1-v0)/50.;
203   Standard_Real dU = (u1-u0)/50., dV = (v1-v0)/50.;
204   gp_Pnt aPnt;
205
206   for(iU = 0; iU < 50; iU++) {
207     
208     if(iU == 0)
209       U = u0;
210     else if(iU == 49)
211       U = u1;
212     else 
213       U = u0 + dU * ((Standard_Real)iU);
214     
215     for(iV = 0; iV < 50; iV++) {
216
217       if(iV == 0)
218         V = v0;
219       else if(iV == 49)
220         V = v1;
221       else
222         V = v0 + dV * ((Standard_Real)iV);
223
224       TheSurfaceTool::D0(surface,U,V,aPnt);
225       boxSurface.Add(aPnt);
226       pntsOnSurface.SetValue(iU+1,iV+1,aPnt);
227     }
228   }
229   Standard_Real Ures = TheSurfaceTool::UResolution(surface,dU);
230   Standard_Real Vres = TheSurfaceTool::VResolution(surface,dV);
231   gap = Max(Ures,Vres);
232 }
233
234 //=======================================================================
235 //function : DoCurve
236 //purpose  : 
237 //=======================================================================
238 void DoCurve(const TheCurve& curve,
239              Bnd_Box& boxCurve)
240 {
241   Standard_Real CF = TheCurveTool::FirstParameter(curve);
242   Standard_Real CL = TheCurveTool::LastParameter(curve);
243   Standard_Real C = 0., dC = fabs(CL-CF)/50.;
244   Standard_Integer iC = 0;
245   gp_Pnt aPnt;
246
247   for(iC = 0; iC < 50; iC++) {
248     if(iC == 0)
249       C = CF;
250     else if(iC == 49)
251       C = CL;
252     else
253       C = CF + dC *((Standard_Real)iC);
254       
255     TheCurveTool::D0(curve,C,aPnt);
256     boxCurve.Add(aPnt);
257   }
258 }
259
260 //=======================================================================
261 //function : DoCommon
262 //purpose  : 
263 //=======================================================================
264 void DoCommon(TColStd_Array1OfReal& Coords,
265               Standard_Real&        Cmin,
266               Standard_Real&        Cmax)
267 {
268   Standard_Integer i = 0, j = 0;
269   for(i = 1; i <= 4; i++) {
270     for(j = i+1; j <= 4; j++) {
271       if(Coords(j) > Coords(i)) {
272         Standard_Real c = Coords(i);
273         Coords.SetValue(i,Coords(j));
274         Coords.SetValue(j,c);
275       }
276     }
277   }
278   Cmax = Coords(2);
279   Cmin = Coords(3);
280 }
281
282 //=======================================================================
283 //function : DoCommonBox
284 //purpose  : 
285 //=======================================================================
286 static void DoCommonBox(const Bnd_Box&        boxSurface,
287                         const Bnd_Box&        boxCurve,
288                         TColStd_Array1OfReal& X,
289                         TColStd_Array1OfReal& Y,
290                         TColStd_Array1OfReal& Z)
291 {
292   Standard_Real SBXmin = 0., SBYmin = 0., SBZmin = 0.;
293   Standard_Real SBXmax = 0., SBYmax = 0., SBZmax = 0.;
294   boxSurface.Get(SBXmin,SBYmin,SBZmin,SBXmax,SBYmax,SBZmax);
295
296   Standard_Real CBXmin = 0., CBYmin = 0., CBZmin = 0.;
297   Standard_Real CBXmax = 0., CBYmax = 0., CBZmax = 0.;
298   boxCurve.Get(CBXmin,CBYmin,CBZmin,CBXmax,CBYmax,CBZmax);
299
300   TColStd_Array1OfReal Coord(1,4);
301
302   Coord(1) = SBXmin; Coord(2) = SBXmax; Coord(3) = CBXmin; Coord(4) = CBXmax;
303   Standard_Real CXmin = SBXmin, CXmax = SBXmax;
304   DoCommon(Coord,CXmin,CXmax);
305   
306   Coord(1) = SBYmin; Coord(2) = SBYmax; Coord(3) = CBYmin; Coord(4) = CBYmax;
307   Standard_Real CYmin = SBYmin, CYmax = SBYmax;
308   DoCommon(Coord,CYmin,CYmax);
309   
310   Coord(1) = SBZmin; Coord(2) = SBZmax; Coord(3) = CBZmin; Coord(4) = CBZmax;
311   Standard_Real CZmin = SBZmin, CZmax = SBZmax;
312   DoCommon(Coord,CZmin,CZmax);
313
314   X.SetValue(1,CXmin); X.SetValue(2,CXmax);
315   Y.SetValue(1,CYmin); Y.SetValue(2,CYmax);
316   Z.SetValue(1,CZmin); Z.SetValue(2,CZmax);
317 }
318
319 //=======================================================================
320 //function : DoNewBounds
321 //purpose  : 
322 //=======================================================================
323 void IntCurveSurface_Inter::DoNewBounds(
324                                         const TheSurface&           surface,
325                                         const Standard_Real         u0,
326                                         const Standard_Real         u1,
327                                         const Standard_Real         v0,
328                                         const Standard_Real         v1,
329                                         const TColgp_Array2OfPnt&   pntsOnSurface,
330                                         const TColStd_Array1OfReal& X,
331                                         const TColStd_Array1OfReal& Y,
332                                         const TColStd_Array1OfReal& Z,
333                                         TColStd_Array1OfReal&       Bounds)
334 {
335   Bounds.SetValue(1,u0);
336   Bounds.SetValue(2,u1);
337   Bounds.SetValue(3,v0);
338   Bounds.SetValue(4,v1);
339
340   Standard_Boolean isUClosed = (TheSurfaceTool::IsUClosed(surface) || TheSurfaceTool::IsUPeriodic(surface));
341   Standard_Boolean isVClosed = (TheSurfaceTool::IsVClosed(surface) || TheSurfaceTool::IsVPeriodic(surface));
342   Standard_Boolean checkU = (isUClosed) ? Standard_False : Standard_True;
343   Standard_Boolean checkV = (isVClosed) ? Standard_False : Standard_True;
344
345   Standard_Integer i = 0, j = 0, k = 0, iU = 0, iV = 0;
346   Standard_Integer iUmin = 50, iVmin = 50, iUmax = 1, iVmax = 1;
347
348   for(i = 1; i <= 2; i++) {
349     for(j = 1; j <= 2; j++) {
350       for(k = 1; k <= 2; k++) {
351         gp_Pnt aPoint(X(i),Y(j),Z(k));
352         Standard_Real DistMin = 1.e+100;
353         Standard_Integer diU = 0, diV = 0;
354         for(iU = 1; iU <= 50; iU++) {
355           for(iV = 1; iV <= 50; iV++) {
356             const gp_Pnt aP = pntsOnSurface.Value(iU,iV);
357             Standard_Real dist = aP.SquareDistance(aPoint);
358             if(dist < DistMin) {
359               DistMin = dist;
360               diU = iU;
361               diV = iV;
362             }
363           }
364         }
365         if(diU > 0 && diU < iUmin) iUmin = diU;
366         if(diU > 0 && diU > iUmax) iUmax = diU;
367         if(diV > 0 && diV < iVmin) iVmin = diV;
368         if(diV > 0 && diV > iVmax) iVmax = diV;
369       }
370     }
371   }
372
373 // modified by NIZHNY-MKK  Mon Oct  3 17:38:43 2005
374 //   Standard_Real dU = fabs(u1-u0)/50., dV = fabs(v1-v0)/50.;
375   Standard_Real dU = (u1-u0)/50., dV = (v1-v0)/50.;
376
377   Standard_Real USmin = u0 + dU * ((Standard_Real)(iUmin - 1));
378   Standard_Real USmax = u0 + dU * ((Standard_Real)(iUmax - 1));
379   Standard_Real VSmin = v0 + dV * ((Standard_Real)(iVmin - 1));
380   Standard_Real VSmax = v0 + dV * ((Standard_Real)(iVmax - 1));
381
382   if(USmin > USmax) {
383     Standard_Real tmp = USmax;
384     USmax = USmin;
385     USmin = tmp;
386   }
387   if(VSmin > VSmax) {
388     Standard_Real tmp = VSmax;
389     VSmax = VSmin;
390     VSmin = tmp;
391   }
392
393   USmin -= 1.5*dU;
394   if(USmin < u0) USmin = u0;
395   USmax += 1.5*dU;
396   if(USmax > u1) USmax = u1;
397   VSmin -= 1.5*dV;
398   if(VSmin < v0) VSmin = v0;
399   VSmax += 1.5*dV;
400   if(VSmax > v1) VSmax = v1;
401
402   if(checkU) {
403     Bounds.SetValue(1,USmin);
404     Bounds.SetValue(2,USmax);
405   }
406   if(checkV) {
407     Bounds.SetValue(3,VSmin);
408     Bounds.SetValue(4,VSmax);
409   }
410 }
411
412 //=======================================================================
413 //function : Perform
414 //purpose  : Decompose la surface si besoin est 
415 //=======================================================================
416 void IntCurveSurface_Inter::Perform(const TheCurve&   curve,
417                                     const TheSurface& surface) {
418   ResetFields();
419   done = Standard_True;
420   Standard_Integer NbUOnS = TheSurfaceTool::NbUIntervals(surface,GeomAbs_C2);
421   Standard_Integer NbVOnS = TheSurfaceTool::NbVIntervals(surface,GeomAbs_C2);
422   Standard_Integer NbOnC  = TheCurveTool::NbIntervals(curve,GeomAbs_C2);
423   Standard_Real U0,U1,V0,V1; 
424   
425   if(NbUOnS > 1) { 
426     TColStd_Array1OfReal TabU(1,NbUOnS+1);
427     TheSurfaceTool::UIntervals(surface,TabU,GeomAbs_C2);
428     for(Standard_Integer iu = 1;iu <= NbUOnS; iu++) {
429       U0 = TabU.Value(iu);
430       U1 = TabU.Value(iu+1);
431       if(NbVOnS > 1) { 
432         TColStd_Array1OfReal TabV(1,NbVOnS+1);
433         TheSurfaceTool::VIntervals(surface,TabV,GeomAbs_C2);
434         for(Standard_Integer iv = 1;iv <= NbVOnS; iv++) {
435           V0 = TabV.Value(iv);
436           V1 = TabV.Value(iv+1);
437           Perform(curve,surface,U0,V0,U1,V1);
438         }
439       }
440       else { //------ composite en U     non composite en V
441         V0 = TheSurfaceTool::FirstVParameter(surface);
442         V1 = TheSurfaceTool::LastVParameter(surface);
443         Perform(curve,surface,U0,V0,U1,V1);
444       }
445     }
446   }
447   else if(NbVOnS > 1) { //---------- non composite en U  composite en V
448     U0 = TheSurfaceTool::FirstUParameter(surface);
449     U1 = TheSurfaceTool::LastUParameter(surface);   
450     TColStd_Array1OfReal TabV(1,NbVOnS+1);
451     TheSurfaceTool::VIntervals(surface,TabV,GeomAbs_C2);
452     for(Standard_Integer iv = 1;iv <= NbVOnS; iv++) {
453       V0 = TabV.Value(iv);
454       V1 = TabV.Value(iv+1);
455       Perform(curve,surface,U0,V0,U1,V1);
456     }
457   } 
458   else {
459     V0 = TheSurfaceTool::FirstVParameter(surface);
460     V1 = TheSurfaceTool::LastVParameter(surface);
461     U0 = TheSurfaceTool::FirstUParameter(surface);
462     U1 = TheSurfaceTool::LastUParameter(surface); 
463
464     //-- ofv: begin
465     Standard_Boolean doTrim = DoTrim(curve,surface);
466     if(doTrim) {
467       TColgp_Array2OfPnt aPS(1,50,1,50);
468       Bnd_Box SB;
469       Standard_Real g = 1.e-7;
470       DoSurface(surface,U0,U1,V0,V1,aPS,SB,g);
471       Bnd_Box CB;
472       DoCurve(curve,CB);
473       CB.Enlarge(g);
474       TColStd_Array1OfReal X(1,2), Y(1,2), Z(1,2);
475       DoCommonBox(SB,CB,X,Y,Z);
476       TColStd_Array1OfReal B(1,4);
477       DoNewBounds(surface,U0,U1,V0,V1,aPS,X,Y,Z,B);
478       U0 = B(1); U1 = B(2); V0 = B(3); V1 = B(4);
479     }
480     //-- ofv: end
481
482 #if 0
483     //-- jgv patch (from)
484     //Computing of local bounds
485     Standard_Real LocalU0 = U0, LocalU1 = U1, LocalV0 = V0, LocalV1 = V1;
486     Standard_Real Umin = RealLast(), Vmin = RealLast(), Umax = RealFirst(), Vmax = RealFirst();
487     Bnd_Box CurveBox;
488     Standard_Integer i, j, k;
489     //Making GeomAdaptor_Curve
490     Standard_Real f = TheCurveTool::FirstParameter(curve);
491     Standard_Real l = TheCurveTool::LastParameter(curve);
492     GeomAbs_CurveType CurveType = TheCurveTool::GetType(curve);
493     Handle(Geom_Curve) theCurve;
494     switch (CurveType)
495       {
496       case GeomAbs_Line:
497         theCurve = new Geom_Line( TheCurveTool::Line(curve) );
498         break;
499       case GeomAbs_Circle:
500         theCurve = new Geom_Circle( TheCurveTool::Circle(curve) );
501         break;
502       case GeomAbs_Ellipse:
503         theCurve = new Geom_Ellipse( TheCurveTool::Ellipse(curve) );
504         break;
505       case GeomAbs_Hyperbola:
506         theCurve = new Geom_Hyperbola( TheCurveTool::Hyperbola(curve) );
507         break;
508       case GeomAbs_Parabola:
509         theCurve = new Geom_Parabola( TheCurveTool::Parabola(curve) );
510         break;
511       case GeomAbs_BezierCurve:
512         theCurve = TheCurveTool::Bezier(curve);
513         break;
514       case GeomAbs_BSplineCurve:
515         theCurve = TheCurveTool::BSpline(curve);
516         break;
517       }
518     if (!theCurve.IsNull())
519       {
520         GeomAdaptor_Curve GACurve( theCurve, f, l );
521         BndLib_Add3dCurve::Add( GACurve, Precision::Confusion(), CurveBox );
522       }
523     else
524       {
525         Standard_Integer nbp = TheCurveTool::NbSamples(curve,f,l);
526         Standard_Real delta = (f-l)/nbp;
527         for (i = 0; i <= nbp; i++)
528           {
529             gp_Pnt aPnt = TheCurveTool::Value(curve, f + i*delta);
530             CurveBox.Add(aPnt);
531           }
532       }
533     Standard_Real X[2], Y[2], Z[2];
534     CurveBox.Get( X[0], Y[0], Z[0], X[1], Y[1], Z[1] );
535     Standard_Real Ures = TheSurfaceTool::UResolution(surface, Precision::Confusion());
536     Standard_Real Vres = TheSurfaceTool::VResolution(surface, Precision::Confusion());
537     //Making GeomAdaptor_Surface
538     GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
539     Handle(Geom_Surface) theSurface;
540     switch (SurfaceType)
541       {
542       case GeomAbs_Plane:
543         theSurface = new Geom_Plane( TheSurfaceTool::Plane(surface) );
544         break;
545       case GeomAbs_Cylinder:
546         theSurface = new Geom_CylindricalSurface( TheSurfaceTool::Cylinder(surface) );
547         break;
548       case GeomAbs_Cone:
549         theSurface = new Geom_ConicalSurface( TheSurfaceTool::Cone(surface) );
550         break;
551       case GeomAbs_Torus:
552         theSurface = new Geom_ToroidalSurface( TheSurfaceTool::Torus(surface) );
553         break;
554       case GeomAbs_Sphere:
555         theSurface = new Geom_SphericalSurface( TheSurfaceTool::Sphere(surface) );
556         break;
557       case GeomAbs_BezierSurface:
558         theSurface = TheSurfaceTool::Bezier(surface);
559         break;
560       case GeomAbs_BSplineSurface:
561         theSurface = TheSurfaceTool::BSpline(surface);
562         break;
563       case GeomAbs_SurfaceOfRevolution:
564         {
565           gp_Ax1 Axis = TheSurfaceTool::AxeOfRevolution(surface);
566           Handle(Adaptor3d_HCurve) AdBC = TheSurfaceTool::BasisCurve(surface);
567           Handle(Geom_Curve) BC = GetCurve(AdBC);
568           if (!BC.IsNull())
569             theSurface = new Geom_SurfaceOfRevolution( BC, Axis );
570           break;
571         }
572       case GeomAbs_SurfaceOfExtrusion:
573         {
574           gp_Dir Direction = TheSurfaceTool::Direction(surface);
575           Handle(Adaptor3d_HCurve) AdBC = TheSurfaceTool::BasisCurve(surface);
576           Handle(Geom_Curve) BC = GetCurve(AdBC);
577           if (!BC.IsNull())
578             theSurface = new Geom_SurfaceOfLinearExtrusion( BC, Direction );
579           break;
580         }
581       case GeomAbs_OffsetSurface:
582         {
583           Standard_Real OffsetValue = TheSurfaceTool::OffsetValue(surface);
584           Handle(Adaptor3d_HSurface) AdBS = TheSurfaceTool::BasisSurface(surface);
585           Handle(Geom_Surface) BS = GetSurface(AdBS);
586           if (!BS.IsNull())
587             theSurface = new Geom_OffsetSurface( BS, OffsetValue );
588           break;
589         }
590       }
591     if (!theSurface.IsNull())
592       {
593         GeomAdaptor_Surface GASurface( theSurface );
594         Extrema_ExtPS Projector;
595         Projector.Initialize( GASurface, U0, U1, V0, V1, Ures, Vres );
596         for (i = 0; i <= 1; i++)
597           for (j = 0; j <= 1; j++)
598             for (k = 0; k <= 1; k++)
599               {
600                 gp_Pnt aPoint( X[i], Y[j], Z[k] );
601                 Projector.Perform( aPoint );
602                 if (Projector.IsDone() && Projector.NbExt() > 0)
603                   {
604                     Standard_Real mindist = RealLast();
605                     Standard_Integer minind, ind;
606                     for (ind = 1; ind <= Projector.NbExt(); ind++)
607                       {
608                         Standard_Real dist = Projector.Value(ind);
609                         if (dist < mindist)
610                           {
611                             mindist = dist;
612                             minind  = ind;
613                           }
614                       }
615                     Extrema_POnSurf pons = Projector.Point(minind);
616                     Standard_Real U, V;
617                     pons.Parameter( U, V );
618                     if (U < Umin) Umin = U;
619                     if (U > Umax) Umax = U;
620                     if (V < Vmin) Vmin = V;
621                     if (V > Vmax) Vmax = V;
622                   }
623               }
624         Umin -= Ures; Umax += Ures; Vmin -= Vres; Vmax += Vres;
625         if (Umin > U0 && Umin <= U1) LocalU0 = Umin;
626         if (Umax < U1 && Umax >= U0) LocalU1 = Umax;
627         if (Vmin > V0 && Vmin <= V1) LocalV0 = Vmin;
628         if (Vmax < V1 && Vmax >= V0) LocalV1 = Vmax;
629         U0 = LocalU0; U1 = LocalU1; V0 = LocalV0; V1 = LocalV1;
630       }
631     //-- jgv patch (to)
632 #endif
633     Perform(curve,surface,U0,V0,U1,V1);
634   }
635 }
636 //=======================================================================
637 //function : Perform
638 //purpose  : 
639 //=======================================================================
640 void IntCurveSurface_Inter::Perform(const TheCurve&   curve,
641                                     const TheSurface& surface,
642                                     const Standard_Real U1,const Standard_Real V1,
643                                     const Standard_Real U2,const Standard_Real V2) { 
644
645   GeomAbs_CurveType CurveType = TheCurveTool::GetType(curve);
646   
647   switch(CurveType) { 
648   case GeomAbs_Line:  
649     { 
650       PerformConicSurf(TheCurveTool::Line(curve),curve,surface,U1,V1,U2,V2);
651       break;
652     }
653   case GeomAbs_Circle: 
654     { 
655       PerformConicSurf(TheCurveTool::Circle(curve),curve,surface,U1,V1,U2,V2);
656       break;
657     }
658   case GeomAbs_Ellipse: 
659     { 
660       PerformConicSurf(TheCurveTool::Ellipse(curve),curve,surface,U1,V1,U2,V2);
661       break;
662     }    
663   case GeomAbs_Parabola:  
664     {
665       PerformConicSurf(TheCurveTool::Parabola(curve),curve,surface,U1,V1,U2,V2);
666       break;
667     }
668   case GeomAbs_Hyperbola: 
669     {
670       PerformConicSurf(TheCurveTool::Hyperbola(curve),curve,surface,U1,V1,U2,V2);
671       break;
672     }
673   default:    
674     {
675       Standard_Integer nbIntervalsOnCurve = TheCurveTool::NbIntervals(curve,GeomAbs_C2);
676       GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
677       if(   (SurfaceType != GeomAbs_Plane) 
678          && (SurfaceType != GeomAbs_Cylinder)
679          && (SurfaceType != GeomAbs_Cone) 
680          && (SurfaceType != GeomAbs_Sphere)) { 
681         
682         if(nbIntervalsOnCurve > 1) { 
683           TColStd_Array1OfReal TabW(1,nbIntervalsOnCurve+1);
684           TheCurveTool::Intervals(curve,TabW,GeomAbs_C2);
685           for(Standard_Integer i = 1; i<=nbIntervalsOnCurve; i++) { 
686             Standard_Real u1,u2;
687             u1 = TabW.Value(i);
688             u2 = TabW.Value(i+1);
689
690             Handle(TColStd_HArray1OfReal) aPars;
691             Standard_Real defl = 0.1;
692             Standard_Integer NbMin = 10;
693             TheCurveTool::SamplePars(curve, u1, u2, defl, NbMin, aPars);
694
695 //          IntCurveSurface_ThePolygon  polygon(curve,u1,u2,TheCurveTool::NbSamples(curve,u1,u2));
696             IntCurveSurface_ThePolygon  polygon(curve, aPars->Array1());
697             InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
698           }
699         }
700         else {
701           Standard_Real u1,u2;
702           u1 = TheCurveTool::FirstParameter(curve);
703           u2 = TheCurveTool::LastParameter(curve);
704
705           Handle(TColStd_HArray1OfReal) aPars;
706           Standard_Real defl = 0.1;
707           Standard_Integer NbMin = 10;
708           TheCurveTool::SamplePars(curve, u1, u2, defl, NbMin, aPars);
709
710 //        IntCurveSurface_ThePolygon       polygon(curve,TheCurveTool::NbSamples(curve,u1,u2));
711           IntCurveSurface_ThePolygon  polygon(curve, aPars->Array1());
712           InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
713         }
714       }
715       else {   //-- la surface est une quadrique 
716         InternalPerformCurveQuadric(curve,surface);
717       }
718     }
719   }
720 }
721 //=======================================================================
722 //function : Perform
723 //purpose  : 
724 //=======================================================================
725 void IntCurveSurface_Inter::Perform(const TheCurve&   curve,
726                                     const IntCurveSurface_ThePolygon& polygon,
727                                     const TheSurface& surface) {
728   ResetFields();
729   done = Standard_True;
730   Standard_Real u1,v1,u2,v2;
731   u1 = TheSurfaceTool::FirstUParameter(surface);
732   v1 = TheSurfaceTool::FirstVParameter(surface);
733   u2 = TheSurfaceTool::LastUParameter(surface);
734   v2 = TheSurfaceTool::LastVParameter(surface);
735   Standard_Integer nbsu,nbsv;
736   nbsu = TheSurfaceTool::NbSamplesU(surface,u1,u2);
737   nbsv = TheSurfaceTool::NbSamplesV(surface,v1,v2);
738   if(nbsu>40) nbsu=40;
739   if(nbsv>40) nbsv=40;
740   IntCurveSurface_ThePolyhedron    polyhedron(surface,nbsu,nbsv,u1,v1,u2,v2);
741   Perform(curve,polygon,surface,polyhedron);
742 }
743 //=======================================================================
744 //function : Perform
745 //purpose  : 
746 //=======================================================================
747 void IntCurveSurface_Inter::Perform(const TheCurve&   curve,
748                                     const TheSurface& surface,
749                                     const IntCurveSurface_ThePolyhedron& polyhedron) {
750   ResetFields();
751   done = Standard_True;
752   Standard_Real u1 = TheCurveTool::FirstParameter(curve);
753   Standard_Real u2 = TheCurveTool::LastParameter(curve);
754   IntCurveSurface_ThePolygon polygon(curve,TheCurveTool::NbSamples(curve,u1,u2));
755   Perform(curve,polygon,surface,polyhedron);
756 }
757 //=======================================================================
758 //function : Perform
759 //purpose  : 
760 //=======================================================================
761 void IntCurveSurface_Inter::Perform(const TheCurve&       curve,
762                                     const IntCurveSurface_ThePolygon&     polygon,
763                                     const TheSurface&     surface,
764                                     const IntCurveSurface_ThePolyhedron&  polyhedron) {
765   ResetFields();
766   done = Standard_True;
767   Standard_Real u1,v1,u2,v2;
768   u1 = TheSurfaceTool::FirstUParameter(surface);
769   v1 = TheSurfaceTool::FirstVParameter(surface);
770   u2 = TheSurfaceTool::LastUParameter(surface);
771   v2 = TheSurfaceTool::LastVParameter(surface);
772   InternalPerform(curve,polygon,surface,polyhedron,u1,v1,u2,v2);
773 }
774
775 //=======================================================================
776 //function : Perform
777 //purpose  : 
778 //=======================================================================
779 void IntCurveSurface_Inter::Perform(const TheCurve&       curve,
780                                     const IntCurveSurface_ThePolygon&     polygon,
781                                     const TheSurface&     surface,
782                                     const IntCurveSurface_ThePolyhedron&  polyhedron,
783                                     Bnd_BoundSortBox& BndBSB) {
784   ResetFields();
785   done = Standard_True;
786   Standard_Real u1,v1,u2,v2;
787   u1 = TheSurfaceTool::FirstUParameter(surface);
788   v1 = TheSurfaceTool::FirstVParameter(surface);
789   u2 = TheSurfaceTool::LastUParameter(surface);
790   v2 = TheSurfaceTool::LastVParameter(surface);
791   InternalPerform(curve,polygon,surface,polyhedron,u1,v1,u2,v2,BndBSB);
792 }
793 //=======================================================================
794 //function : InternalPerform
795 //purpose  : C a l c u l   d u   p o i n t   a p p r o c h e           
796 //==              p u i s   d u   p o i n t   E x a c t  
797 //=======================================================================
798 void IntCurveSurface_Inter::InternalPerform(const TheCurve&       curve,
799                                             const IntCurveSurface_ThePolygon&     polygon,
800                                             const TheSurface&     surface,
801                                             const IntCurveSurface_ThePolyhedron&  polyhedron,
802                                             const Standard_Real u0,
803                                             const Standard_Real v0,
804                                             const Standard_Real u1, 
805                                             const Standard_Real v1,
806                                             Bnd_BoundSortBox& BSB) {
807   IntCurveSurface_TheInterference  interference(polygon,polyhedron,BSB);
808   IntCurveSurface_TheCSFunction    theicsfunction(surface,curve);
809   IntCurveSurface_TheExactInter    intersectionExacte(theicsfunction,TOLTANGENCY);
810   math_FunctionSetRoot rsnld(intersectionExacte.Function());
811
812 //  Standard_Real    u,v,w,winit;
813   Standard_Real    u,v,w;
814   gp_Pnt P;
815   Standard_Real winf = polygon.InfParameter();
816   Standard_Real wsup = polygon.SupParameter();
817   Standard_Integer NbSectionPoints = interference.NbSectionPoints();
818   Standard_Integer NbTangentZones  = interference.NbTangentZones();
819
820
821   //-- Les interferences renvoient parfois de nombreuses fois (>20) les memes points 
822   
823   Standard_Integer i,NbStartPoints=NbSectionPoints;
824   for(i=1; i<= NbTangentZones; i++) {
825     const Intf_TangentZone& TZ = interference.ZoneValue(i);
826     Standard_Integer nbpnts = TZ.NumberOfPoints();
827     NbStartPoints+=nbpnts;
828   }
829   
830   if(NbStartPoints) { 
831     Standard_Real *TabU = new Standard_Real [NbStartPoints+1];
832     Standard_Real *TabV = new Standard_Real [NbStartPoints+1];
833     Standard_Real *TabW = new Standard_Real [NbStartPoints+1];
834     Standard_Integer IndexPoint=0;
835     
836     for(i=1; i<= NbSectionPoints; i++) {
837       const Intf_SectionPoint& SP = interference.PntValue(i);
838       SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
839       TabU[IndexPoint]=u;
840       TabV[IndexPoint]=v;
841       TabW[IndexPoint]=w;
842       IndexPoint++;
843     }
844     for(i=1; i<= NbTangentZones; i++) {
845       const Intf_TangentZone& TZ = interference.ZoneValue(i);
846       Standard_Integer nbpnts = TZ.NumberOfPoints();
847       for(Standard_Integer j=1; j<=nbpnts; j++) { 
848         const Intf_SectionPoint& SP = TZ.GetPoint(j);
849         SectionPointToParameters(SP,polyhedron,polygon,u,v,w);  
850         TabU[IndexPoint]=u;
851         TabV[IndexPoint]=v;
852         TabW[IndexPoint]=w;
853         IndexPoint++;
854       }
855     }
856     
857     //-- Tri
858     Standard_Real su=0,sv=0,sw=0,ptol;
859     ptol = 10*Precision::PConfusion();
860     
861     //-- Tri suivant la variable W 
862     Standard_Boolean Triok;
863     do { 
864       Triok=Standard_True;
865       Standard_Integer im1;
866       for(i=1,im1=0;i<NbStartPoints;im1++,i++) {       
867         if(TabW[i] < TabW[im1]) { 
868           Standard_Real t=TabW[i]; TabW[i]=TabW[im1]; TabW[im1]=t;
869           t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
870           t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
871           Triok=Standard_False;
872         }
873       }
874     }
875     while(Triok==Standard_False);
876     
877     //-- On trie pour des meme W suivant U
878     do { 
879       Triok=Standard_True;
880       Standard_Integer im1;
881       for(i=1,im1=0;i<NbStartPoints;im1++,i++) {       
882 // modified by NIZHNY-MKK  Mon Oct  3 17:38:49 2005
883 //      if(Abs(TabW[i]-TabW[im1])<ptol) { 
884         if((TabW[i]-TabW[im1])<ptol) { 
885           TabW[i]=TabW[im1];
886           if(TabU[i] < TabU[im1]) { 
887             Standard_Real t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
888             t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
889             Triok=Standard_False;
890           }
891         }
892       }
893     }
894     while(Triok==Standard_False);
895     
896     //-- On trie pour des meme U et W suivant V
897     do { 
898       Triok=Standard_True;
899       Standard_Integer im1;
900       for(i=1,im1=0;i<NbStartPoints;im1++,i++) {       
901 // modified by NIZHNY-MKK  Mon Oct  3 17:38:52 2005
902 //      if((Abs(TabW[i]-TabW[im1])<ptol) && (Abs(TabU[i]-TabU[im1])<ptol)) { 
903         if(((TabW[i]-TabW[im1])<ptol) && ((TabU[i]-TabU[im1])<ptol)) { 
904           TabU[i]=TabU[im1];
905           if(TabV[i] < TabV[im1]) { 
906             Standard_Real t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
907             Triok=Standard_False;
908           }
909         }
910       }
911     }
912     while(Triok==Standard_False);
913     
914     
915     for(i=0;i<NbStartPoints; i++) { 
916       u=TabU[i]; v=TabV[i]; w=TabW[i];
917       if(i==0) {
918         su=u-1; 
919       }
920       if(Abs(u-su)>ptol || Abs(v-sv)>ptol || Abs(w-sw)>ptol) { 
921         intersectionExacte.Perform(u,v,w,rsnld,u0,u1,v0,v1,winf,wsup);
922         if(intersectionExacte.IsDone()) { 
923           if(!intersectionExacte.IsEmpty()) { 
924             P=intersectionExacte.Point();
925             w=intersectionExacte.ParameterOnCurve();
926             intersectionExacte.ParameterOnSurface(u,v);
927             AppendPoint(curve,w,surface,u,v);
928           }
929         }
930       }
931       su=TabU[i]; sv=TabV[i]; sw=TabW[i];
932     }
933     delete [] TabW;
934     delete [] TabV;
935     delete [] TabU;
936   }
937 }
938
939 //=======================================================================
940 //function : InternalPerform
941 //purpose  : 
942 //=======================================================================
943 void IntCurveSurface_Inter::InternalPerform(const TheCurve&       curve,
944                                             const IntCurveSurface_ThePolygon&     polygon,
945                                             const TheSurface&     surface,
946                                             const IntCurveSurface_ThePolyhedron&  polyhedron,
947                                             const Standard_Real u0,
948                                             const Standard_Real v0,
949                                             const Standard_Real u1, 
950                                             const Standard_Real v1) { 
951   IntCurveSurface_TheInterference  interference(polygon,polyhedron);
952   IntCurveSurface_TheCSFunction    theicsfunction(surface,curve);
953   IntCurveSurface_TheExactInter    intersectionExacte(theicsfunction,TOLTANGENCY);
954   math_FunctionSetRoot rsnld(intersectionExacte.Function());
955
956 //  Standard_Real    u,v,w,winit;
957   Standard_Real    u,v,w;
958   gp_Pnt P;
959   Standard_Real winf = polygon.InfParameter();
960   Standard_Real wsup = polygon.SupParameter();
961   Standard_Integer NbSectionPoints = interference.NbSectionPoints();
962   Standard_Integer NbTangentZones  = interference.NbTangentZones();
963
964
965   //-- Les interferences renvoient parfois de nombreuses fois (>20) les memes points 
966   
967   Standard_Integer i,NbStartPoints=NbSectionPoints;
968   for(i=1; i<= NbTangentZones; i++) {
969     const Intf_TangentZone& TZ = interference.ZoneValue(i);
970     Standard_Integer nbpnts = TZ.NumberOfPoints();
971     NbStartPoints+=nbpnts;
972   }
973   
974   if(NbStartPoints) { 
975     Standard_Real *TabU = new Standard_Real [NbStartPoints+1];
976     Standard_Real *TabV = new Standard_Real [NbStartPoints+1];
977     Standard_Real *TabW = new Standard_Real [NbStartPoints+1];
978     Standard_Integer IndexPoint=0;
979     
980     for(i=1; i<= NbSectionPoints; i++) {
981       const Intf_SectionPoint& SP = interference.PntValue(i);
982       SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
983       TabU[IndexPoint]=u;
984       TabV[IndexPoint]=v;
985       TabW[IndexPoint]=w;
986       IndexPoint++;
987     }
988     for(i=1; i<= NbTangentZones; i++) {
989       const Intf_TangentZone& TZ = interference.ZoneValue(i);
990       Standard_Integer nbpnts = TZ.NumberOfPoints();
991       for(Standard_Integer j=1; j<=nbpnts; j++) { 
992         const Intf_SectionPoint& SP = TZ.GetPoint(j);
993         SectionPointToParameters(SP,polyhedron,polygon,u,v,w);  
994         TabU[IndexPoint]=u;
995         TabV[IndexPoint]=v;
996         TabW[IndexPoint]=w;
997         IndexPoint++;
998       }
999     }
1000     
1001     //-- Tri
1002     Standard_Real su=0,sv=0,sw=0,ptol;
1003     ptol = 10*Precision::PConfusion();
1004     
1005     //-- Tri suivant la variable W 
1006     Standard_Boolean Triok;
1007     do { 
1008       Triok=Standard_True;
1009       Standard_Integer im1;
1010       for(i=1,im1=0;i<NbStartPoints;im1++,i++) {       
1011         if(TabW[i] < TabW[im1]) { 
1012           Standard_Real t=TabW[i]; TabW[i]=TabW[im1]; TabW[im1]=t;
1013           t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
1014           t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
1015           Triok=Standard_False;
1016         }
1017       }
1018     }
1019     while(Triok==Standard_False);
1020     
1021     //-- On trie pour des meme W suivant U
1022     do { 
1023       Triok=Standard_True;
1024       Standard_Integer im1;
1025       for(i=1,im1=0;i<NbStartPoints;im1++,i++) {       
1026 // modified by NIZHNY-MKK  Mon Oct  3 17:38:56 2005
1027 //      if(Abs(TabW[i]-TabW[im1])<ptol) { 
1028         if((TabW[i]-TabW[im1])<ptol) { 
1029           TabW[i]=TabW[im1];
1030           if(TabU[i] < TabU[im1]) { 
1031             Standard_Real t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
1032             t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
1033             Triok=Standard_False;
1034           }
1035         }
1036       }
1037     }
1038     while(Triok==Standard_False);
1039     
1040     //-- On trie pour des meme U et W suivant V
1041     do { 
1042       Triok=Standard_True;
1043       Standard_Integer im1;
1044       for(i=1,im1=0;i<NbStartPoints;im1++,i++) {       
1045 // modified by NIZHNY-MKK  Mon Oct  3 17:38:58 2005
1046 //      if((Abs(TabW[i]-TabW[im1])<ptol) && (Abs(TabU[i]-TabU[im1])<ptol)) { 
1047         if(((TabW[i]-TabW[im1])<ptol) && ((TabU[i]-TabU[im1])<ptol)) { 
1048           TabU[i]=TabU[im1];
1049           if(TabV[i] < TabV[im1]) { 
1050             Standard_Real t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
1051             Triok=Standard_False;
1052           }
1053         }
1054       }
1055     }
1056     while(Triok==Standard_False);
1057     
1058     
1059     for(i=0;i<NbStartPoints; i++) { 
1060       u=TabU[i]; v=TabV[i]; w=TabW[i];
1061       if(i==0) {
1062         su=u-1; 
1063       }
1064       if(Abs(u-su)>ptol || Abs(v-sv)>ptol || Abs(w-sw)>ptol) { 
1065         intersectionExacte.Perform(u,v,w,rsnld,u0,u1,v0,v1,winf,wsup);
1066         if(intersectionExacte.IsDone()) { 
1067           if(!intersectionExacte.IsEmpty()) { 
1068             P=intersectionExacte.Point();
1069             w=intersectionExacte.ParameterOnCurve();
1070             intersectionExacte.ParameterOnSurface(u,v);
1071             AppendPoint(curve,w,surface,u,v);
1072           }
1073         }
1074       }
1075       su=TabU[i]; sv=TabV[i]; sw=TabW[i];
1076     }
1077     delete [] TabW;
1078     delete [] TabV;
1079     delete [] TabU;
1080   }
1081 }
1082 //=======================================================================
1083 //function : InternalPerformCurveQuadric
1084 //purpose  : 
1085 //=======================================================================
1086 void IntCurveSurface_Inter::InternalPerformCurveQuadric(const TheCurve&                 curve,
1087                                                         const TheSurface&               surface) { 
1088   IntCurveSurface_TheQuadCurvExactInter QuadCurv(surface,curve);  
1089   if(QuadCurv.IsDone()) { 
1090     Standard_Integer NbRoots = QuadCurv.NbRoots();
1091     Standard_Real u,v,w;
1092     for(Standard_Integer i = 1; i<= NbRoots; i++) { 
1093       w = QuadCurv.Root(i); 
1094       IntCurveSurface_ComputeParamsOnQuadric(surface,TheCurveTool::Value(curve,w),u,v);
1095       AppendPoint(curve,w,surface,u,v); 
1096     }
1097     //-- Intervals non traites .............................................
1098   }
1099 }
1100
1101 //=======================================================================
1102 //function : InternalPerform
1103 //purpose  : 
1104 //=======================================================================
1105 void IntCurveSurface_Inter::InternalPerform(const TheCurve&       curve,
1106                                             const IntCurveSurface_ThePolygon&  polygon,
1107                                             const TheSurface&     surface,
1108                                             const Standard_Real U1,
1109                                             const Standard_Real V1,
1110                                             const Standard_Real U2,
1111                                             const Standard_Real V2) {
1112   GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1113   if(   (SurfaceType != GeomAbs_Plane) 
1114      && (SurfaceType != GeomAbs_Cylinder)
1115      && (SurfaceType != GeomAbs_Cone) 
1116      && (SurfaceType != GeomAbs_Sphere) ) {
1117     if(SurfaceType != GeomAbs_BSplineSurface) {
1118       Standard_Integer nbsu,nbsv;
1119       nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1120       nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1121       if(nbsu>40) nbsu=40;
1122       if(nbsv>40) nbsv=40;
1123       IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2);
1124       InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2); 
1125     }
1126     else {
1127       Handle(Adaptor3d_HSurface) aS = TheSurfaceTool::UTrim(surface, U1, U2, 1.e-9);
1128       aS = aS->VTrim(V1, V2, 1.e-9);
1129       Handle(Adaptor3d_TopolTool) aTopTool = new Adaptor3d_TopolTool(aS);
1130       Standard_Real defl = 0.1;
1131       aTopTool->SamplePnts(defl, 10, 10);
1132
1133       Standard_Integer nbpu = aTopTool->NbSamplesU();
1134       Standard_Integer nbpv = aTopTool->NbSamplesV();
1135       TColStd_Array1OfReal Upars(1, nbpu), Vpars(1, nbpv);
1136       aTopTool->UParameters(Upars);
1137       aTopTool->VParameters(Vpars);
1138
1139       IntCurveSurface_ThePolyhedron polyhedron(surface,Upars, Vpars);
1140       InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2); 
1141     }
1142   }
1143   else {
1144     IntCurveSurface_TheQuadCurvExactInter QuadCurv(surface,curve);  
1145     if(QuadCurv.IsDone()) { 
1146       Standard_Integer NbRoots = QuadCurv.NbRoots();
1147       Standard_Real u,v,w;
1148       for(Standard_Integer i = 1; i<= NbRoots; i++) { 
1149         w = QuadCurv.Root(i); 
1150         IntCurveSurface_ComputeParamsOnQuadric(surface,TheCurveTool::Value(curve,w),u,v);
1151         AppendPoint(curve,w,surface,u,v); 
1152       }
1153       //-- Intervalles non traites .............................................
1154     }
1155   } //-- Fin : la Surface  est une quadrique
1156 }
1157 //=======================================================================
1158 //function : PerformConicSurf
1159 //purpose  : 
1160 //=======================================================================
1161 void IntCurveSurface_Inter::PerformConicSurf(const gp_Lin&   Line,
1162                                              const TheCurve&       curve,
1163                                              const TheSurface&     surface,
1164                                              const Standard_Real U1,
1165                                              const Standard_Real V1,
1166                                              const Standard_Real U2,
1167                                              const Standard_Real V2) {
1168   
1169
1170   GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1171   switch(SurfaceType) { 
1172   case GeomAbs_Plane: 
1173     {
1174       IntAna_IntConicQuad LinPlane(Line,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE);
1175       AppendIntAna(curve,surface,LinPlane);
1176       break;
1177     }
1178   case GeomAbs_Cylinder:
1179     {
1180       IntAna_IntConicQuad LinCylinder(Line,TheSurfaceTool::Cylinder(surface));
1181       AppendIntAna(curve,surface,LinCylinder);
1182       break;
1183     }
1184   case GeomAbs_Sphere:
1185     {
1186       IntAna_IntConicQuad LinSphere(Line,TheSurfaceTool::Sphere(surface));
1187       AppendIntAna(curve,surface,LinSphere);
1188       break;
1189     }
1190   case GeomAbs_Torus: 
1191     {
1192       IntAna_IntLinTorus intlintorus(Line,TheSurfaceTool::Torus(surface));
1193       if(intlintorus.IsDone()) { 
1194         Standard_Integer nbp = intlintorus.NbPoints();
1195         Standard_Real fi,theta,w;
1196         for(Standard_Integer i = 1; i<= nbp; i++) { 
1197 #ifndef DEB
1198           gp_Pnt P;
1199           P = intlintorus.Value(i);
1200 #else
1201           gp_Pnt P(intlintorus.Value(i));
1202 #endif
1203           w = intlintorus.ParamOnLine(i);
1204           intlintorus.ParamOnTorus(i,fi,theta);
1205           AppendPoint(curve,w,surface,fi,theta);
1206         }
1207         break;
1208       }
1209     }  //-- Si Done retourne False, On passe dans Default !! 
1210   case GeomAbs_Cone:
1211     {
1212       //OCC516(apo)->
1213       const Standard_Real correction = 1.E+5*Precision::Angular();
1214       gp_Cone cn = TheSurfaceTool::Cone(surface);
1215       if(Abs(cn.SemiAngle()) < M_PI/2.0 - correction){
1216         IntAna_IntConicQuad LinCone(Line,cn);
1217         AppendIntAna(curve,surface,LinCone);
1218         break;
1219       }//<-OCC516(apo)
1220     }   
1221   default: 
1222     {
1223       Standard_Integer nbsu,nbsv;
1224       nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1225       nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1226
1227       Standard_Boolean U1inf = Precision::IsInfinite(U1);
1228       Standard_Boolean U2inf = Precision::IsInfinite(U2);
1229       Standard_Boolean V1inf = Precision::IsInfinite(V1);
1230       Standard_Boolean V2inf = Precision::IsInfinite(V2);
1231
1232       Standard_Real U1new=U1, U2new=U2, V1new=V1, V2new=V2;
1233
1234       Standard_Boolean NoIntersection = Standard_False;
1235
1236       if(U1inf || U2inf || V1inf || V2inf ) {
1237
1238         if(SurfaceType == GeomAbs_SurfaceOfExtrusion) {
1239
1240           EstLimForInfExtr(Line, surface, Standard_False, nbsu, 
1241                            U1inf, U2inf, V1inf, V2inf, 
1242                            U1new, U2new, V1new, V2new, NoIntersection);
1243
1244         } 
1245         else if(SurfaceType == GeomAbs_SurfaceOfRevolution) {
1246
1247           EstLimForInfRevl(Line, surface,  
1248                            U1inf, U2inf, V1inf, V2inf, 
1249                            U1new, U2new, V1new, V2new, NoIntersection);
1250
1251         } 
1252         else if(SurfaceType == GeomAbs_OffsetSurface) {
1253
1254           EstLimForInfOffs(Line, surface, nbsu,  
1255                            U1inf, U2inf, V1inf, V2inf, 
1256                            U1new, U2new, V1new, V2new, NoIntersection);
1257         }
1258         else {
1259             
1260           EstLimForInfSurf(U1new, U2new, V1new, V2new);
1261         }
1262
1263       }
1264
1265
1266       if(NoIntersection) return;
1267
1268
1269       // modified by NIZHNY-OFV  Mon Aug 20 14:56:47 2001 (60963 begin)
1270       if(nbsu<20) nbsu=20;
1271       if(nbsv<20) nbsv=20;
1272       // modified by NIZHNY-OFV  Mon Aug 20 14:57:06 2001 (60963 end)
1273       IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1new,V1new,U2new,V2new);
1274       Intf_Tool                         bndTool;
1275       Bnd_Box                          boxLine;
1276       bndTool.LinBox(Line,polyhedron.Bounding(),boxLine);
1277       for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) { 
1278         Standard_Real pinf = bndTool.BeginParam(nbseg);
1279         Standard_Real psup = bndTool.EndParam(nbseg);
1280         if((psup - pinf)<1e-10) { pinf-=1e-10; psup+=1e-10; } 
1281         IntCurveSurface_ThePolygon polygon(curve, pinf,psup,2);
1282         InternalPerform(curve,polygon,surface,polyhedron,U1new,V1new,U2new,V2new);
1283       }
1284     }
1285   }
1286 }
1287 //=======================================================================
1288 //function : PerformConicSurf
1289 //purpose  : 
1290 //=======================================================================
1291 void IntCurveSurface_Inter::PerformConicSurf(const gp_Circ&        Circle,
1292                                              const TheCurve&       curve,
1293                                              const TheSurface&     surface,
1294                                              const Standard_Real U1,
1295                                              const Standard_Real V1,
1296                                              const Standard_Real U2,
1297                                              const Standard_Real V2) { 
1298   
1299   GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1300   switch(SurfaceType) { 
1301   case GeomAbs_Plane: 
1302     {
1303       IntAna_IntConicQuad CircPlane(Circle,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE,TOLERANCE);
1304       AppendIntAna(curve,surface,CircPlane);
1305       break;
1306     }
1307   case GeomAbs_Cylinder:
1308     {
1309       IntAna_IntConicQuad CircCylinder(Circle,TheSurfaceTool::Cylinder(surface));
1310       AppendIntAna(curve,surface,CircCylinder);
1311       break;
1312     }
1313   case GeomAbs_Cone:
1314     {
1315       IntAna_IntConicQuad CircCone(Circle,TheSurfaceTool::Cone(surface));
1316       AppendIntAna(curve,surface,CircCone);
1317       break;
1318     }   
1319   case GeomAbs_Sphere:
1320     {
1321       IntAna_IntConicQuad CircSphere(Circle,TheSurfaceTool::Sphere(surface));
1322       AppendIntAna(curve,surface,CircSphere);
1323       break;
1324     }
1325   default: 
1326     {
1327       IntCurveSurface_ThePolygon polygon(curve,NBSAMPLESONCIRCLE);
1328       InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
1329     }
1330   }
1331 }
1332 //=======================================================================
1333 //function : PerformConicSurf
1334 //purpose  : 
1335 //=======================================================================
1336 void IntCurveSurface_Inter::PerformConicSurf(const gp_Elips&       Ellipse,
1337                                              const TheCurve&       curve,
1338                                              const TheSurface&     surface,
1339                                              const Standard_Real U1,
1340                                              const Standard_Real V1,
1341                                              const Standard_Real U2,
1342                                              const Standard_Real V2) { 
1343
1344   GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1345   switch(SurfaceType) { 
1346   case GeomAbs_Plane: 
1347     {
1348       IntAna_IntConicQuad EllipsePlane(Ellipse,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE,TOLERANCE);
1349       AppendIntAna(curve,surface,EllipsePlane);
1350       break;
1351     }
1352   case GeomAbs_Cylinder:
1353     {
1354       IntAna_IntConicQuad EllipseCylinder(Ellipse,TheSurfaceTool::Cylinder(surface));
1355       AppendIntAna(curve,surface,EllipseCylinder);
1356       break;
1357     }
1358   case GeomAbs_Cone:
1359      {
1360       IntAna_IntConicQuad EllipseCone(Ellipse,TheSurfaceTool::Cone(surface));
1361       AppendIntAna(curve,surface,EllipseCone);
1362       break;
1363     }   
1364   case GeomAbs_Sphere:
1365     {
1366       IntAna_IntConicQuad EllipseSphere(Ellipse,TheSurfaceTool::Sphere(surface));
1367       AppendIntAna(curve,surface,EllipseSphere);
1368       break;
1369     }
1370   default: 
1371     {
1372       IntCurveSurface_ThePolygon polygon(curve,NBSAMPLESONELLIPSE);
1373       InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
1374     }
1375   }
1376 }
1377 //=======================================================================
1378 //function : PerformConicSurf
1379 //purpose  : 
1380 //=======================================================================
1381 void IntCurveSurface_Inter::PerformConicSurf(const gp_Parab&       Parab,
1382                                              const TheCurve&       curve,
1383                                              const TheSurface&     surface,
1384                                              const Standard_Real U1,
1385                                              const Standard_Real V1,
1386                                              const Standard_Real U2,
1387                                              const Standard_Real V2) { 
1388
1389   GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1390   switch(SurfaceType) { 
1391   case GeomAbs_Plane: 
1392     {
1393       IntAna_IntConicQuad ParabPlane(Parab,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE);
1394       AppendIntAna(curve,surface,ParabPlane);
1395       break;
1396     }
1397   case GeomAbs_Cylinder:
1398     {
1399       IntAna_IntConicQuad ParabCylinder(Parab,TheSurfaceTool::Cylinder(surface));
1400       AppendIntAna(curve,surface,ParabCylinder);
1401       break;
1402     }
1403   case GeomAbs_Cone:
1404      {
1405       IntAna_IntConicQuad ParabCone(Parab,TheSurfaceTool::Cone(surface));
1406       AppendIntAna(curve,surface,ParabCone);
1407       break;
1408     }   
1409   case GeomAbs_Sphere:
1410     {
1411       IntAna_IntConicQuad ParabSphere(Parab,TheSurfaceTool::Sphere(surface));
1412       AppendIntAna(curve,surface,ParabSphere);
1413       break;
1414     }
1415   default: 
1416     {
1417       Standard_Integer nbsu,nbsv;
1418       nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1419       nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1420       if(nbsu>40) nbsu=40;
1421       if(nbsv>40) nbsv=40;
1422       IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2);
1423       Intf_Tool                         bndTool;
1424       Bnd_Box                          boxParab;
1425       bndTool.ParabBox(Parab,polyhedron.Bounding(),boxParab);
1426       for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) { 
1427         IntCurveSurface_ThePolygon polygon(curve,
1428                                            bndTool.BeginParam(nbseg),
1429                                            bndTool.EndParam(nbseg),
1430                                            NBSAMPLESONPARAB);
1431         InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1432       }
1433     }
1434   }
1435 }
1436 //=======================================================================
1437 //function : PerformConicSurf
1438 //purpose  : 
1439 //=======================================================================
1440 void IntCurveSurface_Inter::PerformConicSurf(const gp_Hypr&        Hypr,
1441                                              const TheCurve&       curve,
1442                                              const TheSurface&     surface,
1443                                              const Standard_Real U1,
1444                                              const Standard_Real V1,
1445                                              const Standard_Real U2,
1446                                              const Standard_Real V2) {
1447  
1448   GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1449   switch(SurfaceType) { 
1450   case GeomAbs_Plane: 
1451     {
1452       IntAna_IntConicQuad HyprPlane(Hypr,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE);
1453       AppendIntAna(curve,surface,HyprPlane);
1454       break;
1455     }
1456   case GeomAbs_Cylinder:
1457     {
1458       IntAna_IntConicQuad HyprCylinder(Hypr,TheSurfaceTool::Cylinder(surface));
1459       AppendIntAna(curve,surface,HyprCylinder);
1460       break;
1461     }
1462   case GeomAbs_Cone:
1463      {
1464       IntAna_IntConicQuad HyprCone(Hypr,TheSurfaceTool::Cone(surface));
1465       AppendIntAna(curve,surface,HyprCone);
1466       break;
1467     }   
1468   case GeomAbs_Sphere:
1469     {
1470       IntAna_IntConicQuad HyprSphere(Hypr,TheSurfaceTool::Sphere(surface));
1471       AppendIntAna(curve,surface,HyprSphere);
1472       break;
1473     }
1474   default: 
1475     {
1476       Standard_Integer nbsu,nbsv;
1477       nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1478       nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1479       if(nbsu>40) nbsu=40;
1480       if(nbsv>40) nbsv=40;
1481       IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2);
1482       Intf_Tool                         bndTool;
1483       Bnd_Box                          boxHypr;
1484       bndTool.HyprBox(Hypr,polyhedron.Bounding(),boxHypr);
1485       for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) { 
1486         IntCurveSurface_ThePolygon polygon(curve,
1487                                            bndTool.BeginParam(nbseg),
1488                                            bndTool.EndParam(nbseg),
1489                                            NBSAMPLESONHYPR);
1490         InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1491       }
1492     }
1493   }
1494 }
1495 //=======================================================================
1496 //function : AppendIntAna
1497 //purpose  : 
1498 //=======================================================================
1499 void IntCurveSurface_Inter::AppendIntAna(const TheCurve& curve,
1500                                          const TheSurface& surface,
1501                                          const IntAna_IntConicQuad& intana_ConicQuad) {
1502   if(intana_ConicQuad.IsDone()) { 
1503     if(intana_ConicQuad.IsInQuadric()) { 
1504       //-- cout<<" Courbe Dans la Quadrique !!! Non Traite !!!"<<endl;
1505     }
1506     else if(intana_ConicQuad.IsParallel()) { 
1507       //-- cout<<" Courbe // a la Quadrique !!! Non Traite !!!"<<endl;
1508     }
1509     else { 
1510       Standard_Integer nbp = intana_ConicQuad.NbPoints();
1511       Standard_Real u,v,w;
1512       for(Standard_Integer i = 1; i<= nbp; i++) { 
1513         gp_Pnt P(intana_ConicQuad.Point(i));
1514         w = intana_ConicQuad.ParamOnConic(i);
1515         IntCurveSurface_ComputeParamsOnQuadric(surface,P,u,v);
1516         AppendPoint(curve,w,surface,u,v);
1517       }
1518     }
1519   }
1520   else { 
1521     //-- cout<<" IntAna Conic Quad Not Done  "<<endl;
1522   }
1523 }
1524 //=======================================================================
1525 //function : AppendPoint
1526 //purpose  : 
1527 //=======================================================================
1528 void IntCurveSurface_Inter::AppendPoint(const TheCurve& curve,
1529                                         const Standard_Real lw,
1530                                         const TheSurface& surface,
1531                                         const Standard_Real su,
1532                                         const Standard_Real sv) {
1533  
1534   Standard_Real W0 = TheCurveTool::FirstParameter(curve);
1535   Standard_Real W1 = TheCurveTool::LastParameter(curve);
1536   Standard_Real U0 = TheSurfaceTool::FirstUParameter(surface);
1537   Standard_Real U1 = TheSurfaceTool::LastUParameter(surface);
1538   Standard_Real V0 = TheSurfaceTool::FirstVParameter(surface);
1539   Standard_Real V1 = TheSurfaceTool::LastVParameter(surface);
1540   //-- Test si la courbe est periodique
1541   Standard_Real w = lw, u = su, v = sv;
1542
1543   GeomAbs_CurveType aCType = TheCurveTool::GetType(curve);
1544
1545   if(TheCurveTool::IsPeriodic(curve) 
1546      || aCType == GeomAbs_Circle 
1547      || aCType == GeomAbs_Ellipse) {
1548     w = ElCLib::InPeriod(w, W0, W0 + TheCurveTool::Period(curve));
1549   }
1550
1551   if((W0 - w) >= TOLTANGENCY || (w - W1) >= TOLTANGENCY) return;
1552
1553   GeomAbs_SurfaceType aSType = TheSurfaceTool::GetType(surface);
1554   if (TheSurfaceTool::IsUPeriodic(surface)
1555       || aSType == GeomAbs_Cylinder
1556       || aSType == GeomAbs_Cone
1557       || aSType == GeomAbs_Sphere) {
1558     u = ElCLib::InPeriod(u, U0, U0 + TheSurfaceTool::UPeriod(surface));
1559   }
1560
1561   if (TheSurfaceTool::IsVPeriodic(surface)) {
1562     v = ElCLib::InPeriod(v, V0, V0 + TheSurfaceTool::VPeriod(surface));
1563   }
1564
1565   if((U0 - u) >= TOLTANGENCY || (u - U1) >= TOLTANGENCY) return;
1566   if((V0 - v) >= TOLTANGENCY || (v - V1) >= TOLTANGENCY) return;
1567
1568   IntCurveSurface_TransitionOnCurve   TransOnCurve;
1569   IntCurveSurface_ComputeTransitions(curve,w,TransOnCurve,
1570                                      surface,u,v);
1571   gp_Pnt P(TheCurveTool::Value(curve,w));
1572   IntCurveSurface_IntersectionPoint IP(P,u,v,w,TransOnCurve);
1573   Append(IP); //-- invoque la methode de IntCurveSurface_Intersection.
1574   
1575 }
1576
1577 //=======================================================================
1578 //function : AppendSegment
1579 //purpose  : 
1580 //=======================================================================
1581 void IntCurveSurface_Inter::AppendSegment(const TheCurve& ,
1582                                           const Standard_Real ,
1583                                           const Standard_Real ,
1584                                           const TheSurface& ) { 
1585   //cout<<" !!! Not Yet Implemented 
1586   //IntCurveSurface_Inter::Append(const IntCurveSurf ...)"<<endl;
1587 }
1588
1589 //=======================================================================
1590 //function : SectionPointToParameters
1591 //purpose  : P o i n t   d   i n t e r f e r e n c e   - - >  
1592 //    U , V       e t   W 
1593 //=======================================================================
1594 void SectionPointToParameters(const Intf_SectionPoint&              Sp,
1595                               const IntCurveSurface_ThePolyhedron&  Polyhedron,
1596                               const IntCurveSurface_ThePolygon&     Polygon,
1597                               Standard_Real& U,
1598                               Standard_Real& V,
1599                               Standard_Real& W) {
1600   
1601   Intf_PIType       typ;
1602   Standard_Integer  Adr1,Adr2;
1603   Standard_Real     Param,u,v;
1604   gp_Pnt P(Sp.Pnt());
1605   
1606   Standard_Integer Pt1,Pt2,Pt3;
1607   Standard_Real u1,v1,param;
1608   //----------------------------------------------------------------------
1609   //--          Calcul des parametres approches sur la surface          --
1610   //----------------------------------------------------------------------
1611   
1612   Sp.InfoSecond(typ,Adr1,Adr2,Param);
1613   switch(typ) { 
1614   case Intf_VERTEX:   //-- Adr1 est le numero du vertex
1615     {
1616       Polyhedron.Parameters(Adr1,u1,v1);
1617       break;
1618     }
1619   case Intf_EDGE:
1620     {
1621       Polyhedron.Parameters(Adr1,u1,v1);    
1622       Polyhedron.Parameters(Adr2,u,v);
1623       u1+= Param * (u-u1);
1624       v1+= Param * (v-v1);
1625       break;
1626     }
1627   case Intf_FACE:
1628     {
1629       Standard_Real ua,va,ub,vb,uc,vc,ca,cb,cc,cabc;
1630       Polyhedron.Triangle(Adr1,Pt1,Pt2,Pt3);
1631       gp_Pnt PA(Polyhedron.Point(Pt1));
1632       gp_Pnt PB(Polyhedron.Point(Pt2));
1633       gp_Pnt PC(Polyhedron.Point(Pt3));
1634       Polyhedron.Parameters(Pt1,ua,va);
1635       Polyhedron.Parameters(Pt2,ub,vb);
1636       Polyhedron.Parameters(Pt3,uc,vc);
1637       gp_Vec Normale(gp_Vec(PA,PB).Crossed(gp_Vec(PA,PC)));
1638       cc = (gp_Vec(PA,PB).Crossed(gp_Vec(PA,P))).Dot(Normale);
1639       ca = (gp_Vec(PB,PC).Crossed(gp_Vec(PB,P))).Dot(Normale);
1640       cb = (gp_Vec(PC,PA).Crossed(gp_Vec(PC,P))).Dot(Normale);
1641       cabc = ca + cb + cc;
1642       
1643       ca/=cabc;     cb/=cabc;       cc/=cabc;
1644       
1645       u1 = ca * ua + cb * ub + cc * uc;
1646       v1 = ca * va + cb * vb + cc * vc;
1647       break;
1648     }
1649   default: 
1650     {
1651       cout<<" Default dans SectionPointToParameters "<<endl;
1652       break;
1653     }
1654   }
1655   //----------------------------------------------------------------------
1656   //--                Calcul du point approche sur la Curve             --
1657   //----------------------------------------------------------------------
1658   Standard_Integer SegIndex;
1659
1660   Sp.InfoFirst(typ,SegIndex,param);
1661   W = Polygon.ApproxParamOnCurve(SegIndex,param);
1662   if(param>1.0 || param<0.0) { 
1663     //-- IntCurveSurface_ThePolyhedronTool::Dump(Polyhedron);
1664     //-- IntCurveSurface_ThePolygonTool::Dump(Polygon);
1665     }
1666   U = u1;
1667   V = v1;
1668 }
1669 //=======================================================================
1670 //function : IntCurveSurface_ComputeTransitions
1671 //purpose  : 
1672 //=======================================================================
1673 void IntCurveSurface_ComputeTransitions(const TheCurve& curve,
1674                                         const Standard_Real w,
1675                                         IntCurveSurface_TransitionOnCurve&   TransOnCurve,
1676                                         const TheSurface& surface,
1677                                         const Standard_Real u,
1678                                         const Standard_Real v) { 
1679   
1680   gp_Vec NSurf,D1U,D1V;//TgCurv;
1681   gp_Pnt Psurf;
1682   Standard_Real CosDir;
1683   
1684   
1685   TheSurfaceTool::D1(surface,u,v,Psurf,D1U,D1V);
1686   NSurf = D1U.Crossed(D1V);
1687   TheCurveTool::D1(curve,w,Psurf,D1U);
1688   Standard_Real Norm = NSurf.Magnitude();
1689   if(Norm>TOLERANCE_ANGULAIRE) { 
1690     D1U.Normalize();
1691     CosDir = NSurf.Dot(D1U);
1692     CosDir/=Norm;
1693     if( -CosDir > TOLERANCE_ANGULAIRE) { 
1694       //--  --Curve--->    <----Surface----
1695       TransOnCurve   = IntCurveSurface_In;
1696     }
1697     else if(CosDir > TOLERANCE_ANGULAIRE) { 
1698       //--  --Curve--->  ----Surface-->
1699       TransOnCurve   = IntCurveSurface_Out;
1700     }     
1701     else { 
1702       TransOnCurve   = IntCurveSurface_Tangent;
1703     }
1704   }
1705   else { 
1706     TransOnCurve   = IntCurveSurface_Tangent;
1707   }
1708 }
1709 //=======================================================================
1710 //function : IntCurveSurface_ComputeParamsOnQuadric
1711 //purpose  : 
1712 //=======================================================================
1713 void IntCurveSurface_ComputeParamsOnQuadric(const TheSurface& surface,
1714                                             const gp_Pnt& P,
1715                                             Standard_Real& u,
1716                                             Standard_Real& v) { 
1717   GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1718   switch(SurfaceType) { 
1719   case GeomAbs_Plane: 
1720     {
1721       ElSLib::Parameters(TheSurfaceTool::Plane(surface),P,u,v);
1722         break;
1723       }
1724   case GeomAbs_Cylinder:
1725     {
1726       ElSLib::Parameters(TheSurfaceTool::Cylinder(surface),P,u,v);
1727         break;
1728       }
1729   case GeomAbs_Cone:
1730     {
1731       ElSLib::Parameters(TheSurfaceTool::Cone(surface),P,u,v);
1732         break;
1733       }   
1734   case GeomAbs_Sphere:
1735     {
1736       ElSLib::Parameters(TheSurfaceTool::Sphere(surface),P,u,v);
1737         break;
1738       }
1739 #ifndef DEB
1740   default:      break;      
1741 #endif
1742   }
1743 }
1744 //=======================================================================
1745 //function : EstLimForInfExtr
1746 //purpose  : Estimation of limits for infinite surfaces
1747 //=======================================================================
1748 void EstLimForInfExtr(const gp_Lin&   Line,
1749                       const TheSurface& surface, 
1750                       const Standard_Boolean IsOffSurf,
1751                       const Standard_Integer nbsu, 
1752                       const Standard_Boolean U1inf, 
1753                       const Standard_Boolean U2inf, 
1754                       const Standard_Boolean V1inf, 
1755                       const Standard_Boolean V2inf, 
1756                       Standard_Real& U1new, 
1757                       Standard_Real& U2new, 
1758                       Standard_Real& V1new, 
1759                       Standard_Real& V2new, 
1760                       Standard_Boolean& NoIntersection)
1761
1762 {
1763
1764   NoIntersection = Standard_False;
1765
1766   Handle(Adaptor3d_HSurface) aBasSurf; 
1767
1768   if(IsOffSurf) aBasSurf = TheSurfaceTool::BasisSurface(surface);
1769
1770   gp_Dir aDirOfExt;
1771
1772   if(IsOffSurf) aDirOfExt = aBasSurf->Direction();
1773   else aDirOfExt = TheSurfaceTool::Direction(surface);
1774
1775   Standard_Real tolang = TOLERANCE_ANGULAIRE;
1776
1777   if(aDirOfExt.IsParallel(Line.Direction(), tolang)) {
1778     NoIntersection = Standard_True;
1779     return;
1780   }
1781
1782   if((V1inf || V2inf) && !(U1inf || U2inf)) {
1783
1784     Standard_Real vmin = RealLast(), vmax = -vmin;
1785     gp_Lin aL;
1786     Standard_Real step = (U2new - U1new) / nbsu;
1787     Standard_Real u = U1new, v;
1788     gp_Pnt aP;
1789     Extrema_POnCurv aP1, aP2;
1790     Standard_Integer i;
1791
1792     for(i = 0; i <= nbsu; i++) {
1793
1794       TheSurfaceTool::D0(surface, u, 0., aP);
1795       aL.SetLocation(aP);
1796       aL.SetDirection(aDirOfExt);
1797
1798       Extrema_ExtElC aExtr(aL, Line, tolang);
1799       
1800       if(!aExtr.IsDone()) return;
1801
1802       if(aExtr.IsParallel()) {
1803         NoIntersection = Standard_True;
1804         return;
1805       }
1806
1807       aExtr.Points(1, aP1, aP2);
1808       v = aP1.Parameter();
1809       vmin = Min(vmin, v);
1810       vmax = Max(vmax, v);
1811
1812       u += step;
1813
1814     }
1815
1816     vmin = vmin - Abs(vmin) - 10.;
1817     vmax = vmax + Abs(vmax) + 10.;
1818
1819     V1new = Max(V1new, vmin);
1820     V2new = Min(V2new, vmax);
1821
1822   }
1823   else if(U1inf || U2inf) {
1824
1825     Standard_Real umin = RealLast(), umax = -umin;
1826     Standard_Real u0 = Min(Max(0., U1new), U2new);
1827     Standard_Real v0 = Min(Max(0., V1new), V2new);
1828     gp_Pnt aP;
1829     TheSurfaceTool::D0(surface, u0, v0, aP);
1830     gp_Pln aRefPln(aP, aDirOfExt);
1831
1832     Handle(Adaptor3d_HCurve) aBasCurv;
1833
1834     if(IsOffSurf) aBasCurv = aBasSurf->BasisCurve();
1835     else aBasCurv = TheSurfaceTool::BasisCurve(surface);
1836
1837     ProjLib_Plane Projector(aRefPln);
1838
1839     Projector.Project(Line);
1840
1841     if(!Projector.IsDone()) return;
1842
1843     gp_Lin2d Line2d = Projector.Line();
1844
1845     GeomAbs_CurveType aCurvTyp = aBasCurv->GetType();
1846
1847     if(aCurvTyp == GeomAbs_Line) {
1848       
1849       Projector.Project(aBasCurv->Line());
1850
1851       if(!Projector.IsDone()) return;
1852
1853       gp_Lin2d aL2d = Projector.Line();
1854
1855       IntAna2d_AnaIntersection anInter(Line2d, aL2d);
1856
1857       if(!anInter.IsDone()) return;
1858
1859       if(anInter.IsEmpty() || anInter.IdenticalElements() || 
1860                               anInter.ParallelElements()     ) {
1861         NoIntersection = Standard_True;
1862         return;
1863       }
1864
1865       const IntAna2d_IntPoint& anIntPnt = anInter.Point(1);
1866       umin = umax = anIntPnt.ParamOnSecond();
1867     }
1868     else if(aCurvTyp == GeomAbs_Parabola || aCurvTyp == GeomAbs_Hyperbola) {
1869
1870       IntAna2d_Conic aCon(Line2d);
1871       IntAna2d_AnaIntersection anInter;
1872       
1873       if(aCurvTyp == GeomAbs_Parabola) {
1874         Projector.Project(aBasCurv->Parabola());
1875         if(!Projector.IsDone()) return;
1876
1877         const gp_Parab2d& aP2d = Projector.Parabola();
1878
1879         anInter.Perform(aP2d, aCon);
1880       }
1881       else {
1882         Projector.Project(aBasCurv->Hyperbola());
1883         if(!Projector.IsDone()) return;
1884
1885         const gp_Hypr2d& aH2d = Projector.Hyperbola();
1886         anInter.Perform(aH2d, aCon);
1887       }
1888
1889       if(!anInter.IsDone()) return;
1890
1891       if(anInter.IsEmpty()) {
1892         NoIntersection = Standard_True;
1893         return;
1894       }
1895
1896       Standard_Integer i, nbint = anInter.NbPoints();
1897       for(i = 1; i <= nbint; i++) {
1898
1899         const IntAna2d_IntPoint& anIntPnt = anInter.Point(i);
1900
1901         umin = Min(anIntPnt.ParamOnFirst(), umin);
1902         umax = Max(anIntPnt.ParamOnFirst(), umax);
1903  
1904       }
1905
1906     }
1907     else {
1908       return;
1909     }
1910       
1911     umin = umin - Abs(umin) - 10;
1912     umax = umax + Abs(umax) + 10;
1913
1914     U1new = Max(U1new, umin);
1915     U2new = Min(U2new, umax);
1916     
1917     if(V1inf || V2inf) {
1918       EstLimForInfExtr(Line, surface, IsOffSurf, nbsu, 
1919                        Standard_False, Standard_False, V1inf, V2inf,
1920                        U1new, U2new, V1new, V2new, NoIntersection);
1921     }
1922   }
1923     
1924   return;
1925   
1926 }
1927 //=======================================================================
1928 //function : ProjectIntersectAndEstLim
1929 //purpose  : project <theLine> and it's X-axe symmetric line to <thePln> and
1930 //           intersect resulting curve with <theBasCurvProj>.
1931 //           Then estimate max and min parameters of intersection on
1932 //           <theBasCurvProj>.
1933 //           Is called from EstLimForInfRevl()
1934 //=======================================================================
1935 void ProjectIntersectAndEstLim(const gp_Lin&        theLine,
1936                                const gp_Pln&        thePln,
1937                                const ProjLib_Plane& theBasCurvProj,
1938                                Standard_Real&       theVmin,
1939                                Standard_Real&       theVmax,
1940                                Standard_Boolean&    theNoIntersection)
1941 {
1942   ProjLib_Plane aLineProj( thePln, theLine );
1943   if (!aLineProj.IsDone()) {
1944 #ifdef DEB
1945   cout
1946   << "Info: IntCurveSurface_Inter::ProjectIntersectAndEstLim(), !aLineProj.IsDone()"
1947   << endl;
1948 #endif
1949     return;
1950   }
1951   gp_Lin2d aLin2d = aLineProj.Line();
1952
1953   // make a second line X-axe symmetric to the first one 
1954   gp_Pnt2d aP1 = aLin2d.Location();
1955   gp_Pnt2d aP2 (aP1.XY() + aLin2d.Direction().XY());
1956   gp_Pnt2d aP1sym (aP1.X(), -aP1.Y());
1957   gp_Pnt2d aP2sym (aP2.X(), -aP2.Y());
1958   gp_Lin2d aLin2dsym (aP1sym, gp_Vec2d(aP1sym,aP2sym));
1959   
1960   // intersect projections
1961   IntAna2d_Conic aCon    (aLin2d);
1962   IntAna2d_Conic aConSym (aLin2dsym);
1963   IntAna2d_AnaIntersection anIntersect;
1964   IntAna2d_AnaIntersection anIntersectSym;
1965   
1966   switch (theBasCurvProj.GetType()) {
1967   case GeomAbs_Line:
1968     anIntersectSym.Perform(theBasCurvProj.Line(), aConSym); 
1969     anIntersect.Perform(theBasCurvProj.Line(), aCon); break;
1970   case GeomAbs_Hyperbola:                         
1971     anIntersectSym.Perform(theBasCurvProj.Hyperbola(), aConSym); 
1972     anIntersect.Perform(theBasCurvProj.Hyperbola(), aCon); break;
1973   case GeomAbs_Parabola:                          
1974     anIntersectSym.Perform(theBasCurvProj.Parabola(), aConSym); 
1975     anIntersect.Perform(theBasCurvProj.Parabola(), aCon); break;
1976   default:
1977     return; // not infinite curve
1978   }
1979
1980   // retrieve params of intersections
1981   Standard_Integer aNbIntPnt = anIntersect.IsDone() ? anIntersect.NbPoints() : 0;
1982   Standard_Integer aNbIntPntSym = anIntersectSym.IsDone() ? anIntersectSym.NbPoints() : 0;
1983   Standard_Integer iPnt, aNbPnt = Max (aNbIntPnt, aNbIntPntSym);
1984   
1985   if (aNbPnt == 0) {
1986     theNoIntersection = Standard_True;
1987     return;
1988   }
1989   Standard_Real aParam;
1990   for (iPnt = 1; iPnt <= aNbPnt; iPnt++)
1991   {
1992     if (iPnt <= aNbIntPnt) {
1993       const IntAna2d_IntPoint& aIntPnt = anIntersect.Point(iPnt);
1994       aParam = aIntPnt.ParamOnFirst();
1995       theVmin = Min (theVmin, aParam );
1996       theVmax = Max (theVmax, aParam );
1997     }
1998     if (iPnt <= aNbIntPntSym) {
1999       const IntAna2d_IntPoint& aIntPnt = anIntersectSym.Point(iPnt);
2000       aParam = aIntPnt.ParamOnFirst();
2001       theVmin = Min (theVmin, aParam );
2002       theVmax = Max (theVmax, aParam );
2003     }
2004   }
2005
2006   return;
2007 }
2008 //=======================================================================
2009 //function : EstLimForInfRevl
2010 //purpose  : Estimate V1 and V2 to pass to InternalPerform() if they are
2011 //           infinite for Surface of Revolution
2012 //           Algo: intersect projections of Line and basis curve on the
2013 //           plane passing through revolution axe
2014 //=======================================================================
2015 void EstLimForInfRevl(const gp_Lin&   Line,
2016                       const TheSurface& surface, 
2017                       const Standard_Boolean U1inf, 
2018                       const Standard_Boolean U2inf, 
2019                       const Standard_Boolean V1inf, 
2020                       const Standard_Boolean V2inf, 
2021                       Standard_Real& U1new, 
2022                       Standard_Real& U2new, 
2023                       Standard_Real& V1new, 
2024                       Standard_Real& V2new, 
2025                       Standard_Boolean& NoIntersection)
2026 {
2027
2028   NoIntersection = Standard_False;
2029
2030   if (U1inf || U2inf) {
2031     if (U1inf)
2032       U1new = Max (0., U1new);
2033     else
2034       U2new = Min (2 * M_PI, U2new);
2035     if (! V1inf && !V2inf) return;
2036   }
2037
2038   Handle(Adaptor3d_HCurve) aBasisCurve = TheSurfaceTool::BasisCurve(surface);
2039   gp_Ax1 aRevAx = TheSurfaceTool::AxeOfRevolution(surface);
2040   gp_Vec aXVec = aRevAx.Direction();
2041   Standard_Real aTolAng = Precision::Angular();
2042
2043   // make plane to project a basis curve
2044   gp_Pnt O = aRevAx.Location();
2045   Standard_Real aU = 0.;
2046   gp_Pnt P = aBasisCurve->Value(aU);
2047   while (O.SquareDistance(P) <= Precision::PConfusion() ||
2048          aXVec.IsParallel( gp_Vec(O,P), aTolAng)) {
2049     aU += 1.;
2050     P = aBasisCurve->Value(aU);
2051     if (aU > 3)
2052       // basis curve is a line coinciding with aXVec, P is any not on aXVec
2053       P = gp_Pnt(aU, aU+1, aU+2);
2054   }
2055   gp_Vec aNVec = aXVec ^ gp_Vec(O,P);
2056   gp_Pln aPln (gp_Ax3 (O, aNVec ,aXVec));
2057
2058   // project basic curve
2059   ProjLib_Plane aBasCurvProj(aPln);
2060   switch (aBasisCurve->GetType()) {
2061   case GeomAbs_Line:
2062     aBasCurvProj.Project(aBasisCurve->Line     ()); break;
2063   case GeomAbs_Hyperbola:                       
2064     aBasCurvProj.Project(aBasisCurve->Hyperbola()); break;
2065   case GeomAbs_Parabola:                        
2066     aBasCurvProj.Project(aBasisCurve->Parabola ()); break;
2067   default:
2068     return; // not infinite curve
2069   }
2070   if (!aBasCurvProj.IsDone()) {
2071 #ifdef DEB
2072     cout << "Info: IntCurveSurface_Inter::EstLimForInfRevl(), !aBasCurvProj.IsDone()" << endl;
2073 #endif
2074     return;
2075   }
2076   // make plane to project Line
2077   if (aXVec.IsParallel( Line.Direction(), aTolAng)) {
2078     P = Line.Location();
2079     while (O.SquareDistance(P) <= Precision::PConfusion()) {
2080       aU += 1.;
2081       P = gp_Pnt(aU, aU+1, aU+2); // any not on aXVec
2082     }
2083     aNVec = aXVec ^ gp_Vec(O,P);
2084   } else
2085     aNVec = aXVec.Crossed( Line.Direction() );
2086   
2087   aPln  = gp_Pln (gp_Ax3 (O, aNVec ,aXVec));
2088
2089   // make a second plane perpendicular to the first one, rotated around aXVec
2090   gp_Pln aPlnPrp = aPln.Rotated (gp_Ax1 (O,aXVec), M_PI/2.);
2091   
2092   // project Line and it's X-axe symmetric one to plane and intersect
2093   // resulting curve with projection of Basic Curev
2094   Standard_Real aVmin = RealLast(), aVmax = -aVmin;
2095   Standard_Boolean aNoInt1 = Standard_False, aNoInt2 = Standard_False;
2096   ProjectIntersectAndEstLim (Line, aPln,    aBasCurvProj, aVmin, aVmax, aNoInt1);
2097   ProjectIntersectAndEstLim (Line, aPlnPrp, aBasCurvProj, aVmin, aVmax, aNoInt2);
2098
2099   if (aNoInt1 && aNoInt2) {
2100     NoIntersection = Standard_True;
2101     return;
2102   }
2103   
2104   aVmin = aVmin - Abs(aVmin) - 10;
2105   aVmax = aVmax + Abs(aVmax) + 10;
2106
2107   if (V1inf) V1new = aVmin;
2108   if (V2inf) V2new = aVmax;
2109
2110   //cout << "EstLimForInfRevl: Vmin " << V1new << " Vmax " << V2new << endl;
2111   
2112   return;
2113 }
2114
2115 //=======================================================================
2116 //function : EstLimForInfOffs
2117 //purpose  : 
2118 //=======================================================================
2119 void EstLimForInfOffs(const gp_Lin&   Line,
2120                       const TheSurface& surface, 
2121                       const Standard_Integer nbsu, 
2122                       const Standard_Boolean U1inf, 
2123                       const Standard_Boolean U2inf, 
2124                       const Standard_Boolean V1inf, 
2125                       const Standard_Boolean V2inf, 
2126                       Standard_Real& U1new, 
2127                       Standard_Real& U2new, 
2128                       Standard_Real& V1new, 
2129                       Standard_Real& V2new, 
2130                       Standard_Boolean& NoIntersection)
2131 {
2132
2133   NoIntersection = Standard_False;
2134
2135   const Handle(Adaptor3d_HSurface)& aBasSurf = TheSurfaceTool::BasisSurface(surface);
2136   Standard_Real anOffVal = TheSurfaceTool::OffsetValue(surface);
2137
2138   GeomAbs_SurfaceType aTypeOfBasSurf = aBasSurf->GetType();
2139
2140   //  case for plane, cylinder and cone - make equivalent surface;
2141   if(aTypeOfBasSurf == GeomAbs_Plane) {
2142
2143     gp_Pln aPln = aBasSurf->Plane();
2144     gp_Vec aT = aPln.Position().XDirection()^aPln.Position().YDirection();
2145     aT *= anOffVal;
2146     aPln.Translate(aT);
2147     IntAna_IntConicQuad LinPlane(Line,aPln,TOLERANCE_ANGULAIRE);
2148
2149     if(!LinPlane.IsDone()) return;
2150
2151     if(LinPlane.IsParallel() || LinPlane.IsInQuadric()) {
2152
2153       NoIntersection = Standard_True;
2154       return;
2155
2156     }
2157     
2158     Standard_Real u, v;
2159     ElSLib::Parameters(aPln, LinPlane.Point(1), u, v);
2160     U1new = Max(U1new, u - 10.);
2161     U2new = Min(U2new, u + 10.);
2162     V1new = Max(V1new, v - 10.);
2163     V2new = Min(V2new, v + 10.);
2164
2165   }
2166   else if(aTypeOfBasSurf == GeomAbs_Cylinder) {
2167
2168     gp_Cylinder aCyl = aBasSurf->Cylinder();
2169
2170     Standard_Real aR = aCyl.Radius();
2171     gp_Ax3 anA = aCyl.Position();
2172
2173     if (anA.Direct()) 
2174       aR += anOffVal;
2175     else 
2176       aR -= anOffVal;
2177
2178     if ( aR >= TOLTANGENCY ) {
2179       aCyl.SetRadius(aR);
2180     }
2181     else if ( aR <= -TOLTANGENCY ){
2182       anA.Rotate(gp_Ax1(anA.Location(), anA.Direction()), M_PI);
2183       aCyl.SetPosition(anA);
2184 // modified by NIZHNY-MKK  Mon Oct  3 17:37:54 2005
2185 //       aCyl.SetRadius(Abs(aR));
2186       aCyl.SetRadius(-aR);
2187     }
2188     else {
2189
2190       NoIntersection = Standard_True;
2191       return;
2192       
2193     }
2194
2195     IntAna_IntConicQuad LinCylinder(Line, aCyl);
2196
2197     if(!LinCylinder.IsDone()) return;
2198
2199     if(LinCylinder.IsParallel() || LinCylinder.IsInQuadric()) {
2200
2201       NoIntersection = Standard_True;
2202       return;
2203
2204     }
2205     
2206     Standard_Integer i, nbp = LinCylinder.NbPoints();
2207     Standard_Real vmin = RealLast(), vmax = -vmin, u, v;
2208
2209     for(i = 1; i <= nbp; i++) {
2210
2211       ElSLib::Parameters(aCyl, LinCylinder.Point(i), u, v);
2212       vmin = Min(vmin, v);
2213       vmax = Max(vmax, v);
2214
2215     } 
2216
2217     V1new = Max(V1new, vmin - Abs(vmin) - 10.);
2218     V2new = Min(V2new, vmax + Abs(vmax) + 10.);
2219
2220   }
2221   else if(aTypeOfBasSurf == GeomAbs_Cone) {
2222
2223     gp_Cone aCon = aBasSurf->Cone();
2224     Standard_Real anAng = aCon.SemiAngle();
2225     Standard_Real aR = aCon.RefRadius() + anOffVal * Cos(anAng);
2226     gp_Ax3 anA = aCon.Position();
2227     if ( aR >= 0.) {
2228
2229       gp_Vec aZ( anA.Direction());
2230       aZ *= - anOffVal * Sin(anAng);
2231       anA.Translate(aZ);
2232       aCon.SetPosition(anA);
2233       aCon.SetRadius(aR);
2234       aCon.SetSemiAngle(anAng);
2235
2236     }
2237     else {
2238
2239       return;
2240
2241     }
2242
2243     IntAna_IntConicQuad LinCone(Line, aCon);
2244
2245     if(!LinCone.IsDone()) return;
2246
2247     if(LinCone.IsParallel() || LinCone.IsInQuadric()) {
2248
2249       NoIntersection = Standard_True;
2250       return;
2251
2252     }
2253     
2254     Standard_Integer i, nbp = LinCone.NbPoints();
2255     Standard_Real vmin = RealLast(), vmax = -vmin, u, v;
2256
2257     for(i = 1; i <= nbp; i++) {
2258
2259       ElSLib::Parameters(aCon, LinCone.Point(i), u, v);
2260       vmin = Min(vmin, v);
2261       vmax = Max(vmax, v);
2262
2263     } 
2264
2265     V1new = Max(V1new, vmin - Abs(vmin) - 10.);
2266     V2new = Min(V2new, vmax + Abs(vmax) + 10.);
2267
2268   }
2269   else if(aTypeOfBasSurf == GeomAbs_SurfaceOfExtrusion) {
2270
2271     Standard_Real anU1 = U1new, anU2 = U2new;
2272
2273     EstLimForInfExtr(Line, surface, Standard_True, nbsu, 
2274                      U1inf, U2inf, V1inf, V2inf, 
2275                      U1new, U2new, V1new, V2new, NoIntersection);
2276
2277     if(NoIntersection) return;
2278
2279     if(U1inf || U2inf) {
2280
2281       GeomAbs_CurveType aBasCurvType = aBasSurf->BasisCurve()->GetType();
2282       if(aBasCurvType == GeomAbs_Line) {
2283         U1new = Max(anU1, -1.e10);
2284         U2new = Min(anU2,  1.e10);
2285       } 
2286       else if(aBasCurvType == GeomAbs_Parabola) {
2287         gp_Parab aPrb  = aBasSurf->BasisCurve()->Parabola();
2288         Standard_Real aF = aPrb.Focal();
2289         Standard_Real dU = 2.e5 * Sqrt(aF);
2290         U1new = Max(anU1, -dU);
2291         U2new = Min(anU2,  dU);
2292       }
2293       else if(aBasCurvType == GeomAbs_Hyperbola) {
2294         U1new = Max(anU1, -30.);
2295         U2new = Min(anU2,  30.);
2296       }
2297       else {
2298         U1new = Max(anU1, -1.e10);
2299         U2new = Min(anU2,  1.e10);
2300       } 
2301
2302     }
2303
2304   }
2305   else if(aTypeOfBasSurf == GeomAbs_SurfaceOfRevolution) {
2306
2307     GeomAbs_CurveType aBasCurvType = aBasSurf->BasisCurve()->GetType();
2308     if(aBasCurvType == GeomAbs_Line) {
2309       V1new = Max(V1new, -1.e10);
2310       V2new = Min(V2new,  1.e10);
2311     }   
2312     else if(aBasCurvType == GeomAbs_Parabola) {
2313       gp_Parab aPrb  = aBasSurf->BasisCurve()->Parabola();
2314       Standard_Real aF = aPrb.Focal();
2315       Standard_Real dV = 2.e5 * Sqrt(aF);
2316       V1new = Max(V1new, -dV);
2317       V2new = Min(V2new,  dV);
2318     }
2319     else if(aBasCurvType == GeomAbs_Hyperbola) {
2320      V1new  = Max(V1new, -30.);
2321      V2new  = Min(V2new,  30.);
2322     }
2323     else {
2324      V1new  = Max(V1new, -1.e10);
2325      V2new  = Min(V2new,  1.e10);
2326     }   
2327
2328   }
2329   else {
2330
2331     V1new = Max(V1new, -1.e10);
2332     V2new = Min(V2new,  1.e10);
2333   }
2334 }
2335 //=======================================================================
2336 //function : EstLimForInfSurf
2337 //purpose  : 
2338 //=======================================================================
2339 void EstLimForInfSurf(Standard_Real& U1new, 
2340                       Standard_Real& U2new, 
2341                       Standard_Real& V1new, 
2342                       Standard_Real& V2new)
2343 {
2344     U1new = Max(U1new, -1.e10);
2345     U2new = Min(U2new,  1.e10);
2346     V1new = Max(V1new, -1.e10);
2347     V2new = Min(V2new,  1.e10);
2348 }
2349 //=======================================================================
2350 //function : DoTrim
2351 //purpose  : 
2352 //=======================================================================
2353 Standard_Boolean DoTrim(const TheCurve& curve,
2354                         const TheSurface& surface)
2355 {
2356   Standard_Boolean isAnaCurve, isAnaSurface, result;
2357   GeomAbs_CurveType aCT;
2358   GeomAbs_SurfaceType aST;
2359   
2360   isAnaCurve = Standard_False;
2361   isAnaSurface = Standard_False;
2362   //
2363   aCT=TheCurveTool::GetType(curve);
2364   //
2365   isAnaCurve= (aCT==GeomAbs_Line ||
2366                aCT==GeomAbs_Circle ||
2367                aCT==GeomAbs_Ellipse ||  
2368                aCT==GeomAbs_Hyperbola ||
2369                aCT==GeomAbs_Parabola);
2370   //
2371   aST=TheSurfaceTool::GetType(surface);
2372   isAnaSurface=(aST==GeomAbs_Plane ||
2373                 aST==GeomAbs_Cylinder ||
2374                 aST==GeomAbs_Cone ||
2375                 aST==GeomAbs_Sphere ||
2376                 aST==GeomAbs_Torus);
2377   //
2378   result = !(isAnaCurve && isAnaSurface);
2379   //
2380   if(result) {
2381     Standard_Boolean isUClosed, isVClosed; 
2382     
2383     isUClosed=(TheSurfaceTool::IsUClosed(surface) || 
2384                TheSurfaceTool::IsUPeriodic(surface));
2385     isVClosed=(TheSurfaceTool::IsVClosed(surface)
2386                || TheSurfaceTool::IsVPeriodic(surface));
2387     if(isUClosed && isVClosed) {
2388       result =!result;
2389     }
2390   }
2391    //modified by NIZNHY-PKV Wed Apr 04 12:11:01 2012f
2392   if (result) {
2393     Standard_Real aU0,aU1,aV0,aV1, dU, dV, dA, dB, aR, aTresh;
2394     //
2395     aTresh=100.;
2396     aV0 = TheSurfaceTool::FirstVParameter(surface);
2397     aV1 = TheSurfaceTool::LastVParameter(surface);
2398     aU0 = TheSurfaceTool::FirstUParameter(surface);
2399     aU1 = TheSurfaceTool::LastUParameter(surface); 
2400     dU=aU1-aU0;
2401     dV=aV1-aV0;
2402     //
2403     dA=dU;
2404     dB=dV;
2405     if (dV>dU) {
2406      dA=dV;
2407      dB=dU;
2408     }
2409     //
2410     aR=dA/dB;
2411     if (dB<Precision::PConfusion()) {
2412       result=!result;
2413       return result;
2414     }
2415     if (aR>aTresh) {
2416       result=!result;
2417     }
2418     
2419   }
2420   //modified by NIZNHY-PKV Wed Apr 04 12:11:03 2012t
2421   return result;
2422 }