diff options
author | Campbell Barton <ideasman42@gmail.com> | 2015-02-12 18:17:23 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2015-02-12 18:22:39 +0300 |
commit | 912b4659eca636231d99d7b3611a38791b8270e7 (patch) | |
tree | 28bf2d2757e1bb3d559678558f21b534718282de /release/scripts/startup | |
parent | 719fd5a1ce4683a8ceb402d1138bb7d3b55afea2 (diff) |
Tracker operators: filter & copy track settings
D1069 by @sebastian_k
Diffstat (limited to 'release/scripts/startup')
-rw-r--r-- | release/scripts/startup/bl_operators/clip.py | 150 |
1 files changed, 149 insertions, 1 deletions
diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index 4ce300ecce2..99819166adc 100644 --- a/release/scripts/startup/bl_operators/clip.py +++ b/release/scripts/startup/bl_operators/clip.py @@ -20,7 +20,7 @@ import bpy import os from bpy.types import Operator - +from bpy.props import FloatProperty from mathutils import Vector, Matrix @@ -124,6 +124,99 @@ def CLIP_default_settings_from_track(clip, track, framenr): settings.default_weight = track.weight +class CLIP_OT_filter_tracks(bpy.types.Operator): + bl_label = "Filter Tracks" + bl_idname = "clip.filter_tracks" + bl_options = {'UNDO', 'REGISTER'} + + track_threshold = FloatProperty( + name="Track Threshold", + description="Filter Threshold to select problematic track", + default=5.0, + ) + + @staticmethod + def _filter_values(context, threshold): + + def get_marker_coordinates_in_pixels(clip_size, track, frame_number): + marker = track.markers.find_frame(frame_number) + return Vector((marker.co[0] * clip_size[0], marker.co[1] * clip_size[1])) + + def marker_velocity(clip_size, track, frame): + marker_a = get_marker_coordinates_in_pixels(clip_size, track, frame) + marker_b = get_marker_coordinates_in_pixels(clip_size, track, frame - 1) + return marker_a - marker_b + + scene = context.scene + frame_start = scene.frame_start + frame_end = scene.frame_end + clip = context.space_data.clip + clip_size = clip.size[:] + + bpy.ops.clip.clean_tracks(frames=10, action='DELETE_TRACK') + + tracks_to_clean = set() + + for frame in range(frame_start, frame_end + 1): + + # Find tracks with markers in both this frame and the previous one. + relevant_tracks = [ + track for track in clip.tracking.tracks + if track.markers.find_frame(frame) and + track.markers.find_frame(frame - 1)] + + if not relevant_tracks: + continue + + # Get average velocity and deselect track. + average_velocity = Vector((0.0, 0.0)) + for track in relevant_tracks: + track.select = False + average_velocity += marker_velocity(clip_size, track, frame) + if len(relevant_tracks) >= 1: + average_velocity = average_velocity / len(relevant_tracks) + + # Then find all markers that behave differently than the average. + for track in relevant_tracks: + track_velocity = marker_velocity(clip_size, track, frame) + distance = (average_velocity - track_velocity).length + + if distance > threshold: + tracks_to_clean.add(track) + + for track in tracks_to_clean: + track.select = True + return len(tracks_to_clean) + + @classmethod + def poll(cls, context): + space = context.space_data + return (space.type == 'CLIP_EDITOR') and space.clip + + def execute(self, context): + num_tracks = self._filter_values(context, self.track_threshold) + self.report({'INFO'}, "Identified %d problematic tracks" % num_tracks) + return {'FINISHED'} + + +class CLIP_OT_set_active_clip(bpy.types.Operator): + bl_label = "Set Active Clip" + bl_idname = "clip.set_active_clip" + + @classmethod + def poll(cls, context): + space = context.space_data + return space.type == 'CLIP_EDITOR' + + def execute(self, context): + clip = context.space_data.clip + scene = context.scene + scene.active_clip = clip + scene.render.resolution_x = clip.size[0] + scene.render.resolution_y = clip.size[1] + return {'FINISHED'} + + class CLIP_OT_track_to_empty(Operator): """Create an Empty object which will be copying movement of active track""" @@ -920,3 +1013,58 @@ class CLIP_OT_track_settings_as_default(Operator): CLIP_default_settings_from_track(clip, track, framenr) return {'FINISHED'} + + +class CLIP_OT_track_settings_to_track(bpy.types.Operator): + """Copy tracking settings from active track to selected tracks""" + + bl_label = "Copy Track Settings" + bl_idname = "clip.track_settings_to_track" + bl_options = {'UNDO', 'REGISTER'} + + _attrs_track = ( + "correlation_min", + "frames_limit", + "pattern_match", + "margin", + "motion_model", + "use_brute", + "use_normalization", + "use_mask", + "use_red_channel", + "use_green_channel", + "use_blue_channel", + "weight" + ) + + _attrs_marker = ( + "pattern_corners", + "search_min", + "search_max", + ) + + @classmethod + def poll(cls, context): + space = context.space_data + if space.type != 'CLIP_EDITOR': + return False + clip = space.clip + return clip and clip.tracking.tracks.active + + def execute(self, context): + space = context.space_data + clip = space.clip + track = clip.tracking.tracks.active + + framenr = context.scene.frame_current - clip.frame_start + 1 + marker = track.markers.find_frame(framenr, False) + + for t in clip.tracking.tracks: + if t.select and t != track: + marker_selected = t.markers.find_frame(framenr, False) + for attr in self._attrs_track: + setattr(t, attr, getattr(track, attr)) + for attr in self._attrs_marker: + setattr(marker_selected, attr, getattr(marker, attr)) + + return {'FINISHED'} |