52 #define BSPLINECURVE_BSPLINECURVET_C 56 #include <OpenMesh/Core/Geometry/VectorT.hh> 64 #include <ACG/Geometry/Algorithms.hh> 65 #include <ACG/Math/BSplineBasis.hh> 74 template <
class Po
intT>
78 autocompute_knotvector_(true),
79 fix_number_control_points_(false),
80 ref_count_cpselections_(0),
81 ref_count_eselections_(0)
87 template <
class Po
intT>
92 control_polygon_ = _curve.control_polygon_;
95 knotvector_ = _curve.knotvector_;
97 degree_ = _curve.degree_;
98 autocompute_knotvector_ = _curve.autocompute_knotvector_;
99 fix_number_control_points_ = _curve.fix_number_control_points_;
102 cpselections_ = _curve.cpselections_;
103 eselections_ = _curve.eselections_;
106 ref_count_cpselections_ = _curve.ref_count_cpselections_;
107 ref_count_eselections_ = _curve.ref_count_eselections_;
113 template <
class Po
intT>
114 template <
class PropT>
130 template <
class Po
intT>
131 template <
class PropT>
146 template <
class Po
intT>
151 if (fix_number_control_points_)
155 control_polygon_.push_back(_cp);
158 if (autocompute_knotvector_)
159 knotvector_.createKnots(degree_, control_polygon_.size());
162 if( controlpoint_selections_available())
163 cpselections_.push_back(
false);
165 if( edge_selections_available())
166 eselections_.push_back(
false);
171 template <
class Po
intT>
176 if (fix_number_control_points_)
179 assert(_idx < (
int)control_polygon_.size());
180 control_polygon_.insert(control_polygon_.begin()+_idx, _cp);
183 if (autocompute_knotvector_)
184 knotvector_.createKnots(degree_, control_polygon_.size());
187 double knot = ( knotvector_(_idx-1) + knotvector_(_idx+1) ) / 2.0;
188 knotvector_.insertKnot(_idx, knot);
192 if( controlpoint_selections_available())
193 cpselections_.insert(cpselections_.begin()+_idx,
false);
195 if( edge_selections_available())
196 eselections_.insert(eselections_.begin()+_idx,
false);
202 template <
class Po
intT>
207 if (fix_number_control_points_)
210 assert(_idx < (
int)control_polygon_.size());
211 control_polygon_.erase(control_polygon_.begin()+_idx);
214 if (autocompute_knotvector_)
215 knotvector_.createKnots(degree_, control_polygon_.size());
218 knotvector_.deleteKnot(_idx);
222 if( controlpoint_selections_available())
223 cpselections_.erase(cpselections_.begin()+_idx);
225 if( edge_selections_available())
226 eselections_.erase(eselections_.begin()+_idx);
231 template <
class Po
intT>
236 assert(_idx < (
int)control_polygon_.size());
237 control_polygon_[_idx] = _cp;
242 template <
class Po
intT>
247 control_polygon_.clear();
249 for (
unsigned int i = 0; i < _control_polygon.size(); ++i)
250 control_polygon_.push_back(_control_polygon[i]);
252 cpselections_.clear();
253 if( controlpoint_selections_available())
254 cpselections_.resize(control_polygon_.size(),
false);
256 eselections_.clear();
257 if( edge_selections_available())
258 eselections_.resize(control_polygon_.size(),
false);
263 template <
class Po
intT>
268 control_polygon_.clear();
271 cpselections_.clear();
272 eselections_.clear();
277 template <
class Po
intT>
282 Scalar epsilon = 0.0000001;
294 std::vector<Scalar> N(p+1);
297 Point point = Point(0.0, 0.0, 0.0);
299 for (
int i = 0; i <= p; ++i)
307 template <
class Po
intT>
319 std::vector<Scalar> dNdu(p+1);
322 Point point = Point(0.0, 0.0, 0.0);
324 for (
int i = 0; i <= p; ++i)
332 template <
class Po
intT>
333 typename BSplineCurveT<PointT>::Scalar
337 int m = knotvector_.size() - 1;
340 if ((_i==0 && _t== knotvector_(0)) || (_i==m-_n-1 && _t==knotvector_(m)))
344 if (_t >= knotvector_(_i) && _t < knotvector_(_i+1))
350 typename BSplineCurveT<PointT>::Scalar Nin1 =
basisFunction(_i, _n-1, _t);
351 typename BSplineCurveT<PointT>::Scalar Nin2 =
basisFunction(_i+1, _n-1, _t);
354 if ((knotvector_(_i+_n)-knotvector_(_i)) !=0 )
355 fac1 = (_t - knotvector_(_i)) / (knotvector_(_i+_n) - knotvector_(_i)) ;
358 if ( (knotvector_(_i+1+_n)-knotvector_(_i+1)) !=0 )
359 fac2 = (knotvector_(_i+1+_n) - _t)/ (knotvector_(_i+1+_n) - knotvector_(_i+1));
366 return (fac1*Nin1 + fac2*Nin2);
371 template <
class Po
intT>
372 typename BSplineCurveT<PointT>::Scalar
385 if ( (knotvector_(_i+_n)-knotvector_(_i)) !=0 )
386 fac1 = double(_n) / (knotvector_(_i+_n)-knotvector_(_i));
389 if ( (knotvector_(_i+_n+1)-knotvector_(_i+1)) !=0 )
390 fac2 =
double(_n) / (knotvector_(_i+_n+1)-knotvector_(_i+1));
393 return (fac1*Nin1 - fac2*Nin2);
398 template <
class Po
intT>
408 Point point = Point(0.0, 0.0, 0.0);
412 std::vector<Point> allPoints;
415 std::vector<Point> controlPoints_r;
418 std::vector<Point> controlPoints_r1;
419 for (
int i = span_u[0]; i <= span_u[1]; ++i)
420 controlPoints_r1.push_back(control_polygon_[i]);
422 for (
int r = 1; r <= n; ++r)
424 controlPoints_r.clear();
426 for (
int i = r; i <= n; ++i)
429 double alpha = (_u - knotvector_(span_u[0]+i)) / (knotvector_(span_u[0]+i + n + 1 - r) - knotvector_(span_u[0]+i));
430 Point c = controlPoints_r1[i-r] * (1.0 - alpha) + controlPoints_r1[i-r+1] * alpha;
433 controlPoints_r.push_back(c);
434 allPoints.push_back(c);
437 controlPoints_r1 = controlPoints_r;
445 template <
class Po
intT>
446 typename BSplineCurveT<PointT>::Scalar
450 return knotvector_(
degree());
455 template <
class Po
intT>
456 typename BSplineCurveT<PointT>::Scalar
460 return knotvector_(knotvector_.size() - 1 -
degree());
465 template <
class Po
intT>
475 while (_t >= knotvector_(i)) i++;
476 while (_t < knotvector_(i)) i--;
484 template <
class Po
intT>
490 while (_t >= knotvector_(i)) i++;
491 while (_t < knotvector_(i)) i--;
493 return Vec2i(i, i+1);
498 template <
class Po
intT>
503 std::cerr <<
"****** BSplineInfo ******\n";
505 std::cerr <<
"#control_points: " << control_polygon_.size() << std::endl;
506 for (
unsigned int i = 0; i < control_polygon_.size(); ++i)
512 template <
class Po
intT>
524 std::vector<Point> updateControlPoints;
527 for (
int i = 0; i <= span_u[0]; ++i)
532 for (
unsigned int i = 0; i < degree_; ++i)
533 updateControlPoints.push_back(cp[i]);
542 for (
unsigned int i = 0; i < knotvector_.size(); ++i)
543 if (_u > knotvector_(i))
547 knotvector_.insertKnot(index, _u);
555 template <
class Po
intT>
560 autocompute_knotvector(
false);
563 knotvector_.setKnotvector(_knots);
568 template <
class Po
intT>
574 std::vector<Point> reversed_control_polygon;
580 std::vector< Scalar > reversed_knotvector(num_knots) ;
588 for (
int i = 0; i <= p; ++i)
589 reversed_knotvector[i] =
get_knot(i);
591 for (
int i = m-p-1; i <= m; ++i)
592 reversed_knotvector[i] =
get_knot(i);
594 for (
int i = 1; i < m - 2*p; ++i)
595 reversed_knotvector[m - p - i] = -
get_knot(p+i) + a + b;
VectorT< signed int, 2 > Vec2i
Point curvePoint(Scalar _u)
unsigned int n_knots() const
Returns the number of knots.
Point derivativeCurvePoint(Scalar _u, unsigned int _der)
void set_control_point(int _idx, const Point &_cp)
reset a control point
void bsplineBasisDerivatives(std::vector< Scalar > &_ders, const Vec2i &_span, Scalar _t, int _der, const std::vector< Scalar > &_knots, std::vector< Scalar > *_functionVals)
Compute derivatives of basis functions in a span.
Namespace providing different geometric functions concerning angles.
void add_control_point(const Point &_cp)
add a control point
void insert_control_point(int _idx, const Point &_cp)
insert a control point at given index
void reset_control_polygon()
Clears the control polygon.
unsigned int degree() const
Returns the spline degree.
Scalar upper() const
Returns the upper parameter.
void delete_control_point(int _idx)
delete control point at given index
Vec2i bsplineSpan(Scalar _t, int _degree, const std::vector< Scalar > &_knots)
Find the span of a parameter value.
Scalar lower() const
Returns the lower parameter.
ACG::Vec2i span(double _t)
unsigned int n_control_points() const
Returns the number of control points.
Point & get_control_point(int _i)
get control point i
void bsplineBasisFunctions(std::vector< Scalar > &_N, const Vec2i &_span, Scalar _t, const std::vector< Scalar > &_knots)
Evaluate basis functions in a span.
Scalar derivativeBasisFunction(int _i, int _n, Scalar _t, int _der)
void print() const
print information string
void set_control_polygon(std::vector< Point > &_control_polygon)
set whole control polygon
Scalar basisFunction(int _i, int _n, Scalar _t)
ACG::Vec2i interval(double _t)
void reverse()
Reverses the curve.
void set_knots(std::vector< Scalar > _knots)
set the knotvector of the bspline curve
BSplineCurveT(unsigned int _degree=3)
Constructor.
Scalar get_knot(int _i)
get knot i
std::vector< Point > deBoorAlgorithm(double _u)
void insertKnot(double _u)
Inserts a new knot at parameter u.