diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 4f5f55e..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,24 +0,0 @@ -# This CI is for zipping the plugin when ready for distribution -variables: - ADDON_VERSION: "1.0.0" - -stages: - - build - - deploy - -build-job: - stage: build - tags: - - Docker - image: alpine - before_script: - - apk add --update zip - script: - - echo "Zipping the plugin in its v$ADDON_VERSION…" - - rm .gitlab-ci.yml - - rm .gitignore - - cd .. && zip -9 -r -q khanat_tools_v1.0.0.zip khanat-tools/* - - mv khanat_tools_v$ADDON_VERSION.zip khanat-tools - artifacts: - paths: - - khanat_tools_v$ADDON_VERSION.zip diff --git a/README.md b/README.md index 1c8b4b8..cdb6166 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# Khanat tools +# Godot bridge ## Description -This Blender addon aims to ease the contribution from Blender for the [Khanat MMORPG project](https://khaganat.net/wikhan/fr:mmorpg). +This Blender addon aims to ease the contribution to Godot project for Blender artists. ## Installation -Get the zip file and install it in Blender. +Get the zip file and install it in Blender as any addon. ## Contributing If you want to discuss about the plugin, you can join in on XMPP : - you can use the web client kindly hosted by Jabberfr : diff --git a/__init__.py b/__init__.py index 4818757..a07dbd7 100644 --- a/__init__.py +++ b/__init__.py @@ -17,14 +17,14 @@ # END GPL LICENSE BLOCK ##### bl_info = { - "name": "Khanat tools", + "name": "Godot bridge", "author": "Yann Kervran", "version": (1, 0, 0), - "blender": (3, 4, 0), + "blender": (4, 1, 0), "location": "View3D > UI > N Panel", - "description": "Toolset for Khanat project", - "doc_url": "https://git.numenaute.org/yannk/khanat-tools", - "tracker_url": "https://git.numenaute.org/yannk/khanat-tools/-/issues", + "description": "Toolset for Godot projects", + "doc_url": "", + "tracker_url": "https://git.numenaute.org/YannK/Godot_bridge/issues", "category": "Generic" } diff --git a/addon/common/icons.py b/addon/common/icons.py index 67a9154..d277fca 100644 --- a/addon/common/icons.py +++ b/addon/common/icons.py @@ -3,7 +3,7 @@ import os icons_collection = None -icons_directory = os.path.dirname(__file__) +icons_directory = os.path.split(os.path.dirname(__file__))[0] + '/icons' def get_icon_id(identifier): diff --git a/addon/icons/godot.png b/addon/icons/godot.png new file mode 100644 index 0000000..e7b8df9 Binary files /dev/null and b/addon/icons/godot.png differ diff --git a/addon/icons/godot_bridge.png b/addon/icons/godot_bridge.png new file mode 100644 index 0000000..8dcc248 Binary files /dev/null and b/addon/icons/godot_bridge.png differ diff --git a/addon/icons/khanat.png b/addon/icons/khanat.png deleted file mode 100644 index a2ce0c0..0000000 Binary files a/addon/icons/khanat.png and /dev/null differ diff --git a/addon/menus/__init__.py b/addon/menus/__init__.py index 46a4b13..d6123da 100644 --- a/addon/menus/__init__.py +++ b/addon/menus/__init__.py @@ -1,7 +1,9 @@ -from .panel_main import KH_PT_panel_main +from .panel_main import GB_PT_panel_header, GB_PT_panel_parameters, GB_PT_panel_docs classes = ( - KH_PT_panel_main, + GB_PT_panel_header, + GB_PT_panel_parameters, + GB_PT_panel_docs, ) def register_menus(): diff --git a/addon/menus/panel_main.py b/addon/menus/panel_main.py index 0f6f2dc..0ba367d 100644 --- a/addon/menus/panel_main.py +++ b/addon/menus/panel_main.py @@ -4,28 +4,90 @@ from ..operators import readthedocs, export2godot from ..common import icons -class KH_PT_panel_main(bpy.types.Panel): +class GB_PT_panel_main(bpy.types.Panel): """ Main panel in 3D View """ - bl_label = 'Khanat tools' bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_context = '' - bl_category = 'Khanat' + bl_category = 'Godot bridge' def draw_header(self, context): layout = self.layout - layout.label(icon_value=icons.get_icon_id("khanat")) + layout.label(icon_value=icons.get_icon_id("godot_bridge")) + + +class GB_PT_panel_header(GB_PT_panel_main): + """ + Header of the panel + """ + bl_space_type = 'VIEW_3D' + bl_region_type = 'UI' + bl_context = '' + bl_category = 'Godot bridge' + bl_label = 'Godot bridge' + + def draw_header(self, context): + layout = self.layout + layout.label(icon_value=icons.get_icon_id("godot")) def draw(self, context): layout = self.layout row = layout.row() - row.operator(export2godot.KH_OT_export2godot.bl_idname) + row.operator(export2godot.GB_OT_export2godot.bl_idname, icon_value=icons.get_icon_id("godot")) layout.separator() - row = layout.row() - row.operator(readthedocs.KH_OT_readthedocs.bl_idname, icon_value=72) +class GB_PT_panel_parameters(GB_PT_panel_main): + """ + Sub panel for parameters + """ + bl_space_type = 'VIEW_3D' + bl_region_type = 'UI' + bl_context = '' + bl_category = 'Godot bridge' + bl_parent_id = "GB_PT_panel_header" + bl_label = 'Parameters' + + + def draw_header(self, context): + layout = self.layout + + def draw(self, context): + layout = self.layout + + layout.separator() + row = layout.row() + row.prop(bpy.context.scene, "godot_project_path") + row = layout.row() + row.prop(bpy.context.scene, "blender_repository_path") + row = layout.row() + row.prop(bpy.context.scene, "root_collection") + row = layout.row() + row.prop(bpy.context.scene, "licence") + row = layout.row() + row.prop(bpy.context.scene, "contributor") + +class GB_PT_panel_docs(GB_PT_panel_main): + + """ + Sub panel for documentation & links + """ + bl_space_type = 'VIEW_3D' + bl_region_type = 'UI' + bl_context = '' + bl_category = 'Godot bridge' + bl_label = 'Documentation' + bl_parent_id = "GB_PT_panel_header" + + + def draw_header(self, context): + layout = self.layout + + def draw(self, context): + layout = self.layout + row = layout.row() + row.operator(readthedocs.GB_OT_readthedocs.bl_idname, icon_value=72) layout.separator() diff --git a/addon/operators/__init__.py b/addon/operators/__init__.py index a14a7ed..4aeae5c 100644 --- a/addon/operators/__init__.py +++ b/addon/operators/__init__.py @@ -1,9 +1,10 @@ -from .readthedocs import KH_OT_readthedocs -from .export2godot import KH_OT_export2godot +import bpy +from .readthedocs import GB_OT_readthedocs +from .export2godot import GB_OT_export2godot classes = ( - KH_OT_readthedocs, - KH_OT_export2godot + GB_OT_readthedocs, + GB_OT_export2godot, ) diff --git a/addon/operators/export2godot.py b/addon/operators/export2godot.py index 808c39b..1b7ea1f 100644 --- a/addon/operators/export2godot.py +++ b/addon/operators/export2godot.py @@ -5,9 +5,9 @@ import re from ..common import addon from ..common import validate_name -class KH_OT_export2godot(bpy.types.Operator): +class GB_OT_export2godot(bpy.types.Operator): """Export whole collections to Godot throught glTF format""" - bl_idname = "kh.export2godot" + bl_idname = "gb.export2godot" bl_label = "Export to Godot project" bl_options = {'REGISTER', 'UNDO'} @@ -15,11 +15,16 @@ class KH_OT_export2godot(bpy.types.Operator): return self.execute(context) def execute(self, context): - prefs = addon.get_prefs() - print("Root collection : {}".format(prefs.root_collection)) - print("Godot path : {}".format(prefs.godot_project_path)) + # prefs = addon.get_prefs() + # print("Root collection : {}".format(prefs.default_root_collection)) + # print("Godot path : {}".format(prefs.default_godot_project_path)) + # print("Blender repository path : {}".format( + # prefs.default_blender_repository_path)) + + print("Root collection : {}".format(context.scene.root_collection)) + print("Godot path : {}".format(context.scene.godot_project_path)) print("Blender repository path : {}".format( - prefs.blender_repository_path)) + context.scene.blender_repository_path)) def save_file_beforehand(): self.report( @@ -34,7 +39,7 @@ class KH_OT_export2godot(bpy.types.Operator): """ final_path = bpy.data.filepath.replace( - prefs.blender_repository_path, prefs.godot_project_path) + context.scene.blender_repository_path, context.scene.godot_project_path) gltf_path = os.path.splitext(final_path)[0] if not os.path.isdir(gltf_path): os.makedirs(gltf_path) @@ -70,12 +75,13 @@ class KH_OT_export2godot(bpy.types.Operator): filepath="{}/{}".format(gltf_path, filename), export_format="GLTF_SEPARATE", # Export glTF Separate (.gltf + .bin + textures), Exports multiple files, with separate JSON, binary and texture data export_texture_dir="{}_{}_textures".format((os.path.splitext(os.path.basename(gltf_path)))[0], filename), # Textures folder - export_copyright=prefs.licence, + export_copyright=context.scene.licence, use_active_collection = True, use_renderable = True, export_cameras=False, export_lights=False, - export_apply=True # Applique les modifiers + export_apply=True, # Apply modifiers + export_gn_mesh=True # Apply Geometry Nodes Instance ) tscn_collections = [ coll for coll in bpy.data.collections if scene_collection.user_of_id(coll)] @@ -100,10 +106,10 @@ class KH_OT_export2godot(bpy.types.Operator): save_file_beforehand() else: try: - scn_col = bpy.data.collections[prefs.root_collection] + scn_col = bpy.data.collections[context.scene.root_collection] except KeyError: self.report({"WARNING"}, - "No \"{}\" root collection in the file - skipping export".format(prefs.root_collection)) + "No \"{}\" root collection in the file - skipping export".format(context.scene.root_collection)) return {"CANCELLED"} # Create the proper destination path diff --git a/addon/operators/readthedocs.py b/addon/operators/readthedocs.py index c1fa0e0..c1c94f8 100644 --- a/addon/operators/readthedocs.py +++ b/addon/operators/readthedocs.py @@ -1,17 +1,17 @@ import bpy -class KH_OT_readthedocs(bpy.types.Operator): - """Check online documentation for development""" +class GB_OT_readthedocs(bpy.types.Operator): + """Check online documentation about the addon""" - bl_idname="kh.readthedocs" + bl_idname="gb.readthedocs" bl_label="Online documentation" - bl_description="Go to Khanat Development Guide" + bl_description="Go to Godot bridge documentation" bl_options= {"REGISTER", "UNDO"} def invoke (self, context, event): return self.execute(context) def execute(self, context): - bpy.ops.wm.url_open("INVOKE_DEFAULT", url="https://git.numenaute.org/khaganat/mmorpg_khanat/khanat_gamedev_guide") + bpy.ops.wm.url_open("INVOKE_DEFAULT", url="https://git.numenaute.org/YannK/Godot_bridge_docs") return {"FINISHED"} \ No newline at end of file diff --git a/addon/parameters/__init__.py b/addon/parameters/__init__.py new file mode 100644 index 0000000..4e91250 --- /dev/null +++ b/addon/parameters/__init__.py @@ -0,0 +1,32 @@ +import bpy +from ..common import addon +from .sidecar import GB_sidecar + +prefs = addon.get_prefs() + +PARAMS = [ + ('godot_project_path', bpy.props.StringProperty(name="Godot project path", subtype='DIR_PATH', default=prefs.default_godot_project_path )), + ('blender_repository_path', bpy.props.StringProperty(name="Blender repository root", subtype='DIR_PATH', default=prefs.default_blender_repository_path)), + ('root_collection', bpy.props.StringProperty(name="Root collection", default=prefs.default_root_collection)), + ('licence', bpy.props.StringProperty(name="Licence", default=prefs.default_licence)), + ('contributor', bpy.props.StringProperty(name="Contributor", default=prefs.default_contributor)), +] + +classes = ( + GB_sidecar, +) + +def register_parameters(): + for (param_name, param_value) in PARAMS: + setattr(bpy.types.Scene, param_name, param_value) + from bpy.utils import register_class + for cls in classes: + register_class(cls) + + +def unregister_parameters(): + for (param_name, _) in PARAMS: + delattr(bpy.types.Scene, param_name) + from bpy.utils import unregister_class + for cls in classes: + unregister_class(cls) \ No newline at end of file diff --git a/addon/parameters/sidecar.py b/addon/parameters/sidecar.py new file mode 100644 index 0000000..c29f6ff --- /dev/null +++ b/addon/parameters/sidecar.py @@ -0,0 +1,21 @@ +import os +import bpy + +class GB_sidecar(bpy.types.Operator): + """ + Handling of sidecar file + """ + bl_idname = "gb.sidecar" + bl_label = "Sidecar file handling for Godot bridge" + bl_options = {'REGISTER', 'UNDO'} + + def invoke(self, context, event): + return self.execute(context) + + def execute(self, context): + return {"FINISHED"} + + + def read(filename): + print("filename: {}".format(filename)) + return {"FINISHED"} diff --git a/addon/preferences/__init__.py b/addon/preferences/__init__.py index db56e58..5679c02 100644 --- a/addon/preferences/__init__.py +++ b/addon/preferences/__init__.py @@ -1,9 +1,9 @@ import bpy -from .preferences import KH_Prefs +from .preferences import GB_Prefs classes = ( - KH_Prefs, + GB_Prefs, ) def register_preferences(): diff --git a/addon/preferences/preferences.py b/addon/preferences/preferences.py index 42bec10..d404b35 100644 --- a/addon/preferences/preferences.py +++ b/addon/preferences/preferences.py @@ -5,34 +5,34 @@ from bpy.props import StringProperty, IntProperty, BoolProperty from ..common import addon -class KH_Prefs(bpy.types.AddonPreferences): +class GB_Prefs(bpy.types.AddonPreferences): bl_idname = addon.addon_name # TODO EnumProperty to get list of projects to choose from - godot_project_path: StringProperty( + default_godot_project_path: StringProperty( name="Godot project path", subtype='DIR_PATH', default="//godot_project/" ) - blender_repository_path: StringProperty( + default_blender_repository_path: StringProperty( name="Blender repository root", subtype='DIR_PATH', default="//" ) - root_collection: StringProperty( + default_root_collection: StringProperty( name="Root collection", default="khanat", ) - licence: StringProperty( + default_licence: StringProperty( name="Licence", default="CC BY SA Khaganat", ) - contributor: StringProperty( + default_contributor: StringProperty( name="Contributor", default="", ) @@ -40,11 +40,11 @@ class KH_Prefs(bpy.types.AddonPreferences): def draw(self, context): layout = self.layout box = layout.box() - box.prop(self, "godot_project_path") - box.prop(self, "blender_repository_path") - box.prop(self, "root_collection") + box.prop(self, "default_godot_project_path") + box.prop(self, "default_blender_repository_path") + box.prop(self, "default_root_collection") layout.split() box = layout.box() - box.prop(self, "licence") - box.prop(self, "contributor") + box.prop(self, "default_licence") + box.prop(self, "default_contributor") diff --git a/addon/register/__init__.py b/addon/register/__init__.py index d979589..8d9b4db 100644 --- a/addon/register/__init__.py +++ b/addon/register/__init__.py @@ -6,6 +6,9 @@ def register_addon(): from ..preferences import register_preferences register_preferences() + from ..parameters import register_parameters + register_parameters() + from ..operators import register_operators register_operators() @@ -27,5 +30,8 @@ def unregister_addon(): from ..operators import unregister_operators unregister_operators() + from ..parameters import unregister_parameters + unregister_parameters() + from ..preferences import unregister_preferences unregister_preferences() \ No newline at end of file