Fix group flipping when syncing mirror weights

Corrects mirror syncing for invert, levels & smooth.

Note that the code changed to process mirroring even if both verts are selected,
since group flipping can mean that is still meaningful.
This commit is contained in:
2016-02-09 00:18:45 +11:00
committed by Campbell Barton
parent 172143d4f8
commit c6afa36f47
3 changed files with 46 additions and 17 deletions

View File

@@ -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,

View File

@@ -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;

View File

@@ -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);
}
}