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")
712 class CLIP_PT_active_mask_spline(Panel):
713 bl_space_type = 'CLIP_EDITOR'
714 bl_region_type = 'UI'
715 bl_label = "Active Spline"
718 def poll(cls, context):
719 sc = context.space_data
722 if mask and sc.mode == 'MASKEDIT':
723 return mask.layers.active and mask.layers.active.splines.active
727 def draw(self, context):
730 sc = context.space_data
732 spline = mask.layers.active.splines.active
734 col = layout.column()
735 col.prop(spline, "weight_interpolation")
737 rowsub.prop(spline, "use_cyclic")
738 rowsub.prop(spline, "use_fill")
741 class CLIP_PT_active_mask_point(Panel):
742 bl_space_type = 'CLIP_EDITOR'
743 bl_region_type = 'UI'
744 bl_label = "Active Point"
747 def poll(cls, context):
748 sc = context.space_data
751 if mask and sc.mode == 'MASKEDIT':
752 mask_layer_active = mask.layers.active
753 return (mask_layer_active and
754 mask_layer_active.splines.active_point)
758 def draw(self, context):
761 sc = context.space_data
763 point = mask.layers.active.splines.active_point
764 parent = point.parent
766 col = layout.column()
767 col.prop(point, "handle_type")
769 col = layout.column()
770 # Currently only parenting yo movie clip is allowed, so do not
771 # ver-oplicate things for now and use single template_ID
772 #col.template_any_ID(parent, "id", "id_type", text="")
775 col.prop(parent, "id", text="")
777 if parent.id_type == 'MOVIECLIP' and parent.id:
779 tracking = clip.tracking
781 col.prop_search(parent, "parent", tracking,
782 "objects", icon='OBJECT_DATA', text="Object:")
784 if parent.parent in tracking.objects:
785 object = tracking.objects[parent.parent]
786 col.prop_search(parent, "sub_parent", object,
787 "tracks", icon='ANIM_DATA', text="Track:")
789 col.prop_search(parent, "sub_parent", tracking,
790 "tracks", icon='ANIM_DATA', text="Track:")
793 class CLIP_PT_display(CLIP_PT_clip_view_panel, Panel):
794 bl_space_type = 'CLIP_EDITOR'
795 bl_region_type = 'UI'
798 def draw(self, context):
800 sc = context.space_data
802 row = layout.row(align=True)
804 sub.prop(sc, "show_red_channel", text="R", toggle=True)
805 sub.prop(sc, "show_green_channel", text="G", toggle=True)
806 sub.prop(sc, "show_blue_channel", text="B", toggle=True)
811 sub.prop(sc, "use_grayscale_preview", text="B/W", toggle=True)
813 col = layout.column(align=True)
815 col.prop(sc, "show_disabled", "Disabled Tracks")
816 col.prop(sc, "show_names", text="Names and Status")
817 col.prop(sc, "show_bundles", text="3D Markers")
819 col.prop(sc, "use_mute_footage", text="Mute Footage")
820 col.prop(sc, "lock_selection")
822 if sc.view == 'GRAPH':
823 col.prop(sc, "lock_time_cursor")
825 if sc.mode == 'DISTORTION':
826 col.prop(sc, "show_grid", text="Grid")
827 col.prop(sc, "use_manual_calibration")
828 elif sc.mode == 'RECONSTRUCTION':
829 col.prop(sc, "show_stable", text="Stable")
833 col.label(text="Display Aspect Ratio:")
835 row.prop(clip, "display_aspect", text="")
837 if sc.mode == 'MASKEDIT':
838 col = layout.column()
839 col.prop(sc, "mask_draw_type", text="")
840 col.prop(sc, "show_mask_smooth")
843 # TODO, move into its own file
844 class CLIP_PT_mask(CLIP_PT_mask_view_panel, Panel):
845 bl_space_type = 'CLIP_EDITOR'
846 bl_region_type = 'UI'
847 bl_label = "Mask Settings"
848 bl_options = {'DEFAULT_CLOSED'}
850 def draw(self, context):
853 sc = context.space_data
856 col = layout.column(align=True)
857 col.prop(mask, "frame_start")
858 col.prop(mask, "frame_end")
861 class CLIP_PT_marker_display(CLIP_PT_clip_view_panel, Panel):
862 bl_space_type = 'CLIP_EDITOR'
863 bl_region_type = 'UI'
864 bl_label = "Marker Display"
867 def poll(cls, context):
868 sc = context.space_data
870 return sc.mode != 'MASKEDIT'
872 def draw(self, context):
874 sc = context.space_data
876 col = layout.column(align=True)
879 row.prop(sc, "show_marker_pattern", text="Pattern")
880 row.prop(sc, "show_marker_search", text="Search")
882 col.prop(sc, "show_tiny_markers", text="Thin Markers")
883 col.prop(sc, "show_track_path", text="Path")
886 row.active = sc.show_track_path
887 row.prop(sc, "path_length", text="Length")
890 class CLIP_PT_stabilization(CLIP_PT_reconstruction_panel, Panel):
891 bl_space_type = 'CLIP_EDITOR'
892 bl_region_type = 'UI'
893 bl_label = "2D Stabilization"
894 bl_options = {'DEFAULT_CLOSED'}
896 def draw_header(self, context):
897 stab = context.space_data.clip.tracking.stabilization
899 self.layout.prop(stab, "use_2d_stabilization", text="")
901 def draw(self, context):
904 tracking = context.space_data.clip.tracking
905 stab = tracking.stabilization
907 layout.active = stab.use_2d_stabilization
910 row.template_list(stab, "tracks", stab, "active_track_index", rows=3)
912 sub = row.column(align=True)
914 sub.operator("clip.stabilize_2d_add", icon='ZOOMIN', text="")
915 sub.operator("clip.stabilize_2d_remove", icon='ZOOMOUT', text="")
917 sub.menu('CLIP_MT_stabilize_2d_specials', text="",
918 icon='DOWNARROW_HLT')
920 layout.prop(stab, "influence_location")
922 layout.prop(stab, "use_autoscale")
923 col = layout.column()
924 col.active = stab.use_autoscale
925 col.prop(stab, "scale_max")
926 col.prop(stab, "influence_scale")
928 layout.prop(stab, "use_stabilize_rotation")
929 col = layout.column()
930 col.active = stab.use_stabilize_rotation
932 row = col.row(align=True)
933 row.prop_search(stab, "rotation_track", tracking, "tracks", text="")
934 row.operator("clip.stabilize_2d_set_rotation", text="", icon='ZOOMIN')
937 row.active = stab.rotation_track is not None
938 row.prop(stab, "influence_rotation")
940 layout.prop(stab, "filter_type")
943 class CLIP_PT_marker(CLIP_PT_tracking_panel, Panel):
944 bl_space_type = 'CLIP_EDITOR'
945 bl_region_type = 'UI'
947 bl_options = {'DEFAULT_CLOSED'}
949 def draw(self, context):
951 sc = context.space_data
952 clip = context.space_data.clip
953 act_track = clip.tracking.tracks.active
956 layout.template_marker(sc, "clip", sc.clip_user, act_track, False)
958 layout.active = False
959 layout.label(text="No active track")
962 class CLIP_PT_proxy(CLIP_PT_clip_view_panel, Panel):
963 bl_space_type = 'CLIP_EDITOR'
964 bl_region_type = 'UI'
965 bl_label = "Proxy / Timecode"
966 bl_options = {'DEFAULT_CLOSED'}
968 def draw_header(self, context):
969 sc = context.space_data
971 self.layout.prop(sc.clip, "use_proxy", text="")
973 def draw(self, context):
975 sc = context.space_data
978 layout.active = clip.use_proxy
980 layout.label(text="Build Original:")
982 row = layout.row(align=True)
983 row.prop(clip.proxy, "build_25", toggle=True)
984 row.prop(clip.proxy, "build_50", toggle=True)
985 row.prop(clip.proxy, "build_75", toggle=True)
986 row.prop(clip.proxy, "build_100", toggle=True)
988 layout.label(text="Build Undistorted:")
990 row = layout.row(align=True)
991 row.prop(clip.proxy, "build_undistorted_25", toggle=True)
992 row.prop(clip.proxy, "build_undistorted_50", toggle=True)
993 row.prop(clip.proxy, "build_undistorted_75", toggle=True)
994 row.prop(clip.proxy, "build_undistorted_100", toggle=True)
996 layout.prop(clip.proxy, "quality")
998 layout.prop(clip, "use_proxy_custom_directory")
999 if clip.use_proxy_custom_directory:
1000 layout.prop(clip.proxy, "directory")
1002 layout.operator("clip.rebuild_proxy", text="Build Proxy")
1004 if clip.source == 'MOVIE':
1005 col = layout.column()
1007 col.label(text="Use timecode index:")
1008 col.prop(clip.proxy, "timecode", text="")
1010 col = layout.column()
1011 col.label(text="Proxy render size:")
1013 col.prop(sc.clip_user, "proxy_render_size", text="")
1014 col.prop(sc.clip_user, "use_render_undistorted")
1017 class CLIP_PT_footage(CLIP_PT_clip_view_panel, Panel):
1018 bl_space_type = 'CLIP_EDITOR'
1019 bl_region_type = 'UI'
1020 bl_label = "Footage Settings"
1021 bl_options = {'DEFAULT_CLOSED'}
1023 def draw(self, context):
1024 layout = self.layout
1026 sc = context.space_data
1029 col = layout.column()
1030 col.template_movieclip(sc, "clip", compact=True)
1031 col.prop(clip, "start_frame")
1032 col.prop(clip, "frame_offset")
1035 class CLIP_PT_tools_clip(CLIP_PT_clip_view_panel, Panel):
1036 bl_space_type = 'CLIP_EDITOR'
1037 bl_region_type = 'TOOLS'
1040 def draw(self, context):
1041 layout = self.layout
1043 layout.operator("clip.set_viewport_background")
1044 layout.operator("clip.setup_tracking_scene")
1047 class CLIP_MT_view(Menu):
1050 def draw(self, context):
1051 layout = self.layout
1052 sc = context.space_data
1054 if sc.view == 'CLIP':
1055 layout.operator("clip.properties", icon='MENU_PANEL')
1056 layout.operator("clip.tools", icon='MENU_PANEL')
1059 layout.operator("clip.view_selected")
1060 layout.operator("clip.view_all")
1063 layout.operator("clip.view_zoom_in")
1064 layout.operator("clip.view_zoom_out")
1068 ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1))
1071 text = "Zoom %d:%d" % (a, b)
1072 layout.operator("clip.view_zoom_ratio",
1073 text=text).ratio = a / b
1075 layout.prop(sc, "show_seconds")
1079 layout.operator("screen.area_dupli")
1080 layout.operator("screen.screen_full_area")
1083 class CLIP_MT_clip(Menu):
1086 def draw(self, context):
1087 layout = self.layout
1089 sc = context.space_data
1092 layout.operator("clip.open")
1095 layout.operator("clip.reload")
1096 layout.menu("CLIP_MT_proxy")
1099 class CLIP_MT_proxy(Menu):
1102 def draw(self, context):
1103 layout = self.layout
1105 layout.operator("clip.rebuild_proxy")
1106 layout.operator("clip.delete_proxy")
1109 class CLIP_MT_track(Menu):
1112 def draw(self, context):
1113 layout = self.layout
1115 layout.operator("clip.clear_solution")
1116 layout.operator("clip.solve_camera")
1119 props = layout.operator("clip.clear_track_path", text="Clear After")
1120 props.action = 'REMAINED'
1122 props = layout.operator("clip.clear_track_path", text="Clear Before")
1123 props.action = 'UPTO'
1125 props = layout.operator("clip.clear_track_path",
1126 text="Clear Track Path")
1127 props.action = 'ALL'
1130 layout.operator("clip.join_tracks")
1133 layout.operator("clip.clean_tracks")
1136 layout.operator("clip.copy_tracks")
1137 layout.operator("clip.paste_tracks")
1140 props = layout.operator("clip.track_markers",
1141 text="Track Frame Backwards")
1142 props.backwards = True
1144 props = layout.operator("clip.track_markers", text="Track Backwards")
1145 props.backwards = True
1146 props.sequence = True
1148 props = layout.operator("clip.track_markers", text="Track Forwards")
1149 props.sequence = True
1150 layout.operator("clip.track_markers", text="Track Frame Forwards")
1153 layout.operator("clip.delete_track")
1154 layout.operator("clip.delete_marker")
1157 layout.operator("clip.add_marker_move")
1160 layout.menu("CLIP_MT_track_visibility")
1161 layout.menu("CLIP_MT_track_transform")
1164 class CLIP_MT_reconstruction(Menu):
1165 bl_label = "Reconstruction"
1167 def draw(self, context):
1168 layout = self.layout
1170 layout.operator("clip.set_origin")
1171 props = layout.operator("clip.set_plane", text="Set Floor")
1172 props.plane = 'FLOOR'
1173 props = layout.operator("clip.set_plane", text="Set Wall")
1174 props.plane = 'WALL'
1176 layout.operator("clip.set_axis", text="Set X Axis").axis = "X"
1177 layout.operator("clip.set_axis", text="Set Y Axis").axis = "Y"
1179 layout.operator("clip.set_scale")
1183 layout.operator("clip.track_to_empty")
1184 layout.operator("clip.bundles_to_mesh")
1187 class CLIP_MT_track_visibility(Menu):
1188 bl_label = "Show/Hide"
1190 def draw(self, context):
1191 layout = self.layout
1193 layout.operator("clip.hide_tracks_clear", text="Show Hidden")
1194 layout.operator("clip.hide_tracks", text="Hide Selected")
1196 props = layout.operator("clip.hide_tracks", text="Hide Unselected")
1197 props.unselected = True
1200 class CLIP_MT_track_transform(Menu):
1201 bl_label = "Transform"
1203 def draw(self, context):
1204 layout = self.layout
1206 layout.operator("transform.translate")
1207 layout.operator("transform.resize")
1210 class CLIP_MT_select(Menu):
1213 def draw(self, context):
1214 layout = self.layout
1215 sc = context.space_data
1217 if sc.mode == 'MASKEDIT':
1218 layout.operator("mask.select_border")
1219 layout.operator("mask.select_circle")
1223 layout.operator("mask.select_all"
1225 layout.operator("mask.select_all",
1226 text="Inverse").action = 'INVERT'
1228 layout.operator("clip.select_border")
1229 layout.operator("clip.select_circle")
1233 layout.operator("clip.select_all"
1235 layout.operator("clip.select_all",
1236 text="Inverse").action = 'INVERT'
1238 layout.menu("CLIP_MT_select_grouped")
1241 class CLIP_MT_select_grouped(Menu):
1242 bl_label = "Select Grouped"
1244 def draw(self, context):
1245 layout = self.layout
1247 layout.operator_enum("clip.select_grouped", "group")
1250 class CLIP_MT_tracking_specials(Menu):
1251 bl_label = "Specials"
1254 def poll(cls, context):
1255 return context.space_data.clip
1257 def draw(self, context):
1258 layout = self.layout
1260 props = layout.operator("clip.disable_markers",
1261 text="Enable Markers")
1262 props.action = 'ENABLE'
1264 props = layout.operator("clip.disable_markers", text="Disable markers")
1265 props.action = 'DISABLE'
1268 layout.operator("clip.set_origin")
1271 layout.operator("clip.hide_tracks")
1272 layout.operator("clip.hide_tracks_clear", text="Show Tracks")
1275 props = layout.operator("clip.lock_tracks", text="Lock Tracks")
1276 props.action = 'LOCK'
1278 props = layout.operator("clip.lock_tracks", text="Unlock Tracks")
1279 props.action = 'UNLOCK'
1282 class CLIP_MT_mask(Menu):
1285 def draw(self, context):
1286 layout = self.layout
1288 layout.operator("mask.delete")
1291 layout.operator("mask.cyclic_toggle")
1292 layout.operator("mask.switch_direction")
1293 layout.operator("mask.normals_make_consistent")
1294 layout.operator("mask.feather_weight_clear") # TODO, better place?
1297 layout.operator("mask.parent_clear")
1298 layout.operator("mask.parent_set")
1301 layout.menu("CLIP_MT_mask_visibility")
1302 layout.menu("CLIP_MT_mask_transform")
1303 layout.menu("CLIP_MT_mask_animation")
1306 class CLIP_MT_select_mode(Menu):
1307 bl_label = "Select Mode"
1309 def draw(self, context):
1310 layout = self.layout
1312 layout.operator_context = 'INVOKE_REGION_WIN'
1314 layout.operator_enum("clip.mode_set", "mode")
1317 class CLIP_MT_mask_visibility(Menu):
1318 bl_label = "Show/Hide"
1320 def draw(self, context):
1321 layout = self.layout
1323 layout.operator("mask.hide_view_clear", text="Show Hidden")
1324 layout.operator("mask.hide_view_set", text="Hide Selected")
1326 props = layout.operator("mask.hide_view_set", text="Hide Unselected")
1327 props.unselected = True
1330 class CLIP_MT_mask_transform(Menu):
1331 bl_label = "Transform"
1333 def draw(self, context):
1334 layout = self.layout
1336 layout.operator("transform.translate")
1337 layout.operator("transform.rotate")
1338 layout.operator("transform.resize")
1339 props = layout.operator("transform.transform", text="Shrink/Fatten")
1340 props.mode = 'MASK_SHRINKFATTEN'
1343 class CLIP_MT_mask_animation(Menu):
1344 bl_label = "Animation"
1346 def draw(self, context):
1347 layout = self.layout
1349 layout.operator("mask.shape_key_clear")
1350 layout.operator("mask.shape_key_insert")
1351 layout.operator("mask.shape_key_feather_reset")
1352 layout.operator("mask.shape_key_rekey")
1355 class CLIP_MT_camera_presets(Menu):
1356 """Predefined tracking camera intrinsics"""
1357 bl_label = "Camera Presets"
1358 preset_subdir = "tracking_camera"
1359 preset_operator = "script.execute_preset"
1360 draw = Menu.draw_preset
1363 class CLIP_MT_track_color_presets(Menu):
1364 """Predefined track color"""
1365 bl_label = "Color Presets"
1366 preset_subdir = "tracking_track_color"
1367 preset_operator = "script.execute_preset"
1368 draw = Menu.draw_preset
1371 class CLIP_MT_tracking_settings_presets(Menu):
1372 """Predefined tracking settings"""
1373 bl_label = "Tracking Presets"
1374 preset_subdir = "tracking_settings"
1375 preset_operator = "script.execute_preset"
1376 draw = Menu.draw_preset
1379 class CLIP_MT_track_color_specials(Menu):
1380 bl_label = "Track Color Specials"
1382 def draw(self, context):
1383 layout = self.layout
1385 layout.operator("clip.track_copy_color", icon='COPY_ID')
1388 class CLIP_MT_stabilize_2d_specials(Menu):
1389 bl_label = "Track Color Specials"
1391 def draw(self, context):
1392 layout = self.layout
1394 layout.operator("clip.stabilize_2d_select")
1396 if __name__ == "__main__": # only for live edit.
1397 bpy.utils.register_module(__name__)