Merge remote-tracking branch 'origin/blender-v2.93-release'
[blender.git] / intern / cycles / render / scene.cpp
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdlib.h>
18
19 #include "bvh/bvh.h"
20 #include "device/device.h"
21 #include "render/alembic.h"
22 #include "render/background.h"
23 #include "render/bake.h"
24 #include "render/camera.h"
25 #include "render/curves.h"
26 #include "render/film.h"
27 #include "render/integrator.h"
28 #include "render/light.h"
29 #include "render/mesh.h"
30 #include "render/object.h"
31 #include "render/osl.h"
32 #include "render/particles.h"
33 #include "render/procedural.h"
34 #include "render/scene.h"
35 #include "render/session.h"
36 #include "render/shader.h"
37 #include "render/svm.h"
38 #include "render/tables.h"
39 #include "render/volume.h"
40
41 #include "util/util_foreach.h"
42 #include "util/util_guarded_allocator.h"
43 #include "util/util_logging.h"
44 #include "util/util_progress.h"
45
46 CCL_NAMESPACE_BEGIN
47
48 DeviceScene::DeviceScene(Device *device)
49     : bvh_nodes(device, "__bvh_nodes", MEM_GLOBAL),
50       bvh_leaf_nodes(device, "__bvh_leaf_nodes", MEM_GLOBAL),
51       object_node(device, "__object_node", MEM_GLOBAL),
52       prim_tri_index(device, "__prim_tri_index", MEM_GLOBAL),
53       prim_tri_verts(device, "__prim_tri_verts", MEM_GLOBAL),
54       prim_type(device, "__prim_type", MEM_GLOBAL),
55       prim_visibility(device, "__prim_visibility", MEM_GLOBAL),
56       prim_index(device, "__prim_index", MEM_GLOBAL),
57       prim_object(device, "__prim_object", MEM_GLOBAL),
58       prim_time(device, "__prim_time", MEM_GLOBAL),
59       tri_shader(device, "__tri_shader", MEM_GLOBAL),
60       tri_vnormal(device, "__tri_vnormal", MEM_GLOBAL),
61       tri_vindex(device, "__tri_vindex", MEM_GLOBAL),
62       tri_patch(device, "__tri_patch", MEM_GLOBAL),
63       tri_patch_uv(device, "__tri_patch_uv", MEM_GLOBAL),
64       curves(device, "__curves", MEM_GLOBAL),
65       curve_keys(device, "__curve_keys", MEM_GLOBAL),
66       patches(device, "__patches", MEM_GLOBAL),
67       objects(device, "__objects", MEM_GLOBAL),
68       object_motion_pass(device, "__object_motion_pass", MEM_GLOBAL),
69       object_motion(device, "__object_motion", MEM_GLOBAL),
70       object_flag(device, "__object_flag", MEM_GLOBAL),
71       object_volume_step(device, "__object_volume_step", MEM_GLOBAL),
72       camera_motion(device, "__camera_motion", MEM_GLOBAL),
73       attributes_map(device, "__attributes_map", MEM_GLOBAL),
74       attributes_float(device, "__attributes_float", MEM_GLOBAL),
75       attributes_float2(device, "__attributes_float2", MEM_GLOBAL),
76       attributes_float3(device, "__attributes_float3", MEM_GLOBAL),
77       attributes_uchar4(device, "__attributes_uchar4", MEM_GLOBAL),
78       light_distribution(device, "__light_distribution", MEM_GLOBAL),
79       lights(device, "__lights", MEM_GLOBAL),
80       light_background_marginal_cdf(device, "__light_background_marginal_cdf", MEM_GLOBAL),
81       light_background_conditional_cdf(device, "__light_background_conditional_cdf", MEM_GLOBAL),
82       particles(device, "__particles", MEM_GLOBAL),
83       svm_nodes(device, "__svm_nodes", MEM_GLOBAL),
84       shaders(device, "__shaders", MEM_GLOBAL),
85       lookup_table(device, "__lookup_table", MEM_GLOBAL),
86       sample_pattern_lut(device, "__sample_pattern_lut", MEM_GLOBAL),
87       ies_lights(device, "__ies", MEM_GLOBAL)
88 {
89   memset((void *)&data, 0, sizeof(data));
90 }
91
92 Scene::Scene(const SceneParams &params_, Device *device)
93     : name("Scene"),
94       bvh(NULL),
95       default_surface(NULL),
96       default_volume(NULL),
97       default_light(NULL),
98       default_background(NULL),
99       default_empty(NULL),
100       device(device),
101       dscene(device),
102       params(params_),
103       update_stats(NULL),
104       kernels_loaded(false),
105       /* TODO(sergey): Check if it's indeed optimal value for the split kernel. */
106       max_closure_global(1)
107 {
108   memset((void *)&dscene.data, 0, sizeof(dscene.data));
109
110   /* OSL only works on the CPU */
111   if (device->info.has_osl)
112     shader_manager = ShaderManager::create(params.shadingsystem);
113   else
114     shader_manager = ShaderManager::create(SHADINGSYSTEM_SVM);
115
116   light_manager = new LightManager();
117   geometry_manager = new GeometryManager();
118   object_manager = new ObjectManager();
119   image_manager = new ImageManager(device->info);
120   particle_system_manager = new ParticleSystemManager();
121   bake_manager = new BakeManager();
122   procedural_manager = new ProceduralManager();
123
124   /* Create nodes after managers, since create_node() can tag the managers. */
125   camera = create_node<Camera>();
126   dicing_camera = create_node<Camera>();
127   lookup_tables = new LookupTables();
128   film = create_node<Film>();
129   background = create_node<Background>();
130   integrator = create_node<Integrator>();
131
132   film->add_default(this);
133   shader_manager->add_default(this);
134 }
135
136 Scene::~Scene()
137 {
138   free_memory(true);
139 }
140
141 void Scene::free_memory(bool final)
142 {
143   delete bvh;
144   bvh = NULL;
145
146   /* The order of deletion is important to make sure data is freed based on possible dependencies
147    * as the Nodes' reference counts are decremented in the destructors:
148    *
149    * - Procedurals can create and hold pointers to any other types.
150    * - Objects can hold pointers to Geometries and ParticleSystems
151    * - Lights and Geometries can hold pointers to Shaders.
152    *
153    * Similarly, we first delete all nodes and their associated device data, and then the managers
154    * and their associated device data.
155    */
156   foreach (Procedural *p, procedurals)
157     delete p;
158   foreach (Object *o, objects)
159     delete o;
160   foreach (Geometry *g, geometry)
161     delete g;
162   foreach (ParticleSystem *p, particle_systems)
163     delete p;
164   foreach (Light *l, lights)
165     delete l;
166
167   geometry.clear();
168   objects.clear();
169   lights.clear();
170   particle_systems.clear();
171   procedurals.clear();
172
173   if (device) {
174     camera->device_free(device, &dscene, this);
175     film->device_free(device, &dscene, this);
176     background->device_free(device, &dscene);
177     integrator->device_free(device, &dscene, true);
178   }
179
180   if (final) {
181     delete camera;
182     delete dicing_camera;
183     delete film;
184     delete background;
185     delete integrator;
186   }
187
188   /* Delete Shaders after every other nodes to ensure that we do not try to decrement the reference
189    * count on some dangling pointer. */
190   foreach (Shader *s, shaders)
191     delete s;
192
193   shaders.clear();
194
195   /* Now that all nodes have been deleted, we can safely delete managers and device data. */
196   if (device) {
197     object_manager->device_free(device, &dscene, true);
198     geometry_manager->device_free(device, &dscene, true);
199     shader_manager->device_free(device, &dscene, this);
200     light_manager->device_free(device, &dscene);
201
202     particle_system_manager->device_free(device, &dscene);
203
204     bake_manager->device_free(device, &dscene);
205
206     if (final)
207       image_manager->device_free(device);
208     else
209       image_manager->device_free_builtin(device);
210
211     lookup_tables->device_free(device, &dscene);
212   }
213
214   if (final) {
215     delete lookup_tables;
216     delete object_manager;
217     delete geometry_manager;
218     delete shader_manager;
219     delete light_manager;
220     delete particle_system_manager;
221     delete image_manager;
222     delete bake_manager;
223     delete update_stats;
224     delete procedural_manager;
225   }
226 }
227
228 void Scene::device_update(Device *device_, Progress &progress)
229 {
230   if (!device)
231     device = device_;
232
233   bool print_stats = need_data_update();
234
235   if (update_stats) {
236     update_stats->clear();
237   }
238
239   scoped_callback_timer timer([this, print_stats](double time) {
240     if (update_stats) {
241       update_stats->scene.times.add_entry({"device_update", time});
242
243       if (print_stats) {
244         printf("Update statistics:\n%s\n", update_stats->full_report().c_str());
245       }
246     }
247   });
248
249   /* The order of updates is important, because there's dependencies between
250    * the different managers, using data computed by previous managers.
251    *
252    * - Image manager uploads images used by shaders.
253    * - Camera may be used for adaptive subdivision.
254    * - Displacement shader must have all shader data available.
255    * - Light manager needs lookup tables and final mesh data to compute emission CDF.
256    * - Film needs light manager to run for use_light_visibility
257    * - Lookup tables are done a second time to handle film tables
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");
272   background->device_update(device, &dscene, this);
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
283   geometry_manager->device_update_preprocess(device, this, progress);
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");
295   particle_system_manager->device_update(device, &dscene, this, progress);
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 Images");
313   image_manager->device_update(device, this, progress);
314
315   if (progress.get_cancel() || device->have_error())
316     return;
317
318   progress.set_status("Updating Camera Volume");
319   camera->device_update_volume(device, &dscene, this);
320
321   if (progress.get_cancel() || device->have_error())
322     return;
323
324   progress.set_status("Updating Lookup Tables");
325   lookup_tables->device_update(device, &dscene, this);
326
327   if (progress.get_cancel() || device->have_error())
328     return;
329
330   progress.set_status("Updating Lights");
331   light_manager->device_update(device, &dscene, this, progress);
332
333   if (progress.get_cancel() || device->have_error())
334     return;
335
336   progress.set_status("Updating Integrator");
337   integrator->device_update(device, &dscene, this);
338
339   if (progress.get_cancel() || device->have_error())
340     return;
341
342   progress.set_status("Updating Film");
343   film->device_update(device, &dscene, this);
344
345   if (progress.get_cancel() || device->have_error())
346     return;
347
348   progress.set_status("Updating Lookup Tables");
349   lookup_tables->device_update(device, &dscene, this);
350
351   if (progress.get_cancel() || device->have_error())
352     return;
353
354   progress.set_status("Updating Baking");
355   bake_manager->device_update(device, &dscene, this, progress);
356
357   if (progress.get_cancel() || device->have_error())
358     return;
359
360   if (device->have_error() == false) {
361     progress.set_status("Updating Device", "Writing constant memory");
362     device->const_copy_to("__data", &dscene.data, sizeof(dscene.data));
363   }
364
365   if (print_stats) {
366     size_t mem_used = util_guarded_get_mem_used();
367     size_t mem_peak = util_guarded_get_mem_peak();
368
369     VLOG(1) << "System memory statistics after full device sync:\n"
370             << "  Usage: " << string_human_readable_number(mem_used) << " ("
371             << string_human_readable_size(mem_used) << ")\n"
372             << "  Peak: " << string_human_readable_number(mem_peak) << " ("
373             << string_human_readable_size(mem_peak) << ")";
374   }
375 }
376
377 Scene::MotionType Scene::need_motion()
378 {
379   if (integrator->get_motion_blur())
380     return MOTION_BLUR;
381   else if (Pass::contains(passes, PASS_MOTION))
382     return MOTION_PASS;
383   else
384     return MOTION_NONE;
385 }
386
387 float Scene::motion_shutter_time()
388 {
389   if (need_motion() == Scene::MOTION_PASS)
390     return 2.0f;
391   else
392     return camera->get_shuttertime();
393 }
394
395 bool Scene::need_global_attribute(AttributeStandard std)
396 {
397   if (std == ATTR_STD_UV)
398     return Pass::contains(passes, PASS_UV);
399   else if (std == ATTR_STD_MOTION_VERTEX_POSITION)
400     return need_motion() != MOTION_NONE;
401   else if (std == ATTR_STD_MOTION_VERTEX_NORMAL)
402     return need_motion() == MOTION_BLUR;
403
404   return false;
405 }
406
407 void Scene::need_global_attributes(AttributeRequestSet &attributes)
408 {
409   for (int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++)
410     if (need_global_attribute((AttributeStandard)std))
411       attributes.add((AttributeStandard)std);
412 }
413
414 bool Scene::need_update()
415 {
416   return (need_reset() || film->is_modified());
417 }
418
419 bool Scene::need_data_update()
420 {
421   return (background->is_modified() || image_manager->need_update() ||
422           object_manager->need_update() || geometry_manager->need_update() ||
423           light_manager->need_update() || lookup_tables->need_update() ||
424           integrator->is_modified() || shader_manager->need_update() ||
425           particle_system_manager->need_update() || bake_manager->need_update() ||
426           film->is_modified() || procedural_manager->need_update());
427 }
428
429 bool Scene::need_reset()
430 {
431   return need_data_update() || camera->is_modified();
432 }
433
434 void Scene::reset()
435 {
436   shader_manager->reset(this);
437   shader_manager->add_default(this);
438
439   /* ensure all objects are updated */
440   camera->tag_modified();
441   dicing_camera->tag_modified();
442   film->tag_modified();
443   background->tag_modified();
444
445   background->tag_update(this);
446   integrator->tag_update(this, Integrator::UPDATE_ALL);
447   object_manager->tag_update(this, ObjectManager::UPDATE_ALL);
448   geometry_manager->tag_update(this, GeometryManager::UPDATE_ALL);
449   light_manager->tag_update(this, LightManager::UPDATE_ALL);
450   particle_system_manager->tag_update(this);
451   procedural_manager->tag_update();
452 }
453
454 void Scene::device_free()
455 {
456   free_memory(false);
457 }
458
459 void Scene::collect_statistics(RenderStats *stats)
460 {
461   geometry_manager->collect_statistics(this, stats);
462   image_manager->collect_statistics(stats);
463 }
464
465 void Scene::enable_update_stats()
466 {
467   if (!update_stats) {
468     update_stats = new SceneUpdateStats();
469   }
470 }
471
472 DeviceRequestedFeatures Scene::get_requested_device_features()
473 {
474   DeviceRequestedFeatures requested_features;
475
476   shader_manager->get_requested_features(this, &requested_features);
477
478   /* This features are not being tweaked as often as shaders,
479    * so could be done selective magic for the viewport as well.
480    */
481   bool use_motion = need_motion() == Scene::MotionType::MOTION_BLUR;
482   requested_features.use_hair = false;
483   requested_features.use_hair_thick = (params.hair_shape == CURVE_THICK);
484   requested_features.use_object_motion = false;
485   requested_features.use_camera_motion = use_motion && camera->use_motion();
486   foreach (Object *object, objects) {
487     Geometry *geom = object->get_geometry();
488     if (use_motion) {
489       requested_features.use_object_motion |= object->use_motion() | geom->get_use_motion_blur();
490       requested_features.use_camera_motion |= geom->get_use_motion_blur();
491     }
492     if (object->get_is_shadow_catcher()) {
493       requested_features.use_shadow_tricks = true;
494     }
495     if (geom->is_mesh()) {
496       Mesh *mesh = static_cast<Mesh *>(geom);
497 #ifdef WITH_OPENSUBDIV
498       if (mesh->get_subdivision_type() != Mesh::SUBDIVISION_NONE) {
499         requested_features.use_patch_evaluation = true;
500       }
501 #endif
502       requested_features.use_true_displacement |= mesh->has_true_displacement();
503     }
504     else if (geom->is_hair()) {
505       requested_features.use_hair = true;
506     }
507   }
508
509   requested_features.use_background_light = light_manager->has_background_light(this);
510
511   requested_features.use_baking = bake_manager->get_baking();
512   requested_features.use_integrator_branched = (integrator->get_method() ==
513                                                 Integrator::BRANCHED_PATH);
514   if (film->get_denoising_data_pass()) {
515     requested_features.use_denoising = true;
516     requested_features.use_shadow_tricks = true;
517   }
518
519   return requested_features;
520 }
521
522 bool Scene::update(Progress &progress, bool &kernel_switch_needed)
523 {
524   /* update scene */
525   if (need_update()) {
526     /* Update max_closures. */
527     KernelIntegrator *kintegrator = &dscene.data.integrator;
528     if (params.background) {
529       kintegrator->max_closures = get_max_closure_count();
530     }
531     else {
532       /* Currently viewport render is faster with higher max_closures, needs investigating. */
533       kintegrator->max_closures = MAX_CLOSURE;
534     }
535
536     /* Load render kernels, before device update where we upload data to the GPU. */
537     bool new_kernels_needed = load_kernels(progress, false);
538
539     progress.set_status("Updating Scene");
540     MEM_GUARDED_CALL(&progress, device_update, device, progress);
541
542     DeviceKernelStatus kernel_switch_status = device->get_active_kernel_switch_state();
543     kernel_switch_needed = kernel_switch_status == DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE ||
544                            kernel_switch_status == DEVICE_KERNEL_FEATURE_KERNEL_INVALID;
545     if (new_kernels_needed || kernel_switch_needed) {
546       progress.set_kernel_status("Compiling render kernels");
547       device->wait_for_availability(loaded_kernel_features);
548       progress.set_kernel_status("");
549     }
550
551     return true;
552   }
553   return false;
554 }
555
556 bool Scene::load_kernels(Progress &progress, bool lock_scene)
557 {
558   thread_scoped_lock scene_lock;
559   if (lock_scene) {
560     scene_lock = thread_scoped_lock(mutex);
561   }
562
563   DeviceRequestedFeatures requested_features = get_requested_device_features();
564
565   if (!kernels_loaded || loaded_kernel_features.modified(requested_features)) {
566     progress.set_status("Loading render kernels (may take a few minutes the first time)");
567
568     scoped_timer timer;
569
570     VLOG(2) << "Requested features:\n" << requested_features;
571     if (!device->load_kernels(requested_features)) {
572       string message = device->error_message();
573       if (message.empty())
574         message = "Failed loading render kernel, see console for errors";
575
576       progress.set_error(message);
577       progress.set_status(message);
578       progress.set_update();
579       return false;
580     }
581
582     kernels_loaded = true;
583     loaded_kernel_features = requested_features;
584     return true;
585   }
586   return false;
587 }
588
589 int Scene::get_max_closure_count()
590 {
591   if (shader_manager->use_osl()) {
592     /* OSL always needs the maximum as we can't predict the
593      * number of closures a shader might generate. */
594     return MAX_CLOSURE;
595   }
596
597   int max_closures = 0;
598   for (int i = 0; i < shaders.size(); i++) {
599     Shader *shader = shaders[i];
600     if (shader->reference_count()) {
601       int num_closures = shader->graph->get_num_closures();
602       max_closures = max(max_closures, num_closures);
603     }
604   }
605   max_closure_global = max(max_closure_global, max_closures);
606
607   if (max_closure_global > MAX_CLOSURE) {
608     /* This is usually harmless as more complex shader tend to get many
609      * closures discarded due to mixing or low weights. We need to limit
610      * to MAX_CLOSURE as this is hardcoded in CPU/mega kernels, and it
611      * avoids excessive memory usage for split kernels. */
612     VLOG(2) << "Maximum number of closures exceeded: " << max_closure_global << " > "
613             << MAX_CLOSURE;
614
615     max_closure_global = MAX_CLOSURE;
616   }
617
618   return max_closure_global;
619 }
620
621 template<> Light *Scene::create_node<Light>()
622 {
623   Light *node = new Light();
624   node->set_owner(this);
625   lights.push_back(node);
626   light_manager->tag_update(this, LightManager::LIGHT_ADDED);
627   return node;
628 }
629
630 template<> Mesh *Scene::create_node<Mesh>()
631 {
632   Mesh *node = new Mesh();
633   node->set_owner(this);
634   geometry.push_back(node);
635   geometry_manager->tag_update(this, GeometryManager::MESH_ADDED);
636   return node;
637 }
638
639 template<> Hair *Scene::create_node<Hair>()
640 {
641   Hair *node = new Hair();
642   node->set_owner(this);
643   geometry.push_back(node);
644   geometry_manager->tag_update(this, GeometryManager::HAIR_ADDED);
645   return node;
646 }
647
648 template<> Volume *Scene::create_node<Volume>()
649 {
650   Volume *node = new Volume();
651   node->set_owner(this);
652   geometry.push_back(node);
653   geometry_manager->tag_update(this, GeometryManager::MESH_ADDED);
654   return node;
655 }
656
657 template<> Object *Scene::create_node<Object>()
658 {
659   Object *node = new Object();
660   node->set_owner(this);
661   objects.push_back(node);
662   object_manager->tag_update(this, ObjectManager::OBJECT_ADDED);
663   return node;
664 }
665
666 template<> ParticleSystem *Scene::create_node<ParticleSystem>()
667 {
668   ParticleSystem *node = new ParticleSystem();
669   node->set_owner(this);
670   particle_systems.push_back(node);
671   particle_system_manager->tag_update(this);
672   return node;
673 }
674
675 template<> Shader *Scene::create_node<Shader>()
676 {
677   Shader *node = new Shader();
678   node->set_owner(this);
679   shaders.push_back(node);
680   shader_manager->tag_update(this, ShaderManager::SHADER_ADDED);
681   return node;
682 }
683
684 template<> AlembicProcedural *Scene::create_node<AlembicProcedural>()
685 {
686 #ifdef WITH_ALEMBIC
687   AlembicProcedural *node = new AlembicProcedural();
688   node->set_owner(this);
689   procedurals.push_back(node);
690   procedural_manager->tag_update();
691   return node;
692 #else
693   return nullptr;
694 #endif
695 }
696
697 template<typename T> void delete_node_from_array(vector<T> &nodes, T node)
698 {
699   for (size_t i = 0; i < nodes.size(); ++i) {
700     if (nodes[i] == node) {
701       std::swap(nodes[i], nodes[nodes.size() - 1]);
702       break;
703     }
704   }
705
706   nodes.resize(nodes.size() - 1);
707
708   delete node;
709 }
710
711 template<> void Scene::delete_node_impl(Light *node)
712 {
713   delete_node_from_array(lights, node);
714   light_manager->tag_update(this, LightManager::LIGHT_REMOVED);
715 }
716
717 template<> void Scene::delete_node_impl(Mesh *node)
718 {
719   delete_node_from_array(geometry, static_cast<Geometry *>(node));
720   geometry_manager->tag_update(this, GeometryManager::MESH_REMOVED);
721 }
722
723 template<> void Scene::delete_node_impl(Hair *node)
724 {
725   delete_node_from_array(geometry, static_cast<Geometry *>(node));
726   geometry_manager->tag_update(this, GeometryManager::HAIR_REMOVED);
727 }
728
729 template<> void Scene::delete_node_impl(Volume *node)
730 {
731   delete_node_from_array(geometry, static_cast<Geometry *>(node));
732   geometry_manager->tag_update(this, GeometryManager::MESH_REMOVED);
733 }
734
735 template<> void Scene::delete_node_impl(Geometry *node)
736 {
737   uint flag;
738   if (node->is_hair()) {
739     flag = GeometryManager::HAIR_REMOVED;
740   }
741   else {
742     flag = GeometryManager::MESH_REMOVED;
743   }
744
745   delete_node_from_array(geometry, node);
746   geometry_manager->tag_update(this, flag);
747 }
748
749 template<> void Scene::delete_node_impl(Object *node)
750 {
751   delete_node_from_array(objects, node);
752   object_manager->tag_update(this, ObjectManager::OBJECT_REMOVED);
753 }
754
755 template<> void Scene::delete_node_impl(ParticleSystem *node)
756 {
757   delete_node_from_array(particle_systems, node);
758   particle_system_manager->tag_update(this);
759 }
760
761 template<> void Scene::delete_node_impl(Shader *shader)
762 {
763   /* don't delete unused shaders, not supported */
764   shader->clear_reference_count();
765 }
766
767 template<> void Scene::delete_node_impl(Procedural *node)
768 {
769   delete_node_from_array(procedurals, node);
770   procedural_manager->tag_update();
771 }
772
773 template<> void Scene::delete_node_impl(AlembicProcedural *node)
774 {
775 #ifdef WITH_ALEMBIC
776   delete_node_impl(static_cast<Procedural *>(node));
777 #else
778   (void)node;
779 #endif
780 }
781
782 template<typename T>
783 static void remove_nodes_in_set(const set<T *> &nodes_set,
784                                 vector<T *> &nodes_array,
785                                 const NodeOwner *owner)
786 {
787   size_t new_size = nodes_array.size();
788
789   for (size_t i = 0; i < new_size; ++i) {
790     T *node = nodes_array[i];
791
792     if (nodes_set.find(node) != nodes_set.end()) {
793       std::swap(nodes_array[i], nodes_array[new_size - 1]);
794
795       assert(node->get_owner() == owner);
796       delete node;
797
798       i -= 1;
799       new_size -= 1;
800     }
801   }
802
803   nodes_array.resize(new_size);
804   (void)owner;
805 }
806
807 template<> void Scene::delete_nodes(const set<Light *> &nodes, const NodeOwner *owner)
808 {
809   remove_nodes_in_set(nodes, lights, owner);
810   light_manager->tag_update(this, LightManager::LIGHT_REMOVED);
811 }
812
813 template<> void Scene::delete_nodes(const set<Geometry *> &nodes, const NodeOwner *owner)
814 {
815   remove_nodes_in_set(nodes, geometry, owner);
816   geometry_manager->tag_update(this, GeometryManager::GEOMETRY_REMOVED);
817 }
818
819 template<> void Scene::delete_nodes(const set<Object *> &nodes, const NodeOwner *owner)
820 {
821   remove_nodes_in_set(nodes, objects, owner);
822   object_manager->tag_update(this, ObjectManager::OBJECT_REMOVED);
823 }
824
825 template<> void Scene::delete_nodes(const set<ParticleSystem *> &nodes, const NodeOwner *owner)
826 {
827   remove_nodes_in_set(nodes, particle_systems, owner);
828   particle_system_manager->tag_update(this);
829 }
830
831 template<> void Scene::delete_nodes(const set<Shader *> &nodes, const NodeOwner * /*owner*/)
832 {
833   /* don't delete unused shaders, not supported */
834   for (Shader *shader : nodes) {
835     shader->clear_reference_count();
836   }
837 }
838
839 template<> void Scene::delete_nodes(const set<Procedural *> &nodes, const NodeOwner *owner)
840 {
841   remove_nodes_in_set(nodes, procedurals, owner);
842   procedural_manager->tag_update();
843 }
844
845 CCL_NAMESPACE_END