I'm trying to update an exporter to work with Blender 2.8 but can't seem to get a mesh data-block modified by modifiers or shape keys. It always gives me the base mesh.

I'm currently using Object.to_mesh(). But reading Object.data or bmesh.from_mesh(obj) all returns only the base mesh. So what is the new function to call for getting a mesh data-block with the modifiers and shape keys applied?


Just tested batFINGER's solutions. It's pretty convoluted and you have to call bm.clear() every time the mesh updates before calling the last two functions. It works but really doesn't feel like the intended way to do things. Digging a bit further I think I found the intended solution:

#We only have to do this once:
ob = bpy.context.active_object #getting the object we want.
dg = bpy.context.evaluated_depsgraph_get() #getting the dependency graph

#This has to be done every time the object updates:
ob = ob.evaluated_get(dg) #this gives us the evaluated version of the object. Aka with all modifiers and deformations applied.
me = ob.to_mesh() #turn it into the mesh data block we want.

Still annoying that we can't pick between preview and render for which version of the modifiers it applies (it seems to always pick preview). If there is a way to do that I would love to know.

  • 1
    $\begingroup$ This answer is amazing and saved so much time, a related note is that object must be linked in a collection first for this to actually work, otherwise it won't give error, but modifiers won't be applied (working on object that are not linked) $\endgroup$ – Iyad Ahmed Jan 22 at 5:34
  • $\begingroup$ This was the exact solution I needed for my project. evaluated_get() made it easy! Thank you! $\endgroup$ – Raptormeat Jan 29 at 5:00


Using the bmesh from object, can be written to another mesh as the deformed modified mesh.

Test script, writes context object deformed / modified mesh to new mesh "ObjBmesh"

import bpy
import bmesh

context = bpy.context
ob = context.object
dg = context.evaluated_depsgraph_get()

bm = bmesh.new()
bm.from_object(ob, dg)

Using the evaluated object.

Further to the answer of @Somebody285 can get the evaluated objects from the depsgraph's objects collection.

Python console example, default cube has a subsurf modifier with default settings.

>>> dg = C.evaluated_depsgraph_get()
>>> cube = dg.objects.get("Cube")
>>> me = cube.to_mesh()
>>> len(me.vertices)

>>> len(cube.data.vertices)

me is the evaluated (modifiers / shapekeys) applied mesh.

>>> me

>>> D.meshes["Cube"]

even tho it represents itself the same, it is not the base mesh object

>>> len(D.meshes["Cube"].vertices)

>>> me is D.meshes['Cube']

The original property of an object points to its unevaluated original.

>>> D.objects['Cube'].data is D.meshes['Cube']

>>> cube.original

>>> cube.original.data is D.meshes['Cube']

The object is evaluated, shown by its is_evaluated property. The "evaluated mesh" does not have this set.

>>> cube.is_evaluated

>>> me.is_evaluated

However it is, as displayed in error message when trying to use it as a mesh data block.

>>> newcube = D.objects.new("Cube2", me)
Traceback (most recent call last):
  File "<blender_console>", line 1, in <module>
RuntimeError: Error: Can not create object in main database with an evaluated data data-block

>>> newcube = D.objects.new("Cube2", cube.data)
Traceback (most recent call last):
  File "<blender_console>", line 1, in <module>
RuntimeError: Error: Can not create object in main database with an evaluated data data-block

Copying gives us a mesh data block.

>>> newcube = D.objects.new("Cube2", cube.data.copy())
  • $\begingroup$ Any reasons @Downvoter? $\endgroup$ – brockmann Jul 9 at 13:27
  • $\begingroup$ Very diligent Watson TBH have wanted to edit other answer, which I've both upvoted and taught me the intended way,, to remove the BS wrapped aound "it works" Reminds me of a set the scene cursor via python console answer, where another later answerer starts with "You Don't need the Python Console!", To me; Answer above is IMO a valid way to achieve question title goal. Often see evaluated mesh being loaded into a new bmesh in answers, feel this is "intended" for that. $\endgroup$ – batFINGER Jul 9 at 14:19
  • $\begingroup$ "You do not need Blender, just use your brain.", lol. Anyway, by far the best answer to this question and the console stuff really helps to understand it (If you want to). $\endgroup$ – brockmann Jul 9 at 15:14

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.