Assets: Implement Traits #105841

Open
Harley Acheson wants to merge 2 commits from Harley/blender:AssetTraits into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
Member

Allow Assets to have system-defined keywords to provide information
about the type of the asset.


Implementation of task #105808 for design #105807. This is mostly a copy of the code that implements tags, but without any user-facing addition and deletion of traits.

Allow Assets to have system-defined keywords to provide information about the type of the asset. --- Implementation of task #105808 for design #105807. This is mostly a copy of the code that implements tags, but without any user-facing addition and deletion of traits.
Julian Eisel requested changes 2023-03-17 15:13:53 +01:00
Julian Eisel left a comment
Member

I think we can remove most of the editing capabilities. Let's for now only have a list or traits that is managed internally, with no API functions to edit them. I guess we'd want that later to support custom asset types managed by add-ons, but we may want to use different ways to define those (e.g. a bl_asset_traits property for a new asset type definition).

Plus, we indeed don't need any UI for the traits. We might want to display the traits as non-editable tags in the tags list, for informal purposes.

I think we can remove most of the editing capabilities. Let's for now only have a list or traits that is managed internally, with no API functions to edit them. I guess we'd want that later to support custom asset types managed by add-ons, but we may want to use different ways to define those (e.g. a `bl_asset_traits` property for a new asset type definition). Plus, we indeed don't need any UI for the traits. We might want to display the traits as non-editable tags in the tags list, for informal purposes.
@ -104,0 +115,4 @@
return trait;
}
AssetTrait *BKE_asset_metadata_trait_add(AssetMetaData *asset_data, const char *name)
Member

Can be removed. I'd for traits we just want to ensure a specific trait is set, we never want the name to be changed (like no automatic .001 suffix). So _ensure() is all we need.

Can be removed. I'd for traits we just want to ensure a specific trait is set, we never want the name to be changed (like no automatic `.001` suffix). So `_ensure()` is all we need.
Harley marked this conversation as resolved
@ -27,0 +30,4 @@
*/
typedef struct AssetTrait {
struct AssetTrait *next, *prev;
char name[64];
Member

Add MAX_NAME comment.

Add `MAX_NAME` comment.
Harley marked this conversation as resolved
@ -91,0 +103,4 @@
ListBase traits; /* AssetTrait */
short active_trait;
/** Number of traits to avoid counting. Can be moved with tot_tags to runtime data. */
short tot_traits;
Member

Don't think we need this. I'd like to have a runtime only has of the asset traits in AssetRepresentation. If we ever need the count of traits we can get the size from that.

Don't think we need this. I'd like to have a runtime only has of the asset traits in `AssetRepresentation`. If we ever need the count of traits we can get the size from that.
Harley marked this conversation as resolved
@ -440,0 +534,4 @@
RNA_def_struct_name_property(srna, prop);
}
static void rna_def_asset_traits_api(BlenderRNA *brna, PropertyRNA *cprop)
Member

Can be removed entirely I guess.

Can be removed entirely I guess.
Harley marked this conversation as resolved
@ -507,0 +641,4 @@
RNA_def_property_struct_type(prop, "AssetTrait");
RNA_def_property_editable_func(prop, "rna_AssetMetaData_editable");
RNA_def_property_ui_text(prop,
"Traits",
Member

I think we should consistently use the term "asset traits", not just "traits".

I think we should consistently use the term "asset traits", not just "traits".
Harley marked this conversation as resolved
@ -507,0 +646,4 @@
"general asset management");
rna_def_asset_traits_api(brna, prop);
prop = RNA_def_property(srna, "active_trait", PROP_INT, PROP_NONE);
Member

Shouldn't be needed since we don't allow changing traits in the UI.

Shouldn't be needed since we don't allow changing traits in the UI.
Harley marked this conversation as resolved
Harley Acheson force-pushed AssetTraits from 427fb6e203 to dd518f4313 2023-03-17 21:13:58 +01:00 Compare
Author
Member

@JulianEisel - Sorry for the delay; took a while to get rid of all my extras without leaving any cruft.

@JulianEisel - Sorry for the delay; took a while to get rid of all my extras without leaving any cruft.
Harley Acheson force-pushed AssetTraits from dd518f4313 to 91456a87fa 2023-03-20 23:09:59 +01:00 Compare
Harley Acheson added this to the User Interface project 2023-04-07 19:22:42 +02:00

@JulianEisel @Harley what is the status of this patch?

@JulianEisel @Harley what is the status of this patch?
Julian Eisel requested changes 2023-04-11 11:15:33 +02:00
Julian Eisel left a comment
Member

Could you remove the ensure_traits_fn callbacks for now as noted in #105808 (comment)? We don't need most of these traits yet, I rather add traits as needed, and don't set a whole bunch of unused traits just because they might be useful in future. (Although to a degree we may have to do that for forwards compatibility.)

Also, if a patch is ready for review, please make sure to remove the "WIP:" from the title. This is meant for patches that you still intend to work on independently of the review process.

Could you remove the `ensure_traits_fn` callbacks for now as noted in https://projects.blender.org/blender/blender/issues/105808#issuecomment-905308? We don't need most of these traits yet, I rather add traits as needed, and don't set a whole bunch of unused traits just because they might be useful in future. (Although to a degree we may have to do that for forwards compatibility.) Also, if a patch is ready for review, please make sure to remove the "WIP:" from the title. This is meant for patches that you still intend to work on independently of the review process.
@ -1044,0 +1045,4 @@
{
bNodeTree &node_tree = *static_cast<bNodeTree *>(asset_ptr);
BLI_assert(GS(node_tree.id.name) == ID_NT);
BKE_asset_metadata_trait_ensure(asset_data, node_tree.typeinfo->ui_description);
Member

Why would we store the UI description as trait? But again, I wouldn't even define the ensure_traits_fn anyway, and just let the nodes module implement the traits they need.

Why would we store the UI description as trait? But again, I wouldn't even define the `ensure_traits_fn` anyway, and just let the nodes module implement the traits they need.
Harley marked this conversation as resolved
@ -1223,0 +1225,4 @@
{
Object *ob = (Object *)asset_ptr;
BLI_assert(GS(ob->id.name) == ID_OB);
BKE_asset_metadata_trait_ensure(asset_data, get_obdata_defname(ob->type));
Member

There are two problems with get_obdata_defname():

  • It translates string, asset traits shouldn't be stored translated.
  • Mball, GPencil, LightProbe and such are not the most user friendly terms. I'd prefer Metaball, Grease Pencil, Light Probe.

I guess for now the best option is to have a bunch of #defines in DNA_object_types.h (with a comment noting these may be written to files!), use this in rna_enum_object_type_items() (to avoid duplication, this stuff easily gets out of sync), and add something like get_obdata_ui_name().

We could in theory use RNA_enum_name(), but that would mean that changing UI names in rna_enum_object_type_items() would break compatibility. This isn't the case usually and I rather avoid this, with the #defines in DNA headers it's more clear I think.

There are two problems with `get_obdata_defname()`: - It translates string, asset traits shouldn't be stored translated. - *Mball*, *GPencil*, *LightProbe* and such are not the most user friendly terms. I'd prefer *Metaball*, *Grease Pencil*, *Light Probe*. I guess for now the best option is to have a bunch of `#define`s in `DNA_object_types.h` (with a comment noting these may be written to files!), use this in `rna_enum_object_type_items()` (to avoid duplication, this stuff easily gets out of sync), and add something like `get_obdata_ui_name()`. We *could* in theory use `RNA_enum_name()`, but that would mean that changing UI names in `rna_enum_object_type_items()` would break compatibility. This isn't the case usually and I rather avoid this, with the `#define`s in DNA headers it's more clear I think.
Harley marked this conversation as resolved
@ -41,1 +41,4 @@
BKE_asset_metadata_trait_ensure(id->asset_data, "ID");
BKE_asset_metadata_trait_ensure(id->asset_data, id_type_info->name);
BKE_asset_metadata_trait_ensure(id->asset_data, id->name + 2);
Member

The name as trait doesn't make sense really, this is not type information.

The name as trait doesn't make sense really, this is not type information.
Harley marked this conversation as resolved
@ -25,2 +25,4 @@
} AssetTag;
/**
* \brief System-defined trait.
Member

What does System-defined mean? The OS? Would put it something like: "Keywords describing type characteristics of an asset".

What does *System-defined* mean? The OS? Would put it something like: "Keywords describing type characteristics of an asset".
Harley marked this conversation as resolved
@ -26,1 +26,4 @@
/**
* \brief System-defined trait.
* Defined separately from AssetTag because we might want to vary name length.
Member

Would remove this, it's just a different kind of entity/concept.

Would remove this, it's just a different kind of entity/concept.
Harley marked this conversation as resolved
@ -91,0 +101,4 @@
/** System defined keywords for describing the type of asset. */
ListBase traits; /* AssetTrait */
short active_trait;
Member

Not needed since the traits can't be edited right now. Tags only need this for the UI.

Not needed since the traits can't be edited right now. Tags only need this for the UI.
Harley marked this conversation as resolved
@ -136,0 +141,4 @@
return BLI_sprintfN("asset_data.traits[\"%s\"]", asset_trait_name_esc);
}
static int rna_AssetTrait_editable(PointerRNA *ptr, const char **r_info)
Member

Shouldn't be needed since traits are never editable.

Shouldn't be needed since traits are never editable.
Harley marked this conversation as resolved
Julian Eisel reviewed 2023-04-11 11:22:18 +02:00
@ -507,0 +550,4 @@
RNA_def_property_ui_text(prop,
"Asset Traits",
"Custom traits (name tokens) for the asset, used for filtering and "
"general asset management");
Member

Suggest: "Keywords describing type characteristics of an asset. Used to determine how an asset should behave, and to provide additional information and filtering options to the user"

Suggest: "Keywords describing type characteristics of an asset. Used to determine how an asset should behave, and to provide additional information and filtering options to the user"
Harley marked this conversation as resolved
Julian Eisel reviewed 2023-04-11 11:24:56 +02:00
@ -89,2 +99,4 @@
char _pad[4];
/** System defined keywords for describing the type of asset. */
Member

Again System defined is a bit vague. Would just add a /** See #AssetTrait. */ comment here.

Again *System defined* is a bit vague. Would just add a `/** See #AssetTrait. */` comment here.
Harley marked this conversation as resolved
Harley Acheson force-pushed AssetTraits from 91456a87fa to 352db5ccca 2023-04-12 00:47:37 +02:00 Compare
Harley Acheson changed title from WIP: Assets: Implement Traits to Assets: Implement Traits 2023-04-12 00:47:54 +02:00
Author
Member

@JulianEisel - Why would we store the UI description as trait?

I removed that section so didn't really look at it again, but I think that when I was examining the data there the names had multiple words CamelCased together but the descriptions were nicer. But again, that code is gone now anyway.

What does System-defined mean? The OS?

I changed it all to your requested terminology, but I do think that "system-defined" was the best counterpoint to "user-defined" as it helped explain the similarities and differences. Now we have "User defined tag" and a very similar looking thing as "Keywords describing type characteristics of an asset." Don't think anyone would think system-defined had anything to do with the OS or the platform - just implies not defined or managed by the user.

> @JulianEisel - Why would we store the UI description as trait? I removed that section so didn't really look at it again, but I *think* that when I was examining the data there the names had multiple words CamelCased together but the descriptions were nicer. But again, that code is gone now anyway. > What does System-defined mean? The OS? I changed it all to your requested terminology, but I do think that "system-defined" was the best counterpoint to "user-defined" as it helped explain the similarities and differences. Now we have "User defined tag" and a very similar looking thing as "Keywords describing type characteristics of an asset." Don't think anyone would think system-defined had anything to do with the OS or the platform - just implies not defined or managed by the user.
Julian Eisel reviewed 2023-04-13 16:12:41 +02:00
@ -42,1 +48,4 @@
/** Tags and Traits to match against. These are newly allocated, and compared against the
* #AssetMetaData.tags and #AssetMetaData.traits. */
ListBase tags; /* AssetTag */
ListBase traits; /* AssetTrait */
Member

Either remove this or actually implement the filtering in ED_asset_filter_matches_asset().

Either remove this or actually implement the filtering in `ED_asset_filter_matches_asset()`.
Harley marked this conversation as resolved
Julian Eisel reviewed 2023-04-13 16:13:41 +02:00
@ -2144,6 +2152,47 @@ static const char *get_obdata_defname(int type)
}
}
static const char *get_obdata_uiname(int type)
Member

Note that this string isn't translated in a comment.

Note that this string isn't translated in a comment.
Harley marked this conversation as resolved
Julian Eisel reviewed 2023-04-13 16:14:56 +02:00
@ -1223,3 +1231,3 @@
static AssetTypeInfo AssetType_OB = {
/*pre_save_fn*/ object_asset_pre_save,
};
/*EnsureTraitsFn*/ object_asset_ensure_traits};
Member

/*ensure_traits_fn*/ object_asset_ensure_traits,
The trailing comma ensures the closing } is put on the next line, which I find more visually pleasing and we usually do this.

`/*ensure_traits_fn*/ object_asset_ensure_traits,` The trailing comma ensures the closing `}` is put on the next line, which I find more visually pleasing and we usually do this.
Harley marked this conversation as resolved
Julian Eisel reviewed 2023-04-13 16:22:43 +02:00
@ -35,2 +35,4 @@
} AssetTag;
/**
* \brief Keywords describing type characteristics of an asset. Not user-defined.
Member

Would say: "Managed by Blender, not the user".

Also note that the trait should never be translated for storage (only when displaying in the UI).

Would say: "Managed by Blender, not the user". Also note that the trait should never be translated for storage (only when displaying in the UI).
Harley marked this conversation as resolved
Julian Eisel reviewed 2023-04-13 16:25:40 +02:00
Julian Eisel left a comment
Member

I think this is almost ready, just some smaller points.

I think this is almost ready, just some smaller points.
@ -37,0 +39,4 @@
*/
typedef struct AssetTrait {
struct AssetTrait *next, *prev;
char name[64]; /* MAX_NAME */
Member

Think calling this value makes more sense. Same for the tags actually, but yeah, not worth bothering.

Think calling this `value` makes more sense. Same for the tags actually, but yeah, not worth bothering.
Harley marked this conversation as resolved
@ -46,1 +46,4 @@
/** UI Names for object types. These may be written to files,
* so changing these should be done with extreme caution. */
#define OB_UINAME_MESH "Mesh"
Member

Suggest OB_UI_NAME_MESH.

Suggest `OB_UI_NAME_MESH`.
Harley marked this conversation as resolved
@ -440,0 +452,4 @@
srna = RNA_def_struct(brna, "AssetTrait", NULL);
RNA_def_struct_path_func(srna, "rna_AssetTrait_path");
RNA_def_struct_ui_text(srna, "Asset Trait", "System defined trait (name token)");
Member

Use the same or a similar description as elsewhere. Here this is especially important, since this will be the description for the Python documentation of the type.

Use the same or a similar description as elsewhere. Here this is especially important, since this will be the description for the Python documentation of the type.
Harley marked this conversation as resolved
Hans Goudey approved these changes 2023-04-13 16:49:33 +02:00
Hans Goudey left a comment
Member

Could the get_obdata_uiname stuff be replaced with use of the IDTypeInfo of ob->data? It's a bit of a shame to add another set of defines and another switch with Blender trying to move away from that sort of thing and become more easily extensible.

Also, I know it's simple to use ListBase in DNA, but I wonder if it's worth using an array here instead. That makes it a bit more complex to add and remove items, but it makes everything else much simpler, since there would actually be type safety, etc. For example, the traits could mostly be passed as Span<AssetTrait>. The next and prev pointers could also be removed. That's my personal agenda of moving away from linked lists coming though, but maybe you find it reasonable too.

Could the `get_obdata_uiname` stuff be replaced with use of the `IDTypeInfo` of `ob->data`? It's a bit of a shame to add another set of defines and another switch with Blender trying to move away from that sort of thing and become more easily extensible. Also, I know it's simple to use `ListBase` in DNA, but I wonder if it's worth using an array here instead. That makes it a bit more complex to add and remove items, but it makes everything else much simpler, since there would actually be type safety, etc. For example, the traits could mostly be passed as `Span<AssetTrait>`. The `next` and `prev` pointers could also be removed. That's my personal agenda of moving away from linked lists coming though, but maybe you find it reasonable too.
Hans Goudey requested changes 2023-04-13 16:50:00 +02:00
Hans Goudey left a comment
Member

Oops, meant to just comment, now I can't remove myself as a reviewer though :/

Oops, meant to just comment, now I can't remove myself as a reviewer though :/
Julian Eisel requested review from Hans Goudey 2023-04-13 17:41:51 +02:00
Hans Goudey refused to review 2023-04-13 17:47:17 +02:00
Member

Could the get_obdata_uiname stuff be replaced with use of the IDTypeInfo of ob->data?

We could have a const char *ui_name in there and assign that to the ID_UI_NAME_ value indeed. Similar to id_code, id_filter and main_listbase_index.
Unfortunately the #defines would still be necessary if we want to keep the UI names in the RNA enum in sync and static.

Also, I know it's simple to use ListBase in DNA, but I wonder if it's worth using an array here instead.

For runtime there should be some kind of hash-table inside AssetRepresentation (and/or maybe inside an AssetMetaData_Runtime?). The listbase is more or less just for DNA storage. Don't think it's a big issue, not worth the complexity IMO.

> Could the `get_obdata_uiname` stuff be replaced with use of the `IDTypeInfo` of `ob->data`? We could have a `const char *ui_name` in there and assign that to the `ID_UI_NAME_` value indeed. Similar to `id_code`, `id_filter` and `main_listbase_index`. Unfortunately the `#define`s would still be necessary if we want to keep the UI names in the RNA enum in sync and static. > Also, I know it's simple to use `ListBase` in DNA, but I wonder if it's worth using an array here instead. For runtime there should be some kind of hash-table inside `AssetRepresentation` (and/or maybe inside an `AssetMetaData_Runtime`?). The listbase is more or less just for DNA storage. Don't think it's a big issue, not worth the complexity IMO.
Member

Don't think it's a big issue, not worth the complexity IMO.

I'd argue using ListBase everywhere gives its own pervasive complexity that's less obvious when adding it in the first place. But fair enough. I guess the need to store these at all is just a future-proofing thing?

>Don't think it's a big issue, not worth the complexity IMO. I'd argue using `ListBase` everywhere gives its own pervasive complexity that's less obvious when adding it in the first place. But fair enough. I guess the need to store these at all is just a future-proofing thing?
Julian Eisel reviewed 2023-04-13 18:23:08 +02:00
@ -43,0 +46,4 @@
if (id_type_info->asset_type_info && id_type_info->asset_type_info->ensure_traits_fn) {
id_type_info->asset_type_info->ensure_traits_fn(id, id->asset_data);
}
Member

Bastien is quite against doing this on asset marking only, so let's do it on file save in ED_assets_pre_save().

Bastien is quite against doing this on asset marking only, so let's do it on file save in `ED_assets_pre_save()`.
Harley marked this conversation as resolved
Member

I guess the need to store these at all is just a future-proofing thing?

They are stored in the asset metadata so this type information becomes available when loading asset representations, without loading the entire asset. Or do you mean the object data traits? Yeah we don't actually use them yet, so this is a future proofing thing indeed.

> I guess the need to store these at all is just a future-proofing thing? They are stored in the asset metadata so this type information becomes available when loading asset representations, without loading the entire asset. Or do you mean the object data traits? Yeah we don't actually use them yet, so this is a future proofing thing indeed.
Member

Talked to Bastien, he rejects the idea of something like a ui_name field in IDTypeInfo for this purpose, because then the object callback would have to get the IDTypeInfo of the object data, which creates dependencies between ID types.

So nothing to change there from the current patch, we stick to the #defines and the switch-case for the object data.

Talked to Bastien, he rejects the idea of something like a `ui_name` field in `IDTypeInfo` for this purpose, because then the object callback would have to get the `IDTypeInfo` of the object data, which creates dependencies between ID types. So nothing to change there from the current patch, we stick to the `#define`s and the switch-case for the object data.
Author
Member

@JulianEisel

Should be done with just the following notes:

Think calling this value makes more sense. Same for the tags actually, but yeah, not worth bothering.

I couldn't tell from your comment if you wanted this done for traits, tags, both, or none. So I left it alone. Can certainly do whatever you prefer.

...so let's do it on file save in ED_assets_pre_save()

I did so. But that does mean that assets loaded from a prior session have these while newly-created ones will not until saved. Maybe not a problem at all, and probably just stating the obvious.

@JulianEisel Should be done with just the following notes: > Think calling this value makes more sense. Same for the tags actually, but yeah, not worth bothering. I couldn't tell from your comment if you wanted this done for traits, tags, both, or none. So I left it alone. Can certainly do whatever you prefer. > ...so let's do it on file save in ED_assets_pre_save() I did so. But that does mean that assets loaded from a prior session have these while newly-created ones will not until saved. Maybe not a problem at all, and probably just stating the obvious.
Julian Eisel reviewed 2023-04-14 17:45:04 +02:00
Julian Eisel left a comment
Member

Almost ready!

Almost ready!
@ -2147,0 +2156,4 @@
/* Return a string identifying the object type that is *not* translated. */
static const char *get_obdata_uiname(int type)
{
switch (type) {
Member

Cast this to the enum type, so that the compiler warns when a new enumerator is introduced but not added here.

Cast this to the enum type, so that the compiler warns when a new enumerator is introduced but not added here.
Harley marked this conversation as resolved
@ -37,0 +40,4 @@
*/
typedef struct AssetTrait {
struct AssetTrait *next, *prev;
char name[64]; /* MAX_NAME */
Member

Just rename it to value, makes more sense to me.

Just rename it to `value`, makes more sense to me.
Harley marked this conversation as resolved
Author
Member

@JulianEisel - Just rename it to value, makes more sense to me.

Done. But I also changed other related phrasing around it, so in comments, argument names, etc for consistancy.

Cast this to the enum type, so that the compiler warns when a new enumerator is introduced but not added here.

I did and I was surprised that it worked. Our Object types enum was untyped so I assumed if I added one (here using ObjectType) that it would result in a billion warnings/errors all over the place. But seems to be fine with it. Cool.

> @JulianEisel - Just rename it to value, makes more sense to me. Done. But I also changed other related phrasing around it, so in comments, argument names, etc for consistancy. > Cast this to the enum type, so that the compiler warns when a new enumerator is introduced but not added here. I did and I was surprised that it worked. Our Object types enum was untyped so I assumed if I added one (here using `ObjectType`) that it would result in a billion warnings/errors all over the place. But seems to be fine with it. Cool.
Member

Committed fe7540d39a to add an ObjectType typedef, shouldn't cause any merge conflicts. We should really have that, there are plenty of switch-cases that should cover all enumerators.

Committed fe7540d39a to add an `ObjectType` typedef, shouldn't cause any merge conflicts. We should really have that, there are plenty of `switch`-`cases` that should cover all enumerators.
Author
Member

@JulianEisel - This PR seems to be done? I don't think your last comment (about ObjectType) requested any changes here, but correct me if I am misunderstanding.

@JulianEisel - This PR seems to be done? I don't think your last comment (about ObjectType) requested any changes here, but correct me if I am misunderstanding.
Julian Eisel requested changes 2023-05-01 12:10:48 +02:00
Julian Eisel left a comment
Member

Minor points, this is pretty much ready.

Minor points, this is pretty much ready.
@ -1223,2 +1230,4 @@
static AssetTypeInfo AssetType_OB = {
/*pre_save_fn*/ object_asset_pre_save,
/*EnsureTraitsFn*/ object_asset_ensure_traits,
Member

Use the callback name, not type for the comment, like we do elsewhere (ensure_traits_fn).

Use the callback name, not type for the comment, like we do elsewhere (`ensure_traits_fn`).
Harley marked this conversation as resolved
@ -2147,0 +2156,4 @@
/* Return a string identifying the object type that is *not* translated. */
static const char *get_obdata_uiname(int type)
{
switch ((ObjectType)type) {
Member

For C++ functional cast: ObjectType(type) (see style guide).

For C++ functional cast: `ObjectType(type)` (see [style guide](https://wiki.blender.org/wiki/Style_Guide/C_Cpp#C.2B.2B_Type_Cast)).
Harley marked this conversation as resolved
@ -101,0 +110,4 @@
/** See #AssetTrait. */
ListBase traits;
Member

Trailing empty line, what an eyesore :)

Trailing empty line, what an eyesore :)
Harley marked this conversation as resolved
@ -440,0 +452,4 @@
srna = RNA_def_struct(brna, "AssetTrait", NULL);
RNA_def_struct_path_func(srna, "rna_AssetTrait_path");
RNA_def_struct_ui_text(srna, "Asset Trait", "Asset keywords managed by Blender (not user defined)");
Member

"Asset keywords"? Would stick to the definition as below, e.g. "Keywords describing type characteristics of an asset (managed by Blender, not the user)".

"Asset keywords"? Would stick to the definition as below, e.g. "Keywords describing type characteristics of an asset (managed by Blender, not the user)".
Harley marked this conversation as resolved
Harley Acheson force-pushed AssetTraits from 1909c7a0e5 to 730e0645fb 2023-05-02 01:02:14 +02:00 Compare
Author
Member

@blender-bot build

@blender-bot build
Julian Eisel reviewed 2023-05-02 13:12:50 +02:00
Julian Eisel left a comment
Member

I would like to have some sign off by @mont29 and/or @brecht on the idea of storing UI names as asset traits. This patch stores the IDTypeInfo.name and OB_UI_NAME_XXX as asset traits, so they become relevant for compatibility.

I would like to have some sign off by @mont29 and/or @brecht on the idea of storing UI names as asset traits. This patch stores the `IDTypeInfo.name` and `OB_UI_NAME_XXX` as asset traits, so they become relevant for compatibility.
@ -48,0 +52,4 @@
#define OB_UI_NAME_SURF "Surface"
#define OB_UI_NAME_METABALL "Metaball"
#define OB_UI_NAME_FONT "Text"
#define OB_UI_NAME_CURVES "Hair Curves"
Member

OB_UI_NAME_CURVE and OB_UI_NAME_CURVES are a bit confusing. Should these really be saved to traits as "Curve" and "Hair Curves"? @HooglyBoogly @mont29?

I think for rna_enum_object_type_items() we can keep using the name "Hair Curve", but for the macro they should probably both read "Curve".

`OB_UI_NAME_CURVE` and `OB_UI_NAME_CURVES` are a bit confusing. Should these really be saved to traits as "Curve" and "Hair Curves"? @HooglyBoogly @mont29? I think for `rna_enum_object_type_items()` we can keep using the name "Hair Curve", but for the macro they should probably both read "Curve".

I had not seen the design of asset traits before, and I left questions in #105807.

It's not clear to me what it means exactly to have e.g. a "Mesh" trait on an asset. Does it guarantee there exist some interface to query it as a Mesh datablock? Though when used together with an "Object" trait I guess it means there you can get an Object with type mesh instead? But maybe that object has geometry nodes generating curves from the mesh? Is a distinction needed between an asset being a datablock, or being available to be retrieved as a databock?

To me it seems there can be quite a bit of nuance here, where you may need a tooltip to describe it also. And at that point maybe you might as well use an identifier, and then map that to some UI name and description. Which can then also be translated or updated over time.

I'd suggest to clearly define the meaning of traits and have an understanding of how UI and tools are intended to use them, before creating them and storing them in a way that requires us to think about compatibility. Maybe for the first version of traits it's better to only add those that have a specific meaning, like a "use this node group as a mesh modifier" trait.

I had not seen the design of asset traits before, and I left questions in #105807. It's not clear to me what it means exactly to have e.g. a "Mesh" trait on an asset. Does it guarantee there exist some interface to query it as a Mesh datablock? Though when used together with an "Object" trait I guess it means there you can get an Object with type mesh instead? But maybe that object has geometry nodes generating curves from the mesh? Is a distinction needed between an asset being a datablock, or being available to be retrieved as a databock? To me it seems there can be quite a bit of nuance here, where you may need a tooltip to describe it also. And at that point maybe you might as well use an identifier, and then map that to some UI name and description. Which can then also be translated or updated over time. I'd suggest to clearly define the meaning of traits and have an understanding of how UI and tools are intended to use them, before creating them and storing them in a way that requires us to think about compatibility. Maybe for the first version of traits it's better to only add those that have a specific meaning, like a "use this node group as a mesh modifier" trait.
Member

With #109526 we have a more solid understanding of how these traits will be used. Each trait in this popover has controls which object types and modes a node group is usable as an operator for.
image

I think it makes sense to remove the object type name traits from this PR, since it's not clear how they will be used, and it will simplify this change.

With #109526 we have a more solid understanding of how these traits will be used. Each trait in this popover has controls which object types and modes a node group is usable as an operator for. ![image](/attachments/51d2f0ab-694c-4bdb-bf6f-f760f5cf4bea) I think it makes sense to remove the object type name traits from this PR, since it's not clear how they will be used, and it will simplify this change.
Harley Acheson force-pushed AssetTraits from 730e0645fb to 83d76c28f0 2023-07-08 00:12:52 +02:00 Compare

From the examples of traits that I could see, they are exposing some RNA property of the datablock on the asset. Either an existing property like the brush mode, or one specifically created for this purpose like the node group asset settings. Even for more complex traits you could imagine defining a read-only RNA property specifically for that purpose.

The traits system doesn't have to be limited to that especially if there is an intent to integrate with OpenAssetIO traits. But for Blender native traits, if it's all RNA properties you immediately get an unambiguous meaning, unique identifier, UI name and description. It would be like marking some boolean and enum properties to be indexed more than a new type of data.

So for example traits could be:

type:Brush
type:Mesh
property:Object.type=MESH
property:Brush.mode=SCULPT
property:NodeTree.asset.is_modifier
From the examples of traits that I could see, they are exposing some RNA property of the datablock on the asset. Either an existing property like the brush mode, or one specifically created for this purpose like the node group asset settings. Even for more complex traits you could imagine defining a read-only RNA property specifically for that purpose. The traits system doesn't have to be limited to that especially if there is an intent to integrate with OpenAssetIO traits. But for Blender native traits, if it's all RNA properties you immediately get an unambiguous meaning, unique identifier, UI name and description. It would be like marking some boolean and enum properties to be indexed more than a new type of data. So for example traits could be: ``` type:Brush type:Mesh property:Object.type=MESH property:Brush.mode=SCULPT property:NodeTree.asset.is_modifier ```
Hans Goudey reviewed 2023-07-10 13:56:20 +02:00
@ -136,1 +137,4 @@
static AssetTrait *asset_metadata_trait_add(AssetMetaData *asset_data, const char *const value)
{
AssetTrait *trait = (AssetTrait *)MEM_callocN(sizeof(*trait), __func__);
Member

MEM_cnew<AssetTrait>(__func__) is simpler in C++ code

`MEM_cnew<AssetTrait>(__func__)` is simpler in C++ code
Harley marked this conversation as resolved
@ -137,0 +151,4 @@
return result;
}
AssetTrait *trait = (AssetTrait *)BLI_findstring(&asset_data->traits, value, offsetof(AssetTrait, value));
Member
`static_cast<AssetTrait *>` (https://wiki.blender.org/wiki/Style_Guide/C_Cpp#C.2B.2B_Type_Cast)
Harley marked this conversation as resolved
@ -102,1 +111,4 @@
char _pad[4];
/** See #AssetTrait. */
ListBase traits;
Member

Not sure what Julian thinks about this, personally I think it's better these days to use an array of pointers in DNA rather than a linked list. i.e. AssetTrait **. That makes adding and removing elements a bit more complex, but it means code can be type safe when dealing with an array of traits, because we can pass around Span<const AssetTrait *>. That's really nice, in comparison with just ListBase.

Not sure what Julian thinks about this, personally I think it's better these days to use an array of pointers in DNA rather than a linked list. i.e. `AssetTrait **`. That makes adding and removing elements a bit more complex, but it means code can be type safe when dealing with an array of traits, because we can pass around `Span<const AssetTrait *>`. That's really nice, in comparison with just `ListBase`.
Harley Acheson added 1 commit 2023-07-13 18:55:07 +02:00
Author
Member

@HooglyBoogly - leaving the traits with a ListBase (for now) to remain consistent with tags, until we here one way or the other.

@HooglyBoogly - leaving the traits with a ListBase (for now) to remain consistent with tags, until we here one way or the other.
Hans Goudey approved these changes 2023-07-13 19:27:11 +02:00
Hans Goudey left a comment
Member

Cool, works for me. I'll accept and we'll see what Julian thinks about that point (hopefully agrees? :). (For a recent example, see bNodePanel **panels_array)

Cool, works for me. I'll accept and we'll see what Julian thinks about that point (hopefully agrees? :). (For a recent example, see `bNodePanel **panels_array`)
Member

Based on discussions about "traits" for node group assets and node tools, it seems like they won't be necessary. They ended up not being a necessary abstraction, since they were basically just a cache of properties that made more sense stored on the data-block itself (not the asset). Not sure if there's still need for them longer term-- I also just don't like leaving this PR in a limbo state (and I'm personally not that convinced by the need for them either). If we don't have a need for them, might make sense to close this for now.

Based on discussions about "traits" for node group assets and node tools, it seems like they won't be necessary. They ended up not being a necessary abstraction, since they were basically just a cache of properties that made more sense stored on the data-block itself (not the asset). Not sure if there's still need for them longer term-- I also just don't like leaving this PR in a limbo state (and I'm personally not that convinced by the need for them either). If we don't have a need for them, might make sense to close this for now.
This pull request has changes conflicting with the target branch.
  • source/blender/blenkernel/BKE_asset.h
  • source/blender/blenkernel/intern/asset.cc
  • source/blender/editors/asset/intern/asset_indexer.cc
  • source/blender/makesdna/DNA_asset_types.h

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u AssetTraits:Harley-AssetTraits
git checkout Harley-AssetTraits
Sign in to join this conversation.
No reviewers
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
5 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#105841
No description provided.