Files
io_scene_ase/src/exporter.py

136 lines
4.9 KiB
Python

import bpy_extras
import typing
from bpy.types import UIList, Context, UILayout, AnyType, Operator
from bpy.props import StringProperty, EnumProperty, BoolProperty, PointerProperty, CollectionProperty, IntProperty
from .builder import *
from .writer import *
class AseExportCollectionPropertyGroup(bpy.types.PropertyGroup):
is_selected: BoolProperty()
name: StringProperty()
collection: PointerProperty(type=bpy.types.Collection)
class AseExportPropertyGroup(bpy.types.PropertyGroup):
collection_list: CollectionProperty(type=AseExportCollectionPropertyGroup)
collection_list_index: IntProperty()
class ASE_UL_CollectionList(UIList):
def draw_item(self, context: Context, layout: UILayout, data: AnyType, item: AnyType, icon: int,
active_data: AnyType, active_property: str, index: int = 0, flt_flag: int = 0):
collection: bpy.types.Collection = getattr(item, 'collection')
row = layout.row()
row.prop(item, 'is_selected', text='')
row.label(text=collection.name, icon='OUTLINER_COLLECTION')
class AseExportCollectionsSelectAll(Operator):
bl_idname = 'ase_export.collections_select_all'
bl_label = 'All'
def execute(self, context: Context) -> typing.Union[typing.Set[str], typing.Set[int]]:
pg = getattr(context.scene, 'ase_export')
for collection in pg.collection_list:
collection.is_selected = True
return {'FINISHED'}
class AseExportCollectionsDeselectAll(Operator):
bl_idname = 'ase_export.collections_deselect_all'
bl_label = 'None'
def execute(self, context: Context) -> typing.Union[typing.Set[str], typing.Set[int]]:
pg = getattr(context.scene, 'ase_export')
for collection in pg.collection_list:
collection.is_selected = False
return {'FINISHED'}
class ASE_OT_ExportOperator(bpy.types.Operator, bpy_extras.io_utils.ExportHelper):
bl_idname = 'io_scene_ase.ase_export' # important since its how bpy.ops.import_test.some_data is constructed
bl_label = 'Export ASE'
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
filename_ext = '.ase'
filter_glob: StringProperty(
default="*.ase",
options={'HIDDEN'},
maxlen=255, # Max internal buffer length, longer would be hilighted.
)
units: EnumProperty(
default='U',
items=(('M', 'Meters', ''),
('U', 'Unreal', '')),
name='Units'
)
use_raw_mesh_data: BoolProperty(
default=False,
description='No modifiers will be evaluated as part of the exported mesh',
name='Raw Mesh Data')
units_scale = {
'M': 60.352,
'U': 1.0
}
should_use_sub_materials: BoolProperty(
default=True,
description='Material format', # fill this in with a more human-friendly name/description
name='Use Sub-materials'
)
def draw(self, context):
pg = getattr(context.scene, 'ase_export')
layout = self.layout
rows = max(3, min(len(pg.collection_list), 10))
layout.prop(self, 'units', expand=False)
layout.prop(self, 'use_raw_mesh_data')
layout.prop(self, 'should_use_sub_materials')
# # SELECT ALL/NONE
# row = layout.row(align=True)
# row.label(text='Select')
# row.operator(AseExportCollectionsSelectAll.bl_idname, text='All', icon='CHECKBOX_HLT')
# row.operator(AseExportCollectionsDeselectAll.bl_idname, text='None', icon='CHECKBOX_DEHLT')
#
# layout.template_list('ASE_UL_CollectionList', '', pg, 'collection_list', pg, 'collection_list_index', rows=rows)
def invoke(self, context: bpy.types.Context, event):
# TODO: build a list of collections that have meshes in them
pg = getattr(context.scene, 'ase_export')
pg.collection_list.clear()
for collection in bpy.data.collections:
has_meshes = any(map(lambda x: x.type == 'MESH', collection.objects))
if has_meshes:
c = pg.collection_list.add()
c.collection = collection
context.window_manager.fileselect_add(self)
return {'RUNNING_MODAL'}
def execute(self, context):
options = AseBuilderOptions()
options.scale = self.units_scale[self.units]
options.use_raw_mesh_data = self.use_raw_mesh_data
try:
ase = build_ase(context, options)
writer_options = AseWriterOptions()
writer_options.should_use_sub_materials = self.should_use_sub_materials
AseWriter().write(self.filepath, ase, writer_options)
self.report({'INFO'}, 'ASE exported successful')
return {'FINISHED'}
except AseBuilderError as e:
self.report({'ERROR'}, str(e))
return {'CANCELLED'}
__classes__ = (
AseExportCollectionPropertyGroup,
AseExportPropertyGroup,
AseExportCollectionsSelectAll,
AseExportCollectionsDeselectAll,
ASE_UL_CollectionList,
ASE_OT_ExportOperator
)