[Bf-blender-cvs] [51582bf565b] sculpt-mode-features: Sculpt mode: Grow and shrink mask filters
Pablo Dobarro
noreply at git.blender.org
Fri Apr 12 00:35:51 CEST 2019
Commit: 51582bf565b874fa5ff434c74fa4fb422462dcb6
Author: Pablo Dobarro
Date: Fri Apr 12 00:35:38 2019 +0200
Branches: sculpt-mode-features
https://developer.blender.org/rB51582bf565b874fa5ff434c74fa4fb422462dcb6
Sculpt mode: Grow and shrink mask filters
===================================================================
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/editors/sculpt_paint/sculpt_intern.h
===================================================================
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 882cd0fb090..9934b835350 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -1659,6 +1659,54 @@ static float neighbor_average_mask(SculptSession *ss, unsigned vert)
return vmask[vert];
}
+static float neighbor_min_mask(SculptSession *ss, const int vert, float *prev_mask)
+{
+ const MeshElemMap *vert_map = &ss->pmap[vert];
+ const float *vmask = prev_mask;
+
+ int i = 0;
+ float min = 1.0f;
+ for (i = 0; i < vert_map->count; i++) {
+ const MPoly *p = &ss->mpoly[vert_map->indices[i]];
+ unsigned f_adj_v[2];
+
+ if (poly_get_adj_loops_from_vert(p, ss->mloop, vert, f_adj_v) != -1) {
+ int j;
+ for (j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) {
+ float vmask_f = vmask[f_adj_v[j]];
+ if (vmask_f < min) {
+ min = vmask_f;
+ }
+ }
+ }
+ }
+ return min;
+}
+
+static float neighbor_max_mask(SculptSession *ss, const int vert, float *prev_mask)
+{
+ const MeshElemMap *vert_map = &ss->pmap[vert];
+ const float *vmask = prev_mask;
+
+ int i = 0;
+ float max = 0.0f;
+ for (i = 0; i < vert_map->count; i++) {
+ const MPoly *p = &ss->mpoly[vert_map->indices[i]];
+ unsigned f_adj_v[2];
+
+ if (poly_get_adj_loops_from_vert(p, ss->mloop, vert, f_adj_v) != -1) {
+ int j;
+ for (j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) {
+ float vmask_f = vmask[f_adj_v[j]];
+ if (vmask_f > max) {
+ max = vmask_f;
+ }
+ }
+ }
+ }
+ return max;
+}
+
/* Same logic as neighbor_average(), but for bmesh rather than mesh */
static void bmesh_neighbor_average(float avg[3], BMVert *v)
{
@@ -7210,12 +7258,16 @@ void SCULPT_OT_mesh_filter(struct wmOperatorType *ot)
typedef enum eSculptMaskFilterTypes {
MASK_FILTER_BLUR = 0,
- MASK_FILTER_SHARPEN =1,
+ MASK_FILTER_SHARPEN = 1,
+ MASK_FILTER_GROW = 2,
+ MASK_FILTER_SHRINK = 3,
} eSculptMaskFilterTypes;
EnumPropertyItem prop_mask_filter_types[] = {
{MASK_FILTER_BLUR, "BLUR", 0, "Blur Mask", "Blur mask"},
{MASK_FILTER_SHARPEN, "SHARPEN", 0, "Sharpen Mask", "Sharpen mask"},
+ {MASK_FILTER_GROW, "GROW", 0, "Grow Mask", "Grow mask"},
+ {MASK_FILTER_SHRINK, "SHRINK", 0, "Shrink Mask", "Shrink mask"},
{0, NULL, 0, NULL, NULL},
};
@@ -7262,6 +7314,20 @@ static void mask_filter_task_cb(
*vd.mask += val/2;
CLAMP(*vd.mask, 0.0f, 1.0f);
break;
+ case MASK_FILTER_GROW:
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES){
+ val = neighbor_max_mask(ss, vd.vert_indices[vd.i], data->prev_mask);
+ *vd.mask = val;
+ CLAMP(*vd.mask, 0.0f, 1.0f);
+ }
+ break;
+ case MASK_FILTER_SHRINK:
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES){
+ val = neighbor_min_mask(ss, vd.vert_indices[vd.i], data->prev_mask);
+ *vd.mask = val;
+ CLAMP(*vd.mask, 0.0f, 1.0f);
+ }
+ break;
}
if (vd.mvert)
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
@@ -7277,6 +7343,7 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
ARegion *ar = CTX_wm_region(C);
struct Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
Depsgraph *depsgraph = CTX_data_depsgraph(C);
PBVH *pbvh = ob->sculpt->pbvh;
PBVHNode **nodes;
@@ -7298,8 +7365,14 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
sculpt_undo_push_begin("Mask blur fill");
+ float *prev_mask;
+ if (ELEM(mode, MASK_FILTER_GROW, MASK_FILTER_SHRINK)) {
+ prev_mask = MEM_dupallocN(ss->vmask);
+ }
+
SculptThreadedTaskData data = {
.sd = sd, .ob = ob, .nodes = nodes, .smooth_value = 0.5f, .filter_type = mode,
+ .prev_mask = prev_mask,
};
ParallelRangeSettings settings;
@@ -7316,6 +7389,9 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
if (nodes)
MEM_freeN(nodes);
+ if (ELEM(mode, MASK_FILTER_GROW, MASK_FILTER_SHRINK))
+ MEM_freeN(prev_mask);
+
ED_region_tag_redraw(ar);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 0647074fd0d..7a50efc4fd4 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -209,6 +209,8 @@ typedef struct SculptThreadedTaskData {
float filter_strength;
int filter_type;
+ float *prev_mask;
+
float min_len;
bool use_automasking_brush_location;
More information about the Bf-blender-cvs
mailing list