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:
authorGaia Clary <gaia.clary@machinimatrix.org>2013-06-23 19:37:08 +0400
committerGaia Clary <gaia.clary@machinimatrix.org>2013-06-23 19:37:08 +0400
commit70fd2320c8d2d9682ef8dea586e260193596d0e3 (patch)
tree958618cf6114c989562942731a659fbc62ab88c3
parent219f3ea85dfd1fa3decbe1abd644c53cc1f8bef0 (diff)
Added polished Vertex Weights Panel (properties sidebar)
-rw-r--r--source/blender/blenkernel/BKE_deform.h4
-rw-r--r--source/blender/blenkernel/intern/deform.c45
-rw-r--r--source/blender/editors/include/ED_mesh.h1
-rw-r--r--source/blender/editors/include/ED_object.h30
-rw-r--r--source/blender/editors/object/object_intern.h5
-rw-r--r--source/blender/editors/object/object_ops.c5
-rw-r--r--source/blender/editors/object/object_vgroup.c526
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c366
-rw-r--r--source/blender/makesdna/DNA_scene_types.h20
-rw-r--r--source/blender/makesrna/intern/rna_scene.c16
10 files changed, 674 insertions, 344 deletions
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index 5e8cd8d90fa..07bdbc1009b 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -65,6 +65,8 @@ float defvert_find_weight(const struct MDeformVert *dvert, const int defgroup);
float defvert_array_find_weight_safe(const struct MDeformVert *dvert, const int index, const int defgroup);
void defvert_copy(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src);
+void defvert_copy_subset(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src,
+ const bool *vgroup_subset, const int vgroup_tot);
void defvert_copy_index(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src, const int defgroup);
void defvert_sync(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src, const bool use_verify);
void defvert_sync_mapped(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src,
@@ -73,6 +75,8 @@ void defvert_remap(struct MDeformVert *dvert, int *map, const int map_len);
void defvert_flip(struct MDeformVert *dvert, const int *flip_map, const int flip_map_len);
void defvert_flip_merged(struct MDeformVert *dvert, const int *flip_map, const int flip_map_len);
void defvert_normalize(struct MDeformVert *dvert);
+void defvert_normalize_subset(struct MDeformVert *dvert,
+ const bool *vgroup_subset, const int vgroup_tot);
void defvert_normalize_lock_single(struct MDeformVert *dvert, const int def_nr_lock);
void defvert_normalize_lock_map(struct MDeformVert *dvert, const bool *lock_flags, const int defbase_tot);
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 371f64fd468..edeef26ed58 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -80,7 +80,21 @@ bDeformGroup *defgroup_duplicate(bDeformGroup *ingroup)
return outgroup;
}
-/* copy & overwrite weights */
+/* overwrite weights filtered by vgroup_subset
+ * - do nothing if neither are set.
+ * - add destination weight if needed
+ */
+void defvert_copy_subset(MDeformVert *dvert_dst, const MDeformVert *dvert_src,
+ const bool *vgroup_subset, const int vgroup_tot)
+{
+ int defgroup;
+ for (defgroup=0; defgroup < vgroup_tot; defgroup++) {
+ if (vgroup_subset[defgroup]) {
+ defvert_copy_index(dvert_dst, dvert_src, defgroup);
+ }
+ }
+}
+
void defvert_copy(MDeformVert *dvert_dst, const MDeformVert *dvert_src)
{
if (dvert_dst->totweight == dvert_src->totweight) {
@@ -181,6 +195,35 @@ void defvert_remap(MDeformVert *dvert, int *map, const int map_len)
}
}
+/**
+ * Same as #defvert_normalize but takes a bool array.
+ */
+void defvert_normalize_subset(MDeformVert *dvert,
+ const bool *vgroup_subset, const int vgroup_tot)
+{
+ MDeformWeight *dw;
+ unsigned int i;
+ float tot_weight = 0.0f;
+
+ for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
+ if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+ tot_weight += dw->weight;
+ }
+ }
+
+ if (tot_weight > 0.0f) {
+ float scalar = 1.0f / tot_weight;
+ for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
+ if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
+ dw->weight *= scalar;
+
+ /* in case of division errors with very low weights */
+ CLAMP(dw->weight, 0.0f, 1.0f);
+ }
+ }
+ }
+}
+
void defvert_normalize(MDeformVert *dvert)
{
if (dvert->totweight <= 0) {
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 0b25c494ba9..1ee3ae1283d 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -250,6 +250,7 @@ bool ED_vgroup_object_is_edit_mode(struct Object *ob);
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);
float ED_vgroup_vert_weight(struct Object *ob, struct bDeformGroup *dg, int vertnum);
+void ED_vgroup_vert_active_mirror(struct Object *ob, int def_nr);
/* mesh_data.c */
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index b2810031474..e891f648713 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -65,6 +65,11 @@ struct wmKeyConfig;
struct wmKeyMap;
struct wmOperator;
struct wmOperatorType;
+struct PointerRNA;
+struct PropertyRNA;
+struct EnumPropertyItem;
+
+enum eVGroupSelect;
/* object_edit.c */
struct Object *ED_object_context(struct bContext *C); /* context.object */
@@ -200,21 +205,16 @@ int ED_object_multires_update_totlevels_cb(struct Object *ob, void *totlevel_v);
/* object_select.c */
void ED_object_select_linked_by_id(struct bContext *C, struct ID *id);
-/* object_vgroup.c */
-typedef enum eVGroupSelect {
- WT_VGROUP_ACTIVE = 1,
- WT_VGROUP_BONE_SELECT = 2,
- WT_VGROUP_BONE_DEFORM = 3,
- WT_VGROUP_ALL = 4,
-} eVGroupSelect;
-
-#define WT_VGROUP_MASK_ALL \
- ((1 << WT_VGROUP_ACTIVE) | \
- (1 << WT_VGROUP_BONE_SELECT) | \
- (1 << WT_VGROUP_BONE_DEFORM) | \
- (1 << WT_VGROUP_ALL))
-
-bool *ED_vgroup_subset_from_select_type(struct Object *ob, eVGroupSelect subset_type, int *r_vgroup_tot, int *r_subset_count);
+
+bool *ED_vgroup_subset_from_select_type(struct Object *ob, enum eVGroupSelect subset_type,
+ int *r_vgroup_tot, int *r_subset_count);
+
+struct EnumPropertyItem *ED_object_vgroup_selection_itemf_helper(
+ const struct bContext *C,
+ struct PointerRNA *ptr,
+ struct PropertyRNA *prop,
+ int *free,
+ const unsigned int selection_mask);
#ifdef __cplusplus
}
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index e138d2fe24a..485987fd8fe 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -223,6 +223,11 @@ 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_vertex_group_move(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_weight_paste(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_weight_delete(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_weight_set_active(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_weight_normalize_active(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_weight_copy(struct wmOperatorType *ot);
/* object_shapekey.c */
void OBJECT_OT_shape_key_add(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 594dfd6e271..3afb04c34f6 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -195,6 +195,11 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_vertex_group_set_active);
WM_operatortype_append(OBJECT_OT_vertex_group_sort);
WM_operatortype_append(OBJECT_OT_vertex_group_move);
+ WM_operatortype_append(OBJECT_OT_vertex_weight_paste);
+ WM_operatortype_append(OBJECT_OT_vertex_weight_delete);
+ WM_operatortype_append(OBJECT_OT_vertex_weight_set_active);
+ WM_operatortype_append(OBJECT_OT_vertex_weight_normalize_active);
+ WM_operatortype_append(OBJECT_OT_vertex_weight_copy);
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 80ca0b38f8c..6da403074e8 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -411,6 +411,239 @@ bool ED_vgroup_copy_array(Object *ob, Object *ob_from)
return true;
}
+static MDeformVert *ED_mesh_active_dvert_get_em(Object *ob, BMVert **r_eve)
+{
+ if (ob->mode & OB_MODE_EDIT && ob->type == OB_MESH && ob->defbase.first) {
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_btmesh;
+ const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
+
+ if (cd_dvert_offset != -1) {
+ BMEditSelection *ese = (BMEditSelection *)em->bm->selected.last;
+
+ if (ese && ese->htype == BM_VERT) {
+ BMVert *eve = (BMVert *)ese->ele;
+ if (r_eve) *r_eve = eve;
+ return BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
+ }
+ }
+ }
+
+ if (r_eve) *r_eve = NULL;
+ return NULL;
+}
+
+/* TODO, cache flip data to speedup calls within a loop. */
+static void mesh_defvert_mirror_update_internal(Object *ob,
+ MDeformVert *dvert_dst, MDeformVert *dvert_src,
+ const int def_nr)
+{
+ if (def_nr == -1) {
+ /* all vgroups, add groups where neded */
+ int flip_map_len;
+ int *flip_map = defgroup_flip_map(ob, &flip_map_len, true);
+ defvert_sync_mapped(dvert_dst, dvert_src, flip_map, flip_map_len, true);
+ MEM_freeN(flip_map);
+ }
+ else {
+ /* single vgroup */
+ MDeformWeight *dw = defvert_verify_index(dvert_dst, defgroup_flip_index(ob, def_nr, 1));
+ if (dw) {
+ dw->weight = defvert_find_weight(dvert_src, def_nr);
+ }
+ }
+}
+
+static MDeformVert *ED_mesh_active_dvert_get_ob(Object *ob, int *r_index)
+{
+ Mesh *me = ob->data;
+ int index = BKE_mesh_mselect_active_get(me, ME_VSEL);
+ if (r_index) *r_index = index;
+ if (index == -1 || me->dvert == NULL) {
+ return NULL;
+ }
+ else {
+ return me->dvert + index;
+ }
+}
+
+static void ED_mesh_defvert_mirror_update_em(Object *ob, BMVert *eve, int def_nr, int vidx,
+ const int cd_dvert_offset)
+{
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_btmesh;
+ BMVert *eve_mirr;
+
+ eve_mirr = editbmesh_get_x_mirror_vert(ob, em, eve, eve->co, vidx);
+
+ if (eve_mirr && eve_mirr != eve) {
+ MDeformVert *dvert_src = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
+ MDeformVert *dvert_dst = BM_ELEM_CD_GET_VOID_P(eve_mirr, cd_dvert_offset);
+ mesh_defvert_mirror_update_internal(ob, dvert_dst, dvert_src, def_nr);
+ }
+}
+
+static void ED_mesh_defvert_mirror_update_ob(Object *ob, int def_nr, int vidx)
+{
+ int vidx_mirr;
+ Mesh *me = ob->data;
+ if (vidx == -1)
+ return;
+
+ vidx_mirr = mesh_get_x_mirror_vert(ob, vidx);
+
+ if ((vidx_mirr) >= 0 && (vidx_mirr != vidx)) {
+ MDeformVert *dvert_src = &me->dvert[vidx];
+ MDeformVert *dvert_dst = &me->dvert[vidx_mirr];
+ mesh_defvert_mirror_update_internal(ob, dvert_dst, dvert_src, def_nr);
+ }
+}
+
+static MDeformVert *ED_mesh_active_dvert_get_only(Object *ob)
+{
+ if (ob->type == OB_MESH) {
+ if (ob->mode & OB_MODE_EDIT) {
+ return ED_mesh_active_dvert_get_em(ob, NULL);
+ }
+ else {
+ return ED_mesh_active_dvert_get_ob(ob, NULL);
+ }
+ }
+ else {
+ return NULL;
+ }
+}
+
+/**
+ * Use when adjusting the active vertex weight and apply to mirror vertices.
+ */
+void ED_vgroup_vert_active_mirror(Object *ob, int def_nr)
+{
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_btmesh;
+ MDeformVert *dvert_act;
+
+ if (me->editflag & ME_EDIT_MIRROR_X) {
+ if (em) {
+ BMVert *eve_act;
+ dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act);
+ if (dvert_act) {
+ const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
+ ED_mesh_defvert_mirror_update_em(ob, eve_act, def_nr, -1, cd_dvert_offset);
+ }
+ }
+ else {
+ int v_act;
+ dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
+ if (dvert_act) {
+ ED_mesh_defvert_mirror_update_ob(ob, def_nr, v_act);
+ }
+ }
+ }
+}
+
+static void vgroup_remove_weight(Object *ob, const int def_nr)
+{
+ MDeformVert *dvert_act;
+ MDeformWeight *dw;
+
+ dvert_act = ED_mesh_active_dvert_get_only(ob);
+
+ dw = defvert_find_index(dvert_act, def_nr);
+ defvert_remove_group(dvert_act, dw);
+
+}
+
+static void vgroup_normalize_active(Object *ob, eVGroupSelect subset_type)
+{
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_btmesh;
+ BMVert *eve_act;
+ int v_act;
+ MDeformVert *dvert_act;
+ int subset_count, vgroup_tot;
+ const bool *vgroup_validmap;
+
+
+ if (em) {
+ dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act);
+ }
+ else {
+ dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
+ }
+
+ if (dvert_act == NULL) {
+ return;
+ }
+
+ vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+ defvert_normalize_subset(dvert_act, vgroup_validmap, vgroup_tot);
+ MEM_freeN((void *)vgroup_validmap);
+
+ if (me->editflag & ME_EDIT_MIRROR_X) {
+ if (em) {
+ const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
+ ED_mesh_defvert_mirror_update_em(ob, eve_act, -1, -1, cd_dvert_offset);
+ }
+ else {
+ int v_act = BKE_mesh_mselect_active_get(me, ME_VSEL);
+ ED_mesh_defvert_mirror_update_ob(ob, -1, v_act);
+ }
+ }
+}
+
+static void vgroup_copy_active_to_sel(Object *ob, eVGroupSelect subset_type)
+{
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_btmesh;
+ MDeformVert *dvert_act;
+ int i, vgroup_tot, subset_count;
+ const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+
+
+ if (em) {
+ BMIter iter;
+ BMVert *eve, *eve_act;
+ const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
+
+ dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act);
+ if (dvert_act == NULL) {
+ return;
+ }
+
+ BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && eve != eve_act) {
+ MDeformVert *dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
+ defvert_copy_subset(dv, dvert_act, vgroup_validmap, vgroup_tot);
+ if (me->editflag & ME_EDIT_MIRROR_X) {
+ ED_mesh_defvert_mirror_update_em(ob, eve, -1, i, cd_dvert_offset);
+ }
+ }
+ }
+ }
+ else {
+ MDeformVert *dv;
+ int v_act;
+
+ dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
+ if (dvert_act == NULL) {
+ return;
+ }
+
+ dv = me->dvert;
+ for (i = 0; i < me->totvert; i++, dv++) {
+ if ((me->mvert[i].flag & SELECT) && dv != dvert_act) {
+ defvert_copy_subset(dv, dvert_act, vgroup_validmap, vgroup_tot);
+ if (me->editflag & ME_EDIT_MIRROR_X) {
+ ED_mesh_defvert_mirror_update_ob(ob, -1, i);
+ }
+ }
+ }
+ }
+
+ MEM_freeN((void *)vgroup_validmap);
+}
+
/***********************Start weight transfer (WT)*********************************/
typedef enum WT_VertexGroupMode {
@@ -470,8 +703,8 @@ static EnumPropertyItem WT_vertex_group_select_item[] = {
{0, NULL, 0, NULL, NULL}
};
-static EnumPropertyItem *rna_vertex_group_selection_itemf_helper(
- bContext *C, PointerRNA *UNUSED(ptr),
+EnumPropertyItem *ED_object_vgroup_selection_itemf_helper(
+ const bContext *C, PointerRNA *UNUSED(ptr),
PropertyRNA *UNUSED(prop), int *free, const unsigned int selection_mask)
{
Object *ob;
@@ -505,13 +738,13 @@ static EnumPropertyItem *rna_vertex_group_selection_itemf_helper(
static EnumPropertyItem *rna_vertex_group_with_single_itemf(bContext *C, PointerRNA *ptr,
PropertyRNA *prop, int *free)
{
- return rna_vertex_group_selection_itemf_helper(C, ptr, prop, free, WT_VGROUP_MASK_ALL);
+ return ED_object_vgroup_selection_itemf_helper(C, ptr, prop, free, WT_VGROUP_MASK_ALL);
}
static EnumPropertyItem *rna_vertex_group_select_itemf(bContext *C, PointerRNA *ptr,
PropertyRNA *prop, int *free)
{
- return rna_vertex_group_selection_itemf_helper(C, ptr, prop, free, WT_VGROUP_MASK_ALL & ~(1 << WT_VGROUP_ACTIVE));
+ return ED_object_vgroup_selection_itemf_helper(C, ptr, prop, free, WT_VGROUP_MASK_ALL & ~(1 << WT_VGROUP_ACTIVE));
}
static void vgroup_operator_subset_select_props(wmOperatorType *ot, bool use_active)
@@ -1172,11 +1405,6 @@ bool *ED_vgroup_subset_from_select_type(Object *ob, eVGroupSelect subset_type, i
*r_vgroup_tot = BLI_countlist(&ob->defbase);
switch (subset_type) {
- case WT_VGROUP_ALL:
- vgroup_validmap = MEM_mallocN(*r_vgroup_tot * sizeof(*vgroup_validmap), __func__);
- memset(vgroup_validmap, true, *r_vgroup_tot * sizeof(*vgroup_validmap));
- *r_subset_count = *r_vgroup_tot;
- break;
case WT_VGROUP_ACTIVE:
{
const int def_nr_active = ob->actdef - 1;
@@ -1191,20 +1419,44 @@ bool *ED_vgroup_subset_from_select_type(Object *ob, eVGroupSelect subset_type, i
}
break;
}
- case WT_VGROUP_BONE_SELECT: {
+ case WT_VGROUP_BONE_SELECT:
+ {
vgroup_validmap = BKE_objdef_selected_get(ob, *r_vgroup_tot, r_subset_count);
break;
}
- case WT_VGROUP_BONE_DEFORM: {
+ case WT_VGROUP_BONE_DEFORM:
+ {
+ int i;
+ vgroup_validmap = BKE_objdef_validmap_get(ob, *r_vgroup_tot);
+ *r_subset_count = 0;
+ for (i = 0; i < *r_vgroup_tot; i++) {
+ if (vgroup_validmap[i] == true) {
+ *r_subset_count += 1;
+ }
+ }
+ break;
+ }
+ case WT_VGROUP_BONE_DEFORM_OFF:
+ {
int i;
vgroup_validmap = BKE_objdef_validmap_get(ob, *r_vgroup_tot);
*r_subset_count = 0;
for (i = 0; i < *r_vgroup_tot; i++) {
- if (vgroup_validmap[i])
+ vgroup_validmap[i] = !vgroup_validmap[i];
+ if (vgroup_validmap[i] == true) {
*r_subset_count += 1;
+ }
}
break;
}
+ case WT_VGROUP_ALL:
+ default:
+ {
+ vgroup_validmap = MEM_mallocN(*r_vgroup_tot * sizeof(*vgroup_validmap), __func__);
+ memset(vgroup_validmap, true, *r_vgroup_tot * sizeof(*vgroup_validmap));
+ *r_subset_count = *r_vgroup_tot;
+ break;
+ }
}
return vgroup_validmap;
@@ -1616,7 +1868,8 @@ static void vgroup_fix(Scene *scene, Object *ob, float distToBe, float strength,
}
}
-static void vgroup_levels_subset(Object *ob, bool *vgroup_validmap, const int vgroup_tot, const int UNUSED(subset_count),
+static void vgroup_levels_subset(Object *ob, const bool *vgroup_validmap, const int vgroup_tot,
+ const int UNUSED(subset_count),
const float offset, const float gain)
{
MDeformWeight *dw;
@@ -1746,7 +1999,9 @@ static void vgroup_lock_all(Object *ob, int action)
}
}
-static void vgroup_invert_subset(Object *ob, bool *vgroup_validmap, const int vgroup_tot, const int UNUSED(subset_count), const bool auto_assign, const bool auto_remove)
+static void vgroup_invert_subset(Object *ob,
+ const bool *vgroup_validmap, const int vgroup_tot,
+ const int UNUSED(subset_count), const bool auto_assign, const bool auto_remove)
{
MDeformWeight *dw;
MDeformVert *dv, **dvert_array = NULL;
@@ -3001,10 +3256,9 @@ static int vertex_group_levels_exec(bContext *C, wmOperator *op)
int subset_count, vgroup_tot;
- bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+ const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
vgroup_levels_subset(ob, vgroup_validmap, vgroup_tot, subset_count, offset, gain);
-
- MEM_freeN(vgroup_validmap);
+ MEM_freeN((void *)vgroup_validmap);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
@@ -3183,10 +3437,9 @@ static int vertex_group_invert_exec(bContext *C, wmOperator *op)
int subset_count, vgroup_tot;
- bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+ const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
vgroup_invert_subset(ob, vgroup_validmap, vgroup_tot, subset_count, auto_assign, auto_remove);
-
- MEM_freeN(vgroup_validmap);
+ MEM_freeN((void *)vgroup_validmap);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
@@ -3291,10 +3544,9 @@ static int vertex_group_clean_exec(bContext *C, wmOperator *op)
int subset_count, vgroup_tot;
- bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+ const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
vgroup_clean_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit, keep_single);
-
- MEM_freeN(vgroup_validmap);
+ MEM_freeN((void *)vgroup_validmap);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
@@ -3332,10 +3584,9 @@ static int vertex_group_limit_total_exec(bContext *C, wmOperator *op)
int subset_count, vgroup_tot;
- bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+ const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
int remove_tot = vgroup_limit_total_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit);
-
- MEM_freeN(vgroup_validmap);
+ MEM_freeN((void *)vgroup_validmap);
BKE_reportf(op->reports, remove_tot ? RPT_INFO : RPT_WARNING, "%d vertex weights limited", remove_tot);
@@ -3832,3 +4083,226 @@ void OBJECT_OT_vertex_group_move(wmOperatorType *ot)
RNA_def_enum(ot->srna, "direction", vgroup_slot_move, 0, "Direction", "Direction to move, UP or DOWN");
}
+
+static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr)
+{
+ MDeformVert *dvert_act;
+
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_btmesh;
+ float weight_act;
+ int i;
+
+ if (em) {
+ const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
+ BMIter iter;
+ BMVert *eve, *eve_act;
+
+ dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act);
+ if (dvert_act == NULL) {
+ return;
+ }
+ weight_act = defvert_find_weight(dvert_act, def_nr);
+
+ BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && (eve != eve_act)) {
+ MDeformVert *dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
+ MDeformWeight *dw = defvert_find_index(dv, def_nr);
+ if (dw) {
+ dw->weight = weight_act;
+
+ if (me->editflag & ME_EDIT_MIRROR_X) {
+ ED_mesh_defvert_mirror_update_em(ob, eve, -1, i, cd_dvert_offset);
+ }
+ }
+ }
+ }
+
+ if (me->editflag & ME_EDIT_MIRROR_X) {
+ ED_mesh_defvert_mirror_update_em(ob, eve_act, -1, -1, cd_dvert_offset);
+ }
+ }
+ else {
+ MDeformVert *dv;
+ int v_act;
+
+ dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
+ if (dvert_act == NULL) {
+ return;
+ }
+ weight_act = defvert_find_weight(dvert_act, def_nr);
+
+ dv = me->dvert;
+ for (i = 0; i < me->totvert; i++, dv++) {
+ if ((me->mvert[i].flag & SELECT) && (dv != dvert_act)) {
+ MDeformWeight *dw = defvert_find_index(dv, def_nr);
+ if (dw) {
+ dw->weight = weight_act;
+ if (me->editflag & ME_EDIT_MIRROR_X) {
+ ED_mesh_defvert_mirror_update_ob(ob, -1, i);
+ }
+ }
+ }
+ }
+
+ if (me->editflag & ME_EDIT_MIRROR_X) {
+ ED_mesh_defvert_mirror_update_ob(ob, -1, v_act);
+ }
+ }
+}
+
+static int vertex_weight_paste(bContext *C, wmOperator *op)
+{
+ Object *ob = ED_object_context(C);
+ const int wg_index = RNA_int_get(op->ptr, "weight_group");
+ vgroup_copy_active_to_sel_single(ob, wg_index);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_weight_paste(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ ot->name = "Paste weight to Selected";
+ ot->idname = "OBJECT_OT_vertex_weight_paste";
+ ot->description = "Copy this group's weight to other selected verts";
+
+ prop = RNA_def_int(ot->srna, "weight_group",
+ -1, 0, 0, "Weight Index", "Index of source weight in active Weight Group", 0, 0);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
+
+ /* api callbacks */
+ ot->poll = vertex_group_poll;
+ ot->exec = vertex_weight_paste;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int vertex_weight_delete(bContext *C, wmOperator *op)
+{
+ Object *ob = ED_object_context(C);
+ const int wg_index = RNA_int_get(op->ptr, "weight_group");
+ vgroup_remove_weight(ob, wg_index);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_weight_delete(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ ot->name = "Delete Weight";
+ ot->idname = "OBJECT_OT_vertex_weight_delete";
+ ot->description = "Delete this weight from the vertex";
+
+ prop = RNA_def_int(ot->srna, "weight_group",
+ -1, 0, 0, "Weight Index", "Index of source weight in active Weight Group", 0, 0);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
+
+ /* api callbacks */
+ ot->poll = vertex_group_poll;
+ ot->exec = vertex_weight_delete;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int vertex_weight_set_active(bContext *C, wmOperator *op)
+{
+ Object *ob = ED_object_context(C);
+ const int wg_index = RNA_int_get(op->ptr, "weight_group");
+
+ if (wg_index != -1) {
+ ob->actdef = wg_index + 1;
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_weight_set_active(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ ot->name = "Set Active Group";
+ ot->idname = "OBJECT_OT_vertex_weight_set_active";
+ ot->description = "Set as active Vertex Group";
+
+ prop = RNA_def_int(ot->srna, "weight_group",
+ -1, 0, 0, "Weight Index", "Index of source weight in active Weight Group", 0, 0);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
+
+ /* api callbacks */
+ ot->poll = vertex_group_poll;
+ ot->exec = vertex_weight_set_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int vertex_weight_normalize_active(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = ED_object_context(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ eVGroupSelect subset_type = ts->vgroupsubset;
+
+ vgroup_normalize_active(ob, subset_type);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_weight_normalize_active(wmOperatorType *ot)
+{
+
+ ot->name = "Normalize Active";
+ ot->idname = "OBJECT_OT_vertex_weight_normalize_active";
+ ot->description = "Normalize Active Vert Weights";
+
+ /* api callbacks */
+ ot->poll = vertex_group_poll;
+ ot->exec = vertex_weight_normalize_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int vertex_weight_copy(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = ED_object_context(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ eVGroupSelect subset_type = ts->vgroupsubset;
+
+ vgroup_copy_active_to_sel(ob, subset_type);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_weight_copy(wmOperatorType *ot)
+{
+
+ ot->name = "Copy Active";
+ ot->idname = "OBJECT_OT_vertex_weight_copy";
+ ot->description = "Copy weights from Active to selected";
+
+ /* api callbacks */
+ ot->poll = vertex_group_poll;
+ ot->exec = vertex_weight_copy;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 2fa901a2f28..54173893847 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -830,280 +830,19 @@ static MDeformVert *ED_mesh_active_dvert_get_only(Object *ob)
}
}
-/* TODO, cache flip data to speedup calls within a loop. */
-static void mesh_defvert_mirror_update_internal(Object *ob,
- MDeformVert *dvert_dst, MDeformVert *dvert_src,
- const int def_nr)
-{
- if (def_nr == -1) {
- /* all vgroups, add groups where neded */
- int flip_map_len;
- int *flip_map = defgroup_flip_map(ob, &flip_map_len, true);
- defvert_sync_mapped(dvert_dst, dvert_src, flip_map, flip_map_len, true);
- MEM_freeN(flip_map);
- }
- else {
- /* single vgroup */
- MDeformWeight *dw = defvert_verify_index(dvert_dst, defgroup_flip_index(ob, def_nr, 1));
- if (dw) {
- dw->weight = defvert_find_weight(dvert_src, def_nr);
- }
- }
-}
-
-static void ED_mesh_defvert_mirror_update_em(Object *ob, BMVert *eve, int def_nr, int vidx,
- const int cd_dvert_offset)
-{
- Mesh *me = ob->data;
- BMEditMesh *em = me->edit_btmesh;
- BMVert *eve_mirr;
-
- eve_mirr = editbmesh_get_x_mirror_vert(ob, em, eve, eve->co, vidx);
-
- if (eve_mirr && eve_mirr != eve) {
- MDeformVert *dvert_src = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
- MDeformVert *dvert_dst = BM_ELEM_CD_GET_VOID_P(eve_mirr, cd_dvert_offset);
- mesh_defvert_mirror_update_internal(ob, dvert_dst, dvert_src, def_nr);
- }
-}
-
-static void ED_mesh_defvert_mirror_update_ob(Object *ob, int def_nr, int vidx)
-{
- int vidx_mirr;
- Mesh *me = ob->data;
- if (vidx == -1)
- return;
-
- vidx_mirr = mesh_get_x_mirror_vert(ob, vidx);
-
- if ((vidx_mirr) >= 0 && (vidx_mirr != vidx)) {
- MDeformVert *dvert_src = &me->dvert[vidx];
- MDeformVert *dvert_dst = &me->dvert[vidx_mirr];
- mesh_defvert_mirror_update_internal(ob, dvert_dst, dvert_src, def_nr);
- }
-}
-
-static void vgroup_adjust_active(Object *ob, int def_nr)
-{
- Mesh *me = ob->data;
- BMEditMesh *em = me->edit_btmesh;
- MDeformVert *dvert_act;
-
- if (me->editflag & ME_EDIT_MIRROR_X) {
- if (em) {
- BMVert *eve_act;
- dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act);
- if (dvert_act) {
- const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
- ED_mesh_defvert_mirror_update_em(ob, eve_act, def_nr, -1, cd_dvert_offset);
- }
- }
- else {
- int v_act;
- dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
- if (dvert_act) {
- ED_mesh_defvert_mirror_update_ob(ob, def_nr, v_act);
- }
- }
- }
-}
-
-static void vgroup_remove_weight(Object *ob, const int def_nr)
-{
- MDeformVert *dvert_act;
- MDeformWeight *dw;
-
- dvert_act = ED_mesh_active_dvert_get_only(ob);
-
- dw = defvert_find_index(dvert_act, def_nr);
- defvert_remove_group(dvert_act, dw);
-
-}
-
-static void vgroup_copy_active_to_sel(Object *ob)
-{
- Mesh *me = ob->data;
- BMEditMesh *em = me->edit_btmesh;
- MDeformVert *dvert_act;
- int i;
-
- if (em) {
- BMIter iter;
- BMVert *eve, *eve_act;
- const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
-
- dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act);
- if (dvert_act == NULL) {
- return;
- }
-
- BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
- if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && eve != eve_act) {
- MDeformVert *dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
- defvert_copy(dv, dvert_act);
- if (me->editflag & ME_EDIT_MIRROR_X) {
- ED_mesh_defvert_mirror_update_em(ob, eve, -1, i, cd_dvert_offset);
- }
- }
- }
- }
- else {
- MDeformVert *dv;
- int v_act;
-
- dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
- if (dvert_act == NULL) {
- return;
- }
-
- dv = me->dvert;
- for (i = 0; i < me->totvert; i++, dv++) {
- if ((me->mvert[i].flag & SELECT) && dv != dvert_act) {
- defvert_copy(dv, dvert_act);
- if (me->editflag & ME_EDIT_MIRROR_X) {
- ED_mesh_defvert_mirror_update_ob(ob, -1, i);
- }
- }
- }
- }
-}
-
-static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr)
-{
- MDeformVert *dvert_act;
-
- Mesh *me = ob->data;
- BMEditMesh *em = me->edit_btmesh;
- float weight_act;
- int i;
-
- if (em) {
- const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
- BMIter iter;
- BMVert *eve, *eve_act;
-
- dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act);
- if (dvert_act == NULL) {
- return;
- }
- weight_act = defvert_find_weight(dvert_act, def_nr);
-
- BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
- if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && (eve != eve_act)) {
- MDeformVert *dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
- MDeformWeight *dw = defvert_find_index(dv, def_nr);
- if (dw) {
- dw->weight = weight_act;
-
- if (me->editflag & ME_EDIT_MIRROR_X) {
- ED_mesh_defvert_mirror_update_em(ob, eve, -1, i, cd_dvert_offset);
- }
- }
- }
- }
-
- if (me->editflag & ME_EDIT_MIRROR_X) {
- ED_mesh_defvert_mirror_update_em(ob, eve_act, -1, -1, cd_dvert_offset);
- }
- }
- else {
- MDeformVert *dv;
- int v_act;
-
- dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
- if (dvert_act == NULL) {
- return;
- }
- weight_act = defvert_find_weight(dvert_act, def_nr);
-
- dv = me->dvert;
- for (i = 0; i < me->totvert; i++, dv++) {
- if ((me->mvert[i].flag & SELECT) && (dv != dvert_act)) {
- MDeformWeight *dw = defvert_find_index(dv, def_nr);
- if (dw) {
- dw->weight = weight_act;
- if (me->editflag & ME_EDIT_MIRROR_X) {
- ED_mesh_defvert_mirror_update_ob(ob, -1, i);
- }
- }
- }
- }
-
- if (me->editflag & ME_EDIT_MIRROR_X) {
- ED_mesh_defvert_mirror_update_ob(ob, -1, v_act);
- }
- }
-}
-
-static void vgroup_normalize_active(Object *ob)
-{
- Mesh *me = ob->data;
- BMEditMesh *em = me->edit_btmesh;
- BMVert *eve_act;
- int v_act;
- MDeformVert *dvert_act;
-
- if (em) {
- dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act);
- }
- else {
- dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
- }
-
- if (dvert_act == NULL) {
- return;
- }
-
- defvert_normalize(dvert_act);
-
- if (me->editflag & ME_EDIT_MIRROR_X) {
- if (em) {
- const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
- ED_mesh_defvert_mirror_update_em(ob, eve_act, -1, -1, cd_dvert_offset);
- }
- else {
- int v_act = BKE_mesh_mselect_active_get(me, ME_VSEL);
- ED_mesh_defvert_mirror_update_ob(ob, -1, v_act);
- }
- }
-}
-
static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event)
{
- Scene *scene = CTX_data_scene(C);
- Object *ob = scene->basact->object;
-
- /* XXX TODO Use operators? */
- 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_ACTIVE) {
- ob->actdef = event - B_VGRP_PNL_ACTIVE + 1;
- }
- else if (event >= B_VGRP_PNL_COPY_SINGLE) {
- vgroup_copy_active_to_sel_single(ob, event - B_VGRP_PNL_COPY_SINGLE);
- }
- else if (event >= B_VGRP_PNL_DELETE_SINGLE) {
- vgroup_remove_weight(ob, event - B_VGRP_PNL_DELETE_SINGLE);
- }
- else if (event >= B_VGRP_PNL_EDIT_SINGLE) {
- vgroup_adjust_active(ob, event - B_VGRP_PNL_EDIT_SINGLE);
+ if (event < B_VGRP_PNL_EDIT_SINGLE) {
+ /* not for me */
+ return;
}
else {
- BLI_assert(0);
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = scene->basact->object;
+ ED_vgroup_vert_active_mirror(ob, event - B_VGRP_PNL_EDIT_SINGLE);
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
}
-
-#if 0 /* TODO */
- if (((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_X)
- ED_vgroup_mirror(ob, 1, 1, 0);
-#endif
-
- /* default for now */
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
}
static int view3d_panel_vgroup_poll(const bContext *C, PanelType *UNUSED(pt))
@@ -1132,22 +871,39 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
dv = ED_mesh_active_dvert_get_only(ob);
if (dv && dv->totweight) {
- uiLayout *col;
+ ToolSettings *ts = scene->toolsettings;
+
+ wmOperatorType *ot_weight_set_active = WM_operatortype_find("OBJECT_OT_vertex_weight_set_active", true);
+ wmOperatorType *ot_weight_paste = WM_operatortype_find("OBJECT_OT_vertex_weight_paste", true);
+ wmOperatorType *ot_weight_delete = WM_operatortype_find("OBJECT_OT_vertex_weight_delete", true);
+
+ wmOperatorType *ot;
+ PointerRNA op_ptr, tools_ptr;
+ PointerRNA *but_ptr;
+
+ uiLayout *col, *bcol;
uiLayout *row;
uiLayout *box;
uiBut *but;
bDeformGroup *dg;
unsigned int i;
int subset_count, vgroup_tot;
- bool *vgroup_validmap;
- eVGroupSelect subset_type = WT_VGROUP_ALL;
+ const bool *vgroup_validmap;
+ eVGroupSelect subset_type = ts->vgroupsubset;
int yco = 0;
uiBlockSetHandleFunc(block, do_view3d_vgroup_buttons, NULL);
- box = uiLayoutBox(pa->layout);
- col = uiLayoutColumn(box, true);
+ bcol = uiLayoutColumn(pa->layout, true);
+ row = uiLayoutRow(bcol, true); /* The filter button row */
+ RNA_pointer_create(NULL, &RNA_ToolSettings, ts, &tools_ptr);
+ uiItemR(row, &tools_ptr, "vertex_group_subset", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+
+ col = uiLayoutColumn(bcol, true);
+ box = uiLayoutBox(col); /* The list box */
+
+ col = uiLayoutColumn(box, true);
vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
for (i = 0, dg = ob->defbase.first; dg; i++, dg = dg->next) {
if (vgroup_validmap[i]) {
@@ -1155,56 +911,68 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
if (dw) {
int x, xco = 0;
row = uiLayoutRow(col, true);
- (void)row;
uiBlockSetEmboss(block, UI_EMBOSSN);
- but = uiDefBut(block, BUT, B_VGRP_PNL_ACTIVE + i, dg->name,
- xco, yco, (x = UI_UNIT_X * 5), UI_UNIT_Y,
- NULL, 0.0, 1.0, 1, 3, "");
- uiButSetFlag(but, UI_TEXT_LEFT);
+ /* The Weight Group Name */
+
+ ot = ot_weight_set_active;
+ but = uiDefButO_ptr(block, BUT, ot, WM_OP_EXEC_DEFAULT, dg->name,
+ xco, yco, (x = UI_UNIT_X * 5), UI_UNIT_Y, "");
+ but_ptr = uiButGetOperatorPtrRNA(but);
+ RNA_int_set(but_ptr, "weight_group", i);
+ uiButSetFlag(but, UI_TEXT_LEFT);
if (ob->actdef != i + 1) {
uiButSetFlag(but, UI_BUT_INACTIVE);
}
xco += x;
-
- //uiBlockSetEmboss(block, UI_EMBOSS);
-
+
+ /* The weight group value */
+ /* To be reworked still */
but = uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + i, "",
xco, yco, (x = UI_UNIT_X * 4), UI_UNIT_Y,
&dw->weight, 0.0, 1.0, 1, 3, "");
uiButSetFlag(but, UI_TEXT_LEFT);
xco += x;
- uiDefIconBut(block, BUT, B_VGRP_PNL_COPY_SINGLE + i, ICON_PASTEDOWN,
- xco, yco, (x = UI_UNIT_X), UI_UNIT_Y,
- NULL, 0, 0, 0, 0, TIP_("Copy this group's weight to other selected verts"));
- xco += x;
+ /* The weight group paste function */
- uiDefIconBut(block, BUT, B_VGRP_PNL_DELETE_SINGLE + i, ICON_X,
- xco, yco, (x = UI_UNIT_X), UI_UNIT_Y,
- NULL, 0, 0, 0, 0, TIP_("Delete this weight from the vertex"));
- xco += x;
+ ot = ot_weight_paste;
+ WM_operator_properties_create_ptr(&op_ptr, ot);
+ RNA_int_set(&op_ptr, "weight_group", i);
+ uiItemFullO_ptr(row, ot, "", ICON_PASTEDOWN, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0);
+
+ /* The weight entry delete function */
+
+ ot = ot_weight_delete;
+ WM_operator_properties_create_ptr(&op_ptr, ot);
+ RNA_int_set(&op_ptr, "weight_group", i);
+ uiItemFullO_ptr(row, ot, "", ICON_X, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0);
yco -= UI_UNIT_Y;
- (void)xco;
+
}
}
}
- MEM_freeN(vgroup_validmap);
+ MEM_freeN((void *)vgroup_validmap);
+
+ uiBlockSetEmboss(block, UI_EMBOSS);
yco -= 2;
- uiBlockSetEmboss(block, UI_EMBOSS);
col = uiLayoutColumn(pa->layout, true);
row = uiLayoutRow(col, true);
- uiDefBut(block, BUT, B_VGRP_PNL_NORMALIZE, IFACE_("Normalize"),
- 0, yco, UI_UNIT_X * 5, UI_UNIT_Y,
- NULL, 0, 0, 0, 0, TIP_("Normalize active vertex weights"));
- uiDefBut(block, BUT, B_VGRP_PNL_COPY, IFACE_("Copy"),
- UI_UNIT_X * 5, yco, UI_UNIT_X * 5, UI_UNIT_Y,
- NULL, 0, 0, 0, 0, TIP_("Copy active vertex to other selected verts"));
+ ot = WM_operatortype_find("OBJECT_OT_vertex_weight_normalize_active", 1);
+ but = uiDefButO_ptr(block, BUT, ot, WM_OP_EXEC_DEFAULT, "Normalize",
+ 0, yco,UI_UNIT_X * 5, UI_UNIT_Y,
+ TIP_("Normalize active vertex weights"));
+
+ ot = WM_operatortype_find("OBJECT_OT_vertex_weight_copy", 1);
+ but = uiDefButO_ptr(block, BUT, ot, WM_OP_EXEC_DEFAULT, "Copy",
+ UI_UNIT_X * 5, yco,UI_UNIT_X * 5, UI_UNIT_Y,
+ TIP_("Copy active vertex to other selected verts"));
+
}
}
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index e08ecf6dff8..5e877ed697b 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -1076,11 +1076,11 @@ typedef struct ToolSettings {
short proportional, prop_mode;
char proportional_objects; /* proportional edit, object mode */
char proportional_mask; /* proportional edit, object mode */
- char pad4[1];
char auto_normalize; /*auto normalizing mode in wpaint*/
char multipaint; /* paint multiple bones in wpaint */
char weightuser;
+ char vgroupsubset; /* subset selection filter in wpaint */
/* UV painting */
int use_uv_sculpt;
@@ -1511,6 +1511,24 @@ enum {
OB_DRAW_GROUPUSER_ALL = 2
};
+/* toolsettings->vgroupsubset */
+/* object_vgroup.c */
+typedef enum eVGroupSelect {
+ WT_VGROUP_ALL = 0,
+ WT_VGROUP_ACTIVE = 1,
+ WT_VGROUP_BONE_SELECT = 2,
+ WT_VGROUP_BONE_DEFORM = 3,
+ WT_VGROUP_BONE_DEFORM_OFF = 4
+} eVGroupSelect;
+
+#define WT_VGROUP_MASK_ALL \
+ ((1 << WT_VGROUP_ACTIVE) | \
+ (1 << WT_VGROUP_BONE_SELECT) | \
+ (1 << WT_VGROUP_BONE_DEFORM) | \
+ (1 << WT_VGROUP_BONE_DEFORM_OFF) | \
+ (1 << WT_VGROUP_ALL))
+
+
/* sce->flag */
#define SCE_DS_SELECTED (1<<0)
#define SCE_DS_COLLAPSED (1<<1)
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 0c3f4aa073b..d46b1a28439 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1640,6 +1640,14 @@ static void rna_def_tool_settings(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem vertex_group_select_items[] = {
+ {WT_VGROUP_ALL, "ALL", 0, "All", "All Vertex Groups"},
+ {WT_VGROUP_BONE_DEFORM, "BONE_DEFORM", 0, "Deform", "Vertex Groups assigned to Deform Bones"},
+ {WT_VGROUP_BONE_DEFORM_OFF, "OTHER_DEFORM", 0, "Other", "Vertex Groups assigned to non Deform Bones"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+
srna = RNA_def_struct(brna, "ToolSettings", NULL);
RNA_def_struct_path_func(srna, "rna_ToolSettings_path");
RNA_def_struct_ui_text(srna, "Tool Settings", "");
@@ -1668,10 +1676,14 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Mask Non-Group Vertices", "Display unweighted vertices (multi-paint overrides)");
RNA_def_property_update(prop, 0, "rna_Scene_update_active_object_data");
+ prop = RNA_def_property(srna, "vertex_group_subset", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "vgroupsubset");
+ RNA_def_property_enum_items(prop, vertex_group_select_items);
+ RNA_def_property_ui_text(prop, "Subset", "Filter Vertex groups for Display");
+ RNA_def_property_update(prop, 0, "rna_Scene_update_active_object_data");
prop = RNA_def_property(srna, "vertex_paint", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "vpaint");
- RNA_def_property_ui_text(prop, "Vertex Paint", "");
+ RNA_def_property_pointer_sdna(prop, NULL, "vpaint"); RNA_def_property_ui_text(prop, "Vertex Paint", "");
prop = RNA_def_property(srna, "weight_paint", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "wpaint");