fix [#27572] Mirror Shapekey and Mirror vertex Group not working for Lattice.

This commit is contained in:
Campbell Barton
2011-06-06 06:40:09 +00:00
parent dd4f0f0b9d
commit e55833a094
6 changed files with 146 additions and 37 deletions

View 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

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

View 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);

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

View 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)

View 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