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 | |
42cf5bc1 |
29 | |
7fd59977 |
30 | #include <BSplCLib.hxx> |
42cf5bc1 |
31 | #include <Geom_BezierCurve.hxx> |
32 | #include <Geom_Geometry.hxx> |
7fd59977 |
33 | #include <gp.hxx> |
42cf5bc1 |
34 | #include <gp_Pnt.hxx> |
35 | #include <gp_Trsf.hxx> |
36 | #include <gp_Vec.hxx> |
7fd59977 |
37 | #include <gp_XYZ.hxx> |
42cf5bc1 |
38 | #include <PLib.hxx> |
39 | #include <Precision.hxx> |
7fd59977 |
40 | #include <Standard_ConstructionError.hxx> |
41 | #include <Standard_DimensionError.hxx> |
42 | #include <Standard_OutOfRange.hxx> |
43 | #include <Standard_RangeError.hxx> |
42cf5bc1 |
44 | #include <Standard_Type.hxx> |
7fd59977 |
45 | #include <TColStd_Array1OfInteger.hxx> |
7fd59977 |
46 | |
47 | //======================================================================= |
48 | //function : Rational |
49 | //purpose : check rationality of an array of weights |
50 | //======================================================================= |
7fd59977 |
51 | static Standard_Boolean Rational(const TColStd_Array1OfReal& W) |
52 | { |
53 | Standard_Integer i, n = W.Length(); |
54 | Standard_Boolean rat = Standard_False; |
55 | for (i = 1; i < n; i++) { |
56 | rat = Abs(W(i) - W(i+1)) > gp::Resolution(); |
57 | if (rat) break; |
58 | } |
59 | return rat; |
60 | } |
61 | |
62 | //======================================================================= |
63 | //function : Geom_BezierCurve |
64 | //purpose : |
65 | //======================================================================= |
66 | |
67 | Geom_BezierCurve::Geom_BezierCurve(const TColgp_Array1OfPnt& Poles): |
68 | validcache(0), parametercache(0.), spanlenghtcache(1.) |
69 | { |
70 | Standard_Integer nbpoles = Poles.Length(); |
71 | if(nbpoles < 2 || nbpoles > (Geom_BezierCurve::MaxDegree() + 1)) |
72 | Standard_ConstructionError::Raise(); |
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 | validcache(0), parametercache(0.), spanlenghtcache(1.) |
92 | { |
93 | // copy the poles |
94 | Standard_Integer nbpoles = Poles.Length(); |
95 | if(nbpoles < 2 || nbpoles > (Geom_BezierCurve::MaxDegree() + 1)) |
96 | Standard_ConstructionError::Raise(); |
97 | |
98 | Handle(TColgp_HArray1OfPnt) npoles = |
99 | new TColgp_HArray1OfPnt(1,nbpoles); |
100 | |
101 | npoles->ChangeArray1() = Poles; |
102 | |
103 | |
104 | // check the weights |
105 | |
106 | if (Weights.Length() != nbpoles) |
107 | Standard_ConstructionError::Raise(); |
108 | |
109 | Standard_Integer i; |
110 | for (i = 1; i <= nbpoles; i++) { |
111 | if (Weights(i) <= gp::Resolution()) { |
112 | Standard_ConstructionError::Raise(); |
113 | } |
114 | } |
115 | |
116 | // check really rational |
117 | Standard_Boolean rat = Rational(Weights); |
118 | |
119 | // copy the weights |
120 | Handle(TColStd_HArray1OfReal) nweights; |
121 | if (rat) { |
122 | nweights = new TColStd_HArray1OfReal(1,nbpoles); |
123 | nweights->ChangeArray1() = Weights; |
124 | } |
125 | |
126 | // Init |
127 | Init(npoles,nweights); |
128 | } |
129 | |
130 | //======================================================================= |
131 | //function : Increase |
132 | //purpose : increase degree |
133 | //======================================================================= |
134 | |
135 | void Geom_BezierCurve::Increase (const Standard_Integer Deg) |
136 | { |
137 | if (Deg == Degree()) return; |
138 | |
139 | if(Deg < Degree() || |
140 | Deg > Geom_BezierCurve::MaxDegree()) |
141 | Standard_ConstructionError::Raise("Geom_BezierCurve::Increase"); |
142 | |
143 | Handle(TColgp_HArray1OfPnt) npoles = |
144 | new TColgp_HArray1OfPnt(1,Deg+1); |
145 | |
146 | Handle(TColStd_HArray1OfReal) nweights; |
147 | |
148 | TColStd_Array1OfReal bidknots(1,2); bidknots(1) = 0.; bidknots(2) = 1.; |
149 | TColStd_Array1OfInteger bidmults(1,2); bidmults.Init(Degree() + 1); |
150 | |
151 | if (IsRational()) { |
152 | nweights = new TColStd_HArray1OfReal(1,Deg+1); |
153 | BSplCLib::IncreaseDegree(Degree(), Deg, 0, |
154 | poles->Array1(), |
0e14656b |
155 | &weights->Array1(), |
7fd59977 |
156 | bidknots, bidmults, |
157 | npoles->ChangeArray1(), |
0e14656b |
158 | &nweights->ChangeArray1(), |
7fd59977 |
159 | bidknots, bidmults); |
160 | } |
161 | else { |
162 | BSplCLib::IncreaseDegree(Degree(), Deg, 0, |
163 | poles->Array1(), |
0e14656b |
164 | BSplCLib::NoWeights(), |
7fd59977 |
165 | bidknots, bidmults, |
166 | npoles->ChangeArray1(), |
0e14656b |
167 | BSplCLib::NoWeights(), |
7fd59977 |
168 | bidknots, bidmults); |
169 | } |
170 | |
171 | Init(npoles,nweights); |
172 | } |
173 | |
174 | //======================================================================= |
175 | //function : MaxDegree |
176 | //purpose : |
177 | //======================================================================= |
178 | |
179 | Standard_Integer Geom_BezierCurve::MaxDegree () |
180 | { |
181 | return BSplCLib::MaxDegree(); |
182 | } |
183 | |
184 | //======================================================================= |
185 | //function : InsertPoleAfter |
186 | //purpose : |
187 | //======================================================================= |
188 | |
189 | void Geom_BezierCurve::InsertPoleAfter |
190 | (const Standard_Integer Index, |
191 | const gp_Pnt& P) |
192 | { |
193 | InsertPoleAfter(Index,P,1.); |
194 | } |
195 | |
196 | //======================================================================= |
197 | //function : InsertPoleAfter |
198 | //purpose : |
199 | //======================================================================= |
200 | |
201 | void Geom_BezierCurve::InsertPoleAfter |
202 | (const Standard_Integer Index, |
203 | const gp_Pnt& P, |
204 | const Standard_Real Weight) |
205 | { |
206 | Standard_Integer nbpoles = NbPoles(); |
207 | |
208 | if(nbpoles >= Geom_BezierCurve::MaxDegree() || |
209 | Weight <= gp::Resolution()) |
210 | Standard_ConstructionError::Raise("Geom_BezierCurve::InsertPoleAfter"); |
211 | |
212 | if(Index < 0 || Index > nbpoles) |
213 | Standard_OutOfRange::Raise("Geom_BezierCurve::InsertPoleAfter"); |
214 | |
215 | Standard_Integer i; |
216 | |
217 | // Insert the pole |
218 | Handle(TColgp_HArray1OfPnt) npoles = |
219 | new TColgp_HArray1OfPnt(1,nbpoles+1); |
220 | |
221 | TColgp_Array1OfPnt& newpoles = npoles->ChangeArray1(); |
222 | const TColgp_Array1OfPnt& oldpoles = poles->Array1(); |
223 | |
224 | for (i = 1; i <= Index; i++) |
225 | newpoles(i) = oldpoles(i); |
226 | |
227 | newpoles(Index+1) = P; |
228 | |
229 | for (i = Index+1; i <= nbpoles; i++) |
230 | newpoles(i+1) = oldpoles(i); |
231 | |
232 | |
233 | // Insert the weight |
234 | Handle(TColStd_HArray1OfReal) nweights; |
235 | Standard_Boolean rat = IsRational() || Abs(Weight-1.) > gp::Resolution(); |
236 | |
237 | if (rat) { |
238 | nweights = new TColStd_HArray1OfReal(1,nbpoles+1); |
239 | TColStd_Array1OfReal& newweights = nweights->ChangeArray1(); |
240 | |
241 | for (i = 1; i <= Index; i++) |
242 | if (IsRational()) |
243 | newweights(i) = weights->Value(i); |
244 | else |
245 | newweights(i) = 1.; |
246 | |
247 | newweights(Index+1) = Weight; |
248 | |
249 | for (i = Index+1; i <= nbpoles; i++) |
250 | if (IsRational()) |
251 | newweights(i+1) = weights->Value(i); |
252 | else |
253 | newweights(i+1) = 1.; |
254 | } |
255 | |
256 | |
257 | Init(npoles,nweights); |
258 | } |
259 | |
260 | //======================================================================= |
261 | //function : InsertPoleBefore |
262 | //purpose : |
263 | //======================================================================= |
264 | |
265 | void Geom_BezierCurve::InsertPoleBefore |
266 | (const Standard_Integer Index, |
267 | const gp_Pnt& P) |
268 | { |
269 | InsertPoleAfter(Index-1,P); |
270 | } |
271 | |
272 | //======================================================================= |
273 | //function : InsertPoleBefore |
274 | //purpose : |
275 | //======================================================================= |
276 | |
277 | void Geom_BezierCurve::InsertPoleBefore |
278 | (const Standard_Integer Index, |
279 | const gp_Pnt& P, |
280 | const Standard_Real Weight) |
281 | { |
282 | InsertPoleAfter(Index-1,P,Weight); |
283 | } |
284 | |
285 | //======================================================================= |
286 | //function : RemovePole |
287 | //purpose : |
288 | //======================================================================= |
289 | |
290 | void Geom_BezierCurve::RemovePole |
291 | (const Standard_Integer Index) |
292 | { |
293 | Standard_Integer nbpoles = NbPoles(); |
294 | |
295 | if(nbpoles <= 2) |
296 | Standard_ConstructionError::Raise("Geom_BezierCurve::RemovePole"); |
297 | |
298 | if(Index < 1 || Index > nbpoles) |
299 | Standard_OutOfRange::Raise("Geom_BezierCurve::RemovePole"); |
300 | |
301 | Standard_Integer i; |
302 | |
303 | // Remove the pole |
304 | Handle(TColgp_HArray1OfPnt) npoles = |
305 | new TColgp_HArray1OfPnt(1,nbpoles-1); |
306 | |
307 | TColgp_Array1OfPnt& newpoles = npoles->ChangeArray1(); |
308 | const TColgp_Array1OfPnt& oldpoles = poles->Array1(); |
309 | |
310 | for (i = 1; i < Index; i++) |
311 | newpoles(i) = oldpoles(i); |
312 | |
313 | for (i = Index+1; i <= nbpoles; i++) |
314 | newpoles(i-1) = oldpoles(i); |
315 | |
316 | |
317 | // Remove the weight |
318 | Handle(TColStd_HArray1OfReal) nweights; |
319 | |
320 | if (IsRational()) { |
321 | nweights = new TColStd_HArray1OfReal(1,nbpoles-1); |
322 | TColStd_Array1OfReal& newweights = nweights->ChangeArray1(); |
323 | const TColStd_Array1OfReal& oldweights = weights->Array1(); |
324 | |
325 | for (i = 1; i < Index; i++) |
326 | newweights(i) = oldweights(i); |
327 | |
328 | for (i = Index+1; i <= nbpoles; i++) |
329 | newweights(i-1) = oldweights(i); |
330 | } |
331 | |
332 | Init(npoles,nweights); |
333 | } |
334 | |
335 | //======================================================================= |
336 | //function : Reverse |
337 | //purpose : |
338 | //======================================================================= |
339 | |
340 | void Geom_BezierCurve::Reverse () |
341 | { |
342 | gp_Pnt P; |
343 | Standard_Integer i, nbpoles = NbPoles(); |
344 | TColgp_Array1OfPnt & cpoles = poles->ChangeArray1(); |
345 | |
346 | // reverse poles |
347 | for (i = 1; i <= nbpoles / 2; i++) { |
348 | P = cpoles(i); |
349 | cpoles(i) = cpoles(nbpoles-i+1); |
350 | cpoles(nbpoles-i+1) = P; |
351 | } |
352 | |
353 | // reverse weights |
354 | if (IsRational()) { |
355 | TColStd_Array1OfReal & cweights = weights->ChangeArray1(); |
356 | Standard_Real w; |
357 | for (i = 1; i <= nbpoles / 2; i++) { |
358 | w = cweights(i); |
359 | cweights(i) = cweights(nbpoles-i+1); |
360 | cweights(nbpoles-i+1) = w; |
361 | } |
362 | } |
363 | |
364 | UpdateCoefficients(); |
365 | } |
366 | |
367 | //======================================================================= |
368 | //function : ReversedParameter |
369 | //purpose : |
370 | //======================================================================= |
371 | |
372 | Standard_Real Geom_BezierCurve::ReversedParameter(const Standard_Real U) const |
373 | { |
374 | return ( 1. - U); |
375 | } |
376 | |
377 | //======================================================================= |
378 | //function : Segment |
379 | //purpose : |
380 | //======================================================================= |
381 | |
382 | void Geom_BezierCurve::Segment(const Standard_Real U1, const Standard_Real U2) |
383 | { |
384 | closed = (Abs(Value(U1).Distance (Value(U2))) <= Precision::Confusion()); |
385 | |
386 | if(!CoefficientsOK(0.)) UpdateCoefficients(0.); |
387 | if (IsRational()) { |
388 | PLib::Trimming(U1,U2,coeffs->ChangeArray1(), |
0e14656b |
389 | &wcoeffs->ChangeArray1()); |
7fd59977 |
390 | PLib::CoefficientsPoles(coeffs->Array1(), |
0e14656b |
391 | &wcoeffs->Array1(), |
7fd59977 |
392 | poles->ChangeArray1(), |
0e14656b |
393 | &weights->ChangeArray1()); |
7fd59977 |
394 | } |
395 | else { |
0e14656b |
396 | PLib::Trimming(U1,U2,coeffs->ChangeArray1(), PLib::NoWeights()); |
397 | PLib::CoefficientsPoles(coeffs->Array1(), PLib::NoWeights(), |
398 | poles->ChangeArray1(), PLib::NoWeights()); |
7fd59977 |
399 | } |
400 | UpdateCoefficients(); |
401 | } |
402 | |
403 | //======================================================================= |
404 | //function : SetPole |
405 | //purpose : |
406 | //======================================================================= |
407 | |
408 | void Geom_BezierCurve::SetPole (const Standard_Integer Index, |
409 | const gp_Pnt& P) |
410 | { |
411 | if(Index < 1 || Index > NbPoles()) |
412 | Standard_OutOfRange::Raise("Geom_BezierCurve::SetPole"); |
413 | |
414 | TColgp_Array1OfPnt& cpoles = poles->ChangeArray1(); |
415 | cpoles(Index) = P; |
416 | |
417 | if (Index == 1 || Index == cpoles.Length()) { |
418 | closed = (cpoles(1).Distance(cpoles(NbPoles())) <= Precision::Confusion()); |
419 | } |
420 | UpdateCoefficients(); |
421 | } |
422 | |
423 | //======================================================================= |
424 | //function : SetPole |
425 | //purpose : |
426 | //======================================================================= |
427 | |
428 | void Geom_BezierCurve::SetPole(const Standard_Integer Index, |
429 | const gp_Pnt& P, |
430 | const Standard_Real Weight) |
431 | { |
432 | SetPole(Index,P); |
433 | SetWeight(Index,Weight); |
434 | } |
435 | |
436 | //======================================================================= |
437 | //function : SetWeight |
438 | //purpose : |
439 | //======================================================================= |
440 | |
441 | void Geom_BezierCurve::SetWeight(const Standard_Integer Index, |
442 | const Standard_Real Weight) |
443 | { |
444 | Standard_Integer nbpoles = NbPoles(); |
445 | |
446 | if(Index < 1 || Index > nbpoles) |
447 | Standard_OutOfRange::Raise("Geom_BezierCurve::SetWeight"); |
448 | if(Weight <= gp::Resolution ()) |
449 | Standard_ConstructionError::Raise("Geom_BezierCurve::SetWeight"); |
450 | |
451 | // compute new rationality |
452 | Standard_Boolean wasrat = IsRational(); |
453 | if (!wasrat) { |
454 | // a weight of 1. does not turn to rational |
455 | if (Abs(Weight - 1.) <= gp::Resolution()) return; |
456 | |
457 | // set weights of 1. |
458 | weights = new TColStd_HArray1OfReal(1,nbpoles); |
459 | wcoeffs = new TColStd_HArray1OfReal(1,nbpoles); |
460 | weights->Init(1.); |
461 | } |
462 | |
463 | TColStd_Array1OfReal & cweights = weights->ChangeArray1(); |
464 | cweights(Index) = Weight; |
465 | |
466 | // is it turning into non rational |
467 | if (wasrat) { |
468 | if (!Rational(cweights)) { |
469 | weights.Nullify(); |
470 | wcoeffs.Nullify(); |
471 | } |
472 | } |
473 | UpdateCoefficients(); |
474 | } |
475 | |
476 | //======================================================================= |
477 | //function : IsClosed |
478 | //purpose : |
479 | //======================================================================= |
480 | |
481 | Standard_Boolean Geom_BezierCurve::IsClosed () const |
482 | { |
483 | return closed; |
484 | } |
485 | |
486 | //======================================================================= |
487 | //function : IsCN |
488 | //purpose : |
489 | //======================================================================= |
490 | |
491 | Standard_Boolean Geom_BezierCurve::IsCN (const Standard_Integer ) const |
492 | { |
493 | return Standard_True; |
494 | } |
495 | |
496 | //======================================================================= |
497 | //function : IsPeriodic |
498 | //purpose : |
499 | //======================================================================= |
500 | |
501 | Standard_Boolean Geom_BezierCurve::IsPeriodic () const |
502 | { |
503 | return Standard_False; |
504 | } |
505 | |
506 | //======================================================================= |
507 | //function : IsRational |
508 | //purpose : |
509 | //======================================================================= |
510 | |
511 | Standard_Boolean Geom_BezierCurve::IsRational () const |
512 | { |
513 | return !weights.IsNull(); |
514 | } |
515 | |
516 | //======================================================================= |
517 | //function : Continuity |
518 | //purpose : |
519 | //======================================================================= |
520 | |
521 | GeomAbs_Shape Geom_BezierCurve::Continuity () const |
522 | { |
523 | return GeomAbs_CN; |
524 | } |
525 | |
526 | //======================================================================= |
527 | //function : Degree |
528 | //purpose : |
529 | //======================================================================= |
530 | |
531 | Standard_Integer Geom_BezierCurve::Degree () const |
532 | { |
533 | return poles->Length()-1; |
534 | } |
535 | |
536 | //======================================================================= |
537 | //function : D0 |
538 | //purpose : |
539 | //======================================================================= |
540 | |
541 | void Geom_BezierCurve::D0 (const Standard_Real U, gp_Pnt& P ) const |
542 | { |
543 | // Idee lumineuse sacrifiee sur l autel des performances. |
544 | // |
545 | // if(!CoefficientsOK(U)) |
546 | // ((Geom_BezierCurve*)(void*)this)->UpdateCoefficients(U); |
547 | if (IsRational()) |
548 | BSplCLib::CacheD0(U,Degree(),parametercache,spanlenghtcache, |
549 | coeffs->Array1(), |
0e14656b |
550 | &wcoeffs->Array1(), |
7fd59977 |
551 | P); |
552 | else |
553 | BSplCLib::CacheD0(U,Degree(),parametercache,spanlenghtcache, |
0e14656b |
554 | coeffs->Array1(), BSplCLib::NoWeights(), P); |
7fd59977 |
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(), |
0e14656b |
571 | &wcoeffs->Array1(), |
7fd59977 |
572 | P,V1); |
573 | else |
574 | BSplCLib::CacheD1(U,Degree(),parametercache,spanlenghtcache, |
575 | coeffs->Array1(), |
0e14656b |
576 | BSplCLib::NoWeights(), |
7fd59977 |
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(), |
0e14656b |
597 | &wcoeffs->Array1(), |
7fd59977 |
598 | P,V1,V2); |
599 | else |
600 | BSplCLib::CacheD2(U,Degree(),parametercache,spanlenghtcache, |
601 | coeffs->Array1(), |
0e14656b |
602 | BSplCLib::NoWeights(), |
7fd59977 |
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(), |
0e14656b |
622 | &wcoeffs->Array1(), |
7fd59977 |
623 | P,V1,V2,V3); |
624 | else |
625 | BSplCLib::CacheD3(U,Degree(),parametercache,spanlenghtcache, |
626 | coeffs->Array1(), |
0e14656b |
627 | BSplCLib::NoWeights(), |
7fd59977 |
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(), |
0e14656b |
650 | &weights->Array1(), |
651 | bidknots,&bidmults,V); |
7fd59977 |
652 | else |
653 | // BSplCLib::DN(U,N,0,Degree(),0., |
654 | BSplCLib::DN(U,N,0,Degree(),Standard_False, |
655 | poles->Array1(), |
0e14656b |
656 | BSplCLib::NoWeights(), |
657 | bidknots,&bidmults,V); |
7fd59977 |
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(), |
0e14656b |
802 | &weights->Array1(), |
7fd59977 |
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(), |
0e14656b |
900 | &weights->Array1(), |
7fd59977 |
901 | coeffs->ChangeArray1(), |
0e14656b |
902 | &wcoeffs->ChangeArray1()); |
7fd59977 |
903 | else |
904 | BSplCLib::BuildCache(parametercache,spanlenghtcache,0,Degree(), |
905 | bidflatknots,poles->Array1(), |
0e14656b |
906 | BSplCLib::NoWeights(), |
7fd59977 |
907 | coeffs->ChangeArray1(), |
0e14656b |
908 | BSplCLib::NoWeights()); |
7fd59977 |
909 | validcache = 1; |
910 | } |
911 | |