Camera tracking: tracks copy/paste operator
[blender.git] / release / scripts / startup / bl_ui / space_clip.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
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.
7 #
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.
12 #
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.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8-80 compliant>
20
21 import bpy
22 from bpy.types import Panel, Header, Menu
23
24
25 class CLIP_HT_header(Header):
26     bl_space_type = 'CLIP_EDITOR'
27
28     def draw(self, context):
29         layout = self.layout
30
31         sc = context.space_data
32         clip = sc.clip
33
34         row = layout.row(align=True)
35         row.template_header()
36
37         if context.area.show_menus:
38             sub = row.row(align=True)
39             sub.menu("CLIP_MT_view")
40
41             if clip:
42                 sub.menu("CLIP_MT_select")
43
44             sub.menu("CLIP_MT_clip")
45
46             if clip:
47                 sub.menu("CLIP_MT_track")
48                 sub.menu("CLIP_MT_reconstruction")
49
50         if clip:
51             layout.prop(sc, "mode", text="")
52             layout.prop(sc, "view", text="", expand=True)
53
54             if sc.view == 'GRAPH':
55                 row = layout.row(align=True)
56
57                 if sc.show_filters:
58                     row.prop(sc, "show_filters", icon='DISCLOSURE_TRI_DOWN',
59                         text="Filters")
60
61                     sub = row.column()
62                     sub.active = clip.tracking.reconstruction.is_valid
63                     sub.prop(sc, "show_graph_frames", icon='SEQUENCE', text="")
64
65                     row.prop(sc, "show_graph_tracks", icon='ANIM', text="")
66                 else:
67                     row.prop(sc, "show_filters", icon='DISCLOSURE_TRI_RIGHT',
68                         text="Filters")
69
70         row = layout.row()
71         row.template_ID(sc, "clip", open='clip.open')
72
73         if clip:
74             tracking = clip.tracking
75             active = tracking.objects.active
76
77             if active and not active.is_camera:
78                 r = active.reconstruction
79             else:
80                 r = tracking.reconstruction
81
82             if r.is_valid:
83                 layout.label(text="Average solve error: %.4f" %
84                     (r.average_error))
85
86         layout.template_running_jobs()
87
88
89 class CLIP_PT_tools_marker(Panel):
90     bl_space_type = 'CLIP_EDITOR'
91     bl_region_type = 'TOOLS'
92     bl_label = "Marker"
93
94     @classmethod
95     def poll(cls, context):
96         sc = context.space_data
97         clip = sc.clip
98
99         return clip and sc.mode == 'TRACKING'
100
101     def draw(self, context):
102         sc = context.space_data
103         clip = sc.clip
104         settings = clip.tracking.settings
105         layout = self.layout
106
107         col = layout.column(align=True)
108         col.operator("clip.add_marker_move")
109         col.operator("clip.detect_features")
110         col.operator("clip.delete_track")
111
112         box = layout.box()
113         row = box.row(align=True)
114         row.prop(settings, "show_default_expanded", text="", emboss=False)
115         row.label(text="Tracking Settings")
116
117         if settings.show_default_expanded:
118             col = box.column()
119             row = col.row(align=True)
120             label = bpy.types.CLIP_MT_tracking_settings_presets.bl_label
121             row.menu('CLIP_MT_tracking_settings_presets', text=label)
122             row.operator("clip.tracking_settings_preset_add",
123                          text="", icon='ZOOMIN')
124             props = row.operator("clip.tracking_settings_preset_add",
125                                  text="", icon='ZOOMOUT')
126             props.remove_active = True
127
128             col.separator()
129
130             sub = col.column(align=True)
131             sub.prop(settings, "default_pattern_size")
132             sub.prop(settings, "default_search_size")
133
134             col.label(text="Tracker:")
135             col.prop(settings, "default_tracker", text="")
136
137             if settings.default_tracker == 'KLT':
138                 col.prop(settings, "default_pyramid_levels")
139             col.prop(settings, "default_correlation_min")
140
141             col.separator()
142
143             sub = col.column(align=True)
144             sub.prop(settings, "default_frames_limit")
145             sub.prop(settings, "default_margin")
146
147             col.label(text="Match:")
148             col.prop(settings, "default_pattern_match", text="")
149
150
151 class CLIP_PT_tools_tracking(Panel):
152     bl_space_type = 'CLIP_EDITOR'
153     bl_region_type = 'TOOLS'
154     bl_label = "Track"
155
156     @classmethod
157     def poll(cls, context):
158         sc = context.space_data
159         clip = sc.clip
160
161         return clip and sc.mode == 'TRACKING'
162
163     def draw(self, context):
164         layout = self.layout
165         # clip = context.space_data.clip  # UNUSED
166
167         row = layout.row(align=True)
168
169         props = row.operator("clip.track_markers", text="", icon='FRAME_PREV')
170         props.backwards = True
171         props = row.operator("clip.track_markers", text="",
172              icon='PLAY_REVERSE')
173         props.backwards = True
174         props.sequence = True
175         props = row.operator("clip.track_markers", text="", icon='PLAY')
176         props.sequence = True
177         row.operator("clip.track_markers", text="", icon='FRAME_NEXT')
178
179         col = layout.column(align=True)
180         props = col.operator("clip.clear_track_path", text="Clear After")
181         props.action = 'REMAINED'
182
183         props = col.operator("clip.clear_track_path", text="Clear Before")
184         props.action = 'UPTO'
185
186         props = col.operator("clip.clear_track_path", text="Clear")
187         props.action = 'ALL'
188
189         layout.operator("clip.join_tracks", text="Join")
190
191
192 class CLIP_PT_tools_solve(Panel):
193     bl_space_type = 'CLIP_EDITOR'
194     bl_region_type = 'TOOLS'
195     bl_label = "Solve"
196
197     @classmethod
198     def poll(cls, context):
199         sc = context.space_data
200         clip = sc.clip
201
202         return clip and sc.mode == 'TRACKING'
203
204     def draw(self, context):
205         layout = self.layout
206         clip = context.space_data.clip
207         tracking = clip.tracking
208         settings = tracking.settings
209         tracking_object = tracking.objects.active
210
211         col = layout.column(align=True)
212
213         col.operator("clip.solve_camera",
214                      text="Camera Motion" if tracking_object.is_camera
215                      else "Object Motion")
216         col.operator("clip.clear_solution")
217
218         col = layout.column(align=True)
219         col.prop(settings, "keyframe_a")
220         col.prop(settings, "keyframe_b")
221
222         col = layout.column(align=True)
223         col.active = tracking_object.is_camera
224         col.label(text="Refine:")
225         col.prop(settings, "refine_intrinsics", text="")
226
227
228 class CLIP_PT_tools_cleanup(Panel):
229     bl_space_type = 'CLIP_EDITOR'
230     bl_region_type = 'TOOLS'
231     bl_label = "Clean up"
232
233     @classmethod
234     def poll(cls, context):
235         sc = context.space_data
236         clip = sc.clip
237
238         return clip and sc.mode == 'TRACKING'
239
240     def draw(self, context):
241         layout = self.layout
242         clip = context.space_data.clip
243         settings = clip.tracking.settings
244
245         layout.operator("clip.clean_tracks")
246
247         layout.prop(settings, 'clean_frames', text="Frames")
248         layout.prop(settings, 'clean_error', text="Error")
249         layout.prop(settings, 'clean_action', text="")
250
251
252 class CLIP_PT_tools_geometry(Panel):
253     bl_space_type = 'CLIP_EDITOR'
254     bl_region_type = 'TOOLS'
255     bl_label = "Geometry"
256
257     @classmethod
258     def poll(cls, context):
259         sc = context.space_data
260         clip = sc.clip
261
262         return clip and sc.mode == 'RECONSTRUCTION'
263
264     def draw(self, context):
265         layout = self.layout
266
267         layout.operator("clip.bundles_to_mesh")
268         layout.operator("clip.track_to_empty")
269
270
271 class CLIP_PT_tools_orientation(Panel):
272     bl_space_type = 'CLIP_EDITOR'
273     bl_region_type = 'TOOLS'
274     bl_label = "Orientation"
275
276     @classmethod
277     def poll(cls, context):
278         sc = context.space_data
279         clip = sc.clip
280
281         return clip and sc.mode == 'RECONSTRUCTION'
282
283     def draw(self, context):
284         sc = context.space_data
285         layout = self.layout
286         settings = sc.clip.tracking.settings
287
288         col = layout.column(align=True)
289         col.operator("clip.set_floor")
290         col.operator("clip.set_origin")
291
292         row = col.row()
293         row.operator("clip.set_axis", text="Set X Axis").axis = 'X'
294         row.operator("clip.set_axis", text="Set Y Axis").axis = 'Y'
295
296         layout.separator()
297
298         col = layout.column()
299         col.operator("clip.set_scale")
300         col.prop(settings, "distance")
301
302
303 class CLIP_PT_tools_object(Panel):
304     bl_space_type = 'CLIP_EDITOR'
305     bl_region_type = 'TOOLS'
306     bl_label = "Object"
307
308     @classmethod
309     def poll(cls, context):
310         sc = context.space_data
311         clip = sc.clip
312
313         if clip and sc.mode == 'RECONSTRUCTION':
314             tracking_object = clip.tracking.objects.active
315             return not tracking_object.is_camera
316
317         return False
318
319     def draw(self, context):
320         layout = self.layout
321
322         sc = context.space_data
323         clip = sc.clip
324         tracking_object = clip.tracking.objects.active
325         settings = sc.clip.tracking.settings
326
327         col = layout.column()
328
329         col.prop(tracking_object, "scale")
330
331         col.separator()
332
333         col.operator("clip.set_solution_scale", text="Set Scale")
334         col.prop(settings, "object_distance")
335
336
337 class CLIP_PT_tools_grease_pencil(Panel):
338     bl_space_type = 'CLIP_EDITOR'
339     bl_region_type = 'TOOLS'
340     bl_label = "Grease Pencil"
341
342     @classmethod
343     def poll(cls, context):
344         sc = context.space_data
345         clip = sc.clip
346
347         return clip and sc.mode == 'DISTORTION'
348
349     def draw(self, context):
350         layout = self.layout
351
352         col = layout.column(align=True)
353
354         row = col.row(align=True)
355         row.operator("gpencil.draw", text="Draw").mode = 'DRAW'
356         row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT'
357
358         row = col.row(align=True)
359         row.operator("gpencil.draw", text="Poly").mode = 'DRAW_POLY'
360         row.operator("gpencil.draw", text="Erase").mode = 'ERASER'
361
362         row = col.row()
363         row.prop(context.tool_settings, "use_grease_pencil_sessions")
364
365
366 class CLIP_PT_objects(Panel):
367     bl_space_type = 'CLIP_EDITOR'
368     bl_region_type = 'UI'
369     bl_label = "Objects"
370     bl_options = {'DEFAULT_CLOSED'}
371
372     @classmethod
373     def poll(cls, context):
374         sc = context.space_data
375
376         return sc.clip
377
378     def draw(self, context):
379         layout = self.layout
380         
381         sc = context.space_data
382         tracking = sc.clip.tracking
383
384         row = layout.row()
385         row.template_list(tracking, "objects",
386                           tracking, "active_object_index", rows=3)
387
388         sub = row.column(align=True)
389
390         sub.operator("clip.tracking_object_new", icon='ZOOMIN', text="")
391         sub.operator("clip.tracking_object_remove", icon='ZOOMOUT', text="")
392
393         active = tracking.objects.active
394         if active:
395             layout.prop(active, "name")
396
397
398 class CLIP_PT_track(Panel):
399     bl_space_type = 'CLIP_EDITOR'
400     bl_region_type = 'UI'
401     bl_label = "Track"
402
403     @classmethod
404     def poll(cls, context):
405         sc = context.space_data
406         clip = sc.clip
407
408         return sc.mode == 'TRACKING' and clip
409
410     def draw(self, context):
411         layout = self.layout
412         sc = context.space_data
413         clip = context.space_data.clip
414         act_track = clip.tracking.tracks.active
415
416         if not act_track:
417             layout.active = False
418             layout.label(text="No active track")
419             return
420
421         row = layout.row()
422         row.prop(act_track, "name", text="")
423
424         sub = row.row(align=True)
425
426         sub.template_marker(sc, "clip", sc.clip_user, act_track, True)
427
428         icon = 'LOCKED' if act_track.lock else 'UNLOCKED'
429         sub.prop(act_track, "lock", text="", icon=icon)
430
431         layout.template_track(sc, "scopes")
432
433         row = layout.row(align=True)
434         sub = row.row()
435         sub.prop(act_track, "use_red_channel", text="R", toggle=True)
436         sub.prop(act_track, "use_green_channel", text="G", toggle=True)
437         sub.prop(act_track, "use_blue_channel", text="B", toggle=True)
438
439         row.separator()
440
441         sub = row.row()
442         sub.prop(act_track, "use_grayscale_preview", text="B/W", toggle=True)
443
444         layout.separator()
445
446         row = layout.row(align=True)
447         label = bpy.types.CLIP_MT_track_color_presets.bl_label
448         row.menu('CLIP_MT_track_color_presets', text=label)
449         row.menu('CLIP_MT_track_color_specials', text="", icon='DOWNARROW_HLT')
450         row.operator("clip.track_color_preset_add", text="", icon='ZOOMIN')
451         props = row.operator("clip.track_color_preset_add",
452                              text="", icon='ZOOMOUT')
453         props.remove_active = True
454
455         row = layout.row()
456         row.prop(act_track, "use_custom_color")
457         if act_track.use_custom_color:
458             row.prop(act_track, "color", text="")
459
460         if act_track.has_bundle:
461             label_text = "Average Error: %.4f" % (act_track.average_error)
462             layout.label(text=label_text)
463
464
465 class CLIP_PT_tracking_camera(Panel):
466     bl_space_type = 'CLIP_EDITOR'
467     bl_region_type = 'UI'
468     bl_label = "Camera Data"
469     bl_options = {'DEFAULT_CLOSED'}
470
471     @classmethod
472     def poll(cls, context):
473         sc = context.space_data
474
475         return sc.mode in {'TRACKING', 'DISTORTION'} and sc.clip
476
477     def draw(self, context):
478         layout = self.layout
479
480         sc = context.space_data
481         clip = sc.clip
482
483         row = layout.row(align=True)
484         label = bpy.types.CLIP_MT_camera_presets.bl_label
485         row.menu('CLIP_MT_camera_presets', text=label)
486         row.operator("clip.camera_preset_add", text="", icon='ZOOMIN')
487         props = row.operator("clip.camera_preset_add", text="", icon='ZOOMOUT')
488         props.remove_active = True
489
490         row = layout.row(align=True)
491         sub = row.split(percentage=0.65)
492         if clip.tracking.camera.units == 'MILLIMETERS':
493             sub.prop(clip.tracking.camera, "focal_length")
494         else:
495             sub.prop(clip.tracking.camera, "focal_length_pixels")
496         sub.prop(clip.tracking.camera, "units", text="")
497
498         col = layout.column(align=True)
499         col.label(text="Sensor:")
500         col.prop(clip.tracking.camera, "sensor_width", text="Width")
501         col.prop(clip.tracking.camera, "pixel_aspect")
502
503         col = layout.column()
504         col.label(text="Optical Center:")
505         row = col.row()
506         row.prop(clip.tracking.camera, "principal", text="")
507         col.operator("clip.set_center_principal", text="Center")
508
509         col = layout.column(align=True)
510         col.label(text="Lens Distortion:")
511         col.prop(clip.tracking.camera, "k1")
512         col.prop(clip.tracking.camera, "k2")
513         col.prop(clip.tracking.camera, "k3")
514
515
516 class CLIP_PT_display(Panel):
517     bl_space_type = 'CLIP_EDITOR'
518     bl_region_type = 'UI'
519     bl_label = "Display"
520
521     def draw(self, context):
522         layout = self.layout
523         sc = context.space_data
524
525         col = layout.column(align=True)
526
527         col.prop(sc, "show_marker_pattern", text="Pattern")
528         col.prop(sc, "show_marker_search", text="Search")
529         col.prop(sc, "show_pyramid_levels", text="Pyramid")
530
531         col.prop(sc, "show_track_path", text="Path")
532         row = col.row()
533         row.active = sc.show_track_path
534         row.prop(sc, "path_length", text="Length")
535
536         col.prop(sc, "show_disabled", "Disabled Tracks")
537         col.prop(sc, "show_bundles", text="3D Markers")
538
539         col.prop(sc, "show_names", text="Names and Status")
540         col.prop(sc, "show_tiny_markers", text="Compact Markers")
541
542         col.prop(sc, "show_grease_pencil", text="Grease Pencil")
543         col.prop(sc, "use_mute_footage", text="Mute")
544
545         if sc.mode == 'DISTORTION':
546             col.prop(sc, "show_grid", text="Grid")
547             col.prop(sc, "use_manual_calibration")
548         elif sc.mode == 'RECONSTRUCTION':
549             col.prop(sc, "show_stable", text="Stable")
550
551         col.prop(sc, "lock_selection")
552
553         clip = sc.clip
554         if clip:
555             col.label(text="Display Aspect Ratio:")
556             col.prop(clip, "display_aspect", text="")
557
558
559 class CLIP_PT_track_settings(Panel):
560     bl_space_type = 'CLIP_EDITOR'
561     bl_region_type = 'UI'
562     bl_label = "Tracking Settings"
563     bl_options = {'DEFAULT_CLOSED'}
564
565     @classmethod
566     def poll(cls, context):
567         sc = context.space_data
568
569         return sc.mode == 'TRACKING' and sc.clip
570
571     def draw(self, context):
572         layout = self.layout
573         clip = context.space_data.clip
574         settings = clip.tracking.settings
575
576         col = layout.column()
577
578         active = clip.tracking.tracks.active
579         if active:
580             col.prop(active, "tracker")
581
582             if active.tracker == 'KLT':
583                 col.prop(active, "pyramid_levels")
584             col.prop(active, "correlation_min")
585
586             col.separator()
587             col.prop(active, "frames_limit")
588             col.prop(active, "margin")
589             col.prop(active, "pattern_match", text="Match")
590
591         col.prop(settings, "speed")
592
593
594 class CLIP_PT_stabilization(Panel):
595     bl_space_type = 'CLIP_EDITOR'
596     bl_region_type = 'UI'
597     bl_label = "2D Stabilization"
598     bl_options = {'DEFAULT_CLOSED'}
599
600     @classmethod
601     def poll(cls, context):
602         sc = context.space_data
603
604         return sc.mode == 'RECONSTRUCTION' and sc.clip
605
606     def draw_header(self, context):
607         stab = context.space_data.clip.tracking.stabilization
608
609         self.layout.prop(stab, "use_2d_stabilization", text="")
610
611     def draw(self, context):
612         layout = self.layout
613
614         tracking = context.space_data.clip.tracking
615         stab = tracking.stabilization
616
617         layout.active = stab.use_2d_stabilization
618
619         row = layout.row()
620         row.template_list(stab, "tracks", stab, "active_track_index", rows=3)
621
622         sub = row.column(align=True)
623
624         sub.operator("clip.stabilize_2d_add", icon='ZOOMIN', text="")
625         sub.operator("clip.stabilize_2d_remove", icon='ZOOMOUT', text="")
626
627         sub.menu('CLIP_MT_stabilize_2d_specials', text="",
628                  icon='DOWNARROW_HLT')
629
630         layout.prop(stab, "influence_location")
631
632         layout.prop(stab, "use_autoscale")
633         col = layout.column()
634         col.active = stab.use_autoscale
635         col.prop(stab, "scale_max")
636         col.prop(stab, "influence_scale")
637
638         layout.prop(stab, "use_stabilize_rotation")
639         col = layout.column()
640         col.active = stab.use_stabilize_rotation
641
642         row = col.row(align=True)
643         row.prop_search(stab, "rotation_track", tracking, "tracks", text="")
644         row.operator("clip.stabilize_2d_set_rotation", text="", icon='ZOOMIN')
645
646         row = col.row()
647         row.active = stab.rotation_track is not None
648         row.prop(stab, "influence_rotation")
649
650
651 class CLIP_PT_marker(Panel):
652     bl_space_type = 'CLIP_EDITOR'
653     bl_region_type = 'UI'
654     bl_label = "Marker"
655     bl_options = {'DEFAULT_CLOSED'}
656
657     @classmethod
658     def poll(cls, context):
659         sc = context.space_data
660         clip = sc.clip
661
662         return sc.mode == 'TRACKING' and clip
663
664     def draw(self, context):
665         layout = self.layout
666         sc = context.space_data
667         clip = context.space_data.clip
668         act_track = clip.tracking.tracks.active
669
670         if act_track:
671             layout.template_marker(sc, "clip", sc.clip_user, act_track, False)
672         else:
673             layout.active = False
674             layout.label(text="No active track")
675
676
677 class CLIP_PT_proxy(Panel):
678     bl_space_type = 'CLIP_EDITOR'
679     bl_region_type = 'UI'
680     bl_label = "Proxy / Timecode"
681     bl_options = {'DEFAULT_CLOSED'}
682
683     @classmethod
684     def poll(cls, context):
685         sc = context.space_data
686
687         return sc.clip
688
689     def draw_header(self, context):
690         sc = context.space_data
691
692         self.layout.prop(sc.clip, "use_proxy", text="")
693
694     def draw(self, context):
695         layout = self.layout
696         sc = context.space_data
697         clip = sc.clip
698
699         layout.active = clip.use_proxy
700
701         layout.label(text="Build Sizes:")
702
703         row = layout.row()
704         row.prop(clip.proxy, "build_25")
705         row.prop(clip.proxy, "build_50")
706
707         row = layout.row()
708         row.prop(clip.proxy, "build_75")
709         row.prop(clip.proxy, "build_100")
710
711         layout.prop(clip.proxy, "build_undistorted")
712
713         layout.prop(clip.proxy, "quality")
714
715         layout.prop(clip, 'use_proxy_custom_directory')
716         if clip.use_proxy_custom_directory:
717             layout.prop(clip.proxy, "directory")
718
719         layout.operator("clip.rebuild_proxy", text="Rebuild Proxy")
720
721         if clip.source == 'MOVIE':
722             col = layout.column()
723
724             col.label(text="Use timecode index:")
725             col.prop(clip.proxy, "timecode", text="")
726
727         col = layout.column()
728         col.label(text="Proxy render size:")
729
730         col.prop(sc.clip_user, "proxy_render_size", text="")
731         col.prop(sc.clip_user, "use_render_undistorted")
732
733
734 class CLIP_PT_footage(Panel):
735     bl_space_type = 'CLIP_EDITOR'
736     bl_region_type = 'UI'
737     bl_label = "Footage Settings"
738     bl_options = {'DEFAULT_CLOSED'}
739
740     @classmethod
741     def poll(cls, context):
742         sc = context.space_data
743
744         return sc.clip
745
746     def draw(self, context):
747         layout = self.layout
748
749         sc = context.space_data
750         clip = sc.clip
751
752         if clip:
753             layout.template_movieclip(sc, "clip", compact=True)
754         else:
755             layout.operator("clip.open", icon='FILESEL')
756
757
758 class CLIP_PT_tools_clip(Panel):
759     bl_space_type = 'CLIP_EDITOR'
760     bl_region_type = 'TOOLS'
761     bl_label = "Clip"
762
763     @classmethod
764     def poll(cls, context):
765         sc = context.space_data
766
767         return sc.clip
768
769     def draw(self, context):
770         layout = self.layout
771
772         layout.operator("clip.set_viewport_background")
773         layout.operator("clip.setup_tracking_scene")
774
775
776 class CLIP_MT_view(Menu):
777     bl_label = "View"
778
779     def draw(self, context):
780         layout = self.layout
781
782         layout.operator("clip.properties", icon='MENU_PANEL')
783         layout.operator("clip.tools", icon='MENU_PANEL')
784         layout.separator()
785
786         layout.operator("clip.view_selected")
787         layout.operator("clip.view_all")
788
789         layout.separator()
790         layout.operator("clip.view_zoom_in")
791         layout.operator("clip.view_zoom_out")
792
793         layout.separator()
794
795         ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1))
796
797         for a, b in ratios:
798             text = "Zoom %d:%d" % (a, b)
799             layout.operator("clip.view_zoom_ratio", text=text).ratio = a / b
800
801         layout.separator()
802         layout.operator("screen.area_dupli")
803         layout.operator("screen.screen_full_area")
804
805
806 class CLIP_MT_clip(Menu):
807     bl_label = "Clip"
808
809     def draw(self, context):
810         layout = self.layout
811
812         sc = context.space_data
813         clip = sc.clip
814
815         layout.operator("clip.open")
816
817         if clip:
818             layout.operator("clip.reload")
819             layout.menu("CLIP_MT_proxy")
820
821
822 class CLIP_MT_proxy(Menu):
823     bl_label = "Proxy"
824
825     def draw(self, context):
826         layout = self.layout
827
828         layout.operator("clip.rebuild_proxy")
829         layout.operator("clip.delete_proxy")
830
831
832 class CLIP_MT_track(Menu):
833     bl_label = "Track"
834
835     def draw(self, context):
836         layout = self.layout
837
838         layout.operator("clip.clear_solution")
839         layout.operator("clip.solve_camera")
840
841         layout.separator()
842         props = layout.operator("clip.clear_track_path", text="Clear After")
843         props.action = 'REMAINED'
844
845         props = layout.operator("clip.clear_track_path", text="Clear Before")
846         props.action = 'UPTO'
847
848         props = layout.operator("clip.clear_track_path",
849             text="Clear Track Path")
850         props.action = 'ALL'
851
852         layout.separator()
853         layout.operator("clip.join_tracks")
854
855         layout.separator()
856         layout.operator("clip.clean_tracks")
857
858         layout.separator()
859         layout.operator("clip.copy_tracks")
860         layout.operator("clip.paste_tracks")
861
862         layout.separator()
863         props = layout.operator("clip.track_markers",
864             text="Track Frame Backwards")
865         props.backwards = True
866
867         props = layout.operator("clip.track_markers", text="Track Backwards")
868         props.backwards = True
869         props.sequence = True
870
871         props = layout.operator("clip.track_markers", text="Track Forwards")
872         props.sequence = True
873         layout.operator("clip.track_markers", text="Track Frame Forwards")
874
875         layout.separator()
876         layout.operator("clip.delete_track")
877         layout.operator("clip.delete_marker")
878
879         layout.separator()
880         layout.operator("clip.add_marker_move")
881
882         layout.separator()
883         layout.menu("CLIP_MT_track_visibility")
884         layout.menu("CLIP_MT_track_transform")
885
886
887 class CLIP_MT_reconstruction(Menu):
888     bl_label = "Reconstruction"
889
890     def draw(self, context):
891         layout = self.layout
892
893         layout.operator("clip.set_origin")
894         layout.operator("clip.set_floor")
895
896         layout.operator("clip.set_axis", text="Set X Axis").axis = "X"
897         layout.operator("clip.set_axis", text="Set Y Axis").axis = "Y"
898
899         layout.operator("clip.set_scale")
900
901         layout.separator()
902
903         layout.operator("clip.track_to_empty")
904         layout.operator("clip.bundles_to_mesh")
905
906
907 class CLIP_MT_track_visibility(Menu):
908     bl_label = "Show/Hide"
909
910     def draw(self, context):
911         layout = self.layout
912
913         layout.operator("clip.hide_tracks_clear", text="Show Hidden")
914         layout.operator("clip.hide_tracks", text="Hide Selected")
915
916         props = layout.operator("clip.hide_tracks", text="Hide Unselected")
917         props.unselected = True
918
919
920 class CLIP_MT_track_transform(Menu):
921     bl_label = "Transform"
922
923     def draw(self, context):
924         layout = self.layout
925
926         layout.operator("transform.translate")
927         layout.operator("transform.resize")
928
929
930 class CLIP_MT_select(Menu):
931     bl_label = "Select"
932
933     def draw(self, context):
934         layout = self.layout
935
936         layout.operator("clip.select_border")
937         layout.operator("clip.select_circle")
938
939         layout.separator()
940
941         layout.operator("clip.select_all", text="Select/Deselect all")
942         layout.operator("clip.select_all", text="Inverse").action = 'INVERT'
943
944         layout.menu("CLIP_MT_select_grouped")
945
946
947 class CLIP_MT_select_grouped(Menu):
948     bl_label = "Select Grouped"
949
950     def draw(self, context):
951         layout = self.layout
952
953         layout.operator_enum("clip.select_grouped", "group")
954
955
956 class CLIP_MT_tracking_specials(Menu):
957     bl_label = "Specials"
958
959     @classmethod
960     def poll(cls, context):
961         return context.space_data.clip
962
963     def draw(self, context):
964         layout = self.layout
965
966         props = layout.operator("clip.disable_markers", text="Enable Markers")
967         props.action = 'ENABLE'
968
969         props = layout.operator("clip.disable_markers", text="Disable markers")
970         props.action = 'DISABLE'
971
972         layout.separator()
973         layout.operator("clip.set_origin")
974
975         layout.separator()
976         layout.operator("clip.hide_tracks")
977         layout.operator("clip.hide_tracks_clear", text="Show Tracks")
978
979         layout.separator()
980         props = layout.operator("clip.lock_tracks", text="Lock Tracks")
981         props.action = 'LOCK'
982
983         props = layout.operator("clip.lock_tracks", text="Unlock Tracks")
984         props.action = 'UNLOCK'
985
986
987 class CLIP_MT_camera_presets(Menu):
988     """Predefined tracking camera intrinsics"""
989     bl_label = "Camera Presets"
990     preset_subdir = "tracking_camera"
991     preset_operator = "script.execute_preset"
992     draw = bpy.types.Menu.draw_preset
993
994
995 class CLIP_MT_track_color_presets(Menu):
996     """Predefined track color"""
997     bl_label = "Color Presets"
998     preset_subdir = "tracking_track_color"
999     preset_operator = "script.execute_preset"
1000     draw = bpy.types.Menu.draw_preset
1001
1002
1003 class CLIP_MT_tracking_settings_presets(Menu):
1004     """Predefined tracking settings"""
1005     bl_label = "Tracking Presets"
1006     preset_subdir = "tracking_settings"
1007     preset_operator = "script.execute_preset"
1008     draw = bpy.types.Menu.draw_preset
1009
1010
1011 class CLIP_MT_track_color_specials(Menu):
1012     bl_label = "Track Color Specials"
1013
1014     def draw(self, context):
1015         layout = self.layout
1016
1017         layout.operator('clip.track_copy_color', icon='COPY_ID')
1018
1019
1020 class CLIP_MT_stabilize_2d_specials(Menu):
1021     bl_label = "Track Color Specials"
1022
1023     def draw(self, context):
1024         layout = self.layout
1025
1026         layout.operator('clip.stabilize_2d_select')
1027
1028 if __name__ == "__main__":  # only for live edit.
1029     bpy.utils.register_module(__name__)