diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index e387fc5f97c..4736e7b7312 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -122,7 +122,10 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, void CustomData_bmesh_merge(struct CustomData *source, struct CustomData *dest, CustomDataMask mask, int alloctype, struct BMesh *bm, const char htype); -/* frees data associated with a CustomData object (doesn't free the object +/** NULL's all members and resets the typemap. */ +void CustomData_reset(struct CustomData *data); + +/** frees data associated with a CustomData object (doesn't free the object * itself, though) */ void CustomData_free(struct CustomData *data, int totelem); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 1851042f84a..fd92b7b5d69 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -289,6 +289,13 @@ void DM_init(DerivedMesh *dm, DerivedMeshType type, int numVerts, int numEdges, dm->needsFree = 1; dm->auto_bump_scale = -1.0f; dm->dirty = 0; + + /* don't use CustomData_reset(...); because we dont want to touch customdata */ + fill_vn_i(dm->vertData.typemap, CD_NUMTYPES, -1); + fill_vn_i(dm->edgeData.typemap, CD_NUMTYPES, -1); + fill_vn_i(dm->faceData.typemap, CD_NUMTYPES, -1); + fill_vn_i(dm->loopData.typemap, CD_NUMTYPES, -1); + fill_vn_i(dm->polyData.typemap, CD_NUMTYPES, -1); } void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type, @@ -466,11 +473,11 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob) int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly; int did_shapekeys = 0; - memset(&tmp.vdata, 0, sizeof(tmp.vdata)); - memset(&tmp.edata, 0, sizeof(tmp.edata)); - memset(&tmp.fdata, 0, sizeof(tmp.fdata)); - memset(&tmp.ldata, 0, sizeof(tmp.ldata)); - memset(&tmp.pdata, 0, sizeof(tmp.pdata)); + CustomData_reset(&tmp.vdata); + CustomData_reset(&tmp.edata); + CustomData_reset(&tmp.fdata); + CustomData_reset(&tmp.ldata); + CustomData_reset(&tmp.pdata); totvert = tmp.totvert = dm->getNumVerts(dm); totedge = tmp.totedge = dm->getNumEdges(dm); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index e1041391d3b..76ed8467c8f 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -1245,6 +1245,13 @@ void CustomData_update_typemap(CustomData *data) } } +static int customdata_typemap_is_valid(const CustomData *data) +{ + CustomData data_copy = *data; + CustomData_update_typemap(&data_copy); + return (memcmp(data->typemap, data_copy.typemap, sizeof(data->typemap)) == 0); +} + void CustomData_merge(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, int alloctype, int totelem) { @@ -1310,7 +1317,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, void CustomData_copy(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, int alloctype, int totelem) { - memset(dest, 0, sizeof(*dest)); + CustomData_reset(dest); if (source->external) dest->external = MEM_dupallocN(source->external); @@ -1341,6 +1348,12 @@ static void CustomData_external_free(CustomData *data) } } +void CustomData_reset(CustomData *data) +{ + memset(data, 0, sizeof(*data)); + fill_vn_i(data->typemap, CD_NUMTYPES, -1); +} + void CustomData_free(CustomData *data, int totelem) { int i; @@ -1352,8 +1365,7 @@ void CustomData_free(CustomData *data, int totelem) MEM_freeN(data->layers); CustomData_external_free(data); - - memset(data, 0, sizeof(*data)); + CustomData_reset(data); } static void customData_update_offsets(CustomData *data) @@ -1372,9 +1384,10 @@ static void customData_update_offsets(CustomData *data) CustomData_update_typemap(data); } -int CustomData_get_layer_index(const CustomData *data, int type) +/* to use when we're in the middle of modifying layers */ +static int CustomData_get_layer_index__notypemap(const CustomData *data, int type) { - int i; + int i; for (i = 0; i < data->totlayer; ++i) if (data->layers[i].type == type) @@ -1383,11 +1396,21 @@ int CustomData_get_layer_index(const CustomData *data, int type) return -1; } +/* -------------------------------------------------------------------- */ +/* index values to access the layers (offset from the layer start) */ + +int CustomData_get_layer_index(const CustomData *data, int type) +{ + BLI_assert(customdata_typemap_is_valid(data)); + return data->typemap[type]; +} + int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n) { int i = CustomData_get_layer_index(data, type); if (i != -1) { + BLI_assert(i + n < data->totlayer); i = (data->layers[i + n].type == type) ? (i + n) : (-1); } @@ -1407,91 +1430,62 @@ int CustomData_get_named_layer_index(const CustomData *data, int type, const cha int CustomData_get_active_layer_index(const CustomData *data, int type) { - if (!data->totlayer) - return -1; - - if (data->typemap[type] != -1) { - return data->typemap[type] + data->layers[data->typemap[type]].active; - } - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? layer_index + data->layers[layer_index].active: -1; } int CustomData_get_render_layer_index(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return i + data->layers[i].active_rnd; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? layer_index + data->layers[layer_index].active_rnd : -1; } int CustomData_get_clone_layer_index(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return i + data->layers[i].active_clone; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? layer_index + data->layers[layer_index].active_clone : -1; } int CustomData_get_stencil_layer_index(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return i + data->layers[i].active_mask; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? layer_index + data->layers[layer_index].active_mask : -1; } + +/* -------------------------------------------------------------------- */ +/* index values per layer type */ + int CustomData_get_active_layer(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return data->layers[i].active; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? data->layers[layer_index].active : -1; } int CustomData_get_render_layer(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return data->layers[i].active_rnd; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? data->layers[layer_index].active_rnd : -1; } int CustomData_get_clone_layer(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return data->layers[i].active_clone; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? data->layers[layer_index].active_clone : -1; } int CustomData_get_stencil_layer(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return data->layers[i].active_mask; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? data->layers[layer_index].active_mask : -1; } void CustomData_set_layer_active(CustomData *data, int type, int n) @@ -1722,7 +1716,7 @@ int CustomData_free_layer(CustomData *data, int type, int totelem, int index) /* if layer was last of type in array, set new active layer */ if ((index >= data->totlayer) || (data->layers[index].type != type)) { - i = CustomData_get_layer_index(data, type); + i = CustomData_get_layer_index__notypemap(data, type); if (i >= 0) for (; i < data->totlayer && data->layers[i].type == type; i++) { @@ -1737,7 +1731,6 @@ int CustomData_free_layer(CustomData *data, int type, int totelem, int index) customData_resize(data, -CUSTOMDATA_GROW); customData_update_offsets(data); - CustomData_update_typemap(data); return 1; } diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 449146fe640..c0a28c473f8 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -469,15 +469,17 @@ void free_dverts(MDeformVert *dvert, int totvert) static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata) { - if (free_customdata) + if (free_customdata) { CustomData_free(&mesh->fdata, mesh->totface); + } + else { + CustomData_reset(&mesh->fdata); + } mesh->mface = NULL; mesh->mtface = NULL; mesh->mcol = NULL; mesh->totface = 0; - - memset(&mesh->fdata, 0, sizeof(mesh->fdata)); } Mesh *BKE_mesh_add(const char *name) @@ -2125,8 +2127,6 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, CustomData *fdata, CustomData /* just in case some of these layers are filled in (can happen with python created meshes) */ CustomData_free(ldata, totloop_i); CustomData_free(pdata, totpoly_i); - memset(ldata, 0, sizeof(*ldata)); - memset(pdata, 0, sizeof(*pdata)); totpoly = totface_i; mpoly = MEM_callocN(sizeof(MPoly) * totpoly, "mpoly converted"); @@ -2632,7 +2632,6 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, } CustomData_free(fdata, totface); - memset(fdata, 0, sizeof(CustomData)); totface = mface_index; @@ -2777,7 +2776,6 @@ int BKE_mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata, } CustomData_free(fdata, totface); - memset(fdata, 0, sizeof(CustomData)); totface = k; diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index d34bb99ab98..66f2ff12258 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -2085,8 +2085,8 @@ void multires_load_old(Object *ob, Mesh *me) CustomData_add_layer(&me->vdata, l->type, CD_REFERENCE, l->data, me->totvert); for (i = 0, l = me->mr->fdata.layers; i < me->mr->fdata.totlayer; ++i, ++l) CustomData_add_layer(&me->fdata, l->type, CD_REFERENCE, l->data, me->totface); - memset(&me->mr->vdata, 0, sizeof(CustomData)); - memset(&me->mr->fdata, 0, sizeof(CustomData)); + CustomData_reset(&me->mr->vdata); + CustomData_reset(&me->mr->fdata); multires_load_old_vcols(me); multires_load_old_face_flags(me); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 02016b2597d..b49e392d1f4 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3824,7 +3824,7 @@ static void direct_link_customdata(FileData *fd, CustomData *data, int count) /* annoying workaround for bug [#31079] loading legacy files with * no polygons _but_ have stale customdata */ if (UNLIKELY(count == 0 && data->layers == NULL && data->totlayer != 0)) { - memset(data, 0, sizeof(*data)); + CustomData_reset(data); return; } @@ -8098,6 +8098,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) { Mesh *me; for (me = main->mesh.first; me; me = me->id.next) { + CustomData_update_typemap(&me->vdata); CustomData_free_layers(&me->vdata, CD_MSTICKY, me->totvert); } } diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 32879caec71..d3e3bcd3556 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -85,6 +85,11 @@ BMesh *BM_mesh_create(BMAllocTemplate *allocsize) bm->stackdepth = 1; bm->totflags = 1; + CustomData_reset(&bm->vdata); + CustomData_reset(&bm->edata); + CustomData_reset(&bm->ldata); + CustomData_reset(&bm->pdata); + return bm; } diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index b0a9168ffda..62abf43829b 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -536,7 +536,9 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) oldverts = me->mvert; /* don't free this yet */ - CustomData_set_layer(&me->vdata, CD_MVERT, NULL); + if (oldverts) { + CustomData_set_layer(&me->vdata, CD_MVERT, NULL); + } /* free custom data */ CustomData_free(&me->vdata, me->totvert); diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index a4640677a4e..5414ba2aefb 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -947,6 +947,7 @@ static void mesh_add_verts(Mesh *mesh, int len) /* scan the input list and insert the new vertices */ + /* set default flags */ mvert = &mesh->mvert[mesh->totvert]; for (i = 0; i < len; i++, mvert++) mvert->flag |= SELECT; diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 765f9307247..c0b6327d740 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -299,12 +299,12 @@ int join_mesh_exec(bContext *C, wmOperator *op) /* setup new data for destination mesh */ - memset(&vdata, 0, sizeof(vdata)); - memset(&edata, 0, sizeof(edata)); - memset(&fdata, 0, sizeof(fdata)); - memset(&ldata, 0, sizeof(ldata)); - memset(&pdata, 0, sizeof(pdata)); - + CustomData_reset(&vdata); + CustomData_reset(&edata); + CustomData_reset(&fdata); + CustomData_reset(&ldata); + CustomData_reset(&pdata); + mvert = CustomData_add_layer(&vdata, CD_MVERT, CD_CALLOC, NULL, totvert); medge = CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge); mloop = CustomData_add_layer(&ldata, CD_MLOOP, CD_CALLOC, NULL, totloop);