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