diff options
-rw-r--r-- | source/blender/blenkernel/BKE_deform.h | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/deform.c | 30 | ||||
-rw-r--r-- | source/blender/editors/object/object_vgroup.c | 25 |
3 files changed, 46 insertions, 17 deletions
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index 284080aa50d..8756f73df72 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -76,7 +76,13 @@ void defvert_copy(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert void defvert_copy_subset( struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src, const bool *vgroup_subset, const int vgroup_tot); -void defvert_copy_index(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src, const int defgroup); +void defvert_mirror_subset( + struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src, + const bool *vgroup_subset, const int vgroup_tot, + const int *flip_map, const int flip_map_len); +void defvert_copy_index( + struct MDeformVert *dvert_dst, const int defgroup_dst, + const struct MDeformVert *dvert_src, const int defgroup_src); void defvert_sync(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src, const bool use_verify); void defvert_sync_mapped( struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src, diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 574aa497d74..7052e0a7d25 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -119,7 +119,25 @@ void defvert_copy_subset( int defgroup; for (defgroup = 0; defgroup < vgroup_tot; defgroup++) { if (vgroup_subset[defgroup]) { - defvert_copy_index(dvert_dst, dvert_src, defgroup); + defvert_copy_index(dvert_dst, defgroup, dvert_src, defgroup); + } + } +} + +/** + * Overwrite weights filtered by vgroup_subset and with mirroring specified by the flip map + * - do nothing if neither are set. + * - add destination weight if needed + */ +void defvert_mirror_subset( + MDeformVert *dvert_dst, const MDeformVert *dvert_src, + const bool *vgroup_subset, const int vgroup_tot, + const int *flip_map, const int flip_map_len) +{ + int defgroup; + for (defgroup = 0; defgroup < vgroup_tot && defgroup < flip_map_len; defgroup++) { + if (vgroup_subset[defgroup] && (dvert_dst != dvert_src || flip_map[defgroup] != defgroup)) { + defvert_copy_index(dvert_dst, flip_map[defgroup], dvert_src, defgroup); } } } @@ -148,20 +166,22 @@ void defvert_copy(MDeformVert *dvert_dst, const MDeformVert *dvert_src) * - do nothing if neither are set. * - add destination weight if needed. */ -void defvert_copy_index(MDeformVert *dvert_dst, const MDeformVert *dvert_src, const int defgroup) +void defvert_copy_index( + MDeformVert *dvert_dst, const int defgroup_dst, + const MDeformVert *dvert_src, const int defgroup_src) { MDeformWeight *dw_src, *dw_dst; - dw_src = defvert_find_index(dvert_src, defgroup); + dw_src = defvert_find_index(dvert_src, defgroup_src); if (dw_src) { /* source is valid, verify destination */ - dw_dst = defvert_verify_index(dvert_dst, defgroup); + dw_dst = defvert_verify_index(dvert_dst, defgroup_dst); dw_dst->weight = dw_src->weight; } else { /* source was NULL, assign zero, could also remove */ - dw_dst = defvert_find_index(dvert_dst, defgroup); + dw_dst = defvert_find_index(dvert_dst, defgroup_dst); if (dw_dst) { dw_dst->weight = 0.0f; diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index da1173f363a..cc147464445 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -257,7 +257,6 @@ void ED_vgroup_parray_mirror_sync(Object *ob, BMEditMesh *em = BKE_editmesh_from_object(ob); MDeformVert **dvert_array_all = NULL; int dvert_tot_all; - int i; /* get an array of all verts, not only selected */ if (ED_vgroup_parray_alloc(ob->data, &dvert_array_all, &dvert_tot_all, false) == false) { @@ -268,22 +267,26 @@ void ED_vgroup_parray_mirror_sync(Object *ob, BM_mesh_elem_table_ensure(em->bm, BM_VERT); } - for (i = 0; i < dvert_tot; i++) { - if (dvert_array[i] == NULL) { - /* its unselected, check if its mirror is */ - int i_sel = ED_mesh_mirror_get_vert(ob, i); - if ((i_sel != -1) && (i_sel != i) && (dvert_array[i_sel])) { + int flip_map_len; + const int *flip_map = defgroup_flip_map(ob, &flip_map_len, true); + + for (int i_src = 0; i_src < dvert_tot; i_src++) { + if (dvert_array[i_src] != NULL) { + /* its selected, check if its mirror exists */ + int i_dst = ED_mesh_mirror_get_vert(ob, i_src); + if (i_dst != -1 && dvert_array_all[i_dst] != NULL) { /* we found a match! */ - MDeformVert *dv_src = dvert_array[i_sel]; - MDeformVert *dv_dst = dvert_array_all[i]; + const MDeformVert *dv_src = dvert_array[i_src]; + MDeformVert *dv_dst = dvert_array_all[i_dst]; - defvert_copy_subset(dv_dst, dv_src, vgroup_validmap, vgroup_tot); + defvert_mirror_subset(dv_dst, dv_src, vgroup_validmap, vgroup_tot, flip_map, flip_map_len); - dvert_array[i] = dvert_array_all[i]; + dvert_array[i_dst] = dvert_array_all[i_dst]; } } } + MEM_freeN((void *)flip_map); MEM_freeN(dvert_array_all); } @@ -2123,7 +2126,7 @@ static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr, defvert_copy(dvert, dvert_mirr); } else { - defvert_copy_index(dvert, dvert_mirr, act_vgroup); + defvert_copy_index(dvert, act_vgroup, dvert_mirr, act_vgroup); } } |