From 2cf21604c9130c56021525ed5af3f1fa59dcb19a Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Mon, 3 Oct 2022 16:12:41 -0700 Subject: Sculpt: implement Reveal All for PBVH_BMESH --- source/blender/editors/sculpt_paint/sculpt.c | 70 ++++++++++++++++++++-- .../editors/sculpt_paint/sculpt_face_set.cc | 49 +++++++++++++-- 2 files changed, 110 insertions(+), 9 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index c9d29b3ceb5..89998f19476 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -419,8 +419,15 @@ void SCULPT_face_visibility_all_invert(SculptSession *ss) ss->hide_poly[i] = !ss->hide_poly[i]; } break; - case PBVH_BMESH: + case PBVH_BMESH: { + BMIter iter; + BMFace *f; + + BM_ITER_MESH (f, &iter, ss->bm, BM_FACES_OF_MESH) { + BM_elem_flag_toggle(f, BM_ELEM_HIDDEN); + } break; + } } } @@ -432,8 +439,15 @@ void SCULPT_face_visibility_all_set(SculptSession *ss, bool visible) BLI_assert(ss->hide_poly != NULL); memset(ss->hide_poly, !visible, sizeof(bool) * ss->totfaces); break; - case PBVH_BMESH: + case PBVH_BMESH: { + BMIter iter; + BMFace *f; + + BM_ITER_MESH (f, &iter, ss->bm, BM_FACES_OF_MESH) { + BM_elem_flag_set(f, BM_ELEM_HIDDEN, !visible); + } break; + } } } @@ -475,8 +489,30 @@ bool SCULPT_vertex_all_faces_visible_get(const SculptSession *ss, PBVHVertRef ve } return true; } - case PBVH_BMESH: + case PBVH_BMESH: { + BMVert *v = (BMVert *)vertex.i; + BMEdge *e = v->e; + + if (!e) { + return true; + } + + do { + BMLoop *l = e->l; + + if (!l) { + continue; + } + + do { + if (BM_elem_flag_test(l->f, BM_ELEM_HIDDEN)) { + return false; + } + } while ((l = l->radial_next) != e->l); + } while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e); + return true; + } case PBVH_GRIDS: { if (!ss->hide_poly) { return true; @@ -603,8 +639,34 @@ void SCULPT_visibility_sync_all_from_faces(Object *ob) BKE_sculpt_sync_face_visibility_to_grids(mesh, ss->subdiv_ccg); break; } - case PBVH_BMESH: + case PBVH_BMESH: { + BMIter iter; + BMVert *v; + BMFace *f; + + /* Hide all verts and edges attached to faces.*/ + BM_ITER_MESH (f, &iter, ss->bm, BM_FACES_OF_MESH) { + BMLoop *l = f->l_first; + do { + BM_elem_flag_enable(l->v, BM_ELEM_HIDDEN); + BM_elem_flag_enable(l->e, BM_ELEM_HIDDEN); + } while ((l = l->next) != f->l_first); + } + + /* Unhide verts and edges attached to visible faces. */ + BM_ITER_MESH (f, &iter, ss->bm, BM_FACES_OF_MESH) { + if (!(BM_elem_flag_test(f, BM_ELEM_HIDDEN))) { + continue; + } + + BMLoop *l = f->l_first; + do { + BM_elem_flag_disable(l->v, BM_ELEM_HIDDEN); + BM_elem_flag_disable(l->e, BM_ELEM_HIDDEN); + } while ((l = l->next) != f->l_first); + } break; + } } } diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index 79c1304eee5..34717888966 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -833,8 +833,51 @@ static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op) SculptSession *ss = ob->sculpt; Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); - /* Dyntopo not supported. */ + Mesh *mesh = BKE_object_get_original_mesh(ob); + + BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false); + + /* Dyntopo not supported except for SCULPT_FACE_SET_VISIBILITY_SHOW_ALL. */ if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) { + if (ss->pbvh && ss->bm && + RNA_enum_get(op->ptr, "mode") == SCULPT_FACE_SET_VISIBILITY_SHOW_ALL) { + PBVHNode **nodes; + int totnode; + + BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); + + if (!totnode) { + return OPERATOR_CANCELLED; + } + + SCULPT_undo_push_begin(ob, op); + SCULPT_undo_push_node(ob, nodes[0], SCULPT_UNDO_COORDS); + + for (int i = 0; i < totnode; i++) { + BKE_pbvh_node_mark_update_visibility(nodes[i]); + } + + BMIter iter; + BMFace *f; + BMVert *v; + const int cd_mask = CustomData_get_offset(&ss->bm->vdata, CD_PAINT_MASK); + + BM_ITER_MESH (v, &iter, ss->bm, BM_VERTS_OF_MESH) { + BM_log_vert_before_modified(ss->bm_log, v, cd_mask); + } + BM_ITER_MESH (f, &iter, ss->bm, BM_FACES_OF_MESH) { + BM_log_face_modified(ss->bm_log, f); + } + + SCULPT_face_visibility_all_set(ss, true); + SCULPT_visibility_sync_all_from_faces(ob); + + SCULPT_undo_push_end(ob); + MEM_SAFE_FREE(nodes); + + return OPERATOR_FINISHED; + } + return OPERATOR_CANCELLED; } @@ -842,10 +885,6 @@ static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - Mesh *mesh = BKE_object_get_original_mesh(ob); - - BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false); - const int tot_vert = SCULPT_vertex_count_get(ss); const int mode = RNA_enum_get(op->ptr, "mode"); const int active_face_set = SCULPT_active_face_set_get(ss); -- cgit v1.2.3