Geometry Nodes Checkpoints [Proposal]

This document contains has two main sections. First it outlines the goals and then describes the actual proposal.

Goals

This proposal addresses the following use cases:

  1. Bake simulations for a specific frame range and store the result in a user-defined location on disk.
  2. Bake not only simulations but any non-static geometry.
  3. Bake a static geometry that takes a while to compute. Potentially also store it in the .blend file to avoid having to recompute it after reload.
  4. Edit procedurally generated data manually. For example, to fix individual frames in a simulation.
  5. Create node group assets that allow progressive baking. For example, a fluid sim could be baked in multiple stages like preprocessing, simulation and final mesh generation.
  6. Allow accessing geometry from a different frame by accessing a baked version of it.
  7. Have a centralized place to manage baked data from a .blend file.

Proposal

The proposal has multiple components which are explained one by one below.

Checkpoint Node

At the core of the proposal is a new Checkpoint node. It can bake the incoming geometry at the press of a button. After baking, the baked geometry is owned by the node. That has a few consequences:

  • If the node group is used in multiple places, the checkpoint node will output the same geometry independent of where it is used.
  • If the node group is used as asset, the asset also contains the baked data.

The UI in the screenshot is certainly not set in stone, but it shows some of the important elements. A checkpoint should have a name so that it can easily be identified in a global list containing all checkpoints. The name does not have to be unique, but of course that can help the user.

The path can be used to specify a location on disk where the baked data should be stored and loaded from. If no path is specified, we could support storing the data in the .blend file directly.

Exposing to Group

It’s often the easiest to just work with the Checkpoint node directly. That’s especially true while working on a new node tree or when a node tree is the top level tree for an object.

However, if the Checkpoint is in a node group that’s used in multiple places, and it has to adapt to the inputs of the node group, then each group node should really be able to manage the checkpoint itself.

For that purpose, a checkpoint can be exposed to the group. In the mockup that is done by clicking on the little arrow-up icon next to the name.

When the checkpoint is exposed to the group, the Checkpoint node looses ownership of the baked data. Instead, the users of the node group own the baked data. In the example above, the group node on the right is the new owner. When it is selected, there is a new Checkpoints panel in the side bar that allows managing all exposed checkpoints. This group node could now be used in different places and and every group node can specify its own path where the data should be stored.

As shown in the mockup, the arrow-up icon also exists in the sidebar. That’s because it is possible to further move ownership of the cache up the node hierarchy. In this example, a modifier uses the node group directly. So any checkpoint exposed from the group would become visible and manageable in the modifier. Ownership of the baked data now lies with the object containing the modifier.

Currently, there are three different possible owners for checkpoints, but in theory more are possible.

  • The Checkpoint node itself.
  • Group node containing exposed checkpoints.
  • Modifier containing exposed checkpoints.

Global Checkpoints Panel

Since every checkpoint has a well defined owner and name, it’s easy to list all checkpoints that are available in a .blend file.

The checkpoints panel on the right shows a list of all the checkpoints. What information and operators are available there still has to be worked out. We definitely want some way to bake and free a subset of all checkpoints at once. Furthermore, we likely want some filtering options like “Only show checkpoints that are used by the selected objects”. It may also make sense to support giving checkpoints tags that they can be filtered by.

For studio workflows which use many checkpoints it should be quite straight forward to manage the paths used by all the different checkpoints with an addon.

Note that the checkpoint list in the screenshot above does not contain “C”. That’s because the Checkpoint node with the name C does not own any checkpoint. Instead, it has been exposed to the group and therefore the modifier is the owner of that checkpoint.

Editing

The checkpoints essentially store full geometries containing e.g. meshes and curves. Eventually it should become possible to just enter edit mode on these. I don’t have any specific UI for that yet. The edit mode node that we talked about before could just be part of the checkpoint system.

The checkpoints panel could potentially be expanded to also show the geometries contained in the checkpoints.

Import Checkpoint Node

The Import Checkpoint node allows reading a previously baked checkpoint at an arbitrary frame. This is useful for some use cases:

  • Offset simulation by some frames.
  • Access the data from multiple frames at the same time e.g. for trailing effects.

image

This node is a bit redundant with other planned features like reading from USD or Alembic caches. However, since checkpoints will often be stored in disk anyway, it would be a waste of memory to force the user to convert the data into another format for reading it at arbitrary frames. Currently, I intend to use the same file format that was used for the initial simulation baking. Checkpoints could potentially also be stored in common interchange formats but that always comes with the problem that more configuration is necessary to choose how to map Blender data to those formats and the result may not always be lossless (also see this).

The setup above could be used to get access to the current as well as previous geometry. Note that this also works when the checkpoint is exposed to the group thanks to the link between the Path sockets. One difficulty here is dealing with baked data that is not stored on disk but embedded into the .blend file. In such cases it might make sense if the path uses a special prefix to differentiate between actual file paths and embedded paths.

FAQ

How does this relate to Simulation Baking?

To me, the simulation baking we have now is mostly a user friendly way to quickly get started with simulations. It allows making all the objects in the scene history-independent so that random access of frames is possible. This is required for rendering in many cases. All of that is done mostly automatically in the sense that the user does not have to setup file paths or insert extra nodes.

That approach does not scale to more complex use-cases where one might want to bake more than just the simulation state or one needs detailed control over where baked data is stored. Therefore, I believe that the simulation baking should be kept very simple while the checkpoint system should be able to deal with more complex workflows.

34 Likes

i’m not sure if i understand correctly but basicly the checkpoint node is created for manipulating the geometry at a moment “T” for manipulating the topology, or adding / remove some topology… by non-procedural method, Correct ?

See the houdini (Edit geometry node, is the simple exemple and is the only software we can compare the procedural method) exemple is really simple and more intuitive i don’t understand why a complex node like your proposal for blender ?

Your idea is not really bad, but why not set an auto-name for the area field btw? (Sometimes want go fast and you don’t want lost time with some fields)

i’m not sure if i understand correctly but basicly the checkpoint node is created for manipulating the geometry at a moment “T” for manipulating the topology, or adding / remove some topology… by non-procedural method, Correct ?

That’s one of multiple use cases I mentioned.

Your idea is not really bad, but why not set an auto-name for the area field btw? (Sometimes want go fast and you don’t want lost time with some fields)

You don’t have to set a name if you don’t care about it. It’s just useful when looking at a list containing all the baked checkpoints in your scene if they are properly named. That’s more for the use case when you are baking animated geometry that is stored on disk and less for the use case that you mentioned.

3 Likes

Okay thank you for the clarification i hope can soonly test this bad boy and give a feedback ^^ :slight_smile: that’s look really good ^^

1 Like

I really like the proposal.

I’m super looking forward for the edit mode and the alembic/vdb reading with attribute support (I know that’s another node), but in general I really like the proposal, this brings a lot of flexibility to the table :slight_smile:

3 Likes

I’d like to ask if and/or it was considered to make Checkpoints an ID type instead of this separate new type of thing? I think this ends up implementing a few miscellaneous things that ID types already do well?

Because that’s the downside I see in this proposal, things that need to be re implemented:

  • Needing to reference checkpoints by name, instead of a Blender type that could also be exposed as a node pin and overwriting such paths/names. In this proposal currently done by bubbling up ownership of those settings to owners of a graph with a checkpoint node.
  • Overview of active checkpoints in the file need a new UI instead of being able to reuse the outliner’s different modes
  • Dependency tracking between an Object and the Checkpoints in its node graphs

Things that in this proposal I think are weaker versions that could be better if it were and ID type:

  • Referencing checkpoints for Import Checkpoint on disk through a string path, instead of linking to an ID type. Which then could also be overridden by users linking in this node.
  • “Overrides” for Checkpoint filepaths, now the property to overwrite would bubble up to the owner of the Checkpoint, so the modifier data? But instead of becoming the owner, couldn’t the modifier reference the Checkpoint as an ID and use the overrides system? So the UI feedback for it could be overwritten?

I’m not coming in to strongly “counter propose” to make it an ID type instead, but I felt like this approach should be discussed in the scope of this proposal? A simple and clear dismissal could of course be that it’s much cleaner and simpler to make checkpoints their own thing specifically to have more flexibility.

The name does not have to be unique, but of course that can help the user.

Shouldn’t it be forced to be unique within the scope of an individual graph/group? I don’t see mentioned or can think of the advantage of letting the user not really worry/care about duplicate names by default, over the disadvantage of not being able to trace back checkpoint data to a checkpoint node? I feel like it’s a big loss for debugging/troubleshooting sake.
If the names are forced to be unique within at lest the scope of a single graph, the output data could always have a unique “object name+modifier name+nodegraph name+(group name+)checkpoint name”.
For the simplest usage where a user just adds a bunch of Checkpoint nodes and Blender shouldn’t force them to use unique names, maybe they can then be fully anonymous? Or use auto incrementing names+numbers like ID types already do?

The path can be used to specify a location on disk where the baked data should be stored and loaded from.

I’m not arguing this is not good enough for the first version, but won’t this get cumbersome fast? When a nodegroup uses a bunch of checkpoints and then if used one or more times within the same graph either every instance either all the names or paths need to be changed so they don’t conflict? Or was it just already planned to append the nodegroup node name to every file metadat/name it outputs so this becomes a non issue?

4 Likes

The checkpoints behave essentially like sockets in the way they bubble up, to the point they could even be implemented as a socket type. I don’t want to suggest actually making them input sockets, but at least conceptually it helps me understand how they fit into things and should behave similarly in some ways.

I see the advantage of making the checkpoints datablocks, to make sharing them easier. That’s a good enough reason, but about some of these points:

The checkpoint still needs a name in the same way e.g. an Object datablock exposed as a node group socket involves both a socket name and a datablock name.

It may be best to put the UI for all checkpoints in either the outliner or spreadsheet editor, but this doesn’t require anything to be a datablock.

This type of UI also does not need only the list of datablocks, but for each the context in which it will be baked. There some distinction between all checkpoints in a file, and all checkpoints that you can bake in a file. And for each that can be baked, there’s only a single place that can do that, while there may be multiple places reading from it.

I think using a datablock/overrides and the bubbling up system are orthogonal. It can either bubble up a filepath, or a datablock pointer, in terms of implementation it’s quite similar.

The bubbling up of node sockets and now checkpoints is about providing a high level UI, hiding internals and instantiation. Overrides can work together with that but don’t replace it.

3 Likes

As I mentioned earlier in this design task, I still think there should be some clear UI distinction between checkpoints that are expected to be automatically cached/baked, and freezing of geometry as a more manual step as part of the modelling process.

7 Likes

I still think there should be some clear UI distinction between checkpoints that are expected to be automatically cached/baked

I think automatic caching would be basically completely separate from checkpoints on a UI level. Maybe checkpoints would be higher on some internal priority list for automatic caching, but that might be it. Ideally automatic caching wouldn’t require setting up explicit cache points.

Also, maybe this wasn’t clear but the impression I got from Jacques is that this proposal is an alternative/iteration to the freeze node design.

5 Likes

I’d like to ask if and/or it was considered to make Checkpoints an ID type instead of this separate new type of thing? I think this ends up implementing a few miscellaneous things that ID types already do well?

I’m not generally opposed to making checkpoints an ID type and maybe it turns out better this way. Would be good to discuss this more. Currently I think that this would be an unnecessary indirection, but I might change my mind. If I want to reference a checkpoint location on disk, it feels like it should be enough to just use the file path instead of having to create an ID data block first. A checkpoint data block would essentially just be a general container for various geometry types and maybe other data. It probably shouldn’t be called “checkpoint” then.

Needing to reference checkpoints by name

In the proposal, checkpoints are not referenced by name. The name is more like a label that helps the user organize things. The internal identifier of a checkpoint would be the owner id together with a node id or modifier name and an additional integer id for group nodes.

The path can be used to specify a location on disk where the baked data should be stored and loaded from.

I’m not arguing this is not good enough for the first version, but won’t this get cumbersome fast? When a nodegroup uses a bunch of checkpoints and then if used one or more times within the same graph either every instance either all the names or paths need to be changed so they don’t conflict? Or was it just already planned to append the nodegroup node name to every file metadat/name it outputs so this becomes a non issue?

I think it is essential to have the flexibility to manually choose a path on a per checkpoint basis. However, I also see that it would be useful to build additional utilities on top of that so that you don’t have to choose every path manually all the time. If you don’t care about storing checkpoints separately, they can also be stored in the .blend file directly.

The checkpoints behave essentially like sockets in the way they bubble up, to the point they could even be implemented as a socket type. I don’t want to suggest actually making them input sockets, but at least conceptually it helps me understand how they fit into things and should behave similarly in some ways.

Yeah, the way it’s bubbling up is similar indeed. In theory, it could probably be implemented with a new socket type that’s user-visible. That would also benefit from checkpoints being an id type. A potential issue arises when the checkpoint socket is linked to more than one Checkpoint node. That would work as long as the checkpoint is only read from, but it’s more challenging to define the behavior when baking the checkpoint, because then it’s not clear which nested Checkpoint node should be baked. That could be solved by setting a link-limit of 1 for checkpoint output sockets, but then you couldn’t link it to multiple import nodes.

As I mentioned earlier in this design task, I still think there should be some clear UI distinction between checkpoints that are expected to be automatically cached/baked, and freezing of geometry as a more manual step as part of the modelling process.

I agree that there are different kinds of checkpoints for different use-cases that need to be differentiated somehow:

  • Some checkpoints are only baked temporarily to make geometry nodes evaluation faster while working on it. This should become mostly unnecessy eventually with automated caching.
  • A slight variation of that are checkpoints that you bake for faster evaluation but also want to store in the .blend file or on disk so that the data does not have to be reevaluated after loading the file.
  • Then there are the “classic” animated geometry checkpoints (whether that uses simulation or not is kind of unrelated). Those kinds of checkpoints you likely want to be able to bake/free all at once (or at least in groups).
  • Some checkpoints are made to be able to manually modify the data destructively in the middle of a geometry node tree. Freeing those globally seems mostly useless unless the manual edits are only done to fix up e.g. a simulation that was also freed.

My main point is that I agree that there are different kinds of checkpoints but I don’t think that there are only two categories that every checkpoint can be organized into. Hence I mentioned that we might need some kind of tagging system that allows users to group their checkpoints however they want. And then those tags can be used for filtering when baking/freeing. I wouldn’t mind defining some standard tag for the common use case of simulation baking.

1 Like

My only feedback: call-it the bake node. Blender is not a video game.

3 Likes

Checkpoint conveys a “Savestate” idea, bake on the other hand does not as much, Checkpoint is more accurate for this

3 Likes

I want to bring back to attention the first time we used the term “Checkpoint”:
(slighly updated to use Simulation nodes instead of solver, and to separate cache from baking)

June 2021 - Checkpoints / Baking

  • Simulation Nodes can be baked (to disk).
  • The nodetree can be frozen (baked to disk or file?), edited, and continue with more nodes.
  • Both concepts are interchangeable, where we can get a node that reads from disk (vdb, alembic, …) that can work the same way as if I had simulation nodes connected to the tree.
  • Freezing can be for a “frame” too, not necessarily for the entire sequence.

May 2023

For me, the strength of check-point was that from the user point of view it doesn’t matter whether the simulation is baked, or a few nodes are frozen. Conceptually the same thing is happening:

  • Part of the node tree has a “check-point” where the computation starts from that point onwards.
  • Those “check-points” can be turned off so the live-data is used again.

I saw said concept as a way to unify both needs (simulation and freezing the tree) in the same high-level concept. If the “check-point” is just something that happens orthogonal to simulation baking I think it is just a freeze node. And there is no need to try to invent a new concept here.

I still see some benefit from the 2021 design though. It would need a fresh pass to include the ideas Jacques presented here, and what we know about the simulation nodes.

2 Likes

One thing I wondered about: there are various internal caches with a mesh. Would those be captured and stored as part of a checkpoint? I’m particularly interested in the looptris cache.

One thing I wondered about: there are various internal caches with a mesh. Would those be captured and stored as part of a checkpoint? I’m particularly interested in the looptris cache.

That’s an implementation detail and I think the answer is we can do whatever we want here. It seems likely that we’ll keep the caches around at run-time. Whether they are stored on disk is a different topic and is probably not needed most of the time.

1 Like

One thing I hope this node could do: the ability to also keep the bake saved as a datablock in the .blend file. Packing everything in a blend is nice!

That’s exactly what a bake does…
No need to overthink this

1 Like

Agreed with Jacques, but to add more detail, given how the caches like triangles are implemented (with SharedCache), this should happen automatically as long as the checkpoint keeps a Mesh in memory. So yes, as long as the check-point is active, the caches wouldn’t need to be recomputed.

1 Like

Any update about this task or PR For test it pls ?

Hi @Stimes a lot of this is under development here: #110137 - WIP: Geometry Nodes: new Bake node - blender - Blender Projects

To keep track of those it is easier to follow the module meeting notes. For example: 2023-08-01 Nodes & Physics Module Meeting

3 Likes