| OpenSubdiv

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