1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
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>
25 #include <Extrema_ExtCS.hxx>
26 #include <Extrema_ExtPS.hxx>
27 #include <Extrema_GenExtCS.hxx>
28 #include <Extrema_GenLocateExtPS.hxx>
29 #include <Extrema_POnCurv.hxx>
30 #include <Extrema_POnSurf.hxx>
31 #include <Geom_BSplineSurface.hxx>
32 #include <Geom_Curve.hxx>
33 #include <Geom_Surface.hxx>
34 #include <GeomAdaptor_Curve.hxx>
35 #include <GeomAdaptor_Surface.hxx>
36 #include <GeomAPI_ProjectPointOnCurve.hxx>
37 #include <GeomInt.hxx>
38 #include <IntAna_QuadQuadGeo.hxx>
39 #include <IntCurveSurface_HInter.hxx>
40 #include <IntCurveSurface_IntersectionPoint.hxx>
41 #include <IntCurveSurface_IntersectionSegment.hxx>
42 #include <IntTools.hxx>
43 #include <IntTools_BeanFaceIntersector.hxx>
44 #include <IntTools_Context.hxx>
45 #include <IntTools_CurveRangeLocalizeData.hxx>
46 #include <IntTools_CurveRangeSample.hxx>
47 #include <IntTools_EdgeFace.hxx>
48 #include <IntTools_ListIteratorOfListOfBox.hxx>
49 #include <IntTools_ListIteratorOfListOfCurveRangeSample.hxx>
50 #include <IntTools_ListIteratorOfListOfSurfaceRangeSample.hxx>
51 #include <IntTools_ListOfBox.hxx>
52 #include <IntTools_ListOfCurveRangeSample.hxx>
53 #include <IntTools_ListOfSurfaceRangeSample.hxx>
54 #include <IntTools_MapIteratorOfMapOfCurveSample.hxx>
55 #include <IntTools_Root.hxx>
56 #include <IntTools_SurfaceRangeLocalizeData.hxx>
57 #include <IntTools_SurfaceRangeSample.hxx>
58 #include <IntTools_Tools.hxx>
59 #include <Precision.hxx>
60 #include <TColgp_Array1OfPnt2d.hxx>
61 #include <TColStd_Array1OfBoolean.hxx>
62 #include <TColStd_Array1OfReal.hxx>
63 #include <TColStd_ListIteratorOfListOfInteger.hxx>
64 #include <TColStd_ListOfInteger.hxx>
65 #include <TopoDS_Edge.hxx>
66 #include <TopoDS_Face.hxx>
68 static Standard_Boolean SetEmptyResultRange(const Standard_Real theParameter,
69 IntTools_MarkedRangeSet& theMarkedRange);
73 static Bnd_Box GetSurfaceBox
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);
82 static void ComputeGridPoints
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);
91 static void BuildBox(const Handle(Geom_BSplineSurface) &theSurf,
92 const Standard_Real theFirstU,
93 const Standard_Real theLastU,
94 const Standard_Real theFirstV,
95 const Standard_Real theLastV,
96 IntTools_SurfaceRangeLocalizeData &theSurfaceData,
99 static void MergeSolutions(const IntTools_ListOfCurveRangeSample& theListCurveRange,
100 const IntTools_ListOfSurfaceRangeSample& theListSurfaceRange,
101 IntTools_ListOfCurveRangeSample& theListCurveRangeSort,
102 IntTools_ListOfSurfaceRangeSample& theListSurfaceRangeSort);
104 static void CheckSampling(const IntTools_CurveRangeSample& theCurveRange,
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);
115 // ==================================================================================
116 // function: IntTools_BeanFaceIntersector
118 // ==================================================================================
119 IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector() :
120 myFirstParameter(0.),
129 myIsDone(Standard_False)
131 myCriteria = Precision::Confusion();
132 myCurveResolution = Precision::PConfusion();
136 // ==================================================================================
137 // function: IntTools_BeanFaceIntersector
139 // ==================================================================================
140 IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const TopoDS_Edge& theEdge,
141 const TopoDS_Face& theFace) :
142 myFirstParameter(0.),
151 myIsDone(Standard_False)
153 Init(theEdge, theFace);
156 // ==================================================================================
157 // function: IntTools_BeanFaceIntersector
159 // ==================================================================================
160 IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const BRepAdaptor_Curve& theCurve,
161 const BRepAdaptor_Surface& theSurface,
162 const Standard_Real theBeanTolerance,
163 const Standard_Real theFaceTolerance) :
164 myFirstParameter(0.),
171 myIsDone(Standard_False)
173 Init(theCurve, theSurface, theBeanTolerance, theFaceTolerance);
176 // ==================================================================================
177 // function: IntTools_BeanFaceIntersector
179 // ==================================================================================
180 IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const BRepAdaptor_Curve& theCurve,
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),
199 myIsDone(Standard_False)
203 myCriteria = myBeanTolerance + myFaceTolerance + Precision::Confusion();
204 myCurveResolution = myCurve.Resolution(myCriteria);
206 mySurface = theSurface;
207 myTrsfSurface = Handle(Geom_Surface)::DownCast(mySurface.Surface().Surface()->Transformed(mySurface.Trsf()));
210 // ==================================================================================
213 // ==================================================================================
214 void IntTools_BeanFaceIntersector::Init(const TopoDS_Edge& theEdge,
215 const TopoDS_Face& theFace)
217 myCurve.Initialize(theEdge);
218 mySurface.Initialize(theFace);
219 myTrsfSurface = Handle(Geom_Surface)::DownCast(mySurface.Surface().Surface()->Transformed(mySurface.Trsf()));
220 myBeanTolerance = BRep_Tool::Tolerance(theEdge);
221 myFaceTolerance = BRep_Tool::Tolerance(theFace);
223 myCriteria = myBeanTolerance + myFaceTolerance + Precision::Confusion();
224 myCurveResolution = myCurve.Resolution(myCriteria);
226 SetSurfaceParameters(mySurface.FirstUParameter(), mySurface.LastUParameter(),
227 mySurface.FirstVParameter(), mySurface.LastVParameter());
231 // ==================================================================================
234 // ==================================================================================
235 void IntTools_BeanFaceIntersector::Init(const BRepAdaptor_Curve& theCurve,
236 const BRepAdaptor_Surface& theSurface,
237 const Standard_Real theBeanTolerance,
238 const Standard_Real theFaceTolerance)
241 mySurface = theSurface;
242 myTrsfSurface = Handle(Geom_Surface)::DownCast(mySurface.Surface().Surface()->Transformed(mySurface.Trsf()));
243 myBeanTolerance = theBeanTolerance;
244 myFaceTolerance = theFaceTolerance;
246 myCriteria = myBeanTolerance + myFaceTolerance + Precision::Confusion();
247 myCurveResolution = myCurve.Resolution(myCriteria);
249 SetSurfaceParameters(mySurface.FirstUParameter(), mySurface.LastUParameter(),
250 mySurface.FirstVParameter(), mySurface.LastVParameter());
254 // ==================================================================================
257 // ==================================================================================
258 void IntTools_BeanFaceIntersector::Init(const BRepAdaptor_Curve& theCurve,
259 const BRepAdaptor_Surface& theSurface,
260 const Standard_Real theFirstParOnCurve,
261 const Standard_Real theLastParOnCurve,
262 const Standard_Real theUMinParameter,
263 const Standard_Real theUMaxParameter,
264 const Standard_Real theVMinParameter,
265 const Standard_Real theVMaxParameter,
266 const Standard_Real theBeanTolerance,
267 const Standard_Real theFaceTolerance)
269 Init(theCurve, theSurface, theBeanTolerance, theFaceTolerance);
270 SetBeanParameters(theFirstParOnCurve, theLastParOnCurve);
271 SetSurfaceParameters(theUMinParameter, theUMaxParameter, theVMinParameter, theVMaxParameter);
274 // ==================================================================================
275 // function: SetContext
277 // ==================================================================================
278 void IntTools_BeanFaceIntersector::SetContext(const Handle(IntTools_Context)& theContext)
280 myContext = theContext;
282 // ==================================================================================
285 // ==================================================================================
286 const Handle(IntTools_Context)& IntTools_BeanFaceIntersector::Context()const
291 // ==================================================================================
292 // function: SetBeanParameters
294 // ==================================================================================
295 void IntTools_BeanFaceIntersector::SetBeanParameters(const Standard_Real theFirstParOnCurve,
296 const Standard_Real theLastParOnCurve)
298 myFirstParameter = theFirstParOnCurve;
299 myLastParameter = theLastParOnCurve;
302 // ==================================================================================
303 // function: SetSurfaceParameters
305 // ==================================================================================
306 void IntTools_BeanFaceIntersector::SetSurfaceParameters(const Standard_Real theUMinParameter,
307 const Standard_Real theUMaxParameter,
308 const Standard_Real theVMinParameter,
309 const Standard_Real theVMaxParameter)
311 myUMinParameter = theUMinParameter;
312 myUMaxParameter = theUMaxParameter;
313 myVMinParameter = theVMinParameter;
314 myVMaxParameter = theVMaxParameter;
317 // ==================================================================================
320 // ==================================================================================
321 void IntTools_BeanFaceIntersector::Perform()
323 myIsDone = Standard_False;
325 Standard_Integer bRet;
326 Standard_Integer aDiscretization = 30;
327 Standard_Real aRelativeDeflection = 0.01;
328 myDeflection = aRelativeDeflection;
330 if (myContext.IsNull()) {
331 myContext=new IntTools_Context;
334 if(myCurve.GetType()==GeomAbs_Line && mySurface.GetType()==GeomAbs_Plane) {
339 if(myCurve.GetType()==GeomAbs_Line) {
341 myDeflection = Precision::Confusion();
344 if(myCurve.GetType()==GeomAbs_Circle) {
345 aDiscretization = 23;
346 Standard_Real R = myCurve.Circle().Radius();
347 myDeflection = aRelativeDeflection * R;
349 if(myCurve.GetType() == GeomAbs_Ellipse) {
350 aDiscretization = 23;
351 Standard_Real R = myCurve.Ellipse().MajorRadius();
352 myDeflection = 2 * aRelativeDeflection * R;
355 // modified by NIZHNY-MKK Wed Oct 19 12:15:21 2005
356 Standard_Boolean bLocalize = Standard_False;
358 if(((mySurface.GetType() == GeomAbs_BSplineSurface) &&
359 ((mySurface.UDegree() > 2) || (mySurface.VDegree() > 2)) &&
360 //modified by NIZNHY-PKV Wed Feb 25 15:02:00 2009f
361 //((mySurface.NbUKnots() > 2) || (mySurface.NbVKnots() > 2))) ||
362 ((mySurface.NbUKnots() > 2) && (mySurface.NbVKnots() > 2))) ||
363 //modified by NIZNHY-PKV Wed Feb 25 15:02:13 2009t
364 (mySurface.GetType() == GeomAbs_BezierSurface) ||
365 (mySurface.GetType() == GeomAbs_OtherSurface)) {
366 bLocalize = Standard_True;
370 if(Precision::IsInfinite(myUMinParameter) ||
371 Precision::IsInfinite(myUMaxParameter) ||
372 Precision::IsInfinite(myVMinParameter) ||
373 Precision::IsInfinite(myVMaxParameter))
374 bLocalize = Standard_False;
376 Standard_Boolean bSuccessLocalize = Standard_False;
379 myRangeManager.SetBoundaries(myFirstParameter, myLastParameter, 0);
380 Standard_Boolean coinside = TestComputeCoinside();
383 bSuccessLocalize = ComputeLocalized();
386 if(!bLocalize || !bSuccessLocalize) {
387 // modified by NIZHNY-MKK Wed Oct 19 12:15:26 2005.END
389 IntTools_CArray1OfReal aParams;
391 if(IntTools::PrepareArgs(myCurve,
400 myRangeManager.SetRanges(aParams, 0);
402 if(myRangeManager.Length()==0) {
406 bRet=FastComputeExactIntersection();
408 IntTools_Range aRange(myFirstParameter, myLastParameter);
409 myResults.Append(aRange);
410 myIsDone = Standard_True;
413 //modified by NIZHNY-EMV Fri Apr 20 09:38:08 2012
414 else if (bRet == 2) {
415 myIsDone = Standard_True;
418 //modified by NIZHNY-EMV Fri Apr 20 09:38:10 2012
421 // Standard_Boolean coinside = TestCoinside(myCurve,mySurface);
422 Standard_Boolean coinside = TestComputeCoinside();
424 // myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2);
428 ComputeAroundExactIntersection();
430 ComputeUsingExtremum();
432 ComputeNearRangeBoundaries();
436 myIsDone = Standard_True;
438 for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
440 if(myRangeManager.Flag(i) == 2) {
441 IntTools_Range aRange = myRangeManager.Range(i);
443 if(myResults.Length() > 0) {
444 const IntTools_Range& aLastRange = myResults.Last();
446 if(Abs(aRange.First() - aLastRange.Last()) > Precision::PConfusion()) {
447 myResults.Append(aRange);
450 myResults.ChangeValue(myResults.Length()).SetLast(aRange.Last());
454 myResults.Append(aRange);
460 // ==================================================================================
463 // ==================================================================================
464 const IntTools_SequenceOfRanges& IntTools_BeanFaceIntersector::Result() const
469 // ==================================================================================
472 // ==================================================================================
473 void IntTools_BeanFaceIntersector::Result(IntTools_SequenceOfRanges& theResults) const
475 theResults = myResults;
478 // ==================================================================================
479 // function: Distance
481 // ==================================================================================
482 Standard_Real IntTools_BeanFaceIntersector::Distance(const Standard_Real theArg)
484 gp_Pnt aPoint = myCurve.Value(theArg);
486 GeomAPI_ProjectPointOnSurf& aProjector = myContext->ProjPS(mySurface.Face());
487 aProjector.Perform(aPoint);
489 if(aProjector.IsDone() && aProjector.NbPoints() > 0) {
490 return aProjector.LowerDistance();
493 Standard_Real aDistance = RealLast();
495 for(Standard_Integer i=0; i < 4; i++) {
496 Standard_Real anIsoParameter = (i==0) ? myUMinParameter : ((i==1) ? myUMaxParameter : ((i==2) ? myVMinParameter : myVMaxParameter));
497 Standard_Real aMinParameter = (i < 2) ? myVMinParameter : myUMinParameter;
498 Standard_Real aMaxParameter = (i < 2) ? myVMaxParameter : myUMaxParameter;
499 Standard_Real aMidParameter = (aMinParameter + aMaxParameter) * 0.5;
500 gp_Pnt aPointMin = (i < 2) ? mySurface.Value(anIsoParameter, aMinParameter) : mySurface.Value(aMinParameter, anIsoParameter);
501 gp_Pnt aPointMax = (i < 2) ? mySurface.Value(anIsoParameter, aMaxParameter) : mySurface.Value(aMaxParameter, anIsoParameter);
502 gp_Pnt aPointMid = (i < 2) ? mySurface.Value(anIsoParameter, aMidParameter) : mySurface.Value(aMidParameter, anIsoParameter);
504 Standard_Boolean useMinMaxPoints = Standard_True;
505 Standard_Boolean computeisoline = Standard_True;
507 if(aPointMin.IsEqual(aPointMax, myCriteria) &&
508 aPointMin.IsEqual(aPointMid, myCriteria) &&
509 aPointMax.IsEqual(aPointMid, myCriteria)) {
510 computeisoline = Standard_False;
514 Handle(Geom_Curve) aCurve = (i < 2) ? myTrsfSurface->UIso(anIsoParameter) : myTrsfSurface->VIso(anIsoParameter);
515 GeomAPI_ProjectPointOnCurve aProjectorOnCurve(aPoint, aCurve, aMinParameter, aMaxParameter);
517 if(aProjectorOnCurve.NbPoints() > 0) {
518 useMinMaxPoints = Standard_False;
520 if(aDistance > aProjectorOnCurve.LowerDistance())
521 aDistance = aProjectorOnCurve.LowerDistance();
525 if(useMinMaxPoints) {
526 Standard_Real aPPDistance = aPoint.Distance(aPointMin);
527 aDistance = (aPPDistance < aDistance) ? aPPDistance : aDistance;
528 aPPDistance = aPoint.Distance(aPointMax);
529 aDistance = (aPPDistance < aDistance) ? aPPDistance : aDistance;
536 // ==================================================================================
537 // function: Distance
539 // ==================================================================================
540 Standard_Real IntTools_BeanFaceIntersector::Distance(const Standard_Real theArg,
541 Standard_Real& theUParameter,
542 Standard_Real& theVParameter)
544 gp_Pnt aPoint = myCurve.Value(theArg);
546 theUParameter = myUMinParameter;
547 theVParameter = myVMinParameter;
549 Standard_Real aDistance = RealLast();
550 Standard_Boolean projectionfound = Standard_False;
552 GeomAPI_ProjectPointOnSurf& aProjector = myContext->ProjPS(mySurface.Face());
553 aProjector.Perform(aPoint);
555 if(aProjector.IsDone() && aProjector.NbPoints() > 0) {
556 aProjector.LowerDistanceParameters(theUParameter, theVParameter);
557 aDistance = aProjector.LowerDistance();
558 projectionfound = Standard_True;
561 if(!projectionfound) {
563 for(Standard_Integer i = 0; i < 4; i++) {
564 Standard_Real anIsoParameter = (i==0) ? myUMinParameter : ((i==1) ? myUMaxParameter : ((i==2) ? myVMinParameter : myVMaxParameter));
565 Standard_Real aMinParameter = (i < 2) ? myVMinParameter : myUMinParameter;
566 Standard_Real aMaxParameter = (i < 2) ? myVMaxParameter : myUMaxParameter;
567 Standard_Real aMidParameter = (aMinParameter + aMaxParameter) * 0.5;
568 gp_Pnt aPointMin = (i < 2) ? mySurface.Value(anIsoParameter, aMinParameter) : mySurface.Value(aMinParameter, anIsoParameter);
569 gp_Pnt aPointMax = (i < 2) ? mySurface.Value(anIsoParameter, aMaxParameter) : mySurface.Value(aMaxParameter, anIsoParameter);
570 gp_Pnt aPointMid = (i < 2) ? mySurface.Value(anIsoParameter, aMidParameter) : mySurface.Value(aMidParameter, anIsoParameter);
572 Standard_Boolean useMinMaxPoints = Standard_True;
573 Standard_Boolean computeisoline = Standard_True;
575 if(aPointMin.IsEqual(aPointMax, myCriteria) &&
576 aPointMin.IsEqual(aPointMid, myCriteria) &&
577 aPointMax.IsEqual(aPointMid, myCriteria)) {
578 computeisoline = Standard_False;
582 Handle(Geom_Curve) aCurve = (i < 2) ? myTrsfSurface->UIso(anIsoParameter) : myTrsfSurface->VIso(anIsoParameter);
583 GeomAPI_ProjectPointOnCurve aProjectorOnCurve(aPoint, aCurve, aMinParameter, aMaxParameter);
585 if(aProjectorOnCurve.NbPoints() > 0) {
586 useMinMaxPoints = Standard_False;
588 if(aDistance > aProjectorOnCurve.LowerDistance()) {
589 theUParameter = (i<=1) ? anIsoParameter : aProjectorOnCurve.LowerDistanceParameter();
590 theVParameter = (i>=2) ? anIsoParameter : aProjectorOnCurve.LowerDistanceParameter();
591 aDistance = aProjectorOnCurve.LowerDistance();
596 if(useMinMaxPoints) {
597 Standard_Real aPPDistance = aPoint.Distance(aPointMin);
599 if(aPPDistance < aDistance) {
600 theUParameter = (i<=1) ? anIsoParameter : aMinParameter;
601 theVParameter = (i>=2) ? anIsoParameter : aMinParameter;
602 aDistance = aPPDistance;
604 aPPDistance = aPoint.Distance(aPointMax);
606 if(aPPDistance < aDistance) {
607 theUParameter = (i<=1) ? anIsoParameter : aMaxParameter;
608 theVParameter = (i>=2) ? anIsoParameter : aMaxParameter;
609 aDistance = aPPDistance;
614 theUParameter = (myUMinParameter > theUParameter) ? myUMinParameter : theUParameter;
615 theUParameter = (myUMaxParameter < theUParameter) ? myUMaxParameter : theUParameter;
616 theVParameter = (myVMinParameter > theVParameter) ? myVMinParameter : theVParameter;
617 theVParameter = (myVMaxParameter < theVParameter) ? myVMaxParameter : theVParameter;
622 // ==================================================================================
623 // function: ComputeAroundExactIntersection
625 // ==================================================================================
626 void IntTools_BeanFaceIntersector::ComputeAroundExactIntersection()
628 IntCurveSurface_HInter anExactIntersector;
630 Handle(BRepAdaptor_HCurve) aCurve = new BRepAdaptor_HCurve(myCurve);
631 Handle(BRepAdaptor_HSurface) aSurface = new BRepAdaptor_HSurface(mySurface);
633 anExactIntersector.Perform(aCurve, aSurface);
635 if(anExactIntersector.IsDone()) {
636 Standard_Integer i = 0;
638 for(i = 1; i <= anExactIntersector.NbPoints(); i++) {
639 const IntCurveSurface_IntersectionPoint& aPoint = anExactIntersector.Point(i);
641 if((aPoint.W() >= myFirstParameter) && (aPoint.W() <= myLastParameter)) {
642 Standard_Boolean UIsNotValid = ((myUMinParameter > aPoint.U()) || (aPoint.U() > myUMaxParameter));
643 Standard_Boolean VIsNotValid = ((myVMinParameter > aPoint.V()) || (aPoint.V() > myVMaxParameter));
644 Standard_Boolean solutionIsValid = !UIsNotValid && !VIsNotValid;
645 Standard_Real U = aPoint.U();
646 Standard_Real V = aPoint.V();
648 if(UIsNotValid || VIsNotValid) {
649 Standard_Boolean bUCorrected = Standard_True;
652 bUCorrected = Standard_False;
653 solutionIsValid = Standard_False;
655 if(mySurface.IsUPeriodic()) {
656 Standard_Real aNewU, aUPeriod, aEps, du;
658 aUPeriod = mySurface.UPeriod();
659 aEps = Epsilon(aUPeriod);
661 GeomInt::AdjustPeriodic(U, myUMinParameter, myUMaxParameter,
662 aUPeriod, aNewU, du, aEps);
663 solutionIsValid = Standard_True;
664 bUCorrected = Standard_True;
668 // if(solutionIsValid && VIsNotValid) {
669 if(bUCorrected && VIsNotValid) {
670 solutionIsValid = Standard_False;
672 if(mySurface.IsVPeriodic()) {
673 Standard_Real aNewV, aVPeriod, aEps, dv;
675 aVPeriod = mySurface.VPeriod();
676 aEps = Epsilon(aVPeriod);
678 GeomInt::AdjustPeriodic(V, myVMinParameter, myVMaxParameter,
679 aVPeriod, aNewV, dv, aEps);
680 solutionIsValid = Standard_True;
689 Standard_Integer aNbRanges = myRangeManager.Length();
691 ComputeRangeFromStartPoint(Standard_False, aPoint.W(), U, V);
692 ComputeRangeFromStartPoint(Standard_True, aPoint.W(), U, V);
694 if(aNbRanges == myRangeManager.Length()) {
695 SetEmptyResultRange(aPoint.W(), myRangeManager);
696 } // end if(aNbRanges == myRangeManager.Length())
700 for(i = 1; i <= anExactIntersector.NbSegments(); i++) {
701 const IntCurveSurface_IntersectionSegment& aSegment = anExactIntersector.Segment(i);
702 IntCurveSurface_IntersectionPoint aPoint1, aPoint2;
703 aSegment.Values(aPoint1, aPoint2);
705 Standard_Real aFirstParameter = (aPoint1.W() < myFirstParameter) ? myFirstParameter : aPoint1.W();
706 Standard_Real aLastParameter = (myLastParameter < aPoint2.W()) ? myLastParameter : aPoint2.W();
708 myRangeManager.InsertRange(aFirstParameter, aLastParameter, 2);
710 ComputeRangeFromStartPoint(Standard_False, aPoint1.W(), aPoint1.U(), aPoint1.V());
711 ComputeRangeFromStartPoint(Standard_True, aPoint2.W(), aPoint2.U(), aPoint2.V());
716 // ==================================================================================
717 // function: FastComputeExactIntersection
719 // ==================================================================================
720 Standard_Integer IntTools_BeanFaceIntersector::FastComputeExactIntersection()
722 Standard_Integer aresult;
723 GeomAbs_CurveType aCT;
724 GeomAbs_SurfaceType aST;
727 aCT=myCurve.GetType();
728 aST=mySurface.GetType();
730 if((aCT==GeomAbs_BezierCurve) ||
731 (aCT==GeomAbs_BSplineCurve) ||
732 (aCT==GeomAbs_OffsetCurve) ||
733 (aCT==GeomAbs_OtherCurve)) {
737 if(aST==GeomAbs_Plane) {
738 gp_Pln surfPlane = mySurface.Plane();
740 if(aCT==GeomAbs_Line) {
741 if((surfPlane.Distance(myCurve.Value(myFirstParameter)) < myCriteria) &&
742 (surfPlane.Distance(myCurve.Value(myLastParameter)) < myCriteria)) {
750 case GeomAbs_Circle: {
751 aDir = myCurve.Circle().Axis().Direction();
754 case GeomAbs_Ellipse: {
755 aDir = myCurve.Ellipse().Axis().Direction();
758 case GeomAbs_Hyperbola: {
759 aDir = myCurve.Hyperbola().Axis().Direction();
762 case GeomAbs_Parabola: {
763 aDir = myCurve.Parabola().Axis().Direction();
771 Standard_Real anAngle = aDir.Angle(surfPlane.Axis().Direction());
773 if(anAngle < Precision::Angular()) {
774 Standard_Boolean insertRange = Standard_False;
777 case GeomAbs_Circle: {
778 Standard_Real adist =
779 surfPlane.Distance(myCurve.Circle().Location()) +
780 myCurve.Circle().Radius() * Precision::Angular();
782 if(adist < myCriteria) {
783 insertRange = Standard_True;
787 case GeomAbs_Ellipse: {
788 Standard_Real adist =
789 surfPlane.Distance(myCurve.Ellipse().Location()) +
790 myCurve.Ellipse().MajorRadius() * Precision::Angular();
792 if(adist < myCriteria) {
793 insertRange = Standard_True;
797 case GeomAbs_Hyperbola:
798 case GeomAbs_Parabola: {
799 Standard_Real aMaxPar =
800 (Abs(myFirstParameter) > Abs(myLastParameter)) ?
801 Abs(myFirstParameter) : Abs(myLastParameter);
803 gp_Pnt aLoc = (aCT == GeomAbs_Parabola) ?
804 myCurve.Parabola().Location() :
805 myCurve.Hyperbola().Location();
806 Standard_Real adist = aLoc.Distance(myCurve.Value(aMaxPar));
807 adist = surfPlane.Distance(aLoc) + adist * Precision::Angular();
809 if(adist < myCriteria) {
810 insertRange = Standard_True;
822 }//if(anAngle < Precision::Angular()) {
824 }// if(aST==GeomAbs_Plane) {
826 if(aCT==GeomAbs_Circle) {
827 gp_Circ aCircle = myCurve.Circle();
829 if(aST==GeomAbs_Cylinder) {
830 gp_Cylinder aCylinder = mySurface.Cylinder();
831 gp_Dir aDir1(aCylinder.Axis().Direction());
832 gp_Dir aDir2(aCircle.Axis().Direction());
833 Standard_Real anAngle = aDir1.Angle(aDir2);
835 if(anAngle < Precision::Angular()) {
836 gp_Pnt aLoc = aCircle.Location();
837 gp_Lin anCylAxis(aCylinder.Axis());
838 Standard_Real alocdist = anCylAxis.Distance(aLoc);
839 Standard_Real adist = alocdist;
840 Standard_Real adiff = aCircle.Radius() - aCylinder.Radius();
843 if(adist < myCriteria) {
844 Standard_Real acylradius = aCylinder.Radius();
845 Standard_Real atmpvalue = aCircle.Radius() * sin(Precision::Angular());
846 Standard_Real aprojectedradius = atmpvalue;
848 sqrt((aCircle.Radius() * aCircle.Radius())
849 - (aprojectedradius * aprojectedradius));
850 adiff = aprojectedradius - acylradius;
851 adist = alocdist + Abs(adiff);
853 if(adist < myCriteria) { // Abs is important function here
858 }// if(aST==GeomAbs_Cylinder)
860 if(aST==GeomAbs_Sphere) {
861 gp_Pln aCirclePln(aCircle.Location(), aCircle.Axis().Direction());
862 IntAna_QuadQuadGeo anInter(aCirclePln, mySurface.Sphere());
864 if(anInter.IsDone()) {
865 if(anInter.TypeInter() == IntAna_Circle) {
866 gp_Circ aCircleToCompare = anInter.Circle(1);
867 Standard_Real adist =
868 aCircleToCompare.Location().Distance(aCircle.Location());
869 Standard_Real adiff = aCircle.Radius() - aCircleToCompare.Radius();
872 if(adist < myCriteria) {
877 }// if(aST==GeomAbs_Sphere) {
878 }// if(aCT==GeomAbs_Circle) {
880 //modified by NIZNHY-PKV Thu Mar 01 11:54:04 2012f
881 if(aST==GeomAbs_Cylinder) {
885 aCyl=mySurface.Cylinder();
887 const gp_Ax1& aAx1C=aCyl.Axis();
888 const gp_Dir& aDirC=aAx1C.Direction();
890 if(aCT==GeomAbs_Line) {
891 Standard_Real aCos, aAng2, aTolang2;
896 const gp_Dir& aDirL=aLin.Direction();
898 aCos=aDirC.Dot(aDirL);
900 aAng2 = 2.*(1. - aCos);
903 aAng2 = 2.*(1. + aCos);
906 if(aAng2<=aTolang2) {// IsParallel = Standard_True;
907 Standard_Boolean bFlag = Standard_False;
913 aPL[0]=myCurve.Value(myFirstParameter);
914 aPL[1]=myCurve.Value(myLastParameter);
916 for (i=0; i<2; ++i) {
917 aD=aLC.Distance(aPL[i]);
919 bFlag=(aD > myCriteria);
929 }//if(aCT==GeomAbs_Line) {
931 //modified by NIZNHY-PKV Thu Mar 01 11:54:06 2012t
934 //check intermediate point
936 Standard_Boolean bValid;
938 const TopoDS_Face& aF = mySurface.Face();
939 aTm = IntTools_Tools::IntermediatePoint(myFirstParameter, myLastParameter);
940 const gp_Pnt& aPm = myCurve.Value(aTm);
942 bValid = myContext->IsValidPointForFace(aPm, aF, myCriteria);
944 IntTools_Range aRange(myFirstParameter, myLastParameter);
945 myRangeManager.InsertRange(aRange, 2);
954 // ==================================================================================
955 // function: ComputeLinePlane
957 // ==================================================================================
958 void IntTools_BeanFaceIntersector::ComputeLinePlane()
960 Standard_Real Tolang = 1.e-9;
961 gp_Pln P = mySurface.Plane();
962 gp_Lin L = myCurve.Line();
964 myIsDone = Standard_True;
966 Standard_Real A,B,C,D;
967 Standard_Real Al,Bl,Cl;
968 Standard_Real Dis,Direc;
970 P.Coefficients(A,B,C,D);
971 gp_Pnt Orig(L.Location());
972 L.Direction().Coord(Al,Bl,Cl);
974 Direc=A*Al+B*Bl+C*Cl;
975 Dis = A*Orig.X() + B*Orig.Y() + C*Orig.Z() + D;
977 Standard_Boolean parallel = Standard_False, inplane = Standard_False;
978 if (Abs(Direc) < Tolang) {
979 parallel= Standard_True;
980 if (Abs(Dis) < myCriteria) {
981 inplane=Standard_True;
984 inplane=Standard_False;
988 gp_Pnt p1 = ElCLib::Value(myFirstParameter, L);
989 gp_Pnt p2 = ElCLib::Value(myLastParameter, L);
990 Standard_Real d1 = A*p1.X() + B*p1.Y() + C*p1.Z() + D;
992 Standard_Real d2 = A*p2.X() + B*p2.Y() + C*p2.Z() + D;
994 if(d1 <= myCriteria && d2 <= myCriteria) {
995 inplane=Standard_True;
1000 IntTools_Range aRange(myFirstParameter, myLastParameter);
1001 myResults.Append(aRange);
1009 Standard_Real t = - Dis/Direc;
1010 if(t < myFirstParameter || t > myLastParameter) {
1014 gp_Pnt pint(Orig.X()+t*Al, Orig.Y()+t*Bl, Orig.Z()+t*Cl);
1017 ElSLib::Parameters(P, pint, u, v);
1018 if(myUMinParameter > u || u > myUMaxParameter || myVMinParameter > v || v > myVMaxParameter) {
1022 // compute correct range on the edge
1023 Standard_Real anAngle, aDt;
1026 aDL = L.Position().Direction();
1027 aDP = P.Position().Direction();
1028 anAngle = Abs(M_PI_2 - aDL.Angle(aDP));
1030 aDt = IntTools_Tools::ComputeIntRange
1031 (myBeanTolerance, myFaceTolerance, anAngle);
1033 Standard_Real t1 = Max(myFirstParameter, t - aDt);
1034 Standard_Real t2 = Min(myLastParameter, t + aDt);
1035 IntTools_Range aRange(t1, t2);
1036 myResults.Append(aRange);
1042 // ==================================================================================
1043 // function: ComputeUsingExtremum
1045 // ==================================================================================
1046 void IntTools_BeanFaceIntersector::ComputeUsingExtremum()
1048 Standard_Real Tol, af, al;
1049 Tol = Precision::PConfusion();
1050 Handle(Geom_Curve) aCurve = BRep_Tool::Curve (myCurve.Edge(), af, al);
1051 GeomAdaptor_Surface aGASurface (myTrsfSurface,
1058 BndLib_AddSurface::Add(mySurface, 0., FBox);
1059 FBox.Enlarge(myFaceTolerance);
1061 for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
1063 if(myRangeManager.Flag(i) > 0)
1066 IntTools_Range aParamRange = myRangeManager.Range(i);
1067 Standard_Real anarg1 = aParamRange.First();
1068 Standard_Real anarg2 = aParamRange.Last();
1070 if(anarg2 - anarg1 < Precision::PConfusion()) {
1072 if(((i > 1) && (myRangeManager.Flag(i-1) == 2)) ||
1073 ((i < myRangeManager.Length()) && (myRangeManager.Flag(i+1) == 2))) {
1074 myRangeManager.SetFlag(i, 1);
1079 // check bounding boxes
1081 EBox.Add(myCurve.Value(anarg1));
1082 EBox.Add(myCurve.Value(anarg2));
1083 EBox.Enlarge(myBeanTolerance + myDeflection);
1085 if(EBox.IsOut(FBox)) {
1086 myRangeManager.SetFlag(i, 1);
1090 GeomAdaptor_Curve aGACurve(aCurve, anarg1, anarg2);
1091 Extrema_ExtCS theExtCS(aGACurve, aGASurface, Tol, Tol);
1092 myExtrema = theExtCS;
1094 if(myExtrema.IsDone() && (myExtrema.NbExt() || myExtrema.IsParallel())) {
1095 Standard_Integer anOldNbRanges = myRangeManager.Length();
1097 if (myExtrema.IsParallel()) {
1099 if(myExtrema.SquareDistance(1) < myCriteria * myCriteria) {
1100 Standard_Real U1, V1, U2, V2;
1101 Standard_Real adistance1 = Distance(anarg1, U1, V1);
1102 Standard_Real adistance2 = Distance(anarg2, U2, V2);
1103 Standard_Boolean validdistance1 = (adistance1 < myCriteria);
1104 Standard_Boolean validdistance2 = (adistance2 < myCriteria);
1106 if (validdistance1 && validdistance2) {
1107 myRangeManager.InsertRange(anarg1, anarg2, 2);
1111 if(validdistance1) {
1112 ComputeRangeFromStartPoint(Standard_True, anarg1, U1, V1);
1115 if(validdistance2) {
1116 ComputeRangeFromStartPoint(Standard_False, anarg2, U2, V2);
1119 Standard_Real a = anarg1;
1120 Standard_Real b = anarg2;
1121 Standard_Real da = adistance1;
1122 Standard_Real db = adistance2;
1123 Standard_Real asolution = a;
1124 Standard_Boolean found = Standard_False;
1126 while(((b - a) > myCurveResolution) && !found) {
1127 asolution = (a+b)*0.5;
1128 Standard_Real adist = Distance(asolution, U1, V1);
1130 if(adist < myCriteria) {
1131 found = Standard_True;
1146 ComputeRangeFromStartPoint(Standard_False, asolution, U1, V1);
1147 ComputeRangeFromStartPoint(Standard_True, asolution, U1, V1);
1150 myRangeManager.SetFlag(i, 1);
1157 myRangeManager.SetFlag(i, 1);
1161 Standard_Boolean solutionfound = Standard_False;
1163 for(Standard_Integer j = 1 ; j <= myExtrema.NbExt(); j++) {
1165 if(myExtrema.SquareDistance(j) < myCriteria * myCriteria) {
1168 myExtrema.Points(j, p1, p2);
1172 Standard_Integer aNbRanges = myRangeManager.Length();
1173 ComputeRangeFromStartPoint(Standard_False, p1.Parameter(), U, V);
1174 ComputeRangeFromStartPoint(Standard_True, p1.Parameter(), U, V);
1175 solutionfound = Standard_True;
1177 if(aNbRanges == myRangeManager.Length()) {
1178 SetEmptyResultRange(p1.Parameter(), myRangeManager);
1183 if(!solutionfound) {
1184 myRangeManager.SetFlag(i, 1);
1187 Standard_Integer adifference = myRangeManager.Length() - anOldNbRanges;
1189 if(adifference > 0) {
1192 } // end if(myExtrema.IsDone() && (myExtrema.NbExt() || myExtrema.IsParallel()))
1196 // ==================================================================================
1197 // function: ComputeNearRangeBoundaries
1199 // ==================================================================================
1200 void IntTools_BeanFaceIntersector::ComputeNearRangeBoundaries()
1202 Standard_Real U = myUMinParameter;
1203 Standard_Real V = myVMinParameter;
1205 for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
1207 if(myRangeManager.Flag(i) > 0)
1210 if((i > 1) && (myRangeManager.Flag(i-1) > 0))
1213 IntTools_Range aParamRange = myRangeManager.Range(i);
1215 if(Distance(aParamRange.First(), U, V) < myCriteria) {
1216 Standard_Integer aNbRanges = myRangeManager.Length();
1219 ComputeRangeFromStartPoint(Standard_False, aParamRange.First(), U, V, i-1);
1221 ComputeRangeFromStartPoint(Standard_True, aParamRange.First(), U, V, i + (myRangeManager.Length() - aNbRanges));
1223 if(aNbRanges == myRangeManager.Length()) {
1224 SetEmptyResultRange(aParamRange.First(), myRangeManager);
1229 if(myRangeManager.Flag(myRangeManager.Length()) == 0) {
1230 IntTools_Range aParamRange = myRangeManager.Range(myRangeManager.Length());
1232 if(Distance(aParamRange.Last(), U, V) < myCriteria) {
1233 Standard_Integer aNbRanges = myRangeManager.Length();
1235 ComputeRangeFromStartPoint(Standard_False, aParamRange.Last(), U, V, myRangeManager.Length());
1237 if(aNbRanges == myRangeManager.Length()) {
1238 SetEmptyResultRange(aParamRange.Last(), myRangeManager);
1244 // ==================================================================================
1245 // function: ComputeRangeFromStartPoint
1246 // purpose: Compute range using start point according to parameter theParameter,
1247 // increasing parameter on curve if ToIncreaseParameter == Standard_True or
1248 // decreasing parameter on curve if ToIncreaseParameter == Standard_False
1249 // ==================================================================================
1250 void IntTools_BeanFaceIntersector::ComputeRangeFromStartPoint(const Standard_Boolean ToIncreaseParameter,
1251 const Standard_Real theParameter,
1252 const Standard_Real theUParameter,
1253 const Standard_Real theVParameter)
1255 Standard_Integer aFoundIndex = myRangeManager.GetIndex(theParameter, ToIncreaseParameter);
1257 if(aFoundIndex == 0) {
1261 ComputeRangeFromStartPoint(ToIncreaseParameter, theParameter, theUParameter, theVParameter, aFoundIndex);
1264 // ==================================================================================
1265 // function: ComputeRangeFromStartPoint
1266 // purpose: Compute range using start point according to parameter theParameter,
1267 // increasing parameter on curve if ToIncreaseParameter == Standard_True or
1268 // decreasing parameter on curve if ToIncreaseParameter == Standard_False.
1269 // theIndex indicate that theParameter belong the range number theIndex.
1270 // ==================================================================================
1271 void IntTools_BeanFaceIntersector::ComputeRangeFromStartPoint(const Standard_Boolean ToIncreaseParameter,
1272 const Standard_Real theParameter,
1273 const Standard_Real theUParameter,
1274 const Standard_Real theVParameter,
1275 const Standard_Integer theIndex)
1277 if(myRangeManager.Flag(theIndex) > 0)
1280 Standard_Integer aValidIndex = theIndex;
1282 Standard_Real aMinDelta = myCurveResolution * 0.5;
1283 Standard_Real aDeltaRestrictor = myLastParameter - myFirstParameter;
1285 if(aMinDelta > aDeltaRestrictor)
1286 aMinDelta = aDeltaRestrictor * 0.5;
1288 Standard_Real tenOfMinDelta = aMinDelta * 10.;
1289 Standard_Real aDelta = myCurveResolution;
1291 Standard_Real aCurPar = (ToIncreaseParameter) ? (theParameter + aDelta) : (theParameter - aDelta);
1292 Standard_Real aPrevPar = theParameter;
1293 IntTools_Range aCurrentRange = myRangeManager.Range(aValidIndex);
1295 Standard_Boolean BoundaryCondition = (ToIncreaseParameter) ? (aCurPar > aCurrentRange.Last()) : (aCurPar < aCurrentRange.First());
1297 if(BoundaryCondition) {
1298 aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First();
1299 BoundaryCondition = Standard_False;
1302 Standard_Integer loopcounter = 0; // neccesary as infinite loop restricter
1303 Standard_Real U = theUParameter;
1304 Standard_Real V = theVParameter;
1305 Standard_Boolean anotherSolutionFound = Standard_False;
1307 Standard_Boolean isboundaryindex = Standard_False;
1308 Standard_Boolean isvalidindex = Standard_True;
1310 while((aDelta >= aMinDelta) && (loopcounter <= 10)) {
1311 Standard_Boolean pointfound = Standard_False;
1314 gp_Pnt aPoint = myCurve.Value(aCurPar);
1315 Extrema_GenLocateExtPS anExtrema(mySurface, 1.e-10, 1.e-10);
1316 anExtrema.Perform(aPoint, U, V);
1318 if(anExtrema.IsDone()) {
1319 if(anExtrema.SquareDistance() < myCriteria * myCriteria) {
1320 Extrema_POnSurf aPOnSurf = anExtrema.Point();
1321 aPOnSurf.Parameter(U, V);
1322 pointfound = Standard_True;
1326 pointfound = (Distance(aCurPar) < myCriteria);
1331 anotherSolutionFound = Standard_True;
1333 if(BoundaryCondition && (isboundaryindex || !isvalidindex))
1337 aDeltaRestrictor = aDelta;
1340 // if point found decide to increase aDelta using derivative of distance function
1343 aDelta = (pointfound) ? (aDelta * 2.) : (aDelta * 0.5);
1344 aDelta = (aDelta < aDeltaRestrictor) ? aDelta : aDeltaRestrictor;
1346 aCurPar = (ToIncreaseParameter) ? (aPrevPar + aDelta) : (aPrevPar - aDelta);
1349 // prevent infinite loop when (aPrevPar +/- aDelta) == aPrevPar == 0.
1352 if( aCurPar == aPrevPar )
1355 BoundaryCondition = (ToIncreaseParameter) ? (aCurPar > aCurrentRange.Last()) : (aCurPar < aCurrentRange.First());
1357 isboundaryindex = Standard_False;
1358 isvalidindex = Standard_True;
1360 if(BoundaryCondition) {
1361 isboundaryindex = ((!ToIncreaseParameter && (aValidIndex == 1)) ||
1362 (ToIncreaseParameter && (aValidIndex == myRangeManager.Length())));
1364 if(!isboundaryindex) {
1367 Standard_Integer aFlag = (ToIncreaseParameter) ? myRangeManager.Flag(aValidIndex + 1) : myRangeManager.Flag(aValidIndex - 1);
1370 aValidIndex = (ToIncreaseParameter) ? (aValidIndex + 1) : (aValidIndex - 1);
1371 aCurrentRange = myRangeManager.Range(aValidIndex);
1373 if((ToIncreaseParameter && (aCurPar > aCurrentRange.Last())) ||
1374 (!ToIncreaseParameter && (aCurPar < aCurrentRange.First()))) {
1375 aCurPar = (aCurrentRange.First() + aCurrentRange.Last()) * 0.5;
1380 isvalidindex = Standard_False;
1381 aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First();
1386 aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First();
1389 if(aDelta < tenOfMinDelta) {
1395 } // if(BoundaryCondition)
1398 if(anotherSolutionFound) {
1399 if(ToIncreaseParameter)
1400 myRangeManager.InsertRange(theParameter, aPrevPar, 2);
1402 myRangeManager.InsertRange(aPrevPar, theParameter, 2);
1406 // ---------------------------------------------------------------------------------
1407 // static function: SetEmptyResultRange
1409 // ---------------------------------------------------------------------------------
1410 static Standard_Boolean SetEmptyResultRange(const Standard_Real theParameter,
1411 IntTools_MarkedRangeSet& theMarkedRange) {
1413 const TColStd_SequenceOfInteger& anIndices = theMarkedRange.GetIndices(theParameter);
1414 Standard_Boolean add = (anIndices.Length() > 0);
1416 for(Standard_Integer k = 1; k <= anIndices.Length(); k++) {
1417 if(theMarkedRange.Flag(anIndices(k)) == 2) {
1418 add = Standard_False;
1424 theMarkedRange.InsertRange(theParameter, theParameter, 2);
1430 // ---------------------------------------------------------------------------------
1431 // static function: TestCoinside
1433 // ---------------------------------------------------------------------------------
1434 // static Standard_Boolean TestClose(const Extrema_ExtPS & theExt,
1435 // const Standard_Real theDist)
1437 // Standard_Boolean close = Standard_False;
1438 // if(!theExt.IsDone() || theExt.NbExt() == 0)
1441 // Standard_Integer ie;
1442 // for(ie = 1; ie <= theExt.NbExt(); ie++) {
1443 // Standard_Real dist = theExt.Value(ie);
1444 // if(dist <= theDist) {
1445 // close = Standard_True;
1453 // Standard_Boolean TestCoinside(const BRepAdaptor_Curve& theCurve,
1454 // const BRepAdaptor_Surface& theSurface)
1456 // Standard_Real cfp = theCurve.FirstParameter(), clp = theCurve.LastParameter();
1457 // Standard_Real cdp = fabs(clp - cfp) / 23.;
1459 // Standard_Integer i = 0;
1460 // Standard_Real tolE = theCurve.Tolerance(), tolF = theSurface.Tolerance();
1461 // Standard_Real tolT = tolE + tolF, tolU = 1.e-9, tolV = 1.e-9;
1464 // theCurve.D0(cfp,aP);
1465 // Extrema_ExtPS eps(aP,theSurface,tolU,tolV);
1467 // if(!TestClose(eps,tolT))
1468 // return Standard_False;
1470 // theCurve.D0(clp,aP);
1473 // if(!TestClose(eps,tolT))
1474 // return Standard_False;
1476 // Standard_Boolean close = Standard_True;
1478 // for(i = 1; i <= 22; i++) {
1479 // theCurve.D0((cfp+((Standard_Real)i)*cdp),aP);
1481 // if(!TestClose(eps,tolT)) {
1482 // close = Standard_False;
1489 // ======================================================================================================================
1490 // function: LocalizeSolutions
1492 // ======================================================================================================================
1493 Standard_Boolean IntTools_BeanFaceIntersector::LocalizeSolutions(const IntTools_CurveRangeSample& theCurveRange,
1494 const Bnd_Box& theBoxCurve,
1495 const IntTools_SurfaceRangeSample& theSurfaceRange,
1496 const Bnd_Box& theBoxSurface,
1497 IntTools_CurveRangeLocalizeData& theCurveData,
1498 IntTools_SurfaceRangeLocalizeData& theSurfaceData,
1499 IntTools_ListOfCurveRangeSample& theListCurveRange,
1500 IntTools_ListOfSurfaceRangeSample& theListSurfaceRange)
1502 Standard_Integer tIt = 0, uIt = 0, vIt = 0;
1505 IntTools_CurveRangeSample aRootRangeC(0);
1506 aRootRangeC.SetDepth(0);
1507 IntTools_SurfaceRangeSample aRootRangeS(0, 0, 0, 0);
1509 Bnd_Box aMainBoxC = theBoxCurve;
1510 Bnd_Box aMainBoxS = theBoxSurface;
1511 Standard_Boolean bMainBoxFoundS = Standard_False;
1512 Standard_Boolean bMainBoxFoundC = Standard_False;
1514 IntTools_ListOfCurveRangeSample aListCurveRangeFound;
1515 IntTools_ListOfSurfaceRangeSample aListSurfaceRangeFound;
1518 IntTools_Range aRangeC = theCurveRange.GetRange(myFirstParameter, myLastParameter, theCurveData.GetNbSample());
1519 Standard_Real localdiffC = (aRangeC.Last() - aRangeC.First()) / theCurveData.GetNbSample();
1521 Standard_Real aCurPar = aRangeC.First();
1522 Standard_Real aPrevPar = aRangeC.First();
1523 Standard_Integer aCurIndexInit = theCurveRange.GetRangeIndexDeeper(theCurveData.GetNbSample());
1526 TColStd_ListOfInteger aListCToAvoid;
1527 Standard_Boolean bGlobalCheckDone = Standard_False;
1532 Standard_Integer aCurIndexU = theSurfaceRange.GetRangeIndexUDeeper(theSurfaceData.GetNbSampleU());
1534 Standard_Integer aCurIndexVInit = theSurfaceRange.GetRangeIndexVDeeper(theSurfaceData.GetNbSampleV());
1535 IntTools_Range aRangeV = theSurfaceRange.GetRangeV(myVMinParameter, myVMaxParameter, theSurfaceData.GetNbSampleV());
1538 IntTools_Range aRangeU = theSurfaceRange.GetRangeU(myUMinParameter, myUMaxParameter, theSurfaceData.GetNbSampleU());
1539 Standard_Real aCurParU = aRangeU.First();
1540 Standard_Real aLocalDiffU = (aRangeU.Last() - aRangeU.First()) / theSurfaceData.GetNbSampleU();
1542 Standard_Real aPrevParU = aCurParU;
1543 Standard_Real aLocalDiffV = (aRangeV.Last() - aRangeV.First()) / theSurfaceData.GetNbSampleV();
1546 // ranges check.begin
1547 Standard_Boolean bAllowSamplingC = Standard_True;
1548 Standard_Boolean bAllowSamplingU = Standard_True;
1549 Standard_Boolean bAllowSamplingV = Standard_True;
1552 CheckSampling(theCurveRange, theSurfaceRange, theCurveData, theSurfaceData,
1553 localdiffC, aLocalDiffU, aLocalDiffV,
1554 bAllowSamplingC, bAllowSamplingU, bAllowSamplingV);
1557 if(!bAllowSamplingC && !bAllowSamplingU && !bAllowSamplingV) {
1558 theListCurveRange.Append(theCurveRange);
1559 theListSurfaceRange.Append(theSurfaceRange);
1560 return Standard_True;
1564 // init template. begin
1565 IntTools_CurveRangeSample aNewRangeCTemplate;
1567 if(!bAllowSamplingC) {
1568 aNewRangeCTemplate = theCurveRange;
1569 aCurIndexInit = theCurveRange.GetRangeIndex();
1570 localdiffC = (aRangeC.Last() - aRangeC.First());
1573 aNewRangeCTemplate.SetDepth(theCurveRange.GetDepth() + 1);
1574 aNewRangeCTemplate.SetRangeIndex(aCurIndexInit);
1577 IntTools_SurfaceRangeSample aNewRangeSTemplate = theSurfaceRange;
1579 if(bAllowSamplingU) {
1580 aNewRangeSTemplate.SetDepthU(theSurfaceRange.GetDepthU() + 1);
1583 aCurIndexU = aNewRangeSTemplate.GetIndexU();
1584 aLocalDiffU = aRangeU.Last() - aRangeU.First();
1587 if(bAllowSamplingV) {
1588 aNewRangeSTemplate.SetDepthV(theSurfaceRange.GetDepthV() + 1);
1591 aCurIndexVInit = theSurfaceRange.GetIndexV();
1592 aLocalDiffV = aRangeV.Last() - aRangeV.First();
1594 // init template. end
1597 Standard_Boolean bHasOut = Standard_False;
1598 const Standard_Integer nbU = (bAllowSamplingU) ? theSurfaceData.GetNbSampleU() : 1;
1599 const Standard_Integer nbV = (bAllowSamplingV) ? theSurfaceData.GetNbSampleV() : 1;
1600 const Standard_Integer nbC = (bAllowSamplingC) ? theCurveData.GetNbSample() : 1;
1602 for(uIt = 1; uIt <= nbU; uIt++, aCurIndexU++, aPrevParU = aCurParU) {
1603 aCurParU += aLocalDiffU;
1606 Standard_Real aCurParV = aRangeV.First();
1607 Standard_Real aPrevParV = aCurParV;
1608 Standard_Integer aCurIndexV = aCurIndexVInit;
1610 Standard_Boolean bHasOutV = Standard_False;
1613 for(vIt = 1; vIt <= nbV; vIt++, aCurIndexV++, aPrevParV = aCurParV) {
1615 aCurParV += aLocalDiffV;
1620 IntTools_SurfaceRangeSample aNewRangeS = aNewRangeSTemplate;
1622 if(bAllowSamplingU) {
1623 aNewRangeS.SetIndexU(aCurIndexU);
1626 if(bAllowSamplingV) {
1627 aNewRangeS.SetIndexV(aCurIndexV);
1630 if(theSurfaceData.IsRangeOut(aNewRangeS)) {
1631 bHasOutV = Standard_True;
1639 if(!theSurfaceData.FindBox(aNewRangeS, aBoxS)) {
1641 if(mySurface.GetType() == GeomAbs_BSplineSurface) {
1642 // if(Standard_False ) {
1643 Handle(Geom_BSplineSurface) aSurfBspl = Handle(Geom_BSplineSurface)::DownCast(myTrsfSurface);
1644 aBoxS = GetSurfaceBox(aSurfBspl, aPrevParU, aCurParU, aPrevParV, aCurParV, myCriteria, theSurfaceData);
1647 BndLib_AddSurface::Add(mySurface, aPrevParU, aCurParU, aPrevParV, aCurParV, myCriteria, aBoxS);
1649 // Bnd_Box aMainBoxC;
1651 if(!bMainBoxFoundC && theCurveData.FindBox(aRootRangeC, aMainBoxC)) {
1652 bMainBoxFoundC = Standard_True;
1655 if(aBoxS.IsOut(aMainBoxC)) {
1656 theSurfaceData.AddOutRange(aNewRangeS);
1657 bHasOutV = Standard_True;
1661 theSurfaceData.AddBox(aNewRangeS, aBoxS);
1664 if(aBoxS.IsOut(theBoxCurve)) {
1665 bHasOutV = Standard_True;
1669 IntTools_ListOfBox aListOfBox;
1670 TColStd_ListOfInteger aListOfIndex;
1672 Standard_Boolean bHasOutC = Standard_False;
1673 Standard_Integer aCurIndex = aCurIndexInit;
1675 // ////////////////////////////
1676 aCurPar = aRangeC.First();
1677 aPrevPar = aRangeC.First();
1678 IntTools_CurveRangeSample aCurRangeC = aNewRangeCTemplate;
1680 for (tIt = 1; tIt <= nbC; tIt++, aCurIndex++, aPrevPar = aCurPar) {
1682 aCurPar += localdiffC;
1684 // ignore already computed. begin
1685 Standard_Boolean bFound = Standard_False;
1686 TColStd_ListIteratorOfListOfInteger anItToAvoid(aListCToAvoid);
1688 for(; anItToAvoid.More(); anItToAvoid.Next()) {
1689 if(tIt == anItToAvoid.Value()) {
1690 bFound = Standard_True;
1696 if(bAllowSamplingC) {
1697 aCurRangeC.SetRangeIndex(aCurIndex);
1699 bFound = theCurveData.IsRangeOut(aCurRangeC);
1703 bHasOutC = Standard_True;
1706 // ignore already computed. end
1711 if(!theCurveData.FindBox(aCurRangeC, aBoxC)) {
1712 BndLib_Add3dCurve::Add(myCurve, aPrevPar, aCurPar, myCriteria, aBoxC);
1714 // Bnd_Box aMainBoxS;
1716 if(!bMainBoxFoundS && theSurfaceData.FindBox(aRootRangeS, aMainBoxS)) {
1717 bMainBoxFoundS = Standard_True;
1719 if(aBoxC.IsOut(aMainBoxS)) {
1720 theCurveData.AddOutRange(aCurRangeC);
1721 bHasOutC = Standard_True;
1725 theCurveData.AddBox(aCurRangeC, aBoxC);
1728 if(!bGlobalCheckDone && aBoxC.IsOut(theBoxSurface)) {
1729 aListCToAvoid.Append(tIt);
1730 bHasOutC = Standard_True;
1734 if(aBoxC.IsOut(aBoxS)) {
1735 bHasOutV = Standard_True;
1736 bHasOutC = Standard_True;
1741 aListOfIndex.Append(tIt);
1742 aListOfBox.Append(aBoxC);
1743 } // end for(tIt...)
1745 bGlobalCheckDone = Standard_True;
1748 bHasOutV = Standard_True;
1754 IntTools_CurveRangeSample aNewRangeC = aNewRangeCTemplate;
1756 aCurIndex = aCurIndexInit;
1757 TColStd_ListIteratorOfListOfInteger anItI(aListOfIndex);
1758 IntTools_ListIteratorOfListOfBox anItBox(aListOfBox);
1759 Standard_Boolean bUseOldC = Standard_False;
1760 Standard_Boolean bUseOldS = Standard_False;
1761 Standard_Boolean bCheckSize = !bHasOutC;
1763 for(; anItI.More() && anItBox.More(); anItI.Next(), anItBox.Next()) {
1764 aCurIndex = aCurIndexInit + anItI.Value() - 1;
1766 bUseOldS = Standard_False;
1768 if(bAllowSamplingC) {
1769 aNewRangeC.SetRangeIndex(aCurIndex);
1775 if((theCurveRange.GetDepth() == 0) ||
1776 (theSurfaceRange.GetDepthU() == 0) ||
1777 (theSurfaceRange.GetDepthV() == 0)) {
1778 bHasOutC = Standard_True;
1779 bHasOutV = Standard_True;
1781 else if((theCurveRange.GetDepth() < 4) &&
1782 (theSurfaceRange.GetDepthU() < 4) &&
1783 (theSurfaceRange.GetDepthV() < 4)) {
1784 Bnd_Box aBoxC = anItBox.Value();
1786 if(!aBoxC.IsWhole() && !aBoxS.IsWhole()) {
1787 Standard_Real aDiagC = aBoxC.SquareExtent();
1788 Standard_Real aDiagS = aBoxS.SquareExtent();
1790 if(aDiagC < aDiagS) {
1791 if((aDiagC * 10.) < aDiagS) {
1792 bUseOldC = Standard_True;
1793 bHasOutC = Standard_True;
1794 bHasOutV = Standard_True;
1799 if((aDiagS * 10.) < aDiagC) {
1800 bUseOldS = Standard_True;
1801 bHasOutC = Standard_True;
1802 bHasOutV = Standard_True;
1811 aListCurveRangeFound.Append(aNewRangeC);
1812 aListSurfaceRangeFound.Append(aNewRangeS);
1816 // if(bUseOldS || bAllowSamplingU || bAllowSamplingV) {
1817 // theSurfaceData.AddBox(aNewRangeS, aBoxS);
1820 if(bUseOldS && aNewRangeC.IsEqual(theCurveRange)) {
1821 return Standard_False;
1824 if(!LocalizeSolutions(aNewRangeC, anItBox.Value(),
1825 ((bUseOldS) ? theSurfaceRange : aNewRangeS),
1826 ((bUseOldS) ? theBoxSurface : aBoxS),
1827 theCurveData, theSurfaceData,
1828 theListCurveRange, theListSurfaceRange))
1829 return Standard_False;
1833 aListOfIndex.Clear();
1837 // theSurfaceData.AddBox(aNewRangeS, aBoxS);
1839 if(bUseOldC && bAllowSamplingC && (bAllowSamplingU || bAllowSamplingV)) {
1840 if(!LocalizeSolutions(theCurveRange, theBoxCurve,
1842 theCurveData, theSurfaceData,
1843 theListCurveRange, theListSurfaceRange))
1844 return Standard_False;
1847 } // end for (vIt...)
1850 bHasOut = Standard_True;
1855 theListCurveRange.Append(theCurveRange);
1856 theListSurfaceRange.Append(theSurfaceRange);
1859 IntTools_ListIteratorOfListOfCurveRangeSample anIt1(aListCurveRangeFound);
1860 IntTools_ListIteratorOfListOfSurfaceRangeSample anIt2(aListSurfaceRangeFound);
1862 for(; anIt1.More() && anIt2.More(); anIt1.Next(), anIt2.Next()) {
1863 theListCurveRange.Append(anIt1.Value());
1864 theListSurfaceRange.Append(anIt2.Value());
1867 return Standard_True;
1871 // ======================================================================================================================
1872 // function: ComputeLocalized
1874 // ======================================================================================================================
1875 Standard_Boolean IntTools_BeanFaceIntersector::ComputeLocalized() {
1876 Standard_Real Tol = Precision::PConfusion();
1878 IntTools_SurfaceRangeSample aSurfaceRange(0, 0, 0, 0);
1879 Standard_Real dMinU = 10. * Precision::PConfusion();
1880 Standard_Real dMinV = dMinU;
1881 IntTools_SurfaceRangeLocalizeData aSurfaceDataInit(3, 3, dMinU, dMinV);
1882 IntTools_SurfaceRangeLocalizeData& aSurfaceData = myContext->SurfaceData(mySurface.Face());
1883 aSurfaceData.RemoveRangeOutAll();
1884 aSurfaceData.ClearGrid();
1887 Standard_Boolean bFBoxFound = aSurfaceData.FindBox(aSurfaceRange, FBox);
1889 if(mySurface.GetType() == GeomAbs_BSplineSurface) {
1890 Handle(Geom_BSplineSurface) aSurfBspl = Handle(Geom_BSplineSurface)::DownCast(myTrsfSurface);
1892 ComputeGridPoints(aSurfBspl, myUMinParameter, myUMaxParameter,
1893 myVMinParameter, myVMaxParameter, myFaceTolerance,
1897 FBox = GetSurfaceBox(aSurfBspl, myUMinParameter, myUMaxParameter,
1898 myVMinParameter, myVMaxParameter, myCriteria,
1900 aSurfaceData.AddBox(aSurfaceRange, FBox);
1903 } else if(!bFBoxFound) {
1905 BndLib_AddSurface::Add(mySurface, myUMinParameter, myUMaxParameter, myVMinParameter, myVMaxParameter, myFaceTolerance, FBox);
1906 aSurfaceData.AddBox(aSurfaceRange, FBox);
1911 BndLib_Add3dCurve::Add(myCurve.Trim(myFirstParameter, myLastParameter, Precision::PConfusion())->Curve(), myBeanTolerance, EBox);
1913 if(EBox.IsOut(FBox)) {
1914 for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
1915 myRangeManager.SetFlag(i, 1);
1917 aSurfaceData.ClearGrid();
1919 return Standard_True;
1922 IntTools_ListOfCurveRangeSample aListCurveRange;
1923 IntTools_ListOfSurfaceRangeSample aListSurfaceRange;
1925 IntTools_CurveRangeSample aCurveRange(0);
1926 aCurveRange.SetDepth(0);
1927 Standard_Integer nbSampleC = 3;
1928 Standard_Integer nbSampleU = aSurfaceData.GetNbSampleU();
1929 Standard_Integer nbSampleV = aSurfaceData.GetNbSampleV();
1930 Standard_Real dMinC = 10. * myCurveResolution;
1931 IntTools_ListOfCurveRangeSample aListOut;
1934 Standard_Boolean bAllowSamplingC = Standard_True;
1935 Standard_Boolean bAllowSamplingU = Standard_True;
1936 Standard_Boolean bAllowSamplingV = Standard_True;
1937 IntTools_CurveRangeLocalizeData aCurveDataTmp(nbSampleC, dMinC);
1938 IntTools_SurfaceRangeLocalizeData aSurfaceDataTmp(nbSampleU, nbSampleV, dMinU, dMinV);
1940 CheckSampling(aCurveRange, aSurfaceRange, aCurveDataTmp, aSurfaceDataTmp,
1941 myLastParameter - myFirstParameter,
1942 myUMaxParameter - myUMinParameter,
1943 myVMaxParameter - myVMinParameter,
1944 bAllowSamplingC, bAllowSamplingU, bAllowSamplingV);
1948 IntTools_CurveRangeLocalizeData aCurveData(nbSampleC, dMinC);
1950 aCurveData.AddBox(aCurveRange, EBox);
1952 if(!LocalizeSolutions(aCurveRange, EBox, aSurfaceRange, FBox,
1953 aCurveData, aSurfaceData,
1954 aListCurveRange, aListSurfaceRange)) {
1955 aSurfaceData.ClearGrid();
1957 return Standard_False;
1960 IntTools_ListOfCurveRangeSample aListCurveRangeSort;
1961 IntTools_ListOfSurfaceRangeSample aListSurfaceRangeSort;
1963 MergeSolutions(aListCurveRange, aListSurfaceRange, aListCurveRangeSort, aListSurfaceRangeSort);
1965 IntTools_ListIteratorOfListOfCurveRangeSample anItC(aListCurveRangeSort);
1966 IntTools_ListIteratorOfListOfSurfaceRangeSample anItS(aListSurfaceRangeSort);
1967 IntTools_SurfaceRangeSample aRangeSPrev;
1969 Extrema_GenExtCS anExtremaGen;
1971 for(; anItC.More() && anItS.More(); anItC.Next(), anItS.Next()) {
1973 IntTools_Range aRangeC(myFirstParameter, myLastParameter);
1976 aRangeC = anItC.Value().GetRange(myFirstParameter, myLastParameter, nbSampleC);
1978 IntTools_Range aRangeU(myUMinParameter, myUMaxParameter);
1981 aRangeU = anItS.Value().GetRangeU(myUMinParameter, myUMaxParameter, nbSampleU);
1983 IntTools_Range aRangeV(myVMinParameter, myVMaxParameter);
1986 aRangeV = anItS.Value().GetRangeV(myVMinParameter, myVMaxParameter, nbSampleV);
1988 Standard_Real anarg1 = aRangeC.First(), anarg2 = aRangeC.Last();
1990 Standard_Boolean bFound = Standard_False;
1992 Standard_Integer nMinIndex = myRangeManager.Length();
1993 Standard_Integer nMaxIndex = -1;
1994 const TColStd_SequenceOfInteger& anInds1 = myRangeManager.GetIndices(anarg1);
1995 Standard_Integer indIt = 1;
1997 for(indIt = 1 ; indIt <= anInds1.Length(); indIt++) {
1998 Standard_Integer nIndex = anInds1.Value(indIt);
1999 nMinIndex = (nMinIndex > nIndex) ? nIndex : nMinIndex;
2000 nMaxIndex = (nMaxIndex < nIndex) ? nIndex : nMaxIndex;
2003 for(indIt = nMinIndex ; indIt <= nMaxIndex; indIt++) {
2004 if(myRangeManager.Flag(indIt) == 2) {
2005 bFound = Standard_True;
2012 nMinIndex = (nMaxIndex >= 0) ? nMaxIndex : nMinIndex;
2013 const TColStd_SequenceOfInteger& anInds2 = myRangeManager.GetIndices(anarg2);
2015 for(indIt = 1 ; indIt <= anInds2.Length(); indIt++) {
2016 Standard_Integer nIndex = anInds2.Value(indIt);
2017 nMinIndex = (nMinIndex > nIndex) ? nIndex : nMinIndex;
2018 nMaxIndex = (nMaxIndex < nIndex) ? nIndex : nMaxIndex;
2021 for(indIt = nMinIndex ; indIt <= nMaxIndex; indIt++) {
2022 if(myRangeManager.Flag(indIt) == 2) {
2023 bFound = Standard_True;
2031 Standard_Real parUF = aRangeU.First(), parUL = aRangeU.Last();
2032 Standard_Real parVF = aRangeV.First(), parVL = aRangeV.Last();
2034 if(aRangeSPrev.IsEqual(anItS.Value())) {
2035 anExtremaGen.Perform(myCurve, 10, anarg1, anarg2, Tol);
2038 anExtremaGen.Initialize(mySurface, 10, 10, parUF, parUL, parVF, parVL, Tol);
2039 anExtremaGen.Perform(myCurve, 10, anarg1, anarg2, Tol);
2042 if(anExtremaGen.IsDone() && (anExtremaGen.NbExt() > 0)) {
2044 for(Standard_Integer j = 1 ; j <= anExtremaGen.NbExt(); j++) {
2046 if(anExtremaGen.SquareDistance(j) < myCriteria * myCriteria) {
2050 p1 = anExtremaGen.PointOnCurve(j);
2051 p2 = anExtremaGen.PointOnSurface(j);
2052 Standard_Real U, V, T;
2056 if (myCurve.IsPeriodic())
2057 T = ElCLib::InPeriod(T, anarg1, anarg1 + myCurve.Period());
2058 if (mySurface.IsUPeriodic())
2059 U = ElCLib::InPeriod(U, parUF, parUF + mySurface.UPeriod());
2060 if (mySurface.IsVPeriodic())
2061 V = ElCLib::InPeriod(V, parVF, parVF + mySurface.VPeriod());
2063 //To avoid occasional going out of boundaries because of numerical
2065 if(U < myUMinParameter) U = myUMinParameter;
2066 if(U > myUMaxParameter) U = myUMaxParameter;
2067 if(V < myVMinParameter) V = myVMinParameter;
2068 if(V > myVMaxParameter) V = myVMaxParameter;
2070 Standard_Integer aNbRanges = myRangeManager.Length();
2071 ComputeRangeFromStartPoint(Standard_False, T, U, V);
2072 ComputeRangeFromStartPoint(Standard_True, T, U, V);
2074 if(aNbRanges == myRangeManager.Length()) {
2075 SetEmptyResultRange(T, myRangeManager);
2081 myRangeManager.InsertRange(anarg1, anarg2, 0);
2084 aRangeSPrev = anItS.Value();
2088 aCurveData.ListRangeOut(aListOut);
2092 if(bAllowSamplingC) {
2093 IntTools_ListIteratorOfListOfCurveRangeSample anItC(aListOut);
2095 for(; anItC.More(); anItC.Next()) {
2096 IntTools_Range aRangeC =anItC.Value().GetRange(myFirstParameter, myLastParameter, nbSampleC);
2097 myRangeManager.InsertRange(aRangeC.First(), aRangeC.Last(), 1);
2100 ComputeNearRangeBoundaries();
2102 aSurfaceData.ClearGrid();
2104 return Standard_True;
2107 // ======================================================================================================================
2108 // function: TestComputeCoinside
2110 // ======================================================================================================================
2111 Standard_Boolean IntTools_BeanFaceIntersector::TestComputeCoinside()
2113 Standard_Real cfp = myFirstParameter, clp = myLastParameter;
2114 const Standard_Integer nbSeg = 23;
2115 Standard_Real cdp = (clp - cfp) / (Standard_Real )nbSeg;
2117 Standard_Integer i = 0;
2121 if(Distance(cfp, U, V) > myCriteria)
2122 return Standard_False;
2125 ComputeRangeFromStartPoint(Standard_True, cfp, U, V);
2128 Standard_Integer aFoundIndex = myRangeManager.GetIndex(clp, Standard_False );
2130 if(aFoundIndex != 0) {
2131 if(myRangeManager.Flag(aFoundIndex) == 2)
2132 return Standard_True;
2135 if(Distance(clp, U, V) > myCriteria)
2136 return Standard_False;
2139 ComputeRangeFromStartPoint(Standard_False, clp, U, V);
2142 for(i = 1; i < nbSeg; i++) {
2143 Standard_Real aPar = (cfp+((Standard_Real)i)*cdp);
2145 if(Distance(aPar, U, V) > myCriteria)
2146 return Standard_False;
2148 Standard_Integer aNbRanges = myRangeManager.Length();
2149 ComputeRangeFromStartPoint(Standard_False, aPar, U, V);
2150 ComputeRangeFromStartPoint(Standard_True, aPar, U, V);
2152 if(aNbRanges == myRangeManager.Length()) {
2153 SetEmptyResultRange(aPar, myRangeManager);
2157 return Standard_True;
2160 // Modified by skv - Wed Nov 2 15:21:11 2005 Optimization Begin
2161 // ---------------------------------------------------------------------------------
2162 // static function: GetSurfaceBox
2164 // ---------------------------------------------------------------------------------
2165 Bnd_Box GetSurfaceBox(const Handle(Geom_BSplineSurface) &theSurf,
2166 const Standard_Real theFirstU,
2167 const Standard_Real theLastU,
2168 const Standard_Real theFirstV,
2169 const Standard_Real theLastV,
2170 const Standard_Real theTolerance,
2171 IntTools_SurfaceRangeLocalizeData &theSurfaceData)
2175 BuildBox(theSurf, theFirstU, theLastU, theFirstV, theLastV,
2176 theSurfaceData, aTotalBox);
2178 aTotalBox.Enlarge(theTolerance);
2183 // ---------------------------------------------------------------------------------
2184 // static function: ComputeGridPoints
2186 // ---------------------------------------------------------------------------------
2187 void ComputeGridPoints
2188 (const Handle(Geom_BSplineSurface) &theSurf,
2189 const Standard_Real theFirstU,
2190 const Standard_Real theLastU,
2191 const Standard_Real theFirstV,
2192 const Standard_Real theLastV,
2193 const Standard_Real theTolerance,
2194 IntTools_SurfaceRangeLocalizeData &theSurfaceData)
2199 Standard_Integer aNbSamples[2] = { theSurf->UDegree(),
2200 theSurf->VDegree() };
2201 Standard_Integer aNbKnots[2] = { theSurf->NbUKnots(),
2202 theSurf->NbVKnots() };
2203 TColStd_Array1OfReal aKnotsU(1, aNbKnots[0]);
2204 TColStd_Array1OfReal aKnotsV(1, aNbKnots[1]);
2206 theSurf->UKnots(aKnotsU);
2207 theSurf->VKnots(aKnotsV);
2209 Standard_Integer iLmI;
2210 Standard_Integer iMin[2] = { -1, -1 };
2211 Standard_Integer iMax[2] = { -1, -1 };
2212 Standard_Integer aNbGridPnts[2];
2213 Standard_Real aFPar[2] = { theFirstU, theFirstV};
2214 Standard_Real aLPar[2] = { theLastU, theLastV};
2215 Standard_Real aFpTol[2] = { aFPar[0] + theTolerance,
2216 aFPar[1] + theTolerance };
2217 Standard_Real aFmTol[2] = { aFPar[0] - theTolerance,
2218 aFPar[1] - theTolerance };
2219 Standard_Real aLpTol[2] = { aLPar[0] + theTolerance,
2220 aLPar[1] + theTolerance };
2221 Standard_Real aLmTol[2] = { aLPar[0] - theTolerance,
2222 aLPar[1] - theTolerance };
2225 // Compute number of U and V grid points.
2226 for (j = 0; j < 2; j++) {
2227 const TColStd_Array1OfReal &aKnots = (j == 0) ? aKnotsU : aKnotsV;
2229 for (i = 1; i <= aNbKnots[j] && (iMin[j] == -1 || iMax[j] == -1); i++) {
2230 if (iMin[j] == -1 && aFpTol[j] < aKnots.Value(i))
2233 iLmI = aNbKnots[j] - i + 1;
2235 if (iMax[j] == -1 && aLmTol[j] > aKnots.Value(iLmI))
2239 // If indices are not found, return.
2240 //if (iMin[j] == -1 || iMax[j] == -1)
2246 iMax[j] = aNbKnots[j];
2251 if (iMax[j] > aNbKnots[j])
2252 iMax[j] = aNbKnots[j];
2254 if (iMax[j] < iMin[j])
2257 if (iMax[j] == iMin[j]) {
2262 if (iMax[j] > aNbKnots[j])
2263 iMax[j] = aNbKnots[j];
2267 aNbGridPnts[j] = (iMax[j] - iMin[j])*aNbSamples[j] + 1;
2269 // Setting the number of grid points.
2271 theSurfaceData.SetRangeUGrid(aNbGridPnts[j]);
2273 theSurfaceData.SetRangeVGrid(aNbGridPnts[j]);
2275 // Setting the first and last parameters.
2276 Standard_Integer iAbs = 1;
2277 Standard_Real aMinPar;
2278 Standard_Real aMaxPar = (j == 0) ? theLastU : theLastV;
2280 for (i = iMin[j]; i < iMax[j]; i++) {
2281 // Get the first parameter.
2284 if (aFmTol[j] > aKnots.Value(iMin[j]))
2287 aMinPar = aKnots.Value(iMin[j]);
2289 aMinPar = aKnots.Value(i);
2292 // Get the last parameter.
2293 if (i == iMax[j] - 1) {
2295 if (aLpTol[j] < aKnots.Value(iMax[j]))
2298 aMaxPar = aKnots.Value(iMax[j]);
2300 aMaxPar = aKnots.Value(i + 1);
2303 // Compute grid parameters.
2304 Standard_Real aDelta = (aMaxPar - aMinPar)/aNbSamples[j];
2306 for (k = 0; k < aNbSamples[j]; k++, aMinPar += aDelta) {
2308 theSurfaceData.SetUParam(iAbs++, aMinPar);
2310 theSurfaceData.SetVParam(iAbs++, aMinPar);
2314 // Add the last parameter
2316 theSurfaceData.SetUParam(iAbs++, aMaxPar);
2318 theSurfaceData.SetVParam(iAbs++, aMaxPar);
2321 // Compute of grid points.
2323 Standard_Real aParU;
2324 Standard_Real aParV;
2326 for (i = 1; i <= aNbGridPnts[0]; i++) {
2327 aParU = theSurfaceData.GetUParam(i);
2329 for (j = 1; j <= aNbGridPnts[1]; j++) {
2330 aParV = theSurfaceData.GetVParam(j);
2332 theSurf->D0(aParU, aParV, aPnt);
2333 theSurfaceData.SetGridPoint(i, j, aPnt);
2337 // Compute deflection.
2338 Standard_Real aDef = 0.;
2339 // Standard_Real aDefLin;
2340 // Standard_Real aParMid;
2341 // Standard_Real aParConst;
2342 // Standard_Real aDistPP;
2347 // // Compute DU deflection.
2348 // for (i = 1; i < aNbGridPnts[0]; i++) {
2349 // aParMid = 0.5*(theSurfaceData.GetUParam(i + 1) +
2350 // theSurfaceData.GetUParam(i));
2352 // for (j = 1; j <= aNbGridPnts[1]; j++) {
2353 // const gp_Pnt &thePnt1 = theSurfaceData.GetGridPoint(i, j);
2354 // const gp_Pnt &thePnt2 = theSurfaceData.GetGridPoint(i + 1, j);
2356 // aVec.SetXYZ(thePnt2.XYZ().Subtracted(thePnt1.XYZ()));
2357 // aDistPP = aVec.Magnitude();
2359 // if (aDistPP > theTolerance) {
2360 // // Computation of a distance of a middle point from the line P1 - P2.
2361 // aParConst = theSurfaceData.GetVParam(j);
2362 // theSurf->D0(aParMid, aParConst, aPntMid);
2363 // aCoord = aPntMid.XYZ();
2364 // aCoord.Subtract(thePnt1.XYZ());
2365 // aCoord.Cross (aVec.XYZ());
2366 // aCoord.Divide(aDistPP);
2367 // aDefLin = aCoord.Modulus();
2369 // if (aDefLin > aDef)
2375 // // Compute DV deflection.
2376 // for (j = 1; j < aNbGridPnts[1]; j++) {
2377 // aParMid = 0.5*(theSurfaceData.GetVParam(j + 1) +
2378 // theSurfaceData.GetVParam(j));
2380 // for (i = 1; i <= aNbGridPnts[0]; i++) {
2381 // const gp_Pnt &thePnt1 = theSurfaceData.GetGridPoint(i, j);
2382 // const gp_Pnt &thePnt2 = theSurfaceData.GetGridPoint(i, j + 1);
2384 // aVec.SetXYZ(thePnt2.XYZ().Subtracted(thePnt1.XYZ()));
2385 // aDistPP = aVec.Magnitude();
2387 // if (aDistPP > theTolerance) {
2388 // // Computation of a distance of a middle point from the line P1 - P2.
2389 // aParConst = theSurfaceData.GetUParam(i);
2390 // theSurf->D0(aParConst, aParMid, aPntMid);
2391 // aCoord = aPntMid.XYZ();
2392 // aCoord.Subtract(thePnt1.XYZ());
2393 // aCoord.Cross (aVec.XYZ());
2394 // aCoord.Divide(aDistPP);
2395 // aDefLin = aCoord.Modulus();
2397 // if (aDefLin > aDef)
2403 if (theTolerance > aDef)
2404 aDef = theTolerance;
2407 theSurfaceData.SetGridDeflection(aDef);
2410 // ---------------------------------------------------------------------------------
2411 // static function: BuildBox
2412 // purpose: Compute bounding box.
2413 // ---------------------------------------------------------------------------------
2414 void BuildBox(const Handle(Geom_BSplineSurface) &theSurf,
2415 const Standard_Real theFirstU,
2416 const Standard_Real theLastU,
2417 const Standard_Real theFirstV,
2418 const Standard_Real theLastV,
2419 IntTools_SurfaceRangeLocalizeData &theSurfaceData,
2424 Standard_Integer aNbUPnts;
2425 Standard_Integer aNbVPnts;
2426 Standard_Real aParam;
2429 theSurfaceData.SetFrame(theFirstU, theLastU, theFirstV, theLastV);
2430 aNbUPnts = theSurfaceData.GetNBUPointsInFrame();
2431 aNbVPnts = theSurfaceData.GetNBVPointsInFrame();
2433 // Add corner points.
2434 theSurf->D0(theFirstU, theFirstV, aPnt);
2436 theSurf->D0(theLastU, theFirstV, aPnt);
2438 theSurf->D0(theFirstU, theLastV, aPnt);
2440 theSurf->D0(theLastU, theLastV, aPnt);
2443 for (i = 1; i <= aNbUPnts; i++) {
2444 // Add top and bottom points.
2445 aParam = theSurfaceData.GetUParamInFrame(i);
2446 theSurf->D0(aParam, theFirstV, aPnt);
2448 theSurf->D0(aParam, theLastV, aPnt);
2451 // Add internal points.
2452 for (j = 1; j <= aNbVPnts; j++) {
2453 const gp_Pnt &aGridPnt = theSurfaceData.GetPointInFrame(i, j);
2455 theBox.Add(aGridPnt);
2459 // Add left and right points.
2460 for (j = 1; j <= aNbVPnts; j++) {
2461 aParam = theSurfaceData.GetVParamInFrame(j);
2462 theSurf->D0(theFirstU, aParam, aPnt);
2464 theSurf->D0(theLastU, aParam, aPnt);
2468 theBox.Enlarge(theSurfaceData.GetGridDeflection());
2470 // Modified by skv - Wed Nov 2 15:21:11 2005 Optimization End
2473 // ---------------------------------------------------------------------------------
2474 // static function: MergeSolutions
2476 // ---------------------------------------------------------------------------------
2477 static void MergeSolutions(const IntTools_ListOfCurveRangeSample& theListCurveRange,
2478 const IntTools_ListOfSurfaceRangeSample& theListSurfaceRange,
2479 IntTools_ListOfCurveRangeSample& theListCurveRangeSort,
2480 IntTools_ListOfSurfaceRangeSample& theListSurfaceRangeSort) {
2482 IntTools_ListIteratorOfListOfCurveRangeSample anItC2;
2483 IntTools_ListIteratorOfListOfSurfaceRangeSample anItS1(theListSurfaceRange), anItS2;
2484 IntTools_MapOfSurfaceSample aMapToAvoid;
2486 for(; anItS1.More(); anItS1.Next()) {
2487 const IntTools_SurfaceRangeSample& aRangeS = anItS1.Value();
2489 if(aMapToAvoid.Contains(aRangeS))
2491 aMapToAvoid.Add(aRangeS);
2493 anItC2.Initialize(theListCurveRange);
2494 anItS2.Initialize(theListSurfaceRange);
2496 for(; anItS2.More() && anItC2.More(); anItS2.Next(), anItC2.Next()) {
2497 if(aRangeS.IsEqual(anItS2.Value())) {
2498 theListCurveRangeSort.Append(anItC2.Value());
2499 theListSurfaceRangeSort.Append(anItS2.Value());
2505 // ---------------------------------------------------------------------------------
2506 // static function: CheckSampling
2508 // ---------------------------------------------------------------------------------
2509 static void CheckSampling(const IntTools_CurveRangeSample& theCurveRange,
2510 const IntTools_SurfaceRangeSample& theSurfaceRange,
2511 const IntTools_CurveRangeLocalizeData& theCurveData,
2512 const IntTools_SurfaceRangeLocalizeData& theSurfaceData,
2513 const Standard_Real DiffC,
2514 const Standard_Real DiffU,
2515 const Standard_Real DiffV,
2516 Standard_Boolean& bAllowSamplingC,
2517 Standard_Boolean& bAllowSamplingU,
2518 Standard_Boolean& bAllowSamplingV) {
2520 const Standard_Real dLimit = 1000;
2521 bAllowSamplingC = Standard_True;
2522 bAllowSamplingU = Standard_True;
2523 bAllowSamplingV = Standard_True;
2526 if((pow((Standard_Real)theCurveData.GetNbSample(), (Standard_Real )(theCurveRange.GetDepth() + 1)) > dLimit) ||
2527 ((DiffC / theCurveData.GetNbSample()) < theCurveData.GetMinRange())) {
2528 bAllowSamplingC = Standard_False;
2531 if((pow((Standard_Real )theSurfaceData.GetNbSampleU(), (Standard_Real )(theSurfaceRange.GetDepthU() + 1)) > dLimit) ||
2532 ((DiffU / theSurfaceData.GetNbSampleU()) < theSurfaceData.GetMinRangeU())) {
2533 bAllowSamplingU = Standard_False;
2537 if((pow((Standard_Real )theSurfaceData.GetNbSampleV(), (Standard_Real )(theSurfaceRange.GetDepthV() + 1)) > dLimit) ||
2538 ((DiffV / theSurfaceData.GetNbSampleV()) < theSurfaceData.GetMinRangeV())) {
2539 bAllowSamplingV = Standard_False;