mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 16:34:53 +01:00
Improved loading of blend layouts in Blender to behave like to JSON one
This commit is contained in:
parent
d2ae004b49
commit
41220adfca
6 changed files with 62 additions and 22 deletions
|
|
@ -42,10 +42,13 @@ def get_unique_number(
|
||||||
return f"{count:0>2}"
|
return f"{count:0>2}"
|
||||||
|
|
||||||
|
|
||||||
def prepare_data(data, container_name):
|
def prepare_data(data, container_name=None):
|
||||||
name = data.name
|
name = data.name
|
||||||
local_data = data.make_local()
|
local_data = data.make_local()
|
||||||
local_data.name = f"{container_name}:{name}"
|
if container_name:
|
||||||
|
local_data.name = f"{container_name}:{name}"
|
||||||
|
else:
|
||||||
|
local_data.name = f"{name}"
|
||||||
return local_data
|
return local_data
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ from avalon import api
|
||||||
from avalon.blender.pipeline import AVALON_CONTAINERS
|
from avalon.blender.pipeline import AVALON_CONTAINERS
|
||||||
from avalon.blender.pipeline import AVALON_CONTAINER_ID
|
from avalon.blender.pipeline import AVALON_CONTAINER_ID
|
||||||
from avalon.blender.pipeline import AVALON_PROPERTY
|
from avalon.blender.pipeline import AVALON_PROPERTY
|
||||||
|
from openpype import lib
|
||||||
from openpype.hosts.blender.api import plugin
|
from openpype.hosts.blender.api import plugin
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -59,7 +60,9 @@ class BlendLayoutLoader(plugin.AssetLoader):
|
||||||
library = bpy.data.libraries.get(bpy.path.basename(libpath))
|
library = bpy.data.libraries.get(bpy.path.basename(libpath))
|
||||||
bpy.data.libraries.remove(library)
|
bpy.data.libraries.remove(library)
|
||||||
|
|
||||||
def _process(self, libpath, asset_group, group_name, actions):
|
def _process(
|
||||||
|
self, libpath, asset_group, group_name, asset, representation, actions
|
||||||
|
):
|
||||||
with bpy.data.libraries.load(
|
with bpy.data.libraries.load(
|
||||||
libpath, link=True, relative=False
|
libpath, link=True, relative=False
|
||||||
) as (data_from, data_to):
|
) as (data_from, data_to):
|
||||||
|
|
@ -106,7 +109,7 @@ class BlendLayoutLoader(plugin.AssetLoader):
|
||||||
parent.objects.link(obj)
|
parent.objects.link(obj)
|
||||||
|
|
||||||
for obj in objects:
|
for obj in objects:
|
||||||
local_obj = plugin.prepare_data(obj, group_name)
|
local_obj = plugin.prepare_data(obj)
|
||||||
|
|
||||||
action = None
|
action = None
|
||||||
|
|
||||||
|
|
@ -125,11 +128,12 @@ class BlendLayoutLoader(plugin.AssetLoader):
|
||||||
if material_slot.material:
|
if material_slot.material:
|
||||||
plugin.prepare_data(material_slot.material, group_name)
|
plugin.prepare_data(material_slot.material, group_name)
|
||||||
elif local_obj.type == 'ARMATURE':
|
elif local_obj.type == 'ARMATURE':
|
||||||
plugin.prepare_data(local_obj.data, group_name)
|
plugin.prepare_data(local_obj.data)
|
||||||
|
|
||||||
if action is not None:
|
if action is not None:
|
||||||
local_obj.animation_data.action = action
|
local_obj.animation_data.action = action
|
||||||
elif local_obj.animation_data.action is not None:
|
elif (local_obj.animation_data and
|
||||||
|
local_obj.animation_data.action is not None):
|
||||||
plugin.prepare_data(
|
plugin.prepare_data(
|
||||||
local_obj.animation_data.action, group_name)
|
local_obj.animation_data.action, group_name)
|
||||||
|
|
||||||
|
|
@ -140,6 +144,21 @@ class BlendLayoutLoader(plugin.AssetLoader):
|
||||||
for t in v.targets:
|
for t in v.targets:
|
||||||
t.id = local_obj
|
t.id = local_obj
|
||||||
|
|
||||||
|
elif local_obj.type == 'EMPTY':
|
||||||
|
creator_plugin = lib.get_creator_by_name("CreateAnimation")
|
||||||
|
if not creator_plugin:
|
||||||
|
raise ValueError("Creator plugin \"CreateAnimation\" was "
|
||||||
|
"not found.")
|
||||||
|
|
||||||
|
api.create(
|
||||||
|
creator_plugin,
|
||||||
|
name=local_obj.name.split(':')[-1] + "_animation",
|
||||||
|
asset=asset,
|
||||||
|
options={"useSelection": False,
|
||||||
|
"asset_group": local_obj},
|
||||||
|
data={"dependencies": representation}
|
||||||
|
)
|
||||||
|
|
||||||
if not local_obj.get(AVALON_PROPERTY):
|
if not local_obj.get(AVALON_PROPERTY):
|
||||||
local_obj[AVALON_PROPERTY] = dict()
|
local_obj[AVALON_PROPERTY] = dict()
|
||||||
|
|
||||||
|
|
@ -168,6 +187,7 @@ class BlendLayoutLoader(plugin.AssetLoader):
|
||||||
libpath = self.fname
|
libpath = self.fname
|
||||||
asset = context["asset"]["name"]
|
asset = context["asset"]["name"]
|
||||||
subset = context["subset"]["name"]
|
subset = context["subset"]["name"]
|
||||||
|
representation = str(context["representation"]["_id"])
|
||||||
|
|
||||||
asset_name = plugin.asset_name(asset, subset)
|
asset_name = plugin.asset_name(asset, subset)
|
||||||
unique_number = plugin.get_unique_number(asset, subset)
|
unique_number = plugin.get_unique_number(asset, subset)
|
||||||
|
|
@ -183,7 +203,8 @@ class BlendLayoutLoader(plugin.AssetLoader):
|
||||||
asset_group.empty_display_type = 'SINGLE_ARROW'
|
asset_group.empty_display_type = 'SINGLE_ARROW'
|
||||||
avalon_container.objects.link(asset_group)
|
avalon_container.objects.link(asset_group)
|
||||||
|
|
||||||
objects = self._process(libpath, asset_group, group_name, None)
|
objects = self._process(
|
||||||
|
libpath, asset_group, group_name, asset, representation, None)
|
||||||
|
|
||||||
for child in asset_group.children:
|
for child in asset_group.children:
|
||||||
if child.get(AVALON_PROPERTY):
|
if child.get(AVALON_PROPERTY):
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,13 @@ class ExtractBlendAnimation(openpype.api.Extractor):
|
||||||
if isinstance(obj, bpy.types.Object) and obj.type == 'EMPTY':
|
if isinstance(obj, bpy.types.Object) and obj.type == 'EMPTY':
|
||||||
child = obj.children[0]
|
child = obj.children[0]
|
||||||
if child and child.type == 'ARMATURE':
|
if child and child.type == 'ARMATURE':
|
||||||
if not obj.animation_data:
|
if child.animation_data and child.animation_data.action:
|
||||||
obj.animation_data_create()
|
if not obj.animation_data:
|
||||||
obj.animation_data.action = child.animation_data.action
|
obj.animation_data_create()
|
||||||
obj.animation_data_clear()
|
obj.animation_data.action = child.animation_data.action
|
||||||
data_blocks.add(child.animation_data.action)
|
obj.animation_data_clear()
|
||||||
data_blocks.add(obj)
|
data_blocks.add(child.animation_data.action)
|
||||||
|
data_blocks.add(obj)
|
||||||
|
|
||||||
bpy.data.libraries.write(filepath, data_blocks)
|
bpy.data.libraries.write(filepath, data_blocks)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ class ExtractAnimationFBX(api.Extractor):
|
||||||
json_path = os.path.join(stagingdir, json_filename)
|
json_path = os.path.join(stagingdir, json_filename)
|
||||||
|
|
||||||
json_dict = {
|
json_dict = {
|
||||||
"instance_name": asset_group.get(AVALON_PROPERTY).get("namespace")
|
"instance_name": asset_group.get(AVALON_PROPERTY).get("objectName")
|
||||||
}
|
}
|
||||||
|
|
||||||
# collection = instance.data.get("name")
|
# collection = instance.data.get("name")
|
||||||
|
|
|
||||||
|
|
@ -183,20 +183,35 @@ class AnimationFBXLoader(api.Loader):
|
||||||
task.set_editor_property('destination_name', name)
|
task.set_editor_property('destination_name', name)
|
||||||
task.set_editor_property('replace_existing', True)
|
task.set_editor_property('replace_existing', True)
|
||||||
task.set_editor_property('automated', True)
|
task.set_editor_property('automated', True)
|
||||||
task.set_editor_property('save', False)
|
task.set_editor_property('save', True)
|
||||||
|
|
||||||
# set import options here
|
# set import options here
|
||||||
task.options.set_editor_property(
|
task.options.set_editor_property(
|
||||||
'automated_import_should_detect_type', True)
|
'automated_import_should_detect_type', False)
|
||||||
task.options.set_editor_property(
|
task.options.set_editor_property(
|
||||||
'original_import_type', unreal.FBXImportType.FBXIT_ANIMATION)
|
'original_import_type', unreal.FBXImportType.FBXIT_SKELETAL_MESH)
|
||||||
|
task.options.set_editor_property(
|
||||||
|
'mesh_type_to_import', unreal.FBXImportType.FBXIT_ANIMATION)
|
||||||
task.options.set_editor_property('import_mesh', False)
|
task.options.set_editor_property('import_mesh', False)
|
||||||
task.options.set_editor_property('import_animations', True)
|
task.options.set_editor_property('import_animations', True)
|
||||||
|
task.options.set_editor_property('override_full_name', True)
|
||||||
|
|
||||||
task.options.skeletal_mesh_import_data.set_editor_property(
|
task.options.anim_sequence_import_data.set_editor_property(
|
||||||
'import_content_type',
|
'animation_length',
|
||||||
unreal.FBXImportContentType.FBXICT_SKINNING_WEIGHTS
|
unreal.FBXAnimationLengthImportType.FBXALIT_EXPORTED_TIME
|
||||||
)
|
)
|
||||||
|
task.options.anim_sequence_import_data.set_editor_property(
|
||||||
|
'import_meshes_in_bone_hierarchy', False)
|
||||||
|
task.options.anim_sequence_import_data.set_editor_property(
|
||||||
|
'use_default_sample_rate', True)
|
||||||
|
task.options.anim_sequence_import_data.set_editor_property(
|
||||||
|
'import_custom_attribute', True)
|
||||||
|
task.options.anim_sequence_import_data.set_editor_property(
|
||||||
|
'import_bone_tracks', True)
|
||||||
|
task.options.anim_sequence_import_data.set_editor_property(
|
||||||
|
'remove_redundant_keys', True)
|
||||||
|
task.options.anim_sequence_import_data.set_editor_property(
|
||||||
|
'convert_scene', True)
|
||||||
|
|
||||||
skeletal_mesh = unreal.EditorAssetLibrary.load_asset(
|
skeletal_mesh = unreal.EditorAssetLibrary.load_asset(
|
||||||
container.get('namespace') + "/" + container.get('asset_name'))
|
container.get('namespace') + "/" + container.get('asset_name'))
|
||||||
|
|
@ -229,7 +244,7 @@ class AnimationFBXLoader(api.Loader):
|
||||||
unreal.EditorAssetLibrary.delete_directory(path)
|
unreal.EditorAssetLibrary.delete_directory(path)
|
||||||
|
|
||||||
asset_content = unreal.EditorAssetLibrary.list_assets(
|
asset_content = unreal.EditorAssetLibrary.list_assets(
|
||||||
parent_path, recursive=False
|
parent_path, recursive=False, include_folder=True
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(asset_content) == 0:
|
if len(asset_content) == 0:
|
||||||
|
|
|
||||||
|
|
@ -504,7 +504,7 @@ class LayoutLoader(api.Loader):
|
||||||
EditorAssetLibrary.delete_directory(path)
|
EditorAssetLibrary.delete_directory(path)
|
||||||
|
|
||||||
asset_content = EditorAssetLibrary.list_assets(
|
asset_content = EditorAssetLibrary.list_assets(
|
||||||
parent_path, recursive=False
|
parent_path, recursive=False, include_folder=True
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(asset_content) == 0:
|
if len(asset_content) == 0:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue