Commit 47b88c49 authored by Dawid Huczynski's avatar Dawid Huczynski
Browse files

update API, search, relpath, fixes

parent 15d7cf1a
......@@ -5,14 +5,15 @@ Did this one due to dealys for internal asset manager for Blender.
**Made for simplicity of usage.**
- Opens `blend`, `obj`, `fbx`, `hdr`, `exr` from the same place.
- Dynamic, and custom categories: Except of `material`, and `particle` this addon will follow your library layout, folders and subfolders.
- absolute or relative libraries folder,
- creates structured collections: `Assets`, `Assets/Particles`
- With `Ctrl+scroll` over the categories it is even faster.
- Small and simple UI. Simple, and small to modify code as you like.
- option to batch render all previews.
- works as operator too (One can search `Simple Asset Manager` in command search, and assign a SHORTCUT!! :) But there is no default shortcut assigned for it)
- Opens `blend`, `obj`, `fbx`, `hdr`, `exr` from the same place;
- Dynamic, and custom categories: Except of `material`, and `particle` this addon will follow your library layout, folders and subfolders;
- absolute or relative libraries folder;
- creates structured collections: `Assets`, `Assets/Particles`;
- With `Ctrl+scroll` over the categories it is even faster;
- Small and simple UI. Simple, and small to modify code as you like;
- option to batch render all previews;
- works as operator too (One can search `Simple Asset Manager` in command search, and assign a SHORTCUT!! :) But there is no default shortcut assigned for it);
- search bar.
None of the mangers I've tried was enough for me. Asset flinger was nice, but the idea with previews was much better. Chocofur asset manager is almost perfect, but still, it had its cons: separate spaces for categories, and (i only assume) fixed categories.
......@@ -37,7 +38,7 @@ You will see all your folders as categories, and if any folder has additional fo
![Small and handy.](preview.gif "Small and handy")
## Changelog
- 0.9.5 - relative library path, fix non-english characters, fix at origin import, added rotation.
- 0.9.5 - search bar, relative library path, fix non-english characters, fix at origin import, added rotation, API updates.
- 0.9.4 - fixed append at origin issue, particles when imported again use previous import group.
- 0.9.3 - UI popup operator (shortcut)
- 0.9.0 - fixed silent enum error, improts cllections from blend files, imports particles as groups, can choose exr for render prev, fix render prevs.
......
No preview for this file type
......@@ -53,10 +53,20 @@ def prepare_scene(blendFile):
# clean scene
for ob in bpy.data.objects:
ob.hide_select = False
ob.hide_render = False
ob.hide_viewport = False
ob.hide_set(False)
for coll in bpy.data.collections:
coll.hide_select = False
coll.hide_render = False
coll.hide_viewport = False
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=True)
purge(bpy.data.collections)
purge(bpy.data.objects)
purge(bpy.data.cameras)
purge(bpy.data.lights)
purge(bpy.data.meshes)
purge(bpy.data.particles)
purge(bpy.data.materials)
purge(bpy.data.textures)
......@@ -71,7 +81,7 @@ def prepare_scene(blendFile):
eevee.gtao_distance = 1
render.filepath = os.path.splitext(blendFile)[0]
render.stamp_note_text = os.path.splitext(blendFile)[1][1:].upper()
render.alpha_mode = 'TRANSPARENT'
render.film_transparent = True
render.resolution_x = 200
render.resolution_y = 200
render.use_stamp_date = False
......@@ -87,13 +97,15 @@ def prepare_scene(blendFile):
def add_camera():
bpy.ops.object.camera_add(rotation=(pi / 2, 0, -pi / 6))
cam = bpy.context.active_object
cam.data.shift_y = -.3
cam.data.lens = 71
bpy.data.scenes[0].camera = cam
cam = bpy.data.cameras.new('SAM_cam')
cam_ob = bpy.data.objects.new('SAM_cam_ob', cam)
bpy.context.collection.objects.link(cam_ob)
cam_ob.rotation_euler = (pi / 2, 0, -pi / 6)
cam.shift_y = -.3
cam.lens = 71
bpy.data.scenes[0].camera = cam_ob
bpy.ops.view3d.camera_to_view_selected()
return cam
return cam_ob
def find_layer(coll, lay_coll=None):
......@@ -351,7 +363,7 @@ class SAM_render_previews(bpy.types.Operator):
'import bpy; bpy.ops.asset_manager.render_previews('
f'sub_process=True, rerender="{str(rerender)}", '
f'render_env="{str(pref.render_env)}");'
'bpy.context.preferences.view.use_quit_dialog=False;'
'bpy.context.preferences.view.use_save_prompt=False;'
'bpy.ops.wm.quit_blender();']
subprocess.Popen(command)
bpy.context.scene['asset_manager']['cat'] = 0
......@@ -551,18 +563,45 @@ def update_category(self, context):
enum_previews_from_directory_items(self, context)
def search_library(self, context):
pref = context.preferences.addons[__name__].preferences
lib_path = bpy.path.abspath(pref.lib_path)
empty_path = os.path.join(os.path.dirname(__file__), 'empty.png')
pcoll = preview_collections["main"]
keyword = context.scene.asset_manager.search.lower()
items = []
enum_items = []
for r,dirs,files in os.walk(lib_path):
if keyword in ''.join(files).lower():
for file in files:
if keyword in file.lower():
prev = scan_for_elements(os.path.join(r,file))
if prev:
items.append(prev)
enum_items = gen_thumbnails(items, enum_items, pcoll, empty_path)
if len(enum_items) == 0:
if 'empty' in pcoll:
enum_items.append(('empty', '', "", pcoll['empty'].icon_id, 0))
else:
empty = pcoll.load('empty', empty_path, 'IMAGE')
enum_items.append(('empty', '', '', empty.icon_id, 0))
pcoll.asset_manager_prevs = enum_items
bpy.data.window_managers[0]['asset_manager_prevs'] = 0
def subcategory_callout(self, context):
global items
global subcategories
pref = context.preferences.addons[__name__].preferences
lib_path = bpy.path.abspath(pref.lib_path)
path = os.path.join(lib_path, self.cat)
if self.cat in ('.', 'empty'):
return [('empty', '', '', 0)]
for r, d, f in os.walk(path):
items = sorted([(x, x, '', nr + 1) for nr, x in enumerate(d)])
items.insert(0, ('.', '.', '', 0))
if len(items) > 1:
return items
subcategories = sorted([(x, x, '', nr + 1) for nr, x in enumerate(d)])
subcategories.insert(0, ('.', '.', '', 0))
if len(subcategories) > 1:
return subcategories
else:
bpy.context.scene['asset_manager']['subcat'] = 0
return [('empty', '', '', 0), ]
......@@ -606,32 +645,35 @@ class SimpleAssetManager(bpy.types.PropertyGroup):
description='Placement location')
incl_cursor_rot: BoolProperty(
name='Include cursor rotation',
name='Rotation',
description='fIncludes cursor rotation on import.')
search: StringProperty(
name='Search',
description='Search through whole library',
update=search_library)
def scan_for_elements(path):
if path.lower().endswith(FORMATS):
png = os.path.splitext(path)[0] + '.png'
if path.lower().endswith(('.hdr', '.exr')):
return (path, True)
elif os.path.exists(png):
return (path, True)
else:
return (path, False)
else:
return None
def scan_for_elements(directory):
image_paths = []
for fn in os.listdir(directory):
if fn.lower().endswith(FORMATS):
png = fn.rsplit('.', 1)[0] + '.png'
if fn.lower().endswith(('.hdr', '.exr')):
image_paths.append((fn, True))
elif png in os.listdir(directory):
image_paths.append((fn, True))
else:
image_paths.append((fn, False))
return image_paths
def gen_thumbnails(image_paths, enum_items, pcoll, empty_path, directory):
def gen_thumbnails(image_paths, enum_items, pcoll, empty_path):
# For each image in the directory, load the thumb
# unless it has already been loaded
for i, im in enumerate(image_paths):
name, prev = im
filepath = os.path.join(directory, name)
name = name.rsplit('.', 1)[0].replace('.', ' ').replace('_', ' ')
name = name.lower().capitalize()
filepath, prev = im
name = os.path.splitext(os.path.basename(filepath))[0]
name = name.replace('.', ' ').replace('_', ' ').lower().capitalize()
if filepath in pcoll:
enum_items.append((filepath, name,
"", pcoll[filepath].icon_id, i))
......@@ -655,6 +697,8 @@ def enum_previews_from_directory_items(self, context):
category = context.scene.asset_manager.cat
subcategory = context.scene.asset_manager.subcat
lib_path = bpy.path.abspath(pref.lib_path)
empty_path = os.path.join(os.path.dirname(__file__), 'empty.png')
enum_items = []
if category in ('empty', '.'):
directory = lib_path
elif subcategory in ('empty', '.'):
......@@ -662,18 +706,21 @@ def enum_previews_from_directory_items(self, context):
else:
directory = os.path.join(lib_path, category, subcategory)
# EnumProperty Callback
enum_items = []
if context is None:
return enum_items
# wm = context.window_manager
if directory == pcoll.asset_manager_prev_dir:
return pcoll.asset_manager_prevs
print("Simple Asset Manager - Scanning directory: %s" % directory)
empty_path = os.path.join(os.path.dirname(__file__), 'empty.png')
if directory and os.path.exists(directory):
image_paths = scan_for_elements(directory)
image_paths = []
for fn in os.listdir(directory):
prev = scan_for_elements(os.path.join(directory,fn))
if prev:
image_paths.append(prev)
enum_items = gen_thumbnails(image_paths, enum_items, pcoll,
empty_path, directory)
empty_path)
# Return validation
if len(enum_items) == 0:
if 'empty' in pcoll:
......@@ -687,128 +734,7 @@ def enum_previews_from_directory_items(self, context):
bpy.data.window_managers[0]['asset_manager_prevs'] = 0
return pcoll.asset_manager_prevs
def SAM_UI(self, context):
layout = self.layout
wm = context.window_manager
manager = context.scene.asset_manager
# Categories Drop Down Menu
col = layout.column()
if manager.cat not in ('empty', ''):
col.prop(manager, "cat")
if manager.subcat not in ('empty', ''):
col.prop(manager, "subcat")
# Previews
row = layout.row()
if wm.asset_manager_prevs not in ('', 'empty'):
row = layout.row()
if wm.asset_manager_prevs != 'empty':
row.template_icon_view(wm, "asset_manager_prevs",
show_labels=True)
# Materials
row = layout.row()
material = 'material' in manager.cat.lower() or \
'material' in manager.subcat.lower()
particle = 'particle' in manager.cat.lower() or \
'particle' in manager.subcat.lower()
if material:
row.operator("asset_manager.append_material")
row = layout.row()
row.operator("asset_manager.add_material")
row = layout.row()
row.operator("asset_manager.replace_material")
elif particle:
row.operator("asset_manager.append_object")
row = layout.row()
row.operator("asset_manager.add_particles")
else:
# Objects, HDR, Particles
origin_btn_name = 'At Origin'
if manager.origin:
origin_btn_name = 'At Cursor'
row.prop(manager, "origin", text=origin_btn_name, toggle=True)
if manager.origin:
row.prop(manager, "incl_cursor_rot")
row = layout.row()
row.operator("asset_manager.append_object")
if wm.asset_manager_prevs.endswith('.blend'):
row = layout.row()
row.operator("asset_manager.open_file")
row.operator("asset_manager.link_object")
# Panel
class SAM_Panel(bpy.types.Panel):
# Create a Panel in the Tool Shelf
bl_label = "Simple Asset Manager"
bl_idname = "IMPORT_PT_Asset_Manager"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "Tool"
bl_options = {"DEFAULT_CLOSED"}
# Draw
def draw(self, context):
SAM_UI(self, context)
class SAM_Popup(bpy.types.Operator):
"""Acces to your Objects Library"""
bl_idname = "view3d.add_asset"
bl_label = "Simple Asset Manager"
bl_options = {'REGISTER', 'UNDO'}
def invoke(self, context, event):
return context.window_manager.invoke_props_dialog(self)
def draw(self, context):
SAM_UI(self, context)
def execute(self, context):
return {'FINISHED'}
class SAM_PrefPanel(bpy.types.AddonPreferences):
bl_idname = __name__
dbg_lib = '/home/tibicen/Dokumenty/blendLibrary/'
lib_path: StringProperty(
name="Library Path",
default=dbg_lib if DEBUG else os.path.splitdrive(__file__)[0],
description="Show only hotkeys that have this text in their name",
subtype="DIR_PATH")
rerender: BoolProperty(default=False)
opensame: BoolProperty()
incl_cursor_rot: BoolProperty(
name='Rotation',
description='Include rotation when appending to cursor.')
exrs = [(exr, exr.replace('.exr', '').title(),
'', nr) for nr, exr in enumerate(EXRS)]
render_env: EnumProperty(
items=exrs,
name="Render Scene",
description="With what light the previews.",
default='interior.exr'
)
def draw(self, context):
layout = self.layout
col = layout.column()
col.prop(self, "lib_path", text='Library path')
row = layout.row()
row.operator("asset_manager.render_previews",
text="Render missing previews")
row.prop(self, 'rerender',
text='Re-render ALL previews')
row = layout.row()
row.prop(self, 'opensame',
text='Open file on the same instance')
row = layout.row()
row.prop(self, 'render_env', text='Previews render light')
from .ui import SAM_UI, SAM_Panel, SAM_Popup, SAM_PrefPanel, SAM_button
preview_collections = {}
......@@ -832,11 +758,6 @@ classes = (
)
def SAM_button(self, context):
self.layout.operator(SAM_Popup.bl_idname,
text="Simple Asset Manager")
def register():
for cls in classes:
bpy.utils.register_class(cls)
......
import bpy
from bpy.props import BoolProperty, PointerProperty, \
StringProperty, EnumProperty
from . import DEBUG, EXRS, FORMATS, __name__
def SAM_UI(self, context):
layout = self.layout
wm = context.window_manager
manager = context.scene.asset_manager
# Categories Drop Down Menu
col = layout.column()
if manager.cat not in ('empty', ''):
col.prop(manager, "cat")
if manager.subcat not in ('empty', ''):
col.prop(manager, "subcat")
# search bar
row = layout.row()
col.prop(manager, 'search')
# Previews
# row = layout.row()
if wm.asset_manager_prevs not in ('', 'empty'):
row = layout.row()
if wm.asset_manager_prevs != 'empty':
row.template_icon_view(wm, "asset_manager_prevs",
show_labels=True)
# Materials
row = layout.row()
material = 'material' in manager.cat.lower() or \
'material' in manager.subcat.lower()
particle = 'particle' in manager.cat.lower() or \
'particle' in manager.subcat.lower()
hdr = wm.asset_manager_prevs.endswith(('.hdr', '.hdri', '.exr'))
if material:
row.operator("asset_manager.append_material")
row = layout.row()
row.operator("asset_manager.add_material")
row = layout.row()
row.operator("asset_manager.replace_material")
elif particle:
row.operator("asset_manager.append_object")
row = layout.row()
row.operator("asset_manager.add_particles")
elif hdr:
row = layout.row()
row.operator("asset_manager.append_object")
else:
# Objects, HDR, Particles
origin_btn_name = 'At Origin'
if manager.origin:
origin_btn_name = 'At Cursor'
row.prop(manager, "origin", text=origin_btn_name, toggle=True)
if manager.origin:
row.prop(manager, "incl_cursor_rot")
row = layout.row()
row.operator("asset_manager.append_object")
if wm.asset_manager_prevs.endswith('.blend'):
row = layout.row()
row.operator("asset_manager.open_file")
row.operator("asset_manager.link_object")
# Panel
class SAM_Panel(bpy.types.Panel):
# Create a Panel in the Tool Shelf
bl_label = "Simple Asset Manager"
bl_idname = "IMPORT_PT_Asset_Manager"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "Tool"
bl_options = {"DEFAULT_CLOSED"}
# Draw
def draw(self, context):
SAM_UI(self, context)
class SAM_Popup(bpy.types.Operator):
"""Acces to your Objects Library"""
bl_idname = "view3d.add_asset"
bl_label = "Simple Asset Manager"
bl_options = {'REGISTER', 'UNDO'}
def invoke(self, context, event):
return context.window_manager.invoke_props_dialog(self)
def draw(self, context):
SAM_UI(self, context)
def execute(self, context):
return {'FINISHED'}
class SAM_PrefPanel(bpy.types.AddonPreferences):
bl_idname = __name__
dbg_lib = '/home/tibicen/Dokumenty/blendLibrary/'
lib_path: StringProperty(
name="Library Path",
default=dbg_lib if DEBUG else os.path.splitdrive(__file__)[0],
description="Show only hotkeys that have this text in their name",
subtype="DIR_PATH")
rerender: BoolProperty(default=False)
opensame: BoolProperty()
incl_cursor_rot: BoolProperty(
name='Rotation',
description='Include rotation when appending to cursor.')
exrs = [(exr, exr.replace('.exr', '').title(),
'', nr) for nr, exr in enumerate(EXRS)]
render_env: EnumProperty(
items=exrs,
name="Render Scene",
description="With what light the previews.",
default='interior.exr'
)
def draw(self, context):
layout = self.layout
col = layout.column()
col.prop(self, "lib_path", text='Library path')
row = layout.row()
row.operator("asset_manager.render_previews",
text="Render missing previews")
row.prop(self, 'rerender',
text='Re-render ALL previews')
row = layout.row()
row.prop(self, 'opensame',
text='Open file on the same instance')
row = layout.row()
row.prop(self, 'render_env', text='Previews render light')
def SAM_button(self, context):
self.layout.operator(SAM_Popup.bl_idname,
text="Simple Asset Manager")
preview.gif

180 KB | W: | H:

preview.gif

896 KB | W: | H:

preview.gif
preview.gif
preview.gif
preview.gif
  • 2-up
  • Swipe
  • Onion skin
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment