vertex group sort operator, access from the vgroup panel, sintels mesh has 144 vertex groups which got quite tedious to look through.

This commit is contained in:
Campbell Barton 2010-02-02 21:43:26 +00:00
parent 1ee7b2fae4
commit 95bfbd470e
8 changed files with 135 additions and 30 deletions

@ -121,6 +121,7 @@ class DATA_PT_vertex_groups(DataButtonsPanel):
col = row.column(align=True)
col.operator("object.vertex_group_add", icon='ZOOMIN', text="")
col.operator("object.vertex_group_remove", icon='ZOOMOUT', text="")
col.operator("object.vertex_group_sort", icon='SORTALPHA', text="")
col.operator("object.vertex_group_copy", icon='COPY_ID', text="")
if ob.data.users > 1:

@ -58,6 +58,7 @@ 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_remap (struct MDeformVert *dvert, int *map);
void defvert_flip(struct MDeformVert *dvert, int *flip_map);
void defvert_normalize(struct MDeformVert *dvert);

@ -154,6 +154,16 @@ void defvert_sync_mapped (MDeformVert *dvert_r, const MDeformVert *dvert, int *f
}
}
/* be sure all flip_map values are valid */
void defvert_remap (MDeformVert *dvert, int *map)
{
MDeformWeight *dw;
int i;
for(i=0, dw=dvert->dw; i<dvert->totweight; i++, dw++) {
dw->def_nr= map[dw->def_nr];
}
}
void defvert_normalize (MDeformVert *dvert)
{
if(dvert->totweight<=0) {

@ -45,6 +45,7 @@ void BLI_insertlink(struct ListBase *listbase, void *vprevlink, void *vnewlink);
void *BLI_findlink(struct ListBase *listbase, int number);
int BLI_findindex(struct ListBase *listbase, void *vlink);
void *BLI_findstring(struct ListBase *listbase, const char *id, int offset);
int BLI_findstringindex(struct ListBase *listbase, const char *id, int offset);
void BLI_freelistN(struct ListBase *listbase);
void BLI_addtail(struct ListBase *listbase, void *vlink);
void BLI_remlink(struct ListBase *listbase, void *vlink);

@ -363,6 +363,27 @@ void *BLI_findstring(ListBase *listbase, const char *id, int offset)
return NULL;
}
int BLI_findstringindex(ListBase *listbase, const char *id, int offset)
{
Link *link= NULL;
const char *id_iter;
int i= 0;
if (listbase == NULL) return -1;
link= listbase->first;
while (link) {
id_iter= ((const char *)link) + offset;
if(id[0] == id_iter[0] && strcmp(id, id_iter)==0)
return i;
i++;
link= link->next;
}
return -1;
}
void BLI_duplicatelist(ListBase *list1, const ListBase *list2)
{
struct Link *link1, *link2;

@ -193,6 +193,7 @@ void OBJECT_OT_vertex_group_blend(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_clean(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_mirror(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_set_active(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_sort(struct wmOperatorType *ot);
void OBJECT_OT_game_property_new(struct wmOperatorType *ot);
void OBJECT_OT_game_property_remove(struct wmOperatorType *ot);

@ -178,6 +178,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_vertex_group_clean);
WM_operatortype_append(OBJECT_OT_vertex_group_mirror);
WM_operatortype_append(OBJECT_OT_vertex_group_set_active);
WM_operatortype_append(OBJECT_OT_vertex_group_sort);
WM_operatortype_append(OBJECT_OT_game_property_new);
WM_operatortype_append(OBJECT_OT_game_property_remove);

@ -28,6 +28,7 @@
*/
#include <string.h>
#include <stddef.h>
#include <math.h>
#include "MEM_guardedalloc.h"
@ -921,7 +922,7 @@ void ED_vgroup_mirror(Object *ob, int mirror_weights, int flip_vgroups)
}
}
static void vgroup_delete_update_users(Object *ob, int id)
static void vgroup_remap_update_users(Object *ob, int *map)
{
ExplodeModifierData *emd;
ModifierData *md;
@ -933,54 +934,47 @@ static void vgroup_delete_update_users(Object *ob, int id)
/* these cases don't use names to refer to vertex groups, so when
* they get deleted the numbers get out of sync, this corrects that */
if(ob->soft) {
if(ob->soft->vertgroup == id)
ob->soft->vertgroup= 0;
else if(ob->soft->vertgroup > id)
ob->soft->vertgroup--;
}
if(ob->soft)
ob->soft->vertgroup= map[ob->soft->vertgroup];
for(md=ob->modifiers.first; md; md=md->next) {
if(md->type == eModifierType_Explode) {
emd= (ExplodeModifierData*)md;
if(emd->vgroup == id)
emd->vgroup= 0;
else if(emd->vgroup > id)
emd->vgroup--;
emd->vgroup= map[emd->vgroup];
}
else if(md->type == eModifierType_Cloth) {
clmd= (ClothModifierData*)md;
clsim= clmd->sim_parms;
if(clsim) {
if(clsim->vgroup_mass == id)
clsim->vgroup_mass= 0;
else if(clsim->vgroup_mass > id)
clsim->vgroup_mass--;
if(clsim->vgroup_bend == id)
clsim->vgroup_bend= 0;
else if(clsim->vgroup_bend > id)
clsim->vgroup_bend--;
if(clsim->vgroup_struct == id)
clsim->vgroup_struct= 0;
else if(clsim->vgroup_struct > id)
clsim->vgroup_struct--;
clsim->vgroup_mass= map[clsim->vgroup_mass];
clsim->vgroup_bend= map[clsim->vgroup_bend];
clsim->vgroup_struct= map[clsim->vgroup_struct];
}
}
}
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
for(a=0; a<PSYS_TOT_VG; a++)
if(psys->vgroup[a] == id)
psys->vgroup[a]= 0;
else if(psys->vgroup[a] > id)
psys->vgroup[a]--;
psys->vgroup[a]= map[psys->vgroup[a]];
}
}
static void vgroup_delete_update_users(Object *ob, int id)
{
int i, tot= BLI_countlist(&ob->defbase) + 1;
int *map= MEM_mallocN(sizeof(int) * tot, "vgroup del");
map[id]= map[0]= 0;
for(i=1; i<id; i++) map[i]=i;
for(i=id+1; i<tot; i++) map[i]=i-1;
vgroup_remap_update_users(ob, map);
MEM_freeN(map);
}
static void vgroup_delete_object_mode(Object *ob)
{
bDeformGroup *dg;
@ -1840,3 +1834,78 @@ void OBJECT_OT_vertex_group_set_active(wmOperatorType *ot)
ot->prop= prop;
}
static int vgroup_sort(void *def_a_ptr, void *def_b_ptr)
{
bDeformGroup *def_a= (bDeformGroup *)def_a_ptr;
bDeformGroup *def_b= (bDeformGroup *)def_b_ptr;
return strcmp(def_a->name, def_b->name);
}
#define DEF_GROUP_SIZE (sizeof(((bDeformGroup *)NULL)->name))
static int vertex_group_sort_exec(bContext *C, wmOperator *op)
{
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
bDeformGroup *def;
int def_tot = BLI_countlist(&ob->defbase);
char *name;
char *name_array= MEM_mallocN(DEF_GROUP_SIZE * sizeof(char) * def_tot, "sort vgroups");
int *sort_map_update= MEM_mallocN(DEF_GROUP_SIZE * sizeof(int) * def_tot + 1, "sort vgroups"); /* needs a dummy index at the start*/
int *sort_map= sort_map_update + 1;
int i;
MDeformVert *dvert= NULL;
int dvert_tot;
name= name_array;
for(def = ob->defbase.first; def; def=def->next){
BLI_strncpy(name, def->name, DEF_GROUP_SIZE);
name += DEF_GROUP_SIZE;
}
BLI_sortlist(&ob->defbase, vgroup_sort);
name= name_array;
for(def= ob->defbase.first, i=0; def; def=def->next, i++){
sort_map[i]= BLI_findstringindex(&ob->defbase, name, offsetof(bDeformGroup, name));
name += DEF_GROUP_SIZE;
}
ED_vgroup_give_array(ob->data, &dvert, &dvert_tot);
while(dvert_tot--) {
defvert_remap(dvert, sort_map);
dvert++;
}
/* update users */
for(i=0; i<def_tot; i++)
sort_map[i]++;
sort_map_update[0]= 0;
vgroup_remap_update_users(ob, sort_map_update);
MEM_freeN(name_array);
MEM_freeN(sort_map_update);
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob);
return OPERATOR_FINISHED;
}
#undef DEF_GROUP_SIZE
void OBJECT_OT_vertex_group_sort(wmOperatorType *ot)
{
ot->name= "Sort Vertex Groups";
ot->idname= "OBJECT_OT_vertex_group_sort";
ot->description= "Sorts vertex groups alphabetically.";
/* api callbacks */
ot->poll= vertex_group_poll;
ot->exec= vertex_group_sort_exec;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}