mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0029745: Modeling Data - GeomAdaptor_Surface::VIntervals fails on periodic surfaces
Fixed GeomAdaptor_Curve::LocalContinuity() for periodic curves. Fixed GeomAdaptor_Curve::NbIntervals() for periodic curves. Fixed GeomAdaptor_Curve::Intervals() for periodic curves. Improved definition of length in tests. Update Geom2dAdaptor_Curve to the same behavior.
This commit is contained in:
@@ -58,6 +58,65 @@ static const Standard_Real PosTol = Precision::PConfusion() / 2;
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Geom2dAdaptor_Curve, Adaptor2d_Curve2d)
|
||||
|
||||
static void DefinFPeriod(const Standard_Real theLower,
|
||||
const Standard_Real theUpper,
|
||||
const Standard_Real theEps,
|
||||
const Standard_Real thePeriod,
|
||||
Standard_Real &theCurFirst,
|
||||
Standard_Integer &theFPer);
|
||||
|
||||
static void DefinLPeriod(const Standard_Real theLower,
|
||||
const Standard_Real theUpper,
|
||||
const Standard_Real theEps,
|
||||
const Standard_Real thePeriod,
|
||||
Standard_Real &theCurLast,
|
||||
Standard_Integer &theLPer);
|
||||
|
||||
static Standard_Integer LocalNbIntervals(const TColStd_Array1OfReal& theTK,
|
||||
const TColStd_Array1OfInteger& theTM,
|
||||
const TColStd_Array1OfInteger& theInter,
|
||||
const Standard_Integer theCurDegree,
|
||||
const Standard_Integer theNb,
|
||||
const Standard_Integer theNbInt,
|
||||
const Standard_Real theFirst,
|
||||
const Standard_Real theLast,
|
||||
const Standard_Real theEps,
|
||||
const Standard_Boolean thePeriodicCur,
|
||||
Standard_Integer theNbIntervals,
|
||||
Standard_Real theLower = 0,
|
||||
Standard_Real thePeriod = 0,
|
||||
Standard_Integer theIndex1 = 0,
|
||||
Standard_Integer theIndex2 = 0);
|
||||
|
||||
static void WriteIntervals(const TColStd_Array1OfReal &theTK,
|
||||
const TColStd_Array1OfInteger &theInter,
|
||||
const Standard_Integer theNbInt,
|
||||
const Standard_Integer theIndex1,
|
||||
const Standard_Integer theIndex2,
|
||||
const Standard_Real theCurPeriod,
|
||||
const Standard_Boolean theFlagForFirst,
|
||||
TColStd_Array1OfReal &theT,
|
||||
TColStd_Array1OfInteger &theFinalIntervals,
|
||||
Standard_Integer &theNbIntervals,
|
||||
Standard_Integer &theCurInt);
|
||||
|
||||
static void SpreadInt(const TColStd_Array1OfReal &theTK,
|
||||
const TColStd_Array1OfInteger &theTM,
|
||||
const TColStd_Array1OfInteger &theInter,
|
||||
const Standard_Integer theCurDegree,
|
||||
const Standard_Integer theNb,
|
||||
const Standard_Integer theFPer,
|
||||
const Standard_Integer theLPer,
|
||||
const Standard_Integer theNbInt,
|
||||
const Standard_Real theLower,
|
||||
const Standard_Real theFirst,
|
||||
const Standard_Real theLast,
|
||||
const Standard_Real thePeriod,
|
||||
const Standard_Real theLastParam,
|
||||
const Standard_Real theEps,
|
||||
TColStd_Array1OfReal &theT,
|
||||
Standard_Integer &theNbIntervals);
|
||||
|
||||
//=======================================================================
|
||||
//function : ShallowCopy
|
||||
//purpose :
|
||||
@@ -115,7 +174,7 @@ GeomAbs_Shape Geom2dAdaptor_Curve::LocalContinuity(const Standard_Real U1,
|
||||
if ( myBSplineCurve->IsPeriodic() && Index1 == Nb )
|
||||
Index1 = 1;
|
||||
|
||||
if ( Index2 - Index1 <= 0) {
|
||||
if ((Index2 - Index1 <= 0) && (!myBSplineCurve->IsPeriodic())) {
|
||||
MultMax = 100; // CN entre 2 Noeuds consecutifs
|
||||
}
|
||||
else {
|
||||
@@ -295,6 +354,158 @@ GeomAbs_Shape Geom2dAdaptor_Curve::Continuity() const
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DefinFPeriod
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void DefinFPeriod(const Standard_Real theLower,
|
||||
const Standard_Real theUpper,
|
||||
const Standard_Real theEps,
|
||||
const Standard_Real thePeriod,
|
||||
Standard_Real &theCurFirst,
|
||||
Standard_Integer &theFPer)
|
||||
{
|
||||
if (theCurFirst >= theLower)
|
||||
{
|
||||
while (theCurFirst >= theUpper)
|
||||
{
|
||||
theCurFirst = theCurFirst - thePeriod;
|
||||
theFPer++;
|
||||
}
|
||||
if (Abs(theUpper - theCurFirst) <= theEps)
|
||||
{
|
||||
theFPer++;
|
||||
theCurFirst = theLower;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (theCurFirst < theLower)
|
||||
{
|
||||
theCurFirst = theCurFirst + thePeriod;
|
||||
if (Abs(theLower - theCurFirst) > theEps)
|
||||
{
|
||||
theFPer--;
|
||||
}
|
||||
}
|
||||
|
||||
if (Abs(theUpper - theCurFirst) <= theEps)
|
||||
{
|
||||
theCurFirst = theLower;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DefinLPeriod
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void DefinLPeriod(const Standard_Real theLower,
|
||||
const Standard_Real theUpper,
|
||||
const Standard_Real theEps,
|
||||
const Standard_Real thePeriod,
|
||||
Standard_Real &theCurLast,
|
||||
Standard_Integer &theLPer)
|
||||
{
|
||||
if (theCurLast >= theLower)
|
||||
{
|
||||
if ((theCurLast >= theUpper) && (Abs(theCurLast - theUpper) <= theEps))
|
||||
{
|
||||
theCurLast = theUpper;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (theCurLast >= theUpper)
|
||||
{
|
||||
theCurLast = theCurLast - thePeriod;
|
||||
theLPer++;
|
||||
}
|
||||
if (Abs(theUpper - theCurLast) <= theEps)
|
||||
{
|
||||
theCurLast = theLower;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (theCurLast < theLower)
|
||||
{
|
||||
theCurLast = theCurLast + thePeriod;
|
||||
if (Abs(theLower - theCurLast) > theEps)
|
||||
{
|
||||
theLPer--;
|
||||
}
|
||||
}
|
||||
if (Abs(theUpper - theCurLast) <= theEps)
|
||||
{
|
||||
theCurLast = theLower;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : LocalNbIntervals
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer LocalNbIntervals(const TColStd_Array1OfReal& theTK,
|
||||
const TColStd_Array1OfInteger& theTM,
|
||||
const TColStd_Array1OfInteger& theInter,
|
||||
const Standard_Integer theCurDegree,
|
||||
const Standard_Integer theNb,
|
||||
const Standard_Integer theNbInt,
|
||||
const Standard_Real theFirst,
|
||||
const Standard_Real theLast,
|
||||
const Standard_Real theEps,
|
||||
const Standard_Boolean thePeriodicCur,
|
||||
Standard_Integer theNbIntervals,
|
||||
Standard_Real theLower,
|
||||
Standard_Real thePeriod,
|
||||
Standard_Integer theIndex1,
|
||||
Standard_Integer theIndex2)
|
||||
{
|
||||
Standard_Real aNewFirst = theFirst;
|
||||
Standard_Real aNewLast = theLast;
|
||||
if (theIndex1 == 0)
|
||||
{
|
||||
BSplCLib::LocateParameter(theCurDegree, theTK, theTM, theFirst,
|
||||
thePeriodicCur, 1, theNb, theIndex1, aNewFirst);
|
||||
}
|
||||
if (theIndex2 == 0)
|
||||
{
|
||||
BSplCLib::LocateParameter(theCurDegree, theTK, theTM, theLast,
|
||||
thePeriodicCur, 1, theNb, theIndex2, aNewLast);
|
||||
}
|
||||
// Protection against theFirst = UFirst - eps, which located as ULast - eps
|
||||
if (thePeriodicCur && ((aNewLast - aNewFirst) < Precision::PConfusion()))
|
||||
{
|
||||
if (Abs(aNewLast - theLower) < Precision::PConfusion())
|
||||
{
|
||||
aNewLast += thePeriod;
|
||||
}
|
||||
else
|
||||
{
|
||||
aNewFirst -= thePeriod;
|
||||
}
|
||||
}
|
||||
|
||||
if (Abs(aNewFirst - theTK(theIndex1 + 1)) < theEps)
|
||||
{
|
||||
theIndex1++;
|
||||
}
|
||||
if ((aNewLast - theTK(theIndex2)) > theEps)
|
||||
{
|
||||
theIndex2++;
|
||||
}
|
||||
for (Standard_Integer i = 1; i <= theNbInt; i++)
|
||||
{
|
||||
if (theInter(i) > theIndex1 && theInter(i) < theIndex2) theNbIntervals++;
|
||||
}
|
||||
return theNbIntervals;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : NbIntervals
|
||||
//purpose :
|
||||
@@ -306,77 +517,179 @@ Standard_Integer Geom2dAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
|
||||
Standard_Integer NbSplit;
|
||||
if (myTypeCurve == GeomAbs_BSplineCurve) {
|
||||
Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex();
|
||||
Standard_Integer LastIndex = myBSplineCurve->LastUKnotIndex();
|
||||
TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
|
||||
if ( S > Continuity()) {
|
||||
Standard_Integer LastIndex = myBSplineCurve->LastUKnotIndex();
|
||||
TColStd_Array1OfInteger Inter(1, LastIndex - FirstIndex + 1);
|
||||
Standard_Boolean aContPer = (S >= Continuity()) && myBSplineCurve->IsPeriodic();
|
||||
Standard_Boolean aContNotPer = (S > Continuity()) && !myBSplineCurve->IsPeriodic();
|
||||
if (aContPer || aContNotPer) {
|
||||
Standard_Integer Cont;
|
||||
switch ( S) {
|
||||
switch (S) {
|
||||
case GeomAbs_G1:
|
||||
case GeomAbs_G2:
|
||||
throw Standard_DomainError("Geom2dAdaptor_Curve::NbIntervals");
|
||||
break;
|
||||
throw Standard_DomainError("Geom2dAdaptor_Curve::NbIntervals");
|
||||
break;
|
||||
case GeomAbs_C0:
|
||||
myNbIntervals = 1;
|
||||
break;
|
||||
myNbIntervals = 1;
|
||||
break;
|
||||
case GeomAbs_C1:
|
||||
case GeomAbs_C2:
|
||||
case GeomAbs_C3:
|
||||
case GeomAbs_CN:
|
||||
{
|
||||
if ( S == GeomAbs_C1) Cont = 1;
|
||||
else if ( S == GeomAbs_C2) Cont = 2;
|
||||
else if ( S == GeomAbs_C3) Cont = 3;
|
||||
else Cont = myBSplineCurve->Degree();
|
||||
Standard_Integer Degree = myBSplineCurve->Degree();
|
||||
Standard_Integer NbKnots = myBSplineCurve->NbKnots();
|
||||
TColStd_Array1OfInteger Mults (1, NbKnots);
|
||||
myBSplineCurve->Multiplicities (Mults);
|
||||
NbSplit = 1;
|
||||
Standard_Integer Index = FirstIndex;
|
||||
Inter (NbSplit) = Index;
|
||||
case GeomAbs_C3:
|
||||
case GeomAbs_CN:
|
||||
{
|
||||
if (S == GeomAbs_C1) Cont = 1;
|
||||
else if (S == GeomAbs_C2) Cont = 2;
|
||||
else if (S == GeomAbs_C3) Cont = 3;
|
||||
else Cont = myBSplineCurve->Degree();
|
||||
Standard_Integer Degree = myBSplineCurve->Degree();
|
||||
Standard_Integer NbKnots = myBSplineCurve->NbKnots();
|
||||
TColStd_Array1OfInteger Mults(1, NbKnots);
|
||||
myBSplineCurve->Multiplicities(Mults);
|
||||
NbSplit = 1;
|
||||
Standard_Integer Index = FirstIndex;
|
||||
Inter(NbSplit) = Index;
|
||||
Index++;
|
||||
NbSplit++;
|
||||
while (Index < LastIndex)
|
||||
{
|
||||
if (Degree - Mults(Index) < Cont)
|
||||
{
|
||||
Inter(NbSplit) = Index;
|
||||
NbSplit++;
|
||||
}
|
||||
Index++;
|
||||
NbSplit++;
|
||||
while (Index < LastIndex)
|
||||
{
|
||||
if (Degree - Mults (Index) < Cont)
|
||||
{
|
||||
Inter (NbSplit) = Index;
|
||||
NbSplit++;
|
||||
}
|
||||
Index++;
|
||||
}
|
||||
Inter (NbSplit) = Index;
|
||||
|
||||
Standard_Integer NbInt = NbSplit-1;
|
||||
|
||||
Standard_Integer Nb = myBSplineCurve->NbKnots();
|
||||
Standard_Integer Index1 = 0;
|
||||
Standard_Integer Index2 = 0;
|
||||
Standard_Real newFirst, newLast;
|
||||
TColStd_Array1OfReal TK(1,Nb);
|
||||
TColStd_Array1OfInteger TM(1,Nb);
|
||||
myBSplineCurve->Knots(TK);
|
||||
myBSplineCurve->Multiplicities(TM);
|
||||
BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myFirst,
|
||||
myBSplineCurve->IsPeriodic(),
|
||||
1,Nb,Index1,newFirst);
|
||||
BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myLast,
|
||||
myBSplineCurve->IsPeriodic(),
|
||||
1,Nb,Index2,newLast);
|
||||
|
||||
// On decale eventuellement les indices
|
||||
// On utilise une "petite" tolerance, la resolution ne doit
|
||||
// servir que pour les tres longue courbes....(PRO9248)
|
||||
Standard_Real Eps = Min(Resolution(Precision::Confusion()),
|
||||
Precision::PConfusion());
|
||||
if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++;
|
||||
if ( newLast-TK(Index2)> Eps) Index2++;
|
||||
|
||||
myNbIntervals = 1;
|
||||
for ( Standard_Integer i=1; i<=NbInt; i++)
|
||||
if (Inter(i)>Index1 && Inter(i)<Index2) myNbIntervals++;
|
||||
}
|
||||
break;
|
||||
Inter(NbSplit) = Index;
|
||||
|
||||
Standard_Integer NbInt = NbSplit - 1;
|
||||
|
||||
Standard_Integer Nb = myBSplineCurve->NbKnots();
|
||||
TColStd_Array1OfReal TK(1, Nb);
|
||||
TColStd_Array1OfInteger TM(1, Nb);
|
||||
myBSplineCurve->Knots(TK);
|
||||
myBSplineCurve->Multiplicities(TM);
|
||||
Standard_Real Eps = Min(Resolution(Precision::Confusion()),
|
||||
Precision::PConfusion());
|
||||
|
||||
myNbIntervals = 1;
|
||||
|
||||
if (!myBSplineCurve->IsPeriodic())
|
||||
{
|
||||
myNbIntervals = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
|
||||
myFirst, myLast, Eps, Standard_False, myNbIntervals);
|
||||
}
|
||||
else
|
||||
{
|
||||
Standard_Real aCurFirst = myFirst;
|
||||
Standard_Real aCurLast = myLast;
|
||||
|
||||
Standard_Real aLower = myBSplineCurve->FirstParameter();
|
||||
Standard_Real anUpper = myBSplineCurve->LastParameter();
|
||||
|
||||
if ((Abs(aCurFirst - aLower) < Eps) && (aCurFirst < aLower))
|
||||
{
|
||||
aCurFirst = aLower;
|
||||
}
|
||||
if ((Abs(aCurLast - anUpper) < Eps) && (aCurLast < anUpper))
|
||||
{
|
||||
aCurLast = anUpper;
|
||||
}
|
||||
|
||||
Standard_Real aPeriod = myBSplineCurve->Period();
|
||||
Standard_Integer aLPer = 1; Standard_Integer aFPer = 1;
|
||||
|
||||
if ((Abs(aLower - myFirst) < Eps) && (aCurFirst < aLower))
|
||||
{
|
||||
aCurFirst = aLower;
|
||||
}
|
||||
else
|
||||
{
|
||||
DefinFPeriod(aLower, anUpper,
|
||||
Eps, aPeriod, aCurFirst, aFPer);
|
||||
}
|
||||
DefinLPeriod(aLower, anUpper,
|
||||
Eps, aPeriod, aCurLast, aLPer);
|
||||
|
||||
if ((Abs(aLower - myFirst) < Eps) && (Abs(anUpper - myLast) < Eps))
|
||||
{
|
||||
myNbIntervals = NbInt;
|
||||
}
|
||||
else
|
||||
{
|
||||
Standard_Integer aSumPer = Abs(aLPer - aFPer);
|
||||
|
||||
Standard_Real aFirst = 0;
|
||||
if (aLower < 0 && anUpper == 0)
|
||||
{
|
||||
if (Abs(aCurLast) < Eps)
|
||||
{
|
||||
aCurLast = 0;
|
||||
}
|
||||
aFirst = aLower;
|
||||
}
|
||||
|
||||
if (aSumPer <= 1)
|
||||
{
|
||||
if ((Abs(myFirst - TK(Nb) - aPeriod * (aFPer - 1)) <= Eps) && (myLast < (TK(Nb) + aPeriod * (aLPer - 1))))
|
||||
{
|
||||
myNbIntervals = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
|
||||
myFirst, myLast, Eps, Standard_True, myNbIntervals, aLower, aPeriod);
|
||||
return myNbIntervals;
|
||||
}
|
||||
if ((Abs(myFirst - aLower) < Eps) && (Abs(myLast - anUpper) < Eps))
|
||||
{
|
||||
myNbIntervals = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
|
||||
myFirst, myLast, Eps, Standard_True, myNbIntervals, aLower, aPeriod);
|
||||
return myNbIntervals;
|
||||
}
|
||||
}
|
||||
|
||||
if (aSumPer != 0)
|
||||
{
|
||||
Standard_Integer aFInt = 0;
|
||||
Standard_Integer aLInt = 0;
|
||||
Standard_Integer aPInt = NbInt;
|
||||
|
||||
if ((aCurFirst != aPeriod) || ((aCurFirst != anUpper) && (Abs(myFirst) < Eps)))
|
||||
{
|
||||
aFInt = 1;
|
||||
}
|
||||
if ((aCurLast != 0) && (aCurLast != anUpper))
|
||||
{
|
||||
aLInt = 1;
|
||||
}
|
||||
|
||||
aFInt = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
|
||||
aCurFirst, anUpper, Eps, Standard_True, aFInt, aLower, aPeriod);
|
||||
|
||||
if (aCurLast == anUpper)
|
||||
{
|
||||
aLInt = NbInt;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Abs(aCurLast - aFirst) > Eps)
|
||||
{
|
||||
aLInt = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
|
||||
aFirst, aCurLast, Eps, Standard_True, aLInt, aLower, aPeriod, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
aLInt = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
|
||||
aFirst, aCurLast, Eps, Standard_True, aLInt, aLower, aPeriod);
|
||||
}
|
||||
}
|
||||
|
||||
myNbIntervals = aFInt + aLInt + aPInt * (aSumPer - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
myNbIntervals = LocalNbIntervals(TK, TM, Inter, Degree, Nb, NbInt,
|
||||
aCurFirst, aCurLast, Eps, Standard_True, myNbIntervals, aLower, aPeriod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -399,6 +712,204 @@ Standard_Integer Geom2dAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
|
||||
return myNbIntervals;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : WriteIntervals
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void WriteIntervals(const TColStd_Array1OfReal &theTK,
|
||||
const TColStd_Array1OfInteger &theInter,
|
||||
const Standard_Integer theNbInt,
|
||||
const Standard_Integer theIndex1,
|
||||
const Standard_Integer theIndex2,
|
||||
const Standard_Real theCurPeriod,
|
||||
const Standard_Boolean theFlagForFirst,
|
||||
TColStd_Array1OfReal &theT,
|
||||
TColStd_Array1OfInteger &theFinalIntervals,
|
||||
Standard_Integer &theNbIntervals,
|
||||
Standard_Integer &theCurInt)
|
||||
{
|
||||
if (theFlagForFirst)
|
||||
{
|
||||
for (Standard_Integer anId = 1; anId <= theNbInt; anId++)
|
||||
{
|
||||
if (theInter(anId) > theIndex1 && theInter(anId) <= theIndex2)
|
||||
{
|
||||
theNbIntervals++;
|
||||
theFinalIntervals(theNbIntervals) = theInter(anId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Standard_Integer anId = 1; anId <= theNbInt; anId++)
|
||||
{
|
||||
if (theInter(anId) > theIndex1 && theInter(anId) < theIndex2)
|
||||
{
|
||||
theNbIntervals++;
|
||||
theFinalIntervals(theNbIntervals) = theInter(anId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
theFinalIntervals(theNbIntervals + 1) = theIndex2;
|
||||
|
||||
for (Standard_Integer anId = theCurInt; anId <= theNbIntervals + 1; anId++)
|
||||
{
|
||||
theT(anId) = theTK(theFinalIntervals(anId)) + theCurPeriod;
|
||||
theCurInt++;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SpreadInt
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void SpreadInt(const TColStd_Array1OfReal &theTK,
|
||||
const TColStd_Array1OfInteger &theTM,
|
||||
const TColStd_Array1OfInteger &theInter,
|
||||
const Standard_Integer theCurDegree,
|
||||
const Standard_Integer theNb,
|
||||
const Standard_Integer theFPer,
|
||||
const Standard_Integer theLPer,
|
||||
const Standard_Integer theNbInt,
|
||||
const Standard_Real theLower,
|
||||
const Standard_Real theFirst,
|
||||
const Standard_Real theLast,
|
||||
const Standard_Real thePeriod,
|
||||
const Standard_Real theLastParam,
|
||||
const Standard_Real theEps,
|
||||
TColStd_Array1OfReal &theT,
|
||||
Standard_Integer &theNbIntervals)
|
||||
{
|
||||
Standard_Integer anIndex1 = 0;
|
||||
Standard_Integer anIndex2 = 0;
|
||||
Standard_Real aNewFirst, aNewLast;
|
||||
Standard_Integer anUpper;
|
||||
BSplCLib::LocateParameter(theCurDegree, theTK, theTM, theFirst,
|
||||
Standard_True, 1, theNb, anIndex1, aNewFirst);
|
||||
BSplCLib::LocateParameter(theCurDegree, theTK, theTM, theLastParam,
|
||||
Standard_True, 1, theNb, anIndex2, aNewLast);
|
||||
|
||||
if (Abs(aNewFirst - theTK(anIndex1 + 1)) < theEps)
|
||||
{
|
||||
anIndex1++;
|
||||
}
|
||||
if ((aNewLast - theTK(anIndex2)) > theEps)
|
||||
{
|
||||
anIndex2++;
|
||||
}
|
||||
theNbIntervals = 1;
|
||||
|
||||
if (anIndex1 == theNb)
|
||||
{
|
||||
anIndex1 = 1;
|
||||
}
|
||||
|
||||
// Count the max number of boundaries of intervals
|
||||
if (Abs(theLPer - theFPer) > 1)
|
||||
{
|
||||
anUpper = theNb - anIndex1 + anIndex2 + (theLPer - theFPer - 1) * theNb + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
anUpper = theNb - anIndex1 + anIndex2 + 1;
|
||||
}
|
||||
|
||||
if (theLPer == theFPer)
|
||||
{
|
||||
anUpper = theInter.Upper();
|
||||
}
|
||||
TColStd_Array1OfInteger aFinalIntervals(1, anUpper);
|
||||
aFinalIntervals(1) = anIndex1;
|
||||
|
||||
// If first and last are in the same period
|
||||
if ((Abs(theLPer - theFPer) == 0))
|
||||
{
|
||||
Standard_Integer aCurInt = 1;
|
||||
Standard_Real aCurPeriod = theFPer * thePeriod;
|
||||
|
||||
if (theFirst == aNewFirst && theLast == aNewLast)
|
||||
{
|
||||
aCurPeriod = 0;
|
||||
}
|
||||
WriteIntervals(theTK, theInter, theNbInt, anIndex1,
|
||||
anIndex2, aCurPeriod, Standard_False, theT, aFinalIntervals, theNbIntervals, aCurInt);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the first and the last are in neighboring periods
|
||||
if (Abs(theLPer - theFPer) == 1)
|
||||
{
|
||||
Standard_Integer aCurInt = 1;
|
||||
|
||||
if (Abs(theLastParam - theLower) < theEps)
|
||||
{
|
||||
WriteIntervals(theTK, theInter, theNbInt, anIndex1,
|
||||
theNb, theFPer * thePeriod, Standard_True, theT, aFinalIntervals, theNbIntervals, aCurInt);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// For period with first
|
||||
WriteIntervals(theTK, theInter, theNbInt, anIndex1,
|
||||
theNb, theFPer * thePeriod, Standard_True, theT, aFinalIntervals, theNbIntervals, aCurInt);
|
||||
// For period with last
|
||||
theNbIntervals++;
|
||||
WriteIntervals(theTK, theInter, theNbInt, 1,
|
||||
anIndex2, theLPer * thePeriod, Standard_False, theT, aFinalIntervals, theNbIntervals, aCurInt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// If the first and the last are far apart
|
||||
if (Abs(theLPer - theFPer) > 1)
|
||||
{
|
||||
Standard_Integer aCurInt = 1;
|
||||
if (Abs(theLastParam - theLower) < theEps)
|
||||
{
|
||||
WriteIntervals(theTK, theInter, theNbInt, anIndex1,
|
||||
theNb, theFPer * thePeriod, Standard_True, theT, aFinalIntervals, theNbIntervals, aCurInt);
|
||||
|
||||
Standard_Integer aNbPer = Abs(theLPer - theFPer);
|
||||
Standard_Integer aCurPer = theFPer + 1;
|
||||
|
||||
while (aNbPer > 1)
|
||||
{
|
||||
theNbIntervals++;
|
||||
WriteIntervals(theTK, theInter, theNbInt, 1,
|
||||
theNb, aCurPer * thePeriod, Standard_True, theT, aFinalIntervals, theNbIntervals, aCurInt);
|
||||
|
||||
aNbPer--;
|
||||
aCurPer++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// For period with first
|
||||
WriteIntervals(theTK, theInter, theNbInt, anIndex1,
|
||||
theNb, theFPer * thePeriod, Standard_True, theT, aFinalIntervals, theNbIntervals, aCurInt);
|
||||
|
||||
Standard_Integer aNbPer = Abs(theLPer - theFPer);
|
||||
Standard_Integer aCurPer = theFPer + 1;
|
||||
while (aNbPer > 1)
|
||||
{
|
||||
theNbIntervals++;
|
||||
WriteIntervals(theTK, theInter, theNbInt, 1,
|
||||
theNb, aCurPer * thePeriod, Standard_True, theT, aFinalIntervals, theNbIntervals, aCurInt);
|
||||
|
||||
aNbPer--;
|
||||
aCurPer++;
|
||||
}
|
||||
// For period with last
|
||||
theNbIntervals++;
|
||||
WriteIntervals(theTK, theInter, theNbInt, 1,
|
||||
anIndex2, theLPer * thePeriod, Standard_False, theT, aFinalIntervals, theNbIntervals, aCurInt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Intervals
|
||||
//purpose :
|
||||
@@ -413,7 +924,9 @@ void Geom2dAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
|
||||
Standard_Integer FirstIndex = myBSplineCurve->FirstUKnotIndex();
|
||||
Standard_Integer LastIndex = myBSplineCurve->LastUKnotIndex();
|
||||
TColStd_Array1OfInteger Inter (1, LastIndex-FirstIndex+1);
|
||||
if ( S > Continuity()) {
|
||||
Standard_Boolean aContPer = (S >= Continuity()) && myBSplineCurve->IsPeriodic();
|
||||
Standard_Boolean aContNotPer = (S > Continuity()) && !myBSplineCurve->IsPeriodic();
|
||||
if (aContPer || aContNotPer) {
|
||||
Standard_Integer Cont;
|
||||
switch ( S) {
|
||||
case GeomAbs_G1:
|
||||
@@ -427,72 +940,127 @@ void Geom2dAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
|
||||
case GeomAbs_C2:
|
||||
case GeomAbs_C3:
|
||||
case GeomAbs_CN:
|
||||
{
|
||||
if ( S == GeomAbs_C1) Cont = 1;
|
||||
else if ( S == GeomAbs_C2) Cont = 2;
|
||||
else if ( S == GeomAbs_C3) Cont = 3;
|
||||
else Cont = myBSplineCurve->Degree();
|
||||
Standard_Integer Degree = myBSplineCurve->Degree();
|
||||
Standard_Integer NbKnots = myBSplineCurve->NbKnots();
|
||||
TColStd_Array1OfInteger Mults (1, NbKnots);
|
||||
myBSplineCurve->Multiplicities (Mults);
|
||||
NbSplit = 1;
|
||||
Standard_Integer Index = FirstIndex;
|
||||
Inter (NbSplit) = Index;
|
||||
{
|
||||
if (S == GeomAbs_C1) Cont = 1;
|
||||
else if (S == GeomAbs_C2) Cont = 2;
|
||||
else if (S == GeomAbs_C3) Cont = 3;
|
||||
else Cont = myBSplineCurve->Degree();
|
||||
Standard_Integer Degree = myBSplineCurve->Degree();
|
||||
Standard_Integer NbKnots = myBSplineCurve->NbKnots();
|
||||
TColStd_Array1OfInteger Mults(1, NbKnots);
|
||||
myBSplineCurve->Multiplicities(Mults);
|
||||
NbSplit = 1;
|
||||
Standard_Integer Index = FirstIndex;
|
||||
Inter(NbSplit) = Index;
|
||||
Index++;
|
||||
NbSplit++;
|
||||
while (Index < LastIndex)
|
||||
{
|
||||
if (Degree - Mults(Index) < Cont)
|
||||
{
|
||||
Inter(NbSplit) = Index;
|
||||
NbSplit++;
|
||||
}
|
||||
Index++;
|
||||
NbSplit++;
|
||||
while (Index < LastIndex)
|
||||
{
|
||||
if (Degree - Mults (Index) < Cont)
|
||||
{
|
||||
Inter (NbSplit) = Index;
|
||||
NbSplit++;
|
||||
}
|
||||
Index++;
|
||||
}
|
||||
Inter (NbSplit) = Index;
|
||||
Standard_Integer NbInt = NbSplit-1;
|
||||
|
||||
Standard_Integer Nb = myBSplineCurve->NbKnots();
|
||||
Standard_Integer Index1 = 0;
|
||||
Standard_Integer Index2 = 0;
|
||||
Standard_Real newFirst, newLast;
|
||||
TColStd_Array1OfReal TK(1,Nb);
|
||||
TColStd_Array1OfInteger TM(1,Nb);
|
||||
myBSplineCurve->Knots(TK);
|
||||
myBSplineCurve->Multiplicities(TM);
|
||||
BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myFirst,
|
||||
myBSplineCurve->IsPeriodic(),
|
||||
1,Nb,Index1,newFirst);
|
||||
BSplCLib::LocateParameter(myBSplineCurve->Degree(),TK,TM,myLast,
|
||||
myBSplineCurve->IsPeriodic(),
|
||||
1,Nb,Index2,newLast);
|
||||
}
|
||||
Inter(NbSplit) = Index;
|
||||
Standard_Integer NbInt = NbSplit - 1;
|
||||
|
||||
Standard_Integer Nb = myBSplineCurve->NbKnots();
|
||||
Standard_Integer Index1 = 0;
|
||||
Standard_Integer Index2 = 0;
|
||||
Standard_Real newFirst, newLast;
|
||||
TColStd_Array1OfReal TK(1, Nb);
|
||||
TColStd_Array1OfInteger TM(1, Nb);
|
||||
myBSplineCurve->Knots(TK);
|
||||
myBSplineCurve->Multiplicities(TM);
|
||||
Standard_Real Eps = Min(Resolution(Precision::Confusion()),
|
||||
Precision::PConfusion());
|
||||
|
||||
if (!myBSplineCurve->IsPeriodic())
|
||||
{
|
||||
BSplCLib::LocateParameter(myBSplineCurve->Degree(), TK, TM, myFirst,
|
||||
myBSplineCurve->IsPeriodic(),
|
||||
1, Nb, Index1, newFirst);
|
||||
BSplCLib::LocateParameter(myBSplineCurve->Degree(), TK, TM, myLast,
|
||||
myBSplineCurve->IsPeriodic(),
|
||||
1, Nb, Index2, newLast);
|
||||
|
||||
|
||||
// On decale eventuellement les indices
|
||||
// On utilise une "petite" tolerance, la resolution ne doit
|
||||
// servir que pour les tres longue courbes....(PRO9248)
|
||||
Standard_Real Eps = Min(Resolution(Precision::Confusion()),
|
||||
Precision::PConfusion());
|
||||
if ( Abs(newFirst-TK(Index1+1))< Eps) Index1++;
|
||||
if ( newLast-TK(Index2)> Eps) Index2++;
|
||||
|
||||
Inter( 1) = Index1;
|
||||
myNbIntervals = 1;
|
||||
for ( Standard_Integer i=1; i<=NbInt; i++) {
|
||||
if (Inter(i) > Index1 && Inter(i)<Index2 ) {
|
||||
myNbIntervals++;
|
||||
Inter(myNbIntervals) = Inter(i);
|
||||
}
|
||||
}
|
||||
Inter(myNbIntervals+1) = Index2;
|
||||
|
||||
Standard_Integer ii = T.Lower() - 1;
|
||||
for (Standard_Integer I=1;I<=myNbIntervals+1;I++) {
|
||||
T(ii + I) = TK(Inter(I));
|
||||
}
|
||||
}
|
||||
break;
|
||||
// On decale eventuellement les indices
|
||||
// On utilise une "petite" tolerance, la resolution ne doit
|
||||
// servir que pour les tres longue courbes....(PRO9248)
|
||||
if (Abs(newFirst - TK(Index1 + 1)) < Eps) Index1++;
|
||||
if (newLast - TK(Index2) > Eps) Index2++;
|
||||
|
||||
Inter(1) = Index1;
|
||||
myNbIntervals = 1;
|
||||
for (Standard_Integer i = 1; i <= NbInt; i++) {
|
||||
if (Inter(i) > Index1 && Inter(i) < Index2) {
|
||||
myNbIntervals++;
|
||||
Inter(myNbIntervals) = Inter(i);
|
||||
}
|
||||
}
|
||||
Inter(myNbIntervals + 1) = Index2;
|
||||
|
||||
Standard_Integer ii = T.Lower() - 1;
|
||||
for (Standard_Integer I = 1; I <= myNbIntervals + 1; I++) {
|
||||
T(ii + I) = TK(Inter(I));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Standard_Real aFirst = myFirst;
|
||||
Standard_Real aLast = myLast;
|
||||
|
||||
Standard_Real aCurFirst = aFirst;
|
||||
Standard_Real aCurLast = aLast;
|
||||
|
||||
Standard_Real aPeriod = myBSplineCurve->Period();
|
||||
Standard_Real aLower = myBSplineCurve->FirstParameter();
|
||||
Standard_Real anUpper = myBSplineCurve->LastParameter();
|
||||
|
||||
Standard_Integer aLPer = 0; Standard_Integer aFPer = 0;
|
||||
|
||||
if (Abs(myFirst - aLower) <= Eps)
|
||||
{
|
||||
aCurFirst = aLower;
|
||||
aFirst = aCurFirst;
|
||||
}
|
||||
if (Abs(myLast - anUpper) <= Eps)
|
||||
{
|
||||
aCurLast = anUpper;
|
||||
aLast = aCurLast;
|
||||
}
|
||||
|
||||
if ((Abs(aLower - myFirst) < Eps) && (aCurFirst < aLower))
|
||||
{
|
||||
aCurFirst = aLower;
|
||||
}
|
||||
else
|
||||
{
|
||||
DefinFPeriod(aLower, anUpper,
|
||||
Eps, aPeriod, aCurFirst, aFPer);
|
||||
}
|
||||
DefinLPeriod(aLower, anUpper,
|
||||
Eps, aPeriod, aCurLast, aLPer);
|
||||
|
||||
if (myFirst == aLower)
|
||||
{
|
||||
aFPer = 0;
|
||||
}
|
||||
|
||||
SpreadInt(TK, TM, Inter, myBSplineCurve->Degree(), Nb, aFPer, aLPer, NbInt, aLower, myFirst, myLast, aPeriod,
|
||||
aCurLast, Eps, T, myNbIntervals);
|
||||
T(T.Lower()) = aFirst;
|
||||
T(T.Lower() + myNbIntervals) = aLast;
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
T(T.Lower()) = myFirst;
|
||||
T(T.Lower() + myNbIntervals) = myLast;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user