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:
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user