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