Integration of OCCT 6.5.0 from SVN
[occt.git] / src / Geom2d / Geom2d_BezierCurve.cxx
1 // File:        Geom2d_BezierCurve.cxx
2 // Created:     Thu Mar 25 10:24:39 1993
3 // Author:      JCV
4 //              <fid@sdsun2>
5 // Copyright:   Matra Datavision 1993
6
7 // File Geom2d_BezierCurve.cxx  Septembre 1990
8 // Passage en classe persistante - 23/01/91
9 // Modif suite a la deuxieme revue de projet toolkit Geometry -23/01/91
10 // Infos :
11 // Actuellement pour les champs de la courbe le tableau des poles est 
12 // declare de 1 a NbPoles et le tableau des poids est declare de 1 a NbPoles
13
14
15 // Revised RLE  Aug 19 1993
16 // Suppressed Swaps, added Init, removed typedefs
17
18 #define No_Standard_OutOfRange
19 #define No_Standard_DimensionError
20
21 #include <Geom2d_BezierCurve.ixx>
22 #include <PLib.hxx>
23 #include <BSplCLib.hxx>
24 #include <gp.hxx>
25 #include <gp_XY.hxx>
26 #include <Standard_ConstructionError.hxx>
27 #include <Standard_DimensionError.hxx>
28 #include <Standard_OutOfRange.hxx>
29 #include <Standard_RangeError.hxx>
30 #include <TColStd_Array1OfReal.hxx>
31 #include <TColStd_Array1OfInteger.hxx>
32
33 //=======================================================================
34 //function : Rational
35 //purpose  : check rationality of an array of weights
36 //=======================================================================
37
38 static Standard_Boolean Rational(const TColStd_Array1OfReal& W)
39 {
40   Standard_Integer i, n = W.Length();
41   Standard_Boolean rat = Standard_False;
42   for (i = 1; i < n; i++) {
43     rat =  Abs(W(i) - W(i+1)) > gp::Resolution();
44     if (rat) break;
45   }
46   return rat;
47 }
48
49
50 //=======================================================================
51 //function : Geom2d_BezierCurve
52 //purpose  : 
53 //=======================================================================
54
55 Geom2d_BezierCurve::Geom2d_BezierCurve
56  (const TColgp_Array1OfPnt2d& Poles):
57  validcache(0), parametercache(0.), spanlenghtcache(1.)
58 {
59   //  copy the poles
60   
61   Handle(TColgp_HArray1OfPnt2d) npoles =
62     new TColgp_HArray1OfPnt2d(1,Poles.Length());
63   
64   npoles->ChangeArray1() = Poles;
65   
66   // Init non rational
67   Init(npoles,
68        Handle(TColStd_HArray1OfReal)());
69 }
70
71
72 //=======================================================================
73 //function : Geom2d_BezierCurve
74 //purpose  : 
75 //=======================================================================
76
77 Geom2d_BezierCurve::Geom2d_BezierCurve
78 (const TColgp_Array1OfPnt2d&  Poles, 
79  const TColStd_Array1OfReal& Weights):
80  validcache(0), parametercache(0.), spanlenghtcache(1.)
81
82 {
83   // copy the poles
84   
85   Handle(TColgp_HArray1OfPnt2d) npoles =
86     new TColgp_HArray1OfPnt2d(1,Poles.Length());
87   
88   npoles->ChangeArray1()   = Poles;
89   
90   
91   // check  the weights
92   
93   Standard_Integer nbpoles = Poles.Length();
94   
95   if (Weights.Length() != nbpoles)
96     Standard_ConstructionError::Raise();
97   
98   Standard_Integer i;
99   for (i = 1; i <= nbpoles; i++) {
100     if (Weights(i) <= gp::Resolution()) {
101       Standard_ConstructionError::Raise();
102     }
103   }
104   
105   // check really rational
106   Standard_Boolean rat = Rational(Weights);
107   
108   // copy the weights
109   Handle(TColStd_HArray1OfReal) nweights;
110   if (rat) {
111     nweights = new TColStd_HArray1OfReal(1,nbpoles);
112     nweights->ChangeArray1() = Weights;
113   }
114   
115   // Init
116   Init(npoles,nweights);
117 }
118
119
120 //=======================================================================
121 //function : Increase
122 //purpose  : increase degree
123 //=======================================================================
124
125 void Geom2d_BezierCurve::Increase (const Standard_Integer Deg)
126 {
127   if (Deg == Degree()) return;
128   
129   Standard_ConstructionError_Raise_if
130     (Deg < Degree() ||
131      Deg > Geom2d_BezierCurve::MaxDegree(), "Geom2d_BezierCurve::Increase");
132   
133   Handle(TColgp_HArray1OfPnt2d) npoles =
134     new TColgp_HArray1OfPnt2d(1,Deg+1);
135   
136   Handle(TColStd_HArray1OfReal) nweights;
137   
138   TColStd_Array1OfReal bidknots(1,2); bidknots(1) = 0.; bidknots(2) = 1.;
139   TColStd_Array1OfInteger bidmults(1,2); bidmults.Init(Degree() + 1);
140   
141   if (IsRational()) {
142     nweights = new TColStd_HArray1OfReal(1,Deg+1);
143     BSplCLib::IncreaseDegree(Degree(), Deg, 0,
144                              poles->Array1(),weights->Array1(),
145                              bidknots, bidmults,
146                              npoles->ChangeArray1(),nweights->ChangeArray1(),
147                              bidknots, bidmults);
148   }
149   else {
150     BSplCLib::IncreaseDegree(Degree(), Deg, 0,
151                              poles->Array1(),
152                              *((TColStd_Array1OfReal*) NULL),
153                              bidknots, bidmults,
154                              npoles->ChangeArray1(),
155                              *((TColStd_Array1OfReal*) NULL),
156                              bidknots, bidmults);
157   }
158   
159   Init(npoles,nweights);
160 }
161
162
163 //=======================================================================
164 //function : MaxDegree
165 //purpose  : 
166 //=======================================================================
167
168 Standard_Integer Geom2d_BezierCurve::MaxDegree () 
169
170   return BSplCLib::MaxDegree(); 
171 }
172
173
174 //=======================================================================
175 //function : InsertPoleAfter
176 //purpose  : 
177 //=======================================================================
178
179 void Geom2d_BezierCurve::InsertPoleAfter
180 (const Standard_Integer Index,
181  const gp_Pnt2d& P,
182  const Standard_Real Weight)
183 {
184   Standard_Integer nbpoles = NbPoles();
185   
186   Standard_ConstructionError_Raise_if
187     (nbpoles >= Geom2d_BezierCurve::MaxDegree() ||
188      Weight <= gp::Resolution(), 
189      "Geom2d_BezierCurve::InsertPoleAfter" );
190   
191   Standard_OutOfRange_Raise_if
192     (Index < 0 || Index > nbpoles,
193      "Geom2d_BezierCurve::InsertPoleAfter");
194   
195   Standard_Integer i;
196   
197   // Insert the pole
198   Handle(TColgp_HArray1OfPnt2d) npoles =
199     new TColgp_HArray1OfPnt2d(1,nbpoles+1);
200   
201   TColgp_Array1OfPnt2d&        newpoles = npoles->ChangeArray1();
202   const TColgp_Array1OfPnt2d& oldpoles  = poles->Array1();
203   
204   for (i = 1; i <= Index; i++)
205     newpoles(i) = oldpoles(i);
206   
207   newpoles(Index+1) = P;
208   
209   for (i = Index+1; i <= nbpoles; i++)
210     newpoles(i+1) = oldpoles(i);
211   
212   
213   // Insert the weight
214   Handle(TColStd_HArray1OfReal) nweights;
215   Standard_Boolean rat = IsRational() || Abs(Weight-1.) > gp::Resolution();
216   
217   if (rat) {
218     nweights = new TColStd_HArray1OfReal(1,nbpoles+1);
219     TColStd_Array1OfReal& newweights = nweights->ChangeArray1();
220     
221     for (i = 1; i <= Index; i++)
222       if (IsRational())
223         newweights(i) = weights->Value(i);
224       else
225         newweights(i) = 1.;
226     
227     newweights(Index+1) = Weight;
228     
229     for (i = Index+1; i <= nbpoles; i++)
230       if (IsRational())
231         newweights(i+1) = weights->Value(i);
232       else
233         newweights(i+1) = 1.;
234   }
235   
236   
237   Init(npoles,nweights);
238 }
239
240
241 //=======================================================================
242 //function : InsertPoleBefore
243 //purpose  : 
244 //=======================================================================
245
246 void Geom2d_BezierCurve::InsertPoleBefore
247 (const Standard_Integer Index,
248  const gp_Pnt2d& P,
249  const Standard_Real Weight)
250 {
251   InsertPoleAfter(Index-1,P,Weight);
252 }
253
254
255 //=======================================================================
256 //function : RemovePole
257 //purpose  : 
258 //=======================================================================
259
260 void Geom2d_BezierCurve::RemovePole
261 (const Standard_Integer Index)
262 {
263   Standard_Integer nbpoles = NbPoles();
264   
265   Standard_ConstructionError_Raise_if
266     (nbpoles <= 2 , "Geom2d_BezierCurve::RemovePole" );
267   
268   Standard_OutOfRange_Raise_if
269     (Index < 1 || Index > nbpoles,
270      "Geom2d_BezierCurve::RemovePole");
271   
272   Standard_Integer i;
273   
274   // Remove the pole
275   Handle(TColgp_HArray1OfPnt2d) npoles =
276     new TColgp_HArray1OfPnt2d(1,nbpoles-1);
277   
278   TColgp_Array1OfPnt2d&        newpoles = npoles->ChangeArray1();
279   const TColgp_Array1OfPnt2d& oldpoles  = poles->Array1();
280   
281   for (i = 1; i < Index; i++)
282     newpoles(i) = oldpoles(i);
283   
284   for (i = Index+1; i <= nbpoles; i++)
285     newpoles(i-1) = oldpoles(i);
286   
287   
288   // Remove the weight
289   Handle(TColStd_HArray1OfReal) nweights;
290   
291   if (IsRational()) {
292     nweights = new TColStd_HArray1OfReal(1,nbpoles-1);
293     TColStd_Array1OfReal&       newweights = nweights->ChangeArray1();
294     const TColStd_Array1OfReal& oldweights = weights->Array1();
295     
296     for (i = 1; i < Index; i++)
297       newweights(i) = oldweights(i);
298     
299     for (i = Index+1; i <= nbpoles; i++)
300       newweights(i-1) = oldweights(i);
301   }
302   
303   Init(npoles,nweights);
304 }
305
306
307 //=======================================================================
308 //function : Reverse
309 //purpose  : 
310 //=======================================================================
311
312 void Geom2d_BezierCurve::Reverse ()
313 {
314   gp_Pnt2d P;
315   Standard_Integer i, nbpoles = NbPoles();
316   TColgp_Array1OfPnt2d & cpoles = poles->ChangeArray1();
317   
318   // reverse poles
319   for (i = 1; i <= nbpoles / 2; i++) {
320     P = cpoles(i);
321     cpoles(i) = cpoles(nbpoles-i+1);
322     cpoles(nbpoles-i+1) = P;
323   }
324   
325   // reverse weights
326   if (IsRational()) {
327     TColStd_Array1OfReal & cweights = weights->ChangeArray1();
328     Standard_Real w;
329     for (i = 1; i <= nbpoles / 2; i++) {
330       w = cweights(i);
331       cweights(i) = cweights(nbpoles-i+1);
332       cweights(nbpoles-i+1) = w;
333     }
334   }
335   
336   UpdateCoefficients();
337 }
338
339
340 //=======================================================================
341 //function : ReversedParameter
342 //purpose  : 
343 //=======================================================================
344
345 Standard_Real Geom2d_BezierCurve::ReversedParameter
346 ( const Standard_Real U) const 
347 {
348   return ( 1. - U);
349 }
350
351
352 //=======================================================================
353 //function : Segment
354 //purpose  : 
355 //=======================================================================
356
357 void Geom2d_BezierCurve::Segment
358 (const Standard_Real U1, const Standard_Real U2)
359 {
360   closed =  (Abs(Value(U1).Distance (Value(U2))) <= gp::Resolution());
361 //
362 //   WARNING : when calling trimming be carefull that the cache
363 //   is computed regarding 0.0e0 and not 1.0e0 
364 //
365
366   if (IsRational()) {
367     PLib::Trimming(U1,U2,coeffs->ChangeArray1(),wcoeffs->ChangeArray1());
368     PLib::CoefficientsPoles(coeffs->Array1(),wcoeffs->Array1(),
369                             poles->ChangeArray1(),weights->ChangeArray1());
370   }
371   else {
372     PLib::Trimming(U1,U2,coeffs->ChangeArray1(),
373                    *((TColStd_Array1OfReal*) NULL));
374     PLib::CoefficientsPoles(coeffs->Array1(),
375                             *((TColStd_Array1OfReal*) NULL),
376                             poles->ChangeArray1(),
377                             *((TColStd_Array1OfReal*) NULL));
378   }
379   UpdateCoefficients();
380 }
381
382
383 //=======================================================================
384 //function : SetPole
385 //purpose  : 
386 //=======================================================================
387
388 void Geom2d_BezierCurve::SetPole
389 (const Standard_Integer Index,
390  const gp_Pnt2d& P)
391 {
392   Standard_OutOfRange_Raise_if (Index < 1 || Index > NbPoles(),
393                                 "Geom2d_BezierCurve::SetPole");
394   
395   TColgp_Array1OfPnt2d& cpoles = poles->ChangeArray1();
396   cpoles(Index) = P;
397   
398   if (Index == 1 || Index == cpoles.Length()) {
399     closed = (cpoles(1).Distance(cpoles(NbPoles())) <= gp::Resolution());
400   }
401   
402   UpdateCoefficients();
403 }
404
405
406 //=======================================================================
407 //function : SetPole
408 //purpose  : 
409 //=======================================================================
410
411 void Geom2d_BezierCurve::SetPole
412 (const Standard_Integer Index,
413  const gp_Pnt2d& P,
414  const Standard_Real Weight)
415 {
416   SetPole(Index,P);
417   SetWeight(Index,Weight);
418 }
419
420
421 //=======================================================================
422 //function : SetWeight
423 //purpose  : 
424 //=======================================================================
425
426 void Geom2d_BezierCurve::SetWeight
427 (const Standard_Integer Index,
428  const Standard_Real Weight)
429 {
430   Standard_Integer nbpoles = NbPoles();
431   
432   Standard_OutOfRange_Raise_if
433     (Index < 1 || Index > nbpoles,
434      "Geom2d_BezierCurve::SetWeight");
435   Standard_ConstructionError_Raise_if
436     (Weight <= gp::Resolution (),
437      "Geom2d_BezierCurve::SetWeight");
438   
439   
440   // compute new rationality
441   Standard_Boolean wasrat = IsRational();
442   if (!wasrat) {
443     // a weight of 1. does not turn to rational
444     if (Abs(Weight - 1.) <= gp::Resolution()) return;
445     
446     // set weights of 1.
447     weights = new TColStd_HArray1OfReal(1,nbpoles);
448     wcoeffs = new TColStd_HArray1OfReal(1,nbpoles);
449     weights->Init(1.);
450   }
451   
452   TColStd_Array1OfReal & cweights = weights->ChangeArray1();
453   cweights(Index) = Weight;
454   
455   // is it turning into non rational
456   if (wasrat) {
457     if (!Rational(cweights)) {
458       weights.Nullify();
459       wcoeffs.Nullify();
460     }
461   }
462   
463   UpdateCoefficients();
464 }
465
466
467 //=======================================================================
468 //function : IsClosed
469 //purpose  : 
470 //=======================================================================
471
472 Standard_Boolean Geom2d_BezierCurve::IsClosed () const 
473 {
474   return closed; 
475 }
476
477
478 //=======================================================================
479 //function : IsCN
480 //purpose  : 
481 //=======================================================================
482
483 Standard_Boolean Geom2d_BezierCurve::IsCN (const Standard_Integer ) const 
484 {
485   return Standard_True; 
486 }
487
488
489 //=======================================================================
490 //function : IsPeriodic
491 //purpose  : 
492 //=======================================================================
493
494 Standard_Boolean Geom2d_BezierCurve::IsPeriodic () const 
495 {
496   return Standard_False; 
497 }
498
499
500 //=======================================================================
501 //function : IsRational
502 //purpose  : 
503 //=======================================================================
504
505 Standard_Boolean Geom2d_BezierCurve::IsRational () const 
506 {  
507   return !weights.IsNull(); 
508 }
509
510
511 //=======================================================================
512 //function : Continuity
513 //purpose  : 
514 //=======================================================================
515
516 GeomAbs_Shape Geom2d_BezierCurve::Continuity () const 
517
518   return GeomAbs_CN; 
519 }
520
521
522 //=======================================================================
523 //function : Degree
524 //purpose  : 
525 //=======================================================================
526
527 Standard_Integer Geom2d_BezierCurve::Degree () const 
528 {
529   return poles->Length()-1;
530 }
531
532
533 //=======================================================================
534 //function : D0
535 //purpose  : 
536 //=======================================================================
537
538 void Geom2d_BezierCurve::D0 (const Standard_Real U, gp_Pnt2d& P ) const
539 {
540 //  Idee lumineuse sacrifiee sur l autel des performances.
541 //
542 //  if(!CoefficientsOK(U)) 
543 //    ((Geom2d_BezierCurve*)(void*)this)->UpdateCoefficients(U);
544   if (IsRational())
545     BSplCLib::CacheD0(U,Degree(),parametercache,spanlenghtcache,
546                       coeffs->Array1(),wcoeffs->Array1(),P);
547   else 
548     BSplCLib::CacheD0(U,Degree(),parametercache,spanlenghtcache,
549                       coeffs->Array1(),
550                       *((TColStd_Array1OfReal*) NULL),
551                       P);
552 }
553
554 //=======================================================================
555 //function : D1
556 //purpose  : 
557 //=======================================================================
558
559 void Geom2d_BezierCurve::D1(const Standard_Real U, 
560                             gp_Pnt2d& P, 
561                             gp_Vec2d& V1) const
562 {
563 //  Idee lumineuse sacrifiee sur l autel des performances.
564 //
565 //  if(!CoefficientsOK(U)) 
566 //    ((Geom2d_BezierCurve*)(void*)this)->UpdateCoefficients(U);
567   if (IsRational())
568     BSplCLib::CacheD1(U,Degree(),parametercache,spanlenghtcache,
569                       coeffs->Array1(),wcoeffs->Array1(),P,V1);
570   else 
571     BSplCLib::CacheD1(U,Degree(),parametercache,spanlenghtcache,
572                       coeffs->Array1(),
573                       *((TColStd_Array1OfReal*) NULL),
574                       P,V1);
575 }
576
577 //=======================================================================
578 //function : D2
579 //purpose  : 
580 //=======================================================================
581
582 void Geom2d_BezierCurve::D2 (const Standard_Real U,
583                              gp_Pnt2d& P,
584                              gp_Vec2d& V1,
585                              gp_Vec2d& V2) const
586 {
587 //  Idee lumineuse sacrifiee sur l autel des performances.
588 //
589 //  if(!CoefficientsOK(U)) 
590 //    ((Geom2d_BezierCurve*)(void*)this)->UpdateCoefficients(U);
591   if (IsRational())
592     BSplCLib::CacheD2(U,Degree(),parametercache,spanlenghtcache,
593                       coeffs->Array1(),wcoeffs->Array1(),P,V1,V2);
594   else 
595     BSplCLib::CacheD2(U,Degree(),parametercache,spanlenghtcache,
596                       coeffs->Array1(),
597                       *((TColStd_Array1OfReal*) NULL),
598                       P,V1,V2);
599 }
600
601 //=======================================================================
602 //function : D3
603 //purpose  : 
604 //=======================================================================
605
606 void Geom2d_BezierCurve::D3 (const Standard_Real U,
607                              gp_Pnt2d& P,
608                              gp_Vec2d& V1,
609                              gp_Vec2d& V2,
610                              gp_Vec2d& V3) const
611 {
612 //  Idee lumineuse sacrifiee sur l autel des performances.
613 //
614 //  if(!CoefficientsOK(U)) 
615 //    ((Geom2d_BezierCurve*)(void*)this)->UpdateCoefficients(U);
616   if (IsRational())
617     BSplCLib::CacheD3(U,Degree(),parametercache,spanlenghtcache,
618                       coeffs->Array1(),wcoeffs->Array1(),P,V1,V2,V3);
619   else 
620     BSplCLib::CacheD3(U,Degree(),parametercache,spanlenghtcache,
621                       coeffs->Array1(),
622                       *((TColStd_Array1OfReal*) NULL),
623                       P,V1,V2,V3);
624 }
625
626 //=======================================================================
627 //function : DN
628 //purpose  : 
629 //=======================================================================
630
631 gp_Vec2d Geom2d_BezierCurve::DN (const Standard_Real U,
632                                  const Standard_Integer N) const
633 {
634   Standard_RangeError_Raise_if (N < 1, "Geom2d_BezierCurve::DN");
635   gp_Vec2d V;
636   
637   TColStd_Array1OfReal bidknots(1,2); bidknots(1) = 0.; bidknots(2) = 1.;
638   TColStd_Array1OfInteger bidmults(1,2); bidmults.Init(Degree() + 1);
639   
640   if (IsRational())
641     BSplCLib::DN(U,N,0,Degree(),Standard_False,
642                  poles->Array1(),weights->Array1(),
643                  bidknots,bidmults,V);
644   else 
645     BSplCLib::DN(U,N,0,Degree(),Standard_False,
646                  poles->Array1(),
647                  *((TColStd_Array1OfReal*) NULL),
648                  bidknots,bidmults,V);
649   return V;
650 }
651
652 //=======================================================================
653 //function : EndPoint
654 //purpose  : 
655 //=======================================================================
656
657 gp_Pnt2d Geom2d_BezierCurve::EndPoint () const
658 {
659   return poles->Value (poles->Upper());
660 }
661
662
663 //=======================================================================
664 //function : FirstParameter
665 //purpose  : 
666 //=======================================================================
667
668 Standard_Real Geom2d_BezierCurve::FirstParameter () const 
669 {
670   return 0.0; 
671 }
672
673
674 //=======================================================================
675 //function : LastParameter
676 //purpose  : 
677 //=======================================================================
678
679 Standard_Real Geom2d_BezierCurve::LastParameter () const 
680 {
681   return 1.0; 
682 }
683
684
685 //=======================================================================
686 //function : NbPoles
687 //purpose  : 
688 //=======================================================================
689
690 Standard_Integer Geom2d_BezierCurve::NbPoles () const 
691 {
692   return poles->Length(); 
693 }
694
695
696 //=======================================================================
697 //function : Pole
698 //purpose  : 
699 //=======================================================================
700
701 gp_Pnt2d Geom2d_BezierCurve::Pole (const Standard_Integer Index) const
702 {
703   Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(),
704                                 "Geom2d_BezierCurve::Pole");
705   return poles->Value(Index);
706 }
707
708
709 //=======================================================================
710 //function : Poles
711 //purpose  : 
712 //=======================================================================
713
714 void Geom2d_BezierCurve::Poles (TColgp_Array1OfPnt2d& P) const
715 {
716   Standard_DimensionError_Raise_if (P.Length() != poles->Length(),
717                                     "Geom2d_BezierCurve::Poles");
718   P = poles->Array1();
719 }
720
721
722 //=======================================================================
723 //function : StartPoint
724 //purpose  : 
725 //=======================================================================
726
727 gp_Pnt2d Geom2d_BezierCurve::StartPoint () const
728 {
729   return poles->Value(1);
730 }
731
732
733 //=======================================================================
734 //function : Weight
735 //purpose  : 
736 //=======================================================================
737
738 Standard_Real Geom2d_BezierCurve::Weight
739 (const Standard_Integer Index) const
740 {
741   Standard_OutOfRange_Raise_if (Index < 1 || Index > weights->Length(),
742                                 "Geom2d_BezierCurve::Weight");
743   if (IsRational())
744     return weights->Value(Index);
745   else
746     return 1.;
747 }
748
749
750 //=======================================================================
751 //function : Weights
752 //purpose  : 
753 //=======================================================================
754
755 void Geom2d_BezierCurve::Weights
756 (TColStd_Array1OfReal& W) const
757 {
758   
759   Standard_Integer nbpoles = NbPoles();
760   Standard_DimensionError_Raise_if (W.Length() != nbpoles,
761                                     "Geom2d_BezierCurve::Weights");
762   if (IsRational())
763     W = weights->Array1();
764   else {
765     Standard_Integer i;
766     for (i = 1; i <= nbpoles; i++)
767       W(i) = 1.;
768   }
769 }
770
771
772 //=======================================================================
773 //function : Transform
774 //purpose  : 
775 //=======================================================================
776
777 void Geom2d_BezierCurve::Transform (const gp_Trsf2d& T)
778 {
779   Standard_Integer nbpoles = NbPoles();
780   TColgp_Array1OfPnt2d & cpoles = poles->ChangeArray1();
781   
782   for (Standard_Integer i = 1; i <= nbpoles; i++) 
783     cpoles (i).Transform(T);
784   
785   UpdateCoefficients();
786 }
787
788
789 //=======================================================================
790 //function : Resolution
791 //purpose  : 
792 //=======================================================================
793
794 void Geom2d_BezierCurve::Resolution(const Standard_Real ToleranceUV,
795                                     Standard_Real &     UTolerance)
796 {
797   if(!maxderivinvok){
798     TColStd_Array1OfReal bidflatknots(1, 2*(Degree()+1));
799     for(Standard_Integer i = 1; i <= Degree()+1; i++){
800       bidflatknots(i) = 0.;
801       bidflatknots(i + Degree() +1) = 1.;
802     }
803     
804     if (IsRational()) {  
805       BSplCLib::Resolution(poles->Array1(),
806                            weights->Array1(),
807                            poles->Length(),
808                            bidflatknots,
809                            Degree(),
810                            1.,
811                            maxderivinv) ;
812     }
813     else {
814       BSplCLib::Resolution(poles->Array1(),
815                            *((TColStd_Array1OfReal*) NULL),
816                            poles->Length(),
817                            bidflatknots,
818                            Degree(),
819                            1.,
820                            maxderivinv) ;
821     }
822     maxderivinvok = 1;
823   }
824   UTolerance = ToleranceUV * maxderivinv;
825 }
826
827
828 //=======================================================================
829 //function : Copy
830 //purpose  : 
831 //=======================================================================
832
833 Handle(Geom2d_Geometry) Geom2d_BezierCurve::Copy() const {
834   
835   Handle(Geom2d_BezierCurve) C;
836   if (IsRational())
837     C = new Geom2d_BezierCurve (poles->Array1(),weights->Array1());
838   else
839     C = new Geom2d_BezierCurve (poles->Array1());
840   return C;
841 }
842
843
844 //=======================================================================
845 //function : Init
846 //purpose  : 
847 //=======================================================================
848
849 void Geom2d_BezierCurve::Init
850 (const Handle(TColgp_HArray1OfPnt2d)&   Poles, 
851  const Handle(TColStd_HArray1OfReal)& Weights)
852 {
853   Standard_Integer nbpoles = Poles->Length();
854   // closed ?
855   const TColgp_Array1OfPnt2d&   cpoles   = Poles->Array1();
856   closed = cpoles(1).Distance(cpoles(nbpoles)) <= gp::Resolution(); 
857   
858   // rational
859   rational = !Weights.IsNull();
860   
861   // set fields
862   poles   = Poles;
863   coeffs  = new TColgp_HArray1OfPnt2d  (1,nbpoles);
864   
865   if (rational) {
866     weights = Weights;
867     wcoeffs = new TColStd_HArray1OfReal (1, nbpoles, 0.0);
868   }
869   else {
870     weights.Nullify();
871     wcoeffs.Nullify();
872   }
873   
874   UpdateCoefficients();
875 }
876
877
878 //=======================================================================
879 //function : CoefficientsOK
880 //purpose  : 
881 //=======================================================================
882
883 //Standard_Boolean Geom2d_BezierCurve::CoefficientsOK(const Standard_Real U)const
884 Standard_Boolean Geom2d_BezierCurve::CoefficientsOK(const Standard_Real )const
885 {
886   return (validcache) ;
887                         
888 }
889
890
891 //=======================================================================
892 //function : UpdateCoefficients
893 //purpose  : 
894 //=======================================================================
895
896 //void Geom2d_BezierCurve::UpdateCoefficients(const Standard_Real U)
897 void Geom2d_BezierCurve::UpdateCoefficients(const Standard_Real )
898 {
899   maxderivinvok = 0;
900   parametercache = 0.;
901 //  
902 //  Idee lumineuse sacrifiee sur l autel des performances.
903 //  if (U >= 1.) parametercache = 1.;
904   TColStd_Array1OfReal bidflatknots(BSplCLib::FlatBezierKnots(Degree()),
905                                     1, 2*(Degree()+1));
906   if (IsRational())
907     BSplCLib::BuildCache(parametercache,spanlenghtcache,0,Degree(),
908                          bidflatknots,poles->Array1(),weights->Array1(),
909                          coeffs->ChangeArray1(),wcoeffs->ChangeArray1());
910   else
911     BSplCLib::BuildCache(parametercache,spanlenghtcache,0,Degree(),
912                          bidflatknots,poles->Array1(),
913                          *((TColStd_Array1OfReal*) NULL),
914                          coeffs->ChangeArray1(),
915                          *((TColStd_Array1OfReal*) NULL));
916   validcache = 1;
917 }
918