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