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
This commit is contained in:
Hans Goudey 2023-05-10 16:01:38 +02:00 committed by Hans Goudey
parent c7e9932c46
commit 8efd6d5f82
10 changed files with 40 additions and 3 deletions

View File

@ -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,

View File

@ -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);

View File

@ -181,6 +181,7 @@ class ModifierSimulationCache {
}
void reset();
void clear_prev_states();
};
} // namespace blender::bke::sim

View File

@ -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<ModifierSimulationStateAtFrame> 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_);

View File

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

View File

@ -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.
*

View File

@ -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, \

View File

@ -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

View File

@ -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 */

View File

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