0022627: Change OCCT memory management defaults
[occt.git] / src / Geom2dConvert / Geom2dConvert_ApproxCurve.cxx
CommitLineData
7fd59977 1// File: GeomConvert_ApproxCurve.cxx
2// Created: Thu Sep 11 15:50:30 1997
3// Author: Roman BORISOV
4// <rbv@toctox.nnov.matra-dtv.fr>
5
6
7#include <Geom2dConvert_ApproxCurve.ixx>
8#include <gp_Pnt2d.hxx>
9#include <gp_Vec2d.hxx>
10#include <Geom2dAdaptor_HCurve.hxx>
11#include <TColStd_HArray1OfReal.hxx>
12#include <AdvApprox_PrefAndRec.hxx>
13#include <AdvApprox_ApproxAFunction.hxx>
14#include <TColgp_Array1OfPnt2d.hxx>
15#include <Precision.hxx>
16
17//=======================================================================
18//class : Geom2dConvert_ApproxCurve_Eval
19//purpose: evaluator class for approximation
20//=======================================================================
21
22class Geom2dConvert_ApproxCurve_Eval : public AdvApprox_EvaluatorFunction
23{
24 public:
25 Geom2dConvert_ApproxCurve_Eval (const Handle(Adaptor2d_HCurve2d)& theFunc,
26 Standard_Real First, Standard_Real Last)
27 : fonct(theFunc) { StartEndSav[0] = First; StartEndSav[1] = Last; }
28
29 virtual void Evaluate (Standard_Integer *Dimension,
30 Standard_Real StartEnd[2],
31 Standard_Real *Parameter,
32 Standard_Integer *DerivativeRequest,
33 Standard_Real *Result, // [Dimension]
34 Standard_Integer *ErrorCode);
35
36 private:
37 Handle(Adaptor2d_HCurve2d) fonct;
38 Standard_Real StartEndSav[2];
39};
40
41void Geom2dConvert_ApproxCurve_Eval::Evaluate (Standard_Integer *Dimension,
42 Standard_Real StartEnd[2],
43 Standard_Real *Param, // Parameter at which evaluation
44 Standard_Integer *Order, // Derivative Request
45 Standard_Real *Result,// [Dimension]
46 Standard_Integer *ErrorCode)
47{
48 *ErrorCode = 0;
49 Standard_Real par = *Param;
50
51// Dimension is incorrect
52 if (*Dimension!=2) {
53 *ErrorCode = 1;
54 }
55// Parameter is incorrect
56 if ( par < StartEnd[0] || par > StartEnd[1] ) {
57 *ErrorCode = 2;
58 }
59 if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1])
60 {
61 fonct = fonct->Trim(StartEnd[0],StartEnd[1],Precision::PConfusion());
62 StartEndSav[0]=StartEnd[0];
63 StartEndSav[1]=StartEnd[1];
64 }
65
66 gp_Pnt2d pnt;
67 gp_Vec2d v1, v2;
68
69 switch (*Order) {
70 case 0:
71 pnt = fonct->Value(par);
72 Result[0] = pnt.X();
73 Result[1] = pnt.Y();
74 break;
75 case 1:
76 fonct->D1(par, pnt, v1);
77 Result[0] = v1.X();
78 Result[1] = v1.Y();
79 break;
80 case 2:
81 fonct->D2(par, pnt, v1, v2);
82 Result[0] = v2.X();
83 Result[1] = v2.Y();
84 break;
85 default:
86 Result[0] = Result[1] = 0.;
87 *ErrorCode = 3;
88 break;
89 }
90}
91
92Geom2dConvert_ApproxCurve::Geom2dConvert_ApproxCurve(const Handle(Geom2d_Curve)& Curve,const Standard_Real Tol2d,const GeomAbs_Shape Order,const Standard_Integer MaxSegments,const Standard_Integer MaxDegree)
93{
94 Handle(Geom2dAdaptor_HCurve) HCurve = new Geom2dAdaptor_HCurve (Curve);
95
96 // Initialisation of input parameters of AdvApprox
97
98 Standard_Integer Num1DSS=0, Num2DSS=1, Num3DSS=0;
99 Handle(TColStd_HArray1OfReal) OneDTolNul, ThreeDTolNul;
100 Handle(TColStd_HArray1OfReal) TwoDTol = new TColStd_HArray1OfReal(1,Num2DSS);
101 TwoDTol->Init(Tol2d);
102
103 Standard_Real First = Curve->FirstParameter();
104 Standard_Real Last = Curve->LastParameter();
105
106 Standard_Integer NbInterv_C2 = HCurve->NbIntervals(GeomAbs_C2);
107 TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2+1);
108 HCurve->Intervals(CutPnts_C2,GeomAbs_C2);
109 Standard_Integer NbInterv_C3 = HCurve->NbIntervals(GeomAbs_C3);
110 TColStd_Array1OfReal CutPnts_C3(1, NbInterv_C3+1);
111 HCurve->Intervals(CutPnts_C3,GeomAbs_C3);
112 AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3);
113
114 myMaxError = 0;
115
116 Geom2dConvert_ApproxCurve_Eval ev (HCurve, First, Last);
117 AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS,
118 OneDTolNul, TwoDTol, ThreeDTolNul,
119 First, Last, Order,
120 MaxDegree, MaxSegments,
121 ev, CutTool);
122
123 myIsDone = aApprox.IsDone();
124 myHasResult = aApprox.HasResult();
125
126 if (myHasResult) {
127 TColgp_Array1OfPnt2d Poles(1,aApprox.NbPoles());
128 aApprox.Poles2d(1,Poles);
129 Handle(TColStd_HArray1OfReal) Knots = aApprox.Knots();
130 Handle(TColStd_HArray1OfInteger) Mults = aApprox.Multiplicities();
131 Standard_Integer Degree = aApprox.Degree();
132 myBSplCurve = new Geom2d_BSplineCurve(Poles, Knots->Array1(), Mults->Array1(), Degree);
133 myMaxError = aApprox.MaxError(2, 1);
134 }
135}
136
137 Handle(Geom2d_BSplineCurve) Geom2dConvert_ApproxCurve::Curve() const
138{
139 return myBSplCurve;
140}
141
142 Standard_Boolean Geom2dConvert_ApproxCurve::IsDone() const
143{
144 return myIsDone;
145}
146
147 Standard_Boolean Geom2dConvert_ApproxCurve::HasResult() const
148{
149 return myHasResult;
150}
151
152 Standard_Real Geom2dConvert_ApproxCurve::MaxError() const
153{
154 return myMaxError;
155}
156
157 void Geom2dConvert_ApproxCurve::Dump(Standard_OStream& o) const
158{
159 o << "******* Dump of ApproxCurve *******" << endl;
160 o << "******* Error " << MaxError() << endl;
161}
162