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.
14 #include <IntTools_BeanFaceIntersector.ixx>
16 #include <IntTools_Root.hxx>
17 #include <Precision.hxx>
18 #include <Extrema_POnCurv.hxx>
19 #include <Extrema_POnSurf.hxx>
20 #include <BRep_Tool.hxx>
21 #include <Geom_Surface.hxx>
22 #include <TColStd_Array1OfReal.hxx>
23 #include <TColStd_Array1OfBoolean.hxx>
24 #include <TColStd_ListOfInteger.hxx>
25 #include <TColStd_ListIteratorOfListOfInteger.hxx>
26 #include <IntTools_EdgeFace.hxx>
27 #include <IntTools_ListOfCurveRangeSample.hxx>
28 #include <IntTools_ListOfSurfaceRangeSample.hxx>
29 #include <IntTools_ListOfBox.hxx>
30 #include <IntTools_ListIteratorOfListOfBox.hxx>
31 #include <IntTools_ListIteratorOfListOfCurveRangeSample.hxx>
32 #include <IntTools_ListIteratorOfListOfSurfaceRangeSample.hxx>
33 #include <IntTools_MapIteratorOfMapOfCurveSample.hxx>
34 #include <TColgp_Array1OfPnt2d.hxx>
36 #include <Geom_Curve.hxx>
37 #include <Geom_Surface.hxx>
38 #include <Geom_BSplineSurface.hxx>
39 #include <GeomAdaptor_Curve.hxx>
40 #include <GeomAdaptor_Surface.hxx>
41 #include <Extrema_ExtCS.hxx>
42 #include <Extrema_ExtPS.hxx>
43 #include <IntTools.hxx>
44 #include <IntTools_Context.hxx>
45 #include <IntTools_Tools.hxx>
46 #include <GeomAPI_ProjectPointOnCurve.hxx>
47 #include <IntCurveSurface_HInter.hxx>
48 #include <IntCurveSurface_IntersectionPoint.hxx>
49 #include <IntCurveSurface_IntersectionSegment.hxx>
50 #include <IntAna_QuadQuadGeo.hxx>
51 #include <BRepAdaptor_HCurve.hxx>
52 #include <BRepAdaptor_HSurface.hxx>
53 #include <Extrema_GenLocateExtPS.hxx>
54 #include <Extrema_GenExtCS.hxx>
55 #include <Bnd_Box.hxx>
56 #include <BndLib_AddSurface.hxx>
57 #include <BndLib_Add3dCurve.hxx>
60 #include <GeomInt.hxx>
62 static Standard_Boolean SetEmptyResultRange(const Standard_Real theParameter,
63 IntTools_MarkedRangeSet& theMarkedRange);
67 static Bnd_Box GetSurfaceBox
68 (const Handle(Geom_BSplineSurface) &theSurf,
69 const Standard_Real theFirstU,
70 const Standard_Real theLastU,
71 const Standard_Real theFirstV,
72 const Standard_Real theLastV,
73 const Standard_Real theTolerance,
74 IntTools_SurfaceRangeLocalizeData &theSurfaceData);
76 static void ComputeGridPoints
77 (const Handle(Geom_BSplineSurface) &theSurf,
78 const Standard_Real theFirstU,
79 const Standard_Real theLastU,
80 const Standard_Real theFirstV,
81 const Standard_Real theLastV,
82 const Standard_Real theTolerance,
83 IntTools_SurfaceRangeLocalizeData &theSurfaceData);
85 static void BuildBox(const Handle(Geom_BSplineSurface) &theSurf,
86 const Standard_Real theFirstU,
87 const Standard_Real theLastU,
88 const Standard_Real theFirstV,
89 const Standard_Real theLastV,
90 IntTools_SurfaceRangeLocalizeData &theSurfaceData,
93 static void MergeSolutions(const IntTools_ListOfCurveRangeSample& theListCurveRange,
94 const IntTools_ListOfSurfaceRangeSample& theListSurfaceRange,
95 IntTools_ListOfCurveRangeSample& theListCurveRangeSort,
96 IntTools_ListOfSurfaceRangeSample& theListSurfaceRangeSort);
98 static void CheckSampling(const IntTools_CurveRangeSample& theCurveRange,
99 const IntTools_SurfaceRangeSample& theSurfaceRange,
100 const IntTools_CurveRangeLocalizeData& theCurveData,
101 const IntTools_SurfaceRangeLocalizeData& theSurfaceData,
102 const Standard_Real DiffC,
103 const Standard_Real DiffU,
104 const Standard_Real DiffV,
105 Standard_Boolean& bAllowSamplingC,
106 Standard_Boolean& bAllowSamplingU,
107 Standard_Boolean& bAllowSamplingV);
109 // ==================================================================================
110 // function: IntTools_BeanFaceIntersector
112 // ==================================================================================
113 IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector() :
114 myFirstParameter(0.),
123 myIsDone(Standard_False)
125 myCriteria = Precision::Confusion();
126 myCurveResolution = Precision::PConfusion();
130 // ==================================================================================
131 // function: IntTools_BeanFaceIntersector
133 // ==================================================================================
134 IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const TopoDS_Edge& theEdge,
135 const TopoDS_Face& theFace) :
136 myFirstParameter(0.),
145 myIsDone(Standard_False)
147 Init(theEdge, theFace);
150 // ==================================================================================
151 // function: IntTools_BeanFaceIntersector
153 // ==================================================================================
154 IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const BRepAdaptor_Curve& theCurve,
155 const BRepAdaptor_Surface& theSurface,
156 const Standard_Real theBeanTolerance,
157 const Standard_Real theFaceTolerance) :
158 myFirstParameter(0.),
165 myIsDone(Standard_False)
167 Init(theCurve, theSurface, theBeanTolerance, theFaceTolerance);
170 // ==================================================================================
171 // function: IntTools_BeanFaceIntersector
173 // ==================================================================================
174 IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const BRepAdaptor_Curve& theCurve,
175 const BRepAdaptor_Surface& theSurface,
176 const Standard_Real theFirstParOnCurve,
177 const Standard_Real theLastParOnCurve,
178 const Standard_Real theUMinParameter,
179 const Standard_Real theUMaxParameter,
180 const Standard_Real theVMinParameter,
181 const Standard_Real theVMaxParameter,
182 const Standard_Real theBeanTolerance,
183 const Standard_Real theFaceTolerance) :
184 myFirstParameter(theFirstParOnCurve),
185 myLastParameter(theLastParOnCurve),
186 myUMinParameter(theUMinParameter),
187 myUMaxParameter(theUMaxParameter),
188 myVMinParameter(theVMinParameter),
189 myVMaxParameter(theVMaxParameter),
190 myBeanTolerance(theBeanTolerance),
191 myFaceTolerance(theFaceTolerance),
193 myIsDone(Standard_False)
197 myCriteria = myBeanTolerance + myFaceTolerance;
198 myCurveResolution = myCurve.Resolution(myCriteria);
200 mySurface = theSurface;
201 myTrsfSurface = Handle(Geom_Surface)::DownCast(mySurface.Surface().Surface()->Transformed(mySurface.Trsf()));
204 // ==================================================================================
207 // ==================================================================================
208 void IntTools_BeanFaceIntersector::Init(const TopoDS_Edge& theEdge,
209 const TopoDS_Face& theFace)
211 myCurve.Initialize(theEdge);
212 mySurface.Initialize(theFace);
213 myTrsfSurface = Handle(Geom_Surface)::DownCast(mySurface.Surface().Surface()->Transformed(mySurface.Trsf()));
214 myBeanTolerance = BRep_Tool::Tolerance(theEdge);
215 myFaceTolerance = BRep_Tool::Tolerance(theFace);
217 myCriteria = myBeanTolerance + myFaceTolerance;
218 myCurveResolution = myCurve.Resolution(myCriteria);
220 SetSurfaceParameters(mySurface.FirstUParameter(), mySurface.LastUParameter(),
221 mySurface.FirstVParameter(), mySurface.LastVParameter());
225 // ==================================================================================
228 // ==================================================================================
229 void IntTools_BeanFaceIntersector::Init(const BRepAdaptor_Curve& theCurve,
230 const BRepAdaptor_Surface& theSurface,
231 const Standard_Real theBeanTolerance,
232 const Standard_Real theFaceTolerance)
235 mySurface = theSurface;
236 myTrsfSurface = Handle(Geom_Surface)::DownCast(mySurface.Surface().Surface()->Transformed(mySurface.Trsf()));
237 myBeanTolerance = theBeanTolerance;
238 myFaceTolerance = theFaceTolerance;
240 myCriteria = myBeanTolerance + myFaceTolerance;
241 myCurveResolution = myCurve.Resolution(myCriteria);
243 SetSurfaceParameters(mySurface.FirstUParameter(), mySurface.LastUParameter(),
244 mySurface.FirstVParameter(), mySurface.LastVParameter());
248 // ==================================================================================
251 // ==================================================================================
252 void IntTools_BeanFaceIntersector::Init(const BRepAdaptor_Curve& theCurve,
253 const BRepAdaptor_Surface& theSurface,
254 const Standard_Real theFirstParOnCurve,
255 const Standard_Real theLastParOnCurve,
256 const Standard_Real theUMinParameter,
257 const Standard_Real theUMaxParameter,
258 const Standard_Real theVMinParameter,
259 const Standard_Real theVMaxParameter,
260 const Standard_Real theBeanTolerance,
261 const Standard_Real theFaceTolerance)
263 Init(theCurve, theSurface, theBeanTolerance, theFaceTolerance);
264 SetBeanParameters(theFirstParOnCurve, theLastParOnCurve);
265 SetSurfaceParameters(theUMinParameter, theUMaxParameter, theVMinParameter, theVMaxParameter);
268 // ==================================================================================
269 // function: SetContext
271 // ==================================================================================
272 void IntTools_BeanFaceIntersector::SetContext(const Handle(IntTools_Context)& theContext)
274 myContext = theContext;
276 // ==================================================================================
279 // ==================================================================================
280 const Handle(IntTools_Context)& IntTools_BeanFaceIntersector::Context()const
285 // ==================================================================================
286 // function: SetBeanParameters
288 // ==================================================================================
289 void IntTools_BeanFaceIntersector::SetBeanParameters(const Standard_Real theFirstParOnCurve,
290 const Standard_Real theLastParOnCurve)
292 myFirstParameter = theFirstParOnCurve;
293 myLastParameter = theLastParOnCurve;
296 // ==================================================================================
297 // function: SetSurfaceParameters
299 // ==================================================================================
300 void IntTools_BeanFaceIntersector::SetSurfaceParameters(const Standard_Real theUMinParameter,
301 const Standard_Real theUMaxParameter,
302 const Standard_Real theVMinParameter,
303 const Standard_Real theVMaxParameter)
305 myUMinParameter = theUMinParameter;
306 myUMaxParameter = theUMaxParameter;
307 myVMinParameter = theVMinParameter;
308 myVMaxParameter = theVMaxParameter;
311 // ==================================================================================
314 // ==================================================================================
315 void IntTools_BeanFaceIntersector::Perform()
317 myIsDone = Standard_False;
319 Standard_Integer bRet;
320 Standard_Integer aDiscretization = 30;
321 Standard_Real aRelativeDeflection = 0.01;
322 myDeflection = aRelativeDeflection;
324 if (myContext.IsNull()) {
325 myContext=new IntTools_Context;
328 if(myCurve.GetType()==GeomAbs_Line && mySurface.GetType()==GeomAbs_Plane) {
333 if(myCurve.GetType()==GeomAbs_Line) {
335 myDeflection = Precision::Confusion();
338 if(myCurve.GetType()==GeomAbs_Circle) {
339 aDiscretization = 23;
340 Standard_Real R = myCurve.Circle().Radius();
341 myDeflection = aRelativeDeflection * R;
343 if(myCurve.GetType() == GeomAbs_Ellipse) {
344 aDiscretization = 23;
345 Standard_Real R = myCurve.Ellipse().MajorRadius();
346 myDeflection = 2 * aRelativeDeflection * R;
349 // modified by NIZHNY-MKK Wed Oct 19 12:15:21 2005
350 Standard_Boolean bLocalize = Standard_False;
352 if(((mySurface.GetType() == GeomAbs_BSplineSurface) &&
353 ((mySurface.UDegree() > 2) || (mySurface.VDegree() > 2)) &&
354 //modified by NIZNHY-PKV Wed Feb 25 15:02:00 2009f
355 //((mySurface.NbUKnots() > 2) || (mySurface.NbVKnots() > 2))) ||
356 ((mySurface.NbUKnots() > 2) && (mySurface.NbVKnots() > 2))) ||
357 //modified by NIZNHY-PKV Wed Feb 25 15:02:13 2009t
358 (mySurface.GetType() == GeomAbs_BezierSurface) ||
359 (mySurface.GetType() == GeomAbs_OtherSurface)) {
360 bLocalize = Standard_True;
364 if(Precision::IsInfinite(myUMinParameter) ||
365 Precision::IsInfinite(myUMaxParameter) ||
366 Precision::IsInfinite(myVMinParameter) ||
367 Precision::IsInfinite(myVMaxParameter))
368 bLocalize = Standard_False;
370 Standard_Boolean bSuccessLocalize = Standard_False;
373 myRangeManager.SetBoundaries(myFirstParameter, myLastParameter, 0);
374 Standard_Boolean coinside = TestComputeCoinside();
377 bSuccessLocalize = ComputeLocalized();
380 if(!bLocalize || !bSuccessLocalize) {
381 // modified by NIZHNY-MKK Wed Oct 19 12:15:26 2005.END
383 IntTools_CArray1OfReal aParams;
385 if(IntTools::PrepareArgs(myCurve,
394 myRangeManager.SetRanges(aParams, 0);
396 if(myRangeManager.Length()==0) {
400 bRet=FastComputeExactIntersection();
402 IntTools_Range aRange(myFirstParameter, myLastParameter);
403 myResults.Append(aRange);
404 myIsDone = Standard_True;
407 //modified by NIZHNY-EMV Fri Apr 20 09:38:08 2012
408 else if (bRet == 2) {
409 myIsDone = Standard_True;
412 //modified by NIZHNY-EMV Fri Apr 20 09:38:10 2012
415 // Standard_Boolean coinside = TestCoinside(myCurve,mySurface);
416 Standard_Boolean coinside = TestComputeCoinside();
418 // myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2);
422 ComputeAroundExactIntersection();
424 ComputeUsingExtremum();
426 ComputeNearRangeBoundaries();
430 myIsDone = Standard_True;
432 for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
434 if(myRangeManager.Flag(i) == 2) {
435 IntTools_Range aRange = myRangeManager.Range(i);
437 if(myResults.Length() > 0) {
438 const IntTools_Range& aLastRange = myResults.Last();
440 if(Abs(aRange.First() - aLastRange.Last()) > Precision::PConfusion()) {
441 myResults.Append(aRange);
444 myResults.ChangeValue(myResults.Length()).SetLast(aRange.Last());
448 myResults.Append(aRange);
454 // ==================================================================================
457 // ==================================================================================
458 const IntTools_SequenceOfRanges& IntTools_BeanFaceIntersector::Result() const
463 // ==================================================================================
466 // ==================================================================================
467 void IntTools_BeanFaceIntersector::Result(IntTools_SequenceOfRanges& theResults) const
469 theResults = myResults;
472 // ==================================================================================
473 // function: Distance
475 // ==================================================================================
476 Standard_Real IntTools_BeanFaceIntersector::Distance(const Standard_Real theArg)
478 gp_Pnt aPoint = myCurve.Value(theArg);
480 GeomAPI_ProjectPointOnSurf& aProjector = myContext->ProjPS(mySurface.Face());
481 aProjector.Perform(aPoint);
483 if(aProjector.IsDone() && aProjector.NbPoints() > 0) {
484 return aProjector.LowerDistance();
487 Standard_Real aDistance = RealLast();
489 for(Standard_Integer i=0; i < 4; i++) {
490 Standard_Real anIsoParameter = (i==0) ? myUMinParameter : ((i==1) ? myUMaxParameter : ((i==2) ? myVMinParameter : myVMaxParameter));
491 Standard_Real aMinParameter = (i < 2) ? myVMinParameter : myUMinParameter;
492 Standard_Real aMaxParameter = (i < 2) ? myVMaxParameter : myUMaxParameter;
493 Standard_Real aMidParameter = (aMinParameter + aMaxParameter) * 0.5;
494 gp_Pnt aPointMin = (i < 2) ? mySurface.Value(anIsoParameter, aMinParameter) : mySurface.Value(aMinParameter, anIsoParameter);
495 gp_Pnt aPointMax = (i < 2) ? mySurface.Value(anIsoParameter, aMaxParameter) : mySurface.Value(aMaxParameter, anIsoParameter);
496 gp_Pnt aPointMid = (i < 2) ? mySurface.Value(anIsoParameter, aMidParameter) : mySurface.Value(aMidParameter, anIsoParameter);
498 Standard_Boolean useMinMaxPoints = Standard_True;
499 Standard_Boolean computeisoline = Standard_True;
501 if(aPointMin.IsEqual(aPointMax, myCriteria) &&
502 aPointMin.IsEqual(aPointMid, myCriteria) &&
503 aPointMax.IsEqual(aPointMid, myCriteria)) {
504 computeisoline = Standard_False;
508 Handle(Geom_Curve) aCurve = (i < 2) ? myTrsfSurface->UIso(anIsoParameter) : myTrsfSurface->VIso(anIsoParameter);
509 GeomAPI_ProjectPointOnCurve aProjectorOnCurve(aPoint, aCurve, aMinParameter, aMaxParameter);
511 if(aProjectorOnCurve.NbPoints() > 0) {
512 useMinMaxPoints = Standard_False;
514 if(aDistance > aProjectorOnCurve.LowerDistance())
515 aDistance = aProjectorOnCurve.LowerDistance();
519 if(useMinMaxPoints) {
520 Standard_Real aPPDistance = aPoint.Distance(aPointMin);
521 aDistance = (aPPDistance < aDistance) ? aPPDistance : aDistance;
522 aPPDistance = aPoint.Distance(aPointMax);
523 aDistance = (aPPDistance < aDistance) ? aPPDistance : aDistance;
530 // ==================================================================================
531 // function: Distance
533 // ==================================================================================
534 Standard_Real IntTools_BeanFaceIntersector::Distance(const Standard_Real theArg,
535 Standard_Real& theUParameter,
536 Standard_Real& theVParameter)
538 gp_Pnt aPoint = myCurve.Value(theArg);
540 theUParameter = myUMinParameter;
541 theVParameter = myVMinParameter;
543 Standard_Real aDistance = RealLast();
544 Standard_Boolean projectionfound = Standard_False;
546 GeomAPI_ProjectPointOnSurf& aProjector = myContext->ProjPS(mySurface.Face());
547 aProjector.Perform(aPoint);
549 if(aProjector.IsDone() && aProjector.NbPoints() > 0) {
550 aProjector.LowerDistanceParameters(theUParameter, theVParameter);
551 aDistance = aProjector.LowerDistance();
552 projectionfound = Standard_True;
555 if(!projectionfound) {
557 for(Standard_Integer i = 0; i < 4; i++) {
558 Standard_Real anIsoParameter = (i==0) ? myUMinParameter : ((i==1) ? myUMaxParameter : ((i==2) ? myVMinParameter : myVMaxParameter));
559 Standard_Real aMinParameter = (i < 2) ? myVMinParameter : myUMinParameter;
560 Standard_Real aMaxParameter = (i < 2) ? myVMaxParameter : myUMaxParameter;
561 Standard_Real aMidParameter = (aMinParameter + aMaxParameter) * 0.5;
562 gp_Pnt aPointMin = (i < 2) ? mySurface.Value(anIsoParameter, aMinParameter) : mySurface.Value(aMinParameter, anIsoParameter);
563 gp_Pnt aPointMax = (i < 2) ? mySurface.Value(anIsoParameter, aMaxParameter) : mySurface.Value(aMaxParameter, anIsoParameter);
564 gp_Pnt aPointMid = (i < 2) ? mySurface.Value(anIsoParameter, aMidParameter) : mySurface.Value(aMidParameter, anIsoParameter);
566 Standard_Boolean useMinMaxPoints = Standard_True;
567 Standard_Boolean computeisoline = Standard_True;
569 if(aPointMin.IsEqual(aPointMax, myCriteria) &&
570 aPointMin.IsEqual(aPointMid, myCriteria) &&
571 aPointMax.IsEqual(aPointMid, myCriteria)) {
572 computeisoline = Standard_False;
576 Handle(Geom_Curve) aCurve = (i < 2) ? myTrsfSurface->UIso(anIsoParameter) : myTrsfSurface->VIso(anIsoParameter);
577 GeomAPI_ProjectPointOnCurve aProjectorOnCurve(aPoint, aCurve, aMinParameter, aMaxParameter);
579 if(aProjectorOnCurve.NbPoints() > 0) {
580 useMinMaxPoints = Standard_False;
582 if(aDistance > aProjectorOnCurve.LowerDistance()) {
583 theUParameter = (i<=1) ? anIsoParameter : aProjectorOnCurve.LowerDistanceParameter();
584 theVParameter = (i>=2) ? anIsoParameter : aProjectorOnCurve.LowerDistanceParameter();
585 aDistance = aProjectorOnCurve.LowerDistance();
590 if(useMinMaxPoints) {
591 Standard_Real aPPDistance = aPoint.Distance(aPointMin);
593 if(aPPDistance < aDistance) {
594 theUParameter = (i<=1) ? anIsoParameter : aMinParameter;
595 theVParameter = (i>=2) ? anIsoParameter : aMinParameter;
596 aDistance = aPPDistance;
598 aPPDistance = aPoint.Distance(aPointMax);
600 if(aPPDistance < aDistance) {
601 theUParameter = (i<=1) ? anIsoParameter : aMaxParameter;
602 theVParameter = (i>=2) ? anIsoParameter : aMaxParameter;
603 aDistance = aPPDistance;
608 theUParameter = (myUMinParameter > theUParameter) ? myUMinParameter : theUParameter;
609 theUParameter = (myUMaxParameter < theUParameter) ? myUMaxParameter : theUParameter;
610 theVParameter = (myVMinParameter > theVParameter) ? myVMinParameter : theVParameter;
611 theVParameter = (myVMaxParameter < theVParameter) ? myVMaxParameter : theVParameter;
616 // ==================================================================================
617 // function: ComputeAroundExactIntersection
619 // ==================================================================================
620 void IntTools_BeanFaceIntersector::ComputeAroundExactIntersection()
622 IntCurveSurface_HInter anExactIntersector;
624 Handle(BRepAdaptor_HCurve) aCurve = new BRepAdaptor_HCurve(myCurve);
625 Handle(BRepAdaptor_HSurface) aSurface = new BRepAdaptor_HSurface(mySurface);
627 anExactIntersector.Perform(aCurve, aSurface);
629 if(anExactIntersector.IsDone()) {
630 Standard_Integer i = 0;
632 for(i = 1; i <= anExactIntersector.NbPoints(); i++) {
633 const IntCurveSurface_IntersectionPoint& aPoint = anExactIntersector.Point(i);
635 if((aPoint.W() >= myFirstParameter) && (aPoint.W() <= myLastParameter)) {
636 Standard_Boolean UIsNotValid = ((myUMinParameter > aPoint.U()) || (aPoint.U() > myUMaxParameter));
637 Standard_Boolean VIsNotValid = ((myVMinParameter > aPoint.V()) || (aPoint.V() > myVMaxParameter));
638 Standard_Boolean solutionIsValid = !UIsNotValid && !VIsNotValid;
639 Standard_Real U = aPoint.U();
640 Standard_Real V = aPoint.V();
642 if(UIsNotValid || VIsNotValid) {
643 Standard_Boolean bUCorrected = Standard_True;
646 bUCorrected = Standard_False;
647 solutionIsValid = Standard_False;
649 if(mySurface.IsUPeriodic()) {
650 Standard_Real aNewU, aUPeriod, aEps, du;
652 aUPeriod = mySurface.UPeriod();
653 aEps = Epsilon(aUPeriod);
655 GeomInt::AdjustPeriodic(U, myUMinParameter, myUMaxParameter,
656 aUPeriod, aNewU, du, aEps);
657 solutionIsValid = Standard_True;
658 bUCorrected = Standard_True;
662 // if(solutionIsValid && VIsNotValid) {
663 if(bUCorrected && VIsNotValid) {
664 solutionIsValid = Standard_False;
666 if(mySurface.IsVPeriodic()) {
667 Standard_Real aNewV, aVPeriod, aEps, dv;
669 aVPeriod = mySurface.VPeriod();
670 aEps = Epsilon(aVPeriod);
672 GeomInt::AdjustPeriodic(V, myVMinParameter, myVMaxParameter,
673 aVPeriod, aNewV, dv, aEps);
674 solutionIsValid = Standard_True;
683 Standard_Integer aNbRanges = myRangeManager.Length();
685 ComputeRangeFromStartPoint(Standard_False, aPoint.W(), U, V);
686 ComputeRangeFromStartPoint(Standard_True, aPoint.W(), U, V);
688 if(aNbRanges == myRangeManager.Length()) {
689 SetEmptyResultRange(aPoint.W(), myRangeManager);
690 } // end if(aNbRanges == myRangeManager.Length())
694 for(i = 1; i <= anExactIntersector.NbSegments(); i++) {
695 const IntCurveSurface_IntersectionSegment& aSegment = anExactIntersector.Segment(i);
696 IntCurveSurface_IntersectionPoint aPoint1, aPoint2;
697 aSegment.Values(aPoint1, aPoint2);
699 Standard_Real aFirstParameter = (aPoint1.W() < myFirstParameter) ? myFirstParameter : aPoint1.W();
700 Standard_Real aLastParameter = (myLastParameter < aPoint2.W()) ? myLastParameter : aPoint2.W();
702 myRangeManager.InsertRange(aFirstParameter, aLastParameter, 2);
704 ComputeRangeFromStartPoint(Standard_False, aPoint1.W(), aPoint1.U(), aPoint1.V());
705 ComputeRangeFromStartPoint(Standard_True, aPoint2.W(), aPoint2.U(), aPoint2.V());
710 // ==================================================================================
711 // function: FastComputeExactIntersection
713 // ==================================================================================
714 Standard_Integer IntTools_BeanFaceIntersector::FastComputeExactIntersection()
716 Standard_Integer aresult;
717 GeomAbs_CurveType aCT;
718 GeomAbs_SurfaceType aST;
721 aCT=myCurve.GetType();
722 aST=mySurface.GetType();
724 if((aCT==GeomAbs_BezierCurve) ||
725 (aCT==GeomAbs_BSplineCurve) ||
726 (aCT==GeomAbs_OtherCurve)) {
730 if(aST==GeomAbs_Plane) {
731 gp_Pln surfPlane = mySurface.Plane();
733 if(aCT==GeomAbs_Line) {
734 if((surfPlane.Distance(myCurve.Value(myFirstParameter)) < myCriteria) &&
735 (surfPlane.Distance(myCurve.Value(myLastParameter)) < myCriteria)) {
743 case GeomAbs_Circle: {
744 aDir = myCurve.Circle().Axis().Direction();
747 case GeomAbs_Ellipse: {
748 aDir = myCurve.Ellipse().Axis().Direction();
751 case GeomAbs_Hyperbola: {
752 aDir = myCurve.Hyperbola().Axis().Direction();
755 case GeomAbs_Parabola: {
756 aDir = myCurve.Parabola().Axis().Direction();
764 Standard_Real anAngle = aDir.Angle(surfPlane.Axis().Direction());
766 if(anAngle < Precision::Angular()) {
767 Standard_Boolean insertRange = Standard_False;
770 case GeomAbs_Circle: {
771 Standard_Real adist =
772 surfPlane.Distance(myCurve.Circle().Location()) +
773 myCurve.Circle().Radius() * Precision::Angular();
775 if(adist < myCriteria) {
776 insertRange = Standard_True;
780 case GeomAbs_Ellipse: {
781 Standard_Real adist =
782 surfPlane.Distance(myCurve.Ellipse().Location()) +
783 myCurve.Ellipse().MajorRadius() * Precision::Angular();
785 if(adist < myCriteria) {
786 insertRange = Standard_True;
790 case GeomAbs_Hyperbola:
791 case GeomAbs_Parabola: {
792 Standard_Real aMaxPar =
793 (Abs(myFirstParameter) > Abs(myLastParameter)) ?
794 Abs(myFirstParameter) : Abs(myLastParameter);
796 gp_Pnt aLoc = (aCT == GeomAbs_Parabola) ?
797 myCurve.Parabola().Location() :
798 myCurve.Hyperbola().Location();
799 Standard_Real adist = aLoc.Distance(myCurve.Value(aMaxPar));
800 adist = surfPlane.Distance(aLoc) + adist * Precision::Angular();
802 if(adist < myCriteria) {
803 insertRange = Standard_True;
815 }//if(anAngle < Precision::Angular()) {
817 }// if(aST==GeomAbs_Plane) {
819 if(aCT==GeomAbs_Circle) {
820 gp_Circ aCircle = myCurve.Circle();
822 if(aST==GeomAbs_Cylinder) {
823 gp_Cylinder aCylinder = mySurface.Cylinder();
824 gp_Dir aDir1(aCylinder.Axis().Direction());
825 gp_Dir aDir2(aCircle.Axis().Direction());
826 Standard_Real anAngle = aDir1.Angle(aDir2);
828 if(anAngle < Precision::Angular()) {
829 gp_Pnt aLoc = aCircle.Location();
830 gp_Lin anCylAxis(aCylinder.Axis());
831 Standard_Real alocdist = anCylAxis.Distance(aLoc);
832 Standard_Real adist = alocdist;
833 Standard_Real adiff = aCircle.Radius() - aCylinder.Radius();
836 if(adist < myCriteria) {
837 Standard_Real acylradius = aCylinder.Radius();
838 Standard_Real atmpvalue = aCircle.Radius() * sin(Precision::Angular());
839 Standard_Real aprojectedradius = atmpvalue;
841 sqrt((aCircle.Radius() * aCircle.Radius())
842 - (aprojectedradius * aprojectedradius));
843 adiff = aprojectedradius - acylradius;
844 adist = alocdist + Abs(adiff);
846 if(adist < myCriteria) { // Abs is important function here
851 }// if(aST==GeomAbs_Cylinder)
853 if(aST==GeomAbs_Sphere) {
854 gp_Pln aCirclePln(aCircle.Location(), aCircle.Axis().Direction());
855 IntAna_QuadQuadGeo anInter(aCirclePln, mySurface.Sphere());
857 if(anInter.IsDone()) {
858 if(anInter.TypeInter() == IntAna_Circle) {
859 gp_Circ aCircleToCompare = anInter.Circle(1);
860 Standard_Real adist =
861 aCircleToCompare.Location().Distance(aCircle.Location());
862 Standard_Real adiff = aCircle.Radius() - aCircleToCompare.Radius();
865 if(adist < myCriteria) {
870 }// if(aST==GeomAbs_Sphere) {
871 }// if(aCT==GeomAbs_Circle) {
873 //modified by NIZNHY-PKV Thu Mar 01 11:54:04 2012f
874 if(aST==GeomAbs_Cylinder) {
878 aCyl=mySurface.Cylinder();
880 const gp_Ax1& aAx1C=aCyl.Axis();
881 const gp_Dir& aDirC=aAx1C.Direction();
883 if(aCT==GeomAbs_Line) {
884 Standard_Real aCos, aAng2, aTolang2;
889 const gp_Dir& aDirL=aLin.Direction();
891 aCos=aDirC.Dot(aDirL);
893 aAng2 = 2.*(1. - aCos);
896 aAng2 = 2.*(1. + aCos);
899 if(aAng2<=aTolang2) {// IsParallel = Standard_True;
900 Standard_Boolean bFlag = Standard_False;
906 aPL[0]=myCurve.Value(myFirstParameter);
907 aPL[1]=myCurve.Value(myLastParameter);
909 for (i=0; i<2; ++i) {
910 aD=aLC.Distance(aPL[i]);
912 bFlag=(aD > myCriteria);
922 }//if(aCT==GeomAbs_Line) {
924 //modified by NIZNHY-PKV Thu Mar 01 11:54:06 2012t
927 //check intermediate point
929 Standard_Boolean bValid;
931 const TopoDS_Face& aF = mySurface.Face();
932 aTm = IntTools_Tools::IntermediatePoint(myFirstParameter, myLastParameter);
933 const gp_Pnt& aPm = myCurve.Value(aTm);
935 bValid = myContext->IsValidPointForFace(aPm, aF, myCriteria);
937 IntTools_Range aRange(myFirstParameter, myLastParameter);
938 myRangeManager.InsertRange(aRange, 2);
947 // ==================================================================================
948 // function: ComputeLinePlane
950 // ==================================================================================
951 void IntTools_BeanFaceIntersector::ComputeLinePlane()
953 Standard_Real Tolang = 1.e-9;
954 gp_Pln P = mySurface.Plane();
955 gp_Lin L = myCurve.Line();
957 myIsDone = Standard_True;
959 Standard_Real A,B,C,D;
960 Standard_Real Al,Bl,Cl;
961 Standard_Real Dis,Direc;
963 P.Coefficients(A,B,C,D);
964 gp_Pnt Orig(L.Location());
965 L.Direction().Coord(Al,Bl,Cl);
967 Direc=A*Al+B*Bl+C*Cl;
968 Dis = A*Orig.X() + B*Orig.Y() + C*Orig.Z() + D;
970 Standard_Boolean parallel = Standard_False, inplane = Standard_False;
971 if (Abs(Direc) < Tolang) {
972 parallel= Standard_True;
973 if (Abs(Dis) < myCriteria) {
974 inplane=Standard_True;
977 inplane=Standard_False;
981 gp_Pnt p1 = ElCLib::Value(myFirstParameter, L);
982 gp_Pnt p2 = ElCLib::Value(myLastParameter, L);
983 Standard_Real d1 = A*p1.X() + B*p1.Y() + C*p1.Z() + D;
985 Standard_Real d2 = A*p2.X() + B*p2.Y() + C*p2.Z() + D;
987 if(d1 <= myCriteria && d2 <= myCriteria) {
988 inplane=Standard_True;
993 IntTools_Range aRange(myFirstParameter, myLastParameter);
994 myResults.Append(aRange);
1002 Standard_Real t = - Dis/Direc;
1003 if(t < myFirstParameter || t > myLastParameter) {
1007 gp_Pnt pint(Orig.X()+t*Al, Orig.Y()+t*Bl, Orig.Z()+t*Cl);
1010 ElSLib::Parameters(P, pint, u, v);
1011 if(myUMinParameter > u || u > myUMaxParameter || myVMinParameter > v || v > myVMaxParameter) {
1015 Standard_Real t1 = Max(myFirstParameter, t-myCriteria);
1016 Standard_Real t2 = Min(myLastParameter, t+myCriteria);
1017 IntTools_Range aRange(t1, t2);
1018 myResults.Append(aRange);
1025 // ==================================================================================
1026 // function: ComputeUsingExtremum
1028 // ==================================================================================
1029 void IntTools_BeanFaceIntersector::ComputeUsingExtremum()
1031 Standard_Real Tol, af, al;
1032 Tol = Precision::PConfusion();
1033 Handle(Geom_Curve) aCurve = BRep_Tool::Curve (myCurve.Edge(), af, al);
1034 GeomAdaptor_Surface aGASurface (myTrsfSurface,
1041 BndLib_AddSurface::Add(mySurface, 0., FBox);
1042 FBox.Enlarge(myFaceTolerance);
1044 for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
1046 if(myRangeManager.Flag(i) > 0)
1049 IntTools_Range aParamRange = myRangeManager.Range(i);
1050 Standard_Real anarg1 = aParamRange.First();
1051 Standard_Real anarg2 = aParamRange.Last();
1053 if(anarg2 - anarg1 < Precision::PConfusion()) {
1055 if(((i > 1) && (myRangeManager.Flag(i-1) == 2)) ||
1056 ((i < myRangeManager.Length()) && (myRangeManager.Flag(i+1) == 2))) {
1057 myRangeManager.SetFlag(i, 1);
1062 // check bounding boxes
1064 EBox.Add(myCurve.Value(anarg1));
1065 EBox.Add(myCurve.Value(anarg2));
1066 EBox.Enlarge(myBeanTolerance + myDeflection);
1068 if(EBox.IsOut(FBox)) {
1069 myRangeManager.SetFlag(i, 1);
1073 GeomAdaptor_Curve aGACurve(aCurve, anarg1, anarg2);
1074 Extrema_ExtCS theExtCS(aGACurve, aGASurface, Tol, Tol);
1075 myExtrema = theExtCS;
1077 if(myExtrema.IsDone() && (myExtrema.NbExt() || myExtrema.IsParallel())) {
1078 Standard_Integer anOldNbRanges = myRangeManager.Length();
1080 if (myExtrema.IsParallel()) {
1082 if(myExtrema.SquareDistance(1) < myCriteria * myCriteria) {
1083 Standard_Real U1, V1, U2, V2;
1084 Standard_Real adistance1 = Distance(anarg1, U1, V1);
1085 Standard_Real adistance2 = Distance(anarg2, U2, V2);
1086 Standard_Boolean validdistance1 = (adistance1 < myCriteria);
1087 Standard_Boolean validdistance2 = (adistance2 < myCriteria);
1089 if (validdistance1 && validdistance2) {
1090 myRangeManager.InsertRange(anarg1, anarg2, 2);
1094 if(validdistance1) {
1095 ComputeRangeFromStartPoint(Standard_True, anarg1, U1, V1);
1098 if(validdistance2) {
1099 ComputeRangeFromStartPoint(Standard_False, anarg2, U2, V2);
1102 Standard_Real a = anarg1;
1103 Standard_Real b = anarg2;
1104 Standard_Real da = adistance1;
1105 Standard_Real db = adistance2;
1106 Standard_Real asolution = a;
1107 Standard_Boolean found = Standard_False;
1109 while(((b - a) > myCurveResolution) && !found) {
1110 asolution = (a+b)*0.5;
1111 Standard_Real adist = Distance(asolution, U1, V1);
1113 if(adist < myCriteria) {
1114 found = Standard_True;
1129 ComputeRangeFromStartPoint(Standard_False, asolution, U1, V1);
1130 ComputeRangeFromStartPoint(Standard_True, asolution, U1, V1);
1133 myRangeManager.SetFlag(i, 1);
1140 myRangeManager.SetFlag(i, 1);
1144 Standard_Boolean solutionfound = Standard_False;
1146 for(Standard_Integer j = 1 ; j <= myExtrema.NbExt(); j++) {
1148 if(myExtrema.SquareDistance(j) < myCriteria * myCriteria) {
1151 myExtrema.Points(j, p1, p2);
1155 Standard_Integer aNbRanges = myRangeManager.Length();
1156 ComputeRangeFromStartPoint(Standard_False, p1.Parameter(), U, V);
1157 ComputeRangeFromStartPoint(Standard_True, p1.Parameter(), U, V);
1158 solutionfound = Standard_True;
1160 if(aNbRanges == myRangeManager.Length()) {
1161 SetEmptyResultRange(p1.Parameter(), myRangeManager);
1166 if(!solutionfound) {
1167 myRangeManager.SetFlag(i, 1);
1170 Standard_Integer adifference = myRangeManager.Length() - anOldNbRanges;
1172 if(adifference > 0) {
1175 } // end if(myExtrema.IsDone() && (myExtrema.NbExt() || myExtrema.IsParallel()))
1179 // ==================================================================================
1180 // function: ComputeNearRangeBoundaries
1182 // ==================================================================================
1183 void IntTools_BeanFaceIntersector::ComputeNearRangeBoundaries()
1185 Standard_Real U = myUMinParameter;
1186 Standard_Real V = myVMinParameter;
1188 for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
1190 if(myRangeManager.Flag(i) > 0)
1193 if((i > 1) && (myRangeManager.Flag(i-1) > 0))
1196 IntTools_Range aParamRange = myRangeManager.Range(i);
1198 if(Distance(aParamRange.First(), U, V) < myCriteria) {
1199 Standard_Integer aNbRanges = myRangeManager.Length();
1202 ComputeRangeFromStartPoint(Standard_False, aParamRange.First(), U, V, i-1);
1204 ComputeRangeFromStartPoint(Standard_True, aParamRange.First(), U, V, i + (myRangeManager.Length() - aNbRanges));
1206 if(aNbRanges == myRangeManager.Length()) {
1207 SetEmptyResultRange(aParamRange.First(), myRangeManager);
1212 if(myRangeManager.Flag(myRangeManager.Length()) == 0) {
1213 IntTools_Range aParamRange = myRangeManager.Range(myRangeManager.Length());
1215 if(Distance(aParamRange.Last(), U, V) < myCriteria) {
1216 Standard_Integer aNbRanges = myRangeManager.Length();
1218 ComputeRangeFromStartPoint(Standard_False, aParamRange.Last(), U, V, myRangeManager.Length());
1220 if(aNbRanges == myRangeManager.Length()) {
1221 SetEmptyResultRange(aParamRange.Last(), myRangeManager);
1227 // ==================================================================================
1228 // function: ComputeRangeFromStartPoint
1229 // purpose: Compute range using start point according to parameter theParameter,
1230 // increasing parameter on curve if ToIncreaseParameter == Standard_True or
1231 // decreasing parameter on curve if ToIncreaseParameter == Standard_False
1232 // ==================================================================================
1233 void IntTools_BeanFaceIntersector::ComputeRangeFromStartPoint(const Standard_Boolean ToIncreaseParameter,
1234 const Standard_Real theParameter,
1235 const Standard_Real theUParameter,
1236 const Standard_Real theVParameter)
1238 Standard_Integer aFoundIndex = myRangeManager.GetIndex(theParameter, ToIncreaseParameter);
1240 if(aFoundIndex == 0) {
1244 ComputeRangeFromStartPoint(ToIncreaseParameter, theParameter, theUParameter, theVParameter, aFoundIndex);
1247 // ==================================================================================
1248 // function: ComputeRangeFromStartPoint
1249 // purpose: Compute range using start point according to parameter theParameter,
1250 // increasing parameter on curve if ToIncreaseParameter == Standard_True or
1251 // decreasing parameter on curve if ToIncreaseParameter == Standard_False.
1252 // theIndex indicate that theParameter belong the range number theIndex.
1253 // ==================================================================================
1254 void IntTools_BeanFaceIntersector::ComputeRangeFromStartPoint(const Standard_Boolean ToIncreaseParameter,
1255 const Standard_Real theParameter,
1256 const Standard_Real theUParameter,
1257 const Standard_Real theVParameter,
1258 const Standard_Integer theIndex)
1260 if(myRangeManager.Flag(theIndex) > 0)
1263 Standard_Integer aValidIndex = theIndex;
1265 Standard_Real aMinDelta = myCurveResolution * 0.5;
1266 Standard_Real aDeltaRestrictor = myLastParameter - myFirstParameter;
1268 if(aMinDelta > aDeltaRestrictor)
1269 aMinDelta = aDeltaRestrictor * 0.5;
1271 Standard_Real tenOfMinDelta = aMinDelta * 10.;
1272 Standard_Real aDelta = myCurveResolution;
1274 Standard_Real aCurPar = (ToIncreaseParameter) ? (theParameter + aDelta) : (theParameter - aDelta);
1275 Standard_Real aPrevPar = theParameter;
1276 IntTools_Range aCurrentRange = myRangeManager.Range(aValidIndex);
1278 Standard_Boolean BoundaryCondition = (ToIncreaseParameter) ? (aCurPar > aCurrentRange.Last()) : (aCurPar < aCurrentRange.First());
1280 if(BoundaryCondition) {
1281 aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First();
1282 BoundaryCondition = Standard_False;
1285 Standard_Integer loopcounter = 0; // neccesary as infinite loop restricter
1286 Standard_Real U = theUParameter;
1287 Standard_Real V = theVParameter;
1288 Standard_Boolean anotherSolutionFound = Standard_False;
1290 Standard_Boolean isboundaryindex = Standard_False;
1291 Standard_Boolean isvalidindex = Standard_True;
1293 while((aDelta >= aMinDelta) && (loopcounter <= 10)) {
1294 Standard_Boolean pointfound = Standard_False;
1297 gp_Pnt aPoint = myCurve.Value(aCurPar);
1298 Extrema_GenLocateExtPS anExtrema(aPoint, mySurface, U, V, 1.e-10, 1.e-10);
1300 if(anExtrema.IsDone()) {
1301 if(anExtrema.SquareDistance() < myCriteria * myCriteria) {
1302 Extrema_POnSurf aPOnSurf = anExtrema.Point();
1303 aPOnSurf.Parameter(U, V);
1304 pointfound = Standard_True;
1308 pointfound = (Distance(aCurPar) < myCriteria);
1313 anotherSolutionFound = Standard_True;
1315 if(BoundaryCondition && (isboundaryindex || !isvalidindex))
1319 aDeltaRestrictor = aDelta;
1322 // if point found decide to increase aDelta using derivative of distance function
1325 aDelta = (pointfound) ? (aDelta * 2.) : (aDelta * 0.5);
1326 aDelta = (aDelta < aDeltaRestrictor) ? aDelta : aDeltaRestrictor;
1328 aCurPar = (ToIncreaseParameter) ? (aPrevPar + aDelta) : (aPrevPar - aDelta);
1331 // prevent infinite loop when (aPrevPar +/- aDelta) == aPrevPar == 0.
1334 if( aCurPar == aPrevPar )
1337 BoundaryCondition = (ToIncreaseParameter) ? (aCurPar > aCurrentRange.Last()) : (aCurPar < aCurrentRange.First());
1339 isboundaryindex = Standard_False;
1340 isvalidindex = Standard_True;
1342 if(BoundaryCondition) {
1343 isboundaryindex = ((!ToIncreaseParameter && (aValidIndex == 1)) ||
1344 (ToIncreaseParameter && (aValidIndex == myRangeManager.Length())));
1346 if(!isboundaryindex) {
1349 Standard_Integer aFlag = (ToIncreaseParameter) ? myRangeManager.Flag(aValidIndex + 1) : myRangeManager.Flag(aValidIndex - 1);
1352 aValidIndex = (ToIncreaseParameter) ? (aValidIndex + 1) : (aValidIndex - 1);
1353 aCurrentRange = myRangeManager.Range(aValidIndex);
1355 if((ToIncreaseParameter && (aCurPar > aCurrentRange.Last())) ||
1356 (!ToIncreaseParameter && (aCurPar < aCurrentRange.First()))) {
1357 aCurPar = (aCurrentRange.First() + aCurrentRange.Last()) * 0.5;
1362 isvalidindex = Standard_False;
1363 aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First();
1368 aCurPar = (ToIncreaseParameter) ? aCurrentRange.Last() : aCurrentRange.First();
1371 if(aDelta < tenOfMinDelta) {
1377 } // if(BoundaryCondition)
1380 if(anotherSolutionFound) {
1381 if(ToIncreaseParameter)
1382 myRangeManager.InsertRange(theParameter, aPrevPar, 2);
1384 myRangeManager.InsertRange(aPrevPar, theParameter, 2);
1388 // ---------------------------------------------------------------------------------
1389 // static function: SetEmptyResultRange
1391 // ---------------------------------------------------------------------------------
1392 static Standard_Boolean SetEmptyResultRange(const Standard_Real theParameter,
1393 IntTools_MarkedRangeSet& theMarkedRange) {
1395 const TColStd_SequenceOfInteger& anIndices = theMarkedRange.GetIndices(theParameter);
1396 Standard_Boolean add = (anIndices.Length() > 0);
1398 for(Standard_Integer k = 1; k <= anIndices.Length(); k++) {
1399 if(theMarkedRange.Flag(anIndices(k)) == 2) {
1400 add = Standard_False;
1406 theMarkedRange.InsertRange(theParameter, theParameter, 2);
1412 // ---------------------------------------------------------------------------------
1413 // static function: TestCoinside
1415 // ---------------------------------------------------------------------------------
1416 // static Standard_Boolean TestClose(const Extrema_ExtPS & theExt,
1417 // const Standard_Real theDist)
1419 // Standard_Boolean close = Standard_False;
1420 // if(!theExt.IsDone() || theExt.NbExt() == 0)
1423 // Standard_Integer ie;
1424 // for(ie = 1; ie <= theExt.NbExt(); ie++) {
1425 // Standard_Real dist = theExt.Value(ie);
1426 // if(dist <= theDist) {
1427 // close = Standard_True;
1435 // Standard_Boolean TestCoinside(const BRepAdaptor_Curve& theCurve,
1436 // const BRepAdaptor_Surface& theSurface)
1438 // Standard_Real cfp = theCurve.FirstParameter(), clp = theCurve.LastParameter();
1439 // Standard_Real cdp = fabs(clp - cfp) / 23.;
1441 // Standard_Integer i = 0;
1442 // Standard_Real tolE = theCurve.Tolerance(), tolF = theSurface.Tolerance();
1443 // Standard_Real tolT = tolE + tolF, tolU = 1.e-9, tolV = 1.e-9;
1446 // theCurve.D0(cfp,aP);
1447 // Extrema_ExtPS eps(aP,theSurface,tolU,tolV);
1449 // if(!TestClose(eps,tolT))
1450 // return Standard_False;
1452 // theCurve.D0(clp,aP);
1455 // if(!TestClose(eps,tolT))
1456 // return Standard_False;
1458 // Standard_Boolean close = Standard_True;
1460 // for(i = 1; i <= 22; i++) {
1461 // theCurve.D0((cfp+((Standard_Real)i)*cdp),aP);
1463 // if(!TestClose(eps,tolT)) {
1464 // close = Standard_False;
1471 // ======================================================================================================================
1472 // function: LocalizeSolutions
1474 // ======================================================================================================================
1475 Standard_Boolean IntTools_BeanFaceIntersector::LocalizeSolutions(const IntTools_CurveRangeSample& theCurveRange,
1476 const Bnd_Box& theBoxCurve,
1477 const IntTools_SurfaceRangeSample& theSurfaceRange,
1478 const Bnd_Box& theBoxSurface,
1479 IntTools_CurveRangeLocalizeData& theCurveData,
1480 IntTools_SurfaceRangeLocalizeData& theSurfaceData,
1481 IntTools_ListOfCurveRangeSample& theListCurveRange,
1482 IntTools_ListOfSurfaceRangeSample& theListSurfaceRange)
1484 Standard_Integer tIt = 0, uIt = 0, vIt = 0;
1487 IntTools_CurveRangeSample aRootRangeC(0);
1488 aRootRangeC.SetDepth(0);
1489 IntTools_SurfaceRangeSample aRootRangeS(0, 0, 0, 0);
1491 Bnd_Box aMainBoxC = theBoxCurve;
1492 Bnd_Box aMainBoxS = theBoxSurface;
1493 Standard_Boolean bMainBoxFoundS = Standard_False;
1494 Standard_Boolean bMainBoxFoundC = Standard_False;
1496 IntTools_ListOfCurveRangeSample aListCurveRangeFound;
1497 IntTools_ListOfSurfaceRangeSample aListSurfaceRangeFound;
1500 IntTools_Range aRangeC = theCurveRange.GetRange(myFirstParameter, myLastParameter, theCurveData.GetNbSample());
1501 Standard_Real localdiffC = (aRangeC.Last() - aRangeC.First()) / theCurveData.GetNbSample();
1503 Standard_Real aCurPar = aRangeC.First();
1504 Standard_Real aPrevPar = aRangeC.First();
1505 Standard_Integer aCurIndexInit = theCurveRange.GetRangeIndexDeeper(theCurveData.GetNbSample());
1508 TColStd_ListOfInteger aListCToAvoid;
1509 Standard_Boolean bGlobalCheckDone = Standard_False;
1514 Standard_Integer aCurIndexU = theSurfaceRange.GetRangeIndexUDeeper(theSurfaceData.GetNbSampleU());
1516 Standard_Integer aCurIndexVInit = theSurfaceRange.GetRangeIndexVDeeper(theSurfaceData.GetNbSampleV());
1517 IntTools_Range aRangeV = theSurfaceRange.GetRangeV(myVMinParameter, myVMaxParameter, theSurfaceData.GetNbSampleV());
1520 IntTools_Range aRangeU = theSurfaceRange.GetRangeU(myUMinParameter, myUMaxParameter, theSurfaceData.GetNbSampleU());
1521 Standard_Real aCurParU = aRangeU.First();
1522 Standard_Real aLocalDiffU = (aRangeU.Last() - aRangeU.First()) / theSurfaceData.GetNbSampleU();
1524 Standard_Real aPrevParU = aCurParU;
1525 Standard_Real aLocalDiffV = (aRangeV.Last() - aRangeV.First()) / theSurfaceData.GetNbSampleV();
1528 // ranges check.begin
1529 Standard_Boolean bAllowSamplingC = Standard_True;
1530 Standard_Boolean bAllowSamplingU = Standard_True;
1531 Standard_Boolean bAllowSamplingV = Standard_True;
1534 CheckSampling(theCurveRange, theSurfaceRange, theCurveData, theSurfaceData,
1535 localdiffC, aLocalDiffU, aLocalDiffV,
1536 bAllowSamplingC, bAllowSamplingU, bAllowSamplingV);
1539 if(!bAllowSamplingC && !bAllowSamplingU && !bAllowSamplingV) {
1540 theListCurveRange.Append(theCurveRange);
1541 theListSurfaceRange.Append(theSurfaceRange);
1542 return Standard_True;
1546 // init template. begin
1547 IntTools_CurveRangeSample aNewRangeCTemplate;
1549 if(!bAllowSamplingC) {
1550 aNewRangeCTemplate = theCurveRange;
1551 aCurIndexInit = theCurveRange.GetRangeIndex();
1552 localdiffC = (aRangeC.Last() - aRangeC.First());
1555 aNewRangeCTemplate.SetDepth(theCurveRange.GetDepth() + 1);
1556 aNewRangeCTemplate.SetRangeIndex(aCurIndexInit);
1559 IntTools_SurfaceRangeSample aNewRangeSTemplate = theSurfaceRange;
1561 if(bAllowSamplingU) {
1562 aNewRangeSTemplate.SetDepthU(theSurfaceRange.GetDepthU() + 1);
1565 aCurIndexU = aNewRangeSTemplate.GetIndexU();
1566 aLocalDiffU = aRangeU.Last() - aRangeU.First();
1569 if(bAllowSamplingV) {
1570 aNewRangeSTemplate.SetDepthV(theSurfaceRange.GetDepthV() + 1);
1573 aCurIndexVInit = theSurfaceRange.GetIndexV();
1574 aLocalDiffV = aRangeV.Last() - aRangeV.First();
1576 // init template. end
1579 Standard_Boolean bHasOut = Standard_False;
1580 const Standard_Integer nbU = (bAllowSamplingU) ? theSurfaceData.GetNbSampleU() : 1;
1581 const Standard_Integer nbV = (bAllowSamplingV) ? theSurfaceData.GetNbSampleV() : 1;
1582 const Standard_Integer nbC = (bAllowSamplingC) ? theCurveData.GetNbSample() : 1;
1584 for(uIt = 1; uIt <= nbU; uIt++, aCurIndexU++, aPrevParU = aCurParU) {
1585 aCurParU += aLocalDiffU;
1588 Standard_Real aCurParV = aRangeV.First();
1589 Standard_Real aPrevParV = aCurParV;
1590 Standard_Integer aCurIndexV = aCurIndexVInit;
1592 Standard_Boolean bHasOutV = Standard_False;
1595 for(vIt = 1; vIt <= nbV; vIt++, aCurIndexV++, aPrevParV = aCurParV) {
1597 aCurParV += aLocalDiffV;
1602 IntTools_SurfaceRangeSample aNewRangeS = aNewRangeSTemplate;
1604 if(bAllowSamplingU) {
1605 aNewRangeS.SetIndexU(aCurIndexU);
1608 if(bAllowSamplingV) {
1609 aNewRangeS.SetIndexV(aCurIndexV);
1612 if(theSurfaceData.IsRangeOut(aNewRangeS)) {
1613 bHasOutV = Standard_True;
1621 if(!theSurfaceData.FindBox(aNewRangeS, aBoxS)) {
1623 if(mySurface.GetType() == GeomAbs_BSplineSurface) {
1624 // if(Standard_False ) {
1625 Handle(Geom_BSplineSurface) aSurfBspl = Handle(Geom_BSplineSurface)::DownCast(myTrsfSurface);
1626 aBoxS = GetSurfaceBox(aSurfBspl, aPrevParU, aCurParU, aPrevParV, aCurParV, myCriteria, theSurfaceData);
1629 BndLib_AddSurface::Add(mySurface, aPrevParU, aCurParU, aPrevParV, aCurParV, myCriteria, aBoxS);
1631 // Bnd_Box aMainBoxC;
1633 if(!bMainBoxFoundC && theCurveData.FindBox(aRootRangeC, aMainBoxC)) {
1634 bMainBoxFoundC = Standard_True;
1637 if(aBoxS.IsOut(aMainBoxC)) {
1638 theSurfaceData.AddOutRange(aNewRangeS);
1639 bHasOutV = Standard_True;
1643 theSurfaceData.AddBox(aNewRangeS, aBoxS);
1646 if(aBoxS.IsOut(theBoxCurve)) {
1647 bHasOutV = Standard_True;
1651 IntTools_ListOfBox aListOfBox;
1652 TColStd_ListOfInteger aListOfIndex;
1654 Standard_Boolean bHasOutC = Standard_False;
1655 Standard_Integer aCurIndex = aCurIndexInit;
1657 // ////////////////////////////
1658 aCurPar = aRangeC.First();
1659 aPrevPar = aRangeC.First();
1660 IntTools_CurveRangeSample aCurRangeC = aNewRangeCTemplate;
1662 for (tIt = 1; tIt <= nbC; tIt++, aCurIndex++, aPrevPar = aCurPar) {
1664 aCurPar += localdiffC;
1666 // ignore already computed. begin
1667 Standard_Boolean bFound = Standard_False;
1668 TColStd_ListIteratorOfListOfInteger anItToAvoid(aListCToAvoid);
1670 for(; anItToAvoid.More(); anItToAvoid.Next()) {
1671 if(tIt == anItToAvoid.Value()) {
1672 bFound = Standard_True;
1678 if(bAllowSamplingC) {
1679 aCurRangeC.SetRangeIndex(aCurIndex);
1681 bFound = theCurveData.IsRangeOut(aCurRangeC);
1685 bHasOutC = Standard_True;
1688 // ignore already computed. end
1693 if(!theCurveData.FindBox(aCurRangeC, aBoxC)) {
1694 BndLib_Add3dCurve::Add(myCurve, aPrevPar, aCurPar, myCriteria, aBoxC);
1696 // Bnd_Box aMainBoxS;
1698 if(!bMainBoxFoundS && theSurfaceData.FindBox(aRootRangeS, aMainBoxS)) {
1699 bMainBoxFoundS = Standard_True;
1701 if(aBoxC.IsOut(aMainBoxS)) {
1702 theCurveData.AddOutRange(aCurRangeC);
1703 bHasOutC = Standard_True;
1707 theCurveData.AddBox(aCurRangeC, aBoxC);
1710 if(!bGlobalCheckDone && aBoxC.IsOut(theBoxSurface)) {
1711 aListCToAvoid.Append(tIt);
1712 bHasOutC = Standard_True;
1716 if(aBoxC.IsOut(aBoxS)) {
1717 bHasOutV = Standard_True;
1718 bHasOutC = Standard_True;
1723 aListOfIndex.Append(tIt);
1724 aListOfBox.Append(aBoxC);
1725 } // end for(tIt...)
1727 bGlobalCheckDone = Standard_True;
1730 bHasOutV = Standard_True;
1736 IntTools_CurveRangeSample aNewRangeC = aNewRangeCTemplate;
1738 aCurIndex = aCurIndexInit;
1739 TColStd_ListIteratorOfListOfInteger anItI(aListOfIndex);
1740 IntTools_ListIteratorOfListOfBox anItBox(aListOfBox);
1741 Standard_Boolean bUseOldC = Standard_False;
1742 Standard_Boolean bUseOldS = Standard_False;
1743 Standard_Boolean bCheckSize = !bHasOutC;
1745 for(; anItI.More() && anItBox.More(); anItI.Next(), anItBox.Next()) {
1746 aCurIndex = aCurIndexInit + anItI.Value() - 1;
1748 bUseOldS = Standard_False;
1750 if(bAllowSamplingC) {
1751 aNewRangeC.SetRangeIndex(aCurIndex);
1757 if((theCurveRange.GetDepth() == 0) ||
1758 (theSurfaceRange.GetDepthU() == 0) ||
1759 (theSurfaceRange.GetDepthV() == 0)) {
1760 bHasOutC = Standard_True;
1761 bHasOutV = Standard_True;
1763 else if((theCurveRange.GetDepth() < 4) &&
1764 (theSurfaceRange.GetDepthU() < 4) &&
1765 (theSurfaceRange.GetDepthV() < 4)) {
1766 Bnd_Box aBoxC = anItBox.Value();
1768 if(!aBoxC.IsWhole() && !aBoxS.IsWhole()) {
1769 Standard_Real aDiagC = aBoxC.SquareExtent();
1770 Standard_Real aDiagS = aBoxS.SquareExtent();
1772 if(aDiagC < aDiagS) {
1773 if((aDiagC * 10.) < aDiagS) {
1774 bUseOldC = Standard_True;
1775 bHasOutC = Standard_True;
1776 bHasOutV = Standard_True;
1781 if((aDiagS * 10.) < aDiagC) {
1782 bUseOldS = Standard_True;
1783 bHasOutC = Standard_True;
1784 bHasOutV = Standard_True;
1793 aListCurveRangeFound.Append(aNewRangeC);
1794 aListSurfaceRangeFound.Append(aNewRangeS);
1798 // if(bUseOldS || bAllowSamplingU || bAllowSamplingV) {
1799 // theSurfaceData.AddBox(aNewRangeS, aBoxS);
1802 if(bUseOldS && aNewRangeC.IsEqual(theCurveRange)) {
1803 return Standard_False;
1806 if(!LocalizeSolutions(aNewRangeC, anItBox.Value(),
1807 ((bUseOldS) ? theSurfaceRange : aNewRangeS),
1808 ((bUseOldS) ? theBoxSurface : aBoxS),
1809 theCurveData, theSurfaceData,
1810 theListCurveRange, theListSurfaceRange))
1811 return Standard_False;
1815 aListOfIndex.Clear();
1819 // theSurfaceData.AddBox(aNewRangeS, aBoxS);
1821 if(bUseOldC && bAllowSamplingC && (bAllowSamplingU || bAllowSamplingV)) {
1822 if(!LocalizeSolutions(theCurveRange, theBoxCurve,
1824 theCurveData, theSurfaceData,
1825 theListCurveRange, theListSurfaceRange))
1826 return Standard_False;
1829 } // end for (vIt...)
1832 bHasOut = Standard_True;
1837 theListCurveRange.Append(theCurveRange);
1838 theListSurfaceRange.Append(theSurfaceRange);
1841 IntTools_ListIteratorOfListOfCurveRangeSample anIt1(aListCurveRangeFound);
1842 IntTools_ListIteratorOfListOfSurfaceRangeSample anIt2(aListSurfaceRangeFound);
1844 for(; anIt1.More() && anIt2.More(); anIt1.Next(), anIt2.Next()) {
1845 theListCurveRange.Append(anIt1.Value());
1846 theListSurfaceRange.Append(anIt2.Value());
1849 return Standard_True;
1853 // ======================================================================================================================
1854 // function: ComputeLocalized
1856 // ======================================================================================================================
1857 Standard_Boolean IntTools_BeanFaceIntersector::ComputeLocalized() {
1858 Standard_Real Tol = Precision::PConfusion();
1860 IntTools_SurfaceRangeSample aSurfaceRange(0, 0, 0, 0);
1861 Standard_Real dMinU = 10. * Precision::PConfusion();
1862 Standard_Real dMinV = dMinU;
1863 IntTools_SurfaceRangeLocalizeData aSurfaceDataInit(3, 3, dMinU, dMinV);
1864 IntTools_SurfaceRangeLocalizeData& aSurfaceData = myContext->SurfaceData(mySurface.Face());
1865 aSurfaceData.RemoveRangeOutAll();
1866 aSurfaceData.ClearGrid();
1869 Standard_Boolean bFBoxFound = aSurfaceData.FindBox(aSurfaceRange, FBox);
1871 if(mySurface.GetType() == GeomAbs_BSplineSurface) {
1872 Handle(Geom_BSplineSurface) aSurfBspl = Handle(Geom_BSplineSurface)::DownCast(myTrsfSurface);
1874 ComputeGridPoints(aSurfBspl, myUMinParameter, myUMaxParameter,
1875 myVMinParameter, myVMaxParameter, myFaceTolerance,
1879 FBox = GetSurfaceBox(aSurfBspl, myUMinParameter, myUMaxParameter,
1880 myVMinParameter, myVMaxParameter, myCriteria,
1882 aSurfaceData.AddBox(aSurfaceRange, FBox);
1885 } else if(!bFBoxFound) {
1887 BndLib_AddSurface::Add(mySurface, myUMinParameter, myUMaxParameter, myVMinParameter, myVMaxParameter, myFaceTolerance, FBox);
1888 aSurfaceData.AddBox(aSurfaceRange, FBox);
1893 BndLib_Add3dCurve::Add(myCurve.Trim(myFirstParameter, myLastParameter, Precision::PConfusion())->Curve(), myBeanTolerance, EBox);
1895 if(EBox.IsOut(FBox)) {
1896 for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
1897 myRangeManager.SetFlag(i, 1);
1899 aSurfaceData.ClearGrid();
1901 return Standard_True;
1904 IntTools_ListOfCurveRangeSample aListCurveRange;
1905 IntTools_ListOfSurfaceRangeSample aListSurfaceRange;
1907 IntTools_CurveRangeSample aCurveRange(0);
1908 aCurveRange.SetDepth(0);
1909 Standard_Integer nbSampleC = 3;
1910 Standard_Integer nbSampleU = aSurfaceData.GetNbSampleU();
1911 Standard_Integer nbSampleV = aSurfaceData.GetNbSampleV();
1912 Standard_Real dMinC = 10. * myCurveResolution;
1913 IntTools_ListOfCurveRangeSample aListOut;
1916 Standard_Boolean bAllowSamplingC = Standard_True;
1917 Standard_Boolean bAllowSamplingU = Standard_True;
1918 Standard_Boolean bAllowSamplingV = Standard_True;
1919 IntTools_CurveRangeLocalizeData aCurveDataTmp(nbSampleC, dMinC);
1920 IntTools_SurfaceRangeLocalizeData aSurfaceDataTmp(nbSampleU, nbSampleV, dMinU, dMinV);
1922 CheckSampling(aCurveRange, aSurfaceRange, aCurveDataTmp, aSurfaceDataTmp,
1923 myLastParameter - myFirstParameter,
1924 myUMaxParameter - myUMinParameter,
1925 myVMaxParameter - myVMinParameter,
1926 bAllowSamplingC, bAllowSamplingU, bAllowSamplingV);
1930 IntTools_CurveRangeLocalizeData aCurveData(nbSampleC, dMinC);
1932 aCurveData.AddBox(aCurveRange, EBox);
1934 if(!LocalizeSolutions(aCurveRange, EBox, aSurfaceRange, FBox,
1935 aCurveData, aSurfaceData,
1936 aListCurveRange, aListSurfaceRange)) {
1937 aSurfaceData.ClearGrid();
1939 return Standard_False;
1942 IntTools_ListOfCurveRangeSample aListCurveRangeSort;
1943 IntTools_ListOfSurfaceRangeSample aListSurfaceRangeSort;
1945 MergeSolutions(aListCurveRange, aListSurfaceRange, aListCurveRangeSort, aListSurfaceRangeSort);
1947 IntTools_ListIteratorOfListOfCurveRangeSample anItC(aListCurveRangeSort);
1948 IntTools_ListIteratorOfListOfSurfaceRangeSample anItS(aListSurfaceRangeSort);
1949 IntTools_SurfaceRangeSample aRangeSPrev;
1951 Extrema_GenExtCS anExtremaGen;
1953 for(; anItC.More() && anItS.More(); anItC.Next(), anItS.Next()) {
1955 IntTools_Range aRangeC(myFirstParameter, myLastParameter);
1958 aRangeC = anItC.Value().GetRange(myFirstParameter, myLastParameter, nbSampleC);
1960 IntTools_Range aRangeU(myUMinParameter, myUMaxParameter);
1963 aRangeU = anItS.Value().GetRangeU(myUMinParameter, myUMaxParameter, nbSampleU);
1965 IntTools_Range aRangeV(myVMinParameter, myVMaxParameter);
1968 aRangeV = anItS.Value().GetRangeV(myVMinParameter, myVMaxParameter, nbSampleV);
1970 Standard_Real anarg1 = aRangeC.First(), anarg2 = aRangeC.Last();
1972 Standard_Boolean bFound = Standard_False;
1974 Standard_Integer nMinIndex = myRangeManager.Length();
1975 Standard_Integer nMaxIndex = -1;
1976 const TColStd_SequenceOfInteger& anInds1 = myRangeManager.GetIndices(anarg1);
1977 Standard_Integer indIt = 1;
1979 for(indIt = 1 ; indIt <= anInds1.Length(); indIt++) {
1980 Standard_Integer nIndex = anInds1.Value(indIt);
1981 nMinIndex = (nMinIndex > nIndex) ? nIndex : nMinIndex;
1982 nMaxIndex = (nMaxIndex < nIndex) ? nIndex : nMaxIndex;
1985 for(indIt = nMinIndex ; indIt <= nMaxIndex; indIt++) {
1986 if(myRangeManager.Flag(indIt) == 2) {
1987 bFound = Standard_True;
1994 nMinIndex = (nMaxIndex >= 0) ? nMaxIndex : nMinIndex;
1995 const TColStd_SequenceOfInteger& anInds2 = myRangeManager.GetIndices(anarg2);
1997 for(indIt = 1 ; indIt <= anInds2.Length(); indIt++) {
1998 Standard_Integer nIndex = anInds2.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;
2013 Standard_Real parUF = aRangeU.First(), parUL = aRangeU.Last();
2014 Standard_Real parVF = aRangeV.First(), parVL = aRangeV.Last();
2016 if(aRangeSPrev.IsEqual(anItS.Value())) {
2017 anExtremaGen.Perform(myCurve, 10, anarg1, anarg2, Tol);
2020 anExtremaGen.Initialize(mySurface, 10, 10, parUF, parUL, parVF, parVL, Tol);
2021 anExtremaGen.Perform(myCurve, 10, anarg1, anarg2, Tol);
2024 if(anExtremaGen.IsDone() && (anExtremaGen.NbExt() > 0)) {
2026 for(Standard_Integer j = 1 ; j <= anExtremaGen.NbExt(); j++) {
2028 if(anExtremaGen.SquareDistance(j) < myCriteria * myCriteria) {
2032 p1 = anExtremaGen.PointOnCurve(j);
2033 p2 = anExtremaGen.PointOnSurface(j);
2034 Standard_Real U, V, T;
2038 if (myCurve.IsPeriodic())
2039 T = ElCLib::InPeriod(T, anarg1, anarg1 + myCurve.Period());
2040 if (mySurface.IsUPeriodic())
2041 U = ElCLib::InPeriod(U, parUF, parUF + mySurface.UPeriod());
2042 if (mySurface.IsVPeriodic())
2043 V = ElCLib::InPeriod(V, parVF, parVF + mySurface.VPeriod());
2045 //To avoid occasional going out of boundaries because of numerical
2047 if(U < myUMinParameter) U = myUMinParameter;
2048 if(U > myUMaxParameter) U = myUMaxParameter;
2049 if(V < myVMinParameter) V = myVMinParameter;
2050 if(V > myVMaxParameter) V = myVMaxParameter;
2052 Standard_Integer aNbRanges = myRangeManager.Length();
2053 ComputeRangeFromStartPoint(Standard_False, T, U, V);
2054 ComputeRangeFromStartPoint(Standard_True, T, U, V);
2056 if(aNbRanges == myRangeManager.Length()) {
2057 SetEmptyResultRange(T, myRangeManager);
2063 myRangeManager.InsertRange(anarg1, anarg2, 0);
2066 aRangeSPrev = anItS.Value();
2070 aCurveData.ListRangeOut(aListOut);
2074 if(bAllowSamplingC) {
2075 IntTools_ListIteratorOfListOfCurveRangeSample anItC(aListOut);
2077 for(; anItC.More(); anItC.Next()) {
2078 IntTools_Range aRangeC =anItC.Value().GetRange(myFirstParameter, myLastParameter, nbSampleC);
2079 myRangeManager.InsertRange(aRangeC.First(), aRangeC.Last(), 1);
2082 ComputeNearRangeBoundaries();
2084 aSurfaceData.ClearGrid();
2086 return Standard_True;
2089 // ======================================================================================================================
2090 // function: TestComputeCoinside
2092 // ======================================================================================================================
2093 Standard_Boolean IntTools_BeanFaceIntersector::TestComputeCoinside()
2095 Standard_Real cfp = myFirstParameter, clp = myLastParameter;
2096 const Standard_Integer nbSeg = 23;
2097 Standard_Real cdp = (clp - cfp) / (Standard_Real )nbSeg;
2099 Standard_Integer i = 0;
2103 if(Distance(cfp, U, V) > myCriteria)
2104 return Standard_False;
2107 ComputeRangeFromStartPoint(Standard_True, cfp, U, V);
2110 Standard_Integer aFoundIndex = myRangeManager.GetIndex(clp, Standard_False );
2112 if(aFoundIndex != 0) {
2113 if(myRangeManager.Flag(aFoundIndex) == 2)
2114 return Standard_True;
2117 if(Distance(clp, U, V) > myCriteria)
2118 return Standard_False;
2121 ComputeRangeFromStartPoint(Standard_False, clp, U, V);
2124 for(i = 1; i < nbSeg; i++) {
2125 Standard_Real aPar = (cfp+((Standard_Real)i)*cdp);
2127 if(Distance(aPar, U, V) > myCriteria)
2128 return Standard_False;
2130 Standard_Integer aNbRanges = myRangeManager.Length();
2131 ComputeRangeFromStartPoint(Standard_False, aPar, U, V);
2132 ComputeRangeFromStartPoint(Standard_True, aPar, U, V);
2134 if(aNbRanges == myRangeManager.Length()) {
2135 SetEmptyResultRange(aPar, myRangeManager);
2139 return Standard_True;
2142 // Modified by skv - Wed Nov 2 15:21:11 2005 Optimization Begin
2143 // ---------------------------------------------------------------------------------
2144 // static function: GetSurfaceBox
2146 // ---------------------------------------------------------------------------------
2147 Bnd_Box GetSurfaceBox(const Handle(Geom_BSplineSurface) &theSurf,
2148 const Standard_Real theFirstU,
2149 const Standard_Real theLastU,
2150 const Standard_Real theFirstV,
2151 const Standard_Real theLastV,
2152 const Standard_Real theTolerance,
2153 IntTools_SurfaceRangeLocalizeData &theSurfaceData)
2157 BuildBox(theSurf, theFirstU, theLastU, theFirstV, theLastV,
2158 theSurfaceData, aTotalBox);
2160 aTotalBox.Enlarge(theTolerance);
2165 // ---------------------------------------------------------------------------------
2166 // static function: ComputeGridPoints
2168 // ---------------------------------------------------------------------------------
2169 void ComputeGridPoints
2170 (const Handle(Geom_BSplineSurface) &theSurf,
2171 const Standard_Real theFirstU,
2172 const Standard_Real theLastU,
2173 const Standard_Real theFirstV,
2174 const Standard_Real theLastV,
2175 const Standard_Real theTolerance,
2176 IntTools_SurfaceRangeLocalizeData &theSurfaceData)
2181 Standard_Integer aNbSamples[2] = { theSurf->UDegree(),
2182 theSurf->VDegree() };
2183 Standard_Integer aNbKnots[2] = { theSurf->NbUKnots(),
2184 theSurf->NbVKnots() };
2185 TColStd_Array1OfReal aKnotsU(1, aNbKnots[0]);
2186 TColStd_Array1OfReal aKnotsV(1, aNbKnots[1]);
2188 theSurf->UKnots(aKnotsU);
2189 theSurf->VKnots(aKnotsV);
2191 Standard_Integer iLmI;
2192 Standard_Integer iMin[2] = { -1, -1 };
2193 Standard_Integer iMax[2] = { -1, -1 };
2194 Standard_Integer aNbGridPnts[2];
2195 Standard_Real aFPar[2] = { theFirstU, theFirstV};
2196 Standard_Real aLPar[2] = { theLastU, theLastV};
2197 Standard_Real aFpTol[2] = { aFPar[0] + theTolerance,
2198 aFPar[1] + theTolerance };
2199 Standard_Real aFmTol[2] = { aFPar[0] - theTolerance,
2200 aFPar[1] - theTolerance };
2201 Standard_Real aLpTol[2] = { aLPar[0] + theTolerance,
2202 aLPar[1] + theTolerance };
2203 Standard_Real aLmTol[2] = { aLPar[0] - theTolerance,
2204 aLPar[1] - theTolerance };
2207 // Compute number of U and V grid points.
2208 for (j = 0; j < 2; j++) {
2209 const TColStd_Array1OfReal &aKnots = (j == 0) ? aKnotsU : aKnotsV;
2211 for (i = 1; i <= aNbKnots[j] && (iMin[j] == -1 || iMax[j] == -1); i++) {
2212 if (iMin[j] == -1 && aFpTol[j] < aKnots.Value(i))
2215 iLmI = aNbKnots[j] - i + 1;
2217 if (iMax[j] == -1 && aLmTol[j] > aKnots.Value(iLmI))
2221 // If indices are not found, return.
2222 //if (iMin[j] == -1 || iMax[j] == -1)
2228 iMax[j] = aNbKnots[j];
2233 if (iMax[j] > aNbKnots[j])
2234 iMax[j] = aNbKnots[j];
2236 if (iMax[j] < iMin[j])
2239 if (iMax[j] == iMin[j]) {
2244 if (iMax[j] > aNbKnots[j])
2245 iMax[j] = aNbKnots[j];
2249 aNbGridPnts[j] = (iMax[j] - iMin[j])*aNbSamples[j] + 1;
2251 // Setting the number of grid points.
2253 theSurfaceData.SetRangeUGrid(aNbGridPnts[j]);
2255 theSurfaceData.SetRangeVGrid(aNbGridPnts[j]);
2257 // Setting the first and last parameters.
2258 Standard_Integer iAbs = 1;
2259 Standard_Real aMinPar;
2260 Standard_Real aMaxPar = (j == 0) ? theLastU : theLastV;
2262 for (i = iMin[j]; i < iMax[j]; i++) {
2263 // Get the first parameter.
2266 if (aFmTol[j] > aKnots.Value(iMin[j]))
2269 aMinPar = aKnots.Value(iMin[j]);
2271 aMinPar = aKnots.Value(i);
2274 // Get the last parameter.
2275 if (i == iMax[j] - 1) {
2277 if (aLpTol[j] < aKnots.Value(iMax[j]))
2280 aMaxPar = aKnots.Value(iMax[j]);
2282 aMaxPar = aKnots.Value(i + 1);
2285 // Compute grid parameters.
2286 Standard_Real aDelta = (aMaxPar - aMinPar)/aNbSamples[j];
2288 for (k = 0; k < aNbSamples[j]; k++, aMinPar += aDelta) {
2290 theSurfaceData.SetUParam(iAbs++, aMinPar);
2292 theSurfaceData.SetVParam(iAbs++, aMinPar);
2296 // Add the last parameter
2298 theSurfaceData.SetUParam(iAbs++, aMaxPar);
2300 theSurfaceData.SetVParam(iAbs++, aMaxPar);
2303 // Compute of grid points.
2305 Standard_Real aParU;
2306 Standard_Real aParV;
2308 for (i = 1; i <= aNbGridPnts[0]; i++) {
2309 aParU = theSurfaceData.GetUParam(i);
2311 for (j = 1; j <= aNbGridPnts[1]; j++) {
2312 aParV = theSurfaceData.GetVParam(j);
2314 theSurf->D0(aParU, aParV, aPnt);
2315 theSurfaceData.SetGridPoint(i, j, aPnt);
2319 // Compute deflection.
2320 Standard_Real aDef = 0.;
2321 // Standard_Real aDefLin;
2322 // Standard_Real aParMid;
2323 // Standard_Real aParConst;
2324 // Standard_Real aDistPP;
2329 // // Compute DU deflection.
2330 // for (i = 1; i < aNbGridPnts[0]; i++) {
2331 // aParMid = 0.5*(theSurfaceData.GetUParam(i + 1) +
2332 // theSurfaceData.GetUParam(i));
2334 // for (j = 1; j <= aNbGridPnts[1]; j++) {
2335 // const gp_Pnt &thePnt1 = theSurfaceData.GetGridPoint(i, j);
2336 // const gp_Pnt &thePnt2 = theSurfaceData.GetGridPoint(i + 1, j);
2338 // aVec.SetXYZ(thePnt2.XYZ().Subtracted(thePnt1.XYZ()));
2339 // aDistPP = aVec.Magnitude();
2341 // if (aDistPP > theTolerance) {
2342 // // Computation of a distance of a middle point from the line P1 - P2.
2343 // aParConst = theSurfaceData.GetVParam(j);
2344 // theSurf->D0(aParMid, aParConst, aPntMid);
2345 // aCoord = aPntMid.XYZ();
2346 // aCoord.Subtract(thePnt1.XYZ());
2347 // aCoord.Cross (aVec.XYZ());
2348 // aCoord.Divide(aDistPP);
2349 // aDefLin = aCoord.Modulus();
2351 // if (aDefLin > aDef)
2357 // // Compute DV deflection.
2358 // for (j = 1; j < aNbGridPnts[1]; j++) {
2359 // aParMid = 0.5*(theSurfaceData.GetVParam(j + 1) +
2360 // theSurfaceData.GetVParam(j));
2362 // for (i = 1; i <= aNbGridPnts[0]; i++) {
2363 // const gp_Pnt &thePnt1 = theSurfaceData.GetGridPoint(i, j);
2364 // const gp_Pnt &thePnt2 = theSurfaceData.GetGridPoint(i, j + 1);
2366 // aVec.SetXYZ(thePnt2.XYZ().Subtracted(thePnt1.XYZ()));
2367 // aDistPP = aVec.Magnitude();
2369 // if (aDistPP > theTolerance) {
2370 // // Computation of a distance of a middle point from the line P1 - P2.
2371 // aParConst = theSurfaceData.GetUParam(i);
2372 // theSurf->D0(aParConst, aParMid, aPntMid);
2373 // aCoord = aPntMid.XYZ();
2374 // aCoord.Subtract(thePnt1.XYZ());
2375 // aCoord.Cross (aVec.XYZ());
2376 // aCoord.Divide(aDistPP);
2377 // aDefLin = aCoord.Modulus();
2379 // if (aDefLin > aDef)
2385 if (theTolerance > aDef)
2386 aDef = theTolerance;
2389 theSurfaceData.SetGridDeflection(aDef);
2392 // ---------------------------------------------------------------------------------
2393 // static function: BuildBox
2394 // purpose: Compute bounding box.
2395 // ---------------------------------------------------------------------------------
2396 void BuildBox(const Handle(Geom_BSplineSurface) &theSurf,
2397 const Standard_Real theFirstU,
2398 const Standard_Real theLastU,
2399 const Standard_Real theFirstV,
2400 const Standard_Real theLastV,
2401 IntTools_SurfaceRangeLocalizeData &theSurfaceData,
2406 Standard_Integer aNbUPnts;
2407 Standard_Integer aNbVPnts;
2408 Standard_Real aParam;
2411 theSurfaceData.SetFrame(theFirstU, theLastU, theFirstV, theLastV);
2412 aNbUPnts = theSurfaceData.GetNBUPointsInFrame();
2413 aNbVPnts = theSurfaceData.GetNBVPointsInFrame();
2415 // Add corner points.
2416 theSurf->D0(theFirstU, theFirstV, aPnt);
2418 theSurf->D0(theLastU, theFirstV, aPnt);
2420 theSurf->D0(theFirstU, theLastV, aPnt);
2422 theSurf->D0(theLastU, theLastV, aPnt);
2425 for (i = 1; i <= aNbUPnts; i++) {
2426 // Add top and bottom points.
2427 aParam = theSurfaceData.GetUParamInFrame(i);
2428 theSurf->D0(aParam, theFirstV, aPnt);
2430 theSurf->D0(aParam, theLastV, aPnt);
2433 // Add internal points.
2434 for (j = 1; j <= aNbVPnts; j++) {
2435 const gp_Pnt &aGridPnt = theSurfaceData.GetPointInFrame(i, j);
2437 theBox.Add(aGridPnt);
2441 // Add left and right points.
2442 for (j = 1; j <= aNbVPnts; j++) {
2443 aParam = theSurfaceData.GetVParamInFrame(j);
2444 theSurf->D0(theFirstU, aParam, aPnt);
2446 theSurf->D0(theLastU, aParam, aPnt);
2450 theBox.Enlarge(theSurfaceData.GetGridDeflection());
2452 // Modified by skv - Wed Nov 2 15:21:11 2005 Optimization End
2455 // ---------------------------------------------------------------------------------
2456 // static function: MergeSolutions
2458 // ---------------------------------------------------------------------------------
2459 static void MergeSolutions(const IntTools_ListOfCurveRangeSample& theListCurveRange,
2460 const IntTools_ListOfSurfaceRangeSample& theListSurfaceRange,
2461 IntTools_ListOfCurveRangeSample& theListCurveRangeSort,
2462 IntTools_ListOfSurfaceRangeSample& theListSurfaceRangeSort) {
2464 IntTools_ListIteratorOfListOfCurveRangeSample anItC2;
2465 IntTools_ListIteratorOfListOfSurfaceRangeSample anItS1(theListSurfaceRange), anItS2;
2466 IntTools_MapOfSurfaceSample aMapToAvoid;
2468 for(; anItS1.More(); anItS1.Next()) {
2469 const IntTools_SurfaceRangeSample& aRangeS = anItS1.Value();
2471 if(aMapToAvoid.Contains(aRangeS))
2473 aMapToAvoid.Add(aRangeS);
2475 anItC2.Initialize(theListCurveRange);
2476 anItS2.Initialize(theListSurfaceRange);
2478 for(; anItS2.More() && anItC2.More(); anItS2.Next(), anItC2.Next()) {
2479 if(aRangeS.IsEqual(anItS2.Value())) {
2480 theListCurveRangeSort.Append(anItC2.Value());
2481 theListSurfaceRangeSort.Append(anItS2.Value());
2487 // ---------------------------------------------------------------------------------
2488 // static function: CheckSampling
2490 // ---------------------------------------------------------------------------------
2491 static void CheckSampling(const IntTools_CurveRangeSample& theCurveRange,
2492 const IntTools_SurfaceRangeSample& theSurfaceRange,
2493 const IntTools_CurveRangeLocalizeData& theCurveData,
2494 const IntTools_SurfaceRangeLocalizeData& theSurfaceData,
2495 const Standard_Real DiffC,
2496 const Standard_Real DiffU,
2497 const Standard_Real DiffV,
2498 Standard_Boolean& bAllowSamplingC,
2499 Standard_Boolean& bAllowSamplingU,
2500 Standard_Boolean& bAllowSamplingV) {
2502 const Standard_Real dLimit = 1000;
2503 bAllowSamplingC = Standard_True;
2504 bAllowSamplingU = Standard_True;
2505 bAllowSamplingV = Standard_True;
2508 if((pow((Standard_Real)theCurveData.GetNbSample(), (Standard_Real )(theCurveRange.GetDepth() + 1)) > dLimit) ||
2509 ((DiffC / theCurveData.GetNbSample()) < theCurveData.GetMinRange())) {
2510 bAllowSamplingC = Standard_False;
2513 if((pow((Standard_Real )theSurfaceData.GetNbSampleU(), (Standard_Real )(theSurfaceRange.GetDepthU() + 1)) > dLimit) ||
2514 ((DiffU / theSurfaceData.GetNbSampleU()) < theSurfaceData.GetMinRangeU())) {
2515 bAllowSamplingU = Standard_False;
2519 if((pow((Standard_Real )theSurfaceData.GetNbSampleV(), (Standard_Real )(theSurfaceRange.GetDepthV() + 1)) > dLimit) ||
2520 ((DiffV / theSurfaceData.GetNbSampleV()) < theSurfaceData.GetMinRangeV())) {
2521 bAllowSamplingV = Standard_False;