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