1
$\begingroup$

I am trying to create an drive a shape key using Python. I used this answer to create a shape key: Creating shape keys using Python I have been able to use this answer to create a shape key in Python and I can modify it in the shape key panel.

I would like to be able to change the shape key value in a custom menu or panel, so I tried this answer to add a driver: Python: drive a shape key with scripting

The driver Python script works if I create a shape key in Blender using the GUI, but I can not get it to work if I create the shape key using Python. I tried to incorporate the corrections in the comments related to creating the shape key, but I still can not use the shape key driver to change the value of a shape key created in Python.

Here is the code I am using the create the shape key:

import bpy
import bmesh

context = bpy.context
obj = context.object   # add a shape key to the active object

# now set up shape key in Blender
mesh=obj.data
sk_basis = obj.shape_key_add(name='Basis',from_mix=False)
sk_basis.interpolation = 'KEY_LINEAR'
obj.data.shape_keys.use_relative = False

# create new shape key
sk = obj.shape_key_add(name='Deform',from_mix=False)
sk.interpolation = 'KEY_LINEAR'
sk.slider_min = 1
sk.slider_max = 2

bpy.ops.object.mode_set(mode='EDIT')
bm=bmesh.new()
bm=bmesh.from_edit_mesh(mesh)
bm.faces.ensure_lookup_table()

for face in bm.faces:
# make sure the zeros are actually zero by rounding 
   curr_normal=[round(face.normal[0]*1000)/1000,round(face.normal[1]*1000)/1000,round(face.normal[2]*1000)/1000]
   if curr_normal==[0,0,1]:  # find the top face
       print('this is the face: ',face.index)
       for vert in face.verts: 
           vert.co.z=vert.co.z+2
bmesh.update_edit_mesh(mesh,True)
bm.free()

bpy.ops.object.mode_set(mode='OBJECT')

Can anyone tell me why the value of a this shape key created in Python can not be changed using a shape key custom property driver.

$\endgroup$
3
  • $\begingroup$ Why are you setting slider min and max to (1, 2) instead of (0, 1)? $\endgroup$
    – Ron Jensen
    Oct 13, 2021 at 22:05
  • $\begingroup$ My goal is to put a slider in a custom panel which the user can move and see the object with the shape key modified. Those two lines don't appear to do anything. I was trying to create a slider with variable minimum and maximum values, but I am not sure if that is possible. However, at the moment, I can't even change the value of the shape key in Python. $\endgroup$
    – SJK
    Oct 13, 2021 at 23:38
  • $\begingroup$ The slider min and max are hard limits on values the shape key will accept, they are not just for the UI $\endgroup$
    – Ron Jensen
    Oct 13, 2021 at 23:45

1 Answer 1

1
$\begingroup$

After you set the mode back to "OBJECT" change the shape key to relative mode if you want to adjust the key with its .value property:

obj.data.shape_keys.use_relative = True

If you're not in relative mode you must adjust the key with

bpy.data.shape_keys["Key"].eval_time

Edit: This version of your script builds a working shapekey:

import bpy
import bmesh

context = bpy.context
obj = context.object   # add a shape key to the active object

# now set up shape key in Blender
mesh=obj.data
sk_basis = obj.shape_key_add(name='Basis',from_mix=False)
sk_basis.interpolation = 'KEY_LINEAR'
# must set relative to false here
obj.data.shape_keys.use_relative = False

# create new shape key
sk = obj.shape_key_add(name='Deform',from_mix=False)
sk.interpolation = 'KEY_LINEAR'
sk.slider_min = 0
sk.slider_max = 2

bpy.ops.object.mode_set(mode='EDIT')
bm=bmesh.new()
bm=bmesh.from_edit_mesh(mesh)
bm.faces.ensure_lookup_table()

for face in bm.faces:
# make sure the zeros are actually zero by rounding 
   curr_normal=[round(face.normal[0]*1000)/1000,round(face.normal[1]*1000)/1000,round(face.normal[2]*1000)/1000]
   if curr_normal==[0,0,1]:  # find the top face
       print('this is the face: ',face.index)
       for vert in face.verts: 
           vert.co.z=vert.co.z+2
bmesh.update_edit_mesh(mesh,True)
bm.free()

bpy.ops.object.mode_set(mode='OBJECT')
# Switching to relative must be after
# switching back to Object mode:
obj.data.shape_keys.use_relative = True
$\endgroup$
2
  • $\begingroup$ I noticed that the shape keys I created with the GUI had use_relative=True, so I had tried that and the object still does not change size. I just tried leaving the use_relative-False and bpy.data.shape_keys['Key.001'].eval_time=number, but the object still did not change when I tried different numbers $\endgroup$
    – SJK
    Oct 14, 2021 at 1:11
  • $\begingroup$ Thanks. That works! $\endgroup$
    – SJK
    Oct 14, 2021 at 2:32

You must log in to answer this question.

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