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
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.
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.
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.
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
30 #define No_Standard_OutOfRange
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>
38 #include <BSplCLib.hxx>
39 #include <Standard_ConstructionError.hxx>
41 //=======================================================================
42 //function : Constructor
44 //=======================================================================
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)
57 Standard_Integer ii, delta;
59 NumCoeffPerCurve.IsNull() ||
60 Coefficients.IsNull() ||
61 PolynomialIntervals.IsNull() ||
62 TrueIntervals.IsNull() ||
66 PolynomialIntervals->RowLength() != 2) {
67 Standard_ConstructionError::
68 Raise("Convert_CompPolynomialToPoles:bad arguments");
72 delta = NumCurves - 1 ;
73 for (ii = NumCoeffPerCurve->Lower();
74 ii <= NumCoeffPerCurve->Lower() + delta ;
76 myDegree = Max(NumCoeffPerCurve->Value(ii)-1,myDegree) ;
78 if ((Continuity > myDegree)&& (NumCurves>1)) {
79 Standard_ConstructionError::
80 Raise("Convert_CompPolynomialToPoles:Continuity is too great");
85 Standard_Integer Tindex, multiplicities ;
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)) ;
94 multiplicities = myDegree - Continuity ;
96 new TColStd_HArray1OfInteger(1, NumCurves + 1) ;
97 for (ii = 2 ; ii < NumCurves + 1 ; ii++) {
98 myMults -> SetValue(ii,multiplicities);
100 myMults -> SetValue(1, myDegree + 1) ;
101 myMults -> SetValue(NumCurves + 1, myDegree + 1) ;
103 Perform(NumCurves, MaxDegree, Dimension,
104 NumCoeffPerCurve->Array1(), Coefficients->Array1(),
105 PolynomialIntervals->Array2(), TrueIntervals->Array1());
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)
119 Standard_Integer ii, delta;
120 if (NumCurves <= 0 ||
123 PolynomialIntervals.RowLength() != 2) {
124 Standard_ConstructionError::
125 Raise("Convert_CompPolynomialToPoles:bad arguments");
129 delta = NumCurves - 1 ;
130 for (ii = NumCoeffPerCurve.Lower();
131 ii <= NumCoeffPerCurve.Lower() + delta ;
133 myDegree = Max(NumCoeffPerCurve.Value(ii)-1,myDegree) ;
138 Standard_Integer Tindex ;
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)) ;
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");
155 myMults -> SetValue(ii, myDegree-Continuity(ii) );
157 myMults -> SetValue(1, myDegree + 1) ;
158 myMults -> SetValue(NumCurves + 1, myDegree + 1) ;
161 Perform(NumCurves, MaxDegree, Dimension,
162 NumCoeffPerCurve, Coefficients,
163 PolynomialIntervals, TrueIntervals);
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) :
174 myDone(Standard_False)
177 if (MaxDegree <= 0 ||
179 PolynomialIntervals.Length() != 2)
181 Standard_ConstructionError::
182 Raise("Convert_CompPolynomialToPoles:bad arguments");
185 TColStd_Array2OfReal ThePolynomialIntervals(1,1,1,2);
186 ThePolynomialIntervals.SetValue(1,1,PolynomialIntervals(PolynomialIntervals.Lower()));
187 ThePolynomialIntervals.SetValue(1,2,PolynomialIntervals(PolynomialIntervals.Upper()));
189 TColStd_Array1OfInteger NumCoeffPerCurve(1,1);
190 NumCoeffPerCurve(1) = Degree+1;
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));
198 new TColStd_HArray1OfInteger(1, 2) ;
199 myMults->Init( myDegree + 1);
203 Perform(1, MaxDegree, Dimension,
204 NumCoeffPerCurve, Coefficients,
205 ThePolynomialIntervals, TrueIntervals);
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)
219 index, Tindex, Pindex,
224 Standard_Real normalized_value,
228 num_flat_knots = 2 * myDegree + 2 ;
229 for (ii=2; ii<myMults->Length(); ii++) {
230 num_flat_knots += myMults->Value(ii);
232 num_poles = num_flat_knots - myDegree - 1 ;
234 myFlatKnots = new TColStd_HArray1OfReal(1,num_flat_knots) ;
235 BSplCLib::KnotSequence (myKnots->Array1(),
239 myFlatKnots->ChangeArray1());
241 TColStd_Array1OfReal parameters(1,num_poles) ;
242 BSplCLib::BuildSchoenbergPoints(myDegree,
243 myFlatKnots->Array1(),
245 myPoles = new TColStd_HArray2OfReal(1, num_poles,
248 Tindex = TrueIntervals.Lower()+1;
249 Pindex = PolynomialIntervals.LowerRow();
251 (Standard_Real *) &(myPoles->ChangeArray2()).Value(1,1) ;
253 TColStd_Array1OfInteger contact_array(1,num_poles) ;
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++;
263 // normalized value so that it fits the original intervals for
264 // the polynomial definition of the curves
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())
272 PolynomialIntervals(Pindex, PolynomialIntervals.UpperCol()) ;
273 coeff_index = ((index-2) * Dimension * (Max(MaxDegree, myDegree) + 1))
274 + Coefficients.Lower();
277 (Standard_Real *) &(Coefficients(coeff_index)) ;
278 Standard_Integer Deg = NumCoeffPerCurve(NumCoeffPerCurve.Lower()+index-2) - 1;
280 PLib::NoDerivativeEvalPolynomial
285 coefficient_array[0],
286 poles_array[poles_index]) ;
289 // interpolation at schoenberg points should yield the desired
292 BSplCLib::Interpolate(myDegree,
293 myFlatKnots->Array1(),
299 if (inversion_problem != 0) {
300 Standard_ConstructionError::
301 Raise("Convert_CompPolynomialToPoles:inversion_problem");
303 myDone = Standard_True ;
308 //=======================================================================
311 //=======================================================================
313 Standard_Integer Convert_CompPolynomialToPoles::NbPoles() const
316 return myPoles->ColLength() ;
321 //=======================================================================
324 //=======================================================================
326 void Convert_CompPolynomialToPoles::Poles(
327 Handle_TColStd_HArray2OfReal& P) const
331 //=======================================================================
334 //=======================================================================
336 Standard_Integer Convert_CompPolynomialToPoles::NbKnots() const
339 return myKnots->Length() ;
344 //=======================================================================
347 //=======================================================================
349 void Convert_CompPolynomialToPoles::Knots(
350 Handle_TColStd_HArray1OfReal& K) const
355 //=======================================================================
358 //=======================================================================
360 void Convert_CompPolynomialToPoles::Multiplicities(
361 Handle_TColStd_HArray1OfInteger& M) const
365 //=======================================================================
368 //=======================================================================
370 Standard_Boolean Convert_CompPolynomialToPoles::IsDone() const
372 //=======================================================================
375 //=======================================================================
377 Standard_Integer Convert_CompPolynomialToPoles::Degree() const