From 09eca870603958cc39ad7e41a0b010022de4e3a6 Mon Sep 17 00:00:00 2001 From: pullusb Date: Tue, 15 Oct 2024 15:07:11 +0200 Subject: [PATCH] Fix #4 export transformation to AE with export helper 1.8.8 - added: Add `export transformation to AE` in export menu: - export camera - export objects transformation - export exposition (object, GPencil keys, etc) --- CHANGELOG.md | 7 +++++ OP_export_to_ae.py | 76 ++++++++++++++++++++++------------------------ __init__.py | 2 +- 3 files changed, 45 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 804f035..5ca83d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,13 @@ Activate / deactivate layer opacity according to prefix Activate / deactivate all masks using MA layers --> +1.8.8 + +- added: Add `export transformation to AE` in export menu: + - export camera + - export objects transformation + - export exposition (object, GPencil keys, etc) + 1.8.7 - changed: Layer `channel_colors` have _value component_ clamped to 0.65 when transfered to compo node to limit color flashyness (eye care update) diff --git a/OP_export_to_ae.py b/OP_export_to_ae.py index 97c0072..8a0ab8c 100644 --- a/OP_export_to_ae.py +++ b/OP_export_to_ae.py @@ -154,16 +154,12 @@ def export_ae_transforms(directory, selection=None, camera=None, exposition=True rig_transforms = [tuple(round(x, 5) for v in b.matrix for x in v) for b in item.id_data.pose.bones] is_animated = rig_transforms != animation.get(name) animation[name] = rig_transforms - elif isinstance(item, bpy.types.GreasePencil): + elif item.type == 'GPENCIL': # isinstance(item.data, bpy.types.GreasePencil): + name = item.name co_3d = item.matrix_world.to_translation() - ## Check if there is keys on any layer - is_animated = False - ## append with is_animated flag to True - for l in item.data.layers: - is_animated = next((True for f in l.frames if l.frame_number == i), False) - if is_animated: - break - + ## Check if there is a GP-scene at scene-frame (i) on any visible layer + is_animated = i in [f.frame_number for l in item.data.layers for f in l.frames if not l.hide] + animation[name] = co_3d else: name = item.name co_3d = item.matrix_world.to_translation() @@ -235,11 +231,6 @@ class GPEXP_OT_export_anim_to_ae(bpy.types.Operator, ExportHelper): description="Export only objects from the active collection (and its children)", default=False, ) - # collection: StringProperty( - # name="Source Collection", - # description="Export only objects from this collection (and its children)", - # default="", - # ) object_types: EnumProperty( name="Object Types", options={'ENUM_FLAG'}, @@ -257,18 +248,13 @@ class GPEXP_OT_export_anim_to_ae(bpy.types.Operator, ExportHelper): exposition: BoolProperty( name='Exposition', description='Export the exposition of the keys', - default=False - ) - use_grease_pencil_keys: BoolProperty( - name='Grease Pencil Keys', - description='Consider grease pencil keys for animated exposition', - default=True - ) - use_object_keys: BoolProperty( - name='Object Keys', - description='Consider object transform keys for animated exposition', default=True ) + # use_object_keys: BoolProperty( + # name='Object Keys', + # description='Consider object transform keys for animated exposition', + # default=True + # ) use_active_camera: BoolProperty( name='Active Camera', description='Export active camera keys', @@ -276,7 +262,6 @@ class GPEXP_OT_export_anim_to_ae(bpy.types.Operator, ExportHelper): ) data_lang: EnumProperty( name="AE Language", - # options={'ENUM_FLAG'}, items=(('FR', "Français", ""), ('EN', "Anglais", ""), ), @@ -293,6 +278,13 @@ class GPEXP_OT_export_anim_to_ae(bpy.types.Operator, ExportHelper): default={'txt'}, ) + # def invoke(self, context, event): + # if event.ctrl: + # print('copy individual') # or separate operators + # + # return {'FINISHED'} + # return super().invoke(context, event) + # prefix ? (ensure file is prefixed at export), but weird in the the context of an export field def draw(self, context): @@ -313,19 +305,25 @@ class GPEXP_OT_export_anim_to_ae(bpy.types.Operator, ExportHelper): object_types=self.object_types ) - for o in objects_selection: - print(o.name) - # return {"FINISHED"} - ## Find directory output_path = Path(self.filepath) if not output_path.is_dir(): output_path = output_path.parent + + print('Output directory: ', output_path) - print('output_path: ', output_path) cam = None if self.use_active_camera and context.scene.camera: cam = context.scene.camera + + if cam and cam in objects_selection: + ## Remove active camera from objects + objects_selection.pop(objects_selection.index(cam)) + + print('Export AE transform from objects:') + for o in objects_selection: + print('- ', o.name) + export_ae_transforms(directory=output_path, selection=objects_selection, camera=cam, @@ -334,11 +332,10 @@ class GPEXP_OT_export_anim_to_ae(bpy.types.Operator, ExportHelper): fr=self.data_lang == 'FR', export_format=self.file_format) - self.report({'INFO'}, f'File saved here: {self.filepath}') + self.report({'INFO'}, f'File(s) saved in folder: {output_path}') return {"FINISHED"} - def get_object_selection(use_selection=False, use_visible=False, use_active_collection=False, object_types=None): context = bpy.context ## determine selection based on filters4 @@ -383,10 +380,11 @@ def get_object_selection(use_selection=False, use_visible=False, use_active_coll def export_main(layout, operator, is_file_browser): - layout.prop(operator, 'exposition') - layout.prop(operator, 'use_grease_pencil_keys') - layout.prop(operator, 'use_object_keys') - layout.prop(operator, 'use_active_camera') + 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') ## Format (language and file) layout.prop(operator, 'data_lang', expand=True) @@ -628,14 +626,14 @@ class GPEXP_PT_extra_gprender_func(bpy.types.Panel): col.operator("gp.export_keys_to_ae") col.operator("gp.export_cam_keys_to_ae") - - # def overcan_shift_fix_ui(self, context): # layout = self.layout # layout.operator("gp.fix_overscan_shift") def export_ae_anim_menu(self, context): - self.layout.operator('gp.export_anim_to_ae', text='After Effects Keyframe Data (.txt|.json)') + row = self.layout.row(align=False) + row.operator('gp.export_anim_to_ae', text='After Effects Keyframe Data (.txt/.json)') + # row.operator('gp.export_anim_to_ae', text='', icon='COPYDOWN') classes=( diff --git a/__init__.py b/__init__.py index 0aadaac..06ba50c 100644 --- a/__init__.py +++ b/__init__.py @@ -2,7 +2,7 @@ bl_info = { "name": "GP Render", "description": "Organise export of gp layers through compositor output", "author": "Samuel Bernou", - "version": (1, 8, 7), + "version": (1, 8, 8), "blender": (3, 0, 0), "location": "View3D", "warning": "",