1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-07-30 13:05:50 +03:00
occt/src/ShapeFix/ShapeFix_EdgeProjAux.cxx
ifv f4dee9bb20 0026329: Restore floating point signals handling in DRAW
Added DRAW command dsetsignal, resetting OSD signal handler with either armed or disabled FPE handler, according to an option.
If called without arguments, it sets FPE handler only if environment variable OSD_FPE is defined (with value different from 0).
On start, DRAW calls dsetsignal to set FPE signal if CSF_FPE is defined.
Test bugs fclasses bug6143 uses dsetsignal to set FPE handler unconditionally before the test command, and resets it to default at the end.

A number of changes in the code have been done in order to fix floating point exceptions that became generated after enabling signals:

- Global functions Sinh() and Cosh() defined in Standard_Real.hxx are improved to raise Standard_NumericError exception if argument is too big (greater than 710.47586), instead of relying on system treatment of floating point overflow. These functions are used instead of sinh and cosh in ElCLib.cxx.

- Maximal value of parameter on hyperbola is restricted by 23 (corresponding to ~1e10 in 3d) in order to avoid FP overflow in Extrema_GenExtCS.cxx, ShapeFix_EdgeProjAux.cxx.

- Interface of the root curve adaptor class Adaptor3d_Curve has been updated to add new virtual methods BasisCurve and OffsetValue. They complement the adaptor for the case of offset curves. These methods are used in Extrema_GenExtCS.cxx to restrict domain search in the case of offset of hyperbola, in order to get rid of floating point overflow. All classes inheriting Adaptor3d_Curve have been changed to implement the new virtual methods.

- Protection against division by zero has been implemented in ApproxInt_KnotTools.cxx, BRepClass3d_SClassifier.cxx, BRepGProp_Face.cxx, BRepMesh_FastDiscretFace.cxx, Geom2dGcc_Circ2d2TanOnIter.cxx, Geom2dInt_Geom2dCurveTool.cxx, IntPolyh_MaillageAffinage.cxx.

- Protection against calling of math functions of infinite arguments has been added in BRepCheck_Edge.cxx, BRepLib.cxx, CSLib_NormalPolyDef.cxx, Extrema_FuncExtPC.gxx, Extrema_GExtPC.gxx, Extrema_GLocateExtPC.gxx, Intf_InterferencePolygonPolyhedron.gxx, ShapeAnalysis_Surface.cxx, ShapeAnalysis_TransferParametersProj.cxx, ShapeAnalysis_Wire.cxx, math_FunctionSetRoot.cxx.

- Proper initialization of local variables is done in BOPAlgo_PaveFiller_6.cxx, XSDRAWSTLVRML.cxx.

- Inconsistent usage of Standard_Boolean* to access integer data in HLR (caused by #27772) is corrected

Some test cases have been updated to actual state.
2016-09-30 11:17:17 +03:00

616 lines
20 KiB
C++

// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//:r5 abv 06.04.99: ec_turbine-A.stp, #4313: protect against null curve
// abv 09.04.99 S4136: add parameter preci (to eliminate BRepAPI::Precision)
#include <Adaptor3d_CurveOnSurface.hxx>
#include <BRep_Tool.hxx>
#include <ElCLib.hxx>
#include <Extrema_ExtPC.hxx>
#include <Geom2d_BoundedCurve.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2d_Line.hxx>
#include <Geom2dAdaptor_Curve.hxx>
#include <Geom2dAdaptor_HCurve.hxx>
#include <Geom_Curve.hxx>
#include <Geom_SphericalSurface.hxx>
#include <Geom_Surface.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <gp_Pnt.hxx>
#include <Precision.hxx>
#include <ShapeAnalysis.hxx>
#include <ShapeAnalysis_Curve.hxx>
#include <ShapeAnalysis_Edge.hxx>
#include <ShapeAnalysis_Surface.hxx>
#include <ShapeFix_EdgeProjAux.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_Failure.hxx>
#include <Standard_Type.hxx>
#include <TopExp.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Vertex.hxx>
#include <Adaptor3d_HCurve.hxx>
#include <BSplCLib.hxx>
IMPLEMENT_STANDARD_RTTIEXT(ShapeFix_EdgeProjAux,MMgt_TShared)
//=======================================================================
//function : ShapeFix_EdgeProjAux
//purpose :
//=======================================================================
ShapeFix_EdgeProjAux::ShapeFix_EdgeProjAux ()
{
myFirstDone = myLastDone = Standard_False;
}
//=======================================================================
//function : ShapeFix_EdgeProjAux
//purpose :
//=======================================================================
ShapeFix_EdgeProjAux::ShapeFix_EdgeProjAux (const TopoDS_Face& F,
const TopoDS_Edge& E)
{
Init (F, E);
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void ShapeFix_EdgeProjAux::Init (const TopoDS_Face& F,
const TopoDS_Edge& E)
{
myFace = F;
myEdge = E;
myFirstParam = myLastParam = 0.;
myFirstDone = myLastDone = Standard_False;
}
//=======================================================================
//function : Compute
//purpose :
//=======================================================================
void ShapeFix_EdgeProjAux::Compute (const Standard_Real preci)
{
myFirstDone = myLastDone = Standard_False;
// Project Point3d on Surface
// TEMPORARY Call ShapeFix_EdgeProjAux
myFirstParam = 0.;
myLastParam = 0.;
Init2d(preci);
if (IsFirstDone() && IsLastDone()) {
Standard_Real U1 = FirstParam();
Standard_Real U2 = LastParam();
if (U1>=U2) {
#ifdef OCCT_DEBUG
cout << "Parametres inverses ... " << endl;
#endif
Standard_Real tmp = U1;
U1 = U2; U2 = tmp;
}
myFirstParam = U1;
myFirstDone = Standard_True;
myLastParam = U2;
myLastDone = Standard_True;
}
}
//=======================================================================
//function : IsFirstDone
//purpose :
//=======================================================================
Standard_Boolean ShapeFix_EdgeProjAux::IsFirstDone() const
{
return myFirstDone;
}
//=======================================================================
//function : IsLastDone
//purpose :
//=======================================================================
Standard_Boolean ShapeFix_EdgeProjAux::IsLastDone() const
{
return myLastDone;
}
//=======================================================================
//function : FirstParam
//purpose :
//=======================================================================
Standard_Real ShapeFix_EdgeProjAux::FirstParam() const
{
return myFirstParam;
}
//=======================================================================
//function : LastParam
//purpose :
//=======================================================================
Standard_Real ShapeFix_EdgeProjAux::LastParam() const
{
return myLastParam;
}
//=======================================================================
//function : IsIso
//purpose :
//=======================================================================
Standard_Boolean ShapeFix_EdgeProjAux::IsIso (const Handle(Geom2d_Curve)& /*theCurve2d*/)
{
// Until an ISO is recognized by Adaptor3d_Curve
/*
if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) {
Handle(Geom2d_Line) theLine2d = Handle(Geom2d_Line)::DownCast(theCurve2d);
gp_Dir2d theDir2d = theLine2d->Direction();
gp_Dir2d dir1(0.,1.);
gp_Dir2d dir2(0.,-1.);
return (theDir2d.IsEqual(dir1,Precision::Angular()) ||
theDir2d.IsEqual(dir2,Precision::Angular()) ||
theDir2d.IsNormal(dir1,Precision::Angular()) ||
theDir2d.IsNormal(dir2,Precision::Angular()) );
}
*/
return Standard_False;
}
// ----------------------------------------------------------------------------
// static : FindParameterWithExt
// Purpose : Computes the trimming parameter of Pt1 on COnS
// ----------------------------------------------------------------------------
static Standard_Boolean FindParameterWithExt (const gp_Pnt& Pt1,
const Adaptor3d_CurveOnSurface& COnS,
const Standard_Real Uinf,
const Standard_Real Usup,
const Standard_Real preci,
Standard_Real& w1)
{
try { // et allez donc !
OCC_CATCH_SIGNALS
Extrema_ExtPC myExtPC (Pt1, COnS, Uinf, Usup, preci);
//ShapeFix_ExtPCOnS myExtPCOnS1 =
//ShapeFix_ExtPCOnS(Pt1, COnS, Uinf, Usup, preci);
if (myExtPC.IsDone()) {
Standard_Integer NbExt1 = myExtPC.NbExt();
for (Standard_Integer i=1; i<=NbExt1; i++) {
if (myExtPC.IsMin(i)) {
//Standard_Real dist = myExtPC.Value(i); //szv#4:S4163:12Mar99 debug mode only
w1 = myExtPC.Point(i).Parameter();
}
}
return Standard_True;
}
else return Standard_False;
} // end try
catch(Standard_Failure) {
#ifdef OCCT_DEBUG //:s5
cout << "Warning: ShapeFix_EdgeProjAux, FindParameterWithExt(): Exception: ";
Standard_Failure::Caught()->Print(cout); cout << endl;
#endif
return Standard_False;
}
}
//=======================================================================
//function : Init2d
//purpose :
//=======================================================================
void ShapeFix_EdgeProjAux::Init2d (const Standard_Real preci)
{
Standard_Real cl = 0., cf = 0.;
// Extract Geometries
myFirstDone = myLastDone = Standard_False;
Handle(Geom_Surface) theSurface = BRep_Tool::Surface(myFace);
Handle(Geom2d_Curve) theCurve2d = BRep_Tool::CurveOnSurface(myEdge, myFace, cf, cl);
if ( theCurve2d.IsNull() ) return; //:r5 abv 6 Apr 99: ec_turbine-A.stp, #4313
myFirstParam = 0.;
myLastParam = 0.;
TopoDS_Vertex V1,V2;
TopExp::Vertices(myEdge, V1, V2);
gp_Pnt Pt1,Pt2;
// pdn 28.12.98: r_39-db.stp #605: use ends of 3d curve instead of vertices
ShapeAnalysis_Edge sae;
Standard_Real a,b;
Handle(Geom_Curve) C3d;
if(sae.Curve3d(myEdge,C3d,a,b,Standard_False)) {
Pt1 = C3d->Value(a);
Pt2 = C3d->Value(b);
}
else {
Pt1 = BRep_Tool::Pnt(V1);
Pt2 = BRep_Tool::Pnt(V2);
}
//:S4136 Standard_Real preci = BRepAPI::Precision();
//pdn to manage degenerated case
if (V1.IsSame(V2)) {
Handle(ShapeAnalysis_Surface) stsu = new ShapeAnalysis_Surface (theSurface);
gp_Pnt2d aPt1,aPt2;
Standard_Real firstpar,lastpar;
if (stsu->DegeneratedValues(Pt1,preci,aPt1,aPt2,firstpar,lastpar)){
if(theCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) {
if (aPt1.IsEqual(theCurve2d->Value(firstpar),preci) &&
aPt2.IsEqual(theCurve2d->Value(lastpar),preci)){
myFirstParam = firstpar;
myLastParam = lastpar;
myFirstDone = myLastDone = Standard_True;
return;
}
}
#ifdef OCCT_DEBUG
else cout <<"Other type of deg curve"<<endl;
#endif
}
}
Standard_Boolean parU = Standard_False, parV = Standard_False;
GeomAdaptor_Surface SA = GeomAdaptor_Surface(theSurface);
Handle(GeomAdaptor_HSurface) myHSur = new GeomAdaptor_HSurface(SA);
cf = theCurve2d->FirstParameter();
cl = theCurve2d->LastParameter();
//pdn cutting pcurve by suface bounds
if (Precision::IsInfinite(cf)||Precision::IsInfinite(cl)) {
if(theCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) {
Standard_Real uf,ul,vf,vl;
theSurface->Bounds(uf,ul,vf,vl);
//Correct surface limits for extrusion/revolution surfaces based on hyperbola
//23 is ln(1.0e+10)
if(SA.GetType() == GeomAbs_SurfaceOfExtrusion)
{
if(SA.BasisCurve()->GetType() == GeomAbs_Hyperbola)
{
uf = Max(uf, -23.);
ul = Min(ul, 23.);
}
}
if(SA.GetType() == GeomAbs_SurfaceOfRevolution)
{
if(SA.BasisCurve()->GetType() == GeomAbs_Hyperbola)
{
vf = Max(vf, -23.);
vl = Min(vl, 23.);
}
}
if(!Precision::IsInfinite(uf)&&!Precision::IsInfinite(ul)&&
!Precision::IsInfinite(vf)&&!Precision::IsInfinite(vl)) {
Standard_Real cfi,cli;
Handle(Geom2d_Line) lin = Handle(Geom2d_Line)::DownCast(theCurve2d);
gp_Pnt2d pnt = lin->Location();
gp_Dir2d dir = lin->Direction();
if (dir.Y()==0) {
parU = Standard_True;
cfi = (uf-pnt.X())/dir.X();
cli = (ul-pnt.X())/dir.X();
}
else if (dir.X()==0) {
parV = Standard_True;
cfi = (vf-pnt.Y())/dir.Y();
cli = (vl-pnt.Y())/dir.Y();
}
else {//common case
Standard_Real xfi, xli, yfi, yli;
xfi = (uf-pnt.X())/dir.X();
xli = (ul-pnt.X())/dir.X();
yfi = (vf-pnt.Y())/dir.Y();
yli = (vl-pnt.Y())/dir.Y();
if (dir.X()*dir.Y() > 0) {
cfi = (Abs(xli-xfi) < Abs(xli-yfi)? xfi : yfi);
cli = (Abs(xfi-xli) < Abs(xfi-yli)? xli : yli);
} else {
cfi = (Abs(xli-xfi) < Abs(xli-yli)? xfi : yli);
cli = (Abs(yli-xli) < Abs(yli-yfi)? xli : yfi);
}
}
if (cfi < cli) { cf = cfi; cl = cli; }
else { cf = cli; cl = cfi; }
}
else if(!Precision::IsInfinite(uf)&&!Precision::IsInfinite(ul)){
Handle(Geom2d_Line) lin = Handle(Geom2d_Line)::DownCast(theCurve2d);
gp_Dir2d dir = lin->Direction();
if (dir.X()!=0) {
if (dir.Y()==0) parU = Standard_True;
gp_Pnt2d pnt = lin->Location(); //szv#4:S4163:12Mar99 moved
Standard_Real cfi = (uf-pnt.X())/dir.X();
Standard_Real cli = (ul-pnt.X())/dir.X();
if (cfi < cli) { cf = cfi; cl = cli; }
else { cf = cli; cl = cfi; }
}
else {
cf=-10000;
cl= 10000;
}
}
else {
cf=-10000;
cl= 10000;
//pdn not cutted by bounds
#ifdef OCCT_DEBUG
cout<<"Infinite Surface"<<endl;
#endif
}
}
else {
//pdn not linear case not managed
cf=-10000;
cl= 10000;
if(theCurve2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)))
{
//Try to reparametrize (CASE dxf read bug25899)
Handle(Geom2d_BSplineCurve) aBspl = Handle(Geom2d_BSplineCurve)::DownCast(theCurve2d->Copy());
TColStd_Array1OfReal aNewKnots(1, aBspl->NbKnots());
aBspl->Knots(aNewKnots);
BSplCLib::Reparametrize(cf, cl, aNewKnots);
aBspl->SetKnots(aNewKnots);
theCurve2d = aBspl;
}
#ifdef OCCT_DEBUG
cout<<"Some infinite curve"<<endl;
#endif
}
}
Geom2dAdaptor_Curve CA = Geom2dAdaptor_Curve(theCurve2d,cf,cl);
Handle(Geom2dAdaptor_HCurve) myHCur = new Geom2dAdaptor_HCurve(CA);
Adaptor3d_CurveOnSurface COnS = Adaptor3d_CurveOnSurface(myHCur, myHSur);
// ----------------------------------------------
// --- topological limit == geometric limit ? ---
// ----------------------------------------------
Standard_Real Uinf = COnS.FirstParameter();
Standard_Real Usup = COnS.LastParameter();
Standard_Real w1 = 0., w2 = 0.;
ShapeAnalysis_Curve sac;
gp_Pnt pnt;
Standard_Real dist = sac.Project(COnS,Pt1,preci,pnt,w1,Standard_False);
//if distance is infinite then projection is not performed
if( Precision::IsInfinite(dist))
return;
myFirstDone = Standard_True;
myFirstParam = w1;
dist = sac.Project(COnS,Pt2,preci,pnt,w2,Standard_False);
if( Precision::IsInfinite(dist))
return;
myLastDone = Standard_True;
myLastParam = w2;
if(fabs(w1 - w2) < Precision::PConfusion())
{
if(!theSurface->IsUPeriodic() && !theSurface->IsVPeriodic())
return;
}
if ( myFirstParam == Uinf && myLastParam == Usup ) return;
if ( myFirstParam == Usup && myLastParam == Uinf ) {
myFirstParam = theCurve2d->ReversedParameter(Usup);
myLastParam = theCurve2d->ReversedParameter(Uinf);
theCurve2d->Reverse();
#ifdef OCCT_DEBUG
cout << "Warning: ShapeFix_EdgeProjAux: pcurve reversed" << endl;
#endif
return;
}
//:abv 29.08.01: SAT: fix for closed case
if ( COnS.Value(Uinf).Distance ( COnS.Value(Usup) ) < Precision::Confusion() ) {
// 18.11.2002 SKL OCC630 compare values with tolerance Precision::PConfusion() instead of "=="
if ( Abs(myFirstParam-Uinf) < ::Precision::PConfusion() &&
Abs(myLastParam-Uinf) < ::Precision::PConfusion() )
myLastParam = w2 = Usup;
// 18.11.2002 SKL OCC630 compare values with tolerance Precision::PConfusion() instead of "=="
else if ( Abs(myFirstParam-Usup) < ::Precision::PConfusion() &&
Abs(myLastParam-Usup) < ::Precision::PConfusion() )
myFirstParam = w1 = Uinf;
}
//pdn adjust parameters in periodic case
if(parU || parV) {
Standard_Real uf,ul,vf,vl;
theSurface->Bounds(uf,ul,vf,vl);
Standard_Real period = (parU ? ul-uf : vl-vf);
w1+=ShapeAnalysis::AdjustToPeriod(w1,0,period);
myFirstParam = w1;
w2+=ShapeAnalysis::AdjustToPeriod(w2,0,period);
myLastParam = w2;
Handle(Geom_Curve) C3d1;
if(!sae.Curve3d (myEdge, C3d1, cf, cl, Standard_False )) {
UpdateParam2d(theCurve2d);
return;
}
gp_Pnt mid = C3d1->Value((cf+cl)/2);
Standard_Real wmid;
sac.Project(COnS,mid,preci,pnt,wmid,Standard_False);
wmid+=ShapeAnalysis::AdjustToPeriod(wmid,0,period);
if(w1>=w2) {
if(w2 > wmid) myFirstParam -= period;
else if (w1 > wmid)
UpdateParam2d(theCurve2d);
else {
myLastParam+=period;
#ifdef OCCT_DEBUG
cout <<" Added"<<endl;
#endif
}
}
else {
if(w1 > wmid) {
myLastParam -=period;
UpdateParam2d(theCurve2d);
#ifdef OCCT_DEBUG
cout <<" Added & Inverted"<<endl;
#endif
} else if (w2 < wmid) {
myFirstParam += period;
UpdateParam2d(theCurve2d);
}
}
}
UpdateParam2d(theCurve2d);
return;
}
//=======================================================================
//function : Init3d
//purpose :
//=======================================================================
void ShapeFix_EdgeProjAux::Init3d (const Standard_Real preci)
{
Standard_Real cl, cf;
// Extract Geometries
Handle(Geom_Surface) theSurface = BRep_Tool::Surface(myFace);
Handle(Geom2d_Curve) theCurve2d = BRep_Tool::CurveOnSurface(myEdge, myFace, cf, cl);
if ( theCurve2d.IsNull() ) return; //:r5 abv 6 Apr 99: ec_turbine-A.stp, #4313
TopoDS_Vertex V1,V2;
V1 = TopExp::FirstVertex(myEdge);
V2 = TopExp::LastVertex(myEdge);
gp_Pnt Pt1 = BRep_Tool::Pnt(V1);
gp_Pnt Pt2 = BRep_Tool::Pnt(V2);
GeomAdaptor_Surface SA = GeomAdaptor_Surface(theSurface);
Handle(GeomAdaptor_HSurface) myHSur = new GeomAdaptor_HSurface(SA);
Geom2dAdaptor_Curve CA = Geom2dAdaptor_Curve(theCurve2d);
Handle(Geom2dAdaptor_HCurve) myHCur = new Geom2dAdaptor_HCurve(CA);
Adaptor3d_CurveOnSurface COnS = Adaptor3d_CurveOnSurface(myHCur, myHSur);
//:S4136 Standard_Real preci = BRepAPI::Precision();
Standard_Real Uinf = theCurve2d->FirstParameter();
Standard_Real Usup = theCurve2d->LastParameter();
// ----------------------------------------------
// --- topological limit == geometric limit ? ---
// ----------------------------------------------
if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve))) {
gp_Pnt Pdeb = COnS.Value(Uinf);
gp_Pnt Pfin = COnS.Value(Usup);
//szv#4:S4163:12Mar99 optimized
if ( Pdeb.IsEqual(Pt1, preci) && Pfin.IsEqual(Pt2, preci) ) {
myFirstParam = Uinf;
myLastParam = Usup;
myFirstDone = myLastDone = Standard_True;
return;
}
}
// ------------------------------------------
// --- The CurveOnSurface is not infinite ---
// --- Try with Extrema ---
// ------------------------------------------
Standard_Real w1 = COnS.FirstParameter();
Standard_Real w2 = COnS.LastParameter();
if ((!Precision::IsInfinite(w1) &&
!Precision::IsInfinite(w2) &&
theCurve2d->Continuity() != GeomAbs_C0) ||
IsIso(theCurve2d)) {
//szv#4:S4163:12Mar99 optimized
if ( FindParameterWithExt(Pt1, COnS, Uinf, Usup, preci, w1) &&
FindParameterWithExt(Pt2, COnS, Uinf, Usup, preci, w2) ) {
myFirstParam = w1;
myLastParam = w2;
UpdateParam2d(theCurve2d);
myFirstDone = myLastDone = Standard_True;
return;
}
}
myFirstDone = myLastDone = Standard_True;
}
//=======================================================================
//function : UpdateParam2d
//purpose :
//=======================================================================
void ShapeFix_EdgeProjAux::UpdateParam2d (const Handle(Geom2d_Curve)& theCurve2d)
{
if (myFirstParam < myLastParam) return;
Standard_Real cf = theCurve2d->FirstParameter();
Standard_Real cl = theCurve2d->LastParameter();
//:S4136 Standard_Real preci = BRepAPI::Precision();
Standard_Real preci2d = Precision::PConfusion(); //:S4136: Parametric(preci, 0.01);
// 15.11.2002 PTV OCC966
if (ShapeAnalysis_Curve::IsPeriodic(theCurve2d)) {
ElCLib::AdjustPeriodic(cf,cl,preci2d,myFirstParam,myLastParam);
}
else if (theCurve2d->IsClosed()) {
//szv#4:S4163:12Mar99 optimized
if ( Abs ( myFirstParam - cl ) <= preci2d ) myFirstParam = cf;
else if ( Abs ( myLastParam - cf ) <= preci2d ) myLastParam = cl;
else {
#ifdef OCCT_DEBUG
cout << "Error : curve 2d range crossing non periodic curve origin";
cout << endl;
#endif
// add fail result;
return;
}
}
// the curve is closed within the 'file' 2D tolerance
else if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
Handle(Geom2d_BSplineCurve) aBSpline2d =
Handle(Geom2d_BSplineCurve)::DownCast(theCurve2d);
if (aBSpline2d->StartPoint().Distance(aBSpline2d->EndPoint()) <= preci2d) {
if ( Abs ( myFirstParam - cl ) <= preci2d ) myFirstParam = cf;
else if ( Abs ( myLastParam - cf ) <= preci2d ) myLastParam = cl;
}
}
else {
#ifdef OCCT_DEBUG
cout << "Warning : non increasing parameters for 2d curve." << endl;
cout << " update parameter 2d uncertain." << endl;
#endif
Standard_Real tmp1 = myFirstParam, tmp2 = myLastParam;
myFirstParam = theCurve2d->ReversedParameter(tmp1);
myLastParam = theCurve2d->ReversedParameter(tmp2);
theCurve2d->Reverse();
//cout<<"Reversed case 2"<<endl;
}
}