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

CEVT-06-001 : Projection algorithm improvement to ensure imprinting of a curve on surface

Adaptation for OCCT7.1.0 of commit for CR28909
This commit is contained in:
ifv
2017-09-26 16:27:03 +03:00
parent 2fe71c547a
commit 1e34ad2459
13 changed files with 838 additions and 210 deletions

View File

@@ -50,6 +50,7 @@ Approx_ComputeCLine::Approx_ComputeCLine
mycut = cutting;
myfirstC = FirstC;
mylastC = LastC;
myMaxSegments = IntegerLast();
alldone = Standard_False;
Perform(Line);
}
@@ -76,6 +77,7 @@ Approx_ComputeCLine::Approx_ComputeCLine
mycut = cutting;
myfirstC = FirstC;
mylastC = LastC;
myMaxSegments = IntegerLast();
}
//=======================================================================
@@ -91,9 +93,11 @@ void Approx_ComputeCLine::Perform(const MultiLine& Line)
Standard_Real thetol3d = Precision::Confusion(), thetol2d = Precision::Confusion();
UFirst = Line.FirstParameter();
ULast = Line.LastParameter();
Standard_Real TolU = (ULast-UFirst)*1.e-05;
Standard_Real TolU = Max((ULast-UFirst)*1.e-05, Precision::PApproximation());
Standard_Real myfirstU = UFirst;
Standard_Real mylastU = ULast;
Standard_Integer aMaxSegments = 0;
Standard_Integer aMaxSegments1 = myMaxSegments - 1;
if (!mycut)
{
@@ -126,7 +130,8 @@ void Approx_ComputeCLine::Perform(const MultiLine& Line)
// Calcul de la partie a approximer.
myfirstU = mylastU;
mylastU = ULast;
if (Abs(ULast-myfirstU) <= RealEpsilon())
if (Abs(ULast-myfirstU) <= RealEpsilon()
|| aMaxSegments >= myMaxSegments)
{
Finish = Standard_True;
alldone = Standard_True;
@@ -155,11 +160,15 @@ void Approx_ComputeCLine::Perform(const MultiLine& Line)
// Calcul des parametres sur ce nouvel intervalle.
Ok = Compute(Line, myfirstU, mylastU, thetol3d, thetol2d);
if(Ok)
{
aMaxSegments++;
}
//cout << myfirstU << " - " << mylastU << " tol : " << thetol3d << " " << thetol2d << endl;
// is new decision better?
if (!Ok && Abs(myfirstU-mylastU) <= TolU)
if (!Ok && (Abs(myfirstU-mylastU) <= TolU || aMaxSegments >= aMaxSegments1))
{
Ok = Standard_True; // stop interval cutting, approx the rest part
@@ -176,6 +185,7 @@ void Approx_ComputeCLine::Perform(const MultiLine& Line)
tolreached = Standard_False; // helas
myMultiCurves.Append(KeptMultiCurve);
aMaxSegments++;
Tolers3d.Append (KeptT3d);
Tolers2d.Append (KeptT2d);
myfirstparam.Append (KeptUfirst);
@@ -303,6 +313,16 @@ void Approx_ComputeCLine::SetConstraints(const AppParCurves_Constraint FirstC,
mylastC = LastC;
}
//=======================================================================
//function : SetMaxSegments
//purpose : Changes the max number of segments, which is allowed for cutting.
//=======================================================================
void Approx_ComputeCLine:: SetMaxSegments(const Standard_Integer theMaxSegments)
{
myMaxSegments = theMaxSegments;
}
//=======================================================================
//function : IsAllApproximated
//purpose : returns False if at a moment of the approximation,

View File

@@ -61,6 +61,9 @@ public:
//! Changes the constraints of the approximation.
Standard_EXPORT void SetConstraints (const AppParCurves_Constraint FirstC, const AppParCurves_Constraint LastC);
//! Changes the max number of segments, which is allowed for cutting.
Standard_EXPORT void SetMaxSegments (const Standard_Integer theMaxSegments);
//! returns False if at a moment of the approximation,
//! the status NoApproximation has been sent by the user
//! when more points were needed.
@@ -114,6 +117,7 @@ private:
Standard_Boolean mycut;
AppParCurves_Constraint myfirstC;
AppParCurves_Constraint mylastC;
Standard_Integer myMaxSegments;
};

View File

@@ -61,6 +61,9 @@ public:
//! Changes the constraints of the approximation.
Standard_EXPORT void SetConstraints (const AppParCurves_Constraint FirstC, const AppParCurves_Constraint LastC);
//! Changes the max number of segments, which is allowed for cutting.
Standard_EXPORT void SetMaxSegments (const Standard_Integer theMaxSegments);
//! returns False if at a moment of the approximation,
//! the status NoApproximation has been sent by the user
//! when more points were needed.
@@ -114,6 +117,7 @@ private:
Standard_Boolean mycut;
AppParCurves_Constraint myfirstC;
AppParCurves_Constraint mylastC;
Standard_Integer myMaxSegments;
};

View File

@@ -57,6 +57,7 @@
#include <IntTools_Tools.hxx>
#include <Precision.hxx>
#include <ProjLib_ProjectedCurve.hxx>
#include <ProjLib.hxx>
#include <Standard_ConstructionError.hxx>
#include <Standard_NotImplemented.hxx>
#include <TopExp.hxx>
@@ -64,6 +65,7 @@
#include <TopLoc_Location.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <AppParCurves_Constraint.hxx>
static
Standard_Boolean CheckEdgeLength (const TopoDS_Edge& );
@@ -626,6 +628,9 @@ void BOPTools_AlgoTools2D::MakePCurveOnFace
aBAHS=new GeomAdaptor_HSurface(aGAS);
aBAHC=new GeomAdaptor_HCurve(aC3D, aT1, aT2);
//
Standard_Real aTR = Precision::Confusion();//1.e-7;
Standard_Real aMaxTol = 1.e3 * aTR; //0.0001
Standard_Boolean isAnaSurf = ProjLib::IsAnaSurf(aBAHS);
//when the type of surface is GeomAbs_SurfaceOfRevolution
if (aGAS.GetType() == GeomAbs_SurfaceOfRevolution) {
Standard_Real aTR;
@@ -640,27 +645,42 @@ void BOPTools_AlgoTools2D::MakePCurveOnFace
aTolR = aProj1.GetTolerance();
}
else {
Standard_Real aTR = Precision::Confusion();//1.e-7;
if (TolReached2d > aTR) {
aTR = Min(0.0001, Max(.01 * TolReached2d, aTR));
ProjLib_ProjectedCurve aProjCurv(aBAHS);
Standard_Integer aDegMin = -1, aDegMax = -1, aMaxSegments = -1;
Standard_Real aMaxDist = -1;
AppParCurves_Constraint aBndPnt = AppParCurves_NoConstraint;
if ((TolReached2d >= 10. * aTR) && (TolReached2d <= aMaxTol || isAnaSurf))
{
aTR = Min(aMaxTol, 0.1*TolReached2d);
aMaxSegments = 100;
aMaxDist = 1.e3*TolReached2d;
if (!isAnaSurf)
{
aBndPnt = AppParCurves_PassPoint;
}
}
ProjLib_ProjectedCurve aProjCurv(aBAHS, aBAHC, aTR);// 1
BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurv, aC2D);
else if (TolReached2d > aMaxTol)
{
aTR = Min(TolReached2d, 1.e3 * aMaxTol);
aMaxDist = 1.e2 * aTR;
aMaxSegments = 100;
}
aProjCurv.Load(aTR);
aProjCurv.SetDegree(aDegMin, aDegMax);
aProjCurv.SetMaxSegments(aMaxSegments);
aProjCurv.SetBndPnt(aBndPnt);
aProjCurv.SetMaxDist(aMaxDist);
aProjCurv.Perform(aBAHC);
ProjLib::MakePCurveOfType(aProjCurv, aC2D);
aTolR = aProjCurv.GetTolerance();
}
//
if (aC2D.IsNull()) {
ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, TolReached2d);// 2
BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurvAgain, aC2D);
if (aC2D.IsNull() && (aTR < aMaxTol || aTR < TolReached2d))
{
aTR = Max(TolReached2d, aMaxTol);
ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, aTR);// 2
ProjLib::MakePCurveOfType(aProjCurvAgain, aC2D);
aTolR = aProjCurvAgain.GetTolerance();
//
if (aC2D.IsNull()) {
Standard_Real aTR=0.0001;
ProjLib_ProjectedCurve aProj3(aBAHS, aBAHC, aTR);// 3
BOPTools_AlgoTools2D::MakePCurveOfType(aProj3, aC2D);
aTolR = aProj3.GetTolerance();
}
}
//
if(aC2D.IsNull())

View File

@@ -61,6 +61,9 @@ public:
//! Changes the constraints of the approximation.
Standard_EXPORT void SetConstraints (const AppParCurves_Constraint FirstC, const AppParCurves_Constraint LastC);
//! Changes the max number of segments, which is allowed for cutting.
Standard_EXPORT void SetMaxSegments (const Standard_Integer theMaxSegments);
//! returns False if at a moment of the approximation,
//! the status NoApproximation has been sent by the user
//! when more points were needed.
@@ -114,7 +117,7 @@ private:
Standard_Boolean mycut;
AppParCurves_Constraint myfirstC;
AppParCurves_Constraint mylastC;
Standard_Integer myMaxSegments;
};

View File

@@ -39,6 +39,16 @@
#include <ProjLib_Plane.hxx>
#include <ProjLib_Sphere.hxx>
#include <ProjLib_Torus.hxx>
#include <ProjLib_ProjectedCurve.hxx>
#include <Geom2d_Line.hxx>
#include <Geom2d_Circle.hxx>
#include <Geom2d_Ellipse.hxx>
#include <Geom2d_Parabola.hxx>
#include <Geom2d_Hyperbola.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <Geom2d_BezierCurve.hxx>
#include <Standard_NotImplemented.hxx>
#include <Adaptor3d_HSurface.hxx>
//=======================================================================
//function : Project
@@ -234,3 +244,63 @@ gp_Lin2d ProjLib::Project(const gp_Torus& To, const gp_Circ& Ci)
ProjLib_Torus Proj( To, Ci);
return Proj.Line();
}
//=======================================================================
//function : MakePCurveOfType
//purpose :
//=======================================================================
void ProjLib::MakePCurveOfType
(const ProjLib_ProjectedCurve& PC,
Handle(Geom2d_Curve)& C2D)
{
switch (PC.GetType()) {
case GeomAbs_Line :
C2D = new Geom2d_Line(PC.Line());
break;
case GeomAbs_Circle :
C2D = new Geom2d_Circle(PC.Circle());
break;
case GeomAbs_Ellipse :
C2D = new Geom2d_Ellipse(PC.Ellipse());
break;
case GeomAbs_Parabola :
C2D = new Geom2d_Parabola(PC.Parabola());
break;
case GeomAbs_Hyperbola :
C2D = new Geom2d_Hyperbola(PC.Hyperbola());
break;
case GeomAbs_BSplineCurve :
C2D = PC.BSpline();
break;
case GeomAbs_BezierCurve :
case GeomAbs_OtherCurve :
default :
Standard_NotImplemented::Raise
("ProjLib::MakePCurveOfType");
break;
}
}
//=======================================================================
//function : IsAnaSurf
//purpose :
//=======================================================================
Standard_Boolean ProjLib::IsAnaSurf
(const Handle(Adaptor3d_HSurface)& theAS)
{
switch (theAS->GetType())
{
case GeomAbs_Plane:
case GeomAbs_Cylinder:
case GeomAbs_Cone:
case GeomAbs_Sphere:
case GeomAbs_Torus:
return Standard_True;
break;
default :
return Standard_False;
break;
}
}

View File

@@ -20,6 +20,7 @@
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
#include <Geom2d_Curve.hxx>
class gp_Pnt2d;
class gp_Pln;
@@ -54,7 +55,7 @@ class ProjLib_Cylinder;
class ProjLib_Cone;
class ProjLib_Sphere;
class ProjLib_Torus;
class Adaptor3d_HSurface;
//! The projLib package first provides projection of
//! curves on a plane along a given Direction. The
@@ -128,6 +129,15 @@ public:
Standard_EXPORT static gp_Lin2d Project (const gp_Torus& To, const gp_Circ& Ci);
//! Make empty P-Curve <aC> of relevant to <PC> type
Standard_EXPORT static void MakePCurveOfType (const ProjLib_ProjectedCurve& PC,
Handle(Geom2d_Curve)& aC);
//! Returns "true" if surface is analytical, that is it can be
//! Plane, Cylinder, Cone, Sphere, Torus.
//! For all other types of surface method returns "false".
Standard_EXPORT static Standard_Boolean IsAnaSurf
(const Handle(Adaptor3d_HSurface)& theAS);

View File

@@ -17,6 +17,7 @@
// modified by NIZHNY-OFV Thu Jan 20 11:04:19 2005
#include <ProjLib_ComputeApprox.hxx>
#include <ProjLib.hxx>
#include <GeomAbs_SurfaceType.hxx>
#include <GeomAbs_CurveType.hxx>
@@ -42,6 +43,7 @@
#include <Geom_BezierCurve.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <Geom2d_BezierCurve.hxx>
#include <GCPnts_AbscissaPoint.hxx>
//#define DRAW
#ifdef DRAW
@@ -115,7 +117,7 @@ static gp_Pnt2d Function_Value(const Standard_Real U,
break;
}
default:
Standard_NoSuchObject::Raise("ProjLib_ComputeApprox::Value");
throw Standard_NoSuchObject("ProjLib_ComputeApprox::Value");
}
if ( UCouture) {
@@ -195,7 +197,33 @@ static Standard_Boolean Function_D1( const Standard_Real U,
return Standard_True;
}
//=======================================================================
//function : Function_ComputeStep
//purpose :
//=======================================================================
static Standard_Real Function_ComputeStep(
const Handle(Adaptor3d_HCurve)& myCurve,
const Standard_Real R)
{
Standard_Real Step0 = .1;
Standard_Real W1, W2;
W1 = myCurve->FirstParameter();
W2 = myCurve->LastParameter();
Standard_Real L = GCPnts_AbscissaPoint::Length(myCurve->Curve());
Standard_Integer nbp = RealToInt(L / (R*M_PI_4)) + 1;
nbp = Max(nbp, 3);
Standard_Real Step = (W2 - W1) / (nbp - 1);
if (Step > Step0)
{
Step = Step0;
nbp = RealToInt((W2 - W1) / Step) + 1;
nbp = Max(nbp, 3);
Step = (W2 - W1) / (nbp - 1);
}
return Step;
}
//=======================================================================
//function : Function_SetUVBounds
//purpose :
@@ -272,15 +300,21 @@ static void Function_SetUVBounds(Standard_Real& myU1,
Standard_Real U1, V1, U , V, Delta = 0., d = 0., pmin = W1, pmax = W1, dmax = 0., Uf, Ul;
ElSLib::Parameters( Cone, P1, U1, V1);
ElSLib::Parameters( Cone, P2, Ul, V1);
const gp_Ax1& anAx1 = Cone.Axis();
gp_Lin aLin(anAx1);
Standard_Real R = (aLin.Distance(P1) + aLin.Distance(P2) + aLin.Distance(P)) / 3.;
Standard_Real Step;
myU1 = U1; myU2 = U1; Uf = U1;
Standard_Real Step = .1;
Standard_Integer nbp = (Standard_Integer)((W2 - W1) / Step + 1);
if(myCurve->GetType() == GeomAbs_Line)
if (myCurve->GetType() == GeomAbs_Line)
{
nbp = 3;
Standard_Integer nbp = 3;
Step = (W2 - W1) / (nbp - 1);
}
nbp = Max(nbp, 3);
Step = (W2 - W1) / (nbp - 1);
else
{
Step = Function_ComputeStep(myCurve, R);
}
//
Standard_Boolean isclandper = (!(myCurve->IsClosed()) && !(myCurve->IsPeriodic()));
Standard_Boolean isFirst = Standard_True;
for(Standard_Real par = W1 + Step; par <= W2; par += Step)
@@ -402,11 +436,10 @@ static void Function_SetUVBounds(Standard_Real& myU1,
else {
Standard_Real U1, V1, U , V;
ElSLib::Parameters( Cylinder, P1, U1, V1);
Standard_Real Step = .1, Delta = 0.;
Standard_Real R = Cylinder.Radius();
Standard_Real Delta = 0., Step;
Standard_Real eps = M_PI, dmax = 0., d = 0.;
Standard_Integer nbp = (Standard_Integer)((W2 - W1) / Step + 1);
nbp = Max(nbp, 3);
Step = (W2 - W1) / (nbp - 1);
Step = Function_ComputeStep(myCurve, R);
myU1 = U1; myU2 = U1;
Standard_Real pmin = W1, pmax = W1, plim = W2+.1*Step;
for(Standard_Real par = W1 + Step; par <= plim; par += Step) {
@@ -655,11 +688,10 @@ static void Function_SetUVBounds(Standard_Real& myU1,
else {
Standard_Real U1, V1, U , V;
ElSLib::Parameters( SP, P1, U1, V1);
Standard_Real Step = .1, Delta = 0.;
Standard_Real R = SP.Radius();
Standard_Real Delta = 0., Step;
Standard_Real eps = M_PI, dmax = 0., d = 0.;
Standard_Integer nbp = (Standard_Integer)((W2 - W1) / Step + 1);
nbp = Max(nbp, 3);
Step = (W2 - W1) / (nbp - 1);
Step = Function_ComputeStep(myCurve, R);
myU1 = U1; myU2 = U1;
Standard_Real pmin = W1, pmax = W1, plim = W2+.1*Step;
for(Standard_Real par = W1 + Step; par <= plim; par += Step) {
@@ -710,13 +742,12 @@ static void Function_SetUVBounds(Standard_Real& myU1,
//
case GeomAbs_Torus:{
gp_Torus TR = mySurface->Torus();
Standard_Real U1, V1, U , V;
Standard_Real U1, V1, U , V, dU, dV;
ElSLib::Parameters( TR, P1, U1, V1);
Standard_Real Step = .1, DeltaU = 0., DeltaV = 0.;
Standard_Real eps = M_PI, dmaxU = 0., dU = 0., dmaxV = 0., dV = 0.;
Standard_Integer nbp = (Standard_Integer)((W2 - W1) / Step + 1);
nbp = Max(nbp, 3);
Step = (W2 - W1) / (nbp - 1);
Standard_Real R = TR.MinorRadius();
Standard_Real DeltaU = 0., DeltaV = 0., Step;
Standard_Real eps = M_PI, dmaxU = 0., dmaxV = 0.;
Step = Function_ComputeStep(myCurve, R);
myU1 = U1; myU2 = U1;
myV1 = V1; myV2 = V1;
Standard_Real pminU = W1, pmaxU = W1, pminV = W1, pmaxV = W1,
@@ -926,6 +957,18 @@ static Standard_Real ComputeTolV(const Handle(Adaptor3d_HSurface)& theSurf,
return aTolV;
}
//=======================================================================
//function : ProjLib_ComputeApprox
//purpose :
//=======================================================================
ProjLib_ComputeApprox::ProjLib_ComputeApprox():
myTolerance(Precision::PApproximation()),
myDegMin(-1), myDegMax(-1),
myMaxSegments(-1),
myBndPnt(AppParCurves_TangencyPoint)
{
}
//=======================================================================
//function : ProjLib_ComputeApprox
@@ -935,19 +978,32 @@ static Standard_Real ComputeTolV(const Handle(Adaptor3d_HSurface)& theSurf,
ProjLib_ComputeApprox::ProjLib_ComputeApprox
(const Handle(Adaptor3d_HCurve) & C,
const Handle(Adaptor3d_HSurface) & S,
const Standard_Real Tol )
const Standard_Real Tol):
myTolerance(Max(Tol, Precision::PApproximation())),
myDegMin(-1), myDegMax(-1),
myMaxSegments(-1),
myBndPnt(AppParCurves_TangencyPoint)
{
Perform(C, S);
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void ProjLib_ComputeApprox::Perform
(const Handle(Adaptor3d_HCurve) & C,
const Handle(Adaptor3d_HSurface) & S )
{
// if the surface is a plane and the curve a BSpline or a BezierCurve,
// don`t make an Approx but only the projection of the poles.
myTolerance = Max(Precision::PApproximation(),Tol);
Standard_Integer NbKnots, NbPoles ;
GeomAbs_CurveType CType = C->GetType();
GeomAbs_SurfaceType SType = S->GetType();
Standard_Boolean SurfIsAnal = (SType != GeomAbs_BSplineSurface) &&
(SType != GeomAbs_BezierSurface) &&
(SType != GeomAbs_OtherSurface) ;
Standard_Boolean SurfIsAnal = ProjLib::IsAnaSurf(S);
Standard_Boolean CurvIsAnal = (CType != GeomAbs_BSplineCurve) &&
(CType != GeomAbs_BezierCurve) &&
@@ -1055,21 +1111,43 @@ ProjLib_ComputeApprox::ProjLib_ComputeApprox
#endif
//-----------
Standard_Integer Deg1, Deg2;
Standard_Integer Deg1 = 8, Deg2;
if(simplecase) {
Deg1 = 8;
Deg2 = 10;
}
else {
Deg1 = 8;
Deg2 = 12;
}
if(myDegMin > 0)
{
Deg1 = myDegMin;
}
//
if(myDegMax > 0)
{
Deg2 = myDegMax;
}
//
Standard_Integer aMaxSegments = 1000;
if(myMaxSegments > 0)
{
aMaxSegments = myMaxSegments;
}
AppParCurves_Constraint aFistC = AppParCurves_TangencyPoint, aLastC = AppParCurves_TangencyPoint;
if(myBndPnt != AppParCurves_TangencyPoint)
{
aFistC = myBndPnt;
aLastC = myBndPnt;
}
//-------------
const Standard_Real aTolU = ComputeTolU(S, myTolerance);
const Standard_Real aTolV = ComputeTolV(S, myTolerance);
const Standard_Real aTol2d = Max(Sqrt(aTolU*aTolU + aTolV*aTolV), Precision::PConfusion());
Approx_FitAndDivide2d Fit(F, Deg1, Deg2, myTolerance, aTol2d, Standard_True);
Approx_FitAndDivide2d Fit(Deg1, Deg2, myTolerance, aTol2d, Standard_True, aFistC, aLastC);
Fit.SetMaxSegments(aMaxSegments);
Fit.Perform(F);
Standard_Real aNewTol2d = 0;
if(Fit.IsAllApproximated()) {
@@ -1086,7 +1164,6 @@ ProjLib_ComputeApprox::ProjLib_ComputeApprox
AppParCurves_MultiCurve MC = Fit.Value( i); //Charge la Ieme Curve
TColgp_Array1OfPnt2d Poles2d( 1, MC.Degree() + 1);//Recupere les poles
MC.Curve(1, Poles2d);
Conv.AddCurve(Poles2d);
}
@@ -1111,13 +1188,6 @@ ProjLib_ComputeApprox::ProjLib_ComputeApprox
C->LastParameter(),
NewKnots);
/*cout << endl;
for (int i = 1; i <= NbPoles; i++)
{
cout << NewPoles.Value(i).X() << " " << NewPoles.Value(i).Y() << endl;
}
cout << endl; */
// il faut recadrer les poles de debut et de fin:
// ( Car pour les problemes de couture, on a du ouvrir l`intervalle
// de definition de la courbe.)
@@ -1127,6 +1197,17 @@ ProjLib_ComputeApprox::ProjLib_ComputeApprox
NewKnots,
NewMults,
Conv.Degree());
if(aFistC == AppParCurves_PassPoint || aLastC == AppParCurves_PassPoint)
{
// try to smoother the Curve GeomAbs_C1.
Standard_Integer aDeg = myBSpline->Degree();
Standard_Boolean OK = Standard_True;
Standard_Real aSmoothTol = Max(Precision::Confusion(), aNewTol2d);
for (Standard_Integer ij = 2; ij < NbKnots; ij++) {
OK = OK && myBSpline->RemoveKnot(ij, aDeg-1, aSmoothTol);
}
}
}
else {
Standard_Integer NbCurves = Fit.NbMultiCurves();
@@ -1183,7 +1264,7 @@ ProjLib_ComputeApprox::ProjLib_ComputeApprox
break;
}
default:
Standard_NoSuchObject::Raise("ProjLib_ComputeApprox::Value");
throw Standard_NoSuchObject("ProjLib_ComputeApprox::Value");
}
Standard_Boolean ToMirror = Standard_False;
Standard_Real du = 0., dv = 0.;
@@ -1224,6 +1305,42 @@ ProjLib_ComputeApprox::ProjLib_ComputeApprox
}
}
}
//=======================================================================
//function : SetTolerance
//purpose :
//=======================================================================
void ProjLib_ComputeApprox::SetTolerance(const Standard_Real theTolerance)
{
myTolerance = theTolerance;
}
//=======================================================================
//function : SetDegree
//purpose :
//=======================================================================
void ProjLib_ComputeApprox::SetDegree(const Standard_Integer theDegMin,
const Standard_Integer theDegMax)
{
myDegMin = theDegMin;
myDegMax = theDegMax;
}
//=======================================================================
//function : SetMaxSegments
//purpose :
//=======================================================================
void ProjLib_ComputeApprox::SetMaxSegments(const Standard_Integer theMaxSegments)
{
myMaxSegments = theMaxSegments;
}
//=======================================================================
//function : SetBndPnt
//purpose :
//=======================================================================
void ProjLib_ComputeApprox::SetBndPnt(const AppParCurves_Constraint theBndPnt)
{
myBndPnt = theBndPnt;
}
//=======================================================================
//function : BSpline

View File

@@ -22,6 +22,8 @@
#include <Standard_Handle.hxx>
#include <Standard_Real.hxx>
#include <AppParCurves_Constraint.hxx>
class Geom2d_BSplineCurve;
class Geom2d_BezierCurve;
class Adaptor3d_HCurve;
@@ -31,17 +33,51 @@ class Adaptor3d_HSurface;
//! Approximate the projection of a 3d curve on an
//! analytic surface and stores the result in Approx.
//! The result is a 2d curve.
//! For approximation some parameters are used, including
//! required tolerance of approximation.
//! Tolerance is maximal possible value of 3d deviation of 3d projection of projected curve from
//! "exact" 3d projection. Since algorithm searches 2d curve on surface, required 2d tolerance is computed
//! from 3d tolerance with help of U,V resolutions of surface.
//! 3d and 2d tolerances have sence only for curves on surface, it defines precision of projecting and approximation
//! and have nothing to do with distance between the projected curve and the surface.
class ProjLib_ComputeApprox
{
public:
DEFINE_STANDARD_ALLOC
//! Empty constructor, it only sets some initial values for class fields.
Standard_EXPORT ProjLib_ComputeApprox();
//! <Tol> is the tolerance with which the
//! approximation is performed.
//! Other parameters for approximation have default values.
Standard_EXPORT ProjLib_ComputeApprox(const Handle(Adaptor3d_HCurve)& C, const Handle(Adaptor3d_HSurface)& S, const Standard_Real Tol);
//! Performs projecting.
//! In case of approximation current values of parameters are used:
//! default values or set by corresponding methods Set...
Standard_EXPORT void Perform(const Handle(Adaptor3d_HCurve)& C, const Handle(Adaptor3d_HSurface)& S);
//! Set tolerance of approximation.
//! Default value is Precision::Confusion().
Standard_EXPORT void SetTolerance(const Standard_Real theTolerance);
//! Set min and max possible degree of result BSpline curve2d, which is got by approximation.
//! If theDegMin/Max < 0, algorithm uses values that are chosen depending of types curve 3d
//! and surface.
Standard_EXPORT void SetDegree(const Standard_Integer theDegMin, const Standard_Integer theDegMax);
//! Set the parameter, which defines maximal value of parametric intervals the projected
//! curve can be cut for approximation. If theMaxSegments < 0, algorithm uses default
//! value = 1000.
Standard_EXPORT void SetMaxSegments(const Standard_Integer theMaxSegments);
//! Set the parameter, which defines type of boundary condition between segments during approximation.
//! It can be AppParCurves_PassPoint or AppParCurves_TangencyPoint.
//! Default value is AppParCurves_TangencyPoint;
Standard_EXPORT void SetBndPnt(const AppParCurves_Constraint theBndPnt);
Standard_EXPORT Handle(Geom2d_BSplineCurve) BSpline() const;
Standard_EXPORT Handle(Geom2d_BezierCurve) Bezier() const;
@@ -60,12 +96,13 @@ protected:
private:
Standard_Real myTolerance;
Handle(Geom2d_BSplineCurve) myBSpline;
Handle(Geom2d_BezierCurve) myBezier;
Standard_Integer myDegMin;
Standard_Integer myDegMax;
Standard_Integer myMaxSegments;
AppParCurves_Constraint myBndPnt;
};

View File

@@ -284,7 +284,7 @@ static gp_Pnt2d Function_Value(const Standard_Real theU,
break;
}
default:
Standard_NoSuchObject::Raise("ProjLib_ComputeApproxOnPolarSurface::Value");
throw Standard_NoSuchObject("ProjLib_ComputeApproxOnPolarSurface::Value");
}
return gp_Pnt2d(S, T);
}
@@ -363,7 +363,7 @@ static gp_Pnt2d Function_Value(const Standard_Real theU,
}
else
{
Standard_NoSuchObject::Raise("");
throw Standard_NoSuchObject ("ProjLib_ComputeApproxOnPolarSurface::ProjectUsingInitialCurve2d() - unknown surface type");
}
// Try to run simple search with initial point (U0, V0).
@@ -477,11 +477,15 @@ class ProjLib_PolarFunction : public AppCont_Function
ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface()
: myProjIsDone(Standard_False),
myTolerance (-1.0)
myTolerance(Precision::Approximation()),
myTolReached(-1.0),
myDegMin(-1), myDegMax(-1),
myMaxSegments(-1),
myMaxDist(-1.),
myBndPnt(AppParCurves_TangencyPoint)
{
}
//=======================================================================
//function : ProjLib_ComputeApproxOnPolarSurface
//purpose :
@@ -493,10 +497,37 @@ ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface
const Handle(Adaptor3d_HSurface)& theSurface,
const Standard_Real theTolerance3D)
: myProjIsDone(Standard_False),
myTolerance (theTolerance3D)
myTolerance(theTolerance3D),
myTolReached(-1.0),
myDegMin(-1), myDegMax(-1),
myMaxSegments(-1),
myMaxDist(-1.),
myBndPnt(AppParCurves_TangencyPoint)
{
myBSpline = Perform(theInitialCurve2d, theCurve, theSurface);
}
//=======================================================================
//function : ProjLib_ComputeApproxOnPolarSurface
//purpose : case without curve of initialization
//=======================================================================
ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface
(const Handle(Adaptor3d_HCurve)& theCurve,
const Handle(Adaptor3d_HSurface)& theSurface,
const Standard_Real theTolerance3D)
: myProjIsDone(Standard_False),
myTolerance(theTolerance3D),
myTolReached(-1.0),
myDegMin(-1), myDegMax(-1),
myMaxSegments(-1),
myMaxDist(-1.),
myBndPnt(AppParCurves_TangencyPoint)
{
const Handle(Adaptor2d_HCurve2d) anInitCurve2d;
myBSpline = Perform(anInitCurve2d, theCurve, theSurface);
}
//=======================================================================
//function : ProjLib_ComputeApproxOnPolarSurface
//purpose : Process the case of sewing
@@ -509,7 +540,12 @@ ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface
const Handle(Adaptor3d_HSurface)& theSurface,
const Standard_Real theTolerance3D)
: myProjIsDone(Standard_False),
myTolerance (theTolerance3D)
myTolerance(theTolerance3D),
myTolReached(-1.0),
myDegMin(-1), myDegMax(-1),
myMaxSegments(-1),
myMaxDist(-1.),
myBndPnt(AppParCurves_TangencyPoint)
{
// InitialCurve2d and InitialCurve2dBis are two pcurves of the sewing
Handle(Geom2d_BSplineCurve) bsc =
@@ -538,21 +574,6 @@ ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface
}
}
//=======================================================================
//function : ProjLib_ComputeApproxOnPolarSurface
//purpose : case without curve of initialization
//=======================================================================
ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface
(const Handle(Adaptor3d_HCurve)& theCurve,
const Handle(Adaptor3d_HSurface)& theSurface,
const Standard_Real theTolerance3D)
: myProjIsDone(Standard_False),
myTolerance (theTolerance3D)
{
const Handle(Adaptor2d_HCurve2d) anInitCurve2d;
myBSpline = Perform(anInitCurve2d, theCurve, theSurface);
}
//=======================================================================
//function : Concat
@@ -628,11 +649,23 @@ static Handle(Geom2d_BSplineCurve) Concat(Handle(Geom2d_BSplineCurve) C1,
return BS;
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void ProjLib_ComputeApproxOnPolarSurface::Perform
(const Handle(Adaptor3d_HCurve)& Curve, const Handle(Adaptor3d_HSurface)& S)
{
const Handle(Adaptor2d_HCurve2d) anInitCurve2d;
myBSpline = Perform(anInitCurve2d, Curve, S);
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
Handle(Geom2d_BSplineCurve) ProjLib_ComputeApproxOnPolarSurface::Perform
(const Handle(Adaptor2d_HCurve2d)& InitialCurve2d,
const Handle(Adaptor3d_HCurve)& Curve,
@@ -753,7 +786,10 @@ Handle(Geom2d_BSplineCurve) ProjLib_ComputeApproxOnPolarSurface::Perform
if(myProjIsDone) {
BSC2d = ProjectUsingInitialCurve2d(AHC, S, AHC2d);
if(BSC2d.IsNull()) return Handle(Geom2d_BSplineCurve)(); //IFV
if(BSC2d.IsNull())
{
return Handle(Geom2d_BSplineCurve)();
}
LOfBSpline2d.Append(BSC2d);
}
else {
@@ -857,6 +893,7 @@ Handle(Geom2d_BSplineCurve) ProjLib_ComputeApproxOnPolarSurface::Perform
return ProjectUsingInitialCurve2d(AHC, S, AHC2d);
}
//=======================================================================
//function : ProjLib_BuildInitialCurve2d
//purpose :
@@ -875,7 +912,11 @@ Handle(Adaptor2d_HCurve2d)
Standard_Real Tol3d = myTolerance;
Standard_Real TolU = Surf->UResolution(Tol3d), TolV = Surf->VResolution(Tol3d);
Standard_Real DistTol3d = 100.0*Tol3d;
if(myMaxDist > 0.)
{
DistTol3d = myMaxDist;
}
Standard_Real DistTol3d2 = DistTol3d * DistTol3d;
Standard_Real uperiod = 0.0, vperiod = 0.0;
computePeriodicity(Surf, uperiod, vperiod);
@@ -885,6 +926,7 @@ Handle(Adaptor2d_HCurve2d)
Standard_Integer NbOfPnts = 61;
GCPnts_QuasiUniformAbscissa QUA(Curve->GetCurve(),NbOfPnts);
NbOfPnts = QUA.NbPoints();
TColgp_Array1OfPnt Pts(1,NbOfPnts);
TColStd_Array1OfReal Param(1,NbOfPnts);
Standard_Integer i, j;
@@ -1031,7 +1073,7 @@ Handle(Adaptor2d_HCurve2d)
break;
}
default:
Standard_NoSuchObject::Raise("ProjLib_ComputeApproxOnPolarSurface::BuildInitialCurve2d");
throw Standard_NoSuchObject("ProjLib_ComputeApproxOnPolarSurface::BuildInitialCurve2d");
}
}
else {
@@ -1054,7 +1096,7 @@ Handle(Adaptor2d_HCurve2d)
aMinSqDist = aSqDist;
}
}
if (aMinSqDist > DistTol3d * DistTol3d) //try to project with less tolerance
if (aMinSqDist > DistTol3d2) //try to project with less tolerance
{
TolU = Min(TolU, Precision::PConfusion());
TolV = Min(TolV, Precision::PConfusion());
@@ -1070,7 +1112,7 @@ Handle(Adaptor2d_HCurve2d)
Standard_Integer GoodValue = 1;
for ( i = 1 ; i <= aExtPS.NbExt() ; i++ ) {
if( aExtPS.SquareDistance(i) < DistTol3d * DistTol3d ) {
if( aExtPS.SquareDistance(i) < DistTol3d2 ) {
if( aExtPS.SquareDistance(i) <= 1.e-18 ) {
aExtPS.Point(i).Parameter(u,v);
gp_Pnt2d p2d(u,v);
@@ -1092,7 +1134,7 @@ Handle(Adaptor2d_HCurve2d)
if( Sols.Length() > 1 ) areManyZeros = Standard_True;
if( Dist2Min <= DistTol3d * DistTol3d) {
if( Dist2Min <= DistTol3d2) {
if( !areManyZeros ) {
aExtPS.Point(GoodValue).Parameter(u,v);
Pts2d(1).SetCoord(u,v);
@@ -1122,7 +1164,7 @@ Handle(Adaptor2d_HCurve2d)
Dist2Min = 1.e+200;
if( aTPS.IsDone() && aTPS.NbExt() >= 1 ) {
for( j = 1 ; j <= aTPS.NbExt() ; j++ ) {
if( aTPS.SquareDistance(j) < DistTol3d * DistTol3d ) {
if( aTPS.SquareDistance(j) < DistTol3d2 ) {
nbExtOk++;
if( aTPS.SquareDistance(j) < Dist2Min ) {
Dist2Min = aTPS.SquareDistance(j);
@@ -1150,7 +1192,7 @@ Handle(Adaptor2d_HCurve2d)
Standard_Integer indExt = 0;
if( aTPS.IsDone() && aTPS.NbExt() >= 1 ) {
for( i = 1 ; i <= aTPS.NbExt() ; i++ ) {
if( aTPS.SquareDistance(i) < DistTol3d * DistTol3d && aTPS.SquareDistance(i) < Dist2Min ) {
if( aTPS.SquareDistance(i) < DistTol3d2 && aTPS.SquareDistance(i) < Dist2Min ) {
Dist2Min = aTPS.SquareDistance(i);
indExt = i;
isFound = Standard_True;
@@ -1224,7 +1266,7 @@ Handle(Adaptor2d_HCurve2d)
if (aLocateExtPS.IsDone())
{
if (aLocateExtPS.SquareDistance() < DistTol3d * DistTol3d)
if (aLocateExtPS.SquareDistance() < DistTol3d2)
{ //OCC217
//if (aLocateExtPS.SquareDistance() < Tol3d * Tol3d) {
(aLocateExtPS.Point()).Parameter(U0,V0);
@@ -1249,7 +1291,7 @@ Handle(Adaptor2d_HCurve2d)
imin = isol;
}
}
if (LocalMinSqDist < DistTol3d * DistTol3d)
if (LocalMinSqDist < DistTol3d2)
{
Standard_Real LocalU, LocalV;
aGlobalExtr.Point(imin).Parameter(LocalU, LocalV);
@@ -1321,7 +1363,7 @@ Handle(Adaptor2d_HCurve2d)
locext.Perform(pntproj, Uaux, V0);
if (locext.IsDone())
if (locext.SquareDistance() < DistTol3d * DistTol3d) { //OCC217
if (locext.SquareDistance() < DistTol3d2) { //OCC217
//if (locext.SquareDistance() < Tol3d * Tol3d) {
(locext.Point()).Parameter(u,v);
if((aUsup - U0) > (U0 - aUinf))
@@ -1348,7 +1390,7 @@ Handle(Adaptor2d_HCurve2d)
locext.Perform(pntproj, U0, Vaux);
if (locext.IsDone())
if (locext.SquareDistance() < DistTol3d * DistTol3d) { //OCC217
if (locext.SquareDistance() < DistTol3d2) { //OCC217
//if (locext.SquareDistance() < Tol3d * Tol3d) {
(locext.Point()).Parameter(u,v);
if((aVsup - V0) > (V0 - aVinf))
@@ -1377,7 +1419,7 @@ Handle(Adaptor2d_HCurve2d)
locext.Perform(pntproj, Uaux, Vaux);
if (locext.IsDone())
if (locext.SquareDistance() < DistTol3d * DistTol3d) {
if (locext.SquareDistance() < DistTol3d2) {
//if (locext.SquareDistance() < Tol3d * Tol3d) {
(locext.Point()).Parameter(u,v);
if((Usup - U0) > (U0 - Uinf))
@@ -1405,7 +1447,7 @@ Handle(Adaptor2d_HCurve2d)
Dist2Min = ext.SquareDistance(j);
aGoodValue = j;
}
if (Dist2Min < DistTol3d * DistTol3d) {
if (Dist2Min < DistTol3d2) {
//if (Dist2Min < Tol3d * Tol3d) {
(ext.Point(aGoodValue)).Parameter(u,v);
if(uperiod) {
@@ -1490,9 +1532,6 @@ Handle(Adaptor2d_HCurve2d)
// Modified by Sergey KHROMOV - Thu Apr 18 10:58:02 2002 End
}
//=======================================================================
//function : ProjLib_ProjectUsingInitialCurve2d
//purpose :
@@ -1505,20 +1544,23 @@ Handle(Geom2d_BSplineCurve)
{
//OCC217
Standard_Real Tol3d = myTolerance;
Standard_Real DistTol3d = 1.0*Tol3d;
Standard_Real DistTol3d = 100.0*Tol3d;
if(myMaxDist > 0.)
{
DistTol3d = myMaxDist;
}
Standard_Real DistTol3d2 = DistTol3d * DistTol3d;
Standard_Real TolU = Surf->UResolution(Tol3d), TolV = Surf->VResolution(Tol3d);
Standard_Real Tol2d = Max(Sqrt(TolU*TolU + TolV*TolV), Precision::PConfusion());
Standard_Integer i;
GeomAbs_SurfaceType TheTypeS = Surf->GetType();
GeomAbs_CurveType TheTypeC = Curve->GetType();
// Handle(Standard_Type) TheTypeS = Surf->DynamicType();
// Handle(Standard_Type) TheTypeC = Curve->DynamicType(); // si on a :
// if(TheTypeS == STANDARD_TYPE(Geom_BSplineSurface)) {
if(TheTypeS == GeomAbs_Plane) {
Standard_Real S, T;
gp_Pln Plane = Surf->Plane();
if(TheTypeC == GeomAbs_BSplineCurve) {
myTolReached = Precision::Confusion();
Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
for(i = 1;i <= Curve->NbPoles();i++) {
@@ -1540,6 +1582,7 @@ Handle(Geom2d_BSplineCurve)
}
if(TheTypeC == GeomAbs_BezierCurve) {
myTolReached = Precision::Confusion();
Handle(Geom_BezierCurve) BC = Curve->Bezier();
TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
for(i = 1;i <= Curve->NbPoles();i++) {
@@ -1572,17 +1615,11 @@ Handle(Geom2d_BSplineCurve)
gp_Pnt p22 = BSS->Pole(2,2);
gp_Vec V1(p11,p12);
gp_Vec V2(p21,p22);
if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){ //OCC217
//if(V1.IsEqual(V2,myTolerance,myTolerance/(p11.Distance(p12)*180/M_PI))){
// so the polar surface is plane
// and if it is enough to projet the poles of Curve
if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){
Standard_Integer Dist2Min = IntegerLast();
Standard_Real u,v;
//OCC217
//Standard_Real TolU = Surf->UResolution(myTolerance)
// , TolV = Surf->VResolution(myTolerance);
// gp_Pnt pntproj;
if(TheTypeC == GeomAbs_BSplineCurve) {
myTolReached = Tol3d;
Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
for(i = 1;i <= Curve->NbPoles();i++) {
@@ -1594,8 +1631,7 @@ Handle(Geom2d_BSplineCurve)
if (extrloc.IsDone()) {
Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
if (Dist2Min < DistTol3d * DistTol3d) { //OCC217
//if (Dist2Min < myTolerance * myTolerance) {
if (Dist2Min < DistTol3d2) {
(extrloc.Point()).Parameter(u,v);
Poles2d(i).SetCoord(u,v);
myProjIsDone = Standard_True;
@@ -1624,6 +1660,7 @@ Handle(Geom2d_BSplineCurve)
}
}
if(TheTypeC == GeomAbs_BezierCurve) {
myTolReached = Tol3d;
Handle(Geom_BezierCurve) BC = Curve->Bezier();
TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
for(i = 1;i <= Curve->NbPoles();i++) {
@@ -1634,8 +1671,7 @@ Handle(Geom2d_BSplineCurve)
if (extrloc.IsDone()) {
Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
if (Dist2Min < DistTol3d * DistTol3d) { //OCC217
//if (Dist2Min < myTolerance * myTolerance) {
if (Dist2Min < DistTol3d2) {
(extrloc.Point()).Parameter(u,v);
Poles2d(i).SetCoord(u,v);
myProjIsDone = Standard_True;
@@ -1677,19 +1713,15 @@ Handle(Geom2d_BSplineCurve)
gp_Pnt p22 = BS->Pole(2,2);
gp_Vec V1(p11,p12);
gp_Vec V2(p21,p22);
if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){ //OCC217
//if (V1.IsEqual(V2,myTolerance,myTolerance/(p11.Distance(p12)*180/M_PI))){
// and if it is enough to project the poles of Curve
if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){
Standard_Integer Dist2Min = IntegerLast();
Standard_Real u,v;
//OCC217
//Standard_Real TolU = Surf->UResolution(myTolerance)
// , TolV = Surf->VResolution(myTolerance);
// gp_Pnt pntproj;
if(TheTypeC == GeomAbs_BSplineCurve) {
myTolReached = Tol3d;
Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
for(i = 1;i <= Curve->NbPoles();i++) {
myProjIsDone = Standard_False;
Dist2Min = IntegerLast();
@@ -1699,8 +1731,7 @@ Handle(Geom2d_BSplineCurve)
if (extrloc.IsDone()) {
Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
if (Dist2Min < DistTol3d * DistTol3d) { //OCC217
//if (Dist2Min < myTolerance * myTolerance) {
if (Dist2Min < DistTol3d2) {
(extrloc.Point()).Parameter(u,v);
Poles2d(i).SetCoord(u,v);
myProjIsDone = Standard_True;
@@ -1729,6 +1760,7 @@ Handle(Geom2d_BSplineCurve)
}
}
if(TheTypeC == GeomAbs_BezierCurve) {
myTolReached = Tol3d;
Handle(Geom_BezierCurve) BC = Curve->Bezier();
TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
for(i = 1;i <= Curve->NbPoles();i++) {
@@ -1739,8 +1771,7 @@ Handle(Geom2d_BSplineCurve)
if (extrloc.IsDone()) {
Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
if (Dist2Min < DistTol3d * DistTol3d) { //OCC217
//if (Dist2Min < myTolerance * myTolerance) {
if (Dist2Min < DistTol3d2) {
(extrloc.Point()).Parameter(u,v);
Poles2d(i).SetCoord(u,v);
myProjIsDone = Standard_True;
@@ -1772,8 +1803,7 @@ Handle(Geom2d_BSplineCurve)
}
}
ProjLib_PolarFunction F(Curve, Surf, InitCurve2d, Tol3d) ; //OCC217
//ProjLib_PolarFunction F(Curve, Surf, InitCurve2d, myTolerance) ;
ProjLib_PolarFunction F(Curve, Surf, InitCurve2d, Tol3d) ;
#ifdef OCCT_DEBUG
Standard_Integer Nb = 50;
@@ -1812,15 +1842,34 @@ Handle(Geom2d_BSplineCurve)
#endif
Standard_Integer Deg1,Deg2;
// Deg1 = 8;
// Deg2 = 8;
Deg1 = 2; //IFV
Deg2 = 8; //IFV
Deg1 = 2;
Deg2 = 8;
if(myDegMin > 0)
{
Deg1 = myDegMin;
}
if(myDegMax > 0)
{
Deg2 = myDegMax;
}
Standard_Integer aMaxSegments = 1000;
if(myMaxSegments > 0)
{
aMaxSegments = myMaxSegments;
}
AppParCurves_Constraint aFistC = AppParCurves_TangencyPoint, aLastC = AppParCurves_TangencyPoint;
if(myBndPnt != AppParCurves_TangencyPoint)
{
aFistC = myBndPnt;
aLastC = myBndPnt;
}
Approx_FitAndDivide2d Fit(F,Deg1,Deg2,Tol3d,Tol2d, //OCC217
//Approx_FitAndDivide2d Fit(F,Deg1,Deg2,myTolerance,myTolerance,
Standard_True);
Approx_FitAndDivide2d Fit(Deg1, Deg2, Tol3d, Tol2d, Standard_True, aFistC, aLastC);
Fit.SetMaxSegments(aMaxSegments);
Fit.Perform(F);
Standard_Real anOldTol2d = Tol2d;
Standard_Real aNewTol2d = 0;
if(Fit.IsAllApproximated()) {
Standard_Integer j;
Standard_Integer NbCurves = Fit.NbMultiCurves();
@@ -1831,8 +1880,12 @@ Handle(Geom2d_BSplineCurve)
for (j = 1; j <= NbCurves; j++) {
Standard_Integer Deg = Fit.Value(j).Degree();
MaxDeg = Max ( MaxDeg, Deg);
Fit.Error(j,Tol3d, Tol2d);
aNewTol2d = Max(aNewTol2d, Tol2d);
}
//
myTolReached = Max(myTolReached, myTolerance * (aNewTol2d / anOldTol2d));
//
NbPoles = MaxDeg * NbCurves + 1; //Tops on the BSpline
TColgp_Array1OfPnt2d Poles( 1, NbPoles);
@@ -1884,10 +1937,9 @@ Handle(Geom2d_BSplineCurve)
// try to smoother the Curve GeomAbs_C1.
Standard_Boolean OK = Standard_True;
Standard_Real aSmoothTol = Max(Precision::Confusion(), aNewTol2d);
for (Standard_Integer ij = 2; ij < NbKnots; ij++) {
OK = OK && Dummy->RemoveKnot(ij,MaxDeg-1,Tol3d); //OCC217
//OK = OK && Dummy->RemoveKnot(ij,MaxDeg-1,myTolerance);
OK = OK && Dummy->RemoveKnot(ij,MaxDeg-1, aSmoothTol);
}
#ifdef OCCT_DEBUG
if (!OK) {
@@ -1908,11 +1960,6 @@ Handle(Geom2d_BSplineCurve)
ProjLib_ComputeApproxOnPolarSurface::BSpline() const
{
// Modified by Sergey KHROMOV - Thu Apr 18 11:16:46 2002 End
// Standard_NoSuchObject_Raise_if
// (!myProjIsDone,
// "ProjLib_ComputeApproxOnPolarSurface:BSpline");
// Modified by Sergey KHROMOV - Thu Apr 18 11:16:47 2002 End
return myBSpline ;
}
@@ -1942,3 +1989,65 @@ Standard_Boolean ProjLib_ComputeApproxOnPolarSurface::IsDone() const
{
return myProjIsDone;
}
//=======================================================================
//function : SetTolerance
//purpose :
//=======================================================================
void ProjLib_ComputeApproxOnPolarSurface::SetTolerance(const Standard_Real theTol)
{
myTolerance = theTol;
}
//=======================================================================
//function : SetDegree
//purpose :
//=======================================================================
void ProjLib_ComputeApproxOnPolarSurface::SetDegree(
const Standard_Integer theDegMin,
const Standard_Integer theDegMax)
{
myDegMin = theDegMin;
myDegMax = theDegMax;
}
//=======================================================================
//function : SetMaxSegments
//purpose :
//=======================================================================
void ProjLib_ComputeApproxOnPolarSurface::SetMaxSegments(
const Standard_Integer theMaxSegments)
{
myMaxSegments = theMaxSegments;
}
//=======================================================================
//function : SetBndPnt
//purpose :
//=======================================================================
void ProjLib_ComputeApproxOnPolarSurface::SetBndPnt(
const AppParCurves_Constraint theBndPnt)
{
myBndPnt = theBndPnt;
}
//=======================================================================
//function : SetMaxDist
//purpose :
//=======================================================================
void ProjLib_ComputeApproxOnPolarSurface::SetMaxDist(
const Standard_Real theMaxDist)
{
myMaxDist = theMaxDist;
}
//=======================================================================
//function : Tolerance
//purpose :
//=======================================================================
Standard_Real ProjLib_ComputeApproxOnPolarSurface::Tolerance() const
{
return myTolReached;
}

View File

@@ -23,6 +23,7 @@
#include <Standard_Boolean.hxx>
#include <Standard_Real.hxx>
#include <AppParCurves_Constraint.hxx>
class Geom2d_BSplineCurve;
class Geom2d_Curve;
class Adaptor3d_HCurve;
@@ -35,33 +36,89 @@ class Adaptor2d_HCurve2d;
//! The result is a 2d curve. The evaluation of the
//! current point of the 2d curve is done with the
//! evaluation of the extrema P3d - Surface.
//! For approximation some parameters are used, including
//! required tolerance of approximation.
//! Tolerance is maximal possible value of 3d deviation of 3d projection of projected curve from
//! "exact" 3d projection. Since algorithm searches 2d curve on surface, required 2d tolerance is computed
//! from 3d tolerance with help of U,V resolutions of surface.
//! 3d and 2d tolerances have sence only for curves on surface, it defines precision of projecting and approximation
//! and have nothing to do with distance between the projected curve and the surface.
class ProjLib_ComputeApproxOnPolarSurface
{
public:
DEFINE_STANDARD_ALLOC
//! Empty constructor, it only sets some initial values for class fields.
Standard_EXPORT ProjLib_ComputeApproxOnPolarSurface();
//! Constructor, which performs projecting.
Standard_EXPORT ProjLib_ComputeApproxOnPolarSurface(const Handle(Adaptor3d_HCurve)& C, const Handle(Adaptor3d_HSurface)& S, const Standard_Real Tol = 1.0e-4);
//! Constructor, which performs projecting, using initial curve 2d InitCurve2d, which is any rough approximation of result curve.
//! Parameter Tol is 3d tolerance of approximation.
Standard_EXPORT ProjLib_ComputeApproxOnPolarSurface(const Handle(Adaptor2d_HCurve2d)& InitCurve2d, const Handle(Adaptor3d_HCurve)& C, const Handle(Adaptor3d_HSurface)& S, const Standard_Real Tol);
Standard_EXPORT ProjLib_ComputeApproxOnPolarSurface(const Handle(Adaptor2d_HCurve2d)& InitCurve2d, const Handle(Adaptor2d_HCurve2d)& InitCurve2dBis, const Handle(Adaptor3d_HCurve)& C, const Handle(Adaptor3d_HSurface)& S, const Standard_Real Tol);
//! Constructor, which performs projecting, using two initial curves 2d: InitCurve2d and InitCurve2dBis that are any rough approximations of result curves.
//! This constructor is used to get two pcurves for seem edge.
//! Parameter Tol is 3d tolerance of approximation.
Standard_EXPORT ProjLib_ComputeApproxOnPolarSurface(const Handle(Adaptor2d_HCurve2d)& InitCurve2d, const Handle(Adaptor2d_HCurve2d)& InitCurve2dBis, const Handle(Adaptor3d_HCurve)& C,
const Handle(Adaptor3d_HSurface)& S, const Standard_Real Tol);
//! Set min and max possible degree of result BSpline curve2d, which is got by approximation.
//! If theDegMin/Max < 0, algorithm uses values min = 2, max = 8.
Standard_EXPORT void SetDegree(const Standard_Integer theDegMin, const Standard_Integer theDegMax);
//! Set the parameter, which defines maximal value of parametric intervals the projected
//! curve can be cut for approximation. If theMaxSegments < 0, algorithm uses default
//! value = 1000.
Standard_EXPORT void SetMaxSegments(const Standard_Integer theMaxSegments);
//! Set the parameter, which defines type of boundary condition between segments during approximation.
//! It can be AppParCurves_PassPoint or AppParCurves_TangencyPoint.
//! Default value is AppParCurves_TangencyPoint.
Standard_EXPORT void SetBndPnt(const AppParCurves_Constraint theBndPnt);
//! Set the parameter, which defines maximal possible distance between projected curve and surface.
//! It is used only for projecting on not analytical surfaces.
//! If theMaxDist < 0, algoritm uses default value 100.*Tolerance.
//! If real distance between curve and surface more then theMaxDist, algorithm stops working.
Standard_EXPORT void SetMaxDist(const Standard_Real theMaxDist);
//! Set the tolerance used to project
//! the curve on the surface.
//! Default value is Precision::Approximation().
Standard_EXPORT void SetTolerance (const Standard_Real theTolerance);
//! Method, which performs projecting, using default values of parameters or
//! they must be set by corresponding methods before using.
Standard_EXPORT void Perform (const Handle(Adaptor3d_HCurve)& C, const Handle(Adaptor3d_HSurface)& S);
//! Method, which performs projecting, using default values of parameters or
//! they must be set by corresponding methods before using.
//! Parameter InitCurve2d is any rough estimation of 2d result curve.
Standard_EXPORT Handle(Geom2d_BSplineCurve) Perform (const Handle(Adaptor2d_HCurve2d)& InitCurve2d, const Handle(Adaptor3d_HCurve)& C, const Handle(Adaptor3d_HSurface)& S);
//! Builds initial 2d curve as BSpline with degree = 1 using Extrema algoritm.
//! Method is used in method Perform(...).
Standard_EXPORT Handle(Adaptor2d_HCurve2d) BuildInitialCurve2d (const Handle(Adaptor3d_HCurve)& Curve, const Handle(Adaptor3d_HSurface)& S);
//! Method, which performs projecting.
//! Method is used in method Perform(...).
Standard_EXPORT Handle(Geom2d_BSplineCurve) ProjectUsingInitialCurve2d (const Handle(Adaptor3d_HCurve)& Curve, const Handle(Adaptor3d_HSurface)& S, const Handle(Adaptor2d_HCurve2d)& InitCurve2d);
//! Returns result curve 2d.
Standard_EXPORT Handle(Geom2d_BSplineCurve) BSpline() const;
//! Returns second 2d curve.
Standard_EXPORT Handle(Geom2d_Curve) Curve2d() const;
Standard_EXPORT Standard_Boolean IsDone() const;
//! returns the reached Tolerance.
Standard_EXPORT Standard_Real Tolerance() const;
@@ -79,6 +136,12 @@ private:
Standard_Real myTolerance;
Handle(Geom2d_BSplineCurve) myBSpline;
Handle(Geom2d_Curve) my2ndCurve;
Standard_Real myTolReached;
Standard_Integer myDegMin;
Standard_Integer myDegMax;
Standard_Integer myMaxSegments;
Standard_Real myMaxDist;
AppParCurves_Constraint myBndPnt;
};

View File

@@ -55,6 +55,39 @@
#include <GeomLib.hxx>
#include <Extrema_ExtPC.hxx>
#include <NCollection_DataMap.hxx>
//=======================================================================
//function : ComputeTolU
//purpose :
//=======================================================================
static Standard_Real ComputeTolU(const Handle(Adaptor3d_HSurface)& theSurf,
const Standard_Real theTolerance)
{
Standard_Real aTolU = theSurf->UResolution(theTolerance);
if (theSurf->IsUPeriodic())
{
aTolU = Min(aTolU, 0.01*theSurf->UPeriod());
}
return aTolU;
}
//=======================================================================
//function : ComputeTolV
//purpose :
//=======================================================================
static Standard_Real ComputeTolV(const Handle(Adaptor3d_HSurface)& theSurf,
const Standard_Real theTolerance)
{
Standard_Real aTolV = theSurf->VResolution(theTolerance);
if (theSurf->IsVPeriodic())
{
aTolV = Min(aTolV, 0.01*theSurf->VPeriod());
}
return aTolV;
}
//=======================================================================
//function : IsoIsDeg
@@ -250,7 +283,7 @@ static void Project(ProjLib_Projector& P, Handle(Adaptor3d_HCurve)& C)
case GeomAbs_OtherCurve: // try the approximation
break;
default:
Standard_NoSuchObject::Raise(" ");
throw Standard_NoSuchObject(" ");
}
}
@@ -259,10 +292,13 @@ static void Project(ProjLib_Projector& P, Handle(Adaptor3d_HCurve)& C)
//purpose :
//=======================================================================
ProjLib_ProjectedCurve::ProjLib_ProjectedCurve()
ProjLib_ProjectedCurve::ProjLib_ProjectedCurve() :
myTolerance(Precision::Confusion()),
myDegMin(-1), myDegMax(-1),
myMaxSegments(-1),
myMaxDist(-1.),
myBndPnt(AppParCurves_TangencyPoint)
{
myTolerance = Precision::Confusion();
}
@@ -272,9 +308,13 @@ ProjLib_ProjectedCurve::ProjLib_ProjectedCurve()
//=======================================================================
ProjLib_ProjectedCurve::ProjLib_ProjectedCurve
(const Handle(Adaptor3d_HSurface)& S)
(const Handle(Adaptor3d_HSurface)& S) :
myTolerance(Precision::Confusion()),
myDegMin(-1), myDegMax(-1),
myMaxSegments(-1),
myMaxDist(-1.),
myBndPnt(AppParCurves_TangencyPoint)
{
myTolerance = Precision::Confusion();
Load(S);
}
@@ -286,11 +326,15 @@ ProjLib_ProjectedCurve::ProjLib_ProjectedCurve
ProjLib_ProjectedCurve::ProjLib_ProjectedCurve
(const Handle(Adaptor3d_HSurface)& S,
const Handle(Adaptor3d_HCurve)& C)
const Handle(Adaptor3d_HCurve)& C) :
myTolerance(Precision::Confusion()),
myDegMin(-1), myDegMax(-1),
myMaxSegments(-1),
myMaxDist(-1.),
myBndPnt(AppParCurves_TangencyPoint)
{
myTolerance = Precision::Confusion();
Load(S);
Load(C);
Perform(C);
}
@@ -302,11 +346,15 @@ ProjLib_ProjectedCurve::ProjLib_ProjectedCurve
ProjLib_ProjectedCurve::ProjLib_ProjectedCurve
(const Handle(Adaptor3d_HSurface)& S,
const Handle(Adaptor3d_HCurve)& C,
const Standard_Real Tol)
const Standard_Real Tol) :
myTolerance(Max(Tol, Precision::Confusion())),
myDegMin(-1), myDegMax(-1),
myMaxSegments(-1),
myMaxDist(-1.),
myBndPnt(AppParCurves_TangencyPoint)
{
myTolerance = Max(Tol, Precision::Confusion());
Load(S);
Load(C);
Perform(C);
}
@@ -320,13 +368,22 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HSurface)& S)
mySurface = S ;
}
//=======================================================================
//function : Load
//purpose :
//=======================================================================
void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C)
void ProjLib_ProjectedCurve::Load(const Standard_Real theTol)
{
myTolerance = theTol;
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void ProjLib_ProjectedCurve::Perform(const Handle(Adaptor3d_HCurve)& C)
{
myTolerance = Max(myTolerance, Precision::Confusion());
myCurve = C;
@@ -431,12 +488,19 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C)
TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 4);
}
ProjLib_ComputeApproxOnPolarSurface polar(myCurve, mySurface, myTolerance);
ProjLib_ComputeApproxOnPolarSurface polar;
polar.SetTolerance(myTolerance);
polar.SetDegree(myDegMin, myDegMax);
polar.SetMaxSegments(myMaxSegments);
polar.SetBndPnt(myBndPnt);
polar.SetMaxDist(myMaxDist);
polar.Perform(myCurve, mySurface);
Handle(Geom2d_BSplineCurve) aRes = polar.BSpline();
if (!aRes.IsNull())
{
myTolerance = polar.Tolerance();
if( (IsTrimmed[0] || IsTrimmed[1]))
{
if(IsTrimmed[0])
@@ -538,7 +602,16 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C)
}
}
ProjLib_CompProjectedCurve Projector(mySurface,myCurve, myTolerance, myTolerance, 100 * myTolerance);
Standard_Real aTolU = Max(ComputeTolU(mySurface, myTolerance), Precision::Confusion());
Standard_Real aTolV = Max(ComputeTolV(mySurface, myTolerance), Precision::Confusion());
Standard_Real aTol2d = Sqrt(aTolU*aTolU + aTolV*aTolV);
Standard_Real aMaxDist = 100. * myTolerance;
if(myMaxDist > 0.)
{
aMaxDist = myMaxDist;
}
ProjLib_CompProjectedCurve Projector(mySurface,myCurve, aTolU, aTolV, aMaxDist);
Handle(ProjLib_HCompProjectedCurve) HProjector = new ProjLib_HCompProjectedCurve();
HProjector->Set(Projector);
@@ -559,8 +632,20 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C)
Standard_Boolean Only3d = Standard_False;
Standard_Boolean Only2d = Standard_True;
GeomAbs_Shape Continuity = GeomAbs_C1;
if(myBndPnt == AppParCurves_PassPoint)
{
Continuity = GeomAbs_C0;
}
Standard_Integer MaxDegree = 14;
if(myDegMax > 0)
{
MaxDegree = myDegMax;
}
Standard_Integer MaxSeg = 16;
if(myMaxSegments > 0)
{
MaxSeg = myMaxSegments;
}
Approx_CurveOnSurface appr(HProjector, mySurface, Udeb, Ufin,
myTolerance, Continuity, MaxDegree, MaxSeg,
@@ -570,6 +655,10 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C)
if (!aRes.IsNull())
{
aTolU = appr.MaxError2dU();
aTolV = appr.MaxError2dV();
Standard_Real aNewTol2d = Sqrt(aTolU*aTolU + aTolV*aTolV);
myTolerance *= (aNewTol2d / aTol2d);
if(IsTrimmed[0] || IsTrimmed[1])
{
// Treatment only for surface of revolution
@@ -594,6 +683,16 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C)
aRes->FirstParameter(), aRes->LastParameter(),
FirstPar, LastPar, NewCurve2d);
aRes = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve2d);
if(Continuity == GeomAbs_C0)
{
// try to smoother the Curve GeomAbs_C1.
Standard_Integer aDeg = aRes->Degree();
Standard_Boolean OK = Standard_True;
Standard_Real aSmoothTol = Max(Precision::Confusion(), aNewTol2d);
for (Standard_Integer ij = 2; ij < aRes->NbKnots(); ij++) {
OK = OK && aRes->RemoveKnot(ij, aDeg-1, aSmoothTol);
}
}
}
myResult.SetBSpline(aRes);
@@ -606,7 +705,12 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C)
if ( !myResult.IsDone() && isAnalyticalSurf)
{
// Use advanced analytical projector if base analytical projection failed.
ProjLib_ComputeApprox Comp( myCurve, mySurface, myTolerance);
ProjLib_ComputeApprox Comp;
Comp.SetTolerance(myTolerance);
Comp.SetDegree(myDegMin, myDegMax);
Comp.SetMaxSegments(myMaxSegments);
Comp.SetBndPnt(myBndPnt);
Comp.Perform( myCurve, mySurface);
if (Comp.Bezier().IsNull() && Comp.BSpline().IsNull())
return; // advanced projector has been failed too
myResult.Done();
@@ -723,6 +827,42 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C)
}
}
//=======================================================================
//function : SetDegree
//purpose :
//=======================================================================
void ProjLib_ProjectedCurve::SetDegree(const Standard_Integer theDegMin,
const Standard_Integer theDegMax)
{
myDegMin = theDegMin;
myDegMax = theDegMax;
}
//=======================================================================
//function : SetMaxSegments
//purpose :
//=======================================================================
void ProjLib_ProjectedCurve::SetMaxSegments(const Standard_Integer theMaxSegments)
{
myMaxSegments = theMaxSegments;
}
//=======================================================================
//function : SetBndPnt
//purpose :
//=======================================================================
void ProjLib_ProjectedCurve::SetBndPnt(const AppParCurves_Constraint theBndPnt)
{
myBndPnt = theBndPnt;
}
//=======================================================================
//function : SetMaxDist
//purpose :
//=======================================================================
void ProjLib_ProjectedCurve::SetMaxDist(const Standard_Real theMaxDist)
{
myMaxDist = theMaxDist;
}
//=======================================================================
//function : GetSurface
@@ -786,8 +926,7 @@ Standard_Real ProjLib_ProjectedCurve::LastParameter() const
GeomAbs_Shape ProjLib_ProjectedCurve::Continuity() const
{
Standard_NotImplemented::Raise("");
return GeomAbs_C0;
throw Standard_NotImplemented ("ProjLib_ProjectedCurve::Continuity() - method is not implemented");
}
@@ -798,8 +937,7 @@ GeomAbs_Shape ProjLib_ProjectedCurve::Continuity() const
Standard_Integer ProjLib_ProjectedCurve::NbIntervals(const GeomAbs_Shape ) const
{
Standard_NotImplemented::Raise("");
return 0;
throw Standard_NotImplemented ("ProjLib_ProjectedCurve::NbIntervals() - method is not implemented");
}
@@ -812,7 +950,7 @@ Standard_Integer ProjLib_ProjectedCurve::NbIntervals(const GeomAbs_Shape ) const
void ProjLib_ProjectedCurve::Intervals(TColStd_Array1OfReal& ,
const GeomAbs_Shape ) const
{
Standard_NotImplemented::Raise("");
throw Standard_NotImplemented ("ProjLib_ProjectedCurve::Intervals() - method is not implemented");
}
@@ -823,8 +961,7 @@ void ProjLib_ProjectedCurve::Intervals(TColStd_Array1OfReal& ,
Standard_Boolean ProjLib_ProjectedCurve::IsClosed() const
{
Standard_NotImplemented::Raise("");
return Standard_True;
throw Standard_NotImplemented ("ProjLib_ProjectedCurve::IsClosed() - method is not implemented");
}
@@ -846,8 +983,7 @@ Standard_Boolean ProjLib_ProjectedCurve::IsPeriodic() const
Standard_Real ProjLib_ProjectedCurve::Period() const
{
Standard_NotImplemented::Raise("");
return 0.;
throw Standard_NotImplemented ("ProjLib_ProjectedCurve::Period() - method is not implemented");
}
@@ -858,8 +994,7 @@ Standard_Real ProjLib_ProjectedCurve::Period() const
gp_Pnt2d ProjLib_ProjectedCurve::Value(const Standard_Real ) const
{
Standard_NotImplemented::Raise("");
return gp_Pnt2d(0.,0.);
throw Standard_NotImplemented ("ProjLib_ProjectedCurve::Value() - method is not implemented");
}
@@ -870,7 +1005,7 @@ gp_Pnt2d ProjLib_ProjectedCurve::Value(const Standard_Real ) const
void ProjLib_ProjectedCurve::D0(const Standard_Real , gp_Pnt2d& ) const
{
Standard_NotImplemented::Raise("");
throw Standard_NotImplemented ("ProjLib_ProjectedCurve::D0() - method is not implemented");
}
@@ -883,7 +1018,7 @@ void ProjLib_ProjectedCurve::D1(const Standard_Real ,
gp_Pnt2d& ,
gp_Vec2d& ) const
{
Standard_NotImplemented::Raise("");
throw Standard_NotImplemented ("ProjLib_ProjectedCurve::D1() - method is not implemented");
}
@@ -897,7 +1032,7 @@ void ProjLib_ProjectedCurve::D2(const Standard_Real ,
gp_Vec2d& ,
gp_Vec2d& ) const
{
Standard_NotImplemented::Raise("");
throw Standard_NotImplemented ("ProjLib_ProjectedCurve::D2() - method is not implemented");
}
@@ -912,7 +1047,7 @@ void ProjLib_ProjectedCurve::D3(const Standard_Real,
gp_Vec2d&,
gp_Vec2d&) const
{
Standard_NotImplemented::Raise("");
throw Standard_NotImplemented ("ProjLib_ProjectedCurve::D3() - method is not implemented");
}
@@ -924,8 +1059,7 @@ void ProjLib_ProjectedCurve::D3(const Standard_Real,
gp_Vec2d ProjLib_ProjectedCurve::DN(const Standard_Real,
const Standard_Integer) const
{
Standard_NotImplemented::Raise("");
return gp_Vec2d(0.,0.);
throw Standard_NotImplemented ("ProjLib_ProjectedCurve::DN() - method is not implemented");
}
@@ -936,8 +1070,7 @@ gp_Vec2d ProjLib_ProjectedCurve::DN(const Standard_Real,
Standard_Real ProjLib_ProjectedCurve::Resolution(const Standard_Real) const
{
Standard_NotImplemented::Raise("");
return 0.;
throw Standard_NotImplemented ("ProjLib_ProjectedCurve::Resolution() - method is not implemented");
}
@@ -1117,7 +1250,5 @@ Handle(Adaptor2d_HCurve2d) ProjLib_ProjectedCurve::Trim
const Standard_Real ,
const Standard_Real ) const
{
Standard_NotImplemented::Raise("");
return NULL ;
throw Standard_NotImplemented ("ProjLib_ProjectedCurve::Trim() - method is not implemented");
}

View File

@@ -29,6 +29,7 @@
#include <TColStd_Array1OfReal.hxx>
#include <Standard_Boolean.hxx>
#include <GeomAbs_CurveType.hxx>
#include <AppParCurves_Constraint.hxx>
class Adaptor3d_HSurface;
class Adaptor3d_HCurve;
class Standard_OutOfRange;
@@ -49,20 +50,32 @@ class Geom2d_BSplineCurve;
//! Compute the 2d-curve. Try to solve the particular
//! case if possible. Otherwize, an approximation is
//! done.
//! done. For approximation some parameters are used, including
//! required tolerance of approximation.
//! Tolerance is maximal possible value of 3d deviation of 3d projection of projected curve from
//! "exact" 3d projection. Since algorithm searches 2d curve on surface, required 2d tolerance is computed
//! from 3d tolerance with help of U,V resolutions of surface.
//! 3d and 2d tolerances have sence only for curves on surface, it defines precision of projecting and approximation
//! and have nothing to do with distance between the projected curve and the surface.
class ProjLib_ProjectedCurve : public Adaptor2d_Curve2d
{
public:
DEFINE_STANDARD_ALLOC
//! Empty constructor, it only sets some initial values for class fields.
Standard_EXPORT ProjLib_ProjectedCurve();
//! Constructor with initialisation field mySurface
Standard_EXPORT ProjLib_ProjectedCurve(const Handle(Adaptor3d_HSurface)& S);
//! Constructor, which performs projecting.
//! If projecting uses approximation, default parameters are used, in particular, 3d tolerance of approximation
//! is Precision::Confusion()
Standard_EXPORT ProjLib_ProjectedCurve(const Handle(Adaptor3d_HSurface)& S, const Handle(Adaptor3d_HCurve)& C);
//! Constructor, which performs projecting.
//! If projecting uses approximation, 3d tolerance is Tol, default parameters are used,
Standard_EXPORT ProjLib_ProjectedCurve(const Handle(Adaptor3d_HSurface)& S, const Handle(Adaptor3d_HCurve)& C, const Standard_Real Tol);
//! Changes the tolerance used to project
@@ -72,8 +85,32 @@ public:
//! Changes the Surface.
Standard_EXPORT void Load (const Handle(Adaptor3d_HSurface)& S);
//! Changes the Curve.
Standard_EXPORT void Load (const Handle(Adaptor3d_HCurve)& C);
//! Performs projecting for given curve.
//! If projecting uses approximation,
//! approximation parameters can be set before by corresponding methods
//! SetDegree(...), SetMaxSegmets(...), SetBndPnt(...), SetMaxDist(...)
Standard_EXPORT void Perform (const Handle(Adaptor3d_HCurve)& C);
//! Set min and max possible degree of result BSpline curve2d, which is got by approximation.
//! If theDegMin/Max < 0, algorithm uses values that are chosen depending of types curve 3d
//! and surface.
Standard_EXPORT void SetDegree(const Standard_Integer theDegMin, const Standard_Integer theDegMax);
//! Set the parameter, which defines maximal value of parametric intervals the projected
//! curve can be cut for approximation. If theMaxSegments < 0, algorithm uses default
//! value = 1000.
Standard_EXPORT void SetMaxSegments(const Standard_Integer theMaxSegments);
//! Set the parameter, which defines type of boundary condition between segments during approximation.
//! It can be AppParCurves_PassPoint or AppParCurves_TangencyPoint.
//! Default value is AppParCurves_TangencyPoint;
Standard_EXPORT void SetBndPnt(const AppParCurves_Constraint theBndPnt);
//! Set the parameter, which degines maximal possible distance between projected curve and surface.
//! It uses only for projecting on not analytical surfaces.
//! If theMaxDist < 0, algoritm uses default value 100.*Tolerance.
//! If real distance between curve and surface more then theMaxDist, algorithm stops working.
Standard_EXPORT void SetMaxDist(const Standard_Real theMaxDist);
Standard_EXPORT const Handle(Adaptor3d_HSurface)& GetSurface() const;
@@ -203,8 +240,11 @@ private:
Handle(Adaptor3d_HSurface) mySurface;
Handle(Adaptor3d_HCurve) myCurve;
ProjLib_Projector myResult;
Standard_Integer myDegMin;
Standard_Integer myDegMax;
Standard_Integer myMaxSegments;
Standard_Real myMaxDist;
AppParCurves_Constraint myBndPnt;
};