diff --git a/Assets/avatar-example/mesh/blend~/avatar-example_2.79.blend b/Assets/avatar-example/mesh/blend~/avatar-example_2.79.blend index a7ef3f8..9eae37c 100644 --- a/Assets/avatar-example/mesh/blend~/avatar-example_2.79.blend +++ b/Assets/avatar-example/mesh/blend~/avatar-example_2.79.blend @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee7309c6b5ecce6ecf699855aaee82689e07bdf85212ba280246af6f52bc7c92 -size 674272 +oid sha256:26ad5f7d5b753bd903d22392806c13cb8105f5abca9d335c30ce160fc96a1e55 +size 672576 diff --git a/Assets/avatar-example/mesh/blend~/fbx_export.py b/Assets/avatar-example/mesh/blend~/fbx_export.py index 4a69ff6..6e6189b 100644 --- a/Assets/avatar-example/mesh/blend~/fbx_export.py +++ b/Assets/avatar-example/mesh/blend~/fbx_export.py @@ -39,7 +39,7 @@ def fbx_export(context: Context) -> None: rootpath = os.path.normpath(bpy.path.abspath(context.scene.fbx_export.export_dir)) - for group in [g for g in bpy.data.groups if g.fbx_export.exportable]: + for group in [g for g in bpy.data.groups if g.fbx_exportable]: filepath = os.path.join(rootpath, name_as_path(group.name)) basepath = os.path.dirname(filepath) @@ -49,7 +49,7 @@ def fbx_export(context: Context) -> None: override = context.copy() override.update( { - "selected_objects": [o for o in group.objects if o.fbx_exportable] + "selected_objects": group.objects } ) @@ -61,7 +61,7 @@ def fbx_export(context: Context) -> None: axis_forward='-Z', axis_up='Y', object_types=context.scene.fbx_export.object_types, - use_mesh_modifiers=context.scene.fbx_export.use_mesh_modifiers, + use_mesh_modifiers=True, mesh_smooth_type='OFF', use_mesh_edges=False, use_tspace=False, @@ -77,7 +77,78 @@ def fbx_export(context: Context) -> None: filepath=filepath, ) - print("[%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): + bl_idname = "fbx.manual_export" + bl_label = "Manual Export" + bl_description = "Export FBX manualy" + + def execute(self, context): + try: + fbx_export(context) + except Exception as e: + self.report({'ERROR'}, str(e)) + return {'CANCELLED'} + return {'FINISHED'} + + +class FBX_UL_ExportItems(UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): + row = layout.row(align=True) + row.prop(item, "fbx_exportable", icon='CHECKBOX_HLT' if item.fbx_exportable else 'CHECKBOX_DEHLT', text="", emboss=False) + row.prop(item, "name", text="", emboss=False, icon='GROUP') + + +class SCENE_PT_fbx_autoexport(Panel): + """Creates a Panel in the scene context of the properties editor""" + bl_label = "FBX Auto-Export" + bl_idname = "SCENE_PT_fbx_autoexport" + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "scene" + + def draw(self, context): + layout = self.layout + scene = context.scene + + col = layout.column() + + sub = col.column(align=True) + sub.prop(scene.fbx_export, "on_save", icon='LOAD_FACTORY') + 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 = split.column() + sub.label("Filter object types:") + sub.prop(scene.fbx_export, "object_types") + + col.separator() + + col.prop(scene.fbx_export, "export_dir") def on_save(*args, **kwargs) -> None: @@ -93,109 +164,32 @@ def on_save(*args, **kwargs) -> None: message_box(str(e), "Export error", 'ERROR') -class FBX_OT_ForceExport(Operator): - bl_idname = "fbx.force_export" - bl_label = "Force Export" - bl_description = "Force export FBX" - - def execute(self, context): - try: - fbx_export(context) - except Exception as e: - self.report({'ERROR'}, str(e)) - return {'CANCELLED'} - return {'FINISHED'} +classes = [ + FBXExportProps, + FBX_OT_ManualExport, + FBX_UL_ExportItems, + SCENE_PT_fbx_autoexport, +] -class AutoexportProps(PropertyGroup): - object_types = ExportFBX.object_types - use_mesh_modifiers = ExportFBX.use_mesh_modifiers - 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=True - ) - group_index = IntProperty(default=0) - - -class GroupExportProps(PropertyGroup): - exportable = BoolProperty( +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( name="Export Group", description="Mark group as FBX exportable", default=False ) - obj_index = IntProperty(default=0) - show_obj_list = BoolProperty(default=False) + bpy.app.handlers.save_pre.append(on_save) -class FBX_UL_ExportObjects(UIList): - def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): - col = layout.column() - row = col.row(align=True) - row.prop(item, "fbx_exportable", icon='CHECKBOX_HLT' if item.fbx_exportable else 'CHECKBOX_DEHLT', text="", emboss=False) - row.prop(item, "name", text="", emboss=False, icon='OBJECT_DATA' if item.dupli_type == "NONE" else 'OUTLINER_OB_GROUP_INSTANCE') +def unregister() -> None: + bpy.app.handlers.save_pre.remove(on_save) + del bpy.types.Group.fbx_exportable + del bpy.types.Scene.fbx_export + for cls in reversed(classes): + bpy.utils.unregister_class(cls) -class FBX_UL_ExportItems(UIList): - def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): - col = layout.box().column() - row = col.split() - - sub = row.row(align=True) - # sub.alignment = 'LEFT' - sub.prop(item.fbx_export, "exportable", icon='CHECKBOX_HLT' if item.fbx_export.exportable else 'CHECKBOX_DEHLT', text="", emboss=False) - sub.prop(item, "name", text="", emboss=False, icon='GROUP') - sub = row.row() - sub.alignment = 'RIGHT' - sub.label(text=str(len(item.objects)), icon='OBJECT_DATA') - sub.prop(item.fbx_export, "show_obj_list", icon='TRIA_DOWN' if item.fbx_export.show_obj_list else 'TRIA_LEFT', text="", emboss=False) - - if item.fbx_export.show_obj_list: - col.template_list("FBX_UL_ExportObjects", str(index), item, "objects", item.fbx_export, "obj_index", rows=2) - - -class SCENE_PT_fbx_autoexport(Panel): - """Creates a Panel in the scene context of the properties editor""" - bl_label = "FBX Auto-Export" - bl_idname = "SCENE_PT_fbx_autoexport" - bl_space_type = 'PROPERTIES' - bl_region_type = 'WINDOW' - bl_context = "scene" - - def draw(self, context): - layout = self.layout - scene = context.scene - - col = layout.column() - col.prop(scene.fbx_export, "use_mesh_modifiers") - sub = col.row() - sub.prop(scene.fbx_export, "object_types") - col.template_list("FBX_UL_ExportItems", "", bpy.data, "groups", scene.fbx_export, "group_index", rows=3) - - col.separator() - col.prop(scene.fbx_export, "export_dir") - row = col.row(align=True) - row.prop(scene.fbx_export, "on_save", icon='LOAD_FACTORY') - row.operator(FBX_OT_ForceExport.bl_idname, icon="PASTEDOWN") - - -bpy.types.Object.fbx_exportable = BoolProperty( - name="Export Object", - description="Mark object as FBX exportable", - default=True -) -bpy.utils.register_class(FBX_OT_ForceExport) -bpy.utils.register_class(FBX_UL_ExportObjects) -bpy.utils.register_class(FBX_UL_ExportItems) -bpy.utils.register_class(AutoexportProps) -bpy.utils.register_class(GroupExportProps) -bpy.types.Scene.fbx_export = PointerProperty(type=AutoexportProps) -bpy.types.Group.fbx_export = PointerProperty(type=GroupExportProps) -bpy.utils.register_class(SCENE_PT_fbx_autoexport) -bpy.app.handlers.save_pre.append(on_save) +register()