1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
20 // modified by Edward AGAPOV (eap) Tue Apr 2 2002 (occ265)
21 // -- stop cutting an interval to approximate if next decisions
22 // -- get worse on and on
26 #include <Approx_ParametrizationType.hxx>
27 #include Approx_MyLeastSquare_hxx
28 #include <TColStd_Array1OfReal.hxx>
29 #include <AppParCurves_Constraint.hxx>
30 #include <Approx_Status.hxx>
32 //=======================================================================
33 //function : Approx_ComputeCLine
34 //purpose : The MultiLine <Line> will be approximated until tolerances
36 // The approximation will be done from degreemin to degreemax
37 // with a cutting if the corresponding boolean is True.
38 //=======================================================================
40 Approx_ComputeCLine::Approx_ComputeCLine
41 (const MultiLine& Line,
42 const Standard_Integer degreemin,
43 const Standard_Integer degreemax,
44 const Standard_Real Tolerance3d,
45 const Standard_Real Tolerance2d,
46 const Standard_Boolean cutting,
47 const AppParCurves_Constraint FirstC,
48 const AppParCurves_Constraint LastC)
50 mydegremin = degreemin;
51 mydegremax = degreemax;
52 mytol3d = Tolerance3d;
53 mytol2d = Tolerance2d;
57 alldone = Standard_False;
61 //=======================================================================
62 //function : Approx_ComputeCLine
63 //purpose : Initializes the fields of the algorithm.
64 //=======================================================================
66 Approx_ComputeCLine::Approx_ComputeCLine
67 (const Standard_Integer degreemin,
68 const Standard_Integer degreemax,
69 const Standard_Real Tolerance3d,
70 const Standard_Real Tolerance2d,
71 const Standard_Boolean cutting,
72 const AppParCurves_Constraint FirstC,
73 const AppParCurves_Constraint LastC)
75 alldone = Standard_False;
76 mydegremin = degreemin;
77 mydegremax = degreemax;
78 mytol3d = Tolerance3d;
79 mytol2d = Tolerance2d;
85 //=======================================================================
87 //purpose : runs the algorithm after having initialized the fields.
88 //=======================================================================
90 void Approx_ComputeCLine::Perform(const MultiLine& Line)
94 Standard_Real UFirst, ULast;
95 Standard_Boolean Finish = Standard_False,
96 begin = Standard_True, Ok = Standard_False;
97 Standard_Real thetol3d, thetol2d;
98 UFirst = LineTool::FirstParameter(Line);
99 ULast = LineTool::LastParameter(Line);
100 Standard_Real TolU = (ULast-UFirst)*1.e-05;
101 Standard_Real myfirstU = UFirst;
102 Standard_Real mylastU = ULast;
105 alldone = Compute(Line, UFirst, ULast, thetol3d, thetol2d);
107 tolreached = Standard_False;
108 myfirstparam.Append(UFirst);
109 mylastparam.Append(ULast);
110 myMultiCurves.Append(TheMultiCurve);
111 Tolers3d.Append(currenttol3d);
112 Tolers2d.Append(currenttol2d);
117 // previous decision to be taken if we get worse with next cut (eap)
118 AppParCurves_MultiCurve KeptMultiCurve;
119 Standard_Real KeptUfirst, KeptUlast, KeptT3d, KeptT2d;
120 Standard_Integer NbWorseDecis = 0, NbAllowedBadDecis = 10;
122 KeptT3d = RealLast(); KeptT2d = 0;
126 // Gestion du decoupage de la multiline pour approximer:
129 // Calcul de la partie a approximer.
132 if (Abs(ULast-myfirstU) <= RealEpsilon()) {
133 Finish = Standard_True;
134 alldone = Standard_True;
137 KeptT3d = RealLast(); KeptT2d = 0;
142 if ((thetol3d + thetol2d) < (KeptT3d + KeptT2d)) {
143 KeptMultiCurve = TheMultiCurve;
144 KeptUfirst = myfirstU;
151 mylastU = (myfirstU + mylastU)/2;
155 if (Abs(myfirstU-mylastU) <= TolU) /*break;*/ // pour ne pas planter
156 NbAllowedBadDecis /= 2; // la station.
158 // Calcul des parametres sur ce nouvel intervalle.
159 Ok = Compute(Line, myfirstU, mylastU, thetol3d, thetol2d);
161 //cout << myfirstU << " - " << mylastU << " tol : " << thetol3d << " " << thetol2d << endl;
163 // is new decision better?
164 if ( !Ok && (thetol3d + thetol2d) > (KeptT3d + KeptT2d) )
168 if (NbWorseDecis > NbAllowedBadDecis) {
170 Ok = Standard_True; // stop interval cutting, approx the rest part
173 tolreached = Standard_False; // helas
174 myMultiCurves.Append(KeptMultiCurve);
175 Tolers3d.Append (KeptT3d);
176 Tolers2d.Append (KeptT2d);
177 myfirstparam.Append (KeptUfirst);
178 mylastparam.Append (KeptUlast);
182 begin = Standard_False;
187 //=======================================================================
188 //function : NbMultiCurves
189 //purpose : Returns the number of MultiCurve doing the approximation
191 //=======================================================================
193 Standard_Integer Approx_ComputeCLine::NbMultiCurves()const
195 return myMultiCurves.Length();
198 //=======================================================================
200 //purpose : returns the approximation MultiCurve of range <Index>.
201 //=======================================================================
203 AppParCurves_MultiCurve Approx_ComputeCLine::Value(const Standard_Integer Index)
206 return myMultiCurves.Value(Index);
209 //=======================================================================
211 //purpose : is internally used by the algorithms.
212 //=======================================================================
214 Standard_Boolean Approx_ComputeCLine::Compute(const MultiLine& Line,
215 const Standard_Real Ufirst,
216 const Standard_Real Ulast,
217 Standard_Real& TheTol3d,
218 Standard_Real& TheTol2d)
222 Standard_Integer deg, NbPoints = 24;
223 Standard_Boolean mydone;
226 for (deg = mydegremin; deg <= mydegremax; deg++) {
228 AppParCurves_MultiCurve mySCU(deg+1);
229 Approx_MyLeastSquare LSquare(Line, Ufirst, Ulast, myfirstC, mylastC,
231 mydone = LSquare.IsDone();
233 LSquare.Error(Fv, TheTol3d, TheTol2d);
234 if (TheTol3d <= mytol3d && TheTol2d <= mytol2d) {
235 mySCU = LSquare.Value();
236 // Stockage de la multicurve approximee.
237 tolreached = Standard_True;
238 myMultiCurves.Append(mySCU);
239 myfirstparam.Append(Ufirst);
240 mylastparam.Append(Ulast);
241 Tolers3d.Append(TheTol3d);
242 Tolers2d.Append(TheTol2d);
243 return Standard_True;
246 if (deg == mydegremax) {
247 TheMultiCurve = LSquare.Value();
248 currenttol3d = TheTol3d;
249 currenttol2d = TheTol2d;
253 return Standard_False;
256 //=======================================================================
257 //function : Parameters
258 //purpose : returns the first and last parameters of the
259 // <Index> MultiCurve.
260 //=======================================================================
262 void Approx_ComputeCLine::Parameters(const Standard_Integer Index,
263 Standard_Real& firstpar,
264 Standard_Real& lastpar) const
266 firstpar = myfirstparam.Value(Index);
267 lastpar = mylastparam.Value(Index);
270 //=======================================================================
271 //function : SetDegrees
272 //purpose : changes the degrees of the approximation.
273 //=======================================================================
275 void Approx_ComputeCLine::SetDegrees(const Standard_Integer degreemin,
276 const Standard_Integer degreemax)
278 mydegremin = degreemin;
279 mydegremax = degreemax;
282 //=======================================================================
283 //function : SetTolerances
284 //purpose : Changes the tolerances of the approximation.
285 //=======================================================================
287 void Approx_ComputeCLine::SetTolerances(const Standard_Real Tolerance3d,
288 const Standard_Real Tolerance2d)
290 mytol3d = Tolerance3d;
291 mytol2d = Tolerance2d;
294 //=======================================================================
295 //function : SetConstraints
296 //purpose : Changes the constraints of the approximation.
297 //=======================================================================
299 void Approx_ComputeCLine::SetConstraints(const AppParCurves_Constraint FirstC,
300 const AppParCurves_Constraint LastC)
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 //=======================================================================
313 Standard_Boolean Approx_ComputeCLine::IsAllApproximated()
318 //=======================================================================
319 //function : IsToleranceReached
320 //purpose : returns False if the status NoPointsAdded has been sent.
321 //=======================================================================
323 Standard_Boolean Approx_ComputeCLine::IsToleranceReached()
328 //=======================================================================
330 //purpose : returns the tolerances 2d and 3d of the <Index> MultiCurve.
331 //=======================================================================
333 void Approx_ComputeCLine::Error(const Standard_Integer Index,
334 Standard_Real& tol3d,
335 Standard_Real& tol2d) const
337 tol3d = Tolers3d.Value(Index);
338 tol2d = Tolers2d.Value(Index);