GteNURBSSurface.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.2 (2016/07/06)
7 
8 #pragma once
9 
10 #include <Mathematics/GteVector.h>
13 
14 namespace gte
15 {
16 
17 template <int N, typename Real>
18 class NURBSSurface : public ParametricSurface<N, Real>
19 {
20 public:
21  // Construction. If the input controls is non-null, a copy is made of
22  // the controls. To defer setting the control points or weights, pass
23  // null pointers and later access the control points or weights via
24  // GetControls(), GetWeights(), SetControl(), or SetWeight() member
25  // functions. The 'controls' and 'weights' must be stored in row-major
26  // order, attribute[i0 + numControls0*i1]. As a 2D array, this
27  // corresponds to attribute2D[i1][i0]. To validate construction, create
28  // an object as shown:
29  // NURBSSurface<N, Real> surface(parameters);
30  // if (!surface) { <constructor failed, handle accordingly>; }
32  Vector<N, Real> const* controls, Real const* weights);
33 
34  // Member access. The index 'dim' must be in {0,1}.
35  inline BasisFunction<Real> const& GetBasisFunction(int dim) const;
36  inline int GetNumControls(int dim) const;
37  inline Vector<N, Real> const* GetControls() const;
38  inline Vector<N, Real>* GetControls();
39  inline Real const* GetWeights() const;
40  inline Real* GetWeights();
41  void SetControl(int i0, int i1, Vector<N, Real> const& control);
42  Vector<N, Real> const& GetControl(int i0, int i1) const;
43  void SetWeight(int i0, int i1, Real weight);
44  Real const& GetWeight(int i0, int i1) const;
45 
46  // Evaluation of the surface. The function supports derivative
47  // calculation through order 2; that is, maxOrder <= 2 is required. If
48  // you want only the position, pass in maxOrder of 0. If you want the
49  // position and first-order derivatives, pass in maxOrder of 1, and so on.
50  // The output 'values' are ordered as: position X; first-order derivatives
51  // dX/du, dX/dv; second-order derivatives d2X/du2, d2X/dudv, d2X/dv2.
52  virtual void Evaluate(Real u, Real v, unsigned int maxOrder,
53  Vector<N, Real> values[6]) const;
54 
55 private:
56  // Support for Evaluate(...).
57  void Compute(unsigned int uOrder, unsigned int vOrder, int iumin,
58  int iumax, int ivmin, int ivmax, Vector<N, Real>& X, Real& w) const;
59 
60  std::array<BasisFunction<Real>, 2> mBasisFunction;
61  std::array<int, 2> mNumControls;
62  std::vector<Vector<N, Real>> mControls;
63  std::vector<Real> mWeights;
64 };
65 
66 
67 template <int N, typename Real>
69  Vector<N, Real> const* controls, Real const* weights)
70  :
71  ParametricSurface<N, Real>((Real)0, (Real)1, (Real)0, (Real)1, true)
72 {
73  for (int i = 0; i < 2; ++i)
74  {
75  mNumControls[i] = input[i].numControls;
76  mBasisFunction[i].Create(input[i]);
77  if (!mBasisFunction[i])
78  {
79  // Errors were already generated during construction of the
80  // basis functions.
81  return;
82  }
83  }
84 
85  // The mBasisFunction stores the domain but so does ParametricCurve.
86  this->mUMin = mBasisFunction[0].GetMinDomain();
87  this->mUMax = mBasisFunction[0].GetMaxDomain();
88  this->mVMin = mBasisFunction[1].GetMinDomain();
89  this->mVMax = mBasisFunction[1].GetMaxDomain();
90 
91  // The replication of control points for periodic splines is avoided
92  // by wrapping the i-loop index in Evaluate.
93  int numControls = mNumControls[0] * mNumControls[1];
94  mControls.resize(numControls);
95  mWeights.resize(numControls);
96  if (controls)
97  {
98  std::copy(controls, controls + numControls, mControls.begin());
99  }
100  else
101  {
102  memset(mControls.data(), 0, mControls.size() * sizeof(mControls[0]));
103  }
104  if (weights)
105  {
106  std::copy(weights, weights + numControls, mWeights.begin());
107  }
108  else
109  {
110  memset(mWeights.data(), 0, mWeights.size() * sizeof(mWeights[0]));
111  }
112  this->mConstructed = true;
113 }
114 
115 template <int N, typename Real>
117 {
118  return mBasisFunction[dim];
119 }
120 
121 template <int N, typename Real>
123 {
124  return mNumControls[dim];
125 }
126 
127 template <int N, typename Real>
129 {
130  return mControls.data();
131 }
132 
133 template <int N, typename Real>
135 {
136  return mControls.data();
137 }
138 
139 template <int N, typename Real>
141 {
142  return mWeights.data();
143 }
144 
145 template <int N, typename Real>
147 {
148  return mWeights.data();
149 }
150 
151 template <int N, typename Real>
152 void NURBSSurface<N, Real>::SetControl(int i0, int i1, Vector<N, Real> const& control)
153 {
154  if (0 <= i0 && i0 < GetNumControls(0) && 0 <= i1 && i1 < GetNumControls(1))
155  {
156  mControls[i0 + mNumControls[0] * i1] = control;
157  }
158 }
159 
160 template <int N, typename Real>
162 {
163  if (0 <= i0 && i0 < GetNumControls(0) && 0 <= i1 && i1 < GetNumControls(1))
164  {
165  return mControls[i0 + mNumControls[0] * i1];
166  }
167  else
168  {
169  return mControls[0];
170  }
171 }
172 
173 template <int N, typename Real>
174 void NURBSSurface<N, Real>::SetWeight(int i0, int i1, Real weight)
175 {
176  if (0 <= i0 && i0 < GetNumControls(0) && 0 <= i1 && i1 < GetNumControls(1))
177  {
178  mWeights[i0 + mNumControls[0] * i1] = weight;
179  }
180 }
181 
182 template <int N, typename Real>
183 Real const& NURBSSurface<N, Real>::GetWeight(int i0, int i1) const
184 {
185  if (0 <= i0 && i0 < GetNumControls(0) && 0 <= i1 && i1 < GetNumControls(1))
186  {
187  return mWeights[i0 + mNumControls[0] * i1];
188  }
189  else
190  {
191  return mWeights[0];
192  }
193 }
194 
195 template <int N, typename Real>
196 void NURBSSurface<N, Real>::Evaluate(Real u, Real v, unsigned int maxOrder,
197  Vector<N, Real> values[6]) const
198 {
199  if (!this->mConstructed)
200  {
201  // Errors were already generated during construction.
202  for (int i = 0; i < 6; ++i)
203  {
204  values[i].MakeZero();
205  }
206  return;
207  }
208 
209  int iumin, iumax, ivmin, ivmax;
210  mBasisFunction[0].Evaluate(u, maxOrder, iumin, iumax);
211  mBasisFunction[1].Evaluate(v, maxOrder, ivmin, ivmax);
212 
213  // Compute position.
214  Vector<N, Real> X;
215  Real w;
216  Compute(0, 0, iumin, iumax, ivmin, ivmax, X, w);
217  Real invW = ((Real)1) / w;
218  values[0] = invW * X;
219 
220  if (maxOrder >= 1)
221  {
222  // Compute first-order derivatives.
223  Vector<N, Real> XDerU;
224  Real wDerU;
225  Compute(1, 0, iumin, iumax, ivmin, ivmax, XDerU, wDerU);
226  values[1] = invW * (XDerU - wDerU * values[0]);
227 
228  Vector<N, Real> XDerV;
229  Real wDerV;
230  Compute(0, 1, iumin, iumax, ivmin, ivmax, XDerV, wDerV);
231  values[2] = invW * (XDerV - wDerV * values[0]);
232 
233  if (maxOrder >= 2)
234  {
235  // Compute second-order derivatives.
236  Vector<N, Real> XDerUU;
237  Real wDerUU;
238  Compute(2, 0, iumin, iumax, ivmin, ivmax, XDerUU, wDerUU);
239  values[3] = invW * (XDerUU - ((Real)2) * wDerU * values[1] -
240  wDerUU * values[0]);
241 
242  Vector<N, Real> XDerUV;
243  Real wDerUV;
244  Compute(1, 1, iumin, iumax, ivmin, ivmax, XDerUV, wDerUV);
245  values[4] = invW * (XDerUV - wDerU * values[2] - wDerV * values[1]
246  - wDerUV * values[0]);
247 
248  Vector<N, Real> XDerVV;
249  Real wDerVV;
250  Compute(0, 2, iumin, iumax, ivmin, ivmax, XDerVV, wDerVV);
251  values[5] = invW * (XDerVV - ((Real)2) * wDerV * values[2] -
252  wDerVV * values[0]);
253  }
254  }
255 }
256 
257 template <int N, typename Real>
258 void NURBSSurface<N, Real>::Compute(unsigned int uOrder, unsigned int vOrder,
259  int iumin, int iumax, int ivmin, int ivmax, Vector<N, Real>& X, Real& w) const
260 {
261  // The j*-indices introduce a tiny amount of overhead in order to handle
262  // both aperiodic and periodic splines. For aperiodic splines, j* = i*
263  // always.
264 
265  int const numControls0 = mNumControls[0];
266  int const numControls1 = mNumControls[1];
267  X.MakeZero();
268  w = (Real)0;
269  for (int iv = ivmin; iv <= ivmax; ++iv)
270  {
271  Real tmpv = mBasisFunction[1].GetValue(vOrder, iv);
272  int jv = (iv >= numControls1 ? iv - numControls1 : iv);
273  for (int iu = iumin; iu <= iumax; ++iu)
274  {
275  Real tmpu = mBasisFunction[0].GetValue(uOrder, iu);
276  int ju = (iu >= numControls0 ? iu - numControls0 : iu);
277  int index = ju + numControls0 * jv;
278  Real tmp = tmpu * tmpv * mWeights[index];
279  X += tmp * mControls[index];
280  w += tmp;
281  }
282  }
283 }
284 
285 }
void MakeZero()
Definition: GteVector.h:279
const GLbyte * weights
Definition: glext.h:4455
void SetWeight(int i0, int i1, Real weight)
virtual void Evaluate(Real u, Real v, unsigned int maxOrder, Vector< N, Real > values[6]) const
GLuint GLuint GLfloat weight
Definition: glext.h:9668
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1597
BasisFunction< Real > const & GetBasisFunction(int dim) const
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:852
std::array< BasisFunction< Real >, 2 > mBasisFunction
std::vector< Vector< N, Real > > mControls
std::array< int, 2 > mNumControls
Real const * GetWeights() const
Real const & GetWeight(int i0, int i1) const
const GLdouble * v
Definition: glcorearb.h:832
void SetControl(int i0, int i1, Vector< N, Real > const &control)
GLenum GLenum GLenum input
Definition: glext.h:9913
GLuint index
Definition: glcorearb.h:781
NURBSSurface(BasisFunctionInput< Real > const input[2], Vector< N, Real > const *controls, Real const *weights)
int GetNumControls(int dim) const
void Compute(unsigned int uOrder, unsigned int vOrder, int iumin, int iumax, int ivmin, int ivmax, Vector< N, Real > &X, Real &w) const
std::vector< Real > mWeights
Vector< N, Real > const & GetControl(int i0, int i1) const
Vector< N, Real > const * GetControls() const


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:01