0024002: Overall code and build procedure refactoring -- automatic
[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                              *((TColStd_Array1OfReal*) NULL),
165                              bidknots, bidmults,
166                              npoles->ChangeArray1(),
167                              *((TColStd_Array1OfReal*) NULL),
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(),
397                    *((TColStd_Array1OfReal*) NULL));
398     PLib::CoefficientsPoles(coeffs->Array1(),
399                             *((TColStd_Array1OfReal*) NULL),
400                             poles->ChangeArray1(),
401                             *((TColStd_Array1OfReal*) NULL));
402   }
403   UpdateCoefficients();
404 }
405
406 //=======================================================================
407 //function : SetPole
408 //purpose  : 
409 //=======================================================================
410
411 void Geom_BezierCurve::SetPole (const Standard_Integer Index,
412                                 const gp_Pnt& P)
413 {
414   if(Index < 1 || Index > NbPoles())
415     Standard_OutOfRange::Raise("Geom_BezierCurve::SetPole");
416   
417   TColgp_Array1OfPnt& cpoles = poles->ChangeArray1();
418   cpoles(Index) = P;
419   
420   if (Index == 1 || Index == cpoles.Length()) {
421     closed = (cpoles(1).Distance(cpoles(NbPoles())) <= Precision::Confusion());
422   }
423   UpdateCoefficients();
424 }
425
426 //=======================================================================
427 //function : SetPole
428 //purpose  : 
429 //=======================================================================
430
431 void Geom_BezierCurve::SetPole(const Standard_Integer Index,
432                                const gp_Pnt& P,
433                                const Standard_Real Weight)
434 {
435   SetPole(Index,P);
436   SetWeight(Index,Weight);
437 }
438
439 //=======================================================================
440 //function : SetWeight
441 //purpose  : 
442 //=======================================================================
443
444 void Geom_BezierCurve::SetWeight(const Standard_Integer Index,
445                                  const Standard_Real Weight)
446 {
447   Standard_Integer nbpoles = NbPoles();
448   
449   if(Index < 1 || Index > nbpoles)
450     Standard_OutOfRange::Raise("Geom_BezierCurve::SetWeight");
451   if(Weight <= gp::Resolution ())
452     Standard_ConstructionError::Raise("Geom_BezierCurve::SetWeight");
453   
454   // compute new rationality
455   Standard_Boolean wasrat = IsRational();
456   if (!wasrat) {
457     // a weight of 1. does not turn to rational
458     if (Abs(Weight - 1.) <= gp::Resolution()) return;
459     
460     // set weights of 1.
461     weights = new TColStd_HArray1OfReal(1,nbpoles);
462     wcoeffs = new TColStd_HArray1OfReal(1,nbpoles);
463     weights->Init(1.);
464   }
465   
466   TColStd_Array1OfReal & cweights = weights->ChangeArray1();
467   cweights(Index) = Weight;
468   
469   // is it turning into non rational
470   if (wasrat) {
471     if (!Rational(cweights)) {
472       weights.Nullify();
473       wcoeffs.Nullify();
474     }
475   }
476   UpdateCoefficients();
477 }
478
479 //=======================================================================
480 //function : IsClosed
481 //purpose  : 
482 //=======================================================================
483
484 Standard_Boolean Geom_BezierCurve::IsClosed () const 
485 {
486   return closed; 
487 }
488
489 //=======================================================================
490 //function : IsCN
491 //purpose  : 
492 //=======================================================================
493
494 Standard_Boolean Geom_BezierCurve::IsCN (const Standard_Integer ) const 
495 {
496   return Standard_True; 
497 }
498
499 //=======================================================================
500 //function : IsPeriodic
501 //purpose  : 
502 //=======================================================================
503
504 Standard_Boolean Geom_BezierCurve::IsPeriodic () const 
505 {
506   return Standard_False; 
507 }
508
509 //=======================================================================
510 //function : IsRational
511 //purpose  : 
512 //=======================================================================
513
514 Standard_Boolean Geom_BezierCurve::IsRational () const 
515 {  
516   return !weights.IsNull(); 
517 }
518
519 //=======================================================================
520 //function : Continuity
521 //purpose  : 
522 //=======================================================================
523
524 GeomAbs_Shape Geom_BezierCurve::Continuity () const 
525
526   return GeomAbs_CN; 
527 }
528
529 //=======================================================================
530 //function : Degree
531 //purpose  : 
532 //=======================================================================
533
534 Standard_Integer Geom_BezierCurve::Degree () const 
535 {
536   return poles->Length()-1;
537 }
538
539 //=======================================================================
540 //function : D0
541 //purpose  : 
542 //=======================================================================
543
544 void Geom_BezierCurve::D0 (const Standard_Real U, gp_Pnt& P ) const
545 {
546   //  Idee lumineuse sacrifiee sur l autel des performances.
547   //
548   //  if(!CoefficientsOK(U)) 
549   //    ((Geom_BezierCurve*)(void*)this)->UpdateCoefficients(U);
550   if (IsRational())
551     BSplCLib::CacheD0(U,Degree(),parametercache,spanlenghtcache,
552                       coeffs->Array1(),
553                       wcoeffs->Array1(),
554                       P);
555   else 
556     BSplCLib::CacheD0(U,Degree(),parametercache,spanlenghtcache,
557                       coeffs->Array1(),
558                       *((TColStd_Array1OfReal*) NULL),P
559                       );
560 }
561
562 //=======================================================================
563 //function : D1
564 //purpose  : 
565 //=======================================================================
566
567 void Geom_BezierCurve::D1(const Standard_Real U, gp_Pnt& P, gp_Vec& V1) const
568 {
569   //  Idee lumineuse sacrifiee sur l autel des performances.
570   //
571   //  if(!CoefficientsOK(U)) 
572   //    ((Geom_BezierCurve*)(void*)this)->UpdateCoefficients(U);
573   if (IsRational())
574     BSplCLib::CacheD1(U,Degree(),parametercache,spanlenghtcache,
575                       coeffs->Array1(),
576                       wcoeffs->Array1(),
577                       P,V1);
578   else 
579     BSplCLib::CacheD1(U,Degree(),parametercache,spanlenghtcache,
580                       coeffs->Array1(),
581                       *((TColStd_Array1OfReal*) NULL),
582                       P,V1);
583 }
584
585 //=======================================================================
586 //function : D2
587 //purpose  : 
588 //=======================================================================
589
590 void Geom_BezierCurve::D2 (const Standard_Real U,
591                            gp_Pnt& P,
592                            gp_Vec& V1,
593                            gp_Vec& V2) const
594 {
595   //  Idee lumineuse sacrifiee sur l autel des performances.
596   //
597   //  if(!CoefficientsOK(U)) 
598   //    ((Geom_BezierCurve*)(void*)this)->UpdateCoefficients(U);
599   if (IsRational())
600     BSplCLib::CacheD2(U,Degree(),parametercache,spanlenghtcache,
601                       coeffs->Array1(),
602                       wcoeffs->Array1(),
603                       P,V1,V2);
604   else 
605     BSplCLib::CacheD2(U,Degree(),parametercache,spanlenghtcache,
606                       coeffs->Array1(),
607                       *((TColStd_Array1OfReal*) NULL),
608                       P,V1,V2);
609 }
610
611 //=======================================================================
612 //function : D3
613 //purpose  : 
614 //=======================================================================
615
616 void Geom_BezierCurve::D3 (const Standard_Real U,
617                            gp_Pnt& P,
618                            gp_Vec& V1,
619                            gp_Vec& V2,
620                            gp_Vec& V3) const
621 {
622   if(!CoefficientsOK(U)) 
623     ((Geom_BezierCurve*)(void*)this)->UpdateCoefficients(U);
624   if (IsRational())
625     BSplCLib::CacheD3(U,Degree(),parametercache,spanlenghtcache,
626                       coeffs->Array1(),
627                       wcoeffs->Array1(),
628                       P,V1,V2,V3);
629   else 
630     BSplCLib::CacheD3(U,Degree(),parametercache,spanlenghtcache,
631                       coeffs->Array1(),
632                       *((TColStd_Array1OfReal*) NULL),
633                       P,V1,V2,V3);
634 }
635
636 //=======================================================================
637 //function : DN
638 //purpose  : 
639 //=======================================================================
640
641 gp_Vec Geom_BezierCurve::DN (const Standard_Real U,
642                              const Standard_Integer N) const
643 {
644   if(N < 1) 
645     Standard_RangeError::Raise("Geom_BezierCurve::DN");
646   gp_Vec V;
647
648   TColStd_Array1OfReal bidknots(1,2); bidknots(1) = 0.; bidknots(2) = 1.;
649   TColStd_Array1OfInteger bidmults(1,2); bidmults.Init(Degree() + 1);
650
651   if (IsRational())
652 //    BSplCLib::DN(U,N,0,Degree(),0.,
653     BSplCLib::DN(U,N,0,Degree(),Standard_False,
654                  poles->Array1(),
655                  weights->Array1(),
656                  bidknots,bidmults,V);
657   else 
658 //    BSplCLib::DN(U,N,0,Degree(),0.,
659     BSplCLib::DN(U,N,0,Degree(),Standard_False,
660                  poles->Array1(),
661                  *((TColStd_Array1OfReal*) NULL),
662                  bidknots,bidmults,V);
663   return V;
664 }
665
666 //=======================================================================
667 //function : StartPoint
668 //purpose  : 
669 //=======================================================================
670
671 gp_Pnt Geom_BezierCurve::StartPoint () const
672 {
673   return poles->Value(1);
674 }
675
676 //=======================================================================
677 //function : EndPoint
678 //purpose  : 
679 //=======================================================================
680
681 gp_Pnt Geom_BezierCurve::EndPoint () const
682 {
683   return poles->Value (poles->Upper());
684 }
685
686 //=======================================================================
687 //function : FirstParameter
688 //purpose  : 
689 //=======================================================================
690
691 Standard_Real Geom_BezierCurve::FirstParameter () const 
692 {
693   return 0.0; 
694 }
695
696 //=======================================================================
697 //function : LastParameter
698 //purpose  : 
699 //=======================================================================
700
701 Standard_Real Geom_BezierCurve::LastParameter () const 
702 {
703   return 1.0; 
704 }
705
706 //=======================================================================
707 //function : NbPoles
708 //purpose  : 
709 //=======================================================================
710
711 Standard_Integer Geom_BezierCurve::NbPoles () const 
712 {
713   return poles->Length(); 
714 }
715
716 //=======================================================================
717 //function : Pole
718 //purpose  : 
719 //=======================================================================
720
721 gp_Pnt Geom_BezierCurve::Pole (const Standard_Integer Index) const
722 {
723   if(Index < 1 || Index > poles->Length()) 
724     Standard_OutOfRange::Raise("Geom_BezierCurve::Pole");
725   return poles->Value(Index);
726 }
727
728 //=======================================================================
729 //function : Poles
730 //purpose  : 
731 //=======================================================================
732
733 void Geom_BezierCurve::Poles (TColgp_Array1OfPnt& P) const
734 {
735   if(P.Length() != poles->Length()) 
736     Standard_DimensionError::Raise("Geom_BezierCurve::Poles");
737   P = poles->Array1();
738 }
739
740 //=======================================================================
741 //function : Weight
742 //purpose  : 
743 //=======================================================================
744
745 Standard_Real Geom_BezierCurve::Weight
746 (const Standard_Integer Index) const
747 {
748   if(Index < 1 || Index > poles->Length()) 
749     Standard_OutOfRange::Raise("Geom_BezierCurve::Weight");
750   if (IsRational())
751     return weights->Value(Index);
752   else
753     return 1.;
754 }
755
756 //=======================================================================
757 //function : Weights
758 //purpose  : 
759 //=======================================================================
760
761 void Geom_BezierCurve::Weights
762 (TColStd_Array1OfReal& W) const
763 {
764
765   Standard_Integer nbpoles = NbPoles();
766   if(W.Length() != nbpoles)
767     Standard_DimensionError::Raise("Geom_BezierCurve::Weights");
768   if (IsRational())
769     W = weights->Array1();
770   else {
771     Standard_Integer i;
772     for (i = 1; i <= nbpoles; i++)
773       W(i) = 1.;
774   }
775 }
776
777 //=======================================================================
778 //function : Transform
779 //purpose  : 
780 //=======================================================================
781
782 void Geom_BezierCurve::Transform (const gp_Trsf& T)
783 {
784   Standard_Integer nbpoles = NbPoles();
785   TColgp_Array1OfPnt & cpoles = poles->ChangeArray1();
786
787   for (Standard_Integer i = 1; i <= nbpoles; i++) 
788     cpoles (i).Transform(T);
789   
790   UpdateCoefficients();
791 }
792
793 //=======================================================================
794 //function : Resolution
795 //purpose  : 
796 //=======================================================================
797
798 void Geom_BezierCurve::Resolution(const Standard_Real Tolerance3D,
799                                   Standard_Real &     UTolerance) 
800 {
801   if(!maxderivinvok){
802     TColStd_Array1OfReal bidflatknots(BSplCLib::FlatBezierKnots(Degree()),
803                                       1, 2*(Degree()+1));
804     
805     if (IsRational()) {  
806       BSplCLib::Resolution(poles->Array1(),
807                            weights->Array1(),
808                            poles->Length(),
809                            bidflatknots,
810                            Degree(),
811                            1.,
812                            maxderivinv) ;
813     }
814     else {
815       BSplCLib::Resolution(poles->Array1(),
816                            BSplCLib::NoWeights(),
817                            poles->Length(),
818                            bidflatknots,
819                            Degree(),
820                            1.,
821                            maxderivinv) ;
822     }
823     maxderivinvok = 1;
824   }
825   UTolerance = Tolerance3D * maxderivinv;
826 }
827
828 //=======================================================================
829 //function : Copy
830 //purpose  : 
831 //=======================================================================
832
833 Handle(Geom_Geometry) Geom_BezierCurve::Copy() const {
834
835   Handle(Geom_BezierCurve) C;
836   if (IsRational())
837     C = new Geom_BezierCurve (poles->Array1(),weights->Array1());
838   else
839     C = new Geom_BezierCurve (poles->Array1());
840   return C;
841 }
842
843 //=======================================================================
844 //function : Init
845 //purpose  : 
846 //=======================================================================
847
848 void Geom_BezierCurve::Init
849 (const Handle(TColgp_HArray1OfPnt)&   Poles, 
850  const Handle(TColStd_HArray1OfReal)& Weights)
851 {
852   Standard_Integer nbpoles = Poles->Length();
853   // closed ?
854   const TColgp_Array1OfPnt&   cpoles   = Poles->Array1();
855   closed = cpoles(1).Distance(cpoles(nbpoles)) <= Precision::Confusion(); 
856
857   // rational
858   rational = !Weights.IsNull();
859
860   // set fields
861   poles   = Poles;
862   coeffs  = new TColgp_HArray1OfPnt  (1,nbpoles);
863
864   if (rational) {
865     weights = Weights;
866     wcoeffs = new TColStd_HArray1OfReal (1, nbpoles, 0.0);
867   }
868   else {
869     weights.Nullify();
870     wcoeffs.Nullify();
871   }
872
873   UpdateCoefficients();
874 }
875
876 //=======================================================================
877 //function : CoefficientsOK
878 //purpose  : 
879 //=======================================================================
880
881 Standard_Boolean Geom_BezierCurve::CoefficientsOK(const Standard_Real U)const
882 {
883   return (validcache && ((parametercache == 0. && U < 1.) ||
884                          (parametercache == 1. && U >= 1.)));
885 }
886
887 //=======================================================================
888 //function : UpdateCoefficients
889 //purpose  : 
890 //=======================================================================
891
892 //void Geom_BezierCurve::UpdateCoefficients(const Standard_Real U)
893 void Geom_BezierCurve::UpdateCoefficients(const Standard_Real )
894 {
895   maxderivinvok = 0;
896   parametercache = 0.;
897   //  
898   //  Idee lumineuse sacrifiee sur l autel des performances.
899   //  if (U >= 1.) parametercache = 1.;
900   TColStd_Array1OfReal bidflatknots(BSplCLib::FlatBezierKnots(Degree()),
901                                     1, 2*(Degree()+1));
902   if (IsRational())
903     BSplCLib::BuildCache(parametercache,spanlenghtcache,0,Degree(),
904                          bidflatknots,poles->Array1(),
905                          weights->Array1(),
906                          coeffs->ChangeArray1(),
907                          wcoeffs->ChangeArray1());
908   else
909     BSplCLib::BuildCache(parametercache,spanlenghtcache,0,Degree(),
910                          bidflatknots,poles->Array1(),
911                          *((TColStd_Array1OfReal*) NULL),
912                          coeffs->ChangeArray1(),
913                          *((TColStd_Array1OfReal*) NULL));
914   validcache = 1;
915 }
916