[Bf-blender-cvs] [b204bda] master: EditMesh: Avoid creating deform-vert layer every redraw

Campbell Barton noreply at git.blender.org
Wed Jun 22 13:25:34 CEST 2016


Commit: b204bdad47ffbd92b7b6702e2a680da9cbd6489a
Author: Campbell Barton
Date:   Wed Jun 22 21:20:09 2016 +1000
Branches: master
https://developer.blender.org/rBb204bdad47ffbd92b7b6702e2a680da9cbd6489a

EditMesh: Avoid creating deform-vert layer every redraw

Getting a new edit-derived-bmesh was always creating a deform-vert array, even when it wasn't needed.
Since this was called on redraw, in many cases it was doing it unnecessarily.

Now pass in a custom-data mask and only fill in deform-verts when needed.

Gives noticeable drawing speedup (~10-30% here).

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

M	source/blender/blenkernel/BKE_DerivedMesh.h
M	source/blender/blenkernel/intern/DerivedMesh.c
M	source/blender/blenkernel/intern/crazyspace.c
M	source/blender/blenkernel/intern/editderivedmesh.c
M	source/blender/editors/space_view3d/drawobject.c

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

diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 8ccc4a6..606488f 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -694,7 +694,7 @@ DerivedMesh *mesh_create_derived_render(
         CustomDataMask dataMask);
 
 DerivedMesh *getEditDerivedBMesh(
-        struct BMEditMesh *em, struct Object *ob,
+        struct BMEditMesh *em, struct Object *ob, CustomDataMask data_mask,
         float (*vertexCos)[3]);
 
 DerivedMesh *mesh_create_derived_index_render(
@@ -723,7 +723,7 @@ DerivedMesh *mesh_create_derived_physics(
         CustomDataMask dataMask);
 
 DerivedMesh *editbmesh_get_derived_base(
-        struct Object *, struct BMEditMesh *em);
+        struct Object *ob, struct BMEditMesh *em, CustomDataMask data_mask);
 DerivedMesh *editbmesh_get_derived_cage(
         struct Scene *scene, struct Object *,
         struct BMEditMesh *em, CustomDataMask dataMask);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index d590a35..79e500f 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1433,10 +1433,12 @@ static void calc_weightpaint_vert_array(
         Object *ob, DerivedMesh *dm, int const draw_flag, DMWeightColorInfo *dm_wcinfo,
         unsigned char (*r_wtcol_v)[4])
 {
-	MDeformVert *dv = DM_get_vert_data_layer(dm, CD_MDEFORMVERT);
-	int numVerts = dm->getNumVerts(dm);
+	BMEditMesh *em = (dm->type == DM_TYPE_EDITBMESH) ? BKE_editmesh_from_object(ob) : NULL;
+	const int numVerts = dm->getNumVerts(dm);
 
-	if (dv && (ob->actdef != 0)) {
+	if ((ob->actdef != 0) &&
+	    (CustomData_has_layer(em ? &em->bm->vdata : &dm->vertData, CD_MDEFORMVERT)))
+	{
 		unsigned char (*wc)[4] = r_wtcol_v;
 		unsigned int i;
 
@@ -1455,8 +1457,30 @@ static void calc_weightpaint_vert_array(
 			}
 		}
 
-		for (i = numVerts; i != 0; i--, wc++, dv++) {
-			calc_weightpaint_vert_color((unsigned char *)wc, dv, dm_wcinfo, defbase_tot, defbase_act, defbase_sel, defbase_sel_tot, draw_flag);
+		/* editmesh won't have deform verts unless modifiers require it,
+		 * avoid having to create an array of deform-verts only for drawing
+		 * by reading from the bmesh directly. */
+		if (em) {
+			BMIter iter;
+			BMVert *eve;
+			const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
+			BLI_assert(cd_dvert_offset != -1);
+
+			BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
+				const MDeformVert *dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
+				calc_weightpaint_vert_color(
+				        (unsigned char *)wc, dv, dm_wcinfo,
+				        defbase_tot, defbase_act, defbase_sel, defbase_sel_tot, draw_flag);
+				wc++;
+			}
+		}
+		else {
+			const MDeformVert *dv = DM_get_vert_data_layer(dm, CD_MDEFORMVERT);
+			for (i = numVerts; i != 0; i--, wc++, dv++) {
+				calc_weightpaint_vert_color(
+				        (unsigned char *)wc, dv, dm_wcinfo,
+				        defbase_tot, defbase_act, defbase_sel, defbase_sel_tot, draw_flag);
+			}
 		}
 
 		if (defbase_sel) {
@@ -2282,7 +2306,7 @@ static void editbmesh_calc_modifiers(
 	modifiers_clearErrors(ob);
 
 	if (r_cage && cageIndex == -1) {
-		*r_cage = getEditDerivedBMesh(em, ob, NULL);
+		*r_cage = getEditDerivedBMesh(em, ob, dataMask, NULL);
 	}
 
 	md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
@@ -2448,7 +2472,7 @@ static void editbmesh_calc_modifiers(
 			}
 			else {
 				*r_cage = getEditDerivedBMesh(
-				        em, ob,
+				        em, ob, mask,
 				        deformedVerts ? MEM_dupallocN(deformedVerts) : NULL);
 			}
 		}
@@ -2484,7 +2508,7 @@ static void editbmesh_calc_modifiers(
 	}
 	else {
 		/* this is just a copy of the editmesh, no need to calc normals */
-		*r_final = getEditDerivedBMesh(em, ob, deformedVerts);
+		*r_final = getEditDerivedBMesh(em, ob, dataMask, deformedVerts);
 		deformedVerts = NULL;
 
 		/* In this case, we should never have weight-modifying modifiers in stack... */
@@ -2847,9 +2871,9 @@ DerivedMesh *editbmesh_get_derived_cage(Scene *scene, Object *obedit, BMEditMesh
 	return em->derivedCage;
 }
 
-DerivedMesh *editbmesh_get_derived_base(Object *obedit, BMEditMesh *em)
+DerivedMesh *editbmesh_get_derived_base(Object *obedit, BMEditMesh *em, CustomDataMask data_mask)
 {
-	return getEditDerivedBMesh(em, obedit, NULL);
+	return getEditDerivedBMesh(em, obedit, data_mask, NULL);
 }
 
 /***/
diff --git a/source/blender/blenkernel/intern/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c
index c8de078..56df8e5 100644
--- a/source/blender/blenkernel/intern/crazyspace.c
+++ b/source/blender/blenkernel/intern/crazyspace.c
@@ -39,6 +39,7 @@
 #include "DNA_meshdata_types.h"
 
 #include "BLI_utildefines.h"
+#include "BLI_linklist.h"
 #include "BLI_math.h"
 
 #include "BKE_crazyspace.h"
@@ -275,7 +276,13 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(Scene *scene, Object *ob,
 
 		if (mti->type == eModifierTypeType_OnlyDeform && mti->deformMatricesEM) {
 			if (!defmats) {
-				dm = getEditDerivedBMesh(em, ob, NULL);
+				const int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
+				CustomDataMask data_mask = CD_MASK_BAREMESH;
+				CDMaskLink *datamasks = modifiers_calcDataMasks(scene, ob, md, data_mask, required_mode, NULL, 0);
+				data_mask = datamasks->mask;
+				BLI_linklist_free((LinkNode *)datamasks, NULL);
+
+				dm = getEditDerivedBMesh(em, ob, data_mask, NULL);
 				deformedVerts = editbmesh_get_vertex_cos(em, &numVerts);
 				defmats = MEM_mallocN(sizeof(*defmats) * numVerts, "defmats");
 
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index c101334..1aba76b 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -2226,16 +2226,17 @@ static CustomData *bmDm_getPolyDataLayout(DerivedMesh *dm)
 	return &bmdm->em->bm->pdata;
 }
 
-
+/**
+ * \note This may be called per-draw,
+ * avoid allocating large arrays where possible and keep this a thin wrapper for #BMesh.
+ */
 DerivedMesh *getEditDerivedBMesh(
-        BMEditMesh *em,
-        Object *UNUSED(ob),
+        BMEditMesh *em, struct Object *UNUSED(ob),
+        CustomDataMask data_mask,
         float (*vertexCos)[3])
 {
 	EditDerivedBMesh *bmdm = MEM_callocN(sizeof(*bmdm), __func__);
 	BMesh *bm = em->bm;
-	const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
-	const int cd_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN);
 
 	bmdm->em = em;
 
@@ -2304,6 +2305,9 @@ DerivedMesh *getEditDerivedBMesh(
 	bmdm->vertexCos = (const float (*)[3])vertexCos;
 	bmdm->dm.deformedOnly = (vertexCos != NULL);
 
+	const int cd_dvert_offset = (data_mask & CD_MASK_MDEFORMVERT) ?
+	        CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT) : -1;
+
 	if (cd_dvert_offset != -1) {
 		BMIter iter;
 		BMVert *eve;
@@ -2317,6 +2321,9 @@ DerivedMesh *getEditDerivedBMesh(
 		}
 	}
 
+	const int cd_skin_offset = (data_mask & CD_MASK_MVERT_SKIN) ?
+	        CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN) : -1;
+
 	if (cd_skin_offset != -1) {
 		BMIter iter;
 		BMVert *eve;
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 7c12b8e..1999ff7 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -4250,12 +4250,15 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
 	if (ob == obedit || drawlinked) {
 		DerivedMesh *finalDM, *cageDM;
 		
-		if (obedit != ob)
-			finalDM = cageDM = editbmesh_get_derived_base(ob, em);
-		else
+		if (obedit != ob) {
+			finalDM = cageDM = editbmesh_get_derived_base(
+			        ob, em, scene->customdata_mask);
+		}
+		else {
 			cageDM = editbmesh_get_derived_cage_and_final(
 			        scene, ob, em, scene->customdata_mask,
 			        &finalDM);
+		}
 
 		const bool use_material = ((me->drawflag & ME_DRAWEIGHT) == 0);
 
@@ -8480,7 +8483,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r
 	DerivedMesh *dm = NULL, *edm = NULL;
 	
 	if (ob->mode & OB_MODE_EDIT) {
-		edm = editbmesh_get_derived_base(ob, me->edit_btmesh);
+		edm = editbmesh_get_derived_base(ob, me->edit_btmesh, CD_MASK_BAREMESH);
 		DM_update_materials(edm, ob);
 	}
 	else {




More information about the Bf-blender-cvs mailing list