5
$\begingroup$

I want to set sub surf value by reading number from the Enum Property

How do i do that ?

import bpy
def SubSurfSet(self, context):
    print(self.value)
    #bpy.context.object.modifiers["Subsurf"].render_levels = 2

bpy.types.PoseBone.SubSurfEnum = bpy.props.EnumProperty(
            #(identifier, name, description, icon, number)
    items = [('None','No Smooth','','',0), 
             ('Smooth','Smooth','','',1),
             ('Smoother','Smoother','','',2),
             ('Smoothest','Smoothest','','',4)],
    name = "Mask the MESH",
    default = 'None',
    update = SubSurfSet)

bpy.data.objects["Frog rig"].pose.bones["root.dummy"].SubSurfEnum = 'None'
$\endgroup$
1
  • 1
    $\begingroup$ Note that you do not need the second '' for each item, as the last value will be registered as the number if no icon is provided. docs.blender.org/api/current/… $\endgroup$
    – splic
    Commented May 9, 2018 at 22:45

4 Answers 4

9
$\begingroup$

What I would do is design the items of Enum property like this:

items = [('0','No Smooth',''), 
         ('1','Smooth',''),
         ('2','Smoother',''),
         ('4','Smoothest','')]

Then you just need to cast it to int.

bpy.context.object.modifiers["Subsurf"].render_levels = int(self.SubSurfEnum )

When you change this Enum property and the subsurf levels you don't have to change any dictionary.

$\endgroup$
4
  • $\begingroup$ I am already using this method, but need to know the use of assigning number in #(identifier, name, description, icon, number) $\endgroup$
    – ashwin
    Commented Aug 5, 2015 at 5:32
  • $\begingroup$ @ashwin The three first elements of the items are mandatory (identifier, name, description). The identifier is used for python access and other values are used for the interface only. The forth optional one is either the (unique!) number id of the item or, if followed by a fifth element (which must be the number id), an icon string identifier. $\endgroup$ Commented Aug 5, 2015 at 7:19
  • $\begingroup$ Self.value dose not exist. Self.SubSuefEnum gets the identifier. So dippending on identifier i have to check and assign values! In this case int helped $\endgroup$
    – ashwin
    Commented Aug 5, 2015 at 7:28
  • $\begingroup$ @zeffi you are righ $\endgroup$ Commented Aug 5, 2015 at 7:31
10
$\begingroup$

Just for the record, it's also possible to access the enum items via bpy.types to look up all their properties:

items = bpy.types.PoseBone.bl_rna.properties['SubSurfEnum'].enum_items

pbone = bpy.context.selected_pose_bones[0] # some PoseBone
number = items[pbone.SubSurfEnum].value
# or access another property:    .icon
#                                .identifier
#                                .description

It's much more complicated if multiple items use the same identifier / name with different values however, because you can't lookup the right entry (I believe it will always pick the first with that name).

$\endgroup$
2
  • 1
    $\begingroup$ does this also work for enum props that have a dynamic item list via a callback function? I tried it and it didn't seem to work. Is there a way to get identifiere,value,icon for enum properties with a dynamic item list? $\endgroup$
    – ndee
    Commented Jan 18, 2017 at 21:18
  • 1
    $\begingroup$ It might not be possible to access dynamic enums this way, but I guess you could call that callback function yourself to retrieve all entries. $\endgroup$
    – CodeManX
    Commented Feb 11, 2017 at 11:18
3
$\begingroup$
import bpy

bpy.types.Object.SubSurfEnum = bpy.props.EnumProperty(
            #(identifier, name, description, icon, number)
    items = [('None','No Smooth','','',0), 
             ('Smooth','Smooth','','',1),
             ('Smoother','Smoother','','',2),
             ('Smoothest','Smoothest','','',4)],
    name = "Mask the MESH",
    default = 'None')

bpy.data.objects[0].SubSurfEnum = 'Smooth' # You have to assign something to this value first
print(bpy.data.objects[0].SubSurfEnum) # this print 'Smooth'
print(bpy.data.objects[0]['SubSurfEnum']) # this print 1 <---- ANSWER

Note that You have to assign something to this value first, or else You get

KeyError: 'bpy_struct[key]: key "SubSurfEnum1" not found'
$\endgroup$
1
  • 2
    $\begingroup$ In combination with CoDEmanX's answer default = ob.bl_rna.properties['SubSurfEnum'].default is "None" default_value = ob.bl_rna.properties['SubSurfEnum'].enum_items[default].value is zero, and from your answer ob.get("SubSurfEnum", default_value) will give you the int value without having to set it first. $\endgroup$
    – batFINGER
    Commented Mar 18, 2019 at 21:43
2
$\begingroup$

A simple way is to use a dict.. to map from the string value to an int

def SubSurfSet(self, context):
    remap = dict(NoSmooth=0, Smooth=1, Smoother=2, Smoothest=4)
    val = remap.get(self.SubSurfEnum)
    bpy.context.object.modifiers["Subsurf"].render_levels = val

Though, admittedly, this looks a little repetitive. Warning: I use 'NoSmooth' instead of 'None', to avoid confusion.

$\endgroup$

You must log in to answer this question.

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