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