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