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; }