58 #define BSPLINECURVE_BSPLINECURVET_C
62 #include <OpenMesh/Core/Geometry/VectorT.hh>
70 #include <ACG/Geometry/Algorithms.hh>
71 #include <ACG/Math/BSplineBasis.hh>
80 template <
class Po
intT>
84 autocompute_knotvector_(true),
85 fix_number_control_points_(false),
86 ref_count_cpselections_(0),
87 ref_count_eselections_(0)
93 template <
class Po
intT>
98 control_polygon_ = _curve.control_polygon_;
101 knotvector_ = _curve.knotvector_;
103 degree_ = _curve.degree_;
104 autocompute_knotvector_ = _curve.autocompute_knotvector_;
105 fix_number_control_points_ = _curve.fix_number_control_points_;
108 cpselections_ = _curve.cpselections_;
109 eselections_ = _curve.eselections_;
112 ref_count_cpselections_ = _curve.ref_count_cpselections_;
113 ref_count_eselections_ = _curve.ref_count_eselections_;
119 template <
class Po
intT>
120 template <
class PropT>
129 _prop.resize(n_control_points());
136 template <
class Po
intT>
137 template <
class PropT>
139 BSplineCurveT<PointT>::
140 release_prop(
unsigned int& _ref_count, PropT& _prop)
152 template <
class Po
intT>
157 if (fix_number_control_points_)
161 control_polygon_.push_back(_cp);
164 if (autocompute_knotvector_)
165 knotvector_.createKnots(degree_, control_polygon_.size());
168 if( controlpoint_selections_available())
169 cpselections_.push_back(
false);
171 if( edge_selections_available())
172 eselections_.push_back(
false);
177 template <
class Po
intT>
182 if (fix_number_control_points_)
185 assert(_idx < (
int)control_polygon_.size());
186 control_polygon_.insert(control_polygon_.begin()+_idx, _cp);
189 if (autocompute_knotvector_)
190 knotvector_.createKnots(degree_, control_polygon_.size());
193 double knot = ( knotvector_(_idx-1) + knotvector_(_idx+1) ) / 2.0;
194 knotvector_.insertKnot(_idx, knot);
198 if( controlpoint_selections_available())
199 cpselections_.insert(cpselections_.begin()+_idx,
false);
201 if( edge_selections_available())
202 eselections_.insert(eselections_.begin()+_idx,
false);
208 template <
class Po
intT>
213 if (fix_number_control_points_)
216 assert(_idx < (
int)control_polygon_.size());
217 control_polygon_.erase(control_polygon_.begin()+_idx);
220 if (autocompute_knotvector_)
221 knotvector_.createKnots(degree_, control_polygon_.size());
224 knotvector_.deleteKnot(_idx);
228 if( controlpoint_selections_available())
229 cpselections_.erase(cpselections_.begin()+_idx);
231 if( edge_selections_available())
232 eselections_.erase(eselections_.begin()+_idx);
237 template <
class Po
intT>
242 assert(_idx < (
int)control_polygon_.size());
243 control_polygon_[_idx] = _cp;
248 template <
class Po
intT>
253 control_polygon_.clear();
255 for (
unsigned int i = 0; i < _control_polygon.size(); ++i)
256 control_polygon_.push_back(_control_polygon[i]);
258 cpselections_.clear();
259 if( controlpoint_selections_available())
260 cpselections_.resize(control_polygon_.size(),
false);
262 eselections_.clear();
263 if( edge_selections_available())
264 eselections_.resize(control_polygon_.size(),
false);
269 template <
class Po
intT>
274 control_polygon_.clear();
277 cpselections_.clear();
278 eselections_.clear();
283 template <
class Po
intT>
288 Scalar epsilon = 0.0000001;
290 if (_u > upper() && _u < upper()+epsilon)
293 assert(_u >= lower() && _u <= upper());
300 std::vector<Scalar> N(p+1);
303 Point point = Point(0.0, 0.0, 0.0);
305 for (
int i = 0; i <= p; ++i)
306 point += get_control_point(span[0] + i) * N[i];
313 template <
class Po
intT>
318 assert(_u >= lower() && _u <= upper());
325 std::vector<Scalar> dNdu(p+1);
328 Point point = Point(0.0, 0.0, 0.0);
330 for (
int i = 0; i <= p; ++i)
331 point += get_control_point(i + span[0]) * dNdu[i];
338 template <
class Po
intT>
339 typename BSplineCurveT<PointT>::Scalar
343 int m = knotvector_.size() - 1;
346 if ((_i==0 && _t== knotvector_(0)) || (_i==m-_n-1 && _t==knotvector_(m)))
350 if (_t >= knotvector_(_i) && _t < knotvector_(_i+1))
356 typename BSplineCurveT<PointT>::Scalar Nin1 = basisFunction(_i, _n-1, _t);
357 typename BSplineCurveT<PointT>::Scalar Nin2 = basisFunction(_i+1, _n-1, _t);
360 if ((knotvector_(_i+_n)-knotvector_(_i)) !=0 )
361 fac1 = (_t - knotvector_(_i)) / (knotvector_(_i+_n) - knotvector_(_i)) ;
364 if ( (knotvector_(_i+1+_n)-knotvector_(_i+1)) !=0 )
365 fac2 = (knotvector_(_i+1+_n) - _t)/ (knotvector_(_i+1+_n) - knotvector_(_i+1));
372 return (fac1*Nin1 + fac2*Nin2);
377 template <
class Po
intT>
378 typename BSplineCurveT<PointT>::Scalar
383 return basisFunction(_i, _n, _t);
385 typename BSplineCurveT<PointT>::Scalar Nin1 = derivativeBasisFunction(_i, _n-1, _t, _der-1);
386 typename BSplineCurveT<PointT>::Scalar Nin2 = derivativeBasisFunction(_i+1, _n-1, _t, _der-1);
391 if ( (knotvector_(_i+_n)-knotvector_(_i)) !=0 )
392 fac1 = double(_n) / (knotvector_(_i+_n)-knotvector_(_i));
395 if ( (knotvector_(_i+_n+1)-knotvector_(_i+1)) !=0 )
396 fac2 =
double(_n) / (knotvector_(_i+_n+1)-knotvector_(_i+1));
399 return (fac1*Nin1 - fac2*Nin2);
404 template <
class Po
intT>
410 assert(_u >= lower() && _u <= upper());
414 Point point = Point(0.0, 0.0, 0.0);
418 std::vector<Point> allPoints;
421 std::vector<Point> controlPoints_r;
424 std::vector<Point> controlPoints_r1;
425 for (
int i = span_u[0]; i <= span_u[1]; ++i)
426 controlPoints_r1.push_back(control_polygon_[i]);
428 for (
int r = 1; r <= n; ++r)
430 controlPoints_r.clear();
432 for (
int i = r; i <= n; ++i)
435 double alpha = (_u - knotvector_(span_u[0]+i)) / (knotvector_(span_u[0]+i + n + 1 - r) - knotvector_(span_u[0]+i));
436 Point c = controlPoints_r1[i-r] * (1.0 - alpha) + controlPoints_r1[i-r+1] * alpha;
439 controlPoints_r.push_back(c);
440 allPoints.push_back(c);
443 controlPoints_r1 = controlPoints_r;
451 template <
class Po
intT>
452 typename BSplineCurveT<PointT>::Scalar
456 return knotvector_(degree());
461 template <
class Po
intT>
462 typename BSplineCurveT<PointT>::Scalar
466 return knotvector_(knotvector_.size() - 1 - degree());
471 template <
class Po
intT>
479 i = n_control_points() - 1;
481 while (_t >= knotvector_(i)) i++;
482 while (_t < knotvector_(i)) i--;
485 return Vec2i(i-degree(), i);
490 template <
class Po
intT>
496 while (_t >= knotvector_(i)) i++;
497 while (_t < knotvector_(i)) i--;
499 return Vec2i(i, i+1);
504 template <
class Po
intT>
509 std::cerr <<
"****** BSplineInfo ******\n";
511 std::cerr <<
"#control_points: " << control_polygon_.size() << std::endl;
512 for (
unsigned int i = 0; i < control_polygon_.size(); ++i)
513 std::cerr << get_control_point(i) << std::endl;
518 template <
class Po
intT>
526 assert(_u >= lower() && _u <= upper());
530 std::vector<Point> updateControlPoints;
533 for (
int i = 0; i <= span_u[0]; ++i)
534 updateControlPoints.push_back(get_control_point(i));
537 std::vector<Vec3d> cp = deBoorAlgorithm(_u);
538 for (
unsigned int i = 0; i < degree_; ++i)
539 updateControlPoints.push_back(cp[i]);
542 for (
unsigned int i = span_u[1]; i < n_control_points(); ++i)
543 updateControlPoints.push_back(get_control_point(i));
548 for (
unsigned int i = 0; i < knotvector_.size(); ++i)
549 if (_u > knotvector_(i))
553 knotvector_.insertKnot(index, _u);
556 set_control_polygon(updateControlPoints);
561 template <
class Po
intT>
566 autocompute_knotvector(
false);
569 knotvector_.setKnotvector(_knots);
574 template <
class Po
intT>
580 std::vector<Point> reversed_control_polygon;
581 for (
int i = n_control_points()-1; i > -1; --i)
582 reversed_control_polygon.push_back( get_control_point(i) );
585 int num_knots = n_knots();
586 std::vector< Scalar > reversed_knotvector(num_knots) ;
591 double a = get_knot(0);
592 double b = get_knot(num_knots-1);
594 for (
int i = 0; i <= p; ++i)
595 reversed_knotvector[i] = get_knot(i);
597 for (
int i = m-p-1; i <= m; ++i)
598 reversed_knotvector[i] = get_knot(i);
600 for (
int i = 1; i < m - 2*p; ++i)
601 reversed_knotvector[m - p - i] = - get_knot(p+i) + a + b;
604 set_control_polygon(reversed_control_polygon);
607 set_knots(reversed_knotvector);
void add_control_point(const Point &_cp)
add a control point
void bsplineBasisFunctions(std::vector< Scalar > &_N, const Vec2i &_span, Scalar _t, const std::vector< Scalar > &_knots)
Evaluate basis functions in a span.
Namespace providing different geometric functions concerning angles.
VectorT< signed int, 2 > Vec2i
Scalar lower() const
Returns the lower parameter.
void print() const
print information string
std::vector< Point > deBoorAlgorithm(double _u)
void delete_control_point(int _idx)
delete control point at given index
void set_control_point(int _idx, const Point &_cp)
reset a control point
Scalar upper() const
Returns the upper parameter.
void insertKnot(double _u)
Inserts a new knot at parameter u.
Vec2i bsplineSpan(Scalar _t, int _degree, const std::vector< Scalar > &_knots)
Find the span of a parameter value.
void reset_control_polygon()
Clears the control polygon.
Point curvePoint(Scalar _u)
Scalar derivativeBasisFunction(int _i, int _n, Scalar _t, int _der)
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.
void insert_control_point(int _idx, const Point &_cp)
insert a control point at given index
Scalar basisFunction(int _i, int _n, Scalar _t)
ACG::Vec2i span(double _t)
Point derivativeCurvePoint(Scalar _u, unsigned int _der)
ACG::Vec2i interval(double _t)
BSplineCurveT(unsigned int _degree=3)
Constructor.
void set_knots(std::vector< Scalar > _knots)
set the knotvector of the bspline curve
void set_control_polygon(std::vector< Point > &_control_polygon)
set whole control polygon
void reverse()
Reverses the curve.