Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartek Skorupa <bartekskorupa@bartekskorupa.com>2012-01-10 18:28:40 +0400
committerBartek Skorupa <bartekskorupa@bartekskorupa.com>2012-01-10 18:28:40 +0400
commitcd6725df324cd59e528d0535407ecd1f68896d53 (patch)
tree17e9b0c4f615c801dfb7ab4a2fbee8911ccef0c8 /io_export_after_effects.py
parenta8501db1f6ebe9100065b120921220f2b215d045 (diff)
1. Removed check if camera has attribute 'sensor size'. This option was needed for backwards compatibility. Not needed anymore 2. Moved adding composition's name from blender's toolbox to After Effects. User specifies name when running script in AE. 3. Added option to export selected objects' scale. 4. Rotation and scale export is now the option. User can include or exclude those properties. 5. Removed 'prefix' from AE's layers' names. This option was just creating mess. No real benefits from having this option 6. If no camera is selected - at least scene's camera will be exported (if exists)
Diffstat (limited to 'io_export_after_effects.py')
-rw-r--r--io_export_after_effects.py121
1 files changed, 66 insertions, 55 deletions
diff --git a/io_export_after_effects.py b/io_export_after_effects.py
index 52ab6461..997faec1 100644
--- a/io_export_after_effects.py
+++ b/io_export_after_effects.py
@@ -21,9 +21,9 @@ bl_info = {
'name': 'Export: Adobe After Effects (.jsx)',
'description': 'Export selected cameras, objects & bundles to Adobe After Effects CS3 and above',
'author': 'Bartek Skorupa',
- 'version': (0, 58),
- 'blender': (2, 6, 0),
- 'api': 42052,
+ 'version': (0, 59),
+ 'blender': (2, 6, 1),
+ 'api': 43253,
'location': 'File > Export > Adobe After Effects (.jsx)',
'category': 'Import-Export',
"warning": "",
@@ -59,7 +59,7 @@ def get_comp_data(context):
# create managable list of selected objects
# (only selected objects will be analyzed and exported)
-def get_selected(context, prefix):
+def get_selected(context):
cameras = [] # list of selected cameras
cams_names = [] # list of selected cameras' names (prevent from calling "ConvertName(ob)" function too many times)
nulls = [] # list of all selected objects exept cameras (will be used to create nulls in AE)
@@ -69,11 +69,17 @@ def get_selected(context, prefix):
for ob in obs:
if ob.type == 'CAMERA':
cameras.append(ob)
- cams_names.append(convert_name(False, ob, prefix))
+ cams_names.append(convert_name(False, ob))
else:
nulls.append(ob)
- nulls_names.append(convert_name(False, ob, prefix))
-
+ nulls_names.append(convert_name(False, ob))
+ # If no camera is selected - export at least scene's camera if exists
+ if not cameras:
+ cam = context.scene.camera
+ if cam:
+ cameras.append(cam)
+ cams_names.append(convert_name(False, cam))
+
selection = {
'cameras': cameras,
'cams_names': cams_names,
@@ -84,13 +90,13 @@ def get_selected(context, prefix):
return selection
-# convert names of objects to avoid errors in AE. Add user specified prefix
-def convert_name(is_comp, ob, prefix):
+# convert names of objects to avoid errors in AE.
+def convert_name(is_comp, ob):
if is_comp:
- ob_name = prefix + ob
+ ob_name = ob
ob_name = ob_name.replace('"', "_")
else:
- ob_name = prefix + "_" + ob.name
+ ob_name = "_" + ob.name
if ob_name[0].isdigit():
ob_name = "_" + ob_name
@@ -103,11 +109,12 @@ def convert_name(is_comp, ob, prefix):
# get object's blender's location and rotation and return AE's Position and Rotation/Orientation
# this function will be called for every object for every frame
-def convert_pos_rot_matrix(matrix, width, height, aspect, x_rot_correction=False):
+def convert_transform_matrix(matrix, width, height, aspect, x_rot_correction=False):
# get blender location for ob
b_loc_x, b_loc_y, b_loc_z = matrix.to_translation()
b_rot_x, b_rot_y, b_rot_z = matrix.to_euler()
+ b_scale_x, b_scale_y, b_scale_z = matrix.to_scale()
# get blender rotation for ob
if x_rot_correction:
@@ -122,17 +129,20 @@ def convert_pos_rot_matrix(matrix, width, height, aspect, x_rot_correction=False
x = (b_loc_x * 100.0) / aspect + width / 2.0 # calculate AE's X position
y = (-b_loc_z * 100.0) + (height / 2.0) # calculate AE's Y position
z = b_loc_y * 100.0 # calculate AE's Z position
+ # Using AE's rotation combined with AE's orientation allows to compensate for different euler rotation order.
rx = b_rot_x # calculate AE's X rotation. Will become AE's RotationX property
ry = -b_rot_z # calculate AE's Y rotation. Will become AE's OrientationY property
rz = b_rot_y # calculate AE's Z rotation. Will become AE's OrentationZ property
- # Using AE's rotation combined with AE's orientation allows to compensate for different euler rotation order.
+ sx = b_scale_x * 100.0
+ sy = b_scale_z * 100.0
+ sz = b_scale_y * 100.0
- return x, y, z, rx, ry, rz
+ return x, y, z, rx, ry, rz, sx, sy, sz
-def convert_pos_rot(obj, width, height, aspect, x_rot_correction=False):
+def convert_transform(obj, width, height, aspect, x_rot_correction=False):
matrix = obj.matrix_world.copy()
- return convert_pos_rot_matrix(matrix, width, height, aspect, x_rot_correction)
+ return convert_transform_matrix(matrix, width, height, aspect, x_rot_correction)
# get camera's lens and convert to AE's "zoom" value in pixels
@@ -181,15 +191,11 @@ def convert_pos_rot(obj, width, height, aspect, x_rot_correction=False):
# zoom = lens * dimension / sensor * aspect
#
def convert_lens(camera, width, height, aspect):
- if hasattr(camera.data, "sensor_width"): # Preserve compatibility with versions not supporting camera sensor.
- if camera.data.sensor_fit == 'VERTICAL':
- sensor = camera.data.sensor_height
- dimension = height
- else:
- sensor = camera.data.sensor_width
- dimension = width
+ if camera.data.sensor_fit == 'VERTICAL':
+ sensor = camera.data.sensor_height
+ dimension = height
else:
- sensor = 32 # standard blender's sensor size
+ sensor = camera.data.sensor_width
dimension = width
zoom = camera.data.lens * dimension / sensor * aspect
@@ -198,7 +204,7 @@ def convert_lens(camera, width, height, aspect):
# jsx script for AE creation
-def write_jsx_file(file, data, selection, export_bundles, comp_name, prefix):
+def write_jsx_file(file, data, selection, export_bundles, include_rotation, include_scale):
from mathutils import Matrix
print("\n---------------------------\n- Export to After Effects -\n---------------------------")
@@ -229,6 +235,7 @@ def write_jsx_file(file, data, selection, export_bundles, comp_name, prefix):
'position': '',
'orientation': '',
'rotationX': '',
+ 'scale': '',
}
# get all keyframes for each objects and store into dico
@@ -244,14 +251,14 @@ def write_jsx_file(file, data, selection, export_bundles, comp_name, prefix):
#get cam name
name_ae = selection['cams_names'][i]
#convert cam position to AE space
- ae_pos_rot = convert_pos_rot(cam, data['width'], data['height'], data['aspect'], x_rot_correction=True)
+ ae_transform = convert_transform(cam, data['width'], data['height'], data['aspect'], x_rot_correction=True)
#convert Blender's cam zoom to AE's
zoom = convert_lens(cam, data['width'], data['height'], data['aspect'])
#store all the value into dico
- js_data['cameras'][name_ae]['position'] += '[%f,%f,%f],' % (ae_pos_rot[0], ae_pos_rot[1], ae_pos_rot[2])
- js_data['cameras'][name_ae]['pointOfInterest'] += '[%f,%f,%f],' % (ae_pos_rot[0], ae_pos_rot[1], ae_pos_rot[2])
- js_data['cameras'][name_ae]['orientation'] += '[%f,%f,%f],' % (0, ae_pos_rot[4], ae_pos_rot[5])
- js_data['cameras'][name_ae]['rotationX'] += '%f ,' % (ae_pos_rot[3])
+ js_data['cameras'][name_ae]['position'] += '[%f,%f,%f],' % (ae_transform[0], ae_transform[1], ae_transform[2])
+ js_data['cameras'][name_ae]['pointOfInterest'] += '[%f,%f,%f],' % (ae_transform[0], ae_transform[1], ae_transform[2])
+ js_data['cameras'][name_ae]['orientation'] += '[%f,%f,%f],' % (0, ae_transform[4], ae_transform[5])
+ js_data['cameras'][name_ae]['rotationX'] += '%f ,' % (ae_transform[3])
js_data['cameras'][name_ae]['zoom'] += '[%f],' % (zoom)
#keyframes for all nulls
@@ -259,11 +266,14 @@ def write_jsx_file(file, data, selection, export_bundles, comp_name, prefix):
#get object name
name_ae = selection['nulls_names'][i]
#convert ob position to AE space
- ae_pos_rot = convert_pos_rot(ob, data['width'], data['height'], data['aspect'], x_rot_correction=False)
+ ae_transform = convert_transform(ob, data['width'], data['height'], data['aspect'], x_rot_correction=False)
#store all datas into dico
- js_data['objects'][name_ae]['position'] += '[%f,%f,%f],' % (ae_pos_rot[0], ae_pos_rot[1], ae_pos_rot[2])
- js_data['objects'][name_ae]['orientation'] += '[%f,%f,%f],' % (0, ae_pos_rot[4], ae_pos_rot[5])
- js_data['objects'][name_ae]['rotationX'] += '%f ,' % (ae_pos_rot[3])
+ js_data['objects'][name_ae]['position'] += '[%f,%f,%f],' % (ae_transform[0], ae_transform[1], ae_transform[2])
+ if include_rotation:
+ js_data['objects'][name_ae]['orientation'] += '[%f,%f,%f],' % (0, ae_transform[4], ae_transform[5])
+ js_data['objects'][name_ae]['rotationX'] += '%f ,' % (ae_transform[3])
+ if include_scale:
+ js_data['objects'][name_ae]['scale'] += '[%f,%f,%f],' % (ae_transform[6], ae_transform[7], ae_transform[8])
# ---- write JSX file
jsx_file = open(file, 'w')
@@ -282,7 +292,8 @@ def write_jsx_file(file, data, selection, export_bundles, comp_name, prefix):
#wrap in function
jsx_file.write("function compFromBlender(){\n")
# create new comp
- jsx_file.write('\nvar compName = "%s";' % (comp_name))
+ jsx_file.write('\nvar compName = prompt("Blender Comp\'s Name \\nEnter Name of newly created Composition","BlendComp","Composition\'s Name");')
+ jsx_file.write('if (compName){')
jsx_file.write('\nvar newComp = app.project.items.addComp(compName, %i, %i, %f, %f, %i);\n\n\n' %
(data['width'], data['height'], data['aspect'], data['duration'], data['fps']))
@@ -311,6 +322,7 @@ def write_jsx_file(file, data, selection, export_bundles, comp_name, prefix):
jsx_file.write('%s.property("rotationX").setValuesAtTimes([%s],[%s]);\n' % (name_ae, js_data['times'], js_data['objects'][obj]['rotationX']))
jsx_file.write('%s.property("rotationY").setValue(0);\n' % name_ae)
jsx_file.write('%s.property("rotationZ").setValue(0);\n\n\n' % name_ae)
+ jsx_file.write('%s.property("scale").setValuesAtTimes([%s],[%s]);\n' % (name_ae, js_data['times'], js_data['objects'][obj]['scale']))
# create Bundles
if export_bundles:
@@ -332,22 +344,22 @@ def write_jsx_file(file, data, selection, export_bundles, comp_name, prefix):
else:
mc = constrain.clip
- #go throuhg each tracking point
+ #go through each tracking point
for track in mc.tracking.tracks:
#is this tracking point has a Bundles (does it's 3D position has been solved)
if track.has_bundle:
# bundle are in camera space, so transpose it to world space
matrix = Matrix.Translation(cam.matrix_basis * track.bundle)
#convert the position into AE space
- ae_pos_rot = convert_pos_rot_matrix(matrix, data['width'], data['height'], data['aspect'], x_rot_correction=False)
+ ae_transform = convert_transform_matrix(matrix, data['width'], data['height'], data['aspect'], x_rot_correction=False)
#get the name of the tracker
- name_ae = convert_name(False, track, prefix)
+ name_ae = convert_name(False, track)
#write JS script for this Bundle
jsx_file.write('var %s = newComp.layers.addNull();\n' % name_ae)
jsx_file.write('%s.threeDLayer = true;\n' % name_ae)
jsx_file.write('%s.source.name = "%s";\n' % (name_ae, name_ae))
- jsx_file.write('%s.property("position").setValue([%f,%f,%f]);\n\n\n' % (name_ae, ae_pos_rot[0], ae_pos_rot[1], ae_pos_rot[2]))
-
+ jsx_file.write('%s.property("position").setValue([%f,%f,%f]);\n\n\n' % (name_ae, ae_transform[0], ae_transform[1], ae_transform[2]))
+ jsx_file.write('\n}else{alert ("Exit Import Blender animation data \\nNo Comp\'s name has been chosen","EXIT")};')
jsx_file.write("}\n\n\n")
jsx_file.write('app.beginUndoGroup("Import Blender animation data");\n')
jsx_file.write('compFromBlender();\n')
@@ -361,11 +373,10 @@ def write_jsx_file(file, data, selection, export_bundles, comp_name, prefix):
##########################################
-def main(file, context, export_bundles, comp_name, prefix):
+def main(file, context, export_bundles, include_rotation, include_scale):
data = get_comp_data(context)
- selection = get_selected(context, prefix)
- comp_name = convert_name(True, comp_name, "")
- write_jsx_file(file, data, selection, export_bundles, comp_name, prefix)
+ selection = get_selected(context)
+ write_jsx_file(file, data, selection, export_bundles, include_rotation, include_scale)
print ("\nExport to After Effects Completed")
return {'FINISHED'}
@@ -383,29 +394,29 @@ class ExportJsx(bpy.types.Operator, ExportHelper):
bl_label = "Export to Adobe After Effects"
filename_ext = ".jsx"
filter_glob = StringProperty(default="*.jsx", options={'HIDDEN'})
-
- comp_name = StringProperty(
- name="Comp Name",
- description="Name of composition to be created in After Effects",
- default="BlendComp"
+ include_rotation = BoolProperty(
+ name="Include Rotation",
+ description="Include export of selected objects' rotation",
+ default=True,
)
- prefix = StringProperty(
- name="Layer's Prefix",
- description="Prefix to use before AE layer's name",
- #default="bl_"
+ include_scale = BoolProperty(
+ name="Include Scale",
+ description="Include export of selected objects' scale",
+ default=True,
)
export_bundles = BoolProperty(
name="Export Bundles",
description="Export 3D Tracking points of a selected camera",
- default=False,
+ default=True,
)
+
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
- return main(self.filepath, context, self.export_bundles, self.comp_name, self.prefix)
+ return main(self.filepath, context, self.export_bundles, self.include_rotation, self.include_scale)
def menu_func(self, context):