Making a Blender asset pack, how to distinguish variations? (because names get cut off in the UI)

I’ve run into a problem while making a Blender asset pack (intended for use in the Asset Browser), and I’m wondering if there’s a solution, or if I’m just off the mark as to proper practice.

I’ve got a number of subtle variants of a each asset-- in my current situation, it’s soda cans with different edge counts on the cylindrical spin, so there’s a “16”, a “32”, and a “64”. The variations are subtle enough that the thumbnails won’t show them, and when I’ve got something like “Aim-Hi Root Beer Can 16” versus “Aim-Hi Root Beer Can 32”, the names are both truncated to “Aim-Hi Root Beer …”, so determining what’s what involves guessing, inference, or stretching out the details panel to fit the whole name.

My first thought was Catalogs, and while I could put them into catalogs in a way that worked well on my own machine, catalogs require the sidecar blender_assets.cats.txt file, which can’t be packaged with the .blend file, so it always has to be transmitted separately, and it can’t be integrated with the user’s current library unless they make a new library directory just for that one pack.

So, thoughts and ideas I’ve had so far:

  1. Resign myself to it, and front-load the variant in the name so it shows up with truncation, or do something like a callout in the thumbnail. This is ugly and doesn’t scale well, but is probably the fallback option if I want one.
  2. Solve all problems with Python: Make a Python script that goes through some property in the objects and assigns the categories accordingly. Put it in as a Text datablock and tell the user how to Alt+P run it. Not terribly great, since a user shouldn’t trust some yahoo off the street writing bug- and exploit-free Python to make things work.
  3. Solve all problems with Python, Extreme Edition: Make a Blender addon that does this. It’ll be a lot of time sunk and nobody will care.

So, I suppose the first question is: Am I just Doing It Wrong, fundamentally? Am I just thinking about the packaging and distribution of Blender asset-pack files incorrectly? Is a person expected to put each pack in its own asset directory (which would make shipping a sidecar or naming objects less long-windedly work)? Should I be putting variations in different .blend files, or something like that? (That specifically wouldn’t solve my issues, I don’t think, since if you drop all the .blend files into your asset library directory, you’re going to see everything in a big pile, still.)

Absent that, is there some feature or process consideration that I just haven’t stumbled over yet that solves all my problems? Is the Asset Browser still in its infancy enough that this sort of thing hasn’t taken shape yet? How do other people solve this problem, or do they?

Why not just rename them something that won’t be affected…

to >>> AHRB-16 ?
It won’t really matter then as the Thumbnail image should be enough for selecting the Brand and the Heights…

I suppose that’s a possible workaround, but it falls to edgier cases quickly and just feels like willingly going back to the 8.2 DOS filename days for no reason.

I suppose I’ll have to see about working up some sort of addon once I’m back at a PC.

I ended up leaning on cataloging to separate variations, and a Python script to integrate the catalogs.

I added a catalog hierarchy in the file, generated a blender_assets.cats.txt file in the directory, copied the contents of that to a blender_assets.cats.txt textblock in the .blend file itself, and added this script that someone can Alt+P to run themselves:

"""
This file comes with catalog information for use in the Asset Browser.
To assign Asset Browser catalogs for these assets, run this script:

    1.) Copy this .blend file to your asset library directory (if you haven't already)
    2.) Open the copy of the .blend file in your asset library directory (if you haven't already)
    3.) View this script (If you can read this, you currently are)
    4.) Run this script using the "Text > Run Script" menu item, or Alt+P
    
    
Alternatively, find the blender_assets.cats.txt Text item (in the menu above) and manually combine the contents
with the blender_assets.cats.txt file in your asset library (or copy it all to a new one, if none exists).
"""

# Python script to copy or integrate the packed blender_assets.cats.txt Text datablock with the external
# blender_assets.cats.txt file.

import bpy
import re
import shutil
from bpy.path import abspath
from os.path import isfile

# If version 2 or whatever comes around and it's compatible, just bump this number to make the script work
MAX_CATSFILE_VERSION = 1

cat_file_path = abspath('//blender_assets.cats.txt')
backup_file_path = abspath('//blender_assets.cats.backup.txt')

def get_cats_by_uuid(catfile: str) -> dict[str, str]:
    lines = catfile.split('\n')
    uuids = {}
    for line in lines:
        match = re.search('([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}):.+', line)
        if not match:
            continue
        uuid = match.group(1)
        uuids[uuid] = line
    return uuids


def just_dump():
    """
    Copy the blender_assets.cats.txt textblock from this .blend file to an external file.
    """
    if not 'blender_assets.cats.txt' in bpy.data.texts:
        raise Exception('Internal error: Cannot find text datablock blender_assets.cats.txt')
    fh = open(cat_file_path, 'x')
    fh.write(bpy.data.texts['blender_assets.cats.txt'].as_string())
    fh.close()
    

def add_unseen():
    """
    Add UUIDs from the blender_assets.cats.txt textblock from this .blend file to the external
    blender_assets.cats.txt file if they are not already present
    """

    if not 'blender_assets.cats.txt' in bpy.data.texts:
        raise Exception('Internal error: Cannot find text datablock blender_assets.cats.txt')

    # Read existing information and find new UUIDs
    fh = open(cat_file_path, 'r')
    existing_cats_file = fh.read()
    fh.close()

    version_lines = [line for line in existing_cats_file.split('\n') if re.match('^VERSION \d+$', line)]
    if not version_lines:
        raise Exception('Cannot find VERSION in blender_assets.cats.txt file. It may be a newer version, or invalid.')

    version = int(version_lines[0][8:])
    print(f"Catalog file is version {version}, max supported is version {MAX_CATSFILE_VERSION}")
    if version > MAX_CATSFILE_VERSION:
        raise Exception(f"VERSION in blender_assets.cats.txt file is version {version} and may not be compatible with version {MAX_CATSFILE_VERSION}. Change MAX_CATSFILE_VERSION in the script if you want to try it.")

    existing_cats = get_cats_by_uuid(existing_cats_file)
    my_cats = get_cats_by_uuid(bpy.data.texts['blender_assets.cats.txt'].as_string())
    new_cats = { uuid: spec for (uuid, spec) in my_cats.items() if uuid not in existing_cats }

    new_lines = [ line for line in new_cats.values() ]

    if not new_lines:
        return
    
    # Make a backup
    shutil.copyfile(cat_file_path, backup_file_path)
    
    # Write the new lines
    fh = open(cat_file_path, 'a')
    fh.write('\n'.join(new_lines))
    fh.close()
    

def do_export():
    message = ""
    def draw(s, context):
        s.layout.label(text=message)

    try:
        if not isfile(abspath('//blender_assets.cats.txt')):
            just_dump()
            message = "Created a catalog file"
        else:
            add_unseen()
            message = "Added new catalogs"
        bpy.context.window_manager.popup_menu(draw, title="OK")
    except Exception as e:
        message = str(e)
        bpy.context.window_manager.popup_menu(draw, title="Error")


# Actually do it:
do_export()

Duplicate the outliner and resize is a solution too: