1 // Created on: 1995-05-30
2 // Created by: Xavier BENVENISTE
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
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
25 #define No_Standard_OutOfRange
28 #include <BSplCLib.hxx>
29 #include <Convert_CompPolynomialToPoles.hxx>
31 #include <Standard_ConstructionError.hxx>
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>
38 //=======================================================================
39 //function : Constructor
41 //=======================================================================
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,
47 const Handle(TColStd_HArray1OfInteger)& NumCoeffPerCurve,
48 const Handle(TColStd_HArray1OfReal)& Coefficients,
49 const Handle(TColStd_HArray2OfReal)& PolynomialIntervals,
50 const Handle(TColStd_HArray1OfReal)& TrueIntervals)
51 : myDone(Standard_False)
53 Standard_Integer ii, delta;
55 NumCoeffPerCurve.IsNull() ||
56 Coefficients.IsNull() ||
57 PolynomialIntervals.IsNull() ||
58 TrueIntervals.IsNull() ||
62 PolynomialIntervals->RowLength() != 2) {
63 Standard_ConstructionError::
64 Raise("Convert_CompPolynomialToPoles:bad arguments");
68 delta = NumCurves - 1 ;
69 for (ii = NumCoeffPerCurve->Lower();
70 ii <= NumCoeffPerCurve->Lower() + delta ;
72 myDegree = Max(NumCoeffPerCurve->Value(ii)-1,myDegree) ;
74 if ((Continuity > myDegree)&& (NumCurves>1)) {
75 Standard_ConstructionError::
76 Raise("Convert_CompPolynomialToPoles:Continuity is too great");
81 Standard_Integer Tindex, multiplicities ;
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)) ;
90 multiplicities = myDegree - Continuity ;
92 new TColStd_HArray1OfInteger(1, NumCurves + 1) ;
93 for (ii = 2 ; ii < NumCurves + 1 ; ii++) {
94 myMults -> SetValue(ii,multiplicities);
96 myMults -> SetValue(1, myDegree + 1) ;
97 myMults -> SetValue(NumCurves + 1, myDegree + 1) ;
99 Perform(NumCurves, MaxDegree, Dimension,
100 NumCoeffPerCurve->Array1(), Coefficients->Array1(),
101 PolynomialIntervals->Array2(), TrueIntervals->Array1());
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)
115 Standard_Integer ii, delta;
116 if (NumCurves <= 0 ||
119 PolynomialIntervals.RowLength() != 2) {
120 Standard_ConstructionError::
121 Raise("Convert_CompPolynomialToPoles:bad arguments");
125 delta = NumCurves - 1 ;
126 for (ii = NumCoeffPerCurve.Lower();
127 ii <= NumCoeffPerCurve.Lower() + delta ;
129 myDegree = Max(NumCoeffPerCurve.Value(ii)-1,myDegree) ;
134 Standard_Integer Tindex ;
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)) ;
144 new TColStd_HArray1OfInteger(1, NumCurves + 1) ;
145 for (ii = 2 ; ii < NumCurves + 1 ; ii++) {
146 if ((Continuity(ii) > myDegree)&& (NumCurves>1)) {
147 Standard_ConstructionError::
148 Raise("Convert_CompPolynomialToPoles:Continuity is too great");
151 myMults -> SetValue(ii, myDegree-Continuity(ii) );
153 myMults -> SetValue(1, myDegree + 1) ;
154 myMults -> SetValue(NumCurves + 1, myDegree + 1) ;
157 Perform(NumCurves, MaxDegree, Dimension,
158 NumCoeffPerCurve, Coefficients,
159 PolynomialIntervals, TrueIntervals);
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) :
170 myDone(Standard_False)
173 if (MaxDegree <= 0 ||
175 PolynomialIntervals.Length() != 2)
177 Standard_ConstructionError::
178 Raise("Convert_CompPolynomialToPoles:bad arguments");
181 TColStd_Array2OfReal ThePolynomialIntervals(1,1,1,2);
182 ThePolynomialIntervals.SetValue(1,1,PolynomialIntervals(PolynomialIntervals.Lower()));
183 ThePolynomialIntervals.SetValue(1,2,PolynomialIntervals(PolynomialIntervals.Upper()));
185 TColStd_Array1OfInteger NumCoeffPerCurve(1,1);
186 NumCoeffPerCurve(1) = Degree+1;
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));
194 new TColStd_HArray1OfInteger(1, 2) ;
195 myMults->Init( myDegree + 1);
199 Perform(1, MaxDegree, Dimension,
200 NumCoeffPerCurve, Coefficients,
201 ThePolynomialIntervals, TrueIntervals);
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)
215 index, Tindex, Pindex,
220 Standard_Real normalized_value,
224 num_flat_knots = 2 * myDegree + 2 ;
225 for (ii=2; ii<myMults->Length(); ii++) {
226 num_flat_knots += myMults->Value(ii);
228 num_poles = num_flat_knots - myDegree - 1 ;
230 myFlatKnots = new TColStd_HArray1OfReal(1,num_flat_knots) ;
231 BSplCLib::KnotSequence (myKnots->Array1(),
235 myFlatKnots->ChangeArray1());
237 TColStd_Array1OfReal parameters(1,num_poles) ;
238 BSplCLib::BuildSchoenbergPoints(myDegree,
239 myFlatKnots->Array1(),
241 myPoles = new TColStd_HArray2OfReal(1, num_poles,
244 Tindex = TrueIntervals.Lower()+1;
245 Pindex = PolynomialIntervals.LowerRow();
247 (Standard_Real *) &(myPoles->ChangeArray2()).Value(1,1) ;
249 TColStd_Array1OfInteger contact_array(1,num_poles) ;
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++;
259 // normalized value so that it fits the original intervals for
260 // the polynomial definition of the curves
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())
268 PolynomialIntervals(Pindex, PolynomialIntervals.UpperCol()) ;
269 coeff_index = ((index-2) * Dimension * (Max(MaxDegree, myDegree) + 1))
270 + Coefficients.Lower();
273 (Standard_Real *) &(Coefficients(coeff_index)) ;
274 Standard_Integer Deg = NumCoeffPerCurve(NumCoeffPerCurve.Lower()+index-2) - 1;
276 PLib::NoDerivativeEvalPolynomial
281 coefficient_array[0],
282 poles_array[poles_index]) ;
285 // interpolation at schoenberg points should yield the desired
288 BSplCLib::Interpolate(myDegree,
289 myFlatKnots->Array1(),
295 if (inversion_problem != 0) {
296 Standard_ConstructionError::
297 Raise("Convert_CompPolynomialToPoles:inversion_problem");
299 myDone = Standard_True ;
304 //=======================================================================
307 //=======================================================================
309 Standard_Integer Convert_CompPolynomialToPoles::NbPoles() const
312 return myPoles->ColLength() ;
317 //=======================================================================
320 //=======================================================================
322 void Convert_CompPolynomialToPoles::Poles(
323 Handle(TColStd_HArray2OfReal)& P) const
327 //=======================================================================
330 //=======================================================================
332 Standard_Integer Convert_CompPolynomialToPoles::NbKnots() const
335 return myKnots->Length() ;
340 //=======================================================================
343 //=======================================================================
345 void Convert_CompPolynomialToPoles::Knots(
346 Handle(TColStd_HArray1OfReal)& K) const
351 //=======================================================================
354 //=======================================================================
356 void Convert_CompPolynomialToPoles::Multiplicities(
357 Handle(TColStd_HArray1OfInteger)& M) const
361 //=======================================================================
364 //=======================================================================
366 Standard_Boolean Convert_CompPolynomialToPoles::IsDone() const
368 //=======================================================================
371 //=======================================================================
373 Standard_Integer Convert_CompPolynomialToPoles::Degree() const