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