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