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