From 05d22902c78688ea56f05e9cf0a8434d1d72359f Mon Sep 17 00:00:00 2001 From: Yusarina Date: Sun, 30 Jun 2024 13:07:43 +0100 Subject: [PATCH 1/5] FBX Import - Add's the ability to import FBX Models. --- core/importer.py | 17 +++++++++++++++++ ui/quick_access.py | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 core/importer.py 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/ui/quick_access.py b/ui/quick_access.py index 80562b1..dcbae0b 100644 --- a/ui/quick_access.py +++ b/ui/quick_access.py @@ -4,6 +4,7 @@ from .panel import AvatarToolkitPanel 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): @@ -45,6 +46,8 @@ class AVATAR_TOOLKIT_OT_import_menu(bpy.types.Operator): layout.label(text="Select Import Method") layout.operator("avatar_toolkit.import_pmx", text="Import PMX") layout.operator("avatar_toolkit.import_pmd", text="Import PMD") + layout.operator("avatar_toolkit.import_fbx", text="Import FBX") + @register_wrap class AVATAR_TOOLKIT_OT_export_menu(bpy.types.Operator): @@ -91,3 +94,18 @@ class AVATAR_TOOLKIT_OT_import_pmd(bpy.types.Operator): def invoke(self, 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'} From cce7e986bb6009adeca50aa4d912f32baa79b0ba Mon Sep 17 00:00:00 2001 From: Yusarina Date: Mon, 8 Jul 2024 09:42:16 +0100 Subject: [PATCH 2/5] Re-add typing --- core/register.py | 1 + 1 file changed, 1 insertion(+) diff --git a/core/register.py b/core/register.py index 449050e..aad610f 100644 --- a/core/register.py +++ b/core/register.py @@ -1,4 +1,5 @@ import bpy +import typing from typing import List, Type # List to store the classes to register From ee84ae640af9ca346457841192ba7ecf2dcc1523 Mon Sep 17 00:00:00 2001 From: Yusarina Date: Mon, 22 Jul 2024 01:56:22 +0100 Subject: [PATCH 3/5] Translation Popup now added. Due to some werid thing in Blender 4.2+ where we just can't get descriptions to translate, we now tell the user some translations won't apply unto restart. --- core/properties.py | 7 ++++++- functions/translations.py | 6 ++++-- resources/translations/en_US.json | 6 +++++- resources/translations/ja_JP.json | 6 +++++- ui/settings.py | 23 +++++++++++++++++++++++ 5 files changed, 43 insertions(+), 5 deletions(-) diff --git a/core/properties.py b/core/properties.py index 9bf108d..9841212 100644 --- a/core/properties.py +++ b/core/properties.py @@ -12,7 +12,12 @@ def register(): default=default_language, update=update_language ) + + bpy.types.Scene.avatar_toolkit_language_changed = bpy.props.BoolProperty(default=False) def unregister(): if hasattr(bpy.types.Scene, "avatar_toolkit_language"): - del bpy.types.Scene.avatar_toolkit_language \ No newline at end of file + del bpy.types.Scene.avatar_toolkit_language + + if hasattr(bpy.types.Scene, "avatar_toolkit_language_changed"): + del bpy.types.Scene.avatar_toolkit_language_changed diff --git a/functions/translations.py b/functions/translations.py index c60e886..9e2a742 100644 --- a/functions/translations.py +++ b/functions/translations.py @@ -87,8 +87,10 @@ def update_language(self, context): print(f"Updating language to: {self.avatar_toolkit_language}") # Debug print save_preference("language", int(self.avatar_toolkit_language)) load_translations() - # Reload the addon - bpy.ops.script.reload() + # Set a flag to indicate that a language change has occurred + context.scene.avatar_toolkit_language_changed = True + # Show popup after language change + bpy.ops.avatar_toolkit.translation_restart_popup('INVOKE_DEFAULT') # Initial load of translations print("Performing initial load of translations") # Debug print diff --git a/resources/translations/en_US.json b/resources/translations/en_US.json index c9f60cc..211cb5e 100644 --- a/resources/translations/en_US.json +++ b/resources/translations/en_US.json @@ -31,7 +31,11 @@ "Tools.convert_to_resonite.desc": "Converts bone names on a model to names compatable with Resonite", "Settings.label": "Settings", "Settings.language.label": "Language", - "Settings.language.desc": "Select the language for the addon's UI" + "Settings.language.desc": "Select the language for the addon's UI", + "Settings.translation_restart_popup.label": "Translation Update", + "Settings.translation_restart_popup.description": "Information about translation updates", + "Settings.translation_restart_popup.message1": "Some translations may not apply", + "Settings.translation_restart_popup.message2": "until you restart Blender." } } \ No newline at end of file diff --git a/resources/translations/ja_JP.json b/resources/translations/ja_JP.json index 0fb43c5..01e8d3b 100644 --- a/resources/translations/ja_JP.json +++ b/resources/translations/ja_JP.json @@ -31,6 +31,10 @@ "Tools.convert_to_resonite.desc": "モデルのボーン名をResoniteと互換性のある名前に変換します", "Settings.label": "設定", "Settings.language.label": "言語", - "Settings.language.desc": "アドオンのUI言語を選択してください" + "Settings.language.desc": "アドオンのUI言語を選択してください", + "Settings.translation_restart_popup.label": "翻訳の更新", + "Settings.translation_restart_popup.description": "翻訳の更新に関する情報", + "Settings.translation_restart_popup.message1": "一部の翻訳は適用されない場合があります", + "Settings.translation_restart_popup.message2": "Blenderを再起動するまで。" } } diff --git a/ui/settings.py b/ui/settings.py index 4287a9c..36089e9 100644 --- a/ui/settings.py +++ b/ui/settings.py @@ -15,3 +15,26 @@ class AvatarToolkitSettingsPanel(bpy.types.Panel): def draw(self, context): layout = self.layout layout.prop(context.scene, "avatar_toolkit_language", text=t("Settings.language.label")) + +@register_wrap +class AVATAR_TOOLKIT_OT_translation_restart_popup(bpy.types.Operator): + bl_idname = "avatar_toolkit.translation_restart_popup" + bl_label = t("Settings.translation_restart_popup.label") + bl_description = t("Settings.translation_restart_popup.description") + bl_options = {'INTERNAL'} + + def execute(self, context): + if context.scene.avatar_toolkit_language_changed: + # Reload the addon after the popup is closed + bpy.ops.script.reload() + context.scene.avatar_toolkit_language_changed = False + return {'FINISHED'} + + def invoke(self, context, event): + return context.window_manager.invoke_props_dialog(self, width=300) + + def draw(self, context): + layout = self.layout + layout.label(text=t("Settings.translation_restart_popup.message1")) + layout.label(text=t("Settings.translation_restart_popup.message2")) + From 041ce3e5d11122dc264633b446241934dc2282f1 Mon Sep 17 00:00:00 2001 From: Yusarina Date: Mon, 22 Jul 2024 02:24:33 +0100 Subject: [PATCH 4/5] Added FBX Export --- ui/quick_access.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/ui/quick_access.py b/ui/quick_access.py index dca6bcf..9ceee62 100644 --- a/ui/quick_access.py +++ b/ui/quick_access.py @@ -49,12 +49,15 @@ class AVATAR_TOOLKIT_OT_import_menu(bpy.types.Operator): layout.operator("avatar_toolkit.import_pmd", text="Import PMD") layout.operator("avatar_toolkit.import_fbx", text="Import FBX") - @register_wrap class AVATAR_TOOLKIT_OT_export_menu(bpy.types.Operator): bl_idname = "avatar_toolkit.export_menu" bl_label = "Export Menu" + @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 +69,7 @@ class AVATAR_TOOLKIT_OT_export_menu(bpy.types.Operator): layout = self.layout layout.label(text="Select Export Method") layout.operator("avatar_toolkit.export_resonite", text="Export Resonite") + layout.operator("avatar_toolkit.export_fbx", text="Export FBX") @register_wrap class AVATAR_TOOLKIT_OT_import_pmx(bpy.types.Operator): @@ -111,3 +115,16 @@ class AVATAR_TOOLKIT_OT_import_fbx(bpy.types.Operator): 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'} + + From f0a5f6d10afe11e9712ff42096e29bd5273c037f Mon Sep 17 00:00:00 2001 From: Yusarina Date: Mon, 22 Jul 2024 22:08:38 +0100 Subject: [PATCH 5/5] Added Authors to json --- resources/translations/en_US.json | 3 ++- resources/translations/ja_JP.json | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/resources/translations/en_US.json b/resources/translations/en_US.json index 211cb5e..e5a05f3 100644 --- a/resources/translations/en_US.json +++ b/resources/translations/en_US.json @@ -1,5 +1,6 @@ { - "messages": { + "authors": ["Avatar Toolkit Team"], + "messages": { "Language.auto": "Automatic", "Language.en_US": "English", "Language.ja_JP": "日本語", diff --git a/resources/translations/ja_JP.json b/resources/translations/ja_JP.json index 01e8d3b..8e2c537 100644 --- a/resources/translations/ja_JP.json +++ b/resources/translations/ja_JP.json @@ -1,4 +1,5 @@ { + "authors": ["Avatar Toolkit Team"], "messages": { "Language.auto": "Automatic", "Language.en_US": "English",