From 27c93c3e2999bc962ca95f1d7470e46699aae964 Mon Sep 17 00:00:00 2001 From: raccoon Date: Thu, 23 Jan 2025 20:04:04 +0500 Subject: [PATCH] Future-proof implementation 2.0 --- .../avatar-example/mesh/blend~/fbx_export.py | 87 +++++++++++-------- 1 file changed, 51 insertions(+), 36 deletions(-) diff --git a/Assets/avatar-example/mesh/blend~/fbx_export.py b/Assets/avatar-example/mesh/blend~/fbx_export.py index d6fcd5a..a22aed4 100644 --- a/Assets/avatar-example/mesh/blend~/fbx_export.py +++ b/Assets/avatar-example/mesh/blend~/fbx_export.py @@ -2,10 +2,13 @@ import os from datetime import datetime import bpy -from bpy.props import StringProperty, BoolProperty, PointerProperty, IntProperty -from bpy.types import UIList, Operator, Panel, PropertyGroup, Context - -from io_scene_fbx import ExportFBX +_FUTURE = bpy.app.version >= (2, 80, 0) +from bpy.props import EnumProperty, StringProperty, BoolProperty, PointerProperty, IntProperty +from bpy.types import UIList, Operator, Panel, PropertyGroup, Context, Scene +if _FUTURE: + from bpy.types import Collection as Group +else: + from bpy.types import Group as Group def message_box(message: str, title: str = "Message", icon: str = 'INFO') -> None: @@ -18,7 +21,7 @@ def message_box(message: str, title: str = "Message", icon: str = 'INFO') -> Non def draw(self, context): col = self.layout.column(align=True) for line in message.strip().split("\n"): - col.label(line) + col.label(text=line) bpy.context.window_manager.popup_menu(draw, title=title, icon=icon) @@ -37,9 +40,10 @@ def fbx_export(context: Context) -> None: """ print("[%s] Batch FBX export begin" % datetime.now()) - rootpath = os.path.normpath(bpy.path.abspath(context.scene.fbx_export.export_dir)) + rootpath = os.path.normpath(bpy.path.abspath(context.scene.fbx_export_dir)) + groups = bpy.data.collections if _FUTURE else bpy.data.groups - for group in [g for g in bpy.data.groups if g.fbx_exportable]: + for group in [g for g in groups if g.fbx_exportable]: filepath = os.path.join(rootpath, name_as_path(group.name)) basepath = os.path.dirname(filepath) @@ -60,7 +64,7 @@ def fbx_export(context: Context) -> None: global_scale=1.0, axis_forward='-Z', axis_up='Y', - object_types=context.scene.fbx_export.object_types, + object_types=context.scene.fbx_object_types, use_mesh_modifiers=True, mesh_smooth_type='OFF', use_mesh_edges=False, @@ -81,22 +85,6 @@ def fbx_export(context: Context) -> None: print("\n[%s] Batch FBX export end." % datetime.now()) -class FBXExportProps(PropertyGroup): - export_dir = StringProperty( - name="FBX Export Dir", - description="FBX Export Directory", - subtype="DIR_PATH", - default="//../fbx/", - ) - on_save = BoolProperty( - name="Export on save", - description="Export FBX on Blender file save", - default=False - ) - object_types = ExportFBX.object_types - group_index = IntProperty(default=0) - - class FBX_OT_ManualExport(Operator): bl_idname = "fbx.manual_export" bl_label = "Manual Export" @@ -133,29 +121,29 @@ class SCENE_PT_fbx_autoexport(Panel): col = layout.column() sub = col.column(align=True) - sub.prop(scene.fbx_export, "on_save", icon='LOAD_FACTORY') + sub.prop(scene, "fbx_on_save", icon='FILE_REFRESH') sub.operator(FBX_OT_ManualExport.bl_idname, icon="PASTEDOWN") col.separator() split = col.split() sub = split.column() - sub.label("Filter groups:") - sub.template_list("FBX_UL_ExportItems", "", bpy.data, "groups", scene.fbx_export, "group_index", rows=5) + sub.label(text="Filter groups:") + sub.template_list("FBX_UL_ExportItems", "", bpy.data, "collections" if _FUTURE else "groups", scene, "fbx_group_index", rows=5) sub = split.column() - sub.label("Filter object types:") - sub.prop(scene.fbx_export, "object_types") + sub.label(text="Filter object types:") + sub.prop(scene, "fbx_object_types") col.separator() - col.prop(scene.fbx_export, "export_dir") + col.prop(scene, "fbx_export_dir") def on_save(*args, **kwargs) -> None: """ Runs when Blender file is being saved """ - if not bpy.context.scene.fbx_export.on_save: + if not bpy.context.scene.fbx_on_save: return try: @@ -165,7 +153,6 @@ def on_save(*args, **kwargs) -> None: classes = [ - FBXExportProps, FBX_OT_ManualExport, FBX_UL_ExportItems, SCENE_PT_fbx_autoexport, @@ -175,8 +162,33 @@ classes = [ def register() -> None: for cls in classes: bpy.utils.register_class(cls) - bpy.types.Scene.fbx_export = PointerProperty(type=FBXExportProps) - bpy.types.Group.fbx_exportable = BoolProperty( + Scene.fbx_export_dir = StringProperty( + name="FBX Export Dir", + description="FBX Export Directory", + subtype="DIR_PATH", + default="//../fbx/", + ) + Scene.fbx_on_save = BoolProperty( + name="Export on save", + description="Export FBX on Blender file save", + default=False + ) + Scene.fbx_object_types = EnumProperty( + name="Object Types", + options={'ENUM_FLAG'}, + items=( + ('EMPTY', "Empty", ""), + ('CAMERA', "Camera", ""), + ('LAMP', "Lamp", ""), + ('ARMATURE', "Armature", "WARNING: not supported in dupli/group instances"), + ('MESH', "Mesh", ""), + ('OTHER', "Other", "Other geometry types, like curve, metaball, etc. (converted to meshes)"), + ), + description="Which kind of object to export", + default={'EMPTY', 'CAMERA', 'LAMP', 'ARMATURE', 'MESH', 'OTHER'}, + ) + Scene.fbx_group_index = IntProperty(default=0) + Group.fbx_exportable = BoolProperty( name="Export Group", description="Mark group as FBX exportable", default=False @@ -186,8 +198,11 @@ def register() -> None: def unregister() -> None: bpy.app.handlers.save_pre.remove(on_save) - del bpy.types.Group.fbx_exportable - del bpy.types.Scene.fbx_export + del Group.fbx_exportable + del Scene.fbx_group_index + del Scene.fbx_object_types + del Scene.fbx_on_save + del Scene.fbx_export_dir for cls in reversed(classes): bpy.utils.unregister_class(cls)