forked from bartvdbraak/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.
This commit is contained in:
parent
53f88b231a
commit
90ef435145
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
*/
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user