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", text="Invert", toggle=True)
100 layout.prop(sc, "view", text="", expand=True)
102 def _draw_masking(self, context):
105 toolsettings = context.tool_settings
106 sc = context.space_data
109 row = layout.row(align=True)
110 row.template_header()
112 if context.area.show_menus:
113 sub = row.row(align=True)
114 sub.menu("CLIP_MT_view")
117 sub.menu("CLIP_MT_select")
118 sub.menu("CLIP_MT_clip")
119 sub.menu("CLIP_MT_mask")
121 sub.menu("CLIP_MT_clip")
124 row.template_ID(sc, "clip", open='clip.open')
126 layout.prop(sc, "mode", text="")
129 row.template_ID(sc, "mask", new="mask.new")
131 layout.prop(sc, "pivot_point", text="", icon_only=True)
133 row = layout.row(align=True)
134 row.prop(toolsettings, "use_proportional_edit_mask",
135 text="", icon_only=True)
136 if toolsettings.use_proportional_edit_mask:
137 row.prop(toolsettings, "proportional_edit_falloff",
138 text="", icon_only=True)
140 def draw(self, context):
143 sc = context.space_data
145 if sc.mode in {'TRACKING', 'RECONSTRUCTION', 'DISTORTION'}:
146 self._draw_tracking(context)
148 self._draw_masking(context)
150 layout.template_running_jobs()
153 class CLIP_PT_clip_view_panel:
156 def poll(cls, context):
157 sc = context.space_data
160 return clip and sc.view == 'CLIP'
163 class CLIP_PT_mask_view_panel:
166 def poll(cls, context):
167 sc = context.space_data
170 return clip and sc.view == 'CLIP' and sc.mode == 'MASKEDIT'
173 class CLIP_PT_tracking_panel:
176 def poll(cls, context):
177 sc = context.space_data
180 return clip and sc.mode == 'TRACKING' and sc.view == 'CLIP'
183 class CLIP_PT_reconstruction_panel:
186 def poll(cls, context):
187 sc = context.space_data
190 return clip and sc.mode == 'RECONSTRUCTION' and sc.view == 'CLIP'
193 class CLIP_PT_tools_marker(CLIP_PT_tracking_panel, Panel):
194 bl_space_type = 'CLIP_EDITOR'
195 bl_region_type = 'TOOLS'
198 def draw(self, context):
199 sc = context.space_data
201 settings = clip.tracking.settings
204 col = layout.column(align=True)
205 col.operator("clip.add_marker_move")
206 col.operator("clip.detect_features")
207 col.operator("clip.delete_track")
210 row = box.row(align=True)
211 row.prop(settings, "show_default_expanded", text="", emboss=False)
212 row.label(text="Tracking Settings")
214 if settings.show_default_expanded:
216 row = col.row(align=True)
217 label = CLIP_MT_tracking_settings_presets.bl_label
218 row.menu('CLIP_MT_tracking_settings_presets', text=label)
219 row.operator("clip.tracking_settings_preset_add",
220 text="", icon='ZOOMIN')
221 props = row.operator("clip.tracking_settings_preset_add",
222 text="", icon='ZOOMOUT')
223 props.remove_active = True
227 row = col.row(align=True)
228 row.prop(settings, "use_default_red_channel",
229 text="R", toggle=True)
230 row.prop(settings, "use_default_green_channel",
231 text="G", toggle=True)
232 row.prop(settings, "use_default_blue_channel",
233 text="B", toggle=True)
237 sub = col.column(align=True)
238 sub.prop(settings, "default_pattern_size")
239 sub.prop(settings, "default_search_size")
241 col.label(text="Tracker:")
242 col.prop(settings, "default_motion_model")
243 col.prop(settings, "default_use_brute")
244 col.prop(settings, "default_use_normalization")
245 col.prop(settings, "default_use_mask")
246 col.prop(settings, "default_correlation_min")
250 sub = col.column(align=True)
251 sub.prop(settings, "default_frames_limit")
252 sub.prop(settings, "default_margin")
254 col.label(text="Match:")
255 col.prop(settings, "default_pattern_match", text="")
258 col.operator('clip.track_settings_as_default',
259 text="Copy From Active Track")
262 class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel):
263 bl_space_type = 'CLIP_EDITOR'
264 bl_region_type = 'TOOLS'
267 def draw(self, context):
270 row = layout.row(align=True)
272 props = row.operator("clip.track_markers", text="", icon='FRAME_PREV')
273 props.backwards = True
274 props.sequence = False
275 props = row.operator("clip.track_markers", text="",
277 props.backwards = True
278 props.sequence = True
279 props = row.operator("clip.track_markers", text="", icon='PLAY')
280 props.backwards = False
281 props.sequence = True
282 props = row.operator("clip.track_markers", text="", icon='FRAME_NEXT')
283 props.backwards = False
284 props.sequence = False
286 col = layout.column(align=True)
287 props = col.operator("clip.clear_track_path", text="Clear After")
288 props.action = 'REMAINED'
290 props = col.operator("clip.clear_track_path", text="Clear Before")
291 props.action = 'UPTO'
292 col.operator("clip.clear_track_path", text="Clear").action = 'ALL'
294 layout.operator("clip.join_tracks", text="Join")
297 class CLIP_PT_tools_solve(CLIP_PT_tracking_panel, Panel):
298 bl_space_type = 'CLIP_EDITOR'
299 bl_region_type = 'TOOLS'
302 def draw(self, context):
304 clip = context.space_data.clip
305 tracking = clip.tracking
306 settings = tracking.settings
307 tracking_object = tracking.objects.active
309 col = layout.column(align=True)
311 col.operator("clip.solve_camera",
312 text="Camera Motion" if tracking_object.is_camera
313 else "Object Motion")
314 col.operator("clip.clear_solution")
316 col = layout.column()
317 col.prop(settings, "use_tripod_solver")
319 col = layout.column(align=True)
320 col.active = not settings.use_tripod_solver
321 col.prop(settings, "keyframe_a")
322 col.prop(settings, "keyframe_b")
324 col = layout.column(align=True)
325 col.active = (tracking_object.is_camera and
326 not settings.use_tripod_solver)
327 col.label(text="Refine:")
328 col.prop(settings, "refine_intrinsics", text="")
331 class CLIP_PT_tools_cleanup(CLIP_PT_tracking_panel, Panel):
332 bl_space_type = 'CLIP_EDITOR'
333 bl_region_type = 'TOOLS'
334 bl_label = "Clean up"
336 def draw(self, context):
338 clip = context.space_data.clip
339 settings = clip.tracking.settings
341 layout.operator("clip.clean_tracks")
343 layout.prop(settings, 'clean_frames', text="Frames")
344 layout.prop(settings, 'clean_error', text="Error")
345 layout.prop(settings, 'clean_action', text="")
348 class CLIP_PT_tools_geometry(CLIP_PT_reconstruction_panel, Panel):
349 bl_space_type = 'CLIP_EDITOR'
350 bl_region_type = 'TOOLS'
351 bl_label = "Geometry"
353 def draw(self, context):
356 layout.operator("clip.bundles_to_mesh")
357 layout.operator("clip.track_to_empty")
360 class CLIP_PT_tools_orientation(CLIP_PT_reconstruction_panel, Panel):
361 bl_space_type = 'CLIP_EDITOR'
362 bl_region_type = 'TOOLS'
363 bl_label = "Orientation"
365 def draw(self, context):
366 sc = context.space_data
368 settings = sc.clip.tracking.settings
370 col = layout.column(align=True)
372 props = row.operator("clip.set_plane", text="Floor")
373 props.plane = 'FLOOR'
374 props = row.operator("clip.set_plane", text="Wall")
376 col.operator("clip.set_origin")
379 row.operator("clip.set_axis", text="Set X Axis").axis = 'X'
380 row.operator("clip.set_axis", text="Set Y Axis").axis = 'Y'
384 col = layout.column()
385 col.operator("clip.set_scale")
386 col.prop(settings, "distance")
389 class CLIP_PT_tools_object(CLIP_PT_reconstruction_panel, Panel):
390 bl_space_type = 'CLIP_EDITOR'
391 bl_region_type = 'TOOLS'
395 def poll(cls, context):
396 if CLIP_PT_reconstruction_panel.poll(context):
397 sc = context.space_data
400 tracking_object = clip.tracking.objects.active
402 return not tracking_object.is_camera
406 def draw(self, context):
409 sc = context.space_data
411 tracking_object = clip.tracking.objects.active
412 settings = sc.clip.tracking.settings
414 col = layout.column()
416 col.prop(tracking_object, "scale")
420 col.operator("clip.set_solution_scale", text="Set Scale")
421 col.prop(settings, "object_distance")
424 class CLIP_PT_tools_mask(CLIP_PT_mask_view_panel, Panel):
425 bl_space_type = 'CLIP_EDITOR'
426 bl_region_type = 'TOOLS'
427 bl_label = "Mask Tools"
429 def draw(self, context):
432 col = layout.column(align=True)
433 col.label(text="Transform:")
434 col.operator("transform.translate")
435 col.operator("transform.rotate")
436 col.operator("transform.resize", text="Scale")
437 props = col.operator("transform.transform", text="Shrink/Fatten")
438 props.mode = 'MASK_SHRINKFATTEN'
440 col = layout.column(align=True)
441 col.label(text="Spline:")
442 col.operator("mask.delete")
443 col.operator("mask.cyclic_toggle")
444 col.operator("mask.switch_direction")
446 col = layout.column(align=True)
447 col.label(text="Parenting:")
448 col.operator("mask.parent_set")
449 col.operator("mask.parent_clear")
452 class CLIP_PT_tools_grease_pencil(Panel):
453 bl_space_type = 'CLIP_EDITOR'
454 bl_region_type = 'TOOLS'
455 bl_label = "Grease Pencil"
458 def poll(cls, context):
459 sc = context.space_data
465 if sc.mode == 'DISTORTION':
466 return sc.view == 'CLIP'
467 elif sc.mode == 'MASKEDIT':
472 def draw(self, context):
475 col = layout.column(align=True)
477 row = col.row(align=True)
478 row.operator("gpencil.draw", text="Draw").mode = 'DRAW'
479 row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT'
481 row = col.row(align=True)
482 row.operator("gpencil.draw", text="Poly").mode = 'DRAW_POLY'
483 row.operator("gpencil.draw", text="Erase").mode = 'ERASER'
486 row.prop(context.tool_settings, "use_grease_pencil_sessions")
489 class CLIP_PT_objects(CLIP_PT_clip_view_panel, Panel):
490 bl_space_type = 'CLIP_EDITOR'
491 bl_region_type = 'UI'
493 bl_options = {'DEFAULT_CLOSED'}
495 def draw(self, context):
498 sc = context.space_data
499 tracking = sc.clip.tracking
502 row.template_list(tracking, "objects",
503 tracking, "active_object_index", rows=3)
505 sub = row.column(align=True)
507 sub.operator("clip.tracking_object_new", icon='ZOOMIN', text="")
508 sub.operator("clip.tracking_object_remove", icon='ZOOMOUT', text="")
510 active = tracking.objects.active
512 layout.prop(active, "name")
515 class CLIP_PT_track(CLIP_PT_tracking_panel, Panel):
516 bl_space_type = 'CLIP_EDITOR'
517 bl_region_type = 'UI'
520 def draw(self, context):
522 sc = context.space_data
523 clip = context.space_data.clip
524 act_track = clip.tracking.tracks.active
527 layout.active = False
528 layout.label(text="No active track")
532 row.prop(act_track, "name", text="")
534 sub = row.row(align=True)
536 sub.template_marker(sc, "clip", sc.clip_user, act_track, True)
538 icon = 'LOCKED' if act_track.lock else 'UNLOCKED'
539 sub.prop(act_track, "lock", text="", icon=icon)
541 layout.template_track(sc, "scopes")
543 row = layout.row(align=True)
545 sub.prop(act_track, "use_red_channel", text="R", toggle=True)
546 sub.prop(act_track, "use_green_channel", text="G", toggle=True)
547 sub.prop(act_track, "use_blue_channel", text="B", toggle=True)
552 sub.prop(act_track, "use_grayscale_preview", text="B/W", toggle=True)
556 sub.prop(act_track, "use_alpha_preview", text="", toggle=True, icon='IMAGE_ALPHA')
560 row = layout.row(align=True)
561 label = bpy.types.CLIP_MT_track_color_presets.bl_label
562 row.menu('CLIP_MT_track_color_presets', text=label)
563 row.menu('CLIP_MT_track_color_specials', text="", icon='DOWNARROW_HLT')
564 row.operator("clip.track_color_preset_add", text="", icon='ZOOMIN')
565 props = row.operator("clip.track_color_preset_add",
566 text="", icon='ZOOMOUT')
567 props.remove_active = True
570 row.prop(act_track, "use_custom_color")
571 if act_track.use_custom_color:
572 row.prop(act_track, "color", text="")
574 if act_track.has_bundle:
575 label_text = "Average Error: %.4f" % (act_track.average_error)
576 layout.label(text=label_text)
579 class CLIP_PT_track_settings(CLIP_PT_tracking_panel, Panel):
580 bl_space_type = 'CLIP_EDITOR'
581 bl_region_type = 'UI'
582 bl_label = "Tracking Settings"
583 bl_options = {'DEFAULT_CLOSED'}
585 def draw(self, context):
587 clip = context.space_data.clip
588 settings = clip.tracking.settings
590 col = layout.column()
592 active = clip.tracking.tracks.active
594 col.prop(active, "motion_model")
595 col.prop(active, "use_brute")
596 col.prop(active, "use_normalization")
597 col.prop(active, "use_mask")
598 col.prop(active, "correlation_min")
601 col.prop(active, "frames_limit")
602 col.prop(active, "margin")
603 col.prop(active, "pattern_match", text="Match")
605 col.prop(settings, "speed")
608 class CLIP_PT_tracking_camera(Panel):
609 bl_space_type = 'CLIP_EDITOR'
610 bl_region_type = 'UI'
611 bl_label = "Camera Data"
612 bl_options = {'DEFAULT_CLOSED'}
615 def poll(cls, context):
616 if CLIP_PT_clip_view_panel.poll(context):
617 sc = context.space_data
619 return sc.mode in {'TRACKING', 'DISTORTION'} and sc.clip
623 def draw(self, context):
626 sc = context.space_data
629 row = layout.row(align=True)
630 label = bpy.types.CLIP_MT_camera_presets.bl_label
631 row.menu('CLIP_MT_camera_presets', text=label)
632 row.operator("clip.camera_preset_add", text="", icon='ZOOMIN')
633 props = row.operator("clip.camera_preset_add", text="", icon='ZOOMOUT')
634 props.remove_active = True
636 row = layout.row(align=True)
637 sub = row.split(percentage=0.65)
638 if clip.tracking.camera.units == 'MILLIMETERS':
639 sub.prop(clip.tracking.camera, "focal_length")
641 sub.prop(clip.tracking.camera, "focal_length_pixels")
642 sub.prop(clip.tracking.camera, "units", text="")
644 col = layout.column(align=True)
645 col.label(text="Sensor:")
646 col.prop(clip.tracking.camera, "sensor_width", text="Width")
647 col.prop(clip.tracking.camera, "pixel_aspect")
649 col = layout.column()
650 col.label(text="Optical Center:")
652 row.prop(clip.tracking.camera, "principal", text="")
653 col.operator("clip.set_center_principal", text="Center")
655 col = layout.column(align=True)
656 col.label(text="Lens Distortion:")
657 col.prop(clip.tracking.camera, "k1")
658 col.prop(clip.tracking.camera, "k2")
659 col.prop(clip.tracking.camera, "k3")
662 class CLIP_PT_mask_layers(Panel):
663 bl_space_type = 'CLIP_EDITOR'
664 bl_region_type = 'UI'
665 bl_label = "Mask Layers"
668 def poll(cls, context):
669 sc = context.space_data
671 return sc.mask and sc.mode == 'MASKEDIT'
673 def draw(self, context):
676 sc = context.space_data
680 row.template_list(mask, "layers",
681 mask, "active_layer_index", rows=3)
683 sub = row.column(align=True)
685 sub.operator("mask.layer_new", icon='ZOOMIN', text="")
686 sub.operator("mask.layer_remove", icon='ZOOMOUT', text="")
688 active = mask.layers.active
690 layout.prop(active, "name")
693 row = layout.row(align=True)
694 row.prop(active, "alpha")
695 row.prop(active, "invert", text="", icon='IMAGE_ALPHA')
697 layout.prop(active, "blend")
700 class CLIP_PT_active_mask_spline(Panel):
701 bl_space_type = 'CLIP_EDITOR'
702 bl_region_type = 'UI'
703 bl_label = "Active Spline"
706 def poll(cls, context):
707 sc = context.space_data
710 if mask and sc.mode == 'MASKEDIT':
711 return mask.layers.active and mask.layers.active.splines.active
715 def draw(self, context):
718 sc = context.space_data
720 spline = mask.layers.active.splines.active
722 col = layout.column()
723 col.prop(spline, "weight_interpolation")
724 col.prop(spline, "use_cyclic")
727 class CLIP_PT_active_mask_point(Panel):
728 bl_space_type = 'CLIP_EDITOR'
729 bl_region_type = 'UI'
730 bl_label = "Active Point"
733 def poll(cls, context):
734 sc = context.space_data
737 if mask and sc.mode == 'MASKEDIT':
738 return mask.layers.active and mask.layers.active.splines.active_point
742 def draw(self, context):
745 sc = context.space_data
747 point = mask.layers.active.splines.active_point
748 parent = point.parent
750 col = layout.column()
751 col.prop(point, "handle_type")
753 col = layout.column()
754 # Currently only parenting yo movie clip is allowed, so do not
755 # ver-oplicate things for now and use single template_ID
756 #col.template_any_ID(parent, "id", "id_type", text="")
759 col.prop(parent, "id", text="")
761 if parent.id_type == 'MOVIECLIP' and parent.id:
763 tracking = clip.tracking
765 col.prop_search(parent, "parent", tracking,
766 "objects", icon='OBJECT_DATA', text="Object:")
768 if parent.parent in tracking.objects:
769 object = tracking.objects[parent.parent]
770 col.prop_search(parent, "sub_parent", object,
771 "tracks", icon='ANIM_DATA', text="Track:")
773 col.prop_search(parent, "sub_parent", tracking,
774 "tracks", icon='ANIM_DATA', text="Track:")
777 class CLIP_PT_display(CLIP_PT_clip_view_panel, Panel):
778 bl_space_type = 'CLIP_EDITOR'
779 bl_region_type = 'UI'
782 def draw(self, context):
784 sc = context.space_data
786 row = layout.row(align=True)
788 sub.prop(sc, "show_red_channel", text="R", toggle=True)
789 sub.prop(sc, "show_green_channel", text="G", toggle=True)
790 sub.prop(sc, "show_blue_channel", text="B", toggle=True)
795 sub.prop(sc, "use_grayscale_preview", text="B/W", toggle=True)
797 col = layout.column(align=True)
799 col.prop(sc, "show_disabled", "Disabled Tracks")
800 col.prop(sc, "show_names", text="Names and Status")
801 col.prop(sc, "show_bundles", text="3D Markers")
803 col.prop(sc, "use_mute_footage", text="Mute Footage")
804 col.prop(sc, "lock_selection")
806 if sc.view == 'GRAPH':
807 col.prop(sc, "lock_time_cursor")
809 if sc.mode == 'DISTORTION':
810 col.prop(sc, "show_grid", text="Grid")
811 col.prop(sc, "use_manual_calibration")
812 elif sc.mode == 'RECONSTRUCTION':
813 col.prop(sc, "show_stable", text="Stable")
817 col.label(text="Display Aspect Ratio:")
819 row.prop(clip, "display_aspect", text="")
821 if sc.mode == 'MASKEDIT':
822 col = layout.column()
823 col.prop(sc, "mask_draw_type", text="")
824 col.prop(sc, "show_mask_smooth")
827 # TODO, move into its own file
828 class CLIP_PT_mask(CLIP_PT_mask_view_panel, Panel):
829 bl_space_type = 'CLIP_EDITOR'
830 bl_region_type = 'UI'
831 bl_label = "Mask Settings"
832 bl_options = {'DEFAULT_CLOSED'}
834 def draw(self, context):
837 sc = context.space_data
840 col = layout.column(align=True)
841 col.prop(mask, "frame_start")
842 col.prop(mask, "frame_end")
845 class CLIP_PT_marker_display(CLIP_PT_clip_view_panel, Panel):
846 bl_space_type = 'CLIP_EDITOR'
847 bl_region_type = 'UI'
848 bl_label = "Marker Display"
851 def poll(cls, context):
852 sc = context.space_data
854 return sc.mode != 'MASKEDIT'
856 def draw(self, context):
858 sc = context.space_data
860 col = layout.column(align=True)
863 row.prop(sc, "show_marker_pattern", text="Pattern")
864 row.prop(sc, "show_marker_search", text="Search")
866 col.prop(sc, "show_tiny_markers", text="Thin Markers")
867 col.prop(sc, "show_track_path", text="Path")
870 row.active = sc.show_track_path
871 row.prop(sc, "path_length", text="Length")
874 class CLIP_PT_stabilization(CLIP_PT_reconstruction_panel, Panel):
875 bl_space_type = 'CLIP_EDITOR'
876 bl_region_type = 'UI'
877 bl_label = "2D Stabilization"
878 bl_options = {'DEFAULT_CLOSED'}
880 def draw_header(self, context):
881 stab = context.space_data.clip.tracking.stabilization
883 self.layout.prop(stab, "use_2d_stabilization", text="")
885 def draw(self, context):
888 tracking = context.space_data.clip.tracking
889 stab = tracking.stabilization
891 layout.active = stab.use_2d_stabilization
894 row.template_list(stab, "tracks", stab, "active_track_index", rows=3)
896 sub = row.column(align=True)
898 sub.operator("clip.stabilize_2d_add", icon='ZOOMIN', text="")
899 sub.operator("clip.stabilize_2d_remove", icon='ZOOMOUT', text="")
901 sub.menu('CLIP_MT_stabilize_2d_specials', text="",
902 icon='DOWNARROW_HLT')
904 layout.prop(stab, "influence_location")
906 layout.prop(stab, "use_autoscale")
907 col = layout.column()
908 col.active = stab.use_autoscale
909 col.prop(stab, "scale_max")
910 col.prop(stab, "influence_scale")
912 layout.prop(stab, "use_stabilize_rotation")
913 col = layout.column()
914 col.active = stab.use_stabilize_rotation
916 row = col.row(align=True)
917 row.prop_search(stab, "rotation_track", tracking, "tracks", text="")
918 row.operator("clip.stabilize_2d_set_rotation", text="", icon='ZOOMIN')
921 row.active = stab.rotation_track is not None
922 row.prop(stab, "influence_rotation")
924 layout.prop(stab, "filter_type")
927 class CLIP_PT_marker(CLIP_PT_tracking_panel, Panel):
928 bl_space_type = 'CLIP_EDITOR'
929 bl_region_type = 'UI'
931 bl_options = {'DEFAULT_CLOSED'}
933 def draw(self, context):
935 sc = context.space_data
936 clip = context.space_data.clip
937 act_track = clip.tracking.tracks.active
940 layout.template_marker(sc, "clip", sc.clip_user, act_track, False)
942 layout.active = False
943 layout.label(text="No active track")
946 class CLIP_PT_proxy(CLIP_PT_clip_view_panel, Panel):
947 bl_space_type = 'CLIP_EDITOR'
948 bl_region_type = 'UI'
949 bl_label = "Proxy / Timecode"
950 bl_options = {'DEFAULT_CLOSED'}
952 def draw_header(self, context):
953 sc = context.space_data
955 self.layout.prop(sc.clip, "use_proxy", text="")
957 def draw(self, context):
959 sc = context.space_data
962 layout.active = clip.use_proxy
964 layout.label(text="Build Original:")
966 row = layout.row(align=True)
967 row.prop(clip.proxy, "build_25", toggle=True)
968 row.prop(clip.proxy, "build_50", toggle=True)
969 row.prop(clip.proxy, "build_75", toggle=True)
970 row.prop(clip.proxy, "build_100", toggle=True)
972 layout.label(text="Build Undistorted:")
974 row = layout.row(align=True)
975 row.prop(clip.proxy, "build_undistorted_25", toggle=True)
976 row.prop(clip.proxy, "build_undistorted_50", toggle=True)
977 row.prop(clip.proxy, "build_undistorted_75", toggle=True)
978 row.prop(clip.proxy, "build_undistorted_100", toggle=True)
980 layout.prop(clip.proxy, "quality")
982 layout.prop(clip, 'use_proxy_custom_directory')
983 if clip.use_proxy_custom_directory:
984 layout.prop(clip.proxy, "directory")
986 layout.operator("clip.rebuild_proxy", text="Build Proxy")
988 if clip.source == 'MOVIE':
989 col = layout.column()
991 col.label(text="Use timecode index:")
992 col.prop(clip.proxy, "timecode", text="")
994 col = layout.column()
995 col.label(text="Proxy render size:")
997 col.prop(sc.clip_user, "proxy_render_size", text="")
998 col.prop(sc.clip_user, "use_render_undistorted")
1001 class CLIP_PT_footage(CLIP_PT_clip_view_panel, Panel):
1002 bl_space_type = 'CLIP_EDITOR'
1003 bl_region_type = 'UI'
1004 bl_label = "Footage Settings"
1005 bl_options = {'DEFAULT_CLOSED'}
1007 def draw(self, context):
1008 layout = self.layout
1010 sc = context.space_data
1013 col = layout.column()
1014 col.template_movieclip(sc, "clip", compact=True)
1015 col.prop(clip, "start_frame")
1016 col.prop(clip, "frame_offset")
1019 class CLIP_PT_tools_clip(CLIP_PT_clip_view_panel, Panel):
1020 bl_space_type = 'CLIP_EDITOR'
1021 bl_region_type = 'TOOLS'
1024 def draw(self, context):
1025 layout = self.layout
1027 layout.operator("clip.set_viewport_background")
1028 layout.operator("clip.setup_tracking_scene")
1031 class CLIP_MT_view(Menu):
1034 def draw(self, context):
1035 layout = self.layout
1036 sc = context.space_data
1038 if sc.view == 'CLIP':
1039 layout.operator("clip.properties", icon='MENU_PANEL')
1040 layout.operator("clip.tools", icon='MENU_PANEL')
1043 layout.operator("clip.view_selected")
1044 layout.operator("clip.view_all")
1047 layout.operator("clip.view_zoom_in")
1048 layout.operator("clip.view_zoom_out")
1052 ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1))
1055 text = "Zoom %d:%d" % (a, b)
1056 layout.operator("clip.view_zoom_ratio", text=text).ratio = a / b
1058 layout.prop(sc, "show_seconds")
1062 layout.operator("screen.area_dupli")
1063 layout.operator("screen.screen_full_area")
1066 class CLIP_MT_clip(Menu):
1069 def draw(self, context):
1070 layout = self.layout
1072 sc = context.space_data
1075 layout.operator("clip.open")
1078 layout.operator("clip.reload")
1079 layout.menu("CLIP_MT_proxy")
1082 class CLIP_MT_proxy(Menu):
1085 def draw(self, context):
1086 layout = self.layout
1088 layout.operator("clip.rebuild_proxy")
1089 layout.operator("clip.delete_proxy")
1092 class CLIP_MT_track(Menu):
1095 def draw(self, context):
1096 layout = self.layout
1098 layout.operator("clip.clear_solution")
1099 layout.operator("clip.solve_camera")
1102 props = layout.operator("clip.clear_track_path", text="Clear After")
1103 props.action = 'REMAINED'
1105 props = layout.operator("clip.clear_track_path", text="Clear Before")
1106 props.action = 'UPTO'
1108 props = layout.operator("clip.clear_track_path",
1109 text="Clear Track Path")
1110 props.action = 'ALL'
1113 layout.operator("clip.join_tracks")
1116 layout.operator("clip.clean_tracks")
1119 layout.operator("clip.copy_tracks")
1120 layout.operator("clip.paste_tracks")
1123 props = layout.operator("clip.track_markers",
1124 text="Track Frame Backwards")
1125 props.backwards = True
1127 props = layout.operator("clip.track_markers", text="Track Backwards")
1128 props.backwards = True
1129 props.sequence = True
1131 props = layout.operator("clip.track_markers", text="Track Forwards")
1132 props.sequence = True
1133 layout.operator("clip.track_markers", text="Track Frame Forwards")
1136 layout.operator("clip.delete_track")
1137 layout.operator("clip.delete_marker")
1140 layout.operator("clip.add_marker_move")
1143 layout.menu("CLIP_MT_track_visibility")
1144 layout.menu("CLIP_MT_track_transform")
1147 class CLIP_MT_reconstruction(Menu):
1148 bl_label = "Reconstruction"
1150 def draw(self, context):
1151 layout = self.layout
1153 layout.operator("clip.set_origin")
1154 props = layout.operator("clip.set_plane", text="Set Floor")
1155 props.plane = 'FLOOR'
1156 props = layout.operator("clip.set_plane", text="Set Wall")
1157 props.plane = 'WALL'
1159 layout.operator("clip.set_axis", text="Set X Axis").axis = "X"
1160 layout.operator("clip.set_axis", text="Set Y Axis").axis = "Y"
1162 layout.operator("clip.set_scale")
1166 layout.operator("clip.track_to_empty")
1167 layout.operator("clip.bundles_to_mesh")
1170 class CLIP_MT_track_visibility(Menu):
1171 bl_label = "Show/Hide"
1173 def draw(self, context):
1174 layout = self.layout
1176 layout.operator("clip.hide_tracks_clear", text="Show Hidden")
1177 layout.operator("clip.hide_tracks", text="Hide Selected")
1179 props = layout.operator("clip.hide_tracks", text="Hide Unselected")
1180 props.unselected = True
1183 class CLIP_MT_track_transform(Menu):
1184 bl_label = "Transform"
1186 def draw(self, context):
1187 layout = self.layout
1189 layout.operator("transform.translate")
1190 layout.operator("transform.resize")
1193 class CLIP_MT_select(Menu):
1196 def draw(self, context):
1197 layout = self.layout
1198 sc = context.space_data
1200 if sc.mode == 'MASKEDIT':
1201 layout.operator("mask.select_border")
1202 layout.operator("mask.select_circle")
1206 layout.operator("mask.select_all").action = 'TOGGLE'
1207 layout.operator("mask.select_all", text="Inverse").action = 'INVERT'
1209 layout.operator("clip.select_border")
1210 layout.operator("clip.select_circle")
1214 layout.operator("clip.select_all").action = 'TOGGLE'
1215 layout.operator("clip.select_all", text="Inverse").action = 'INVERT'
1217 layout.menu("CLIP_MT_select_grouped")
1220 class CLIP_MT_select_grouped(Menu):
1221 bl_label = "Select Grouped"
1223 def draw(self, context):
1224 layout = self.layout
1226 layout.operator_enum("clip.select_grouped", "group")
1229 class CLIP_MT_tracking_specials(Menu):
1230 bl_label = "Specials"
1233 def poll(cls, context):
1234 return context.space_data.clip
1236 def draw(self, context):
1237 layout = self.layout
1239 props = layout.operator("clip.disable_markers",
1240 text="Enable Markers")
1241 props.action = 'ENABLE'
1243 props = layout.operator("clip.disable_markers", text="Disable markers")
1244 props.action = 'DISABLE'
1247 layout.operator("clip.set_origin")
1250 layout.operator("clip.hide_tracks")
1251 layout.operator("clip.hide_tracks_clear", text="Show Tracks")
1254 props = layout.operator("clip.lock_tracks", text="Lock Tracks")
1255 props.action = 'LOCK'
1257 props = layout.operator("clip.lock_tracks", text="Unlock Tracks")
1258 props.action = 'UNLOCK'
1261 class CLIP_MT_mask(Menu):
1264 def draw(self, context):
1265 layout = self.layout
1267 layout.operator("mask.delete")
1270 layout.operator("mask.cyclic_toggle")
1271 layout.operator("mask.switch_direction")
1272 layout.operator("mask.normals_make_consistent")
1273 layout.operator("mask.feather_weight_clear") # TODO, better place?
1276 layout.operator("mask.parent_clear")
1277 layout.operator("mask.parent_set")
1280 layout.menu("CLIP_MT_mask_visibility")
1281 layout.menu("CLIP_MT_mask_transform")
1282 layout.menu("CLIP_MT_mask_animation")
1285 class CLIP_MT_mask_visibility(Menu):
1286 bl_label = "Show/Hide"
1288 def draw(self, context):
1289 layout = self.layout
1291 layout.operator("mask.hide_view_clear", text="Show Hidden")
1292 layout.operator("mask.hide_view_set", text="Hide Selected")
1294 props = layout.operator("mask.hide_view_set", text="Hide Unselected")
1295 props.unselected = True
1298 class CLIP_MT_mask_transform(Menu):
1299 bl_label = "Transform"
1301 def draw(self, context):
1302 layout = self.layout
1304 layout.operator("transform.translate")
1305 layout.operator("transform.rotate")
1306 layout.operator("transform.resize")
1307 props = layout.operator("transform.transform", text="Shrink/Fatten")
1308 props.mode = 'MASK_SHRINKFATTEN'
1311 class CLIP_MT_mask_animation(Menu):
1312 bl_label = "Animation"
1314 def draw(self, context):
1315 layout = self.layout
1317 layout.operator("mask.shape_key_clear")
1318 layout.operator("mask.shape_key_insert")
1319 layout.operator("mask.shape_key_feather_reset")
1322 class CLIP_MT_camera_presets(Menu):
1323 """Predefined tracking camera intrinsics"""
1324 bl_label = "Camera Presets"
1325 preset_subdir = "tracking_camera"
1326 preset_operator = "script.execute_preset"
1327 draw = Menu.draw_preset
1330 class CLIP_MT_track_color_presets(Menu):
1331 """Predefined track color"""
1332 bl_label = "Color Presets"
1333 preset_subdir = "tracking_track_color"
1334 preset_operator = "script.execute_preset"
1335 draw = Menu.draw_preset
1338 class CLIP_MT_tracking_settings_presets(Menu):
1339 """Predefined tracking settings"""
1340 bl_label = "Tracking Presets"
1341 preset_subdir = "tracking_settings"
1342 preset_operator = "script.execute_preset"
1343 draw = Menu.draw_preset
1346 class CLIP_MT_track_color_specials(Menu):
1347 bl_label = "Track Color Specials"
1349 def draw(self, context):
1350 layout = self.layout
1352 layout.operator('clip.track_copy_color', icon='COPY_ID')
1355 class CLIP_MT_stabilize_2d_specials(Menu):
1356 bl_label = "Track Color Specials"
1358 def draw(self, context):
1359 layout = self.layout
1361 layout.operator('clip.stabilize_2d_select')
1363 if __name__ == "__main__": # only for live edit.
1364 bpy.utils.register_module(__name__)