16
$\begingroup$

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?

$\endgroup$
6
  • 2
    $\begingroup$ 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. $\endgroup$
    – John Eason
    Dec 4, 2021 at 10:03
  • $\begingroup$ Great tutorial thanks. Unfortunately the browser is not as convenient as I'd hope $\endgroup$
    – TheJeran
    Dec 4, 2021 at 10:27
  • 5
    $\begingroup$ 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 (?) $\endgroup$
    – moonboots
    Dec 4, 2021 at 10:27
  • 2
    $\begingroup$ @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. $\endgroup$
    – John Eason
    Dec 4, 2021 at 10:46
  • $\begingroup$ 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. $\endgroup$
    – TheJeran
    Dec 4, 2021 at 12:29

3 Answers 3

2
+50
$\begingroup$

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.

$\endgroup$
1
$\begingroup$

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.

$\endgroup$
-1
$\begingroup$

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.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .