diff options
author | Pablo Dobarro <pablodp606@gmail.com> | 2019-11-19 20:44:13 +0300 |
---|---|---|
committer | Pablo Dobarro <pablodp606@gmail.com> | 2019-11-27 19:02:02 +0300 |
commit | b6d436ae28311a8e2e7ea0079b1fa1fb046909ab (patch) | |
tree | a47826ae8f9245254add3de4c17298995799672d /source/blender/editors | |
parent | e85ab2cdc2a6905f4d2eb4a2acdc6db8e20fbeec (diff) |
Fix T71667: Use the Sculpt Mesh API in the Multires Smooth brush
This removes all multires code from the smooth brush and replaces it
with a new implementation that uses the sculpt mesh API. This makes the
code much easier to understand and maintain.
We could unify all the smooth brushes into a single implementation, but
mesh smoothing has code to deal with open boundaries that I don't want
to remove yet.
Most bugs and artifacts related to access neighbor grids should be fixed
(like T71667). This also fixes performance bugs such as T70689, that were
related to grid stitching after applying the brush.
Reviewed By: jbakker
Maniphest Tasks: T71667
Differential Revision: https://developer.blender.org/D6277
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 174 |
1 files changed, 25 insertions, 149 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 5e1a36e8873..2964d53bc48 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -2631,152 +2631,48 @@ static void do_smooth_brush_multires_task_cb_ex(void *__restrict userdata, const TaskParallelTLS *__restrict tls) { SculptThreadedTaskData *data = userdata; - SculptDoBrushSmoothGridDataChunk *data_chunk = tls->userdata_chunk; SculptSession *ss = data->ob->sculpt; Sculpt *sd = data->sd; const Brush *brush = data->brush; const bool smooth_mask = data->smooth_mask; float bstrength = data->strength; - CCGElem **griddata, *gddata; - - float(*tmpgrid_co)[3] = NULL; - float tmprow_co[2][3]; - float *tmpgrid_mask = NULL; - float tmprow_mask[2]; + PBVHVertexIter vd; - BLI_bitmap *const *grid_hidden; - int *grid_indices, totgrid, gridsize; - int i, x, y; + CLAMP(bstrength, 0.0f, 1.0f); SculptBrushTest test; SculptBrushTestFn sculpt_brush_test_sq_fn = sculpt_brush_test_init_with_falloff_shape( ss, &test, data->brush->falloff_shape); - CLAMP(bstrength, 0.0f, 1.0f); - - BKE_pbvh_node_get_grids( - ss->pbvh, data->nodes[n], &grid_indices, &totgrid, NULL, &gridsize, &griddata); - CCGKey key = *BKE_pbvh_get_grid_key(ss->pbvh); - - grid_hidden = BKE_pbvh_grid_hidden(ss->pbvh); - - if (smooth_mask) { - tmpgrid_mask = (void *)(data_chunk + 1); - } - else { - tmpgrid_co = (void *)(data_chunk + 1); - } - - for (i = 0; i < totgrid; i++) { - int gi = grid_indices[i]; - const BLI_bitmap *gh = grid_hidden[gi]; - gddata = griddata[gi]; - - if (smooth_mask) { - memset(tmpgrid_mask, 0, data_chunk->tmpgrid_size); - } - else { - memset(tmpgrid_co, 0, data_chunk->tmpgrid_size); - } - - for (y = 0; y < gridsize - 1; y++) { - const int v = y * gridsize; + BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) + { + if (sculpt_brush_test_sq_fn(&test, vd.co)) { + const float fade = bstrength * tex_strength(ss, + brush, + vd.co, + sqrtf(test.dist), + vd.no, + vd.fno, + smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f), + vd.index, + tls->thread_id); if (smooth_mask) { - tmprow_mask[0] = (*CCG_elem_offset_mask(&key, gddata, v) + - *CCG_elem_offset_mask(&key, gddata, v + gridsize)); + float val = grids_neighbor_average_mask(ss, vd.index) - *vd.mask; + val *= fade * bstrength; + *vd.mask += val; + CLAMP(*vd.mask, 0.0f, 1.0f); } else { - add_v3_v3v3(tmprow_co[0], - CCG_elem_offset_co(&key, gddata, v), - CCG_elem_offset_co(&key, gddata, v + gridsize)); - } - - for (x = 0; x < gridsize - 1; x++) { - const int v1 = x + y * gridsize; - const int v2 = v1 + 1; - const int v3 = v1 + gridsize; - const int v4 = v3 + 1; - - if (smooth_mask) { - float tmp; - - tmprow_mask[(x + 1) % 2] = (*CCG_elem_offset_mask(&key, gddata, v2) + - *CCG_elem_offset_mask(&key, gddata, v4)); - tmp = tmprow_mask[(x + 1) % 2] + tmprow_mask[x % 2]; - - 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) % 2], - CCG_elem_offset_co(&key, gddata, v2), - CCG_elem_offset_co(&key, gddata, v4)); - add_v3_v3v3(tmp, tmprow_co[(x + 1) % 2], tmprow_co[x % 2]); - - 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); - } - } - } - - /* blend with existing coordinates */ - for (y = 0; y < gridsize; y++) { - for (x = 0; x < gridsize; x++) { - float *co; - const float *fno; - float *mask; - const int index = y * gridsize + x; - - if (gh) { - if (BLI_BITMAP_TEST(gh, index)) { - continue; - } - } - - co = CCG_elem_offset_co(&key, gddata, index); - fno = CCG_elem_offset_no(&key, gddata, index); - mask = CCG_elem_offset_mask(&key, gddata, index); - - if (sculpt_brush_test_sq_fn(&test, co)) { - const float strength_mask = (smooth_mask ? 0.0f : *mask); - const float fade = - bstrength * - tex_strength( - ss, brush, co, sqrtf(test.dist), NULL, fno, strength_mask, 0, tls->thread_id); - float f = 1.0f / 16.0f; - - if (x == 0 || x == gridsize - 1) { - f *= 2.0f; - } - - if (y == 0 || y == gridsize - 1) { - f *= 2.0f; - } - - if (smooth_mask) { - *mask += ((tmpgrid_mask[index] * f) - *mask) * fade; - } - else { - float *avg = tmpgrid_co[index]; - float val[3]; - - mul_v3_fl(avg, f); - sub_v3_v3v3(val, avg, co); - madd_v3_v3v3fl(val, co, val, fade); - - sculpt_clip(sd, ss, co, val); - } - } + float avg[3], val[3]; + grids_neighbor_average(ss, avg, vd.index); + sub_v3_v3v3(val, avg, vd.co); + madd_v3_v3v3fl(val, vd.co, val, fade); + sculpt_clip(sd, ss, vd.co, val); } } } + BKE_pbvh_vertex_iter_end; } static void smooth(Sculpt *sd, @@ -2821,25 +2717,9 @@ static void smooth(Sculpt *sd, BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode); switch (type) { - case PBVH_GRIDS: { - int gridsize; - size_t size; - SculptDoBrushSmoothGridDataChunk *data_chunk; - - BKE_pbvh_node_get_grids(ss->pbvh, NULL, NULL, NULL, NULL, &gridsize, NULL); - size = (size_t)gridsize; - size = sizeof(float) * size * size * (smooth_mask ? 1 : 3); - data_chunk = MEM_mallocN(sizeof(*data_chunk) + size, __func__); - data_chunk->tmpgrid_size = size; - size += sizeof(*data_chunk); - - settings.userdata_chunk = data_chunk; - settings.userdata_chunk_size = size; + case PBVH_GRIDS: BKE_pbvh_parallel_range(0, totnode, &data, do_smooth_brush_multires_task_cb_ex, &settings); - - MEM_freeN(data_chunk); break; - } case PBVH_FACES: BKE_pbvh_parallel_range(0, totnode, &data, do_smooth_brush_mesh_task_cb_ex, &settings); break; @@ -2847,10 +2727,6 @@ static void smooth(Sculpt *sd, BKE_pbvh_parallel_range(0, totnode, &data, do_smooth_brush_bmesh_task_cb_ex, &settings); break; } - - if (ss->multires) { - multires_stitch_grids(ob); - } } } |