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