diff --git a/add_curve_ivygen.py b/add_curve_ivygen.py
index 60f6ec5960d142b59a16d0b740c249f14d825160..7c68384679533e0d455c0e4fce611a2c3ae3270d 100644
--- a/add_curve_ivygen.py
+++ b/add_curve_ivygen.py
@@ -439,12 +439,13 @@ def bvhtree_from_object(ob):
     bm = bmesh.new()
 
     depsgraph = context.evaluated_depsgraph_get()
-    mesh = ob.evaluated_get(depsgraph).to_mesh()
+    ob_eval = ob.evaluated_get(depsgraph)
+    mesh = ob_eval.to_mesh()
     bm.from_mesh(mesh)
     bm.transform(ob.matrix_world)
 
     bvhtree = BVHTree.FromBMesh(bm)
-    bpy.data.meshes.remove(mesh)
+    ob_eval.to_mesh_clear()
     return bvhtree
 
 def check_mesh_faces(ob):
diff --git a/animation_add_corrective_shape_key.py b/animation_add_corrective_shape_key.py
index e40a7919c090e873e1bf0cdd42dcd824ef7068e0..91d57396d30bff7eff2113a3d4dd5bd91a423380 100644
--- a/animation_add_corrective_shape_key.py
+++ b/animation_add_corrective_shape_key.py
@@ -71,7 +71,8 @@ def extract_mapped_coords(ob, shape_verts):
     totvert = len(shape_verts)
 
     depsgraph = context.evaluated_depsgraph_get()
-    mesh = ob.evaluated_get(depsgraph).to_mesh()
+    ob_eval = ob.evaluated_get(depsgraph)
+    mesh = ob_eval.to_mesh()
 
     # cheating, the original mapped verts happen
     # to be at the end of the vertex array
@@ -79,7 +80,7 @@ def extract_mapped_coords(ob, shape_verts):
     arr = [verts[i].co.copy() for i in range(len(verts) - totvert, len(verts))]
 
     mesh.user_clear()
-    bpy.data.meshes.remove(mesh)
+    ob_eval.to_mesh_clear()
 
     return arr
 
@@ -203,7 +204,7 @@ class add_corrective_pose_shape(bpy.types.Operator):
 
 def func_object_duplicate_flatten_modifiers(context, obj):
     depsgraph = context.evaluated_depsgraph_get()
-    mesh = obj.evaluated_get(depsgraph).to_mesh()
+    mesh = bpy.data.meshes.new_from_object(obj.evaluated_get(depsgraph))
     name = obj.name + "_clean"
     new_object = bpy.data.objects.new(name, mesh)
     new_object.data = mesh
diff --git a/blenderkit/asset_inspector.py b/blenderkit/asset_inspector.py
index 93a39d593580b6a1ff4d1c6e100d43d3ed04f0d1..58867d6e4007554db6046c6dcabdb8770c0d4f31 100644
--- a/blenderkit/asset_inspector.py
+++ b/blenderkit/asset_inspector.py
@@ -204,9 +204,11 @@ def check_meshprops(props, obs):
 
     for ob in obs:
         if ob.type == 'MESH' or ob.type == 'CURVE':
+            ob_eval = None
             if ob.type == 'CURVE':
                 depsgraph = bpy.context.evaluated_depsgraph_get()
-                mesh = ob.evaluated_get(depsgraph).to_mesh()
+                ob_eval = ob.evaluated_get(depsgraph)
+                mesh = ob_eval.to_mesh()
             else:
                 mesh = ob.data
             fco = len(mesh.polygons)
@@ -244,6 +246,9 @@ def check_meshprops(props, obs):
                     fcor *= m.ratio
             fcr += fcor
 
+            if ob_eval:
+                ob_eval.to_mesh_clear()
+
     # write out props
     props.face_count = fc
     props.face_count_render = fcr
diff --git a/blenderkit/ui.py b/blenderkit/ui.py
index fd475af9c41940e2a43b770bcee2303308f8fc35..b0ac920939a16d556981ff908fd5b33010022db0 100644
--- a/blenderkit/ui.py
+++ b/blenderkit/ui.py
@@ -1242,8 +1242,10 @@ class AssetBarOperator(bpy.types.Operator):
                                 target_object = object.name
                                 # create final mesh to extract correct material slot
                                 depsgraph = bpy.context.evaluated_depsgraph_get()
-                                temp_mesh = object.evaluated_get(depsgraph).to_mesh()
+                                object_eval = object.evaluated_get(depsgraph)
+                                temp_mesh = object_eval.to_mesh()
                                 target_slot = temp_mesh.polygons[face_index].material_index
+                                object_eval.to_mesh_clear()
                             else:
                                 self.report({'WARNING'}, "Invalid or library object as input:")
                                 target_object = ''
diff --git a/blenderkit/utils.py b/blenderkit/utils.py
index c6e97fa9beb81ab50aa05b5201dac64cd5587c69..fd6c7d83c22ee554f0b28b90cd841af51383c16b 100644
--- a/blenderkit/utils.py
+++ b/blenderkit/utils.py
@@ -301,7 +301,8 @@ def get_bounds_snappable(obs, use_modifiers=False):
             # If to_mesh() works we can use it on curves and any other ob type almost.
             # disabled to_mesh for 2.8 by now, not wanting to use dependency graph yet.
             depsgraph = bpy.context.evaluated_depsgraph_get()
-            mesh = ob.evaluated_get(depsgraph).to_mesh()
+            object_eval = ob.evaluated_get(depsgraph)
+            mesh = object_eval.to_mesh()
 
             # if self.applyModifiers:
             #     evaluated_get(depsgraph).to_mesh()
@@ -318,7 +319,8 @@ def get_bounds_snappable(obs, use_modifiers=False):
                 maxx = max(maxx, parent_coord.x)
                 maxy = max(maxy, parent_coord.y)
                 maxz = max(maxz, parent_coord.z)
-            # bpy.data.meshes.remove(mesh)
+
+            object_eval.to_mesh_clear()
 
     if obcount == 0:
         minx, miny, minz, maxx, maxy, maxz = 0, 0, 0, 0, 0, 0
@@ -344,7 +346,8 @@ def get_bounds_worldspace(obs, use_modifiers=False):
         mw = ob.matrix_world
         if ob.type == 'MESH' or ob.type == 'CURVE':
             depsgraph = bpy.context.evaluated_depsgraph_get()
-            mesh = ob.evaluated_get(depsgraph).to_mesh()
+            ob_eval = ob.evaluated_get(depsgraph)
+            mesh = ob_eval.to_mesh()
             obcount += 1
             for c in mesh.vertices:
                 coord = c.co
@@ -355,6 +358,7 @@ def get_bounds_worldspace(obs, use_modifiers=False):
                 maxx = max(maxx, world_coord.x)
                 maxy = max(maxy, world_coord.y)
                 maxz = max(maxz, world_coord.z)
+            ob_eval.to_mesh_clear()
 
     if obcount == 0:
         minx, miny, minz, maxx, maxy, maxz = 0, 0, 0, 0, 0, 0
diff --git a/io_export_dxf/primitive_exporters/mesh_exporter.py b/io_export_dxf/primitive_exporters/mesh_exporter.py
index 358bc2e3a3eca851abff0dc4b6a038dd422bbd2e..6b1f0a4121be4b3f0e3434e057db52a36b1b83f1 100644
--- a/io_export_dxf/primitive_exporters/mesh_exporter.py
+++ b/io_export_dxf/primitive_exporters/mesh_exporter.py
@@ -42,7 +42,11 @@ class MeshDXFExporter(BasePrimitiveDXFExporter):
                         entities = self._writeInsert(ob, mx, me.name, **(kwargs))
 
             else: # no other instances, so go the standard way
-                return self._standard_way(drawing, me, mx, mx_n)
+                self._standard_way(drawing, me, mx, mx_n)
+
+        if obj.modifiers and settings['apply_modifiers']:
+            depsgraph = ctx.evaluated_depsgraph_get()
+            obj.evaluated_get(depsgraph).to_mesh_clear()
 
     def _writeInsert(self, drawing, ob, mx, insert_name, **kwargs):
         from insert_exporter import InsertDXFExporter
diff --git a/io_export_pc2.py b/io_export_pc2.py
index 5e69d14ffce229328b59cb17b0fed39f70442475..a5ad1b0cb7a4c1bdddc8a43ad2332b0250eda4cc 100644
--- a/io_export_pc2.py
+++ b/io_export_pc2.py
@@ -112,7 +112,10 @@ def do_export(context, props, filepath):
                                      float(v.co[2]))
             file.write(thisVertex)
 
-        bpy.data.meshes.remove(me, do_unlink=True)
+    if apply_modifiers:
+        ob.evaluated_get(depsgraph).to_mesh_clear()
+    else:
+        me = ob.to_mesh_clear()
 
     file.flush()
     file.close()
diff --git a/io_export_unreal_psk_psa.py b/io_export_unreal_psk_psa.py
index 4851586b78969abb0c2be1b24784df241a7ec605..cbccdb9b2241c44e140bdc036734b5a401a6ba8b 100644
--- a/io_export_unreal_psk_psa.py
+++ b/io_export_unreal_psk_psa.py
@@ -982,7 +982,7 @@ def triangulate_mesh(object):
 
     me_ob = object.copy()
     depsgraph = bpy.context.evaluated_depsgraph_get()
-    me_ob.data = object.evaluated_get(depsgraph).to_mesh()  # write data object
+    me_ob.data = bpy.data.meshes.new_from_object(object.evaluated_get(depsgraph))  # write data object
     bpy.context.collection.objects.link(me_ob)
     bpy.context.scene.update()
     bpy.ops.object.mode_set(mode='OBJECT')
@@ -1007,7 +1007,7 @@ def triangulate_mesh(object):
 
     verbose("Triangulated mesh")
 
-    me_ob.data = me_ob.evaluated_get(depsgraph).to_mesh()  # write data object
+    me_ob.data = bpy.data.meshes.new_from_object(me_ob.evaluated_get(depsgraph))  # write data object
     bpy.context.scene.update()
     return me_ob
 
@@ -2102,7 +2102,8 @@ def rebuildmesh(obj):
     uvfaces = []
     # print("creating array build mesh...")
     depsgraph = bpy.context.evaluated_depsgraph_get()
-    mmesh = obj.evaluated_get(depsgraph).to_mesh()
+    obj_eval = obj.evaluated_get(depsgraph)
+    mmesh = obj_eval.to_mesh()
     uv_layer = mmesh.tessface_uv_textures.active
 
     for face in mmesh.tessfaces:
@@ -2119,6 +2120,8 @@ def rebuildmesh(obj):
         else:
             faces.extend([(face.vertices[0], face.vertices[1], face.vertices[2], face.vertices[3])])
 
+    obj_eval.to_mesh_clear()
+
     # vertex positions
     for vertex in mesh.vertices:
         verts.append(vertex.co.to_tuple())
diff --git a/io_mesh_ply/export_ply.py b/io_mesh_ply/export_ply.py
index f465ed91d6ff84e0ac4b241c2da0bfdbc0be8e53..b14641bec3ddccec9cc6137f4fa453468d8d1a08 100644
--- a/io_mesh_ply/export_ply.py
+++ b/io_mesh_ply/export_ply.py
@@ -201,12 +201,14 @@ def save(
     if bpy.ops.object.mode_set.poll():
         bpy.ops.object.mode_set(mode='OBJECT')
 
+    mesh_owner_object = None
     if use_mesh_modifiers and obj.modifiers:
         depsgraph = context.evaluated_depsgraph_get()
-        mesh = obj.evaluated_get(depsgraph).to_mesh()
-
+        mesh_owner_object = obj.evaluated_get(depsgraph)
+        mesh = mesh_owner_object.to_mesh()
     else:
-        mesh = obj.data.copy()
+        mesh_owner_object = obj
+        mesh = mesh_owner_object.to_mesh()
 
     if not mesh:
         raise Exception("Error, could not get mesh data from active object")
@@ -221,6 +223,6 @@ def save(
                     use_colors=use_colors,
                     )
 
-    bpy.data.meshes.remove(mesh)
+    mesh_owner_object.to_mesh_clear()
 
     return ret
diff --git a/io_mesh_raw/export_raw.py b/io_mesh_raw/export_raw.py
index 8672134adda47bc63d101c6226351c7439b88930..ed34e3aeef28dac98b246de3b40e8a09f6911e13 100644
--- a/io_mesh_raw/export_raw.py
+++ b/io_mesh_raw/export_raw.py
@@ -68,9 +68,11 @@ def write(filepath,
 
     faces = []
     for obj in bpy.context.selected_objects:
+        obj_eval = None
         if applyMods or obj.type != 'MESH':
             try:
-                me = obj.evaluated_get(depsgraph).to_mesh()
+                obj_eval = obj.evaluated_get(depsgraph)
+                me = obj_eval.to_mesh()
             except:
                 me = None
             is_tmp_mesh = True
@@ -90,7 +92,7 @@ def write(filepath,
                     faces.append(fv)
 
             if is_tmp_mesh:
-                bpy.data.meshes.remove(me)
+                obj_eval.to_mesh_clear()
 
     # write the faces to a file
     file = open(filepath, "w")
diff --git a/io_mesh_stl/blender_utils.py b/io_mesh_stl/blender_utils.py
index 088caa8e6ec7e8ad2bc9fda2a84c200f3a68e827..d61adf31add749b8b8109220bf3cb5a02e9fdb06 100644
--- a/io_mesh_stl/blender_utils.py
+++ b/io_mesh_stl/blender_utils.py
@@ -81,12 +81,14 @@ def faces_from_mesh(ob, global_matrix, use_mesh_modifiers=False):
     ob.update_from_editmode()
 
     # get the modifiers
+    if use_mesh_modifiers:
+        depsgraph = bpy.context.evaluated_depsgraph_get()
+        mesh_owner = ob.evaluated_get(depsgraph)
+    else:
+        mesh_owner = ob
+
     try:
-        if use_mesh_modifiers:
-            depsgraph = bpy.context.evaluated_depsgraph_get()
-            mesh = ob.evaluated_get(depsgraph).to_mesh()
-        else:
-            mesh = ob.to_mesh()
+        mesh = mesh_owner.to_mesh()
     except RuntimeError:
         return
 
@@ -101,4 +103,4 @@ def faces_from_mesh(ob, global_matrix, use_mesh_modifiers=False):
     for tri in mesh.loop_triangles:
         yield [vertices[index].co.copy() for index in tri.vertices]
 
-    bpy.data.meshes.remove(mesh)
+    mesh_owner.to_mesh_clear()
diff --git a/io_scene_3ds/export_3ds.py b/io_scene_3ds/export_3ds.py
index 84b7c91a0a924299f637517495f8f093d58dd4ed..a81cd11d875b8df5c7fda5333fd5c13a4baa2df1 100644
--- a/io_scene_3ds/export_3ds.py
+++ b/io_scene_3ds/export_3ds.py
@@ -1039,8 +1039,9 @@ def save(operator,
             if ob.type not in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META'}:
                 continue
 
+            ob_derived_eval = ob_derived.evaluated_get(depsgraph)
             try:
-                data = ob_derived.evaluated_get(depsgraph).to_mesh()
+                data = ob_derived_eval.to_mesh()
             except:
                 data = None
 
@@ -1080,6 +1081,8 @@ def save(operator,
                         if f.material_index >= mat_ls_len:
                             f.material_index = 0
 
+                ob_derived_eval.to_mesh_clear()
+
         if free:
             free_derived_objects(ob)
 
diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py
index e399c8077b4a5232038acb888834a46d0b7539bb..a64e9a838ccccb66670a99ef158c718a0a8e319c 100644
--- a/io_scene_fbx/export_fbx_bin.py
+++ b/io_scene_fbx/export_fbx_bin.py
@@ -2228,7 +2228,10 @@ def fbx_data_from_scene(scene, depsgraph, settings):
                 if backup_pose_positions:
                     depsgraph.update()
                 ob_to_convert = ob.evaluated_get(depsgraph) if settings.use_mesh_modifiers else ob
-                tmp_me = ob_to_convert.to_mesh()
+                # NOTE: The dependency graph might be re-evaluating multiple times, which could
+                # potentially free the mesh created early on. So we put those meshes to bmain and
+                # free them afterwards. Not ideal but ensures correct ownerwhip.
+                tmp_me = bpy.data.meshes.new_from_object(ob_to_convert)
                 data_meshes[ob_obj] = (get_blenderID_key(tmp_me), tmp_me, True)
             # Change armatures back.
             for armature, pose_position in backup_pose_positions:
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
index 35785c80a919ed849d9c0ffcf3287b48d8e7a59e..d74a5c1d347d1b2ab27d232b666f7e21ab68d7ce 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
@@ -227,7 +227,8 @@ def __gather_mesh(blender_object, export_settings):
                     modifier.show_viewport = False
 
         depsgraph = bpy.context.evaluated_depsgraph_get()
-        blender_mesh = blender_object.evaluated_get(depsgraph).to_mesh()
+        blender_mesh_owner = blender_object.evaluated_get(depsgraph)
+        blender_mesh = blender_mesh_owner.to_mesh()
         for prop in blender_object.data.keys():
             blender_mesh[prop] = blender_object.data[prop]
         skip_filter = True
@@ -247,7 +248,7 @@ def __gather_mesh(blender_object, export_settings):
     result = gltf2_blender_gather_mesh.gather_mesh(blender_mesh, vertex_groups, modifiers, skip_filter, export_settings)
 
     if export_settings[gltf2_blender_export_keys.APPLY]:
-        bpy.data.meshes.remove(blender_mesh)
+        blender_mesh_owner.to_mesh_clear()
 
     return result
 
@@ -308,6 +309,7 @@ def __gather_skin(blender_object, export_settings):
 
     # check if any vertices in the mesh are part of a vertex group
     depsgraph = bpy.context.evaluated_depsgraph_get()
+    # XXX: ...
     blender_mesh = blender_object.evaluated_get(depsgraph).to_mesh()
     if not any(vertex.groups is not None and len(vertex.groups) > 0 for vertex in blender_mesh.vertices):
         return None
diff --git a/io_scene_ms3d/ms3d_export.py b/io_scene_ms3d/ms3d_export.py
index ba48e04631f509ac0e4bfa2086106775f2668b44..4fe31c00bb7ac76d34b1e82a65bdce90ae672eab 100644
--- a/io_scene_ms3d/ms3d_export.py
+++ b/io_scene_ms3d/ms3d_export.py
@@ -299,12 +299,15 @@ class Ms3dExporter():
 
             # convert to tris by using the triangulate modifier
             blender_mesh_object_temp.modifiers.new("temp", 'TRIANGULATE')
-            blender_mesh_temp = blender_mesh_object_temp.evaluated_get(blender_depsgraph).to_mesh()
+            blender_mesh_object_temp_eval = blender_mesh_object_temp.evaluated_get(blender_depsgraph)
+            blender_mesh_temp = blender_mesh_object_temp_eval.to_mesh()
 
             enable_edit_mode(True, blender_context)
             bm = bmesh.new()
             bm.from_mesh(blender_mesh_temp)
 
+            blender_mesh_object_temp_eval.to_mesh_clear()
+
             layer_texture = bm.faces.layers.tex.get(
                     ms3d_str['OBJECT_LAYER_TEXTURE'])
             if layer_texture is None:
diff --git a/io_scene_obj/export_obj.py b/io_scene_obj/export_obj.py
index 49ec8bc0a524dcc72a6e2c155f8d82508cae5dec..d77690356abdfd8aeb689b90b0774ca83fd1495f 100644
--- a/io_scene_obj/export_obj.py
+++ b/io_scene_obj/export_obj.py
@@ -639,7 +639,7 @@ def write_file(filepath, objects, depsgraph, scene,
                         totno += no_unique_count
 
                         # clean up
-                        bpy.data.meshes.remove(me)
+                        ob_for_convert.to_mesh_clear()
 
                 subprogress1.leave_substeps("Finished writing geometry of '%s'." % ob_main.name)
             subprogress1.leave_substeps()
diff --git a/io_scene_vrml2/export_vrml2.py b/io_scene_vrml2/export_vrml2.py
index d259e0b5afaf2a95dc1842d86de924a7e851b08f..e4038990d30d46115006858a9cfe512e5a3b866f 100644
--- a/io_scene_vrml2/export_vrml2.py
+++ b/io_scene_vrml2/export_vrml2.py
@@ -163,9 +163,11 @@ def save_object(fw, global_matrix,
         if is_editmode:
             bpy.ops.object.editmode_toggle()
 
-        me = obj.evaluated_get(depsgraph).to_mesh()
+        obj_eval = obj.evaluated_get(depsgraph)
+        me = obj_eval.to_mesh()
         bm = bmesh.new()
         bm.from_mesh(me)
+        obj_eval.to_mesh_clear()
 
         if is_editmode:
             bpy.ops.object.editmode_toggle()
diff --git a/io_scene_x/export_x.py b/io_scene_x/export_x.py
index d2773881bca97928ea1e1e9856b1e619319c832c..e0fc817bf24b8ee228b96e960f74c23be550ea5a 100644
--- a/io_scene_x/export_x.py
+++ b/io_scene_x/export_x.py
@@ -371,7 +371,7 @@ class MeshExportObject(ExportObject):
                 for Modifier in DeactivatedModifierList:
                     Modifier.show_viewport = False
 
-               depsgraph = self.Exporter.context.evaluated_depsgraph_get()
+                depsgraph = self.Exporter.context.evaluated_depsgraph_get()
                 Mesh = self.BlenderObject.evaluated_get(depsgraph).to_mesh()
 
                 # Restore the deactivated modifiers
@@ -384,7 +384,11 @@ class MeshExportObject(ExportObject):
             self.__WriteMesh(Mesh)
 
             # Cleanup
-            bpy.data.meshes.remove(Mesh)
+            if self.Config.ApplyModifiers:
+                depsgraph = self.Exporter.context.evaluated_depsgraph_get()
+                self.BlenderObject.evaluated_get(depsgraph).to_mesh_clear()
+            else:
+                self.BlenderObject.to_mesh_clear()
 
         self.Exporter.Log("Writing children of {}".format(self))
         self._WriteChildren()
diff --git a/io_scene_x3d/export_x3d.py b/io_scene_x3d/export_x3d.py
index 491675e73794e6296bf73c497ac357b9644f893f..92094dc6c23e61a583d8304487508b7a8e937bcc 100644
--- a/io_scene_x3d/export_x3d.py
+++ b/io_scene_x3d/export_x3d.py
@@ -1451,7 +1451,7 @@ def export(file,
 
                     # free mesh created with create_mesh()
                     if do_remove:
-                        bpy.data.meshes.remove(me)
+                        obj_for_mesh.to_mesh_clear()
 
             elif obj_type == 'LIGHT':
                 data = obj.data
diff --git a/io_shape_mdd/export_mdd.py b/io_shape_mdd/export_mdd.py
index 69b9dbe1af73fc99168039a4c6a6a689f6cc3bd5..4ca22e9114edaa0929abec470f8170de620a124d 100644
--- a/io_shape_mdd/export_mdd.py
+++ b/io_shape_mdd/export_mdd.py
@@ -68,7 +68,8 @@ def save(context, filepath="", frame_start=1, frame_end=300, fps=25.0, use_rest_
     orig_frame = scene.frame_current
     scene.frame_set(frame_start)
     depsgraph = context.evaluated_depsgraph_get()
-    me = obj.evaluated_get(depsgraph).to_mesh()
+    obj_eval = obj.evaluated_get
+    me = obj_eval.to_mesh()
 
     #Flip y and z
     '''
@@ -118,4 +119,6 @@ def save(context, filepath="", frame_start=1, frame_end=300, fps=25.0, use_rest_
     print('MDD Exported: %r frames:%d\n' % (filepath, numframes - 1))
     scene.frame_set(orig_frame)
 
+    obj_eval.to_mesh_clear()
+
     return {'FINISHED'}
diff --git a/mesh_looptools.py b/mesh_looptools.py
index a863218db35d915196d0d707b2d4500043b317e0..2b11465f2b4350aa9b43df4344d504a3dbd8ee40 100644
--- a/mesh_looptools.py
+++ b/mesh_looptools.py
@@ -527,9 +527,10 @@ def get_derived_bmesh(object, bm):
         # get derived mesh
         bm_mod = bmesh.new()
         depsgraph = bpy.context.evaluated_depsgraph_get()
-        mesh_mod = object.evaluated_get(depsgraph).to_mesh()
+        object_eval = object.evaluated_get(depsgraph)
+        mesh_mod = object_eval.to_mesh()
         bm_mod.from_mesh(mesh_mod)
-        bpy.context.blend_data.meshes.remove(mesh_mod)
+        object_eval.to_mesh_clear()
         # re-enable other modifiers
         for mod_name in show_viewport:
             object.modifiers[mod_name].show_viewport = True
diff --git a/mesh_tissue/lattice.py b/mesh_tissue/lattice.py
index eb1269a30312ac4c4aae3f801d95bb64197d10ab..2850c77aa75bf48ef8a744615cdbb291496f318e 100644
--- a/mesh_tissue/lattice.py
+++ b/mesh_tissue/lattice.py
@@ -319,9 +319,10 @@ class lattice_along_surface(Operator):
                 obj = o
                 o.select_set(False)
                 break
+        obj_eval = obj.evaluated_get(depsgraph)
         try:
             obj_dim = obj.dimensions
-            obj_me = obj.evaluated_get(depsgraph).to_mesh()
+            obj_me = obj_eval.to_mesh()
         except:
             self.report({'ERROR'}, "The object to deform is not valid. Only "
                         "Mesh, Curve, Surface and Font objects are allowed.")
@@ -360,6 +361,8 @@ class lattice_along_surface(Operator):
                 max[2] = vert[2]
             first = False
 
+        obj_eval.to_mesh_clear()
+
         bb = max - min
         lattice_loc = (max + min) / 2
         bpy.ops.object.add(type='LATTICE', align='WORLD',
diff --git a/mesh_tissue/tessellate_numpy.py b/mesh_tissue/tessellate_numpy.py
index 07c4fc87ced8c3b9756f7359479c9140898a3b3c..02464be75c2ce12190bfd8ca0a55f0adcbdb0aaa 100644
--- a/mesh_tissue/tessellate_numpy.py
+++ b/mesh_tissue/tessellate_numpy.py
@@ -77,8 +77,10 @@ def tassellate(ob0, ob1, offset, zscale, gen_modifiers, com_modifiers, mode,
     else:
         depsgraph = None
 
+    me0_owner = None
     if gen_modifiers:       # Apply generator modifiers
-        me0 = ob0.evaluated_get(depsgraph).to_mesh()
+        me0_owner = ob0.evaluated_get(depsgraph)
+        me0 = me0_owner.to_mesh()
     else:
         me0 = ob0.data
     ob0.data = me0
@@ -95,8 +97,9 @@ def tassellate(ob0, ob1, offset, zscale, gen_modifiers, com_modifiers, mode,
         return 0
 
     # Apply component modifiers
+    me1_owner = ob1.evaluated_get(depsgraph)
     if com_modifiers:
-        me1 = ob1.evaluated_get(depsgraph).to_mesh()
+        me1 = me1_owner.to_mesh()
     else:
         me1 = ob1.data
 
@@ -410,6 +413,13 @@ def tassellate(ob0, ob1, offset, zscale, gen_modifiers, com_modifiers, mode,
                                                         new_vertex_group_np[i],
                                                         "ADD")
     ob0.data = old_me0
+
+    if me0_owner:
+        me0_owner.to_mesh_clear()
+
+    if me1_owner:
+        me1_owner.to_mesh_clear()
+
     return new_ob
 
 
@@ -675,9 +685,12 @@ class tessellate(Operator):
                 depsgraph = None
             try:
                 polygons = 0
+                me_temp_owner = None
                 if self.gen_modifiers:
-                    me_temp = ob0.evaluated_get(depsgraph).to_mesh()
+                    me_temp_owner = ob0.evaluated_get(depsgraph)
+                    me_temp = me_temp_owner.to_mesh()
                 else:
+                    me_temp_owner = None
                     me_temp = ob0.data
 
                 for p in me_temp.polygons:
@@ -687,11 +700,18 @@ class tessellate(Operator):
                         else:
                             polygons += 1
 
+                if me_temp_owner:
+                    me_temp_owner.to_mesh_clear()
+
                 if self.com_modifiers:
-                    me_temp = bpy.data.objects[self.component].evaluated_get(depsgraph).to_mesh()
+                    me_temp_owner = bpy.data.objects[self.component].evaluated_get(depsgraph)
+                    me_temp = me_temp_owner.to_mesh()
                 else:
+                    me_temp_owner = None
                     me_temp = bpy.data.objects[self.component].data
                 polygons *= len(me_temp.polygons)
+                if me_temp_owner:
+                    me_temp_owner.to_mesh_clear()
 
                 str_polygons = '{:0,.0f}'.format(polygons)
                 if polygons > 200000:
@@ -1239,9 +1259,12 @@ class settings_tessellate(Operator):
         # Count number of faces
         try:
             polygons = 0
+            me_temp_owner = None
             if self.gen_modifiers:
-                me_temp = bpy.data.objects[self.generator].evaluated_get(depsgraph).to_mesh()
+                me_temp_owner = bpy.data.objects[self.generator].evaluated_get(depsgraph)
+                me_temp = me_temp_owner.to_mesh()
             else:
+                me_temp_owner = None
                 me_temp = bpy.data.objects[self.generator].data
 
             for p in me_temp.polygons:
@@ -1251,12 +1274,20 @@ class settings_tessellate(Operator):
                     else:
                         polygons += 1
 
+            if me_temp_owner:
+                me_temp_owner.to_mesh_clear()
+
             if self.com_modifiers:
-                me_temp = bpy.data.objects[self.component].evaluated_get(depsgraph).to_mesh()
+                me_temp_owner = bpy.data.objects[self.component].evaluated_get(depsgraph)
+                me_temp = me_temp_owner.to_mesh()
             else:
+                me_temp_owner = None
                 me_temp = bpy.data.objects[self.component].data
             polygons *= len(me_temp.polygons)
 
+            if me_temp_owner:
+                me_temp_owner.to_mesh_clear()
+
             str_polygons = '{:0,.0f}'.format(polygons)
             if polygons > 200000:
                 col.label(text=str_polygons + " polygons will be created!",
diff --git a/mesh_tissue/uv_to_mesh.py b/mesh_tissue/uv_to_mesh.py
index 8a69b4d3f3ff49cd6c975e34e8572e47d69d8fc0..bccee0bab14e135ae14a24fede24b514cd16d57f 100644
--- a/mesh_tissue/uv_to_mesh.py
+++ b/mesh_tissue/uv_to_mesh.py
@@ -87,9 +87,9 @@ class uv_to_mesh(Operator):
 
         if self.apply_modifiers:
             depsgraph = context.evaluated_depsgraph_get()
-            me0 = ob0.evaluated_get(depsgraph).to_mesh()
+            me0 = bpy.data.meshes.new_from_object(ob0.evaluated_get(depsgraph))
         else:
-            me0 = ob0.to_mesh()
+            me0 = bpy.data.new_from_meshed(ob0)
         area = 0
 
         verts = []
diff --git a/object_fracture_cell/fracture_cell_setup.py b/object_fracture_cell/fracture_cell_setup.py
index c3e47bbd55a555ade218b20d2dbc65cfdf6dbc91..dc45c43c66b640a7edad78a78b2b90407227cbf0 100644
--- a/object_fracture_cell/fracture_cell_setup.py
+++ b/object_fracture_cell/fracture_cell_setup.py
@@ -66,15 +66,16 @@ def _points_from_object(obj, source):
             points.extend([matrix * v.co for v in mesh.vertices])
         else:
             depsgraph = bpy.context.evaluated_depsgraph_get()
+            ob_eval = ob.evaluated_get(depsgraph)
             try:
-                mesh = ob.evaluated_get(depsgraph).to_mesh()
+                mesh = ob_eval.to_mesh()
             except:
                 mesh = None
 
             if mesh is not None:
                 matrix = obj.matrix_world.copy()
                 points.extend([matrix * v.co for v in mesh.vertices])
-                bpy.data.meshes.remove(mesh)
+                ob_eval.to_mesh_clear()
 
     def points_from_particles(obj):
         points.extend([p.location.copy()
@@ -339,7 +340,8 @@ def cell_fracture_boolean(context, obj, objects,
             if use_interior_hide:
                 obj_cell.data.polygons.foreach_set("hide", [True] * len(obj_cell.data.polygons))
 
-            mesh_new = obj_cell.evaluated_get(depsgraph).to_mesh()
+            obj_cell_eval = obj_cell.evaluated_get(depsgraph)
+            mesh_new = bpy.data.meshes.new_from_object(obj_cell_eval)
             mesh_old = obj_cell.data
             obj_cell.data = mesh_new
             obj_cell.modifiers.remove(mod)
diff --git a/object_print3d_utils/mesh_helpers.py b/object_print3d_utils/mesh_helpers.py
index 79e877742f3c11e29a6b8d865c79d30310b97b3a..0f444c09e283b88e84492f51074c3e42cc3fac55 100644
--- a/object_print3d_utils/mesh_helpers.py
+++ b/object_print3d_utils/mesh_helpers.py
@@ -33,10 +33,11 @@ def bmesh_copy_from_object(obj, transform=True, triangulate=True, apply_modifier
     if apply_modifiers and obj.modifiers:
         import bpy
         depsgraph = bpy.context.evaluated_depsgraph_get()
-        me = obj.evaluated_get(depsgraph).to_mesh()
+        obj_eval = obj.evaluated_get(depsgraph)
+        me = obj_eval.to_mesh()
         bm = bmesh.new()
         bm.from_mesh(me)
-        bpy.data.meshes.remove(me)
+        obj_eval.to_mesh_clear()
         del bpy
     else:
         me = obj.data
@@ -260,7 +261,8 @@ def object_merge(context, objects):
             continue
 
         # convert each to a mesh
-        mesh_new = obj.evaluated_get(depsgraph).to_mesh()
+        obj_eval = obj.evaluated_get(depsgraph)
+        mesh_new = obj_eval.to_mesh()
 
         # remove non-active uvs/vcols
         cd_remove_all_but_active(mesh_new.vertex_colors)
@@ -282,7 +284,7 @@ def object_merge(context, objects):
         # scene_collection.objects.unlink(obj_new)
         # bpy.data.objects.remove(obj_new)
 
-        bpy.data.meshes.remove(mesh_new)
+        obj_eval.to_mesh_clear()
 
     scene.update()
 
diff --git a/object_scatter/operator.py b/object_scatter/operator.py
index eb5d4f9bff02dcf4dd1d1acb6bb3999b7b77bb96..e040ef15667eef0c584bf00be8a9159a8f70de76 100644
--- a/object_scatter/operator.py
+++ b/object_scatter/operator.py
@@ -461,12 +461,13 @@ def bvhtree_from_object(object):
     bm = bmesh.new()
 
     depsgraph = context.evaluated_depsgraph_get()
-    mesh = object.evaluated_get(depsgraph).to_mesh()
+    object_eval = object.evaluated_get(depsgraph)
+    mesh = object_eval.to_mesh()
     bm.from_mesh(mesh)
     bm.transform(object.matrix_world)
 
     bvhtree = BVHTree.FromBMesh(bm)
-    bpy.data.meshes.remove(mesh)
+    object_eval.to_mesh_clear()
     return bvhtree
 
 def shoot_region_2d_ray(bvhtree, position_2d):
diff --git a/oscurart_tools/mesh/shapes_to_objects.py b/oscurart_tools/mesh/shapes_to_objects.py
index c2af30ed52ff47e8ae830e21ec9b61cae3f2afa2..29a5babc3a222141cc29f8500f8f77a7e70a3019 100644
--- a/oscurart_tools/mesh/shapes_to_objects.py
+++ b/oscurart_tools/mesh/shapes_to_objects.py
@@ -49,7 +49,8 @@ class ShapeToObjects(Operator):
                 print(SHAPE.name)
                 bpy.ops.object.shape_key_clear()
                 SHAPE.value = 1
-                mesh = OBJACT.evaluated_get(depsgraph).to_mesh()
+                OBJACT_eval = OBJACT.evaluated_get(depsgraph)
+                mesh = bpy.data.meshes.new_from_object(OBJACT_eval)
                 object = bpy.data.objects.new(SHAPE.name, mesh)
                 bpy.context.scene.collection.objects.link(object)
         else:
diff --git a/render_povray/render.py b/render_povray/render.py
index 02e05641a5508e0d1399c345e17a9bfd358518a3..56e3f8ec136bcb9b28dbffb90bfd45cfb6a7ca64 100644
--- a/render_povray/render.py
+++ b/render_povray/render.py
@@ -2680,8 +2680,9 @@ def write_pov(filename, scene=None, info_callback=None):
                     # TODO(sergey): PovRay is a render engine, so should be using dependency graph
                     # which was given to it via render engine API.
                     depsgraph = bpy.context.evaluated_depsgraph_get()
+                    ob_eval = ob.evaluated_get(depsgraph)
                     try:
-                        me = ob.evaluated_get(depsgraph).to_mesh()
+                        me = ob_eval.to_mesh()
 
                     #XXX Here? identify the specific exception for mesh object with no data
                     #XXX So that we can write something for the dataname !
@@ -3214,7 +3215,7 @@ def write_pov(filename, scene=None, info_callback=None):
 
 
 
-                    bpy.data.meshes.remove(me)
+                    ob_eval.to_mesh_clear()
 
         if csg:
             duplidata_ref = []