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:
parent
1ee7b2fae4
commit
95bfbd470e
@ -121,6 +121,7 @@ class DATA_PT_vertex_groups(DataButtonsPanel):
|
|||||||
col = row.column(align=True)
|
col = row.column(align=True)
|
||||||
col.operator("object.vertex_group_add", icon='ZOOMIN', text="")
|
col.operator("object.vertex_group_add", icon='ZOOMIN', text="")
|
||||||
col.operator("object.vertex_group_remove", icon='ZOOMOUT', 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="")
|
col.operator("object.vertex_group_copy", icon='COPY_ID', text="")
|
||||||
if ob.data.users > 1:
|
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_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(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, 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, int *flip_map);
|
||||||
void defvert_normalize(struct MDeformVert *dvert);
|
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)
|
void defvert_normalize (MDeformVert *dvert)
|
||||||
{
|
{
|
||||||
if(dvert->totweight<=0) {
|
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);
|
void *BLI_findlink(struct ListBase *listbase, int number);
|
||||||
int BLI_findindex(struct ListBase *listbase, void *vlink);
|
int BLI_findindex(struct ListBase *listbase, void *vlink);
|
||||||
void *BLI_findstring(struct ListBase *listbase, const char *id, int offset);
|
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_freelistN(struct ListBase *listbase);
|
||||||
void BLI_addtail(struct ListBase *listbase, void *vlink);
|
void BLI_addtail(struct ListBase *listbase, void *vlink);
|
||||||
void BLI_remlink(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;
|
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)
|
void BLI_duplicatelist(ListBase *list1, const ListBase *list2)
|
||||||
{
|
{
|
||||||
struct Link *link1, *link2;
|
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_clean(struct wmOperatorType *ot);
|
||||||
void OBJECT_OT_vertex_group_mirror(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_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_new(struct wmOperatorType *ot);
|
||||||
void OBJECT_OT_game_property_remove(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_clean);
|
||||||
WM_operatortype_append(OBJECT_OT_vertex_group_mirror);
|
WM_operatortype_append(OBJECT_OT_vertex_group_mirror);
|
||||||
WM_operatortype_append(OBJECT_OT_vertex_group_set_active);
|
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_new);
|
||||||
WM_operatortype_append(OBJECT_OT_game_property_remove);
|
WM_operatortype_append(OBJECT_OT_game_property_remove);
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.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;
|
ExplodeModifierData *emd;
|
||||||
ModifierData *md;
|
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
|
/* 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 */
|
* they get deleted the numbers get out of sync, this corrects that */
|
||||||
|
|
||||||
if(ob->soft) {
|
if(ob->soft)
|
||||||
if(ob->soft->vertgroup == id)
|
ob->soft->vertgroup= map[ob->soft->vertgroup];
|
||||||
ob->soft->vertgroup= 0;
|
|
||||||
else if(ob->soft->vertgroup > id)
|
|
||||||
ob->soft->vertgroup--;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(md=ob->modifiers.first; md; md=md->next) {
|
for(md=ob->modifiers.first; md; md=md->next) {
|
||||||
if(md->type == eModifierType_Explode) {
|
if(md->type == eModifierType_Explode) {
|
||||||
emd= (ExplodeModifierData*)md;
|
emd= (ExplodeModifierData*)md;
|
||||||
|
emd->vgroup= map[emd->vgroup];
|
||||||
if(emd->vgroup == id)
|
|
||||||
emd->vgroup= 0;
|
|
||||||
else if(emd->vgroup > id)
|
|
||||||
emd->vgroup--;
|
|
||||||
}
|
}
|
||||||
else if(md->type == eModifierType_Cloth) {
|
else if(md->type == eModifierType_Cloth) {
|
||||||
clmd= (ClothModifierData*)md;
|
clmd= (ClothModifierData*)md;
|
||||||
clsim= clmd->sim_parms;
|
clsim= clmd->sim_parms;
|
||||||
|
|
||||||
if(clsim) {
|
if(clsim) {
|
||||||
if(clsim->vgroup_mass == id)
|
clsim->vgroup_mass= map[clsim->vgroup_mass];
|
||||||
clsim->vgroup_mass= 0;
|
clsim->vgroup_bend= map[clsim->vgroup_bend];
|
||||||
else if(clsim->vgroup_mass > id)
|
clsim->vgroup_struct= map[clsim->vgroup_struct];
|
||||||
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--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
|
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
|
||||||
for(a=0; a<PSYS_TOT_VG; a++)
|
for(a=0; a<PSYS_TOT_VG; a++)
|
||||||
if(psys->vgroup[a] == id)
|
psys->vgroup[a]= map[psys->vgroup[a]];
|
||||||
psys->vgroup[a]= 0;
|
|
||||||
else if(psys->vgroup[a] > id)
|
|
||||||
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)
|
static void vgroup_delete_object_mode(Object *ob)
|
||||||
{
|
{
|
||||||
bDeformGroup *dg;
|
bDeformGroup *dg;
|
||||||
@ -1840,3 +1834,78 @@ void OBJECT_OT_vertex_group_set_active(wmOperatorType *ot)
|
|||||||
ot->prop= prop;
|
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;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user