19 #ifndef OPENSUBDIV_EVAL_OUTPUT_H_
20 #define OPENSUBDIV_EVAL_OUTPUT_H_
22 #include <opensubdiv/osd/cpuPatchTable.h>
23 #include <opensubdiv/osd/glPatchTable.h>
24 #include <opensubdiv/osd/mesh.h>
25 #include <opensubdiv/osd/types.h>
32 using OpenSubdiv::Far::PatchTable;
33 using OpenSubdiv::Far::StencilTable;
34 using OpenSubdiv::Osd::BufferDescriptor;
35 using OpenSubdiv::Osd::CpuPatchTable;
36 using OpenSubdiv::Osd::GLPatchTable;
37 using OpenSubdiv::Osd::PatchCoord;
40 namespace opensubdiv {
49 virtual void updateData(
const float *
src,
int start_vertex,
int num_vertices) = 0;
58 int num_vertices) = 0;
64 const int num_patch_coords,
69 const int num_patch_coords,
76 const int num_patch_coords,
81 const int num_patch_coords,
82 float *vertex_data) = 0;
85 const PatchCoord *patch_coord,
86 const int num_patch_coords,
87 float face_varying[2]) = 0;
144 template<
typename T>
class RawDataWrapperBuffer {
166 template<
typename T>
class RawDataWrapperVertexBuffer :
public RawDataWrapperBuffer<T> {
168 RawDataWrapperVertexBuffer(
T *
data,
int num_vertices)
182 class ConstPatchCoordWrapperBuffer :
public RawDataWrapperVertexBuffer<const PatchCoord> {
184 ConstPatchCoordWrapperBuffer(
const PatchCoord *
data,
int num_vertices)
185 : RawDataWrapperVertexBuffer(
data, num_vertices)
196 template<
typename EVAL_VERTEX_BUFFER,
197 typename STENCIL_TABLE,
198 typename PATCH_TABLE,
200 typename DEVICE_CONTEXT =
void>
206 const StencilTable *face_varying_stencils,
207 int face_varying_width,
208 PATCH_TABLE *patch_table,
210 DEVICE_CONTEXT *device_context =
NULL)
217 using OpenSubdiv::Osd::convertToCompatibleStencilTable;
219 const int num_total_face_varying_vertices = face_varying_stencils->GetNumControlVertices() +
220 face_varying_stencils->GetNumStencils();
222 2, num_total_face_varying_vertices, device_context);
243 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
250 dst_face_varying_desc,
257 void evalPatches(
const PatchCoord *patch_coord,
const int num_patch_coords,
float *face_varying)
259 RawDataWrapperBuffer<float> face_varying_data(face_varying);
260 BufferDescriptor face_varying_desc(0, 2, 2);
261 ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
262 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
265 BufferDescriptor src_desc = get_src_varying_desc();
271 patch_coord_buffer.GetNumVertices(),
286 BufferDescriptor src_desc = get_src_varying_desc();
287 return src_desc.offset;
296 BufferDescriptor get_src_varying_desc()
const
334 template<
typename SRC_VERTEX_BUFFER,
335 typename EVAL_VERTEX_BUFFER,
336 typename STENCIL_TABLE,
337 typename PATCH_TABLE,
339 typename DEVICE_CONTEXT =
void>
351 const StencilTable *varying_stencils,
352 const vector<const StencilTable *> &all_face_varying_stencils,
353 const int face_varying_width,
354 const PatchTable *patch_table,
356 DEVICE_CONTEXT *device_context =
NULL)
357 : src_vertex_data_(
NULL),
359 src_varying_desc_(0, 3, 3),
360 src_vertex_data_desc_(0, 0, 0),
361 face_varying_width_(face_varying_width),
362 evaluator_cache_(evaluator_cache),
363 device_context_(device_context)
366 int num_total_vertices = vertex_stencils->GetNumControlVertices() +
367 vertex_stencils->GetNumStencils();
368 num_coarse_vertices_ = vertex_stencils->GetNumControlVertices();
369 using OpenSubdiv::Osd::convertToCompatibleStencilTable;
370 src_data_ = SRC_VERTEX_BUFFER::Create(3, num_total_vertices, device_context_);
371 src_varying_data_ = SRC_VERTEX_BUFFER::Create(3, num_total_vertices, device_context_);
372 patch_table_ = PATCH_TABLE::Create(patch_table, device_context_);
373 vertex_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(vertex_stencils,
375 varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(varying_stencils,
379 face_varying_evaluators_.reserve(all_face_varying_stencils.size());
380 int face_varying_channel = 0;
381 for (
const StencilTable *face_varying_stencils : all_face_varying_stencils) {
382 face_varying_evaluators_.push_back(
new FaceVaryingEval(face_varying_channel,
383 face_varying_stencils,
388 ++face_varying_channel;
395 delete src_varying_data_;
396 delete src_vertex_data_;
398 delete vertex_stencils_;
399 delete varying_stencils_;
400 for (
FaceVaryingEval *face_varying_evaluator : face_varying_evaluators_) {
401 delete face_varying_evaluator;
409 delete src_vertex_data_;
411 src_vertex_data_ = SRC_VERTEX_BUFFER::Create(
412 settings->
num_vertex_data, src_data_->GetNumVertices(), device_context_);
415 src_vertex_data_ =
NULL;
417 src_vertex_data_desc_ = BufferDescriptor(
424 void updateData(
const float *
src,
int start_vertex,
int num_vertices)
override
426 src_data_->UpdateData(
src, start_vertex, num_vertices, device_context_);
431 src_varying_data_->UpdateData(
src, start_vertex, num_vertices, device_context_);
436 src_vertex_data_->UpdateData(
src, start_vertex, num_vertices, device_context_);
442 int num_vertices)
override
444 assert(face_varying_channel >= 0);
445 assert(face_varying_channel < face_varying_evaluators_.size());
446 face_varying_evaluators_[face_varying_channel]->updateData(
src, start_vertex, num_vertices);
458 return face_varying_evaluators_.size() != 0;
463 return src_vertex_data_ !=
nullptr;
469 BufferDescriptor dst_desc = src_desc_;
470 dst_desc.offset += num_coarse_vertices_ * src_desc_.stride;
471 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
472 evaluator_cache_, src_desc_, dst_desc, device_context_);
473 EVALUATOR::EvalStencils(src_data_,
482 if (src_vertex_data_) {
483 BufferDescriptor dst_vertex_data_desc = src_vertex_data_desc_;
484 dst_vertex_data_desc.offset += num_coarse_vertices_ * src_vertex_data_desc_.stride;
485 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
486 evaluator_cache_, src_vertex_data_desc_, dst_vertex_data_desc, device_context_);
487 EVALUATOR::EvalStencils(src_vertex_data_,
488 src_vertex_data_desc_,
490 dst_vertex_data_desc,
498 BufferDescriptor dst_varying_desc = src_varying_desc_;
499 dst_varying_desc.offset += num_coarse_vertices_ * src_varying_desc_.stride;
500 eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
501 evaluator_cache_, src_varying_desc_, dst_varying_desc, device_context_);
502 EVALUATOR::EvalStencils(src_varying_data_,
512 for (
FaceVaryingEval *face_varying_evaluator : face_varying_evaluators_) {
513 face_varying_evaluator->refine();
519 void evalPatches(
const PatchCoord *patch_coord,
const int num_patch_coords,
float *
P)
override
521 RawDataWrapperBuffer<float> P_data(
P);
523 BufferDescriptor P_desc(0, 3, 3);
524 ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
525 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
526 evaluator_cache_, src_desc_, P_desc, device_context_);
527 EVALUATOR::EvalPatches(src_data_,
531 patch_coord_buffer.GetNumVertices(),
540 const int num_patch_coords,
543 float *dPdv)
override
547 RawDataWrapperBuffer<float> P_data(
P);
548 RawDataWrapperBuffer<float> dPdu_data(dPdu), dPdv_data(dPdv);
550 BufferDescriptor P_desc(0, 3, 3);
551 BufferDescriptor dpDu_desc(0, 3, 3), pPdv_desc(0, 3, 3);
552 ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
553 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
554 evaluator_cache_, src_desc_, P_desc, dpDu_desc, pPdv_desc, device_context_);
555 EVALUATOR::EvalPatches(src_data_,
563 patch_coord_buffer.GetNumVertices(),
572 const int num_patch_coords,
573 float *varying)
override
575 RawDataWrapperBuffer<float> varying_data(varying);
576 BufferDescriptor varying_desc(3, 3, 6);
577 ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
578 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
579 evaluator_cache_, src_varying_desc_, varying_desc, device_context_);
580 EVALUATOR::EvalPatchesVarying(src_varying_data_,
584 patch_coord_buffer.GetNumVertices(),
593 const int num_patch_coords,
594 float *
data)
override
596 RawDataWrapperBuffer<float> vertex_data(
data);
597 BufferDescriptor vertex_desc(0, src_vertex_data_desc_.length, src_vertex_data_desc_.length);
598 ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
599 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
600 evaluator_cache_, src_vertex_data_desc_, vertex_desc, device_context_);
601 EVALUATOR::EvalPatches(src_vertex_data_,
602 src_vertex_data_desc_,
605 patch_coord_buffer.GetNumVertices(),
613 const PatchCoord *patch_coord,
614 const int num_patch_coords,
615 float face_varying[2])
override
617 assert(face_varying_channel >= 0);
618 assert(face_varying_channel < face_varying_evaluators_.size());
619 face_varying_evaluators_[face_varying_channel]->evalPatches(
620 patch_coord, num_patch_coords, face_varying);
630 return src_vertex_data_;
640 return face_varying_evaluators_[face_varying_channel]->getSrcBuffer();
645 return face_varying_evaluators_[face_varying_channel]->getFVarSrcBufferOffset();
650 return face_varying_evaluators_[face_varying_channel]->getPatchTable();
654 SRC_VERTEX_BUFFER *src_data_;
655 SRC_VERTEX_BUFFER *src_varying_data_;
656 SRC_VERTEX_BUFFER *src_vertex_data_;
657 PATCH_TABLE *patch_table_;
658 BufferDescriptor src_desc_;
659 BufferDescriptor src_varying_desc_;
660 BufferDescriptor src_vertex_data_desc_;
662 int num_coarse_vertices_;
664 const STENCIL_TABLE *vertex_stencils_;
665 const STENCIL_TABLE *varying_stencils_;
667 int face_varying_width_;
668 vector<FaceVaryingEval *> face_varying_evaluators_;
671 DEVICE_CONTEXT *device_context_;
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 ~EvalOutput()=default
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
int getFVarSrcBufferOffset() const
~FaceVaryingVolatileEval()
BufferDescriptor src_face_varying_desc_
void updateData(const float *src, int start_vertex, int num_vertices)
DEVICE_CONTEXT * device_context_
EvaluatorCache * evaluator_cache_
OpenSubdiv::Osd::EvaluatorCacheT< EVALUATOR > EvaluatorCache
int face_varying_channel_
PATCH_TABLE * getPatchTable() const
PATCH_TABLE * patch_table_
FaceVaryingVolatileEval(int face_varying_channel, const StencilTable *face_varying_stencils, int face_varying_width, PATCH_TABLE *patch_table, EvaluatorCache *evaluator_cache=NULL, DEVICE_CONTEXT *device_context=NULL)
EVAL_VERTEX_BUFFER * getSrcBuffer() const
const STENCIL_TABLE * face_varying_stencils_
void evalPatches(const PatchCoord *patch_coord, const int num_patch_coords, float *face_varying)
EVAL_VERTEX_BUFFER * src_face_varying_data_
int num_coarse_face_varying_vertices_
OpenSubdiv::Osd::EvaluatorCacheT< EVALUATOR > EvaluatorCache
PATCH_TABLE * getFVarPatchTable(const int face_varying_channel) const
SRC_VERTEX_BUFFER * getSrcVertexDataBuffer() const
void updateVaryingData(const float *src, int start_vertex, int num_vertices) override
SRC_VERTEX_BUFFER * getFVarSrcBuffer(const int face_varying_channel) const
void evalPatches(const PatchCoord *patch_coord, const int num_patch_coords, float *P) override
FaceVaryingVolatileEval< EVAL_VERTEX_BUFFER, STENCIL_TABLE, PATCH_TABLE, EVALUATOR, DEVICE_CONTEXT > FaceVaryingEval
bool hasVaryingData() const
bool hasVertexData() const override
void updateVertexData(const float *src, int start_vertex, int num_vertices) override
VolatileEvalOutput(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, DEVICE_CONTEXT *device_context=NULL)
int getFVarSrcBufferOffset(const int face_varying_channel) const
void evalPatchesVarying(const PatchCoord *patch_coord, const int num_patch_coords, float *varying) override
void evalPatchesVertexData(const PatchCoord *patch_coord, const int num_patch_coords, float *data) override
SRC_VERTEX_BUFFER * getSrcBuffer() const
void updateFaceVaryingData(const int face_varying_channel, const float *src, int start_vertex, int num_vertices) override
void updateSettings(const OpenSubdiv_EvaluatorSettings *settings) override
void evalPatchesWithDerivatives(const PatchCoord *patch_coord, const int num_patch_coords, float *P, float *dPdu, float *dPdv) override
bool hasFaceVaryingData() const
void evalPatchesFaceVarying(const int face_varying_channel, const PatchCoord *patch_coord, const int num_patch_coords, float face_varying[2]) override
~VolatileEvalOutput() override
void updateData(const float *src, int start_vertex, int num_vertices) override
PATCH_TABLE * getPatchTable() const
SyclQueue void void * src
bool is_adaptive(CpuPatchTable *patch_table)