Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2010-01-26 20:07:47 +0300
committerCampbell Barton <ideasman42@gmail.com>2010-01-26 20:07:47 +0300
commit246bcf48ade22aefd06cb9e5c0dbd4e0f5e68f3c (patch)
treed52d6a4846e80c7a37d95417c978dbe55a4b2789 /source/blender/blenkernel/intern/deform.c
parente308fe9632b990ab2616d5ecc8402c945e15de3d (diff)
weight panel editing now supports mirroring
- use mirror when the option is enabled in editmode. - fliped group names are used when they exist. - only the setting that is edited will be applied to the mirrored verts group. - copy value is applied to all mirrored verts of the selection. - normalize normalizes all vgroups and mirrors. utility functions defvert_sync and defvert_sync_mapped, similar to defvert_copy but does not remove existing groups and optionally creates groups as needed. defvert_sync_mapped uses a an int array for mapping the flipped values.
Diffstat (limited to 'source/blender/blenkernel/intern/deform.c')
-rw-r--r--source/blender/blenkernel/intern/deform.c123
1 files changed, 108 insertions, 15 deletions
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 69a10768477..cb31f533d9a 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -96,6 +96,7 @@ bDeformGroup *defgroup_duplicate (bDeformGroup *ingroup)
return outgroup;
}
+/* copy & overwrite weights */
void defvert_copy (MDeformVert *dvert_r, const MDeformVert *dvert)
{
if(dvert_r->totweight == dvert->totweight) {
@@ -115,6 +116,44 @@ void defvert_copy (MDeformVert *dvert_r, const MDeformVert *dvert)
}
}
+/* only sync over matching weights, don't add or remove groups
+ * warning, loop within loop.
+ */
+void defvert_sync (MDeformVert *dvert_r, const MDeformVert *dvert, int use_verify)
+{
+ if(dvert->totweight && dvert_r->totweight) {
+ int i;
+ MDeformWeight *dw;
+ for(i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++) {
+ MDeformWeight *dw_r;
+ if(use_verify) dw_r= defvert_find_index(dvert_r, dw->def_nr);
+ else dw_r= defvert_verify_index(dvert_r, dw->def_nr);
+
+ if(dw_r) {
+ dw_r->weight= dw->weight;
+ }
+ }
+ }
+}
+
+/* be sure all flip_map values are valid */
+void defvert_sync_mapped (MDeformVert *dvert_r, const MDeformVert *dvert, int *flip_map, int use_verify)
+{
+ if(dvert->totweight && dvert_r->totweight) {
+ int i;
+ MDeformWeight *dw;
+ for(i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++) {
+ MDeformWeight *dw_r;
+ if(use_verify) dw_r= defvert_find_index(dvert_r, flip_map[dw->def_nr]);
+ else dw_r= defvert_verify_index(dvert_r, flip_map[dw->def_nr]);
+
+ if(dw_r) {
+ dw_r->weight= dw->weight;
+ }
+ }
+ }
+}
+
void defvert_normalize (MDeformVert *dvert)
{
if(dvert->totweight<=0) {
@@ -225,7 +264,7 @@ int defgroup_find_index (Object *ob, bDeformGroup *dg)
}
/* note, must be freed */
-int *defgroup_flip_map(Object *ob)
+int *defgroup_flip_map(Object *ob, int use_default)
{
bDeformGroup *dg;
int totdg= BLI_countlist(&ob->defbase);
@@ -236,14 +275,20 @@ int *defgroup_flip_map(Object *ob)
else {
char name[sizeof(dg->name)];
int i, flip_num, *map= MEM_mallocN(totdg * sizeof(int), "get_defgroup_flip_map");
+
memset(map, -1, totdg * sizeof(int));
for (dg=ob->defbase.first, i=0; dg; dg=dg->next, i++) {
if(map[i] == -1) { /* may be calculated previously */
+
+ /* incase no valid value is found, use this */
+ if(use_default)
+ map[i]= i;
+
flip_side_name(name, dg->name, 0);
if(strcmp(name, dg->name)) {
flip_num= defgroup_name_index(ob, name);
- if(flip_num > -1) {
+ if(flip_num >= 0) {
map[i]= flip_num;
map[flip_num]= i; /* save an extra lookup */
}
@@ -254,6 +299,22 @@ int *defgroup_flip_map(Object *ob)
}
}
+int defgroup_flip_index(Object *ob, int index, int use_default)
+{
+ bDeformGroup *dg= BLI_findlink(&ob->defbase, index);
+ int flip_index = -1;
+
+ if(dg) {
+ char name[sizeof(dg->name)];
+ flip_side_name(name, dg->name, 0);
+
+ if(strcmp(name, dg->name))
+ flip_index= defgroup_name_index(ob, name);
+ }
+
+ return (flip_index==-1 && use_default) ? index : flip_index;
+}
+
void defgroup_unique_name (bDeformGroup *dg, Object *ob)
{
bDeformGroup *curdef;
@@ -423,29 +484,61 @@ void flip_side_name (char *name, const char *from_name, int strip_number)
sprintf (name, "%s%s%s%s", prefix, replace, suffix, number);
}
+float defvert_find_weight(const struct MDeformVert *dvert, int group_num)
+{
+ MDeformWeight *dw= defvert_find_index(dvert, group_num);
+ return dw ? dw->weight : 1.0f;
+}
+float defvert_array_find_weight_safe(const struct MDeformVert *dvert, int index, int group_num)
+{
+ if(group_num == -1 || dvert == NULL)
+ return 1.0f;
-float defvert_find_weight(const struct MDeformVert *dvert, int group_num)
+ return defvert_find_weight(dvert+index, group_num);
+}
+
+
+MDeformWeight *defvert_find_index(const MDeformVert *dvert, int defgroup)
{
- if(dvert)
- {
- const MDeformWeight *dw = dvert->dw;
+ if(dvert && defgroup >= 0) {
+ MDeformWeight *dw = dvert->dw;
int i;
for(i=dvert->totweight; i>0; i--, dw++)
- if(dw->def_nr == group_num)
- return dw->weight;
+ if(dw->def_nr == defgroup)
+ return dw;
}
- /* Not found */
- return 0.0;
+ return NULL;
}
-float defvert_find_weight_safe(const struct MDeformVert *dvert, int index, int group_num)
+/* Ensures that mv has a deform weight entry for the specified defweight group */
+/* Note this function is mirrored in editmesh_tools.c, for use for editvertices */
+MDeformWeight *defvert_verify_index(MDeformVert *dv, int defgroup)
{
- if(group_num == -1 || dvert == NULL)
- return 1.0;
+ MDeformWeight *newdw;
- return defvert_find_weight(dvert+index, group_num);
-}
+ /* do this check always, this function is used to check for it */
+ if(!dv || defgroup<0)
+ return NULL;
+ newdw = defvert_find_index(dv, defgroup);
+ if(newdw)
+ return newdw;
+
+ newdw = MEM_callocN(sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight");
+ if(dv->dw) {
+ memcpy(newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
+ MEM_freeN(dv->dw);
+ }
+ dv->dw=newdw;
+
+ dv->dw[dv->totweight].weight=0.0f;
+ dv->dw[dv->totweight].def_nr=defgroup;
+ /* Group index */
+
+ dv->totweight++;
+
+ return dv->dw+(dv->totweight-1);
+}