Make all features working
This commit is contained in:
+1
-1
@@ -14,7 +14,7 @@ def draw_context_menu(layout):
|
||||
layout.operator_context = 'INVOKE_DEFAULT'
|
||||
|
||||
#layout.operator("assetlib.rename_asset", text="Rename Action")
|
||||
layout.operator("assetlib.clear_asset", text="Remove Asset")
|
||||
layout.operator("assetlib.remove_assets", text="Remove Assets")
|
||||
layout.operator("assetlib.edit_data", text="Edit Asset data")
|
||||
|
||||
#layout.operator("actionlib.clear_asset", text="Clear Asset (Fake User)").use_fake_user = True
|
||||
|
||||
+138
-60
@@ -21,6 +21,7 @@ import uuid
|
||||
import time
|
||||
from pathlib import Path
|
||||
from functools import partial
|
||||
from pprint import pprint
|
||||
|
||||
|
||||
from asset_library.pose.pose_creation import(
|
||||
@@ -90,7 +91,8 @@ from asset_library.common.bl_utils import (
|
||||
split_path,
|
||||
get_preview,
|
||||
get_view3d_persp,
|
||||
load_assets_from,
|
||||
get_viewport,
|
||||
#load_assets_from,
|
||||
get_asset_space_params,
|
||||
get_bl_cmd,
|
||||
get_overriden_col
|
||||
@@ -275,7 +277,7 @@ class ACTIONLIB_OT_apply_anim(Operator):
|
||||
lib = get_active_library()
|
||||
if 'filepath' in asset_file_handle.asset_data:
|
||||
action_path = asset_file_handle.asset_data['filepath']
|
||||
action_path = lib.adapter.format_path(action_path)
|
||||
action_path = lib.library_type.format_path(action_path)
|
||||
else:
|
||||
action_path = bpy.types.AssetHandle.get_full_library_path(
|
||||
asset_file_handle, asset_library_ref
|
||||
@@ -778,14 +780,68 @@ class ACTIONLIB_OT_open_blendfile(Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
|
||||
|
||||
#LIBRARY_ITEMS = []
|
||||
'''
|
||||
def callback_operator(modal_func, operator, override={}):
|
||||
|
||||
def wrap(self, context, event):
|
||||
ret, = retset = modal_func(self, context, event)
|
||||
if ret in {'FINISHED'}:
|
||||
|
||||
with context.temp_override(**override):
|
||||
callback()
|
||||
|
||||
return retset
|
||||
return wrap
|
||||
'''
|
||||
|
||||
|
||||
class ACTIONLIB_OT_make_custom_preview(Operator):
|
||||
bl_idname = "actionlib.make_custom_preview"
|
||||
bl_label = "Custom Preview"
|
||||
bl_description = "Set a camera to preview an asset"
|
||||
|
||||
def modal(self, context, event):
|
||||
prefs = get_addons_prefs()
|
||||
|
||||
if not prefs.preview_modal:
|
||||
with context.temp_override(area=self.source_area, region=self.source_area.regions[-1]):
|
||||
bpy.ops.actionlib.store_anim_pose("INVOKE_DEFAULT", clear_previews=False, **prefs.add_asset_dict)
|
||||
return {"FINISHED"}
|
||||
|
||||
return {'PASS_THROUGH'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
|
||||
self.source_area = bpy.context.area
|
||||
|
||||
view3d = get_viewport()
|
||||
with context.temp_override(area=view3d, region=view3d.regions[-1], window=context.window):
|
||||
# To close the popup
|
||||
bpy.ops.screen.screen_full_area()
|
||||
bpy.ops.screen.back_to_previous()
|
||||
|
||||
view3d = get_viewport()
|
||||
with context.temp_override(area=view3d, region=view3d.regions[-1], window=context.window):
|
||||
bpy.ops.assetlib.make_custom_preview('INVOKE_DEFAULT', modal=True)
|
||||
|
||||
context.window_manager.modal_handler_add(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
|
||||
def get_preview_items(self, context):
|
||||
prefs = get_addon_prefs()
|
||||
return sorted([(k, k, '', v.icon_id, index) for index, (k, v) in enumerate(prefs.previews.items())], reverse=True)
|
||||
|
||||
|
||||
|
||||
class ACTIONLIB_OT_store_anim_pose(Operator):
|
||||
bl_idname = "actionlib.store_anim_pose"
|
||||
bl_label = "Add Action to the current library"
|
||||
bl_description = "Store current pose/anim to local library"
|
||||
|
||||
#use_new_folder: BoolProperty(default=False)
|
||||
warning: StringProperty(name='')
|
||||
path: StringProperty(name='Path')
|
||||
catalog: StringProperty(name='Catalog', update=asset_warning_callback, options={'TEXTEDIT_UPDATE'})
|
||||
@@ -795,13 +851,12 @@ class ACTIONLIB_OT_store_anim_pose(Operator):
|
||||
frame_end: IntProperty(name="Frame End")
|
||||
tags: StringProperty(name='Tags', description='Tags need to separate with a comma (,)')
|
||||
description: StringProperty(name='Description')
|
||||
preview : EnumProperty(items=get_preview_items)
|
||||
clear_previews : BoolProperty(default=True)
|
||||
store_library: StringProperty(name='Store Library')
|
||||
|
||||
#library: EnumProperty(items=lambda s, c: s.library_items, name="Library")
|
||||
#library: EnumProperty(items=lambda s, c: LIBRARY_ITEMS, name="Library")
|
||||
#CLIPBOARD_ASSET_MARKER = "ASSET-BLEND="
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context: Context) -> bool:
|
||||
def poll(cls, context: Context) -> bool:
|
||||
ob = context.object
|
||||
if not ob:
|
||||
cls.poll_message_set(f'You have no active object')
|
||||
@@ -826,16 +881,36 @@ class ACTIONLIB_OT_store_anim_pose(Operator):
|
||||
# col.operator("asset.tag_add", icon='ADD', text="")
|
||||
# col.operator("asset.tag_remove", icon='REMOVE', text="")
|
||||
|
||||
def to_dict(self):
|
||||
keys = ("catalog", "name", "action_type", "frame_start", "frame_end", "tags", "description", "store_library")
|
||||
return {k : getattr(self, k) for k in keys}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.separator()
|
||||
prefs = get_addon_prefs()
|
||||
|
||||
#row = layout.row(align=True)
|
||||
layout.use_property_split = True
|
||||
#layout.alignment = 'LEFT'
|
||||
split = layout.split(factor=0.39, align=True)
|
||||
#row = split.row(align=False)
|
||||
#split.use_property_split = False
|
||||
split.alignment = 'RIGHT'
|
||||
|
||||
split.label(text='Preview')
|
||||
|
||||
sub = split.row(align=True)
|
||||
sub.template_icon_view(self, "preview", show_labels=False)
|
||||
sub.separator()
|
||||
sub.operator("actionlib.make_custom_preview", icon='RESTRICT_RENDER_OFF', text='')
|
||||
|
||||
prefs.add_asset_dict.clear()
|
||||
prefs.add_asset_dict.update(self.to_dict())
|
||||
|
||||
sub.label(icon='BLANK1')
|
||||
#layout.ui_units_x = 50
|
||||
|
||||
#row = layout.row(align=True)
|
||||
layout.use_property_split = True
|
||||
|
||||
if self.current_library.merge_libraries:
|
||||
layout.prop(self.current_library, 'store_library', expand=False)
|
||||
|
||||
@@ -890,7 +965,14 @@ class ACTIONLIB_OT_store_anim_pose(Operator):
|
||||
self.asset_action.asset_mark()
|
||||
self.area = context.area
|
||||
self.current_library = get_active_library()
|
||||
#self.sce
|
||||
|
||||
if self.store_library:
|
||||
self.current_library.store_library = self.store_library
|
||||
else:
|
||||
lib = self.current_library.library_type.get_active_asset_library()
|
||||
if lib.name:
|
||||
self.current_library.store_library = lib.name
|
||||
self.store_library = lib.name
|
||||
|
||||
#lib = self.current_library
|
||||
self.tags = ''
|
||||
@@ -899,9 +981,21 @@ class ACTIONLIB_OT_store_anim_pose(Operator):
|
||||
#print(self, self.library_items)
|
||||
|
||||
self.catalog = get_active_catalog()
|
||||
self.set_action_type()
|
||||
self.set_action_type()
|
||||
|
||||
return context.window_manager.invoke_props_dialog(self, width=450)
|
||||
if self.clear_previews:
|
||||
prefs.previews.clear()
|
||||
|
||||
view3d = get_viewport()
|
||||
with context.temp_override(area=view3d, region=view3d.regions[-1]):
|
||||
bpy.ops.assetlib.make_custom_preview('INVOKE_DEFAULT')
|
||||
|
||||
else:
|
||||
preview_items = get_preview_items(self, context)
|
||||
if preview_items:
|
||||
self.preview = preview_items[0][0]
|
||||
|
||||
return context.window_manager.invoke_props_dialog(self, width=350)
|
||||
|
||||
def action_to_asset(self, action):
|
||||
#action.asset_mark()
|
||||
@@ -945,34 +1039,20 @@ class ACTIONLIB_OT_store_anim_pose(Operator):
|
||||
|
||||
return action
|
||||
|
||||
def render_preview(self, image_path, video_path):
|
||||
def render_animation(self, video_path):
|
||||
ctx = bpy.context
|
||||
scn = ctx.scene
|
||||
vl = ctx.view_layer
|
||||
area = get_view3d_persp()
|
||||
space = area.spaces.active
|
||||
|
||||
preview_attrs = [
|
||||
attrs = [
|
||||
(scn, 'use_preview_range', True),
|
||||
(scn, 'frame_preview_start', self.frame_start),
|
||||
(scn, 'frame_preview_end', self.frame_end),
|
||||
(scn.render, 'resolution_percentage', 100),
|
||||
(space.overlay, 'show_overlays', False),
|
||||
(space.region_3d, 'view_perspective', 'CAMERA'),
|
||||
]
|
||||
|
||||
image_attrs = [
|
||||
(scn.render, 'resolution_x', 512),
|
||||
(scn.render, 'resolution_y', 512),
|
||||
(scn.render, 'film_transparent', True),
|
||||
(scn.render.image_settings, 'file_format', 'PNG'),
|
||||
(scn.render.image_settings, 'color_mode', 'RGBA'),
|
||||
(scn.render.image_settings, 'color_depth', 8),
|
||||
(scn.render, 'use_overwrite', True),
|
||||
(scn.render, 'filepath', str(image_path))
|
||||
]
|
||||
|
||||
video_attrs = [
|
||||
(scn.render, 'resolution_x', 1280),
|
||||
(scn.render, 'resolution_y', 720),
|
||||
(scn.render.image_settings, 'file_format', 'FFMPEG'),
|
||||
@@ -984,10 +1064,6 @@ class ACTIONLIB_OT_store_anim_pose(Operator):
|
||||
(scn.render, 'filepath', str(video_path)),
|
||||
]
|
||||
|
||||
with attr_set(preview_attrs+image_attrs):
|
||||
with ctx.temp_override(area=area):
|
||||
bpy.ops.render.opengl(write_still=True)
|
||||
|
||||
if self.action_type == "ANIMATION":
|
||||
with attr_set(preview_attrs+video_attrs):
|
||||
with ctx.temp_override(area=area):
|
||||
@@ -1000,7 +1076,8 @@ class ACTIONLIB_OT_store_anim_pose(Operator):
|
||||
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):
|
||||
def execute(self, context: Context):
|
||||
|
||||
scn = context.scene
|
||||
vl = context.view_layer
|
||||
ob = context.object
|
||||
@@ -1011,11 +1088,11 @@ class ACTIONLIB_OT_store_anim_pose(Operator):
|
||||
if lib.merge_libraries:
|
||||
lib = prefs.libraries[self.current_library.store_library]
|
||||
|
||||
#lib_path = lib.library_path
|
||||
#name = lib.adapter.norm_file_name(self.name)
|
||||
asset_path = lib.adapter.get_asset_path(name=self.name, catalog=self.catalog)
|
||||
img_path = lib.adapter.get_image_path(name=self.name, catalog=self.catalog, filepath=asset_path)
|
||||
video_path = lib.adapter.get_video_path(name=self.name, catalog=self.catalog, filepath=asset_path)
|
||||
lib_type = lib.library_type
|
||||
|
||||
asset_path = lib_type.get_asset_path(name=self.name, catalog=self.catalog)
|
||||
img_path = lib_type.get_image_path(name=self.name, catalog=self.catalog, filepath=asset_path)
|
||||
video_path = lib_type.get_video_path(name=self.name, catalog=self.catalog, filepath=asset_path)
|
||||
|
||||
## Copy Action
|
||||
current_action = ob.animation_data.action
|
||||
@@ -1025,31 +1102,31 @@ class ACTIONLIB_OT_store_anim_pose(Operator):
|
||||
|
||||
self.action_to_asset(asset_action)
|
||||
|
||||
#lib.adapter.new_asset()
|
||||
#lib_type.new_asset()
|
||||
|
||||
#Saving the preview
|
||||
self.render_preview(img_path, video_path)
|
||||
with context.temp_override(id=asset_action):
|
||||
bpy.ops.ed.lib_id_load_custom_preview(
|
||||
filepath=str(img_path)
|
||||
)
|
||||
#Saving the video
|
||||
if self.action_type == "ANIMATION":
|
||||
self.render_animation(video_path)
|
||||
|
||||
#Saving the preview image
|
||||
preview = prefs.previews[self.preview]
|
||||
lib_type.write_preview(preview, img_path)
|
||||
|
||||
lib.adapter.write_asset(asset=asset_action, asset_path=asset_path)
|
||||
# Transfert the pixel to the action preview
|
||||
pixels = [0] * preview.image_size[0] * preview.image_size[1] * 4
|
||||
preview.image_pixels_float.foreach_get(pixels)
|
||||
asset_action.preview_ensure().image_pixels_float.foreach_set(pixels)
|
||||
|
||||
lib_type.write_asset(asset=asset_action, asset_path=asset_path)
|
||||
|
||||
asset_data = lib.adapter.get_asset_data(asset_action)
|
||||
asset_data = dict(lib_type.get_asset_data(asset_action), catalog=self.catalog)
|
||||
asset_info = lib_type.format_asset_info([asset_data], asset_path=asset_path)
|
||||
|
||||
diff = [dict(asset_data,
|
||||
image=str(img_path),
|
||||
filepath=str(asset_path),
|
||||
type='ACTION',
|
||||
library_id=lib.id,
|
||||
catalog=self.catalog,
|
||||
operation='ADD'
|
||||
)]
|
||||
# lib.adapter.write_description_file(asset_description, asset_path)
|
||||
#print('asset_info')
|
||||
#pprint(asset_info)
|
||||
|
||||
diff = [dict(a, operation='ADD') for a in lib_type.flatten_cache([asset_info])]
|
||||
|
||||
# Restore action and cleanup
|
||||
ob.animation_data.action = current_action
|
||||
|
||||
asset_action.asset_clear()
|
||||
@@ -1059,7 +1136,7 @@ class ACTIONLIB_OT_store_anim_pose(Operator):
|
||||
# TODO Write a proper method for this
|
||||
diff_path = Path(bpy.app.tempdir, 'diff.json')
|
||||
|
||||
#diff = [dict(a, operation='ADD') for a in [asset_description])]
|
||||
#diff = [dict(a, operation='ADD') for a in [asset_info])]
|
||||
diff_path.write_text(json.dumps(diff, indent=4))
|
||||
|
||||
bpy.ops.assetlib.bundle(name=lib.name, diff=str(diff_path), blocking=True)
|
||||
@@ -1085,6 +1162,7 @@ classes = (
|
||||
ACTIONLIB_OT_update_action_data,
|
||||
ACTIONLIB_OT_assign_rest_pose,
|
||||
ACTIONLIB_OT_store_anim_pose,
|
||||
ACTIONLIB_OT_make_custom_preview
|
||||
)
|
||||
|
||||
register, unregister = bpy.utils.register_classes_factory(classes)
|
||||
|
||||
Reference in New Issue
Block a user