Page MenuHome

Move python preset serialization in AddPresetBase into a separate function to allow easier extension of presets.
Needs ReviewPublic

Authored by Lukas Tönne (lukastoenne) on Jun 16 2015, 6:17 PM.
This revision needs review, but there are no reviewers specified.

Details

Reviewers
None
Summary

The AddPresetBase class by default uses a simple key:value map for RNA property values. This is not sufficient in many cases for specialized behavior or complex property types.

To make the extension of presets more convenient while keeping most of the functionality, the write_preset_py function can now be implemented in subclasses. Preset operators can use the existing key:value implementation or write their own version for arbitrary preset code.

(note: this is a backport of rB076b65e67787447b40226664039dafb87743b0b5 from the gooseberry branch)

Example 1:
Very simple: we want to print a hello world! before writing properties to the preset:

class AddPresetHello(AddPresetBase, Operator):
    preset_menu = "OBJECT_MT_presets_hello"

    preset_defines = [
        "ob = bpy.context.object",
    ]

    preset_subdir = "hello_world"

    preset_values = [
        "ob.location",
        ]

    # our own version of write_preset_py, adding a print call
    def write_preset_py(self, file_preset):
        print("hello world!")

        # call the original implementation to serialize preset_values
        AddPresetBase.write_preset_py(self, file_preset)

Example 2:
Imagine we had a CurveMapping property dummy_curve in Object. We have to write a customized serialization method, since it's not trivial to convert into python. Our implementation of write_preset_py replaces the simple dictionary approach.

class AddPresetCurves(AddPresetBase, Operator):
    preset_menu = "OBJECT_MT_presets_dummy_curve"

    preset_subdir = "dummy_curve"

    preset_defines = [
        "ob = bpy.context.object",
    ]

    def write_curve_map(self, file_preset, cuma, prop):
        if cuma is None:
            return

        file_preset.write("from mathutils import *\n")

        file_preset.write("cuma = %s\n" % prop)
        file_preset.write("if cuma:\n")

        file_preset.write("    cuma.black_level = %r\n" % cuma.black_level)
        file_preset.write("    cuma.white_level = %r\n" % cuma.white_level)

        file_preset.write("    cuma.use_clip = %r\n" % cuma.use_clip)
        if cuma.use_clip:
            file_preset.write("    cuma.clip_min_x = %r\n" % cuma.clip_min_x)
            file_preset.write("    cuma.clip_max_x = %r\n" % cuma.clip_max_x)
            file_preset.write("    cuma.clip_min_y = %r\n" % cuma.clip_min_y)
            file_preset.write("    cuma.clip_max_y = %r\n" % cuma.clip_max_y)

        for i, cu in enumerate(cuma.curves):
            file_preset.write("    cu = cuma.curves[%d]\n" % i)
            file_preset.write("    cu.extend = %r\n" % cu.extend)
            file_preset.write("    for p in range(max(len(cu.points) - %d, 0)):\n" % len(cu.points))
            file_preset.write("        cu.points.remove(cu.points[0])\n")
            file_preset.write("    for i in range(max(%d - len(cu.points), 0)):\n" % len(cu.points))
            file_preset.write("        cu.points.new(0, 0)\n")
            for j, p in enumerate(cu.points):
                file_preset.write("    cu.points[%d].handle_type = %r\n" % (j, p.handle_type))
                file_preset.write("    cu.points[%d].location = %r\n" % (j, p.location))
                file_preset.write("    cu.points[%d].select = %r\n" % (j, p.select))

        file_preset.write("    cuma.update()\n")

    def write_preset_py(self, file_preset):
        ob = bpy.context.object
        self.write_curve_map(file_preset, ob.dummy_curve, "ob.dummy_curve")

Diff Detail

Repository
rB Blender
Branch
preset_extensions

Event Timeline

Lukas Tönne (lukastoenne) retitled this revision from to Move python preset serialization in AddPresetBase into a separate function to allow easier extension of presets..
Lukas Tönne (lukastoenne) updated this object.