# Attribute Semantics We are in the process of unifying the geometry attribute system in Blender. To continue with that, we have to make a decision on how to deal with different kinds of attributes and their relations. ## Attribute Kinds Below is a list of the different kinds of attributes we know of. It's unknown whether there are more. * Custom named user defined attributes. * Can have any type and domain. * Example: `my_mask` a float attribute on the point domain. * Built-in attributes. * Fixed domain, type and name. * Example: `position` on meshes. * Anonymous attributes. * Has no user defined name. * Example: Selection output sockets in geometry nodes. * UI attributes. * Are used for working with the geometry in the ui. * Should not affect procedural operations or be exported. * That wouldn't match user expectations and make some optimizations harder (e.g. meshes generally would have to be reevaluated after a selection change). * Should still be accessible from Python. * Example: Mesh vertex selection. ## Attribute Relations Some higher level concepts have to store more than one piece of data for each element. For example, each uv layer has to store the actual uv coordinate and a selection/pin state for each face corner. Currently, this data is packed together into a single struct (`MLoopUV`). This is not ideal because: * It needs a special attribute data type, just for this purpose. * Having a non-standard data type also means that it is harder to integrate with generic algorithm which expect to work on spans with raw data. * Generally, a SoA format should be preferred over AoS for attributes for performance reasons. For these reasons, we want to split `MLoopUV` and similar types into separate attributes. There still has to be some relation between these attributes. ## Proposal How these design problems are solved mostly depends on how we want to identify attributes. * Traditionally, attributes in Blender were identified by `Domain + CustomDataType + Name` (whereby the name could be empty for some `CustomDataTypes`). * In the past year, we were working towards identifying attributes just by their `Name`. * This simplifies using attributes quite a bit, because one does not have to specify domain + type all the time when an attribute is used. * It's also a more common standard in other software and file formats. There seem to be two main ways to move forward: * (A) Introduce a new `AttributeKind` enum * This enum would be a bit like `CustomDataType` but it would only encode the semantics of an attribute (`CustomDataType` mixes the concepts of semantic and data type). * Possible enum items would be `ATTR_KIND_UI`, `ATTR_KIND_ANONYMOUS`, `ATTR_KIND_GENERIC`, `ATTR_KIND_UV_LAYER_PIN`, ... * With this enum, attributes would be identified by `AttributeKind + Name`. * This is fairly non-standard and would complicate using attributes in code and maybe in the ui, because the name is not enough to identify an attribute (which was our goal previously). * (B) Encode Attribute Semantics in the Name * In this case, attributes are still uniquely identified on a geometry just by their `Name`. * The different attribute kinds are encoded in the name. * We could introduce a reserved attribute name prefix for Blender (e.g. `>`). * Generally, Blender has full control over attributes in this namespace. * Attributes may be changed/removed/added however Blender wants. * Blender may choose to "stabilize" certain names/sub-prefixes so that external code can depend on them. * Blender can restrict access to these attributes depending on the context. For example, ui attributes cannot be used in procedural contexts. * Nodes that access attributes by name should show a warning or error when trying to use attributes in this namespace. * Different sub-prefixes can be used for different semantics. * `>a_` for anonymous attributes (e.g. `>a_23425234`). * `>uv_pinned_` for uv layer pinning (e.g. `>uv_pinned_UVMap`, that corresponds to the `UVMap` layer). * `>select_vertex` for vertex selection * `>sculpt_mask_vertex` for masking in sculpt mode. * Attribute relations are handled outside of the core attributes container (aka `CustomData` currently). * For example, adding a uv layer should also add the corresponding `>uv_pinned_` layer (or it is only created when it's first used). * A rename uv-layer operator would have to rename all the related attributes. * Utility functions should make it easy to find all corresponding attributes based on their "base name". Personally, I prefer option (B). * It's conceptually much simpler on the data level. * Makes it easier to understand, debug and interface with for technical users. * Non technical users are not expected to see these "weird" `>` attributes anyway. * Also it allows addons/node groups to use the same mechanism for "related attributes" that Blender uses itself. * It's much closer to what we have already, so the transition would be relatively straight forward.