1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
19 #include <IntTools_BeanFaceIntersector.ixx>
21 #include <IntTools_Root.hxx>
22 #include <Precision.hxx>
23 #include <Extrema_POnCurv.hxx>
24 #include <Extrema_POnSurf.hxx>
25 #include <BRep_Tool.hxx>
26 #include <Geom_Surface.hxx>
27 #include <TColStd_Array1OfReal.hxx>
28 #include <TColStd_Array1OfBoolean.hxx>
29 #include <TColStd_ListOfInteger.hxx>
30 #include <TColStd_ListIteratorOfListOfInteger.hxx>
31 #include <IntTools_EdgeFace.hxx>
32 #include <IntTools_ListOfCurveRangeSample.hxx>
33 #include <IntTools_ListOfSurfaceRangeSample.hxx>
34 #include <IntTools_ListOfBox.hxx>
35 #include <IntTools_ListIteratorOfListOfBox.hxx>
36 #include <IntTools_ListIteratorOfListOfCurveRangeSample.hxx>
37 #include <IntTools_ListIteratorOfListOfSurfaceRangeSample.hxx>
38 #include <IntTools_MapIteratorOfMapOfCurveSample.hxx>
39 #include <TColgp_Array1OfPnt2d.hxx>
41 #include <Geom_Curve.hxx>
42 #include <Geom_Surface.hxx>
43 #include <Geom_BSplineSurface.hxx>
44 #include <GeomAdaptor_Curve.hxx>
45 #include <GeomAdaptor_Surface.hxx>
46 #include <Extrema_ExtCS.hxx>
47 #include <Extrema_ExtPS.hxx>
48 #include <IntTools.hxx>
49 #include <BOPInt_Context.hxx>
50 #include <IntTools_Tools.hxx>
51 #include <GeomAPI_ProjectPointOnCurve.hxx>
52 #include <IntCurveSurface_HInter.hxx>
53 #include <IntCurveSurface_IntersectionPoint.hxx>
54 #include <IntCurveSurface_IntersectionSegment.hxx>
55 #include <IntAna_QuadQuadGeo.hxx>
56 #include <BRepAdaptor_HCurve.hxx>
57 #include <BRepAdaptor_HSurface.hxx>
58 #include <Extrema_GenLocateExtPS.hxx>
59 #include <Extrema_GenExtCS.hxx>
60 #include <Bnd_Box.hxx>
61 #include <BndLib_AddSurface.hxx>
62 #include <BndLib_Add3dCurve.hxx>
65 #include <BOPTools_AlgoTools.hxx>
67 static Standard_Boolean AdjustPeriodic(const Standard_Real U,
68 const Standard_Real UFirst,
69 const Standard_Real ULast,
70 const Standard_Real Period,
71 Standard_Real& UResult);
73 static Standard_Boolean SetEmptyResultRange(const Standard_Real theParameter,
74 IntTools_MarkedRangeSet& theMarkedRange);
76 // static Standard_Boolean TestCoinside(const BRepAdaptor_Curve& theCurve,
77 // const BRepAdaptor_Surface& theSurface);
79 // Modified by skv - Wed Nov 2 15:21:11 2005 Optimization Begin
80 static Bnd_Box GetSurfaceBox
81 (const Handle(Geom_BSplineSurface) &theSurf,
82 const Standard_Real theFirstU,
83 const Standard_Real theLastU,
84 const Standard_Real theFirstV,
85 const Standard_Real theLastV,
86 const Standard_Real theTolerance,
87 IntTools_SurfaceRangeLocalizeData &theSurfaceData);
89 static void ComputeGridPoints
90 (const Handle(Geom_BSplineSurface) &theSurf,
91 const Standard_Real theFirstU,
92 const Standard_Real theLastU,
93 const Standard_Real theFirstV,
94 const Standard_Real theLastV,
95 const Standard_Real theTolerance,
96 IntTools_SurfaceRangeLocalizeData &theSurfaceData);
98 static void BuildBox(const Handle(Geom_BSplineSurface) &theSurf,
99 const Standard_Real theFirstU,
100 const Standard_Real theLastU,
101 const Standard_Real theFirstV,
102 const Standard_Real theLastV,
103 IntTools_SurfaceRangeLocalizeData &theSurfaceData,
105 // Modified by skv - Wed Nov 2 15:21:11 2005 Optimization End
107 static void MergeSolutions(const IntTools_ListOfCurveRangeSample& theListCurveRange,
108 const IntTools_ListOfSurfaceRangeSample& theListSurfaceRange,
109 IntTools_ListOfCurveRangeSample& theListCurveRangeSort,
110 IntTools_ListOfSurfaceRangeSample& theListSurfaceRangeSort);
112 static void CheckSampling(const IntTools_CurveRangeSample& theCurveRange,
113 const IntTools_SurfaceRangeSample& theSurfaceRange,
114 const IntTools_CurveRangeLocalizeData& theCurveData,
115 const IntTools_SurfaceRangeLocalizeData& theSurfaceData,
116 const Standard_Real DiffC,
117 const Standard_Real DiffU,
118 const Standard_Real DiffV,
119 Standard_Boolean& bAllowSamplingC,
120 Standard_Boolean& bAllowSamplingU,
121 Standard_Boolean& bAllowSamplingV);
122 // ==================================================================================
123 // function: IntTools_BeanFaceIntersector
125 // ==================================================================================
126 IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector() :
127 myFirstParameter(0.),
136 myIsDone(Standard_False)
138 myCriteria = Precision::Confusion();
139 myCurveResolution = Precision::PConfusion();
143 // ==================================================================================
144 // function: IntTools_BeanFaceIntersector
146 // ==================================================================================
147 IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const TopoDS_Edge& theEdge,
148 const TopoDS_Face& theFace) :
149 myFirstParameter(0.),
158 myIsDone(Standard_False)
160 Init(theEdge, theFace);
163 // ==================================================================================
164 // function: IntTools_BeanFaceIntersector
166 // ==================================================================================
167 IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const BRepAdaptor_Curve& theCurve,
168 const BRepAdaptor_Surface& theSurface,
169 const Standard_Real theBeanTolerance,
170 const Standard_Real theFaceTolerance) :
171 myFirstParameter(0.),
178 myIsDone(Standard_False)
180 Init(theCurve, theSurface, theBeanTolerance, theFaceTolerance);
183 // ==================================================================================
184 // function: IntTools_BeanFaceIntersector
186 // ==================================================================================
187 IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const BRepAdaptor_Curve& theCurve,
188 const BRepAdaptor_Surface& theSurface,
189 const Standard_Real theFirstParOnCurve,
190 const Standard_Real theLastParOnCurve,
191 const Standard_Real theUMinParameter,
192 const Standard_Real theUMaxParameter,
193 const Standard_Real theVMinParameter,
194 const Standard_Real theVMaxParameter,
195 const Standard_Real theBeanTolerance,
196 const Standard_Real theFaceTolerance) :
197 myFirstParameter(theFirstParOnCurve),
198 myLastParameter(theLastParOnCurve),
199 myUMinParameter(theUMinParameter),
200 myUMaxParameter(theUMaxParameter),
201 myVMinParameter(theVMinParameter),
202 myVMaxParameter(theVMaxParameter),
203 myBeanTolerance(theBeanTolerance),
204 myFaceTolerance(theFaceTolerance),
206 myIsDone(Standard_False)
210 myCriteria = myBeanTolerance + myFaceTolerance;
211 myCurveResolution = myCurve.Resolution(myCriteria);
213 mySurface = theSurface;
214 myTrsfSurface = Handle(Geom_Surface)::DownCast(mySurface.Surface().Surface()->Transformed(mySurface.Trsf()));
217 // ==================================================================================
220 // ==================================================================================
221 void IntTools_BeanFaceIntersector::Init(const TopoDS_Edge& theEdge,
222 const TopoDS_Face& theFace)
224 myCurve.Initialize(theEdge);
225 mySurface.Initialize(theFace);
226 myTrsfSurface = Handle(Geom_Surface)::DownCast(mySurface.Surface().Surface()->Transformed(mySurface.Trsf()));
227 myBeanTolerance = BRep_Tool::Tolerance(theEdge);
228 myFaceTolerance = BRep_Tool::Tolerance(theFace);
230 myCriteria = myBeanTolerance + myFaceTolerance;
231 myCurveResolution = myCurve.Resolution(myCriteria);
233 SetSurfaceParameters(mySurface.FirstUParameter(), mySurface.LastUParameter(),
234 mySurface.FirstVParameter(), mySurface.LastVParameter());
238 // ==================================================================================
241 // ==================================================================================
242 void IntTools_BeanFaceIntersector::Init(const BRepAdaptor_Curve& theCurve,
243 const BRepAdaptor_Surface& theSurface,
244 const Standard_Real theBeanTolerance,
245 const Standard_Real theFaceTolerance)
248 mySurface = theSurface;
249 myTrsfSurface = Handle(Geom_Surface)::DownCast(mySurface.Surface().Surface()->Transformed(mySurface.Trsf()));
250 myBeanTolerance = theBeanTolerance;
251 myFaceTolerance = theFaceTolerance;
253 myCriteria = myBeanTolerance + myFaceTolerance;
254 myCurveResolution = myCurve.Resolution(myCriteria);
256 SetSurfaceParameters(mySurface.FirstUParameter(), mySurface.LastUParameter(),
257 mySurface.FirstVParameter(), mySurface.LastVParameter());
261 // ==================================================================================
264 // ==================================================================================
265 void IntTools_BeanFaceIntersector::Init(const BRepAdaptor_Curve& theCurve,
266 const BRepAdaptor_Surface& theSurface,
267 const Standard_Real theFirstParOnCurve,
268 const Standard_Real theLastParOnCurve,
269 const Standard_Real theUMinParameter,
270 const Standard_Real theUMaxParameter,
271 const Standard_Real theVMinParameter,
272 const Standard_Real theVMaxParameter,
273 const Standard_Real theBeanTolerance,
274 const Standard_Real theFaceTolerance)
276 Init(theCurve, theSurface, theBeanTolerance, theFaceTolerance);
277 SetBeanParameters(theFirstParOnCurve, theLastParOnCurve);
278 SetSurfaceParameters(theUMinParameter, theUMaxParameter, theVMinParameter, theVMaxParameter);
281 // ==================================================================================
282 // function: SetContext
284 // ==================================================================================
285 void IntTools_BeanFaceIntersector::SetContext(const Handle(BOPInt_Context)& theContext)
287 myContext = theContext;
289 // ==================================================================================
292 // ==================================================================================
293 const Handle(BOPInt_Context)& IntTools_BeanFaceIntersector::Context()const
298 // ==================================================================================
299 // function: SetBeanParameters
301 // ==================================================================================
302 void IntTools_BeanFaceIntersector::SetBeanParameters(const Standard_Real theFirstParOnCurve,
303 const Standard_Real theLastParOnCurve)
305 myFirstParameter = theFirstParOnCurve;
306 myLastParameter = theLastParOnCurve;
309 // ==================================================================================
310 // function: SetSurfaceParameters
312 // ==================================================================================
313 void IntTools_BeanFaceIntersector::SetSurfaceParameters(const Standard_Real theUMinParameter,
314 const Standard_Real theUMaxParameter,
315 const Standard_Real theVMinParameter,
316 const Standard_Real theVMaxParameter)
318 myUMinParameter = theUMinParameter;
319 myUMaxParameter = theUMaxParameter;
320 myVMinParameter = theVMinParameter;
321 myVMaxParameter = theVMaxParameter;
324 // ==================================================================================
327 // ==================================================================================
328 void IntTools_BeanFaceIntersector::Perform()
330 myIsDone = Standard_False;
332 Standard_Integer bRet;
333 Standard_Integer aDiscretization = 30;
334 Standard_Real aRelativeDeflection = 0.01;
335 myDeflection = aRelativeDeflection;
337 if (myContext.IsNull()) {
338 myContext=new BOPInt_Context;
341 if(myCurve.GetType()==GeomAbs_Line && mySurface.GetType()==GeomAbs_Plane) {
346 if(myCurve.GetType()==GeomAbs_Line) {
348 myDeflection = Precision::Confusion();
351 if(myCurve.GetType()==GeomAbs_Circle) {
352 aDiscretization = 23;
353 Standard_Real R = myCurve.Circle().Radius();
354 myDeflection = aRelativeDeflection * R;
356 if(myCurve.GetType() == GeomAbs_Ellipse) {
357 aDiscretization = 23;
358 Standard_Real R = myCurve.Ellipse().MajorRadius();
359 myDeflection = 2 * aRelativeDeflection * R;
362 // modified by NIZHNY-MKK Wed Oct 19 12:15:21 2005
363 Standard_Boolean bLocalize = Standard_False;
365 if(((mySurface.GetType() == GeomAbs_BSplineSurface) &&
366 ((mySurface.UDegree() > 2) || (mySurface.VDegree() > 2)) &&
367 //modified by NIZNHY-PKV Wed Feb 25 15:02:00 2009f
368 //((mySurface.NbUKnots() > 2) || (mySurface.NbVKnots() > 2))) ||
369 ((mySurface.NbUKnots() > 2) && (mySurface.NbVKnots() > 2))) ||
370 //modified by NIZNHY-PKV Wed Feb 25 15:02:13 2009t
371 (mySurface.GetType() == GeomAbs_BezierSurface) ||
372 (mySurface.GetType() == GeomAbs_OtherSurface)) {
373 bLocalize = Standard_True;
377 if(Precision::IsInfinite(myUMinParameter) ||
378 Precision::IsInfinite(myUMaxParameter) ||
379 Precision::IsInfinite(myVMinParameter) ||
380 Precision::IsInfinite(myVMaxParameter))
381 bLocalize = Standard_False;
383 Standard_Boolean bSuccessLocalize = Standard_False;
386 myRangeManager.SetBoundaries(myFirstParameter, myLastParameter, 0);
387 Standard_Boolean coinside = TestComputeCoinside();
390 bSuccessLocalize = ComputeLocalized();
393 if(!bLocalize || !bSuccessLocalize) {
394 // modified by NIZHNY-MKK Wed Oct 19 12:15:26 2005.END
396 IntTools_CArray1OfReal aParams;
398 if(IntTools::PrepareArgs(myCurve,
407 myRangeManager.SetRanges(aParams, 0);
409 if(myRangeManager.Length()==0) {
413 bRet=FastComputeExactIntersection();
415 IntTools_Range aRange(myFirstParameter, myLastParameter);
416 myResults.Append(aRange);
417 myIsDone = Standard_True;
420 //modified by NIZHNY-EMV Fri Apr 20 09:38:08 2012
421 else if (bRet == 2) {
422 myIsDone = Standard_True;
425 //modified by NIZHNY-EMV Fri Apr 20 09:38:10 2012
428 // Standard_Boolean coinside = TestCoinside(myCurve,mySurface);
429 Standard_Boolean coinside = TestComputeCoinside();
431 // myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2);
435 ComputeAroundExactIntersection();
437 ComputeUsingExtremum();
439 ComputeNearRangeBoundaries();
443 myIsDone = Standard_True;
445 for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
447 if(myRangeManager.Flag(i) == 2) {
448 IntTools_Range aRange = myRangeManager.Range(i);
450 if(myResults.Length() > 0) {
451 const IntTools_Range& aLastRange = myResults.Last();
453 if(Abs(aRange.First() - aLastRange.Last()) > Precision::PConfusion()) {
454 myResults.Append(aRange);
457 myResults.ChangeValue(myResults.Length()).SetLast(aRange.Last());
461 myResults.Append(aRange);
467 // ==================================================================================
470 // ==================================================================================
471 const IntTools_SequenceOfRanges& IntTools_BeanFaceIntersector::Result() const
476 // ==================================================================================
479 // ==================================================================================
480 void IntTools_BeanFaceIntersector::Result(IntTools_SequenceOfRanges& theResults) const
482 theResults = myResults;
485 // ==================================================================================
486 // function: Distance
488 // ==================================================================================
489 Standard_Real IntTools_BeanFaceIntersector::Distance(const Standard_Real theArg)
491 gp_Pnt aPoint = myCurve.Value(theArg);
493 GeomAPI_ProjectPointOnSurf& aProjector = myContext->ProjPS(mySurface.Face());
494 aProjector.Perform(aPoint);
496 if(aProjector.IsDone() && aProjector.NbPoints() > 0) {
497 return aProjector.LowerDistance();
500 Standard_Real aDistance = RealLast();
502 for(Standard_Integer i=0; i < 4; i++) {
503 Standard_Real anIsoParameter = (i==0) ? myUMinParameter : ((i==1) ? myUMaxParameter : ((i==2) ? myVMinParameter : myVMaxParameter));
504 Standard_Real aMinParameter = (i < 2) ? myVMinParameter : myUMinParameter;
505 Standard_Real aMaxParameter = (i < 2) ? myVMaxParameter : myUMaxParameter;
506 Standard_Real aMidParameter = (aMinParameter + aMaxParameter) * 0.5;
507 gp_Pnt aPointMin = (i < 2) ? mySurface.Value(anIsoParameter, aMinParameter) : mySurface.Value(aMinParameter, anIsoParameter);
508 gp_Pnt aPointMax = (i < 2) ? mySurface.Value(anIsoParameter, aMaxParameter) : mySurface.Value(aMaxParameter, anIsoParameter);
509 gp_Pnt aPointMid = (i < 2) ? mySurface.Value(anIsoParameter, aMidParameter) : mySurface.Value(aMidParameter, anIsoParameter);
511 Standard_Boolean useMinMaxPoints = Standard_True;
512 Standard_Boolean computeisoline = Standard_True;
514 if(aPointMin.IsEqual(aPointMax, myCriteria) &&
515 aPointMin.IsEqual(aPointMid, myCriteria) &&
516 aPointMax.IsEqual(aPointMid, myCriteria)) {
517 computeisoline = Standard_False;
521 Handle(Geom_Curve) aCurve = (i < 2) ? myTrsfSurface->UIso(anIsoParameter) : myTrsfSurface->VIso(anIsoParameter);
522 GeomAPI_ProjectPointOnCurve aProjectorOnCurve(aPoint, aCurve, aMinParameter, aMaxParameter);
524 if(aProjectorOnCurve.NbPoints() > 0) {
525 useMinMaxPoints = Standard_False;
527 if(aDistance > aProjectorOnCurve.LowerDistance())
528 aDistance = aProjectorOnCurve.LowerDistance();
532 if(useMinMaxPoints) {
533 Standard_Real aPPDistance = aPoint.Distance(aPointMin);
534 aDistance = (aPPDistance < aDistance) ? aPPDistance : aDistance;
535 aPPDistance = aPoint.Distance(aPointMax);
536 aDistance = (aPPDistance < aDistance) ? aPPDistance : aDistance;
543 // ==================================================================================
544 // function: Distance
546 // ==================================================================================
547 Standard_Real IntTools_BeanFaceIntersector::Distance(const Standard_Real theArg,
548 Standard_Real& theUParameter,
549 Standard_Real& theVParameter)
551 gp_Pnt aPoint = myCurve.Value(theArg);
553 theUParameter = myUMinParameter;
554 theVParameter = myVMinParameter;
556 Standard_Real aDistance = RealLast();
557 Standard_Boolean projectionfound = Standard_False;
559 GeomAPI_ProjectPointOnSurf& aProjector = myContext->ProjPS(mySurface.Face());
560 aProjector.Perform(aPoint);
562 if(aProjector.IsDone() && aProjector.NbPoints() > 0) {
563 aProjector.LowerDistanceParameters(theUParameter, theVParameter);
564 aDistance = aProjector.LowerDistance();
565 projectionfound = Standard_True;
568 if(!projectionfound) {
570 for(Standard_Integer i = 0; i < 4; i++) {
571 Standard_Real anIsoParameter = (i==0) ? myUMinParameter : ((i==1) ? myUMaxParameter : ((i==2) ? myVMinParameter : myVMaxParameter));
572 Standard_Real aMinParameter = (i < 2) ? myVMinParameter : myUMinParameter;
573 Standard_Real aMaxParameter = (i < 2) ? myVMaxParameter : myUMaxParameter;
574 Standard_Real aMidParameter = (aMinParameter + aMaxParameter) * 0.5;
575 gp_Pnt aPointMin = (i < 2) ? mySurface.Value(anIsoParameter, aMinParameter) : mySurface.Value(aMinParameter, anIsoParameter);
576 gp_Pnt aPointMax = (i < 2) ? mySurface.Value(anIsoParameter, aMaxParameter) : mySurface.Value(aMaxParameter, anIsoParameter);
577 gp_Pnt aPointMid = (i < 2) ? mySurface.Value(anIsoParameter, aMidParameter) : mySurface.Value(aMidParameter, anIsoParameter);
579 Standard_Boolean useMinMaxPoints = Standard_True;
580 Standard_Boolean computeisoline = Standard_True;
582 if(aPointMin.IsEqual(aPointMax, myCriteria) &&
583 aPointMin.IsEqual(aPointMid, myCriteria) &&
584 aPointMax.IsEqual(aPointMid, myCriteria)) {
585 computeisoline = Standard_False;
589 Handle(Geom_Curve) aCurve = (i < 2) ? myTrsfSurface->UIso(anIsoParameter) : myTrsfSurface->VIso(anIsoParameter);
590 GeomAPI_ProjectPointOnCurve aProjectorOnCurve(aPoint, aCurve, aMinParameter, aMaxParameter);
592 if(aProjectorOnCurve.NbPoints() > 0) {
593 useMinMaxPoints = Standard_False;
595 if(aDistance > aProjectorOnCurve.LowerDistance()) {
596 theUParameter = (i<=1) ? anIsoParameter : aProjectorOnCurve.LowerDistanceParameter();
597 theVParameter = (i>=2) ? anIsoParameter : aProjectorOnCurve.LowerDistanceParameter();
598 aDistance = aProjectorOnCurve.LowerDistance();
603 if(useMinMaxPoints) {
604 Standard_Real aPPDistance = aPoint.Distance(aPointMin);
606 if(aPPDistance < aDistance) {
607 theUParameter = (i<=1) ? anIsoParameter : aMinParameter;
608 theVParameter = (i>=2) ? anIsoParameter : aMinParameter;
609 aDistance = aPPDistance;
611 aPPDistance = aPoint.Distance(aPointMax);
613 if(aPPDistance < aDistance) {
614 theUParameter = (i<=1) ? anIsoParameter : aMaxParameter;
615 theVParameter = (i>=2) ? anIsoParameter : aMaxParameter;
616 aDistance = aPPDistance;
621 theUParameter = (myUMinParameter > theUParameter) ? myUMinParameter : theUParameter;
622 theUParameter = (myUMaxParameter < theUParameter) ? myUMaxParameter : theUParameter;
623 theVParameter = (myVMinParameter > theVParameter) ? myVMinParameter : theVParameter;
624 theVParameter = (myVMaxParameter < theVParameter) ? myVMaxParameter : theVParameter;
629 // ==================================================================================
630 // function: ComputeAroundExactIntersection
632 // ==================================================================================
633 void IntTools_BeanFaceIntersector::ComputeAroundExactIntersection()
635 IntCurveSurface_HInter anExactIntersector;
637 Handle(BRepAdaptor_HCurve) aCurve = new BRepAdaptor_HCurve(myCurve);
638 Handle(BRepAdaptor_HSurface) aSurface = new BRepAdaptor_HSurface(mySurface);
640 anExactIntersector.Perform(aCurve, aSurface);
642 if(anExactIntersector.IsDone()) {
643 Standard_Integer i = 0;
645 for(i = 1; i <= anExactIntersector.NbPoints(); i++) {
646 const IntCurveSurface_IntersectionPoint& aPoint = anExactIntersector.Point(i);
648 if((aPoint.W() >= myFirstParameter) && (aPoint.W() <= myLastParameter)) {
649 Standard_Boolean UIsNotValid = ((myUMinParameter > aPoint.U()) || (aPoint.U() > myUMaxParameter));
650 Standard_Boolean VIsNotValid = ((myVMinParameter > aPoint.V()) || (aPoint.V() > myVMaxParameter));
651 Standard_Boolean solutionIsValid = !UIsNotValid && !VIsNotValid;
652 Standard_Real U = aPoint.U();
653 Standard_Real V = aPoint.V();
655 if(UIsNotValid || VIsNotValid) {
656 // modified by NIZHNY-MKK Thu Jun 17 12:50:39 2004
657 Standard_Boolean bUCorrected = Standard_True;
660 // modified by NIZHNY-MKK Thu Jun 17 12:50:37 2004
661 bUCorrected = Standard_False;
662 solutionIsValid = Standard_False;
664 if(mySurface.IsUPeriodic()) {
665 Standard_Real aNewU = U;
667 if(AdjustPeriodic(U, myUMinParameter, myUMaxParameter, mySurface.UPeriod(), aNewU)) {
668 solutionIsValid = Standard_True;
669 // modified by NIZHNY-MKK Thu Jun 17 12:51:01 2004
670 bUCorrected = Standard_True;
675 // modified by NIZHNY-MKK Thu Jun 17 12:51:03 2004
676 // if(solutionIsValid && VIsNotValid) {
677 if(bUCorrected && VIsNotValid) {
678 solutionIsValid = Standard_False;
680 if(mySurface.IsVPeriodic()) {
681 Standard_Real aNewV = V;
683 if(AdjustPeriodic(V, myVMinParameter, myVMaxParameter, mySurface.VPeriod(), aNewV)) {
684 solutionIsValid = Standard_True;
694 Standard_Integer aNbRanges = myRangeManager.Length();
696 ComputeRangeFromStartPoint(Standard_False, aPoint.W(), U, V);
697 ComputeRangeFromStartPoint(Standard_True, aPoint.W(), U, V);
699 if(aNbRanges == myRangeManager.Length()) {
700 SetEmptyResultRange(aPoint.W(), myRangeManager);
701 } // end if(aNbRanges == myRangeManager.Length())
705 for(i = 1; i <= anExactIntersector.NbSegments(); i++) {
706 const IntCurveSurface_IntersectionSegment& aSegment = anExactIntersector.Segment(i);
707 IntCurveSurface_IntersectionPoint aPoint1, aPoint2;
708 aSegment.Values(aPoint1, aPoint2);
710 Standard_Real aFirstParameter = (aPoint1.W() < myFirstParameter) ? myFirstParameter : aPoint1.W();
711 Standard_Real aLastParameter = (myLastParameter < aPoint2.W()) ? myLastParameter : aPoint2.W();
713 myRangeManager.InsertRange(aFirstParameter, aLastParameter, 2);
715 ComputeRangeFromStartPoint(Standard_False, aPoint1.W(), aPoint1.U(), aPoint1.V());
716 ComputeRangeFromStartPoint(Standard_True, aPoint2.W(), aPoint2.U(), aPoint2.V());
721 // ==================================================================================
722 // function: FastComputeExactIntersection
724 // ==================================================================================
725 Standard_Integer IntTools_BeanFaceIntersector::FastComputeExactIntersection()
727 Standard_Integer aresult;
728 GeomAbs_CurveType aCT;
729 GeomAbs_SurfaceType aST;
732 aCT=myCurve.GetType();
733 aST=mySurface.GetType();
735 if((aCT==GeomAbs_BezierCurve) ||
736 (aCT==GeomAbs_BSplineCurve) ||
737 (aCT==GeomAbs_OtherCurve)) {
741 if(aST==GeomAbs_Plane) {
742 gp_Pln surfPlane = mySurface.Plane();
744 if(aCT==GeomAbs_Line) {
745 if((surfPlane.Distance(myCurve.Value(myFirstParameter)) < myCriteria) &&
746 (surfPlane.Distance(myCurve.Value(myLastParameter)) < myCriteria)) {
754 case GeomAbs_Circle: {
755 aDir = myCurve.Circle().Axis().Direction();
758 case GeomAbs_Ellipse: {
759 aDir = myCurve.Ellipse().Axis().Direction();
762 case GeomAbs_Hyperbola: {
763 aDir = myCurve.Hyperbola().Axis().Direction();
766 case GeomAbs_Parabola: {
767 aDir = myCurve.Parabola().Axis().Direction();
775 Standard_Real anAngle = aDir.Angle(surfPlane.Axis().Direction());
777 if(anAngle < Precision::Angular()) {
778 Standard_Boolean insertRange = Standard_False;
781 case GeomAbs_Circle: {
782 Standard_Real adist =
783 surfPlane.Distance(myCurve.Circle().Location()) +
784 myCurve.Circle().Radius() * Precision::Angular();
786 if(adist < myCriteria) {
787 insertRange = Standard_True;
791 case GeomAbs_Ellipse: {
792 Standard_Real adist =
793 surfPlane.Distance(myCurve.Ellipse().Location()) +
794 myCurve.Ellipse().MajorRadius() * Precision::Angular();
796 if(adist < myCriteria) {
797 insertRange = Standard_True;
801 case GeomAbs_Hyperbola:
802 case GeomAbs_Parabola: {
803 Standard_Real aMaxPar =
804 (Abs(myFirstParameter) > Abs(myLastParameter)) ?
805 Abs(myFirstParameter) : Abs(myLastParameter);
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();
813 if(adist < myCriteria) {
814 insertRange = Standard_True;
826 }//if(anAngle < Precision::Angular()) {
828 }// if(aST==GeomAbs_Plane) {
830 if(aCT==GeomAbs_Circle) {
831 gp_Circ aCircle = myCurve.Circle();
833 if(aST==GeomAbs_Cylinder) {
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);
839 if(anAngle < Precision::Angular()) {
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();
847 if(adist < myCriteria) {
848 Standard_Real acylradius = aCylinder.Radius();
849 Standard_Real atmpvalue = aCircle.Radius() * sin(Precision::Angular());
850 Standard_Real aprojectedradius = atmpvalue;
852 sqrt((aCircle.Radius() * aCircle.Radius())
853 - (aprojectedradius * aprojectedradius));
854 adiff = aprojectedradius - acylradius;
855 adist = alocdist + Abs(adiff);
857 if(adist < myCriteria) { // Abs is important function here
862 }// if(aST==GeomAbs_Cylinder)
864 if(aST==GeomAbs_Sphere) {
865 gp_Pln aCirclePln(aCircle.Location(), aCircle.Axis().Direction());
866 IntAna_QuadQuadGeo anInter(aCirclePln, mySurface.Sphere());
868 if(anInter.IsDone()) {
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();
876 if(adist < myCriteria) {
881 }// if(aST==GeomAbs_Sphere) {
882 }// if(aCT==GeomAbs_Circle) {
884 //modified by NIZNHY-PKV Thu Mar 01 11:54:04 2012f
885 if(aST==GeomAbs_Cylinder) {
889 aCyl=mySurface.Cylinder();
891 const gp_Ax1& aAx1C=aCyl.Axis();
892 const gp_Dir& aDirC=aAx1C.Direction();
894 if(aCT==GeomAbs_Line) {
895 Standard_Real aCos, aAng2, aTolang2;
900 const gp_Dir& aDirL=aLin.Direction();
901 const gp_Pnt& aLocL=aLin.Location();
903 aCos=aDirC.Dot(aDirL);
905 aAng2 = 2.*(1. - aCos);
908 aAng2 = 2.*(1. + aCos);
911 if(aAng2<=aTolang2) {// IsParallel = Standard_True;
912 Standard_Boolean bFlag;
918 aPL[0]=myCurve.Value(myFirstParameter);
919 aPL[1]=myCurve.Value(myLastParameter);
921 for (i=0; i<2; ++i) {
922 aD=aLC.Distance(aPL[i]);
924 bFlag=(aD > myCriteria);
934 }//if(aCT==GeomAbs_Line) {
936 //modified by NIZNHY-PKV Thu Mar 01 11:54:06 2012t
938 //modified by NIZHNY-EMV Fri May 17 09:48:49 2013
940 IntTools_Range aRange(myFirstParameter, myLastParameter);
941 const TopoDS_Face& aF = mySurface.Face();
942 const TopoDS_Edge& aE = myCurve.Edge();
944 if (BOPTools_AlgoTools::IsBlockInOnFace(aRange, aF, aE, myContext)) {
945 myRangeManager.InsertRange(aRange, 2);
950 //modified by NIZHNY-EMV Fri May 17 09:48:53 2013
955 // ==================================================================================
956 // function: ComputeLinePlane
958 // ==================================================================================
959 void IntTools_BeanFaceIntersector::ComputeLinePlane()
961 Standard_Real Tolang = 1.e-9;
962 gp_Pln P = mySurface.Plane();
963 gp_Lin L = myCurve.Line();
965 myIsDone = Standard_True;
967 Standard_Real A,B,C,D;
968 Standard_Real Al,Bl,Cl;
969 Standard_Real Dis,Direc;
971 P.Coefficients(A,B,C,D);
972 gp_Pnt Orig(L.Location());
973 L.Direction().Coord(Al,Bl,Cl);
975 Direc=A*Al+B*Bl+C*Cl;
976 Dis = A*Orig.X() + B*Orig.Y() + C*Orig.Z() + D;
978 Standard_Boolean parallel = Standard_False, inplane = Standard_False;
979 if (Abs(Direc) < Tolang) {
980 parallel= Standard_True;
981 if (Abs(Dis) < myCriteria) {
982 inplane=Standard_True;
985 inplane=Standard_False;
989 gp_Pnt p1 = ElCLib::Value(myFirstParameter, L);
990 gp_Pnt p2 = ElCLib::Value(myLastParameter, L);
991 Standard_Real d1 = A*p1.X() + B*p1.Y() + C*p1.Z() + D;
993 Standard_Real d2 = A*p2.X() + B*p2.Y() + C*p2.Z() + D;
995 if(d1 <= myCriteria && d2 <= myCriteria) {
996 inplane=Standard_True;
1001 IntTools_Range aRange(myFirstParameter, myLastParameter);
1002 myResults.Append(aRange);
1010 Standard_Real t = - Dis/Direc;
1011 if(t < myFirstParameter || t > myLastParameter) {
1015 gp_Pnt pint(Orig.X()+t*Al, Orig.Y()+t*Bl, Orig.Z()+t*Cl);
1018 ElSLib::Parameters(P, pint, u, v);
1019 if(myUMinParameter > u || u > myUMaxParameter || myVMinParameter > v || v > myVMaxParameter) {
1023 Standard_Real t1 = Max(myFirstParameter, t-myCriteria);
1024 Standard_Real t2 = Min(myLastParameter, t+myCriteria);
1025 IntTools_Range aRange(t1, t2);
1026 myResults.Append(aRange);
1033 // ==================================================================================
1034 // function: ComputeUsingExtremum
1036 // ==================================================================================
1037 void IntTools_BeanFaceIntersector::ComputeUsingExtremum()
1039 Standard_Real Tol, af, al;
1040 Tol = Precision::PConfusion();
1041 Handle(Geom_Curve) aCurve = BRep_Tool::Curve (myCurve.Edge(), af, al);
1042 GeomAdaptor_Surface aGASurface (myTrsfSurface,
1049 BndLib_AddSurface::Add(mySurface, 0., FBox);
1050 FBox.Enlarge(myFaceTolerance);
1052 for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
1054 if(myRangeManager.Flag(i) > 0)
1057 IntTools_Range aParamRange = myRangeManager.Range(i);
1058 Standard_Real anarg1 = aParamRange.First();
1059 Standard_Real anarg2 = aParamRange.Last();
1061 if(anarg2 - anarg1 < Precision::PConfusion()) {
1063 if(((i > 1) && (myRangeManager.Flag(i-1) == 2)) ||
1064 ((i < myRangeManager.Length()) && (myRangeManager.Flag(i+1) == 2))) {
1065 myRangeManager.SetFlag(i, 1);
1070 // check bounding boxes
1072 EBox.Add(myCurve.Value(anarg1));
1073 EBox.Add(myCurve.Value(anarg2));
1074 EBox.Enlarge(myBeanTolerance + myDeflection);
1076 if(EBox.IsOut(FBox)) {
1077 myRangeManager.SetFlag(i, 1);
1081 GeomAdaptor_Curve aGACurve(aCurve, anarg1, anarg2);
1082 Extrema_ExtCS theExtCS(aGACurve, aGASurface, Tol, Tol);
1083 myExtrema = theExtCS;
1085 if(myExtrema.IsDone() && (myExtrema.NbExt() || myExtrema.IsParallel())) {
1086 Standard_Integer anOldNbRanges = myRangeManager.Length();
1088 if (myExtrema.IsParallel()) {
1090 if(myExtrema.SquareDistance(1) < myCriteria * myCriteria) {
1091 Standard_Real U1, V1, U2, V2;
1092 Standard_Real adistance1 = Distance(anarg1, U1, V1);
1093 Standard_Real adistance2 = Distance(anarg2, U2, V2);
1094 Standard_Boolean validdistance1 = (adistance1 < myCriteria);
1095 Standard_Boolean validdistance2 = (adistance2 < myCriteria);
1097 if (validdistance1 && validdistance2) {
1098 myRangeManager.InsertRange(anarg1, anarg2, 2);
1102 if(validdistance1) {
1103 ComputeRangeFromStartPoint(Standard_True, anarg1, U1, V1);
1106 if(validdistance2) {
1107 ComputeRangeFromStartPoint(Standard_False, anarg2, U2, V2);
1110 Standard_Real a = anarg1;
1111 Standard_Real b = anarg2;
1112 Standard_Real da = adistance1;
1113 Standard_Real db = adistance2;
1114 Standard_Real asolution = a;
1115 Standard_Boolean found = Standard_False;
1117 while(((b - a) > myCurveResolution) && !found) {
1118 asolution = (a+b)*0.5;
1119 Standard_Real adist = Distance(asolution, U1, V1);
1121 if(adist < myCriteria) {
1122 found = Standard_True;
1137 ComputeRangeFromStartPoint(Standard_False, asolution, U1, V1);
1138 ComputeRangeFromStartPoint(Standard_True, asolution, U1, V1);
1141 myRangeManager.SetFlag(i, 1);
1148 myRangeManager.SetFlag(i, 1);
1152 Standard_Boolean solutionfound = Standard_False;
1154 for(Standard_Integer j = 1 ; j <= myExtrema.NbExt(); j++) {
1156 if(myExtrema.SquareDistance(j) < myCriteria * myCriteria) {
1159 myExtrema.Points(j, p1, p2);
1163 Standard_Integer aNbRanges = myRangeManager.Length();
1164 ComputeRangeFromStartPoint(Standard_False, p1.Parameter(), U, V);
1165 ComputeRangeFromStartPoint(Standard_True, p1.Parameter(), U, V);
1166 solutionfound = Standard_True;
1168 if(aNbRanges == myRangeManager.Length()) {
1169 SetEmptyResultRange(p1.Parameter(), myRangeManager);
1174 if(!solutionfound) {
1175 myRangeManager.SetFlag(i, 1);
1178 Standard_Integer adifference = myRangeManager.Length() - anOldNbRanges;
1180 if(adifference > 0) {
1183 } // end if(myExtrema.IsDone() && (myExtrema.NbExt() || myExtrema.IsParallel()))
1187 // ==================================================================================
1188 // function: ComputeNearRangeBoundaries
1190 // ==================================================================================
1191 void IntTools_BeanFaceIntersector::ComputeNearRangeBoundaries()
1193 Standard_Real U = myUMinParameter;
1194 Standard_Real V = myVMinParameter;
1196 for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
1198 if(myRangeManager.Flag(i) > 0)
1201 if((i > 1) && (myRangeManager.Flag(i-1) > 0))
1204 IntTools_Range aParamRange = myRangeManager.Range(i);
1206 if(Distance(aParamRange.First(), U, V) < myCriteria) {
1207 Standard_Integer aNbRanges = myRangeManager.Length();
1210 ComputeRangeFromStartPoint(Standard_False, aParamRange.First(), U, V, i-1);
1212 ComputeRangeFromStartPoint(Standard_True, aParamRange.First(), U, V, i + (myRangeManager.Length() - aNbRanges));
1214 if(aNbRanges == myRangeManager.Length()) {
1215 SetEmptyResultRange(aParamRange.First(), myRangeManager);
1220 if(myRangeManager.Flag(myRangeManager.Length()) == 0) {
1221 IntTools_Range aParamRange = myRangeManager.Range(myRangeManager.Length());
1223 if(Distance(aParamRange.Last(), U, V) < myCriteria) {
1224 Standard_Integer aNbRanges = myRangeManager.Length();
1226 ComputeRangeFromStartPoint(Standard_False, aParamRange.Last(), U, V, myRangeManager.Length());
1228 if(aNbRanges == myRangeManager.Length()) {
1229 SetEmptyResultRange(aParamRange.Last(), myRangeManager);
1235 // ==================================================================================
1236 // function: ComputeRangeFromStartPoint
1237 // purpose: Compute range using start point according to parameter theParameter,
1238 // increasing parameter on curve if ToIncreaseParameter == Standard_True or
1239 // decreasing parameter on curve if ToIncreaseParameter == Standard_False
1240 // ==================================================================================
1241 void IntTools_BeanFaceIntersector::ComputeRangeFromStartPoint(const Standard_Boolean ToIncreaseParameter,
1242 const Standard_Real theParameter,
1243 const Standard_Real theUParameter,
1244 const Standard_Real theVParameter)
1246 Standard_Integer aFoundIndex = myRangeManager.GetIndex(theParameter, ToIncreaseParameter);
1248 if(aFoundIndex == 0) {
1252 ComputeRangeFromStartPoint(ToIncreaseParameter, theParameter, theUParameter, theVParameter, aFoundIndex);
1255 // ==================================================================================
1256 // function: ComputeRangeFromStartPoint
1257 // purpose: Compute range using start point according to parameter theParameter,
1258 // increasing parameter on curve if ToIncreaseParameter == Standard_True or
1259 // decreasing parameter on curve if ToIncreaseParameter == Standard_False.
1260 // theIndex indicate that theParameter belong the range number theIndex.
1261 // ==================================================================================
1262 void IntTools_BeanFaceIntersector::ComputeRangeFromStartPoint(const Standard_Boolean ToIncreaseParameter,
1263 const Standard_Real theParameter,
1264 const Standard_Real theUParameter,
1265 const Standard_Real theVParameter,
1266 const Standard_Integer theIndex)
1268 if(myRangeManager.Flag(theIndex) > 0)
1271 Standard_Integer aValidIndex = theIndex;
1273 Standard_Real aMinDelta = myCurveResolution * 0.5;
1274 Standard_Real aDeltaRestrictor = myLastParameter - myFirstParameter;
1276 if(aMinDelta > aDeltaRestrictor)
1277 aMinDelta = aDeltaRestrictor * 0.5;
1279 Standard_Real tenOfMinDelta = aMinDelta * 10.;
1280 Standard_Real aDelta = myCurveResolution;
1282 Standard_Real aCurPar = (ToIncreaseParameter) ? (theParameter + aDelta) : (theParameter - aDelta);
1283 Standard_Real aPrevPar = theParameter;
1284 IntTools_Range aCurrentRange = myRangeManager.Range(aValidIndex);
1286 Standard_Boolean BoundaryCondition = (ToIncreaseParameter) ? (aCurPar > aCurrentRange.Last()) : (aCurPar < aCurrentRange.First());
1288 if(BoundaryCondition) {
1289 aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First();
1290 BoundaryCondition = Standard_False;
1293 Standard_Integer loopcounter = 0; // neccesary as infinite loop restricter
1294 Standard_Real U = theUParameter;
1295 Standard_Real V = theVParameter;
1296 Standard_Boolean anotherSolutionFound = Standard_False;
1298 Standard_Boolean isboundaryindex = Standard_False;
1299 Standard_Boolean isvalidindex = Standard_True;
1301 while((aDelta >= aMinDelta) && (loopcounter <= 10)) {
1302 Standard_Boolean pointfound = Standard_False;
1305 gp_Pnt aPoint = myCurve.Value(aCurPar);
1306 Extrema_GenLocateExtPS anExtrema(aPoint, mySurface, U, V, 1.e-10, 1.e-10);
1308 if(anExtrema.IsDone()) {
1309 if(anExtrema.SquareDistance() < myCriteria * myCriteria) {
1310 Extrema_POnSurf aPOnSurf = anExtrema.Point();
1311 aPOnSurf.Parameter(U, V);
1312 pointfound = Standard_True;
1316 pointfound = (Distance(aCurPar) < myCriteria);
1321 anotherSolutionFound = Standard_True;
1323 if(BoundaryCondition && (isboundaryindex || !isvalidindex))
1327 aDeltaRestrictor = aDelta;
1330 // if point found decide to increase aDelta using derivative of distance function
1333 aDelta = (pointfound) ? (aDelta * 2.) : (aDelta * 0.5);
1334 aDelta = (aDelta < aDeltaRestrictor) ? aDelta : aDeltaRestrictor;
1336 aCurPar = (ToIncreaseParameter) ? (aPrevPar + aDelta) : (aPrevPar - aDelta);
1339 // prevent infinite loop when (aPrevPar +/- aDelta) == aPrevPar == 0.
1342 if( aCurPar == aPrevPar )
1345 BoundaryCondition = (ToIncreaseParameter) ? (aCurPar > aCurrentRange.Last()) : (aCurPar < aCurrentRange.First());
1347 isboundaryindex = Standard_False;
1348 isvalidindex = Standard_True;
1350 if(BoundaryCondition) {
1351 isboundaryindex = ((!ToIncreaseParameter && (aValidIndex == 1)) ||
1352 (ToIncreaseParameter && (aValidIndex == myRangeManager.Length())));
1354 if(!isboundaryindex) {
1357 Standard_Integer aFlag = (ToIncreaseParameter) ? myRangeManager.Flag(aValidIndex + 1) : myRangeManager.Flag(aValidIndex - 1);
1360 aValidIndex = (ToIncreaseParameter) ? (aValidIndex + 1) : (aValidIndex - 1);
1361 aCurrentRange = myRangeManager.Range(aValidIndex);
1363 if((ToIncreaseParameter && (aCurPar > aCurrentRange.Last())) ||
1364 (!ToIncreaseParameter && (aCurPar < aCurrentRange.First()))) {
1365 aCurPar = (aCurrentRange.First() + aCurrentRange.Last()) * 0.5;
1370 isvalidindex = Standard_False;
1371 aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First();
1376 aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First();
1379 if(aDelta < tenOfMinDelta) {
1385 } // if(BoundaryCondition)
1388 if(anotherSolutionFound) {
1389 if(ToIncreaseParameter)
1390 myRangeManager.InsertRange(theParameter, aPrevPar, 2);
1392 myRangeManager.InsertRange(aPrevPar, theParameter, 2);
1396 // ---------------------------------------------------------------------------------
1397 // static function: AdjustPeriodic
1399 // ---------------------------------------------------------------------------------
1400 static Standard_Boolean AdjustPeriodic(const Standard_Real U,
1401 const Standard_Real UFirst,
1402 const Standard_Real ULast,
1403 const Standard_Real Period,
1404 Standard_Real& UResult) {
1406 Standard_Real u = U;
1407 Standard_Real Eps = Epsilon(Period);
1408 while (Eps < (UFirst-u)) u += Period;
1409 while (Eps > (ULast -u)) u -= Period;
1411 return Standard_False;
1414 return Standard_True;
1417 // ---------------------------------------------------------------------------------
1418 // static function: SetEmptyResultRange
1420 // ---------------------------------------------------------------------------------
1421 static Standard_Boolean SetEmptyResultRange(const Standard_Real theParameter,
1422 IntTools_MarkedRangeSet& theMarkedRange) {
1424 const TColStd_SequenceOfInteger& anIndices = theMarkedRange.GetIndices(theParameter);
1425 Standard_Boolean add = (anIndices.Length() > 0);
1427 for(Standard_Integer k = 1; k <= anIndices.Length(); k++) {
1428 if(theMarkedRange.Flag(anIndices(k)) == 2) {
1429 add = Standard_False;
1435 theMarkedRange.InsertRange(theParameter, theParameter, 2);
1441 // ---------------------------------------------------------------------------------
1442 // static function: TestCoinside
1444 // ---------------------------------------------------------------------------------
1445 // static Standard_Boolean TestClose(const Extrema_ExtPS & theExt,
1446 // const Standard_Real theDist)
1448 // Standard_Boolean close = Standard_False;
1449 // if(!theExt.IsDone() || theExt.NbExt() == 0)
1452 // Standard_Integer ie;
1453 // for(ie = 1; ie <= theExt.NbExt(); ie++) {
1454 // Standard_Real dist = theExt.Value(ie);
1455 // if(dist <= theDist) {
1456 // close = Standard_True;
1464 // Standard_Boolean TestCoinside(const BRepAdaptor_Curve& theCurve,
1465 // const BRepAdaptor_Surface& theSurface)
1467 // Standard_Real cfp = theCurve.FirstParameter(), clp = theCurve.LastParameter();
1468 // Standard_Real cdp = fabs(clp - cfp) / 23.;
1470 // Standard_Integer i = 0;
1471 // Standard_Real tolE = theCurve.Tolerance(), tolF = theSurface.Tolerance();
1472 // Standard_Real tolT = tolE + tolF, tolU = 1.e-9, tolV = 1.e-9;
1475 // theCurve.D0(cfp,aP);
1476 // Extrema_ExtPS eps(aP,theSurface,tolU,tolV);
1478 // if(!TestClose(eps,tolT))
1479 // return Standard_False;
1481 // theCurve.D0(clp,aP);
1484 // if(!TestClose(eps,tolT))
1485 // return Standard_False;
1487 // Standard_Boolean close = Standard_True;
1489 // for(i = 1; i <= 22; i++) {
1490 // theCurve.D0((cfp+((Standard_Real)i)*cdp),aP);
1492 // if(!TestClose(eps,tolT)) {
1493 // close = Standard_False;
1500 // ======================================================================================================================
1501 // function: LocalizeSolutions
1503 // ======================================================================================================================
1504 Standard_Boolean IntTools_BeanFaceIntersector::LocalizeSolutions(const IntTools_CurveRangeSample& theCurveRange,
1505 const Bnd_Box& theBoxCurve,
1506 const IntTools_SurfaceRangeSample& theSurfaceRange,
1507 const Bnd_Box& theBoxSurface,
1508 IntTools_CurveRangeLocalizeData& theCurveData,
1509 IntTools_SurfaceRangeLocalizeData& theSurfaceData,
1510 IntTools_ListOfCurveRangeSample& theListCurveRange,
1511 IntTools_ListOfSurfaceRangeSample& theListSurfaceRange)
1513 Standard_Integer tIt = 0, uIt = 0, vIt = 0;
1516 IntTools_CurveRangeSample aRootRangeC(0);
1517 aRootRangeC.SetDepth(0);
1518 IntTools_SurfaceRangeSample aRootRangeS(0, 0, 0, 0);
1520 Bnd_Box aMainBoxC = theBoxCurve;
1521 Bnd_Box aMainBoxS = theBoxSurface;
1522 Standard_Boolean bMainBoxFoundS = Standard_False;
1523 Standard_Boolean bMainBoxFoundC = Standard_False;
1525 IntTools_ListOfCurveRangeSample aListCurveRangeFound;
1526 IntTools_ListOfSurfaceRangeSample aListSurfaceRangeFound;
1529 IntTools_Range aRangeC = theCurveRange.GetRange(myFirstParameter, myLastParameter, theCurveData.GetNbSample());
1530 Standard_Real localdiffC = (aRangeC.Last() - aRangeC.First()) / theCurveData.GetNbSample();
1532 Standard_Real aCurPar = aRangeC.First();
1533 Standard_Real aPrevPar = aRangeC.First();
1534 Standard_Integer aCurIndexInit = theCurveRange.GetRangeIndexDeeper(theCurveData.GetNbSample());
1537 TColStd_ListOfInteger aListCToAvoid;
1538 Standard_Boolean bGlobalCheckDone = Standard_False;
1543 Standard_Integer aCurIndexU = theSurfaceRange.GetRangeIndexUDeeper(theSurfaceData.GetNbSampleU());
1545 Standard_Integer aCurIndexVInit = theSurfaceRange.GetRangeIndexVDeeper(theSurfaceData.GetNbSampleV());
1546 IntTools_Range aRangeV = theSurfaceRange.GetRangeV(myVMinParameter, myVMaxParameter, theSurfaceData.GetNbSampleV());
1549 IntTools_Range aRangeU = theSurfaceRange.GetRangeU(myUMinParameter, myUMaxParameter, theSurfaceData.GetNbSampleU());
1550 Standard_Real aCurParU = aRangeU.First();
1551 Standard_Real aLocalDiffU = (aRangeU.Last() - aRangeU.First()) / theSurfaceData.GetNbSampleU();
1553 Standard_Real aPrevParU = aCurParU;
1554 Standard_Real aLocalDiffV = (aRangeV.Last() - aRangeV.First()) / theSurfaceData.GetNbSampleV();
1557 // ranges check.begin
1558 Standard_Boolean bAllowSamplingC = Standard_True;
1559 Standard_Boolean bAllowSamplingU = Standard_True;
1560 Standard_Boolean bAllowSamplingV = Standard_True;
1563 CheckSampling(theCurveRange, theSurfaceRange, theCurveData, theSurfaceData,
1564 localdiffC, aLocalDiffU, aLocalDiffV,
1565 bAllowSamplingC, bAllowSamplingU, bAllowSamplingV);
1568 if(!bAllowSamplingC && !bAllowSamplingU && !bAllowSamplingV) {
1569 theListCurveRange.Append(theCurveRange);
1570 theListSurfaceRange.Append(theSurfaceRange);
1571 return Standard_True;
1575 // init template. begin
1576 IntTools_CurveRangeSample aNewRangeCTemplate;
1578 if(!bAllowSamplingC) {
1579 aNewRangeCTemplate = theCurveRange;
1580 aCurIndexInit = theCurveRange.GetRangeIndex();
1581 localdiffC = (aRangeC.Last() - aRangeC.First());
1584 aNewRangeCTemplate.SetDepth(theCurveRange.GetDepth() + 1);
1585 aNewRangeCTemplate.SetRangeIndex(aCurIndexInit);
1588 IntTools_SurfaceRangeSample aNewRangeSTemplate = theSurfaceRange;
1590 if(bAllowSamplingU) {
1591 aNewRangeSTemplate.SetDepthU(theSurfaceRange.GetDepthU() + 1);
1594 aCurIndexU = aNewRangeSTemplate.GetIndexU();
1595 aLocalDiffU = aRangeU.Last() - aRangeU.First();
1598 if(bAllowSamplingV) {
1599 aNewRangeSTemplate.SetDepthV(theSurfaceRange.GetDepthV() + 1);
1602 aCurIndexVInit = theSurfaceRange.GetIndexV();
1603 aLocalDiffV = aRangeV.Last() - aRangeV.First();
1605 // init template. end
1608 Standard_Boolean bHasOut = Standard_False;
1609 const Standard_Integer nbU = (bAllowSamplingU) ? theSurfaceData.GetNbSampleU() : 1;
1610 const Standard_Integer nbV = (bAllowSamplingV) ? theSurfaceData.GetNbSampleV() : 1;
1611 const Standard_Integer nbC = (bAllowSamplingC) ? theCurveData.GetNbSample() : 1;
1613 for(uIt = 1; uIt <= nbU; uIt++, aCurIndexU++, aPrevParU = aCurParU) {
1614 aCurParU += aLocalDiffU;
1617 Standard_Real aCurParV = aRangeV.First();
1618 Standard_Real aPrevParV = aCurParV;
1619 Standard_Integer aCurIndexV = aCurIndexVInit;
1621 Standard_Boolean bHasOutV = Standard_False;
1624 for(vIt = 1; vIt <= nbV; vIt++, aCurIndexV++, aPrevParV = aCurParV) {
1626 aCurParV += aLocalDiffV;
1631 IntTools_SurfaceRangeSample aNewRangeS = aNewRangeSTemplate;
1633 if(bAllowSamplingU) {
1634 aNewRangeS.SetIndexU(aCurIndexU);
1637 if(bAllowSamplingV) {
1638 aNewRangeS.SetIndexV(aCurIndexV);
1641 if(theSurfaceData.IsRangeOut(aNewRangeS)) {
1642 bHasOutV = Standard_True;
1650 if(!theSurfaceData.FindBox(aNewRangeS, aBoxS)) {
1652 if(mySurface.GetType() == GeomAbs_BSplineSurface) {
1653 // if(Standard_False ) {
1654 Handle(Geom_BSplineSurface) aSurfBspl = Handle(Geom_BSplineSurface)::DownCast(myTrsfSurface);
1655 aBoxS = GetSurfaceBox(aSurfBspl, aPrevParU, aCurParU, aPrevParV, aCurParV, myCriteria, theSurfaceData);
1658 BndLib_AddSurface::Add(mySurface, aPrevParU, aCurParU, aPrevParV, aCurParV, myCriteria, aBoxS);
1660 // Bnd_Box aMainBoxC;
1662 if(!bMainBoxFoundC && theCurveData.FindBox(aRootRangeC, aMainBoxC)) {
1663 bMainBoxFoundC = Standard_True;
1666 if(aBoxS.IsOut(aMainBoxC)) {
1667 theSurfaceData.AddOutRange(aNewRangeS);
1668 bHasOutV = Standard_True;
1672 theSurfaceData.AddBox(aNewRangeS, aBoxS);
1675 if(aBoxS.IsOut(theBoxCurve)) {
1676 bHasOutV = Standard_True;
1680 IntTools_ListOfBox aListOfBox;
1681 TColStd_ListOfInteger aListOfIndex;
1683 Standard_Boolean bHasOutC = Standard_False;
1684 Standard_Integer aCurIndex = aCurIndexInit;
1686 // ////////////////////////////
1687 aCurPar = aRangeC.First();
1688 aPrevPar = aRangeC.First();
1689 IntTools_CurveRangeSample aCurRangeC = aNewRangeCTemplate;
1691 for (tIt = 1; tIt <= nbC; tIt++, aCurIndex++, aPrevPar = aCurPar) {
1693 aCurPar += localdiffC;
1695 // ignore already computed. begin
1696 Standard_Boolean bFound = Standard_False;
1697 TColStd_ListIteratorOfListOfInteger anItToAvoid(aListCToAvoid);
1699 for(; anItToAvoid.More(); anItToAvoid.Next()) {
1700 if(tIt == anItToAvoid.Value()) {
1701 bFound = Standard_True;
1707 if(bAllowSamplingC) {
1708 aCurRangeC.SetRangeIndex(aCurIndex);
1710 bFound = theCurveData.IsRangeOut(aCurRangeC);
1714 bHasOutC = Standard_True;
1717 // ignore already computed. end
1722 if(!theCurveData.FindBox(aCurRangeC, aBoxC)) {
1723 BndLib_Add3dCurve::Add(myCurve, aPrevPar, aCurPar, myCriteria, aBoxC);
1725 // Bnd_Box aMainBoxS;
1727 if(!bMainBoxFoundS && theSurfaceData.FindBox(aRootRangeS, aMainBoxS)) {
1728 bMainBoxFoundS = Standard_True;
1730 if(aBoxC.IsOut(aMainBoxS)) {
1731 theCurveData.AddOutRange(aCurRangeC);
1732 bHasOutC = Standard_True;
1736 theCurveData.AddBox(aCurRangeC, aBoxC);
1739 if(!bGlobalCheckDone && aBoxC.IsOut(theBoxSurface)) {
1740 aListCToAvoid.Append(tIt);
1741 bHasOutC = Standard_True;
1745 if(aBoxC.IsOut(aBoxS)) {
1746 bHasOutV = Standard_True;
1747 bHasOutC = Standard_True;
1752 aListOfIndex.Append(tIt);
1753 aListOfBox.Append(aBoxC);
1754 } // end for(tIt...)
1756 bGlobalCheckDone = Standard_True;
1759 bHasOutV = Standard_True;
1765 IntTools_CurveRangeSample aNewRangeC = aNewRangeCTemplate;
1767 aCurIndex = aCurIndexInit;
1768 TColStd_ListIteratorOfListOfInteger anItI(aListOfIndex);
1769 IntTools_ListIteratorOfListOfBox anItBox(aListOfBox);
1770 Standard_Boolean bUseOldC = Standard_False;
1771 Standard_Boolean bUseOldS = Standard_False;
1772 Standard_Boolean bCheckSize = !bHasOutC;
1774 for(; anItI.More() && anItBox.More(); anItI.Next(), anItBox.Next()) {
1775 aCurIndex = aCurIndexInit + anItI.Value() - 1;
1777 bUseOldS = Standard_False;
1779 if(bAllowSamplingC) {
1780 aNewRangeC.SetRangeIndex(aCurIndex);
1786 if((theCurveRange.GetDepth() == 0) ||
1787 (theSurfaceRange.GetDepthU() == 0) ||
1788 (theSurfaceRange.GetDepthV() == 0)) {
1789 bHasOutC = Standard_True;
1790 bHasOutV = Standard_True;
1792 else if((theCurveRange.GetDepth() < 4) &&
1793 (theSurfaceRange.GetDepthU() < 4) &&
1794 (theSurfaceRange.GetDepthV() < 4)) {
1795 Bnd_Box aBoxC = anItBox.Value();
1797 if(!aBoxC.IsWhole() && !aBoxS.IsWhole()) {
1798 Standard_Real aDiagC = aBoxC.SquareExtent();
1799 Standard_Real aDiagS = aBoxS.SquareExtent();
1801 if(aDiagC < aDiagS) {
1802 if((aDiagC * 10.) < aDiagS) {
1803 bUseOldC = Standard_True;
1804 bHasOutC = Standard_True;
1805 bHasOutV = Standard_True;
1810 if((aDiagS * 10.) < aDiagC) {
1811 bUseOldS = Standard_True;
1812 bHasOutC = Standard_True;
1813 bHasOutV = Standard_True;
1822 aListCurveRangeFound.Append(aNewRangeC);
1823 aListSurfaceRangeFound.Append(aNewRangeS);
1827 // if(bUseOldS || bAllowSamplingU || bAllowSamplingV) {
1828 // theSurfaceData.AddBox(aNewRangeS, aBoxS);
1831 if(bUseOldS && aNewRangeC.IsEqual(theCurveRange)) {
1832 return Standard_False;
1835 if(!LocalizeSolutions(aNewRangeC, anItBox.Value(),
1836 ((bUseOldS) ? theSurfaceRange : aNewRangeS),
1837 ((bUseOldS) ? theBoxSurface : aBoxS),
1838 theCurveData, theSurfaceData,
1839 theListCurveRange, theListSurfaceRange))
1840 return Standard_False;
1844 aListOfIndex.Clear();
1848 // theSurfaceData.AddBox(aNewRangeS, aBoxS);
1850 if(bUseOldC && bAllowSamplingC && (bAllowSamplingU || bAllowSamplingV)) {
1851 if(!LocalizeSolutions(theCurveRange, theBoxCurve,
1853 theCurveData, theSurfaceData,
1854 theListCurveRange, theListSurfaceRange))
1855 return Standard_False;
1858 } // end for (vIt...)
1861 bHasOut = Standard_True;
1866 theListCurveRange.Append(theCurveRange);
1867 theListSurfaceRange.Append(theSurfaceRange);
1870 IntTools_ListIteratorOfListOfCurveRangeSample anIt1(aListCurveRangeFound);
1871 IntTools_ListIteratorOfListOfSurfaceRangeSample anIt2(aListSurfaceRangeFound);
1873 for(; anIt1.More() && anIt2.More(); anIt1.Next(), anIt2.Next()) {
1874 theListCurveRange.Append(anIt1.Value());
1875 theListSurfaceRange.Append(anIt2.Value());
1878 return Standard_True;
1882 // ======================================================================================================================
1883 // function: ComputeLocalized
1885 // ======================================================================================================================
1886 Standard_Boolean IntTools_BeanFaceIntersector::ComputeLocalized() {
1887 Standard_Real Tol = Precision::PConfusion();
1889 IntTools_SurfaceRangeSample aSurfaceRange(0, 0, 0, 0);
1890 Standard_Real dMinU = 10. * Precision::PConfusion();
1891 Standard_Real dMinV = dMinU;
1892 IntTools_SurfaceRangeLocalizeData aSurfaceDataInit(3, 3, dMinU, dMinV);
1893 IntTools_SurfaceRangeLocalizeData& aSurfaceData = myContext->SurfaceData(mySurface.Face());
1894 aSurfaceData.RemoveRangeOutAll();
1895 aSurfaceData.ClearGrid();
1898 Standard_Boolean bFBoxFound = aSurfaceData.FindBox(aSurfaceRange, FBox);
1900 if(mySurface.GetType() == GeomAbs_BSplineSurface) {
1901 Handle(Geom_BSplineSurface) aSurfBspl = Handle(Geom_BSplineSurface)::DownCast(myTrsfSurface);
1903 ComputeGridPoints(aSurfBspl, myUMinParameter, myUMaxParameter,
1904 myVMinParameter, myVMaxParameter, myCriteria,
1908 FBox = GetSurfaceBox(aSurfBspl, myUMinParameter, myUMaxParameter,
1909 myVMinParameter, myVMaxParameter, myCriteria,
1911 aSurfaceData.AddBox(aSurfaceRange, FBox);
1914 } else if(!bFBoxFound) {
1916 BndLib_AddSurface::Add(mySurface, myUMinParameter, myUMaxParameter, myVMinParameter, myVMaxParameter, myFaceTolerance, FBox);
1917 aSurfaceData.AddBox(aSurfaceRange, FBox);
1922 BndLib_Add3dCurve::Add(myCurve.Trim(myFirstParameter, myLastParameter, Precision::PConfusion())->Curve(), myBeanTolerance, EBox);
1924 if(EBox.IsOut(FBox)) {
1925 for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
1926 myRangeManager.SetFlag(i, 1);
1928 aSurfaceData.ClearGrid();
1930 return Standard_True;
1933 IntTools_ListOfCurveRangeSample aListCurveRange;
1934 IntTools_ListOfSurfaceRangeSample aListSurfaceRange;
1936 IntTools_CurveRangeSample aCurveRange(0);
1937 aCurveRange.SetDepth(0);
1938 Standard_Integer nbSampleC = 3;
1939 Standard_Integer nbSampleU = aSurfaceData.GetNbSampleU();
1940 Standard_Integer nbSampleV = aSurfaceData.GetNbSampleV();
1941 Standard_Real dMinC = 10. * myCurveResolution;
1942 IntTools_ListOfCurveRangeSample aListOut;
1945 Standard_Boolean bAllowSamplingC = Standard_True;
1946 Standard_Boolean bAllowSamplingU = Standard_True;
1947 Standard_Boolean bAllowSamplingV = Standard_True;
1948 IntTools_CurveRangeLocalizeData aCurveDataTmp(nbSampleC, dMinC);
1949 IntTools_SurfaceRangeLocalizeData aSurfaceDataTmp(nbSampleU, nbSampleV, dMinU, dMinV);
1951 CheckSampling(aCurveRange, aSurfaceRange, aCurveDataTmp, aSurfaceDataTmp,
1952 myLastParameter - myFirstParameter,
1953 myUMaxParameter - myUMinParameter,
1954 myVMaxParameter - myVMinParameter,
1955 bAllowSamplingC, bAllowSamplingU, bAllowSamplingV);
1959 IntTools_CurveRangeLocalizeData aCurveData(nbSampleC, dMinC);
1961 aCurveData.AddBox(aCurveRange, EBox);
1963 if(!LocalizeSolutions(aCurveRange, EBox, aSurfaceRange, FBox,
1964 aCurveData, aSurfaceData,
1965 aListCurveRange, aListSurfaceRange)) {
1966 aSurfaceData.ClearGrid();
1968 return Standard_False;
1971 IntTools_ListOfCurveRangeSample aListCurveRangeSort;
1972 IntTools_ListOfSurfaceRangeSample aListSurfaceRangeSort;
1974 MergeSolutions(aListCurveRange, aListSurfaceRange, aListCurveRangeSort, aListSurfaceRangeSort);
1976 IntTools_ListIteratorOfListOfCurveRangeSample anItC(aListCurveRangeSort);
1977 IntTools_ListIteratorOfListOfSurfaceRangeSample anItS(aListSurfaceRangeSort);
1978 IntTools_SurfaceRangeSample aRangeSPrev;
1980 Extrema_GenExtCS anExtremaGen;
1982 for(; anItC.More() && anItS.More(); anItC.Next(), anItS.Next()) {
1984 IntTools_Range aRangeC(myFirstParameter, myLastParameter);
1987 aRangeC = anItC.Value().GetRange(myFirstParameter, myLastParameter, nbSampleC);
1989 IntTools_Range aRangeU(myUMinParameter, myUMaxParameter);
1992 aRangeU = anItS.Value().GetRangeU(myUMinParameter, myUMaxParameter, nbSampleU);
1994 IntTools_Range aRangeV(myVMinParameter, myVMaxParameter);
1997 aRangeV = anItS.Value().GetRangeV(myVMinParameter, myVMaxParameter, nbSampleV);
1999 Standard_Real anarg1 = aRangeC.First(), anarg2 = aRangeC.Last();
2001 Standard_Boolean bFound = Standard_False;
2003 Standard_Integer nMinIndex = myRangeManager.Length();
2004 Standard_Integer nMaxIndex = -1;
2005 const TColStd_SequenceOfInteger& anInds1 = myRangeManager.GetIndices(anarg1);
2006 Standard_Integer indIt = 1;
2008 for(indIt = 1 ; indIt <= anInds1.Length(); indIt++) {
2009 Standard_Integer nIndex = anInds1.Value(indIt);
2010 nMinIndex = (nMinIndex > nIndex) ? nIndex : nMinIndex;
2011 nMaxIndex = (nMaxIndex < nIndex) ? nIndex : nMaxIndex;
2014 for(indIt = nMinIndex ; indIt <= nMaxIndex; indIt++) {
2015 if(myRangeManager.Flag(indIt) == 2) {
2016 bFound = Standard_True;
2023 nMinIndex = (nMaxIndex >= 0) ? nMaxIndex : nMinIndex;
2024 const TColStd_SequenceOfInteger& anInds2 = myRangeManager.GetIndices(anarg2);
2026 for(indIt = 1 ; indIt <= anInds2.Length(); indIt++) {
2027 Standard_Integer nIndex = anInds2.Value(indIt);
2028 nMinIndex = (nMinIndex > nIndex) ? nIndex : nMinIndex;
2029 nMaxIndex = (nMaxIndex < nIndex) ? nIndex : nMaxIndex;
2032 for(indIt = nMinIndex ; indIt <= nMaxIndex; indIt++) {
2033 if(myRangeManager.Flag(indIt) == 2) {
2034 bFound = Standard_True;
2042 Standard_Real parUF = aRangeU.First(), parUL = aRangeU.Last();
2043 Standard_Real parVF = aRangeV.First(), parVL = aRangeV.Last();
2045 if(aRangeSPrev.IsEqual(anItS.Value())) {
2046 anExtremaGen.Perform(myCurve, 10, anarg1, anarg2, Tol);
2049 anExtremaGen.Initialize(mySurface, 10, 10, parUF, parUL, parVF, parVL, Tol);
2050 anExtremaGen.Perform(myCurve, 10, anarg1, anarg2, Tol);
2053 if(anExtremaGen.IsDone() && (anExtremaGen.NbExt() > 0)) {
2055 for(Standard_Integer j = 1 ; j <= anExtremaGen.NbExt(); j++) {
2057 if(anExtremaGen.SquareDistance(j) < myCriteria * myCriteria) {
2061 p1 = anExtremaGen.PointOnCurve(j);
2062 p2 = anExtremaGen.PointOnSurface(j);
2063 Standard_Real U, V, T;
2067 if (myCurve.IsPeriodic())
2068 T = ElCLib::InPeriod(T, anarg1, anarg1 + myCurve.Period());
2069 if (mySurface.IsUPeriodic())
2070 U = ElCLib::InPeriod(U, parUF, parUF + mySurface.UPeriod());
2071 if (mySurface.IsVPeriodic())
2072 V = ElCLib::InPeriod(V, parVF, parVF + mySurface.VPeriod());
2074 //To avoid occasional going out of boundaries because of numerical
2076 if(U < myUMinParameter) U = myUMinParameter;
2077 if(U > myUMaxParameter) U = myUMaxParameter;
2078 if(V < myVMinParameter) V = myVMinParameter;
2079 if(V > myVMaxParameter) V = myVMaxParameter;
2081 Standard_Integer aNbRanges = myRangeManager.Length();
2082 ComputeRangeFromStartPoint(Standard_False, T, U, V);
2083 ComputeRangeFromStartPoint(Standard_True, T, U, V);
2085 if(aNbRanges == myRangeManager.Length()) {
2086 SetEmptyResultRange(T, myRangeManager);
2092 myRangeManager.InsertRange(anarg1, anarg2, 0);
2095 aRangeSPrev = anItS.Value();
2099 aCurveData.ListRangeOut(aListOut);
2103 if(bAllowSamplingC) {
2104 IntTools_ListIteratorOfListOfCurveRangeSample anItC(aListOut);
2106 for(; anItC.More(); anItC.Next()) {
2107 IntTools_Range aRangeC =anItC.Value().GetRange(myFirstParameter, myLastParameter, nbSampleC);
2108 myRangeManager.InsertRange(aRangeC.First(), aRangeC.Last(), 1);
2111 ComputeNearRangeBoundaries();
2113 aSurfaceData.ClearGrid();
2115 return Standard_True;
2118 // ======================================================================================================================
2119 // function: TestComputeCoinside
2121 // ======================================================================================================================
2122 Standard_Boolean IntTools_BeanFaceIntersector::TestComputeCoinside()
2124 Standard_Real cfp = myFirstParameter, clp = myLastParameter;
2125 const Standard_Integer nbSeg = 23;
2126 Standard_Real cdp = (clp - cfp) / (Standard_Real )nbSeg;
2128 Standard_Integer i = 0;
2132 if(Distance(cfp, U, V) > myCriteria)
2133 return Standard_False;
2136 ComputeRangeFromStartPoint(Standard_True, cfp, U, V);
2139 Standard_Integer aFoundIndex = myRangeManager.GetIndex(clp, Standard_False );
2141 if(aFoundIndex != 0) {
2142 if(myRangeManager.Flag(aFoundIndex) == 2)
2143 return Standard_True;
2146 if(Distance(clp, U, V) > myCriteria)
2147 return Standard_False;
2150 ComputeRangeFromStartPoint(Standard_False, clp, U, V);
2153 for(i = 1; i < nbSeg; i++) {
2154 Standard_Real aPar = (cfp+((Standard_Real)i)*cdp);
2156 if(Distance(aPar, U, V) > myCriteria)
2157 return Standard_False;
2159 Standard_Integer aNbRanges = myRangeManager.Length();
2160 ComputeRangeFromStartPoint(Standard_False, aPar, U, V);
2161 ComputeRangeFromStartPoint(Standard_True, aPar, U, V);
2163 if(aNbRanges == myRangeManager.Length()) {
2164 SetEmptyResultRange(aPar, myRangeManager);
2168 return Standard_True;
2171 // Modified by skv - Wed Nov 2 15:21:11 2005 Optimization Begin
2172 // ---------------------------------------------------------------------------------
2173 // static function: GetSurfaceBox
2175 // ---------------------------------------------------------------------------------
2176 Bnd_Box GetSurfaceBox(const Handle(Geom_BSplineSurface) &theSurf,
2177 const Standard_Real theFirstU,
2178 const Standard_Real theLastU,
2179 const Standard_Real theFirstV,
2180 const Standard_Real theLastV,
2181 const Standard_Real theTolerance,
2182 IntTools_SurfaceRangeLocalizeData &theSurfaceData)
2186 BuildBox(theSurf, theFirstU, theLastU, theFirstV, theLastV,
2187 theSurfaceData, aTotalBox);
2189 aTotalBox.Enlarge(theTolerance);
2194 // ---------------------------------------------------------------------------------
2195 // static function: ComputeGridPoints
2197 // ---------------------------------------------------------------------------------
2198 void ComputeGridPoints
2199 (const Handle(Geom_BSplineSurface) &theSurf,
2200 const Standard_Real theFirstU,
2201 const Standard_Real theLastU,
2202 const Standard_Real theFirstV,
2203 const Standard_Real theLastV,
2204 const Standard_Real theTolerance,
2205 IntTools_SurfaceRangeLocalizeData &theSurfaceData)
2210 Standard_Integer aNbSamples[2] = { theSurf->UDegree(),
2211 theSurf->VDegree() };
2212 Standard_Integer aNbKnots[2] = { theSurf->NbUKnots(),
2213 theSurf->NbVKnots() };
2214 TColStd_Array1OfReal aKnotsU(1, aNbKnots[0]);
2215 TColStd_Array1OfReal aKnotsV(1, aNbKnots[1]);
2217 theSurf->UKnots(aKnotsU);
2218 theSurf->VKnots(aKnotsV);
2220 Standard_Integer iLmI;
2221 Standard_Integer iMin[2] = { -1, -1 };
2222 Standard_Integer iMax[2] = { -1, -1 };
2223 Standard_Integer aNbGridPnts[2];
2224 Standard_Real aFPar[2] = { theFirstU, theFirstV};
2225 Standard_Real aLPar[2] = { theLastU, theLastV};
2226 Standard_Real aFpTol[2] = { aFPar[0] + theTolerance,
2227 aFPar[1] + theTolerance };
2228 Standard_Real aFmTol[2] = { aFPar[0] - theTolerance,
2229 aFPar[1] - theTolerance };
2230 Standard_Real aLpTol[2] = { aLPar[0] + theTolerance,
2231 aLPar[1] + theTolerance };
2232 Standard_Real aLmTol[2] = { aLPar[0] - theTolerance,
2233 aLPar[1] - theTolerance };
2236 // Compute number of U and V grid points.
2237 for (j = 0; j < 2; j++) {
2238 const TColStd_Array1OfReal &aKnots = (j == 0) ? aKnotsU : aKnotsV;
2240 for (i = 1; i <= aNbKnots[j] && (iMin[j] == -1 || iMax[j] == -1); i++) {
2241 if (iMin[j] == -1 && aFpTol[j] < aKnots.Value(i))
2244 iLmI = aNbKnots[j] - i + 1;
2246 if (iMax[j] == -1 && aLmTol[j] > aKnots.Value(iLmI))
2250 // If indices are not found, return.
2251 //if (iMin[j] == -1 || iMax[j] == -1)
2257 iMax[j] = aNbKnots[j];
2262 if (iMax[j] > aNbKnots[j])
2263 iMax[j] = aNbKnots[j];
2265 if (iMax[j] < iMin[j])
2268 if (iMax[j] == iMin[j]) {
2273 if (iMax[j] > aNbKnots[j])
2274 iMax[j] = aNbKnots[j];
2278 aNbGridPnts[j] = (iMax[j] - iMin[j])*aNbSamples[j] + 1;
2280 // Setting the number of grid points.
2282 theSurfaceData.SetRangeUGrid(aNbGridPnts[j]);
2284 theSurfaceData.SetRangeVGrid(aNbGridPnts[j]);
2286 // Setting the first and last parameters.
2287 Standard_Integer iAbs = 1;
2288 Standard_Real aMinPar;
2289 Standard_Real aMaxPar = (j == 0) ? theLastU : theLastV;
2291 for (i = iMin[j]; i < iMax[j]; i++) {
2292 // Get the first parameter.
2295 if (aFmTol[j] > aKnots.Value(iMin[j]))
2298 aMinPar = aKnots.Value(iMin[j]);
2300 aMinPar = aKnots.Value(i);
2303 // Get the last parameter.
2304 if (i == iMax[j] - 1) {
2306 if (aLpTol[j] < aKnots.Value(iMax[j]))
2309 aMaxPar = aKnots.Value(iMax[j]);
2311 aMaxPar = aKnots.Value(i + 1);
2314 // Compute grid parameters.
2315 Standard_Real aDelta = (aMaxPar - aMinPar)/aNbSamples[j];
2317 for (k = 0; k < aNbSamples[j]; k++, aMinPar += aDelta) {
2319 theSurfaceData.SetUParam(iAbs++, aMinPar);
2321 theSurfaceData.SetVParam(iAbs++, aMinPar);
2325 // Add the last parameter
2327 theSurfaceData.SetUParam(iAbs++, aMaxPar);
2329 theSurfaceData.SetVParam(iAbs++, aMaxPar);
2332 // Compute of grid points.
2334 Standard_Real aParU;
2335 Standard_Real aParV;
2337 for (i = 1; i <= aNbGridPnts[0]; i++) {
2338 aParU = theSurfaceData.GetUParam(i);
2340 for (j = 1; j <= aNbGridPnts[1]; j++) {
2341 aParV = theSurfaceData.GetVParam(j);
2343 theSurf->D0(aParU, aParV, aPnt);
2344 theSurfaceData.SetGridPoint(i, j, aPnt);
2348 // Compute deflection.
2349 Standard_Real aDef = 0.;
2350 // Standard_Real aDefLin;
2351 // Standard_Real aParMid;
2352 // Standard_Real aParConst;
2353 // Standard_Real aDistPP;
2358 // // Compute DU deflection.
2359 // for (i = 1; i < aNbGridPnts[0]; i++) {
2360 // aParMid = 0.5*(theSurfaceData.GetUParam(i + 1) +
2361 // theSurfaceData.GetUParam(i));
2363 // for (j = 1; j <= aNbGridPnts[1]; j++) {
2364 // const gp_Pnt &thePnt1 = theSurfaceData.GetGridPoint(i, j);
2365 // const gp_Pnt &thePnt2 = theSurfaceData.GetGridPoint(i + 1, j);
2367 // aVec.SetXYZ(thePnt2.XYZ().Subtracted(thePnt1.XYZ()));
2368 // aDistPP = aVec.Magnitude();
2370 // if (aDistPP > theTolerance) {
2371 // // Computation of a distance of a middle point from the line P1 - P2.
2372 // aParConst = theSurfaceData.GetVParam(j);
2373 // theSurf->D0(aParMid, aParConst, aPntMid);
2374 // aCoord = aPntMid.XYZ();
2375 // aCoord.Subtract(thePnt1.XYZ());
2376 // aCoord.Cross (aVec.XYZ());
2377 // aCoord.Divide(aDistPP);
2378 // aDefLin = aCoord.Modulus();
2380 // if (aDefLin > aDef)
2386 // // Compute DV deflection.
2387 // for (j = 1; j < aNbGridPnts[1]; j++) {
2388 // aParMid = 0.5*(theSurfaceData.GetVParam(j + 1) +
2389 // theSurfaceData.GetVParam(j));
2391 // for (i = 1; i <= aNbGridPnts[0]; i++) {
2392 // const gp_Pnt &thePnt1 = theSurfaceData.GetGridPoint(i, j);
2393 // const gp_Pnt &thePnt2 = theSurfaceData.GetGridPoint(i, j + 1);
2395 // aVec.SetXYZ(thePnt2.XYZ().Subtracted(thePnt1.XYZ()));
2396 // aDistPP = aVec.Magnitude();
2398 // if (aDistPP > theTolerance) {
2399 // // Computation of a distance of a middle point from the line P1 - P2.
2400 // aParConst = theSurfaceData.GetUParam(i);
2401 // theSurf->D0(aParConst, aParMid, aPntMid);
2402 // aCoord = aPntMid.XYZ();
2403 // aCoord.Subtract(thePnt1.XYZ());
2404 // aCoord.Cross (aVec.XYZ());
2405 // aCoord.Divide(aDistPP);
2406 // aDefLin = aCoord.Modulus();
2408 // if (aDefLin > aDef)
2414 if (theTolerance > aDef)
2415 aDef = theTolerance;
2418 theSurfaceData.SetGridDeflection(aDef);
2421 // ---------------------------------------------------------------------------------
2422 // static function: BuildBox
2423 // purpose: Compute bounding box.
2424 // ---------------------------------------------------------------------------------
2425 void BuildBox(const Handle(Geom_BSplineSurface) &theSurf,
2426 const Standard_Real theFirstU,
2427 const Standard_Real theLastU,
2428 const Standard_Real theFirstV,
2429 const Standard_Real theLastV,
2430 IntTools_SurfaceRangeLocalizeData &theSurfaceData,
2435 Standard_Integer aNbUPnts;
2436 Standard_Integer aNbVPnts;
2437 Standard_Real aParam;
2440 theSurfaceData.SetFrame(theFirstU, theLastU, theFirstV, theLastV);
2441 aNbUPnts = theSurfaceData.GetNBUPointsInFrame();
2442 aNbVPnts = theSurfaceData.GetNBVPointsInFrame();
2444 // Add corner points.
2445 theSurf->D0(theFirstU, theFirstV, aPnt);
2447 theSurf->D0(theLastU, theFirstV, aPnt);
2449 theSurf->D0(theFirstU, theLastV, aPnt);
2451 theSurf->D0(theLastU, theLastV, aPnt);
2454 for (i = 1; i <= aNbUPnts; i++) {
2455 // Add top and bottom points.
2456 aParam = theSurfaceData.GetUParamInFrame(i);
2457 theSurf->D0(aParam, theFirstV, aPnt);
2459 theSurf->D0(aParam, theLastV, aPnt);
2462 // Add internal points.
2463 for (j = 1; j <= aNbVPnts; j++) {
2464 const gp_Pnt &aGridPnt = theSurfaceData.GetPointInFrame(i, j);
2466 theBox.Add(aGridPnt);
2470 // Add left and right points.
2471 for (j = 1; j <= aNbVPnts; j++) {
2472 aParam = theSurfaceData.GetVParamInFrame(j);
2473 theSurf->D0(theFirstU, aParam, aPnt);
2475 theSurf->D0(theLastU, aParam, aPnt);
2479 theBox.Enlarge(theSurfaceData.GetGridDeflection());
2481 // Modified by skv - Wed Nov 2 15:21:11 2005 Optimization End
2484 // ---------------------------------------------------------------------------------
2485 // static function: MergeSolutions
2487 // ---------------------------------------------------------------------------------
2488 static void MergeSolutions(const IntTools_ListOfCurveRangeSample& theListCurveRange,
2489 const IntTools_ListOfSurfaceRangeSample& theListSurfaceRange,
2490 IntTools_ListOfCurveRangeSample& theListCurveRangeSort,
2491 IntTools_ListOfSurfaceRangeSample& theListSurfaceRangeSort) {
2493 IntTools_ListIteratorOfListOfCurveRangeSample anItC2;
2494 IntTools_ListIteratorOfListOfSurfaceRangeSample anItS1(theListSurfaceRange), anItS2;
2495 IntTools_MapOfSurfaceSample aMapToAvoid;
2497 for(; anItS1.More(); anItS1.Next()) {
2498 const IntTools_SurfaceRangeSample& aRangeS = anItS1.Value();
2500 if(aMapToAvoid.Contains(aRangeS))
2502 aMapToAvoid.Add(aRangeS);
2504 anItC2.Initialize(theListCurveRange);
2505 anItS2.Initialize(theListSurfaceRange);
2507 for(; anItS2.More() && anItC2.More(); anItS2.Next(), anItC2.Next()) {
2508 if(aRangeS.IsEqual(anItS2.Value())) {
2509 theListCurveRangeSort.Append(anItC2.Value());
2510 theListSurfaceRangeSort.Append(anItS2.Value());
2516 // ---------------------------------------------------------------------------------
2517 // static function: CheckSampling
2519 // ---------------------------------------------------------------------------------
2520 static void CheckSampling(const IntTools_CurveRangeSample& theCurveRange,
2521 const IntTools_SurfaceRangeSample& theSurfaceRange,
2522 const IntTools_CurveRangeLocalizeData& theCurveData,
2523 const IntTools_SurfaceRangeLocalizeData& theSurfaceData,
2524 const Standard_Real DiffC,
2525 const Standard_Real DiffU,
2526 const Standard_Real DiffV,
2527 Standard_Boolean& bAllowSamplingC,
2528 Standard_Boolean& bAllowSamplingU,
2529 Standard_Boolean& bAllowSamplingV) {
2531 const Standard_Real dLimit = 1000;
2532 bAllowSamplingC = Standard_True;
2533 bAllowSamplingU = Standard_True;
2534 bAllowSamplingV = Standard_True;
2537 if((pow((Standard_Real)theCurveData.GetNbSample(), (Standard_Real )(theCurveRange.GetDepth() + 1)) > dLimit) ||
2538 ((DiffC / theCurveData.GetNbSample()) < theCurveData.GetMinRange())) {
2539 bAllowSamplingC = Standard_False;
2542 if((pow((Standard_Real )theSurfaceData.GetNbSampleU(), (Standard_Real )(theSurfaceRange.GetDepthU() + 1)) > dLimit) ||
2543 ((DiffU / theSurfaceData.GetNbSampleU()) < theSurfaceData.GetMinRangeU())) {
2544 bAllowSamplingU = Standard_False;
2548 if((pow((Standard_Real )theSurfaceData.GetNbSampleV(), (Standard_Real )(theSurfaceRange.GetDepthV() + 1)) > dLimit) ||
2549 ((DiffV / theSurfaceData.GetNbSampleV()) < theSurfaceData.GetMinRangeV())) {
2550 bAllowSamplingV = Standard_False;