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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to