// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-#include <IntTools_EdgeEdge.ixx>
-
-#include <NCollection_UBTreeFiller.hxx>
-
-#include <gp_Dir.hxx>
-#include <gp_Lin.hxx>
-
-#include <ElCLib.hxx>
-
-#include <TopoDS_Iterator.hxx>
#include <Bnd_Box.hxx>
#include <BndLib_Add3dCurve.hxx>
-
-#include <GeomAPI_ProjectPointOnCurve.hxx>
-
+#include <BOPCol_MapOfInteger.hxx>
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Curve.hxx>
-
-#include <BOPCol_MapOfInteger.hxx>
-#include <BOPCol_BoxBndTree.hxx>
-
-#include <IntTools_Tools.hxx>
+#include <ElCLib.hxx>
+#include <Geom_BezierCurve.hxx>
+#include <Geom_BSplineCurve.hxx>
+#include <Geom_Line.hxx>
+#include <Geom_Circle.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Ellipse.hxx>
+#include <Geom_OffsetCurve.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <gp_Dir.hxx>
+#include <gp_Lin.hxx>
#include <IntTools_CommonPrt.hxx>
+#include <IntTools_EdgeEdge.hxx>
+#include <IntTools_Range.hxx>
+#include <IntTools_Tools.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Iterator.hxx>
-static
- Standard_Boolean BndCommon(const Bnd_Box& theB1,
- const Bnd_Box& theB2,
- Bnd_Box& theBOut);
static
void BndBuildBox(const BRepAdaptor_Curve& theBAC,
const Standard_Real aT1,
const Standard_Real aT2,
const Standard_Real theTol,
Bnd_Box& theBox);
+static
+ Standard_Real PointBoxDistance(const Bnd_Box& aB,
+ const gp_Pnt& aP);
static
- void SplitRangeOnSegments(const Standard_Real aT1,
- const Standard_Real aT2,
- const Standard_Real theResolution,
- const Standard_Integer theNbSeg,
- IntTools_SequenceOfRanges& theSegments);
-static
- void SplitRangeOnTwo(const Standard_Real aT1,
- const Standard_Real aT2,
- IntTools_SequenceOfRanges& theSegments);
+ Standard_Integer SplitRangeOnSegments(const Standard_Real aT1,
+ const Standard_Real aT2,
+ const Standard_Real theResolution,
+ const Standard_Integer theNbSeg,
+ IntTools_SequenceOfRanges& theSegments);
static
Standard_Integer DistPC(const Standard_Real aT1,
const Handle(Geom_Curve)& theC1,
Standard_Real& aT1max,
Standard_Real& aT2max,
const Standard_Boolean bMaxDist = Standard_True);
+static
+ Standard_Real ResolutionCoeff(const BRepAdaptor_Curve& theBAC,
+ const IntTools_Range& theRange);
+static
+ Standard_Real Resolution(const Handle(Geom_Curve)& theCurve,
+ const GeomAbs_CurveType theCurveType,
+ const Standard_Real theResCoeff,
+ const Standard_Real theR3D);
+static
+ Standard_Real CurveDeflection(const BRepAdaptor_Curve& theBAC,
+ const IntTools_Range& theRange);
+static
+ Standard_Boolean IsClosed(const Handle(Geom_Curve)& theCurve,
+ const Standard_Real aT1,
+ const Standard_Real aT2,
+ const Standard_Real theTol,
+ const Standard_Real theRes);
static
Standard_Integer TypeToInteger(const GeomAbs_CurveType theCType);
if (iCT1 == iCT2) {
if (iCT1 != 0) {
//compute deflection
- Standard_Integer i;
- Standard_Real aDt, aT, aT1, aT2;
- gp_Vec aV1, aV2;
- gp_Pnt aP;
+ Standard_Real aC1, aC2;
//
- Standard_Real aC1(0.), aC2(0.);
- for (i = 0; i < 2; ++i) {
- Standard_Real &aC = !i ? aC1 : aC2;
- IntTools_Range aR = !i ? myRange1 : myRange2;
- const BRepAdaptor_Curve& aBAC = !i ? myCurve1 : myCurve2;
- aR.Range(aT1, aT2);
- aDt = (aT2 - aT1) / 10.;
- aT = aT1;
- aBAC.D1(aT, aP, aV1);
- while (aT <= aT2) {
- aT += aDt;
- aBAC.D1(aT, aP, aV2);
- aC += aV1.Angle(aV2);
- aV1 = aV2;
- }
- }
+ aC2 = CurveDeflection(myCurve2, myRange2);
+ aC1 = (aC2 > Precision::Confusion()) ?
+ CurveDeflection(myCurve1, myRange1) : 1.;
//
if (aC1 < aC2) {
--iCT1;
mySwap = Standard_True;
}
//
- myTol1 = myCurve1.Tolerance();
- myTol2 = myCurve2.Tolerance();
+ Standard_Real aTolAdd = myFuzzyValue / 2.;
+ myTol1 = myCurve1.Tolerance() + aTolAdd;
+ myTol2 = myCurve2.Tolerance() + aTolAdd;
myTol = myTol1 + myTol2;
//
- myRes1 = myCurve1.Resolution(myTol);
- myRes2 = myCurve2.Resolution(myTol);
- //
if (iCT1 != 0 || iCT2 != 0) {
- Standard_Real f, l;
+ Standard_Real f, l, aTM;
+ //
myGeom1 = BRep_Tool::Curve(myEdge1, f, l);
myGeom2 = BRep_Tool::Curve(myEdge2, f, l);
+ //
+ myResCoeff1 = ResolutionCoeff(myCurve1, myRange1);
+ myResCoeff2 = ResolutionCoeff(myCurve2, myRange2);
+ //
+ myRes1 = Resolution(myCurve1.Curve().Curve(), myCurve1.GetType(), myResCoeff1, myTol1);
+ myRes2 = Resolution(myCurve2.Curve().Curve(), myCurve2.GetType(), myResCoeff2, myTol2);
+ //
+ myPTol1 = 5.e-13;
+ aTM = Max(fabs(myRange1.First()), fabs(myRange1.Last()));
+ if (aTM > 999.) {
+ myPTol1 = 5.e-16 * aTM;
+ }
+ //
+ myPTol2 = 5.e-13;
+ aTM = Max(fabs(myRange2.First()), fabs(myRange2.Last()));
+ if (aTM > 999.) {
+ myPTol2 = 5.e-16 * aTM;
+ }
}
}
return;
}
//
- //3.2. Find solutions
- IntTools_SequenceOfRanges aRanges1, aRanges2, aSegments1;
- Standard_Integer i, aNb;
+ if (myQuickCoincidenceCheck) {
+ if (IsCoincident()) {
+ Standard_Real aT11, aT12, aT21, aT22;
+ //
+ myRange1.Range(aT11, aT12);
+ myRange2.Range(aT21, aT22);
+ AddSolution(aT11, aT12, aT21, aT22, TopAbs_EDGE);
+ return;
+ }
+ }
//
- //3.2.1 Find rough ranges
- FindRoughRanges(myRange1, myRange2, aSegments1);
- aNb = aSegments1.Length();
- //3.2.2. Find exact solutions and ranges
- for (i = 1; i <= aNb; ++i) {
+ IntTools_SequenceOfRanges aRanges1, aRanges2;
+ //
+ //3.2. Find ranges containig solutions
+ Standard_Boolean bSplit2;
+ FindSolutions(aRanges1, aRanges2, bSplit2);
+ //
+ //4. Merge solutions and save common parts
+ MergeSolutions(aRanges1, aRanges2, bSplit2);
+}
+
+//=======================================================================
+//function : IsCoincident
+//purpose :
+//=======================================================================
+Standard_Boolean IntTools_EdgeEdge::IsCoincident()
+{
+ Standard_Integer i, iCnt, aNbSeg, aNbP2;
+ Standard_Real dT, aT1, aCoeff, aTresh, aD;
+ Standard_Real aT11, aT12, aT21, aT22;
+ GeomAPI_ProjectPointOnCurve aProjPC;
+ gp_Pnt aP1;
+ //
+ aTresh=0.5;
+ aNbSeg=23;
+ myRange1.Range(aT11, aT12);
+ myRange2.Range(aT21, aT22);
+ //
+ aProjPC.Init(myGeom2, aT21, aT22);
+ //
+ dT=(aT12-aT11)/aNbSeg;
+ //
+ iCnt=0;
+ for(i=0; i <= aNbSeg; ++i) {
+ aT1 = aT11+i*dT;
+ myGeom1->D0(aT1, aP1);
+ //
+ aProjPC.Perform(aP1);
+ aNbP2=aProjPC.NbPoints();
+ if (!aNbP2) {
+ continue;
+ }
+ //
+ aD=aProjPC.LowerDistance();
+ if(aD < myTol) {
+ ++iCnt;
+ }
+ }
+ //
+ aCoeff=(Standard_Real)iCnt/((Standard_Real)aNbSeg+1);
+ return aCoeff > aTresh;
+}
+//=======================================================================
+//function : FindSolutions
+//purpose :
+//=======================================================================
+void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
+ IntTools_SequenceOfRanges& theRanges2,
+ Standard_Boolean& bSplit2)
+{
+ Standard_Boolean bIsClosed2;
+ Standard_Real aT11, aT12, aT21, aT22;
+ Bnd_Box aB2;
+ //
+ bSplit2 = Standard_False;
+ myRange1.Range(aT11, aT12);
+ myRange2.Range(aT21, aT22);
+ //
+ bIsClosed2 = IsClosed(myGeom2, aT21, aT22, myTol2, myRes2);
+ //
+ if (bIsClosed2) {
+ Bnd_Box aB1;
+ BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
+ //
+ gp_Pnt aP = myGeom2->Value(aT21);
+ bIsClosed2 = !aB1.IsOut(aP);
+ }
+ //
+ if (!bIsClosed2) {
+ BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
+ FindSolutions(myRange1, myRange2, aB2, theRanges1, theRanges2);
+ return;
+ }
+ //
+ if (!CheckCoincidence(aT11, aT12, aT21, aT22, myTol, myRes1)) {
+ theRanges1.Append(myRange1);
+ theRanges2.Append(myRange2);
+ return;
+ }
+ //
+ Standard_Integer i, j, aNb1, aNb2;
+ IntTools_SequenceOfRanges aSegments1, aSegments2;
+ //
+ aNb1 = IsClosed(myGeom1, aT11, aT12, myTol1, myRes1) ? 2 : 1;
+ aNb2 = 2;
+ //
+ aNb1 = SplitRangeOnSegments(aT11, aT12, myRes1, aNb1, aSegments1);
+ aNb2 = SplitRangeOnSegments(aT21, aT22, myRes2, aNb2, aSegments2);
+ //
+ for (i = 1; i <= aNb1; ++i) {
const IntTools_Range& aR1 = aSegments1(i);
- FindSolutions(aR1, myRange2, aRanges1, aRanges2);
+ for (j = 1; j <= aNb2; ++j) {
+ const IntTools_Range& aR2 = aSegments2(j);
+ BndBuildBox(myCurve2, aR2.First(), aR2.Last(), myTol2, aB2);
+ FindSolutions(aR1, aR2, aB2, theRanges1, theRanges2);
+ }
}
//
- //4. Merge solutions and save common parts
- MergeSolutions(aRanges1, aRanges2);
+ bSplit2 = aNb2 > 1;
}
//=======================================================================
//=======================================================================
void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
const IntTools_Range& theR2,
- IntTools_SequenceOfRanges& theRanges1,
+ const Bnd_Box& theBox2,
+ IntTools_SequenceOfRanges& theRanges1,
IntTools_SequenceOfRanges& theRanges2)
{
+ Standard_Boolean bOut, bStop, bThin;
Standard_Real aT11, aT12, aT21, aT22;
+ Standard_Real aTB11, aTB12, aTB21, aTB22;
+ Standard_Real aSmallStep1, aSmallStep2;
+ Standard_Integer iCom;
Bnd_Box aB1, aB2;
//
theR1.Range(aT11, aT12);
theR2.Range(aT21, aT22);
- BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
- BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
- if (!BndCommon(aB1, aB2, aB1)) {
- return;
- }
//
- Standard_Boolean bOut, bStop, bThin;
- Standard_Real aTB11, aTB12, aTB21, aTB22, aTol,
- aSmallStep1, aSmallStep2;
- Standard_Integer iCom;
+ aB2 = theBox2;
//
- bOut = Standard_False;
bThin = Standard_False;
bStop = Standard_False;
- aTol = 2*myTol;
iCom = 1;
//
do {
- bOut = !FindParameters(myCurve2, aT21, aT22, myRes2, aB1, aTB21, aTB22);
+ aTB11 = aT11;
+ aTB12 = aT12;
+ aTB21 = aT21;
+ aTB22 = aT22;
+ //
+ //1. Build box for first edge and find parameters
+ // of the second one in that box
+ BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
+ bOut = aB1.IsOut(aB2);
if (bOut) {
break;
}
//
- bThin = (aTB22 - aTB21) < myRes2;
- if (bThin) {
- bOut = !FindParameters(myCurve1, aT11, aT12, myRes1, aB1, aTB11, aTB12);
- if (bOut) {
- break;
- }
- } else {
- BndBuildBox(myCurve2, aTB21, aTB22, myTol2, aB2);
- BndCommon(aB1, aB2, aB2);
- //
- bOut = !FindParameters(myCurve1, aT11, aT12, myRes1, aB2, aTB11, aTB12);
- if (bOut) {
- break;
- }
- //
- bThin = ((aTB12 - aTB11) < myRes1) ||
- (aB2.IsXThin(aTol) && aB2.IsYThin(aTol) && aB2.IsZThin(aTol));
- //
- if (!bThin) {
- aSmallStep1 = (aT12 - aT11) / 250.;
- aSmallStep2 = (aT22 - aT21) / 250.;
- //
- if (aSmallStep1 < myRes1) {
- aSmallStep1 = myRes1;
- }
- if (aSmallStep2 < myRes2) {
- aSmallStep2 = myRes2;
- }
- //
- if (((aTB11 - aT11) < aSmallStep1) && ((aT12 - aTB12) < aSmallStep1) &&
- ((aTB21 - aT21) < aSmallStep2) && ((aT22 - aTB22) < aSmallStep2)) {
- bStop = Standard_True;
- } else {
- BndBuildBox(myCurve1, aTB11, aTB12, myTol1, aB1);
- bOut = !BndCommon(aB1, aB2, aB1);
- if (bOut) {
- break;
- }
- }
- }
+ bThin = ((aT12 - aT11) < myRes1) ||
+ (aB1.IsXThin(myTol) && aB1.IsYThin(myTol) && aB1.IsZThin(myTol));
+ //
+ bOut = !FindParameters(myCurve2, aTB21, aTB22, myTol2, myRes2, myPTol2,
+ myResCoeff2, aB1, aT21, aT22);
+ if (bOut || bThin) {
+ break;
+ }
+ //
+ //2. Build box for second edge and find parameters
+ // of the first one in that box
+ BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
+ bOut = aB1.IsOut(aB2);
+ if (bOut) {
+ break;
+ }
+ //
+ bThin = ((aT22 - aT21) < myRes2) ||
+ (aB2.IsXThin(myTol) && aB2.IsYThin(myTol) && aB2.IsZThin(myTol));
+ //
+ bOut = !FindParameters(myCurve1, aTB11, aTB12, myTol1, myRes1, myPTol1,
+ myResCoeff1, aB2, aT11, aT12);
+ //
+ if (bOut || bThin) {
+ break;
+ }
+ //
+ //3. Check if it makes sense to continue
+ aSmallStep1 = (aTB12 - aTB11) / 250.;
+ aSmallStep2 = (aTB22 - aTB21) / 250.;
+ //
+ if (aSmallStep1 < myRes1) {
+ aSmallStep1 = myRes1;
+ }
+ if (aSmallStep2 < myRes2) {
+ aSmallStep2 = myRes2;
}
//
- aT11 = aTB11;
- aT12 = aTB12;
- aT21 = aTB21;
- aT22 = aTB22;
- } while (!bThin && !bStop);
+ if (((aT11 - aTB11) < aSmallStep1) && ((aTB12 - aT12) < aSmallStep1) &&
+ ((aT21 - aTB21) < aSmallStep2) && ((aTB22 - aT22) < aSmallStep2)) {
+ bStop = Standard_True;
+ }
+ //
+ } while (!bStop);
//
if (bOut) {
//no intersection;
iCom = CheckCoincidence(aT11, aT12, aT21, aT22, myTol, myRes1);
if (!iCom) {
bThin = Standard_True;
- }
+ }
}
//
if (bThin) {
if (iCom != 0) {
//check intermediate points
- Standard_Real aT1, aT2, aDist;
- gp_Pnt aP1, aP2;
+ Standard_Boolean bSol;
+ Standard_Real aT1;
+ gp_Pnt aP1;
+ GeomAPI_ProjectPointOnCurve aProjPC;
//
- aT1 = IntTools_Tools::IntermediatePoint(aT11, aT12);
- aT2 = IntTools_Tools::IntermediatePoint(aT21, aT22);
+ aT1 = (aT11 + aT12) * .5;
+ myGeom1->D0(aT1, aP1);
//
- aP1 = myGeom1->Value(aT1);
- aP2 = myGeom2->Value(aT2);
+ aProjPC.Init(myGeom2, aT21, aT22);
+ aProjPC.Perform(aP1);
//
- aDist = aP1.Distance(aP2);
- if (aDist > myTol) {
+ if (aProjPC.NbPoints()) {
+ bSol = aProjPC.LowerDistance() <= myTol;
+ }
+ else {
+ Standard_Real aT2;
+ gp_Pnt aP2;
+ //
+ aT2 = (aT21 + aT22) * .5;
+ myGeom2->D0(aT2, aP2);
+ //
+ bSol = aP1.IsEqual(aP2, myTol);
+ }
+ //
+ if (!bSol) {
return;
}
}
IntTools_SequenceOfRanges aSegments1;
//
IntTools_Range aR2(aT21, aT22);
- SplitRangeOnSegments(aT11, aT12, myRes1, 3, aSegments1);
- aNb1 = aSegments1.Length();
+ BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
+ //
+ aNb1 = SplitRangeOnSegments(aT11, aT12, myRes1, 3, aSegments1);
for (i = 1; i <= aNb1; ++i) {
const IntTools_Range& aR1 = aSegments1(i);
- FindSolutions(aR1, aR2, theRanges1, theRanges2);
+ FindSolutions(aR1, aR2, aB2, theRanges1, theRanges2);
}
}
//=======================================================================
Standard_Boolean IntTools_EdgeEdge::FindParameters(const BRepAdaptor_Curve& theBAC,
const Standard_Real aT1,
- const Standard_Real aT2,
+ const Standard_Real aT2,
+ const Standard_Real theTol,
const Standard_Real theRes,
+ const Standard_Real thePTol,
+ const Standard_Real theResCoeff,
const Bnd_Box& theCBox,
Standard_Real& aTB1,
Standard_Real& aTB2)
{
Standard_Boolean bRet;
- Standard_Integer aC, i, k;
- Standard_Real aCf, aDiff, aDt, aT, aTB, aTOut, aTIn, aPTol, aTol,
- aDist, aDistP;
+ Standard_Integer aC, i;
+ Standard_Real aCf, aDiff, aDt, aT, aTB, aTOut, aTIn;
+ Standard_Real aDist, aDistP;
gp_Pnt aP;
Bnd_Box aCBx;
//
bRet = Standard_False;
aCf = 0.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.))/2.;
- aDt = theRes;
- aPTol = theRes * 0.001;
- aTol = theBAC.Tolerance();
- aDistP = 0.;
aCBx = theCBox;
- aCBx.Enlarge(aTol);
+ aCBx.SetGap(aCBx.GetGap() + theTol);
+ //
+ const Handle(Geom_Curve)& aCurve = theBAC.Curve().Curve();
+ const GeomAbs_CurveType aCurveType = theBAC.GetType();
+ Standard_Real aMaxDt = (aT2 - aT1) * 0.01;
//
for (i = 0; i < 2; ++i) {
aTB = !i ? aT1 : aT2;
aT = !i ? aT2 : aTB1;
aC = !i ? 1 : -1;
+ aDt = theRes;
+ aDistP = 0.;
bRet = Standard_False;
- k = 0;
+ Standard_Real k = 1;
//looking for the point on the edge which is in the box;
while (aC*(aT-aTB) >= 0) {
- aP = theBAC.Value(aTB);
- Bnd_Box aBP;
- aBP.Add(aP);
- aDist = aBP.Distance(theCBox);
- k = (fabs(aDist - aDistP) < Precision::PConfusion()) ? k+1 : 0;
- if (aDist > aTol) {
- aDt = theBAC.Resolution(aDist*Max(k, 1));
+ theBAC.D0(aTB, aP);
+ aDist = PointBoxDistance(theCBox, aP);
+ if (aDist > theTol) {
+ if (aDistP > 0.) {
+ Standard_Boolean toGrow = Standard_False;
+ if (Abs(aDistP - aDist) / aDistP < 0.1) {
+ aDt = Resolution(aCurve, aCurveType, theResCoeff, k*aDist);
+ if (aDt < aMaxDt)
+ {
+ toGrow = Standard_True;
+ k *= 2;
+ }
+ }
+ if (!toGrow) {
+ k = 1;
+ aDt = Resolution(aCurve, aCurveType, theResCoeff, aDist);
+ }
+ }
aTB += aC*aDt;
} else {
bRet = Standard_True;
aTIn = aTB;
aTOut = aTB - aC*aDt;
aDiff = aTIn - aTOut;
- while (fabs(aDiff) > aPTol) {
+ while (fabs(aDiff) > thePTol) {
aTB = aTOut + aDiff*aCf;
- aP = theBAC.Value(aTB);
+ theBAC.D0(aTB, aP);
if (aCBx.IsOut(aP)) {
aTOut = aTB;
} else {
//purpose :
//=======================================================================
void IntTools_EdgeEdge::MergeSolutions(const IntTools_SequenceOfRanges& theRanges1,
- const IntTools_SequenceOfRanges& theRanges2)
+ const IntTools_SequenceOfRanges& theRanges2,
+ const Standard_Boolean bSplit2)
{
+ Standard_Integer aNbCP = theRanges1.Length();
+ if (aNbCP == 0) {
+ return;
+ }
+ //
IntTools_Range aRi1, aRi2, aRj1, aRj2;
- Standard_Integer aNbCP, i, j;
+ Standard_Boolean bCond;
+ Standard_Integer i, j;
TopAbs_ShapeEnum aType;
- Standard_Real aTi11, aTi12, aTi21, aTi22,
- aTj11, aTj12, aTj21, aTj22;
+ Standard_Real aT11, aT12, aT21, aT22;
+ Standard_Real aTi11, aTi12, aTi21, aTi22;
+ Standard_Real aTj11, aTj12, aTj21, aTj22;
+ Standard_Real aRes1, aRes2, dTR1, dTR2;
+ BOPCol_MapOfInteger aMI;
+ //
+ aRes1 = Resolution(myCurve1.Curve().Curve(),
+ myCurve1.GetType(), myResCoeff1, myTol);
+ aRes2 = Resolution(myCurve2.Curve().Curve(),
+ myCurve2.GetType(), myResCoeff2, myTol);
//
- aNbCP = theRanges1.Length();
+ myRange1.Range(aT11, aT12);
+ myRange2.Range(aT21, aT22);
+ dTR1 = 20*aRes1;
+ dTR2 = 20*aRes2;
aType = TopAbs_VERTEX;
//
- for (i = 1; i <= aNbCP; ) {
+ for (i = 1; i <= aNbCP;) {
+ if (aMI.Contains(i)) {
+ ++i;
+ continue;
+ }
+ //
aRi1 = theRanges1(i);
aRi2 = theRanges2(i);
//
aRi1.Range(aTi11, aTi12);
aRi2.Range(aTi21, aTi22);
//
+ aMI.Add(i);
+ //
for (j = i+1; j <= aNbCP; ++j) {
+ if (aMI.Contains(j)) {
+ continue;
+ }
+ //
aRj1 = theRanges1(j);
aRj2 = theRanges2(j);
//
aRj1.Range(aTj11, aTj12);
aRj2.Range(aTj21, aTj22);
- if (fabs(aTi12 - aTj11) < 10*myRes1 ||
- fabs(aTi22 - aTj21) < 10*myRes2) {
+ //
+ bCond = (fabs(aTi12 - aTj11) < dTR1) ||
+ (bSplit2 && (fabs(aTj12 - aTi11) < dTR1));
+ if (bCond && bSplit2) {
+ bCond = (fabs((Max(aTi22, aTj22) - Min(aTi21, aTj21)) -
+ ((aTi22 - aTi21) + (aTj22 - aTj21))) < dTR2);
+ }
+ //
+ if (bCond) {
aTi11 = Min(aTi11, aTj11);
aTi12 = Max(aTi12, aTj12);
aTi21 = Min(aTi21, aTj21);
aTi22 = Max(aTi22, aTj22);
- } else {
+ aMI.Add(j);
+ }
+ else if (!bSplit2) {
+ i = j;
break;
}
}
- i = j;
//
- if (aTi11 == myRange1.First() && aTi12 == myRange1.Last() &&
- aTi21 == myRange2.First() && aTi22 == myRange2.Last()) {
+ if (((fabs(aT11 - aTi11) < myRes1) && (fabs(aT12 - aTi12) < myRes1)) ||
+ ((fabs(aT21 - aTi21) < myRes2) && (fabs(aT22 - aTi22) < myRes2))) {
aType = TopAbs_EDGE;
+ myCommonParts.Clear();
}
//
AddSolution(aTi11, aTi12, aTi21, aTi22, aType);
+ if (aType == TopAbs_EDGE) {
+ break;
+ }
+ //
+ if (bSplit2) {
+ ++i;
+ }
}
}
aCPart.SetEdge2(myEdge1);
aCPart.SetRange1(aT21, aT22);
aCPart.AppendRange2(aT11, aT12);
- }
+ }
//
if (theType == TopAbs_VERTEX) {
Standard_Real aT1, aT2;
Standard_Real& aT1,
Standard_Real& aT2)
{
- Standard_Real aD, aDMin, aDt, aT1x, aT2x, aT1p, aT2p, aMinStep, aTMax;
- Standard_Integer i, aNbP, iErr;
- GeomAPI_ProjectPointOnCurve aProj;
- gp_Pnt aP;
+ Standard_Integer i, aNbS, iErr;
+ Standard_Real aDMin, aD, aRes1, aSolCriteria, aTouchCriteria;
+ Standard_Real aT1A, aT1B, aT1Min, aT2Min;
+ GeomAPI_ProjectPointOnCurve aProjPC;
+ IntTools_SequenceOfRanges aRanges;
//
- aNbP = 10;
- aT1 = IntTools_Tools::IntermediatePoint(aT11, aT12);
- aT2 = IntTools_Tools::IntermediatePoint(aT21, aT22);
- aDMin = 100.;
- aD = 100.;
- aDt = (aT12 - aT11) / aNbP;
- aMinStep = 5.e-13;
- aTMax = Max(fabs(aT11), fabs(aT12));
- if (aTMax > 999.) {
- aMinStep = 5.e-16 * aTMax;
- }
+ aDMin = Precision::Infinite();
+ aSolCriteria = 5.e-16;
+ aTouchCriteria = 5.e-13;
+ Standard_Boolean bTouch = Standard_False;
+ Standard_Boolean bTouchConfirm = Standard_False;
//
- aProj.Init(myGeom2, aT21, aT22);
- for (i = 0; i < aNbP; ++i) {
- aT1x = aT11 + i*aDt;
- aT2x = aT1x + aDt;
- iErr = FindDistPC(aT1x, aT2x, myGeom1, 0., aMinStep, aProj, aD, aT1p, aT2p, Standard_False);
- if (iErr != 1 && aD < aDMin) {
- aT1 = aT1p;
- aT2 = aT2p;
- aDMin = aD;
- if (aDMin == 0.) {
- break;
+ aRes1 = Resolution(myCurve1.Curve().Curve(),
+ myCurve1.GetType(), myResCoeff1, myTol);
+ aNbS = 10;
+ aNbS = SplitRangeOnSegments(aT11, aT12, 3*aRes1, aNbS, aRanges);
+ //
+ aProjPC.Init(myGeom2, aT21, aT22);
+ //
+ Standard_Real aT11Touch = aT11, aT12Touch = aT12;
+ Standard_Real aT21Touch = aT21, aT22Touch = aT22;
+ Standard_Boolean isSolFound = Standard_False;
+ for (i = 1; i <= aNbS; ++i) {
+ const IntTools_Range& aR1 = aRanges(i);
+ aR1.Range(aT1A, aT1B);
+ //
+ aD = myTol;
+ iErr = FindDistPC(aT1A, aT1B, myGeom1, aSolCriteria, myPTol1,
+ aProjPC, aD, aT1Min, aT2Min, Standard_False);
+ if (iErr != 1) {
+ if (aD < aDMin) {
+ aT1 = aT1Min;
+ aT2 = aT2Min;
+ aDMin = aD;
+ isSolFound = Standard_True;
+ }
+ //
+ if (aD < aTouchCriteria) {
+ if (bTouch) {
+ aT12Touch = aT1Min;
+ aT22Touch = aT2Min;
+ bTouchConfirm = Standard_True;
+ }
+ else {
+ aT11Touch = aT1Min;
+ aT21Touch = aT2Min;
+ bTouch = Standard_True;
+ }
}
}
}
+ if (!isSolFound || bTouchConfirm)
+ {
+ aT1 = (aT11Touch + aT12Touch) * 0.5;
+ iErr = DistPC(aT1, myGeom1, aSolCriteria, aProjPC, aD, aT2, -1);
+ if (iErr == 1) {
+ aT2 = (aT21Touch + aT22Touch) * 0.5;
+ }
+ }
}
//=======================================================================
return;
}
//
- aCommonPrt.SetRange1(aT1 - myTol, aT1 + myTol);
- aCommonPrt.AppendRange2(aT2 - myTol, aT2 + myTol);
+ // compute correct range on the edges
+ Standard_Real anAngle, aDt1, aDt2;
+ //
+ anAngle = aD1.Angle(aD2);
+ //
+ aDt1 = IntTools_Tools::ComputeIntRange(myTol1, myTol2, anAngle);
+ aDt2 = IntTools_Tools::ComputeIntRange(myTol2, myTol1, anAngle);
+ //
+ aCommonPrt.SetRange1(aT1 - aDt1, aT1 + aDt1);
+ aCommonPrt.AppendRange2(aT2 - aDt2, aT2 + aDt2);
aCommonPrt.SetType(TopAbs_VERTEX);
aCommonPrt.SetVertexParameter1(aT1);
aCommonPrt.SetVertexParameter2(aT2);
myCommonParts.Append(aCommonPrt);
}
-//=======================================================================
-//function : FindRoughRanges
-//purpose :
-//=======================================================================
-Standard_Integer IntTools_EdgeEdge::FindRoughRanges(const IntTools_Range& theR1,
- const IntTools_Range& theR2,
- IntTools_SequenceOfRanges& theSegments1)
-{
- Standard_Integer iRet, i, j, aNbi, aNbj, aNbSD;
- Standard_Real aTi1, aTi2, aTj1, aTj2, aDi, aDj;
- IntTools_SequenceOfRanges aSi, aSj, aNewSi, aNewSj;
- BOPCol_MapOfInteger aMj;
- BOPCol_ListIteratorOfListOfInteger aItLI;
- Bnd_Box aBi, aBj;
- BOPCol_BoxBndTreeSelector aSelector;
- BOPCol_BoxBndTree aBBTree;
- NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
- //
- theR1.Range(aTi1, aTi2);
- theR2.Range(aTj1, aTj2);
- aDi = (aTi2 - aTi1) / 2.;
- aDj = (aTj2 - aTj1) / 2.;
- aNbi = 2;
- aNbj = 2;
- //
- SplitRangeOnTwo(aTi1, aTi2, aSi);
- SplitRangeOnTwo(aTj1, aTj2, aSj);
- //
- while (aDi > myRes1 || aDj > myRes2) {
- aDi /= 2.;
- aDj /= 2.;
- //
- aBBTree.Clear();
- aTreeFiller.Reset();
- for (j = 1; j <= aNbj; ++j) {
- const IntTools_Range& aRj = aSj(j);
- aRj.Range(aTj1, aTj2);
- //
- BndBuildBox(myCurve2, aTj1, aTj2, myTol2, aBj);
- //
- aTreeFiller.Add(j, aBj);
- }
- //
- aTreeFiller.Fill();
- //
- for (i = 1; i <= aNbi; ++i) {
- const IntTools_Range& aRi = aSi(i);
- aRi.Range(aTi1, aTi2);
- //
- BndBuildBox(myCurve1, aTi1, aTi2, myTol1, aBi);
- //
- aSelector.Clear();
- aSelector.SetBox(aBi);
- //
- aNbSD = aBBTree.Select(aSelector);
- if (!aNbSD){
- continue;
- }
- //
- SplitRangeOnTwo(aTi1, aTi2, aNewSi);
- //
- const BOPCol_ListOfInteger& aLI = aSelector.Indices();
- aItLI.Initialize(aLI);
- for (; aItLI.More(); aItLI.Next()) {
- j = aItLI.Value();
- if (aMj.Add(j)) {
- const IntTools_Range& aRj = aSj(j);
- aRj.Range(aTj1, aTj2);
- SplitRangeOnTwo(aTj1, aTj2, aNewSj);
- }
- }
- }
- //
- aSi.Assign(aNewSi);
- aSj.Assign(aNewSj);
- aNbi = aSi.Length();
- aNbj = aSj.Length();
- //
- if ((aNbi == 0) || (aNbj == 0) || (aNbi > 500) || (aNbj > 500)) {
- break;
- }
- //
- aNewSi.Clear();
- aNewSj.Clear();
- aMj.Clear();
- }
- //
- iRet = (aNbi && aNbj) ? 1 : 0;
- if (iRet) {
- //collect ranges
- IntTools_Range aRi1 = aSi(1), aRi2;
- Standard_Real aT1 = aRi1.First();
- for (i = 2; i <= aNbi; ++i) {
- aRi2 = aSi(i);
- if ((aRi2.First() - aRi1.Last()) > myRes1) {
- theSegments1.Append(IntTools_Range(aT1, aRi1.Last()));
- aT1 = aRi2.First();
- }
- aRi1 = aRi2;
- }
- theSegments1.Append(IntTools_Range(aT1, aRi2.Last()));
- }
- //
- return iRet;
-}
-
//=======================================================================
//function : IsIntersection
//purpose :
//
if (((anAngle1 < anAngleCriteria) || ((M_PI - anAngle1) < anAngleCriteria)) ||
((anAngle2 < anAngleCriteria) || ((M_PI - anAngle2) < anAngleCriteria))) {
- GeomAPI_ProjectPointOnCurve aProj;
+ GeomAPI_ProjectPointOnCurve aProjPC;
Standard_Integer iErr;
- Standard_Real aD, aT1p, aT2p;
+ Standard_Real aD, aT1Min, aT2Min;
//
- aD = 100.;
- aProj.Init(myGeom2, aT21, aT22);
- iErr = FindDistPC(aT11, aT12, myGeom1, myTol, myRes1, aProj, aD, aT1p, aT2p, Standard_False);
+ aD = Precision::Infinite();
+ aProjPC.Init(myGeom2, aT21, aT22);
+ iErr = FindDistPC(aT11, aT12, myGeom1, myTol, myRes1,
+ aProjPC, aD, aT1Min, aT2Min, Standard_False);
bRet = (iErr == 2);
}
}
const Standard_Real aT21,
const Standard_Real aT22,
const Standard_Real theCriteria,
- const Standard_Real theCurveResolution1)
+ const Standard_Real theCurveRes1)
{
- Standard_Integer iErr, aNb, i;
- Standard_Real dT1, aT1, aT2, aD, aDmax;
- Standard_Real aT1A, aT1B, aT1max, aT2max;
+ Standard_Integer iErr, aNb, aNb1, i;
+ Standard_Real aT1A, aT1B, aT1max, aT2max, aDmax;
GeomAPI_ProjectPointOnCurve aProjPC;
+ IntTools_SequenceOfRanges aRanges;
//
iErr = 0;
aDmax = -1.;
//
// 1. Express evaluation
aNb = 10; // Number of intervals on the curve #1
- dT1 = (aT12 - aT11) / aNb;
- for (i = 1; i < aNb; ++i) {
- aT1 = aT11 + i*dT1;
+ aNb1 = SplitRangeOnSegments(aT11, aT12, theCurveRes1, aNb, aRanges);
+ for (i = 1; i < aNb1; ++i) {
+ const IntTools_Range& aR1 = aRanges(i);
+ aR1.Range(aT1A, aT1B);
//
- iErr = DistPC(aT1, myGeom1, theCriteria, aProjPC, aD, aT2);
+ iErr = DistPC(aT1B, myGeom1, theCriteria, aProjPC, aDmax, aT2max);
if (iErr) {
return iErr;
}
}
//
+ // if the ranges in aRanges are less than theCurveRes1,
+ // there is no need to do step 2 (deep evaluation)
+ if (aNb1 < aNb) {
+ return iErr;
+ }
+ //
// 2. Deep evaluation
- aNb -= 1;
- for (i = 1; i < aNb; ++i) {
- aT1A = aT11 + i*dT1;
- aT1B = aT1A + dT1;
+ for (i = 2; i < aNb1; ++i) {
+ const IntTools_Range& aR1 = aRanges(i);
+ aR1.Range(aT1A, aT1B);
//
- iErr = FindDistPC(aT1A, aT1B, myGeom1, theCriteria, theCurveResolution1,
+ iErr = FindDistPC(aT1A, aT1B, myGeom1, theCriteria, theCurveRes1,
aProjPC, aDmax, aT1max, aT2max);
if (iErr) {
return iErr;
//
iC = bMaxDist ? 1 : -1;
iErr = 0;
+ aT1max = aT2max = 0.; // silence GCC warning
//
aGS = 0.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.))-1.;
aA = aT1A;
aB = aT1B;
//
// check bounds
- iErr = DistPC(aA, theC1, theCriteria, theProjPC, aYP, aT2P, aDmax, aT1max, aT2max, iC);
+ iErr = DistPC(aA, theC1, theCriteria, theProjPC,
+ aYP, aT2P, aDmax, aT1max, aT2max, iC);
if (iErr == 2) {
return iErr;
}
//
- iErr = DistPC(aB, theC1, theCriteria, theProjPC, aYL, aT2L, aDmax, aT1max, aT2max, iC);
+ iErr = DistPC(aB, theC1, theCriteria, theProjPC,
+ aYL, aT2L, aDmax, aT1max, aT2max, iC);
if (iErr == 2) {
return iErr;
}
aXP = aA + (aB - aA)*aGS;
aXL = aB - (aB - aA)*aGS;
//
- iErr = DistPC(aXP, theC1, theCriteria, theProjPC, aYP, aT2P, aDmax, aT1max, aT2max, iC);
+ iErr = DistPC(aXP, theC1, theCriteria, theProjPC,
+ aYP, aT2P, aDmax, aT1max, aT2max, iC);
if (iErr) {
return iErr;
}
//
- iErr = DistPC(aXL, theC1, theCriteria, theProjPC, aYL, aT2L, aDmax, aT1max, aT2max, iC);
+ iErr = DistPC(aXL, theC1, theCriteria, theProjPC,
+ aYL, aT2L, aDmax, aT1max, aT2max, iC);
if (iErr) {
return iErr;
}
//
+ Standard_Real anEps = Max(theEps, Epsilon(Max(Abs(aA), Abs(aB))) * 10.);
for (;;) {
if (iC*(aYP - aYL) > 0) {
aA = aXL;
aXL = aXP;
aYL = aYP;
aXP = aA + (aB - aA)*aGS;
- iErr = DistPC(aXP, theC1, theCriteria, theProjPC, aYP, aT2P, aDmax, aT1max, aT2max, iC);
- if (iErr) {
- return iErr;
- }
+ iErr = DistPC(aXP, theC1, theCriteria, theProjPC,
+ aYP, aT2P, aDmax, aT1max, aT2max, iC);
}
else {
aB = aXP;
aXP = aXL;
aYP = aYL;
aXL = aB - (aB - aA)*aGS;
- iErr = DistPC(aXL, theC1, theCriteria, theProjPC, aYL, aT2L, aDmax, aT1max, aT2max, iC);
- if (iErr) {
- return iErr;
+ iErr = DistPC(aXL, theC1, theCriteria, theProjPC,
+ aYL, aT2L, aDmax, aT1max, aT2max, iC);
+ }
+ //
+ if (iErr) {
+ if ((iErr == 2) && !bMaxDist) {
+ aXP = (aA + aB) * 0.5;
+ DistPC(aXP, theC1, theCriteria, theProjPC,
+ aYP, aT2P, aDmax, aT1max, aT2max, iC);
}
+ return iErr;
}
//
- if ((aB - aA) < theEps) {
+ if ((aB - aA) < anEps) {
break;
}
}// for (;;) {
Standard_Integer iErr;
//
iErr = DistPC(aT1, theC1, theCriteria, theProjPC, aD, aT2, iC);
- if (iErr) {
+ if (iErr == 1) {
return iErr;
}
//
//function : SplitRangeOnSegments
//purpose :
//=======================================================================
-void SplitRangeOnSegments(const Standard_Real aT1,
- const Standard_Real aT2,
- const Standard_Real theResolution,
- const Standard_Integer theNbSeg,
- IntTools_SequenceOfRanges& theSegments)
+Standard_Integer SplitRangeOnSegments(const Standard_Real aT1,
+ const Standard_Real aT2,
+ const Standard_Real theResolution,
+ const Standard_Integer theNbSeg,
+ IntTools_SequenceOfRanges& theSegments)
{
+ Standard_Real aDiff = aT2 - aT1;
+ if (aDiff < theResolution || theNbSeg == 1) {
+ theSegments.Append(IntTools_Range(aT1, aT2));
+ return 1;
+ }
+ //
Standard_Real aDt, aT1x, aT2x, aSeg;
Standard_Integer aNbSegments, i;
//
aNbSegments = theNbSeg;
- aDt = aT2 - aT1;
+ aDt = aDiff / aNbSegments;
if (aDt < theResolution) {
- aNbSegments = 1;
- } else if (aDt < Precision::Confusion()) {
- aSeg = aDt / theResolution;
- if (aSeg < theNbSeg) {
- aNbSegments = Standard_Integer(aSeg) + 1;
- }
+ aSeg = aDiff / theResolution;
+ aNbSegments = Standard_Integer(aSeg) + 1;
+ aDt = aDiff / aNbSegments;
}
//
- aDt /= aNbSegments;
aT1x = aT1;
- for (i = 1; i <= aNbSegments; ++i) {
+ for (i = 1; i < aNbSegments; ++i) {
aT2x = aT1x + aDt;
- if (i==aNbSegments) {
- aT2x = aT2;
- }
//
IntTools_Range aR(aT1x, aT2x);
theSegments.Append(aR);
//
aT1x = aT2x;
}
-}
-
-//=======================================================================
-//function : SplitRangeOnTwo
-//purpose :
-//=======================================================================
-void SplitRangeOnTwo(const Standard_Real aT1,
- const Standard_Real aT2,
- IntTools_SequenceOfRanges& theSegments)
-{
- Standard_Real aCf, aT;
- //
- aCf=0.5;
- aT = aT1 + (aT2-aT1)*aCf;
//
- IntTools_Range aR1(aT1, aT), aR2(aT, aT2);
- //
- theSegments.Append(aR1);
- theSegments.Append(aR2);
-}
-
-//=======================================================================
-//function : BndCommon
-//purpose :
-//=======================================================================
-Standard_Boolean BndCommon(const Bnd_Box& theB1,
- const Bnd_Box& theB2,
- Bnd_Box& theBOut)
-{
- Standard_Boolean bRet;
+ IntTools_Range aR(aT1x, aT2);
+ theSegments.Append(aR);
//
- bRet = !theB1.IsOut(theB2);
- if (bRet) {
- Standard_Real aXmin1, aYmin1, aZmin1, aXmax1, aYmax1, aZmax1,
- aXmin2, aYmin2, aZmin2, aXmax2, aYmax2, aZmax2;
- Bnd_Box aBCom;
- //
- theB1.Get(aXmin1, aYmin1, aZmin1, aXmax1, aYmax1, aZmax1);
- theB2.Get(aXmin2, aYmin2, aZmin2, aXmax2, aYmax2, aZmax2);
- //
- aBCom.Update(Max(aXmin1, aXmin2), Max(aYmin1, aYmin2), Max(aZmin1, aZmin2),
- Min(aXmax1, aXmax2), Min(aYmax1, aYmax2), Min(aZmax1, aZmax2));
- //
- aBCom.Get(aXmin1, aYmin1, aZmin1, aXmax1, aYmax1, aZmax1);
- theBOut = aBCom;
- }
- return bRet;
+ return aNbSegments;
}
//=======================================================================
theBox = aB;
}
+//=======================================================================
+//function : PointBoxDistance
+//purpose :
+//=======================================================================
+Standard_Real PointBoxDistance(const Bnd_Box& aB,
+ const gp_Pnt& aP)
+{
+ Standard_Real aPCoord[3];
+ Standard_Real aBMinCoord[3], aBMaxCoord[3];
+ Standard_Real aDist, aR1, aR2;
+ Standard_Integer i;
+ //
+ aP.Coord(aPCoord[0], aPCoord[1], aPCoord[2]);
+ aB.Get(aBMinCoord[0], aBMinCoord[1], aBMinCoord[2],
+ aBMaxCoord[0], aBMaxCoord[1], aBMaxCoord[2]);
+ //
+ aDist = 0.;
+ for (i = 0; i < 3; ++i) {
+ aR1 = aBMinCoord[i] - aPCoord[i];
+ if (aR1 > 0.) {
+ aDist += aR1*aR1;
+ continue;
+ }
+ //
+ aR2 = aPCoord[i] - aBMaxCoord[i];
+ if (aR2 > 0.) {
+ aDist += aR2*aR2;
+ }
+ }
+ //
+ aDist = Sqrt(aDist);
+ return aDist;
+}
+
//=======================================================================
//function : TypeToInteger
//purpose :
case GeomAbs_Line:
iRet=0;
break;
- case GeomAbs_Circle:
+ case GeomAbs_Hyperbola:
+ case GeomAbs_Parabola:
iRet=1;
break;
+ case GeomAbs_Circle:
case GeomAbs_Ellipse:
- case GeomAbs_Hyperbola:
- case GeomAbs_Parabola:
iRet=2;
break;
case GeomAbs_BezierCurve:
return iRet;
}
+//=======================================================================
+//function : ResolutionCoeff
+//purpose :
+//=======================================================================
+Standard_Real ResolutionCoeff(const BRepAdaptor_Curve& theBAC,
+ const IntTools_Range& theRange)
+{
+ Standard_Real aResCoeff = 0.;
+ //
+ const Handle(Geom_Curve)& aCurve = theBAC.Curve().Curve();
+ const GeomAbs_CurveType aCurveType = theBAC.GetType();
+ //
+ switch (aCurveType) {
+ case GeomAbs_Circle :
+ aResCoeff = 1. / (2 * Handle(Geom_Circle)::DownCast (aCurve)->Circ().Radius());
+ break;
+ case GeomAbs_Ellipse :
+ aResCoeff = 1. / Handle(Geom_Ellipse)::DownCast (aCurve)->MajorRadius();
+ break;
+ case GeomAbs_OffsetCurve : {
+ const Handle(Geom_OffsetCurve)& anOffsetCurve = Handle(Geom_OffsetCurve)::DownCast(aCurve);
+ const Handle(Geom_Curve)& aBasisCurve = anOffsetCurve->BasisCurve();
+ GeomAdaptor_Curve aGBasisCurve(aBasisCurve);
+ const GeomAbs_CurveType aBCType = aGBasisCurve.GetType();
+ if (aBCType == GeomAbs_Line) {
+ break;
+ }
+ else if (aBCType == GeomAbs_Circle) {
+ aResCoeff = 1. / (2 * (anOffsetCurve->Offset() + aGBasisCurve.Circle().Radius()));
+ break;
+ }
+ else if (aBCType == GeomAbs_Ellipse) {
+ aResCoeff = 1. / (anOffsetCurve->Offset() + aGBasisCurve.Ellipse().MajorRadius());
+ break;
+ }
+ }
+ Standard_FALLTHROUGH
+ case GeomAbs_Hyperbola :
+ case GeomAbs_Parabola :
+ case GeomAbs_OtherCurve :{
+ Standard_Real k, kMin, aDist, aDt, aT1, aT2, aT;
+ Standard_Integer aNbP, i;
+ gp_Pnt aP1, aP2;
+ //
+ aNbP = 30;
+ theRange.Range(aT1, aT2);
+ aDt = (aT2 - aT1) / aNbP;
+ aT = aT1;
+ kMin = 10.;
+ //
+ theBAC.D0(aT1, aP1);
+ for (i = 1; i <= aNbP; ++i) {
+ aT += aDt;
+ theBAC.D0(aT, aP2);
+ aDist = aP1.Distance(aP2);
+ k = aDt / aDist;
+ if (k < kMin) {
+ kMin = k;
+ }
+ aP1 = aP2;
+ }
+ //
+ aResCoeff = kMin;
+ break;
+ }
+ default:
+ break;
+ }
+ //
+ return aResCoeff;
+}
+
+//=======================================================================
+//function : Resolution
+//purpose :
+//=======================================================================
+Standard_Real Resolution(const Handle(Geom_Curve)& theCurve,
+ const GeomAbs_CurveType theCurveType,
+ const Standard_Real theResCoeff,
+ const Standard_Real theR3D)
+{
+ Standard_Real aRes;
+ //
+ switch (theCurveType) {
+ case GeomAbs_Line :
+ aRes = theR3D;
+ break;
+ case GeomAbs_Circle: {
+ Standard_Real aDt = theResCoeff * theR3D;
+ aRes = (aDt <= 1.) ? 2*ASin(aDt) : 2*M_PI;
+ break;
+ }
+ case GeomAbs_BezierCurve:
+ Handle(Geom_BezierCurve)::DownCast (theCurve)->Resolution(theR3D, aRes);
+ break;
+ case GeomAbs_BSplineCurve:
+ Handle(Geom_BSplineCurve)::DownCast (theCurve)->Resolution(theR3D, aRes);
+ break;
+ case GeomAbs_OffsetCurve: {
+ const Handle(Geom_Curve)& aBasisCurve =
+ Handle(Geom_OffsetCurve)::DownCast(theCurve)->BasisCurve();
+ const GeomAbs_CurveType aBCType = GeomAdaptor_Curve(aBasisCurve).GetType();
+ if (aBCType == GeomAbs_Line) {
+ aRes = theR3D;
+ break;
+ }
+ else if (aBCType == GeomAbs_Circle) {
+ Standard_Real aDt = theResCoeff * theR3D;
+ aRes = (aDt <= 1.) ? 2*ASin(aDt) : 2*M_PI;
+ break;
+ }
+ }
+ Standard_FALLTHROUGH
+ default:
+ aRes = theResCoeff * theR3D;
+ break;
+ }
+ //
+ return aRes;
+}
+
+//=======================================================================
+//function : CurveDeflection
+//purpose :
+//=======================================================================
+Standard_Real CurveDeflection(const BRepAdaptor_Curve& theBAC,
+ const IntTools_Range& theRange)
+{
+ Standard_Real aDt, aT, aT1, aT2, aDefl;
+ Standard_Integer i, aNbP;
+ gp_Vec aV1, aV2;
+ gp_Pnt aP;
+ //
+ aDefl = 0;
+ aNbP = 10;
+ theRange.Range(aT1, aT2);
+ aDt = (aT2 - aT1) / aNbP;
+ aT = aT1;
+ //
+ theBAC.D1(aT1, aP, aV1);
+ for (i = 1; i <= aNbP; ++i) {
+ aT += aDt;
+ theBAC.D1(aT, aP, aV2);
+ if (aV1.Magnitude() > gp::Resolution() &&
+ aV2.Magnitude() > gp::Resolution()) {
+ gp_Dir aD1(aV1), aD2(aV2);
+ aDefl += aD1.Angle(aD2);
+ }
+ aV1 = aV2;
+ }
+ //
+ return aDefl;
+}
+
+//=======================================================================
+//function : IsClosed
+//purpose :
+//=======================================================================
+Standard_Boolean IsClosed(const Handle(Geom_Curve)& theCurve,
+ const Standard_Real aT1,
+ const Standard_Real aT2,
+ const Standard_Real theTol,
+ const Standard_Real theRes)
+{
+ if (Abs(aT1 - aT2) < theRes)
+ {
+ return Standard_False;
+ }
+
+ gp_Pnt aP1, aP2;
+ theCurve->D0(aT1, aP1);
+ theCurve->D0(aT2, aP2);
+ //
+ Standard_Real aD = aP1.Distance(aP2);
+ return aD < theTol;
+}