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 <GeomAPI_ProjectPointOnCurve.hxx>
29 #include <BRep_Tool.hxx>
30 #include <BRepAdaptor_Curve.hxx>
32 #include <IntTools_Tools.hxx>
33 #include <IntTools_CommonPrt.hxx>
37 void BndBuildBox(const BRepAdaptor_Curve& theBAC,
38 const Standard_Real aT1,
39 const Standard_Real aT2,
40 const Standard_Real theTol,
43 Standard_Real PointBoxDistance(const Bnd_Box& aB,
46 void SplitRangeOnSegments(const Standard_Real aT1,
47 const Standard_Real aT2,
48 const Standard_Real theResolution,
49 const Standard_Integer theNbSeg,
50 IntTools_SequenceOfRanges& theSegments);
52 Standard_Integer DistPC(const Standard_Real aT1,
53 const Handle(Geom_Curve)& theC1,
54 const Standard_Real theCriteria,
55 GeomAPI_ProjectPointOnCurve& theProjector,
58 const Standard_Integer iC = 1);
60 Standard_Integer DistPC(const Standard_Real aT1,
61 const Handle(Geom_Curve)& theC1,
62 const Standard_Real theCriteria,
63 GeomAPI_ProjectPointOnCurve& theProjector,
67 Standard_Real& aT1max,
68 Standard_Real& aT2max,
69 const Standard_Integer iC = 1);
71 Standard_Integer FindDistPC(const Standard_Real aT1A,
72 const Standard_Real aT1B,
73 const Handle(Geom_Curve)& theC1,
74 const Standard_Real theCriteria,
75 const Standard_Real theEps,
76 GeomAPI_ProjectPointOnCurve& theProjector,
78 Standard_Real& aT1max,
79 Standard_Real& aT2max,
80 const Standard_Boolean bMaxDist = Standard_True);
82 Standard_Integer TypeToInteger(const GeomAbs_CurveType theCType);
84 //=======================================================================
87 //=======================================================================
88 void IntTools_EdgeEdge::Prepare()
90 GeomAbs_CurveType aCT1, aCT2;
91 Standard_Integer iCT1, iCT2;
93 myCurve1.Initialize(myEdge1);
94 myCurve2.Initialize(myEdge2);
96 if (myRange1.First() == 0. && myRange1.Last() == 0.) {
97 myRange1.SetFirst(myCurve1.FirstParameter());
98 myRange1.SetLast (myCurve1.LastParameter());
101 if (myRange2.First() == 0. && myRange2.Last() == 0.) {
102 myRange2.SetFirst(myCurve2.FirstParameter());
103 myRange2.SetLast (myCurve2.LastParameter());
106 aCT1 = myCurve1.GetType();
107 aCT2 = myCurve2.GetType();
109 iCT1 = TypeToInteger(aCT1);
110 iCT2 = TypeToInteger(aCT2);
116 Standard_Real aDt, aT, aT1, aT2;
120 Standard_Real aC1(10.), aC2(10.);
121 for (i = 0; i < 2; ++i) {
122 Standard_Real &aC = !i ? aC2 : aC1;
124 IntTools_Range aR = !i ? myRange2 : myRange1;
125 const BRepAdaptor_Curve& aBAC = !i ? myCurve2 : myCurve1;
127 aDt = (aT2 - aT1) / 10.;
129 aBAC.D1(aT, aP, aV1);
132 aBAC.D1(aT, aP, aV2);
133 if (aV1.Magnitude() > gp::Resolution() &&
134 aV2.Magnitude() > gp::Resolution()) {
135 gp_Dir aD1(aV1), aD2(aV2);
136 aC += aD1.Angle(aD2);
141 if (aC < Precision::Confusion()) {
153 TopoDS_Edge tmpE = myEdge1;
157 BRepAdaptor_Curve tmpC = myCurve1;
161 IntTools_Range tmpR = myRange1;
165 mySwap = Standard_True;
168 myTol1 = myCurve1.Tolerance();
169 myTol2 = myCurve2.Tolerance();
170 myTol = myTol1 + myTol2;
172 myRes1 = myCurve1.Resolution(myTol);
173 myRes2 = myCurve2.Resolution(myTol);
175 if (iCT1 != 0 || iCT2 != 0) {
176 Standard_Real f, l, aTM;
178 myGeom1 = BRep_Tool::Curve(myEdge1, f, l);
179 myGeom2 = BRep_Tool::Curve(myEdge2, f, l);
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 FindSolutions(myRange1, myRange2, aRanges1, aRanges2);
222 //4. Merge solutions and save common parts
223 MergeSolutions(aRanges1, aRanges2);
226 //=======================================================================
227 //function : FindSolutions
229 //=======================================================================
230 void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
231 const IntTools_Range& theR2,
232 IntTools_SequenceOfRanges& theRanges1,
233 IntTools_SequenceOfRanges& theRanges2)
235 Standard_Boolean bOut, bStop, bThin;
236 Standard_Real aT11, aT12, aT21, aT22;
237 Standard_Real aTB11, aTB12, aTB21, aTB22;
238 Standard_Real aTol, aSmallStep1, aSmallStep2;
239 Standard_Integer iCom;
242 theR1.Range(aT11, aT12);
243 theR2.Range(aT21, aT22);
245 BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
246 BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
247 if (aB1.IsOut(aB2)) {
252 bOut = Standard_False;
253 bThin = Standard_False;
254 bStop = Standard_False;
259 bOut = !FindParameters(myCurve2, aT21, aT22, myRes2, myPTol2, aB1, aTB21, aTB22);
264 bThin = (aTB22 - aTB21) < myRes2;
266 bOut = !FindParameters(myCurve1, aT11, aT12, myRes1, myPTol1, aB1, aTB11, aTB12);
270 BndBuildBox(myCurve2, aTB21, aTB22, myTol2, aB2);
272 bOut = !FindParameters(myCurve1, aT11, aT12, myRes1, myPTol1, aB2, aTB11, aTB12);
277 bThin = ((aTB12 - aTB11) < myRes1) ||
278 (aB2.IsXThin(aTol) && aB2.IsYThin(aTol) && aB2.IsZThin(aTol));
281 aSmallStep1 = (aT12 - aT11) / 250.;
282 aSmallStep2 = (aT22 - aT21) / 250.;
284 if (aSmallStep1 < myRes1) {
285 aSmallStep1 = myRes1;
287 if (aSmallStep2 < myRes2) {
288 aSmallStep2 = myRes2;
291 if (((aTB11 - aT11) < aSmallStep1) && ((aT12 - aTB12) < aSmallStep1) &&
292 ((aTB21 - aT21) < aSmallStep2) && ((aT22 - aTB22) < aSmallStep2)) {
293 bStop = Standard_True;
295 BndBuildBox(myCurve1, aTB11, aTB12, myTol1, aB1);
296 bOut = aB1.IsOut(aB2);
307 } while (!bThin && !bStop);
315 //check curves for coincidence on the ranges
316 iCom = CheckCoincidence(aT11, aT12, aT21, aT22, myTol, myRes1);
318 bThin = Standard_True;
324 //check intermediate points
325 Standard_Real aT1, aT2, aDist;
328 aT1 = IntTools_Tools::IntermediatePoint(aT11, aT12);
329 aT2 = IntTools_Tools::IntermediatePoint(aT21, aT22);
331 myGeom1->D0(aT1, aP1);
332 myGeom2->D0(aT2, aP2);
334 aDist = aP1.Distance(aP2);
340 IntTools_Range aR1(aT11, aT12), aR2(aT21, aT22);
342 theRanges1.Append(aR1);
343 theRanges2.Append(aR2);
347 if (!IsIntersection(aT11, aT12, aT21, aT22)) {
351 //split ranges on segments and repeat
352 Standard_Integer i, aNb1;
353 IntTools_SequenceOfRanges aSegments1;
355 IntTools_Range aR2(aT21, aT22);
357 SplitRangeOnSegments(aT11, aT12, myRes1, 3, aSegments1);
358 aNb1 = aSegments1.Length();
359 for (i = 1; i <= aNb1; ++i) {
360 const IntTools_Range& aR1 = aSegments1(i);
361 FindSolutions(aR1, aR2, theRanges1, theRanges2);
365 //=======================================================================
366 //function : FindParameters
368 //=======================================================================
369 Standard_Boolean IntTools_EdgeEdge::FindParameters(const BRepAdaptor_Curve& theBAC,
370 const Standard_Real aT1,
371 const Standard_Real aT2,
372 const Standard_Real theRes,
373 const Standard_Real thePTol,
374 const Bnd_Box& theCBox,
378 Standard_Boolean bRet;
379 Standard_Integer aC, i, k;
380 Standard_Real aCf, aDiff, aDt, aT, aTB, aTOut, aTIn;
381 Standard_Real aDist, aDistP, aDistTol, aTol;
385 bRet = Standard_False;
386 aCf = 0.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.))/2.;
388 aTol = theBAC.Tolerance();
390 aDistTol = Precision::PConfusion();
394 for (i = 0; i < 2; ++i) {
395 aTB = !i ? aT1 : aT2;
396 aT = !i ? aT2 : aTB1;
398 bRet = Standard_False;
400 //looking for the point on the edge which is in the box;
401 while (aC*(aT-aTB) >= 0) {
403 aDist = PointBoxDistance(theCBox, aP);
405 if (fabs(aDist - aDistP) < aDistTol) {
406 aDt = theBAC.Resolution((++k)*aDist);
409 aDt = theBAC.Resolution(aDist);
413 bRet = Standard_True;
421 //edge is out of the box;
432 //one point IN, one point OUT; looking for the bounding point;
434 aTOut = aTB - aC*aDt;
435 aDiff = aTIn - aTOut;
436 while (fabs(aDiff) > thePTol) {
437 aTB = aTOut + aDiff*aCf;
439 if (aCBx.IsOut(aP)) {
444 aDiff = aTIn - aTOut;
456 //=======================================================================
457 //function : MergeSolutions
459 //=======================================================================
460 void IntTools_EdgeEdge::MergeSolutions(const IntTools_SequenceOfRanges& theRanges1,
461 const IntTools_SequenceOfRanges& theRanges2)
463 IntTools_Range aRi1, aRi2, aRj1, aRj2;
464 Standard_Integer aNbCP, i, j;
465 TopAbs_ShapeEnum aType;
466 Standard_Real aTi11, aTi12, aTi21, aTi22,
467 aTj11, aTj12, aTj21, aTj22;
469 aNbCP = theRanges1.Length();
470 aType = TopAbs_VERTEX;
472 for (i = 1; i <= aNbCP; ) {
473 aRi1 = theRanges1(i);
474 aRi2 = theRanges2(i);
476 aRi1.Range(aTi11, aTi12);
477 aRi2.Range(aTi21, aTi22);
479 for (j = i+1; j <= aNbCP; ++j) {
480 aRj1 = theRanges1(j);
481 aRj2 = theRanges2(j);
483 aRj1.Range(aTj11, aTj12);
484 aRj2.Range(aTj21, aTj22);
485 if (fabs(aTi12 - aTj11) < 10*myRes1 ||
486 fabs(aTi22 - aTj21) < 10*myRes2) {
487 aTi11 = Min(aTi11, aTj11);
488 aTi12 = Max(aTi12, aTj12);
489 aTi21 = Min(aTi21, aTj21);
490 aTi22 = Max(aTi22, aTj22);
497 if (aTi11 == myRange1.First() && aTi12 == myRange1.Last() &&
498 aTi21 == myRange2.First() && aTi22 == myRange2.Last()) {
502 AddSolution(aTi11, aTi12, aTi21, aTi22, aType);
506 //=======================================================================
507 //function : AddSolution
509 //=======================================================================
510 void IntTools_EdgeEdge::AddSolution(const Standard_Real aT11,
511 const Standard_Real aT12,
512 const Standard_Real aT21,
513 const Standard_Real aT22,
514 const TopAbs_ShapeEnum theType)
516 IntTools_CommonPrt aCPart;
518 aCPart.SetType(theType);
520 aCPart.SetEdge1(myEdge1);
521 aCPart.SetEdge2(myEdge2);
522 aCPart.SetRange1(aT11, aT12);
523 aCPart.AppendRange2(aT21, aT22);
525 aCPart.SetEdge1(myEdge2);
526 aCPart.SetEdge2(myEdge1);
527 aCPart.SetRange1(aT21, aT22);
528 aCPart.AppendRange2(aT11, aT12);
531 if (theType == TopAbs_VERTEX) {
532 Standard_Real aT1, aT2;
534 FindBestSolution(aT11, aT12, aT21, aT22, aT1, aT2);
537 aCPart.SetVertexParameter1(aT1);
538 aCPart.SetVertexParameter2(aT2);
540 aCPart.SetVertexParameter1(aT2);
541 aCPart.SetVertexParameter2(aT1);
544 myCommonParts.Append(aCPart);
547 //=======================================================================
548 //function : FindBestSolution
550 //=======================================================================
551 void IntTools_EdgeEdge::FindBestSolution(const Standard_Real aT11,
552 const Standard_Real aT12,
553 const Standard_Real aT21,
554 const Standard_Real aT22,
558 Standard_Integer i, aNbS, iErr;
559 Standard_Real aDMin, aD, aCrit;
560 Standard_Real aT1x, aT2x, aT1p, aT2p;
561 GeomAPI_ProjectPointOnCurve aProj;
562 IntTools_SequenceOfRanges aSeg1;
564 aT1 = IntTools_Tools::IntermediatePoint(aT11, aT12);
565 aT2 = IntTools_Tools::IntermediatePoint(aT21, aT22);
572 SplitRangeOnSegments(aT11, aT12, 3*myRes1, aNbS, aSeg1);
573 aNbS = aSeg1.Length();
575 aProj.Init(myGeom2, aT21, aT22);
576 for (i = 1; i <= aNbS; ++i) {
577 const IntTools_Range& aR1 = aSeg1(i);
578 aR1.Range(aT1x, aT2x);
580 iErr = FindDistPC(aT1x, aT2x, myGeom1, aCrit, myPTol1,
581 aProj, aD, aT1p, aT2p, Standard_False);
582 if (iErr != 1 && aD < aDMin) {
586 if (aDMin <= aCrit) {
593 //=======================================================================
594 //function : ComputeLineLine
596 //=======================================================================
597 void IntTools_EdgeEdge::ComputeLineLine()
599 Standard_Boolean IsParallel, IsCoincide;
600 Standard_Real aSin, aCos, aAng, aTol;
601 Standard_Real aT1, aT2, aT11, aT12, aT21, aT22;
605 IntTools_CommonPrt aCommonPrt;
607 IsParallel = Standard_False;
608 IsCoincide = Standard_False;
610 aL1 = myCurve1.Line();
611 aL2 = myCurve2.Line();
612 aD1 = aL1.Position().Direction();
613 aD2 = aL2.Position().Direction();
614 myRange1.Range(aT11, aT12);
615 myRange2.Range(aT21, aT22);
617 aCommonPrt.SetEdge1(myEdge1);
618 aCommonPrt.SetEdge2(myEdge2);
621 aAng = (aCos >= 0.) ? 2.*(1. - aCos) : 2.*(1. + aCos);
623 if(aAng <= Precision::Angular()) {
624 IsParallel = Standard_True;
625 if(aL1.SquareDistance(aL2.Location()) <= aTol) {
626 IsCoincide = Standard_True;
627 aP11 = ElCLib::Value(aT11, aL1);
628 aP12 = ElCLib::Value(aT12, aL1);
632 aP11 = ElCLib::Value(aT11, aL1);
633 aP12 = ElCLib::Value(aT12, aL1);
634 if(aL2.SquareDistance(aP11) <= aTol && aL2.SquareDistance(aP12) <= aTol) {
635 IsCoincide = Standard_True;
640 Standard_Real t21, t22;
642 t21 = ElCLib::Parameter(aL2, aP11);
643 t22 = ElCLib::Parameter(aL2, aP12);
644 if((t21 > aT22 && t22 > aT22) || (t21 < aT21 && t22 < aT21)) {
657 aCommonPrt.SetRange1(aT11, aT12);
658 aCommonPrt.SetAllNullFlag(Standard_True);
659 aCommonPrt.AppendRange2(t21, t22);
662 aCommonPrt.SetRange1(aT11, aT12 - (t22 - aT22));
663 aCommonPrt.AppendRange2(t21, aT22);
667 aCommonPrt.SetRange1(aT11 + (aT21 - t21), aT12);
668 aCommonPrt.AppendRange2(aT21, t22);
670 aCommonPrt.SetType(TopAbs_EDGE);
671 myCommonParts.Append(aCommonPrt);
680 TopoDS_Iterator aIt1, aIt2;
681 aIt1.Initialize(myEdge1);
682 for (; aIt1.More(); aIt1.Next()) {
683 const TopoDS_Shape& aV1 = aIt1.Value();
684 aIt2.Initialize(myEdge2);
685 for (; aIt2.More(); aIt2.Next()) {
686 const TopoDS_Shape& aV2 = aIt2.Value();
687 if (aV2.IsSame(aV1)) {
694 aSin = 1. - aCos*aCos;
695 gp_Pnt O1 = aL1.Location();
696 gp_Pnt O2 = aL2.Location();
697 gp_Vec O1O2 (O1, O2);
699 aT2 = (aD1.XYZ()*(O1O2.Dot(aD1))-(O1O2.XYZ())).Dot(aD2.XYZ());
702 if(aT2 < aT21 || aT2 > aT22) {
706 gp_Pnt aP2(ElCLib::Value(aT2, aL2));
707 aT1 = (gp_Vec(O1, aP2)).Dot(aD1);
709 if(aT1 < aT11 || aT1 > aT12) {
713 gp_Pnt aP1(ElCLib::Value(aT1, aL1));
714 Standard_Real aDist = aP1.SquareDistance(aP2);
720 aCommonPrt.SetRange1(aT1 - myTol, aT1 + myTol);
721 aCommonPrt.AppendRange2(aT2 - myTol, aT2 + myTol);
722 aCommonPrt.SetType(TopAbs_VERTEX);
723 aCommonPrt.SetVertexParameter1(aT1);
724 aCommonPrt.SetVertexParameter2(aT2);
725 myCommonParts.Append(aCommonPrt);
728 //=======================================================================
729 //function : IsIntersection
731 //=======================================================================
732 Standard_Boolean IntTools_EdgeEdge::IsIntersection(const Standard_Real aT11,
733 const Standard_Real aT12,
734 const Standard_Real aT21,
735 const Standard_Real aT22)
737 Standard_Boolean bRet;
738 gp_Pnt aP11, aP12, aP21, aP22;
739 gp_Vec aV11, aV12, aV21, aV22;
740 Standard_Real aD11_21, aD11_22, aD12_21, aD12_22, aCriteria, aCoef;
741 Standard_Boolean bSmall_11_21, bSmall_11_22, bSmall_12_21, bSmall_12_22;
743 bRet = Standard_True;
745 if (((aT12 - aT11) > aCoef*myRes1) && ((aT22 - aT21) > aCoef*myRes2)) {
748 Standard_Real aTRMin = Min((aT12 - aT11)/myRes1, (aT22 - aT21)/myRes2);
749 aCoef = aTRMin / 100.;
754 aCriteria = aCoef * myTol;
755 aCriteria *= aCriteria;
757 myGeom1->D1(aT11, aP11, aV11);
758 myGeom1->D1(aT12, aP12, aV12);
759 myGeom2->D1(aT21, aP21, aV21);
760 myGeom2->D1(aT22, aP22, aV22);
762 aD11_21 = aP11.SquareDistance(aP21);
763 aD11_22 = aP11.SquareDistance(aP22);
764 aD12_21 = aP12.SquareDistance(aP21);
765 aD12_22 = aP12.SquareDistance(aP22);
767 bSmall_11_21 = aD11_21 < aCriteria;
768 bSmall_11_22 = aD11_22 < aCriteria;
769 bSmall_12_21 = aD12_21 < aCriteria;
770 bSmall_12_22 = aD12_22 < aCriteria;
772 if ((bSmall_11_21 && bSmall_12_22) ||
773 (bSmall_11_22 && bSmall_12_21)) {
778 Standard_Real anAngleCriteria;
779 Standard_Real anAngle1, anAngle2;
781 anAngleCriteria = 5.e-3;
782 if (bSmall_11_21 && bSmall_12_22) {
783 anAngle1 = aV11.Angle(aV21);
784 anAngle2 = aV12.Angle(aV22);
786 anAngle1 = aV11.Angle(aV22);
787 anAngle2 = aV12.Angle(aV21);
790 if (((anAngle1 < anAngleCriteria) || ((M_PI - anAngle1) < anAngleCriteria)) ||
791 ((anAngle2 < anAngleCriteria) || ((M_PI - anAngle2) < anAngleCriteria))) {
792 GeomAPI_ProjectPointOnCurve aProj;
793 Standard_Integer iErr;
794 Standard_Real aD, aT1p, aT2p;
797 aProj.Init(myGeom2, aT21, aT22);
798 iErr = FindDistPC(aT11, aT12, myGeom1, myTol, myRes1, aProj, aD, aT1p, aT2p, Standard_False);
805 //=======================================================================
806 //function : CheckCoincidence
808 //=======================================================================
809 Standard_Integer IntTools_EdgeEdge::CheckCoincidence(const Standard_Real aT11,
810 const Standard_Real aT12,
811 const Standard_Real aT21,
812 const Standard_Real aT22,
813 const Standard_Real theCriteria,
814 const Standard_Real theCurveRes1)
816 Standard_Integer iErr, aNb, aNb1, i;
817 Standard_Real aT1A, aT1B, aT1max, aT2max, aDmax;
818 GeomAPI_ProjectPointOnCurve aProjPC;
819 IntTools_SequenceOfRanges aSeg1;
823 aProjPC.Init(myGeom2, aT21, aT22);
825 // 1. Express evaluation
826 aNb = 10; // Number of intervals on the curve #1
827 SplitRangeOnSegments(aT11, aT12, theCurveRes1, aNb, aSeg1);
828 aNb1 = aSeg1.Length();
829 for (i = 1; i < aNb1; ++i) {
830 const IntTools_Range& aR1 = aSeg1(i);
831 aR1.Range(aT1A, aT1B);
833 iErr = DistPC(aT1B, myGeom1, theCriteria, aProjPC, aDmax, aT2max);
839 // if the ranges in aSeg1 are less than theCurveRes1,
840 // there is no need to do step 2 (deep evaluation)
845 // 2. Deep evaluation
846 for (i = 2; i < aNb1; ++i) {
847 const IntTools_Range& aR1 = aSeg1(i);
848 aR1.Range(aT1A, aT1B);
850 iErr = FindDistPC(aT1A, aT1B, myGeom1, theCriteria, theCurveRes1,
851 aProjPC, aDmax, aT1max, aT2max);
857 // iErr == 0 - the patches are coincided
858 // iErr == 1 - a point from aC1 can not be projected on aC2
859 // iErr == 2 - the distance is too big
863 //=======================================================================
864 //function : FindDistPC
866 //=======================================================================
867 Standard_Integer FindDistPC(const Standard_Real aT1A,
868 const Standard_Real aT1B,
869 const Handle(Geom_Curve)& theC1,
870 const Standard_Real theCriteria,
871 const Standard_Real theEps,
872 GeomAPI_ProjectPointOnCurve& theProjPC,
873 Standard_Real& aDmax,
874 Standard_Real& aT1max,
875 Standard_Real& aT2max,
876 const Standard_Boolean bMaxDist)
878 Standard_Integer iErr, iC;
879 Standard_Real aGS, aXP, aA, aB, aXL, aYP, aYL, aT2P, aT2L;
881 iC = bMaxDist ? 1 : -1;
884 aGS = 0.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.))-1.;
889 iErr = DistPC(aA, theC1, theCriteria, theProjPC, aYP, aT2P, aDmax, aT1max, aT2max, iC);
894 iErr = DistPC(aB, theC1, theCriteria, theProjPC, aYL, aT2L, aDmax, aT1max, aT2max, iC);
899 aXP = aA + (aB - aA)*aGS;
900 aXL = aB - (aB - aA)*aGS;
902 iErr = DistPC(aXP, theC1, theCriteria, theProjPC, aYP, aT2P, aDmax, aT1max, aT2max, iC);
907 iErr = DistPC(aXL, theC1, theCriteria, theProjPC, aYL, aT2L, aDmax, aT1max, aT2max, iC);
913 if (iC*(aYP - aYL) > 0) {
917 aXP = aA + (aB - aA)*aGS;
918 iErr = DistPC(aXP, theC1, theCriteria, theProjPC, aYP, aT2P, aDmax, aT1max, aT2max, iC);
927 aXL = aB - (aB - aA)*aGS;
928 iErr = DistPC(aXL, theC1, theCriteria, theProjPC, aYL, aT2L, aDmax, aT1max, aT2max, iC);
934 if ((aB - aA) < theEps) {
941 //=======================================================================
944 //=======================================================================
945 Standard_Integer DistPC(const Standard_Real aT1,
946 const Handle(Geom_Curve)& theC1,
947 const Standard_Real theCriteria,
948 GeomAPI_ProjectPointOnCurve& theProjPC,
951 Standard_Real& aDmax,
952 Standard_Real& aT1max,
953 Standard_Real& aT2max,
954 const Standard_Integer iC)
956 Standard_Integer iErr;
958 iErr = DistPC(aT1, theC1, theCriteria, theProjPC, aD, aT2, iC);
963 if (iC*(aD - aDmax) > 0) {
971 //=======================================================================
974 //=======================================================================
975 Standard_Integer DistPC(const Standard_Real aT1,
976 const Handle(Geom_Curve)& theC1,
977 const Standard_Real theCriteria,
978 GeomAPI_ProjectPointOnCurve& theProjPC,
981 const Standard_Integer iC)
983 Standard_Integer iErr, aNbP2;
989 theProjPC.Perform(aP1);
990 aNbP2 = theProjPC.NbPoints();
992 iErr = 1;// the point from aC1 can not be projected on aC2
996 aD = theProjPC.LowerDistance();
997 aT2 = theProjPC.LowerDistanceParameter();
998 if (iC*(aD - theCriteria) > 0) {
999 iErr = 2;// the distance is too big or small
1005 //=======================================================================
1006 //function : SplitRangeOnSegments
1008 //=======================================================================
1009 void SplitRangeOnSegments(const Standard_Real aT1,
1010 const Standard_Real aT2,
1011 const Standard_Real theResolution,
1012 const Standard_Integer theNbSeg,
1013 IntTools_SequenceOfRanges& theSegments)
1015 Standard_Real aDiff = aT2 - aT1;
1016 if (aDiff < theResolution) {
1017 theSegments.Append(IntTools_Range(aT1, aT2));
1021 Standard_Real aDt, aT1x, aT2x, aSeg;
1022 Standard_Integer aNbSegments, i;
1024 aNbSegments = theNbSeg;
1025 aDt = aDiff / aNbSegments;
1026 if (aDt < theResolution) {
1027 aSeg = aDiff / theResolution;
1028 aNbSegments = Standard_Integer(aSeg) + 1;
1029 aDt = aDiff / aNbSegments;
1033 for (i = 1; i < aNbSegments; ++i) {
1036 IntTools_Range aR(aT1x, aT2x);
1037 theSegments.Append(aR);
1042 IntTools_Range aR(aT1x, aT2);
1043 theSegments.Append(aR);
1046 //=======================================================================
1047 //function : BndBuildBox
1049 //=======================================================================
1050 void BndBuildBox(const BRepAdaptor_Curve& theBAC,
1051 const Standard_Real aT1,
1052 const Standard_Real aT2,
1053 const Standard_Real theTol,
1057 BndLib_Add3dCurve::Add(theBAC, aT1, aT2, theTol, aB);
1061 //=======================================================================
1062 //function : PointBoxDistance
1064 //=======================================================================
1065 Standard_Real PointBoxDistance(const Bnd_Box& aB,
1068 Standard_Real aPCoord[3];
1069 Standard_Real aBMinCoord[3], aBMaxCoord[3];
1070 Standard_Real aDist, aR1, aR2;
1073 aP.Coord(aPCoord[0], aPCoord[1], aPCoord[2]);
1074 aB.Get(aBMinCoord[0], aBMinCoord[1], aBMinCoord[2],
1075 aBMaxCoord[0], aBMaxCoord[1], aBMaxCoord[2]);
1078 for (i = 0; i < 3; ++i) {
1079 aR1 = aBMinCoord[i] - aPCoord[i];
1085 aR2 = aPCoord[i] - aBMaxCoord[i];
1091 aDist = Sqrt(aDist);
1095 //=======================================================================
1096 //function : TypeToInteger
1098 //=======================================================================
1099 Standard_Integer TypeToInteger(const GeomAbs_CurveType theCType)
1101 Standard_Integer iRet;
1107 case GeomAbs_Circle:
1110 case GeomAbs_Ellipse:
1111 case GeomAbs_Hyperbola:
1112 case GeomAbs_Parabola:
1115 case GeomAbs_BezierCurve:
1116 case GeomAbs_BSplineCurve: