Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2020-07-23 13:09:28 +0300
committerJacques Lucke <jacques@blender.org>2020-07-23 13:09:36 +0300
commit634585aa6875f9e6e8a2e43e283f9d530764a094 (patch)
tree837a72316887305f8e0b14c69bb1469dea4b1c7c /source/blender/simulation
parent65968911217380a7a594f8684150b5fa01866d6a (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')
-rw-r--r--source/blender/simulation/SIM_simulation_update.hh4
-rw-r--r--source/blender/simulation/intern/simulation_collect_influences.cc22
-rw-r--r--source/blender/simulation/intern/simulation_collect_influences.hh21
-rw-r--r--source/blender/simulation/intern/simulation_update.cc134
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