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