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
8 // under the terms of the GNU Lesser General Public 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.
16 #include <IntTools_EdgeFace.ixx>
20 #include <IntTools_CArray1OfReal.hxx>
21 #include <IntTools.hxx>
22 #include <IntTools_CArray1OfInteger.hxx>
23 #include <IntTools_Range.hxx>
24 #include <IntTools_Tools.hxx>
25 #include <IntTools_Array1OfRange.hxx>
26 #include <IntTools_QuickSortRange.hxx>
27 #include <IntTools_CompareRange.hxx>
28 #include <IntTools_CommonPrt.hxx>
29 #include <IntTools_Root.hxx>
30 #include <IntTools_BeanFaceIntersector.hxx>
31 #include <BOPInt_Context.hxx>
33 #include <BRep_Tool.hxx>
35 #include <GeomAdaptor_Surface.hxx>
36 #include <GeomAdaptor_Curve.hxx>
38 #include <Geom_Surface.hxx>
39 #include <Geom_Curve.hxx>
41 #include <GeomAPI_ProjectPointOnSurf.hxx>
43 #include <Precision.hxx>
45 #include <Bnd_Box.hxx>
46 #include <BndLib_AddSurface.hxx>
48 #include <gp_Cylinder.hxx>
51 #include <gp_Cone.hxx>
52 #include <gp_Torus.hxx>
53 #include <gp_Circ.hxx>
57 #include <Extrema_ExtCS.hxx>
58 #include <Extrema_POnCurv.hxx>
59 #include <Extrema_POnSurf.hxx>
61 // modified by NIZHNY-MKK Thu Jul 21 11:35:59 2005
62 #include <IntCurveSurface_HInter.hxx>
63 #include <GeomAdaptor_HCurve.hxx>
64 #include <GeomAdaptor_HSurface.hxx>
65 #include <IntCurveSurface_IntersectionPoint.hxx>
68 #pragma warning ( disable : 4101 )
72 Standard_Boolean IsCoplanar (const BRepAdaptor_Curve& ,
73 const BRepAdaptor_Surface& );
75 Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve ,
76 const BRepAdaptor_Surface& aSurface);
78 Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret,
79 const BRepAdaptor_Curve& aCurve ,
80 const BRepAdaptor_Surface& aSurface);
82 //=======================================================================
83 //function : IntTools_EdgeFace::IntTools_EdgeFace
85 //=======================================================================
86 IntTools_EdgeFace::IntTools_EdgeFace()
94 myIsDone=Standard_False;
96 myParallel=Standard_False;
99 //=======================================================================
100 //function : SetContext
102 //=======================================================================
103 void IntTools_EdgeFace::SetContext(const Handle(BOPInt_Context)& theContext)
105 myContext = theContext;
108 //=======================================================================
111 //=======================================================================
112 const Handle(BOPInt_Context)& IntTools_EdgeFace::Context()const
116 //=======================================================================
119 //=======================================================================
120 void IntTools_EdgeFace::SetEdge(const TopoDS_Edge& anEdge)
125 //=======================================================================
128 //=======================================================================
129 void IntTools_EdgeFace::SetFace(const TopoDS_Face& aFace)
134 //=======================================================================
137 //=======================================================================
138 void IntTools_EdgeFace::SetTolE(const Standard_Real aTol)
142 //=======================================================================
145 //=======================================================================
146 void IntTools_EdgeFace::SetTolF(const Standard_Real aTol)
151 //=======================================================================
152 //function : SetDiscretize
154 //=======================================================================
155 void IntTools_EdgeFace::SetDiscretize(const Standard_Integer aDiscret)
159 //=======================================================================
160 //function : SetDeflection
162 //=======================================================================
163 void IntTools_EdgeFace::SetDeflection(const Standard_Real aDefl)
167 //=======================================================================
168 //function : SetEpsilonT
170 //=======================================================================
171 void IntTools_EdgeFace::SetEpsilonT(const Standard_Real anEpsT)
175 //=======================================================================
176 //function : SetEpsilonNull
178 //=======================================================================
179 void IntTools_EdgeFace::SetEpsilonNull(const Standard_Real anEpsNull)
184 //=======================================================================
185 //function : SetRange
187 //=======================================================================
188 void IntTools_EdgeFace::SetRange(const Standard_Real aFirst,
189 const Standard_Real aLast)
191 myRange.SetFirst (aFirst);
192 myRange.SetLast (aLast);
195 //=======================================================================
196 //function : SetRange
198 //=======================================================================
199 void IntTools_EdgeFace::SetRange(const IntTools_Range& aRange)
201 myRange.SetFirst (aRange.First());
202 myRange.SetLast (aRange.Last());
204 //=======================================================================
207 //=======================================================================
208 Standard_Boolean IntTools_EdgeFace::IsDone()const
212 //=======================================================================
213 //function : ErrorStatus
215 //=======================================================================
216 Standard_Integer IntTools_EdgeFace::ErrorStatus()const
218 return myErrorStatus;
220 //=======================================================================
221 //function : CommonParts
223 //=======================================================================
224 const IntTools_SequenceOfCommonPrts& IntTools_EdgeFace::CommonParts() const
226 return mySeqOfCommonPrts;
228 //=======================================================================
231 //=======================================================================
232 const IntTools_Range& IntTools_EdgeFace::Range() const
237 //=======================================================================
238 //function : CheckData
240 //=======================================================================
241 void IntTools_EdgeFace::CheckData()
243 if (BRep_Tool::Degenerated(myEdge)) {
246 if (!BRep_Tool::IsGeometric(myEdge)) {
250 //=======================================================================
253 //=======================================================================
254 void IntTools_EdgeFace::Prepare()
256 Standard_Integer pri;
257 IntTools_CArray1OfReal aPars;
260 // 1.Prepare Curve's data and Surface's data
261 myC.Initialize(myEdge);
262 GeomAbs_CurveType aCurveType;
263 aCurveType=myC.GetType();
265 // 2.Prepare myCriteria
266 if (aCurveType==GeomAbs_BSplineCurve||
267 aCurveType==GeomAbs_BezierCurve) {
268 myCriteria=1.5*myTolE+myTolF;
271 myCriteria=myTolE+myTolF;
273 // 2.a myTmin, myTmax
274 myTmin=myRange.First();
275 myTmax=myRange.Last();
277 myS.Initialize (myFace,Standard_True);
278 myFClass2d.Init(myFace, 1.e-6);
280 // 2.c Prepare adaptive myDiscret
281 myDiscret=AdaptiveDiscret(myDiscret, myC, myS);
285 pri = IntTools::PrepareArgs(myC, myTmax, myTmin, myDiscret, myDeflection, aPars);
292 Standard_Integer i, iProj, aNb, aNbProj, ind0, ind1;
293 Standard_Real t0, t1, tRoot;
296 // Table of Projection's function values
298 IntTools_CArray1OfInteger anArrProjectability;
299 anArrProjectability.Resize(aNb);
301 for (iProj=0, i=0; i<aNb; i++) {
303 aNbProj=IsProjectable (t0);
305 anArrProjectability(i)=0;
307 anArrProjectability(i)=1;
319 // Projectable Ranges
320 IntTools_Range aRange;
322 ind0=anArrProjectability(0);
328 for(i=1; i<aNb; i++) {
329 ind1=anArrProjectability(i);
336 myProjectableRanges.Append(aRange);
339 FindProjectableRoot(t0, t1, ind0, ind1, tRoot);
340 aRange.SetFirst(tRoot);
342 myProjectableRanges.Append(aRange);
346 FindProjectableRoot(t0, t1, ind0, ind1, tRoot);
347 aRange.SetLast(tRoot);
348 myProjectableRanges.Append(aRange);
355 FindProjectableRoot(t0, t1, ind0, ind1, tRoot);
358 aRange.SetLast(tRoot);
359 myProjectableRanges.Append(aRange);
362 aRange.SetFirst(tRoot);
364 } // if (ind0 != ind1)
366 } // for(i=1; i<aNb; i++) {
369 //=======================================================================
370 //function : FindProjectableRoot
372 //=======================================================================
373 void IntTools_EdgeFace::FindProjectableRoot (const Standard_Real tt1,
374 const Standard_Real tt2,
375 const Standard_Integer ff1,
376 const Standard_Integer ff2,
377 Standard_Real& tRoot)
379 Standard_Real tm, t1, t2, aEpsT;
380 Standard_Integer anIsProj1, anIsProj2, anIsProjm;
383 // Root is inside [tt1, tt2]
390 if (fabs(t1-t2) < aEpsT) {
391 tRoot=(anIsProj1) ? t1 : t2;
395 anIsProjm=IsProjectable(tm);
397 if (anIsProjm != anIsProj1) {
407 //=======================================================================
408 //function : IsProjectable
410 //=======================================================================
411 Standard_Boolean IntTools_EdgeFace::IsProjectable(const Standard_Real aT) const
413 Standard_Boolean bFlag;
417 bFlag=myContext->IsValidPointForFace(aPC, myFace, myCriteria);
421 //=======================================================================
422 //function : DistanceFunction
424 //=======================================================================
425 Standard_Real IntTools_EdgeFace::DistanceFunction(const Standard_Real t)
433 Standard_Boolean bIsEqDistance;
435 bIsEqDistance= IntTools_EdgeFace::IsEqDistance(P, myS, 1.e-7, aD);
442 Standard_Boolean bFlag = Standard_False;
444 GeomAPI_ProjectPointOnSurf& aLocProj = myContext->ProjPS(myFace);
446 bFlag = aLocProj.IsDone();
449 aD = aLocProj.LowerDistance();
459 // aD=aProjector.LowerDistance();
465 //=======================================================================
466 //function : IsEqDistance
468 //=======================================================================
469 Standard_Boolean IntTools_EdgeFace::IsEqDistance(const gp_Pnt& aP,
470 const BRepAdaptor_Surface& aBAS,
471 const Standard_Real aTol,
474 Standard_Boolean bRetFlag=Standard_True;
476 GeomAbs_SurfaceType aSurfType=aBAS.GetType();
478 if (aSurfType==GeomAbs_Cylinder) {
479 gp_Cylinder aCyl=aBAS.Cylinder();
480 const gp_Ax1& anAx1 =aCyl.Axis();
481 gp_Lin aLinAxis(anAx1);
482 Standard_Real aDC, aRadius=aCyl.Radius();
483 aDC=aLinAxis.Distance(aP);
490 if (aSurfType==GeomAbs_Cone) {
491 gp_Cone aCone=aBAS.Cone();
492 const gp_Ax1& anAx1 =aCone.Axis();
493 gp_Lin aLinAxis(anAx1);
494 Standard_Real aDC, aRadius, aDS, aSemiAngle;
495 aDC=aLinAxis.Distance(aP);
497 gp_Pnt anApex=aCone.Apex();
498 aSemiAngle=aCone.SemiAngle();
499 aDS=aP.Distance(anApex);
501 aRadius=aDS*tan(aSemiAngle);
507 if (aSurfType==GeomAbs_Torus) {
508 Standard_Real aMajorRadius, aMinorRadius, aDC;
510 gp_Torus aTorus=aBAS.Torus();
511 gp_Pnt aPLoc=aTorus.Location();
512 aMajorRadius=aTorus.MajorRadius();
514 aDC=fabs(aPLoc.Distance(aP)-aMajorRadius);
516 aMinorRadius=aTorus.MinorRadius();
524 //=======================================================================
525 //function : PrepareArgsFuncArrays
527 // myFuncArray and myArgsArray for the interval [ta, tb]
528 //=======================================================================
529 void IntTools_EdgeFace::PrepareArgsFuncArrays(const Standard_Real ta,
530 const Standard_Real tb)
532 IntTools_CArray1OfReal anArgs, aFunc;
533 Standard_Integer i, aNb, pri;
534 Standard_Real t, f, f1;
536 // Prepare values of arguments for the interval [ta, tb]
537 pri=IntTools::PrepareArgs (myC, tb, ta, myDiscret, myDeflection, anArgs);
551 // Prepare values of functions for the interval [ta, tb]
553 for (i=0; i<aNb; i++) {
555 f1=DistanceFunction(t);
558 if (myErrorStatus==11)
561 if (f1 < myEpsNull) {
567 // Add points where the derivative = 0
568 AddDerivativePoints(anArgs, aFunc);
573 //=======================================================================
574 //function : AddDerivativePoints
576 //=======================================================================
577 void IntTools_EdgeFace::AddDerivativePoints(const IntTools_CArray1OfReal& t,
578 const IntTools_CArray1OfReal& f)
580 Standard_Integer i, j, n, k, nn=100;
581 Standard_Real fr, tr, tr1, dEpsNull=10.*myEpsNull;
582 IntTools_CArray1OfReal fd;
583 TColStd_SequenceOfReal aTSeq, aFSeq;
588 // Table of derivatives
589 Standard_Real dfx, tx, tx1, fx, fx1, dt=1.e-6;
594 fx1=DistanceFunction(tx1);
596 if (fx1 < myEpsNull) {
602 if (fabs(fd(0)) < dEpsNull){
608 for (i=1; i<k; i++) {
609 fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1));
610 if (fabs(fd(i)) < dEpsNull){
618 fx1=DistanceFunction(tx1);
620 if (fx1 < myEpsNull) {
626 if (fabs(fd(n-1)) < dEpsNull){
630 // Finding the range where the derivatives have different signs
631 // for neighbouring points
632 for (i=1; i<n; i++) {
633 Standard_Real fd1, fd2, t1, t2;
640 if (fabs(fd1) < myEpsNull) {
642 fr=DistanceFunction(tr);//fd1;
644 else if (fabs(fd2) < myEpsNull) {
646 fr=DistanceFunction(tr);
649 tr=FindSimpleRoot(2, t1, t2, fd1);
650 fr=DistanceFunction(tr);
656 } // end of for (i=1; i<n; i++)
658 // remove identical t, f
661 for (i=1; i<=aTSeq.Length(); i++) {
663 for (j=0; j<n; j++) {
665 if (fabs (tr1-tr) < myEpsT) {
674 // sorting args and funcs in increasing order
677 IntTools_Array1OfRange anArray1OfRange(1, k);
678 for (i=1; i<=n; i++) {
679 anArray1OfRange(i).SetFirst(t(i-1));
680 anArray1OfRange(i).SetLast (f(i-1));
682 for (i=1; i<=nn; i++) {
683 anArray1OfRange(n+i).SetFirst(aTSeq(i));
684 anArray1OfRange(n+i).SetLast (aFSeq(i));
687 IntTools_QuickSortRange aQuickSortRange;
688 IntTools_CompareRange aComparator;
689 aQuickSortRange.Sort (anArray1OfRange, aComparator);
691 // filling the output arrays
692 myArgsArray.Resize(k);
693 myFuncArray.Resize(k);
694 for (i=1; i<=k; i++) {
695 myArgsArray(i-1)=anArray1OfRange(i).First();
696 myFuncArray(i-1)=anArray1OfRange(i).Last ();
701 myArgsArray.Resize(n);
702 myFuncArray.Resize(n);
703 for (i=0; i<n; i++) {
710 //=======================================================================
711 //function : DerivativeFunction
713 //=======================================================================
714 Standard_Real IntTools_EdgeFace::DerivativeFunction(const Standard_Real t2)
716 Standard_Real t1, t3, aD1, aD2, aD3;
717 Standard_Real dt=1.e-9;
719 aD1=DistanceFunction(t1);
721 aD3=DistanceFunction(t3);
727 //=======================================================================
728 //function : FindSimpleRoot
729 //purpose : [private]
730 //=======================================================================
731 Standard_Real IntTools_EdgeFace::FindSimpleRoot (const Standard_Integer IP,
732 const Standard_Real tA,
733 const Standard_Real tB,
734 const Standard_Real fA)
736 Standard_Real r, a, b, y, x0, s;
744 y=DistanceFunction(x0);
746 y=DerivativeFunction(x0);
748 if (fabs(b-a) < myEpsT || y==0.) {
765 //=======================================================================
766 //function : FindGoldRoot
767 //purpose : [private]
768 //=======================================================================
769 Standard_Real IntTools_EdgeFace::FindGoldRoot (const Standard_Real tA,
770 const Standard_Real tB,
771 const Standard_Real coeff)
773 Standard_Real gs=0.61803399;
774 Standard_Real a, b, xp, xl, yp, yl;
780 yp=coeff*DistanceFunction(xp);
781 yl=coeff*DistanceFunction(xl);
786 if (fabs(b-a) < myEpsT) {
794 yp=coeff*DistanceFunction(xp);
802 yl=coeff*DistanceFunction(xl);
807 //=======================================================================
808 //function : MakeType
810 //=======================================================================
811 Standard_Integer IntTools_EdgeFace::MakeType(IntTools_CommonPrt& aCommonPrt)
813 Standard_Real af1, al1;
814 Standard_Real df1, tm;
815 Standard_Boolean bAllNullFlag;
817 bAllNullFlag=aCommonPrt.AllNullFlag();
819 aCommonPrt.SetType(TopAbs_EDGE);
823 aCommonPrt.Range1(af1, al1);
829 df1=aPF.Distance(aPL);
830 Standard_Boolean isWholeRange = Standard_False;
832 if((Abs(af1 - myRange.First()) < myC.Resolution(myCriteria)) &&
833 (Abs(al1 - myRange.Last()) < myC.Resolution(myCriteria)))
834 isWholeRange = Standard_True;
837 if ((df1 > myCriteria * 2.) && isWholeRange) {
838 aCommonPrt.SetType(TopAbs_EDGE);
842 tm = (af1 + al1) * 0.5;
844 if(aPF.Distance(myC.Value(tm)) > myCriteria * 2.) {
845 aCommonPrt.SetType(TopAbs_EDGE);
850 if(!CheckTouch(aCommonPrt, tm)) {
851 tm = (af1 + al1) * 0.5;
853 aCommonPrt.SetType(TopAbs_VERTEX);
854 aCommonPrt.SetVertexParameter1(tm);
855 aCommonPrt.SetRange1 (af1, al1);
866 df1=aPF.Distance(aPL);
867 if (df1<myCriteria) {
870 aCommonPrt.SetType(TopAbs_VERTEX);
871 aCommonPrt.SetVertexParameter1(tm);
872 aCommonPrt.SetRange1 (af1, al1);
877 IsIntersection (af1, al1);
880 aCommonPrt.SetType(TopAbs_VERTEX);
881 aCommonPrt.SetVertexParameter1(myPar1);
882 aCommonPrt.SetRange1 (af1, al1);
887 df1=DistanceFunction(af1);
888 df2=DistanceFunction(al1);
889 tm=(df1 < df2) ? af1 : al1;
890 aCommonPrt.SetType(TopAbs_VERTEX);
891 aCommonPrt.SetVertexParameter1(tm);
892 aCommonPrt.SetRange1 (af1, al1);
896 aCommonPrt.SetType(TopAbs_EDGE);
904 //=======================================================================
905 //function : IsIntersection
907 //=======================================================================
908 void IntTools_EdgeFace::IsIntersection (const Standard_Real ta,
909 const Standard_Real tb)
911 IntTools_CArray1OfReal anArgs, aFunc;
912 Standard_Integer i, aNb, aCnt=0;
914 Standard_Integer aCntIncreasing=1, aCntDecreasing=1;
915 Standard_Real t, f, f1;
917 // Prepare values of arguments for the interval [ta, tb]
918 IntTools::PrepareArgs (myC, tb, ta, myDiscret, myDeflection, anArgs);
922 for (i=0; i<aNb; i++) {
925 f1=DistanceFunction(t);
928 if (fabs(f1) < myEpsNull) {
935 if (aFunc(i)>aFunc(i-1)) {
938 if (aFunc(i)<aFunc(i-1)) {
946 myParallel=Standard_True;
950 FindDerivativeRoot(anArgs, aFunc);
954 if (!(myC.GetType()==GeomAbs_Line
956 myS.GetType()==GeomAbs_Cylinder)) {
957 if (aCntDecreasing==aNb) {
958 myPar1=anArgs(aNb-1);
959 myParallel=Standard_False;
961 if (aCntIncreasing==aNb) {
963 myParallel=Standard_False;
971 //=======================================================================
972 //function : FindDerivativeRoot
974 //=======================================================================
975 void IntTools_EdgeFace::FindDerivativeRoot(const IntTools_CArray1OfReal& t,
976 const IntTools_CArray1OfReal& f)
978 Standard_Integer i, n, k;
980 IntTools_CArray1OfReal fd;
981 TColStd_SequenceOfReal aTSeq, aFSeq;
984 myParallel=Standard_True;
989 // Table of derivatives
990 fd(0)=(f(1)-f(0))/(t(1)-t(0));
991 if (fabs(fd(0)) < myEpsNull) {
996 for (i=1; i<k; i++) {
997 fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1));
998 if (fabs(fd(i)) < myEpsNull) {
1003 fd(n-1)=(f(n-1)-f(n-2))/(t(n-1)-t(n-2));
1004 if (fabs(fd(n-1)) < myEpsNull) {
1008 // Finding the range where the derivatives have different signs
1009 // for neighbouring points
1010 for (i=1; i<n; i++) {
1011 Standard_Real fd1, fd2, t1, t2, fabsfd1, fabsfd2;
1012 Standard_Boolean bF1, bF2;
1019 bF1=fabsfd1 < myEpsNull;
1022 bF2=fabsfd2 < myEpsNull;
1025 tr=FindSimpleRoot(2, t1, t2, fd1);
1026 DistanceFunction(tr);
1028 myParallel=Standard_False;
1035 myParallel=Standard_False;
1042 myParallel=Standard_False;
1048 //=======================================================================
1049 //function : RemoveIdenticalRoots
1051 //=======================================================================
1052 void IntTools_EdgeFace::RemoveIdenticalRoots()
1054 Standard_Integer aNbRoots, j, k;
1056 aNbRoots=mySequenceOfRoots.Length();
1057 for (j=1; j<=aNbRoots; j++) {
1058 const IntTools_Root& aRj=mySequenceOfRoots(j);
1059 for (k=j+1; k<=aNbRoots; k++) {
1060 const IntTools_Root& aRk=mySequenceOfRoots(k);
1062 Standard_Real aTj, aTk, aDistance;
1071 aDistance=aPj.Distance(aPk);
1072 if (aDistance < myCriteria) {
1073 mySequenceOfRoots.Remove(k);
1074 aNbRoots=mySequenceOfRoots.Length();
1080 //=======================================================================
1081 //function : CheckTouch
1083 //=======================================================================
1084 Standard_Boolean IntTools_EdgeFace::CheckTouch(const IntTools_CommonPrt& aCP,
1087 Standard_Real aTF, aTL, Tol, U1f, U1l, V1f, V1l, af, al,aDist2, aMinDist2;
1088 Standard_Boolean theflag=Standard_False;
1089 Standard_Integer aNbExt, i, iLower ;
1091 aCP.Range1(aTF, aTL);
1095 aCR=myC.Resolution(myCriteria);
1096 if((Abs(aTF - myRange.First()) < aCR) &&
1097 (Abs(aTL - myRange.Last()) < aCR)) {
1098 return theflag; // EDGE
1102 Tol = Precision::PConfusion();
1104 const Handle(Geom_Curve)& Curve =BRep_Tool::Curve (myC.Edge(), af, al);
1105 const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
1106 // Surface->Bounds(U1f,U1l,V1f,V1l);
1107 U1f = myS.FirstUParameter();
1108 U1l = myS.LastUParameter();
1109 V1f = myS.FirstVParameter();
1110 V1l = myS.LastVParameter();
1112 GeomAdaptor_Curve TheCurve (Curve,aTF, aTL);
1113 GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l);
1115 Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
1119 if(anExtrema.IsDone()) {
1122 if(!anExtrema.IsParallel()) {
1123 aNbExt=anExtrema.NbExt();
1127 for (i=1; i<=aNbExt; i++) {
1128 aDist2=anExtrema.SquareDistance(i);
1129 if (aDist2 < aMinDist2) {
1134 aDist2=anExtrema.SquareDistance(iLower);
1135 Extrema_POnCurv aPOnC;
1136 Extrema_POnSurf aPOnS;
1137 anExtrema.Points(iLower, aPOnC, aPOnS);
1138 aTx=aPOnC.Parameter();
1141 // modified by NIZHNY-MKK Thu Jul 21 11:35:32 2005.BEGIN
1142 IntCurveSurface_HInter anExactIntersector;
1144 Handle(GeomAdaptor_HCurve) aCurve = new GeomAdaptor_HCurve(TheCurve);
1145 Handle(GeomAdaptor_HSurface) aSurface = new GeomAdaptor_HSurface(TheSurface);
1147 anExactIntersector.Perform(aCurve, aSurface);
1149 if(anExactIntersector.IsDone()) {
1150 Standard_Integer i = 0;
1152 for(i = 1; i <= anExactIntersector.NbPoints(); i++) {
1153 const IntCurveSurface_IntersectionPoint& aPoint = anExactIntersector.Point(i);
1155 if((aPoint.W() >= aTF) && (aPoint.W() <= aTL)) {
1161 // modified by NIZHNY-MKK Thu Jul 21 11:35:40 2005.END
1169 Standard_Real aBoundaryDist;
1171 aBoundaryDist = DistanceFunction(aTF) + myCriteria;
1172 if(aBoundaryDist * aBoundaryDist < aDist2) {
1173 aDist2 = aBoundaryDist * aBoundaryDist;
1177 aBoundaryDist = DistanceFunction(aTL) + myCriteria;
1178 if(aBoundaryDist * aBoundaryDist < aDist2) {
1179 aDist2 = aBoundaryDist * aBoundaryDist;
1183 Standard_Real aParameter = (aTF + aTL) * 0.5;
1184 aBoundaryDist = DistanceFunction(aParameter) + myCriteria;
1185 if(aBoundaryDist * aBoundaryDist < aDist2) {
1186 aDist2 = aBoundaryDist * aBoundaryDist;
1190 if(aDist2 > myCriteria * myCriteria) {
1194 if (fabs (aTx-aTF) < myEpsT) {
1198 if (fabs (aTx-aTL) < myEpsT) {
1202 if (aTx>aTF && aTx<aTL) {
1210 //=======================================================================
1211 //function : Perform
1213 //=======================================================================
1214 void IntTools_EdgeFace::Perform()
1216 Standard_Integer i, aNb;
1217 IntTools_CommonPrt aCommonPrt;
1219 aCommonPrt.SetEdge1(myEdge);
1223 if (myErrorStatus) {
1227 if (myContext.IsNull()) {
1228 myContext=new BOPInt_Context;
1231 myIsDone = Standard_False;
1232 myC.Initialize(myEdge);
1233 GeomAbs_CurveType aCurveType;
1234 aCurveType=myC.GetType();
1236 // Prepare myCriteria
1237 if (aCurveType==GeomAbs_BSplineCurve||
1238 aCurveType==GeomAbs_BezierCurve) {
1240 Standard_Real diff1 = (myTolE/myTolF);
1241 Standard_Real diff2 = (myTolF/myTolE);
1242 if( diff1 > 100 || diff2 > 100 ) {
1243 myCriteria = Max(myTolE,myTolF);
1246 myCriteria=1.5*myTolE+myTolF;
1249 myCriteria=myTolE+myTolF;
1252 myTmin=myRange.First();
1253 myTmax=myRange.Last();
1255 myS.Initialize (myFace,Standard_True);
1257 if(myContext.IsNull()) {
1258 myFClass2d.Init(myFace, 1.e-6);
1261 IntTools_BeanFaceIntersector anIntersector(myC, myS, myTolE, myTolF);
1262 anIntersector.SetBeanParameters(myRange.First(), myRange.Last());
1264 anIntersector.SetContext(myContext);
1266 anIntersector.Perform();
1268 if(!anIntersector.IsDone()) {
1272 for(Standard_Integer r = 1; r <= anIntersector.Result().Length(); r++) {
1273 const IntTools_Range& aRange = anIntersector.Result().Value(r);
1275 if(IsProjectable(IntTools_Tools::IntermediatePoint(aRange.First(), aRange.Last()))) {
1276 aCommonPrt.SetRange1(aRange.First(), aRange.Last());
1277 mySeqOfCommonPrts.Append(aCommonPrt);
1281 aNb = mySeqOfCommonPrts.Length();
1283 for (i=1; i<=aNb; i++) {
1284 IntTools_CommonPrt& aCP=mySeqOfCommonPrts.ChangeValue(i);
1286 Standard_Real aTx1, aTx2;
1289 aCP.Range1(aTx1, aTx2);
1292 aCP.SetBoundingPoints(aPx1, aPx2);
1297 // Line\Cylinder's Common Parts treatement
1298 GeomAbs_CurveType aCType;
1299 GeomAbs_SurfaceType aSType;
1300 TopAbs_ShapeEnum aType;
1301 Standard_Boolean bIsTouch;
1304 aCType=myC.GetType();
1305 aSType=myS.GetType();
1307 if (aCType==GeomAbs_Line && aSType==GeomAbs_Cylinder) {
1308 for (i=1; i<=aNb; i++) {
1309 IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
1311 if (aType==TopAbs_EDGE) {
1312 bIsTouch=CheckTouch (aCP, aTx);
1314 aCP.SetType(TopAbs_VERTEX);
1315 aCP.SetVertexParameter1(aTx);
1316 aCP.SetRange1 (aTx, aTx);
1319 if (aType==TopAbs_VERTEX) {
1320 bIsTouch=CheckTouchVertex (aCP, aTx);
1322 aCP.SetVertexParameter1(aTx);
1323 aCP.SetRange1 (aTx, aTx);
1329 // Circle\Plane's Common Parts treatement
1331 if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1332 Standard_Boolean bIsCoplanar, bIsRadius;
1333 bIsCoplanar=IsCoplanar(myC, myS);
1334 bIsRadius=IsRadius(myC, myS);
1335 if (!bIsCoplanar && !bIsRadius) {
1336 for (i=1; i<=aNb; i++) {
1337 IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
1339 if (aType==TopAbs_EDGE) {
1340 bIsTouch=CheckTouch (aCP, aTx);
1342 aCP.SetType(TopAbs_VERTEX);
1343 aCP.SetVertexParameter1(aTx);
1344 aCP.SetRange1 (aTx, aTx);
1351 myIsDone=Standard_True;
1356 // 1 - the method Perform() is not invoked
1357 // 2,3,4,5 -the method CheckData() fails
1358 // 6 - PrepareArgs() problems
1359 // 7 - No Projectable ranges
1360 // 8,9 - PrepareArgs() problems occured inside projectable Ranges
1361 // 11 - can't fill array aFunc(i) in PrepareArgsFuncArrays
1364 //=======================================================================
1365 //function : CheckTouch
1367 //=======================================================================
1368 Standard_Boolean IntTools_EdgeFace::CheckTouchVertex (const IntTools_CommonPrt& aCP,
1371 Standard_Real aTF, aTL, Tol, U1f,U1l,V1f,V1l, af, al,aDist2, aMinDist2, aTm, aDist2New;
1372 Standard_Real aEpsT;
1373 Standard_Boolean theflag=Standard_False;
1374 Standard_Integer aNbExt, i, iLower ;
1376 aCP.Range1(aTF, aTL);
1379 aDist2=DistanceFunction(aTm);
1382 Tol = Precision::PConfusion();
1384 const Handle(Geom_Curve)& Curve =BRep_Tool::Curve (myC.Edge(), af, al);
1385 const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
1387 Surface->Bounds(U1f,U1l,V1f,V1l);
1389 GeomAdaptor_Curve TheCurve (Curve,aTF, aTL);
1390 GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l);
1392 Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
1394 if(!anExtrema.IsDone()) {
1397 if (anExtrema.IsParallel()) {
1401 aNbExt=anExtrema.NbExt() ;
1408 for (i=1; i<=aNbExt; ++i) {
1409 aDist2=anExtrema.SquareDistance(i);
1410 if (aDist2 < aMinDist2) {
1416 aDist2New=anExtrema.SquareDistance(iLower);
1418 if (aDist2New > aDist2) {
1423 if (aDist2New > myCriteria * myCriteria) {
1427 Extrema_POnCurv aPOnC;
1428 Extrema_POnSurf aPOnS;
1429 anExtrema.Points(iLower, aPOnC, aPOnS);
1432 aTx=aPOnC.Parameter();
1434 if (fabs (aTx-aTF) < aEpsT) {
1438 if (fabs (aTx-aTL) < aEpsT) {
1442 if (aTx>aTF && aTx<aTL) {
1450 //=======================================================================
1451 //function : IsCoplanar
1453 //=======================================================================
1454 Standard_Boolean IsCoplanar (const BRepAdaptor_Curve& aCurve ,
1455 const BRepAdaptor_Surface& aSurface)
1457 Standard_Boolean bFlag=Standard_False;
1459 GeomAbs_CurveType aCType;
1460 GeomAbs_SurfaceType aSType;
1462 aCType=aCurve.GetType();
1463 aSType=aSurface.GetType();
1465 if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1466 gp_Circ aCirc=aCurve.Circle();
1467 const gp_Ax1& anAx1=aCirc.Axis();
1468 const gp_Dir& aDirAx1=anAx1.Direction();
1470 gp_Pln aPln=aSurface.Plane();
1471 const gp_Ax1& anAx=aPln.Axis();
1472 const gp_Dir& aDirPln=anAx.Direction();
1474 bFlag=IntTools_Tools::IsDirsCoinside(aDirAx1, aDirPln);
1478 //=======================================================================
1479 //function : IsRadius
1481 //=======================================================================
1482 Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve ,
1483 const BRepAdaptor_Surface& aSurface)
1485 Standard_Boolean bFlag=Standard_False;
1487 GeomAbs_CurveType aCType;
1488 GeomAbs_SurfaceType aSType;
1490 aCType=aCurve.GetType();
1491 aSType=aSurface.GetType();
1493 if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1494 gp_Circ aCirc=aCurve.Circle();
1495 const gp_Pnt aCenter=aCirc.Location();
1496 Standard_Real aR=aCirc.Radius();
1497 gp_Pln aPln=aSurface.Plane();
1498 Standard_Real aD=aPln.Distance(aCenter);
1499 if (fabs (aD-aR) < 1.e-7) {
1506 //=======================================================================
1507 //function : AdaptiveDiscret
1509 //=======================================================================
1510 Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret,
1511 const BRepAdaptor_Curve& aCurve ,
1512 const BRepAdaptor_Surface& aSurface)
1514 Standard_Integer iDiscretNew;
1516 iDiscretNew=iDiscret;
1518 GeomAbs_SurfaceType aSType;
1520 aSType=aSurface.GetType();
1522 if (aSType==GeomAbs_Cylinder) {
1523 Standard_Real aELength, aRadius, dLR;
1525 aELength=IntTools::Length(aCurve.Edge());
1527 gp_Cylinder aCylinder=aSurface.Cylinder();
1528 aRadius=aCylinder.Radius();
1531 iDiscretNew=(Standard_Integer)(aELength/dLR);
1533 if (iDiscretNew<iDiscret) {
1534 iDiscretNew=iDiscret;
1543 #pragma warning ( default : 4101 )