Future-proof implementation 2.0

This commit is contained in:
raccoon
2025-01-23 20:04:04 +05:00
parent 6c7f9e5493
commit 27c93c3e29

View File

@@ -2,10 +2,13 @@ import os
from datetime import datetime from datetime import datetime
import bpy import bpy
from bpy.props import StringProperty, BoolProperty, PointerProperty, IntProperty _FUTURE = bpy.app.version >= (2, 80, 0)
from bpy.types import UIList, Operator, Panel, PropertyGroup, Context from bpy.props import EnumProperty, StringProperty, BoolProperty, PointerProperty, IntProperty
from bpy.types import UIList, Operator, Panel, PropertyGroup, Context, Scene
from io_scene_fbx import ExportFBX 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: 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): def draw(self, context):
col = self.layout.column(align=True) col = self.layout.column(align=True)
for line in message.strip().split("\n"): 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) 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()) 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)) filepath = os.path.join(rootpath, name_as_path(group.name))
basepath = os.path.dirname(filepath) basepath = os.path.dirname(filepath)
@@ -60,7 +64,7 @@ def fbx_export(context: Context) -> None:
global_scale=1.0, global_scale=1.0,
axis_forward='-Z', axis_forward='-Z',
axis_up='Y', axis_up='Y',
object_types=context.scene.fbx_export.object_types, object_types=context.scene.fbx_object_types,
use_mesh_modifiers=True, use_mesh_modifiers=True,
mesh_smooth_type='OFF', mesh_smooth_type='OFF',
use_mesh_edges=False, use_mesh_edges=False,
@@ -81,22 +85,6 @@ def fbx_export(context: Context) -> None:
print("\n[%s] Batch FBX export end." % datetime.now()) 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): class FBX_OT_ManualExport(Operator):
bl_idname = "fbx.manual_export" bl_idname = "fbx.manual_export"
bl_label = "Manual Export" bl_label = "Manual Export"
@@ -133,29 +121,29 @@ class SCENE_PT_fbx_autoexport(Panel):
col = layout.column() col = layout.column()
sub = col.column(align=True) 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") sub.operator(FBX_OT_ManualExport.bl_idname, icon="PASTEDOWN")
col.separator() col.separator()
split = col.split() split = col.split()
sub = split.column() sub = split.column()
sub.label("Filter groups:") sub.label(text="Filter groups:")
sub.template_list("FBX_UL_ExportItems", "", bpy.data, "groups", scene.fbx_export, "group_index", rows=5) sub.template_list("FBX_UL_ExportItems", "", bpy.data, "collections" if _FUTURE else "groups", scene, "fbx_group_index", rows=5)
sub = split.column() sub = split.column()
sub.label("Filter object types:") sub.label(text="Filter object types:")
sub.prop(scene.fbx_export, "object_types") sub.prop(scene, "fbx_object_types")
col.separator() col.separator()
col.prop(scene.fbx_export, "export_dir") col.prop(scene, "fbx_export_dir")
def on_save(*args, **kwargs) -> None: def on_save(*args, **kwargs) -> None:
""" """
Runs when Blender file is being saved 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 return
try: try:
@@ -165,7 +153,6 @@ def on_save(*args, **kwargs) -> None:
classes = [ classes = [
FBXExportProps,
FBX_OT_ManualExport, FBX_OT_ManualExport,
FBX_UL_ExportItems, FBX_UL_ExportItems,
SCENE_PT_fbx_autoexport, SCENE_PT_fbx_autoexport,
@@ -175,8 +162,33 @@ classes = [
def register() -> None: def register() -> None:
for cls in classes: for cls in classes:
bpy.utils.register_class(cls) bpy.utils.register_class(cls)
bpy.types.Scene.fbx_export = PointerProperty(type=FBXExportProps) Scene.fbx_export_dir = StringProperty(
bpy.types.Group.fbx_exportable = BoolProperty( 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", name="Export Group",
description="Mark group as FBX exportable", description="Mark group as FBX exportable",
default=False default=False
@@ -186,8 +198,11 @@ def register() -> None:
def unregister() -> None: def unregister() -> None:
bpy.app.handlers.save_pre.remove(on_save) bpy.app.handlers.save_pre.remove(on_save)
del bpy.types.Group.fbx_exportable del Group.fbx_exportable
del bpy.types.Scene.fbx_export 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): for cls in reversed(classes):
bpy.utils.unregister_class(cls) bpy.utils.unregister_class(cls)