1 // File: Geom2d_BSplineCurve_1.cxx
2 // Created: Wed Mar 31 18:11:15 1993
5 // Copyright: Matra Datavision 1993
7 // File: Geom2d_BSplineCurve_1.cxx
8 // Created: Fri Jul 5 16:37:59 1991
10 // 03-02-97 : pmn ->LocateU sur Periodic (PRO6963),
11 // bon appel a LocateParameter (PRO6973) et mise en conformite avec
12 // le cdl de LocateU, lorsque U est un noeud (PRO6988)
14 #define No_Standard_OutOfRange
15 #define No_Standard_DimensionError
17 #include <Geom2d_BSplineCurve.jxx>
18 #include <BSplCLib.hxx>
21 #include <Geom2d_UndefinedDerivative.hxx>
22 #include <Standard_DimensionError.hxx>
23 #include <Standard_OutOfRange.hxx>
24 #include <Standard_DomainError.hxx>
25 #include <Standard_RangeError.hxx>
27 #define POLES (poles->Array1())
28 #define KNOTS (knots->Array1())
29 #define FKNOTS (flatknots->Array1())
30 #define FMULTS (BSplCLib::NoMults())
32 //=======================================================================
35 //=======================================================================
37 Standard_Boolean Geom2d_BSplineCurve::IsCN ( const Standard_Integer N) const
39 Standard_RangeError_Raise_if
40 (N < 0, "Geom2d_BSplineCurve::IsCN");
43 case GeomAbs_CN : return Standard_True;
44 case GeomAbs_C0 : return N <= 0;
45 case GeomAbs_G1 : return N <= 0;
46 case GeomAbs_C1 : return N <= 1;
47 case GeomAbs_G2 : return N <= 1;
48 case GeomAbs_C2 : return N <= 2;
50 return N <= 3 ? Standard_True :
51 N <= deg - BSplCLib::MaxKnotMult (mults->Array1(), mults->Lower() + 1, mults->Upper() - 1);
53 return Standard_False;
57 //=======================================================================
60 //=======================================================================
62 Standard_Boolean Geom2d_BSplineCurve::IsClosed () const
63 { return (StartPoint().Distance (EndPoint())) <= gp::Resolution (); }
67 //=======================================================================
68 //function : IsPeriodic
70 //=======================================================================
72 Standard_Boolean Geom2d_BSplineCurve::IsPeriodic () const
75 //=======================================================================
76 //function : Continuity
78 //=======================================================================
80 GeomAbs_Shape Geom2d_BSplineCurve::Continuity () const
83 //=======================================================================
86 //=======================================================================
88 Standard_Integer Geom2d_BSplineCurve::Degree () const
92 //=======================================================================
95 //=======================================================================
97 void Geom2d_BSplineCurve::D0 ( const Standard_Real U,
100 Standard_Real NewU = U ;
101 PeriodicNormalization(NewU) ;
102 if (!IsCacheValid(NewU)) {
103 Geom2d_BSplineCurve * MyCurve = (Geom2d_BSplineCurve *) this ;
104 MyCurve->ValidateCache(NewU) ;
108 BSplCLib::CacheD0(NewU,
112 (cachepoles->Array1()),
113 cacheweights->Array1(),
117 BSplCLib::CacheD0(NewU,
121 (cachepoles->Array1()),
122 BSplCLib::NoWeights(),
128 //=======================================================================
131 //=======================================================================
133 void Geom2d_BSplineCurve::D1 (const Standard_Real U,
137 Standard_Real NewU = U ;
138 PeriodicNormalization(NewU) ;
139 if (!IsCacheValid(NewU)) {
140 Geom2d_BSplineCurve * MyCurve = (Geom2d_BSplineCurve *) this ;
141 MyCurve->ValidateCache(NewU) ;
145 BSplCLib::CacheD1(NewU,
149 (cachepoles->Array1()),
150 cacheweights->Array1(),
155 BSplCLib::CacheD1(NewU,
159 (cachepoles->Array1()),
160 BSplCLib::NoWeights(),
166 //=======================================================================
169 //=======================================================================
171 void Geom2d_BSplineCurve::D2 (const Standard_Real U ,
176 Standard_Real NewU = U ;
177 PeriodicNormalization(NewU) ;
178 if (!IsCacheValid(NewU)) {
179 Geom2d_BSplineCurve * MyCurve = (Geom2d_BSplineCurve *) this ;
180 MyCurve->ValidateCache(NewU) ;
184 BSplCLib::CacheD2(NewU,
188 (cachepoles->Array1()),
189 cacheweights->Array1(),
195 BSplCLib::CacheD2(NewU,
199 (cachepoles->Array1()),
200 BSplCLib::NoWeights(),
207 //=======================================================================
210 //=======================================================================
212 void Geom2d_BSplineCurve::D3 (const Standard_Real U ,
218 Standard_Real NewU = U ;
219 PeriodicNormalization(NewU) ;
220 if (!IsCacheValid(NewU)) {
221 Geom2d_BSplineCurve * MyCurve = (Geom2d_BSplineCurve *) this ;
222 MyCurve->ValidateCache(NewU) ;
226 BSplCLib::CacheD3(NewU,
230 (cachepoles->Array1()),
231 cacheweights->Array1(),
238 BSplCLib::CacheD3(NewU,
242 (cachepoles->Array1()),
243 BSplCLib::NoWeights(),
251 //=======================================================================
254 //=======================================================================
256 gp_Vec2d Geom2d_BSplineCurve::DN (const Standard_Real U,
257 const Standard_Integer N ) const
262 BSplCLib::DN(U,N,0,deg,periodic,POLES,
267 BSplCLib::DN(U,N,0,deg,periodic,POLES,
268 *((TColStd_Array1OfReal*) NULL),
274 //=======================================================================
275 //function : EndPoint
277 //=======================================================================
279 gp_Pnt2d Geom2d_BSplineCurve::EndPoint () const
281 if (mults->Value (knots->Upper ()) == deg + 1)
282 return poles->Value (poles->Upper());
284 return Value(LastParameter());
287 //=======================================================================
288 //function : FirstUKnotIndex
290 //=======================================================================
292 Standard_Integer Geom2d_BSplineCurve::FirstUKnotIndex () const
294 if (periodic) return 1;
295 else return BSplCLib::FirstUKnotIndex (deg, mults->Array1());
298 //=======================================================================
299 //function : FirstParameter
301 //=======================================================================
303 Standard_Real Geom2d_BSplineCurve::FirstParameter () const
305 return flatknots->Value (deg+1);
308 //=======================================================================
311 //=======================================================================
313 Standard_Real Geom2d_BSplineCurve::Knot (const Standard_Integer Index) const
315 Standard_OutOfRange_Raise_if
316 (Index < 1 || Index > knots->Length(), "Geom2d_BSplineCurve::Knot");
317 return knots->Value (Index);
320 //=======================================================================
321 //function : KnotDistribution
323 //=======================================================================
325 GeomAbs_BSplKnotDistribution Geom2d_BSplineCurve::KnotDistribution () const
330 //=======================================================================
333 //=======================================================================
335 void Geom2d_BSplineCurve::Knots (TColStd_Array1OfReal& K) const
337 Standard_DimensionError_Raise_if
338 (K.Length() != knots->Length(), "Geom2d_BSplineCurve::Knots");
342 //=======================================================================
343 //function : KnotSequence
345 //=======================================================================
347 void Geom2d_BSplineCurve::KnotSequence (TColStd_Array1OfReal& K) const
349 Standard_DimensionError_Raise_if
350 (K.Length() != flatknots->Length(), "Geom2d_BSplineCurve::KnotSequence");
351 K = flatknots->Array1();
354 //=======================================================================
355 //function : LastUKnotIndex
357 //=======================================================================
359 Standard_Integer Geom2d_BSplineCurve::LastUKnotIndex() const
361 if (periodic) return knots->Length();
362 else return BSplCLib::LastUKnotIndex (deg, mults->Array1());
365 //=======================================================================
366 //function : LastParameter
368 //=======================================================================
370 Standard_Real Geom2d_BSplineCurve::LastParameter () const
372 return flatknots->Value (flatknots->Upper()-deg);
375 //=======================================================================
376 //function : LocalValue
378 //=======================================================================
380 gp_Pnt2d Geom2d_BSplineCurve::LocalValue
381 (const Standard_Real U,
382 const Standard_Integer FromK1,
383 const Standard_Integer ToK2) const
386 LocalD0(U,FromK1,ToK2,P);
390 //=======================================================================
393 //=======================================================================
395 void Geom2d_BSplineCurve::LocalD0
396 (const Standard_Real U,
397 const Standard_Integer FromK1,
398 const Standard_Integer ToK2,
401 Standard_DomainError_Raise_if (FromK1 == ToK2,
402 "Geom2d_BSplineCurve::LocalValue");
405 Standard_Integer index = 0;
406 BSplCLib::LocateParameter(deg, FKNOTS, U, periodic,FromK1,ToK2, index,u);
407 index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic);
410 BSplCLib::D0(u,index,deg,periodic,POLES,
415 BSplCLib::D0(u,index,deg,periodic,POLES,
416 *((TColStd_Array1OfReal*) NULL),
421 //=======================================================================
424 //=======================================================================
426 void Geom2d_BSplineCurve::LocalD1 (const Standard_Real U,
427 const Standard_Integer FromK1,
428 const Standard_Integer ToK2,
432 Standard_DomainError_Raise_if (FromK1 == ToK2,
433 "Geom2d_BSplineCurve::LocalD1");
436 Standard_Integer index = 0;
437 BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u);
438 index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic);
441 BSplCLib::D1(u,index,deg,periodic,POLES,
446 BSplCLib::D1(u,index,deg,periodic,POLES,
447 *((TColStd_Array1OfReal*) NULL),
452 //=======================================================================
455 //=======================================================================
457 void Geom2d_BSplineCurve::LocalD2
458 (const Standard_Real U,
459 const Standard_Integer FromK1,
460 const Standard_Integer ToK2,
465 Standard_DomainError_Raise_if (FromK1 == ToK2,
466 "Geom2d_BSplineCurve::LocalD2");
469 Standard_Integer index = 0;
470 BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u);
471 index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic);
474 BSplCLib::D2(u,index,deg,periodic,POLES,
476 FKNOTS,FMULTS,P,V1,V2);
479 BSplCLib::D2(u,index,deg,periodic,POLES,
480 *((TColStd_Array1OfReal*) NULL),
481 FKNOTS,FMULTS,P,V1,V2);
485 //=======================================================================
488 //=======================================================================
490 void Geom2d_BSplineCurve::LocalD3
491 (const Standard_Real U,
492 const Standard_Integer FromK1,
493 const Standard_Integer ToK2,
499 Standard_DomainError_Raise_if (FromK1 == ToK2,
500 "Geom2d_BSplineCurve::LocalD3");
503 Standard_Integer index = 0;
504 BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u);
505 index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic);
508 BSplCLib::D3(u,index,deg,periodic,POLES,
510 FKNOTS,FMULTS,P,V1,V2,V3);
513 BSplCLib::D3(u,index,deg,periodic,POLES,
514 *((TColStd_Array1OfReal*) NULL),
515 FKNOTS,FMULTS,P,V1,V2,V3);
519 //=======================================================================
522 //=======================================================================
524 gp_Vec2d Geom2d_BSplineCurve::LocalDN
525 (const Standard_Real U,
526 const Standard_Integer FromK1,
527 const Standard_Integer ToK2,
528 const Standard_Integer N ) const
530 Standard_DomainError_Raise_if (FromK1 == ToK2,
531 "Geom2d_BSplineCurve::LocalD3");
534 Standard_Integer index = 0;
535 BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u);
536 index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic);
541 BSplCLib::DN(u,N,index,deg,periodic,POLES,
546 BSplCLib::DN(u,N,index,deg,periodic,POLES,
547 *((TColStd_Array1OfReal*) NULL),
553 //=======================================================================
554 //function : Multiplicity
556 //=======================================================================
558 Standard_Integer Geom2d_BSplineCurve::Multiplicity
559 (const Standard_Integer Index) const
561 Standard_OutOfRange_Raise_if (Index < 1 || Index > mults->Length(),
562 "Geom2d_BSplineCurve::Multiplicity");
563 return mults->Value (Index);
566 //=======================================================================
567 //function : Multiplicities
569 //=======================================================================
571 void Geom2d_BSplineCurve::Multiplicities (TColStd_Array1OfInteger& M) const
573 Standard_DimensionError_Raise_if (M.Length() != mults->Length(),
574 "Geom2d_BSplineCurve::Multiplicities");
578 //=======================================================================
581 //=======================================================================
583 Standard_Integer Geom2d_BSplineCurve::NbKnots () const
584 { return knots->Length(); }
586 //=======================================================================
589 //=======================================================================
591 Standard_Integer Geom2d_BSplineCurve::NbPoles () const
592 { return poles->Length(); }
594 //=======================================================================
597 //=======================================================================
599 gp_Pnt2d Geom2d_BSplineCurve::Pole (const Standard_Integer Index) const
601 Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(),
602 "Geom2d_BSplineCurve::Pole");
603 return poles->Value (Index);
606 //=======================================================================
609 //=======================================================================
611 void Geom2d_BSplineCurve::Poles (TColgp_Array1OfPnt2d& P) const
613 Standard_DimensionError_Raise_if (P.Length() != poles->Length(),
614 "Geom2d_BSplineCurve::Poles");
618 //=======================================================================
619 //function : StartPoint
621 //=======================================================================
623 gp_Pnt2d Geom2d_BSplineCurve::StartPoint () const
625 if (mults->Value (1) == deg + 1)
626 return poles->Value (1);
628 return Value(FirstParameter());
631 //=======================================================================
634 //=======================================================================
636 Standard_Real Geom2d_BSplineCurve::Weight
637 (const Standard_Integer Index) const
639 Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(),
640 "Geom2d_BSplineCurve::Weight");
642 return weights->Value (Index);
647 //=======================================================================
650 //=======================================================================
652 void Geom2d_BSplineCurve::Weights
653 (TColStd_Array1OfReal& W) const
655 Standard_DimensionError_Raise_if (W.Length() != poles->Length(),
656 "Geom2d_BSplineCurve::Weights");
658 W = weights->Array1();
661 for (i = W.Lower(); i <= W.Upper(); i++)
666 //=======================================================================
667 //function : IsRational
669 //=======================================================================
671 Standard_Boolean Geom2d_BSplineCurve::IsRational () const
673 return !weights.IsNull();
676 //=======================================================================
677 //function : Transform
679 //=======================================================================
681 void Geom2d_BSplineCurve::Transform
684 TColgp_Array1OfPnt2d & CPoles = poles->ChangeArray1();
685 for (Standard_Integer I = 1; I <= CPoles.Length(); I++)
686 CPoles (I).Transform (T);
689 // maxderivinvok = 0;
692 //=======================================================================
695 //=======================================================================
697 void Geom2d_BSplineCurve::LocateU
698 (const Standard_Real U,
699 const Standard_Real ParametricTolerance,
700 Standard_Integer& I1,
701 Standard_Integer& I2,
702 const Standard_Boolean WithKnotRepetition) const
704 Standard_Real NewU = U;
705 Handle(TColStd_HArray1OfReal) TheKnots;
706 if (WithKnotRepetition) TheKnots = flatknots;
707 else TheKnots = knots;
709 const TColStd_Array1OfReal & CKnots = TheKnots->Array1();
711 PeriodicNormalization(NewU); //Attention a la periode
712 Standard_Real UFirst = CKnots (1);
713 Standard_Real ULast = CKnots (CKnots.Length());
714 if (Abs (NewU - UFirst) <= Abs(ParametricTolerance)) { I1 = I2 = 1; }
715 else if (Abs (U - ULast) <= Abs(ParametricTolerance)) {
716 I1 = I2 = CKnots.Length();
718 else if (NewU < UFirst - Abs(ParametricTolerance)) {
722 else if (NewU > ULast + Abs(ParametricTolerance)) {
723 I1 = CKnots.Length();
728 BSplCLib::Hunt (CKnots, NewU, I1);
729 while ( Abs( CKnots(I1+1) - NewU) <= Abs(ParametricTolerance)) I1++;
730 if ( Abs( CKnots(I1) - NewU) <= Abs(ParametricTolerance)) {
739 //=======================================================================
740 //function : Resolution
742 //=======================================================================
744 void Geom2d_BSplineCurve::Resolution(const Standard_Real ToleranceUV,
745 Standard_Real & UTolerance)
747 Standard_Integer ii ;
750 Standard_Integer NbKnots, NbPoles;
751 BSplCLib::PrepareUnperiodize( deg,
755 TColgp_Array1OfPnt2d new_poles(1,NbPoles) ;
756 TColStd_Array1OfReal new_weights(1,NbPoles) ;
757 for(ii = 1 ; ii <= NbPoles ; ii++) {
758 new_poles(ii) = poles->Array1()(((ii-1) % poles->Length()) + 1) ;
761 for(ii = 1 ; ii <= NbPoles ; ii++) {
762 new_weights(ii) = weights->Array1()(((ii-1) % poles->Length()) + 1) ;
764 BSplCLib::Resolution(new_poles,
773 BSplCLib::Resolution(new_poles,
774 *((TColStd_Array1OfReal*) NULL),
784 BSplCLib::Resolution(poles->Array1(),
793 BSplCLib::Resolution(poles->Array1(),
794 *((TColStd_Array1OfReal*) NULL),
804 UTolerance = ToleranceUV * maxderivinv;