0
$\begingroup$

I have created and rigged a simple cartoon-style model. His facial expressions are really just an image sequence texture. This allows me to quickly change his facial expression by changing the "offset" value of the image sequence. Then I created a custom property and attached it to a driver. This system works well, but it would be nice to have friendly names like mouth_oo rather than trying to remember the numerical index.

Here is the code I have so far based on an article I read at blendersushi: http://pastebin.com/2aJWd2ZB. The trouble with this code seems to be that context.object.My_List never seems to be populated.

How can I create a custom property control for an object that updates the value of the driver, but gives me a user-friendly popup?

$\endgroup$
  • $\begingroup$ Modifying properties in draw() context is not allowed. Either use an operator to add items, or consider to use a dynamic EnumProperty instead. $\endgroup$ – CodeManX Dec 17 '14 at 10:52
2
$\begingroup$

Check this code, this shows you 2 different options:

One is with direct control over the index with a slider with changing labels, The other one is with the EnumProp like you have it.

enter image description here

import bpy

from bpy.props import EnumProperty

def updateEnumParameter(self, context):
    context.object.my_list_index = int(self.face)
    print(self.face)

class cls_IntFloatString(bpy.types.PropertyGroup):
    face_items =(("0","None","none"),
                 ("1","Smile","smile"),
                 ("2","Content","content"),
                 ("3","Dizzy","dizzy"),
                 ("4","Cat","cat"),
                 ("5","Girl","girl"),
                 ("6","Yuck","yuck"),
                 ("7","Macho","macho"),
                 ("8","Pixel","pixel"),
                 ("9","Charming","charming"),
                 ("10","Cry","cry"),
                 ("11","Ouch","ouch"),
                 ("12","Ultraman","ultraman"))
    face = bpy.props.EnumProperty(items=face_items, update=updateEnumParameter)

bpy.utils.register_class(cls_IntFloatString)

faces = {
    '0': "None",
    '1': "Smile",
    '2': "Content",
    '3': "Dizzy",
    '4': "Cat",
    '5': "Girl",
    '6': "Yuck",
    '7': "Macho",
    '8': "Pixel",
    '9': "Charming",
    '10': "Cry",
    '11': "Ouch",
    '12': "Ultraman"}

# Add these properties to every object in the entire Blender system
bpy.types.Object.my_list_index = bpy.props.IntProperty(min=0, max=len(faces)-1, default=0)
bpy.types.Object.my_list = bpy.props.PointerProperty(type=cls_IntFloatString)

class IntFloatStringPanel(bpy.types.Panel):
    bl_label = "Int Float String"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = "PROPERTIES"
    bl_region_type = "WINDOW"
    bl_context = "object"

    def draw(self, context):
        layout = self.layout
        box = layout.box()
        row = box.row()
        row.label("Selected Face:")
        row.prop(context.object, 'my_list_index', text=faces[str(context.object.my_list_index)], slider=True)
        box.prop(context.object.my_list, 'face', text='Selected Face')

def register():
    bpy.utils.register_class(IntFloatStringPanel)

def unregister():
    bpy.utils.unregister_class(IntFloatStringPanel)

if __name__ == "__main__":
    register()
| improve this answer | |
$\endgroup$
  • $\begingroup$ Thank you, this worked like a charm! I very much appreciate your detailed working example. I have attached this to my driver and it works exactly as I hoped. Now I just need to find out how to move the panel to the 3D View properties shelf and my character will be ready to post on blendswap. :) $\endgroup$ – tofarley Dec 17 '14 at 22:04

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.