From a7fb1b31d8e7c3dade15a17aaeb5e7f3d75431f0 Mon Sep 17 00:00:00 2001 From: Bartek Skorupa Date: Mon, 23 Jan 2012 10:50:54 +0000 Subject: 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 --- io_export_after_effects.py | 481 +++++++++++++++++++++++++++++++-------------- 1 file 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 -- cgit v1.2.3