1 // Created on: 2001-02-26
2 // Created by: Peter KURNEV
3 // Copyright (c) 2001-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
21 #include <IntTools_EdgeFace.ixx>
25 #include <IntTools_CArray1OfReal.hxx>
26 #include <IntTools.hxx>
27 #include <IntTools_CArray1OfInteger.hxx>
28 #include <IntTools_Range.hxx>
29 #include <IntTools_Tools.hxx>
30 #include <IntTools_Array1OfRange.hxx>
31 #include <IntTools_QuickSortRange.hxx>
32 #include <IntTools_CompareRange.hxx>
33 #include <IntTools_CommonPrt.hxx>
34 #include <IntTools_Root.hxx>
35 #include <IntTools_BeanFaceIntersector.hxx>
36 #include <BOPInt_Context.hxx>
38 #include <BRep_Tool.hxx>
40 #include <GeomAdaptor_Surface.hxx>
41 #include <GeomAdaptor_Curve.hxx>
43 #include <Geom_Surface.hxx>
44 #include <Geom_Curve.hxx>
46 #include <GeomAPI_ProjectPointOnSurf.hxx>
48 #include <Precision.hxx>
50 #include <Bnd_Box.hxx>
51 #include <BndLib_AddSurface.hxx>
53 #include <gp_Cylinder.hxx>
56 #include <gp_Cone.hxx>
57 #include <gp_Torus.hxx>
58 #include <gp_Circ.hxx>
62 #include <Extrema_ExtCS.hxx>
63 #include <Extrema_POnCurv.hxx>
64 #include <Extrema_POnSurf.hxx>
66 // modified by NIZHNY-MKK Thu Jul 21 11:35:59 2005
67 #include <IntCurveSurface_HInter.hxx>
68 #include <GeomAdaptor_HCurve.hxx>
69 #include <GeomAdaptor_HSurface.hxx>
70 #include <IntCurveSurface_IntersectionPoint.hxx>
73 #pragma warning ( disable : 4101 )
77 Standard_Boolean IsCoplanar (const BRepAdaptor_Curve& ,
78 const BRepAdaptor_Surface& );
80 Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve ,
81 const BRepAdaptor_Surface& aSurface);
83 Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret,
84 const BRepAdaptor_Curve& aCurve ,
85 const BRepAdaptor_Surface& aSurface);
87 //=======================================================================
88 //function : IntTools_EdgeFace::IntTools_EdgeFace
90 //=======================================================================
91 IntTools_EdgeFace::IntTools_EdgeFace()
99 myIsDone=Standard_False;
101 myParallel=Standard_False;
104 //=======================================================================
105 //function : SetContext
107 //=======================================================================
108 void IntTools_EdgeFace::SetContext(const Handle(BOPInt_Context)& theContext)
110 myContext = theContext;
113 //=======================================================================
116 //=======================================================================
117 const Handle(BOPInt_Context)& IntTools_EdgeFace::Context()const
121 //=======================================================================
124 //=======================================================================
125 void IntTools_EdgeFace::SetEdge(const TopoDS_Edge& anEdge)
130 //=======================================================================
133 //=======================================================================
134 void IntTools_EdgeFace::SetFace(const TopoDS_Face& aFace)
139 //=======================================================================
142 //=======================================================================
143 void IntTools_EdgeFace::SetTolE(const Standard_Real aTol)
147 //=======================================================================
150 //=======================================================================
151 void IntTools_EdgeFace::SetTolF(const Standard_Real aTol)
156 //=======================================================================
157 //function : SetDiscretize
159 //=======================================================================
160 void IntTools_EdgeFace::SetDiscretize(const Standard_Integer aDiscret)
164 //=======================================================================
165 //function : SetDeflection
167 //=======================================================================
168 void IntTools_EdgeFace::SetDeflection(const Standard_Real aDefl)
172 //=======================================================================
173 //function : SetEpsilonT
175 //=======================================================================
176 void IntTools_EdgeFace::SetEpsilonT(const Standard_Real anEpsT)
180 //=======================================================================
181 //function : SetEpsilonNull
183 //=======================================================================
184 void IntTools_EdgeFace::SetEpsilonNull(const Standard_Real anEpsNull)
189 //=======================================================================
190 //function : SetRange
192 //=======================================================================
193 void IntTools_EdgeFace::SetRange(const Standard_Real aFirst,
194 const Standard_Real aLast)
196 myRange.SetFirst (aFirst);
197 myRange.SetLast (aLast);
200 //=======================================================================
201 //function : SetRange
203 //=======================================================================
204 void IntTools_EdgeFace::SetRange(const IntTools_Range& aRange)
206 myRange.SetFirst (aRange.First());
207 myRange.SetLast (aRange.Last());
209 //=======================================================================
212 //=======================================================================
213 Standard_Boolean IntTools_EdgeFace::IsDone()const
217 //=======================================================================
218 //function : ErrorStatus
220 //=======================================================================
221 Standard_Integer IntTools_EdgeFace::ErrorStatus()const
223 return myErrorStatus;
225 //=======================================================================
226 //function : CommonParts
228 //=======================================================================
229 const IntTools_SequenceOfCommonPrts& IntTools_EdgeFace::CommonParts() const
231 return mySeqOfCommonPrts;
233 //=======================================================================
236 //=======================================================================
237 const IntTools_Range& IntTools_EdgeFace::Range() const
242 //=======================================================================
243 //function : CheckData
245 //=======================================================================
246 void IntTools_EdgeFace::CheckData()
248 if (BRep_Tool::Degenerated(myEdge)) {
251 if (!BRep_Tool::IsGeometric(myEdge)) {
255 //=======================================================================
258 //=======================================================================
259 void IntTools_EdgeFace::Prepare()
261 Standard_Integer pri;
262 IntTools_CArray1OfReal aPars;
265 // 1.Prepare Curve's data and Surface's data
266 myC.Initialize(myEdge);
267 GeomAbs_CurveType aCurveType;
268 aCurveType=myC.GetType();
270 // 2.Prepare myCriteria
271 if (aCurveType==GeomAbs_BSplineCurve||
272 aCurveType==GeomAbs_BezierCurve) {
273 myCriteria=1.5*myTolE+myTolF;
276 myCriteria=myTolE+myTolF;
278 // 2.a myTmin, myTmax
279 myTmin=myRange.First();
280 myTmax=myRange.Last();
282 myS.Initialize (myFace,Standard_True);
283 myFClass2d.Init(myFace, 1.e-6);
285 // 2.c Prepare adaptive myDiscret
286 myDiscret=AdaptiveDiscret(myDiscret, myC, myS);
290 pri = IntTools::PrepareArgs(myC, myTmax, myTmin, myDiscret, myDeflection, aPars);
297 Standard_Integer i, iProj, aNb, aNbProj, ind0, ind1;
298 Standard_Real t0, t1, tRoot;
301 // Table of Projection's function values
303 IntTools_CArray1OfInteger anArrProjectability;
304 anArrProjectability.Resize(aNb);
306 for (iProj=0, i=0; i<aNb; i++) {
308 aNbProj=IsProjectable (t0);
310 anArrProjectability(i)=0;
312 anArrProjectability(i)=1;
324 // Projectable Ranges
325 IntTools_Range aRange;
327 ind0=anArrProjectability(0);
333 for(i=1; i<aNb; i++) {
334 ind1=anArrProjectability(i);
341 myProjectableRanges.Append(aRange);
344 FindProjectableRoot(t0, t1, ind0, ind1, tRoot);
345 aRange.SetFirst(tRoot);
347 myProjectableRanges.Append(aRange);
351 FindProjectableRoot(t0, t1, ind0, ind1, tRoot);
352 aRange.SetLast(tRoot);
353 myProjectableRanges.Append(aRange);
360 FindProjectableRoot(t0, t1, ind0, ind1, tRoot);
363 aRange.SetLast(tRoot);
364 myProjectableRanges.Append(aRange);
367 aRange.SetFirst(tRoot);
369 } // if (ind0 != ind1)
371 } // for(i=1; i<aNb; i++) {
374 //=======================================================================
375 //function : FindProjectableRoot
377 //=======================================================================
378 void IntTools_EdgeFace::FindProjectableRoot (const Standard_Real tt1,
379 const Standard_Real tt2,
380 const Standard_Integer ff1,
381 const Standard_Integer ff2,
382 Standard_Real& tRoot)
384 Standard_Real tm, t1, t2, aEpsT;
385 Standard_Integer anIsProj1, anIsProj2, anIsProjm;
388 // Root is inside [tt1, tt2]
395 if (fabs(t1-t2) < aEpsT) {
396 tRoot=(anIsProj1) ? t1 : t2;
400 anIsProjm=IsProjectable(tm);
402 if (anIsProjm != anIsProj1) {
412 //=======================================================================
413 //function : IsProjectable
415 //=======================================================================
416 Standard_Boolean IntTools_EdgeFace::IsProjectable(const Standard_Real t) const
418 Standard_Boolean bFlag;
419 Standard_Real Umin, Usup, Vmin, Vsup;
421 Umin=myS.FirstUParameter();
422 Usup=myS.LastUParameter();
423 Vmin=myS.FirstVParameter();
424 Vsup=myS.LastVParameter ();
428 GeomAPI_ProjectPointOnSurf aProjector;
430 Standard_Real ULD, VLD;
432 GeomAPI_ProjectPointOnSurf& aLocProj = myContext->ProjPS(myFace);
434 bFlag = aLocProj.IsDone();
437 aLocProj.LowerDistanceParameters(ULD, VLD);
442 bFlag=Standard_False;
446 gp_Pnt2d aP2d(ULD, VLD);
448 aState = myContext->FClass2d(myFace).Perform(aP2d);
451 if (aState==TopAbs_IN || aState==TopAbs_ON) {
458 //=======================================================================
459 //function : DistanceFunction
461 //=======================================================================
462 Standard_Real IntTools_EdgeFace::DistanceFunction(const Standard_Real t)
464 Standard_Real Umin, Usup, Vmin, Vsup, aD;
469 Standard_Boolean bIsEqDistance;
471 bIsEqDistance= IntTools_EdgeFace::IsEqDistance(P, myS, 1.e-7, aD);
477 Umin=myS.FirstUParameter();
478 Usup=myS.LastUParameter();
479 Vmin=myS.FirstVParameter();
480 Vsup=myS.LastVParameter ();
483 Standard_Boolean bFlag = Standard_False;
485 GeomAPI_ProjectPointOnSurf& aLocProj = myContext->ProjPS(myFace);
487 bFlag = aLocProj.IsDone();
490 aD = aLocProj.LowerDistance();
500 // aD=aProjector.LowerDistance();
506 //=======================================================================
507 //function : IsEqDistance
509 //=======================================================================
510 Standard_Boolean IntTools_EdgeFace::IsEqDistance(const gp_Pnt& aP,
511 const BRepAdaptor_Surface& aBAS,
512 const Standard_Real aTol,
515 Standard_Boolean bRetFlag=Standard_True;
517 GeomAbs_SurfaceType aSurfType=aBAS.GetType();
519 if (aSurfType==GeomAbs_Cylinder) {
520 gp_Cylinder aCyl=aBAS.Cylinder();
521 const gp_Ax1& anAx1 =aCyl.Axis();
522 gp_Lin aLinAxis(anAx1);
523 Standard_Real aDC, aRadius=aCyl.Radius();
524 aDC=aLinAxis.Distance(aP);
531 if (aSurfType==GeomAbs_Cone) {
532 gp_Cone aCone=aBAS.Cone();
533 const gp_Ax1& anAx1 =aCone.Axis();
534 gp_Lin aLinAxis(anAx1);
535 Standard_Real aDC, aRadius, aDS, aSemiAngle;
536 aDC=aLinAxis.Distance(aP);
538 gp_Pnt anApex=aCone.Apex();
539 aSemiAngle=aCone.SemiAngle();
540 aDS=aP.Distance(anApex);
542 aRadius=aDS*tan(aSemiAngle);
548 if (aSurfType==GeomAbs_Torus) {
549 Standard_Real aMajorRadius, aMinorRadius, aDC;
551 gp_Torus aTorus=aBAS.Torus();
552 gp_Pnt aPLoc=aTorus.Location();
553 aMajorRadius=aTorus.MajorRadius();
555 aDC=fabs(aPLoc.Distance(aP)-aMajorRadius);
557 aMinorRadius=aTorus.MinorRadius();
565 //=======================================================================
566 //function : PrepareArgsFuncArrays
568 // myFuncArray and myArgsArray for the interval [ta, tb]
569 //=======================================================================
570 void IntTools_EdgeFace::PrepareArgsFuncArrays(const Standard_Real ta,
571 const Standard_Real tb)
573 IntTools_CArray1OfReal anArgs, aFunc;
574 Standard_Integer i, aNb, pri;
575 Standard_Real t, f, f1;
577 // Prepare values of arguments for the interval [ta, tb]
578 pri=IntTools::PrepareArgs (myC, tb, ta, myDiscret, myDeflection, anArgs);
592 // Prepare values of functions for the interval [ta, tb]
594 for (i=0; i<aNb; i++) {
596 f1=DistanceFunction(t);
599 if (myErrorStatus==11)
602 if (f1 < myEpsNull) {
608 // Add points where the derivative = 0
609 AddDerivativePoints(anArgs, aFunc);
614 //=======================================================================
615 //function : AddDerivativePoints
617 //=======================================================================
618 void IntTools_EdgeFace::AddDerivativePoints(const IntTools_CArray1OfReal& t,
619 const IntTools_CArray1OfReal& f)
621 Standard_Integer i, j, n, k, nn=100;
622 Standard_Real fr, tr, tr1, dEpsNull=10.*myEpsNull;
623 IntTools_CArray1OfReal fd;
624 TColStd_SequenceOfReal aTSeq, aFSeq;
629 // Table of derivatives
630 Standard_Real dfx, tx, tx1, fx, fx1, dt=1.e-6;
635 fx1=DistanceFunction(tx1);
637 if (fx1 < myEpsNull) {
643 if (fabs(fd(0)) < dEpsNull){
649 for (i=1; i<k; i++) {
650 Standard_Real ti, ti1;
653 fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1));
654 if (fabs(fd(i)) < dEpsNull){
662 fx1=DistanceFunction(tx1);
664 if (fx1 < myEpsNull) {
670 if (fabs(fd(n-1)) < dEpsNull){
674 // Finding the range where the derivatives have different signs
675 // for neighbouring points
676 for (i=1; i<n; i++) {
677 Standard_Real fd1, fd2, t1, t2;
684 if (fabs(fd1) < myEpsNull) {
686 fr=DistanceFunction(tr);//fd1;
688 else if (fabs(fd2) < myEpsNull) {
690 fr=DistanceFunction(tr);
693 tr=FindSimpleRoot(2, t1, t2, fd1);
694 fr=DistanceFunction(tr);
700 } // end of for (i=1; i<n; i++)
702 // remove identical t, f
705 for (i=1; i<=aTSeq.Length(); i++) {
707 for (j=0; j<n; j++) {
709 if (fabs (tr1-tr) < myEpsT) {
718 // sorting args and funcs in increasing order
721 IntTools_Array1OfRange anArray1OfRange(1, k);
722 for (i=1; i<=n; i++) {
723 anArray1OfRange(i).SetFirst(t(i-1));
724 anArray1OfRange(i).SetLast (f(i-1));
726 for (i=1; i<=nn; i++) {
727 anArray1OfRange(n+i).SetFirst(aTSeq(i));
728 anArray1OfRange(n+i).SetLast (aFSeq(i));
731 IntTools_QuickSortRange aQuickSortRange;
732 IntTools_CompareRange aComparator;
733 aQuickSortRange.Sort (anArray1OfRange, aComparator);
735 // filling the output arrays
736 myArgsArray.Resize(k);
737 myFuncArray.Resize(k);
738 for (i=1; i<=k; i++) {
739 myArgsArray(i-1)=anArray1OfRange(i).First();
740 myFuncArray(i-1)=anArray1OfRange(i).Last ();
745 myArgsArray.Resize(n);
746 myFuncArray.Resize(n);
747 for (i=0; i<n; i++) {
754 //=======================================================================
755 //function : DerivativeFunction
757 //=======================================================================
758 Standard_Real IntTools_EdgeFace::DerivativeFunction(const Standard_Real t2)
760 Standard_Real t1, t3, aD1, aD2, aD3;
761 Standard_Real dt=1.e-9;
763 aD1=DistanceFunction(t1);
765 aD3=DistanceFunction(t3);
771 //=======================================================================
772 //function : FindSimpleRoot
773 //purpose : [private]
774 //=======================================================================
775 Standard_Real IntTools_EdgeFace::FindSimpleRoot (const Standard_Integer IP,
776 const Standard_Real tA,
777 const Standard_Real tB,
778 const Standard_Real fA)
780 Standard_Real r, a, b, y, x0, s;
788 y=DistanceFunction(x0);
790 y=DerivativeFunction(x0);
792 if (fabs(b-a) < myEpsT || y==0.) {
809 //=======================================================================
810 //function : FindGoldRoot
811 //purpose : [private]
812 //=======================================================================
813 Standard_Real IntTools_EdgeFace::FindGoldRoot (const Standard_Real tA,
814 const Standard_Real tB,
815 const Standard_Real coeff)
817 Standard_Real gs=0.61803399;
818 Standard_Real a, b, xp, xl, yp, yl;
824 yp=coeff*DistanceFunction(xp);
825 yl=coeff*DistanceFunction(xl);
830 if (fabs(b-a) < myEpsT) {
838 yp=coeff*DistanceFunction(xp);
846 yl=coeff*DistanceFunction(xl);
851 //=======================================================================
852 //function : MakeType
854 //=======================================================================
855 Standard_Integer IntTools_EdgeFace::MakeType(IntTools_CommonPrt& aCommonPrt)
857 Standard_Real af1, al1;
858 Standard_Real dt, df1, df2, tm;
859 Standard_Boolean bAllNullFlag;
861 bAllNullFlag=aCommonPrt.AllNullFlag();
863 aCommonPrt.SetType(TopAbs_EDGE);
867 aCommonPrt.Range1(af1, al1);
873 df1=aPF.Distance(aPL);
874 Standard_Boolean isWholeRange = Standard_False;
876 if((Abs(af1 - myRange.First()) < myC.Resolution(myCriteria)) &&
877 (Abs(al1 - myRange.Last()) < myC.Resolution(myCriteria)))
878 isWholeRange = Standard_True;
881 if ((df1 > myCriteria * 2.) && isWholeRange) {
882 aCommonPrt.SetType(TopAbs_EDGE);
886 tm = (af1 + al1) * 0.5;
888 if(aPF.Distance(myC.Value(tm)) > myCriteria * 2.) {
889 aCommonPrt.SetType(TopAbs_EDGE);
894 if(!CheckTouch(aCommonPrt, tm)) {
895 tm = (af1 + al1) * 0.5;
897 aCommonPrt.SetType(TopAbs_VERTEX);
898 aCommonPrt.SetVertexParameter1(tm);
899 aCommonPrt.SetRange1 (af1, al1);
910 df1=aPF.Distance(aPL);
911 if (df1<myCriteria) {
914 aCommonPrt.SetType(TopAbs_VERTEX);
915 aCommonPrt.SetVertexParameter1(tm);
916 aCommonPrt.SetRange1 (af1, al1);
921 IsIntersection (af1, al1);
924 aCommonPrt.SetType(TopAbs_VERTEX);
925 aCommonPrt.SetVertexParameter1(myPar1);
926 aCommonPrt.SetRange1 (af1, al1);
931 df1=DistanceFunction(af1);
932 df2=DistanceFunction(al1);
933 tm=(df1 < df2) ? af1 : al1;
934 aCommonPrt.SetType(TopAbs_VERTEX);
935 aCommonPrt.SetVertexParameter1(tm);
936 aCommonPrt.SetRange1 (af1, al1);
940 aCommonPrt.SetType(TopAbs_EDGE);
948 //=======================================================================
949 //function : IsIntersection
951 //=======================================================================
952 void IntTools_EdgeFace::IsIntersection (const Standard_Real ta,
953 const Standard_Real tb)
955 IntTools_CArray1OfReal anArgs, aFunc;
956 Standard_Integer i, aNb, pri, aCnt=0;
958 Standard_Integer aCntIncreasing=1, aCntDecreasing=1;
959 Standard_Real t, f, f1;
961 // Prepare values of arguments for the interval [ta, tb]
962 pri=IntTools::PrepareArgs (myC, tb, ta, myDiscret, myDeflection, anArgs);
966 for (i=0; i<aNb; i++) {
969 f1=DistanceFunction(t);
972 if (fabs(f1) < myEpsNull) {
979 if (aFunc(i)>aFunc(i-1)) {
982 if (aFunc(i)<aFunc(i-1)) {
990 myParallel=Standard_True;
994 FindDerivativeRoot(anArgs, aFunc);
998 if (!(myC.GetType()==GeomAbs_Line
1000 myS.GetType()==GeomAbs_Cylinder)) {
1001 if (aCntDecreasing==aNb) {
1002 myPar1=anArgs(aNb-1);
1003 myParallel=Standard_False;
1005 if (aCntIncreasing==aNb) {
1007 myParallel=Standard_False;
1015 //=======================================================================
1016 //function : FindDerivativeRoot
1018 //=======================================================================
1019 void IntTools_EdgeFace::FindDerivativeRoot(const IntTools_CArray1OfReal& t,
1020 const IntTools_CArray1OfReal& f)
1022 Standard_Integer i, n, k;
1023 Standard_Real fr, tr;
1024 IntTools_CArray1OfReal fd;
1025 TColStd_SequenceOfReal aTSeq, aFSeq;
1028 myParallel=Standard_True;
1033 // Table of derivatives
1034 fd(0)=(f(1)-f(0))/(t(1)-t(0));
1035 if (fabs(fd(0)) < myEpsNull) {
1040 for (i=1; i<k; i++) {
1041 fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1));
1042 if (fabs(fd(i)) < myEpsNull) {
1047 fd(n-1)=(f(n-1)-f(n-2))/(t(n-1)-t(n-2));
1048 if (fabs(fd(n-1)) < myEpsNull) {
1052 // Finding the range where the derivatives have different signs
1053 // for neighbouring points
1054 for (i=1; i<n; i++) {
1055 Standard_Real fd1, fd2, t1, t2, fabsfd1, fabsfd2;
1056 Standard_Boolean bF1, bF2;
1063 bF1=fabsfd1 < myEpsNull;
1066 bF2=fabsfd2 < myEpsNull;
1069 tr=FindSimpleRoot(2, t1, t2, fd1);
1070 fr=DistanceFunction(tr);
1072 myParallel=Standard_False;
1080 myParallel=Standard_False;
1088 myParallel=Standard_False;
1094 //=======================================================================
1095 //function : RemoveIdenticalRoots
1097 //=======================================================================
1098 void IntTools_EdgeFace::RemoveIdenticalRoots()
1100 Standard_Integer aNbRoots, j, k;
1102 aNbRoots=mySequenceOfRoots.Length();
1103 for (j=1; j<=aNbRoots; j++) {
1104 const IntTools_Root& aRj=mySequenceOfRoots(j);
1105 for (k=j+1; k<=aNbRoots; k++) {
1106 const IntTools_Root& aRk=mySequenceOfRoots(k);
1108 Standard_Real aTj, aTk, aDistance;
1117 aDistance=aPj.Distance(aPk);
1118 if (aDistance < myCriteria) {
1119 mySequenceOfRoots.Remove(k);
1120 aNbRoots=mySequenceOfRoots.Length();
1126 //=======================================================================
1127 //function : CheckTouch
1129 //=======================================================================
1130 Standard_Boolean IntTools_EdgeFace::CheckTouch(const IntTools_CommonPrt& aCP,
1133 Standard_Real aTF, aTL, Tol, U1f, U1l, V1f, V1l, af, al,aDist2, aMinDist2;
1134 Standard_Boolean theflag=Standard_False;
1135 Standard_Integer aNbExt, i, iLower ;
1137 aCP.Range1(aTF, aTL);
1141 aCR=myC.Resolution(myCriteria);
1142 if((Abs(aTF - myRange.First()) < aCR) &&
1143 (Abs(aTL - myRange.Last()) < aCR)) {
1144 return theflag; // EDGE
1148 Tol = Precision::PConfusion();
1150 const Handle(Geom_Curve)& Curve =BRep_Tool::Curve (myC.Edge(), af, al);
1151 const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
1152 // Surface->Bounds(U1f,U1l,V1f,V1l);
1153 U1f = myS.FirstUParameter();
1154 U1l = myS.LastUParameter();
1155 V1f = myS.FirstVParameter();
1156 V1l = myS.LastVParameter();
1158 GeomAdaptor_Curve TheCurve (Curve,aTF, aTL);
1159 GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l);
1161 Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
1165 if(anExtrema.IsDone()) {
1168 if(!anExtrema.IsParallel()) {
1169 aNbExt=anExtrema.NbExt();
1173 for (i=1; i<=aNbExt; i++) {
1174 aDist2=anExtrema.SquareDistance(i);
1175 if (aDist2 < aMinDist2) {
1180 aDist2=anExtrema.SquareDistance(iLower);
1181 Extrema_POnCurv aPOnC;
1182 Extrema_POnSurf aPOnS;
1183 anExtrema.Points(iLower, aPOnC, aPOnS);
1184 aTx=aPOnC.Parameter();
1187 // modified by NIZHNY-MKK Thu Jul 21 11:35:32 2005.BEGIN
1188 IntCurveSurface_HInter anExactIntersector;
1190 Handle(GeomAdaptor_HCurve) aCurve = new GeomAdaptor_HCurve(TheCurve);
1191 Handle(GeomAdaptor_HSurface) aSurface = new GeomAdaptor_HSurface(TheSurface);
1193 anExactIntersector.Perform(aCurve, aSurface);
1195 if(anExactIntersector.IsDone()) {
1196 Standard_Integer i = 0;
1198 for(i = 1; i <= anExactIntersector.NbPoints(); i++) {
1199 const IntCurveSurface_IntersectionPoint& aPoint = anExactIntersector.Point(i);
1201 if((aPoint.W() >= aTF) && (aPoint.W() <= aTL)) {
1207 // modified by NIZHNY-MKK Thu Jul 21 11:35:40 2005.END
1215 Standard_Real aBoundaryDist;
1217 aBoundaryDist = DistanceFunction(aTF) + myCriteria;
1218 if(aBoundaryDist * aBoundaryDist < aDist2) {
1219 aDist2 = aBoundaryDist * aBoundaryDist;
1223 aBoundaryDist = DistanceFunction(aTL) + myCriteria;
1224 if(aBoundaryDist * aBoundaryDist < aDist2) {
1225 aDist2 = aBoundaryDist * aBoundaryDist;
1229 Standard_Real aParameter = (aTF + aTL) * 0.5;
1230 aBoundaryDist = DistanceFunction(aParameter) + myCriteria;
1231 if(aBoundaryDist * aBoundaryDist < aDist2) {
1232 aDist2 = aBoundaryDist * aBoundaryDist;
1236 if(aDist2 > myCriteria * myCriteria) {
1240 if (fabs (aTx-aTF) < myEpsT) {
1244 if (fabs (aTx-aTL) < myEpsT) {
1248 if (aTx>aTF && aTx<aTL) {
1256 //=======================================================================
1257 //function : Perform
1259 //=======================================================================
1260 void IntTools_EdgeFace::Perform()
1262 Standard_Integer i, aNb;
1263 IntTools_CommonPrt aCommonPrt;
1265 aCommonPrt.SetEdge1(myEdge);
1269 if (myErrorStatus) {
1273 if (myContext.IsNull()) {
1274 myContext=new BOPInt_Context;
1277 myIsDone = Standard_False;
1278 myC.Initialize(myEdge);
1279 GeomAbs_CurveType aCurveType;
1280 aCurveType=myC.GetType();
1282 // Prepare myCriteria
1283 if (aCurveType==GeomAbs_BSplineCurve||
1284 aCurveType==GeomAbs_BezierCurve) {
1286 Standard_Real diff1 = (myTolE/myTolF);
1287 Standard_Real diff2 = (myTolF/myTolE);
1288 if( diff1 > 100 || diff2 > 100 ) {
1289 myCriteria = Max(myTolE,myTolF);
1292 myCriteria=1.5*myTolE+myTolF;
1295 myCriteria=myTolE+myTolF;
1298 myTmin=myRange.First();
1299 myTmax=myRange.Last();
1301 myS.Initialize (myFace,Standard_True);
1303 if(myContext.IsNull()) {
1304 myFClass2d.Init(myFace, 1.e-6);
1307 IntTools_BeanFaceIntersector anIntersector(myC, myS, myTolE, myTolF);
1308 anIntersector.SetBeanParameters(myRange.First(), myRange.Last());
1310 anIntersector.SetContext(myContext);
1312 anIntersector.Perform();
1314 if(!anIntersector.IsDone()) {
1318 for(Standard_Integer r = 1; r <= anIntersector.Result().Length(); r++) {
1319 const IntTools_Range& aRange = anIntersector.Result().Value(r);
1321 if(IsProjectable(IntTools_Tools::IntermediatePoint(aRange.First(), aRange.Last()))) {
1322 aCommonPrt.SetRange1(aRange.First(), aRange.Last());
1323 mySeqOfCommonPrts.Append(aCommonPrt);
1327 aNb = mySeqOfCommonPrts.Length();
1329 for (i=1; i<=aNb; i++) {
1330 IntTools_CommonPrt& aCP=mySeqOfCommonPrts.ChangeValue(i);
1332 Standard_Real aTx1, aTx2;
1335 aCP.Range1(aTx1, aTx2);
1338 aCP.SetBoundingPoints(aPx1, aPx2);
1343 // Line\Cylinder's Common Parts treatement
1344 GeomAbs_CurveType aCType;
1345 GeomAbs_SurfaceType aSType;
1346 TopAbs_ShapeEnum aType;
1347 Standard_Boolean bIsTouch;
1350 aCType=myC.GetType();
1351 aSType=myS.GetType();
1353 if (aCType==GeomAbs_Line && aSType==GeomAbs_Cylinder) {
1354 for (i=1; i<=aNb; i++) {
1355 IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
1357 if (aType==TopAbs_EDGE) {
1358 bIsTouch=CheckTouch (aCP, aTx);
1360 aCP.SetType(TopAbs_VERTEX);
1361 aCP.SetVertexParameter1(aTx);
1362 aCP.SetRange1 (aTx, aTx);
1365 if (aType==TopAbs_VERTEX) {
1366 bIsTouch=CheckTouchVertex (aCP, aTx);
1368 aCP.SetVertexParameter1(aTx);
1369 aCP.SetRange1 (aTx, aTx);
1375 // Circle\Plane's Common Parts treatement
1377 if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1378 Standard_Boolean bIsCoplanar, bIsRadius;
1379 bIsCoplanar=IsCoplanar(myC, myS);
1380 bIsRadius=IsRadius(myC, myS);
1381 if (!bIsCoplanar && !bIsRadius) {
1382 for (i=1; i<=aNb; i++) {
1383 IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
1385 if (aType==TopAbs_EDGE) {
1386 bIsTouch=CheckTouch (aCP, aTx);
1388 aCP.SetType(TopAbs_VERTEX);
1389 aCP.SetVertexParameter1(aTx);
1390 aCP.SetRange1 (aTx, aTx);
1397 myIsDone=Standard_True;
1402 // 1 - the method Perform() is not invoked
1403 // 2,3,4,5 -the method CheckData() fails
1404 // 6 - PrepareArgs() problems
1405 // 7 - No Projectable ranges
1406 // 8,9 - PrepareArgs() problems occured inside projectable Ranges
1407 // 11 - can't fill array aFunc(i) in PrepareArgsFuncArrays
1410 //=======================================================================
1411 //function : CheckTouch
1413 //=======================================================================
1414 Standard_Boolean IntTools_EdgeFace::CheckTouchVertex (const IntTools_CommonPrt& aCP,
1417 Standard_Real aTF, aTL, Tol, U1f,U1l,V1f,V1l, af, al,aDist2, aMinDist2, aTm, aDist2New;
1418 Standard_Real aEpsT;
1419 Standard_Boolean theflag=Standard_False;
1420 Standard_Integer aNbExt, i, iLower ;
1422 aCP.Range1(aTF, aTL);
1425 aDist2=DistanceFunction(aTm);
1428 Tol = Precision::PConfusion();
1430 const Handle(Geom_Curve)& Curve =BRep_Tool::Curve (myC.Edge(), af, al);
1431 const Handle(Geom_Surface)& Surface=BRep_Tool::Surface(myS.Face());
1433 Surface->Bounds(U1f,U1l,V1f,V1l);
1435 GeomAdaptor_Curve TheCurve (Curve,aTF, aTL);
1436 GeomAdaptor_Surface TheSurface (Surface, U1f, U1l, V1f, V1l);
1438 Extrema_ExtCS anExtrema (TheCurve, TheSurface, Tol, Tol);
1440 if(!anExtrema.IsDone()) {
1443 if (anExtrema.IsParallel()) {
1447 aNbExt=anExtrema.NbExt() ;
1454 for (i=1; i<=aNbExt; ++i) {
1455 aDist2=anExtrema.SquareDistance(i);
1456 if (aDist2 < aMinDist2) {
1462 aDist2New=anExtrema.SquareDistance(iLower);
1464 if (aDist2New > aDist2) {
1469 if (aDist2New > myCriteria * myCriteria) {
1473 Extrema_POnCurv aPOnC;
1474 Extrema_POnSurf aPOnS;
1475 anExtrema.Points(iLower, aPOnC, aPOnS);
1478 aTx=aPOnC.Parameter();
1480 if (fabs (aTx-aTF) < aEpsT) {
1484 if (fabs (aTx-aTL) < aEpsT) {
1488 if (aTx>aTF && aTx<aTL) {
1496 //=======================================================================
1497 //function : IsCoplanar
1499 //=======================================================================
1500 Standard_Boolean IsCoplanar (const BRepAdaptor_Curve& aCurve ,
1501 const BRepAdaptor_Surface& aSurface)
1503 Standard_Boolean bFlag=Standard_False;
1505 GeomAbs_CurveType aCType;
1506 GeomAbs_SurfaceType aSType;
1508 aCType=aCurve.GetType();
1509 aSType=aSurface.GetType();
1511 if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1512 gp_Circ aCirc=aCurve.Circle();
1513 const gp_Ax1& anAx1=aCirc.Axis();
1514 const gp_Dir& aDirAx1=anAx1.Direction();
1516 gp_Pln aPln=aSurface.Plane();
1517 const gp_Ax1& anAx=aPln.Axis();
1518 const gp_Dir& aDirPln=anAx.Direction();
1520 bFlag=IntTools_Tools::IsDirsCoinside(aDirAx1, aDirPln);
1524 //=======================================================================
1525 //function : IsRadius
1527 //=======================================================================
1528 Standard_Boolean IsRadius (const BRepAdaptor_Curve& aCurve ,
1529 const BRepAdaptor_Surface& aSurface)
1531 Standard_Boolean bFlag=Standard_False;
1533 GeomAbs_CurveType aCType;
1534 GeomAbs_SurfaceType aSType;
1536 aCType=aCurve.GetType();
1537 aSType=aSurface.GetType();
1539 if (aCType==GeomAbs_Circle && aSType==GeomAbs_Plane) {
1540 gp_Circ aCirc=aCurve.Circle();
1541 const gp_Pnt aCenter=aCirc.Location();
1542 Standard_Real aR=aCirc.Radius();
1543 gp_Pln aPln=aSurface.Plane();
1544 Standard_Real aD=aPln.Distance(aCenter);
1545 if (fabs (aD-aR) < 1.e-7) {
1552 //=======================================================================
1553 //function : AdaptiveDiscret
1555 //=======================================================================
1556 Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret,
1557 const BRepAdaptor_Curve& aCurve ,
1558 const BRepAdaptor_Surface& aSurface)
1560 Standard_Integer iDiscretNew;
1562 iDiscretNew=iDiscret;
1564 GeomAbs_CurveType aCType;
1565 GeomAbs_SurfaceType aSType;
1567 aCType=aCurve.GetType();
1568 aSType=aSurface.GetType();
1570 if (aSType==GeomAbs_Cylinder) {
1571 Standard_Real aELength, aRadius, dL, dLR;
1573 aELength=IntTools::Length(aCurve.Edge());
1574 dL=aELength/iDiscret;
1576 gp_Cylinder aCylinder=aSurface.Cylinder();
1577 aRadius=aCylinder.Radius();
1580 iDiscretNew=(Standard_Integer)(aELength/dLR);
1582 if (iDiscretNew<iDiscret) {
1583 iDiscretNew=iDiscret;
1592 #pragma warning ( default : 4101 )