Fix group flipping when syncing mirror weights
authorAlexander Gavrilov <angavrilov@gmail.com>
Mon, 8 Feb 2016 13:18:45 +0000 (00:18 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 8 Feb 2016 13:19:28 +0000 (00:19 +1100)
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.

source/blender/blenkernel/BKE_deform.h
source/blender/blenkernel/intern/deform.c
source/blender/editors/object/object_vgroup.c

index 284080aa50d25cbd4788ed7d2be3f2b7e8a5ed51..8756f73df7236fde72405a708fb5e6843e92dfac 100644 (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,
index 574aa497d7477760ef34669d6568f006e96fc898..7052e0a7d25d13cb8afd5fd12c0fff993574b5cf 100644 (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;
index da1173f363aa2897bca646afedb634ab5abdf8ae..cc147464445a44306d5d34636593785e4abb3537 100644 (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);
                        }
                }