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