mesh.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_OSD_MESH_H
26 #define OPENSUBDIV3_OSD_MESH_H
27 
28 #include "../version.h"
29 
30 #include <bitset>
31 #include <cassert>
32 #include <cstring>
33 #include <vector>
34 
35 #include "../far/topologyRefiner.h"
36 #include "../far/patchTableFactory.h"
37 #include "../far/stencilTable.h"
38 #include "../far/stencilTableFactory.h"
39 
40 #include "../osd/bufferDescriptor.h"
41 
42 struct ID3D11DeviceContext;
43 
44 namespace OpenSubdiv {
45 namespace OPENSUBDIV_VERSION {
46 
47 namespace Osd {
48 
49 enum MeshBits {
54  MeshEndCapBSplineBasis = 4, // exclusive
55  MeshEndCapGregoryBasis = 5, // exclusive
56  MeshEndCapLegacyGregory = 6, // exclusive
58 };
59 typedef std::bitset<NUM_MESH_BITS> MeshBitset;
60 
61 // ---------------------------------------------------------------------------
62 
63 template <class PATCH_TABLE>
65 public:
66  typedef PATCH_TABLE PatchTable;
67  typedef typename PatchTable::VertexBufferBinding VertexBufferBinding;
68 
69 public:
71 
72  virtual ~MeshInterface() { }
73 
74  virtual int GetNumVertices() const = 0;
75 
76  virtual int GetMaxValence() const = 0;
77 
78  virtual void UpdateVertexBuffer(float const *vertexData,
79  int startVertex, int numVerts) = 0;
80 
81  virtual void UpdateVaryingBuffer(float const *varyingData,
82  int startVertex, int numVerts) = 0;
83 
84  virtual void Refine() = 0;
85 
86  virtual void Synchronize() = 0;
87 
88  virtual PatchTable * GetPatchTable() const = 0;
89 
90  virtual Far::PatchTable const *GetFarPatchTable() const = 0;
91 
92  virtual VertexBufferBinding BindVertexBuffer() = 0;
93 
94  virtual VertexBufferBinding BindVaryingBuffer() = 0;
95 
96 protected:
97  static inline void refineMesh(Far::TopologyRefiner & refiner,
98  int level, bool adaptive,
99  bool singleCreasePatch) {
100  if (adaptive) {
102  options.useSingleCreasePatch = singleCreasePatch;
103  refiner.RefineAdaptive(options);
104  } else {
105  // This dependency on FVar channels should not be necessary
106  bool fullTopologyInLastLevel = refiner.GetNumFVarChannels()>0;
107 
109  options.fullTopologyInLastLevel = fullTopologyInLastLevel;
110  refiner.RefineUniform(options);
111  }
112  }
113 };
114 
115 // ---------------------------------------------------------------------------
116 
117 template <typename STENCIL_TABLE, typename SRC_STENCIL_TABLE,
118  typename DEVICE_CONTEXT>
119 STENCIL_TABLE const *
121  SRC_STENCIL_TABLE const *table, DEVICE_CONTEXT *context) {
122  if (not table) return NULL;
123  return STENCIL_TABLE::Create(table, context);
124 }
125 
126 template <>
127 inline Far::StencilTable const *
128 convertToCompatibleStencilTable<Far::StencilTable, Far::StencilTable, void>(
129  Far::StencilTable const *table, void * /*context*/) {
130  // no need for conversion
131  // XXX: We don't want to even copy.
132  if (not table) return NULL;
133  return new Far::StencilTable(*table);
134 }
135 
136 template <>
137 inline Far::LimitStencilTable const *
138 convertToCompatibleStencilTable<Far::LimitStencilTable, Far::LimitStencilTable, void>(
139  Far::LimitStencilTable const *table, void * /*context*/) {
140  // no need for conversion
141  // XXX: We don't want to even copy.
142  if (not table) return NULL;
143  return new Far::LimitStencilTable(*table);
144 }
145 
146 template <>
147 inline Far::StencilTable const *
148 convertToCompatibleStencilTable<Far::StencilTable, Far::StencilTable, ID3D11DeviceContext>(
149  Far::StencilTable const *table, ID3D11DeviceContext * /*context*/) {
150  // no need for conversion
151  // XXX: We don't want to even copy.
152  if (not table) return NULL;
153  return new Far::StencilTable(*table);
154 }
155 
156 // ---------------------------------------------------------------------------
157 
158 // Osd evaluator cache: for the GPU backends require compiled instance
159 // (GLXFB, GLCompue, CL)
160 //
161 // note: this is just an example usage and client applications are supposed
162 // to implement their own structure for Evaluator instance.
163 //
164 template <typename EVALUATOR>
166 public:
168  for(typename Evaluators::iterator it = _evaluators.begin();
169  it != _evaluators.end(); ++it) {
170  delete it->evaluator;
171  }
172  }
173 
174  // XXX: FIXME, linear search
175  struct Entry {
176  Entry(BufferDescriptor const &srcDescArg,
177  BufferDescriptor const &dstDescArg,
178  BufferDescriptor const &duDescArg,
179  BufferDescriptor const &dvDescArg,
180  EVALUATOR *evalArg) : srcDesc(srcDescArg), dstDesc(dstDescArg),
181  duDesc(duDescArg), dvDesc(dvDescArg), evaluator(evalArg) {}
182  BufferDescriptor srcDesc, dstDesc, duDesc, dvDesc;
183  EVALUATOR *evaluator;
184  };
185  typedef std::vector<Entry> Evaluators;
186 
187  template <typename DEVICE_CONTEXT>
188  EVALUATOR *GetEvaluator(BufferDescriptor const &srcDesc,
189  BufferDescriptor const &dstDesc,
190  DEVICE_CONTEXT *deviceContext) {
191  return GetEvaluator(srcDesc, dstDesc,
194  deviceContext);
195  }
196 
197  template <typename DEVICE_CONTEXT>
198  EVALUATOR *GetEvaluator(BufferDescriptor const &srcDesc,
199  BufferDescriptor const &dstDesc,
200  BufferDescriptor const &duDesc,
201  BufferDescriptor const &dvDesc,
202  DEVICE_CONTEXT *deviceContext) {
203 
204  for(typename Evaluators::iterator it = _evaluators.begin();
205  it != _evaluators.end(); ++it) {
206  if (isEqual(srcDesc, it->srcDesc) &&
207  isEqual(dstDesc, it->dstDesc) &&
208  isEqual(duDesc, it->duDesc) &&
209  isEqual(dvDesc, it->dvDesc)) {
210  return it->evaluator;
211  }
212  }
213  EVALUATOR *e = EVALUATOR::Create(srcDesc, dstDesc,
214  duDesc, dvDesc,
215  deviceContext);
216  _evaluators.push_back(Entry(srcDesc, dstDesc, duDesc, dvDesc, e));
217  return e;
218  }
219 
220 private:
221  static bool isEqual(BufferDescriptor const &a,
222  BufferDescriptor const &b) {
223  int offsetA = a.stride ? (a.offset % a.stride) : 0;
224  int offsetB = b.stride ? (b.offset % b.stride) : 0;
225 
226  // Note: XFB kernel needs to be configured with the local offset
227  // of the dstDesc to skip preceding primvars.
228  return (offsetA == offsetB &&
229  a.length == b.length &&
230  a.stride == b.stride);
231  }
232 
233  Evaluators _evaluators;
234 };
235 
237 
238 // template helpers to see if the evaluator is instantiatable or not.
239 template <typename EVALUATOR>
240 struct instantiatable
241 {
242  typedef char yes[1];
243  typedef char no[2];
244  template <typename C> static yes &chk(typename C::Instantiatable *t=0);
245  template <typename C> static no &chk(...);
246  static bool const value = sizeof(chk<EVALUATOR>(0)) == sizeof(yes);
247 };
248 template <bool C, typename T=void>
249 struct enable_if { typedef T type; };
250 template <typename T>
251 struct enable_if<false, T> { };
252 
254 
255 // extract a kernel from cache if available
256 template <typename EVALUATOR, typename DEVICE_CONTEXT>
257 static EVALUATOR *GetEvaluator(
259  BufferDescriptor const &srcDesc,
260  BufferDescriptor const &dstDesc,
261  BufferDescriptor const &duDesc,
262  BufferDescriptor const &dvDesc,
263  DEVICE_CONTEXT deviceContext,
264  typename enable_if<instantiatable<EVALUATOR>::value, void>::type*t=0) {
265  (void)t;
266  if (cache == NULL) return NULL;
267  return cache->GetEvaluator(srcDesc, dstDesc, duDesc, dvDesc, deviceContext);
268 }
269 
270 template <typename EVALUATOR, typename DEVICE_CONTEXT>
271 static EVALUATOR *GetEvaluator(
273  BufferDescriptor const &srcDesc,
274  BufferDescriptor const &dstDesc,
275  DEVICE_CONTEXT deviceContext,
276  typename enable_if<instantiatable<EVALUATOR>::value, void>::type*t=0) {
277  (void)t;
278  if (cache == NULL) return NULL;
279  return cache->GetEvaluator(srcDesc, dstDesc,
282  deviceContext);
283 }
284 
285 // fallback
286 template <typename EVALUATOR, typename DEVICE_CONTEXT>
287 static EVALUATOR *GetEvaluator(
289  BufferDescriptor const &,
290  BufferDescriptor const &,
291  BufferDescriptor const &,
292  BufferDescriptor const &,
293  DEVICE_CONTEXT,
294  typename enable_if<!instantiatable<EVALUATOR>::value, void>::type*t=0) {
295  (void)t;
296  return NULL;
297 }
298 
299 template <typename EVALUATOR, typename DEVICE_CONTEXT>
300 static EVALUATOR *GetEvaluator(
302  BufferDescriptor const &,
303  BufferDescriptor const &,
304  DEVICE_CONTEXT,
305  typename enable_if<!instantiatable<EVALUATOR>::value, void>::type*t=0) {
306  (void)t;
307  return NULL;
308 }
309 
310 // ---------------------------------------------------------------------------
311 
312 template <typename VERTEX_BUFFER,
313  typename STENCIL_TABLE,
314  typename EVALUATOR,
315  typename PATCH_TABLE,
316  typename DEVICE_CONTEXT = void>
317 class Mesh : public MeshInterface<PATCH_TABLE> {
318 public:
319  typedef VERTEX_BUFFER VertexBuffer;
320  typedef EVALUATOR Evaluator;
321  typedef STENCIL_TABLE StencilTable;
322  typedef PATCH_TABLE PatchTable;
323  typedef DEVICE_CONTEXT DeviceContext;
325  typedef typename PatchTable::VertexBufferBinding VertexBufferBinding;
326 
328  int numVertexElements,
329  int numVaryingElements,
330  int level,
331  MeshBitset bits = MeshBitset(),
332  EvaluatorCache * evaluatorCache = NULL,
333  DeviceContext * deviceContext = NULL) :
334 
335  _refiner(refiner),
336  _farPatchTable(NULL),
337  _numVertices(0),
338  _maxValence(0),
339  _vertexBuffer(NULL),
340  _varyingBuffer(NULL),
341  _vertexStencilTable(NULL),
342  _varyingStencilTable(NULL),
343  _evaluatorCache(evaluatorCache),
344  _patchTable(NULL),
345  _deviceContext(deviceContext) {
346 
347  assert(_refiner);
348 
350  *_refiner, level,
351  bits.test(MeshAdaptive),
352  bits.test(MeshUseSingleCreasePatch));
353 
354  int vertexBufferStride = numVertexElements +
355  (bits.test(MeshInterleaveVarying) ? numVaryingElements : 0);
356  int varyingBufferStride =
357  (bits.test(MeshInterleaveVarying) ? 0 : numVaryingElements);
358 
359  initializeContext(numVertexElements,
360  numVaryingElements,
361  level, bits);
362 
363  initializeVertexBuffers(_numVertices,
364  vertexBufferStride,
365  varyingBufferStride);
366 
367  // configure vertex buffer descriptor
368  _vertexDesc =
369  BufferDescriptor(0, numVertexElements, vertexBufferStride);
370  if (bits.test(MeshInterleaveVarying)) {
371  _varyingDesc = BufferDescriptor(
372  numVertexElements, numVaryingElements, vertexBufferStride);
373  } else {
374  _varyingDesc = BufferDescriptor(
375  0, numVaryingElements, varyingBufferStride);
376  }
377  }
378 
379  virtual ~Mesh() {
380  delete _refiner;
381  delete _farPatchTable;
382  delete _vertexBuffer;
383  delete _varyingBuffer;
384  delete _vertexStencilTable;
385  delete _varyingStencilTable;
386  delete _patchTable;
387  // deviceContext and evaluatorCache are not owned by this class.
388  }
389 
390  virtual void UpdateVertexBuffer(float const *vertexData,
391  int startVertex, int numVerts) {
392  _vertexBuffer->UpdateData(vertexData, startVertex, numVerts,
393  _deviceContext);
394  }
395 
396  virtual void UpdateVaryingBuffer(float const *varyingData,
397  int startVertex, int numVerts) {
398  _varyingBuffer->UpdateData(varyingData, startVertex, numVerts,
399  _deviceContext);
400  }
401 
402  virtual void Refine() {
403 
404  int numControlVertices = _refiner->GetLevel(0).GetNumVertices();
405 
406  BufferDescriptor srcDesc = _vertexDesc;
407  BufferDescriptor dstDesc(srcDesc);
408  dstDesc.offset += numControlVertices * dstDesc.stride;
409 
410  // note that the _evaluatorCache can be NULL and thus
411  // the evaluatorInstance can be NULL
412  // (for uninstantiatable kernels CPU,TBB etc)
413  Evaluator const *instance = GetEvaluator<Evaluator>(
414  _evaluatorCache, srcDesc, dstDesc,
415  _deviceContext);
416 
417  Evaluator::EvalStencils(_vertexBuffer, srcDesc,
418  _vertexBuffer, dstDesc,
419  _vertexStencilTable,
420  instance, _deviceContext);
421 
422  if (_varyingDesc.length > 0) {
423  BufferDescriptor vSrcDesc = _varyingDesc;
424  BufferDescriptor vDstDesc(vSrcDesc);
425  vDstDesc.offset += numControlVertices * vDstDesc.stride;
426 
427  instance = GetEvaluator<Evaluator>(
428  _evaluatorCache, vSrcDesc, vDstDesc,
429  _deviceContext);
430 
431  if (_varyingBuffer) {
432  // non-interleaved
433  Evaluator::EvalStencils(_varyingBuffer, vSrcDesc,
434  _varyingBuffer, vDstDesc,
435  _varyingStencilTable,
436  instance, _deviceContext);
437  } else {
438  // interleaved
439  Evaluator::EvalStencils(_vertexBuffer, vSrcDesc,
440  _vertexBuffer, vDstDesc,
441  _varyingStencilTable,
442  instance, _deviceContext);
443  }
444  }
445  }
446 
447  virtual void Synchronize() {
448  Evaluator::Synchronize(_deviceContext);
449  }
450 
451  virtual PatchTable * GetPatchTable() const {
452  return _patchTable;
453  }
454 
455  virtual Far::PatchTable const *GetFarPatchTable() const {
456  return _farPatchTable;
457  }
458 
459  virtual int GetNumVertices() const { return _numVertices; }
460 
461  virtual int GetMaxValence() const { return _maxValence; }
462 
463  virtual VertexBufferBinding BindVertexBuffer() {
464  return _vertexBuffer->BindVBO(_deviceContext);
465  }
466 
467  virtual VertexBufferBinding BindVaryingBuffer() {
468  return _varyingBuffer->BindVBO(_deviceContext);
469  }
470 
471  virtual VertexBuffer * GetVertexBuffer() {
472  return _vertexBuffer;
473  }
474 
475  virtual VertexBuffer * GetVaryingBuffer() {
476  return _varyingBuffer;
477  }
478 
479  virtual Far::TopologyRefiner const * GetTopologyRefiner() const {
480  return _refiner;
481  }
482 
483 private:
484  void initializeContext(int numVertexElements,
485  int numVaryingElements,
486  int level, MeshBitset bits) {
487  assert(_refiner);
488 
490  options.generateOffsets = true;
492  _refiner->IsUniform() ? false : true;
493 
494  Far::StencilTable const * vertexStencils = NULL;
495  Far::StencilTable const * varyingStencils = NULL;
496 
497  if (numVertexElements>0) {
498 
499  vertexStencils = Far::StencilTableFactory::Create(*_refiner,
500  options);
501  }
502 
503  if (numVaryingElements>0) {
504 
505  options.interpolationMode =
507 
508  varyingStencils = Far::StencilTableFactory::Create(*_refiner,
509  options);
510  }
511 
512  Far::PatchTableFactory::Options poptions(level);
513  poptions.generateFVarTables = bits.test(MeshFVarData);
514  poptions.useSingleCreasePatch = bits.test(MeshUseSingleCreasePatch);
515 
516  if (bits.test(MeshEndCapBSplineBasis)) {
517  poptions.SetEndCapType(
519  } else if (bits.test(MeshEndCapGregoryBasis)) {
520  poptions.SetEndCapType(
522  // points on gregory basis endcap boundary can be shared among
523  // adjacent patches to save some stencils.
524  poptions.shareEndCapPatchPoints = true;
525  } else if (bits.test(MeshEndCapLegacyGregory)) {
526  poptions.SetEndCapType(
528  }
529 
530  _farPatchTable = Far::PatchTableFactory::Create(*_refiner, poptions);
531 
532  // if there's endcap stencils, merge it into regular stencils.
533  if (_farPatchTable->GetLocalPointStencilTable()) {
534  // append stencils
535  if (Far::StencilTable const *vertexStencilsWithLocalPoints =
537  *_refiner,
538  vertexStencils,
539  _farPatchTable->GetLocalPointStencilTable())) {
540  delete vertexStencils;
541  vertexStencils = vertexStencilsWithLocalPoints;
542  }
543  if (varyingStencils) {
544  if (Far::StencilTable const *varyingStencilsWithLocalPoints =
546  *_refiner,
547  varyingStencils,
548  _farPatchTable->GetLocalPointVaryingStencilTable())) {
549  delete varyingStencils;
550  varyingStencils = varyingStencilsWithLocalPoints;
551  }
552  }
553  }
554 
555  _maxValence = _farPatchTable->GetMaxValence();
556  _patchTable = PatchTable::Create(_farPatchTable, _deviceContext);
557 
558  // numvertices = coarse verts + refined verts + gregory basis verts
559  _numVertices = vertexStencils->GetNumControlVertices()
560  + vertexStencils->GetNumStencils();
561 
562  // convert to device stenciltable if necessary.
563  _vertexStencilTable =
564  convertToCompatibleStencilTable<StencilTable>(
565  vertexStencils, _deviceContext);
566  _varyingStencilTable =
567  convertToCompatibleStencilTable<StencilTable>(
568  varyingStencils, _deviceContext);
569 
570  // FIXME: we do extra copyings for Far::Stencils.
571  delete vertexStencils;
572  delete varyingStencils;
573  }
574 
575  void initializeVertexBuffers(int numVertices,
576  int numVertexElements,
577  int numVaryingElements) {
578 
579  if (numVertexElements) {
580  _vertexBuffer = VertexBuffer::Create(numVertexElements,
581  numVertices, _deviceContext);
582  }
583 
584  if (numVaryingElements) {
585  _varyingBuffer = VertexBuffer::Create(numVaryingElements,
586  numVertices, _deviceContext);
587  }
588  }
589 
590  Far::TopologyRefiner * _refiner;
591  Far::PatchTable * _farPatchTable;
592 
593  int _numVertices;
594  int _maxValence;
595 
596  VertexBuffer * _vertexBuffer;
597  VertexBuffer * _varyingBuffer;
598 
599  BufferDescriptor _vertexDesc;
600  BufferDescriptor _varyingDesc;
601 
602  StencilTable const * _vertexStencilTable;
603  StencilTable const * _varyingStencilTable;
604  EvaluatorCache * _evaluatorCache;
605 
606  PatchTable *_patchTable;
607  DeviceContext *_deviceContext;
608 };
609 
610 } // end namespace Osd
611 
612 } // end namespace OPENSUBDIV_VERSION
613 using namespace OPENSUBDIV_VERSION;
614 
615 } // end namespace OpenSubdiv
616 
617 #endif // OPENSUBDIV3_OSD_MESH_H
virtual void UpdateVaryingBuffer(float const *varyingData, int startVertex, int numVerts)
Definition: mesh.h:396
virtual Far::TopologyRefiner const * GetTopologyRefiner() const
Definition: mesh.h:479
Mesh(Far::TopologyRefiner *refiner, int numVertexElements, int numVaryingElements, int level, MeshBitset bits=MeshBitset(), EvaluatorCache *evaluatorCache=NULL, DeviceContext *deviceContext=NULL)
Definition: mesh.h:327
EvaluatorCacheT< Evaluator > EvaluatorCache
Definition: mesh.h:324
Entry(BufferDescriptor const &srcDescArg, BufferDescriptor const &dstDescArg, BufferDescriptor const &duDescArg, BufferDescriptor const &dvDescArg, EVALUATOR *evalArg)
Definition: mesh.h:176
void RefineAdaptive(AdaptiveOptions options)
Feature Adaptive topology refinement (restricted to scheme Catmark)
virtual PatchTable * GetPatchTable() const
Definition: mesh.h:451
virtual int GetNumVertices() const
Definition: mesh.h:459
virtual Far::PatchTable const * GetFarPatchTable() const =0
int GetNumStencils() const
Returns the number of stencils in the table.
Definition: stencilTable.h:139
unsigned int generateIntermediateLevels
vertices at all levels or highest only
static PatchTable * Create(TopologyRefiner const &refiner, Options options=Options())
Factory constructor for PatchTable.
virtual void UpdateVaryingBuffer(float const *varyingData, int startVertex, int numVerts)=0
PatchTable::VertexBufferBinding VertexBufferBinding
Definition: mesh.h:325
virtual void UpdateVertexBuffer(float const *vertexData, int startVertex, int numVerts)
Definition: mesh.h:390
virtual VertexBufferBinding BindVaryingBuffer()
Definition: mesh.h:467
virtual VertexBufferBinding BindVertexBuffer()
Definition: mesh.h:463
use legacy (2.x) Gregory patches (4 cp + valence table) as end-caps
virtual VertexBuffer * GetVaryingBuffer()
Definition: mesh.h:475
static StencilTable const * Create(TopologyRefiner const &refiner, Options options=Options())
Instantiates StencilTable from TopologyRefiner that have been refined uniformly or adaptively...
void RefineUniform(UniformOptions options)
Refine the topology uniformly.
int GetNumControlVertices() const
Returns the number of control vertices indexed in the table.
Definition: stencilTable.h:144
virtual VertexBufferBinding BindVaryingBuffer()=0
virtual PatchTable * GetPatchTable() const =0
virtual VertexBufferBinding BindVertexBuffer()=0
EVALUATOR * GetEvaluator(BufferDescriptor const &srcDesc, BufferDescriptor const &dstDesc, DEVICE_CONTEXT *deviceContext)
Definition: mesh.h:188
PatchTable::VertexBufferBinding VertexBufferBinding
Definition: mesh.h:67
Stores topology data for a specified set of refinement options.
int GetNumFVarChannels() const
Returns the number of face-varying channels in the tables.
static StencilTable const * AppendLocalPointStencilTable(TopologyRefiner const &refiner, StencilTable const *baseStencilTable, StencilTable const *localPointStencilTable, bool factorize=true)
Utility function for stencil splicing for local point stencils.
std::bitset< NUM_MESH_BITS > MeshBitset
Definition: mesh.h:59
unsigned int generateFVarTables
Generate face-varying patch tables.
BufferDescriptor is a struct which describes buffer elements in interleaved data buffers. Almost all Osd Evaluator APIs take BufferDescriptors along with device-specific buffer objects.
Container for arrays of parametric patches.
Definition: patchTable.h:56
virtual void UpdateVertexBuffer(float const *vertexData, int startVertex, int numVerts)=0
unsigned int generateOffsets
populate optional "_offsets" field
static void refineMesh(Far::TopologyRefiner &refiner, int level, bool adaptive, bool singleCreasePatch)
Definition: mesh.h:97
virtual VertexBuffer * GetVertexBuffer()
Definition: mesh.h:471
Table of limit subdivision stencils.
Definition: stencilTable.h:287
virtual Far::PatchTable const * GetFarPatchTable() const
Definition: mesh.h:455
EVALUATOR * GetEvaluator(BufferDescriptor const &srcDesc, BufferDescriptor const &dstDesc, BufferDescriptor const &duDesc, BufferDescriptor const &dvDesc, DEVICE_CONTEXT *deviceContext)
Definition: mesh.h:198
STENCIL_TABLE const * convertToCompatibleStencilTable(SRC_STENCIL_TABLE const *table, DEVICE_CONTEXT *context)
Definition: mesh.h:120
virtual int GetMaxValence() const
Definition: mesh.h:461