Blender  V3.3
embree.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2018-2022 Blender Foundation. */
3 
4 /* This class implements a ray accelerator for Cycles using Intel's Embree library.
5  * It supports triangles, curves, object and deformation blur and instancing.
6  *
7  * Since Embree allows object to be either curves or triangles but not both, Cycles object IDs are
8  * mapped to Embree IDs by multiplying by two and adding one for curves.
9  *
10  * This implementation shares RTCDevices between Cycles instances. Eventually each instance should
11  * get a separate RTCDevice to correctly keep track of memory usage.
12  *
13  * Vertex and index buffers are duplicated between Cycles device arrays and Embree. These could be
14  * merged, which would require changes to intersection refinement, shader setup, mesh light
15  * sampling and a few other places in Cycles where direct access to vertex data is required.
16  */
17 
18 #ifdef WITH_EMBREE
19 
20 # include <embree3/rtcore_geometry.h>
21 
22 # include "bvh/embree.h"
23 
24 # include "kernel/device/cpu/bvh.h"
27 
28 # include "scene/hair.h"
29 # include "scene/mesh.h"
30 # include "scene/object.h"
31 # include "scene/pointcloud.h"
32 
33 # include "util/foreach.h"
34 # include "util/log.h"
35 # include "util/progress.h"
36 # include "util/stats.h"
37 
39 
40 static_assert(Object::MAX_MOTION_STEPS <= RTC_MAX_TIME_STEP_COUNT,
41  "Object and Embree max motion steps inconsistent");
43  "Object and Geometry max motion steps inconsistent");
44 
45 static size_t unaccounted_mem = 0;
46 
47 static bool rtc_memory_monitor_func(void *userPtr, const ssize_t bytes, const bool)
48 {
49  Stats *stats = (Stats *)userPtr;
50  if (stats) {
51  if (bytes > 0) {
52  stats->mem_alloc(bytes);
53  }
54  else {
55  stats->mem_free(-bytes);
56  }
57  }
58  else {
59  /* A stats pointer may not yet be available. Keep track of the memory usage for later. */
60  if (bytes >= 0) {
61  atomic_add_and_fetch_z(&unaccounted_mem, bytes);
62  }
63  else {
64  atomic_sub_and_fetch_z(&unaccounted_mem, -bytes);
65  }
66  }
67  return true;
68 }
69 
70 static void rtc_error_func(void *, enum RTCError, const char *str)
71 {
72  VLOG_WARNING << str;
73 }
74 
75 static double progress_start_time = 0.0;
76 
77 static bool rtc_progress_func(void *user_ptr, const double n)
78 {
79  Progress *progress = (Progress *)user_ptr;
80 
81  if (time_dt() - progress_start_time < 0.25) {
82  return true;
83  }
84 
85  string msg = string_printf("Building BVH %.0f%%", n * 100.0);
86  progress->set_substatus(msg);
87  progress_start_time = time_dt();
88 
89  return !progress->get_cancel();
90 }
91 
92 BVHEmbree::BVHEmbree(const BVHParams &params_,
93  const vector<Geometry *> &geometry_,
94  const vector<Object *> &objects_)
95  : BVH(params_, geometry_, objects_),
96  scene(NULL),
97  rtc_device(NULL),
98  build_quality(RTC_BUILD_QUALITY_REFIT)
99 {
101 }
102 
103 BVHEmbree::~BVHEmbree()
104 {
105  if (scene) {
106  rtcReleaseScene(scene);
107  }
108 }
109 
110 void BVHEmbree::build(Progress &progress, Stats *stats, RTCDevice rtc_device_)
111 {
112  rtc_device = rtc_device_;
113  assert(rtc_device);
114 
115  rtcSetDeviceErrorFunction(rtc_device, rtc_error_func, NULL);
116  rtcSetDeviceMemoryMonitorFunction(rtc_device, rtc_memory_monitor_func, stats);
117 
118  progress.set_substatus("Building BVH");
119 
120  if (scene) {
121  rtcReleaseScene(scene);
122  scene = NULL;
123  }
124 
125  const bool dynamic = params.bvh_type == BVH_TYPE_DYNAMIC;
126  const bool compact = params.use_compact_structure;
127 
128  scene = rtcNewScene(rtc_device);
129  const RTCSceneFlags scene_flags = (dynamic ? RTC_SCENE_FLAG_DYNAMIC : RTC_SCENE_FLAG_NONE) |
130  (compact ? RTC_SCENE_FLAG_COMPACT : RTC_SCENE_FLAG_NONE) |
131  RTC_SCENE_FLAG_ROBUST;
132  rtcSetSceneFlags(scene, scene_flags);
133  build_quality = dynamic ? RTC_BUILD_QUALITY_LOW :
134  (params.use_spatial_split ? RTC_BUILD_QUALITY_HIGH :
135  RTC_BUILD_QUALITY_MEDIUM);
136  rtcSetSceneBuildQuality(scene, build_quality);
137 
138  int i = 0;
139  foreach (Object *ob, objects) {
140  if (params.top_level) {
141  if (!ob->is_traceable()) {
142  ++i;
143  continue;
144  }
145  if (!ob->get_geometry()->is_instanced()) {
146  add_object(ob, i);
147  }
148  else {
149  add_instance(ob, i);
150  }
151  }
152  else {
153  add_object(ob, i);
154  }
155  ++i;
156  if (progress.get_cancel())
157  return;
158  }
159 
160  if (progress.get_cancel()) {
161  return;
162  }
163 
164  rtcSetSceneProgressMonitorFunction(scene, rtc_progress_func, &progress);
165  rtcCommitScene(scene);
166 }
167 
168 void BVHEmbree::add_object(Object *ob, int i)
169 {
170  Geometry *geom = ob->get_geometry();
171 
172  if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
173  Mesh *mesh = static_cast<Mesh *>(geom);
174  if (mesh->num_triangles() > 0) {
175  add_triangles(ob, mesh, i);
176  }
177  }
178  else if (geom->geometry_type == Geometry::HAIR) {
179  Hair *hair = static_cast<Hair *>(geom);
180  if (hair->num_curves() > 0) {
181  add_curves(ob, hair, i);
182  }
183  }
184  else if (geom->geometry_type == Geometry::POINTCLOUD) {
185  PointCloud *pointcloud = static_cast<PointCloud *>(geom);
186  if (pointcloud->num_points() > 0) {
187  add_points(ob, pointcloud, i);
188  }
189  }
190 }
191 
192 void BVHEmbree::add_instance(Object *ob, int i)
193 {
194  BVHEmbree *instance_bvh = (BVHEmbree *)(ob->get_geometry()->bvh);
195  assert(instance_bvh != NULL);
196 
197  const size_t num_object_motion_steps = ob->use_motion() ? ob->get_motion().size() : 1;
198  const size_t num_motion_steps = min(num_object_motion_steps, (size_t)RTC_MAX_TIME_STEP_COUNT);
199  assert(num_object_motion_steps <= RTC_MAX_TIME_STEP_COUNT);
200 
201  RTCGeometry geom_id = rtcNewGeometry(rtc_device, RTC_GEOMETRY_TYPE_INSTANCE);
202  rtcSetGeometryInstancedScene(geom_id, instance_bvh->scene);
203  rtcSetGeometryTimeStepCount(geom_id, num_motion_steps);
204 
205  if (ob->use_motion()) {
206  array<DecomposedTransform> decomp(ob->get_motion().size());
207  transform_motion_decompose(decomp.data(), ob->get_motion().data(), ob->get_motion().size());
208  for (size_t step = 0; step < num_motion_steps; ++step) {
209  RTCQuaternionDecomposition rtc_decomp;
210  rtcInitQuaternionDecomposition(&rtc_decomp);
211  rtcQuaternionDecompositionSetQuaternion(
212  &rtc_decomp, decomp[step].x.w, decomp[step].x.x, decomp[step].x.y, decomp[step].x.z);
213  rtcQuaternionDecompositionSetScale(
214  &rtc_decomp, decomp[step].y.w, decomp[step].z.w, decomp[step].w.w);
215  rtcQuaternionDecompositionSetTranslation(
216  &rtc_decomp, decomp[step].y.x, decomp[step].y.y, decomp[step].y.z);
217  rtcQuaternionDecompositionSetSkew(
218  &rtc_decomp, decomp[step].z.x, decomp[step].z.y, decomp[step].w.x);
219  rtcSetGeometryTransformQuaternion(geom_id, step, &rtc_decomp);
220  }
221  }
222  else {
223  rtcSetGeometryTransform(
224  geom_id, 0, RTC_FORMAT_FLOAT3X4_ROW_MAJOR, (const float *)&ob->get_tfm());
225  }
226 
227  rtcSetGeometryUserData(geom_id, (void *)instance_bvh->scene);
228  rtcSetGeometryMask(geom_id, ob->visibility_for_tracing());
229 
230  rtcCommitGeometry(geom_id);
231  rtcAttachGeometryByID(scene, geom_id, i * 2);
232  rtcReleaseGeometry(geom_id);
233 }
234 
235 void BVHEmbree::add_triangles(const Object *ob, const Mesh *mesh, int i)
236 {
237  size_t prim_offset = mesh->prim_offset;
238 
239  const Attribute *attr_mP = NULL;
240  size_t num_motion_steps = 1;
241  if (mesh->has_motion_blur()) {
243  if (attr_mP) {
244  num_motion_steps = mesh->get_motion_steps();
245  }
246  }
247 
248  assert(num_motion_steps <= RTC_MAX_TIME_STEP_COUNT);
249  num_motion_steps = min(num_motion_steps, (size_t)RTC_MAX_TIME_STEP_COUNT);
250 
251  const size_t num_triangles = mesh->num_triangles();
252 
253  RTCGeometry geom_id = rtcNewGeometry(rtc_device, RTC_GEOMETRY_TYPE_TRIANGLE);
254  rtcSetGeometryBuildQuality(geom_id, build_quality);
255  rtcSetGeometryTimeStepCount(geom_id, num_motion_steps);
256 
257  unsigned *rtc_indices = (unsigned *)rtcSetNewGeometryBuffer(
258  geom_id, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, sizeof(int) * 3, num_triangles);
259  assert(rtc_indices);
260  if (!rtc_indices) {
261  VLOG_WARNING << "Embree could not create new geometry buffer for mesh " << mesh->name.c_str()
262  << ".\n";
263  return;
264  }
265  for (size_t j = 0; j < num_triangles; ++j) {
267  rtc_indices[j * 3] = t.v[0];
268  rtc_indices[j * 3 + 1] = t.v[1];
269  rtc_indices[j * 3 + 2] = t.v[2];
270  }
271 
272  set_tri_vertex_buffer(geom_id, mesh, false);
273 
274  rtcSetGeometryUserData(geom_id, (void *)prim_offset);
275  rtcSetGeometryOccludedFilterFunction(geom_id, kernel_embree_filter_occluded_func);
276  rtcSetGeometryIntersectFilterFunction(geom_id, kernel_embree_filter_intersection_func);
277  rtcSetGeometryMask(geom_id, ob->visibility_for_tracing());
278 
279  rtcCommitGeometry(geom_id);
280  rtcAttachGeometryByID(scene, geom_id, i * 2);
281  rtcReleaseGeometry(geom_id);
282 }
283 
284 void BVHEmbree::set_tri_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh, const bool update)
285 {
286  const Attribute *attr_mP = NULL;
287  size_t num_motion_steps = 1;
288  int t_mid = 0;
289  if (mesh->has_motion_blur()) {
291  if (attr_mP) {
292  num_motion_steps = mesh->get_motion_steps();
293  t_mid = (num_motion_steps - 1) / 2;
294  if (num_motion_steps > RTC_MAX_TIME_STEP_COUNT) {
295  assert(0);
296  num_motion_steps = RTC_MAX_TIME_STEP_COUNT;
297  }
298  }
299  }
300  const size_t num_verts = mesh->get_verts().size();
301 
302  for (int t = 0; t < num_motion_steps; ++t) {
303  const float3 *verts;
304  if (t == t_mid) {
305  verts = mesh->get_verts().data();
306  }
307  else {
308  int t_ = (t > t_mid) ? (t - 1) : t;
309  verts = &attr_mP->data_float3()[t_ * num_verts];
310  }
311 
312  float *rtc_verts = (update) ?
313  (float *)rtcGetGeometryBufferData(geom_id, RTC_BUFFER_TYPE_VERTEX, t) :
314  (float *)rtcSetNewGeometryBuffer(geom_id,
315  RTC_BUFFER_TYPE_VERTEX,
316  t,
317  RTC_FORMAT_FLOAT3,
318  sizeof(float) * 3,
319  num_verts + 1);
320 
321  assert(rtc_verts);
322  if (rtc_verts) {
323  for (size_t j = 0; j < num_verts; ++j) {
324  rtc_verts[0] = verts[j].x;
325  rtc_verts[1] = verts[j].y;
326  rtc_verts[2] = verts[j].z;
327  rtc_verts += 3;
328  }
329  }
330 
331  if (update) {
332  rtcUpdateGeometryBuffer(geom_id, RTC_BUFFER_TYPE_VERTEX, t);
333  }
334  }
335 }
336 
337 void BVHEmbree::set_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair, const bool update)
338 {
339  const Attribute *attr_mP = NULL;
340  size_t num_motion_steps = 1;
341  if (hair->has_motion_blur()) {
343  if (attr_mP) {
344  num_motion_steps = hair->get_motion_steps();
345  }
346  }
347 
348  const size_t num_curves = hair->num_curves();
349  size_t num_keys = 0;
350  for (size_t j = 0; j < num_curves; ++j) {
351  const Hair::Curve c = hair->get_curve(j);
352  num_keys += c.num_keys;
353  }
354 
355  /* Catmull-Rom splines need extra CVs at the beginning and end of each curve. */
356  size_t num_keys_embree = num_keys;
357  num_keys_embree += num_curves * 2;
358 
359  /* Copy the CV data to Embree */
360  const int t_mid = (num_motion_steps - 1) / 2;
361  const float *curve_radius = &hair->get_curve_radius()[0];
362  for (int t = 0; t < num_motion_steps; ++t) {
363  const float3 *verts;
364  if (t == t_mid || attr_mP == NULL) {
365  verts = &hair->get_curve_keys()[0];
366  }
367  else {
368  int t_ = (t > t_mid) ? (t - 1) : t;
369  verts = &attr_mP->data_float3()[t_ * num_keys];
370  }
371 
372  float4 *rtc_verts = (update) ? (float4 *)rtcGetGeometryBufferData(
373  geom_id, RTC_BUFFER_TYPE_VERTEX, t) :
374  (float4 *)rtcSetNewGeometryBuffer(geom_id,
375  RTC_BUFFER_TYPE_VERTEX,
376  t,
377  RTC_FORMAT_FLOAT4,
378  sizeof(float) * 4,
379  num_keys_embree);
380 
381  assert(rtc_verts);
382  if (rtc_verts) {
383  const size_t num_curves = hair->num_curves();
384  for (size_t j = 0; j < num_curves; ++j) {
385  Hair::Curve c = hair->get_curve(j);
386  int fk = c.first_key;
387  int k = 1;
388  for (; k < c.num_keys + 1; ++k, ++fk) {
389  rtc_verts[k] = float3_to_float4(verts[fk]);
390  rtc_verts[k].w = curve_radius[fk];
391  }
392  /* Duplicate Embree's Catmull-Rom spline CVs at the start and end of each curve. */
393  rtc_verts[0] = rtc_verts[1];
394  rtc_verts[k] = rtc_verts[k - 1];
395  rtc_verts += c.num_keys + 2;
396  }
397  }
398 
399  if (update) {
400  rtcUpdateGeometryBuffer(geom_id, RTC_BUFFER_TYPE_VERTEX, t);
401  }
402  }
403 }
404 
405 void BVHEmbree::set_point_vertex_buffer(RTCGeometry geom_id,
406  const PointCloud *pointcloud,
407  const bool update)
408 {
409  const Attribute *attr_mP = NULL;
410  size_t num_motion_steps = 1;
411  if (pointcloud->has_motion_blur()) {
412  attr_mP = pointcloud->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
413  if (attr_mP) {
414  num_motion_steps = pointcloud->get_motion_steps();
415  }
416  }
417 
418  const size_t num_points = pointcloud->num_points();
419 
420  /* Copy the point data to Embree */
421  const int t_mid = (num_motion_steps - 1) / 2;
422  const float *radius = pointcloud->get_radius().data();
423  for (int t = 0; t < num_motion_steps; ++t) {
424  const float3 *verts;
425  if (t == t_mid || attr_mP == NULL) {
426  verts = pointcloud->get_points().data();
427  }
428  else {
429  int t_ = (t > t_mid) ? (t - 1) : t;
430  verts = &attr_mP->data_float3()[t_ * num_points];
431  }
432 
433  float4 *rtc_verts = (update) ? (float4 *)rtcGetGeometryBufferData(
434  geom_id, RTC_BUFFER_TYPE_VERTEX, t) :
435  (float4 *)rtcSetNewGeometryBuffer(geom_id,
436  RTC_BUFFER_TYPE_VERTEX,
437  t,
438  RTC_FORMAT_FLOAT4,
439  sizeof(float) * 4,
440  num_points);
441 
442  assert(rtc_verts);
443  if (rtc_verts) {
444  for (size_t j = 0; j < num_points; ++j) {
445  rtc_verts[j] = float3_to_float4(verts[j]);
446  rtc_verts[j].w = radius[j];
447  }
448  }
449 
450  if (update) {
451  rtcUpdateGeometryBuffer(geom_id, RTC_BUFFER_TYPE_VERTEX, t);
452  }
453  }
454 }
455 
456 void BVHEmbree::add_points(const Object *ob, const PointCloud *pointcloud, int i)
457 {
458  size_t prim_offset = pointcloud->prim_offset;
459 
460  const Attribute *attr_mP = NULL;
461  size_t num_motion_steps = 1;
462  if (pointcloud->has_motion_blur()) {
463  attr_mP = pointcloud->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
464  if (attr_mP) {
465  num_motion_steps = pointcloud->get_motion_steps();
466  }
467  }
468 
469  enum RTCGeometryType type = RTC_GEOMETRY_TYPE_SPHERE_POINT;
470 
471  RTCGeometry geom_id = rtcNewGeometry(rtc_device, type);
472 
473  rtcSetGeometryBuildQuality(geom_id, build_quality);
474  rtcSetGeometryTimeStepCount(geom_id, num_motion_steps);
475 
476  set_point_vertex_buffer(geom_id, pointcloud, false);
477 
478  rtcSetGeometryUserData(geom_id, (void *)prim_offset);
479  rtcSetGeometryIntersectFilterFunction(geom_id, kernel_embree_filter_func_backface_cull);
480  rtcSetGeometryOccludedFilterFunction(geom_id, kernel_embree_filter_occluded_func_backface_cull);
481  rtcSetGeometryMask(geom_id, ob->visibility_for_tracing());
482 
483  rtcCommitGeometry(geom_id);
484  rtcAttachGeometryByID(scene, geom_id, i * 2);
485  rtcReleaseGeometry(geom_id);
486 }
487 
488 void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i)
489 {
490  size_t prim_offset = hair->curve_segment_offset;
491 
492  const Attribute *attr_mP = NULL;
493  size_t num_motion_steps = 1;
494  if (hair->has_motion_blur()) {
496  if (attr_mP) {
497  num_motion_steps = hair->get_motion_steps();
498  }
499  }
500 
501  assert(num_motion_steps <= RTC_MAX_TIME_STEP_COUNT);
502  num_motion_steps = min(num_motion_steps, (size_t)RTC_MAX_TIME_STEP_COUNT);
503 
504  const size_t num_curves = hair->num_curves();
505  size_t num_segments = 0;
506  for (size_t j = 0; j < num_curves; ++j) {
507  Hair::Curve c = hair->get_curve(j);
508  assert(c.num_segments() > 0);
509  num_segments += c.num_segments();
510  }
511 
512  enum RTCGeometryType type = (hair->curve_shape == CURVE_RIBBON ?
513  RTC_GEOMETRY_TYPE_FLAT_CATMULL_ROM_CURVE :
514  RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_CURVE);
515 
516  RTCGeometry geom_id = rtcNewGeometry(rtc_device, type);
517  rtcSetGeometryTessellationRate(geom_id, params.curve_subdivisions + 1);
518  unsigned *rtc_indices = (unsigned *)rtcSetNewGeometryBuffer(
519  geom_id, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT, sizeof(int), num_segments);
520  size_t rtc_index = 0;
521  for (size_t j = 0; j < num_curves; ++j) {
522  Hair::Curve c = hair->get_curve(j);
523  for (size_t k = 0; k < c.num_segments(); ++k) {
524  rtc_indices[rtc_index] = c.first_key + k;
525  /* Room for extra CVs at Catmull-Rom splines. */
526  rtc_indices[rtc_index] += j * 2;
527 
528  ++rtc_index;
529  }
530  }
531 
532  rtcSetGeometryBuildQuality(geom_id, build_quality);
533  rtcSetGeometryTimeStepCount(geom_id, num_motion_steps);
534 
535  set_curve_vertex_buffer(geom_id, hair, false);
536 
537  rtcSetGeometryUserData(geom_id, (void *)prim_offset);
538  if (hair->curve_shape == CURVE_RIBBON) {
539  rtcSetGeometryIntersectFilterFunction(geom_id, kernel_embree_filter_intersection_func);
540  rtcSetGeometryOccludedFilterFunction(geom_id, kernel_embree_filter_occluded_func);
541  }
542  else {
543  rtcSetGeometryIntersectFilterFunction(geom_id, kernel_embree_filter_func_backface_cull);
544  rtcSetGeometryOccludedFilterFunction(geom_id,
546  }
547  rtcSetGeometryMask(geom_id, ob->visibility_for_tracing());
548 
549  rtcCommitGeometry(geom_id);
550  rtcAttachGeometryByID(scene, geom_id, i * 2 + 1);
551  rtcReleaseGeometry(geom_id);
552 }
553 
554 void BVHEmbree::refit(Progress &progress)
555 {
556  progress.set_substatus("Refitting BVH nodes");
557 
558  /* Update all vertex buffers, then tell Embree to rebuild/-fit the BVHs. */
559  unsigned geom_id = 0;
560  foreach (Object *ob, objects) {
561  if (!params.top_level || (ob->is_traceable() && !ob->get_geometry()->is_instanced())) {
562  Geometry *geom = ob->get_geometry();
563 
564  if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
565  Mesh *mesh = static_cast<Mesh *>(geom);
566  if (mesh->num_triangles() > 0) {
567  RTCGeometry geom = rtcGetGeometry(scene, geom_id);
568  set_tri_vertex_buffer(geom, mesh, true);
569  rtcSetGeometryUserData(geom, (void *)mesh->prim_offset);
570  rtcCommitGeometry(geom);
571  }
572  }
573  else if (geom->geometry_type == Geometry::HAIR) {
574  Hair *hair = static_cast<Hair *>(geom);
575  if (hair->num_curves() > 0) {
576  RTCGeometry geom = rtcGetGeometry(scene, geom_id + 1);
577  set_curve_vertex_buffer(geom, hair, true);
578  rtcSetGeometryUserData(geom, (void *)hair->curve_segment_offset);
579  rtcCommitGeometry(geom);
580  }
581  }
582  else if (geom->geometry_type == Geometry::POINTCLOUD) {
583  PointCloud *pointcloud = static_cast<PointCloud *>(geom);
584  if (pointcloud->num_points() > 0) {
585  RTCGeometry geom = rtcGetGeometry(scene, geom_id);
586  set_point_vertex_buffer(geom, pointcloud, true);
587  rtcCommitGeometry(geom);
588  }
589  }
590  }
591  geom_id += 2;
592  }
593 
594  rtcCommitScene(scene);
595 }
596 
598 
599 #endif /* WITH_EMBREE */
typedef float(TangentPoint)[2]
SSIZE_T ssize_t
Definition: BLI_winstuff.h:71
_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 z
_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 y
_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 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]
ATOMIC_INLINE size_t atomic_add_and_fetch_z(size_t *p, size_t x)
ATOMIC_INLINE size_t atomic_sub_and_fetch_z(size_t *p, size_t x)
void refit(btStridingMeshInterface *triangles, const btVector3 &aabbMin, const btVector3 &aabbMax)
void build(btStridingMeshInterface *triangles, bool useQuantizedAabbCompression, const btVector3 &bvhAabbMin, const btVector3 &bvhAabbMax)
Attribute * find(ustring name) const
float3 * data_float3()
Definition: bvh/bvh.h:63
Type geometry_type
static const uint MAX_MOTION_STEPS
size_t prim_offset
bool has_motion_blur() const
AttributeSet attributes
Definition: hair.h:13
Curve get_curve(size_t i) const
Definition: hair.h:109
size_t curve_segment_offset
Definition: hair.h:88
size_t num_curves() const
Definition: hair.h:123
CurveShapeType curve_shape
Definition: hair.h:89
void set_substatus(const string &substatus_)
Definition: progress.h:259
bool get_cancel() const
Definition: progress.h:90
void mem_free(size_t size)
Definition: util/stats.h:29
void mem_alloc(size_t size)
Definition: util/stats.h:23
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
Scene scene
#define str(s)
static float verts[][3]
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
ccl_device void kernel_embree_filter_occluded_func(const RTCFilterFunctionNArguments *args)
ccl_device void kernel_embree_filter_occluded_func_backface_cull(const RTCFilterFunctionNArguments *args)
ccl_device void kernel_embree_filter_intersection_func(const RTCFilterFunctionNArguments *args)
ccl_device void kernel_embree_filter_func_backface_cull(const RTCFilterFunctionNArguments *args)
@ ATTR_STD_MOTION_VERTEX_POSITION
Definition: kernel/types.h:624
@ CURVE_RIBBON
Definition: kernel/types.h:582
#define VLOG_WARNING
Definition: log.h:75
static unsigned c
Definition: RandGen.cpp:83
static void update(bNodeTree *ntree)
@ BVH_TYPE_DYNAMIC
Definition: params.h:30
#define SIMD_SET_FLUSH_TO_ZERO
Definition: simd.h:42
#define min(a, b)
Definition: sort.c:35
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
Definition: string.cpp:22
float size[3]
Triangle get_triangle(size_t i) const
Definition: scene/mesh.h:73
size_t num_triangles() const
Definition: scene/mesh.h:79
ustring name
Definition: graph/node.h:174
bool use_motion() const
static const uint MAX_MOTION_STEPS
Definition: scene/object.h:90
bool is_traceable() const
uint visibility_for_tracing() const
void * data
size_t num_points() const
CCL_NAMESPACE_BEGIN double time_dt()
Definition: time.cpp:35
void transform_motion_decompose(DecomposedTransform *decomp, const Transform *motion, size_t size)
Definition: transform.cpp:246
ccl_device_inline float4 float3_to_float4(const float3 a)
Definition: util/math.h:505