NGL  6.5
The NCCA Graphics Library
BezierCurve.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 Jon Macey
3 
4  This program is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17 //----------------------------------------------------------------------------------------------------------------------
20 //----------------------------------------------------------------------------------------------------------------------
21 #include "BezierCurve.h"
22 #include <iostream>
23 namespace ngl
24 {
25 //----------------------------------------------------------------------------------------------------------------------
27 {
28  m_numCP=0;
29  m_degree=0;
30  m_order=m_degree+1;
32  m_lod=20;
33  m_listIndex=0;
34  m_vaoCurve=0;
35  m_vaoPoints=0;
36 }
37 //----------------------------------------------------------------------------------------------------------------------
38 void BezierCurve::createKnots() noexcept
39 {
40  for(unsigned int i=0; i<m_numKnots; ++i)
41  {
42  m_knots.push_back( (i<(m_numKnots/2)) ? 0.0f : 1.0f);
43  }
44 }
45 
46 //----------------------------------------------------------------------------------------------------------------------
48 {
49  m_order=_c.m_order;
50  m_lod=_c.m_lod;
51  m_numCP=_c.m_numCP;
52  m_degree=_c.m_degree;
53  m_numKnots=_c.m_numKnots;
54  m_cp=_c.m_cp;
55  m_knots=_c.m_knots;
56  m_vaoCurve=0;
57  m_vaoPoints=0;
58 
59 }
60 
61 //----------------------------------------------------------------------------------------------------------------------
62 BezierCurve::BezierCurve( Real const *_p, unsigned int _nPoints ) noexcept
63 {
64  for(unsigned int i=0; i<_nPoints; i+=3)
65  {
66  m_cp.push_back(Vec3(_p[i],_p[i+1],_p[i+2]));
67  }
68  m_numCP=_nPoints/3;
69  m_degree=_nPoints/3;
70  m_order=m_degree+1;
72  m_lod=20;
73  createKnots();
74  m_vaoCurve=0;
75  m_vaoPoints=0;
76 
77 }
78 
79 //----------------------------------------------------------------------------------------------------------------------
80 BezierCurve::BezierCurve(const Vec3 *_p, unsigned int _nPoints, Real const *_k, unsigned int _nKnots ) noexcept
81 {
82  m_numCP=_nPoints;
83  m_degree=_nPoints;
84  m_order=m_degree+1;
85  m_numKnots=_nKnots; //m_numCP+m_order;
86  m_lod=20;
87  for(unsigned int i=0; i<m_numCP; ++i)
88  {
89  m_cp.push_back(Vec3(_p[i]));
90  }
91  for(unsigned int i=0; i<_nKnots; ++i)
92  {
93  m_knots.push_back(_k[i]);
94  }
95  m_vaoCurve=0;
96  m_vaoPoints=0;
97 }
98 
99 //----------------------------------------------------------------------------------------------------------------------
101 {
102  m_cp.clear();
103  m_knots.clear();
104  if(m_vaoCurve!=0 && m_vaoPoints!=0)
105  {
106  m_vaoCurve->unbind();
108  m_vaoPoints->unbind();
110  }
111 }
112 
113 //----------------------------------------------------------------------------------------------------------------------
114 Real BezierCurve::coxDeBoor( Real _u,unsigned int _i, unsigned int _k, const std::vector <Real> &_knots ) const noexcept
115 {
116  if(_k==1)
117  {
118  if( _knots[_i] <= _u && _u <= _knots[_i+1] )
119  {
120  return 1.0f;
121  }
122  return 0.0f;
123  }
124  Real Den1 = _knots[_i+_k-1] - _knots[_i];
125  Real Den2 = _knots[_i+_k] - _knots[_i+1];
126  Real Eq1=0,Eq2=0;
127  if(Den1>0)
128  {
129  Eq1 = ((_u-_knots[_i]) / Den1) * coxDeBoor(_u,_i,_k-1,_knots);
130  }
131  if(Den2>0)
132  {
133  Eq2 = (_knots[_i+_k]-_u) / Den2 * coxDeBoor(_u,_i+1,_k-1,_knots);
134  }
135  return Eq1+Eq2;
136 }
137 
138 
139 //----------------------------------------------------------------------------------------------------------------------
140 void BezierCurve::drawControlPoints()const noexcept
141 {
142 
143  m_vaoPoints->bind();
145  m_vaoPoints->draw();
146  m_vaoPoints->unbind();
147 
148 }
149 
150 //----------------------------------------------------------------------------------------------------------------------
151 void BezierCurve::drawHull()const noexcept
152 {
153  m_vaoPoints->bind();
155  m_vaoPoints->draw();
156  m_vaoPoints->unbind();
157  }
158 
159 //----------------------------------------------------------------------------------------------------------------------
160 void BezierCurve::draw() const noexcept
161 {
162 m_vaoCurve->bind();
163 m_vaoCurve->draw();
164 m_vaoCurve->unbind();
165 }
166 
167 //----------------------------------------------------------------------------------------------------------------------
168 Vec3 BezierCurve::getPointOnCurve( Real _value ) const noexcept
169 {
170  Vec3 p;
171 
172  // sum the effect of all CV's on the curve at this point to
173  // get the evaluated curve point
174  //
175  for(unsigned int i=0;i!=m_numCP;++i)
176  {
177  // calculate the effect of this point on the curve
178  Real val = coxDeBoor(_value,i,m_degree /*was m_order */,m_knots);
179 
180  if(val>0.001f)
181  {
182  // sum effect of CV on this part of the curve
183  p+=val*m_cp[i];
184  }
185  }
186 
187  return p;
188 }
189 
190 
191 
192 
193 //----------------------------------------------------------------------------------------------------------------------
194 void BezierCurve::addPoint( const Vec3 &_p ) noexcept
195 {
196  m_cp.push_back(_p);
197  ++m_numCP;
198  ++m_degree;
199  m_order=m_degree+1;
201  #ifdef DEBUG
202  std::cout <<"Added "<<m_numCP<<" m_degree "<<m_degree<<" m_numKnots"<<m_numKnots<<" m_order "<<m_order<<std::endl;
203  #endif
204 }
205 
206 //----------------------------------------------------------------------------------------------------------------------
207 void BezierCurve::addPoint( Real _x, Real _y, Real _z) noexcept
208 {
209  m_cp.push_back(Vec3(_x,_y,_z));
210  ++m_numCP;
211  ++m_degree;
212  m_order=m_degree+1;
213 
215  #ifdef DEBUG
216  std::cout <<"Added "<<m_numCP<<" m_degree "<<m_degree<<" m_numKnots"<<m_numKnots<<" m_order "<<m_order<<std::endl;
217  #endif
218 }
219 //----------------------------------------------------------------------------------------------------------------------
220 void BezierCurve::addKnot(Real _k) noexcept
221 {
222  m_knots.push_back(_k);
224 }
225 
226 void BezierCurve::createVAO() noexcept
227 {
228  if(m_vaoCurve!=0 && m_vaoPoints!=0)
229  {
230  m_vaoCurve->unbind();
232  //delete m_vaoCurve;
233  m_vaoPoints->unbind();
235  //delete m_vaoPoints;
236  }
237 
239  m_vaoPoints->bind();
240  size_t size=m_cp.size();
241  std::vector <Vec3> points(size);
242  for(size_t i=0;i<size;++i)
243  {
244  points[i].set(m_cp[i]);
245  }
246  m_vaoPoints->setData(SimpleVAO::VertexData(m_numCP*sizeof(Vec3),points[0].m_x));
249  m_vaoPoints->unbind();
250 
251 
253  m_vaoCurve->bind();
254 
255  std::vector <Vec3> lines(m_lod);
256  for(unsigned int i=0;i!=m_lod;++i)
257  {
258  Real t = m_knots[m_numKnots-1] * i / static_cast<Real>(m_lod-1);
259 
260  if(i==m_lod-1)
261  {
262  t-=0.001f;
263  }
264  lines[i].set(getPointOnCurve(t));
265  }
266  m_vaoCurve->setData(SimpleVAO::VertexData(m_lod*sizeof(Vec3),lines[0].m_x));
269  m_vaoCurve->unbind();
270 
271 }
272 
273 //----------------------------------------------------------------------------------------------------------------------
274 
275 } // end ngl namespace
276 
277 
Generic Bezier Curve Class allowing the user to generate basic curves using a number of different con...
Definition: BezierCurve.h:45
static AbstractVAO * createVAO(const std::string &_type, GLenum _mode=GL_TRIANGLES)
Definition: VAOFactory.cpp:19
void drawHull() const noexcept
Draw the control hull.
unsigned int m_lod
The level of detail used to calculate how much detail to draw.
Definition: BezierCurve.h:156
std::vector< Vec3 > m_cp
the contol points for the curve
Definition: BezierCurve.h:172
GLuint const GLfloat * val
Definition: glew.h:2797
GLdouble GLdouble t
Definition: glew.h:1401
void createVAO() noexcept
set the Level of Detail for Drawing
simple Vec3 encapsulates a 3 float object like glsl vec3 but not maths use the Vec3 class for maths a...
Definition: Vec3.h:51
implementation files for RibExport class
Definition: AABB.cpp:22
void setVertexAttributePointer(GLuint _id, GLint _size, GLenum _type, GLsizei _stride, unsigned int _dataOffset, bool _normalise=false)
set the generic vertex attribute pointer data usually this method will do however the user may occasi...
Definition: AbstractVAO.cpp:36
void addKnot(Real _k) noexcept
add a knot value to the curve
virtual void removeVAO()=0
this will clean up the VAO and associated data, it is the users responsibility to do this usually thi...
PRECISION Real
create a variable called Real which is the main data type we use (GLfloat for most cases) ...
Definition: Types.h:127
Vec3 getPointOnCurve(Real _value) const noexcept
get a point on the curve in the range of 0 - 1 based on the control points
BezierCurve() noexcept
default ctor sets initial values for Curve to be used with AddPoint , AddKnot etc ...
Definition: BezierCurve.cpp:26
std::vector< Real > m_knots
the knot vector for the curve
Definition: BezierCurve.h:176
void setMode(const GLenum &_mode)
set the draw mode
Definition: AbstractVAO.cpp:17
void createKnots() noexcept
create a knot vector array based as an Open Vector (half 0.0 half 1.0)
Definition: BezierCurve.cpp:38
void setNumIndices(size_t _s)
the number of indices to draw in the array. It may be that the draw routine can overide this at anoth...
Definition: AbstractVAO.h:91
#define GL_POINTS
Definition: glew.h:319
GLfloat GLfloat p
Definition: glew.h:16654
void unbind()
unbind the VAO by binding default 0
Definition: AbstractVAO.cpp:29
void bind()
bind the VAO so it can be used.
Definition: AbstractVAO.cpp:23
unsigned int m_degree
The degree of the curve, Calculated from the Number of Control Points.
Definition: BezierCurve.h:164
virtual void setData(const VertexData &_data)=0
this method is used to set the data in the VAO, we have a base data type of VertexData above...
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
Definition: glew.h:3458
unsigned int m_numCP
The ammount of Control Points in the Curve.
Definition: BezierCurve.h:160
unsigned int m_order
The Order of the Curve = Degree +1.
Definition: BezierCurve.h:152
GLuint m_listIndex
the display list index created from glCreateLists
Definition: BezierCurve.h:148
void draw() const noexcept
Draw method to draw the curve Note this will be slow as it calls the CoxDeBoor function to calculate ...
AbstractVAO * m_vaoPoints
a vertex array object for our point drawing
Definition: BezierCurve.h:184
~BezierCurve() noexcept
destructor
virtual void draw() const =0
this is the draw method for the VAO the user must implement this per VAO data, usually this will be a...
unsigned int m_numKnots
The knot vector always has as many values as the numer of verts (cp) + the degree.
Definition: BezierCurve.h:168
Real coxDeBoor(Real _u, unsigned int _i, unsigned int _k, const std::vector< Real > &_knots) const noexcept
implementation of the CoxDeBoor algorithm for Bezier Curves borrowed from Rob Bateman&#39;s example and m...
GLsizeiptr size
Definition: glew.h:1684
#define GL_FLOAT
Definition: glew.h:642
void drawControlPoints() const noexcept
draw the control points
void addPoint(const Vec3 &_p) noexcept
add a control point to the Curve
#define GL_LINE_STRIP
Definition: glew.h:328
AbstractVAO * m_vaoCurve
a vertex array object for our curve drawing
Definition: BezierCurve.h:180
basic BezierCurve using CoxDeBoor algorithm
GLclampf f
Definition: glew.h:3511