Geometry Attributes Design #76659

Closed
opened 2020-05-11 23:09:46 +02:00 by Brecht Van Lommel · 34 comments

Blender geometry datablocks like meshes, pointclouds, hair need support for arbitrary attributes on vertices, edges, corners, faces, points and curves. Internally there exists a custom data layer system to support this. But there is no user interface and the types of data layers available s predefined.

Arbitrary attributes will serve a few purposes:

  • Compatibility for old per-corner colors to be replaced by per-vertex colors (#71947)
  • (Particle) simulation nodes that need to store arbitrary layers like velocity, radius, color, or other user defined properties
  • Import of geometry from other applications with such attributes

The proposed design is as follows:

  • New mesh.attributes, hair.attributes, pointcloud.attributes collection property on datablocks with each item an Attribute.
  • Attribute has:
    ** .name: unique name
    ** .type: float, int, color, 3D vector, string, ...
    ** .domain:
    *** (whole) geometry
    vertex edge (mesh only)
    corner (mesh only) primitive (face for mesh, curve for hair)
    *grids (multires grids for mesh) .data: values of the attributes, data type depends on type, length depends on domain
    ** .usage: describes the default meaning of the attribute: position, direction, normal, UV map, ...
  • Existing data layers like UVs, (old and new) vertex colors or sculpt mask are also in this list of attributes
  • Attribute Edit mode to edit and visualize such attributes

This change can be done incrementally, and more currently "hardcoded" attributes can become available in this list once the initial design is worked out. We would start supporting only a subset of the domains and data types, and extend this over time so that (nearly?) any data layer becomes available as a generic attribute.

The initial steps for an implementation to support new sculpt vertex colors could be as follows:

  • Add data types CD_PROP_COLOR, CD_PROP_VECTOR custom data layers in addition to the existing CD_PROP_FLOAT (CD_PROP_COLOR is just a renamed CD_MVERTCOL from sculpt vertex colors).
  • Implement Attribute RNA type that wraps CustomDataLayer with data type CD_PROP_*. Initially only support for vertex, corner and primitive domains, and float, color and vector data types.
  • Implement .attributes collection property, which iterates over custom data layers on all supported domains and supported data types. And which has add/remove API functions.
  • Add "Attributes" user interface panel with operators to add/remove such attributes.
  • Support rendering such attributes in Eevee and Cycles through the Attribute node.

Then in future releases we'd add support for more domains, data types and bring existing custom data layers into this system. As we add existing data layers into this system, we will also need to consider how to handle unique naming.

Blender geometry datablocks like meshes, pointclouds, hair need support for arbitrary attributes on vertices, edges, corners, faces, points and curves. Internally there exists a custom data layer system to support this. But there is no user interface and the types of data layers available s predefined. Arbitrary attributes will serve a few purposes: * Compatibility for old per-corner colors to be replaced by per-vertex colors (#71947) * (Particle) simulation nodes that need to store arbitrary layers like velocity, radius, color, or other user defined properties * Import of geometry from other applications with such attributes The proposed design is as follows: * New `mesh.attributes`, `hair.attributes`, `pointcloud.attributes` collection property on datablocks with each item an `Attribute`. * `Attribute` has: ** `.name`: unique name ** `.type`: float, int, color, 3D vector, string, ... ** `.domain`: *** (whole) geometry ***vertex*** edge (mesh only) ***corner (mesh only)*** primitive (face for mesh, curve for hair) ***grids (multires grids for mesh)** `.data`: values of the attributes, data type depends on type, length depends on domain ** `.usage`: describes the default meaning of the attribute: position, direction, normal, UV map, ... * Existing data layers like UVs, (old and new) vertex colors or sculpt mask are also in this list of attributes * Attribute Edit mode to edit and visualize such attributes This change can be done incrementally, and more currently "hardcoded" attributes can become available in this list once the initial design is worked out. We would start supporting only a subset of the domains and data types, and extend this over time so that (nearly?) any data layer becomes available as a generic attribute. The initial steps for an implementation to support new sculpt vertex colors could be as follows: - [x] Add data types `CD_PROP_COLOR`, `CD_PROP_VECTOR` custom data layers in addition to the existing `CD_PROP_FLOAT` (`CD_PROP_COLOR` is just a renamed `CD_MVERTCOL` from sculpt vertex colors). - [x] Implement `Attribute` RNA type that wraps `CustomDataLayer` with data type `CD_PROP_*`. Initially only support for vertex, corner and primitive domains, and float, color and vector data types. - [x] Implement `.attributes` collection property, which iterates over custom data layers on all supported domains and supported data types. And which has add/remove API functions. - [x] Add "Attributes" user interface panel with operators to add/remove such attributes. - [x] Support rendering such attributes in Eevee and Cycles through the Attribute node. Then in future releases we'd add support for more domains, data types and bring existing custom data layers into this system. As we add existing data layers into this system, we will also need to consider how to handle unique naming.
Author
Owner

Changed status from 'Needs Triage' to: 'Confirmed'

Changed status from 'Needs Triage' to: 'Confirmed'
Author
Owner
Added subscribers: @brecht, @PabloDobarro, @JacquesLucke, @lichtwerk
Brecht Van Lommel changed title from Geometry Attributes Data and Editing Design to Geometry Attributes Design 2020-05-11 23:11:00 +02:00
Member

It all sounds good to me.

It all sounds good to me.
Member

I have two questions regarding the implementation of the sculpt vertex colors/new vertex paint mode using this design:

  • Is the new vertex paint mode is going to paint into a generic layer (type color and domain vertex) or are we going to create a separate UI to manage these layers? I think that we should have a separate UI and system for them to integrate future features like multilayer/multichannel painting.
  • How are we going to manage the association of a grid domain layer a and a vertex domain layer to propagate the data from the grids to the base mesh when using apply base?
I have two questions regarding the implementation of the sculpt vertex colors/new vertex paint mode using this design: - Is the new vertex paint mode is going to paint into a generic layer (type color and domain vertex) or are we going to create a separate UI to manage these layers? I think that we should have a separate UI and system for them to integrate future features like multilayer/multichannel painting. - How are we going to manage the association of a grid domain layer a and a vertex domain layer to propagate the data from the grids to the base mesh when using apply base?
Author
Owner

Is the new vertex paint mode is going to paint into a generic layer (type color and domain vertex) or are we going to create a separate UI to manage these layers? I think that we should have a separate UI and system for them to integrate future features like multilayer/multichannel painting.

See my explanation in #71947#929316.

All mesh attributes should be available as generic attributes, but for vertex color painting there can be a UI that specifically shows the relevant subset. I think the first iteration would just be a list of vertex colors that you can display and edit one by one.

But beyond that I would imagine this integrates with the material system somehow, similar to texture painting? So that textures and vertex colors can be blended and layered arbitrarily, also with procedural texture nodes.

How are we going to manage the association of a grid domain layer a and a vertex domain layer to propagate the data from the grids to the base mesh when using apply base?

This part of the design is not really worked out.

For vertex colors (and sculpt layers?), I would hope this can be done automatic and there would just be a single grid domain layer in the UI. And Blender internally would be able to use that also for the base level too.

The precise implementation of that I'm not sure about. I think the multires modifier would convert grid domain attributes to vertex domain attributes. And if there is no multires modifier, mesh evaluation could also still do such a conversion. At least render engines would then be able to work with grid attributes without needing any changes. For painting, I guess the sculpt session could store the vertex array somewhere as well.

Alternatively we could have a hidden vertex custom data layer that is synced with the grid custom data layer, but I'd rather avoid that if possible.

> Is the new vertex paint mode is going to paint into a generic layer (type color and domain vertex) or are we going to create a separate UI to manage these layers? I think that we should have a separate UI and system for them to integrate future features like multilayer/multichannel painting. See my explanation in #71947#929316. All mesh attributes should be available as generic attributes, but for vertex color painting there can be a UI that specifically shows the relevant subset. I think the first iteration would just be a list of vertex colors that you can display and edit one by one. But beyond that I would imagine this integrates with the material system somehow, similar to texture painting? So that textures and vertex colors can be blended and layered arbitrarily, also with procedural texture nodes. > How are we going to manage the association of a grid domain layer a and a vertex domain layer to propagate the data from the grids to the base mesh when using apply base? This part of the design is not really worked out. For vertex colors (and sculpt layers?), I would hope this can be done automatic and there would just be a single grid domain layer in the UI. And Blender internally would be able to use that also for the base level too. The precise implementation of that I'm not sure about. I think the multires modifier would convert grid domain attributes to vertex domain attributes. And if there is no multires modifier, mesh evaluation could also still do such a conversion. At least render engines would then be able to work with grid attributes without needing any changes. For painting, I guess the sculpt session could store the vertex array somewhere as well. Alternatively we could have a hidden vertex custom data layer that is synced with the grid custom data layer, but I'd rather avoid that if possible.
Member

Alternatively we could have a hidden vertex custom data layer that is synced with the grid custom data layer, but I'd rather avoid that if possible.

I was thinking on doing the opposite thing when trying to implement Multires for sculpt vertex colors. My idea was to have a hidden grid domain layer per vertex color layer that are created when a Multires modifier is added to the mesh.
I'm not sure what is the use case of having grid datalayers exposed in the UI to edit them directly without a corresponding vertex datalayer in the base mesh (for any kind of attribute). Maybe we can just create them automatically, store the reference in the vertex datalayer and don't expose grids in the UI at all.

> Alternatively we could have a hidden vertex custom data layer that is synced with the grid custom data layer, but I'd rather avoid that if possible. I was thinking on doing the opposite thing when trying to implement Multires for sculpt vertex colors. My idea was to have a hidden grid domain layer per vertex color layer that are created when a Multires modifier is added to the mesh. I'm not sure what is the use case of having grid datalayers exposed in the UI to edit them directly without a corresponding vertex datalayer in the base mesh (for any kind of attribute). Maybe we can just create them automatically, store the reference in the vertex datalayer and don't expose grids in the UI at all.
Author
Owner

In #76659#930127, @PabloDobarro wrote:
I was thinking on doing the opposite thing when trying to implement Multires for sculpt vertex colors. My idea was to have a hidden grid domain layer per vertex color layer that are created when a Multires modifier is added to the mesh.
I'm not sure what is the use case of having grid datalayers exposed in the UI to edit them directly without a corresponding vertex datalayer in the base mesh (for any kind of attribute). Maybe we can just create them automatically, store the reference in the vertex datalayer and don't expose grids in the UI at all.

I agree there should be a single attribute visible in the UI (and Python API?). And maybe under the hood there are two CustomDayaLayer instances if necessary.

But I think it must be possible for an attribute to exist only per-vertex even if multires is used. For vertex colors that might not be needed usually, but I think the generic attribute system should support it. And then that should be configurable for the user somehow, either as a type of domain or another attribute setting.

> In #76659#930127, @PabloDobarro wrote: > I was thinking on doing the opposite thing when trying to implement Multires for sculpt vertex colors. My idea was to have a hidden grid domain layer per vertex color layer that are created when a Multires modifier is added to the mesh. > I'm not sure what is the use case of having grid datalayers exposed in the UI to edit them directly without a corresponding vertex datalayer in the base mesh (for any kind of attribute). Maybe we can just create them automatically, store the reference in the vertex datalayer and don't expose grids in the UI at all. I agree there should be a single attribute visible in the UI (and Python API?). And maybe under the hood there are two `CustomDayaLayer` instances if necessary. But I think it must be possible for an attribute to exist only per-vertex even if multires is used. For vertex colors that might not be needed usually, but I think the generic attribute system should support it. And then that should be configurable for the user somehow, either as a type of domain or another attribute setting.
Member

@brecht Regardless of the Multires/Vertex customdata design to make the propagation work for all attributes, in order to have the new vertex paint tools working the next step would be a patch for the color datalayer, which should be the same as the one in D5975 but renamed to ##CD_PROP_COLOR##, right?

@brecht Regardless of the Multires/Vertex customdata design to make the propagation work for all attributes, in order to have the new vertex paint tools working the next step would be a patch for the color datalayer, which should be the same as the one in [D5975](https://archive.blender.org/developer/D5975) but renamed to ##CD_PROP_COLOR##, right?
Author
Owner

Yes, that's right.

Yes, that's right.
Member

@brecht After the color datalayer in D7838, what should be the next step?

@brecht After the color datalayer in [D7838](https://archive.blender.org/developer/D7838), what should be the next step?
Author
Owner

@PabloDobarro, you could go through the steps in the task description, with the next steps being adding an Attribute RNA type, .attributes and the UI panel for it.

@PabloDobarro, you could go through the steps in the task description, with the next steps being adding an `Attribute` RNA type, `.attributes` and the UI panel for it.
Author
Owner

What would also be good here to go along with this task or do afterwards is to refactor the internal data structure to match the RNA API names proposed here. "custom data layer" is non-standard and confusing in various ways. So CustomData could become AttributeSet and CustomDataLayer could become Attribute internally.

It's probably easiest to do this afterwards to not disturb existing sculpt vertex colors patches.

What would also be good here to go along with this task or do afterwards is to refactor the internal data structure to match the RNA API names proposed here. "custom data layer" is non-standard and confusing in various ways. So `CustomData` could become `AttributeSet` and `CustomDataLayer` could become `Attribute` internally. It's probably easiest to do this afterwards to not disturb existing sculpt vertex colors patches.
Member

Have a question about the .name:

  • atm. this can clash between different types (Sculpt Vertex Colors, Vertex Colors, UV Maps, ...)
  • this can lead to confusion (at least when using the Attribute shading node) -- this came up in #78187 for example
  • should these really be ensured to be unique? (and if so, how can we handle old files once we convert more currently "hardcoded" data layers?)
  • would we need a more sophisticated Attribute shading node? Or only have more specialized nodes like the Vertex Color node or the UV Map node?
Have a question about the `.name`: - atm. this can clash between different types (Sculpt Vertex Colors, Vertex Colors, UV Maps, ...) - this can lead to confusion (at least when using the `Attribute` shading node) -- this came up in #78187 for example - should these really be ensured to be unique? (and if so, how can we handle old files once we convert more currently "hardcoded" data layers?) - would we need a more sophisticated `Attribute` shading node? Or only have more specialized nodes like the `Vertex Color` node or the `UV Map` node?
Member

I think we should enforce unique names across all domains and data types. This makes it much easier to work with them in a node based workflow. This is because then an attribute can be referred to by a name and not by a name+domain+type combination. Also have a look at this slightly outdated document: https://wiki.blender.org/wiki/Source/Nodes/MeshTypeRequirements
I'd assume that there are not too many name collisions in current files. I don't really see another option to renaming them in versioning code...
How would a "more sophisticated" Attribute node look like in your opinion?

I think the way one works with the attribute node could be changed a bit. Instead of having to insert a blank attribute node, it would be much nicer if users could just see all the different attributes in a menu (that is dynamically populated based on evaluated objects that use the material). When the user clicks on an attribute name, it inserts a new Attribute node with the name being initialized and only one output socket of the correct type.

I think we should enforce unique names across all domains and data types. This makes it much easier to work with them in a node based workflow. This is because then an attribute can be referred to by a name and not by a name+domain+type combination. Also have a look at this slightly outdated document: https://wiki.blender.org/wiki/Source/Nodes/MeshTypeRequirements I'd assume that there are not too many name collisions in current files. I don't really see another option to renaming them in versioning code... How would a "more sophisticated" Attribute node look like in your opinion? I think the way one works with the attribute node could be changed a bit. Instead of having to insert a blank attribute node, it would be much nicer if users could just see all the different attributes in a menu (that is dynamically populated based on evaluated objects that use the material). When the user clicks on an attribute name, it inserts a new Attribute node with the name being initialized and only one output socket of the correct type.
Author
Owner

The Attribute shading node should be considered to be quite low-level and conflicts can happen there, but we can indeed improve it's UI. For sculpt vertex colors we will get the Vertex Color node working still, which should solve this particular problem.

Enforcing unique naming is something I want to look at once this attributes system is in place. But it will break compatibility in some cases and the UI is challenging as well if all attributes are not displayed in a single list everywhere. So this needs more design work.

A simple first step is to rename the default sculpt vertex colors from "Col" to "Color", that abbreviation is not helpful and avoids the most obvious conflicts.

The Attribute shading node should be considered to be quite low-level and conflicts can happen there, but we can indeed improve it's UI. For sculpt vertex colors we will get the Vertex Color node working still, which should solve this particular problem. Enforcing unique naming is something I want to look at once this attributes system is in place. But it will break compatibility in some cases and the UI is challenging as well if all attributes are not displayed in a single list everywhere. So this needs more design work. A simple first step is to rename the default sculpt vertex colors from "Col" to "Color", that abbreviation is not helpful and avoids the most obvious conflicts.

This issue was referenced by e59712b7c8

This issue was referenced by e59712b7c80358f7912eebd55ef08c8cc6daafc4
Member

In #76659#964204, @JacquesLucke wrote:
How would a "more sophisticated" Attribute node look like in your opinion?

Having to choose .usage first, then .name? (or any other combination that would make it unique, but name+domain+type would not be enough)
Not a big fan of this either, so maybe your following suggestion is better (this is all not an issue if we dont allow nameclashes, if we do though, changing the name in your suggestion might still be problematic?)

I think the way one works with the attribute node could be changed a bit. Instead of having to insert a blank attribute node, it would be much nicer if users could just see all the different attributes in a menu (that is dynamically populated based on evaluated objects that use the material). When the user clicks on an attribute name, it inserts a new Attribute node with the name being initialized and only one output socket of the correct type.

> In #76659#964204, @JacquesLucke wrote: > How would a "more sophisticated" Attribute node look like in your opinion? Having to choose `.usage` first, then `.name`? (or any other combination that would make it unique, but name+domain+type would not be enough) Not a big fan of this either, so maybe your following suggestion is better (this is all not an issue if we dont allow nameclashes, if we do though, changing the name in your suggestion might still be problematic?) > I think the way one works with the attribute node could be changed a bit. Instead of having to insert a blank attribute node, it would be much nicer if users could just see all the different attributes in a menu (that is dynamically populated based on evaluated objects that use the material). When the user clicks on an attribute name, it inserts a new Attribute node with the name being initialized and only one output socket of the correct type.
Member

In #76659#964214, @brecht wrote:
A simple first step is to rename the default sculpt vertex colors from "Col" to "Color", that abbreviation is not helpful and avoids the most obvious conflicts.

Sounds good, maybe this could be explicitly mentioned in {#78041}?

> In #76659#964214, @brecht wrote: > A simple first step is to rename the default sculpt vertex colors from "Col" to "Color", that abbreviation is not helpful and avoids the most obvious conflicts. Sounds good, maybe this could be explicitly mentioned in {#78041}?
Author
Owner

Also something to consider for unique naming is how file formats like USD and Alembic deal with them, and how that affects compatibility. For example in Houdini the name is required to be unique per domain, but not across all domains.

Also something to consider for unique naming is how file formats like USD and Alembic deal with them, and how that affects compatibility. For example in Houdini the name is required to be unique per domain, but not across all domains.

This issue was referenced by 565510bd7f

This issue was referenced by 565510bd7fd87ae146cabafb27f1dfd550450f58

This issue was referenced by a1397a3cc6

This issue was referenced by a1397a3cc69382a64ab97bb71e4769fc0add0791
Contributor

Added subscriber: @KenzieMac130

Added subscriber: @KenzieMac130
Member

Added subscriber: @EAW

Added subscriber: @EAW

This issue was referenced by 370d6e5025

This issue was referenced by 370d6e50252b979433f27959070315911cc340e5
Member

Added subscriber: @kursadk

Added subscriber: @kursadk
Member

Is there an eta for " Support rendering such attributes in Eevee and Cycles through the Attribute node" ? Thanks

Is there an eta for " Support rendering such attributes in Eevee and Cycles through the Attribute node" ? Thanks
Member

Added subscriber: @HooglyBoogly

Added subscriber: @HooglyBoogly

Added subscriber: @SteffenD

Added subscriber: @SteffenD
Contributor

Added subscriber: @RedMser

Added subscriber: @RedMser
Author
Owner

Changed status from 'Confirmed' to: 'Resolved'

Changed status from 'Confirmed' to: 'Resolved'
Brecht Van Lommel self-assigned this 2022-04-06 18:55:17 +02:00
Author
Owner

This has been largely implemented or replaced by more specific tasks in the sculpt/paint and geometry nodes modules.

This has been largely implemented or replaced by more specific tasks in the sculpt/paint and geometry nodes modules.

Added subscriber: @crowe

Added subscriber: @crowe

Maybe I'm just stupid, but shouldn't curve attributes be accessible in the same way meshes' are?

You can, for example, do a bpy.context.active_object.data.attributes[idx] to get to a mesh attribute collection, but for the life of me I can't find where the curves attributes are. There's also no UI panel for them, making it look as if it were overlooked.

Maybe I'm just stupid, but shouldn't **curve** attributes be accessible in the same way meshes' are? You can, for example, do a `bpy.context.active_object.data.attributes[idx]` to get to a mesh attribute collection, but for the life of me I can't find where the curves attributes are. There's also no UI panel for them, making it look as if it were overlooked.
Member

Curves attributes are being implemented for the new Curves object (#68981).

Curves attributes are being implemented for the new *Curves* object (#68981).
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
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
EEVEE & Viewport
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
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
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
EEVEE & Viewport
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
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
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
12 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#76659
No description provided.