space_clip.py 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789
  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. # <pep8-80 compliant>
  19. import bpy
  20. from bpy.types import Panel, Header, Menu, UIList
  21. from bpy.app.translations import pgettext_iface as iface_
  22. from bl_ui.utils import PresetPanel
  23. from bl_ui.properties_grease_pencil_common import (
  24. AnnotationDrawingToolsPanel,
  25. AnnotationDataPanel,
  26. )
  27. class CLIP_UL_tracking_objects(UIList):
  28. def draw_item(self, _context, layout, _data, item, _icon,
  29. _active_data, _active_propname, _index):
  30. # assert(isinstance(item, bpy.types.MovieTrackingObject)
  31. tobj = item
  32. if self.layout_type in {'DEFAULT', 'COMPACT'}:
  33. layout.prop(tobj, "name", text="", emboss=False,
  34. icon='CAMERA_DATA' if tobj.is_camera
  35. else 'OBJECT_DATA')
  36. elif self.layout_type == 'GRID':
  37. layout.alignment = 'CENTER'
  38. layout.label(text="",
  39. icon='CAMERA_DATA' if tobj.is_camera
  40. else 'OBJECT_DATA')
  41. class CLIP_PT_display(Panel):
  42. bl_space_type = 'CLIP_EDITOR'
  43. bl_region_type = 'HEADER'
  44. bl_label = "Clip Display"
  45. bl_ui_units_x = 13
  46. def draw(self, context):
  47. pass
  48. class CLIP_PT_marker_display(Panel):
  49. bl_space_type = 'CLIP_EDITOR'
  50. bl_region_type = 'HEADER'
  51. bl_label = "Marker Display"
  52. bl_parent_id = 'CLIP_PT_display'
  53. bl_ui_units_x = 13
  54. def draw(self, context):
  55. layout = self.layout
  56. view = context.space_data
  57. row = layout.row()
  58. col = row.column()
  59. col.prop(view, "show_marker_pattern", text="Pattern")
  60. col.prop(view, "show_marker_search", text="Search")
  61. col.active = view.show_track_path
  62. col.prop(view, "show_track_path", text="Path")
  63. col.prop(view, "path_length", text="Length")
  64. col = row.column()
  65. col.prop(view, "show_disabled", text="Show Disabled")
  66. col.prop(view, "show_names", text="Info")
  67. if view.mode != 'MASK':
  68. col.prop(view, "show_bundles", text="3D Markers")
  69. col.prop(view, "show_tiny_markers", text="Display Thin")
  70. class CLIP_PT_clip_display(Panel):
  71. bl_space_type = 'CLIP_EDITOR'
  72. bl_region_type = 'HEADER'
  73. bl_label = "Clip Display"
  74. bl_parent_id = 'CLIP_PT_display'
  75. bl_ui_units_x = 13
  76. def draw(self, context):
  77. layout = self.layout
  78. sc = context.space_data
  79. col = layout.column(align=True)
  80. row = layout.row(align=True)
  81. row.prop(sc, "show_red_channel", text="R", toggle=True)
  82. row.prop(sc, "show_green_channel", text="G", toggle=True)
  83. row.prop(sc, "show_blue_channel", text="B", toggle=True)
  84. row.separator()
  85. row.prop(sc, "use_grayscale_preview", text="B/W", toggle=True)
  86. row.separator()
  87. row.prop(sc, "use_mute_footage", text="", icon='HIDE_OFF', toggle=True)
  88. layout.separator()
  89. row = layout.row()
  90. col = row.column()
  91. col.prop(sc.clip_user, "use_render_undistorted", text="Render Undistorted")
  92. col.prop(sc, "lock_selection", text="Lock to Selection")
  93. col = row.column()
  94. col.prop(sc, "show_stable", text="Show Stable")
  95. col.prop(sc, "show_grid", text="Grid")
  96. col.prop(sc, "use_manual_calibration", text="Calibration")
  97. clip = sc.clip
  98. if clip:
  99. col = layout.column()
  100. col.prop(clip, "display_aspect", text="Display Aspect Ratio")
  101. class CLIP_HT_header(Header):
  102. bl_space_type = 'CLIP_EDITOR'
  103. def _draw_tracking(self, context):
  104. layout = self.layout
  105. sc = context.space_data
  106. clip = sc.clip
  107. CLIP_MT_tracking_editor_menus.draw_collapsible(context, layout)
  108. layout.separator_spacer()
  109. row = layout.row()
  110. if sc.view == 'CLIP':
  111. row.template_ID(sc, "clip", open="clip.open")
  112. else:
  113. row = layout.row(align=True)
  114. props = row.operator("clip.refine_markers", text="", icon='TRACKING_REFINE_BACKWARDS')
  115. props.backwards = True
  116. row.separator()
  117. props = row.operator("clip.clear_track_path", text="", icon='TRACKING_CLEAR_BACKWARDS')
  118. props.action = 'UPTO'
  119. row.separator()
  120. props = row.operator("clip.track_markers", text="", icon='TRACKING_BACKWARDS_SINGLE')
  121. props.backwards = True
  122. props.sequence = False
  123. props = row.operator("clip.track_markers", text="",
  124. icon='TRACKING_BACKWARDS')
  125. props.backwards = True
  126. props.sequence = True
  127. props = row.operator("clip.track_markers", text="", icon='TRACKING_FORWARDS')
  128. props.backwards = False
  129. props.sequence = True
  130. props = row.operator("clip.track_markers", text="", icon='TRACKING_FORWARDS_SINGLE')
  131. props.backwards = False
  132. props.sequence = False
  133. row.separator()
  134. props = row.operator("clip.clear_track_path", text="", icon='TRACKING_CLEAR_FORWARDS')
  135. props.action = 'REMAINED'
  136. row.separator()
  137. props = row.operator("clip.refine_markers", text="", icon='TRACKING_REFINE_FORWARDS')
  138. props.backwards = False
  139. layout.separator_spacer()
  140. if clip:
  141. tracking = clip.tracking
  142. active_object = tracking.objects.active
  143. if sc.view == 'CLIP':
  144. layout.template_running_jobs()
  145. r = active_object.reconstruction
  146. if r.is_valid and sc.view == 'CLIP':
  147. layout.label(text="Solve error: %.4f" %
  148. (r.average_error))
  149. row = layout.row()
  150. row.prop(sc, "pivot_point", text="", icon_only=True)
  151. row = layout.row(align=True)
  152. icon = 'LOCKED' if sc.lock_selection else 'UNLOCKED'
  153. row.prop(sc, "lock_selection", icon=icon, text="")
  154. row.popover(panel='CLIP_PT_display')
  155. elif sc.view == 'GRAPH':
  156. row = layout.row(align=True)
  157. row.prop(sc, "show_graph_only_selected", text="")
  158. row.prop(sc, "show_graph_hidden", text="")
  159. row = layout.row(align=True)
  160. sub = row.row(align=True)
  161. sub.active = clip.tracking.reconstruction.is_valid
  162. sub.prop(sc, "show_graph_frames", icon='SEQUENCE', text="")
  163. row.prop(sc, "show_graph_tracks_motion", icon='GRAPH', text="")
  164. row.prop(sc, "show_graph_tracks_error", icon='ANIM', text="")
  165. elif sc.view == 'DOPESHEET':
  166. dopesheet = tracking.dopesheet
  167. row = layout.row(align=True)
  168. row.prop(dopesheet, "show_only_selected", text="")
  169. row.prop(dopesheet, "show_hidden", text="")
  170. row = layout.row(align=True)
  171. row.prop(dopesheet, "sort_method", text="")
  172. row.prop(dopesheet, "use_invert_sort",
  173. text="Invert", toggle=True)
  174. def _draw_masking(self, context):
  175. layout = self.layout
  176. tool_settings = context.tool_settings
  177. sc = context.space_data
  178. clip = sc.clip
  179. CLIP_MT_masking_editor_menus.draw_collapsible(context, layout)
  180. layout.separator_spacer()
  181. row = layout.row()
  182. row.template_ID(sc, "clip", open="clip.open")
  183. layout.separator_spacer()
  184. if clip:
  185. layout.prop(sc, "pivot_point", text="", icon_only=True)
  186. row = layout.row(align=True)
  187. row.prop(tool_settings, "use_proportional_edit_mask", text="", icon_only=True)
  188. sub = row.row(align=True)
  189. sub.active = tool_settings.use_proportional_edit_mask
  190. sub.prop(tool_settings, "proportional_edit_falloff", text="", icon_only=True)
  191. row = layout.row()
  192. row.template_ID(sc, "mask", new="mask.new")
  193. row.popover(panel='CLIP_PT_mask_display')
  194. row = layout.row(align=True)
  195. icon = 'LOCKED' if sc.lock_selection else 'UNLOCKED'
  196. row.prop(sc, "lock_selection", icon=icon, text="")
  197. row.popover(panel='CLIP_PT_display')
  198. def draw(self, context):
  199. layout = self.layout
  200. sc = context.space_data
  201. layout.template_header()
  202. layout.prop(sc, "mode", text="")
  203. if sc.mode == 'TRACKING':
  204. layout.prop(sc, "view", text="")
  205. self._draw_tracking(context)
  206. else:
  207. self._draw_masking(context)
  208. class CLIP_MT_tracking_editor_menus(Menu):
  209. bl_idname = "CLIP_MT_tracking_editor_menus"
  210. bl_label = ""
  211. def draw(self, context):
  212. layout = self.layout
  213. sc = context.space_data
  214. clip = sc.clip
  215. layout.menu("CLIP_MT_view")
  216. if sc.view == 'CLIP':
  217. if clip:
  218. layout.menu("CLIP_MT_select")
  219. layout.menu("CLIP_MT_clip")
  220. layout.menu("CLIP_MT_track")
  221. layout.menu("CLIP_MT_reconstruction")
  222. else:
  223. layout.menu("CLIP_MT_clip")
  224. class CLIP_MT_masking_editor_menus(Menu):
  225. bl_idname = "CLIP_MT_masking_editor_menus"
  226. bl_label = ""
  227. def draw(self, context):
  228. layout = self.layout
  229. sc = context.space_data
  230. clip = sc.clip
  231. layout.menu("CLIP_MT_view")
  232. if clip:
  233. layout.menu("MASK_MT_select")
  234. layout.menu("CLIP_MT_clip") # XXX - remove?
  235. layout.menu("MASK_MT_add")
  236. layout.menu("MASK_MT_mask")
  237. else:
  238. layout.menu("CLIP_MT_clip") # XXX - remove?
  239. class CLIP_PT_clip_view_panel:
  240. @classmethod
  241. def poll(cls, context):
  242. sc = context.space_data
  243. clip = sc.clip
  244. return clip and sc.view == 'CLIP'
  245. class CLIP_PT_tracking_panel:
  246. @classmethod
  247. def poll(cls, context):
  248. sc = context.space_data
  249. clip = sc.clip
  250. return clip and sc.mode == 'TRACKING' and sc.view == 'CLIP'
  251. class CLIP_PT_reconstruction_panel:
  252. @classmethod
  253. def poll(cls, context):
  254. sc = context.space_data
  255. clip = sc.clip
  256. return clip and sc.view == 'CLIP'
  257. class CLIP_PT_tools_clip(Panel):
  258. bl_space_type = 'CLIP_EDITOR'
  259. bl_region_type = 'TOOLS'
  260. bl_label = "Clip"
  261. bl_translation_context = bpy.app.translations.contexts.id_movieclip
  262. bl_category = "Track"
  263. @classmethod
  264. def poll(cls, context):
  265. sc = context.space_data
  266. clip = sc.clip
  267. return clip and sc.view == 'CLIP' and sc.mode != 'MASK'
  268. def draw(self, _context):
  269. layout = self.layout
  270. col = layout.column(align=True)
  271. col.operator("clip.set_scene_frames")
  272. row = col.row(align=True)
  273. row.operator("clip.prefetch", text="Prefetch")
  274. row.operator("clip.reload", text="Reload")
  275. class CLIP_PT_tools_marker(CLIP_PT_tracking_panel, Panel):
  276. bl_space_type = 'CLIP_EDITOR'
  277. bl_region_type = 'TOOLS'
  278. bl_label = "Marker"
  279. bl_category = "Track"
  280. def draw(self, _context):
  281. layout = self.layout
  282. col = layout.column(align=True)
  283. row = col.row(align=True)
  284. row.operator("clip.add_marker_at_click", text="Add")
  285. row.operator("clip.delete_track", text="Delete")
  286. col.operator("clip.detect_features")
  287. class CLIP_PT_tracking_settings(CLIP_PT_tracking_panel, Panel):
  288. bl_space_type = 'CLIP_EDITOR'
  289. bl_region_type = 'TOOLS'
  290. bl_label = "Tracking Settings"
  291. bl_category = "Track"
  292. def draw_header_preset(self, _context):
  293. CLIP_PT_tracking_settings_presets.draw_panel_header(self.layout)
  294. def draw(self, context):
  295. layout = self.layout
  296. layout.use_property_split = True
  297. layout.use_property_decorate = False
  298. sc = context.space_data
  299. clip = sc.clip
  300. settings = clip.tracking.settings
  301. col = layout.column(align=True)
  302. col.prop(settings, "default_pattern_size")
  303. col.prop(settings, "default_search_size")
  304. col.separator()
  305. col.prop(settings, "default_motion_model")
  306. col.prop(settings, "default_pattern_match", text="Match")
  307. col.prop(settings, "use_default_brute")
  308. col.prop(settings, "use_default_normalization")
  309. col = layout.column()
  310. row = col.row(align=True)
  311. row.use_property_split = False
  312. row.prop(settings, "use_default_red_channel",
  313. text="R", toggle=True)
  314. row.prop(settings, "use_default_green_channel",
  315. text="G", toggle=True)
  316. row.prop(settings, "use_default_blue_channel",
  317. text="B", toggle=True)
  318. col.separator()
  319. col.operator("clip.track_settings_as_default",
  320. text="Copy From Active Track")
  321. class CLIP_PT_tracking_settings_extras(CLIP_PT_tracking_panel, Panel):
  322. bl_label = "Tracking Settings Extra"
  323. bl_parent_id = "CLIP_PT_tracking_settings"
  324. bl_space_type = 'CLIP_EDITOR'
  325. bl_region_type = 'TOOLS'
  326. bl_options = {'DEFAULT_CLOSED'}
  327. def draw(self, context):
  328. layout = self.layout
  329. layout.use_property_split = True
  330. layout.use_property_decorate = False
  331. sc = context.space_data
  332. clip = sc.clip
  333. settings = clip.tracking.settings
  334. col = layout.column()
  335. col.prop(settings, "default_weight")
  336. col = layout.column(align=True)
  337. col.prop(settings, "default_correlation_min")
  338. col.prop(settings, "default_margin")
  339. col.prop(settings, "use_default_mask")
  340. class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel):
  341. bl_space_type = 'CLIP_EDITOR'
  342. bl_region_type = 'TOOLS'
  343. bl_label = "Track"
  344. bl_category = "Track"
  345. bl_options = {'DEFAULT_CLOSED'}
  346. def draw(self, _context):
  347. layout = self.layout
  348. row = layout.row(align=True)
  349. row.label(text="Track:")
  350. props = row.operator("clip.track_markers", text="", icon='TRACKING_BACKWARDS_SINGLE')
  351. props.backwards = True
  352. props.sequence = False
  353. props = row.operator("clip.track_markers", text="",
  354. icon='TRACKING_BACKWARDS')
  355. props.backwards = True
  356. props.sequence = True
  357. props = row.operator("clip.track_markers", text="", icon='TRACKING_FORWARDS')
  358. props.backwards = False
  359. props.sequence = True
  360. props = row.operator("clip.track_markers", text="", icon='TRACKING_FORWARDS_SINGLE')
  361. props.backwards = False
  362. props.sequence = False
  363. col = layout.column(align=True)
  364. row = col.row(align=True)
  365. row.label(text="Clear:")
  366. row.scale_x = 2.0
  367. props = row.operator("clip.clear_track_path", text="", icon='TRACKING_CLEAR_BACKWARDS')
  368. props.action = 'UPTO'
  369. props = row.operator("clip.clear_track_path", text="", icon='TRACKING_CLEAR_FORWARDS')
  370. props.action = 'REMAINED'
  371. col = layout.column()
  372. row = col.row(align=True)
  373. row.label(text="Refine:")
  374. row.scale_x = 2.0
  375. props = row.operator("clip.refine_markers", text="", icon='TRACKING_REFINE_BACKWARDS')
  376. props.backwards = True
  377. props = row.operator("clip.refine_markers", text="", icon='TRACKING_REFINE_FORWARDS')
  378. props.backwards = False
  379. col = layout.column(align=True)
  380. row = col.row(align=True)
  381. row.label(text="Merge:")
  382. row.operator("clip.join_tracks", text="Join Tracks")
  383. class CLIP_PT_tools_plane_tracking(CLIP_PT_tracking_panel, Panel):
  384. bl_space_type = 'CLIP_EDITOR'
  385. bl_region_type = 'TOOLS'
  386. bl_label = "Plane Track"
  387. bl_options = {'DEFAULT_CLOSED'}
  388. bl_category = "Solve"
  389. def draw(self, _context):
  390. layout = self.layout
  391. layout.operator("clip.create_plane_track")
  392. class CLIP_PT_tools_solve(CLIP_PT_tracking_panel, Panel):
  393. bl_space_type = 'CLIP_EDITOR'
  394. bl_region_type = 'TOOLS'
  395. bl_label = "Solve"
  396. bl_category = "Solve"
  397. def draw(self, context):
  398. layout = self.layout
  399. layout.use_property_split = True
  400. layout.use_property_decorate = False
  401. clip = context.space_data.clip
  402. tracking = clip.tracking
  403. settings = tracking.settings
  404. tracking_object = tracking.objects.active
  405. col = layout.column()
  406. col.prop(settings, "use_tripod_solver", text="Tripod")
  407. col = layout.column()
  408. col.active = not settings.use_tripod_solver
  409. col.prop(settings, "use_keyframe_selection", text="Keyframe")
  410. col = layout.column(align=True)
  411. col.active = (not settings.use_tripod_solver and
  412. not settings.use_keyframe_selection)
  413. col.prop(tracking_object, "keyframe_a")
  414. col.prop(tracking_object, "keyframe_b")
  415. col = layout.column()
  416. col.active = tracking_object.is_camera
  417. col.prop(settings, "refine_intrinsics", text="Refine")
  418. col = layout.column(align=True)
  419. col.scale_y = 2.0
  420. col.operator("clip.solve_camera",
  421. text="Solve Camera Motion" if tracking_object.is_camera
  422. else "Solve Object Motion")
  423. class CLIP_PT_tools_cleanup(CLIP_PT_tracking_panel, Panel):
  424. bl_space_type = 'CLIP_EDITOR'
  425. bl_region_type = 'TOOLS'
  426. bl_label = "Clean up"
  427. bl_options = {'DEFAULT_CLOSED'}
  428. bl_category = "Solve"
  429. def draw(self, context):
  430. layout = self.layout
  431. layout.use_property_split = True
  432. layout.use_property_decorate = False
  433. clip = context.space_data.clip
  434. settings = clip.tracking.settings
  435. col = layout.column()
  436. col.prop(settings, "clean_frames", text="Frames")
  437. col.prop(settings, "clean_error", text="Error")
  438. col.prop(settings, "clean_action", text="Type")
  439. col.separator()
  440. col.operator("clip.clean_tracks")
  441. col.operator("clip.filter_tracks")
  442. class CLIP_PT_tools_geometry(CLIP_PT_tracking_panel, Panel):
  443. bl_space_type = 'CLIP_EDITOR'
  444. bl_region_type = 'TOOLS'
  445. bl_label = "Geometry"
  446. bl_options = {'DEFAULT_CLOSED'}
  447. bl_category = "Solve"
  448. def draw(self, _context):
  449. layout = self.layout
  450. layout.operator("clip.bundles_to_mesh")
  451. layout.operator("clip.track_to_empty")
  452. class CLIP_PT_tools_orientation(CLIP_PT_tracking_panel, Panel):
  453. bl_space_type = 'CLIP_EDITOR'
  454. bl_region_type = 'TOOLS'
  455. bl_label = "Orientation"
  456. bl_category = "Solve"
  457. def draw(self, context):
  458. layout = self.layout
  459. layout.use_property_split = True
  460. layout.use_property_decorate = False
  461. sc = context.space_data
  462. settings = sc.clip.tracking.settings
  463. col = layout.column(align=True)
  464. row = col.row(align=True)
  465. row.operator("clip.set_plane", text="Floor").plane = 'FLOOR'
  466. row.operator("clip.set_plane", text="Wall").plane = 'WALL'
  467. col.operator("clip.set_origin")
  468. row = col.row(align=True)
  469. row.operator("clip.set_axis", text="Set X Axis").axis = 'X'
  470. row.operator("clip.set_axis", text="Set Y Axis").axis = 'Y'
  471. layout.separator()
  472. col = layout.column()
  473. row = col.row(align=True)
  474. row.operator("clip.set_scale")
  475. row.operator("clip.apply_solution_scale", text="Apply Scale")
  476. col.prop(settings, "distance")
  477. class CLIP_PT_tools_object(CLIP_PT_reconstruction_panel, Panel):
  478. bl_space_type = 'CLIP_EDITOR'
  479. bl_region_type = 'TOOLS'
  480. bl_label = "Object"
  481. bl_category = "Solve"
  482. @classmethod
  483. def poll(cls, context):
  484. sc = context.space_data
  485. if CLIP_PT_reconstruction_panel.poll(context) and sc.mode == 'TRACKING':
  486. clip = sc.clip
  487. tracking_object = clip.tracking.objects.active
  488. return not tracking_object.is_camera
  489. return False
  490. def draw(self, context):
  491. layout = self.layout
  492. sc = context.space_data
  493. clip = sc.clip
  494. tracking_object = clip.tracking.objects.active
  495. settings = sc.clip.tracking.settings
  496. col = layout.column()
  497. col.prop(tracking_object, "scale")
  498. col.separator()
  499. col.operator("clip.set_solution_scale", text="Set Scale")
  500. col.prop(settings, "object_distance")
  501. class CLIP_PT_objects(CLIP_PT_clip_view_panel, Panel):
  502. bl_space_type = 'CLIP_EDITOR'
  503. bl_region_type = 'UI'
  504. bl_category = "Track"
  505. bl_label = "Objects"
  506. bl_options = {'DEFAULT_CLOSED'}
  507. def draw(self, context):
  508. layout = self.layout
  509. sc = context.space_data
  510. tracking = sc.clip.tracking
  511. row = layout.row()
  512. row.template_list("CLIP_UL_tracking_objects", "", tracking, "objects",
  513. tracking, "active_object_index", rows=1)
  514. sub = row.column(align=True)
  515. sub.operator("clip.tracking_object_new", icon='ADD', text="")
  516. sub.operator("clip.tracking_object_remove", icon='REMOVE', text="")
  517. class CLIP_PT_track(CLIP_PT_tracking_panel, Panel):
  518. bl_space_type = 'CLIP_EDITOR'
  519. bl_region_type = 'UI'
  520. bl_category = "Track"
  521. bl_label = "Track"
  522. def draw(self, context):
  523. layout = self.layout
  524. sc = context.space_data
  525. clip = context.space_data.clip
  526. act_track = clip.tracking.tracks.active
  527. if not act_track:
  528. layout.active = False
  529. layout.label(text="No active track")
  530. return
  531. row = layout.row()
  532. row.prop(act_track, "name", text="")
  533. sub = row.row(align=True)
  534. sub.template_marker(sc, "clip", sc.clip_user, act_track, compact=True)
  535. icon = 'LOCKED' if act_track.lock else 'UNLOCKED'
  536. sub.prop(act_track, "lock", text="", icon=icon)
  537. layout.template_track(sc, "scopes")
  538. row = layout.row(align=True)
  539. sub = row.row(align=True)
  540. sub.prop(act_track, "use_red_channel", text="R", toggle=True)
  541. sub.prop(act_track, "use_green_channel", text="G", toggle=True)
  542. sub.prop(act_track, "use_blue_channel", text="B", toggle=True)
  543. row.separator()
  544. layout.use_property_split = True
  545. row.prop(act_track, "use_grayscale_preview", text="B/W", toggle=True)
  546. row.separator()
  547. row.prop(act_track, "use_alpha_preview",
  548. text="", toggle=True, icon='IMAGE_ALPHA')
  549. layout.prop(act_track, "weight")
  550. layout.prop(act_track, "weight_stab")
  551. if act_track.has_bundle:
  552. label_text = "Average Error: %.4f" % (act_track.average_error)
  553. layout.label(text=label_text)
  554. layout.use_property_split = False
  555. row = layout.row(align=True)
  556. row.prop(act_track, "use_custom_color", text="")
  557. CLIP_PT_track_color_presets.draw_menu(row, 'Custom Color Presets')
  558. row.operator("clip.track_copy_color", icon='COPY_ID', text="")
  559. if act_track.use_custom_color:
  560. row = layout.row()
  561. row.prop(act_track, "color", text="")
  562. class CLIP_PT_plane_track(CLIP_PT_tracking_panel, Panel):
  563. bl_space_type = 'CLIP_EDITOR'
  564. bl_region_type = 'UI'
  565. bl_category = "Track"
  566. bl_label = "Plane Track"
  567. bl_options = {'DEFAULT_CLOSED'}
  568. def draw(self, context):
  569. layout = self.layout
  570. layout.use_property_split = True
  571. clip = context.space_data.clip
  572. active_track = clip.tracking.plane_tracks.active
  573. if not active_track:
  574. layout.active = False
  575. layout.label(text="No active plane track")
  576. return
  577. layout.prop(active_track, "name")
  578. layout.prop(active_track, "use_auto_keying")
  579. layout.prop(active_track, "image")
  580. row = layout.row()
  581. row.active = active_track.image is not None
  582. row.prop(active_track, "image_opacity", text="Opacity")
  583. class CLIP_PT_track_settings(CLIP_PT_tracking_panel, Panel):
  584. bl_space_type = 'CLIP_EDITOR'
  585. bl_region_type = 'UI'
  586. bl_category = "Track"
  587. bl_label = "Tracking Settings"
  588. bl_options = {'DEFAULT_CLOSED'}
  589. def draw(self, context):
  590. layout = self.layout
  591. layout.use_property_split = True
  592. layout.use_property_decorate = False
  593. clip = context.space_data.clip
  594. col = layout.column()
  595. active = clip.tracking.tracks.active
  596. if active:
  597. col.prop(active, "motion_model")
  598. col.prop(active, "pattern_match", text="Match")
  599. col.prop(active, "use_brute")
  600. col.prop(active, "use_normalization")
  601. class CLIP_PT_track_settings_extras(CLIP_PT_tracking_panel, Panel):
  602. bl_space_type = 'CLIP_EDITOR'
  603. bl_region_type = 'UI'
  604. bl_category = "Track"
  605. bl_label = "Tracking Settings Extras"
  606. bl_parent_id = 'CLIP_PT_track_settings'
  607. bl_options = {'DEFAULT_CLOSED'}
  608. def draw(self, context):
  609. layout = self.layout
  610. layout.use_property_split = True
  611. layout.use_property_decorate = False
  612. clip = context.space_data.clip
  613. active = clip.tracking.tracks.active
  614. settings = clip.tracking.settings
  615. col = layout.column(align=True)
  616. col.prop(active, "correlation_min")
  617. col.prop(active, "margin")
  618. col = layout.column()
  619. col.prop(active, "use_mask")
  620. col.prop(active, "frames_limit")
  621. col.prop(settings, "speed")
  622. class CLIP_PT_tracking_camera(Panel):
  623. bl_space_type = 'CLIP_EDITOR'
  624. bl_region_type = 'UI'
  625. bl_category = "Track"
  626. bl_label = "Camera"
  627. bl_options = {'DEFAULT_CLOSED'}
  628. @classmethod
  629. def poll(cls, context):
  630. if CLIP_PT_clip_view_panel.poll(context):
  631. sc = context.space_data
  632. return sc.mode == 'TRACKING' and sc.clip
  633. return False
  634. def draw_header_preset(self, _context):
  635. CLIP_PT_camera_presets.draw_panel_header(self.layout)
  636. def draw(self, context):
  637. layout = self.layout
  638. layout.use_property_split = True
  639. layout.use_property_decorate = False
  640. sc = context.space_data
  641. clip = sc.clip
  642. col = layout.column(align=True)
  643. col.prop(clip.tracking.camera, "sensor_width", text="Sensor Width")
  644. col.prop(clip.tracking.camera, "pixel_aspect", text="Pixel Aspect")
  645. col = layout.column()
  646. col.prop(clip.tracking.camera, "principal", text="Optical Center")
  647. col.operator("clip.set_center_principal", text="Set Center")
  648. class CLIP_PT_tracking_lens(Panel):
  649. bl_space_type = 'CLIP_EDITOR'
  650. bl_region_type = 'UI'
  651. bl_category = "Track"
  652. bl_label = "Lens"
  653. bl_options = {'DEFAULT_CLOSED'}
  654. @classmethod
  655. def poll(cls, context):
  656. if CLIP_PT_clip_view_panel.poll(context):
  657. sc = context.space_data
  658. return sc.mode == 'TRACKING' and sc.clip
  659. return False
  660. def draw(self, context):
  661. layout = self.layout
  662. layout.use_property_split = True
  663. layout.use_property_decorate = False
  664. sc = context.space_data
  665. clip = sc.clip
  666. camera = clip.tracking.camera
  667. col = layout.column()
  668. if camera.units == 'MILLIMETERS':
  669. col.prop(camera, "focal_length")
  670. else:
  671. col.prop(camera, "focal_length_pixels")
  672. col.prop(camera, "units", text="Units")
  673. col = layout.column()
  674. col.prop(camera, "distortion_model", text="Lens Distortion")
  675. if camera.distortion_model == 'POLYNOMIAL':
  676. col = layout.column(align=True)
  677. col.prop(camera, "k1")
  678. col.prop(camera, "k2")
  679. col.prop(camera, "k3")
  680. elif camera.distortion_model == 'DIVISION':
  681. col = layout.column(align=True)
  682. col.prop(camera, "division_k1")
  683. col.prop(camera, "division_k2")
  684. class CLIP_PT_marker(CLIP_PT_tracking_panel, Panel):
  685. bl_space_type = 'CLIP_EDITOR'
  686. bl_region_type = 'UI'
  687. bl_category = "Track"
  688. bl_label = "Marker"
  689. bl_options = {'DEFAULT_CLOSED'}
  690. def draw(self, context):
  691. layout = self.layout
  692. layout.use_property_split = True
  693. layout.use_property_decorate = False
  694. sc = context.space_data
  695. clip = context.space_data.clip
  696. act_track = clip.tracking.tracks.active
  697. if act_track:
  698. layout.template_marker(sc, "clip", sc.clip_user, act_track, compact=False)
  699. else:
  700. layout.active = False
  701. layout.label(text="No active track")
  702. class CLIP_PT_stabilization(CLIP_PT_reconstruction_panel, Panel):
  703. bl_space_type = 'CLIP_EDITOR'
  704. bl_region_type = 'UI'
  705. bl_label = "2D Stabilization"
  706. bl_category = "Stabilization"
  707. @classmethod
  708. def poll(cls, context):
  709. if CLIP_PT_clip_view_panel.poll(context):
  710. sc = context.space_data
  711. return sc.mode == 'TRACKING' and sc.clip
  712. return False
  713. def draw_header(self, context):
  714. stab = context.space_data.clip.tracking.stabilization
  715. self.layout.prop(stab, "use_2d_stabilization", text="")
  716. def draw(self, context):
  717. layout = self.layout
  718. layout.use_property_split = True
  719. layout.use_property_decorate = False
  720. tracking = context.space_data.clip.tracking
  721. stab = tracking.stabilization
  722. layout.active = stab.use_2d_stabilization
  723. layout.prop(stab, "anchor_frame")
  724. row = layout.row(align=True)
  725. row.prop(stab, "use_stabilize_rotation", text="Rotation")
  726. sub = row.row(align=True)
  727. sub.active = stab.use_stabilize_rotation
  728. sub.prop(stab, "use_stabilize_scale", text="Scale")
  729. box = layout.box()
  730. row = box.row(align=True)
  731. row.prop(stab, "show_tracks_expanded", text="", emboss=False)
  732. if not stab.show_tracks_expanded:
  733. row.label(text="Tracks For Stabilization")
  734. else:
  735. row.label(text="Tracks For Location")
  736. row = box.row()
  737. row.template_list("UI_UL_list", "stabilization_tracks", stab, "tracks",
  738. stab, "active_track_index", rows=2)
  739. sub = row.column(align=True)
  740. sub.operator("clip.stabilize_2d_add", icon='ADD', text="")
  741. sub.operator("clip.stabilize_2d_remove", icon='REMOVE', text="")
  742. sub.menu('CLIP_MT_stabilize_2d_context_menu', text="",
  743. icon='DOWNARROW_HLT')
  744. # Usually we don't hide things from iterface, but here every pixel of
  745. # vertical space is precious.
  746. if stab.use_stabilize_rotation:
  747. box.label(text="Tracks For Rotation / Scale")
  748. row = box.row()
  749. row.template_list("UI_UL_list", "stabilization_rotation_tracks",
  750. stab, "rotation_tracks",
  751. stab, "active_rotation_track_index", rows=2)
  752. sub = row.column(align=True)
  753. sub.operator("clip.stabilize_2d_rotation_add", icon='ADD', text="")
  754. sub.operator("clip.stabilize_2d_rotation_remove", icon='REMOVE', text="")
  755. sub.menu('CLIP_MT_stabilize_2d_rotation_context_menu', text="",
  756. icon='DOWNARROW_HLT')
  757. col = layout.column()
  758. col.prop(stab, "use_autoscale")
  759. sub = col.row()
  760. sub.active = stab.use_autoscale
  761. sub.prop(stab, "scale_max", text="Max")
  762. col = layout.column(align=True)
  763. row = col.row(align=True)
  764. row.prop(stab, "target_position", text="Target")
  765. col.prop(stab, "target_rotation")
  766. row = col.row(align=True)
  767. row.prop(stab, "target_scale")
  768. row.active = not stab.use_autoscale
  769. col = layout.column(align=True)
  770. col.prop(stab, "influence_location")
  771. sub = col.column(align=True)
  772. sub.active = stab.use_stabilize_rotation
  773. sub.prop(stab, "influence_rotation")
  774. sub.prop(stab, "influence_scale")
  775. layout.prop(stab, "filter_type")
  776. class CLIP_PT_proxy(CLIP_PT_clip_view_panel, Panel):
  777. bl_space_type = 'CLIP_EDITOR'
  778. bl_region_type = 'UI'
  779. bl_category = "Footage"
  780. bl_label = "Proxy/Timecode"
  781. bl_options = {'DEFAULT_CLOSED'}
  782. def draw_header(self, context):
  783. sc = context.space_data
  784. self.layout.prop(sc.clip, "use_proxy", text="")
  785. def draw(self, context):
  786. layout = self.layout
  787. sc = context.space_data
  788. clip = sc.clip
  789. col = layout.column()
  790. col.active = clip.use_proxy
  791. col.label(text="Build Original:")
  792. row = col.row(align=True)
  793. row.prop(clip.proxy, "build_25", toggle=True)
  794. row.prop(clip.proxy, "build_50", toggle=True)
  795. row.prop(clip.proxy, "build_75", toggle=True)
  796. row.prop(clip.proxy, "build_100", toggle=True)
  797. col.label(text="Build Undistorted:")
  798. row = col.row(align=True)
  799. row.prop(clip.proxy, "build_undistorted_25", toggle=True)
  800. row.prop(clip.proxy, "build_undistorted_50", toggle=True)
  801. row.prop(clip.proxy, "build_undistorted_75", toggle=True)
  802. row.prop(clip.proxy, "build_undistorted_100", toggle=True)
  803. layout.use_property_split = True
  804. layout.use_property_decorate = False
  805. col = layout.column()
  806. col.prop(clip.proxy, "quality")
  807. col.prop(clip, "use_proxy_custom_directory")
  808. if clip.use_proxy_custom_directory:
  809. col.prop(clip.proxy, "directory")
  810. col.operator(
  811. "clip.rebuild_proxy",
  812. text="Build Proxy / Timecode" if clip.source == 'MOVIE'
  813. else "Build Proxy"
  814. )
  815. if clip.source == 'MOVIE':
  816. col2 = col.column()
  817. col2.prop(clip.proxy, "timecode", text="Timecode Index")
  818. col.separator()
  819. col.prop(sc.clip_user, "proxy_render_size", text="Proxy Size")
  820. # -----------------------------------------------------------------------------
  821. # Mask (similar code in space_image.py, keep in sync)
  822. from bl_ui.properties_mask_common import (
  823. MASK_PT_mask,
  824. MASK_PT_layers,
  825. MASK_PT_spline,
  826. MASK_PT_point,
  827. MASK_PT_display,
  828. MASK_PT_transforms,
  829. MASK_PT_tools
  830. )
  831. class CLIP_PT_mask_layers(MASK_PT_layers, Panel):
  832. bl_space_type = 'CLIP_EDITOR'
  833. bl_region_type = 'UI'
  834. bl_category = "Mask"
  835. class CLIP_PT_mask_display(MASK_PT_display, Panel):
  836. bl_space_type = 'CLIP_EDITOR'
  837. bl_region_type = 'HEADER'
  838. bl_category = "Mask"
  839. class CLIP_PT_active_mask_spline(MASK_PT_spline, Panel):
  840. bl_space_type = 'CLIP_EDITOR'
  841. bl_region_type = 'UI'
  842. bl_category = "Mask"
  843. class CLIP_PT_active_mask_point(MASK_PT_point, Panel):
  844. bl_space_type = 'CLIP_EDITOR'
  845. bl_region_type = 'UI'
  846. bl_category = "Mask"
  847. class CLIP_PT_mask(MASK_PT_mask, Panel):
  848. bl_space_type = 'CLIP_EDITOR'
  849. bl_region_type = 'UI'
  850. bl_category = "Mask"
  851. class CLIP_PT_tools_mask_transforms(MASK_PT_transforms, Panel):
  852. bl_space_type = 'CLIP_EDITOR'
  853. bl_region_type = 'TOOLS'
  854. bl_category = "Mask"
  855. class CLIP_PT_tools_mask_tools(MASK_PT_tools, Panel):
  856. bl_space_type = 'CLIP_EDITOR'
  857. bl_region_type = 'TOOLS'
  858. bl_category = "Mask"
  859. # --- end mask ---
  860. class CLIP_PT_footage(CLIP_PT_clip_view_panel, Panel):
  861. bl_space_type = 'CLIP_EDITOR'
  862. bl_region_type = 'UI'
  863. bl_category = "Footage"
  864. bl_label = "Footage Settings"
  865. def draw(self, context):
  866. layout = self.layout
  867. layout.use_property_split = True
  868. layout.use_property_decorate = False
  869. sc = context.space_data
  870. clip = sc.clip
  871. col = layout.column()
  872. col.template_movieclip(sc, "clip", compact=True)
  873. col.prop(clip, "frame_start")
  874. col.prop(clip, "frame_offset")
  875. col.template_movieclip_information(sc, "clip", sc.clip_user)
  876. class CLIP_PT_tools_scenesetup(Panel):
  877. bl_space_type = 'CLIP_EDITOR'
  878. bl_region_type = 'TOOLS'
  879. bl_label = "Scene Setup"
  880. bl_translation_context = bpy.app.translations.contexts.id_movieclip
  881. bl_category = "Solve"
  882. @classmethod
  883. def poll(cls, context):
  884. sc = context.space_data
  885. clip = sc.clip
  886. return clip and sc.view == 'CLIP' and sc.mode != 'MASK'
  887. def draw(self, _context):
  888. layout = self.layout
  889. layout.operator("clip.set_viewport_background")
  890. layout.operator("clip.setup_tracking_scene")
  891. # Grease Pencil properties
  892. class CLIP_PT_grease_pencil(AnnotationDataPanel, CLIP_PT_clip_view_panel, Panel):
  893. bl_space_type = 'CLIP_EDITOR'
  894. bl_region_type = 'UI'
  895. bl_category = "Annotation"
  896. bl_options = set()
  897. # NOTE: this is just a wrapper around the generic GP Panel
  898. # But, this should only be visible in "clip" view
  899. # Grease Pencil drawing tools
  900. class CLIP_PT_tools_grease_pencil_draw(AnnotationDrawingToolsPanel, Panel):
  901. bl_space_type = 'CLIP_EDITOR'
  902. bl_region_type = 'TOOLS'
  903. class CLIP_MT_view(Menu):
  904. bl_label = "View"
  905. def draw(self, context):
  906. layout = self.layout
  907. sc = context.space_data
  908. if sc.view == 'CLIP':
  909. layout.prop(sc, "show_region_ui")
  910. layout.prop(sc, "show_region_toolbar")
  911. layout.prop(sc, "show_region_hud")
  912. layout.separator()
  913. layout.operator("clip.view_selected")
  914. layout.operator("clip.view_all")
  915. layout.operator("clip.view_all", text="View Fit").fit_view = True
  916. layout.separator()
  917. layout.operator("clip.view_zoom_in")
  918. layout.operator("clip.view_zoom_out")
  919. layout.separator()
  920. layout.prop(sc, "show_metadata")
  921. layout.separator()
  922. ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1))
  923. text = iface_("Zoom %d:%d")
  924. for a, b in ratios:
  925. layout.operator("clip.view_zoom_ratio",
  926. text=text % (a, b),
  927. translate=False).ratio = a / b
  928. else:
  929. if sc.view == 'GRAPH':
  930. layout.operator_context = 'INVOKE_REGION_PREVIEW'
  931. layout.operator("clip.graph_center_current_frame")
  932. layout.operator("clip.graph_view_all")
  933. layout.operator_context = 'INVOKE_DEFAULT'
  934. layout.prop(sc, "show_seconds")
  935. layout.prop(sc, "show_locked_time")
  936. layout.separator()
  937. layout.menu("INFO_MT_area")
  938. class CLIP_MT_clip(Menu):
  939. bl_label = "Clip"
  940. bl_translation_context = bpy.app.translations.contexts.id_movieclip
  941. def draw(self, context):
  942. layout = self.layout
  943. sc = context.space_data
  944. clip = sc.clip
  945. layout.operator("clip.open")
  946. if clip:
  947. layout.operator("clip.prefetch")
  948. layout.operator("clip.reload")
  949. layout.menu("CLIP_MT_proxy")
  950. class CLIP_MT_proxy(Menu):
  951. bl_label = "Proxy"
  952. def draw(self, _context):
  953. layout = self.layout
  954. layout.operator("clip.rebuild_proxy")
  955. layout.operator("clip.delete_proxy")
  956. class CLIP_MT_track(Menu):
  957. bl_label = "Track"
  958. def draw(self, _context):
  959. layout = self.layout
  960. layout.operator("clip.clear_solution")
  961. layout.operator("clip.solve_camera")
  962. layout.separator()
  963. props = layout.operator("clip.clear_track_path", text="Clear After")
  964. props.clear_active = False
  965. props.action = 'REMAINED'
  966. props = layout.operator("clip.clear_track_path", text="Clear Before")
  967. props.clear_active = False
  968. props.action = 'UPTO'
  969. props = layout.operator("clip.clear_track_path", text="Clear Track Path")
  970. props.clear_active = False
  971. props.action = 'ALL'
  972. layout.separator()
  973. layout.operator("clip.join_tracks")
  974. layout.separator()
  975. layout.operator("clip.clean_tracks")
  976. layout.separator()
  977. layout.operator("clip.copy_tracks")
  978. layout.operator("clip.paste_tracks")
  979. layout.separator()
  980. props = layout.operator("clip.track_markers", text="Track Frame Backwards")
  981. props.backwards = True
  982. props.sequence = False
  983. props = layout.operator("clip.track_markers", text="Track Backwards")
  984. props.backwards = True
  985. props.sequence = True
  986. props = layout.operator("clip.track_markers", text="Track Forwards")
  987. props.backwards = False
  988. props.sequence = True
  989. props = layout.operator("clip.track_markers", text="Track Frame Forwards")
  990. props.backwards = False
  991. props.sequence = False
  992. layout.separator()
  993. layout.operator("clip.delete_track")
  994. layout.operator("clip.delete_marker")
  995. layout.separator()
  996. layout.operator("clip.add_marker_move")
  997. layout.separator()
  998. layout.menu("CLIP_MT_track_visibility")
  999. layout.menu("CLIP_MT_track_transform")
  1000. class CLIP_MT_reconstruction(Menu):
  1001. bl_label = "Reconstruction"
  1002. def draw(self, _context):
  1003. layout = self.layout
  1004. layout.operator("clip.set_origin")
  1005. layout.operator("clip.set_plane", text="Set Floor").plane = 'FLOOR'
  1006. layout.operator("clip.set_plane", text="Set Wall").plane = 'WALL'
  1007. layout.operator("clip.set_axis", text="Set X Axis").axis = 'X'
  1008. layout.operator("clip.set_axis", text="Set Y Axis").axis = 'Y'
  1009. layout.operator("clip.set_scale")
  1010. layout.separator()
  1011. layout.operator("clip.track_to_empty")
  1012. layout.operator("clip.bundles_to_mesh")
  1013. class CLIP_MT_track_visibility(Menu):
  1014. bl_label = "Show/Hide"
  1015. def draw(self, _context):
  1016. layout = self.layout
  1017. layout.operator("clip.hide_tracks_clear")
  1018. layout.operator("clip.hide_tracks", text="Hide Selected").unselected = False
  1019. layout.operator("clip.hide_tracks", text="Hide Unselected").unselected = True
  1020. class CLIP_MT_track_transform(Menu):
  1021. bl_label = "Transform"
  1022. def draw(self, _context):
  1023. layout = self.layout
  1024. layout.operator("transform.translate")
  1025. layout.operator("transform.resize")
  1026. class CLIP_MT_select(Menu):
  1027. bl_label = "Select"
  1028. def draw(self, _context):
  1029. layout = self.layout
  1030. layout.operator("clip.select_box")
  1031. layout.operator("clip.select_circle")
  1032. layout.separator()
  1033. layout.operator("clip.select_all"
  1034. ).action = 'TOGGLE'
  1035. layout.operator("clip.select_all",
  1036. text="Inverse").action = 'INVERT'
  1037. layout.menu("CLIP_MT_select_grouped")
  1038. class CLIP_MT_select_grouped(Menu):
  1039. bl_label = "Select Grouped"
  1040. def draw(self, _context):
  1041. layout = self.layout
  1042. layout.operator_enum("clip.select_grouped", "group")
  1043. class CLIP_MT_mask_handle_type_menu(Menu):
  1044. bl_label = "Set Handle Type"
  1045. def draw(self, _context):
  1046. layout = self.layout
  1047. layout.operator_enum("mask.handle_type_set", "type")
  1048. class CLIP_MT_tracking_context_menu(Menu):
  1049. bl_label = "Context Menu"
  1050. @classmethod
  1051. def poll(cls, context):
  1052. return context.space_data.clip
  1053. def draw(self, _context):
  1054. layout = self.layout
  1055. mode = _context.space_data.mode
  1056. if mode == 'TRACKING':
  1057. layout.operator("clip.track_settings_to_track")
  1058. layout.operator("clip.track_settings_as_default")
  1059. layout.separator()
  1060. layout.operator("clip.track_copy_color")
  1061. layout.separator()
  1062. layout.operator("clip.copy_tracks", icon='COPYDOWN')
  1063. layout.operator("clip.paste_tracks", icon='PASTEDOWN')
  1064. layout.separator()
  1065. layout.operator("clip.disable_markers",
  1066. text="Disable Markers").action = 'DISABLE'
  1067. layout.operator("clip.disable_markers",
  1068. text="Enable Markers").action = 'ENABLE'
  1069. layout.separator()
  1070. layout.operator("clip.hide_tracks")
  1071. layout.operator("clip.hide_tracks_clear", text="Show Tracks")
  1072. layout.separator()
  1073. layout.operator("clip.lock_tracks", text="Lock Tracks").action = 'LOCK'
  1074. layout.operator("clip.lock_tracks",
  1075. text="Unlock Tracks").action = 'UNLOCK'
  1076. layout.separator()
  1077. layout.operator("clip.join_tracks")
  1078. layout.separator()
  1079. layout.operator("clip.delete_track")
  1080. elif mode == 'MASK':
  1081. layout.menu("CLIP_MT_mask_handle_type_menu")
  1082. layout.operator("mask.switch_direction")
  1083. layout.operator("mask.cyclic_toggle")
  1084. layout.separator()
  1085. layout.operator("mask.copy_splines", icon='COPYDOWN')
  1086. layout.operator("mask.paste_splines", icon='PASTEDOWN')
  1087. layout.separator()
  1088. layout.operator("mask.shape_key_rekey", text="Re-key Shape Points")
  1089. layout.operator("mask.feather_weight_clear")
  1090. layout.operator("mask.shape_key_feather_reset", text="Reset Feather Animation")
  1091. layout.separator()
  1092. layout.operator("mask.parent_set")
  1093. layout.operator("mask.parent_clear")
  1094. layout.separator()
  1095. layout.operator("mask.delete")
  1096. class CLIP_PT_camera_presets(PresetPanel, Panel):
  1097. """Predefined tracking camera intrinsics"""
  1098. bl_label = "Camera Presets"
  1099. preset_subdir = "tracking_camera"
  1100. preset_operator = "script.execute_preset"
  1101. preset_add_operator = "clip.camera_preset_add"
  1102. class CLIP_PT_track_color_presets(PresetPanel, Panel):
  1103. """Predefined track color"""
  1104. bl_label = "Color Presets"
  1105. preset_subdir = "tracking_track_color"
  1106. preset_operator = "script.execute_preset"
  1107. preset_add_operator = "clip.track_color_preset_add"
  1108. class CLIP_PT_tracking_settings_presets(PresetPanel, Panel):
  1109. """Predefined tracking settings"""
  1110. bl_label = "Tracking Presets"
  1111. preset_subdir = "tracking_settings"
  1112. preset_operator = "script.execute_preset"
  1113. preset_add_operator = "clip.tracking_settings_preset_add"
  1114. class CLIP_MT_stabilize_2d_context_menu(Menu):
  1115. bl_label = "Translation Track Specials"
  1116. def draw(self, _context):
  1117. layout = self.layout
  1118. layout.operator("clip.stabilize_2d_select")
  1119. class CLIP_MT_stabilize_2d_rotation_context_menu(Menu):
  1120. bl_label = "Rotation Track Specials"
  1121. def draw(self, _context):
  1122. layout = self.layout
  1123. layout.operator("clip.stabilize_2d_rotation_select")
  1124. class CLIP_MT_pivot_pie(Menu):
  1125. bl_label = "Pivot Point"
  1126. def draw(self, context):
  1127. layout = self.layout
  1128. pie = layout.menu_pie()
  1129. pie.prop_enum(context.space_data, "pivot_point", value='BOUNDING_BOX_CENTER')
  1130. pie.prop_enum(context.space_data, "pivot_point", value='CURSOR')
  1131. pie.prop_enum(context.space_data, "pivot_point", value='INDIVIDUAL_ORIGINS')
  1132. pie.prop_enum(context.space_data, "pivot_point", value='MEDIAN_POINT')
  1133. class CLIP_MT_marker_pie(Menu):
  1134. # Settings for the individual markers
  1135. bl_label = "Marker Settings"
  1136. @classmethod
  1137. def poll(cls, context):
  1138. space = context.space_data
  1139. return space.mode == 'TRACKING' and space.clip
  1140. def draw(self, context):
  1141. clip = context.space_data.clip
  1142. tracks = getattr(getattr(clip, "tracking", None), "tracks", None)
  1143. track_active = tracks.active if tracks else None
  1144. layout = self.layout
  1145. pie = layout.menu_pie()
  1146. # Use Location Tracking
  1147. prop = pie.operator("wm.context_set_enum", text="Loc")
  1148. prop.data_path = "space_data.clip.tracking.tracks.active.motion_model"
  1149. prop.value = "Loc"
  1150. # Use Affine Tracking
  1151. prop = pie.operator("wm.context_set_enum", text="Affine")
  1152. prop.data_path = "space_data.clip.tracking.tracks.active.motion_model"
  1153. prop.value = "Affine"
  1154. # Copy Settings From Active To Selected
  1155. pie.operator("clip.track_settings_to_track", icon='COPYDOWN')
  1156. # Make Settings Default
  1157. pie.operator("clip.track_settings_as_default", icon='SETTINGS')
  1158. if track_active:
  1159. # Use Normalization
  1160. pie.prop(track_active, "use_normalization", text="Normalization")
  1161. # Use Brute Force
  1162. pie.prop(track_active, "use_brute", text="Use Brute Force")
  1163. # Match Keyframe
  1164. prop = pie.operator("wm.context_set_enum", text="Match Previous", icon='KEYFRAME_HLT')
  1165. prop.data_path = "space_data.clip.tracking.tracks.active.pattern_match"
  1166. prop.value = 'KEYFRAME'
  1167. # Match Previous Frame
  1168. prop = pie.operator("wm.context_set_enum", text="Match Keyframe", icon='KEYFRAME')
  1169. prop.data_path = "space_data.clip.tracking.tracks.active.pattern_match"
  1170. prop.value = 'PREV_FRAME'
  1171. class CLIP_MT_tracking_pie(Menu):
  1172. # Tracking Operators
  1173. bl_label = "Tracking"
  1174. @classmethod
  1175. def poll(cls, context):
  1176. space = context.space_data
  1177. return space.mode == 'TRACKING' and space.clip
  1178. def draw(self, _context):
  1179. layout = self.layout
  1180. pie = layout.menu_pie()
  1181. # Track Backwards
  1182. prop = pie.operator("clip.track_markers", icon='TRACKING_BACKWARDS')
  1183. prop.backwards = True
  1184. prop.sequence = True
  1185. # Track Forwards
  1186. prop = pie.operator("clip.track_markers", icon='TRACKING_FORWARDS')
  1187. prop.backwards = False
  1188. prop.sequence = True
  1189. # Disable Marker
  1190. pie.operator("clip.disable_markers", icon='HIDE_OFF').action = 'TOGGLE'
  1191. # Detect Features
  1192. pie.operator("clip.detect_features", icon='ZOOM_SELECTED')
  1193. # Clear Path Backwards
  1194. pie.operator("clip.clear_track_path", icon='TRACKING_CLEAR_BACKWARDS').action = 'UPTO'
  1195. # Clear Path Forwards
  1196. pie.operator("clip.clear_track_path", icon='TRACKING_CLEAR_FORWARDS').action = 'REMAINED'
  1197. # Refine Backwards
  1198. pie.operator("clip.refine_markers", icon='TRACKING_REFINE_BACKWARDS').backwards = True
  1199. # Refine Forwards
  1200. pie.operator("clip.refine_markers", icon='TRACKING_REFINE_FORWARDS').backwards = False
  1201. class CLIP_MT_solving_pie(Menu):
  1202. # Operators to solve the scene
  1203. bl_label = "Solving"
  1204. @classmethod
  1205. def poll(cls, context):
  1206. space = context.space_data
  1207. return space.mode == 'TRACKING' and space.clip
  1208. def draw(self, context):
  1209. clip = context.space_data.clip
  1210. settings = getattr(getattr(clip, "tracking", None), "settings", None)
  1211. layout = self.layout
  1212. pie = layout.menu_pie()
  1213. # Clear Solution
  1214. pie.operator("clip.clear_solution", icon='FILE_REFRESH')
  1215. # Solve Camera
  1216. pie.operator("clip.solve_camera", text="Solve Camera", icon='OUTLINER_OB_CAMERA')
  1217. # Use Tripod Solver
  1218. if settings:
  1219. pie.prop(settings, "use_tripod_solver", text="Tripod Solver")
  1220. # create Plane Track
  1221. pie.operator("clip.create_plane_track", icon='MATPLANE')
  1222. # Set Keyframe A
  1223. pie.operator(
  1224. "clip.set_solver_keyframe",
  1225. text="Set Keyframe A",
  1226. icon='KEYFRAME',
  1227. ).keyframe = 'KEYFRAME_A'
  1228. # Set Keyframe B
  1229. pie.operator(
  1230. "clip.set_solver_keyframe",
  1231. text="Set Keyframe B",
  1232. icon='KEYFRAME',
  1233. ).keyframe = 'KEYFRAME_B'
  1234. # Clean Tracks
  1235. prop = pie.operator("clip.clean_tracks", icon='X')
  1236. # Filter Tracks
  1237. pie.operator("clip.filter_tracks", icon='FILTER')
  1238. prop.frames = 15
  1239. prop.error = 2
  1240. class CLIP_MT_reconstruction_pie(Menu):
  1241. # Scene Reconstruction
  1242. bl_label = "Reconstruction"
  1243. @classmethod
  1244. def poll(cls, context):
  1245. space = context.space_data
  1246. return space.mode == 'TRACKING' and space.clip
  1247. def draw(self, _context):
  1248. layout = self.layout
  1249. pie = layout.menu_pie()
  1250. # Set Active Clip As Viewport Background
  1251. pie.operator("clip.set_viewport_background", text="Set Viewport Background", icon='FILE_IMAGE')
  1252. # Setup Tracking Scene
  1253. pie.operator("clip.setup_tracking_scene", text="Setup Tracking Scene", icon='SCENE_DATA')
  1254. # Setup Floor
  1255. pie.operator("clip.set_plane", text="Set Floor", icon='AXIS_TOP')
  1256. # Set Origin
  1257. pie.operator("clip.set_origin", text="Set Origin", icon='OBJECT_ORIGIN')
  1258. # Set X Axis
  1259. pie.operator("clip.set_axis", text="Set X Axis", icon='AXIS_FRONT').axis = 'X'
  1260. # Set Y Axis
  1261. pie.operator("clip.set_axis", text="Set Y Axis", icon='AXIS_SIDE').axis = 'Y'
  1262. # Set Scale
  1263. pie.operator("clip.set_scale", text="Set Scale", icon='ARROW_LEFTRIGHT')
  1264. # Apply Solution Scale
  1265. pie.operator("clip.apply_solution_scale", icon='ARROW_LEFTRIGHT')
  1266. classes = (
  1267. CLIP_UL_tracking_objects,
  1268. CLIP_HT_header,
  1269. CLIP_PT_display,
  1270. CLIP_PT_clip_display,
  1271. CLIP_PT_marker_display,
  1272. CLIP_MT_track,
  1273. CLIP_MT_tracking_editor_menus,
  1274. CLIP_MT_masking_editor_menus,
  1275. CLIP_PT_track,
  1276. CLIP_PT_tools_clip,
  1277. CLIP_PT_tools_marker,
  1278. CLIP_PT_tracking_settings,
  1279. CLIP_PT_tracking_settings_extras,
  1280. CLIP_PT_tools_tracking,
  1281. CLIP_PT_tools_plane_tracking,
  1282. CLIP_PT_tools_solve,
  1283. CLIP_PT_tools_cleanup,
  1284. CLIP_PT_tools_geometry,
  1285. CLIP_PT_tools_orientation,
  1286. CLIP_PT_tools_object,
  1287. CLIP_PT_objects,
  1288. CLIP_PT_plane_track,
  1289. CLIP_PT_track_settings,
  1290. CLIP_PT_track_settings_extras,
  1291. CLIP_PT_tracking_camera,
  1292. CLIP_PT_tracking_lens,
  1293. CLIP_PT_marker,
  1294. CLIP_PT_proxy,
  1295. CLIP_PT_footage,
  1296. CLIP_PT_stabilization,
  1297. CLIP_PT_mask,
  1298. CLIP_PT_mask_layers,
  1299. CLIP_PT_mask_display,
  1300. CLIP_PT_active_mask_spline,
  1301. CLIP_PT_active_mask_point,
  1302. CLIP_PT_tools_mask_transforms,
  1303. CLIP_PT_tools_mask_tools,
  1304. CLIP_PT_tools_scenesetup,
  1305. CLIP_PT_grease_pencil,
  1306. CLIP_PT_tools_grease_pencil_draw,
  1307. CLIP_MT_view,
  1308. CLIP_MT_clip,
  1309. CLIP_MT_proxy,
  1310. CLIP_MT_reconstruction,
  1311. CLIP_MT_track_visibility,
  1312. CLIP_MT_track_transform,
  1313. CLIP_MT_select,
  1314. CLIP_MT_select_grouped,
  1315. CLIP_MT_tracking_context_menu,
  1316. CLIP_PT_camera_presets,
  1317. CLIP_PT_track_color_presets,
  1318. CLIP_PT_tracking_settings_presets,
  1319. CLIP_MT_stabilize_2d_context_menu,
  1320. CLIP_MT_stabilize_2d_rotation_context_menu,
  1321. CLIP_MT_pivot_pie,
  1322. CLIP_MT_marker_pie,
  1323. CLIP_MT_tracking_pie,
  1324. CLIP_MT_reconstruction_pie,
  1325. CLIP_MT_solving_pie,
  1326. CLIP_MT_mask_handle_type_menu
  1327. )
  1328. if __name__ == "__main__": # only for live edit.
  1329. from bpy.utils import register_class
  1330. for cls in classes:
  1331. register_class(cls)