Fix T78665: Face Set visibility reverted when chaning Multires Levels

Face Sets where only set and updated on the PBVH after starting a sculpt
tool. In order to preserve the visibility they store when changing
levels, they need to be updated and sync also on PBVH creation

Reviewed By: sergey

Maniphest Tasks: T78665

Differential Revision: https://developer.blender.org/D8225
This commit is contained in:
Pablo Dobarro 2020-07-27 23:40:19 +02:00
parent 50e6d56e4e
commit 3ebe97c06b
Notes: blender-bot 2023-02-14 05:37:19 +01:00
Referenced by issue #80771, Mode switching hides vertices in Edit mode (Weight paint / Sculpt mode --> Edit mode)
Referenced by issue #78665, Face Set visibility is reverted when toggling local view or face set overlay while working with Multires subdivisions
4 changed files with 81 additions and 0 deletions

View File

@ -471,6 +471,10 @@ struct PBVH *BKE_sculpt_object_pbvh_ensure(struct Depsgraph *depsgraph, struct O
void BKE_sculpt_bvh_update_from_ccg(struct PBVH *pbvh, struct SubdivCCG *subdiv_ccg);
/* This ensure that all elements in the mesh (both vertices and grids) have their visibility
* updated according to the face sets. */
void BKE_sculpt_sync_face_set_visibility(struct Mesh *mesh, struct SubdivCCG *subdiv_ccg);
bool BKE_sculptsession_use_pbvh_draw(const struct Object *ob, const struct View3D *v3d);
enum {

View File

@ -338,6 +338,8 @@ SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(const Subdi
const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG *subdiv_ccg);
const int *BKE_subdiv_ccg_start_face_grid_index_get(const SubdivCCG *subdiv_ccg);
void BKE_subdiv_ccg_grid_hidden_ensure(SubdivCCG *subdiv_ccg, int grid_index);
#ifdef __cplusplus
}
#endif

View File

@ -1825,6 +1825,64 @@ static bool check_sculpt_object_deformed(Object *object, const bool for_construc
return deformed;
}
static void sculpt_sync_face_sets_visibility_to_base_mesh(Mesh *mesh)
{
int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
if (!face_sets) {
return;
}
for (int i = 0; i < mesh->totvert; i++) {
mesh->mvert[i].flag |= ME_HIDE;
}
for (int i = 0; i < mesh->totpoly; i++) {
if (face_sets[i] >= 0) {
for (int l = 0; l < mesh->mpoly[i].totloop; l++) {
MLoop *loop = &mesh->mloop[mesh->mpoly[i].loopstart + l];
mesh->mvert[loop->v].flag &= ~ME_HIDE;
}
}
}
}
static void sculpt_sync_face_sets_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
{
int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
if (!face_sets) {
return;
}
if (!subdiv_ccg) {
return;
}
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
for (int i = 0; i < mesh->totloop; i++) {
const int face_index = BKE_subdiv_ccg_grid_to_face_index(subdiv_ccg, i);
const bool is_hidden = (face_sets[face_index] < 0);
/* Avoid creating and modifying the grid_hidden bitmap if the base mesh face is visible and
* there is not bitmap for the grid. This is because missing grid_hidden implies grid is fully
* visible. */
if (is_hidden) {
BKE_subdiv_ccg_grid_hidden_ensure(subdiv_ccg, i);
}
BLI_bitmap *gh = subdiv_ccg->grid_hidden[i];
if (gh) {
BLI_bitmap_set_all(gh, is_hidden, key.grid_area);
}
}
}
void BKE_sculpt_sync_face_set_visibility(struct Mesh *mesh, struct SubdivCCG *subdiv_ccg)
{
sculpt_sync_face_sets_visibility_to_base_mesh(mesh);
sculpt_sync_face_sets_visibility_to_grids(mesh, subdiv_ccg);
}
static PBVH *build_pbvh_for_dynamic_topology(Object *ob)
{
PBVH *pbvh = BKE_pbvh_new();
@ -1850,6 +1908,8 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri);
BKE_sculpt_sync_face_set_visibility(me, NULL);
BKE_pbvh_build_mesh(pbvh,
me,
me->mpoly,
@ -1882,6 +1942,10 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg, bool respect
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
PBVH *pbvh = BKE_pbvh_new();
BKE_pbvh_respect_hide_set(pbvh, respect_hide);
Mesh *base_mesh = BKE_mesh_from_object(ob);
BKE_sculpt_sync_face_set_visibility(base_mesh, subdiv_ccg);
BKE_pbvh_build_grids(pbvh,
subdiv_ccg->grids,
subdiv_ccg->num_grids,

View File

@ -1922,4 +1922,15 @@ SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(const Subdi
return SUBDIV_CCG_ADJACENT_NONE;
}
void BKE_subdiv_ccg_grid_hidden_ensure(SubdivCCG *subdiv_ccg, int grid_index)
{
if (subdiv_ccg->grid_hidden[grid_index] != NULL) {
return;
}
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
subdiv_ccg->grid_hidden[grid_index] = BLI_BITMAP_NEW(key.grid_area, __func__);
}
/** \} */