diff options
-rw-r--r-- | intern/cycles/blender/blender_id_map.h | 28 | ||||
-rw-r--r-- | intern/cycles/blender/blender_light.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/blender/blender_object.cpp | 10 | ||||
-rw-r--r-- | intern/cycles/blender/blender_particles.cpp | 3 | ||||
-rw-r--r-- | intern/cycles/blender/blender_session.cpp | 1 | ||||
-rw-r--r-- | intern/cycles/blender/blender_shader.cpp | 4 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.cpp | 12 | ||||
-rw-r--r-- | intern/cycles/render/scene.cpp | 54 | ||||
-rw-r--r-- | intern/cycles/render/scene.h | 22 |
9 files changed, 114 insertions, 26 deletions
diff --git a/intern/cycles/blender/blender_id_map.h b/intern/cycles/blender/blender_id_map.h index 8ce1d23665d..198cfb4b29a 100644 --- a/intern/cycles/blender/blender_id_map.h +++ b/intern/cycles/blender/blender_id_map.h @@ -35,10 +35,22 @@ CCL_NAMESPACE_BEGIN template<typename K, typename T> class id_map { public: - id_map() + id_map(Scene *scene_) : scene(scene_) { } + ~id_map() + { + set<T *> nodes; + + typename map<K, T *>::iterator jt; + for (jt = b_map.begin(); jt != b_map.end(); jt++) { + nodes.insert(jt->second); + } + + scene->delete_nodes(nodes); + } + T *find(const BL::ID &id) { return find(id.ptr.owner_id); @@ -98,16 +110,15 @@ template<typename K, typename T> class id_map { } /* Combined add and update as needed. */ - bool add_or_update(Scene *scene, T **r_data, const BL::ID &id) + bool add_or_update(T **r_data, const BL::ID &id) { - return add_or_update(scene, r_data, id, id, id.ptr.owner_id); + return add_or_update(r_data, id, id, id.ptr.owner_id); } - bool add_or_update(Scene *scene, T **r_data, const BL::ID &id, const K &key) + bool add_or_update(T **r_data, const BL::ID &id, const K &key) { - return add_or_update(scene, r_data, id, id, key); + return add_or_update(r_data, id, id, key); } - bool add_or_update( - Scene *scene, T **r_data, const BL::ID &id, const BL::ID &parent, const K &key) + bool add_or_update(T **r_data, const BL::ID &id, const BL::ID &parent, const K &key) { T *data = find(key); bool recalc; @@ -146,7 +157,7 @@ template<typename K, typename T> class id_map { b_map[NULL] = data; } - void post_sync(Scene *scene, bool do_delete = true) + void post_sync(bool do_delete = true) { map<K, T *> new_map; typedef pair<const K, T *> TMapPair; @@ -177,6 +188,7 @@ template<typename K, typename T> class id_map { map<K, T *> b_map; set<T *> used_set; set<void *> b_recalc; + Scene *scene; }; /* Object Key diff --git a/intern/cycles/blender/blender_light.cpp b/intern/cycles/blender/blender_light.cpp index 117e9214e5a..6f95821e31e 100644 --- a/intern/cycles/blender/blender_light.cpp +++ b/intern/cycles/blender/blender_light.cpp @@ -39,9 +39,9 @@ void BlenderSync::sync_light(BL::Object &b_parent, BL::Light b_light(b_ob.data()); /* Update if either object or light data changed. */ - if (!light_map.add_or_update(scene, &light, b_ob, b_parent, key)) { + if (!light_map.add_or_update(&light, b_ob, b_parent, key)) { Shader *shader; - if (!shader_map.add_or_update(scene, &shader, b_light)) { + if (!shader_map.add_or_update(&shader, b_light)) { if (light->is_portal) *use_portal = true; return; @@ -176,7 +176,7 @@ void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal) Light *light; ObjectKey key(b_world, 0, b_world, false); - if (light_map.add_or_update(scene, &light, b_world, b_world, key) || world_recalc || + if (light_map.add_or_update(&light, b_world, b_world, key) || world_recalc || b_world.ptr.data != world_map) { light->type = LIGHT_BACKGROUND; if (sampling_method == SAMPLING_MANUAL) { diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 23faacc15da..d8c4ce9c5df 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -218,7 +218,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, /* test if we need to sync */ bool object_updated = false; - if (object_map.add_or_update(scene, &object, b_ob, b_parent, key)) + if (object_map.add_or_update(&object, b_ob, b_parent, key)) object_updated = true; /* mesh sync */ @@ -435,10 +435,10 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, sync_background_light(b_v3d, use_portal); /* handle removed data and modified pointers */ - light_map.post_sync(scene); - geometry_map.post_sync(scene); - object_map.post_sync(scene); - particle_system_map.post_sync(scene); + light_map.post_sync(); + geometry_map.post_sync(); + object_map.post_sync(); + particle_system_map.post_sync(); } if (motion) diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp index ee14217988b..e5eab1ae62b 100644 --- a/intern/cycles/blender/blender_particles.cpp +++ b/intern/cycles/blender/blender_particles.cpp @@ -53,8 +53,7 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob, ParticleSystem *psys; bool first_use = !particle_system_map.is_used(key); - bool need_update = particle_system_map.add_or_update( - scene, &psys, b_ob, b_instance.object(), key); + bool need_update = particle_system_map.add_or_update(&psys, b_ob, b_instance.object(), key); /* no update needed? */ if (!need_update && !object->geometry->need_update && !scene->object_manager->need_update) diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 8214ff7d532..7abfc6d81bc 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -238,6 +238,7 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg * See note on create_session(). */ /* sync object should be re-created */ + delete sync; sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress); BL::SpaceView3D b_null_space_view3d(PointerRNA_NULL); diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 03ed88ea9ec..c171982b29d 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -1241,7 +1241,7 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all) Shader *shader; /* test if we need to sync */ - if (shader_map.add_or_update(scene, &shader, b_mat) || update_all) { + if (shader_map.add_or_update(&shader, b_mat) || update_all) { ShaderGraph *graph = new ShaderGraph(); shader->name = b_mat.name().c_str(); @@ -1467,7 +1467,7 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all) Shader *shader; /* test if we need to sync */ - if (shader_map.add_or_update(scene, &shader, b_light) || update_all) { + if (shader_map.add_or_update(&shader, b_light) || update_all) { ShaderGraph *graph = new ShaderGraph(); /* create nodes */ diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index d2760d55f2d..0139afb711d 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -56,11 +56,11 @@ BlenderSync::BlenderSync(BL::RenderEngine &b_engine, : b_engine(b_engine), b_data(b_data), b_scene(b_scene), - shader_map(), - object_map(), - geometry_map(), - light_map(), - particle_system_map(), + shader_map(scene), + object_map(scene), + geometry_map(scene), + light_map(scene), + particle_system_map(scene), world_map(NULL), world_recalc(false), scene(scene), @@ -247,7 +247,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render, /* Shader sync done at the end, since object sync uses it. * false = don't delete unused shaders, not supported. */ - shader_map.post_sync(scene, false); + shader_map.post_sync(false); free_data_after_sync(b_depsgraph); diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index e98b2c76e88..3fb6c9620e6 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -707,4 +707,58 @@ template<> void Scene::delete_node_impl(Shader * /*node*/) /* don't delete unused shaders, not supported */ } +template<typename T> +static void remove_nodes_in_set(const set<T *> &nodes_set, + vector<T *> &nodes_array, + const NodeOwner *owner) +{ + size_t new_size = nodes_array.size(); + + for (size_t i = 0; i < new_size; ++i) { + T *node = nodes_array[i]; + + if (nodes_set.find(node) != nodes_set.end()) { + std::swap(nodes_array[i], nodes_array[new_size - 1]); + + assert(node->get_owner() == owner); + delete node; + + i -= 1; + new_size -= 1; + } + } + + nodes_array.resize(new_size); + (void)owner; +} + +template<> void Scene::delete_nodes(const set<Light *> &nodes, const NodeOwner *owner) +{ + remove_nodes_in_set(nodes, lights, owner); + light_manager->tag_update(this); +} + +template<> void Scene::delete_nodes(const set<Geometry *> &nodes, const NodeOwner *owner) +{ + remove_nodes_in_set(nodes, geometry, owner); + geometry_manager->tag_update(this); +} + +template<> void Scene::delete_nodes(const set<Object *> &nodes, const NodeOwner *owner) +{ + remove_nodes_in_set(nodes, objects, owner); + object_manager->tag_update(this); +} + +template<> void Scene::delete_nodes(const set<ParticleSystem *> &nodes, const NodeOwner *owner) +{ + remove_nodes_in_set(nodes, particle_systems, owner); + particle_system_manager->tag_update(this); +} + +template<> void Scene::delete_nodes(const set<Shader *> & /*nodes*/, const NodeOwner * /*owner*/) +{ + /* don't delete unused shaders, not supported */ +} + CCL_NAMESPACE_END diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h index cc2ef8da589..6686327dc49 100644 --- a/intern/cycles/render/scene.h +++ b/intern/cycles/render/scene.h @@ -322,6 +322,18 @@ class Scene : public NodeOwner { (void)owner; } + /* Remove all nodes in the set from the appropriate data arrays, and tag the + * specific managers for an update. This assumes that the scene owns the nodes. + */ + template<typename T> void delete_nodes(const set<T *> &nodes) + { + delete_nodes(nodes, this); + } + + /* Same as above, but specify the actual owner of all the nodes in the set. + */ + template<typename T> void delete_nodes(const set<T *> &nodes, const NodeOwner *owner); + protected: /* Check if some heavy data worth logging was updated. * Mainly used to suppress extra annoying logging. @@ -381,6 +393,16 @@ template<> void Scene::delete_node_impl(ParticleSystem *node); template<> void Scene::delete_node_impl(Shader *node); +template<> void Scene::delete_nodes(const set<Light *> &nodes, const NodeOwner *owner); + +template<> void Scene::delete_nodes(const set<Geometry *> &nodes, const NodeOwner *owner); + +template<> void Scene::delete_nodes(const set<Object *> &nodes, const NodeOwner *owner); + +template<> void Scene::delete_nodes(const set<ParticleSystem *> &nodes, const NodeOwner *owner); + +template<> void Scene::delete_nodes(const set<Shader *> &nodes, const NodeOwner *owner); + CCL_NAMESPACE_END #endif /* __SCENE_H__ */ |