asset_library/operators.py

834 lines
26 KiB
Python
Raw Normal View History

2022-12-24 15:30:32 +01:00
from typing import Set
#import shutil
from pathlib import Path
import subprocess
import importlib
import time
import json
import bpy
from bpy_extras import asset_utils
from bpy.types import Context, Operator
from bpy.props import (
BoolProperty,
EnumProperty,
StringProperty,
IntProperty)
#from asset_library.constants import (DATA_TYPES, DATA_TYPE_ITEMS, MODULE_DIR)
import asset_library
from asset_library.common.bl_utils import (
2023-01-17 18:05:22 +01:00
attr_set,
2022-12-24 15:30:32 +01:00
get_addon_prefs,
get_bl_cmd,
2023-01-17 18:05:22 +01:00
get_view3d_persp,
2022-12-24 15:30:32 +01:00
#suitable_areas,
refresh_asset_browsers,
load_datablocks)
from asset_library.common.file_utils import open_blender_file, synchronize
from asset_library.common.functions import get_active_library, asset_warning_callback
from textwrap import dedent
from tempfile import gettempdir
2023-01-17 18:05:22 +01:00
import gpu
from gpu_extras.batch import batch_for_shader
import blf
import bgl
2022-12-24 15:30:32 +01:00
2023-01-17 18:05:22 +01:00
class ASSETLIB_OT_remove_assets(Operator):
bl_idname = "assetlib.remove_assets"
2022-12-24 15:30:32 +01:00
bl_options = {"REGISTER", "UNDO", "INTERNAL"}
2023-01-17 18:05:22 +01:00
bl_label = 'Remove Assets'
bl_description = 'Remove Selected Assets'
2022-12-24 15:30:32 +01:00
@classmethod
def poll(cls, context):
if not asset_utils.SpaceAssetInfo.is_asset_browser(context.space_data):
return False
sp = context.space_data
if sp.params.asset_library_ref == 'LOCAL':
return False
return True
def execute(self, context: Context) -> Set[str]:
asset = context.active_file
lib = get_active_library()
2023-01-17 18:05:22 +01:00
lib_type = lib.library_type
2022-12-24 15:30:32 +01:00
2023-01-17 18:05:22 +01:00
asset_handle = context.asset_file_handle
2022-12-24 15:30:32 +01:00
2023-01-17 18:05:22 +01:00
catalog_file = lib.library_type.read_catalog()
catalog_ids = {v['id']: {'path': k, 'name': v['name']} for k,v in catalog_file.items()}
catalog = catalog_ids[asset_handle.asset_data.catalog_id]['path']
asset_path = lib_type.format_path(asset.asset_data['filepath'])
img_path = lib_type.get_image_path(name=asset_handle.name, catalog=catalog, filepath=asset_path)
video_path = lib_type.get_video_path(name=asset_handle.name, catalog=catalog, filepath=asset_path)
if asset_path and asset_path.exists():
asset_path.unlink()
if img_path and img_path.exists():
img_path.unlink()
if video_path and video_path.exists():
video_path.unlink()
2022-12-24 15:30:32 +01:00
#open_blender_file(filepath)
2023-01-17 18:05:22 +01:00
try:
asset_path.parent.rmdir()
except Exception:#Directory not empty
pass
2022-12-24 15:30:32 +01:00
bpy.ops.assetlib.bundle(name=lib.name, blocking=True)
return {'FINISHED'}
class ASSETLIB_OT_edit_data(Operator):
bl_idname = "assetlib.edit_data"
bl_label = "Edit Asset Data"
bl_description = "Edit Current Asset Data"
bl_options = {"REGISTER", "UNDO"}
warning: StringProperty(name='')
path: StringProperty(name='Path')
catalog: StringProperty(name='Catalog', update=asset_warning_callback, options={'TEXTEDIT_UPDATE'})
name: StringProperty(name='Name', update=asset_warning_callback, options={'TEXTEDIT_UPDATE'})
tags: StringProperty(name='Tags', description='Tags need to separate with a comma (,)')
2023-01-03 13:53:01 +01:00
description: StringProperty(name='Description')
2022-12-24 15:30:32 +01:00
@classmethod
def poll(cls, context):
if not asset_utils.SpaceAssetInfo.is_asset_browser(context.space_data):
return False
return True
def execute(self, context: Context) -> Set[str]:
prefs = get_addon_prefs()
lib = get_active_library()
if lib.merge_libraries:
lib = prefs.libraries[lib.store_library]
2023-01-17 18:05:22 +01:00
new_name = lib.library_type.norm_file_name(self.name)
new_asset_path = lib.library_type.get_asset_path(name=new_name, catalog=self.catalog)
2022-12-24 15:30:32 +01:00
2023-01-17 18:05:22 +01:00
#asset_data = lib.library_type.get_asset_data(self.asset)
2023-01-03 13:53:01 +01:00
asset_data = dict(
tags=[t.strip() for t in self.tags.split(',') if t],
description=self.description,
)
2023-01-17 18:05:22 +01:00
#lib.library_type.set_asset_catalog(asset, asset_data, catalog_data)
2023-01-03 13:53:01 +01:00
self.asset.name = self.name
2023-01-17 18:05:22 +01:00
lib.library_type.set_asset_tags(self.asset, asset_data)
lib.library_type.set_asset_info(self.asset, asset_data)
2023-01-03 13:53:01 +01:00
2022-12-24 15:30:32 +01:00
self.old_asset_path.unlink()
2023-01-17 18:05:22 +01:00
lib.library_type.write_asset(asset=self.asset, asset_path=new_asset_path)
2022-12-24 15:30:32 +01:00
if self.old_image_path.exists():
2023-01-17 18:05:22 +01:00
new_img_path = lib.library_type.get_image_path(new_name, self.catalog, new_asset_path)
2022-12-24 15:30:32 +01:00
self.old_image_path.rename(new_img_path)
if self.old_video_path.exists():
2023-01-17 18:05:22 +01:00
new_video_path = lib.library_type.get_video_path(new_name, self.catalog, new_asset_path)
2022-12-24 15:30:32 +01:00
self.old_video_path.rename(new_video_path)
2023-01-03 13:53:01 +01:00
#if self.old_description_path.exists():
# self.old_description_path.unlink()
2022-12-24 15:30:32 +01:00
2023-01-03 13:53:01 +01:00
try:
2022-12-24 15:30:32 +01:00
self.old_asset_path.parent.rmdir()
2023-01-03 13:53:01 +01:00
except Exception: #The folder is not empty
pass
2022-12-24 15:30:32 +01:00
diff_path = Path(bpy.app.tempdir, 'diff.json')
2023-01-03 13:53:01 +01:00
diff = [dict(name=self.old_asset_name, catalog=self.old_catalog, filepath=str(self.old_asset_path), operation='REMOVE')]
2023-01-17 18:05:22 +01:00
asset_data = lib.library_type.get_asset_data(self.asset)
2023-01-03 13:53:01 +01:00
diff += [dict(asset_data,
image=str(new_img_path),
filepath=str(new_asset_path),
type=lib.data_type,
library_id=lib.id,
catalog=self.catalog,
operation='ADD'
)]
2022-12-24 15:30:32 +01:00
2023-01-03 13:53:01 +01:00
print(diff)
2022-12-24 15:30:32 +01:00
diff_path.write_text(json.dumps(diff, indent=4), encoding='utf-8')
bpy.ops.assetlib.bundle(name=lib.name, diff=str(diff_path), blocking=True)
return {"FINISHED"}
def draw(self, context):
layout = self.layout
layout.separator()
layout.use_property_split = True
lib = get_active_library()
if lib.merge_libraries:
layout.prop(lib, 'store_library', expand=False)
layout.prop(self, "catalog", text="Catalog")
layout.prop(self, "name", text="Name")
layout.prop(self, 'tags')
2023-01-03 13:53:01 +01:00
layout.prop(self, 'description')
2022-12-24 15:30:32 +01:00
#layout.prop()
layout.separator()
col = layout.column()
col.use_property_split = False
#row.enabled = False
if self.path:
col.label(text=self.path)
if self.warning:
col.label(icon='ERROR', text=self.warning)
def invoke(self, context, event):
lib = get_active_library()
2023-01-17 18:05:22 +01:00
active_lib = lib.library_type.get_active_asset_library()
2022-12-24 15:30:32 +01:00
lib.store_library = active_lib.name
asset_handle = context.asset_file_handle
2023-01-17 18:05:22 +01:00
catalog_file = lib.library_type.read_catalog()
2022-12-24 15:30:32 +01:00
catalog_ids = {v['id']: {'path': k, 'name': v['name']} for k,v in catalog_file.items()}
#asset_handle = context.asset_file_handle
self.old_asset_name = asset_handle.name
2023-01-17 18:05:22 +01:00
self.old_asset_path = lib.library_type.get_active_asset_path()
2022-12-24 15:30:32 +01:00
self.asset = load_datablocks(self.old_asset_path, self.old_asset_name, type=lib.data_types)
if not self.asset:
self.report({'ERROR'}, 'No asset found')
self.name = self.old_asset_name
2023-01-03 13:53:01 +01:00
self.description = asset_handle.asset_data.description
tags = [t.strip() for t in self.asset.asset_data.tags.keys() if t]
self.tags = ', '.join(tags)
2022-12-24 15:30:32 +01:00
#asset_path
2023-01-03 13:53:01 +01:00
self.old_catalog = catalog_ids[asset_handle.asset_data.catalog_id]['path']
self.catalog = self.old_catalog
2023-01-17 18:05:22 +01:00
self.old_image_path = lib.library_type.get_image_path(name=self.name, catalog=self.catalog, filepath=self.old_asset_path)
self.old_video_path = lib.library_type.get_video_path(name=self.name, catalog=self.catalog, filepath=self.old_asset_path)
2023-01-03 13:53:01 +01:00
2023-01-17 18:05:22 +01:00
#self.old_description_path = lib.library_type.get_description_path(self.old_asset_path)
2023-01-03 13:53:01 +01:00
2023-01-17 18:05:22 +01:00
#self.old_asset_info = lib.library_type.read_asset_info_file(self.old_asset_path)
#self.old_asset_info = lib.library_type.norm_asset_datas([self.old_asset_info])[0]
2023-01-03 13:53:01 +01:00
2022-12-24 15:30:32 +01:00
2023-01-03 13:53:01 +01:00
return context.window_manager.invoke_props_dialog(self, width=450)
2022-12-24 15:30:32 +01:00
def cancel(self, context):
print('Cancel Edit Data, removing the asset')
lib = get_active_library()
2023-01-17 18:05:22 +01:00
active_lib = lib.library_type.get_active_asset_library()
2022-12-24 15:30:32 +01:00
getattr(bpy.data, active_lib.data_types).remove(self.asset)
class ASSETLIB_OT_remove_user_library(Operator):
bl_idname = "assetlib.remove_user_library"
bl_options = {"REGISTER", "UNDO"}
bl_label = 'Remove User Library'
bl_description = 'Remove User Library'
index : IntProperty(default=-1)
def execute(self, context: Context) -> Set[str]:
prefs = get_addon_prefs()
prefs.user_libraries.remove(self.index)
return {'FINISHED'}
class ASSETLIB_OT_add_user_library(Operator):
bl_idname = "assetlib.add_user_library"
bl_options = {"REGISTER", "UNDO"}
bl_label = 'Add User Library'
bl_description = 'Add User Library'
def execute(self, context: Context) -> Set[str]:
prefs = get_addon_prefs()
lib = prefs.user_libraries.add()
lib.expand = True
return {'FINISHED'}
class ASSETLIB_OT_open_blend(Operator):
bl_idname = "assetlib.open_blend"
bl_options = {"REGISTER", "UNDO"}
bl_label = 'Open Blender File'
bl_description = 'Open blender file'
#filepath : StringProperty(subtype='FILE_PATH')
def execute(self, context: Context) -> Set[str]:
#asset = context.active_file
#prefs = get_addon_prefs()
lib = get_active_library()
2023-01-17 18:05:22 +01:00
#filepath = lib.library_type.format_path(asset.asset_data['filepath'])
2022-12-24 15:30:32 +01:00
2023-01-17 18:05:22 +01:00
filepath = lib.library_type.get_active_asset_path()
2022-12-24 15:30:32 +01:00
open_blender_file(filepath)
return {'FINISHED'}
class ASSETLIB_OT_set_paths(Operator):
bl_idname = "assetlib.set_paths"
bl_options = {"REGISTER", "UNDO", "INTERNAL"}
bl_label = 'Set Paths'
bl_description = 'Set Library Paths'
name: StringProperty()
all: BoolProperty(default=False)
def execute(self, context: Context) -> Set[str]:
prefs = get_addon_prefs()
print('Set Paths')
if self.all:
libs = prefs.libraries
else:
libs = [prefs.libraries[self.name]]
for lib in libs:
lib.clear_library_path()
lib.set_library_path()
return {'FINISHED'}
class ASSETLIB_OT_bundle_library(Operator):
bl_idname = "assetlib.bundle"
bl_options = {"INTERNAL"}
bl_label = 'Bundle Library'
bl_description = 'Bundle all matching asset found inside one blend'
name : StringProperty()
diff : StringProperty()
blocking : BoolProperty(default=False)
mode : EnumProperty(items=[(i.replace(' ', '_').upper(), i, '') for i in ('None', 'All', 'Auto Bundle')], default='NONE')
directory : StringProperty(subtype='DIR_PATH')
#conform : BoolProperty(default=False)
2022-12-24 15:30:32 +01:00
#def refresh(self):
# for area in suitable_areas(bpy.context.screen):
# bpy.ops.asset.library_refresh({"area": area, 'region': area.regions[3]})
#space_data.activate_asset_by_id(asset, deferred=deferred)
def execute(self, context: Context) -> Set[str]:
prefs = get_addon_prefs()
libs = []
if self.name:
libs += [prefs.libraries[self.name]]
if self.mode == 'ALL':
libs += prefs.libraries.values()
elif self.mode == 'AUTO_BUNDLE':
2022-12-25 02:54:50 +01:00
libs += [l for l in prefs.libraries if l.auto_bundle]
if not libs:
return {"CANCELLED"}
2022-12-24 15:30:32 +01:00
lib_datas = [l.to_dict() for l in libs]
print(f'Bundle Libraries: {[l.name for l in libs]}')
script_code = dedent(f"""
import bpy
prefs = bpy.context.preferences.addons["asset_library"].preferences
for lib_data in {lib_datas}:
lib = prefs.env_libraries.add()
lib.set_dict(lib_data)
2023-01-17 18:05:22 +01:00
lib.library_type.bundle(cache_diff='{self.diff}')
2022-12-25 02:54:50 +01:00
bpy.ops.wm.quit_blender()
2022-12-24 15:30:32 +01:00
""")
2022-12-25 02:54:50 +01:00
script_path = Path(bpy.app.tempdir) / 'bundle_library.py'
2022-12-24 15:30:32 +01:00
script_path.write_text(script_code)
2022-12-25 02:54:50 +01:00
print(script_code)
2022-12-24 15:30:32 +01:00
#raise Exception()
cmd = get_bl_cmd(script=str(script_path), background=True)
#print(cmd)
if self.blocking:
subprocess.call(cmd)
bpy.app.timers.register(refresh_asset_browsers, first_interval=0.2)
else:
subprocess.Popen(cmd)
return {'FINISHED'}
class ASSETLIB_OT_reload_addon(Operator):
bl_idname = "assetlib.reload_addon"
bl_options = {"UNDO"}
bl_label = 'Reload Asset Library Addon'
bl_description = 'Reload The Asset Library Addon and the addapters'
def execute(self, context: Context) -> Set[str]:
print('Execute reload')
asset_library.unregister()
importlib.reload(asset_library)
asset_library.register()
return {'FINISHED'}
class ASSETLIB_OT_diff(Operator):
bl_idname = "assetlib.diff"
bl_options = {"REGISTER", "UNDO"}
bl_label = 'Synchronize'
bl_description = 'Synchronize Action Lib to Local Directory'
name : StringProperty()
conform : BoolProperty(default=False)
def execute(self, context: Context) -> Set[str]:
prefs = get_addon_prefs()
lib = prefs.libraries.get(self.name)
2023-01-17 18:05:22 +01:00
lib.library_type.diff()
2022-12-24 15:30:32 +01:00
return {'FINISHED'}
'''
2022-12-24 15:30:32 +01:00
class ASSETLIB_OT_conform_library(Operator):
bl_idname = "assetlib.conform_library"
bl_options = {"REGISTER", "UNDO"}
bl_label = "Conform Library"
bl_description = "Split each assets per blend and externalize preview"
name : StringProperty()
2022-12-27 23:49:57 +01:00
template_image : StringProperty()
template_video : StringProperty()
2022-12-24 15:30:32 +01:00
directory : StringProperty(subtype='DIR_PATH', name='Filepath')
def execute(self, context: Context) -> Set[str]:
prefs = get_addon_prefs()
lib = prefs.libraries.get(self.name)
2023-01-17 18:05:22 +01:00
#lib.library_type.conform(self.directory)
2022-12-24 15:30:32 +01:00
templates = {}
2022-12-27 23:49:57 +01:00
if self.template_image:
templates['image'] = self.template_image
if self.template_video:
templates['video'] = self.template_video
2022-12-24 15:30:32 +01:00
2022-12-27 23:49:57 +01:00
script_path = Path(bpy.app.tempdir) / 'bundle_library.py'
2022-12-24 15:30:32 +01:00
script_code = dedent(f"""
import bpy
prefs = bpy.context.preferences.addons["asset_library"].preferences
lib = prefs.env_libraries.add()
lib.set_dict({lib.to_dict()})
2023-01-17 18:05:22 +01:00
lib.library_type.conform(directory='{self.directory}', templates={templates})
2022-12-24 15:30:32 +01:00
""")
script_path.write_text(script_code)
cmd = get_bl_cmd(script=str(script_path), background=True)
subprocess.Popen(cmd)
return {'FINISHED'}
def invoke(self, context, event):
context.window_manager.fileselect_add(self)
return {'RUNNING_MODAL'}
'''
2022-12-24 15:30:32 +01:00
2023-01-17 18:05:22 +01:00
class ASSETLIB_OT_make_custom_preview(Operator):
bl_idname = "assetlib.make_custom_preview"
bl_label = "Custom Preview"
bl_description = "Set a camera to preview an asset"
image_size : IntProperty(default=512)
modal : BoolProperty(default=False)
def modal(self, context, event):
if event.type in {'ESC'}: # Cancel
self.restore()
return {'CANCELLED'}
elif event.type in {'RET', 'NUMPAD_ENTER'}: # Cancel
return self.execute(context)
#return {'FINISHED'}
return {'PASS_THROUGH'}
def execute(self, context):
prefs = get_addon_prefs()
bpy.ops.render.opengl(write_still=True)
img_path = context.scene.render.filepath
#print('Load Image to previews')
prefs.previews.load(Path(img_path).stem, img_path, 'IMAGE')
#img = bpy.data.images.load(context.scene.render.filepath)
#img.update()
#img.preview_ensure()
#Copy the image with a new name
# render = bpy.data.images['Render Result']
# render_pixels = [0] * self.image_size * self.image_size * 4
# render.pixels.foreach_get(render_pixels)
# img = bpy.data.images.new(name=img_name, width=self.image_size, height=self.image_size, is_data=True, alpha=True)
# img.pixels.foreach_set(render_pixels)
#img.scale(128, 128)
#img.preview_ensure()
# preview_size = render.size
# pixels = [0] * preview_size[0] * preview_size[1] * 4
# render.pixels.foreach_get(pixels)
# image.preview.image_size = preview_size
# image.preview.image_pixels_float.foreach_set(pixels)
self.restore()
#self.is_running = False
prefs.preview_modal = False
return {"FINISHED"}
def restore(self):
print('RESTORE')
try:
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
except:
print('Failed remove handler')
pass
bpy.data.objects.remove(self.camera)
self.attr_changed.restore()
def draw_callback_px(self, context):
if context.space_data != self._space_data:
return
dpi = context.preferences.system.dpi
bg_color = (0.8, 0.1, 0.1, 0.5)
font_color = (1, 1, 1, 1)
text = f'Escape: Cancel Enter: Make Preview'
font_id = 0
dim = blf.dimensions(font_id, text)
#gpu.state.line_width_set(100)
# bgl.glLineWidth(100)
# self.shader_2d.bind()
# self.shader_2d.uniform_float("color", bg_color)
# self.screen_framing.draw(self.shader_2d)
# # Reset
# gpu.state.line_width_set(1)
# -dim[0]/2, +dim[1]/2 + 5
# Display Text
blf.color(font_id, *font_color) # unpack color
blf.position(font_id, context.region.width/2 -dim[0]/2, dim[1]/2 + 5, 0)
blf.size(font_id, 12, dpi)
blf.draw(font_id, f'Escape: Cancel Enter: Make Preview')
def get_image_name(self):
prefs = get_addon_prefs()
preview_names = [p for p in prefs.previews.keys()]
preview_names.sort()
index = 0
if preview_names:
index = int(preview_names[-1][-2:]) + 1
return f'preview_{index:03d}'
def invoke(self, context, event):
prefs = get_addon_prefs()
cam_data = bpy.data.cameras.new(name='Preview Camera')
self.camera = bpy.data.objects.new(name='Preview Camera', object_data=cam_data)
#view_3d = get_view3d_persp()
scn = context.scene
space = context.space_data
matrix = space.region_3d.view_matrix.inverted()
if space.region_3d.view_perspective == 'CAMERA':
matrix = scn.camera.matrix_world
self.camera.matrix_world = matrix
img_name = self.get_image_name()
img_path = Path(bpy.app.tempdir, img_name).with_suffix('.webp')
self.attr_changed = attr_set([
(space.overlay, 'show_overlays', False),
(space.region_3d, 'view_perspective', 'CAMERA'),
(space.region_3d, 'view_camera_offset'),
(space.region_3d, 'view_camera_zoom'),
(space, 'lock_camera', True),
(space, 'show_region_ui', False),
(scn, 'camera', self.camera),
(scn.render, 'resolution_percentage', 100),
(scn.render, 'resolution_x', self.image_size),
(scn.render, 'resolution_y', self.image_size),
(scn.render, 'film_transparent', True),
(scn.render.image_settings, 'file_format', 'WEBP'),
(scn.render.image_settings, 'color_mode', 'RGBA'),
#(scn.render.image_settings, 'color_depth', '8'),
(scn.render, 'use_overwrite', True),
(scn.render, 'filepath', str(img_path)),
])
bpy.ops.view3d.view_center_camera()
space.region_3d.view_camera_zoom -= 6
space.region_3d.view_camera_offset[1] += 0.03
w, h = (context.region.width, context.region.height)
self._space_data = context.space_data
if self.modal:
prefs.preview_modal = True
self.shader_2d = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
self.screen_framing = batch_for_shader(
self.shader_2d, 'LINE_LOOP', {"pos": [(0,0), (0,h), (w,h), (w,0)]})
self._handle = bpy.types.SpaceView3D.draw_handler_add(self.draw_callback_px, (context,), 'WINDOW', 'POST_PIXEL')
context.window_manager.modal_handler_add(self)
return {'RUNNING_MODAL'}
else:
return self.execute(context)
2022-12-27 23:49:57 +01:00
class ASSETLIB_OT_generate_previews(Operator):
bl_idname = "assetlib.generate_previews"
bl_options = {"REGISTER", "UNDO"}
bl_label = "Generate Previews"
bl_description = "Generate and write the image for assets"
cache : StringProperty()
2022-12-27 23:49:57 +01:00
preview_blend : StringProperty()
name : StringProperty()
blocking : BoolProperty(default=True)
def execute(self, context: Context) -> Set[str]:
prefs = get_addon_prefs()
lib = prefs.libraries.get(self.name)
# self.write_file(self.diff_file, self.diff)
# preview_assets = [(a.asset_data['filepath'], self.data_types, a.name) for a in assets]
# self.preview_assets_file.write_text(json.dumps(preview_assets), encoding='utf-8')
# cmd = [
# bpy.app.binary_path, '-b', '--use-system-env',
# '--python', str(PREVIEW_ASSETS_SCRIPT), '--',
# '--preview-blend', str(self.preview_blend),
# '--preview-assets-file', str(self.preview_assets_file)
# ]
# subprocess.call(cmd)
2023-01-17 18:05:22 +01:00
preview_blend = self.preview_blend or lib.library_type.preview_blend
2022-12-27 23:49:57 +01:00
if not preview_blend or not Path(preview_blend).exists():
preview_blend = MODULE_DIR / 'common' / 'preview.blend'
2022-12-27 23:49:57 +01:00
script_path = Path(bpy.app.tempdir) / 'generate_previews.py'
script_code = dedent(f"""
import bpy
prefs = bpy.context.preferences.addons["asset_library"].preferences
lib = prefs.env_libraries.add()
lib.set_dict({lib.to_dict()})
bpy.ops.wm.open_mainfile(filepath='{preview_blend}', load_ui=True)
2023-01-17 18:05:22 +01:00
lib.library_type.generate_previews(cache='{self.cache}')
2022-12-27 23:49:57 +01:00
""")
script_path.write_text(script_code)
cmd = get_bl_cmd(script=str(script_path), background=True)
if self.blocking:
subprocess.call(cmd)
else:
subprocess.Popen(cmd)
return {'FINISHED'}
2022-12-24 15:30:32 +01:00
class ASSETLIB_OT_play_preview(Operator):
bl_idname = "assetlib.play_preview"
bl_options = {"REGISTER", "UNDO", "INTERNAL"}
bl_label = 'Play Preview'
bl_description = 'Play Preview'
@classmethod
def poll(cls, context: Context) -> bool:
if not context.active_file:
return False
if not asset_utils.SpaceAssetInfo.is_asset_browser(context.space_data):
cls.poll_message_set("Current editor is not an asset browser")
return False
lib = get_active_library()
if not lib:
return False
return True
def execute(self, context: Context) -> Set[str]:
asset = context.active_file
prefs = get_addon_prefs()
lib = get_active_library()
2023-01-17 18:05:22 +01:00
#filepath = lib.library_type.format_path(asset.asset_data['filepath'])
asset_path = lib.library_type.get_active_asset_path()
2022-12-24 15:30:32 +01:00
2023-01-17 18:05:22 +01:00
asset_image = lib.library_type.get_image(asset.name, asset_path)
asset_video = lib.library_type.get_video(asset.name, asset_path)
2022-12-24 15:30:32 +01:00
if not asset_image and not asset_video:
self.report({'ERROR'}, f'Preview for {asset.name} not found.')
return {"CANCELLED"}
if asset_video:
self.report({'INFO'}, f'Video found. {asset_video}.')
if prefs.video_player:
subprocess.Popen([prefs.video_player, asset_video])
else:
bpy.ops.wm.path_open(filepath=str(asset_video))
else:
self.report({'INFO'}, f'Image found. {asset_image}.')
if prefs.image_player:
subprocess.Popen([prefs.image_player, asset_image])
else:
bpy.ops.wm.path_open(filepath=str(asset_image))
return {"FINISHED"}
class ASSETLIB_OT_synchronize(Operator):
bl_idname = "assetlib.synchronize"
bl_options = {"REGISTER", "UNDO"}
bl_label = 'Synchronize'
bl_description = 'Synchronize Action Lib to Local Directory'
clean : BoolProperty(default=False)
only_new : BoolProperty(default=False)
only_recent : BoolProperty(default=False)
name: StringProperty()
all: BoolProperty(default=False)
def execute(self, context: Context) -> Set[str]:
print('Not yet Implemented, have to be replace by Bundle instead')
return {'FINISHED'}
prefs = get_addon_prefs()
print('Synchronize')
if self.all:
libs = prefs.libraries
else:
libs = [prefs.libraries.get(self.name)]
for lib in libs:
if self.clean and Path(lib.path_local).exists():
pass
print('To check first')
#shutil.rmtree(path_local)
if not lib.path_local:
continue
synchronize(
src=lib.path,
dst=lib.path_local,
only_new=self.only_new,
only_recent=self.only_recent
)
return {'FINISHED'}
classes = (
ASSETLIB_OT_play_preview,
ASSETLIB_OT_open_blend,
ASSETLIB_OT_set_paths,
ASSETLIB_OT_synchronize,
ASSETLIB_OT_add_user_library,
ASSETLIB_OT_remove_user_library,
ASSETLIB_OT_diff,
2022-12-27 23:49:57 +01:00
ASSETLIB_OT_generate_previews,
2022-12-24 15:30:32 +01:00
ASSETLIB_OT_bundle_library,
2023-01-17 18:05:22 +01:00
ASSETLIB_OT_remove_assets,
2022-12-24 15:30:32 +01:00
ASSETLIB_OT_edit_data,
#ASSETLIB_OT_conform_library,
2023-01-17 18:05:22 +01:00
ASSETLIB_OT_reload_addon,
ASSETLIB_OT_make_custom_preview
2022-12-24 15:30:32 +01:00
)
def register():
#bpy.types.UserAssetLibrary.is_env = False
for cls in classes:
bpy.utils.register_class(cls)
def unregister():
for cls in reversed(classes):
bpy.utils.unregister_class(cls)