1 // Created on: 2000-10-26
2 // Created by: Peter KURNEV
3 // Copyright (c) 2000-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_EdgeEdge.ixx>
18 #include <Precision.hxx>
20 #include <TColStd_SequenceOfReal.hxx>
22 #include <gp_Circ.hxx>
29 #include <Geom_Curve.hxx>
31 #include <Geom_BSplineCurve.hxx>
32 #include <GeomAdaptor_Curve.hxx>
34 #include <CPnts_AbscissaPoint.hxx>
36 #include <GeomAPI_ProjectPointOnCurve.hxx>
38 #include <Extrema_ExtElC.hxx>
39 #include <Extrema_POnCurv.hxx>
40 #include <Extrema_ExtCC.hxx>
42 #include <TopoDS_Iterator.hxx>
43 #include <BRep_Tool.hxx>
45 #include <IntTools.hxx>
46 #include <IntTools_Range.hxx>
47 #include <IntTools_CArray1OfReal.hxx>
48 #include <IntTools_CommonPrt.hxx>
49 #include <IntTools_SequenceOfRanges.hxx>
50 #include <IntTools_Tools.hxx>
51 #include <IntTools_BeanBeanIntersector.hxx>
54 //=======================================================================
55 //function : IntTools_EdgeEdge::IntTools_EdgeEdge
57 //=======================================================================
58 IntTools_EdgeEdge::IntTools_EdgeEdge()
66 myIsDone=Standard_False;
68 myOrder=Standard_False;
71 myParallel=Standard_False;
74 //=======================================================================
77 //=======================================================================
78 void IntTools_EdgeEdge::SetEdge1(const TopoDS_Edge& anEdge)
82 //=======================================================================
85 //=======================================================================
86 void IntTools_EdgeEdge::SetEdge2(const TopoDS_Edge& anEdge)
91 //=======================================================================
92 //function : SetTolerance1
94 //=======================================================================
95 void IntTools_EdgeEdge::SetTolerance1(const Standard_Real aTol)
99 //=======================================================================
100 //function : SetTolerance2
102 //=======================================================================
103 void IntTools_EdgeEdge::SetTolerance2(const Standard_Real aTol)
108 //=======================================================================
109 //function : SetDiscretize
111 //=======================================================================
112 void IntTools_EdgeEdge::SetDiscretize(const Standard_Integer aDiscret)
116 //=======================================================================
117 //function : SetDeflection
119 //=======================================================================
120 void IntTools_EdgeEdge::SetDeflection(const Standard_Real aDefl)
124 //=======================================================================
125 //function : SetEpsilonT
127 //=======================================================================
128 void IntTools_EdgeEdge::SetEpsilonT(const Standard_Real anEpsT)
132 //=======================================================================
133 //function : SetEpsilonNull
135 //=======================================================================
136 void IntTools_EdgeEdge::SetEpsilonNull(const Standard_Real anEpsNull)
141 //=======================================================================
142 //function : SetRange1
144 //=======================================================================
145 void IntTools_EdgeEdge::SetRange1(const Standard_Real aFirst,
146 const Standard_Real aLast)
148 myRange1.SetFirst (aFirst);
149 myRange1.SetLast (aLast);
151 //=======================================================================
152 //function : SetRange2
154 //=======================================================================
155 void IntTools_EdgeEdge::SetRange2(const Standard_Real aFirst,
156 const Standard_Real aLast)
158 myRange2.SetFirst (aFirst);
159 myRange2.SetLast (aLast);
162 //=======================================================================
163 //function : SetRange1
165 //=======================================================================
166 void IntTools_EdgeEdge::SetRange1(const IntTools_Range& aRange)
168 myRange1.SetFirst (aRange.First());
169 myRange1.SetLast (aRange.Last());
171 //=======================================================================
172 //function : SetRange2
174 //=======================================================================
175 void IntTools_EdgeEdge::SetRange2(const IntTools_Range& aRange)
177 myRange2.SetFirst (aRange.First());
178 myRange2.SetLast (aRange.Last());
181 //=======================================================================
184 //=======================================================================
185 Standard_Boolean IntTools_EdgeEdge::Order()const
189 //=======================================================================
192 //=======================================================================
193 Standard_Boolean IntTools_EdgeEdge::IsDone()const
197 //=======================================================================
198 //function : ErrorStatus
200 //=======================================================================
201 Standard_Integer IntTools_EdgeEdge::ErrorStatus()const
203 return myErrorStatus;
206 //=======================================================================
207 //function : CommonParts
209 //=======================================================================
210 const IntTools_SequenceOfCommonPrts& IntTools_EdgeEdge::CommonParts() const
212 return mySeqOfCommonPrts;
214 //=======================================================================
217 //=======================================================================
218 const IntTools_Range& IntTools_EdgeEdge::Range1() const
222 //=======================================================================
225 //=======================================================================
226 const IntTools_Range& IntTools_EdgeEdge::Range2() const
230 //=======================================================================
233 //=======================================================================
234 void IntTools_EdgeEdge::Perform()
236 Standard_Boolean bIsSameCurves;
237 Standard_Integer i, pri, aNbCommonPrts, aNbRange;
238 Standard_Real aT1, aT2, aPC;
239 IntTools_CommonPrt aCommonPrt;
240 GeomAbs_CurveType aCTFrom, aCTTo;
242 myIsDone=Standard_False;
255 aCTFrom = myCFrom.GetType();
256 aCTTo = myCTo.GetType();
258 if(aCTFrom==GeomAbs_Line && aCTTo==GeomAbs_Line) {
269 bIsSameCurves=IsSameCurves();
271 aCommonPrt.SetType(TopAbs_EDGE);
272 aCommonPrt.SetRange1 (myTminFrom, myTmaxFrom);
273 aCommonPrt.AppendRange2 (myTminTo, myTmaxTo);
274 mySeqOfCommonPrts.Append(aCommonPrt);
275 myIsDone=Standard_True;
279 IntTools_BeanBeanIntersector anIntersector(myCFrom, myCTo, myTolFrom, myTolTo);
280 anIntersector.SetBeanParameters(Standard_True, myTminFrom, myTmaxFrom);
281 anIntersector.SetBeanParameters(Standard_False, myTminTo, myTmaxTo);
283 anIntersector.Perform();
284 if(!anIntersector.IsDone()) {
285 myIsDone = Standard_False;
289 aPC=Precision::PConfusion();
290 aCommonPrt.SetEdge1(myCFrom.Edge());
291 aCommonPrt.SetEdge2(myCTo.Edge());
293 const IntTools_SequenceOfRanges& aSR=anIntersector.Result();
294 aNbRange=aSR.Length();
295 for(i=1; i <=aNbRange; ++i) {
296 const IntTools_Range& aRange =aSR.Value(i);
300 if(IsProjectable(IntTools_Tools::IntermediatePoint(aT1, aT2))) {
301 aCommonPrt.SetRange1(aT1, aT2);
303 if(((aT1 - myTminFrom)<aPC) && ((myTmaxFrom - aT2)<aPC)) {
304 aCommonPrt.SetAllNullFlag(Standard_True);
306 mySeqOfCommonPrts.Append(aCommonPrt);
310 aNbCommonPrts=mySeqOfCommonPrts.Length();
311 for (i=1; i<=aNbCommonPrts; ++i) {
312 IntTools_CommonPrt& aCmnPrt=mySeqOfCommonPrts.ChangeValue(i);
313 pri=FindRangeOnCurve2 (aCmnPrt);
320 // Line Circle's Common Parts treatement
321 if ((aCTFrom==GeomAbs_Line && aCTTo==GeomAbs_Circle) ||
322 (aCTFrom==GeomAbs_Circle && aCTTo==GeomAbs_Line) ||
323 (aCTFrom==GeomAbs_Ellipse && aCTTo==GeomAbs_Ellipse) ||
324 (aCTFrom==GeomAbs_Circle && aCTTo==GeomAbs_Circle)) {
325 for (i=1; i<=aNbCommonPrts; i++) {
326 IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
327 TopAbs_ShapeEnum aType=aCP.Type();
328 Standard_Boolean bIsTouch;
329 Standard_Real aTx1, aTx2;
331 if ((aType==TopAbs_EDGE) && !aCommonPrt.AllNullFlag()) {
332 bIsTouch=CheckTouch (aCP, aTx1, aTx2);
334 aCP.SetType(TopAbs_VERTEX);
335 aCP.SetVertexParameter1(aTx1);
336 aCP.SetRange1 (aTx1, aTx1);
337 IntTools_Range& aRange2=(aCP.ChangeRanges2()).ChangeValue(1);
338 aRange2.SetFirst(aTx2);
339 aRange2.SetLast (aTx2);
343 if (aType==TopAbs_VERTEX) {
344 if(aCTFrom==GeomAbs_Line || aCTTo==GeomAbs_Line) {
345 bIsTouch=CheckTouchVertex (aCP, aTx1, aTx2);
347 aCP.SetVertexParameter1(aTx1);
348 aCP.SetRange1 (aTx1, aTx1);
349 IntTools_Range& aRange2=(aCP.ChangeRanges2()).ChangeValue(1);
350 aRange2.SetFirst(aTx2);
351 aRange2.SetLast (aTx2);
365 myIsDone=Standard_True;
368 //=======================================================================
369 //function : CheckData
371 //=======================================================================
372 void IntTools_EdgeEdge::CheckData()
374 if (BRep_Tool::Degenerated(myEdge1)) {
377 if (!BRep_Tool::IsGeometric(myEdge1)) {
380 if (BRep_Tool::Degenerated(myEdge2)) {
383 if (!BRep_Tool::IsGeometric(myEdge2)) {
387 //=======================================================================
390 //=======================================================================
391 void IntTools_EdgeEdge::Prepare()
393 Standard_Real aLE1, aLE2, aT1, aT2, aTol1, aTol2;
394 GeomAdaptor_Curve aGAC;
395 GeomAbs_CurveType aCT1, aCT2;
397 // 1.Prepare Curves' data
398 const Handle(Geom_Curve)& aC1=BRep_Tool::Curve (myEdge1, aT1, aT2);
399 aT1=myRange1.First();
401 aGAC.Load(aC1, myRange1.First(), myRange1.Last());
402 aLE1=CPnts_AbscissaPoint::Length(aGAC, aT1, aT2);
404 const Handle(Geom_Curve)& aC2=BRep_Tool::Curve (myEdge2, aT1, aT2);
405 aT1=myRange2.First();
407 aGAC.Load(aC2, aT1, aT2);
408 aLE2=CPnts_AbscissaPoint::Length(aGAC, aT1, aT2);
410 myOrder=Standard_False;
412 myCFrom.Initialize(myEdge1);
413 myCTo .Initialize(myEdge2);
416 myTminFrom=myRange1.First();
417 myTmaxFrom=myRange1.Last ();
418 myTminTo =myRange2.First();
419 myTmaxTo =myRange2.Last ();
422 myCFrom.Initialize(myEdge2);
423 myCTo .Initialize(myEdge1);
426 myTminFrom=myRange2.First();
427 myTmaxFrom=myRange2.Last ();
428 myTminTo =myRange1.First();
429 myTmaxTo =myRange1.Last ();
431 myOrder=Standard_True; // revesed order
434 // 2.Prepare myCriteria
435 aCT1=myCFrom.GetType();
436 aCT2=myCTo.GetType();
439 if(aCT1==GeomAbs_BSplineCurve|| aCT1==GeomAbs_BezierCurve){
443 if(aCT2==GeomAbs_BSplineCurve|| aCT2==GeomAbs_BezierCurve){
446 myCriteria=aTol1+aTol2;
448 //=======================================================================
449 //function : IsProjectable
451 //=======================================================================
452 Standard_Integer IntTools_EdgeEdge::IsProjectable(const Standard_Real t) const
454 Standard_Integer aNbProj;
458 GeomAPI_ProjectPointOnCurve aProjector;
459 const TopoDS_Edge& aEFrom=myCFrom.Edge();
460 Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (aEFrom, f, l);
461 aCurveFrom->D0(t, aPFrom);
463 Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (myCTo.Edge(), f, l);
464 aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
465 aProjector.Perform(aPFrom);
466 aNbProj=aProjector.NbPoints();
468 if (myCTo.GetType()==GeomAbs_Circle) {
469 gp_Circ aCirc=myCTo.Circle();
470 const gp_Pnt& aCenter=aCirc.Location();
471 if (aCenter.SquareDistance(aPFrom) < 1.e-7) {
478 //=======================================================================
479 //function : DistanceFunction
481 //=======================================================================
482 Standard_Real IntTools_EdgeEdge::DistanceFunction(const Standard_Real t)//const
484 Standard_Real aD, f, l;
485 GeomAPI_ProjectPointOnCurve aProjector;
486 gp_Pnt aPFrom; //ZZ , aPTo;
488 const TopoDS_Edge& aEFrom=myCFrom.Edge();
489 const TopoDS_Edge& aETo =myCTo.Edge();
491 Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (aEFrom, f, l);
492 aCurveFrom->D0 (t, aPFrom);
493 Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (aETo, f, l);
495 if (myCTo.GetType()==GeomAbs_Circle) {
496 gp_Circ aCirc=myCTo.Circle();
497 const gp_Pnt& aCenter=aCirc.Location();
498 const gp_Ax1& anAx1 =aCirc.Axis();
499 const gp_Dir& aDir =anAx1.Direction();
500 gp_Lin aLin(aCenter, aDir);
501 Standard_Real dPFromLin=aLin.Distance(aPFrom);
502 if (dPFromLin < 1.e-7) {
504 aCurveTo->D0 (myTminTo, anAnyPTo);
505 aD=aPFrom.Distance(anAnyPTo);
512 aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
513 aProjector.Perform(aPFrom);
515 Standard_Integer j, aNbPoints;
517 aNbPoints =aProjector.NbPoints();
519 for (j=0; j<=1; j++) {
526 aCurveFrom->D0 (tt, aPFrom);
527 aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
528 aProjector.Perform(aPFrom);
529 aNbPoints=aProjector.NbPoints();
538 // Can't find projection.
544 aD=aProjector.LowerDistance();
550 //=======================================================================
551 //function : DerivativeFunction
553 //=======================================================================
554 Standard_Real IntTools_EdgeEdge::DerivativeFunction(const Standard_Real t2)
556 Standard_Real t1, t3, aD1, aD2, aD3;
557 Standard_Real dt=1.e-7;
559 aD1=DistanceFunction(t1);
561 aD3=DistanceFunction(t3);
568 //=======================================================================
569 //function : FindSimpleRoot
570 //purpose : [private]
571 //=======================================================================
572 Standard_Real IntTools_EdgeEdge::FindSimpleRoot (const Standard_Integer IP,
573 const Standard_Real tA,
574 const Standard_Real tB,
575 const Standard_Real fA)
577 Standard_Real r, a, b, y, x0, s;
581 Standard_Integer step = 1, stepcheck = 1000, steplimit = 100000;
582 Standard_Real value = (IP==1) ? DistanceFunction(0.5*(a+b)) : DerivativeFunction(0.5*(a+b));
588 y=DistanceFunction(x0);
590 y=DerivativeFunction(x0);
592 Standard_Real aMaxAB100 = 100.*Max(a, b);
593 Standard_Real anEps = Epsilon(aMaxAB100);
594 Standard_Real anEpsT = Max(anEps, myEpsT);
595 // if (fabs(b-a) < myEpsT || y==0.) {
596 if (fabs(b-a) < anEpsT || y==0.) {
600 if( step == stepcheck ) {
601 if( Abs(value - y) <= 1.e-9 ) {
610 if( step == steplimit ) {
630 //=======================================================================
631 //function : FindRangeOnCurve2
633 //=======================================================================
634 Standard_Integer IntTools_EdgeEdge::FindRangeOnCurve2(IntTools_CommonPrt& aCommonPrt)
636 Standard_Integer pri;
639 if (aCommonPrt.AllNullFlag()) {
640 aCommonPrt.SetType(TopAbs_EDGE);
641 aCommonPrt.AppendRange2 (myTminTo, myTmaxTo);
645 Standard_Real ttmp, f, l, af1, al1, am1, af2, al2, am2;
646 gp_Pnt aPf1, aPl1, aPm1, aPf2, aPl2, aPm2;
647 GeomAPI_ProjectPointOnCurve aProjector;
649 aCommonPrt.Range1(af1, al1);
652 const TopoDS_Edge& anEdgeTo=myCTo.Edge();
653 Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (anEdgeTo, f, l);
655 const TopoDS_Edge& anEdgeFrom=myCFrom.Edge();
656 Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f, l);
659 aCurveFrom->D0 (af1, aPf1);
660 pri=GetParameterOnCurve2 (af1, af2);
664 aCurveTo->D0(af2, aPf2);
667 aCurveFrom->D0 (al1, aPl1);
668 pri=GetParameterOnCurve2 (al1, al2);
672 aCurveTo->D0(al2, aPl2);
675 aCurveFrom->D0 (am1, aPm1);
676 pri=GetParameterOnCurve2 (am1, am2);
680 aCurveTo->D0(am2, aPm2);
682 // Reverse C2 points if it is necessary
683 Standard_Boolean reverse = (af2 > al2);
695 if((Abs(af2 - myTminTo) < Precision::PConfusion()) &&
696 (Abs(al2 - myTmaxTo) < Precision::PConfusion())) {
697 aCommonPrt.SetAllNullFlag(Standard_True);
701 Standard_Boolean aVFlag1, aVFlag2, aGeomFlag1, aGeomFlag2;
702 Standard_Real Df2m2, Dm2l2, Df2l2, df2m2, dm2l2, df2l2, df1m1, dm1l1, df1l1;
703 Standard_Real tV1, tV2;
705 // parametric differences for C2
710 // geometric distances for C2
711 df2m2=aPf2.Distance(aPm2);
712 dm2l2=aPm2.Distance(aPl2);
713 df2l2=aPf2.Distance(aPl2);
715 aVFlag1=(Df2m2<myEpsT && Dm2l2<myEpsT);
716 aVFlag2=(df2m2 < myCriteria && dm2l2 < myCriteria);
719 // Two perpendicular lines => VERTEX
720 if ( aVFlag1 && aVFlag2) {
722 aCommonPrt.SetType(TopAbs_VERTEX);
723 pri=TreatVertexType(am1, am2, aCommonPrt);
727 aCommonPrt.SetVertexParameter2(tV2);
728 aCommonPrt.AppendRange2 (af2, al2);
731 aCommonPrt.SetVertexParameter1(tV1);
732 aCommonPrt.SetRange1 (af1, al1);
737 // geometric distances for C1
738 df1m1=aPf1.Distance(aPm1);
739 dm1l1=aPm1.Distance(aPl1);
740 df1l1=aPf1.Distance(aPl1);
742 // if geometric distances between boundaries is less than myCriteria
744 aGeomFlag1=(df1l1 < myCriteria);
745 aGeomFlag2=(df2l2 < myCriteria);
746 if (aGeomFlag1 && aGeomFlag2) {
747 aCommonPrt.SetType(TopAbs_VERTEX);
750 aCommonPrt.SetVertexParameter2(tV2);
751 aCommonPrt.AppendRange2 (af2, al2);
754 aCommonPrt.SetVertexParameter1(tV1);
755 aCommonPrt.SetRange1 (af1, al1);
760 if (Df2l2 < myEpsT && !aVFlag1) {
761 if (aPf1.Distance(aPl1) < myCriteria && aPf2.Distance(aPl2) < myCriteria) {
764 aCommonPrt.AppendRange2 (af1, al2);
765 aCommonPrt.SetType(TopAbs_EDGE);
770 aProjector.Init(aCurveFrom, myTminFrom, myTmaxFrom);
771 aProjector.Perform(aPm2);
772 Standard_Integer aNbPoints=aProjector.NbPoints();
774 Standard_Real aDD=aProjector.LowerDistance();
775 if (aDD > myCriteria) {
777 aCommonPrt.SetType(TopAbs_EDGE);
778 aCommonPrt.AppendRange2 (myTminTo, af2);
779 aCommonPrt.AppendRange2 (al2, myTmaxTo);
785 aCommonPrt.SetType(TopAbs_EDGE);
786 aCommonPrt.AppendRange2 (myTminTo, af2);
787 aCommonPrt.AppendRange2 (al2, myTmaxTo);
791 IsIntersection (af1, al1);
792 if (!myParallel && !aCommonPrt.AllNullFlag()) {
794 GetParameterOnCurve2 (myPar1, aPar2);
795 aCommonPrt.SetType(TopAbs_VERTEX);
797 Standard_Boolean IsmyPar1 = Standard_True;
799 if(Abs(af1-myTminFrom) < Precision::PConfusion()) {
800 IsmyPar1 = Standard_False;
801 aCommonPrt.SetVertexParameter1(af1);
803 aCommonPrt.SetVertexParameter2(al2);
805 aCommonPrt.SetVertexParameter2(af2);
808 if(Abs(al1-myTmaxFrom) < Precision::PConfusion()) {
809 IsmyPar1 = Standard_False;
810 aCommonPrt.SetVertexParameter1(al1);
813 aCommonPrt.SetVertexParameter2(af2);
815 aCommonPrt.SetVertexParameter2(al2);
818 if(Abs(af2-myTminTo) < Precision::PConfusion()) {
819 IsmyPar1 = Standard_False;
820 aCommonPrt.SetVertexParameter2(af2);
823 aCommonPrt.SetVertexParameter1(al1);
825 aCommonPrt.SetVertexParameter1(af1);
828 if(Abs(al2-myTmaxTo) < Precision::PConfusion()) {
829 IsmyPar1 = Standard_False;
830 aCommonPrt.SetVertexParameter2(al2);
833 aCommonPrt.SetVertexParameter1(af1);
835 aCommonPrt.SetVertexParameter1(al1);
837 // aCommonPrt.SetVertexParameter1(myPar1);
838 // aCommonPrt.SetRange1 (af1, al1);
840 // aCommonPrt.SetVertexParameter2(aPar2);
842 aCommonPrt.SetVertexParameter1(myPar1);
843 aCommonPrt.SetRange1 (af1, al1);
845 aCommonPrt.SetVertexParameter2(aPar2);
847 aCommonPrt.AppendRange2 (af2, al2);
853 aCommonPrt.SetType(TopAbs_EDGE);
854 aCommonPrt.AppendRange2 (af2, al2);
858 //=======================================================================
859 //function : IsIntersection
861 //=======================================================================
862 void IntTools_EdgeEdge::IsIntersection (const Standard_Real ta,
863 const Standard_Real tb)
865 Standard_Integer i, aNb, pri;
867 GeomAbs_CurveType aCT1, aCT2;
868 IntTools_CArray1OfReal anArgs, aFunc;
870 aCT1=myCFrom.GetType();
871 aCT2=myCTo.GetType();
872 if((aCT1==GeomAbs_Line) && (aCT2==GeomAbs_Line)) {
873 const Handle(Geom_Curve)& Curve1=BRep_Tool::Curve (myCFrom.Edge(), t, f);
874 const Handle(Geom_Curve)& Curve2=BRep_Tool::Curve (myCTo.Edge() , t, f);
876 GeomAdaptor_Curve TheCurve1 (Curve1);
877 GeomAdaptor_Curve TheCurve2 (Curve2);
878 Extrema_ExtCC anExtrema (TheCurve1, TheCurve2);
880 if(anExtrema.IsDone() && anExtrema.IsParallel()) {
881 myParallel = Standard_True;
886 if (aCT1==GeomAbs_Circle && aCT2==GeomAbs_Circle) {
887 Standard_Boolean bIsDone, bIsParallel;
888 Standard_Integer aNbExt;
889 Standard_Real aD2, aCriteria2, aT1;
890 gp_Circ aCirc1, aCirc2;
891 Extrema_POnCurv aPC1, aPC2;
893 aCirc1=myCFrom.Circle();
894 aCirc2=myCTo.Circle();
896 Extrema_ExtElC aExtElC(aCirc1, aCirc2);
898 bIsDone=aExtElC.IsDone();
900 bIsParallel=aExtElC.IsParallel();
902 aCriteria2=myCriteria*myCriteria;
903 aNbExt=aExtElC.NbExt();
904 for (i=1; i<=aNbExt; ++i) {
905 aD2=aExtElC.SquareDistance(i);
906 if (aD2<aCriteria2) {
907 aExtElC.Points(i, aPC1, aPC2);
908 aT1=aPC1.Parameter();
909 if (aT1>ta && aT1<tb) {
911 myParallel=Standard_False;
920 // Prepare values of arguments for the interval [ta, tb]
921 pri=IntTools::PrepareArgs (myCFrom, tb, ta, myDiscret, myDeflection, anArgs);
925 for (i=0; i<aNb; i++) {
927 f=DistanceFunction(t);
928 if (fabs(f) < myEpsNull) {
933 FindDerivativeRoot(anArgs, aFunc);
937 //=======================================================================
938 //function : FindDerivativeRoot
940 //=======================================================================
941 void IntTools_EdgeEdge::FindDerivativeRoot(const IntTools_CArray1OfReal& t,
942 const IntTools_CArray1OfReal& f)
944 Standard_Integer i, n, k;
945 Standard_Real fr, tr, anEpsNull;
946 IntTools_CArray1OfReal fd;
947 TColStd_SequenceOfReal aTSeq, aFSeq;
949 anEpsNull=100.*myEpsNull;
951 myParallel=Standard_True;
956 // Table of derivatives
957 fd(0)=(f(1)-f(0))/(t(1)-t(0));
958 if (fabs(fd(0)) < anEpsNull) {
962 for (i=1; i<k; i++) {
963 fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1));
964 if (fabs(fd(i)) < anEpsNull) {
968 fd(n-1)=(f(n-1)-f(n-2))/(t(n-1)-t(n-2));
969 if (fabs(fd(n-1)) < anEpsNull) {
973 // Finding the range where the derivatives have different signs
974 // for neighbouring points
975 for (i=1; i<n; i++) {
976 Standard_Real fd1, fd2, t1, t2, fabsfd1, fabsfd2;
977 Standard_Boolean bF1, bF2;
984 bF1=fabsfd1 < myEpsNull;
987 bF2=fabsfd2 < myEpsNull;
991 tr=FindSimpleRoot(2, t1, t2, fd1);
992 fr=DistanceFunction(tr);
994 myParallel=Standard_False;
1002 myParallel=Standard_False;
1010 myParallel=Standard_False;
1017 //=======================================================================
1018 //function : GetParameterOnCurve2
1020 //=======================================================================
1021 Standard_Integer IntTools_EdgeEdge::GetParameterOnCurve2(const Standard_Real aT1,
1022 Standard_Real& aT2) const
1025 Standard_Integer j, found, aNbPoints;
1026 const TopoDS_Edge& anEdgeTo=myCTo.Edge();
1027 const TopoDS_Edge& anEdgeFrom=myCFrom.Edge();
1029 Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f, l);
1030 Handle(Geom_Curve)aCurveTo =BRep_Tool::Curve (anEdgeTo, f, l);
1033 aCurveFrom->D0 (aT1, aP1);
1034 GeomAPI_ProjectPointOnCurve aProjector;
1035 aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
1036 aProjector.Perform(aP1);
1037 aNbPoints=aProjector.NbPoints();
1041 for (j=0; j<=1; j++) {
1047 aCurveFrom->D0 (tt, aP1);
1048 aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
1049 aProjector.Perform(aP1);
1050 aNbPoints=aProjector.NbPoints();
1059 aCurveFrom->D0 (aT1, aP1);
1060 Standard_Real aDistance = RealLast();
1062 for(Standard_Integer pIt=0; pIt < 2; pIt++) {
1063 Standard_Real adist = aDistance;
1065 adist = aP1.Distance(aCurveTo->Value(myTminTo));
1067 adist = aP1.Distance(aCurveTo->Value(myTmaxTo));
1069 if(adist < myCriteria) {
1070 found = Standard_True;
1072 if(adist < aDistance) {
1073 aT2 = (pIt) ? myTminTo : myTmaxTo;
1087 for (j=1; j<=aNbPoints; j++) {
1088 aT2=aProjector.Parameter(j);
1089 f=aProjector.Distance(j);
1092 aT2=aProjector.LowerDistanceParameter();
1093 if (aT2 < myTminTo) {
1096 if (aT2 > myTmaxTo) {
1102 //=======================================================================
1103 //function : TreatVertexType
1105 //=======================================================================
1106 Standard_Integer IntTools_EdgeEdge::TreatVertexType(const Standard_Real am1,
1107 const Standard_Real am2,
1108 IntTools_CommonPrt& aCommonPrt)
1110 Standard_Real f1, l1, f2, l2, Alfa , aPeriod;
1111 gp_Pnt aPm1, aPm2, aP;
1115 const TopoDS_Edge& anEdgeFrom=myCFrom.Edge();
1116 Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f1, l1);
1117 aCurveFrom->D1 (am1, aPm1, aVm1);
1120 const TopoDS_Edge& anEdgeTo=myCTo.Edge();
1121 Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (anEdgeTo, f2, l2);
1122 aCurveTo->D1 (am2, aPm2, aVm2);
1125 Alfa=aVm1.Angle(aVm2);
1127 if (Alfa < Precision::Angular()) {
1131 Standard_Real sinAlfa, cosAlfa, dd, tf1, tl1, tf2, tl2, aL1, aL2;
1132 Standard_Integer ip;
1137 dd=aPm1.Distance(aPm2);
1139 if (dd>myCriteria) {
1142 aL2=(myTolTo*cosAlfa+myTolFrom)/sinAlfa;
1144 aP.SetXYZ(aPm2.XYZ()-aVm2.XYZ()*aL2);
1145 ip=IntTools::Parameter (aP, aCurveTo, tf2);
1150 if(aP.Distance(aCurveTo->Value(tf2)) > myTolTo)
1154 aP.SetXYZ(aPm2.XYZ()+aVm2.XYZ()*aL2);
1155 ip=IntTools::Parameter (aP, aCurveTo, tl2);
1160 if(aP.Distance(aCurveTo->Value(tl2)) > myTolTo)
1164 if (dd>myCriteria) {
1168 aL1=(myTolFrom*cosAlfa+myTolTo)/sinAlfa;
1170 aP.SetXYZ(aPm1.XYZ()-aVm1.XYZ()*aL1);
1171 ip=IntTools::Parameter (aP, aCurveFrom, tf1);
1176 if(aP.Distance(aCurveFrom->Value(tf1)) > myTolFrom)
1180 aP.SetXYZ(aPm1.XYZ()+aVm1.XYZ()*aL1);
1181 ip=IntTools::Parameter (aP, aCurveFrom, tl1);
1186 if(aP.Distance(aCurveFrom->Value(tl1)) > myTolFrom)
1190 if (aCurveFrom->IsPeriodic()) {
1191 aPeriod=aCurveFrom->Period();
1192 if (tf1<f1 || tf1>l1) {
1195 if (tl1<f1 || tl1>l1) {
1201 aCommonPrt.SetRange1 (tf1, tl1);
1202 aCommonPrt.SetVertexParameter1((tf1 + tl1) * 0.5);
1205 if (aCurveTo->IsPeriodic() && tf2 > tl2) {
1206 // aCurveTo is periodic curve and we pass through 0.
1208 aPeriod=aCurveTo->Period();
1209 aCommonPrt.AppendRange2 (tf2, aPeriod);
1210 aCommonPrt.AppendRange2 (0., tl2);
1211 aCommonPrt.SetVertexParameter2((tf2 + aPeriod) * 0.5);
1227 // 1 - the method Perform() is not invoked
1228 // 2,3,4,5 -the method CheckData() fails
1229 // 6 - PrepareArgs() problems
1230 // 7 - No Projectable ranges
1231 // 8,9 - PrepareArgs() problems occured inside projectable Ranges
1232 // 10 - problems in FindRange2
1233 // 11 - can't fill array aFunc(i) in PrepareArgsFuncArrays:
1234 // possible reason is that no points on myCFrom that could be projected
1239 //=======================================================================
1240 //function : CheckTouchVertex
1241 //purpose : line/Circle refinement
1242 //=======================================================================
1243 Standard_Boolean IntTools_EdgeEdge::CheckTouchVertex (const IntTools_CommonPrt& aCP,
1244 Standard_Real& aTx1,
1245 Standard_Real& aTx2) const
1247 Standard_Boolean bFlag;
1248 Standard_Real aTFR1, aTLR1, aTFR2, aTLR2;
1249 Standard_Real aTL1, aTL2, aTC1, aTC2;
1250 Standard_Real aRC, aDLC, aD2, aC2, aTLx, aTCx;
1251 GeomAbs_CurveType aTFrom, aTTo;
1254 gp_Pnt aPC, aPLx, aPCx;
1256 bFlag=Standard_False;
1257 aCP.Range1(aTFR1, aTLR1);
1258 (aCP.Ranges2())(1).Range(aTFR2, aTLR2);
1260 aTFrom=myCFrom.GetType();
1261 aTTo =myCTo.GetType();
1267 if (aTFrom==GeomAbs_Circle) {
1268 aCirc=myCFrom.Circle();
1276 aCirc=myCTo.Circle();
1277 aLine=myCFrom.Line();
1280 aPC=aCirc.Location();
1283 aDLC=aLine.Distance(aPC);
1284 if (fabs(aDLC-aRC)>myCriteria) {
1288 aTLx=ElCLib::Parameter(aLine, aPC);
1289 aPLx=ElCLib::Value(aTLx, aLine);
1290 aTCx=ElCLib::Parameter(aCirc, aPLx);
1291 aPCx=ElCLib::Value(aTCx, aCirc);
1292 aD2=aPLx.SquareDistance(aPCx);
1293 aC2=myCriteria*myCriteria;
1298 if (aTLx<aTL1 || aTLx>aTL2) {
1301 if (aTCx<aTC1 || aTCx>aTC2) {
1307 if (aTFrom==GeomAbs_Circle) {
1314 //=======================================================================
1315 //function : CheckTouch
1317 //=======================================================================
1318 Standard_Boolean IntTools_EdgeEdge::CheckTouch(const IntTools_CommonPrt& aCP,
1319 Standard_Real& aTx1,
1320 Standard_Real& aTx2)
1322 Standard_Real aTF1, aTL1, aTF2, aTL2, Tol, af, al,aDist2, aMinDist2;
1323 Standard_Boolean theflag=Standard_False;
1324 Standard_Integer aNbExt, i, iLower;
1326 aCP.Range1(aTF1, aTL1);
1327 (aCP.Ranges2())(1).Range(aTF2, aTL2);
1329 Tol = Precision::PConfusion();
1331 const Handle(Geom_Curve)& Curve1 =BRep_Tool::Curve (myCFrom.Edge(), af, al);
1332 const Handle(Geom_Curve)& Curve2 =BRep_Tool::Curve (myCTo.Edge() , af, al);
1334 GeomAdaptor_Curve TheCurve1 (Curve1, aTF1, aTL1);
1335 GeomAdaptor_Curve TheCurve2 (Curve2, aTF2, aTL2);
1338 Standard_Real aTol1 = TheCurve1.Resolution(myCriteria);
1339 aTol1 = (Tol < aTol1) ? Tol : aTol1;
1341 Standard_Boolean isfirst = (Abs(myTminFrom - aTF1) < aTol1);
1342 Standard_Boolean islast = (Abs(myTmaxFrom - aTL1) < aTol1);
1344 if(!isfirst || !islast) {
1347 GeomAPI_ProjectPointOnCurve aProjector;
1348 aProjector.Init(Curve2, aTF2, aTL2);
1349 aProjector.Perform(Curve1->Value(aTx1));
1351 if(aProjector.NbPoints() > 0)
1352 aTx2 = aProjector.LowerDistanceParameter();
1354 if(Curve1->Value(aTx1).Distance(Curve2->Value(aTF2)) < myCriteria)
1364 GeomAPI_ProjectPointOnCurve aProjector;
1365 aProjector.Init(Curve2, aTF2, aTL2);
1366 aProjector.Perform(Curve1->Value(aTx1));
1367 if(aProjector.NbPoints() > 0)
1368 aTx2 = aProjector.LowerDistanceParameter();
1370 if(Curve1->Value(aTx1).Distance(Curve2->Value(aTL2)) < myCriteria)
1380 Extrema_ExtCC anExtrema (TheCurve1, TheCurve2, aTF1-Tol, aTL1+Tol, aTF2-Tol, aTL2+Tol, Tol, Tol);
1382 if(!anExtrema.IsDone()) {
1385 if (anExtrema.IsParallel()) {
1389 aNbExt=anExtrema.NbExt() ;
1394 Standard_Boolean istouch = Standard_True;
1395 Standard_Integer avalidindex = 0;
1399 for (i=1; i<=aNbExt; ++i) {
1400 aDist2=anExtrema.SquareDistance(i);
1401 if (aDist2 < aMinDist2) {
1406 if(aDist2 < myCriteria * myCriteria) {
1408 Extrema_POnCurv aPOnC1, aPOnC2;
1409 anExtrema.Points(i, aPOnC1, aPOnC2);
1410 Standard_Real aPar1 = aPOnC1.Parameter();
1411 anExtrema.Points(avalidindex, aPOnC1, aPOnC2);
1412 Standard_Real aPar2 = aPOnC1.Parameter();
1414 if(Abs(aPar1 - aPar2) > Precision::PConfusion()) {
1415 istouch = Standard_False;
1422 aDist2=anExtrema.SquareDistance(iLower);
1423 if (aDist2 > myCriteria * myCriteria) {
1427 Extrema_POnCurv aPOnC1, aPOnC2;
1428 anExtrema.Points(iLower, aPOnC1, aPOnC2);
1430 aTx1=aPOnC1.Parameter();
1431 aTx2=aPOnC2.Parameter();
1433 if((myCFrom.GetType() == GeomAbs_Line && myCTo.GetType() == GeomAbs_Circle) ||
1434 (myCFrom.GetType() == GeomAbs_Circle && myCTo.GetType() == GeomAbs_Line))
1436 Standard_Real aRadius;
1437 GeomAbs_CurveType aTFrom, aTTo;
1440 gp_Pnt aPCenter, aPOnLine;
1442 aTFrom=myCFrom.GetType();
1443 aTTo =myCTo.GetType();
1445 if (aTFrom==GeomAbs_Circle) {
1446 aCirc=myCFrom.Circle();
1448 Curve2->D0(aTx2, aPOnLine);
1452 aCirc=myCTo.Circle();
1453 aLine=myCFrom.Line();
1454 Curve1->D0(aTx1, aPOnLine);
1458 aPCenter=aCirc.Location();
1459 aRadius =aCirc.Radius();
1461 aDist2=aPOnLine.SquareDistance(aPCenter);
1462 aDist2=fabs (sqrt(aDist2)-aRadius);
1464 if (aDist2 < Tol * Tol) {
1469 GeomAPI_ProjectPointOnCurve aProjector;
1470 Standard_Real aMidPar, aMidDist;
1471 aMidPar = (aTF1 + aTL1) * 0.5;
1472 aProjector.Init(Curve2, aTF2, aTL2);
1473 aProjector.Perform(Curve1->Value(aMidPar));
1474 if(aProjector.NbPoints() > 0) {
1475 aMidDist=aProjector.LowerDistance();
1476 if(aMidDist * aMidDist < aDist2 || !istouch) {
1478 aTx2 = aProjector.LowerDistanceParameter();
1482 if (fabs (aTx1-aTF1) < Tol) {
1486 if (fabs (aTx1-aTL1) < Tol) {
1490 if (aTx1 > (aTF1-Tol) && aTx1 < (aTL1+Tol) ) {
1497 //=======================================================================
1498 //function : ComputeLineLine
1500 //=======================================================================
1501 void IntTools_EdgeEdge::ComputeLineLine()
1503 Standard_Boolean IsParallel, IsCoincide;
1504 Standard_Real Tolang2, Tol2;
1505 gp_Pnt P11, P12, P21, P22;
1507 myIsDone = Standard_True;
1509 IsParallel = Standard_False;
1510 IsCoincide = Standard_False;
1511 Tolang2 = Precision::Angular();
1512 Tol2 = myCriteria*myCriteria;
1514 gp_Lin C1 = myCFrom.Line();
1515 gp_Lin C2 = myCTo.Line();
1516 const gp_Dir& D1 = C1.Position().Direction();
1517 const gp_Dir& D2 = C2.Position().Direction();
1518 Standard_Real aCos = D1.Dot(D2);
1522 Ang2 = 2.*(1. - aCos);
1525 Ang2 = 2.*(1. + aCos);
1528 if(Ang2 <= Tolang2) {
1529 IsParallel = Standard_True;
1530 if(C2.SquareDistance(C1.Location()) <= Tol2) {
1531 IsCoincide = Standard_True;
1532 P11 = ElCLib::Value(myTminFrom, C1);
1533 P12 = ElCLib::Value(myTmaxFrom, C1);
1537 //Check coincidence of extremity points;
1538 //Check only shortest line
1539 P11 = ElCLib::Value(myTminFrom, C1);
1540 P12 = ElCLib::Value(myTmaxFrom, C1);
1541 if(C2.SquareDistance(P11) <= Tol2 && C2.SquareDistance(P12) <= Tol2) {
1542 IsCoincide = Standard_True;
1547 Standard_Real t21, t22;
1548 t21 = ElCLib::Parameter(C2, P11);
1549 t22 = ElCLib::Parameter(C2, P12);
1551 if((t21 > myTmaxTo && t22 > myTmaxTo) || (t21 < myTminTo && t22 < myTminTo)) {
1562 IntTools_CommonPrt aCommonPrt;
1563 aCommonPrt.SetEdge1(myCFrom.Edge());
1564 aCommonPrt.SetEdge2(myCTo.Edge());
1565 if(t21 >= myTminTo) {
1566 if(t22 <= myTmaxTo) {
1567 aCommonPrt.SetRange1(myTminFrom, myTmaxFrom);
1568 aCommonPrt.SetAllNullFlag(Standard_True);
1569 aCommonPrt.AppendRange2(t21, t22);
1572 aCommonPrt.SetRange1(myTminFrom, myTmaxFrom - (t22 - myTmaxTo));
1573 aCommonPrt.AppendRange2(t21, myTmaxTo);
1577 aCommonPrt.SetRange1(myTminFrom + (myTminTo - t21), myTmaxFrom);
1578 aCommonPrt.AppendRange2(myTminTo, t22);
1580 aCommonPrt.SetType(TopAbs_EDGE);
1581 mySeqOfCommonPrts.Append(aCommonPrt);
1591 TopoDS_Iterator aIt1, aIt2;
1593 aIt1.Initialize(myEdge1);
1594 for (; aIt1.More(); aIt1.Next()) {
1595 const TopoDS_Shape& aV1=aIt1.Value();
1596 aIt2.Initialize(myEdge2);
1597 for (; aIt2.More(); aIt2.Next()) {
1598 const TopoDS_Shape& aV2=aIt2.Value();
1599 if (aV2.IsSame(aV1)) {
1600 // the two straight lines have commpn vertex
1607 Standard_Real aSin2 = 1. - aCos*aCos;
1608 gp_Pnt O1 = C1.Location();
1609 gp_Pnt O2 = C2.Location();
1610 gp_Vec O1O2 (O1,O2);
1611 Standard_Real U2 = (D1.XYZ()*(O1O2.Dot(D1))-(O1O2.XYZ())).Dot(D2.XYZ());
1613 if(U2 < myTminTo || U2 > myTmaxTo) {
1617 gp_Pnt P2(ElCLib::Value(U2,C2));
1618 Standard_Real U1 = (gp_Vec(O1,P2)).Dot(D1);
1619 if(U1 < myTminFrom || U1 > myTmaxFrom) {
1623 gp_Pnt P1(ElCLib::Value(U1,C1));
1624 Standard_Real d2 = P1.SquareDistance(P2);
1630 IntTools_CommonPrt aCommonPrt;
1631 aCommonPrt.SetEdge1(myCFrom.Edge());
1632 aCommonPrt.SetEdge2(myCTo.Edge());
1633 aCommonPrt.SetRange1(U1 - myCriteria, U1 + myCriteria);
1634 aCommonPrt.AppendRange2(U2 - myCriteria, U2 + myCriteria);
1635 aCommonPrt.SetType(TopAbs_VERTEX);
1636 aCommonPrt.SetVertexParameter1(U1);
1637 aCommonPrt.SetVertexParameter2(U2);
1638 mySeqOfCommonPrts.Append(aCommonPrt);