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-23 14:50:54 +0400
committerBartek Skorupa <bartekskorupa@bartekskorupa.com>2012-01-23 14:50:54 +0400
commita7fb1b31d8e7c3dade15a17aaeb5e7f3d75431f0 (patch)
tree91ec31f8e122e115ae23a15675cf15d8ea0379c1 /io_export_after_effects.py
parenteeb3fc50a0a00d267459d239fbc0d6ede8970b7d (diff)
1. Fix for active camera export - when cameras bound to markers - option to export as one camera. 2. poll fix - changed from active object to active camera or selected objects 3. Export of active camera is now optional 4. Export of selected cameras is now optional 5. Naming fix - Changed tracking data export naming for user from BUNDLES to 3D MARKERS 6. Toolbar fix - wrapped in box, options added 7. Code cleanup - Prepared structure for future options of exporting lamps as AE lights, planes as AE solids and object tracking bundles, additional conditions added to avoid AE errors in some rare cases
Diffstat (limited to 'io_export_after_effects.py')
-rw-r--r--io_export_after_effects.py481
1 files changed, 331 insertions, 150 deletions
diff --git a/io_export_after_effects.py b/io_export_after_effects.py
index f0d44daf..8a56f4a3 100644
--- a/io_export_after_effects.py
+++ b/io_export_after_effects.py
@@ -19,9 +19,9 @@
#
bl_info = {
'name': 'Export: Adobe After Effects (.jsx)',
- 'description': 'Export selected cameras, objects & bundles to Adobe After Effects CS3 and above',
+ 'description': 'Export cameras, selected objects & camera solution 3D Markers to Adobe After Effects CS3 and above',
'author': 'Bartek Skorupa',
- 'version': (0, 5, 9),
+ 'version': (0, 6, 0),
'blender': (2, 6, 1),
'location': 'File > Export > Adobe After Effects (.jsx)',
"warning": "",
@@ -33,9 +33,10 @@ bl_info = {
}
-from math import pi
import bpy
import datetime
+from math import pi
+from mathutils import Matrix
# create list of static blender's data
@@ -44,6 +45,9 @@ def get_comp_data(context):
aspect_x = scene.render.pixel_aspect_x
aspect_y = scene.render.pixel_aspect_y
aspect = aspect_x / aspect_y
+ start = scene.frame_start
+ end = scene.frame_end
+ active_cam_frames = get_active_cam_for_each_frame(scene, start, end)
fps = scene.render.fps
return {
@@ -52,64 +56,94 @@ def get_comp_data(context):
'height': scene.render.resolution_y,
'aspect': aspect,
'fps': fps,
- 'start': scene.frame_start,
- 'end': scene.frame_end,
- 'duration': (scene.frame_end - scene.frame_start + 1.0) / fps,
+ 'start': start,
+ 'end': end,
+ 'duration': (end - start + 1.0) / fps,
+ 'active_cam_frames': active_cam_frames,
'curframe': scene.frame_current,
}
+# create list of active camera for each frame in case active camera is set by markers
+def get_active_cam_for_each_frame(scene, start, end):
+ active_cam_frames = []
+ sorted_markers = []
+ markers = scene.timeline_markers
+ if markers:
+ for marker in markers:
+ if marker.camera:
+ sorted_markers.append([marker.frame, marker])
+ sorted_markers = sorted(sorted_markers)
+
+ for i, marker in enumerate (sorted_markers):
+ cam = marker[1].camera
+ if i is 0 and marker[0] > start:
+ start_range = start
+ else:
+ start_range = sorted_markers[i][0]
+ if len(sorted_markers) > i + 1:
+ end_range = sorted_markers[i+1][0] - 1
+ else:
+ end_range = end
+ for i in range(start_range, end_range + 1):
+ active_cam_frames.append(cam)
+ if not active_cam_frames:
+ if scene.camera:
+ # in this case active_cam_frames array will have legth of 1. This will indicate that there is only one active cam in all frames
+ active_cam_frames.append(scene.camera)
+
+ return(active_cam_frames)
# create managable list of selected objects
-# (only selected objects will be analyzed and exported)
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)
+ solids = [] # list of all selected meshes that can be exported as AE's solids
+ lights = [] # list of all selected lamps that can be exported as AE's lights
nulls = [] # list of all selected objects exept cameras (will be used to create nulls in AE)
- nulls_names = [] # list of above objects names (prevent from calling "ConvertName(ob)" function too many times)
obs = context.selected_objects
for ob in obs:
if ob.type == 'CAMERA':
- cameras.append(ob)
- cams_names.append(convert_name(False, ob))
+ cameras.append([ob, convert_name(ob.name)])
+
+ elif is_plane(ob):
+ # not ready yet. is_plane(object) returns False in all cases. This is temporary
+ solids.append([ob, convert_name(ob.name)])
+
+ elif ob.type == 'LAMP':
+ # not ready yet. Lamps will be exported as nulls. This is temporary
+ nulls.append([ob, convert_name(ob.name)])
+
else:
- nulls.append(ob)
- 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))
-
+ nulls.append([ob, convert_name(ob.name)])
+
selection = {
'cameras': cameras,
- 'cams_names': cams_names,
+ 'solids': solids,
+ 'lights': lights,
'nulls': nulls,
- 'nulls_names': nulls_names,
}
return selection
+# check if object is plane and can be exported as AE's solid
+def is_plane(object):
+ # work in progress. Not ready yet
+ return False
# convert names of objects to avoid errors in AE.
-def convert_name(is_comp, ob):
- if is_comp:
- ob_name = ob
- ob_name = ob_name.replace('"', "_")
- else:
- ob_name = "_" + ob.name
+def convert_name(name):
+ name = "_" + name
- if ob_name[0].isdigit():
- ob_name = "_" + ob_name
-
- ob_name = bpy.path.clean_name(ob_name)
- ob_name = ob_name.replace("-", "_")
+ if name[0].isdigit():
+ name = "_" + name
+
+ name = bpy.path.clean_name(name)
+ name = name.replace("-", "_")
- return ob_name
+ return name
-# get object's blender's location and rotation and return AE's Position and Rotation/Orientation
+# get object's blender's location rotation and scale and return AE's Position, Rotation/Orientation and scale
# this function will be called for every object for every frame
def convert_transform_matrix(matrix, width, height, aspect, x_rot_correction=False):
@@ -126,7 +160,7 @@ def convert_transform_matrix(matrix, width, height, aspect, x_rot_correction=Fal
b_rot_y = b_rot_y / pi * 180.0
b_rot_z = b_rot_z / pi * 180.0
- # convert to AE Position and Rotation
+ # convert to AE Position Rotation and Scale
# Axes in AE are different. AE's X is blender's X, AE's Y is negative Blender's Z, AE's Z is Blender's Y
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
@@ -135,18 +169,12 @@ def convert_transform_matrix(matrix, width, height, aspect, x_rot_correction=Fal
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
- sx = b_scale_x * 100.0
- sy = b_scale_z * 100.0
- sz = b_scale_y * 100.0
+ sx = b_scale_x * 100.0 # scale of 1.0 is 100% in AE
+ sy = b_scale_z * 100.0 # scale of 1.0 is 100% in AE
+ sz = b_scale_y * 100.0 # scale of 1.0 is 100% in AE
return x, y, z, rx, ry, rz, sx, sy, sz
-
-def convert_transform(obj, width, height, aspect, x_rot_correction=False):
- matrix = obj.matrix_world.copy()
- return convert_transform_matrix(matrix, width, height, aspect, x_rot_correction)
-
-
# get camera's lens and convert to AE's "zoom" value in pixels
# this function will be called for every camera for every frame
#
@@ -204,10 +232,14 @@ def convert_lens(camera, width, height, aspect):
return zoom
+# convert object bundle's matrix. Not ready yet. Temporarily not active
+#def get_ob_bundle_matrix_world(cam_matrix_world, bundle_matrix):
+# matrix = cam_matrix_basis
+# return matrix
+
# jsx script for AE creation
-def write_jsx_file(file, data, selection, export_bundles, include_rotation, include_scale):
- from mathutils import Matrix
+def write_jsx_file(file, data, selection, include_active_cam, include_selected_cams, include_selected_objects, include_cam_bundles, include_rotation, include_scale):
print("\n---------------------------\n- Export to After Effects -\n---------------------------")
#store the current frame to restore it at the enf of export
@@ -216,12 +248,22 @@ def write_jsx_file(file, data, selection, export_bundles, include_rotation, incl
js_data = {
'times': '',
'cameras': {},
- 'objects': {},
+ 'solids': {},
+ 'lights': {},
+ 'nulls': {},
+ 'bundles_cam': {},
+ 'bundles_ob': {}, # not ready yet
}
- # create camera structure
- for i, cam in enumerate(selection['cameras']): # more than one camera can be selected
- name_ae = selection['cams_names'][i]
+ # create structure for active camera/cameras
+ active_cam_name = ''
+ if include_active_cam and data['active_cam_frames'] != []:
+ # check if more that one active cam exist (true if active cams set by markers)
+ if len(data['active_cam_frames']) is 1:
+ name_ae = convert_name(data['active_cam_frames'][0].name) # take name of the only active camera in scene
+ else:
+ name_ae = 'Active_Camera'
+ active_cam_name = name_ae # store name to be used when creating keyframes for active cam.
js_data['cameras'][name_ae] = {
'position': '',
'pointOfInterest': '',
@@ -230,52 +272,170 @@ def write_jsx_file(file, data, selection, export_bundles, include_rotation, incl
'zoom': '',
}
- # create object structure
- for i, obj in enumerate(selection['nulls']): # nulls representing blender's obs except cameras
- name_ae = selection['nulls_names'][i]
- js_data['objects'][name_ae] = {
- 'position': '',
- 'orientation': '',
- 'rotationX': '',
- 'scale': '',
- }
+ # create camera structure for selected cameras
+ if include_selected_cams:
+ for i, cam in enumerate(selection['cameras']): # more than one camera can be selected
+ if cam[1] != active_cam_name:
+ name_ae = selection['cameras'][i][1]
+ js_data['cameras'][name_ae] = {
+ 'position': '',
+ 'pointOfInterest': '',
+ 'orientation': '',
+ 'rotationX': '',
+ 'zoom': '',
+ }
+
+ # create structure for solids. Not ready yet. Temporarily not active
+# for i, obj in enumerate(selection['solids']):
+# name_ae = selection['solids'][i][1]
+# js_data['solids'][name_ae] = {
+# 'position': '',
+# 'orientation': '',
+# 'rotationX': '',
+# 'scale': '',
+# }
+
+ # create structure for lights. Not ready yet. Temporarily not active
+# for i, obj in enumerate(selection['lights']):
+# name_ae = selection['lights'][i][1]
+# js_data['nulls'][name_ae] = {
+# 'position': '',
+# 'orientation': '',
+# 'rotationX': '',
+# 'scale': '',
+# }
+
+
+ # create structure for nulls
+ for i, obj in enumerate(selection['nulls']): # nulls representing blender's obs except cameras, lamps and solids
+ if include_selected_objects:
+ name_ae = selection['nulls'][i][1]
+ js_data['nulls'][name_ae] = {
+ 'position': '',
+ 'orientation': '',
+ 'rotationX': '',
+ 'scale': '',
+ }
+
+ # create structure for cam bundles including positions (cam bundles don't move)
+ if include_cam_bundles:
+ # go through each selected Camera and active cameras
+ selected_cams = []
+ active_cams = []
+ if include_active_cam:
+ active_cams = data['active_cam_frames']
+ if include_selected_cams:
+ for cam in selection['cameras']:
+ selected_cams.append(cam[0])
+ # list of cameras that will be checked for 'CAMERA SOLVER'
+ cams = list(set.union(set(selected_cams), set(active_cams)))
+
+ for cam in cams:
+ # go through each constraints of this camera
+ for constraint in cam.constraints:
+ # does the camera have a Camera Solver constraint
+ if constraint.type == 'CAMERA_SOLVER':
+ # Which movie clip does it use ?
+ if constraint.use_active_clip:
+ clip = data['scn'].active_clip
+ else:
+ clip = constraint.clip
- # get all keyframes for each objects and store into dico
+ # go through each tracking point
+ for track in clip.tracking.tracks:
+ # Does this tracking point have a bundle (has its 3D position been solved)
+ if track.has_bundle:
+ # get the name of the tracker
+ name_ae = convert_name(str(cam.name) + '__' + str(track.name))
+ js_data['bundles_cam'][name_ae] = {
+ 'position': '',
+ }
+ # bundles are in camera space. Transpose to world space
+ matrix = Matrix.Translation(cam.matrix_basis.copy() * track.bundle)
+ # convert the position into AE space
+ ae_transform = convert_transform_matrix(matrix, data['width'], data['height'], data['aspect'], x_rot_correction=False)
+ js_data['bundles_cam'][name_ae]['position'] += '[%f,%f,%f],' % (ae_transform[0], ae_transform[1], ae_transform[2])
+
+
+ # get all keyframes for each object and store in dico
for frame in range(data['start'], data['end'] + 1):
print("working on frame: " + str(frame))
data['scn'].frame_set(frame)
- #get time for this loop
+ # get time for this loop
js_data['times'] += '%f ,' % ((frame - data['start']) / data['fps'])
- # keyframes for all cameras
- for i, cam in enumerate(selection['cameras']):
- #get cam name
- name_ae = selection['cams_names'][i]
- #convert cam position to AE space
- 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
+ # keyframes for active camera/cameras
+ if include_active_cam and data['active_cam_frames'] != []:
+ if len(data['active_cam_frames']) == 1:
+ cur_cam_index = 0
+ else:
+ cur_cam_index = frame - data['start']
+ active_cam = data['active_cam_frames'][cur_cam_index]
+ # get cam name
+ name_ae = active_cam_name
+ # convert cam transform properties to AE space
+ ae_transform = convert_transform_matrix(active_cam.matrix_world.copy(), data['width'], data['height'], data['aspect'], x_rot_correction=True)
+ # convert Blender's lens to AE's zoom in pixels
+ zoom = convert_lens(active_cam, data['width'], data['height'], data['aspect'])
+ # store all values in dico
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
- for i, ob in enumerate(selection['nulls']):
- #get object name
- name_ae = selection['nulls_names'][i]
- #convert ob position to AE space
- 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_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])
+ # keyframes for selected cameras
+ if include_selected_cams:
+ for i, cam in enumerate(selection['cameras']):
+ if cam[1] != active_cam_name:
+ # get cam name
+ name_ae = selection['cameras'][i][1]
+ # convert cam transform properties to AE space
+ ae_transform = convert_transform_matrix(cam[0].matrix_world.copy(), data['width'], data['height'], data['aspect'], x_rot_correction=True)
+ # convert Blender's lens to AE's zoom in pixels
+ zoom = convert_lens(cam[0], data['width'], data['height'], data['aspect'])
+ # store all values in dico
+ 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 solids. Not ready yet. Temporarily not active
+# for i, ob in enumerate(selection['solids']):
+# #get object name
+# name_ae = selection['solids'][i][1]
+# #convert ob position to AE space
+
+
+ # keyframes for all lights. Not ready yet. Temporarily not active
+# for i, ob in enumerate(selection['lights']):
+# #get object name
+# name_ae = selection['lights'][i][1]
+# #convert ob position to AE space
+
+
+ # keyframes for all nulls
+ if include_selected_objects:
+ for i, ob in enumerate(selection['nulls']):
+ # get object name
+ name_ae = selection['nulls'][i][1]
+ # convert ob transform properties to AE space
+ ae_transform = convert_transform_matrix(ob[0].matrix_world.copy(), data['width'], data['height'], data['aspect'], x_rot_correction=False)
+ # store all values in dico
+ js_data['nulls'][name_ae]['position'] += '[%f,%f,%f],' % (ae_transform[0], ae_transform[1], ae_transform[2])
+ if include_rotation:
+ js_data['nulls'][name_ae]['orientation'] += '[%f,%f,%f],' % (0, ae_transform[4], ae_transform[5])
+ js_data['nulls'][name_ae]['rotationX'] += '%f ,' % (ae_transform[3])
+ if include_scale:
+ js_data['nulls'][name_ae]['scale'] += '[%f,%f,%f],' % (ae_transform[6], ae_transform[7], ae_transform[8])
+
+ # keyframes for all object bundles. Not ready yet.
+ #
+ #
+ #
# ---- write JSX file
jsx_file = open(file, 'w')
@@ -291,7 +451,7 @@ def write_jsx_file(file, data, selection, export_bundles, include_rotation, incl
jsx_file.write('Exported with io_export_after_effects.py\n')
jsx_file.write('**************************************/\n\n\n\n')
- #wrap in function
+ # wrap in function
jsx_file.write("function compFromBlender(){\n")
# create new comp
jsx_file.write('\nvar compName = prompt("Blender Comp\'s Name \\nEnter Name of newly created Composition","BlendComp","Composition\'s Name");')
@@ -299,6 +459,37 @@ def write_jsx_file(file, data, selection, export_bundles, include_rotation, incl
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']))
+ # create camera bundles (nulls)
+ jsx_file.write('// ************** CAMERA 3D MARKERS **************\n\n\n')
+ for i, obj in enumerate(js_data['bundles_cam']):
+ name_ae = obj
+ 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(%s);\n\n\n' % (name_ae, js_data['bundles_cam'][obj]['position']))
+
+ # create object bundles (not ready yet)
+
+ # create objects (nulls)
+ jsx_file.write('// ************** OBJECTS **************\n\n\n')
+ for i, obj in enumerate(js_data['nulls']):
+ name_ae = obj
+ 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").setValuesAtTimes([%s],[%s]);\n' % (name_ae, js_data['times'], js_data['nulls'][obj]['position']))
+ if include_rotation:
+ jsx_file.write('%s.property("orientation").setValuesAtTimes([%s],[%s]);\n' % (name_ae, js_data['times'], js_data['nulls'][obj]['orientation']))
+ jsx_file.write('%s.property("rotationX").setValuesAtTimes([%s],[%s]);\n' % (name_ae, js_data['times'], js_data['nulls'][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)
+ if include_scale:
+ jsx_file.write('%s.property("scale").setValuesAtTimes([%s],[%s]);\n\n\n' % (name_ae, js_data['times'], js_data['nulls'][obj]['scale']))
+
+ # create solids (not ready yet)
+
+ # create lights (not ready yet)
+
# create cameras
jsx_file.write('// ************** CAMERAS **************\n\n\n')
for i, cam in enumerate(js_data['cameras']): # more than one camera can be selected
@@ -312,55 +503,6 @@ def write_jsx_file(file, data, selection, export_bundles, include_rotation, incl
jsx_file.write('%s.property("rotationZ").setValue(0);\n' % name_ae)
jsx_file.write('%s.property("zoom").setValuesAtTimes([%s],[%s]);\n\n\n' % (name_ae, js_data['times'], js_data['cameras'][cam]['zoom']))
- # create objects
- jsx_file.write('// ************** OBJECTS **************\n\n\n')
- for i, obj in enumerate(js_data['objects']): # more than one camera can be selected
- name_ae = obj
- 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").setValuesAtTimes([%s],[%s]);\n' % (name_ae, js_data['times'], js_data['objects'][obj]['position']))
- jsx_file.write('%s.property("orientation").setValuesAtTimes([%s],[%s]);\n' % (name_ae, js_data['times'], js_data['objects'][obj]['orientation']))
- 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:
-
- jsx_file.write('// ************** BUNDLES (3d tracks) **************\n\n\n')
-
- #Bundles are linked to MovieClip, so we have to find which MC is linked to our selected camera (if any?)
- mc = ''
-
- #go through each selected Cameras
- for cam in selection['cameras']:
- #go through each constrains of this camera
- for constrain in cam.constraints:
- #does the camera have a Camera Solver constrain
- if constrain.type == 'CAMERA_SOLVER':
- #Which movie clip does it use ?
- if constrain.use_active_clip:
- mc = data['scn'].active_clip
- else:
- mc = constrain.clip
-
- #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_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)
- #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_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')
@@ -375,10 +517,10 @@ def write_jsx_file(file, data, selection, export_bundles, include_rotation, incl
##########################################
-def main(file, context, export_bundles, include_rotation, include_scale):
+def main(file, context, include_active_cam, include_selected_cams, include_selected_objects, include_cam_bundles, include_rotation, include_scale):
data = get_comp_data(context)
selection = get_selected(context)
- write_jsx_file(file, data, selection, export_bundles, include_rotation, include_scale)
+ write_jsx_file(file, data, selection, include_active_cam, include_selected_cams, include_selected_objects, include_cam_bundles, include_rotation, include_scale)
print ("\nExport to After Effects Completed")
return {'FINISHED'}
@@ -396,29 +538,68 @@ class ExportJsx(bpy.types.Operator, ExportHelper):
bl_label = "Export to Adobe After Effects"
filename_ext = ".jsx"
filter_glob = StringProperty(default="*.jsx", options={'HIDDEN'})
+
+ include_active_cam = BoolProperty(
+ name = "Active Camera",
+ description = "Include Active Camera Data",
+ default = True,
+ )
+ include_selected_cams = BoolProperty(
+ name = "Selected Cameras",
+ description = "Add Selected Cameras Data",
+ default = True,
+ )
+ include_selected_objects = BoolProperty(
+ name = "Selected Objects",
+ description = "Add Selected Objects Data",
+ default = True,
+ )
include_rotation = BoolProperty(
- name="Include Rotation",
- description="Include export of selected objects' rotation",
- default=True,
+ name = "Rotation",
+ description ="Include rotation of selected objects",
+ default = True,
)
include_scale = BoolProperty(
- name="Include Scale",
- description="Include export of selected objects' scale",
- default=True,
+ name = "Scale",
+ description = "Include scale of selected object",
+ default = True,
)
- export_bundles = BoolProperty(
- name="Export Bundles",
- description="Export 3D Tracking points of a selected camera",
- default=True,
+ include_cam_bundles = BoolProperty(
+ name = "Camera 3D Markers",
+ description = "Include 3D Markers of Camera Motion Solution for selected cameras",
+ default = True,
)
-
+# include_ob_bundles = BoolProperty(
+# name = "Objects 3D Markers",
+# description = "Include 3D Markers of Object Motion Solution for selected cameras",
+# default = True,
+# )
+
+ def draw(self, context):
+ layout = self.layout
+
+ box = layout.box()
+ box.label('Include Cameras and Objects:')
+ box.prop(self, 'include_active_cam')
+ box.prop(self, 'include_selected_cams')
+ box.prop(self, 'include_selected_objects')
+ box.label("Include Objects' Properties:")
+ box.prop(self, 'include_rotation')
+ box.prop(self, 'include_scale')
+ box.label("Include Tracking Data:")
+ box.prop(self, 'include_cam_bundles')
+# box.prop(self, 'include_ob_bundles')
@classmethod
def poll(cls, context):
- return context.active_object is not None
+ active = context.active_object
+ selected = context.selected_objects
+ camera = context.scene.camera
+ ok = selected or camera
+ return ok
def execute(self, context):
- return main(self.filepath, context, self.export_bundles, self.include_rotation, self.include_scale)
+ return main(self.filepath, context, self.include_active_cam, self.include_selected_cams, self.include_selected_objects, self.include_cam_bundles, self.include_rotation, self.include_scale)
def menu_func(self, context):
@@ -435,4 +616,4 @@ def unregister():
bpy.types.INFO_MT_file_export.remove(menu_func)
if __name__ == "__main__":
- register()
+ register() \ No newline at end of file