Blender  V3.3
scene/geometry.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #include "bvh/bvh.h"
5 #include "bvh/bvh2.h"
6 
7 #include "device/device.h"
8 
9 #include "scene/attribute.h"
10 #include "scene/camera.h"
11 #include "scene/geometry.h"
12 #include "scene/hair.h"
13 #include "scene/light.h"
14 #include "scene/mesh.h"
15 #include "scene/object.h"
16 #include "scene/pointcloud.h"
17 #include "scene/scene.h"
18 #include "scene/shader.h"
19 #include "scene/shader_nodes.h"
20 #include "scene/stats.h"
21 #include "scene/volume.h"
22 
23 #include "subd/patch_table.h"
24 #include "subd/split.h"
25 
26 #include "kernel/osl/globals.h"
27 
28 #include "util/foreach.h"
29 #include "util/log.h"
30 #include "util/progress.h"
31 #include "util/task.h"
32 
34 
35 /* Geometry */
36 
38 {
39  NodeType *type = NodeType::add("geometry_base", NULL);
40 
41  SOCKET_UINT(motion_steps, "Motion Steps", 3);
42  SOCKET_BOOLEAN(use_motion_blur, "Use Motion Blur", false);
43  SOCKET_NODE_ARRAY(used_shaders, "Shaders", Shader::get_node_type());
44 
45  return type;
46 }
47 
48 Geometry::Geometry(const NodeType *node_type, const Type type)
49  : Node(node_type), geometry_type(type), attributes(this, ATTR_PRIM_GEOMETRY)
50 {
51  need_update_rebuild = false;
53 
54  transform_applied = false;
58 
59  has_volume = false;
60  has_surface_bssrdf = false;
61 
62  bvh = NULL;
63  attr_map_offset = 0;
64  prim_offset = 0;
65 }
66 
68 {
70  delete bvh;
71 }
72 
73 void Geometry::clear(bool preserve_shaders)
74 {
75  if (!preserve_shaders)
76  used_shaders.clear();
77 
78  transform_applied = false;
81  tag_modified();
82 }
83 
85 {
86  if (std == ATTR_STD_NONE)
87  return false;
88 
90  return true;
91 
92  foreach (Node *node, used_shaders) {
93  Shader *shader = static_cast<Shader *>(node);
94  if (shader->attributes.find(std))
95  return true;
96  }
97 
98  return false;
99 }
100 
101 bool Geometry::need_attribute(Scene * /*scene*/, ustring name)
102 {
103  if (name == ustring())
104  return false;
105 
106  foreach (Node *node, used_shaders) {
107  Shader *shader = static_cast<Shader *>(node);
108  if (shader->attributes.find(name))
109  return true;
110  }
111 
112  return false;
113 }
114 
116 {
118 
119  foreach (Node *node, used_shaders) {
120  Shader *shader = static_cast<Shader *>(node);
121  result.add(shader->attributes);
122  }
123 
124  return result;
125 }
126 
127 float Geometry::motion_time(int step) const
128 {
129  return (motion_steps > 1) ? 2.0f * step / (motion_steps - 1) - 1.0f : 0.0f;
130 }
131 
132 int Geometry::motion_step(float time) const
133 {
134  if (motion_steps > 1) {
135  int attr_step = 0;
136 
137  for (int step = 0; step < motion_steps; step++) {
138  float step_time = motion_time(step);
139  if (step_time == time) {
140  return attr_step;
141  }
142 
143  /* Center step is stored in a separate attribute. */
144  if (step != motion_steps / 2) {
145  attr_step++;
146  }
147  }
148  }
149 
150  return -1;
151 }
152 
154 {
155  return is_instanced() || layout == BVH_LAYOUT_OPTIX || layout == BVH_LAYOUT_MULTI_OPTIX ||
156  layout == BVH_LAYOUT_METAL || layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE ||
158 }
159 
161 {
162  /* Currently we treat subsurface objects as instanced.
163  *
164  * While it might be not very optimal for ray traversal, it avoids having
165  * duplicated BVH in the memory, saving quite some space.
166  */
168 }
169 
171 {
172  foreach (Node *node, used_shaders) {
173  Shader *shader = static_cast<Shader *>(node);
174  if (shader->has_displacement && shader->get_displacement_method() != DISPLACE_BUMP) {
175  return true;
176  }
177  }
178 
179  return false;
180 }
181 
183  DeviceScene *dscene,
185  Progress *progress,
186  size_t n,
187  size_t total)
188 {
189  if (progress->get_cancel())
190  return;
191 
192  compute_bounds();
193 
194  const BVHLayout bvh_layout = BVHParams::best_bvh_layout(params->bvh_layout,
195  device->get_bvh_layout_mask());
196  if (need_build_bvh(bvh_layout)) {
197  string msg = "Updating Geometry BVH ";
198  if (name.empty())
199  msg += string_printf("%u/%u", (uint)(n + 1), (uint)total);
200  else
201  msg += string_printf("%s %u/%u", name.c_str(), (uint)(n + 1), (uint)total);
202 
203  Object object;
204 
205  /* Ensure all visibility bits are set at the geometry level BVH. In
206  * the object level BVH is where actual visibility is tested. */
207  object.set_is_shadow_catcher(true);
208  object.set_visibility(~0);
209 
210  object.set_geometry(this);
211 
212  vector<Geometry *> geometry;
213  geometry.push_back(this);
214  vector<Object *> objects;
215  objects.push_back(&object);
216 
217  if (bvh && !need_update_rebuild) {
218  progress->set_status(msg, "Refitting BVH");
219 
220  bvh->replace_geometry(geometry, objects);
221 
222  device->build_bvh(bvh, *progress, true);
223  }
224  else {
225  progress->set_status(msg, "Building BVH");
226 
227  BVHParams bparams;
228  bparams.use_spatial_split = params->use_bvh_spatial_split;
229  bparams.use_compact_structure = params->use_bvh_compact_structure;
230  bparams.bvh_layout = bvh_layout;
231  bparams.use_unaligned_nodes = dscene->data.bvh.have_curves &&
232  params->use_bvh_unaligned_nodes;
233  bparams.num_motion_triangle_steps = params->num_bvh_time_steps;
234  bparams.num_motion_curve_steps = params->num_bvh_time_steps;
235  bparams.num_motion_point_steps = params->num_bvh_time_steps;
236  bparams.bvh_type = params->bvh_type;
237  bparams.curve_subdivisions = params->curve_subdivisions();
238 
239  delete bvh;
240  bvh = BVH::create(bparams, geometry, objects, device);
241  MEM_GUARDED_CALL(progress, device->build_bvh, bvh, *progress, false);
242  }
243  }
244 
245  need_update_rebuild = false;
247 }
248 
250 {
251  return (use_motion_blur && attributes.find(ATTR_STD_MOTION_VERTEX_POSITION));
252 }
253 
255 {
256  foreach (const Attribute &attr, attributes.attributes) {
257  if (attr.element == ATTR_ELEMENT_VOXEL) {
258  return true;
259  }
260  }
261 
262  return false;
263 }
264 
265 void Geometry::tag_update(Scene *scene, bool rebuild)
266 {
267  if (rebuild) {
268  need_update_rebuild = true;
270  }
271  else {
272  foreach (Node *node, used_shaders) {
273  Shader *shader = static_cast<Shader *>(node);
274  if (shader->has_surface_emission) {
276  break;
277  }
278  }
279  }
280 
282 }
283 
284 void Geometry::tag_bvh_update(bool rebuild)
285 {
286  tag_modified();
287 
288  if (rebuild) {
289  need_update_rebuild = true;
290  }
291 }
292 
293 /* Geometry Manager */
294 
296 {
297  update_flags = UPDATE_ALL;
298  need_flags_update = true;
299 }
300 
302 {
303 }
304 
306  Scene *scene,
307  vector<AttributeRequestSet> &geom_attributes)
308 {
309 #ifdef WITH_OSL
310  /* for OSL, a hash map is used to lookup the attribute by name. */
311  OSLGlobals *og = (OSLGlobals *)device->get_cpu_osl_memory();
312 
313  og->object_name_map.clear();
314  og->attribute_map.clear();
315  og->object_names.clear();
316 
317  og->attribute_map.resize(scene->objects.size() * ATTR_PRIM_TYPES);
318 
319  for (size_t i = 0; i < scene->objects.size(); i++) {
320  /* set object name to object index map */
321  Object *object = scene->objects[i];
322  og->object_name_map[object->name] = i;
323  og->object_names.push_back(object->name);
324 
325  /* set object attributes */
326  foreach (ParamValue &attr, object->attributes) {
327  OSLGlobals::Attribute osl_attr;
328 
329  osl_attr.type = attr.type();
330  osl_attr.desc.element = ATTR_ELEMENT_OBJECT;
331  osl_attr.value = attr;
332  osl_attr.desc.offset = 0;
333  osl_attr.desc.flags = 0;
334 
335  og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][attr.name()] = osl_attr;
336  og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][attr.name()] = osl_attr;
337  }
338 
339  /* find geometry attributes */
340  size_t j = object->geometry->index;
341  assert(j < scene->geometry.size() && scene->geometry[j] == object->geometry);
342 
343  AttributeRequestSet &attributes = geom_attributes[j];
344 
345  /* set mesh attributes */
346  foreach (AttributeRequest &req, attributes.requests) {
347  OSLGlobals::Attribute osl_attr;
348 
349  if (req.desc.element != ATTR_ELEMENT_NONE) {
350  osl_attr.desc = req.desc;
351 
352  if (req.type == TypeDesc::TypeFloat)
353  osl_attr.type = TypeDesc::TypeFloat;
354  else if (req.type == TypeDesc::TypeMatrix)
355  osl_attr.type = TypeDesc::TypeMatrix;
356  else if (req.type == TypeFloat2)
357  osl_attr.type = TypeFloat2;
358  else if (req.type == TypeRGBA)
359  osl_attr.type = TypeRGBA;
360  else
361  osl_attr.type = TypeDesc::TypeColor;
362 
363  if (req.std != ATTR_STD_NONE) {
364  /* if standard attribute, add lookup by geom: name convention */
365  ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
366  og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][stdname] = osl_attr;
367  }
368  else if (req.name != ustring()) {
369  /* add lookup by geometry attribute name */
370  og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][req.name] = osl_attr;
371  }
372  }
373 
374  if (req.subd_desc.element != ATTR_ELEMENT_NONE) {
375  osl_attr.desc = req.subd_desc;
376 
377  if (req.subd_type == TypeDesc::TypeFloat)
378  osl_attr.type = TypeDesc::TypeFloat;
379  else if (req.subd_type == TypeDesc::TypeMatrix)
380  osl_attr.type = TypeDesc::TypeMatrix;
381  else if (req.subd_type == TypeFloat2)
382  osl_attr.type = TypeFloat2;
383  else if (req.subd_type == TypeRGBA)
384  osl_attr.type = TypeRGBA;
385  else
386  osl_attr.type = TypeDesc::TypeColor;
387 
388  if (req.std != ATTR_STD_NONE) {
389  /* if standard attribute, add lookup by geom: name convention */
390  ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
391  og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][stdname] = osl_attr;
392  }
393  else if (req.name != ustring()) {
394  /* add lookup by geometry attribute name */
395  og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][req.name] = osl_attr;
396  }
397  }
398  }
399  }
400 #else
401  (void)device;
402  (void)scene;
403  (void)geom_attributes;
404 #endif
405 }
406 
407 /* Generate a normal attribute map entry from an attribute descriptor. */
409  AttributeMap *attr_map, int index, uint id, TypeDesc type, const AttributeDescriptor &desc)
410 {
411  attr_map[index].id = id;
412  attr_map[index].element = desc.element;
413  attr_map[index].offset = as_uint(desc.offset);
414 
415  if (type == TypeDesc::TypeFloat)
416  attr_map[index].type = NODE_ATTR_FLOAT;
417  else if (type == TypeDesc::TypeMatrix)
418  attr_map[index].type = NODE_ATTR_MATRIX;
419  else if (type == TypeFloat2)
420  attr_map[index].type = NODE_ATTR_FLOAT2;
421  else if (type == TypeFloat4)
422  attr_map[index].type = NODE_ATTR_FLOAT4;
423  else if (type == TypeRGBA)
424  attr_map[index].type = NODE_ATTR_RGBA;
425  else
426  attr_map[index].type = NODE_ATTR_FLOAT3;
427 
428  attr_map[index].flags = desc.flags;
429 }
430 
431 /* Generate an attribute map end marker, optionally including a link to another map.
432  * Links are used to connect object attribute maps to mesh attribute maps. */
434  int index,
435  bool chain,
436  uint chain_link)
437 {
438  for (int j = 0; j < ATTR_PRIM_TYPES; j++) {
439  attr_map[index + j].id = ATTR_STD_NONE;
440  attr_map[index + j].element = chain; /* link is valid flag */
441  attr_map[index + j].offset = chain ? chain_link + j : 0; /* link to the correct sub-entry */
442  attr_map[index + j].type = 0;
443  attr_map[index + j].flags = 0;
444  }
445 }
446 
447 /* Generate all necessary attribute map entries from the attribute request. */
449  AttributeMap *attr_map, int index, Scene *scene, AttributeRequest &req, Geometry *geom)
450 {
451  uint id;
452 
453  if (req.std == ATTR_STD_NONE)
455  else
457 
458  emit_attribute_map_entry(attr_map, index, id, req.type, req.desc);
459 
460  if (geom->is_mesh()) {
461  Mesh *mesh = static_cast<Mesh *>(geom);
462  if (mesh->get_num_subd_faces()) {
463  emit_attribute_map_entry(attr_map, index + 1, id, req.subd_type, req.subd_desc);
464  }
465  }
466 }
467 
469  DeviceScene *dscene,
470  Scene *scene,
471  vector<AttributeRequestSet> &geom_attributes,
472  vector<AttributeRequestSet> &object_attributes)
473 {
474  /* for SVM, the attributes_map table is used to lookup the offset of an
475  * attribute, based on a unique shader attribute id. */
476 
477  /* compute array stride */
478  int attr_map_size = 0;
479 
480  for (size_t i = 0; i < scene->geometry.size(); i++) {
481  Geometry *geom = scene->geometry[i];
482  geom->attr_map_offset = attr_map_size;
483  attr_map_size += (geom_attributes[i].size() + 1) * ATTR_PRIM_TYPES;
484  }
485 
486  for (size_t i = 0; i < scene->objects.size(); i++) {
487  Object *object = scene->objects[i];
488 
489  /* only allocate a table for the object if it actually has attributes */
490  if (object_attributes[i].size() == 0) {
491  object->attr_map_offset = 0;
492  }
493  else {
494  object->attr_map_offset = attr_map_size;
495  attr_map_size += (object_attributes[i].size() + 1) * ATTR_PRIM_TYPES;
496  }
497  }
498 
499  if (attr_map_size == 0)
500  return;
501 
502  if (!dscene->attributes_map.need_realloc()) {
503  return;
504  }
505 
506  /* create attribute map */
507  AttributeMap *attr_map = dscene->attributes_map.alloc(attr_map_size);
508  memset(attr_map, 0, dscene->attributes_map.size() * sizeof(*attr_map));
509 
510  for (size_t i = 0; i < scene->geometry.size(); i++) {
511  Geometry *geom = scene->geometry[i];
512  AttributeRequestSet &attributes = geom_attributes[i];
513 
514  /* set geometry attributes */
515  int index = geom->attr_map_offset;
516 
517  foreach (AttributeRequest &req, attributes.requests) {
518  emit_attribute_mapping(attr_map, index, scene, req, geom);
519  index += ATTR_PRIM_TYPES;
520  }
521 
522  emit_attribute_map_terminator(attr_map, index, false, 0);
523  }
524 
525  for (size_t i = 0; i < scene->objects.size(); i++) {
526  Object *object = scene->objects[i];
527  AttributeRequestSet &attributes = object_attributes[i];
528 
529  /* set object attributes */
530  if (attributes.size() > 0) {
531  int index = object->attr_map_offset;
532 
533  foreach (AttributeRequest &req, attributes.requests) {
534  emit_attribute_mapping(attr_map, index, scene, req, object->geometry);
535  index += ATTR_PRIM_TYPES;
536  }
537 
538  emit_attribute_map_terminator(attr_map, index, true, object->geometry->attr_map_offset);
539  }
540  }
541 
542  /* copy to device */
543  dscene->attributes_map.copy_to_device();
544 }
545 
547  Attribute *mattr,
548  AttributePrimitive prim,
549  size_t *attr_float_size,
550  size_t *attr_float2_size,
551  size_t *attr_float3_size,
552  size_t *attr_float4_size,
553  size_t *attr_uchar4_size)
554 {
555  if (mattr) {
556  size_t size = mattr->element_size(geom, prim);
557 
558  if (mattr->element == ATTR_ELEMENT_VOXEL) {
559  /* pass */
560  }
561  else if (mattr->element == ATTR_ELEMENT_CORNER_BYTE) {
562  *attr_uchar4_size += size;
563  }
564  else if (mattr->type == TypeDesc::TypeFloat) {
565  *attr_float_size += size;
566  }
567  else if (mattr->type == TypeFloat2) {
568  *attr_float2_size += size;
569  }
570  else if (mattr->type == TypeDesc::TypeMatrix) {
571  *attr_float4_size += size * 4;
572  }
573  else if (mattr->type == TypeFloat4 || mattr->type == TypeRGBA) {
574  *attr_float4_size += size;
575  }
576  else {
577  *attr_float3_size += size;
578  }
579  }
580 }
581 
582 void GeometryManager::update_attribute_element_offset(Geometry *geom,
583  device_vector<float> &attr_float,
584  size_t &attr_float_offset,
585  device_vector<float2> &attr_float2,
586  size_t &attr_float2_offset,
587  device_vector<packed_float3> &attr_float3,
588  size_t &attr_float3_offset,
589  device_vector<float4> &attr_float4,
590  size_t &attr_float4_offset,
591  device_vector<uchar4> &attr_uchar4,
592  size_t &attr_uchar4_offset,
593  Attribute *mattr,
594  AttributePrimitive prim,
595  TypeDesc &type,
596  AttributeDescriptor &desc)
597 {
598  if (mattr) {
599  /* store element and type */
600  desc.element = mattr->element;
601  desc.flags = mattr->flags;
602  type = mattr->type;
603 
604  /* store attribute data in arrays */
605  size_t size = mattr->element_size(geom, prim);
606 
608  int &offset = desc.offset;
609 
610  if (mattr->element == ATTR_ELEMENT_VOXEL) {
611  /* store slot in offset value */
612  ImageHandle &handle = mattr->data_voxel();
613  offset = handle.svm_slot();
614  }
615  else if (mattr->element == ATTR_ELEMENT_CORNER_BYTE) {
616  uchar4 *data = mattr->data_uchar4();
617  offset = attr_uchar4_offset;
618 
619  assert(attr_uchar4.size() >= offset + size);
620  if (mattr->modified) {
621  for (size_t k = 0; k < size; k++) {
622  attr_uchar4[offset + k] = data[k];
623  }
624  attr_uchar4.tag_modified();
625  }
626  attr_uchar4_offset += size;
627  }
628  else if (mattr->type == TypeDesc::TypeFloat) {
629  float *data = mattr->data_float();
630  offset = attr_float_offset;
631 
632  assert(attr_float.size() >= offset + size);
633  if (mattr->modified) {
634  for (size_t k = 0; k < size; k++) {
635  attr_float[offset + k] = data[k];
636  }
637  attr_float.tag_modified();
638  }
639  attr_float_offset += size;
640  }
641  else if (mattr->type == TypeFloat2) {
642  float2 *data = mattr->data_float2();
643  offset = attr_float2_offset;
644 
645  assert(attr_float2.size() >= offset + size);
646  if (mattr->modified) {
647  for (size_t k = 0; k < size; k++) {
648  attr_float2[offset + k] = data[k];
649  }
650  attr_float2.tag_modified();
651  }
652  attr_float2_offset += size;
653  }
654  else if (mattr->type == TypeDesc::TypeMatrix) {
655  Transform *tfm = mattr->data_transform();
656  offset = attr_float4_offset;
657 
658  assert(attr_float4.size() >= offset + size * 3);
659  if (mattr->modified) {
660  for (size_t k = 0; k < size * 3; k++) {
661  attr_float4[offset + k] = (&tfm->x)[k];
662  }
663  attr_float4.tag_modified();
664  }
665  attr_float4_offset += size * 3;
666  }
667  else if (mattr->type == TypeFloat4 || mattr->type == TypeRGBA) {
668  float4 *data = mattr->data_float4();
669  offset = attr_float4_offset;
670 
671  assert(attr_float4.size() >= offset + size);
672  if (mattr->modified) {
673  for (size_t k = 0; k < size; k++) {
674  attr_float4[offset + k] = data[k];
675  }
676  attr_float4.tag_modified();
677  }
678  attr_float4_offset += size;
679  }
680  else {
681  float3 *data = mattr->data_float3();
682  offset = attr_float3_offset;
683 
684  assert(attr_float3.size() >= offset + size);
685  if (mattr->modified) {
686  for (size_t k = 0; k < size; k++) {
687  attr_float3[offset + k] = data[k];
688  }
689  attr_float3.tag_modified();
690  }
691  attr_float3_offset += size;
692  }
693 
694  /* mesh vertex/curve index is global, not per object, so we sneak
695  * a correction for that in here */
696  if (geom->is_mesh()) {
697  Mesh *mesh = static_cast<Mesh *>(geom);
698  if (mesh->subdivision_type == Mesh::SUBDIVISION_CATMULL_CLARK &&
699  desc.flags & ATTR_SUBDIVIDED) {
700  /* Indices for subdivided attributes are retrieved
701  * from patch table so no need for correction here. */
702  }
703  else if (element == ATTR_ELEMENT_VERTEX)
704  offset -= mesh->vert_offset;
706  offset -= mesh->vert_offset;
707  else if (element == ATTR_ELEMENT_FACE) {
708  if (prim == ATTR_PRIM_GEOMETRY)
709  offset -= mesh->prim_offset;
710  else
711  offset -= mesh->face_offset;
712  }
714  if (prim == ATTR_PRIM_GEOMETRY)
715  offset -= 3 * mesh->prim_offset;
716  else
717  offset -= mesh->corner_offset;
718  }
719  }
720  else if (geom->is_hair()) {
721  Hair *hair = static_cast<Hair *>(geom);
723  offset -= hair->prim_offset;
724  else if (element == ATTR_ELEMENT_CURVE_KEY)
725  offset -= hair->curve_key_offset;
727  offset -= hair->curve_key_offset;
728  }
729  else if (geom->is_pointcloud()) {
731  offset -= geom->prim_offset;
733  offset -= geom->prim_offset;
734  }
735  }
736  else {
737  /* attribute not found */
738  desc.element = ATTR_ELEMENT_NONE;
739  desc.offset = 0;
740  }
741 }
742 
744  DeviceScene *dscene,
745  Scene *scene,
746  Progress &progress)
747 {
748  progress.set_status("Updating Mesh", "Computing attributes");
749 
750  /* gather per mesh requested attributes. as meshes may have multiple
751  * shaders assigned, this merges the requested attributes that have
752  * been set per shader by the shader manager */
753  vector<AttributeRequestSet> geom_attributes(scene->geometry.size());
754 
755  for (size_t i = 0; i < scene->geometry.size(); i++) {
756  Geometry *geom = scene->geometry[i];
757 
758  geom->index = i;
759  scene->need_global_attributes(geom_attributes[i]);
760 
761  foreach (Node *node, geom->get_used_shaders()) {
762  Shader *shader = static_cast<Shader *>(node);
763  geom_attributes[i].add(shader->attributes);
764  }
765 
766  if (geom->is_hair() && static_cast<Hair *>(geom)->need_shadow_transparency()) {
767  geom_attributes[i].add(ATTR_STD_SHADOW_TRANSPARENCY);
768  }
769  }
770 
771  /* convert object attributes to use the same data structures as geometry ones */
772  vector<AttributeRequestSet> object_attributes(scene->objects.size());
773  vector<AttributeSet> object_attribute_values;
774 
775  object_attribute_values.reserve(scene->objects.size());
776 
777  for (size_t i = 0; i < scene->objects.size(); i++) {
778  Object *object = scene->objects[i];
779  Geometry *geom = object->geometry;
780  size_t geom_idx = geom->index;
781 
782  assert(geom_idx < scene->geometry.size() && scene->geometry[geom_idx] == geom);
783 
784  object_attribute_values.push_back(AttributeSet(geom, ATTR_PRIM_GEOMETRY));
785 
786  AttributeRequestSet &geom_requests = geom_attributes[geom_idx];
787  AttributeRequestSet &attributes = object_attributes[i];
788  AttributeSet &values = object_attribute_values[i];
789 
790  for (size_t j = 0; j < object->attributes.size(); j++) {
791  ParamValue &param = object->attributes[j];
792 
793  /* add attributes that are requested and not already handled by the mesh */
794  if (geom_requests.find(param.name()) && !geom->attributes.find(param.name())) {
795  attributes.add(param.name());
796 
797  Attribute *attr = values.add(param.name(), param.type(), ATTR_ELEMENT_OBJECT);
798  assert(param.datasize() == attr->buffer.size());
799  memcpy(attr->buffer.data(), param.data(), param.datasize());
800  }
801  }
802  }
803 
804  /* mesh attribute are stored in a single array per data type. here we fill
805  * those arrays, and set the offset and element type to create attribute
806  * maps next */
807 
808  /* Pre-allocate attributes to avoid arrays re-allocation which would
809  * take 2x of overall attribute memory usage.
810  */
811  size_t attr_float_size = 0;
812  size_t attr_float2_size = 0;
813  size_t attr_float3_size = 0;
814  size_t attr_float4_size = 0;
815  size_t attr_uchar4_size = 0;
816 
817  for (size_t i = 0; i < scene->geometry.size(); i++) {
818  Geometry *geom = scene->geometry[i];
819  AttributeRequestSet &attributes = geom_attributes[i];
820  foreach (AttributeRequest &req, attributes.requests) {
821  Attribute *attr = geom->attributes.find(req);
822 
824  attr,
826  &attr_float_size,
827  &attr_float2_size,
828  &attr_float3_size,
829  &attr_float4_size,
830  &attr_uchar4_size);
831 
832  if (geom->is_mesh()) {
833  Mesh *mesh = static_cast<Mesh *>(geom);
834  Attribute *subd_attr = mesh->subd_attributes.find(req);
835 
837  subd_attr,
839  &attr_float_size,
840  &attr_float2_size,
841  &attr_float3_size,
842  &attr_float4_size,
843  &attr_uchar4_size);
844  }
845  }
846  }
847 
848  for (size_t i = 0; i < scene->objects.size(); i++) {
849  Object *object = scene->objects[i];
850 
851  foreach (Attribute &attr, object_attribute_values[i].attributes) {
852  update_attribute_element_size(object->geometry,
853  &attr,
855  &attr_float_size,
856  &attr_float2_size,
857  &attr_float3_size,
858  &attr_float4_size,
859  &attr_uchar4_size);
860  }
861  }
862 
863  dscene->attributes_float.alloc(attr_float_size);
864  dscene->attributes_float2.alloc(attr_float2_size);
865  dscene->attributes_float3.alloc(attr_float3_size);
866  dscene->attributes_float4.alloc(attr_float4_size);
867  dscene->attributes_uchar4.alloc(attr_uchar4_size);
868 
869  /* The order of those flags needs to match that of AttrKernelDataType. */
870  const bool attributes_need_realloc[AttrKernelDataType::NUM] = {
871  dscene->attributes_float.need_realloc(),
876  };
877 
878  size_t attr_float_offset = 0;
879  size_t attr_float2_offset = 0;
880  size_t attr_float3_offset = 0;
881  size_t attr_float4_offset = 0;
882  size_t attr_uchar4_offset = 0;
883 
884  /* Fill in attributes. */
885  for (size_t i = 0; i < scene->geometry.size(); i++) {
886  Geometry *geom = scene->geometry[i];
887  AttributeRequestSet &attributes = geom_attributes[i];
888 
889  /* todo: we now store std and name attributes from requests even if
890  * they actually refer to the same mesh attributes, optimize */
891  foreach (AttributeRequest &req, attributes.requests) {
892  Attribute *attr = geom->attributes.find(req);
893 
894  if (attr) {
895  /* force a copy if we need to reallocate all the data */
896  attr->modified |= attributes_need_realloc[Attribute::kernel_type(*attr)];
897  }
898 
899  update_attribute_element_offset(geom,
900  dscene->attributes_float,
901  attr_float_offset,
902  dscene->attributes_float2,
903  attr_float2_offset,
904  dscene->attributes_float3,
905  attr_float3_offset,
906  dscene->attributes_float4,
907  attr_float4_offset,
908  dscene->attributes_uchar4,
909  attr_uchar4_offset,
910  attr,
912  req.type,
913  req.desc);
914 
915  if (geom->is_mesh()) {
916  Mesh *mesh = static_cast<Mesh *>(geom);
917  Attribute *subd_attr = mesh->subd_attributes.find(req);
918 
919  if (subd_attr) {
920  /* force a copy if we need to reallocate all the data */
921  subd_attr->modified |= attributes_need_realloc[Attribute::kernel_type(*subd_attr)];
922  }
923 
924  update_attribute_element_offset(mesh,
925  dscene->attributes_float,
926  attr_float_offset,
927  dscene->attributes_float2,
928  attr_float2_offset,
929  dscene->attributes_float3,
930  attr_float3_offset,
931  dscene->attributes_float4,
932  attr_float4_offset,
933  dscene->attributes_uchar4,
934  attr_uchar4_offset,
935  subd_attr,
937  req.subd_type,
938  req.subd_desc);
939  }
940 
941  if (progress.get_cancel())
942  return;
943  }
944  }
945 
946  for (size_t i = 0; i < scene->objects.size(); i++) {
947  Object *object = scene->objects[i];
948  AttributeRequestSet &attributes = object_attributes[i];
949  AttributeSet &values = object_attribute_values[i];
950 
951  foreach (AttributeRequest &req, attributes.requests) {
952  Attribute *attr = values.find(req);
953 
954  if (attr) {
955  attr->modified |= attributes_need_realloc[Attribute::kernel_type(*attr)];
956  }
957 
958  update_attribute_element_offset(object->geometry,
959  dscene->attributes_float,
960  attr_float_offset,
961  dscene->attributes_float2,
962  attr_float2_offset,
963  dscene->attributes_float3,
964  attr_float3_offset,
965  dscene->attributes_float4,
966  attr_float4_offset,
967  dscene->attributes_uchar4,
968  attr_uchar4_offset,
969  attr,
971  req.type,
972  req.desc);
973 
974  /* object attributes don't care about subdivision */
975  req.subd_type = req.type;
976  req.subd_desc = req.desc;
977 
978  if (progress.get_cancel())
979  return;
980  }
981  }
982 
983  /* create attribute lookup maps */
984  if (scene->shader_manager->use_osl())
985  update_osl_attributes(device, scene, geom_attributes);
986 
987  update_svm_attributes(device, dscene, scene, geom_attributes, object_attributes);
988 
989  if (progress.get_cancel())
990  return;
991 
992  /* copy to device */
993  progress.set_status("Updating Mesh", "Copying Attributes to device");
994 
1000 
1001  if (progress.get_cancel())
1002  return;
1003 
1004  /* After mesh attributes and patch tables have been copied to device memory,
1005  * we need to update offsets in the objects. */
1007 }
1008 
1010 {
1011  size_t vert_size = 0;
1012  size_t tri_size = 0;
1013 
1014  size_t curve_size = 0;
1015  size_t curve_key_size = 0;
1016  size_t curve_segment_size = 0;
1017 
1018  size_t point_size = 0;
1019 
1020  size_t patch_size = 0;
1021  size_t face_size = 0;
1022  size_t corner_size = 0;
1023 
1024  foreach (Geometry *geom, scene->geometry) {
1025  bool prim_offset_changed = false;
1026 
1027  if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
1028  Mesh *mesh = static_cast<Mesh *>(geom);
1029 
1030  prim_offset_changed = (mesh->prim_offset != tri_size);
1031 
1032  mesh->vert_offset = vert_size;
1033  mesh->prim_offset = tri_size;
1034 
1035  mesh->patch_offset = patch_size;
1036  mesh->face_offset = face_size;
1037  mesh->corner_offset = corner_size;
1038 
1039  vert_size += mesh->verts.size();
1040  tri_size += mesh->num_triangles();
1041 
1042  if (mesh->get_num_subd_faces()) {
1044  patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8;
1045 
1046  /* patch tables are stored in same array so include them in patch_size */
1047  if (mesh->patch_table) {
1048  mesh->patch_table_offset = patch_size;
1049  patch_size += mesh->patch_table->total_size();
1050  }
1051  }
1052 
1053  face_size += mesh->get_num_subd_faces();
1054  corner_size += mesh->subd_face_corners.size();
1055  }
1056  else if (geom->is_hair()) {
1057  Hair *hair = static_cast<Hair *>(geom);
1058 
1059  prim_offset_changed = (hair->curve_segment_offset != curve_segment_size);
1060  hair->curve_key_offset = curve_key_size;
1061  hair->curve_segment_offset = curve_segment_size;
1062  hair->prim_offset = curve_size;
1063 
1064  curve_size += hair->num_curves();
1065  curve_key_size += hair->get_curve_keys().size();
1066  curve_segment_size += hair->num_segments();
1067  }
1068  else if (geom->is_pointcloud()) {
1069  PointCloud *pointcloud = static_cast<PointCloud *>(geom);
1070 
1071  prim_offset_changed = (pointcloud->prim_offset != point_size);
1072 
1073  pointcloud->prim_offset = point_size;
1074  point_size += pointcloud->num_points();
1075  }
1076 
1077  if (prim_offset_changed) {
1078  /* Need to rebuild BVH in OptiX, since refit only allows modified mesh data there */
1079  const bool has_optix_bvh = bvh_layout == BVH_LAYOUT_OPTIX ||
1080  bvh_layout == BVH_LAYOUT_MULTI_OPTIX ||
1081  bvh_layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE;
1082  geom->need_update_rebuild |= has_optix_bvh;
1083  geom->need_update_bvh_for_offset = true;
1084  }
1085  }
1086 }
1087 
1089  DeviceScene *dscene,
1090  Scene *scene,
1091  Progress &progress)
1092 {
1093  /* Count. */
1094  size_t vert_size = 0;
1095  size_t tri_size = 0;
1096 
1097  size_t curve_key_size = 0;
1098  size_t curve_size = 0;
1099  size_t curve_segment_size = 0;
1100 
1101  size_t point_size = 0;
1102 
1103  size_t patch_size = 0;
1104 
1105  foreach (Geometry *geom, scene->geometry) {
1106  if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
1107  Mesh *mesh = static_cast<Mesh *>(geom);
1108 
1109  vert_size += mesh->verts.size();
1110  tri_size += mesh->num_triangles();
1111 
1112  if (mesh->get_num_subd_faces()) {
1114  patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8;
1115 
1116  /* patch tables are stored in same array so include them in patch_size */
1117  if (mesh->patch_table) {
1118  mesh->patch_table_offset = patch_size;
1119  patch_size += mesh->patch_table->total_size();
1120  }
1121  }
1122  }
1123  else if (geom->is_hair()) {
1124  Hair *hair = static_cast<Hair *>(geom);
1125 
1126  curve_key_size += hair->get_curve_keys().size();
1127  curve_size += hair->num_curves();
1128  curve_segment_size += hair->num_segments();
1129  }
1130  else if (geom->is_pointcloud()) {
1131  PointCloud *pointcloud = static_cast<PointCloud *>(geom);
1132  point_size += pointcloud->num_points();
1133  }
1134  }
1135 
1136  /* Fill in all the arrays. */
1137  if (tri_size != 0) {
1138  /* normals */
1139  progress.set_status("Updating Mesh", "Computing normals");
1140 
1141  packed_float3 *tri_verts = dscene->tri_verts.alloc(tri_size * 3);
1142  uint *tri_shader = dscene->tri_shader.alloc(tri_size);
1143  packed_float3 *vnormal = dscene->tri_vnormal.alloc(vert_size);
1144  uint4 *tri_vindex = dscene->tri_vindex.alloc(tri_size);
1145  uint *tri_patch = dscene->tri_patch.alloc(tri_size);
1146  float2 *tri_patch_uv = dscene->tri_patch_uv.alloc(vert_size);
1147 
1148  const bool copy_all_data = dscene->tri_shader.need_realloc() ||
1149  dscene->tri_vindex.need_realloc() ||
1150  dscene->tri_vnormal.need_realloc() ||
1151  dscene->tri_patch.need_realloc() ||
1152  dscene->tri_patch_uv.need_realloc();
1153 
1154  foreach (Geometry *geom, scene->geometry) {
1155  if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
1156  Mesh *mesh = static_cast<Mesh *>(geom);
1157 
1158  if (mesh->shader_is_modified() || mesh->smooth_is_modified() ||
1159  mesh->triangles_is_modified() || copy_all_data) {
1160  mesh->pack_shaders(scene, &tri_shader[mesh->prim_offset]);
1161  }
1162 
1163  if (mesh->verts_is_modified() || copy_all_data) {
1164  mesh->pack_normals(&vnormal[mesh->vert_offset]);
1165  }
1166 
1167  if (mesh->verts_is_modified() || mesh->triangles_is_modified() ||
1168  mesh->vert_patch_uv_is_modified() || copy_all_data) {
1169  mesh->pack_verts(&tri_verts[mesh->prim_offset * 3],
1170  &tri_vindex[mesh->prim_offset],
1171  &tri_patch[mesh->prim_offset],
1172  &tri_patch_uv[mesh->vert_offset]);
1173  }
1174 
1175  if (progress.get_cancel())
1176  return;
1177  }
1178  }
1179 
1180  /* vertex coordinates */
1181  progress.set_status("Updating Mesh", "Copying Mesh to device");
1182 
1189  }
1190 
1191  if (curve_segment_size != 0) {
1192  progress.set_status("Updating Mesh", "Copying Curves to device");
1193 
1194  float4 *curve_keys = dscene->curve_keys.alloc(curve_key_size);
1195  KernelCurve *curves = dscene->curves.alloc(curve_size);
1196  KernelCurveSegment *curve_segments = dscene->curve_segments.alloc(curve_segment_size);
1197 
1198  const bool copy_all_data = dscene->curve_keys.need_realloc() ||
1199  dscene->curves.need_realloc() ||
1200  dscene->curve_segments.need_realloc();
1201 
1202  foreach (Geometry *geom, scene->geometry) {
1203  if (geom->is_hair()) {
1204  Hair *hair = static_cast<Hair *>(geom);
1205 
1206  bool curve_keys_co_modified = hair->curve_radius_is_modified() ||
1207  hair->curve_keys_is_modified();
1208  bool curve_data_modified = hair->curve_shader_is_modified() ||
1209  hair->curve_first_key_is_modified();
1210 
1211  if (!curve_keys_co_modified && !curve_data_modified && !copy_all_data) {
1212  continue;
1213  }
1214 
1215  hair->pack_curves(scene,
1216  &curve_keys[hair->curve_key_offset],
1217  &curves[hair->prim_offset],
1218  &curve_segments[hair->curve_segment_offset]);
1219  if (progress.get_cancel())
1220  return;
1221  }
1222  }
1223 
1227  }
1228 
1229  if (point_size != 0) {
1230  progress.set_status("Updating Mesh", "Copying Point clouds to device");
1231 
1232  float4 *points = dscene->points.alloc(point_size);
1233  uint *points_shader = dscene->points_shader.alloc(point_size);
1234 
1235  foreach (Geometry *geom, scene->geometry) {
1236  if (geom->is_pointcloud()) {
1237  PointCloud *pointcloud = static_cast<PointCloud *>(geom);
1238  pointcloud->pack(
1239  scene, &points[pointcloud->prim_offset], &points_shader[pointcloud->prim_offset]);
1240  if (progress.get_cancel())
1241  return;
1242  }
1243  }
1244 
1245  dscene->points.copy_to_device();
1246  dscene->points_shader.copy_to_device();
1247  }
1248 
1249  if (patch_size != 0 && dscene->patches.need_realloc()) {
1250  progress.set_status("Updating Mesh", "Copying Patches to device");
1251 
1252  uint *patch_data = dscene->patches.alloc(patch_size);
1253 
1254  foreach (Geometry *geom, scene->geometry) {
1255  if (geom->is_mesh()) {
1256  Mesh *mesh = static_cast<Mesh *>(geom);
1257  mesh->pack_patches(&patch_data[mesh->patch_offset]);
1258 
1259  if (mesh->patch_table) {
1260  mesh->patch_table->copy_adjusting_offsets(&patch_data[mesh->patch_table_offset],
1261  mesh->patch_table_offset);
1262  }
1263 
1264  if (progress.get_cancel())
1265  return;
1266  }
1267  }
1268 
1269  dscene->patches.copy_to_device();
1270  }
1271 }
1272 
1274  DeviceScene *dscene,
1275  Scene *scene,
1276  Progress &progress)
1277 {
1278  /* bvh build */
1279  progress.set_status("Updating Scene BVH", "Building");
1280 
1281  BVHParams bparams;
1282  bparams.top_level = true;
1284  device->get_bvh_layout_mask());
1286  bparams.use_unaligned_nodes = dscene->data.bvh.have_curves &&
1291  bparams.bvh_type = scene->params.bvh_type;
1293 
1294  VLOG_INFO << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout.";
1295 
1296  const bool can_refit = scene->bvh != nullptr &&
1299 
1300  BVH *bvh = scene->bvh;
1301  if (!scene->bvh) {
1302  bvh = scene->bvh = BVH::create(bparams, scene->geometry, scene->objects, device);
1303  }
1304 
1305  device->build_bvh(bvh, progress, can_refit);
1306 
1307  if (progress.get_cancel()) {
1308  return;
1309  }
1310 
1311  const bool has_bvh2_layout = (bparams.bvh_layout == BVH_LAYOUT_BVH2);
1312 
1313  PackedBVH pack;
1314  if (has_bvh2_layout) {
1315  pack = std::move(static_cast<BVH2 *>(bvh)->pack);
1316  }
1317  else {
1318  pack.root_index = -1;
1319  }
1320 
1321  /* copy to device */
1322  progress.set_status("Updating Scene BVH", "Copying BVH to device");
1323 
1324  /* When using BVH2, we always have to copy/update the data as its layout is dependent on the
1325  * BVH's leaf nodes which may be different when the objects or vertices move. */
1326 
1327  if (pack.nodes.size()) {
1328  dscene->bvh_nodes.steal_data(pack.nodes);
1329  dscene->bvh_nodes.copy_to_device();
1330  }
1331  if (pack.leaf_nodes.size()) {
1332  dscene->bvh_leaf_nodes.steal_data(pack.leaf_nodes);
1333  dscene->bvh_leaf_nodes.copy_to_device();
1334  }
1335  if (pack.object_node.size()) {
1336  dscene->object_node.steal_data(pack.object_node);
1337  dscene->object_node.copy_to_device();
1338  }
1339  if (pack.prim_type.size()) {
1340  dscene->prim_type.steal_data(pack.prim_type);
1341  dscene->prim_type.copy_to_device();
1342  }
1343  if (pack.prim_visibility.size()) {
1345  dscene->prim_visibility.copy_to_device();
1346  }
1347  if (pack.prim_index.size()) {
1348  dscene->prim_index.steal_data(pack.prim_index);
1349  dscene->prim_index.copy_to_device();
1350  }
1351  if (pack.prim_object.size()) {
1352  dscene->prim_object.steal_data(pack.prim_object);
1353  dscene->prim_object.copy_to_device();
1354  }
1355  if (pack.prim_time.size()) {
1356  dscene->prim_time.steal_data(pack.prim_time);
1357  dscene->prim_time.copy_to_device();
1358  }
1359 
1360  dscene->data.bvh.root = pack.root_index;
1361  dscene->data.bvh.use_bvh_steps = (scene->params.num_bvh_time_steps != 0);
1362  dscene->data.bvh.curve_subdivisions = scene->params.curve_subdivisions();
1363  /* The scene handle is set in 'CPUDevice::const_copy_to' and 'OptiXDevice::const_copy_to' */
1364  dscene->data.device_bvh = 0;
1365 }
1366 
1367 /* Set of flags used to help determining what data has been modified or needs reallocation, so we
1368  * can decide which device data to free or update. */
1369 enum {
1373 
1379 
1383 
1388 
1390 
1397 };
1398 
1399 static void update_device_flags_attribute(uint32_t &device_update_flags,
1400  const AttributeSet &attributes)
1401 {
1402  foreach (const Attribute &attr, attributes.attributes) {
1403  if (!attr.modified) {
1404  continue;
1405  }
1406 
1407  AttrKernelDataType kernel_type = Attribute::kernel_type(attr);
1408 
1409  switch (kernel_type) {
1411  device_update_flags |= ATTR_FLOAT_MODIFIED;
1412  break;
1413  }
1415  device_update_flags |= ATTR_FLOAT2_MODIFIED;
1416  break;
1417  }
1419  device_update_flags |= ATTR_FLOAT3_MODIFIED;
1420  break;
1421  }
1423  device_update_flags |= ATTR_FLOAT4_MODIFIED;
1424  break;
1425  }
1427  device_update_flags |= ATTR_UCHAR4_MODIFIED;
1428  break;
1429  }
1430  case AttrKernelDataType::NUM: {
1431  break;
1432  }
1433  }
1434  }
1435 }
1436 
1437 static void update_attribute_realloc_flags(uint32_t &device_update_flags,
1438  const AttributeSet &attributes)
1439 {
1440  if (attributes.modified(AttrKernelDataType::FLOAT)) {
1441  device_update_flags |= ATTR_FLOAT_NEEDS_REALLOC;
1442  }
1443  if (attributes.modified(AttrKernelDataType::FLOAT2)) {
1444  device_update_flags |= ATTR_FLOAT2_NEEDS_REALLOC;
1445  }
1446  if (attributes.modified(AttrKernelDataType::FLOAT3)) {
1447  device_update_flags |= ATTR_FLOAT3_NEEDS_REALLOC;
1448  }
1449  if (attributes.modified(AttrKernelDataType::FLOAT4)) {
1450  device_update_flags |= ATTR_FLOAT4_NEEDS_REALLOC;
1451  }
1452  if (attributes.modified(AttrKernelDataType::UCHAR4)) {
1453  device_update_flags |= ATTR_UCHAR4_NEEDS_REALLOC;
1454  }
1455 }
1456 
1458 {
1459  if (!need_update() && !need_flags_update) {
1460  return;
1461  }
1462 
1463  uint32_t device_update_flags = 0;
1464 
1465  scoped_callback_timer timer([scene](double time) {
1466  if (scene->update_stats) {
1467  scene->update_stats->geometry.times.add_entry({"device_update_preprocess", time});
1468  }
1469  });
1470 
1471  progress.set_status("Updating Meshes Flags");
1472 
1473  /* Update flags. */
1474  bool volume_images_updated = false;
1475 
1476  foreach (Geometry *geom, scene->geometry) {
1477  geom->has_volume = false;
1478 
1479  update_attribute_realloc_flags(device_update_flags, geom->attributes);
1480 
1481  if (geom->is_mesh()) {
1482  Mesh *mesh = static_cast<Mesh *>(geom);
1483  update_attribute_realloc_flags(device_update_flags, mesh->subd_attributes);
1484  }
1485 
1486  foreach (Node *node, geom->get_used_shaders()) {
1487  Shader *shader = static_cast<Shader *>(node);
1488  if (shader->has_volume) {
1489  geom->has_volume = true;
1490  }
1491 
1492  if (shader->has_surface_bssrdf) {
1493  geom->has_surface_bssrdf = true;
1494  }
1495 
1496  if (shader->need_update_uvs) {
1497  device_update_flags |= ATTR_FLOAT2_NEEDS_REALLOC;
1498 
1499  /* Attributes might need to be tessellated if added. */
1500  if (geom->is_mesh()) {
1501  Mesh *mesh = static_cast<Mesh *>(geom);
1502  if (mesh->need_tesselation()) {
1503  mesh->tag_modified();
1504  }
1505  }
1506  }
1507 
1508  if (shader->need_update_attribute) {
1509  device_update_flags |= ATTRS_NEED_REALLOC;
1510 
1511  /* Attributes might need to be tessellated if added. */
1512  if (geom->is_mesh()) {
1513  Mesh *mesh = static_cast<Mesh *>(geom);
1514  if (mesh->need_tesselation()) {
1515  mesh->tag_modified();
1516  }
1517  }
1518  }
1519 
1520  if (shader->need_update_displacement) {
1521  /* tag displacement related sockets as modified */
1522  if (geom->is_mesh()) {
1523  Mesh *mesh = static_cast<Mesh *>(geom);
1524  mesh->tag_verts_modified();
1525  mesh->tag_subd_dicing_rate_modified();
1526  mesh->tag_subd_max_level_modified();
1527  mesh->tag_subd_objecttoworld_modified();
1528 
1529  device_update_flags |= ATTRS_NEED_REALLOC;
1530  }
1531  }
1532  }
1533 
1534  /* only check for modified attributes if we do not need to reallocate them already */
1535  if ((device_update_flags & ATTRS_NEED_REALLOC) == 0) {
1536  update_device_flags_attribute(device_update_flags, geom->attributes);
1537  /* don't check for subd_attributes, as if they were modified, we would need to reallocate
1538  * anyway */
1539  }
1540 
1541  /* Re-create volume mesh if we will rebuild or refit the BVH. Note we
1542  * should only do it in that case, otherwise the BVH and mesh can go
1543  * out of sync. */
1544  if (geom->is_modified() && geom->geometry_type == Geometry::VOLUME) {
1545  /* Create volume meshes if there is voxel data. */
1546  if (!volume_images_updated) {
1547  progress.set_status("Updating Meshes Volume Bounds");
1548  device_update_volume_images(device, scene, progress);
1549  volume_images_updated = true;
1550  }
1551 
1552  Volume *volume = static_cast<Volume *>(geom);
1553  create_volume_mesh(scene, volume, progress);
1554 
1555  /* always reallocate when we have a volume, as we need to rebuild the BVH */
1556  device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;
1557  }
1558 
1559  if (geom->is_hair()) {
1560  /* Set curve shape, still a global scene setting for now. */
1561  Hair *hair = static_cast<Hair *>(geom);
1563 
1564  if (hair->need_update_rebuild) {
1565  device_update_flags |= DEVICE_CURVE_DATA_NEEDS_REALLOC;
1566  }
1567  else if (hair->is_modified()) {
1568  device_update_flags |= DEVICE_CURVE_DATA_MODIFIED;
1569  }
1570  }
1571 
1572  if (geom->is_mesh()) {
1573  Mesh *mesh = static_cast<Mesh *>(geom);
1574 
1575  if (mesh->need_update_rebuild) {
1576  device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;
1577  }
1578  else if (mesh->is_modified()) {
1579  device_update_flags |= DEVICE_MESH_DATA_MODIFIED;
1580  }
1581  }
1582 
1583  if (geom->is_pointcloud()) {
1584  PointCloud *pointcloud = static_cast<PointCloud *>(geom);
1585 
1586  if (pointcloud->need_update_rebuild) {
1587  device_update_flags |= DEVICE_POINT_DATA_NEEDS_REALLOC;
1588  }
1589  else if (pointcloud->is_modified()) {
1590  device_update_flags |= DEVICE_POINT_DATA_MODIFIED;
1591  }
1592  }
1593  }
1594 
1595  if (update_flags & (MESH_ADDED | MESH_REMOVED)) {
1596  device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;
1597  }
1598 
1599  if (update_flags & (HAIR_ADDED | HAIR_REMOVED)) {
1600  device_update_flags |= DEVICE_CURVE_DATA_NEEDS_REALLOC;
1601  }
1602 
1603  if (update_flags & (POINT_ADDED | POINT_REMOVED)) {
1604  device_update_flags |= DEVICE_POINT_DATA_NEEDS_REALLOC;
1605  }
1606 
1607  /* tag the device arrays for reallocation or modification */
1608  DeviceScene *dscene = &scene->dscene;
1609 
1612  delete scene->bvh;
1613  scene->bvh = nullptr;
1614 
1615  dscene->bvh_nodes.tag_realloc();
1616  dscene->bvh_leaf_nodes.tag_realloc();
1617  dscene->object_node.tag_realloc();
1618  dscene->prim_type.tag_realloc();
1619  dscene->prim_visibility.tag_realloc();
1620  dscene->prim_index.tag_realloc();
1621  dscene->prim_object.tag_realloc();
1622  dscene->prim_time.tag_realloc();
1623 
1624  if (device_update_flags & DEVICE_MESH_DATA_NEEDS_REALLOC) {
1625  dscene->tri_verts.tag_realloc();
1626  dscene->tri_vnormal.tag_realloc();
1627  dscene->tri_vindex.tag_realloc();
1628  dscene->tri_patch.tag_realloc();
1629  dscene->tri_patch_uv.tag_realloc();
1630  dscene->tri_shader.tag_realloc();
1631  dscene->patches.tag_realloc();
1632  }
1633 
1634  if (device_update_flags & DEVICE_CURVE_DATA_NEEDS_REALLOC) {
1635  dscene->curves.tag_realloc();
1636  dscene->curve_keys.tag_realloc();
1637  dscene->curve_segments.tag_realloc();
1638  }
1639 
1640  if (device_update_flags & DEVICE_POINT_DATA_NEEDS_REALLOC) {
1641  dscene->points.tag_realloc();
1642  dscene->points_shader.tag_realloc();
1643  }
1644  }
1645 
1646  if ((update_flags & VISIBILITY_MODIFIED) != 0) {
1647  dscene->prim_visibility.tag_modified();
1648  }
1649 
1650  if (device_update_flags & ATTR_FLOAT_NEEDS_REALLOC) {
1651  dscene->attributes_map.tag_realloc();
1652  dscene->attributes_float.tag_realloc();
1653  }
1654  else if (device_update_flags & ATTR_FLOAT_MODIFIED) {
1655  dscene->attributes_float.tag_modified();
1656  }
1657 
1658  if (device_update_flags & ATTR_FLOAT2_NEEDS_REALLOC) {
1659  dscene->attributes_map.tag_realloc();
1660  dscene->attributes_float2.tag_realloc();
1661  }
1662  else if (device_update_flags & ATTR_FLOAT2_MODIFIED) {
1663  dscene->attributes_float2.tag_modified();
1664  }
1665 
1666  if (device_update_flags & ATTR_FLOAT3_NEEDS_REALLOC) {
1667  dscene->attributes_map.tag_realloc();
1668  dscene->attributes_float3.tag_realloc();
1669  }
1670  else if (device_update_flags & ATTR_FLOAT3_MODIFIED) {
1671  dscene->attributes_float3.tag_modified();
1672  }
1673 
1674  if (device_update_flags & ATTR_FLOAT4_NEEDS_REALLOC) {
1675  dscene->attributes_map.tag_realloc();
1676  dscene->attributes_float4.tag_realloc();
1677  }
1678  else if (device_update_flags & ATTR_FLOAT4_MODIFIED) {
1679  dscene->attributes_float4.tag_modified();
1680  }
1681 
1682  if (device_update_flags & ATTR_UCHAR4_NEEDS_REALLOC) {
1683  dscene->attributes_map.tag_realloc();
1684  dscene->attributes_uchar4.tag_realloc();
1685  }
1686  else if (device_update_flags & ATTR_UCHAR4_MODIFIED) {
1687  dscene->attributes_uchar4.tag_modified();
1688  }
1689 
1690  if (device_update_flags & DEVICE_MESH_DATA_MODIFIED) {
1691  /* if anything else than vertices or shaders are modified, we would need to reallocate, so
1692  * these are the only arrays that can be updated */
1693  dscene->tri_verts.tag_modified();
1694  dscene->tri_vnormal.tag_modified();
1695  dscene->tri_shader.tag_modified();
1696  }
1697 
1698  if (device_update_flags & DEVICE_CURVE_DATA_MODIFIED) {
1699  dscene->curve_keys.tag_modified();
1700  dscene->curves.tag_modified();
1701  dscene->curve_segments.tag_modified();
1702  }
1703 
1704  if (device_update_flags & DEVICE_POINT_DATA_MODIFIED) {
1705  dscene->points.tag_modified();
1706  dscene->points_shader.tag_modified();
1707  }
1708 
1709  need_flags_update = false;
1710 }
1711 
1713  Scene *scene,
1714  Progress &progress)
1715 {
1716  progress.set_status("Updating Displacement Images");
1717  TaskPool pool;
1718  ImageManager *image_manager = scene->image_manager;
1719  set<int> bump_images;
1720  foreach (Geometry *geom, scene->geometry) {
1721  if (geom->is_modified()) {
1722  /* Geometry-level check for hair shadow transparency.
1723  * This matches the logic in the `Hair::update_shadow_transparency()`, avoiding access to
1724  * possible non-loaded images. */
1725  bool need_shadow_transparency = false;
1726  if (geom->geometry_type == Geometry::HAIR) {
1727  Hair *hair = static_cast<Hair *>(geom);
1728  need_shadow_transparency = hair->need_shadow_transparency();
1729  }
1730 
1731  foreach (Node *node, geom->get_used_shaders()) {
1732  Shader *shader = static_cast<Shader *>(node);
1733  const bool is_true_displacement = (shader->has_displacement &&
1734  shader->get_displacement_method() != DISPLACE_BUMP);
1735  if (!is_true_displacement && !need_shadow_transparency) {
1736  continue;
1737  }
1738  foreach (ShaderNode *node, shader->graph->nodes) {
1739  if (node->special_type != SHADER_SPECIAL_TYPE_IMAGE_SLOT) {
1740  continue;
1741  }
1742 
1743  ImageSlotTextureNode *image_node = static_cast<ImageSlotTextureNode *>(node);
1744  for (int i = 0; i < image_node->handle.num_tiles(); i++) {
1745  const int slot = image_node->handle.svm_slot(i);
1746  if (slot != -1) {
1747  bump_images.insert(slot);
1748  }
1749  }
1750  }
1751  }
1752  }
1753  }
1754  foreach (int slot, bump_images) {
1756  &ImageManager::device_update_slot, image_manager, device, scene, slot, &progress));
1757  }
1758  pool.wait_work();
1759 }
1760 
1762 {
1763  progress.set_status("Updating Volume Images");
1764  TaskPool pool;
1765  ImageManager *image_manager = scene->image_manager;
1766  set<int> volume_images;
1767 
1768  foreach (Geometry *geom, scene->geometry) {
1769  if (!geom->is_modified()) {
1770  continue;
1771  }
1772 
1773  foreach (Attribute &attr, geom->attributes.attributes) {
1774  if (attr.element != ATTR_ELEMENT_VOXEL) {
1775  continue;
1776  }
1777 
1778  ImageHandle &handle = attr.data_voxel();
1779  /* We can build directly from OpenVDB data structures, no need to
1780  * load such images early. */
1781  if (!handle.vdb_loader()) {
1782  const int slot = handle.svm_slot();
1783  if (slot != -1) {
1784  volume_images.insert(slot);
1785  }
1786  }
1787  }
1788  }
1789 
1790  foreach (int slot, volume_images) {
1792  &ImageManager::device_update_slot, image_manager, device, scene, slot, &progress));
1793  }
1794  pool.wait_work();
1795 }
1796 
1798  DeviceScene *dscene,
1799  Scene *scene,
1800  Progress &progress)
1801 {
1802  if (!need_update())
1803  return;
1804 
1805  VLOG_INFO << "Total " << scene->geometry.size() << " meshes.";
1806 
1807  bool true_displacement_used = false;
1808  bool curve_shadow_transparency_used = false;
1809  size_t total_tess_needed = 0;
1810 
1811  {
1812  scoped_callback_timer timer([scene](double time) {
1813  if (scene->update_stats) {
1814  scene->update_stats->geometry.times.add_entry({"device_update (normals)", time});
1815  }
1816  });
1817 
1818  foreach (Geometry *geom, scene->geometry) {
1819  if (geom->is_modified()) {
1820  if ((geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME)) {
1821  Mesh *mesh = static_cast<Mesh *>(geom);
1822 
1823  /* Update normals. */
1826 
1828  mesh->add_undisplaced();
1829  }
1830 
1831  /* Test if we need tessellation. */
1832  if (mesh->need_tesselation()) {
1833  total_tess_needed++;
1834  }
1835 
1836  /* Test if we need displacement. */
1837  if (mesh->has_true_displacement()) {
1838  true_displacement_used = true;
1839  }
1840  }
1841  else if (geom->geometry_type == Geometry::HAIR) {
1842  Hair *hair = static_cast<Hair *>(geom);
1843  if (hair->need_shadow_transparency()) {
1844  curve_shadow_transparency_used = true;
1845  }
1846  }
1847 
1848  if (progress.get_cancel()) {
1849  return;
1850  }
1851  }
1852  }
1853  }
1854 
1855  if (progress.get_cancel()) {
1856  return;
1857  }
1858 
1859  /* Tessellate meshes that are using subdivision */
1860  if (total_tess_needed) {
1861  scoped_callback_timer timer([scene](double time) {
1862  if (scene->update_stats) {
1863  scene->update_stats->geometry.times.add_entry(
1864  {"device_update (adaptive subdivision)", time});
1865  }
1866  });
1867 
1868  Camera *dicing_camera = scene->dicing_camera;
1869  dicing_camera->set_screen_size(dicing_camera->get_full_width(),
1870  dicing_camera->get_full_height());
1871  dicing_camera->update(scene);
1872 
1873  size_t i = 0;
1874  foreach (Geometry *geom, scene->geometry) {
1875  if (!(geom->is_modified() && geom->is_mesh())) {
1876  continue;
1877  }
1878 
1879  Mesh *mesh = static_cast<Mesh *>(geom);
1880  if (mesh->need_tesselation()) {
1881  string msg = "Tessellating ";
1882  if (mesh->name == "")
1883  msg += string_printf("%u/%u", (uint)(i + 1), (uint)total_tess_needed);
1884  else
1885  msg += string_printf(
1886  "%s %u/%u", mesh->name.c_str(), (uint)(i + 1), (uint)total_tess_needed);
1887 
1888  progress.set_status("Updating Mesh", msg);
1889 
1890  mesh->subd_params->camera = dicing_camera;
1891  DiagSplit dsplit(*mesh->subd_params);
1892  mesh->tessellate(&dsplit);
1893 
1894  i++;
1895 
1896  if (progress.get_cancel()) {
1897  return;
1898  }
1899  }
1900  }
1901 
1902  if (progress.get_cancel()) {
1903  return;
1904  }
1905  }
1906 
1907  /* Update images needed for true displacement. */
1908  bool old_need_object_flags_update = false;
1909  if (true_displacement_used || curve_shadow_transparency_used) {
1910  scoped_callback_timer timer([scene](double time) {
1911  if (scene->update_stats) {
1912  scene->update_stats->geometry.times.add_entry(
1913  {"device_update (displacement: load images)", time});
1914  }
1915  });
1916  device_update_displacement_images(device, scene, progress);
1917  old_need_object_flags_update = scene->object_manager->need_flags_update;
1918  scene->object_manager->device_update_flags(device, dscene, scene, progress, false);
1919  }
1920 
1921  /* Device update. */
1922  device_free(device, dscene, false);
1923 
1925  device->get_bvh_layout_mask());
1926  geom_calc_offset(scene, bvh_layout);
1927  if (true_displacement_used || curve_shadow_transparency_used) {
1928  scoped_callback_timer timer([scene](double time) {
1929  if (scene->update_stats) {
1930  scene->update_stats->geometry.times.add_entry(
1931  {"device_update (displacement: copy meshes to device)", time});
1932  }
1933  });
1934  device_update_mesh(device, dscene, scene, progress);
1935  }
1936  if (progress.get_cancel()) {
1937  return;
1938  }
1939 
1940  {
1941  scoped_callback_timer timer([scene](double time) {
1942  if (scene->update_stats) {
1943  scene->update_stats->geometry.times.add_entry({"device_update (attributes)", time});
1944  }
1945  });
1946  device_update_attributes(device, dscene, scene, progress);
1947  if (progress.get_cancel()) {
1948  return;
1949  }
1950  }
1951 
1952  /* Update displacement and hair shadow transparency. */
1953  bool displacement_done = false;
1954  bool curve_shadow_transparency_done = false;
1955  size_t num_bvh = 0;
1956 
1957  {
1958  /* Copy constant data needed by shader evaluation. */
1959  device->const_copy_to("data", &dscene->data, sizeof(dscene->data));
1960 
1961  scoped_callback_timer timer([scene](double time) {
1962  if (scene->update_stats) {
1963  scene->update_stats->geometry.times.add_entry({"device_update (displacement)", time});
1964  }
1965  });
1966 
1967  foreach (Geometry *geom, scene->geometry) {
1968  if (geom->is_modified()) {
1969  if (geom->is_mesh()) {
1970  Mesh *mesh = static_cast<Mesh *>(geom);
1971  if (displace(device, scene, mesh, progress)) {
1972  displacement_done = true;
1973  }
1974  }
1975  else if (geom->geometry_type == Geometry::HAIR) {
1976  Hair *hair = static_cast<Hair *>(geom);
1977  if (hair->update_shadow_transparency(device, scene, progress)) {
1978  curve_shadow_transparency_done = true;
1979  }
1980  }
1981  }
1982 
1983  if (geom->is_modified() || geom->need_update_bvh_for_offset) {
1984  if (geom->need_build_bvh(bvh_layout)) {
1985  num_bvh++;
1986  }
1987  }
1988 
1989  if (progress.get_cancel()) {
1990  return;
1991  }
1992  }
1993  }
1994 
1995  if (progress.get_cancel()) {
1996  return;
1997  }
1998 
1999  /* Device re-update after displacement. */
2000  if (displacement_done || curve_shadow_transparency_done) {
2001  scoped_callback_timer timer([scene](double time) {
2002  if (scene->update_stats) {
2003  scene->update_stats->geometry.times.add_entry(
2004  {"device_update (displacement: attributes)", time});
2005  }
2006  });
2007  device_free(device, dscene, false);
2008 
2009  device_update_attributes(device, dscene, scene, progress);
2010  if (progress.get_cancel()) {
2011  return;
2012  }
2013  }
2014 
2015  /* Update the BVH even when there is no geometry so the kernel's BVH data is still valid,
2016  * especially when removing all of the objects during interactive renders.
2017  * Also update the BVH if the transformations change, we cannot rely on tagging the Geometry
2018  * as modified in this case, as we may accumulate displacement if the vertices do not also
2019  * change. */
2020  bool need_update_scene_bvh = (scene->bvh == nullptr ||
2021  (update_flags & (TRANSFORM_MODIFIED | VISIBILITY_MODIFIED)) != 0);
2022  {
2023  scoped_callback_timer timer([scene](double time) {
2024  if (scene->update_stats) {
2025  scene->update_stats->geometry.times.add_entry({"device_update (build object BVHs)", time});
2026  }
2027  });
2028  TaskPool pool;
2029 
2030  size_t i = 0;
2031  foreach (Geometry *geom, scene->geometry) {
2032  if (geom->is_modified() || geom->need_update_bvh_for_offset) {
2033  need_update_scene_bvh = true;
2035  &Geometry::compute_bvh, geom, device, dscene, &scene->params, &progress, i, num_bvh));
2036  if (geom->need_build_bvh(bvh_layout)) {
2037  i++;
2038  }
2039  }
2040  }
2041 
2042  TaskPool::Summary summary;
2043  pool.wait_work(&summary);
2044  VLOG_WORK << "Objects BVH build pool statistics:\n" << summary.full_report();
2045  }
2046 
2047  foreach (Shader *shader, scene->shaders) {
2048  shader->need_update_uvs = false;
2049  shader->need_update_attribute = false;
2050  shader->need_update_displacement = false;
2051  }
2052 
2053  Scene::MotionType need_motion = scene->need_motion();
2054  bool motion_blur = need_motion == Scene::MOTION_BLUR;
2055 
2056  /* Update objects. */
2057  {
2058  scoped_callback_timer timer([scene](double time) {
2059  if (scene->update_stats) {
2060  scene->update_stats->geometry.times.add_entry({"device_update (compute bounds)", time});
2061  }
2062  });
2063  foreach (Object *object, scene->objects) {
2064  object->compute_bounds(motion_blur);
2065  }
2066  }
2067 
2068  if (progress.get_cancel()) {
2069  return;
2070  }
2071 
2072  if (need_update_scene_bvh) {
2073  scoped_callback_timer timer([scene](double time) {
2074  if (scene->update_stats) {
2075  scene->update_stats->geometry.times.add_entry({"device_update (build scene BVH)", time});
2076  }
2077  });
2078  device_update_bvh(device, dscene, scene, progress);
2079  if (progress.get_cancel()) {
2080  return;
2081  }
2082  }
2083 
2084  /* Always set BVH layout again after displacement where it was set to none,
2085  * to avoid ray-tracing at that stage. */
2086  dscene->data.bvh.bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout,
2087  device->get_bvh_layout_mask());
2088 
2089  {
2090  scoped_callback_timer timer([scene](double time) {
2091  if (scene->update_stats) {
2092  scene->update_stats->geometry.times.add_entry(
2093  {"device_update (copy meshes to device)", time});
2094  }
2095  });
2096  device_update_mesh(device, dscene, scene, progress);
2097  if (progress.get_cancel()) {
2098  return;
2099  }
2100  }
2101 
2102  if (true_displacement_used) {
2103  /* Re-tag flags for update, so they're re-evaluated
2104  * for meshes with correct bounding boxes.
2105  *
2106  * This wouldn't cause wrong results, just true
2107  * displacement might be less optimal to calculate.
2108  */
2109  scene->object_manager->need_flags_update = old_need_object_flags_update;
2110  }
2111 
2112  /* unset flags */
2113 
2114  foreach (Geometry *geom, scene->geometry) {
2115  geom->clear_modified();
2116  geom->attributes.clear_modified();
2117 
2118  if (geom->is_mesh()) {
2119  Mesh *mesh = static_cast<Mesh *>(geom);
2120  mesh->subd_attributes.clear_modified();
2121  }
2122  }
2123 
2124  update_flags = UPDATE_NONE;
2125 
2126  dscene->bvh_nodes.clear_modified();
2127  dscene->bvh_leaf_nodes.clear_modified();
2128  dscene->object_node.clear_modified();
2129  dscene->prim_type.clear_modified();
2130  dscene->prim_visibility.clear_modified();
2131  dscene->prim_index.clear_modified();
2132  dscene->prim_object.clear_modified();
2133  dscene->prim_time.clear_modified();
2134  dscene->tri_verts.clear_modified();
2135  dscene->tri_shader.clear_modified();
2136  dscene->tri_vindex.clear_modified();
2137  dscene->tri_patch.clear_modified();
2138  dscene->tri_vnormal.clear_modified();
2139  dscene->tri_patch_uv.clear_modified();
2140  dscene->curves.clear_modified();
2141  dscene->curve_keys.clear_modified();
2142  dscene->curve_segments.clear_modified();
2143  dscene->points.clear_modified();
2144  dscene->points_shader.clear_modified();
2145  dscene->patches.clear_modified();
2146  dscene->attributes_map.clear_modified();
2147  dscene->attributes_float.clear_modified();
2152 }
2153 
2154 void GeometryManager::device_free(Device *device, DeviceScene *dscene, bool force_free)
2155 {
2156  dscene->bvh_nodes.free_if_need_realloc(force_free);
2157  dscene->bvh_leaf_nodes.free_if_need_realloc(force_free);
2158  dscene->object_node.free_if_need_realloc(force_free);
2159  dscene->prim_type.free_if_need_realloc(force_free);
2160  dscene->prim_visibility.free_if_need_realloc(force_free);
2161  dscene->prim_index.free_if_need_realloc(force_free);
2162  dscene->prim_object.free_if_need_realloc(force_free);
2163  dscene->prim_time.free_if_need_realloc(force_free);
2164  dscene->tri_verts.free_if_need_realloc(force_free);
2165  dscene->tri_shader.free_if_need_realloc(force_free);
2166  dscene->tri_vnormal.free_if_need_realloc(force_free);
2167  dscene->tri_vindex.free_if_need_realloc(force_free);
2168  dscene->tri_patch.free_if_need_realloc(force_free);
2169  dscene->tri_patch_uv.free_if_need_realloc(force_free);
2170  dscene->curves.free_if_need_realloc(force_free);
2171  dscene->curve_keys.free_if_need_realloc(force_free);
2172  dscene->curve_segments.free_if_need_realloc(force_free);
2173  dscene->points.free_if_need_realloc(force_free);
2174  dscene->points_shader.free_if_need_realloc(force_free);
2175  dscene->patches.free_if_need_realloc(force_free);
2176  dscene->attributes_map.free_if_need_realloc(force_free);
2177  dscene->attributes_float.free_if_need_realloc(force_free);
2178  dscene->attributes_float2.free_if_need_realloc(force_free);
2179  dscene->attributes_float3.free_if_need_realloc(force_free);
2180  dscene->attributes_float4.free_if_need_realloc(force_free);
2181  dscene->attributes_uchar4.free_if_need_realloc(force_free);
2182 
2183  /* Signal for shaders like displacement not to do ray tracing. */
2184  dscene->data.bvh.bvh_layout = BVH_LAYOUT_NONE;
2185 
2186 #ifdef WITH_OSL
2187  OSLGlobals *og = (OSLGlobals *)device->get_cpu_osl_memory();
2188 
2189  if (og) {
2190  og->object_name_map.clear();
2191  og->attribute_map.clear();
2192  og->object_names.clear();
2193  }
2194 #else
2195  (void)device;
2196 #endif
2197 }
2198 
2200 {
2201  update_flags |= flag;
2202 
2203  /* do not tag the object manager for an update if it is the one who tagged us */
2204  if ((flag & OBJECT_MANAGER) == 0) {
2206  }
2207 }
2208 
2210 {
2211  return update_flags != UPDATE_NONE;
2212 }
2213 
2215 {
2216  foreach (Geometry *geometry, scene->geometry) {
2217  stats->mesh.geometry.add_entry(
2218  NamedSizeEntry(string(geometry->name.c_str()), geometry->get_total_size_in_bytes()));
2219  }
2220 }
2221 
unsigned int uint
Definition: BLI_sys_types.h:67
_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
float float4[4]
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to curves
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 or normal between and object coordinate space Combine Create a color from its and value channels Color Attribute
ATTR_WARN_UNUSED_RESULT const void * element
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
CCL_NAMESPACE_BEGIN const char * bvh_layout_name(BVHLayout layout)
Definition: bvh.cpp:20
vector< AttributeRequest > requests
bool find(ustring name)
void add(ustring name)
AttributeDescriptor subd_desc
AttributeDescriptor desc
AttributeStandard std
Attribute * add(ustring name, TypeDesc type, AttributeElement element)
list< Attribute > attributes
Attribute * find(ustring name) const
bool modified(AttrKernelDataType kernel_type) const
ImageHandle & data_voxel()
AttributeElement element
static AttrKernelDataType kernel_type(const Attribute &attr)
float * data_float()
uchar4 * data_uchar4()
Transform * data_transform()
TypeDesc type
size_t element_size(Geometry *geom, AttributePrimitive prim) const
float4 * data_float4()
vector< char > buffer
static const char * standard_name(AttributeStandard std)
float3 * data_float3()
float2 * data_float2()
Definition: bvh2.h:33
bool use_spatial_split
Definition: params.h:57
int num_motion_triangle_steps
Definition: params.h:97
static BVHLayout best_bvh_layout(BVHLayout requested_layout, BVHLayoutMask supported_layouts)
Definition: bvh.cpp:45
BVHLayout bvh_layout
Definition: params.h:80
bool use_compact_structure
Definition: params.h:88
bool use_unaligned_nodes
Definition: params.h:85
int curve_subdivisions
Definition: params.h:105
int num_motion_point_steps
Definition: params.h:99
bool top_level
Definition: params.h:77
int bvh_type
Definition: params.h:102
int num_motion_curve_steps
Definition: params.h:98
Definition: bvh/bvh.h:63
virtual void replace_geometry(const vector< Geometry * > &geometry, const vector< Object * > &objects)
Definition: bvh/bvh.h:77
static BVH * create(const BVHParams &params, const vector< Geometry * > &geometry, const vector< Object * > &objects, Device *device)
Definition: bvh.cpp:77
device_vector< uint > points_shader
Definition: scene.h:87
device_vector< float2 > prim_time
Definition: scene.h:69
device_vector< uint > patches
Definition: scene.h:83
device_vector< float4 > points
Definition: scene.h:86
device_vector< uint > prim_visibility
Definition: scene.h:66
device_vector< uint4 > tri_vindex
Definition: scene.h:75
device_vector< float4 > attributes_float4
Definition: scene.h:105
device_vector< KernelCurveSegment > curve_segments
Definition: scene.h:81
device_vector< float2 > attributes_float2
Definition: scene.h:103
device_vector< AttributeMap > attributes_map
Definition: scene.h:101
device_vector< KernelCurve > curves
Definition: scene.h:79
device_vector< int > object_node
Definition: scene.h:64
device_vector< packed_float3 > attributes_float3
Definition: scene.h:104
device_vector< int > prim_object
Definition: scene.h:68
device_vector< float4 > curve_keys
Definition: scene.h:80
device_vector< packed_float3 > tri_vnormal
Definition: scene.h:74
device_vector< int4 > bvh_leaf_nodes
Definition: scene.h:63
device_vector< uint > tri_shader
Definition: scene.h:73
device_vector< packed_float3 > tri_verts
Definition: scene.h:72
device_vector< float > attributes_float
Definition: scene.h:102
device_vector< float2 > tri_patch_uv
Definition: scene.h:77
device_vector< uint > tri_patch
Definition: scene.h:76
KernelData data
Definition: scene.h:130
device_vector< int > prim_type
Definition: scene.h:65
device_vector< int4 > bvh_nodes
Definition: scene.h:62
device_vector< int > prim_index
Definition: scene.h:67
device_vector< uchar4 > attributes_uchar4
Definition: scene.h:106
virtual BVHLayoutMask get_bvh_layout_mask() const =0
virtual void build_bvh(BVH *bvh, Progress &progress, bool refit)
virtual void * get_cpu_osl_memory()
void device_update_displacement_images(Device *device, Scene *scene, Progress &progress)
void update_osl_attributes(Device *device, Scene *scene, vector< AttributeRequestSet > &geom_attributes)
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
void geom_calc_offset(Scene *scene, BVHLayout bvh_layout)
void device_update_attributes(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
void device_free(Device *device, DeviceScene *dscene, bool force_free)
void tag_update(Scene *scene, uint32_t flag)
void device_update_bvh(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
void collect_statistics(const Scene *scene, RenderStats *stats)
void device_update_preprocess(Device *device, Scene *scene, Progress &progress)
void device_update_volume_images(Device *device, Scene *scene, Progress &progress)
void update_svm_attributes(Device *device, DeviceScene *dscene, Scene *scene, vector< AttributeRequestSet > &geom_attributes, vector< AttributeRequestSet > &object_attributes)
bool need_update() const
void device_update_mesh(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
Transform transform_normal
float motion_time(int step) const
Type geometry_type
virtual void compute_bounds()=0
BoundBox bounds
bool need_update_bvh_for_offset
bool transform_applied
bool has_volume
bool has_voxel_attributes() const
bool has_true_displacement() const
bool need_build_bvh(BVHLayout layout) const
size_t index
bool is_pointcloud() const
int motion_step(float time) const
bool need_attribute(Scene *scene, AttributeStandard std)
bool is_hair() const
bool has_surface_bssrdf
bool is_instanced() const
AttributeRequestSet needed_attributes()
size_t attr_map_offset
size_t prim_offset
bool has_motion_blur() const
void tag_update(Scene *scene, bool rebuild)
bool need_update_rebuild
AttributeSet attributes
bool is_mesh() const
virtual ~Geometry()
Geometry(const NodeType *node_type, const Type type)
bool transform_negative_scaled
void compute_bvh(Device *device, DeviceScene *dscene, SceneParams *params, Progress *progress, size_t n, size_t total)
void tag_bvh_update(bool rebuild)
virtual void clear(bool preserve_shaders=false)
Definition: hair.h:13
bool need_shadow_transparency()
Definition: hair.cpp:554
size_t curve_key_offset
Definition: hair.h:87
size_t curve_segment_offset
Definition: hair.h:88
size_t num_curves() const
Definition: hair.h:123
bool update_shadow_transparency(Device *device, Scene *scene, Progress &progress)
Definition: hair.cpp:566
void pack_curves(Scene *scene, float4 *curve_key_co, KernelCurve *curve, KernelCurveSegment *curve_segments)
Definition: hair.cpp:459
size_t num_segments() const
Definition: hair.h:128
CurveShapeType curve_shape
Definition: hair.h:89
int num_tiles() const
VDBImageLoader * vdb_loader(const int tile_index=0) const
int svm_slot(const int tile_index=0) const
void device_update_slot(Device *device, Scene *scene, int slot, Progress *progress)
ImageHandle handle
Definition: shader_nodes.h:87
@ EMISSIVE_MESH_MODIFIED
Definition: scene/light.h:88
void tag_update(Scene *scene, uint32_t flag)
NamedSizeStats geometry
Definition: scene/stats.h:149
void add_entry(const NamedSizeEntry &entry)
Definition: stats.cpp:65
void tag_update(Scene *scene, uint32_t flag)
void device_update_geom_offsets(Device *device, DeviceScene *dscene, Scene *scene)
bool need_flags_update
Definition: scene/object.h:144
void device_update_flags(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress, bool bounds_valid=true)
bool get_cancel() const
Definition: progress.h:90
void set_status(const string &status_, const string &substatus_="")
Definition: progress.h:248
BVHLayout bvh_layout
Definition: scene.h:146
bool use_bvh_unaligned_nodes
Definition: scene.h:151
bool use_bvh_spatial_split
Definition: scene.h:149
int curve_subdivisions()
Definition: scene.h:186
CurveShapeType hair_shape
Definition: scene.h:154
int num_bvh_time_steps
Definition: scene.h:152
BVHType bvh_type
Definition: scene.h:148
list< ShaderNode * > nodes
Definition: shader_graph.h:299
uint get_attribute_id(ustring name)
virtual bool use_osl()
Definition: scene/shader.h:178
bool has_surface_bssrdf
Definition: scene/shader.h:109
bool need_update_attribute
Definition: scene/shader.h:90
bool has_volume
Definition: scene/shader.h:107
NODE_DECLARE ShaderGraph * graph
Definition: scene/shader.h:71
bool need_update_displacement
Definition: scene/shader.h:91
bool has_surface_emission
Definition: scene/shader.h:104
bool need_update_uvs
Definition: scene/shader.h:89
bool has_displacement
Definition: scene/shader.h:108
AttributeRequestSet attributes
Definition: scene/shader.h:118
size_t size() const
T * alloc(size_t width, size_t height=0, size_t depth=0)
size_t size() const
void copy_to_device_if_modified()
void steal_data(array< T > &from)
void free_if_need_realloc(bool force_free)
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
OperationNode * node
double time
Scene scene
#define function_bind
SyclQueue void void size_t num_bytes void
#define MEM_GUARDED_CALL(progress, func,...)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
ccl_device_inline Transform transform_identity()
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
@ NODE_ATTR_FLOAT
@ NODE_ATTR_FLOAT3
@ NODE_ATTR_RGBA
@ NODE_ATTR_FLOAT2
@ NODE_ATTR_FLOAT4
@ NODE_ATTR_MATRIX
AttributeStandard
Definition: kernel/types.h:612
@ ATTR_STD_NONE
Definition: kernel/types.h:613
@ ATTR_STD_POSITION_UNDISPLACED
Definition: kernel/types.h:623
@ ATTR_STD_MOTION_VERTEX_POSITION
Definition: kernel/types.h:624
@ ATTR_STD_SHADOW_TRANSPARENCY
Definition: kernel/types.h:644
@ ATTR_SUBDIVIDED
Definition: kernel/types.h:652
@ BVH_LAYOUT_OPTIX
@ BVH_LAYOUT_NONE
@ BVH_LAYOUT_METAL
@ BVH_LAYOUT_MULTI_OPTIX
@ BVH_LAYOUT_BVH2
@ BVH_LAYOUT_MULTI_METAL
@ BVH_LAYOUT_MULTI_METAL_EMBREE
@ BVH_LAYOUT_MULTI_OPTIX_EMBREE
AttributeElement
Definition: kernel/types.h:597
@ ATTR_ELEMENT_NONE
Definition: kernel/types.h:598
@ ATTR_ELEMENT_CORNER_BYTE
Definition: kernel/types.h:605
@ ATTR_ELEMENT_CURVE_KEY
Definition: kernel/types.h:607
@ ATTR_ELEMENT_CURVE_KEY_MOTION
Definition: kernel/types.h:608
@ ATTR_ELEMENT_VOXEL
Definition: kernel/types.h:609
@ ATTR_ELEMENT_CORNER
Definition: kernel/types.h:604
@ ATTR_ELEMENT_OBJECT
Definition: kernel/types.h:599
@ ATTR_ELEMENT_VERTEX_MOTION
Definition: kernel/types.h:603
@ ATTR_ELEMENT_VERTEX
Definition: kernel/types.h:602
@ ATTR_ELEMENT_FACE
Definition: kernel/types.h:601
@ ATTR_ELEMENT_CURVE
Definition: kernel/types.h:606
AttributePrimitive
Definition: kernel/types.h:590
@ ATTR_PRIM_SUBD
Definition: kernel/types.h:592
@ ATTR_PRIM_TYPES
Definition: kernel/types.h:594
@ ATTR_PRIM_GEOMETRY
Definition: kernel/types.h:591
#define VLOG_INFO
Definition: log.h:77
#define VLOG_WORK
Definition: log.h:80
static void vnormal(PROCESS *process, const float point[3], float r_no[3])
#define SOCKET_NODE_ARRAY(name, ui_name, node_type,...)
Definition: node_type.h:268
#define SOCKET_UINT(name, ui_name, default_value,...)
Definition: node_type.h:189
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
Definition: node_type.h:185
static constexpr TypeDesc TypeRGBA(TypeDesc::FLOAT, TypeDesc::VEC4, TypeDesc::COLOR)
CCL_NAMESPACE_BEGIN static constexpr OIIO_NAMESPACE_USING TypeDesc TypeFloat2(TypeDesc::FLOAT, TypeDesc::VEC2)
CCL_NAMESPACE_BEGIN typedef KernelBVHLayout BVHLayout
Definition: params.h:19
AttrKernelDataType
@ FLOAT4
@ NUM
@ FLOAT2
@ UCHAR4
@ FLOAT3
@ FLOAT
static void emit_attribute_map_terminator(AttributeMap *attr_map, int index, bool chain, uint chain_link)
static void update_device_flags_attribute(uint32_t &device_update_flags, const AttributeSet &attributes)
static void emit_attribute_mapping(AttributeMap *attr_map, int index, Scene *scene, AttributeRequest &req, Geometry *geom)
static void emit_attribute_map_entry(AttributeMap *attr_map, int index, uint id, TypeDesc type, const AttributeDescriptor &desc)
static void update_attribute_element_size(Geometry *geom, Attribute *mattr, AttributePrimitive prim, size_t *attr_float_size, size_t *attr_float2_size, size_t *attr_float3_size, size_t *attr_float4_size, size_t *attr_uchar4_size)
@ ATTR_FLOAT4_MODIFIED
@ ATTR_UCHAR4_MODIFIED
@ MESH_DATA_NEED_REALLOC
@ DEVICE_MESH_DATA_NEEDS_REALLOC
@ ATTR_FLOAT3_MODIFIED
@ DEVICE_POINT_DATA_MODIFIED
@ DEVICE_POINT_DATA_NEEDS_REALLOC
@ ATTR_FLOAT4_NEEDS_REALLOC
@ ATTR_UCHAR4_NEEDS_REALLOC
@ ATTR_FLOAT_MODIFIED
@ ATTR_FLOAT2_NEEDS_REALLOC
@ DEVICE_MESH_DATA_MODIFIED
@ DEVICE_CURVE_DATA_MODIFIED
@ ATTR_FLOAT2_MODIFIED
@ ATTR_FLOAT_NEEDS_REALLOC
@ CURVE_DATA_NEED_REALLOC
@ POINT_DATA_NEED_REALLOC
@ DEVICE_CURVE_DATA_NEEDS_REALLOC
@ ATTR_FLOAT3_NEEDS_REALLOC
@ ATTRS_NEED_REALLOC
static void update_attribute_realloc_flags(uint32_t &device_update_flags, const AttributeSet &attributes)
CCL_NAMESPACE_BEGIN NODE_ABSTRACT_DEFINE(Geometry)
@ DISPLACE_BUMP
Definition: scene/shader.h:53
@ SHADER_SPECIAL_TYPE_IMAGE_SLOT
Definition: shader_graph.h:52
unsigned int uint32_t
Definition: stdint.h:80
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
Definition: string.cpp:22
AttributeElement element
Definition: kernel/types.h:656
NodeAttributeType type
Definition: kernel/types.h:657
uint8_t flags
Definition: kernel/types.h:668
uint8_t type
Definition: kernel/types.h:667
@ empty
Definition: boundbox.h:35
void set_screen_size(int width_, int height_)
void update(Scene *scene)
int num_ptex_faces() const
Definition: scene/mesh.h:97
void tessellate(DiagSplit *split)
void pack_verts(packed_float3 *tri_verts, uint4 *tri_vindex, uint *tri_patch, float2 *tri_patch_uv)
Definition: scene/mesh.cpp:737
size_t get_num_subd_faces() const
Definition: scene/mesh.h:232
void add_undisplaced()
Definition: scene/mesh.cpp:657
float size[3]
void add_vertex_normals()
Definition: scene/mesh.cpp:566
void pack_patches(uint *patch_data)
Definition: scene/mesh.cpp:767
bool need_tesselation()
Definition: scene/mesh.cpp:169
@ SUBDIVISION_CATMULL_CLARK
Definition: scene/mesh.h:122
size_t num_triangles() const
Definition: scene/mesh.h:79
void pack_normals(packed_float3 *vnormal)
Definition: scene/mesh.cpp:713
SubdFace get_subd_face(size_t index) const
Definition: scene/mesh.cpp:390
void pack_shaders(Scene *scene, uint *shader)
Definition: scene/mesh.cpp:686
void add_face_normals()
Definition: scene/mesh.cpp:536
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=NULL)
void dereference_all_used_nodes()
Definition: graph/node.cpp:779
ustring name
Definition: graph/node.h:174
size_t get_total_size_in_bytes() const
Definition: graph/node.cpp:695
void clear_modified()
Definition: graph/node.cpp:814
void tag_modified()
Definition: graph/node.cpp:809
bool is_modified() const
Definition: graph/node.cpp:804
size_t attr_map_offset
Definition: scene/object.h:115
vector< ParamValue > attributes
Definition: scene/object.h:49
array< int > prim_index
Definition: bvh/bvh.h:46
array< int > prim_type
Definition: bvh/bvh.h:41
array< int4 > nodes
Definition: bvh/bvh.h:35
array< uint > prim_visibility
Definition: bvh/bvh.h:43
array< float2 > prim_time
Definition: bvh/bvh.h:50
array< int4 > leaf_nodes
Definition: bvh/bvh.h:37
array< int > prim_object
Definition: bvh/bvh.h:48
int root_index
Definition: bvh/bvh.h:53
array< int > object_node
Definition: bvh/bvh.h:39
void copy_adjusting_offsets(uint *dest, int doffset)
void pack(Scene *scene, float4 *packed_points, uint *packed_shader)
size_t num_points() const
MeshStats mesh
Definition: scene/stats.h:176
BVH * bvh
Definition: scene.h:204
bool need_global_attribute(AttributeStandard std)
Definition: scene.cpp:405
vector< Geometry * > geometry
Definition: scene.h:214
MotionType need_motion() const
Definition: scene.cpp:387
void need_global_attributes(AttributeRequestSet &attributes)
Definition: scene.cpp:421
vector< Shader * > shaders
Definition: scene.h:215
Camera * dicing_camera
Definition: scene.h:206
SceneParams params
Definition: scene.h:243
ImageManager * image_manager
Definition: scene.h:222
vector< Object * > objects
Definition: scene.h:213
ObjectManager * object_manager
Definition: scene.h:226
MotionType
Definition: scene.h:259
@ MOTION_BLUR
Definition: scene.h:259
ShaderManager * shader_manager
Definition: scene.h:224
LightManager * light_manager
Definition: scene.h:223
SceneUpdateStats * update_stats
Definition: scene.h:249
GeometryManager * geometry_manager
Definition: scene.h:225
DeviceScene dscene
Definition: scene.h:240
Camera * camera
Definition: dice.h:31
string full_report() const
Definition: task.cpp:231
void push(TaskRunFunction &&task)
Definition: task.cpp:23
void wait_work(Summary *stats=NULL)
Definition: task.cpp:29
ccl_device_inline uint as_uint(int i)
Definition: util/math.h:222