28 #include <opensubdiv/far/patchMap.h>
29 #include <opensubdiv/far/patchTable.h>
30 #include <opensubdiv/far/patchTableFactory.h>
31 #include <opensubdiv/osd/cpuEvaluator.h>
32 #include <opensubdiv/osd/cpuPatchTable.h>
33 #include <opensubdiv/osd/cpuVertexBuffer.h>
34 #include <opensubdiv/osd/mesh.h>
35 #include <opensubdiv/osd/types.h>
36 #include <opensubdiv/version.h>
44 using OpenSubdiv::Far::PatchMap;
45 using OpenSubdiv::Far::PatchTable;
46 using OpenSubdiv::Far::PatchTableFactory;
47 using OpenSubdiv::Far::StencilTable;
48 using OpenSubdiv::Far::StencilTableFactory;
49 using OpenSubdiv::Far::TopologyRefiner;
50 using OpenSubdiv::Osd::BufferDescriptor;
51 using OpenSubdiv::Osd::CpuEvaluator;
52 using OpenSubdiv::Osd::CpuPatchTable;
53 using OpenSubdiv::Osd::CpuVertexBuffer;
54 using OpenSubdiv::Osd::PatchCoord;
57 namespace opensubdiv {
62 template<
typename T,
int kNumMaxElementsOnStack>
class StackOrHeapArray {
69 explicit StackOrHeapArray(
int size) : StackOrHeapArray()
89 void resize(
int num_elements)
95 if (old_num_elements >= num_elements) {
115 T *allocate(
int num_elements)
117 if (num_elements < kNumMaxElementsOnStack) {
141 typedef StackOrHeapArray<PatchCoord, 32 * 32> StackOrHeapPatchCoordArray;
145 template<
typename T>
class RawDataWrapperBuffer {
162 template<
typename T>
class RawDataWrapperVertexBuffer :
public RawDataWrapperBuffer<T> {
164 RawDataWrapperVertexBuffer(
T *
data,
int num_vertices)
178 class ConstPatchCoordWrapperBuffer :
public RawDataWrapperVertexBuffer<const PatchCoord> {
180 ConstPatchCoordWrapperBuffer(
const PatchCoord *
data,
int num_vertices)
181 : RawDataWrapperVertexBuffer(
data, num_vertices)
186 template<
typename EVAL_VERTEX_BUFFER,
187 typename STENCIL_TABLE,
188 typename PATCH_TABLE,
190 typename DEVICE_CONTEXT =
void>
191 class FaceVaryingVolatileEval {
193 typedef OpenSubdiv::Osd::EvaluatorCacheT<EVALUATOR> EvaluatorCache;
195 FaceVaryingVolatileEval(
int face_varying_channel,
196 const StencilTable *face_varying_stencils,
197 int face_varying_width,
198 PATCH_TABLE *patch_table,
199 EvaluatorCache *evaluator_cache =
NULL,
200 DEVICE_CONTEXT *device_context =
NULL)
207 using OpenSubdiv::Osd::convertToCompatibleStencilTable;
209 const int num_total_face_varying_vertices = face_varying_stencils->GetNumControlVertices() +
210 face_varying_stencils->GetNumStencils();
212 2, num_total_face_varying_vertices, device_context);
217 ~FaceVaryingVolatileEval()
223 void updateData(
const float *src,
int start_vertex,
int num_vertices)
233 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
240 dst_face_varying_desc,
247 void evalPatches(
const PatchCoord *patch_coord,
const int num_patch_coords,
float *face_varying)
249 RawDataWrapperBuffer<float> face_varying_data(face_varying);
250 BufferDescriptor face_varying_desc(0, 2, 2);
251 ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
252 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
263 if (!
patch_table_->GetPatchArrayBuffer()[0].GetDescriptor().IsAdaptive()) {
271 patch_coord_buffer.GetNumVertices(),
301 template<
typename SRC_VERTEX_BUFFER,
302 typename EVAL_VERTEX_BUFFER,
303 typename STENCIL_TABLE,
304 typename PATCH_TABLE,
306 typename DEVICE_CONTEXT =
void>
307 class VolatileEvalOutput {
309 typedef OpenSubdiv::Osd::EvaluatorCacheT<EVALUATOR> EvaluatorCache;
310 typedef FaceVaryingVolatileEval<EVAL_VERTEX_BUFFER,
317 VolatileEvalOutput(
const StencilTable *vertex_stencils,
318 const StencilTable *varying_stencils,
320 const int face_varying_width,
321 const PatchTable *patch_table,
322 EvaluatorCache *evaluator_cache =
NULL,
323 DEVICE_CONTEXT *device_context =
NULL)
324 : src_desc_(0, 3, 3),
325 src_varying_desc_(0, 3, 3),
326 face_varying_width_(face_varying_width),
331 int num_total_vertices = vertex_stencils->GetNumControlVertices() +
332 vertex_stencils->GetNumStencils();
333 num_coarse_vertices_ = vertex_stencils->GetNumControlVertices();
334 using OpenSubdiv::Osd::convertToCompatibleStencilTable;
335 src_data_ = SRC_VERTEX_BUFFER::Create(3, num_total_vertices,
device_context_);
336 src_varying_data_ = SRC_VERTEX_BUFFER::Create(3, num_total_vertices,
device_context_);
338 vertex_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(vertex_stencils,
340 varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(varying_stencils,
343 face_varying_evaluators.reserve(all_face_varying_stencils.size());
344 int face_varying_channel = 0;
345 for (
const StencilTable *face_varying_stencils : all_face_varying_stencils) {
346 face_varying_evaluators.push_back(
new FaceVaryingEval(face_varying_channel,
347 face_varying_stencils,
352 ++face_varying_channel;
356 ~VolatileEvalOutput()
359 delete src_varying_data_;
361 delete vertex_stencils_;
362 delete varying_stencils_;
363 for (FaceVaryingEval *face_varying_evaluator : face_varying_evaluators) {
364 delete face_varying_evaluator;
370 void updateData(
const float *src,
int start_vertex,
int num_vertices)
372 src_data_->UpdateData(src, start_vertex, num_vertices,
device_context_);
375 void updateVaryingData(
const float *src,
int start_vertex,
int num_vertices)
377 src_varying_data_->UpdateData(src, start_vertex, num_vertices,
device_context_);
380 void updateFaceVaryingData(
const int face_varying_channel,
385 assert(face_varying_channel >= 0);
386 assert(face_varying_channel < face_varying_evaluators.size());
387 face_varying_evaluators[face_varying_channel]->updateData(src, start_vertex, num_vertices);
390 bool hasVaryingData()
const
397 bool hasFaceVaryingData()
const
399 return face_varying_evaluators.size() != 0;
405 BufferDescriptor dst_desc = src_desc_;
406 dst_desc.offset += num_coarse_vertices_ * src_desc_.stride;
407 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
409 EVALUATOR::EvalStencils(src_data_,
417 if (hasVaryingData()) {
418 BufferDescriptor dst_varying_desc = src_varying_desc_;
419 dst_varying_desc.offset += num_coarse_vertices_ * src_varying_desc_.stride;
420 eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
422 EVALUATOR::EvalStencils(src_varying_data_,
431 if (hasFaceVaryingData()) {
432 for (FaceVaryingEval *face_varying_evaluator : face_varying_evaluators) {
433 face_varying_evaluator->refine();
439 void evalPatches(
const PatchCoord *patch_coord,
const int num_patch_coords,
float *
P)
441 RawDataWrapperBuffer<float> P_data(
P);
443 BufferDescriptor P_desc(0, 3, 3);
444 ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
445 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
447 EVALUATOR::EvalPatches(src_data_,
451 patch_coord_buffer.GetNumVertices(),
459 void evalPatchesWithDerivatives(
const PatchCoord *patch_coord,
460 const int num_patch_coords,
467 RawDataWrapperBuffer<float> P_data(
P);
468 RawDataWrapperBuffer<float> dPdu_data(dPdu), dPdv_data(dPdv);
470 BufferDescriptor P_desc(0, 3, 3);
471 BufferDescriptor dpDu_desc(0, 3, 3), pPdv_desc(0, 3, 3);
472 ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
473 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
475 EVALUATOR::EvalPatches(src_data_,
483 patch_coord_buffer.GetNumVertices(),
491 void evalPatchesVarying(
const PatchCoord *patch_coord,
492 const int num_patch_coords,
495 RawDataWrapperBuffer<float> varying_data(varying);
496 BufferDescriptor varying_desc(3, 3, 6);
497 ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
498 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
500 EVALUATOR::EvalPatchesVarying(src_varying_data_,
504 patch_coord_buffer.GetNumVertices(),
511 void evalPatchesFaceVarying(
const int face_varying_channel,
512 const PatchCoord *patch_coord,
513 const int num_patch_coords,
514 float face_varying[2])
516 assert(face_varying_channel >= 0);
517 assert(face_varying_channel < face_varying_evaluators.size());
518 face_varying_evaluators[face_varying_channel]->evalPatches(
519 patch_coord, num_patch_coords, face_varying);
523 SRC_VERTEX_BUFFER *src_data_;
524 SRC_VERTEX_BUFFER *src_varying_data_;
526 BufferDescriptor src_desc_;
527 BufferDescriptor src_varying_desc_;
529 int num_coarse_vertices_;
531 const STENCIL_TABLE *vertex_stencils_;
532 const STENCIL_TABLE *varying_stencils_;
534 int face_varying_width_;
542 const int num_patch_coords,
543 const OpenSubdiv::Far::PatchMap *patch_map,
544 StackOrHeapPatchCoordArray *
array)
547 for (
int i = 0; i < num_patch_coords; ++i) {
549 patch_coords[i].ptex_face, patch_coords[i].u, patch_coords[i].
v);
550 (
array->
data())[i] = PatchCoord(*handle, patch_coords[i].u, patch_coords[i].
v);
565 const StencilTable *varying_stencils,
566 const vector<const StencilTable *> &all_face_varying_stencils,
567 const int face_varying_width,
568 const PatchTable *patch_table,
569 EvaluatorCache *evaluator_cache =
NULL)
570 : VolatileEvalOutput<CpuVertexBuffer,
574 CpuEvaluator>(vertex_stencils,
576 all_face_varying_stencils,
588 OpenSubdiv::Far::PatchMap *patch_map)
589 : implementation_(implementation), patch_map_(patch_map)
599 const int start_vertex_index,
600 const int num_vertices)
603 implementation_->updateData(positions, start_vertex_index, num_vertices);
607 const int start_vertex_index,
608 const int num_vertices)
611 implementation_->updateVaryingData(varying_data, start_vertex_index, num_vertices);
615 const float *face_varying_data,
616 const int start_vertex_index,
617 const int num_vertices)
621 face_varying_channel, face_varying_data, start_vertex_index, num_vertices);
625 const int start_offset,
627 const int start_vertex_index,
628 const int num_vertices)
631 const unsigned char *current_buffer = (
unsigned char *)
buffer;
632 current_buffer += start_offset;
633 for (
int i = 0; i < num_vertices; ++i) {
634 const int current_vertex_index = start_vertex_index + i;
636 reinterpret_cast<const float *
>(current_buffer), current_vertex_index, 1);
642 const int start_offset,
644 const int start_vertex_index,
645 const int num_vertices)
648 const unsigned char *current_buffer = (
unsigned char *)
buffer;
649 current_buffer += start_offset;
650 for (
int i = 0; i < num_vertices; ++i) {
651 const int current_vertex_index = start_vertex_index + i;
653 reinterpret_cast<const float *
>(current_buffer), current_vertex_index, 1);
660 const int start_offset,
662 const int start_vertex_index,
663 const int num_vertices)
666 const unsigned char *current_buffer = (
unsigned char *)
buffer;
667 current_buffer += start_offset;
668 for (
int i = 0; i < num_vertices; ++i) {
669 const int current_vertex_index = start_vertex_index + i;
671 reinterpret_cast<const float *
>(current_buffer),
672 current_vertex_index,
690 assert(face_u >= 0.0f);
691 assert(face_u <= 1.0f);
692 assert(face_v >= 0.0f);
693 assert(face_v <= 1.0f);
695 PatchCoord patch_coord(*handle, face_u, face_v);
697 implementation_->evalPatchesWithDerivatives(&patch_coord, 1,
P, dPdu, dPdv);
709 assert(face_u >= 0.0f);
710 assert(face_u <= 1.0f);
711 assert(face_v >= 0.0f);
712 assert(face_v <= 1.0f);
714 PatchCoord patch_coord(*handle, face_u, face_v);
719 const int ptex_face_index,
722 float face_varying[2])
724 assert(face_u >= 0.0f);
725 assert(face_u <= 1.0f);
726 assert(face_v >= 0.0f);
727 assert(face_v <= 1.0f);
729 PatchCoord patch_coord(*handle, face_u, face_v);
730 implementation_->evalPatchesFaceVarying(face_varying_channel, &patch_coord, 1, face_varying);
734 const int num_patch_coords,
739 StackOrHeapPatchCoordArray patch_coords_array;
740 convertPatchCoordsToArray(patch_coords, num_patch_coords,
patch_map_, &patch_coords_array);
743 patch_coords_array.data(), num_patch_coords,
P, dPdu, dPdv);
746 implementation_->evalPatches(patch_coords_array.data(), num_patch_coords,
P);
770 if (refiner ==
NULL) {
775 const bool has_varying_data =
false;
776 const int num_face_varying_channels = refiner->GetNumFVarChannels();
777 const bool has_face_varying_data = (num_face_varying_channels != 0);
779 const bool is_adaptive = topology_refiner->
getIsAdaptive(topology_refiner);
781 const bool stencil_generate_intermediate_levels = is_adaptive;
782 const bool stencil_generate_offsets =
true;
783 const bool use_inf_sharp_patch =
true;
787 TopologyRefiner::AdaptiveOptions
options(level);
788 options.considerFVarChannels = has_face_varying_data;
789 options.useInfSharpPatch = use_inf_sharp_patch;
790 refiner->RefineAdaptive(
options);
793 TopologyRefiner::UniformOptions
options(level);
794 refiner->RefineUniform(
options);
800 StencilTableFactory::Options vertex_stencil_options;
801 vertex_stencil_options.generateOffsets = stencil_generate_offsets;
802 vertex_stencil_options.generateIntermediateLevels = stencil_generate_intermediate_levels;
803 const StencilTable *vertex_stencils = StencilTableFactory::Create(*refiner,
804 vertex_stencil_options);
809 const StencilTable *varying_stencils =
NULL;
810 if (has_varying_data) {
811 StencilTableFactory::Options varying_stencil_options;
812 varying_stencil_options.generateOffsets = stencil_generate_offsets;
813 varying_stencil_options.generateIntermediateLevels = stencil_generate_intermediate_levels;
814 varying_stencil_options.interpolationMode = StencilTableFactory::INTERPOLATE_VARYING;
815 varying_stencils = StencilTableFactory::Create(*refiner, varying_stencil_options);
819 all_face_varying_stencils.reserve(num_face_varying_channels);
820 for (
int face_varying_channel = 0; face_varying_channel < num_face_varying_channels;
821 ++face_varying_channel) {
822 StencilTableFactory::Options face_varying_stencil_options;
823 face_varying_stencil_options.generateOffsets = stencil_generate_offsets;
824 face_varying_stencil_options.generateIntermediateLevels = stencil_generate_intermediate_levels;
825 face_varying_stencil_options.interpolationMode = StencilTableFactory::INTERPOLATE_FACE_VARYING;
826 face_varying_stencil_options.fvarChannel = face_varying_channel;
827 all_face_varying_stencils.push_back(
828 StencilTableFactory::Create(*refiner, face_varying_stencil_options));
831 PatchTableFactory::Options patch_options(level);
832 patch_options.SetEndCapType(PatchTableFactory::Options::ENDCAP_GREGORY_BASIS);
833 patch_options.useInfSharpPatch = use_inf_sharp_patch;
834 patch_options.generateFVarTables = has_face_varying_data;
835 patch_options.generateFVarLegacyLinearPatches =
false;
836 const PatchTable *patch_table = PatchTableFactory::Create(*refiner, patch_options);
839 const StencilTable *local_point_stencil_table = patch_table->GetLocalPointStencilTable();
840 if (local_point_stencil_table !=
NULL) {
841 const StencilTable *table = StencilTableFactory::AppendLocalPointStencilTable(
842 *refiner, vertex_stencils, local_point_stencil_table);
843 delete vertex_stencils;
844 vertex_stencils = table;
847 if (has_varying_data) {
848 const StencilTable *local_point_varying_stencil_table =
849 patch_table->GetLocalPointVaryingStencilTable();
850 if (local_point_varying_stencil_table !=
NULL) {
851 const StencilTable *table = StencilTableFactory::AppendLocalPointStencilTable(
852 *refiner, varying_stencils, local_point_varying_stencil_table);
853 delete varying_stencils;
854 varying_stencils = table;
857 for (
int face_varying_channel = 0; face_varying_channel < num_face_varying_channels;
858 ++face_varying_channel) {
859 const StencilTable *table = StencilTableFactory::AppendLocalPointStencilTableFaceVarying(
861 all_face_varying_stencils[face_varying_channel],
862 patch_table->GetLocalPointFaceVaryingStencilTable(face_varying_channel),
863 face_varying_channel);
865 delete all_face_varying_stencils[face_varying_channel];
866 all_face_varying_stencils[face_varying_channel] = table;
872 vertex_stencils, varying_stencils, all_face_varying_stencils, 2, patch_table);
873 OpenSubdiv::Far::PatchMap *patch_map =
new PatchMap(*patch_table);
881 delete vertex_stencils;
882 delete varying_stencils;
883 for (
const StencilTable *table : all_face_varying_stencils) {
886 return evaluator_descr;
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei stride
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
T * resize(size_t newsize)
OpenSubdiv::Far::PatchMap * patch_map_
void setFaceVaryingData(const int face_varying_channel, const float *varying_data, const int start_vertex_index, const int num_vertices)
void evaluateFaceVarying(const int face_varying_channel, const int ptes_face_index, float face_u, float face_v, float face_varying[2])
void setCoarsePositions(const float *positions, const int start_vertex_index, const int num_vertices)
void evaluateLimit(const int ptex_face_index, float face_u, float face_v, float P[3], float dPdu[3], float dPdv[3])
void setCoarsePositionsFromBuffer(const void *buffer, const int start_offset, const int stride, const int start_vertex_index, const int num_vertices)
void setVaryingDataFromBuffer(const void *buffer, const int start_offset, const int stride, const int start_vertex_index, const int num_vertices)
void evaluateVarying(const int ptes_face_index, float face_u, float face_v, float varying[3])
void evaluatePatchesLimit(const OpenSubdiv_PatchCoord *patch_coords, const int num_patch_coords, float *P, float *dPdu, float *dPdv)
void setFaceVaryingDataFromBuffer(const int face_varying_channel, const void *buffer, const int start_offset, const int stride, const int start_vertex_index, const int num_vertices)
CpuEvalOutput * implementation_
CpuEvalOutputAPI(CpuEvalOutput *implementation, OpenSubdiv::Far::PatchMap *patch_map)
void setVaryingData(const float *varying_data, const int start_vertex_index, const int num_vertices)
CpuEvalOutput(const StencilTable *vertex_stencils, const StencilTable *varying_stencils, const vector< const StencilTable * > &all_face_varying_stencils, const int face_varying_width, const PatchTable *patch_table, EvaluatorCache *evaluator_cache=NULL)
OpenSubdiv::Far::TopologyRefiner * topology_refiner
CCL_NAMESPACE_BEGIN struct Options options
PATCH_TABLE * patch_table_
int num_coarse_face_varying_vertices_
BufferDescriptor src_face_varying_desc_
DEVICE_CONTEXT * device_context_
void openSubdiv_deleteEvaluatorInternal(OpenSubdiv_EvaluatorImpl *evaluator)
EvaluatorCache * evaluator_cache_
EVAL_VERTEX_BUFFER * src_face_varying_data_
OpenSubdiv_EvaluatorImpl * openSubdiv_createEvaluatorInternal(OpenSubdiv_TopologyRefiner *topology_refiner)
const STENCIL_TABLE * face_varying_stencils_
T stack_elements_[kNumMaxElementsOnStack]
int face_varying_channel_
CCL_NAMESPACE_BEGIN struct PatchHandle PatchHandle
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
std::vector< ElementType, Eigen::aligned_allocator< ElementType > > vector
blender::opensubdiv::CpuEvalOutputAPI * eval_output
const OpenSubdiv::Far::PatchMap * patch_map
const OpenSubdiv::Far::PatchTable * patch_table
OpenSubdiv_EvaluatorImpl()
~OpenSubdiv_EvaluatorImpl()
struct OpenSubdiv_TopologyRefinerImpl * impl
bool(* getIsAdaptive)(const struct OpenSubdiv_TopologyRefiner *topology_refiner)
int(* getSubdivisionLevel)(const struct OpenSubdiv_TopologyRefiner *topology_refiner)