1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00

0024377: [Regression-like] OCC 6.7.0 beta contaminates log with more unnecessary debug symbols

These "DEBUG outputs" are replace with analogically comments.
This commit is contained in:
nbv 2013-11-19 12:06:09 +04:00 committed by bugmaster
parent 3cb19cf162
commit 28cec2ba3e
2 changed files with 382 additions and 437 deletions

View File

@ -23,19 +23,19 @@
// GetStateNumber() // GetStateNumber()
/*----------------------------------------------------------------------------- /*-----------------------------------------------------------------------------
Fonctions permettant de rechercher une distance extremale entre 2 courbes Fonctions permettant de rechercher une distance extremale entre 2 courbes
C1 et C2 (en partant de points approches C1(u0) et C2(v0)). C1 et C2 (en partant de points approches C1(u0) et C2(v0)).
Cette classe herite de math_FunctionSetWithDerivatives et est utilisee par Cette classe herite de math_FunctionSetWithDerivatives et est utilisee par
l'algorithme math_FunctionSetRoot. l'algorithme math_FunctionSetRoot.
Si on note Du et Dv, les derivees en u et v, les 2 fonctions a annuler sont: Si on note Du et Dv, les derivees en u et v, les 2 fonctions a annuler sont:
{ F1(u,v) = (C2(v)-C1(u)).Du(u)/||Du|| } { F1(u,v) = (C2(v)-C1(u)).Du(u)/||Du|| }
{ F2(u,v) = (C2(v)-C1(u)).Dv(v)||Dv|| } { F2(u,v) = (C2(v)-C1(u)).Dv(v)||Dv|| }
Si on note Duu et Dvv, les derivees secondes de C1 et C2, les derivees de F1 Si on note Duu et Dvv, les derivees secondes de C1 et C2, les derivees de F1
et F2 sont egales a: et F2 sont egales a:
{ Duf1(u,v) = -||Du|| + C1C2.Duu/||Du||- F1(u,v)*Duu*Du/||Du||**2 { Duf1(u,v) = -||Du|| + C1C2.Duu/||Du||- F1(u,v)*Duu*Du/||Du||**2
{ Dvf1(u,v) = Dv.Du/||Du|| { Dvf1(u,v) = Dv.Du/||Du||
{ Duf2(u,v) = -Du.Dv/||Dv|| { Duf2(u,v) = -Du.Dv/||Dv||
{ Dvf2(u,v) = ||Dv|| + C2C1.Dvv/||Dv||- F2(u,v)*Dv*Dvv/||Dv||**2 { Dvf2(u,v) = ||Dv|| + C2C1.Dvv/||Dv||- F2(u,v)*Dv*Dvv/||Dv||**2
----------------------------------------------------------------------------*/ ----------------------------------------------------------------------------*/
@ -52,56 +52,53 @@ static const Standard_Integer MaxOrder = 3;
//============================================================================= //=============================================================================
Standard_Real Extrema_FuncExtCC::SearchOfTolerance(const Standard_Address C) Standard_Real Extrema_FuncExtCC::SearchOfTolerance(const Standard_Address C)
{ {
const Standard_Integer NPoint = 10; const Standard_Integer NPoint = 10;
Standard_Real aStartParam, anEndParam; Standard_Real aStartParam, anEndParam;
if(C==myC1) if(C==myC1)
{ {
aStartParam = myUinfium; aStartParam = myUinfium;
anEndParam = myUsupremum; anEndParam = myUsupremum;
} }
else if(C==myC2) else if(C==myC2)
{ {
aStartParam = myVinfium; aStartParam = myVinfium;
anEndParam = myVsupremum; anEndParam = myVsupremum;
} }
else else
{ {
#ifdef DEB //Warning: No curve for tolerance computing!
cout << "+++ Function Extrema_FuncExtCC::SearchOfTolerance(...)" << endl;
cout << "Warning: No curve for tolerance computing!---"<<endl;
#endif
return MinTol; return MinTol;
} }
const Standard_Real aStep = (anEndParam - aStartParam)/(Standard_Real)NPoint; const Standard_Real aStep = (anEndParam - aStartParam)/(Standard_Real)NPoint;
Standard_Integer aNum = 0; Standard_Integer aNum = 0;
Standard_Real aMax = -Precision::Infinite(); //Maximum value of 1st derivative Standard_Real aMax = -Precision::Infinite(); //Maximum value of 1st derivative
//(it is computed with using NPoint point) //(it is computed with using NPoint point)
do do
{ {
Standard_Real u = aStartParam + aNum*aStep; //parameter for every point Standard_Real u = aStartParam + aNum*aStep; //parameter for every point
if(u > anEndParam) if(u > anEndParam)
u = anEndParam; u = anEndParam;
Pnt Ptemp; //empty point (is not used below) Pnt Ptemp; //empty point (is not used below)
Vec VDer; // 1st derivative vector Vec VDer; // 1st derivative vector
Tool1::D1(*((Curve1*)C), u, Ptemp, VDer); Tool1::D1(*((Curve1*)C), u, Ptemp, VDer);
Standard_Real vm = VDer.Magnitude(); Standard_Real vm = VDer.Magnitude();
if(vm > aMax) if(vm > aMax)
aMax = vm; aMax = vm;
}
while(++aNum < NPoint+1);
return Max(aMax*TolFactor,MinTol);
} }
while(++aNum < NPoint+1);
return Max(aMax*TolFactor,MinTol);
}
//============================================================================= //=============================================================================
Extrema_FuncExtCC::Extrema_FuncExtCC(const Standard_Real thetol) : myC1 (0), myC2 (0), myTol (thetol) Extrema_FuncExtCC::Extrema_FuncExtCC(const Standard_Real thetol) : myC1 (0), myC2 (0), myTol (thetol)
{ {
math_Vector V1(1,2), V2(1,2); math_Vector V1(1,2), V2(1,2);
V1(1) = 0.0; V1(1) = 0.0;
V2(1) = 0.0; V2(1) = 0.0;
@ -112,60 +109,60 @@ Extrema_FuncExtCC::Extrema_FuncExtCC(const Standard_Real thetol) : myC1 (0), myC
myTolC1=MinTol; myTolC1=MinTol;
myMaxDerivOrderC2 = 0; myMaxDerivOrderC2 = 0;
myTolC2=MinTol; myTolC2=MinTol;
} }
//============================================================================= //=============================================================================
Extrema_FuncExtCC::Extrema_FuncExtCC (const Curve1& C1, Extrema_FuncExtCC::Extrema_FuncExtCC (const Curve1& C1,
const Curve2& C2, const Curve2& C2,
const Standard_Real thetol) : const Standard_Real thetol) :
myC1 ((Standard_Address)&C1), myC2 ((Standard_Address)&C2), myC1 ((Standard_Address)&C1), myC2 ((Standard_Address)&C2),
myTol (thetol) myTol (thetol)
{ {
math_Vector V1(1,2), V2(1,2); math_Vector V1(1,2), V2(1,2);
V1(1) = Tool1::FirstParameter(*((Curve1*)myC1)); V1(1) = Tool1::FirstParameter(*((Curve1*)myC1));
V2(1) = Tool1::LastParameter(*((Curve1*)myC1)); V2(1) = Tool1::LastParameter(*((Curve1*)myC1));
V1(2) = Tool2::FirstParameter(*((Curve2*)myC2)); V1(2) = Tool2::FirstParameter(*((Curve2*)myC2));
V2(2) = Tool2::LastParameter(*((Curve2*)myC2)); V2(2) = Tool2::LastParameter(*((Curve2*)myC2));
SubIntervalInitialize(V1, V2); SubIntervalInitialize(V1, V2);
switch(Tool1::GetType(*((Curve1*)myC1))) switch(Tool1::GetType(*((Curve1*)myC1)))
{ {
case GeomAbs_BezierCurve: case GeomAbs_BezierCurve:
case GeomAbs_BSplineCurve: case GeomAbs_BSplineCurve:
case GeomAbs_OtherCurve: case GeomAbs_OtherCurve:
myMaxDerivOrderC1 = MaxOrder; myMaxDerivOrderC1 = MaxOrder;
myTolC1 = SearchOfTolerance((Standard_Address)&C1); myTolC1 = SearchOfTolerance((Standard_Address)&C1);
break; break;
default: default:
myMaxDerivOrderC1 = 0; myMaxDerivOrderC1 = 0;
myTolC1=MinTol; myTolC1=MinTol;
break; break;
}
switch(Tool2::GetType(*((Curve2*)myC2)))
{
case GeomAbs_BezierCurve:
case GeomAbs_BSplineCurve:
case GeomAbs_OtherCurve:
myMaxDerivOrderC2 = MaxOrder;
myTolC2 = SearchOfTolerance((Standard_Address)&C2);
break;
default:
myMaxDerivOrderC2 = 0;
myTolC2=MinTol;
break;
}
} }
switch(Tool2::GetType(*((Curve2*)myC2)))
{
case GeomAbs_BezierCurve:
case GeomAbs_BSplineCurve:
case GeomAbs_OtherCurve:
myMaxDerivOrderC2 = MaxOrder;
myTolC2 = SearchOfTolerance((Standard_Address)&C2);
break;
default:
myMaxDerivOrderC2 = 0;
myTolC2=MinTol;
break;
}
}
//============================================================================= //=============================================================================
void Extrema_FuncExtCC::SetCurve (const Standard_Integer theRank, const Curve1& C) void Extrema_FuncExtCC::SetCurve (const Standard_Integer theRank, const Curve1& C)
{ {
Standard_OutOfRange_Raise_if (theRank < 1 || theRank > 2, "Extrema_FuncExtCC::SetCurve()") Standard_OutOfRange_Raise_if (theRank < 1 || theRank > 2, "Extrema_FuncExtCC::SetCurve()")
if (theRank == 1) if (theRank == 1)
{ {
myC1 = (Standard_Address)&C; myC1 = (Standard_Address)&C;
switch(/*Tool1::GetType(*((Curve1*)myC1))*/ C.GetType()) switch(/*Tool1::GetType(*((Curve1*)myC1))*/ C.GetType())
{ {
case GeomAbs_BezierCurve: case GeomAbs_BezierCurve:
case GeomAbs_BSplineCurve: case GeomAbs_BSplineCurve:
@ -179,10 +176,10 @@ void Extrema_FuncExtCC::SetCurve (const Standard_Integer theRank, const Curve1&
break; break;
} }
} }
else if (theRank == 2) else if (theRank == 2)
{ {
myC2 = (Standard_Address)&C; myC2 = (Standard_Address)&C;
switch(/*Tool2::GetType(*((Curve2*)myC2))*/C.GetType()) switch(/*Tool2::GetType(*((Curve2*)myC2))*/C.GetType())
{ {
case GeomAbs_BezierCurve: case GeomAbs_BezierCurve:
case GeomAbs_BSplineCurve: case GeomAbs_BSplineCurve:
@ -196,11 +193,11 @@ void Extrema_FuncExtCC::SetCurve (const Standard_Integer theRank, const Curve1&
break; break;
} }
} }
} }
//============================================================================= //=============================================================================
Standard_Boolean Extrema_FuncExtCC::Value (const math_Vector& UV, math_Vector& F) Standard_Boolean Extrema_FuncExtCC::Value (const math_Vector& UV, math_Vector& F)
{ {
myU = UV(1); myU = UV(1);
myV = UV(2); myV = UV(2);
Tool1::D1(*((Curve1*)myC1), myU,myP1,myDu); Tool1::D1(*((Curve1*)myC1), myU,myP1,myDu);
@ -212,264 +209,254 @@ Standard_Boolean Extrema_FuncExtCC::Value (const math_Vector& UV, math_Vector& F
if(myMaxDerivOrderC1 != 0) if(myMaxDerivOrderC1 != 0)
{ {
if (Ndu <= myTolC1) if (Ndu <= myTolC1)
{ {
//Derivative is approximated by Taylor-series //Derivative is approximated by Taylor-series
const Standard_Real DivisionFactor = 1.e-3; const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du; Standard_Real du;
if((myUsupremum >= RealLast()) || (myUinfium <= RealFirst())) if((myUsupremum >= RealLast()) || (myUinfium <= RealFirst()))
du = 0.0; du = 0.0;
else else
du = myUsupremum-myUinfium; du = myUsupremum-myUinfium;
const Standard_Real aDelta = Max(du*DivisionFactor,MinStep); const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
Standard_Integer n = 1; //Derivative order Standard_Integer n = 1; //Derivative order
Vec V; Vec V;
Standard_Boolean IsDeriveFound; Standard_Boolean IsDeriveFound;
do do
{ {
V = Tool1::DN(*((Curve1*)myC1),myU,++n); V = Tool1::DN(*((Curve1*)myC1),myU,++n);
Ndu = V.Magnitude(); Ndu = V.Magnitude();
IsDeriveFound = (Ndu > myTolC1); IsDeriveFound = (Ndu > myTolC1);
} }
while(!IsDeriveFound && n < myMaxDerivOrderC1); while(!IsDeriveFound && n < myMaxDerivOrderC1);
if(IsDeriveFound) if(IsDeriveFound)
{ {
Standard_Real u; Standard_Real u;
if(myU-myUinfium < aDelta) if(myU-myUinfium < aDelta)
u = myU+aDelta; u = myU+aDelta;
else else
u = myU-aDelta; u = myU-aDelta;
Pnt P1, P2; Pnt P1, P2;
Tool1::D0(*((Curve1*)myC1),Min(myU, u),P1); Tool1::D0(*((Curve1*)myC1),Min(myU, u),P1);
Tool1::D0(*((Curve1*)myC1),Max(myU, u),P2); Tool1::D0(*((Curve1*)myC1),Max(myU, u),P2);
Vec V1(P1,P2); Vec V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1); Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0) if(aDirFactor < 0.0)
myDu = -V; myDu = -V;
else else
myDu = V; myDu = V;
}//if(IsDeriveFound) }//if(IsDeriveFound)
else else
{ {
//Derivative is approximated by three points //Derivative is approximated by three points
Pnt Ptemp; //(0,0,0)-coordinate Pnt Ptemp; //(0,0,0)-coordinate
Pnt P1, P2, P3; Pnt P1, P2, P3;
Standard_Boolean IsParameterGrown; Standard_Boolean IsParameterGrown;
if(myU-myUinfium < 2*aDelta) if(myU-myUinfium < 2*aDelta)
{ {
Tool1::D0(*((Curve1*)myC1),myU,P1); Tool1::D0(*((Curve1*)myC1),myU,P1);
Tool1::D0(*((Curve1*)myC1),myU+aDelta,P2); Tool1::D0(*((Curve1*)myC1),myU+aDelta,P2);
Tool1::D0(*((Curve1*)myC1),myU+2*aDelta,P3); Tool1::D0(*((Curve1*)myC1),myU+2*aDelta,P3);
IsParameterGrown = Standard_True; IsParameterGrown = Standard_True;
} }
else else
{ {
Tool1::D0(*((Curve1*)myC1),myU-2*aDelta,P1); Tool1::D0(*((Curve1*)myC1),myU-2*aDelta,P1);
Tool1::D0(*((Curve1*)myC1),myU-aDelta,P2); Tool1::D0(*((Curve1*)myC1),myU-aDelta,P2);
Tool1::D0(*((Curve1*)myC1),myU,P3); Tool1::D0(*((Curve1*)myC1),myU,P3);
IsParameterGrown = Standard_False; IsParameterGrown = Standard_False;
} }
Vec V1(Ptemp,P1), V2(Ptemp,P2), V3(Ptemp,P3); Vec V1(Ptemp,P1), V2(Ptemp,P2), V3(Ptemp,P3);
if(IsParameterGrown) if(IsParameterGrown)
myDu=-3*V1+4*V2-V3; myDu=-3*V1+4*V2-V3;
else else
myDu=V1-4*V2+3*V3; myDu=V1-4*V2+3*V3;
}//else of if(IsDeriveFound) }//else of if(IsDeriveFound)
Ndu = myDu.Magnitude(); Ndu = myDu.Magnitude();
}//if (Ndu <= myTolC1) condition }//if (Ndu <= myTolC1) condition
}//if(myMaxDerivOrder != 0) }//if(myMaxDerivOrder != 0)
if (Ndu <= MinTol) if (Ndu <= MinTol)
{ {
#ifdef DEB //Warning: 1st derivative of C1 is equal to zero!
cout << "+++Function Extrema_FuncExtCC::Value(...)." << endl;
cout << "Warning: 1st derivative of C1 is equal to zero!---"<<endl;
#endif
return Standard_False; return Standard_False;
} }
Standard_Real Ndv = myDv.Magnitude(); Standard_Real Ndv = myDv.Magnitude();
if(myMaxDerivOrderC2 != 0) if(myMaxDerivOrderC2 != 0)
{ {
if (Ndv <= myTolC2) if (Ndv <= myTolC2)
{ {
const Standard_Real DivisionFactor = 1.e-3; const Standard_Real DivisionFactor = 1.e-3;
Standard_Real dv; Standard_Real dv;
if((myVsupremum >= RealLast()) || (myVinfium <= RealFirst())) if((myVsupremum >= RealLast()) || (myVinfium <= RealFirst()))
dv = 0.0; dv = 0.0;
else else
dv = myVsupremum-myVinfium; dv = myVsupremum-myVinfium;
const Standard_Real aDelta = Max(dv*DivisionFactor,MinStep); const Standard_Real aDelta = Max(dv*DivisionFactor,MinStep);
//Derivative is approximated by Taylor-series //Derivative is approximated by Taylor-series
Standard_Integer n = 1; //Derivative order Standard_Integer n = 1; //Derivative order
Vec V; Vec V;
Standard_Boolean IsDeriveFound; Standard_Boolean IsDeriveFound;
do do
{ {
V = Tool2::DN(*((Curve2*)myC2),myV,++n); V = Tool2::DN(*((Curve2*)myC2),myV,++n);
Ndv = V.Magnitude(); Ndv = V.Magnitude();
IsDeriveFound = (Ndv > myTolC2); IsDeriveFound = (Ndv > myTolC2);
} }
while(!IsDeriveFound && n < myMaxDerivOrderC2); while(!IsDeriveFound && n < myMaxDerivOrderC2);
if(IsDeriveFound) if(IsDeriveFound)
{ {
Standard_Real v; Standard_Real v;
if(myV-myVinfium < aDelta) if(myV-myVinfium < aDelta)
v = myV+aDelta; v = myV+aDelta;
else else
v = myV-aDelta; v = myV-aDelta;
Pnt P1, P2; Pnt P1, P2;
Tool2::D0(*((Curve2*)myC2),Min(myV, v),P1); Tool2::D0(*((Curve2*)myC2),Min(myV, v),P1);
Tool2::D0(*((Curve2*)myC2),Max(myV, v),P2); Tool2::D0(*((Curve2*)myC2),Max(myV, v),P2);
Vec V1(P1,P2); Vec V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1); Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0) if(aDirFactor < 0.0)
myDv = -V; myDv = -V;
else else
myDv = V; myDv = V;
}//if(IsDeriveFound) }//if(IsDeriveFound)
else else
{ {
//Derivative is approximated by three points //Derivative is approximated by three points
Pnt Ptemp; //(0,0,0)-coordinate Pnt Ptemp; //(0,0,0)-coordinate
Pnt P1, P2, P3; Pnt P1, P2, P3;
Standard_Boolean IsParameterGrown; Standard_Boolean IsParameterGrown;
if(myV-myVinfium < 2*aDelta) if(myV-myVinfium < 2*aDelta)
{ {
Tool2::D0(*((Curve2*)myC2),myV,P1); Tool2::D0(*((Curve2*)myC2),myV,P1);
Tool2::D0(*((Curve2*)myC2),myV+aDelta,P2); Tool2::D0(*((Curve2*)myC2),myV+aDelta,P2);
Tool2::D0(*((Curve2*)myC2),myV+2*aDelta,P3); Tool2::D0(*((Curve2*)myC2),myV+2*aDelta,P3);
IsParameterGrown = Standard_True; IsParameterGrown = Standard_True;
} }
else else
{ {
Tool2::D0(*((Curve2*)myC2),myV-2*aDelta,P1); Tool2::D0(*((Curve2*)myC2),myV-2*aDelta,P1);
Tool2::D0(*((Curve2*)myC2),myV-aDelta,P2); Tool2::D0(*((Curve2*)myC2),myV-aDelta,P2);
Tool2::D0(*((Curve2*)myC2),myV,P3); Tool2::D0(*((Curve2*)myC2),myV,P3);
IsParameterGrown = Standard_False; IsParameterGrown = Standard_False;
} }
Vec V1(Ptemp,P1), V2(Ptemp,P2), V3(Ptemp,P3); Vec V1(Ptemp,P1), V2(Ptemp,P2), V3(Ptemp,P3);
if(IsParameterGrown) if(IsParameterGrown)
myDv=-3*V1+4*V2-V3; myDv=-3*V1+4*V2-V3;
else else
myDv=V1-4*V2+3*V3; myDv=V1-4*V2+3*V3;
}//else of if(IsDeriveFound) }//else of if(IsDeriveFound)
Ndv = myDv.Magnitude(); Ndv = myDv.Magnitude();
}//if (Ndv <= myTolC2) }//if (Ndv <= myTolC2)
}//if(myMaxDerivOrder != 0) }//if(myMaxDerivOrder != 0)
if (Ndv <= MinTol) if (Ndv <= MinTol)
{ {
#ifdef DEB //1st derivative of C2 is equal to zero!
cout << "+++Function Extrema_FuncExtCC::Value(...)." << endl;
cout << "1st derivative of C2 is equal to zero!---"<<endl;
#endif
return Standard_False; return Standard_False;
} }
F(1) = P1P2.Dot(myDu)/Ndu; F(1) = P1P2.Dot(myDu)/Ndu;
F(2) = P1P2.Dot(myDv)/Ndv; F(2) = P1P2.Dot(myDv)/Ndv;
return Standard_True; return Standard_True;
} }
//============================================================================= //=============================================================================
Standard_Boolean Extrema_FuncExtCC::Derivatives (const math_Vector& UV, Standard_Boolean Extrema_FuncExtCC::Derivatives (const math_Vector& UV,
math_Matrix& Df) math_Matrix& Df)
{ {
math_Vector F(1,2); math_Vector F(1,2);
return Values(UV,F,Df); return Values(UV,F,Df);
} }
//============================================================================= //=============================================================================
Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV, Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV,
math_Vector& F, math_Vector& F,
math_Matrix& Df) math_Matrix& Df)
{ {
myU = UV(1); myU = UV(1);
myV = UV(2); myV = UV(2);
if(Value(UV, F) == Standard_False) //Computes F, myDu, myDv if(Value(UV, F) == Standard_False) //Computes F, myDu, myDv
{ {
#ifdef DEB //Warning: No function value found!
cout << "+++Standard_Boolean Extrema_FuncExtCC::Values(...)." << endl;
cout << "Warning: No function value found!---"<<endl;
#endif
return Standard_False; return Standard_False;
}//if(Value(UV, F) == Standard_False) }//if(Value(UV, F) == Standard_False)
Vec Du, Dv, Duu, Dvv; Vec Du, Dv, Duu, Dvv;
Tool1::D2(*((Curve1*)myC1), myU,myP1,Du,Duu); Tool1::D2(*((Curve1*)myC1), myU,myP1,Du,Duu);
Tool2::D2(*((Curve2*)myC2), myV,myP2,Dv,Dvv); Tool2::D2(*((Curve2*)myC2), myV,myP2,Dv,Dvv);
//Calling of "Value(...)" function change class member values. //Calling of "Value(...)" function change class member values.
//After running it is necessary to return to previous values. //After running it is necessary to return to previous values.
const Standard_Real myU_old = myU, myV_old = myV; const Standard_Real myU_old = myU, myV_old = myV;
const Pnt myP1_old = myP1, myP2_old = myP2; const Pnt myP1_old = myP1, myP2_old = myP2;
const Vec myDu_old = myDu, myDv_old = myDv; const Vec myDu_old = myDu, myDv_old = myDv;
//Attention: aDelta value must be greater than same value for "Value(...)"
// function to avoid of points' collisions. //Attention: aDelta value must be greater than same value for "Value(...)"
// function to avoid of points' collisions.
const Standard_Real DivisionFactor = 0.01; const Standard_Real DivisionFactor = 0.01;
Standard_Real du; Standard_Real du;
if((myUsupremum >= RealLast()) || (myUinfium <= RealFirst())) if((myUsupremum >= RealLast()) || (myUinfium <= RealFirst()))
du = 0.0; du = 0.0;
else else
du = myUsupremum-myUinfium; du = myUsupremum-myUinfium;
const Standard_Real aDeltaU = Max(du*DivisionFactor,MinStep); const Standard_Real aDeltaU = Max(du*DivisionFactor,MinStep);
Standard_Real dv; Standard_Real dv;
if((myVsupremum >= RealLast()) || (myVinfium <= RealFirst())) if((myVsupremum >= RealLast()) || (myVinfium <= RealFirst()))
dv = 0.0; dv = 0.0;
else else
dv = myVsupremum-myVinfium; dv = myVsupremum-myVinfium;
const Standard_Real aDeltaV = Max(dv*DivisionFactor,MinStep); const Standard_Real aDeltaV = Max(dv*DivisionFactor,MinStep);
Vec P1P2 (myP1,myP2); Vec P1P2 (myP1,myP2);
if((myMaxDerivOrderC1 != 0) && (Du.Magnitude() <= myTolC1)) if((myMaxDerivOrderC1 != 0) && (Du.Magnitude() <= myTolC1))
{ {
//Derivative is approximated by three points //Derivative is approximated by three points
math_Vector FF1(1,2), FF2(1,2), FF3(1,2); math_Vector FF1(1,2), FF2(1,2), FF3(1,2);
Standard_Real F1, F2, F3; Standard_Real F1, F2, F3;
/////////////////////////// Search of DF1_u derivative (begin) /////////////////// /////////////////////////// Search of DF1_u derivative (begin) ///////////////////
if(myU-myUinfium < 2*aDeltaU) if(myU-myUinfium < 2*aDeltaU)
{ {
F1=F(1); F1=F(1);
math_Vector UV2(1,2), UV3(1,2); math_Vector UV2(1,2), UV3(1,2);
UV2(1)=myU+aDeltaU; UV2(1)=myU+aDeltaU;
@ -477,23 +464,19 @@ Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV,
UV3(1)=myU+2*aDeltaU; UV3(1)=myU+2*aDeltaU;
UV3(2)=myV; UV3(2)=myV;
if(!((Value(UV2,FF2)) && (Value(UV3,FF3)))) if(!((Value(UV2,FF2)) && (Value(UV3,FF3))))
{ {
#ifdef DEB //There are many points close to singularity points and which have zero-derivative.
cout << "+++ Function Extrema_FuncExtCC::Values(...)" << endl; //Try to decrease aDelta variable's value.
cout << "There are many points close to singularity points "
"and which have zero-derivative." << endl;
cout << "Try to decrease aDelta variable's value. ---" << endl;
#endif
return Standard_False; return Standard_False;
} }
F2 = FF2(1); F2 = FF2(1);
F3 = FF3(1); F3 = FF3(1);
Df(1,1) = (-3*F1+4*F2-F3)/(2.0*aDeltaU); Df(1,1) = (-3*F1+4*F2-F3)/(2.0*aDeltaU);
}//if(myU-myUinfium < 2*aDeltaU) }//if(myU-myUinfium < 2*aDeltaU)
else else
{ {
F3 = F(1); F3 = F(1);
math_Vector UV2(1,2), UV1(1,2); math_Vector UV2(1,2), UV1(1,2);
UV2(1)=myU-aDeltaU; UV2(1)=myU-aDeltaU;
@ -502,30 +485,26 @@ Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV,
UV1(2)=myV; UV1(2)=myV;
if(!((Value(UV2,FF2)) && (Value(UV1,FF1)))) if(!((Value(UV2,FF2)) && (Value(UV1,FF1))))
{ {
#ifdef DEB //There are many points close to singularity points and which have zero-derivative.
cout << "+++ Function Extrema_FuncExtCC::Values(...)" << endl; //Try to decrease aDelta variable's value.
cout << "There are many points close to singularity points "
"and which have zero-derivative." << endl;
cout << "Try to decrease aDelta variable's value. ---" << endl;
#endif
return Standard_False; return Standard_False;
} }
F1 = FF1(1); F1 = FF1(1);
F2 = FF2(1); F2 = FF2(1);
Df(1,1) = (F1-4*F2+3*F3)/(2.0*aDeltaU); Df(1,1) = (F1-4*F2+3*F3)/(2.0*aDeltaU);
}//else of if(myU-myUinfium < 2*aDeltaU) condition }//else of if(myU-myUinfium < 2*aDeltaU) condition
/////////////////////////// Search of DF1_u derivative (end) /////////////////// /////////////////////////// Search of DF1_u derivative (end) ///////////////////
//Return to previous values
myU = myU_old;
myV = myV_old;
/////////////////////////// Search of DF1_v derivative (begin) /////////////////// //Return to previous values
myU = myU_old;
myV = myV_old;
/////////////////////////// Search of DF1_v derivative (begin) ///////////////////
if(myV-myVinfium < 2*aDeltaV) if(myV-myVinfium < 2*aDeltaV)
{ {
F1=F(1); F1=F(1);
math_Vector UV2(1,2), UV3(1,2); math_Vector UV2(1,2), UV3(1,2);
UV2(1)=myU; UV2(1)=myU;
@ -534,22 +513,18 @@ Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV,
UV3(2)=myV+2*aDeltaV; UV3(2)=myV+2*aDeltaV;
if(!((Value(UV2,FF2)) && (Value(UV3,FF3)))) if(!((Value(UV2,FF2)) && (Value(UV3,FF3))))
{ {
#ifdef DEB //There are many points close to singularity points and which have zero-derivative.
cout << "+++ Function Extrema_FuncExtCC::Values(...)" << endl; //Try to decrease aDelta variable's value.
cout << "There are many points close to singularity points "
"and which have zero-derivative." << endl;
cout << "Try to decrease aDelta variable's value. ---" << endl;
#endif
return Standard_False; return Standard_False;
} }
F2 = FF2(1); F2 = FF2(1);
F3 = FF3(1); F3 = FF3(1);
Df(1,2) = (-3*F1+4*F2-F3)/(2.0*aDeltaV); Df(1,2) = (-3*F1+4*F2-F3)/(2.0*aDeltaV);
}//if(myV-myVinfium < 2*aDeltaV) }//if(myV-myVinfium < 2*aDeltaV)
else else
{ {
F3 = F(1); F3 = F(1);
math_Vector UV2(1,2), UV1(1,2); math_Vector UV2(1,2), UV1(1,2);
UV2(1)=myU; UV2(1)=myU;
@ -557,46 +532,42 @@ Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV,
UV1(1)=myU; UV1(1)=myU;
UV1(2)=myV-2*aDeltaV; UV1(2)=myV-2*aDeltaV;
if(!((Value(UV2,FF2)) && (Value(UV1,FF1)))) if(!((Value(UV2,FF2)) && (Value(UV1,FF1))))
{ {
#ifdef DEB //There are many points close to singularity points and which have zero-derivative.
cout << "+++ Function Extrema_FuncExtCC::Values(...)" << endl; //Try to decrease aDelta variable's value.
cout << "There are many points close to singularity points "
"and which have zero-derivative." << endl;
cout << "Try to decrease aDelta variable's value. ---" << endl;
#endif
return Standard_False; return Standard_False;
} }
F1 = FF1(1); F1 = FF1(1);
F2 = FF2(1); F2 = FF2(1);
Df(1,2) = (F1-4*F2+3*F3)/(2.0*aDeltaV); Df(1,2) = (F1-4*F2+3*F3)/(2.0*aDeltaV);
}//else of if(myV-myVinfium < 2*aDeltaV) }//else of if(myV-myVinfium < 2*aDeltaV)
/////////////////////////// Search of DF1_v derivative (end) /////////////////// /////////////////////////// Search of DF1_v derivative (end) ///////////////////
//Return to previous values //Return to previous values
myU = myU_old; myU = myU_old;
myV = myV_old; myV = myV_old;
myP1 = myP1_old, myP2 = myP2_old; myP1 = myP1_old, myP2 = myP2_old;
myDu = myDu_old, myDv = myDv_old; myDu = myDu_old, myDv = myDv_old;
}//if((myMaxDerivOrderC1 != 0) && (Du.Magnitude() <= myTolC1)) }//if((myMaxDerivOrderC1 != 0) && (Du.Magnitude() <= myTolC1))
else else
{ {
const Standard_Real Ndu = myDu.Magnitude(); const Standard_Real Ndu = myDu.Magnitude();
Df(1,1) = - Ndu + (P1P2.Dot(Duu)/Ndu) - F(1)*(myDu.Dot(Duu)/(Ndu*Ndu)); Df(1,1) = - Ndu + (P1P2.Dot(Duu)/Ndu) - F(1)*(myDu.Dot(Duu)/(Ndu*Ndu));
Df(1,2) = myDv.Dot(myDu)/Ndu; Df(1,2) = myDv.Dot(myDu)/Ndu;
}//else of if((myMaxDerivOrderC1 != 0) && (Du.Magnitude() <= myTolC1)) }//else of if((myMaxDerivOrderC1 != 0) && (Du.Magnitude() <= myTolC1))
if((myMaxDerivOrderC2 != 0) && (Dv.Magnitude() <= myTolC2)) if((myMaxDerivOrderC2 != 0) && (Dv.Magnitude() <= myTolC2))
{ {
//Derivative is approximated by three points //Derivative is approximated by three points
math_Vector FF1(1,2), FF2(1,2), FF3(1,2); math_Vector FF1(1,2), FF2(1,2), FF3(1,2);
Standard_Real F1, F2, F3; Standard_Real F1, F2, F3;
/////////////////////////// Search of DF2_v derivative (begin) /////////////////// /////////////////////////// Search of DF2_v derivative (begin) ///////////////////
if(myV-myVinfium < 2*aDeltaV) if(myV-myVinfium < 2*aDeltaV)
{ {
F1=F(2); F1=F(2);
math_Vector UV2(1,2), UV3(1,2); math_Vector UV2(1,2), UV3(1,2);
UV2(1)=myU; UV2(1)=myU;
@ -605,24 +576,20 @@ Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV,
UV3(2)=myV+2*aDeltaV; UV3(2)=myV+2*aDeltaV;
if(!((Value(UV2,FF2)) && (Value(UV3,FF3)))) if(!((Value(UV2,FF2)) && (Value(UV3,FF3))))
{ {
#ifdef DEB //There are many points close to singularity points and which have zero-derivative.
cout << "+++ Function Extrema_FuncExtCC::Values(...)" << endl; //Try to decrease aDelta variable's value.
cout << "There are many points close to singularity points "
"and which have zero-derivative." << endl;
cout << "Try to decrease aDelta variable's value. ---" << endl;
#endif
return Standard_False; return Standard_False;
} }
F2 = FF2(2); F2 = FF2(2);
F3 = FF3(2); F3 = FF3(2);
Df(2,2) = (-3*F1+4*F2-F3)/(2.0*aDeltaV); Df(2,2) = (-3*F1+4*F2-F3)/(2.0*aDeltaV);
}//if(myV-myVinfium < 2*aDeltaV) }//if(myV-myVinfium < 2*aDeltaV)
else else
{ {
F3 = F(2); F3 = F(2);
math_Vector UV2(1,2), UV1(1,2); math_Vector UV2(1,2), UV1(1,2);
UV2(1)=myU; UV2(1)=myU;
@ -631,30 +598,26 @@ Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV,
UV1(2)=myV-2*aDeltaV; UV1(2)=myV-2*aDeltaV;
if(!((Value(UV2,FF2)) && (Value(UV1,FF1)))) if(!((Value(UV2,FF2)) && (Value(UV1,FF1))))
{ {
#ifdef DEB //There are many points close to singularity points and which have zero-derivative.
cout << "+++ Function Extrema_FuncExtCC::Values(...)" << endl; //Try to decrease aDelta variable's value.
cout << "There are many points close to singularity points "
"and which have zero-derivative." << endl;
cout << "Try to decrease aDelta variable's value. ---" << endl;
#endif
return Standard_False; return Standard_False;
} }
F1 = FF1(2); F1 = FF1(2);
F2 = FF2(2); F2 = FF2(2);
Df(2,2) = (F1-4*F2+3*F3)/(2.0*aDeltaV); Df(2,2) = (F1-4*F2+3*F3)/(2.0*aDeltaV);
}//else of if(myV-myVinfium < 2*aDeltaV) }//else of if(myV-myVinfium < 2*aDeltaV)
/////////////////////////// Search of DF2_v derivative (end) /////////////////// /////////////////////////// Search of DF2_v derivative (end) ///////////////////
//Return to previous values //Return to previous values
myU = myU_old; myU = myU_old;
myV = myV_old; myV = myV_old;
/////////////////////////// Search of DF2_u derivative (begin) /////////////////// /////////////////////////// Search of DF2_u derivative (begin) ///////////////////
if(myU-myUinfium < 2*aDeltaU) if(myU-myUinfium < 2*aDeltaU)
{ {
F1=F(2); F1=F(2);
math_Vector UV2(1,2), UV3(1,2); math_Vector UV2(1,2), UV3(1,2);
UV2(1)=myU+aDeltaU; UV2(1)=myU+aDeltaU;
@ -662,48 +625,41 @@ Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV,
UV3(1)=myU+2*aDeltaU; UV3(1)=myU+2*aDeltaU;
UV3(2)=myV; UV3(2)=myV;
if(!((Value(UV2,FF2)) && (Value(UV3,FF3)))) if(!((Value(UV2,FF2)) && (Value(UV3,FF3))))
{ {
#ifdef DEB //There are many points close to singularity points and which have zero-derivative.
cout << "+++ Function Extrema_FuncExtCC::Values(...)" << endl; //Try to decrease aDelta variable's value.
cout << "There are many points close to singularity points "
"and which have zero-derivative." << endl;
cout << "Try to decrease aDelta variable's value. ---" << endl;
#endif
return Standard_False; return Standard_False;
} }
F2 = FF2(2); F2 = FF2(2);
F3 = FF3(2); F3 = FF3(2);
Df(2,1) = (-3*F1+4*F2-F3)/(2.0*aDeltaU); Df(2,1) = (-3*F1+4*F2-F3)/(2.0*aDeltaU);
}//if(myU-myUinfium < 2*aDelta) }//if(myU-myUinfium < 2*aDelta)
else else
{ {
F3 = F(2); F3 = F(2);
math_Vector UV2(1,2), UV1(1,2); math_Vector UV2(1,2), UV1(1,2);
UV2(1)=myU-aDeltaU; UV2(1)=myU-aDeltaU;
UV2(2)=myV; UV2(2)=myV;
UV1(1)=myU-2*aDeltaU; UV1(1)=myU-2*aDeltaU;
UV1(2)=myV; UV1(2)=myV;
if(!((Value(UV2,FF2)) && (Value(UV1,FF1)))) if(!((Value(UV2,FF2)) && (Value(UV1,FF1))))
{ {
#ifdef DEB //There are many points close to singularity points
cout << "+++ Function Extrema_FuncExtCC::Values(...)" << endl; //and which have zero-derivative.
cout << "There are many points close to singularity points " //Try to decrease aDelta variable's value.
"and which have zero-derivative." << endl;
cout << "Try to decrease aDelta variable's value. ---" << endl;
#endif
return Standard_False; return Standard_False;
} }
F1 = FF1(2); F1 = FF1(2);
F2 = FF2(2); F2 = FF2(2);
Df(2,1) = (F1-4*F2+3*F3)/(2.0*aDeltaU); Df(2,1) = (F1-4*F2+3*F3)/(2.0*aDeltaU);
}//else of if(myU-myUinfium < 2*aDeltaU) }//else of if(myU-myUinfium < 2*aDeltaU)
/////////////////////////// Search of DF2_u derivative (end) /////////////////// /////////////////////////// Search of DF2_u derivative (end) ///////////////////
//Return to previous values //Return to previous values
myU = myU_old; myU = myU_old;
myV = myV_old; myV = myV_old;
@ -711,17 +667,17 @@ Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV,
myP2 = myP2_old; myP2 = myP2_old;
myDu = myDu_old; myDu = myDu_old;
myDv = myDv_old; myDv = myDv_old;
}//if((myMaxDerivOrderC2 != 0) && (Dv.Magnitude() <= myTolC2)) }//if((myMaxDerivOrderC2 != 0) && (Dv.Magnitude() <= myTolC2))
else else
{ {
Standard_Real Ndv = myDv.Magnitude(); Standard_Real Ndv = myDv.Magnitude();
Df(2,2) = Ndv + (P1P2.Dot(Dvv)/Ndv) - F(2)*(myDv.Dot(Dvv)/(Ndv*Ndv)); Df(2,2) = Ndv + (P1P2.Dot(Dvv)/Ndv) - F(2)*(myDv.Dot(Dvv)/(Ndv*Ndv));
Df(2,1) = -myDu.Dot(myDv)/Ndv; Df(2,1) = -myDu.Dot(myDv)/Ndv;
}//else of if((myMaxDerivOrderC2 != 0) && (Dv.Magnitude() <= myTolC2)) }//else of if((myMaxDerivOrderC2 != 0) && (Dv.Magnitude() <= myTolC2))
return Standard_True; return Standard_True;
}//end of function }//end of function
//============================================================================= //=============================================================================
Standard_Integer Extrema_FuncExtCC::GetStateNumber () Standard_Integer Extrema_FuncExtCC::GetStateNumber ()
@ -748,8 +704,8 @@ Standard_Integer Extrema_FuncExtCC::GetStateNumber ()
//============================================================================= //=============================================================================
void Extrema_FuncExtCC::Points (const Standard_Integer N, void Extrema_FuncExtCC::Points (const Standard_Integer N,
POnC& P1, POnC& P1,
POnC& P2) const POnC& P2) const
{ {
P1 = myPoints.Value(2*N-1); P1 = myPoints.Value(2*N-1);
P2 = myPoints.Value(2*N); P2 = myPoints.Value(2*N);
@ -758,10 +714,10 @@ void Extrema_FuncExtCC::Points (const Standard_Integer N,
void Extrema_FuncExtCC::SubIntervalInitialize(const math_Vector& theInfBound, void Extrema_FuncExtCC::SubIntervalInitialize(const math_Vector& theInfBound,
const math_Vector& theSupBound) const math_Vector& theSupBound)
{ {
myUinfium = theInfBound(1); myUinfium = theInfBound(1);
myUsupremum = theSupBound(1); myUsupremum = theSupBound(1);
myVinfium = theInfBound(2); myVinfium = theInfBound(2);
myVsupremum = theSupBound(2); myVsupremum = theSupBound(2);
} }
//============================================================================= //=============================================================================

View File

@ -27,47 +27,47 @@ static const Standard_Integer MaxOrder = 3;
/*----------------------------------------------------------------------------- /*-----------------------------------------------------------------------------
Fonction permettant de rechercher une distance extremale entre un point P et Fonction permettant de rechercher une distance extremale entre un point P et
une courbe C (en partant d'un point approche C(u0)). une courbe C (en partant d'un point approche C(u0)).
Cette classe herite de math_FunctionWithDerivative et est utilisee par Cette classe herite de math_FunctionWithDerivative et est utilisee par
les algorithmes math_FunctionRoot et math_FunctionRoots. les algorithmes math_FunctionRoot et math_FunctionRoots.
Si on note D1c et D2c les derivees premiere et seconde: Si on note D1c et D2c les derivees premiere et seconde:
{ F(u) = (C(u)-P).D1c(u)/ ||Du||} { F(u) = (C(u)-P).D1c(u)/ ||Du||}
{ DF(u) = ||Du|| + (C(u)-P).D2c(u)/||Du|| - F(u)*Duu*Du/||Du||**2 { DF(u) = ||Du|| + (C(u)-P).D2c(u)/||Du|| - F(u)*Duu*Du/||Du||**2
{ F(u) = (C(u)-P).D1c(u) } { F(u) = (C(u)-P).D1c(u) }
{ DF(u) = D1c(u).D1c(u) + (C(u)-P).D2c(u) { DF(u) = D1c(u).D1c(u) + (C(u)-P).D2c(u)
= ||D1c(u)|| ** 2 + (C(u)-P).D2c(u) } = ||D1c(u)|| ** 2 + (C(u)-P).D2c(u) }
----------------------------------------------------------------------------*/ ----------------------------------------------------------------------------*/
Standard_Real Extrema_FuncExtPC::SearchOfTolerance() Standard_Real Extrema_FuncExtPC::SearchOfTolerance()
{ {
const Standard_Integer NPoint = 10; const Standard_Integer NPoint = 10;
const Standard_Real aStep = (myUsupremum - myUinfium)/(Standard_Real)NPoint; const Standard_Real aStep = (myUsupremum - myUinfium)/(Standard_Real)NPoint;
Standard_Integer aNum = 0; Standard_Integer aNum = 0;
Standard_Real aMax = -Precision::Infinite(); //Maximum value of 1st derivative Standard_Real aMax = -Precision::Infinite(); //Maximum value of 1st derivative
//(it is computed with using NPoint point) //(it is computed with using NPoint point)
do do
{ {
Standard_Real u = myUinfium + aNum*aStep; //parameter for every point Standard_Real u = myUinfium + aNum*aStep; //parameter for every point
if(u > myUsupremum) if(u > myUsupremum)
u = myUsupremum; u = myUsupremum;
Pnt Ptemp; //empty point (is not used below) Pnt Ptemp; //empty point (is not used below)
Vec VDer; // 1st derivative vector Vec VDer; // 1st derivative vector
Tool::D1(*((Curve*)myC), u, Ptemp, VDer); Tool::D1(*((Curve*)myC), u, Ptemp, VDer);
Standard_Real vm = VDer.Magnitude(); Standard_Real vm = VDer.Magnitude();
if(vm > aMax) if(vm > aMax)
aMax = vm; aMax = vm;
}
while(++aNum < NPoint+1);
return Max(aMax*TolFactor,MinTol);
} }
while(++aNum < NPoint+1);
return Max(aMax*TolFactor,MinTol);
}
//============================================================================= //=============================================================================
@ -78,7 +78,7 @@ myD1f(0.)
myPinit = Standard_False; myPinit = Standard_False;
myCinit = Standard_False; myCinit = Standard_False;
myD1Init = Standard_False; myD1Init = Standard_False;
SubIntervalInitialize(0.0,0.0); SubIntervalInitialize(0.0,0.0);
myMaxDerivOrder = 0; myMaxDerivOrder = 0;
myTol=MinTol; myTol=MinTol;
@ -87,58 +87,58 @@ myD1f(0.)
//============================================================================= //=============================================================================
Extrema_FuncExtPC::Extrema_FuncExtPC (const Pnt& P, Extrema_FuncExtPC::Extrema_FuncExtPC (const Pnt& P,
const Curve& C): myU(0.), myD1f(0.) const Curve& C): myU(0.), myD1f(0.)
{ {
myP = P; myP = P;
myC = (Standard_Address)&C; myC = (Standard_Address)&C;
myPinit = Standard_True; myPinit = Standard_True;
myCinit = Standard_True; myCinit = Standard_True;
myD1Init = Standard_False; myD1Init = Standard_False;
SubIntervalInitialize(Tool::FirstParameter(*((Curve*)myC)), SubIntervalInitialize(Tool::FirstParameter(*((Curve*)myC)),
Tool::LastParameter(*((Curve*)myC))); Tool::LastParameter(*((Curve*)myC)));
switch(Tool::GetType(*((Curve*)myC))) switch(Tool::GetType(*((Curve*)myC)))
{ {
case GeomAbs_BezierCurve: case GeomAbs_BezierCurve:
case GeomAbs_BSplineCurve: case GeomAbs_BSplineCurve:
case GeomAbs_OtherCurve: case GeomAbs_OtherCurve:
myMaxDerivOrder = MaxOrder; myMaxDerivOrder = MaxOrder;
myTol = SearchOfTolerance(); myTol = SearchOfTolerance();
break; break;
default: default:
myMaxDerivOrder = 0; myMaxDerivOrder = 0;
myTol=MinTol; myTol=MinTol;
break; break;
}
} }
}
//============================================================================= //=============================================================================
void Extrema_FuncExtPC::Initialize(const Curve& C) void Extrema_FuncExtPC::Initialize(const Curve& C)
{ {
myC = (Standard_Address)&C; myC = (Standard_Address)&C;
myCinit = Standard_True; myCinit = Standard_True;
myPoint.Clear(); myPoint.Clear();
mySqDist.Clear(); mySqDist.Clear();
myIsMin.Clear(); myIsMin.Clear();
SubIntervalInitialize(Tool::FirstParameter(*((Curve*)myC)), SubIntervalInitialize(Tool::FirstParameter(*((Curve*)myC)),
Tool::LastParameter(*((Curve*)myC))); Tool::LastParameter(*((Curve*)myC)));
switch(Tool::GetType(*((Curve*)myC))) switch(Tool::GetType(*((Curve*)myC)))
{ {
case GeomAbs_BezierCurve: case GeomAbs_BezierCurve:
case GeomAbs_BSplineCurve: case GeomAbs_BSplineCurve:
case GeomAbs_OtherCurve: case GeomAbs_OtherCurve:
myMaxDerivOrder = MaxOrder; myMaxDerivOrder = MaxOrder;
myTol = SearchOfTolerance(); myTol = SearchOfTolerance();
break; break;
default: default:
myMaxDerivOrder = 0; myMaxDerivOrder = 0;
myTol=MinTol; myTol=MinTol;
break; break;
}
} }
}
//============================================================================= //=============================================================================
@ -158,102 +158,99 @@ Standard_Boolean Extrema_FuncExtPC::Value (const Standard_Real U, Standard_Real&
{ {
if (!myPinit || !myCinit) if (!myPinit || !myCinit)
Standard_TypeMismatch::Raise("No init"); Standard_TypeMismatch::Raise("No init");
myU = U; myU = U;
Vec D1c; Vec D1c;
Tool::D1(*((Curve*)myC),myU,myPc,D1c); Tool::D1(*((Curve*)myC),myU,myPc,D1c);
Standard_Real Ndu = D1c.Magnitude(); Standard_Real Ndu = D1c.Magnitude();
if(myMaxDerivOrder != 0) if(myMaxDerivOrder != 0)
{ {
if (Ndu <= myTol) // Cas Singulier (PMN 22/04/1998) if (Ndu <= myTol) // Cas Singulier (PMN 22/04/1998)
{ {
const Standard_Real DivisionFactor = 1.e-3; const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du; Standard_Real du;
if((myUsupremum >= RealLast()) || (myUinfium <= RealFirst())) if((myUsupremum >= RealLast()) || (myUinfium <= RealFirst()))
du = 0.0; du = 0.0;
else else
du = myUsupremum-myUinfium; du = myUsupremum-myUinfium;
const Standard_Real aDelta = Max(du*DivisionFactor,MinStep); const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
//Derivative is approximated by Taylor-series //Derivative is approximated by Taylor-series
Standard_Integer n = 1; //Derivative order Standard_Integer n = 1; //Derivative order
Vec V; Vec V;
Standard_Boolean IsDeriveFound; Standard_Boolean IsDeriveFound;
do do
{ {
V = Tool::DN(*((Curve*)myC),myU,++n); V = Tool::DN(*((Curve*)myC),myU,++n);
Ndu = V.Magnitude(); Ndu = V.Magnitude();
IsDeriveFound = (Ndu > myTol); IsDeriveFound = (Ndu > myTol);
} }
while(!IsDeriveFound && n < myMaxDerivOrder); while(!IsDeriveFound && n < myMaxDerivOrder);
if(IsDeriveFound) if(IsDeriveFound)
{ {
Standard_Real u; Standard_Real u;
if(myU-myUinfium < aDelta) if(myU-myUinfium < aDelta)
u = myU+aDelta; u = myU+aDelta;
else else
u = myU-aDelta; u = myU-aDelta;
Pnt P1, P2; Pnt P1, P2;
Tool::D0(*((Curve*)myC),Min(myU, u),P1); Tool::D0(*((Curve*)myC),Min(myU, u),P1);
Tool::D0(*((Curve*)myC),Max(myU, u),P2); Tool::D0(*((Curve*)myC),Max(myU, u),P2);
Vec V1(P1,P2); Vec V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1); Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0) if(aDirFactor < 0.0)
D1c = -V; D1c = -V;
else else
D1c = V; D1c = V;
}//if(IsDeriveFound) }//if(IsDeriveFound)
else else
{ {
//Derivative is approximated by three points //Derivative is approximated by three points
Pnt Ptemp; //(0,0,0)-coordinate Pnt Ptemp; //(0,0,0)-coordinate
Pnt P1, P2, P3; Pnt P1, P2, P3;
Standard_Boolean IsParameterGrown; Standard_Boolean IsParameterGrown;
if(myU-myUinfium < 2*aDelta) if(myU-myUinfium < 2*aDelta)
{ {
Tool::D0(*((Curve*)myC),myU,P1); Tool::D0(*((Curve*)myC),myU,P1);
Tool::D0(*((Curve*)myC),myU+aDelta,P2); Tool::D0(*((Curve*)myC),myU+aDelta,P2);
Tool::D0(*((Curve*)myC),myU+2*aDelta,P3); Tool::D0(*((Curve*)myC),myU+2*aDelta,P3);
IsParameterGrown = Standard_True; IsParameterGrown = Standard_True;
} }
else else
{ {
Tool::D0(*((Curve*)myC),myU-2*aDelta,P1); Tool::D0(*((Curve*)myC),myU-2*aDelta,P1);
Tool::D0(*((Curve*)myC),myU-aDelta,P2); Tool::D0(*((Curve*)myC),myU-aDelta,P2);
Tool::D0(*((Curve*)myC),myU,P3); Tool::D0(*((Curve*)myC),myU,P3);
IsParameterGrown = Standard_False; IsParameterGrown = Standard_False;
} }
Vec V1(Ptemp,P1), V2(Ptemp,P2), V3(Ptemp,P3); Vec V1(Ptemp,P1), V2(Ptemp,P2), V3(Ptemp,P3);
if(IsParameterGrown) if(IsParameterGrown)
D1c=-3*V1+4*V2-V3; D1c=-3*V1+4*V2-V3;
else else
D1c=V1-4*V2+3*V3; D1c=V1-4*V2+3*V3;
} }
Ndu = D1c.Magnitude(); Ndu = D1c.Magnitude();
}//(if (Ndu <= myTol)) condition }//(if (Ndu <= myTol)) condition
}//if(myMaxDerivOrder != 0) }//if(myMaxDerivOrder != 0)
if (Ndu <= MinTol) if (Ndu <= MinTol)
{ {
#ifdef DEB //Warning: 1st derivative is equal to zero!
cout << "+++Function Extrema_FuncExtPC::Value(...)." << endl;
cout << "Warning: 1st derivative is equal to zero!---"<<endl;
#endif
return Standard_False; return Standard_False;
} }
Vec PPc (myP,myPc); Vec PPc (myP,myPc);
F = PPc.Dot(D1c)/Ndu; F = PPc.Dot(D1c)/Ndu;
return Standard_True; return Standard_True;
@ -266,113 +263,105 @@ Standard_Boolean Extrema_FuncExtPC::Derivative (const Standard_Real U, Standard_
if (!myPinit || !myCinit) Standard_TypeMismatch::Raise(); if (!myPinit || !myCinit) Standard_TypeMismatch::Raise();
Standard_Real F; Standard_Real F;
return Values(U,F,D1f); /* on fait appel a Values pour simplifier la return Values(U,F,D1f); /* on fait appel a Values pour simplifier la
sauvegarde de l'etat. */ sauvegarde de l'etat. */
} }
//============================================================================= //=============================================================================
Standard_Boolean Extrema_FuncExtPC::Values (const Standard_Real U, Standard_Real& F, Standard_Real& D1f) Standard_Boolean Extrema_FuncExtPC::Values (const Standard_Real U,
{ Standard_Real& F,
Standard_Real& D1f)
{
if (!myPinit || !myCinit) if (!myPinit || !myCinit)
Standard_TypeMismatch::Raise("No init"); Standard_TypeMismatch::Raise("No init");
Pnt myPc_old = myPc, myP_old = myP; Pnt myPc_old = myPc, myP_old = myP;
if(Value(U,F) == Standard_False) if(Value(U,F) == Standard_False)
{ {
#ifdef DEB //Warning: No function value found!;
cout << "+++Function Extrema_FuncExtPC::Values(...)." << endl;
cout << "Warning: No function value found!---"<<endl;
#endif
myD1Init = Standard_False; myD1Init = Standard_False;
return Standard_False; return Standard_False;
} }
myU = U; myU = U;
myPc = myPc_old; myPc = myPc_old;
myP = myP_old; myP = myP_old;
Vec D1c,D2c; Vec D1c,D2c;
Tool::D2(*((Curve*)myC),myU,myPc,D1c,D2c); Tool::D2(*((Curve*)myC),myU,myPc,D1c,D2c);
Standard_Real Ndu = D1c.Magnitude(); Standard_Real Ndu = D1c.Magnitude();
if (Ndu <= myTol) // Cas Singulier (PMN 22/04/1998) if (Ndu <= myTol) // Cas Singulier (PMN 22/04/1998)
{ {
//Derivative is approximated by three points //Derivative is approximated by three points
//Attention: aDelta value must be greater than same value for "Value(...)" //Attention: aDelta value must be greater than same value for "Value(...)"
// function to avoid of points' collisions. // function to avoid of points' collisions.
const Standard_Real DivisionFactor = 0.01; const Standard_Real DivisionFactor = 0.01;
Standard_Real du; Standard_Real du;
if((myUsupremum >= RealLast()) || (myUinfium <= RealFirst())) if((myUsupremum >= RealLast()) || (myUinfium <= RealFirst()))
du = 0.0; du = 0.0;
else else
du = myUsupremum-myUinfium; du = myUsupremum-myUinfium;
const Standard_Real aDelta = Max(du*DivisionFactor,MinStep); const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
Standard_Real F1, F2, F3; Standard_Real F1, F2, F3;
if(myU-myUinfium < 2*aDelta) if(myU-myUinfium < 2*aDelta)
{ {
F1=F; F1=F;
//const Standard_Real U1 = myU; //const Standard_Real U1 = myU;
const Standard_Real U2 = myU + aDelta; const Standard_Real U2 = myU + aDelta;
const Standard_Real U3 = myU + aDelta * 2.0; const Standard_Real U3 = myU + aDelta * 2.0;
if(!((Value(U2,F2)) && (Value(U3,F3)))) if(!((Value(U2,F2)) && (Value(U3,F3))))
{ {
#ifdef DEB //There are many points close to singularity points and
cout << "+++ Function Extrema_FuncExtPC::Values(...)" << endl; //which have zero-derivative. Try to decrease aDelta variable's value.
cout << "There are many points close to singularity points "
"and which have zero-derivative." << endl;
cout << "Try to decrease aDelta variable's value. ---" << endl;
#endif
myD1Init = Standard_False; myD1Init = Standard_False;
return Standard_False; return Standard_False;
}
//After calling of Value(...) function variable myU will be redeterminated.
//So we must return it previous value.
D1f=(-3*F1+4*F2-F3)/(2.0*aDelta);
} }
//After calling of Value(...) function variable myU will be redeterminated.
//So we must return it previous value.
D1f=(-3*F1+4*F2-F3)/(2.0*aDelta);
}
else else
{ {
F3 = F; F3 = F;
const Standard_Real U1 = myU - aDelta * 2.0; const Standard_Real U1 = myU - aDelta * 2.0;
const Standard_Real U2 = myU - aDelta; const Standard_Real U2 = myU - aDelta;
//const Standard_Real U3 = myU; //const Standard_Real U3 = myU;
if(!((Value(U2,F2)) && (Value(U1,F1)))) if(!((Value(U2,F2)) && (Value(U1,F1))))
{ {
#ifdef DEB //There are many points close to singularity points and
cout << "+++ Function Extrema_FuncExtPC::Values(...)" << endl; //which have zero-derivative. Try to decrease aDelta variable's value.
cout << "There are many points close to singularity points "
"and which have zero-derivative." << endl;
cout << "Try to decrease aDelta variable's value. ---" << endl;
#endif
myD1Init = Standard_False; myD1Init = Standard_False;
return Standard_False; return Standard_False;
}
//After calling of Value(...) function variable myU will be redeterminated.
//So we must return it previous value.
D1f=(F1-4*F2+3*F3)/(2.0*aDelta);
} }
myU = U; //After calling of Value(...) function variable myU will be redeterminated.
myPc = myPc_old; //So we must return it previous value.
myP = myP_old; D1f=(F1-4*F2+3*F3)/(2.0*aDelta);
} }
myU = U;
myPc = myPc_old;
myP = myP_old;
}
else else
{ {
Vec PPc (myP,myPc); Vec PPc (myP,myPc);
D1f = Ndu + (PPc.Dot(D2c)/Ndu) - F*(D1c.Dot(D2c))/(Ndu*Ndu); D1f = Ndu + (PPc.Dot(D2c)/Ndu) - F*(D1c.Dot(D2c))/(Ndu*Ndu);
} }
myD1f = D1f; myD1f = D1f;
myD1Init = Standard_True; myD1Init = Standard_True;
return Standard_True; return Standard_True;
} }
//============================================================================= //=============================================================================
Standard_Integer Extrema_FuncExtPC::GetStateNumber () Standard_Integer Extrema_FuncExtPC::GetStateNumber ()
@ -419,7 +408,7 @@ const POnC & Extrema_FuncExtPC::Point (const Standard_Integer N) const
//============================================================================= //=============================================================================
void Extrema_FuncExtPC::SubIntervalInitialize(const Standard_Real theUfirst, const Standard_Real theUlast) void Extrema_FuncExtPC::SubIntervalInitialize(const Standard_Real theUfirst, const Standard_Real theUlast)
{ {
myUinfium = theUfirst; myUinfium = theUfirst;
myUsupremum = theUlast; myUsupremum = theUlast;
} }