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:
authorNicholas Bishop <nicholasbishop@gmail.com>2012-05-11 00:35:32 +0400
committerNicholas Bishop <nicholasbishop@gmail.com>2012-05-11 00:35:32 +0400
commitc8465eb42c5f853c5706a06229537c31f9dea391 (patch)
tree4019c0c34dadd973fe53946ed94c14ff2dbc4d07
parent450bb3afcb572da3a43b68480d859eefbea7dd18 (diff)
Add mask brush for sculpt mode.
The mask brush currently has two modes, 'draw' and 'smooth'.
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py3
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c269
-rw-r--r--source/blender/makesdna/DNA_brush_types.h9
-rw-r--r--source/blender/makesrna/intern/rna_brush.c26
4 files changed, 245 insertions, 62 deletions
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index f220ec19bfe..31b6bf72f5d 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -575,6 +575,9 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
row.prop(brush, "sculpt_plane", text="")
+ if brush.sculpt_tool == 'MASK':
+ col.prop(brush, "mask_tool", text="")
+
# plane_offset, use_offset_pressure, use_plane_trim, plane_trim
if capabilities.has_plane_offset:
row = col.row(align=True)
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index ac00583da74..27b1b3f2325 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -291,10 +291,14 @@ static void paint_mesh_restore_co(Sculpt *sd, SculptSession *ss)
PBVHVertexIter vd;
BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) {
- copy_v3_v3(vd.co, unode->co[vd.i]);
- if (vd.no) copy_v3_v3_short(vd.no, unode->no[vd.i]);
- else normal_short_to_float_v3(vd.fno, unode->no[vd.i]);
-
+ if (unode->type == SCULPT_UNDO_COORDS) {
+ copy_v3_v3(vd.co, unode->co[vd.i]);
+ if (vd.no) copy_v3_v3_short(vd.no, unode->no[vd.i]);
+ else normal_short_to_float_v3(vd.fno, unode->no[vd.i]);
+ }
+ else if (unode->type == SCULPT_UNDO_MASK) {
+ *vd.mask = unode->mask[vd.i];
+ }
if (vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
BLI_pbvh_vertex_iter_end;
@@ -640,6 +644,15 @@ static float brush_strength(Sculpt *sd, StrokeCache *cache, float feather)
case SCULPT_TOOL_DRAW:
case SCULPT_TOOL_LAYER:
return alpha * flip * pressure * overlap * feather;
+
+ case SCULPT_TOOL_MASK:
+ overlap = (1 + overlap) / 2;
+ switch ((BrushMaskTool)brush->mask_tool) {
+ case BRUSH_MASK_DRAW:
+ return alpha * flip * pressure * overlap * feather;
+ case BRUSH_MASK_SMOOTH:
+ return alpha * pressure * feather;
+ }
case SCULPT_TOOL_CREASE:
case SCULPT_TOOL_BLOB:
@@ -1019,7 +1032,36 @@ static void neighbor_average(SculptSession *ss, float avg[3], unsigned vert)
copy_v3_v3(avg, deform_co ? deform_co[vert] : mvert[vert].co);
}
-static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node, float bstrength)
+/* Similar to neighbor_average(), but returns an averaged mask value
+ instead of coordinate. Also does not restrict based on border or
+ corner vertices. */
+static float neighbor_average_mask(SculptSession *ss, unsigned vert)
+{
+ const float *vmask = ss->vmask;
+ float avg = 0;
+ int i, total = 0;
+
+ for (i = 0; i < ss->pmap[vert].count; i++) {
+ const MPoly *p = &ss->mpoly[ss->pmap[vert].indices[i]];
+ unsigned f_adj_v[3];
+
+ if (poly_get_adj_loops_from_vert(f_adj_v, p, ss->mloop, vert) != -1) {
+ int j;
+
+ for (j = 0; j < 3; j++) {
+ avg += vmask[f_adj_v[j]];
+ total++;
+ }
+ }
+ }
+
+ if (total > 0)
+ return avg / (float)total;
+ else
+ return vmask[vert];
+}
+
+static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node, float bstrength, int smooth_mask)
{
Brush *brush = paint_brush(&sd->paint);
PBVHVertexIter vd;
@@ -1032,16 +1074,25 @@ static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node,
BLI_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
if (sculpt_brush_test(&test, vd.co)) {
const float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist,
- ss->cache->view_normal, vd.no, vd.fno, *vd.mask);
- float avg[3], val[3];
+ ss->cache->view_normal, vd.no, vd.fno,
+ smooth_mask ? 0 : *vd.mask);
+ if (smooth_mask) {
+ float val = neighbor_average_mask(ss, vd.vert_indices[vd.i]) - *vd.mask;
+ val *= fade * bstrength;
+ *vd.mask += val;
+ CLAMP(*vd.mask, 0, 1);
+ }
+ else {
+ float avg[3], val[3];
- neighbor_average(ss, avg, vd.vert_indices[vd.i]);
- sub_v3_v3v3(val, avg, vd.co);
- mul_v3_fl(val, fade);
+ neighbor_average(ss, avg, vd.vert_indices[vd.i]);
+ sub_v3_v3v3(val, avg, vd.co);
+ mul_v3_fl(val, fade);
- add_v3_v3(val, vd.co);
+ add_v3_v3(val, vd.co);
- sculpt_clip(sd, ss, vd.co, val);
+ sculpt_clip(sd, ss, vd.co, val);
+ }
if (vd.mvert)
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
@@ -1050,14 +1101,16 @@ static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node,
BLI_pbvh_vertex_iter_end;
}
-static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node, float bstrength)
+static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node,
+ float bstrength, int smooth_mask)
{
Brush *brush = paint_brush(&sd->paint);
SculptBrushTest test;
CCGElem **griddata, *data;
CCGKey key;
DMGridAdjacency *gridadj, *adj;
- float (*tmpgrid)[3], (*tmprow)[3];
+ float (*tmpgrid_co)[3], (*tmprow_co)[3];
+ float *tmpgrid_mask, *tmprow_mask;
int v1, v2, v3, v4;
int *grid_indices, totgrid, gridsize, i, x, y;
@@ -1071,23 +1124,36 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no
#pragma omp critical
{
- tmpgrid = MEM_mallocN(sizeof(float) * 3 * gridsize * gridsize, "tmpgrid");
- tmprow = MEM_mallocN(sizeof(float) * 3 * gridsize, "tmprow");
+ if (smooth_mask) {
+ tmpgrid_mask = MEM_mallocN(sizeof(float)*gridsize*gridsize, "tmpgrid_mask");
+ tmprow_mask = MEM_mallocN(sizeof(float)*gridsize, "tmprow_mask");
+ }
+ else {
+ tmpgrid_co = MEM_mallocN(sizeof(float)*3*gridsize*gridsize, "tmpgrid_co");
+ tmprow_co = MEM_mallocN(sizeof(float)*3*gridsize, "tmprow_co");
+ }
}
for (i = 0; i < totgrid; ++i) {
data = griddata[grid_indices[i]];
adj = &gridadj[grid_indices[i]];
- memset(tmpgrid, 0, sizeof(float) * 3 * gridsize * gridsize);
+ if (smooth_mask)
+ memset(tmpgrid_mask, 0, sizeof(float)*gridsize*gridsize);
+ else
+ memset(tmpgrid_co, 0, sizeof(float)*3*gridsize*gridsize);
for (y = 0; y < gridsize - 1; y++) {
- float tmp[3];
-
- v1 = y * gridsize;
- add_v3_v3v3(tmprow[0],
- CCG_elem_offset_co(&key, data, v1),
- CCG_elem_offset_co(&key, data, v1 + gridsize));
+ v1 = y*gridsize;
+ if (smooth_mask) {
+ tmprow_mask[0] = (*CCG_elem_offset_mask(&key, data, v1) +
+ *CCG_elem_offset_mask(&key, data, v1 + gridsize));
+ }
+ else {
+ add_v3_v3v3(tmprow_co[0],
+ CCG_elem_offset_co(&key, data, v1),
+ CCG_elem_offset_co(&key, data, v1 + gridsize));
+ }
for (x = 0; x < gridsize - 1; x++) {
v1 = x + y * gridsize;
@@ -1095,15 +1161,31 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no
v3 = v1 + gridsize;
v4 = v3 + 1;
- add_v3_v3v3(tmprow[x + 1],
- CCG_elem_offset_co(&key, data, v2),
- CCG_elem_offset_co(&key, data, v4));
- add_v3_v3v3(tmp, tmprow[x + 1], tmprow[x]);
+ if (smooth_mask) {
+ float tmp;
+
+ tmprow_mask[x + 1] = (*CCG_elem_offset_mask(&key, data, v2) +
+ *CCG_elem_offset_mask(&key, data, v4));
+ tmp = tmprow_mask[x + 1] + tmprow_mask[x];
- add_v3_v3(tmpgrid[v1], tmp);
- add_v3_v3(tmpgrid[v2], tmp);
- add_v3_v3(tmpgrid[v3], tmp);
- add_v3_v3(tmpgrid[v4], tmp);
+ tmpgrid_mask[v1] += tmp;
+ tmpgrid_mask[v2] += tmp;
+ tmpgrid_mask[v3] += tmp;
+ tmpgrid_mask[v4] += tmp;
+ }
+ else {
+ float tmp[3];
+
+ add_v3_v3v3(tmprow_co[x + 1],
+ CCG_elem_offset_co(&key, data, v2),
+ CCG_elem_offset_co(&key, data, v4));
+ add_v3_v3v3(tmp, tmprow_co[x + 1], tmprow_co[x]);
+
+ add_v3_v3(tmpgrid_co[v1], tmp);
+ add_v3_v3(tmpgrid_co[v2], tmp);
+ add_v3_v3(tmpgrid_co[v3], tmp);
+ add_v3_v3(tmpgrid_co[v4], tmp);
+ }
}
}
@@ -1130,32 +1212,38 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no
index = x + y*gridsize;
co = CCG_elem_offset_co(&key, data, index);
fno = CCG_elem_offset_no(&key, data, index);
- mask = CCG_elem_offset_no(&key, data, index);
+ mask = CCG_elem_offset_mask(&key, data, index);
if (sculpt_brush_test(&test, co)) {
+ const float strength_mask = (smooth_mask ? 0 : *mask);
const float fade = bstrength*tex_strength(ss, brush, co, test.dist,
- ss->cache->view_normal, NULL, fno, *mask);
- float *avg, val[3];
- float n;
-
- avg = tmpgrid[x + y * gridsize];
-
- n = 1 / 16.0f;
-
+ ss->cache->view_normal,
+ NULL, fno, strength_mask);
+ float n = 1.0f / 16.0f;
+
if (x == 0 || x == gridsize - 1)
n *= 2;
-
+
if (y == 0 || y == gridsize - 1)
n *= 2;
+
+ if (smooth_mask) {
+ *mask += ((tmpgrid_mask[x + y*gridsize] * n) - *mask) * fade;
+ }
+ else {
+ float *avg, val[3];
+
+ avg = tmpgrid_co[x + y*gridsize];
- mul_v3_fl(avg, n);
+ mul_v3_fl(avg, n);
- sub_v3_v3v3(val, avg, co);
- mul_v3_fl(val, fade);
+ sub_v3_v3v3(val, avg, co);
+ mul_v3_fl(val, fade);
- add_v3_v3(val, co);
+ add_v3_v3(val, co);
- sculpt_clip(sd, ss, co, val);
+ sculpt_clip(sd, ss, co, val);
+ }
}
}
}
@@ -1163,12 +1251,19 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no
#pragma omp critical
{
- MEM_freeN(tmpgrid);
- MEM_freeN(tmprow);
+ if (smooth_mask) {
+ MEM_freeN(tmpgrid_mask);
+ MEM_freeN(tmprow_mask);
+ }
+ else {
+ MEM_freeN(tmpgrid_co);
+ MEM_freeN(tmprow_co);
+ }
}
}
-static void smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float bstrength)
+static void smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode,
+ float bstrength, int smooth_mask)
{
SculptSession *ss = ob->sculpt;
const int max_iterations = 4;
@@ -1185,10 +1280,13 @@ static void smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
for (n = 0; n < totnode; n++) {
if (ss->multires) {
- do_multires_smooth_brush(sd, ss, nodes[n], iteration != count ? 1.0f : last);
+ do_multires_smooth_brush(sd, ss, nodes[n],
+ iteration != count ? 1.0f : last, smooth_mask);
+ }
+ else if (ss->pmap) {
+ do_mesh_smooth_brush(sd, ss, nodes[n],
+ iteration != count ? 1.0f : last, smooth_mask);
}
- else if (ss->pmap)
- do_mesh_smooth_brush(sd, ss, nodes[n], iteration != count ? 1.0f : last);
}
if (ss->multires)
@@ -1199,7 +1297,53 @@ static void smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float
static void do_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
SculptSession *ss = ob->sculpt;
- smooth(sd, ob, nodes, totnode, ss->cache->bstrength);
+ smooth(sd, ob, nodes, totnode, ss->cache->bstrength, FALSE);
+}
+
+static void do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
+{
+ SculptSession *ss = ob->sculpt;
+ Brush *brush = paint_brush(&sd->paint);
+ float bstrength = ss->cache->bstrength;
+ int n;
+
+ /* threaded loop over nodes */
+ #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
+ for (n = 0; n < totnode; n++) {
+ PBVHVertexIter vd;
+ SculptBrushTest test;
+
+ sculpt_brush_test_init(ss, &test);
+
+ BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) {
+ if (sculpt_brush_test(&test, vd.co)) {
+ float fade = tex_strength(ss, brush, vd.co, test.dist,
+ ss->cache->view_normal, vd.no, vd.fno, 0);
+
+ (*vd.mask) += fade*bstrength;
+ CLAMP(*vd.mask, 0, 1);
+
+ if (vd.mvert)
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ }
+ BLI_pbvh_vertex_iter_end;
+ }
+ }
+}
+
+static void do_mask_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
+{
+ SculptSession *ss = ob->sculpt;
+ Brush *brush = paint_brush(&sd->paint);
+
+ switch ((BrushMaskTool)brush->mask_tool) {
+ case BRUSH_MASK_DRAW:
+ do_mask_brush_draw(sd, ob, nodes, totnode);
+ break;
+ case BRUSH_MASK_SMOOTH:
+ smooth(sd, ob, nodes, totnode, ss->cache->bstrength, TRUE);
+ break;
+ }
}
static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
@@ -1624,7 +1768,7 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
SculptUndoNode *unode;
float (*origco)[3], *layer_disp;
/* XXX: layer brush needs conversion to proxy but its more complicated */
- /* proxy= BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; */
+ /* proxy = BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; */
unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS);
origco = unode->co;
@@ -2417,7 +2561,9 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush)
if (totnode) {
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
for (n = 0; n < totnode; n++) {
- sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS);
+ sculpt_undo_push_node(ob, nodes[n],
+ brush->sculpt_tool == SCULPT_TOOL_MASK ?
+ SCULPT_UNDO_MASK : SCULPT_UNDO_COORDS);
BLI_pbvh_node_mark_update(nodes[n]);
}
@@ -2474,14 +2620,18 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush)
case SCULPT_TOOL_SCRAPE:
do_scrape_brush(sd, ob, nodes, totnode);
break;
+ case SCULPT_TOOL_MASK:
+ do_mask_brush(sd, ob, nodes, totnode);
+ break;
}
- if (brush->sculpt_tool != SCULPT_TOOL_SMOOTH && brush->autosmooth_factor > 0) {
+ if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_MASK) &&
+ brush->autosmooth_factor > 0) {
if (brush->flag & BRUSH_INVERSE_SMOOTH_PRESSURE) {
- smooth(sd, ob, nodes, totnode, brush->autosmooth_factor * (1 - ss->cache->pressure));
+ smooth(sd, ob, nodes, totnode, brush->autosmooth_factor * (1 - ss->cache->pressure), FALSE);
}
else {
- smooth(sd, ob, nodes, totnode, brush->autosmooth_factor);
+ smooth(sd, ob, nodes, totnode, brush->autosmooth_factor, FALSE);
}
}
@@ -2785,6 +2935,7 @@ void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, int need_
ss->mloop = me->mloop;
ss->face_normals = NULL;
ss->multires = NULL;
+ ss->vmask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
}
/* BMESH ONLY --- at some point we should move sculpt code to use polygons only - but for now it needs tessfaces */
@@ -3384,6 +3535,8 @@ static int sculpt_brush_stroke_init(bContext *C, wmOperator *op)
is_smooth |= mode == BRUSH_STROKE_SMOOTH;
is_smooth |= brush->sculpt_tool == SCULPT_TOOL_SMOOTH;
+ is_smooth |= ((brush->sculpt_tool == SCULPT_TOOL_MASK) &&
+ (brush->mask_tool == BRUSH_MASK_SMOOTH));
sculpt_update_mesh_elements(scene, sd, ob, is_smooth);
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 4b84b819a1c..d3b7381cdb5 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -86,7 +86,7 @@ typedef struct Brush {
char sculpt_tool; /* active sculpt tool */
char vertexpaint_tool; /* active vertex/weight paint blend mode (poorly named) */
char imagepaint_tool; /* active image paint tool */
- char pad;
+ char mask_tool; /* enum BrushMaskTool, only used if sculpt_tool is SCULPT_TOOL_MASK */
float autosmooth_factor;
@@ -162,7 +162,8 @@ typedef enum BrushSculptTool {
SCULPT_TOOL_CREASE = 16,
SCULPT_TOOL_BLOB = 17,
- SCULPT_TOOL_CLAY_STRIPS = 18
+ SCULPT_TOOL_CLAY_STRIPS = 18,
+ SCULPT_TOOL_MASK = 19
} BrushSculptTool;
/* ImagePaintSettings.tool */
@@ -190,6 +191,10 @@ enum {
PAINT_BLEND_DARKEN
};
+typedef enum {
+ BRUSH_MASK_DRAW,
+ BRUSH_MASK_SMOOTH
+} BrushMaskTool;
#define MAX_BRUSH_PIXEL_RADIUS 200
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index ee4b34508d1..6ff51f7e864 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -59,6 +59,7 @@ EnumPropertyItem brush_sculpt_tool_items[] = {
{SCULPT_TOOL_GRAB, "GRAB", ICON_BRUSH_GRAB, "Grab", ""},
{SCULPT_TOOL_INFLATE, "INFLATE", ICON_BRUSH_INFLATE, "Inflate", ""},
{SCULPT_TOOL_LAYER, "LAYER", ICON_BRUSH_LAYER, "Layer", ""},
+ {SCULPT_TOOL_MASK, "MASK", ICON_BRUSH_MASK, "Mask", ""},
{SCULPT_TOOL_NUDGE, "NUDGE", ICON_BRUSH_NUDGE, "Nudge", ""},
{SCULPT_TOOL_PINCH, "PINCH", ICON_BRUSH_PINCH, "Pinch", ""},
{SCULPT_TOOL_ROTATE, "ROTATE", ICON_BRUSH_ROTATE, "Rotate", ""},
@@ -112,7 +113,7 @@ static int rna_SculptCapabilities_has_accumulate_get(PointerRNA *ptr)
static int rna_SculptCapabilities_has_auto_smooth_get(PointerRNA *ptr)
{
Brush *br = (Brush*)ptr->data;
- return br->sculpt_tool != SCULPT_TOOL_SMOOTH;
+ return !ELEM(br->sculpt_tool, SCULPT_TOOL_MASK, SCULPT_TOOL_SMOOTH);
}
static int rna_SculptCapabilities_has_height_get(PointerRNA *ptr)
@@ -169,7 +170,8 @@ static int rna_SculptCapabilities_has_random_texture_angle_get(PointerRNA *ptr)
static int rna_SculptCapabilities_has_sculpt_plane_get(PointerRNA *ptr)
{
Brush *br = (Brush*)ptr->data;
- return !ELEM3(br->sculpt_tool, SCULPT_TOOL_INFLATE, SCULPT_TOOL_PINCH,
+ return !ELEM4(br->sculpt_tool, SCULPT_TOOL_INFLATE,
+ SCULPT_TOOL_MASK, SCULPT_TOOL_PINCH,
SCULPT_TOOL_SMOOTH);
}
@@ -343,6 +345,16 @@ static EnumPropertyItem *rna_Brush_direction_itemf(bContext *UNUSED(C), PointerR
case SCULPT_TOOL_CLAY:
return prop_direction_items;
+ case SCULPT_TOOL_MASK:
+ switch ((BrushMaskTool)me->mask_tool) {
+ case BRUSH_MASK_DRAW:
+ return prop_direction_items;
+ break;
+ case BRUSH_MASK_SMOOTH:
+ return prop_default_items;
+ break;
+ }
+
case SCULPT_TOOL_FLATTEN:
return prop_flatten_contrast_items;
@@ -475,6 +487,11 @@ static void rna_def_brush(BlenderRNA *brna)
{SCULPT_DISP_DIR_Z, "Z", 0, "Z Plane", ""},
{0, NULL, 0, NULL, NULL}};
+ static EnumPropertyItem brush_mask_tool_items[] = {
+ {BRUSH_MASK_DRAW, "DRAW", 0, "Draw", ""},
+ {BRUSH_MASK_SMOOTH, "SMOOTH", 0, "Smooth", ""},
+ {0, NULL, 0, NULL, NULL}};
+
srna = RNA_def_struct(brna, "Brush", "ID");
RNA_def_struct_ui_text(srna, "Brush", "Brush datablock for storing brush settings for painting and sculpting");
RNA_def_struct_ui_icon(srna, ICON_BRUSH_DATA);
@@ -531,6 +548,11 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_enum_items(prop, brush_sculpt_plane_items);
RNA_def_property_ui_text(prop, "Sculpt Plane", "");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop= RNA_def_property(srna, "mask_tool", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, brush_mask_tool_items);
+ RNA_def_property_ui_text(prop, "Mask Tool", "");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
/* number values */
prop = RNA_def_property(srna, "size", PROP_INT, PROP_DISTANCE);