0

I'm trying to programatically apply a partial scaling to a mesh. For this specific scaling, I'm trying to replicate what happens when you've selected a number of vertices of a mesh in Edit Mode and scale them by pressing 'S' to bring them closer together or farther apart.

Like so: [img]

What I've tried is this:

bpy.ops.object.select_all(action='DESELECT')

object was originally a plane which I extruded into the z-axis, so this selects the upper half of the mesh.

upper_verts = [vert for vert in glyph_obj.data.vertices if vert.co[2] > 0]

for vert in upper_verts: vert.select = True

bpy.ops.transform.resize(value=(0.9, 0.9, 0.9), orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', mirror=True, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False, snap=False, snap_elements={'INCREMENT'}, use_snap_project=False, snap_target='CLOSEST', use_snap_self=True, use_snap_edit=True, use_snap_nonedit=True, use_snap_selectable=False)

Where glyph_obj is a bpy Object .

The last command, the bpy.ops.transform.resize, I copied from the info window from when I performed the operation by hand.

I can see in the viewer that my script does select all the appropriate vertices, but no transformation is performed. No errors are generated either. Because I followed programmatically all the steps I would have done by hand (I think), I don't know what I'm missing.

1 Answers1

2

Without an operator:

import bmesh
from bpy import context as C
from mathutils import Vector

condition = lambda v: v.co.z > 0 scale = 0.9

ob = C.object me = ob.data bm = bmesh.from_edit_mesh(me) verts = [v for v in bm.verts if condition(v)] average = sum((v.co for v in verts), start=Vector()) / len(verts)

for v in verts: offset = v.co - average

direction = offset.normalized()

v.co += direction * scale

v.co += offset * (scale - 1)

bmesh.update_edit_mesh(me)

Markus von Broady
  • 36,563
  • 3
  • 30
  • 99