b311480e |
1 | // Created on: 1995-05-30 |
2 | // Created by: Xavier BENVENISTE |
3 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
17 | // 19-06-96 : JPI : NbPoles doit utiliser ColLength() au lieu de RowLength() |
18 | // 16-09-96 : PMN : On ne doit pas se soucier de la continuite lorsqu'il n'y |
19 | // qu'un seul segment(PRO5474). |
20 | // 11-12-96 : PMN : Respect de l'indicage des tableaux passer en arguments |
21 | // TrueIntervals et PolynomialIntervals (BUC40077) |
22 | // 15-04-97 : PMN : Constructeurs avec un seul segement ou differentes |
23 | // continuitees. |
24 | |
25 | #define No_Standard_OutOfRange |
26 | |
42cf5bc1 |
27 | |
7fd59977 |
28 | #include <BSplCLib.hxx> |
42cf5bc1 |
29 | #include <Convert_CompPolynomialToPoles.hxx> |
30 | #include <PLib.hxx> |
7fd59977 |
31 | #include <Standard_ConstructionError.hxx> |
42cf5bc1 |
32 | #include <Standard_OutOfRange.hxx> |
33 | #include <TColStd_Array1OfInteger.hxx> |
34 | #include <TColStd_Array1OfReal.hxx> |
35 | #include <TColStd_HArray1OfInteger.hxx> |
36 | #include <TColStd_HArray1OfReal.hxx> |
7fd59977 |
37 | |
38 | //======================================================================= |
39 | //function : Constructor |
40 | //purpose : |
41 | //======================================================================= |
7fd59977 |
42 | Convert_CompPolynomialToPoles::Convert_CompPolynomialToPoles( |
43 | const Standard_Integer NumCurves, |
44 | const Standard_Integer Continuity, |
45 | const Standard_Integer Dimension, |
46 | const Standard_Integer MaxDegree, |
857ffd5e |
47 | const Handle(TColStd_HArray1OfInteger)& NumCoeffPerCurve, |
48 | const Handle(TColStd_HArray1OfReal)& Coefficients, |
49 | const Handle(TColStd_HArray2OfReal)& PolynomialIntervals, |
50 | const Handle(TColStd_HArray1OfReal)& TrueIntervals) |
7fd59977 |
51 | : myDone(Standard_False) |
52 | { |
53 | Standard_Integer ii, delta; |
54 | if (NumCurves <= 0 || |
55 | NumCoeffPerCurve.IsNull() || |
56 | Coefficients.IsNull() || |
57 | PolynomialIntervals.IsNull() || |
58 | TrueIntervals.IsNull() || |
59 | Continuity < 0 || |
60 | MaxDegree <= 0 || |
61 | Dimension <= 0 || |
62 | PolynomialIntervals->RowLength() != 2) { |
9775fa61 |
63 | throw Standard_ConstructionError |
64 | ("Convert_CompPolynomialToPoles:bad arguments"); |
7fd59977 |
65 | } |
66 | myDegree = 0 ; |
67 | |
68 | delta = NumCurves - 1 ; |
69 | for (ii = NumCoeffPerCurve->Lower(); |
70 | ii <= NumCoeffPerCurve->Lower() + delta ; |
71 | ii++) { |
72 | myDegree = Max(NumCoeffPerCurve->Value(ii)-1,myDegree) ; |
73 | } |
74 | if ((Continuity > myDegree)&& (NumCurves>1)) { |
9775fa61 |
75 | throw Standard_ConstructionError |
76 | ("Convert_CompPolynomialToPoles:Continuity is too great"); |
7fd59977 |
77 | } |
78 | // |
79 | // prepare output |
80 | // |
81 | Standard_Integer Tindex, multiplicities ; |
82 | |
83 | myKnots = |
84 | new TColStd_HArray1OfReal(1, NumCurves + 1) ; |
85 | for (ii = 1, Tindex = TrueIntervals->Lower() ; |
86 | ii <= NumCurves + 1 ; ii++,Tindex++ ) { |
87 | myKnots->ChangeArray1().SetValue(ii,TrueIntervals->Value(Tindex)) ; |
88 | } |
89 | |
90 | multiplicities = myDegree - Continuity ; |
91 | myMults = |
92 | new TColStd_HArray1OfInteger(1, NumCurves + 1) ; |
93 | for (ii = 2 ; ii < NumCurves + 1 ; ii++) { |
94 | myMults -> SetValue(ii,multiplicities); |
95 | } |
96 | myMults -> SetValue(1, myDegree + 1) ; |
97 | myMults -> SetValue(NumCurves + 1, myDegree + 1) ; |
98 | |
99 | Perform(NumCurves, MaxDegree, Dimension, |
100 | NumCoeffPerCurve->Array1(), Coefficients->Array1(), |
101 | PolynomialIntervals->Array2(), TrueIntervals->Array1()); |
102 | } |
103 | |
104 | Convert_CompPolynomialToPoles:: |
105 | Convert_CompPolynomialToPoles(const Standard_Integer NumCurves, |
106 | const Standard_Integer Dimension, |
107 | const Standard_Integer MaxDegree, |
108 | const TColStd_Array1OfInteger& Continuity, |
109 | const TColStd_Array1OfInteger& NumCoeffPerCurve, |
110 | const TColStd_Array1OfReal& Coefficients, |
111 | const TColStd_Array2OfReal& PolynomialIntervals, |
112 | const TColStd_Array1OfReal& TrueIntervals) |
113 | : myDone(Standard_False) |
114 | { |
115 | Standard_Integer ii, delta; |
116 | if (NumCurves <= 0 || |
117 | MaxDegree <= 0 || |
118 | Dimension <= 0 || |
119 | PolynomialIntervals.RowLength() != 2) { |
9775fa61 |
120 | throw Standard_ConstructionError |
121 | ("Convert_CompPolynomialToPoles:bad arguments"); |
7fd59977 |
122 | } |
123 | myDegree = 0 ; |
124 | |
125 | delta = NumCurves - 1 ; |
126 | for (ii = NumCoeffPerCurve.Lower(); |
127 | ii <= NumCoeffPerCurve.Lower() + delta ; |
128 | ii++) { |
129 | myDegree = Max(NumCoeffPerCurve.Value(ii)-1,myDegree) ; |
130 | } |
131 | // |
132 | // prepare output |
133 | // |
134 | Standard_Integer Tindex ; |
135 | |
136 | myKnots = |
137 | new TColStd_HArray1OfReal(1, NumCurves + 1) ; |
138 | for (ii = 1, Tindex = TrueIntervals.Lower() ; |
139 | ii <= NumCurves + 1 ; ii++,Tindex++ ) { |
140 | myKnots->ChangeArray1().SetValue(ii,TrueIntervals.Value(Tindex)) ; |
141 | } |
142 | |
143 | myMults = |
144 | new TColStd_HArray1OfInteger(1, NumCurves + 1) ; |
145 | for (ii = 2 ; ii < NumCurves + 1 ; ii++) { |
146 | if ((Continuity(ii) > myDegree)&& (NumCurves>1)) { |
9775fa61 |
147 | throw Standard_ConstructionError |
148 | ("Convert_CompPolynomialToPoles:Continuity is too great"); |
7fd59977 |
149 | } |
150 | |
151 | myMults -> SetValue(ii, myDegree-Continuity(ii) ); |
152 | } |
153 | myMults -> SetValue(1, myDegree + 1) ; |
154 | myMults -> SetValue(NumCurves + 1, myDegree + 1) ; |
155 | |
156 | // Calculs |
157 | Perform(NumCurves, MaxDegree, Dimension, |
158 | NumCoeffPerCurve, Coefficients, |
159 | PolynomialIntervals, TrueIntervals); |
160 | } |
161 | |
162 | Convert_CompPolynomialToPoles:: |
163 | Convert_CompPolynomialToPoles(const Standard_Integer Dimension, |
164 | const Standard_Integer MaxDegree, |
165 | const Standard_Integer Degree, |
166 | const TColStd_Array1OfReal& Coefficients, |
167 | const TColStd_Array1OfReal& PolynomialIntervals, |
168 | const TColStd_Array1OfReal& TrueIntervals) : |
169 | myDegree(Degree) , |
170 | myDone(Standard_False) |
171 | |
172 | { |
173 | if (MaxDegree <= 0 || |
174 | Dimension <= 0 || |
175 | PolynomialIntervals.Length() != 2) |
176 | { |
9775fa61 |
177 | throw Standard_ConstructionError |
178 | ("Convert_CompPolynomialToPoles:bad arguments"); |
7fd59977 |
179 | } |
180 | |
181 | TColStd_Array2OfReal ThePolynomialIntervals(1,1,1,2); |
182 | ThePolynomialIntervals.SetValue(1,1,PolynomialIntervals(PolynomialIntervals.Lower())); |
183 | ThePolynomialIntervals.SetValue(1,2,PolynomialIntervals(PolynomialIntervals.Upper())); |
184 | |
185 | TColStd_Array1OfInteger NumCoeffPerCurve(1,1); |
186 | NumCoeffPerCurve(1) = Degree+1; |
187 | |
188 | myKnots = |
189 | new TColStd_HArray1OfReal(1, 2) ; |
190 | myKnots->ChangeArray1().SetValue(1, TrueIntervals.Value(TrueIntervals.Lower())); |
191 | myKnots->ChangeArray1().SetValue(2, TrueIntervals.Value(TrueIntervals.Lower()+1)); |
192 | |
193 | myMults = |
194 | new TColStd_HArray1OfInteger(1, 2) ; |
195 | myMults->Init( myDegree + 1); |
196 | |
197 | |
198 | // Calculs |
199 | Perform(1, MaxDegree, Dimension, |
200 | NumCoeffPerCurve, Coefficients, |
201 | ThePolynomialIntervals, TrueIntervals); |
202 | } |
203 | |
204 | void Convert_CompPolynomialToPoles:: |
205 | Perform(const Standard_Integer NumCurves, |
206 | const Standard_Integer MaxDegree, |
207 | const Standard_Integer Dimension, |
208 | const TColStd_Array1OfInteger& NumCoeffPerCurve, |
209 | const TColStd_Array1OfReal& Coefficients, |
210 | const TColStd_Array2OfReal& PolynomialIntervals, |
211 | const TColStd_Array1OfReal& TrueIntervals) |
212 | { |
213 | Standard_Integer ii, |
214 | num_flat_knots, |
215 | index, Tindex, Pindex, |
216 | coeff_index, |
217 | inversion_problem, |
218 | poles_index, |
219 | num_poles ; |
220 | Standard_Real normalized_value, |
221 | *coefficient_array, |
222 | *poles_array ; |
223 | |
224 | num_flat_knots = 2 * myDegree + 2 ; |
225 | for (ii=2; ii<myMults->Length(); ii++) { |
226 | num_flat_knots += myMults->Value(ii); |
227 | } |
228 | num_poles = num_flat_knots - myDegree - 1 ; |
229 | |
230 | myFlatKnots = new TColStd_HArray1OfReal(1,num_flat_knots) ; |
231 | BSplCLib::KnotSequence (myKnots->Array1(), |
232 | myMults->Array1(), |
233 | myDegree, |
234 | Standard_False, |
235 | myFlatKnots->ChangeArray1()); |
236 | |
237 | TColStd_Array1OfReal parameters(1,num_poles) ; |
238 | BSplCLib::BuildSchoenbergPoints(myDegree, |
239 | myFlatKnots->Array1(), |
240 | parameters) ; |
241 | myPoles = new TColStd_HArray2OfReal(1, num_poles, |
242 | 1, Dimension) ; |
243 | index = 2; |
244 | Tindex = TrueIntervals.Lower()+1; |
245 | Pindex = PolynomialIntervals.LowerRow(); |
246 | poles_array = |
247 | (Standard_Real *) &(myPoles->ChangeArray2()).Value(1,1) ; |
248 | |
249 | TColStd_Array1OfInteger contact_array(1,num_poles) ; |
250 | |
251 | poles_index = 0 ; |
252 | for (ii = 1 ; ii <= num_poles ; ii++, poles_index += Dimension) { |
253 | contact_array.SetValue(ii,0) ; |
254 | while (parameters.Value(ii) >= TrueIntervals(Tindex) && |
255 | index <= NumCurves) { |
256 | index++; Tindex++; Pindex++; |
257 | } |
258 | // |
259 | // normalized value so that it fits the original intervals for |
260 | // the polynomial definition of the curves |
261 | // |
262 | normalized_value = parameters.Value(ii) - TrueIntervals(Tindex-1) ; |
263 | normalized_value /= TrueIntervals(Tindex) |
264 | - TrueIntervals(Tindex-1) ; |
265 | normalized_value = (1.0e0 -normalized_value) * |
266 | PolynomialIntervals(Pindex, PolynomialIntervals.LowerCol()) |
267 | + normalized_value * |
268 | PolynomialIntervals(Pindex, PolynomialIntervals.UpperCol()) ; |
269 | coeff_index = ((index-2) * Dimension * (Max(MaxDegree, myDegree) + 1)) |
270 | + Coefficients.Lower(); |
271 | |
272 | coefficient_array = |
273 | (Standard_Real *) &(Coefficients(coeff_index)) ; |
274 | Standard_Integer Deg = NumCoeffPerCurve(NumCoeffPerCurve.Lower()+index-2) - 1; |
275 | |
276 | PLib::NoDerivativeEvalPolynomial |
277 | (normalized_value, |
278 | Deg, |
279 | Dimension, |
280 | Deg * Dimension, |
281 | coefficient_array[0], |
282 | poles_array[poles_index]) ; |
283 | } |
284 | // |
285 | // interpolation at schoenberg points should yield the desired |
286 | // result |
287 | // |
288 | BSplCLib::Interpolate(myDegree, |
289 | myFlatKnots->Array1(), |
290 | parameters, |
291 | contact_array, |
292 | Dimension, |
293 | poles_array[0], |
294 | inversion_problem) ; |
295 | if (inversion_problem != 0) { |
9775fa61 |
296 | throw Standard_ConstructionError |
297 | ("Convert_CompPolynomialToPoles:inversion_problem"); |
7fd59977 |
298 | } |
299 | myDone = Standard_True ; |
300 | } |
301 | |
302 | |
303 | |
304 | //======================================================================= |
305 | //function : NbPoles |
306 | //purpose : |
307 | //======================================================================= |
308 | |
309 | Standard_Integer Convert_CompPolynomialToPoles::NbPoles() const |
310 | { |
311 | if (myDone) { |
312 | return myPoles->ColLength() ; |
313 | } |
314 | else |
315 | return 0 ; |
316 | } |
317 | //======================================================================= |
318 | //function : Poles |
319 | //purpose : |
320 | //======================================================================= |
321 | |
322 | void Convert_CompPolynomialToPoles::Poles( |
857ffd5e |
323 | Handle(TColStd_HArray2OfReal)& P) const |
7fd59977 |
324 | { if (myDone) { |
325 | P = myPoles ; } |
326 | } |
327 | //======================================================================= |
328 | //function : NbKnots |
329 | //purpose : |
330 | //======================================================================= |
331 | |
332 | Standard_Integer Convert_CompPolynomialToPoles::NbKnots() const |
333 | { |
334 | if (myDone) { |
335 | return myKnots->Length() ; |
336 | } |
337 | else |
338 | return 0 ; |
339 | } |
340 | //======================================================================= |
341 | //function : Knots |
342 | //purpose : |
343 | //======================================================================= |
344 | |
345 | void Convert_CompPolynomialToPoles::Knots( |
857ffd5e |
346 | Handle(TColStd_HArray1OfReal)& K) const |
7fd59977 |
347 | { if (myDone) { |
348 | K = myKnots ; } |
349 | } |
350 | |
351 | //======================================================================= |
352 | //function : Knots |
353 | //purpose : |
354 | //======================================================================= |
355 | |
356 | void Convert_CompPolynomialToPoles::Multiplicities( |
857ffd5e |
357 | Handle(TColStd_HArray1OfInteger)& M) const |
7fd59977 |
358 | { if (myDone) { |
359 | M = myMults ; } |
360 | } |
361 | //======================================================================= |
362 | //function : IsDone |
363 | //purpose : |
364 | //======================================================================= |
365 | |
366 | Standard_Boolean Convert_CompPolynomialToPoles::IsDone() const |
367 | { return myDone ; } |
368 | //======================================================================= |
369 | //function : IsDone |
370 | //purpose : |
371 | //======================================================================= |
372 | |
373 | Standard_Integer Convert_CompPolynomialToPoles::Degree() const |
374 | { |
375 | if (myDone) { |
376 | return myDegree ; |
377 | } |
378 | return 0 ; |
379 | } |