From 8efd6d5f82a700f6d109f3aa22668e49e435a7e4 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 10 May 2023 16:01:38 +0200 Subject: [PATCH] Geometry Nodes: Make simulation caching optional For realtime use cases, storing the geometry's state in memory at every frame can be prohibitively expensive. This commit adds an option to disable the caching, stored per object and accessible in the baking panel. The default is still to enable caching. Pull Request: https://projects.blender.org/blender/blender/pulls/107767 --- .../startup/bl_ui/properties_physics_geometry_nodes.py | 5 +++++ source/blender/blenkernel/BKE_blender_version.h | 2 +- source/blender/blenkernel/BKE_simulation_state.hh | 1 + source/blender/blenkernel/intern/simulation_state.cc | 9 +++++++++ source/blender/blenloader/intern/versioning_280.c | 2 +- source/blender/blenloader/intern/versioning_300.cc | 7 +++++++ source/blender/makesdna/DNA_object_defaults.h | 1 + source/blender/makesdna/DNA_object_types.h | 2 +- source/blender/makesrna/intern/rna_object.c | 6 ++++++ source/blender/modifiers/intern/MOD_nodes.cc | 8 ++++++++ 10 files changed, 40 insertions(+), 3 deletions(-) diff --git a/scripts/startup/bl_ui/properties_physics_geometry_nodes.py b/scripts/startup/bl_ui/properties_physics_geometry_nodes.py index 25eb0371efb..ff5454e60ef 100644 --- a/scripts/startup/bl_ui/properties_physics_geometry_nodes.py +++ b/scripts/startup/bl_ui/properties_physics_geometry_nodes.py @@ -39,6 +39,11 @@ class PHYSICS_PT_geometry_nodes(Panel): row.operator("object.simulation_nodes_cache_bake", text=bake_text).selected = True row.operator("object.simulation_nodes_cache_delete", text="", icon='TRASH').selected = True + layout.use_property_split = True + layout.use_property_decorate = False + ob = context.object + layout.prop(ob, "use_simulation_cache", text="Cache") + classes = ( PHYSICS_PT_geometry_nodes, diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index eeeb15fd20f..943ecb2bf64 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -31,7 +31,7 @@ extern "C" { * version. Older Blender versions will test this and show a warning if the file * was written with too new a version. */ #define BLENDER_FILE_MIN_VERSION 305 -#define BLENDER_FILE_MIN_SUBVERSION 8 +#define BLENDER_FILE_MIN_SUBVERSION 9 /** User readable version string. */ const char *BKE_blender_version_string(void); diff --git a/source/blender/blenkernel/BKE_simulation_state.hh b/source/blender/blenkernel/BKE_simulation_state.hh index 04ab35c0422..c72a50c3568 100644 --- a/source/blender/blenkernel/BKE_simulation_state.hh +++ b/source/blender/blenkernel/BKE_simulation_state.hh @@ -181,6 +181,7 @@ class ModifierSimulationCache { } void reset(); + void clear_prev_states(); }; } // namespace blender::bke::sim diff --git a/source/blender/blenkernel/intern/simulation_state.cc b/source/blender/blenkernel/intern/simulation_state.cc index fdd92a72d49..3424186b645 100644 --- a/source/blender/blenkernel/intern/simulation_state.cc +++ b/source/blender/blenkernel/intern/simulation_state.cc @@ -202,6 +202,15 @@ void ModifierSimulationState::ensure_bake_loaded() const bake_loaded_ = true; } +void ModifierSimulationCache::clear_prev_states() +{ + std::lock_guard lock(states_at_frames_mutex_); + std::unique_ptr temp = std::move(states_at_frames_.last()); + states_at_frames_.clear_and_shrink(); + bdata_sharing_.reset(); + states_at_frames_.append(std::move(temp)); +} + void ModifierSimulationCache::reset() { std::lock_guard lock(states_at_frames_mutex_); diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index fc38ee8ee90..77666206979 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -3472,7 +3472,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { - ob->flag &= ~(OB_FLAG_UNUSED_11 | OB_FLAG_UNUSED_12); + ob->flag &= ~(OB_FLAG_USE_SIMULATION_CACHE | OB_FLAG_UNUSED_12); ob->transflag &= ~(OB_TRANSFORM_ADJUST_ROOT_PARENT_FOR_VIEW_LOCK | OB_TRANSFLAG_UNUSED_1); ob->shapeflag &= ~OB_SHAPE_FLAG_UNUSED_1; } diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index fd37de1b4c8..c59f03876ef 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -4351,6 +4351,13 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } } } + + if (!MAIN_VERSION_ATLEAST(bmain, 306, 8)) { + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { + ob->flag |= OB_FLAG_USE_SIMULATION_CACHE; + } + } + /** * Versioning code until next subversion bump goes here. * diff --git a/source/blender/makesdna/DNA_object_defaults.h b/source/blender/makesdna/DNA_object_defaults.h index 2a5796d2aea..4afc4d65161 100644 --- a/source/blender/makesdna/DNA_object_defaults.h +++ b/source/blender/makesdna/DNA_object_defaults.h @@ -37,6 +37,7 @@ .drotAngle = 0, \ .quat = _DNA_DEFAULT_UNIT_QT, \ .dquat = _DNA_DEFAULT_UNIT_QT, \ + .flag = OB_FLAG_USE_SIMULATION_CACHE, \ .protectflag = OB_LOCK_ROT4D, \ \ .dt = OB_TEXTURE, \ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 53cd96c00ba..c33a31cfa90 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -720,8 +720,8 @@ enum { #define OB_FROMDUPLI (1 << 9) #define OB_DONE (1 << 10) /* unknown state, clear before use */ +#define OB_FLAG_USE_SIMULATION_CACHE (1 << 11) #ifdef DNA_DEPRECATED_ALLOW -# define OB_FLAG_UNUSED_11 (1 << 11) /* cleared */ # define OB_FLAG_UNUSED_12 (1 << 12) /* cleared */ #endif diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 1d763c5bb17..a50c125f4cb 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -3679,6 +3679,12 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_struct_type(prop, "RigidBodyConstraint"); RNA_def_property_ui_text(prop, "Rigid Body Constraint", "Constraint constraining rigid bodies"); + prop = RNA_def_property(srna, "use_simulation_cache", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", OB_FLAG_USE_SIMULATION_CACHE); + RNA_def_property_ui_text( + prop, "Use Simulation Cache", "Cache all frames during simulation nodes playback"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); + rna_def_object_visibility(srna); /* instancing */ diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index f53645dc46e..08b9bc3c664 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1351,6 +1351,14 @@ static GeometrySet compute_geometry(const bNodeTree &btree, nmd_orig->runtime_eval_log = eval_log.release(); } + if (DEG_is_active(ctx->depsgraph)) { + /* When caching is turned off, remove all states except the last which was just created in this + * evaluation. Check if active status to avoid changing original data in other depsgraphs. */ + if (!(ctx->object->flag & OB_FLAG_USE_SIMULATION_CACHE)) { + nmd_orig->simulation_cache->clear_prev_states(); + } + } + return output_geometry_set; }