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