1 // Created on: 2001-02-26
2 // Created by: Peter KURNEV
3 // Copyright (c) 2001-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
17 #include <Bnd_Box.hxx>
18 #include <BndLib_AddSurface.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAdaptor_Surface.hxx>
21 #include <Extrema_ExtCS.hxx>
22 #include <Extrema_POnCurv.hxx>
23 #include <Extrema_POnSurf.hxx>
24 #include <Geom_Curve.hxx>
25 #include <Geom_Surface.hxx>
26 #include <GeomAdaptor_Curve.hxx>
27 #include <GeomAdaptor_HCurve.hxx>
28 #include <GeomAdaptor_HSurface.hxx>
29 #include <GeomAdaptor_Surface.hxx>
30 #include <GeomAPI_ProjectPointOnSurf.hxx>
32 #include <gp_Circ.hxx>
33 #include <gp_Cone.hxx>
34 #include <gp_Cylinder.hxx>
38 #include <gp_Torus.hxx>
39 #include <IntCurveSurface_HInter.hxx>
40 #include <IntCurveSurface_IntersectionPoint.hxx>
41 #include <IntTools.hxx>
42 #include <IntTools_Array1OfRange.hxx>
43 #include <IntTools_BeanFaceIntersector.hxx>
44 #include <IntTools_CArray1OfInteger.hxx>
45 #include <IntTools_CArray1OfReal.hxx>
46 #include <IntTools_CommonPrt.hxx>
47 #include <IntTools_Context.hxx>
48 #include <IntTools_EdgeFace.hxx>
49 #include <IntTools_Range.hxx>
50 #include <IntTools_Root.hxx>
51 #include <IntTools_Tools.hxx>
52 #include <Precision.hxx>
53 #include <TopoDS_Edge.hxx>
54 #include <TopoDS_Face.hxx>
58 Standard_Boolean IsCoplanar (const BRepAdaptor_Curve& ,
59 const BRepAdaptor_Surface& );
61 Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve ,
62 const BRepAdaptor_Surface& aSurface,
63 const Standard_Real aCriteria);
65 Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret,
66 const BRepAdaptor_Curve& aCurve ,
67 const BRepAdaptor_Surface& aSurface);
69 //=======================================================================
70 //function : IntTools_EdgeFace::IntTools_EdgeFace
72 //=======================================================================
73 IntTools_EdgeFace::IntTools_EdgeFace()
81 myIsDone=Standard_False;
83 myParallel=Standard_False;
86 //=======================================================================
87 //function : SetContext
89 //=======================================================================
90 void IntTools_EdgeFace::SetContext(const Handle(IntTools_Context)& theContext)
92 myContext = theContext;
95 //=======================================================================
98 //=======================================================================
99 const Handle(IntTools_Context)& IntTools_EdgeFace::Context()const
103 //=======================================================================
106 //=======================================================================
107 void IntTools_EdgeFace::SetEdge(const TopoDS_Edge& anEdge)
111 //=======================================================================
114 //=======================================================================
115 void IntTools_EdgeFace::SetFace(const TopoDS_Face& aFace)
119 //=======================================================================
122 //=======================================================================
123 void IntTools_EdgeFace::SetTolE(const Standard_Real aTol)
127 //=======================================================================
130 //=======================================================================
131 void IntTools_EdgeFace::SetTolF(const Standard_Real aTol)
135 //=======================================================================
138 //=======================================================================
139 const TopoDS_Edge& IntTools_EdgeFace::Edge()const
143 //=======================================================================
146 //=======================================================================
147 const TopoDS_Face& IntTools_EdgeFace::Face()const
151 //=======================================================================
154 //=======================================================================
155 Standard_Real IntTools_EdgeFace::TolE()const
159 //=======================================================================
162 //=======================================================================
163 Standard_Real IntTools_EdgeFace::TolF()const
167 //=======================================================================
168 //function : SetDiscretize
170 //=======================================================================
171 void IntTools_EdgeFace::SetDiscretize(const Standard_Integer aDiscret)
175 //=======================================================================
176 //function : SetDeflection
178 //=======================================================================
179 void IntTools_EdgeFace::SetDeflection(const Standard_Real aDefl)
183 //=======================================================================
184 //function : SetEpsilonT
186 //=======================================================================
187 void IntTools_EdgeFace::SetEpsilonT(const Standard_Real anEpsT)
191 //=======================================================================
192 //function : SetEpsilonNull
194 //=======================================================================
195 void IntTools_EdgeFace::SetEpsilonNull(const Standard_Real anEpsNull)
200 //=======================================================================
201 //function : SetRange
203 //=======================================================================
204 void IntTools_EdgeFace::SetRange(const Standard_Real aFirst,
205 const Standard_Real aLast)
207 myRange.SetFirst (aFirst);
208 myRange.SetLast (aLast);
211 //=======================================================================
212 //function : SetRange
214 //=======================================================================
215 void IntTools_EdgeFace::SetRange(const IntTools_Range& aRange)
217 myRange.SetFirst (aRange.First());
218 myRange.SetLast (aRange.Last());
220 //=======================================================================
223 //=======================================================================
224 Standard_Boolean IntTools_EdgeFace::IsDone()const
228 //=======================================================================
229 //function : ErrorStatus
231 //=======================================================================
232 Standard_Integer IntTools_EdgeFace::ErrorStatus()const
234 return myErrorStatus;
236 //=======================================================================
237 //function : CommonParts
239 //=======================================================================
240 const IntTools_SequenceOfCommonPrts& IntTools_EdgeFace::CommonParts() const
242 return mySeqOfCommonPrts;
244 //=======================================================================
247 //=======================================================================
248 const IntTools_Range& IntTools_EdgeFace::Range() const
253 //=======================================================================
254 //function : CheckData
256 //=======================================================================
257 void IntTools_EdgeFace::CheckData()
259 if (BRep_Tool::Degenerated(myEdge)) {
262 if (!BRep_Tool::IsGeometric(myEdge)) {
266 //=======================================================================
269 //=======================================================================
270 void IntTools_EdgeFace::Prepare()
272 Standard_Integer pri;
273 IntTools_CArray1OfReal aPars;
276 // 1.Prepare Curve's data and Surface's data
277 myC.Initialize(myEdge);
278 GeomAbs_CurveType aCurveType;
279 aCurveType=myC.GetType();
281 // 2.Prepare myCriteria
282 if (aCurveType==GeomAbs_BSplineCurve||
283 aCurveType==GeomAbs_BezierCurve) {
284 myCriteria=1.5*myTolE+myTolF;
287 myCriteria=myTolE+myTolF;
289 // 2.a myTmin, myTmax
290 myTmin=myRange.First();
291 myTmax=myRange.Last();
293 myS.Initialize (myFace,Standard_True);
294 myFClass2d.Init(myFace, 1.e-6);
296 // 2.c Prepare adaptive myDiscret
297 myDiscret=AdaptiveDiscret(myDiscret, myC, myS);
301 pri = IntTools::PrepareArgs(myC, myTmax, myTmin,
302 myDiscret, myDeflection, aPars);
309 Standard_Integer i, iProj, aNb, aNbProj, ind0, ind1;
310 Standard_Real t0, t1, tRoot;
313 // Table of Projection's function values
315 IntTools_CArray1OfInteger anArrProjectability;
316 anArrProjectability.Resize(aNb);
318 for (iProj=0, i=0; i<aNb; i++) {
320 aNbProj=IsProjectable (t0);
322 anArrProjectability(i)=0;
324 anArrProjectability(i)=1;
336 // Projectable Ranges
337 IntTools_Range aRange;
339 ind0=anArrProjectability(0);
345 for(i=1; i<aNb; i++) {
346 ind1=anArrProjectability(i);
353 myProjectableRanges.Append(aRange);
356 FindProjectableRoot(t0, t1, ind0, ind1, tRoot);
357 aRange.SetFirst(tRoot);
359 myProjectableRanges.Append(aRange);
363 FindProjectableRoot(t0, t1, ind0, ind1, tRoot);
364 aRange.SetLast(tRoot);
365 myProjectableRanges.Append(aRange);
372 FindProjectableRoot(t0, t1, ind0, ind1, tRoot);
375 aRange.SetLast(tRoot);
376 myProjectableRanges.Append(aRange);
379 aRange.SetFirst(tRoot);
381 } // if (ind0 != ind1)
383 } // for(i=1; i<aNb; i++) {
386 //=======================================================================
387 //function : FindProjectableRoot
389 //=======================================================================
390 void IntTools_EdgeFace::FindProjectableRoot (const Standard_Real tt1,
391 const Standard_Real tt2,
392 const Standard_Integer ff1,
393 const Standard_Integer /*ff2*/,
394 Standard_Real& tRoot)
396 Standard_Real tm, t1, t2, aEpsT;
397 Standard_Integer anIsProj1, anIsProjm;
398 aEpsT = 0.5 * myEpsT;
400 // Root is inside [tt1, tt2]
407 if (fabs(t1 - t2) < aEpsT)
409 tRoot = (anIsProj1) ? t1 : t2;
412 tm = 0.5 * (t1 + t2);
413 anIsProjm = IsProjectable(tm);
415 if (anIsProjm != anIsProj1)
422 anIsProj1 = anIsProjm;
426 //=======================================================================
427 //function : IsProjectable
429 //=======================================================================
430 Standard_Boolean IntTools_EdgeFace::IsProjectable
431 (const Standard_Real aT) const
433 Standard_Boolean bFlag;
437 bFlag=myContext->IsValidPointForFace(aPC, myFace, myCriteria);
441 //=======================================================================
442 //function : DistanceFunction
444 //=======================================================================
445 Standard_Real IntTools_EdgeFace::DistanceFunction
446 (const Standard_Real t)
454 Standard_Boolean bIsEqDistance;
456 bIsEqDistance= IntTools_EdgeFace::IsEqDistance(P, myS, 1.e-7, aD);
463 Standard_Boolean bFlag = Standard_False;
465 GeomAPI_ProjectPointOnSurf& aLocProj = myContext->ProjPS(myFace);
467 bFlag = aLocProj.IsDone();
470 aD = aLocProj.LowerDistance();
480 // aD=aProjector.LowerDistance();
486 //=======================================================================
487 //function : IsEqDistance
489 //=======================================================================
490 Standard_Boolean IntTools_EdgeFace::IsEqDistance
492 const BRepAdaptor_Surface& aBAS,
493 const Standard_Real aTol,
496 Standard_Boolean bRetFlag=Standard_True;
498 GeomAbs_SurfaceType aSurfType=aBAS.GetType();
500 if (aSurfType==GeomAbs_Cylinder) {
501 gp_Cylinder aCyl=aBAS.Cylinder();
502 const gp_Ax1& anAx1 =aCyl.Axis();
503 gp_Lin aLinAxis(anAx1);
504 Standard_Real aDC, aRadius=aCyl.Radius();
505 aDC=aLinAxis.Distance(aP);
512 if (aSurfType==GeomAbs_Cone) {
513 gp_Cone aCone=aBAS.Cone();
514 const gp_Ax1& anAx1 =aCone.Axis();
515 gp_Lin aLinAxis(anAx1);
516 Standard_Real aDC, aRadius, aDS, aSemiAngle;
517 aDC=aLinAxis.Distance(aP);
519 gp_Pnt anApex=aCone.Apex();
520 aSemiAngle=aCone.SemiAngle();
521 aDS=aP.Distance(anApex);
523 aRadius=aDS*tan(aSemiAngle);
529 if (aSurfType==GeomAbs_Torus) {
530 Standard_Real aMajorRadius, aMinorRadius, aDC;
532 gp_Torus aTorus=aBAS.Torus();
533 gp_Pnt aPLoc=aTorus.Location();
534 aMajorRadius=aTorus.MajorRadius();
536 aDC=fabs(aPLoc.Distance(aP)-aMajorRadius);
538 aMinorRadius=aTorus.MinorRadius();
546 //=======================================================================
547 //function : PrepareArgsFuncArrays
549 // myFuncArray and myArgsArray for the interval [ta, tb]
550 //=======================================================================
551 void IntTools_EdgeFace::PrepareArgsFuncArrays(const Standard_Real ta,
552 const Standard_Real tb)
554 IntTools_CArray1OfReal anArgs, aFunc;
555 Standard_Integer i, aNb, pri;
556 Standard_Real t, f, f1;
558 // Prepare values of arguments for the interval [ta, tb]
559 pri=IntTools::PrepareArgs (myC, tb, ta, myDiscret, myDeflection, anArgs);
573 // Prepare values of functions for the interval [ta, tb]
575 for (i=0; i<aNb; i++) {
577 f1=DistanceFunction(t);
580 if (myErrorStatus==11)
583 if (f1 < myEpsNull) {
589 // Add points where the derivative = 0
590 AddDerivativePoints(anArgs, aFunc);
594 //=======================================================================
597 // Auxiliary: comparator function for sorting ranges
598 bool IntTools_RangeComparator (const IntTools_Range& theLeft, const IntTools_Range& theRight)
600 return theLeft.First() < theRight.First();
604 //=======================================================================
605 //function : AddDerivativePoints
607 //=======================================================================
608 void IntTools_EdgeFace::AddDerivativePoints
609 (const IntTools_CArray1OfReal& t,
610 const IntTools_CArray1OfReal& f)
612 Standard_Integer i, j, n, k, nn=100;
613 Standard_Real fr, tr, tr1, dEpsNull=10.*myEpsNull;
614 IntTools_CArray1OfReal fd;
615 TColStd_SequenceOfReal aTSeq, aFSeq;
620 // Table of derivatives
621 Standard_Real dfx, tx, tx1, fx, fx1, dt=1.e-6;
626 fx1=DistanceFunction(tx1);
628 if (fx1 < myEpsNull) {
634 if (fabs(fd(0)) < dEpsNull){
640 for (i=1; i<k; i++) {
641 fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1));
642 if (fabs(fd(i)) < dEpsNull){
650 fx1=DistanceFunction(tx1);
652 if (fx1 < myEpsNull) {
658 if (fabs(fd(n-1)) < dEpsNull){
662 // Finding the range where the derivatives have different signs
663 // for neighbouring points
664 for (i=1; i<n; i++) {
665 Standard_Real fd1, fd2, t1, t2;
672 if (fabs(fd1) < myEpsNull) {
674 fr=DistanceFunction(tr);//fd1;
676 else if (fabs(fd2) < myEpsNull) {
678 fr=DistanceFunction(tr);
681 tr=FindSimpleRoot(2, t1, t2, fd1);
682 fr=DistanceFunction(tr);
688 } // end of for (i=1; i<n; i++)
690 // remove identical t, f
693 for (i=1; i<=aTSeq.Length(); i++) {
695 for (j=0; j<n; j++) {
697 if (fabs (tr1-tr) < myEpsT) {
706 // sorting args and funcs in increasing order
709 IntTools_Array1OfRange anArray1OfRange(1, k);
710 for (i=1; i<=n; i++) {
711 anArray1OfRange(i).SetFirst(t(i-1));
712 anArray1OfRange(i).SetLast (f(i-1));
714 for (i=1; i<=nn; i++) {
715 anArray1OfRange(n+i).SetFirst(aTSeq(i));
716 anArray1OfRange(n+i).SetLast (aFSeq(i));
719 std::sort (anArray1OfRange.begin(), anArray1OfRange.end(), IntTools_RangeComparator);
721 // filling the output arrays
722 myArgsArray.Resize(k);
723 myFuncArray.Resize(k);
724 for (i=1; i<=k; i++) {
725 myArgsArray(i-1)=anArray1OfRange(i).First();
726 myFuncArray(i-1)=anArray1OfRange(i).Last ();
731 myArgsArray.Resize(n);
732 myFuncArray.Resize(n);
733 for (i=0; i<n; i++) {
740 //=======================================================================
741 //function : DerivativeFunction
743 //=======================================================================
744 Standard_Real IntTools_EdgeFace::DerivativeFunction
745 (const Standard_Real t2)
747 Standard_Real t1, t3, aD1, aD2, aD3;
748 Standard_Real dt=1.e-9;
750 aD1=DistanceFunction(t1);
752 aD3=DistanceFunction(t3);
758 //=======================================================================
759 //function : FindSimpleRoot
760 //purpose : [private]
761 //=======================================================================
762 Standard_Real IntTools_EdgeFace::FindSimpleRoot
763 (const Standard_Integer IP,
764 const Standard_Real tA,
765 const Standard_Real tB,
766 const Standard_Real fA)
768 Standard_Real r, a, b, y, x0, s;
776 y=DistanceFunction(x0);
778 y=DerivativeFunction(x0);
780 if (fabs(b-a) < myEpsT || y==0.) {
797 //=======================================================================
798 //function : FindGoldRoot
799 //purpose : [private]
800 //=======================================================================
801 Standard_Real IntTools_EdgeFace::FindGoldRoot
802 (const Standard_Real tA,
803 const Standard_Real tB,
804 const Standard_Real coeff)
806 Standard_Real gs=0.61803399;
807 Standard_Real a, b, xp, xl, yp, yl;
813 yp=coeff*DistanceFunction(xp);
814 yl=coeff*DistanceFunction(xl);
819 if (fabs(b-a) < myEpsT) {
827 yp=coeff*DistanceFunction(xp);
835 yl=coeff*DistanceFunction(xl);
840 //=======================================================================
841 //function : MakeType
843 //=======================================================================
844 Standard_Integer IntTools_EdgeFace::MakeType
845 (IntTools_CommonPrt& aCommonPrt)
847 Standard_Real af1, al1;
848 Standard_Real df1, tm;
849 Standard_Boolean bAllNullFlag;
851 bAllNullFlag=aCommonPrt.AllNullFlag();
853 aCommonPrt.SetType(TopAbs_EDGE);
857 aCommonPrt.Range1(af1, al1);
863 df1=aPF.Distance(aPL);
864 Standard_Boolean isWholeRange = Standard_False;
866 if((Abs(af1 - myRange.First()) < myC.Resolution(myCriteria)) &&
867 (Abs(al1 - myRange.Last()) < myC.Resolution(myCriteria)))
868 isWholeRange = Standard_True;
871 if ((df1 > myCriteria * 2.) && isWholeRange) {
872 aCommonPrt.SetType(TopAbs_EDGE);
876 tm = (af1 + al1) * 0.5;
878 if(aPF.Distance(myC.Value(tm)) > myCriteria * 2.) {
879 aCommonPrt.SetType(TopAbs_EDGE);
884 if(!CheckTouch(aCommonPrt, tm)) {
885 tm = (af1 + al1) * 0.5;
887 aCommonPrt.SetType(TopAbs_VERTEX);
888 aCommonPrt.SetVertexParameter1(tm);
889 aCommonPrt.SetRange1 (af1, al1);
896 //=======================================================================
897 //function : IsIntersection
899 //=======================================================================
900 void IntTools_EdgeFace::IsIntersection (const Standard_Real ta,
901 const Standard_Real tb)
903 IntTools_CArray1OfReal anArgs, aFunc;
904 Standard_Integer i, aNb, aCnt=0;
906 Standard_Integer aCntIncreasing=1, aCntDecreasing=1;
907 Standard_Real t, f, f1;
909 // Prepare values of arguments for the interval [ta, tb]
910 IntTools::PrepareArgs (myC, tb, ta, myDiscret, myDeflection, anArgs);
914 for (i=0; i<aNb; i++) {
917 f1=DistanceFunction(t);
920 if (fabs(f1) < myEpsNull) {
927 if (aFunc(i)>aFunc(i-1)) {
930 if (aFunc(i)<aFunc(i-1)) {
938 myParallel=Standard_True;
942 FindDerivativeRoot(anArgs, aFunc);
946 if (!(myC.GetType()==GeomAbs_Line
948 myS.GetType()==GeomAbs_Cylinder)) {
949 if (aCntDecreasing==aNb) {
950 myPar1=anArgs(aNb-1);
951 myParallel=Standard_False;
953 if (aCntIncreasing==aNb) {
955 myParallel=Standard_False;
963 //=======================================================================
964 //function : FindDerivativeRoot
966 //=======================================================================
967 void IntTools_EdgeFace::FindDerivativeRoot
968 (const IntTools_CArray1OfReal& t,
969 const IntTools_CArray1OfReal& f)
971 Standard_Integer i, n, k;
973 IntTools_CArray1OfReal fd;
974 TColStd_SequenceOfReal aTSeq, aFSeq;
977 myParallel=Standard_True;
982 // Table of derivatives
983 fd(0)=(f(1)-f(0))/(t(1)-t(0));
984 if (fabs(fd(0)) < myEpsNull) {
989 for (i=1; i<k; i++) {
990 fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1));
991 if (fabs(fd(i)) < myEpsNull) {
996 fd(n-1)=(f(n-1)-f(n-2))/(t(n-1)-t(n-2));
997 if (fabs(fd(n-1)) < myEpsNull) {
1001 // Finding the range where the derivatives have different signs
1002 // for neighbouring points
1003 for (i=1; i<n; i++) {
1004 Standard_Real fd1, fd2, t1, t2, fabsfd1, fabsfd2;
1005 Standard_Boolean bF1, bF2;
1012 bF1=fabsfd1 < myEpsNull;
1015 bF2=fabsfd2 < myEpsNull;
1018 tr=FindSimpleRoot(2, t1, t2, fd1);
1019 DistanceFunction(tr);
1021 myParallel=Standard_False;
1028 myParallel=Standard_False;
1035 myParallel=Standard_False;
1041 //=======================================================================
1042 //function : RemoveIdenticalRoots
1044 //=======================================================================
1045 void IntTools_EdgeFace::RemoveIdenticalRoots()
1047 Standard_Integer aNbRoots, j, k;
1049 aNbRoots=mySequenceOfRoots.Length();
1050 for (j=1; j<=aNbRoots; j++) {
1051 const IntTools_Root& aRj=mySequenceOfRoots(j);
1052 for (k=j+1; k<=aNbRoots; k++) {
1053 const IntTools_Root& aRk=mySequenceOfRoots(k);
1055 Standard_Real aTj, aTk, aDistance;
1064 aDistance=aPj.Distance(aPk);
1065 if (aDistance < myCriteria) {
1066 mySequenceOfRoots.Remove(k);
1067 aNbRoots=mySequenceOfRoots.Length();
1073 //=======================================================================
1074 //function : CheckTouch
1076 //=======================================================================
1077 Standard_Boolean IntTools_EdgeFace::CheckTouch
1078 (const IntTools_CommonPrt& aCP,
1081 Standard_Real aTF, aTL, Tol, U1f, U1l, V1f, V1l, af, al,aDist2, aMinDist2;
1082 Standard_Boolean theflag=Standard_False;
1083 Standard_Integer aNbExt, iLower;
1085 aCP.Range1(aTF, aTL);
1089 aCR=myC.Resolution(myCriteria);
1090 if((Abs(aTF - myRange.First()) < aCR) &&
1091 (Abs(aTL - myRange.Last()) < aCR)) {
1092 return theflag; // EDGE
1096 Tol = Precision::PConfusion();
1098 const Handle(Geom_Curve)& Curve =BRep_Tool::Curve (myC.Edge(), af, al);
1099 const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
1100 // Surface->Bounds(U1f,U1l,V1f,V1l);
1101 U1f = myS.FirstUParameter();
1102 U1l = myS.LastUParameter();
1103 V1f = myS.FirstVParameter();
1104 V1l = myS.LastVParameter();
1106 GeomAdaptor_Curve TheCurve (Curve,aTF, aTL);
1107 GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l);
1109 Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
1113 if(anExtrema.IsDone()) {
1116 if(!anExtrema.IsParallel()) {
1117 aNbExt=anExtrema.NbExt();
1121 for (Standard_Integer i=1; i<=aNbExt; i++) {
1122 aDist2=anExtrema.SquareDistance(i);
1123 if (aDist2 < aMinDist2) {
1128 aDist2=anExtrema.SquareDistance(iLower);
1129 Extrema_POnCurv aPOnC;
1130 Extrema_POnSurf aPOnS;
1131 anExtrema.Points(iLower, aPOnC, aPOnS);
1132 aTx=aPOnC.Parameter();
1135 // modified by NIZHNY-MKK Thu Jul 21 11:35:32 2005.BEGIN
1136 IntCurveSurface_HInter anExactIntersector;
1138 Handle(GeomAdaptor_HCurve) aCurve = new GeomAdaptor_HCurve(TheCurve);
1139 Handle(GeomAdaptor_HSurface) aSurface = new GeomAdaptor_HSurface(TheSurface);
1141 anExactIntersector.Perform(aCurve, aSurface);
1143 if(anExactIntersector.IsDone()) {
1144 for(Standard_Integer i = 1; i <= anExactIntersector.NbPoints(); i++) {
1145 const IntCurveSurface_IntersectionPoint& aPoint = anExactIntersector.Point(i);
1147 if((aPoint.W() >= aTF) && (aPoint.W() <= aTL)) {
1153 // modified by NIZHNY-MKK Thu Jul 21 11:35:40 2005.END
1161 Standard_Real aBoundaryDist;
1163 aBoundaryDist = DistanceFunction(aTF) + myCriteria;
1164 if(aBoundaryDist * aBoundaryDist < aDist2) {
1165 aDist2 = aBoundaryDist * aBoundaryDist;
1169 aBoundaryDist = DistanceFunction(aTL) + myCriteria;
1170 if(aBoundaryDist * aBoundaryDist < aDist2) {
1171 aDist2 = aBoundaryDist * aBoundaryDist;
1175 Standard_Real aParameter = (aTF + aTL) * 0.5;
1176 aBoundaryDist = DistanceFunction(aParameter) + myCriteria;
1177 if(aBoundaryDist * aBoundaryDist < aDist2) {
1178 aDist2 = aBoundaryDist * aBoundaryDist;
1182 if(aDist2 > myCriteria * myCriteria) {
1186 if (fabs (aTx-aTF) < myEpsT) {
1190 if (fabs (aTx-aTL) < myEpsT) {
1194 if (aTx>aTF && aTx<aTL) {
1200 //=======================================================================
1201 //function : Perform
1203 //=======================================================================
1204 void IntTools_EdgeFace::Perform()
1206 Standard_Integer i, aNb;
1207 IntTools_CommonPrt aCommonPrt;
1209 aCommonPrt.SetEdge1(myEdge);
1213 if (myErrorStatus) {
1217 if (myContext.IsNull()) {
1218 myContext=new IntTools_Context;
1221 myIsDone = Standard_False;
1222 myC.Initialize(myEdge);
1223 GeomAbs_CurveType aCurveType;
1224 aCurveType=myC.GetType();
1226 // Prepare myCriteria
1227 if (aCurveType==GeomAbs_BSplineCurve||
1228 aCurveType==GeomAbs_BezierCurve) {
1230 Standard_Real diff1 = (myTolE/myTolF);
1231 Standard_Real diff2 = (myTolF/myTolE);
1232 if( diff1 > 100 || diff2 > 100 ) {
1233 myCriteria = Max(myTolE,myTolF);
1236 myCriteria=1.5*myTolE+myTolF;
1239 myCriteria=myTolE+myTolF;
1242 myTmin=myRange.First();
1243 myTmax=myRange.Last();
1245 myS.Initialize (myFace,Standard_True);
1247 if(myContext.IsNull()) {
1248 myFClass2d.Init(myFace, 1.e-6);
1251 IntTools_BeanFaceIntersector anIntersector(myC, myS, myTolE, myTolF);
1252 anIntersector.SetBeanParameters(myRange.First(), myRange.Last());
1254 anIntersector.SetContext(myContext);
1256 anIntersector.Perform();
1258 if(!anIntersector.IsDone()) {
1262 for(Standard_Integer r = 1; r <= anIntersector.Result().Length(); r++) {
1263 const IntTools_Range& aRange = anIntersector.Result().Value(r);
1265 if(IsProjectable(IntTools_Tools::IntermediatePoint(aRange.First(), aRange.Last()))) {
1266 aCommonPrt.SetRange1(aRange.First(), aRange.Last());
1267 mySeqOfCommonPrts.Append(aCommonPrt);
1271 aNb = mySeqOfCommonPrts.Length();
1273 for (i=1; i<=aNb; i++) {
1274 IntTools_CommonPrt& aCP=mySeqOfCommonPrts.ChangeValue(i);
1276 Standard_Real aTx1, aTx2;
1279 aCP.Range1(aTx1, aTx2);
1282 aCP.SetBoundingPoints(aPx1, aPx2);
1287 // Line\Cylinder's Common Parts treatement
1288 GeomAbs_CurveType aCType;
1289 GeomAbs_SurfaceType aSType;
1290 TopAbs_ShapeEnum aType;
1291 Standard_Boolean bIsTouch;
1294 aCType=myC.GetType();
1295 aSType=myS.GetType();
1297 if (aCType==GeomAbs_Line && aSType==GeomAbs_Cylinder) {
1298 for (i=1; i<=aNb; i++) {
1299 IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
1301 if (aType==TopAbs_EDGE) {
1302 bIsTouch=CheckTouch (aCP, aTx);
1304 aCP.SetType(TopAbs_VERTEX);
1305 aCP.SetVertexParameter1(aTx);
1306 //aCP.SetRange1 (aTx, aTx);
1309 else if (aType==TopAbs_VERTEX) {
1310 bIsTouch=CheckTouchVertex (aCP, aTx);
1312 aCP.SetVertexParameter1(aTx);
1313 //aCP.SetRange1 (aTx, aTx);
1319 // Circle\Plane's Common Parts treatement
1321 if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1322 Standard_Boolean bIsCoplanar, bIsRadius;
1323 bIsCoplanar=IsCoplanar(myC, myS);
1324 bIsRadius=IsRadius(myC, myS, myCriteria);
1325 if (!bIsCoplanar && !bIsRadius) {
1326 for (i=1; i<=aNb; i++) {
1327 IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
1329 if (aType==TopAbs_EDGE) {
1330 bIsTouch=CheckTouch (aCP, aTx);
1332 aCP.SetType(TopAbs_VERTEX);
1333 aCP.SetVertexParameter1(aTx);
1334 //aCP.SetRange1 (aTx, aTx);
1337 else if (aType==TopAbs_VERTEX) {
1338 bIsTouch=CheckTouchVertex (aCP, aTx);
1340 aCP.SetVertexParameter1(aTx);
1341 //aCP.SetRange1 (aTx, aTx);
1348 myIsDone=Standard_True;
1353 // 1 - the method Perform() is not invoked
1354 // 2,3,4,5 -the method CheckData() fails
1355 // 6 - PrepareArgs() problems
1356 // 7 - No Projectable ranges
1357 // 8,9 - PrepareArgs() problems occured inside projectable Ranges
1358 // 11 - can't fill array aFunc(i) in PrepareArgsFuncArrays
1361 //=======================================================================
1362 //function : CheckTouch
1364 //=======================================================================
1365 Standard_Boolean IntTools_EdgeFace::CheckTouchVertex
1366 (const IntTools_CommonPrt& aCP,
1369 Standard_Real aTF, aTL, Tol, U1f,U1l,V1f,V1l;
1370 Standard_Real aEpsT, af, al,aDist2, aMinDist2, aTm, aDist2New;
1371 Standard_Boolean theflag=Standard_False;
1372 Standard_Integer aNbExt, i, iLower ;
1373 GeomAbs_CurveType aType;
1375 aCP.Range1(aTF, aTL);
1376 aType=myC.GetType();
1379 if (aType==GeomAbs_Line) {
1384 aDist2=DistanceFunction(aTm);
1387 Tol = Precision::PConfusion();
1389 const Handle(Geom_Curve)& Curve =BRep_Tool::Curve (myC.Edge(), af, al);
1390 const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
1392 Surface->Bounds(U1f,U1l,V1f,V1l);
1394 GeomAdaptor_Curve TheCurve (Curve,aTF, aTL);
1395 GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l);
1397 Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
1399 if(!anExtrema.IsDone()) {
1402 if (anExtrema.IsParallel()) {
1406 aNbExt=anExtrema.NbExt() ;
1413 for (i=1; i<=aNbExt; ++i) {
1414 aDist2=anExtrema.SquareDistance(i);
1415 if (aDist2 < aMinDist2) {
1421 aDist2New=anExtrema.SquareDistance(iLower);
1423 if (aDist2New > aDist2) {
1428 if (aDist2New > myCriteria * myCriteria) {
1432 Extrema_POnCurv aPOnC;
1433 Extrema_POnSurf aPOnS;
1434 anExtrema.Points(iLower, aPOnC, aPOnS);
1437 aTx=aPOnC.Parameter();
1439 if (fabs (aTx-aTF) < aEpsT) {
1443 if (fabs (aTx-aTL) < aEpsT) {
1447 if (aTx>aTF && aTx<aTL) {
1455 //=======================================================================
1456 //function : IsCoplanar
1458 //=======================================================================
1459 Standard_Boolean IsCoplanar (const BRepAdaptor_Curve& aCurve ,
1460 const BRepAdaptor_Surface& aSurface)
1462 Standard_Boolean bFlag=Standard_False;
1464 GeomAbs_CurveType aCType;
1465 GeomAbs_SurfaceType aSType;
1467 aCType=aCurve.GetType();
1468 aSType=aSurface.GetType();
1470 if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1471 gp_Circ aCirc=aCurve.Circle();
1472 const gp_Ax1& anAx1=aCirc.Axis();
1473 const gp_Dir& aDirAx1=anAx1.Direction();
1475 gp_Pln aPln=aSurface.Plane();
1476 const gp_Ax1& anAx=aPln.Axis();
1477 const gp_Dir& aDirPln=anAx.Direction();
1479 bFlag=IntTools_Tools::IsDirsCoinside(aDirAx1, aDirPln);
1483 //=======================================================================
1484 //function : IsRadius
1486 //=======================================================================
1487 Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve,
1488 const BRepAdaptor_Surface& aSurface,
1489 const Standard_Real aCriteria)
1491 Standard_Boolean bFlag=Standard_False;
1493 GeomAbs_CurveType aCType;
1494 GeomAbs_SurfaceType aSType;
1496 aCType=aCurve.GetType();
1497 aSType=aSurface.GetType();
1499 if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1500 gp_Circ aCirc=aCurve.Circle();
1501 const gp_Pnt aCenter=aCirc.Location();
1502 Standard_Real aR=aCirc.Radius();
1503 gp_Pln aPln=aSurface.Plane();
1504 Standard_Real aD=aPln.Distance(aCenter);
1505 if (fabs (aD-aR) < aCriteria) {
1512 //=======================================================================
1513 //function : AdaptiveDiscret
1515 //=======================================================================
1516 Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret,
1517 const BRepAdaptor_Curve& aCurve ,
1518 const BRepAdaptor_Surface& aSurface)
1520 Standard_Integer iDiscretNew;
1522 iDiscretNew=iDiscret;
1524 GeomAbs_SurfaceType aSType;
1526 aSType=aSurface.GetType();
1528 if (aSType==GeomAbs_Cylinder) {
1529 Standard_Real aELength, aRadius, dLR;
1531 aELength=IntTools::Length(aCurve.Edge());
1533 gp_Cylinder aCylinder=aSurface.Cylinder();
1534 aRadius=aCylinder.Radius();
1537 iDiscretNew=(Standard_Integer)(aELength/dLR);
1539 if (iDiscretNew<iDiscret) {
1540 iDiscretNew=iDiscret;
1549 #pragma warning ( default : 4101 )