0026937: Eliminate NO_CXX_EXCEPTION macro support
[occt.git] / src / Convert / Convert_CompPolynomialToPoles.cxx
CommitLineData
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 42Convert_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
104Convert_CompPolynomialToPoles::
105Convert_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
162Convert_CompPolynomialToPoles::
163Convert_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
204void Convert_CompPolynomialToPoles::
205Perform(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
309Standard_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
322void 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
332Standard_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
345void 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
356void 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
366Standard_Boolean Convert_CompPolynomialToPoles::IsDone() const
367{ return myDone ; }
368//=======================================================================
369//function : IsDone
370//purpose :
371//=======================================================================
372
373Standard_Integer Convert_CompPolynomialToPoles::Degree() const
374{
375 if (myDone) {
376 return myDegree ;
377 }
378 return 0 ;
379}