Merging r39312 through r39329 from trunk into soc-2011-tomato
[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 compliant>
20 import bpy
21
22
23 class CLIP_OT_apply_follow_track(bpy.types.Operator):
24     bl_idname = "clip.apply_follow_track"
25     bl_label = "Apply Follow Track"
26     bl_options = {'UNDO', 'REGISTER'}
27
28     @classmethod
29     def poll(cls, context):
30         if context.space_data.type != 'CLIP_EDITOR':
31             return False
32
33         sc = context.space_data
34         clip = sc.clip
35
36         return clip and clip.tracking.active_track and context.active_object
37
38     def execute(self, context):
39         ob = context.active_object
40         sc = context.space_data
41         clip = sc.clip
42         track = clip.tracking.active_track
43         constraint = None
44
45         for con in ob.constraints:
46             if con.type == 'FOLLOW_TRACK':
47                 constraint = con
48                 break
49
50         if constraint is None:
51             constraint = ob.constraints.new(type='FOLLOW_TRACK')
52
53         constraint.clip = sc.clip
54         constraint.track = track.name
55         constraint.reference = 'TRACK'
56
57         return {'FINISHED'}
58
59
60 class CLIP_OT_bundles_to_mesh(bpy.types.Operator):
61     bl_idname = "clip.bundles_to_mesh"
62     bl_label = "Bundles to Mesh"
63     bl_options = {'UNDO', 'REGISTER'}
64
65     @classmethod
66     def poll(cls, context):
67         if context.space_data.type != 'CLIP_EDITOR':
68             return False
69
70         sc = context.space_data
71         clip = sc.clip
72
73         return clip
74
75     def execute(self, context):
76         sc = context.space_data
77         clip = sc.clip
78
79         mesh = bpy.data.meshes.new(name="Bundles")
80         for track in clip.tracking.tracks:
81             if track.has_bundle:
82                 mesh.vertices.add(1)
83                 mesh.vertices[-1].co = track.bundle
84
85         ob = bpy.data.objects.new(name="Bundles", object_data=mesh)
86
87         bpy.context.scene.objects.link(ob)
88
89         return {'FINISHED'}
90
91
92 class CLIP_HT_header(bpy.types.Header):
93     bl_space_type = 'CLIP_EDITOR'
94
95     def draw(self, context):
96         layout = self.layout
97
98         sc = context.space_data
99         clip = sc.clip
100
101         row = layout.row(align=True)
102         row.template_header()
103
104         if context.area.show_menus:
105             sub = row.row(align=True)
106             sub.menu("CLIP_MT_view")
107             sub.menu("CLIP_MT_clip")
108
109             if clip:
110                 sub.menu("CLIP_MT_select")
111                 sub.menu("CLIP_MT_track")
112
113         layout.template_ID(sc, "clip")
114         layout.template_running_jobs()
115
116         if clip:
117             r = clip.tracking.reconstruction
118
119             if r.is_reconstructed:
120                 layout.label(text="Average solve error: %.4f"  % (r.average_error))
121
122
123 class CLIP_PT_tools(bpy.types.Panel):
124     bl_space_type = 'CLIP_EDITOR'
125     bl_region_type = 'TOOLS'
126     bl_label = "Tools"
127
128     def draw(self, context):
129         layout = self.layout
130         clip = context.space_data.clip
131
132         if clip:
133             settings = clip.tracking.settings
134
135             col = layout.column(align=True)
136             col.label(text="Marker:")
137             col.operator("clip.add_marker_move")
138             col.operator("clip.delete_track")
139             col.operator("clip.delete_marker")
140
141             col = layout.column(align=True)
142             col.label(text="2D tracking:")
143             row = col.row(align=True)
144
145             op = row.operator("clip.track_markers", text="", icon='FRAME_PREV')
146             op.backwards = True
147             op = row.operator("clip.track_markers", text="", \
148                  icon='PLAY_REVERSE')
149             op.backwards = True
150             op.sequence = True
151             op = row.operator("clip.track_markers", text="", icon='PLAY')
152             op.sequence = True
153             row.operator("clip.track_markers", text="", icon='FRAME_NEXT')
154
155             col = layout.column(align=True)
156             op = col.operator("clip.clear_track_path", \
157                  text="Clear Remained Path")
158             op.action = 'REMAINED'
159
160             op = col.operator("clip.clear_track_path", text="Clear Path Up To")
161             op.action = 'UPTO'
162
163             op = col.operator("clip.clear_track_path", text="Clear Track Path")
164             op.action = 'ALL'
165
166             layout.operator("clip.join_tracks")
167             layout.operator("clip.detect_features")
168             layout.operator("clip.apply_follow_track")
169
170             col = layout.column(align=True)
171             col.label(text="Reconstruction:")
172
173             col.prop(settings, "keyframe1")
174             col.prop(settings, "keyframe2")
175
176             col = layout.column(align=True)
177             col.operator("clip.solve_camera")
178             col.operator("clip.clear_reconstruction")
179
180             col = layout.column(align=True)
181             col.operator("clip.bundles_to_mesh")
182
183             col = layout.column(align=True)
184             col.label(text="Scene Orientation:")
185             col.operator("clip.set_floor")
186             col.operator("clip.set_origin")
187
188             row = col.row()
189             row.operator("clip.set_axis", text="Set X Axis").axis = 'X'
190             row.operator("clip.set_axis", text="Set Y Axis").axis = 'Y'
191
192             col = layout.column()
193             col.prop(settings, "distance")
194             col.operator("clip.set_scale")
195
196             col = layout.column(align=True)
197             col.label(text="Clean-up:")
198             col.operator("clip.clean_tracks")
199         else:
200             layout.operator('clip.open')
201
202
203 class CLIP_PT_track(bpy.types.Panel):
204     bl_space_type = 'CLIP_EDITOR'
205     bl_region_type = 'UI'
206     bl_label = "Track"
207
208     @classmethod
209     def poll(cls, context):
210         sc = context.space_data
211         clip = sc.clip
212
213         return clip and clip.tracking.active_track
214
215     def draw(self, context):
216         layout = self.layout
217         sc = context.space_data
218         clip = context.space_data.clip
219         act_track = clip.tracking.active_track
220
221         layout.prop(act_track, "name")
222         layout.prop(act_track, "locked")
223
224         row = layout.row(align=True)
225         label = bpy.types.CLIP_MT_track_color_presets.bl_label
226         row.menu('CLIP_MT_track_color_presets', text=label)
227         row.menu('CLIP_MT_track_color_specials', text="", icon="DOWNARROW_HLT")
228         row.operator("clip.track_color_preset_add", text="", icon="ZOOMIN")
229         op = row.operator("clip.track_color_preset_add", \
230             text="", icon="ZOOMOUT")
231         op.remove_active = True
232
233         row = layout.row()
234         row.prop(act_track, "use_custom_color")
235         if act_track.use_custom_color:
236             row.prop(act_track, "color", text="")
237
238         layout.template_track(sc, "scopes")
239
240         row = layout.row()
241         row.prop(act_track, "use_red_channel", text="Red")
242         row.prop(act_track, "use_green_channel", text="Green")
243         row.prop(act_track, "use_blue_channel", text="Blue")
244
245         if act_track.has_bundle:
246             label_text = "Average Error: %.4f" % (act_track.average_error)
247             layout.label(text=label_text)
248
249
250 class CLIP_PT_track_settings(bpy.types.Panel):
251     bl_space_type = 'CLIP_EDITOR'
252     bl_region_type = 'UI'
253     bl_label = "Tracking Settings"
254     bl_options = {'DEFAULT_CLOSED'}
255
256     @classmethod
257     def poll(cls, context):
258         sc = context.space_data
259
260         return sc.clip
261
262     def draw(self, context):
263         layout = self.layout
264         clip = context.space_data.clip
265         settings = clip.tracking.settings
266
267         layout.label(text="2D tracking:")
268         layout.prop(settings, "speed")
269         layout.prop(settings, "use_frames_limit")
270
271         row = layout.row()
272         row.active = settings.use_frames_limit
273         row.prop(settings, "frames_limit")
274
275
276 class CLIP_PT_tracking_camera(bpy.types.Panel):
277     bl_space_type = 'CLIP_EDITOR'
278     bl_region_type = 'UI'
279     bl_label = "Camera Data"
280     bl_options = {'DEFAULT_CLOSED'}
281
282     @classmethod
283     def poll(cls, context):
284         sc = context.space_data
285
286         return sc.clip
287
288     def draw(self, context):
289         layout = self.layout
290
291         sc = context.space_data
292         clip = sc.clip
293
294         row = layout.row(align=True)
295         label = bpy.types.CLIP_MT_camera_presets.bl_label
296         row.menu('CLIP_MT_camera_presets', text=label)
297         row.operator("clip.camera_preset_add", text="", icon="ZOOMIN")
298         op = row.operator("clip.camera_preset_add", text="", icon="ZOOMOUT")
299         op.remove_active = True
300
301         row = layout.row(align=True)
302         sub = row.split(percentage=0.65)
303         sub.prop(clip.tracking.camera, "focal_length")
304         sub.prop(clip.tracking.camera, "units", text="")
305
306         col = layout.column(align=True)
307         col.label(text="Sensor:")
308         col.prop(clip.tracking.camera, "sensor_width", text="Size")
309         col.prop(clip.tracking.camera, "pixel_aspect")
310
311         col = layout.column()
312         col.label(text="Principal Point")
313         row = col.row()
314         row.prop(clip.tracking.camera, "principal", text="")
315         col.operator("clip.set_center_principal", text="Center")
316
317         col = layout.column(align=True)
318         col.label(text="Undistortion:")
319         col.prop(clip.tracking.camera, "k1")
320         col.prop(clip.tracking.camera, "k2")
321         col.prop(clip.tracking.camera, "k3")
322
323
324 class CLIP_PT_display(bpy.types.Panel):
325     bl_space_type = 'CLIP_EDITOR'
326     bl_region_type = 'UI'
327     bl_label = "Display"
328     bl_options = {'DEFAULT_CLOSED'}
329
330     def draw(self, context):
331         layout = self.layout
332         sc = context.space_data
333
334         row = layout.row()
335         row.prop(sc, "show_marker_pattern", text="Pattern")
336         row.prop(sc, "show_marker_search", text="Search")
337
338         row = layout.row()
339         row.prop(sc, "show_track_path", text="Path")
340         sub = row.column()
341         sub.active = sc.show_track_path
342         sub.prop(sc, "path_length", text="Length")
343
344         row = layout.row()
345         row.prop(sc, "show_disabled", text="Disabled")
346         row.prop(sc, "show_bundles", text="Bundles")
347
348         row = layout.row()
349         row.prop(sc, "show_names", text="Names")
350         row.prop(sc, "show_grid", text="Grid")
351
352         row = layout.row()
353         row.prop(sc, "show_tiny_markers", text="Tiny Markers")
354         row.prop(sc, "show_stable", text="Stable")
355
356         layout.prop(sc, "lock_selection")
357         layout.prop(sc, "use_mute_footage")
358         layout.prop(sc, "use_manual_calibration")
359
360         clip = sc.clip
361         if clip:
362             layout.label(text="Display Aspect:")
363             layout.prop(clip, "display_aspect", text="")
364
365
366 class CLIP_PT_stabilization(bpy.types.Panel):
367     bl_space_type = 'CLIP_EDITOR'
368     bl_region_type = 'UI'
369     bl_label = "2D Stabilization"
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_header(self, context):
379         sc = context.space_data
380         tracking = sc.clip.tracking
381         stab = tracking.stabilization
382
383         self.layout.prop(stab, "use_2d_stabilization", text="")
384
385     def draw(self, context):
386         layout = self.layout
387         sc = context.space_data
388         tracking = sc.clip.tracking
389         stab = tracking.stabilization
390
391         layout.active = stab.use_2d_stabilization
392
393
394         row = layout.row()
395         row.template_list(stab, "tracks", stab, "active_track_index", rows=3)
396
397         sub = row.column(align=True)
398         sub.operator("clip.stabilize_2d_add", icon='ZOOMIN', text="")
399         sub.operator("clip.stabilize_2d_remove", icon='ZOOMOUT', text="")
400         sub.menu('CLIP_MT_stabilize_2d_specials', text="", icon="DOWNARROW_HLT")
401
402         layout.prop(stab, "influence_location")
403
404         layout.prop(stab, "use_autoscale")
405         row = layout.row()
406         row.active = stab.use_autoscale
407         row.prop(stab, "influence_scale")
408
409
410 class CLIP_PT_proxy(bpy.types.Panel):
411     bl_space_type = 'CLIP_EDITOR'
412     bl_region_type = 'UI'
413     bl_label = "Proxy / Timecode"
414     bl_options = {'DEFAULT_CLOSED'}
415
416     @classmethod
417     def poll(cls, context):
418         sc = context.space_data
419
420         return sc.clip
421
422     def draw_header(self, context):
423         sc = context.space_data
424
425         self.layout.prop(sc.clip, "use_proxy", text="")
426
427     def draw(self, context):
428         layout = self.layout
429         sc = context.space_data
430         clip = sc.clip
431
432         layout.active = clip.use_proxy
433
434         layout.label(text="Build Sizes:")
435         row = layout.row()
436         row.prop(clip.proxy, "build_25")
437         row.prop(clip.proxy, "build_50")
438         row.prop(clip.proxy, "build_75")
439
440         layout.prop(clip.proxy, "quality")
441
442         layout.prop(clip, 'use_proxy_custom_directory')
443         if clip.use_proxy_custom_directory:
444            layout.prop(clip.proxy, "directory")
445
446         layout.operator("clip.rebuild_proxy", text="Rebuild Proxy")
447
448         if clip.source == 'MOVIE':
449             col = layout.column()
450
451             col.label(text="Use timecode index:")
452             col.prop(clip.proxy, "timecode", text="")
453
454         col = layout.column()
455         col.label(text="Proxy render size:")
456         col.prop(clip, "proxy_render_size", text="")
457
458
459 class CLIP_PT_footage(bpy.types.Panel):
460     bl_space_type = 'CLIP_EDITOR'
461     bl_region_type = 'UI'
462     bl_label = "Footage Settings"
463     bl_options = {'DEFAULT_CLOSED'}
464
465     @classmethod
466     def poll(cls, context):
467         sc = context.space_data
468
469         return sc.clip
470
471     def draw(self, context):
472         layout = self.layout
473
474         sc = context.space_data
475         clip = sc.clip
476
477         if clip:
478             layout.template_movieclip(sc, "clip", sc.clip_user, compact=True)
479         else:
480             layout.operator("clip.open", icon='FILESEL')
481
482
483 class CLIP_MT_view(bpy.types.Menu):
484     bl_label = "View"
485
486     def draw(self, context):
487         layout = self.layout
488
489         layout.operator("clip.properties", icon='MENU_PANEL')
490         layout.operator("clip.tools", icon='MENU_PANEL')
491         layout.separator()
492
493         layout.operator("clip.view_selected")
494         layout.operator("clip.view_all")
495
496         layout.separator()
497         layout.operator("clip.view_zoom_in")
498         layout.operator("clip.view_zoom_out")
499
500         layout.separator()
501
502         ratios = [[1, 8], [1, 4], [1, 2], [1, 1], [2, 1], [4, 1], [8, 1]]
503
504         for a, b in ratios:
505             text = "Zoom %d:%d" % (a, b)
506             layout.operator("clip.view_zoom_ratio", text=text).ratio = a / b
507
508         layout.separator()
509         layout.operator("screen.area_dupli")
510         layout.operator("screen.screen_full_area")
511
512
513 class CLIP_MT_clip(bpy.types.Menu):
514     bl_label = "Clip"
515
516     def draw(self, context):
517         layout = self.layout
518
519         sc = context.space_data
520         clip = sc.clip
521
522         if clip:
523             layout.operator("clip.reload")
524
525         layout.operator("clip.open")
526
527
528 class CLIP_MT_track(bpy.types.Menu):
529     bl_label = "Track"
530
531     def draw(self, context):
532         layout = self.layout
533
534         layout.operator("clip.set_origin")
535
536         layout.separator()
537         layout.operator("clip.clear_reconstruction")
538         layout.operator("clip.solve_camera")
539
540         layout.separator()
541         op = layout.operator("clip.clear_track_path", \
542              text="Clear Remained Path")
543         op.action = 'REMAINED'
544
545         op = layout.operator("clip.clear_track_path", \
546              text="Clear Path Up To")
547         op.action = 'UPTO'
548
549         op = layout.operator("clip.clear_track_path", \
550              text="Clear Track Path")
551         op.action = 'ALL'
552
553         layout.separator()
554         op = layout.operator("clip.track_markers", \
555             text="Track Frame Backwards")
556         op.backwards = True
557
558         op = layout.operator("clip.track_markers", text="Track Backwards")
559         op.backwards = True
560         op.sequence = True
561
562         op = layout.operator("clip.track_markers", text="Track Forwards")
563         op.sequence = True
564         layout.operator("clip.track_markers", text="Track Frame Forwards")
565
566         layout.separator()
567         layout.operator("clip.delete_track")
568         layout.operator("clip.delete_marker")
569
570         layout.separator()
571         layout.operator("clip.add_marker_move")
572
573         layout.separator()
574         layout.menu("CLIP_MT_track_visibility")
575         layout.menu("CLIP_MT_track_transform")
576
577
578 class CLIP_MT_track_visibility(bpy.types.Menu):
579     bl_label = "Show/Hide"
580
581     def draw(self, context):
582         layout = self.layout
583
584         layout.operator("clip.hide_tracks_clear", text="Show Hidden")
585         layout.operator("clip.hide_tracks", text="Hide Selected")
586
587         op = layout.operator("clip.hide_tracks", text="Hide Unselected")
588         op.unselected = True
589
590
591 class CLIP_MT_track_transform(bpy.types.Menu):
592     bl_label = "Transform"
593
594     def draw(self, context):
595         layout = self.layout
596
597         layout.operator("transform.translate")
598         layout.operator("transform.resize")
599
600
601 class CLIP_MT_select(bpy.types.Menu):
602     bl_label = "Select"
603
604     def draw(self, context):
605         layout = self.layout
606
607         sc = context.space_data
608
609         layout.menu("CLIP_MT_select_grouped")
610         layout.operator("clip.select_border")
611         layout.operator("clip.select_circle")
612         layout.operator("clip.select_all", text="Select/Deselect all")
613         layout.operator("clip.select_all", text="Inverse").action = 'INVERT'
614
615
616 class CLIP_MT_select_grouped(bpy.types.Menu):
617     bl_label = "Select Grouped"
618
619     def draw(self, context):
620         layout = self.layout
621
622         sc = context.space_data
623
624         op = layout.operator("clip.select_grouped", text="Select Keyframed")
625         op.group = 'KEYFRAMED'
626
627         op = layout.operator("clip.select_grouped", text="Select Estimated")
628         op.group = 'ESTIMATED'
629
630         op = layout.operator("clip.select_grouped", text="Select Tracked")
631         op.group = 'TRACKED'
632
633         op = layout.operator("clip.select_grouped", text="Select Locked")
634         op.group = 'LOCKED'
635
636         op = layout.operator("clip.select_grouped", text="Select Disabled")
637         op.group = 'DISABLED'
638
639         op = layout.operator("clip.select_grouped", text="Select Failed")
640         op.group = 'FAILED'
641
642         op = layout.operator("clip.select_grouped", text="Select by Color")
643         op.group = 'COLOR'
644
645
646 class CLIP_MT_tracking_specials(bpy.types.Menu):
647     bl_label = "Specials"
648
649     @classmethod
650     def poll(cls, context):
651         return context.space_data.clip
652
653     def draw(self, context):
654         layout = self.layout
655
656         op = layout.operator("clip.disable_markers", text="Enable Markers")
657         op.action = 'ENABLE'
658
659         op = layout.operator("clip.disable_markers", text="Disable markers")
660         op.action = 'DISABLE'
661
662         layout.separator()
663         layout.operator("clip.set_origin")
664
665         layout.separator()
666         layout.operator("clip.hide_tracks")
667         layout.operator("clip.hide_tracks_clear", text="Show Tracks")
668
669         layout.separator()
670         op = layout.operator("clip.lock_tracks", text="Lock Tracks")
671         op.action = 'LOCK'
672
673         op = layout.operator("clip.lock_tracks", text="Unlock Tracks")
674         op.action = 'UNLOCK'
675
676
677 class CLIP_MT_camera_presets(bpy.types.Menu):
678     bl_label = "Camera Presets"
679     preset_subdir = "tracking_camera"
680     preset_operator = "script.execute_preset"
681     draw = bpy.types.Menu.draw_preset
682
683
684 class CLIP_MT_track_color_presets(bpy.types.Menu):
685     bl_label = "Color Presets"
686     preset_subdir = "tracking_track_color"
687     preset_operator = "script.execute_preset"
688     draw = bpy.types.Menu.draw_preset
689
690
691 class CLIP_MT_track_color_specials(bpy.types.Menu):
692     bl_label = "Track Color Specials"
693
694     def draw(self, context):
695         layout = self.layout
696
697         layout.operator('clip.track_copy_color', icon='COPY_ID')
698
699
700 class CLIP_MT_stabilize_2d_specials(bpy.types.Menu):
701     bl_label = "Track Color Specials"
702
703     def draw(self, context):
704         layout = self.layout
705
706         layout.operator('clip.stabilize_2d_select')
707
708
709 if __name__ == "__main__":  # only for live edit.
710     bpy.utils.register_module(__name__)