stencilTable.h
Go to the documentation of this file.
1 //
2 // Copyright 2013 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 
25 #ifndef OPENSUBDIV3_FAR_STENCILTABLE_H
26 #define OPENSUBDIV3_FAR_STENCILTABLE_H
27 
28 #include "../version.h"
29 
30 #include "../far/types.h"
31 
32 #include <cassert>
33 #include <cstring>
34 #include <vector>
35 #include <iostream>
36 
37 namespace OpenSubdiv {
38 namespace OPENSUBDIV_VERSION {
39 
40 namespace Far {
41 
46 class Stencil {
47 
48 public:
49 
51  Stencil() {}
52 
61  Stencil(int * size,
62  Index * indices,
63  float * weights)
64  : _size(size),
65  _indices(indices),
66  _weights(weights) {
67  }
68 
70  Stencil(Stencil const & other) {
71  _size = other._size;
72  _indices = other._indices;
73  _weights = other._weights;
74  }
75 
77  int GetSize() const {
78  return *_size;
79  }
80 
82  int * GetSizePtr() const {
83  return _size;
84  }
85 
87  Index const * GetVertexIndices() const {
88  return _indices;
89  }
90 
92  float const * GetWeights() const {
93  return _weights;
94  }
95 
97  void Next() {
98  int stride = *_size;
99  ++_size;
100  _indices += stride;
101  _weights += stride;
102  }
103 
104 protected:
105  friend class StencilTableFactory;
107 
108  int * _size;
110  float * _weights;
111 };
112 
126  StencilTable(int numControlVerts,
127  std::vector<int> const& offsets,
128  std::vector<int> const& sizes,
129  std::vector<int> const& sources,
130  std::vector<float> const& weights,
131  bool includeCoarseVerts,
132  size_t firstOffset);
133 
134 public:
135 
136  virtual ~StencilTable() {};
137 
139  int GetNumStencils() const {
140  return (int)_sizes.size();
141  }
142 
144  int GetNumControlVertices() const {
145  return _numControlVertices;
146  }
147 
149  Stencil GetStencil(Index i) const;
150 
152  std::vector<int> const & GetSizes() const {
153  return _sizes;
154  }
155 
157  std::vector<Index> const & GetOffsets() const {
158  return _offsets;
159  }
160 
162  std::vector<Index> const & GetControlIndices() const {
163  return _indices;
164  }
165 
167  std::vector<float> const & GetWeights() const {
168  return _weights;
169  }
170 
172  Stencil operator[] (Index index) const;
173 
188  template <class T>
189  void UpdateValues(T const *controlValues, T *values, Index start=-1, Index end=-1) const {
190  update(controlValues, values, _weights, start, end);
191  }
192 
194  void Clear();
195 
196 protected:
197 
198  // Update values by applying cached stencil weights to new control values
199  template <class T> void update( T const *controlValues, T *values,
200  std::vector<float> const & valueWeights, Index start, Index end) const;
201 
202  // Populate the offsets table from the stencil sizes in _sizes (factory helper)
203  void generateOffsets();
204 
205  // Resize the table arrays (factory helper)
206  void resize(int nstencils, int nelems);
207 
208  // Reserves the table arrays (factory helper)
209  void reserve(int nstencils, int nelems);
210 
211  // Reallocates the table arrays to remove excess capacity (factory helper)
212  void shrinkToFit();
213 
214  // Performs any final operations on internal tables (factory helper)
215  void finalize();
216 
217 protected:
218  StencilTable() : _numControlVertices(0) {}
219  StencilTable(int numControlVerts)
220  : _numControlVertices(numControlVerts)
221  { }
222 
223  friend class StencilTableFactory;
224  friend class PatchTableFactory;
225  // XXX: temporarily, GregoryBasis class will go away.
226  friend class GregoryBasis;
227  // XXX: needed to call reserve().
228  friend class EndCapBSplineBasisPatchFactory;
229  friend class EndCapGregoryBasisPatchFactory;
230 
231  int _numControlVertices; // number of control vertices
232 
233  std::vector<int> _sizes; // number of coeffiecient for each stencil
234  std::vector<Index> _offsets, // offset to the start of each stencil
235  _indices; // indices of contributing coarse vertices
236  std::vector<float> _weights; // stencil weight coefficients
237 };
238 
239 
242 class LimitStencil : public Stencil {
243 
244 public:
245 
264  LimitStencil( int* size,
265  Index * indices,
266  float * weights,
267  float * duWeights=0,
268  float * dvWeights=0,
269  float * duuWeights=0,
270  float * duvWeights=0,
271  float * dvvWeights=0)
272  : Stencil(size, indices, weights),
273  _duWeights(duWeights),
274  _dvWeights(dvWeights),
275  _duuWeights(duuWeights),
276  _duvWeights(duvWeights),
277  _dvvWeights(dvvWeights) {
278  }
279 
281  float const * GetDuWeights() const {
282  return _duWeights;
283  }
284 
286  float const * GetDvWeights() const {
287  return _dvWeights;
288  }
289 
291  float const * GetDuuWeights() const {
292  return _duuWeights;
293  }
294 
296  float const * GetDuvWeights() const {
297  return _duvWeights;
298  }
299 
301  float const * GetDvvWeights() const {
302  return _dvvWeights;
303  }
304 
306  void Next() {
307  int stride = *_size;
308  ++_size;
309  _indices += stride;
310  _weights += stride;
311  if (_duWeights) _duWeights += stride;
312  if (_dvWeights) _dvWeights += stride;
313  if (_duuWeights) _duuWeights += stride;
314  if (_duvWeights) _duvWeights += stride;
315  if (_dvvWeights) _dvvWeights += stride;
316  }
317 
318 private:
319 
320  friend class StencilTableFactory;
322 
323  float * _duWeights, // pointer to stencil u derivative limit weights
324  * _dvWeights, // pointer to stencil v derivative limit weights
325  * _duuWeights, // pointer to stencil uu derivative limit weights
326  * _duvWeights, // pointer to stencil uv derivative limit weights
327  * _dvvWeights; // pointer to stencil vv derivative limit weights
328 };
329 
334  LimitStencilTable(int numControlVerts,
335  std::vector<int> const& offsets,
336  std::vector<int> const& sizes,
337  std::vector<int> const& sources,
338  std::vector<float> const& weights,
339  std::vector<float> const& duWeights,
340  std::vector<float> const& dvWeights,
341  std::vector<float> const& duuWeights,
342  std::vector<float> const& duvWeights,
343  std::vector<float> const& dvvWeights,
344  bool includeCoarseVerts,
345  size_t firstOffset);
346 
347 public:
348 
350  LimitStencil GetLimitStencil(Index i) const;
351 
353  LimitStencil operator[] (Index index) const;
354 
356  std::vector<float> const & GetDuWeights() const {
357  return _duWeights;
358  }
359 
361  std::vector<float> const & GetDvWeights() const {
362  return _dvWeights;
363  }
364 
366  std::vector<float> const & GetDuuWeights() const {
367  return _duuWeights;
368  }
369 
371  std::vector<float> const & GetDuvWeights() const {
372  return _duvWeights;
373  }
374 
376  std::vector<float> const & GetDvvWeights() const {
377  return _dvvWeights;
378  }
379 
397  template <class T>
398  void UpdateDerivs(T const *controlValues, T *uderivs, T *vderivs,
399  int start=-1, int end=-1) const {
400 
401  update(controlValues, uderivs, _duWeights, start, end);
402  update(controlValues, vderivs, _dvWeights, start, end);
403  }
404 
425  template <class T>
426  void Update2ndDerivs(T const *controlValues, T *uuderivs, T *uvderivs, T *vvderivs,
427  int start=-1, int end=-1) const {
428 
429  update(controlValues, uuderivs, _duuWeights, start, end);
430  update(controlValues, uvderivs, _duvWeights, start, end);
431  update(controlValues, vvderivs, _dvvWeights, start, end);
432  }
433 
435  void Clear();
436 
437 private:
439 
440  // Resize the table arrays (factory helper)
441  void resize(int nstencils, int nelems);
442 
443 private:
444  std::vector<float> _duWeights, // u derivative limit stencil weights
445  _dvWeights, // v derivative limit stencil weights
446  _duuWeights, // uu derivative limit stencil weights
447  _duvWeights, // uv derivative limit stencil weights
448  _dvvWeights; // vv derivative limit stencil weights
449 };
450 
451 
452 // Update values by appling cached stencil weights to new control values
453 template <class T> void
454 StencilTable::update(T const *controlValues, T *values,
455  std::vector<float> const &valueWeights, Index start, Index end) const {
456 
457  int const * sizes = &_sizes.at(0);
458  Index const * indices = &_indices.at(0);
459  float const * weights = &valueWeights.at(0);
460 
461  if (start>0) {
462  assert(start<(Index)_offsets.size());
463  sizes += start;
464  indices += _offsets[start];
465  weights += _offsets[start];
466  values += start;
467  }
468 
469  if (end<start || end<0) {
470  end = GetNumStencils();
471  }
472 
473  int nstencils = end - std::max(0, start);
474  for (int i=0; i<nstencils; ++i, ++sizes) {
475 
476  // Zero out the result accumulators
477  values[i].Clear();
478 
479  // For each element in the array, add the coefs contribution
480  for (int j=0; j<*sizes; ++j, ++indices, ++weights) {
481  values[i].AddWithWeight( controlValues[*indices], *weights );
482  }
483  }
484 }
485 
486 inline void
488  Index offset=0;
489  int noffsets = (int)_sizes.size();
490  _offsets.resize(noffsets);
491  for (int i=0; i<(int)_sizes.size(); ++i ) {
492  _offsets[i]=offset;
493  offset+=_sizes[i];
494  }
495 }
496 
497 inline void
498 StencilTable::resize(int nstencils, int nelems) {
499  _sizes.resize(nstencils);
500  _indices.resize(nelems);
501  _weights.resize(nelems);
502 }
503 
504 inline void
505 StencilTable::reserve(int nstencils, int nelems) {
506  _sizes.reserve(nstencils);
507  _indices.reserve(nelems);
508  _weights.reserve(nelems);
509 }
510 
511 inline void
513  std::vector<int>(_sizes).swap(_sizes);
514  std::vector<Index>(_indices).swap(_indices);
515  std::vector<float>(_weights).swap(_weights);
516 }
517 
518 inline void
520  shrinkToFit();
521  generateOffsets();
522 }
523 
524 // Returns a Stencil at index i in the table
525 inline Stencil
527  assert((! _offsets.empty()) && i<(int)_offsets.size());
528 
529  Index ofs = _offsets[i];
530 
531  return Stencil( const_cast<int*>(&_sizes[i]),
532  const_cast<Index *>(&_indices[ofs]),
533  const_cast<float *>(&_weights[ofs]) );
534 }
535 
536 inline Stencil
538  return GetStencil(index);
539 }
540 
541 inline void
542 LimitStencilTable::resize(int nstencils, int nelems) {
543  StencilTable::resize(nstencils, nelems);
544  _duWeights.resize(nelems);
545  _dvWeights.resize(nelems);
546 }
547 
548 // Returns a LimitStencil at index i in the table
549 inline LimitStencil
551  assert((! GetOffsets().empty()) && i<(int)GetOffsets().size());
552 
553  Index ofs = GetOffsets()[i];
554 
555  if (!_duWeights.empty() && !_dvWeights.empty() &&
556  !_duuWeights.empty() && !_duvWeights.empty() && !_dvvWeights.empty()) {
557  return LimitStencil( const_cast<int *>(&GetSizes()[i]),
558  const_cast<Index *>(&GetControlIndices()[ofs]),
559  const_cast<float *>(&GetWeights()[ofs]),
560  const_cast<float *>(&GetDuWeights()[ofs]),
561  const_cast<float *>(&GetDvWeights()[ofs]),
562  const_cast<float *>(&GetDuuWeights()[ofs]),
563  const_cast<float *>(&GetDuvWeights()[ofs]),
564  const_cast<float *>(&GetDvvWeights()[ofs]) );
565  } else if (!_duWeights.empty() && !_dvWeights.empty()) {
566  return LimitStencil( const_cast<int *>(&GetSizes()[i]),
567  const_cast<Index *>(&GetControlIndices()[ofs]),
568  const_cast<float *>(&GetWeights()[ofs]),
569  const_cast<float *>(&GetDuWeights()[ofs]),
570  const_cast<float *>(&GetDvWeights()[ofs]) );
571  } else {
572  return LimitStencil( const_cast<int *>(&GetSizes()[i]),
573  const_cast<Index *>(&GetControlIndices()[ofs]),
574  const_cast<float *>(&GetWeights()[ofs]) );
575  }
576 }
577 
578 inline LimitStencil
580  return GetLimitStencil(index);
581 }
582 
583 
584 } // end namespace Far
585 
586 } // end namespace OPENSUBDIV_VERSION
587 using namespace OPENSUBDIV_VERSION;
588 
589 } // end namespace OpenSubdiv
590 
591 #endif // OPENSUBDIV3_FAR_STENCILTABLE_H
int GetSize() const
Returns the size of the stencil.
Definition: stencilTable.h:77
std::vector< float > const & GetWeights() const
Returns the stencil interpolation weights.
Definition: stencilTable.h:167
std::vector< Index > const & GetOffsets() const
Returns the offset to a given stencil (factory may leave empty)
Definition: stencilTable.h:157
Stencil(Stencil const &other)
Copy constructor.
Definition: stencilTable.h:70
LimitStencil operator[](Index index) const
Returns the limit stencil at index i in the table.
Definition: stencilTable.h:579
void Next()
Advance to the next stencil in the table.
Definition: stencilTable.h:306
int * GetSizePtr() const
Returns the size of the stencil as a pointer.
Definition: stencilTable.h:82
Table of limit subdivision stencils.
Definition: stencilTable.h:333
float const * GetDvWeights() const
Returns the v derivative weights.
Definition: stencilTable.h:286
std::vector< float > const & GetDuuWeights() const
Returns the &#39;uu&#39; derivative stencil interpolation weights.
Definition: stencilTable.h:366
std::vector< float > const & GetDuvWeights() const
Returns the &#39;uv&#39; derivative stencil interpolation weights.
Definition: stencilTable.h:371
void Update2ndDerivs(T const *controlValues, T *uuderivs, T *uvderivs, T *vvderivs, int start=-1, int end=-1) const
Updates 2nd derivative values based on the control values.
Definition: stencilTable.h:426
Factory for constructing a PatchTable from a TopologyRefiner.
float const * GetDvvWeights() const
Returns the vv derivative weights.
Definition: stencilTable.h:301
Stencil operator[](Index index) const
Returns the stencil at index i in the table.
Definition: stencilTable.h:537
Stencil GetStencil(Index i) const
Returns a Stencil at index i in the table.
Definition: stencilTable.h:526
void UpdateDerivs(T const *controlValues, T *uderivs, T *vderivs, int start=-1, int end=-1) const
Updates derivative values based on the control values.
Definition: stencilTable.h:398
Stencil(int *size, Index *indices, float *weights)
Constructor.
Definition: stencilTable.h:61
void Next()
Advance to the next stencil in the table.
Definition: stencilTable.h:97
void update(T const *controlValues, T *values, std::vector< float > const &valueWeights, Index start, Index end) const
Definition: stencilTable.h:454
LimitStencil GetLimitStencil(Index i) const
Returns a LimitStencil at index i in the table.
Definition: stencilTable.h:550
float const * GetDuuWeights() const
Returns the uu derivative weights.
Definition: stencilTable.h:291
std::vector< float > const & GetDvWeights() const
Returns the &#39;v&#39; derivative stencil interpolation weights.
Definition: stencilTable.h:361
std::vector< float > const & GetDvvWeights() const
Returns the &#39;vv&#39; derivative stencil interpolation weights.
Definition: stencilTable.h:376
std::vector< float > const & GetDuWeights() const
Returns the &#39;u&#39; derivative stencil interpolation weights.
Definition: stencilTable.h:356
Index const * GetVertexIndices() const
Returns the control vertices indices.
Definition: stencilTable.h:87
float const * GetDuWeights() const
Returns the u derivative weights.
Definition: stencilTable.h:281
float const * GetDuvWeights() const
Returns the uv derivative weights.
Definition: stencilTable.h:296
void reserve(int nstencils, int nelems)
Definition: stencilTable.h:505
std::vector< Index > const & GetControlIndices() const
Returns the indices of the control vertices.
Definition: stencilTable.h:162
std::vector< int > const & GetSizes() const
Returns the number of control vertices of each stencil in the table.
Definition: stencilTable.h:152
void resize(int nstencils, int nelems)
Definition: stencilTable.h:498
void UpdateValues(T const *controlValues, T *values, Index start=-1, Index end=-1) const
Updates point values based on the control values.
Definition: stencilTable.h:189
int GetNumControlVertices() const
Returns the number of control vertices indexed in the table.
Definition: stencilTable.h:144
LimitStencil(int *size, Index *indices, float *weights, float *duWeights=0, float *dvWeights=0, float *duuWeights=0, float *duvWeights=0, float *dvvWeights=0)
Constructor.
Definition: stencilTable.h:264
float const * GetWeights() const
Returns the interpolation weights.
Definition: stencilTable.h:92
int GetNumStencils() const
Returns the number of stencils in the table.
Definition: stencilTable.h:139