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