[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [42722] trunk/blender/source/blender: Fix a bug in CustomData_duplicate_referenced_layer(_named) functions: MEM_dupallocN does not work with complex layers like CD_MDEFORMVERT ones, so rather use copy func when available.

Bastien Montagne montagne29 at wanadoo.fr
Mon Dec 19 09:27:07 CET 2011


Revision: 42722
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=42722
Author:   mont29
Date:     2011-12-19 08:26:53 +0000 (Mon, 19 Dec 2011)
Log Message:
-----------
Fix a bug in CustomData_duplicate_referenced_layer(_named) functions: MEM_dupallocN does not work with complex layers like CD_MDEFORMVERT ones, so rather use copy func when available.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_customdata.h
    trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
    trunk/blender/source/blender/blenkernel/intern/customdata.c
    trunk/blender/source/blender/modifiers/intern/MOD_solidify.c
    trunk/blender/source/blender/modifiers/intern/MOD_uvproject.c

Modified: trunk/blender/source/blender/blenkernel/BKE_customdata.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_customdata.h	2011-12-19 05:23:52 UTC (rev 42721)
+++ trunk/blender/source/blender/blenkernel/BKE_customdata.h	2011-12-19 08:26:53 UTC (rev 42722)
@@ -121,9 +121,9 @@
 
 /* duplicate data of a layer with flag NOFREE, and remove that flag.
  * returns the layer data */
-void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type);
+void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem);
 void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
-												  int type, const char *name);
+												  const int type, const char *name, const int totelem);
 
 /* set the CD_FLAG_NOCOPY flag in custom data layers where the mask is
  * zero for the layer type, so only layer types specified by the mask

Modified: trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c	2011-12-19 05:23:52 UTC (rev 42721)
+++ trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c	2011-12-19 08:26:53 UTC (rev 42722)
@@ -1870,7 +1870,7 @@
 	int i;
 
 	/* this will just return the pointer if it wasn't a referenced layer */
-	vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
+	vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
 	cddm->mvert = vert;
 
 	for(i = 0; i < dm->numVertData; ++i, ++vert)
@@ -1884,7 +1884,7 @@
 	int i;
 
 	/* this will just return the pointer if it wasn't a referenced layer */
-	vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
+	vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
 	cddm->mvert = vert;
 
 	for(i = 0; i < dm->numVertData; ++i, ++vert)
@@ -1899,7 +1899,7 @@
 	if(dm->numVertData == 0) return;
 
 	/* we don't want to overwrite any referenced layers */
-	cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
+	cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
 
 	/* make a face normal layer if not present */
 	face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);

Modified: trunk/blender/source/blender/blenkernel/intern/customdata.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/customdata.c	2011-12-19 05:23:52 UTC (rev 42721)
+++ trunk/blender/source/blender/blenkernel/intern/customdata.c	2011-12-19 08:26:53 UTC (rev 42722)
@@ -1404,7 +1404,7 @@
 	return number;
 }
 
-void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type)
+void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem)
 {
 	CustomDataLayer *layer;
 	int layer_index;
@@ -1416,7 +1416,20 @@
 	layer = &data->layers[layer_index];
 
 	if (layer->flag & CD_FLAG_NOFREE) {
-		layer->data = MEM_dupallocN(layer->data);
+		/* MEM_dupallocN won’t work in case of complex layers, like e.g.
+		 * CD_MDEFORMVERT, which has pointers to allocated data...
+		 * So in case a custom copy function is defined, use it!
+		 */
+		const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
+
+		if(typeInfo->copy) {
+			char *dest_data = MEM_mallocN(typeInfo->size * totelem, "CD duplicate ref layer");
+			typeInfo->copy(layer->data, dest_data, totelem);
+			layer->data = dest_data;
+		}
+		else
+			layer->data = MEM_dupallocN(layer->data);
+
 		layer->flag &= ~CD_FLAG_NOFREE;
 	}
 
@@ -1424,7 +1437,7 @@
 }
 
 void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
-												  int type, const char *name)
+												  const int type, const char *name, const int totelem)
 {
 	CustomDataLayer *layer;
 	int layer_index;
@@ -1436,7 +1449,20 @@
 	layer = &data->layers[layer_index];
 
 	if (layer->flag & CD_FLAG_NOFREE) {
-		layer->data = MEM_dupallocN(layer->data);
+		/* MEM_dupallocN won’t work in case of complex layers, like e.g.
+		 * CD_MDEFORMVERT, which has pointers to allocated data...
+		 * So in case a custom copy function is defined, use it!
+		 */
+		const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
+
+		if(typeInfo->copy) {
+			char *dest_data = MEM_mallocN(typeInfo->size * totelem, "CD duplicate ref layer");
+			typeInfo->copy(layer->data, dest_data, totelem);
+			layer->data = dest_data;
+		}
+		else
+			layer->data = MEM_dupallocN(layer->data);
+
 		layer->flag &= ~CD_FLAG_NOFREE;
 	}
 

Modified: trunk/blender/source/blender/modifiers/intern/MOD_solidify.c
===================================================================
--- trunk/blender/source/blender/modifiers/intern/MOD_solidify.c	2011-12-19 05:23:52 UTC (rev 42721)
+++ trunk/blender/source/blender/modifiers/intern/MOD_solidify.c	2011-12-19 08:26:53 UTC (rev 42722)
@@ -75,8 +75,8 @@
 	/* we don't want to overwrite any referenced layers */
 
 	/*
-	Dosnt work here!
-	mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
+	Doesn't work here!
+	mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, numVerts);
 	cddm->mvert = mv;
 	*/
 

Modified: trunk/blender/source/blender/modifiers/intern/MOD_uvproject.c
===================================================================
--- trunk/blender/source/blender/modifiers/intern/MOD_uvproject.c	2011-12-19 05:23:52 UTC (rev 42721)
+++ trunk/blender/source/blender/modifiers/intern/MOD_uvproject.c	2011-12-19 08:26:53 UTC (rev 42722)
@@ -259,11 +259,12 @@
 		mul_mat3_m4_v3(projectors[i].ob->obmat, projectors[i].normal);
 	}
 
+	numFaces = dm->getNumFaces(dm);
+
 	/* make sure we are not modifying the original UV map */
 	tface = CustomData_duplicate_referenced_layer_named(&dm->faceData,
-			CD_MTFACE, uvname);
+			CD_MTFACE, uvname, numFaces);
 
-	
 	numVerts = dm->getNumVerts(dm);
 
 	coords = MEM_callocN(sizeof(*coords) * numVerts,
@@ -280,7 +281,6 @@
 			mul_project_m4_v3(projectors[0].projmat, *co);
 
 	mface = dm->getFaceArray(dm);
-	numFaces = dm->getNumFaces(dm);
 
 	/* apply coords as UVs, and apply image if tfaces are new */
 	for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tface) {




More information about the Bf-blender-cvs mailing list