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 Standard_Boolean DoTrim(const TheCurve& curve,
154 const TheSurface& surface);
156 void DoCurve(const TheCurve& curve,
160 void DoCommon(TColStd_Array1OfReal& Coords,
162 Standard_Real& Cmax);
165 void DoCommonBox(const Bnd_Box& boxSurface,
166 const Bnd_Box& boxCurve,
167 TColStd_Array1OfReal& X,
168 TColStd_Array1OfReal& Y,
169 TColStd_Array1OfReal& Z);
172 void ProjectIntersectAndEstLim(const gp_Lin& theLine,
173 const gp_Pln& thePln,
174 const ProjLib_Plane& theBasCurvProj,
175 Standard_Real& theVmin,
176 Standard_Real& theVmax,
177 Standard_Boolean& theNoIntersection);
179 //=======================================================================
180 //function : IntCurveSurface_Inter
182 //=======================================================================
183 IntCurveSurface_Inter::IntCurveSurface_Inter()
186 //=======================================================================
187 //function : DoSurface
189 //=======================================================================
190 void IntCurveSurface_Inter::DoSurface(const TheSurface& surface,
191 const Standard_Real u0,
192 const Standard_Real u1,
193 const Standard_Real v0,
194 const Standard_Real v1,
195 TColgp_Array2OfPnt& pntsOnSurface,
199 Standard_Integer iU = 0, iV = 0;
200 Standard_Real U = 0., V = 0;
201 // modified by NIZHNY-MKK Mon Oct 3 17:38:45 2005
202 // Standard_Real dU = fabs(u1-u0)/50., dV = fabs(v1-v0)/50.;
203 Standard_Real dU = (u1-u0)/50., dV = (v1-v0)/50.;
206 for(iU = 0; iU < 50; iU++) {
213 U = u0 + dU * ((Standard_Real)iU);
215 for(iV = 0; iV < 50; iV++) {
222 V = v0 + dV * ((Standard_Real)iV);
224 TheSurfaceTool::D0(surface,U,V,aPnt);
225 boxSurface.Add(aPnt);
226 pntsOnSurface.SetValue(iU+1,iV+1,aPnt);
229 Standard_Real Ures = TheSurfaceTool::UResolution(surface,dU);
230 Standard_Real Vres = TheSurfaceTool::VResolution(surface,dV);
231 gap = Max(Ures,Vres);
234 //=======================================================================
237 //=======================================================================
238 void DoCurve(const TheCurve& curve,
241 Standard_Real CF = TheCurveTool::FirstParameter(curve);
242 Standard_Real CL = TheCurveTool::LastParameter(curve);
243 Standard_Real C = 0., dC = fabs(CL-CF)/50.;
244 Standard_Integer iC = 0;
247 for(iC = 0; iC < 50; iC++) {
253 C = CF + dC *((Standard_Real)iC);
255 TheCurveTool::D0(curve,C,aPnt);
260 //=======================================================================
261 //function : DoCommon
263 //=======================================================================
264 void DoCommon(TColStd_Array1OfReal& Coords,
268 Standard_Integer i = 0, j = 0;
269 for(i = 1; i <= 4; i++) {
270 for(j = i+1; j <= 4; j++) {
271 if(Coords(j) > Coords(i)) {
272 Standard_Real c = Coords(i);
273 Coords.SetValue(i,Coords(j));
274 Coords.SetValue(j,c);
282 //=======================================================================
283 //function : DoCommonBox
285 //=======================================================================
286 static void DoCommonBox(const Bnd_Box& boxSurface,
287 const Bnd_Box& boxCurve,
288 TColStd_Array1OfReal& X,
289 TColStd_Array1OfReal& Y,
290 TColStd_Array1OfReal& Z)
292 Standard_Real SBXmin = 0., SBYmin = 0., SBZmin = 0.;
293 Standard_Real SBXmax = 0., SBYmax = 0., SBZmax = 0.;
294 boxSurface.Get(SBXmin,SBYmin,SBZmin,SBXmax,SBYmax,SBZmax);
296 Standard_Real CBXmin = 0., CBYmin = 0., CBZmin = 0.;
297 Standard_Real CBXmax = 0., CBYmax = 0., CBZmax = 0.;
298 boxCurve.Get(CBXmin,CBYmin,CBZmin,CBXmax,CBYmax,CBZmax);
300 TColStd_Array1OfReal Coord(1,4);
302 Coord(1) = SBXmin; Coord(2) = SBXmax; Coord(3) = CBXmin; Coord(4) = CBXmax;
303 Standard_Real CXmin = SBXmin, CXmax = SBXmax;
304 DoCommon(Coord,CXmin,CXmax);
306 Coord(1) = SBYmin; Coord(2) = SBYmax; Coord(3) = CBYmin; Coord(4) = CBYmax;
307 Standard_Real CYmin = SBYmin, CYmax = SBYmax;
308 DoCommon(Coord,CYmin,CYmax);
310 Coord(1) = SBZmin; Coord(2) = SBZmax; Coord(3) = CBZmin; Coord(4) = CBZmax;
311 Standard_Real CZmin = SBZmin, CZmax = SBZmax;
312 DoCommon(Coord,CZmin,CZmax);
314 X.SetValue(1,CXmin); X.SetValue(2,CXmax);
315 Y.SetValue(1,CYmin); Y.SetValue(2,CYmax);
316 Z.SetValue(1,CZmin); Z.SetValue(2,CZmax);
319 //=======================================================================
320 //function : DoNewBounds
322 //=======================================================================
323 void IntCurveSurface_Inter::DoNewBounds(
324 const TheSurface& surface,
325 const Standard_Real u0,
326 const Standard_Real u1,
327 const Standard_Real v0,
328 const Standard_Real v1,
329 const TColgp_Array2OfPnt& pntsOnSurface,
330 const TColStd_Array1OfReal& X,
331 const TColStd_Array1OfReal& Y,
332 const TColStd_Array1OfReal& Z,
333 TColStd_Array1OfReal& Bounds)
335 Bounds.SetValue(1,u0);
336 Bounds.SetValue(2,u1);
337 Bounds.SetValue(3,v0);
338 Bounds.SetValue(4,v1);
340 Standard_Boolean isUClosed = (TheSurfaceTool::IsUClosed(surface) || TheSurfaceTool::IsUPeriodic(surface));
341 Standard_Boolean isVClosed = (TheSurfaceTool::IsVClosed(surface) || TheSurfaceTool::IsVPeriodic(surface));
342 Standard_Boolean checkU = (isUClosed) ? Standard_False : Standard_True;
343 Standard_Boolean checkV = (isVClosed) ? Standard_False : Standard_True;
345 Standard_Integer i = 0, j = 0, k = 0, iU = 0, iV = 0;
346 Standard_Integer iUmin = 50, iVmin = 50, iUmax = 1, iVmax = 1;
348 for(i = 1; i <= 2; i++) {
349 for(j = 1; j <= 2; j++) {
350 for(k = 1; k <= 2; k++) {
351 gp_Pnt aPoint(X(i),Y(j),Z(k));
352 Standard_Real DistMin = 1.e+100;
353 Standard_Integer diU = 0, diV = 0;
354 for(iU = 1; iU <= 50; iU++) {
355 for(iV = 1; iV <= 50; iV++) {
356 const gp_Pnt aP = pntsOnSurface.Value(iU,iV);
357 Standard_Real dist = aP.SquareDistance(aPoint);
365 if(diU > 0 && diU < iUmin) iUmin = diU;
366 if(diU > 0 && diU > iUmax) iUmax = diU;
367 if(diV > 0 && diV < iVmin) iVmin = diV;
368 if(diV > 0 && diV > iVmax) iVmax = diV;
373 // modified by NIZHNY-MKK Mon Oct 3 17:38:43 2005
374 // Standard_Real dU = fabs(u1-u0)/50., dV = fabs(v1-v0)/50.;
375 Standard_Real dU = (u1-u0)/50., dV = (v1-v0)/50.;
377 Standard_Real USmin = u0 + dU * ((Standard_Real)(iUmin - 1));
378 Standard_Real USmax = u0 + dU * ((Standard_Real)(iUmax - 1));
379 Standard_Real VSmin = v0 + dV * ((Standard_Real)(iVmin - 1));
380 Standard_Real VSmax = v0 + dV * ((Standard_Real)(iVmax - 1));
383 Standard_Real tmp = USmax;
388 Standard_Real tmp = VSmax;
394 if(USmin < u0) USmin = u0;
396 if(USmax > u1) USmax = u1;
398 if(VSmin < v0) VSmin = v0;
400 if(VSmax > v1) VSmax = v1;
403 Bounds.SetValue(1,USmin);
404 Bounds.SetValue(2,USmax);
407 Bounds.SetValue(3,VSmin);
408 Bounds.SetValue(4,VSmax);
412 //=======================================================================
414 //purpose : Decompose la surface si besoin est
415 //=======================================================================
416 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
417 const TheSurface& surface) {
419 done = Standard_True;
420 Standard_Integer NbUOnS = TheSurfaceTool::NbUIntervals(surface,GeomAbs_C2);
421 Standard_Integer NbVOnS = TheSurfaceTool::NbVIntervals(surface,GeomAbs_C2);
422 Standard_Integer NbOnC = TheCurveTool::NbIntervals(curve,GeomAbs_C2);
423 Standard_Real U0,U1,V0,V1;
426 TColStd_Array1OfReal TabU(1,NbUOnS+1);
427 TheSurfaceTool::UIntervals(surface,TabU,GeomAbs_C2);
428 for(Standard_Integer iu = 1;iu <= NbUOnS; iu++) {
430 U1 = TabU.Value(iu+1);
432 TColStd_Array1OfReal TabV(1,NbVOnS+1);
433 TheSurfaceTool::VIntervals(surface,TabV,GeomAbs_C2);
434 for(Standard_Integer iv = 1;iv <= NbVOnS; iv++) {
436 V1 = TabV.Value(iv+1);
437 Perform(curve,surface,U0,V0,U1,V1);
440 else { //------ composite en U non composite en V
441 V0 = TheSurfaceTool::FirstVParameter(surface);
442 V1 = TheSurfaceTool::LastVParameter(surface);
443 Perform(curve,surface,U0,V0,U1,V1);
447 else if(NbVOnS > 1) { //---------- non composite en U composite en V
448 U0 = TheSurfaceTool::FirstUParameter(surface);
449 U1 = TheSurfaceTool::LastUParameter(surface);
450 TColStd_Array1OfReal TabV(1,NbVOnS+1);
451 TheSurfaceTool::VIntervals(surface,TabV,GeomAbs_C2);
452 for(Standard_Integer iv = 1;iv <= NbVOnS; iv++) {
454 V1 = TabV.Value(iv+1);
455 Perform(curve,surface,U0,V0,U1,V1);
459 V0 = TheSurfaceTool::FirstVParameter(surface);
460 V1 = TheSurfaceTool::LastVParameter(surface);
461 U0 = TheSurfaceTool::FirstUParameter(surface);
462 U1 = TheSurfaceTool::LastUParameter(surface);
465 Standard_Boolean doTrim = DoTrim(curve,surface);
467 TColgp_Array2OfPnt aPS(1,50,1,50);
469 Standard_Real g = 1.e-7;
470 DoSurface(surface,U0,U1,V0,V1,aPS,SB,g);
474 TColStd_Array1OfReal X(1,2), Y(1,2), Z(1,2);
475 DoCommonBox(SB,CB,X,Y,Z);
476 TColStd_Array1OfReal B(1,4);
477 DoNewBounds(surface,U0,U1,V0,V1,aPS,X,Y,Z,B);
478 U0 = B(1); U1 = B(2); V0 = B(3); V1 = B(4);
483 //-- jgv patch (from)
484 //Computing of local bounds
485 Standard_Real LocalU0 = U0, LocalU1 = U1, LocalV0 = V0, LocalV1 = V1;
486 Standard_Real Umin = RealLast(), Vmin = RealLast(), Umax = RealFirst(), Vmax = RealFirst();
488 Standard_Integer i, j, k;
489 //Making GeomAdaptor_Curve
490 Standard_Real f = TheCurveTool::FirstParameter(curve);
491 Standard_Real l = TheCurveTool::LastParameter(curve);
492 GeomAbs_CurveType CurveType = TheCurveTool::GetType(curve);
493 Handle(Geom_Curve) theCurve;
497 theCurve = new Geom_Line( TheCurveTool::Line(curve) );
500 theCurve = new Geom_Circle( TheCurveTool::Circle(curve) );
502 case GeomAbs_Ellipse:
503 theCurve = new Geom_Ellipse( TheCurveTool::Ellipse(curve) );
505 case GeomAbs_Hyperbola:
506 theCurve = new Geom_Hyperbola( TheCurveTool::Hyperbola(curve) );
508 case GeomAbs_Parabola:
509 theCurve = new Geom_Parabola( TheCurveTool::Parabola(curve) );
511 case GeomAbs_BezierCurve:
512 theCurve = TheCurveTool::Bezier(curve);
514 case GeomAbs_BSplineCurve:
515 theCurve = TheCurveTool::BSpline(curve);
518 if (!theCurve.IsNull())
520 GeomAdaptor_Curve GACurve( theCurve, f, l );
521 BndLib_Add3dCurve::Add( GACurve, Precision::Confusion(), CurveBox );
525 Standard_Integer nbp = TheCurveTool::NbSamples(curve,f,l);
526 Standard_Real delta = (f-l)/nbp;
527 for (i = 0; i <= nbp; i++)
529 gp_Pnt aPnt = TheCurveTool::Value(curve, f + i*delta);
533 Standard_Real X[2], Y[2], Z[2];
534 CurveBox.Get( X[0], Y[0], Z[0], X[1], Y[1], Z[1] );
535 Standard_Real Ures = TheSurfaceTool::UResolution(surface, Precision::Confusion());
536 Standard_Real Vres = TheSurfaceTool::VResolution(surface, Precision::Confusion());
537 //Making GeomAdaptor_Surface
538 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
539 Handle(Geom_Surface) theSurface;
543 theSurface = new Geom_Plane( TheSurfaceTool::Plane(surface) );
545 case GeomAbs_Cylinder:
546 theSurface = new Geom_CylindricalSurface( TheSurfaceTool::Cylinder(surface) );
549 theSurface = new Geom_ConicalSurface( TheSurfaceTool::Cone(surface) );
552 theSurface = new Geom_ToroidalSurface( TheSurfaceTool::Torus(surface) );
555 theSurface = new Geom_SphericalSurface( TheSurfaceTool::Sphere(surface) );
557 case GeomAbs_BezierSurface:
558 theSurface = TheSurfaceTool::Bezier(surface);
560 case GeomAbs_BSplineSurface:
561 theSurface = TheSurfaceTool::BSpline(surface);
563 case GeomAbs_SurfaceOfRevolution:
565 gp_Ax1 Axis = TheSurfaceTool::AxeOfRevolution(surface);
566 Handle(Adaptor3d_HCurve) AdBC = TheSurfaceTool::BasisCurve(surface);
567 Handle(Geom_Curve) BC = GetCurve(AdBC);
569 theSurface = new Geom_SurfaceOfRevolution( BC, Axis );
572 case GeomAbs_SurfaceOfExtrusion:
574 gp_Dir Direction = TheSurfaceTool::Direction(surface);
575 Handle(Adaptor3d_HCurve) AdBC = TheSurfaceTool::BasisCurve(surface);
576 Handle(Geom_Curve) BC = GetCurve(AdBC);
578 theSurface = new Geom_SurfaceOfLinearExtrusion( BC, Direction );
581 case GeomAbs_OffsetSurface:
583 Standard_Real OffsetValue = TheSurfaceTool::OffsetValue(surface);
584 Handle(Adaptor3d_HSurface) AdBS = TheSurfaceTool::BasisSurface(surface);
585 Handle(Geom_Surface) BS = GetSurface(AdBS);
587 theSurface = new Geom_OffsetSurface( BS, OffsetValue );
591 if (!theSurface.IsNull())
593 GeomAdaptor_Surface GASurface( theSurface );
594 Extrema_ExtPS Projector;
595 Projector.Initialize( GASurface, U0, U1, V0, V1, Ures, Vres );
596 for (i = 0; i <= 1; i++)
597 for (j = 0; j <= 1; j++)
598 for (k = 0; k <= 1; k++)
600 gp_Pnt aPoint( X[i], Y[j], Z[k] );
601 Projector.Perform( aPoint );
602 if (Projector.IsDone() && Projector.NbExt() > 0)
604 Standard_Real mindist = RealLast();
605 Standard_Integer minind, ind;
606 for (ind = 1; ind <= Projector.NbExt(); ind++)
608 Standard_Real dist = Projector.Value(ind);
615 Extrema_POnSurf pons = Projector.Point(minind);
617 pons.Parameter( U, V );
618 if (U < Umin) Umin = U;
619 if (U > Umax) Umax = U;
620 if (V < Vmin) Vmin = V;
621 if (V > Vmax) Vmax = V;
624 Umin -= Ures; Umax += Ures; Vmin -= Vres; Vmax += Vres;
625 if (Umin > U0 && Umin <= U1) LocalU0 = Umin;
626 if (Umax < U1 && Umax >= U0) LocalU1 = Umax;
627 if (Vmin > V0 && Vmin <= V1) LocalV0 = Vmin;
628 if (Vmax < V1 && Vmax >= V0) LocalV1 = Vmax;
629 U0 = LocalU0; U1 = LocalU1; V0 = LocalV0; V1 = LocalV1;
633 Perform(curve,surface,U0,V0,U1,V1);
636 //=======================================================================
639 //=======================================================================
640 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
641 const TheSurface& surface,
642 const Standard_Real U1,const Standard_Real V1,
643 const Standard_Real U2,const Standard_Real V2) {
645 GeomAbs_CurveType CurveType = TheCurveTool::GetType(curve);
650 PerformConicSurf(TheCurveTool::Line(curve),curve,surface,U1,V1,U2,V2);
655 PerformConicSurf(TheCurveTool::Circle(curve),curve,surface,U1,V1,U2,V2);
658 case GeomAbs_Ellipse:
660 PerformConicSurf(TheCurveTool::Ellipse(curve),curve,surface,U1,V1,U2,V2);
663 case GeomAbs_Parabola:
665 PerformConicSurf(TheCurveTool::Parabola(curve),curve,surface,U1,V1,U2,V2);
668 case GeomAbs_Hyperbola:
670 PerformConicSurf(TheCurveTool::Hyperbola(curve),curve,surface,U1,V1,U2,V2);
675 Standard_Integer nbIntervalsOnCurve = TheCurveTool::NbIntervals(curve,GeomAbs_C2);
676 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
677 if( (SurfaceType != GeomAbs_Plane)
678 && (SurfaceType != GeomAbs_Cylinder)
679 && (SurfaceType != GeomAbs_Cone)
680 && (SurfaceType != GeomAbs_Sphere)) {
682 if(nbIntervalsOnCurve > 1) {
683 TColStd_Array1OfReal TabW(1,nbIntervalsOnCurve+1);
684 TheCurveTool::Intervals(curve,TabW,GeomAbs_C2);
685 for(Standard_Integer i = 1; i<=nbIntervalsOnCurve; i++) {
688 u2 = TabW.Value(i+1);
690 Handle(TColStd_HArray1OfReal) aPars;
691 Standard_Real defl = 0.1;
692 Standard_Integer NbMin = 10;
693 TheCurveTool::SamplePars(curve, u1, u2, defl, NbMin, aPars);
695 // IntCurveSurface_ThePolygon polygon(curve,u1,u2,TheCurveTool::NbSamples(curve,u1,u2));
696 IntCurveSurface_ThePolygon polygon(curve, aPars->Array1());
697 InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
702 u1 = TheCurveTool::FirstParameter(curve);
703 u2 = TheCurveTool::LastParameter(curve);
705 Handle(TColStd_HArray1OfReal) aPars;
706 Standard_Real defl = 0.1;
707 Standard_Integer NbMin = 10;
708 TheCurveTool::SamplePars(curve, u1, u2, defl, NbMin, aPars);
710 // IntCurveSurface_ThePolygon polygon(curve,TheCurveTool::NbSamples(curve,u1,u2));
711 IntCurveSurface_ThePolygon polygon(curve, aPars->Array1());
712 InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
715 else { //-- la surface est une quadrique
716 InternalPerformCurveQuadric(curve,surface);
721 //=======================================================================
724 //=======================================================================
725 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
726 const IntCurveSurface_ThePolygon& polygon,
727 const TheSurface& surface) {
729 done = Standard_True;
730 Standard_Real u1,v1,u2,v2;
731 u1 = TheSurfaceTool::FirstUParameter(surface);
732 v1 = TheSurfaceTool::FirstVParameter(surface);
733 u2 = TheSurfaceTool::LastUParameter(surface);
734 v2 = TheSurfaceTool::LastVParameter(surface);
735 Standard_Integer nbsu,nbsv;
736 nbsu = TheSurfaceTool::NbSamplesU(surface,u1,u2);
737 nbsv = TheSurfaceTool::NbSamplesV(surface,v1,v2);
740 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,u1,v1,u2,v2);
741 Perform(curve,polygon,surface,polyhedron);
743 //=======================================================================
746 //=======================================================================
747 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
748 const TheSurface& surface,
749 const IntCurveSurface_ThePolyhedron& polyhedron) {
751 done = Standard_True;
752 Standard_Real u1 = TheCurveTool::FirstParameter(curve);
753 Standard_Real u2 = TheCurveTool::LastParameter(curve);
754 IntCurveSurface_ThePolygon polygon(curve,TheCurveTool::NbSamples(curve,u1,u2));
755 Perform(curve,polygon,surface,polyhedron);
757 //=======================================================================
760 //=======================================================================
761 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
762 const IntCurveSurface_ThePolygon& polygon,
763 const TheSurface& surface,
764 const IntCurveSurface_ThePolyhedron& polyhedron) {
766 done = Standard_True;
767 Standard_Real u1,v1,u2,v2;
768 u1 = TheSurfaceTool::FirstUParameter(surface);
769 v1 = TheSurfaceTool::FirstVParameter(surface);
770 u2 = TheSurfaceTool::LastUParameter(surface);
771 v2 = TheSurfaceTool::LastVParameter(surface);
772 InternalPerform(curve,polygon,surface,polyhedron,u1,v1,u2,v2);
775 //=======================================================================
778 //=======================================================================
779 void IntCurveSurface_Inter::Perform(const TheCurve& curve,
780 const IntCurveSurface_ThePolygon& polygon,
781 const TheSurface& surface,
782 const IntCurveSurface_ThePolyhedron& polyhedron,
783 Bnd_BoundSortBox& BndBSB) {
785 done = Standard_True;
786 Standard_Real u1,v1,u2,v2;
787 u1 = TheSurfaceTool::FirstUParameter(surface);
788 v1 = TheSurfaceTool::FirstVParameter(surface);
789 u2 = TheSurfaceTool::LastUParameter(surface);
790 v2 = TheSurfaceTool::LastVParameter(surface);
791 InternalPerform(curve,polygon,surface,polyhedron,u1,v1,u2,v2,BndBSB);
793 //=======================================================================
794 //function : InternalPerform
795 //purpose : C a l c u l d u p o i n t a p p r o c h e
796 //== p u i s d u p o i n t E x a c t
797 //=======================================================================
798 void IntCurveSurface_Inter::InternalPerform(const TheCurve& curve,
799 const IntCurveSurface_ThePolygon& polygon,
800 const TheSurface& surface,
801 const IntCurveSurface_ThePolyhedron& polyhedron,
802 const Standard_Real u0,
803 const Standard_Real v0,
804 const Standard_Real u1,
805 const Standard_Real v1,
806 Bnd_BoundSortBox& BSB) {
807 IntCurveSurface_TheInterference interference(polygon,polyhedron,BSB);
808 IntCurveSurface_TheCSFunction theicsfunction(surface,curve);
809 IntCurveSurface_TheExactInter intersectionExacte(theicsfunction,TOLTANGENCY);
810 math_FunctionSetRoot rsnld(intersectionExacte.Function());
812 // Standard_Real u,v,w,winit;
815 Standard_Real winf = polygon.InfParameter();
816 Standard_Real wsup = polygon.SupParameter();
817 Standard_Integer NbSectionPoints = interference.NbSectionPoints();
818 Standard_Integer NbTangentZones = interference.NbTangentZones();
821 //-- Les interferences renvoient parfois de nombreuses fois (>20) les memes points
823 Standard_Integer i,NbStartPoints=NbSectionPoints;
824 for(i=1; i<= NbTangentZones; i++) {
825 const Intf_TangentZone& TZ = interference.ZoneValue(i);
826 Standard_Integer nbpnts = TZ.NumberOfPoints();
827 NbStartPoints+=nbpnts;
831 Standard_Real *TabU = new Standard_Real [NbStartPoints+1];
832 Standard_Real *TabV = new Standard_Real [NbStartPoints+1];
833 Standard_Real *TabW = new Standard_Real [NbStartPoints+1];
834 Standard_Integer IndexPoint=0;
836 for(i=1; i<= NbSectionPoints; i++) {
837 const Intf_SectionPoint& SP = interference.PntValue(i);
838 SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
844 for(i=1; i<= NbTangentZones; i++) {
845 const Intf_TangentZone& TZ = interference.ZoneValue(i);
846 Standard_Integer nbpnts = TZ.NumberOfPoints();
847 for(Standard_Integer j=1; j<=nbpnts; j++) {
848 const Intf_SectionPoint& SP = TZ.GetPoint(j);
849 SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
858 Standard_Real su=0,sv=0,sw=0,ptol;
859 ptol = 10*Precision::PConfusion();
861 //-- Tri suivant la variable W
862 Standard_Boolean Triok;
865 Standard_Integer im1;
866 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
867 if(TabW[i] < TabW[im1]) {
868 Standard_Real t=TabW[i]; TabW[i]=TabW[im1]; TabW[im1]=t;
869 t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
870 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
871 Triok=Standard_False;
875 while(Triok==Standard_False);
877 //-- On trie pour des meme W suivant U
880 Standard_Integer im1;
881 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
882 // modified by NIZHNY-MKK Mon Oct 3 17:38:49 2005
883 // if(Abs(TabW[i]-TabW[im1])<ptol) {
884 if((TabW[i]-TabW[im1])<ptol) {
886 if(TabU[i] < TabU[im1]) {
887 Standard_Real t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
888 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
889 Triok=Standard_False;
894 while(Triok==Standard_False);
896 //-- On trie pour des meme U et W suivant V
899 Standard_Integer im1;
900 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
901 // modified by NIZHNY-MKK Mon Oct 3 17:38:52 2005
902 // if((Abs(TabW[i]-TabW[im1])<ptol) && (Abs(TabU[i]-TabU[im1])<ptol)) {
903 if(((TabW[i]-TabW[im1])<ptol) && ((TabU[i]-TabU[im1])<ptol)) {
905 if(TabV[i] < TabV[im1]) {
906 Standard_Real t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
907 Triok=Standard_False;
912 while(Triok==Standard_False);
915 for(i=0;i<NbStartPoints; i++) {
916 u=TabU[i]; v=TabV[i]; w=TabW[i];
920 if(Abs(u-su)>ptol || Abs(v-sv)>ptol || Abs(w-sw)>ptol) {
921 intersectionExacte.Perform(u,v,w,rsnld,u0,u1,v0,v1,winf,wsup);
922 if(intersectionExacte.IsDone()) {
923 if(!intersectionExacte.IsEmpty()) {
924 P=intersectionExacte.Point();
925 w=intersectionExacte.ParameterOnCurve();
926 intersectionExacte.ParameterOnSurface(u,v);
927 AppendPoint(curve,w,surface,u,v);
931 su=TabU[i]; sv=TabV[i]; sw=TabW[i];
939 //=======================================================================
940 //function : InternalPerform
942 //=======================================================================
943 void IntCurveSurface_Inter::InternalPerform(const TheCurve& curve,
944 const IntCurveSurface_ThePolygon& polygon,
945 const TheSurface& surface,
946 const IntCurveSurface_ThePolyhedron& polyhedron,
947 const Standard_Real u0,
948 const Standard_Real v0,
949 const Standard_Real u1,
950 const Standard_Real v1) {
951 IntCurveSurface_TheInterference interference(polygon,polyhedron);
952 IntCurveSurface_TheCSFunction theicsfunction(surface,curve);
953 IntCurveSurface_TheExactInter intersectionExacte(theicsfunction,TOLTANGENCY);
954 math_FunctionSetRoot rsnld(intersectionExacte.Function());
956 // Standard_Real u,v,w,winit;
959 Standard_Real winf = polygon.InfParameter();
960 Standard_Real wsup = polygon.SupParameter();
961 Standard_Integer NbSectionPoints = interference.NbSectionPoints();
962 Standard_Integer NbTangentZones = interference.NbTangentZones();
965 //-- Les interferences renvoient parfois de nombreuses fois (>20) les memes points
967 Standard_Integer i,NbStartPoints=NbSectionPoints;
968 for(i=1; i<= NbTangentZones; i++) {
969 const Intf_TangentZone& TZ = interference.ZoneValue(i);
970 Standard_Integer nbpnts = TZ.NumberOfPoints();
971 NbStartPoints+=nbpnts;
975 Standard_Real *TabU = new Standard_Real [NbStartPoints+1];
976 Standard_Real *TabV = new Standard_Real [NbStartPoints+1];
977 Standard_Real *TabW = new Standard_Real [NbStartPoints+1];
978 Standard_Integer IndexPoint=0;
980 for(i=1; i<= NbSectionPoints; i++) {
981 const Intf_SectionPoint& SP = interference.PntValue(i);
982 SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
988 for(i=1; i<= NbTangentZones; i++) {
989 const Intf_TangentZone& TZ = interference.ZoneValue(i);
990 Standard_Integer nbpnts = TZ.NumberOfPoints();
991 for(Standard_Integer j=1; j<=nbpnts; j++) {
992 const Intf_SectionPoint& SP = TZ.GetPoint(j);
993 SectionPointToParameters(SP,polyhedron,polygon,u,v,w);
1002 Standard_Real su=0,sv=0,sw=0,ptol;
1003 ptol = 10*Precision::PConfusion();
1005 //-- Tri suivant la variable W
1006 Standard_Boolean Triok;
1008 Triok=Standard_True;
1009 Standard_Integer im1;
1010 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
1011 if(TabW[i] < TabW[im1]) {
1012 Standard_Real t=TabW[i]; TabW[i]=TabW[im1]; TabW[im1]=t;
1013 t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
1014 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
1015 Triok=Standard_False;
1019 while(Triok==Standard_False);
1021 //-- On trie pour des meme W suivant U
1023 Triok=Standard_True;
1024 Standard_Integer im1;
1025 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
1026 // modified by NIZHNY-MKK Mon Oct 3 17:38:56 2005
1027 // if(Abs(TabW[i]-TabW[im1])<ptol) {
1028 if((TabW[i]-TabW[im1])<ptol) {
1030 if(TabU[i] < TabU[im1]) {
1031 Standard_Real t=TabU[i]; TabU[i]=TabU[im1]; TabU[im1]=t;
1032 t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
1033 Triok=Standard_False;
1038 while(Triok==Standard_False);
1040 //-- On trie pour des meme U et W suivant V
1042 Triok=Standard_True;
1043 Standard_Integer im1;
1044 for(i=1,im1=0;i<NbStartPoints;im1++,i++) {
1045 // modified by NIZHNY-MKK Mon Oct 3 17:38:58 2005
1046 // if((Abs(TabW[i]-TabW[im1])<ptol) && (Abs(TabU[i]-TabU[im1])<ptol)) {
1047 if(((TabW[i]-TabW[im1])<ptol) && ((TabU[i]-TabU[im1])<ptol)) {
1049 if(TabV[i] < TabV[im1]) {
1050 Standard_Real t=TabV[i]; TabV[i]=TabV[im1]; TabV[im1]=t;
1051 Triok=Standard_False;
1056 while(Triok==Standard_False);
1059 for(i=0;i<NbStartPoints; i++) {
1060 u=TabU[i]; v=TabV[i]; w=TabW[i];
1064 if(Abs(u-su)>ptol || Abs(v-sv)>ptol || Abs(w-sw)>ptol) {
1065 intersectionExacte.Perform(u,v,w,rsnld,u0,u1,v0,v1,winf,wsup);
1066 if(intersectionExacte.IsDone()) {
1067 if(!intersectionExacte.IsEmpty()) {
1068 P=intersectionExacte.Point();
1069 w=intersectionExacte.ParameterOnCurve();
1070 intersectionExacte.ParameterOnSurface(u,v);
1071 AppendPoint(curve,w,surface,u,v);
1075 su=TabU[i]; sv=TabV[i]; sw=TabW[i];
1082 //=======================================================================
1083 //function : InternalPerformCurveQuadric
1085 //=======================================================================
1086 void IntCurveSurface_Inter::InternalPerformCurveQuadric(const TheCurve& curve,
1087 const TheSurface& surface) {
1088 IntCurveSurface_TheQuadCurvExactInter QuadCurv(surface,curve);
1089 if(QuadCurv.IsDone()) {
1090 Standard_Integer NbRoots = QuadCurv.NbRoots();
1091 Standard_Real u,v,w;
1092 for(Standard_Integer i = 1; i<= NbRoots; i++) {
1093 w = QuadCurv.Root(i);
1094 IntCurveSurface_ComputeParamsOnQuadric(surface,TheCurveTool::Value(curve,w),u,v);
1095 AppendPoint(curve,w,surface,u,v);
1097 //-- Intervals non traites .............................................
1101 //=======================================================================
1102 //function : InternalPerform
1104 //=======================================================================
1105 void IntCurveSurface_Inter::InternalPerform(const TheCurve& curve,
1106 const IntCurveSurface_ThePolygon& polygon,
1107 const TheSurface& surface,
1108 const Standard_Real U1,
1109 const Standard_Real V1,
1110 const Standard_Real U2,
1111 const Standard_Real V2) {
1112 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1113 if( (SurfaceType != GeomAbs_Plane)
1114 && (SurfaceType != GeomAbs_Cylinder)
1115 && (SurfaceType != GeomAbs_Cone)
1116 && (SurfaceType != GeomAbs_Sphere) ) {
1117 if(SurfaceType != GeomAbs_BSplineSurface) {
1118 Standard_Integer nbsu,nbsv;
1119 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1120 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1121 if(nbsu>40) nbsu=40;
1122 if(nbsv>40) nbsv=40;
1123 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2);
1124 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1127 Handle(Adaptor3d_HSurface) aS = TheSurfaceTool::UTrim(surface, U1, U2, 1.e-9);
1128 aS = aS->VTrim(V1, V2, 1.e-9);
1129 Handle(Adaptor3d_TopolTool) aTopTool = new Adaptor3d_TopolTool(aS);
1130 Standard_Real defl = 0.1;
1131 aTopTool->SamplePnts(defl, 10, 10);
1133 Standard_Integer nbpu = aTopTool->NbSamplesU();
1134 Standard_Integer nbpv = aTopTool->NbSamplesV();
1135 TColStd_Array1OfReal Upars(1, nbpu), Vpars(1, nbpv);
1136 aTopTool->UParameters(Upars);
1137 aTopTool->VParameters(Vpars);
1139 IntCurveSurface_ThePolyhedron polyhedron(surface,Upars, Vpars);
1140 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1144 IntCurveSurface_TheQuadCurvExactInter QuadCurv(surface,curve);
1145 if(QuadCurv.IsDone()) {
1146 Standard_Integer NbRoots = QuadCurv.NbRoots();
1147 Standard_Real u,v,w;
1148 for(Standard_Integer i = 1; i<= NbRoots; i++) {
1149 w = QuadCurv.Root(i);
1150 IntCurveSurface_ComputeParamsOnQuadric(surface,TheCurveTool::Value(curve,w),u,v);
1151 AppendPoint(curve,w,surface,u,v);
1153 //-- Intervalles non traites .............................................
1155 } //-- Fin : la Surface est une quadrique
1157 //=======================================================================
1158 //function : PerformConicSurf
1160 //=======================================================================
1161 void IntCurveSurface_Inter::PerformConicSurf(const gp_Lin& Line,
1162 const TheCurve& curve,
1163 const TheSurface& surface,
1164 const Standard_Real U1,
1165 const Standard_Real V1,
1166 const Standard_Real U2,
1167 const Standard_Real V2) {
1170 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1171 switch(SurfaceType) {
1174 IntAna_IntConicQuad LinPlane(Line,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE);
1175 AppendIntAna(curve,surface,LinPlane);
1178 case GeomAbs_Cylinder:
1180 IntAna_IntConicQuad LinCylinder(Line,TheSurfaceTool::Cylinder(surface));
1181 AppendIntAna(curve,surface,LinCylinder);
1184 case GeomAbs_Sphere:
1186 IntAna_IntConicQuad LinSphere(Line,TheSurfaceTool::Sphere(surface));
1187 AppendIntAna(curve,surface,LinSphere);
1192 IntAna_IntLinTorus intlintorus(Line,TheSurfaceTool::Torus(surface));
1193 if(intlintorus.IsDone()) {
1194 Standard_Integer nbp = intlintorus.NbPoints();
1195 Standard_Real fi,theta,w;
1196 for(Standard_Integer i = 1; i<= nbp; i++) {
1199 P = intlintorus.Value(i);
1201 gp_Pnt P(intlintorus.Value(i));
1203 w = intlintorus.ParamOnLine(i);
1204 intlintorus.ParamOnTorus(i,fi,theta);
1205 AppendPoint(curve,w,surface,fi,theta);
1209 } //-- Si Done retourne False, On passe dans Default !!
1213 const Standard_Real correction = 1.E+5*Precision::Angular();
1214 gp_Cone cn = TheSurfaceTool::Cone(surface);
1215 if(Abs(cn.SemiAngle()) < M_PI/2.0 - correction){
1216 IntAna_IntConicQuad LinCone(Line,cn);
1217 AppendIntAna(curve,surface,LinCone);
1223 Standard_Integer nbsu,nbsv;
1224 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1225 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1227 Standard_Boolean U1inf = Precision::IsInfinite(U1);
1228 Standard_Boolean U2inf = Precision::IsInfinite(U2);
1229 Standard_Boolean V1inf = Precision::IsInfinite(V1);
1230 Standard_Boolean V2inf = Precision::IsInfinite(V2);
1232 Standard_Real U1new=U1, U2new=U2, V1new=V1, V2new=V2;
1234 Standard_Boolean NoIntersection = Standard_False;
1236 if(U1inf || U2inf || V1inf || V2inf ) {
1238 if(SurfaceType == GeomAbs_SurfaceOfExtrusion) {
1240 EstLimForInfExtr(Line, surface, Standard_False, nbsu,
1241 U1inf, U2inf, V1inf, V2inf,
1242 U1new, U2new, V1new, V2new, NoIntersection);
1245 else if(SurfaceType == GeomAbs_SurfaceOfRevolution) {
1247 EstLimForInfRevl(Line, surface,
1248 U1inf, U2inf, V1inf, V2inf,
1249 U1new, U2new, V1new, V2new, NoIntersection);
1252 else if(SurfaceType == GeomAbs_OffsetSurface) {
1254 EstLimForInfOffs(Line, surface, nbsu,
1255 U1inf, U2inf, V1inf, V2inf,
1256 U1new, U2new, V1new, V2new, NoIntersection);
1260 EstLimForInfSurf(U1new, U2new, V1new, V2new);
1266 if(NoIntersection) return;
1269 // modified by NIZHNY-OFV Mon Aug 20 14:56:47 2001 (60963 begin)
1270 if(nbsu<20) nbsu=20;
1271 if(nbsv<20) nbsv=20;
1272 // modified by NIZHNY-OFV Mon Aug 20 14:57:06 2001 (60963 end)
1273 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1new,V1new,U2new,V2new);
1276 bndTool.LinBox(Line,polyhedron.Bounding(),boxLine);
1277 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) {
1278 Standard_Real pinf = bndTool.BeginParam(nbseg);
1279 Standard_Real psup = bndTool.EndParam(nbseg);
1280 if((psup - pinf)<1e-10) { pinf-=1e-10; psup+=1e-10; }
1281 IntCurveSurface_ThePolygon polygon(curve, pinf,psup,2);
1282 InternalPerform(curve,polygon,surface,polyhedron,U1new,V1new,U2new,V2new);
1287 //=======================================================================
1288 //function : PerformConicSurf
1290 //=======================================================================
1291 void IntCurveSurface_Inter::PerformConicSurf(const gp_Circ& Circle,
1292 const TheCurve& curve,
1293 const TheSurface& surface,
1294 const Standard_Real U1,
1295 const Standard_Real V1,
1296 const Standard_Real U2,
1297 const Standard_Real V2) {
1299 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1300 switch(SurfaceType) {
1303 IntAna_IntConicQuad CircPlane(Circle,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE,TOLERANCE);
1304 AppendIntAna(curve,surface,CircPlane);
1307 case GeomAbs_Cylinder:
1309 IntAna_IntConicQuad CircCylinder(Circle,TheSurfaceTool::Cylinder(surface));
1310 AppendIntAna(curve,surface,CircCylinder);
1315 IntAna_IntConicQuad CircCone(Circle,TheSurfaceTool::Cone(surface));
1316 AppendIntAna(curve,surface,CircCone);
1319 case GeomAbs_Sphere:
1321 IntAna_IntConicQuad CircSphere(Circle,TheSurfaceTool::Sphere(surface));
1322 AppendIntAna(curve,surface,CircSphere);
1327 IntCurveSurface_ThePolygon polygon(curve,NBSAMPLESONCIRCLE);
1328 InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
1332 //=======================================================================
1333 //function : PerformConicSurf
1335 //=======================================================================
1336 void IntCurveSurface_Inter::PerformConicSurf(const gp_Elips& Ellipse,
1337 const TheCurve& curve,
1338 const TheSurface& surface,
1339 const Standard_Real U1,
1340 const Standard_Real V1,
1341 const Standard_Real U2,
1342 const Standard_Real V2) {
1344 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1345 switch(SurfaceType) {
1348 IntAna_IntConicQuad EllipsePlane(Ellipse,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE,TOLERANCE);
1349 AppendIntAna(curve,surface,EllipsePlane);
1352 case GeomAbs_Cylinder:
1354 IntAna_IntConicQuad EllipseCylinder(Ellipse,TheSurfaceTool::Cylinder(surface));
1355 AppendIntAna(curve,surface,EllipseCylinder);
1360 IntAna_IntConicQuad EllipseCone(Ellipse,TheSurfaceTool::Cone(surface));
1361 AppendIntAna(curve,surface,EllipseCone);
1364 case GeomAbs_Sphere:
1366 IntAna_IntConicQuad EllipseSphere(Ellipse,TheSurfaceTool::Sphere(surface));
1367 AppendIntAna(curve,surface,EllipseSphere);
1372 IntCurveSurface_ThePolygon polygon(curve,NBSAMPLESONELLIPSE);
1373 InternalPerform(curve,polygon,surface,U1,V1,U2,V2);
1377 //=======================================================================
1378 //function : PerformConicSurf
1380 //=======================================================================
1381 void IntCurveSurface_Inter::PerformConicSurf(const gp_Parab& Parab,
1382 const TheCurve& curve,
1383 const TheSurface& surface,
1384 const Standard_Real U1,
1385 const Standard_Real V1,
1386 const Standard_Real U2,
1387 const Standard_Real V2) {
1389 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1390 switch(SurfaceType) {
1393 IntAna_IntConicQuad ParabPlane(Parab,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE);
1394 AppendIntAna(curve,surface,ParabPlane);
1397 case GeomAbs_Cylinder:
1399 IntAna_IntConicQuad ParabCylinder(Parab,TheSurfaceTool::Cylinder(surface));
1400 AppendIntAna(curve,surface,ParabCylinder);
1405 IntAna_IntConicQuad ParabCone(Parab,TheSurfaceTool::Cone(surface));
1406 AppendIntAna(curve,surface,ParabCone);
1409 case GeomAbs_Sphere:
1411 IntAna_IntConicQuad ParabSphere(Parab,TheSurfaceTool::Sphere(surface));
1412 AppendIntAna(curve,surface,ParabSphere);
1417 Standard_Integer nbsu,nbsv;
1418 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1419 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1420 if(nbsu>40) nbsu=40;
1421 if(nbsv>40) nbsv=40;
1422 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2);
1425 bndTool.ParabBox(Parab,polyhedron.Bounding(),boxParab);
1426 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) {
1427 IntCurveSurface_ThePolygon polygon(curve,
1428 bndTool.BeginParam(nbseg),
1429 bndTool.EndParam(nbseg),
1431 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1436 //=======================================================================
1437 //function : PerformConicSurf
1439 //=======================================================================
1440 void IntCurveSurface_Inter::PerformConicSurf(const gp_Hypr& Hypr,
1441 const TheCurve& curve,
1442 const TheSurface& surface,
1443 const Standard_Real U1,
1444 const Standard_Real V1,
1445 const Standard_Real U2,
1446 const Standard_Real V2) {
1448 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1449 switch(SurfaceType) {
1452 IntAna_IntConicQuad HyprPlane(Hypr,TheSurfaceTool::Plane(surface),TOLERANCE_ANGULAIRE);
1453 AppendIntAna(curve,surface,HyprPlane);
1456 case GeomAbs_Cylinder:
1458 IntAna_IntConicQuad HyprCylinder(Hypr,TheSurfaceTool::Cylinder(surface));
1459 AppendIntAna(curve,surface,HyprCylinder);
1464 IntAna_IntConicQuad HyprCone(Hypr,TheSurfaceTool::Cone(surface));
1465 AppendIntAna(curve,surface,HyprCone);
1468 case GeomAbs_Sphere:
1470 IntAna_IntConicQuad HyprSphere(Hypr,TheSurfaceTool::Sphere(surface));
1471 AppendIntAna(curve,surface,HyprSphere);
1476 Standard_Integer nbsu,nbsv;
1477 nbsu = TheSurfaceTool::NbSamplesU(surface,U1,U2);
1478 nbsv = TheSurfaceTool::NbSamplesV(surface,V1,V2);
1479 if(nbsu>40) nbsu=40;
1480 if(nbsv>40) nbsv=40;
1481 IntCurveSurface_ThePolyhedron polyhedron(surface,nbsu,nbsv,U1,V1,U2,V2);
1484 bndTool.HyprBox(Hypr,polyhedron.Bounding(),boxHypr);
1485 for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) {
1486 IntCurveSurface_ThePolygon polygon(curve,
1487 bndTool.BeginParam(nbseg),
1488 bndTool.EndParam(nbseg),
1490 InternalPerform(curve,polygon,surface,polyhedron,U1,V1,U2,V2);
1495 //=======================================================================
1496 //function : AppendIntAna
1498 //=======================================================================
1499 void IntCurveSurface_Inter::AppendIntAna(const TheCurve& curve,
1500 const TheSurface& surface,
1501 const IntAna_IntConicQuad& intana_ConicQuad) {
1502 if(intana_ConicQuad.IsDone()) {
1503 if(intana_ConicQuad.IsInQuadric()) {
1504 //-- cout<<" Courbe Dans la Quadrique !!! Non Traite !!!"<<endl;
1506 else if(intana_ConicQuad.IsParallel()) {
1507 //-- cout<<" Courbe // a la Quadrique !!! Non Traite !!!"<<endl;
1510 Standard_Integer nbp = intana_ConicQuad.NbPoints();
1511 Standard_Real u,v,w;
1512 for(Standard_Integer i = 1; i<= nbp; i++) {
1513 gp_Pnt P(intana_ConicQuad.Point(i));
1514 w = intana_ConicQuad.ParamOnConic(i);
1515 IntCurveSurface_ComputeParamsOnQuadric(surface,P,u,v);
1516 AppendPoint(curve,w,surface,u,v);
1521 //-- cout<<" IntAna Conic Quad Not Done "<<endl;
1524 //=======================================================================
1525 //function : AppendPoint
1527 //=======================================================================
1528 void IntCurveSurface_Inter::AppendPoint(const TheCurve& curve,
1529 const Standard_Real lw,
1530 const TheSurface& surface,
1531 const Standard_Real su,
1532 const Standard_Real sv) {
1534 Standard_Real W0 = TheCurveTool::FirstParameter(curve);
1535 Standard_Real W1 = TheCurveTool::LastParameter(curve);
1536 Standard_Real U0 = TheSurfaceTool::FirstUParameter(surface);
1537 Standard_Real U1 = TheSurfaceTool::LastUParameter(surface);
1538 Standard_Real V0 = TheSurfaceTool::FirstVParameter(surface);
1539 Standard_Real V1 = TheSurfaceTool::LastVParameter(surface);
1540 //-- Test si la courbe est periodique
1541 Standard_Real w = lw, u = su, v = sv;
1543 GeomAbs_CurveType aCType = TheCurveTool::GetType(curve);
1545 if(TheCurveTool::IsPeriodic(curve)
1546 || aCType == GeomAbs_Circle
1547 || aCType == GeomAbs_Ellipse) {
1548 w = ElCLib::InPeriod(w, W0, W0 + TheCurveTool::Period(curve));
1551 if((W0 - w) >= TOLTANGENCY || (w - W1) >= TOLTANGENCY) return;
1553 GeomAbs_SurfaceType aSType = TheSurfaceTool::GetType(surface);
1554 if (TheSurfaceTool::IsUPeriodic(surface)
1555 || aSType == GeomAbs_Cylinder
1556 || aSType == GeomAbs_Cone
1557 || aSType == GeomAbs_Sphere) {
1558 u = ElCLib::InPeriod(u, U0, U0 + TheSurfaceTool::UPeriod(surface));
1561 if (TheSurfaceTool::IsVPeriodic(surface)) {
1562 v = ElCLib::InPeriod(v, V0, V0 + TheSurfaceTool::VPeriod(surface));
1565 if((U0 - u) >= TOLTANGENCY || (u - U1) >= TOLTANGENCY) return;
1566 if((V0 - v) >= TOLTANGENCY || (v - V1) >= TOLTANGENCY) return;
1568 IntCurveSurface_TransitionOnCurve TransOnCurve;
1569 IntCurveSurface_ComputeTransitions(curve,w,TransOnCurve,
1571 gp_Pnt P(TheCurveTool::Value(curve,w));
1572 IntCurveSurface_IntersectionPoint IP(P,u,v,w,TransOnCurve);
1573 Append(IP); //-- invoque la methode de IntCurveSurface_Intersection.
1577 //=======================================================================
1578 //function : AppendSegment
1580 //=======================================================================
1581 void IntCurveSurface_Inter::AppendSegment(const TheCurve& ,
1582 const Standard_Real ,
1583 const Standard_Real ,
1584 const TheSurface& ) {
1585 //cout<<" !!! Not Yet Implemented
1586 //IntCurveSurface_Inter::Append(const IntCurveSurf ...)"<<endl;
1589 //=======================================================================
1590 //function : SectionPointToParameters
1591 //purpose : P o i n t d i n t e r f e r e n c e - - >
1593 //=======================================================================
1594 void SectionPointToParameters(const Intf_SectionPoint& Sp,
1595 const IntCurveSurface_ThePolyhedron& Polyhedron,
1596 const IntCurveSurface_ThePolygon& Polygon,
1602 Standard_Integer Adr1,Adr2;
1603 Standard_Real Param,u,v;
1606 Standard_Integer Pt1,Pt2,Pt3;
1607 Standard_Real u1,v1,param;
1608 //----------------------------------------------------------------------
1609 //-- Calcul des parametres approches sur la surface --
1610 //----------------------------------------------------------------------
1612 Sp.InfoSecond(typ,Adr1,Adr2,Param);
1614 case Intf_VERTEX: //-- Adr1 est le numero du vertex
1616 Polyhedron.Parameters(Adr1,u1,v1);
1621 Polyhedron.Parameters(Adr1,u1,v1);
1622 Polyhedron.Parameters(Adr2,u,v);
1623 u1+= Param * (u-u1);
1624 v1+= Param * (v-v1);
1629 Standard_Real ua,va,ub,vb,uc,vc,ca,cb,cc,cabc;
1630 Polyhedron.Triangle(Adr1,Pt1,Pt2,Pt3);
1631 gp_Pnt PA(Polyhedron.Point(Pt1));
1632 gp_Pnt PB(Polyhedron.Point(Pt2));
1633 gp_Pnt PC(Polyhedron.Point(Pt3));
1634 Polyhedron.Parameters(Pt1,ua,va);
1635 Polyhedron.Parameters(Pt2,ub,vb);
1636 Polyhedron.Parameters(Pt3,uc,vc);
1637 gp_Vec Normale(gp_Vec(PA,PB).Crossed(gp_Vec(PA,PC)));
1638 cc = (gp_Vec(PA,PB).Crossed(gp_Vec(PA,P))).Dot(Normale);
1639 ca = (gp_Vec(PB,PC).Crossed(gp_Vec(PB,P))).Dot(Normale);
1640 cb = (gp_Vec(PC,PA).Crossed(gp_Vec(PC,P))).Dot(Normale);
1641 cabc = ca + cb + cc;
1643 ca/=cabc; cb/=cabc; cc/=cabc;
1645 u1 = ca * ua + cb * ub + cc * uc;
1646 v1 = ca * va + cb * vb + cc * vc;
1651 cout<<" Default dans SectionPointToParameters "<<endl;
1655 //----------------------------------------------------------------------
1656 //-- Calcul du point approche sur la Curve --
1657 //----------------------------------------------------------------------
1658 Standard_Integer SegIndex;
1660 Sp.InfoFirst(typ,SegIndex,param);
1661 W = Polygon.ApproxParamOnCurve(SegIndex,param);
1662 if(param>1.0 || param<0.0) {
1663 //-- IntCurveSurface_ThePolyhedronTool::Dump(Polyhedron);
1664 //-- IntCurveSurface_ThePolygonTool::Dump(Polygon);
1669 //=======================================================================
1670 //function : IntCurveSurface_ComputeTransitions
1672 //=======================================================================
1673 void IntCurveSurface_ComputeTransitions(const TheCurve& curve,
1674 const Standard_Real w,
1675 IntCurveSurface_TransitionOnCurve& TransOnCurve,
1676 const TheSurface& surface,
1677 const Standard_Real u,
1678 const Standard_Real v) {
1680 gp_Vec NSurf,D1U,D1V;//TgCurv;
1682 Standard_Real CosDir;
1685 TheSurfaceTool::D1(surface,u,v,Psurf,D1U,D1V);
1686 NSurf = D1U.Crossed(D1V);
1687 TheCurveTool::D1(curve,w,Psurf,D1U);
1688 Standard_Real Norm = NSurf.Magnitude();
1689 if(Norm>TOLERANCE_ANGULAIRE) {
1691 CosDir = NSurf.Dot(D1U);
1693 if( -CosDir > TOLERANCE_ANGULAIRE) {
1694 //-- --Curve---> <----Surface----
1695 TransOnCurve = IntCurveSurface_In;
1697 else if(CosDir > TOLERANCE_ANGULAIRE) {
1698 //-- --Curve---> ----Surface-->
1699 TransOnCurve = IntCurveSurface_Out;
1702 TransOnCurve = IntCurveSurface_Tangent;
1706 TransOnCurve = IntCurveSurface_Tangent;
1709 //=======================================================================
1710 //function : IntCurveSurface_ComputeParamsOnQuadric
1712 //=======================================================================
1713 void IntCurveSurface_ComputeParamsOnQuadric(const TheSurface& surface,
1717 GeomAbs_SurfaceType SurfaceType = TheSurfaceTool::GetType(surface);
1718 switch(SurfaceType) {
1721 ElSLib::Parameters(TheSurfaceTool::Plane(surface),P,u,v);
1724 case GeomAbs_Cylinder:
1726 ElSLib::Parameters(TheSurfaceTool::Cylinder(surface),P,u,v);
1731 ElSLib::Parameters(TheSurfaceTool::Cone(surface),P,u,v);
1734 case GeomAbs_Sphere:
1736 ElSLib::Parameters(TheSurfaceTool::Sphere(surface),P,u,v);
1744 //=======================================================================
1745 //function : EstLimForInfExtr
1746 //purpose : Estimation of limits for infinite surfaces
1747 //=======================================================================
1748 void EstLimForInfExtr(const gp_Lin& Line,
1749 const TheSurface& surface,
1750 const Standard_Boolean IsOffSurf,
1751 const Standard_Integer nbsu,
1752 const Standard_Boolean U1inf,
1753 const Standard_Boolean U2inf,
1754 const Standard_Boolean V1inf,
1755 const Standard_Boolean V2inf,
1756 Standard_Real& U1new,
1757 Standard_Real& U2new,
1758 Standard_Real& V1new,
1759 Standard_Real& V2new,
1760 Standard_Boolean& NoIntersection)
1764 NoIntersection = Standard_False;
1766 Handle(Adaptor3d_HSurface) aBasSurf;
1768 if(IsOffSurf) aBasSurf = TheSurfaceTool::BasisSurface(surface);
1772 if(IsOffSurf) aDirOfExt = aBasSurf->Direction();
1773 else aDirOfExt = TheSurfaceTool::Direction(surface);
1775 Standard_Real tolang = TOLERANCE_ANGULAIRE;
1777 if(aDirOfExt.IsParallel(Line.Direction(), tolang)) {
1778 NoIntersection = Standard_True;
1782 if((V1inf || V2inf) && !(U1inf || U2inf)) {
1784 Standard_Real vmin = RealLast(), vmax = -vmin;
1786 Standard_Real step = (U2new - U1new) / nbsu;
1787 Standard_Real u = U1new, v;
1789 Extrema_POnCurv aP1, aP2;
1792 for(i = 0; i <= nbsu; i++) {
1794 TheSurfaceTool::D0(surface, u, 0., aP);
1796 aL.SetDirection(aDirOfExt);
1798 Extrema_ExtElC aExtr(aL, Line, tolang);
1800 if(!aExtr.IsDone()) return;
1802 if(aExtr.IsParallel()) {
1803 NoIntersection = Standard_True;
1807 aExtr.Points(1, aP1, aP2);
1808 v = aP1.Parameter();
1809 vmin = Min(vmin, v);
1810 vmax = Max(vmax, v);
1816 vmin = vmin - Abs(vmin) - 10.;
1817 vmax = vmax + Abs(vmax) + 10.;
1819 V1new = Max(V1new, vmin);
1820 V2new = Min(V2new, vmax);
1823 else if(U1inf || U2inf) {
1825 Standard_Real umin = RealLast(), umax = -umin;
1826 Standard_Real u0 = Min(Max(0., U1new), U2new);
1827 Standard_Real v0 = Min(Max(0., V1new), V2new);
1829 TheSurfaceTool::D0(surface, u0, v0, aP);
1830 gp_Pln aRefPln(aP, aDirOfExt);
1832 Handle(Adaptor3d_HCurve) aBasCurv;
1834 if(IsOffSurf) aBasCurv = aBasSurf->BasisCurve();
1835 else aBasCurv = TheSurfaceTool::BasisCurve(surface);
1837 ProjLib_Plane Projector(aRefPln);
1839 Projector.Project(Line);
1841 if(!Projector.IsDone()) return;
1843 gp_Lin2d Line2d = Projector.Line();
1845 GeomAbs_CurveType aCurvTyp = aBasCurv->GetType();
1847 if(aCurvTyp == GeomAbs_Line) {
1849 Projector.Project(aBasCurv->Line());
1851 if(!Projector.IsDone()) return;
1853 gp_Lin2d aL2d = Projector.Line();
1855 IntAna2d_AnaIntersection anInter(Line2d, aL2d);
1857 if(!anInter.IsDone()) return;
1859 if(anInter.IsEmpty() || anInter.IdenticalElements() ||
1860 anInter.ParallelElements() ) {
1861 NoIntersection = Standard_True;
1865 const IntAna2d_IntPoint& anIntPnt = anInter.Point(1);
1866 umin = umax = anIntPnt.ParamOnSecond();
1868 else if(aCurvTyp == GeomAbs_Parabola || aCurvTyp == GeomAbs_Hyperbola) {
1870 IntAna2d_Conic aCon(Line2d);
1871 IntAna2d_AnaIntersection anInter;
1873 if(aCurvTyp == GeomAbs_Parabola) {
1874 Projector.Project(aBasCurv->Parabola());
1875 if(!Projector.IsDone()) return;
1877 const gp_Parab2d& aP2d = Projector.Parabola();
1879 anInter.Perform(aP2d, aCon);
1882 Projector.Project(aBasCurv->Hyperbola());
1883 if(!Projector.IsDone()) return;
1885 const gp_Hypr2d& aH2d = Projector.Hyperbola();
1886 anInter.Perform(aH2d, aCon);
1889 if(!anInter.IsDone()) return;
1891 if(anInter.IsEmpty()) {
1892 NoIntersection = Standard_True;
1896 Standard_Integer i, nbint = anInter.NbPoints();
1897 for(i = 1; i <= nbint; i++) {
1899 const IntAna2d_IntPoint& anIntPnt = anInter.Point(i);
1901 umin = Min(anIntPnt.ParamOnFirst(), umin);
1902 umax = Max(anIntPnt.ParamOnFirst(), umax);
1911 umin = umin - Abs(umin) - 10;
1912 umax = umax + Abs(umax) + 10;
1914 U1new = Max(U1new, umin);
1915 U2new = Min(U2new, umax);
1917 if(V1inf || V2inf) {
1918 EstLimForInfExtr(Line, surface, IsOffSurf, nbsu,
1919 Standard_False, Standard_False, V1inf, V2inf,
1920 U1new, U2new, V1new, V2new, NoIntersection);
1927 //=======================================================================
1928 //function : ProjectIntersectAndEstLim
1929 //purpose : project <theLine> and it's X-axe symmetric line to <thePln> and
1930 // intersect resulting curve with <theBasCurvProj>.
1931 // Then estimate max and min parameters of intersection on
1932 // <theBasCurvProj>.
1933 // Is called from EstLimForInfRevl()
1934 //=======================================================================
1935 void ProjectIntersectAndEstLim(const gp_Lin& theLine,
1936 const gp_Pln& thePln,
1937 const ProjLib_Plane& theBasCurvProj,
1938 Standard_Real& theVmin,
1939 Standard_Real& theVmax,
1940 Standard_Boolean& theNoIntersection)
1942 ProjLib_Plane aLineProj( thePln, theLine );
1943 if (!aLineProj.IsDone()) {
1946 << "Info: IntCurveSurface_Inter::ProjectIntersectAndEstLim(), !aLineProj.IsDone()"
1951 gp_Lin2d aLin2d = aLineProj.Line();
1953 // make a second line X-axe symmetric to the first one
1954 gp_Pnt2d aP1 = aLin2d.Location();
1955 gp_Pnt2d aP2 (aP1.XY() + aLin2d.Direction().XY());
1956 gp_Pnt2d aP1sym (aP1.X(), -aP1.Y());
1957 gp_Pnt2d aP2sym (aP2.X(), -aP2.Y());
1958 gp_Lin2d aLin2dsym (aP1sym, gp_Vec2d(aP1sym,aP2sym));
1960 // intersect projections
1961 IntAna2d_Conic aCon (aLin2d);
1962 IntAna2d_Conic aConSym (aLin2dsym);
1963 IntAna2d_AnaIntersection anIntersect;
1964 IntAna2d_AnaIntersection anIntersectSym;
1966 switch (theBasCurvProj.GetType()) {
1968 anIntersectSym.Perform(theBasCurvProj.Line(), aConSym);
1969 anIntersect.Perform(theBasCurvProj.Line(), aCon); break;
1970 case GeomAbs_Hyperbola:
1971 anIntersectSym.Perform(theBasCurvProj.Hyperbola(), aConSym);
1972 anIntersect.Perform(theBasCurvProj.Hyperbola(), aCon); break;
1973 case GeomAbs_Parabola:
1974 anIntersectSym.Perform(theBasCurvProj.Parabola(), aConSym);
1975 anIntersect.Perform(theBasCurvProj.Parabola(), aCon); break;
1977 return; // not infinite curve
1980 // retrieve params of intersections
1981 Standard_Integer aNbIntPnt = anIntersect.IsDone() ? anIntersect.NbPoints() : 0;
1982 Standard_Integer aNbIntPntSym = anIntersectSym.IsDone() ? anIntersectSym.NbPoints() : 0;
1983 Standard_Integer iPnt, aNbPnt = Max (aNbIntPnt, aNbIntPntSym);
1986 theNoIntersection = Standard_True;
1989 Standard_Real aParam;
1990 for (iPnt = 1; iPnt <= aNbPnt; iPnt++)
1992 if (iPnt <= aNbIntPnt) {
1993 const IntAna2d_IntPoint& aIntPnt = anIntersect.Point(iPnt);
1994 aParam = aIntPnt.ParamOnFirst();
1995 theVmin = Min (theVmin, aParam );
1996 theVmax = Max (theVmax, aParam );
1998 if (iPnt <= aNbIntPntSym) {
1999 const IntAna2d_IntPoint& aIntPnt = anIntersectSym.Point(iPnt);
2000 aParam = aIntPnt.ParamOnFirst();
2001 theVmin = Min (theVmin, aParam );
2002 theVmax = Max (theVmax, aParam );
2008 //=======================================================================
2009 //function : EstLimForInfRevl
2010 //purpose : Estimate V1 and V2 to pass to InternalPerform() if they are
2011 // infinite for Surface of Revolution
2012 // Algo: intersect projections of Line and basis curve on the
2013 // plane passing through revolution axe
2014 //=======================================================================
2015 void EstLimForInfRevl(const gp_Lin& Line,
2016 const TheSurface& surface,
2017 const Standard_Boolean U1inf,
2018 const Standard_Boolean U2inf,
2019 const Standard_Boolean V1inf,
2020 const Standard_Boolean V2inf,
2021 Standard_Real& U1new,
2022 Standard_Real& U2new,
2023 Standard_Real& V1new,
2024 Standard_Real& V2new,
2025 Standard_Boolean& NoIntersection)
2028 NoIntersection = Standard_False;
2030 if (U1inf || U2inf) {
2032 U1new = Max (0., U1new);
2034 U2new = Min (2 * M_PI, U2new);
2035 if (! V1inf && !V2inf) return;
2038 Handle(Adaptor3d_HCurve) aBasisCurve = TheSurfaceTool::BasisCurve(surface);
2039 gp_Ax1 aRevAx = TheSurfaceTool::AxeOfRevolution(surface);
2040 gp_Vec aXVec = aRevAx.Direction();
2041 Standard_Real aTolAng = Precision::Angular();
2043 // make plane to project a basis curve
2044 gp_Pnt O = aRevAx.Location();
2045 Standard_Real aU = 0.;
2046 gp_Pnt P = aBasisCurve->Value(aU);
2047 while (O.SquareDistance(P) <= Precision::PConfusion() ||
2048 aXVec.IsParallel( gp_Vec(O,P), aTolAng)) {
2050 P = aBasisCurve->Value(aU);
2052 // basis curve is a line coinciding with aXVec, P is any not on aXVec
2053 P = gp_Pnt(aU, aU+1, aU+2);
2055 gp_Vec aNVec = aXVec ^ gp_Vec(O,P);
2056 gp_Pln aPln (gp_Ax3 (O, aNVec ,aXVec));
2058 // project basic curve
2059 ProjLib_Plane aBasCurvProj(aPln);
2060 switch (aBasisCurve->GetType()) {
2062 aBasCurvProj.Project(aBasisCurve->Line ()); break;
2063 case GeomAbs_Hyperbola:
2064 aBasCurvProj.Project(aBasisCurve->Hyperbola()); break;
2065 case GeomAbs_Parabola:
2066 aBasCurvProj.Project(aBasisCurve->Parabola ()); break;
2068 return; // not infinite curve
2070 if (!aBasCurvProj.IsDone()) {
2072 cout << "Info: IntCurveSurface_Inter::EstLimForInfRevl(), !aBasCurvProj.IsDone()" << endl;
2076 // make plane to project Line
2077 if (aXVec.IsParallel( Line.Direction(), aTolAng)) {
2078 P = Line.Location();
2079 while (O.SquareDistance(P) <= Precision::PConfusion()) {
2081 P = gp_Pnt(aU, aU+1, aU+2); // any not on aXVec
2083 aNVec = aXVec ^ gp_Vec(O,P);
2085 aNVec = aXVec.Crossed( Line.Direction() );
2087 aPln = gp_Pln (gp_Ax3 (O, aNVec ,aXVec));
2089 // make a second plane perpendicular to the first one, rotated around aXVec
2090 gp_Pln aPlnPrp = aPln.Rotated (gp_Ax1 (O,aXVec), M_PI/2.);
2092 // project Line and it's X-axe symmetric one to plane and intersect
2093 // resulting curve with projection of Basic Curev
2094 Standard_Real aVmin = RealLast(), aVmax = -aVmin;
2095 Standard_Boolean aNoInt1 = Standard_False, aNoInt2 = Standard_False;
2096 ProjectIntersectAndEstLim (Line, aPln, aBasCurvProj, aVmin, aVmax, aNoInt1);
2097 ProjectIntersectAndEstLim (Line, aPlnPrp, aBasCurvProj, aVmin, aVmax, aNoInt2);
2099 if (aNoInt1 && aNoInt2) {
2100 NoIntersection = Standard_True;
2104 aVmin = aVmin - Abs(aVmin) - 10;
2105 aVmax = aVmax + Abs(aVmax) + 10;
2107 if (V1inf) V1new = aVmin;
2108 if (V2inf) V2new = aVmax;
2110 //cout << "EstLimForInfRevl: Vmin " << V1new << " Vmax " << V2new << endl;
2115 //=======================================================================
2116 //function : EstLimForInfOffs
2118 //=======================================================================
2119 void EstLimForInfOffs(const gp_Lin& Line,
2120 const TheSurface& surface,
2121 const Standard_Integer nbsu,
2122 const Standard_Boolean U1inf,
2123 const Standard_Boolean U2inf,
2124 const Standard_Boolean V1inf,
2125 const Standard_Boolean V2inf,
2126 Standard_Real& U1new,
2127 Standard_Real& U2new,
2128 Standard_Real& V1new,
2129 Standard_Real& V2new,
2130 Standard_Boolean& NoIntersection)
2133 NoIntersection = Standard_False;
2135 const Handle(Adaptor3d_HSurface)& aBasSurf = TheSurfaceTool::BasisSurface(surface);
2136 Standard_Real anOffVal = TheSurfaceTool::OffsetValue(surface);
2138 GeomAbs_SurfaceType aTypeOfBasSurf = aBasSurf->GetType();
2140 // case for plane, cylinder and cone - make equivalent surface;
2141 if(aTypeOfBasSurf == GeomAbs_Plane) {
2143 gp_Pln aPln = aBasSurf->Plane();
2144 gp_Vec aT = aPln.Position().XDirection()^aPln.Position().YDirection();
2147 IntAna_IntConicQuad LinPlane(Line,aPln,TOLERANCE_ANGULAIRE);
2149 if(!LinPlane.IsDone()) return;
2151 if(LinPlane.IsParallel() || LinPlane.IsInQuadric()) {
2153 NoIntersection = Standard_True;
2159 ElSLib::Parameters(aPln, LinPlane.Point(1), u, v);
2160 U1new = Max(U1new, u - 10.);
2161 U2new = Min(U2new, u + 10.);
2162 V1new = Max(V1new, v - 10.);
2163 V2new = Min(V2new, v + 10.);
2166 else if(aTypeOfBasSurf == GeomAbs_Cylinder) {
2168 gp_Cylinder aCyl = aBasSurf->Cylinder();
2170 Standard_Real aR = aCyl.Radius();
2171 gp_Ax3 anA = aCyl.Position();
2178 if ( aR >= TOLTANGENCY ) {
2181 else if ( aR <= -TOLTANGENCY ){
2182 anA.Rotate(gp_Ax1(anA.Location(), anA.Direction()), M_PI);
2183 aCyl.SetPosition(anA);
2184 // modified by NIZHNY-MKK Mon Oct 3 17:37:54 2005
2185 // aCyl.SetRadius(Abs(aR));
2186 aCyl.SetRadius(-aR);
2190 NoIntersection = Standard_True;
2195 IntAna_IntConicQuad LinCylinder(Line, aCyl);
2197 if(!LinCylinder.IsDone()) return;
2199 if(LinCylinder.IsParallel() || LinCylinder.IsInQuadric()) {
2201 NoIntersection = Standard_True;
2206 Standard_Integer i, nbp = LinCylinder.NbPoints();
2207 Standard_Real vmin = RealLast(), vmax = -vmin, u, v;
2209 for(i = 1; i <= nbp; i++) {
2211 ElSLib::Parameters(aCyl, LinCylinder.Point(i), u, v);
2212 vmin = Min(vmin, v);
2213 vmax = Max(vmax, v);
2217 V1new = Max(V1new, vmin - Abs(vmin) - 10.);
2218 V2new = Min(V2new, vmax + Abs(vmax) + 10.);
2221 else if(aTypeOfBasSurf == GeomAbs_Cone) {
2223 gp_Cone aCon = aBasSurf->Cone();
2224 Standard_Real anAng = aCon.SemiAngle();
2225 Standard_Real aR = aCon.RefRadius() + anOffVal * Cos(anAng);
2226 gp_Ax3 anA = aCon.Position();
2229 gp_Vec aZ( anA.Direction());
2230 aZ *= - anOffVal * Sin(anAng);
2232 aCon.SetPosition(anA);
2234 aCon.SetSemiAngle(anAng);
2243 IntAna_IntConicQuad LinCone(Line, aCon);
2245 if(!LinCone.IsDone()) return;
2247 if(LinCone.IsParallel() || LinCone.IsInQuadric()) {
2249 NoIntersection = Standard_True;
2254 Standard_Integer i, nbp = LinCone.NbPoints();
2255 Standard_Real vmin = RealLast(), vmax = -vmin, u, v;
2257 for(i = 1; i <= nbp; i++) {
2259 ElSLib::Parameters(aCon, LinCone.Point(i), u, v);
2260 vmin = Min(vmin, v);
2261 vmax = Max(vmax, v);
2265 V1new = Max(V1new, vmin - Abs(vmin) - 10.);
2266 V2new = Min(V2new, vmax + Abs(vmax) + 10.);
2269 else if(aTypeOfBasSurf == GeomAbs_SurfaceOfExtrusion) {
2271 Standard_Real anU1 = U1new, anU2 = U2new;
2273 EstLimForInfExtr(Line, surface, Standard_True, nbsu,
2274 U1inf, U2inf, V1inf, V2inf,
2275 U1new, U2new, V1new, V2new, NoIntersection);
2277 if(NoIntersection) return;
2279 if(U1inf || U2inf) {
2281 GeomAbs_CurveType aBasCurvType = aBasSurf->BasisCurve()->GetType();
2282 if(aBasCurvType == GeomAbs_Line) {
2283 U1new = Max(anU1, -1.e10);
2284 U2new = Min(anU2, 1.e10);
2286 else if(aBasCurvType == GeomAbs_Parabola) {
2287 gp_Parab aPrb = aBasSurf->BasisCurve()->Parabola();
2288 Standard_Real aF = aPrb.Focal();
2289 Standard_Real dU = 2.e5 * Sqrt(aF);
2290 U1new = Max(anU1, -dU);
2291 U2new = Min(anU2, dU);
2293 else if(aBasCurvType == GeomAbs_Hyperbola) {
2294 U1new = Max(anU1, -30.);
2295 U2new = Min(anU2, 30.);
2298 U1new = Max(anU1, -1.e10);
2299 U2new = Min(anU2, 1.e10);
2305 else if(aTypeOfBasSurf == GeomAbs_SurfaceOfRevolution) {
2307 GeomAbs_CurveType aBasCurvType = aBasSurf->BasisCurve()->GetType();
2308 if(aBasCurvType == GeomAbs_Line) {
2309 V1new = Max(V1new, -1.e10);
2310 V2new = Min(V2new, 1.e10);
2312 else if(aBasCurvType == GeomAbs_Parabola) {
2313 gp_Parab aPrb = aBasSurf->BasisCurve()->Parabola();
2314 Standard_Real aF = aPrb.Focal();
2315 Standard_Real dV = 2.e5 * Sqrt(aF);
2316 V1new = Max(V1new, -dV);
2317 V2new = Min(V2new, dV);
2319 else if(aBasCurvType == GeomAbs_Hyperbola) {
2320 V1new = Max(V1new, -30.);
2321 V2new = Min(V2new, 30.);
2324 V1new = Max(V1new, -1.e10);
2325 V2new = Min(V2new, 1.e10);
2331 V1new = Max(V1new, -1.e10);
2332 V2new = Min(V2new, 1.e10);
2335 //=======================================================================
2336 //function : EstLimForInfSurf
2338 //=======================================================================
2339 void EstLimForInfSurf(Standard_Real& U1new,
2340 Standard_Real& U2new,
2341 Standard_Real& V1new,
2342 Standard_Real& V2new)
2344 U1new = Max(U1new, -1.e10);
2345 U2new = Min(U2new, 1.e10);
2346 V1new = Max(V1new, -1.e10);
2347 V2new = Min(V2new, 1.e10);
2349 //=======================================================================
2352 //=======================================================================
2353 Standard_Boolean DoTrim(const TheCurve& curve,
2354 const TheSurface& surface)
2356 Standard_Boolean isAnaCurve, isAnaSurface, result;
2357 GeomAbs_CurveType aCT;
2358 GeomAbs_SurfaceType aST;
2360 isAnaCurve = Standard_False;
2361 isAnaSurface = Standard_False;
2363 aCT=TheCurveTool::GetType(curve);
2365 isAnaCurve= (aCT==GeomAbs_Line ||
2366 aCT==GeomAbs_Circle ||
2367 aCT==GeomAbs_Ellipse ||
2368 aCT==GeomAbs_Hyperbola ||
2369 aCT==GeomAbs_Parabola);
2371 aST=TheSurfaceTool::GetType(surface);
2372 isAnaSurface=(aST==GeomAbs_Plane ||
2373 aST==GeomAbs_Cylinder ||
2374 aST==GeomAbs_Cone ||
2375 aST==GeomAbs_Sphere ||
2376 aST==GeomAbs_Torus);
2378 result = !(isAnaCurve && isAnaSurface);
2381 Standard_Boolean isUClosed, isVClosed;
2383 isUClosed=(TheSurfaceTool::IsUClosed(surface) ||
2384 TheSurfaceTool::IsUPeriodic(surface));
2385 isVClosed=(TheSurfaceTool::IsVClosed(surface)
2386 || TheSurfaceTool::IsVPeriodic(surface));
2387 if(isUClosed && isVClosed) {
2391 //modified by NIZNHY-PKV Wed Apr 04 12:11:01 2012f
2393 Standard_Real aU0,aU1,aV0,aV1, dU, dV, dA, dB, aR, aTresh;
2396 aV0 = TheSurfaceTool::FirstVParameter(surface);
2397 aV1 = TheSurfaceTool::LastVParameter(surface);
2398 aU0 = TheSurfaceTool::FirstUParameter(surface);
2399 aU1 = TheSurfaceTool::LastUParameter(surface);
2411 if (dB<Precision::PConfusion()) {
2420 //modified by NIZNHY-PKV Wed Apr 04 12:11:03 2012t