[Bf-blender-cvs] [3df335d330a] temp_bmesh_multires: Sculpt dyntopo:
Joseph Eagar
noreply at git.blender.org
Tue Sep 14 04:28:08 CEST 2021
Commit: 3df335d330a694269a9ceefb7234a00c69ca4be9
Author: Joseph Eagar
Date: Mon Sep 13 19:24:21 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB3df335d330a694269a9ceefb7234a00c69ca4be9
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.
===================================================================
M source/blender/blenkernel/BKE_paint.h
M source/blender/blenkernel/BKE_pbvh.h
M source/blender/blenkernel/intern/customdata.c
M source/blender/blenkernel/intern/dyntopo.c
M source/blender/blenkernel/intern/paint.c
M source/blender/blenkernel/intern/pbvh.c
M source/blender/blenkernel/intern/pbvh_bmesh.c
M source/blender/blenkernel/intern/pbvh_intern.h
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/editors/sculpt_paint/sculpt_boundary.c
M source/blender/editors/sculpt_paint/sculpt_dyntopo.c
M source/blender/editors/sculpt_paint/sculpt_filter_color.c
M source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
M source/blender/editors/sculpt_paint/sculpt_intern.h
M source/blender/editors/sculpt_paint/sculpt_paint_color.c
M source/blender/editors/sculpt_paint/sculpt_pose.c
M source/blender/editors/sculpt_paint/sculpt_smooth.c
M source/blender/editors/sculpt_paint/sculpt_transform.c
M source/blender/editors/sculpt_paint/sculpt_undo.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 53d59c42a81..22362b34548 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -34,6 +34,7 @@
extern "C" {
#endif
+struct MDynTopoVert;
struct BMFace;
struct BMesh;
struct BlendDataReader;
@@ -658,6 +659,8 @@ typedef struct SculptSession {
int stroke_id, boundary_symmetry;
bool fast_draw; // hides facesets/masks and forces smooth to save GPU bandwidth
+ struct MDynTopoVert *mdyntopo_verts; // for non-bmesh
+ int mdyntopo_verts_size;
} SculptSession;
void BKE_sculptsession_free(struct Object *ob);
@@ -665,6 +668,7 @@ void BKE_sculptsession_free_deformMats(struct SculptSession *ss);
void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss);
void BKE_sculptsession_bm_to_me(struct Object *ob, bool reorder);
void BKE_sculptsession_bm_to_me_for_render(struct Object *object);
+bool BKE_sculptsession_check_mdyntopo(SculptSession *ss, int totvert);
/* Create new color layer on object if it doesn't have one and if experimental feature set has
* sculpt vertex color enabled. Returns truth if new layer has been added, false otherwise. */
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 77da0616b69..72c48d21af7 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -269,6 +269,7 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
const struct MPoly *mpoly,
const struct MLoop *mloop,
struct MVert *verts,
+ struct MDynTopoVert *mdyntopo_verts,
int totvert,
struct CustomData *vdata,
struct CustomData *ldata,
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 0ac6c9a42ce..b53ed71070c 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -1552,7 +1552,8 @@ static void layerDynTopoVert_interp(
float mul = 1.0f / totweight;
mul_v3_fl(co, mul);
- mul_v3_fl(no, mul);
+ normalize_v3(no);
+
mul_v4_fl(color, mul);
origmask *= mul;
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 2585959bdae..7e02131d2c6 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -560,10 +560,26 @@ static BMEdge *bmesh_edge_create_log(PBVH *pbvh, BMVert *v1, BMVert *v2, BMEdge
BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v, float fac)
{
float co[3];
+ float origco[3], origco1[3];
+ float origno1[3];
float tan[3];
float tot = 0.0;
+ MDynTopoVert *mv1 = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v);
+
+ if (mv1->stroke_id != pbvh->stroke_id) {
+ copy_v3_v3(origco1, v->co);
+ copy_v3_v3(origno1, v->no);
+ }
+ else {
+ copy_v3_v3(origco1, mv1->origco);
+ copy_v3_v3(origno1, dot_v3v3(mv1->origno, mv1->origno) == 0.0f ? v->no : mv1->origno);
+ }
+
+ // BKE_pbvh_bmesh_check_origdata(pbvh, v, pbvh->stroke_id);
+
zero_v3(co);
+ zero_v3(origco);
// this is a manual edge walk
@@ -572,11 +588,14 @@ BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v, float fac)
return;
}
- pbvh_check_vert_boundary(pbvh, v);
+ if (mv1->flag & DYNVERT_NEED_BOUNDARY) {
+ return; // can't update boundary in thread
+ }
+
+ // pbvh_check_vert_boundary(pbvh, v);
const int cd_dyn_vert = pbvh->cd_dyn_vert;
- MDynTopoVert *mv1 = BKE_PBVH_DYNVERT(cd_dyn_vert, v);
const bool bound1 = mv1->flag & DYNVERT_SMOOTH_BOUNDARY;
if (mv1->flag & DYNVERT_SMOOTH_CORNER) {
@@ -601,6 +620,18 @@ BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v, float fac)
madd_v3_v3fl(tan, v->no, -d * 0.99f);
add_v3_v3(co, tan);
+
+ if (mv2->stroke_id == pbvh->stroke_id) {
+ sub_v3_v3v3(tan, mv2->origco, origco1);
+ }
+ else {
+ sub_v3_v3v3(tan, v2->co, origco1);
+ }
+
+ d = dot_v3v3(tan, origno1);
+ madd_v3_v3fl(tan, origno1, -d * 0.99f);
+ add_v3_v3(origco, tan);
+
tot += 1.0f;
} while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
@@ -610,12 +641,32 @@ BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v, float fac)
}
mul_v3_fl(co, 1.0f / tot);
- float x = v->co[0], y = v->co[1], z = v->co[2];
+ mul_v3_fl(origco, 1.0f / tot);
+
+ volatile float x = v->co[0], y = v->co[1], z = v->co[2];
+ volatile float nx = x + co[0] * fac, ny = y + co[1] * fac, nz = z + co[2] * fac;
// conflicts here should be pretty rare.
- atomic_cas_float(&v->co[0], x, x + co[0] * fac);
- atomic_cas_float(&v->co[1], y, y + co[1] * fac);
- atomic_cas_float(&v->co[2], z, z + co[2] * fac);
+ atomic_cas_float(&v->co[0], x, nx);
+ atomic_cas_float(&v->co[1], y, ny);
+ atomic_cas_float(&v->co[2], z, nz);
+
+ // conflicts here should be pretty rare.
+ x = mv1->origco[0];
+ y = mv1->origco[1];
+ z = mv1->origco[2];
+
+ nx = x + origco[0] * fac;
+ ny = y + origco[1] * fac;
+ nz = z + origco[2] * fac;
+
+ atomic_cas_float(&mv1->origco[0], x, nx);
+ atomic_cas_float(&mv1->origco[1], y, ny);
+ atomic_cas_float(&mv1->origco[2], z, nz);
+
+ volatile int stroke_id = mv1->stroke_id;
+
+ // atomic_cas_int32(&mv1->stroke_id, stroke_id, pbvh->stroke_id);
}
static void pbvh_kill_vert(PBVH *pbvh, BMVert *v)
@@ -3624,8 +3675,10 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
// snap customdata
if (snap) {
int ni_conn = BM_ELEM_CD_GET_INT(v_conn, pbvh->cd_vert_node_offset);
+
const float v_ws[2] = {0.5f, 0.5f};
const void *v_blocks[2] = {v_del->head.data, v_conn->head.data};
+
CustomData_bmesh_interp(&pbvh->bm->vdata, v_blocks, v_ws, NULL, 2, v_conn->head.data);
BM_ELEM_CD_SET_INT(v_conn, pbvh->cd_vert_node_offset, ni_conn);
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 3ed146c38a8..45abd6a96c6 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -85,6 +85,8 @@ void SCULPT_on_sculptsession_bmesh_free(SculptSession *ss);
void SCULPT_dyntopo_node_layers_add(SculptSession *ss);
BMesh *SCULPT_dyntopo_empty_bmesh();
+static void init_mdyntopo_layer(SculptSession *ss, int totvert);
+
static void palette_init_data(ID *id)
{
Palette *palette = (Palette *)id;
@@ -1483,6 +1485,11 @@ void BKE_sculptsession_free(Object *ob)
if (ob && ob->sculpt) {
SculptSession *ss = ob->sculpt;
+ if (ss->mdyntopo_verts) {
+ MEM_freeN(ss->mdyntopo_verts);
+ ss->mdyntopo_verts = NULL;
+ }
+
if (ss->bm_log && BM_log_free(ss->bm_log, true)) {
ss->bm_log = NULL;
}
@@ -1671,7 +1678,6 @@ static void sculpt_update_object(Depsgraph *depsgraph,
}
ss->shapekey_active = (mmd == NULL) ? BKE_keyblock_from_object(ob) : NULL;
-
ss->boundary_symmetry = (int)BKE_get_fset_boundary_symflag(ob);
/* NOTE: Weight pPaint require mesh info for loop lookup, but it never uses multires code path,
@@ -1724,6 +1730,7 @@ static void sculpt_update_object(Depsgraph *depsgraph,
ss->fast_draw = (scene->toolsettings->sculpt->flags & SCULPT_FAST_DRAW) != 0;
PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(depsgraph, ob);
+
BLI_assert(pbvh == ss->pbvh);
UNUSED_VARS_NDEBUG(pbvh);
@@ -2190,11 +2197,14 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
BKE_sculpt_sync_face_set_visibility(me, NULL);
+ BKE_sculptsession_check_mdyntopo(ob->sculpt, me->totvert);
+
BKE_pbvh_build_mesh(pbvh,
me,
me->mpoly,
me->mloop,
me->mvert,
+ ob->sculpt->mdyntopo_verts,
me->totvert,
&me->vdata,
&me->ldata,
@@ -2235,11 +2245,40 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg, bool respect
subdiv_ccg->grid_flag_mats,
subdiv_ccg->grid_hidden,
ob->sculpt->fast_draw);
+
+ BKE_sculptsession_check_mdyntopo(ob->sculpt, BKE_pbvh_get_grid_num_vertices(pbvh));
+
pbvh_show_mask_set(pbvh, ob->sculpt->show_mask);
pbvh_show_face_sets_set(pbvh, ob->sculpt->show_face_sets);
return pbvh;
}
+bool BKE_sculptsession_check_mdyntopo(SculptSession *ss, int totvert)
+{
+ if (!ss->bm && (!ss->mdyntopo_verts || totvert != ss->mdyntopo_verts_size)) {
+ init_mdyntopo_layer(ss, totvert);
+ return true;
+ }
+
+ return false;
+}
+
+static void init_mdyntopo_layer(SculptSession *ss, int totvert)
+{
+ if (ss->mdyntopo_verts) {
+ MEM_freeN(ss->mdyntopo_verts);
+ }
+
+ ss->mdyntopo_verts = MEM_calloc_arrayN(totvert, sizeof(*ss->mdyntopo_verts), "mdyntopo_verts");
+ ss->mdyntopo_verts_size = totvert;
+
+ MDynTopoVert *mv = ss->mdyntopo_verts;
+
+ for (int i = 0; i < totvert; i++, mv++) {
+ mv->flag = DYNVERT_NEED_BOUNDARY | DYNVERT_NEED_VALENCE | DYNVERT_NEED_DISK_SORT;
+ mv->stroke_id = -1;
+ }
+}
PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
{
if (ob == NULL || ob->sculpt == NULL) {
@@ -2331,6 +2370,9 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
}
else if (ob->type == OB_MESH) {
Mesh *me_eval_deform = object_eval->runtime.mesh_deform_eval;
+
+ BKE_sculptsession_check_mdyntopo(ob->sculpt, me_eval_deform->totvert);
+
pbvh = build_pbvh_from_regular_mesh(ob, me_eval_deform, respect_hide);
}
#endif
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 313e01ca1a1..fc25826e731 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -607,6 +607,8 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
const MPoly *mpoly,
const MLoop *mloop,
MVert *verts,
+ MDynTopoVert *mdyntopo_verts,
+
int totvert,
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list