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