panel for adjusting the active vertex groups weights
authorCampbell Barton <ideasman42@gmail.com>
Mon, 25 Jan 2010 23:12:02 +0000 (23:12 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 25 Jan 2010 23:12:02 +0000 (23:12 +0000)
source/blender/blenkernel/BKE_deform.h
source/blender/blenkernel/intern/deform.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/include/ED_mesh.h
source/blender/editors/object/object_vgroup.c
source/blender/editors/space_view3d/view3d_buttons.c
source/blender/makesdna/DNA_vec_types.h

index 59acea3..0e18683 100644 (file)
@@ -54,6 +54,7 @@ float vertexgroup_get_vertex_weight(const struct MDeformVert *dvert, int index,
 
 void copy_defvert (struct MDeformVert *dvert_r, const struct MDeformVert *dvert);
 void flip_defvert (struct MDeformVert *dvert, int *flip_map);
+void normalize_defvert (struct MDeformVert *dvert);
 
 #endif
 
index 38d4d72..a4c8e58 100644 (file)
@@ -115,6 +115,28 @@ void copy_defvert (MDeformVert *dvert_r, const MDeformVert *dvert)
        }
 }
 
+void normalize_defvert (MDeformVert *dvert)
+{
+       if(dvert->totweight<=0) {
+               /* nothing */
+       }
+       else if (dvert->totweight==1) {
+               dvert->dw[0].weight= 1.0f;
+       }
+       else {
+               int i;
+               float tot= 0.0f;
+               MDeformWeight *dw;
+               for(i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++)
+                       tot += dw->weight;
+
+               if(tot > 0.0f) {
+                       for(i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++)
+                               dw->weight /= tot;
+               }
+       }
+}
+
 void flip_defvert (MDeformVert *dvert, int *flip_map)
 {
        MDeformWeight *dw;
index f8e1523..06b01a8 100644 (file)
@@ -2031,7 +2031,7 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                                        BGpic *bgpic;
                                        writestruct(wd, DATA, "View3D", 1, v3d);
                                        for (bgpic= v3d->bgpicbase.first; bgpic; bgpic= bgpic->next)
-                                       writestruct(wd, DATA, "BGpic", 1, bgpic);
+                                               writestruct(wd, DATA, "BGpic", 1, bgpic);
                                        if(v3d->localvd) writestruct(wd, DATA, "View3D", 1, v3d->localvd);
                                }
                                else if(sl->spacetype==SPACE_IPO) {
index 174447c..6f0cf95 100644 (file)
@@ -189,6 +189,7 @@ struct bDeformGroup         *ED_vgroup_add_name(struct Object *ob, char *name);
 void                                   ED_vgroup_select_by_name(struct Object *ob, 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);
+void                                   ED_vgroup_mirror(struct Object *ob, int mirror_weights, int flip_vgroups);
 
 void           ED_vgroup_vert_add(struct Object *ob, struct bDeformGroup *dg, int vertnum,  float weight, int assignmode);
 void           ED_vgroup_vert_remove(struct Object *ob, struct bDeformGroup *dg, int vertnum);
index 20241f1..9ba1d9c 100644 (file)
@@ -904,7 +904,7 @@ static void vgroup_clean_all(Object *ob, float eul, int keep_single)
        }
 }
 
-static void vgroup_mirror(Object *ob, int mirror_weights, int flip_vgroups)
+void ED_vgroup_mirror(Object *ob, int mirror_weights, int flip_vgroups)
 {
        EditVert *eve, *eve_mirr;
        MDeformVert *dvert, *dvert_mirr;
@@ -1751,7 +1751,7 @@ static int vertex_group_mirror_exec(bContext *C, wmOperator *op)
 {
        Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
 
-       vgroup_mirror(ob, RNA_boolean_get(op->ptr,"mirror_weights"), RNA_boolean_get(op->ptr,"flip_group_names"));
+       ED_vgroup_mirror(ob, RNA_boolean_get(op->ptr,"mirror_weights"), RNA_boolean_get(op->ptr,"flip_group_names"));
 
        DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
@@ -1780,7 +1780,6 @@ void OBJECT_OT_vertex_group_mirror(wmOperatorType *ot)
 
 }
 
-
 static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *op)
 {
        Scene *scene= CTX_data_scene(C);
index 2ba281a..8d2b9a8 100644 (file)
@@ -70,6 +70,7 @@
 #include "BKE_scene.h"
 #include "BKE_screen.h"
 #include "BKE_utildefines.h"
+#include "BKE_deform.h"
 
 #include "BIF_gl.h"
 
@@ -366,6 +367,8 @@ static void v3d_editvertex_buts(const bContext *C, uiLayout *layout, View3D *v3d
                else if(totedge>1)
                        uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Crease:",    0, 20, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
                
+
+               uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Crease:",    0, 20, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
        }
        else {  // apply
                memcpy(ve_median, tfp->ve_median, sizeof(tfp->ve_median));
@@ -477,6 +480,197 @@ static void v3d_editvertex_buts(const bContext *C, uiLayout *layout, View3D *v3d
        }
 }
 
+#define B_VGRP_PNL_EDIT 1
+#define B_VGRP_PNL_COPY 2
+#define B_VGRP_PNL_NORMALIZE 3
+#define B_VGRP_PNL_COPY_SINGLE 100 /* or greater */
+
+static void act_vert_def(Object *ob, EditVert **eve, MDeformVert **dvert)
+{
+       if(ob && ob->mode & OB_MODE_EDIT && ob->type==OB_MESH && ob->defbase.first) {
+               Mesh *me= ob->data;
+               EditMesh *em = BKE_mesh_get_editmesh(me);
+               EditSelection *ese = ((EditSelection*)em->selected.last);
+
+               if(ese && ese->type == EDITVERT) {
+                       *eve= (EditVert*)ese->data;
+                       *dvert= CustomData_em_get(&em->vdata, (*eve)->data, CD_MDEFORMVERT);
+                       return;
+               }
+
+               BKE_mesh_end_editmesh(me, em);
+       }
+
+       *eve= NULL;
+       *dvert= NULL;
+}
+
+static void vgroup_copy_active_to_sel(Object *ob)
+{
+       EditVert *eve_act;
+       MDeformVert *dvert_act;
+
+       act_vert_def(ob, &eve_act, &dvert_act);
+
+       if(dvert_act==NULL) {
+               return;
+       }
+       else {
+               Mesh *me= ob->data;
+               EditMesh *em = BKE_mesh_get_editmesh(me);
+               EditVert *eve;
+               MDeformVert *dvert;
+
+               for(eve= em->verts.first; eve; eve= eve->next) {
+                       if(eve->f & SELECT && eve != eve_act) {
+                               dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
+                               if(dvert)
+                                       copy_defvert(dvert, dvert_act);
+                       }
+               }
+       }
+}
+
+static void vgroup_copy_active_to_sel_single(Object *ob, int def_nr)
+{
+       EditVert *eve_act;
+       MDeformVert *dvert_act;
+
+       act_vert_def(ob, &eve_act, &dvert_act);
+
+       if(dvert_act==NULL) {
+               return;
+       }
+       else {
+               Mesh *me= ob->data;
+               EditMesh *em = BKE_mesh_get_editmesh(me);
+               EditVert *eve;
+               MDeformVert *dvert;
+               MDeformWeight *dw;
+               float act_weight = -1.0f;
+               int i;
+
+               for(i=0, dw=dvert_act->dw; i < dvert_act->totweight; i++, dw++) {
+                       if(def_nr == dw->def_nr) {
+                               act_weight= dw->weight;
+                               break;
+                       }
+               }
+
+               if(act_weight < -0.5f)
+                       return;
+
+               for(eve= em->verts.first; eve; eve= eve->next) {
+                       if(eve->f & SELECT && eve != eve_act) {
+                               dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
+                               if(dvert) {
+                                       for(i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++) {
+                                               if(def_nr == dw->def_nr) {
+                                                       dw->weight= act_weight;
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+static void vgroup_normalize_active(Object *ob)
+{
+       EditVert *eve_act;
+       MDeformVert *dvert_act;
+
+       act_vert_def(ob, &eve_act, &dvert_act);
+
+       if(dvert_act==NULL)
+               return;
+
+       normalize_defvert(dvert_act);
+}
+
+static void do_view3d_vgroup_buttons(bContext *C, void *arg, int event)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *ob= OBACT;
+
+       if(event==B_VGRP_PNL_EDIT) {
+               /* nothing */
+       }
+       else if(event==B_VGRP_PNL_NORMALIZE) {
+               vgroup_normalize_active(ob);
+       }
+       else if(event == B_VGRP_PNL_COPY) {
+               vgroup_copy_active_to_sel(ob);
+       }
+       else if(event >= B_VGRP_PNL_COPY_SINGLE) {
+               vgroup_copy_active_to_sel_single(ob, event - B_VGRP_PNL_COPY_SINGLE);
+       }
+
+//  todo
+//     if(((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_X)
+//             ED_vgroup_mirror(ob, 1, 1, 0);
+
+       /* default for now */
+       DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data);
+}
+
+int view3d_panel_vgroup_poll(const bContext *C, PanelType *pt)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *ob= OBACT;
+       EditVert *eve_act;
+       MDeformVert *dvert_act;
+
+       act_vert_def(ob, &eve_act, &dvert_act);
+
+       return dvert_act ? dvert_act->totweight : 0;
+}
+
+
+static void view3d_panel_vgroup(const bContext *C, Panel *pa)
+{
+       uiBlock *block= uiLayoutAbsoluteBlock(pa->layout);
+       Scene *scene= CTX_data_scene(C);
+       Object *ob= OBACT;
+
+       EditVert *eve;
+       MDeformVert *dvert;
+
+       act_vert_def(ob, &eve, &dvert);
+
+       if(dvert && dvert->totweight) {
+               uiLayout *col;
+               bDeformGroup *dg;
+               int i;
+               int yco = 0;
+
+               uiBlockSetHandleFunc(block, do_view3d_vgroup_buttons, NULL);
+
+               col= uiLayoutColumn(pa->layout, 0);
+               block= uiLayoutAbsoluteBlock(col);
+
+               uiBlockBeginAlign(block);
+
+               for (i=0; i<dvert->totweight; i++){
+                       dg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
+                       if(dg) {
+                               uiDefButF(block, NUM, B_VGRP_PNL_EDIT, dg->name,        0, yco, 180, 20, &dvert->dw[i].weight, 0.0, 1.0, 1, 3, "");
+                               uiDefBut(block, BUT, B_VGRP_PNL_COPY_SINGLE + dvert->dw[i].def_nr, "C", 180,yco,20,20, 0, 0, 0, 0, 0, "Copy this groups weight to other selected verts");
+                               yco -= 20;
+                       }
+               }
+               yco-=2;
+
+               uiBlockEndAlign(block);
+               uiBlockBeginAlign(block);
+               uiDefBut(block, BUT, B_VGRP_PNL_NORMALIZE, "Normalize", 0, yco,100,20, 0, 0, 0, 0, 0, "Normalize active vertex weights");
+               uiDefBut(block, BUT, B_VGRP_PNL_COPY, "Copy", 100,yco,100,20, 0, 0, 0, 0, 0, "Copy active vertex to other seleted verts");
+               uiBlockEndAlign(block);
+       }
+}
+
 static void v3d_transform_butsR(uiLayout *layout, PointerRNA *ptr)
 {
        uiLayout *split, *colsub;
@@ -1191,7 +1385,14 @@ void view3d_buttons_register(ARegionType *art)
        strcpy(pt->label, "Grease Pencil");
        pt->draw= gpencil_panel_standard;
        BLI_addtail(&art->paneltypes, pt);
-       
+
+       pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel vgroup");
+       strcpy(pt->idname, "VIEW3D_PT_vgroup");
+       strcpy(pt->label, "Vertex Groups");
+       pt->draw= view3d_panel_vgroup;
+       pt->poll= view3d_panel_vgroup_poll;
+       BLI_addtail(&art->paneltypes, pt);
+
        // XXX view3d_panel_preview(C, ar, 0);
 }
 
index 264ad34..4dc3c44 100644 (file)
@@ -38,14 +38,16 @@ typedef struct vec2s {
        short x, y;
 } vec2s;
 
-typedef struct vec2i {
-       int x, y;
-} vec2i;
-
 typedef struct vec2f {
        float x, y;
 } vec2f;
 
+/* not used at the moment */
+#if 0
+typedef struct vec2i {
+       int x, y;
+} vec2i;
+
 typedef struct vec2d {
        double x, y;
 } vec2d;
@@ -73,6 +75,7 @@ typedef struct vec4f {
 typedef struct vec4d {
        double x, y, z, w;
 } vec4d;
+#endif
 
 typedef struct rcti {
     int xmin, xmax;