[Bf-blender-cvs] [136c8d1] cycles_memory: Add argument to DM_to_mesh() function to take ownership over the DM

Sergey Sharybin noreply at git.blender.org
Fri Feb 27 12:36:25 CET 2015


Commit: 136c8d1ae0fafc90281bd778c3ce362bf7837694
Author: Sergey Sharybin
Date:   Thu Feb 19 00:00:23 2015 +0500
Branches: cycles_memory
https://developer.blender.org/rB136c8d1ae0fafc90281bd778c3ce362bf7837694

Add argument to DM_to_mesh() function to take ownership over the DM

The idea is pretty simple: instead of making temporary copy of all the
related custom data layers just pass the ownership from the DM to the
mesh.

This is really handy in cases when you've got DM which you need to
convert to Mesh datablock and wouldn't need that DM after conversion
anyway.

Foe example, render database conversion, exporters and even Modifier
Apply will benefit from this option.

Reviewers: campbellbarton

Differential Revision: https://developer.blender.org/D1127

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

M	source/blender/blenkernel/BKE_DerivedMesh.h
M	source/blender/blenkernel/BKE_customdata.h
M	source/blender/blenkernel/intern/DerivedMesh.c
M	source/blender/blenkernel/intern/customdata.c
M	source/blender/blenkernel/intern/mesh.c
M	source/blender/collada/collada_utils.cpp
M	source/blender/editors/object/object_add.c
M	source/blender/editors/object/object_modifier.c

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

diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 0425164..236eae2 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -503,7 +503,7 @@ int DM_release(DerivedMesh *dm);
 
 /** utility function to convert a DerivedMesh to a Mesh
  */
-void DM_to_mesh(DerivedMesh *dm, struct Mesh *me, struct Object *ob, CustomDataMask mask);
+void DM_to_mesh(DerivedMesh *dm, struct Mesh *me, struct Object *ob, CustomDataMask mask, bool take_ownership);
 
 struct BMEditMesh *DM_to_editbmesh(struct DerivedMesh *dm,
                                    struct BMEditMesh *existing, const bool do_tessellate);
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 9028ad0..a5ccb50 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -142,6 +142,9 @@ void CustomData_reset(struct CustomData *data);
  */
 void CustomData_free(struct CustomData *data, int totelem);
 
+/* same as above, but only frees layers which matches the given mask. */
+void CustomData_free_typemask(struct CustomData *data, int totelem, CustomDataMask mask);
+
 /* frees all layers with CD_FLAG_TEMPORARY */
 void CustomData_free_temporary(struct CustomData *data, int totelem);
 
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 51f17f7..98d8ff9 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -531,13 +531,18 @@ MTFace *DM_paint_uvlayer_active_get(DerivedMesh *dm, int mat_nr)
 	return tf_base;
 }
 
-void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
+void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask, bool take_ownership)
 {
 	/* dm might depend on me, so we need to do everything with a local copy */
 	Mesh tmp = *me;
 	int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly;
 	int did_shapekeys = 0;
-	
+	int alloctype = CD_DUPLICATE;
+
+	if (take_ownership && dm->type == DM_TYPE_CDDM && dm->needsFree) {
+		alloctype = CD_ASSIGN;
+	}
+
 	CustomData_reset(&tmp.vdata);
 	CustomData_reset(&tmp.edata);
 	CustomData_reset(&tmp.fdata);
@@ -552,10 +557,10 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
 	totpoly = tmp.totpoly = dm->getNumPolys(dm);
 	tmp.totface = 0;
 
-	CustomData_copy(&dm->vertData, &tmp.vdata, mask, CD_DUPLICATE, totvert);
-	CustomData_copy(&dm->edgeData, &tmp.edata, mask, CD_DUPLICATE, totedge);
-	CustomData_copy(&dm->loopData, &tmp.ldata, mask, CD_DUPLICATE, totloop);
-	CustomData_copy(&dm->polyData, &tmp.pdata, mask, CD_DUPLICATE, totpoly);
+	CustomData_copy(&dm->vertData, &tmp.vdata, mask, alloctype, totvert);
+	CustomData_copy(&dm->edgeData, &tmp.edata, mask, alloctype, totedge);
+	CustomData_copy(&dm->loopData, &tmp.ldata, mask, alloctype, totloop);
+	CustomData_copy(&dm->polyData, &tmp.pdata, mask, alloctype, totpoly);
 	tmp.cd_flag = dm->cd_flag;
 
 	if (CustomData_has_layer(&dm->vertData, CD_SHAPEKEY)) {
@@ -590,13 +595,19 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
 	
 	/* not all DerivedMeshes store their verts/edges/faces in CustomData, so
 	 * we set them here in case they are missing */
-	if (!CustomData_has_layer(&tmp.vdata, CD_MVERT))
-		CustomData_add_layer(&tmp.vdata, CD_MVERT, CD_ASSIGN, dm->dupVertArray(dm), totvert);
-	if (!CustomData_has_layer(&tmp.edata, CD_MEDGE))
-		CustomData_add_layer(&tmp.edata, CD_MEDGE, CD_ASSIGN, dm->dupEdgeArray(dm), totedge);
+	if (!CustomData_has_layer(&tmp.vdata, CD_MVERT)) {
+		CustomData_add_layer(&tmp.vdata, CD_MVERT, CD_ASSIGN,
+		                     (alloctype == CD_ASSIGN) ? dm->getVertArray(dm) : dm->dupVertArray(dm),
+		                     totvert);
+	}
+	if (!CustomData_has_layer(&tmp.edata, CD_MEDGE)) {
+		CustomData_add_layer(&tmp.edata, CD_MEDGE, CD_ASSIGN,
+		                     (alloctype == CD_ASSIGN) ? dm->getEdgeArray(dm) : dm->dupEdgeArray(dm),
+		                     totedge);
+	}
 	if (!CustomData_has_layer(&tmp.pdata, CD_MPOLY)) {
-		tmp.mloop = dm->dupLoopArray(dm);
-		tmp.mpoly = dm->dupPolyArray(dm);
+		tmp.mloop = (alloctype == CD_ASSIGN) ? dm->getLoopArray(dm) : dm->dupLoopArray(dm);
+		tmp.mpoly = (alloctype == CD_ASSIGN) ? dm->getPolyArray(dm) : dm->dupPolyArray(dm);
 
 		CustomData_add_layer(&tmp.ldata, CD_MLOOP, CD_ASSIGN, tmp.mloop, tmp.totloop);
 		CustomData_add_layer(&tmp.pdata, CD_MPOLY, CD_ASSIGN, tmp.mpoly, tmp.totpoly);
@@ -607,7 +618,7 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
 	if (CustomData_has_layer(&me->ldata, CD_MDISPS)) {
 		if (totloop == me->totloop) {
 			MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
-			CustomData_add_layer(&tmp.ldata, CD_MDISPS, CD_DUPLICATE, mdisps, totloop);
+			CustomData_add_layer(&tmp.ldata, CD_MDISPS, alloctype, mdisps, totloop);
 		}
 	}
 
@@ -641,6 +652,16 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
 
 	/* skip the listbase */
 	MEMCPY_STRUCT_OFS(me, &tmp, id.prev);
+
+	if (take_ownership) {
+		if (alloctype == CD_ASSIGN) {
+			CustomData_free_typemask(&dm->vertData, dm->numVertData, ~mask);
+			CustomData_free_typemask(&dm->edgeData, dm->numEdgeData, ~mask);
+			CustomData_free_typemask(&dm->loopData, dm->numLoopData, ~mask);
+			CustomData_free_typemask(&dm->polyData, dm->numPolyData, ~mask);
+		}
+		dm->release(dm);
+	}
 }
 
 void DM_to_meshkey(DerivedMesh *dm, Mesh *me, KeyBlock *kb)
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 483a4b9..6994412 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -1559,6 +1559,25 @@ void CustomData_free(CustomData *data, int totelem)
 	CustomData_reset(data);
 }
 
+void CustomData_free_typemask(struct CustomData *data, int totelem, CustomDataMask mask)
+{
+	int i;
+
+	for (i = 0; i < data->totlayer; ++i) {
+		CustomDataLayer *layer = &data->layers[i];
+		if (!(mask & CD_TYPE_AS_MASK(layer->type))) {
+			continue;
+		}
+		customData_free_layer__internal(layer, totelem);
+	}
+
+	if (data->layers)
+		MEM_freeN(data->layers);
+
+	CustomData_external_free(data);
+	CustomData_reset(data);
+}
+
 static void customData_update_offsets(CustomData *data)
 {
 	const LayerTypeInfo *typeInfo;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 7757bab..809d213 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -1501,7 +1501,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use
 	}
 	else {
 		me = BKE_mesh_add(G.main, "Mesh");
-		DM_to_mesh(dm, me, ob, CD_MASK_MESH);
+		DM_to_mesh(dm, me, ob, CD_MASK_MESH, false);
 	}
 
 	me->totcol = cu->totcol;
@@ -2256,8 +2256,7 @@ Mesh *BKE_mesh_new_from_object(
 					dm = mesh_create_derived_view(sce, ob, mask);
 
 				tmpmesh = BKE_mesh_add(bmain, "Mesh");
-				DM_to_mesh(dm, tmpmesh, ob, mask);
-				dm->release(dm);
+				DM_to_mesh(dm, tmpmesh, ob, mask, true);
 			}
 
 			/* BKE_mesh_add/copy gives us a user count we don't need */
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index d91689f..f15efa8 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -164,8 +164,7 @@ Mesh *bc_get_mesh_copy(Scene *scene, Object *ob, BC_export_mesh_type export_mesh
 	}
 
 	tmpmesh = BKE_mesh_add(G.main, "ColladaMesh"); // name is not important here
-	DM_to_mesh(dm, tmpmesh, ob, CD_MASK_MESH);
-	dm->release(dm);
+	DM_to_mesh(dm, tmpmesh, ob, CD_MASK_MESH, true);
 
 	if (triangulate) {
 		bc_triangulate_mesh(tmpmesh);
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 8fd857a..5c8f95b 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1688,11 +1688,10 @@ static int convert_exec(bContext *C, wmOperator *op)
 			dm = mesh_get_derived_final(scene, newob, CD_MASK_MESH);
 			// dm = mesh_create_derived_no_deform(ob1, NULL);  /* this was called original (instead of get_derived). man o man why! (ton) */
 
-			DM_to_mesh(dm, newob->data, newob, CD_MASK_MESH);
+			DM_to_mesh(dm, newob->data, newob, CD_MASK_MESH, true);
 
 			/* re-tessellation is called by DM_to_mesh */
 
-			dm->release(dm);
 			BKE_object_free_modifiers(newob);   /* after derivedmesh calls! */
 		}
 		else if (ob->type == OB_FONT) {
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index bed8544..710cf2d 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -614,9 +614,7 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob,
 				return 0;
 			}
 
-			DM_to_mesh(dm, me, ob, CD_MASK_MESH);
-
-			dm->release(dm);
+			DM_to_mesh(dm, me, ob, CD_MASK_MESH, true);
 
 			if (md->type == eModifierType_Multires)
 				multires_customdata_delete(me);




More information about the Bf-blender-cvs mailing list