diff --git a/core/importer.py b/core/importer.py new file mode 100644 index 0000000..e29ca11 --- /dev/null +++ b/core/importer.py @@ -0,0 +1,17 @@ +import bpy + +# Importers which don't need much code should be added here, however if a importer needs alot of code +# Like the PMX and PMD importers, they should be added to their own files. + + +# FBX Importer settings borrowed form Cat's Blender Plugin +def import_fbx(filepath): + try: + bpy.ops.import_scene.fbx( + filepath=filepath, + automatic_bone_orientation=False, + use_prepost_rot=False, + use_anim=False + ) + except (TypeError, ValueError) as e: + print(f"Error importing FBX: {str(e)}") diff --git a/core/register.py b/core/register.py index aad610f..5745870 100644 --- a/core/register.py +++ b/core/register.py @@ -113,4 +113,3 @@ def toposort(deps_dict): deps_dict = {value : deps_dict[value] - sorted_values for value in unsorted} return sorted_list - diff --git a/ui/quick_access.py b/ui/quick_access.py index a4d1373..81b9bee 100644 --- a/ui/quick_access.py +++ b/ui/quick_access.py @@ -6,6 +6,7 @@ from ..functions.translations import t from ..core.import_pmx import import_pmx from ..core.import_pmd import import_pmd +from ..core.importer import import_fbx @register_wrap class AvatarToolkitQuickAccessPanel(bpy.types.Panel): @@ -48,6 +49,7 @@ class AVATAR_TOOLKIT_OT_import_menu(bpy.types.Operator): layout.label(text="Select Import Method") layout.operator("avatar_toolkit.import_pmx", text=t("Quick_Access.import_pmx")) layout.operator("avatar_toolkit.import_pmd", text=t("Quick_Access.import_pmd")) + layout.operator("avatar_toolkit.import_fbx", text="Import FBX") @register_wrap class AVATAR_TOOLKIT_OT_export_menu(bpy.types.Operator): @@ -55,6 +57,10 @@ class AVATAR_TOOLKIT_OT_export_menu(bpy.types.Operator): bl_label = t("Quick_Access.export_menu.label") bl_description = t("Quick_Access.import_pmx.desc") + @classmethod + def poll(cls, context): + return any(obj.type == 'MESH' for obj in context.scene.objects) + def execute(self, context: Context): return {'FINISHED'} @@ -66,6 +72,7 @@ class AVATAR_TOOLKIT_OT_export_menu(bpy.types.Operator): layout = self.layout layout.label(text=t("Quick_Access.select_export.label")) layout.operator("avatar_toolkit.export_resonite", text=t("Quick_Access.select_export_resonite.label")) + layout.operator("avatar_toolkit.export_fbx", text="Export FBX") @register_wrap class AVATAR_TOOLKIT_OT_import_pmx(bpy.types.Operator): @@ -96,3 +103,31 @@ class AVATAR_TOOLKIT_OT_import_pmd(bpy.types.Operator): def invoke(self, context: Context, event): context.window_manager.fileselect_add(self) return {'RUNNING_MODAL'} + +@register_wrap +class AVATAR_TOOLKIT_OT_import_fbx(bpy.types.Operator): + bl_idname = "avatar_toolkit.import_fbx" + bl_label = "Import FBX" + + filepath: bpy.props.StringProperty(subtype="FILE_PATH") + + def execute(self, context): + import_fbx(self.filepath) + return {'FINISHED'} + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {'RUNNING_MODAL'} + +@register_wrap +class AVATAR_TOOLKIT_OT_export_fbx(bpy.types.Operator): + bl_idname = 'avatar_toolkit.export_fbx' + bl_label = "Export FBX" + bl_description = "Export the model as FBX" + bl_options = {'REGISTER', 'UNDO', 'INTERNAL'} + + def execute(self, context): + bpy.ops.export_scene.fbx('INVOKE_DEFAULT') + return {'FINISHED'} + + diff --git a/ui/settings.py b/ui/settings.py index 36089e9..9714da6 100644 --- a/ui/settings.py +++ b/ui/settings.py @@ -37,4 +37,3 @@ class AVATAR_TOOLKIT_OT_translation_restart_popup(bpy.types.Operator): layout = self.layout layout.label(text=t("Settings.translation_restart_popup.message1")) layout.label(text=t("Settings.translation_restart_popup.message2")) -