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