diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index edbf4da33ac..339d13b06b2 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -361,6 +361,13 @@ void BKE_mesh_poly_edgehash_insert(struct EdgeHash *ehash, const struct MPoly *m void BKE_mesh_do_versions_cd_flag_init(struct Mesh *mesh); + +void BKE_mesh_mselect_clear(struct Mesh *me); +void BKE_mesh_mselect_validate(struct Mesh *me); +int BKE_mesh_mselect_find(struct Mesh *me, int index, int type); +int BKE_mesh_mselect_active_get(struct Mesh *me, int type); +void BKE_mesh_mselect_active_set(struct Mesh *me, int index, int type); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 3bb2d6fdba4..0ef92ca75a3 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -3767,3 +3767,130 @@ void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh) } } + + +/* -------------------------------------------------------------------- */ +/* MSelect functions (currently used in weight paint mode) */ + +void BKE_mesh_mselect_clear(Mesh *me) +{ + MEM_freeN(me->mselect); + me->mselect = NULL; + me->totselect = 0; +} + +void BKE_mesh_mselect_validate(Mesh *me) +{ + MSelect *mselect_src, *mselect_dst; + int i_src, i_dst; + + if (me->totselect == 0) + return; + + mselect_src = me->mselect; + mselect_dst = MEM_mallocN(sizeof(MSelect) * (me->totselect), "Mesh selection history"); + + for (i_src = 0, i_dst = 0; i_src < me->totselect; i_src++) { + int index = mselect_src[i_src].index; + switch (mselect_src[i_src].type) { + case ME_VSEL: + { + if (me->mvert[index].flag & SELECT) { + mselect_dst[i_dst] = mselect_src[i_src]; + i_dst++; + } + break; + } + case ME_ESEL: + { + if (me->medge[index].flag & SELECT) { + mselect_dst[i_dst] = mselect_src[i_src]; + i_dst++; + } + break; + } + case ME_FSEL: + { + if (me->mpoly[index].flag & SELECT) { + mselect_dst[i_dst] = mselect_src[i_src]; + i_dst++; + } + break; + } + default: + { + BLI_assert(0); + break; + } + } + } + + MEM_freeN(mselect_src); + + if (i_dst == 0) { + MEM_freeN(mselect_dst); + mselect_dst = NULL; + } + else if (i_dst != me->totselect) { + mselect_dst = MEM_reallocN(mselect_dst, sizeof(MSelect) * i_dst); + } + + me->totselect = i_dst; + me->mselect = mselect_dst; + +} + +/** + * Return the index within me->mselect, or -1 + */ +int BKE_mesh_mselect_find(Mesh *me, int index, int type) +{ + int i; + + BLI_assert(ELEM3(type, ME_VSEL, ME_ESEL, ME_FSEL)); + + for (i = 0; i < me->totselect; i++) { + if ((me->mselect[i].index == index) && + (me->mselect[i].type == type)) + { + return i; + } + } + + return -1; +} + +/** + * Return The index of the active element. + */ +int BKE_mesh_mselect_active_get(Mesh *me, int type) +{ + BLI_assert(ELEM3(type, ME_VSEL, ME_ESEL, ME_FSEL)); + + if (me->totselect) { + if (me->mselect[me->totselect - 1].type == type) { + return me->mselect[me->totselect - 1].index; + } + } + return -1; +} + +void BKE_mesh_mselect_active_set(Mesh *me, int index, int type) +{ + const int msel_index = BKE_mesh_mselect_find(me, index, type); + + if (msel_index == -1) { + /* add to the end */ + me->mselect = MEM_reallocN(me->mselect, sizeof(MSelect) * (me->totselect + 1)); + me->mselect[me->totselect].index = index; + me->mselect[me->totselect].type = type; + me->totselect++; + } + else if (msel_index != me->totselect - 1) { + /* move to the end */ + SWAP(MSelect, me->mselect[msel_index], me->mselect[me->totselect - 1]); + } + + BLI_assert((me->mselect[me->totselect - 1].index == index) && + (me->mselect[me->totselect - 1].type == type)); +}