Dev:2.8/Source/overrides/manifesto
目次
The Override Manifesto
Proposal for code design of overrides in Blender 2.8.
Forewords
Blender 2.8 is implementing different forms of overrides.
Static overrides take proxies to a new level, allowing users to treat linked data as if they were local. Workspace render settings overrides make each workspace unique yet sharing common settings. Layer Collection render settings overrides go a setup further and let the user define how you want to see or render a collection of objects altogether. And finally, Layer Collection data overrides make the best of the new depsgraph allowing any data in blender to redefined in a per layer, per collection basis.
It sounds confusing, right? But what if I told you that most of those overrides are the exactly same thing? They are ID Property overrides. The exception that validates the rule are the static overrides.
Static Overrides and Proxies
In Blender 2.7x proxies were limited to armatures, and could only have local pose data. In Blender 2.8 any Datablock (Mesh, Armature, ...) will be able to have local properties. And as far as the editors are concerned, the linked in data with its modifications will be treated the same as any local.
Which means that an object that has static overrides will be treated as a regular object. And will benefit just as well of the following IDProperty overrides described throughout this document.
ID Property
Blender IDProperty data type allows us to join RNA data nested in groups, with merging and syncing functionalities. It’s what we use for Cycles (e.g., bpy.context.object.cycles).
This is as well what we use for keymaps. The Keymap is a particular interesting application of IDProperty. The IDProperty are only created when set, and are nested under an IDProperty group:
As you can see, we already have overrides working in Blender 2.7x, we are just shy of calling them as such.
Data Storage
For simplicity, I will refer to IDProperty of IDP_GROUP type as IDPropery Group.
The idea is to store for each datablock a single IDProperty Group, and have a nested IDProperty Group for each engine.
Layer Collections will have a single IDProperty Group, and have a nested IDProperty Group for each render engine (e.g., Cycles, Eevee), and for every practical mode (e.g., object mode, edit mesh mode, …).
Engine Settings
We have three kind of engines defined render settings:
- Global settings
- Workspace settings
- Layer collection settings
Global Settings
For example: Cycles compute device, floor grid spacing, PBR “model”, grid distance.
The global settings are engine-related properties that are not overridden. They are set up once, and shared across the entire project. They may be per scene or user preference, it doesn’t matter.
Workspace Settings
For example: layer, engine, number of samples, integrator, floor reflection, brush settings.
The Workspace settings allow a workspace to customize how it will render the data. That includes having a different layer than the scene (F12), a different engine and other settings such as specific object mode properties.
Like the Keymap image above, we can expose them all in the User Interface, and the user set only the settings that she wants to override. By using IDProperty we benefit from merging syncing and storing only the set properties.
Note: Although this is barely covered in the workspaces documentation, this design allows a user to have her own “workspaces.blend” file, re-usable for different projects, with pre-defined render settings for specific workflows.
Layer Collection Settings
Example: matcap, show normals, Cycles ray visibility.
Finally we have the Layer collection settings. Those are settings that can be defined per collection in the layer level (i.e., scene → layer → collection).
At any given time a user should be able to see two set of engine settings: the active mode engine settings, and the active (render) engine settings.
Just like the KeyMap, we set only the properties we want to change, while the others are left grayed out. Unlike the keymaps, however, we can’t rely on the operator “default” values as a fallback when a property is not set.
In this case we need the properties to be set in the scene level, potentially overridden by workspaces, and then potentially overridden by a Layer Collection.
Also, a collection that is defining a render setting this way should be able to communicate this in the outliner. Perhaps having those overrides listed there, (or even directly editable there), followed by the data overrides.
Note: The override system is particular important for Layer Collections because of its tree nature. Nested and sibling collections can override the same settings, and the objects in those collections get assigned a final flushed evaluated settings.
Evaluation
The override chain needs to have a strict evaluation design, clearly communicated to users.
The Layer Collection render settings is evaluated from Scene →Workspace →Layer Collections.
The datablock evaluation goes from Datablock →Static Override →Layer Collection
Depsgraph centralizes the layer collection to objects data flushing, and will handle both override chain evaluations.