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