fix [#27572] Mirror Shapekey and Mirror vertex Group not working for Lattice.
This commit is contained in:
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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= <->def[i1];
|
||||
bp_mirr= <->def[i2];
|
||||
|
||||
sel= bp->f1 & SELECT;
|
||||
sel_mirr= bp_mirr->f1 & SELECT;
|
||||
|
||||
if(sel || sel_mirr) {
|
||||
dvert= <->dvert[i1];
|
||||
dvert_mirr= <->dvert[i2];
|
||||
|
||||
VGROUP_MIRR_OP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MEM_freeN(flip_map);
|
||||
|
||||
#undef VGROUP_MIRR_OP
|
||||
}
|
||||
|
||||
static void vgroup_remap_update_users(Object *ob, int *map)
|
||||
|
@@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user