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