Blender  V3.3
mesh_subdivision.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #include "scene/attribute.h"
5 #include "scene/camera.h"
6 #include "scene/mesh.h"
7 
8 #include "subd/patch.h"
9 #include "subd/patch_table.h"
10 #include "subd/split.h"
11 
12 #include "util/algorithm.h"
13 #include "util/foreach.h"
14 #include "util/hash.h"
15 
17 
18 #ifdef WITH_OPENSUBDIV
19 
21 
22 # include <opensubdiv/far/patchMap.h>
23 # include <opensubdiv/far/patchTableFactory.h>
24 # include <opensubdiv/far/primvarRefiner.h>
25 # include <opensubdiv/far/topologyRefinerFactory.h>
26 
27 /* specializations of TopologyRefinerFactory for ccl::Mesh */
28 
29 namespace OpenSubdiv {
30 namespace OPENSUBDIV_VERSION {
31 namespace Far {
32 template<>
33 bool TopologyRefinerFactory<ccl::Mesh>::resizeComponentTopology(TopologyRefiner &refiner,
34  ccl::Mesh const &mesh)
35 {
36  setNumBaseVertices(refiner, mesh.get_verts().size());
37  setNumBaseFaces(refiner, mesh.get_num_subd_faces());
38 
39  for (int i = 0; i < mesh.get_num_subd_faces(); i++) {
40  setNumBaseFaceVertices(refiner, i, mesh.get_subd_num_corners()[i]);
41  }
42 
43  return true;
44 }
45 
46 template<>
47 bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTopology(TopologyRefiner &refiner,
48  ccl::Mesh const &mesh)
49 {
50  const ccl::array<int> &subd_face_corners = mesh.get_subd_face_corners();
51  const ccl::array<int> &subd_start_corner = mesh.get_subd_start_corner();
52  const ccl::array<int> &subd_num_corners = mesh.get_subd_num_corners();
53 
54  for (int i = 0; i < mesh.get_num_subd_faces(); i++) {
55  IndexArray face_verts = getBaseFaceVertices(refiner, i);
56 
57  int start_corner = subd_start_corner[i];
58  int *corner = &subd_face_corners[start_corner];
59 
60  for (int j = 0; j < subd_num_corners[i]; j++, corner++) {
61  face_verts[j] = *corner;
62  }
63  }
64 
65  return true;
66 }
67 
68 template<>
69 bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTags(TopologyRefiner &refiner,
70  ccl::Mesh const &mesh)
71 {
72  /* Historical maximum crease weight used at Pixar, influencing the maximum in OpenSubDiv. */
73  static constexpr float CREASE_SCALE = 10.0f;
74 
75  size_t num_creases = mesh.get_subd_creases_weight().size();
76  size_t num_vertex_creases = mesh.get_subd_vert_creases().size();
77 
78  /* The last loop is over the vertices, so early exit to avoid iterating them needlessly. */
79  if (num_creases == 0 && num_vertex_creases == 0) {
80  return true;
81  }
82 
83  for (int i = 0; i < num_creases; i++) {
84  ccl::Mesh::SubdEdgeCrease crease = mesh.get_subd_crease(i);
85  Index edge = findBaseEdge(refiner, crease.v[0], crease.v[1]);
86 
87  if (edge != INDEX_INVALID) {
88  setBaseEdgeSharpness(refiner, edge, crease.crease * CREASE_SCALE);
89  }
90  }
91 
92  std::map<int, float> vertex_creases;
93 
94  for (size_t i = 0; i < num_vertex_creases; ++i) {
95  const int vertex_idx = mesh.get_subd_vert_creases()[i];
96  const float weight = mesh.get_subd_vert_creases_weight()[i];
97 
98  vertex_creases[vertex_idx] = weight * CREASE_SCALE;
99  }
100 
101  for (int i = 0; i < mesh.get_verts().size(); i++) {
102  float sharpness = 0.0f;
103  std::map<int, float>::const_iterator iter = vertex_creases.find(i);
104 
105  if (iter != vertex_creases.end()) {
106  sharpness = iter->second;
107  }
108 
109  ConstIndexArray vert_edges = getBaseVertexEdges(refiner, i);
110 
111  if (vert_edges.size() == 2) {
112  const float sharpness0 = refiner.getLevel(0).getEdgeSharpness(vert_edges[0]);
113  const float sharpness1 = refiner.getLevel(0).getEdgeSharpness(vert_edges[1]);
114 
115  sharpness += ccl::min(sharpness0, sharpness1);
116  sharpness = ccl::min(sharpness, CREASE_SCALE);
117  }
118 
119  if (sharpness != 0.0f) {
120  setBaseVertexSharpness(refiner, i, sharpness);
121  }
122  }
123 
124  return true;
125 }
126 
127 template<>
128 bool TopologyRefinerFactory<ccl::Mesh>::assignFaceVaryingTopology(TopologyRefiner & /*refiner*/,
129  ccl::Mesh const & /*mesh*/)
130 {
131  return true;
132 }
133 
134 template<>
135 void TopologyRefinerFactory<ccl::Mesh>::reportInvalidTopology(TopologyError /*err_code*/,
136  char const * /*msg*/,
137  ccl::Mesh const & /*mesh*/)
138 {
139 }
140 } /* namespace Far */
141 } /* namespace OPENSUBDIV_VERSION */
142 } /* namespace OpenSubdiv */
143 
145 
146 using namespace OpenSubdiv;
147 
148 /* struct that implements OpenSubdiv's vertex interface */
149 
150 template<typename T> struct OsdValue {
151  T value;
152 
153  OsdValue()
154  {
155  }
156 
157  void Clear(void * = 0)
158  {
159  memset(&value, 0, sizeof(T));
160  }
161 
162  void AddWithWeight(OsdValue<T> const &src, float weight)
163  {
164  value += src.value * weight;
165  }
166 };
167 
168 template<> void OsdValue<uchar4>::AddWithWeight(OsdValue<uchar4> const &src, float weight)
169 {
170  for (int i = 0; i < 4; i++) {
171  value[i] += (uchar)(src.value[i] * weight);
172  }
173 }
174 
175 /* class for holding OpenSubdiv data used during tessellation */
176 
177 class OsdData {
178  Mesh *mesh;
179  vector<OsdValue<float3>> verts;
180  Far::TopologyRefiner *refiner;
181  Far::PatchTable *patch_table;
182  Far::PatchMap *patch_map;
183 
184  public:
185  OsdData() : mesh(NULL), refiner(NULL), patch_table(NULL), patch_map(NULL)
186  {
187  }
188 
189  ~OsdData()
190  {
191  delete refiner;
192  delete patch_table;
193  delete patch_map;
194  }
195 
196  void build_from_mesh(Mesh *mesh_)
197  {
198  mesh = mesh_;
199 
200  /* type and options */
201  Sdc::SchemeType type = Sdc::SCHEME_CATMARK;
202 
203  Sdc::Options options;
204  options.SetVtxBoundaryInterpolation(Sdc::Options::VTX_BOUNDARY_EDGE_ONLY);
205 
206  /* create refiner */
207  refiner = Far::TopologyRefinerFactory<Mesh>::Create(
208  *mesh, Far::TopologyRefinerFactory<Mesh>::Options(type, options));
209 
210  /* adaptive refinement */
211  int max_isolation = calculate_max_isolation();
212  refiner->RefineAdaptive(Far::TopologyRefiner::AdaptiveOptions(max_isolation));
213 
214  /* create patch table */
215  Far::PatchTableFactory::Options patch_options;
216  patch_options.endCapType = Far::PatchTableFactory::Options::ENDCAP_GREGORY_BASIS;
217 
218  patch_table = Far::PatchTableFactory::Create(*refiner, patch_options);
219 
220  /* interpolate verts */
221  int num_refiner_verts = refiner->GetNumVerticesTotal();
222  int num_local_points = patch_table->GetNumLocalPoints();
223 
224  verts.resize(num_refiner_verts + num_local_points);
225  for (int i = 0; i < mesh->get_verts().size(); i++) {
226  verts[i].value = mesh->get_verts()[i];
227  }
228 
229  OsdValue<float3> *src = verts.data();
230  for (int i = 0; i < refiner->GetMaxLevel(); i++) {
231  OsdValue<float3> *dest = src + refiner->GetLevel(i).GetNumVertices();
232  Far::PrimvarRefiner(*refiner).Interpolate(i + 1, src, dest);
233  src = dest;
234  }
235 
236  if (num_local_points) {
237  patch_table->ComputeLocalPointValues(&verts[0], &verts[num_refiner_verts]);
238  }
239 
240  /* create patch map */
241  patch_map = new Far::PatchMap(*patch_table);
242  }
243 
244  void subdivide_attribute(Attribute &attr)
245  {
246  Far::PrimvarRefiner primvar_refiner(*refiner);
247 
248  if (attr.element == ATTR_ELEMENT_VERTEX) {
249  int num_refiner_verts = refiner->GetNumVerticesTotal();
250  int num_local_points = patch_table->GetNumLocalPoints();
251 
252  attr.resize(num_refiner_verts + num_local_points);
253  attr.flags |= ATTR_FINAL_SIZE;
254 
255  char *src = attr.buffer.data();
256 
257  for (int i = 0; i < refiner->GetMaxLevel(); i++) {
258  char *dest = src + refiner->GetLevel(i).GetNumVertices() * attr.data_sizeof();
259 
260  if (attr.same_storage(attr.type, TypeDesc::TypeFloat)) {
261  primvar_refiner.Interpolate(i + 1, (OsdValue<float> *)src, (OsdValue<float> *&)dest);
262  }
263  else if (attr.same_storage(attr.type, TypeFloat2)) {
264  primvar_refiner.Interpolate(i + 1, (OsdValue<float2> *)src, (OsdValue<float2> *&)dest);
265  }
266  else {
267  primvar_refiner.Interpolate(i + 1, (OsdValue<float4> *)src, (OsdValue<float4> *&)dest);
268  }
269 
270  src = dest;
271  }
272 
273  if (num_local_points) {
274  if (attr.same_storage(attr.type, TypeDesc::TypeFloat)) {
275  patch_table->ComputeLocalPointValues(
276  (OsdValue<float> *)&attr.buffer[0],
277  (OsdValue<float> *)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
278  }
279  else if (attr.same_storage(attr.type, TypeFloat2)) {
280  patch_table->ComputeLocalPointValues(
281  (OsdValue<float2> *)&attr.buffer[0],
282  (OsdValue<float2> *)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
283  }
284  else {
285  patch_table->ComputeLocalPointValues(
286  (OsdValue<float4> *)&attr.buffer[0],
287  (OsdValue<float4> *)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
288  }
289  }
290  }
291  else if (attr.element == ATTR_ELEMENT_CORNER || attr.element == ATTR_ELEMENT_CORNER_BYTE) {
292  // TODO(mai): fvar interpolation
293  }
294  }
295 
296  int calculate_max_isolation()
297  {
298  /* loop over all edges to find longest in screen space */
299  const Far::TopologyLevel &level = refiner->GetLevel(0);
300  const SubdParams *subd_params = mesh->get_subd_params();
301  Transform objecttoworld = subd_params->objecttoworld;
302  Camera *cam = subd_params->camera;
303 
304  float longest_edge = 0.0f;
305 
306  for (size_t i = 0; i < level.GetNumEdges(); i++) {
307  Far::ConstIndexArray verts = level.GetEdgeVertices(i);
308 
309  float3 a = mesh->get_verts()[verts[0]];
310  float3 b = mesh->get_verts()[verts[1]];
311 
312  float edge_len;
313 
314  if (cam) {
315  a = transform_point(&objecttoworld, a);
316  b = transform_point(&objecttoworld, b);
317 
318  edge_len = len(a - b) / cam->world_to_raster_size((a + b) * 0.5f);
319  }
320  else {
321  edge_len = len(a - b);
322  }
323 
324  longest_edge = max(longest_edge, edge_len);
325  }
326 
327  /* calculate isolation level */
328  int isolation = (int)(log2f(max(longest_edge / subd_params->dicing_rate, 1.0f)) + 1.0f);
329 
330  return min(isolation, 10);
331  }
332 
333  friend struct OsdPatch;
334  friend class Mesh;
335 };
336 
337 /* ccl::Patch implementation that uses OpenSubdiv for eval */
338 
339 struct OsdPatch : Patch {
340  OsdData *osd_data;
341 
342  OsdPatch()
343  {
344  }
345  OsdPatch(OsdData *data) : osd_data(data)
346  {
347  }
348 
349  void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v)
350  {
351  const Far::PatchTable::PatchHandle *handle = osd_data->patch_map->FindPatch(
352  patch_index, (double)u, (double)v);
353  assert(handle);
354 
355  float p_weights[20], du_weights[20], dv_weights[20];
356  osd_data->patch_table->EvaluateBasis(*handle, u, v, p_weights, du_weights, dv_weights);
357 
358  Far::ConstIndexArray cv = osd_data->patch_table->GetPatchVertices(*handle);
359 
360  float3 du, dv;
361  if (P)
362  *P = zero_float3();
363  du = zero_float3();
364  dv = zero_float3();
365 
366  for (int i = 0; i < cv.size(); i++) {
367  float3 p = osd_data->verts[cv[i]].value;
368 
369  if (P)
370  *P += p * p_weights[i];
371  du += p * du_weights[i];
372  dv += p * dv_weights[i];
373  }
374 
375  if (dPdu)
376  *dPdu = du;
377  if (dPdv)
378  *dPdv = dv;
379  if (N) {
380  *N = cross(du, dv);
381 
382  float t = len(*N);
383  *N = (t != 0.0f) ? *N / t : make_float3(0.0f, 0.0f, 1.0f);
384  }
385  }
386 };
387 
388 #endif
389 
391 {
392  /* reset the number of subdivision vertices, in case the Mesh was not cleared
393  * between calls or data updates */
394  num_subd_verts = 0;
395 
396 #ifdef WITH_OPENSUBDIV
397  OsdData osd_data;
398  bool need_packed_patch_table = false;
399 
400  if (subdivision_type == SUBDIVISION_CATMULL_CLARK) {
401  if (get_num_subd_faces()) {
402  osd_data.build_from_mesh(this);
403  }
404  }
405  else
406 #endif
407  {
408  /* force linear subdivision if OpenSubdiv is unavailable to avoid
409  * falling into catmull-clark code paths by accident
410  */
411  subdivision_type = SUBDIVISION_LINEAR;
412 
413  /* force disable attribute subdivision for same reason as above */
414  foreach (Attribute &attr, subd_attributes.attributes) {
415  attr.flags &= ~ATTR_SUBDIVIDED;
416  }
417  }
418 
419  int num_faces = get_num_subd_faces();
420 
421  Attribute *attr_vN = subd_attributes.find(ATTR_STD_VERTEX_NORMAL);
422  float3 *vN = (attr_vN) ? attr_vN->data_float3() : NULL;
423 
424  /* count patches */
425  int num_patches = 0;
426  for (int f = 0; f < num_faces; f++) {
427  SubdFace face = get_subd_face(f);
428 
429  if (face.is_quad()) {
430  num_patches++;
431  }
432  else {
433  num_patches += face.num_corners;
434  }
435  }
436 
437  /* build patches from faces */
438 #ifdef WITH_OPENSUBDIV
439  if (subdivision_type == SUBDIVISION_CATMULL_CLARK) {
440  vector<OsdPatch> osd_patches(num_patches, &osd_data);
441  OsdPatch *patch = osd_patches.data();
442 
443  for (int f = 0; f < num_faces; f++) {
444  SubdFace face = get_subd_face(f);
445 
446  if (face.is_quad()) {
447  patch->patch_index = face.ptex_offset;
448  patch->from_ngon = false;
449  patch->shader = face.shader;
450  patch++;
451  }
452  else {
453  for (int corner = 0; corner < face.num_corners; corner++) {
454  patch->patch_index = face.ptex_offset + corner;
455  patch->from_ngon = true;
456  patch->shader = face.shader;
457  patch++;
458  }
459  }
460  }
461 
462  /* split patches */
463  split->split_patches(osd_patches.data(), sizeof(OsdPatch));
464  }
465  else
466 #endif
467  {
468  vector<LinearQuadPatch> linear_patches(num_patches);
469  LinearQuadPatch *patch = linear_patches.data();
470 
471  for (int f = 0; f < num_faces; f++) {
472  SubdFace face = get_subd_face(f);
473 
474  if (face.is_quad()) {
475  float3 *hull = patch->hull;
476  float3 *normals = patch->normals;
477 
478  patch->patch_index = face.ptex_offset;
479  patch->from_ngon = false;
480 
481  for (int i = 0; i < 4; i++) {
482  hull[i] = verts[subd_face_corners[face.start_corner + i]];
483  }
484 
485  if (face.smooth) {
486  for (int i = 0; i < 4; i++) {
487  normals[i] = vN[subd_face_corners[face.start_corner + i]];
488  }
489  }
490  else {
491  float3 N = face.normal(this);
492  for (int i = 0; i < 4; i++) {
493  normals[i] = N;
494  }
495  }
496 
497  swap(hull[2], hull[3]);
498  swap(normals[2], normals[3]);
499 
500  patch->shader = face.shader;
501  patch++;
502  }
503  else {
504  /* ngon */
505  float3 center_vert = zero_float3();
506  float3 center_normal = zero_float3();
507 
508  float inv_num_corners = 1.0f / float(face.num_corners);
509  for (int corner = 0; corner < face.num_corners; corner++) {
510  center_vert += verts[subd_face_corners[face.start_corner + corner]] * inv_num_corners;
511  center_normal += vN[subd_face_corners[face.start_corner + corner]] * inv_num_corners;
512  }
513 
514  for (int corner = 0; corner < face.num_corners; corner++) {
515  float3 *hull = patch->hull;
516  float3 *normals = patch->normals;
517 
518  patch->patch_index = face.ptex_offset + corner;
519  patch->from_ngon = true;
520 
521  patch->shader = face.shader;
522 
523  hull[0] =
524  verts[subd_face_corners[face.start_corner + mod(corner + 0, face.num_corners)]];
525  hull[1] =
526  verts[subd_face_corners[face.start_corner + mod(corner + 1, face.num_corners)]];
527  hull[2] =
528  verts[subd_face_corners[face.start_corner + mod(corner - 1, face.num_corners)]];
529  hull[3] = center_vert;
530 
531  hull[1] = (hull[1] + hull[0]) * 0.5;
532  hull[2] = (hull[2] + hull[0]) * 0.5;
533 
534  if (face.smooth) {
535  normals[0] =
536  vN[subd_face_corners[face.start_corner + mod(corner + 0, face.num_corners)]];
537  normals[1] =
538  vN[subd_face_corners[face.start_corner + mod(corner + 1, face.num_corners)]];
539  normals[2] =
540  vN[subd_face_corners[face.start_corner + mod(corner - 1, face.num_corners)]];
541  normals[3] = center_normal;
542 
543  normals[1] = (normals[1] + normals[0]) * 0.5;
544  normals[2] = (normals[2] + normals[0]) * 0.5;
545  }
546  else {
547  float3 N = face.normal(this);
548  for (int i = 0; i < 4; i++) {
549  normals[i] = N;
550  }
551  }
552 
553  patch++;
554  }
555  }
556  }
557 
558  /* split patches */
559  split->split_patches(linear_patches.data(), sizeof(LinearQuadPatch));
560  }
561 
562  /* interpolate center points for attributes */
563  foreach (Attribute &attr, subd_attributes.attributes) {
564 #ifdef WITH_OPENSUBDIV
565  if (subdivision_type == SUBDIVISION_CATMULL_CLARK && attr.flags & ATTR_SUBDIVIDED) {
567  /* keep subdivision for corner attributes disabled for now */
568  attr.flags &= ~ATTR_SUBDIVIDED;
569  }
570  else if (get_num_subd_faces()) {
571  osd_data.subdivide_attribute(attr);
572 
573  need_packed_patch_table = true;
574  continue;
575  }
576  }
577 #endif
578 
579  char *data = attr.data();
580  size_t stride = attr.data_sizeof();
581  int ngons = 0;
582 
583  switch (attr.element) {
584  case ATTR_ELEMENT_VERTEX: {
585  for (int f = 0; f < num_faces; f++) {
586  SubdFace face = get_subd_face(f);
587 
588  if (!face.is_quad()) {
589  char *center = data + (verts.size() - num_subd_verts + ngons) * stride;
590  attr.zero_data(center);
591 
592  float inv_num_corners = 1.0f / float(face.num_corners);
593 
594  for (int corner = 0; corner < face.num_corners; corner++) {
595  attr.add_with_weight(center,
596  data + subd_face_corners[face.start_corner + corner] * stride,
597  inv_num_corners);
598  }
599 
600  ngons++;
601  }
602  }
603  } break;
605  // TODO(mai): implement
606  } break;
607  case ATTR_ELEMENT_CORNER: {
608  for (int f = 0; f < num_faces; f++) {
609  SubdFace face = get_subd_face(f);
610 
611  if (!face.is_quad()) {
612  char *center = data + (subd_face_corners.size() + ngons) * stride;
613  attr.zero_data(center);
614 
615  float inv_num_corners = 1.0f / float(face.num_corners);
616 
617  for (int corner = 0; corner < face.num_corners; corner++) {
618  attr.add_with_weight(
619  center, data + (face.start_corner + corner) * stride, inv_num_corners);
620  }
621 
622  ngons++;
623  }
624  }
625  } break;
627  for (int f = 0; f < num_faces; f++) {
628  SubdFace face = get_subd_face(f);
629 
630  if (!face.is_quad()) {
631  uchar *center = (uchar *)data + (subd_face_corners.size() + ngons) * stride;
632 
633  float inv_num_corners = 1.0f / float(face.num_corners);
634  float4 val = zero_float4();
635 
636  for (int corner = 0; corner < face.num_corners; corner++) {
637  for (int i = 0; i < 4; i++) {
638  val[i] += float(*(data + (face.start_corner + corner) * stride + i)) *
639  inv_num_corners;
640  }
641  }
642 
643  for (int i = 0; i < 4; i++) {
644  center[i] = uchar(min(max(val[i], 0.0f), 255.0f));
645  }
646 
647  ngons++;
648  }
649  }
650  } break;
651  default:
652  break;
653  }
654  }
655 
656 #ifdef WITH_OPENSUBDIV
657  /* pack patch tables */
658  if (need_packed_patch_table) {
659  delete patch_table;
660  patch_table = new PackedPatchTable;
661  patch_table->pack(osd_data.patch_table);
662  }
663 #endif
664 }
665 
typedef float(TangentPoint)[2]
unsigned char uchar
Definition: BLI_sys_types.h:70
void swap(T &a, T &b)
Definition: Common.h:19
struct Mesh Mesh
NSNotificationCenter * center
_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 type
_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
_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 const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
float float4[4]
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
AttributeElement element
static bool same_storage(TypeDesc a, TypeDesc b)
void add_with_weight(void *dst, void *src, float weight)
TypeDesc type
void resize(Geometry *geom, AttributePrimitive prim, bool reserve_only)
char * data()
vector< char > buffer
void zero_data(void *dst)
size_t data_sizeof() const
float3 * data_float3()
float3 hull[4]
Definition: subd/patch.h:31
float3 normals[4]
Definition: subd/patch.h:32
int shader
Definition: subd/patch.h:23
bool from_ngon
Definition: subd/patch.h:24
int patch_index
Definition: subd/patch.h:22
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
CCL_NAMESPACE_BEGIN struct Options options
SyclQueue void void * src
SyclQueue void * dest
int len
Definition: draw_manager.c:108
static float verts[][3]
CCL_NAMESPACE_END CCL_NAMESPACE_BEGIN ccl_device_inline float3 transform_point(ccl_private const Transform *t, const float3 a)
CCL_NAMESPACE_BEGIN struct PatchHandle PatchHandle
@ ATTR_STD_VERTEX_NORMAL
Definition: kernel/types.h:614
@ ATTR_FINAL_SIZE
Definition: kernel/types.h:651
@ ATTR_SUBDIVIDED
Definition: kernel/types.h:652
@ ATTR_ELEMENT_CORNER_BYTE
Definition: kernel/types.h:605
@ ATTR_ELEMENT_CORNER
Definition: kernel/types.h:604
@ ATTR_ELEMENT_VERTEX_MOTION
Definition: kernel/types.h:603
@ ATTR_ELEMENT_VERTEX
Definition: kernel/types.h:602
ccl_device_inline float3 zero_float3()
Definition: math_float3.h:80
ccl_device_inline float4 zero_float4()
Definition: math_float4.h:92
static float P(float k)
Definition: math_interp.c:25
#define N
#define T
#define INDEX_INVALID
#define make_float3(x, y, z)
Definition: metal/compat.h:204
static unsigned a[3]
Definition: RandGen.cpp:78
void split(const std::string &s, const char delim, std::vector< std::string > &tokens)
Definition: abc_util.cc:92
vec_base< T, 3 > cross(const vec_base< T, 3 > &a, const vec_base< T, 3 > &b)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
MutableSpan< float3 > normals
CCL_NAMESPACE_BEGIN static constexpr OIIO_NAMESPACE_USING TypeDesc TypeFloat2(TypeDesc::FLOAT, TypeDesc::VEC2)
#define min(a, b)
Definition: sort.c:35
float world_to_raster_size(float3 P)
bool is_quad()
Definition: scene/mesh.h:92
float3 normal(const Mesh *mesh) const
Definition: scene/mesh.cpp:102
void tessellate(DiagSplit *split)
SubdParams * get_subd_params()
Definition: scene/mesh.cpp:152
size_t get_num_subd_faces() const
Definition: scene/mesh.h:232
float size[3]
SubdEdgeCrease get_subd_crease(size_t i) const
Definition: scene/mesh.h:108
void pack(Far::PatchTable *patch_table, int offset=0)
Camera * camera
Definition: dice.h:31
Transform objecttoworld
Definition: dice.h:32
float dicing_rate
Definition: dice.h:29
float max
ccl_device_inline int mod(int x, int m)
Definition: util/math.h:490