1 // Created on: 2000-10-26
2 // Created by: Peter KURNEV
3 // Copyright (c) 2000-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.
20 #include <IntTools_EdgeEdge.ixx>
22 #include <Precision.hxx>
24 #include <TColStd_SequenceOfReal.hxx>
26 #include <gp_Circ.hxx>
33 #include <Geom_Curve.hxx>
35 #include <Geom_BSplineCurve.hxx>
36 #include <GeomAdaptor_Curve.hxx>
38 #include <CPnts_AbscissaPoint.hxx>
40 #include <GeomAPI_ProjectPointOnCurve.hxx>
42 #include <Extrema_ExtElC.hxx>
43 #include <Extrema_POnCurv.hxx>
44 #include <Extrema_ExtCC.hxx>
46 #include <TopoDS_Iterator.hxx>
47 #include <BRep_Tool.hxx>
49 #include <IntTools.hxx>
50 #include <IntTools_Range.hxx>
51 #include <IntTools_CArray1OfReal.hxx>
52 #include <IntTools_CommonPrt.hxx>
53 #include <IntTools_SequenceOfRanges.hxx>
54 #include <IntTools_Tools.hxx>
55 #include <IntTools_BeanBeanIntersector.hxx>
58 //=======================================================================
59 //function : IntTools_EdgeEdge::IntTools_EdgeEdge
61 //=======================================================================
62 IntTools_EdgeEdge::IntTools_EdgeEdge()
70 myIsDone=Standard_False;
72 myOrder=Standard_False;
75 myParallel=Standard_False;
78 //=======================================================================
81 //=======================================================================
82 void IntTools_EdgeEdge::SetEdge1(const TopoDS_Edge& anEdge)
86 //=======================================================================
89 //=======================================================================
90 void IntTools_EdgeEdge::SetEdge2(const TopoDS_Edge& anEdge)
95 //=======================================================================
96 //function : SetTolerance1
98 //=======================================================================
99 void IntTools_EdgeEdge::SetTolerance1(const Standard_Real aTol)
103 //=======================================================================
104 //function : SetTolerance2
106 //=======================================================================
107 void IntTools_EdgeEdge::SetTolerance2(const Standard_Real aTol)
112 //=======================================================================
113 //function : SetDiscretize
115 //=======================================================================
116 void IntTools_EdgeEdge::SetDiscretize(const Standard_Integer aDiscret)
120 //=======================================================================
121 //function : SetDeflection
123 //=======================================================================
124 void IntTools_EdgeEdge::SetDeflection(const Standard_Real aDefl)
128 //=======================================================================
129 //function : SetEpsilonT
131 //=======================================================================
132 void IntTools_EdgeEdge::SetEpsilonT(const Standard_Real anEpsT)
136 //=======================================================================
137 //function : SetEpsilonNull
139 //=======================================================================
140 void IntTools_EdgeEdge::SetEpsilonNull(const Standard_Real anEpsNull)
145 //=======================================================================
146 //function : SetRange1
148 //=======================================================================
149 void IntTools_EdgeEdge::SetRange1(const Standard_Real aFirst,
150 const Standard_Real aLast)
152 myRange1.SetFirst (aFirst);
153 myRange1.SetLast (aLast);
155 //=======================================================================
156 //function : SetRange2
158 //=======================================================================
159 void IntTools_EdgeEdge::SetRange2(const Standard_Real aFirst,
160 const Standard_Real aLast)
162 myRange2.SetFirst (aFirst);
163 myRange2.SetLast (aLast);
166 //=======================================================================
167 //function : SetRange1
169 //=======================================================================
170 void IntTools_EdgeEdge::SetRange1(const IntTools_Range& aRange)
172 myRange1.SetFirst (aRange.First());
173 myRange1.SetLast (aRange.Last());
175 //=======================================================================
176 //function : SetRange2
178 //=======================================================================
179 void IntTools_EdgeEdge::SetRange2(const IntTools_Range& aRange)
181 myRange2.SetFirst (aRange.First());
182 myRange2.SetLast (aRange.Last());
185 //=======================================================================
188 //=======================================================================
189 Standard_Boolean IntTools_EdgeEdge::Order()const
193 //=======================================================================
196 //=======================================================================
197 Standard_Boolean IntTools_EdgeEdge::IsDone()const
201 //=======================================================================
202 //function : ErrorStatus
204 //=======================================================================
205 Standard_Integer IntTools_EdgeEdge::ErrorStatus()const
207 return myErrorStatus;
210 //=======================================================================
211 //function : CommonParts
213 //=======================================================================
214 const IntTools_SequenceOfCommonPrts& IntTools_EdgeEdge::CommonParts() const
216 return mySeqOfCommonPrts;
218 //=======================================================================
221 //=======================================================================
222 const IntTools_Range& IntTools_EdgeEdge::Range1() const
226 //=======================================================================
229 //=======================================================================
230 const IntTools_Range& IntTools_EdgeEdge::Range2() const
234 //=======================================================================
237 //=======================================================================
238 void IntTools_EdgeEdge::Perform()
240 Standard_Boolean bIsSameCurves;
241 Standard_Integer i, pri, aNbCommonPrts, aNbRange;
242 Standard_Real aT1, aT2, aPC;
243 IntTools_CommonPrt aCommonPrt;
244 GeomAbs_CurveType aCTFrom, aCTTo;
246 myIsDone=Standard_False;
259 aCTFrom = myCFrom.GetType();
260 aCTTo = myCTo.GetType();
262 if(aCTFrom==GeomAbs_Line && aCTTo==GeomAbs_Line) {
273 bIsSameCurves=IsSameCurves();
275 aCommonPrt.SetType(TopAbs_EDGE);
276 aCommonPrt.SetRange1 (myTminFrom, myTmaxFrom);
277 aCommonPrt.AppendRange2 (myTminTo, myTmaxTo);
278 mySeqOfCommonPrts.Append(aCommonPrt);
279 myIsDone=Standard_True;
283 IntTools_BeanBeanIntersector anIntersector(myCFrom, myCTo, myTolFrom, myTolTo);
284 anIntersector.SetBeanParameters(Standard_True, myTminFrom, myTmaxFrom);
285 anIntersector.SetBeanParameters(Standard_False, myTminTo, myTmaxTo);
287 anIntersector.Perform();
288 if(!anIntersector.IsDone()) {
289 myIsDone = Standard_False;
293 aPC=Precision::PConfusion();
294 aCommonPrt.SetEdge1(myCFrom.Edge());
295 aCommonPrt.SetEdge2(myCTo.Edge());
297 const IntTools_SequenceOfRanges& aSR=anIntersector.Result();
298 aNbRange=aSR.Length();
299 for(i=1; i <=aNbRange; ++i) {
300 const IntTools_Range& aRange =aSR.Value(i);
304 if(IsProjectable(IntTools_Tools::IntermediatePoint(aT1, aT2))) {
305 aCommonPrt.SetRange1(aT1, aT2);
307 if(((aT1 - myTminFrom)<aPC) && ((myTmaxFrom - aT2)<aPC)) {
308 aCommonPrt.SetAllNullFlag(Standard_True);
310 mySeqOfCommonPrts.Append(aCommonPrt);
314 aNbCommonPrts=mySeqOfCommonPrts.Length();
315 for (i=1; i<=aNbCommonPrts; ++i) {
316 IntTools_CommonPrt& aCmnPrt=mySeqOfCommonPrts.ChangeValue(i);
317 pri=FindRangeOnCurve2 (aCmnPrt);
324 // Line Circle's Common Parts treatement
325 if ((aCTFrom==GeomAbs_Line && aCTTo==GeomAbs_Circle) ||
326 (aCTFrom==GeomAbs_Circle && aCTTo==GeomAbs_Line) ||
327 (aCTFrom==GeomAbs_Ellipse && aCTTo==GeomAbs_Ellipse) ||
328 (aCTFrom==GeomAbs_Circle && aCTTo==GeomAbs_Circle)) {
329 for (i=1; i<=aNbCommonPrts; i++) {
330 IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
331 TopAbs_ShapeEnum aType=aCP.Type();
332 Standard_Boolean bIsTouch;
333 Standard_Real aTx1, aTx2;
335 if ((aType==TopAbs_EDGE) && !aCommonPrt.AllNullFlag()) {
336 bIsTouch=CheckTouch (aCP, aTx1, aTx2);
338 aCP.SetType(TopAbs_VERTEX);
339 aCP.SetVertexParameter1(aTx1);
340 aCP.SetRange1 (aTx1, aTx1);
341 IntTools_Range& aRange2=(aCP.ChangeRanges2()).ChangeValue(1);
342 aRange2.SetFirst(aTx2);
343 aRange2.SetLast (aTx2);
347 if (aType==TopAbs_VERTEX) {
348 if(aCTFrom==GeomAbs_Line || aCTTo==GeomAbs_Line) {
349 bIsTouch=CheckTouchVertex (aCP, aTx1, aTx2);
351 aCP.SetVertexParameter1(aTx1);
352 aCP.SetRange1 (aTx1, aTx1);
353 IntTools_Range& aRange2=(aCP.ChangeRanges2()).ChangeValue(1);
354 aRange2.SetFirst(aTx2);
355 aRange2.SetLast (aTx2);
369 myIsDone=Standard_True;
372 //=======================================================================
373 //function : CheckData
375 //=======================================================================
376 void IntTools_EdgeEdge::CheckData()
378 if (BRep_Tool::Degenerated(myEdge1)) {
381 if (!BRep_Tool::IsGeometric(myEdge1)) {
384 if (BRep_Tool::Degenerated(myEdge2)) {
387 if (!BRep_Tool::IsGeometric(myEdge2)) {
391 //=======================================================================
394 //=======================================================================
395 void IntTools_EdgeEdge::Prepare()
397 Standard_Real aLE1, aLE2, aT1, aT2, aTol1, aTol2;
398 GeomAdaptor_Curve aGAC;
399 GeomAbs_CurveType aCT1, aCT2;
401 // 1.Prepare Curves' data
402 const Handle(Geom_Curve)& aC1=BRep_Tool::Curve (myEdge1, aT1, aT2);
403 aT1=myRange1.First();
405 aGAC.Load(aC1, myRange1.First(), myRange1.Last());
406 aLE1=CPnts_AbscissaPoint::Length(aGAC, aT1, aT2);
408 const Handle(Geom_Curve)& aC2=BRep_Tool::Curve (myEdge2, aT1, aT2);
409 aT1=myRange2.First();
411 aGAC.Load(aC2, aT1, aT2);
412 aLE2=CPnts_AbscissaPoint::Length(aGAC, aT1, aT2);
414 myOrder=Standard_False;
416 myCFrom.Initialize(myEdge1);
417 myCTo .Initialize(myEdge2);
420 myTminFrom=myRange1.First();
421 myTmaxFrom=myRange1.Last ();
422 myTminTo =myRange2.First();
423 myTmaxTo =myRange2.Last ();
426 myCFrom.Initialize(myEdge2);
427 myCTo .Initialize(myEdge1);
430 myTminFrom=myRange2.First();
431 myTmaxFrom=myRange2.Last ();
432 myTminTo =myRange1.First();
433 myTmaxTo =myRange1.Last ();
435 myOrder=Standard_True; // revesed order
438 // 2.Prepare myCriteria
439 aCT1=myCFrom.GetType();
440 aCT2=myCTo.GetType();
443 if(aCT1==GeomAbs_BSplineCurve|| aCT1==GeomAbs_BezierCurve){
447 if(aCT2==GeomAbs_BSplineCurve|| aCT2==GeomAbs_BezierCurve){
450 myCriteria=aTol1+aTol2;
452 //=======================================================================
453 //function : IsProjectable
455 //=======================================================================
456 Standard_Integer IntTools_EdgeEdge::IsProjectable(const Standard_Real t) const
458 Standard_Integer aNbProj;
462 GeomAPI_ProjectPointOnCurve aProjector;
463 const TopoDS_Edge& aEFrom=myCFrom.Edge();
464 Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (aEFrom, f, l);
465 aCurveFrom->D0(t, aPFrom);
467 Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (myCTo.Edge(), f, l);
468 aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
469 aProjector.Perform(aPFrom);
470 aNbProj=aProjector.NbPoints();
472 if (myCTo.GetType()==GeomAbs_Circle) {
473 gp_Circ aCirc=myCTo.Circle();
474 const gp_Pnt& aCenter=aCirc.Location();
475 if (aCenter.SquareDistance(aPFrom) < 1.e-7) {
482 //=======================================================================
483 //function : DistanceFunction
485 //=======================================================================
486 Standard_Real IntTools_EdgeEdge::DistanceFunction(const Standard_Real t)//const
488 Standard_Real aD, f, l;
489 GeomAPI_ProjectPointOnCurve aProjector;
490 gp_Pnt aPFrom; //ZZ , aPTo;
492 const TopoDS_Edge& aEFrom=myCFrom.Edge();
493 const TopoDS_Edge& aETo =myCTo.Edge();
495 Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (aEFrom, f, l);
496 aCurveFrom->D0 (t, aPFrom);
497 Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (aETo, f, l);
499 if (myCTo.GetType()==GeomAbs_Circle) {
500 gp_Circ aCirc=myCTo.Circle();
501 const gp_Pnt& aCenter=aCirc.Location();
502 const gp_Ax1& anAx1 =aCirc.Axis();
503 const gp_Dir& aDir =anAx1.Direction();
504 gp_Lin aLin(aCenter, aDir);
505 Standard_Real dPFromLin=aLin.Distance(aPFrom);
506 if (dPFromLin < 1.e-7) {
508 aCurveTo->D0 (myTminTo, anAnyPTo);
509 aD=aPFrom.Distance(anAnyPTo);
516 aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
517 aProjector.Perform(aPFrom);
519 Standard_Integer j, aNbPoints;
521 aNbPoints =aProjector.NbPoints();
523 for (j=0; j<=1; j++) {
530 aCurveFrom->D0 (tt, aPFrom);
531 aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
532 aProjector.Perform(aPFrom);
533 aNbPoints=aProjector.NbPoints();
542 // Can't find projection.
548 aD=aProjector.LowerDistance();
554 //=======================================================================
555 //function : DerivativeFunction
557 //=======================================================================
558 Standard_Real IntTools_EdgeEdge::DerivativeFunction(const Standard_Real t2)
560 Standard_Real t1, t3, aD1, aD2, aD3;
561 Standard_Real dt=1.e-7;
563 aD1=DistanceFunction(t1);
565 aD3=DistanceFunction(t3);
572 //=======================================================================
573 //function : FindSimpleRoot
574 //purpose : [private]
575 //=======================================================================
576 Standard_Real IntTools_EdgeEdge::FindSimpleRoot (const Standard_Integer IP,
577 const Standard_Real tA,
578 const Standard_Real tB,
579 const Standard_Real fA)
581 Standard_Real r, a, b, y, x0, s;
585 Standard_Integer step = 1, stepcheck = 1000, steplimit = 100000;
586 Standard_Real value = (IP==1) ? DistanceFunction(0.5*(a+b)) : DerivativeFunction(0.5*(a+b));
592 y=DistanceFunction(x0);
594 y=DerivativeFunction(x0);
596 Standard_Real aMaxAB100 = 100.*Max(a, b);
597 Standard_Real anEps = Epsilon(aMaxAB100);
598 Standard_Real anEpsT = Max(anEps, myEpsT);
599 // if (fabs(b-a) < myEpsT || y==0.) {
600 if (fabs(b-a) < anEpsT || y==0.) {
604 if( step == stepcheck ) {
605 if( Abs(value - y) <= 1.e-9 ) {
614 if( step == steplimit ) {
634 //=======================================================================
635 //function : FindRangeOnCurve2
637 //=======================================================================
638 Standard_Integer IntTools_EdgeEdge::FindRangeOnCurve2(IntTools_CommonPrt& aCommonPrt)
640 Standard_Integer pri;
643 if (aCommonPrt.AllNullFlag()) {
644 aCommonPrt.SetType(TopAbs_EDGE);
645 aCommonPrt.AppendRange2 (myTminTo, myTmaxTo);
649 Standard_Real ttmp, f, l, af1, al1, am1, af2, al2, am2;
650 gp_Pnt aPf1, aPl1, aPm1, aPf2, aPl2, aPm2;
651 GeomAPI_ProjectPointOnCurve aProjector;
653 aCommonPrt.Range1(af1, al1);
656 const TopoDS_Edge& anEdgeTo=myCTo.Edge();
657 Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (anEdgeTo, f, l);
659 const TopoDS_Edge& anEdgeFrom=myCFrom.Edge();
660 Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f, l);
663 aCurveFrom->D0 (af1, aPf1);
664 pri=GetParameterOnCurve2 (af1, af2);
668 aCurveTo->D0(af2, aPf2);
671 aCurveFrom->D0 (al1, aPl1);
672 pri=GetParameterOnCurve2 (al1, al2);
676 aCurveTo->D0(al2, aPl2);
679 aCurveFrom->D0 (am1, aPm1);
680 pri=GetParameterOnCurve2 (am1, am2);
684 aCurveTo->D0(am2, aPm2);
686 // Reverse C2 points if it is necessary
687 Standard_Boolean reverse = (af2 > al2);
699 if((Abs(af2 - myTminTo) < Precision::PConfusion()) &&
700 (Abs(al2 - myTmaxTo) < Precision::PConfusion())) {
701 aCommonPrt.SetAllNullFlag(Standard_True);
705 Standard_Boolean aVFlag1, aVFlag2, aGeomFlag1, aGeomFlag2;
706 Standard_Real Df2m2, Dm2l2, Df2l2, df2m2, dm2l2, df2l2, df1m1, dm1l1, df1l1;
707 Standard_Real tV1, tV2;
709 // parametric differences for C2
714 // geometric distances for C2
715 df2m2=aPf2.Distance(aPm2);
716 dm2l2=aPm2.Distance(aPl2);
717 df2l2=aPf2.Distance(aPl2);
719 aVFlag1=(Df2m2<myEpsT && Dm2l2<myEpsT);
720 aVFlag2=(df2m2 < myCriteria && dm2l2 < myCriteria);
723 // Two perpendicular lines => VERTEX
724 if ( aVFlag1 && aVFlag2) {
726 aCommonPrt.SetType(TopAbs_VERTEX);
727 pri=TreatVertexType(am1, am2, aCommonPrt);
731 aCommonPrt.SetVertexParameter2(tV2);
732 aCommonPrt.AppendRange2 (af2, al2);
735 aCommonPrt.SetVertexParameter1(tV1);
736 aCommonPrt.SetRange1 (af1, al1);
741 // geometric distances for C1
742 df1m1=aPf1.Distance(aPm1);
743 dm1l1=aPm1.Distance(aPl1);
744 df1l1=aPf1.Distance(aPl1);
746 // if geometric distances between boundaries is less than myCriteria
748 aGeomFlag1=(df1l1 < myCriteria);
749 aGeomFlag2=(df2l2 < myCriteria);
750 if (aGeomFlag1 && aGeomFlag2) {
751 aCommonPrt.SetType(TopAbs_VERTEX);
754 aCommonPrt.SetVertexParameter2(tV2);
755 aCommonPrt.AppendRange2 (af2, al2);
758 aCommonPrt.SetVertexParameter1(tV1);
759 aCommonPrt.SetRange1 (af1, al1);
764 if (Df2l2 < myEpsT && !aVFlag1) {
765 if (aPf1.Distance(aPl1) < myCriteria && aPf2.Distance(aPl2) < myCriteria) {
768 aCommonPrt.AppendRange2 (af1, al2);
769 aCommonPrt.SetType(TopAbs_EDGE);
774 aProjector.Init(aCurveFrom, myTminFrom, myTmaxFrom);
775 aProjector.Perform(aPm2);
776 Standard_Integer aNbPoints=aProjector.NbPoints();
778 Standard_Real aDD=aProjector.LowerDistance();
779 if (aDD > myCriteria) {
781 aCommonPrt.SetType(TopAbs_EDGE);
782 aCommonPrt.AppendRange2 (myTminTo, af2);
783 aCommonPrt.AppendRange2 (al2, myTmaxTo);
789 aCommonPrt.SetType(TopAbs_EDGE);
790 aCommonPrt.AppendRange2 (myTminTo, af2);
791 aCommonPrt.AppendRange2 (al2, myTmaxTo);
795 IsIntersection (af1, al1);
796 if (!myParallel && !aCommonPrt.AllNullFlag()) {
798 GetParameterOnCurve2 (myPar1, aPar2);
799 aCommonPrt.SetType(TopAbs_VERTEX);
801 Standard_Boolean IsmyPar1 = Standard_True;
803 if(Abs(af1-myTminFrom) < Precision::PConfusion()) {
804 IsmyPar1 = Standard_False;
805 aCommonPrt.SetVertexParameter1(af1);
807 aCommonPrt.SetVertexParameter2(al2);
809 aCommonPrt.SetVertexParameter2(af2);
812 if(Abs(al1-myTmaxFrom) < Precision::PConfusion()) {
813 IsmyPar1 = Standard_False;
814 aCommonPrt.SetVertexParameter1(al1);
817 aCommonPrt.SetVertexParameter2(af2);
819 aCommonPrt.SetVertexParameter2(al2);
822 if(Abs(af2-myTminTo) < Precision::PConfusion()) {
823 IsmyPar1 = Standard_False;
824 aCommonPrt.SetVertexParameter2(af2);
827 aCommonPrt.SetVertexParameter1(al1);
829 aCommonPrt.SetVertexParameter1(af1);
832 if(Abs(al2-myTmaxTo) < Precision::PConfusion()) {
833 IsmyPar1 = Standard_False;
834 aCommonPrt.SetVertexParameter2(al2);
837 aCommonPrt.SetVertexParameter1(af1);
839 aCommonPrt.SetVertexParameter1(al1);
841 // aCommonPrt.SetVertexParameter1(myPar1);
842 // aCommonPrt.SetRange1 (af1, al1);
844 // aCommonPrt.SetVertexParameter2(aPar2);
846 aCommonPrt.SetVertexParameter1(myPar1);
847 aCommonPrt.SetRange1 (af1, al1);
849 aCommonPrt.SetVertexParameter2(aPar2);
851 aCommonPrt.AppendRange2 (af2, al2);
857 aCommonPrt.SetType(TopAbs_EDGE);
858 aCommonPrt.AppendRange2 (af2, al2);
862 //=======================================================================
863 //function : IsIntersection
865 //=======================================================================
866 void IntTools_EdgeEdge::IsIntersection (const Standard_Real ta,
867 const Standard_Real tb)
869 Standard_Integer i, aNb, pri;
871 GeomAbs_CurveType aCT1, aCT2;
872 IntTools_CArray1OfReal anArgs, aFunc;
874 aCT1=myCFrom.GetType();
875 aCT2=myCTo.GetType();
876 if((aCT1==GeomAbs_Line) && (aCT2==GeomAbs_Line)) {
877 const Handle(Geom_Curve)& Curve1=BRep_Tool::Curve (myCFrom.Edge(), t, f);
878 const Handle(Geom_Curve)& Curve2=BRep_Tool::Curve (myCTo.Edge() , t, f);
880 GeomAdaptor_Curve TheCurve1 (Curve1);
881 GeomAdaptor_Curve TheCurve2 (Curve2);
882 Extrema_ExtCC anExtrema (TheCurve1, TheCurve2);
884 if(anExtrema.IsDone() && anExtrema.IsParallel()) {
885 myParallel = Standard_True;
890 if (aCT1==GeomAbs_Circle && aCT2==GeomAbs_Circle) {
891 Standard_Boolean bIsDone, bIsParallel;
892 Standard_Integer aNbExt;
893 Standard_Real aD2, aCriteria2, aT1;
894 gp_Circ aCirc1, aCirc2;
895 Extrema_POnCurv aPC1, aPC2;
897 aCirc1=myCFrom.Circle();
898 aCirc2=myCTo.Circle();
900 Extrema_ExtElC aExtElC(aCirc1, aCirc2);
902 bIsDone=aExtElC.IsDone();
904 bIsParallel=aExtElC.IsParallel();
906 aCriteria2=myCriteria*myCriteria;
907 aNbExt=aExtElC.NbExt();
908 for (i=1; i<=aNbExt; ++i) {
909 aD2=aExtElC.SquareDistance(i);
910 if (aD2<aCriteria2) {
911 aExtElC.Points(i, aPC1, aPC2);
912 aT1=aPC1.Parameter();
913 if (aT1>ta && aT1<tb) {
915 myParallel=Standard_False;
924 // Prepare values of arguments for the interval [ta, tb]
925 pri=IntTools::PrepareArgs (myCFrom, tb, ta, myDiscret, myDeflection, anArgs);
929 for (i=0; i<aNb; i++) {
931 f=DistanceFunction(t);
932 if (fabs(f) < myEpsNull) {
937 FindDerivativeRoot(anArgs, aFunc);
941 //=======================================================================
942 //function : FindDerivativeRoot
944 //=======================================================================
945 void IntTools_EdgeEdge::FindDerivativeRoot(const IntTools_CArray1OfReal& t,
946 const IntTools_CArray1OfReal& f)
948 Standard_Integer i, n, k;
949 Standard_Real fr, tr, anEpsNull;
950 IntTools_CArray1OfReal fd;
951 TColStd_SequenceOfReal aTSeq, aFSeq;
953 anEpsNull=100.*myEpsNull;
955 myParallel=Standard_True;
960 // Table of derivatives
961 fd(0)=(f(1)-f(0))/(t(1)-t(0));
962 if (fabs(fd(0)) < anEpsNull) {
966 for (i=1; i<k; i++) {
967 fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1));
968 if (fabs(fd(i)) < anEpsNull) {
972 fd(n-1)=(f(n-1)-f(n-2))/(t(n-1)-t(n-2));
973 if (fabs(fd(n-1)) < anEpsNull) {
977 // Finding the range where the derivatives have different signs
978 // for neighbouring points
979 for (i=1; i<n; i++) {
980 Standard_Real fd1, fd2, t1, t2, fabsfd1, fabsfd2;
981 Standard_Boolean bF1, bF2;
988 bF1=fabsfd1 < myEpsNull;
991 bF2=fabsfd2 < myEpsNull;
995 tr=FindSimpleRoot(2, t1, t2, fd1);
996 fr=DistanceFunction(tr);
998 myParallel=Standard_False;
1006 myParallel=Standard_False;
1014 myParallel=Standard_False;
1021 //=======================================================================
1022 //function : GetParameterOnCurve2
1024 //=======================================================================
1025 Standard_Integer IntTools_EdgeEdge::GetParameterOnCurve2(const Standard_Real aT1,
1026 Standard_Real& aT2) const
1029 Standard_Integer j, found, aNbPoints;
1030 const TopoDS_Edge& anEdgeTo=myCTo.Edge();
1031 const TopoDS_Edge& anEdgeFrom=myCFrom.Edge();
1033 Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f, l);
1034 Handle(Geom_Curve)aCurveTo =BRep_Tool::Curve (anEdgeTo, f, l);
1037 aCurveFrom->D0 (aT1, aP1);
1038 GeomAPI_ProjectPointOnCurve aProjector;
1039 aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
1040 aProjector.Perform(aP1);
1041 aNbPoints=aProjector.NbPoints();
1045 for (j=0; j<=1; j++) {
1051 aCurveFrom->D0 (tt, aP1);
1052 aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
1053 aProjector.Perform(aP1);
1054 aNbPoints=aProjector.NbPoints();
1063 aCurveFrom->D0 (aT1, aP1);
1064 Standard_Real aDistance = RealLast();
1066 for(Standard_Integer pIt=0; pIt < 2; pIt++) {
1067 Standard_Real adist = aDistance;
1069 adist = aP1.Distance(aCurveTo->Value(myTminTo));
1071 adist = aP1.Distance(aCurveTo->Value(myTmaxTo));
1073 if(adist < myCriteria) {
1074 found = Standard_True;
1076 if(adist < aDistance) {
1077 aT2 = (pIt) ? myTminTo : myTmaxTo;
1091 for (j=1; j<=aNbPoints; j++) {
1092 aT2=aProjector.Parameter(j);
1093 f=aProjector.Distance(j);
1096 aT2=aProjector.LowerDistanceParameter();
1097 if (aT2 < myTminTo) {
1100 if (aT2 > myTmaxTo) {
1106 //=======================================================================
1107 //function : TreatVertexType
1109 //=======================================================================
1110 Standard_Integer IntTools_EdgeEdge::TreatVertexType(const Standard_Real am1,
1111 const Standard_Real am2,
1112 IntTools_CommonPrt& aCommonPrt)
1114 Standard_Real f1, l1, f2, l2, Alfa , aPeriod;
1115 gp_Pnt aPm1, aPm2, aP;
1119 const TopoDS_Edge& anEdgeFrom=myCFrom.Edge();
1120 Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f1, l1);
1121 aCurveFrom->D1 (am1, aPm1, aVm1);
1124 const TopoDS_Edge& anEdgeTo=myCTo.Edge();
1125 Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (anEdgeTo, f2, l2);
1126 aCurveTo->D1 (am2, aPm2, aVm2);
1129 Alfa=aVm1.Angle(aVm2);
1131 if (Alfa < Precision::Angular()) {
1135 Standard_Real sinAlfa, cosAlfa, dd, tf1, tl1, tf2, tl2, aL1, aL2;
1136 Standard_Integer ip;
1141 dd=aPm1.Distance(aPm2);
1143 if (dd>myCriteria) {
1146 aL2=(myTolTo*cosAlfa+myTolFrom)/sinAlfa;
1148 aP.SetXYZ(aPm2.XYZ()-aVm2.XYZ()*aL2);
1149 ip=IntTools::Parameter (aP, aCurveTo, tf2);
1154 if(aP.Distance(aCurveTo->Value(tf2)) > myTolTo)
1158 aP.SetXYZ(aPm2.XYZ()+aVm2.XYZ()*aL2);
1159 ip=IntTools::Parameter (aP, aCurveTo, tl2);
1164 if(aP.Distance(aCurveTo->Value(tl2)) > myTolTo)
1168 if (dd>myCriteria) {
1172 aL1=(myTolFrom*cosAlfa+myTolTo)/sinAlfa;
1174 aP.SetXYZ(aPm1.XYZ()-aVm1.XYZ()*aL1);
1175 ip=IntTools::Parameter (aP, aCurveFrom, tf1);
1180 if(aP.Distance(aCurveFrom->Value(tf1)) > myTolFrom)
1184 aP.SetXYZ(aPm1.XYZ()+aVm1.XYZ()*aL1);
1185 ip=IntTools::Parameter (aP, aCurveFrom, tl1);
1190 if(aP.Distance(aCurveFrom->Value(tl1)) > myTolFrom)
1194 if (aCurveFrom->IsPeriodic()) {
1195 aPeriod=aCurveFrom->Period();
1196 if (tf1<f1 || tf1>l1) {
1199 if (tl1<f1 || tl1>l1) {
1205 aCommonPrt.SetRange1 (tf1, tl1);
1206 aCommonPrt.SetVertexParameter1((tf1 + tl1) * 0.5);
1209 if (aCurveTo->IsPeriodic() && tf2 > tl2) {
1210 // aCurveTo is periodic curve and we pass through 0.
1212 aPeriod=aCurveTo->Period();
1213 aCommonPrt.AppendRange2 (tf2, aPeriod);
1214 aCommonPrt.AppendRange2 (0., tl2);
1215 aCommonPrt.SetVertexParameter2((tf2 + aPeriod) * 0.5);
1231 // 1 - the method Perform() is not invoked
1232 // 2,3,4,5 -the method CheckData() fails
1233 // 6 - PrepareArgs() problems
1234 // 7 - No Projectable ranges
1235 // 8,9 - PrepareArgs() problems occured inside projectable Ranges
1236 // 10 - problems in FindRange2
1237 // 11 - can't fill array aFunc(i) in PrepareArgsFuncArrays:
1238 // possible reason is that no points on myCFrom that could be projected
1243 //=======================================================================
1244 //function : CheckTouchVertex
1245 //purpose : line/Circle refinement
1246 //=======================================================================
1247 Standard_Boolean IntTools_EdgeEdge::CheckTouchVertex (const IntTools_CommonPrt& aCP,
1248 Standard_Real& aTx1,
1249 Standard_Real& aTx2) const
1251 Standard_Boolean bFlag;
1252 Standard_Real aTFR1, aTLR1, aTFR2, aTLR2;
1253 Standard_Real aTL1, aTL2, aTC1, aTC2;
1254 Standard_Real aRC, aDLC, aD2, aC2, aTLx, aTCx;
1255 GeomAbs_CurveType aTFrom, aTTo;
1258 gp_Pnt aPC, aPLx, aPCx;
1260 bFlag=Standard_False;
1261 aCP.Range1(aTFR1, aTLR1);
1262 (aCP.Ranges2())(1).Range(aTFR2, aTLR2);
1264 aTFrom=myCFrom.GetType();
1265 aTTo =myCTo.GetType();
1271 if (aTFrom==GeomAbs_Circle) {
1272 aCirc=myCFrom.Circle();
1280 aCirc=myCTo.Circle();
1281 aLine=myCFrom.Line();
1284 aPC=aCirc.Location();
1287 aDLC=aLine.Distance(aPC);
1288 if (fabs(aDLC-aRC)>myCriteria) {
1292 aTLx=ElCLib::Parameter(aLine, aPC);
1293 aPLx=ElCLib::Value(aTLx, aLine);
1294 aTCx=ElCLib::Parameter(aCirc, aPLx);
1295 aPCx=ElCLib::Value(aTCx, aCirc);
1296 aD2=aPLx.SquareDistance(aPCx);
1297 aC2=myCriteria*myCriteria;
1302 if (aTLx<aTL1 || aTLx>aTL2) {
1305 if (aTCx<aTC1 || aTCx>aTC2) {
1311 if (aTFrom==GeomAbs_Circle) {
1318 //=======================================================================
1319 //function : CheckTouch
1321 //=======================================================================
1322 Standard_Boolean IntTools_EdgeEdge::CheckTouch(const IntTools_CommonPrt& aCP,
1323 Standard_Real& aTx1,
1324 Standard_Real& aTx2)
1326 Standard_Real aTF1, aTL1, aTF2, aTL2, Tol, af, al,aDist2, aMinDist2;
1327 Standard_Boolean theflag=Standard_False;
1328 Standard_Integer aNbExt, i, iLower;
1330 aCP.Range1(aTF1, aTL1);
1331 (aCP.Ranges2())(1).Range(aTF2, aTL2);
1333 Tol = Precision::PConfusion();
1335 const Handle(Geom_Curve)& Curve1 =BRep_Tool::Curve (myCFrom.Edge(), af, al);
1336 const Handle(Geom_Curve)& Curve2 =BRep_Tool::Curve (myCTo.Edge() , af, al);
1338 GeomAdaptor_Curve TheCurve1 (Curve1, aTF1, aTL1);
1339 GeomAdaptor_Curve TheCurve2 (Curve2, aTF2, aTL2);
1342 Standard_Real aTol1 = TheCurve1.Resolution(myCriteria);
1343 aTol1 = (Tol < aTol1) ? Tol : aTol1;
1345 Standard_Boolean isfirst = (Abs(myTminFrom - aTF1) < aTol1);
1346 Standard_Boolean islast = (Abs(myTmaxFrom - aTL1) < aTol1);
1348 if(!isfirst || !islast) {
1351 GeomAPI_ProjectPointOnCurve aProjector;
1352 aProjector.Init(Curve2, aTF2, aTL2);
1353 aProjector.Perform(Curve1->Value(aTx1));
1355 if(aProjector.NbPoints() > 0)
1356 aTx2 = aProjector.LowerDistanceParameter();
1358 if(Curve1->Value(aTx1).Distance(Curve2->Value(aTF2)) < myCriteria)
1368 GeomAPI_ProjectPointOnCurve aProjector;
1369 aProjector.Init(Curve2, aTF2, aTL2);
1370 aProjector.Perform(Curve1->Value(aTx1));
1371 if(aProjector.NbPoints() > 0)
1372 aTx2 = aProjector.LowerDistanceParameter();
1374 if(Curve1->Value(aTx1).Distance(Curve2->Value(aTL2)) < myCriteria)
1384 Extrema_ExtCC anExtrema (TheCurve1, TheCurve2, aTF1-Tol, aTL1+Tol, aTF2-Tol, aTL2+Tol, Tol, Tol);
1386 if(!anExtrema.IsDone()) {
1389 if (anExtrema.IsParallel()) {
1393 aNbExt=anExtrema.NbExt() ;
1398 Standard_Boolean istouch = Standard_True;
1399 Standard_Integer avalidindex = 0;
1403 for (i=1; i<=aNbExt; ++i) {
1404 aDist2=anExtrema.SquareDistance(i);
1405 if (aDist2 < aMinDist2) {
1410 if(aDist2 < myCriteria * myCriteria) {
1412 Extrema_POnCurv aPOnC1, aPOnC2;
1413 anExtrema.Points(i, aPOnC1, aPOnC2);
1414 Standard_Real aPar1 = aPOnC1.Parameter();
1415 anExtrema.Points(avalidindex, aPOnC1, aPOnC2);
1416 Standard_Real aPar2 = aPOnC1.Parameter();
1418 if(Abs(aPar1 - aPar2) > Precision::PConfusion()) {
1419 istouch = Standard_False;
1426 aDist2=anExtrema.SquareDistance(iLower);
1427 if (aDist2 > myCriteria * myCriteria) {
1431 Extrema_POnCurv aPOnC1, aPOnC2;
1432 anExtrema.Points(iLower, aPOnC1, aPOnC2);
1434 aTx1=aPOnC1.Parameter();
1435 aTx2=aPOnC2.Parameter();
1437 if((myCFrom.GetType() == GeomAbs_Line && myCTo.GetType() == GeomAbs_Circle) ||
1438 (myCFrom.GetType() == GeomAbs_Circle && myCTo.GetType() == GeomAbs_Line))
1440 Standard_Real aRadius;
1441 GeomAbs_CurveType aTFrom, aTTo;
1444 gp_Pnt aPCenter, aPOnLine;
1446 aTFrom=myCFrom.GetType();
1447 aTTo =myCTo.GetType();
1449 if (aTFrom==GeomAbs_Circle) {
1450 aCirc=myCFrom.Circle();
1452 Curve2->D0(aTx2, aPOnLine);
1456 aCirc=myCTo.Circle();
1457 aLine=myCFrom.Line();
1458 Curve1->D0(aTx1, aPOnLine);
1462 aPCenter=aCirc.Location();
1463 aRadius =aCirc.Radius();
1465 aDist2=aPOnLine.SquareDistance(aPCenter);
1466 aDist2=fabs (sqrt(aDist2)-aRadius);
1468 if (aDist2 < Tol * Tol) {
1473 GeomAPI_ProjectPointOnCurve aProjector;
1474 Standard_Real aMidPar, aMidDist;
1475 aMidPar = (aTF1 + aTL1) * 0.5;
1476 aProjector.Init(Curve2, aTF2, aTL2);
1477 aProjector.Perform(Curve1->Value(aMidPar));
1478 if(aProjector.NbPoints() > 0) {
1479 aMidDist=aProjector.LowerDistance();
1480 if(aMidDist * aMidDist < aDist2 || !istouch) {
1482 aTx2 = aProjector.LowerDistanceParameter();
1486 if (fabs (aTx1-aTF1) < Tol) {
1490 if (fabs (aTx1-aTL1) < Tol) {
1494 if (aTx1 > (aTF1-Tol) && aTx1 < (aTL1+Tol) ) {
1501 //=======================================================================
1502 //function : ComputeLineLine
1504 //=======================================================================
1505 void IntTools_EdgeEdge::ComputeLineLine()
1507 Standard_Boolean IsParallel, IsCoincide;
1508 Standard_Real Tolang2, Tol2;
1509 gp_Pnt P11, P12, P21, P22;
1511 myIsDone = Standard_True;
1513 IsParallel = Standard_False;
1514 IsCoincide = Standard_False;
1515 Tolang2 = Precision::Angular();
1516 Tol2 = myCriteria*myCriteria;
1518 gp_Lin C1 = myCFrom.Line();
1519 gp_Lin C2 = myCTo.Line();
1520 const gp_Dir& D1 = C1.Position().Direction();
1521 const gp_Dir& D2 = C2.Position().Direction();
1522 Standard_Real aCos = D1.Dot(D2);
1526 Ang2 = 2.*(1. - aCos);
1529 Ang2 = 2.*(1. + aCos);
1532 if(Ang2 <= Tolang2) {
1533 IsParallel = Standard_True;
1534 if(C2.SquareDistance(C1.Location()) <= Tol2) {
1535 IsCoincide = Standard_True;
1536 P11 = ElCLib::Value(myTminFrom, C1);
1537 P12 = ElCLib::Value(myTmaxFrom, C1);
1541 //Check coincidence of extremity points;
1542 //Check only shortest line
1543 P11 = ElCLib::Value(myTminFrom, C1);
1544 P12 = ElCLib::Value(myTmaxFrom, C1);
1545 if(C2.SquareDistance(P11) <= Tol2 && C2.SquareDistance(P12) <= Tol2) {
1546 IsCoincide = Standard_True;
1551 Standard_Real t21, t22;
1552 t21 = ElCLib::Parameter(C2, P11);
1553 t22 = ElCLib::Parameter(C2, P12);
1555 if((t21 > myTmaxTo && t22 > myTmaxTo) || (t21 < myTminTo && t22 < myTminTo)) {
1566 IntTools_CommonPrt aCommonPrt;
1567 aCommonPrt.SetEdge1(myCFrom.Edge());
1568 aCommonPrt.SetEdge2(myCTo.Edge());
1569 if(t21 >= myTminTo) {
1570 if(t22 <= myTmaxTo) {
1571 aCommonPrt.SetRange1(myTminFrom, myTmaxFrom);
1572 aCommonPrt.SetAllNullFlag(Standard_True);
1573 aCommonPrt.AppendRange2(t21, t22);
1576 aCommonPrt.SetRange1(myTminFrom, myTmaxFrom - (t22 - myTmaxTo));
1577 aCommonPrt.AppendRange2(t21, myTmaxTo);
1581 aCommonPrt.SetRange1(myTminFrom + (myTminTo - t21), myTmaxFrom);
1582 aCommonPrt.AppendRange2(myTminTo, t22);
1584 aCommonPrt.SetType(TopAbs_EDGE);
1585 mySeqOfCommonPrts.Append(aCommonPrt);
1595 TopoDS_Iterator aIt1, aIt2;
1597 aIt1.Initialize(myEdge1);
1598 for (; aIt1.More(); aIt1.Next()) {
1599 const TopoDS_Shape& aV1=aIt1.Value();
1600 aIt2.Initialize(myEdge2);
1601 for (; aIt2.More(); aIt2.Next()) {
1602 const TopoDS_Shape& aV2=aIt2.Value();
1603 if (aV2.IsSame(aV1)) {
1604 // the two straight lines have commpn vertex
1611 Standard_Real aSin2 = 1. - aCos*aCos;
1612 gp_Pnt O1 = C1.Location();
1613 gp_Pnt O2 = C2.Location();
1614 gp_Vec O1O2 (O1,O2);
1615 Standard_Real U2 = (D1.XYZ()*(O1O2.Dot(D1))-(O1O2.XYZ())).Dot(D2.XYZ());
1617 if(U2 < myTminTo || U2 > myTmaxTo) {
1621 gp_Pnt P2(ElCLib::Value(U2,C2));
1622 Standard_Real U1 = (gp_Vec(O1,P2)).Dot(D1);
1623 if(U1 < myTminFrom || U1 > myTmaxFrom) {
1627 gp_Pnt P1(ElCLib::Value(U1,C1));
1628 Standard_Real d2 = P1.SquareDistance(P2);
1634 IntTools_CommonPrt aCommonPrt;
1635 aCommonPrt.SetEdge1(myCFrom.Edge());
1636 aCommonPrt.SetEdge2(myCTo.Edge());
1637 aCommonPrt.SetRange1(U1 - myCriteria, U1 + myCriteria);
1638 aCommonPrt.AppendRange2(U2 - myCriteria, U2 + myCriteria);
1639 aCommonPrt.SetType(TopAbs_VERTEX);
1640 aCommonPrt.SetVertexParameter1(U1);
1641 aCommonPrt.SetVertexParameter2(U2);
1642 mySeqOfCommonPrts.Append(aCommonPrt);