//=======================================================================
Approx_ComputeCLine::Approx_ComputeCLine
- (const MultiLine& Line,
- const Standard_Integer degreemin,
- const Standard_Integer degreemax,
- const Standard_Real Tolerance3d,
- const Standard_Real Tolerance2d,
- const Standard_Boolean cutting,
- const AppParCurves_Constraint FirstC,
- const AppParCurves_Constraint LastC)
+(const MultiLine& Line,
+const Standard_Integer degreemin,
+const Standard_Integer degreemax,
+const Standard_Real Tolerance3d,
+const Standard_Real Tolerance2d,
+const Standard_Boolean cutting,
+const AppParCurves_Constraint FirstC,
+const AppParCurves_Constraint LastC)
{
mydegremin = degreemin;
mydegremax = degreemax;
mycut = cutting;
myfirstC = FirstC;
mylastC = LastC;
+ myMaxSegments = IntegerLast();
alldone = Standard_False;
Perform(Line);
}
//=======================================================================
Approx_ComputeCLine::Approx_ComputeCLine
- (const Standard_Integer degreemin,
- const Standard_Integer degreemax,
- const Standard_Real Tolerance3d,
- const Standard_Real Tolerance2d,
- const Standard_Boolean cutting,
- const AppParCurves_Constraint FirstC,
- const AppParCurves_Constraint LastC)
+(const Standard_Integer degreemin,
+const Standard_Integer degreemax,
+const Standard_Real Tolerance3d,
+const Standard_Real Tolerance2d,
+const Standard_Boolean cutting,
+const AppParCurves_Constraint FirstC,
+const AppParCurves_Constraint LastC)
{
alldone = Standard_False;
mydegremin = degreemin;
mycut = cutting;
myfirstC = FirstC;
mylastC = LastC;
+ myMaxSegments = IntegerLast();
}
//=======================================================================
void Approx_ComputeCLine::Perform(const MultiLine& Line)
{
Standard_Real UFirst, ULast;
- Standard_Boolean Finish = Standard_False,
- begin = Standard_True, Ok = Standard_False;
+ Standard_Boolean Finish = Standard_False,
+ begin = Standard_True, Ok = Standard_False;
Standard_Real thetol3d = Precision::Confusion(), thetol2d = Precision::Confusion();
UFirst = Line.FirstParameter();
- ULast = Line.LastParameter();
- Standard_Real TolU = (ULast-UFirst)*1.e-05;
- Standard_Real myfirstU = UFirst;
+ ULast = Line.LastParameter();
+ Standard_Real TolU = Max((ULast - UFirst)*1.e-03, Precision::Confusion());
+ Standard_Real myfirstU = UFirst;
Standard_Real mylastU = ULast;
+ Standard_Integer aMaxSegments = 0;
+ Standard_Integer aMaxSegments1 = myMaxSegments - 1;
+ Standard_Integer aNbCut = 0, aNbImp = 0, aNbComp = 5;
if (!mycut)
{
alldone = Compute(Line, UFirst, ULast, thetol3d, thetol2d);
- if (!alldone)
+ if (!alldone)
{
tolreached = Standard_False;
myfirstparam.Append(UFirst);
Tolers2d.Append(currenttol2d);
}
}
- else
+ else
{
// previous decision to be taken if we get worse with next cut (eap)
AppParCurves_MultiCurve KeptMultiCurve;
Standard_Real KeptUfirst = 0., KeptUlast = 0., KeptT3d = RealLast(), KeptT2d = 0.;
- while (!Finish)
+ while (!Finish)
{
-
+
// Gestion du decoupage de la multiline pour approximer:
- if (!begin)
+ if (!begin)
{
- if (Ok)
+ if (Ok)
{
// Calcul de la partie a approximer.
myfirstU = mylastU;
- mylastU = ULast;
- if (Abs(ULast-myfirstU) <= RealEpsilon())
+ mylastU = ULast;
+ aNbCut = 0;
+ aNbImp = 0;
+ if (Abs(ULast - myfirstU) <= RealEpsilon()
+ || aMaxSegments >= myMaxSegments)
{
Finish = Standard_True;
alldone = Standard_True;
if ((thetol3d + thetol2d) < (KeptT3d + KeptT2d))
{
KeptMultiCurve = TheMultiCurve;
- KeptUfirst = myfirstU;
- KeptUlast = mylastU;
- KeptT3d = thetol3d;
- KeptT2d = thetol2d;
+ KeptUfirst = myfirstU;
+ KeptUlast = mylastU;
+ KeptT3d = thetol3d;
+ KeptT2d = thetol2d;
+ aNbImp++;
}
// cut an interval
- mylastU = (myfirstU + mylastU)/2;
+ mylastU = (myfirstU + mylastU) / 2;
+ aNbCut++;
}
}
// Calcul des parametres sur ce nouvel intervalle.
Ok = Compute(Line, myfirstU, mylastU, thetol3d, thetol2d);
+ if (Ok)
+ {
+ aMaxSegments++;
+ }
//cout << myfirstU << " - " << mylastU << " tol : " << thetol3d << " " << thetol2d << endl;
-
+ Standard_Boolean aStopCutting = Standard_False;
+ if (aNbCut >= aNbComp)
+ {
+ if (aNbCut > aNbImp)
+ {
+ aStopCutting = Standard_True;
+ }
+ }
// is new decision better?
- if (!Ok && Abs(myfirstU-mylastU) <= TolU)
+ if (!Ok && (Abs(myfirstU - mylastU) <= TolU || aMaxSegments >= aMaxSegments1 || aStopCutting ))
{
- Ok = Standard_True; // stop interval cutting, approx the rest part
+ Ok = Standard_True; // stop interval cutting, approx the rest part
- if ((thetol3d + thetol2d) < (KeptT3d + KeptT2d))
- {
- KeptMultiCurve = TheMultiCurve;
- KeptUfirst = myfirstU;
- KeptUlast = mylastU;
- KeptT3d = thetol3d;
- KeptT2d = thetol2d;
- }
+ if ((thetol3d + thetol2d) < (KeptT3d + KeptT2d))
+ {
+ KeptMultiCurve = TheMultiCurve;
+ KeptUfirst = myfirstU;
+ KeptUlast = mylastU;
+ KeptT3d = thetol3d;
+ KeptT2d = thetol2d;
+ }
- mylastU = KeptUlast;
+ mylastU = KeptUlast;
- tolreached = Standard_False; // helas
- myMultiCurves.Append(KeptMultiCurve);
- Tolers3d.Append (KeptT3d);
- Tolers2d.Append (KeptT2d);
- myfirstparam.Append (KeptUfirst);
- mylastparam.Append (KeptUlast);
- }
+ tolreached = Standard_False; // helas
+ myMultiCurves.Append(KeptMultiCurve);
+ aMaxSegments++;
+ Tolers3d.Append(KeptT3d);
+ Tolers2d.Append(KeptT2d);
+ myfirstparam.Append(KeptUfirst);
+ mylastparam.Append(KeptUlast);
+ }
begin = Standard_False;
} // while (!Finish)
//=======================================================================
Standard_Boolean Approx_ComputeCLine::Compute(const MultiLine& Line,
- const Standard_Real Ufirst,
- const Standard_Real Ulast,
- Standard_Real& TheTol3d,
- Standard_Real& TheTol2d)
+ const Standard_Real Ufirst,
+ const Standard_Real Ulast,
+ Standard_Real& TheTol3d,
+ Standard_Real& TheTol2d)
{
if (mydone) {
LSquare.Error(Fv, TheTol3d, TheTol2d);
if (TheTol3d <= mytol3d && TheTol2d <= mytol2d) {
- // Stockage de la multicurve approximee.
- tolreached = Standard_True;
+ // Stockage de la multicurve approximee.
+ tolreached = Standard_True;
myMultiCurves.Append(LSquare.Value());
- myfirstparam.Append(Ufirst);
- mylastparam.Append(Ulast);
- Tolers3d.Append(TheTol3d);
- Tolers2d.Append(TheTol2d);
- return Standard_True;
+ myfirstparam.Append(Ufirst);
+ mylastparam.Append(Ulast);
+ Tolers3d.Append(TheTol3d);
+ Tolers2d.Append(TheTol2d);
+ return Standard_True;
}
}
if (deg == mydegremax) {
currenttol3d = TheTol3d;
currenttol2d = TheTol2d;
}
-
+
}
return Standard_False;
}
//=======================================================================
void Approx_ComputeCLine::Parameters(const Standard_Integer Index,
- Standard_Real& firstpar,
- Standard_Real& lastpar) const
+ Standard_Real& firstpar,
+ Standard_Real& lastpar) const
{
firstpar = myfirstparam.Value(Index);
- lastpar = mylastparam.Value(Index);
+ lastpar = mylastparam.Value(Index);
}
//=======================================================================
//=======================================================================
void Approx_ComputeCLine::SetDegrees(const Standard_Integer degreemin,
- const Standard_Integer degreemax)
+ const Standard_Integer degreemax)
{
mydegremin = degreemin;
mydegremax = degreemax;
//=======================================================================
void Approx_ComputeCLine::SetTolerances(const Standard_Real Tolerance3d,
- const Standard_Real Tolerance2d)
+ const Standard_Real Tolerance2d)
{
mytol3d = Tolerance3d;
mytol2d = Tolerance2d;
//=======================================================================
void Approx_ComputeCLine::SetConstraints(const AppParCurves_Constraint FirstC,
- const AppParCurves_Constraint LastC)
+ const AppParCurves_Constraint LastC)
{
myfirstC = FirstC;
- mylastC = LastC;
+ 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;
}
//=======================================================================
//=======================================================================
void Approx_ComputeCLine::Error(const Standard_Integer Index,
- Standard_Real& tol3d,
- Standard_Real& tol2d) const
+ Standard_Real& tol3d,
+ Standard_Real& tol2d) const
{
tol3d = Tolers3d.Value(Index);
tol2d = Tolers2d.Value(Index);
//! 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
Standard_Boolean mycut;
AppParCurves_Constraint myfirstC;
AppParCurves_Constraint mylastC;
+ Standard_Integer myMaxSegments;
};
//! 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
Standard_Boolean mycut;
AppParCurves_Constraint myfirstC;
AppParCurves_Constraint mylastC;
+ Standard_Integer myMaxSegments;
};
Handle(GeomAdaptor_HCurve) aBAHC = new GeomAdaptor_HCurve(aC3D, aT1, aT2);
//
Standard_Real aTolR;
+ 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 (pBAS->GetType() == GeomAbs_SurfaceOfRevolution) {
- Standard_Real aTR;
- //
- aTR=Precision::Confusion();//1.e-7;
+ if (pBAS->GetType() == GeomAbs_SurfaceOfRevolution)
+ {
if (TolReached2d > aTR) {
aTR=TolReached2d;
}
ProjLib::MakePCurveOfType(aProj1, aC2D);
aTolR = aProj1.GetTolerance();
}
- else {
- ProjLib_ProjectedCurve aProjCurv(aBAHS, aBAHC);// 1
+ else
+ {
+ ProjLib_ProjectedCurve aProjCurv(aBAHS);
+ Standard_Integer aDegMin = -1, aDegMax = -1, aMaxSegments = -1;
+ Standard_Real aMaxDist = -1;
+ AppParCurves_Constraint aBndPnt = AppParCurves_TangencyPoint;
+ if ((TolReached2d >= 10. * aTR) && (TolReached2d <= aMaxTol || isAnaSurf))
+ {
+ aTR = Min(aMaxTol, 0.1*TolReached2d);
+ aMaxSegments = 100;
+ aMaxDist = 1.e3*TolReached2d;
+ if(!isAnaSurf)
+ {
+ aBndPnt = AppParCurves_PassPoint;
+ }
+ }
+ 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
+ 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
- ProjLib::MakePCurveOfType(aProj3, aC2D);
- aTolR = aProj3.GetTolerance();
- }
}
//
if(aC2D.IsNull())
//! 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.
Standard_Boolean mycut;
AppParCurves_Constraint myfirstC;
AppParCurves_Constraint mylastC;
-
+ Standard_Integer myMaxSegments;
};
#include <Geom2d_BSplineCurve.hxx>
#include <Geom2d_BezierCurve.hxx>
#include <Standard_NotImplemented.hxx>
+#include <Adaptor3d_HSurface.hxx>
//=======================================================================
//function : Project
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;
+ }
+}
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
//! 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);
+
// 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>
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
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) &&
#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()) {
aNewTol2d = Max(aNewTol2d, Tol2d);
AppParCurves_MultiCurve MC = Fit.Value( i); //Charge la Ieme Curve
TColgp_Array1OfPnt2d Poles2d( 1, MC.Degree() + 1);//Recupere les poles
- MC.Curve(1, Poles2d);
-
+ MC.Curve(1, Poles2d);
Conv.AddCurve(Poles2d);
}
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.)
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();
}
}
}
+//=======================================================================
+//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
#include <Standard_Handle.hxx>
#include <Standard_Real.hxx>
+#include <AppParCurves_Constraint.hxx>
+
class Geom2d_BSplineCurve;
class Geom2d_BezierCurve;
class Adaptor3d_HCurve;
//! 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;
private:
-
-
Standard_Real myTolerance;
Handle(Geom2d_BSplineCurve) myBSpline;
Handle(Geom2d_BezierCurve) myBezier;
-
+ Standard_Integer myDegMin;
+ Standard_Integer myDegMax;
+ Standard_Integer myMaxSegments;
+ AppParCurves_Constraint myBndPnt;
};
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 :
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
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 =
}
}
-//=======================================================================
-//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
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,
- const Handle(Adaptor3d_HSurface)& S)
+ const Handle(Adaptor3d_HSurface)& S)
{
//OCC217
Standard_Real Tol3d = myTolerance;
}
if(myProjIsDone) {
- BSC2d = ProjectUsingInitialCurve2d(AHC, S, AHC2d);
- if(BSC2d.IsNull()) return Handle(Geom2d_BSplineCurve)(); //IFV
+ BSC2d = ProjectUsingInitialCurve2d(AHC, S, AHC2d);
+ if(BSC2d.IsNull())
+ {
+ return Handle(Geom2d_BSplineCurve)();
+ }
LOfBSpline2d.Append(BSC2d);
}
else {
}
}
if(myProjIsDone) {
- BSC2d = ProjectUsingInitialCurve2d(AHC, S, AHC2d);
+ BSC2d = ProjectUsingInitialCurve2d(AHC, S, AHC2d);
if(BSC2d.IsNull()) {
return Handle(Geom2d_BSplineCurve)();
}
if(!myProjIsDone)
return Handle(Geom2d_BSplineCurve)();
}
- return ProjectUsingInitialCurve2d(AHC, S, AHC2d);
+ return ProjectUsingInitialCurve2d(AHC, S, AHC2d);
}
+
//=======================================================================
//function : ProjLib_BuildInitialCurve2d
//purpose :
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);
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());
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);
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);
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);
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;
if (aLocateExtPS.IsDone())
{
- if (aLocateExtPS.SquareDistance() < DistTol3d * DistTol3d)
+ if (aLocateExtPS.SquareDistance() < DistTol3d2)
{ //OCC217
//if (aLocateExtPS.SquareDistance() < Tol3d * Tol3d) {
(aLocateExtPS.Point()).Parameter(U0,V0);
imin = isol;
}
}
- if (LocalMinSqDist < DistTol3d * DistTol3d)
+ if (LocalMinSqDist < DistTol3d2)
{
Standard_Real LocalU, LocalV;
aGlobalExtr.Point(imin).Parameter(LocalU, LocalV);
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))
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))
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))
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) {
// Modified by Sergey KHROMOV - Thu Apr 18 10:58:02 2002 End
}
-
-
-
//=======================================================================
//function : ProjLib_ProjectUsingInitialCurve2d
//purpose :
ProjLib_ComputeApproxOnPolarSurface::
ProjectUsingInitialCurve2d(const Handle(Adaptor3d_HCurve)& Curve,
const Handle(Adaptor3d_HSurface)& Surf,
- const Handle(Adaptor2d_HCurve2d)& InitCurve2d)
+ const Handle(Adaptor2d_HCurve2d)& InitCurve2d)
{
//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++) {
}
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++) {
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++) {
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;
}
}
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++) {
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;
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();
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;
}
}
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++) {
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;
}
}
- 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;
#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();
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);
// 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) {
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 ;
}
{
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;
+}
+
#include <Standard_Boolean.hxx>
#include <Standard_Real.hxx>
+#include <AppParCurves_Constraint.hxx>
class Geom2d_BSplineCurve;
class Geom2d_Curve;
class Adaptor3d_HCurve;
//! 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);
+
+ //! 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);
+
- 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;
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;
};
#include <TColgp_HArray1OfPnt2d.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
+#include <Geom2dConvert.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <GeomLib.hxx>
#include <Extrema_ExtPC.hxx>
#include <NCollection_DataMap.hxx>
+#include <ElSLib.hxx>
+#include <ElCLib.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
//=======================================================================
static void TrimC3d(Handle(Adaptor3d_HCurve)& myCurve,
- Standard_Boolean* IsTrimmed,
- const Standard_Real dt,
- const gp_Pnt& Pole,
+ Standard_Boolean* IsTrimmed,
+ const Standard_Real dt,
+ const gp_Pnt& Pole,
Standard_Integer* SingularCase,
- const Standard_Integer NumberOfSingularCase)
+ const Standard_Integer NumberOfSingularCase,
+ const Standard_Real TolConf)
{
Standard_Real f = myCurve->FirstParameter();
Standard_Real l = myCurve->LastParameter();
gp_Pnt P = myCurve->Value(f);
- if(P.Distance(Pole) < Precision::Confusion()) {
+ if(P.Distance(Pole) <= TolConf) {
IsTrimmed[0] = Standard_True;
f = f+dt;
myCurve = myCurve->Trim(f, l, Precision::Confusion());
}
P = myCurve->Value(l);
- if(P.Distance(Pole) < Precision::Confusion()) {
+ if(P.Distance(Pole) <= TolConf) {
IsTrimmed[1] = Standard_True;
l = l-dt;
myCurve = myCurve->Trim(f, l, Precision::Confusion());
}
}
gp_Lin2d BoundLin(thePole, theBoundDir); //one of the bounds of rectangle
+ Standard_Real ParOnLin = 0.;
+ if (theBoundDir.IsParallel(aDBnd, 100.*Precision::Angular()))
+ {
+ ParOnLin = ElCLib::Parameter(aLin, thePole);
+ }
+ else
+ {
+ Standard_Real U1x = BoundLin.Direction().X();
+ Standard_Real U1y = BoundLin.Direction().Y();
+ Standard_Real U2x = aLin.Direction().X();
+ Standard_Real U2y = aLin.Direction().Y();
+ Standard_Real Uo21x = aLin.Location().X() - BoundLin.Location().X();
+ Standard_Real Uo21y = aLin.Location().Y() - BoundLin.Location().Y();
- Standard_Real U1x = BoundLin.Direction().X();
- Standard_Real U1y = BoundLin.Direction().Y();
- Standard_Real U2x = aLin.Direction().X();
- Standard_Real U2y = aLin.Direction().Y();
- Standard_Real Uo21x = aLin.Location().X() - BoundLin.Location().X();
- Standard_Real Uo21y = aLin.Location().Y() - BoundLin.Location().Y();
-
- Standard_Real D = U1y*U2x-U1x*U2y;
-
- Standard_Real ParOnLin = (Uo21y * U1x - Uo21x * U1y)/D; //parameter of intersection point
+ Standard_Real D = U1y*U2x - U1x*U2y;
+
+ ParOnLin = (Uo21y * U1x - Uo21x * U1y) / D; //parameter of intersection point
+ }
Handle(Geom2d_Line) aSegLine = new Geom2d_Line(aLin);
aSegment = (FirstOrLast == 0)?
//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();
}
//=======================================================================
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);
}
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);
}
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);
}
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;
GeomAbs_SurfaceType SType = mySurface->GetType();
GeomAbs_CurveType CType = myCurve->GetType();
Standard_Boolean isAnalyticalSurf = Standard_True;
+ Standard_Boolean IsTrimmed[2] = { Standard_False, Standard_False };
+ Standard_Integer SingularCase[2];
+ const Standard_Real eps = 0.01;
+ Standard_Real TolConf = Precision::Confusion();
+ Standard_Real dt = (LastPar - FirstPar) * eps;
+ Standard_Real U1 = 0.0, U2 = 0.0, V1 = 0.0, V2 = 0.0;
+ U1 = mySurface->FirstUParameter();
+ U2 = mySurface->LastUParameter();
+ V1 = mySurface->FirstVParameter();
+ V2 = mySurface->LastVParameter();
switch (SType)
{
// periodique en V !)
P.SetInBounds(myCurve->FirstParameter());
}
+ else
+ {
+ const Standard_Real Vmax = M_PI / 2.;
+ const Standard_Real Vmin = -Vmax;
+ const Standard_Real minang = 1.e-5 * M_PI;
+ gp_Sphere aSph = mySurface->Sphere();
+ Standard_Real anR = aSph.Radius();
+ Standard_Real f = myCurve->FirstParameter();
+ Standard_Real l = myCurve->LastParameter();
+
+ gp_Pnt Pf = myCurve->Value(f);
+ gp_Pnt Pl = myCurve->Value(l);
+ gp_Pnt aLoc = aSph.Position().Location();
+ Standard_Real maxdist = Max(Pf.Distance(aLoc), Pl.Distance(aLoc));
+ TolConf = Max(anR * minang, Abs(anR - maxdist));
+
+ //Surface has pole at V = Vmin and Vmax
+ gp_Pnt Pole = mySurface->Value(U1, Vmin);
+ TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 3, TolConf);
+ Pole = mySurface->Value(U1, Vmax);
+ TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 4, TolConf);
+ }
myResult = P;
}
break;
case GeomAbs_BSplineSurface:
{
isAnalyticalSurf = Standard_False;
- Standard_Boolean IsTrimmed[2] = {Standard_False, Standard_False};
- Standard_Integer SingularCase[2];
- Standard_Real f, l, dt;
- const Standard_Real eps = 0.01;
+ Standard_Real f, l;
f = myCurve->FirstParameter();
l = myCurve->LastParameter();
dt = (l - f) * eps;
- Standard_Real U1 = 0.0, U2=0.0, V1=0.0, V2=0.0;
const Adaptor3d_Surface& S = mySurface->Surface();
U1 = S.FirstUParameter();
U2 = S.LastUParameter();
{
//Surface has pole at U = Umin
gp_Pnt Pole = mySurface->Value(U1, V1);
- TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 1);
+ TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 1, TolConf);
}
if(IsoIsDeg(S, U2, GeomAbs_IsoU, 0., myTolerance))
{
//Surface has pole at U = Umax
gp_Pnt Pole = mySurface->Value(U2, V1);
- TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 2);
+ TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 2, TolConf);
}
if(IsoIsDeg(S, V1, GeomAbs_IsoV, 0., myTolerance))
{
//Surface has pole at V = Vmin
gp_Pnt Pole = mySurface->Value(U1, V1);
- TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 3);
+ TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 3, TolConf);
}
if(IsoIsDeg(S, V2, GeomAbs_IsoV, 0., myTolerance))
{
//Surface has pole at V = Vmax
gp_Pnt Pole = mySurface->Value(U1, V2);
- TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 4);
+ TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 4, TolConf);
}
- 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])
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;
- const Standard_Real eps = 0.01;
+ Standard_Real f = 0.0, l = 0.0;
+ dt = 0.0;
if(mySurface->GetType() == GeomAbs_SurfaceOfRevolution)
{
}
}
- 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);
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,
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
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);
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();
-
- // set the type
- if ( SType == GeomAbs_Plane && CType == GeomAbs_BezierCurve)
+ Handle(Geom2d_BSplineCurve) aRes;
+ if (Comp.BSpline().IsNull())
{
- myResult.SetType(GeomAbs_BezierCurve);
- myResult.SetBezier(Comp.Bezier()) ;
+ aRes = Geom2dConvert::CurveToBSplineCurve(Comp.Bezier());
}
else
{
+ aRes = Comp.BSpline();
+ }
+ if ((IsTrimmed[0] || IsTrimmed[1]))
+ {
+ if (IsTrimmed[0])
+ {
+ //Add segment before start of curve
+ Standard_Real f = myCurve->FirstParameter();
+ ExtendC2d(aRes, f, -dt, U1, U2, V1, V2, 0, SingularCase[0]);
+ }
+ if (IsTrimmed[1])
+ {
+ //Add segment after end of curve
+ Standard_Real 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.SetType(GeomAbs_BSplineCurve);
- myResult.SetBSpline(Comp.BSpline()) ;
+ }
+ else
+ {
+ // set the type
+ if (SType == GeomAbs_Plane && CType == GeomAbs_BezierCurve)
+ {
+ myResult.SetType(GeomAbs_BezierCurve);
+ myResult.SetBezier(Comp.Bezier());
+ }
+ else
+ {
+ myResult.SetType(GeomAbs_BSplineCurve);
+ myResult.SetBSpline(Comp.BSpline());
+ }
}
// set the periodicity flag
if (SType == GeomAbs_Plane &&
- CType == GeomAbs_BSplineCurve &&
- myCurve->IsPeriodic() )
+ CType == GeomAbs_BSplineCurve &&
+ myCurve->IsPeriodic())
{
myResult.SetPeriodic();
}
}
}
+//=======================================================================
+//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
#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;
//! 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
//! 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;
Standard_EXPORT const Handle(Adaptor3d_HCurve)& GetCurve() const;
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;
};