16#include <opensubdiv/far/patchMap.h>
17#include <opensubdiv/far/patchTable.h>
18#include <opensubdiv/far/patchTableFactory.h>
19#include <opensubdiv/osd/mesh.h>
20#include <opensubdiv/osd/types.h>
21#include <opensubdiv/version.h>
33using OpenSubdiv::Far::PatchTable;
34using OpenSubdiv::Far::PatchTableFactory;
35using OpenSubdiv::Far::StencilTable;
36using OpenSubdiv::Far::StencilTableFactory;
37using OpenSubdiv::Far::TopologyRefiner;
38using OpenSubdiv::Osd::PatchArray;
39using OpenSubdiv::Osd::PatchCoord;
77 if (old_num_elements >= num_elements) {
100 if (num_elements < kNumMaxElementsOnStack) {
127 const int num_patch_coords,
132 for (
int i = 0; i < num_patch_coords; ++i) {
133 const PatchTable::PatchHandle *handle = patch_map->
FindPatch(
134 patch_coords[i].ptex_face, patch_coords[i].u, patch_coords[i].
v);
135 (
array->
data())[i] = PatchCoord(*handle, patch_coords[i].u, patch_coords[i].
v);
143 : patch_map_(patch_map), implementation_(implementation)
158 const int start_vertex_index,
159 const int num_vertices)
166 const int start_vertex_index,
167 const int num_vertices)
174 const int start_vertex_index,
175 const int num_vertices)
182 const float *face_varying_data,
183 const int start_vertex_index,
184 const int num_vertices)
188 face_varying_channel, face_varying_data, start_vertex_index, num_vertices);
192 const int start_offset,
194 const int start_vertex_index,
195 const int num_vertices)
198 const unsigned char *current_buffer = (
unsigned char *)buffer;
199 current_buffer += start_offset;
200 for (
int i = 0; i < num_vertices; ++i) {
201 const int current_vertex_index = start_vertex_index + i;
203 reinterpret_cast<const float *
>(current_buffer), current_vertex_index, 1);
204 current_buffer += stride;
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);
221 current_buffer += stride;
227 const int start_offset,
229 const int start_vertex_index,
230 const int num_vertices)
233 const unsigned char *current_buffer = (
unsigned char *)buffer;
234 current_buffer += start_offset;
235 for (
int i = 0; i < num_vertices; ++i) {
236 const int current_vertex_index = start_vertex_index + i;
238 reinterpret_cast<const float *
>(current_buffer),
239 current_vertex_index,
241 current_buffer += stride;
257 assert(face_u >= 0.0f);
258 assert(face_u <= 1.0f);
259 assert(face_v >= 0.0f);
260 assert(face_v <= 1.0f);
261 const PatchTable::PatchHandle *handle =
patch_map_->
FindPatch(ptex_face_index, face_u, face_v);
262 PatchCoord patch_coord(*handle, face_u, face_v);
276 assert(face_u >= 0.0f);
277 assert(face_u <= 1.0f);
278 assert(face_v >= 0.0f);
279 assert(face_v <= 1.0f);
280 const PatchTable::PatchHandle *handle =
patch_map_->
FindPatch(ptex_face_index, face_u, face_v);
281 PatchCoord patch_coord(*handle, face_u, face_v);
290 assert(face_u >= 0.0f);
291 assert(face_u <= 1.0f);
292 assert(face_v >= 0.0f);
293 assert(face_v <= 1.0f);
294 const PatchTable::PatchHandle *handle =
patch_map_->
FindPatch(ptex_face_index, face_u, face_v);
295 PatchCoord patch_coord(*handle, face_u, face_v);
300 const int ptex_face_index,
303 float face_varying[2])
305 assert(face_u >= 0.0f);
306 assert(face_u <= 1.0f);
307 assert(face_v >= 0.0f);
308 assert(face_v <= 1.0f);
309 const PatchTable::PatchHandle *handle =
patch_map_->
FindPatch(ptex_face_index, face_u, face_v);
310 PatchCoord patch_coord(*handle, face_u, face_v);
315 const int num_patch_coords,
324 patch_coords_array.
data(), num_patch_coords,
P, dPdu, dPdv);
336 int *patches_are_triangular)
344 PatchTable::PatchHandle *buffer_handles =
static_cast<PatchTable::PatchHandle *
>(
345 patch_map_handles->
alloc(patch_map_handles, handles.size()));
346 memcpy(buffer_handles, &handles[0],
sizeof(PatchTable::PatchHandle) * handles.size());
350 patch_map_quadtree->
alloc(patch_map_quadtree, quadtree.size()));
428 if (refiner ==
NULL) {
433 const bool has_varying_data =
false;
434 const int num_face_varying_channels = refiner->GetNumFVarChannels();
435 const bool has_face_varying_data = (num_face_varying_channels != 0);
439 const bool stencil_generate_intermediate_levels = is_adaptive;
440 const bool stencil_generate_offsets =
true;
441 const bool use_inf_sharp_patch =
true;
445 TopologyRefiner::AdaptiveOptions
options(level);
446 options.considerFVarChannels = has_face_varying_data;
447 options.useInfSharpPatch = use_inf_sharp_patch;
448 refiner->RefineAdaptive(
options);
451 TopologyRefiner::UniformOptions
options(level);
452 refiner->RefineUniform(
options);
458 StencilTableFactory::Options vertex_stencil_options;
459 vertex_stencil_options.generateOffsets = stencil_generate_offsets;
460 vertex_stencil_options.generateIntermediateLevels = stencil_generate_intermediate_levels;
461 const StencilTable *vertex_stencils = StencilTableFactory::Create(*refiner,
462 vertex_stencil_options);
467 const StencilTable *varying_stencils =
NULL;
468 if (has_varying_data) {
469 StencilTableFactory::Options varying_stencil_options;
470 varying_stencil_options.generateOffsets = stencil_generate_offsets;
471 varying_stencil_options.generateIntermediateLevels = stencil_generate_intermediate_levels;
472 varying_stencil_options.interpolationMode = StencilTableFactory::INTERPOLATE_VARYING;
473 varying_stencils = StencilTableFactory::Create(*refiner, varying_stencil_options);
476 std::vector<const StencilTable *> all_face_varying_stencils;
477 all_face_varying_stencils.reserve(num_face_varying_channels);
478 for (
int face_varying_channel = 0; face_varying_channel < num_face_varying_channels;
479 ++face_varying_channel)
481 StencilTableFactory::Options face_varying_stencil_options;
482 face_varying_stencil_options.generateOffsets = stencil_generate_offsets;
483 face_varying_stencil_options.generateIntermediateLevels = stencil_generate_intermediate_levels;
484 face_varying_stencil_options.interpolationMode = StencilTableFactory::INTERPOLATE_FACE_VARYING;
485 face_varying_stencil_options.fvarChannel = face_varying_channel;
486 all_face_varying_stencils.push_back(
487 StencilTableFactory::Create(*refiner, face_varying_stencil_options));
490 PatchTableFactory::Options patch_options(level);
491 patch_options.SetEndCapType(PatchTableFactory::Options::ENDCAP_GREGORY_BASIS);
492 patch_options.useInfSharpPatch = use_inf_sharp_patch;
493 patch_options.generateFVarTables = has_face_varying_data;
494 patch_options.generateFVarLegacyLinearPatches =
false;
495 const PatchTable *patch_table = PatchTableFactory::Create(*refiner, patch_options);
498 const StencilTable *local_point_stencil_table = patch_table->GetLocalPointStencilTable();
499 if (local_point_stencil_table !=
NULL) {
500 const StencilTable *table = StencilTableFactory::AppendLocalPointStencilTable(
501 *refiner, vertex_stencils, local_point_stencil_table);
502 delete vertex_stencils;
503 vertex_stencils = table;
506 if (has_varying_data) {
507 const StencilTable *local_point_varying_stencil_table =
508 patch_table->GetLocalPointVaryingStencilTable();
509 if (local_point_varying_stencil_table !=
NULL) {
510 const StencilTable *table = StencilTableFactory::AppendLocalPointStencilTable(
511 *refiner, varying_stencils, local_point_varying_stencil_table);
512 delete varying_stencils;
513 varying_stencils = table;
516 for (
int face_varying_channel = 0; face_varying_channel < num_face_varying_channels;
517 ++face_varying_channel)
519 const StencilTable *table = StencilTableFactory::AppendLocalPointStencilTableFaceVarying(
521 all_face_varying_stencils[face_varying_channel],
522 patch_table->GetLocalPointFaceVaryingStencilTable(face_varying_channel),
523 face_varying_channel);
525 delete all_face_varying_stencils[face_varying_channel];
526 all_face_varying_stencils[face_varying_channel] = table;
533 if (use_gpu_evaluator) {
535 if (evaluator_cache_descr) {
542 all_face_varying_stencils,
549 vertex_stencils, varying_stencils, all_face_varying_stencils, 2, patch_table);
561 delete vertex_stencils;
562 delete varying_stencils;
563 for (
const StencilTable *table : all_face_varying_stencils) {
566 return evaluator_descr;
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v
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.
int getMinPatchFace() const
const std::vector< QuadNode > & nodes()
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
T * allocate(int num_elements)
T stack_elements_[kNumMaxElementsOnStack]
void resize(int num_elements)
StackOrHeapArray(int size)
OpenSubdiv::Far::TopologyRefiner * topology_refiner
OpenSubdiv_TopologyRefinerSettings settings
OpenSubdiv::Osd::EvaluatorCacheT< GLComputeEvaluator > EvaluatorCache
CCL_NAMESPACE_BEGIN struct Options options
void openSubdiv_deleteEvaluatorInternal(OpenSubdiv_EvaluatorImpl *evaluator)
OpenSubdiv_EvaluatorImpl * openSubdiv_createEvaluatorInternal(blender::opensubdiv::TopologyRefinerImpl *topology_refiner, eOpenSubdivEvaluator evaluator_type, OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr)
StackOrHeapArray< PatchCoord, 32 *32 > StackOrHeapPatchCoordArray
static void convertPatchCoordsToArray(const OpenSubdiv_PatchCoord *patch_coords, const int num_patch_coords, const PatchMap *patch_map, StackOrHeapPatchCoordArray *array)
@ OPENSUBDIV_EVALUATOR_GPU
void *(* alloc)(const 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()