[Bf-blender-cvs] [5e3d84eed79] sculpt-dev: Sculpt: fix multires crashing
Joseph Eagar
noreply at git.blender.org
Thu Sep 30 19:54:23 CEST 2021
Commit: 5e3d84eed792edf278b5b59b7843757d2a49d324
Author: Joseph Eagar
Date: Thu Sep 30 10:54:11 2021 -0700
Branches: sculpt-dev
https://developer.blender.org/rB5e3d84eed792edf278b5b59b7843757d2a49d324
Sculpt: fix multires crashing
===================================================================
M source/blender/blenkernel/BKE_paint.h
M source/blender/blenkernel/BKE_pbvh.h
M source/blender/blenkernel/intern/paint.c
M source/blender/blenkernel/intern/pbvh.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 31aa0b3d2b5..4700fd7fb9e 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -791,7 +791,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);
+bool BKE_sculptsession_check_mdyntopo(SculptSession *ss, struct PBVH *pbvh, 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 f4cb0dac6ed..f081b810733 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -135,6 +135,7 @@ struct MPoly;
struct MVert;
struct Mesh;
struct PBVH;
+struct MEdge;
struct PBVHNode;
struct SubdivCCG;
struct TaskParallelSettings;
@@ -933,6 +934,11 @@ void BKE_pbvh_update_vert_boundary_faces(int *face_sets,
struct MDynTopoVert *mdyntopo_verts,
struct MeshElemMap *pmap,
SculptVertRef vertex);
+void BKE_pbvh_update_vert_boundary_grids(PBVH *pbvh,
+ struct SubdivCCG *subdiv_ccg,
+ SculptVertRef vertex);
+
+void BKE_pbvh_set_mdyntopo_verts(PBVH *pbvh, struct MDynTopoVert *mdyntopoverts);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 61e83f4d090..e4d65963772 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -86,7 +86,7 @@ void SCULPT_dyntopo_node_layers_add(SculptSession *ss);
BMesh *SCULPT_dyntopo_empty_bmesh();
void SCULPT_undo_ensure_bmlog(Object *ob);
-static void init_mdyntopo_layer(SculptSession *ss, int totvert);
+static void init_mdyntopo_layer(SculptSession *ss, PBVH *pbvh, int totvert);
static void palette_init_data(ID *id)
{
@@ -2201,7 +2201,9 @@ static PBVH *build_pbvh_for_dynamic_topology(Object *ob)
return pbvh;
}
-static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool respect_hide)
+ATTR_NO_OPT static PBVH *build_pbvh_from_regular_mesh(Object *ob,
+ Mesh *me_eval_deform,
+ bool respect_hide)
{
SculptSession *ss = ob->sculpt;
Mesh *me = BKE_object_get_original_mesh(ob);
@@ -2228,7 +2230,7 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
false);
}
- BKE_sculptsession_check_mdyntopo(ob->sculpt, me->totvert);
+ BKE_sculptsession_check_mdyntopo(ob->sculpt, pbvh, me->totvert);
BKE_pbvh_build_mesh(pbvh,
me,
@@ -2277,24 +2279,24 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg, bool respect
subdiv_ccg->grid_hidden,
ob->sculpt->fast_draw);
- BKE_sculptsession_check_mdyntopo(ob->sculpt, BKE_pbvh_get_grid_num_vertices(pbvh));
+ BKE_sculptsession_check_mdyntopo(ob->sculpt, pbvh, 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)
+ATTR_NO_OPT bool BKE_sculptsession_check_mdyntopo(SculptSession *ss, PBVH *pbvh, int totvert)
{
if (!ss->bm && (!ss->mdyntopo_verts || totvert != ss->mdyntopo_verts_size)) {
- init_mdyntopo_layer(ss, totvert);
+ init_mdyntopo_layer(ss, pbvh, totvert);
return true;
}
return false;
}
-static void init_mdyntopo_layer(SculptSession *ss, int totvert)
+ATTR_NO_OPT static void init_mdyntopo_layer_faces(SculptSession *ss, PBVH *pbvh, int totvert)
{
if (ss->mdyntopo_verts) {
MEM_freeN(ss->mdyntopo_verts);
@@ -2303,6 +2305,8 @@ static void init_mdyntopo_layer(SculptSession *ss, int totvert)
ss->mdyntopo_verts = MEM_calloc_arrayN(totvert, sizeof(*ss->mdyntopo_verts), "mdyntopo_verts");
ss->mdyntopo_verts_size = totvert;
+ BKE_pbvh_set_mdyntopo_verts(pbvh, ss->mdyntopo_verts);
+
MDynTopoVert *mv = ss->mdyntopo_verts;
for (int i = 0; i < totvert; i++, mv++) {
@@ -2310,6 +2314,7 @@ static void init_mdyntopo_layer(SculptSession *ss, int totvert)
mv->stroke_id = -1;
SculptVertRef vertex = {.i = i};
+
BKE_pbvh_update_vert_boundary_faces(ss->face_sets,
ss->mvert,
ss->medge,
@@ -2320,6 +2325,40 @@ static void init_mdyntopo_layer(SculptSession *ss, int totvert)
vertex);
}
}
+
+ATTR_NO_OPT static void init_mdyntopo_layer_grids(SculptSession *ss, PBVH *pbvh, 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;
+
+ BKE_pbvh_set_mdyntopo_verts(pbvh, ss->mdyntopo_verts);
+
+ 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;
+
+ SculptVertRef vertex = {.i = i};
+
+ BKE_pbvh_update_vert_boundary_grids(pbvh, ss->subdiv_ccg, vertex);
+ }
+}
+
+ATTR_NO_OPT static void init_mdyntopo_layer(SculptSession *ss, PBVH *pbvh, int totvert)
+{
+ if (BKE_pbvh_type(pbvh) == PBVH_FACES) {
+ init_mdyntopo_layer_faces(ss, pbvh, totvert);
+ }
+ else if (BKE_pbvh_type(pbvh) == PBVH_GRIDS) {
+ init_mdyntopo_layer_grids(ss, pbvh, totvert);
+ }
+}
+
PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
{
if (ob == NULL || ob->sculpt == NULL) {
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index e1e07093ba8..dea4d48a6d8 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -4127,6 +4127,47 @@ void BKE_pbvh_set_symmetry(PBVH *pbvh, int symmetry, int boundary_symmetry)
}
}
+void BKE_pbvh_set_mdyntopo_verts(PBVH *pbvh, struct MDynTopoVert *mdyntopoverts)
+{
+ pbvh->mdyntopo_verts = mdyntopoverts;
+}
+
+void BKE_pbvh_update_vert_boundary_grids(PBVH *pbvh,
+ struct SubdivCCG *subdiv_ccg,
+ SculptVertRef vertex)
+{
+ MDynTopoVert *mv = pbvh->mdyntopo_verts + vertex.i;
+
+ int last_fset = 0;
+ int last_fset2 = 0;
+
+ mv->flag &= ~(DYNVERT_BOUNDARY | DYNVERT_FSET_BOUNDARY | DYNVERT_NEED_BOUNDARY |
+ DYNVERT_FSET_CORNER | DYNVERT_CORNER | DYNVERT_SEAM_BOUNDARY |
+ DYNVERT_SHARP_BOUNDARY | DYNVERT_SEAM_CORNER | DYNVERT_SHARP_CORNER);
+
+ int totsharp = 0, totseam = 0;
+ int visible = false;
+
+ int index = (int)vertex.i;
+
+ /* TODO: optimize this. We could fill #SculptVertexNeighborIter directly,
+ * maybe provide coordinate and mask pointers directly rather than converting
+ * back and forth between #CCGElem and global index. */
+ const CCGKey *key = BKE_pbvh_get_grid_key(pbvh);
+ const int grid_index = index / key->grid_area;
+ const int vertex_index = index - grid_index * key->grid_area;
+
+ SubdivCCGCoord coord = {.grid_index = grid_index,
+ .x = vertex_index % key->grid_size,
+ .y = vertex_index / key->grid_size};
+
+ SubdivCCGNeighbors neighbors;
+ BKE_subdiv_ccg_neighbor_coords_get(subdiv_ccg, &coord, false, &neighbors);
+
+ mv->valence = neighbors.size;
+ mv->flag &= ~DYNVERT_NEED_VALENCE;
+}
+
void BKE_pbvh_update_vert_boundary_faces(int *face_sets,
MVert *mvert,
MEdge *medge,
More information about the Bf-blender-cvs
mailing list