1 // Created by: Eugeny MALTCHIKOV
2 // Copyright (c) 2013-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <IntTools_EdgeEdge.ixx>
22 #include <TopoDS_Iterator.hxx>
24 #include <Bnd_Box.hxx>
25 #include <BndLib_Add3dCurve.hxx>
27 #include <Geom_Circle.hxx>
28 #include <Geom_Ellipse.hxx>
29 #include <Geom_BezierCurve.hxx>
30 #include <Geom_BSplineCurve.hxx>
32 #include <GeomAPI_ProjectPointOnCurve.hxx>
34 #include <BRep_Tool.hxx>
35 #include <BRepAdaptor_Curve.hxx>
37 #include <IntTools_CommonPrt.hxx>
39 #include <BOPCol_MapOfInteger.hxx>
42 void BndBuildBox(const BRepAdaptor_Curve& theBAC,
43 const Standard_Real aT1,
44 const Standard_Real aT2,
45 const Standard_Real theTol,
48 Standard_Real PointBoxDistance(const Bnd_Box& aB,
51 void SplitRangeOnSegments(const Standard_Real aT1,
52 const Standard_Real aT2,
53 const Standard_Real theResolution,
54 const Standard_Integer theNbSeg,
55 IntTools_SequenceOfRanges& theSegments);
57 Standard_Integer DistPC(const Standard_Real aT1,
58 const Handle(Geom_Curve)& theC1,
59 const Standard_Real theCriteria,
60 GeomAPI_ProjectPointOnCurve& theProjector,
63 const Standard_Integer iC = 1);
65 Standard_Integer DistPC(const Standard_Real aT1,
66 const Handle(Geom_Curve)& theC1,
67 const Standard_Real theCriteria,
68 GeomAPI_ProjectPointOnCurve& theProjector,
72 Standard_Real& aT1max,
73 Standard_Real& aT2max,
74 const Standard_Integer iC = 1);
76 Standard_Integer FindDistPC(const Standard_Real aT1A,
77 const Standard_Real aT1B,
78 const Handle(Geom_Curve)& theC1,
79 const Standard_Real theCriteria,
80 const Standard_Real theEps,
81 GeomAPI_ProjectPointOnCurve& theProjector,
83 Standard_Real& aT1max,
84 Standard_Real& aT2max,
85 const Standard_Boolean bMaxDist = Standard_True);
87 Standard_Real ResolutionCoeff(const BRepAdaptor_Curve& theBAC,
88 const IntTools_Range& theRange);
90 Standard_Real Resolution(const Handle(Geom_Curve)& theCurve,
91 const GeomAbs_CurveType theCurveType,
92 const Standard_Real theResCoeff,
93 const Standard_Real theR3D);
95 Standard_Real CurveDeflection(const BRepAdaptor_Curve& theBAC,
96 const IntTools_Range& theRange);
98 Standard_Integer IsClosed(const Handle(Geom_Curve)& theCurve,
99 const Standard_Real aT1,
100 const Standard_Real aT2,
101 const Standard_Real theTol,
102 const Standard_Real theRes);
104 Standard_Integer TypeToInteger(const GeomAbs_CurveType theCType);
106 //=======================================================================
109 //=======================================================================
110 void IntTools_EdgeEdge::Prepare()
112 GeomAbs_CurveType aCT1, aCT2;
113 Standard_Integer iCT1, iCT2;
115 myCurve1.Initialize(myEdge1);
116 myCurve2.Initialize(myEdge2);
118 if (myRange1.First() == 0. && myRange1.Last() == 0.) {
119 myRange1.SetFirst(myCurve1.FirstParameter());
120 myRange1.SetLast (myCurve1.LastParameter());
123 if (myRange2.First() == 0. && myRange2.Last() == 0.) {
124 myRange2.SetFirst(myCurve2.FirstParameter());
125 myRange2.SetLast (myCurve2.LastParameter());
128 aCT1 = myCurve1.GetType();
129 aCT2 = myCurve2.GetType();
131 iCT1 = TypeToInteger(aCT1);
132 iCT2 = TypeToInteger(aCT2);
137 Standard_Real aC1, aC2;
139 aC2 = CurveDeflection(myCurve2, myRange2);
140 aC1 = (aC2 > Precision::Confusion()) ?
141 CurveDeflection(myCurve1, myRange1) : 1.;
150 TopoDS_Edge tmpE = myEdge1;
154 BRepAdaptor_Curve tmpC = myCurve1;
158 IntTools_Range tmpR = myRange1;
162 mySwap = Standard_True;
165 myTol1 = myCurve1.Tolerance();
166 myTol2 = myCurve2.Tolerance();
167 myTol = myTol1 + myTol2;
169 if (iCT1 != 0 || iCT2 != 0) {
170 Standard_Real f, l, aTM;
172 myGeom1 = BRep_Tool::Curve(myEdge1, f, l);
173 myGeom2 = BRep_Tool::Curve(myEdge2, f, l);
175 myResCoeff1 = ResolutionCoeff(myCurve1, myRange1);
176 myResCoeff2 = ResolutionCoeff(myCurve2, myRange2);
178 myRes1 = Resolution(myCurve1.Curve().Curve(), myCurve1.GetType(), myResCoeff1, myTol1);
179 myRes2 = Resolution(myCurve2.Curve().Curve(), myCurve2.GetType(), myResCoeff2, myTol2);
182 aTM = Max(fabs(myRange1.First()), fabs(myRange1.Last()));
184 myPTol1 = 5.e-16 * aTM;
188 aTM = Max(fabs(myRange2.First()), fabs(myRange2.Last()));
190 myPTol2 = 5.e-16 * aTM;
195 //=======================================================================
198 //=======================================================================
199 void IntTools_EdgeEdge::Perform()
210 //3.1. Check Line/Line case
211 if (myCurve1.GetType() == GeomAbs_Line &&
212 myCurve2.GetType() == GeomAbs_Line) {
217 IntTools_SequenceOfRanges aRanges1, aRanges2;
219 //3.2. Find ranges containig solutions
220 Standard_Boolean bSplit2;
221 FindSolutions(aRanges1, aRanges2, bSplit2);
223 //4. Merge solutions and save common parts
224 MergeSolutions(aRanges1, aRanges2, bSplit2);
227 //=======================================================================
228 //function : FindSolutions
230 //=======================================================================
231 void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
232 IntTools_SequenceOfRanges& theRanges2,
233 Standard_Boolean& bSplit2)
235 Standard_Boolean bIsClosed2;
236 Standard_Real aT11, aT12, aT21, aT22;
239 bSplit2 = Standard_False;
240 myRange1.Range(aT11, aT12);
241 myRange2.Range(aT21, aT22);
243 bIsClosed2 = IsClosed(myGeom2, aT21, aT22, myTol2, myRes2);
247 BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
249 gp_Pnt aP = myGeom2->Value(aT21);
250 bIsClosed2 = !aB1.IsOut(aP);
254 BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
255 FindSolutions(myRange1, myRange2, aB2, theRanges1, theRanges2);
259 if (!CheckCoincidence(aT11, aT12, aT21, aT22, myTol, myRes1)) {
260 theRanges1.Append(myRange1);
261 theRanges2.Append(myRange2);
265 Standard_Integer i, j, aNb1, aNb2;
266 IntTools_SequenceOfRanges aSegments1, aSegments2;
268 aNb1 = IsClosed(myGeom1, aT11, aT12, myTol1, myRes1) ? 2 : 1;
271 SplitRangeOnSegments(aT11, aT12, myRes1, aNb1, aSegments1);
272 SplitRangeOnSegments(aT21, aT22, myRes2, aNb2, aSegments2);
274 aNb1 = aSegments1.Length();
275 aNb2 = aSegments2.Length();
276 for (i = 1; i <= aNb1; ++i) {
277 const IntTools_Range& aR1 = aSegments1(i);
278 for (j = 1; j <= aNb2; ++j) {
279 const IntTools_Range& aR2 = aSegments2(j);
280 BndBuildBox(myCurve2, aR2.First(), aR2.Last(), myTol2, aB2);
281 FindSolutions(aR1, aR2, aB2, theRanges1, theRanges2);
288 //=======================================================================
289 //function : FindSolutions
291 //=======================================================================
292 void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
293 const IntTools_Range& theR2,
294 const Bnd_Box& theBox2,
295 IntTools_SequenceOfRanges& theRanges1,
296 IntTools_SequenceOfRanges& theRanges2)
298 Standard_Boolean bOut, bStop, bThin;
299 Standard_Real aT11, aT12, aT21, aT22;
300 Standard_Real aTB11, aTB12, aTB21, aTB22;
301 Standard_Real aSmallStep1, aSmallStep2;
302 Standard_Integer iCom;
305 theR1.Range(aT11, aT12);
306 theR2.Range(aT21, aT22);
310 bThin = Standard_False;
311 bStop = Standard_False;
320 //1. Build box for first edge and find parameters
321 // of the second one in that box
322 BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
323 bOut = aB1.IsOut(aB2);
328 bThin = ((aT12 - aT11) < myRes1) ||
329 (aB1.IsXThin(myTol) && aB1.IsYThin(myTol) && aB1.IsZThin(myTol));
331 bOut = !FindParameters(myCurve2, aTB21, aTB22, myRes2, myPTol2,
332 myResCoeff2, aB1, aT21, aT22);
337 //2. Build box for second edge and find parameters
338 // of the first one in that box
339 BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
340 bOut = aB1.IsOut(aB2);
345 bThin = ((aT22 - aT21) < myRes2) ||
346 (aB2.IsXThin(myTol) && aB2.IsYThin(myTol) && aB2.IsZThin(myTol));
348 bOut = !FindParameters(myCurve1, aTB11, aTB12, myRes1, myPTol1,
349 myResCoeff1, aB2, aT11, aT12);
355 //3. Check if it makes sense to continue
356 aSmallStep1 = (aTB12 - aTB11) / 250.;
357 aSmallStep2 = (aTB22 - aTB21) / 250.;
359 if (aSmallStep1 < myRes1) {
360 aSmallStep1 = myRes1;
362 if (aSmallStep2 < myRes2) {
363 aSmallStep2 = myRes2;
366 if (((aT11 - aTB11) < aSmallStep1) && ((aTB12 - aT12) < aSmallStep1) &&
367 ((aT21 - aTB21) < aSmallStep2) && ((aTB22 - aT22) < aSmallStep2)) {
368 bStop = Standard_True;
379 //check curves for coincidence on the ranges
380 iCom = CheckCoincidence(aT11, aT12, aT21, aT22, myTol, myRes1);
382 bThin = Standard_True;
388 //check intermediate points
389 Standard_Boolean bSol;
392 GeomAPI_ProjectPointOnCurve aProjPC;
394 aT1 = (aT11 + aT12) * .5;
395 myGeom1->D0(aT1, aP1);
397 aProjPC.Init(myGeom2, aT21, aT22);
398 aProjPC.Perform(aP1);
400 if (aProjPC.NbPoints()) {
401 bSol = aProjPC.LowerDistance() <= myTol;
407 aT2 = (aT21 + aT22) * .5;
408 myGeom2->D0(aT2, aP2);
410 bSol = aP1.IsEqual(aP2, myTol);
418 IntTools_Range aR1(aT11, aT12), aR2(aT21, aT22);
420 theRanges1.Append(aR1);
421 theRanges2.Append(aR2);
425 if (!IsIntersection(aT11, aT12, aT21, aT22)) {
429 //split ranges on segments and repeat
430 Standard_Integer i, aNb1;
431 IntTools_SequenceOfRanges aSegments1;
433 IntTools_Range aR2(aT21, aT22);
434 BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
436 SplitRangeOnSegments(aT11, aT12, myRes1, 3, aSegments1);
437 aNb1 = aSegments1.Length();
438 for (i = 1; i <= aNb1; ++i) {
439 const IntTools_Range& aR1 = aSegments1(i);
440 FindSolutions(aR1, aR2, aB2, theRanges1, theRanges2);
444 //=======================================================================
445 //function : FindParameters
447 //=======================================================================
448 Standard_Boolean IntTools_EdgeEdge::FindParameters(const BRepAdaptor_Curve& theBAC,
449 const Standard_Real aT1,
450 const Standard_Real aT2,
451 const Standard_Real theRes,
452 const Standard_Real thePTol,
453 const Standard_Real theResCoeff,
454 const Bnd_Box& theCBox,
458 Standard_Boolean bRet;
459 Standard_Integer aC, i, k;
460 Standard_Real aCf, aDiff, aDt, aT, aTB, aTOut, aTIn;
461 Standard_Real aDist, aDistP, aDistTol, aTol;
465 bRet = Standard_False;
466 aCf = 0.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.))/2.;
468 aTol = theBAC.Tolerance();
470 aDistTol = Precision::PConfusion();
474 const Handle(Geom_Curve)& aCurve = theBAC.Curve().Curve();
475 const GeomAbs_CurveType aCurveType = theBAC.GetType();
477 for (i = 0; i < 2; ++i) {
478 aTB = !i ? aT1 : aT2;
479 aT = !i ? aT2 : aTB1;
481 bRet = Standard_False;
483 //looking for the point on the edge which is in the box;
484 while (aC*(aT-aTB) >= 0) {
486 aDist = PointBoxDistance(theCBox, aP);
488 if (fabs(aDist - aDistP) < aDistTol) {
489 aDt = Resolution(aCurve, aCurveType, theResCoeff, (++k)*aDist);
492 aDt = Resolution(aCurve, aCurveType, theResCoeff, aDist);
496 bRet = Standard_True;
504 //edge is out of the box;
515 //one point IN, one point OUT; looking for the bounding point;
517 aTOut = aTB - aC*aDt;
518 aDiff = aTIn - aTOut;
519 while (fabs(aDiff) > thePTol) {
520 aTB = aTOut + aDiff*aCf;
522 if (aCBx.IsOut(aP)) {
527 aDiff = aTIn - aTOut;
539 //=======================================================================
540 //function : MergeSolutions
542 //=======================================================================
543 void IntTools_EdgeEdge::MergeSolutions(const IntTools_SequenceOfRanges& theRanges1,
544 const IntTools_SequenceOfRanges& theRanges2,
545 const Standard_Boolean bSplit2)
547 Standard_Integer aNbCP = theRanges1.Length();
552 IntTools_Range aRi1, aRi2, aRj1, aRj2;
553 Standard_Boolean bCond;
554 Standard_Integer i, j;
555 TopAbs_ShapeEnum aType;
556 Standard_Real aT11, aT12, aT21, aT22;
557 Standard_Real aTi11, aTi12, aTi21, aTi22;
558 Standard_Real aTj11, aTj12, aTj21, aTj22;
559 Standard_Real aRes1, aRes2, dTR1, dTR2;
560 BOPCol_MapOfInteger aMI;
562 aRes1 = Resolution(myCurve1.Curve().Curve(),
563 myCurve1.GetType(), myResCoeff1, myTol);
564 aRes2 = Resolution(myCurve2.Curve().Curve(),
565 myCurve2.GetType(), myResCoeff2, myTol);
567 myRange1.Range(aT11, aT12);
568 myRange2.Range(aT21, aT22);
571 aType = TopAbs_VERTEX;
573 for (i = 1; i <= aNbCP;) {
574 if (aMI.Contains(i)) {
579 aRi1 = theRanges1(i);
580 aRi2 = theRanges2(i);
582 aRi1.Range(aTi11, aTi12);
583 aRi2.Range(aTi21, aTi22);
587 for (j = i+1; j <= aNbCP; ++j) {
588 if (aMI.Contains(j)) {
592 aRj1 = theRanges1(j);
593 aRj2 = theRanges2(j);
595 aRj1.Range(aTj11, aTj12);
596 aRj2.Range(aTj21, aTj22);
598 bCond = (fabs(aTi12 - aTj11) < dTR1) ||
599 (bSplit2 && (fabs(aTj12 - aTi11) < dTR1));
600 if (bCond && bSplit2) {
601 bCond = (fabs((Max(aTi22, aTj22) - Min(aTi21, aTj21)) -
602 ((aTi22 - aTi21) + (aTj22 - aTj21))) < dTR2);
606 aTi11 = Min(aTi11, aTj11);
607 aTi12 = Max(aTi12, aTj12);
608 aTi21 = Min(aTi21, aTj21);
609 aTi22 = Max(aTi22, aTj22);
618 if (((fabs(aT11 - aTi11) < myRes1) && (fabs(aT12 - aTi12) < myRes1)) ||
619 ((fabs(aT21 - aTi21) < myRes2) && (fabs(aT22 - aTi22) < myRes2))) {
621 myCommonParts.Clear();
624 AddSolution(aTi11, aTi12, aTi21, aTi22, aType);
625 if (aType == TopAbs_EDGE) {
635 //=======================================================================
636 //function : AddSolution
638 //=======================================================================
639 void IntTools_EdgeEdge::AddSolution(const Standard_Real aT11,
640 const Standard_Real aT12,
641 const Standard_Real aT21,
642 const Standard_Real aT22,
643 const TopAbs_ShapeEnum theType)
645 IntTools_CommonPrt aCPart;
647 aCPart.SetType(theType);
649 aCPart.SetEdge1(myEdge1);
650 aCPart.SetEdge2(myEdge2);
651 aCPart.SetRange1(aT11, aT12);
652 aCPart.AppendRange2(aT21, aT22);
654 aCPart.SetEdge1(myEdge2);
655 aCPart.SetEdge2(myEdge1);
656 aCPart.SetRange1(aT21, aT22);
657 aCPart.AppendRange2(aT11, aT12);
660 if (theType == TopAbs_VERTEX) {
661 Standard_Real aT1, aT2;
663 FindBestSolution(aT11, aT12, aT21, aT22, aT1, aT2);
666 aCPart.SetVertexParameter1(aT1);
667 aCPart.SetVertexParameter2(aT2);
669 aCPart.SetVertexParameter1(aT2);
670 aCPart.SetVertexParameter2(aT1);
673 myCommonParts.Append(aCPart);
676 //=======================================================================
677 //function : FindBestSolution
679 //=======================================================================
680 void IntTools_EdgeEdge::FindBestSolution(const Standard_Real aT11,
681 const Standard_Real aT12,
682 const Standard_Real aT21,
683 const Standard_Real aT22,
687 Standard_Integer i, aNbS, iErr;
688 Standard_Real aDMin, aD, aCrit, aRes1;
689 Standard_Real aT1x, aT2x, aT1p, aT2p;
690 GeomAPI_ProjectPointOnCurve aProj;
691 IntTools_SequenceOfRanges aSeg1;
693 aT1 = (aT11 + aT12) * .5;
694 aT2 = (aT21 + aT22) * .5;
700 aRes1 = Resolution(myCurve1.Curve().Curve(),
701 myCurve1.GetType(), myResCoeff1, myTol);
703 SplitRangeOnSegments(aT11, aT12, 3*aRes1, aNbS, aSeg1);
704 aNbS = aSeg1.Length();
706 aProj.Init(myGeom2, aT21, aT22);
707 for (i = 1; i <= aNbS; ++i) {
708 const IntTools_Range& aR1 = aSeg1(i);
709 aR1.Range(aT1x, aT2x);
711 iErr = FindDistPC(aT1x, aT2x, myGeom1, aCrit, myPTol1,
712 aProj, aD, aT1p, aT2p, Standard_False);
713 if (iErr != 1 && aD < aDMin) {
717 if (aDMin <= aCrit) {
724 //=======================================================================
725 //function : ComputeLineLine
727 //=======================================================================
728 void IntTools_EdgeEdge::ComputeLineLine()
730 Standard_Boolean IsParallel, IsCoincide;
731 Standard_Real aSin, aCos, aAng, aTol;
732 Standard_Real aT1, aT2, aT11, aT12, aT21, aT22;
736 IntTools_CommonPrt aCommonPrt;
738 IsParallel = Standard_False;
739 IsCoincide = Standard_False;
741 aL1 = myCurve1.Line();
742 aL2 = myCurve2.Line();
743 aD1 = aL1.Position().Direction();
744 aD2 = aL2.Position().Direction();
745 myRange1.Range(aT11, aT12);
746 myRange2.Range(aT21, aT22);
748 aCommonPrt.SetEdge1(myEdge1);
749 aCommonPrt.SetEdge2(myEdge2);
752 aAng = (aCos >= 0.) ? 2.*(1. - aCos) : 2.*(1. + aCos);
754 if(aAng <= Precision::Angular()) {
755 IsParallel = Standard_True;
756 if(aL1.SquareDistance(aL2.Location()) <= aTol) {
757 IsCoincide = Standard_True;
758 aP11 = ElCLib::Value(aT11, aL1);
759 aP12 = ElCLib::Value(aT12, aL1);
763 aP11 = ElCLib::Value(aT11, aL1);
764 aP12 = ElCLib::Value(aT12, aL1);
765 if(aL2.SquareDistance(aP11) <= aTol && aL2.SquareDistance(aP12) <= aTol) {
766 IsCoincide = Standard_True;
771 Standard_Real t21, t22;
773 t21 = ElCLib::Parameter(aL2, aP11);
774 t22 = ElCLib::Parameter(aL2, aP12);
775 if((t21 > aT22 && t22 > aT22) || (t21 < aT21 && t22 < aT21)) {
788 aCommonPrt.SetRange1(aT11, aT12);
789 aCommonPrt.SetAllNullFlag(Standard_True);
790 aCommonPrt.AppendRange2(t21, t22);
793 aCommonPrt.SetRange1(aT11, aT12 - (t22 - aT22));
794 aCommonPrt.AppendRange2(t21, aT22);
798 aCommonPrt.SetRange1(aT11 + (aT21 - t21), aT12);
799 aCommonPrt.AppendRange2(aT21, t22);
801 aCommonPrt.SetType(TopAbs_EDGE);
802 myCommonParts.Append(aCommonPrt);
811 TopoDS_Iterator aIt1, aIt2;
812 aIt1.Initialize(myEdge1);
813 for (; aIt1.More(); aIt1.Next()) {
814 const TopoDS_Shape& aV1 = aIt1.Value();
815 aIt2.Initialize(myEdge2);
816 for (; aIt2.More(); aIt2.Next()) {
817 const TopoDS_Shape& aV2 = aIt2.Value();
818 if (aV2.IsSame(aV1)) {
825 aSin = 1. - aCos*aCos;
826 gp_Pnt O1 = aL1.Location();
827 gp_Pnt O2 = aL2.Location();
828 gp_Vec O1O2 (O1, O2);
830 aT2 = (aD1.XYZ()*(O1O2.Dot(aD1))-(O1O2.XYZ())).Dot(aD2.XYZ());
833 if(aT2 < aT21 || aT2 > aT22) {
837 gp_Pnt aP2(ElCLib::Value(aT2, aL2));
838 aT1 = (gp_Vec(O1, aP2)).Dot(aD1);
840 if(aT1 < aT11 || aT1 > aT12) {
844 gp_Pnt aP1(ElCLib::Value(aT1, aL1));
845 Standard_Real aDist = aP1.SquareDistance(aP2);
851 aCommonPrt.SetRange1(aT1 - myTol, aT1 + myTol);
852 aCommonPrt.AppendRange2(aT2 - myTol, aT2 + myTol);
853 aCommonPrt.SetType(TopAbs_VERTEX);
854 aCommonPrt.SetVertexParameter1(aT1);
855 aCommonPrt.SetVertexParameter2(aT2);
856 myCommonParts.Append(aCommonPrt);
859 //=======================================================================
860 //function : IsIntersection
862 //=======================================================================
863 Standard_Boolean IntTools_EdgeEdge::IsIntersection(const Standard_Real aT11,
864 const Standard_Real aT12,
865 const Standard_Real aT21,
866 const Standard_Real aT22)
868 Standard_Boolean bRet;
869 gp_Pnt aP11, aP12, aP21, aP22;
870 gp_Vec aV11, aV12, aV21, aV22;
871 Standard_Real aD11_21, aD11_22, aD12_21, aD12_22, aCriteria, aCoef;
872 Standard_Boolean bSmall_11_21, bSmall_11_22, bSmall_12_21, bSmall_12_22;
874 bRet = Standard_True;
876 if (((aT12 - aT11) > aCoef*myRes1) && ((aT22 - aT21) > aCoef*myRes2)) {
879 Standard_Real aTRMin = Min((aT12 - aT11)/myRes1, (aT22 - aT21)/myRes2);
880 aCoef = aTRMin / 100.;
885 aCriteria = aCoef * myTol;
886 aCriteria *= aCriteria;
888 myGeom1->D1(aT11, aP11, aV11);
889 myGeom1->D1(aT12, aP12, aV12);
890 myGeom2->D1(aT21, aP21, aV21);
891 myGeom2->D1(aT22, aP22, aV22);
893 aD11_21 = aP11.SquareDistance(aP21);
894 aD11_22 = aP11.SquareDistance(aP22);
895 aD12_21 = aP12.SquareDistance(aP21);
896 aD12_22 = aP12.SquareDistance(aP22);
898 bSmall_11_21 = aD11_21 < aCriteria;
899 bSmall_11_22 = aD11_22 < aCriteria;
900 bSmall_12_21 = aD12_21 < aCriteria;
901 bSmall_12_22 = aD12_22 < aCriteria;
903 if ((bSmall_11_21 && bSmall_12_22) ||
904 (bSmall_11_22 && bSmall_12_21)) {
909 Standard_Real anAngleCriteria;
910 Standard_Real anAngle1, anAngle2;
912 anAngleCriteria = 5.e-3;
913 if (bSmall_11_21 && bSmall_12_22) {
914 anAngle1 = aV11.Angle(aV21);
915 anAngle2 = aV12.Angle(aV22);
917 anAngle1 = aV11.Angle(aV22);
918 anAngle2 = aV12.Angle(aV21);
921 if (((anAngle1 < anAngleCriteria) || ((M_PI - anAngle1) < anAngleCriteria)) ||
922 ((anAngle2 < anAngleCriteria) || ((M_PI - anAngle2) < anAngleCriteria))) {
923 GeomAPI_ProjectPointOnCurve aProj;
924 Standard_Integer iErr;
925 Standard_Real aD, aT1p, aT2p;
928 aProj.Init(myGeom2, aT21, aT22);
929 iErr = FindDistPC(aT11, aT12, myGeom1, myTol, myRes1, aProj, aD, aT1p, aT2p, Standard_False);
936 //=======================================================================
937 //function : CheckCoincidence
939 //=======================================================================
940 Standard_Integer IntTools_EdgeEdge::CheckCoincidence(const Standard_Real aT11,
941 const Standard_Real aT12,
942 const Standard_Real aT21,
943 const Standard_Real aT22,
944 const Standard_Real theCriteria,
945 const Standard_Real theCurveRes1)
947 Standard_Integer iErr, aNb, aNb1, i;
948 Standard_Real aT1A, aT1B, aT1max, aT2max, aDmax;
949 GeomAPI_ProjectPointOnCurve aProjPC;
950 IntTools_SequenceOfRanges aSeg1;
954 aProjPC.Init(myGeom2, aT21, aT22);
956 // 1. Express evaluation
957 aNb = 10; // Number of intervals on the curve #1
958 SplitRangeOnSegments(aT11, aT12, theCurveRes1, aNb, aSeg1);
959 aNb1 = aSeg1.Length();
960 for (i = 1; i < aNb1; ++i) {
961 const IntTools_Range& aR1 = aSeg1(i);
962 aR1.Range(aT1A, aT1B);
964 iErr = DistPC(aT1B, myGeom1, theCriteria, aProjPC, aDmax, aT2max);
970 // if the ranges in aSeg1 are less than theCurveRes1,
971 // there is no need to do step 2 (deep evaluation)
976 // 2. Deep evaluation
977 for (i = 2; i < aNb1; ++i) {
978 const IntTools_Range& aR1 = aSeg1(i);
979 aR1.Range(aT1A, aT1B);
981 iErr = FindDistPC(aT1A, aT1B, myGeom1, theCriteria, theCurveRes1,
982 aProjPC, aDmax, aT1max, aT2max);
988 // iErr == 0 - the patches are coincided
989 // iErr == 1 - a point from aC1 can not be projected on aC2
990 // iErr == 2 - the distance is too big
994 //=======================================================================
995 //function : FindDistPC
997 //=======================================================================
998 Standard_Integer FindDistPC(const Standard_Real aT1A,
999 const Standard_Real aT1B,
1000 const Handle(Geom_Curve)& theC1,
1001 const Standard_Real theCriteria,
1002 const Standard_Real theEps,
1003 GeomAPI_ProjectPointOnCurve& theProjPC,
1004 Standard_Real& aDmax,
1005 Standard_Real& aT1max,
1006 Standard_Real& aT2max,
1007 const Standard_Boolean bMaxDist)
1009 Standard_Integer iErr, iC;
1010 Standard_Real aGS, aXP, aA, aB, aXL, aYP, aYL, aT2P, aT2L;
1012 iC = bMaxDist ? 1 : -1;
1015 aGS = 0.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.))-1.;
1020 iErr = DistPC(aA, theC1, theCriteria, theProjPC, aYP, aT2P, aDmax, aT1max, aT2max, iC);
1025 iErr = DistPC(aB, theC1, theCriteria, theProjPC, aYL, aT2L, aDmax, aT1max, aT2max, iC);
1030 aXP = aA + (aB - aA)*aGS;
1031 aXL = aB - (aB - aA)*aGS;
1033 iErr = DistPC(aXP, theC1, theCriteria, theProjPC, aYP, aT2P, aDmax, aT1max, aT2max, iC);
1038 iErr = DistPC(aXL, theC1, theCriteria, theProjPC, aYL, aT2L, aDmax, aT1max, aT2max, iC);
1044 if (iC*(aYP - aYL) > 0) {
1048 aXP = aA + (aB - aA)*aGS;
1049 iErr = DistPC(aXP, theC1, theCriteria, theProjPC, aYP, aT2P, aDmax, aT1max, aT2max, iC);
1058 aXL = aB - (aB - aA)*aGS;
1059 iErr = DistPC(aXL, theC1, theCriteria, theProjPC, aYL, aT2L, aDmax, aT1max, aT2max, iC);
1065 if ((aB - aA) < theEps) {
1072 //=======================================================================
1075 //=======================================================================
1076 Standard_Integer DistPC(const Standard_Real aT1,
1077 const Handle(Geom_Curve)& theC1,
1078 const Standard_Real theCriteria,
1079 GeomAPI_ProjectPointOnCurve& theProjPC,
1082 Standard_Real& aDmax,
1083 Standard_Real& aT1max,
1084 Standard_Real& aT2max,
1085 const Standard_Integer iC)
1087 Standard_Integer iErr;
1089 iErr = DistPC(aT1, theC1, theCriteria, theProjPC, aD, aT2, iC);
1094 if (iC*(aD - aDmax) > 0) {
1102 //=======================================================================
1105 //=======================================================================
1106 Standard_Integer DistPC(const Standard_Real aT1,
1107 const Handle(Geom_Curve)& theC1,
1108 const Standard_Real theCriteria,
1109 GeomAPI_ProjectPointOnCurve& theProjPC,
1112 const Standard_Integer iC)
1114 Standard_Integer iErr, aNbP2;
1118 theC1->D0(aT1, aP1);
1120 theProjPC.Perform(aP1);
1121 aNbP2 = theProjPC.NbPoints();
1123 iErr = 1;// the point from aC1 can not be projected on aC2
1127 aD = theProjPC.LowerDistance();
1128 aT2 = theProjPC.LowerDistanceParameter();
1129 if (iC*(aD - theCriteria) > 0) {
1130 iErr = 2;// the distance is too big or small
1136 //=======================================================================
1137 //function : SplitRangeOnSegments
1139 //=======================================================================
1140 void SplitRangeOnSegments(const Standard_Real aT1,
1141 const Standard_Real aT2,
1142 const Standard_Real theResolution,
1143 const Standard_Integer theNbSeg,
1144 IntTools_SequenceOfRanges& theSegments)
1146 Standard_Real aDiff = aT2 - aT1;
1147 if (aDiff < theResolution || theNbSeg == 1) {
1148 theSegments.Append(IntTools_Range(aT1, aT2));
1152 Standard_Real aDt, aT1x, aT2x, aSeg;
1153 Standard_Integer aNbSegments, i;
1155 aNbSegments = theNbSeg;
1156 aDt = aDiff / aNbSegments;
1157 if (aDt < theResolution) {
1158 aSeg = aDiff / theResolution;
1159 aNbSegments = Standard_Integer(aSeg) + 1;
1160 aDt = aDiff / aNbSegments;
1164 for (i = 1; i < aNbSegments; ++i) {
1167 IntTools_Range aR(aT1x, aT2x);
1168 theSegments.Append(aR);
1173 IntTools_Range aR(aT1x, aT2);
1174 theSegments.Append(aR);
1177 //=======================================================================
1178 //function : BndBuildBox
1180 //=======================================================================
1181 void BndBuildBox(const BRepAdaptor_Curve& theBAC,
1182 const Standard_Real aT1,
1183 const Standard_Real aT2,
1184 const Standard_Real theTol,
1188 BndLib_Add3dCurve::Add(theBAC, aT1, aT2, theTol, aB);
1192 //=======================================================================
1193 //function : PointBoxDistance
1195 //=======================================================================
1196 Standard_Real PointBoxDistance(const Bnd_Box& aB,
1199 Standard_Real aPCoord[3];
1200 Standard_Real aBMinCoord[3], aBMaxCoord[3];
1201 Standard_Real aDist, aR1, aR2;
1204 aP.Coord(aPCoord[0], aPCoord[1], aPCoord[2]);
1205 aB.Get(aBMinCoord[0], aBMinCoord[1], aBMinCoord[2],
1206 aBMaxCoord[0], aBMaxCoord[1], aBMaxCoord[2]);
1209 for (i = 0; i < 3; ++i) {
1210 aR1 = aBMinCoord[i] - aPCoord[i];
1216 aR2 = aPCoord[i] - aBMaxCoord[i];
1222 aDist = Sqrt(aDist);
1226 //=======================================================================
1227 //function : TypeToInteger
1229 //=======================================================================
1230 Standard_Integer TypeToInteger(const GeomAbs_CurveType theCType)
1232 Standard_Integer iRet;
1238 case GeomAbs_Hyperbola:
1239 case GeomAbs_Parabola:
1242 case GeomAbs_Circle:
1243 case GeomAbs_Ellipse:
1246 case GeomAbs_BezierCurve:
1247 case GeomAbs_BSplineCurve:
1257 //=======================================================================
1258 //function : ResolutionCoeff
1260 //=======================================================================
1261 Standard_Real ResolutionCoeff(const BRepAdaptor_Curve& theBAC,
1262 const IntTools_Range& theRange)
1264 Standard_Real aResCoeff;
1266 const Handle(Geom_Curve)& aCurve = theBAC.Curve().Curve();
1267 const GeomAbs_CurveType aCurveType = theBAC.GetType();
1269 switch (aCurveType) {
1270 case GeomAbs_Circle :
1271 aResCoeff = 1. / (2 * (*((Handle(Geom_Circle)*)&aCurve))->Circ().Radius());
1273 case GeomAbs_Ellipse :
1274 aResCoeff = 1. / (*((Handle(Geom_Ellipse)*)&aCurve))->MajorRadius();
1276 case GeomAbs_Hyperbola :
1277 case GeomAbs_Parabola :
1278 case GeomAbs_OtherCurve :{
1279 Standard_Real k, kMin, aDist, aDt, aT1, aT2, aT;
1280 Standard_Integer aNbP, i;
1284 theRange.Range(aT1, aT2);
1285 aDt = (aT2 - aT1) / aNbP;
1289 theBAC.D0(aT1, aP1);
1290 for (i = 1; i <= aNbP; ++i) {
1293 aDist = aP1.Distance(aP2);
1312 //=======================================================================
1313 //function : Resolution
1315 //=======================================================================
1316 Standard_Real Resolution(const Handle(Geom_Curve)& theCurve,
1317 const GeomAbs_CurveType theCurveType,
1318 const Standard_Real theResCoeff,
1319 const Standard_Real theR3D)
1323 switch (theCurveType) {
1327 case GeomAbs_Circle: {
1328 Standard_Real aDt = theResCoeff * theR3D;
1329 aRes = (aDt <= 1.) ? 2*ASin(aDt) : 2*M_PI;
1332 case GeomAbs_BezierCurve:
1333 (*((Handle(Geom_BezierCurve)*)&theCurve))->Resolution(theR3D, aRes);
1335 case GeomAbs_BSplineCurve:
1336 (*((Handle(Geom_BSplineCurve)*)&theCurve))->Resolution(theR3D, aRes);
1339 aRes = theResCoeff * theR3D;
1346 //=======================================================================
1347 //function : CurveDeflection
1349 //=======================================================================
1350 Standard_Real CurveDeflection(const BRepAdaptor_Curve& theBAC,
1351 const IntTools_Range& theRange)
1353 Standard_Real aDt, aT, aT1, aT2, aDefl;
1354 Standard_Integer i, aNbP;
1360 theRange.Range(aT1, aT2);
1361 aDt = (aT2 - aT1) / aNbP;
1364 theBAC.D1(aT1, aP, aV1);
1365 for (i = 1; i <= aNbP; ++i) {
1367 theBAC.D1(aT, aP, aV2);
1368 if (aV1.Magnitude() > gp::Resolution() &&
1369 aV2.Magnitude() > gp::Resolution()) {
1370 gp_Dir aD1(aV1), aD2(aV2);
1371 aDefl += aD1.Angle(aD2);
1379 //=======================================================================
1380 //function : IsClosed
1382 //=======================================================================
1383 Standard_Integer IsClosed(const Handle(Geom_Curve)& theCurve,
1384 const Standard_Real aT1,
1385 const Standard_Real aT2,
1386 const Standard_Real theTol,
1387 const Standard_Real theRes)
1389 Standard_Boolean bClosed;
1393 bClosed = Standard_False;
1394 if (Abs(aT1 - aT2) < theRes) {
1398 theCurve->D0(aT1, aP1);
1399 theCurve->D0(aT2, aP2);
1401 aD = aP1.Distance(aP2);
1402 bClosed = aD < theTol;