Blender V4.5
scene.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include <cstdlib>
6
7#include "bvh/bvh.h"
8#include "device/device.h"
9#include "scene/alembic.h"
10#include "scene/background.h"
11#include "scene/bake.h"
12#include "scene/camera.h"
13#include "scene/curves.h"
14#include "scene/devicescene.h"
15#include "scene/film.h"
16#include "scene/hair.h"
17#include "scene/integrator.h"
18#include "scene/light.h"
19#include "scene/mesh.h"
20#include "scene/object.h"
21#include "scene/osl.h"
22#include "scene/particles.h"
23#include "scene/pointcloud.h"
24#include "scene/procedural.h"
25#include "scene/scene.h"
26#include "scene/shader.h"
27#include "scene/svm.h"
28#include "scene/tables.h"
29#include "scene/volume.h"
30#include "session/session.h"
31
33#include "util/log.h"
34#include "util/progress.h"
35
37
38Scene ::Scene(const SceneParams &params_, Device *device)
39 : name("Scene"),
47 params(params_),
50 /* TODO(sergey): Check if it's indeed optimal value for the split kernel.
51 */
53{
54 memset((void *)&dscene.data, 0, sizeof(dscene.data));
55
56 osl_manager = make_unique<OSLManager>(device);
57 shader_manager = ShaderManager::create(device->info.has_osl ? params.shadingsystem :
59
60 light_manager = make_unique<LightManager>();
61 geometry_manager = make_unique<GeometryManager>();
62 object_manager = make_unique<ObjectManager>();
63 image_manager = make_unique<ImageManager>(device->info);
64 particle_system_manager = make_unique<ParticleSystemManager>();
65 bake_manager = make_unique<BakeManager>();
66 procedural_manager = make_unique<ProceduralManager>();
67
68 /* Create nodes after managers, since create_node() can tag the managers. */
71 lookup_tables = make_unique<LookupTables>();
75
76 ccl::Film::add_default(this);
77 ccl::ShaderManager::add_default(this);
78}
79
81{
82 free_memory(true);
83}
84
85void Scene::free_memory(bool final)
86{
87 bvh.reset();
88
89 /* The order of deletion is important to make sure data is freed based on
90 * possible dependencies as the Nodes' reference counts are decremented in the
91 * destructors:
92 *
93 * - Procedurals can create and hold pointers to any other types.
94 * - Objects can hold pointers to Geometries and ParticleSystems
95 * - Lights and Geometries can hold pointers to Shaders.
96 *
97 * Similarly, we first delete all nodes and their associated device data, and
98 * then the managers and their associated device data.
99 */
100 procedurals.clear();
101 objects.clear();
102 geometry.clear();
103 particle_systems.clear();
104 passes.clear();
105
106 if (device) {
107 camera->device_free(device, &dscene, this);
108 film->device_free(device, &dscene, this);
109 background->device_free(device, &dscene);
110 integrator->device_free(device, &dscene, true);
111 }
112
113 if (final) {
114 cameras.clear();
115 integrators.clear();
116 films.clear();
117 backgrounds.clear();
118
119 camera = nullptr;
120 dicing_camera = nullptr;
121 integrator = nullptr;
122 film = nullptr;
123 background = nullptr;
124 }
125
126 /* Delete Shaders after every other nodes to ensure that we do not try to
127 * decrement the reference count on some dangling pointer. */
128 shaders.clear();
129
130 /* Now that all nodes have been deleted, we can safely delete managers and
131 * device data. */
132 if (device) {
133 object_manager->device_free(device, &dscene, true);
134 geometry_manager->device_free(device, &dscene, true);
135 shader_manager->device_free(device, &dscene, this);
136 osl_manager->device_free(device, &dscene, this);
137 light_manager->device_free(device, &dscene);
138
139 particle_system_manager->device_free(device, &dscene);
140
141 bake_manager->device_free(device, &dscene);
142
143 if (final) {
144 image_manager->device_free(device);
145 }
146 else {
147 image_manager->device_free_builtin(device);
148 }
149
150 lookup_tables->device_free(device, &dscene);
151 }
152
153 if (final) {
154 lookup_tables.reset();
155 object_manager.reset();
156 geometry_manager.reset();
157 shader_manager.reset();
158 osl_manager.reset();
159 light_manager.reset();
161 image_manager.reset();
162 bake_manager.reset();
163 update_stats.reset();
164 procedural_manager.reset();
165 }
166}
167
169{
170 if (!device) {
171 device = device_;
172 }
173
174 const bool print_stats = need_data_update();
175 bool kernels_reloaded = false;
176
177 while (true) {
178 if (update_stats) {
179 update_stats->clear();
180 }
181
182 const scoped_callback_timer timer([this, print_stats](double time) {
183 if (update_stats) {
184 update_stats->scene.times.add_entry({"device_update", time});
185
186 if (print_stats) {
187 printf("Update statistics:\n%s\n", update_stats->full_report().c_str());
188 }
189 }
190 });
191
192 /* The order of updates is important, because there's dependencies between
193 * the different managers, using data computed by previous managers. */
194
195 if (film->update_lightgroups(this)) {
196 light_manager->tag_update(this, ccl::LightManager::LIGHT_MODIFIED);
197 object_manager->tag_update(this, ccl::ObjectManager::OBJECT_MODIFIED);
198 background->tag_modified();
199 }
200 if (film->exposure_is_modified()) {
201 integrator->tag_modified();
202 }
203
204 /* Compile shaders and get information about features they used. */
205 progress.set_status("Updating Shaders");
206 osl_manager->device_update_pre(device, this);
207 shader_manager->device_update_pre(device, &dscene, this, progress);
208
209 if (progress.get_cancel() || device->have_error()) {
210 return;
211 }
212
213 /* Passes. After shader manager as this depends on the shaders. */
214 film->update_passes(this);
215
216 /* Update kernel features. After shaders and passes since those affect features. */
218
219 /* Load render kernels, before uploading most data to the GPU, and before displacement and
220 * background light need to run kernels.
221 *
222 * Do it outside of the scene mutex since the heavy part of the loading (i.e. kernel
223 * compilation) does not depend on the scene and some other functionality (like display
224 * driver) might be waiting on the scene mutex to synchronize display pass.
225 *
226 * This does mean the scene might have gotten updated in the meantime, in which case
227 * we have to redo the first part of the scene update. */
228 const uint kernel_features = dscene.data.kernel_features;
230 if (!kernels_loaded || loaded_kernel_features != kernel_features) {
231 mutex.unlock();
232 kernels_reloaded |= load_kernels(progress);
233 mutex.lock();
234 }
235
236 if (progress.get_cancel() || device->have_error()) {
237 return;
238 }
239
241 break;
242 }
243 }
244
245 /* Upload shaders to GPU and compile OSL kernels, after kernels have been loaded. */
246 shader_manager->device_update_post(device, &dscene, this, progress);
247 osl_manager->device_update_post(device, this, progress, kernels_reloaded);
248
249 if (progress.get_cancel() || device->have_error()) {
250 return;
251 }
252
253 procedural_manager->update(this, progress);
254
255 if (progress.get_cancel()) {
256 return;
257 }
258
259 progress.set_status("Updating Background");
260 background->device_update(device, &dscene, this);
261
262 if (progress.get_cancel() || device->have_error()) {
263 return;
264 }
265
266 /* Camera will be used by adaptive subdivision, so do early. */
267 progress.set_status("Updating Camera");
268 camera->device_update(device, &dscene, this);
269
270 if (progress.get_cancel() || device->have_error()) {
271 return;
272 }
273
274 geometry_manager->device_update_preprocess(device, this, progress);
275 if (progress.get_cancel() || device->have_error()) {
276 return;
277 }
278
279 /* Update objects after geometry preprocessing. */
280 progress.set_status("Updating Objects");
281 object_manager->device_update(device, &dscene, this, progress);
282
283 if (progress.get_cancel() || device->have_error()) {
284 return;
285 }
286
287 progress.set_status("Updating Particle Systems");
288 particle_system_manager->device_update(device, &dscene, this, progress);
289
290 if (progress.get_cancel() || device->have_error()) {
291 return;
292 }
293
294 /* Camera and shaders must be ready here for adaptive subdivision and displacement. */
295 progress.set_status("Updating Meshes");
296 geometry_manager->device_update(device, &dscene, this, progress);
297
298 if (progress.get_cancel() || device->have_error()) {
299 return;
300 }
301
302 /* Update object flags with final geometry. */
303 progress.set_status("Updating Objects Flags");
304 object_manager->device_update_flags(device, &dscene, this, progress);
305
306 if (progress.get_cancel() || device->have_error()) {
307 return;
308 }
309
310 /* Update BVH primitive objects with final geometry. */
311 progress.set_status("Updating Primitive Offsets");
312 object_manager->device_update_prim_offsets(device, &dscene, this);
313
314 if (progress.get_cancel() || device->have_error()) {
315 return;
316 }
317
318 /* Images last, as they should be more likely to use host memory fallback than geometry.
319 * Some images may have been uploaded early for displacement already at this point. */
320 progress.set_status("Updating Images");
321 image_manager->device_update(device, this, progress);
322
323 if (progress.get_cancel() || device->have_error()) {
324 return;
325 }
326
327 progress.set_status("Updating Camera Volume");
328 camera->device_update_volume(device, &dscene, this);
329
330 if (progress.get_cancel() || device->have_error()) {
331 return;
332 }
333
334 progress.set_status("Updating Lookup Tables");
335 lookup_tables->device_update(device, &dscene, this);
336
337 if (progress.get_cancel() || device->have_error()) {
338 return;
339 }
340
341 /* Light manager needs shaders and final meshes for triangles in light tree. */
342 progress.set_status("Updating Lights");
343 light_manager->device_update(device, &dscene, this, progress);
344
345 if (progress.get_cancel() || device->have_error()) {
346 return;
347 }
348
349 progress.set_status("Updating Integrator");
350 integrator->device_update(device, &dscene, this);
351
352 if (progress.get_cancel() || device->have_error()) {
353 return;
354 }
355
356 progress.set_status("Updating Film");
357 film->device_update(device, &dscene, this);
358
359 if (progress.get_cancel() || device->have_error()) {
360 return;
361 }
362
363 /* Update lookup tables a second time for film tables. */
364 progress.set_status("Updating Lookup Tables");
365 lookup_tables->device_update(device, &dscene, this);
366
367 if (progress.get_cancel() || device->have_error()) {
368 return;
369 }
370
371 progress.set_status("Updating Baking");
372 bake_manager->device_update(device, &dscene, this, progress);
373
374 if (progress.get_cancel() || device->have_error()) {
375 return;
376 }
377
378 if (device->have_error() == false) {
379 dscene.data.volume_stack_size = get_volume_stack_size();
380
381 progress.set_status("Updating Device", "Writing constant memory");
382 device->const_copy_to("data", &dscene.data, sizeof(dscene.data));
383 }
384
385 device->optimize_for_scene(this);
386
387 if (print_stats) {
388 const size_t mem_used = util_guarded_get_mem_used();
389 const size_t mem_peak = util_guarded_get_mem_peak();
390
391 VLOG_INFO << "System memory statistics after full device sync:\n"
392 << " Usage: " << string_human_readable_number(mem_used) << " ("
393 << string_human_readable_size(mem_used) << ")\n"
394 << " Peak: " << string_human_readable_number(mem_peak) << " ("
395 << string_human_readable_size(mem_peak) << ")";
396 }
397}
398
400{
401 if (integrator->get_motion_blur()) {
402 return MOTION_BLUR;
403 }
405 return MOTION_PASS;
406 }
407 return MOTION_NONE;
408}
409
411{
413 return 2.0f;
414 }
415 return camera->get_shuttertime();
416}
417
419{
420 if (std == ATTR_STD_UV) {
422 }
424 return need_motion() != MOTION_NONE;
425 }
427 return need_motion() == MOTION_BLUR;
428 }
431 {
432 return need_motion() != MOTION_NONE;
433 }
434
435 return false;
436}
437
439{
440 for (int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++) {
442 attributes.add((AttributeStandard)std);
443 }
444 }
445}
446
448{
449 return (need_reset() || film->is_modified());
450}
451
453{
454 return (background->is_modified() || image_manager->need_update() ||
455 object_manager->need_update() || geometry_manager->need_update() ||
456 light_manager->need_update() || lookup_tables->need_update() ||
457 integrator->is_modified() || shader_manager->need_update() ||
458 particle_system_manager->need_update() || bake_manager->need_update() ||
459 film->is_modified() || procedural_manager->need_update());
460}
461
462bool Scene::need_reset(const bool check_camera)
463{
464 return need_data_update() || (check_camera && camera->is_modified());
465}
466
468{
469 osl_manager->reset(this);
471
472 /* ensure all objects are updated */
473 camera->tag_modified();
474 dicing_camera->tag_modified();
475 film->tag_modified();
476 background->tag_modified();
477
478 background->tag_update(this);
479 integrator->tag_update(this, Integrator::UPDATE_ALL);
480 object_manager->tag_update(this, ObjectManager::UPDATE_ALL);
482 light_manager->tag_update(this, LightManager::UPDATE_ALL);
483 particle_system_manager->tag_update(this);
484 procedural_manager->tag_update();
485}
486
488{
489 free_memory(false);
490}
491
493{
494 geometry_manager->collect_statistics(this, stats);
495 image_manager->collect_statistics(stats);
496}
497
499{
500 if (!update_stats) {
501 update_stats = make_unique<SceneUpdateStats>();
502 }
503}
504
506{
507 if (!need_update()) {
508 return;
509 }
510
511 /* These features are not being tweaked as often as shaders,
512 * so could be done selective magic for the viewport as well. */
513 uint kernel_features = shader_manager->get_kernel_features(this);
514
515 const bool use_motion = need_motion() == Scene::MotionType::MOTION_BLUR;
516 kernel_features |= KERNEL_FEATURE_PATH_TRACING;
517 if (params.hair_shape == CURVE_THICK) {
518 kernel_features |= KERNEL_FEATURE_HAIR_THICK;
519 }
520
521 /* Figure out whether the scene will use shader ray-trace we need at least
522 * one caustic light, one caustic caster and one caustic receiver to use
523 * and enable the MNEE code path. */
524 bool has_caustics_receiver = false;
525 bool has_caustics_caster = false;
526 bool has_caustics_light = false;
527
528 for (Object *object : objects) {
529 if (object->get_is_caustics_caster()) {
530 has_caustics_caster = true;
531 }
532 else if (object->get_is_caustics_receiver()) {
533 has_caustics_receiver = true;
534 }
535 Geometry *geom = object->get_geometry();
536 if (use_motion) {
537 if (object->use_motion() || geom->get_use_motion_blur()) {
538 kernel_features |= KERNEL_FEATURE_OBJECT_MOTION;
539 }
540 }
541 if (object->get_is_shadow_catcher() && !geom->is_light()) {
542 kernel_features |= KERNEL_FEATURE_SHADOW_CATCHER;
543 }
544 if (geom->is_hair()) {
545 kernel_features |= KERNEL_FEATURE_HAIR;
546 }
547 else if (geom->is_pointcloud()) {
548 kernel_features |= KERNEL_FEATURE_POINTCLOUD;
549 }
550 else if (geom->is_light()) {
551 const Light *light = static_cast<const Light *>(object->get_geometry());
552 if (light->get_use_caustics()) {
553 has_caustics_light = true;
554 }
555 }
556 if (object->has_light_linking()) {
557 kernel_features |= KERNEL_FEATURE_LIGHT_LINKING;
558 }
559 if (object->has_shadow_linking()) {
560 kernel_features |= KERNEL_FEATURE_SHADOW_LINKING;
561 }
562 }
563
564 dscene.data.integrator.use_caustics = false;
565 if (device->info.has_mnee && has_caustics_caster && has_caustics_receiver && has_caustics_light)
566 {
567 dscene.data.integrator.use_caustics = true;
568 kernel_features |= KERNEL_FEATURE_MNEE;
569 }
570
571 if (integrator->get_guiding_params(device).use) {
572 kernel_features |= KERNEL_FEATURE_PATH_GUIDING;
573 }
574
575 if (bake_manager->get_baking()) {
576 kernel_features |= KERNEL_FEATURE_BAKING;
577 }
578
579 kernel_features |= film->get_kernel_features(this);
580 kernel_features |= integrator->get_kernel_features();
581 kernel_features |= camera->get_kernel_features();
582
583 dscene.data.kernel_features = kernel_features;
584
585 /* Currently viewport render is faster with higher max_closures, needs
586 * investigating. */
587 const uint max_closures = (params.background) ? get_max_closure_count() : MAX_CLOSURE;
588 dscene.data.max_closures = max_closures;
589 dscene.data.max_shaders = shaders.size();
590}
591
593{
594 if (!need_update()) {
595 return false;
596 }
597
598 /* Upload scene data to the GPU. */
599 progress.set_status("Updating Scene");
601
602 return true;
603}
604
606{
607 if (!camera->set_screen_size(width, height)) {
608 return false;
609 }
610
611 camera->device_update(device, &dscene, this);
612
613 progress.set_status("Updating Device", "Writing constant memory");
614 device->const_copy_to("data", &dscene.data, sizeof(dscene.data));
615 return true;
616}
617
618static void log_kernel_features(const uint features)
619{
620 VLOG_INFO << "Requested features:\n";
621 VLOG_INFO << "Use BSDF " << string_from_bool(features & KERNEL_FEATURE_NODE_BSDF) << "\n";
622 VLOG_INFO << "Use Emission " << string_from_bool(features & KERNEL_FEATURE_NODE_EMISSION)
623 << "\n";
624 VLOG_INFO << "Use Volume " << string_from_bool(features & KERNEL_FEATURE_NODE_VOLUME) << "\n";
625 VLOG_INFO << "Use Bump " << string_from_bool(features & KERNEL_FEATURE_NODE_BUMP) << "\n";
626 VLOG_INFO << "Use Voronoi " << string_from_bool(features & KERNEL_FEATURE_NODE_VORONOI_EXTRA)
627 << "\n";
628 VLOG_INFO << "Use Shader Raytrace " << string_from_bool(features & KERNEL_FEATURE_NODE_RAYTRACE)
629 << "\n";
630 VLOG_INFO << "Use MNEE " << string_from_bool(features & KERNEL_FEATURE_MNEE) << "\n";
631 VLOG_INFO << "Use Transparent " << string_from_bool(features & KERNEL_FEATURE_TRANSPARENT)
632 << "\n";
633 VLOG_INFO << "Use Denoising " << string_from_bool(features & KERNEL_FEATURE_DENOISING) << "\n";
634 VLOG_INFO << "Use Path Tracing " << string_from_bool(features & KERNEL_FEATURE_PATH_TRACING)
635 << "\n";
636 VLOG_INFO << "Use Hair " << string_from_bool(features & KERNEL_FEATURE_HAIR) << "\n";
637 VLOG_INFO << "Use Pointclouds " << string_from_bool(features & KERNEL_FEATURE_POINTCLOUD)
638 << "\n";
639 VLOG_INFO << "Use Object Motion " << string_from_bool(features & KERNEL_FEATURE_OBJECT_MOTION)
640 << "\n";
641 VLOG_INFO << "Use Baking " << string_from_bool(features & KERNEL_FEATURE_BAKING) << "\n";
642 VLOG_INFO << "Use Subsurface " << string_from_bool(features & KERNEL_FEATURE_SUBSURFACE) << "\n";
643 VLOG_INFO << "Use Volume " << string_from_bool(features & KERNEL_FEATURE_VOLUME) << "\n";
644 VLOG_INFO << "Use Shadow Catcher " << string_from_bool(features & KERNEL_FEATURE_SHADOW_CATCHER)
645 << "\n";
646}
647
649{
650 progress.set_status("Loading render kernels (may take a few minutes the first time)");
651
652 const scoped_timer timer;
653
654 const uint kernel_features = dscene.data.kernel_features;
655 log_kernel_features(kernel_features);
656 if (!device->load_kernels(kernel_features)) {
657 string message = device->error_message();
658 if (message.empty()) {
659 message = "Failed loading render kernel, see console for errors";
660 }
661
662 progress.set_error(message);
663 progress.set_status(message);
664 progress.set_update();
665 return false;
666 }
667
668 kernels_loaded = true;
669 loaded_kernel_features = kernel_features;
670 return true;
671}
672
674{
675 if (shader_manager->use_osl()) {
676 /* OSL always needs the maximum as we can't predict the
677 * number of closures a shader might generate. */
678 return MAX_CLOSURE;
679 }
680
681 int max_closures = 0;
682 for (int i = 0; i < shaders.size(); i++) {
683 Shader *shader = shaders[i];
684 if (shader->reference_count()) {
685 const int num_closures = shader->graph->get_num_closures();
686 max_closures = max(max_closures, num_closures);
687 }
688 }
690
692 /* This is usually harmless as more complex shader tend to get many
693 * closures discarded due to mixing or low weights. We need to limit
694 * to MAX_CLOSURE as this is hardcoded in CPU/mega kernels, and it
695 * avoids excessive memory usage for split kernels. */
696 VLOG_WARNING << "Maximum number of closures exceeded: " << max_closure_global << " > "
697 << MAX_CLOSURE;
698
700 }
701
702 return max_closure_global;
703}
704
706{
707 int volume_stack_size = 0;
708
709 /* Space for background volume and terminator.
710 * Don't do optional here because camera ray initialization expects that there
711 * is space for at least those elements (avoiding extra condition to check if
712 * there is actual volume or not).
713 */
714 volume_stack_size += 2;
715
716 /* Quick non-expensive check. Can over-estimate maximum possible nested level,
717 * but does not require expensive calculation during pre-processing. */
718 bool has_volume_object = false;
719 for (const Object *object : objects) {
720 if (!object->get_geometry()->has_volume) {
721 continue;
722 }
723
724 if (object->intersects_volume) {
725 /* Object intersects another volume, assume it's possible to go deeper in
726 * the stack. */
727 /* TODO(sergey): This might count nesting twice (A intersects B and B
728 * intersects A), but can't think of a computationally cheap algorithm.
729 * Dividing my 2 doesn't work because of Venn diagram example with 3
730 * circles. */
731 ++volume_stack_size;
732 }
733 else if (!has_volume_object) {
734 /* Allocate space for at least one volume object. */
735 ++volume_stack_size;
736 }
737
738 has_volume_object = true;
739
740 if (volume_stack_size == MAX_VOLUME_STACK_SIZE) {
741 break;
742 }
743 }
744
745 volume_stack_size = min(volume_stack_size, MAX_VOLUME_STACK_SIZE);
746
747 VLOG_WORK << "Detected required volume stack size " << volume_stack_size;
748
749 return volume_stack_size;
750}
751
753{
755 has_shadow_catcher_ = false;
756 for (Object *object : objects) {
757 /* Shadow catcher flags on lights only controls effect on other objects, it's
758 * not catching shadows itself. This is on by default, so ignore to avoid
759 * performance impact when there is no actual shadow catcher. */
760 if (object->get_is_shadow_catcher() && !object->get_geometry()->is_light()) {
761 has_shadow_catcher_ = true;
762 break;
763 }
764 }
765
767 }
768
769 return has_shadow_catcher_;
770}
771
776
778{
779 unique_ptr<Light> node = make_unique<Light>();
780 Light *node_ptr = node.get();
781 node->set_owner(this);
782 geometry.push_back(std::move(node));
783 light_manager->tag_update(this, LightManager::LIGHT_ADDED);
784 return node_ptr;
785}
786
788{
789 unique_ptr<Mesh> node = make_unique<Mesh>();
790 Mesh *node_ptr = node.get();
791 node->set_owner(this);
792 geometry.push_back(std::move(node));
794 return node_ptr;
795}
796
798{
799 unique_ptr<Hair> node = make_unique<Hair>();
800 Hair *node_ptr = node.get();
801 node->set_owner(this);
802 geometry.push_back(std::move(node));
804 return node_ptr;
805}
806
808{
809 unique_ptr<Volume> node = make_unique<Volume>();
810 Volume *node_ptr = node.get();
811 node->set_owner(this);
812 geometry.push_back(std::move(node));
814 return node_ptr;
815}
816
818{
819 unique_ptr<PointCloud> node = make_unique<PointCloud>();
820 PointCloud *node_ptr = node.get();
821 node->set_owner(this);
822 geometry.push_back(std::move(node));
824 return node_ptr;
825}
826
828{
829 unique_ptr<Object> node = make_unique<Object>();
830 Object *node_ptr = node.get();
831 node->set_owner(this);
832 objects.push_back(std::move(node));
834 return node_ptr;
835}
836
838{
839 unique_ptr<ParticleSystem> node = make_unique<ParticleSystem>();
840 ParticleSystem *node_ptr = node.get();
841 node->set_owner(this);
842 particle_systems.push_back(std::move(node));
843 particle_system_manager->tag_update(this);
844 return node_ptr;
845}
846
848{
849 unique_ptr<Shader> node = make_unique<Shader>();
850 Shader *node_ptr = node.get();
851 node->set_owner(this);
852 shaders.push_back(std::move(node));
854 return node_ptr;
855}
856
857template<> AlembicProcedural *Scene::create_node<AlembicProcedural>()
858{
859#ifdef WITH_ALEMBIC
860 unique_ptr<AlembicProcedural> node = make_unique<AlembicProcedural>();
861 AlembicProcedural *node_ptr = node.get();
862 node->set_owner(this);
863 procedurals.push_back(std::move(node));
864 procedural_manager->tag_update();
865 return node_ptr;
866#else
867 return nullptr;
868#endif
869}
870
872{
873 unique_ptr<Pass> node = make_unique<Pass>();
874 Pass *node_ptr = node.get();
875 node->set_owner(this);
876 passes.push_back(std::move(node));
877 film->tag_modified();
878 return node_ptr;
879}
880
882{
883 unique_ptr<Camera> node = make_unique<Camera>();
884 Camera *node_ptr = node.get();
885 node->set_owner(this);
886 cameras.push_back(std::move(node));
887 return node_ptr;
888}
889
891{
892 unique_ptr<Integrator> node = make_unique<Integrator>();
893 Integrator *node_ptr = node.get();
894 node->set_owner(this);
895 integrators.push_back(std::move(node));
896 return node_ptr;
897}
898
900{
901 unique_ptr<Background> node = make_unique<Background>();
902 Background *node_ptr = node.get();
903 node->set_owner(this);
904 backgrounds.push_back(std::move(node));
905 return node_ptr;
906}
907
909{
910 unique_ptr<Film> node = make_unique<Film>();
911 Film *node_ptr = node.get();
912 node->set_owner(this);
913 films.push_back(std::move(node));
914 return node_ptr;
915}
916
917template<> void Scene::delete_node(Light *node)
918{
919 assert(node->get_owner() == this);
920 geometry.erase_by_swap(node);
922}
923
924template<> void Scene::delete_node(Mesh *node)
925{
926 assert(node->get_owner() == this);
927 geometry.erase_by_swap(node);
929}
930
931template<> void Scene::delete_node(Hair *node)
932{
933 assert(node->get_owner() == this);
934 geometry.erase_by_swap(node);
936}
937
938template<> void Scene::delete_node(Volume *node)
939{
940 assert(node->get_owner() == this);
941 geometry.erase_by_swap(node);
943}
944
945template<> void Scene::delete_node(PointCloud *node)
946{
947 assert(node->get_owner() == this);
948 geometry.erase_by_swap(node);
950}
951
952template<> void Scene::delete_node(Geometry *node)
953{
954 assert(node->get_owner() == this);
955
956 uint flag;
957 if (node->is_hair()) {
959 }
960 else {
962 }
963
964 geometry.erase_by_swap(node);
965 geometry_manager->tag_update(this, flag);
966}
967
968template<> void Scene::delete_node(Object *node)
969{
970 assert(node->get_owner() == this);
971 objects.erase_by_swap(node);
973}
974
975template<> void Scene::delete_node(ParticleSystem *node)
976{
977 assert(node->get_owner() == this);
978 particle_systems.erase_by_swap(node);
979 particle_system_manager->tag_update(this);
980}
981
982template<> void Scene::delete_node(Shader *node)
983{
984 assert(node->get_owner() == this);
985 /* don't delete unused shaders, not supported */
986 node->clear_reference_count();
987}
988
989template<> void Scene::delete_node(Procedural *node)
990{
991 assert(node->get_owner() == this);
992 procedurals.erase_by_swap(node);
993 procedural_manager->tag_update();
994}
995
996template<> void Scene::delete_node(AlembicProcedural *node)
997{
998#ifdef WITH_ALEMBIC
999 delete_node(static_cast<Procedural *>(node));
1000#else
1001 (void)node;
1002#endif
1003}
1004
1005template<> void Scene::delete_node(Pass *node)
1006{
1007 assert(node->get_owner() == this);
1008 passes.erase_by_swap(node);
1009 film->tag_modified();
1010}
1011
1012template<typename T> static void assert_same_owner(const set<T *> &nodes, const NodeOwner *owner)
1013{
1014#ifdef NDEBUG
1015 (void)nodes;
1016 (void)owner;
1017#else
1018 for (const T *node : nodes) {
1019 assert(node->get_owner() == owner);
1020 }
1021#endif
1022}
1023
1024template<> void Scene::delete_nodes(const set<Geometry *> &nodes, const NodeOwner *owner)
1025{
1026 assert_same_owner(nodes, owner);
1027 geometry.erase_in_set(nodes);
1029 light_manager->tag_update(this, LightManager::LIGHT_REMOVED);
1030}
1031
1032template<> void Scene::delete_nodes(const set<Object *> &nodes, const NodeOwner *owner)
1033{
1034 assert_same_owner(nodes, owner);
1035 objects.erase_in_set(nodes);
1037}
1038
1039template<> void Scene::delete_nodes(const set<ParticleSystem *> &nodes, const NodeOwner *owner)
1040{
1041 assert_same_owner(nodes, owner);
1042 particle_systems.erase_in_set(nodes);
1043 particle_system_manager->tag_update(this);
1044}
1045
1046template<> void Scene::delete_nodes(const set<Shader *> &nodes, const NodeOwner * /*owner*/)
1047{
1048 /* don't delete unused shaders, not supported */
1049 for (Shader *shader : nodes) {
1050 shader->clear_reference_count();
1051 }
1052}
1053
1054template<> void Scene::delete_nodes(const set<Procedural *> &nodes, const NodeOwner *owner)
1055{
1056 assert_same_owner(nodes, owner);
1057 procedurals.erase_in_set(nodes);
1058 procedural_manager->tag_update();
1059}
1060
1061template<> void Scene::delete_nodes(const set<Pass *> &nodes, const NodeOwner *owner)
1062{
1063 assert_same_owner(nodes, owner);
1064 passes.erase_in_set(nodes);
1065 film->tag_modified();
1066}
1067
unsigned int uint
float progress
Definition WM_types.hh:1019
void add(ustring name)
Definition film.h:29
bool is_light() const
bool is_pointcloud() const
bool is_hair() const
Definition hair.h:13
Definition pass.h:49
static bool contains(const unique_ptr_vector< Pass > &passes, PassType type)
Definition pass.cpp:367
static unique_ptr< ShaderManager > create(const int shadingsystem)
static void add_default(Scene *scene)
NODE_DECLARE unique_ptr< ShaderGraph > graph
#define KERNEL_FEATURE_VOLUME
#define MAX_VOLUME_STACK_SIZE
#define KERNEL_FEATURE_SHADOW_CATCHER
#define KERNEL_FEATURE_OBJECT_MOTION
#define KERNEL_FEATURE_PATH_GUIDING
#define KERNEL_FEATURE_TRANSPARENT
#define KERNEL_FEATURE_SUBSURFACE
#define KERNEL_FEATURE_NODE_BSDF
#define KERNEL_FEATURE_HAIR_THICK
#define KERNEL_FEATURE_NODE_VORONOI_EXTRA
#define KERNEL_FEATURE_NODE_VOLUME
#define KERNEL_FEATURE_PATH_TRACING
#define MAX_CLOSURE
#define KERNEL_FEATURE_SHADOW_LINKING
#define KERNEL_FEATURE_DENOISING
#define KERNEL_FEATURE_LIGHT_LINKING
#define KERNEL_FEATURE_HAIR
#define KERNEL_FEATURE_NODE_RAYTRACE
#define KERNEL_FEATURE_BAKING
#define KERNEL_FEATURE_MNEE
#define KERNEL_FEATURE_POINTCLOUD
#define KERNEL_FEATURE_NODE_EMISSION
#define KERNEL_FEATURE_NODE_BUMP
#define CCL_NAMESPACE_END
#define assert(assertion)
#define printf(...)
#define MEM_GUARDED_CALL(progress, func,...)
size_t util_guarded_get_mem_used()
size_t util_guarded_get_mem_peak()
AttributeStandard
@ ATTR_STD_UV
@ ATTR_STD_MOTION_VERTEX_NORMAL
@ ATTR_STD_VOLUME_VELOCITY_Y
@ ATTR_STD_NONE
@ ATTR_STD_VOLUME_VELOCITY_Z
@ ATTR_STD_NUM
@ ATTR_STD_VOLUME_VELOCITY
@ ATTR_STD_MOTION_VERTEX_POSITION
@ ATTR_STD_VOLUME_VELOCITY_X
@ CURVE_THICK
@ PASS_UV
@ PASS_MOTION
#define VLOG_INFO
Definition log.h:71
#define VLOG_WARNING
Definition log.h:69
#define VLOG_WORK
Definition log.h:74
#define T
@ SHADINGSYSTEM_SVM
static void assert_same_owner(const set< T * > &nodes, const NodeOwner *owner)
Definition scene.cpp:1012
static void log_kernel_features(const uint features)
Definition scene.cpp:618
#define min(a, b)
Definition sort.cc:36
string string_from_bool(bool var)
Definition string.cpp:183
string string_human_readable_size(size_t size)
Definition string.cpp:257
string string_human_readable_number(size_t num)
Definition string.cpp:276
int reference_count() const
Definition graph/node.h:183
const NodeOwner * get_owner() const
void clear_reference_count()
Definition graph/node.h:201
bool kernels_loaded
Definition scene.h:240
unique_ptr_vector< Procedural > procedurals
Definition scene.h:142
Film * film
Definition scene.h:128
string name
Definition scene.h:117
unique_ptr< ObjectManager > object_manager
Definition scene.h:150
bool need_global_attribute(AttributeStandard std)
Definition scene.cpp:418
MotionType need_motion() const
Definition scene.cpp:399
void need_global_attributes(AttributeRequestSet &attributes)
Definition scene.cpp:438
bool update(Progress &progress)
Definition scene.cpp:592
unique_ptr< LightManager > light_manager
Definition scene.h:146
Device * device
Definition scene.h:163
unique_ptr< ParticleSystemManager > particle_system_manager
Definition scene.h:151
int get_max_closure_count()
Definition scene.cpp:673
bool scene_updated_while_loading_kernels
Definition scene.h:171
void device_free()
Definition scene.cpp:487
bool has_shadow_catcher_
Definition scene.h:245
Shader * default_volume
Definition scene.h:157
Camera * dicing_camera
Definition scene.h:127
SceneParams params
Definition scene.h:167
unique_ptr_vector< Geometry > geometry
Definition scene.h:140
Shader * default_surface
Definition scene.h:156
unique_ptr< SceneUpdateStats > update_stats
Definition scene.h:174
void tag_shadow_catcher_modified()
Definition scene.cpp:772
void free_memory(bool final)
Definition scene.cpp:85
unique_ptr_vector< Camera > cameras
Definition scene.h:136
Shader * default_empty
Definition scene.h:160
unique_ptr_vector< Background > backgrounds
Definition scene.h:133
void enable_update_stats()
Definition scene.cpp:498
Shader * default_background
Definition scene.h:159
uint loaded_kernel_features
Definition scene.h:241
Light * create_node()
Definition scene.cpp:777
unique_ptr< BakeManager > bake_manager
Definition scene.h:152
bool shadow_catcher_modified_
Definition scene.h:246
Background * background
Definition scene.h:129
unique_ptr_vector< Shader > shaders
Definition scene.h:137
MotionType
Definition scene.h:184
@ MOTION_PASS
Definition scene.h:184
@ MOTION_NONE
Definition scene.h:184
@ MOTION_BLUR
Definition scene.h:184
void update_kernel_features()
Definition scene.cpp:505
unique_ptr< ShaderManager > shader_manager
Definition scene.h:148
void delete_nodes(const set< T * > &nodes)
Definition scene.h:223
unique_ptr_vector< ParticleSystem > particle_systems
Definition scene.h:139
bool has_shadow_catcher()
Definition scene.cpp:752
unique_ptr< GeometryManager > geometry_manager
Definition scene.h:149
void delete_node(T *node)=delete
~Scene() override
Definition scene.cpp:80
unique_ptr< OSLManager > osl_manager
Definition scene.h:147
unique_ptr_vector< Integrator > integrators
Definition scene.h:135
bool load_kernels(Progress &progress)
Definition scene.cpp:648
int max_closure_global
Definition scene.h:249
unique_ptr_vector< Object > objects
Definition scene.h:141
Integrator * integrator
Definition scene.h:130
thread_mutex mutex
Definition scene.h:170
bool need_data_update()
Definition scene.cpp:452
int get_volume_stack_size() const
Definition scene.cpp:705
unique_ptr< ImageManager > image_manager
Definition scene.h:145
unique_ptr< ProceduralManager > procedural_manager
Definition scene.h:153
bool need_reset(const bool check_camera=true)
Definition scene.cpp:462
struct Object * camera
bool need_update()
Definition scene.cpp:447
Shader * default_light
Definition scene.h:158
unique_ptr< BVH > bvh
Definition scene.h:123
bool update_camera_resolution(Progress &progress, int width, int height)
Definition scene.cpp:605
void reset()
Definition scene.cpp:467
void collect_statistics(RenderStats *stats)
Definition scene.cpp:492
unique_ptr_vector< Pass > passes
Definition scene.h:138
unique_ptr_vector< Film > films
Definition scene.h:134
DeviceScene dscene
Definition scene.h:164
float motion_shutter_time()
Definition scene.cpp:410
struct Scene * set
unique_ptr< LookupTables > lookup_tables
Definition scene.h:124
void device_update(Device *device, Progress &progress)
Definition scene.cpp:168
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251
wmTimer * timer