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