diff --git a/OP_export_to_ae.py b/OP_export_to_ae.py index 39b591d..bfc5a65 100644 --- a/OP_export_to_ae.py +++ b/OP_export_to_ae.py @@ -17,6 +17,8 @@ from bpy.props import ( CollectionProperty, ) +from bpy.app.translations import pgettext_data as data_ + ''' def Export_AE_2d_position_json_data(): scn = bpy.context.scene @@ -200,21 +202,36 @@ def export_ae_transforms(directory, selection=None, camera=None, exposition=True scn.render.simplify_subdivision = simplify_subdivision -class GPEXP_OT_export_anim_to_ae(bpy.types.Operator, ExportHelper): +## Export operator without export_helper +class GPEXP_OT_export_anim_to_ae(bpy.types.Operator): bl_idname = "gp.export_anim_to_ae" - bl_label = "Export To After Effects" - bl_description = "Export the animation to after effect, object, greasepencil keys exposition, camera" + bl_label = "Export AE Files" + bl_description = "Export the animation to After Effects, 2D transform of objects, camera\ + \nand/or exposition (including greasepencil frames)" bl_options = {"REGISTER"} - # filter_glob: StringProperty(default='*.txt;*.json;', options={'HIDDEN'})# *.jpeg;*.png;*.tif;*.tiff;*.bmp - filter_glob: StringProperty(default='*.*', options={'HIDDEN'})# *.jpeg;*.png;*.tif;*.tiff;*.bmp + # filter_glob: StringProperty(default='*.*', options={'HIDDEN'})# *.jpeg;*.png;*.tif;*.tiff;*.bmp - filename_ext = '' + # filename_ext = '' - filepath : StringProperty( + # filepath : StringProperty( + # name="File Path", + # description="File path used for export", + # maxlen= 1024) + + ## Only need directory + directory : StringProperty( name="File Path", description="File path used for export", - maxlen= 1024) + maxlen= 1024, + subtype='DIR_PATH' + ) + prefix : StringProperty( + name="Prefix", + default='ae_', + description="Prefix name for exported txt and json files", + maxlen= 1024, + ) use_selection: BoolProperty( name="Selected Objects", @@ -262,30 +279,38 @@ class GPEXP_OT_export_anim_to_ae(bpy.types.Operator, ExportHelper): ) data_lang: EnumProperty( name="AE Language", - items=(('FR', "Français", ""), - ('EN', "Anglais", ""), + items=(('FR', "French", ""), + ('EN', "English", ""), ), - description="Language for the exported keyframe data (depend on After Effect language settings)", + description="Clipboard keyframe data language", default='FR', ) file_format: EnumProperty( - name="File", + name="File Type", options={'ENUM_FLAG'}, items=(('txt', "txt", ""), ('json', "json", ""), ), - description="File format to export (allow multiple at once)", + description="File format to export (possible to select multiple choices with Shift + Click)", default={'txt'}, ) - # def invoke(self, context, event): - # if event.ctrl: - # print('copy individual') # or separate operators - # - # return {'FINISHED'} - # return super().invoke(context, event) + def invoke(self, context, _event): + if not self.directory: + blend_filepath = context.blend_data.filepath + if blend_filepath: + dest_folder = Path(blend_filepath).parent + + ## If pre-enter a specific subfolder exists + ## (Commented, should be used with a project environment variable) + # output_folder = dest_folder / 'render' + # if output_folder.exists() and output_folder.is_dir(): + # dest_folder = output_folder - # prefix ? (ensure file is prefixed at export), but weird in the the context of an export field + self.directory = str(dest_folder) + + context.window_manager.fileselect_add(self) + return {'RUNNING_MODAL'} def draw(self, context): layout = self.layout @@ -296,6 +321,7 @@ class GPEXP_OT_export_anim_to_ae(bpy.types.Operator, ExportHelper): is_file_browser = context.space_data.type == 'FILE_BROWSER' export_main(layout, self, is_file_browser) + export_panel_format(layout, self, is_file_browser) export_panel_include(layout, self, is_file_browser) def execute(self, context): @@ -305,11 +331,11 @@ class GPEXP_OT_export_anim_to_ae(bpy.types.Operator, ExportHelper): object_types=self.object_types ) - ## Find directory - output_path = Path(self.filepath) + ## Ensure output path is directory + output_path = Path(self.directory) if not output_path.is_dir(): output_path = output_path.parent - + print('Output directory: ', output_path) cam = None @@ -328,7 +354,7 @@ class GPEXP_OT_export_anim_to_ae(bpy.types.Operator, ExportHelper): selection=objects_selection, camera=cam, exposition=self.exposition, - prefix='ae_', + prefix=self.prefix, fr=self.data_lang == 'FR', export_format=self.file_format, export_cam=self.use_active_camera) @@ -343,13 +369,6 @@ def get_object_selection(use_selection=False, use_visible=False, use_active_coll source_collection = None if use_active_collection: source_collection = context.view_layer.active_layer_collection.collection - # elif collection: - # local_collection = bpy.data.collections.get((collection, None)) - # if local_collection: - # source_collection = local_collection - # else: - # operator.report({'ERROR'}, "Collection '%s' was not found" % collection) - # return {'CANCELLED'} if source_collection: if use_selection: @@ -383,15 +402,20 @@ def get_object_selection(use_selection=False, use_visible=False, use_active_coll def export_main(layout, operator, is_file_browser): col = layout.column() col.prop(operator, 'exposition') - # col.prop(operator, 'use_grease_pencil_keys') - # col.prop(operator, 'use_object_keys') col.prop(operator, 'use_active_camera') + # col.prop(operator, 'use_object_keys') - ## Format (language and file) - layout.prop(operator, 'data_lang', expand=True) - if is_file_browser: - layout.column().prop(operator, 'file_format') +def export_panel_format(layout, operator, is_file_browser): + header, body = layout.panel("AE_export_format", default_closed=False) + header.label(text="Format") + if body: + col = body.column() + col.prop(operator, 'prefix') + ## Format (language and file) + col.row().prop(operator, 'data_lang', expand=True) + if is_file_browser: + col.column().prop(operator, 'file_format') def export_panel_include(layout, operator, is_file_browser): header, body = layout.panel("AE_export_include", default_closed=False)