diff options
author | Jacques Lucke <jacques@blender.org> | 2020-07-23 13:09:28 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2020-07-23 13:09:36 +0300 |
commit | 634585aa6875f9e6e8a2e43e283f9d530764a094 (patch) | |
tree | 837a72316887305f8e0b14c69bb1469dea4b1c7c /source/blender/simulation | |
parent | 65968911217380a7a594f8684150b5fa01866d6a (diff) |
Simulation: add depsgraph relations for ids referenced by node tree
I'll really have to refactor `ntreeUpdateTree` soon to avoid scanning
all node trees multiple times.
Diffstat (limited to 'source/blender/simulation')
4 files changed, 85 insertions, 96 deletions
diff --git a/source/blender/simulation/SIM_simulation_update.hh b/source/blender/simulation/SIM_simulation_update.hh index 40b62bfb58a..efdfde8a4de 100644 --- a/source/blender/simulation/SIM_simulation_update.hh +++ b/source/blender/simulation/SIM_simulation_update.hh @@ -27,6 +27,8 @@ void update_simulation_in_depsgraph(Depsgraph *depsgraph, Scene *scene_cow, Simulation *simulation_cow); -} +bool update_simulation_dependencies(Simulation *simulation); + +} // namespace blender::sim #endif /* __SIM_SIMULATION_UPDATE_HH__ */ diff --git a/source/blender/simulation/intern/simulation_collect_influences.cc b/source/blender/simulation/intern/simulation_collect_influences.cc index bbc28077dff..876d0b50fc1 100644 --- a/source/blender/simulation/intern/simulation_collect_influences.cc +++ b/source/blender/simulation/intern/simulation_collect_influences.cc @@ -436,28 +436,10 @@ static void prepare_particle_attribute_builders(nodes::MFNetworkTreeMap &network } } -static void find_used_persistent_data(const nodes::DerivedNodeTree &tree, - UsedPersistentData &r_used_persistent_data) -{ - const bNodeSocketType *socktype = nodeSocketTypeFind("NodeSocketObject"); - BLI_assert(socktype != nullptr); - - for (const nodes::DInputSocket *dsocket : tree.input_sockets()) { - const bNodeSocket *bsocket = dsocket->bsocket(); - if (bsocket->typeinfo == socktype) { - Object *object = ((const bNodeSocketValueObject *)bsocket->default_value)->value; - if (object != nullptr) { - r_used_persistent_data.add(DEG_get_original_id(&object->id)); - } - } - } -} - void collect_simulation_influences(Simulation &simulation, ResourceCollector &resources, SimulationInfluences &r_influences, - RequiredStates &r_required_states, - UsedPersistentData &r_used_persistent_data) + RequiredStates &r_required_states) { nodes::NodeTreeRefMap tree_refs; const nodes::DerivedNodeTree tree{simulation.nodetree, tree_refs}; @@ -481,8 +463,6 @@ void collect_simulation_influences(Simulation &simulation, for (const nodes::DNode *dnode : get_particle_simulation_nodes(tree)) { r_required_states.add(dnode_to_path(*dnode), SIM_TYPE_NAME_PARTICLE_SIMULATION); } - - find_used_persistent_data(tree, r_used_persistent_data); } } // namespace blender::sim diff --git a/source/blender/simulation/intern/simulation_collect_influences.hh b/source/blender/simulation/intern/simulation_collect_influences.hh index 13744c3bc1a..42cbea6977e 100644 --- a/source/blender/simulation/intern/simulation_collect_influences.hh +++ b/source/blender/simulation/intern/simulation_collect_influences.hh @@ -58,29 +58,10 @@ class RequiredStates { } }; -class UsedPersistentData { - private: - VectorSet<ID *> used_ids_; - - public: - void add(ID *id) - { - BLI_assert(id != nullptr); - BLI_assert((id->tag & LIB_TAG_NO_MAIN) == 0); - used_ids_.add(id); - } - - const VectorSet<ID *> &used_ids() const - { - return used_ids_; - } -}; - void collect_simulation_influences(Simulation &simulation, ResourceCollector &resources, SimulationInfluences &r_influences, - RequiredStates &r_required_states, - UsedPersistentData &r_used_persistent_data); + RequiredStates &r_required_states); } // namespace blender::sim diff --git a/source/blender/simulation/intern/simulation_update.cc b/source/blender/simulation/intern/simulation_update.cc index 9258d9cac07..3303145b891 100644 --- a/source/blender/simulation/intern/simulation_update.cc +++ b/source/blender/simulation/intern/simulation_update.cc @@ -33,6 +33,8 @@ #include "BLI_set.hh" #include "BLI_vector.hh" +#include "NOD_node_tree_dependencies.hh" + #include "particle_function.hh" #include "simulation_collect_influences.hh" #include "simulation_solver.hh" @@ -90,56 +92,6 @@ static void update_simulation_state_list(Simulation *simulation, add_missing_states(simulation, required_states); } -/* TODO: It might be better to do this as part of ntreeUpdateTree, so that the information - * about referenced data blocks is available when building the depsgraph. */ -static void update_persistent_data_handles(Simulation &simulation_orig, - const UsedPersistentData &used_persistent_data) -{ - Set<ID *> contained_ids; - Set<int> used_handles; - - /* Remove handles that have been invalidated. */ - LISTBASE_FOREACH_MUTABLE ( - PersistentDataHandleItem *, handle_item, &simulation_orig.persistent_data_handles) { - if (handle_item->id == nullptr) { - BLI_remlink(&simulation_orig.persistent_data_handles, handle_item); - MEM_freeN(handle_item); - continue; - } - if (!used_persistent_data.used_ids().contains(handle_item->id)) { - id_us_min(handle_item->id); - BLI_remlink(&simulation_orig.persistent_data_handles, handle_item); - MEM_freeN(handle_item); - continue; - } - contained_ids.add_new(handle_item->id); - used_handles.add_new(handle_item->handle); - } - - /* Add new handles that are not in the list yet. */ - int next_handle = 0; - for (ID *id : used_persistent_data.used_ids()) { - if (contained_ids.contains(id)) { - continue; - } - - /* Find the next available handle. */ - while (used_handles.contains(next_handle)) { - next_handle++; - } - used_handles.add_new(next_handle); - - PersistentDataHandleItem *handle_item = (PersistentDataHandleItem *)MEM_callocN( - sizeof(*handle_item), AT); - /* Cannot store const pointers in DNA. */ - id_us_plus(id); - handle_item->id = id; - handle_item->handle = next_handle; - - BLI_addtail(&simulation_orig.persistent_data_handles, handle_item); - } -} - void update_simulation_in_depsgraph(Depsgraph *depsgraph, Scene *scene_cow, Simulation *simulation_cow) @@ -159,11 +111,8 @@ void update_simulation_in_depsgraph(Depsgraph *depsgraph, ResourceCollector resources; SimulationInfluences influences; RequiredStates required_states; - UsedPersistentData used_persistent_data; - collect_simulation_influences( - *simulation_cow, resources, influences, required_states, used_persistent_data); - update_persistent_data_handles(*simulation_orig, used_persistent_data); + collect_simulation_influences(*simulation_cow, resources, influences, required_states); bke::PersistentDataHandleMap handle_map; LISTBASE_FOREACH ( @@ -191,4 +140,81 @@ void update_simulation_in_depsgraph(Depsgraph *depsgraph, } } +/* Returns true when dependencies have changed. */ +bool update_simulation_dependencies(Simulation *simulation) +{ + nodes::NodeTreeDependencies dependencies = nodes::find_node_tree_dependencies( + *simulation->nodetree); + + ListBase *handle_list = &simulation->persistent_data_handles; + + bool dependencies_changed = false; + + Map<ID *, PersistentDataHandleItem *> handle_item_by_id; + Map<PersistentDataHandleItem *, int> old_flag_by_handle_item; + Set<int> used_handles; + + /* Remove unused handle items and clear flags that are reinitialized later. */ + LISTBASE_FOREACH_MUTABLE (PersistentDataHandleItem *, handle_item, handle_list) { + if (dependencies.depends_on(handle_item->id)) { + handle_item_by_id.add_new(handle_item->id, handle_item); + used_handles.add_new(handle_item->handle); + old_flag_by_handle_item.add_new(handle_item, handle_item->flag); + handle_item->flag &= ~(SIM_HANDLE_DEPENDS_ON_TRANSFORM | SIM_HANDLE_DEPENDS_ON_GEOMETRY); + } + else { + if (handle_item->id != nullptr) { + id_us_min(handle_item->id); + } + BLI_remlink(handle_list, handle_item); + MEM_freeN(handle_item); + dependencies_changed = true; + } + } + + /* Add handle items for new id dependencies. */ + int next_handle = 0; + for (ID *id : dependencies.id_dependencies()) { + handle_item_by_id.lookup_or_add_cb(id, [&]() { + while (used_handles.contains(next_handle)) { + next_handle++; + } + used_handles.add_new(next_handle); + + PersistentDataHandleItem *handle_item = (PersistentDataHandleItem *)MEM_callocN( + sizeof(*handle_item), AT); + id_us_plus(id); + handle_item->id = id; + handle_item->handle = next_handle; + BLI_addtail(handle_list, handle_item); + + return handle_item; + }); + } + + /* Set appropriate dependency flags. */ + for (Object *object : dependencies.transform_dependencies()) { + PersistentDataHandleItem *handle_item = handle_item_by_id.lookup(&object->id); + handle_item->flag |= SIM_HANDLE_DEPENDS_ON_TRANSFORM; + } + for (Object *object : dependencies.geometry_dependencies()) { + PersistentDataHandleItem *handle_item = handle_item_by_id.lookup(&object->id); + handle_item->flag |= SIM_HANDLE_DEPENDS_ON_GEOMETRY; + } + + if (!dependencies_changed) { + /* Check if any flags have changed. */ + LISTBASE_FOREACH (PersistentDataHandleItem *, handle_item, handle_list) { + int old_flag = old_flag_by_handle_item.lookup_default(handle_item, 0); + int new_flag = handle_item->flag; + if (old_flag != new_flag) { + dependencies_changed = true; + break; + } + } + } + + return dependencies_changed; +} + } // namespace blender::sim |