Simulation Nodes: bake simulation states to disk #106937
No reviewers
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset System
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Viewport & EEVEE
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Asset Browser Project
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Module
Viewport & EEVEE
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Severity
High
Severity
Low
Severity
Normal
Severity
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
4 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#106937
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "JacquesLucke/blender:sim-bake"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This adds baking support to simulation nodes. While there are still a couple things to do, I think this is in a state where it can be merged into
geometry-nodes-simulation
so that we can easier work on it together.The following features are supported:
.json
for meta data. Other formats besides.json
could be used (most code is agnostic to that), but json is the easiest to use right now and seems to be good enough the common use cases (note that the size of the.json
files do not depend on how large e.g. the baked mesh is).Limitations:
The image below shows the file structure of the baked data. The file names are the (sub)frames.
.bdata
is an arbitrary name, we might want to use something else (currently it can stand for blender-data or binary-data). Also note now the first frame's file is larger. That's because the topology has only been stored in the first frame and was not modified afterwards.The content of the
.json
files looks like so (without the indentation): https://hastebin.com/share/emaluparoh.json@blender-bot package
Package build started. Download here when ready.
WIP: Simulation Nodes: bake simulation state to diskto Simulation Nodes: bake simulation states to diskI only looked at the first half of the changed files so far. I still need to look at
MOD_nodes.cc
and the baking operator.My only high-level comment so far is that it might be nice to separate the geometry set serialization from the idea of the simulation state a bit, because they're conceptually separate (right?) and we'll probably want to use it for caching.
UI-wise, I'd like to avoid the need for the "Simulation Nodes Cache:" label button, and the mixing of the "cache" and "bake" terms. It would be better to separate those more completely I think, and save "bake" for the file-writing and "cache" for the in-memory/automatic version. They can still both be in the "baking" panel, but separating the UI for baking and caching a bit more would be helpful I think (and also relate to the option for turning off the cache). Maybe separate subpanels?
The code that writes attributes is very nice, it's really satisfying to see our work on the attribute API and making that area more generic pay off here.
@ -0,0 +22,4 @@
* Reference to a slice of memory typically stored on disk.
*/
struct BDataSlice {
std::string name;
name
->file_name
maybe? It could be anything right nowCould be
file_name
, but it's somewhat intentionally not, because it's not strictly necessary that this refers to a file (even though currently it always does).@ -0,0 +66,4 @@
*/
int64_t sharing_info_version;
/**
* Identifier of the stored data.
A couple more words after "Identifier" could help the reader figure out the type of this value, something like "Identifier file name"
@ -0,0 +72,4 @@
};
/**
* Map that is used to detect when a some data has been written previously. For that it keeps a
Simpler wording suggestion:
@ -0,0 +78,4 @@
*/
Map<const ImplicitSharingInfo *, StoredByRuntimeValue> stored_by_runtime_;
mutable std::mutex mutex_;
A comment mentioning the need for a mutex might be nice here. Also fine to skip if you think it's obvious or not necessary for the user of the API
@ -0,0 +80,4 @@
mutable std::mutex mutex_;
/**
* Map that is used to detect when some data has been previously loaded. This keeps strong
Map that is used
->Map used
@ -0,0 +238,4 @@
{
const CPPType &type = data.type();
BLI_assert(type.is_trivial());
if (type.size() == 1 || type.is<ColorGeometry4b>()) {
No need to do this now necessarily, but I wonder if a
CPPType
should know if its values need endian switchesHm it could. Only makes sense for trivial types of course.
@ -0,0 +259,4 @@
}
if (type.is_any<float2, int2>()) {
return read_bdata_raw_data_with_endian(
bdata_reader, io_data, sizeof(float), r_data.size() * 2, r_data.data());
Maybe replace
float
here withint32_t
or4
?Voice against the magic four.
@ -0,0 +263,4 @@
}
if (type.is<float3>()) {
return read_bdata_raw_data_with_endian(
bdata_reader, io_data, sizeof(float), r_data.size() * 3, r_data.data());
Better to add a
size_in_bytes()
method toGMutableSpan
orGSpan
IMOOops, never mind I misunderstood this.
@ -0,0 +286,4 @@
sharing_info, [&]() { return write_bdata_simple_gspan(bdata_writer, data); });
}
[[nodiscard]] static bool read_bdata_shared_simple_gspan(
When I was working on the stuff in the
implicit_sharing
namespace, I foundvoid **
to be quite annoying, it's also not portable technically. Something like this avoids that issue, though you might not like it better, not sure:@ -0,0 +428,4 @@
return nullptr;
}
Curves *curves_id = bke::curves_new_nomain(num_points, num_curves);
It's probably worth creating empty curves first, then assigning the offsets, to avoid allocating them and then freeing them.
This could be a TODO comment too I guess
@ -0,0 +536,4 @@
instances->resize(num_instances);
const auto cancel = [&]() {
delete instances;
Using
unique_ptr<bke::Instances>
at least withing this function should remove the need for this@ -0,0 +576,4 @@
const BDataSharing &bdata_sharing)
{
GeometrySet geometry;
if (Mesh *mesh = try_load_mesh(io_geometry, bdata_reader, bdata_sharing)) {
These functions handle null inputs already, this is a bit prettier :)
@ -0,0 +280,4 @@
objects.append(object);
}
}
@ -0,0 +286,4 @@
if (md->type == eModifierType_Nodes) {
NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md);
const std::string bake_directory = bke::sim::get_bake_directory(*bmain, *object, *md);
BLI_delete(bake_directory.c_str(), true, true);
An error message when this fails maybe?
@ -1202,3 +1202,1 @@
if (DEG_is_active(ctx->depsgraph)) {
const Scene *scene = DEG_get_input_scene(ctx->depsgraph);
const int start_frame = scene->r.sfra;
const Main *bmain = DEG_get_bmain(ctx->depsgraph);
Do you think you'd be able to split any of this new code in
compute_geometry
to a separate function(s)? I think that would go a long way toward making it more readable and less overwhelming@ -1219,0 +1232,4 @@
nmd_orig->simulation_cache->reset();
}
}
/* Decide of a new simulation state should be created in this evaluation. */
Decide of
->Decide if
@ -208,0 +225,4 @@
const bke::sim::SimulationZoneState &next_state,
const float mix_factor) const
{
this->output_cached_state(params, prev_state);
TODO comment
That can work. I don't really have a good proposal for this part of the UI yet.
There's definitely things that should go into main separately here, but this seems ready for the simulation branch.
@ -66,0 +92,4 @@
* Adding a weak owner prevents the #ImplicitSharingInfo from being freed but not the referenced
* data.
*
* \note Other than with std::shared_ptr a weak user cannot be turned into a strong user. This is
Maybe "Unlike std::shared_ptr" instead of "Other than with std::shared_ptr"
@ -66,0 +109,4 @@
void tag_ensured_mutable() const
{
BLI_assert(this->is_mutable());
/* Does not need an atomic increment, because if the data is mutable, there is only a single
"Doesn't need an atomic increment" but it seems to do one anyway, am I missing something?
Oops, yeah. I thought this wouldn't need one but then wasn't so sure anymore.
@ -1162,1 +1163,4 @@
static void prepare_simulation_states_for_evaluation(
NodesModifierData *nmd,
NodesModifierData *nmd_orig,
Pass by reference and maybe const reference?