diff options
Diffstat (limited to 'intern')
9 files changed, 156 insertions, 9 deletions
diff --git a/intern/opensubdiv/internal/evaluator/eval_output.h b/intern/opensubdiv/internal/evaluator/eval_output.h index a55b89001a4..cff7c8d18c9 100644 --- a/intern/opensubdiv/internal/evaluator/eval_output.h +++ b/intern/opensubdiv/internal/evaluator/eval_output.h @@ -46,6 +46,8 @@ class EvalOutputAPI::EvalOutput { virtual void updateVaryingData(const float *src, int start_vertex, int num_vertices) = 0; + virtual void updateVertexData(const float *src, int start_vertex, int num_vertices) = 0; + virtual void updateFaceVaryingData(const int face_varying_channel, const float *src, int start_vertex, @@ -70,6 +72,11 @@ class EvalOutputAPI::EvalOutput { const int num_patch_coords, float *varying) = 0; + // NOTE: vertex_data must point to a memory of at least float*num_vertex_data. + virtual void evalPatchesVertexData(const PatchCoord *patch_coord, + const int num_patch_coords, + float *vertex_data) = 0; + virtual void evalPatchesFaceVarying(const int face_varying_channel, const PatchCoord *patch_coord, const int num_patch_coords, @@ -331,11 +338,13 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput { const StencilTable *varying_stencils, const vector<const StencilTable *> &all_face_varying_stencils, const int face_varying_width, + const int vertex_data_width, const PatchTable *patch_table, EvaluatorCache *evaluator_cache = NULL, DEVICE_CONTEXT *device_context = NULL) : src_desc_(0, 3, 3), src_varying_desc_(0, 3, 3), + src_vertex_data_desc_(0, vertex_data_width, vertex_data_width), face_varying_width_(face_varying_width), evaluator_cache_(evaluator_cache), device_context_(device_context) @@ -352,6 +361,16 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput { device_context_); varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(varying_stencils, device_context_); + + // Optionally allocate additional data to be subdivided like vertex coordinates. + if (vertex_data_width > 0) { + src_vertex_data_ = SRC_VERTEX_BUFFER::Create( + vertex_data_width, num_total_vertices, device_context_); + } + else { + src_vertex_data_ = NULL; + } + // Create evaluators for every face varying channel. face_varying_evaluators.reserve(all_face_varying_stencils.size()); int face_varying_channel = 0; @@ -370,6 +389,7 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput { { delete src_data_; delete src_varying_data_; + delete src_vertex_data_; delete patch_table_; delete vertex_stencils_; delete varying_stencils_; @@ -390,6 +410,11 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput { src_varying_data_->UpdateData(src, start_vertex, num_vertices, device_context_); } + void updateVertexData(const float *src, int start_vertex, int num_vertices) override + { + src_vertex_data_->UpdateData(src, start_vertex, num_vertices, device_context_); + } + void updateFaceVaryingData(const int face_varying_channel, const float *src, int start_vertex, @@ -426,6 +451,22 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput { vertex_stencils_, eval_instance, device_context_); + + // Evaluate smoothly interpolated vertex data. + if (src_vertex_data_) { + BufferDescriptor dst_vertex_data_desc = src_vertex_data_desc_; + dst_vertex_data_desc.offset += num_coarse_vertices_ * src_vertex_data_desc_.stride; + const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>( + evaluator_cache_, src_vertex_data_desc_, dst_vertex_data_desc, device_context_); + EVALUATOR::EvalStencils(src_vertex_data_, + src_vertex_data_desc_, + src_vertex_data_, + dst_vertex_data_desc, + vertex_stencils_, + eval_instance, + device_context_); + } + // Evaluate varying data. if (hasVaryingData()) { BufferDescriptor dst_varying_desc = src_varying_desc_; @@ -521,6 +562,27 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput { device_context_); } + // NOTE: data must point to a memory of at least float*num_vertex_data. + void evalPatchesVertexData(const PatchCoord *patch_coord, + const int num_patch_coords, + float *data) override + { + RawDataWrapperBuffer<float> vertex_data(data); + BufferDescriptor vertex_desc(0, src_vertex_data_desc_.length, src_vertex_data_desc_.length); + ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords); + const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>( + evaluator_cache_, src_vertex_data_desc_, vertex_desc, device_context_); + EVALUATOR::EvalPatches(src_vertex_data_, + src_vertex_data_desc_, + &vertex_data, + vertex_desc, + patch_coord_buffer.GetNumVertices(), + &patch_coord_buffer, + patch_table_, + eval_instance, + device_context_); + } + void evalPatchesFaceVarying(const int face_varying_channel, const PatchCoord *patch_coord, const int num_patch_coords, @@ -560,9 +622,11 @@ class VolatileEvalOutput : public EvalOutputAPI::EvalOutput { private: SRC_VERTEX_BUFFER *src_data_; SRC_VERTEX_BUFFER *src_varying_data_; + SRC_VERTEX_BUFFER *src_vertex_data_; PATCH_TABLE *patch_table_; BufferDescriptor src_desc_; BufferDescriptor src_varying_desc_; + BufferDescriptor src_vertex_data_desc_; int num_coarse_vertices_; diff --git a/intern/opensubdiv/internal/evaluator/eval_output_cpu.h b/intern/opensubdiv/internal/evaluator/eval_output_cpu.h index 58bae7a322e..2b3c738d6ab 100644 --- a/intern/opensubdiv/internal/evaluator/eval_output_cpu.h +++ b/intern/opensubdiv/internal/evaluator/eval_output_cpu.h @@ -44,6 +44,7 @@ class CpuEvalOutput : public VolatileEvalOutput<CpuVertexBuffer, const StencilTable *varying_stencils, const vector<const StencilTable *> &all_face_varying_stencils, const int face_varying_width, + const int vertex_data_width, const PatchTable *patch_table, EvaluatorCache *evaluator_cache = NULL) : VolatileEvalOutput<CpuVertexBuffer, @@ -54,6 +55,7 @@ class CpuEvalOutput : public VolatileEvalOutput<CpuVertexBuffer, varying_stencils, all_face_varying_stencils, face_varying_width, + vertex_data_width, patch_table, evaluator_cache) { diff --git a/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc b/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc index b352ed2c014..566071d581b 100644 --- a/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc +++ b/intern/opensubdiv/internal/evaluator/eval_output_gpu.cc @@ -45,6 +45,7 @@ GpuEvalOutput::GpuEvalOutput(const StencilTable *vertex_stencils, const StencilTable *varying_stencils, const vector<const StencilTable *> &all_face_varying_stencils, const int face_varying_width, + const int vertex_data_width, const PatchTable *patch_table, VolatileEvalOutput::EvaluatorCache *evaluator_cache) : VolatileEvalOutput<GLVertexBuffer, @@ -55,6 +56,7 @@ GpuEvalOutput::GpuEvalOutput(const StencilTable *vertex_stencils, varying_stencils, all_face_varying_stencils, face_varying_width, + vertex_data_width, patch_table, evaluator_cache) { diff --git a/intern/opensubdiv/internal/evaluator/eval_output_gpu.h b/intern/opensubdiv/internal/evaluator/eval_output_gpu.h index dc137e4322e..2306a87b87c 100644 --- a/intern/opensubdiv/internal/evaluator/eval_output_gpu.h +++ b/intern/opensubdiv/internal/evaluator/eval_output_gpu.h @@ -40,6 +40,7 @@ class GpuEvalOutput : public VolatileEvalOutput<GLVertexBuffer, const StencilTable *varying_stencils, const vector<const StencilTable *> &all_face_varying_stencils, const int face_varying_width, + const int vertex_data_width, const PatchTable *patch_table, EvaluatorCache *evaluator_cache = NULL); diff --git a/intern/opensubdiv/internal/evaluator/evaluator_capi.cc b/intern/opensubdiv/internal/evaluator/evaluator_capi.cc index 567afd3a763..8a54ed653dc 100644 --- a/intern/opensubdiv/internal/evaluator/evaluator_capi.cc +++ b/intern/opensubdiv/internal/evaluator/evaluator_capi.cc @@ -36,6 +36,14 @@ void setCoarsePositions(OpenSubdiv_Evaluator *evaluator, evaluator->impl->eval_output->setCoarsePositions(positions, start_vertex_index, num_vertices); } +void setVertexData(OpenSubdiv_Evaluator *evaluator, + const float *vertex_data, + const int start_vertex_index, + const int num_vertices) +{ + evaluator->impl->eval_output->setVertexData(vertex_data, start_vertex_index, num_vertices); +} + void setVaryingData(OpenSubdiv_Evaluator *evaluator, const float *varying_data, const int start_vertex_index, @@ -115,6 +123,15 @@ void evaluatePatchesLimit(OpenSubdiv_Evaluator *evaluator, patch_coords, num_patch_coords, P, dPdu, dPdv); } +void evaluateVertexData(OpenSubdiv_Evaluator *evaluator, + const int ptex_face_index, + float face_u, + float face_v, + float vertex_data[3]) +{ + evaluator->impl->eval_output->evaluateVertexData(ptex_face_index, face_u, face_v, vertex_data); +} + void evaluateVarying(OpenSubdiv_Evaluator *evaluator, const int ptex_face_index, float face_u, @@ -206,6 +223,7 @@ void wrapFVarSrcBuffer(struct OpenSubdiv_Evaluator *evaluator, void assignFunctionPointers(OpenSubdiv_Evaluator *evaluator) { evaluator->setCoarsePositions = setCoarsePositions; + evaluator->setVertexData = setVertexData; evaluator->setVaryingData = setVaryingData; evaluator->setFaceVaryingData = setFaceVaryingData; @@ -217,6 +235,7 @@ void assignFunctionPointers(OpenSubdiv_Evaluator *evaluator) evaluator->evaluateLimit = evaluateLimit; evaluator->evaluateVarying = evaluateVarying; + evaluator->evaluateVertexData = evaluateVertexData; evaluator->evaluateFaceVarying = evaluateFaceVarying; evaluator->evaluatePatchesLimit = evaluatePatchesLimit; @@ -239,12 +258,16 @@ void assignFunctionPointers(OpenSubdiv_Evaluator *evaluator) OpenSubdiv_Evaluator *openSubdiv_createEvaluatorFromTopologyRefiner( OpenSubdiv_TopologyRefiner *topology_refiner, eOpenSubdivEvaluator evaluator_type, - OpenSubdiv_EvaluatorCache *evaluator_cache) + OpenSubdiv_EvaluatorCache *evaluator_cache, + const OpenSubdiv_EvaluatorSettings *settings) { OpenSubdiv_Evaluator *evaluator = MEM_new<OpenSubdiv_Evaluator>(__func__); assignFunctionPointers(evaluator); - evaluator->impl = openSubdiv_createEvaluatorInternal( - topology_refiner, evaluator_type, evaluator_cache ? evaluator_cache->impl : nullptr); + evaluator->impl = openSubdiv_createEvaluatorInternal(topology_refiner, + evaluator_type, + evaluator_cache ? evaluator_cache->impl : + nullptr, + settings); evaluator->type = evaluator->impl ? evaluator_type : static_cast<eOpenSubdivEvaluator>(0); return evaluator; } diff --git a/intern/opensubdiv/internal/evaluator/evaluator_impl.cc b/intern/opensubdiv/internal/evaluator/evaluator_impl.cc index 755b8bfbc81..bb9e6e7bd0d 100644 --- a/intern/opensubdiv/internal/evaluator/evaluator_impl.cc +++ b/intern/opensubdiv/internal/evaluator/evaluator_impl.cc @@ -182,6 +182,14 @@ void EvalOutputAPI::setVaryingData(const float *varying_data, implementation_->updateVaryingData(varying_data, start_vertex_index, num_vertices); } +void EvalOutputAPI::setVertexData(const float *vertex_data, + const int start_vertex_index, + const int num_vertices) +{ + // TODO(sergey): Add sanity check on indices. + implementation_->updateVertexData(vertex_data, start_vertex_index, num_vertices); +} + void EvalOutputAPI::setFaceVaryingData(const int face_varying_channel, const float *face_varying_data, const int start_vertex_index, @@ -286,6 +294,20 @@ void EvalOutputAPI::evaluateVarying(const int ptex_face_index, implementation_->evalPatchesVarying(&patch_coord, 1, varying); } +void EvalOutputAPI::evaluateVertexData(const int ptex_face_index, + float face_u, + float face_v, + float vertex_data[]) +{ + assert(face_u >= 0.0f); + assert(face_u <= 1.0f); + assert(face_v >= 0.0f); + assert(face_v <= 1.0f); + const PatchTable::PatchHandle *handle = patch_map_->FindPatch(ptex_face_index, face_u, face_v); + PatchCoord patch_coord(*handle, face_u, face_v); + implementation_->evalPatchesVertexData(&patch_coord, 1, vertex_data); +} + void EvalOutputAPI::evaluateFaceVarying(const int face_varying_channel, const int ptex_face_index, float face_u, @@ -403,7 +425,8 @@ OpenSubdiv_EvaluatorImpl::~OpenSubdiv_EvaluatorImpl() OpenSubdiv_EvaluatorImpl *openSubdiv_createEvaluatorInternal( OpenSubdiv_TopologyRefiner *topology_refiner, eOpenSubdivEvaluator evaluator_type, - OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr) + OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr, + const OpenSubdiv_EvaluatorSettings *settings) { // Only CPU and GLCompute are implemented at the moment. if (evaluator_type != OPENSUBDIV_EVALUATOR_CPU && @@ -422,6 +445,7 @@ OpenSubdiv_EvaluatorImpl *openSubdiv_createEvaluatorInternal( const bool has_face_varying_data = (num_face_varying_channels != 0); const int level = topology_refiner->getSubdivisionLevel(topology_refiner); const bool is_adaptive = topology_refiner->getIsAdaptive(topology_refiner); + const int vertex_data_width = settings->num_vertex_data; // Common settings for stencils and patches. const bool stencil_generate_intermediate_levels = is_adaptive; const bool stencil_generate_offsets = true; @@ -526,12 +550,17 @@ OpenSubdiv_EvaluatorImpl *openSubdiv_createEvaluatorInternal( varying_stencils, all_face_varying_stencils, 2, + vertex_data_width, patch_table, evaluator_cache); } else { - eval_output = new blender::opensubdiv::CpuEvalOutput( - vertex_stencils, varying_stencils, all_face_varying_stencils, 2, patch_table); + eval_output = new blender::opensubdiv::CpuEvalOutput(vertex_stencils, + varying_stencils, + all_face_varying_stencils, + 2, + vertex_data_width, + patch_table); } blender::opensubdiv::PatchMap *patch_map = new blender::opensubdiv::PatchMap(*patch_table); diff --git a/intern/opensubdiv/internal/evaluator/evaluator_impl.h b/intern/opensubdiv/internal/evaluator/evaluator_impl.h index e24d47cba79..8ecfa4477be 100644 --- a/intern/opensubdiv/internal/evaluator/evaluator_impl.h +++ b/intern/opensubdiv/internal/evaluator/evaluator_impl.h @@ -32,6 +32,7 @@ struct OpenSubdiv_Buffer; struct OpenSubdiv_EvaluatorCacheImpl; +struct OpenSubdiv_EvaluatorSettings; struct OpenSubdiv_PatchCoord; struct OpenSubdiv_TopologyRefiner; @@ -60,6 +61,8 @@ class EvalOutputAPI { void setCoarsePositions(const float *positions, const int start_vertex_index, const int num_vertices); + // Set vertex data from a continuous array of data. + void setVertexData(const float *data, const int start_vertex_index, const int num_vertices); // Set varying data from a continuous array of data. void setVaryingData(const float *varying_data, const int start_vertex_index, @@ -115,6 +118,9 @@ class EvalOutputAPI { float dPdv[3]); // Evaluate varying data at a given bilinear coordinate of given ptex face. + void evaluateVertexData(const int ptes_face_index, float face_u, float face_v, float data[]); + + // Evaluate varying data at a given bilinear coordinate of given ptex face. void evaluateVarying(const int ptes_face_index, float face_u, float face_v, float varying[3]); // Evaluate facee-varying data at a given bilinear coordinate of given @@ -198,7 +204,8 @@ struct OpenSubdiv_EvaluatorImpl { OpenSubdiv_EvaluatorImpl *openSubdiv_createEvaluatorInternal( struct OpenSubdiv_TopologyRefiner *topology_refiner, eOpenSubdivEvaluator evaluator_type, - OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr); + OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr, + const OpenSubdiv_EvaluatorSettings *settings); void openSubdiv_deleteEvaluatorInternal(OpenSubdiv_EvaluatorImpl *evaluator); diff --git a/intern/opensubdiv/opensubdiv_evaluator_capi.h b/intern/opensubdiv/opensubdiv_evaluator_capi.h index 1afd3e966f6..98e1db6e323 100644 --- a/intern/opensubdiv/opensubdiv_evaluator_capi.h +++ b/intern/opensubdiv/opensubdiv_evaluator_capi.h @@ -69,6 +69,11 @@ typedef struct OpenSubdiv_Evaluator { const float *positions, const int start_vertex_index, const int num_vertices); + // Set vertex data from a continuous array of coordinates. + void (*setVertexData)(struct OpenSubdiv_Evaluator *evaluator, + const float *data, + const int start_vertex_index, + const int num_vertices); // Set varying data from a continuous array of data. void (*setVaryingData)(struct OpenSubdiv_Evaluator *evaluator, const float *varying_data, @@ -129,6 +134,13 @@ typedef struct OpenSubdiv_Evaluator { float dPdu[3], float dPdv[3]); + // Evaluate vertex data at a given bilinear coordinate of given ptex face. + void (*evaluateVertexData)(struct OpenSubdiv_Evaluator *evaluator, + const int ptex_face_index, + float face_u, + float face_v, + float data[]); + // Evaluate varying data at a given bilinear coordinate of given ptex face. void (*evaluateVarying)(struct OpenSubdiv_Evaluator *evaluator, const int ptex_face_index, @@ -215,10 +227,16 @@ typedef struct OpenSubdiv_EvaluatorCache { struct OpenSubdiv_EvaluatorCacheImpl *impl; } OpenSubdiv_EvaluatorCache; +typedef struct OpenSubdiv_EvaluatorSettings { + // Number of smoothly interpolated vertex data channels. + int num_vertex_data; +} OpenSubdiv_EvaluatorSettings; + OpenSubdiv_Evaluator *openSubdiv_createEvaluatorFromTopologyRefiner( struct OpenSubdiv_TopologyRefiner *topology_refiner, eOpenSubdivEvaluator evaluator_type, - OpenSubdiv_EvaluatorCache *evaluator_cache); + OpenSubdiv_EvaluatorCache *evaluator_cache, + const OpenSubdiv_EvaluatorSettings *settings); void openSubdiv_deleteEvaluator(OpenSubdiv_Evaluator *evaluator); diff --git a/intern/opensubdiv/stub/opensubdiv_evaluator_stub.cc b/intern/opensubdiv/stub/opensubdiv_evaluator_stub.cc index bc39326b57d..78c1d23d2cc 100644 --- a/intern/opensubdiv/stub/opensubdiv_evaluator_stub.cc +++ b/intern/opensubdiv/stub/opensubdiv_evaluator_stub.cc @@ -23,7 +23,8 @@ OpenSubdiv_Evaluator *openSubdiv_createEvaluatorFromTopologyRefiner( struct OpenSubdiv_TopologyRefiner * /*topology_refiner*/, eOpenSubdivEvaluator /*evaluator_type*/, - OpenSubdiv_EvaluatorCache * /*evaluator_cache*/) + OpenSubdiv_EvaluatorCache * /*evaluator_cache*/, + const OpenSubdiv_EvaluatorSettings * /*settings*/) { return NULL; } |