Active Attributes #98366

Open
opened 2022-05-25 13:46:12 +02:00 by Jacques Lucke · 18 comments
Member

A Mesh in Blender has several active attributes. Generally, they fall into two categories:

  • Attributes that are currently being edited by the user.
  • Attributes that should be used by the renderer and exporters by default.

Both categories exist for uv maps and color attributes. Looking at CustomDataLayer, there are also two more kinds of active attributes: clone and mask. However, I'm not sure how and where they are used exactly.

With the advent of geometry nodes, the existing implementation for active attributes is not good enough. We are facing the following problems:

  • UV maps are becoming generic float2 attributes, but render engines treat those as two different things and the activeness status is lost.
  • Active attributes are stored using indices and flags. Since we add/remove attributes much more often now, keeping indices up to date is cumbersome. Flags have to be stored within the attributes, but generally, an attribute shouldn't have to know whether it's active or not. That's a property of the geometry.
  • Active attributes cannot be used with procedurally generated geometry.

Proposal

To make it more clear what "active" means, we can introduce the following names:

  • "edit attribute": This is what "active" referred to before. It's the attribute that currently being edited by the user in some editor.
  • "default attribute": This is what "active render" referred to before. It's better then "render", because it's not specific to rendering. It can also be used in exporters and nodes.

Besides naming, the main internal change is this: Store edit/default attribute names as strings on geometry data blocks.

More specifically, add the following data members to Mesh and possibly other geometry types. The exact names are not final of course.

struct Mesh {
  char *edit_uv_map_attribute;
  char *edit_color_attribute;
  char *default_uv_map_attribute;
  char *default_color_attribute;
  /* ... */
};

This also allows the following to be removed:

  • CD_FLAG_COLOR_ACTIVE and CD_FLAG_COLOR_RENDER.
  • CustomDataLayer.active/active_rnd/active_clone/active_mask.

The existing ui-list based ui to activate attributes can stay the same. Clicking on an attribute would just update the corresponding string. Renaming becomes a little bit more complex if the active-status has to be maintained. It's still quite simple to update the string as well though.

Once we have a more general attribute edit mode, a new edit_attribute can be added as well.

Usage in Nodes

A couple of existing nodes can make use of the default attribute name. The default attributes can be used when no other name is provided.

  • Shader nodes: Texture Coordinate, UV Map, Color Attribute and Image Texture.
  • Geometry nodes: Image Texture.

Since these default attributes become part of the geometry, we also want to be able to edit the names using geometry nodes. The following nodes could be added:

  • Set Default UV Map/Set Default Color: Has a geometry and string input, and a geometry output.
  • UV Map/Color Attribute: Have a attribute name input and a float2/color field output. If the input name is empty, the default attribute name should be used.

Having these active attributes is not strictly necessary, because one could also specify the attribute name everywhere where it is used (or pass the string/field around). However, it has to be seen as a convenience feature, that reduces the number of explicit connections users have to make in common situations. Also it's a feature that Blender users are used to, because active attributes exists for a long time already.

Misc Notes

One problem is that when meshes are merged, which have different active attributes, some information is lost. In this case the user is responsible for making sure that the active attribute name is the same on all meshes that are merged together. An info message should be easy to implement. This is hardly a new problem though.

A `Mesh` in Blender has several active attributes. Generally, they fall into two categories: * Attributes that are currently being edited by the user. * Attributes that should be used by the renderer and exporters by default. Both categories exist for uv maps and color attributes. Looking at `CustomDataLayer`, there are also two more kinds of active attributes: clone and mask. However, I'm not sure how and where they are used exactly. With the advent of geometry nodes, the existing implementation for active attributes is not good enough. We are facing the following problems: * UV maps are becoming generic `float2` attributes, but render engines treat those as two different things and the activeness status is lost. * Active attributes are stored using indices and flags. Since we add/remove attributes much more often now, keeping indices up to date is cumbersome. Flags have to be stored within the attributes, but generally, an attribute shouldn't have to know whether it's active or not. That's a property of the geometry. * Active attributes cannot be used with procedurally generated geometry. ## Proposal To make it more clear what "active" means, we can introduce the following names: * "edit attribute": This is what "active" referred to before. It's the attribute that currently being edited by the user in some editor. * "default attribute": This is what "active render" referred to before. It's better then "render", because it's not specific to rendering. It can also be used in exporters and nodes. Besides naming, the main internal change is this: Store edit/default attribute names as strings on geometry data blocks. More specifically, add the following data members to `Mesh` and possibly other geometry types. The exact names are not final of course. ``` struct Mesh { char *edit_uv_map_attribute; char *edit_color_attribute; char *default_uv_map_attribute; char *default_color_attribute; /* ... */ }; ``` This also allows the following to be removed: * `CD_FLAG_COLOR_ACTIVE` and `CD_FLAG_COLOR_RENDER`. * `CustomDataLayer.active/active_rnd/active_clone/active_mask`. The existing ui-list based ui to activate attributes can stay the same. Clicking on an attribute would just update the corresponding string. Renaming becomes a little bit more complex if the active-status has to be maintained. It's still quite simple to update the string as well though. Once we have a more general attribute edit mode, a new `edit_attribute` can be added as well. ## Usage in Nodes A couple of existing nodes can make use of the default attribute name. The default attributes can be used when no other name is provided. * Shader nodes: Texture Coordinate, UV Map, Color Attribute and Image Texture. * Geometry nodes: Image Texture. Since these default attributes become part of the geometry, we also want to be able to edit the names using geometry nodes. The following nodes could be added: * `Set Default UV Map`/`Set Default Color`: Has a geometry and string input, and a geometry output. * `UV Map`/`Color Attribute`: Have a attribute name input and a `float2`/`color` field output. If the input name is empty, the default attribute name should be used. Having these active attributes is not strictly necessary, because one could also specify the attribute name everywhere where it is used (or pass the string/field around). However, it has to be seen as a convenience feature, that reduces the number of explicit connections users have to make in common situations. Also it's a feature that Blender users are used to, because active attributes exists for a long time already. ## Misc Notes One problem is that when meshes are merged, which have different active attributes, some information is lost. In this case the user is responsible for making sure that the active attribute name is the same on all meshes that are merged together. An info message should be easy to implement. This is hardly a new problem though.
Author
Member

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

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

Added subscriber: @JacquesLucke

Added subscriber: @JacquesLucke

Added subscriber: @brecht

Added subscriber: @brecht
  • Storing a name seems reasonable to me, but this will require adding validation in various places that add/remove attributes, not just manually by the user but also in the modifier stack or geometry nodes.
  • If no name is set, will just the first attribute with the appropriate type in the list of attributes be used? Or would it be valid for none to be active?
  • Merging meshes with different active attribute names is no new problem I think, is already something users may need to handle.
  • I think it makes sense to have "default" and "edit" attributes. Not sure the term "active" is needed still.
* Storing a name seems reasonable to me, but this will require adding validation in various places that add/remove attributes, not just manually by the user but also in the modifier stack or geometry nodes. * If no name is set, will just the first attribute with the appropriate type in the list of attributes be used? Or would it be valid for none to be active? * Merging meshes with different active attribute names is no new problem I think, is already something users may need to handle. * I think it makes sense to have "default" and "edit" attributes. Not sure the term "active" is needed still.
Author
Member

but this will require adding validation in various places that add/remove attributes, not just manually by the user but also in the modifier stack or geometry nodes.

Yes indeed.

If no name is set, will just the first attribute with the appropriate type in the list of attributes be used? Or would it be valid for none to be active?

I think if no name is set, or the attribute does not exist, then no attribute should be used. These heuristics of where to use which attributes seem to cause us more trouble than it's worth. Using some float2 attribute as uv map, even though it just contains some other data won't help anyone.

I think it makes sense to have "default" and "edit" attributes. Not sure the term "active" is needed still.

Good, will rephrase the proposal based on that soon.

> but this will require adding validation in various places that add/remove attributes, not just manually by the user but also in the modifier stack or geometry nodes. Yes indeed. > If no name is set, will just the first attribute with the appropriate type in the list of attributes be used? Or would it be valid for none to be active? I think if no name is set, or the attribute does not exist, then no attribute should be used. These heuristics of where to use which attributes seem to cause us more trouble than it's worth. Using some `float2` attribute as uv map, even though it just contains some other data won't help anyone. > I think it makes sense to have "default" and "edit" attributes. Not sure the term "active" is needed still. Good, will rephrase the proposal based on that soon.

In #98366#1364403, @JacquesLucke wrote:
I think if no name is set, or the attribute does not exist, then no attribute should be used. These heuristics of where to use which attributes seem to cause us more trouble than it's worth.

What I'm wondering is when this would happen in practice, if everything is implemented correctly. Most of the time there will be a single UV map, users will not even be thinking about setting one as active and just expect it to be used. If all tools, modifiers and nodes automatically set the active UV map on creation, are there cases where this would happen and users would have to go and fix the active UV map?

The UV editor and related tools and drawing may also need some changes to deal with the idea of there being UV maps but none is active.

Using some float2 attribute as uv map, even though it just contains some other data won't help anyone.

I don't think that's ideal indeed, but I guess there is still an intent to mark with float2 attributes are UV maps, or not?

> In #98366#1364403, @JacquesLucke wrote: > I think if no name is set, or the attribute does not exist, then no attribute should be used. These heuristics of where to use which attributes seem to cause us more trouble than it's worth. What I'm wondering is when this would happen in practice, if everything is implemented correctly. Most of the time there will be a single UV map, users will not even be thinking about setting one as active and just expect it to be used. If all tools, modifiers and nodes automatically set the active UV map on creation, are there cases where this would happen and users would have to go and fix the active UV map? The UV editor and related tools and drawing may also need some changes to deal with the idea of there being UV maps but none is active. > Using some `float2` attribute as uv map, even though it just contains some other data won't help anyone. I don't think that's ideal indeed, but I guess there is still an intent to mark with float2 attributes are UV maps, or not?
Author
Member

If all tools, modifiers and nodes automatically set the active UV map on creation, are there cases where this would happen and users would have to go and fix the active UV map?

Guess that depends on how the ui for creating uv maps look like. We could e.g. have a drop down in the Store Named Attribute node that allows the user to pick "uv map", and then the default uv map would be set on the mesh automatically. The same would be needed in the modifier ui or node group output ui (where it's possible to create named attributes as well). With that, I don't think users would have to manually set the default uv map in almost all cases. A special node for that might still be useful when importing external data within a node, where it's not clear what attribute is a uv map.

I don't think that's ideal indeed, but I guess there is still an intent to mark with float2 attributes are UV maps, or not?

Yes, that still sounds reasonable to me, but it's not very urgent to me currently, especially when we've solved the "active uv map" issue in a different way.
Such a tag would still be useful when some node does special handling for uv maps for reasons that I don't know right now.

> If all tools, modifiers and nodes automatically set the active UV map on creation, are there cases where this would happen and users would have to go and fix the active UV map? Guess that depends on how the ui for creating uv maps look like. We could e.g. have a drop down in the Store Named Attribute node that allows the user to pick "uv map", and then the default uv map would be set on the mesh automatically. The same would be needed in the modifier ui or node group output ui (where it's possible to create named attributes as well). With that, I don't think users would have to manually set the default uv map in almost all cases. A special node for that might still be useful when importing external data within a node, where it's not clear what attribute is a uv map. > I don't think that's ideal indeed, but I guess there is still an intent to mark with float2 attributes are UV maps, or not? Yes, that still sounds reasonable to me, but it's not very urgent to me currently, especially when we've solved the "active uv map" issue in a different way. Such a tag would still be useful when some node does special handling for uv maps for reasons that I don't know right now.

In #98366#1364419, @JacquesLucke wrote:

I don't think that's ideal indeed, but I guess there is still an intent to mark with float2 attributes are UV maps, or not?

Yes, that still sounds reasonable to me, but it's not very urgent to me currently, especially when we've solved the "active uv map" issue in a different way.
Such a tag would still be useful when some node does special handling for uv maps for reasons that I don't know right now.

There are many exporters/importers that need to know what the UV maps are, so it seems like something that must be resolved before UV map to float2 attribute conversion lands.

> In #98366#1364419, @JacquesLucke wrote: >> I don't think that's ideal indeed, but I guess there is still an intent to mark with float2 attributes are UV maps, or not? > Yes, that still sounds reasonable to me, but it's not very urgent to me currently, especially when we've solved the "active uv map" issue in a different way. > Such a tag would still be useful when some node does special handling for uv maps for reasons that I don't know right now. There are many exporters/importers that need to know what the UV maps are, so it seems like something that must be resolved before UV map to float2 attribute conversion lands.
Author
Member

There are many exporters/importers that need to know what the UV maps are, so it seems like something that must be resolved before UV map to float2 attribute conversion lands.

Yes that's right. But as far as I know, it's not something that needs to be resolved before the edit/default attributes are stored as names (which already solves quite a few problems we have right now).
Adding a flag to attributes to indicate that it is a uv map should be fairly straight forward though, so we can also just do it soon.

> There are many exporters/importers that need to know what the UV maps are, so it seems like something that must be resolved before UV map to float2 attribute conversion lands. Yes that's right. But as far as I know, it's not something that needs to be resolved before the edit/default attributes are stored as names (which already solves quite a few problems we have right now). Adding a flag to attributes to indicate that it is a uv map should be fairly straight forward though, so we can also just do it soon.

Added subscriber: @GeorgiaPacific

Added subscriber: @GeorgiaPacific

Added subscriber: @Baardaap

Added subscriber: @Baardaap

There are many exporters/importers that need to know what the UV maps are, so it seems like something that must be resolved before UV map to float2 attribute conversion lands.

If the topic of this discussion is resolved first (storing the default/edit uvmap as a string on the geometry), adding a tag to mark UVs is rather trivial I think. But without this, with the current system of active/render layers it becomes a nightmare to add such a tag to D14365 because you'd need special handling for FLOAT2 layers to distinguish between the active 'UV' flavor of a FLOAT2 layer and the active 'non-UV' flavor.

IMO if we want to keep UV layers separate from general purpose float2 layers while still using the current active/render layer system it would make more sense to create a special CD_PROP_UV type and be done with it.

So I think there are 2 options:

  • first landing something like this tasks D15101, and only after that work in a tagging system into D14365
  • making a CD_PROP_UV layer type (which can of course be treated as CD_PROP_FLOAT2 for 90% of the code)

I'd much prefer the first option. Though I hope it won't take too long, because merging D14365 with master becomes more and more work as that patch grows.

> There are many exporters/importers that need to know what the UV maps are, so it seems like something that must be resolved before UV map to float2 attribute conversion lands. If the topic of this discussion is resolved first (storing the default/edit uvmap as a string on the geometry), adding a tag to mark UVs is rather trivial I think. But without this, with the current system of active/render layers it becomes a nightmare to add such a tag to [D14365](https://archive.blender.org/developer/D14365) because you'd need special handling for FLOAT2 layers to distinguish between the active 'UV' flavor of a FLOAT2 layer and the active 'non-UV' flavor. IMO if we want to keep UV layers separate from general purpose float2 layers while still using the current active/render layer system it would make more sense to create a special CD_PROP_UV type and be done with it. So I think there are 2 options: - first landing something like this tasks [D15101](https://archive.blender.org/developer/D15101), and only after that work in a tagging system into [D14365](https://archive.blender.org/developer/D14365) - making a CD_PROP_UV layer type (which can of course be treated as CD_PROP_FLOAT2 for 90% of the code) I'd much prefer the first option. Though I hope it won't take too long, because merging [D14365](https://archive.blender.org/developer/D14365) with master becomes more and more work as that patch grows.

Personally I would have only CD_PROP_UV and no CD_PROP_FLOAT2. It's not clear to me there are good use cases where using either CD_PROP_UV or CD_PROP_FLOAT3 would not work well. I don't think users care much about the differences, they would mainly get in the way.

I we use either tagging, or both CD_PROP_UV and CD_PROP_FLOAT2, there are questions about what the UI looks like. For example for tagging, would there we some way to add/remove the tags, in geometry nodes and the attributes list? Do nodes to create attributes or operators like convert attribute all get additional option to choose the tag? If there are other use cases for tagging maybe this makes sense, but if we don't have them it's an additional concept for users to understand without any payoff.

Personally I would have only CD_PROP_UV and no CD_PROP_FLOAT2. It's not clear to me there are good use cases where using either CD_PROP_UV or CD_PROP_FLOAT3 would not work well. I don't think users care much about the differences, they would mainly get in the way. I we use either tagging, or both CD_PROP_UV and CD_PROP_FLOAT2, there are questions about what the UI looks like. For example for tagging, would there we some way to add/remove the tags, in geometry nodes and the attributes list? Do nodes to create attributes or operators like convert attribute all get additional option to choose the tag? If there are other use cases for tagging maybe this makes sense, but if we don't have them it's an additional concept for users to understand without any payoff.
Member

Added subscriber: @HooglyBoogly

Added subscriber: @HooglyBoogly
Member

only CD_PROP_UV and no CD_PROP_FLOAT2

This is functionally the same as only having a float2 type though, only it has a different name.
Then the downside is that the name of the data-type encodes how the attribute is used, which is exactly what we wanted to move away from with the generic attribute system.
I think it has been a huge improvement in terms of flexibility and simplicity to have a way to store truly-generic data on geometry.

So in the long term, I don't think it's a good idea to remove the ability to store generic 2D vector data on geometries (data that isn't meant to be interpreted as a UV).
In the short term, maybe that's okay, since the whole pipeline for generic attributes is still "under construction"-- I just think it's better to stick to the generic data type design.

However, I think the tagging would be that complex. An implementation could add a flag to CustomDataLayer. It could be set in the property editor attribute UI list, and by the store named attribute node in geometry nodes.

>only CD_PROP_UV and no CD_PROP_FLOAT2 This is functionally the same as only having a float2 type though, only it has a different name. Then the downside is that the name of the data-type encodes how the attribute is used, which is exactly what we wanted to move away from with the generic attribute system. I think it has been a huge improvement in terms of flexibility and simplicity to have a way to store truly-generic data on geometry. So in the long term, I don't think it's a good idea to remove the ability to store generic 2D vector data on geometries (data that isn't meant to be interpreted as a UV). In the short term, maybe that's okay, since the whole pipeline for generic attributes is still "under construction"-- I just think it's better to stick to the generic data type design. However, I think the tagging would be that complex. An implementation could add a flag to `CustomDataLayer`. It could be set in the property editor attribute UI list, and by the store named attribute node in geometry nodes.

The way I see it is we're not removing the ability to store generic 2D vector data on geometry, since you can just use a 3D vector. For me that's a reasonable long term solution.

Anyway, I don't feel too strongly about it, as long as we can keep the UI for working with UV maps simple, which I guess will be the case as long as we keep a dedicated list for UV maps.

For generic attributes UI, it would be a bit simpler if it was presented in the same dropdown as the data types (regardless if it's a flag internally or not), so users would not need to know the concept of a tag.

The way I see it is we're not removing the ability to store generic 2D vector data on geometry, since you can just use a 3D vector. For me that's a reasonable long term solution. Anyway, I don't feel too strongly about it, as long as we can keep the UI for working with UV maps simple, which I guess will be the case as long as we keep a dedicated list for UV maps. For generic attributes UI, it would be a bit simpler if it was presented in the same dropdown as the data types (regardless if it's a flag internally or not), so users would not need to know the concept of a tag.

In my opinion it's best to use CD_PROP_FLOAT2 as name for the datalayer as that describes the data layout. And since currently the UV system is the only one that uses CD_PROP_FLOAT2 layers I don't think it's already necessary to add special flags. Currently in my patch all CD_PROP_FLOAT2 layers on face corners are listed as UV maps. If there would ever be a pressing need for other float2 data on face corners we can always decide to add extra tagging then. I think if a user purposefully creates a float2 attribute on face corners (s)he won't mind them appearing in the UV maps list as well. Trying to solve that issue pre-emptively looks like premature optimization to me.

In my opinion it's best to use CD_PROP_FLOAT2 as name for the datalayer as that describes the data layout. And since currently the UV system is the only one that uses CD_PROP_FLOAT2 layers I don't think it's already necessary to add special flags. Currently in my patch all CD_PROP_FLOAT2 layers *on face corners* are listed as UV maps. If there would ever be a pressing need for other float2 data on face corners we can always decide to add extra tagging then. I think if a user purposefully creates a float2 attribute on face corners (s)he won't mind them appearing in the UV maps list as well. Trying to solve that issue pre-emptively looks like premature optimization to me.

This issue was referenced by 6514bb05ea

This issue was referenced by 6514bb05ea5a138d897151db02cb0bad9fe01968
Bastien Montagne added this to the Pipeline, Assets & IO project 2023-02-09 15:40:38 +01:00
Philipp Oeser removed the
Interest
Nodes & Physics
label 2023-02-10 08:44:02 +01:00
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 Assignees
6 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#98366
No description provided.