Integration of OCCT 6.5.0 from SVN
[occt.git] / src / Approx / Approx_ComputeCLine.gxx
CommitLineData
7fd59977 1// File Approx_ComputeCLine.gxx
2
3// modified by Edward AGAPOV (eap) Tue Apr 2 2002 (occ265)
4// -- stop cutting an interval to approximate if next decisions
5// -- get worse on and on
6
7
8
9#include <Approx_ParametrizationType.hxx>
10#include Approx_MyLeastSquare_hxx
11#include <TColStd_Array1OfReal.hxx>
12#include <AppParCurves_Constraint.hxx>
13#include <Approx_Status.hxx>
14
15//=======================================================================
16//function : Approx_ComputeCLine
17//purpose : The MultiLine <Line> will be approximated until tolerances
18// will be reached.
19// The approximation will be done from degreemin to degreemax
20// with a cutting if the corresponding boolean is True.
21//=======================================================================
22
23Approx_ComputeCLine::Approx_ComputeCLine
24 (const MultiLine& Line,
25 const Standard_Integer degreemin,
26 const Standard_Integer degreemax,
27 const Standard_Real Tolerance3d,
28 const Standard_Real Tolerance2d,
29 const Standard_Boolean cutting,
30 const AppParCurves_Constraint FirstC,
31 const AppParCurves_Constraint LastC)
32{
33 mydegremin = degreemin;
34 mydegremax = degreemax;
35 mytol3d = Tolerance3d;
36 mytol2d = Tolerance2d;
37 mycut = cutting;
38 myfirstC = FirstC;
39 mylastC = LastC;
40 alldone = Standard_False;
41 Perform(Line);
42}
43
44//=======================================================================
45//function : Approx_ComputeCLine
46//purpose : Initializes the fields of the algorithm.
47//=======================================================================
48
49Approx_ComputeCLine::Approx_ComputeCLine
50 (const Standard_Integer degreemin,
51 const Standard_Integer degreemax,
52 const Standard_Real Tolerance3d,
53 const Standard_Real Tolerance2d,
54 const Standard_Boolean cutting,
55 const AppParCurves_Constraint FirstC,
56 const AppParCurves_Constraint LastC)
57{
58 alldone = Standard_False;
59 mydegremin = degreemin;
60 mydegremax = degreemax;
61 mytol3d = Tolerance3d;
62 mytol2d = Tolerance2d;
63 mycut = cutting;
64 myfirstC = FirstC;
65 mylastC = LastC;
66}
67
68//=======================================================================
69//function : Perform
70//purpose : runs the algorithm after having initialized the fields.
71//=======================================================================
72
73void Approx_ComputeCLine::Perform(const MultiLine& Line)
74{
75
76
77 Standard_Real UFirst, ULast;
78 Standard_Boolean Finish = Standard_False,
79 begin = Standard_True, Ok = Standard_False;
80 Standard_Real thetol3d, thetol2d;
81 UFirst = LineTool::FirstParameter(Line);
82 ULast = LineTool::LastParameter(Line);
83 Standard_Real TolU = (ULast-UFirst)*1.e-05;
84 Standard_Real myfirstU = UFirst;
85 Standard_Real mylastU = ULast;
86
87 if (!mycut) {
88 alldone = Compute(Line, UFirst, ULast, thetol3d, thetol2d);
89 if (!alldone) {
90 tolreached = Standard_False;
91 myfirstparam.Append(UFirst);
92 mylastparam.Append(ULast);
93 myMultiCurves.Append(TheMultiCurve);
94 Tolers3d.Append(currenttol3d);
95 Tolers2d.Append(currenttol2d);
96 }
97 }
98 else {
99
100 // previous decision to be taken if we get worse with next cut (eap)
101 AppParCurves_MultiCurve KeptMultiCurve;
102 Standard_Real KeptUfirst, KeptUlast, KeptT3d, KeptT2d;
103 Standard_Integer NbWorseDecis = 0, NbAllowedBadDecis = 10;
104
105 KeptT3d = RealLast(); KeptT2d = 0;
106
107 while (!Finish) {
108
109 // Gestion du decoupage de la multiline pour approximer:
110 if (!begin) {
111 if (Ok) {
112 // Calcul de la partie a approximer.
113 myfirstU = mylastU;
114 mylastU = ULast;
115 if (Abs(ULast-myfirstU) <= RealEpsilon()) {
116 Finish = Standard_True;
117 alldone = Standard_True;
118 return;
119 }
120 KeptT3d = RealLast(); KeptT2d = 0;
121 NbWorseDecis = 0;
122 }
123 else {
124 // keep best decison
125 if ((thetol3d + thetol2d) < (KeptT3d + KeptT2d)) {
126 KeptMultiCurve = TheMultiCurve;
127 KeptUfirst = myfirstU;
128 KeptUlast = mylastU;
129 KeptT3d = thetol3d;
130 KeptT2d = thetol2d;
131 }
132
133 // cut an interval
134 mylastU = (myfirstU + mylastU)/2;
135 }
136 }
137
138 if (Abs(myfirstU-mylastU) <= TolU) /*break;*/ // pour ne pas planter
139 NbAllowedBadDecis /= 2; // la station.
140
141 // Calcul des parametres sur ce nouvel intervalle.
142 Ok = Compute(Line, myfirstU, mylastU, thetol3d, thetol2d);
143
144 //cout << myfirstU << " - " << mylastU << " tol : " << thetol3d << " " << thetol2d << endl;
145
146 // is new decision better?
147 if ( !Ok && (thetol3d + thetol2d) > (KeptT3d + KeptT2d) )
148 {
149 NbWorseDecis++;
150
151 if (NbWorseDecis > NbAllowedBadDecis) {
152
153 Ok = Standard_True; // stop interval cutting, approx the rest part
154 mylastU = KeptUlast;
155
156 tolreached = Standard_False; // helas
157 myMultiCurves.Append(KeptMultiCurve);
158 Tolers3d.Append (KeptT3d);
159 Tolers2d.Append (KeptT2d);
160 myfirstparam.Append (KeptUfirst);
161 mylastparam.Append (KeptUlast);
162 }
163 }
164
165 begin = Standard_False;
166 } // while (!Finish)
167 }
168}
169
170//=======================================================================
171//function : NbMultiCurves
172//purpose : Returns the number of MultiCurve doing the approximation
173// of the MultiLine.
174//=======================================================================
175
176Standard_Integer Approx_ComputeCLine::NbMultiCurves()const
177{
178 return myMultiCurves.Length();
179}
180
181//=======================================================================
182//function : Value
183//purpose : returns the approximation MultiCurve of range <Index>.
184//=======================================================================
185
186AppParCurves_MultiCurve Approx_ComputeCLine::Value(const Standard_Integer Index)
187const
188{
189 return myMultiCurves.Value(Index);
190}
191
192//=======================================================================
193//function : Compute
194//purpose : is internally used by the algorithms.
195//=======================================================================
196
197Standard_Boolean Approx_ComputeCLine::Compute(const MultiLine& Line,
198 const Standard_Real Ufirst,
199 const Standard_Real Ulast,
200 Standard_Real& TheTol3d,
201 Standard_Real& TheTol2d)
202{
203
204
205 Standard_Integer deg, NbPoints = 24;
206 Standard_Boolean mydone;
207 Standard_Real Fv;
208
209 for (deg = mydegremin; deg <= mydegremax; deg++) {
210
211 AppParCurves_MultiCurve mySCU(deg+1);
212 Approx_MyLeastSquare LSquare(Line, Ufirst, Ulast, myfirstC, mylastC,
213 deg, NbPoints);
214 mydone = LSquare.IsDone();
215 if (mydone) {
216 LSquare.Error(Fv, TheTol3d, TheTol2d);
217 if (TheTol3d <= mytol3d && TheTol2d <= mytol2d) {
218 mySCU = LSquare.Value();
219 // Stockage de la multicurve approximee.
220 tolreached = Standard_True;
221 myMultiCurves.Append(mySCU);
222 myfirstparam.Append(Ufirst);
223 mylastparam.Append(Ulast);
224 Tolers3d.Append(TheTol3d);
225 Tolers2d.Append(TheTol2d);
226 return Standard_True;
227 }
228 }
229 if (deg == mydegremax) {
230 TheMultiCurve = LSquare.Value();
231 currenttol3d = TheTol3d;
232 currenttol2d = TheTol2d;
233 }
234
235 }
236 return Standard_False;
237}
238
239//=======================================================================
240//function : Parameters
241//purpose : returns the first and last parameters of the
242// <Index> MultiCurve.
243//=======================================================================
244
245void Approx_ComputeCLine::Parameters(const Standard_Integer Index,
246 Standard_Real& firstpar,
247 Standard_Real& lastpar) const
248{
249 firstpar = myfirstparam.Value(Index);
250 lastpar = mylastparam.Value(Index);
251}
252
253//=======================================================================
254//function : SetDegrees
255//purpose : changes the degrees of the approximation.
256//=======================================================================
257
258void Approx_ComputeCLine::SetDegrees(const Standard_Integer degreemin,
259 const Standard_Integer degreemax)
260{
261 mydegremin = degreemin;
262 mydegremax = degreemax;
263}
264
265//=======================================================================
266//function : SetTolerances
267//purpose : Changes the tolerances of the approximation.
268//=======================================================================
269
270void Approx_ComputeCLine::SetTolerances(const Standard_Real Tolerance3d,
271 const Standard_Real Tolerance2d)
272{
273 mytol3d = Tolerance3d;
274 mytol2d = Tolerance2d;
275}
276
277//=======================================================================
278//function : SetConstraints
279//purpose : Changes the constraints of the approximation.
280//=======================================================================
281
282void Approx_ComputeCLine::SetConstraints(const AppParCurves_Constraint FirstC,
283 const AppParCurves_Constraint LastC)
284{
285 myfirstC = FirstC;
286 mylastC = LastC;
287}
288
289//=======================================================================
290//function : IsAllApproximated
291//purpose : returns False if at a moment of the approximation,
292// the status NoApproximation has been sent by the user
293// when more points were needed.
294//=======================================================================
295
296Standard_Boolean Approx_ComputeCLine::IsAllApproximated()
297const {
298 return alldone;
299}
300
301//=======================================================================
302//function : IsToleranceReached
303//purpose : returns False if the status NoPointsAdded has been sent.
304//=======================================================================
305
306Standard_Boolean Approx_ComputeCLine::IsToleranceReached()
307const {
308 return tolreached;
309}
310
311//=======================================================================
312//function : Error
313//purpose : returns the tolerances 2d and 3d of the <Index> MultiCurve.
314//=======================================================================
315
316void Approx_ComputeCLine::Error(const Standard_Integer Index,
317 Standard_Real& tol3d,
318 Standard_Real& tol2d) const
319{
320 tol3d = Tolers3d.Value(Index);
321 tol2d = Tolers2d.Value(Index);
322}