Solve partial redraw issues in sculpting.

* Do union with previous partial redraw before overwriting with self and
store unmodified new rect to avoid rect getting bigger.
* Make rect one pixel wider instead of smaller so edges do not get left
outside. Overall this looks quite better.
This commit is contained in:
Antony Riakiotakis
2014-03-06 16:30:16 +02:00
parent 3d2b530315
commit 175a6b2fce

View File

@@ -1421,7 +1421,7 @@ static float bmesh_neighbor_average_mask(BMesh *bm, BMVert *v)
}
}
static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node, float bstrength, int smooth_mask)
static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node, float bstrength, int smooth_mask, float (*proxy)[3])
{
Brush *brush = BKE_paint_brush(&sd->paint);
PBVHVertexIter vd;
@@ -1450,9 +1450,7 @@ static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node,
sub_v3_v3v3(val, avg, vd.co);
mul_v3_fl(val, fade);
add_v3_v3(val, vd.co);
sculpt_clip(sd, ss, vd.co, val);
sculpt_clip(sd, ss, proxy[vd.i], val);
}
if (vd.mvert)
@@ -1462,7 +1460,7 @@ static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node,
BKE_pbvh_vertex_iter_end;
}
static void do_bmesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node, float bstrength, int smooth_mask)
static void do_bmesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node, float bstrength, int smooth_mask, float (*proxy)[3])
{
Brush *brush = BKE_paint_brush(&sd->paint);
PBVHVertexIter vd;
@@ -1491,9 +1489,7 @@ static void do_bmesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node,
sub_v3_v3v3(val, avg, vd.co);
mul_v3_fl(val, fade);
add_v3_v3(val, vd.co);
sculpt_clip(sd, ss, vd.co, val);
sculpt_clip(sd, ss, proxy[vd.i], val);
}
if (vd.mvert)
@@ -1504,7 +1500,7 @@ static void do_bmesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node,
}
static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node,
float bstrength, int smooth_mask)
float bstrength, int smooth_mask, float (*proxy)[3])
{
Brush *brush = BKE_paint_brush(&sd->paint);
SculptBrushTest test;
@@ -1517,6 +1513,7 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no
int thread_num;
BLI_bitmap **grid_hidden;
int *grid_indices, totgrid, gridsize, i, x, y;
int proxyindex = 0;
sculpt_brush_test_init(ss, &test);
@@ -1602,6 +1599,10 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no
float *fno;
float *mask;
int index;
int proxyindex_local;
/* store locally here because we may not get a chance to increase later */
proxyindex_local = proxyindex++;
if (gh) {
if (BLI_BITMAP_GET(gh, y * gridsize + x))
@@ -1651,9 +1652,7 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no
sub_v3_v3v3(val, avg, co);
mul_v3_fl(val, fade);
add_v3_v3(val, co);
sculpt_clip(sd, ss, co, val);
sculpt_clip(sd, ss, proxy[proxyindex_local], val);
}
}
}
@@ -1665,44 +1664,34 @@ 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;
const float fract = 1.0f / max_iterations;
PBVHType type = BKE_pbvh_type(ss->pbvh);
int iteration, n, count;
float last;
int n;
CLAMP(bstrength, 0, 1);
count = (int)(bstrength * max_iterations);
last = max_iterations * (bstrength - count * fract);
if (type == PBVH_FACES && !ss->pmap) {
BLI_assert(!"sculpt smooth: pmap missing");
return;
}
for (iteration = 0; iteration <= count; ++iteration) {
float strength = (iteration != count) ? 1.0f : last;
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
for (n = 0; n < totnode; n++) {
switch (type) {
case PBVH_GRIDS:
do_multires_smooth_brush(sd, ss, nodes[n], strength,
smooth_mask);
break;
case PBVH_FACES:
do_mesh_smooth_brush(sd, ss, nodes[n], strength,
smooth_mask);
break;
case PBVH_BMESH:
do_bmesh_smooth_brush(sd, ss, nodes[n], strength, smooth_mask);
break;
}
}
for (n = 0; n < totnode; n++) {
float (*proxy)[3];
proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
if (ss->multires)
multires_stitch_grids(ob);
switch (type) {
case PBVH_GRIDS:
do_multires_smooth_brush(sd, ss, nodes[n], bstrength,
smooth_mask, proxy);
break;
case PBVH_FACES:
do_mesh_smooth_brush(sd, ss, nodes[n], bstrength,
smooth_mask, proxy);
break;
case PBVH_BMESH:
do_bmesh_smooth_brush(sd, ss, nodes[n], bstrength, smooth_mask, proxy);
break;
}
}
}
@@ -3279,7 +3268,7 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode);
/* first line is tools that don't support proxies */
if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_LAYER) ||
if ((brush->sculpt_tool != SCULPT_TOOL_LAYER) ||
ss->cache->supports_gravity)
{
/* these brushes start from original coordinates */
@@ -3327,6 +3316,9 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
BKE_pbvh_node_free_proxies(nodes[n]);
}
if (ss->multires && brush->sculpt_tool == SCULPT_TOOL_SMOOTH)
multires_stitch_grids(ob);
}
if (nodes)
@@ -3358,8 +3350,8 @@ static void sculpt_flush_stroke_deform(Sculpt *sd, Object *ob)
SculptSession *ss = ob->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
if (ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_LAYER)) {
/* this brushes aren't using proxies, so sculpt_combine_proxies() wouldn't
if (brush->sculpt_tool == SCULPT_TOOL_LAYER) {
/* this brushes doesn't use proxies, so sculpt_combine_proxies() wouldn't
* propagate needed deformation to original base */
int n, totnode;
@@ -4413,15 +4405,16 @@ static void sculpt_flush_update(bContext *C)
sculpt_update_object_bounding_box(ob);
if (sculpt_get_redraw_rect(ar, CTX_wm_region_view3d(C), ob, &r)) {
if (ss->cache)
ss->cache->previous_r = r;
rcti tmp = r;
sculpt_extend_redraw_rect_previous(ob, &r);
r.xmin += ar->winrct.xmin + 1;
r.xmax += ar->winrct.xmin - 1;
r.ymin += ar->winrct.ymin + 1;
r.ymax += ar->winrct.ymin - 1;
if (ss->cache)
ss->cache->previous_r = tmp;
r.xmin += ar->winrct.xmin - 1;
r.xmax += ar->winrct.xmin + 1;
r.ymin += ar->winrct.ymin - 1;
r.ymax += ar->winrct.ymin + 1;
ss->partial_redraw = 1;
ED_region_tag_redraw_partial(ar, &r);