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

0023824: Bad results of sweep operation when a path curve has unpredictable torsion along its way.

Adding test cases for this fix
This commit is contained in:
jgv
2013-03-22 17:10:51 +04:00
parent 26347898a8
commit a31abc03d7
26 changed files with 1226 additions and 105 deletions

View File

@@ -44,6 +44,7 @@
#include <Geom_BSplineCurve.hxx>
#include <TColgp_HArray1OfPnt.hxx>
#ifdef DEB
static Standard_Boolean Affich=0;
#endif
@@ -90,6 +91,30 @@ static void draw(const Handle(Law_Function)& law)
}
#endif
static Standard_Real ComputeTorsion(const Standard_Real Param,
const Handle(Adaptor3d_HCurve)& aCurve)
{
Standard_Real Torsion;
gp_Pnt aPoint;
gp_Vec DC1, DC2, DC3;
aCurve->D3(Param, aPoint, DC1, DC2, DC3);
gp_Vec DC1crossDC2 = DC1 ^ DC2;
Standard_Real Norm_DC1crossDC2 = DC1crossDC2.Magnitude();
Standard_Real DC1DC2DC3 = DC1crossDC2 * DC3 ; //mixed product
Standard_Real Tol = gp::Resolution();
Standard_Real SquareNorm_DC1crossDC2 = Norm_DC1crossDC2 * Norm_DC1crossDC2;
if (SquareNorm_DC1crossDC2 <= Tol)
Torsion = 0.;
else
Torsion = DC1DC2DC3 / SquareNorm_DC1crossDC2 ;
return Torsion;
}
//===============================================================
// Function : smoothlaw
// Purpose : to smooth a law : Reduce the number of knots
@@ -280,13 +305,25 @@ static Standard_Boolean FindPlane ( const Handle(Adaptor3d_HCurve)& c,
}
//===============================================================
// Function :
// Function : Constructor
// Purpose :
//===============================================================
GeomFill_CorrectedFrenet::GeomFill_CorrectedFrenet()
: isFrenet(Standard_False)
{
frenet = new GeomFill_Frenet();
myForEvaluation = Standard_False;
}
//===============================================================
// Function : Constructor
// Purpose :
//===============================================================
GeomFill_CorrectedFrenet::GeomFill_CorrectedFrenet(const Standard_Boolean ForEvaluation)
: isFrenet(Standard_False)
{
frenet = new GeomFill_Frenet();
myForEvaluation = ForEvaluation;
}
Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
@@ -314,6 +351,7 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
{
// No probleme isFrenet
isFrenet = Standard_True;
break;
}
default :
{
@@ -382,8 +420,12 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
for(i = 1; i <= NbI; i++) {
NbStep = Max(Standard_Integer((T(i+1) - T(i))/AvStep), 3);
Step = (T(i+1) - T(i))/NbStep;
if(!InitInterval(T(i), T(i+1), Step, StartAng, Tangent, Normal, AT, AN, Func, SeqPoles, SeqAngle, SeqTangent, SeqNormal))
if(isFrenet) isFrenet = Standard_False;
if(!InitInterval(T(i), T(i+1), Step, StartAng, Tangent, Normal, AT, AN, Func,
SeqPoles, SeqAngle, SeqTangent, SeqNormal))
{
if(isFrenet)
isFrenet = Standard_False;
}
Handle(Law_Composite)::DownCast(EvolAroundT)->ChangeLaws().Append(Func);
}
if(myTrimmed->IsPeriodic())
@@ -402,7 +444,7 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
HArrTangent->ChangeValue(i) = SeqTangent(i);
HArrNormal->ChangeValue(i) = SeqNormal(i);
};
#if DRAW
if (Affich) {
draw(EvolAroundT);
@@ -431,6 +473,7 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
TColStd_SequenceOfReal EvolAT;
Standard_Real Param = First, LengthMin, L, norm;
Standard_Boolean isZero = Standard_True, isConst = Standard_True;
const Standard_Real minnorm = 1.e-16;
Standard_Integer i;
gp_Pnt PonC;
gp_Vec D1;
@@ -446,7 +489,9 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
Standard_Real angleAT, currParam, currStep = Step;
Handle( Geom_Plane ) aPlane;
Standard_Boolean isPlanar = FindPlane( myCurve, aPlane );
Standard_Boolean isPlanar = Standard_False;
if (!myForEvaluation)
isPlanar = FindPlane( myCurve, aPlane );
i = 1;
currParam = Param;
@@ -493,13 +538,21 @@ Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
//Evaluate the Next step
CS.D1(Param, PonC, D1);
L = Max(PonC.XYZ().Modulus()/2, LengthMin);
L = PonC.XYZ().Modulus()/2;
norm = D1.Magnitude();
if (norm < Precision::Confusion()) {
norm = Precision::Confusion();
if (norm <= gp::Resolution())
{
//norm = 2.*gp::Resolution();
norm = minnorm;
}
currStep = L / norm;
if (currStep > Step) currStep = Step;//default value
if (currStep <= gp::Resolution()) //L = 0 => curvature = 0, linear segment
currStep = Step;
if (currStep < Precision::Confusion()) //too small step
currStep = Precision::Confusion();
if (currStep > Step) //too big step
currStep = Step;//default value
}
else
currStep /= 2; // Step too long !
@@ -887,6 +940,59 @@ Standard_Real GeomFill_CorrectedFrenet::GetAngleAT(const Standard_Real Param) co
Precision::PConfusion()/2);
}
//===============================================================
// Function : EvaluateBestMode
// Purpose :
//===============================================================
GeomFill_Trihedron GeomFill_CorrectedFrenet::EvaluateBestMode()
{
if (EvolAroundT.IsNull())
return GeomFill_IsFrenet; //Frenet
const Standard_Real MaxAngle = 3.*M_PI/4.;
const Standard_Real MaxTorsion = 100.;
Standard_Real Step, u, v, tmin, tmax;
Standard_Integer NbInt, i, j, k = 1;
NbInt = EvolAroundT->NbIntervals(GeomAbs_CN);
TColStd_Array1OfReal Int(1, NbInt+1);
EvolAroundT->Intervals(Int, GeomAbs_CN);
gp_Pnt2d old;
gp_Vec2d aVec, PrevVec;
Standard_Integer NbSamples = 10;
for(i = 1; i <= NbInt; i++){
tmin = Int(i);
tmax = Int(i+1);
Standard_Real Torsion = ComputeTorsion(tmin, myTrimmed);
if (Abs(Torsion) > MaxTorsion)
return GeomFill_IsDiscreteTrihedron; //DiscreteTrihedron
Handle(Law_Function) trimmedlaw = EvolAroundT->Trim(tmin, tmax, Precision::PConfusion()/2);
Step = (Int(i+1)-Int(i))/NbSamples;
for (j = 0; j <= NbSamples; j++) {
u = tmin + j*Step;
v = trimmedlaw->Value(u);
gp_Pnt2d point2d(u,v);
if (j != 0)
{
aVec.SetXY(point2d.XY() - old.XY());
if (k > 2)
{
Standard_Real theAngle = PrevVec.Angle(aVec);
if (Abs(theAngle) > MaxAngle)
return GeomFill_IsDiscreteTrihedron; //DiscreteTrihedron
}
PrevVec = aVec;
}
old = point2d;
k++;
}
}
return GeomFill_IsCorrectedFrenet; //CorrectedFrenet
}
//===============================================================
// Function : GetAverageLaw
// Purpose :