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