fix [#27572] Mirror Shapekey and Mirror vertex Group not working for Lattice.
authorCampbell Barton <ideasman42@gmail.com>
Mon, 6 Jun 2011 06:40:09 +0000 (06:40 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 6 Jun 2011 06:40:09 +0000 (06:40 +0000)
source/blender/blenkernel/BKE_deform.h
source/blender/blenkernel/intern/deform.c
source/blender/editors/include/ED_mesh.h
source/blender/editors/object/object_shapekey.c
source/blender/editors/object/object_vgroup.c
source/blender/makesdna/DNA_lattice_types.h

index a9ac201beda64c0a5b174e21040b9699df9483af..64cea9295736d999a5cc531352fa7bfa314c74bf 100644 (file)
@@ -59,9 +59,9 @@ float  defvert_array_find_weight_safe(const struct MDeformVert *dvert, int index
 
 void defvert_copy(struct MDeformVert *dvert_r, const struct MDeformVert *dvert);
 void defvert_sync(struct MDeformVert *dvert_r, const struct MDeformVert *dvert, int use_verify);
-void defvert_sync_mapped(struct MDeformVert *dvert_r, const struct MDeformVert *dvert, int *flip_map, int use_verify);
+void defvert_sync_mapped(struct MDeformVert *dvert_r, const struct MDeformVert *dvert, const int *flip_map, int use_verify);
 void defvert_remap (struct MDeformVert *dvert, int *map);
-void defvert_flip(struct MDeformVert *dvert, int *flip_map);
+void defvert_flip(struct MDeformVert *dvert, const int *flip_map);
 void defvert_normalize(struct MDeformVert *dvert);
 
 /* utility function, note that 32 chars is the maximum string length since its only
index 0696653d2e4c2c065168153d1fc283fa7b649ef5..11a0a5884eec7f3fd57c80b65b32c705cf1c91cf 100644 (file)
@@ -121,7 +121,7 @@ void defvert_sync (MDeformVert *dvert_r, const MDeformVert *dvert, int use_verif
 }
 
 /* be sure all flip_map values are valid */
-void defvert_sync_mapped (MDeformVert *dvert_r, const MDeformVert *dvert, int *flip_map, int use_verify)
+void defvert_sync_mapped (MDeformVert *dvert_r, const MDeformVert *dvert, const int *flip_map, int use_verify)
 {
        if(dvert->totweight && dvert_r->totweight) {
                int i;
@@ -170,7 +170,7 @@ void defvert_normalize (MDeformVert *dvert)
        }
 }
 
-void defvert_flip (MDeformVert *dvert, int *flip_map)
+void defvert_flip (MDeformVert *dvert, const int *flip_map)
 {
        MDeformWeight *dw;
        int i;
index 5c4dfc6ba3d9bbe93892c915353a0f51f8bfff44..ade69a00ff855b2e136f8156e81d36bcd23a17e6 100644 (file)
@@ -209,7 +209,7 @@ void                                        ED_vgroup_select_by_name(struct Object *ob, const char *name);
 void                                   ED_vgroup_data_create(struct ID *id);
 int                                            ED_vgroup_give_array(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot);
 int                                            ED_vgroup_copy_array(struct Object *ob, struct Object *ob_from);
-void                                   ED_vgroup_mirror(struct Object *ob, int mirror_weights, int flip_vgroups);
+void                                   ED_vgroup_mirror(struct Object *ob, const short mirror_weights, const short flip_vgroups);
 
 int                                            ED_vgroup_object_is_edit_mode(struct Object *ob);
 
index 7c59278dcf5ec66fcf464a68500e1c39877c7ada..fd2e7fd7c998540b2056159573a3ccbf18341afb 100644 (file)
@@ -203,9 +203,9 @@ static int object_shape_key_mirror(bContext *C, Object *ob)
                                                fp1= ((float *)kb->data) + i1*3;
                                                fp2= ((float *)kb->data) + i2*3;
 
-                                               VECCOPY(tvec,   fp1);
-                                               VECCOPY(fp1,    fp2);
-                                               VECCOPY(fp2,    tvec);
+                                               copy_v3_v3(tvec,        fp1);
+                                               copy_v3_v3(fp1, fp2);
+                                               copy_v3_v3(fp2, tvec);
 
                                                /* flip x axis */
                                                fp1[0] = -fp1[0];
@@ -217,7 +217,46 @@ static int object_shape_key_mirror(bContext *C, Object *ob)
 
                        mesh_octree_table(ob, NULL, NULL, 'e');
                }
-               /* todo, other types? */
+               else if (ob->type == OB_LATTICE) {
+                       Lattice *lt= ob->data;
+                       int i1, i2;
+                       float *fp1, *fp2;
+                       int u, v, w;
+                       /* half but found up odd value */
+                       const int pntsu_half = (((lt->pntsu / 2) + (lt->pntsu % 2))) ;
+
+                       /* currently editmode isnt supported by mesh so
+                        * ignore here for now too */
+
+                       /* if(lt->editlatt) lt= lt->editlatt->latt; */
+
+                       for(w=0; w<lt->pntsw; w++) {
+                               for(v=0; v<lt->pntsv; v++) {
+                                       for(u=0; u<pntsu_half; u++) {
+                                               int u_inv= (lt->pntsu - 1) - u;
+                                               float tvec[3];
+                                               if(u == u_inv) {
+                                                       i1= LT_INDEX(lt, u, v, w);
+                                                       fp1= ((float *)kb->data) + i1*3;
+                                                       fp1[0]= -fp1[0];
+                                               }
+                                               else {
+                                                       i1= LT_INDEX(lt, u, v, w);
+                                                       i2= LT_INDEX(lt, u_inv, v, w);
+
+                                                       fp1= ((float *)kb->data) + i1*3;
+                                                       fp2= ((float *)kb->data) + i2*3;
+
+                                                       copy_v3_v3(tvec, fp1);
+                                                       copy_v3_v3(fp1, fp2);
+                                                       copy_v3_v3(fp2, tvec);
+                                                       fp1[0]= -fp1[0];
+                                                       fp2[0]= -fp2[0];
+                                               }
+                                       }
+                               }
+                       }
+               }
 
                MEM_freeN(tag_elem);
        }
index 43448198ae153eaec46c7127ab60a73bf1601ea5..072c08c7ec06dcca8f92e39de29d9ca65d36fae3 100644 (file)
@@ -1015,55 +1015,75 @@ static void vgroup_clean_all(Object *ob, float eul, int keep_single)
        if (dvert_array) MEM_freeN(dvert_array);
 }
 
-void ED_vgroup_mirror(Object *ob, int mirror_weights, int flip_vgroups)
+
+static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr,
+                            const char sel, const char sel_mirr,
+                            const int *flip_map,
+                            const short mirror_weights, const short flip_vgroups)
+{
+       BLI_assert(sel || sel_mirr);
+
+       if(sel_mirr && sel) {
+               /* swap */
+               if(mirror_weights)
+                       SWAP(MDeformVert, *dvert, *dvert_mirr);
+               if(flip_vgroups) {
+                       defvert_flip(dvert, flip_map);
+                       defvert_flip(dvert_mirr, flip_map);
+               }
+       }
+       else {
+               /* dvert should always be the target */
+               if(sel_mirr) {
+                       SWAP(MDeformVert *, dvert, dvert_mirr);
+               }
+
+               if(mirror_weights)
+                       defvert_copy(dvert, dvert_mirr);
+               if(flip_vgroups) {
+                       defvert_flip(dvert, flip_map);
+               }
+       }
+}
+
+void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_vgroups)
 {
+#define VGROUP_MIRR_OP dvert_mirror_op(dvert, dvert_mirr, sel, sel_mirr, flip_map, mirror_weights, flip_vgroups)
+
        EditVert *eve, *eve_mirr;
        MDeformVert *dvert, *dvert_mirr;
+       short sel, sel_mirr;
        int     *flip_map;
 
        if(mirror_weights==0 && flip_vgroups==0)
                return;
 
+       flip_map= defgroup_flip_map(ob, 0);
+
        /* only the active group */
        if(ob->type == OB_MESH) {
                Mesh *me= ob->data;
                EditMesh *em = BKE_mesh_get_editmesh(me);
 
-               EM_cache_x_mirror_vert(ob, em);
 
-               if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT))
+               if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) {
+                       MEM_freeN(flip_map);
                        return;
+               }
 
-               flip_map= defgroup_flip_map(ob, 0);
+               EM_cache_x_mirror_vert(ob, em);
 
                /* Go through the list of editverts and assign them */
                for(eve=em->verts.first; eve; eve=eve->next){
                        if((eve_mirr=eve->tmp.v)) {
-                               if((eve_mirr->f & SELECT || eve->f & SELECT) && (eve != eve_mirr)) {
+                               sel= eve->f & SELECT;
+                               sel_mirr= eve_mirr->f & SELECT;
+
+                               if((sel || sel_mirr) && (eve != eve_mirr)) {
                                        dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
                                        dvert_mirr= CustomData_em_get(&em->vdata, eve_mirr->data, CD_MDEFORMVERT);
                                        if(dvert && dvert_mirr) {
-                                               if(eve_mirr->f & SELECT && eve->f & SELECT) {
-                                                       /* swap */
-                                                       if(mirror_weights)
-                                                               SWAP(MDeformVert, *dvert, *dvert_mirr);
-                                                       if(flip_vgroups) {
-                                                               defvert_flip(dvert, flip_map);
-                                                               defvert_flip(dvert_mirr, flip_map);
-                                                       }
-                                               }
-                                               else {
-                                                       /* dvert should always be the target */
-                                                       if(eve_mirr->f & SELECT) {
-                                                               SWAP(MDeformVert *, dvert, dvert_mirr);
-                                                       }
-
-                                                       if(mirror_weights)
-                                                               defvert_copy(dvert, dvert_mirr);
-                                                       if(flip_vgroups) {
-                                                               defvert_flip(dvert, flip_map);
-                                                       }
-                                               }
+                                               VGROUP_MIRR_OP;
                                        }
                                }
 
@@ -1071,10 +1091,58 @@ void ED_vgroup_mirror(Object *ob, int mirror_weights, int flip_vgroups)
                        }
                }
 
-               MEM_freeN(flip_map);
-
                BKE_mesh_end_editmesh(me, em);
        }
+       else if (ob->type == OB_LATTICE) {
+               Lattice *lt= ob->data;
+               int i1, i2;
+               int u, v, w;
+               int pntsu_half;
+               /* half but found up odd value */
+
+               if(lt->editlatt) lt= lt->editlatt->latt;
+
+               if(lt->pntsu == 1 || lt->dvert == NULL) {
+                       MEM_freeN(flip_map);
+                       return;
+               }
+
+               /* unlike editmesh we know that by only looping over the first hald of
+                * the 'u' indicies it will cover all points except the middle which is
+                * ok in this case */
+               pntsu_half= lt->pntsu / 2;
+
+               for(w=0; w<lt->pntsw; w++) {
+                       for(v=0; v<lt->pntsv; v++) {
+                               for(u=0; u<pntsu_half; u++) {
+                                       int u_inv= (lt->pntsu - 1) - u;
+                                       if(u != u_inv) {
+                                               BPoint *bp, *bp_mirr;
+
+                                               i1= LT_INDEX(lt, u, v, w);
+                                               i2= LT_INDEX(lt, u_inv, v, w);
+
+                                               bp= &lt->def[i1];
+                                               bp_mirr= &lt->def[i2];
+
+                                               sel= bp->f1 & SELECT;
+                                               sel_mirr= bp_mirr->f1 & SELECT;
+
+                                               if(sel || sel_mirr) {
+                                                       dvert= &lt->dvert[i1];
+                                                       dvert_mirr= &lt->dvert[i2];
+
+                                                       VGROUP_MIRR_OP;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       MEM_freeN(flip_map);
+
+#undef VGROUP_MIRR_OP
 }
 
 static void vgroup_remap_update_users(Object *ob, int *map)
index 662ef9e8a453d4e8b58f95b1e21b3213f5b1547c..a9e745b81487f2f87b382e43ffa026936a643744 100644 (file)
@@ -83,5 +83,7 @@ typedef struct Lattice {
 
 #define LT_DS_EXPAND   4
 
+#define LT_INDEX(lt, u, v, w) ((w) * ((lt)->pntsu * (lt)->pntsv) + ((v) * (lt)->pntsu) + (u))
+
 #endif