b311480e |
1 | // Created on: 1991-07-05 |
2 | // Created by: JCV |
3 | // Copyright (c) 1991-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 | |
42cf5bc1 |
17 | #include <BSplCLib.hxx> |
18 | #include <Geom2d_BSplineCurve.hxx> |
19 | #include <Geom2d_Geometry.hxx> |
7fd59977 |
20 | #include <Geom2d_UndefinedDerivative.hxx> |
42cf5bc1 |
21 | #include <gp.hxx> |
22 | #include <gp_Pnt2d.hxx> |
23 | #include <gp_Trsf2d.hxx> |
24 | #include <gp_Vec2d.hxx> |
25 | #include <Precision.hxx> |
26 | #include <Standard_ConstructionError.hxx> |
7fd59977 |
27 | #include <Standard_DimensionError.hxx> |
7fd59977 |
28 | #include <Standard_DomainError.hxx> |
42cf5bc1 |
29 | #include <Standard_NoSuchObject.hxx> |
30 | #include <Standard_OutOfRange.hxx> |
7fd59977 |
31 | #include <Standard_RangeError.hxx> |
32 | |
33 | #define POLES (poles->Array1()) |
34 | #define KNOTS (knots->Array1()) |
35 | #define FKNOTS (flatknots->Array1()) |
36 | #define FMULTS (BSplCLib::NoMults()) |
37 | |
38 | //======================================================================= |
39 | //function : IsCN |
40 | //purpose : |
41 | //======================================================================= |
42 | |
43 | Standard_Boolean Geom2d_BSplineCurve::IsCN ( const Standard_Integer N) const |
44 | { |
45 | Standard_RangeError_Raise_if |
46 | (N < 0, "Geom2d_BSplineCurve::IsCN"); |
47 | |
48 | switch (smooth) { |
49 | case GeomAbs_CN : return Standard_True; |
50 | case GeomAbs_C0 : return N <= 0; |
51 | case GeomAbs_G1 : return N <= 0; |
52 | case GeomAbs_C1 : return N <= 1; |
53 | case GeomAbs_G2 : return N <= 1; |
54 | case GeomAbs_C2 : return N <= 2; |
55 | case GeomAbs_C3 : |
56 | return N <= 3 ? Standard_True : |
57 | N <= deg - BSplCLib::MaxKnotMult (mults->Array1(), mults->Lower() + 1, mults->Upper() - 1); |
58 | default: |
59 | return Standard_False; |
60 | } |
61 | } |
3d58dc49 |
62 | //======================================================================= |
63 | //function : IsG1 |
64 | //purpose : |
65 | //======================================================================= |
66 | |
67 | Standard_Boolean Geom2d_BSplineCurve::IsG1 ( const Standard_Real theTf, |
68 | const Standard_Real theTl, |
69 | const Standard_Real theAngTol) const |
70 | { |
71 | |
72 | if(IsCN(1)) |
73 | { |
74 | return Standard_True; |
75 | } |
76 | |
77 | Standard_Integer start = FirstUKnotIndex()+1, |
78 | finish = LastUKnotIndex()-1; |
79 | Standard_Integer aDeg = Degree(); |
80 | for(Standard_Integer aNKnot = start; aNKnot <= finish; aNKnot++) |
81 | { |
82 | const Standard_Real aTpar = Knot(aNKnot); |
83 | |
84 | if(aTpar < theTf) |
85 | continue; |
86 | if(aTpar > theTl) |
87 | break; |
88 | |
89 | Standard_Integer mult = Multiplicity(aNKnot); |
90 | if (mult < aDeg) |
91 | continue; |
92 | |
93 | gp_Pnt2d aP1, aP2; |
94 | gp_Vec2d aV1, aV2; |
95 | LocalD1(aTpar, aNKnot-1, aNKnot, aP1, aV1); |
96 | LocalD1(aTpar, aNKnot, aNKnot+1, aP2, aV2); |
97 | |
98 | if((aV1.SquareMagnitude() <= gp::Resolution()) || |
99 | aV2.SquareMagnitude() <= gp::Resolution()) |
100 | { |
101 | return Standard_False; |
102 | } |
103 | |
104 | if(Abs(aV1.Angle(aV2)) > theAngTol) |
105 | return Standard_False; |
106 | } |
107 | |
108 | if(!IsPeriodic()) |
109 | return Standard_True; |
110 | |
111 | const Standard_Real aFirstParam = FirstParameter(), |
112 | aLastParam = LastParameter(); |
113 | |
114 | if( ((aFirstParam - theTf)*(theTl - aFirstParam) < 0.0) && |
115 | ((aLastParam - theTf)*(theTl - aLastParam) < 0.0)) |
116 | { |
117 | //Range [theTf, theTl] does not intersect curve bounadries |
118 | return Standard_True; |
119 | } |
120 | |
121 | //Curve is closed or periodic and range [theTf, theTl] |
122 | //intersect curve boundary. Therefore, it is necessary to |
123 | //check if curve is smooth in its first and last point. |
124 | |
125 | gp_Pnt2d aP; |
126 | gp_Vec2d aV1, aV2; |
127 | D1(Knot(FirstUKnotIndex()), aP, aV1); |
128 | D1(Knot(LastUKnotIndex()), aP, aV2); |
129 | |
130 | if((aV1.SquareMagnitude() <= gp::Resolution()) || |
131 | aV2.SquareMagnitude() <= gp::Resolution()) |
132 | { |
133 | return Standard_False; |
134 | } |
135 | |
136 | if(Abs(aV1.Angle(aV2)) > theAngTol) |
137 | return Standard_False; |
138 | |
139 | |
140 | return Standard_True; |
141 | |
142 | } |
7fd59977 |
143 | |
144 | //======================================================================= |
145 | //function : IsClosed |
146 | //purpose : |
147 | //======================================================================= |
148 | |
149 | Standard_Boolean Geom2d_BSplineCurve::IsClosed () const |
150 | { return (StartPoint().Distance (EndPoint())) <= gp::Resolution (); } |
151 | |
152 | |
153 | |
154 | //======================================================================= |
155 | //function : IsPeriodic |
156 | //purpose : |
157 | //======================================================================= |
158 | |
159 | Standard_Boolean Geom2d_BSplineCurve::IsPeriodic () const |
160 | { return periodic; } |
161 | |
162 | //======================================================================= |
163 | //function : Continuity |
164 | //purpose : |
165 | //======================================================================= |
166 | |
167 | GeomAbs_Shape Geom2d_BSplineCurve::Continuity () const |
168 | { return smooth; } |
169 | |
170 | //======================================================================= |
171 | //function : Degree |
172 | //purpose : |
173 | //======================================================================= |
174 | |
175 | Standard_Integer Geom2d_BSplineCurve::Degree () const |
176 | { return deg; } |
177 | |
178 | |
179 | //======================================================================= |
180 | //function : D0 |
181 | //purpose : |
182 | //======================================================================= |
183 | |
94f71cad |
184 | void Geom2d_BSplineCurve::D0(const Standard_Real U, |
185 | gp_Pnt2d& P) const |
7fd59977 |
186 | { |
94f71cad |
187 | Standard_Integer aSpanIndex = 0; |
188 | Standard_Real aNewU(U); |
189 | PeriodicNormalization(aNewU); |
0e14656b |
190 | BSplCLib::LocateParameter(deg, knots->Array1(), &mults->Array1(), U, periodic, aSpanIndex, aNewU); |
94f71cad |
191 | if (aNewU < knots->Value(aSpanIndex)) |
192 | aSpanIndex--; |
aff73fd5 |
193 | |
194 | BSplCLib::D0 (aNewU, aSpanIndex, deg, periodic, POLES, |
195 | rational ? &weights->Array1() : BSplCLib::NoWeights(), |
196 | knots->Array1(), &mults->Array1(), |
197 | P); |
7fd59977 |
198 | } |
199 | |
200 | |
201 | //======================================================================= |
202 | //function : D1 |
203 | //purpose : |
204 | //======================================================================= |
205 | |
94f71cad |
206 | void Geom2d_BSplineCurve::D1(const Standard_Real U, |
207 | gp_Pnt2d& P, |
208 | gp_Vec2d& V1) const |
7fd59977 |
209 | { |
94f71cad |
210 | Standard_Integer aSpanIndex = 0; |
211 | Standard_Real aNewU(U); |
212 | PeriodicNormalization(aNewU); |
0e14656b |
213 | BSplCLib::LocateParameter(deg, knots->Array1(), &mults->Array1(), U, periodic, aSpanIndex, aNewU); |
94f71cad |
214 | if (aNewU < knots->Value(aSpanIndex)) |
215 | aSpanIndex--; |
aff73fd5 |
216 | |
217 | BSplCLib::D1 (aNewU, aSpanIndex, deg, periodic, POLES, |
218 | rational ? &weights->Array1() : BSplCLib::NoWeights(), |
219 | knots->Array1(), &mults->Array1(), |
220 | P, V1); |
7fd59977 |
221 | } |
222 | |
223 | //======================================================================= |
224 | //function : D2 |
225 | //purpose : |
226 | //======================================================================= |
227 | |
94f71cad |
228 | void Geom2d_BSplineCurve::D2(const Standard_Real U, |
229 | gp_Pnt2d& P, |
230 | gp_Vec2d& V1, |
231 | gp_Vec2d& V2) const |
7fd59977 |
232 | { |
94f71cad |
233 | Standard_Integer aSpanIndex = 0; |
234 | Standard_Real aNewU(U); |
235 | PeriodicNormalization(aNewU); |
0e14656b |
236 | BSplCLib::LocateParameter(deg, knots->Array1(), &mults->Array1(), U, periodic, aSpanIndex, aNewU); |
94f71cad |
237 | if (aNewU < knots->Value(aSpanIndex)) |
238 | aSpanIndex--; |
aff73fd5 |
239 | |
240 | BSplCLib::D2 (aNewU, aSpanIndex, deg, periodic, POLES, |
241 | rational ? &weights->Array1() : BSplCLib::NoWeights(), |
242 | knots->Array1(), &mults->Array1(), |
243 | P, V1, V2); |
7fd59977 |
244 | } |
245 | |
246 | //======================================================================= |
247 | //function : D3 |
248 | //purpose : |
249 | //======================================================================= |
250 | |
94f71cad |
251 | void Geom2d_BSplineCurve::D3(const Standard_Real U, |
252 | gp_Pnt2d& P, |
253 | gp_Vec2d& V1, |
254 | gp_Vec2d& V2, |
255 | gp_Vec2d& V3) const |
7fd59977 |
256 | { |
94f71cad |
257 | Standard_Integer aSpanIndex = 0; |
258 | Standard_Real aNewU(U); |
259 | PeriodicNormalization(aNewU); |
0e14656b |
260 | BSplCLib::LocateParameter(deg, knots->Array1(), &mults->Array1(), U, periodic, aSpanIndex, aNewU); |
94f71cad |
261 | if (aNewU < knots->Value(aSpanIndex)) |
262 | aSpanIndex--; |
aff73fd5 |
263 | |
264 | BSplCLib::D3 (aNewU, aSpanIndex, deg, periodic, POLES, |
265 | rational ? &weights->Array1() : BSplCLib::NoWeights(), |
266 | knots->Array1(), &mults->Array1(), |
267 | P, V1, V2, V3); |
7fd59977 |
268 | } |
269 | |
270 | //======================================================================= |
271 | //function : DN |
272 | //purpose : |
273 | //======================================================================= |
274 | |
94f71cad |
275 | gp_Vec2d Geom2d_BSplineCurve::DN(const Standard_Real U, |
276 | const Standard_Integer N) const |
7fd59977 |
277 | { |
278 | gp_Vec2d V; |
aff73fd5 |
279 | BSplCLib::DN (U, N, 0, deg, periodic, POLES, |
280 | rational ? &weights->Array1() : BSplCLib::NoWeights(), |
281 | FKNOTS, FMULTS, V); |
7fd59977 |
282 | return V; |
283 | } |
284 | |
285 | //======================================================================= |
286 | //function : EndPoint |
287 | //purpose : |
288 | //======================================================================= |
289 | |
290 | gp_Pnt2d Geom2d_BSplineCurve::EndPoint () const |
291 | { |
292 | if (mults->Value (knots->Upper ()) == deg + 1) |
293 | return poles->Value (poles->Upper()); |
294 | else |
295 | return Value(LastParameter()); |
296 | } |
297 | |
298 | //======================================================================= |
299 | //function : FirstUKnotIndex |
300 | //purpose : |
301 | //======================================================================= |
302 | |
303 | Standard_Integer Geom2d_BSplineCurve::FirstUKnotIndex () const |
304 | { |
305 | if (periodic) return 1; |
306 | else return BSplCLib::FirstUKnotIndex (deg, mults->Array1()); |
307 | } |
308 | |
309 | //======================================================================= |
310 | //function : FirstParameter |
311 | //purpose : |
312 | //======================================================================= |
313 | |
314 | Standard_Real Geom2d_BSplineCurve::FirstParameter () const |
315 | { |
316 | return flatknots->Value (deg+1); |
317 | } |
318 | |
319 | //======================================================================= |
320 | //function : Knot |
321 | //purpose : |
322 | //======================================================================= |
323 | |
324 | Standard_Real Geom2d_BSplineCurve::Knot (const Standard_Integer Index) const |
325 | { |
326 | Standard_OutOfRange_Raise_if |
327 | (Index < 1 || Index > knots->Length(), "Geom2d_BSplineCurve::Knot"); |
328 | return knots->Value (Index); |
329 | } |
330 | |
331 | //======================================================================= |
332 | //function : KnotDistribution |
333 | //purpose : |
334 | //======================================================================= |
335 | |
336 | GeomAbs_BSplKnotDistribution Geom2d_BSplineCurve::KnotDistribution () const |
337 | { |
338 | return knotSet; |
339 | } |
340 | |
341 | //======================================================================= |
342 | //function : Knots |
343 | //purpose : |
344 | //======================================================================= |
345 | |
346 | void Geom2d_BSplineCurve::Knots (TColStd_Array1OfReal& K) const |
347 | { |
738d336b |
348 | Standard_DomainError_Raise_if (K.Lower() < knots->Lower() || |
349 | K.Upper() > knots->Upper(), |
350 | "Geom2d_BSplineCurve::Knots"); |
351 | for(Standard_Integer anIdx = K.Lower(); anIdx <= K.Upper(); anIdx++) |
352 | K(anIdx) = knots->Value(anIdx); |
7fd59977 |
353 | } |
354 | |
94f71cad |
355 | const TColStd_Array1OfReal& Geom2d_BSplineCurve::Knots() const |
356 | { |
357 | return knots->Array1(); |
358 | } |
359 | |
7fd59977 |
360 | //======================================================================= |
361 | //function : KnotSequence |
362 | //purpose : |
363 | //======================================================================= |
364 | |
365 | void Geom2d_BSplineCurve::KnotSequence (TColStd_Array1OfReal& K) const |
366 | { |
738d336b |
367 | Standard_DomainError_Raise_if (K.Lower() < flatknots->Lower() || |
368 | K.Upper() > flatknots->Upper(), |
369 | "Geom2d_BSplineCurve::KnotSequence"); |
370 | for(Standard_Integer anIdx = K.Lower(); anIdx <= K.Upper(); anIdx++) |
371 | K(anIdx) = flatknots->Value(anIdx); |
7fd59977 |
372 | } |
373 | |
94f71cad |
374 | const TColStd_Array1OfReal& Geom2d_BSplineCurve::KnotSequence() const |
375 | { |
376 | return flatknots->Array1(); |
377 | } |
378 | |
7fd59977 |
379 | //======================================================================= |
380 | //function : LastUKnotIndex |
381 | //purpose : |
382 | //======================================================================= |
383 | |
384 | Standard_Integer Geom2d_BSplineCurve::LastUKnotIndex() const |
385 | { |
386 | if (periodic) return knots->Length(); |
387 | else return BSplCLib::LastUKnotIndex (deg, mults->Array1()); |
388 | } |
389 | |
390 | //======================================================================= |
391 | //function : LastParameter |
392 | //purpose : |
393 | //======================================================================= |
394 | |
395 | Standard_Real Geom2d_BSplineCurve::LastParameter () const |
396 | { |
397 | return flatknots->Value (flatknots->Upper()-deg); |
398 | } |
399 | |
400 | //======================================================================= |
401 | //function : LocalValue |
402 | //purpose : |
403 | //======================================================================= |
404 | |
405 | gp_Pnt2d Geom2d_BSplineCurve::LocalValue |
406 | (const Standard_Real U, |
407 | const Standard_Integer FromK1, |
408 | const Standard_Integer ToK2) const |
409 | { |
410 | gp_Pnt2d P; |
411 | LocalD0(U,FromK1,ToK2,P); |
412 | return P; |
413 | } |
414 | |
415 | //======================================================================= |
416 | //function : LocalD0 |
417 | //purpose : |
418 | //======================================================================= |
419 | |
420 | void Geom2d_BSplineCurve::LocalD0 |
421 | (const Standard_Real U, |
422 | const Standard_Integer FromK1, |
423 | const Standard_Integer ToK2, |
424 | gp_Pnt2d& P) const |
425 | { |
426 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
427 | "Geom2d_BSplineCurve::LocalValue"); |
428 | |
429 | Standard_Real u = U; |
430 | Standard_Integer index = 0; |
431 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic,FromK1,ToK2, index,u); |
432 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
433 | |
aff73fd5 |
434 | BSplCLib::D0 (u, index, deg, periodic, POLES, |
435 | rational ? &weights->Array1() : BSplCLib::NoWeights(), |
436 | FKNOTS, FMULTS, P); |
7fd59977 |
437 | } |
438 | |
439 | //======================================================================= |
440 | //function : LocalD1 |
441 | //purpose : |
442 | //======================================================================= |
443 | |
444 | void Geom2d_BSplineCurve::LocalD1 (const Standard_Real U, |
445 | const Standard_Integer FromK1, |
446 | const Standard_Integer ToK2, |
447 | gp_Pnt2d& P, |
448 | gp_Vec2d& V1) const |
449 | { |
450 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
451 | "Geom2d_BSplineCurve::LocalD1"); |
452 | |
453 | Standard_Real u = U; |
454 | Standard_Integer index = 0; |
455 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u); |
456 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
457 | |
aff73fd5 |
458 | BSplCLib::D1 (u, index, deg, periodic, POLES, |
459 | rational ? &weights->Array1() : BSplCLib::NoWeights(), |
460 | FKNOTS, FMULTS, P, V1); |
7fd59977 |
461 | } |
462 | |
463 | //======================================================================= |
464 | //function : LocalD2 |
465 | //purpose : |
466 | //======================================================================= |
467 | |
468 | void Geom2d_BSplineCurve::LocalD2 |
469 | (const Standard_Real U, |
470 | const Standard_Integer FromK1, |
471 | const Standard_Integer ToK2, |
472 | gp_Pnt2d& P, |
473 | gp_Vec2d& V1, |
474 | gp_Vec2d& V2) const |
475 | { |
476 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
477 | "Geom2d_BSplineCurve::LocalD2"); |
478 | |
479 | Standard_Real u = U; |
480 | Standard_Integer index = 0; |
481 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u); |
482 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
483 | |
aff73fd5 |
484 | BSplCLib::D2 (u, index, deg, periodic, POLES, |
485 | rational ? &weights->Array1() : BSplCLib::NoWeights(), |
486 | FKNOTS, FMULTS, P, V1, V2); |
7fd59977 |
487 | } |
488 | |
489 | //======================================================================= |
490 | //function : LocalD3 |
491 | //purpose : |
492 | //======================================================================= |
493 | |
494 | void Geom2d_BSplineCurve::LocalD3 |
495 | (const Standard_Real U, |
496 | const Standard_Integer FromK1, |
497 | const Standard_Integer ToK2, |
498 | gp_Pnt2d& P, |
499 | gp_Vec2d& V1, |
500 | gp_Vec2d& V2, |
501 | gp_Vec2d& V3) const |
502 | { |
503 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
504 | "Geom2d_BSplineCurve::LocalD3"); |
505 | |
506 | Standard_Real u = U; |
507 | Standard_Integer index = 0; |
508 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u); |
509 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
510 | |
aff73fd5 |
511 | BSplCLib::D3 (u, index, deg, periodic, POLES, |
512 | rational ? &weights->Array1() : BSplCLib::NoWeights(), |
513 | FKNOTS, FMULTS, P, V1, V2, V3); |
7fd59977 |
514 | } |
515 | |
516 | //======================================================================= |
517 | //function : LocalDN |
518 | //purpose : |
519 | //======================================================================= |
520 | |
521 | gp_Vec2d Geom2d_BSplineCurve::LocalDN |
522 | (const Standard_Real U, |
523 | const Standard_Integer FromK1, |
524 | const Standard_Integer ToK2, |
525 | const Standard_Integer N ) const |
526 | { |
527 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
528 | "Geom2d_BSplineCurve::LocalD3"); |
529 | |
530 | Standard_Real u = U; |
531 | Standard_Integer index = 0; |
532 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u); |
533 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
534 | |
535 | gp_Vec2d V; |
aff73fd5 |
536 | BSplCLib::DN (u, N, index, deg, periodic, POLES, |
537 | rational ? &weights->Array1() : BSplCLib::NoWeights(), |
538 | FKNOTS, FMULTS, V); |
7fd59977 |
539 | return V; |
540 | } |
541 | |
542 | //======================================================================= |
543 | //function : Multiplicity |
544 | //purpose : |
545 | //======================================================================= |
546 | |
547 | Standard_Integer Geom2d_BSplineCurve::Multiplicity |
548 | (const Standard_Integer Index) const |
549 | { |
550 | Standard_OutOfRange_Raise_if (Index < 1 || Index > mults->Length(), |
551 | "Geom2d_BSplineCurve::Multiplicity"); |
552 | return mults->Value (Index); |
553 | } |
554 | |
555 | //======================================================================= |
556 | //function : Multiplicities |
557 | //purpose : |
558 | //======================================================================= |
559 | |
560 | void Geom2d_BSplineCurve::Multiplicities (TColStd_Array1OfInteger& M) const |
561 | { |
562 | Standard_DimensionError_Raise_if (M.Length() != mults->Length(), |
563 | "Geom2d_BSplineCurve::Multiplicities"); |
564 | M = mults->Array1(); |
565 | } |
566 | |
94f71cad |
567 | const TColStd_Array1OfInteger& Geom2d_BSplineCurve::Multiplicities() const |
568 | { |
569 | return mults->Array1(); |
570 | } |
571 | |
7fd59977 |
572 | //======================================================================= |
573 | //function : NbKnots |
574 | //purpose : |
575 | //======================================================================= |
576 | |
577 | Standard_Integer Geom2d_BSplineCurve::NbKnots () const |
578 | { return knots->Length(); } |
579 | |
580 | //======================================================================= |
581 | //function : NbPoles |
582 | //purpose : |
583 | //======================================================================= |
584 | |
585 | Standard_Integer Geom2d_BSplineCurve::NbPoles () const |
586 | { return poles->Length(); } |
587 | |
588 | //======================================================================= |
589 | //function : Pole |
590 | //purpose : |
591 | //======================================================================= |
592 | |
81093856 |
593 | const gp_Pnt2d& Geom2d_BSplineCurve::Pole (const Standard_Integer Index) const |
7fd59977 |
594 | { |
595 | Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(), |
596 | "Geom2d_BSplineCurve::Pole"); |
597 | return poles->Value (Index); |
598 | } |
599 | |
600 | //======================================================================= |
601 | //function : Poles |
602 | //purpose : |
603 | //======================================================================= |
604 | |
605 | void Geom2d_BSplineCurve::Poles (TColgp_Array1OfPnt2d& P) const |
606 | { |
607 | Standard_DimensionError_Raise_if (P.Length() != poles->Length(), |
608 | "Geom2d_BSplineCurve::Poles"); |
609 | P = poles->Array1(); |
610 | } |
611 | |
94f71cad |
612 | const TColgp_Array1OfPnt2d& Geom2d_BSplineCurve::Poles() const |
613 | { |
614 | return poles->Array1(); |
615 | } |
616 | |
7fd59977 |
617 | //======================================================================= |
618 | //function : StartPoint |
619 | //purpose : |
620 | //======================================================================= |
621 | |
622 | gp_Pnt2d Geom2d_BSplineCurve::StartPoint () const |
623 | { |
624 | if (mults->Value (1) == deg + 1) |
625 | return poles->Value (1); |
626 | else |
627 | return Value(FirstParameter()); |
628 | } |
629 | |
630 | //======================================================================= |
631 | //function : Weight |
632 | //purpose : |
633 | //======================================================================= |
634 | |
635 | Standard_Real Geom2d_BSplineCurve::Weight |
636 | (const Standard_Integer Index) const |
637 | { |
638 | Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(), |
639 | "Geom2d_BSplineCurve::Weight"); |
640 | if (IsRational()) |
641 | return weights->Value (Index); |
642 | else |
643 | return 1.; |
644 | } |
645 | |
646 | //======================================================================= |
647 | //function : Weights |
648 | //purpose : |
649 | //======================================================================= |
650 | |
651 | void Geom2d_BSplineCurve::Weights |
652 | (TColStd_Array1OfReal& W) const |
653 | { |
654 | Standard_DimensionError_Raise_if (W.Length() != poles->Length(), |
655 | "Geom2d_BSplineCurve::Weights"); |
656 | if (IsRational()) |
657 | W = weights->Array1(); |
658 | else { |
659 | Standard_Integer i; |
660 | for (i = W.Lower(); i <= W.Upper(); i++) |
661 | W(i) = 1.; |
662 | } |
663 | } |
664 | |
0e14656b |
665 | const TColStd_Array1OfReal* Geom2d_BSplineCurve::Weights() const |
94f71cad |
666 | { |
667 | if (IsRational()) |
0e14656b |
668 | return &weights->Array1(); |
94f71cad |
669 | return BSplCLib::NoWeights(); |
670 | } |
671 | |
7fd59977 |
672 | //======================================================================= |
673 | //function : IsRational |
674 | //purpose : |
675 | //======================================================================= |
676 | |
677 | Standard_Boolean Geom2d_BSplineCurve::IsRational () const |
678 | { |
679 | return !weights.IsNull(); |
680 | } |
681 | |
682 | //======================================================================= |
683 | //function : Transform |
684 | //purpose : |
685 | //======================================================================= |
686 | |
687 | void Geom2d_BSplineCurve::Transform |
688 | (const gp_Trsf2d& T) |
689 | { |
690 | TColgp_Array1OfPnt2d & CPoles = poles->ChangeArray1(); |
691 | for (Standard_Integer I = 1; I <= CPoles.Length(); I++) |
692 | CPoles (I).Transform (T); |
693 | |
7fd59977 |
694 | // maxderivinvok = 0; |
695 | } |
696 | |
697 | //======================================================================= |
698 | //function : LocateU |
699 | //purpose : |
700 | //======================================================================= |
701 | |
702 | void Geom2d_BSplineCurve::LocateU |
703 | (const Standard_Real U, |
704 | const Standard_Real ParametricTolerance, |
705 | Standard_Integer& I1, |
706 | Standard_Integer& I2, |
707 | const Standard_Boolean WithKnotRepetition) const |
708 | { |
709 | Standard_Real NewU = U; |
710 | Handle(TColStd_HArray1OfReal) TheKnots; |
711 | if (WithKnotRepetition) TheKnots = flatknots; |
712 | else TheKnots = knots; |
713 | |
714 | const TColStd_Array1OfReal & CKnots = TheKnots->Array1(); |
715 | |
716 | PeriodicNormalization(NewU); //Attention a la periode |
717 | Standard_Real UFirst = CKnots (1); |
718 | Standard_Real ULast = CKnots (CKnots.Length()); |
41c52af3 |
719 | Standard_Real PParametricTolerance = Abs(ParametricTolerance); |
720 | if (Abs (NewU - UFirst) <= PParametricTolerance) { I1 = I2 = 1; } |
721 | else if (Abs (NewU - ULast) <= PParametricTolerance) { |
7fd59977 |
722 | I1 = I2 = CKnots.Length(); |
723 | } |
41c52af3 |
724 | else if (NewU < UFirst) { |
7fd59977 |
725 | I2 = 1; |
726 | I1 = 0; |
727 | } |
41c52af3 |
728 | else if (NewU > ULast) { |
7fd59977 |
729 | I1 = CKnots.Length(); |
730 | I2 = I1 + 1; |
731 | } |
732 | else { |
733 | I1 = 1; |
734 | BSplCLib::Hunt (CKnots, NewU, I1); |
437ef771 |
735 | I1 = Max (Min (I1, CKnots.Upper()), CKnots.Lower()); |
736 | while (I1 + 1 <= CKnots.Upper() |
737 | && Abs (CKnots (I1 + 1) - NewU) <= PParametricTolerance) |
738 | { |
739 | I1++; |
740 | } |
41c52af3 |
741 | if ( Abs( CKnots(I1) - NewU) <= PParametricTolerance) { |
7fd59977 |
742 | I2 = I1; |
743 | } |
744 | else { |
745 | I2 = I1 + 1; |
746 | } |
747 | } |
748 | } |
749 | |
750 | //======================================================================= |
751 | //function : Resolution |
752 | //purpose : |
753 | //======================================================================= |
754 | |
aff73fd5 |
755 | void Geom2d_BSplineCurve::Resolution (const Standard_Real ToleranceUV, |
756 | Standard_Real& UTolerance) |
7fd59977 |
757 | { |
aff73fd5 |
758 | if (!maxderivinvok) |
759 | { |
760 | if (periodic) |
761 | { |
7fd59977 |
762 | Standard_Integer NbKnots, NbPoles; |
aff73fd5 |
763 | BSplCLib::PrepareUnperiodize (deg, mults->Array1(), NbKnots, NbPoles); |
764 | TColgp_Array1OfPnt2d new_poles (1, NbPoles); |
765 | TColStd_Array1OfReal new_weights (1, NbPoles); |
766 | for (Standard_Integer ii = 1; ii <= NbPoles ; ii++) |
767 | { |
768 | new_poles (ii) = poles->Array1()(((ii-1) % poles->Length()) + 1); |
7fd59977 |
769 | } |
aff73fd5 |
770 | if (rational) |
771 | { |
772 | for (Standard_Integer ii = 1; ii <= NbPoles; ii++) |
773 | { |
774 | new_weights (ii) = weights->Array1()(((ii-1) % poles->Length()) + 1); |
775 | } |
7fd59977 |
776 | } |
aff73fd5 |
777 | BSplCLib::Resolution (new_poles, |
778 | rational ? &new_weights : BSplCLib::NoWeights(), |
779 | new_poles.Length(), |
780 | flatknots->Array1(), |
781 | deg, |
782 | 1., |
783 | maxderivinv); |
7fd59977 |
784 | } |
aff73fd5 |
785 | else |
786 | { |
787 | BSplCLib::Resolution (poles->Array1(), |
788 | rational ? &weights->Array1() : BSplCLib::NoWeights(), |
789 | poles->Length(), |
790 | flatknots->Array1(), |
791 | deg, |
792 | 1., |
793 | maxderivinv); |
7fd59977 |
794 | } |
795 | maxderivinvok = 1; |
796 | } |
797 | UTolerance = ToleranceUV * maxderivinv; |
798 | } |
799 | |