5
$\begingroup$

Hey I was wondering it it would be possible to store the stats of the different things I made in the user interface. So each option in the drop down menu would store different information. Also I would like the add option so they could add more groups in and therefore take them away... Any help would be greatly appreciated!!! import bpy from bpy.props import * import math import mathutils

class TargetMakerPanel(bpy.types.Panel) :
    bl_space_type = "VIEW_3D"
    bl_region_type = "TOOLS"
    bl_context = "objectmode"
    bl_label = "CrowD"
    def draw(self, context) :
        layout = self.layout
        layout = self.layout
        TheCol = self.layout.row(align = True)
        TheCol.operator("mesh.make_target", text = "Add Target")
        TheCol.prop(context.scene, "Render_Target")
        TheCol = self.layout.row(align = True)
        TheCol.prop(context.scene, "GroupSelection")
        TheCol.operator("render.preset_add", text="", icon='ZOOMIN')
        TheCol.operator("render.preset_add", text="", icon='ZOOMOUT').remove_active = True
        row = layout.row()
        row.prop(context.scene, "Mingle")
        row = layout.row()
        row.prop(context.scene, "People_Name")
        layout.label(text=" Random Speed:")
        row = layout.row()
        row.prop(context.scene, "Min_Speed")
        row.prop(context.scene, "Max_Speed")
        layout.label(text=" Random Spawn minimum:")
        row = layout.row(align=True)
        row.prop(context.scene, "Min_X")
        row.prop(context.scene, "Min_Y")
        row.prop(context.scene, "Min_Z")
        layout.label(text=" Random Spawn maximum:")
        row = layout.row(align=True)
        row.prop(context.scene, "Max_X")
        row.prop(context.scene, "Max_Y")
        row.prop(context.scene, "Max_Z")
        layout.label(text=" Number of people to spawn:")
        row = layout.row(align=True)
        row.prop(context.scene, "SpawnCount")

bpy.types.Scene.Mingle = bpy.props.BoolProperty\
(
    name = "Mingle",
    description = "Decides if people should mingle or not."
    ) 
bpy.types.Scene.Render_Target = bpy.props.BoolProperty\
(
    name = "Render Target",
    default = False,
    description = "Decides if the Target plane should be rendered."
    )       
bpy.types.Scene.Min_Speed= bpy.props.IntProperty\
    (
    name = "MinSpeed",
    default = 1,
    description = "Minimum speed of the people."
    )        
bpy.types.Scene.Max_Speed= bpy.props.IntProperty\
    (
    name = "MaxSpeed",
    default = 1,
    description = "Maximum speed of the people."
    ) 
bpy.types.Scene.Min_X= bpy.props.IntProperty\
    (
    name = "Min X",
    default = 1,
    description = "Minimum X location of the people."
    ) 
bpy.types.Scene.Min_Y= bpy.props.IntProperty\
    (
    name = "Min Y",
    default = 1,
    description = "Minimum Y location of the people."
    ) 
bpy.types.Scene.Min_Z= bpy.props.IntProperty\
    (
    name = "Min Z",
    default = 1,
    description = "Minimum Z location of the people."
    ) 
bpy.types.Scene.Max_X= bpy.props.IntProperty\
    (
    name = "Max X",
    default = 1,
    description = "Maximum X location of the people"
    ) 
bpy.types.Scene.Max_Y= bpy.props.IntProperty\
    (
    name = "Max Y",
    default = 1,
    description = "Maximum Y location of the people"
    ) 
bpy.types.Scene.Max_Z= bpy.props.IntProperty\
    (
    name = "Max Z",
    default = 1,
    description = "Maximum Z location of the people"
    ) 
bpy.types.Scene.People_Name = bpy.props.StringProperty\
    (
    name = "Spawn Names",
    description = "The name the people will be called when spawned"
    )
bpy.types.Scene.SpawnCount= bpy.props.IntProperty\
    (
    name = "Spawn Count",
    default = 10,
    description = "How many people should spawn"
    ) 
bpy.types.Scene.GroupSelection = EnumProperty(
        items = [("1", "Group 1", "First Group"),
                 ("2", "Group 2", "Second Group"),
                 ("3", "Group 3", "Third Group")],
        name = "GroupNumber")


class MakeTarget(bpy.types.Operator) :
    bl_idname = "mesh.make_target"
    bl_label = "Add Target"
    bl_options = {"UNDO"}

    def invoke(self, context, event):

        Vertices = \
          [
            mathutils.Vector((-2, -2,0)),
            mathutils.Vector((2, -2, 0)),
            mathutils.Vector((2, 2, 0)),
            mathutils.Vector((-2, 2, 0)),

          ]
        NewMesh = bpy.data.meshes.new("Target")
        NewMesh.from_pydata \
          (
            Vertices,
            [],
            [[0, 1, 2], [0, 1, 3], [1, 2, 3], [2, 0, 3]]
          )
        NewMesh.update()
        NewObj = bpy.data.objects.new("Target", NewMesh)
        context.scene.objects.link(NewObj)     
        if context.scene.Render_Target == True:
            bpy.data.objects["Target"].hide_render = False
        if context.scene.Render_Target == False:
            bpy.data.objects["Target"].hide_render = True
        return {"FINISHED"}
    #end invoke


def register() :
    bpy.utils.register_class(MakeTarget)
    bpy.utils.register_class(TargetMakerPanel)

def unregister() :
    bpy.utils.unregister_class(MakeTarget)
    bpy.utils.unregister_class(TargetMakerPanel)

if __name__ == "__main__" :
    register()
$\endgroup$
2
  • $\begingroup$ This is basically two questions in one. My answer is a suggestion to one of them, namely user-editable group selection list. $\endgroup$
    – Adhi
    Aug 23, 2013 at 1:01
  • $\begingroup$ An aside: consider using a vector property instead of specifying x, y and z separately. $\endgroup$
    – z0r
    Aug 23, 2013 at 1:59

1 Answer 1

11
$\begingroup$

You can make use of Blender's as yet undocumented preset system.

Operator

First, make an operator that's also subclassing from bl_operators.presets.AddPresetBase to define values to store:

import bpy
from bl_operators.presets import AddPresetBase

class RENDER_OT_my_preset_add(AddPresetBase, bpy.types.Operator):
    """Add a new render preset."""
    bl_idname = 'render.my_preset_add'
    bl_label = 'Add My Render Preset'
    bl_options = {'REGISTER', 'UNDO'}
    preset_menu = 'RENDER_MT_my_presets'
    preset_subdir = 'my_render_preset'

    preset_defines = [
        "scene  = bpy.context.scene",
        "render = bpy.context.scene.render",
        "image  = bpy.context.scene.render.image_settings",
        ]

    preset_values = [
        "scene.use_preview_range",
        "render.engine",
        "render.use_stamp",
        "image.file_format",
        ]

In an AddPresetBase-derived operator, several attributes need to be defined:

  • preset_menu, menu class that will display preset items.
  • preset_subdir, subdirectory of scripts/presets/ that will store preset files.
  • preset_defines, whatever needs to be defined before variable storage operation, including creation of variables to be stored.
  • preset_values, variables whose value will be stored in the preset.

Menu

Next, the menu itself:

class RENDER_MT_my_presets(bpy.types.Menu):
    '''Presets for render settings.'''
    bl_label = "My Render Presets"
    bl_idname = "RENDER_MT_my_presets"
    preset_subdir = "my_render_preset"
    preset_operator = "script.execute_preset"

    draw = bpy.types.Menu.draw_preset

It's an ordinary menu with two attributes defined:

  • preset_subdir, same as for the operator, above.
  • preset_operator, operator class related to this menu.

Also provide bpy.types.Menu.draw_preset as the menu's draw function.

Each preset will be saved as a Python script in preset_subdir, and these classes enforce file (therefore preset) naming. There are ways to bypass preset naming enforcement, e.g. by overloading the menu class' path_menu method, but it's too much mucking the internal.

Panel

The only thing left is to display the preset menu:

class RENDER_PT_my_settings(bpy.types.Panel):
    bl_label = 'My Render Settings'
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = 'render'

    def draw(self, context):
        layout = self.layout

        col = layout.column_flow(align=True)
        col.label('My Render Presets:')
        row = col.row(align=True)
        row.menu("RENDER_MT_my_presets",
                 text=bpy.types.RENDER_MT_my_presets.bl_label)
        row.operator("render.my_preset_add", text="", icon='ZOOMIN')
        row.operator("render.my_preset_add", text="", icon='ZOOMOUT').remove_active = True

... that will look like this:

My Render Presets

$\endgroup$
4
  • $\begingroup$ The code you sent works after being put in the register and unregister function thanks! One question though, how would I go around having a save button so if they change the values of the "preset" then they can save it after it is created. Because at the moment once you create it , its values are stuck in stone. $\endgroup$
    – Danny S
    Aug 23, 2013 at 12:23
  • $\begingroup$ @DannyS: I don't think it's possible without resorting to hacks. I'd try to put a property initializer in a separate file, import/execute it from main operator file, then overwrite it each time user selects new preset. Read AddPresetBase's definition in scripts/startup/bl_operators/presets.py to see how such file is written. Overload Menu to overwrite on preset selection, or overload AddPresetBase (as I did once) to overwrite on creation. $\endgroup$
    – Adhi
    Aug 23, 2013 at 15:01
  • $\begingroup$ Hmm.... Is there a way to see what current name the preset they are on is selected? If so, then you could use the same method to making a new preset, but send it the same name, consequently it would act like saving? $\endgroup$
    – Danny S
    Aug 23, 2013 at 15:20
  • $\begingroup$ This may not be reliable, but after first selection, the menu class' bl_label is set to last selected preset item. $\endgroup$
    – Adhi
    Aug 23, 2013 at 15:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .