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:
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
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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__);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
Loading…
Reference in New Issue