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

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.