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 
IMPLEMENT_STANDARD_RTTIEXT(Geom_BezierCurve,Geom_BoundedCurve)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 
Geom_BezierCurve(const TColgp_Array1OfPnt & Poles)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 
Geom_BezierCurve(const TColgp_Array1OfPnt & Poles,const TColStd_Array1OfReal & Weights)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 
Increase(const Standard_Integer Deg)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 
MaxDegree()178 Standard_Integer Geom_BezierCurve::MaxDegree ()
179 {
180   return BSplCLib::MaxDegree();
181 }
182 
183 //=======================================================================
184 //function : InsertPoleAfter
185 //purpose  :
186 //=======================================================================
187 
InsertPoleAfter(const Standard_Integer Index,const gp_Pnt & P)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 
InsertPoleAfter(const Standard_Integer Index,const gp_Pnt & P,const Standard_Real Weight)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 
InsertPoleBefore(const Standard_Integer Index,const gp_Pnt & P)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 
InsertPoleBefore(const Standard_Integer Index,const gp_Pnt & P,const Standard_Real Weight)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 
RemovePole(const Standard_Integer Index)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 
Reverse()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 
ReversedParameter(const Standard_Real U) const369 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 
Segment(const Standard_Real U1,const Standard_Real U2)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 
SetPole(const Standard_Integer Index,const gp_Pnt & P)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 
SetPole(const Standard_Integer Index,const gp_Pnt & P,const Standard_Real Weight)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 
SetWeight(const Standard_Integer Index,const Standard_Real Weight)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 
IsClosed() const471 Standard_Boolean Geom_BezierCurve::IsClosed () const
472 {
473   return closed;
474 }
475 
476 //=======================================================================
477 //function : IsCN
478 //purpose  :
479 //=======================================================================
480 
IsCN(const Standard_Integer) const481 Standard_Boolean Geom_BezierCurve::IsCN (const Standard_Integer ) const
482 {
483   return Standard_True;
484 }
485 
486 //=======================================================================
487 //function : IsPeriodic
488 //purpose  :
489 //=======================================================================
490 
IsPeriodic() const491 Standard_Boolean Geom_BezierCurve::IsPeriodic () const
492 {
493   return Standard_False;
494 }
495 
496 //=======================================================================
497 //function : IsRational
498 //purpose  :
499 //=======================================================================
500 
IsRational() const501 Standard_Boolean Geom_BezierCurve::IsRational () const
502 {
503   return !weights.IsNull();
504 }
505 
506 //=======================================================================
507 //function : Continuity
508 //purpose  :
509 //=======================================================================
510 
Continuity() const511 GeomAbs_Shape Geom_BezierCurve::Continuity () const
512 {
513   return GeomAbs_CN;
514 }
515 
516 //=======================================================================
517 //function : Degree
518 //purpose  :
519 //=======================================================================
520 
Degree() const521 Standard_Integer Geom_BezierCurve::Degree () const
522 {
523   return poles->Length()-1;
524 }
525 
526 //=======================================================================
527 //function : D0
528 //purpose  :
529 //=======================================================================
530 
D0(const Standard_Real U,gp_Pnt & P) const531 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 
D1(const Standard_Real U,gp_Pnt & P,gp_Vec & V1) const541 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 
D2(const Standard_Real U,gp_Pnt & P,gp_Vec & V1,gp_Vec & V2) const551 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 
D3(const Standard_Real U,gp_Pnt & P,gp_Vec & V1,gp_Vec & V2,gp_Vec & V3) const564 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 
DN(const Standard_Real U,const Standard_Integer N) const578 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 
StartPoint() const608 gp_Pnt Geom_BezierCurve::StartPoint () const
609 {
610   return poles->Value(1);
611 }
612 
613 //=======================================================================
614 //function : EndPoint
615 //purpose  :
616 //=======================================================================
617 
EndPoint() const618 gp_Pnt Geom_BezierCurve::EndPoint () const
619 {
620   return poles->Value (poles->Upper());
621 }
622 
623 //=======================================================================
624 //function : FirstParameter
625 //purpose  :
626 //=======================================================================
627 
FirstParameter() const628 Standard_Real Geom_BezierCurve::FirstParameter () const
629 {
630   return 0.0;
631 }
632 
633 //=======================================================================
634 //function : LastParameter
635 //purpose  :
636 //=======================================================================
637 
LastParameter() const638 Standard_Real Geom_BezierCurve::LastParameter () const
639 {
640   return 1.0;
641 }
642 
643 //=======================================================================
644 //function : NbPoles
645 //purpose  :
646 //=======================================================================
647 
NbPoles() const648 Standard_Integer Geom_BezierCurve::NbPoles () const
649 {
650   return poles->Length();
651 }
652 
653 //=======================================================================
654 //function : Pole
655 //purpose  :
656 //=======================================================================
657 
Pole(const Standard_Integer Index) const658 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 
Poles(TColgp_Array1OfPnt & P) const670 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 
Poles() const683 const TColgp_Array1OfPnt& Geom_BezierCurve::Poles() const
684 {
685   return poles->Array1();
686 }
687 
688 //=======================================================================
689 //function : Weight
690 //purpose  :
691 //=======================================================================
692 
Weight(const Standard_Integer Index) const693 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 
Weights(TColStd_Array1OfReal & W) const709 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 
Transform(const gp_Trsf & T)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 
Resolution(const Standard_Real Tolerance3D,Standard_Real & UTolerance)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 
Handle(Geom_Geometry)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 
Init(const Handle (TColgp_HArray1OfPnt)& Poles,const Handle (TColStd_HArray1OfReal)& Weights)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 //=======================================================================
DumpJson(Standard_OStream & theOStream,Standard_Integer theDepth) const819 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 
836