GteBSplineVolume.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.1 (2016/06/26)
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, pass a null pointer
22  // and later access the control points via GetControls() or SetControl()
23  // member functions. The input 'controls' must be stored in
24  // lexicographical order, control[i0+numControls0*(i1+numControls1*i2)].
25  // As a 3D array, this corresponds to control3D[i2][i1][i0].
27  Vector<N, Real> const* controls);
28 
29  // To validate construction, create an object as shown:
30  // BSplineVolume<N, Real> volume(parameters);
31  // if (!volume) { <constructor failed, handle accordingly>; }
32  inline operator bool() const;
33 
34  // Member access. The index 'dim' must be in {0,1,2}.
35  inline BasisFunction<Real> const& GetBasisFunction(int dim) const;
36  inline Real GetMinDomain(int dim) const;
37  inline Real GetMaxDomain(int dim) const;
38  inline int GetNumControls(int dim) const;
39  inline Vector<N, Real> const* GetControls() const;
40  inline Vector<N, Real>* GetControls();
41  void SetControl(int i0, int i1, int i2, Vector<N, Real> const& control);
42  Vector<N, Real> const& GetControl(int i0, int i1, int i2) const;
43 
44  // Evaluation of the volume. The function supports derivative
45  // calculation through order 2; that is, maxOrder <= 2 is required. If
46  // you want only the position, pass in maxOrder of 0. If you want the
47  // position and first-order derivatives, pass in maxOrder of 1, and so on.
48  // The output 'values' are ordered as: position X; first-order derivatives
49  // dX/du, dX/dv, dX/dw; second-order derivatives d2X/du2, d2X/dv2,
50  // d2X/dw2, d2X/dudv, d2X/dudw, d2X/dvdw.
51  void Evaluate(Real u, Real v, Real w, unsigned int maxOrder,
52  Vector<N, Real> values[10]) const;
53 
54 private:
55  // Support for Evaluate(...).
56  Vector<N, Real> Compute(unsigned int uOrder, unsigned int vOrder,
57  unsigned int wOrder, int iumin, int iumax, int ivmin, int ivmax,
58  int iwmin, int iwmax) const;
59 
60  std::array<BasisFunction<Real>, 3> mBasisFunction;
61  std::array<int, 3> mNumControls;
62  std::vector<Vector<N, Real>> mControls;
64 };
65 
66 
67 template <int N, typename Real>
69  Vector<N, Real> const* controls)
70  :
71  mConstructed(false)
72 {
73  for (int i = 0; i < 3; ++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 replication of control points for periodic splines is avoided
86  // by wrapping the i-loop index in Evaluate.
87  int numControls = mNumControls[0] * mNumControls[1] * mNumControls[2];
88  mControls.resize(numControls);
89  if (controls)
90  {
91  std::copy(controls, controls + numControls, mControls.begin());
92  }
93  else
94  {
95  memset(mControls.data(), 0, mControls.size() * sizeof(mControls[0]));
96  }
97  mConstructed = true;
98 }
99 
100 template <int N, typename Real>
102 {
103  return mBasisFunction[dim];
104 }
105 
106 template <int N, typename Real>
108 {
109  return mBasisFunction[dim].GetMinDomain();
110 }
111 
112 template <int N, typename Real>
114 {
115  return mBasisFunction[dim].GetMaxDomain();
116 }
117 
118 template <int N, typename Real>
120 {
121  return mConstructed;
122 }
123 
124 template <int N, typename Real>
126 {
127  return mNumControls[dim];
128 }
129 
130 template <int N, typename Real>
132 {
133  return mControls.data();
134 }
135 
136 template <int N, typename Real>
138 {
139  return mControls.data();
140 }
141 
142 template <int N, typename Real>
143 void BSplineVolume<N, Real>::SetControl(int i0, int i1, int i2,
144  Vector<N, Real> const& control)
145 {
146  if (0 <= i0 && i0 < GetNumControls(0)
147  && 0 <= i1 && i1 < GetNumControls(1)
148  && 0 <= i2 && i2 < GetNumControls(2))
149  {
150  mControls[i0 + mNumControls[0] * (i1 + mNumControls[1] * i2)] = control;
151  }
152 }
153 
154 template <int N, typename Real>
155 Vector<N, Real> const& BSplineVolume<N, Real>::GetControl(int i0, int i1, int i2) const
156 {
157  if (0 <= i0 && i0 < GetNumControls(0)
158  && 0 <= i1 && i1 < GetNumControls(1)
159  && 0 <= i2 && i2 < GetNumControls(2))
160  {
161  return mControls[i0 + mNumControls[0] * (i1 + mNumControls[1] * i2)];
162  }
163  else
164  {
165  return mControls[0];
166  }
167 }
168 
169 template <int N, typename Real>
170 void BSplineVolume<N, Real>::Evaluate(Real u, Real v, Real w,
171  unsigned int maxOrder, Vector<N, Real> values[10]) const
172 {
173  if (!mConstructed)
174  {
175  // Errors were already generated during construction.
176  for (int i = 0; i < 10; ++i)
177  {
178  values[i].MakeZero();
179  }
180  return;
181  }
182 
183  int iumin, iumax, ivmin, ivmax, iwmin, iwmax;
184  mBasisFunction[0].Evaluate(u, maxOrder, iumin, iumax);
185  mBasisFunction[1].Evaluate(v, maxOrder, ivmin, ivmax);
186  mBasisFunction[2].Evaluate(w, maxOrder, iwmin, iwmax);
187 
188  // Compute position.
189  values[0] = Compute(0, 0, 0, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
190  if (maxOrder >= 1)
191  {
192  // Compute first-order derivatives.
193  values[1] =
194  Compute(1, 0, 0, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
195  values[2] =
196  Compute(0, 1, 0, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
197  values[3] =
198  Compute(0, 0, 1, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
199  if (maxOrder >= 2)
200  {
201  // Compute second-order derivatives.
202  values[4] =
203  Compute(2, 0, 0, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
204  values[5] =
205  Compute(0, 2, 0, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
206  values[6] =
207  Compute(0, 0, 2, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
208  values[7] =
209  Compute(1, 1, 0, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
210  values[8] =
211  Compute(1, 0, 1, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
212  values[9] =
213  Compute(0, 1, 1, iumin, iumax, ivmin, ivmax, iwmin, iwmax);
214  }
215  }
216 }
217 
218 template <int N, typename Real>
220  unsigned int vOrder, unsigned int wOrder, int iumin, int iumax, int ivmin,
221  int ivmax, int iwmin, int iwmax) const
222 {
223  // The j*-indices introduce a tiny amount of overhead in order to handle
224  // both aperiodic and periodic splines. For aperiodic splines, j* = i*
225  // always.
226 
227  int const numControls0 = mNumControls[0];
228  int const numControls1 = mNumControls[1];
229  int const numControls2 = mNumControls[2];
231  result.MakeZero();
232  for (int iw = iwmin; iw <= iwmax; ++iw)
233  {
234  Real tmpw = mBasisFunction[2].GetValue(wOrder, iw);
235  int jw = (iw >= numControls2 ? iw - numControls2 : iw);
236  for (int iv = ivmin; iv <= ivmax; ++iv)
237  {
238  Real tmpv = mBasisFunction[1].GetValue(vOrder, iv);
239  Real tmpvw = tmpv * tmpw;
240  int jv = (iv >= numControls1 ? iv - numControls1 : iv);
241  for (int iu = iumin; iu <= iumax; ++iu)
242  {
243  Real tmpu = mBasisFunction[0].GetValue(uOrder, iu);
244  int ju = (iu >= numControls0 ? iu - numControls0 : iu);
245  result += (tmpu * tmpvw) *
246  mControls[ju + numControls0*(jv + numControls1*jw)];
247  }
248  }
249  }
250  return result;
251 }
252 
253 }
Real GetMaxDomain(int dim) const
void Evaluate(Real u, Real v, Real w, unsigned int maxOrder, Vector< N, Real > values[10]) const
void MakeZero()
Definition: GteVector.h:279
Real GetMinDomain(int dim) const
std::array< int, 3 > mNumControls
void SetControl(int i0, int i1, int i2, Vector< N, Real > const &control)
Vector< N, Real > const * GetControls() const
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1597
int GetNumControls(int dim) const
BSplineVolume(BasisFunctionInput< Real > const input[3], Vector< N, Real > const *controls)
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:852
std::array< BasisFunction< Real >, 3 > mBasisFunction
Vector< N, Real > Compute(unsigned int uOrder, unsigned int vOrder, unsigned int wOrder, int iumin, int iumax, int ivmin, int ivmax, int iwmin, int iwmax) const
const GLdouble * v
Definition: glcorearb.h:832
GLenum GLenum GLenum input
Definition: glext.h:9913
Vector< N, Real > const & GetControl(int i0, int i1, int i2) const
std::vector< Vector< N, Real > > mControls
BasisFunction< Real > const & GetBasisFunction(int dim) const
GLuint64EXT * result
Definition: glext.h:10003


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 03:59:59