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