0
$\begingroup$

Why does a mesh object return an empty vertex collection when in Edit Mode? As you can imagine my forehead is a bit bloody from this noodling and want to understand why the following access to data.vertices is dependent on mode. Here you see the same print statements before and after the editmode_toggle:


                bpy.ops.mesh.primitive_plane_add( size=sizeR, location=locat, scale=(1, yScale, 1), enter_editmode=True )
                bpy.ops.mesh.select_all( action='SELECT' )
                bpy.ops.mesh.subdivide( number_cuts=12 )
                # randomly select a portion of the vertices and move them along the Z axis (to create shadows)   
                obj = bpy.context.active_object
                print( str(obj.data  ) + " vertices=" + str( obj.data.vertices ) )     
                bpy.ops.object.editmode_toggle() 

prints:

<bpy_struct, Mesh("Plane.008") at 0x000001FFE8F782D8> vertices=<bpy_collection[0], MeshVertices>
<bpy_struct, Mesh("Plane.008") at 0x000001FFE8F782D8> vertices=<bpy_collection[196], MeshVertices>

i.e, an empty collection when in Edit Mode, but a complete set of (196) vertices in Object Mode.

Thanks for any insight.

$\endgroup$

2 Answers 2

2
$\begingroup$

A "snap shot" copy.

When entering edit mode, blender takes a "snap-shot" object mode copy of the mesh. (Differs from accepted answer, as AFAIK this is not a bmesh) Any referencing of the mesh while in edit mode will be values of the copy. The edit mode manipulated mesh is written back to the mesh when exiting edit mode, or via Object.update_from_editmode()

The question code is adding a new object entering edit mode via the operators enter_edit_mode property, in which case it reports the 0 verts.. of a new mesh object with no geometry.

Had we added the plane primitive in object mode, then toggled into edit mode and subdivided would report 4 verts (the unsubdivided plane pre edit mode)

updating the mesh from edit mode, eg inserting this line

obj = bpy.context.active_object
obj.update_from_editmode()
print( str(obj.data  ) + " vertices=" + str( obj.data.vertices ) )    

would update the mesh and print 196 vertices.

Avoid edit mode.

In many cases can avoid edit mode completely. My rule of thumb would be, if there is no need for the user input to select specific geometry there is probably no need to bother with the mind numbing overhead of numerous & repetitive bpy.ops.mesh... calls.

Avoid unnecessary operations.

A 12x12 cut subdivided plane is a 14x14 grid

>>> bpy.ops.mesh.primitive_grid_add(
...         x_subdivisions=14, 
...         y_subdivisions=14,
...         )
{'FINISHED'}

>>> len(C.object.data.vertices)
196

instantly replacing all code in question.

Use bmesh.

If edit mode selection is required would recommend the use of a bound edit mode bmesh, bound in that it is tied to the edit mode mesh and any changes to selection or geometry via bpy.ops.mesh... are instantly reflected by the bmesh data.

Have answered numerous questions and titled them bmesh script, so in no particular order https://blender.stackexchange.com/search?q=user%3A15543+bmesh+script

$\endgroup$
1
$\begingroup$

When you enter edit mode, the mesh data in obj.data is copied into a BMesh (a representations that takes more memory but is good for editing operations). When you exit edit mode, the BMesh is coped back into obj.data.

So if you're looking at obj.data, you won't see any changes done in edit mode until you exit edit mode. Also any changes you make to obj.data while in edit mode will be lost when you exit edit mode and they get overwritten by the data coming from the BMesh.

In short, if you want to operate on obj.data, always make sure it's not in edit mode first.

If you want to operate on mesh data in edit mode, you can instead get the BMesh for a mesh with bmesh.from_edit_mesh(mesh) and work on that.

$\endgroup$
2
  • $\begingroup$ Kinda makes my head explode, but your answer gives reasoning. Worse, I need to invoke bpy.ops.mesh.select_random() from Edit Mode, but needs aVertex.select = True/False from Object Mode. Where's my mouth harp?! $\endgroup$
    – james_t
    Apr 1, 2021 at 18:40
  • 1
    $\begingroup$ You can select a vertex with bmesh. docs.blender.org/api/current/… $\endgroup$
    – scurest
    Apr 1, 2021 at 18:43

You must log in to answer this question.

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