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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user