1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
22 from bpy.types import Panel, Header, Menu
25 class CLIP_HT_header(Header):
26 bl_space_type = 'CLIP_EDITOR'
28 def _draw_tracking(self, context):
31 sc = context.space_data
34 row = layout.row(align=True)
37 if context.area.show_menus:
38 sub = row.row(align=True)
39 sub.menu("CLIP_MT_view")
43 sub.menu("CLIP_MT_select")
44 sub.menu("CLIP_MT_clip")
45 sub.menu("CLIP_MT_track")
46 sub.menu("CLIP_MT_reconstruction")
48 sub.menu("CLIP_MT_clip")
51 row.template_ID(sc, "clip", open="clip.open")
54 tracking = clip.tracking
55 active_object = tracking.objects.active
58 layout.prop(sc, "mode", text="")
59 layout.prop(sc, "view", text="", expand=True)
60 layout.prop(sc, "pivot_point", text="", icon_only=True)
62 r = active_object.reconstruction
64 if r.is_valid and sc.view == 'CLIP':
65 layout.label(text="Solve error: %.4f" %
67 elif sc.view == 'GRAPH':
68 layout.prop(sc, "view", text="", expand=True)
70 row = layout.row(align=True)
71 row.prop(sc, "show_graph_only_selected", text="")
72 row.prop(sc, "show_graph_hidden", text="")
74 row = layout.row(align=True)
77 row.prop(sc, "show_filters", icon='DISCLOSURE_TRI_DOWN',
81 sub.active = clip.tracking.reconstruction.is_valid
82 sub.prop(sc, "show_graph_frames", icon='SEQUENCE', text="")
84 row.prop(sc, "show_graph_tracks", icon='ANIM', text="")
86 row.prop(sc, "show_filters", icon='DISCLOSURE_TRI_RIGHT',
88 elif sc.view == 'DOPESHEET':
89 dopesheet = tracking.dopesheet
90 layout.prop(sc, "view", text="", expand=True)
92 row = layout.row(align=True)
93 row.prop(dopesheet, "show_only_selected", text="")
94 row.prop(dopesheet, "show_hidden", text="")
96 row = layout.row(align=True)
97 row.prop(dopesheet, "sort_method", text="")
98 row.prop(dopesheet, "use_invert_sort",
99 text="Invert", toggle=True)
101 layout.prop(sc, "view", text="", expand=True)
103 def _draw_masking(self, context):
106 toolsettings = context.tool_settings
107 sc = context.space_data
110 row = layout.row(align=True)
111 row.template_header()
113 if context.area.show_menus:
114 sub = row.row(align=True)
115 sub.menu("CLIP_MT_view")
118 sub.menu("CLIP_MT_select")
119 sub.menu("CLIP_MT_clip")
120 sub.menu("CLIP_MT_mask")
122 sub.menu("CLIP_MT_clip")
125 row.template_ID(sc, "clip", open="clip.open")
127 layout.prop(sc, "mode", text="")
130 row.template_ID(sc, "mask", new="mask.new")
132 layout.prop(sc, "pivot_point", text="", icon_only=True)
134 row = layout.row(align=True)
135 row.prop(toolsettings, "use_proportional_edit_mask",
136 text="", icon_only=True)
137 if toolsettings.use_proportional_edit_mask:
138 row.prop(toolsettings, "proportional_edit_falloff",
139 text="", icon_only=True)
141 def draw(self, context):
144 sc = context.space_data
146 if sc.mode in {'TRACKING', 'RECONSTRUCTION', 'DISTORTION'}:
147 self._draw_tracking(context)
149 self._draw_masking(context)
151 layout.template_running_jobs()
154 class CLIP_PT_clip_view_panel:
157 def poll(cls, context):
158 sc = context.space_data
161 return clip and sc.view == 'CLIP'
164 class CLIP_PT_mask_view_panel:
167 def poll(cls, context):
168 sc = context.space_data
171 return clip and sc.view == 'CLIP' and sc.mode == 'MASKEDIT'
174 class CLIP_PT_tracking_panel:
177 def poll(cls, context):
178 sc = context.space_data
181 return clip and sc.mode == 'TRACKING' and sc.view == 'CLIP'
184 class CLIP_PT_reconstruction_panel:
187 def poll(cls, context):
188 sc = context.space_data
191 return clip and sc.mode == 'RECONSTRUCTION' and sc.view == 'CLIP'
194 class CLIP_PT_tools_marker(CLIP_PT_tracking_panel, Panel):
195 bl_space_type = 'CLIP_EDITOR'
196 bl_region_type = 'TOOLS'
199 def draw(self, context):
200 sc = context.space_data
202 settings = clip.tracking.settings
205 col = layout.column(align=True)
206 col.operator("clip.add_marker_move")
207 col.operator("clip.detect_features")
208 col.operator("clip.delete_track")
211 row = box.row(align=True)
212 row.prop(settings, "show_default_expanded", text="", emboss=False)
213 row.label(text="Tracking Settings")
215 if settings.show_default_expanded:
217 row = col.row(align=True)
218 label = CLIP_MT_tracking_settings_presets.bl_label
219 row.menu('CLIP_MT_tracking_settings_presets', text=label)
220 row.operator("clip.tracking_settings_preset_add",
221 text="", icon='ZOOMIN')
222 props = row.operator("clip.tracking_settings_preset_add",
223 text="", icon='ZOOMOUT')
224 props.remove_active = True
228 row = col.row(align=True)
229 row.prop(settings, "use_default_red_channel",
230 text="R", toggle=True)
231 row.prop(settings, "use_default_green_channel",
232 text="G", toggle=True)
233 row.prop(settings, "use_default_blue_channel",
234 text="B", toggle=True)
238 sub = col.column(align=True)
239 sub.prop(settings, "default_pattern_size")
240 sub.prop(settings, "default_search_size")
242 col.label(text="Tracker:")
243 col.prop(settings, "default_motion_model")
244 col.prop(settings, "default_use_brute")
245 col.prop(settings, "default_use_normalization")
246 col.prop(settings, "default_use_mask")
247 col.prop(settings, "default_correlation_min")
251 sub = col.column(align=True)
252 sub.prop(settings, "default_frames_limit")
253 sub.prop(settings, "default_margin")
255 col.label(text="Match:")
256 col.prop(settings, "default_pattern_match", text="")
259 col.operator("clip.track_settings_as_default",
260 text="Copy From Active Track")
263 class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel):
264 bl_space_type = 'CLIP_EDITOR'
265 bl_region_type = 'TOOLS'
268 def draw(self, context):
271 row = layout.row(align=True)
273 props = row.operator("clip.track_markers", text="", icon='FRAME_PREV')
274 props.backwards = True
275 props.sequence = False
276 props = row.operator("clip.track_markers", text="",
278 props.backwards = True
279 props.sequence = True
280 props = row.operator("clip.track_markers", text="", icon='PLAY')
281 props.backwards = False
282 props.sequence = True
283 props = row.operator("clip.track_markers", text="", icon='FRAME_NEXT')
284 props.backwards = False
285 props.sequence = False
287 col = layout.column(align=True)
288 props = col.operator("clip.clear_track_path", text="Clear After")
289 props.action = 'REMAINED'
291 props = col.operator("clip.clear_track_path", text="Clear Before")
292 props.action = 'UPTO'
293 col.operator("clip.clear_track_path", text="Clear").action = 'ALL'
295 layout.operator("clip.join_tracks", text="Join")
298 class CLIP_PT_tools_solve(CLIP_PT_tracking_panel, Panel):
299 bl_space_type = 'CLIP_EDITOR'
300 bl_region_type = 'TOOLS'
303 def draw(self, context):
305 clip = context.space_data.clip
306 tracking = clip.tracking
307 settings = tracking.settings
308 tracking_object = tracking.objects.active
310 col = layout.column(align=True)
312 col.operator("clip.solve_camera",
313 text="Camera Motion" if tracking_object.is_camera
314 else "Object Motion")
315 col.operator("clip.clear_solution")
317 col = layout.column()
318 col.prop(settings, "use_tripod_solver")
320 col = layout.column(align=True)
321 col.active = not settings.use_tripod_solver
322 col.prop(settings, "keyframe_a")
323 col.prop(settings, "keyframe_b")
325 col = layout.column(align=True)
326 col.active = (tracking_object.is_camera and
327 not settings.use_tripod_solver)
328 col.label(text="Refine:")
329 col.prop(settings, "refine_intrinsics", text="")
332 class CLIP_PT_tools_cleanup(CLIP_PT_tracking_panel, Panel):
333 bl_space_type = 'CLIP_EDITOR'
334 bl_region_type = 'TOOLS'
335 bl_label = "Clean up"
337 def draw(self, context):
339 clip = context.space_data.clip
340 settings = clip.tracking.settings
342 layout.operator("clip.clean_tracks")
344 layout.prop(settings, "clean_frames", text="Frames")
345 layout.prop(settings, "clean_error", text="Error")
346 layout.prop(settings, "clean_action", text="")
349 class CLIP_PT_tools_geometry(CLIP_PT_reconstruction_panel, Panel):
350 bl_space_type = 'CLIP_EDITOR'
351 bl_region_type = 'TOOLS'
352 bl_label = "Geometry"
354 def draw(self, context):
357 layout.operator("clip.bundles_to_mesh")
358 layout.operator("clip.track_to_empty")
361 class CLIP_PT_tools_orientation(CLIP_PT_reconstruction_panel, Panel):
362 bl_space_type = 'CLIP_EDITOR'
363 bl_region_type = 'TOOLS'
364 bl_label = "Orientation"
366 def draw(self, context):
367 sc = context.space_data
369 settings = sc.clip.tracking.settings
371 col = layout.column(align=True)
373 props = row.operator("clip.set_plane", text="Floor")
374 props.plane = 'FLOOR'
375 props = row.operator("clip.set_plane", text="Wall")
377 col.operator("clip.set_origin")
380 row.operator("clip.set_axis", text="Set X Axis").axis = 'X'
381 row.operator("clip.set_axis", text="Set Y Axis").axis = 'Y'
385 col = layout.column()
386 col.operator("clip.set_scale")
387 col.prop(settings, "distance")
390 class CLIP_PT_tools_object(CLIP_PT_reconstruction_panel, Panel):
391 bl_space_type = 'CLIP_EDITOR'
392 bl_region_type = 'TOOLS'
396 def poll(cls, context):
397 if CLIP_PT_reconstruction_panel.poll(context):
398 sc = context.space_data
401 tracking_object = clip.tracking.objects.active
403 return not tracking_object.is_camera
407 def draw(self, context):
410 sc = context.space_data
412 tracking_object = clip.tracking.objects.active
413 settings = sc.clip.tracking.settings
415 col = layout.column()
417 col.prop(tracking_object, "scale")
421 col.operator("clip.set_solution_scale", text="Set Scale")
422 col.prop(settings, "object_distance")
425 class CLIP_PT_tools_mask(CLIP_PT_mask_view_panel, Panel):
426 bl_space_type = 'CLIP_EDITOR'
427 bl_region_type = 'TOOLS'
428 bl_label = "Mask Tools"
430 def draw(self, context):
433 col = layout.column(align=True)
434 col.label(text="Transform:")
435 col.operator("transform.translate")
436 col.operator("transform.rotate")
437 col.operator("transform.resize", text="Scale")
438 props = col.operator("transform.transform", text="Shrink/Fatten")
439 props.mode = 'MASK_SHRINKFATTEN'
441 col = layout.column(align=True)
442 col.label(text="Spline:")
443 col.operator("mask.delete")
444 col.operator("mask.cyclic_toggle")
445 col.operator("mask.switch_direction")
447 col = layout.column(align=True)
448 col.label(text="Parenting:")
449 col.operator("mask.parent_set")
450 col.operator("mask.parent_clear")
453 class CLIP_PT_tools_grease_pencil(Panel):
454 bl_space_type = 'CLIP_EDITOR'
455 bl_region_type = 'TOOLS'
456 bl_label = "Grease Pencil"
459 def poll(cls, context):
460 sc = context.space_data
466 if sc.mode == 'DISTORTION':
467 return sc.view == 'CLIP'
468 elif sc.mode == 'MASKEDIT':
473 def draw(self, context):
476 col = layout.column(align=True)
478 row = col.row(align=True)
479 row.operator("gpencil.draw", text="Draw").mode = 'DRAW'
480 row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT'
482 row = col.row(align=True)
483 row.operator("gpencil.draw", text="Poly").mode = 'DRAW_POLY'
484 row.operator("gpencil.draw", text="Erase").mode = 'ERASER'
487 row.prop(context.tool_settings, "use_grease_pencil_sessions")
490 class CLIP_PT_objects(CLIP_PT_clip_view_panel, Panel):
491 bl_space_type = 'CLIP_EDITOR'
492 bl_region_type = 'UI'
494 bl_options = {'DEFAULT_CLOSED'}
496 def draw(self, context):
499 sc = context.space_data
500 tracking = sc.clip.tracking
503 row.template_list(tracking, "objects",
504 tracking, "active_object_index", rows=3)
506 sub = row.column(align=True)
508 sub.operator("clip.tracking_object_new", icon='ZOOMIN', text="")
509 sub.operator("clip.tracking_object_remove", icon='ZOOMOUT', text="")
511 active = tracking.objects.active
513 layout.prop(active, "name")
516 class CLIP_PT_track(CLIP_PT_tracking_panel, Panel):
517 bl_space_type = 'CLIP_EDITOR'
518 bl_region_type = 'UI'
521 def draw(self, context):
523 sc = context.space_data
524 clip = context.space_data.clip
525 act_track = clip.tracking.tracks.active
528 layout.active = False
529 layout.label(text="No active track")
533 row.prop(act_track, "name", text="")
535 sub = row.row(align=True)
537 sub.template_marker(sc, "clip", sc.clip_user, act_track, True)
539 icon = 'LOCKED' if act_track.lock else 'UNLOCKED'
540 sub.prop(act_track, "lock", text="", icon=icon)
542 layout.template_track(sc, "scopes")
544 row = layout.row(align=True)
546 sub.prop(act_track, "use_red_channel", text="R", toggle=True)
547 sub.prop(act_track, "use_green_channel", text="G", toggle=True)
548 sub.prop(act_track, "use_blue_channel", text="B", toggle=True)
553 sub.prop(act_track, "use_grayscale_preview", text="B/W", toggle=True)
557 sub.prop(act_track, "use_alpha_preview",
558 text="", toggle=True, icon='IMAGE_ALPHA')
562 row = layout.row(align=True)
563 label = bpy.types.CLIP_MT_track_color_presets.bl_label
564 row.menu('CLIP_MT_track_color_presets', text=label)
565 row.menu('CLIP_MT_track_color_specials', text="", icon='DOWNARROW_HLT')
566 row.operator("clip.track_color_preset_add", text="", icon='ZOOMIN')
567 props = row.operator("clip.track_color_preset_add",
568 text="", icon='ZOOMOUT')
569 props.remove_active = True
572 row.prop(act_track, "use_custom_color")
573 if act_track.use_custom_color:
574 row.prop(act_track, "color", text="")
576 if act_track.has_bundle:
577 label_text = "Average Error: %.4f" % (act_track.average_error)
578 layout.label(text=label_text)
581 class CLIP_PT_track_settings(CLIP_PT_tracking_panel, Panel):
582 bl_space_type = 'CLIP_EDITOR'
583 bl_region_type = 'UI'
584 bl_label = "Tracking Settings"
585 bl_options = {'DEFAULT_CLOSED'}
587 def draw(self, context):
589 clip = context.space_data.clip
590 settings = clip.tracking.settings
592 col = layout.column()
594 active = clip.tracking.tracks.active
596 col.prop(active, "motion_model")
597 col.prop(active, "use_brute")
598 col.prop(active, "use_normalization")
599 col.prop(active, "use_mask")
600 col.prop(active, "correlation_min")
603 col.prop(active, "frames_limit")
604 col.prop(active, "margin")
605 col.prop(active, "pattern_match", text="Match")
607 col.prop(settings, "speed")
610 class CLIP_PT_tracking_camera(Panel):
611 bl_space_type = 'CLIP_EDITOR'
612 bl_region_type = 'UI'
613 bl_label = "Camera Data"
614 bl_options = {'DEFAULT_CLOSED'}
617 def poll(cls, context):
618 if CLIP_PT_clip_view_panel.poll(context):
619 sc = context.space_data
621 return sc.mode in {'TRACKING', 'DISTORTION'} and sc.clip
625 def draw(self, context):
628 sc = context.space_data
631 row = layout.row(align=True)
632 label = bpy.types.CLIP_MT_camera_presets.bl_label
633 row.menu('CLIP_MT_camera_presets', text=label)
634 row.operator("clip.camera_preset_add", text="", icon='ZOOMIN')
635 props = row.operator("clip.camera_preset_add", text="", icon='ZOOMOUT')
636 props.remove_active = True
638 row = layout.row(align=True)
639 sub = row.split(percentage=0.65)
640 if clip.tracking.camera.units == 'MILLIMETERS':
641 sub.prop(clip.tracking.camera, "focal_length")
643 sub.prop(clip.tracking.camera, "focal_length_pixels")
644 sub.prop(clip.tracking.camera, "units", text="")
646 col = layout.column(align=True)
647 col.label(text="Sensor:")
648 col.prop(clip.tracking.camera, "sensor_width", text="Width")
649 col.prop(clip.tracking.camera, "pixel_aspect")
651 col = layout.column()
652 col.label(text="Optical Center:")
654 row.prop(clip.tracking.camera, "principal", text="")
655 col.operator("clip.set_center_principal", text="Center")
657 col = layout.column(align=True)
658 col.label(text="Lens Distortion:")
659 col.prop(clip.tracking.camera, "k1")
660 col.prop(clip.tracking.camera, "k2")
661 col.prop(clip.tracking.camera, "k3")
664 class CLIP_PT_mask_layers(Panel):
665 bl_space_type = 'CLIP_EDITOR'
666 bl_region_type = 'UI'
667 bl_label = "Mask Layers"
670 def poll(cls, context):
671 sc = context.space_data
673 return sc.mask and sc.mode == 'MASKEDIT'
675 def draw(self, context):
678 sc = context.space_data
680 active_layer = mask.layers.active
682 rows = 5 if active_layer else 2
685 row.template_list(mask, "layers",
686 mask, "active_layer_index", rows=rows)
688 sub = row.column(align=True)
690 sub.operator("mask.layer_new", icon='ZOOMIN', text="")
691 sub.operator("mask.layer_remove", icon='ZOOMOUT', text="")
696 props = sub.operator("mask.layer_move", icon='TRIA_UP', text="")
697 props.direction = 'UP'
699 props = sub.operator("mask.layer_move", icon='TRIA_DOWN', text="")
700 props.direction = 'DOWN'
702 layout.prop(active_layer, "name")
705 row = layout.row(align=True)
706 row.prop(active_layer, "alpha")
707 row.prop(active_layer, "invert", text="", icon='IMAGE_ALPHA')
709 layout.prop(active_layer, "blend")
710 layout.prop(active_layer, "falloff")
713 class CLIP_PT_active_mask_spline(Panel):
714 bl_space_type = 'CLIP_EDITOR'
715 bl_region_type = 'UI'
716 bl_label = "Active Spline"
719 def poll(cls, context):
720 sc = context.space_data
723 if mask and sc.mode == 'MASKEDIT':
724 return mask.layers.active and mask.layers.active.splines.active
728 def draw(self, context):
731 sc = context.space_data
733 spline = mask.layers.active.splines.active
735 col = layout.column()
736 col.prop(spline, "weight_interpolation")
738 rowsub.prop(spline, "use_cyclic")
739 rowsub.prop(spline, "use_fill")
742 class CLIP_PT_active_mask_point(Panel):
743 bl_space_type = 'CLIP_EDITOR'
744 bl_region_type = 'UI'
745 bl_label = "Active Point"
748 def poll(cls, context):
749 sc = context.space_data
752 if mask and sc.mode == 'MASKEDIT':
753 mask_layer_active = mask.layers.active
754 return (mask_layer_active and
755 mask_layer_active.splines.active_point)
759 def draw(self, context):
762 sc = context.space_data
764 point = mask.layers.active.splines.active_point
765 parent = point.parent
767 col = layout.column()
768 col.prop(point, "handle_type")
770 col = layout.column()
771 # Currently only parenting yo movie clip is allowed, so do not
772 # ver-oplicate things for now and use single template_ID
773 #col.template_any_ID(parent, "id", "id_type", text="")
776 col.prop(parent, "id", text="")
778 if parent.id_type == 'MOVIECLIP' and parent.id:
780 tracking = clip.tracking
782 col.prop_search(parent, "parent", tracking,
783 "objects", icon='OBJECT_DATA', text="Object:")
785 if parent.parent in tracking.objects:
786 object = tracking.objects[parent.parent]
787 col.prop_search(parent, "sub_parent", object,
788 "tracks", icon='ANIM_DATA', text="Track:")
790 col.prop_search(parent, "sub_parent", tracking,
791 "tracks", icon='ANIM_DATA', text="Track:")
794 class CLIP_PT_display(CLIP_PT_clip_view_panel, Panel):
795 bl_space_type = 'CLIP_EDITOR'
796 bl_region_type = 'UI'
799 def draw(self, context):
801 sc = context.space_data
803 row = layout.row(align=True)
805 sub.prop(sc, "show_red_channel", text="R", toggle=True)
806 sub.prop(sc, "show_green_channel", text="G", toggle=True)
807 sub.prop(sc, "show_blue_channel", text="B", toggle=True)
812 sub.prop(sc, "use_grayscale_preview", text="B/W", toggle=True)
814 col = layout.column(align=True)
816 col.prop(sc, "show_disabled", "Disabled Tracks")
817 col.prop(sc, "show_names", text="Names and Status")
818 col.prop(sc, "show_bundles", text="3D Markers")
820 col.prop(sc, "use_mute_footage", text="Mute Footage")
821 col.prop(sc, "lock_selection")
823 if sc.view == 'GRAPH':
824 col.prop(sc, "lock_time_cursor")
826 if sc.mode == 'DISTORTION':
827 col.prop(sc, "show_grid", text="Grid")
828 col.prop(sc, "use_manual_calibration")
829 elif sc.mode == 'RECONSTRUCTION':
830 col.prop(sc, "show_stable", text="Stable")
834 col.label(text="Display Aspect Ratio:")
836 row.prop(clip, "display_aspect", text="")
838 if sc.mode == 'MASKEDIT':
839 col = layout.column()
840 col.prop(sc, "mask_draw_type", text="")
841 col.prop(sc, "show_mask_smooth")
844 # TODO, move into its own file
845 class CLIP_PT_mask(CLIP_PT_mask_view_panel, Panel):
846 bl_space_type = 'CLIP_EDITOR'
847 bl_region_type = 'UI'
848 bl_label = "Mask Settings"
849 bl_options = {'DEFAULT_CLOSED'}
851 def draw(self, context):
854 sc = context.space_data
857 col = layout.column(align=True)
858 col.prop(mask, "frame_start")
859 col.prop(mask, "frame_end")
862 class CLIP_PT_marker_display(CLIP_PT_clip_view_panel, Panel):
863 bl_space_type = 'CLIP_EDITOR'
864 bl_region_type = 'UI'
865 bl_label = "Marker Display"
868 def poll(cls, context):
869 sc = context.space_data
871 return sc.mode != 'MASKEDIT'
873 def draw(self, context):
875 sc = context.space_data
877 col = layout.column(align=True)
880 row.prop(sc, "show_marker_pattern", text="Pattern")
881 row.prop(sc, "show_marker_search", text="Search")
883 col.prop(sc, "show_tiny_markers", text="Thin Markers")
884 col.prop(sc, "show_track_path", text="Path")
887 row.active = sc.show_track_path
888 row.prop(sc, "path_length", text="Length")
891 class CLIP_PT_stabilization(CLIP_PT_reconstruction_panel, Panel):
892 bl_space_type = 'CLIP_EDITOR'
893 bl_region_type = 'UI'
894 bl_label = "2D Stabilization"
895 bl_options = {'DEFAULT_CLOSED'}
897 def draw_header(self, context):
898 stab = context.space_data.clip.tracking.stabilization
900 self.layout.prop(stab, "use_2d_stabilization", text="")
902 def draw(self, context):
905 tracking = context.space_data.clip.tracking
906 stab = tracking.stabilization
908 layout.active = stab.use_2d_stabilization
911 row.template_list(stab, "tracks", stab, "active_track_index", rows=3)
913 sub = row.column(align=True)
915 sub.operator("clip.stabilize_2d_add", icon='ZOOMIN', text="")
916 sub.operator("clip.stabilize_2d_remove", icon='ZOOMOUT', text="")
918 sub.menu('CLIP_MT_stabilize_2d_specials', text="",
919 icon='DOWNARROW_HLT')
921 layout.prop(stab, "influence_location")
923 layout.prop(stab, "use_autoscale")
924 col = layout.column()
925 col.active = stab.use_autoscale
926 col.prop(stab, "scale_max")
927 col.prop(stab, "influence_scale")
929 layout.prop(stab, "use_stabilize_rotation")
930 col = layout.column()
931 col.active = stab.use_stabilize_rotation
933 row = col.row(align=True)
934 row.prop_search(stab, "rotation_track", tracking, "tracks", text="")
935 row.operator("clip.stabilize_2d_set_rotation", text="", icon='ZOOMIN')
938 row.active = stab.rotation_track is not None
939 row.prop(stab, "influence_rotation")
941 layout.prop(stab, "filter_type")
944 class CLIP_PT_marker(CLIP_PT_tracking_panel, Panel):
945 bl_space_type = 'CLIP_EDITOR'
946 bl_region_type = 'UI'
948 bl_options = {'DEFAULT_CLOSED'}
950 def draw(self, context):
952 sc = context.space_data
953 clip = context.space_data.clip
954 act_track = clip.tracking.tracks.active
957 layout.template_marker(sc, "clip", sc.clip_user, act_track, False)
959 layout.active = False
960 layout.label(text="No active track")
963 class CLIP_PT_proxy(CLIP_PT_clip_view_panel, Panel):
964 bl_space_type = 'CLIP_EDITOR'
965 bl_region_type = 'UI'
966 bl_label = "Proxy / Timecode"
967 bl_options = {'DEFAULT_CLOSED'}
969 def draw_header(self, context):
970 sc = context.space_data
972 self.layout.prop(sc.clip, "use_proxy", text="")
974 def draw(self, context):
976 sc = context.space_data
979 layout.active = clip.use_proxy
981 layout.label(text="Build Original:")
983 row = layout.row(align=True)
984 row.prop(clip.proxy, "build_25", toggle=True)
985 row.prop(clip.proxy, "build_50", toggle=True)
986 row.prop(clip.proxy, "build_75", toggle=True)
987 row.prop(clip.proxy, "build_100", toggle=True)
989 layout.label(text="Build Undistorted:")
991 row = layout.row(align=True)
992 row.prop(clip.proxy, "build_undistorted_25", toggle=True)
993 row.prop(clip.proxy, "build_undistorted_50", toggle=True)
994 row.prop(clip.proxy, "build_undistorted_75", toggle=True)
995 row.prop(clip.proxy, "build_undistorted_100", toggle=True)
997 layout.prop(clip.proxy, "quality")
999 layout.prop(clip, "use_proxy_custom_directory")
1000 if clip.use_proxy_custom_directory:
1001 layout.prop(clip.proxy, "directory")
1003 layout.operator("clip.rebuild_proxy", text="Build Proxy")
1005 if clip.source == 'MOVIE':
1006 col = layout.column()
1008 col.label(text="Use timecode index:")
1009 col.prop(clip.proxy, "timecode", text="")
1011 col = layout.column()
1012 col.label(text="Proxy render size:")
1014 col.prop(sc.clip_user, "proxy_render_size", text="")
1015 col.prop(sc.clip_user, "use_render_undistorted")
1018 class CLIP_PT_footage(CLIP_PT_clip_view_panel, Panel):
1019 bl_space_type = 'CLIP_EDITOR'
1020 bl_region_type = 'UI'
1021 bl_label = "Footage Settings"
1022 bl_options = {'DEFAULT_CLOSED'}
1024 def draw(self, context):
1025 layout = self.layout
1027 sc = context.space_data
1030 col = layout.column()
1031 col.template_movieclip(sc, "clip", compact=True)
1032 col.prop(clip, "start_frame")
1033 col.prop(clip, "frame_offset")
1036 class CLIP_PT_tools_clip(CLIP_PT_clip_view_panel, Panel):
1037 bl_space_type = 'CLIP_EDITOR'
1038 bl_region_type = 'TOOLS'
1041 def draw(self, context):
1042 layout = self.layout
1044 layout.operator("clip.set_viewport_background")
1045 layout.operator("clip.setup_tracking_scene")
1048 class CLIP_MT_view(Menu):
1051 def draw(self, context):
1052 layout = self.layout
1053 sc = context.space_data
1055 if sc.view == 'CLIP':
1056 layout.operator("clip.properties", icon='MENU_PANEL')
1057 layout.operator("clip.tools", icon='MENU_PANEL')
1060 layout.operator("clip.view_selected")
1061 layout.operator("clip.view_all")
1064 layout.operator("clip.view_zoom_in")
1065 layout.operator("clip.view_zoom_out")
1069 ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1))
1072 text = "Zoom %d:%d" % (a, b)
1073 layout.operator("clip.view_zoom_ratio",
1074 text=text).ratio = a / b
1076 layout.prop(sc, "show_seconds")
1080 layout.operator("screen.area_dupli")
1081 layout.operator("screen.screen_full_area")
1084 class CLIP_MT_clip(Menu):
1087 def draw(self, context):
1088 layout = self.layout
1090 sc = context.space_data
1093 layout.operator("clip.open")
1096 layout.operator("clip.reload")
1097 layout.menu("CLIP_MT_proxy")
1100 class CLIP_MT_proxy(Menu):
1103 def draw(self, context):
1104 layout = self.layout
1106 layout.operator("clip.rebuild_proxy")
1107 layout.operator("clip.delete_proxy")
1110 class CLIP_MT_track(Menu):
1113 def draw(self, context):
1114 layout = self.layout
1116 layout.operator("clip.clear_solution")
1117 layout.operator("clip.solve_camera")
1120 props = layout.operator("clip.clear_track_path", text="Clear After")
1121 props.action = 'REMAINED'
1123 props = layout.operator("clip.clear_track_path", text="Clear Before")
1124 props.action = 'UPTO'
1126 props = layout.operator("clip.clear_track_path",
1127 text="Clear Track Path")
1128 props.action = 'ALL'
1131 layout.operator("clip.join_tracks")
1134 layout.operator("clip.clean_tracks")
1137 layout.operator("clip.copy_tracks")
1138 layout.operator("clip.paste_tracks")
1141 props = layout.operator("clip.track_markers",
1142 text="Track Frame Backwards")
1143 props.backwards = True
1145 props = layout.operator("clip.track_markers", text="Track Backwards")
1146 props.backwards = True
1147 props.sequence = True
1149 props = layout.operator("clip.track_markers", text="Track Forwards")
1150 props.sequence = True
1151 layout.operator("clip.track_markers", text="Track Frame Forwards")
1154 layout.operator("clip.delete_track")
1155 layout.operator("clip.delete_marker")
1158 layout.operator("clip.add_marker_move")
1161 layout.menu("CLIP_MT_track_visibility")
1162 layout.menu("CLIP_MT_track_transform")
1165 class CLIP_MT_reconstruction(Menu):
1166 bl_label = "Reconstruction"
1168 def draw(self, context):
1169 layout = self.layout
1171 layout.operator("clip.set_origin")
1172 props = layout.operator("clip.set_plane", text="Set Floor")
1173 props.plane = 'FLOOR'
1174 props = layout.operator("clip.set_plane", text="Set Wall")
1175 props.plane = 'WALL'
1177 layout.operator("clip.set_axis", text="Set X Axis").axis = "X"
1178 layout.operator("clip.set_axis", text="Set Y Axis").axis = "Y"
1180 layout.operator("clip.set_scale")
1184 layout.operator("clip.track_to_empty")
1185 layout.operator("clip.bundles_to_mesh")
1188 class CLIP_MT_track_visibility(Menu):
1189 bl_label = "Show/Hide"
1191 def draw(self, context):
1192 layout = self.layout
1194 layout.operator("clip.hide_tracks_clear", text="Show Hidden")
1195 layout.operator("clip.hide_tracks", text="Hide Selected")
1197 props = layout.operator("clip.hide_tracks", text="Hide Unselected")
1198 props.unselected = True
1201 class CLIP_MT_track_transform(Menu):
1202 bl_label = "Transform"
1204 def draw(self, context):
1205 layout = self.layout
1207 layout.operator("transform.translate")
1208 layout.operator("transform.resize")
1211 class CLIP_MT_select(Menu):
1214 def draw(self, context):
1215 layout = self.layout
1216 sc = context.space_data
1218 if sc.mode == 'MASKEDIT':
1219 layout.operator("mask.select_border")
1220 layout.operator("mask.select_circle")
1224 layout.operator("mask.select_all"
1226 layout.operator("mask.select_all",
1227 text="Inverse").action = 'INVERT'
1229 layout.operator("clip.select_border")
1230 layout.operator("clip.select_circle")
1234 layout.operator("clip.select_all"
1236 layout.operator("clip.select_all",
1237 text="Inverse").action = 'INVERT'
1239 layout.menu("CLIP_MT_select_grouped")
1242 class CLIP_MT_select_grouped(Menu):
1243 bl_label = "Select Grouped"
1245 def draw(self, context):
1246 layout = self.layout
1248 layout.operator_enum("clip.select_grouped", "group")
1251 class CLIP_MT_tracking_specials(Menu):
1252 bl_label = "Specials"
1255 def poll(cls, context):
1256 return context.space_data.clip
1258 def draw(self, context):
1259 layout = self.layout
1261 props = layout.operator("clip.disable_markers",
1262 text="Enable Markers")
1263 props.action = 'ENABLE'
1265 props = layout.operator("clip.disable_markers", text="Disable markers")
1266 props.action = 'DISABLE'
1269 layout.operator("clip.set_origin")
1272 layout.operator("clip.hide_tracks")
1273 layout.operator("clip.hide_tracks_clear", text="Show Tracks")
1276 props = layout.operator("clip.lock_tracks", text="Lock Tracks")
1277 props.action = 'LOCK'
1279 props = layout.operator("clip.lock_tracks", text="Unlock Tracks")
1280 props.action = 'UNLOCK'
1283 class CLIP_MT_mask(Menu):
1286 def draw(self, context):
1287 layout = self.layout
1289 layout.operator("mask.delete")
1292 layout.operator("mask.cyclic_toggle")
1293 layout.operator("mask.switch_direction")
1294 layout.operator("mask.normals_make_consistent")
1295 layout.operator("mask.feather_weight_clear") # TODO, better place?
1298 layout.operator("mask.parent_clear")
1299 layout.operator("mask.parent_set")
1302 layout.menu("CLIP_MT_mask_visibility")
1303 layout.menu("CLIP_MT_mask_transform")
1304 layout.menu("CLIP_MT_mask_animation")
1307 class CLIP_MT_select_mode(Menu):
1308 bl_label = "Select Mode"
1310 def draw(self, context):
1311 layout = self.layout
1313 layout.operator_context = 'INVOKE_REGION_WIN'
1315 layout.operator_enum("clip.mode_set", "mode")
1318 class CLIP_MT_mask_visibility(Menu):
1319 bl_label = "Show/Hide"
1321 def draw(self, context):
1322 layout = self.layout
1324 layout.operator("mask.hide_view_clear", text="Show Hidden")
1325 layout.operator("mask.hide_view_set", text="Hide Selected")
1327 props = layout.operator("mask.hide_view_set", text="Hide Unselected")
1328 props.unselected = True
1331 class CLIP_MT_mask_transform(Menu):
1332 bl_label = "Transform"
1334 def draw(self, context):
1335 layout = self.layout
1337 layout.operator("transform.translate")
1338 layout.operator("transform.rotate")
1339 layout.operator("transform.resize")
1340 props = layout.operator("transform.transform", text="Shrink/Fatten")
1341 props.mode = 'MASK_SHRINKFATTEN'
1344 class CLIP_MT_mask_animation(Menu):
1345 bl_label = "Animation"
1347 def draw(self, context):
1348 layout = self.layout
1350 layout.operator("mask.shape_key_clear")
1351 layout.operator("mask.shape_key_insert")
1352 layout.operator("mask.shape_key_feather_reset")
1353 layout.operator("mask.shape_key_rekey")
1356 class CLIP_MT_camera_presets(Menu):
1357 """Predefined tracking camera intrinsics"""
1358 bl_label = "Camera Presets"
1359 preset_subdir = "tracking_camera"
1360 preset_operator = "script.execute_preset"
1361 draw = Menu.draw_preset
1364 class CLIP_MT_track_color_presets(Menu):
1365 """Predefined track color"""
1366 bl_label = "Color Presets"
1367 preset_subdir = "tracking_track_color"
1368 preset_operator = "script.execute_preset"
1369 draw = Menu.draw_preset
1372 class CLIP_MT_tracking_settings_presets(Menu):
1373 """Predefined tracking settings"""
1374 bl_label = "Tracking Presets"
1375 preset_subdir = "tracking_settings"
1376 preset_operator = "script.execute_preset"
1377 draw = Menu.draw_preset
1380 class CLIP_MT_track_color_specials(Menu):
1381 bl_label = "Track Color Specials"
1383 def draw(self, context):
1384 layout = self.layout
1386 layout.operator("clip.track_copy_color", icon='COPY_ID')
1389 class CLIP_MT_stabilize_2d_specials(Menu):
1390 bl_label = "Track Color Specials"
1392 def draw(self, context):
1393 layout = self.layout
1395 layout.operator("clip.stabilize_2d_select")
1397 if __name__ == "__main__": # only for live edit.
1398 bpy.utils.register_module(__name__)