0026310: Very slow boolean cut operations on cylinders
[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
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
51Standard_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
75Standard_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
154Standard_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
163Standard_Boolean Geom_BSplineCurve::IsPeriodic () const
164{ return periodic; }
165
166//=======================================================================
167//function : Continuity
168//purpose :
169//=======================================================================
170
171GeomAbs_Shape Geom_BSplineCurve::Continuity () const
172{ return smooth; }
173
174//=======================================================================
175//function : Degree
176//purpose :
177//=======================================================================
178
179Standard_Integer Geom_BSplineCurve::Degree () const
180{ return deg; }
181
182//=======================================================================
183//function : D0
184//purpose :
185//=======================================================================
186
83ada95b 187void 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
216void 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 247void 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 279void 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 312gp_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
334gp_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
347Standard_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
358Standard_Real Geom_BSplineCurve::FirstParameter () const
359{
360 return flatknots->Value (deg+1);
361}
362
363//=======================================================================
364//function : Knot
365//purpose :
366//=======================================================================
367
368Standard_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
380GeomAbs_BSplKnotDistribution Geom_BSplineCurve::KnotDistribution () const
381{
382 return knotSet;
383}
384
385//=======================================================================
386//function : Knots
387//purpose :
388//=======================================================================
389
390void 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 397const TColStd_Array1OfReal& Geom_BSplineCurve::Knots() const
398{
399 return knots->Array1();
400}
401
7fd59977 402//=======================================================================
403//function : KnotSequence
404//purpose :
405//=======================================================================
406
407void 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 414const TColStd_Array1OfReal& Geom_BSplineCurve::KnotSequence() const
415{
416 return flatknots->Array1();
417}
418
7fd59977 419//=======================================================================
420//function : LastUKnotIndex
421//purpose :
422//=======================================================================
423
424Standard_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
435Standard_Real Geom_BSplineCurve::LastParameter () const
436{
437 return flatknots->Value (flatknots->Upper()-deg);
438}
439
440//=======================================================================
441//function : LocalValue
442//purpose :
443//=======================================================================
444
445gp_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
460void 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
490void 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
520void 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
552void 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
585gp_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
618Standard_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
631void 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 638const TColStd_Array1OfInteger& Geom_BSplineCurve::Multiplicities() const
639{
640 return mults->Array1();
641}
642
7fd59977 643//=======================================================================
644//function : NbKnots
645//purpose :
646//=======================================================================
647
648Standard_Integer Geom_BSplineCurve::NbKnots () const
649{ return knots->Length(); }
650
651//=======================================================================
652//function : NbPoles
653//purpose :
654//=======================================================================
655
656Standard_Integer Geom_BSplineCurve::NbPoles () const
657{ return poles->Length(); }
658
659//=======================================================================
660//function : Pole
661//purpose :
662//=======================================================================
663
664gp_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
676void 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 683const TColgp_Array1OfPnt& Geom_BSplineCurve::Poles() const
684{
685 return poles->Array1();
686}
687
7fd59977 688//=======================================================================
689//function : StartPoint
690//purpose :
691//=======================================================================
692
693gp_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
706Standard_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
722void 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 737const 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
749Standard_Boolean Geom_BSplineCurve::IsRational () const
750{
751 return !weights.IsNull();
752}
753
754//=======================================================================
755//function : Transform
756//purpose :
757//=======================================================================
758
759void 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
775void 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
823void 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
892Standard_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}