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