I'm creating new vertices using bmesh at 3d cursor position but every time I add a new one, all the previously created vertices jump to their original positions (if they were moved). It's like I need to somehow update the bmesh, I'm doing bmesh.update_edit_mesh(ob.data) but this doesn't seem to help. Also I've noticed that if I manually switch to Object mode and back to Edit, verts keep their positions next time I run the script (switching modes with Python didn't help)

Here's what's happening:

enter image description here

And my code:

import bpy
import bmesh

def get_cursor_pos():
    for area in bpy.context.screen.areas:
        if area.type == 'VIEW_3D':
            ctx = bpy.context.copy();
            ctx['area'] = area
            return bpy.context.scene.cursor.location.copy()

def main():
  cursor = get_cursor_pos()
  ob = bpy.context.selected_objects[0]

  bm = bmesh.new()

  # convert the current mesh to a bmesh (must be in edit mode)
  bpy.ops.object.mode_set(mode='OBJECT')  # return to object mode

  bm.verts.new(cursor - ob.location)  # add a new vert

  # make the bmesh the object's mesh
  ob.data.update() # ¯\_(ツ)_/¯

  bpy.ops.object.mode_set(mode='EDIT') #back to edit mode
  bmesh.update_edit_mesh(ob.data) # ¯\_(ツ)_/¯ 


p.s. on a side note I also find weird that running the script selects all the verts I had selected when I had entered the Edit mode, I ownder if that's also part of the same problem


Add vert at cursor in edit mode

The cursor is in global coordinates. Set to local by multiplying by the objects world matrix inverse.

import bpy
import bmesh

context = bpy.context
scene = context.scene
ob = context.object
mwi = ob.matrix_world.inverted()
me = ob.data
bm = bmesh.from_edit_mesh(me)
bm.verts.new(mwi @ scene.cursor.location)
  • $\begingroup$ even though my question wasn't about getting cursor coordinates (you can see on my gif that they're created in correct coordinates), your snippet helped me to fix my code by using bmesh.from_edit_mesh instead of bmesh.from_mesh. Thanks! $\endgroup$ – Sergey Kritskiy Feb 8 '20 at 10:25
  • $\begingroup$ Try moving, rotating and scaling object then see if you get "correct coordinates" With identity matrix world object coordinates == global coordinates and global cursor location difference with global object location (no parent?), otherwise it won't work as expected. $\endgroup$ – batFINGER Feb 8 '20 at 10:30
  • $\begingroup$ ah yes, I was only applying object location, not rotation or scale... thank you again $\endgroup$ – Sergey Kritskiy Feb 8 '20 at 10:41

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.