diff --git a/openpype/hosts/blender/plugins/publish/extract_layout.py b/openpype/hosts/blender/plugins/publish/extract_layout.py index 93df5fe01c..804004bf4e 100644 --- a/openpype/hosts/blender/plugins/publish/extract_layout.py +++ b/openpype/hosts/blender/plugins/publish/extract_layout.py @@ -19,8 +19,8 @@ class ExtractLayout(openpype.api.Extractor): families = ["layout"] optional = True - def _export_animation(self, asset, instance, stagingdir): - file_names = [] + def _export_animation(self, asset, instance, stagingdir, fbx_count): + n = fbx_count for obj in asset.children: if obj.type != "ARMATURE": @@ -75,7 +75,7 @@ class ExtractLayout(openpype.api.Extractor): asset.select_set(True) obj.select_set(True) - fbx_filename = f"{instance.name}_{asset_group_name}.fbx" + fbx_filename = f"{n:03d}.fbx" filepath = os.path.join(stagingdir, fbx_filename) override = plugin.create_blender_context( @@ -108,9 +108,9 @@ class ExtractLayout(openpype.api.Extractor): pair[1].user_clear() bpy.data.actions.remove(pair[1]) - file_names.append(fbx_filename) + return fbx_filename, n + 1 - return file_names + return None, n def process(self, instance): # Define extract output file path @@ -127,6 +127,8 @@ class ExtractLayout(openpype.api.Extractor): asset_group = bpy.data.objects[str(instance)] + fbx_count = 0 + for asset in asset_group.children: metadata = asset.get(AVALON_PROPERTY) @@ -176,13 +178,17 @@ class ExtractLayout(openpype.api.Extractor): "z": asset.scale.z } } - json_data.append(json_element) # Extract the animation as well if family == "rig": - fbx_files.extend( - self._export_animation( - asset, instance, stagingdir)) + f, n = self._export_animation( + asset, instance, stagingdir, fbx_count) + if f: + fbx_files.append(f) + json_element["animation"] = f + fbx_count = n + + json_data.append(json_element) json_filename = "{}.json".format(instance.name) json_path = os.path.join(stagingdir, json_filename) @@ -196,14 +202,26 @@ class ExtractLayout(openpype.api.Extractor): 'files': json_filename, "stagingDir": stagingdir, } - fbx_representation = { - 'name': 'fbx', - 'ext': 'fbx', - 'files': fbx_files, - "stagingDir": stagingdir, - } instance.data["representations"].append(json_representation) - instance.data["representations"].append(fbx_representation) + + self.log.debug(fbx_files) + + if len(fbx_files) == 1: + fbx_representation = { + 'name': 'fbx', + 'ext': 'fbx', + 'files': fbx_files[0], + "stagingDir": stagingdir, + } + instance.data["representations"].append(fbx_representation) + elif len(fbx_files) > 1: + fbx_representation = { + 'name': 'fbx', + 'ext': 'fbx', + 'files': fbx_files, + "stagingDir": stagingdir, + } + instance.data["representations"].append(fbx_representation) self.log.info("Extracted instance '%s' to: %s", instance.name, json_representation) diff --git a/openpype/hosts/unreal/plugins/load/load_layout.py b/openpype/hosts/unreal/plugins/load/load_layout.py index 77691949bf..0ef24e42f4 100644 --- a/openpype/hosts/unreal/plugins/load/load_layout.py +++ b/openpype/hosts/unreal/plugins/load/load_layout.py @@ -85,16 +85,19 @@ class LayoutLoader(api.Loader): return actors def _import_animation( - self, asset_dir, path, rig_count, instance_name, skeleton, - actors_dict): - anim_path = f"{asset_dir}/animations/{path.with_suffix('').name}_{rig_count:02d}" + self, asset_dir, path, instance_name, skeleton, actors_dict, + animation_file): + anim_file = Path(animation_file) + anim_file_name = anim_file.with_suffix('') + + anim_path = f"{asset_dir}/animations/{anim_file_name}" # Import animation task = unreal.AssetImportTask() task.options = unreal.FbxImportUI() task.set_editor_property( - 'filename', str(path.with_suffix(f".{rig_count:02d}.fbx"))) + 'filename', str(path.with_suffix(f".{animation_file}"))) task.set_editor_property('destination_path', anim_path) task.set_editor_property( 'destination_name', f"{instance_name}_animation") @@ -174,7 +177,6 @@ class LayoutLoader(api.Loader): loaded = [] path = Path(libpath) - rig_count = 0 skeleton_dict = {} actors_dict = {} @@ -239,12 +241,12 @@ class LayoutLoader(api.Loader): else: skeleton = skeleton_dict.get(reference) - if skeleton: - self._import_animation( - asset_dir, path, rig_count, instance_name, skeleton, - actors_dict) + animation_file = element.get('animation') - rig_count += 1 + if animation_file and skeleton: + self._import_animation( + asset_dir, path, instance_name, skeleton, + actors_dict, animation_file) def _remove_family(self, assets, components, classname, propname): ar = unreal.AssetRegistryHelpers.get_asset_registry() @@ -356,6 +358,7 @@ class LayoutLoader(api.Loader): return asset_content def update(self, container, representation): + assert False, "Update not working for now. Delete and reload the layout." source_path = api.get_representation_path(representation) destination_path = container["namespace"]