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>
136 template <
class Po
intT>
137 template <
class PropT>
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;
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)
313 template <
class Po
intT>
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)
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
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>
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>
481 while (_t >= knotvector_(i)) i++;
482 while (_t < knotvector_(i)) 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)
518 template <
class Po
intT>
530 std::vector<Point> updateControlPoints;
533 for (
int i = 0; i <= span_u[0]; ++i)
538 for (
unsigned int i = 0; i < degree_; ++i)
539 updateControlPoints.push_back(cp[i]);
548 for (
unsigned int i = 0; i < knotvector_.size(); ++i)
549 if (_u > knotvector_(i))
553 knotvector_.insertKnot(index, _u);
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;
586 std::vector< Scalar > reversed_knotvector(num_knots) ;
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;
void set_control_polygon(std::vector< Point > &_control_polygon)
set whole control polygon
BSplineCurveT(unsigned int _degree=3)
Constructor.
ACG::Vec2i interval(double _t)
void delete_control_point(int _idx)
delete control point at given index
Scalar derivativeBasisFunction(int _i, int _n, Scalar _t, int _der)
Scalar get_knot(int _i)
get knot i
Scalar upper() const
Returns the upper parameter.
void reset_control_polygon()
Clears the control polygon.
Point & get_control_point(int _i)
get control point i
unsigned int n_control_points() const
Returns the number of control points.
void reverse()
Reverses the curve.
unsigned int n_knots() const
Returns the number of knots.
void bsplineBasisFunctions(std::vector< Scalar > &_N, const Vec2i &_span, Scalar _t, const std::vector< Scalar > &_knots)
Evaluate basis functions in a span.
void set_control_point(int _idx, const Point &_cp)
reset a control point
void insertKnot(double _u)
Inserts a new knot at parameter u.
void print() const
print information string
unsigned int degree() const
Returns the spline degree.
Scalar basisFunction(int _i, int _n, Scalar _t)
Point curvePoint(Scalar _u)
std::vector< Point > deBoorAlgorithm(double _u)
VectorT< signed int, 2 > Vec2i
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
Vec2i bsplineSpan(Scalar _t, int _degree, const std::vector< Scalar > &_knots)
Find the span of a parameter value.
Namespace providing different geometric functions concerning angles.
ACG::Vec2i span(double _t)
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 set_knots(std::vector< Scalar > _knots)
set the knotvector of the bspline curve
Scalar lower() const
Returns the lower parameter.
Point derivativeCurvePoint(Scalar _u, unsigned int _der)