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);
319 Standard_Integer NbOnC = TheCurveTool::NbIntervals(curve,GeomAbs_C2);
321 Standard_Real U0,U1,V0,V1;
324 TColStd_Array1OfReal TabU(1,NbUOnS+1);
325 TheSurfaceTool::UIntervals(surface,TabU,GeomAbs_C2);
326 for(Standard_Integer iu = 1;iu <= NbUOnS; iu++) {
328 U1 = TabU.Value(iu+1);
330 TColStd_Array1OfReal TabV(1,NbVOnS+1);
331 TheSurfaceTool::VIntervals(surface,TabV,GeomAbs_C2);
332 for(Standard_Integer iv = 1;iv <= NbVOnS; iv++) {
334 V1 = TabV.Value(iv+1);
335 Perform(curve,surface,U0,V0,U1,V1);
338 else { //------ composite en U non composite en V
339 V0 = TheSurfaceTool::FirstVParameter(surface);
340 V1 = TheSurfaceTool::LastVParameter(surface);
341 Perform(curve,surface,U0,V0,U1,V1);
345 else if(NbVOnS > 1) { //---------- non composite en U composite en V
346 U0 = TheSurfaceTool::FirstUParameter(surface);
347 U1 = TheSurfaceTool::LastUParameter(surface);
348 TColStd_Array1OfReal TabV(1,NbVOnS+1);
349 TheSurfaceTool::VIntervals(surface,TabV,GeomAbs_C2);
350 for(Standard_Integer iv = 1;iv <= NbVOnS; iv++) {
352 V1 = TabV.Value(iv+1);
353 Perform(curve,surface,U0,V0,U1,V1);
357 V0 = TheSurfaceTool::FirstVParameter(surface);
358 V1 = TheSurfaceTool::LastVParameter(surface);
359 U0 = TheSurfaceTool::FirstUParameter(surface);
360 U1 = TheSurfaceTool::LastUParameter(surface);
364 //-- jgv patch (from)
365 //Computing of local bounds
366 Standard_Real LocalU0 = U0, LocalU1 = U1, LocalV0 = V0, LocalV1 = V1;
367 Standard_Real Umin = RealLast(), Vmin = RealLast(), Umax = RealFirst(), Vmax = RealFirst();
369 Standard_Integer i, j, k;
370 //Making GeomAdaptor_Curve
371 Standard_Real f = TheCurveTool::FirstParameter(curve);
372 Standard_Real l = TheCurveTool::LastParameter(curve);
373 GeomAbs_CurveType CurveType = TheCurveTool::GetType(curve);
374 Handle(Geom_Curve) theCurve;
378 theCurve = new Geom_Line( TheCurveTool::Line(curve) );
381 theCurve = new Geom_Circle( TheCurveTool::Circle(curve) );
383 case GeomAbs_Ellipse:
384 theCurve = new Geom_Ellipse( TheCurveTool::Ellipse(curve) );
386 case GeomAbs_Hyperbola:
387 theCurve = new Geom_Hyperbola( TheCurveTool::Hyperbola(curve) );
389 case GeomAbs_Parabola:
390 theCurve = new Geom_Parabola( TheCurveTool::Parabola(curve) );
392 case GeomAbs_BezierCurve:
393 theCurve = TheCurveTool::Bezier(curve);
395 case GeomAbs_BSplineCurve:
396 theCurve = TheCurveTool::BSpline(curve);
399 if (!theCurve.IsNull())
401 GeomAdaptor_Curve GACurve( theCurve, f, l );
402 BndLib_Add3dCurve::Add( GACurve, Precision::Confusion(), CurveBox );
406 Standard_Integer nbp = TheCurveTool::NbSamples(curve,f,l);
407 Standard_Real delta = (f-l)/nbp;
408 for (i = 0; i <= nbp; i++)
410 gp_Pnt aPnt = TheCurveTool::Value(curve, f + i*delta);
414 Standard_Real X[2], Y[2], Z[2];
415 CurveBox.Get( X[0], Y[0], Z[0], X[1], Y[1], Z[1] );
416 Standard_Real Ures = TheSurfaceTool::UResolution(surface, Precision::Confusion());
417 Standard_Real Vres = TheSurfaceTool::VResolution(surface, Precision::Confusion());
418 //Making GeomAdaptor_Surface
419 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
420 Handle(Geom_Surface) theSurface;
424 theSurface = new Geom_Plane( TheSurfaceTool::Plane(surface) );
426 case GeomAbs_Cylinder:
427 theSurface = new Geom_CylindricalSurface( TheSurfaceTool::Cylinder(surface) );
430 theSurface = new Geom_ConicalSurface( TheSurfaceTool::Cone(surface) );
433 theSurface = new Geom_ToroidalSurface( TheSurfaceTool::Torus(surface) );
436 theSurface = new Geom_SphericalSurface( TheSurfaceTool::Sphere(surface) );
438 case GeomAbs_BezierSurface:
439 theSurface = TheSurfaceTool::Bezier(surface);
441 case GeomAbs_BSplineSurface:
442 theSurface = TheSurfaceTool::BSpline(surface);
444 case GeomAbs_SurfaceOfRevolution:
446 gp_Ax1 Axis = TheSurfaceTool::AxeOfRevolution(surface);
447 Handle(Adaptor3d_HCurve) AdBC = TheSurfaceTool::BasisCurve(surface);
448 Handle(Geom_Curve) BC = GetCurve(AdBC);
450 theSurface = new Geom_SurfaceOfRevolution( BC, Axis );
453 case GeomAbs_SurfaceOfExtrusion:
455 gp_Dir Direction = TheSurfaceTool::Direction(surface);
456 Handle(Adaptor3d_HCurve) AdBC = TheSurfaceTool::BasisCurve(surface);
457 Handle(Geom_Curve) BC = GetCurve(AdBC);
459 theSurface = new Geom_SurfaceOfLinearExtrusion( BC, Direction );
462 case GeomAbs_OffsetSurface:
464 Standard_Real OffsetValue = TheSurfaceTool::OffsetValue(surface);
465 Handle(Adaptor3d_HSurface) AdBS = TheSurfaceTool::BasisSurface(surface);
466 Handle(Geom_Surface) BS = GetSurface(AdBS);
468 theSurface = new Geom_OffsetSurface( BS, OffsetValue );
472 if (!theSurface.IsNull())
474 GeomAdaptor_Surface GASurface( theSurface );
475 Extrema_ExtPS Projector;
476 Projector.Initialize( GASurface, U0, U1, V0, V1, Ures, Vres );
477 for (i = 0; i <= 1; i++)
478 for (j = 0; j <= 1; j++)
479 for (k = 0; k <= 1; k++)
481 gp_Pnt aPoint( X[i], Y[j], Z[k] );
482 Projector.Perform( aPoint );
483 if (Projector.IsDone() && Projector.NbExt() > 0)
485 Standard_Real mindist = RealLast();
486 Standard_Integer minind, ind;
487 for (ind = 1; ind <= Projector.NbExt(); ind++)
489 Standard_Real dist = Projector.Value(ind);
496 Extrema_POnSurf pons = Projector.Point(minind);
498 pons.Parameter( U, V );
499 if (U < Umin) Umin = U;
500 if (U > Umax) Umax = U;
501 if (V < Vmin) Vmin = V;
502 if (V > Vmax) Vmax = V;
505 Umin -= Ures; Umax += Ures; Vmin -= Vres; Vmax += Vres;
506 if (Umin > U0 && Umin <= U1) LocalU0 = Umin;
507 if (Umax < U1 && Umax >= U0) LocalU1 = Umax;
508 if (Vmin > V0 && Vmin <= V1) LocalV0 = Vmin;
509 if (Vmax < V1 && Vmax >= V0) LocalV1 = Vmax;
510 U0 = LocalU0; U1 = LocalU1; V0 = LocalV0; V1 = LocalV1;
514 Perform(curve,surface,U0,V0,U1,V1);
517 //=======================================================================
520 //=======================================================================
521 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
522 const TheSurface& surface,
523 const Standard_Real U1,const Standard_Real V1,
524 const Standard_Real U2,const Standard_Real V2) {
526 GeomAbs_CurveType CurveType = TheCurveTool::GetType(curve);
531 PerformConicSurf(TheCurveTool::Line(curve),curve,surface,U1,V1,U2,V2);
536 PerformConicSurf(TheCurveTool::Circle(curve),curve,surface,U1,V1,U2,V2);
539 case GeomAbs_Ellipse:
541 PerformConicSurf(TheCurveTool::Ellipse(curve),curve,surface,U1,V1,U2,V2);
544 case GeomAbs_Parabola:
546 PerformConicSurf(TheCurveTool::Parabola(curve),curve,surface,U1,V1,U2,V2);
549 case GeomAbs_Hyperbola:
551 PerformConicSurf(TheCurveTool::Hyperbola(curve),curve,surface,U1,V1,U2,V2);
556 Standard_Integer nbIntervalsOnCurve = TheCurveTool::NbIntervals(curve,GeomAbs_C2);
557 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
558 if( (SurfaceType != GeomAbs_Plane)
559 && (SurfaceType != GeomAbs_Cylinder)
560 && (SurfaceType != GeomAbs_Cone)
561 && (SurfaceType != GeomAbs_Sphere)) {
563 if(nbIntervalsOnCurve > 1) {
564 TColStd_Array1OfReal TabW(1,nbIntervalsOnCurve+1);
565 TheCurveTool::Intervals(curve,TabW,GeomAbs_C2);
566 for(Standard_Integer i = 1; i<=nbIntervalsOnCurve; i++) {
569 u2 = TabW.Value(i+1);
571 Handle(TColStd_HArray1OfReal) aPars;
572 Standard_Real defl = 0.1;
573 Standard_Integer NbMin = 10;
574 TheCurveTool::SamplePars(curve, u1, u2, defl, NbMin, aPars);
576 // IntCurveSurface_ThePolygon polygon(curve,u1,u2,TheCurveTool::NbSamples(curve,u1,u2));
577 IntCurveSurface_ThePolygon polygon(curve, aPars->Array1());
578 InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
583 u1 = TheCurveTool::FirstParameter(curve);
584 u2 = TheCurveTool::LastParameter(curve);
586 Handle(TColStd_HArray1OfReal) aPars;
587 Standard_Real defl = 0.1;
588 Standard_Integer NbMin = 10;
589 TheCurveTool::SamplePars(curve, u1, u2, defl, NbMin, aPars);
591 // IntCurveSurface_ThePolygon polygon(curve,TheCurveTool::NbSamples(curve,u1,u2));
592 IntCurveSurface_ThePolygon polygon(curve, aPars->Array1());
593 InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
596 else { //-- la surface est une quadrique
597 InternalPerformCurveQuadric(curve,surface);
602 //=======================================================================
605 //=======================================================================
606 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
607 const IntCurveSurface_ThePolygon& polygon,
608 const TheSurface& surface) {
610 done = Standard_True;
611 Standard_Real u1,v1,u2,v2;
612 u1 = TheSurfaceTool::FirstUParameter(surface);
613 v1 = TheSurfaceTool::FirstVParameter(surface);
614 u2 = TheSurfaceTool::LastUParameter(surface);
615 v2 = TheSurfaceTool::LastVParameter(surface);
616 Standard_Integer nbsu,nbsv;
617 nbsu = TheSurfaceTool::NbSamplesU(surface,u1,u2);
618 nbsv = TheSurfaceTool::NbSamplesV(surface,v1,v2);
621 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,u1,v1,u2,v2);
622 Perform(curve,polygon,surface,polyhedron);
624 //=======================================================================
627 //=======================================================================
628 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
629 const TheSurface& surface,
630 const IntCurveSurface_ThePolyhedron& polyhedron) {
632 done = Standard_True;
633 Standard_Real u1 = TheCurveTool::FirstParameter(curve);
634 Standard_Real u2 = TheCurveTool::LastParameter(curve);
635 IntCurveSurface_ThePolygon polygon(curve,TheCurveTool::NbSamples(curve,u1,u2));
636 Perform(curve,polygon,surface,polyhedron);
638 //=======================================================================
641 //=======================================================================
642 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
643 const IntCurveSurface_ThePolygon& polygon,
644 const TheSurface& surface,
645 const IntCurveSurface_ThePolyhedron& polyhedron) {
647 done = Standard_True;
648 Standard_Real u1,v1,u2,v2;
649 u1 = TheSurfaceTool::FirstUParameter(surface);
650 v1 = TheSurfaceTool::FirstVParameter(surface);
651 u2 = TheSurfaceTool::LastUParameter(surface);
652 v2 = TheSurfaceTool::LastVParameter(surface);
653 InternalPerform(curve,polygon,surface,polyhedron,u1,v1,u2,v2);
656 //=======================================================================
659 //=======================================================================
660 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
661 const IntCurveSurface_ThePolygon& polygon,
662 const TheSurface& surface,
663 const IntCurveSurface_ThePolyhedron& polyhedron,
664 Bnd_BoundSortBox& BndBSB) {
666 done = Standard_True;
667 Standard_Real u1,v1,u2,v2;
668 u1 = TheSurfaceTool::FirstUParameter(surface);
669 v1 = TheSurfaceTool::FirstVParameter(surface);
670 u2 = TheSurfaceTool::LastUParameter(surface);
671 v2 = TheSurfaceTool::LastVParameter(surface);
672 InternalPerform(curve,polygon,surface,polyhedron,u1,v1,u2,v2,BndBSB);
674 //=======================================================================
675 //function : InternalPerform
676 //purpose : C a l c u l d u p o i n t a p p r o c h e
677 //== p u i s d u p o i n t E x a c t
678 //=======================================================================
679 void IntCurveSurface_Inter::InternalPerform(const TheCurve& curve,
680 const IntCurveSurface_ThePolygon& polygon,
681 const TheSurface& surface,
682 const IntCurveSurface_ThePolyhedron& polyhedron,
683 const Standard_Real u0,
684 const Standard_Real v0,
685 const Standard_Real u1,
686 const Standard_Real v1,
687 Bnd_BoundSortBox& BSB) {
688 IntCurveSurface_TheInterference interference(polygon,polyhedron,BSB);
689 IntCurveSurface_TheCSFunction theicsfunction(surface,curve);
690 IntCurveSurface_TheExactInter intersectionExacte(theicsfunction,TOLTANGENCY);
691 math_FunctionSetRoot rsnld(intersectionExacte.Function());
693 // Standard_Real u,v,w,winit;
696 Standard_Real winf = polygon.InfParameter();
697 Standard_Real wsup = polygon.SupParameter();
698 Standard_Integer NbSectionPoints = interference.NbSectionPoints();
699 Standard_Integer NbTangentZones = interference.NbTangentZones();
702 //-- Les interferences renvoient parfois de nombreuses fois (>20) les memes points
704 Standard_Integer i,NbStartPoints=NbSectionPoints;
705 for(i=1; i<= NbTangentZones; i++) {
706 const Intf_TangentZone& TZ = interference.ZoneValue(i);
707 Standard_Integer nbpnts = TZ.NumberOfPoints();
708 NbStartPoints+=nbpnts;
712 Standard_Real *TabU = new Standard_Real [NbStartPoints+1];
713 Standard_Real *TabV = new Standard_Real [NbStartPoints+1];
714 Standard_Real *TabW = new Standard_Real [NbStartPoints+1];
715 Standard_Integer IndexPoint=0;
717 for(i=1; i<= NbSectionPoints; i++) {
718 const Intf_SectionPoint& SP = interference.PntValue(i);
719 SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
725 for(i=1; i<= NbTangentZones; i++) {
726 const Intf_TangentZone& TZ = interference.ZoneValue(i);
727 Standard_Integer nbpnts = TZ.NumberOfPoints();
728 for(Standard_Integer j=1; j<=nbpnts; j++) {
729 const Intf_SectionPoint& SP = TZ.GetPoint(j);
730 SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
739 Standard_Real su=0,sv=0,sw=0,ptol;
740 ptol = 10*Precision::PConfusion();
742 //-- Tri suivant la variable W
743 Standard_Boolean Triok;
746 Standard_Integer im1;
747 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
748 if(TabW[i] < TabW[im1]) {
749 Standard_Real t=TabW[i]; TabW[i]=TabW[im1]; TabW[im1]=t;
750 t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
751 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
752 Triok=Standard_False;
756 while(Triok==Standard_False);
758 //-- On trie pour des meme W suivant U
761 Standard_Integer im1;
762 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
763 // modified by NIZHNY-MKK Mon Oct 3 17:38:49 2005
764 // if(Abs(TabW[i]-TabW[im1])<ptol) {
765 if((TabW[i]-TabW[im1])<ptol) {
767 if(TabU[i] < TabU[im1]) {
768 Standard_Real t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
769 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
770 Triok=Standard_False;
775 while(Triok==Standard_False);
777 //-- On trie pour des meme U et W suivant V
780 Standard_Integer im1;
781 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
782 // modified by NIZHNY-MKK Mon Oct 3 17:38:52 2005
783 // if((Abs(TabW[i]-TabW[im1])<ptol) && (Abs(TabU[i]-TabU[im1])<ptol)) {
784 if(((TabW[i]-TabW[im1])<ptol) && ((TabU[i]-TabU[im1])<ptol)) {
786 if(TabV[i] < TabV[im1]) {
787 Standard_Real t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
788 Triok=Standard_False;
793 while(Triok==Standard_False);
796 for(i=0;i<NbStartPoints; i++) {
797 u=TabU[i]; v=TabV[i]; w=TabW[i];
801 if(Abs(u-su)>ptol || Abs(v-sv)>ptol || Abs(w-sw)>ptol) {
802 intersectionExacte.Perform(u,v,w,rsnld,u0,u1,v0,v1,winf,wsup);
803 if(intersectionExacte.IsDone()) {
804 if(!intersectionExacte.IsEmpty()) {
805 P=intersectionExacte.Point();
806 w=intersectionExacte.ParameterOnCurve();
807 intersectionExacte.ParameterOnSurface(u,v);
808 AppendPoint(curve,w,surface,u,v);
812 su=TabU[i]; sv=TabV[i]; sw=TabW[i];
820 //=======================================================================
821 //function : InternalPerform
823 //=======================================================================
824 void IntCurveSurface_Inter::InternalPerform(const TheCurve& curve,
825 const IntCurveSurface_ThePolygon& polygon,
826 const TheSurface& surface,
827 const IntCurveSurface_ThePolyhedron& polyhedron,
828 const Standard_Real u0,
829 const Standard_Real v0,
830 const Standard_Real u1,
831 const Standard_Real v1) {
832 IntCurveSurface_TheInterference interference(polygon,polyhedron);
833 IntCurveSurface_TheCSFunction theicsfunction(surface,curve);
834 IntCurveSurface_TheExactInter intersectionExacte(theicsfunction,TOLTANGENCY);
835 math_FunctionSetRoot rsnld(intersectionExacte.Function());
837 // Standard_Real u,v,w,winit;
840 Standard_Real winf = polygon.InfParameter();
841 Standard_Real wsup = polygon.SupParameter();
842 Standard_Integer NbSectionPoints = interference.NbSectionPoints();
843 Standard_Integer NbTangentZones = interference.NbTangentZones();
846 //-- Les interferences renvoient parfois de nombreuses fois (>20) les memes points
848 Standard_Integer i,NbStartPoints=NbSectionPoints;
849 for(i=1; i<= NbTangentZones; i++) {
850 const Intf_TangentZone& TZ = interference.ZoneValue(i);
851 Standard_Integer nbpnts = TZ.NumberOfPoints();
852 NbStartPoints+=nbpnts;
856 Standard_Real *TabU = new Standard_Real [NbStartPoints+1];
857 Standard_Real *TabV = new Standard_Real [NbStartPoints+1];
858 Standard_Real *TabW = new Standard_Real [NbStartPoints+1];
859 Standard_Integer IndexPoint=0;
861 for(i=1; i<= NbSectionPoints; i++) {
862 const Intf_SectionPoint& SP = interference.PntValue(i);
863 SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
869 for(i=1; i<= NbTangentZones; i++) {
870 const Intf_TangentZone& TZ = interference.ZoneValue(i);
871 Standard_Integer nbpnts = TZ.NumberOfPoints();
872 for(Standard_Integer j=1; j<=nbpnts; j++) {
873 const Intf_SectionPoint& SP = TZ.GetPoint(j);
874 SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
883 Standard_Real su=0,sv=0,sw=0,ptol;
884 ptol = 10*Precision::PConfusion();
886 //-- Tri suivant la variable W
887 Standard_Boolean Triok;
890 Standard_Integer im1;
891 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
892 if(TabW[i] < TabW[im1]) {
893 Standard_Real t=TabW[i]; TabW[i]=TabW[im1]; TabW[im1]=t;
894 t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
895 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
896 Triok=Standard_False;
900 while(Triok==Standard_False);
902 //-- On trie pour des meme W suivant U
905 Standard_Integer im1;
906 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
907 // modified by NIZHNY-MKK Mon Oct 3 17:38:56 2005
908 // if(Abs(TabW[i]-TabW[im1])<ptol) {
909 if((TabW[i]-TabW[im1])<ptol) {
911 if(TabU[i] < TabU[im1]) {
912 Standard_Real t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
913 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
914 Triok=Standard_False;
919 while(Triok==Standard_False);
921 //-- On trie pour des meme U et W suivant V
924 Standard_Integer im1;
925 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
926 // modified by NIZHNY-MKK Mon Oct 3 17:38:58 2005
927 // if((Abs(TabW[i]-TabW[im1])<ptol) && (Abs(TabU[i]-TabU[im1])<ptol)) {
928 if(((TabW[i]-TabW[im1])<ptol) && ((TabU[i]-TabU[im1])<ptol)) {
930 if(TabV[i] < TabV[im1]) {
931 Standard_Real t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
932 Triok=Standard_False;
937 while(Triok==Standard_False);
940 for(i=0;i<NbStartPoints; i++) {
941 u=TabU[i]; v=TabV[i]; w=TabW[i];
945 if(Abs(u-su)>ptol || Abs(v-sv)>ptol || Abs(w-sw)>ptol) {
946 intersectionExacte.Perform(u,v,w,rsnld,u0,u1,v0,v1,winf,wsup);
947 if(intersectionExacte.IsDone()) {
948 if(!intersectionExacte.IsEmpty()) {
949 P=intersectionExacte.Point();
950 w=intersectionExacte.ParameterOnCurve();
951 intersectionExacte.ParameterOnSurface(u,v);
952 AppendPoint(curve,w,surface,u,v);
956 su=TabU[i]; sv=TabV[i]; sw=TabW[i];
963 //=======================================================================
964 //function : InternalPerformCurveQuadric
966 //=======================================================================
967 void IntCurveSurface_Inter::InternalPerformCurveQuadric(const TheCurve& curve,
968 const TheSurface& surface) {
969 IntCurveSurface_TheQuadCurvExactInter QuadCurv(surface,curve);
970 if(QuadCurv.IsDone()) {
971 Standard_Integer NbRoots = QuadCurv.NbRoots();
973 for(Standard_Integer i = 1; i<= NbRoots; i++) {
974 w = QuadCurv.Root(i);
975 IntCurveSurface_ComputeParamsOnQuadric(surface,TheCurveTool::Value(curve,w),u,v);
976 AppendPoint(curve,w,surface,u,v);
978 //-- Intervals non traites .............................................
982 //=======================================================================
983 //function : InternalPerform
985 //=======================================================================
986 void IntCurveSurface_Inter::InternalPerform(const TheCurve& curve,
987 const IntCurveSurface_ThePolygon& polygon,
988 const TheSurface& surface,
989 const Standard_Real U1,
990 const Standard_Real V1,
991 const Standard_Real U2,
992 const Standard_Real V2) {
993 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
994 if( (SurfaceType != GeomAbs_Plane)
995 && (SurfaceType != GeomAbs_Cylinder)
996 && (SurfaceType != GeomAbs_Cone)
997 && (SurfaceType != GeomAbs_Sphere) ) {
998 if(SurfaceType != GeomAbs_BSplineSurface) {
999 Standard_Integer nbsu,nbsv;
1000 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1001 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1002 if(nbsu>40) nbsu=40;
1003 if(nbsv>40) nbsv=40;
1004 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2);
1005 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1008 Handle(Adaptor3d_HSurface) aS = TheSurfaceTool::UTrim(surface, U1, U2, 1.e-9);
1009 aS = aS->VTrim(V1, V2, 1.e-9);
1010 Handle(Adaptor3d_TopolTool) aTopTool = new Adaptor3d_TopolTool(aS);
1011 Standard_Real defl = 0.1;
1012 aTopTool->SamplePnts(defl, 10, 10);
1014 Standard_Integer nbpu = aTopTool->NbSamplesU();
1015 Standard_Integer nbpv = aTopTool->NbSamplesV();
1016 TColStd_Array1OfReal Upars(1, nbpu), Vpars(1, nbpv);
1017 aTopTool->UParameters(Upars);
1018 aTopTool->VParameters(Vpars);
1020 IntCurveSurface_ThePolyhedron polyhedron(surface,Upars, Vpars);
1021 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1025 IntCurveSurface_TheQuadCurvExactInter QuadCurv(surface,curve);
1026 if(QuadCurv.IsDone()) {
1027 Standard_Integer NbRoots = QuadCurv.NbRoots();
1028 Standard_Real u,v,w;
1029 for(Standard_Integer i = 1; i<= NbRoots; i++) {
1030 w = QuadCurv.Root(i);
1031 IntCurveSurface_ComputeParamsOnQuadric(surface,TheCurveTool::Value(curve,w),u,v);
1032 AppendPoint(curve,w,surface,u,v);
1034 //-- Intervalles non traites .............................................
1036 } //-- Fin : la Surface est une quadrique
1038 //=======================================================================
1039 //function : PerformConicSurf
1041 //=======================================================================
1042 void IntCurveSurface_Inter::PerformConicSurf(const gp_Lin& Line,
1043 const TheCurve& curve,
1044 const TheSurface& surface,
1045 const Standard_Real U1,
1046 const Standard_Real V1,
1047 const Standard_Real U2,
1048 const Standard_Real V2) {
1051 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1052 switch(SurfaceType) {
1055 IntAna_IntConicQuad LinPlane(Line,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE);
1056 AppendIntAna(curve,surface,LinPlane);
1059 case GeomAbs_Cylinder:
1061 IntAna_IntConicQuad LinCylinder(Line,TheSurfaceTool::Cylinder(surface));
1062 AppendIntAna(curve,surface,LinCylinder);
1065 case GeomAbs_Sphere:
1067 IntAna_IntConicQuad LinSphere(Line,TheSurfaceTool::Sphere(surface));
1068 AppendIntAna(curve,surface,LinSphere);
1073 IntAna_IntLinTorus intlintorus(Line,TheSurfaceTool::Torus(surface));
1074 if(intlintorus.IsDone()) {
1075 Standard_Integer nbp = intlintorus.NbPoints();
1076 Standard_Real fi,theta,w;
1077 for(Standard_Integer i = 1; i<= nbp; i++) {
1080 P = intlintorus.Value(i);
1082 gp_Pnt P(intlintorus.Value(i));
1084 w = intlintorus.ParamOnLine(i);
1085 intlintorus.ParamOnTorus(i,fi,theta);
1086 AppendPoint(curve,w,surface,fi,theta);
1090 } //-- Si Done retourne False, On passe dans Default !!
1094 const Standard_Real correction = 1.E+5*Precision::Angular();
1095 gp_Cone cn = TheSurfaceTool::Cone(surface);
1096 if(Abs(cn.SemiAngle()) < M_PI/2.0 - correction){
1097 IntAna_IntConicQuad LinCone(Line,cn);
1098 AppendIntAna(curve,surface,LinCone);
1104 Standard_Integer nbsu,nbsv;
1105 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1106 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1108 Standard_Boolean U1inf = Precision::IsInfinite(U1);
1109 Standard_Boolean U2inf = Precision::IsInfinite(U2);
1110 Standard_Boolean V1inf = Precision::IsInfinite(V1);
1111 Standard_Boolean V2inf = Precision::IsInfinite(V2);
1113 Standard_Real U1new=U1, U2new=U2, V1new=V1, V2new=V2;
1115 Standard_Boolean NoIntersection = Standard_False;
1117 if(U1inf || U2inf || V1inf || V2inf ) {
1119 if(SurfaceType == GeomAbs_SurfaceOfExtrusion) {
1121 EstLimForInfExtr(Line, surface, Standard_False, nbsu,
1122 U1inf, U2inf, V1inf, V2inf,
1123 U1new, U2new, V1new, V2new, NoIntersection);
1126 else if(SurfaceType == GeomAbs_SurfaceOfRevolution) {
1128 EstLimForInfRevl(Line, surface,
1129 U1inf, U2inf, V1inf, V2inf,
1130 U1new, U2new, V1new, V2new, NoIntersection);
1133 else if(SurfaceType == GeomAbs_OffsetSurface) {
1135 EstLimForInfOffs(Line, surface, nbsu,
1136 U1inf, U2inf, V1inf, V2inf,
1137 U1new, U2new, V1new, V2new, NoIntersection);
1141 EstLimForInfSurf(U1new, U2new, V1new, V2new);
1147 if(NoIntersection) return;
1150 // modified by NIZHNY-OFV Mon Aug 20 14:56:47 2001 (60963 begin)
1151 if(nbsu<20) nbsu=20;
1152 if(nbsv<20) nbsv=20;
1153 // modified by NIZHNY-OFV Mon Aug 20 14:57:06 2001 (60963 end)
1154 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1new,V1new,U2new,V2new);
1157 bndTool.LinBox(Line,polyhedron.Bounding(),boxLine);
1158 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) {
1159 Standard_Real pinf = bndTool.BeginParam(nbseg);
1160 Standard_Real psup = bndTool.EndParam(nbseg);
1161 if((psup - pinf)<1e-10) { pinf-=1e-10; psup+=1e-10; }
1162 IntCurveSurface_ThePolygon polygon(curve, pinf,psup,2);
1163 InternalPerform(curve,polygon,surface,polyhedron,U1new,V1new,U2new,V2new);
1168 //=======================================================================
1169 //function : PerformConicSurf
1171 //=======================================================================
1172 void IntCurveSurface_Inter::PerformConicSurf(const gp_Circ& Circle,
1173 const TheCurve& curve,
1174 const TheSurface& surface,
1175 const Standard_Real U1,
1176 const Standard_Real V1,
1177 const Standard_Real U2,
1178 const Standard_Real V2) {
1180 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1181 switch(SurfaceType) {
1184 IntAna_IntConicQuad CircPlane(Circle,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE,TOLERANCE);
1185 AppendIntAna(curve,surface,CircPlane);
1188 case GeomAbs_Cylinder:
1190 IntAna_IntConicQuad CircCylinder(Circle,TheSurfaceTool::Cylinder(surface));
1191 AppendIntAna(curve,surface,CircCylinder);
1196 IntAna_IntConicQuad CircCone(Circle,TheSurfaceTool::Cone(surface));
1197 AppendIntAna(curve,surface,CircCone);
1200 case GeomAbs_Sphere:
1202 IntAna_IntConicQuad CircSphere(Circle,TheSurfaceTool::Sphere(surface));
1203 AppendIntAna(curve,surface,CircSphere);
1208 IntCurveSurface_ThePolygon polygon(curve,NBSAMPLESONCIRCLE);
1209 InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
1213 //=======================================================================
1214 //function : PerformConicSurf
1216 //=======================================================================
1217 void IntCurveSurface_Inter::PerformConicSurf(const gp_Elips& Ellipse,
1218 const TheCurve& curve,
1219 const TheSurface& surface,
1220 const Standard_Real U1,
1221 const Standard_Real V1,
1222 const Standard_Real U2,
1223 const Standard_Real V2) {
1225 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1226 switch(SurfaceType) {
1229 IntAna_IntConicQuad EllipsePlane(Ellipse,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE,TOLERANCE);
1230 AppendIntAna(curve,surface,EllipsePlane);
1233 case GeomAbs_Cylinder:
1235 IntAna_IntConicQuad EllipseCylinder(Ellipse,TheSurfaceTool::Cylinder(surface));
1236 AppendIntAna(curve,surface,EllipseCylinder);
1241 IntAna_IntConicQuad EllipseCone(Ellipse,TheSurfaceTool::Cone(surface));
1242 AppendIntAna(curve,surface,EllipseCone);
1245 case GeomAbs_Sphere:
1247 IntAna_IntConicQuad EllipseSphere(Ellipse,TheSurfaceTool::Sphere(surface));
1248 AppendIntAna(curve,surface,EllipseSphere);
1253 IntCurveSurface_ThePolygon polygon(curve,NBSAMPLESONELLIPSE);
1254 InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
1258 //=======================================================================
1259 //function : PerformConicSurf
1261 //=======================================================================
1262 void IntCurveSurface_Inter::PerformConicSurf(const gp_Parab& Parab,
1263 const TheCurve& curve,
1264 const TheSurface& surface,
1265 const Standard_Real U1,
1266 const Standard_Real V1,
1267 const Standard_Real U2,
1268 const Standard_Real V2) {
1270 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1271 switch(SurfaceType) {
1274 IntAna_IntConicQuad ParabPlane(Parab,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE);
1275 AppendIntAna(curve,surface,ParabPlane);
1278 case GeomAbs_Cylinder:
1280 IntAna_IntConicQuad ParabCylinder(Parab,TheSurfaceTool::Cylinder(surface));
1281 AppendIntAna(curve,surface,ParabCylinder);
1286 IntAna_IntConicQuad ParabCone(Parab,TheSurfaceTool::Cone(surface));
1287 AppendIntAna(curve,surface,ParabCone);
1290 case GeomAbs_Sphere:
1292 IntAna_IntConicQuad ParabSphere(Parab,TheSurfaceTool::Sphere(surface));
1293 AppendIntAna(curve,surface,ParabSphere);
1298 Standard_Integer nbsu,nbsv;
1299 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1300 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1301 if(nbsu>40) nbsu=40;
1302 if(nbsv>40) nbsv=40;
1303 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2);
1306 bndTool.ParabBox(Parab,polyhedron.Bounding(),boxParab);
1307 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) {
1308 IntCurveSurface_ThePolygon polygon(curve,
1309 bndTool.BeginParam(nbseg),
1310 bndTool.EndParam(nbseg),
1312 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1317 //=======================================================================
1318 //function : PerformConicSurf
1320 //=======================================================================
1321 void IntCurveSurface_Inter::PerformConicSurf(const gp_Hypr& Hypr,
1322 const TheCurve& curve,
1323 const TheSurface& surface,
1324 const Standard_Real U1,
1325 const Standard_Real V1,
1326 const Standard_Real U2,
1327 const Standard_Real V2) {
1329 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1330 switch(SurfaceType) {
1333 IntAna_IntConicQuad HyprPlane(Hypr,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE);
1334 AppendIntAna(curve,surface,HyprPlane);
1337 case GeomAbs_Cylinder:
1339 IntAna_IntConicQuad HyprCylinder(Hypr,TheSurfaceTool::Cylinder(surface));
1340 AppendIntAna(curve,surface,HyprCylinder);
1345 IntAna_IntConicQuad HyprCone(Hypr,TheSurfaceTool::Cone(surface));
1346 AppendIntAna(curve,surface,HyprCone);
1349 case GeomAbs_Sphere:
1351 IntAna_IntConicQuad HyprSphere(Hypr,TheSurfaceTool::Sphere(surface));
1352 AppendIntAna(curve,surface,HyprSphere);
1357 Standard_Integer nbsu,nbsv;
1358 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1359 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1360 if(nbsu>40) nbsu=40;
1361 if(nbsv>40) nbsv=40;
1362 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2);
1365 bndTool.HyprBox(Hypr,polyhedron.Bounding(),boxHypr);
1366 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) {
1367 IntCurveSurface_ThePolygon polygon(curve,
1368 bndTool.BeginParam(nbseg),
1369 bndTool.EndParam(nbseg),
1371 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1376 //=======================================================================
1377 //function : AppendIntAna
1379 //=======================================================================
1380 void IntCurveSurface_Inter::AppendIntAna(const TheCurve& curve,
1381 const TheSurface& surface,
1382 const IntAna_IntConicQuad& intana_ConicQuad) {
1383 if(intana_ConicQuad.IsDone()) {
1384 if(intana_ConicQuad.IsInQuadric()) {
1385 //-- cout<<" Courbe Dans la Quadrique !!! Non Traite !!!"<<endl;
1387 else if(intana_ConicQuad.IsParallel()) {
1388 //-- cout<<" Courbe // a la Quadrique !!! Non Traite !!!"<<endl;
1391 Standard_Integer nbp = intana_ConicQuad.NbPoints();
1392 Standard_Real u,v,w;
1393 for(Standard_Integer i = 1; i<= nbp; i++) {
1394 gp_Pnt P(intana_ConicQuad.Point(i));
1395 w = intana_ConicQuad.ParamOnConic(i);
1396 IntCurveSurface_ComputeParamsOnQuadric(surface,P,u,v);
1397 AppendPoint(curve,w,surface,u,v);
1402 //-- cout<<" IntAna Conic Quad Not Done "<<endl;
1405 //=======================================================================
1406 //function : AppendPoint
1408 //=======================================================================
1409 void IntCurveSurface_Inter::AppendPoint(const TheCurve& curve,
1410 const Standard_Real lw,
1411 const TheSurface& surface,
1412 const Standard_Real su,
1413 const Standard_Real sv) {
1415 Standard_Real W0 = TheCurveTool::FirstParameter(curve);
1416 Standard_Real W1 = TheCurveTool::LastParameter(curve);
1417 Standard_Real U0 = TheSurfaceTool::FirstUParameter(surface);
1418 Standard_Real U1 = TheSurfaceTool::LastUParameter(surface);
1419 Standard_Real V0 = TheSurfaceTool::FirstVParameter(surface);
1420 Standard_Real V1 = TheSurfaceTool::LastVParameter(surface);
1421 //-- Test si la courbe est periodique
1422 Standard_Real w = lw, u = su, v = sv;
1424 GeomAbs_CurveType aCType = TheCurveTool::GetType(curve);
1426 if(TheCurveTool::IsPeriodic(curve)
1427 || aCType == GeomAbs_Circle
1428 || aCType == GeomAbs_Ellipse) {
1429 w = ElCLib::InPeriod(w, W0, W0 + TheCurveTool::Period(curve));
1432 if((W0 - w) >= TOLTANGENCY || (w - W1) >= TOLTANGENCY) return;
1434 GeomAbs_SurfaceType aSType = TheSurfaceTool::GetType(surface);
1435 if (TheSurfaceTool::IsUPeriodic(surface)
1436 || aSType == GeomAbs_Cylinder
1437 || aSType == GeomAbs_Cone
1438 || aSType == GeomAbs_Sphere) {
1439 u = ElCLib::InPeriod(u, U0, U0 + TheSurfaceTool::UPeriod(surface));
1442 if (TheSurfaceTool::IsVPeriodic(surface)) {
1443 v = ElCLib::InPeriod(v, V0, V0 + TheSurfaceTool::VPeriod(surface));
1446 if((U0 - u) >= TOLTANGENCY || (u - U1) >= TOLTANGENCY) return;
1447 if((V0 - v) >= TOLTANGENCY || (v - V1) >= TOLTANGENCY) return;
1449 IntCurveSurface_TransitionOnCurve TransOnCurve;
1450 IntCurveSurface_ComputeTransitions(curve,w,TransOnCurve,
1452 gp_Pnt P(TheCurveTool::Value(curve,w));
1453 IntCurveSurface_IntersectionPoint IP(P,u,v,w,TransOnCurve);
1454 Append(IP); //-- invoque la methode de IntCurveSurface_Intersection.
1458 //=======================================================================
1459 //function : AppendSegment
1461 //=======================================================================
1462 void IntCurveSurface_Inter::AppendSegment(const TheCurve& ,
1463 const Standard_Real ,
1464 const Standard_Real ,
1465 const TheSurface& ) {
1466 //cout<<" !!! Not Yet Implemented
1467 //IntCurveSurface_Inter::Append(const IntCurveSurf ...)"<<endl;
1470 //=======================================================================
1471 //function : SectionPointToParameters
1472 //purpose : P o i n t d i n t e r f e r e n c e - - >
1474 //=======================================================================
1475 void SectionPointToParameters(const Intf_SectionPoint& Sp,
1476 const IntCurveSurface_ThePolyhedron& Polyhedron,
1477 const IntCurveSurface_ThePolygon& Polygon,
1483 Standard_Integer Adr1,Adr2;
1484 Standard_Real Param,u,v;
1487 Standard_Integer Pt1,Pt2,Pt3;
1488 Standard_Real u1 = 0.,v1 = 0.,param;
1489 //----------------------------------------------------------------------
1490 //-- Calcul des parametres approches sur la surface --
1491 //----------------------------------------------------------------------
1493 Sp.InfoSecond(typ,Adr1,Adr2,Param);
1495 case Intf_VERTEX: //-- Adr1 est le numero du vertex
1497 Polyhedron.Parameters(Adr1,u1,v1);
1502 Polyhedron.Parameters(Adr1,u1,v1);
1503 Polyhedron.Parameters(Adr2,u,v);
1504 u1+= Param * (u-u1);
1505 v1+= Param * (v-v1);
1510 Standard_Real ua,va,ub,vb,uc,vc,ca,cb,cc,cabc;
1511 Polyhedron.Triangle(Adr1,Pt1,Pt2,Pt3);
1512 gp_Pnt PA(Polyhedron.Point(Pt1));
1513 gp_Pnt PB(Polyhedron.Point(Pt2));
1514 gp_Pnt PC(Polyhedron.Point(Pt3));
1515 Polyhedron.Parameters(Pt1,ua,va);
1516 Polyhedron.Parameters(Pt2,ub,vb);
1517 Polyhedron.Parameters(Pt3,uc,vc);
1518 gp_Vec Normale(gp_Vec(PA,PB).Crossed(gp_Vec(PA,PC)));
1519 cc = (gp_Vec(PA,PB).Crossed(gp_Vec(PA,P))).Dot(Normale);
1520 ca = (gp_Vec(PB,PC).Crossed(gp_Vec(PB,P))).Dot(Normale);
1521 cb = (gp_Vec(PC,PA).Crossed(gp_Vec(PC,P))).Dot(Normale);
1522 cabc = ca + cb + cc;
1524 ca/=cabc; cb/=cabc; cc/=cabc;
1526 u1 = ca * ua + cb * ub + cc * uc;
1527 v1 = ca * va + cb * vb + cc * vc;
1532 cout<<" Default dans SectionPointToParameters "<<endl;
1536 //----------------------------------------------------------------------
1537 //-- Calcul du point approche sur la Curve --
1538 //----------------------------------------------------------------------
1539 Standard_Integer SegIndex;
1541 Sp.InfoFirst(typ,SegIndex,param);
1542 W = Polygon.ApproxParamOnCurve(SegIndex,param);
1543 if(param>1.0 || param<0.0) {
1544 //-- IntCurveSurface_ThePolyhedronTool::Dump(Polyhedron);
1545 //-- IntCurveSurface_ThePolygonTool::Dump(Polygon);
1550 //=======================================================================
1551 //function : IntCurveSurface_ComputeTransitions
1553 //=======================================================================
1554 void IntCurveSurface_ComputeTransitions(const TheCurve& curve,
1555 const Standard_Real w,
1556 IntCurveSurface_TransitionOnCurve& TransOnCurve,
1557 const TheSurface& surface,
1558 const Standard_Real u,
1559 const Standard_Real v) {
1561 gp_Vec NSurf,D1U,D1V;//TgCurv;
1563 Standard_Real CosDir;
1566 TheSurfaceTool::D1(surface,u,v,Psurf,D1U,D1V);
1567 NSurf = D1U.Crossed(D1V);
1568 TheCurveTool::D1(curve,w,Psurf,D1U);
1569 Standard_Real Norm = NSurf.Magnitude();
1570 if(Norm>TOLERANCE_ANGULAIRE) {
1572 CosDir = NSurf.Dot(D1U);
1574 if( -CosDir > TOLERANCE_ANGULAIRE) {
1575 //-- --Curve---> <----Surface----
1576 TransOnCurve = IntCurveSurface_In;
1578 else if(CosDir > TOLERANCE_ANGULAIRE) {
1579 //-- --Curve---> ----Surface-->
1580 TransOnCurve = IntCurveSurface_Out;
1583 TransOnCurve = IntCurveSurface_Tangent;
1587 TransOnCurve = IntCurveSurface_Tangent;
1590 //=======================================================================
1591 //function : IntCurveSurface_ComputeParamsOnQuadric
1593 //=======================================================================
1594 void IntCurveSurface_ComputeParamsOnQuadric(const TheSurface& surface,
1598 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1599 switch(SurfaceType) {
1602 ElSLib::Parameters(TheSurfaceTool::Plane(surface),P,u,v);
1605 case GeomAbs_Cylinder:
1607 ElSLib::Parameters(TheSurfaceTool::Cylinder(surface),P,u,v);
1612 ElSLib::Parameters(TheSurfaceTool::Cone(surface),P,u,v);
1615 case GeomAbs_Sphere:
1617 ElSLib::Parameters(TheSurfaceTool::Sphere(surface),P,u,v);
1625 //=======================================================================
1626 //function : EstLimForInfExtr
1627 //purpose : Estimation of limits for infinite surfaces
1628 //=======================================================================
1629 void EstLimForInfExtr(const gp_Lin& Line,
1630 const TheSurface& surface,
1631 const Standard_Boolean IsOffSurf,
1632 const Standard_Integer nbsu,
1633 const Standard_Boolean U1inf,
1634 const Standard_Boolean U2inf,
1635 const Standard_Boolean V1inf,
1636 const Standard_Boolean V2inf,
1637 Standard_Real& U1new,
1638 Standard_Real& U2new,
1639 Standard_Real& V1new,
1640 Standard_Real& V2new,
1641 Standard_Boolean& NoIntersection)
1645 NoIntersection = Standard_False;
1647 Handle(Adaptor3d_HSurface) aBasSurf;
1649 if(IsOffSurf) aBasSurf = TheSurfaceTool::BasisSurface(surface);
1653 if(IsOffSurf) aDirOfExt = aBasSurf->Direction();
1654 else aDirOfExt = TheSurfaceTool::Direction(surface);
1656 Standard_Real tolang = TOLERANCE_ANGULAIRE;
1658 if(aDirOfExt.IsParallel(Line.Direction(), tolang)) {
1659 NoIntersection = Standard_True;
1663 if((V1inf || V2inf) && !(U1inf || U2inf)) {
1665 Standard_Real vmin = RealLast(), vmax = -vmin;
1667 Standard_Real step = (U2new - U1new) / nbsu;
1668 Standard_Real u = U1new, v;
1670 Extrema_POnCurv aP1, aP2;
1673 for(i = 0; i <= nbsu; i++) {
1675 TheSurfaceTool::D0(surface, u, 0., aP);
1677 aL.SetDirection(aDirOfExt);
1679 Extrema_ExtElC aExtr(aL, Line, tolang);
1681 if(!aExtr.IsDone()) return;
1683 if(aExtr.IsParallel()) {
1684 NoIntersection = Standard_True;
1688 aExtr.Points(1, aP1, aP2);
1689 v = aP1.Parameter();
1690 vmin = Min(vmin, v);
1691 vmax = Max(vmax, v);
1697 vmin = vmin - Abs(vmin) - 10.;
1698 vmax = vmax + Abs(vmax) + 10.;
1700 V1new = Max(V1new, vmin);
1701 V2new = Min(V2new, vmax);
1704 else if(U1inf || U2inf) {
1706 Standard_Real umin = RealLast(), umax = -umin;
1707 Standard_Real u0 = Min(Max(0., U1new), U2new);
1708 Standard_Real v0 = Min(Max(0., V1new), V2new);
1710 TheSurfaceTool::D0(surface, u0, v0, aP);
1711 gp_Pln aRefPln(aP, aDirOfExt);
1713 Handle(Adaptor3d_HCurve) aBasCurv;
1715 if(IsOffSurf) aBasCurv = aBasSurf->BasisCurve();
1716 else aBasCurv = TheSurfaceTool::BasisCurve(surface);
1718 ProjLib_Plane Projector(aRefPln);
1720 Projector.Project(Line);
1722 if(!Projector.IsDone()) return;
1724 gp_Lin2d Line2d = Projector.Line();
1726 GeomAbs_CurveType aCurvTyp = aBasCurv->GetType();
1728 if(aCurvTyp == GeomAbs_Line) {
1730 Projector.Project(aBasCurv->Line());
1732 if(!Projector.IsDone()) return;
1734 gp_Lin2d aL2d = Projector.Line();
1736 IntAna2d_AnaIntersection anInter(Line2d, aL2d);
1738 if(!anInter.IsDone()) return;
1740 if(anInter.IsEmpty() || anInter.IdenticalElements() ||
1741 anInter.ParallelElements() ) {
1742 NoIntersection = Standard_True;
1746 const IntAna2d_IntPoint& anIntPnt = anInter.Point(1);
1747 umin = umax = anIntPnt.ParamOnSecond();
1749 else if(aCurvTyp == GeomAbs_Parabola || aCurvTyp == GeomAbs_Hyperbola) {
1751 IntAna2d_Conic aCon(Line2d);
1752 IntAna2d_AnaIntersection anInter;
1754 if(aCurvTyp == GeomAbs_Parabola) {
1755 Projector.Project(aBasCurv->Parabola());
1756 if(!Projector.IsDone()) return;
1758 const gp_Parab2d& aP2d = Projector.Parabola();
1760 anInter.Perform(aP2d, aCon);
1763 Projector.Project(aBasCurv->Hyperbola());
1764 if(!Projector.IsDone()) return;
1766 const gp_Hypr2d& aH2d = Projector.Hyperbola();
1767 anInter.Perform(aH2d, aCon);
1770 if(!anInter.IsDone()) return;
1772 if(anInter.IsEmpty()) {
1773 NoIntersection = Standard_True;
1777 Standard_Integer i, nbint = anInter.NbPoints();
1778 for(i = 1; i <= nbint; i++) {
1780 const IntAna2d_IntPoint& anIntPnt = anInter.Point(i);
1782 umin = Min(anIntPnt.ParamOnFirst(), umin);
1783 umax = Max(anIntPnt.ParamOnFirst(), umax);
1792 umin = umin - Abs(umin) - 10;
1793 umax = umax + Abs(umax) + 10;
1795 U1new = Max(U1new, umin);
1796 U2new = Min(U2new, umax);
1798 if(V1inf || V2inf) {
1799 EstLimForInfExtr(Line, surface, IsOffSurf, nbsu,
1800 Standard_False, Standard_False, V1inf, V2inf,
1801 U1new, U2new, V1new, V2new, NoIntersection);
1808 //=======================================================================
1809 //function : ProjectIntersectAndEstLim
1810 //purpose : project <theLine> and it's X-axe symmetric line to <thePln> and
1811 // intersect resulting curve with <theBasCurvProj>.
1812 // Then estimate max and min parameters of intersection on
1813 // <theBasCurvProj>.
1814 // Is called from EstLimForInfRevl()
1815 //=======================================================================
1816 void ProjectIntersectAndEstLim(const gp_Lin& theLine,
1817 const gp_Pln& thePln,
1818 const ProjLib_Plane& theBasCurvProj,
1819 Standard_Real& theVmin,
1820 Standard_Real& theVmax,
1821 Standard_Boolean& theNoIntersection)
1823 ProjLib_Plane aLineProj( thePln, theLine );
1824 if (!aLineProj.IsDone()) {
1827 << "Info: IntCurveSurface_Inter::ProjectIntersectAndEstLim(), !aLineProj.IsDone()"
1832 gp_Lin2d aLin2d = aLineProj.Line();
1834 // make a second line X-axe symmetric to the first one
1835 gp_Pnt2d aP1 = aLin2d.Location();
1836 gp_Pnt2d aP2 (aP1.XY() + aLin2d.Direction().XY());
1837 gp_Pnt2d aP1sym (aP1.X(), -aP1.Y());
1838 gp_Pnt2d aP2sym (aP2.X(), -aP2.Y());
1839 gp_Lin2d aLin2dsym (aP1sym, gp_Vec2d(aP1sym,aP2sym));
1841 // intersect projections
1842 IntAna2d_Conic aCon (aLin2d);
1843 IntAna2d_Conic aConSym (aLin2dsym);
1844 IntAna2d_AnaIntersection anIntersect;
1845 IntAna2d_AnaIntersection anIntersectSym;
1847 switch (theBasCurvProj.GetType()) {
1849 anIntersectSym.Perform(theBasCurvProj.Line(), aConSym);
1850 anIntersect.Perform(theBasCurvProj.Line(), aCon); break;
1851 case GeomAbs_Hyperbola:
1852 anIntersectSym.Perform(theBasCurvProj.Hyperbola(), aConSym);
1853 anIntersect.Perform(theBasCurvProj.Hyperbola(), aCon); break;
1854 case GeomAbs_Parabola:
1855 anIntersectSym.Perform(theBasCurvProj.Parabola(), aConSym);
1856 anIntersect.Perform(theBasCurvProj.Parabola(), aCon); break;
1858 return; // not infinite curve
1861 // retrieve params of intersections
1862 Standard_Integer aNbIntPnt = anIntersect.IsDone() ? anIntersect.NbPoints() : 0;
1863 Standard_Integer aNbIntPntSym = anIntersectSym.IsDone() ? anIntersectSym.NbPoints() : 0;
1864 Standard_Integer iPnt, aNbPnt = Max (aNbIntPnt, aNbIntPntSym);
1867 theNoIntersection = Standard_True;
1870 Standard_Real aParam;
1871 for (iPnt = 1; iPnt <= aNbPnt; iPnt++)
1873 if (iPnt <= aNbIntPnt) {
1874 const IntAna2d_IntPoint& aIntPnt = anIntersect.Point(iPnt);
1875 aParam = aIntPnt.ParamOnFirst();
1876 theVmin = Min (theVmin, aParam );
1877 theVmax = Max (theVmax, aParam );
1879 if (iPnt <= aNbIntPntSym) {
1880 const IntAna2d_IntPoint& aIntPnt = anIntersectSym.Point(iPnt);
1881 aParam = aIntPnt.ParamOnFirst();
1882 theVmin = Min (theVmin, aParam );
1883 theVmax = Max (theVmax, aParam );
1889 //=======================================================================
1890 //function : EstLimForInfRevl
1891 //purpose : Estimate V1 and V2 to pass to InternalPerform() if they are
1892 // infinite for Surface of Revolution
1893 // Algo: intersect projections of Line and basis curve on the
1894 // plane passing through revolution axe
1895 //=======================================================================
1896 void EstLimForInfRevl(const gp_Lin& Line,
1897 const TheSurface& surface,
1898 const Standard_Boolean U1inf,
1899 const Standard_Boolean U2inf,
1900 const Standard_Boolean V1inf,
1901 const Standard_Boolean V2inf,
1902 Standard_Real& U1new,
1903 Standard_Real& U2new,
1904 Standard_Real& V1new,
1905 Standard_Real& V2new,
1906 Standard_Boolean& NoIntersection)
1909 NoIntersection = Standard_False;
1911 if (U1inf || U2inf) {
1913 U1new = Max (0., U1new);
1915 U2new = Min (2 * M_PI, U2new);
1916 if (! V1inf && !V2inf) return;
1919 Handle(Adaptor3d_HCurve) aBasisCurve = TheSurfaceTool::BasisCurve(surface);
1920 gp_Ax1 aRevAx = TheSurfaceTool::AxeOfRevolution(surface);
1921 gp_Vec aXVec = aRevAx.Direction();
1922 Standard_Real aTolAng = Precision::Angular();
1924 // make plane to project a basis curve
1925 gp_Pnt O = aRevAx.Location();
1926 Standard_Real aU = 0.;
1927 gp_Pnt P = aBasisCurve->Value(aU);
1928 while (O.SquareDistance(P) <= Precision::PConfusion() ||
1929 aXVec.IsParallel( gp_Vec(O,P), aTolAng)) {
1931 P = aBasisCurve->Value(aU);
1933 // basis curve is a line coinciding with aXVec, P is any not on aXVec
1934 P = gp_Pnt(aU, aU+1, aU+2);
1936 gp_Vec aNVec = aXVec ^ gp_Vec(O,P);
1937 gp_Pln aPln (gp_Ax3 (O, aNVec ,aXVec));
1939 // project basic curve
1940 ProjLib_Plane aBasCurvProj(aPln);
1941 switch (aBasisCurve->GetType()) {
1943 aBasCurvProj.Project(aBasisCurve->Line ()); break;
1944 case GeomAbs_Hyperbola:
1945 aBasCurvProj.Project(aBasisCurve->Hyperbola()); break;
1946 case GeomAbs_Parabola:
1947 aBasCurvProj.Project(aBasisCurve->Parabola ()); break;
1949 return; // not infinite curve
1951 if (!aBasCurvProj.IsDone()) {
1953 cout << "Info: IntCurveSurface_Inter::EstLimForInfRevl(), !aBasCurvProj.IsDone()" << endl;
1957 // make plane to project Line
1958 if (aXVec.IsParallel( Line.Direction(), aTolAng)) {
1959 P = Line.Location();
1960 while (O.SquareDistance(P) <= Precision::PConfusion()) {
1962 P = gp_Pnt(aU, aU+1, aU+2); // any not on aXVec
1964 aNVec = aXVec ^ gp_Vec(O,P);
1966 aNVec = aXVec.Crossed( Line.Direction() );
1968 aPln = gp_Pln (gp_Ax3 (O, aNVec ,aXVec));
1970 // make a second plane perpendicular to the first one, rotated around aXVec
1971 gp_Pln aPlnPrp = aPln.Rotated (gp_Ax1 (O,aXVec), M_PI/2.);
1973 // project Line and it's X-axe symmetric one to plane and intersect
1974 // resulting curve with projection of Basic Curev
1975 Standard_Real aVmin = RealLast(), aVmax = -aVmin;
1976 Standard_Boolean aNoInt1 = Standard_False, aNoInt2 = Standard_False;
1977 ProjectIntersectAndEstLim (Line, aPln, aBasCurvProj, aVmin, aVmax, aNoInt1);
1978 ProjectIntersectAndEstLim (Line, aPlnPrp, aBasCurvProj, aVmin, aVmax, aNoInt2);
1980 if (aNoInt1 && aNoInt2) {
1981 NoIntersection = Standard_True;
1985 aVmin = aVmin - Abs(aVmin) - 10;
1986 aVmax = aVmax + Abs(aVmax) + 10;
1988 if (V1inf) V1new = aVmin;
1989 if (V2inf) V2new = aVmax;
1991 //cout << "EstLimForInfRevl: Vmin " << V1new << " Vmax " << V2new << endl;
1996 //=======================================================================
1997 //function : EstLimForInfOffs
1999 //=======================================================================
2000 void EstLimForInfOffs(const gp_Lin& Line,
2001 const TheSurface& surface,
2002 const Standard_Integer nbsu,
2003 const Standard_Boolean U1inf,
2004 const Standard_Boolean U2inf,
2005 const Standard_Boolean V1inf,
2006 const Standard_Boolean V2inf,
2007 Standard_Real& U1new,
2008 Standard_Real& U2new,
2009 Standard_Real& V1new,
2010 Standard_Real& V2new,
2011 Standard_Boolean& NoIntersection)
2014 NoIntersection = Standard_False;
2016 const Handle(Adaptor3d_HSurface)& aBasSurf = TheSurfaceTool::BasisSurface(surface);
2017 Standard_Real anOffVal = TheSurfaceTool::OffsetValue(surface);
2019 GeomAbs_SurfaceType aTypeOfBasSurf = aBasSurf->GetType();
2021 // case for plane, cylinder and cone - make equivalent surface;
2022 if(aTypeOfBasSurf == GeomAbs_Plane) {
2024 gp_Pln aPln = aBasSurf->Plane();
2025 gp_Vec aT = aPln.Position().XDirection()^aPln.Position().YDirection();
2028 IntAna_IntConicQuad LinPlane(Line,aPln,TOLERANCE_ANGULAIRE);
2030 if(!LinPlane.IsDone()) return;
2032 if(LinPlane.IsParallel() || LinPlane.IsInQuadric()) {
2034 NoIntersection = Standard_True;
2040 ElSLib::Parameters(aPln, LinPlane.Point(1), u, v);
2041 U1new = Max(U1new, u - 10.);
2042 U2new = Min(U2new, u + 10.);
2043 V1new = Max(V1new, v - 10.);
2044 V2new = Min(V2new, v + 10.);
2047 else if(aTypeOfBasSurf == GeomAbs_Cylinder) {
2049 gp_Cylinder aCyl = aBasSurf->Cylinder();
2051 Standard_Real aR = aCyl.Radius();
2052 gp_Ax3 anA = aCyl.Position();
2059 if ( aR >= TOLTANGENCY ) {
2062 else if ( aR <= -TOLTANGENCY ){
2063 anA.Rotate(gp_Ax1(anA.Location(), anA.Direction()), M_PI);
2064 aCyl.SetPosition(anA);
2065 // modified by NIZHNY-MKK Mon Oct 3 17:37:54 2005
2066 // aCyl.SetRadius(Abs(aR));
2067 aCyl.SetRadius(-aR);
2071 NoIntersection = Standard_True;
2076 IntAna_IntConicQuad LinCylinder(Line, aCyl);
2078 if(!LinCylinder.IsDone()) return;
2080 if(LinCylinder.IsParallel() || LinCylinder.IsInQuadric()) {
2082 NoIntersection = Standard_True;
2087 Standard_Integer i, nbp = LinCylinder.NbPoints();
2088 Standard_Real vmin = RealLast(), vmax = -vmin, u, v;
2090 for(i = 1; i <= nbp; i++) {
2092 ElSLib::Parameters(aCyl, LinCylinder.Point(i), u, v);
2093 vmin = Min(vmin, v);
2094 vmax = Max(vmax, v);
2098 V1new = Max(V1new, vmin - Abs(vmin) - 10.);
2099 V2new = Min(V2new, vmax + Abs(vmax) + 10.);
2102 else if(aTypeOfBasSurf == GeomAbs_Cone) {
2104 gp_Cone aCon = aBasSurf->Cone();
2105 Standard_Real anAng = aCon.SemiAngle();
2106 Standard_Real aR = aCon.RefRadius() + anOffVal * Cos(anAng);
2107 gp_Ax3 anA = aCon.Position();
2110 gp_Vec aZ( anA.Direction());
2111 aZ *= - anOffVal * Sin(anAng);
2113 aCon.SetPosition(anA);
2115 aCon.SetSemiAngle(anAng);
2124 IntAna_IntConicQuad LinCone(Line, aCon);
2126 if(!LinCone.IsDone()) return;
2128 if(LinCone.IsParallel() || LinCone.IsInQuadric()) {
2130 NoIntersection = Standard_True;
2135 Standard_Integer i, nbp = LinCone.NbPoints();
2136 Standard_Real vmin = RealLast(), vmax = -vmin, u, v;
2138 for(i = 1; i <= nbp; i++) {
2140 ElSLib::Parameters(aCon, LinCone.Point(i), u, v);
2141 vmin = Min(vmin, v);
2142 vmax = Max(vmax, v);
2146 V1new = Max(V1new, vmin - Abs(vmin) - 10.);
2147 V2new = Min(V2new, vmax + Abs(vmax) + 10.);
2150 else if(aTypeOfBasSurf == GeomAbs_SurfaceOfExtrusion) {
2152 Standard_Real anU1 = U1new, anU2 = U2new;
2154 EstLimForInfExtr(Line, surface, Standard_True, nbsu,
2155 U1inf, U2inf, V1inf, V2inf,
2156 U1new, U2new, V1new, V2new, NoIntersection);
2158 if(NoIntersection) return;
2160 if(U1inf || U2inf) {
2162 GeomAbs_CurveType aBasCurvType = aBasSurf->BasisCurve()->GetType();
2163 if(aBasCurvType == GeomAbs_Line) {
2164 U1new = Max(anU1, -1.e10);
2165 U2new = Min(anU2, 1.e10);
2167 else if(aBasCurvType == GeomAbs_Parabola) {
2168 gp_Parab aPrb = aBasSurf->BasisCurve()->Parabola();
2169 Standard_Real aF = aPrb.Focal();
2170 Standard_Real dU = 2.e5 * Sqrt(aF);
2171 U1new = Max(anU1, -dU);
2172 U2new = Min(anU2, dU);
2174 else if(aBasCurvType == GeomAbs_Hyperbola) {
2175 U1new = Max(anU1, -30.);
2176 U2new = Min(anU2, 30.);
2179 U1new = Max(anU1, -1.e10);
2180 U2new = Min(anU2, 1.e10);
2186 else if(aTypeOfBasSurf == GeomAbs_SurfaceOfRevolution) {
2188 GeomAbs_CurveType aBasCurvType = aBasSurf->BasisCurve()->GetType();
2189 if(aBasCurvType == GeomAbs_Line) {
2190 V1new = Max(V1new, -1.e10);
2191 V2new = Min(V2new, 1.e10);
2193 else if(aBasCurvType == GeomAbs_Parabola) {
2194 gp_Parab aPrb = aBasSurf->BasisCurve()->Parabola();
2195 Standard_Real aF = aPrb.Focal();
2196 Standard_Real dV = 2.e5 * Sqrt(aF);
2197 V1new = Max(V1new, -dV);
2198 V2new = Min(V2new, dV);
2200 else if(aBasCurvType == GeomAbs_Hyperbola) {
2201 V1new = Max(V1new, -30.);
2202 V2new = Min(V2new, 30.);
2205 V1new = Max(V1new, -1.e10);
2206 V2new = Min(V2new, 1.e10);
2212 V1new = Max(V1new, -1.e10);
2213 V2new = Min(V2new, 1.e10);
2216 //=======================================================================
2217 //function : EstLimForInfSurf
2219 //=======================================================================
2220 void EstLimForInfSurf(Standard_Real& U1new,
2221 Standard_Real& U2new,
2222 Standard_Real& V1new,
2223 Standard_Real& V2new)
2225 U1new = Max(U1new, -1.e10);
2226 U2new = Min(U2new, 1.e10);
2227 V1new = Max(V1new, -1.e10);
2228 V2new = Min(V2new, 1.e10);