25 #ifndef OPENSUBDIV3_OSD_MESH_H 
   26 #define OPENSUBDIV3_OSD_MESH_H 
   28 #include "../version.h" 
   35 #include "../far/topologyRefiner.h" 
   36 #include "../far/patchTableFactory.h" 
   37 #include "../far/stencilTable.h" 
   38 #include "../far/stencilTableFactory.h" 
   40 #include "../osd/bufferDescriptor.h" 
   42 struct ID3D11DeviceContext;
 
   44 namespace OpenSubdiv {
 
   45 namespace OPENSUBDIV_VERSION {
 
   67 template <
class PATCH_TABLE>
 
   83                                     int startVertex, 
int numVerts) = 0;
 
   86                                      int startVertex, 
int numVerts) = 0;
 
  102                                   int level, 
bool adaptive,
 
  103                                   bool singleCreasePatch) {
 
  138 template <
typename STENCIL_TABLE, 
typename SRC_STENCIL_TABLE,
 
  139           typename DEVICE_CONTEXT>
 
  140 STENCIL_TABLE 
const *
 
  142     SRC_STENCIL_TABLE 
const *table, DEVICE_CONTEXT *context) {
 
  143     if (! table) 
return NULL;
 
  144     return STENCIL_TABLE::Create(table, context);
 
  149 convertToCompatibleStencilTable<Far::StencilTable, Far::StencilTable, void>(
 
  153     if (! table) 
return NULL;
 
  159 convertToCompatibleStencilTable<Far::LimitStencilTable, Far::LimitStencilTable, void>(
 
  163     if (! table) 
return NULL;
 
  169 convertToCompatibleStencilTable<Far::StencilTable, Far::StencilTable, ID3D11DeviceContext>(
 
  173     if (! table) 
return NULL;
 
  185 template <
typename EVALUATOR>
 
  189         for(
typename Evaluators::iterator it = _evaluators.begin();
 
  190             it != _evaluators.end(); ++it) {
 
  191             delete it->evaluator;
 
  227     template <
typename DEVICE_CONTEXT>
 
  230                             DEVICE_CONTEXT *deviceContext) {
 
  240     template <
typename DEVICE_CONTEXT>
 
  245                             DEVICE_CONTEXT *deviceContext) {
 
  254     template <
typename DEVICE_CONTEXT>
 
  262                             DEVICE_CONTEXT *deviceContext) {
 
  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;
 
  276         EVALUATOR *e = EVALUATOR::Create(srcDesc, dstDesc,
 
  278                                          duuDesc, duvDesc, dvvDesc,
 
  280         _evaluators.push_back(
Entry(srcDesc, dstDesc,
 
  282                                     duuDesc, duvDesc, dvvDesc, e));
 
  294         return (offsetA == offsetB &&
 
  305 template <
typename EVALUATOR>
 
  306 struct instantiatable
 
  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);
 
  314 template <
bool C, 
typename T=
void>
 
  315 struct enable_if { 
typedef T type; };
 
  316 template <
typename T>
 
  317 struct enable_if<false, T> { };
 
  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) {
 
  335     if (cache == NULL) 
return NULL;
 
  336     return cache->GetEvaluator(srcDesc, dstDesc,
 
  337                                duDesc, dvDesc, duuDesc, duvDesc, dvvDesc,
 
  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) {
 
  351     if (cache == NULL) 
return NULL;
 
  352     return cache->GetEvaluator(srcDesc, dstDesc, duDesc, dvDesc, deviceContext);
 
  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) {
 
  363     if (cache == NULL) 
return NULL;
 
  364     return cache->GetEvaluator(srcDesc, dstDesc,
 
  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 &,
 
  382     typename enable_if<!instantiatable<EVALUATOR>::value, 
void>::type*t=0) {
 
  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 &,
 
  395     typename enable_if<!instantiatable<EVALUATOR>::value, 
void>::type*t=0) {
 
  400 template <
typename EVALUATOR, 
typename DEVICE_CONTEXT>
 
  401 static EVALUATOR *GetEvaluator(
 
  402     EvaluatorCacheT<EVALUATOR> *,
 
  403     BufferDescriptor 
const &,
 
  404     BufferDescriptor 
const &,
 
  406     typename enable_if<!instantiatable<EVALUATOR>::value, 
void>::type*t=0) {
 
  413 template <
typename VERTEX_BUFFER,
 
  414           typename STENCIL_TABLE,
 
  416           typename PATCH_TABLE,
 
  417           typename DEVICE_CONTEXT = 
void>
 
  429          int numVertexElements,
 
  430          int numVaryingElements,
 
  437             _farPatchTable(NULL),
 
  441             _varyingBuffer(NULL),
 
  442             _vertexStencilTable(NULL),
 
  443             _varyingStencilTable(NULL),
 
  444             _evaluatorCache(evaluatorCache),
 
  446             _deviceContext(deviceContext) {
 
  451             *_refiner, level, bits);
 
  453         int vertexBufferStride = numVertexElements +
 
  455         int varyingBufferStride =
 
  458         initializeContext(numVertexElements,
 
  462         initializeVertexBuffers(_numVertices,
 
  464                                 varyingBufferStride);
 
  471                 numVertexElements, numVaryingElements, vertexBufferStride);
 
  474                 0, numVaryingElements, varyingBufferStride);
 
  480         delete _farPatchTable;
 
  481         delete _vertexBuffer;
 
  482         delete _varyingBuffer;
 
  483         delete _vertexStencilTable;
 
  484         delete _varyingStencilTable;
 
  490                                     int startVertex, 
int numVerts) {
 
  491         _vertexBuffer->UpdateData(vertexData, startVertex, numVerts,
 
  496                                      int startVertex, 
int numVerts) {
 
  497         _varyingBuffer->UpdateData(varyingData, startVertex, numVerts,
 
  512         Evaluator const *instance = GetEvaluator<Evaluator>(
 
  513             _evaluatorCache, srcDesc, dstDesc,
 
  516         Evaluator::EvalStencils(_vertexBuffer, srcDesc,
 
  517                                 _vertexBuffer, dstDesc,
 
  519                                 instance, _deviceContext);
 
  521         if (_varyingDesc.
length > 0) {
 
  524             vDstDesc.
offset += numControlVertices * vDstDesc.
stride;
 
  526             instance = GetEvaluator<Evaluator>(
 
  527                 _evaluatorCache, vSrcDesc, vDstDesc,
 
  530             if (_varyingBuffer) {
 
  532                 Evaluator::EvalStencils(_varyingBuffer, vSrcDesc,
 
  533                                         _varyingBuffer, vDstDesc,
 
  534                                         _varyingStencilTable,
 
  535                                         instance, _deviceContext);
 
  538                 Evaluator::EvalStencils(_vertexBuffer, vSrcDesc,
 
  539                                         _vertexBuffer, vDstDesc,
 
  540                                         _varyingStencilTable,
 
  541                                         instance, _deviceContext);
 
  547         Evaluator::Synchronize(_deviceContext);
 
  555         return _farPatchTable;
 
  563         return _vertexBuffer->BindVBO(_deviceContext);
 
  567         return _varyingBuffer->BindVBO(_deviceContext);
 
  571         return _vertexBuffer;
 
  575         return _varyingBuffer;
 
  583     void initializeContext(
int numVertexElements,
 
  584                            int numVaryingElements,
 
  588         Far::StencilTableFactory::Options options;
 
  589         options.generateOffsets = 
true;
 
  590         options.generateIntermediateLevels =
 
  596         if (numVertexElements>0) {
 
  602         if (numVaryingElements>0) {
 
  604             options.interpolationMode =
 
  621             poptions.SetEndCapType(
 
  623             poptions.shareEndCapPatchPoints = 
true;
 
  625             poptions.SetEndCapType(
 
  628             poptions.SetEndCapType(
 
  630             poptions.shareEndCapPatchPoints = 
true;
 
  632             poptions.SetEndCapType(
 
  641             if (Far::StencilTable 
const *vertexStencilsWithLocalPoints =
 
  646                 delete vertexStencils;
 
  647                 vertexStencils = vertexStencilsWithLocalPoints;
 
  649             if (varyingStencils) {
 
  650                 if (Far::StencilTable 
const *varyingStencilsWithLocalPoints =
 
  655                     delete varyingStencils;
 
  656                     varyingStencils = varyingStencilsWithLocalPoints;
 
  662         _patchTable = PatchTable::Create(_farPatchTable, _deviceContext);
 
  669         _vertexStencilTable =
 
  670             convertToCompatibleStencilTable<StencilTable>(
 
  671             vertexStencils, _deviceContext);
 
  672         _varyingStencilTable =
 
  673             convertToCompatibleStencilTable<StencilTable>(
 
  674             varyingStencils, _deviceContext);
 
  677         delete vertexStencils;
 
  678         delete varyingStencils;
 
  681     void initializeVertexBuffers(
int numVertices,
 
  682                                  int numVertexElements,
 
  683                                  int numVaryingElements) {
 
  685         if (numVertexElements) {
 
  686             _vertexBuffer = VertexBuffer::Create(numVertexElements,
 
  687                                                  numVertices, _deviceContext);
 
  690         if (numVaryingElements) {
 
  691             _varyingBuffer = VertexBuffer::Create(numVaryingElements,
 
  692                                                   numVertices, _deviceContext);
 
  696     Far::TopologyRefiner * _refiner;
 
  697     Far::PatchTable * _farPatchTable;
 
  705     BufferDescriptor _vertexDesc;
 
  706     BufferDescriptor _varyingDesc;
 
  719 using namespace OPENSUBDIV_VERSION;
 
  723 #endif  // OPENSUBDIV3_OSD_MESH_H 
legacy option for 2.x style Gregory patches (Catmark only) 
Entry(BufferDescriptor const &srcDescArg, BufferDescriptor const &dstDescArg, BufferDescriptor const &duDescArg, BufferDescriptor const &dvDescArg, BufferDescriptor const &duuDescArg, BufferDescriptor const &duvDescArg, BufferDescriptor const &dvvDescArg, EVALUATOR *evalArg)
static StencilTable const * AppendLocalPointStencilTable(TopologyRefiner const &refiner, StencilTable const *baseStencilTable, StencilTable const *localPointStencilTable, bool factorize=true)
Entry(BufferDescriptor const &srcDescArg, BufferDescriptor const &dstDescArg, BufferDescriptor const &duDescArg, BufferDescriptor const &dvDescArg, EVALUATOR *evalArg)
virtual int GetNumVertices() const 
EvaluatorCacheT< Evaluator > EvaluatorCache
static PatchTable * Create(TopologyRefiner const &refiner, Options options=Options(), ConstIndexArray selectedFaces=ConstIndexArray())
Instantiates a PatchTable from a client-provided TopologyRefiner. 
virtual void Synchronize()=0
STENCIL_TABLE StencilTable
std::bitset< NUM_MESH_BITS > MeshBitset
int stride
stride to the next element 
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. 
int GetNumVertices() const 
Return the number of vertices in this level. 
Adaptive refinement options. 
unsigned int useInfSharpPatch
unsigned int considerFVarChannels
void RefineAdaptive(AdaptiveOptions options, ConstIndexArray selectedFaces=ConstIndexArray())
Feature Adaptive topology refinement. 
StencilTable const * GetLocalPointStencilTable() const 
Returns the stencil table to compute local point vertex values. 
virtual int GetNumVertices() const =0
unsigned int fullTopologyInLastLevel
use Gregory patches (highest quality, recommended default) 
virtual int GetMaxValence() const =0
Limit stencil table class wrapping the template for compatibility. 
virtual PatchTable * GetPatchTable() const 
Public options for the PatchTable factory. 
virtual Far::TopologyRefiner const * GetTopologyRefiner() const 
Stores topology data for a specified set of refinement options. 
STENCIL_TABLE const * convertToCompatibleStencilTable(SRC_STENCIL_TABLE const *table, DEVICE_CONTEXT *context)
EVALUATOR * GetEvaluator(BufferDescriptor const &srcDesc, BufferDescriptor const &dstDesc, BufferDescriptor const &duDesc, BufferDescriptor const &dvDesc, DEVICE_CONTEXT *deviceContext)
virtual PatchTable * GetPatchTable() const =0
static void refineMesh(Far::TopologyRefiner &refiner, int level, bool adaptive, bool singleCreasePatch)
static void refineMesh(Far::TopologyRefiner &refiner, int level, MeshBitset bits)
int GetMaxValence() const 
Returns max vertex valence. 
static StencilTable const * Create(TopologyRefiner const &refiner, Options options=Options())
int GetNumControlVertices() const 
Returns the number of control vertices indexed in the table. 
virtual VertexBufferBinding BindVertexBuffer()
int GetNumStencils() const 
Returns the number of stencils in the table. 
TopologyLevel const & GetLevel(int level) const 
Returns a handle to access data specific to a particular level. 
PatchTable::VertexBufferBinding VertexBufferBinding
StencilTable const * GetLocalPointVaryingStencilTable() const 
Returns the stencil table to compute local point varying values. 
use BSpline-like patches (same patch type as regular) 
PatchTable::VertexBufferBinding VertexBufferBinding
DEVICE_CONTEXT DeviceContext
Container for arrays of parametric patches. 
VERTEX_BUFFER VertexBuffer
virtual int GetMaxValence() const 
virtual Far::PatchTable const * GetFarPatchTable() const =0
void RefineUniform(UniformOptions options)
Refine the topology uniformly. 
Mesh(Far::TopologyRefiner *refiner, int numVertexElements, int numVaryingElements, int level, MeshBitset bits=MeshBitset(), EvaluatorCache *evaluatorCache=NULL, DeviceContext *deviceContext=NULL)
virtual void UpdateVertexBuffer(float const *vertexData, int startVertex, int numVerts)=0
int length
number or length of the data 
virtual VertexBufferBinding BindVaryingBuffer()
int GetNumFVarChannels() const 
Returns the number of face-varying channels in the tables. 
virtual VertexBufferBinding BindVaryingBuffer()=0
virtual void Synchronize()
virtual VertexBuffer * GetVertexBuffer()
int offset
offset to desired element data 
unsigned int useSingleCreasePatch
virtual VertexBufferBinding BindVertexBuffer()=0
virtual void UpdateVaryingBuffer(float const *varyingData, int startVertex, int numVerts)
virtual void UpdateVertexBuffer(float const *vertexData, int startVertex, int numVerts)
virtual VertexBuffer * GetVaryingBuffer()
virtual Far::PatchTable const * GetFarPatchTable() const 
Stencil table class wrapping the template for compatibility. 
virtual void UpdateVaryingBuffer(float const *varyingData, int startVertex, int numVerts)=0
use linear patches (simple quads or tris) 
bool IsUniform() const 
Returns true if uniform refinement has been applied. 
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)
Uniform refinement options. 
std::vector< Entry > Evaluators
EVALUATOR * GetEvaluator(BufferDescriptor const &srcDesc, BufferDescriptor const &dstDesc, DEVICE_CONTEXT *deviceContext)