1
$\begingroup$

I'm trying to understand what's going on here:

obj = bpy.context.object
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.delete(type='VERT')


# The instruction below prints <bpy_collection[8], MeshVertices>,
# but I expected the vertices to be gone.
print(obj.data.vertices)

My intent was to delete the vertices of the current object.

When executing the bpy.ops.mesh.delete(type='VERT') instruction I can tell that the vertices are gone because they don't show up in the GUI anymore.

However, I can still access them via python with obj.data.vertices.

Is that the normal behaviour? Why are the vertices still accessible if I deleted them?

$\endgroup$

1 Answer 1

2
$\begingroup$

You can access all of Blenders mesh data with bpy.data.objects[i].data. However this data can't really be edited as you do in edit mode. When you switch to edit mode, a whole new object (at codelevel) is temporarily created untill you exit edit mode and return to object mode. When you return to object mode, the temporary edit mesh is converted to an object mode mesh.

This means while you are in edit mode, the changes you see are not reflected in yourObject.data. yourObject.data only contains the object mode mesh. It will be updated once we exit edit mode.

You could add the lines to update the object mode mesh, before printing its data.

bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='EDIT')

But this only adds unnecessary overhead to your operations. (And you shouldn't be using the bpy.ops functions anyways.)

The solution is to use the bmesh module, it is designed to handle mesh data and has calls to update it.

Import it with import bmesh.
Then get the object data with me = bpy.context.object.data

Getting and setting the object data is dependant on which mode we are in.

Edit Mode

bm = bmesh.from_edit_mesh(me)

# manipulate the mesh data with the bmesh reference here

bmesh.update_edit_mesh(me, False, False)

Object Mode

bm = bmesh.new()
bm.from_mesh(me)

# manipulate the mesh data with the bmesh reference here

bm.to_mesh(me)
me.update()

If you don't know, wether you are in edit or object mode, when your script executes, use this answers code (last block). It will check if the object is in edit mode and use the according functions.

$\endgroup$
1
  • $\begingroup$ Thanks for the insightful explanations, makes sense now. $\endgroup$
    – ling
    Commented Dec 13, 2018 at 18:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .