GteBSplineSurface.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 
12 
13 namespace gte
14 {
15 
16 template <int N, typename Real>
17 class BSplineSurface : public ParametricSurface<N, 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 row-major
24  // order, control[i0 + numControls0*i1]. As a 2D array, this corresponds
25  // to control2D[i1][i0]. To validate construction, create an object as
26  // shown:
27  // BSplineSurface<N,Real> surface(parameters);
28  // if (!surface) { <constructor failed, handle accordingly>; }
30  Vector<N, Real> const* controls);
31 
32  // Member access. The index 'dim' must be in {0,1}.
33  inline BasisFunction<Real> const& GetBasisFunction(int dim) const;
34  inline int GetNumControls(int dim) const;
35  inline Vector<N, Real>* GetControls();
36  inline Vector<N, Real> const* GetControls() const;
37  void SetControl(int i0, int i1, Vector<N, Real> const& control);
38  Vector<N, Real> const& GetControl(int i0, int i1) const;
39 
40  // Evaluation of the surface. The function supports derivative
41  // calculation through order 2; that is, maxOrder <= 2 is required. If
42  // you want only the position, pass in maxOrder of 0. If you want the
43  // position and first-order derivatives, pass in maxOrder of 1, and so on.
44  // The output 'values' are ordered as: position X; first-order derivatives
45  // dX/du, dX/dv; second-order derivatives d2X/du2, d2X/dudv, d2X/dv2.
46  virtual void Evaluate(Real u, Real v, unsigned int maxOrder,
47  Vector<N, Real> values[6]) const;
48 
49 private:
50  // Support for Evaluate(...).
51  Vector<N, Real> Compute(unsigned int uOrder, unsigned int vOrder,
52  int iumin, int iumax, int ivmin, int ivmax) const;
53 
54  std::array<BasisFunction<Real>, 2> mBasisFunction;
55  std::array<int, 2> mNumControls;
56  std::vector<Vector<N, Real>> mControls;
57 };
58 
59 
60 template <int N, typename Real>
62  Vector<N, Real> const* controls)
63  :
64  ParametricSurface<N, Real>((Real)0, (Real)1, (Real)0, (Real)1, true)
65 {
66  for (int i = 0; i < 2; ++i)
67  {
68  mNumControls[i] = input[i].numControls;
69  mBasisFunction[i].Create(input[i]);
70  if (!mBasisFunction[i])
71  {
72  // Errors were already generated during construction of the
73  // basis functions.
74  return;
75  }
76  }
77 
78  // The mBasisFunction stores the domain but so does ParametricCurve.
79  this->mUMin = mBasisFunction[0].GetMinDomain();
80  this->mUMax = mBasisFunction[0].GetMaxDomain();
81  this->mVMin = mBasisFunction[1].GetMinDomain();
82  this->mVMax = mBasisFunction[1].GetMaxDomain();
83 
84  // The replication of control points for periodic splines is avoided
85  // by wrapping the i-loop index in Evaluate.
86  int numControls = mNumControls[0] * mNumControls[1];
87  mControls.resize(numControls);
88  if (controls)
89  {
90  std::copy(controls, controls + numControls, mControls.begin());
91  }
92  else
93  {
94  memset(mControls.data(), 0, mControls.size() * sizeof(mControls[0]));
95  }
96  this->mConstructed = true;
97 }
98 
99 template <int N, typename Real>
101 {
102  return mBasisFunction[dim];
103 }
104 
105 template <int N, typename Real>
107 {
108  return mNumControls[dim];
109 }
110 
111 template <int N, typename Real>
113 {
114  return mControls.data();
115 }
116 
117 template <int N, typename Real>
119 {
120  return mControls.data();
121 }
122 
123 template <int N, typename Real>
124 void BSplineSurface<N, Real>::SetControl(int i0, int i1, Vector<N, Real> const& control)
125 {
126  if (0 <= i0 && i0 < GetNumControls(0)
127  && 0 <= i1 && i1 < GetNumControls(1))
128  {
129  mControls[i0 + mNumControls[0] * i1] = control;
130  }
131 }
132 
133 template <int N, typename Real>
135 {
136  if (0 <= i0 && i0 < GetNumControls(0) && 0 <= i1 && i1 < GetNumControls(1))
137  {
138  return mControls[i0 + mNumControls[0] * i1];
139  }
140  else
141  {
142  return mControls[0];
143  }
144 }
145 
146 template <int N, typename Real>
147 void BSplineSurface<N, Real>::Evaluate(Real u, Real v, unsigned int maxOrder,
148  Vector<N, Real> values[6]) const
149 {
150  if (!this->mConstructed)
151  {
152  // Errors were already generated during construction.
153  for (int i = 0; i < 6; ++i)
154  {
155  values[i].MakeZero();
156  }
157  return;
158  }
159 
160  int iumin, iumax, ivmin, ivmax;
161  mBasisFunction[0].Evaluate(u, maxOrder, iumin, iumax);
162  mBasisFunction[1].Evaluate(v, maxOrder, ivmin, ivmax);
163 
164  // Compute position.
165  values[0] = Compute(0, 0, iumin, iumax, ivmin, ivmax);
166  if (maxOrder >= 1)
167  {
168  // Compute first-order derivatives.
169  values[1] = Compute(1, 0, iumin, iumax, ivmin, ivmax);
170  values[2] = Compute(0, 1, iumin, iumax, ivmin, ivmax);
171  if (maxOrder >= 2)
172  {
173  // Compute second-order derivatives.
174  values[3] = Compute(2, 0, iumin, iumax, ivmin, ivmax);
175  values[4] = Compute(1, 1, iumin, iumax, ivmin, ivmax);
176  values[5] = Compute(0, 2, iumin, iumax, ivmin, ivmax);
177  }
178  }
179 }
180 
181 template <int N, typename Real>
183  unsigned int vOrder, int iumin, int iumax, int ivmin, int ivmax) const
184 {
185  // The j*-indices introduce a tiny amount of overhead in order to handle
186  // both aperiodic and periodic splines. For aperiodic splines, j* = i*
187  // always.
188 
189  int const numControls0 = mNumControls[0];
190  int const numControls1 = mNumControls[1];
192  result.MakeZero();
193  for (int iv = ivmin; iv <= ivmax; ++iv)
194  {
195  Real tmpv = mBasisFunction[1].GetValue(vOrder, iv);
196  int jv = (iv >= numControls1 ? iv - numControls1 : iv);
197  for (int iu = iumin; iu <= iumax; ++iu)
198  {
199  Real tmpu = mBasisFunction[0].GetValue(uOrder, iu);
200  int ju = (iu >= numControls0 ? iu - numControls0 : iu);
201  result += (tmpu * tmpv) * mControls[ju + numControls0 * jv];
202  }
203  }
204  return result;
205 }
206 
207 }
Vector< N, Real > * GetControls()
void MakeZero()
Definition: GteVector.h:279
BasisFunction< Real > const & GetBasisFunction(int dim) const
int GetNumControls(int dim) const
void SetControl(int i0, int i1, Vector< N, Real > const &control)
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1597
virtual void Evaluate(Real u, Real v, unsigned int maxOrder, Vector< N, Real > values[6]) const
BSplineSurface(BasisFunctionInput< Real > const input[2], Vector< N, Real > const *controls)
std::array< BasisFunction< Real >, 2 > mBasisFunction
Vector< N, Real > Compute(unsigned int uOrder, unsigned int vOrder, int iumin, int iumax, int ivmin, int ivmax) const
const GLdouble * v
Definition: glcorearb.h:832
std::array< int, 2 > mNumControls
GLenum GLenum GLenum input
Definition: glext.h:9913
Vector< N, Real > const & GetControl(int i0, int i1) const
GLuint64EXT * result
Definition: glext.h:10003
std::vector< Vector< N, Real > > mControls


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