Blender V4.3
eval_output.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Foundation
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later
4 *
5 * Author: Sergey Sharybin. */
6
7#ifndef OPENSUBDIV_EVAL_OUTPUT_H_
8#define OPENSUBDIV_EVAL_OUTPUT_H_
9
10#include <opensubdiv/osd/cpuPatchTable.h>
11#include <opensubdiv/osd/glPatchTable.h>
12#include <opensubdiv/osd/mesh.h>
13#include <opensubdiv/osd/types.h>
14
16
18
19using OpenSubdiv::Far::PatchTable;
20using OpenSubdiv::Far::StencilTable;
21using OpenSubdiv::Osd::BufferDescriptor;
22using OpenSubdiv::Osd::CpuPatchTable;
23using OpenSubdiv::Osd::GLPatchTable;
24using OpenSubdiv::Osd::PatchCoord;
25
26namespace blender::opensubdiv {
27
28// Base class for the implementation of the evaluators.
30 public:
31 virtual ~EvalOutput() = default;
32
33 virtual void updateSettings(const OpenSubdiv_EvaluatorSettings *settings) = 0;
34
35 virtual void updateData(const float *src, int start_vertex, int num_vertices) = 0;
36
37 virtual void updateVaryingData(const float *src, int start_vertex, int num_vertices) = 0;
38
39 virtual void updateVertexData(const float *src, int start_vertex, int num_vertices) = 0;
40
41 virtual void updateFaceVaryingData(const int face_varying_channel,
42 const float *src,
43 int start_vertex,
44 int num_vertices) = 0;
45
46 virtual void refine() = 0;
47
48 // NOTE: P must point to a memory of at least float[3]*num_patch_coords.
49 virtual void evalPatches(const PatchCoord *patch_coord,
50 const int num_patch_coords,
51 float *P) = 0;
52
53 // NOTE: P, dPdu, dPdv must point to a memory of at least float[3]*num_patch_coords.
54 virtual void evalPatchesWithDerivatives(const PatchCoord *patch_coord,
55 const int num_patch_coords,
56 float *P,
57 float *dPdu,
58 float *dPdv) = 0;
59
60 // NOTE: varying must point to a memory of at least float[3]*num_patch_coords.
61 virtual void evalPatchesVarying(const PatchCoord *patch_coord,
62 const int num_patch_coords,
63 float *varying) = 0;
64
65 // NOTE: vertex_data must point to a memory of at least float*num_vertex_data.
66 virtual void evalPatchesVertexData(const PatchCoord *patch_coord,
67 const int num_patch_coords,
68 float *vertex_data) = 0;
69
70 virtual void evalPatchesFaceVarying(const int face_varying_channel,
71 const PatchCoord *patch_coord,
72 const int num_patch_coords,
73 float face_varying[2]) = 0;
74
75 // The following interfaces are dependant on the actual evaluator type (CPU, OpenGL, etc.) which
76 // have slightly different APIs to access patch arrays, as well as different types for their
77 // data structure. They need to be overridden in the specific instances of the EvalOutput derived
78 // classes if needed, while the interfaces above are overridden through VolatileEvalOutput.
79
80 virtual void fillPatchArraysBuffer(OpenSubdiv_Buffer * /*patch_arrays_buffer*/) {}
81
82 virtual void wrapPatchIndexBuffer(OpenSubdiv_Buffer * /*patch_index_buffer*/) {}
83
84 virtual void wrapPatchParamBuffer(OpenSubdiv_Buffer * /*patch_param_buffer*/) {}
85
86 virtual void wrapSrcBuffer(OpenSubdiv_Buffer * /*src_buffer*/) {}
87
88 virtual void wrapSrcVertexDataBuffer(OpenSubdiv_Buffer * /*src_buffer*/) {}
89
90 virtual void fillFVarPatchArraysBuffer(const int /*face_varying_channel*/,
91 OpenSubdiv_Buffer * /*patch_arrays_buffer*/)
92 {
93 }
94
95 virtual void wrapFVarPatchIndexBuffer(const int /*face_varying_channel*/,
96 OpenSubdiv_Buffer * /*patch_index_buffer*/)
97 {
98 }
99
100 virtual void wrapFVarPatchParamBuffer(const int /*face_varying_channel*/,
101 OpenSubdiv_Buffer * /*patch_param_buffer*/)
102 {
103 }
104
105 virtual void wrapFVarSrcBuffer(const int /*face_varying_channel*/,
106 OpenSubdiv_Buffer * /*src_buffer*/)
107 {
108 }
109
110 virtual bool hasVertexData() const
111 {
112 return false;
113 }
114};
115
116// Buffer which implements API required by OpenSubdiv and uses an existing memory as an underlying
117// storage.
118template<typename T> class RawDataWrapperBuffer {
119 public:
120 RawDataWrapperBuffer(T *data) : data_(data) {}
121
123 {
124 return data_;
125 }
126
128 {
129 return 0;
130 }
131
132 // TODO(sergey): Support UpdateData().
133
134 protected:
136};
137
138template<typename T> class RawDataWrapperVertexBuffer : public RawDataWrapperBuffer<T> {
139 public:
140 RawDataWrapperVertexBuffer(T *data, int num_vertices)
141 : RawDataWrapperBuffer<T>(data), num_vertices_(num_vertices)
142 {
143 }
144
146 {
147 return num_vertices_;
148 }
149
150 protected:
152};
153
155 public:
156 ConstPatchCoordWrapperBuffer(const PatchCoord *data, int num_vertices)
157 : RawDataWrapperVertexBuffer(data, num_vertices)
158 {
159 }
160};
161
162// Discriminators used in FaceVaryingVolatileEval in order to detect whether we are using adaptive
163// patches as the CPU and OpenGL PatchTable have different APIs.
164bool is_adaptive(const CpuPatchTable *patch_table);
165bool is_adaptive(const GLPatchTable *patch_table);
166
167template<typename EVAL_VERTEX_BUFFER,
168 typename STENCIL_TABLE,
169 typename PATCH_TABLE,
170 typename EVALUATOR,
171 typename DEVICE_CONTEXT = void>
173 public:
174 typedef OpenSubdiv::Osd::EvaluatorCacheT<EVALUATOR> EvaluatorCache;
175
176 FaceVaryingVolatileEval(int face_varying_channel,
177 const StencilTable *face_varying_stencils,
178 int face_varying_width,
179 PATCH_TABLE *patch_table,
180 EvaluatorCache *evaluator_cache = NULL,
181 DEVICE_CONTEXT *device_context = NULL)
182 : face_varying_channel_(face_varying_channel),
183 src_face_varying_desc_(0, face_varying_width, face_varying_width),
184 patch_table_(patch_table),
185 evaluator_cache_(evaluator_cache),
186 device_context_(device_context)
187 {
188 using OpenSubdiv::Osd::convertToCompatibleStencilTable;
189 num_coarse_face_varying_vertices_ = face_varying_stencils->GetNumControlVertices();
190 const int num_total_face_varying_vertices = face_varying_stencils->GetNumControlVertices() +
191 face_varying_stencils->GetNumStencils();
192 src_face_varying_data_ = EVAL_VERTEX_BUFFER::Create(
193 2, num_total_face_varying_vertices, device_context);
194 face_varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(face_varying_stencils,
196 }
197
203
204 void updateData(const float *src, int start_vertex, int num_vertices)
205 {
206 src_face_varying_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
207 }
208
209 void refine()
210 {
211 BufferDescriptor dst_face_varying_desc = src_face_varying_desc_;
212 dst_face_varying_desc.offset += num_coarse_face_varying_vertices_ *
214 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
216 // in and out points to same buffer so output is put directly after coarse vertices, needed in
217 // adaptive mode
218 EVALUATOR::EvalStencils(src_face_varying_data_,
221 dst_face_varying_desc,
223 eval_instance,
225 }
226
227 // NOTE: face_varying must point to a memory of at least float[2]*num_patch_coords.
228 void evalPatches(const PatchCoord *patch_coord, const int num_patch_coords, float *face_varying)
229 {
230 RawDataWrapperBuffer<float> face_varying_data(face_varying);
231 BufferDescriptor face_varying_desc(0, 2, 2);
232 ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
233 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
235
236 BufferDescriptor src_desc = get_src_varying_desc();
237
238 EVALUATOR::EvalPatchesFaceVarying(src_face_varying_data_,
239 src_desc,
240 &face_varying_data,
241 face_varying_desc,
242 patch_coord_buffer.GetNumVertices(),
243 &patch_coord_buffer,
246 eval_instance,
248 }
249
250 EVAL_VERTEX_BUFFER *getSrcBuffer() const
251 {
253 }
254
256 {
257 BufferDescriptor src_desc = get_src_varying_desc();
258 return src_desc.offset;
259 }
260
261 PATCH_TABLE *getPatchTable() const
262 {
263 return patch_table_;
264 }
265
266 private:
267 BufferDescriptor get_src_varying_desc() const
268 {
269 // src_face_varying_data_ always contains coarse vertices at the beginning.
270 // In adaptive mode they are followed by number of blocks for intermediate
271 // subdivision levels, and this is what OSD expects in this mode.
272 // In non-adaptive mode (generateIntermediateLevels == false),
273 // they are followed by max subdivision level, but they break interpolation as OSD
274 // expects only one subd level in this buffer.
275 // So in non-adaptive mode we put offset into buffer descriptor to skip over coarse vertices.
276 BufferDescriptor src_desc = src_face_varying_desc_;
279 }
280 return src_desc;
281 }
282
283 protected:
285
286 BufferDescriptor src_face_varying_desc_;
287
289 EVAL_VERTEX_BUFFER *src_face_varying_data_;
290 const STENCIL_TABLE *face_varying_stencils_;
291
292 // NOTE: We reference this, do not own it.
293 PATCH_TABLE *patch_table_;
294
296 DEVICE_CONTEXT *device_context_;
297};
298
299// Volatile evaluator which can be used from threads.
300//
301// TODO(sergey): Make it possible to evaluate coordinates in chunks.
302// TODO(sergey): Make it possible to evaluate multiple face varying layers.
303// (or maybe, it's cheap to create new evaluator for existing
304// topology to evaluate all needed face varying layers?)
305template<typename SRC_VERTEX_BUFFER,
306 typename EVAL_VERTEX_BUFFER,
307 typename STENCIL_TABLE,
308 typename PATCH_TABLE,
309 typename EVALUATOR,
310 typename DEVICE_CONTEXT = void>
312 public:
313 typedef OpenSubdiv::Osd::EvaluatorCacheT<EVALUATOR> EvaluatorCache;
314 typedef FaceVaryingVolatileEval<EVAL_VERTEX_BUFFER,
315 STENCIL_TABLE,
316 PATCH_TABLE,
317 EVALUATOR,
318 DEVICE_CONTEXT>
320
321 VolatileEvalOutput(const StencilTable *vertex_stencils,
322 const StencilTable *varying_stencils,
323 const std::vector<const StencilTable *> &all_face_varying_stencils,
324 const int face_varying_width,
325 const PatchTable *patch_table,
326 EvaluatorCache *evaluator_cache = NULL,
327 DEVICE_CONTEXT *device_context = NULL)
328 : src_vertex_data_(NULL),
329 src_desc_(0, 3, 3),
330 src_varying_desc_(0, 3, 3),
331 src_vertex_data_desc_(0, 0, 0),
332 face_varying_width_(face_varying_width),
333 evaluator_cache_(evaluator_cache),
334 device_context_(device_context)
335 {
336 // Total number of vertices = coarse points + refined points + local points.
337 int num_total_vertices = vertex_stencils->GetNumControlVertices() +
338 vertex_stencils->GetNumStencils();
339 num_coarse_vertices_ = vertex_stencils->GetNumControlVertices();
340 using OpenSubdiv::Osd::convertToCompatibleStencilTable;
341 src_data_ = SRC_VERTEX_BUFFER::Create(3, num_total_vertices, device_context_);
342 src_varying_data_ = SRC_VERTEX_BUFFER::Create(3, num_total_vertices, device_context_);
343 patch_table_ = PATCH_TABLE::Create(patch_table, device_context_);
344 vertex_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(vertex_stencils,
345 device_context_);
346 varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(varying_stencils,
347 device_context_);
348
349 // Create evaluators for every face varying channel.
350 face_varying_evaluators_.reserve(all_face_varying_stencils.size());
351 int face_varying_channel = 0;
352 for (const StencilTable *face_varying_stencils : all_face_varying_stencils) {
353 face_varying_evaluators_.push_back(new FaceVaryingEval(face_varying_channel,
354 face_varying_stencils,
355 face_varying_width,
356 patch_table_,
357 evaluator_cache_,
358 device_context_));
359 ++face_varying_channel;
360 }
361 }
362
364 {
365 delete src_data_;
366 delete src_varying_data_;
367 delete src_vertex_data_;
368 delete patch_table_;
369 delete vertex_stencils_;
370 delete varying_stencils_;
371 for (FaceVaryingEval *face_varying_evaluator : face_varying_evaluators_) {
372 delete face_varying_evaluator;
373 }
374 }
375
376 void updateSettings(const OpenSubdiv_EvaluatorSettings *settings) override
377 {
378 // Optionally allocate additional data to be subdivided like vertex coordinates.
379 if (settings->num_vertex_data != src_vertex_data_desc_.length) {
380 delete src_vertex_data_;
381 if (settings->num_vertex_data > 0) {
382 src_vertex_data_ = SRC_VERTEX_BUFFER::Create(
383 settings->num_vertex_data, src_data_->GetNumVertices(), device_context_);
384 }
385 else {
386 src_vertex_data_ = NULL;
387 }
388 src_vertex_data_desc_ = BufferDescriptor(
389 0, settings->num_vertex_data, settings->num_vertex_data);
390 }
391 }
392
393 // TODO(sergey): Implement binding API.
394
395 void updateData(const float *src, int start_vertex, int num_vertices) override
396 {
397 src_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
398 }
399
400 void updateVaryingData(const float *src, int start_vertex, int num_vertices) override
401 {
402 src_varying_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
403 }
404
405 void updateVertexData(const float *src, int start_vertex, int num_vertices) override
406 {
407 src_vertex_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
408 }
409
410 void updateFaceVaryingData(const int face_varying_channel,
411 const float *src,
412 int start_vertex,
413 int num_vertices) override
414 {
415 assert(face_varying_channel >= 0);
416 assert(face_varying_channel < face_varying_evaluators_.size());
417 face_varying_evaluators_[face_varying_channel]->updateData(src, start_vertex, num_vertices);
418 }
419
420 bool hasVaryingData() const
421 {
422 // return varying_stencils_ != NULL;
423 // TODO(sergey): Check this based on actual topology.
424 return false;
425 }
426
428 {
429 return face_varying_evaluators_.size() != 0;
430 }
431
432 bool hasVertexData() const override
433 {
434 return src_vertex_data_ != nullptr;
435 }
436
437 void refine() override
438 {
439 // Evaluate vertex positions.
440 BufferDescriptor dst_desc = src_desc_;
441 dst_desc.offset += num_coarse_vertices_ * src_desc_.stride;
442 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
443 evaluator_cache_, src_desc_, dst_desc, device_context_);
444 EVALUATOR::EvalStencils(src_data_,
445 src_desc_,
446 src_data_,
447 dst_desc,
448 vertex_stencils_,
449 eval_instance,
450 device_context_);
451
452 // Evaluate smoothly interpolated vertex data.
453 if (src_vertex_data_) {
454 BufferDescriptor dst_vertex_data_desc = src_vertex_data_desc_;
455 dst_vertex_data_desc.offset += num_coarse_vertices_ * src_vertex_data_desc_.stride;
456 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
457 evaluator_cache_, src_vertex_data_desc_, dst_vertex_data_desc, device_context_);
458 EVALUATOR::EvalStencils(src_vertex_data_,
459 src_vertex_data_desc_,
460 src_vertex_data_,
461 dst_vertex_data_desc,
462 vertex_stencils_,
463 eval_instance,
464 device_context_);
465 }
466
467 // Evaluate varying data.
468 if (hasVaryingData()) {
469 BufferDescriptor dst_varying_desc = src_varying_desc_;
470 dst_varying_desc.offset += num_coarse_vertices_ * src_varying_desc_.stride;
471 eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
472 evaluator_cache_, src_varying_desc_, dst_varying_desc, device_context_);
473 EVALUATOR::EvalStencils(src_varying_data_,
474 src_varying_desc_,
475 src_varying_data_,
476 dst_varying_desc,
477 varying_stencils_,
478 eval_instance,
479 device_context_);
480 }
481 // Evaluate face-varying data.
482 if (hasFaceVaryingData()) {
483 for (FaceVaryingEval *face_varying_evaluator : face_varying_evaluators_) {
484 face_varying_evaluator->refine();
485 }
486 }
487 }
488
489 // NOTE: P must point to a memory of at least float[3]*num_patch_coords.
490 void evalPatches(const PatchCoord *patch_coord, const int num_patch_coords, float *P) override
491 {
493 // TODO(sergey): Support interleaved vertex-varying data.
494 BufferDescriptor P_desc(0, 3, 3);
495 ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
496 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
497 evaluator_cache_, src_desc_, P_desc, device_context_);
498 EVALUATOR::EvalPatches(src_data_,
499 src_desc_,
500 &P_data,
501 P_desc,
502 patch_coord_buffer.GetNumVertices(),
503 &patch_coord_buffer,
504 patch_table_,
505 eval_instance,
506 device_context_);
507 }
508
509 // NOTE: P, dPdu, dPdv must point to a memory of at least float[3]*num_patch_coords.
510 void evalPatchesWithDerivatives(const PatchCoord *patch_coord,
511 const int num_patch_coords,
512 float *P,
513 float *dPdu,
514 float *dPdv) override
515 {
516 assert(dPdu);
517 assert(dPdv);
519 RawDataWrapperBuffer<float> dPdu_data(dPdu), dPdv_data(dPdv);
520 // TODO(sergey): Support interleaved vertex-varying data.
521 BufferDescriptor P_desc(0, 3, 3);
522 BufferDescriptor dpDu_desc(0, 3, 3), pPdv_desc(0, 3, 3);
523 ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
524 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
525 evaluator_cache_, src_desc_, P_desc, dpDu_desc, pPdv_desc, device_context_);
526 EVALUATOR::EvalPatches(src_data_,
527 src_desc_,
528 &P_data,
529 P_desc,
530 &dPdu_data,
531 dpDu_desc,
532 &dPdv_data,
533 pPdv_desc,
534 patch_coord_buffer.GetNumVertices(),
535 &patch_coord_buffer,
536 patch_table_,
537 eval_instance,
538 device_context_);
539 }
540
541 // NOTE: varying must point to a memory of at least float[3]*num_patch_coords.
542 void evalPatchesVarying(const PatchCoord *patch_coord,
543 const int num_patch_coords,
544 float *varying) override
545 {
546 RawDataWrapperBuffer<float> varying_data(varying);
547 BufferDescriptor varying_desc(3, 3, 6);
548 ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
549 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
550 evaluator_cache_, src_varying_desc_, varying_desc, device_context_);
551 EVALUATOR::EvalPatchesVarying(src_varying_data_,
552 src_varying_desc_,
553 &varying_data,
554 varying_desc,
555 patch_coord_buffer.GetNumVertices(),
556 &patch_coord_buffer,
557 patch_table_,
558 eval_instance,
559 device_context_);
560 }
561
562 // NOTE: data must point to a memory of at least float*num_vertex_data.
563 void evalPatchesVertexData(const PatchCoord *patch_coord,
564 const int num_patch_coords,
565 float *data) override
566 {
567 RawDataWrapperBuffer<float> vertex_data(data);
568 BufferDescriptor vertex_desc(0, src_vertex_data_desc_.length, src_vertex_data_desc_.length);
569 ConstPatchCoordWrapperBuffer patch_coord_buffer(patch_coord, num_patch_coords);
570 const EVALUATOR *eval_instance = OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(
571 evaluator_cache_, src_vertex_data_desc_, vertex_desc, device_context_);
572 EVALUATOR::EvalPatches(src_vertex_data_,
573 src_vertex_data_desc_,
574 &vertex_data,
575 vertex_desc,
576 patch_coord_buffer.GetNumVertices(),
577 &patch_coord_buffer,
578 patch_table_,
579 eval_instance,
580 device_context_);
581 }
582
583 void evalPatchesFaceVarying(const int face_varying_channel,
584 const PatchCoord *patch_coord,
585 const int num_patch_coords,
586 float face_varying[2]) override
587 {
588 assert(face_varying_channel >= 0);
589 assert(face_varying_channel < face_varying_evaluators_.size());
590 face_varying_evaluators_[face_varying_channel]->evalPatches(
591 patch_coord, num_patch_coords, face_varying);
592 }
593
594 SRC_VERTEX_BUFFER *getSrcBuffer() const
595 {
596 return src_data_;
597 }
598
599 SRC_VERTEX_BUFFER *getSrcVertexDataBuffer() const
600 {
601 return src_vertex_data_;
602 }
603
604 PATCH_TABLE *getPatchTable() const
605 {
606 return patch_table_;
607 }
608
609 SRC_VERTEX_BUFFER *getFVarSrcBuffer(const int face_varying_channel) const
610 {
611 return face_varying_evaluators_[face_varying_channel]->getSrcBuffer();
612 }
613
614 int getFVarSrcBufferOffset(const int face_varying_channel) const
615 {
616 return face_varying_evaluators_[face_varying_channel]->getFVarSrcBufferOffset();
617 }
618
619 PATCH_TABLE *getFVarPatchTable(const int face_varying_channel) const
620 {
621 return face_varying_evaluators_[face_varying_channel]->getPatchTable();
622 }
623
624 private:
625 SRC_VERTEX_BUFFER *src_data_;
626 SRC_VERTEX_BUFFER *src_varying_data_;
627 SRC_VERTEX_BUFFER *src_vertex_data_;
628 PATCH_TABLE *patch_table_;
629 BufferDescriptor src_desc_;
630 BufferDescriptor src_varying_desc_;
631 BufferDescriptor src_vertex_data_desc_;
632
633 int num_coarse_vertices_;
634
635 const STENCIL_TABLE *vertex_stencils_;
636 const STENCIL_TABLE *varying_stencils_;
637
638 int face_varying_width_;
639 std::vector<FaceVaryingEval *> face_varying_evaluators_;
640
641 EvaluatorCache *evaluator_cache_;
642 DEVICE_CONTEXT *device_context_;
643};
644
645} // namespace blender::opensubdiv
646
647#endif // OPENSUBDIV_EVAL_OUTPUT_H_
ConstPatchCoordWrapperBuffer(const PatchCoord *data, int num_vertices)
virtual void wrapPatchIndexBuffer(OpenSubdiv_Buffer *)
Definition eval_output.h:82
virtual void evalPatches(const PatchCoord *patch_coord, const int num_patch_coords, float *P)=0
virtual void fillFVarPatchArraysBuffer(const int, OpenSubdiv_Buffer *)
Definition eval_output.h:90
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 *)
Definition eval_output.h:84
virtual void wrapFVarPatchParamBuffer(const int, OpenSubdiv_Buffer *)
virtual void wrapFVarPatchIndexBuffer(const int, OpenSubdiv_Buffer *)
Definition eval_output.h:95
virtual void wrapSrcVertexDataBuffer(OpenSubdiv_Buffer *)
Definition eval_output.h:88
virtual void updateVertexData(const float *src, int start_vertex, int num_vertices)=0
virtual void fillPatchArraysBuffer(OpenSubdiv_Buffer *)
Definition eval_output.h:80
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 *)
Definition eval_output.h:86
virtual void updateVaryingData(const float *src, int start_vertex, int num_vertices)=0
EVAL_VERTEX_BUFFER * getSrcBuffer() const
void updateData(const float *src, int start_vertex, int num_vertices)
OpenSubdiv::Osd::EvaluatorCacheT< EVALUATOR > EvaluatorCache
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)
void evalPatches(const PatchCoord *patch_coord, const int num_patch_coords, float *face_varying)
RawDataWrapperVertexBuffer(T *data, int num_vertices)
OpenSubdiv::Osd::EvaluatorCacheT< EVALUATOR > EvaluatorCache
PATCH_TABLE * getFVarPatchTable(const int face_varying_channel) const
void updateVaryingData(const float *src, int start_vertex, int num_vertices) override
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
void updateVertexData(const float *src, int start_vertex, int num_vertices) override
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
void updateFaceVaryingData(const int face_varying_channel, const float *src, int start_vertex, int num_vertices) override
SRC_VERTEX_BUFFER * getSrcBuffer() const
SRC_VERTEX_BUFFER * getSrcVertexDataBuffer() const
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
void evalPatchesFaceVarying(const int face_varying_channel, const PatchCoord *patch_coord, const int num_patch_coords, float face_varying[2]) override
void updateData(const float *src, int start_vertex, int num_vertices) override
VolatileEvalOutput(const StencilTable *vertex_stencils, const StencilTable *varying_stencils, const std::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)
SRC_VERTEX_BUFFER * getFVarSrcBuffer(const int face_varying_channel) const
#define NULL
bool is_adaptive(const CpuPatchTable *patch_table)