GteNURBSVolume.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>
12 
13 namespace gte
14 {
15 
16 template <int N, typename Real>
18 {
19 public:
20  // Construction. If the input controls is non-null, a copy is made of
21  // the controls. To defer setting the control points or weights, pass
22  // null pointers and later access the control points or weights via
23  // GetControls(), GetWeights(), SetControl(), or SetWeight() member
24  // functions. The 'controls' and 'weights' must be stored in
25  // lexicographical order, attribute[i0 + numControls0*(i1 + numControls1*i2)].
26  // As a 3D array, this corresponds to attribute3D[i2][i1][i0].
28  Vector<N, Real> const* controls, Real const* weights);
29 
30  // To validate construction, create an object as shown:
31  // NURBSVolume<N, Real> volume(parameters);
32  // if (!volume) { <constructor failed, handle accordingly>; }
33  inline operator bool() const;
34 
35  // Member access. The index 'dim' must be in {0,1,2}.
36  inline BasisFunction<Real> const& GetBasisFunction(int dim) const;
37  inline Real GetMinDomain(int dim) const;
38  inline Real GetMaxDomain(int dim) const;
39  inline int GetNumControls(int dim) const;
40  inline Vector<N, Real> const* GetControls() const;
41  inline Vector<N, Real>* GetControls();
42  inline Real const* GetWeights() const;
43  inline Real* GetWeights();
44 
45  // Evaluation of the volume. The function supports derivative
46  // calculation through order 2; that is, maxOrder <= 2 is required. If
47  // you want only the position, pass in maxOrder of 0. If you want the
48  // position and first-order derivatives, pass in maxOrder of 1, and so on.
49  // The output 'values' are ordered as: position X; first-order derivatives
50  // dX/du, dX/dv, dX/dw; second-order derivatives d2X/du2, d2X/dv2,
51  // d2X/dw2, d2X/dudv, d2X/dudw, d2X/dvdw.
52  void Evaluate(Real u, Real v, Real w, unsigned int maxOrder,
53  Vector<N, Real> values[10]) const;
54 
55 private:
56  // Support for Evaluate(...).
57  void Compute(unsigned int uOrder, unsigned int vOrder,
58  unsigned int wOrder, int iumin, int iumax, int ivmin, int ivmax,
59  int iwmin, int iwmax, Vector<N, Real>& X, Real& h) const;
60 
61  std::array<BasisFunction<Real>, 3> mBasisFunction;
62  std::array<int, 3> mNumControls;
63  std::vector<Vector<N, Real>> mControls;
64  std::vector<Real> mWeights;
66 };
67 
68 
69 template <int N, typename Real>
71  Vector<N, Real> const* controls, Real const* weights)
72  :
73  mConstructed(false)
74 {
75  for (int i = 0; i < 3; ++i)
76  {
77  mNumControls[i] = input[i].numControls;
78  mBasisFunction[i].Create(input[i]);
79  if (!mBasisFunction[i])
80  {
81  // Errors were already generated during construction of the
82  // basis functions.
83  return;
84  }
85  }
86 
87  // The replication of control points for periodic splines is avoided
88  // by wrapping the i-loop index in Evaluate.
89  int numControls = mNumControls[0] * mNumControls[1] * mNumControls[2];
90  mControls.resize(numControls);
91  mWeights.resize(numControls);
92  if (controls)
93  {
94  std::copy(controls, controls + numControls, mControls.begin());
95  }
96  else
97  {
98  memset(mControls.data(), 0, mControls.size() * sizeof(mControls[0]));
99  }
100  if (weights)
101  {
102  std::copy(weights, weights + numControls, mWeights.begin());
103  }
104  else
105  {
106  memset(mWeights.data(), 0, mWeights.size() * sizeof(mWeights[0]));
107  }
108  mConstructed = true;
109 }
110 
111 template <int N, typename Real>
113 {
114  return mConstructed;
115 }
116 
117 template <int N, typename Real>
119 const
120 {
121  return mBasisFunction[dim];
122 }
123 
124 template <int N, typename Real>
126 {
127  return mBasisFunction[dim].GetMinDomain();
128 }
129 
130 template <int N, typename Real>
132 {
133  return mBasisFunction[dim].GetMaxDomain();
134 }
135 
136 template <int N, typename Real>
138 {
139  return mNumControls[dim];
140 }
141 
142 template <int N, typename Real>
144 {
145  return mControls.data();
146 }
147 
148 template <int N, typename Real>
150 {
151  return mControls.data();
152 }
153 
154 template <int N, typename Real>
156 {
157  return mWeights.data();
158 }
159 
160 template <int N, typename Real>
162 {
163  return mWeights.data();
164 }
165 
166 template <int N, typename Real>
167 void NURBSVolume<N, Real>::Evaluate(Real u, Real v, Real w,
168  unsigned int maxOrder, Vector<N, Real> values[10]) const
169 {
170  if (!mConstructed)
171  {
172  // Errors were already generated during construction.
173  for (int i = 0; i < 10; ++i)
174  {
175  values[i].MakeZero();
176  }
177  return;
178  }
179 
180  int iumin, iumax, ivmin, ivmax, iwmin, iwmax;
181  mBasisFunction[0].Evaluate(u, maxOrder, iumin, iumax);
182  mBasisFunction[1].Evaluate(v, maxOrder, ivmin, ivmax);
183  mBasisFunction[2].Evaluate(w, maxOrder, iwmin, iwmax);
184 
185  // Compute position.
186  Vector<N, Real> X;
187  Real h;
188  Compute(0, 0, 0, iumin, iumax, ivmin, ivmax, iwmin, iwmax, X, h);
189  Real invH = ((Real)1) / h;
190  values[0] = invH * X;
191 
192  if (maxOrder >= 1)
193  {
194  // Compute first-order derivatives.
195  Vector<N, Real> XDerU;
196  Real hDerU;
197  Compute(1, 0, 0, iumin, iumax, ivmin, ivmax, iwmin, iwmax,
198  XDerU, hDerU);
199  values[1] = invH * (XDerU - hDerU * values[0]);
200 
201  Vector<N, Real> XDerV;
202  Real hDerV;
203  Compute(0, 1, 0, iumin, iumax, ivmin, ivmax, iwmin, iwmax,
204  XDerV, hDerV);
205  values[2] = invH * (XDerV - hDerV * values[0]);
206 
207  Vector<N, Real> XDerW;
208  Real hDerW;
209  Compute(0, 0, 1, iumin, iumax, ivmin, ivmax, iwmin, iwmax,
210  XDerW, hDerW);
211  values[3] = invH * (XDerW - hDerW * values[0]);
212 
213  if (maxOrder >= 2)
214  {
215  // Compute second-order derivatives.
216  Vector<N, Real> XDerUU;
217  Real hDerUU;
218  Compute(2, 0, 0, iumin, iumax, ivmin, ivmax, iwmin, iwmax,
219  XDerUU, hDerUU);
220  values[4] = invH * (XDerUU - ((Real)2) * hDerU * values[1] -
221  hDerUU * values[0]);
222 
223  Vector<N, Real> XDerVV;
224  Real hDerVV;
225  Compute(0, 2, 0, iumin, iumax, ivmin, ivmax, iwmin, iwmax,
226  XDerVV, hDerVV);
227  values[5] = invH * (XDerVV - ((Real)2) * hDerV * values[2] -
228  hDerVV * values[0]);
229 
230  Vector<N, Real> XDerWW;
231  Real hDerWW;
232  Compute(0, 0, 2, iumin, iumax, ivmin, ivmax, iwmin, iwmax,
233  XDerWW, hDerWW);
234  values[6] = invH * (XDerWW - ((Real)2) * hDerW * values[3] -
235  hDerWW * values[0]);
236 
237  Vector<N, Real> XDerUV;
238  Real hDerUV;
239  Compute(1, 1, 0, iumin, iumax, ivmin, ivmax, iwmin, iwmax,
240  XDerUV, hDerUV);
241  values[7] = invH * (XDerUV - hDerU * values[2]
242  - hDerV * values[1] - hDerUV * values[0]);
243 
244  Vector<N, Real> XDerUW;
245  Real hDerUW;
246  Compute(1, 0, 1, iumin, iumax, ivmin, ivmax, iwmin, iwmax,
247  XDerUW, hDerUW);
248  values[8] = invH * (XDerUW - hDerU * values[3]
249  - hDerW * values[1] - hDerUW * values[0]);
250 
251  Vector<N, Real> XDerVW;
252  Real hDerVW;
253  Compute(0, 1, 1, iumin, iumax, ivmin, ivmax, iwmin, iwmax,
254  XDerVW, hDerVW);
255  values[9] = invH * (XDerVW - hDerV * values[3]
256  - hDerW * values[2] - hDerVW * values[0]);
257  }
258  }
259 }
260 
261 template <int N, typename Real>
262 void NURBSVolume<N, Real>::Compute(unsigned int uOrder, unsigned int vOrder,
263  unsigned int wOrder, int iumin, int iumax, int ivmin, int ivmax,
264  int iwmin, int iwmax, Vector<N, Real>& X, Real& h) const
265 {
266  // The j*-indices introduce a tiny amount of overhead in order to handle
267  // both aperiodic and periodic splines. For aperiodic splines, j* = i*
268  // always.
269 
270  int const numControls0 = mNumControls[0];
271  int const numControls1 = mNumControls[1];
272  int const numControls2 = mNumControls[2];
273  X.MakeZero();
274  h = (Real)0;
275  for (int iw = iwmin; iw <= iwmax; ++iw)
276  {
277  Real tmpw = mBasisFunction[2].GetValue(wOrder, iw);
278  int jw = (iw >= numControls2 ? iw - numControls2 : iw);
279  for (int iv = ivmin; iv <= ivmax; ++iv)
280  {
281  Real tmpv = mBasisFunction[1].GetValue(vOrder, iv);
282  Real tmpvw = tmpv * tmpw;
283  int jv = (iv >= numControls1 ? iv - numControls1 : iv);
284  for (int iu = iumin; iu <= iumax; ++iu)
285  {
286  Real tmpu = mBasisFunction[0].GetValue(uOrder, iu);
287  int ju = (iu >= numControls0 ? iu - numControls0 : iu);
288  int index = ju + numControls0*(jv + numControls1*jw);
289  Real tmp = (tmpu * tmpvw) * mWeights[index];
290  X += tmp * mControls[index];
291  h += tmp;
292  }
293  }
294  }
295 }
296 
297 }
void MakeZero()
Definition: GteVector.h:279
const GLbyte * weights
Definition: glext.h:4455
std::vector< Real > mWeights
Real const * GetWeights() const
void Evaluate(Real u, Real v, Real w, unsigned int maxOrder, Vector< N, Real > values[10]) const
std::array< int, 3 > mNumControls
NURBSVolume(BasisFunctionInput< Real > const input[3], Vector< N, Real > const *controls, Real const *weights)
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1597
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:852
std::vector< Vector< N, Real > > mControls
void Compute(unsigned int uOrder, unsigned int vOrder, unsigned int wOrder, int iumin, int iumax, int ivmin, int ivmax, int iwmin, int iwmax, Vector< N, Real > &X, Real &h) const
Real GetMaxDomain(int dim) const
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:1997
BasisFunction< Real > const & GetBasisFunction(int dim) const
const GLdouble * v
Definition: glcorearb.h:832
Vector< N, Real > const * GetControls() const
GLenum GLenum GLenum input
Definition: glext.h:9913
GLuint index
Definition: glcorearb.h:781
int GetNumControls(int dim) const
Real GetMinDomain(int dim) const
std::array< BasisFunction< Real >, 3 > mBasisFunction


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