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
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-11-17 07:54:42 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-11-17 07:58:23 +0400
commitc9209de573ad680dbad6b560c05a90b02b780267 (patch)
tree5bc56093a29daab0b354919bdf2e28f8980ce813 /source
parentf9785bdeb4ebe3ebc9527ba3eb45793c660bb3ec (diff)
vertex weights: add weight quantize tool.
Diffstat (limited to 'source')
-rw-r--r--source/blender/editors/object/object_intern.h1
-rw-r--r--source/blender/editors/object/object_ops.c1
-rw-r--r--source/blender/editors/object/object_vgroup.c76
3 files changed, 78 insertions, 0 deletions
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 4ff3bc9ac06..313ac1d29f0 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -222,6 +222,7 @@ void OBJECT_OT_vertex_group_fix(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_invert(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_blend(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_clean(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_quantize(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_limit_total(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_mirror(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_set_active(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 333e5ff3006..f5c2bcbef70 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -191,6 +191,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_vertex_group_levels);
WM_operatortype_append(OBJECT_OT_vertex_group_blend);
WM_operatortype_append(OBJECT_OT_vertex_group_clean);
+ WM_operatortype_append(OBJECT_OT_vertex_group_quantize);
WM_operatortype_append(OBJECT_OT_vertex_group_limit_total);
WM_operatortype_append(OBJECT_OT_vertex_group_mirror);
WM_operatortype_append(OBJECT_OT_vertex_group_set_active);
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index a6f7c4d5383..16ee400fa67 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -2398,6 +2398,44 @@ static void vgroup_clean_subset(Object *ob, const bool *vgroup_validmap, const i
}
}
+static void vgroup_quantize_subset(Object *ob, const bool *vgroup_validmap, const int vgroup_tot, const int UNUSED(subset_count),
+ const int steps)
+{
+ MDeformVert **dvert_array = NULL;
+ int dvert_tot = 0;
+ const bool use_vert_sel = vertex_group_use_vert_sel(ob);
+ const bool use_mirror = (ob->type == OB_MESH) ? (((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_X) != 0 : false;
+ ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, use_vert_sel);
+
+ if (dvert_array) {
+ const float steps_fl = steps;
+ MDeformVert *dv;
+ int i;
+
+ if (use_mirror && use_vert_sel) {
+ ED_vgroup_parray_mirror_assign(ob, dvert_array, dvert_tot);
+ }
+
+ for (i = 0; i < dvert_tot; i++) {
+ MDeformWeight *dw;
+ int j;
+
+ /* in case its not selected */
+ if (!(dv = dvert_array[i])) {
+ continue;
+ }
+
+ for (j = 0, dw = dv->dw; j < dv->totweight; j++, dw++) {
+ if ((dw->def_nr < vgroup_tot) && vgroup_validmap[dw->def_nr]) {
+ dw->weight = floorf((dw->weight * steps_fl) + 0.5f) / steps_fl;
+ CLAMP(dw->weight, 0.0f, 1.0f);
+ }
+ }
+ }
+
+ MEM_freeN(dvert_array);
+ }
+}
static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr,
const char sel, const char sel_mirr,
@@ -3754,6 +3792,44 @@ void OBJECT_OT_vertex_group_clean(wmOperatorType *ot)
"Keep verts assigned to at least one group when cleaning");
}
+static int vertex_group_quantize_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = ED_object_context(C);
+
+ const int steps = RNA_int_get(op->ptr, "steps");
+ eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode");
+
+ int subset_count, vgroup_tot;
+
+ const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+ vgroup_quantize_subset(ob, vgroup_validmap, vgroup_tot, subset_count, steps);
+ MEM_freeN((void *)vgroup_validmap);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_vertex_group_quantize(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Quantize Vertex Weights";
+ ot->idname = "OBJECT_OT_vertex_group_quantize";
+ ot->description = "Set weights to a fixed number of steps";
+
+ /* api callbacks */
+ ot->poll = vertex_group_poll;
+ ot->exec = vertex_group_quantize_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ vgroup_operator_subset_select_props(ot, true);
+ RNA_def_int(ot->srna, "steps", 4, 1, 1000, "Steps", "Number of steps between 0 and 1", 1, 100);
+}
+
static int vertex_group_limit_total_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);