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