28 #include <opensubdiv/far/patchMap.h>
29 #include <opensubdiv/far/patchTable.h>
30 #include <opensubdiv/far/patchTableFactory.h>
31 #include <opensubdiv/osd/mesh.h>
32 #include <opensubdiv/osd/types.h>
33 #include <opensubdiv/version.h>
46 using OpenSubdiv::Far::PatchTable;
47 using OpenSubdiv::Far::PatchTableFactory;
48 using OpenSubdiv::Far::StencilTable;
49 using OpenSubdiv::Far::StencilTableFactory;
50 using OpenSubdiv::Far::TopologyRefiner;
51 using OpenSubdiv::Osd::PatchArray;
52 using OpenSubdiv::Osd::PatchCoord;
55 namespace opensubdiv {
60 template<
typename T,
int kNumMaxElementsOnStack>
class StackOrHeapArray {
67 explicit StackOrHeapArray(
int size) : StackOrHeapArray()
87 void resize(
int num_elements)
93 if (old_num_elements >= num_elements) {
113 T *allocate(
int num_elements)
115 if (num_elements < kNumMaxElementsOnStack) {
139 typedef StackOrHeapArray<PatchCoord, 32 * 32> StackOrHeapPatchCoordArray;
142 const int num_patch_coords,
143 const PatchMap *patch_map,
144 StackOrHeapPatchCoordArray *
array)
147 for (
int i = 0; i < num_patch_coords; ++i) {
149 patch_coords[i].ptex_face, patch_coords[i].u, patch_coords[i].
v);
150 (
array->
data())[i] = PatchCoord(*handle, patch_coords[i].u, patch_coords[i].
v);
160 : patch_map_(patch_map), implementation_(implementation)
175 const int start_vertex_index,
176 const int num_vertices)
183 const int start_vertex_index,
184 const int num_vertices)
191 const int start_vertex_index,
192 const int num_vertices)
199 const float *face_varying_data,
200 const int start_vertex_index,
201 const int num_vertices)
205 face_varying_channel, face_varying_data, start_vertex_index, num_vertices);
209 const int start_offset,
211 const int start_vertex_index,
212 const int num_vertices)
215 const unsigned char *current_buffer = (
unsigned char *)
buffer;
216 current_buffer += start_offset;
217 for (
int i = 0; i < num_vertices; ++i) {
218 const int current_vertex_index = start_vertex_index + i;
220 reinterpret_cast<const float *
>(current_buffer), current_vertex_index, 1);
226 const int start_offset,
228 const int start_vertex_index,
229 const int num_vertices)
232 const unsigned char *current_buffer = (
unsigned char *)
buffer;
233 current_buffer += start_offset;
234 for (
int i = 0; i < num_vertices; ++i) {
235 const int current_vertex_index = start_vertex_index + i;
237 reinterpret_cast<const float *
>(current_buffer), current_vertex_index, 1);
244 const int start_offset,
246 const int start_vertex_index,
247 const int num_vertices)
250 const unsigned char *current_buffer = (
unsigned char *)
buffer;
251 current_buffer += start_offset;
252 for (
int i = 0; i < num_vertices; ++i) {
253 const int current_vertex_index = start_vertex_index + i;
255 reinterpret_cast<const float *
>(current_buffer),
256 current_vertex_index,
274 assert(face_u >= 0.0f);
275 assert(face_u <= 1.0f);
276 assert(face_v >= 0.0f);
277 assert(face_v <= 1.0f);
279 PatchCoord patch_coord(*handle, face_u, face_v);
293 assert(face_u >= 0.0f);
294 assert(face_u <= 1.0f);
295 assert(face_v >= 0.0f);
296 assert(face_v <= 1.0f);
298 PatchCoord patch_coord(*handle, face_u, face_v);
307 assert(face_u >= 0.0f);
308 assert(face_u <= 1.0f);
309 assert(face_v >= 0.0f);
310 assert(face_v <= 1.0f);
312 PatchCoord patch_coord(*handle, face_u, face_v);
317 const int ptex_face_index,
320 float face_varying[2])
322 assert(face_u >= 0.0f);
323 assert(face_u <= 1.0f);
324 assert(face_v >= 0.0f);
325 assert(face_v <= 1.0f);
327 PatchCoord patch_coord(*handle, face_u, face_v);
332 const int num_patch_coords,
337 StackOrHeapPatchCoordArray patch_coords_array;
338 convertPatchCoordsToArray(patch_coords, num_patch_coords,
patch_map_, &patch_coords_array);
341 patch_coords_array.data(), num_patch_coords,
P, dPdu, dPdv);
353 int *patches_are_triangular)
362 patch_map_handles->
alloc(patch_map_handles,
handles.size()));
367 patch_map_quadtree->
alloc(patch_map_quadtree, quadtree.size()));
447 if (refiner ==
NULL) {
452 const bool has_varying_data =
false;
453 const int num_face_varying_channels = refiner->GetNumFVarChannels();
454 const bool has_face_varying_data = (num_face_varying_channels != 0);
458 const bool stencil_generate_intermediate_levels =
is_adaptive;
459 const bool stencil_generate_offsets =
true;
460 const bool use_inf_sharp_patch =
true;
464 TopologyRefiner::AdaptiveOptions
options(level);
465 options.considerFVarChannels = has_face_varying_data;
466 options.useInfSharpPatch = use_inf_sharp_patch;
467 refiner->RefineAdaptive(
options);
470 TopologyRefiner::UniformOptions
options(level);
471 refiner->RefineUniform(
options);
477 StencilTableFactory::Options vertex_stencil_options;
478 vertex_stencil_options.generateOffsets = stencil_generate_offsets;
479 vertex_stencil_options.generateIntermediateLevels = stencil_generate_intermediate_levels;
480 const StencilTable *vertex_stencils = StencilTableFactory::Create(*refiner,
481 vertex_stencil_options);
486 const StencilTable *varying_stencils =
NULL;
487 if (has_varying_data) {
488 StencilTableFactory::Options varying_stencil_options;
489 varying_stencil_options.generateOffsets = stencil_generate_offsets;
490 varying_stencil_options.generateIntermediateLevels = stencil_generate_intermediate_levels;
491 varying_stencil_options.interpolationMode = StencilTableFactory::INTERPOLATE_VARYING;
492 varying_stencils = StencilTableFactory::Create(*refiner, varying_stencil_options);
496 all_face_varying_stencils.reserve(num_face_varying_channels);
497 for (
int face_varying_channel = 0; face_varying_channel < num_face_varying_channels;
498 ++face_varying_channel) {
499 StencilTableFactory::Options face_varying_stencil_options;
500 face_varying_stencil_options.generateOffsets = stencil_generate_offsets;
501 face_varying_stencil_options.generateIntermediateLevels = stencil_generate_intermediate_levels;
502 face_varying_stencil_options.interpolationMode = StencilTableFactory::INTERPOLATE_FACE_VARYING;
503 face_varying_stencil_options.fvarChannel = face_varying_channel;
504 all_face_varying_stencils.push_back(
505 StencilTableFactory::Create(*refiner, face_varying_stencil_options));
508 PatchTableFactory::Options patch_options(level);
509 patch_options.SetEndCapType(PatchTableFactory::Options::ENDCAP_GREGORY_BASIS);
510 patch_options.useInfSharpPatch = use_inf_sharp_patch;
511 patch_options.generateFVarTables = has_face_varying_data;
512 patch_options.generateFVarLegacyLinearPatches =
false;
513 const PatchTable *patch_table = PatchTableFactory::Create(*refiner, patch_options);
516 const StencilTable *local_point_stencil_table = patch_table->GetLocalPointStencilTable();
517 if (local_point_stencil_table !=
NULL) {
518 const StencilTable *table = StencilTableFactory::AppendLocalPointStencilTable(
519 *refiner, vertex_stencils, local_point_stencil_table);
520 delete vertex_stencils;
521 vertex_stencils = table;
524 if (has_varying_data) {
525 const StencilTable *local_point_varying_stencil_table =
526 patch_table->GetLocalPointVaryingStencilTable();
527 if (local_point_varying_stencil_table !=
NULL) {
528 const StencilTable *table = StencilTableFactory::AppendLocalPointStencilTable(
529 *refiner, varying_stencils, local_point_varying_stencil_table);
530 delete varying_stencils;
531 varying_stencils = table;
534 for (
int face_varying_channel = 0; face_varying_channel < num_face_varying_channels;
535 ++face_varying_channel) {
536 const StencilTable *table = StencilTableFactory::AppendLocalPointStencilTableFaceVarying(
538 all_face_varying_stencils[face_varying_channel],
539 patch_table->GetLocalPointFaceVaryingStencilTable(face_varying_channel),
540 face_varying_channel);
542 delete all_face_varying_stencils[face_varying_channel];
543 all_face_varying_stencils[face_varying_channel] = table;
550 if (use_gpu_evaluator) {
552 if (evaluator_cache_descr) {
559 all_face_varying_stencils,
566 vertex_stencils, varying_stencils, all_face_varying_stencils, 2, patch_table);
578 delete vertex_stencils;
579 delete varying_stencils;
580 for (
const StencilTable *table : all_face_varying_stencils) {
583 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.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a vector
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
T * resize(size_t newsize)
virtual void wrapPatchIndexBuffer(OpenSubdiv_Buffer *)
virtual void evalPatches(const PatchCoord *patch_coord, const int num_patch_coords, float *P)=0
virtual void fillFVarPatchArraysBuffer(const int, OpenSubdiv_Buffer *)
virtual void evalPatchesVertexData(const PatchCoord *patch_coord, const int num_patch_coords, float *vertex_data)=0
virtual void evalPatchesWithDerivatives(const PatchCoord *patch_coord, const int num_patch_coords, float *P, float *dPdu, float *dPdv)=0
virtual void wrapPatchParamBuffer(OpenSubdiv_Buffer *)
virtual void wrapFVarPatchParamBuffer(const int, OpenSubdiv_Buffer *)
virtual void wrapFVarPatchIndexBuffer(const int, OpenSubdiv_Buffer *)
virtual void wrapSrcVertexDataBuffer(OpenSubdiv_Buffer *)
virtual bool hasVertexData() const
virtual void updateVertexData(const float *src, int start_vertex, int num_vertices)=0
virtual void fillPatchArraysBuffer(OpenSubdiv_Buffer *)
virtual void updateData(const float *src, int start_vertex, int num_vertices)=0
virtual void evalPatchesVarying(const PatchCoord *patch_coord, const int num_patch_coords, float *varying)=0
virtual void updateSettings(const OpenSubdiv_EvaluatorSettings *settings)=0
virtual void updateFaceVaryingData(const int face_varying_channel, const float *src, int start_vertex, int num_vertices)=0
virtual void evalPatchesFaceVarying(const int face_varying_channel, const PatchCoord *patch_coord, const int num_patch_coords, float face_varying[2])=0
virtual void wrapFVarSrcBuffer(const int, OpenSubdiv_Buffer *)
virtual void wrapSrcBuffer(OpenSubdiv_Buffer *)
virtual void updateVaryingData(const float *src, int start_vertex, int num_vertices)=0
void setVaryingData(const float *varying_data, const int start_vertex_index, const int num_vertices)
void wrapSrcBuffer(OpenSubdiv_Buffer *src_buffer)
void wrapFVarSrcBuffer(const int face_varying_channel, OpenSubdiv_Buffer *src_buffer)
void evaluatePatchesLimit(const OpenSubdiv_PatchCoord *patch_coords, const int num_patch_coords, float *P, float *dPdu, float *dPdv)
void wrapPatchIndexBuffer(OpenSubdiv_Buffer *patch_index_buffer)
void fillPatchArraysBuffer(OpenSubdiv_Buffer *patch_arrays_buffer)
void setSettings(const OpenSubdiv_EvaluatorSettings *settings)
void wrapPatchParamBuffer(OpenSubdiv_Buffer *patch_param_buffer)
void evaluateLimit(const int ptex_face_index, float face_u, float face_v, float P[3], float dPdu[3], float dPdv[3])
void evaluateFaceVarying(const int face_varying_channel, const int ptes_face_index, float face_u, float face_v, float face_varying[2])
void setFaceVaryingData(const int face_varying_channel, const float *varying_data, const int start_vertex_index, const int num_vertices)
void getPatchMap(OpenSubdiv_Buffer *patch_map_handles, OpenSubdiv_Buffer *patch_map_quadtree, int *min_patch_face, int *max_patch_face, int *max_depth, int *patches_are_triangular)
void wrapFVarPatchIndexBuffer(const int face_varying_channel, OpenSubdiv_Buffer *patch_index_buffer)
EvalOutput * implementation_
void fillFVarPatchArraysBuffer(const int face_varying_channel, OpenSubdiv_Buffer *patch_arrays_buffer)
void wrapSrcVertexDataBuffer(OpenSubdiv_Buffer *src_buffer)
void evaluateVertexData(const int ptes_face_index, float face_u, float face_v, float data[])
void setCoarsePositionsFromBuffer(const void *buffer, const int start_offset, const int stride, const int start_vertex_index, const int num_vertices)
void wrapFVarPatchParamBuffer(const int face_varying_channel, OpenSubdiv_Buffer *patch_param_buffer)
void setVaryingDataFromBuffer(const void *buffer, const int start_offset, const int stride, const int start_vertex_index, const int num_vertices)
bool hasVertexData() const
EvalOutputAPI(EvalOutput *implementation, PatchMap *patch_map)
void evaluateVarying(const int ptes_face_index, float face_u, float face_v, float varying[3])
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)
void setVertexData(const float *data, const int start_vertex_index, const int num_vertices)
void setCoarsePositions(const float *positions, const int start_vertex_index, const int num_vertices)
An quadtree-based map connecting coarse faces to their sub-patches.
const std::vector< QuadNode > & nodes()
int getMinPatchFace() const
bool getPatchesAreTriangular() const
const std::vector< Handle > & getHandles()
Handle const * FindPatch(int patchFaceId, double u, double v) const
Returns a handle to the sub-patch of the face at the given (u,v). Note that the patch face ID corresp...
int getMaxPatchFace() const
OpenSubdiv::Far::TopologyRefiner * topology_refiner
OpenSubdiv::Osd::EvaluatorCacheT< GLComputeEvaluator > EvaluatorCache
CCL_NAMESPACE_BEGIN struct Options options
OpenSubdiv_EvaluatorImpl * openSubdiv_createEvaluatorInternal(OpenSubdiv_TopologyRefiner *topology_refiner, eOpenSubdivEvaluator evaluator_type, OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr)
void openSubdiv_deleteEvaluatorInternal(OpenSubdiv_EvaluatorImpl *evaluator)
T stack_elements_[kNumMaxElementsOnStack]
ccl_global float * buffer
CCL_NAMESPACE_BEGIN struct PatchHandle PatchHandle
bool is_adaptive(CpuPatchTable *patch_table)
MutableSpan< float3 > positions
@ OPENSUBDIV_EVALUATOR_GPU
void *(* alloc)(const struct OpenSubdiv_Buffer *buffer, const unsigned int size)
const blender::opensubdiv::PatchMap * patch_map
blender::opensubdiv::EvalOutputAPI * eval_output
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)