1 // Created on: 1993-04-09
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
22 //#define No_Standard_RangeError
23 //#define No_Standard_OutOfRange
27 #define TOLTANGENCY 0.00000001
28 #define TOLERANCE_ANGULAIRE 1.e-12//0.00000001
29 #define TOLERANCE 0.00000001
31 #define NBSAMPLESONCIRCLE 32
32 #define NBSAMPLESONELLIPSE 32
33 #define NBSAMPLESONPARAB 16
34 #define NBSAMPLESONHYPR 32
37 #include <Intf_SectionPoint.hxx>
38 #include <Intf_TangentZone.hxx>
39 #include <Intf_Tool.hxx>
40 #include <math_FunctionSetRoot.hxx>
41 #include <IntCurveSurface_IntersectionPoint.hxx>
42 #include <IntCurveSurface_IntersectionSegment.hxx>
43 #include <IntAna_IntConicQuad.hxx>
44 #include <IntAna_Quadric.hxx>
47 #include <Precision.hxx>
48 #include <IntAna_IntLinTorus.hxx>
50 #include <GeomAbs_Shape.hxx>
51 #include <GeomAbs_CurveType.hxx>
52 #include <TColStd_Array1OfReal.hxx>
53 #include <TColgp_Array1OfPnt.hxx>
57 #include <GProp_PEquation.hxx>
58 #include <GProp_PGProps.hxx>
59 #include <GProp_PrincipalProps.hxx>
60 #include <Extrema_ExtElC.hxx>
61 #include <Extrema_POnCurv.hxx>
65 #include <ProjLib_Plane.hxx>
66 #include <IntAna2d_AnaIntersection.hxx>
67 #include <gp_Lin2d.hxx>
68 #include <IntAna2d_IntPoint.hxx>
69 #include <gp_Parab2d.hxx>
70 #include <IntAna2d_Conic.hxx>
71 #include <IntAna2d_AnaIntersection.hxx>
72 #include <gp_Hypr2d.hxx>
73 #include <Adaptor3d_HCurve.hxx>
74 #include <Adaptor3d_HSurface.hxx>
77 #include <TColgp_Array2OfPnt.hxx>
78 #include <TColStd_HArray1OfReal.hxx>
79 #include <Adaptor3d_TopolTool.hxx>
83 void EstLimForInfExtr(const gp_Lin& Line,
84 const TheSurface& surface,
85 const Standard_Boolean IsOffSurf,
86 const Standard_Integer nbsu,
87 const Standard_Boolean U1inf,
88 const Standard_Boolean U2inf,
89 const Standard_Boolean V1inf,
90 const Standard_Boolean V2inf,
95 Standard_Boolean& NoIntersection);
98 void EstLimForInfRevl(const gp_Lin& Line,
99 const TheSurface& surface,
100 const Standard_Boolean U1inf,
101 const Standard_Boolean U2inf,
102 const Standard_Boolean V1inf,
103 const Standard_Boolean V2inf,
104 Standard_Real& U1new,
105 Standard_Real& U2new,
106 Standard_Real& V1new,
107 Standard_Real& V2new,
108 Standard_Boolean& NoIntersection);
111 void EstLimForInfOffs(const gp_Lin& Line,
112 const TheSurface& surface,
113 const Standard_Integer nbsu,
114 const Standard_Boolean U1inf,
115 const Standard_Boolean U2inf,
116 const Standard_Boolean V1inf,
117 const Standard_Boolean V2inf,
118 Standard_Real& U1new,
119 Standard_Real& U2new,
120 Standard_Real& V1new,
121 Standard_Real& V2new,
122 Standard_Boolean& NoIntersection);
125 void EstLimForInfSurf(Standard_Real& U1new,
126 Standard_Real& U2new,
127 Standard_Real& V1new,
128 Standard_Real& V2new);
131 void SectionPointToParameters(const Intf_SectionPoint& Sp,
132 const IntCurveSurface_ThePolyhedron& Surf,
133 const IntCurveSurface_ThePolygon& Curv,
139 void IntCurveSurface_ComputeTransitions(const TheCurve& curve,
140 const Standard_Real w,
141 IntCurveSurface_TransitionOnCurve& TransOnCurve,
142 const TheSurface& surface,
143 const Standard_Real u,
144 const Standard_Real v);
147 void IntCurveSurface_ComputeParamsOnQuadric(const TheSurface& surface,
153 void ProjectIntersectAndEstLim(const gp_Lin& theLine,
154 const gp_Pln& thePln,
155 const ProjLib_Plane& theBasCurvProj,
156 Standard_Real& theVmin,
157 Standard_Real& theVmax,
158 Standard_Boolean& theNoIntersection);
160 //=======================================================================
161 //function : IntCurveSurface_Inter
163 //=======================================================================
164 IntCurveSurface_Inter::IntCurveSurface_Inter()
167 //=======================================================================
168 //function : DoSurface
170 //=======================================================================
171 void IntCurveSurface_Inter::DoSurface(const TheSurface& surface,
172 const Standard_Real u0,
173 const Standard_Real u1,
174 const Standard_Real v0,
175 const Standard_Real v1,
176 TColgp_Array2OfPnt& pntsOnSurface,
180 Standard_Integer iU = 0, iV = 0;
181 Standard_Real U = 0., V = 0;
182 // modified by NIZHNY-MKK Mon Oct 3 17:38:45 2005
183 // Standard_Real dU = fabs(u1-u0)/50., dV = fabs(v1-v0)/50.;
184 Standard_Real dU = (u1-u0)/50., dV = (v1-v0)/50.;
187 for(iU = 0; iU < 50; iU++) {
194 U = u0 + dU * ((Standard_Real)iU);
196 for(iV = 0; iV < 50; iV++) {
203 V = v0 + dV * ((Standard_Real)iV);
205 TheSurfaceTool::D0(surface,U,V,aPnt);
206 boxSurface.Add(aPnt);
207 pntsOnSurface.SetValue(iU+1,iV+1,aPnt);
210 Standard_Real Ures = TheSurfaceTool::UResolution(surface,dU);
211 Standard_Real Vres = TheSurfaceTool::VResolution(surface,dV);
212 gap = Max(Ures,Vres);
215 //=======================================================================
216 //function : DoNewBounds
218 //=======================================================================
219 void IntCurveSurface_Inter::DoNewBounds(
220 const TheSurface& surface,
221 const Standard_Real u0,
222 const Standard_Real u1,
223 const Standard_Real v0,
224 const Standard_Real v1,
225 const TColgp_Array2OfPnt& pntsOnSurface,
226 const TColStd_Array1OfReal& X,
227 const TColStd_Array1OfReal& Y,
228 const TColStd_Array1OfReal& Z,
229 TColStd_Array1OfReal& Bounds)
231 Bounds.SetValue(1,u0);
232 Bounds.SetValue(2,u1);
233 Bounds.SetValue(3,v0);
234 Bounds.SetValue(4,v1);
236 Standard_Boolean isUClosed = (TheSurfaceTool::IsUClosed(surface) || TheSurfaceTool::IsUPeriodic(surface));
237 Standard_Boolean isVClosed = (TheSurfaceTool::IsVClosed(surface) || TheSurfaceTool::IsVPeriodic(surface));
238 Standard_Boolean checkU = (isUClosed) ? Standard_False : Standard_True;
239 Standard_Boolean checkV = (isVClosed) ? Standard_False : Standard_True;
241 Standard_Integer i = 0, j = 0, k = 0, iU = 0, iV = 0;
242 Standard_Integer iUmin = 50, iVmin = 50, iUmax = 1, iVmax = 1;
244 for(i = 1; i <= 2; i++) {
245 for(j = 1; j <= 2; j++) {
246 for(k = 1; k <= 2; k++) {
247 gp_Pnt aPoint(X(i),Y(j),Z(k));
248 Standard_Real DistMin = 1.e+100;
249 Standard_Integer diU = 0, diV = 0;
250 for(iU = 1; iU <= 50; iU++) {
251 for(iV = 1; iV <= 50; iV++) {
252 const gp_Pnt aP = pntsOnSurface.Value(iU,iV);
253 Standard_Real dist = aP.SquareDistance(aPoint);
261 if(diU > 0 && diU < iUmin) iUmin = diU;
262 if(diU > 0 && diU > iUmax) iUmax = diU;
263 if(diV > 0 && diV < iVmin) iVmin = diV;
264 if(diV > 0 && diV > iVmax) iVmax = diV;
269 // modified by NIZHNY-MKK Mon Oct 3 17:38:43 2005
270 // Standard_Real dU = fabs(u1-u0)/50., dV = fabs(v1-v0)/50.;
271 Standard_Real dU = (u1-u0)/50., dV = (v1-v0)/50.;
273 Standard_Real USmin = u0 + dU * ((Standard_Real)(iUmin - 1));
274 Standard_Real USmax = u0 + dU * ((Standard_Real)(iUmax - 1));
275 Standard_Real VSmin = v0 + dV * ((Standard_Real)(iVmin - 1));
276 Standard_Real VSmax = v0 + dV * ((Standard_Real)(iVmax - 1));
279 Standard_Real tmp = USmax;
284 Standard_Real tmp = VSmax;
290 if(USmin < u0) USmin = u0;
292 if(USmax > u1) USmax = u1;
294 if(VSmin < v0) VSmin = v0;
296 if(VSmax > v1) VSmax = v1;
299 Bounds.SetValue(1,USmin);
300 Bounds.SetValue(2,USmax);
303 Bounds.SetValue(3,VSmin);
304 Bounds.SetValue(4,VSmax);
308 //=======================================================================
310 //purpose : Decompose la surface si besoin est
311 //=======================================================================
312 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
313 const TheSurface& surface) {
315 done = Standard_True;
316 Standard_Integer NbUOnS = TheSurfaceTool::NbUIntervals(surface,GeomAbs_C2);
317 Standard_Integer NbVOnS = TheSurfaceTool::NbVIntervals(surface,GeomAbs_C2);
318 Standard_Integer NbOnC = TheCurveTool::NbIntervals(curve,GeomAbs_C2);
319 Standard_Real U0,U1,V0,V1;
322 TColStd_Array1OfReal TabU(1,NbUOnS+1);
323 TheSurfaceTool::UIntervals(surface,TabU,GeomAbs_C2);
324 for(Standard_Integer iu = 1;iu <= NbUOnS; iu++) {
326 U1 = TabU.Value(iu+1);
328 TColStd_Array1OfReal TabV(1,NbVOnS+1);
329 TheSurfaceTool::VIntervals(surface,TabV,GeomAbs_C2);
330 for(Standard_Integer iv = 1;iv <= NbVOnS; iv++) {
332 V1 = TabV.Value(iv+1);
333 Perform(curve,surface,U0,V0,U1,V1);
336 else { //------ composite en U non composite en V
337 V0 = TheSurfaceTool::FirstVParameter(surface);
338 V1 = TheSurfaceTool::LastVParameter(surface);
339 Perform(curve,surface,U0,V0,U1,V1);
343 else if(NbVOnS > 1) { //---------- non composite en U composite en V
344 U0 = TheSurfaceTool::FirstUParameter(surface);
345 U1 = TheSurfaceTool::LastUParameter(surface);
346 TColStd_Array1OfReal TabV(1,NbVOnS+1);
347 TheSurfaceTool::VIntervals(surface,TabV,GeomAbs_C2);
348 for(Standard_Integer iv = 1;iv <= NbVOnS; iv++) {
350 V1 = TabV.Value(iv+1);
351 Perform(curve,surface,U0,V0,U1,V1);
355 V0 = TheSurfaceTool::FirstVParameter(surface);
356 V1 = TheSurfaceTool::LastVParameter(surface);
357 U0 = TheSurfaceTool::FirstUParameter(surface);
358 U1 = TheSurfaceTool::LastUParameter(surface);
362 //-- jgv patch (from)
363 //Computing of local bounds
364 Standard_Real LocalU0 = U0, LocalU1 = U1, LocalV0 = V0, LocalV1 = V1;
365 Standard_Real Umin = RealLast(), Vmin = RealLast(), Umax = RealFirst(), Vmax = RealFirst();
367 Standard_Integer i, j, k;
368 //Making GeomAdaptor_Curve
369 Standard_Real f = TheCurveTool::FirstParameter(curve);
370 Standard_Real l = TheCurveTool::LastParameter(curve);
371 GeomAbs_CurveType CurveType = TheCurveTool::GetType(curve);
372 Handle(Geom_Curve) theCurve;
376 theCurve = new Geom_Line( TheCurveTool::Line(curve) );
379 theCurve = new Geom_Circle( TheCurveTool::Circle(curve) );
381 case GeomAbs_Ellipse:
382 theCurve = new Geom_Ellipse( TheCurveTool::Ellipse(curve) );
384 case GeomAbs_Hyperbola:
385 theCurve = new Geom_Hyperbola( TheCurveTool::Hyperbola(curve) );
387 case GeomAbs_Parabola:
388 theCurve = new Geom_Parabola( TheCurveTool::Parabola(curve) );
390 case GeomAbs_BezierCurve:
391 theCurve = TheCurveTool::Bezier(curve);
393 case GeomAbs_BSplineCurve:
394 theCurve = TheCurveTool::BSpline(curve);
397 if (!theCurve.IsNull())
399 GeomAdaptor_Curve GACurve( theCurve, f, l );
400 BndLib_Add3dCurve::Add( GACurve, Precision::Confusion(), CurveBox );
404 Standard_Integer nbp = TheCurveTool::NbSamples(curve,f,l);
405 Standard_Real delta = (f-l)/nbp;
406 for (i = 0; i <= nbp; i++)
408 gp_Pnt aPnt = TheCurveTool::Value(curve, f + i*delta);
412 Standard_Real X[2], Y[2], Z[2];
413 CurveBox.Get( X[0], Y[0], Z[0], X[1], Y[1], Z[1] );
414 Standard_Real Ures = TheSurfaceTool::UResolution(surface, Precision::Confusion());
415 Standard_Real Vres = TheSurfaceTool::VResolution(surface, Precision::Confusion());
416 //Making GeomAdaptor_Surface
417 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
418 Handle(Geom_Surface) theSurface;
422 theSurface = new Geom_Plane( TheSurfaceTool::Plane(surface) );
424 case GeomAbs_Cylinder:
425 theSurface = new Geom_CylindricalSurface( TheSurfaceTool::Cylinder(surface) );
428 theSurface = new Geom_ConicalSurface( TheSurfaceTool::Cone(surface) );
431 theSurface = new Geom_ToroidalSurface( TheSurfaceTool::Torus(surface) );
434 theSurface = new Geom_SphericalSurface( TheSurfaceTool::Sphere(surface) );
436 case GeomAbs_BezierSurface:
437 theSurface = TheSurfaceTool::Bezier(surface);
439 case GeomAbs_BSplineSurface:
440 theSurface = TheSurfaceTool::BSpline(surface);
442 case GeomAbs_SurfaceOfRevolution:
444 gp_Ax1 Axis = TheSurfaceTool::AxeOfRevolution(surface);
445 Handle(Adaptor3d_HCurve) AdBC = TheSurfaceTool::BasisCurve(surface);
446 Handle(Geom_Curve) BC = GetCurve(AdBC);
448 theSurface = new Geom_SurfaceOfRevolution( BC, Axis );
451 case GeomAbs_SurfaceOfExtrusion:
453 gp_Dir Direction = TheSurfaceTool::Direction(surface);
454 Handle(Adaptor3d_HCurve) AdBC = TheSurfaceTool::BasisCurve(surface);
455 Handle(Geom_Curve) BC = GetCurve(AdBC);
457 theSurface = new Geom_SurfaceOfLinearExtrusion( BC, Direction );
460 case GeomAbs_OffsetSurface:
462 Standard_Real OffsetValue = TheSurfaceTool::OffsetValue(surface);
463 Handle(Adaptor3d_HSurface) AdBS = TheSurfaceTool::BasisSurface(surface);
464 Handle(Geom_Surface) BS = GetSurface(AdBS);
466 theSurface = new Geom_OffsetSurface( BS, OffsetValue );
470 if (!theSurface.IsNull())
472 GeomAdaptor_Surface GASurface( theSurface );
473 Extrema_ExtPS Projector;
474 Projector.Initialize( GASurface, U0, U1, V0, V1, Ures, Vres );
475 for (i = 0; i <= 1; i++)
476 for (j = 0; j <= 1; j++)
477 for (k = 0; k <= 1; k++)
479 gp_Pnt aPoint( X[i], Y[j], Z[k] );
480 Projector.Perform( aPoint );
481 if (Projector.IsDone() && Projector.NbExt() > 0)
483 Standard_Real mindist = RealLast();
484 Standard_Integer minind, ind;
485 for (ind = 1; ind <= Projector.NbExt(); ind++)
487 Standard_Real dist = Projector.Value(ind);
494 Extrema_POnSurf pons = Projector.Point(minind);
496 pons.Parameter( U, V );
497 if (U < Umin) Umin = U;
498 if (U > Umax) Umax = U;
499 if (V < Vmin) Vmin = V;
500 if (V > Vmax) Vmax = V;
503 Umin -= Ures; Umax += Ures; Vmin -= Vres; Vmax += Vres;
504 if (Umin > U0 && Umin <= U1) LocalU0 = Umin;
505 if (Umax < U1 && Umax >= U0) LocalU1 = Umax;
506 if (Vmin > V0 && Vmin <= V1) LocalV0 = Vmin;
507 if (Vmax < V1 && Vmax >= V0) LocalV1 = Vmax;
508 U0 = LocalU0; U1 = LocalU1; V0 = LocalV0; V1 = LocalV1;
512 Perform(curve,surface,U0,V0,U1,V1);
515 //=======================================================================
518 //=======================================================================
519 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
520 const TheSurface& surface,
521 const Standard_Real U1,const Standard_Real V1,
522 const Standard_Real U2,const Standard_Real V2) {
524 GeomAbs_CurveType CurveType = TheCurveTool::GetType(curve);
529 PerformConicSurf(TheCurveTool::Line(curve),curve,surface,U1,V1,U2,V2);
534 PerformConicSurf(TheCurveTool::Circle(curve),curve,surface,U1,V1,U2,V2);
537 case GeomAbs_Ellipse:
539 PerformConicSurf(TheCurveTool::Ellipse(curve),curve,surface,U1,V1,U2,V2);
542 case GeomAbs_Parabola:
544 PerformConicSurf(TheCurveTool::Parabola(curve),curve,surface,U1,V1,U2,V2);
547 case GeomAbs_Hyperbola:
549 PerformConicSurf(TheCurveTool::Hyperbola(curve),curve,surface,U1,V1,U2,V2);
554 Standard_Integer nbIntervalsOnCurve = TheCurveTool::NbIntervals(curve,GeomAbs_C2);
555 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
556 if( (SurfaceType != GeomAbs_Plane)
557 && (SurfaceType != GeomAbs_Cylinder)
558 && (SurfaceType != GeomAbs_Cone)
559 && (SurfaceType != GeomAbs_Sphere)) {
561 if(nbIntervalsOnCurve > 1) {
562 TColStd_Array1OfReal TabW(1,nbIntervalsOnCurve+1);
563 TheCurveTool::Intervals(curve,TabW,GeomAbs_C2);
564 for(Standard_Integer i = 1; i<=nbIntervalsOnCurve; i++) {
567 u2 = TabW.Value(i+1);
569 Handle(TColStd_HArray1OfReal) aPars;
570 Standard_Real defl = 0.1;
571 Standard_Integer NbMin = 10;
572 TheCurveTool::SamplePars(curve, u1, u2, defl, NbMin, aPars);
574 // IntCurveSurface_ThePolygon polygon(curve,u1,u2,TheCurveTool::NbSamples(curve,u1,u2));
575 IntCurveSurface_ThePolygon polygon(curve, aPars->Array1());
576 InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
581 u1 = TheCurveTool::FirstParameter(curve);
582 u2 = TheCurveTool::LastParameter(curve);
584 Handle(TColStd_HArray1OfReal) aPars;
585 Standard_Real defl = 0.1;
586 Standard_Integer NbMin = 10;
587 TheCurveTool::SamplePars(curve, u1, u2, defl, NbMin, aPars);
589 // IntCurveSurface_ThePolygon polygon(curve,TheCurveTool::NbSamples(curve,u1,u2));
590 IntCurveSurface_ThePolygon polygon(curve, aPars->Array1());
591 InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
594 else { //-- la surface est une quadrique
595 InternalPerformCurveQuadric(curve,surface);
600 //=======================================================================
603 //=======================================================================
604 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
605 const IntCurveSurface_ThePolygon& polygon,
606 const TheSurface& surface) {
608 done = Standard_True;
609 Standard_Real u1,v1,u2,v2;
610 u1 = TheSurfaceTool::FirstUParameter(surface);
611 v1 = TheSurfaceTool::FirstVParameter(surface);
612 u2 = TheSurfaceTool::LastUParameter(surface);
613 v2 = TheSurfaceTool::LastVParameter(surface);
614 Standard_Integer nbsu,nbsv;
615 nbsu = TheSurfaceTool::NbSamplesU(surface,u1,u2);
616 nbsv = TheSurfaceTool::NbSamplesV(surface,v1,v2);
619 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,u1,v1,u2,v2);
620 Perform(curve,polygon,surface,polyhedron);
622 //=======================================================================
625 //=======================================================================
626 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
627 const TheSurface& surface,
628 const IntCurveSurface_ThePolyhedron& polyhedron) {
630 done = Standard_True;
631 Standard_Real u1 = TheCurveTool::FirstParameter(curve);
632 Standard_Real u2 = TheCurveTool::LastParameter(curve);
633 IntCurveSurface_ThePolygon polygon(curve,TheCurveTool::NbSamples(curve,u1,u2));
634 Perform(curve,polygon,surface,polyhedron);
636 //=======================================================================
639 //=======================================================================
640 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
641 const IntCurveSurface_ThePolygon& polygon,
642 const TheSurface& surface,
643 const IntCurveSurface_ThePolyhedron& polyhedron) {
645 done = Standard_True;
646 Standard_Real u1,v1,u2,v2;
647 u1 = TheSurfaceTool::FirstUParameter(surface);
648 v1 = TheSurfaceTool::FirstVParameter(surface);
649 u2 = TheSurfaceTool::LastUParameter(surface);
650 v2 = TheSurfaceTool::LastVParameter(surface);
651 InternalPerform(curve,polygon,surface,polyhedron,u1,v1,u2,v2);
654 //=======================================================================
657 //=======================================================================
658 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
659 const IntCurveSurface_ThePolygon& polygon,
660 const TheSurface& surface,
661 const IntCurveSurface_ThePolyhedron& polyhedron,
662 Bnd_BoundSortBox& BndBSB) {
664 done = Standard_True;
665 Standard_Real u1,v1,u2,v2;
666 u1 = TheSurfaceTool::FirstUParameter(surface);
667 v1 = TheSurfaceTool::FirstVParameter(surface);
668 u2 = TheSurfaceTool::LastUParameter(surface);
669 v2 = TheSurfaceTool::LastVParameter(surface);
670 InternalPerform(curve,polygon,surface,polyhedron,u1,v1,u2,v2,BndBSB);
672 //=======================================================================
673 //function : InternalPerform
674 //purpose : C a l c u l d u p o i n t a p p r o c h e
675 //== p u i s d u p o i n t E x a c t
676 //=======================================================================
677 void IntCurveSurface_Inter::InternalPerform(const TheCurve& curve,
678 const IntCurveSurface_ThePolygon& polygon,
679 const TheSurface& surface,
680 const IntCurveSurface_ThePolyhedron& polyhedron,
681 const Standard_Real u0,
682 const Standard_Real v0,
683 const Standard_Real u1,
684 const Standard_Real v1,
685 Bnd_BoundSortBox& BSB) {
686 IntCurveSurface_TheInterference interference(polygon,polyhedron,BSB);
687 IntCurveSurface_TheCSFunction theicsfunction(surface,curve);
688 IntCurveSurface_TheExactInter intersectionExacte(theicsfunction,TOLTANGENCY);
689 math_FunctionSetRoot rsnld(intersectionExacte.Function());
691 // Standard_Real u,v,w,winit;
694 Standard_Real winf = polygon.InfParameter();
695 Standard_Real wsup = polygon.SupParameter();
696 Standard_Integer NbSectionPoints = interference.NbSectionPoints();
697 Standard_Integer NbTangentZones = interference.NbTangentZones();
700 //-- Les interferences renvoient parfois de nombreuses fois (>20) les memes points
702 Standard_Integer i,NbStartPoints=NbSectionPoints;
703 for(i=1; i<= NbTangentZones; i++) {
704 const Intf_TangentZone& TZ = interference.ZoneValue(i);
705 Standard_Integer nbpnts = TZ.NumberOfPoints();
706 NbStartPoints+=nbpnts;
710 Standard_Real *TabU = new Standard_Real [NbStartPoints+1];
711 Standard_Real *TabV = new Standard_Real [NbStartPoints+1];
712 Standard_Real *TabW = new Standard_Real [NbStartPoints+1];
713 Standard_Integer IndexPoint=0;
715 for(i=1; i<= NbSectionPoints; i++) {
716 const Intf_SectionPoint& SP = interference.PntValue(i);
717 SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
723 for(i=1; i<= NbTangentZones; i++) {
724 const Intf_TangentZone& TZ = interference.ZoneValue(i);
725 Standard_Integer nbpnts = TZ.NumberOfPoints();
726 for(Standard_Integer j=1; j<=nbpnts; j++) {
727 const Intf_SectionPoint& SP = TZ.GetPoint(j);
728 SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
737 Standard_Real su=0,sv=0,sw=0,ptol;
738 ptol = 10*Precision::PConfusion();
740 //-- Tri suivant la variable W
741 Standard_Boolean Triok;
744 Standard_Integer im1;
745 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
746 if(TabW[i] < TabW[im1]) {
747 Standard_Real t=TabW[i]; TabW[i]=TabW[im1]; TabW[im1]=t;
748 t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
749 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
750 Triok=Standard_False;
754 while(Triok==Standard_False);
756 //-- On trie pour des meme W suivant U
759 Standard_Integer im1;
760 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
761 // modified by NIZHNY-MKK Mon Oct 3 17:38:49 2005
762 // if(Abs(TabW[i]-TabW[im1])<ptol) {
763 if((TabW[i]-TabW[im1])<ptol) {
765 if(TabU[i] < TabU[im1]) {
766 Standard_Real t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
767 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
768 Triok=Standard_False;
773 while(Triok==Standard_False);
775 //-- On trie pour des meme U et W suivant V
778 Standard_Integer im1;
779 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
780 // modified by NIZHNY-MKK Mon Oct 3 17:38:52 2005
781 // if((Abs(TabW[i]-TabW[im1])<ptol) && (Abs(TabU[i]-TabU[im1])<ptol)) {
782 if(((TabW[i]-TabW[im1])<ptol) && ((TabU[i]-TabU[im1])<ptol)) {
784 if(TabV[i] < TabV[im1]) {
785 Standard_Real t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
786 Triok=Standard_False;
791 while(Triok==Standard_False);
794 for(i=0;i<NbStartPoints; i++) {
795 u=TabU[i]; v=TabV[i]; w=TabW[i];
799 if(Abs(u-su)>ptol || Abs(v-sv)>ptol || Abs(w-sw)>ptol) {
800 intersectionExacte.Perform(u,v,w,rsnld,u0,u1,v0,v1,winf,wsup);
801 if(intersectionExacte.IsDone()) {
802 if(!intersectionExacte.IsEmpty()) {
803 P=intersectionExacte.Point();
804 w=intersectionExacte.ParameterOnCurve();
805 intersectionExacte.ParameterOnSurface(u,v);
806 AppendPoint(curve,w,surface,u,v);
810 su=TabU[i]; sv=TabV[i]; sw=TabW[i];
818 //=======================================================================
819 //function : InternalPerform
821 //=======================================================================
822 void IntCurveSurface_Inter::InternalPerform(const TheCurve& curve,
823 const IntCurveSurface_ThePolygon& polygon,
824 const TheSurface& surface,
825 const IntCurveSurface_ThePolyhedron& polyhedron,
826 const Standard_Real u0,
827 const Standard_Real v0,
828 const Standard_Real u1,
829 const Standard_Real v1) {
830 IntCurveSurface_TheInterference interference(polygon,polyhedron);
831 IntCurveSurface_TheCSFunction theicsfunction(surface,curve);
832 IntCurveSurface_TheExactInter intersectionExacte(theicsfunction,TOLTANGENCY);
833 math_FunctionSetRoot rsnld(intersectionExacte.Function());
835 // Standard_Real u,v,w,winit;
838 Standard_Real winf = polygon.InfParameter();
839 Standard_Real wsup = polygon.SupParameter();
840 Standard_Integer NbSectionPoints = interference.NbSectionPoints();
841 Standard_Integer NbTangentZones = interference.NbTangentZones();
844 //-- Les interferences renvoient parfois de nombreuses fois (>20) les memes points
846 Standard_Integer i,NbStartPoints=NbSectionPoints;
847 for(i=1; i<= NbTangentZones; i++) {
848 const Intf_TangentZone& TZ = interference.ZoneValue(i);
849 Standard_Integer nbpnts = TZ.NumberOfPoints();
850 NbStartPoints+=nbpnts;
854 Standard_Real *TabU = new Standard_Real [NbStartPoints+1];
855 Standard_Real *TabV = new Standard_Real [NbStartPoints+1];
856 Standard_Real *TabW = new Standard_Real [NbStartPoints+1];
857 Standard_Integer IndexPoint=0;
859 for(i=1; i<= NbSectionPoints; i++) {
860 const Intf_SectionPoint& SP = interference.PntValue(i);
861 SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
867 for(i=1; i<= NbTangentZones; i++) {
868 const Intf_TangentZone& TZ = interference.ZoneValue(i);
869 Standard_Integer nbpnts = TZ.NumberOfPoints();
870 for(Standard_Integer j=1; j<=nbpnts; j++) {
871 const Intf_SectionPoint& SP = TZ.GetPoint(j);
872 SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
881 Standard_Real su=0,sv=0,sw=0,ptol;
882 ptol = 10*Precision::PConfusion();
884 //-- Tri suivant la variable W
885 Standard_Boolean Triok;
888 Standard_Integer im1;
889 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
890 if(TabW[i] < TabW[im1]) {
891 Standard_Real t=TabW[i]; TabW[i]=TabW[im1]; TabW[im1]=t;
892 t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
893 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
894 Triok=Standard_False;
898 while(Triok==Standard_False);
900 //-- On trie pour des meme W suivant U
903 Standard_Integer im1;
904 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
905 // modified by NIZHNY-MKK Mon Oct 3 17:38:56 2005
906 // if(Abs(TabW[i]-TabW[im1])<ptol) {
907 if((TabW[i]-TabW[im1])<ptol) {
909 if(TabU[i] < TabU[im1]) {
910 Standard_Real t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
911 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
912 Triok=Standard_False;
917 while(Triok==Standard_False);
919 //-- On trie pour des meme U et W suivant V
922 Standard_Integer im1;
923 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
924 // modified by NIZHNY-MKK Mon Oct 3 17:38:58 2005
925 // if((Abs(TabW[i]-TabW[im1])<ptol) && (Abs(TabU[i]-TabU[im1])<ptol)) {
926 if(((TabW[i]-TabW[im1])<ptol) && ((TabU[i]-TabU[im1])<ptol)) {
928 if(TabV[i] < TabV[im1]) {
929 Standard_Real t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
930 Triok=Standard_False;
935 while(Triok==Standard_False);
938 for(i=0;i<NbStartPoints; i++) {
939 u=TabU[i]; v=TabV[i]; w=TabW[i];
943 if(Abs(u-su)>ptol || Abs(v-sv)>ptol || Abs(w-sw)>ptol) {
944 intersectionExacte.Perform(u,v,w,rsnld,u0,u1,v0,v1,winf,wsup);
945 if(intersectionExacte.IsDone()) {
946 if(!intersectionExacte.IsEmpty()) {
947 P=intersectionExacte.Point();
948 w=intersectionExacte.ParameterOnCurve();
949 intersectionExacte.ParameterOnSurface(u,v);
950 AppendPoint(curve,w,surface,u,v);
954 su=TabU[i]; sv=TabV[i]; sw=TabW[i];
961 //=======================================================================
962 //function : InternalPerformCurveQuadric
964 //=======================================================================
965 void IntCurveSurface_Inter::InternalPerformCurveQuadric(const TheCurve& curve,
966 const TheSurface& surface) {
967 IntCurveSurface_TheQuadCurvExactInter QuadCurv(surface,curve);
968 if(QuadCurv.IsDone()) {
969 Standard_Integer NbRoots = QuadCurv.NbRoots();
971 for(Standard_Integer i = 1; i<= NbRoots; i++) {
972 w = QuadCurv.Root(i);
973 IntCurveSurface_ComputeParamsOnQuadric(surface,TheCurveTool::Value(curve,w),u,v);
974 AppendPoint(curve,w,surface,u,v);
976 //-- Intervals non traites .............................................
980 //=======================================================================
981 //function : InternalPerform
983 //=======================================================================
984 void IntCurveSurface_Inter::InternalPerform(const TheCurve& curve,
985 const IntCurveSurface_ThePolygon& polygon,
986 const TheSurface& surface,
987 const Standard_Real U1,
988 const Standard_Real V1,
989 const Standard_Real U2,
990 const Standard_Real V2) {
991 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
992 if( (SurfaceType != GeomAbs_Plane)
993 && (SurfaceType != GeomAbs_Cylinder)
994 && (SurfaceType != GeomAbs_Cone)
995 && (SurfaceType != GeomAbs_Sphere) ) {
996 if(SurfaceType != GeomAbs_BSplineSurface) {
997 Standard_Integer nbsu,nbsv;
998 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
999 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1000 if(nbsu>40) nbsu=40;
1001 if(nbsv>40) nbsv=40;
1002 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2);
1003 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1006 Handle(Adaptor3d_HSurface) aS = TheSurfaceTool::UTrim(surface, U1, U2, 1.e-9);
1007 aS = aS->VTrim(V1, V2, 1.e-9);
1008 Handle(Adaptor3d_TopolTool) aTopTool = new Adaptor3d_TopolTool(aS);
1009 Standard_Real defl = 0.1;
1010 aTopTool->SamplePnts(defl, 10, 10);
1012 Standard_Integer nbpu = aTopTool->NbSamplesU();
1013 Standard_Integer nbpv = aTopTool->NbSamplesV();
1014 TColStd_Array1OfReal Upars(1, nbpu), Vpars(1, nbpv);
1015 aTopTool->UParameters(Upars);
1016 aTopTool->VParameters(Vpars);
1018 IntCurveSurface_ThePolyhedron polyhedron(surface,Upars, Vpars);
1019 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1023 IntCurveSurface_TheQuadCurvExactInter QuadCurv(surface,curve);
1024 if(QuadCurv.IsDone()) {
1025 Standard_Integer NbRoots = QuadCurv.NbRoots();
1026 Standard_Real u,v,w;
1027 for(Standard_Integer i = 1; i<= NbRoots; i++) {
1028 w = QuadCurv.Root(i);
1029 IntCurveSurface_ComputeParamsOnQuadric(surface,TheCurveTool::Value(curve,w),u,v);
1030 AppendPoint(curve,w,surface,u,v);
1032 //-- Intervalles non traites .............................................
1034 } //-- Fin : la Surface est une quadrique
1036 //=======================================================================
1037 //function : PerformConicSurf
1039 //=======================================================================
1040 void IntCurveSurface_Inter::PerformConicSurf(const gp_Lin& Line,
1041 const TheCurve& curve,
1042 const TheSurface& surface,
1043 const Standard_Real U1,
1044 const Standard_Real V1,
1045 const Standard_Real U2,
1046 const Standard_Real V2) {
1049 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1050 switch(SurfaceType) {
1053 IntAna_IntConicQuad LinPlane(Line,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE);
1054 AppendIntAna(curve,surface,LinPlane);
1057 case GeomAbs_Cylinder:
1059 IntAna_IntConicQuad LinCylinder(Line,TheSurfaceTool::Cylinder(surface));
1060 AppendIntAna(curve,surface,LinCylinder);
1063 case GeomAbs_Sphere:
1065 IntAna_IntConicQuad LinSphere(Line,TheSurfaceTool::Sphere(surface));
1066 AppendIntAna(curve,surface,LinSphere);
1071 IntAna_IntLinTorus intlintorus(Line,TheSurfaceTool::Torus(surface));
1072 if(intlintorus.IsDone()) {
1073 Standard_Integer nbp = intlintorus.NbPoints();
1074 Standard_Real fi,theta,w;
1075 for(Standard_Integer i = 1; i<= nbp; i++) {
1078 P = intlintorus.Value(i);
1080 gp_Pnt P(intlintorus.Value(i));
1082 w = intlintorus.ParamOnLine(i);
1083 intlintorus.ParamOnTorus(i,fi,theta);
1084 AppendPoint(curve,w,surface,fi,theta);
1088 } //-- Si Done retourne False, On passe dans Default !!
1092 const Standard_Real correction = 1.E+5*Precision::Angular();
1093 gp_Cone cn = TheSurfaceTool::Cone(surface);
1094 if(Abs(cn.SemiAngle()) < M_PI/2.0 - correction){
1095 IntAna_IntConicQuad LinCone(Line,cn);
1096 AppendIntAna(curve,surface,LinCone);
1102 Standard_Integer nbsu,nbsv;
1103 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1104 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1106 Standard_Boolean U1inf = Precision::IsInfinite(U1);
1107 Standard_Boolean U2inf = Precision::IsInfinite(U2);
1108 Standard_Boolean V1inf = Precision::IsInfinite(V1);
1109 Standard_Boolean V2inf = Precision::IsInfinite(V2);
1111 Standard_Real U1new=U1, U2new=U2, V1new=V1, V2new=V2;
1113 Standard_Boolean NoIntersection = Standard_False;
1115 if(U1inf || U2inf || V1inf || V2inf ) {
1117 if(SurfaceType == GeomAbs_SurfaceOfExtrusion) {
1119 EstLimForInfExtr(Line, surface, Standard_False, nbsu,
1120 U1inf, U2inf, V1inf, V2inf,
1121 U1new, U2new, V1new, V2new, NoIntersection);
1124 else if(SurfaceType == GeomAbs_SurfaceOfRevolution) {
1126 EstLimForInfRevl(Line, surface,
1127 U1inf, U2inf, V1inf, V2inf,
1128 U1new, U2new, V1new, V2new, NoIntersection);
1131 else if(SurfaceType == GeomAbs_OffsetSurface) {
1133 EstLimForInfOffs(Line, surface, nbsu,
1134 U1inf, U2inf, V1inf, V2inf,
1135 U1new, U2new, V1new, V2new, NoIntersection);
1139 EstLimForInfSurf(U1new, U2new, V1new, V2new);
1145 if(NoIntersection) return;
1148 // modified by NIZHNY-OFV Mon Aug 20 14:56:47 2001 (60963 begin)
1149 if(nbsu<20) nbsu=20;
1150 if(nbsv<20) nbsv=20;
1151 // modified by NIZHNY-OFV Mon Aug 20 14:57:06 2001 (60963 end)
1152 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1new,V1new,U2new,V2new);
1155 bndTool.LinBox(Line,polyhedron.Bounding(),boxLine);
1156 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) {
1157 Standard_Real pinf = bndTool.BeginParam(nbseg);
1158 Standard_Real psup = bndTool.EndParam(nbseg);
1159 if((psup - pinf)<1e-10) { pinf-=1e-10; psup+=1e-10; }
1160 IntCurveSurface_ThePolygon polygon(curve, pinf,psup,2);
1161 InternalPerform(curve,polygon,surface,polyhedron,U1new,V1new,U2new,V2new);
1166 //=======================================================================
1167 //function : PerformConicSurf
1169 //=======================================================================
1170 void IntCurveSurface_Inter::PerformConicSurf(const gp_Circ& Circle,
1171 const TheCurve& curve,
1172 const TheSurface& surface,
1173 const Standard_Real U1,
1174 const Standard_Real V1,
1175 const Standard_Real U2,
1176 const Standard_Real V2) {
1178 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1179 switch(SurfaceType) {
1182 IntAna_IntConicQuad CircPlane(Circle,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE,TOLERANCE);
1183 AppendIntAna(curve,surface,CircPlane);
1186 case GeomAbs_Cylinder:
1188 IntAna_IntConicQuad CircCylinder(Circle,TheSurfaceTool::Cylinder(surface));
1189 AppendIntAna(curve,surface,CircCylinder);
1194 IntAna_IntConicQuad CircCone(Circle,TheSurfaceTool::Cone(surface));
1195 AppendIntAna(curve,surface,CircCone);
1198 case GeomAbs_Sphere:
1200 IntAna_IntConicQuad CircSphere(Circle,TheSurfaceTool::Sphere(surface));
1201 AppendIntAna(curve,surface,CircSphere);
1206 IntCurveSurface_ThePolygon polygon(curve,NBSAMPLESONCIRCLE);
1207 InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
1211 //=======================================================================
1212 //function : PerformConicSurf
1214 //=======================================================================
1215 void IntCurveSurface_Inter::PerformConicSurf(const gp_Elips& Ellipse,
1216 const TheCurve& curve,
1217 const TheSurface& surface,
1218 const Standard_Real U1,
1219 const Standard_Real V1,
1220 const Standard_Real U2,
1221 const Standard_Real V2) {
1223 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1224 switch(SurfaceType) {
1227 IntAna_IntConicQuad EllipsePlane(Ellipse,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE,TOLERANCE);
1228 AppendIntAna(curve,surface,EllipsePlane);
1231 case GeomAbs_Cylinder:
1233 IntAna_IntConicQuad EllipseCylinder(Ellipse,TheSurfaceTool::Cylinder(surface));
1234 AppendIntAna(curve,surface,EllipseCylinder);
1239 IntAna_IntConicQuad EllipseCone(Ellipse,TheSurfaceTool::Cone(surface));
1240 AppendIntAna(curve,surface,EllipseCone);
1243 case GeomAbs_Sphere:
1245 IntAna_IntConicQuad EllipseSphere(Ellipse,TheSurfaceTool::Sphere(surface));
1246 AppendIntAna(curve,surface,EllipseSphere);
1251 IntCurveSurface_ThePolygon polygon(curve,NBSAMPLESONELLIPSE);
1252 InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
1256 //=======================================================================
1257 //function : PerformConicSurf
1259 //=======================================================================
1260 void IntCurveSurface_Inter::PerformConicSurf(const gp_Parab& Parab,
1261 const TheCurve& curve,
1262 const TheSurface& surface,
1263 const Standard_Real U1,
1264 const Standard_Real V1,
1265 const Standard_Real U2,
1266 const Standard_Real V2) {
1268 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1269 switch(SurfaceType) {
1272 IntAna_IntConicQuad ParabPlane(Parab,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE);
1273 AppendIntAna(curve,surface,ParabPlane);
1276 case GeomAbs_Cylinder:
1278 IntAna_IntConicQuad ParabCylinder(Parab,TheSurfaceTool::Cylinder(surface));
1279 AppendIntAna(curve,surface,ParabCylinder);
1284 IntAna_IntConicQuad ParabCone(Parab,TheSurfaceTool::Cone(surface));
1285 AppendIntAna(curve,surface,ParabCone);
1288 case GeomAbs_Sphere:
1290 IntAna_IntConicQuad ParabSphere(Parab,TheSurfaceTool::Sphere(surface));
1291 AppendIntAna(curve,surface,ParabSphere);
1296 Standard_Integer nbsu,nbsv;
1297 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1298 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1299 if(nbsu>40) nbsu=40;
1300 if(nbsv>40) nbsv=40;
1301 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2);
1304 bndTool.ParabBox(Parab,polyhedron.Bounding(),boxParab);
1305 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) {
1306 IntCurveSurface_ThePolygon polygon(curve,
1307 bndTool.BeginParam(nbseg),
1308 bndTool.EndParam(nbseg),
1310 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1315 //=======================================================================
1316 //function : PerformConicSurf
1318 //=======================================================================
1319 void IntCurveSurface_Inter::PerformConicSurf(const gp_Hypr& Hypr,
1320 const TheCurve& curve,
1321 const TheSurface& surface,
1322 const Standard_Real U1,
1323 const Standard_Real V1,
1324 const Standard_Real U2,
1325 const Standard_Real V2) {
1327 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1328 switch(SurfaceType) {
1331 IntAna_IntConicQuad HyprPlane(Hypr,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE);
1332 AppendIntAna(curve,surface,HyprPlane);
1335 case GeomAbs_Cylinder:
1337 IntAna_IntConicQuad HyprCylinder(Hypr,TheSurfaceTool::Cylinder(surface));
1338 AppendIntAna(curve,surface,HyprCylinder);
1343 IntAna_IntConicQuad HyprCone(Hypr,TheSurfaceTool::Cone(surface));
1344 AppendIntAna(curve,surface,HyprCone);
1347 case GeomAbs_Sphere:
1349 IntAna_IntConicQuad HyprSphere(Hypr,TheSurfaceTool::Sphere(surface));
1350 AppendIntAna(curve,surface,HyprSphere);
1355 Standard_Integer nbsu,nbsv;
1356 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1357 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1358 if(nbsu>40) nbsu=40;
1359 if(nbsv>40) nbsv=40;
1360 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2);
1363 bndTool.HyprBox(Hypr,polyhedron.Bounding(),boxHypr);
1364 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) {
1365 IntCurveSurface_ThePolygon polygon(curve,
1366 bndTool.BeginParam(nbseg),
1367 bndTool.EndParam(nbseg),
1369 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1374 //=======================================================================
1375 //function : AppendIntAna
1377 //=======================================================================
1378 void IntCurveSurface_Inter::AppendIntAna(const TheCurve& curve,
1379 const TheSurface& surface,
1380 const IntAna_IntConicQuad& intana_ConicQuad) {
1381 if(intana_ConicQuad.IsDone()) {
1382 if(intana_ConicQuad.IsInQuadric()) {
1383 //-- cout<<" Courbe Dans la Quadrique !!! Non Traite !!!"<<endl;
1385 else if(intana_ConicQuad.IsParallel()) {
1386 //-- cout<<" Courbe // a la Quadrique !!! Non Traite !!!"<<endl;
1389 Standard_Integer nbp = intana_ConicQuad.NbPoints();
1390 Standard_Real u,v,w;
1391 for(Standard_Integer i = 1; i<= nbp; i++) {
1392 gp_Pnt P(intana_ConicQuad.Point(i));
1393 w = intana_ConicQuad.ParamOnConic(i);
1394 IntCurveSurface_ComputeParamsOnQuadric(surface,P,u,v);
1395 AppendPoint(curve,w,surface,u,v);
1400 //-- cout<<" IntAna Conic Quad Not Done "<<endl;
1403 //=======================================================================
1404 //function : AppendPoint
1406 //=======================================================================
1407 void IntCurveSurface_Inter::AppendPoint(const TheCurve& curve,
1408 const Standard_Real lw,
1409 const TheSurface& surface,
1410 const Standard_Real su,
1411 const Standard_Real sv) {
1413 Standard_Real W0 = TheCurveTool::FirstParameter(curve);
1414 Standard_Real W1 = TheCurveTool::LastParameter(curve);
1415 Standard_Real U0 = TheSurfaceTool::FirstUParameter(surface);
1416 Standard_Real U1 = TheSurfaceTool::LastUParameter(surface);
1417 Standard_Real V0 = TheSurfaceTool::FirstVParameter(surface);
1418 Standard_Real V1 = TheSurfaceTool::LastVParameter(surface);
1419 //-- Test si la courbe est periodique
1420 Standard_Real w = lw, u = su, v = sv;
1422 GeomAbs_CurveType aCType = TheCurveTool::GetType(curve);
1424 if(TheCurveTool::IsPeriodic(curve)
1425 || aCType == GeomAbs_Circle
1426 || aCType == GeomAbs_Ellipse) {
1427 w = ElCLib::InPeriod(w, W0, W0 + TheCurveTool::Period(curve));
1430 if((W0 - w) >= TOLTANGENCY || (w - W1) >= TOLTANGENCY) return;
1432 GeomAbs_SurfaceType aSType = TheSurfaceTool::GetType(surface);
1433 if (TheSurfaceTool::IsUPeriodic(surface)
1434 || aSType == GeomAbs_Cylinder
1435 || aSType == GeomAbs_Cone
1436 || aSType == GeomAbs_Sphere) {
1437 u = ElCLib::InPeriod(u, U0, U0 + TheSurfaceTool::UPeriod(surface));
1440 if (TheSurfaceTool::IsVPeriodic(surface)) {
1441 v = ElCLib::InPeriod(v, V0, V0 + TheSurfaceTool::VPeriod(surface));
1444 if((U0 - u) >= TOLTANGENCY || (u - U1) >= TOLTANGENCY) return;
1445 if((V0 - v) >= TOLTANGENCY || (v - V1) >= TOLTANGENCY) return;
1447 IntCurveSurface_TransitionOnCurve TransOnCurve;
1448 IntCurveSurface_ComputeTransitions(curve,w,TransOnCurve,
1450 gp_Pnt P(TheCurveTool::Value(curve,w));
1451 IntCurveSurface_IntersectionPoint IP(P,u,v,w,TransOnCurve);
1452 Append(IP); //-- invoque la methode de IntCurveSurface_Intersection.
1456 //=======================================================================
1457 //function : AppendSegment
1459 //=======================================================================
1460 void IntCurveSurface_Inter::AppendSegment(const TheCurve& ,
1461 const Standard_Real ,
1462 const Standard_Real ,
1463 const TheSurface& ) {
1464 //cout<<" !!! Not Yet Implemented
1465 //IntCurveSurface_Inter::Append(const IntCurveSurf ...)"<<endl;
1468 //=======================================================================
1469 //function : SectionPointToParameters
1470 //purpose : P o i n t d i n t e r f e r e n c e - - >
1472 //=======================================================================
1473 void SectionPointToParameters(const Intf_SectionPoint& Sp,
1474 const IntCurveSurface_ThePolyhedron& Polyhedron,
1475 const IntCurveSurface_ThePolygon& Polygon,
1481 Standard_Integer Adr1,Adr2;
1482 Standard_Real Param,u,v;
1485 Standard_Integer Pt1,Pt2,Pt3;
1486 Standard_Real u1,v1,param;
1487 //----------------------------------------------------------------------
1488 //-- Calcul des parametres approches sur la surface --
1489 //----------------------------------------------------------------------
1491 Sp.InfoSecond(typ,Adr1,Adr2,Param);
1493 case Intf_VERTEX: //-- Adr1 est le numero du vertex
1495 Polyhedron.Parameters(Adr1,u1,v1);
1500 Polyhedron.Parameters(Adr1,u1,v1);
1501 Polyhedron.Parameters(Adr2,u,v);
1502 u1+= Param * (u-u1);
1503 v1+= Param * (v-v1);
1508 Standard_Real ua,va,ub,vb,uc,vc,ca,cb,cc,cabc;
1509 Polyhedron.Triangle(Adr1,Pt1,Pt2,Pt3);
1510 gp_Pnt PA(Polyhedron.Point(Pt1));
1511 gp_Pnt PB(Polyhedron.Point(Pt2));
1512 gp_Pnt PC(Polyhedron.Point(Pt3));
1513 Polyhedron.Parameters(Pt1,ua,va);
1514 Polyhedron.Parameters(Pt2,ub,vb);
1515 Polyhedron.Parameters(Pt3,uc,vc);
1516 gp_Vec Normale(gp_Vec(PA,PB).Crossed(gp_Vec(PA,PC)));
1517 cc = (gp_Vec(PA,PB).Crossed(gp_Vec(PA,P))).Dot(Normale);
1518 ca = (gp_Vec(PB,PC).Crossed(gp_Vec(PB,P))).Dot(Normale);
1519 cb = (gp_Vec(PC,PA).Crossed(gp_Vec(PC,P))).Dot(Normale);
1520 cabc = ca + cb + cc;
1522 ca/=cabc; cb/=cabc; cc/=cabc;
1524 u1 = ca * ua + cb * ub + cc * uc;
1525 v1 = ca * va + cb * vb + cc * vc;
1530 cout<<" Default dans SectionPointToParameters "<<endl;
1534 //----------------------------------------------------------------------
1535 //-- Calcul du point approche sur la Curve --
1536 //----------------------------------------------------------------------
1537 Standard_Integer SegIndex;
1539 Sp.InfoFirst(typ,SegIndex,param);
1540 W = Polygon.ApproxParamOnCurve(SegIndex,param);
1541 if(param>1.0 || param<0.0) {
1542 //-- IntCurveSurface_ThePolyhedronTool::Dump(Polyhedron);
1543 //-- IntCurveSurface_ThePolygonTool::Dump(Polygon);
1548 //=======================================================================
1549 //function : IntCurveSurface_ComputeTransitions
1551 //=======================================================================
1552 void IntCurveSurface_ComputeTransitions(const TheCurve& curve,
1553 const Standard_Real w,
1554 IntCurveSurface_TransitionOnCurve& TransOnCurve,
1555 const TheSurface& surface,
1556 const Standard_Real u,
1557 const Standard_Real v) {
1559 gp_Vec NSurf,D1U,D1V;//TgCurv;
1561 Standard_Real CosDir;
1564 TheSurfaceTool::D1(surface,u,v,Psurf,D1U,D1V);
1565 NSurf = D1U.Crossed(D1V);
1566 TheCurveTool::D1(curve,w,Psurf,D1U);
1567 Standard_Real Norm = NSurf.Magnitude();
1568 if(Norm>TOLERANCE_ANGULAIRE) {
1570 CosDir = NSurf.Dot(D1U);
1572 if( -CosDir > TOLERANCE_ANGULAIRE) {
1573 //-- --Curve---> <----Surface----
1574 TransOnCurve = IntCurveSurface_In;
1576 else if(CosDir > TOLERANCE_ANGULAIRE) {
1577 //-- --Curve---> ----Surface-->
1578 TransOnCurve = IntCurveSurface_Out;
1581 TransOnCurve = IntCurveSurface_Tangent;
1585 TransOnCurve = IntCurveSurface_Tangent;
1588 //=======================================================================
1589 //function : IntCurveSurface_ComputeParamsOnQuadric
1591 //=======================================================================
1592 void IntCurveSurface_ComputeParamsOnQuadric(const TheSurface& surface,
1596 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1597 switch(SurfaceType) {
1600 ElSLib::Parameters(TheSurfaceTool::Plane(surface),P,u,v);
1603 case GeomAbs_Cylinder:
1605 ElSLib::Parameters(TheSurfaceTool::Cylinder(surface),P,u,v);
1610 ElSLib::Parameters(TheSurfaceTool::Cone(surface),P,u,v);
1613 case GeomAbs_Sphere:
1615 ElSLib::Parameters(TheSurfaceTool::Sphere(surface),P,u,v);
1623 //=======================================================================
1624 //function : EstLimForInfExtr
1625 //purpose : Estimation of limits for infinite surfaces
1626 //=======================================================================
1627 void EstLimForInfExtr(const gp_Lin& Line,
1628 const TheSurface& surface,
1629 const Standard_Boolean IsOffSurf,
1630 const Standard_Integer nbsu,
1631 const Standard_Boolean U1inf,
1632 const Standard_Boolean U2inf,
1633 const Standard_Boolean V1inf,
1634 const Standard_Boolean V2inf,
1635 Standard_Real& U1new,
1636 Standard_Real& U2new,
1637 Standard_Real& V1new,
1638 Standard_Real& V2new,
1639 Standard_Boolean& NoIntersection)
1643 NoIntersection = Standard_False;
1645 Handle(Adaptor3d_HSurface) aBasSurf;
1647 if(IsOffSurf) aBasSurf = TheSurfaceTool::BasisSurface(surface);
1651 if(IsOffSurf) aDirOfExt = aBasSurf->Direction();
1652 else aDirOfExt = TheSurfaceTool::Direction(surface);
1654 Standard_Real tolang = TOLERANCE_ANGULAIRE;
1656 if(aDirOfExt.IsParallel(Line.Direction(), tolang)) {
1657 NoIntersection = Standard_True;
1661 if((V1inf || V2inf) && !(U1inf || U2inf)) {
1663 Standard_Real vmin = RealLast(), vmax = -vmin;
1665 Standard_Real step = (U2new - U1new) / nbsu;
1666 Standard_Real u = U1new, v;
1668 Extrema_POnCurv aP1, aP2;
1671 for(i = 0; i <= nbsu; i++) {
1673 TheSurfaceTool::D0(surface, u, 0., aP);
1675 aL.SetDirection(aDirOfExt);
1677 Extrema_ExtElC aExtr(aL, Line, tolang);
1679 if(!aExtr.IsDone()) return;
1681 if(aExtr.IsParallel()) {
1682 NoIntersection = Standard_True;
1686 aExtr.Points(1, aP1, aP2);
1687 v = aP1.Parameter();
1688 vmin = Min(vmin, v);
1689 vmax = Max(vmax, v);
1695 vmin = vmin - Abs(vmin) - 10.;
1696 vmax = vmax + Abs(vmax) + 10.;
1698 V1new = Max(V1new, vmin);
1699 V2new = Min(V2new, vmax);
1702 else if(U1inf || U2inf) {
1704 Standard_Real umin = RealLast(), umax = -umin;
1705 Standard_Real u0 = Min(Max(0., U1new), U2new);
1706 Standard_Real v0 = Min(Max(0., V1new), V2new);
1708 TheSurfaceTool::D0(surface, u0, v0, aP);
1709 gp_Pln aRefPln(aP, aDirOfExt);
1711 Handle(Adaptor3d_HCurve) aBasCurv;
1713 if(IsOffSurf) aBasCurv = aBasSurf->BasisCurve();
1714 else aBasCurv = TheSurfaceTool::BasisCurve(surface);
1716 ProjLib_Plane Projector(aRefPln);
1718 Projector.Project(Line);
1720 if(!Projector.IsDone()) return;
1722 gp_Lin2d Line2d = Projector.Line();
1724 GeomAbs_CurveType aCurvTyp = aBasCurv->GetType();
1726 if(aCurvTyp == GeomAbs_Line) {
1728 Projector.Project(aBasCurv->Line());
1730 if(!Projector.IsDone()) return;
1732 gp_Lin2d aL2d = Projector.Line();
1734 IntAna2d_AnaIntersection anInter(Line2d, aL2d);
1736 if(!anInter.IsDone()) return;
1738 if(anInter.IsEmpty() || anInter.IdenticalElements() ||
1739 anInter.ParallelElements() ) {
1740 NoIntersection = Standard_True;
1744 const IntAna2d_IntPoint& anIntPnt = anInter.Point(1);
1745 umin = umax = anIntPnt.ParamOnSecond();
1747 else if(aCurvTyp == GeomAbs_Parabola || aCurvTyp == GeomAbs_Hyperbola) {
1749 IntAna2d_Conic aCon(Line2d);
1750 IntAna2d_AnaIntersection anInter;
1752 if(aCurvTyp == GeomAbs_Parabola) {
1753 Projector.Project(aBasCurv->Parabola());
1754 if(!Projector.IsDone()) return;
1756 const gp_Parab2d& aP2d = Projector.Parabola();
1758 anInter.Perform(aP2d, aCon);
1761 Projector.Project(aBasCurv->Hyperbola());
1762 if(!Projector.IsDone()) return;
1764 const gp_Hypr2d& aH2d = Projector.Hyperbola();
1765 anInter.Perform(aH2d, aCon);
1768 if(!anInter.IsDone()) return;
1770 if(anInter.IsEmpty()) {
1771 NoIntersection = Standard_True;
1775 Standard_Integer i, nbint = anInter.NbPoints();
1776 for(i = 1; i <= nbint; i++) {
1778 const IntAna2d_IntPoint& anIntPnt = anInter.Point(i);
1780 umin = Min(anIntPnt.ParamOnFirst(), umin);
1781 umax = Max(anIntPnt.ParamOnFirst(), umax);
1790 umin = umin - Abs(umin) - 10;
1791 umax = umax + Abs(umax) + 10;
1793 U1new = Max(U1new, umin);
1794 U2new = Min(U2new, umax);
1796 if(V1inf || V2inf) {
1797 EstLimForInfExtr(Line, surface, IsOffSurf, nbsu,
1798 Standard_False, Standard_False, V1inf, V2inf,
1799 U1new, U2new, V1new, V2new, NoIntersection);
1806 //=======================================================================
1807 //function : ProjectIntersectAndEstLim
1808 //purpose : project <theLine> and it's X-axe symmetric line to <thePln> and
1809 // intersect resulting curve with <theBasCurvProj>.
1810 // Then estimate max and min parameters of intersection on
1811 // <theBasCurvProj>.
1812 // Is called from EstLimForInfRevl()
1813 //=======================================================================
1814 void ProjectIntersectAndEstLim(const gp_Lin& theLine,
1815 const gp_Pln& thePln,
1816 const ProjLib_Plane& theBasCurvProj,
1817 Standard_Real& theVmin,
1818 Standard_Real& theVmax,
1819 Standard_Boolean& theNoIntersection)
1821 ProjLib_Plane aLineProj( thePln, theLine );
1822 if (!aLineProj.IsDone()) {
1825 << "Info: IntCurveSurface_Inter::ProjectIntersectAndEstLim(), !aLineProj.IsDone()"
1830 gp_Lin2d aLin2d = aLineProj.Line();
1832 // make a second line X-axe symmetric to the first one
1833 gp_Pnt2d aP1 = aLin2d.Location();
1834 gp_Pnt2d aP2 (aP1.XY() + aLin2d.Direction().XY());
1835 gp_Pnt2d aP1sym (aP1.X(), -aP1.Y());
1836 gp_Pnt2d aP2sym (aP2.X(), -aP2.Y());
1837 gp_Lin2d aLin2dsym (aP1sym, gp_Vec2d(aP1sym,aP2sym));
1839 // intersect projections
1840 IntAna2d_Conic aCon (aLin2d);
1841 IntAna2d_Conic aConSym (aLin2dsym);
1842 IntAna2d_AnaIntersection anIntersect;
1843 IntAna2d_AnaIntersection anIntersectSym;
1845 switch (theBasCurvProj.GetType()) {
1847 anIntersectSym.Perform(theBasCurvProj.Line(), aConSym);
1848 anIntersect.Perform(theBasCurvProj.Line(), aCon); break;
1849 case GeomAbs_Hyperbola:
1850 anIntersectSym.Perform(theBasCurvProj.Hyperbola(), aConSym);
1851 anIntersect.Perform(theBasCurvProj.Hyperbola(), aCon); break;
1852 case GeomAbs_Parabola:
1853 anIntersectSym.Perform(theBasCurvProj.Parabola(), aConSym);
1854 anIntersect.Perform(theBasCurvProj.Parabola(), aCon); break;
1856 return; // not infinite curve
1859 // retrieve params of intersections
1860 Standard_Integer aNbIntPnt = anIntersect.IsDone() ? anIntersect.NbPoints() : 0;
1861 Standard_Integer aNbIntPntSym = anIntersectSym.IsDone() ? anIntersectSym.NbPoints() : 0;
1862 Standard_Integer iPnt, aNbPnt = Max (aNbIntPnt, aNbIntPntSym);
1865 theNoIntersection = Standard_True;
1868 Standard_Real aParam;
1869 for (iPnt = 1; iPnt <= aNbPnt; iPnt++)
1871 if (iPnt <= aNbIntPnt) {
1872 const IntAna2d_IntPoint& aIntPnt = anIntersect.Point(iPnt);
1873 aParam = aIntPnt.ParamOnFirst();
1874 theVmin = Min (theVmin, aParam );
1875 theVmax = Max (theVmax, aParam );
1877 if (iPnt <= aNbIntPntSym) {
1878 const IntAna2d_IntPoint& aIntPnt = anIntersectSym.Point(iPnt);
1879 aParam = aIntPnt.ParamOnFirst();
1880 theVmin = Min (theVmin, aParam );
1881 theVmax = Max (theVmax, aParam );
1887 //=======================================================================
1888 //function : EstLimForInfRevl
1889 //purpose : Estimate V1 and V2 to pass to InternalPerform() if they are
1890 // infinite for Surface of Revolution
1891 // Algo: intersect projections of Line and basis curve on the
1892 // plane passing through revolution axe
1893 //=======================================================================
1894 void EstLimForInfRevl(const gp_Lin& Line,
1895 const TheSurface& surface,
1896 const Standard_Boolean U1inf,
1897 const Standard_Boolean U2inf,
1898 const Standard_Boolean V1inf,
1899 const Standard_Boolean V2inf,
1900 Standard_Real& U1new,
1901 Standard_Real& U2new,
1902 Standard_Real& V1new,
1903 Standard_Real& V2new,
1904 Standard_Boolean& NoIntersection)
1907 NoIntersection = Standard_False;
1909 if (U1inf || U2inf) {
1911 U1new = Max (0., U1new);
1913 U2new = Min (2 * M_PI, U2new);
1914 if (! V1inf && !V2inf) return;
1917 Handle(Adaptor3d_HCurve) aBasisCurve = TheSurfaceTool::BasisCurve(surface);
1918 gp_Ax1 aRevAx = TheSurfaceTool::AxeOfRevolution(surface);
1919 gp_Vec aXVec = aRevAx.Direction();
1920 Standard_Real aTolAng = Precision::Angular();
1922 // make plane to project a basis curve
1923 gp_Pnt O = aRevAx.Location();
1924 Standard_Real aU = 0.;
1925 gp_Pnt P = aBasisCurve->Value(aU);
1926 while (O.SquareDistance(P) <= Precision::PConfusion() ||
1927 aXVec.IsParallel( gp_Vec(O,P), aTolAng)) {
1929 P = aBasisCurve->Value(aU);
1931 // basis curve is a line coinciding with aXVec, P is any not on aXVec
1932 P = gp_Pnt(aU, aU+1, aU+2);
1934 gp_Vec aNVec = aXVec ^ gp_Vec(O,P);
1935 gp_Pln aPln (gp_Ax3 (O, aNVec ,aXVec));
1937 // project basic curve
1938 ProjLib_Plane aBasCurvProj(aPln);
1939 switch (aBasisCurve->GetType()) {
1941 aBasCurvProj.Project(aBasisCurve->Line ()); break;
1942 case GeomAbs_Hyperbola:
1943 aBasCurvProj.Project(aBasisCurve->Hyperbola()); break;
1944 case GeomAbs_Parabola:
1945 aBasCurvProj.Project(aBasisCurve->Parabola ()); break;
1947 return; // not infinite curve
1949 if (!aBasCurvProj.IsDone()) {
1951 cout << "Info: IntCurveSurface_Inter::EstLimForInfRevl(), !aBasCurvProj.IsDone()" << endl;
1955 // make plane to project Line
1956 if (aXVec.IsParallel( Line.Direction(), aTolAng)) {
1957 P = Line.Location();
1958 while (O.SquareDistance(P) <= Precision::PConfusion()) {
1960 P = gp_Pnt(aU, aU+1, aU+2); // any not on aXVec
1962 aNVec = aXVec ^ gp_Vec(O,P);
1964 aNVec = aXVec.Crossed( Line.Direction() );
1966 aPln = gp_Pln (gp_Ax3 (O, aNVec ,aXVec));
1968 // make a second plane perpendicular to the first one, rotated around aXVec
1969 gp_Pln aPlnPrp = aPln.Rotated (gp_Ax1 (O,aXVec), M_PI/2.);
1971 // project Line and it's X-axe symmetric one to plane and intersect
1972 // resulting curve with projection of Basic Curev
1973 Standard_Real aVmin = RealLast(), aVmax = -aVmin;
1974 Standard_Boolean aNoInt1 = Standard_False, aNoInt2 = Standard_False;
1975 ProjectIntersectAndEstLim (Line, aPln, aBasCurvProj, aVmin, aVmax, aNoInt1);
1976 ProjectIntersectAndEstLim (Line, aPlnPrp, aBasCurvProj, aVmin, aVmax, aNoInt2);
1978 if (aNoInt1 && aNoInt2) {
1979 NoIntersection = Standard_True;
1983 aVmin = aVmin - Abs(aVmin) - 10;
1984 aVmax = aVmax + Abs(aVmax) + 10;
1986 if (V1inf) V1new = aVmin;
1987 if (V2inf) V2new = aVmax;
1989 //cout << "EstLimForInfRevl: Vmin " << V1new << " Vmax " << V2new << endl;
1994 //=======================================================================
1995 //function : EstLimForInfOffs
1997 //=======================================================================
1998 void EstLimForInfOffs(const gp_Lin& Line,
1999 const TheSurface& surface,
2000 const Standard_Integer nbsu,
2001 const Standard_Boolean U1inf,
2002 const Standard_Boolean U2inf,
2003 const Standard_Boolean V1inf,
2004 const Standard_Boolean V2inf,
2005 Standard_Real& U1new,
2006 Standard_Real& U2new,
2007 Standard_Real& V1new,
2008 Standard_Real& V2new,
2009 Standard_Boolean& NoIntersection)
2012 NoIntersection = Standard_False;
2014 const Handle(Adaptor3d_HSurface)& aBasSurf = TheSurfaceTool::BasisSurface(surface);
2015 Standard_Real anOffVal = TheSurfaceTool::OffsetValue(surface);
2017 GeomAbs_SurfaceType aTypeOfBasSurf = aBasSurf->GetType();
2019 // case for plane, cylinder and cone - make equivalent surface;
2020 if(aTypeOfBasSurf == GeomAbs_Plane) {
2022 gp_Pln aPln = aBasSurf->Plane();
2023 gp_Vec aT = aPln.Position().XDirection()^aPln.Position().YDirection();
2026 IntAna_IntConicQuad LinPlane(Line,aPln,TOLERANCE_ANGULAIRE);
2028 if(!LinPlane.IsDone()) return;
2030 if(LinPlane.IsParallel() || LinPlane.IsInQuadric()) {
2032 NoIntersection = Standard_True;
2038 ElSLib::Parameters(aPln, LinPlane.Point(1), u, v);
2039 U1new = Max(U1new, u - 10.);
2040 U2new = Min(U2new, u + 10.);
2041 V1new = Max(V1new, v - 10.);
2042 V2new = Min(V2new, v + 10.);
2045 else if(aTypeOfBasSurf == GeomAbs_Cylinder) {
2047 gp_Cylinder aCyl = aBasSurf->Cylinder();
2049 Standard_Real aR = aCyl.Radius();
2050 gp_Ax3 anA = aCyl.Position();
2057 if ( aR >= TOLTANGENCY ) {
2060 else if ( aR <= -TOLTANGENCY ){
2061 anA.Rotate(gp_Ax1(anA.Location(), anA.Direction()), M_PI);
2062 aCyl.SetPosition(anA);
2063 // modified by NIZHNY-MKK Mon Oct 3 17:37:54 2005
2064 // aCyl.SetRadius(Abs(aR));
2065 aCyl.SetRadius(-aR);
2069 NoIntersection = Standard_True;
2074 IntAna_IntConicQuad LinCylinder(Line, aCyl);
2076 if(!LinCylinder.IsDone()) return;
2078 if(LinCylinder.IsParallel() || LinCylinder.IsInQuadric()) {
2080 NoIntersection = Standard_True;
2085 Standard_Integer i, nbp = LinCylinder.NbPoints();
2086 Standard_Real vmin = RealLast(), vmax = -vmin, u, v;
2088 for(i = 1; i <= nbp; i++) {
2090 ElSLib::Parameters(aCyl, LinCylinder.Point(i), u, v);
2091 vmin = Min(vmin, v);
2092 vmax = Max(vmax, v);
2096 V1new = Max(V1new, vmin - Abs(vmin) - 10.);
2097 V2new = Min(V2new, vmax + Abs(vmax) + 10.);
2100 else if(aTypeOfBasSurf == GeomAbs_Cone) {
2102 gp_Cone aCon = aBasSurf->Cone();
2103 Standard_Real anAng = aCon.SemiAngle();
2104 Standard_Real aR = aCon.RefRadius() + anOffVal * Cos(anAng);
2105 gp_Ax3 anA = aCon.Position();
2108 gp_Vec aZ( anA.Direction());
2109 aZ *= - anOffVal * Sin(anAng);
2111 aCon.SetPosition(anA);
2113 aCon.SetSemiAngle(anAng);
2122 IntAna_IntConicQuad LinCone(Line, aCon);
2124 if(!LinCone.IsDone()) return;
2126 if(LinCone.IsParallel() || LinCone.IsInQuadric()) {
2128 NoIntersection = Standard_True;
2133 Standard_Integer i, nbp = LinCone.NbPoints();
2134 Standard_Real vmin = RealLast(), vmax = -vmin, u, v;
2136 for(i = 1; i <= nbp; i++) {
2138 ElSLib::Parameters(aCon, LinCone.Point(i), u, v);
2139 vmin = Min(vmin, v);
2140 vmax = Max(vmax, v);
2144 V1new = Max(V1new, vmin - Abs(vmin) - 10.);
2145 V2new = Min(V2new, vmax + Abs(vmax) + 10.);
2148 else if(aTypeOfBasSurf == GeomAbs_SurfaceOfExtrusion) {
2150 Standard_Real anU1 = U1new, anU2 = U2new;
2152 EstLimForInfExtr(Line, surface, Standard_True, nbsu,
2153 U1inf, U2inf, V1inf, V2inf,
2154 U1new, U2new, V1new, V2new, NoIntersection);
2156 if(NoIntersection) return;
2158 if(U1inf || U2inf) {
2160 GeomAbs_CurveType aBasCurvType = aBasSurf->BasisCurve()->GetType();
2161 if(aBasCurvType == GeomAbs_Line) {
2162 U1new = Max(anU1, -1.e10);
2163 U2new = Min(anU2, 1.e10);
2165 else if(aBasCurvType == GeomAbs_Parabola) {
2166 gp_Parab aPrb = aBasSurf->BasisCurve()->Parabola();
2167 Standard_Real aF = aPrb.Focal();
2168 Standard_Real dU = 2.e5 * Sqrt(aF);
2169 U1new = Max(anU1, -dU);
2170 U2new = Min(anU2, dU);
2172 else if(aBasCurvType == GeomAbs_Hyperbola) {
2173 U1new = Max(anU1, -30.);
2174 U2new = Min(anU2, 30.);
2177 U1new = Max(anU1, -1.e10);
2178 U2new = Min(anU2, 1.e10);
2184 else if(aTypeOfBasSurf == GeomAbs_SurfaceOfRevolution) {
2186 GeomAbs_CurveType aBasCurvType = aBasSurf->BasisCurve()->GetType();
2187 if(aBasCurvType == GeomAbs_Line) {
2188 V1new = Max(V1new, -1.e10);
2189 V2new = Min(V2new, 1.e10);
2191 else if(aBasCurvType == GeomAbs_Parabola) {
2192 gp_Parab aPrb = aBasSurf->BasisCurve()->Parabola();
2193 Standard_Real aF = aPrb.Focal();
2194 Standard_Real dV = 2.e5 * Sqrt(aF);
2195 V1new = Max(V1new, -dV);
2196 V2new = Min(V2new, dV);
2198 else if(aBasCurvType == GeomAbs_Hyperbola) {
2199 V1new = Max(V1new, -30.);
2200 V2new = Min(V2new, 30.);
2203 V1new = Max(V1new, -1.e10);
2204 V2new = Min(V2new, 1.e10);
2210 V1new = Max(V1new, -1.e10);
2211 V2new = Min(V2new, 1.e10);
2214 //=======================================================================
2215 //function : EstLimForInfSurf
2217 //=======================================================================
2218 void EstLimForInfSurf(Standard_Real& U1new,
2219 Standard_Real& U2new,
2220 Standard_Real& V1new,
2221 Standard_Real& V2new)
2223 U1new = Max(U1new, -1.e10);
2224 U2new = Min(U2new, 1.e10);
2225 V1new = Max(V1new, -1.e10);
2226 V2new = Min(V2new, 1.e10);