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 | |
22 | class 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 | |
41 | void 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 | |
92 | Geom2dConvert_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 | |