Blender  V3.3
evaluator_impl.cc
Go to the documentation of this file.
1 // Copyright 2018 Blender Foundation. All rights reserved.
2 //
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License
5 // as published by the Free Software Foundation; either version 2
6 // of the License, or (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software Foundation,
15 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 //
17 // Author: Sergey Sharybin
18 
20 
21 #include <cassert>
22 #include <cstdio>
23 
24 #ifdef _MSC_VER
25 # include <iso646.h>
26 #endif
27 
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>
34 
35 #include "MEM_guardedalloc.h"
36 
37 #include "internal/base/type.h"
45 
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;
53 
54 namespace blender {
55 namespace opensubdiv {
56 
57 namespace {
58 
59 // Array implementation which stores small data on stack (or, rather, in the class itself).
60 template<typename T, int kNumMaxElementsOnStack> class StackOrHeapArray {
61  public:
62  StackOrHeapArray()
64  {
65  }
66 
67  explicit StackOrHeapArray(int size) : StackOrHeapArray()
68  {
69  resize(size);
70  }
71 
72  ~StackOrHeapArray()
73  {
74  delete[] heap_elements_;
75  }
76 
77  int size() const
78  {
79  return num_elements_;
80  };
81 
82  T *data()
83  {
84  return effective_elements_;
85  }
86 
87  void resize(int num_elements)
88  {
89  const int old_num_elements = num_elements_;
90  num_elements_ = num_elements;
91  // Early output if allcoation size did not change, or allocation size is smaller.
92  // We never re-allocate, sacrificing some memory over performance.
93  if (old_num_elements >= num_elements) {
94  return;
95  }
96  // Simple case: no previously allocated buffer, can simply do one allocation.
97  if (effective_elements_ == NULL) {
98  effective_elements_ = allocate(num_elements);
99  return;
100  }
101  // Make new allocation, and copy elements if needed.
102  T *old_buffer = effective_elements_;
103  effective_elements_ = allocate(num_elements);
104  if (old_buffer != effective_elements_) {
105  memcpy(effective_elements_, old_buffer, sizeof(T) * min(old_num_elements, num_elements));
106  }
107  if (old_buffer != stack_elements_) {
108  delete[] old_buffer;
109  }
110  }
111 
112  protected:
113  T *allocate(int num_elements)
114  {
115  if (num_elements < kNumMaxElementsOnStack) {
116  return stack_elements_;
117  }
118  heap_elements_ = new T[num_elements];
119  return heap_elements_;
120  }
121 
122  // Number of elements in the buffer.
124 
125  // Elements which are allocated on a stack (or, rather, in the same allocation as the buffer
126  // itself).
127  // Is used as long as buffer is smaller than kNumMaxElementsOnStack.
128  T stack_elements_[kNumMaxElementsOnStack];
129 
130  // Heap storage for buffer larger than kNumMaxElementsOnStack.
133 
134  // Depending on the current buffer size points to rither stack_elements_ or heap_elements_.
136 };
137 
138 // 32 is a number of inner vertices along the patch size at subdivision level 6.
139 typedef StackOrHeapArray<PatchCoord, 32 * 32> StackOrHeapPatchCoordArray;
140 
141 void convertPatchCoordsToArray(const OpenSubdiv_PatchCoord *patch_coords,
142  const int num_patch_coords,
143  const PatchMap *patch_map,
144  StackOrHeapPatchCoordArray *array)
145 {
146  array->resize(num_patch_coords);
147  for (int i = 0; i < num_patch_coords; ++i) {
148  const PatchTable::PatchHandle *handle = patch_map->FindPatch(
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);
151  }
152 }
153 
154 } // namespace
155 
157 // Evaluator wrapper for anonymous API.
158 
160  : patch_map_(patch_map), implementation_(implementation)
161 {
162 }
163 
165 {
166  delete implementation_;
167 }
168 
170 {
171  implementation_->updateSettings(settings);
172 }
173 
175  const int start_vertex_index,
176  const int num_vertices)
177 {
178  // TODO(sergey): Add sanity check on indices.
179  implementation_->updateData(positions, start_vertex_index, num_vertices);
180 }
181 
182 void EvalOutputAPI::setVaryingData(const float *varying_data,
183  const int start_vertex_index,
184  const int num_vertices)
185 {
186  // TODO(sergey): Add sanity check on indices.
187  implementation_->updateVaryingData(varying_data, start_vertex_index, num_vertices);
188 }
189 
190 void EvalOutputAPI::setVertexData(const float *vertex_data,
191  const int start_vertex_index,
192  const int num_vertices)
193 {
194  // TODO(sergey): Add sanity check on indices.
195  implementation_->updateVertexData(vertex_data, start_vertex_index, num_vertices);
196 }
197 
198 void EvalOutputAPI::setFaceVaryingData(const int face_varying_channel,
199  const float *face_varying_data,
200  const int start_vertex_index,
201  const int num_vertices)
202 {
203  // TODO(sergey): Add sanity check on indices.
205  face_varying_channel, face_varying_data, start_vertex_index, num_vertices);
206 }
207 
209  const int start_offset,
210  const int stride,
211  const int start_vertex_index,
212  const int num_vertices)
213 {
214  // TODO(sergey): Add sanity check on indices.
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;
222  }
223 }
224 
226  const int start_offset,
227  const int stride,
228  const int start_vertex_index,
229  const int num_vertices)
230 {
231  // TODO(sergey): Add sanity check on indices.
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);
238  current_buffer += stride;
239  }
240 }
241 
242 void EvalOutputAPI::setFaceVaryingDataFromBuffer(const int face_varying_channel,
243  const void *buffer,
244  const int start_offset,
245  const int stride,
246  const int start_vertex_index,
247  const int num_vertices)
248 {
249  // TODO(sergey): Add sanity check on indices.
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;
254  implementation_->updateFaceVaryingData(face_varying_channel,
255  reinterpret_cast<const float *>(current_buffer),
256  current_vertex_index,
257  1);
258  current_buffer += stride;
259  }
260 }
261 
263 {
265 }
266 
267 void EvalOutputAPI::evaluateLimit(const int ptex_face_index,
268  float face_u,
269  float face_v,
270  float P[3],
271  float dPdu[3],
272  float dPdv[3])
273 {
274  assert(face_u >= 0.0f);
275  assert(face_u <= 1.0f);
276  assert(face_v >= 0.0f);
277  assert(face_v <= 1.0f);
278  const PatchTable::PatchHandle *handle = patch_map_->FindPatch(ptex_face_index, face_u, face_v);
279  PatchCoord patch_coord(*handle, face_u, face_v);
280  if (dPdu != NULL || dPdv != NULL) {
281  implementation_->evalPatchesWithDerivatives(&patch_coord, 1, P, dPdu, dPdv);
282  }
283  else {
284  implementation_->evalPatches(&patch_coord, 1, P);
285  }
286 }
287 
288 void EvalOutputAPI::evaluateVarying(const int ptex_face_index,
289  float face_u,
290  float face_v,
291  float varying[3])
292 {
293  assert(face_u >= 0.0f);
294  assert(face_u <= 1.0f);
295  assert(face_v >= 0.0f);
296  assert(face_v <= 1.0f);
297  const PatchTable::PatchHandle *handle = patch_map_->FindPatch(ptex_face_index, face_u, face_v);
298  PatchCoord patch_coord(*handle, face_u, face_v);
299  implementation_->evalPatchesVarying(&patch_coord, 1, varying);
300 }
301 
302 void EvalOutputAPI::evaluateVertexData(const int ptex_face_index,
303  float face_u,
304  float face_v,
305  float vertex_data[])
306 {
307  assert(face_u >= 0.0f);
308  assert(face_u <= 1.0f);
309  assert(face_v >= 0.0f);
310  assert(face_v <= 1.0f);
311  const PatchTable::PatchHandle *handle = patch_map_->FindPatch(ptex_face_index, face_u, face_v);
312  PatchCoord patch_coord(*handle, face_u, face_v);
313  implementation_->evalPatchesVertexData(&patch_coord, 1, vertex_data);
314 }
315 
316 void EvalOutputAPI::evaluateFaceVarying(const int face_varying_channel,
317  const int ptex_face_index,
318  float face_u,
319  float face_v,
320  float face_varying[2])
321 {
322  assert(face_u >= 0.0f);
323  assert(face_u <= 1.0f);
324  assert(face_v >= 0.0f);
325  assert(face_v <= 1.0f);
326  const PatchTable::PatchHandle *handle = patch_map_->FindPatch(ptex_face_index, face_u, face_v);
327  PatchCoord patch_coord(*handle, face_u, face_v);
328  implementation_->evalPatchesFaceVarying(face_varying_channel, &patch_coord, 1, face_varying);
329 }
330 
332  const int num_patch_coords,
333  float *P,
334  float *dPdu,
335  float *dPdv)
336 {
337  StackOrHeapPatchCoordArray patch_coords_array;
338  convertPatchCoordsToArray(patch_coords, num_patch_coords, patch_map_, &patch_coords_array);
339  if (dPdu != NULL || dPdv != NULL) {
341  patch_coords_array.data(), num_patch_coords, P, dPdu, dPdv);
342  }
343  else {
344  implementation_->evalPatches(patch_coords_array.data(), num_patch_coords, P);
345  }
346 }
347 
349  OpenSubdiv_Buffer *patch_map_quadtree,
350  int *min_patch_face,
351  int *max_patch_face,
352  int *max_depth,
353  int *patches_are_triangular)
354 {
355  *min_patch_face = patch_map_->getMinPatchFace();
356  *max_patch_face = patch_map_->getMaxPatchFace();
357  *max_depth = patch_map_->getMaxDepth();
358  *patches_are_triangular = patch_map_->getPatchesAreTriangular();
359 
360  const std::vector<PatchTable::PatchHandle> &handles = patch_map_->getHandles();
361  PatchTable::PatchHandle *buffer_handles = static_cast<PatchTable::PatchHandle *>(
362  patch_map_handles->alloc(patch_map_handles, handles.size()));
363  memcpy(buffer_handles, &handles[0], sizeof(PatchTable::PatchHandle) * handles.size());
364 
365  const std::vector<PatchMap::QuadNode> &quadtree = patch_map_->nodes();
366  PatchMap::QuadNode *buffer_nodes = static_cast<PatchMap::QuadNode *>(
367  patch_map_quadtree->alloc(patch_map_quadtree, quadtree.size()));
368  memcpy(buffer_nodes, &quadtree[0], sizeof(PatchMap::QuadNode) * quadtree.size());
369 }
370 
372 {
373  implementation_->fillPatchArraysBuffer(patch_arrays_buffer);
374 }
375 
377 {
378  implementation_->wrapPatchIndexBuffer(patch_index_buffer);
379 }
380 
382 {
383  implementation_->wrapPatchParamBuffer(patch_param_buffer);
384 }
385 
387 {
388  implementation_->wrapSrcBuffer(src_buffer);
389 }
390 
392 {
394 }
395 
396 void EvalOutputAPI::fillFVarPatchArraysBuffer(const int face_varying_channel,
397  OpenSubdiv_Buffer *patch_arrays_buffer)
398 {
399  implementation_->fillFVarPatchArraysBuffer(face_varying_channel, patch_arrays_buffer);
400 }
401 
402 void EvalOutputAPI::wrapFVarPatchIndexBuffer(const int face_varying_channel,
403  OpenSubdiv_Buffer *patch_index_buffer)
404 {
405  implementation_->wrapFVarPatchIndexBuffer(face_varying_channel, patch_index_buffer);
406 }
407 
408 void EvalOutputAPI::wrapFVarPatchParamBuffer(const int face_varying_channel,
409  OpenSubdiv_Buffer *patch_param_buffer)
410 {
411  implementation_->wrapFVarPatchParamBuffer(face_varying_channel, patch_param_buffer);
412 }
413 
414 void EvalOutputAPI::wrapFVarSrcBuffer(const int face_varying_channel,
415  OpenSubdiv_Buffer *src_buffer)
416 {
417  implementation_->wrapFVarSrcBuffer(face_varying_channel, src_buffer);
418 }
419 
421 {
422  return implementation_->hasVertexData();
423 }
424 
425 } // namespace opensubdiv
426 } // namespace blender
427 
429  : eval_output(NULL), patch_map(NULL), patch_table(NULL)
430 {
431 }
432 
434 {
435  delete eval_output;
436  delete patch_map;
437  delete patch_table;
438 }
439 
441  OpenSubdiv_TopologyRefiner *topology_refiner,
442  eOpenSubdivEvaluator evaluator_type,
443  OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr)
444 {
446  TopologyRefiner *refiner = topology_refiner->impl->topology_refiner;
447  if (refiner == NULL) {
448  // Happens on bad topology.
449  return NULL;
450  }
451  // TODO(sergey): Base this on actual topology.
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);
455  const int level = topology_refiner->getSubdivisionLevel(topology_refiner);
456  const bool is_adaptive = topology_refiner->getIsAdaptive(topology_refiner);
457  // Common settings for stencils and patches.
458  const bool stencil_generate_intermediate_levels = is_adaptive;
459  const bool stencil_generate_offsets = true;
460  const bool use_inf_sharp_patch = true;
461  // Refine the topology with given settings.
462  // TODO(sergey): What if topology is already refined?
463  if (is_adaptive) {
464  TopologyRefiner::AdaptiveOptions options(level);
465  options.considerFVarChannels = has_face_varying_data;
466  options.useInfSharpPatch = use_inf_sharp_patch;
467  refiner->RefineAdaptive(options);
468  }
469  else {
470  TopologyRefiner::UniformOptions options(level);
471  refiner->RefineUniform(options);
472  }
473  // Generate stencil table to update the bi-cubic patches control vertices
474  // after they have been re-posed (both for vertex & varying interpolation).
475  //
476  // Vertex stencils.
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);
482  // Varying stencils.
483  //
484  // TODO(sergey): Seems currently varying stencils are always required in
485  // OpenSubdiv itself.
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);
493  }
494  // Face warying stencil.
495  vector<const StencilTable *> all_face_varying_stencils;
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));
506  }
507  // Generate bi-cubic patch table for the limit surface.
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);
514  // Append local points stencils.
515  // Point stencils.
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;
522  }
523  // Varying stencils.
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;
532  }
533  }
534  for (int face_varying_channel = 0; face_varying_channel < num_face_varying_channels;
535  ++face_varying_channel) {
536  const StencilTable *table = StencilTableFactory::AppendLocalPointStencilTableFaceVarying(
537  *refiner,
538  all_face_varying_stencils[face_varying_channel],
539  patch_table->GetLocalPointFaceVaryingStencilTable(face_varying_channel),
540  face_varying_channel);
541  if (table != NULL) {
542  delete all_face_varying_stencils[face_varying_channel];
543  all_face_varying_stencils[face_varying_channel] = table;
544  }
545  }
546  // Create OpenSubdiv's CPU side evaluator.
547  blender::opensubdiv::EvalOutputAPI::EvalOutput *eval_output = nullptr;
548 
549  const bool use_gpu_evaluator = evaluator_type == OPENSUBDIV_EVALUATOR_GPU;
550  if (use_gpu_evaluator) {
551  blender::opensubdiv::GpuEvalOutput::EvaluatorCache *evaluator_cache = nullptr;
552  if (evaluator_cache_descr) {
553  evaluator_cache = static_cast<blender::opensubdiv::GpuEvalOutput::EvaluatorCache *>(
554  evaluator_cache_descr->eval_cache);
555  }
556 
557  eval_output = new blender::opensubdiv::GpuEvalOutput(vertex_stencils,
558  varying_stencils,
559  all_face_varying_stencils,
560  2,
561  patch_table,
562  evaluator_cache);
563  }
564  else {
565  eval_output = new blender::opensubdiv::CpuEvalOutput(
566  vertex_stencils, varying_stencils, all_face_varying_stencils, 2, patch_table);
567  }
568 
569  blender::opensubdiv::PatchMap *patch_map = new blender::opensubdiv::PatchMap(*patch_table);
570  // Wrap everything we need into an object which we control from our side.
571  OpenSubdiv_EvaluatorImpl *evaluator_descr;
572  evaluator_descr = new OpenSubdiv_EvaluatorImpl();
573 
574  evaluator_descr->eval_output = new blender::opensubdiv::EvalOutputAPI(eval_output, patch_map);
575  evaluator_descr->patch_map = patch_map;
576  evaluator_descr->patch_table = patch_table;
577  // TODO(sergey): Look into whether we've got duplicated stencils arrays.
578  delete vertex_stencils;
579  delete varying_stencils;
580  for (const StencilTable *table : all_face_varying_stencils) {
581  delete table;
582  }
583  return evaluator_descr;
584 }
585 
587 {
588  delete evaluator;
589 }
_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)
Definition: btDbvt.cpp:52
T * resize(size_t newsize)
virtual void wrapPatchIndexBuffer(OpenSubdiv_Buffer *)
Definition: eval_output.h:98
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:114
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:102
virtual void wrapFVarPatchParamBuffer(const int, OpenSubdiv_Buffer *)
Definition: eval_output.h:124
virtual void wrapFVarPatchIndexBuffer(const int, OpenSubdiv_Buffer *)
Definition: eval_output.h:119
virtual void wrapSrcVertexDataBuffer(OpenSubdiv_Buffer *)
Definition: eval_output.h:110
virtual void updateVertexData(const float *src, int start_vertex, int num_vertices)=0
virtual void fillPatchArraysBuffer(OpenSubdiv_Buffer *)
Definition: eval_output.h:94
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 *)
Definition: eval_output.h:129
virtual void wrapSrcBuffer(OpenSubdiv_Buffer *)
Definition: eval_output.h:106
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)
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)
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.
Definition: patch_map.h:43
const std::vector< QuadNode > & nodes()
Definition: patch_map.h:116
bool getPatchesAreTriangular() const
Definition: patch_map.h:106
const std::vector< Handle > & getHandles()
Definition: patch_map.h:111
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...
Definition: patch_map.h:219
OpenSubdiv::Far::TopologyRefiner * topology_refiner
CCL_NAMESPACE_BEGIN struct Options options
OpenSubdiv_EvaluatorImpl * openSubdiv_createEvaluatorInternal(OpenSubdiv_TopologyRefiner *topology_refiner, eOpenSubdivEvaluator evaluator_type, OpenSubdiv_EvaluatorCacheImpl *evaluator_cache_descr)
T * effective_elements_
void openSubdiv_deleteEvaluatorInternal(OpenSubdiv_EvaluatorImpl *evaluator)
int num_elements_
int num_heap_elements_
T * heap_elements_
T stack_elements_[kNumMaxElementsOnStack]
ccl_global float * buffer
CCL_NAMESPACE_BEGIN struct PatchHandle PatchHandle
static float P(float k)
Definition: math_interp.c:25
#define T
bool is_adaptive(CpuPatchTable *patch_table)
Definition: eval_output.cc:24
MutableSpan< float3 > positions
eOpenSubdivEvaluator
@ OPENSUBDIV_EVALUATOR_GPU
#define min(a, b)
Definition: sort.c:35
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
struct OpenSubdiv_TopologyRefinerImpl * impl
bool(* getIsAdaptive)(const struct OpenSubdiv_TopologyRefiner *topology_refiner)
int(* getSubdivisionLevel)(const struct OpenSubdiv_TopologyRefiner *topology_refiner)
ParamHandle ** handles