presets.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  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 compliant>
  19. import bpy
  20. from bpy.types import (
  21. Menu,
  22. Operator,
  23. WindowManager,
  24. )
  25. from bpy.props import (
  26. BoolProperty,
  27. StringProperty,
  28. )
  29. # For preset popover menu
  30. WindowManager.preset_name = StringProperty(
  31. name="Preset Name",
  32. description="Name for new preset",
  33. default="New Preset"
  34. )
  35. class AddPresetBase:
  36. """Base preset class, only for subclassing
  37. subclasses must define
  38. - preset_values
  39. - preset_subdir """
  40. # bl_idname = "script.preset_base_add"
  41. # bl_label = "Add a Python Preset"
  42. # only because invoke_props_popup requires. Also do not add to search menu.
  43. bl_options = {'REGISTER', 'INTERNAL'}
  44. name: StringProperty(
  45. name="Name",
  46. description="Name of the preset, used to make the path name",
  47. maxlen=64,
  48. options={'SKIP_SAVE'},
  49. )
  50. remove_name: BoolProperty(
  51. default=False,
  52. options={'HIDDEN', 'SKIP_SAVE'},
  53. )
  54. remove_active: BoolProperty(
  55. default=False,
  56. options={'HIDDEN', 'SKIP_SAVE'},
  57. )
  58. @staticmethod
  59. def as_filename(name): # could reuse for other presets
  60. # lazy init maketrans
  61. def maketrans_init():
  62. cls = AddPresetBase
  63. attr = "_as_filename_trans"
  64. trans = getattr(cls, attr, None)
  65. if trans is None:
  66. trans = str.maketrans({char: "_" for char in " !@#$%^&*(){}:\";'[]<>,.\\/?"})
  67. setattr(cls, attr, trans)
  68. return trans
  69. name = name.lower().strip()
  70. name = bpy.path.display_name_to_filepath(name)
  71. trans = maketrans_init()
  72. return name.translate(trans)
  73. def execute(self, context):
  74. import os
  75. if hasattr(self, "pre_cb"):
  76. self.pre_cb(context)
  77. preset_menu_class = getattr(bpy.types, self.preset_menu)
  78. is_xml = getattr(preset_menu_class, "preset_type", None) == 'XML'
  79. if is_xml:
  80. ext = ".xml"
  81. else:
  82. ext = ".py"
  83. name = self.name.strip()
  84. if not (self.remove_name or self.remove_active):
  85. if not name:
  86. return {'FINISHED'}
  87. # Reset preset name
  88. wm = bpy.data.window_managers[0]
  89. if name == wm.preset_name:
  90. wm.preset_name = 'New Preset'
  91. filename = self.as_filename(name)
  92. target_path = os.path.join("presets", self.preset_subdir)
  93. target_path = bpy.utils.user_resource('SCRIPTS',
  94. target_path,
  95. create=True)
  96. if not target_path:
  97. self.report({'WARNING'}, "Failed to create presets path")
  98. return {'CANCELLED'}
  99. filepath = os.path.join(target_path, filename) + ext
  100. if hasattr(self, "add"):
  101. self.add(context, filepath)
  102. else:
  103. print("Writing Preset: %r" % filepath)
  104. if is_xml:
  105. import rna_xml
  106. rna_xml.xml_file_write(context,
  107. filepath,
  108. preset_menu_class.preset_xml_map)
  109. else:
  110. def rna_recursive_attr_expand(value, rna_path_step, level):
  111. if isinstance(value, bpy.types.PropertyGroup):
  112. for sub_value_attr in value.bl_rna.properties.keys():
  113. if sub_value_attr == "rna_type":
  114. continue
  115. sub_value = getattr(value, sub_value_attr)
  116. rna_recursive_attr_expand(sub_value, "%s.%s" % (rna_path_step, sub_value_attr), level)
  117. elif type(value).__name__ == "bpy_prop_collection_idprop": # could use nicer method
  118. file_preset.write("%s.clear()\n" % rna_path_step)
  119. for sub_value in value:
  120. file_preset.write("item_sub_%d = %s.add()\n" % (level, rna_path_step))
  121. rna_recursive_attr_expand(sub_value, "item_sub_%d" % level, level + 1)
  122. else:
  123. # convert thin wrapped sequences
  124. # to simple lists to repr()
  125. try:
  126. value = value[:]
  127. except:
  128. pass
  129. file_preset.write("%s = %r\n" % (rna_path_step, value))
  130. file_preset = open(filepath, 'w', encoding="utf-8")
  131. file_preset.write("import bpy\n")
  132. if hasattr(self, "preset_defines"):
  133. for rna_path in self.preset_defines:
  134. exec(rna_path)
  135. file_preset.write("%s\n" % rna_path)
  136. file_preset.write("\n")
  137. for rna_path in self.preset_values:
  138. value = eval(rna_path)
  139. rna_recursive_attr_expand(value, rna_path, 1)
  140. file_preset.close()
  141. preset_menu_class.bl_label = bpy.path.display_name(filename)
  142. else:
  143. if self.remove_active:
  144. name = preset_menu_class.bl_label
  145. # fairly sloppy but convenient.
  146. filepath = bpy.utils.preset_find(name,
  147. self.preset_subdir,
  148. ext=ext)
  149. if not filepath:
  150. filepath = bpy.utils.preset_find(name,
  151. self.preset_subdir,
  152. display_name=True,
  153. ext=ext)
  154. if not filepath:
  155. return {'CANCELLED'}
  156. try:
  157. if hasattr(self, "remove"):
  158. self.remove(context, filepath)
  159. else:
  160. os.remove(filepath)
  161. except Exception as e:
  162. self.report({'ERROR'}, "Unable to remove preset: %r" % e)
  163. import traceback
  164. traceback.print_exc()
  165. return {'CANCELLED'}
  166. # XXX, stupid!
  167. preset_menu_class.bl_label = "Presets"
  168. if hasattr(self, "post_cb"):
  169. self.post_cb(context)
  170. return {'FINISHED'}
  171. def check(self, _context):
  172. self.name = self.as_filename(self.name.strip())
  173. def invoke(self, context, _event):
  174. if not (self.remove_active or self.remove_name):
  175. wm = context.window_manager
  176. return wm.invoke_props_dialog(self)
  177. else:
  178. return self.execute(context)
  179. class ExecutePreset(Operator):
  180. """Execute a preset"""
  181. bl_idname = "script.execute_preset"
  182. bl_label = "Execute a Python Preset"
  183. filepath: StringProperty(
  184. subtype='FILE_PATH',
  185. options={'SKIP_SAVE'},
  186. )
  187. menu_idname: StringProperty(
  188. name="Menu ID Name",
  189. description="ID name of the menu this was called from",
  190. options={'SKIP_SAVE'},
  191. )
  192. def execute(self, context):
  193. from os.path import basename, splitext
  194. filepath = self.filepath
  195. # change the menu title to the most recently chosen option
  196. preset_class = getattr(bpy.types, self.menu_idname)
  197. preset_class.bl_label = bpy.path.display_name(basename(filepath))
  198. ext = splitext(filepath)[1].lower()
  199. if ext not in {".py", ".xml"}:
  200. self.report({'ERROR'}, "unknown filetype: %r" % ext)
  201. return {'CANCELLED'}
  202. if hasattr(preset_class, "reset_cb"):
  203. preset_class.reset_cb(context)
  204. if ext == ".py":
  205. try:
  206. bpy.utils.execfile(filepath)
  207. except Exception as ex:
  208. self.report({'ERROR'}, "Failed to execute the preset: " + repr(ex))
  209. elif ext == ".xml":
  210. import rna_xml
  211. rna_xml.xml_file_run(context,
  212. filepath,
  213. preset_class.preset_xml_map)
  214. if hasattr(preset_class, "post_cb"):
  215. preset_class.post_cb(context)
  216. return {'FINISHED'}
  217. class AddPresetRender(AddPresetBase, Operator):
  218. """Add or remove a Render Preset"""
  219. bl_idname = "render.preset_add"
  220. bl_label = "Add Render Preset"
  221. preset_menu = "RENDER_PT_presets"
  222. preset_defines = [
  223. "scene = bpy.context.scene"
  224. ]
  225. preset_values = [
  226. "scene.render.fps",
  227. "scene.render.fps_base",
  228. "scene.render.pixel_aspect_x",
  229. "scene.render.pixel_aspect_y",
  230. "scene.render.resolution_percentage",
  231. "scene.render.resolution_x",
  232. "scene.render.resolution_y",
  233. ]
  234. preset_subdir = "render"
  235. class AddPresetCamera(AddPresetBase, Operator):
  236. """Add or remove a Camera Preset"""
  237. bl_idname = "camera.preset_add"
  238. bl_label = "Add Camera Preset"
  239. preset_menu = "CAMERA_PT_presets"
  240. preset_defines = [
  241. "cam = bpy.context.camera"
  242. ]
  243. preset_subdir = "camera"
  244. use_focal_length: BoolProperty(
  245. name="Include Focal Length",
  246. description="Include focal length into the preset",
  247. options={'SKIP_SAVE'},
  248. )
  249. @property
  250. def preset_values(self):
  251. preset_values = [
  252. "cam.sensor_width",
  253. "cam.sensor_height",
  254. "cam.sensor_fit"
  255. ]
  256. if self.use_focal_length:
  257. preset_values.append("cam.lens")
  258. preset_values.append("cam.lens_unit")
  259. return preset_values
  260. class AddPresetSafeAreas(AddPresetBase, Operator):
  261. """Add or remove a Safe Areas Preset"""
  262. bl_idname = "safe_areas.preset_add"
  263. bl_label = "Add Safe Area Preset"
  264. preset_menu = "SAFE_AREAS_PT_presets"
  265. preset_defines = [
  266. "safe_areas = bpy.context.scene.safe_areas"
  267. ]
  268. preset_values = [
  269. "safe_areas.title",
  270. "safe_areas.action",
  271. "safe_areas.title_center",
  272. "safe_areas.action_center",
  273. ]
  274. preset_subdir = "safe_areas"
  275. class AddPresetCloth(AddPresetBase, Operator):
  276. """Add or remove a Cloth Preset"""
  277. bl_idname = "cloth.preset_add"
  278. bl_label = "Add Cloth Preset"
  279. preset_menu = "CLOTH_PT_presets"
  280. preset_defines = [
  281. "cloth = bpy.context.cloth"
  282. ]
  283. preset_values = [
  284. "cloth.settings.quality",
  285. "cloth.settings.mass",
  286. "cloth.settings.air_damping",
  287. "cloth.settings.bending_model",
  288. "cloth.settings.tension_stiffness",
  289. "cloth.settings.compression_stiffness",
  290. "cloth.settings.shear_stiffness",
  291. "cloth.settings.bending_stiffness",
  292. "cloth.settings.tension_damping",
  293. "cloth.settings.compression_damping",
  294. "cloth.settings.shear_damping",
  295. "cloth.settings.bending_damping",
  296. ]
  297. preset_subdir = "cloth"
  298. class AddPresetFluid(AddPresetBase, Operator):
  299. """Add or remove a Fluid Preset"""
  300. bl_idname = "fluid.preset_add"
  301. bl_label = "Add Fluid Preset"
  302. preset_menu = "FLUID_PT_presets"
  303. preset_defines = [
  304. "fluid = bpy.context.fluid"
  305. ]
  306. preset_values = [
  307. "fluid.settings.viscosity_base",
  308. "fluid.settings.viscosity_exponent",
  309. ]
  310. preset_subdir = "fluid"
  311. class AddPresetHairDynamics(AddPresetBase, Operator):
  312. """Add or remove a Hair Dynamics Preset"""
  313. bl_idname = "particle.hair_dynamics_preset_add"
  314. bl_label = "Add Hair Dynamics Preset"
  315. preset_menu = "PARTICLE_PT_hair_dynamics_presets"
  316. preset_defines = [
  317. "psys = bpy.context.particle_system",
  318. "cloth = bpy.context.particle_system.cloth",
  319. "settings = bpy.context.particle_system.cloth.settings",
  320. "collision = bpy.context.particle_system.cloth.collision_settings",
  321. ]
  322. preset_subdir = "hair_dynamics"
  323. preset_values = [
  324. "settings.quality",
  325. "settings.mass",
  326. "settings.bending_stiffness",
  327. "psys.settings.bending_random",
  328. "settings.bending_damping",
  329. "settings.air_damping",
  330. "settings.internal_friction",
  331. "settings.density_target",
  332. "settings.density_strength",
  333. "settings.voxel_cell_size",
  334. "settings.pin_stiffness",
  335. ]
  336. class AddPresetTrackingCamera(AddPresetBase, Operator):
  337. """Add or remove a Tracking Camera Intrinsics Preset"""
  338. bl_idname = "clip.camera_preset_add"
  339. bl_label = "Add Camera Preset"
  340. preset_menu = "CLIP_PT_camera_presets"
  341. preset_defines = [
  342. "camera = bpy.context.edit_movieclip.tracking.camera"
  343. ]
  344. preset_subdir = "tracking_camera"
  345. use_focal_length: BoolProperty(
  346. name="Include Focal Length",
  347. description="Include focal length into the preset",
  348. options={'SKIP_SAVE'},
  349. default=True,
  350. )
  351. @property
  352. def preset_values(self):
  353. preset_values = [
  354. "camera.sensor_width",
  355. "camera.pixel_aspect",
  356. "camera.k1",
  357. "camera.k2",
  358. "camera.k3"
  359. ]
  360. if self.use_focal_length:
  361. preset_values.append("camera.units")
  362. preset_values.append("camera.focal_length")
  363. return preset_values
  364. class AddPresetTrackingTrackColor(AddPresetBase, Operator):
  365. """Add or remove a Clip Track Color Preset"""
  366. bl_idname = "clip.track_color_preset_add"
  367. bl_label = "Add Track Color Preset"
  368. preset_menu = "CLIP_PT_track_color_presets"
  369. preset_defines = [
  370. "track = bpy.context.edit_movieclip.tracking.tracks.active"
  371. ]
  372. preset_values = [
  373. "track.color",
  374. "track.use_custom_color"
  375. ]
  376. preset_subdir = "tracking_track_color"
  377. class AddPresetTrackingSettings(AddPresetBase, Operator):
  378. """Add or remove a motion tracking settings preset"""
  379. bl_idname = "clip.tracking_settings_preset_add"
  380. bl_label = "Add Tracking Settings Preset"
  381. preset_menu = "CLIP_PT_tracking_settings_presets"
  382. preset_defines = [
  383. "settings = bpy.context.edit_movieclip.tracking.settings"
  384. ]
  385. preset_values = [
  386. "settings.default_correlation_min",
  387. "settings.default_pattern_size",
  388. "settings.default_search_size",
  389. "settings.default_frames_limit",
  390. "settings.default_pattern_match",
  391. "settings.default_margin",
  392. "settings.default_motion_model",
  393. "settings.use_default_brute",
  394. "settings.use_default_normalization",
  395. "settings.use_default_mask",
  396. "settings.use_default_red_channel",
  397. "settings.use_default_green_channel",
  398. "settings.use_default_blue_channel"
  399. "settings.default_weight"
  400. ]
  401. preset_subdir = "tracking_settings"
  402. class AddPresetNodeColor(AddPresetBase, Operator):
  403. """Add or remove a Node Color Preset"""
  404. bl_idname = "node.node_color_preset_add"
  405. bl_label = "Add Node Color Preset"
  406. preset_menu = "NODE_PT_node_color_presets"
  407. preset_defines = [
  408. "node = bpy.context.active_node"
  409. ]
  410. preset_values = [
  411. "node.color",
  412. "node.use_custom_color"
  413. ]
  414. preset_subdir = "node_color"
  415. class AddPresetInterfaceTheme(AddPresetBase, Operator):
  416. """Add or remove a theme preset"""
  417. bl_idname = "wm.interface_theme_preset_add"
  418. bl_label = "Add Theme Preset"
  419. preset_menu = "USERPREF_MT_interface_theme_presets"
  420. preset_subdir = "interface_theme"
  421. class AddPresetKeyconfig(AddPresetBase, Operator):
  422. """Add or remove a Key-config Preset"""
  423. bl_idname = "wm.keyconfig_preset_add"
  424. bl_label = "Add Keyconfig Preset"
  425. preset_menu = "USERPREF_MT_keyconfigs"
  426. preset_subdir = "keyconfig"
  427. def add(self, _context, filepath):
  428. bpy.ops.preferences.keyconfig_export(filepath=filepath)
  429. bpy.utils.keyconfig_set(filepath)
  430. def pre_cb(self, context):
  431. keyconfigs = bpy.context.window_manager.keyconfigs
  432. if self.remove_active:
  433. preset_menu_class = getattr(bpy.types, self.preset_menu)
  434. preset_menu_class.bl_label = keyconfigs.active.name
  435. def post_cb(self, context):
  436. keyconfigs = bpy.context.window_manager.keyconfigs
  437. if self.remove_active:
  438. keyconfigs.remove(keyconfigs.active)
  439. class AddPresetOperator(AddPresetBase, Operator):
  440. """Add or remove an Operator Preset"""
  441. bl_idname = "wm.operator_preset_add"
  442. bl_label = "Operator Preset"
  443. preset_menu = "WM_MT_operator_presets"
  444. operator: StringProperty(
  445. name="Operator",
  446. maxlen=64,
  447. options={'HIDDEN', 'SKIP_SAVE'},
  448. )
  449. preset_defines = [
  450. "op = bpy.context.active_operator",
  451. ]
  452. @property
  453. def preset_subdir(self):
  454. return AddPresetOperator.operator_path(self.operator)
  455. @property
  456. def preset_values(self):
  457. properties_blacklist = Operator.bl_rna.properties.keys()
  458. prefix, suffix = self.operator.split("_OT_", 1)
  459. op = getattr(getattr(bpy.ops, prefix.lower()), suffix)
  460. operator_rna = op.get_rna_type()
  461. del op
  462. ret = []
  463. for prop_id, prop in operator_rna.properties.items():
  464. if not (prop.is_hidden or prop.is_skip_save):
  465. if prop_id not in properties_blacklist:
  466. ret.append("op.%s" % prop_id)
  467. return ret
  468. @staticmethod
  469. def operator_path(operator):
  470. import os
  471. prefix, suffix = operator.split("_OT_", 1)
  472. return os.path.join("operator", "%s.%s" % (prefix.lower(), suffix))
  473. class WM_MT_operator_presets(Menu):
  474. bl_label = "Operator Presets"
  475. def draw(self, context):
  476. self.operator = context.active_operator.bl_idname
  477. # dummy 'default' menu item
  478. layout = self.layout
  479. layout.operator("wm.operator_defaults")
  480. layout.separator()
  481. Menu.draw_preset(self, context)
  482. @property
  483. def preset_subdir(self):
  484. return AddPresetOperator.operator_path(self.operator)
  485. preset_operator = "script.execute_preset"
  486. class AddPresetGpencilBrush(AddPresetBase, Operator):
  487. """Add or remove grease pencil brush preset"""
  488. bl_idname = "scene.gpencil_brush_preset_add"
  489. bl_label = "Add Grease Pencil Brush Preset"
  490. preset_menu = "VIEW3D_PT_gpencil_brush_presets"
  491. preset_defines = [
  492. "brush = bpy.context.tool_settings.gpencil_paint.brush",
  493. "settings = brush.gpencil_settings"
  494. ]
  495. preset_values = [
  496. "settings.input_samples",
  497. "settings.active_smooth_factor",
  498. "settings.angle",
  499. "settings.angle_factor",
  500. "settings.use_settings_stabilizer",
  501. "brush.smooth_stroke_radius",
  502. "brush.smooth_stroke_factor",
  503. "settings.pen_smooth_factor",
  504. "settings.pen_smooth_steps",
  505. "settings.pen_thick_smooth_factor",
  506. "settings.pen_thick_smooth_steps",
  507. "settings.pen_subdivision_steps",
  508. "settings.random_subdiv",
  509. "settings.use_settings_random",
  510. "settings.random_pressure",
  511. "settings.random_strength",
  512. "settings.uv_random",
  513. "settings.pen_jitter",
  514. "settings.use_jitter_pressure",
  515. "settings.trim",
  516. ]
  517. preset_subdir = "gpencil_brush"
  518. class AddPresetGpencilMaterial(AddPresetBase, Operator):
  519. """Add or remove grease pencil material preset"""
  520. bl_idname = "scene.gpencil_material_preset_add"
  521. bl_label = "Add Grease Pencil Material Preset"
  522. preset_menu = "MATERIAL_PT_gpencil_material_presets"
  523. preset_defines = [
  524. "material = bpy.context.object.active_material",
  525. "gpcolor = material.grease_pencil"
  526. ]
  527. preset_values = [
  528. "gpcolor.mode",
  529. "gpcolor.stroke_style",
  530. "gpcolor.color",
  531. "gpcolor.stroke_image",
  532. "gpcolor.pixel_size",
  533. "gpcolor.use_stroke_pattern",
  534. "gpcolor.use_stroke_texture_mix",
  535. "gpcolor.mix_stroke_factor",
  536. "gpcolor.alignment_mode",
  537. "gpcolor.fill_style",
  538. "gpcolor.fill_color",
  539. "gpcolor.fill_image",
  540. "gpcolor.gradient_type",
  541. "gpcolor.mix_color",
  542. "gpcolor.mix_factor",
  543. "gpcolor.flip",
  544. "gpcolor.pattern_shift",
  545. "gpcolor.pattern_scale",
  546. "gpcolor.pattern_radius",
  547. "gpcolor.pattern_angle",
  548. "gpcolor.pattern_gridsize",
  549. "gpcolor.use_fill_pattern",
  550. "gpcolor.texture_offset",
  551. "gpcolor.texture_scale",
  552. "gpcolor.texture_angle",
  553. "gpcolor.texture_opacity",
  554. "gpcolor.texture_clamp",
  555. "gpcolor.use_fill_texture_mix",
  556. "gpcolor.mix_factor",
  557. "gpcolor.show_stroke",
  558. "gpcolor.show_fill",
  559. ]
  560. preset_subdir = "gpencil_material"
  561. classes = (
  562. AddPresetCamera,
  563. AddPresetCloth,
  564. AddPresetFluid,
  565. AddPresetHairDynamics,
  566. AddPresetInterfaceTheme,
  567. AddPresetKeyconfig,
  568. AddPresetNodeColor,
  569. AddPresetOperator,
  570. AddPresetRender,
  571. AddPresetSafeAreas,
  572. AddPresetTrackingCamera,
  573. AddPresetTrackingSettings,
  574. AddPresetTrackingTrackColor,
  575. AddPresetGpencilBrush,
  576. AddPresetGpencilMaterial,
  577. ExecutePreset,
  578. WM_MT_operator_presets,
  579. )