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