Is it possible -- without using a previously defined vertex group -- to select those vertice, which are affected by a shape key? How?
I think a shape key stores the coordinates of any vertex of the mesh, regardless of whether the position has been changed or not. So it seems as if the only way to select vertices affected by the shape key is to individually compare whether the position of the vertices is the same for different shape keys.
import bpy tolerance = 1e-5 obj = bpy.context.active_object shape_keys = obj.data.shape_keys.key_blocks sk1_data = shape_keys['Key 1'].data skb_data = shape_keys['Basis'].data bpy.ops.object.mode_set(mode="EDIT") bpy.ops.mesh.select_all(action="DESELECT") bpy.ops.mesh.select_mode(type="VERT") bpy.ops.object.mode_set(mode="OBJECT") for i, (x, y) in enumerate(zip(sk1_data, skb_data)): if (x.co - y.co).length > tolerance: obj.data.vertices[i].select = True bpy.ops.object.mode_set(mode="EDIT")
EDIT: As per batFINGER's suggestion, replaced comparison based on equality with a tolerance based approach.
Using the same principle as @binweg's answer with an edit bmesh
- Shapekey vertex coordinate needs to be further than
TOL(local) from vertex coordinate. Always suggest using a tolerance approach when looking at floats, rather than relying on
10.0000000001 == 10for example.
- The two points of interest are vector coords. Test the length of the vector calcuated from their difference.
- Uses the active shapekey.
- Selected result is those verts further than tolerance from base mesh, IF the shapekey is the solo shape at full value
- For the script to "poll" needs to be run in edit mesh mode. The object must have an active shapekey.
import bpy import bmesh context = bpy.context TOL = 1e-5 # tolerance ob = context.edit_object me = ob.data bm = bmesh.from_edit_mesh(me) ask = ob.active_shape_key for v in bm.verts: bv = me.vertices[v.index] v.select = (ask.data[v.index].co - bv.co).length > TOL bmesh.update_edit_mesh(me)