[Bf-blender-cvs] [3ebe97c06b6] blender-v2.90-release: Fix T78665: Face Set visibility reverted when chaning Multires Levels

Pablo Dobarro noreply at git.blender.org
Tue Aug 4 23:34:25 CEST 2020


Commit: 3ebe97c06b67d1611dfeaa3919512155416b0378
Author: Pablo Dobarro
Date:   Mon Jul 27 23:40:19 2020 +0200
Branches: blender-v2.90-release
https://developer.blender.org/rB3ebe97c06b67d1611dfeaa3919512155416b0378

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

===================================================================

M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/BKE_subdiv_ccg.h
M	source/blender/blenkernel/intern/paint.c
M	source/blender/blenkernel/intern/subdiv_ccg.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 1c02aece06f..de18ec6b792 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -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 {
diff --git a/source/blender/blenkernel/BKE_subdiv_ccg.h b/source/blender/blenkernel/BKE_subdiv_ccg.h
index 5808f223f32..02b83a043b4 100644
--- a/source/blender/blenkernel/BKE_subdiv_ccg.h
+++ b/source/blender/blenkernel/BKE_subdiv_ccg.h
@@ -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
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index d6fbba74a89..0ba5ec43318 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -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,
diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c
index 11d5df4f672..bc1b79f62c5 100644
--- a/source/blender/blenkernel/intern/subdiv_ccg.c
+++ b/source/blender/blenkernel/intern/subdiv_ccg.c
@@ -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__);
+}
+
 /** \} */



More information about the Bf-blender-cvs mailing list