0022488: Typo in Geom2d_BSplineCurve::LocateU() - which uses a value not adjusted...
[occt.git] / src / Geom2d / Geom2d_BSplineCurve_1.cxx
1 // File:        Geom2d_BSplineCurve_1.cxx
2 // Created:     Wed Mar 31 18:11:15 1993
3 // Author:      JCV
4 //              <fid@sdsun2>
5 // Copyright:   Matra Datavision 1993
6
7 // File:        Geom2d_BSplineCurve_1.cxx
8 // Created:     Fri Jul  5 16:37:59 1991
9 // Author:      JCV
10 // 03-02-97 : pmn ->LocateU sur Periodic (PRO6963), 
11 //            bon appel a LocateParameter (PRO6973) et mise en conformite avec
12 //            le cdl de LocateU, lorsque U est un noeud (PRO6988)
13
14 #define No_Standard_OutOfRange
15 #define No_Standard_DimensionError
16
17 #include <Geom2d_BSplineCurve.jxx>
18 #include <BSplCLib.hxx>
19 #include <gp.hxx>
20
21 #include <Geom2d_UndefinedDerivative.hxx>
22 #include <Standard_DimensionError.hxx>
23 #include <Standard_OutOfRange.hxx>
24 #include <Standard_DomainError.hxx>
25 #include <Standard_RangeError.hxx>
26
27 #define  POLES    (poles->Array1())
28 #define  KNOTS    (knots->Array1())
29 #define  FKNOTS   (flatknots->Array1())
30 #define  FMULTS   (BSplCLib::NoMults())
31
32 //=======================================================================
33 //function : IsCN
34 //purpose  : 
35 //=======================================================================
36
37 Standard_Boolean Geom2d_BSplineCurve::IsCN ( const Standard_Integer N) const
38 {
39   Standard_RangeError_Raise_if
40     (N < 0, "Geom2d_BSplineCurve::IsCN");
41
42   switch (smooth) {
43   case GeomAbs_CN : return Standard_True;
44   case GeomAbs_C0 : return N <= 0;
45   case GeomAbs_G1 : return N <= 0;
46   case GeomAbs_C1 : return N <= 1;
47   case GeomAbs_G2 : return N <= 1;
48   case GeomAbs_C2 : return N <= 2;
49   case GeomAbs_C3 : 
50     return N <= 3 ? Standard_True :
51            N <= deg - BSplCLib::MaxKnotMult (mults->Array1(), mults->Lower() + 1, mults->Upper() - 1);
52   default:
53     return Standard_False;
54   }
55 }
56
57 //=======================================================================
58 //function : IsClosed
59 //purpose  : 
60 //=======================================================================
61
62 Standard_Boolean Geom2d_BSplineCurve::IsClosed () const
63 { return (StartPoint().Distance (EndPoint())) <= gp::Resolution (); }
64
65
66
67 //=======================================================================
68 //function : IsPeriodic
69 //purpose  : 
70 //=======================================================================
71
72 Standard_Boolean Geom2d_BSplineCurve::IsPeriodic () const
73 { return periodic; }
74
75 //=======================================================================
76 //function : Continuity
77 //purpose  : 
78 //=======================================================================
79
80 GeomAbs_Shape Geom2d_BSplineCurve::Continuity () const
81 { return smooth; }
82
83 //=======================================================================
84 //function : Degree
85 //purpose  : 
86 //=======================================================================
87
88 Standard_Integer Geom2d_BSplineCurve::Degree () const
89 { return deg; }
90
91
92 //=======================================================================
93 //function : D0
94 //purpose  : 
95 //=======================================================================
96
97 void Geom2d_BSplineCurve::D0 ( const Standard_Real U, 
98                               gp_Pnt2d& P) const
99 {
100   Standard_Real  NewU = U ;
101   PeriodicNormalization(NewU) ;
102   if (!IsCacheValid(NewU)) {
103     Geom2d_BSplineCurve  * MyCurve = (Geom2d_BSplineCurve *) this ;
104     MyCurve->ValidateCache(NewU) ;
105   }
106   
107   if ( rational ) {
108     BSplCLib::CacheD0(NewU,
109                       deg,
110                       parametercache,
111                       spanlenghtcache,
112                       (cachepoles->Array1()),
113                       cacheweights->Array1(),
114                       P) ;
115   }
116   else {
117     BSplCLib::CacheD0(NewU,
118                       deg,
119                       parametercache,
120                       spanlenghtcache,
121                       (cachepoles->Array1()),
122                       BSplCLib::NoWeights(),
123                       P) ;
124   }
125 }
126
127
128 //=======================================================================
129 //function : D1
130 //purpose  : 
131 //=======================================================================
132
133 void Geom2d_BSplineCurve::D1 (const Standard_Real U,
134                               gp_Pnt2d& P,
135                               gp_Vec2d& V1) const
136 {
137   Standard_Real  NewU = U ;
138   PeriodicNormalization(NewU) ;
139   if (!IsCacheValid(NewU)) {
140     Geom2d_BSplineCurve  * MyCurve = (Geom2d_BSplineCurve *) this ;
141     MyCurve->ValidateCache(NewU) ;
142   }
143
144   if ( rational ) {
145     BSplCLib::CacheD1(NewU,
146                       deg,
147                       parametercache,
148                       spanlenghtcache,
149                       (cachepoles->Array1()),
150                       cacheweights->Array1(),
151                       P,
152                       V1) ;
153   }
154   else {
155     BSplCLib::CacheD1(NewU,
156                       deg,
157                       parametercache,
158                       spanlenghtcache,
159                       (cachepoles->Array1()),
160                       BSplCLib::NoWeights(),
161                       P,
162                       V1) ;
163   }
164 }
165
166 //=======================================================================
167 //function : D2
168 //purpose  : 
169 //=======================================================================
170
171 void Geom2d_BSplineCurve::D2 (const Standard_Real U ,
172                               gp_Pnt2d& P ,
173                               gp_Vec2d& V1,
174                               gp_Vec2d& V2 ) const
175 {
176   Standard_Real  NewU = U ;
177   PeriodicNormalization(NewU) ;
178   if (!IsCacheValid(NewU)) {
179     Geom2d_BSplineCurve  * MyCurve = (Geom2d_BSplineCurve *) this ;
180     MyCurve->ValidateCache(NewU) ;
181   }
182   
183   if ( rational ) {
184     BSplCLib::CacheD2(NewU,
185                       deg,
186                       parametercache,
187                       spanlenghtcache,
188                       (cachepoles->Array1()),
189                       cacheweights->Array1(),
190                       P,
191                       V1,
192                       V2) ;
193   }
194   else {
195     BSplCLib::CacheD2(NewU,
196                       deg,
197                       parametercache,
198                       spanlenghtcache,
199                       (cachepoles->Array1()),
200                       BSplCLib::NoWeights(),
201                       P,
202                       V1,
203                       V2) ;
204   }
205 }
206
207 //=======================================================================
208 //function : D3
209 //purpose  : 
210 //=======================================================================
211
212 void Geom2d_BSplineCurve::D3  (const Standard_Real U ,
213                                gp_Pnt2d& P ,
214                                gp_Vec2d& V1,
215                                gp_Vec2d& V2,
216                                gp_Vec2d& V3 ) const
217 {
218   Standard_Real  NewU = U ;
219   PeriodicNormalization(NewU) ;
220   if (!IsCacheValid(NewU)) {
221     Geom2d_BSplineCurve  * MyCurve = (Geom2d_BSplineCurve *) this ;
222     MyCurve->ValidateCache(NewU) ;
223   }
224
225   if ( rational ) {
226     BSplCLib::CacheD3(NewU,
227                       deg,
228                       parametercache,
229                       spanlenghtcache,
230                       (cachepoles->Array1()),
231                       cacheweights->Array1(),
232                       P,
233                       V1,
234                       V2,
235                       V3) ;
236   }
237   else {
238     BSplCLib::CacheD3(NewU,
239                       deg,
240                       parametercache,
241                       spanlenghtcache,
242                       (cachepoles->Array1()),
243                       BSplCLib::NoWeights(),
244                       P,
245                       V1,
246                       V2,
247                       V3) ;
248   }
249 }
250
251 //=======================================================================
252 //function : DN
253 //purpose  : 
254 //=======================================================================
255
256 gp_Vec2d Geom2d_BSplineCurve::DN  (const Standard_Real    U,
257                                    const Standard_Integer N ) const
258 {
259   gp_Vec2d V;
260
261   if ( rational ) {
262     BSplCLib::DN(U,N,0,deg,periodic,POLES,
263                  weights->Array1(),
264                  FKNOTS,FMULTS,V);
265   }
266   else {  
267     BSplCLib::DN(U,N,0,deg,periodic,POLES,
268                  *((TColStd_Array1OfReal*) NULL),
269                  FKNOTS,FMULTS,V);
270   }
271   return V;
272 }
273
274 //=======================================================================
275 //function : EndPoint
276 //purpose  : 
277 //=======================================================================
278
279 gp_Pnt2d Geom2d_BSplineCurve::EndPoint () const
280
281   if (mults->Value (knots->Upper ()) == deg + 1) 
282     return poles->Value (poles->Upper());
283   else
284     return Value(LastParameter());
285 }
286
287 //=======================================================================
288 //function : FirstUKnotIndex
289 //purpose  : 
290 //=======================================================================
291
292 Standard_Integer Geom2d_BSplineCurve::FirstUKnotIndex () const
293
294   if (periodic) return 1;
295   else return BSplCLib::FirstUKnotIndex (deg, mults->Array1()); 
296 }
297
298 //=======================================================================
299 //function : FirstParameter
300 //purpose  : 
301 //=======================================================================
302
303 Standard_Real Geom2d_BSplineCurve::FirstParameter () const
304 {
305   return flatknots->Value (deg+1); 
306 }
307
308 //=======================================================================
309 //function : Knot
310 //purpose  : 
311 //=======================================================================
312
313 Standard_Real Geom2d_BSplineCurve::Knot (const Standard_Integer Index) const
314 {
315   Standard_OutOfRange_Raise_if
316     (Index < 1 || Index > knots->Length(), "Geom2d_BSplineCurve::Knot");
317   return knots->Value (Index);
318 }
319
320 //=======================================================================
321 //function : KnotDistribution
322 //purpose  : 
323 //=======================================================================
324
325 GeomAbs_BSplKnotDistribution Geom2d_BSplineCurve::KnotDistribution () const
326
327   return knotSet; 
328 }
329
330 //=======================================================================
331 //function : Knots
332 //purpose  : 
333 //=======================================================================
334
335 void Geom2d_BSplineCurve::Knots (TColStd_Array1OfReal& K) const
336 {
337   Standard_DimensionError_Raise_if
338     (K.Length() != knots->Length(), "Geom2d_BSplineCurve::Knots");
339   K = knots->Array1();
340 }
341
342 //=======================================================================
343 //function : KnotSequence
344 //purpose  : 
345 //=======================================================================
346
347 void Geom2d_BSplineCurve::KnotSequence (TColStd_Array1OfReal& K) const
348 {
349   Standard_DimensionError_Raise_if
350     (K.Length() != flatknots->Length(), "Geom2d_BSplineCurve::KnotSequence");
351   K = flatknots->Array1();
352 }
353
354 //=======================================================================
355 //function : LastUKnotIndex
356 //purpose  : 
357 //=======================================================================
358
359 Standard_Integer Geom2d_BSplineCurve::LastUKnotIndex() const
360 {
361   if (periodic) return knots->Length();
362   else return BSplCLib::LastUKnotIndex (deg, mults->Array1()); 
363 }
364
365 //=======================================================================
366 //function : LastParameter
367 //purpose  : 
368 //=======================================================================
369
370 Standard_Real Geom2d_BSplineCurve::LastParameter () const
371 {
372   return flatknots->Value (flatknots->Upper()-deg); 
373 }
374
375 //=======================================================================
376 //function : LocalValue
377 //purpose  : 
378 //=======================================================================
379
380 gp_Pnt2d Geom2d_BSplineCurve::LocalValue
381 (const Standard_Real    U,
382  const Standard_Integer FromK1,
383  const Standard_Integer ToK2)   const
384 {
385   gp_Pnt2d P;
386   LocalD0(U,FromK1,ToK2,P);
387   return P;
388 }
389
390 //=======================================================================
391 //function : LocalD0
392 //purpose  : 
393 //=======================================================================
394
395 void  Geom2d_BSplineCurve::LocalD0
396 (const Standard_Real    U,
397  const Standard_Integer FromK1,
398  const Standard_Integer ToK2,
399  gp_Pnt2d& P)   const
400 {
401   Standard_DomainError_Raise_if (FromK1 == ToK2,
402                                  "Geom2d_BSplineCurve::LocalValue");
403
404   Standard_Real u = U;
405   Standard_Integer index = 0;
406   BSplCLib::LocateParameter(deg, FKNOTS, U, periodic,FromK1,ToK2, index,u);
407   index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic);
408
409   if ( rational ) {
410     BSplCLib::D0(u,index,deg,periodic,POLES,
411                  weights->Array1(),
412                  FKNOTS,FMULTS,P);
413   }
414   else {
415     BSplCLib::D0(u,index,deg,periodic,POLES,
416                  *((TColStd_Array1OfReal*) NULL),
417                  FKNOTS,FMULTS,P);
418   }
419 }
420
421 //=======================================================================
422 //function : LocalD1
423 //purpose  : 
424 //=======================================================================
425
426 void Geom2d_BSplineCurve::LocalD1 (const Standard_Real    U,
427                                    const Standard_Integer FromK1,
428                                    const Standard_Integer ToK2,
429                                    gp_Pnt2d&    P, 
430                                    gp_Vec2d&    V1)    const
431 {
432   Standard_DomainError_Raise_if (FromK1 == ToK2,
433                                  "Geom2d_BSplineCurve::LocalD1");
434   
435   Standard_Real u = U;
436   Standard_Integer index = 0;
437   BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u);
438   index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic);
439   
440   if (rational) {
441     BSplCLib::D1(u,index,deg,periodic,POLES,
442                  weights->Array1(),
443                  FKNOTS,FMULTS,P,V1);
444   }
445   else {
446     BSplCLib::D1(u,index,deg,periodic,POLES,
447                  *((TColStd_Array1OfReal*) NULL),
448                  FKNOTS,FMULTS,P,V1);
449   }
450 }
451
452 //=======================================================================
453 //function : LocalD2
454 //purpose  : 
455 //=======================================================================
456
457 void Geom2d_BSplineCurve::LocalD2
458 (const Standard_Real    U,
459  const Standard_Integer FromK1,
460  const Standard_Integer ToK2, 
461  gp_Pnt2d&    P,
462  gp_Vec2d&    V1,
463  gp_Vec2d&    V2) const
464 {
465   Standard_DomainError_Raise_if (FromK1 == ToK2,
466                                  "Geom2d_BSplineCurve::LocalD2");
467   
468   Standard_Real u = U;
469   Standard_Integer index = 0;
470   BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u);
471   index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic);
472   
473   if ( rational ) {
474     BSplCLib::D2(u,index,deg,periodic,POLES,
475                  weights->Array1(),
476                  FKNOTS,FMULTS,P,V1,V2);
477   }
478   else {
479     BSplCLib::D2(u,index,deg,periodic,POLES,
480                  *((TColStd_Array1OfReal*) NULL),
481                  FKNOTS,FMULTS,P,V1,V2);
482   }
483 }
484
485 //=======================================================================
486 //function : LocalD3
487 //purpose  : 
488 //=======================================================================
489
490 void Geom2d_BSplineCurve::LocalD3
491 (const Standard_Real    U,
492  const Standard_Integer FromK1,
493  const Standard_Integer ToK2, 
494  gp_Pnt2d&    P,
495  gp_Vec2d&    V1,
496  gp_Vec2d&    V2,
497  gp_Vec2d&    V3) const
498 {
499   Standard_DomainError_Raise_if (FromK1 == ToK2,
500                                  "Geom2d_BSplineCurve::LocalD3");
501   
502   Standard_Real u = U;
503   Standard_Integer index = 0;
504   BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u);
505   index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic);
506   
507   if ( rational ) {
508     BSplCLib::D3(u,index,deg,periodic,POLES,
509                  weights->Array1(),
510                  FKNOTS,FMULTS,P,V1,V2,V3);
511   }
512   else {
513     BSplCLib::D3(u,index,deg,periodic,POLES,
514                  *((TColStd_Array1OfReal*) NULL),
515                  FKNOTS,FMULTS,P,V1,V2,V3);
516   }
517 }
518
519 //=======================================================================
520 //function : LocalDN
521 //purpose  : 
522 //=======================================================================
523
524 gp_Vec2d Geom2d_BSplineCurve::LocalDN
525 (const Standard_Real    U,
526  const Standard_Integer FromK1,
527  const Standard_Integer ToK2,
528  const Standard_Integer N      ) const
529 {
530   Standard_DomainError_Raise_if (FromK1 == ToK2,
531                                  "Geom2d_BSplineCurve::LocalD3");
532   
533   Standard_Real u = U;
534   Standard_Integer index = 0;
535   BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u);
536   index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic);
537   
538   gp_Vec2d V;
539
540   if ( rational ) {
541     BSplCLib::DN(u,N,index,deg,periodic,POLES,
542                  weights->Array1(),
543                  FKNOTS,FMULTS,V);
544   }
545   else {
546     BSplCLib::DN(u,N,index,deg,periodic,POLES,
547                  *((TColStd_Array1OfReal*) NULL),
548                  FKNOTS,FMULTS,V);
549   }
550   return V;
551 }
552
553 //=======================================================================
554 //function : Multiplicity
555 //purpose  : 
556 //=======================================================================
557
558 Standard_Integer Geom2d_BSplineCurve::Multiplicity 
559 (const Standard_Integer Index) const
560 {
561   Standard_OutOfRange_Raise_if (Index < 1 || Index > mults->Length(),
562                                 "Geom2d_BSplineCurve::Multiplicity");
563   return mults->Value (Index);
564 }
565
566 //=======================================================================
567 //function : Multiplicities
568 //purpose  : 
569 //=======================================================================
570
571 void Geom2d_BSplineCurve::Multiplicities (TColStd_Array1OfInteger& M) const
572 {
573   Standard_DimensionError_Raise_if (M.Length() != mults->Length(),
574                                     "Geom2d_BSplineCurve::Multiplicities");
575   M = mults->Array1();
576 }
577
578 //=======================================================================
579 //function : NbKnots
580 //purpose  : 
581 //=======================================================================
582
583 Standard_Integer Geom2d_BSplineCurve::NbKnots () const
584 { return knots->Length(); }
585
586 //=======================================================================
587 //function : NbPoles
588 //purpose  : 
589 //=======================================================================
590
591 Standard_Integer Geom2d_BSplineCurve::NbPoles () const
592 { return poles->Length(); }
593
594 //=======================================================================
595 //function : Pole
596 //purpose  : 
597 //=======================================================================
598
599 gp_Pnt2d Geom2d_BSplineCurve::Pole (const Standard_Integer Index) const
600 {
601   Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(),
602                                 "Geom2d_BSplineCurve::Pole");
603   return poles->Value (Index);      
604 }
605
606 //=======================================================================
607 //function : Poles
608 //purpose  : 
609 //=======================================================================
610
611 void Geom2d_BSplineCurve::Poles (TColgp_Array1OfPnt2d& P) const
612 {
613   Standard_DimensionError_Raise_if (P.Length() != poles->Length(),
614                                     "Geom2d_BSplineCurve::Poles");
615   P = poles->Array1();
616 }
617
618 //=======================================================================
619 //function : StartPoint
620 //purpose  : 
621 //=======================================================================
622
623 gp_Pnt2d Geom2d_BSplineCurve::StartPoint () const
624 {
625   if (mults->Value (1) == deg + 1)  
626     return poles->Value (1);
627   else 
628     return Value(FirstParameter());
629 }
630
631 //=======================================================================
632 //function : Weight
633 //purpose  : 
634 //=======================================================================
635
636 Standard_Real Geom2d_BSplineCurve::Weight
637 (const Standard_Integer Index) const
638 {
639   Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(),
640                                 "Geom2d_BSplineCurve::Weight");
641   if (IsRational())
642     return weights->Value (Index);
643   else
644     return 1.;
645 }
646
647 //=======================================================================
648 //function : Weights
649 //purpose  : 
650 //=======================================================================
651
652 void Geom2d_BSplineCurve::Weights
653 (TColStd_Array1OfReal& W) const
654 {
655   Standard_DimensionError_Raise_if (W.Length() != poles->Length(),
656                                     "Geom2d_BSplineCurve::Weights");
657   if (IsRational())
658     W = weights->Array1();
659   else {
660     Standard_Integer i;
661     for (i = W.Lower(); i <= W.Upper(); i++)
662       W(i) = 1.;
663   }
664 }
665
666 //=======================================================================
667 //function : IsRational
668 //purpose  : 
669 //=======================================================================
670
671 Standard_Boolean Geom2d_BSplineCurve::IsRational () const
672
673   return !weights.IsNull(); 
674
675
676 //=======================================================================
677 //function : Transform
678 //purpose  : 
679 //=======================================================================
680
681 void Geom2d_BSplineCurve::Transform
682 (const gp_Trsf2d& T)
683 {
684   TColgp_Array1OfPnt2d & CPoles = poles->ChangeArray1();
685   for (Standard_Integer I = 1; I <= CPoles.Length(); I++)  
686     CPoles (I).Transform (T);
687
688   InvalidateCache();
689   //  maxderivinvok = 0;
690 }
691
692 //=======================================================================
693 //function : LocateU
694 //purpose  : 
695 //=======================================================================
696
697 void Geom2d_BSplineCurve::LocateU
698 (const Standard_Real    U, 
699  const Standard_Real    ParametricTolerance, 
700  Standard_Integer&      I1,
701  Standard_Integer&      I2,
702  const Standard_Boolean WithKnotRepetition) const
703 {
704   Standard_Real NewU = U;
705   Handle(TColStd_HArray1OfReal) TheKnots;
706   if (WithKnotRepetition)  TheKnots = flatknots;
707   else                     TheKnots = knots;
708   
709   const TColStd_Array1OfReal & CKnots = TheKnots->Array1();
710
711   PeriodicNormalization(NewU); //Attention a la periode
712   Standard_Real UFirst = CKnots (1);
713   Standard_Real ULast  = CKnots (CKnots.Length());
714   Standard_Real PParametricTolerance = Abs(ParametricTolerance);
715   if (Abs (NewU - UFirst) <= PParametricTolerance) { I1 = I2 = 1; }
716   else if (Abs (NewU - ULast) <= PParametricTolerance) { 
717     I1 = I2 = CKnots.Length();
718   }
719   else if (NewU < UFirst) {
720     I2 = 1;
721     I1 = 0;
722   }
723   else if (NewU > ULast) {
724     I1 = CKnots.Length();
725     I2 = I1 + 1;
726   }
727   else {
728     I1 = 1;
729     BSplCLib::Hunt (CKnots, NewU, I1);
730     while ( Abs( CKnots(I1+1) - NewU) <= PParametricTolerance) I1++;
731     if ( Abs( CKnots(I1) - NewU) <= PParametricTolerance) {
732       I2 = I1;
733     }
734     else {
735       I2 = I1 + 1;
736     }
737   }
738 }
739
740 //=======================================================================
741 //function : Resolution
742 //purpose  : 
743 //=======================================================================
744
745 void Geom2d_BSplineCurve::Resolution(const Standard_Real ToleranceUV,
746                                      Standard_Real &     UTolerance) 
747 {
748   Standard_Integer ii ;  
749   if(!maxderivinvok){
750     if ( periodic) {
751       Standard_Integer NbKnots, NbPoles;
752       BSplCLib::PrepareUnperiodize( deg, 
753                                    mults->Array1(),
754                                    NbKnots,
755                                    NbPoles);
756       TColgp_Array1OfPnt2d    new_poles(1,NbPoles) ;
757       TColStd_Array1OfReal  new_weights(1,NbPoles) ;
758       for(ii = 1 ; ii <= NbPoles ; ii++) {
759         new_poles(ii) = poles->Array1()(((ii-1) % poles->Length()) + 1) ;
760       }
761       if (rational) {
762         for(ii = 1 ; ii <= NbPoles ; ii++) {
763           new_weights(ii) = weights->Array1()(((ii-1) % poles->Length()) + 1) ;
764         }
765         BSplCLib::Resolution(new_poles,
766                              new_weights,
767                              new_poles.Length(),
768                              flatknots->Array1(),
769                              deg,
770                              1.,
771                              maxderivinv) ;
772       }
773       else {
774         BSplCLib::Resolution(new_poles,
775                              *((TColStd_Array1OfReal*) NULL),
776                              new_poles.Length(),
777                              flatknots->Array1(),
778                              deg,
779                              1.,
780                              maxderivinv) ;
781       }
782     }
783     else {
784       if (rational) {
785         BSplCLib::Resolution(poles->Array1(),
786                              weights->Array1(),
787                              poles->Length(),
788                              flatknots->Array1(),
789                              deg,
790                              1.,
791                              maxderivinv) ;
792       }
793       else {
794         BSplCLib::Resolution(poles->Array1(),
795                              *((TColStd_Array1OfReal*) NULL),
796                              poles->Length(),
797                              flatknots->Array1(),
798                              deg,
799                              1.,
800                              maxderivinv) ;
801       }
802     }
803     maxderivinvok = 1;
804   } 
805   UTolerance = ToleranceUV * maxderivinv; 
806 }
807