52 #define BSPLINESURFACE_BSPLINESURFACET_C 56 #include <OpenMesh/Core/Geometry/VectorT.hh> 61 #include "BSplineSurfaceT.hh" 64 #include <ACG/Geometry/Algorithms.hh> 65 #include <ACG/Math/BSplineBasis.hh> 73 template <
class Po
intT>
78 ref_count_cpselections_(0),
79 ref_count_eselections_(0)
86 template <
class Po
intT>
87 template <
class PropT>
98 for (
unsigned int i = 0; i < _prop.size(); ++i)
106 template <
class Po
intT>
107 template <
class PropT>
122 template <
class Po
intT>
127 control_net_.resize(_m);
129 for (
unsigned int i = 0; i < control_net_.size(); ++i)
130 control_net_[i].
resize(_n);
148 template <
class Po
intT>
153 control_net_.clear();
162 template <
class Po
intT>
173 template <
class Po
intT>
184 template <
class Po
intT>
194 template <
class Po
intT>
204 template <
class Po
intT>
209 std::cout <<
"insert_vector_m of size " << _control_polygon.size() <<
" at m = " << _m << std::endl;
213 dimn_ =_control_polygon.size();
215 assert(_control_polygon.size() ==
dimn_);
219 control_net_.insert(control_net_.begin() + _m, _control_polygon);
220 control_net_.pop_back();
221 std::cout <<
"control_net_: " << control_net_.size() <<
" x " << control_net_[control_net_.size()-1].size() << std::endl;
224 std::vector<unsigned char> dummy(_control_polygon.size(), 0);
237 template <
class Po
intT>
244 dimm_ = _control_polygon.size();
246 assert(_control_polygon.size() ==
dimm_);
250 for (
unsigned int i = 0; i <
dimm_; ++i)
252 control_net_[i].insert(control_net_[i].begin() + _n, _control_polygon[i]);
253 control_net_[i].pop_back();
257 for (
unsigned int i = 0; i <
dimm_; ++i)
263 for (
unsigned int i = 0; i <
dimm_; ++i)
272 template <
class Po
intT>
281 if(control_net_.begin() + _m < control_net_.end())
282 control_net_.erase(control_net_.begin() + _m);
299 template <
class Po
intT>
308 for (
unsigned int i = 0; i < control_net_.size(); ++i) {
309 if(control_net_[i].begin() + _n < control_net_[i].end())
310 control_net_[i].erase(control_net_[i].begin() + _n);
330 template <
class Po
intT>
336 _control_polygon = control_net_[_m];
341 template <
class Po
intT>
347 _control_polygon.resize(
dimm_);
349 for (
unsigned int i = 0; i <
dimm_; ++i)
350 _control_polygon[i] = control_net_[i][_n];
355 template <
class Po
intT>
366 template <
class Po
intT>
377 template <
class Po
intT>
388 newknotvecu.insertKnot(interval[1], _u);
391 std::vector<double> alpha;
392 for(
int i = span[0]; i < span[1]; ++i)
396 alpha.push_back((_u-a)/(b-a));
401 ControlNet oldcpts(control_net_);
408 control_net_[i] = oldcpts[i];
409 else if( i <= span[1])
412 control_net_[i][j] = oldcpts[i-1][j]*(1.0-alpha[i-span[0]-1])+oldcpts[i][j]*alpha[i-span[0]-1];
415 control_net_[i] = oldcpts[i-1];
421 template <
class Po
intT>
432 newknotvecv.insertKnot(interval[1], _v);
435 std::vector<double> alpha;
436 for(
int i = span[0]; i < span[1]; ++i)
440 alpha.push_back((_v-a)/(b-a));
445 ControlNet oldcpts(control_net_);
453 control_net_[j][i] = oldcpts[j][i];
454 else if( i <= span[1])
457 control_net_[j][i] = oldcpts[j][i-1]*(1.0-alpha[i-span[0]-1])+oldcpts[j][i]*alpha[i-span[0]-1];
461 control_net_[j][i] = oldcpts[j][i-1];
467 template <
class Po
intT>
472 double epsilon = 0.0000001;
486 Point point = Point(0.0, 0.0, 0.0);
492 std::vector<Scalar> basisFuns_m(pm+1);
493 std::vector<Scalar> basisFuns_n(pn+1);
501 for (
int i = span_m[0]; i <= span_m[1]; ++i)
502 for (
int j = span_n[0]; j <= span_n[1]; ++j)
503 point += control_net_[i][j] * basisFuns_m[i-span_m[0]] * basisFuns_n[j - span_n[0]];
510 template <
class Po
intT>
515 double epsilon = 0.0000001;
529 _pt = Point(0.0, 0.0, 0.0);
535 std::vector<Scalar> basisFuns_m(pm+1);
536 std::vector<Scalar> ders_m(pm+1);
537 std::vector<Scalar> basisFuns_n(pn+1);
538 std::vector<Scalar> ders_n(pn+1);
547 Point dpdu = Point(0,0,0);
548 Point dpdv = Point(0,0,0);
550 for (
int i = 0; i <= pm; ++i)
552 for (
int j = 0; j <= pn; ++j)
554 Point cp = control_net_[i + span_m[0]][j + span_n[0]];
556 _pt += cp * (basisFuns_m[i] * basisFuns_n[j]);
558 dpdu += cp * (ders_m[i] * basisFuns_n[j]);
559 dpdv += cp * (basisFuns_m[i] * ders_n[j]);
563 _normal = (dpdu % dpdv).normalize();
568 template <
class Po
intT>
573 double epsilon = 0.0000001;
587 Point point = Point(0.0, 0.0, 0.0);
592 for (
int i = span_m[0]; i <= span_m[1]; ++i)
593 for (
int j = span_n[0]; j <= span_n[1]; ++j)
601 template <
class Po
intT>
602 typename BSplineSurfaceT<PointT>::Scalar
606 int m = _knotvector.size() - 1;
609 if ((_i==0 && _t== _knotvector(0)) || (_i==m-_n-1 && _t==_knotvector(m)))
613 if (_t >= _knotvector(_i) && _t < _knotvector(_i+1))
624 if ((_knotvector(_i+_n) - _knotvector(_i)) != 0)
625 fac1 = (_t - _knotvector(_i)) / (_knotvector(_i+_n) - _knotvector(_i)) ;
629 if ( (_knotvector(_i+1+_n) - _knotvector(_i+1)) != 0 )
630 fac2 = (_knotvector(_i+1+_n) - _t) / (_knotvector(_i+1+_n) - _knotvector(_i+1));
634 return (fac1*Nin1 + fac2*Nin2);
639 template <
class Po
intT>
655 std::vector<Scalar> ders_m(pm+1);
656 std::vector<Scalar> ders_n(pn+1);
658 ACG::bsplineBasisDerivatives<Scalar>(ders_m, span_m, _u, _derm,
knotvector_m_.getKnotvector(), 0);
659 ACG::bsplineBasisDerivatives<Scalar>(ders_n, span_n, _v, _dern,
knotvector_n_.getKnotvector(), 0);
661 for (
int i = span_m[0]; i <= span_m[1]; i++)
662 for (
int j = span_n[0]; j <= span_n[1]; j++)
663 point += control_net_[i][j] * ders_m[i - span_m[0]] * ders_n[j - span_n[0]];
671 template <
class Po
intT>
682 Point normal( (derivu%derivv).normalize());
689 template <
class Po
intT>
690 typename BSplineSurfaceT<PointT>::Scalar
704 if ( fabs(_knotvector(_i+_n)-_knotvector(_i)) > 1e-6 )
705 fac1 = Scalar(_n) / (_knotvector(_i+_n)-_knotvector(_i));
708 if ( fabs(_knotvector(_i+_n+1)-_knotvector(_i+1)) > 1e-6 )
709 fac2 = Scalar(_n) / (_knotvector(_i+_n+1)-_knotvector(_i+1));
711 return (fac1*Nin1 - fac2*Nin2);
716 template <
class Po
intT>
717 typename BSplineSurfaceT<PointT>::Scalar
726 template <
class Po
intT>
727 typename BSplineSurfaceT<PointT>::Scalar
735 template <
class Po
intT>
736 typename BSplineSurfaceT<PointT>::Scalar
745 template <
class Po
intT>
746 typename BSplineSurfaceT<PointT>::Scalar
754 template <
class Po
intT>
764 template <
class Po
intT>
774 template <
class Po
intT>
789 return Vec2i(i, i+1);
794 template <
class Po
intT>
809 return Vec2i(i, i+1);
void delete_vector_n(unsigned int _n)
Deletes an m control point vector.
void resize(unsigned int _m, unsigned int _n)
Resizes the spline struct.
Point normalSurfacePoint(double _u, double _v)
Returns the normal of a spline surface.
VectorT< signed int, 2 > Vec2i
Point surfacePoint_rec(double _u, double _v)
Evaluates a spline surface at parameters _u and _v.
int degree_m() const
Returns the spline degree in m direction.
unsigned int dimm_
number of control points in m direction
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.
ACG::Vec2i spanm(double _t)
Returns the basis functions which are unequal to zero at parameter u.
Scalar loweru()
Returns the lower u parameter.
Namespace providing different geometric functions concerning angles.
Scalar upperv()
Returns the upper v parameter.
unsigned int n_control_points_n() const
Returns the number of controlpoints in n direction.
void add_vector_n(const std::vector< Point > &_control_polygon)
Adds a control point m-vector.
Knotvector knotvector_m_
Knotvector in m direction.
void set_degree(unsigned int _degm, unsigned int _degn)
Sets the degree of the spline surface.
ACG::Vec2i spann(double _t)
Returns the basis functions which are unequal to zero at parameter v.
ACG::Vec2i interval_n(double _t)
Returns the index of the knots v and v+1 such that t in [v, v+1)
unsigned int n_control_points_m() const
Returns the number of controlpoints in m direction.
void createKnots()
Creates interpolating knotvectors 0...0, 1, 2, ..., n...n.
ACG::Vec2i interval_m(double _t)
Returns the index of the knots u and u+1 such that t in [u, u+1)
Point surfacePoint(double _u, double _v)
Evaluates a spline surface at parameters _u and _v.
BSplineSurfaceT(unsigned int _degm=3, unsigned int _degn=3)
Constructor.
Vec2i bsplineSpan(Scalar _t, int _degree, const std::vector< Scalar > &_knots)
Find the span of a parameter value.
void add_vector_m(const std::vector< Point > &_control_polygon)
Adds a control point n-vector.
void set_knots_m(std::vector< Scalar > _knots)
Set the knotvector of the bspline surface in m direction.
void insert_vector_n(const std::vector< Point > &_control_polygon, unsigned int _n)
Inserts an m control point vector.
void set_knots_n(std::vector< Scalar > _knots)
Set the knotvector of the bspline surface in n direction.
Knotvector get_knotvector_m()
Get the knotvector in m direction.
PropertyNet cpselections_
list of control point properties
unsigned int degree_n_
Spline degree in n direction.
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.
void reset_control_net()
Clears the control net.
Scalar lowerv()
Returns the lower v parameter.
void delete_vector_m(unsigned int _m)
Deletes an n control point vector.
unsigned int dimn_
number of control points in n direction
Scalar upperu()
Returns the upper u parameter.
void insert_knot_m(double _t)
Insert a knot i in m direction without changing the surface.
Knotvector knotvector_n_
Knotvector in n direction.
PropertyNet eselections_
list of edge properties
void insert_vector_m(const std::vector< Point > &_control_polygon, unsigned int _m)
Inserts an n control point vector.
void surfacePointNormal(Point &_pt, Point &_normal, double _u, double _v)
Evaluates a spline surface at parameters _u and _v.
void get_vector_n(std::vector< Point > &_control_polygon, unsigned int _n)
Returns an m ctrPointVector.
int degree_n() const
Returns the spline degree in n direction.
Scalar basisFunction(Knotvector &_knotvector, int _i, int _n, double _t)
A Spline Basis Function.
void insert_knot_n(double _t)
Insert a knot i in n direction without changing the surface.
Knotvector get_knotvector_n()
Get the knotvector in n direction.
Point derivativeSurfacePoint(double _u, double _v, int _derm, int _dern)
Returns the _derm'th derivative of a spline surface.
unsigned int degree_m_
Spline degree in m direction.
Scalar derivativeBasisFunction(Knotvector &_knotvector, int _i, int _n, double _t, int _der)
Derivative of a Spline Basis Function.