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