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-08-17 06:50:02 +0300
committerJoseph Eagar <joeedh@gmail.com>2021-08-17 06:50:02 +0300
commit9503751c83345b2941a4fc41dcc979ef456b0c5f (patch)
tree3fadb7567304a58ba233c32e017fb2f8f5f41bca /source/blender/editors
parentdcaba4c5e3494240464ed6cc6330f40c30ba0e0e (diff)
Sculpt dyntopo
* Added a limited "fast draw" mode to pbvh drawing that tries to limit data sent to the GPU. - Facesets and mask data are disabled. - Indexed mode is forced. - Does not work (at all) for multires. * Finally fixed some outstanding bmesh sculpt undo bugs: - Forgot to mark pbvh nodes to update their bounds, which produced a bug I had thought was caused by something else. - Hopefully fixed a long-standing occasional memory corruption bug.
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c9
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c68
2 files changed, 43 insertions, 34 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index b3fcb9155f3..04db16d4516 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -1305,19 +1305,20 @@ static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext)
MEM_freeN(looptris);
- if (sgcontext->ss && sgcontext->ss->bm) { //rebuild pbvh
+ if (sgcontext->ss && sgcontext->ss->bm) { // rebuild pbvh
BKE_pbvh_free(sgcontext->ss->pbvh);
sgcontext->ss->pbvh = BKE_pbvh_new();
BKE_pbvh_build_bmesh(sgcontext->ss->pbvh,
sgcontext->ss->bm,
- false,
+ sgcontext->ss->bm_smooth_shading,
sgcontext->ss->bm_log,
sgcontext->ss->cd_vert_node_offset,
sgcontext->ss->cd_face_node_offset,
- sgcontext->ss->cd_dyn_vert);
+ sgcontext->ss->cd_dyn_vert,
+ sgcontext->ss->fast_draw);
}
- else { //save result to mesh
+ else { // save result to mesh
Mesh *result = BKE_mesh_from_bmesh_nomain(bm,
(&(struct BMeshToMeshParams){
.calc_object_remap = false,
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 3e5aa90a6ba..1cc928525ec 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -435,6 +435,8 @@ typedef struct BmeshUndoData {
bool balance_pbvh;
int cd_face_node_offset, cd_vert_node_offset;
int cd_dyn_vert;
+ bool regen_all_unique_verts;
+ bool is_redo;
} BmeshUndoData;
static void bmesh_undo_on_vert_kill(BMVert *v, void *userdata)
@@ -448,29 +450,17 @@ static void bmesh_undo_on_vert_kill(BMVert *v, void *userdata)
data->do_full_recalc = true;
return;
}
- else {
- int ni = BM_ELEM_CD_GET_INT(v, data->cd_vert_node_offset);
-
- /*
- regenerate bm_unique_verts, which can end up with
- freed verts for some reason. I've run this through
- ASAN and fixed one likely cause, but it still happens.
- - joeedh
- */
- if (ni >= 0) {
- PBVHNode *node = BKE_pbvh_get_node(data->pbvh, ni);
- BKE_pbvh_bmesh_mark_node_regen(data->pbvh, node);
- }
- }
BKE_pbvh_bmesh_remove_vertex(data->pbvh, v, false);
data->balance_pbvh = true;
}
+
static void bmesh_undo_on_vert_add(BMVert *v, void *userdata)
{
BmeshUndoData *data = (BmeshUndoData *)userdata;
BM_ELEM_CD_SET_INT(v, data->cd_vert_node_offset, -1);
// data->do_full_recalc = true;
+
data->balance_pbvh = true;
MDynTopoVert *mv = BKE_PBVH_DYNVERT(data->cd_dyn_vert, v);
@@ -482,19 +472,13 @@ static void bmesh_undo_on_face_kill(BMFace *f, void *userdata)
BmeshUndoData *data = (BmeshUndoData *)userdata;
int ni = BM_ELEM_CD_GET_INT(f, data->cd_face_node_offset);
- /*
- regenerate bm_unique_verts, which can end up with
- freed verts for some reason. I've run this through
- ASAN and fixed one likely cause, but it still happens.
- - joeedh
- */
+ BKE_pbvh_bmesh_remove_face(data->pbvh, f, false);
+
if (ni >= 0) {
PBVHNode *node = BKE_pbvh_get_node(data->pbvh, ni);
BKE_pbvh_bmesh_mark_node_regen(data->pbvh, node);
}
- BKE_pbvh_bmesh_remove_face(data->pbvh, f, false);
-
// data->do_full_recalc = true;
data->balance_pbvh = true;
}
@@ -521,22 +505,36 @@ static void bmesh_undo_full_mesh(void *userdata)
data->do_full_recalc = true;
}
-static void bmesh_undo_on_vert_change(BMVert *v, void *userdata, void *old_customdata)
+ATTR_NO_OPT static void bmesh_undo_on_vert_change(BMVert *v, void *userdata, void *old_customdata)
{
BmeshUndoData *data = (BmeshUndoData *)userdata;
if (!old_customdata) {
BM_ELEM_CD_SET_INT(v, data->cd_vert_node_offset, -1);
+ data->regen_all_unique_verts = true;
return;
}
- BM_ELEM_CD_SET_INT(v, data->cd_vert_node_offset, -1);
+ BMElem h;
+ h.head.data = old_customdata;
+
+ int ni = BM_ELEM_CD_GET_INT(&h, data->cd_vert_node_offset);
+
+ // attempt to find old node
+ PBVHNode *node = BKE_pbvh_get_node_leaf_safe(data->pbvh, ni);
+ if (node) {
+ // BKE_pbvh_bmesh_mark_node_regen(data->pbvh, node);
+ BKE_pbvh_node_mark_update(node);
+ // BM_ELEM_CD_SET_INT(v, data->cd_vert_node_offset, -1);
+ }
+ else {
+ BM_ELEM_CD_SET_INT(v, data->cd_vert_node_offset, -1);
+ data->regen_all_unique_verts = true;
+ }
+
return;
// preserve pbvh node references
- BMVert h;
- h.head.data = old_customdata;
-
int oldnode_i = BM_ELEM_CD_GET_INT(&h, data->cd_vert_node_offset);
BM_ELEM_CD_SET_INT(v, data->cd_vert_node_offset, oldnode_i);
@@ -563,7 +561,9 @@ static void sculpt_undo_bmesh_restore_generic(SculptUndoNode *unode, Object *ob,
false,
ss->cd_face_node_offset,
ss->cd_vert_node_offset,
- ss->cd_dyn_vert};
+ ss->cd_dyn_vert,
+ false,
+ !unode->applied};
BMLogCallbacks callbacks = {bmesh_undo_on_vert_add,
bmesh_undo_on_vert_kill,
@@ -589,11 +589,17 @@ static void sculpt_undo_bmesh_restore_generic(SculptUndoNode *unode, Object *ob,
int totnode;
PBVHNode **nodes;
+ BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
+
+ if (data.regen_all_unique_verts) {
+ for (int i = 0; i < totnode; i++) {
+ BKE_pbvh_bmesh_mark_node_regen(ss->pbvh, nodes[i]);
+ }
+ }
+
BKE_pbvh_bmesh_regen_node_verts(ss->pbvh);
pbvh_bmesh_check_nodes(ss->pbvh);
- BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
-
TaskParallelSettings settings;
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(
@@ -608,6 +614,8 @@ static void sculpt_undo_bmesh_restore_generic(SculptUndoNode *unode, Object *ob,
if (data.balance_pbvh) {
BKE_pbvh_bmesh_after_stroke(ss->pbvh);
}
+
+ BKE_pbvh_update_bounds(ss->pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw);
}
else {
SCULPT_pbvh_clear(ob);