Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2011-12-19 12:26:53 +0400
committerBastien Montagne <montagne29@wanadoo.fr>2011-12-19 12:26:53 +0400
commit90ef435145416313596cafa6f8c4c6c6aebe4e44 (patch)
treea4fb3a2027baee153227365f65a3795529b99a31
parent53f88b231a3cd492ba45914a1813a633b1189218 (diff)
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.
-rw-r--r--source/blender/blenkernel/BKE_customdata.h4
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c6
-rw-r--r--source/blender/blenkernel/intern/customdata.c34
-rw-r--r--source/blender/modifiers/intern/MOD_solidify.c4
-rw-r--r--source/blender/modifiers/intern/MOD_uvproject.c6
5 files changed, 40 insertions, 14 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index f6b4240a026..1d344c6e810 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -121,9 +121,9 @@ int CustomData_number_of_layers(const struct CustomData *data, int type);
/* 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
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 2cf2225607e..6f088b8abf7 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1870,7 +1870,7 @@ void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
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 @@ void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
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 @@ void CDDM_calc_normals(DerivedMesh *dm)
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);
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index c88b21e2813..5305372402b 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -1404,7 +1404,7 @@ int CustomData_number_of_layers(const CustomData *data, int type)
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 @@ void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type)
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(struct CustomData *data, int type)
}
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 @@ void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
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;
}
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index 347af0066c6..067d66fc82c 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -75,8 +75,8 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3])
/* 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;
*/
diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c
index acf65a56561..3146d1c9d5d 100644
--- a/source/blender/modifiers/intern/MOD_uvproject.c
+++ b/source/blender/modifiers/intern/MOD_uvproject.c
@@ -259,11 +259,12 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
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 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
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) {