[Bf-blender-cvs] [c402057] master: Weight Paint: replace Blend with Smooth tool

Campbell Barton noreply at git.blender.org
Thu Jun 25 08:24:49 CEST 2015


Commit: c40205738b242f7501fea245f69cf1d7187e9d2c
Author: Campbell Barton
Date:   Thu Jun 25 16:10:18 2015 +1000
Branches: master
https://developer.blender.org/rBc40205738b242f7501fea245f69cf1d7187e9d2c

Weight Paint: replace Blend with Smooth tool

Improved behavior

- can smooth # iterations
- option to expand/contract weights
- optionally mix with all/selected/unselected

===================================================================

M	release/scripts/startup/bl_ui/space_view3d.py
M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/editors/object/object_intern.h
M	source/blender/editors/object/object_ops.c
M	source/blender/editors/object/object_vgroup.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 2933e3d..b608ff9 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -1667,7 +1667,7 @@ class VIEW3D_MT_paint_weight(Menu):
         layout.operator("object.vertex_group_clean", text="Clean")
         layout.operator("object.vertex_group_quantize", text="Quantize")
         layout.operator("object.vertex_group_levels", text="Levels")
-        layout.operator("object.vertex_group_blend", text="Blend")
+        layout.operator("object.vertex_group_smooth", text="Smooth")
         props = layout.operator("object.data_transfer", text="Transfer Weights")
         props.use_reverse_transfer = True
         props.data_type = 'VGROUP_WEIGHTS'
@@ -2293,7 +2293,7 @@ class VIEW3D_MT_edit_mesh_vertices(Menu):
 
         layout.operator("mesh.blend_from_shape")
 
-        layout.operator("object.vertex_group_blend")
+        layout.operator("object.vertex_group_smooth")
         layout.operator("mesh.shape_propagate_to_all")
 
         layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 14e8bd0..e381800 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -367,7 +367,7 @@ class VIEW3D_PT_tools_meshweight(View3DPanel, Panel):
         col.operator("object.vertex_group_clean", text="Clean")
         col.operator("object.vertex_group_quantize", text="Quantize")
         col.operator("object.vertex_group_levels", text="Levels")
-        col.operator("object.vertex_group_blend", text="Blend")
+        col.operator("object.vertex_group_smooth", text="Smooth")
         col.operator("object.vertex_group_limit_total", text="Limit Total")
         col.operator("object.vertex_group_fix", text="Fix Deforms")
 
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 27549ea..6344e04 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -230,7 +230,7 @@ void OBJECT_OT_vertex_group_levels(struct wmOperatorType *ot);
 void OBJECT_OT_vertex_group_lock(struct wmOperatorType *ot);
 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_smooth(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);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index b2562b7..22cac86 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -186,7 +186,7 @@ void ED_operatortypes_object(void)
 	WM_operatortype_append(OBJECT_OT_vertex_group_fix);
 	WM_operatortype_append(OBJECT_OT_vertex_group_invert);
 	WM_operatortype_append(OBJECT_OT_vertex_group_levels);
-	WM_operatortype_append(OBJECT_OT_vertex_group_blend);
+	WM_operatortype_append(OBJECT_OT_vertex_group_smooth);
 	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);
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index d586e35..f2b2923 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -50,6 +50,7 @@
 #include "BLI_blenlib.h"
 #include "BLI_utildefines.h"
 #include "BLI_linklist_stack.h"
+#include "BLI_stackdefines.h"
 
 
 #include "BKE_context.h"
@@ -1673,9 +1674,17 @@ static void vgroup_invert_subset(Object *ob,
 	}
 }
 
-static void vgroup_blend_subset(Object *ob, const bool *vgroup_validmap, const int vgroup_tot,
-                                const int subset_count,
-                                const float fac)
+enum {
+	WEIGHT_SMOOTH_ALL = -1,
+	WEIGHT_SMOOTH_DESELECT = false,
+	WEIGHT_SMOOTH_SELECT = true,
+};
+
+static void vgroup_smooth_subset(
+        Object *ob, const bool *vgroup_validmap, const int vgroup_tot,
+        const int subset_count,
+        const float fac, const int repeat,
+        const float fac_expand, const int source)
 {
 	const float ifac = 1.0f - fac;
 	MDeformVert **dvert_array = NULL;
@@ -1684,6 +1693,10 @@ static void vgroup_blend_subset(Object *ob, const bool *vgroup_validmap, const i
 	float *vgroup_subset_weights = BLI_array_alloca(vgroup_subset_weights, subset_count);
 	const bool use_mirror = (ob->type == OB_MESH) ? (((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_X) != 0 : false;
 
+	const int    expand_sign = signum_i(fac_expand);
+	const float  expand = fabsf(fac_expand);
+	const float iexpand = 1.0f - expand;
+
 	BMEditMesh *em = BKE_editmesh_from_object(ob);
 	BMesh *bm = em ? em->bm : NULL;
 	Mesh  *me = em ? NULL   : ob->data;
@@ -1691,7 +1704,15 @@ static void vgroup_blend_subset(Object *ob, const bool *vgroup_validmap, const i
 	MeshElemMap *emap;
 	int *emap_mem;
 
-	BLI_LINKSTACK_DECLARE(dv_stack, MDeformVert *);
+	float *weight_accum_prev;
+	float *weight_accum_curr;
+
+	unsigned int subset_index;
+
+	/* vertex indices that will be smoothed, (only to avoid iterating over verts that do nothing) */
+	unsigned int *verts_used;
+	STACK_DECLARE(verts_used);
+
 
 	BKE_object_defgroup_subset_to_index_array(vgroup_validmap, vgroup_tot, vgroup_subset_map);
 	ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, false);
@@ -1699,89 +1720,158 @@ static void vgroup_blend_subset(Object *ob, const bool *vgroup_validmap, const i
 
 	if (bm) {
 		BM_mesh_elem_table_ensure(bm, BM_VERT);
+		BM_mesh_elem_index_ensure(bm, BM_VERT);
 
 		emap = NULL;
 		emap_mem = NULL;
 	}
 	else {
-		BKE_mesh_vert_edge_map_create(&emap, &emap_mem,
-		                              me->medge, me->totvert, me->totedge);
+		BKE_mesh_vert_edge_map_create(&emap, &emap_mem, me->medge, me->totvert, me->totedge);
 	}
 
-	BLI_LINKSTACK_INIT(dv_stack);
+	weight_accum_prev = MEM_mallocN(sizeof(*weight_accum_prev) * dvert_tot, __func__);
+	weight_accum_curr = MEM_mallocN(sizeof(*weight_accum_curr) * dvert_tot, __func__);
+
+	verts_used = MEM_mallocN(sizeof(*verts_used) * dvert_tot, __func__);
+	STACK_INIT(verts_used, dvert_tot);
 
-	for (i = 0; i < dvert_tot; i++) {
-		MDeformVert *dv;
-		int dv_stack_tot = 0;
-		int j;
-		/* in case its not selected */
 
-		if (bm) {
+	/* initialize used verts */
+	if (bm) {
+		for (i = 0; i < dvert_tot; i++) {
 			BMVert *v = BM_vert_at_index(bm, i);
 			if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
 				BMIter eiter;
 				BMEdge *e;
 				BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
 					BMVert *v_other = BM_edge_other_vert(e, v);
-					const int i_other = BM_elem_index_get(v_other);
-
-					if (BM_elem_flag_test(v_other, BM_ELEM_SELECT) == 0) {
-						dv = dvert_array[i_other];
-						BLI_LINKSTACK_PUSH(dv_stack, dv);
-						dv_stack_tot++;
+					if ((source == WEIGHT_SMOOTH_ALL) ||
+					    (source == (BM_elem_flag_test(v_other, BM_ELEM_SELECT) != 0)))
+					{
+						STACK_PUSH(verts_used, i);
+						break;
 					}
 				}
 			}
 		}
-		else {
+	}
+	else {
+		for (i = 0; i < dvert_tot; i++) {
 			MVert *v = &me->mvert[i];
 			if (v->flag & SELECT) {
+				int j;
 				for (j = 0; j < emap[i].count; j++) {
 					MEdge *e = &me->medge[emap[i].indices[j]];
 					const int i_other = (e->v1 == i ? e->v2 : e->v1);
 					MVert *v_other = &me->mvert[i_other];
-
-					if ((v_other->flag & SELECT) == 0) {
-						dv = dvert_array[i_other];
-						BLI_LINKSTACK_PUSH(dv_stack, dv);
-						dv_stack_tot++;
+					if ((source == WEIGHT_SMOOTH_ALL) ||
+					    (source == ((v_other->flag & SELECT) != 0)))
+					{
+						STACK_PUSH(verts_used, i);
+						break;
 					}
 				}
 			}
 		}
+	}
 
-		if (dv_stack_tot) {
-			const float dv_mul = 1.0f / (float)dv_stack_tot;
-
-			/* vgroup_subset_weights is zero'd at this point */
-			while ((dv = BLI_LINKSTACK_POP(dv_stack))) {
-				for (j = 0; j < subset_count; j++) {
-					vgroup_subset_weights[j] += dv_mul * defvert_find_weight(dv, vgroup_subset_map[j]);
-				}
-			}
-
-			dv = dvert_array[i];
-			for (j = 0; j < subset_count; j++) {
-				MDeformWeight *dw;
-				if (vgroup_subset_weights[j] > 0.0f) {
-					dw = defvert_verify_index(dv, vgroup_subset_map[j]);
+	for (subset_index = 0; subset_index < subset_count; subset_index++) {
+		const int def_nr = vgroup_subset_map[subset_index];
+		int iter;
+
+		ED_vgroup_parray_to_weight_array((const MDeformVert **)dvert_array, dvert_tot, weight_accum_prev, def_nr);
+		memcpy(weight_accum_curr, weight_accum_prev, sizeof(*weight_accum_curr) * dvert_tot);
+
+		for (iter = 0; iter < repeat; iter++) {
+			unsigned *vi_step, *vi_end = verts_used + STACK_SIZE(verts_used);
+
+			/* avoid looping over all verts */
+			// for (i = 0; i < dvert_tot; i++)
+			for (vi_step = verts_used; vi_step != vi_end; vi_step++) {
+				const unsigned int i  = *vi_step;
+				float weight_tot = 0.0f;
+				float weight = 0.0f;
+
+#define WEIGHT_ACCUMULATE \
+				{ \
+					float weight_other = weight_accum_prev[i_other]; \
+					float tot_factor = 1.0f; \
+					if (expand_sign == 1) {  /* expand */ \
+						if (weight_other < weight_accum_prev[i]) { \
+							weight_other = (weight_accum_prev[i_other] * iexpand) + (weight_other * expand); \
+							tot_factor = iexpand; \
+						} \
+					} \
+					else if (expand_sign == -1) {  /* contract */ \
+						if (weight_other > weight_accum_prev[i]) { \
+							weight_other = (weight_accum_prev[i_other] * iexpand) + (weight_other * expand); \
+							tot_factor = iexpand; \
+						} \
+					} \
+					weight     += tot_factor * weight_other; \
+					weight_tot += tot_factor; \
+				} ((void)0)
+
+
+				if (bm) {
+					BMVert *v = BM_vert_at_index(bm, i);
+					BMIter eiter;
+					BMEdge *e;
+
+					/* checked already */
+					BLI_assert(BM_elem_flag_test(v, BM_ELEM_SELECT));
+
+					B

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list