Improved loading of blend layouts in Blender to behave like to JSON one

This commit is contained in:
Simone Barbieri 2021-11-12 15:42:10 +00:00
parent d2ae004b49
commit 41220adfca
6 changed files with 62 additions and 22 deletions

View file

@ -42,10 +42,13 @@ def get_unique_number(
return f"{count:0>2}"
def prepare_data(data, container_name):
def prepare_data(data, container_name=None):
name = data.name
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

View file

@ -10,6 +10,7 @@ from avalon import api
from avalon.blender.pipeline import AVALON_CONTAINERS
from avalon.blender.pipeline import AVALON_CONTAINER_ID
from avalon.blender.pipeline import AVALON_PROPERTY
from openpype import lib
from openpype.hosts.blender.api import plugin
@ -59,7 +60,9 @@ class BlendLayoutLoader(plugin.AssetLoader):
library = bpy.data.libraries.get(bpy.path.basename(libpath))
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(
libpath, link=True, relative=False
) as (data_from, data_to):
@ -106,7 +109,7 @@ class BlendLayoutLoader(plugin.AssetLoader):
parent.objects.link(obj)
for obj in objects:
local_obj = plugin.prepare_data(obj, group_name)
local_obj = plugin.prepare_data(obj)
action = None
@ -125,11 +128,12 @@ class BlendLayoutLoader(plugin.AssetLoader):
if material_slot.material:
plugin.prepare_data(material_slot.material, group_name)
elif local_obj.type == 'ARMATURE':
plugin.prepare_data(local_obj.data, group_name)
plugin.prepare_data(local_obj.data)
if action is not None:
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(
local_obj.animation_data.action, group_name)
@ -140,6 +144,21 @@ class BlendLayoutLoader(plugin.AssetLoader):
for t in v.targets:
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):
local_obj[AVALON_PROPERTY] = dict()
@ -168,6 +187,7 @@ class BlendLayoutLoader(plugin.AssetLoader):
libpath = self.fname
asset = context["asset"]["name"]
subset = context["subset"]["name"]
representation = str(context["representation"]["_id"])
asset_name = plugin.asset_name(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'
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:
if child.get(AVALON_PROPERTY):

View file

@ -29,12 +29,13 @@ class ExtractBlendAnimation(openpype.api.Extractor):
if isinstance(obj, bpy.types.Object) and obj.type == 'EMPTY':
child = obj.children[0]
if child and child.type == 'ARMATURE':
if not obj.animation_data:
obj.animation_data_create()
obj.animation_data.action = child.animation_data.action
obj.animation_data_clear()
data_blocks.add(child.animation_data.action)
data_blocks.add(obj)
if child.animation_data and child.animation_data.action:
if not obj.animation_data:
obj.animation_data_create()
obj.animation_data.action = child.animation_data.action
obj.animation_data_clear()
data_blocks.add(child.animation_data.action)
data_blocks.add(obj)
bpy.data.libraries.write(filepath, data_blocks)

View file

@ -123,7 +123,7 @@ class ExtractAnimationFBX(api.Extractor):
json_path = os.path.join(stagingdir, json_filename)
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")

View file

@ -183,20 +183,35 @@ class AnimationFBXLoader(api.Loader):
task.set_editor_property('destination_name', name)
task.set_editor_property('replace_existing', True)
task.set_editor_property('automated', True)
task.set_editor_property('save', False)
task.set_editor_property('save', True)
# set import options here
task.options.set_editor_property(
'automated_import_should_detect_type', True)
'automated_import_should_detect_type', False)
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_animations', True)
task.options.set_editor_property('override_full_name', True)
task.options.skeletal_mesh_import_data.set_editor_property(
'import_content_type',
unreal.FBXImportContentType.FBXICT_SKINNING_WEIGHTS
task.options.anim_sequence_import_data.set_editor_property(
'animation_length',
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(
container.get('namespace') + "/" + container.get('asset_name'))
@ -229,7 +244,7 @@ class AnimationFBXLoader(api.Loader):
unreal.EditorAssetLibrary.delete_directory(path)
asset_content = unreal.EditorAssetLibrary.list_assets(
parent_path, recursive=False
parent_path, recursive=False, include_folder=True
)
if len(asset_content) == 0:

View file

@ -504,7 +504,7 @@ class LayoutLoader(api.Loader):
EditorAssetLibrary.delete_directory(path)
asset_content = EditorAssetLibrary.list_assets(
parent_path, recursive=False
parent_path, recursive=False, include_folder=True
)
if len(asset_content) == 0: