16

I would like to use the asset library, but everything I add to it is only stored on the current file which is of little use. There's no intuitive way to add assets to the main library and apparently there's supposed to be an append option, but I don't see an append option.

What am I missing?

Gorgious
  • 30,723
  • 2
  • 44
  • 101
TheJeran
  • 2,601
  • 1
  • 8
  • 24
  • 2
    I've not used it yet but this is from a tutorial about the asset browser in the November beta version of 3.0 which might help. – John Eason Dec 04 '21 at 10:03
  • Great tutorial thanks. Unfortunately the browser is not as convenient as I'd hope – TheJeran Dec 04 '21 at 10:27
  • 5
    I guess you need to save a copy of your file in the folder you've chosen as asset library, then the objects that you've marked as assets in this file will be available if you select the User Library. If you want a file to contain all your assets I guess you need to open this file and import the objects. It would have been great to have a kind of "export as asset" if this is what you're looking for but it doesn't seem to work this way (?) – moonboots Dec 04 '21 at 10:27
  • 2
    @JeranPoehls I believe it's still under development with lots more to come, probably in 3.1. There's a long interview about it with Sybren Stüvel one of the developers (specifically the pose library section, but including other bits of it as well) here. That was recorded back in June I think, but there's also another Blender Today video here detailing some of the later updates. – John Eason Dec 04 '21 at 10:46
  • Yea I've just created a blend file for materials and one for models and am just appending stuff to them. Hopefully in the future you can append TO files instead just appending from. – TheJeran Dec 04 '21 at 12:29
  • It's still in work in progress, but it may be the solution to your problem : Save assets directly outside current file This free addon exports the selected object/material to an empty blend file and saves it to the library of your choice. – Strewer Jan 25 '22 at 11:33

3 Answers3

2

Add selected data-block(s) in Outliner to the library on current blend file

Here is the script to achieve this:

  1. Make sure you have a library Path

enter image description here

  1. Make sure the current blend file is saved

  2. Run Script in Text Editor

enter image description here

import bpy
from pathlib import Path
from os.path import join as os_path_join
from bpy.props import *
from bpy.types import Operator, Panel
from bpy.utils import register_class, unregister_class
from collections import defaultdict
from bpy.app.handlers import persistent

id_type_to_blend_data = { "Action": "actions", "Armature": "armatures", "Brush": "brushes", "CacheFile": "cache_files", "Camera": "cameras", "Curve": "curves", "VectorFont": "fonts", "GreasePencil": "grease_pencils", "Collection": "collections", "Image": "images", "Key": "shape_keys", "PointLight": "lights", "FreestyleLineStyle": "linestyles", "Lattice": "lattices", "Material": "materials", "Mesh": "meshes", "MovieClip": "movieclips", "GeometryNodeTree": "node_groups", "CompositorNodeTree": "node_groups", "ShaderNodeTree": "node_groups", "TextureNodeTree": "node_groups", "Object": "objects", "PaintCurve": "paint_curves", "Palette": "palettes", "ParticleSettings": "particles", "LightProbe": "lightprobes", "Scene": "scenes", "Speaker": "speakers", "Text": "texts", "ImageTexture": "textures", "WindowManager": "window_managers", "World": "worlds", "WorkSpace": "workspaces", } id_type_to_inner = { "Action": "Action", "Armature": "Armature", "Brush": "Brush", "CacheFile": "CacheFile", "Camera": "Camera", "Curve": "Curve", "VectorFont": "Font", "GreasePencil": "GPencil", "Collection": "Collection", "Image": "Image", "PointLight": "Light", "FreestyleLineStyle": "FreestyleLineStyle", "Lattice": "Lattice", "Material": "Material", "Mesh": "Mesh", "MovieClip": "MovieClip", "GeometryNodeTree": "NodeTree", "CompositorNodeTree": "NodeTree", "ShaderNodeTree": "NodeTree", "TextureNodeTree": "NodeTree", "Object": "Object", "PaintCurve": "PaintCurve", "Palette": "Palette", "ParticleSettings": "ParticleSettings", "LightProbe": "LightProbe", "Scene": "Scene", "Speaker": "Speaker", "Text": "Text", "ImageTexture": "Texture", "World": "World", "WorkSpace": "WorkSpace", }

def get_outliner_area_region(): try: success = False for area in bpy.context.screen.areas: if area.type == "OUTLINER": success = True break if not success: return None, None

    success = False
    for region in area.regions:
        if region.type == "WINDOW":
            success = True
            break
    if not success: return None, None

    return area, region
except:
    return None, None


def get_enum_items(self, context): try: lib_ind = bpy.context.preferences.filepaths.asset_libraries except: get_enum_items.path_items = []

get_enum_items.path_items = [(str(r), p.path, "") for r, p in enumerate(lib_ind)]
return get_enum_items.path_items

get_enum_items.path_items = []

class NPanel(Panel): bl_label = "Library Tool" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "Library Tool" bl_idname = "LIB_PT_TOOL"

def draw(self, context):
    layout = self.layout
    col = layout.column()
    col.prop(context.scene, "lib_ind")
    col.prop(context.scene, "lib_blend")
    col.operator(AddLib.bl_idname)

class AddLib(Operator): bl_idname = "view3d.add_lib" bl_label = "Lib Add from Outliner" bl_description = "Add Library from Outliner selected data-blocks" bl_options = {'REGISTER', 'UNDO'}

def error_end(self, s):
    self.report({'WARNING'}, s)
    return {'CANCELLED'}

def invoke(self, context, event):
    global current_path
    current_path = bpy.data.filepath
    if not current_path: return self.error_end("Need Save current blend file first, cancelled")

    try:
        lib_paths = bpy.context.preferences.filepaths.asset_libraries
    except:
        return self.error_end("Library Paths not find, cancelled")

    if not lib_paths: return self.error_end("No Library Paths, cancelled")

    try:
        tar_ind = int(context.scene.lib_ind)
        tar_path = Path(lib_paths[tar_ind].path)
    except:
        return self.error_end("Target Path not find, cancelled")

    success = False
    for blend in tar_path.glob("**/*.blend"):
        if not blend.is_file(): continue
        if blend.stem == context.scene.lib_blend:
            success = True
            break
    if not success: return self.error_end("Could not find the library blend file, please add an empty blend file to the library directory first.")

    area, region = get_outliner_area_region()
    if area and region:
        with bpy.context.temp_override(area=area, region=region):
            ids = [(e.name, type(e).__name__) for e in bpy.context.selected_ids if hasattr(e, "asset_mark") and type(e).__name__ in id_type_to_inner]
    else:
        return self.error_end("Outliner not find, cancelled")

    if not ids: return self.error_end("No Markable Selected data-blocks in Outliner, cancelled")

    global ddict, lib_blend
    lib_blend = blend
    ddict = defaultdict(list)
    for name, ty in ids:
        ddict[ty].append(name)

    print("load file")
    bpy.app.handlers.load_post.append(load_post)
    bpy.ops.wm.open_mainfile(filepath=str(blend))

    print("end")
    return {'FINISHED'}

@persistent def load_post(dummy): print("load_post") old_names = {} for ty, names in ddict.items(): old_names[ty] = {e.name for e in getattr(bpy.data, id_type_to_blend_data[ty])} inner = id_type_to_inner[ty]

    for name in names:
        print(name)
        bpy.ops.wm.append(
            filepath=os_path_join(current_path, inner, name),
            directory=os_path_join(current_path, inner),
            filename=name)

blend_data = bpy.data
for ty in ddict:
    names = old_names[ty]
    for obj in getattr(blend_data, id_type_to_blend_data[ty]):
        if obj.name not in names:
            obj.asset_mark()

bpy.ops.wm.save_as_mainfile(filepath=str(lib_blend))
bpy.app.handlers.load_post.remove(load_post)
bpy.ops.wm.open_mainfile(filepath=current_path)

reg_cls = ( NPanel, AddLib, )

def register(): for cls in reg_cls: register_class(cls)

bpy.types.Scene.lib_ind = EnumProperty(name="Library Paths", items=get_enum_items)
bpy.types.Scene.lib_blend = StringProperty(name="Library Blend file", default="_lib_")

def unregister(): for cls in reg_cls: unregister_class(cls)

if name == "main": register()

  1. Choose a path in Library Tool category in 3D Viewport N-panel

enter image description here

  1. Add an empty blend file to this directory and rename to _lib_

enter image description here

  1. Open 1 Outliner and go to blend file category

enter image description here

  1. Selct material(s)

enter image description here

  1. Press the Button in N-panel

enter image description here

It will open the _lib_.blend and append the selected data-block(s), mark the assets, save, and open the current blend file again.

X Y
  • 5,234
  • 1
  • 6
  • 20
1

you can save your blenderfile in folder User Library. User/Documents/Blender/Assets/ is default location. And local assed are now add to main libary.

If you want place them in catalog in main libary. you might need to reopen the file. by right clicking on the assets.

Hope this helps.

wieger
  • 31
  • 3
-1

Copy the file to your Assets file in your blender file, if it doesn't exist create it, else change your file path in preferences. Then open your file which you placed in Assets, choose the object in your Outliner usually on the right right click the object and Mark as Asset it worked for me. Don't forget to save your changes and reload the file where you want to access your new added assets.

jose
  • 11
  • 2