58 #define BSPLINESURFACE_BSPLINESURFACET_C
62 #include <OpenMesh/Core/Geometry/VectorT.hh>
67 #include "BSplineSurfaceT.hh"
70 #include <ACG/Geometry/Algorithms.hh>
71 #include <ACG/Math/BSplineBasis.hh>
79 template <
class Po
intT>
84 ref_count_cpselections_(0),
85 ref_count_eselections_(0)
92 template <
class Po
intT>
93 template <
class PropT>
103 _prop.
resize(n_control_points_m());
104 for (
unsigned int i = 0; i < _prop.size(); ++i)
105 _prop[i].resize(n_control_points_n());
112 template <
class Po
intT>
113 template <
class PropT>
115 BSplineSurfaceT<PointT>::
116 release_prop(
unsigned int& _ref_count, PropT& _prop)
128 template <
class Po
intT>
133 control_net_.resize(_m);
135 for (
unsigned int i = 0; i < control_net_.size(); ++i)
136 control_net_[i].resize(_n);
142 cpselections_.resize(_m);
143 for (
unsigned int i = 0; i < cpselections_.size(); ++i)
144 cpselections_[i].resize(_n);
147 eselections_.resize(_m);
148 for (
unsigned int i = 0; i < eselections_.size(); ++i)
149 eselections_[i].resize(_n);
154 template <
class Po
intT>
159 control_net_.clear();
162 cpselections_.clear();
163 eselections_.clear();
168 template <
class Po
intT>
173 knotvector_m_.createKnots(degree_m_, dimm_);
174 knotvector_n_.createKnots(degree_n_, dimn_);
179 template <
class Po
intT>
190 template <
class Po
intT>
195 insert_vector_m(_control_polygon, dimm_);
200 template <
class Po
intT>
205 insert_vector_n(_control_polygon, dimn_);
210 template <
class Po
intT>
215 std::cout <<
"insert_vector_m of size " << _control_polygon.size() <<
" at m = " << _m << std::endl;
219 dimn_ =_control_polygon.size();
221 assert(_control_polygon.size() == dimn_);
223 resize(dimm_ + 1, dimn_);
225 control_net_.insert(control_net_.begin() + _m, _control_polygon);
226 control_net_.pop_back();
227 std::cout <<
"control_net_: " << control_net_.size() <<
" x " << control_net_[control_net_.size()-1].size() << std::endl;
230 std::vector<unsigned char> dummy(_control_polygon.size(), 0);
231 cpselections_.insert(cpselections_.begin() + _m, dummy);
232 cpselections_.pop_back();
233 std::cout <<
"cpselections_: " << cpselections_.size() <<
" x " << cpselections_[cpselections_.size()-1].size() << std::endl;
236 eselections_.insert(eselections_.begin() + _m, dummy);
237 eselections_.pop_back();
238 std::cout <<
"eselections_: " << eselections_.size() <<
" x " << eselections_[eselections_.size()-1].size() << std::endl;
243 template <
class Po
intT>
250 dimm_ = _control_polygon.size();
252 assert(_control_polygon.size() == dimm_);
254 resize(dimm_, dimn_+1);
256 for (
unsigned int i = 0; i < dimm_; ++i)
258 control_net_[i].insert(control_net_[i].begin() + _n, _control_polygon[i]);
259 control_net_[i].pop_back();
263 for (
unsigned int i = 0; i < dimm_; ++i)
265 cpselections_[i].insert(cpselections_[i].begin() + _n, 0);
266 cpselections_[i].pop_back();
269 for (
unsigned int i = 0; i < dimm_; ++i)
271 eselections_[i].insert(eselections_[i].begin() + _n, 0);
272 eselections_[i].pop_back();
278 template <
class Po
intT>
287 if(control_net_.begin() + _m < control_net_.end())
288 control_net_.erase(control_net_.begin() + _m);
290 resize(dimm_-1, dimn_);
293 if(cpselections_.begin() + _m < cpselections_.end())
294 cpselections_.erase(cpselections_.begin() + _m);
296 if(eselections_.begin() + _m < eselections_.end())
297 eselections_.erase(eselections_.begin() + _m);
305 template <
class Po
intT>
314 for (
unsigned int i = 0; i < control_net_.size(); ++i) {
315 if(control_net_[i].begin() + _n < control_net_[i].end())
316 control_net_[i].erase(control_net_[i].begin() + _n);
319 resize(dimm_, dimn_-1);
322 for (
unsigned int i = 0; i < cpselections_.size(); ++i)
323 if(cpselections_[i].begin() + _n < cpselections_[i].end())
324 cpselections_[i].erase(cpselections_[i].begin() + _n);
326 for (
unsigned int i = 0; i < eselections_.size(); ++i)
327 if(eselections_[i].begin() + _n < eselections_[i].end())
328 eselections_[i].erase(eselections_[i].begin() + _n);
336 template <
class Po
intT>
342 _control_polygon = control_net_[_m];
347 template <
class Po
intT>
353 _control_polygon.resize(dimm_);
355 for (
unsigned int i = 0; i < dimm_; ++i)
356 _control_polygon[i] = control_net_[i][_n];
361 template <
class Po
intT>
367 knotvector_m_.setKnotvector(_knots);
372 template <
class Po
intT>
378 knotvector_n_.setKnotvector(_knots);
383 template <
class Po
intT>
389 Vec2i span = spanm(_u);
390 Vec2i interval = interval_m(_u);
394 newknotvecu.insertKnot(interval[1], _u);
397 std::vector<double> alpha;
398 for(
int i = span[0]; i < span[1]; ++i)
400 double a(knotvector_m_.getKnot(i+1));
401 double b(knotvector_m_.getKnot(i+degree_m_+1));
402 alpha.push_back((_u-a)/(b-a));
404 knotvector_m_ = newknotvecu;
407 ControlNet oldcpts(control_net_);
409 resize(n_control_points_m()+1, n_control_points_n());
411 for(
int i = 0; i < n_control_points_m(); ++i)
414 control_net_[i] = oldcpts[i];
415 else if( i <= span[1])
416 for(
unsigned int j = 0; j < n_control_points_n(); ++j)
418 control_net_[i][j] = oldcpts[i-1][j]*(1.0-alpha[i-span[0]-1])+oldcpts[i][j]*alpha[i-span[0]-1];
421 control_net_[i] = oldcpts[i-1];
427 template <
class Po
intT>
433 Vec2i span = spann(_v);
434 Vec2i interval = interval_n(_v);
438 newknotvecv.insertKnot(interval[1], _v);
441 std::vector<double> alpha;
442 for(
int i = span[0]; i < span[1]; ++i)
444 double a(knotvector_n_.getKnot(i+1));
445 double b(knotvector_n_.getKnot(i+degree_n_+1));
446 alpha.push_back((_v-a)/(b-a));
448 knotvector_n_ = newknotvecv;
451 ControlNet oldcpts(control_net_);
453 resize(n_control_points_m(), n_control_points_n()+1);
455 for(
int i = 0; i < n_control_points_n(); ++i)
458 for(
unsigned int j = 0; j < n_control_points_m(); ++j)
459 control_net_[j][i] = oldcpts[j][i];
460 else if( i <= span[1])
461 for(
unsigned int j = 0; j < n_control_points_m(); ++j)
463 control_net_[j][i] = oldcpts[j][i-1]*(1.0-alpha[i-span[0]-1])+oldcpts[j][i]*alpha[i-span[0]-1];
466 for(
unsigned int j = 0; j < n_control_points_m(); ++j)
467 control_net_[j][i] = oldcpts[j][i-1];
473 template <
class Po
intT>
478 double epsilon = 0.0000001;
480 if (_u > upperu() && _u < upperu()+epsilon)
483 if (_v > upperv() && _v < upperv()+epsilon)
486 assert(_u >= loweru() && _u <= upperu());
487 assert(_v >= lowerv() && _v <= upperv());
492 Point point = Point(0.0, 0.0, 0.0);
494 Vec2i span_m(spanm(_u));
495 Vec2i span_n(spann(_v));
498 std::vector<Scalar> basisFuns_m(pm+1);
499 std::vector<Scalar> basisFuns_n(pn+1);
507 for (
int i = span_m[0]; i <= span_m[1]; ++i)
508 for (
int j = span_n[0]; j <= span_n[1]; ++j)
509 point += control_net_[i][j] * basisFuns_m[i-span_m[0]] * basisFuns_n[j - span_n[0]];
516 template <
class Po
intT>
521 double epsilon = 0.0000001;
523 if (_u > upperu() && _u < upperu()+epsilon)
526 if (_v > upperv() && _v < upperv()+epsilon)
529 assert(_u >= loweru() && _u <= upperu());
530 assert(_v >= lowerv() && _v <= upperv());
535 _pt = Point(0.0, 0.0, 0.0);
537 Vec2i span_m(spanm(_u));
538 Vec2i span_n(spann(_v));
541 std::vector<Scalar> basisFuns_m(pm+1);
542 std::vector<Scalar> ders_m(pm+1);
543 std::vector<Scalar> basisFuns_n(pn+1);
544 std::vector<Scalar> ders_n(pn+1);
553 Point dpdu = Point(0,0,0);
554 Point dpdv = Point(0,0,0);
556 for (
int i = 0; i <= pm; ++i)
558 for (
int j = 0; j <= pn; ++j)
560 Point cp = control_net_[i + span_m[0]][j + span_n[0]];
562 _pt += cp * (basisFuns_m[i] * basisFuns_n[j]);
564 dpdu += cp * (ders_m[i] * basisFuns_n[j]);
565 dpdv += cp * (basisFuns_m[i] * ders_n[j]);
569 _normal = (dpdu % dpdv).normalize();
574 template <
class Po
intT>
579 double epsilon = 0.0000001;
581 if (_u > upperu() && _u < upperu()+epsilon)
584 if (_v > upperv() && _v < upperv()+epsilon)
587 assert(_u >= loweru() && _u <= upperu());
588 assert(_v >= lowerv() && _v <= upperv());
593 Point point = Point(0.0, 0.0, 0.0);
595 Vec2i span_m(spanm(_u));
596 Vec2i span_n(spann(_v));
598 for (
int i = span_m[0]; i <= span_m[1]; ++i)
599 for (
int j = span_n[0]; j <= span_n[1]; ++j)
600 point += control_net_[i][j] * basisFunction(knotvector_m_, i, pm, _u) * basisFunction(knotvector_n_, j, pn, _v);
607 template <
class Po
intT>
608 typename BSplineSurfaceT<PointT>::Scalar
612 int m = _knotvector.size() - 1;
615 if ((_i==0 && _t== _knotvector(0)) || (_i==m-_n-1 && _t==_knotvector(m)))
619 if (_t >= _knotvector(_i) && _t < _knotvector(_i+1))
625 double Nin1 = basisFunction(_knotvector, _i, _n-1, _t);
626 double Nin2 = basisFunction(_knotvector, _i+1, _n-1, _t);
630 if ((_knotvector(_i+_n) - _knotvector(_i)) != 0)
631 fac1 = (_t - _knotvector(_i)) / (_knotvector(_i+_n) - _knotvector(_i)) ;
635 if ( (_knotvector(_i+1+_n) - _knotvector(_i+1)) != 0 )
636 fac2 = (_knotvector(_i+1+_n) - _t) / (_knotvector(_i+1+_n) - _knotvector(_i+1));
640 return (fac1*Nin1 + fac2*Nin2);
645 template <
class Po
intT>
650 assert(_u >= loweru() && _u <= upperu());
651 assert(_v >= lowerv() && _v <= upperv());
658 Vec2i span_m(spanm(_u));
659 Vec2i span_n(spann(_v));
661 std::vector<Scalar> ders_m(pm+1);
662 std::vector<Scalar> ders_n(pn+1);
664 ACG::bsplineBasisDerivatives<Scalar>(ders_m, span_m, _u, _derm, knotvector_m_.getKnotvector(), 0);
665 ACG::bsplineBasisDerivatives<Scalar>(ders_n, span_n, _v, _dern, knotvector_n_.getKnotvector(), 0);
667 for (
int i = span_m[0]; i <= span_m[1]; i++)
668 for (
int j = span_n[0]; j <= span_n[1]; j++)
669 point += control_net_[i][j] * ders_m[i - span_m[0]] * ders_n[j - span_n[0]];
677 template <
class Po
intT>
682 assert(_u >= loweru() && _u <= upperu());
683 assert(_v >= lowerv() && _v <= upperv());
685 Point derivu = derivativeSurfacePoint(_u,_v,1,0);
686 Point derivv = derivativeSurfacePoint(_u,_v,0,1);
688 Point normal( (derivu%derivv).normalize());
695 template <
class Po
intT>
696 typename BSplineSurfaceT<PointT>::Scalar
704 return basisFunction(_knotvector, _i, _n, _t);
706 Scalar Nin1 = derivativeBasisFunction(_knotvector, _i, _n-1, _t, _der-1);
707 Scalar Nin2 = derivativeBasisFunction(_knotvector, _i+1, _n-1, _t, _der-1);
710 if ( fabs(_knotvector(_i+_n)-_knotvector(_i)) > 1e-6 )
711 fac1 = Scalar(_n) / (_knotvector(_i+_n)-_knotvector(_i));
714 if ( fabs(_knotvector(_i+_n+1)-_knotvector(_i+1)) > 1e-6 )
715 fac2 = Scalar(_n) / (_knotvector(_i+_n+1)-_knotvector(_i+1));
717 return (fac1*Nin1 - fac2*Nin2);
722 template <
class Po
intT>
723 typename BSplineSurfaceT<PointT>::Scalar
727 return knotvector_m_(degree_m());
732 template <
class Po
intT>
733 typename BSplineSurfaceT<PointT>::Scalar
736 return knotvector_m_(knotvector_m_.size() - 1 - degree_m());
741 template <
class Po
intT>
742 typename BSplineSurfaceT<PointT>::Scalar
746 return knotvector_n_(degree_n());
751 template <
class Po
intT>
752 typename BSplineSurfaceT<PointT>::Scalar
755 return knotvector_n_(knotvector_n_.size() - 1 - degree_n());
760 template <
class Po
intT>
770 template <
class Po
intT>
780 template <
class Po
intT>
791 while (_t >= knotvector_m_(i)) i++;
792 while (_t < knotvector_m_(i)) i--;
795 return Vec2i(i, i+1);
800 template <
class Po
intT>
811 while (_t >= knotvector_n_(i)) i++;
812 while (_t < knotvector_n_(i)) i--;
815 return Vec2i(i, i+1);
void get_vector_n(std::vector< Point > &_control_polygon, unsigned int _n)
Returns an m ctrPointVector.
void get_vector_m(std::vector< Point > &_control_polygon, unsigned int _m)
Returns an n control point vector.
void bsplineBasisFunctions(std::vector< Scalar > &_N, const Vec2i &_span, Scalar _t, const std::vector< Scalar > &_knots)
Evaluate basis functions in a span.
Point surfacePoint(double _u, double _v)
Evaluates a spline surface at parameters _u and _v.
Namespace providing different geometric functions concerning angles.
VectorT< signed int, 2 > Vec2i
Scalar upperv()
Returns the upper v parameter.
void set_knots_m(std::vector< Scalar > _knots)
Set the knotvector of the bspline surface in m direction.
ACG::Vec2i interval_n(double _t)
Returns the index of the knots v and v+1 such that t in [v, v+1)
void add_vector_m(const std::vector< Point > &_control_polygon)
Adds a control point n-vector.
void delete_vector_m(unsigned int _m)
Deletes an n control point vector.
ACG::Vec2i interval_m(double _t)
Returns the index of the knots u and u+1 such that t in [u, u+1)
void createKnots()
Creates interpolating knotvectors 0...0, 1, 2, ..., n...n.
Vec2i bsplineSpan(Scalar _t, int _degree, const std::vector< Scalar > &_knots)
Find the span of a parameter value.
void insert_knot_n(double _t)
Insert a knot i in n direction without changing the surface.
Point derivativeSurfacePoint(double _u, double _v, int _derm, int _dern)
Returns the _derm'th derivative of a spline surface.
Scalar basisFunction(Knotvector &_knotvector, int _i, int _n, double _t)
A Spline Basis Function.
Scalar lowerv()
Returns the lower v parameter.
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_vector_n(const std::vector< Point > &_control_polygon, unsigned int _n)
Inserts an m control point vector.
void delete_vector_n(unsigned int _n)
Deletes an m control point vector.
void reset_control_net()
Clears the control net.
BSplineSurfaceT(unsigned int _degm=3, unsigned int _degn=3)
Constructor.
Scalar derivativeBasisFunction(Knotvector &_knotvector, int _i, int _n, double _t, int _der)
Derivative of a Spline Basis Function.
ACG::Vec2i spann(double _t)
Returns the basis functions which are unequal to zero at parameter v.
void add_vector_n(const std::vector< Point > &_control_polygon)
Adds a control point m-vector.
ACG::Vec2i spanm(double _t)
Returns the basis functions which are unequal to zero at parameter u.
void surfacePointNormal(Point &_pt, Point &_normal, double _u, double _v)
Evaluates a spline surface at parameters _u and _v.
void resize(unsigned int _m, unsigned int _n)
Resizes the spline struct.
void insert_knot_m(double _t)
Insert a knot i in m direction without changing the surface.
void insert_vector_m(const std::vector< Point > &_control_polygon, unsigned int _m)
Inserts an n control point vector.
void set_degree(unsigned int _degm, unsigned int _degn)
Sets the degree of the spline surface.
Scalar upperu()
Returns the upper u parameter.
Point surfacePoint_rec(double _u, double _v)
Evaluates a spline surface at parameters _u and _v.
Point normalSurfacePoint(double _u, double _v)
Returns the normal of a spline surface.
Scalar loweru()
Returns the lower u parameter.
void set_knots_n(std::vector< Scalar > _knots)
Set the knotvector of the bspline surface in n direction.