I need to get the average value between the selected vertices. I can get it for a single object, but when I try to do it in multi-object editing mode, it fails.
if bpy.context.scene.tool_settings.transform_pivot_point == 'MEDIAN_POINT':
obj = bpy.context.edit_object
bm = bmesh.from_edit_mesh(obj.data)
verts_sel = [v for v in bm.verts if v.select is True]
verts_co = [v.co for v in verts_sel]
matrix_select = mathutils.Matrix.Translation(sum(verts_co, mathutils.Vector()) / len(verts_sel))
ob = obj.matrix_world @ matrix_select
this is one of the annoying things about working with BMesh- there is no built-in way to handle multi-object edit mode. I added a python paper cut asking for a bmesh.from_edit_meshes(context.selected_objects) or something along those lines a long time ago but never got any responses.
what you have to do is create a list of bmeshes for each object and calculate everything that way. it’s annoying boilerplate, but it works.
that last bit is where you’re going to run into problems with multi-edit, because each object has its own transform so you can’t reasonably expect to use N different matrices and apply them all to the same gizmo. It’s better to transform your vert coordinates into world space and then get the median point
for example-
bms = {}
for o in bpy.context.selected_objects:
bms[o] = bmesh.from_edit_mesh(o.data)
verts = []
for o in bms:
verts.extend([v.co @ o.matrix_world for v in bms[o].verts if v.select])
median_point = sum(verts, mathutils.Vector()) / len(verts)
The nice part about doing it this way is that you end up with a dictionary of bmeshes indexed by their object, so updating the edit mesh is as simple as:
uniques = context.objects_in_mode
bms = {}
for obj in uniques:
bms[obj] = bmesh.from_edit_mesh(obj.data)
verts = []
for ob in bms:
verts.extend([ob.matrix_world @ v.co for v in bms[ob].verts if v.select])
ob = mathutils.Matrix.Translation(sum(verts, mathutils.Vector()) / len(verts))