1 // File: IntCurveSurface_Inter.gxx
2 // Created: Fri Apr 9 15:05:43 1993
3 // Author: Laurent BUCHARD
6 #define No_Standard_RangeError
7 #define No_Standard_OutOfRange
11 #define TOLTANGENCY 0.00000001
12 #define TOLERANCE_ANGULAIRE 0.00000001
13 #define TOLERANCE 0.00000001
15 #define NBSAMPLESONCIRCLE 32
16 #define NBSAMPLESONELLIPSE 32
17 #define NBSAMPLESONPARAB 16
18 #define NBSAMPLESONHYPR 32
21 #include <Intf_SectionPoint.hxx>
22 #include <Intf_TangentZone.hxx>
23 #include <Intf_Tool.hxx>
24 #include <math_FunctionSetRoot.hxx>
25 #include <IntCurveSurface_IntersectionPoint.hxx>
26 #include <IntCurveSurface_IntersectionSegment.hxx>
27 #include <IntAna_IntConicQuad.hxx>
28 #include <IntAna_Quadric.hxx>
31 #include <Precision.hxx>
32 #include <IntAna_IntLinTorus.hxx>
34 #include <GeomAbs_Shape.hxx>
35 #include <GeomAbs_CurveType.hxx>
36 #include <TColStd_Array1OfReal.hxx>
37 #include <TColgp_Array1OfPnt.hxx>
41 #include <GProp_PEquation.hxx>
42 #include <GProp_PGProps.hxx>
43 #include <GProp_PrincipalProps.hxx>
44 #include <Extrema_ExtElC.hxx>
45 #include <Extrema_POnCurv.hxx>
49 #include <Extrema_ExtPS.hxx>
53 #include <ProjLib_Plane.hxx>
54 #include <IntAna2d_AnaIntersection.hxx>
55 #include <gp_Lin2d.hxx>
56 #include <IntAna2d_IntPoint.hxx>
57 #include <gp_Parab2d.hxx>
58 #include <IntAna2d_Conic.hxx>
59 #include <IntAna2d_AnaIntersection.hxx>
60 #include <gp_Hypr2d.hxx>
61 #include <Adaptor3d_HCurve.hxx>
62 #include <Adaptor3d_HSurface.hxx>
66 #include <BndLib_Add3dCurve.hxx>
67 #include <GeomAdaptor_Curve.hxx>
68 #include <Geom_Line.hxx>
69 #include <Geom_Circle.hxx>
70 #include <Geom_Ellipse.hxx>
71 #include <Geom_Hyperbola.hxx>
72 #include <Geom_Parabola.hxx>
73 #include <Geom_TrimmedCurve.hxx>
74 #include <GeomAdaptor_Surface.hxx>
75 #include <Geom_Plane.hxx>
76 #include <Geom_CylindricalSurface.hxx>
77 #include <Geom_ConicalSurface.hxx>
78 #include <Geom_ToroidalSurface.hxx>
79 #include <Geom_SphericalSurface.hxx>
80 #include <Geom_SurfaceOfRevolution.hxx>
81 #include <Geom_SurfaceOfLinearExtrusion.hxx>
82 #include <Geom_OffsetSurface.hxx>
83 #include <Geom_RectangularTrimmedSurface.hxx>
87 #include <TColgp_Array2OfPnt.hxx>
88 #include <TColStd_HArray1OfReal.hxx>
89 #include <Adaptor3d_TopolTool.hxx>
92 //================================================================================
93 static void EstLimForInfExtr(const gp_Lin& Line,
94 const TheSurface& surface,
95 const Standard_Boolean IsOffSurf,
96 const Standard_Integer nbsu,
97 const Standard_Boolean U1inf,
98 const Standard_Boolean U2inf,
99 const Standard_Boolean V1inf,
100 const Standard_Boolean V2inf,
101 Standard_Real& U1new,
102 Standard_Real& U2new,
103 Standard_Real& V1new,
104 Standard_Real& V2new,
105 Standard_Boolean& NoIntersection);
107 //================================================================================
108 static void EstLimForInfRevl(const gp_Lin& Line,
109 const TheSurface& surface,
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);
120 //================================================================================
121 static void EstLimForInfOffs(const gp_Lin& Line,
122 const TheSurface& surface,
123 const Standard_Integer nbsu,
124 const Standard_Boolean U1inf,
125 const Standard_Boolean U2inf,
126 const Standard_Boolean V1inf,
127 const Standard_Boolean V2inf,
128 Standard_Real& U1new,
129 Standard_Real& U2new,
130 Standard_Real& V1new,
131 Standard_Real& V2new,
132 Standard_Boolean& NoIntersection);
134 //================================================================================
135 static void EstLimForInfSurf(Standard_Real& U1new,
136 Standard_Real& U2new,
137 Standard_Real& V1new,
138 Standard_Real& V2new);
140 //================================================================================
141 static void SectionPointToParameters(const Intf_SectionPoint& Sp,
142 const IntCurveSurface_ThePolyhedron& Surf,
143 const IntCurveSurface_ThePolygon& Curv,
147 //================================================================================
148 static void IntCurveSurface_ComputeTransitions(const TheCurve& curve,
149 const Standard_Real w,
150 IntCurveSurface_TransitionOnCurve& TransOnCurve,
151 const TheSurface& surface,
152 const Standard_Real u,
153 const Standard_Real v);
154 //================================================================================
155 static void IntCurveSurface_ComputeParamsOnQuadric(const TheSurface& surface,
159 //================================================================================
161 static Handle(Geom_Curve) GetCurve(const Handle(Adaptor3d_HCurve) AdCurve);
162 //================================================================================
163 static Handle(Geom_Surface) GetSurface(const Handle(Adaptor3d_HSurface) AdSurface);
165 //================================================================================
167 IntCurveSurface_Inter::IntCurveSurface_Inter() {
170 static Standard_Boolean DoTrim(const TheCurve& curve,
171 const TheSurface& surface)
173 Standard_Boolean isAnaCurve = Standard_False, isAnaSurface = Standard_False;
174 GeomAbs_CurveType CurveType = TheCurveTool::GetType(curve);
178 case GeomAbs_Ellipse:
179 case GeomAbs_Hyperbola:
180 case GeomAbs_Parabola: isAnaCurve = Standard_True; break;
183 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
184 switch (SurfaceType) {
186 case GeomAbs_Cylinder:
189 case GeomAbs_Torus: isAnaSurface = Standard_True; break;
192 Standard_Boolean result = (isAnaCurve && isAnaSurface) ? Standard_False : Standard_True;
194 Standard_Boolean isUClosed = (TheSurfaceTool::IsUClosed(surface) || TheSurfaceTool::IsUPeriodic(surface));
195 Standard_Boolean isVClosed = (TheSurfaceTool::IsVClosed(surface) || TheSurfaceTool::IsVPeriodic(surface));
196 if(isUClosed && isVClosed)
197 result = Standard_False;
202 // modified by NIZHNY-MKK Tue Jul 26 14:41:59 2005
203 // static void DoSurface(const TheSurface& surface,
204 void IntCurveSurface_Inter::DoSurface(const TheSurface& surface,
205 const Standard_Real u0,
206 const Standard_Real u1,
207 const Standard_Real v0,
208 const Standard_Real v1,
209 TColgp_Array2OfPnt& pntsOnSurface,
213 Standard_Integer iU = 0, iV = 0;
214 Standard_Real U = 0., V = 0;
215 // modified by NIZHNY-MKK Mon Oct 3 17:38:45 2005
216 // Standard_Real dU = fabs(u1-u0)/50., dV = fabs(v1-v0)/50.;
217 Standard_Real dU = (u1-u0)/50., dV = (v1-v0)/50.;
220 for(iU = 0; iU < 50; iU++) {
227 U = u0 + dU * ((Standard_Real)iU);
229 for(iV = 0; iV < 50; iV++) {
236 V = v0 + dV * ((Standard_Real)iV);
238 TheSurfaceTool::D0(surface,U,V,aPnt);
239 boxSurface.Add(aPnt);
240 pntsOnSurface.SetValue(iU+1,iV+1,aPnt);
243 Standard_Real Ures = TheSurfaceTool::UResolution(surface,dU);
244 Standard_Real Vres = TheSurfaceTool::VResolution(surface,dV);
245 gap = Max(Ures,Vres);
248 static void DoCurve(const TheCurve& curve,
251 Standard_Real CF = TheCurveTool::FirstParameter(curve);
252 Standard_Real CL = TheCurveTool::LastParameter(curve);
253 Standard_Real C = 0., dC = fabs(CL-CF)/50.;
254 Standard_Integer iC = 0;
257 for(iC = 0; iC < 50; iC++) {
263 C = CF + dC *((Standard_Real)iC);
265 TheCurveTool::D0(curve,C,aPnt);
269 static void DoCommon(TColStd_Array1OfReal& Coords,
273 Standard_Integer i = 0, j = 0;
274 for(i = 1; i <= 4; i++) {
275 for(j = i+1; j <= 4; j++) {
276 if(Coords(j) > Coords(i)) {
277 Standard_Real c = Coords(i);
278 Coords.SetValue(i,Coords(j));
279 Coords.SetValue(j,c);
287 static void DoCommonBox(const Bnd_Box& boxSurface,
288 const Bnd_Box& boxCurve,
289 TColStd_Array1OfReal& X,
290 TColStd_Array1OfReal& Y,
291 TColStd_Array1OfReal& Z)
293 Standard_Real SBXmin = 0., SBYmin = 0., SBZmin = 0.;
294 Standard_Real SBXmax = 0., SBYmax = 0., SBZmax = 0.;
295 boxSurface.Get(SBXmin,SBYmin,SBZmin,SBXmax,SBYmax,SBZmax);
297 Standard_Real CBXmin = 0., CBYmin = 0., CBZmin = 0.;
298 Standard_Real CBXmax = 0., CBYmax = 0., CBZmax = 0.;
299 boxCurve.Get(CBXmin,CBYmin,CBZmin,CBXmax,CBYmax,CBZmax);
301 TColStd_Array1OfReal Coord(1,4);
303 Coord(1) = SBXmin; Coord(2) = SBXmax; Coord(3) = CBXmin; Coord(4) = CBXmax;
304 Standard_Real CXmin = SBXmin, CXmax = SBXmax;
305 DoCommon(Coord,CXmin,CXmax);
307 Coord(1) = SBYmin; Coord(2) = SBYmax; Coord(3) = CBYmin; Coord(4) = CBYmax;
308 Standard_Real CYmin = SBYmin, CYmax = SBYmax;
309 DoCommon(Coord,CYmin,CYmax);
311 Coord(1) = SBZmin; Coord(2) = SBZmax; Coord(3) = CBZmin; Coord(4) = CBZmax;
312 Standard_Real CZmin = SBZmin, CZmax = SBZmax;
313 DoCommon(Coord,CZmin,CZmax);
315 X.SetValue(1,CXmin); X.SetValue(2,CXmax);
316 Y.SetValue(1,CYmin); Y.SetValue(2,CYmax);
317 Z.SetValue(1,CZmin); Z.SetValue(2,CZmax);
320 // modified by NIZHNY-MKK Tue Jul 26 14:41:42 2005
321 void IntCurveSurface_Inter::DoNewBounds(
322 // static void DoNewBounds(
323 const TheSurface& surface,
324 const Standard_Real u0,
325 const Standard_Real u1,
326 const Standard_Real v0,
327 const Standard_Real v1,
328 const TColgp_Array2OfPnt& pntsOnSurface,
329 const TColStd_Array1OfReal& X,
330 const TColStd_Array1OfReal& Y,
331 const TColStd_Array1OfReal& Z,
332 TColStd_Array1OfReal& Bounds)
334 Bounds.SetValue(1,u0);
335 Bounds.SetValue(2,u1);
336 Bounds.SetValue(3,v0);
337 Bounds.SetValue(4,v1);
339 Standard_Boolean isUClosed = (TheSurfaceTool::IsUClosed(surface) || TheSurfaceTool::IsUPeriodic(surface));
340 Standard_Boolean isVClosed = (TheSurfaceTool::IsVClosed(surface) || TheSurfaceTool::IsVPeriodic(surface));
341 Standard_Boolean checkU = (isUClosed) ? Standard_False : Standard_True;
342 Standard_Boolean checkV = (isVClosed) ? Standard_False : Standard_True;
344 Standard_Integer i = 0, j = 0, k = 0, iU = 0, iV = 0;
345 Standard_Integer iUmin = 50, iVmin = 50, iUmax = 1, iVmax = 1;
347 for(i = 1; i <= 2; i++) {
348 for(j = 1; j <= 2; j++) {
349 for(k = 1; k <= 2; k++) {
350 gp_Pnt aPoint(X(i),Y(j),Z(k));
351 Standard_Real DistMin = 1.e+100;
352 Standard_Integer diU = 0, diV = 0;
353 for(iU = 1; iU <= 50; iU++) {
354 for(iV = 1; iV <= 50; iV++) {
355 const gp_Pnt aP = pntsOnSurface.Value(iU,iV);
356 Standard_Real dist = aP.SquareDistance(aPoint);
364 if(diU > 0 && diU < iUmin) iUmin = diU;
365 if(diU > 0 && diU > iUmax) iUmax = diU;
366 if(diV > 0 && diV < iVmin) iVmin = diV;
367 if(diV > 0 && diV > iVmax) iVmax = diV;
372 // modified by NIZHNY-MKK Mon Oct 3 17:38:43 2005
373 // Standard_Real dU = fabs(u1-u0)/50., dV = fabs(v1-v0)/50.;
374 Standard_Real dU = (u1-u0)/50., dV = (v1-v0)/50.;
376 Standard_Real USmin = u0 + dU * ((Standard_Real)(iUmin - 1));
377 Standard_Real USmax = u0 + dU * ((Standard_Real)(iUmax - 1));
378 Standard_Real VSmin = v0 + dV * ((Standard_Real)(iVmin - 1));
379 Standard_Real VSmax = v0 + dV * ((Standard_Real)(iVmax - 1));
382 Standard_Real tmp = USmax;
387 Standard_Real tmp = VSmax;
393 if(USmin < u0) USmin = u0;
395 if(USmax > u1) USmax = u1;
397 if(VSmin < v0) VSmin = v0;
399 if(VSmax > v1) VSmax = v1;
402 Bounds.SetValue(1,USmin);
403 Bounds.SetValue(2,USmax);
406 Bounds.SetValue(3,VSmin);
407 Bounds.SetValue(4,VSmax);
411 //================================================================================
412 //== P e r f o r m g e n e r a l
414 //== Decompose la surface si besoin est
415 //================================================================================
416 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
417 const TheSurface& surface) {
419 done = Standard_True;
420 Standard_Integer NbUOnS = TheSurfaceTool::NbUIntervals(surface,GeomAbs_C2);
421 Standard_Integer NbVOnS = TheSurfaceTool::NbVIntervals(surface,GeomAbs_C2);
423 Standard_Integer NbOnC = TheCurveTool::NbIntervals(curve,GeomAbs_C2);
425 TheCurveTool::NbIntervals(curve,GeomAbs_C2);
427 Standard_Real U0,U1,V0,V1;
430 TColStd_Array1OfReal TabU(1,NbUOnS+1);
431 TheSurfaceTool::UIntervals(surface,TabU,GeomAbs_C2);
432 for(Standard_Integer iu = 1;iu <= NbUOnS; iu++) {
434 U1 = TabU.Value(iu+1);
436 TColStd_Array1OfReal TabV(1,NbVOnS+1);
437 TheSurfaceTool::VIntervals(surface,TabV,GeomAbs_C2);
438 for(Standard_Integer iv = 1;iv <= NbVOnS; iv++) {
440 V1 = TabV.Value(iv+1);
441 Perform(curve,surface,U0,V0,U1,V1);
444 else { //------ composite en U non composite en V
445 V0 = TheSurfaceTool::FirstVParameter(surface);
446 V1 = TheSurfaceTool::LastVParameter(surface);
447 Perform(curve,surface,U0,V0,U1,V1);
451 else if(NbVOnS > 1) { //---------- non composite en U composite en V
452 U0 = TheSurfaceTool::FirstUParameter(surface);
453 U1 = TheSurfaceTool::LastUParameter(surface);
454 TColStd_Array1OfReal TabV(1,NbVOnS+1);
455 TheSurfaceTool::VIntervals(surface,TabV,GeomAbs_C2);
456 for(Standard_Integer iv = 1;iv <= NbVOnS; iv++) {
458 V1 = TabV.Value(iv+1);
459 Perform(curve,surface,U0,V0,U1,V1);
463 V0 = TheSurfaceTool::FirstVParameter(surface);
464 V1 = TheSurfaceTool::LastVParameter(surface);
465 U0 = TheSurfaceTool::FirstUParameter(surface);
466 U1 = TheSurfaceTool::LastUParameter(surface);
469 Standard_Boolean doTrim = DoTrim(curve,surface);
471 TColgp_Array2OfPnt aPS(1,50,1,50);
473 Standard_Real g = 1.e-7;
474 DoSurface(surface,U0,U1,V0,V1,aPS,SB,g);
478 TColStd_Array1OfReal X(1,2), Y(1,2), Z(1,2);
479 DoCommonBox(SB,CB,X,Y,Z);
480 TColStd_Array1OfReal B(1,4);
481 DoNewBounds(surface,U0,U1,V0,V1,aPS,X,Y,Z,B);
482 U0 = B(1); U1 = B(2); V0 = B(3); V1 = B(4);
487 //-- jgv patch (from)
488 //Computing of local bounds
489 Standard_Real LocalU0 = U0, LocalU1 = U1, LocalV0 = V0, LocalV1 = V1;
490 Standard_Real Umin = RealLast(), Vmin = RealLast(), Umax = RealFirst(), Vmax = RealFirst();
492 Standard_Integer i, j, k;
493 //Making GeomAdaptor_Curve
494 Standard_Real f = TheCurveTool::FirstParameter(curve);
495 Standard_Real l = TheCurveTool::LastParameter(curve);
496 GeomAbs_CurveType CurveType = TheCurveTool::GetType(curve);
497 Handle(Geom_Curve) theCurve;
501 theCurve = new Geom_Line( TheCurveTool::Line(curve) );
504 theCurve = new Geom_Circle( TheCurveTool::Circle(curve) );
506 case GeomAbs_Ellipse:
507 theCurve = new Geom_Ellipse( TheCurveTool::Ellipse(curve) );
509 case GeomAbs_Hyperbola:
510 theCurve = new Geom_Hyperbola( TheCurveTool::Hyperbola(curve) );
512 case GeomAbs_Parabola:
513 theCurve = new Geom_Parabola( TheCurveTool::Parabola(curve) );
515 case GeomAbs_BezierCurve:
516 theCurve = TheCurveTool::Bezier(curve);
518 case GeomAbs_BSplineCurve:
519 theCurve = TheCurveTool::BSpline(curve);
522 if (!theCurve.IsNull())
524 GeomAdaptor_Curve GACurve( theCurve, f, l );
525 BndLib_Add3dCurve::Add( GACurve, Precision::Confusion(), CurveBox );
529 Standard_Integer nbp = TheCurveTool::NbSamples(curve,f,l);
530 Standard_Real delta = (f-l)/nbp;
531 for (i = 0; i <= nbp; i++)
533 gp_Pnt aPnt = TheCurveTool::Value(curve, f + i*delta);
537 Standard_Real X[2], Y[2], Z[2];
538 CurveBox.Get( X[0], Y[0], Z[0], X[1], Y[1], Z[1] );
539 Standard_Real Ures = TheSurfaceTool::UResolution(surface, Precision::Confusion());
540 Standard_Real Vres = TheSurfaceTool::VResolution(surface, Precision::Confusion());
541 //Making GeomAdaptor_Surface
542 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
543 Handle(Geom_Surface) theSurface;
547 theSurface = new Geom_Plane( TheSurfaceTool::Plane(surface) );
549 case GeomAbs_Cylinder:
550 theSurface = new Geom_CylindricalSurface( TheSurfaceTool::Cylinder(surface) );
553 theSurface = new Geom_ConicalSurface( TheSurfaceTool::Cone(surface) );
556 theSurface = new Geom_ToroidalSurface( TheSurfaceTool::Torus(surface) );
559 theSurface = new Geom_SphericalSurface( TheSurfaceTool::Sphere(surface) );
561 case GeomAbs_BezierSurface:
562 theSurface = TheSurfaceTool::Bezier(surface);
564 case GeomAbs_BSplineSurface:
565 theSurface = TheSurfaceTool::BSpline(surface);
567 case GeomAbs_SurfaceOfRevolution:
569 gp_Ax1 Axis = TheSurfaceTool::AxeOfRevolution(surface);
570 Handle(Adaptor3d_HCurve) AdBC = TheSurfaceTool::BasisCurve(surface);
571 Handle(Geom_Curve) BC = GetCurve(AdBC);
573 theSurface = new Geom_SurfaceOfRevolution( BC, Axis );
576 case GeomAbs_SurfaceOfExtrusion:
578 gp_Dir Direction = TheSurfaceTool::Direction(surface);
579 Handle(Adaptor3d_HCurve) AdBC = TheSurfaceTool::BasisCurve(surface);
580 Handle(Geom_Curve) BC = GetCurve(AdBC);
582 theSurface = new Geom_SurfaceOfLinearExtrusion( BC, Direction );
585 case GeomAbs_OffsetSurface:
587 Standard_Real OffsetValue = TheSurfaceTool::OffsetValue(surface);
588 Handle(Adaptor3d_HSurface) AdBS = TheSurfaceTool::BasisSurface(surface);
589 Handle(Geom_Surface) BS = GetSurface(AdBS);
591 theSurface = new Geom_OffsetSurface( BS, OffsetValue );
595 if (!theSurface.IsNull())
597 GeomAdaptor_Surface GASurface( theSurface );
598 Extrema_ExtPS Projector;
599 Projector.Initialize( GASurface, U0, U1, V0, V1, Ures, Vres );
600 for (i = 0; i <= 1; i++)
601 for (j = 0; j <= 1; j++)
602 for (k = 0; k <= 1; k++)
604 gp_Pnt aPoint( X[i], Y[j], Z[k] );
605 Projector.Perform( aPoint );
606 if (Projector.IsDone() && Projector.NbExt() > 0)
608 Standard_Real mindist = RealLast();
609 Standard_Integer minind, ind;
610 for (ind = 1; ind <= Projector.NbExt(); ind++)
612 Standard_Real dist = Projector.Value(ind);
619 Extrema_POnSurf pons = Projector.Point(minind);
621 pons.Parameter( U, V );
622 if (U < Umin) Umin = U;
623 if (U > Umax) Umax = U;
624 if (V < Vmin) Vmin = V;
625 if (V > Vmax) Vmax = V;
628 Umin -= Ures; Umax += Ures; Vmin -= Vres; Vmax += Vres;
629 if (Umin > U0 && Umin <= U1) LocalU0 = Umin;
630 if (Umax < U1 && Umax >= U0) LocalU1 = Umax;
631 if (Vmin > V0 && Vmin <= V1) LocalV0 = Vmin;
632 if (Vmax < V1 && Vmax >= V0) LocalV1 = Vmax;
633 U0 = LocalU0; U1 = LocalU1; V0 = LocalV0; V1 = LocalV1;
637 Perform(curve,surface,U0,V0,U1,V1);
640 //================================================================================
641 //================================================================================
642 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
643 const TheSurface& surface,
644 const Standard_Real U1,const Standard_Real V1,
645 const Standard_Real U2,const Standard_Real V2) {
647 GeomAbs_CurveType CurveType = TheCurveTool::GetType(curve);
652 PerformConicSurf(TheCurveTool::Line(curve),curve,surface,U1,V1,U2,V2);
657 PerformConicSurf(TheCurveTool::Circle(curve),curve,surface,U1,V1,U2,V2);
660 case GeomAbs_Ellipse:
662 PerformConicSurf(TheCurveTool::Ellipse(curve),curve,surface,U1,V1,U2,V2);
665 case GeomAbs_Parabola:
667 PerformConicSurf(TheCurveTool::Parabola(curve),curve,surface,U1,V1,U2,V2);
670 case GeomAbs_Hyperbola:
672 PerformConicSurf(TheCurveTool::Hyperbola(curve),curve,surface,U1,V1,U2,V2);
677 Standard_Integer nbIntervalsOnCurve = TheCurveTool::NbIntervals(curve,GeomAbs_C2);
678 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
679 if( (SurfaceType != GeomAbs_Plane)
680 && (SurfaceType != GeomAbs_Cylinder)
681 && (SurfaceType != GeomAbs_Cone)
682 && (SurfaceType != GeomAbs_Sphere)) {
684 if(nbIntervalsOnCurve > 1) {
685 TColStd_Array1OfReal TabW(1,nbIntervalsOnCurve+1);
686 TheCurveTool::Intervals(curve,TabW,GeomAbs_C2);
687 for(Standard_Integer i = 1; i<=nbIntervalsOnCurve; i++) {
690 u2 = TabW.Value(i+1);
692 Handle(TColStd_HArray1OfReal) aPars;
693 Standard_Real defl = 0.1;
694 Standard_Integer NbMin = 10;
695 TheCurveTool::SamplePars(curve, u1, u2, defl, NbMin, aPars);
697 // IntCurveSurface_ThePolygon polygon(curve,u1,u2,TheCurveTool::NbSamples(curve,u1,u2));
698 IntCurveSurface_ThePolygon polygon(curve, aPars->Array1());
699 InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
704 u1 = TheCurveTool::FirstParameter(curve);
705 u2 = TheCurveTool::LastParameter(curve);
707 Handle(TColStd_HArray1OfReal) aPars;
708 Standard_Real defl = 0.1;
709 Standard_Integer NbMin = 10;
710 TheCurveTool::SamplePars(curve, u1, u2, defl, NbMin, aPars);
712 // IntCurveSurface_ThePolygon polygon(curve,TheCurveTool::NbSamples(curve,u1,u2));
713 IntCurveSurface_ThePolygon polygon(curve, aPars->Array1());
714 InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
717 else { //-- la surface est une quadrique
718 InternalPerformCurveQuadric(curve,surface);
723 //================================================================================
724 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
725 const IntCurveSurface_ThePolygon& polygon,
726 const TheSurface& surface) {
728 done = Standard_True;
729 Standard_Real u1,v1,u2,v2;
730 u1 = TheSurfaceTool::FirstUParameter(surface);
731 v1 = TheSurfaceTool::FirstVParameter(surface);
732 u2 = TheSurfaceTool::LastUParameter(surface);
733 v2 = TheSurfaceTool::LastVParameter(surface);
734 Standard_Integer nbsu,nbsv;
735 nbsu = TheSurfaceTool::NbSamplesU(surface,u1,u2);
736 nbsv = TheSurfaceTool::NbSamplesV(surface,v1,v2);
739 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,u1,v1,u2,v2);
740 Perform(curve,polygon,surface,polyhedron);
742 //================================================================================
743 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
744 const TheSurface& surface,
745 const IntCurveSurface_ThePolyhedron& polyhedron) {
747 done = Standard_True;
748 Standard_Real u1 = TheCurveTool::FirstParameter(curve);
749 Standard_Real u2 = TheCurveTool::LastParameter(curve);
750 IntCurveSurface_ThePolygon polygon(curve,TheCurveTool::NbSamples(curve,u1,u2));
751 Perform(curve,polygon,surface,polyhedron);
753 //================================================================================
754 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
755 const IntCurveSurface_ThePolygon& polygon,
756 const TheSurface& surface,
757 const IntCurveSurface_ThePolyhedron& polyhedron) {
759 done = Standard_True;
760 Standard_Real u1,v1,u2,v2;
761 u1 = TheSurfaceTool::FirstUParameter(surface);
762 v1 = TheSurfaceTool::FirstVParameter(surface);
763 u2 = TheSurfaceTool::LastUParameter(surface);
764 v2 = TheSurfaceTool::LastVParameter(surface);
765 InternalPerform(curve,polygon,surface,polyhedron,u1,v1,u2,v2);
768 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
769 const IntCurveSurface_ThePolygon& polygon,
770 const TheSurface& surface,
771 const IntCurveSurface_ThePolyhedron& polyhedron,
772 Bnd_BoundSortBox& BndBSB) {
774 done = Standard_True;
775 Standard_Real u1,v1,u2,v2;
776 u1 = TheSurfaceTool::FirstUParameter(surface);
777 v1 = TheSurfaceTool::FirstVParameter(surface);
778 u2 = TheSurfaceTool::LastUParameter(surface);
779 v2 = TheSurfaceTool::LastVParameter(surface);
780 InternalPerform(curve,polygon,surface,polyhedron,u1,v1,u2,v2,BndBSB);
782 //================================================================================
783 //== C a l c u l d u p o i n t a p p r o c h e ==
784 //== p u i s d u p o i n t E x a c t ==
785 //================================================================================
786 void IntCurveSurface_Inter::InternalPerform(const TheCurve& curve,
787 const IntCurveSurface_ThePolygon& polygon,
788 const TheSurface& surface,
789 const IntCurveSurface_ThePolyhedron& polyhedron,
790 const Standard_Real u0,
791 const Standard_Real v0,
792 const Standard_Real u1,
793 const Standard_Real v1,
794 Bnd_BoundSortBox& BSB) {
795 IntCurveSurface_TheInterference interference(polygon,polyhedron,BSB);
796 IntCurveSurface_TheCSFunction theicsfunction(surface,curve);
797 IntCurveSurface_TheExactInter intersectionExacte(theicsfunction,TOLTANGENCY);
798 math_FunctionSetRoot rsnld(intersectionExacte.Function());
800 // Standard_Real u,v,w,winit;
803 Standard_Real winf = polygon.InfParameter();
804 Standard_Real wsup = polygon.SupParameter();
805 Standard_Integer NbSectionPoints = interference.NbSectionPoints();
806 Standard_Integer NbTangentZones = interference.NbTangentZones();
809 //-- Les interferences renvoient parfois de nombreuses fois (>20) les memes points
811 Standard_Integer i,NbStartPoints=NbSectionPoints;
812 for(i=1; i<= NbTangentZones; i++) {
813 const Intf_TangentZone& TZ = interference.ZoneValue(i);
814 Standard_Integer nbpnts = TZ.NumberOfPoints();
815 NbStartPoints+=nbpnts;
819 Standard_Real *TabU = new Standard_Real [NbStartPoints+1];
820 Standard_Real *TabV = new Standard_Real [NbStartPoints+1];
821 Standard_Real *TabW = new Standard_Real [NbStartPoints+1];
822 Standard_Integer IndexPoint=0;
824 for(i=1; i<= NbSectionPoints; i++) {
825 const Intf_SectionPoint& SP = interference.PntValue(i);
826 SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
832 for(i=1; i<= NbTangentZones; i++) {
833 const Intf_TangentZone& TZ = interference.ZoneValue(i);
834 Standard_Integer nbpnts = TZ.NumberOfPoints();
835 for(Standard_Integer j=1; j<=nbpnts; j++) {
836 const Intf_SectionPoint& SP = TZ.GetPoint(j);
837 SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
846 Standard_Real su=0,sv=0,sw=0,ptol;
847 ptol = 10*Precision::PConfusion();
849 //-- Tri suivant la variable W
850 Standard_Boolean Triok;
853 Standard_Integer im1;
854 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
855 if(TabW[i] < TabW[im1]) {
856 Standard_Real t=TabW[i]; TabW[i]=TabW[im1]; TabW[im1]=t;
857 t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
858 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
859 Triok=Standard_False;
863 while(Triok==Standard_False);
865 //-- On trie pour des meme W suivant U
868 Standard_Integer im1;
869 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
870 // modified by NIZHNY-MKK Mon Oct 3 17:38:49 2005
871 // if(Abs(TabW[i]-TabW[im1])<ptol) {
872 if((TabW[i]-TabW[im1])<ptol) {
874 if(TabU[i] < TabU[im1]) {
875 Standard_Real t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
876 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
877 Triok=Standard_False;
882 while(Triok==Standard_False);
884 //-- On trie pour des meme U et W suivant V
887 Standard_Integer im1;
888 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
889 // modified by NIZHNY-MKK Mon Oct 3 17:38:52 2005
890 // if((Abs(TabW[i]-TabW[im1])<ptol) && (Abs(TabU[i]-TabU[im1])<ptol)) {
891 if(((TabW[i]-TabW[im1])<ptol) && ((TabU[i]-TabU[im1])<ptol)) {
893 if(TabV[i] < TabV[im1]) {
894 Standard_Real t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
895 Triok=Standard_False;
900 while(Triok==Standard_False);
903 for(i=0;i<NbStartPoints; i++) {
904 u=TabU[i]; v=TabV[i]; w=TabW[i];
908 if(Abs(u-su)>ptol || Abs(v-sv)>ptol || Abs(w-sw)>ptol) {
909 intersectionExacte.Perform(u,v,w,rsnld,u0,u1,v0,v1,winf,wsup);
910 if(intersectionExacte.IsDone()) {
911 if(!intersectionExacte.IsEmpty()) {
912 P=intersectionExacte.Point();
913 w=intersectionExacte.ParameterOnCurve();
914 intersectionExacte.ParameterOnSurface(u,v);
915 AppendPoint(curve,w,surface,u,v);
919 su=TabU[i]; sv=TabV[i]; sw=TabW[i];
927 void IntCurveSurface_Inter::InternalPerform(const TheCurve& curve,
928 const IntCurveSurface_ThePolygon& polygon,
929 const TheSurface& surface,
930 const IntCurveSurface_ThePolyhedron& polyhedron,
931 const Standard_Real u0,
932 const Standard_Real v0,
933 const Standard_Real u1,
934 const Standard_Real v1) {
935 IntCurveSurface_TheInterference interference(polygon,polyhedron);
936 IntCurveSurface_TheCSFunction theicsfunction(surface,curve);
937 IntCurveSurface_TheExactInter intersectionExacte(theicsfunction,TOLTANGENCY);
938 math_FunctionSetRoot rsnld(intersectionExacte.Function());
940 // Standard_Real u,v,w,winit;
943 Standard_Real winf = polygon.InfParameter();
944 Standard_Real wsup = polygon.SupParameter();
945 Standard_Integer NbSectionPoints = interference.NbSectionPoints();
946 Standard_Integer NbTangentZones = interference.NbTangentZones();
949 //-- Les interferences renvoient parfois de nombreuses fois (>20) les memes points
951 Standard_Integer i,NbStartPoints=NbSectionPoints;
952 for(i=1; i<= NbTangentZones; i++) {
953 const Intf_TangentZone& TZ = interference.ZoneValue(i);
954 Standard_Integer nbpnts = TZ.NumberOfPoints();
955 NbStartPoints+=nbpnts;
959 Standard_Real *TabU = new Standard_Real [NbStartPoints+1];
960 Standard_Real *TabV = new Standard_Real [NbStartPoints+1];
961 Standard_Real *TabW = new Standard_Real [NbStartPoints+1];
962 Standard_Integer IndexPoint=0;
964 for(i=1; i<= NbSectionPoints; i++) {
965 const Intf_SectionPoint& SP = interference.PntValue(i);
966 SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
972 for(i=1; i<= NbTangentZones; i++) {
973 const Intf_TangentZone& TZ = interference.ZoneValue(i);
974 Standard_Integer nbpnts = TZ.NumberOfPoints();
975 for(Standard_Integer j=1; j<=nbpnts; j++) {
976 const Intf_SectionPoint& SP = TZ.GetPoint(j);
977 SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
986 Standard_Real su=0,sv=0,sw=0,ptol;
987 ptol = 10*Precision::PConfusion();
989 //-- Tri suivant la variable W
990 Standard_Boolean Triok;
993 Standard_Integer im1;
994 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
995 if(TabW[i] < TabW[im1]) {
996 Standard_Real t=TabW[i]; TabW[i]=TabW[im1]; TabW[im1]=t;
997 t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
998 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
999 Triok=Standard_False;
1003 while(Triok==Standard_False);
1005 //-- On trie pour des meme W suivant U
1007 Triok=Standard_True;
1008 Standard_Integer im1;
1009 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
1010 // modified by NIZHNY-MKK Mon Oct 3 17:38:56 2005
1011 // if(Abs(TabW[i]-TabW[im1])<ptol) {
1012 if((TabW[i]-TabW[im1])<ptol) {
1014 if(TabU[i] < TabU[im1]) {
1015 Standard_Real t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
1016 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
1017 Triok=Standard_False;
1022 while(Triok==Standard_False);
1024 //-- On trie pour des meme U et W suivant V
1026 Triok=Standard_True;
1027 Standard_Integer im1;
1028 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
1029 // modified by NIZHNY-MKK Mon Oct 3 17:38:58 2005
1030 // if((Abs(TabW[i]-TabW[im1])<ptol) && (Abs(TabU[i]-TabU[im1])<ptol)) {
1031 if(((TabW[i]-TabW[im1])<ptol) && ((TabU[i]-TabU[im1])<ptol)) {
1033 if(TabV[i] < TabV[im1]) {
1034 Standard_Real t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
1035 Triok=Standard_False;
1040 while(Triok==Standard_False);
1043 for(i=0;i<NbStartPoints; i++) {
1044 u=TabU[i]; v=TabV[i]; w=TabW[i];
1048 if(Abs(u-su)>ptol || Abs(v-sv)>ptol || Abs(w-sw)>ptol) {
1049 intersectionExacte.Perform(u,v,w,rsnld,u0,u1,v0,v1,winf,wsup);
1050 if(intersectionExacte.IsDone()) {
1051 if(!intersectionExacte.IsEmpty()) {
1052 P=intersectionExacte.Point();
1053 w=intersectionExacte.ParameterOnCurve();
1054 intersectionExacte.ParameterOnSurface(u,v);
1055 AppendPoint(curve,w,surface,u,v);
1059 su=TabU[i]; sv=TabV[i]; sw=TabW[i];
1066 //================================================================================
1067 void IntCurveSurface_Inter::InternalPerformCurveQuadric(const TheCurve& curve,
1068 const TheSurface& surface) {
1069 IntCurveSurface_TheQuadCurvExactInter QuadCurv(surface,curve);
1070 if(QuadCurv.IsDone()) {
1071 Standard_Integer NbRoots = QuadCurv.NbRoots();
1073 Standard_Integer NbInter = QuadCurv.NbIntervals();
1075 QuadCurv.NbIntervals();
1077 Standard_Real u,v,w;
1078 for(Standard_Integer i = 1; i<= NbRoots; i++) {
1079 w = QuadCurv.Root(i);
1080 IntCurveSurface_ComputeParamsOnQuadric(surface,TheCurveTool::Value(curve,w),u,v);
1081 AppendPoint(curve,w,surface,u,v);
1083 //-- Intervals non traites .............................................
1087 //================================================================================
1088 void IntCurveSurface_Inter::InternalPerform(const TheCurve& curve,
1089 const IntCurveSurface_ThePolygon& polygon,
1090 const TheSurface& surface,
1091 const Standard_Real U1,
1092 const Standard_Real V1,
1093 const Standard_Real U2,
1094 const Standard_Real V2) {
1095 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1096 if( (SurfaceType != GeomAbs_Plane)
1097 && (SurfaceType != GeomAbs_Cylinder)
1098 && (SurfaceType != GeomAbs_Cone)
1099 && (SurfaceType != GeomAbs_Sphere) ) {
1100 if(SurfaceType != GeomAbs_BSplineSurface) {
1101 Standard_Integer nbsu,nbsv;
1102 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1103 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1104 if(nbsu>40) nbsu=40;
1105 if(nbsv>40) nbsv=40;
1106 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2);
1107 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1110 Handle(Adaptor3d_HSurface) aS = TheSurfaceTool::UTrim(surface, U1, U2, 1.e-9);
1111 aS = aS->VTrim(V1, V2, 1.e-9);
1112 Handle(Adaptor3d_TopolTool) aTopTool = new Adaptor3d_TopolTool(aS);
1113 Standard_Real defl = 0.1;
1114 aTopTool->SamplePnts(defl, 10, 10);
1116 Standard_Integer nbpu = aTopTool->NbSamplesU();
1117 Standard_Integer nbpv = aTopTool->NbSamplesV();
1118 TColStd_Array1OfReal Upars(1, nbpu), Vpars(1, nbpv);
1119 aTopTool->UParameters(Upars);
1120 aTopTool->VParameters(Vpars);
1122 IntCurveSurface_ThePolyhedron polyhedron(surface,Upars, Vpars);
1123 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1127 IntCurveSurface_TheQuadCurvExactInter QuadCurv(surface,curve);
1128 if(QuadCurv.IsDone()) {
1129 Standard_Integer NbRoots = QuadCurv.NbRoots();
1131 Standard_Integer NbInter = QuadCurv.NbIntervals();
1133 QuadCurv.NbIntervals();
1135 Standard_Real u,v,w;
1136 for(Standard_Integer i = 1; i<= NbRoots; i++) {
1137 w = QuadCurv.Root(i);
1138 IntCurveSurface_ComputeParamsOnQuadric(surface,TheCurveTool::Value(curve,w),u,v);
1139 AppendPoint(curve,w,surface,u,v);
1141 //-- Intervalles non traites .............................................
1143 } //-- Fin : la Surface est une quadrique
1145 //================================================================================
1146 void IntCurveSurface_Inter::PerformConicSurf(const gp_Lin& Line,
1147 const TheCurve& curve,
1148 const TheSurface& surface,
1149 const Standard_Real U1,
1150 const Standard_Real V1,
1151 const Standard_Real U2,
1152 const Standard_Real V2) {
1155 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1156 switch(SurfaceType) {
1159 IntAna_IntConicQuad LinPlane(Line,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE);
1160 AppendIntAna(curve,surface,LinPlane);
1163 case GeomAbs_Cylinder:
1165 IntAna_IntConicQuad LinCylinder(Line,TheSurfaceTool::Cylinder(surface));
1166 AppendIntAna(curve,surface,LinCylinder);
1169 case GeomAbs_Sphere:
1171 IntAna_IntConicQuad LinSphere(Line,TheSurfaceTool::Sphere(surface));
1172 AppendIntAna(curve,surface,LinSphere);
1177 IntAna_IntLinTorus intlintorus(Line,TheSurfaceTool::Torus(surface));
1178 if(intlintorus.IsDone()) {
1179 Standard_Integer nbp = intlintorus.NbPoints();
1180 Standard_Real fi,theta,w;
1181 for(Standard_Integer i = 1; i<= nbp; i++) {
1184 P = intlintorus.Value(i);
1186 gp_Pnt P(intlintorus.Value(i));
1188 w = intlintorus.ParamOnLine(i);
1189 intlintorus.ParamOnTorus(i,fi,theta);
1190 AppendPoint(curve,w,surface,fi,theta);
1194 } //-- Si Done retourne False, On passe dans Default !!
1198 static Standard_Real correction = 1.E+5*Precision::Angular();
1199 gp_Cone cn = TheSurfaceTool::Cone(surface);
1200 if(Abs(cn.SemiAngle()) < M_PI/2.0 - correction){
1201 IntAna_IntConicQuad LinCone(Line,cn);
1202 AppendIntAna(curve,surface,LinCone);
1208 Standard_Integer nbsu,nbsv;
1209 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1210 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1212 Standard_Boolean U1inf = Precision::IsInfinite(U1);
1213 Standard_Boolean U2inf = Precision::IsInfinite(U2);
1214 Standard_Boolean V1inf = Precision::IsInfinite(V1);
1215 Standard_Boolean V2inf = Precision::IsInfinite(V2);
1217 Standard_Real U1new=U1, U2new=U2, V1new=V1, V2new=V2;
1219 Standard_Boolean NoIntersection = Standard_False;
1221 if(U1inf || U2inf || V1inf || V2inf ) {
1223 if(SurfaceType == GeomAbs_SurfaceOfExtrusion) {
1225 EstLimForInfExtr(Line, surface, Standard_False, nbsu,
1226 U1inf, U2inf, V1inf, V2inf,
1227 U1new, U2new, V1new, V2new, NoIntersection);
1230 else if(SurfaceType == GeomAbs_SurfaceOfRevolution) {
1232 EstLimForInfRevl(Line, surface,
1233 U1inf, U2inf, V1inf, V2inf,
1234 U1new, U2new, V1new, V2new, NoIntersection);
1237 else if(SurfaceType == GeomAbs_OffsetSurface) {
1239 EstLimForInfOffs(Line, surface, nbsu,
1240 U1inf, U2inf, V1inf, V2inf,
1241 U1new, U2new, V1new, V2new, NoIntersection);
1245 EstLimForInfSurf(U1new, U2new, V1new, V2new);
1251 if(NoIntersection) return;
1254 // modified by NIZHNY-OFV Mon Aug 20 14:56:47 2001 (60963 begin)
1255 if(nbsu<20) nbsu=20;
1256 if(nbsv<20) nbsv=20;
1257 // modified by NIZHNY-OFV Mon Aug 20 14:57:06 2001 (60963 end)
1258 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1new,V1new,U2new,V2new);
1261 bndTool.LinBox(Line,polyhedron.Bounding(),boxLine);
1262 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) {
1263 Standard_Real pinf = bndTool.BeginParam(nbseg);
1264 Standard_Real psup = bndTool.EndParam(nbseg);
1265 if((psup - pinf)<1e-10) { pinf-=1e-10; psup+=1e-10; }
1266 IntCurveSurface_ThePolygon polygon(curve, pinf,psup,2);
1267 InternalPerform(curve,polygon,surface,polyhedron,U1new,V1new,U2new,V2new);
1272 //================================================================================
1273 void IntCurveSurface_Inter::PerformConicSurf(const gp_Circ& Circle,
1274 const TheCurve& curve,
1275 const TheSurface& surface,
1276 const Standard_Real U1,
1277 const Standard_Real V1,
1278 const Standard_Real U2,
1279 const Standard_Real V2) {
1281 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1282 switch(SurfaceType) {
1285 IntAna_IntConicQuad CircPlane(Circle,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE,TOLERANCE);
1286 AppendIntAna(curve,surface,CircPlane);
1289 case GeomAbs_Cylinder:
1291 IntAna_IntConicQuad CircCylinder(Circle,TheSurfaceTool::Cylinder(surface));
1292 AppendIntAna(curve,surface,CircCylinder);
1297 IntAna_IntConicQuad CircCone(Circle,TheSurfaceTool::Cone(surface));
1298 AppendIntAna(curve,surface,CircCone);
1301 case GeomAbs_Sphere:
1303 IntAna_IntConicQuad CircSphere(Circle,TheSurfaceTool::Sphere(surface));
1304 AppendIntAna(curve,surface,CircSphere);
1309 IntCurveSurface_ThePolygon polygon(curve,NBSAMPLESONCIRCLE);
1310 InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
1314 //================================================================================
1315 void IntCurveSurface_Inter::PerformConicSurf(const gp_Elips& Ellipse,
1316 const TheCurve& curve,
1317 const TheSurface& surface,
1318 const Standard_Real U1,
1319 const Standard_Real V1,
1320 const Standard_Real U2,
1321 const Standard_Real V2) {
1323 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1324 switch(SurfaceType) {
1327 IntAna_IntConicQuad EllipsePlane(Ellipse,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE,TOLERANCE);
1328 AppendIntAna(curve,surface,EllipsePlane);
1331 case GeomAbs_Cylinder:
1333 IntAna_IntConicQuad EllipseCylinder(Ellipse,TheSurfaceTool::Cylinder(surface));
1334 AppendIntAna(curve,surface,EllipseCylinder);
1339 IntAna_IntConicQuad EllipseCone(Ellipse,TheSurfaceTool::Cone(surface));
1340 AppendIntAna(curve,surface,EllipseCone);
1343 case GeomAbs_Sphere:
1345 IntAna_IntConicQuad EllipseSphere(Ellipse,TheSurfaceTool::Sphere(surface));
1346 AppendIntAna(curve,surface,EllipseSphere);
1351 IntCurveSurface_ThePolygon polygon(curve,NBSAMPLESONELLIPSE);
1352 InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
1356 //================================================================================
1357 void IntCurveSurface_Inter::PerformConicSurf(const gp_Parab& Parab,
1358 const TheCurve& curve,
1359 const TheSurface& surface,
1360 const Standard_Real U1,
1361 const Standard_Real V1,
1362 const Standard_Real U2,
1363 const Standard_Real V2) {
1365 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1366 switch(SurfaceType) {
1369 IntAna_IntConicQuad ParabPlane(Parab,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE);
1370 AppendIntAna(curve,surface,ParabPlane);
1373 case GeomAbs_Cylinder:
1375 IntAna_IntConicQuad ParabCylinder(Parab,TheSurfaceTool::Cylinder(surface));
1376 AppendIntAna(curve,surface,ParabCylinder);
1381 IntAna_IntConicQuad ParabCone(Parab,TheSurfaceTool::Cone(surface));
1382 AppendIntAna(curve,surface,ParabCone);
1385 case GeomAbs_Sphere:
1387 IntAna_IntConicQuad ParabSphere(Parab,TheSurfaceTool::Sphere(surface));
1388 AppendIntAna(curve,surface,ParabSphere);
1393 Standard_Integer nbsu,nbsv;
1394 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1395 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1396 if(nbsu>40) nbsu=40;
1397 if(nbsv>40) nbsv=40;
1398 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2);
1401 bndTool.ParabBox(Parab,polyhedron.Bounding(),boxParab);
1402 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) {
1403 IntCurveSurface_ThePolygon polygon(curve,
1404 bndTool.BeginParam(nbseg),
1405 bndTool.EndParam(nbseg),
1407 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1412 //================================================================================
1413 void IntCurveSurface_Inter::PerformConicSurf(const gp_Hypr& Hypr,
1414 const TheCurve& curve,
1415 const TheSurface& surface,
1416 const Standard_Real U1,
1417 const Standard_Real V1,
1418 const Standard_Real U2,
1419 const Standard_Real V2) {
1421 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1422 switch(SurfaceType) {
1425 IntAna_IntConicQuad HyprPlane(Hypr,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE);
1426 AppendIntAna(curve,surface,HyprPlane);
1429 case GeomAbs_Cylinder:
1431 IntAna_IntConicQuad HyprCylinder(Hypr,TheSurfaceTool::Cylinder(surface));
1432 AppendIntAna(curve,surface,HyprCylinder);
1437 IntAna_IntConicQuad HyprCone(Hypr,TheSurfaceTool::Cone(surface));
1438 AppendIntAna(curve,surface,HyprCone);
1441 case GeomAbs_Sphere:
1443 IntAna_IntConicQuad HyprSphere(Hypr,TheSurfaceTool::Sphere(surface));
1444 AppendIntAna(curve,surface,HyprSphere);
1449 Standard_Integer nbsu,nbsv;
1450 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1451 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1452 if(nbsu>40) nbsu=40;
1453 if(nbsv>40) nbsv=40;
1454 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2);
1457 bndTool.HyprBox(Hypr,polyhedron.Bounding(),boxHypr);
1458 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) {
1459 IntCurveSurface_ThePolygon polygon(curve,
1460 bndTool.BeginParam(nbseg),
1461 bndTool.EndParam(nbseg),
1463 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1468 //================================================================================
1469 void IntCurveSurface_Inter::AppendIntAna(const TheCurve& curve,
1470 const TheSurface& surface,
1471 const IntAna_IntConicQuad& intana_ConicQuad) {
1472 if(intana_ConicQuad.IsDone()) {
1473 if(intana_ConicQuad.IsInQuadric()) {
1474 //-- cout<<" Courbe Dans la Quadrique !!! Non Traite !!!"<<endl;
1476 else if(intana_ConicQuad.IsParallel()) {
1477 //-- cout<<" Courbe // a la Quadrique !!! Non Traite !!!"<<endl;
1480 Standard_Integer nbp = intana_ConicQuad.NbPoints();
1481 Standard_Real u,v,w;
1482 for(Standard_Integer i = 1; i<= nbp; i++) {
1483 gp_Pnt P(intana_ConicQuad.Point(i));
1484 w = intana_ConicQuad.ParamOnConic(i);
1485 IntCurveSurface_ComputeParamsOnQuadric(surface,P,u,v);
1486 AppendPoint(curve,w,surface,u,v);
1491 //-- cout<<" IntAna Conic Quad Not Done "<<endl;
1494 //================================================================================
1495 void IntCurveSurface_Inter::AppendPoint(const TheCurve& curve,
1496 const Standard_Real lw,
1497 const TheSurface& surface,
1498 const Standard_Real su,
1499 const Standard_Real sv) {
1501 Standard_Real W0 = TheCurveTool::FirstParameter(curve);
1502 Standard_Real W1 = TheCurveTool::LastParameter(curve);
1503 Standard_Real U0 = TheSurfaceTool::FirstUParameter(surface);
1504 Standard_Real U1 = TheSurfaceTool::LastUParameter(surface);
1505 Standard_Real V0 = TheSurfaceTool::FirstVParameter(surface);
1506 Standard_Real V1 = TheSurfaceTool::LastVParameter(surface);
1507 //-- Test si la courbe est periodique
1508 Standard_Real w = lw, u = su, v = sv;
1510 GeomAbs_CurveType aCType = TheCurveTool::GetType(curve);
1512 if(TheCurveTool::IsPeriodic(curve)
1513 || aCType == GeomAbs_Circle
1514 || aCType == GeomAbs_Ellipse) {
1515 w = ElCLib::InPeriod(w, W0, W0 + TheCurveTool::Period(curve));
1518 if((W0 - w) >= TOLTANGENCY || (w - W1) >= TOLTANGENCY) return;
1520 GeomAbs_SurfaceType aSType = TheSurfaceTool::GetType(surface);
1521 if (TheSurfaceTool::IsUPeriodic(surface)
1522 || aSType == GeomAbs_Cylinder
1523 || aSType == GeomAbs_Cone
1524 || aSType == GeomAbs_Sphere) {
1525 u = ElCLib::InPeriod(u, U0, U0 + TheSurfaceTool::UPeriod(surface));
1528 if (TheSurfaceTool::IsVPeriodic(surface)) {
1529 v = ElCLib::InPeriod(v, V0, V0 + TheSurfaceTool::VPeriod(surface));
1532 if((U0 - u) >= TOLTANGENCY || (u - U1) >= TOLTANGENCY) return;
1533 if((V0 - v) >= TOLTANGENCY || (v - V1) >= TOLTANGENCY) return;
1535 IntCurveSurface_TransitionOnCurve TransOnCurve;
1536 IntCurveSurface_ComputeTransitions(curve,w,TransOnCurve,
1538 gp_Pnt P(TheCurveTool::Value(curve,w));
1539 IntCurveSurface_IntersectionPoint IP(P,u,v,w,TransOnCurve);
1540 Append(IP); //-- invoque la methode de IntCurveSurface_Intersection.
1544 //================================================================================
1545 void IntCurveSurface_Inter::AppendSegment(const TheCurve& ,
1546 const Standard_Real ,
1547 const Standard_Real ,
1548 const TheSurface& ) {
1549 cout<<" !!! Not Yet Implemented IntCurveSurface_Inter::Append(const IntCurveSurf ...)"<<endl;
1552 //================================================================================
1553 //== P o i n t d i n t e r f e r e n c e - - > U , V e t W ==
1554 //================================================================================
1555 void SectionPointToParameters(const Intf_SectionPoint& Sp,
1556 const IntCurveSurface_ThePolyhedron& Polyhedron,
1557 const IntCurveSurface_ThePolygon& Polygon,
1563 Standard_Integer Adr1,Adr2;
1564 Standard_Real Param,u,v;
1567 Standard_Integer Pt1,Pt2,Pt3;
1568 Standard_Real u1,v1,param;
1569 //----------------------------------------------------------------------
1570 //-- Calcul des parametres approches sur la surface --
1571 //----------------------------------------------------------------------
1573 Sp.InfoSecond(typ,Adr1,Adr2,Param);
1575 case Intf_VERTEX: //-- Adr1 est le numero du vertex
1577 Polyhedron.Parameters(Adr1,u1,v1);
1582 Polyhedron.Parameters(Adr1,u1,v1);
1583 Polyhedron.Parameters(Adr2,u,v);
1584 u1+= Param * (u-u1);
1585 v1+= Param * (v-v1);
1590 Standard_Real ua,va,ub,vb,uc,vc,ca,cb,cc,cabc;
1591 Polyhedron.Triangle(Adr1,Pt1,Pt2,Pt3);
1592 gp_Pnt PA(Polyhedron.Point(Pt1));
1593 gp_Pnt PB(Polyhedron.Point(Pt2));
1594 gp_Pnt PC(Polyhedron.Point(Pt3));
1595 Polyhedron.Parameters(Pt1,ua,va);
1596 Polyhedron.Parameters(Pt2,ub,vb);
1597 Polyhedron.Parameters(Pt3,uc,vc);
1598 gp_Vec Normale(gp_Vec(PA,PB).Crossed(gp_Vec(PA,PC)));
1599 cc = (gp_Vec(PA,PB).Crossed(gp_Vec(PA,P))).Dot(Normale);
1600 ca = (gp_Vec(PB,PC).Crossed(gp_Vec(PB,P))).Dot(Normale);
1601 cb = (gp_Vec(PC,PA).Crossed(gp_Vec(PC,P))).Dot(Normale);
1602 cabc = ca + cb + cc;
1604 ca/=cabc; cb/=cabc; cc/=cabc;
1606 u1 = ca * ua + cb * ub + cc * uc;
1607 v1 = ca * va + cb * vb + cc * vc;
1612 cout<<" Default dans SectionPointToParameters "<<endl;
1616 //----------------------------------------------------------------------
1617 //-- Calcul du point approche sur la Curve --
1618 //----------------------------------------------------------------------
1619 Standard_Integer SegIndex;
1621 Sp.InfoFirst(typ,SegIndex,param);
1622 W = Polygon.ApproxParamOnCurve(SegIndex,param);
1623 if(param>1.0 || param<0.0) {
1624 //-- IntCurveSurface_ThePolyhedronTool::Dump(Polyhedron);
1625 //-- IntCurveSurface_ThePolygonTool::Dump(Polygon);
1630 //================================================================================
1631 void IntCurveSurface_ComputeTransitions(const TheCurve& curve,
1632 const Standard_Real w,
1633 IntCurveSurface_TransitionOnCurve& TransOnCurve,
1634 const TheSurface& surface,
1635 const Standard_Real u,
1636 const Standard_Real v) {
1638 gp_Vec NSurf,D1U,D1V;//TgCurv;
1640 Standard_Real CosDir;
1643 TheSurfaceTool::D1(surface,u,v,Psurf,D1U,D1V);
1644 NSurf = D1U.Crossed(D1V);
1645 TheCurveTool::D1(curve,w,Psurf,D1U);
1646 Standard_Real Norm = NSurf.Magnitude();
1647 if(Norm>TOLERANCE_ANGULAIRE) {
1649 CosDir = NSurf.Dot(D1U);
1651 if( -CosDir > TOLERANCE_ANGULAIRE) {
1652 //-- --Curve---> <----Surface----
1653 TransOnCurve = IntCurveSurface_In;
1655 else if(CosDir > TOLERANCE_ANGULAIRE) {
1656 //-- --Curve---> ----Surface-->
1657 TransOnCurve = IntCurveSurface_Out;
1660 TransOnCurve = IntCurveSurface_Tangent;
1664 TransOnCurve = IntCurveSurface_Tangent;
1667 //================================================================================
1668 void IntCurveSurface_ComputeParamsOnQuadric(const TheSurface& surface,
1672 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1673 switch(SurfaceType) {
1676 ElSLib::Parameters(TheSurfaceTool::Plane(surface),P,u,v);
1679 case GeomAbs_Cylinder:
1681 ElSLib::Parameters(TheSurfaceTool::Cylinder(surface),P,u,v);
1686 ElSLib::Parameters(TheSurfaceTool::Cone(surface),P,u,v);
1689 case GeomAbs_Sphere:
1691 ElSLib::Parameters(TheSurfaceTool::Sphere(surface),P,u,v);
1699 //================================================================================
1706 Standard_Real u1,v1,u2,v2;
1707 u1 = TheSurfaceTool::FirstUParameter(surface);
1708 v1 = TheSurfaceTool::FirstVParameter(surface);
1709 u2 = TheSurfaceTool::LastUParameter(surface);
1710 v2 = TheSurfaceTool::LastVParameter(surface);
1711 Standard_Integer nbsu,nbsv;
1712 nbsu = TheSurfaceTool::NbSamplesU(surface,u1,u2);
1713 nbsv = TheSurfaceTool::NbSamplesV(surface,v1,v2);
1714 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,u1,v1,u2,v2);
1717 //====================================================================================
1718 // Estimation of limits for infinite surfaces
1719 //====================================================================================
1721 //================================================================================
1722 static void EstLimForInfExtr(const gp_Lin& Line,
1723 const TheSurface& surface,
1724 const Standard_Boolean IsOffSurf,
1725 const Standard_Integer nbsu,
1726 const Standard_Boolean U1inf,
1727 const Standard_Boolean U2inf,
1728 const Standard_Boolean V1inf,
1729 const Standard_Boolean V2inf,
1730 Standard_Real& U1new,
1731 Standard_Real& U2new,
1732 Standard_Real& V1new,
1733 Standard_Real& V2new,
1734 Standard_Boolean& NoIntersection)
1738 NoIntersection = Standard_False;
1740 Handle(Adaptor3d_HSurface) aBasSurf;
1742 if(IsOffSurf) aBasSurf = TheSurfaceTool::BasisSurface(surface);
1746 if(IsOffSurf) aDirOfExt = aBasSurf->Direction();
1747 else aDirOfExt = TheSurfaceTool::Direction(surface);
1749 Standard_Real tolang = TOLERANCE_ANGULAIRE;
1751 if(aDirOfExt.IsParallel(Line.Direction(), tolang)) {
1752 NoIntersection = Standard_True;
1756 if((V1inf || V2inf) && !(U1inf || U2inf)) {
1758 Standard_Real vmin = RealLast(), vmax = -vmin;
1760 Standard_Real step = (U2new - U1new) / nbsu;
1761 Standard_Real u = U1new, v;
1763 Extrema_POnCurv aP1, aP2;
1766 for(i = 0; i <= nbsu; i++) {
1768 TheSurfaceTool::D0(surface, u, 0., aP);
1770 aL.SetDirection(aDirOfExt);
1772 Extrema_ExtElC aExtr(aL, Line, tolang);
1774 if(!aExtr.IsDone()) return;
1776 if(aExtr.IsParallel()) {
1777 NoIntersection = Standard_True;
1781 aExtr.Points(1, aP1, aP2);
1782 v = aP1.Parameter();
1783 vmin = Min(vmin, v);
1784 vmax = Max(vmax, v);
1790 vmin = vmin - Abs(vmin) - 10.;
1791 vmax = vmax + Abs(vmax) + 10.;
1793 V1new = Max(V1new, vmin);
1794 V2new = Min(V2new, vmax);
1797 else if(U1inf || U2inf) {
1799 Standard_Real umin = RealLast(), umax = -umin;
1800 Standard_Real u0 = Min(Max(0., U1new), U2new);
1801 Standard_Real v0 = Min(Max(0., V1new), V2new);
1803 TheSurfaceTool::D0(surface, u0, v0, aP);
1804 gp_Pln aRefPln(aP, aDirOfExt);
1806 Handle(Adaptor3d_HCurve) aBasCurv;
1808 if(IsOffSurf) aBasCurv = aBasSurf->BasisCurve();
1809 else aBasCurv = TheSurfaceTool::BasisCurve(surface);
1811 ProjLib_Plane Projector(aRefPln);
1813 Projector.Project(Line);
1815 if(!Projector.IsDone()) return;
1817 gp_Lin2d Line2d = Projector.Line();
1819 GeomAbs_CurveType aCurvTyp = aBasCurv->GetType();
1821 if(aCurvTyp == GeomAbs_Line) {
1823 Projector.Project(aBasCurv->Line());
1825 if(!Projector.IsDone()) return;
1827 gp_Lin2d aL2d = Projector.Line();
1829 IntAna2d_AnaIntersection anInter(Line2d, aL2d);
1831 if(!anInter.IsDone()) return;
1833 if(anInter.IsEmpty() || anInter.IdenticalElements() ||
1834 anInter.ParallelElements() ) {
1835 NoIntersection = Standard_True;
1839 const IntAna2d_IntPoint& anIntPnt = anInter.Point(1);
1840 umin = umax = anIntPnt.ParamOnSecond();
1842 else if(aCurvTyp == GeomAbs_Parabola || aCurvTyp == GeomAbs_Hyperbola) {
1844 IntAna2d_Conic aCon(Line2d);
1845 IntAna2d_AnaIntersection anInter;
1847 if(aCurvTyp == GeomAbs_Parabola) {
1848 Projector.Project(aBasCurv->Parabola());
1849 if(!Projector.IsDone()) return;
1851 const gp_Parab2d& aP2d = Projector.Parabola();
1853 anInter.Perform(aP2d, aCon);
1856 Projector.Project(aBasCurv->Hyperbola());
1857 if(!Projector.IsDone()) return;
1859 const gp_Hypr2d& aH2d = Projector.Hyperbola();
1860 anInter.Perform(aH2d, aCon);
1863 if(!anInter.IsDone()) return;
1865 if(anInter.IsEmpty()) {
1866 NoIntersection = Standard_True;
1870 Standard_Integer i, nbint = anInter.NbPoints();
1871 for(i = 1; i <= nbint; i++) {
1873 const IntAna2d_IntPoint& anIntPnt = anInter.Point(i);
1875 umin = Min(anIntPnt.ParamOnFirst(), umin);
1876 umax = Max(anIntPnt.ParamOnFirst(), umax);
1885 umin = umin - Abs(umin) - 10;
1886 umax = umax + Abs(umax) + 10;
1888 U1new = Max(U1new, umin);
1889 U2new = Min(U2new, umax);
1891 if(V1inf || V2inf) {
1892 EstLimForInfExtr(Line, surface, IsOffSurf, nbsu,
1893 Standard_False, Standard_False, V1inf, V2inf,
1894 U1new, U2new, V1new, V2new, NoIntersection);
1902 //================================================================================
1903 //=======================================================================
1904 //function : ProjectIntersectAndEstLim
1905 //purpose : project <theLine> and it's X-axe symmetric line to <thePln> and
1906 // intersect resulting curve with <theBasCurvProj>.
1907 // Then estimate max and min parameters of intersection on
1908 // <theBasCurvProj>.
1909 // Is called from EstLimForInfRevl()
1910 //=======================================================================
1912 static void ProjectIntersectAndEstLim(const gp_Lin& theLine,
1913 const gp_Pln& thePln,
1914 const ProjLib_Plane& theBasCurvProj,
1915 Standard_Real& theVmin,
1916 Standard_Real& theVmax,
1917 Standard_Boolean& theNoIntersection)
1919 ProjLib_Plane aLineProj( thePln, theLine );
1920 if (!aLineProj.IsDone()) {
1923 << "Info: IntCurveSurface_Inter::ProjectIntersectAndEstLim(), !aLineProj.IsDone()"
1928 gp_Lin2d aLin2d = aLineProj.Line();
1930 // make a second line X-axe symmetric to the first one
1931 gp_Pnt2d aP1 = aLin2d.Location();
1932 gp_Pnt2d aP2 (aP1.XY() + aLin2d.Direction().XY());
1933 gp_Pnt2d aP1sym (aP1.X(), -aP1.Y());
1934 gp_Pnt2d aP2sym (aP2.X(), -aP2.Y());
1935 gp_Lin2d aLin2dsym (aP1sym, gp_Vec2d(aP1sym,aP2sym));
1937 // intersect projections
1938 IntAna2d_Conic aCon (aLin2d);
1939 IntAna2d_Conic aConSym (aLin2dsym);
1940 IntAna2d_AnaIntersection anIntersect;
1941 IntAna2d_AnaIntersection anIntersectSym;
1943 switch (theBasCurvProj.GetType()) {
1945 anIntersectSym.Perform(theBasCurvProj.Line(), aConSym);
1946 anIntersect.Perform(theBasCurvProj.Line(), aCon); break;
1947 case GeomAbs_Hyperbola:
1948 anIntersectSym.Perform(theBasCurvProj.Hyperbola(), aConSym);
1949 anIntersect.Perform(theBasCurvProj.Hyperbola(), aCon); break;
1950 case GeomAbs_Parabola:
1951 anIntersectSym.Perform(theBasCurvProj.Parabola(), aConSym);
1952 anIntersect.Perform(theBasCurvProj.Parabola(), aCon); break;
1954 return; // not infinite curve
1957 // retrieve params of intersections
1958 Standard_Integer aNbIntPnt = anIntersect.IsDone() ? anIntersect.NbPoints() : 0;
1959 Standard_Integer aNbIntPntSym = anIntersectSym.IsDone() ? anIntersectSym.NbPoints() : 0;
1960 Standard_Integer iPnt, aNbPnt = Max (aNbIntPnt, aNbIntPntSym);
1963 theNoIntersection = Standard_True;
1966 Standard_Real aParam;
1967 for (iPnt = 1; iPnt <= aNbPnt; iPnt++)
1969 if (iPnt <= aNbIntPnt) {
1970 const IntAna2d_IntPoint& aIntPnt = anIntersect.Point(iPnt);
1971 aParam = aIntPnt.ParamOnFirst();
1972 theVmin = Min (theVmin, aParam );
1973 theVmax = Max (theVmax, aParam );
1975 if (iPnt <= aNbIntPntSym) {
1976 const IntAna2d_IntPoint& aIntPnt = anIntersectSym.Point(iPnt);
1977 aParam = aIntPnt.ParamOnFirst();
1978 theVmin = Min (theVmin, aParam );
1979 theVmax = Max (theVmax, aParam );
1985 //=======================================================================
1986 //function : EstLimForInfRevl
1987 //purpose : Estimate V1 and V2 to pass to InternalPerform() if they are
1988 // infinite for Surface of Revolution
1989 // Algo: intersect projections of Line and basis curve on the
1990 // plane passing through revolution axe
1991 //=======================================================================
1993 static void EstLimForInfRevl(const gp_Lin& Line,
1994 const TheSurface& surface,
1995 const Standard_Boolean U1inf,
1996 const Standard_Boolean U2inf,
1997 const Standard_Boolean V1inf,
1998 const Standard_Boolean V2inf,
1999 Standard_Real& U1new,
2000 Standard_Real& U2new,
2001 Standard_Real& V1new,
2002 Standard_Real& V2new,
2003 Standard_Boolean& NoIntersection)
2006 NoIntersection = Standard_False;
2008 if (U1inf || U2inf) {
2010 U1new = Max (0., U1new);
2012 U2new = Min (2 * M_PI, U2new);
2013 if (! V1inf && !V2inf) return;
2016 Handle(Adaptor3d_HCurve) aBasisCurve = TheSurfaceTool::BasisCurve(surface);
2017 gp_Ax1 aRevAx = TheSurfaceTool::AxeOfRevolution(surface);
2018 gp_Vec aXVec = aRevAx.Direction();
2019 Standard_Real aTolAng = Precision::Angular();
2021 // make plane to project a basis curve
2022 gp_Pnt O = aRevAx.Location();
2023 Standard_Real aU = 0.;
2024 gp_Pnt P = aBasisCurve->Value(aU);
2025 while (O.SquareDistance(P) <= Precision::PConfusion() ||
2026 aXVec.IsParallel( gp_Vec(O,P), aTolAng)) {
2028 P = aBasisCurve->Value(aU);
2030 // basis curve is a line coinciding with aXVec, P is any not on aXVec
2031 P = gp_Pnt(aU, aU+1, aU+2);
2033 gp_Vec aNVec = aXVec ^ gp_Vec(O,P);
2034 gp_Pln aPln (gp_Ax3 (O, aNVec ,aXVec));
2036 // project basic curve
2037 ProjLib_Plane aBasCurvProj(aPln);
2038 switch (aBasisCurve->GetType()) {
2040 aBasCurvProj.Project(aBasisCurve->Line ()); break;
2041 case GeomAbs_Hyperbola:
2042 aBasCurvProj.Project(aBasisCurve->Hyperbola()); break;
2043 case GeomAbs_Parabola:
2044 aBasCurvProj.Project(aBasisCurve->Parabola ()); break;
2046 return; // not infinite curve
2048 if (!aBasCurvProj.IsDone()) {
2050 cout << "Info: IntCurveSurface_Inter::EstLimForInfRevl(), !aBasCurvProj.IsDone()" << endl;
2054 // make plane to project Line
2055 if (aXVec.IsParallel( Line.Direction(), aTolAng)) {
2056 P = Line.Location();
2057 while (O.SquareDistance(P) <= Precision::PConfusion()) {
2059 P = gp_Pnt(aU, aU+1, aU+2); // any not on aXVec
2061 aNVec = aXVec ^ gp_Vec(O,P);
2063 aNVec = aXVec.Crossed( Line.Direction() );
2065 aPln = gp_Pln (gp_Ax3 (O, aNVec ,aXVec));
2067 // make a second plane perpendicular to the first one, rotated around aXVec
2068 gp_Pln aPlnPrp = aPln.Rotated (gp_Ax1 (O,aXVec), M_PI/2.);
2070 // project Line and it's X-axe symmetric one to plane and intersect
2071 // resulting curve with projection of Basic Curev
2072 Standard_Real aVmin = RealLast(), aVmax = -aVmin;
2073 Standard_Boolean aNoInt1 = Standard_False, aNoInt2 = Standard_False;
2074 ProjectIntersectAndEstLim (Line, aPln, aBasCurvProj, aVmin, aVmax, aNoInt1);
2075 ProjectIntersectAndEstLim (Line, aPlnPrp, aBasCurvProj, aVmin, aVmax, aNoInt2);
2077 if (aNoInt1 && aNoInt2) {
2078 NoIntersection = Standard_True;
2082 aVmin = aVmin - Abs(aVmin) - 10;
2083 aVmax = aVmax + Abs(aVmax) + 10;
2085 if (V1inf) V1new = aVmin;
2086 if (V2inf) V2new = aVmax;
2088 //cout << "EstLimForInfRevl: Vmin " << V1new << " Vmax " << V2new << endl;
2093 //================================================================================
2094 static void EstLimForInfOffs(const gp_Lin& Line,
2095 const TheSurface& surface,
2096 const Standard_Integer nbsu,
2097 const Standard_Boolean U1inf,
2098 const Standard_Boolean U2inf,
2099 const Standard_Boolean V1inf,
2100 const Standard_Boolean V2inf,
2101 Standard_Real& U1new,
2102 Standard_Real& U2new,
2103 Standard_Real& V1new,
2104 Standard_Real& V2new,
2105 Standard_Boolean& NoIntersection)
2108 NoIntersection = Standard_False;
2110 const Handle(Adaptor3d_HSurface)& aBasSurf = TheSurfaceTool::BasisSurface(surface);
2111 Standard_Real anOffVal = TheSurfaceTool::OffsetValue(surface);
2113 GeomAbs_SurfaceType aTypeOfBasSurf = aBasSurf->GetType();
2115 // case for plane, cylinder and cone - make equivalent surface;
2116 if(aTypeOfBasSurf == GeomAbs_Plane) {
2118 gp_Pln aPln = aBasSurf->Plane();
2119 gp_Vec aT = aPln.Position().XDirection()^aPln.Position().YDirection();
2122 IntAna_IntConicQuad LinPlane(Line,aPln,TOLERANCE_ANGULAIRE);
2124 if(!LinPlane.IsDone()) return;
2126 if(LinPlane.IsParallel() || LinPlane.IsInQuadric()) {
2128 NoIntersection = Standard_True;
2134 ElSLib::Parameters(aPln, LinPlane.Point(1), u, v);
2135 U1new = Max(U1new, u - 10.);
2136 U2new = Min(U2new, u + 10.);
2137 V1new = Max(V1new, v - 10.);
2138 V2new = Min(V2new, v + 10.);
2141 else if(aTypeOfBasSurf == GeomAbs_Cylinder) {
2143 gp_Cylinder aCyl = aBasSurf->Cylinder();
2145 Standard_Real aR = aCyl.Radius();
2146 gp_Ax3 anA = aCyl.Position();
2153 if ( aR >= TOLTANGENCY ) {
2156 else if ( aR <= -TOLTANGENCY ){
2157 anA.Rotate(gp_Ax1(anA.Location(), anA.Direction()), M_PI);
2158 aCyl.SetPosition(anA);
2159 // modified by NIZHNY-MKK Mon Oct 3 17:37:54 2005
2160 // aCyl.SetRadius(Abs(aR));
2161 aCyl.SetRadius(-aR);
2165 NoIntersection = Standard_True;
2170 IntAna_IntConicQuad LinCylinder(Line, aCyl);
2172 if(!LinCylinder.IsDone()) return;
2174 if(LinCylinder.IsParallel() || LinCylinder.IsInQuadric()) {
2176 NoIntersection = Standard_True;
2181 Standard_Integer i, nbp = LinCylinder.NbPoints();
2182 Standard_Real vmin = RealLast(), vmax = -vmin, u, v;
2184 for(i = 1; i <= nbp; i++) {
2186 ElSLib::Parameters(aCyl, LinCylinder.Point(i), u, v);
2187 vmin = Min(vmin, v);
2188 vmax = Max(vmax, v);
2192 V1new = Max(V1new, vmin - Abs(vmin) - 10.);
2193 V2new = Min(V2new, vmax + Abs(vmax) + 10.);
2196 else if(aTypeOfBasSurf == GeomAbs_Cone) {
2198 gp_Cone aCon = aBasSurf->Cone();
2199 Standard_Real anAng = aCon.SemiAngle();
2200 Standard_Real aR = aCon.RefRadius() + anOffVal * Cos(anAng);
2201 gp_Ax3 anA = aCon.Position();
2204 gp_Vec aZ( anA.Direction());
2205 aZ *= - anOffVal * Sin(anAng);
2207 aCon.SetPosition(anA);
2209 aCon.SetSemiAngle(anAng);
2218 IntAna_IntConicQuad LinCone(Line, aCon);
2220 if(!LinCone.IsDone()) return;
2222 if(LinCone.IsParallel() || LinCone.IsInQuadric()) {
2224 NoIntersection = Standard_True;
2229 Standard_Integer i, nbp = LinCone.NbPoints();
2230 Standard_Real vmin = RealLast(), vmax = -vmin, u, v;
2232 for(i = 1; i <= nbp; i++) {
2234 ElSLib::Parameters(aCon, LinCone.Point(i), u, v);
2235 vmin = Min(vmin, v);
2236 vmax = Max(vmax, v);
2240 V1new = Max(V1new, vmin - Abs(vmin) - 10.);
2241 V2new = Min(V2new, vmax + Abs(vmax) + 10.);
2244 else if(aTypeOfBasSurf == GeomAbs_SurfaceOfExtrusion) {
2246 Standard_Real anU1 = U1new, anU2 = U2new;
2248 EstLimForInfExtr(Line, surface, Standard_True, nbsu,
2249 U1inf, U2inf, V1inf, V2inf,
2250 U1new, U2new, V1new, V2new, NoIntersection);
2252 if(NoIntersection) return;
2254 if(U1inf || U2inf) {
2256 GeomAbs_CurveType aBasCurvType = aBasSurf->BasisCurve()->GetType();
2257 if(aBasCurvType == GeomAbs_Line) {
2258 U1new = Max(anU1, -1.e10);
2259 U2new = Min(anU2, 1.e10);
2261 else if(aBasCurvType == GeomAbs_Parabola) {
2262 gp_Parab aPrb = aBasSurf->BasisCurve()->Parabola();
2263 Standard_Real aF = aPrb.Focal();
2264 Standard_Real dU = 2.e5 * Sqrt(aF);
2265 U1new = Max(anU1, -dU);
2266 U2new = Min(anU2, dU);
2268 else if(aBasCurvType == GeomAbs_Hyperbola) {
2269 U1new = Max(anU1, -30.);
2270 U2new = Min(anU2, 30.);
2273 U1new = Max(anU1, -1.e10);
2274 U2new = Min(anU2, 1.e10);
2280 else if(aTypeOfBasSurf == GeomAbs_SurfaceOfRevolution) {
2282 GeomAbs_CurveType aBasCurvType = aBasSurf->BasisCurve()->GetType();
2283 if(aBasCurvType == GeomAbs_Line) {
2284 V1new = Max(V1new, -1.e10);
2285 V2new = Min(V2new, 1.e10);
2287 else if(aBasCurvType == GeomAbs_Parabola) {
2288 gp_Parab aPrb = aBasSurf->BasisCurve()->Parabola();
2289 Standard_Real aF = aPrb.Focal();
2290 Standard_Real dV = 2.e5 * Sqrt(aF);
2291 V1new = Max(V1new, -dV);
2292 V2new = Min(V2new, dV);
2294 else if(aBasCurvType == GeomAbs_Hyperbola) {
2295 V1new = Max(V1new, -30.);
2296 V2new = Min(V2new, 30.);
2299 V1new = Max(V1new, -1.e10);
2300 V2new = Min(V2new, 1.e10);
2306 V1new = Max(V1new, -1.e10);
2307 V2new = Min(V2new, 1.e10);
2313 //================================================================================
2314 static void EstLimForInfSurf(Standard_Real& U1new,
2315 Standard_Real& U2new,
2316 Standard_Real& V1new,
2317 Standard_Real& V2new)
2319 U1new = Max(U1new, -1.e10);
2320 U2new = Min(U2new, 1.e10);
2321 V1new = Max(V1new, -1.e10);
2322 V2new = Min(V2new, 1.e10);
2326 //-- jgv patch (from)
2327 static Handle(Geom_Curve) GetCurve(const Handle(Adaptor3d_HCurve) AdCurve)
2329 Handle(Geom_Curve) theCurve;
2330 GeomAbs_CurveType CurveType = AdCurve->GetType();
2334 theCurve = new Geom_Line( AdCurve->Line() );
2336 case GeomAbs_Circle:
2337 theCurve = new Geom_Circle( AdCurve->Circle() );
2339 case GeomAbs_Ellipse:
2340 theCurve = new Geom_Ellipse( AdCurve->Ellipse() );
2342 case GeomAbs_Hyperbola:
2343 theCurve = new Geom_Hyperbola( AdCurve->Hyperbola() );
2345 case GeomAbs_Parabola:
2346 theCurve = new Geom_Parabola( AdCurve->Parabola() );
2348 case GeomAbs_BezierCurve:
2349 theCurve = AdCurve->Bezier();
2351 case GeomAbs_BSplineCurve:
2352 theCurve = AdCurve->BSpline();
2355 if (!theCurve.IsNull())
2357 Standard_Real f = AdCurve->FirstParameter();
2358 Standard_Real l = AdCurve->LastParameter();
2359 theCurve = new Geom_TrimmedCurve( theCurve, f, l );
2364 static Handle(Geom_Surface) GetSurface(const Handle(Adaptor3d_HSurface) AdSurface)
2366 Handle(Geom_Surface) theSurface;
2367 GeomAbs_SurfaceType SurfaceType = AdSurface->GetType();
2368 switch (SurfaceType)
2371 theSurface = new Geom_Plane( AdSurface->Plane() );
2373 case GeomAbs_Cylinder:
2374 theSurface = new Geom_CylindricalSurface( AdSurface->Cylinder() );
2377 theSurface = new Geom_ConicalSurface( AdSurface->Cone() );
2380 theSurface = new Geom_ToroidalSurface( AdSurface->Torus() );
2382 case GeomAbs_Sphere:
2383 theSurface = new Geom_SphericalSurface( AdSurface->Sphere() );
2385 case GeomAbs_BezierSurface:
2386 theSurface = AdSurface->Bezier();
2388 case GeomAbs_BSplineSurface:
2389 theSurface = AdSurface->BSpline();
2391 case GeomAbs_SurfaceOfRevolution:
2393 gp_Ax1 Axis = AdSurface->AxeOfRevolution();
2394 Handle(Adaptor3d_HCurve) AdBC = AdSurface->BasisCurve();
2395 Handle(Geom_Curve) BC = GetCurve(AdBC);
2397 theSurface = new Geom_SurfaceOfRevolution( BC, Axis );
2400 case GeomAbs_SurfaceOfExtrusion:
2402 gp_Dir Direction = AdSurface->Direction();
2403 Handle(Adaptor3d_HCurve) AdBC = AdSurface->BasisCurve();
2404 Handle(Geom_Curve) BC = GetCurve(AdBC);
2406 theSurface = new Geom_SurfaceOfLinearExtrusion( BC, Direction );
2410 if (!theSurface.IsNull())
2412 Standard_Real uf = AdSurface->FirstUParameter();
2413 Standard_Real ul = AdSurface->LastUParameter();
2414 Standard_Real vf = AdSurface->FirstVParameter();
2415 Standard_Real vl = AdSurface->LastVParameter();
2416 theSurface = new Geom_RectangularTrimmedSurface( theSurface, uf, ul, vf, vl );