From 95bfbd470eeb1ccb3f69b5ba63875772860acdbf Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 2 Feb 2010 21:43:26 +0000 Subject: vertex group sort operator, access from the vgroup panel, sintels mesh has 144 vertex groups which got quite tedious to look through. --- source/blender/blenkernel/BKE_deform.h | 1 + source/blender/blenkernel/intern/deform.c | 10 ++ source/blender/blenlib/BLI_listbase.h | 1 + source/blender/blenlib/intern/listbase.c | 21 +++++ source/blender/editors/object/object_intern.h | 1 + source/blender/editors/object/object_ops.c | 1 + source/blender/editors/object/object_vgroup.c | 129 ++++++++++++++++++++------ 7 files changed, 134 insertions(+), 30 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index 53844c1e6a5..e2302993551 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -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); diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 6c873bc262e..5af375696ba 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -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; itotweight; i++, dw++) { + dw->def_nr= map[dw->def_nr]; + } +} + void defvert_normalize (MDeformVert *dvert) { if(dvert->totweight<=0) { diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index f4841762227..79f7fb90091 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -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); diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index 6626896d266..5c43c2440aa 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -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; diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 06768404d7e..0f931e6912d 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -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); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index b9935fafb74..1e71f9bf1d3 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -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); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index b3bea407b2f..933c25b7dbd 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -28,6 +28,7 @@ */ #include +#include #include #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; avgroup[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; iprop= 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; iid, 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; +} -- cgit v1.2.3