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:
authorJoseph Eagar <joeedh@gmail.com>2021-09-14 05:24:21 +0300
committerJoseph Eagar <joeedh@gmail.com>2021-09-14 05:24:21 +0300
commit3df335d330a694269a9ceefb7234a00c69ca4be9 (patch)
treee8ebcd41ab9ae8602ed1a8e762f4fd6a40c14cae /source/blender/editors
parent0676928408af53d6ca76690b1a9772b303ccc39d (diff)
Sculpt dyntopo:
* Fixed noise on using autosmooth with tools that use original coorinates. While this was most prominent with DynTopo, it did happen with other tools. * The solution is to smooth the original coordinates as well as the explicit coordinates if the active tool requires original data. * I decided to replace the original coordinates system for PBVH_FACES and PBVH_GRIDS with the same MDynTopoVert structure DynTopo uses. The alternative would have been extremely messy code. * Todo: Rename MDynTopoVert to. . .SculptInfoVert? * Todo: Cache boundary flag and corner info in MDynTopoVert->flag for PBVH_FACES/GRIDS similar to PBVH_BMESH.
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c189
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_boundary.c16
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_dyntopo.c5
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_color.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mesh.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h27
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_paint_color.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_pose.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_smooth.c150
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_transform.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c2
11 files changed, 256 insertions, 145 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index f2f4ca9582b..fc2720bc31d 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -158,15 +158,40 @@ int SCULPT_vertex_count_get(SculptSession *ss)
return 0;
}
-const float *SCULPT_vertex_origco_get(SculptSession *ss, SculptVertRef vertex)
+MDynTopoVert *SCULPT_vertex_get_mdyntopo(SculptSession *ss, SculptVertRef vertex)
{
- if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
- BMVert *v = (BMVert *)vertex.i;
- return BKE_PBVH_DYNVERT(ss->cd_dyn_vert, v)->origco;
+ switch (BKE_pbvh_type(ss->pbvh)) {
+ case PBVH_BMESH: {
+ BMVert *v = (BMVert *)vertex.i;
+ return BKE_PBVH_DYNVERT(ss->cd_dyn_vert, v);
+ }
+
+ case PBVH_GRIDS:
+ case PBVH_FACES: {
+ return ss->mdyntopo_verts + vertex.i;
+ }
}
- // XXX implement me
- return SCULPT_vertex_co_get(ss, vertex);
+ return NULL;
+}
+
+float *SCULPT_vertex_origco_get(SculptSession *ss, SculptVertRef vertex)
+{
+ switch (BKE_pbvh_type(ss->pbvh)) {
+ case PBVH_BMESH: {
+ BMVert *v = (BMVert *)vertex.i;
+ return BKE_PBVH_DYNVERT(ss->cd_dyn_vert, v)->origco;
+ }
+
+ case PBVH_GRIDS:
+ case PBVH_FACES: {
+ MDynTopoVert *mv = ss->mdyntopo_verts + vertex.i;
+
+ return ss->mdyntopo_verts[vertex.i].origco;
+ }
+ }
+
+ return NULL;
}
const float *SCULPT_vertex_co_get(SculptSession *ss, SculptVertRef index)
@@ -2284,6 +2309,9 @@ typedef enum StrokeFlags {
void SCULPT_orig_vert_data_unode_init(SculptOrigVertData *data, Object *ob, SculptUndoNode *unode)
{
SculptSession *ss = ob->sculpt;
+
+ // do nothing
+
BMesh *bm = ss->bm;
memset(data, 0, sizeof(*data));
@@ -2295,12 +2323,9 @@ void SCULPT_orig_vert_data_unode_init(SculptOrigVertData *data, Object *ob, Scul
if (bm) {
data->bm_log = ss->bm_log;
}
+
else {
- data->datatype = data->unode->type;
- data->coords = data->unode->co;
- data->normals = data->unode->no;
- data->vmasks = data->unode->mask;
- data->colors = data->unode->col;
+ // data->datatype = data->unode->type;
}
}
@@ -2316,75 +2341,58 @@ void SCULPT_orig_vert_data_init(SculptOrigVertData *data,
SculptUndoNode *unode = NULL;
data->ss = ob->sculpt;
- /*do not allocate an undo node for bmesh pbvh*/
+ // don't need undo node here anymore
if (!ob->sculpt->bm) {
- unode = SCULPT_undo_push_node(ob, node, type);
+ // unode = SCULPT_undo_push_node(ob, node, type);
}
SCULPT_orig_vert_data_unode_init(data, ob, unode);
data->datatype = type;
}
-/**
- * Update a #SculptOrigVertData for a particular vertex from the PBVH iterator.
- */
-void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, PBVHVertexIter *iter)
+void SCULPT_vertex_check_origdata(SculptSession *ss, SculptVertRef vertex)
{
// check if we need to update original data for current stroke
- if (orig_data->bm_log) {
- MDynTopoVert *mv = BKE_PBVH_DYNVERT(iter->cd_dyn_vert, iter->bm_vert);
- if (mv->stroke_id != orig_data->ss->stroke_id) {
- mv->stroke_id = orig_data->ss->stroke_id;
+ MDynTopoVert *mv = ss->bm ? BKE_PBVH_DYNVERT(ss->cd_dyn_vert, (BMVert *)vertex.i) :
+ ss->mdyntopo_verts + vertex.i;
- copy_v3_v3(mv->origco, iter->bm_vert->co);
- copy_v3_v3(mv->origno, iter->bm_vert->no);
+ if (mv->stroke_id != ss->stroke_id) {
+ mv->stroke_id = ss->stroke_id;
- const int cd_vcol = iter->cd_vcol_offset;
- const int cd_mask = iter->cd_vert_mask_offset;
-
- if (cd_vcol >= 0) {
- MPropCol *col = BM_ELEM_CD_GET_VOID_P(iter->bm_vert, cd_vcol);
- copy_v4_v4(mv->origcolor, col->color);
- }
+ copy_v3_v3(mv->origco, SCULPT_vertex_co_get(ss, vertex));
+ SCULPT_vertex_normal_get(ss, vertex, mv->origno);
- if (cd_mask >= 0) {
- mv->origmask = BM_ELEM_CD_GET_FLOAT(iter->bm_vert, cd_mask);
- }
+ const float *color = SCULPT_vertex_color_get(ss, vertex);
+ if (color) {
+ copy_v4_v4(mv->origcolor, color);
}
+
+ mv->origmask = SCULPT_vertex_mask_get(ss, vertex);
}
+}
- if (orig_data->datatype == SCULPT_UNDO_COORDS) {
- if (orig_data->bm_log) {
- orig_data->co = BKE_PBVH_DYNVERT(iter->cd_dyn_vert, iter->bm_vert)->origco;
+/**
+ * DEPRECATED use Update a #SculptOrigVertData for a particular vertex from the PBVH iterator.
+ */
+void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, SculptVertRef vertex)
+{
+ // check if we need to update original data for current stroke
+ MDynTopoVert *mv = SCULPT_vertex_get_mdyntopo(orig_data->ss, vertex);
- float *no = BKE_PBVH_DYNVERT(iter->cd_dyn_vert, iter->bm_vert)->origno;
- normal_float_to_short_v3(orig_data->_no, no);
- orig_data->no = orig_data->_no;
+ SCULPT_vertex_check_origdata(orig_data->ss, vertex);
- orig_data->col = iter->cd_vcol_offset >= 0 ?
- BKE_PBVH_DYNVERT(iter->cd_dyn_vert, iter->bm_vert)->origcolor :
- NULL;
- }
- else {
- orig_data->co = orig_data->coords[iter->i];
- orig_data->no = orig_data->normals[iter->i];
- }
+ if (orig_data->datatype == SCULPT_UNDO_COORDS) {
+ float *no = mv->origno;
+ normal_float_to_short_v3(orig_data->_no, no);
+
+ orig_data->no = orig_data->_no;
+ orig_data->co = mv->origco;
}
else if (orig_data->datatype == SCULPT_UNDO_COLOR) {
- if (orig_data->bm_log) {
- orig_data->col = BKE_PBVH_DYNVERT(iter->cd_dyn_vert, iter->bm_vert)->origcolor;
- }
- else {
- orig_data->col = orig_data->colors[iter->i];
- }
+ orig_data->col = mv->origcolor;
}
else if (orig_data->datatype == SCULPT_UNDO_MASK) {
- if (orig_data->bm_log) {
- orig_data->mask = BKE_PBVH_DYNVERT(iter->cd_dyn_vert, iter->bm_vert)->origmask;
- }
- else {
- orig_data->mask = orig_data->vmasks[iter->i];
- }
+ orig_data->mask = mv->origmask;
}
}
@@ -2547,7 +2555,7 @@ static void paint_mesh_restore_co_task_cb(void *__restrict userdata,
SCULPT_orig_vert_data_unode_init(&orig_data, data->ob, unode);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
if (orig_data.unode->type == SCULPT_UNDO_COORDS) {
copy_v3_v3(vd.co, orig_data.co);
@@ -4050,20 +4058,25 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata,
}
#endif
- SCULPT_bmesh_four_neighbor_average(ss,
- avg,
- direction2,
- vd.bm_vert,
- data->rake_projection,
- check_fsets,
- data->cd_temp,
- data->cd_dyn_vert);
+ int steps = data->do_origco ? 2 : 1;
- sub_v3_v3v3(val, avg, vd.co);
+ for (int step = 0; step < steps; step++) {
+ float *co = step ? (float *)SCULPT_vertex_origco_get(ss, vd.vertex) : vd.co;
- madd_v3_v3v3fl(val, vd.co, val, fade);
+ SCULPT_bmesh_four_neighbor_average(ss,
+ avg,
+ direction2,
+ vd.bm_vert,
+ data->rake_projection,
+ check_fsets,
+ data->cd_temp,
+ data->cd_dyn_vert,
+ step);
- SCULPT_clip(sd, ss, vd.co, val);
+ sub_v3_v3v3(val, avg, co);
+ madd_v3_v3v3fl(val, co, val, fade);
+ SCULPT_clip(sd, ss, co, val);
+ }
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
@@ -4146,7 +4159,8 @@ static void bmesh_topology_rake(
.strength = factor,
.cd_temp = cd_temp,
.cd_dyn_vert = ss->cd_dyn_vert,
- .rake_projection = brush->topology_rake_projection};
+ .rake_projection = brush->topology_rake_projection,
+ .do_origco = SCULPT_stroke_needs_original(brush)};
TaskParallelSettings settings;
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
@@ -4220,7 +4234,7 @@ static void do_mask_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
do_mask_brush_draw(sd, ob, nodes, totnode);
break;
case BRUSH_MASK_SMOOTH:
- SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, true, 0.0f);
+ SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, true, 0.0f, false);
break;
}
}
@@ -4537,7 +4551,7 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata,
const int thread_id = BLI_task_parallel_thread_id(tls);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
continue;
@@ -4620,7 +4634,7 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata,
const int thread_id = BLI_task_parallel_thread_id(tls);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
continue;
@@ -4789,7 +4803,7 @@ static void do_topology_relax_task_cb_ex(void *__restrict userdata,
const int thread_id = BLI_task_parallel_thread_id(tls);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
continue;
@@ -5188,7 +5202,7 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata,
const bool grab_silhouette = brush->flag2 & BRUSH_GRAB_SILHOUETTE;
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
continue;
@@ -5289,7 +5303,7 @@ static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata,
&params, ss->cache->radius, force, 1.0f, brush->elastic_deform_volume_preservation);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
float final_disp[3];
switch (brush->elastic_deform_type) {
case BRUSH_ELASTIC_DEFORM_GRAB:
@@ -5740,7 +5754,7 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata,
const int thread_id = BLI_task_parallel_thread_id(tls);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
continue;
@@ -5813,7 +5827,7 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata,
const int thread_id = BLI_task_parallel_thread_id(tls);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
continue;
@@ -5916,7 +5930,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
const int thread_id = BLI_task_parallel_thread_id(tls);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) {
continue;
@@ -7710,11 +7724,18 @@ void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings
totnode,
brush->autosmooth_factor * (1.0f - ss->cache->pressure),
false,
- brush->autosmooth_projection);
+ brush->autosmooth_projection,
+ false);
}
else {
- SCULPT_smooth(
- sd, ob, nodes, totnode, brush->autosmooth_factor, false, brush->autosmooth_projection);
+ SCULPT_smooth(sd,
+ ob,
+ nodes,
+ totnode,
+ brush->autosmooth_factor,
+ false,
+ brush->autosmooth_projection,
+ false);
}
if (brush->autosmooth_radius_factor != 1.0f) {
diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c
index c77d9c92a2e..2e65c7afe65 100644
--- a/source/blender/editors/sculpt_paint/sculpt_boundary.c
+++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c
@@ -1589,7 +1589,7 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
continue;
}
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
continue;
@@ -1638,7 +1638,7 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
continue;
}
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
continue;
@@ -1684,7 +1684,7 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
continue;
}
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
continue;
@@ -1730,7 +1730,7 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
continue;
}
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
continue;
@@ -1781,7 +1781,7 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
continue;
}
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
continue;
@@ -1827,7 +1827,7 @@ static void do_boundary_brush_smooth_task_cb_ex(void *__restrict userdata,
continue;
}
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
continue;
@@ -1913,7 +1913,7 @@ static void SCULPT_boundary_autosmooth(SculptSession *ss, SculptBoundary *bounda
float sco[3];
SCULPT_neighbor_coords_average_interior(
- ss, sco, vd.vertex, ss->cache->brush->autosmooth_projection, NULL);
+ ss, sco, vd.vertex, ss->cache->brush->autosmooth_projection, NULL, false);
float *co = SCULPT_brush_deform_target_vertex_co_get(
ss, ss->cache->brush->deform_target, &vd);
@@ -1952,7 +1952,7 @@ static void SCULPT_boundary_build_smoothco(SculptSession *ss, SculptBoundary *bo
float sco[3];
- SCULPT_neighbor_coords_average_interior(ss, sco, vd.vertex, projection, NULL);
+ SCULPT_neighbor_coords_average_interior(ss, sco, vd.vertex, projection, NULL, false);
float *co = SCULPT_brush_deform_target_vertex_co_get(
ss, ss->cache->brush->deform_target, &vd);
diff --git a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
index 31919b82a82..888874941f7 100644
--- a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
@@ -768,6 +768,11 @@ void SCULPT_dynamic_topology_enable_ex(Main *bmain, Depsgraph *depsgraph, Scene
SCULPT_pbvh_clear(ob);
+ if (ss->mdyntopo_verts) {
+ MEM_freeN(ss->mdyntopo_verts);
+ ss->mdyntopo_verts = NULL;
+ }
+
ss->bm_smooth_shading = (scene->toolsettings->sculpt->flags & SCULPT_DYNTOPO_SMOOTH_SHADING) !=
0;
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.c b/source/blender/editors/sculpt_paint/sculpt_filter_color.c
index 6e204705953..dfb1f2e74dc 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.c
@@ -111,7 +111,7 @@ static void color_filter_task_cb(void *__restrict userdata,
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
float orig_color[3], final_color[4], hsv_color[3];
int hue;
float brightness, contrast, gain, delta, offset;
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
index e9d699d4f79..4e50b9fbd9b 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
@@ -303,7 +303,7 @@ static void mesh_filter_task_cb(void *__restrict userdata,
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
float orig_co[3], val[3], avg[3], normal[3], disp[3], disp2[3], transform[3][3], final_pos[3];
float fade = vd.mask ? *vd.mask : 0.0f;
fade = 1.0f - fade;
@@ -334,7 +334,7 @@ static void mesh_filter_task_cb(void *__restrict userdata,
switch (filter_type) {
case MESH_FILTER_SMOOTH:
fade = clamp_f(fade, -1.0f, 1.0f);
- SCULPT_neighbor_coords_average_interior(ss, avg, vd.vertex, 0.0f, NULL);
+ SCULPT_neighbor_coords_average_interior(ss, avg, vd.vertex, 0.0f, NULL, false);
sub_v3_v3v3(val, avg, orig_co);
madd_v3_v3v3fl(val, orig_co, val, fade);
sub_v3_v3v3(disp, val, orig_co);
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 131fbf4cf1c..5448ab5746b 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -217,8 +217,9 @@ void SCULPT_vertex_neighbors_get(const struct SculptSession *ss,
SculptVertRef SCULPT_active_vertex_get(SculptSession *ss);
const float *SCULPT_active_vertex_co_get(SculptSession *ss);
-const float *SCULPT_vertex_origco_get(SculptSession *ss, SculptVertRef vertex);
+float *SCULPT_vertex_origco_get(SculptSession *ss, SculptVertRef vertex);
void SCULPT_active_vertex_normal_get(SculptSession *ss, float normal[3]);
+MDynTopoVert *SCULPT_vertex_get_mdyntopo(SculptSession *ss, SculptVertRef vertex);
/* Returns PBVH deformed vertices array if shape keys or deform modifiers are used, otherwise
* returns mesh original vertices array. */
@@ -646,7 +647,8 @@ void SCULPT_bmesh_four_neighbor_average(SculptSession *ss,
float projection,
bool check_fsets,
int cd_temp,
- int cd_dyn_vert);
+ int cd_dyn_vert,
+ bool do_origco);
/* Smoothing api */
void SCULPT_neighbor_coords_average(
@@ -659,7 +661,8 @@ void SCULPT_neighbor_coords_average_interior(SculptSession *ss,
float result[3],
SculptVertRef index,
float projection,
- SculptCustomLayer *bound_scl);
+ SculptCustomLayer *bound_scl,
+ bool do_origco);
void SCULPT_smooth_vcol_boundary(
Sculpt *sd, Object *ob, PBVHNode **nodes, const int totnode, float bstrength);
@@ -670,7 +673,8 @@ void SCULPT_smooth(Sculpt *sd,
const int totnode,
float bstrength,
const bool smooth_mask,
- float projection);
+ float projection,
+ bool do_origco);
void SCULPT_do_smooth_brush(
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float projection);
@@ -923,6 +927,7 @@ typedef struct SculptThreadedTaskData {
float smooth_projection;
float rake_projection;
SculptCustomLayer *scl, *scl2;
+ bool do_origco;
} SculptThreadedTaskData;
/*************** Brush testing declarations ****************/
@@ -1446,11 +1451,13 @@ void SCULPT_cache_calc_brushdata_symm(StrokeCache *cache,
const float angle);
void SCULPT_cache_free(StrokeCache *cache);
+void SCULPT_vertex_check_origdata(SculptSession *ss, SculptVertRef vertex);
+
void SCULPT_orig_vert_data_init(SculptOrigVertData *data,
Object *ob,
PBVHNode *node,
SculptUndoType type);
-void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, PBVHVertexIter *iter);
+void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, SculptVertRef vertex);
void SCULPT_orig_vert_data_unode_init(SculptOrigVertData *data,
Object *ob,
struct SculptUndoNode *unode);
@@ -1692,3 +1699,13 @@ void SCULPT_replay_log_append(struct Sculpt *sd, struct SculptSession *ss, struc
void SCULPT_replay_test(void);
#endif
+
+#define SCULPT_stroke_needs_original(brush) \
+ ELEM(brush->sculpt_tool, \
+ SCULPT_TOOL_DRAW_SHARP, \
+ SCULPT_TOOL_GRAB, \
+ SCULPT_TOOL_ROTATE, \
+ SCULPT_TOOL_THUMB, \
+ SCULPT_TOOL_ELASTIC_DEFORM, \
+ SCULPT_TOOL_BOUNDARY, \
+ SCULPT_TOOL_POSE)
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
index a294108c228..e86c5b9ecb9 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
@@ -140,7 +140,7 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata,
IMB_colormanagement_srgb_to_scene_linear_v3(brush_color);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
bool affect_vertex = false;
float distance_to_stroke_location = 0.0f;
diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c
index 07f0f763ff9..09517820485 100644
--- a/source/blender/editors/sculpt_paint/sculpt_pose.c
+++ b/source/blender/editors/sculpt_paint/sculpt_pose.c
@@ -175,7 +175,7 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata,
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
float total_disp[3];
zero_v3(total_disp);
diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c
index 33a6fadde7f..293702f33b0 100644
--- a/source/blender/editors/sculpt_paint/sculpt_smooth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c
@@ -78,9 +78,17 @@ void SCULPT_neighbor_coords_average_interior(SculptSession *ss,
float result[3],
SculptVertRef vertex,
float projection,
- SculptCustomLayer *bound_scl)
+ SculptCustomLayer *bound_scl,
+ bool do_origco)
{
float avg[3] = {0.0f, 0.0f, 0.0f};
+
+ MDynTopoVert *mv = SCULPT_vertex_get_mdyntopo(ss, vertex);
+
+ if (do_origco) {
+ SCULPT_vertex_check_origdata(ss, vertex);
+ }
+
float total = 0.0f;
int neighbor_count = 0;
bool check_fsets = ss->cache->brush->flag2 & BRUSH_SMOOTH_PRESERVE_FACE_SETS;
@@ -97,11 +105,16 @@ void SCULPT_neighbor_coords_average_interior(SculptSession *ss,
const SculptBoundaryType is_boundary = SCULPT_vertex_is_boundary(ss, vertex, bflag);
- const float *co = SCULPT_vertex_co_get(ss, vertex);
+ const float *co = do_origco ? mv->origco : SCULPT_vertex_co_get(ss, vertex);
float no[3];
if (true || projection > 0.0f) {
- SCULPT_vertex_normal_get(ss, vertex, no);
+ if (do_origco) {
+ copy_v3_v3(no, mv->origno);
+ }
+ else {
+ SCULPT_vertex_normal_get(ss, vertex, no);
+ }
}
const bool weighted = (ss->cache->brush->flag2 & BRUSH_SMOOTH_USE_AREA_WEIGHT) && !is_boundary;
@@ -131,6 +144,16 @@ void SCULPT_neighbor_coords_average_interior(SculptSession *ss,
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) {
+ MDynTopoVert *mv2 = SCULPT_vertex_get_mdyntopo(ss, ni.vertex);
+ const float *co2;
+
+ if (!do_origco || mv2->stroke_id != ss->stroke_id) {
+ co2 = SCULPT_vertex_co_get(ss, ni.vertex);
+ }
+ else {
+ co2 = mv2->origco;
+ }
+
neighbor_count++;
float tmp[3], w;
@@ -186,12 +209,12 @@ void SCULPT_neighbor_coords_average_interior(SculptSession *ss,
w *= slide_fset;
- sub_v3_v3v3(t, SCULPT_vertex_co_get(ss, ni.vertex), co);
+ sub_v3_v3v3(t, co2, co);
madd_v3_v3v3fl(tmp, co, no, dot_v3v3(t, no));
ok = true;
}
else if (final_boundary) {
- copy_v3_v3(tmp, SCULPT_vertex_co_get(ss, ni.vertex));
+ copy_v3_v3(tmp, co2);
ok = true;
do_diffuse = false;
}
@@ -200,7 +223,7 @@ void SCULPT_neighbor_coords_average_interior(SculptSession *ss,
}
}
else {
- copy_v3_v3(tmp, SCULPT_vertex_co_get(ss, ni.vertex));
+ copy_v3_v3(tmp, co2);
ok = true;
}
@@ -210,7 +233,7 @@ void SCULPT_neighbor_coords_average_interior(SculptSession *ss,
makes more rounded edges.
*/
- copy_v3_v3(tmp, SCULPT_vertex_co_get(ss, ni.vertex));
+ copy_v3_v3(tmp, co2);
ok = true;
float len = len_v3v3(co, tmp);
@@ -228,7 +251,13 @@ void SCULPT_neighbor_coords_average_interior(SculptSession *ss,
btot += w2;
float no2[3];
- SCULPT_vertex_normal_get(ss, ni.vertex, no2);
+
+ if (!do_origco || mv2->stroke_id != ss->stroke_id) {
+ SCULPT_vertex_normal_get(ss, ni.vertex, no2);
+ }
+ else {
+ copy_v3_v3(no2, mv2->origno);
+ }
float radius = ss->cache->radius * 10.0f;
@@ -280,13 +309,13 @@ void SCULPT_neighbor_coords_average_interior(SculptSession *ss,
/* Do not modify corner vertices. */
if (neighbor_count <= 2 && is_boundary) {
- copy_v3_v3(result, SCULPT_vertex_co_get(ss, vertex));
+ copy_v3_v3(result, co);
return;
}
/* Avoid division by 0 when there are no neighbors. */
if (total == 0.0f) {
- copy_v3_v3(result, SCULPT_vertex_co_get(ss, vertex));
+ copy_v3_v3(result, co);
return;
}
@@ -475,11 +504,12 @@ void SCULPT_bmesh_four_neighbor_average(SculptSession *ss,
float projection,
bool check_fsets,
int cd_temp,
- int cd_dyn_vert)
+ int cd_dyn_vert,
+ bool do_origco)
{
-
float avg_co[3] = {0.0f, 0.0f, 0.0f};
float tot_co = 0.0f;
+
float buckets[8] = {0};
// zero_v3(direction);
@@ -493,6 +523,17 @@ void SCULPT_bmesh_four_neighbor_average(SculptSession *ss,
const bool weighted = (ss->cache->brush->flag2 & BRUSH_SMOOTH_USE_AREA_WEIGHT);
float *areas;
+ SCULPT_vertex_check_origdata(ss, (SculptVertRef){.i = (intptr_t)v});
+
+ if (do_origco) {
+ // SCULPT_vertex_check_origdata(ss, (SculptVertRef){.i = (intptr_t)v});
+ madd_v3_v3fl(direction, mv->origno, -dot_v3v3(mv->origno, direction));
+ normalize_v3(direction);
+ }
+
+ float *co1 = do_origco ? mv->origco : v->co;
+ float *no1 = do_origco ? mv->origno : v->no;
+
if (weighted) {
SculptVertRef vertex = {.i = (intptr_t)v};
@@ -508,12 +549,12 @@ void SCULPT_bmesh_four_neighbor_average(SculptSession *ss,
copy_v3_v3(dir, direction);
}
else {
- closest_vec_to_perp(dir, direction, v->no, buckets, 1.0f); // col[3]);
+ closest_vec_to_perp(dir, direction, no1, buckets, 1.0f); // col[3]);
}
float totdir3 = 0.0f;
- const float selfw = (float)mv->valence * 0.25f;
+ const float selfw = (float)mv->valence * 0.0025f;
madd_v3_v3fl(dir3, direction, selfw);
totdir3 += selfw;
@@ -538,6 +579,18 @@ void SCULPT_bmesh_four_neighbor_average(SculptSession *ss,
//}
MDynTopoVert *mv2 = BKE_PBVH_DYNVERT(cd_dyn_vert, v_other);
+ float *co2;
+ float *no2;
+
+ if (!do_origco || mv2->stroke_id != ss->stroke_id) {
+ co2 = v_other->co;
+ no2 = v_other->no;
+ }
+ else {
+ co2 = mv2->origco;
+ no2 = mv2->origno;
+ }
+
// bool bound = (mv2->flag &
// (DYNVERT_BOUNDARY)); // | DYNVERT_FSET_BOUNDARY | DYNVERT_SHARP_BOUNDARY));
// bool bound2 = (mv2->flag &
@@ -552,8 +605,8 @@ void SCULPT_bmesh_four_neighbor_average(SculptSession *ss,
if (bound) {
had_bound = true;
- sub_v3_v3v3(dir2, v_other->co, v->co);
- madd_v3_v3fl(dir2, v->no, -dot_v3v3(v->no, dir2));
+ sub_v3_v3v3(dir2, co2, co1);
+ madd_v3_v3fl(dir2, no1, -dot_v3v3(no1, dir2));
normalize_v3(dir2);
dirw = 100000.0f;
}
@@ -566,7 +619,7 @@ void SCULPT_bmesh_four_neighbor_average(SculptSession *ss,
}
}
- closest_vec_to_perp(dir, dir2, v->no, buckets, bucketw); // col2[3]);
+ closest_vec_to_perp(dir, dir2, no1, buckets, bucketw); // col2[3]);
madd_v3_v3fl(dir3, dir2, dirw);
totdir3 += dirw;
@@ -577,9 +630,9 @@ void SCULPT_bmesh_four_neighbor_average(SculptSession *ss,
}
float vec[3];
- sub_v3_v3v3(vec, v_other->co, v->co);
+ sub_v3_v3v3(vec, co2, co1);
- madd_v3_v3fl(vec, v->no, -dot_v3v3(vec, v->no) * projection);
+ madd_v3_v3fl(vec, no1, -dot_v3v3(vec, no1) * projection);
normalize_v3(vec);
/* fac is a measure of how orthogonal or parallel the edge is
@@ -610,7 +663,7 @@ void SCULPT_bmesh_four_neighbor_average(SculptSession *ss,
fac *= areas[area_i];
}
- madd_v3_v3fl(avg_co, v_other->co, fac);
+ madd_v3_v3fl(avg_co, co2, fac);
tot_co += fac;
}
@@ -620,14 +673,19 @@ void SCULPT_bmesh_four_neighbor_average(SculptSession *ss,
/* Preserve volume. */
float vec[3];
- sub_v3_v3(avg, v->co);
- mul_v3_v3fl(vec, v->no, dot_v3v3(avg, v->no) * projection);
+ sub_v3_v3(avg, co1);
+ mul_v3_v3fl(vec, no1, dot_v3v3(avg, no1) * projection);
sub_v3_v3(avg, vec);
- add_v3_v3(avg, v->co);
+ add_v3_v3(avg, co1);
}
else {
// zero_v3(avg);
- copy_v3_v3(avg, v->co);
+ copy_v3_v3(avg, co1);
+ }
+
+ // do not update in do_origco
+ if (do_origco) {
+ return;
}
if (totdir3 > 0.0f) {
@@ -658,7 +716,7 @@ void SCULPT_bmesh_four_neighbor_average(SculptSession *ss,
}
// negate_v3(col);
- vec_transform(col, v->no, bi);
+ vec_transform(col, no1, bi);
// negate_v3(col);
}
}
@@ -1077,10 +1135,16 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata,
// continue;
//}
- SCULPT_neighbor_coords_average_interior(ss, avg, vd.vertex, projection, bound_scl);
- sub_v3_v3v3(val, avg, vd.co);
- madd_v3_v3v3fl(val, vd.co, val, fade);
- SCULPT_clip(sd, ss, vd.co, val);
+ int steps = data->do_origco ? 2 : 1;
+ for (int step = 0; step < steps; step++) {
+ float *co = step ? (float *)SCULPT_vertex_origco_get(ss, vd.vertex) : vd.co;
+
+ SCULPT_neighbor_coords_average_interior(ss, avg, vd.vertex, projection, bound_scl, step);
+
+ sub_v3_v3v3(val, avg, co);
+ madd_v3_v3v3fl(val, co, val, fade);
+ SCULPT_clip(sd, ss, co, val);
+ }
}
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
@@ -1159,7 +1223,8 @@ void SCULPT_smooth(Sculpt *sd,
const int totnode,
float bstrength,
const bool smooth_mask,
- float projection)
+ float projection,
+ bool do_origco)
{
SculptSession *ss = ob->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
@@ -1221,15 +1286,18 @@ void SCULPT_smooth(Sculpt *sd,
for (iteration = 0; iteration <= count; iteration++) {
const float strength = (iteration != count) ? 1.0f : last;
- SculptThreadedTaskData data = {.sd = sd,
- .ob = ob,
- .brush = brush,
- .nodes = nodes,
- .smooth_mask = smooth_mask,
- .strength = strength,
- .smooth_projection = projection,
- .scl = have_scl ? &scl : NULL,
- .scl2 = bound_scl};
+ SculptThreadedTaskData data = {
+ .sd = sd,
+ .ob = ob,
+ .brush = brush,
+ .nodes = nodes,
+ .smooth_mask = smooth_mask,
+ .strength = strength,
+ .smooth_projection = projection,
+ .scl = have_scl ? &scl : NULL,
+ .scl2 = bound_scl,
+ .do_origco = SCULPT_stroke_needs_original(ss->cache->brush),
+ };
TaskParallelSettings settings;
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
@@ -1263,7 +1331,7 @@ void SCULPT_do_smooth_brush(
}
else {
/* Regular mode, smooth. */
- SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, false, projection);
+ SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, false, projection, false);
}
}
@@ -1350,7 +1418,7 @@ static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex(
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
continue;
diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.c b/source/blender/editors/sculpt_paint/sculpt_transform.c
index 8d9497f6bef..61ea43efd66 100644
--- a/source/blender/editors/sculpt_paint/sculpt_transform.c
+++ b/source/blender/editors/sculpt_paint/sculpt_transform.c
@@ -165,7 +165,7 @@ static void sculpt_transform_task_cb(void *__restrict userdata,
SCULPT_undo_push_node(data->ob, node, SCULPT_UNDO_COORDS);
BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
float transformed_co[3], orig_co[3], disp[3];
float *start_co;
float fade = vd.mask ? *vd.mask : 0.0f;
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 9df17c2c7e5..7a5bd81f358 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -1602,7 +1602,7 @@ static void sculpt_undo_store_coords(Object *ob, SculptUndoNode *unode)
}
if (ss->deform_modifiers_active) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
int index = BKE_pbvh_vertex_index_to_table(ss->pbvh, unode->index[vd.i]);