[Bf-blender-cvs] [29f9a197088] blender2.8: Modifier stack: Avoid roundtrip from mesh to DM back to mesh

Sergey Sharybin noreply at git.blender.org
Wed May 30 14:39:25 CEST 2018


Commit: 29f9a197088e0e1ea56cae675803f61165d790c1
Author: Sergey Sharybin
Date:   Wed May 30 12:56:20 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB29f9a197088e0e1ea56cae675803f61165d790c1

Modifier stack: Avoid roundtrip from mesh to DM back to mesh

Saves quite a bit of CPU ticks per mesh update, giving measurable
speedup for file from T55228.

Memory usage goes up a it, most likely due to evaluated mesh having
more custom data layers than corresponding DM does.

===================================================================

M	source/blender/blenkernel/intern/DerivedMesh.c
M	source/blender/blenkernel/intern/object_update.c

===================================================================

diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index d2a3732a31d..c8d5bb5ffd7 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -2916,6 +2916,47 @@ static bool calc_modifiers_skip_orco(Depsgraph *depsgraph,
 }
 #endif
 
+static void mesh_finalize_eval(Object *object)
+{
+	if (!DEG_depsgraph_use_copy_on_write()) {
+		return;
+	}
+	Mesh *mesh = (Mesh *)object->data;
+	Mesh *mesh_eval = object->runtime.mesh_eval;
+	/* Special Tweaks for cases when evaluated mesh came from
+	 * BKE_mesh_new_nomain_from_template().
+	 */
+	BLI_strncpy(mesh_eval->id.name, mesh->id.name, sizeof(mesh_eval->id.name));
+	if (mesh_eval->mat != NULL) {
+		MEM_freeN(mesh_eval->mat);
+	}
+	mesh_eval->mat = MEM_dupallocN(mesh->mat);
+	mesh_eval->totcol = mesh->totcol;
+	/* Make evaluated mesh to share same edit mesh pointer as original
+	 * and copied meshes.
+	 */
+	mesh_eval->edit_btmesh = mesh->edit_btmesh;
+	/* Special flags to help debugging and also to allow copy-on-write core
+	 * to understand that on re-evaluation this mesh is to be preserved and
+	 * to be remapped back to copied original mesh when used as object data.
+	 */
+	mesh_eval->id.tag |= LIB_TAG_COPY_ON_WRITE_EVAL;
+	mesh_eval->id.orig_id = &mesh->id;
+	/* Copy autosmooth settings from original mesh.
+	 * This is not done by BKE_mesh_new_nomain_from_template(), so need to take
+	 * extra care here.
+	 */
+	mesh_eval->flag |= (mesh->flag & ME_AUTOSMOOTH);
+	mesh_eval->smoothresh = mesh->smoothresh;
+	/* Replace evaluated object's data with fully evaluated mesh. */
+	/* TODO(sergey): There was statement done by Sybren and Mai that this
+	 * caused modifiers to be applied twice. which is weirtd and shouldn't
+	 * really happen. But since there is no reference to the report, can not
+	 * do much about this.
+	 */
+	object->data = mesh_eval;
+}
+
 static void mesh_build_data(
         struct Depsgraph *depsgraph, Scene *scene, Object *ob, CustomDataMask dataMask,
         const bool build_shapekey_layers, const bool need_mapping)
@@ -2931,12 +2972,21 @@ static void mesh_build_data(
 	}
 #endif
 
-	mesh_calc_modifiers_dm(
+	mesh_calc_modifiers(
 	        depsgraph, scene, ob, NULL, 1, need_mapping, dataMask, -1, true, build_shapekey_layers,
 	        true,
-	        &ob->derivedDeform, &ob->derivedFinal);
+	        &ob->runtime.mesh_deform_eval, &ob->runtime.mesh_eval);
+
+	mesh_finalize_eval(ob);
+
+	ob->derivedDeform = CDDM_from_mesh_ex(ob->runtime.mesh_deform_eval, CD_REFERENCE, CD_MASK_MESH);
+	ob->derivedFinal = CDDM_from_mesh_ex(ob->runtime.mesh_eval, CD_REFERENCE, CD_MASK_MESH);
 
 	DM_set_object_boundbox(ob, ob->derivedFinal);
+	/* TODO(sergey): Convert bounding box calculation to use mesh, then
+	 * we can skip this copy.
+	 */
+	BKE_mesh_texspace_copy_from_object(ob->runtime.mesh_eval, ob);
 
 	ob->derivedFinal->needsFree = 0;
 	ob->derivedDeform->needsFree = 0;
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 5848de3aa87..e953185b726 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -330,62 +330,6 @@ void BKE_object_eval_uber_data(Depsgraph *depsgraph,
 			BKE_mball_batch_cache_dirty(ob->data, BKE_MBALL_BATCH_DIRTY_ALL);
 			break;
 	}
-
-	if (DEG_depsgraph_use_copy_on_write()) {
-		if (ob->type == OB_MESH) {
-			/* Quick hack to convert evaluated derivedMesh to Mesh. */
-			DerivedMesh *dm = ob->derivedFinal;
-			if (dm != NULL) {
-				Mesh *mesh = (Mesh *)ob->data;
-				Mesh *new_mesh = BKE_libblock_alloc_notest(ID_ME);
-				BKE_mesh_init(new_mesh);
-				/* Copy ID name so GS(new_mesh->id) works correct later on. */
-				BLI_strncpy(new_mesh->id.name, mesh->id.name, sizeof(new_mesh->id.name));
-				/* Copy materials so render engines can access them. */
-				new_mesh->mat = MEM_dupallocN(mesh->mat);
-				new_mesh->totcol = mesh->totcol;
-				DM_to_mesh(dm, new_mesh, ob, CD_MASK_MESH, true);
-				new_mesh->edit_btmesh = mesh->edit_btmesh;
-				/* Store result mesh as derived_mesh of object. This way we have
-				 * explicit  way to query final object evaluated data and know for sure
-				 * who owns the newly created mesh datablock.
-				 */
-				ob->runtime.mesh_eval = new_mesh;
-				/* TODO(sergey): This is kind of compatibility thing, so all render
-				 * engines can use object->data for mesh data for display. This is
-				 * something what we might want to change in the future.
-				 * XXX: This can sometimes cause modifiers to be applied twice!
-				 */
-				ob->data = new_mesh;
-				/* Special flags to help debugging. */
-				new_mesh->id.tag |= LIB_TAG_COPY_ON_WRITE_EVAL;
-				/* Save some memory by throwing DerivedMesh away. */
-				/* NOTE: Watch out, some tools might need it!
-				 * So keep around for now..
-				 */
-				/* Store original ID as a pointer in evaluated ID.
-				 * This way we can restore original object data when we are freeing
-				 * evaluated mesh.
-				 */
-				new_mesh->id.orig_id = &mesh->id;
-				/* Copy autosmooth settings from original mesh. */
-				new_mesh->flag |= (mesh->flag & ME_AUTOSMOOTH);
-				new_mesh->smoothresh = mesh->smoothresh;
-			}
-#if 0
-			if (ob->derivedFinal != NULL) {
-				ob->derivedFinal->needsFree = 1;
-				ob->derivedFinal->release(ob->derivedFinal);
-				ob->derivedFinal = NULL;
-			}
-			if (ob->derivedDeform != NULL) {
-				ob->derivedDeform->needsFree = 1;
-				ob->derivedDeform->release(ob->derivedDeform);
-				ob->derivedDeform = NULL;
-			}
-#endif
-		}
-	}
 }
 
 void BKE_object_eval_cloth(Depsgraph *depsgraph,



More information about the Bf-blender-cvs mailing list