Blender  V3.3
scene.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #include <stdlib.h>
5 
6 #include "bvh/bvh.h"
7 #include "device/device.h"
8 #include "scene/alembic.h"
9 #include "scene/background.h"
10 #include "scene/bake.h"
11 #include "scene/camera.h"
12 #include "scene/curves.h"
13 #include "scene/film.h"
14 #include "scene/integrator.h"
15 #include "scene/light.h"
16 #include "scene/mesh.h"
17 #include "scene/object.h"
18 #include "scene/osl.h"
19 #include "scene/particles.h"
20 #include "scene/pointcloud.h"
21 #include "scene/procedural.h"
22 #include "scene/scene.h"
23 #include "scene/shader.h"
24 #include "scene/svm.h"
25 #include "scene/tables.h"
26 #include "scene/volume.h"
27 #include "session/session.h"
28 
29 #include "util/foreach.h"
30 #include "util/guarded_allocator.h"
31 #include "util/log.h"
32 #include "util/progress.h"
33 
35 
37  : bvh_nodes(device, "bvh_nodes", MEM_GLOBAL),
38  bvh_leaf_nodes(device, "bvh_leaf_nodes", MEM_GLOBAL),
39  object_node(device, "object_node", MEM_GLOBAL),
40  prim_type(device, "prim_type", MEM_GLOBAL),
41  prim_visibility(device, "prim_visibility", MEM_GLOBAL),
42  prim_index(device, "prim_index", MEM_GLOBAL),
43  prim_object(device, "prim_object", MEM_GLOBAL),
44  prim_time(device, "prim_time", MEM_GLOBAL),
45  tri_verts(device, "tri_verts", MEM_GLOBAL),
46  tri_shader(device, "tri_shader", MEM_GLOBAL),
47  tri_vnormal(device, "tri_vnormal", MEM_GLOBAL),
48  tri_vindex(device, "tri_vindex", MEM_GLOBAL),
49  tri_patch(device, "tri_patch", MEM_GLOBAL),
50  tri_patch_uv(device, "tri_patch_uv", MEM_GLOBAL),
51  curves(device, "curves", MEM_GLOBAL),
52  curve_keys(device, "curve_keys", MEM_GLOBAL),
53  curve_segments(device, "curve_segments", MEM_GLOBAL),
54  patches(device, "patches", MEM_GLOBAL),
55  points(device, "points", MEM_GLOBAL),
56  points_shader(device, "points_shader", MEM_GLOBAL),
57  objects(device, "objects", MEM_GLOBAL),
58  object_motion_pass(device, "object_motion_pass", MEM_GLOBAL),
59  object_motion(device, "object_motion", MEM_GLOBAL),
60  object_flag(device, "object_flag", MEM_GLOBAL),
61  object_volume_step(device, "object_volume_step", MEM_GLOBAL),
62  object_prim_offset(device, "object_prim_offset", MEM_GLOBAL),
63  camera_motion(device, "camera_motion", MEM_GLOBAL),
64  attributes_map(device, "attributes_map", MEM_GLOBAL),
65  attributes_float(device, "attributes_float", MEM_GLOBAL),
66  attributes_float2(device, "attributes_float2", MEM_GLOBAL),
67  attributes_float3(device, "attributes_float3", MEM_GLOBAL),
68  attributes_float4(device, "attributes_float4", MEM_GLOBAL),
69  attributes_uchar4(device, "attributes_uchar4", MEM_GLOBAL),
70  light_distribution(device, "light_distribution", MEM_GLOBAL),
71  lights(device, "lights", MEM_GLOBAL),
72  light_background_marginal_cdf(device, "light_background_marginal_cdf", MEM_GLOBAL),
73  light_background_conditional_cdf(device, "light_background_conditional_cdf", MEM_GLOBAL),
74  particles(device, "particles", MEM_GLOBAL),
75  svm_nodes(device, "svm_nodes", MEM_GLOBAL),
76  shaders(device, "shaders", MEM_GLOBAL),
77  lookup_table(device, "lookup_table", MEM_GLOBAL),
78  sample_pattern_lut(device, "sample_pattern_lut", MEM_GLOBAL),
79  ies_lights(device, "ies", MEM_GLOBAL)
80 {
81  memset((void *)&data, 0, sizeof(data));
82 }
83 
84 Scene::Scene(const SceneParams &params_, Device *device)
85  : name("Scene"),
86  bvh(NULL),
87  default_surface(NULL),
88  default_volume(NULL),
89  default_light(NULL),
90  default_background(NULL),
91  default_empty(NULL),
92  device(device),
93  dscene(device),
94  params(params_),
95  update_stats(NULL),
96  kernels_loaded(false),
97  /* TODO(sergey): Check if it's indeed optimal value for the split kernel. */
98  max_closure_global(1)
99 {
100  memset((void *)&dscene.data, 0, sizeof(dscene.data));
101 
102  /* OSL only works on the CPU */
103  if (device->info.has_osl)
105  else
107 
108  light_manager = new LightManager();
113  bake_manager = new BakeManager();
115 
116  /* Create nodes after managers, since create_node() can tag the managers. */
117  camera = create_node<Camera>();
118  dicing_camera = create_node<Camera>();
119  lookup_tables = new LookupTables();
120  film = create_node<Film>();
121  background = create_node<Background>();
122  integrator = create_node<Integrator>();
123 
124  film->add_default(this);
126 }
127 
129 {
130  free_memory(true);
131 }
132 
133 void Scene::free_memory(bool final)
134 {
135  delete bvh;
136  bvh = NULL;
137 
138  /* The order of deletion is important to make sure data is freed based on possible dependencies
139  * as the Nodes' reference counts are decremented in the destructors:
140  *
141  * - Procedurals can create and hold pointers to any other types.
142  * - Objects can hold pointers to Geometries and ParticleSystems
143  * - Lights and Geometries can hold pointers to Shaders.
144  *
145  * Similarly, we first delete all nodes and their associated device data, and then the managers
146  * and their associated device data.
147  */
148  foreach (Procedural *p, procedurals)
149  delete p;
150  foreach (Object *o, objects)
151  delete o;
152  foreach (Geometry *g, geometry)
153  delete g;
154  foreach (ParticleSystem *p, particle_systems)
155  delete p;
156  foreach (Light *l, lights)
157  delete l;
158  foreach (Pass *p, passes)
159  delete p;
160 
161  geometry.clear();
162  objects.clear();
163  lights.clear();
164  particle_systems.clear();
165  procedurals.clear();
166  passes.clear();
167 
168  if (device) {
169  camera->device_free(device, &dscene, this);
170  film->device_free(device, &dscene, this);
173  }
174 
175  if (final) {
176  delete camera;
177  delete dicing_camera;
178  delete film;
179  delete background;
180  delete integrator;
181  }
182 
183  /* Delete Shaders after every other nodes to ensure that we do not try to decrement the reference
184  * count on some dangling pointer. */
185  foreach (Shader *s, shaders)
186  delete s;
187 
188  shaders.clear();
189 
190  /* Now that all nodes have been deleted, we can safely delete managers and device data. */
191  if (device) {
196 
198 
200 
201  if (final)
203  else
205 
207  }
208 
209  if (final) {
210  delete lookup_tables;
211  delete object_manager;
212  delete geometry_manager;
213  delete shader_manager;
214  delete light_manager;
216  delete image_manager;
217  delete bake_manager;
218  delete update_stats;
219  delete procedural_manager;
220  }
221 }
222 
223 void Scene::device_update(Device *device_, Progress &progress)
224 {
225  if (!device)
226  device = device_;
227 
228  bool print_stats = need_data_update();
229 
230  if (update_stats) {
231  update_stats->clear();
232  }
233 
234  scoped_callback_timer timer([this, print_stats](double time) {
235  if (update_stats) {
236  update_stats->scene.times.add_entry({"device_update", time});
237 
238  if (print_stats) {
239  printf("Update statistics:\n%s\n", update_stats->full_report().c_str());
240  }
241  }
242  });
243 
244  /* The order of updates is important, because there's dependencies between
245  * the different managers, using data computed by previous managers.
246  *
247  * - Image manager uploads images used by shaders.
248  * - Camera may be used for adaptive subdivision.
249  * - Displacement shader must have all shader data available.
250  * - Light manager needs lookup tables and final mesh data to compute emission CDF.
251  * - Lookup tables are done a second time to handle film tables
252  */
253 
254  if (film->update_lightgroups(this)) {
255  light_manager->tag_update(this, ccl::LightManager::LIGHT_MODIFIED);
256  object_manager->tag_update(this, ccl::ObjectManager::OBJECT_MODIFIED);
258  }
259 
260  progress.set_status("Updating Shaders");
261  shader_manager->device_update(device, &dscene, this, progress);
262 
263  if (progress.get_cancel() || device->have_error())
264  return;
265 
266  procedural_manager->update(this, progress);
267 
268  if (progress.get_cancel())
269  return;
270 
271  progress.set_status("Updating Background");
273 
274  if (progress.get_cancel() || device->have_error())
275  return;
276 
277  progress.set_status("Updating Camera");
278  camera->device_update(device, &dscene, this);
279 
280  if (progress.get_cancel() || device->have_error())
281  return;
282 
284 
285  if (progress.get_cancel() || device->have_error())
286  return;
287 
288  progress.set_status("Updating Objects");
289  object_manager->device_update(device, &dscene, this, progress);
290 
291  if (progress.get_cancel() || device->have_error())
292  return;
293 
294  progress.set_status("Updating Particle Systems");
296 
297  if (progress.get_cancel() || device->have_error())
298  return;
299 
300  progress.set_status("Updating Meshes");
301  geometry_manager->device_update(device, &dscene, this, progress);
302 
303  if (progress.get_cancel() || device->have_error())
304  return;
305 
306  progress.set_status("Updating Objects Flags");
307  object_manager->device_update_flags(device, &dscene, this, progress);
308 
309  if (progress.get_cancel() || device->have_error())
310  return;
311 
312  progress.set_status("Updating Primitive Offsets");
314 
315  if (progress.get_cancel() || device->have_error())
316  return;
317 
318  progress.set_status("Updating Images");
319  image_manager->device_update(device, this, progress);
320 
321  if (progress.get_cancel() || device->have_error())
322  return;
323 
324  progress.set_status("Updating Camera Volume");
325  camera->device_update_volume(device, &dscene, this);
326 
327  if (progress.get_cancel() || device->have_error())
328  return;
329 
330  progress.set_status("Updating Lookup Tables");
332 
333  if (progress.get_cancel() || device->have_error())
334  return;
335 
336  progress.set_status("Updating Lights");
337  light_manager->device_update(device, &dscene, this, progress);
338 
339  if (progress.get_cancel() || device->have_error())
340  return;
341 
342  progress.set_status("Updating Integrator");
344 
345  if (progress.get_cancel() || device->have_error())
346  return;
347 
348  progress.set_status("Updating Film");
349  film->device_update(device, &dscene, this);
350 
351  if (progress.get_cancel() || device->have_error())
352  return;
353 
354  progress.set_status("Updating Lookup Tables");
356 
357  if (progress.get_cancel() || device->have_error())
358  return;
359 
360  progress.set_status("Updating Baking");
361  bake_manager->device_update(device, &dscene, this, progress);
362 
363  if (progress.get_cancel() || device->have_error())
364  return;
365 
366  if (device->have_error() == false) {
368 
369  progress.set_status("Updating Device", "Writing constant memory");
370  device->const_copy_to("data", &dscene.data, sizeof(dscene.data));
371  }
372 
373  device->optimize_for_scene(this);
374 
375  if (print_stats) {
376  size_t mem_used = util_guarded_get_mem_used();
377  size_t mem_peak = util_guarded_get_mem_peak();
378 
379  VLOG_INFO << "System memory statistics after full device sync:\n"
380  << " Usage: " << string_human_readable_number(mem_used) << " ("
381  << string_human_readable_size(mem_used) << ")\n"
382  << " Peak: " << string_human_readable_number(mem_peak) << " ("
383  << string_human_readable_size(mem_peak) << ")";
384  }
385 }
386 
388 {
389  if (integrator->get_motion_blur())
390  return MOTION_BLUR;
391  else if (Pass::contains(passes, PASS_MOTION))
392  return MOTION_PASS;
393  else
394  return MOTION_NONE;
395 }
396 
398 {
400  return 2.0f;
401  else
402  return camera->get_shuttertime();
403 }
404 
406 {
407  if (std == ATTR_STD_UV)
408  return Pass::contains(passes, PASS_UV);
410  return need_motion() != MOTION_NONE;
412  return need_motion() == MOTION_BLUR;
415  return need_motion() != MOTION_NONE;
416  }
417 
418  return false;
419 }
420 
422 {
423  for (int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++)
425  attributes.add((AttributeStandard)std);
426 }
427 
429 {
430  return (need_reset() || film->is_modified());
431 }
432 
434 {
435  return (background->is_modified() || image_manager->need_update() ||
441 }
442 
444 {
445  return need_data_update() || camera->is_modified();
446 }
447 
449 {
450  shader_manager->reset(this);
452 
453  /* ensure all objects are updated */
454  camera->tag_modified();
456  film->tag_modified();
458 
459  background->tag_update(this);
466 }
467 
469 {
470  free_memory(false);
471 }
472 
474 {
475  geometry_manager->collect_statistics(this, stats);
477 }
478 
480 {
481  if (!update_stats) {
483  }
484 }
485 
487 {
488  if (!need_update()) {
489  return;
490  }
491 
492  /* These features are not being tweaked as often as shaders,
493  * so could be done selective magic for the viewport as well. */
494  uint kernel_features = shader_manager->get_kernel_features(this);
495 
496  bool use_motion = need_motion() == Scene::MotionType::MOTION_BLUR;
497  kernel_features |= KERNEL_FEATURE_PATH_TRACING;
498  if (params.hair_shape == CURVE_THICK) {
499  kernel_features |= KERNEL_FEATURE_HAIR_THICK;
500  }
501  if (use_motion && camera->use_motion()) {
502  kernel_features |= KERNEL_FEATURE_CAMERA_MOTION;
503  }
504 
505  /* Figure out whether the scene will use shader ray-trace we need at least
506  * one caustic light, one caustic caster and one caustic receiver to use
507  * and enable the MNEE code path. */
508  bool has_caustics_receiver = false;
509  bool has_caustics_caster = false;
510  bool has_caustics_light = false;
511 
512  foreach (Object *object, objects) {
513  if (object->get_is_caustics_caster()) {
514  has_caustics_caster = true;
515  }
516  else if (object->get_is_caustics_receiver()) {
517  has_caustics_receiver = true;
518  }
519  Geometry *geom = object->get_geometry();
520  if (use_motion) {
521  if (object->use_motion() || geom->get_use_motion_blur()) {
522  kernel_features |= KERNEL_FEATURE_OBJECT_MOTION;
523  }
524  if (geom->get_use_motion_blur()) {
525  kernel_features |= KERNEL_FEATURE_CAMERA_MOTION;
526  }
527  }
528  if (object->get_is_shadow_catcher()) {
529  kernel_features |= KERNEL_FEATURE_SHADOW_CATCHER;
530  }
531  if (geom->is_mesh()) {
532 #ifdef WITH_OPENSUBDIV
533  Mesh *mesh = static_cast<Mesh *>(geom);
534  if (mesh->get_subdivision_type() != Mesh::SUBDIVISION_NONE) {
535  kernel_features |= KERNEL_FEATURE_PATCH_EVALUATION;
536  }
537 #endif
538  }
539  else if (geom->is_hair()) {
540  kernel_features |= KERNEL_FEATURE_HAIR;
541  }
542  else if (geom->is_pointcloud()) {
543  kernel_features |= KERNEL_FEATURE_POINTCLOUD;
544  }
545  }
546 
547  foreach (Light *light, lights) {
548  if (light->get_use_caustics()) {
549  has_caustics_light = true;
550  }
551  }
552 
553  dscene.data.integrator.use_caustics = false;
554  if (has_caustics_caster && has_caustics_receiver && has_caustics_light) {
555  dscene.data.integrator.use_caustics = true;
556  kernel_features |= KERNEL_FEATURE_MNEE;
557  }
558 
559  if (bake_manager->get_baking()) {
560  kernel_features |= KERNEL_FEATURE_BAKING;
561  }
562 
563  kernel_features |= film->get_kernel_features(this);
564  kernel_features |= integrator->get_kernel_features();
565 
566  dscene.data.kernel_features = kernel_features;
567 
568  /* Currently viewport render is faster with higher max_closures, needs investigating. */
569  const uint max_closures = (params.background) ? get_max_closure_count() : MAX_CLOSURE;
570  dscene.data.max_closures = max_closures;
571  dscene.data.max_shaders = shaders.size();
572 }
573 
574 bool Scene::update(Progress &progress)
575 {
576  if (!need_update()) {
577  return false;
578  }
579 
580  /* Load render kernels, before device update where we upload data to the GPU. */
581  load_kernels(progress, false);
582 
583  /* Upload scene data to the GPU. */
584  progress.set_status("Updating Scene");
585  MEM_GUARDED_CALL(&progress, device_update, device, progress);
586 
587  return true;
588 }
589 
590 static void log_kernel_features(const uint features)
591 {
592  VLOG_INFO << "Requested features:\n";
593  VLOG_INFO << "Use BSDF " << string_from_bool(features & KERNEL_FEATURE_NODE_BSDF) << "\n";
594  VLOG_INFO << "Use Principled BSDF " << string_from_bool(features & KERNEL_FEATURE_PRINCIPLED)
595  << "\n";
596  VLOG_INFO << "Use Emission " << string_from_bool(features & KERNEL_FEATURE_NODE_EMISSION)
597  << "\n";
598  VLOG_INFO << "Use Volume " << string_from_bool(features & KERNEL_FEATURE_NODE_VOLUME) << "\n";
599  VLOG_INFO << "Use Bump " << string_from_bool(features & KERNEL_FEATURE_NODE_BUMP) << "\n";
600  VLOG_INFO << "Use Voronoi " << string_from_bool(features & KERNEL_FEATURE_NODE_VORONOI_EXTRA)
601  << "\n";
602  VLOG_INFO << "Use Shader Raytrace " << string_from_bool(features & KERNEL_FEATURE_NODE_RAYTRACE)
603  << "\n";
604  VLOG_INFO << "Use MNEE" << string_from_bool(features & KERNEL_FEATURE_MNEE) << "\n";
605  VLOG_INFO << "Use Transparent " << string_from_bool(features & KERNEL_FEATURE_TRANSPARENT)
606  << "\n";
607  VLOG_INFO << "Use Denoising " << string_from_bool(features & KERNEL_FEATURE_DENOISING) << "\n";
608  VLOG_INFO << "Use Path Tracing " << string_from_bool(features & KERNEL_FEATURE_PATH_TRACING)
609  << "\n";
610  VLOG_INFO << "Use Hair " << string_from_bool(features & KERNEL_FEATURE_HAIR) << "\n";
611  VLOG_INFO << "Use Pointclouds " << string_from_bool(features & KERNEL_FEATURE_POINTCLOUD)
612  << "\n";
613  VLOG_INFO << "Use Object Motion " << string_from_bool(features & KERNEL_FEATURE_OBJECT_MOTION)
614  << "\n";
615  VLOG_INFO << "Use Camera Motion " << string_from_bool(features & KERNEL_FEATURE_CAMERA_MOTION)
616  << "\n";
617  VLOG_INFO << "Use Baking " << string_from_bool(features & KERNEL_FEATURE_BAKING) << "\n";
618  VLOG_INFO << "Use Subsurface " << string_from_bool(features & KERNEL_FEATURE_SUBSURFACE) << "\n";
619  VLOG_INFO << "Use Volume " << string_from_bool(features & KERNEL_FEATURE_VOLUME) << "\n";
620  VLOG_INFO << "Use Patch Evaluation "
621  << string_from_bool(features & KERNEL_FEATURE_PATCH_EVALUATION) << "\n";
622  VLOG_INFO << "Use Shadow Catcher " << string_from_bool(features & KERNEL_FEATURE_SHADOW_CATCHER)
623  << "\n";
624 }
625 
626 bool Scene::load_kernels(Progress &progress, bool lock_scene)
627 {
628  thread_scoped_lock scene_lock;
629  if (lock_scene) {
630  scene_lock = thread_scoped_lock(mutex);
631  }
632 
634 
635  const uint kernel_features = dscene.data.kernel_features;
636 
637  if (!kernels_loaded || loaded_kernel_features != kernel_features) {
638  progress.set_status("Loading render kernels (may take a few minutes the first time)");
639 
640  scoped_timer timer;
641 
642  log_kernel_features(kernel_features);
643  if (!device->load_kernels(kernel_features)) {
644  string message = device->error_message();
645  if (message.empty())
646  message = "Failed loading render kernel, see console for errors";
647 
648  progress.set_error(message);
649  progress.set_status(message);
650  progress.set_update();
651  return false;
652  }
653 
654  kernels_loaded = true;
655  loaded_kernel_features = kernel_features;
656  return true;
657  }
658  return false;
659 }
660 
662 {
663  if (shader_manager->use_osl()) {
664  /* OSL always needs the maximum as we can't predict the
665  * number of closures a shader might generate. */
666  return MAX_CLOSURE;
667  }
668 
669  int max_closures = 0;
670  for (int i = 0; i < shaders.size(); i++) {
671  Shader *shader = shaders[i];
672  if (shader->reference_count()) {
673  int num_closures = shader->graph->get_num_closures();
674  max_closures = max(max_closures, num_closures);
675  }
676  }
677  max_closure_global = max(max_closure_global, max_closures);
678 
680  /* This is usually harmless as more complex shader tend to get many
681  * closures discarded due to mixing or low weights. We need to limit
682  * to MAX_CLOSURE as this is hardcoded in CPU/mega kernels, and it
683  * avoids excessive memory usage for split kernels. */
684  VLOG_WARNING << "Maximum number of closures exceeded: " << max_closure_global << " > "
685  << MAX_CLOSURE;
686 
688  }
689 
690  return max_closure_global;
691 }
692 
694 {
695  int volume_stack_size = 0;
696 
697  /* Space for background volume and terminator.
698  * Don't do optional here because camera ray initialization expects that there is space for
699  * at least those elements (avoiding extra condition to check if there is actual volume or not).
700  */
701  volume_stack_size += 2;
702 
703  /* Quick non-expensive check. Can over-estimate maximum possible nested level, but does not
704  * require expensive calculation during pre-processing. */
705  bool has_volume_object = false;
706  for (const Object *object : objects) {
707  if (!object->get_geometry()->has_volume) {
708  continue;
709  }
710 
711  if (object->intersects_volume) {
712  /* Object intersects another volume, assume it's possible to go deeper in the stack. */
713  /* TODO(sergey): This might count nesting twice (A intersects B and B intersects A), but
714  * can't think of a computationally cheap algorithm. Dividing my 2 doesn't work because of
715  * Venn diagram example with 3 circles. */
716  ++volume_stack_size;
717  }
718  else if (!has_volume_object) {
719  /* Allocate space for at least one volume object. */
720  ++volume_stack_size;
721  }
722 
723  has_volume_object = true;
724 
725  if (volume_stack_size == MAX_VOLUME_STACK_SIZE) {
726  break;
727  }
728  }
729 
730  volume_stack_size = min(volume_stack_size, MAX_VOLUME_STACK_SIZE);
731 
732  VLOG_WORK << "Detected required volume stack size " << volume_stack_size;
733 
734  return volume_stack_size;
735 }
736 
738 {
740  has_shadow_catcher_ = false;
741  for (Object *object : objects) {
742  if (object->get_is_shadow_catcher()) {
743  has_shadow_catcher_ = true;
744  break;
745  }
746  }
747 
748  shadow_catcher_modified_ = false;
749  }
750 
751  return has_shadow_catcher_;
752 }
753 
755 {
757 }
758 
759 template<> Light *Scene::create_node<Light>()
760 {
761  Light *node = new Light();
762  node->set_owner(this);
763  lights.push_back(node);
765  return node;
766 }
767 
768 template<> Mesh *Scene::create_node<Mesh>()
769 {
770  Mesh *node = new Mesh();
771  node->set_owner(this);
772  geometry.push_back(node);
774  return node;
775 }
776 
777 template<> Hair *Scene::create_node<Hair>()
778 {
779  Hair *node = new Hair();
780  node->set_owner(this);
781  geometry.push_back(node);
783  return node;
784 }
785 
786 template<> Volume *Scene::create_node<Volume>()
787 {
788  Volume *node = new Volume();
789  node->set_owner(this);
790  geometry.push_back(node);
792  return node;
793 }
794 
795 template<> PointCloud *Scene::create_node<PointCloud>()
796 {
797  PointCloud *node = new PointCloud();
798  node->set_owner(this);
799  geometry.push_back(node);
801  return node;
802 }
803 
804 template<> Object *Scene::create_node<Object>()
805 {
806  Object *node = new Object();
807  node->set_owner(this);
808  objects.push_back(node);
810  return node;
811 }
812 
813 template<> ParticleSystem *Scene::create_node<ParticleSystem>()
814 {
816  node->set_owner(this);
817  particle_systems.push_back(node);
819  return node;
820 }
821 
822 template<> Shader *Scene::create_node<Shader>()
823 {
824  Shader *node = new Shader();
825  node->set_owner(this);
826  shaders.push_back(node);
828  return node;
829 }
830 
831 template<> AlembicProcedural *Scene::create_node<AlembicProcedural>()
832 {
833 #ifdef WITH_ALEMBIC
834  AlembicProcedural *node = new AlembicProcedural();
835  node->set_owner(this);
836  procedurals.push_back(node);
838  return node;
839 #else
840  return nullptr;
841 #endif
842 }
843 
844 template<> Pass *Scene::create_node<Pass>()
845 {
846  Pass *node = new Pass();
847  node->set_owner(this);
848  passes.push_back(node);
849  film->tag_modified();
850  return node;
851 }
852 
853 template<typename T> void delete_node_from_array(vector<T> &nodes, T node)
854 {
855  for (size_t i = 0; i < nodes.size(); ++i) {
856  if (nodes[i] == node) {
857  std::swap(nodes[i], nodes[nodes.size() - 1]);
858  break;
859  }
860  }
861 
862  nodes.resize(nodes.size() - 1);
863 
864  delete node;
865 }
866 
868 {
871 }
872 
874 {
875  delete_node_from_array(geometry, static_cast<Geometry *>(node));
877 }
878 
880 {
881  delete_node_from_array(geometry, static_cast<Geometry *>(node));
883 }
884 
886 {
887  delete_node_from_array(geometry, static_cast<Geometry *>(node));
889 }
890 
892 {
893  delete_node_from_array(geometry, static_cast<Geometry *>(node));
895 }
896 
898 {
899  uint flag;
900  if (node->is_hair()) {
902  }
903  else {
905  }
906 
909 }
910 
912 {
915 }
916 
918 {
921 }
922 
923 template<> void Scene::delete_node_impl(Shader *shader)
924 {
925  /* don't delete unused shaders, not supported */
926  shader->clear_reference_count();
927 }
928 
930 {
933 }
934 
935 template<> void Scene::delete_node_impl(AlembicProcedural *node)
936 {
937 #ifdef WITH_ALEMBIC
938  delete_node_impl(static_cast<Procedural *>(node));
939 #else
940  (void)node;
941 #endif
942 }
943 
945 {
947  film->tag_modified();
948 }
949 
950 template<typename T>
951 static void remove_nodes_in_set(const set<T *> &nodes_set,
952  vector<T *> &nodes_array,
953  const NodeOwner *owner)
954 {
955  size_t new_size = nodes_array.size();
956 
957  for (size_t i = 0; i < new_size; ++i) {
958  T *node = nodes_array[i];
959 
960  if (nodes_set.find(node) != nodes_set.end()) {
961  std::swap(nodes_array[i], nodes_array[new_size - 1]);
962 
963  assert(node->get_owner() == owner);
964  delete node;
965 
966  i -= 1;
967  new_size -= 1;
968  }
969  }
970 
971  nodes_array.resize(new_size);
972  (void)owner;
973 }
974 
975 template<> void Scene::delete_nodes(const set<Light *> &nodes, const NodeOwner *owner)
976 {
977  remove_nodes_in_set(nodes, lights, owner);
979 }
980 
981 template<> void Scene::delete_nodes(const set<Geometry *> &nodes, const NodeOwner *owner)
982 {
983  remove_nodes_in_set(nodes, geometry, owner);
985 }
986 
987 template<> void Scene::delete_nodes(const set<Object *> &nodes, const NodeOwner *owner)
988 {
989  remove_nodes_in_set(nodes, objects, owner);
991 }
992 
993 template<> void Scene::delete_nodes(const set<ParticleSystem *> &nodes, const NodeOwner *owner)
994 {
995  remove_nodes_in_set(nodes, particle_systems, owner);
997 }
998 
999 template<> void Scene::delete_nodes(const set<Shader *> &nodes, const NodeOwner * /*owner*/)
1000 {
1001  /* don't delete unused shaders, not supported */
1002  for (Shader *shader : nodes) {
1003  shader->clear_reference_count();
1004  }
1005 }
1006 
1007 template<> void Scene::delete_nodes(const set<Procedural *> &nodes, const NodeOwner *owner)
1008 {
1009  remove_nodes_in_set(nodes, procedurals, owner);
1011 }
1012 
1013 template<> void Scene::delete_nodes(const set<Pass *> &nodes, const NodeOwner *owner)
1014 {
1015  remove_nodes_in_set(nodes, passes, owner);
1016  film->tag_modified();
1017 }
1018 
unsigned int uint
Definition: BLI_sys_types.h:67
void swap(T &a, T &b)
Definition: Common.h:19
struct Light Light
struct Mesh Mesh
struct Object Object
struct ParticleSystem ParticleSystem
struct PointCloud PointCloud
struct Volume Volume
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
ATTR_WARN_UNUSED_RESULT const BMLoop * l
void add(ustring name)
void device_update(Device *device, DeviceScene *dscene, Scene *scene)
void device_free(Device *device, DeviceScene *dscene)
void tag_update(Scene *scene)
bool need_update() const
Definition: bake.cpp:86
void device_free(Device *device, DeviceScene *dscene)
Definition: bake.cpp:77
bool get_baking() const
Definition: bake.cpp:25
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
Definition: bake.cpp:41
DeviceScene(Device *device)
Definition: scene.cpp:36
KernelData data
Definition: scene.h:130
virtual void optimize_for_scene(Scene *)
virtual void const_copy_to(const char *name, void *host, size_t size)=0
virtual bool load_kernels(uint)
virtual const string & error_message()
DeviceInfo info
bool have_error()
uint get_kernel_features(const Scene *scene) const
Definition: film.cpp:696
static void add_default(Scene *scene)
Definition: film.cpp:134
void device_free(Device *device, DeviceScene *dscene, Scene *scene)
Definition: film.cpp:410
void device_update(Device *device, DeviceScene *dscene, Scene *scene)
Definition: film.cpp:140
bool update_lightgroups(Scene *scene)
Definition: film.cpp:441
void device_update(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 collect_statistics(const Scene *scene, RenderStats *stats)
void device_update_preprocess(Device *device, Scene *scene, Progress &progress)
bool need_update() const
bool is_pointcloud() const
bool is_hair() const
bool is_mesh() const
Definition: hair.h:13
void device_update(Device *device, Scene *scene, Progress &progress)
bool need_update() const
void device_free(Device *device)
void device_free_builtin(Device *device)
void collect_statistics(RenderStats *stats)
void tag_update(Scene *scene, uint32_t flag)
Definition: integrator.cpp:291
void device_update(Device *device, DeviceScene *dscene, Scene *scene)
Definition: integrator.cpp:128
void device_free(Device *device, DeviceScene *dscene, bool force_free=false)
Definition: integrator.cpp:286
uint get_kernel_features() const
Definition: integrator.cpp:318
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
void device_free(Device *device, DeviceScene *dscene, const bool free_background=true)
bool need_update() const
void tag_update(Scene *scene, uint32_t flag)
void device_free(Device *device, DeviceScene *dscene)
Definition: tables.cpp:45
void device_update(Device *device, DeviceScene *dscene, Scene *scene)
Definition: tables.cpp:26
bool need_update() const
Definition: tables.cpp:50
void add_entry(const NamedTimeEntry &entry)
Definition: scene/stats.h:68
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
void tag_update(Scene *scene, uint32_t flag)
void device_free(Device *device, DeviceScene *dscene, bool force_free)
bool need_update() const
void device_update_prim_offsets(Device *device, DeviceScene *dscene, Scene *scene)
void device_update_flags(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress, bool bounds_valid=true)
void device_free(Device *device, DeviceScene *dscene)
void tag_update(Scene *scene)
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
Definition: pass.h:48
static bool contains(const vector< Pass * > &passes, PassType type)
Definition: pass.cpp:349
bool need_update() const
Definition: procedural.cpp:70
void update(Scene *scene, Progress &progress)
Definition: procedural.cpp:36
bool get_cancel() const
Definition: progress.h:90
void set_status(const string &status_, const string &substatus_="")
Definition: progress.h:248
void set_update()
Definition: progress.h:306
void set_error(const string &error_message_)
Definition: progress.h:110
bool background
Definition: scene.h:157
CurveShapeType hair_shape
Definition: scene.h:154
ShadingSystem shadingsystem
Definition: scene.h:139
string full_report()
Definition: stats.cpp:329
void clear()
Definition: stats.cpp:350
UpdateTimeStats scene
Definition: scene/stats.h:206
int get_num_closures()
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
virtual void device_free(Device *device, DeviceScene *dscene, Scene *scene)=0
bool need_update() const
static ShaderManager * create(int shadingsystem)
void tag_update(Scene *scene, uint32_t flag)
uint get_kernel_features(Scene *scene)
static void add_default(Scene *scene)
virtual bool use_osl()
Definition: scene/shader.h:178
virtual void reset(Scene *scene)=0
NODE_DECLARE ShaderGraph * graph
Definition: scene/shader.h:71
NamedTimeStats times
Definition: scene/stats.h:188
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
@ MEM_GLOBAL
OperationNode * node
double time
SyclQueue void void size_t num_bytes void
size_t util_guarded_get_mem_used()
size_t util_guarded_get_mem_peak()
#define MEM_GUARDED_CALL(progress, func,...)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define MAX_VOLUME_STACK_SIZE
Definition: kernel/types.h:692
AttributeStandard
Definition: kernel/types.h:612
@ ATTR_STD_UV
Definition: kernel/types.h:616
@ ATTR_STD_MOTION_VERTEX_NORMAL
Definition: kernel/types.h:625
@ ATTR_STD_VOLUME_VELOCITY_Y
Definition: kernel/types.h:640
@ ATTR_STD_NONE
Definition: kernel/types.h:613
@ ATTR_STD_VOLUME_VELOCITY_Z
Definition: kernel/types.h:641
@ ATTR_STD_NUM
Definition: kernel/types.h:645
@ ATTR_STD_VOLUME_VELOCITY
Definition: kernel/types.h:638
@ ATTR_STD_MOTION_VERTEX_POSITION
Definition: kernel/types.h:624
@ ATTR_STD_VOLUME_VELOCITY_X
Definition: kernel/types.h:639
@ KERNEL_FEATURE_BAKING
@ KERNEL_FEATURE_NODE_VOLUME
@ KERNEL_FEATURE_NODE_EMISSION
@ KERNEL_FEATURE_NODE_BSDF
@ KERNEL_FEATURE_NODE_BUMP
@ KERNEL_FEATURE_OBJECT_MOTION
@ KERNEL_FEATURE_MNEE
@ KERNEL_FEATURE_SUBSURFACE
@ KERNEL_FEATURE_PRINCIPLED
@ KERNEL_FEATURE_CAMERA_MOTION
@ KERNEL_FEATURE_SHADOW_CATCHER
@ KERNEL_FEATURE_HAIR
@ KERNEL_FEATURE_TRANSPARENT
@ KERNEL_FEATURE_HAIR_THICK
@ KERNEL_FEATURE_PATCH_EVALUATION
@ KERNEL_FEATURE_PATH_TRACING
@ KERNEL_FEATURE_NODE_VORONOI_EXTRA
@ KERNEL_FEATURE_VOLUME
@ KERNEL_FEATURE_POINTCLOUD
@ KERNEL_FEATURE_DENOISING
@ KERNEL_FEATURE_NODE_RAYTRACE
@ CURVE_THICK
Definition: kernel/types.h:583
#define MAX_CLOSURE
Definition: kernel/types.h:675
@ PASS_UV
Definition: kernel/types.h:362
@ PASS_MOTION
Definition: kernel/types.h:365
#define VLOG_INFO
Definition: log.h:77
#define VLOG_WARNING
Definition: log.h:75
#define VLOG_WORK
Definition: log.h:80
#define T
static const pxr::TfToken g("g", pxr::TfToken::Immortal)
static const pxr::TfToken Shader("Shader", pxr::TfToken::Immortal)
@ SHADINGSYSTEM_SVM
Definition: scene/shader.h:34
void delete_node_from_array(vector< T > &nodes, T node)
Definition: scene.cpp:853
static void log_kernel_features(const uint features)
Definition: scene.cpp:590
static void remove_nodes_in_set(const set< T * > &nodes_set, vector< T * > &nodes_array, const NodeOwner *owner)
Definition: scene.cpp:951
#define min(a, b)
Definition: sort.c:35
string string_from_bool(bool var)
Definition: string.cpp:167
string string_human_readable_size(size_t size)
Definition: string.cpp:229
string string_human_readable_number(size_t num)
Definition: string.cpp:248
uint max_closures
uint max_shaders
uint volume_stack_size
uint kernel_features
@ SUBDIVISION_NONE
Definition: scene/mesh.h:120
int reference_count() const
Definition: graph/node.h:180
void tag_modified()
Definition: graph/node.cpp:809
bool is_modified() const
Definition: graph/node.cpp:804
void clear_reference_count()
Definition: graph/node.h:198
bool use_motion() const
bool kernels_loaded
Definition: scene.h:332
BakeManager * bake_manager
Definition: scene.h:228
Film * film
Definition: scene.h:208
BVH * bvh
Definition: scene.h:204
bool need_global_attribute(AttributeStandard std)
Definition: scene.cpp:405
ParticleSystemManager * particle_system_manager
Definition: scene.h:227
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
bool update(Progress &progress)
Definition: scene.cpp:574
vector< Pass * > passes
Definition: scene.h:218
Device * device
Definition: scene.h:239
vector< Shader * > shaders
Definition: scene.h:215
vector< Procedural * > procedurals
Definition: scene.h:219
int get_max_closure_count()
Definition: scene.cpp:661
~Scene()
Definition: scene.cpp:128
void device_free()
Definition: scene.cpp:468
bool load_kernels(Progress &progress, bool lock_scene=true)
Definition: scene.cpp:626
bool has_shadow_catcher_
Definition: scene.h:338
Camera * dicing_camera
Definition: scene.h:206
LookupTables * lookup_tables
Definition: scene.h:207
SceneParams params
Definition: scene.h:243
vector< Light * > lights
Definition: scene.h:216
void tag_shadow_catcher_modified()
Definition: scene.cpp:754
void free_memory(bool final)
Definition: scene.cpp:133
short flag
vector< ParticleSystem * > particle_systems
Definition: scene.h:217
ImageManager * image_manager
Definition: scene.h:222
void enable_update_stats()
Definition: scene.cpp:479
uint loaded_kernel_features
Definition: scene.h:333
vector< Object * > objects
Definition: scene.h:213
ObjectManager * object_manager
Definition: scene.h:226
bool shadow_catcher_modified_
Definition: scene.h:339
Background * background
Definition: scene.h:209
MotionType
Definition: scene.h:259
@ MOTION_PASS
Definition: scene.h:259
@ MOTION_NONE
Definition: scene.h:259
@ MOTION_BLUR
Definition: scene.h:259
void update_kernel_features()
Definition: scene.cpp:486
void delete_nodes(const set< T * > &nodes)
Definition: scene.h:315
bool has_shadow_catcher()
Definition: scene.cpp:737
ProceduralManager * procedural_manager
Definition: scene.h:229
ShaderManager * shader_manager
Definition: scene.h:224
void delete_node_impl(T *node)
Definition: scene.h:350
int max_closure_global
Definition: scene.h:342
Integrator * integrator
Definition: scene.h:210
LightManager * light_manager
Definition: scene.h:223
thread_mutex mutex
Definition: scene.h:246
bool need_data_update()
Definition: scene.cpp:433
int get_volume_stack_size() const
Definition: scene.cpp:693
struct Object * camera
bool need_update()
Definition: scene.cpp:428
void reset()
Definition: scene.cpp:448
void collect_statistics(RenderStats *stats)
Definition: scene.cpp:473
bool need_reset()
Definition: scene.cpp:443
SceneUpdateStats * update_stats
Definition: scene.h:249
GeometryManager * geometry_manager
Definition: scene.h:225
DeviceScene dscene
Definition: scene.h:240
float motion_shutter_time()
Definition: scene.cpp:397
Scene(const SceneParams &params, Device *device)
Definition: scene.cpp:84
void device_update(Device *device, Progress &progress)
Definition: scene.cpp:223
std::unique_lock< std::mutex > thread_scoped_lock
Definition: thread.h:28
float max