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