//======================================================================= //function : LocalValue //purpose : //======================================================================= gp_Pnt Geom_BSplineCurve::LocalValue (const Standard_Real U, const Standard_Integer FromK1, const Standard_Integer ToK2) const { gp_Pnt P; LocalD0(U,FromK1,ToK2,P); return P; } //======================================================================= //function : LocalD0 //purpose : //======================================================================= void Geom_BSplineCurve::LocalD0 (const Standard_Real U, const Standard_Integer FromK1, const Standard_Integer ToK2, gp_Pnt& P) const { Standard_DomainError_Raise_if (FromK1 == ToK2, "Geom_BSplineCurve::LocalValue"); Standard_Real u = U; Standard_Integer index = 0; BSplCLib::LocateParameter(deg, FKNOTS, U, periodic,FromK1,ToK2, index,u); index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); if (rational) { BSplCLib::D0(u,index,deg,periodic,POLES, weights->Array1(), FKNOTS,FMULTS,P); } else { BSplCLib::D0(u,index,deg,periodic,POLES, *((TColStd_Array1OfReal*) NULL), FKNOTS,FMULTS,P); } }
//======================================================================= //function : LocateParameter //purpose : Pour des noeuds plats // pmn 28-01-97 -> On a bel est bien besoin du degree pour calculer // la periode eventuelle //======================================================================= void BSplCLib::LocateParameter (const Standard_Integer Degree, const Array1OfReal& Knots, const Standard_Real U, const Standard_Boolean IsPeriodic, const Standard_Integer FromK1, const Standard_Integer ToK2, Standard_Integer& KnotIndex, Standard_Real& NewU) { if (IsPeriodic) BSplCLib::LocateParameter(Knots, U, IsPeriodic, FromK1, ToK2, KnotIndex, NewU, Knots(Knots.Lower() + Degree), Knots(Knots.Upper() - Degree)); else BSplCLib::LocateParameter(Knots, U, IsPeriodic, FromK1, ToK2, KnotIndex, NewU, 0., 1.); }
//======================================================================= //function : LocateParameter //purpose : Claculs effectifs // pmn 28-01-97 : Ajoute les bornes de la periode en argument d'entree, car il est // car il est imposible de les inventer a ce niveaux. //======================================================================= void BSplCLib::LocateParameter (const TColStd_Array1OfReal& Knots, const Standard_Real U, const Standard_Boolean IsPeriodic, const Standard_Integer FromK1, const Standard_Integer ToK2, Standard_Integer& KnotIndex, Standard_Real& NewU, const Standard_Real UFirst, const Standard_Real ULast) { Standard_Integer First,Last; if (FromK1 < ToK2) { First = FromK1; Last = ToK2; } else { First = ToK2; Last = FromK1; } Standard_Integer Last1 = Last - 1; NewU = U; if (IsPeriodic) { Standard_Real Period = ULast - UFirst; while (NewU > ULast ) NewU -= Period; while (NewU < UFirst) NewU += Period; } BSplCLib::Hunt (Knots, NewU, KnotIndex); Standard_Real Eps = Epsilon(U); Standard_Real val; if (Eps < 0) Eps = - Eps; Standard_Integer KLower = Knots.Lower(); const Standard_Real *knots = &Knots(KLower); knots -= KLower; if ( KnotIndex < Knots.Upper()) { val = NewU - knots[KnotIndex + 1]; if (val < 0) val = - val; // <= pour etre coherant avec les Segment ou Eps correspond a un bit d'erreur. if (val <= Eps) KnotIndex++; } if (KnotIndex < First) KnotIndex = First; if (KnotIndex > Last1) KnotIndex = Last1; if (KnotIndex != Last1) { Standard_Real K1 = knots[KnotIndex]; Standard_Real K2 = knots[KnotIndex + 1]; val = K2 - K1; if (val < 0) val = - val; while (val <= Eps) { KnotIndex++; K1 = K2; K2 = knots[KnotIndex + 1]; val = K2 - K1; if (val < 0) val = - val; } } }
//======================================================================= //function : Hunt //purpose : //======================================================================= void BSplCLib::Hunt (const Array1OfReal& XX, const Standard_Real X, Standard_Integer& Ilc) { // replaced by simple dichotomy (RLE) Ilc = XX.Lower(); const Standard_Real *px = &XX(Ilc); px -= Ilc; if (X < px[Ilc]) { Ilc--; return; } Standard_Integer Ihi = XX.Upper(); if (X > px[Ihi]) { Ilc = Ihi + 1; return; } Standard_Integer Im; while (Ihi - Ilc != 1) { Im = (Ihi + Ilc) >> 1; if (X > px[Im]) Ilc = Im; else Ihi = Im; } }