1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0023706: Cannot project point on curve

1.   Approximation of derivative (by Taylor-series and by three points).
2.   Some methods (Degree(), GetType(), D0(), D3(), DN()) are added.
3.   Getting of subInterval's boundaries.
4.   Algorithm for checking if 1st derivative is equal to zero is amended.
5.   Cases are controlled when extrema or Project point do not exist.
6.   GetNormal() function for gp_Vec2d was added.
7.   Computing of Value, D0, D1, D2 and D3 for offset curves was changed.
8.   Limitation of tolerance for derivative computing was added.
9.   Methods for computing trihedron in singularity point are added.
10. Test tests/bugs/moddata_3/bug23706 is added.
11. Restriction on the LastParameter for visualization of 3-D curves. Calling PlotCurve(...) function for last interval.
12. LProp package is modified for tangent computing in singularity point (LProp_CLProps, LProp_SLProps).
13. Added test cases for issue.
Deleting bad test cases for this fix
This commit is contained in:
nbv
2013-06-13 15:12:06 +04:00
parent 71797c62f1
commit 32ca7a5106
93 changed files with 4498 additions and 1203 deletions

View File

@@ -139,21 +139,21 @@ is
fields
myCurve : Curve; -- the Curve on which thw calculus are done
u : Real; -- the current value of the parameter
level : Integer; -- the order of derivation
cn : Real; -- the order of continuity of the Curve
linTol : Real; -- the tolerance for null Vector
myCurve : Curve; -- the Curve on which thw calculus are done
myU : Real; -- the current value of the parameter
myDerOrder : Integer; -- the order of derivation
myCN : Real; -- the order of continuity of the Curve
myLinTol : Real; -- the tolerance for null Vector
pnt : Pnt; -- the current point value
d : Vec[3]; -- the current first, second and third derivative
-- value
tangent : Dir; -- the tangent value
curvature : Real; -- the curvature value
myPnt : Pnt; -- the current point value
myDerivArr : Vec[3]; -- the current first, second and third derivative
-- value
myTangent : Dir; -- the tangent value
myCurvature : Real; -- the curvature value
tangentStatus : Status from LProp;
myTangentStatus : Status from LProp;
-- the status of the tangent direction
significantFirstDerivativeOrder : Integer;
mySignificantFirstDerivativeOrder : Integer;
-- the order of the first non null derivative
--
end CLProps;

View File

@@ -20,215 +20,265 @@
#include <LProp_NotDefined.hxx>
#include <Standard_OutOfRange.hxx>
static const Standard_Real MinStep = 1.0e-7;
LProp_CLProps::LProp_CLProps (const Curve& C,
LProp_CLProps::LProp_CLProps (const Curve& C,
const Standard_Real U,
const Standard_Integer N,
const Standard_Integer N,
const Standard_Real Resolution)
: myCurve(C),
level(N),
cn(4), // cn(Tool::Continuity(C)), RLE
linTol(Resolution),
tangentStatus (LProp_Undecided)
: myCurve(C), myDerOrder(N), myCN(4),
myLinTol(Resolution), myTangentStatus (LProp_Undecided)
{
Standard_OutOfRange_Raise_if (N < 0 || N > 3,
"LProp_CLProps::LProp_CLProps()");
"LProp_CLProps::LProp_CLProps()");
SetParameter(U);
}
LProp_CLProps::LProp_CLProps (const Curve& C,
const Standard_Integer N,
const Standard_Real Resolution)
: myCurve(C),
u(RealLast()),
level(N),
cn(4), // (Tool::Continuity(C)), RLE
linTol(Resolution),
tangentStatus (LProp_Undecided)
LProp_CLProps::LProp_CLProps (const Curve& C, const Standard_Integer N,
const Standard_Real Resolution)
: myCurve(C), myU(RealLast()), myDerOrder(N), myCN(4),
myLinTol(Resolution), myTangentStatus (LProp_Undecided)
{
Standard_OutOfRange_Raise_if (N < 0 || N > 3, "");
Standard_OutOfRange_Raise_if (N < 0 || N > 3,
"LProp_CLProps::LProp_CLProps()");
}
LProp_CLProps::LProp_CLProps (const Standard_Integer N,
const Standard_Real Resolution)
: u(RealLast()),
level(N),
cn(0),
linTol(Resolution),
tangentStatus (LProp_Undecided)
: myU(RealLast()), myDerOrder(N), myCN(0), myLinTol(Resolution),
myTangentStatus (LProp_Undecided)
{
Standard_OutOfRange_Raise_if (N < 0 || N > 3, "");
}
void LProp_CLProps::SetParameter(const Standard_Real U)
{
u = U;
switch (level) {
{
myU = U;
switch (myDerOrder)
{
case 0:
Tool::Value(myCurve, u, pnt);
Tool::Value(myCurve, myU, myPnt);
break;
case 1:
Tool::D1(myCurve, u, pnt, d[0]);
Tool::D1(myCurve, myU, myPnt, myDerivArr[0]);
break;
case 2:
Tool::D2(myCurve, u, pnt, d[0], d[1]);
Tool::D2(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1]);
break;
case 3:
Tool::D3(myCurve, u, pnt, d[0], d[1], d[2]);
Tool::D3(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1], myDerivArr[2]);
break;
}
tangentStatus = LProp_Undecided;
myTangentStatus = LProp_Undecided;
}
void LProp_CLProps::SetCurve(const Curve& C) {
myCurve = C ;
cn = 4; // Tool::Continuity(C); RLE
void LProp_CLProps::SetCurve(const Curve& C)
{
myCurve = C ;
myCN = 4; // Tool::Continuity(C); RLE
}
const Pnt& LProp_CLProps::Value () const
{
return pnt;
{
return myPnt;
}
const Vec& LProp_CLProps::D1 ()
{
if (level < 1) {
level = 1;
Tool::D1(myCurve, u, pnt, d[0]);
if (myDerOrder < 1)
{
myDerOrder = 1;
Tool::D1(myCurve, myU, myPnt, myDerivArr[0]);
}
return d[0];
return myDerivArr[0];
}
const Vec& LProp_CLProps::D2 ()
{
if (level < 2) {
level = 2;
Tool::D2(myCurve, u, pnt, d[0], d[1]);
if (myDerOrder < 2)
{
myDerOrder = 2;
Tool::D2(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1]);
}
return d[1];
return myDerivArr[1];
}
const Vec& LProp_CLProps::D3 ()
{
if (level < 3) {
level = 3;
Tool::D3(myCurve, u, pnt, d[0], d[1], d[2]);
if (myDerOrder < 3)
{
myDerOrder = 3;
Tool::D3(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1], myDerivArr[2]);
}
return d[2];
return myDerivArr[2];
}
Standard_Boolean LProp_CLProps::IsTangentDefined ()
{
if (tangentStatus == LProp_Undefined) {
if (myTangentStatus == LProp_Undefined)
return Standard_False;
}
else if (tangentStatus >= LProp_Defined) {
else if (myTangentStatus >= LProp_Defined)
return Standard_True;
}
// tangentStatus == Lprop_Undecided
// we have to calculate the first non null derivative
Standard_Real Tol = linTol * linTol;
const Standard_Real Tol = myLinTol * myLinTol;
Vec V;
Standard_Integer Order = 0;
while (Order < 4) {
Order++;
if(cn >= Order) {
switch(Order) {
case 1 :
V = D1();
break;
case 2 :
V = D2();
break;
case 3 :
V = D3();
break;
};
if(V.SquareMagnitude() > Tol) {
significantFirstDerivativeOrder = Order;
tangentStatus = LProp_Defined;
return Standard_True;
}
}
else {
tangentStatus = LProp_Undefined;
while (Order++ < 4)
{
if(myCN >= Order)
{
switch(Order)
{
case 1:
V = D1();
break;
case 2:
V = D2();
break;
case 3:
V = D3();
break;
}//switch(Order)
if(V.SquareMagnitude() > Tol)
{
mySignificantFirstDerivativeOrder = Order;
myTangentStatus = LProp_Defined;
return Standard_True;
}//if(V.SquareMagnitude() > Tol)
}//if(cn >= Order)
else
{
myTangentStatus = LProp_Undefined;
return Standard_False;
}
}
}// else of "if(cn >= Order)" condition
}//while (Order < 4)
return Standard_False;
}
void LProp_CLProps::Tangent (Dir& D)
{
if(!IsTangentDefined())
LProp_NotDefined::Raise();
if(mySignificantFirstDerivativeOrder == 1)
D = Dir(myDerivArr[0]);
else if (mySignificantFirstDerivativeOrder > 1)
{
const Standard_Real DivisionFactor = 1.e-3;
const Standard_Real anUsupremum = Tool::LastParameter(myCurve),
anUinfium = Tool::FirstParameter(myCurve);
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum-anUinfium;
const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
if(!IsTangentDefined()) { LProp_NotDefined::Raise(); }
D = Dir(d[significantFirstDerivativeOrder - 1]);
Vec V = myDerivArr[mySignificantFirstDerivativeOrder - 1];
Standard_Real u;
if(myU-anUinfium < aDelta)
u = myU+aDelta;
else
u = myU-aDelta;
Pnt P1, P2;
Tool::Value(myCurve, Min(myU, u),P1);
Tool::Value(myCurve, Max(myU, u),P2);
Vec V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0)
V = -V;
D = Dir(V);
}//else if (mySignificantFirstDerivativeOrder > 1)
}
Standard_Real LProp_CLProps::Curvature ()
{
Standard_Boolean isDefined = IsTangentDefined();
LProp_NotDefined_Raise_if(!isDefined,
"LProp_CLProps::CurvatureNotDefined()");
"LProp_CLProps::CurvatureNotDefined()");
// if the first derivative is null the curvature is infinite.
if(significantFirstDerivativeOrder > 1) return RealLast();
if(mySignificantFirstDerivativeOrder > 1)
return RealLast();
Standard_Real Tol = linTol * linTol;
Standard_Real DD1 = d[0].SquareMagnitude();
Standard_Real DD2 = d[1].SquareMagnitude();
Standard_Real Tol = myLinTol * myLinTol;
Standard_Real DD1 = myDerivArr[0].SquareMagnitude();
Standard_Real DD2 = myDerivArr[1].SquareMagnitude();
// if the second derivative is null the curvature is null.
if (DD2 <= Tol) {
curvature = 0.0;
if (DD2 <= Tol)
{
myCurvature = 0.0;
}
else {
Standard_Real N = d[0].CrossSquareMagnitude(d[1]);
else
{
Standard_Real N = myDerivArr[0].CrossSquareMagnitude(myDerivArr[1]);
// if d[0] and d[1] are colinear the curvature is null.
Standard_Real t = N/(DD1*DD2);
if (t<=Tol) {
curvature = 0.0;
if (t<=Tol)
{
myCurvature = 0.0;
}
else {
curvature = sqrt(N) / (DD1*sqrt(DD1));
else
{
myCurvature = sqrt(N) / (DD1*sqrt(DD1));
}
}
return curvature;
}
return myCurvature;
}
void LProp_CLProps::Normal (Dir& D)
{
Standard_Real c = Curvature();
if(c==RealLast() || Abs(c) <= linTol) { LProp_NotDefined::Raise(); }
if(c==RealLast() || Abs(c) <= myLinTol)
{
LProp_NotDefined::Raise("LProp_CLProps::Normal(...):"
"Curvature is null or infinity");
}
// we used here the following vector relation
// a ^ (b ^ c) = b(ac) - c(ab)
// Norm = d[0] ^ (d[1] ^ d[0])
Vec Norm = d[1] * (d[0] * d[0]) - d[0] * (d[0] * d[1]);
Vec Norm = myDerivArr[1] * (myDerivArr[0] * myDerivArr[0]) - myDerivArr[0] * (myDerivArr[0] * myDerivArr[1]);
D = Dir(Norm);
}
void LProp_CLProps::CentreOfCurvature (Pnt& P)
{
if(Abs(Curvature()) <= linTol) { LProp_NotDefined::Raise(); }
if(Abs(Curvature()) <= myLinTol)
{
LProp_NotDefined::Raise();
}
// we used here the following vector relation
// a ^ (b ^ c) = b(ac) - c(ab)
// Norm = d[0] ^ (d[1] ^ d[0])
Vec Norm = d[1] * (d[0] * d[0]) - d[0] * (d[0] * d[1]);
Vec Norm = myDerivArr[1] * (myDerivArr[0] * myDerivArr[0]) - myDerivArr[0] * (myDerivArr[0] * myDerivArr[1]);
Norm.Normalize();
Norm.Divide(curvature);
P= pnt.Translated(Norm);
Norm.Divide(myCurvature);
P= myPnt.Translated(Norm);
}

View File

@@ -197,35 +197,35 @@ is
fields
surf : Surface;
u : Real;
v : Real;
level : Integer;
cn : Integer;
linTol : Real;
mySurf : Surface;
myU : Real;
myV : Real;
myDerOrder : Integer;
myCN : Integer;
myLinTol : Real;
pnt : Pnt from gp;
d1U : Vec from gp;
d1V : Vec from gp;
d2U : Vec from gp;
d2V : Vec from gp;
dUV : Vec from gp;
myPnt : Pnt from gp;
myD1u : Vec from gp;
myD1v : Vec from gp;
myD2u : Vec from gp;
myD2v : Vec from gp;
myDuv : Vec from gp;
normal : Dir from gp;
minCurv : Real;
maxCurv : Real;
dirMinCurv : Dir from gp;
dirMaxCurv : Dir from gp;
meanCurv : Real;
gausCurv : Real;
myNormal : Dir from gp;
myMinCurv : Real;
myMaxCurv : Real;
myDirMinCurv : Dir from gp;
myDirMaxCurv : Dir from gp;
myMeanCurv : Real;
myGausCurv : Real;
significantFirstUDerivativeOrder : Integer;
significantFirstVDerivativeOrder : Integer;
mySignificantFirstDerivativeOrderU : Integer;
mySignificantFirstDerivativeOrderV : Integer;
uTangentStatus : Status from LProp;
vTangentStatus : Status from LProp;
normalStatus : Status from LProp;
curvatureStatus : Status from LProp;
myUTangentStatus : Status from LProp;
myVTangentStatus : Status from LProp;
myNormalStatus : Status from LProp;
myCurvatureStatus : Status from LProp;
end SLProps;

View File

@@ -26,56 +26,62 @@
#include <TColgp_Array2OfVec.hxx>
#include <math_DirectPolynomialRoots.hxx>
static const Standard_Real MinStep = 1.0e-7;
static Standard_Boolean IsTangentDefined (LProp_SLProps& SProp,
const Standard_Integer cn,
const Standard_Real linTol,
const Standard_Integer Derivative,
Standard_Integer& Order,
LProp_Status& Status)
const Standard_Integer cn,
const Standard_Real linTol,
const Standard_Integer Derivative,
Standard_Integer& Order,
LProp_Status& Status)
{
Standard_Real Tol = linTol * linTol;
gp_Vec V[2];
Order = 0;
while (Order < 3) {
while (Order < 3)
{
Order++;
if(cn >= Order) {
switch(Order) {
case 1 :
V[0] = SProp.D1U();
V[1] = SProp.D1V();
break;
case 2 :
V[0] = SProp.D2U();
V[1] = SProp.D2V();
break;
};
if(V[Derivative].SquareMagnitude() > Tol) {
Status = LProp_Defined;
return Standard_True;
if(cn >= Order)
{
switch(Order)
{
case 1:
V[0] = SProp.D1U();
V[1] = SProp.D1V();
break;
case 2:
V[0] = SProp.D2U();
V[1] = SProp.D2V();
break;
}//switch(Order)
if(V[Derivative].SquareMagnitude() > Tol)
{
Status = LProp_Defined;
return Standard_True;
}
}
else {
}//if(cn >= Order)
else
{
Status = LProp_Undefined;
return Standard_False;
}
}
return Standard_False;
}
LProp_SLProps::LProp_SLProps (const Surface& S,
const Standard_Real U,
const Standard_Real V,
const Standard_Integer N,
const Standard_Real Resolution)
: surf(S),
level(N),
cn(4), // (Tool::Continuity(S)),
linTol(Resolution)
const Standard_Real U,
const Standard_Real V,
const Standard_Integer N,
const Standard_Real Resolution)
: mySurf(S),myDerOrder(N), myCN(4), // (Tool::Continuity(S)),
myLinTol(Resolution)
{
Standard_OutOfRange_Raise_if(N < 0 || N > 2,
"LProp_SLProps::LProp_SLProps()");
"LProp_SLProps::LProp_SLProps()");
SetParameters(U, V);
}
@@ -83,292 +89,328 @@ LProp_SLProps::LProp_SLProps (const Surface& S,
LProp_SLProps::LProp_SLProps (const Surface& S,
const Standard_Integer N,
const Standard_Real Resolution)
: surf(S),
u(RealLast()), v(RealLast()),
level(N),
cn(4), // (Tool::Continuity(S)),
linTol(Resolution),
uTangentStatus (LProp_Undecided),
vTangentStatus (LProp_Undecided),
normalStatus (LProp_Undecided),
curvatureStatus(LProp_Undecided)
: mySurf(S), myU(RealLast()), myV(RealLast()), myDerOrder(N),
myCN(4), // (Tool::Continuity(S))
myLinTol(Resolution),
myUTangentStatus (LProp_Undecided),
myVTangentStatus (LProp_Undecided),
myNormalStatus (LProp_Undecided),
myCurvatureStatus(LProp_Undecided)
{
Standard_OutOfRange_Raise_if(N < 0 || N > 2,
"LProp_SLProps::LProp_SLProps()");
"LProp_SLProps::LProp_SLProps()");
}
LProp_SLProps::LProp_SLProps (const Standard_Integer N,
const Standard_Real Resolution)
:u(RealLast()), v(RealLast()),
level(N),
cn(0),
linTol(Resolution),
uTangentStatus (LProp_Undecided),
vTangentStatus (LProp_Undecided),
normalStatus (LProp_Undecided),
curvatureStatus(LProp_Undecided)
const Standard_Real Resolution)
: myU(RealLast()), myV(RealLast()), myDerOrder(N), myCN(0),
myLinTol(Resolution),
myUTangentStatus (LProp_Undecided),
myVTangentStatus (LProp_Undecided),
myNormalStatus (LProp_Undecided),
myCurvatureStatus(LProp_Undecided)
{
Standard_OutOfRange_Raise_if(N < 0 || N > 2,
"LProp_SLProps::LProp_SLProps() bad level");
"LProp_SLProps::LProp_SLProps() bad level");
}
void LProp_SLProps::SetSurface (const Surface& S ) {
surf = S;
cn = 4; // =Tool::Continuity(S);
}
void LProp_SLProps::SetParameters (const Standard_Real U, const Standard_Real V)
void LProp_SLProps::SetSurface (const Surface& S )
{
u = U;
v = V;
switch (level) {
mySurf = S;
myCN = 4; // =Tool::Continuity(S);
}
void LProp_SLProps::SetParameters (const Standard_Real U,
const Standard_Real V)
{
myU = U;
myV = V;
switch (myDerOrder)
{
case 0:
Tool::Value(surf, u, v, pnt);
Tool::Value(mySurf, myU, myV, myPnt);
break;
case 1:
Tool::D1(surf, u, v, pnt, d1U, d1V);
Tool::D1(mySurf, myU, myV, myPnt, myD1u, myD1v);
break;
case 2:
Tool::D2(surf, u, v, pnt, d1U, d1V, d2U, d2V, dUV);
Tool::D2(mySurf, myU, myV, myPnt, myD1u, myD1v, myD2u, myD2v, myDuv);
break;
};
uTangentStatus = LProp_Undecided;
vTangentStatus = LProp_Undecided;
normalStatus = LProp_Undecided;
curvatureStatus = LProp_Undecided;
}
myUTangentStatus = LProp_Undecided;
myVTangentStatus = LProp_Undecided;
myNormalStatus = LProp_Undecided;
myCurvatureStatus = LProp_Undecided;
}
const gp_Pnt& LProp_SLProps::Value() const
{
return pnt;
return myPnt;
}
const gp_Vec& LProp_SLProps::D1U()
{
if (level < 1) {
level =1;
Tool::D1(surf,u,v,pnt,d1U,d1V);
if (myDerOrder < 1)
{
myDerOrder =1;
Tool::D1(mySurf,myU,myV,myPnt,myD1u,myD1v);
}
return d1U;
return myD1u;
}
const gp_Vec& LProp_SLProps::D1V()
{
if (level < 1) {
level =1;
Tool::D1(surf,u,v,pnt,d1U,d1V);
if (myDerOrder < 1)
{
myDerOrder =1;
Tool::D1(mySurf,myU,myV,myPnt,myD1u,myD1v);
}
return d1V;
return myD1v;
}
const gp_Vec& LProp_SLProps::D2U()
{
if (level < 2) {
level =2;
Tool::D2(surf,u,v,pnt,d1U,d1V,d2U,d2V,dUV);
if (myDerOrder < 2)
{
myDerOrder =2;
Tool::D2(mySurf,myU,myV,myPnt,myD1u,myD1v,myD2u,myD2v,myDuv);
}
return d2U;
return myD2u;
}
const gp_Vec& LProp_SLProps::D2V()
{
if (level < 2) {
level =2;
Tool::D2(surf,u,v,pnt,d1U,d1V,d2U,d2V,dUV);
if (myDerOrder < 2)
{
myDerOrder =2;
Tool::D2(mySurf,myU,myV,myPnt,myD1u,myD1v,myD2u,myD2v,myDuv);
}
return d2V;
return myD2v;
}
const gp_Vec& LProp_SLProps::DUV()
{
if (level < 2) {
level =2;
Tool::D2(surf,u,v,pnt,d1U,d1V,d2U,d2V,dUV);
if (myDerOrder < 2)
{
myDerOrder =2;
Tool::D2(mySurf,myU,myV,myPnt,myD1u,myD1v,myD2u,myD2v,myDuv);
}
return dUV;
return myDuv;
}
Standard_Boolean LProp_SLProps::IsTangentUDefined ()
{
if (uTangentStatus == LProp_Undefined) {
if (myUTangentStatus == LProp_Undefined)
return Standard_False;
}
else if (uTangentStatus >= LProp_Defined) {
else if (myUTangentStatus >= LProp_Defined)
return Standard_True;
}
// uTangentStatus == Lprop_Undecided
// we have to calculate the first non null U derivative
return IsTangentDefined(*this, cn, linTol, 0,
significantFirstUDerivativeOrder, uTangentStatus);
return IsTangentDefined(*this, myCN, myLinTol, 0,
mySignificantFirstDerivativeOrderU, myUTangentStatus);
}
void LProp_SLProps::TangentU (gp_Dir& D) {
void LProp_SLProps::TangentU (gp_Dir& D)
{
if(!IsTangentUDefined())
LProp_NotDefined::Raise();
if(!IsTangentUDefined()) { LProp_NotDefined::Raise(); }
if(significantFirstUDerivativeOrder == 1) {
D = gp_Dir(d1U);
}
else {
D = gp_Dir(d2U);
if(mySignificantFirstDerivativeOrderU == 1)
D = gp_Dir(myD1u);
else
{
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real anUsupremum, anUinfium;
Standard_Real anVsupremum, anVinfium;
Tool::Bounds(mySurf,anUinfium,anVinfium,anUsupremum,anVsupremum);
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum-anUinfium;
const Standard_Real aDeltaU = Max(du*DivisionFactor,MinStep);
gp_Vec V = myD2u;
Standard_Real u;
if(myU-anUinfium < aDeltaU)
u = myU+aDeltaU;
else
u = myU-aDeltaU;
gp_Pnt P1, P2;
Tool::Value(mySurf, Min(myU, u),myV,P1);
Tool::Value(mySurf, Max(myU, u),myV,P2);
gp_Vec V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0)
V = -V;
D = gp_Dir(V);
}
}
Standard_Boolean LProp_SLProps::IsTangentVDefined ()
{
if (vTangentStatus == LProp_Undefined) {
if (myVTangentStatus == LProp_Undefined)
return Standard_False;
}
else if (vTangentStatus >= LProp_Defined) {
else if (myVTangentStatus >= LProp_Defined)
return Standard_True;
}
// vTangentStatus == Lprop_Undecided
// we have to calculate the first non null V derivative
return IsTangentDefined(*this, cn, linTol, 1,
significantFirstVDerivativeOrder, vTangentStatus);
return IsTangentDefined(*this, myCN, myLinTol, 1,
mySignificantFirstDerivativeOrderV, myVTangentStatus);
}
void LProp_SLProps::TangentV (gp_Dir& D) {
void LProp_SLProps::TangentV (gp_Dir& D)
{
if(!IsTangentVDefined())
LProp_NotDefined::Raise();
if(mySignificantFirstDerivativeOrderV == 1)
D = gp_Dir(myD1v);
else
{
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real anUsupremum, anUinfium;
Standard_Real anVsupremum, anVinfium;
Tool::Bounds(mySurf,anUinfium,anVinfium,anUsupremum,anVsupremum);
Standard_Real dv;
if((anVsupremum >= RealLast()) || (anVinfium <= RealFirst()))
dv = 0.0;
else
dv = anVsupremum-anVinfium;
const Standard_Real aDeltaV = Max(dv*DivisionFactor,MinStep);
if(!IsTangentVDefined()) { LProp_NotDefined::Raise(); }
if(significantFirstVDerivativeOrder == 1) {
D = gp_Dir(d1V);
}
else {
D = gp_Dir(d2V);
gp_Vec V = myD2v;
Standard_Real v;
if(myV-anVinfium < aDeltaV)
v = myV+aDeltaV;
else
v = myV-aDeltaV;
gp_Pnt P1, P2;
Tool::Value(mySurf, myU, Min(myV, v),P1);
Tool::Value(mySurf, myU, Max(myV, v),P2);
gp_Vec V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0)
V = -V;
D = gp_Dir(V);
}
}
Standard_Boolean LProp_SLProps::IsNormalDefined()
{
if (normalStatus == LProp_Undefined) {
if (myNormalStatus == LProp_Undefined)
return Standard_False;
}
else if (normalStatus >= LProp_Defined) {
else if (myNormalStatus >= LProp_Defined)
return Standard_True;
}
// status = UnDecided
// first try the standard computation of the normal.
CSLib_DerivativeStatus Status;
CSLib::Normal(d1U, d1V, linTol, Status, normal);
if (Status == CSLib_Done ) {
normalStatus = LProp_Computed;
CSLib::Normal(myD1u, myD1v, myLinTol, Status, myNormal);
if (Status == CSLib_Done )
{
myNormalStatus = LProp_Computed;
return Standard_True;
}
// else solve the degenerated case only if continuity >= 2
/* if (cn >= 2) {
if(level < 2) this->D2U();
Standard_Boolean Done;
CSLib_NormalStatus Stat;
CSLib::Normal(d1U, d1V, d2U, d2V, dUV, linTol, Done, Stat, normal);
if (Done) {
normalStatus = LProp_Computed;
return Standard_True;
}
}*/
/*
else {
Standard_Integer MaxOrder=3;
CSLib_NormalStatus Stat;
gp_Dir thenormal;
TColgp_Array2OfVec DerNUV(0,MaxOrder,0,MaxOrder);
TColgp_Array2OfVec DerSurf(0,MaxOrder+1,0,MaxOrder+1);
Standard_Integer i,j,OrderU,OrderV;
Standard_Real Umin,Umax,Vmin,Vmax;
Tool::Bounds(surf, Umin, Vmin, Umax, Vmax);
// Calcul des derivees
for(i=1;i<=MaxOrder+1;i++){
DerSurf.SetValue(i,0, Tool::DN(surf,u,v,i,0));
}
for(i=0;i<=MaxOrder+1;i++)
for(j=1;j<=MaxOrder+1;j++){
DerSurf.SetValue(i,j, Tool::DN(surf,u,v,i,j));
}
for(i=0;i<=MaxOrder;i++)
for(j=0;j<=MaxOrder;j++){
DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurf));
}
CSLib::Normal(MaxOrder,DerNUV, 1.e-9, u,v,
Umin,Umax,Vmin,Vmax,
Stat, thenormal, OrderU, OrderV);
normal.SetXYZ(thenormal.XYZ());
if (Stat == CSLib_Defined) {
normalStatus = LProp_Computed;
return Standard_True;
}
}
*/
normalStatus = LProp_Undefined;
myNormalStatus = LProp_Undefined;
return Standard_False;
}
const gp_Dir& LProp_SLProps::Normal () {
const gp_Dir& LProp_SLProps::Normal ()
{
if(!IsNormalDefined())
{
LProp_NotDefined::Raise();
}
if(!IsNormalDefined()) { LProp_NotDefined::Raise(); }
return normal;
return myNormal;
}
Standard_Boolean LProp_SLProps::IsCurvatureDefined ()
{
if (curvatureStatus == LProp_Undefined) {
if (myCurvatureStatus == LProp_Undefined)
return Standard_False;
}
else if (curvatureStatus >= LProp_Defined) {
else if (myCurvatureStatus >= LProp_Defined)
return Standard_True;
}
if(cn < 2) {
curvatureStatus = LProp_Undefined;
if(myCN < 2)
{
myCurvatureStatus = LProp_Undefined;
return Standard_False;
}
// status = UnDecided
if (!IsNormalDefined()) {
curvatureStatus = LProp_Undefined;
if (!IsNormalDefined())
{
myCurvatureStatus = LProp_Undefined;
return Standard_False;
}
// pour eviter un plantage dans le cas du caro pointu
// en fait on doit pouvoir calculer les courbure
// avoir
if(!IsTangentUDefined() || !IsTangentVDefined()) {
curvatureStatus = LProp_Undefined;
if(!IsTangentUDefined() || !IsTangentVDefined())
{
myCurvatureStatus = LProp_Undefined;
return Standard_False;
}
// here we compute the curvature features of the surface
gp_Vec Norm (normal);
gp_Vec Norm (myNormal);
Standard_Real E = d1U.SquareMagnitude();
Standard_Real F = d1U.Dot(d1V);
Standard_Real G = d1V.SquareMagnitude();
Standard_Real E = myD1u.SquareMagnitude();
Standard_Real F = myD1u.Dot(myD1v);
Standard_Real G = myD1v.SquareMagnitude();
if(level < 2) this->D2U();
if(myDerOrder < 2)
this->D2U();
Standard_Real L = Norm.Dot(d2U);
Standard_Real M = Norm.Dot(dUV);
Standard_Real N = Norm.Dot(d2V);
Standard_Real L = Norm.Dot(myD2u);
Standard_Real M = Norm.Dot(myDuv);
Standard_Real N = Norm.Dot(myD2v);
Standard_Real A = E * M - F * L;
Standard_Real B = E * N - G * L;
Standard_Real C = F * N - G * M;
Standard_Real MaxABC = Max(Max(Abs(A),Abs(B)),Abs(C));
if (MaxABC < RealEpsilon()) { // ombilic
minCurv = N / G;
maxCurv = minCurv;
dirMinCurv = gp_Dir (d1U);
dirMaxCurv = gp_Dir (d1U.Crossed(Norm));
meanCurv = minCurv; // (Cmin + Cmax) / 2.
gausCurv = minCurv * minCurv; // (Cmin * Cmax)
curvatureStatus = LProp_Computed;
if (MaxABC < RealEpsilon()) // ombilic
{
myMinCurv = N / G;
myMaxCurv = myMinCurv;
myDirMinCurv = gp_Dir (myD1u);
myDirMaxCurv = gp_Dir (myD1u.Crossed(Norm));
myMeanCurv = myMinCurv; // (Cmin + Cmax) / 2.
myGausCurv = myMinCurv * myMinCurv; // (Cmin * Cmax)
myCurvatureStatus = LProp_Computed;
return Standard_True;
}
@@ -377,105 +419,124 @@ Standard_Boolean LProp_SLProps::IsCurvatureDefined ()
C = C / MaxABC;
Standard_Real Curv1, Curv2, Root1, Root2;
gp_Vec VectCurv1, VectCurv2;
if (Abs(A) > RealEpsilon()) {
if (Abs(A) > RealEpsilon())
{
math_DirectPolynomialRoots Root (A, B, C);
if(Root.NbSolutions() != 2) {
curvatureStatus = LProp_Undefined;
if(Root.NbSolutions() != 2)
{
myCurvatureStatus = LProp_Undefined;
return Standard_False;
}
else {
Root1 = Root.Value(1);
else
{
Root1 = Root.Value(1);
Root2 = Root.Value(2);
Curv1 = ((L * Root1 + 2. * M) * Root1 + N) /
((E * Root1 + 2. * F) * Root1 + G);
Curv2 = ((L * Root2 + 2. * M) * Root2 + N) /
((E * Root2 + 2. * F) * Root2 + G);
VectCurv1 = Root1 * d1U + d1V;
VectCurv2 = Root2 * d1U + d1V;
VectCurv1 = Root1 * myD1u + myD1v;
VectCurv2 = Root2 * myD1u + myD1v;
}
}
else if (Abs(C) > RealEpsilon()) {
else if (Abs(C) > RealEpsilon())
{
math_DirectPolynomialRoots Root(C, B, A);
if((Root.NbSolutions() != 2)) {
curvatureStatus = LProp_Undefined;
if((Root.NbSolutions() != 2))
{
myCurvatureStatus = LProp_Undefined;
return Standard_False;
}
else {
else
{
Root1 = Root.Value(1);
Root2 = Root.Value(2);
Curv1 = ((N * Root1 + 2. * M) * Root1 + L) /
((G * Root1 + 2. * F) * Root1 + E);
Curv2 = ((N * Root2 + 2. * M) * Root2 + L) /
((G * Root2 + 2. * F) * Root2 + E);
VectCurv1 = d1U + Root1 * d1V;
VectCurv2 = d1U + Root2 * d1V;
VectCurv1 = myD1u + Root1 * myD1v;
VectCurv2 = myD1u + Root2 * myD1v;
}
}
else {
else
{
Curv1 = L / E;
Curv2 = N / G;
VectCurv1 = d1U;
VectCurv2 = d1V;
VectCurv1 = myD1u;
VectCurv2 = myD1v;
}
if (Curv1 < Curv2) {
minCurv = Curv1;
maxCurv = Curv2;
dirMinCurv = gp_Dir (VectCurv1);
dirMaxCurv = gp_Dir (VectCurv2);
}
else {
minCurv = Curv2;
maxCurv = Curv1;
dirMinCurv = gp_Dir (VectCurv2);
dirMaxCurv = gp_Dir (VectCurv1);
}
meanCurv = ((N * E) - (2. * M * F) + (L * G)) // voir Farin p.282
/ (2. * ((E * G) - (F * F)));
gausCurv = ((L * N) - (M * M))
/ ((E * G) - (F * F));
curvatureStatus = LProp_Computed;
return Standard_True;
}
if (Curv1 < Curv2)
{
myMinCurv = Curv1;
myMaxCurv = Curv2;
myDirMinCurv = gp_Dir (VectCurv1);
myDirMaxCurv = gp_Dir (VectCurv2);
}
else
{
myMinCurv = Curv2;
myMaxCurv = Curv1;
myDirMinCurv = gp_Dir (VectCurv2);
myDirMaxCurv = gp_Dir (VectCurv1);
}
myMeanCurv = ((N * E) - (2. * M * F) + (L * G)) // voir Farin p.282
/ (2. * ((E * G) - (F * F)));
myGausCurv = ((L * N) - (M * M))
/ ((E * G) - (F * F));
myCurvatureStatus = LProp_Computed;
return Standard_True;
}
Standard_Boolean LProp_SLProps::IsUmbilic ()
{
if(!IsCurvatureDefined()) { LProp_NotDefined::Raise(); }
return Abs(maxCurv - minCurv) < Abs(Epsilon(maxCurv));
if(!IsCurvatureDefined())
LProp_NotDefined::Raise();
return Abs(myMaxCurv - myMinCurv) < Abs(Epsilon(myMaxCurv));
}
Standard_Real LProp_SLProps::MaxCurvature ()
{
if(!IsCurvatureDefined()) { LProp_NotDefined::Raise(); }
return maxCurv;
if(!IsCurvatureDefined())
LProp_NotDefined::Raise();
return myMaxCurv;
}
Standard_Real LProp_SLProps::MinCurvature ()
{
if(!IsCurvatureDefined()) { LProp_NotDefined::Raise(); }
return minCurv;
if(!IsCurvatureDefined())
LProp_NotDefined::Raise();
return myMinCurv;
}
void LProp_SLProps::CurvatureDirections(gp_Dir& Max, gp_Dir& Min)
{
if(!IsCurvatureDefined())
LProp_NotDefined::Raise();
if(!IsCurvatureDefined()) { LProp_NotDefined::Raise(); }
Max = dirMaxCurv;
Min = dirMinCurv;
Max = myDirMaxCurv;
Min = myDirMinCurv;
}
Standard_Real LProp_SLProps::MeanCurvature () {
if(!IsCurvatureDefined()) { LProp_NotDefined::Raise(); }
return meanCurv;
Standard_Real LProp_SLProps::MeanCurvature ()
{
if(!IsCurvatureDefined())
LProp_NotDefined::Raise();
return myMeanCurv;
}
Standard_Real LProp_SLProps::GaussianCurvature () {
Standard_Real LProp_SLProps::GaussianCurvature ()
{
if(!IsCurvatureDefined())
LProp_NotDefined::Raise();
if(!IsCurvatureDefined()) { LProp_NotDefined::Raise(); }
return gausCurv;
return myGausCurv;
}