0024002: Overall code and build procedure refactoring -- automatic
[occt.git] / src / Convert / Convert_ConicToBSplineCurve.cxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 //JCV 16/10/91
16
17 #define No_Standard_OutOfRange
18
19
20 #include <BSplCLib.hxx>
21 #include <Convert_ConicToBSplineCurve.hxx>
22 #include <Convert_CosAndSinEvalFunction.hxx>
23 #include <Convert_PolynomialCosAndSin.hxx>
24 #include <gp.hxx>
25 #include <gp_Pnt2d.hxx>
26 #include <PLib.hxx>
27 #include <Precision.hxx>
28 #include <Standard_ConstructionError.hxx>
29 #include <Standard_OutOfRange.hxx>
30 #include <TColgp_Array1OfPnt.hxx>
31 #include <TColgp_Array1OfPnt2d.hxx>
32 #include <TColgp_HArray1OfPnt2d.hxx>
33 #include <TColStd_Array1OfInteger.hxx>
34 #include <TColStd_Array1OfReal.hxx>
35 #include <TColStd_HArray1OfInteger.hxx>
36 #include <TColStd_HArray1OfReal.hxx>
37
38 //=======================================================================
39 //function : Convert_ConicToBSplineCurve
40 //purpose  : 
41 //=======================================================================
42 Convert_ConicToBSplineCurve::Convert_ConicToBSplineCurve 
43   (const Standard_Integer NbPoles,
44    const Standard_Integer NbKnots,
45    const Standard_Integer Degree  ) 
46 : degree (Degree)    ,  nbPoles (NbPoles)   ,  nbKnots (NbKnots)
47   
48
49   if (NbPoles >= 2) {
50     poles    = new TColgp_HArray1OfPnt2d (1, NbPoles)  ;
51    
52     weights  = new TColStd_HArray1OfReal (1, NbPoles)  ;
53   }
54   if (NbKnots >= 2) {
55     knots    = new TColStd_HArray1OfReal (1, NbKnots)  ;
56     mults    = new TColStd_HArray1OfInteger(1,NbKnots) ;
57   }
58 }
59
60
61 //=======================================================================
62 //function : Degree
63 //purpose  : 
64 //=======================================================================
65
66 Standard_Integer Convert_ConicToBSplineCurve::Degree () const 
67 {
68   return degree;
69 }
70
71 //=======================================================================
72 //function : NbPoles
73 //purpose  : 
74 //=======================================================================
75
76 Standard_Integer Convert_ConicToBSplineCurve::NbPoles () const 
77 {
78  return nbPoles; 
79 }
80
81 //=======================================================================
82 //function : NbKnots
83 //purpose  : 
84 //=======================================================================
85
86 Standard_Integer Convert_ConicToBSplineCurve::NbKnots () const 
87 {
88   return nbKnots;
89 }
90
91 //=======================================================================
92 //function : IsPeriodic
93 //purpose  : 
94 //=======================================================================
95
96 Standard_Boolean Convert_ConicToBSplineCurve::IsPeriodic() const 
97 {
98   return isperiodic;
99 }
100
101 //=======================================================================
102 //function : Pole
103 //purpose  : 
104 //=======================================================================
105
106 gp_Pnt2d Convert_ConicToBSplineCurve::Pole 
107   (const Standard_Integer Index) const 
108 {
109   if (Index < 1 || Index > nbPoles)
110     Standard_OutOfRange::Raise(" ");
111   return poles->Value (Index);
112 }
113
114
115 //=======================================================================
116 //function : Weight
117 //purpose  : 
118 //=======================================================================
119
120 Standard_Real Convert_ConicToBSplineCurve::Weight 
121   (const Standard_Integer Index) const 
122 {
123   if (Index < 1 || Index > nbPoles)
124     Standard_OutOfRange::Raise(" ");
125   return weights->Value (Index);
126 }
127
128
129 //=======================================================================
130 //function : Knot
131 //purpose  : 
132 //=======================================================================
133
134 Standard_Real Convert_ConicToBSplineCurve::Knot 
135   (const Standard_Integer Index) const 
136 {
137   if (Index < 1 || Index > nbKnots)
138     Standard_OutOfRange::Raise(" ");
139   return knots->Value (Index);
140 }
141
142
143 //=======================================================================
144 //function : Multiplicity
145 //purpose  : 
146 //=======================================================================
147
148 Standard_Integer Convert_ConicToBSplineCurve::Multiplicity
149   (const Standard_Integer Index) const 
150 {
151   if (Index < 1 || Index > nbKnots)
152     Standard_OutOfRange::Raise(" ");
153   return mults->Value (Index);
154 }
155 //=======================================================================
156 //function : CosAndSinRationalC1
157 //purpose  : evaluates U(t) and V(t) such that
158 //                      2      2
159 //                     U   -  V 
160 //   cos (theta(t)) = ----------
161 //                      2      2
162 //                     U   +  V 
163 //
164
165 //                      2 * U*V
166 //   sin (theta(t)) = ----------
167 //                      2      2
168 //                     U   +  V 
169 //                                                    2     2
170 //  such that the derivative at the domain bounds of U   + V   is 0.0e0 
171 //  with is helpfull when having to make a C1 BSpline  by merging two
172 //  BSpline toghether
173 //=======================================================================
174
175 void CosAndSinRationalC1(Standard_Real Parameter,
176                           const Standard_Integer         EvalDegree,
177                           const TColgp_Array1OfPnt2d&    EvalPoles,
178                           const TColStd_Array1OfReal&    EvalKnots,
179                           const TColStd_Array1OfInteger& EvalMults,
180                           Standard_Real Result[2]) 
181 {
182  gp_Pnt2d a_point ;
183  BSplCLib::D0(Parameter,
184               0,
185               EvalDegree,
186               Standard_False,
187               EvalPoles,
188               BSplCLib::NoWeights(),
189               EvalKnots,
190               EvalMults,
191               a_point) ;
192  Result[0] = a_point.Coord(1) ;
193  Result[1] = a_point.Coord(2) ;
194 }
195       
196
197 //=======================================================================
198 //function : CosAndSinQuasiAngular
199 //purpose  : evaluates U(t) and V(t) such that
200 //                      2      2
201 //                     U   -  V 
202 //   cos (theta(t)) = ----------
203 //                      2      2
204 //                     U   +  V 
205 //
206
207 //                      2 * U*V
208 //   sin (theta(t)) = ----------
209 //                      2      2
210 //                     U   +  V 
211 //=======================================================================
212
213 void  CosAndSinQuasiAngular(Standard_Real  Parameter,
214                             const Standard_Integer         EvalDegree,
215                             const TColgp_Array1OfPnt2d&    EvalPoles,
216 //                          const TColStd_Array1OfReal&    EvalKnots,
217                             const TColStd_Array1OfReal&    ,
218 //                          const TColStd_Array1OfInteger& EvalMults,
219                             const TColStd_Array1OfInteger& ,
220                             Standard_Real  Result[2])
221 {
222   Standard_Real 
223   param,
224   *coeff ;
225  
226    coeff = (Standard_Real *) &EvalPoles(EvalPoles.Lower()) ;
227 //
228 //   rational_function_coeff represent a rational approximation
229 //   of U ---> cotan( PI * U /2) between [0 1] 
230 //   rational_function_coeff[i][0] is the denominator
231 //   rational_function_coeff[i][1] is the numerator
232 //   
233    param = Parameter * 0.5e0 ;
234   PLib::NoDerivativeEvalPolynomial (param,
235                                     EvalDegree,
236                                     2,
237                                     EvalDegree << 1,
238                                     coeff[0],
239                                     Result[0]) ;
240 }
241    
242 //=======================================================================
243 //function : function that build the Bspline Representation of 
244 // an algorithmic description of the function cos and sin
245 //purpose  : 
246 //=======================================================================
247 void AlgorithmicCosAndSin(Standard_Integer               Degree,
248                           const TColStd_Array1OfReal&    FlatKnots,
249                           const Standard_Integer         EvalDegree,
250                           const TColgp_Array1OfPnt2d&    EvalPoles,
251                           const TColStd_Array1OfReal&    EvalKnots,
252                           const TColStd_Array1OfInteger& EvalMults,
253                           Convert_CosAndSinEvalFunction  Evaluator,
254                           TColStd_Array1OfReal&          CosNumerator,
255                           TColStd_Array1OfReal&          SinNumerator,
256                           TColStd_Array1OfReal&          Denominator) 
257 {
258    Standard_Integer order,
259    num_poles,
260    pivot_index_problem,
261    ii;
262  
263    Standard_Real  result[2],
264    inverse ;
265
266    order = Degree + 1 ;
267    num_poles = FlatKnots.Length() - order ;
268
269    if (num_poles != CosNumerator.Length() ||
270        num_poles != SinNumerator.Length() ||
271        num_poles != Denominator.Length() ) {
272       Standard_ConstructionError::Raise();
273       }
274    TColStd_Array1OfReal      parameters(1,num_poles)  ;
275    TColgp_Array1OfPnt        poles_array(1,num_poles) ;
276    TColStd_Array1OfInteger   contact_order_array(1,num_poles) ;  
277    BSplCLib::BuildSchoenbergPoints(Degree,
278                                    FlatKnots,
279                                    parameters) ;
280    for (ii = parameters.Lower() ; ii <= parameters.Upper() ; ii++) {
281      Evaluator(parameters(ii),
282                EvalDegree,
283                EvalPoles,
284                EvalKnots,
285                EvalMults,
286                result) ;
287      contact_order_array(ii) = 0 ;
288      
289      poles_array(ii).SetCoord(1,
290                               (result[1]*result[1] - result[0]*result[0]));
291      poles_array(ii).SetCoord(2,
292                               2.0e0  * result[1]* result[0]) ;
293      poles_array(ii).SetCoord(3,
294                               result[1]*result[1] + result[0] * result[0]) ;
295    }
296     BSplCLib::Interpolate(Degree,
297                           FlatKnots,
298                           parameters,
299                           contact_order_array,
300                           poles_array,
301                           pivot_index_problem) ;
302     for (ii = 1 ; ii <= num_poles ; ii++) {
303       inverse = 1.0e0 / poles_array(ii).Coord(3) ;
304       CosNumerator(ii) = poles_array(ii).Coord(1) * inverse ;
305       SinNumerator(ii) = poles_array(ii).Coord(2) * inverse ;
306       Denominator(ii)  = poles_array(ii).Coord(3) ;
307     }
308  }
309
310 //=======================================================================
311 //function : BuildCosAndSin
312 //purpose  : 
313 //=======================================================================
314
315 void Convert_ConicToBSplineCurve::BuildCosAndSin(
316           const Convert_ParameterisationType     Parameterisation,
317           const Standard_Real                    UFirst,
318           const Standard_Real                    ULast,
319           Handle(TColStd_HArray1OfReal)&         CosNumeratorPtr,
320           Handle(TColStd_HArray1OfReal)&         SinNumeratorPtr,
321           Handle(TColStd_HArray1OfReal)&         DenominatorPtr,
322           Standard_Integer&                      Degree,
323           Handle(TColStd_HArray1OfReal)&         KnotsPtr,
324           Handle(TColStd_HArray1OfInteger)&      MultsPtr)  const 
325 {
326   Standard_Real delta = ULast - UFirst,
327   direct,
328   inverse,
329   value1,
330   value2,
331   cos_beta,
332   sin_beta,
333   alpha=0,
334   alpha_2,
335   alpha_4,
336   tan_alpha_2,
337   beta,
338   p_param,
339   q_param,
340   param ;
341
342   Standard_Integer num_poles = 0,
343   ii,
344   jj,
345   num_knots = 1,
346   num_spans = 1,
347   num_flat_knots,
348   num_temp_knots,
349   temp_degree = 0,
350   tgt_theta_flag,
351   num_temp_poles,
352   order  = 0;
353
354   Convert_CosAndSinEvalFunction *EvaluatorPtr=NULL ;
355
356   tgt_theta_flag = 0 ;
357
358
359   switch (Parameterisation) {
360   case Convert_TgtThetaOver2: 
361     num_spans =
362       (Standard_Integer)IntegerPart( 1.2 * delta / M_PI) + 1;
363     
364     tgt_theta_flag = 1 ;
365     break ;
366   case Convert_TgtThetaOver2_1:
367     num_spans = 1 ;
368     if (delta > 0.9999 * M_PI) {
369       Standard_ConstructionError::Raise() ; 
370       }
371     tgt_theta_flag = 1 ;
372     break ;
373   case Convert_TgtThetaOver2_2:
374     num_spans = 2 ;
375     if (delta > 1.9999 * M_PI) {
376       Standard_ConstructionError::Raise() ;
377       }
378     tgt_theta_flag = 1 ;
379     break ;
380   
381   case Convert_TgtThetaOver2_3:
382     num_spans = 3 ;
383     tgt_theta_flag = 1 ;
384     break ;
385   case Convert_TgtThetaOver2_4:
386     num_spans = 4 ;
387     tgt_theta_flag = 1 ;
388     break ; 
389   case Convert_QuasiAngular:
390     num_poles = 7 ;
391     Degree    = 6 ;
392     num_spans = 1 ;
393     num_knots = 2 ;
394     order = Degree + 1 ;
395     break ;
396    case Convert_RationalC1:
397     Degree    = 4 ;
398     order = Degree + 1 ; 
399     num_poles = 8 ;
400     num_knots = 3 ;
401     num_spans = 2 ;
402     break ;
403    case Convert_Polynomial:
404     Degree    = 7 ;
405     num_poles = 8 ;
406     num_knots = 2 ;
407     num_spans = 1 ;
408     break ;
409   default:
410     break ;
411   }
412   if (tgt_theta_flag) {
413     alpha = delta / ( 2.0e0 * num_spans) ;    
414     Degree = 2 ;
415     num_poles = 2 * num_spans + 1;
416   }  
417   
418   CosNumeratorPtr = 
419     new TColStd_HArray1OfReal(1,num_poles) ;
420   SinNumeratorPtr =
421     new TColStd_HArray1OfReal(1,num_poles) ;      
422   DenominatorPtr =
423     new TColStd_HArray1OfReal(1,num_poles) ;      
424   KnotsPtr = 
425     new TColStd_HArray1OfReal(1,num_spans+1) ;
426   MultsPtr =
427     new TColStd_HArray1OfInteger(1,num_spans+1) ;
428   if (tgt_theta_flag) {
429
430     param = UFirst ;
431     CosNumeratorPtr->SetValue(1,Cos(UFirst)) ;
432     SinNumeratorPtr->SetValue(1,Sin(UFirst)) ;
433     DenominatorPtr ->SetValue(1,1.0e0) ;
434     KnotsPtr->SetValue(1,param) ;
435     MultsPtr->SetValue(1,Degree + 1) ;
436     direct = Cos(alpha) ;
437     inverse = 1.0e0 / direct ;
438     for (ii = 1 ; ii <= num_spans ; ii++ ) {
439       CosNumeratorPtr->SetValue(2 * ii, inverse * Cos(param + alpha)) ;
440       SinNumeratorPtr->SetValue(2 * ii, inverse * Sin(param + alpha)) ;
441       DenominatorPtr->SetValue(2 * ii,  direct) ; 
442       CosNumeratorPtr->SetValue(2 * ii + 1, Cos(param + 2 * alpha)) ;
443       SinNumeratorPtr->SetValue(2 * ii + 1, Sin(param + 2 * alpha)) ;
444       DenominatorPtr->SetValue(2 * ii + 1,  1.0e0) ;
445       KnotsPtr->SetValue(ii + 1, param + 2 * alpha) ;
446       MultsPtr->SetValue(ii + 1, 2) ;
447       param += 2 * alpha ;
448     }
449     MultsPtr->SetValue(num_spans + 1, Degree + 1) ;
450   }
451   else if (Parameterisation != Convert_Polynomial) {
452     alpha = ULast - UFirst ;
453     alpha *= 0.5e0 ;
454     beta = ULast + UFirst ;
455     beta *= 0.5e0 ;
456     cos_beta = Cos(beta) ;
457     sin_beta = Sin(beta) ;
458     num_flat_knots = num_poles + order ;
459
460     num_temp_poles = 4 ;
461     num_temp_knots = 3 ;
462     TColStd_Array1OfReal   flat_knots(1, num_flat_knots) ;
463     
464
465     TColgp_Array1OfPnt2d    temp_poles(1,num_temp_poles)  ;
466     TColStd_Array1OfReal    temp_knots(1,num_temp_knots)  ;
467     TColStd_Array1OfInteger temp_mults(1,num_temp_knots) ;
468
469     for (ii = 1 ; ii <= order ; ii++) {
470       flat_knots(ii) = -alpha ;
471       flat_knots(ii + num_poles) = alpha ;
472     }
473     KnotsPtr->SetValue(1,UFirst) ;
474     KnotsPtr->SetValue(num_knots, ULast) ;
475     MultsPtr->SetValue(1,order) ;
476     MultsPtr->SetValue(num_knots,order) ;
477     
478     switch (Parameterisation) {
479     case Convert_QuasiAngular:
480 //
481 //    we code here in temp_poles(xx).Coord(1) the following function V(t) 
482 //   and in temp_poles(xx).Coord(2) the function U(t) 
483 //                     3
484 //       V(t) = t + c t
485 //                     2
486 //       U(t) = 1 + b t
487 //            1
488 //       c = ---  + b   = q_param
489 //            3 
490 //                          3
491 //                     gamma
492 //            gamma +  ------  - tang gamma
493 //                      3
494 //       b =------------------------------    = p_param
495 //                 2 
496 //            gamma  (tang gamma - gamma) 
497 //
498 //     with gamma = alpha / 2
499 //
500 //
501      
502       alpha_2 = alpha * 0.5e0 ;
503       p_param = - 1.0e0 / (alpha_2 * alpha_2) ;
504      
505       if (alpha_2 <  M_PI * 0.5e0) 
506       {
507         if (alpha_2 < 1.0e-7)
508         {
509           // Fixed degenerate case, when obtain 0 / 0 uncertainty.
510           // According to Taylor aprroximation:
511           // b (gamma) = -6.0 / 15.0 + o(gamma^2)
512           p_param = -6.0 / 15.0;
513         }
514         else
515         {
516           tan_alpha_2 = Tan(alpha_2) ;
517           value1 = 3.0e0 * (tan_alpha_2 - alpha_2) ;
518           value1 = alpha_2 / value1 ;
519           p_param += value1 ;
520         }
521       }
522       q_param = (1.0e0 / 3.0e0)  + p_param ;
523       
524       
525       temp_degree = 3 ;
526       temp_poles(1).SetCoord(1,0.0e0);
527       temp_poles(2).SetCoord(1,1.0e0);
528       temp_poles(3).SetCoord(1,0.0e0) ;
529       temp_poles(4).SetCoord(1,q_param) ;
530
531       temp_poles(1).SetCoord(2, 1.0e0) ;
532       temp_poles(2).SetCoord(2, 0.0e0) ;
533       temp_poles(3).SetCoord(2, p_param) ;
534       temp_poles(4).SetCoord(2, 0.0e0);
535       EvaluatorPtr = &CosAndSinQuasiAngular ;
536       break ;
537     case  Convert_RationalC1:
538       for (ii = order + 1 ; ii <= num_poles ; ii++) {
539         flat_knots(ii) = 0.0e0 ;
540       }
541       KnotsPtr->SetValue(2,UFirst + alpha) ;
542       MultsPtr->SetValue(2,Degree -1) ;
543       temp_degree = 2 ;   
544       alpha_2 = alpha * 0.5e0 ;
545       alpha_4 = alpha * 0.25e0 ;
546       tan_alpha_2 = Tan(alpha_2) ;
547       jj = 1 ;
548       for (ii = 1 ; ii <= 2 ; ii++) {
549         temp_poles(1+ ii).SetCoord(2,1.0e0 + alpha_4 * tan_alpha_2) ;
550         temp_poles(jj).SetCoord(2,1.e0) ;
551         jj += 3 ;
552       }
553       temp_poles(1).SetCoord(1,-tan_alpha_2) ;  
554       temp_poles(2).SetCoord(1,alpha_4 - tan_alpha_2) ; 
555       temp_poles(3).SetCoord(1,-alpha_4 + tan_alpha_2) ; 
556       temp_poles(4).SetCoord(1,tan_alpha_2) ; 
557       temp_knots(1) = -alpha ;
558       temp_knots(2) = 0.0e0 ;
559       temp_knots(3) = alpha ;
560       temp_mults(1) = temp_degree + 1;
561       temp_mults(2) = 1 ;
562       temp_mults(3) = temp_degree + 1;
563      
564       EvaluatorPtr = &CosAndSinRationalC1 ;
565       break ;
566     default: 
567       break ;
568     }
569     AlgorithmicCosAndSin(Degree,
570                          flat_knots,
571                          temp_degree,
572                          temp_poles,
573                          temp_knots,
574                          temp_mults,
575                          *EvaluatorPtr,
576                          CosNumeratorPtr->ChangeArray1(),
577                          SinNumeratorPtr->ChangeArray1(),
578                          DenominatorPtr->ChangeArray1()) ;
579
580     for (ii = 1 ; ii <= num_poles ; ii++) {
581        value1 = cos_beta * CosNumeratorPtr->Value(ii) -
582          sin_beta * SinNumeratorPtr->Value(ii) ;
583        value2 = sin_beta * CosNumeratorPtr->Value(ii) +
584          cos_beta * SinNumeratorPtr->Value(ii) ;
585        CosNumeratorPtr->SetValue(ii,value1) ;
586        SinNumeratorPtr->SetValue(ii,value2) ;
587      }
588   }
589   else { // Convert_Polynomial
590
591     KnotsPtr->SetValue(1, 0.) ;
592     KnotsPtr->SetValue(num_knots, 1.);
593     MultsPtr->SetValue(1, num_poles);
594     MultsPtr->SetValue(num_knots, num_poles);
595     
596     BuildPolynomialCosAndSin(UFirst,ULast,num_poles,
597                              CosNumeratorPtr,SinNumeratorPtr,DenominatorPtr);
598   }
599
600
601 }
602 //=======================================================================
603 //function : BuildCosAndSin
604 //purpose  : 
605 //=======================================================================
606
607 void Convert_ConicToBSplineCurve::BuildCosAndSin(
608           const Convert_ParameterisationType     Parameterisation,
609           Handle(TColStd_HArray1OfReal)&         CosNumeratorPtr,
610           Handle(TColStd_HArray1OfReal)&         SinNumeratorPtr,
611           Handle(TColStd_HArray1OfReal)&         DenominatorPtr,
612           Standard_Integer&                      Degree,
613           Handle(TColStd_HArray1OfReal)&         KnotsPtr,
614           Handle(TColStd_HArray1OfInteger)&      MultsPtr)  const 
615 {
616   Standard_Real half_pi,
617   param,
618   first_param,
619   last_param,
620 //  direct,
621   inverse,
622   value1,
623   value2,
624   value3 ;
625
626   Standard_Integer 
627   ii,
628   jj,
629   index,
630   num_poles,
631   num_periodic_poles,
632   temp_degree,
633   pivot_index_problem,
634   num_flat_knots,
635   num_knots,
636   order ;
637
638   if (Parameterisation != Convert_TgtThetaOver2 &&
639       Parameterisation != Convert_RationalC1) {
640       Standard_ConstructionError::Raise() ;
641       }
642   Handle(TColStd_HArray1OfReal) temp_cos_ptr,
643   temp_sin_ptr,
644   temp_denominator_ptr,
645   temp_knots_ptr;
646   Handle(TColStd_HArray1OfInteger)  temp_mults_ptr;
647   if (Parameterisation == Convert_TgtThetaOver2) {
648     BuildCosAndSin(Convert_TgtThetaOver2_3,
649                    0.0e0,
650                    2 * M_PI,
651                    temp_cos_ptr,
652                    temp_sin_ptr,
653                    temp_denominator_ptr,
654                    Degree,
655                    KnotsPtr,
656                    MultsPtr) ;
657      CosNumeratorPtr =
658        new TColStd_HArray1OfReal(1,temp_cos_ptr->Length() -1) ;
659      SinNumeratorPtr =
660         new TColStd_HArray1OfReal(1,temp_cos_ptr->Length() -1) ;
661      DenominatorPtr =
662         new TColStd_HArray1OfReal(1,temp_cos_ptr->Length() -1) ; 
663      for (ii = temp_cos_ptr->Lower()  ; ii <= temp_cos_ptr->Upper()-1 ; ii++) {
664        CosNumeratorPtr->SetValue(ii,temp_cos_ptr->Value(ii)) ;
665        SinNumeratorPtr->SetValue(ii,temp_sin_ptr->Value(ii)) ;
666        DenominatorPtr->SetValue(ii,temp_denominator_ptr->Value(ii)) ;
667      }
668     for (ii = MultsPtr->Lower() ; ii <= MultsPtr->Upper() ; ii++) {
669       MultsPtr->SetValue(ii, Degree) ;
670     }
671   }
672   else if (Parameterisation == Convert_RationalC1) 
673     {
674      first_param = 0.0e0 ;
675      last_param  = M_PI ;
676      BuildCosAndSin(Convert_RationalC1,
677                    first_param,
678                    last_param,
679                    temp_cos_ptr,
680                    temp_sin_ptr,
681                    temp_denominator_ptr,
682                    temp_degree,
683                    temp_knots_ptr,
684                    temp_mults_ptr) ;
685
686
687      Degree = 4 ;
688      order = Degree + 1 ;
689      num_knots = 5 ;
690      num_flat_knots = (Degree -1) * num_knots + 2 * 2 ;
691      num_poles = num_flat_knots - order ;
692      num_periodic_poles = num_poles - 2 ;
693      TColStd_Array1OfReal  flat_knots(1,num_flat_knots) ;
694      CosNumeratorPtr = 
695       new TColStd_HArray1OfReal(1,num_periodic_poles) ;
696      SinNumeratorPtr = 
697       new TColStd_HArray1OfReal(1,num_periodic_poles) ;
698      DenominatorPtr = 
699       new TColStd_HArray1OfReal(1,num_periodic_poles) ;
700     
701      half_pi = M_PI * 0.5e0 ;
702      index = 1 ;
703      for (jj = 1 ; jj <= 2 ; jj++) {
704          flat_knots(index) = -  half_pi  ;
705          index += 1 ;
706        }
707      for (ii = 1 ; ii <= num_knots ; ii++) {
708        for (jj = 1 ; jj <= Degree -1 ; jj++) {
709          flat_knots(index) = (ii-1) * half_pi ;
710
711          index += 1 ;
712
713        }
714      }
715      for (jj = 1 ; jj <= 2 ; jj++) {
716          flat_knots(index) = 2 * M_PI +  half_pi  ;
717          index += 1 ;
718        }
719      KnotsPtr = 
720        new TColStd_HArray1OfReal(1,num_knots) ;
721      MultsPtr =
722        new TColStd_HArray1OfInteger(1,num_knots) ;
723      for ( ii = 1 ; ii <= num_knots  ; ii++) { 
724        KnotsPtr->SetValue(ii, (ii-1) * half_pi) ;
725        MultsPtr->SetValue(ii, Degree-1) ;
726      }
727      order = degree + 1 ;
728
729      TColStd_Array1OfReal      parameters(1,num_poles)  ;
730      TColgp_Array1OfPnt        poles_array(1,num_poles) ;
731      TColStd_Array1OfInteger   contact_order_array(1,num_poles) ;  
732      BSplCLib::BuildSchoenbergPoints(Degree,
733                                      flat_knots,
734                                      parameters) ;
735      inverse = 1.0e0 ;
736      for (ii = parameters.Lower() ; ii <= parameters.Upper() ; ii++) {
737        param = parameters(ii) ;
738        if (param > M_PI) {
739          inverse = -1.0e0 ;
740          param -= M_PI ;
741        }
742        BSplCLib::D0(param,
743                     0,
744                     temp_degree,
745                     Standard_False,
746                     temp_cos_ptr->Array1(),
747                     temp_denominator_ptr->Array1(),
748                     temp_knots_ptr->Array1(),
749                     temp_mults_ptr->Array1(),
750                     value1) ;
751
752        BSplCLib::D0(param,
753                     0,
754                     temp_degree,
755                     Standard_False,
756                     temp_sin_ptr->Array1(),
757                     temp_denominator_ptr->Array1(),
758                     temp_knots_ptr->Array1(),
759                     temp_mults_ptr->Array1(),
760                     value2) ;
761        BSplCLib::D0(param,
762                     0,
763                     temp_degree,
764                     Standard_False,
765                     temp_denominator_ptr->Array1(),
766                     BSplCLib::NoWeights(),
767                     temp_knots_ptr->Array1(),
768                     temp_mults_ptr->Array1(),
769                     value3) ;
770      contact_order_array(ii) = 0 ;
771      
772      poles_array(ii).SetCoord(1,
773                               value1 * value3 * inverse) ;
774      poles_array(ii).SetCoord(2,
775                               value2 * value3 * inverse) ;
776      poles_array(ii).SetCoord(3,
777                               value3) ;
778    }
779     BSplCLib::Interpolate(Degree,
780                           flat_knots,
781                           parameters,
782                           contact_order_array,
783                           poles_array,
784                           pivot_index_problem) ;
785     for (ii = 1 ; ii <= num_periodic_poles ; ii++) {
786       inverse = 1.0e0 / poles_array(ii).Coord(3) ;
787       CosNumeratorPtr->ChangeArray1()(ii) = poles_array(ii).Coord(1) * inverse ;
788       SinNumeratorPtr->ChangeArray1()(ii) = poles_array(ii).Coord(2) * inverse ;
789       DenominatorPtr->ChangeArray1()(ii)  = poles_array(ii).Coord(3) ;
790     }
791  }
792 }
793
794
795