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