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