Leveraging the preset system
A while back when doing some addon maintenance, changed the preset code for the add curve extra objects addon for 2.7x. In particular add curve spirals.
Can leverage off the existing preset code to emulate the 'PRESET' option. This way can choose what goes in the preset, what folder to save in, the menu and the operator to execute the preset.
Code snippets from /2.79/scripts/addons/add_curve_extra_objects/add_curve_spirals.py
Firstly there is an add preset base base class to inherit
from bl_operators.presets import AddPresetBase
The operator that creates the presets, notice can set the subdir here, defines in the script, and what properties to save in the preset. It is also associated with a menu.
class CURVE_EXTRAS_OT_spirals_presets(AddPresetBase, Operator):
bl_idname = "curve_extras.spiral_presets"
bl_label = "Spirals"
bl_description = "Spirals Presets"
preset_menu = "OBJECT_MT_spiral_curve_presets"
preset_subdir = "curve_extras/curve.spirals"
preset_defines = [
"op = bpy.context.active_operator",
]
preset_values = [
"op.spiral_type",
"op.curve_type",
"op.spiral_direction",
"op.turns",
"op.steps",
"op.radius",
"op.dif_z",
"op.dif_radius",
"op.B_force",
"op.inner_radius",
"op.dif_inner_radius",
"op.cycles",
"op.curves_number",
"op.touch",
]
its associated menu class. The bpy.types.Menu class has a 'draw_preset(..)` class method that draws the menu from the files in the presets folder. The default preset execute operator, which runs the code within the preset file setting the props is assigned as the operator of each menu item.
class OBJECT_MT_spiral_curve_presets(Menu):
'''Presets for curve.spiral'''
bl_label = "Spiral Curve Presets"
bl_idname = "OBJECT_MT_spiral_curve_presets"
preset_subdir = "curve_extras/curve.spirals"
preset_operator = "script.execute_preset"
draw = bpy.types.Menu.draw_preset
In the draw method of the operator that the presets are for
def draw(self, context):
layout = self.layout
col = layout.column_flow(align=True)
col.label("Presets:")
row = col.row(align=True)
row.menu("OBJECT_MT_spiral_curve_presets",
text=bpy.types.OBJECT_MT_spiral_curve_presets.bl_label)
row.operator("curve_extras.spiral_presets", text="", icon='ZOOMIN')
op = row.operator("curve_extras.spiral_presets", text="", icon='ZOOMOUT')
op.remove_active = True
With this set up presets are being saved to or loaded from the defined folder. This way if your operators A and B have similar (same) structure can draw their presets from the same folder.
Also Look for code in addon prefs in __init__.py to convert from the old preset locations to new presets.
C:\Users\USERNAME\AppData\Roaming\Blender Foundation\Blender\2.80\scripts\presetsinstead of my custom scripts path – aliasguru Mar 18 '19 at 16:48os.path.join(os.path.dirname(os.path.abspath(__file__)) , 'my_addon')to work around it, but absolute paths are not allowed it seems. Is there a magic flag I missed? – aliasguru Mar 18 '19 at 16:49bl_operators.presets. Is expected path set via EV same asbpy.utils.script_path_user()and or showing inbpy.utils.script_paths("presets")? – batFINGER Mar 18 '19 at 17:13class AddPresetBase:fromrelease/scripts/startup/bl_operatorsin the Blender source code. There they construct the file path frombpy.utils.user_resource('SCRIPTS', target_path, create=True)which technically would yield the correct path (it does so when run from a blender console). Not sure why this fails on inheritance. – aliasguru Mar 18 '19 at 17:13bpy.utils.user_resource('SCRIPTS', create=False)yields the correct path.bpy.utils.user_resource('SCRIPTS', 'test', create=False)defaults back to the AppData blah blah one... Must be a Blender bug? – aliasguru Mar 18 '19 at 17:20bpy.utils.script_paths("presets")andbpy.utils.script_path_user()work, but the first one returns two locations as a list, having the one I want ordered last. I've created a bug report https://developer.blender.org/T62736 to see what the devs think about this. – aliasguru Mar 19 '19 at 08:09