mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0025892: Wrong result obtained by projection algorithm.
1) Treatment of case when projection algorithm to BSpline surface return null 2d curve. 2) Changed approximation of next step in default projection algorithm. 3) Special handling of surface of revolution added. "Period jump" handling evaded in case when curve not computed. Test cases for issue CR25892 Small correction of test cases fot CR25892
This commit is contained in:
@@ -767,7 +767,7 @@ void ProjLib_CompProjectedCurve::Init()
|
||||
|
||||
t = Triple.X() + Step;
|
||||
if (t > LastU) t = LastU;
|
||||
|
||||
Standard_Real prevStep = Step;
|
||||
Standard_Real U0, V0;
|
||||
gp_Pnt2d aLowBorder(mySurface->FirstUParameter(),mySurface->FirstVParameter());
|
||||
gp_Pnt2d aUppBorder(mySurface->LastUParameter(), mySurface->LastVParameter());
|
||||
@@ -776,8 +776,8 @@ void ProjLib_CompProjectedCurve::Init()
|
||||
while (t <= LastU && new_part)
|
||||
{
|
||||
|
||||
U0 = Triple.Y() + (Triple.Y() - prevTriple.Y());
|
||||
V0 = Triple.Z() + (Triple.Z() - prevTriple.Z());
|
||||
U0 = Triple.Y() + (Step / prevStep) * (Triple.Y() - prevTriple.Y());
|
||||
V0 = Triple.Z() + (Step / prevStep) * (Triple.Z() - prevTriple.Z());
|
||||
// adjust U0 to be in [mySurface->FirstUParameter(),mySurface->LastUParameter()]
|
||||
U0 = Min(Max(U0, aLowBorder.X()), aUppBorder.X());
|
||||
// adjust V0 to be in [mySurface->FirstVParameter(),mySurface->LastVParameter()]
|
||||
@@ -837,9 +837,27 @@ void ProjLib_CompProjectedCurve::Init()
|
||||
// Go further
|
||||
else
|
||||
{
|
||||
prevTriple = Triple;
|
||||
prevTriple = Triple;
|
||||
prevStep = Step;
|
||||
Triple = gp_Pnt(t, aPrjPS.Solution().X(), aPrjPS.Solution().Y());
|
||||
|
||||
if (mySurface->GetType() == GeomAbs_SurfaceOfRevolution &&
|
||||
(Abs (Triple.Z() - mySurface->FirstVParameter()) < Precision::Confusion() ||
|
||||
Abs (Triple.Z() - mySurface->LastVParameter() ) < Precision::Confusion() ))
|
||||
{
|
||||
// Go out from possible attraktor.
|
||||
|
||||
Standard_Real U,V;
|
||||
InitialPoint(myCurve->Value(t), t, myCurve, mySurface, myTolU, myTolV, U, V);
|
||||
if (Abs (Abs(U - Triple.Y()) - mySurface->UPeriod()) < Precision::Confusion())
|
||||
{
|
||||
// Handle period jump.
|
||||
U = Triple.Y();
|
||||
}
|
||||
Triple.SetY(U);
|
||||
Triple.SetZ(V);
|
||||
}
|
||||
|
||||
if((Triple.X() - mySequence->Value(myNbCurves)->Value(mySequence->Value(myNbCurves)->Length()).X()) > 1.e-10)
|
||||
mySequence->Value(myNbCurves)->Append(Triple);
|
||||
if (t == LastU) {t = LastU + 1; break;}//return;
|
||||
@@ -854,7 +872,7 @@ void ProjLib_CompProjectedCurve::Init()
|
||||
Step = WalkStep;
|
||||
t += Step;
|
||||
if (t > (LastU-MinStep/2) )
|
||||
{
|
||||
{
|
||||
Step =Step+LastU-t;
|
||||
t = LastU;
|
||||
}
|
||||
|
@@ -332,6 +332,7 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C)
|
||||
Standard_Real LastPar = C->LastParameter();
|
||||
GeomAbs_SurfaceType SType = mySurface->GetType();
|
||||
GeomAbs_CurveType CType = myCurve->GetType();
|
||||
Standard_Boolean isAnalyticalSurf = Standard_True;
|
||||
|
||||
switch (SType)
|
||||
{
|
||||
@@ -384,6 +385,7 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C)
|
||||
case GeomAbs_BezierSurface:
|
||||
case GeomAbs_BSplineSurface:
|
||||
{
|
||||
isAnalyticalSurf = Standard_False;
|
||||
Standard_Boolean IsTrimmed[2] = {Standard_False, Standard_False};
|
||||
Standard_Integer SingularCase[2];
|
||||
Standard_Real f, l, dt;
|
||||
@@ -431,34 +433,38 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C)
|
||||
|
||||
Handle(Geom2d_BSplineCurve) aRes = polar.BSpline();
|
||||
|
||||
if(IsTrimmed[0] || IsTrimmed[1])
|
||||
if (!aRes.IsNull())
|
||||
{
|
||||
if(IsTrimmed[0])
|
||||
if( (IsTrimmed[0] || IsTrimmed[1]))
|
||||
{
|
||||
//Add segment before start of curve
|
||||
f = myCurve->FirstParameter();
|
||||
ExtendC2d(aRes, f, -dt, U1, U2, V1, V2, 0, SingularCase[0]);
|
||||
if(IsTrimmed[0])
|
||||
{
|
||||
//Add segment before start of curve
|
||||
f = myCurve->FirstParameter();
|
||||
ExtendC2d(aRes, f, -dt, U1, U2, V1, V2, 0, SingularCase[0]);
|
||||
}
|
||||
if(IsTrimmed[1])
|
||||
{
|
||||
//Add segment after end of curve
|
||||
l = myCurve->LastParameter();
|
||||
ExtendC2d(aRes, l, dt, U1, U2, V1, V2, 1, SingularCase[1]);
|
||||
}
|
||||
Handle(Geom2d_Curve) NewCurve2d;
|
||||
GeomLib::SameRange(Precision::PConfusion(), aRes,
|
||||
aRes->FirstParameter(), aRes->LastParameter(),
|
||||
FirstPar, LastPar, NewCurve2d);
|
||||
aRes = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve2d);
|
||||
}
|
||||
if(IsTrimmed[1])
|
||||
{
|
||||
//Add segment after end of curve
|
||||
l = myCurve->LastParameter();
|
||||
ExtendC2d(aRes, l, dt, U1, U2, V1, V2, 1, SingularCase[1]);
|
||||
}
|
||||
Handle(Geom2d_Curve) NewCurve2d;
|
||||
GeomLib::SameRange(Precision::PConfusion(), aRes,
|
||||
aRes->FirstParameter(), aRes->LastParameter(),
|
||||
FirstPar, LastPar, NewCurve2d);
|
||||
aRes = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve2d);
|
||||
myResult.SetBSpline(aRes);
|
||||
myResult.Done();
|
||||
myResult.SetType(GeomAbs_BSplineCurve);
|
||||
}
|
||||
myResult.SetBSpline(aRes);
|
||||
myResult.Done();
|
||||
myResult.SetType(GeomAbs_BSplineCurve);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
isAnalyticalSurf = Standard_False;
|
||||
Standard_Boolean IsTrimmed[2] = {Standard_False, Standard_False};
|
||||
Standard_Real Vsingular[2] = {0.0 , 0.0}; //for surfaces of revolution
|
||||
Standard_Real f = 0.0, l = 0.0, dt = 0.0;
|
||||
@@ -546,39 +552,44 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C)
|
||||
|
||||
Handle(Geom2d_BSplineCurve) aRes = appr.Curve2d();
|
||||
|
||||
if(IsTrimmed[0] || IsTrimmed[1])
|
||||
if (!aRes.IsNull())
|
||||
{
|
||||
// Treatment only for surface of revolution
|
||||
Standard_Real u1, u2, v1, v2;
|
||||
u1 = mySurface->FirstUParameter();
|
||||
u2 = mySurface->LastUParameter();
|
||||
v1 = mySurface->FirstVParameter();
|
||||
v2 = mySurface->LastVParameter();
|
||||
if(IsTrimmed[0] || IsTrimmed[1])
|
||||
{
|
||||
// Treatment only for surface of revolution
|
||||
Standard_Real u1, u2, v1, v2;
|
||||
u1 = mySurface->FirstUParameter();
|
||||
u2 = mySurface->LastUParameter();
|
||||
v1 = mySurface->FirstVParameter();
|
||||
v2 = mySurface->LastVParameter();
|
||||
|
||||
if(IsTrimmed[0])
|
||||
{
|
||||
//Add segment before start of curve
|
||||
ExtendC2d(aRes, f, -dt, u1, u2, Vsingular[0], v2, 0, 3);
|
||||
if(IsTrimmed[0])
|
||||
{
|
||||
//Add segment before start of curve
|
||||
ExtendC2d(aRes, f, -dt, u1, u2, Vsingular[0], v2, 0, 3);
|
||||
}
|
||||
if(IsTrimmed[1])
|
||||
{
|
||||
//Add segment after end of curve
|
||||
ExtendC2d(aRes, l, dt, u1, u2, v1, Vsingular[1], 1, 4);
|
||||
}
|
||||
Handle(Geom2d_Curve) NewCurve2d;
|
||||
GeomLib::SameRange(Precision::PConfusion(), aRes,
|
||||
aRes->FirstParameter(), aRes->LastParameter(),
|
||||
FirstPar, LastPar, NewCurve2d);
|
||||
aRes = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve2d);
|
||||
}
|
||||
if(IsTrimmed[1])
|
||||
{
|
||||
//Add segment after end of curve
|
||||
ExtendC2d(aRes, l, dt, u1, u2, v1, Vsingular[1], 1, 4);
|
||||
}
|
||||
Handle(Geom2d_Curve) NewCurve2d;
|
||||
GeomLib::SameRange(Precision::PConfusion(), aRes,
|
||||
aRes->FirstParameter(), aRes->LastParameter(),
|
||||
FirstPar, LastPar, NewCurve2d);
|
||||
aRes = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve2d);
|
||||
|
||||
myResult.SetBSpline(aRes);
|
||||
myResult.Done();
|
||||
myResult.SetType(GeomAbs_BSplineCurve);
|
||||
}
|
||||
|
||||
myResult.SetBSpline(aRes);
|
||||
myResult.Done();
|
||||
myResult.SetType(GeomAbs_BSplineCurve);
|
||||
}
|
||||
}
|
||||
if ( !myResult.IsDone())
|
||||
|
||||
if ( !myResult.IsDone() && isAnalyticalSurf)
|
||||
{
|
||||
// Use advanced analytical projector if base analytical projection failed.
|
||||
ProjLib_ComputeApprox Comp( myCurve, mySurface, myTolerance);
|
||||
myResult.Done();
|
||||
|
||||
@@ -602,8 +613,7 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C)
|
||||
}
|
||||
myTolerance = Comp.Tolerance();
|
||||
}
|
||||
|
||||
else
|
||||
else if (myResult.IsDone())
|
||||
{
|
||||
// On remet arbitrairement la tol atteinte a une valeur
|
||||
// petite en attendant mieux. dub lbo 11/03/97
|
||||
|
@@ -29,6 +29,8 @@
|
||||
|
||||
ProjLib_Projector::ProjLib_Projector()
|
||||
{
|
||||
isDone = Standard_False;
|
||||
myType = GeomAbs_BSplineCurve;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user