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$
  • $\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 '13 at 1:01
  • $\begingroup$ An aside: consider using a vector property instead of specifying x, y and z separately. $\endgroup$ – z0r Aug 23 '13 at 1:59
10
$\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$
  • $\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 '13 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 '13 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 '13 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 '13 at 15:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.