0023008: Too many intersection vertices between line and cylinder
[occt.git] / src / IntTools / IntTools_BeanFaceIntersector.cxx
CommitLineData
7fd59977 1//
2//
3
4#include <IntTools_BeanFaceIntersector.ixx>
5
6#include <IntTools_Root.hxx>
7#include <Precision.hxx>
8#include <Extrema_POnCurv.hxx>
9#include <Extrema_POnSurf.hxx>
10#include <BRep_Tool.hxx>
11#include <Geom_Surface.hxx>
12#include <TColStd_Array1OfReal.hxx>
13#include <TColStd_Array1OfBoolean.hxx>
14#include <TColStd_ListOfInteger.hxx>
15#include <TColStd_ListIteratorOfListOfInteger.hxx>
16#include <IntTools_EdgeFace.hxx>
17#include <IntTools_ListOfCurveRangeSample.hxx>
18#include <IntTools_ListOfSurfaceRangeSample.hxx>
19#include <IntTools_ListOfBox.hxx>
20#include <IntTools_ListIteratorOfListOfBox.hxx>
21#include <IntTools_ListIteratorOfListOfCurveRangeSample.hxx>
22#include <IntTools_ListIteratorOfListOfSurfaceRangeSample.hxx>
23#include <IntTools_MapIteratorOfMapOfCurveSample.hxx>
24#include <TColgp_Array1OfPnt2d.hxx>
25
26#include <Geom_Curve.hxx>
27#include <Geom_Surface.hxx>
28#include <Geom_BSplineSurface.hxx>
29#include <GeomAdaptor_Curve.hxx>
30#include <GeomAdaptor_Surface.hxx>
31#include <Extrema_ExtCS.hxx>
32#include <Extrema_ExtPS.hxx>
33#include <IntTools.hxx>
34#include <IntTools_Context.hxx>
35#include <GeomAPI_ProjectPointOnCurve.hxx>
36#include <IntCurveSurface_HInter.hxx>
37#include <IntCurveSurface_IntersectionPoint.hxx>
38#include <IntCurveSurface_IntersectionSegment.hxx>
39#include <IntAna_QuadQuadGeo.hxx>
40#include <BRepAdaptor_HCurve.hxx>
41#include <BRepAdaptor_HSurface.hxx>
42#include <Extrema_GenLocateExtPS.hxx>
43#include <Extrema_GenExtCS.hxx>
44#include <Bnd_Box.hxx>
45#include <BndLib_AddSurface.hxx>
46#include <BndLib_Add3dCurve.hxx>
47#include <ElCLib.hxx>
48#include <ElSLib.hxx>
49
50static Standard_Boolean AdjustPeriodic(const Standard_Real U,
51 const Standard_Real UFirst,
52 const Standard_Real ULast,
53 const Standard_Real Period,
54 Standard_Real& UResult);
55
56static Standard_Boolean SetEmptyResultRange(const Standard_Real theParameter,
57 IntTools_MarkedRangeSet& theMarkedRange);
58
59// static Standard_Boolean TestCoinside(const BRepAdaptor_Curve& theCurve,
60// const BRepAdaptor_Surface& theSurface);
61
62// Modified by skv - Wed Nov 2 15:21:11 2005 Optimization Begin
63static Bnd_Box GetSurfaceBox
64 (const Handle(Geom_BSplineSurface) &theSurf,
65 const Standard_Real theFirstU,
66 const Standard_Real theLastU,
67 const Standard_Real theFirstV,
68 const Standard_Real theLastV,
69 const Standard_Real theTolerance,
70 IntTools_SurfaceRangeLocalizeData &theSurfaceData);
71
72static void ComputeGridPoints
73 (const Handle(Geom_BSplineSurface) &theSurf,
74 const Standard_Real theFirstU,
75 const Standard_Real theLastU,
76 const Standard_Real theFirstV,
77 const Standard_Real theLastV,
78 const Standard_Real theTolerance,
79 IntTools_SurfaceRangeLocalizeData &theSurfaceData);
80
81static void BuildBox(const Handle(Geom_BSplineSurface) &theSurf,
82 const Standard_Real theFirstU,
83 const Standard_Real theLastU,
84 const Standard_Real theFirstV,
85 const Standard_Real theLastV,
86 IntTools_SurfaceRangeLocalizeData &theSurfaceData,
87 Bnd_Box &theBox);
88// Modified by skv - Wed Nov 2 15:21:11 2005 Optimization End
89
90static void MergeSolutions(const IntTools_ListOfCurveRangeSample& theListCurveRange,
91 const IntTools_ListOfSurfaceRangeSample& theListSurfaceRange,
92 IntTools_ListOfCurveRangeSample& theListCurveRangeSort,
93 IntTools_ListOfSurfaceRangeSample& theListSurfaceRangeSort);
94
95static void CheckSampling(const IntTools_CurveRangeSample& theCurveRange,
96 const IntTools_SurfaceRangeSample& theSurfaceRange,
97 const IntTools_CurveRangeLocalizeData& theCurveData,
98 const IntTools_SurfaceRangeLocalizeData& theSurfaceData,
99 const Standard_Real DiffC,
100 const Standard_Real DiffU,
101 const Standard_Real DiffV,
102 Standard_Boolean& bAllowSamplingC,
103 Standard_Boolean& bAllowSamplingU,
104 Standard_Boolean& bAllowSamplingV);
105// ==================================================================================
106// function: IntTools_BeanFaceIntersector
107// purpose:
108// ==================================================================================
109IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector() :
110myFirstParameter(0.),
111myLastParameter(0.),
112myUMinParameter(0.),
113myUMaxParameter(0.),
114myVMinParameter(0.),
115myVMaxParameter(0.),
116myBeanTolerance(0.),
117myFaceTolerance(0.),
118myDeflection(0.01),
119myIsDone(Standard_False)
120{
121 myCriteria = Precision::Confusion();
122 myCurveResolution = Precision::PConfusion();
4f189102 123
7fd59977 124}
125
126// ==================================================================================
127// function: IntTools_BeanFaceIntersector
128// purpose:
129// ==================================================================================
130IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const TopoDS_Edge& theEdge,
131 const TopoDS_Face& theFace) :
132myFirstParameter(0.),
133myLastParameter(0.),
134myUMinParameter(0.),
135myUMaxParameter(0.),
136myVMinParameter(0.),
137myVMaxParameter(0.),
138myBeanTolerance(0.),
139myFaceTolerance(0.),
140myDeflection(0.01),
141myIsDone(Standard_False)
142{
7fd59977 143 Init(theEdge, theFace);
144}
145
146// ==================================================================================
147// function: IntTools_BeanFaceIntersector
148// purpose:
149// ==================================================================================
150IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const BRepAdaptor_Curve& theCurve,
151 const BRepAdaptor_Surface& theSurface,
152 const Standard_Real theBeanTolerance,
153 const Standard_Real theFaceTolerance) :
154myFirstParameter(0.),
155myLastParameter(0.),
156myUMinParameter(0.),
157myUMaxParameter(0.),
158myVMinParameter(0.),
159myVMaxParameter(0.),
160myDeflection(0.01),
161myIsDone(Standard_False)
162{
7fd59977 163 Init(theCurve, theSurface, theBeanTolerance, theFaceTolerance);
164}
165
166// ==================================================================================
167// function: IntTools_BeanFaceIntersector
168// purpose:
169// ==================================================================================
170IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const BRepAdaptor_Curve& theCurve,
171 const BRepAdaptor_Surface& theSurface,
172 const Standard_Real theFirstParOnCurve,
173 const Standard_Real theLastParOnCurve,
174 const Standard_Real theUMinParameter,
175 const Standard_Real theUMaxParameter,
176 const Standard_Real theVMinParameter,
177 const Standard_Real theVMaxParameter,
178 const Standard_Real theBeanTolerance,
179 const Standard_Real theFaceTolerance) :
180myFirstParameter(theFirstParOnCurve),
181myLastParameter(theLastParOnCurve),
182myUMinParameter(theUMinParameter),
183myUMaxParameter(theUMaxParameter),
184myVMinParameter(theVMinParameter),
185myVMaxParameter(theVMaxParameter),
186myBeanTolerance(theBeanTolerance),
187myFaceTolerance(theFaceTolerance),
188myDeflection(0.01),
189myIsDone(Standard_False)
190{
191 myCurve = theCurve;
192
193 myCriteria = myBeanTolerance + myFaceTolerance;
194 myCurveResolution = myCurve.Resolution(myCriteria);
195
196 mySurface = theSurface;
197 myTrsfSurface = Handle(Geom_Surface)::DownCast(mySurface.Surface().Surface()->Transformed(mySurface.Trsf()));
7fd59977 198}
199
200// ==================================================================================
201// function: Init
202// purpose:
203// ==================================================================================
204void IntTools_BeanFaceIntersector::Init(const TopoDS_Edge& theEdge,
205 const TopoDS_Face& theFace)
206{
207 myCurve.Initialize(theEdge);
208 mySurface.Initialize(theFace);
209 myTrsfSurface = Handle(Geom_Surface)::DownCast(mySurface.Surface().Surface()->Transformed(mySurface.Trsf()));
210 myBeanTolerance = BRep_Tool::Tolerance(theEdge);
211 myFaceTolerance = BRep_Tool::Tolerance(theFace);
212
213 myCriteria = myBeanTolerance + myFaceTolerance;
214 myCurveResolution = myCurve.Resolution(myCriteria);
215
216 SetSurfaceParameters(mySurface.FirstUParameter(), mySurface.LastUParameter(),
217 mySurface.FirstVParameter(), mySurface.LastVParameter());
218 myResults.Clear();
7fd59977 219}
220
221// ==================================================================================
222// function: Init
223// purpose:
224// ==================================================================================
225void IntTools_BeanFaceIntersector::Init(const BRepAdaptor_Curve& theCurve,
226 const BRepAdaptor_Surface& theSurface,
227 const Standard_Real theBeanTolerance,
228 const Standard_Real theFaceTolerance)
229{
230 myCurve = theCurve;
231 mySurface = theSurface;
232 myTrsfSurface = Handle(Geom_Surface)::DownCast(mySurface.Surface().Surface()->Transformed(mySurface.Trsf()));
233 myBeanTolerance = theBeanTolerance;
234 myFaceTolerance = theFaceTolerance;
235
236 myCriteria = myBeanTolerance + myFaceTolerance;
237 myCurveResolution = myCurve.Resolution(myCriteria);
238
239 SetSurfaceParameters(mySurface.FirstUParameter(), mySurface.LastUParameter(),
240 mySurface.FirstVParameter(), mySurface.LastVParameter());
241 myResults.Clear();
7fd59977 242}
243
244// ==================================================================================
245// function: Init
246// purpose:
247// ==================================================================================
248void IntTools_BeanFaceIntersector::Init(const BRepAdaptor_Curve& theCurve,
249 const BRepAdaptor_Surface& theSurface,
250 const Standard_Real theFirstParOnCurve,
251 const Standard_Real theLastParOnCurve,
252 const Standard_Real theUMinParameter,
253 const Standard_Real theUMaxParameter,
254 const Standard_Real theVMinParameter,
255 const Standard_Real theVMaxParameter,
256 const Standard_Real theBeanTolerance,
257 const Standard_Real theFaceTolerance)
258{
259 Init(theCurve, theSurface, theBeanTolerance, theFaceTolerance);
260 SetBeanParameters(theFirstParOnCurve, theLastParOnCurve);
261 SetSurfaceParameters(theUMinParameter, theUMaxParameter, theVMinParameter, theVMaxParameter);
7fd59977 262}
263
264// ==================================================================================
265// function: SetContext
266// purpose:
267// ==================================================================================
4f189102 268void IntTools_BeanFaceIntersector::SetContext(const Handle(IntTools_Context)& theContext)
7fd59977 269{
270 myContext = theContext;
271}
4f189102
P
272// ==================================================================================
273// function: Context
274// purpose:
275// ==================================================================================
276const Handle(IntTools_Context)& IntTools_BeanFaceIntersector::Context()const
277{
278 return myContext;
279}
7fd59977 280
281// ==================================================================================
282// function: SetBeanParameters
283// purpose:
284// ==================================================================================
285void IntTools_BeanFaceIntersector::SetBeanParameters(const Standard_Real theFirstParOnCurve,
286 const Standard_Real theLastParOnCurve)
287{
288 myFirstParameter = theFirstParOnCurve;
289 myLastParameter = theLastParOnCurve;
290}
291
292// ==================================================================================
293// function: SetSurfaceParameters
294// purpose:
295// ==================================================================================
296void IntTools_BeanFaceIntersector::SetSurfaceParameters(const Standard_Real theUMinParameter,
297 const Standard_Real theUMaxParameter,
298 const Standard_Real theVMinParameter,
299 const Standard_Real theVMaxParameter)
300{
301 myUMinParameter = theUMinParameter;
302 myUMaxParameter = theUMaxParameter;
303 myVMinParameter = theVMinParameter;
304 myVMaxParameter = theVMaxParameter;
305}
306
307// ==================================================================================
308// function: Perform
309// purpose:
310// ==================================================================================
311void IntTools_BeanFaceIntersector::Perform()
312{
313 myIsDone = Standard_False;
314 myResults.Clear();
e8997bbd 315 Standard_Boolean bRet;
316 Standard_Integer aDiscretization = 30;
7fd59977 317 Standard_Real aRelativeDeflection = 0.01;
318 myDeflection = aRelativeDeflection;
4f189102
P
319 //
320 if (myContext.IsNull()) {
321 myContext=new IntTools_Context;
322 }
323 //
7fd59977 324 if(myCurve.GetType()==GeomAbs_Line && mySurface.GetType()==GeomAbs_Plane) {
325 ComputeLinePlane();
326 return;
327 }
328
329 if(myCurve.GetType()==GeomAbs_Line) {
330 aDiscretization = 3;
331 myDeflection = Precision::Confusion();
332 }
333 else {
334 if(myCurve.GetType()==GeomAbs_Circle) {
335 aDiscretization = 23;
336 Standard_Real R = myCurve.Circle().Radius();
337 myDeflection = aRelativeDeflection * R;
338 }
339 if(myCurve.GetType() == GeomAbs_Ellipse) {
340 aDiscretization = 23;
341 Standard_Real R = myCurve.Ellipse().MajorRadius();
342 myDeflection = 2 * aRelativeDeflection * R;
343 }
344 }
345// modified by NIZHNY-MKK Wed Oct 19 12:15:21 2005
346 Standard_Boolean bLocalize = Standard_False;
347
348 if(((mySurface.GetType() == GeomAbs_BSplineSurface) &&
349 ((mySurface.UDegree() > 2) || (mySurface.VDegree() > 2)) &&
350 //modified by NIZNHY-PKV Wed Feb 25 15:02:00 2009f
351 //((mySurface.NbUKnots() > 2) || (mySurface.NbVKnots() > 2))) ||
352 ((mySurface.NbUKnots() > 2) && (mySurface.NbVKnots() > 2))) ||
353 //modified by NIZNHY-PKV Wed Feb 25 15:02:13 2009t
354 (mySurface.GetType() == GeomAbs_BezierSurface) ||
355 (mySurface.GetType() == GeomAbs_OtherSurface)) {
356 bLocalize = Standard_True;
357 }
358
359 if(bLocalize) {
360 if(Precision::IsInfinite(myUMinParameter) ||
361 Precision::IsInfinite(myUMaxParameter) ||
362 Precision::IsInfinite(myVMinParameter) ||
363 Precision::IsInfinite(myVMaxParameter))
364 bLocalize = Standard_False;
365 }
366 Standard_Boolean bSuccessLocalize = Standard_False;
367
368 if( bLocalize) {
369 myRangeManager.SetBoundaries(myFirstParameter, myLastParameter, 0);
370 Standard_Boolean coinside = TestComputeCoinside();
371
372 if(!coinside)
373 bSuccessLocalize = ComputeLocalized();
374 }
375
376 if(!bLocalize || !bSuccessLocalize) {
377// modified by NIZHNY-MKK Wed Oct 19 12:15:26 2005.END
378
379 IntTools_CArray1OfReal aParams;
380
e8997bbd 381 if(IntTools::PrepareArgs(myCurve,
382 myLastParameter,
383 myFirstParameter,
384 aDiscretization,
385 aRelativeDeflection,
386 aParams)) {
7fd59977 387 return;
388 }
389
390 myRangeManager.SetRanges(aParams, 0);
391
392 if(myRangeManager.Length()==0) {
393 return;
394 }
e8997bbd 395 //
396 bRet=FastComputeExactIntersection();
397 if(bRet) {
7fd59977 398 IntTools_Range aRange(myFirstParameter, myLastParameter);
399 myResults.Append(aRange);
400 myIsDone = Standard_True;
401 return;
402 }
403
404
405// Standard_Boolean coinside = TestCoinside(myCurve,mySurface);
406 Standard_Boolean coinside = TestComputeCoinside();
407// if(coinside) {
408// myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2);
409// }
410// else {
411 if(!coinside) {
412 ComputeAroundExactIntersection();
413
414 ComputeUsingExtremum();
415
416 ComputeNearRangeBoundaries();
417 }
418 }
419
420 myIsDone = Standard_True;
421
422 for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
423
424 if(myRangeManager.Flag(i) == 2) {
425 IntTools_Range aRange = myRangeManager.Range(i);
426
427 if(myResults.Length() > 0) {
428 const IntTools_Range& aLastRange = myResults.Last();
429
430 if(Abs(aRange.First() - aLastRange.Last()) > Precision::PConfusion()) {
431 myResults.Append(aRange);
432 }
433 else {
434 myResults.ChangeValue(myResults.Length()).SetLast(aRange.Last());
435 }
436 }
437 else {
438 myResults.Append(aRange);
439 }
440 }
441 }
442}
443
444// ==================================================================================
445// function: Result
446// purpose:
447// ==================================================================================
448const IntTools_SequenceOfRanges& IntTools_BeanFaceIntersector::Result() const
449{
450 return myResults;
451}
452
453// ==================================================================================
454// function: Result
455// purpose:
456// ==================================================================================
457void IntTools_BeanFaceIntersector::Result(IntTools_SequenceOfRanges& theResults) const
458{
459 theResults = myResults;
460}
461
462// ==================================================================================
463// function: Distance
464// purpose:
465// ==================================================================================
466Standard_Real IntTools_BeanFaceIntersector::Distance(const Standard_Real theArg)
467{
468 gp_Pnt aPoint = myCurve.Value(theArg);
469
4f189102
P
470 GeomAPI_ProjectPointOnSurf& aProjector = myContext->ProjPS(mySurface.Face());
471 aProjector.Perform(aPoint);
472
473 if(aProjector.IsDone() && aProjector.NbPoints() > 0) {
474 return aProjector.LowerDistance();
7fd59977 475 }
476 //
477 Standard_Real aDistance = RealLast();
478
479 for(Standard_Integer i=0; i < 4; i++) {
480 Standard_Real anIsoParameter = (i==0) ? myUMinParameter : ((i==1) ? myUMaxParameter : ((i==2) ? myVMinParameter : myVMaxParameter));
481 Standard_Real aMinParameter = (i < 2) ? myVMinParameter : myUMinParameter;
482 Standard_Real aMaxParameter = (i < 2) ? myVMaxParameter : myUMaxParameter;
483 Standard_Real aMidParameter = (aMinParameter + aMaxParameter) * 0.5;
484 gp_Pnt aPointMin = (i < 2) ? mySurface.Value(anIsoParameter, aMinParameter) : mySurface.Value(aMinParameter, anIsoParameter);
485 gp_Pnt aPointMax = (i < 2) ? mySurface.Value(anIsoParameter, aMaxParameter) : mySurface.Value(aMaxParameter, anIsoParameter);
486 gp_Pnt aPointMid = (i < 2) ? mySurface.Value(anIsoParameter, aMidParameter) : mySurface.Value(aMidParameter, anIsoParameter);
487
488 Standard_Boolean useMinMaxPoints = Standard_True;
489 Standard_Boolean computeisoline = Standard_True;
490
491 if(aPointMin.IsEqual(aPointMax, myCriteria) &&
492 aPointMin.IsEqual(aPointMid, myCriteria) &&
493 aPointMax.IsEqual(aPointMid, myCriteria)) {
494 computeisoline = Standard_False;
495 }
496
497 if(computeisoline) {
498 Handle(Geom_Curve) aCurve = (i < 2) ? myTrsfSurface->UIso(anIsoParameter) : myTrsfSurface->VIso(anIsoParameter);
499 GeomAPI_ProjectPointOnCurve aProjectorOnCurve(aPoint, aCurve, aMinParameter, aMaxParameter);
500
501 if(aProjectorOnCurve.NbPoints() > 0) {
502 useMinMaxPoints = Standard_False;
503
504 if(aDistance > aProjectorOnCurve.LowerDistance())
505 aDistance = aProjectorOnCurve.LowerDistance();
506 }
507 }
508
509 if(useMinMaxPoints) {
510 Standard_Real aPPDistance = aPoint.Distance(aPointMin);
511 aDistance = (aPPDistance < aDistance) ? aPPDistance : aDistance;
512 aPPDistance = aPoint.Distance(aPointMax);
513 aDistance = (aPPDistance < aDistance) ? aPPDistance : aDistance;
514 }
515 }
516 return aDistance;
517}
518
519
520// ==================================================================================
521// function: Distance
522// purpose:
523// ==================================================================================
524Standard_Real IntTools_BeanFaceIntersector::Distance(const Standard_Real theArg,
525 Standard_Real& theUParameter,
526 Standard_Real& theVParameter)
527{
528 gp_Pnt aPoint = myCurve.Value(theArg);
529
530 theUParameter = myUMinParameter;
531 theVParameter = myVMinParameter;
532 //
533 Standard_Real aDistance = RealLast();
534 Standard_Boolean projectionfound = Standard_False;
535
4f189102
P
536 GeomAPI_ProjectPointOnSurf& aProjector = myContext->ProjPS(mySurface.Face());
537 aProjector.Perform(aPoint);
538
539 if(aProjector.IsDone() && aProjector.NbPoints() > 0) {
540 aProjector.LowerDistanceParameters(theUParameter, theVParameter);
541 aDistance = aProjector.LowerDistance();
542 projectionfound = Standard_True;
7fd59977 543 }
4f189102 544
7fd59977 545 if(!projectionfound) {
546 //
547 for(Standard_Integer i = 0; i < 4; i++) {
548 Standard_Real anIsoParameter = (i==0) ? myUMinParameter : ((i==1) ? myUMaxParameter : ((i==2) ? myVMinParameter : myVMaxParameter));
549 Standard_Real aMinParameter = (i < 2) ? myVMinParameter : myUMinParameter;
550 Standard_Real aMaxParameter = (i < 2) ? myVMaxParameter : myUMaxParameter;
551 Standard_Real aMidParameter = (aMinParameter + aMaxParameter) * 0.5;
552 gp_Pnt aPointMin = (i < 2) ? mySurface.Value(anIsoParameter, aMinParameter) : mySurface.Value(aMinParameter, anIsoParameter);
553 gp_Pnt aPointMax = (i < 2) ? mySurface.Value(anIsoParameter, aMaxParameter) : mySurface.Value(aMaxParameter, anIsoParameter);
554 gp_Pnt aPointMid = (i < 2) ? mySurface.Value(anIsoParameter, aMidParameter) : mySurface.Value(aMidParameter, anIsoParameter);
555
556 Standard_Boolean useMinMaxPoints = Standard_True;
557 Standard_Boolean computeisoline = Standard_True;
558
559 if(aPointMin.IsEqual(aPointMax, myCriteria) &&
560 aPointMin.IsEqual(aPointMid, myCriteria) &&
561 aPointMax.IsEqual(aPointMid, myCriteria)) {
562 computeisoline = Standard_False;
563 }
564
565 if(computeisoline) {
566 Handle(Geom_Curve) aCurve = (i < 2) ? myTrsfSurface->UIso(anIsoParameter) : myTrsfSurface->VIso(anIsoParameter);
567 GeomAPI_ProjectPointOnCurve aProjectorOnCurve(aPoint, aCurve, aMinParameter, aMaxParameter);
568
569 if(aProjectorOnCurve.NbPoints() > 0) {
570 useMinMaxPoints = Standard_False;
571
572 if(aDistance > aProjectorOnCurve.LowerDistance()) {
573 theUParameter = (i<=1) ? anIsoParameter : aProjectorOnCurve.LowerDistanceParameter();
574 theVParameter = (i>=2) ? anIsoParameter : aProjectorOnCurve.LowerDistanceParameter();
575 aDistance = aProjectorOnCurve.LowerDistance();
576 }
577 }
578 }
579
580 if(useMinMaxPoints) {
581 Standard_Real aPPDistance = aPoint.Distance(aPointMin);
582
583 if(aPPDistance < aDistance) {
584 theUParameter = (i<=1) ? anIsoParameter : aMinParameter;
585 theVParameter = (i>=2) ? anIsoParameter : aMinParameter;
586 aDistance = aPPDistance;
587 }
588 aPPDistance = aPoint.Distance(aPointMax);
589
590 if(aPPDistance < aDistance) {
591 theUParameter = (i<=1) ? anIsoParameter : aMaxParameter;
592 theVParameter = (i>=2) ? anIsoParameter : aMaxParameter;
593 aDistance = aPPDistance;
594 }
595 }
596 }
597 }
598 theUParameter = (myUMinParameter > theUParameter) ? myUMinParameter : theUParameter;
599 theUParameter = (myUMaxParameter < theUParameter) ? myUMaxParameter : theUParameter;
600 theVParameter = (myVMinParameter > theVParameter) ? myVMinParameter : theVParameter;
601 theVParameter = (myVMaxParameter < theVParameter) ? myVMaxParameter : theVParameter;
602
603 return aDistance;
604}
605
606// ==================================================================================
607// function: ComputeAroundExactIntersection
608// purpose:
609// ==================================================================================
610void IntTools_BeanFaceIntersector::ComputeAroundExactIntersection()
611{
612 IntCurveSurface_HInter anExactIntersector;
613
614 Handle(BRepAdaptor_HCurve) aCurve = new BRepAdaptor_HCurve(myCurve);
615 Handle(BRepAdaptor_HSurface) aSurface = new BRepAdaptor_HSurface(mySurface);
616
617 anExactIntersector.Perform(aCurve, aSurface);
618
619 if(anExactIntersector.IsDone()) {
620 Standard_Integer i = 0;
621
622 for(i = 1; i <= anExactIntersector.NbPoints(); i++) {
623 const IntCurveSurface_IntersectionPoint& aPoint = anExactIntersector.Point(i);
624
625 if((aPoint.W() >= myFirstParameter) && (aPoint.W() <= myLastParameter)) {
626 Standard_Boolean UIsNotValid = ((myUMinParameter > aPoint.U()) || (aPoint.U() > myUMaxParameter));
627 Standard_Boolean VIsNotValid = ((myVMinParameter > aPoint.V()) || (aPoint.V() > myVMaxParameter));
628 Standard_Boolean solutionIsValid = !UIsNotValid && !VIsNotValid;
629 Standard_Real U = aPoint.U();
630 Standard_Real V = aPoint.V();
631
632 if(UIsNotValid || VIsNotValid) {
633// modified by NIZHNY-MKK Thu Jun 17 12:50:39 2004
634 Standard_Boolean bUCorrected = Standard_True;
635
636 if(UIsNotValid) {
637// modified by NIZHNY-MKK Thu Jun 17 12:50:37 2004
638 bUCorrected = Standard_False;
639 solutionIsValid = Standard_False;
640
641 if(mySurface.IsUPeriodic()) {
642 Standard_Real aNewU = U;
643
644 if(AdjustPeriodic(U, myUMinParameter, myUMaxParameter, mySurface.UPeriod(), aNewU)) {
645 solutionIsValid = Standard_True;
646// modified by NIZHNY-MKK Thu Jun 17 12:51:01 2004
647 bUCorrected = Standard_True;
648 U = aNewU;
649 }
650 }
651 }
652 // modified by NIZHNY-MKK Thu Jun 17 12:51:03 2004
653// if(solutionIsValid && VIsNotValid) {
654 if(bUCorrected && VIsNotValid) {
655 solutionIsValid = Standard_False;
656
657 if(mySurface.IsVPeriodic()) {
658 Standard_Real aNewV = V;
659
660 if(AdjustPeriodic(V, myVMinParameter, myVMaxParameter, mySurface.VPeriod(), aNewV)) {
661 solutionIsValid = Standard_True;
662 V = aNewV;
663 }
664 }
665 }
666 }
667
668 if(!solutionIsValid)
669 continue;
670
671 Standard_Integer aNbRanges = myRangeManager.Length();
672
673 ComputeRangeFromStartPoint(Standard_False, aPoint.W(), U, V);
674 ComputeRangeFromStartPoint(Standard_True, aPoint.W(), U, V);
675
676 if(aNbRanges == myRangeManager.Length()) {
677 SetEmptyResultRange(aPoint.W(), myRangeManager);
678 } // end if(aNbRanges == myRangeManager.Length())
679 }
680 }
681
682 for(i = 1; i <= anExactIntersector.NbSegments(); i++) {
683 const IntCurveSurface_IntersectionSegment& aSegment = anExactIntersector.Segment(i);
684 IntCurveSurface_IntersectionPoint aPoint1, aPoint2;
685 aSegment.Values(aPoint1, aPoint2);
686
687 Standard_Real aFirstParameter = (aPoint1.W() < myFirstParameter) ? myFirstParameter : aPoint1.W();
688 Standard_Real aLastParameter = (myLastParameter < aPoint2.W()) ? myLastParameter : aPoint2.W();
689
690 myRangeManager.InsertRange(aFirstParameter, aLastParameter, 2);
691
692 ComputeRangeFromStartPoint(Standard_False, aPoint1.W(), aPoint1.U(), aPoint1.V());
693 ComputeRangeFromStartPoint(Standard_True, aPoint2.W(), aPoint2.U(), aPoint2.V());
694 }
695 }
696}
697
698// ==================================================================================
699// function: FastComputeExactIntersection
700// purpose:
701// ==================================================================================
702Standard_Boolean IntTools_BeanFaceIntersector::FastComputeExactIntersection()
703{
e8997bbd 704 Standard_Boolean aresult;
705 GeomAbs_CurveType aCT;
706 GeomAbs_SurfaceType aST;
707 //
708 aresult = Standard_False;
709 aCT=myCurve.GetType();
710 aST=mySurface.GetType();
711 //
712 if((aCT==GeomAbs_BezierCurve) ||
713 (aCT==GeomAbs_BSplineCurve) ||
714 (aCT==GeomAbs_OtherCurve)) {
7fd59977 715 return aresult;
716 }
717
e8997bbd 718 if(aST==GeomAbs_Plane) {
7fd59977 719 gp_Pln surfPlane = mySurface.Plane();
720
e8997bbd 721 if(aCT==GeomAbs_Line) {
7fd59977 722 if((surfPlane.Distance(myCurve.Value(myFirstParameter)) < myCriteria) &&
723 (surfPlane.Distance(myCurve.Value(myLastParameter)) < myCriteria)) {
724 myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2);
725 aresult = Standard_True;
726 }
727 }
e8997bbd 728 else { // else 1
7fd59977 729 gp_Dir aDir;
730
e8997bbd 731 switch(aCT) {
732 case GeomAbs_Circle: {
733 aDir = myCurve.Circle().Axis().Direction();
734 break;
735 }
736 case GeomAbs_Ellipse: {
737 aDir = myCurve.Ellipse().Axis().Direction();
738 break;
739 }
740 case GeomAbs_Hyperbola: {
741 aDir = myCurve.Hyperbola().Axis().Direction();
742 break;
743 }
744 case GeomAbs_Parabola: {
745 aDir = myCurve.Parabola().Axis().Direction();
746 break;
747 }
748 default: {
749 return aresult;
750 }
7fd59977 751 }
e8997bbd 752 //
7fd59977 753 Standard_Real anAngle = aDir.Angle(surfPlane.Axis().Direction());
754
755 if(anAngle < Precision::Angular()) {
756 Standard_Boolean insertRange = Standard_False;
757
e8997bbd 758 switch(aCT) {
759 case GeomAbs_Circle: {
760 Standard_Real adist =
761 surfPlane.Distance(myCurve.Circle().Location()) +
762 myCurve.Circle().Radius() * Precision::Angular();
763
764 if(adist < myCriteria) {
765 insertRange = Standard_True;
766 }
767 break;
7fd59977 768 }
e8997bbd 769 case GeomAbs_Ellipse: {
770 Standard_Real adist =
771 surfPlane.Distance(myCurve.Ellipse().Location()) +
772 myCurve.Ellipse().MajorRadius() * Precision::Angular();
773
774 if(adist < myCriteria) {
775 insertRange = Standard_True;
776 }
777 break;
7fd59977 778 }
e8997bbd 779 case GeomAbs_Hyperbola:
780 case GeomAbs_Parabola: {
781 Standard_Real aMaxPar =
782 (Abs(myFirstParameter) > Abs(myLastParameter)) ?
783 Abs(myFirstParameter) : Abs(myLastParameter);
784
785 gp_Pnt aLoc = (aCT == GeomAbs_Parabola) ?
786 myCurve.Parabola().Location() :
787 myCurve.Hyperbola().Location();
788 Standard_Real adist = aLoc.Distance(myCurve.Value(aMaxPar));
789 adist = surfPlane.Distance(aLoc) + adist * Precision::Angular();
790
791 if(adist < myCriteria) {
792 insertRange = Standard_True;
793 }
794 break;
795 }
796 default: {
797 break;
7fd59977 798 }
7fd59977 799 }
e8997bbd 800 //
7fd59977 801 if(insertRange) {
802 myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2);
803 aresult = Standard_True;
804 }
e8997bbd 805 }//if(anAngle < Precision::Angular()) {
806 }//else { // else 1
807 }// if(aST==GeomAbs_Plane) {
808
809 if(aCT==GeomAbs_Circle) {
7fd59977 810 gp_Circ aCircle = myCurve.Circle();
811
e8997bbd 812 if(aST==GeomAbs_Cylinder) {
7fd59977 813 gp_Cylinder aCylinder = mySurface.Cylinder();
814 gp_Dir aDir1(aCylinder.Axis().Direction());
815 gp_Dir aDir2(aCircle.Axis().Direction());
816 Standard_Real anAngle = aDir1.Angle(aDir2);
817
818 if(anAngle < Precision::Angular()) {
819 gp_Pnt aLoc = aCircle.Location();
820 gp_Lin anCylAxis(aCylinder.Axis());
821 Standard_Real alocdist = anCylAxis.Distance(aLoc);
822 Standard_Real adist = alocdist;
823 Standard_Real adiff = aCircle.Radius() - aCylinder.Radius();
824 adist += Abs(adiff);
825
826 if(adist < myCriteria) {
827 Standard_Real acylradius = aCylinder.Radius();
828 Standard_Real atmpvalue = aCircle.Radius() * sin(Precision::Angular());
829 Standard_Real aprojectedradius = atmpvalue;
e8997bbd 830 aprojectedradius =
831 sqrt((aCircle.Radius() * aCircle.Radius())
832 - (aprojectedradius * aprojectedradius));
7fd59977 833 adiff = aprojectedradius - acylradius;
834 adist = alocdist + Abs(adiff);
835
836 if(adist < myCriteria) { // Abs is important function here
837 myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2);
838 aresult = Standard_True;
839 }
840 }
841 }
e8997bbd 842 }// if(aST==GeomAbs_Cylinder)
7fd59977 843
e8997bbd 844 if(aST==GeomAbs_Sphere) {
7fd59977 845 gp_Pln aCirclePln(aCircle.Location(), aCircle.Axis().Direction());
846 IntAna_QuadQuadGeo anInter(aCirclePln, mySurface.Sphere());
847
848 if(anInter.IsDone()) {
849 if(anInter.TypeInter() == IntAna_Circle) {
850 gp_Circ aCircleToCompare = anInter.Circle(1);
e8997bbd 851 Standard_Real adist =
852 aCircleToCompare.Location().Distance(aCircle.Location());
7fd59977 853 Standard_Real adiff = aCircle.Radius() - aCircleToCompare.Radius();
854 adist += Abs(adiff);
855
856 if(adist < myCriteria) {
857 myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2);
858 aresult = Standard_True;
859 }
860 }
861 }
e8997bbd 862 }// if(aST==GeomAbs_Sphere) {
863 }// if(aCT==GeomAbs_Circle) {
864 //
865 //modified by NIZNHY-PKV Thu Mar 01 11:54:04 2012f
866 if(aST==GeomAbs_Cylinder) {
867 Standard_Real aRC;
868 gp_Cylinder aCyl;
869 //
870 aCyl=mySurface.Cylinder();
871 aRC=aCyl.Radius();
872 const gp_Ax1& aAx1C=aCyl.Axis();
873 const gp_Dir& aDirC=aAx1C.Direction();
874 //
875 if(aCT==GeomAbs_Line) {
876 Standard_Real aCos, aAng2, aTolang2;
877 gp_Lin aLin;
878 //
879 aTolang2=1.e-16;
880 aLin=myCurve.Line();
881 const gp_Dir& aDirL=aLin.Direction();
882 const gp_Pnt& aLocL=aLin.Location();
883 //
884 aCos=aDirC.Dot(aDirL);
885 if(aCos >= 0.) {
886 aAng2 = 2.*(1. - aCos);
887 }
888 else {
889 aAng2 = 2.*(1. + aCos);
890 }
891 //
892 if(aAng2<=aTolang2) {// IsParallel = Standard_True;
893 Standard_Boolean bFlag;
894 Standard_Integer i;
895 Standard_Real aD;
896 gp_Pnt aPL[2];
897 gp_Lin aLC(aAx1C);
898 //
899 aPL[0]=myCurve.Value(myFirstParameter);
900 aPL[1]=myCurve.Value(myLastParameter);
901 //
902 for (i=0; i<2; ++i) {
903 aD=aLC.Distance(aPL[i]);
904 aD=fabs(aD-aRC);
905 bFlag=(aD > myCriteria);
906 if (bFlag) {
907 break;
908 }
909 }
910 //
911 if (!bFlag){
912 myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2);
913 aresult = Standard_True;
914 return aresult;
915 }
916 }
917
918 }//if(aCT==GeomAbs_Line) {
7fd59977 919 }
e8997bbd 920 //modified by NIZNHY-PKV Thu Mar 01 11:54:06 2012t
7fd59977 921 return aresult;
922}
923
924// ==================================================================================
925// function: ComputeLinePlane
926// purpose:
927// ==================================================================================
928void IntTools_BeanFaceIntersector::ComputeLinePlane()
929{
930 Standard_Real Tolang = 1.e-9;
931 gp_Pln P = mySurface.Plane();
932 gp_Lin L = myCurve.Line();
933
934 myIsDone = Standard_True;
935
936 Standard_Real A,B,C,D;
937 Standard_Real Al,Bl,Cl;
938 Standard_Real Dis,Direc;
939
940 P.Coefficients(A,B,C,D);
941 gp_Pnt Orig(L.Location());
942 L.Direction().Coord(Al,Bl,Cl);
943
944 Direc=A*Al+B*Bl+C*Cl;
945 Dis = A*Orig.X() + B*Orig.Y() + C*Orig.Z() + D;
946
947 Standard_Boolean parallel = Standard_False, inplane = Standard_False;
948 if (Abs(Direc) < Tolang) {
949 parallel= Standard_True;
950 if (Abs(Dis) < myCriteria) {
951 inplane=Standard_True;
952 }
953 else {
954 inplane=Standard_False;
955 }
956 }
957 else {
958 gp_Pnt p1 = ElCLib::Value(myFirstParameter, L);
959 gp_Pnt p2 = ElCLib::Value(myLastParameter, L);
960 Standard_Real d1 = A*p1.X() + B*p1.Y() + C*p1.Z() + D;
961 if(d1 < 0) d1 = -d1;
962 Standard_Real d2 = A*p2.X() + B*p2.Y() + C*p2.Z() + D;
963 if(d2 < 0) d2 = -d2;
964 if(d1 <= myCriteria && d2 <= myCriteria) {
965 inplane=Standard_True;
966 }
967 }
968
969 if(inplane) {
970 IntTools_Range aRange(myFirstParameter, myLastParameter);
971 myResults.Append(aRange);
972 return;
973 }
974
975 if(parallel) {
976 return;
977 }
978
979 Standard_Real t = - Dis/Direc;
980 if(t < myFirstParameter || t > myLastParameter) {
981 return;
982 }
983
984 gp_Pnt pint(Orig.X()+t*Al, Orig.Y()+t*Bl, Orig.Z()+t*Cl);
985
986 Standard_Real u, v;
987 ElSLib::Parameters(P, pint, u, v);
988 if(myUMinParameter > u || u > myUMaxParameter || myVMinParameter > v || v > myVMaxParameter) {
989 return;
990 }
991
992 Standard_Real t1 = Max(myFirstParameter, t-myCriteria);
993 Standard_Real t2 = Min(myLastParameter, t+myCriteria);
994 IntTools_Range aRange(t1, t2);
995 myResults.Append(aRange);
996
997 return;
998
999}
1000
1001
1002// ==================================================================================
1003// function: ComputeUsingExtremum
1004// purpose:
1005// ==================================================================================
1006void IntTools_BeanFaceIntersector::ComputeUsingExtremum()
1007{
1008 Standard_Real Tol, af, al;
1009 Tol = Precision::PConfusion();
1010 Handle(Geom_Curve) aCurve = BRep_Tool::Curve (myCurve.Edge(), af, al);
1011 GeomAdaptor_Surface aGASurface (myTrsfSurface,
1012 myUMinParameter,
1013 myUMaxParameter,
1014 myVMinParameter,
1015 myVMaxParameter);
1016
1017 Bnd_Box FBox;
1018 BndLib_AddSurface::Add(mySurface, 0., FBox);
1019 FBox.Enlarge(myFaceTolerance);
1020
1021 for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
1022
1023 if(myRangeManager.Flag(i) > 0)
1024 continue;
1025
1026 IntTools_Range aParamRange = myRangeManager.Range(i);
1027 Standard_Real anarg1 = aParamRange.First();
1028 Standard_Real anarg2 = aParamRange.Last();
1029
1030 if(anarg2 - anarg1 < Precision::PConfusion()) {
1031
1032 if(((i > 1) && (myRangeManager.Flag(i-1) == 2)) ||
1033 ((i < myRangeManager.Length()) && (myRangeManager.Flag(i+1) == 2))) {
1034 myRangeManager.SetFlag(i, 1);
1035 continue;
1036 }
1037 }
1038
1039 // check bounding boxes
1040 Bnd_Box EBox;
1041 EBox.Add(myCurve.Value(anarg1));
1042 EBox.Add(myCurve.Value(anarg2));
1043 EBox.Enlarge(myBeanTolerance + myDeflection);
1044
1045 if(EBox.IsOut(FBox)) {
1046 myRangeManager.SetFlag(i, 1);
1047 continue;
1048 }
1049
1050 GeomAdaptor_Curve aGACurve(aCurve, anarg1, anarg2);
1051 Extrema_ExtCS theExtCS(aGACurve, aGASurface, Tol, Tol);
1052 myExtrema = theExtCS;
1053
1054 if(myExtrema.IsDone() && (myExtrema.NbExt() || myExtrema.IsParallel())) {
1055 Standard_Integer anOldNbRanges = myRangeManager.Length();
1056
1057 if (myExtrema.IsParallel()) {
1058
1059 if(myExtrema.SquareDistance(1) < myCriteria * myCriteria) {
1060 Standard_Real U1, V1, U2, V2;
1061 Standard_Real adistance1 = Distance(anarg1, U1, V1);
1062 Standard_Real adistance2 = Distance(anarg2, U2, V2);
1063 Standard_Boolean validdistance1 = (adistance1 < myCriteria);
1064 Standard_Boolean validdistance2 = (adistance2 < myCriteria);
1065
1066 if (validdistance1 && validdistance2) {
1067 myRangeManager.InsertRange(anarg1, anarg2, 2);
1068 continue;
1069 }
1070 else {
1071 if(validdistance1) {
1072 ComputeRangeFromStartPoint(Standard_True, anarg1, U1, V1);
1073 }
1074 else {
1075 if(validdistance2) {
1076 ComputeRangeFromStartPoint(Standard_False, anarg2, U2, V2);
1077 }
1078 else {
1079 Standard_Real a = anarg1;
1080 Standard_Real b = anarg2;
1081 Standard_Real da = adistance1;
1082 Standard_Real db = adistance2;
1083 Standard_Real asolution = a;
1084 Standard_Boolean found = Standard_False;
1085
1086 while(((b - a) > myCurveResolution) && !found) {
1087 asolution = (a+b)*0.5;
1088 Standard_Real adist = Distance(asolution, U1, V1);
1089
1090 if(adist < myCriteria) {
1091 found = Standard_True;
1092 }
1093 else {
1094 if(da < db) {
1095 b = asolution;
1096 db = adist;
1097 }
1098 else {
1099 a = asolution;
1100 da = adist;
1101 }
1102 }
1103 } // end while
1104
1105 if(found) {
1106 ComputeRangeFromStartPoint(Standard_False, asolution, U1, V1);
1107 ComputeRangeFromStartPoint(Standard_True, asolution, U1, V1);
1108 }
1109 else {
1110 myRangeManager.SetFlag(i, 1);
1111 }
1112 }
1113 }
1114 }
1115 }
1116 else {
1117 myRangeManager.SetFlag(i, 1);
1118 }
1119 }
1120 else {
1121 Standard_Boolean solutionfound = Standard_False;
1122
1123 for(Standard_Integer j = 1 ; j <= myExtrema.NbExt(); j++) {
1124
1125 if(myExtrema.SquareDistance(j) < myCriteria * myCriteria) {
1126 Extrema_POnCurv p1;
1127 Extrema_POnSurf p2;
1128 myExtrema.Points(j, p1, p2);
1129 Standard_Real U, V;
1130 p2.Parameter(U, V);
1131
1132 Standard_Integer aNbRanges = myRangeManager.Length();
1133 ComputeRangeFromStartPoint(Standard_False, p1.Parameter(), U, V);
1134 ComputeRangeFromStartPoint(Standard_True, p1.Parameter(), U, V);
1135 solutionfound = Standard_True;
1136
1137 if(aNbRanges == myRangeManager.Length()) {
1138 SetEmptyResultRange(p1.Parameter(), myRangeManager);
1139 }
1140 }
1141 } //end for
1142
1143 if(!solutionfound) {
1144 myRangeManager.SetFlag(i, 1);
1145 }
1146 }
1147 Standard_Integer adifference = myRangeManager.Length() - anOldNbRanges;
1148
1149 if(adifference > 0) {
1150 i+=adifference;
1151 }
1152 } // end if(myExtrema.IsDone() && (myExtrema.NbExt() || myExtrema.IsParallel()))
1153 }
1154}
1155
1156// ==================================================================================
1157// function: ComputeNearRangeBoundaries
1158// purpose:
1159// ==================================================================================
1160void IntTools_BeanFaceIntersector::ComputeNearRangeBoundaries()
1161{
1162 Standard_Real U = myUMinParameter;
1163 Standard_Real V = myVMinParameter;
1164
1165 for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
1166
1167 if(myRangeManager.Flag(i) > 0)
1168 continue;
1169
1170 if((i > 1) && (myRangeManager.Flag(i-1) > 0))
1171 continue;
1172
1173 IntTools_Range aParamRange = myRangeManager.Range(i);
1174
1175 if(Distance(aParamRange.First(), U, V) < myCriteria) {
1176 Standard_Integer aNbRanges = myRangeManager.Length();
1177
1178 if(i > 1) {
1179 ComputeRangeFromStartPoint(Standard_False, aParamRange.First(), U, V, i-1);
1180 }
1181 ComputeRangeFromStartPoint(Standard_True, aParamRange.First(), U, V, i + (myRangeManager.Length() - aNbRanges));
1182
1183 if(aNbRanges == myRangeManager.Length()) {
1184 SetEmptyResultRange(aParamRange.First(), myRangeManager);
1185 }
1186 }
1187 }
1188
1189 if(myRangeManager.Flag(myRangeManager.Length()) == 0) {
1190 IntTools_Range aParamRange = myRangeManager.Range(myRangeManager.Length());
1191
1192 if(Distance(aParamRange.Last(), U, V) < myCriteria) {
1193 Standard_Integer aNbRanges = myRangeManager.Length();
1194
1195 ComputeRangeFromStartPoint(Standard_False, aParamRange.Last(), U, V, myRangeManager.Length());
1196
1197 if(aNbRanges == myRangeManager.Length()) {
1198 SetEmptyResultRange(aParamRange.Last(), myRangeManager);
1199 }
1200 }
1201 }
1202}
1203
1204// ==================================================================================
1205// function: ComputeRangeFromStartPoint
1206// purpose: Compute range using start point according to parameter theParameter,
1207// increasing parameter on curve if ToIncreaseParameter == Standard_True or
1208// decreasing parameter on curve if ToIncreaseParameter == Standard_False
1209// ==================================================================================
1210void IntTools_BeanFaceIntersector::ComputeRangeFromStartPoint(const Standard_Boolean ToIncreaseParameter,
1211 const Standard_Real theParameter,
1212 const Standard_Real theUParameter,
1213 const Standard_Real theVParameter)
1214{
1215 Standard_Integer aFoundIndex = myRangeManager.GetIndex(theParameter, ToIncreaseParameter);
1216
1217 if(aFoundIndex == 0) {
1218 return;
1219 }
1220
1221 ComputeRangeFromStartPoint(ToIncreaseParameter, theParameter, theUParameter, theVParameter, aFoundIndex);
1222}
1223
1224// ==================================================================================
1225// function: ComputeRangeFromStartPoint
1226// purpose: Compute range using start point according to parameter theParameter,
1227// increasing parameter on curve if ToIncreaseParameter == Standard_True or
1228// decreasing parameter on curve if ToIncreaseParameter == Standard_False.
1229// theIndex indicate that theParameter belong the range number theIndex.
1230// ==================================================================================
1231void IntTools_BeanFaceIntersector::ComputeRangeFromStartPoint(const Standard_Boolean ToIncreaseParameter,
1232 const Standard_Real theParameter,
1233 const Standard_Real theUParameter,
1234 const Standard_Real theVParameter,
1235 const Standard_Integer theIndex)
1236{
1237 if(myRangeManager.Flag(theIndex) > 0)
1238 return;
1239
1240 Standard_Integer aValidIndex = theIndex;
1241
1242 Standard_Real aMinDelta = myCurveResolution * 0.5;
1243 Standard_Real aDeltaRestrictor = myLastParameter - myFirstParameter;
1244
1245 if(aMinDelta > aDeltaRestrictor)
1246 aMinDelta = aDeltaRestrictor * 0.5;
1247
1248 Standard_Real tenOfMinDelta = aMinDelta * 10.;
1249 Standard_Real aDelta = myCurveResolution;
1250
1251 Standard_Real aCurPar = (ToIncreaseParameter) ? (theParameter + aDelta) : (theParameter - aDelta);
1252 Standard_Real aPrevPar = theParameter;
1253 IntTools_Range aCurrentRange = myRangeManager.Range(aValidIndex);
1254
1255 Standard_Boolean BoundaryCondition = (ToIncreaseParameter) ? (aCurPar > aCurrentRange.Last()) : (aCurPar < aCurrentRange.First());
1256
1257 if(BoundaryCondition) {
1258 aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First();
1259 BoundaryCondition = Standard_False;
1260 }
1261
1262 Standard_Integer loopcounter = 0; // neccesary as infinite loop restricter
1263 Standard_Real U = theUParameter;
1264 Standard_Real V = theVParameter;
1265 Standard_Boolean anotherSolutionFound = Standard_False;
1266
1267 Standard_Boolean isboundaryindex = Standard_False;
1268 Standard_Boolean isvalidindex = Standard_True;
1269
1270 while((aDelta >= aMinDelta) && (loopcounter <= 10)) {
1271 Standard_Boolean pointfound = Standard_False;
1272
1273 //
1274 gp_Pnt aPoint = myCurve.Value(aCurPar);
1275 Extrema_GenLocateExtPS anExtrema(aPoint, mySurface, U, V, 1.e-10, 1.e-10);
1276
1277 if(anExtrema.IsDone()) {
1278 if(anExtrema.SquareDistance() < myCriteria * myCriteria) {
1279 Extrema_POnSurf aPOnSurf = anExtrema.Point();
1280 aPOnSurf.Parameter(U, V);
1281 pointfound = Standard_True;
1282 }
1283 }
1284 else {
1285 pointfound = (Distance(aCurPar) < myCriteria);
1286 }
1287
1288 if(pointfound) {
1289 aPrevPar = aCurPar;
1290 anotherSolutionFound = Standard_True;
1291
1292 if(BoundaryCondition && (isboundaryindex || !isvalidindex))
1293 break;
1294 }
1295 else {
1296 aDeltaRestrictor = aDelta;
1297 }
1298
1299 // if point found decide to increase aDelta using derivative of distance function
1300 //
1301
1302 aDelta = (pointfound) ? (aDelta * 2.) : (aDelta * 0.5);
1303 aDelta = (aDelta < aDeltaRestrictor) ? aDelta : aDeltaRestrictor;
1304
1305 aCurPar = (ToIncreaseParameter) ? (aPrevPar + aDelta) : (aPrevPar - aDelta);
1306
1307
1308 // prevent infinite loop when (aPrevPar +/- aDelta) == aPrevPar == 0.
1309 //
1310
1311 if( aCurPar == aPrevPar )
1312 break;
1313
1314 BoundaryCondition = (ToIncreaseParameter) ? (aCurPar > aCurrentRange.Last()) : (aCurPar < aCurrentRange.First());
1315
1316 isboundaryindex = Standard_False;
1317 isvalidindex = Standard_True;
1318
1319 if(BoundaryCondition) {
1320 isboundaryindex = ((!ToIncreaseParameter && (aValidIndex == 1)) ||
1321 (ToIncreaseParameter && (aValidIndex == myRangeManager.Length())));
1322
1323 if(!isboundaryindex) {
1324
1325 if(pointfound) {
1326 Standard_Integer aFlag = (ToIncreaseParameter) ? myRangeManager.Flag(aValidIndex + 1) : myRangeManager.Flag(aValidIndex - 1);
1327
1328 if(aFlag==0) {
1329 aValidIndex = (ToIncreaseParameter) ? (aValidIndex + 1) : (aValidIndex - 1);
1330 aCurrentRange = myRangeManager.Range(aValidIndex);
1331
1332 if((ToIncreaseParameter && (aCurPar > aCurrentRange.Last())) ||
1333 (!ToIncreaseParameter && (aCurPar < aCurrentRange.First()))) {
1334 aCurPar = (aCurrentRange.First() + aCurrentRange.Last()) * 0.5;
1335 aDelta*=0.5;
1336 }
1337 }
1338 else {
1339 isvalidindex = Standard_False;
1340 aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First();
1341 }
1342 }
1343 }
1344 else {
1345 aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First();
1346 }
1347
1348 if(aDelta < tenOfMinDelta) {
1349 loopcounter++;
1350 }
1351 else {
1352 loopcounter = 0;
1353 }
1354 } // if(BoundaryCondition)
1355 }
1356
1357 if(anotherSolutionFound) {
1358 if(ToIncreaseParameter)
1359 myRangeManager.InsertRange(theParameter, aPrevPar, 2);
1360 else
1361 myRangeManager.InsertRange(aPrevPar, theParameter, 2);
1362 }
1363}
1364
1365// ---------------------------------------------------------------------------------
1366// static function: AdjustPeriodic
1367// purpose:
1368// ---------------------------------------------------------------------------------
1369static Standard_Boolean AdjustPeriodic(const Standard_Real U,
1370 const Standard_Real UFirst,
1371 const Standard_Real ULast,
1372 const Standard_Real Period,
1373 Standard_Real& UResult) {
1374 UResult = U;
1375 Standard_Real u = U;
1376 Standard_Real Eps = Epsilon(Period);
1377 while (Eps < (UFirst-u)) u += Period;
1378 while (Eps > (ULast -u)) u -= Period;
1379 if ( u < UFirst)
1380 return Standard_False;
1381
1382 UResult = u;
1383 return Standard_True;
1384}
1385
1386// ---------------------------------------------------------------------------------
1387// static function: SetEmptyResultRange
1388// purpose:
1389// ---------------------------------------------------------------------------------
1390static Standard_Boolean SetEmptyResultRange(const Standard_Real theParameter,
1391 IntTools_MarkedRangeSet& theMarkedRange) {
1392
1393 const TColStd_SequenceOfInteger& anIndices = theMarkedRange.GetIndices(theParameter);
1394 Standard_Boolean add = (anIndices.Length() > 0);
1395
1396 for(Standard_Integer k = 1; k <= anIndices.Length(); k++) {
1397 if(theMarkedRange.Flag(anIndices(k)) == 2) {
1398 add = Standard_False;
1399 break;
1400 }
1401 }
1402
1403 if(add) {
1404 theMarkedRange.InsertRange(theParameter, theParameter, 2);
1405 }
1406
1407 return add;
1408}
1409
1410// ---------------------------------------------------------------------------------
1411// static function: TestCoinside
1412// purpose:
1413// ---------------------------------------------------------------------------------
1414// static Standard_Boolean TestClose(const Extrema_ExtPS & theExt,
1415// const Standard_Real theDist)
1416// {
1417// Standard_Boolean close = Standard_False;
1418// if(!theExt.IsDone() || theExt.NbExt() == 0)
1419// return close;
1420// else {
1421// Standard_Integer ie;
1422// for(ie = 1; ie <= theExt.NbExt(); ie++) {
1423// Standard_Real dist = theExt.Value(ie);
1424// if(dist <= theDist) {
1425// close = Standard_True;
1426// break;
1427// }
1428// }
1429// }
1430// return close;
1431// }
1432
1433// Standard_Boolean TestCoinside(const BRepAdaptor_Curve& theCurve,
1434// const BRepAdaptor_Surface& theSurface)
1435// {
1436// Standard_Real cfp = theCurve.FirstParameter(), clp = theCurve.LastParameter();
1437// Standard_Real cdp = fabs(clp - cfp) / 23.;
1438
1439// Standard_Integer i = 0;
1440// Standard_Real tolE = theCurve.Tolerance(), tolF = theSurface.Tolerance();
1441// Standard_Real tolT = tolE + tolF, tolU = 1.e-9, tolV = 1.e-9;
1442// gp_Pnt aP;
1443
1444// theCurve.D0(cfp,aP);
1445// Extrema_ExtPS eps(aP,theSurface,tolU,tolV);
1446
1447// if(!TestClose(eps,tolT))
1448// return Standard_False;
1449
1450// theCurve.D0(clp,aP);
1451// eps.Perform(aP);
1452
1453// if(!TestClose(eps,tolT))
1454// return Standard_False;
1455
1456// Standard_Boolean close = Standard_True;
1457
1458// for(i = 1; i <= 22; i++) {
1459// theCurve.D0((cfp+((Standard_Real)i)*cdp),aP);
1460// eps.Perform(aP);
1461// if(!TestClose(eps,tolT)) {
1462// close = Standard_False;
1463// break;
1464// }
1465// }
1466// return close;
1467// }
1468
1469// ======================================================================================================================
1470// function: LocalizeSolutions
1471// purpose:
1472// ======================================================================================================================
1473Standard_Boolean IntTools_BeanFaceIntersector::LocalizeSolutions(const IntTools_CurveRangeSample& theCurveRange,
1474 const Bnd_Box& theBoxCurve,
1475 const IntTools_SurfaceRangeSample& theSurfaceRange,
1476 const Bnd_Box& theBoxSurface,
1477 IntTools_CurveRangeLocalizeData& theCurveData,
1478 IntTools_SurfaceRangeLocalizeData& theSurfaceData,
1479 IntTools_ListOfCurveRangeSample& theListCurveRange,
1480 IntTools_ListOfSurfaceRangeSample& theListSurfaceRange)
1481{
1482 Standard_Integer tIt = 0, uIt = 0, vIt = 0;
1483
1484 //
1485 IntTools_CurveRangeSample aRootRangeC(0);
1486 aRootRangeC.SetDepth(0);
1487 IntTools_SurfaceRangeSample aRootRangeS(0, 0, 0, 0);
1488
1489 Bnd_Box aMainBoxC = theBoxCurve;
1490 Bnd_Box aMainBoxS = theBoxSurface;
1491 Standard_Boolean bMainBoxFoundS = Standard_False;
1492 Standard_Boolean bMainBoxFoundC = Standard_False;
1493 //
1494 IntTools_ListOfCurveRangeSample aListCurveRangeFound;
1495 IntTools_ListOfSurfaceRangeSample aListSurfaceRangeFound;
1496
1497
1498 IntTools_Range aRangeC = theCurveRange.GetRange(myFirstParameter, myLastParameter, theCurveData.GetNbSample());
1499 Standard_Real localdiffC = (aRangeC.Last() - aRangeC.First()) / theCurveData.GetNbSample();
1500
1501 Standard_Real aCurPar = aRangeC.First();
1502 Standard_Real aPrevPar = aRangeC.First();
1503 Standard_Integer aCurIndexInit = theCurveRange.GetRangeIndexDeeper(theCurveData.GetNbSample());
1504
1505
1506 TColStd_ListOfInteger aListCToAvoid;
1507 Standard_Boolean bGlobalCheckDone = Standard_False;
1508 //
1509
1510 //
1511
1512 Standard_Integer aCurIndexU = theSurfaceRange.GetRangeIndexUDeeper(theSurfaceData.GetNbSampleU());
1513
1514 Standard_Integer aCurIndexVInit = theSurfaceRange.GetRangeIndexVDeeper(theSurfaceData.GetNbSampleV());
1515 IntTools_Range aRangeV = theSurfaceRange.GetRangeV(myVMinParameter, myVMaxParameter, theSurfaceData.GetNbSampleV());
1516
1517 //
1518 IntTools_Range aRangeU = theSurfaceRange.GetRangeU(myUMinParameter, myUMaxParameter, theSurfaceData.GetNbSampleU());
1519 Standard_Real aCurParU = aRangeU.First();
1520 Standard_Real aLocalDiffU = (aRangeU.Last() - aRangeU.First()) / theSurfaceData.GetNbSampleU();
1521
1522 Standard_Real aPrevParU = aCurParU;
1523 Standard_Real aLocalDiffV = (aRangeV.Last() - aRangeV.First()) / theSurfaceData.GetNbSampleV();
1524
1525
1526 // ranges check.begin
1527 Standard_Boolean bAllowSamplingC = Standard_True;
1528 Standard_Boolean bAllowSamplingU = Standard_True;
1529 Standard_Boolean bAllowSamplingV = Standard_True;
1530
1531 // check
1532 CheckSampling(theCurveRange, theSurfaceRange, theCurveData, theSurfaceData,
1533 localdiffC, aLocalDiffU, aLocalDiffV,
1534 bAllowSamplingC, bAllowSamplingU, bAllowSamplingV);
1535 //
1536
1537 if(!bAllowSamplingC && !bAllowSamplingU && !bAllowSamplingV) {
1538 theListCurveRange.Append(theCurveRange);
1539 theListSurfaceRange.Append(theSurfaceRange);
1540 return Standard_True;
1541 }
1542 // ranges check.end
1543
1544 // init template. begin
1545 IntTools_CurveRangeSample aNewRangeCTemplate;
1546
1547 if(!bAllowSamplingC) {
1548 aNewRangeCTemplate = theCurveRange;
1549 aCurIndexInit = theCurveRange.GetRangeIndex();
1550 localdiffC = (aRangeC.Last() - aRangeC.First());
1551 }
1552 else {
1553 aNewRangeCTemplate.SetDepth(theCurveRange.GetDepth() + 1);
1554 aNewRangeCTemplate.SetRangeIndex(aCurIndexInit);
1555 }
1556
1557 IntTools_SurfaceRangeSample aNewRangeSTemplate = theSurfaceRange;
1558
1559 if(bAllowSamplingU) {
1560 aNewRangeSTemplate.SetDepthU(theSurfaceRange.GetDepthU() + 1);
1561 }
1562 else {
1563 aCurIndexU = aNewRangeSTemplate.GetIndexU();
1564 aLocalDiffU = aRangeU.Last() - aRangeU.First();
1565 }
1566
1567 if(bAllowSamplingV) {
1568 aNewRangeSTemplate.SetDepthV(theSurfaceRange.GetDepthV() + 1);
1569 }
1570 else {
1571 aCurIndexVInit = theSurfaceRange.GetIndexV();
1572 aLocalDiffV = aRangeV.Last() - aRangeV.First();
1573 }
1574 // init template. end
1575
1576
1577 Standard_Boolean bHasOut = Standard_False;
1578 const Standard_Integer nbU = (bAllowSamplingU) ? theSurfaceData.GetNbSampleU() : 1;
1579 const Standard_Integer nbV = (bAllowSamplingV) ? theSurfaceData.GetNbSampleV() : 1;
1580 const Standard_Integer nbC = (bAllowSamplingC) ? theCurveData.GetNbSample() : 1;
1581
1582 for(uIt = 1; uIt <= nbU; uIt++, aCurIndexU++, aPrevParU = aCurParU) {
1583 aCurParU += aLocalDiffU;
1584
1585
1586 Standard_Real aCurParV = aRangeV.First();
1587 Standard_Real aPrevParV = aCurParV;
1588 Standard_Integer aCurIndexV = aCurIndexVInit;
1589
1590 Standard_Boolean bHasOutV = Standard_False;
1591
1592 // ///////
1593 for(vIt = 1; vIt <= nbV; vIt++, aCurIndexV++, aPrevParV = aCurParV) {
1594
1595 aCurParV += aLocalDiffV;
1596
1597
1598 // //////////////
1599 //
1600 IntTools_SurfaceRangeSample aNewRangeS = aNewRangeSTemplate;
1601
1602 if(bAllowSamplingU) {
1603 aNewRangeS.SetIndexU(aCurIndexU);
1604 }
1605
1606 if(bAllowSamplingV) {
1607 aNewRangeS.SetIndexV(aCurIndexV);
1608 }
1609
1610 if(theSurfaceData.IsRangeOut(aNewRangeS)) {
1611 bHasOutV = Standard_True;
1612 continue;
1613 }
1614
1615 // ///////
1616
1617 Bnd_Box aBoxS;
1618
1619 if(!theSurfaceData.FindBox(aNewRangeS, aBoxS)) {
1620
1621 if(mySurface.GetType() == GeomAbs_BSplineSurface) {
1622// if(Standard_False ) {
1623 Handle(Geom_BSplineSurface) aSurfBspl = Handle(Geom_BSplineSurface)::DownCast(myTrsfSurface);
1624 aBoxS = GetSurfaceBox(aSurfBspl, aPrevParU, aCurParU, aPrevParV, aCurParV, myCriteria, theSurfaceData);
1625 }
1626 else {
1627 BndLib_AddSurface::Add(mySurface, aPrevParU, aCurParU, aPrevParV, aCurParV, myCriteria, aBoxS);
1628 }
1629// Bnd_Box aMainBoxC;
1630
1631 if(!bMainBoxFoundC && theCurveData.FindBox(aRootRangeC, aMainBoxC)) {
1632 bMainBoxFoundC = Standard_True;
1633 }
1634
1635 if(aBoxS.IsOut(aMainBoxC)) {
1636 theSurfaceData.AddOutRange(aNewRangeS);
1637 bHasOutV = Standard_True;
1638 continue;
1639 }
1640// }
1641 theSurfaceData.AddBox(aNewRangeS, aBoxS);
1642 }
1643
1644 if(aBoxS.IsOut(theBoxCurve)) {
1645 bHasOutV = Standard_True;
1646 continue;
1647 }
1648
1649 IntTools_ListOfBox aListOfBox;
1650 TColStd_ListOfInteger aListOfIndex;
1651
1652 Standard_Boolean bHasOutC = Standard_False;
1653 Standard_Integer aCurIndex = aCurIndexInit;
1654
1655 // ////////////////////////////
1656 aCurPar = aRangeC.First();
1657 aPrevPar = aRangeC.First();
1658 IntTools_CurveRangeSample aCurRangeC = aNewRangeCTemplate;
1659
1660 for (tIt = 1; tIt <= nbC; tIt++, aCurIndex++, aPrevPar = aCurPar) {
1661
1662 aCurPar += localdiffC;
1663
1664 // ignore already computed. begin
1665 Standard_Boolean bFound = Standard_False;
1666 TColStd_ListIteratorOfListOfInteger anItToAvoid(aListCToAvoid);
1667
1668 for(; anItToAvoid.More(); anItToAvoid.Next()) {
1669 if(tIt == anItToAvoid.Value()) {
1670 bFound = Standard_True;
1671 break;
1672 }
1673 }
1674
1675 if(!bFound) {
1676 if(bAllowSamplingC) {
1677 aCurRangeC.SetRangeIndex(aCurIndex);
1678 }
1679 bFound = theCurveData.IsRangeOut(aCurRangeC);
1680 }
1681
1682 if(bFound) {
1683 bHasOutC = Standard_True;
1684 continue;
1685 }
1686 // ignore already computed. end
1687
1688 // compute Box
1689 Bnd_Box aBoxC;
1690
1691 if(!theCurveData.FindBox(aCurRangeC, aBoxC)) {
1692 BndLib_Add3dCurve::Add(myCurve, aPrevPar, aCurPar, myCriteria, aBoxC);
1693
1694// Bnd_Box aMainBoxS;
1695
1696 if(!bMainBoxFoundS && theSurfaceData.FindBox(aRootRangeS, aMainBoxS)) {
1697 bMainBoxFoundS = Standard_True;
1698 }
1699 if(aBoxC.IsOut(aMainBoxS)) {
1700 theCurveData.AddOutRange(aCurRangeC);
1701 bHasOutC = Standard_True;
1702 continue;
1703 }
1704// }
1705 theCurveData.AddBox(aCurRangeC, aBoxC);
1706 }
1707
1708 if(!bGlobalCheckDone && aBoxC.IsOut(theBoxSurface)) {
1709 aListCToAvoid.Append(tIt);
1710 bHasOutC = Standard_True;
1711 continue;
1712 }
1713
1714 if(aBoxC.IsOut(aBoxS)) {
1715 bHasOutV = Standard_True;
1716 bHasOutC = Standard_True;
1717 continue;
1718 }
1719 //
1720
1721 aListOfIndex.Append(tIt);
1722 aListOfBox.Append(aBoxC);
1723 } // end for(tIt...)
1724
1725 bGlobalCheckDone = Standard_True;
1726
1727 if(bHasOutC) {
1728 bHasOutV = Standard_True;
1729 }
1730
1731 // //////////////
1732 //
1733
1734 IntTools_CurveRangeSample aNewRangeC = aNewRangeCTemplate;
1735
1736 aCurIndex = aCurIndexInit;
1737 TColStd_ListIteratorOfListOfInteger anItI(aListOfIndex);
1738 IntTools_ListIteratorOfListOfBox anItBox(aListOfBox);
1739 Standard_Boolean bUseOldC = Standard_False;
1740 Standard_Boolean bUseOldS = Standard_False;
1741 Standard_Boolean bCheckSize = !bHasOutC;
1742
1743 for(; anItI.More() && anItBox.More(); anItI.Next(), anItBox.Next()) {
1744 aCurIndex = aCurIndexInit + anItI.Value() - 1;
1745
1746 bUseOldS = Standard_False;
1747
1748 if(bAllowSamplingC) {
1749 aNewRangeC.SetRangeIndex(aCurIndex);
1750 }
1751
1752
1753 if(bCheckSize) {
1754
1755 if((theCurveRange.GetDepth() == 0) ||
1756 (theSurfaceRange.GetDepthU() == 0) ||
1757 (theSurfaceRange.GetDepthV() == 0)) {
1758 bHasOutC = Standard_True;
1759 bHasOutV = Standard_True;
1760 }
1761 else if((theCurveRange.GetDepth() < 4) &&
1762 (theSurfaceRange.GetDepthU() < 4) &&
1763 (theSurfaceRange.GetDepthV() < 4)) {
1764 Bnd_Box aBoxC = anItBox.Value();
1765
1766 if(!aBoxC.IsWhole() && !aBoxS.IsWhole()) {
1767 Standard_Real aDiagC = aBoxC.SquareExtent();
1768 Standard_Real aDiagS = aBoxS.SquareExtent();
1769
1770 if(aDiagC < aDiagS) {
1771 if((aDiagC * 10.) < aDiagS) {
1772 bUseOldC = Standard_True;
1773 bHasOutC = Standard_True;
1774 bHasOutV = Standard_True;
1775 break;
1776 }
1777 }
1778 else {
1779 if((aDiagS * 10.) < aDiagC) {
1780 bUseOldS = Standard_True;
1781 bHasOutC = Standard_True;
1782 bHasOutV = Standard_True;
1783 }
1784 }
1785 }
1786 }
1787 }
1788
1789
1790 if(!bHasOutC) {
1791 aListCurveRangeFound.Append(aNewRangeC);
1792 aListSurfaceRangeFound.Append(aNewRangeS);
1793 }
1794 else {
1795
1796// if(bUseOldS || bAllowSamplingU || bAllowSamplingV) {
1797// theSurfaceData.AddBox(aNewRangeS, aBoxS);
1798// }
1799
1800 if(bUseOldS && aNewRangeC.IsEqual(theCurveRange)) {
1801 return Standard_False;
1802 }
1803
1804 if(!LocalizeSolutions(aNewRangeC, anItBox.Value(),
1805 ((bUseOldS) ? theSurfaceRange : aNewRangeS),
1806 ((bUseOldS) ? theBoxSurface : aBoxS),
1807 theCurveData, theSurfaceData,
1808 theListCurveRange, theListSurfaceRange))
1809 return Standard_False;
1810 }
1811 }
1812 // end (tIt...)
1813 aListOfIndex.Clear();
1814 aListOfBox.Clear();
1815
1816 if(bHasOutV) {
1817// theSurfaceData.AddBox(aNewRangeS, aBoxS);
1818
1819 if(bUseOldC && bAllowSamplingC && (bAllowSamplingU || bAllowSamplingV)) {
1820 if(!LocalizeSolutions(theCurveRange, theBoxCurve,
1821 aNewRangeS, aBoxS,
1822 theCurveData, theSurfaceData,
1823 theListCurveRange, theListSurfaceRange))
1824 return Standard_False;
1825 }
1826 }
1827 } // end for (vIt...)
1828
1829 if(bHasOutV) {
1830 bHasOut = Standard_True;
1831 }
1832 }
1833
1834 if(!bHasOut) {
1835 theListCurveRange.Append(theCurveRange);
1836 theListSurfaceRange.Append(theSurfaceRange);
1837 }
1838 else {
1839 IntTools_ListIteratorOfListOfCurveRangeSample anIt1(aListCurveRangeFound);
1840 IntTools_ListIteratorOfListOfSurfaceRangeSample anIt2(aListSurfaceRangeFound);
1841
1842 for(; anIt1.More() && anIt2.More(); anIt1.Next(), anIt2.Next()) {
1843 theListCurveRange.Append(anIt1.Value());
1844 theListSurfaceRange.Append(anIt2.Value());
1845 }
1846 }
1847 return Standard_True;
1848}
1849
1850
1851// ======================================================================================================================
1852// function: ComputeLocalized
1853// purpose:
1854// ======================================================================================================================
1855Standard_Boolean IntTools_BeanFaceIntersector::ComputeLocalized() {
1856 Standard_Real Tol = Precision::PConfusion();
1857
1858 IntTools_SurfaceRangeSample aSurfaceRange(0, 0, 0, 0);
1859 Standard_Real dMinU = 10. * Precision::PConfusion();
1860 Standard_Real dMinV = dMinU;
1861 IntTools_SurfaceRangeLocalizeData aSurfaceDataInit(3, 3, dMinU, dMinV);
4f189102 1862 IntTools_SurfaceRangeLocalizeData& aSurfaceData = myContext->SurfaceData(mySurface.Face());
7fd59977 1863 aSurfaceData.RemoveRangeOutAll();
1864 aSurfaceData.ClearGrid();
1865
1866 Bnd_Box FBox;
1867 Standard_Boolean bFBoxFound = aSurfaceData.FindBox(aSurfaceRange, FBox);
1868
1869 if(mySurface.GetType() == GeomAbs_BSplineSurface) {
1870 Handle(Geom_BSplineSurface) aSurfBspl = Handle(Geom_BSplineSurface)::DownCast(myTrsfSurface);
1871
1872 ComputeGridPoints(aSurfBspl, myUMinParameter, myUMaxParameter,
1873 myVMinParameter, myVMaxParameter, myCriteria,
1874 aSurfaceData);
1875
1876 if(!bFBoxFound) {
1877 FBox = GetSurfaceBox(aSurfBspl, myUMinParameter, myUMaxParameter,
1878 myVMinParameter, myVMaxParameter, myCriteria,
1879 aSurfaceData);
1880 aSurfaceData.AddBox(aSurfaceRange, FBox);
1881 }
1882
1883 } else if(!bFBoxFound) {
1884
1885 BndLib_AddSurface::Add(mySurface, myUMinParameter, myUMaxParameter, myVMinParameter, myVMaxParameter, myFaceTolerance, FBox);
1886 aSurfaceData.AddBox(aSurfaceRange, FBox);
1887 }
1888
1889 Bnd_Box EBox;
1890
1891 BndLib_Add3dCurve::Add(myCurve.Trim(myFirstParameter, myLastParameter, Precision::PConfusion())->Curve(), myBeanTolerance, EBox);
1892
1893 if(EBox.IsOut(FBox)) {
1894 for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
1895 myRangeManager.SetFlag(i, 1);
1896 }
1897 aSurfaceData.ClearGrid();
1898
1899 return Standard_True;
1900 }
1901
1902 IntTools_ListOfCurveRangeSample aListCurveRange;
1903 IntTools_ListOfSurfaceRangeSample aListSurfaceRange;
1904
1905 IntTools_CurveRangeSample aCurveRange(0);
1906 aCurveRange.SetDepth(0);
1907 Standard_Integer nbSampleC = 3;
1908 Standard_Integer nbSampleU = aSurfaceData.GetNbSampleU();
1909 Standard_Integer nbSampleV = aSurfaceData.GetNbSampleV();
1910 Standard_Real dMinC = 10. * myCurveResolution;
1911 IntTools_ListOfCurveRangeSample aListOut;
1912
1913 // check
1914 Standard_Boolean bAllowSamplingC = Standard_True;
1915 Standard_Boolean bAllowSamplingU = Standard_True;
1916 Standard_Boolean bAllowSamplingV = Standard_True;
1917 IntTools_CurveRangeLocalizeData aCurveDataTmp(nbSampleC, dMinC);
1918 IntTools_SurfaceRangeLocalizeData aSurfaceDataTmp(nbSampleU, nbSampleV, dMinU, dMinV);
1919
1920 CheckSampling(aCurveRange, aSurfaceRange, aCurveDataTmp, aSurfaceDataTmp,
1921 myLastParameter - myFirstParameter,
1922 myUMaxParameter - myUMinParameter,
1923 myVMaxParameter - myVMinParameter,
1924 bAllowSamplingC, bAllowSamplingU, bAllowSamplingV);
1925
1926
1927 {
1928 IntTools_CurveRangeLocalizeData aCurveData(nbSampleC, dMinC);
1929
1930 aCurveData.AddBox(aCurveRange, EBox);
1931
1932 if(!LocalizeSolutions(aCurveRange, EBox, aSurfaceRange, FBox,
1933 aCurveData, aSurfaceData,
1934 aListCurveRange, aListSurfaceRange)) {
1935 aSurfaceData.ClearGrid();
1936
1937 return Standard_False;
1938 }
1939
1940 IntTools_ListOfCurveRangeSample aListCurveRangeSort;
1941 IntTools_ListOfSurfaceRangeSample aListSurfaceRangeSort;
1942
1943 MergeSolutions(aListCurveRange, aListSurfaceRange, aListCurveRangeSort, aListSurfaceRangeSort);
1944
1945 IntTools_ListIteratorOfListOfCurveRangeSample anItC(aListCurveRangeSort);
1946 IntTools_ListIteratorOfListOfSurfaceRangeSample anItS(aListSurfaceRangeSort);
1947 IntTools_SurfaceRangeSample aRangeSPrev;
1948
1949 Extrema_GenExtCS anExtremaGen;
1950
1951 for(; anItC.More() && anItS.More(); anItC.Next(), anItS.Next()) {
1952
1953 IntTools_Range aRangeC(myFirstParameter, myLastParameter);
1954
1955 if(bAllowSamplingC)
1956 aRangeC = anItC.Value().GetRange(myFirstParameter, myLastParameter, nbSampleC);
1957
1958 IntTools_Range aRangeU(myUMinParameter, myUMaxParameter);
1959
1960 if(bAllowSamplingU)
1961 aRangeU = anItS.Value().GetRangeU(myUMinParameter, myUMaxParameter, nbSampleU);
1962
1963 IntTools_Range aRangeV(myVMinParameter, myVMaxParameter);
1964
1965 if(bAllowSamplingV)
1966 aRangeV = anItS.Value().GetRangeV(myVMinParameter, myVMaxParameter, nbSampleV);
1967
1968 Standard_Real anarg1 = aRangeC.First(), anarg2 = aRangeC.Last();
1969
1970 Standard_Boolean bFound = Standard_False;
1971
1972 Standard_Integer nMinIndex = myRangeManager.Length();
1973 Standard_Integer nMaxIndex = -1;
1974 const TColStd_SequenceOfInteger& anInds1 = myRangeManager.GetIndices(anarg1);
1975 Standard_Integer indIt = 1;
1976
1977 for(indIt = 1 ; indIt <= anInds1.Length(); indIt++) {
1978 Standard_Integer nIndex = anInds1.Value(indIt);
1979 nMinIndex = (nMinIndex > nIndex) ? nIndex : nMinIndex;
1980 nMaxIndex = (nMaxIndex < nIndex) ? nIndex : nMaxIndex;
1981 }
1982
1983 for(indIt = nMinIndex ; indIt <= nMaxIndex; indIt++) {
1984 if(myRangeManager.Flag(indIt) == 2) {
1985 bFound = Standard_True;
1986 break;
1987 }
1988 }
1989
1990 if(bFound)
1991 continue;
1992 nMinIndex = (nMaxIndex >= 0) ? nMaxIndex : nMinIndex;
1993 const TColStd_SequenceOfInteger& anInds2 = myRangeManager.GetIndices(anarg2);
1994
1995 for(indIt = 1 ; indIt <= anInds2.Length(); indIt++) {
1996 Standard_Integer nIndex = anInds2.Value(indIt);
1997 nMinIndex = (nMinIndex > nIndex) ? nIndex : nMinIndex;
1998 nMaxIndex = (nMaxIndex < nIndex) ? nIndex : nMaxIndex;
1999 }
2000
2001 for(indIt = nMinIndex ; indIt <= nMaxIndex; indIt++) {
2002 if(myRangeManager.Flag(indIt) == 2) {
2003 bFound = Standard_True;
2004 break;
2005 }
2006 }
2007
2008 if(bFound)
2009 continue;
2010
2011 Standard_Real parUF = aRangeU.First(), parUL = aRangeU.Last();
2012 Standard_Real parVF = aRangeV.First(), parVL = aRangeV.Last();
2013
2014 if(aRangeSPrev.IsEqual(anItS.Value())) {
2015 anExtremaGen.Perform(myCurve, 10, anarg1, anarg2, Tol);
2016 }
2017 else {
2018 anExtremaGen.Initialize(mySurface, 10, 10, parUF, parUL, parVF, parVL, Tol);
2019 anExtremaGen.Perform(myCurve, 10, anarg1, anarg2, Tol);
2020 }
2021
2022 if(anExtremaGen.IsDone() && (anExtremaGen.NbExt() > 0)) {
2023
2024 for(Standard_Integer j = 1 ; j <= anExtremaGen.NbExt(); j++) {
2025
2026 if(anExtremaGen.SquareDistance(j) < myCriteria * myCriteria) {
2027
2028 Extrema_POnCurv p1;
2029 Extrema_POnSurf p2;
2030 p1 = anExtremaGen.PointOnCurve(j);
2031 p2 = anExtremaGen.PointOnSurface(j);
2032 Standard_Real U, V, T;
2033 T = p1.Parameter();
2034 p2.Parameter(U, V);
2035
2036 if (myCurve.IsPeriodic())
2037 T = ElCLib::InPeriod(T, anarg1, anarg1 + myCurve.Period());
2038 if (mySurface.IsUPeriodic())
2039 U = ElCLib::InPeriod(U, parUF, parUF + mySurface.UPeriod());
2040 if (mySurface.IsVPeriodic())
2041 V = ElCLib::InPeriod(V, parVF, parVF + mySurface.VPeriod());
2042
2043 //To avoid occasional going out of boundaries because of numerical
2044 //problem
2045 if(U < myUMinParameter) U = myUMinParameter;
2046 if(U > myUMaxParameter) U = myUMaxParameter;
2047 if(V < myVMinParameter) V = myVMinParameter;
2048 if(V > myVMaxParameter) V = myVMaxParameter;
2049
2050 Standard_Integer aNbRanges = myRangeManager.Length();
2051 ComputeRangeFromStartPoint(Standard_False, T, U, V);
2052 ComputeRangeFromStartPoint(Standard_True, T, U, V);
2053
2054 if(aNbRanges == myRangeManager.Length()) {
2055 SetEmptyResultRange(T, myRangeManager);
2056 }
2057 }
2058 } //end for
2059 }
2060 else {
2061 myRangeManager.InsertRange(anarg1, anarg2, 0);
2062 }
2063
2064 aRangeSPrev = anItS.Value();
2065 }
2066
2067 //
2068 aCurveData.ListRangeOut(aListOut);
2069 }
2070
2071 //
2072 if(bAllowSamplingC) {
2073 IntTools_ListIteratorOfListOfCurveRangeSample anItC(aListOut);
2074
2075 for(; anItC.More(); anItC.Next()) {
2076 IntTools_Range aRangeC =anItC.Value().GetRange(myFirstParameter, myLastParameter, nbSampleC);
2077 myRangeManager.InsertRange(aRangeC.First(), aRangeC.Last(), 1);
2078 }
2079 }
2080 ComputeNearRangeBoundaries();
2081
2082 aSurfaceData.ClearGrid();
2083
2084 return Standard_True;
2085}
2086
2087// ======================================================================================================================
2088// function: TestComputeCoinside
2089// purpose:
2090// ======================================================================================================================
2091Standard_Boolean IntTools_BeanFaceIntersector::TestComputeCoinside()
2092{
2093 Standard_Real cfp = myFirstParameter, clp = myLastParameter;
2094 const Standard_Integer nbSeg = 23;
2095 Standard_Real cdp = (clp - cfp) / (Standard_Real )nbSeg;
2096
2097 Standard_Integer i = 0;
2098
2099 Standard_Real U, V;
2100
2101 if(Distance(cfp, U, V) > myCriteria)
2102 return Standard_False;
2103
2104 //
2105 ComputeRangeFromStartPoint(Standard_True, cfp, U, V);
2106 //
2107
2108 Standard_Integer aFoundIndex = myRangeManager.GetIndex(clp, Standard_False );
2109
2110 if(aFoundIndex != 0) {
2111 if(myRangeManager.Flag(aFoundIndex) == 2)
2112 return Standard_True;
2113 }
2114
2115 if(Distance(clp, U, V) > myCriteria)
2116 return Standard_False;
2117
2118 //
2119 ComputeRangeFromStartPoint(Standard_False, clp, U, V);
2120 //
2121
2122 for(i = 1; i < nbSeg; i++) {
2123 Standard_Real aPar = (cfp+((Standard_Real)i)*cdp);
2124
2125 if(Distance(aPar, U, V) > myCriteria)
2126 return Standard_False;
2127
2128 Standard_Integer aNbRanges = myRangeManager.Length();
2129 ComputeRangeFromStartPoint(Standard_False, aPar, U, V);
2130 ComputeRangeFromStartPoint(Standard_True, aPar, U, V);
2131
2132 if(aNbRanges == myRangeManager.Length()) {
2133 SetEmptyResultRange(aPar, myRangeManager);
2134 }
2135 }
2136
2137 return Standard_True;
2138}
2139
2140// Modified by skv - Wed Nov 2 15:21:11 2005 Optimization Begin
2141// ---------------------------------------------------------------------------------
2142// static function: GetSurfaceBox
2143// purpose:
2144// ---------------------------------------------------------------------------------
2145Bnd_Box GetSurfaceBox(const Handle(Geom_BSplineSurface) &theSurf,
2146 const Standard_Real theFirstU,
2147 const Standard_Real theLastU,
2148 const Standard_Real theFirstV,
2149 const Standard_Real theLastV,
2150 const Standard_Real theTolerance,
2151 IntTools_SurfaceRangeLocalizeData &theSurfaceData)
2152{
2153 Bnd_Box aTotalBox;
2154
2155 BuildBox(theSurf, theFirstU, theLastU, theFirstV, theLastV,
2156 theSurfaceData, aTotalBox);
2157
2158 aTotalBox.Enlarge(theTolerance);
2159 return aTotalBox;
2160}
2161
2162
2163// ---------------------------------------------------------------------------------
2164// static function: ComputeGridPoints
2165// purpose:
2166// ---------------------------------------------------------------------------------
2167void ComputeGridPoints
2168 (const Handle(Geom_BSplineSurface) &theSurf,
2169 const Standard_Real theFirstU,
2170 const Standard_Real theLastU,
2171 const Standard_Real theFirstV,
2172 const Standard_Real theLastV,
2173 const Standard_Real theTolerance,
2174 IntTools_SurfaceRangeLocalizeData &theSurfaceData)
2175{
2176 Standard_Integer i;
2177 Standard_Integer j;
2178 Standard_Integer k;
2179 Standard_Integer aNbSamples[2] = { theSurf->UDegree(),
2180 theSurf->VDegree() };
2181 Standard_Integer aNbKnots[2] = { theSurf->NbUKnots(),
2182 theSurf->NbVKnots() };
2183 TColStd_Array1OfReal aKnotsU(1, aNbKnots[0]);
2184 TColStd_Array1OfReal aKnotsV(1, aNbKnots[1]);
2185
2186 theSurf->UKnots(aKnotsU);
2187 theSurf->VKnots(aKnotsV);
2188
2189 Standard_Integer iLmI;
2190 Standard_Integer iMin[2] = { -1, -1 };
2191 Standard_Integer iMax[2] = { -1, -1 };
2192 Standard_Integer aNbGridPnts[2];
2193 Standard_Real aFPar[2] = { theFirstU, theFirstV};
2194 Standard_Real aLPar[2] = { theLastU, theLastV};
2195 Standard_Real aFpTol[2] = { aFPar[0] + theTolerance,
2196 aFPar[1] + theTolerance };
2197 Standard_Real aFmTol[2] = { aFPar[0] - theTolerance,
2198 aFPar[1] - theTolerance };
2199 Standard_Real aLpTol[2] = { aLPar[0] + theTolerance,
2200 aLPar[1] + theTolerance };
2201 Standard_Real aLmTol[2] = { aLPar[0] - theTolerance,
2202 aLPar[1] - theTolerance };
2203
2204
2205 // Compute number of U and V grid points.
2206 for (j = 0; j < 2; j++) {
2207 const TColStd_Array1OfReal &aKnots = (j == 0) ? aKnotsU : aKnotsV;
2208
2209 for (i = 1; i <= aNbKnots[j] && (iMin[j] == -1 || iMax[j] == -1); i++) {
2210 if (iMin[j] == -1 && aFpTol[j] < aKnots.Value(i))
2211 iMin[j] = i - 1;
2212
2213 iLmI = aNbKnots[j] - i + 1;
2214
2215 if (iMax[j] == -1 && aLmTol[j] > aKnots.Value(iLmI))
2216 iMax[j] = iLmI + 1;
2217 }
2218
2219 // If indices are not found, return.
2220 //if (iMin[j] == -1 || iMax[j] == -1)
2221 //return;
2222 if(iMin[j] == -1)
2223 iMin[j] = 1;
2224
2225 if (iMax[j] == -1)
2226 iMax[j] = aNbKnots[j];
2227
2228 if (iMin[j] == 0)
2229 iMin[j] = 1;
2230
2231 if (iMax[j] > aNbKnots[j])
2232 iMax[j] = aNbKnots[j];
2233
2234 if (iMax[j] < iMin[j])
2235 return;
2236
2237 if (iMax[j] == iMin[j]) {
2238 iMax[j]++;
2239 iMin[j]--;
2240 if (iMin[j] == 0)
2241 iMin[j] = 1;
2242 if (iMax[j] > aNbKnots[j])
2243 iMax[j] = aNbKnots[j];
2244
2245 }
2246
2247 aNbGridPnts[j] = (iMax[j] - iMin[j])*aNbSamples[j] + 1;
2248
2249 // Setting the number of grid points.
2250 if (j == 0)
2251 theSurfaceData.SetRangeUGrid(aNbGridPnts[j]);
2252 else // j == 1
2253 theSurfaceData.SetRangeVGrid(aNbGridPnts[j]);
2254
2255 // Setting the first and last parameters.
2256 Standard_Integer iAbs = 1;
2257 Standard_Real aMinPar;
2258 Standard_Real aMaxPar = (j == 0) ? theLastU : theLastV;
2259
2260 for (i = iMin[j]; i < iMax[j]; i++) {
2261 // Get the first parameter.
2262 if (i == iMin[j]) {
2263 // The first knot.
2264 if (aFmTol[j] > aKnots.Value(iMin[j]))
2265 aMinPar = aFPar[j];
2266 else
2267 aMinPar = aKnots.Value(iMin[j]);
2268 } else {
2269 aMinPar = aKnots.Value(i);
2270 }
2271
2272 // Get the last parameter.
2273 if (i == iMax[j] - 1) {
2274 // The last knot.
2275 if (aLpTol[j] < aKnots.Value(iMax[j]))
2276 aMaxPar = aLPar[j];
2277 else
2278 aMaxPar = aKnots.Value(iMax[j]);
2279 } else {
2280 aMaxPar = aKnots.Value(i + 1);
2281 }
2282
2283 // Compute grid parameters.
2284 Standard_Real aDelta = (aMaxPar - aMinPar)/aNbSamples[j];
2285
2286 for (k = 0; k < aNbSamples[j]; k++, aMinPar += aDelta) {
2287 if (j == 0)
2288 theSurfaceData.SetUParam(iAbs++, aMinPar);
2289 else
2290 theSurfaceData.SetVParam(iAbs++, aMinPar);
2291 }
2292 }
2293
2294 // Add the last parameter
2295 if (j == 0)
2296 theSurfaceData.SetUParam(iAbs++, aMaxPar);
2297 else
2298 theSurfaceData.SetVParam(iAbs++, aMaxPar);
2299 }
2300
2301 // Compute of grid points.
2302 gp_Pnt aPnt;
2303 Standard_Real aParU;
2304 Standard_Real aParV;
2305
2306 for (i = 1; i <= aNbGridPnts[0]; i++) {
2307 aParU = theSurfaceData.GetUParam(i);
2308
2309 for (j = 1; j <= aNbGridPnts[1]; j++) {
2310 aParV = theSurfaceData.GetVParam(j);
2311
2312 theSurf->D0(aParU, aParV, aPnt);
2313 theSurfaceData.SetGridPoint(i, j, aPnt);
2314 }
2315 }
2316
2317 // Compute deflection.
2318 Standard_Real aDef = 0.;
2319// Standard_Real aDefLin;
2320// Standard_Real aParMid;
2321// Standard_Real aParConst;
2322// Standard_Real aDistPP;
2323// gp_Pnt aPntMid;
2324// gp_Vec aVec;
2325// gp_XYZ aCoord;
2326
2327// // Compute DU deflection.
2328// for (i = 1; i < aNbGridPnts[0]; i++) {
2329// aParMid = 0.5*(theSurfaceData.GetUParam(i + 1) +
2330// theSurfaceData.GetUParam(i));
2331
2332// for (j = 1; j <= aNbGridPnts[1]; j++) {
2333// const gp_Pnt &thePnt1 = theSurfaceData.GetGridPoint(i, j);
2334// const gp_Pnt &thePnt2 = theSurfaceData.GetGridPoint(i + 1, j);
2335
2336// aVec.SetXYZ(thePnt2.XYZ().Subtracted(thePnt1.XYZ()));
2337// aDistPP = aVec.Magnitude();
2338
2339// if (aDistPP > theTolerance) {
2340// // Computation of a distance of a middle point from the line P1 - P2.
2341// aParConst = theSurfaceData.GetVParam(j);
2342// theSurf->D0(aParMid, aParConst, aPntMid);
2343// aCoord = aPntMid.XYZ();
2344// aCoord.Subtract(thePnt1.XYZ());
2345// aCoord.Cross (aVec.XYZ());
2346// aCoord.Divide(aDistPP);
2347// aDefLin = aCoord.Modulus();
2348
2349// if (aDefLin > aDef)
2350// aDef = aDefLin;
2351// }
2352// }
2353// }
2354
2355// // Compute DV deflection.
2356// for (j = 1; j < aNbGridPnts[1]; j++) {
2357// aParMid = 0.5*(theSurfaceData.GetVParam(j + 1) +
2358// theSurfaceData.GetVParam(j));
2359
2360// for (i = 1; i <= aNbGridPnts[0]; i++) {
2361// const gp_Pnt &thePnt1 = theSurfaceData.GetGridPoint(i, j);
2362// const gp_Pnt &thePnt2 = theSurfaceData.GetGridPoint(i, j + 1);
2363
2364// aVec.SetXYZ(thePnt2.XYZ().Subtracted(thePnt1.XYZ()));
2365// aDistPP = aVec.Magnitude();
2366
2367// if (aDistPP > theTolerance) {
2368// // Computation of a distance of a middle point from the line P1 - P2.
2369// aParConst = theSurfaceData.GetUParam(i);
2370// theSurf->D0(aParConst, aParMid, aPntMid);
2371// aCoord = aPntMid.XYZ();
2372// aCoord.Subtract(thePnt1.XYZ());
2373// aCoord.Cross (aVec.XYZ());
2374// aCoord.Divide(aDistPP);
2375// aDefLin = aCoord.Modulus();
2376
2377// if (aDefLin > aDef)
2378// aDef = aDefLin;
2379// }
2380// }
2381// }
2382
2383 if (theTolerance > aDef)
2384 aDef = theTolerance;
2385
2386 aDef *= 2.;
2387 theSurfaceData.SetGridDeflection(aDef);
2388}
2389
2390// ---------------------------------------------------------------------------------
2391// static function: BuildBox
2392// purpose: Compute bounding box.
2393// ---------------------------------------------------------------------------------
2394void BuildBox(const Handle(Geom_BSplineSurface) &theSurf,
2395 const Standard_Real theFirstU,
2396 const Standard_Real theLastU,
2397 const Standard_Real theFirstV,
2398 const Standard_Real theLastV,
2399 IntTools_SurfaceRangeLocalizeData &theSurfaceData,
2400 Bnd_Box &theBox)
2401{
2402 Standard_Integer i;
2403 Standard_Integer j;
2404 Standard_Integer aNbUPnts;
2405 Standard_Integer aNbVPnts;
2406 Standard_Real aParam;
2407 gp_Pnt aPnt;
2408
2409 theSurfaceData.SetFrame(theFirstU, theLastU, theFirstV, theLastV);
2410 aNbUPnts = theSurfaceData.GetNBUPointsInFrame();
2411 aNbVPnts = theSurfaceData.GetNBVPointsInFrame();
2412
2413 // Add corner points.
2414 theSurf->D0(theFirstU, theFirstV, aPnt);
2415 theBox.Add(aPnt);
2416 theSurf->D0(theLastU, theFirstV, aPnt);
2417 theBox.Add(aPnt);
2418 theSurf->D0(theFirstU, theLastV, aPnt);
2419 theBox.Add(aPnt);
2420 theSurf->D0(theLastU, theLastV, aPnt);
2421 theBox.Add(aPnt);
2422
2423 for (i = 1; i <= aNbUPnts; i++) {
2424 // Add top and bottom points.
2425 aParam = theSurfaceData.GetUParamInFrame(i);
2426 theSurf->D0(aParam, theFirstV, aPnt);
2427 theBox.Add(aPnt);
2428 theSurf->D0(aParam, theLastV, aPnt);
2429 theBox.Add(aPnt);
2430
2431 // Add internal points.
2432 for (j = 1; j <= aNbVPnts; j++) {
2433 const gp_Pnt &aGridPnt = theSurfaceData.GetPointInFrame(i, j);
2434
2435 theBox.Add(aGridPnt);
2436 }
2437 }
2438
2439 // Add left and right points.
2440 for (j = 1; j <= aNbVPnts; j++) {
2441 aParam = theSurfaceData.GetVParamInFrame(j);
2442 theSurf->D0(theFirstU, aParam, aPnt);
2443 theBox.Add(aPnt);
2444 theSurf->D0(theLastU, aParam, aPnt);
2445 theBox.Add(aPnt);
2446 }
2447
2448 theBox.Enlarge(theSurfaceData.GetGridDeflection());
2449}
2450// Modified by skv - Wed Nov 2 15:21:11 2005 Optimization End
2451
2452
2453// ---------------------------------------------------------------------------------
2454// static function: MergeSolutions
2455// purpose:
2456// ---------------------------------------------------------------------------------
2457static void MergeSolutions(const IntTools_ListOfCurveRangeSample& theListCurveRange,
2458 const IntTools_ListOfSurfaceRangeSample& theListSurfaceRange,
2459 IntTools_ListOfCurveRangeSample& theListCurveRangeSort,
2460 IntTools_ListOfSurfaceRangeSample& theListSurfaceRangeSort) {
2461
2462 IntTools_ListIteratorOfListOfCurveRangeSample anItC2;
2463 IntTools_ListIteratorOfListOfSurfaceRangeSample anItS1(theListSurfaceRange), anItS2;
2464 IntTools_MapOfSurfaceSample aMapToAvoid;
2465
2466 for(; anItS1.More(); anItS1.Next()) {
2467 const IntTools_SurfaceRangeSample& aRangeS = anItS1.Value();
2468
2469 if(aMapToAvoid.Contains(aRangeS))
2470 continue;
2471 aMapToAvoid.Add(aRangeS);
2472
2473 anItC2.Initialize(theListCurveRange);
2474 anItS2.Initialize(theListSurfaceRange);
2475
2476 for(; anItS2.More() && anItC2.More(); anItS2.Next(), anItC2.Next()) {
2477 if(aRangeS.IsEqual(anItS2.Value())) {
2478 theListCurveRangeSort.Append(anItC2.Value());
2479 theListSurfaceRangeSort.Append(anItS2.Value());
2480 }
2481 }
2482 }
2483}
2484
2485// ---------------------------------------------------------------------------------
2486// static function: CheckSampling
2487// purpose:
2488// ---------------------------------------------------------------------------------
2489static void CheckSampling(const IntTools_CurveRangeSample& theCurveRange,
2490 const IntTools_SurfaceRangeSample& theSurfaceRange,
2491 const IntTools_CurveRangeLocalizeData& theCurveData,
2492 const IntTools_SurfaceRangeLocalizeData& theSurfaceData,
2493 const Standard_Real DiffC,
2494 const Standard_Real DiffU,
2495 const Standard_Real DiffV,
2496 Standard_Boolean& bAllowSamplingC,
2497 Standard_Boolean& bAllowSamplingU,
2498 Standard_Boolean& bAllowSamplingV) {
2499
2500 const Standard_Real dLimit = 1000;
2501 bAllowSamplingC = Standard_True;
2502 bAllowSamplingU = Standard_True;
2503 bAllowSamplingV = Standard_True;
2504
2505 // check
2506 if((pow((Standard_Real)theCurveData.GetNbSample(), (Standard_Real )(theCurveRange.GetDepth() + 1)) > dLimit) ||
2507 ((DiffC / theCurveData.GetNbSample()) < theCurveData.GetMinRange())) {
2508 bAllowSamplingC = Standard_False;
2509 }
2510
2511 if((pow((Standard_Real )theSurfaceData.GetNbSampleU(), (Standard_Real )(theSurfaceRange.GetDepthU() + 1)) > dLimit) ||
2512 ((DiffU / theSurfaceData.GetNbSampleU()) < theSurfaceData.GetMinRangeU())) {
2513 bAllowSamplingU = Standard_False;
2514 }
2515
2516
2517 if((pow((Standard_Real )theSurfaceData.GetNbSampleV(), (Standard_Real )(theSurfaceRange.GetDepthV() + 1)) > dLimit) ||
2518 ((DiffV / theSurfaceData.GetNbSampleV()) < theSurfaceData.GetMinRangeV())) {
2519 bAllowSamplingV = Standard_False;
2520 }
2521}