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