1

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.

SJK
  • 169
  • 1
  • 7
  • Why are you setting slider min and max to (1, 2) instead of (0, 1)? – Ron Jensen Oct 13 '21 at 22:05
  • 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. – SJK Oct 13 '21 at 23:38
  • The slider min and max are hard limits on values the shape key will accept, they are not just for the UI – Ron Jensen Oct 13 '21 at 23:45

1 Answers1

1

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

Ron Jensen
  • 3,421
  • 1
  • 9
  • 27
  • 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 – SJK Oct 14 '21 at 01:11
  • Thanks. That works! – SJK Oct 14 '21 at 02:32