forked from bartvdbraak/blender
Add mask brush for sculpt mode.
The mask brush currently has two modes, 'draw' and 'smooth'.
This commit is contained in:
parent
450bb3afcb
commit
c8465eb42c
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
add_v3_v3(tmpgrid[v1], tmp);
|
||||
add_v3_v3(tmpgrid[v2], tmp);
|
||||
add_v3_v3(tmpgrid[v3], tmp);
|
||||
add_v3_v3(tmpgrid[v4], 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];
|
||||
|
||||
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];
|
||||
|
||||
mul_v3_fl(avg, n);
|
||||
avg = tmpgrid_co[x + y*gridsize];
|
||||
|
||||
sub_v3_v3v3(val, avg, co);
|
||||
mul_v3_fl(val, fade);
|
||||
mul_v3_fl(avg, n);
|
||||
|
||||
add_v3_v3(val, co);
|
||||
sub_v3_v3v3(val, avg, co);
|
||||
mul_v3_fl(val, fade);
|
||||
|
||||
sculpt_clip(sd, ss, co, val);
|
||||
add_v3_v3(val, co);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user