diff options
author | Howard Trickey <howard.trickey@gmail.com> | 2011-11-09 00:40:27 +0400 |
---|---|---|
committer | Howard Trickey <howard.trickey@gmail.com> | 2011-11-09 00:40:27 +0400 |
commit | 4075fd85b9a873e43fa383bcfc5d6564b1880c9f (patch) | |
tree | e972bfdbb597099038b62702892299a7e5749977 | |
parent | f11d5e19539afe46a758d7e2dd6b99db6e8d0c39 (diff) |
add clip.py and space_clip.py, needed for last merge with trunk
-rw-r--r-- | release/scripts/startup/bl_operators/clip.py | 319 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/space_clip.py | 885 |
2 files changed, 1204 insertions, 0 deletions
diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py new file mode 100644 index 00000000000..55592621112 --- /dev/null +++ b/release/scripts/startup/bl_operators/clip.py @@ -0,0 +1,319 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> +import bpy +import os +import shutil +from bpy.types import Operator +from bpy_extras.io_utils import unpack_list + + +class CLIP_OT_track_to_empty(Operator): + """Create an Empty object which will be copying movement of active track""" + + bl_idname = "clip.track_to_empty" + bl_label = "2D Track to Empty" + bl_options = {'UNDO', 'REGISTER'} + + @classmethod + def poll(cls, context): + if context.space_data.type != 'CLIP_EDITOR': + return False + + sc = context.space_data + clip = sc.clip + + return clip and clip.tracking.tracks.active + + def execute(self, context): + sc = context.space_data + clip = sc.clip + track = clip.tracking.tracks.active + constraint = None + ob = None + + ob = bpy.data.objects.new(name=track.name, object_data=None) + ob.select = True + bpy.context.scene.objects.link(ob) + bpy.context.scene.objects.active = ob + + for con in ob.constraints: + if con.type == 'FOLLOW_TRACK': + constraint = con + break + + if constraint is None: + constraint = ob.constraints.new(type='FOLLOW_TRACK') + + constraint.clip = sc.clip + constraint.track = track.name + constraint.reference = 'TRACK' + + return {'FINISHED'} + + +class CLIP_OT_bundles_to_mesh(Operator): + """Create vertex cloud using coordinates of bundles""" + + bl_idname = "clip.bundles_to_mesh" + bl_label = "Bundles to Mesh" + bl_options = {'UNDO', 'REGISTER'} + + @classmethod + def poll(cls, context): + if context.space_data.type != 'CLIP_EDITOR': + return False + + sc = context.space_data + clip = sc.clip + + return clip + + def execute(self, context): + sc = context.space_data + clip = sc.clip + + new_verts = [] + + mesh = bpy.data.meshes.new(name="Bundles") + for track in clip.tracking.tracks: + if track.has_bundle: + new_verts.append(track.bundle) + + if new_verts: + mesh.vertices.add(len(new_verts)) + mesh.vertices.foreach_set("co", unpack_list(new_verts)) + + ob = bpy.data.objects.new(name="Bundles", object_data=mesh) + + bpy.context.scene.objects.link(ob) + + return {'FINISHED'} + + +class CLIP_OT_delete_proxy(Operator): + """Delete movie clip proxy files from the hard drive""" + + bl_idname = "clip.delete_proxy" + bl_label = "Delete Proxy" + bl_options = {'UNDO', 'REGISTER'} + + @classmethod + def poll(cls, context): + sc = context.space_data + + return sc.clip + + def invoke(self, context, event): + wm = context.window_manager + + return wm.invoke_confirm(self, event) + + def _rmproxy(self, abspath): + if not os.path.exists(abspath): + return + + if os.path.isdir(abspath): + shutil.rmtree(abspath) + else: + os.remove(abspath) + + def execute(self, context): + sc = context.space_data + clip = sc.clip + if clip.use_proxy_custom_directory: + proxydir = clip.proxy.directory + else: + clipdir = os.path.dirname(clip.filepath) + proxydir = os.path.join(clipdir, 'BL_proxy') + + clipfile = os.path.basename(clip.filepath) + proxy = os.path.join(proxydir, clipfile) + absproxy = bpy.path.abspath(proxy) + + # proxy_<quality>[_undostorted] + for x in (25, 50, 75, 100): + d = os.path.join(absproxy, 'proxy_' + str(x)) + + self._rmproxy(d) + self._rmproxy(d + '_undistorted') + self._rmproxy(os.path.join(absproxy, 'proxy_' + str(x) + '.avi')) + + tc = ('free_run.blen_tc', + 'interp_free_run.blen_tc', + 'record_run.blen_tc') + + for x in tc: + self._rmproxy(os.path.join(absproxy, x)) + + # remove proxy per-clip directory + try: + os.rmdir(absproxy) + except OSError: + pass + + # remove [custom] proxy directory if empty + try: + absdir = bpy.path.abspath(proxydir) + os.rmdir(absdir) + except OSError: + pass + + return {'FINISHED'} + + +class CLIP_OT_set_viewport_background(Operator): + """Set current movie clip as a camera background in 3D viewport""" + + bl_idname = "clip.set_viewport_background" + bl_label = "Set as Background" + bl_options = {'UNDO', 'REGISTER'} + + @classmethod + def poll(cls, context): + if context.space_data.type != 'CLIP_EDITOR': + return False + + sc = context.space_data + + return sc.clip + + def _set_background(self, space_v3d, clip, user): + bgpic = None + + for x in space_v3d.background_images: + if x.source == 'MOVIE': + bgpic = x + break + + if not bgpic: + bgpic = space_v3d.background_images.add() + + bgpic.source = 'MOVIE' + bgpic.clip = clip + bgpic.clip_user.proxy_render_size = user.proxy_render_size + bgpic.clip_user.use_render_undistorted = user.use_render_undistorted + bgpic.use_camera_clip = False + bgpic.view_axis = 'CAMERA' + + space_v3d.show_background_images = True + + def execute(self, context): + sc = context.space_data + clip = sc.clip + + for area in context.window.screen.areas: + if area.type == 'VIEW_3D': + for space in area.spaces: + if space.type == 'VIEW_3D': + self._set_background(space, clip, sc.clip_user) + + return {'FINISHED'} + + +class CLIP_OT_constraint_to_fcurve(Operator): + """Create F-Curves for object which will copy object's movement caused by this constraint""" + + bl_idname = "clip.constraint_to_fcurve" + bl_label = "Constraint to F-Curve" + bl_options = {'UNDO', 'REGISTER'} + + def _bake_object(self, scene, ob): + con = None + clip = None + sfra = None + efra = None + frame_current = scene.frame_current + matrices = [] + + # Find constraint which would eb converting + # TODO: several camera solvers and track followers would fail, + # but can't think about eal workflow where it'll be useful + for x in ob.constraints: + if x.type in ('CAMERA_SOLVER', 'FOLLOW_TRACK'): + con = x + + if not con: + return + + if con.type == 'FOLLOW_TRACK' and con.reference == 'BUNDLE': + mat = ob.matrix_world.copy() + ob.constraints.remove(con) + ob.matrix_world = mat + + return + + # Get clip used for parenting + if con.use_active_clip: + clip = scene.active_clip + else: + clip = con.clip + + if not clip: + return + + # Find start and end frames + for track in clip.tracking.tracks: + if sfra is None: + sfra = track.markers[0].frame + else: + sfra = min(sfra, track.markers[0].frame) + + if efra is None: + efra = track.markers[-1].frame + else: + efra = max(efra, track.markers[-1].frame) + + if sfra is None or efra is None: + return + + # Store object matrices + for x in range(sfra, efra + 1): + scene.frame_set(x) + matrices.append(ob.matrix_world.copy()) + + ob.animation_data_create() + + # Apply matrices on object and insert keyframes + i = 0 + for x in range(sfra, efra + 1): + scene.frame_set(x) + ob.matrix_world = matrices[i] + + ob.keyframe_insert("location") + + if ob.rotation_mode == 'QUATERNION': + ob.keyframe_insert("rotation_quaternion") + else: + ob.keyframe_insert("rotation_euler") + + i += 1 + + ob.constraints.remove(con) + + scene.frame_set(frame_current) + + def execute(self, context): + scene = context.scene + + for ob in scene.objects: + if ob.select: + self._bake_object(scene, ob) + + return {'FINISHED'} diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py new file mode 100644 index 00000000000..55fc641f5ae --- /dev/null +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -0,0 +1,885 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> +import bpy +from bpy.types import Panel, Header, Menu + + +class CLIP_HT_header(Header): + bl_space_type = 'CLIP_EDITOR' + + def draw(self, context): + layout = self.layout + + sc = context.space_data + clip = sc.clip + + row = layout.row(align=True) + row.template_header() + + if context.area.show_menus: + sub = row.row(align=True) + sub.menu("CLIP_MT_view") + + if clip: + sub.menu("CLIP_MT_select") + + sub.menu("CLIP_MT_clip") + + if clip: + sub.menu("CLIP_MT_track") + sub.menu("CLIP_MT_reconstruction") + + if clip: + layout.prop(sc, "mode", text="") + layout.prop(sc, "view", text="", expand=True) + + if sc.view == 'GRAPH': + row = layout.row(align=True) + + if sc.show_filters: + row.prop(sc, "show_filters", icon='DISCLOSURE_TRI_DOWN', text="Filters") + row.prop(sc, "show_graph_frames", icon='SEQUENCE', text="") + row.prop(sc, "show_graph_tracks", icon='ANIM', text="") + else: + row.prop(sc, "show_filters", icon='DISCLOSURE_TRI_RIGHT', text="Filters") + + row = layout.row() + row.template_ID(sc, "clip", open='clip.open') + + if clip: + r = clip.tracking.reconstruction + + if r.is_valid: + layout.label(text="Average solve error: %.4f" % + (r.average_error)) + + layout.template_running_jobs() + + +class CLIP_PT_tools_marker(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Marker" + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return clip and sc.mode == 'TRACKING' + + def draw(self, context): + layout = self.layout + + col = layout.column(align=True) + col.operator("clip.add_marker_move") + col.operator("clip.detect_features") + col.operator("clip.delete_track") + + +class CLIP_PT_tools_tracking(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Track" + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return clip and sc.mode == 'TRACKING' + + def draw(self, context): + layout = self.layout + clip = context.space_data.clip + settings = clip.tracking.settings + + row = layout.row(align=True) + + props = row.operator("clip.track_markers", text="", icon='FRAME_PREV') + props.backwards = True + props = row.operator("clip.track_markers", text="", + icon='PLAY_REVERSE') + props.backwards = True + props.sequence = True + props = row.operator("clip.track_markers", text="", icon='PLAY') + props.sequence = True + row.operator("clip.track_markers", text="", icon='FRAME_NEXT') + + col = layout.column(align=True) + props = col.operator("clip.clear_track_path", text="Clear After") + props.action = 'REMAINED' + + props = col.operator("clip.clear_track_path", text="Clear Before") + props.action = 'UPTO' + + props = col.operator("clip.clear_track_path", text="Clear Track Path") + props.action = 'ALL' + + layout.operator("clip.join_tracks") + + +class CLIP_PT_tools_solving(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Solving" + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return clip and sc.mode == 'TRACKING' + + def draw(self, context): + layout = self.layout + clip = context.space_data.clip + settings = clip.tracking.settings + + col = layout.column(align=True) + col.operator("clip.solve_camera") + col.operator("clip.clear_solution") + + col = layout.column(align=True) + col.prop(settings, "keyframe_a") + col.prop(settings, "keyframe_b") + + +class CLIP_PT_tools_cleanup(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Clean up" + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return clip and sc.mode == 'TRACKING' + + def draw(self, context): + layout = self.layout + clip = context.space_data.clip + settings = clip.tracking.settings + + layout.operator("clip.clean_tracks") + + layout.prop(settings, 'clean_frames', text="Frames") + layout.prop(settings, 'clean_error', text="Error") + layout.prop(settings, 'clean_action', text="") + + +class CLIP_PT_tools_geometry(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Geometry" + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return clip and sc.mode == 'RECONSTRUCTION' + + def draw(self, context): + layout = self.layout + + layout.operator("clip.bundles_to_mesh") + layout.operator("clip.track_to_empty") + + +class CLIP_PT_tools_orientation(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Orientation" + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return clip and sc.mode == 'RECONSTRUCTION' + + def draw(self, context): + sc = context.space_data + layout = self.layout + settings = sc.clip.tracking.settings + + col = layout.column(align=True) + col.label(text="Scene Orientation:") + col.operator("clip.set_floor") + col.operator("clip.set_origin") + + row = col.row() + row.operator("clip.set_axis", text="Set X Axis").axis = 'X' + row.operator("clip.set_axis", text="Set Y Axis").axis = 'Y' + + layout.separator() + + col = layout.column() + col.operator("clip.set_scale") + col.prop(settings, "distance") + + +class CLIP_PT_tools_grease_pencil(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Grease Pencil" + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return clip and sc.mode == 'DISTORTION' + + def draw(self, context): + layout = self.layout + + col = layout.column(align=True) + + row = col.row(align=True) + row.operator("gpencil.draw", text="Draw").mode = 'DRAW' + row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT' + + row = col.row(align=True) + row.operator("gpencil.draw", text="Poly").mode = 'DRAW_POLY' + row.operator("gpencil.draw", text="Erase").mode = 'ERASER' + + row = col.row() + row.prop(context.tool_settings, "use_grease_pencil_sessions") + + +class CLIP_PT_track(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Track" + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return sc.mode == 'TRACKING' and clip + + def draw(self, context): + layout = self.layout + sc = context.space_data + clip = context.space_data.clip + act_track = clip.tracking.tracks.active + + if not act_track: + layout.active = False + layout.label(text="No active track") + return + + row = layout.row() + row.prop(act_track, "name", text="") + + sub = row.row(align=True) + + sub.template_marker(sc, "clip", sc.clip_user, act_track, True) + + icon = 'LOCKED' if act_track.lock else 'UNLOCKED' + sub.prop(act_track, "lock", text="", icon=icon) + + layout.template_track(sc, "scopes") + + row = layout.row(align=True) + row.prop(act_track, "use_red_channel", text="R", toggle=True) + row.prop(act_track, "use_green_channel", text="G", toggle=True) + row.prop(act_track, "use_blue_channel", text="B", toggle=True) + + layout.separator() + + row = layout.row(align=True) + label = bpy.types.CLIP_MT_track_color_presets.bl_label + row.menu('CLIP_MT_track_color_presets', text=label) + row.menu('CLIP_MT_track_color_specials', text="", icon='DOWNARROW_HLT') + row.operator("clip.track_color_preset_add", text="", icon='ZOOMIN') + props = row.operator("clip.track_color_preset_add", + text="", icon='ZOOMOUT') + props.remove_active = True + + row = layout.row() + row.prop(act_track, "use_custom_color") + if act_track.use_custom_color: + row.prop(act_track, "color", text="") + + if act_track.has_bundle: + label_text = "Average Error: %.4f" % (act_track.average_error) + layout.label(text=label_text) + + +class CLIP_PT_tracking_camera(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Camera Data" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + sc = context.space_data + + return sc.mode in ['TRACKING', 'DISTORTION'] and sc.clip + + def draw(self, context): + layout = self.layout + + sc = context.space_data + clip = sc.clip + + row = layout.row(align=True) + label = bpy.types.CLIP_MT_camera_presets.bl_label + row.menu('CLIP_MT_camera_presets', text=label) + row.operator("clip.camera_preset_add", text="", icon='ZOOMIN') + props = row.operator("clip.camera_preset_add", text="", icon='ZOOMOUT') + props.remove_active = True + + row = layout.row(align=True) + sub = row.split(percentage=0.65) + if clip.tracking.camera.units == 'MILLIMETERS': + sub.prop(clip.tracking.camera, "focal_length") + else: + sub.prop(clip.tracking.camera, "focal_length_pixels") + sub.prop(clip.tracking.camera, "units", text="") + + col = layout.column(align=True) + col.label(text="Sensor:") + col.prop(clip.tracking.camera, "sensor_width", text="Width") + col.prop(clip.tracking.camera, "pixel_aspect") + + col = layout.column() + col.label(text="Principal Point") + row = col.row() + row.prop(clip.tracking.camera, "principal", text="") + col.operator("clip.set_center_principal", text="Center") + + col = layout.column(align=True) + col.label(text="Undistortion:") + col.prop(clip.tracking.camera, "k1") + col.prop(clip.tracking.camera, "k2") + col.prop(clip.tracking.camera, "k3") + + +class CLIP_PT_display(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Display" + + def draw(self, context): + layout = self.layout + sc = context.space_data + + col = layout.column(align=True) + + col.prop(sc, "show_marker_pattern", text="Pattern") + col.prop(sc, "show_marker_search", text="Search") + col.prop(sc, "show_pyramid_levels", text="Pyramid") + + col.prop(sc, "show_track_path", text="Track Path") + row = col.row() + row.active = sc.show_track_path + row.prop(sc, "path_length", text="Length") + + col.prop(sc, "show_disabled", "Disabled Tracks") + col.prop(sc, "show_bundles", text="Bundles") + + col.prop(sc, "show_names", text="Track Names") + col.prop(sc, "show_tiny_markers", text="Tiny Markers") + + col.prop(sc, "show_grease_pencil", text="Grease Pencil") + col.prop(sc, "use_mute_footage", text="Mute") + + if sc.mode == 'DISTORTION': + col.prop(sc, "show_grid", text="Grid") + col.prop(sc, "use_manual_calibration") + elif sc.mode == 'RECONSTRUCTION': + col.prop(sc, "show_stable", text="Stable") + + col.prop(sc, "lock_selection") + + clip = sc.clip + if clip: + col.label(text="Display Aspect:") + col.prop(clip, "display_aspect", text="") + + +class CLIP_PT_track_settings(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Tracking Settings" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + sc = context.space_data + + return sc.mode == 'TRACKING' and sc.clip + + def draw(self, context): + layout = self.layout + clip = context.space_data.clip + settings = clip.tracking.settings + + active = clip.tracking.tracks.active + if active: + layout.prop(active, "tracker") + if active.tracker == 'KLT': + layout.prop(active, "pyramid_levels") + elif active.tracker == 'SAD': + layout.prop(active, "correlation_min") + + layout.prop(settings, "frames_adjust") + layout.prop(settings, "speed") + layout.prop(settings, "frames_limit") + layout.prop(settings, "margin") + + +class CLIP_PT_stabilization(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "2D Stabilization" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + sc = context.space_data + + return sc.mode == 'RECONSTRUCTION' and sc.clip + + def draw_header(self, context): + sc = context.space_data + tracking = sc.clip.tracking + stab = tracking.stabilization + + self.layout.prop(stab, "use_2d_stabilization", text="") + + def draw(self, context): + layout = self.layout + sc = context.space_data + tracking = sc.clip.tracking + stab = tracking.stabilization + + layout.active = stab.use_2d_stabilization + + row = layout.row() + row.template_list(stab, "tracks", stab, "active_track_index", rows=3) + + sub = row.column(align=True) + + sub.operator("clip.stabilize_2d_add", icon='ZOOMIN', text="") + sub.operator("clip.stabilize_2d_remove", icon='ZOOMOUT', text="") + + sub.menu('CLIP_MT_stabilize_2d_specials', text="", + icon='DOWNARROW_HLT') + + layout.prop(stab, "influence_location") + + layout.separator() + + layout.prop(stab, "use_autoscale") + col = layout.column() + col.active = stab.use_autoscale + col.prop(stab, "scale_max") + col.prop(stab, "influence_scale") + + layout.separator() + + layout.label(text="Rotation:") + + row = layout.row(align=True) + row.prop_search(stab, "rotation_track", tracking, "tracks", text="") + row.operator("clip.stabilize_2d_set_rotation", text="", icon='ZOOMIN') + + row = layout.row() + row.active = stab.rotation_track is not None + row.prop(stab, "influence_rotation") + + +class CLIP_PT_marker(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Marker" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return sc.mode == 'TRACKING' and clip + + def draw(self, context): + layout = self.layout + sc = context.space_data + clip = context.space_data.clip + act_track = clip.tracking.tracks.active + + if act_track: + layout.template_marker(sc, "clip", sc.clip_user, act_track, False) + else: + layout.active = False + layout.label(text="No active track") + + +class CLIP_PT_proxy(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Proxy / Timecode" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + sc = context.space_data + + return sc.clip + + def draw_header(self, context): + sc = context.space_data + + self.layout.prop(sc.clip, "use_proxy", text="") + + def draw(self, context): + layout = self.layout + sc = context.space_data + clip = sc.clip + + layout.active = clip.use_proxy + + layout.label(text="Build Sizes:") + + row = layout.row() + row.prop(clip.proxy, "build_25") + row.prop(clip.proxy, "build_50") + + row = layout.row() + row.prop(clip.proxy, "build_75") + row.prop(clip.proxy, "build_100") + + layout.prop(clip.proxy, "build_undistorted") + + layout.prop(clip.proxy, "quality") + + layout.prop(clip, 'use_proxy_custom_directory') + if clip.use_proxy_custom_directory: + layout.prop(clip.proxy, "directory") + + layout.operator("clip.rebuild_proxy", text="Rebuild Proxy") + + if clip.source == 'MOVIE': + col = layout.column() + + col.label(text="Use timecode index:") + col.prop(clip.proxy, "timecode", text="") + + col = layout.column() + col.label(text="Proxy render size:") + + col.prop(sc.clip_user, "proxy_render_size", text="") + col.prop(sc.clip_user, "use_render_undistorted") + + +class CLIP_PT_footage(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Footage Settings" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + sc = context.space_data + + return sc.clip + + def draw(self, context): + layout = self.layout + + sc = context.space_data + clip = sc.clip + + if clip: + layout.template_movieclip(sc, "clip", compact=True) + else: + layout.operator("clip.open", icon='FILESEL') + + +class CLIP_PT_tools_clip(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Clip" + + @classmethod + def poll(cls, context): + sc = context.space_data + + return sc.clip + + def draw(self, context): + layout = self.layout + clip = context.space_data.clip + + layout.operator("clip.set_viewport_background") + + +class CLIP_MT_view(Menu): + bl_label = "View" + + def draw(self, context): + layout = self.layout + + layout.operator("clip.properties", icon='MENU_PANEL') + layout.operator("clip.tools", icon='MENU_PANEL') + layout.separator() + + layout.operator("clip.view_selected") + layout.operator("clip.view_all") + + layout.separator() + layout.operator("clip.view_zoom_in") + layout.operator("clip.view_zoom_out") + + layout.separator() + + ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1)) + + for a, b in ratios: + text = "Zoom %d:%d" % (a, b) + layout.operator("clip.view_zoom_ratio", text=text).ratio = a / b + + layout.separator() + layout.operator("screen.area_dupli") + layout.operator("screen.screen_full_area") + + +class CLIP_MT_clip(Menu): + bl_label = "Clip" + + def draw(self, context): + layout = self.layout + + sc = context.space_data + clip = sc.clip + + layout.operator("clip.open") + + if clip: + layout.operator("clip.reload") + layout.menu("CLIP_MT_proxy") + + +class CLIP_MT_proxy(Menu): + bl_label = "Proxy" + + def draw(self, context): + layout = self.layout + + sc = context.space_data + clip = sc.clip + + layout.operator("clip.rebuild_proxy") + layout.operator("clip.delete_proxy") + + +class CLIP_MT_track(Menu): + bl_label = "Track" + + def draw(self, context): + layout = self.layout + + layout.operator("clip.clear_solution") + layout.operator("clip.solve_camera") + + layout.separator() + props = layout.operator("clip.clear_track_path", text="Clear After") + props.action = 'REMAINED' + + props = layout.operator("clip.clear_track_path", text="Clear Before") + props.action = 'UPTO' + + props = layout.operator("clip.clear_track_path", text="Clear Track Path") + props.action = 'ALL' + + layout.separator() + layout.operator("clip.join_tracks") + + layout.separator() + layout.operator("clip.clean_tracks") + + layout.separator() + props = layout.operator("clip.track_markers", + text="Track Frame Backwards") + props.backwards = True + + props = layout.operator("clip.track_markers", text="Track Backwards") + props.backwards = True + props.sequence = True + + props = layout.operator("clip.track_markers", text="Track Forwards") + props.sequence = True + layout.operator("clip.track_markers", text="Track Frame Forwards") + + layout.separator() + layout.operator("clip.delete_track") + layout.operator("clip.delete_marker") + + layout.separator() + layout.operator("clip.add_marker_move") + + layout.separator() + layout.menu("CLIP_MT_track_visibility") + layout.menu("CLIP_MT_track_transform") + + +class CLIP_MT_reconstruction(Menu): + bl_label = "Reconstruction" + + def draw(self, context): + layout = self.layout + + layout.operator("clip.set_origin") + layout.operator("clip.set_floor") + + layout.operator("clip.set_axis", text="Set X Axis").axis = "X" + layout.operator("clip.set_axis", text="Set Y Axis").axis = "Y" + + layout.operator("clip.set_scale") + + layout.separator() + + layout.operator("clip.track_to_empty") + layout.operator("clip.bundles_to_mesh") + + +class CLIP_MT_track_visibility(Menu): + bl_label = "Show/Hide" + + def draw(self, context): + layout = self.layout + + layout.operator("clip.hide_tracks_clear", text="Show Hidden") + layout.operator("clip.hide_tracks", text="Hide Selected") + + props = layout.operator("clip.hide_tracks", text="Hide Unselected") + props.unselected = True + + +class CLIP_MT_track_transform(Menu): + bl_label = "Transform" + + def draw(self, context): + layout = self.layout + + layout.operator("transform.translate") + layout.operator("transform.resize") + + +class CLIP_MT_select(Menu): + bl_label = "Select" + + def draw(self, context): + layout = self.layout + + sc = context.space_data + + layout.operator("clip.select_border") + layout.operator("clip.select_circle") + + layout.separator() + + layout.operator("clip.select_all", text="Select/Deselect all") + layout.operator("clip.select_all", text="Inverse").action = 'INVERT' + + layout.menu("CLIP_MT_select_grouped") + + +class CLIP_MT_select_grouped(Menu): + bl_label = "Select Grouped" + + def draw(self, context): + layout = self.layout + + layout.operator_enum("clip.select_grouped", "group") + + +class CLIP_MT_tracking_specials(Menu): + bl_label = "Specials" + + @classmethod + def poll(cls, context): + return context.space_data.clip + + def draw(self, context): + layout = self.layout + + props = layout.operator("clip.disable_markers", text="Enable Markers") + props.action = 'ENABLE' + + props = layout.operator("clip.disable_markers", text="Disable markers") + props.action = 'DISABLE' + + layout.separator() + layout.operator("clip.set_origin") + + layout.separator() + layout.operator("clip.hide_tracks") + layout.operator("clip.hide_tracks_clear", text="Show Tracks") + + layout.separator() + props = layout.operator("clip.lock_tracks", text="Lock Tracks") + props.action = 'LOCK' + + props = layout.operator("clip.lock_tracks", text="Unlock Tracks") + props.action = 'UNLOCK' + + +class CLIP_MT_camera_presets(Menu): + bl_label = "Camera Presets" + preset_subdir = "tracking_camera" + preset_operator = "script.execute_preset" + draw = bpy.types.Menu.draw_preset + + +class CLIP_MT_track_color_presets(Menu): + bl_label = "Color Presets" + preset_subdir = "tracking_track_color" + preset_operator = "script.execute_preset" + draw = bpy.types.Menu.draw_preset + + +class CLIP_MT_track_color_specials(Menu): + bl_label = "Track Color Specials" + + def draw(self, context): + layout = self.layout + + layout.operator('clip.track_copy_color', icon='COPY_ID') + + +class CLIP_MT_stabilize_2d_specials(Menu): + bl_label = "Track Color Specials" + + def draw(self, context): + layout = self.layout + + layout.operator('clip.stabilize_2d_select') + +if __name__ == "__main__": # only for live edit. + bpy.utils.register_module(__name__) |