[Bf-blender-cvs] [da3cb514e52] master: Multires: Initial Face Sets support

Pablo Dobarro noreply at git.blender.org
Wed Apr 1 01:09:04 CEST 2020


Commit: da3cb514e52de922148534c660a0b04ee5c43eeb
Author: Pablo Dobarro
Date:   Wed Apr 1 01:03:20 2020 +0200
Branches: master
https://developer.blender.org/rBda3cb514e52de922148534c660a0b04ee5c43eeb

Multires: Initial Face Sets support

This implements the Sculpt Mode API functions needed for Face Sets and
visibility management for PBVH_GRIDS. No major changes were needed in
the operators and the sculpt mode code. This implementation stores the
face sets in the base mesh, so faces created in higher subdivision
levels can't be modified individually. Also, we are not checking for
multiple face sets per vertex (that can be added in the future), so
relax tools don't work yet. The rest of the features (paint, undo,
visibility operators..) work as expected.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D7168

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

M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/BKE_subdiv_ccg.h
M	source/blender/blenkernel/intern/paint.c
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/blenkernel/intern/subdiv_ccg.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_undo.c
M	source/blender/gpu/GPU_buffers.h
M	source/blender/gpu/intern/gpu_buffers.c

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

diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 881f3356a86..8c925ee2ae1 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -296,6 +296,7 @@ typedef struct SculptSession {
   int *pmap_mem;
 
   /* Mesh Face Sets */
+  int totfaces;
   int *face_sets;
 
   /* BMesh for dynamic topology sculpting */
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 16a7e4d38d0..b4f16bfd899 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -219,6 +219,8 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
                               int totgrid,
                               int gridsize);
 
+void BKE_pbvh_sync_face_sets_to_grids(PBVH *bvh);
+
 /* multires level, only valid for type == PBVH_GRIDS */
 const struct CCGKey *BKE_pbvh_get_grid_key(const PBVH *pbvh);
 
@@ -298,6 +300,8 @@ void BKE_pbvh_grids_update(PBVH *bvh,
                            void **gridfaces,
                            struct DMFlagMat *flagmats,
                            unsigned int **grid_hidden);
+void BKE_pbvh_subdiv_cgg_set(PBVH *bvh, struct SubdivCCG *subdiv_ccg);
+void BKE_pbvh_face_sets_set(PBVH *bvh, int *face_sets);
 
 void BKE_pbvh_face_sets_color_set(PBVH *bvh, int seed, int color_default);
 
diff --git a/source/blender/blenkernel/BKE_subdiv_ccg.h b/source/blender/blenkernel/BKE_subdiv_ccg.h
index f8534371b17..99b134dab3e 100644
--- a/source/blender/blenkernel/BKE_subdiv_ccg.h
+++ b/source/blender/blenkernel/BKE_subdiv_ccg.h
@@ -305,6 +305,8 @@ void BKE_subdiv_ccg_neighbor_coords_get(const SubdivCCG *subdiv_ccg,
                                         const bool include_duplicates,
                                         SubdivCCGNeighbors *r_neighbors);
 
+int BKE_subdiv_cgg_grid_to_face_index(const SubdivCCG *subdiv_ccg, const int grid_index);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 719336f7351..f52ec5f568f 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1525,6 +1525,7 @@ static void sculpt_update_object(
     ss->multires = mmd;
     ss->totvert = me_eval->totvert;
     ss->totpoly = me_eval->totpoly;
+    ss->totfaces = me->totpoly;
     ss->mvert = NULL;
     ss->mpoly = NULL;
     ss->mloop = NULL;
@@ -1532,25 +1533,26 @@ static void sculpt_update_object(
   else {
     ss->totvert = me->totvert;
     ss->totpoly = me->totpoly;
+    ss->totfaces = me->totpoly;
     ss->mvert = me->mvert;
     ss->mpoly = me->mpoly;
     ss->mloop = me->mloop;
     ss->multires = NULL;
     ss->vmask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
+  }
 
-    /* Sculpt Face Sets. */
-    if (!CustomData_has_layer(&me->pdata, CD_SCULPT_FACE_SETS)) {
-      ss->face_sets = CustomData_add_layer(
-          &me->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, NULL, me->totpoly);
-      for (int i = 0; i < me->totpoly; i++) {
-        ss->face_sets[i] = 1;
-      }
-
-      /* Set the default face set color if the datalayer did not exist. */
-      me->face_sets_color_default = 1;
+  /* Sculpt Face Sets. */
+  if (!CustomData_has_layer(&me->pdata, CD_SCULPT_FACE_SETS)) {
+    ss->face_sets = CustomData_add_layer(
+        &me->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, NULL, me->totpoly);
+    for (int i = 0; i < me->totpoly; i++) {
+      ss->face_sets[i] = 1;
     }
-    ss->face_sets = CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS);
+
+    /* Set the default face set color if the datalayer did not exist. */
+    me->face_sets_color_default = 1;
   }
+  ss->face_sets = CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS);
 
   ss->subdiv_ccg = me_eval->runtime.subdiv_ccg;
 
@@ -1558,6 +1560,9 @@ static void sculpt_update_object(
   BLI_assert(pbvh == ss->pbvh);
   UNUSED_VARS_NDEBUG(pbvh);
 
+  BKE_pbvh_subdiv_cgg_set(ss->pbvh, ss->subdiv_ccg);
+  BKE_pbvh_face_sets_set(ss->pbvh, ss->face_sets);
+
   BKE_pbvh_face_sets_color_set(ss->pbvh, me->face_sets_color_seed, me->face_sets_color_default);
 
   if (need_pmap && ob->type == OB_MESH && !ss->pmap) {
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 9a4ce8acb11..ac0c9d030cf 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -383,6 +383,25 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
   return totquad;
 }
 
+void BKE_pbvh_sync_face_sets_to_grids(PBVH *bvh)
+{
+  const int gridsize = bvh->gridkey.grid_size;
+  for (int i = 0; i < bvh->totgrid; i++) {
+    BLI_bitmap *gh = bvh->grid_hidden[i];
+    const int face_index = BKE_subdiv_cgg_grid_to_face_index(bvh->subdiv_ccg, i);
+    if (!gh && bvh->face_sets[face_index] < 0) {
+      gh = bvh->grid_hidden[i] = BLI_BITMAP_NEW(bvh->gridkey.grid_area, "partialvis_update_grids");
+    }
+    if (gh) {
+      for (int y = 0; y < gridsize; y++) {
+        for (int x = 0; x < gridsize; x++) {
+          BLI_BITMAP_SET(gh, y * gridsize + x, bvh->face_sets[face_index] < 0);
+        }
+      }
+    }
+  }
+}
+
 static void build_grid_leaf_node(PBVH *bvh, PBVHNode *node)
 {
   int totquads = BKE_pbvh_count_grid_quads(
@@ -1289,10 +1308,14 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
     switch (bvh->type) {
       case PBVH_GRIDS:
         GPU_pbvh_grid_buffers_update(node->draw_buffers,
+                                     bvh->subdiv_ccg,
                                      bvh->grids,
                                      bvh->grid_flag_mats,
                                      node->prim_indices,
                                      node->totprim,
+                                     bvh->face_sets,
+                                     bvh->face_sets_color_seed,
+                                     bvh->face_sets_color_default,
                                      &bvh->gridkey,
                                      update_flags);
         break;
@@ -2974,3 +2997,13 @@ MVert *BKE_pbvh_get_verts(const PBVH *bvh)
   BLI_assert(bvh->type == PBVH_FACES);
   return bvh->verts;
 }
+
+void BKE_pbvh_subdiv_cgg_set(PBVH *bvh, SubdivCCG *subdiv_ccg)
+{
+  bvh->subdiv_ccg = subdiv_ccg;
+}
+
+void BKE_pbvh_face_sets_set(PBVH *bvh, int *face_sets)
+{
+  bvh->face_sets = face_sets;
+}
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index af92f11e219..21cb5649330 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -138,6 +138,7 @@ struct PBVH {
 
   int face_sets_color_seed;
   int face_sets_color_default;
+  int *face_sets;
 
   /* Grid Data */
   CCGKey gridkey;
@@ -168,6 +169,7 @@ struct PBVH {
   int cd_face_node_offset;
 
   struct BMLog *bm_log;
+  struct SubdivCCG *subdiv_ccg;
 };
 
 /* pbvh.c */
diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c
index 3c1a9c4d3d6..dff7170e517 100644
--- a/source/blender/blenkernel/intern/subdiv_ccg.c
+++ b/source/blender/blenkernel/intern/subdiv_ccg.c
@@ -1780,3 +1780,14 @@ void BKE_subdiv_ccg_neighbor_coords_get(const SubdivCCG *subdiv_ccg,
   }
 #endif
 }
+
+int BKE_subdiv_cgg_grid_to_face_index(const SubdivCCG *subdiv_ccg, const int grid_index)
+{
+  Subdiv *subdiv = subdiv_ccg->subdiv;
+  OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
+  SubdivCCGFace *face = subdiv_ccg->grid_faces[grid_index];
+
+  const int face_grid_index = grid_index - face->start_grid_index;
+  const int face_index = face - subdiv_ccg->faces;
+  return face_index;
+}
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 6ccd197c908..50b8c9a9677 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -248,7 +248,8 @@ static void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool
 {
   switch (BKE_pbvh_type(ss->pbvh)) {
     case PBVH_FACES:
-      for (int i = 0; i < ss->totpoly; i++) {
+    case PBVH_GRIDS:
+      for (int i = 0; i < ss->totfaces; i++) {
         if (abs(ss->face_sets[i]) == face_set) {
           if (visible) {
             ss->face_sets[i] = abs(ss->face_sets[i]);
@@ -261,8 +262,6 @@ static void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool
       break;
     case PBVH_BMESH:
       break;
-    case PBVH_GRIDS:
-      break;
   }
 }
 
@@ -270,14 +269,13 @@ static void SCULPT_face_sets_visibility_invert(SculptSession *ss)
 {
   switch (BKE_pbvh_type(ss->pbvh)) {
     case PBVH_FACES:
-      for (int i = 0; i < ss->totpoly; i++) {
+    case PBVH_GRIDS:
+      for (int i = 0; i < ss->totfaces; i++) {
         ss->face_sets[i] *= -1;
       }
       break;
     case PBVH_BMESH:
       break;
-    case PBVH_GRIDS:
-      break;
   }
 }
 
@@ -285,7 +283,8 @@ static void SCULPT_face_sets_visibility_all_set(SculptSession *ss, bool visible)
 {
   switch (BKE_pbvh_type(ss->pbvh)) {
     case PBVH_FACES:
-      for (int i = 0; i < ss->totpoly; i++) {
+    case PBVH_GRIDS:
+      for (int i = 0; i < ss->totfaces; i++) {
 
         /* This can run on geometry without a face set assigned, so its ID sign can't be changed to
          * modify the visibility. Force that geometry to the ID 1 to enable changing the visibility
@@ -304,8 +303,6 @@ static void SCULPT_face_sets_visibility_all_set(SculptSession *ss, bool visible)
       break;
     case PBVH_BMESH:
       break;
-    case PBVH_GRIDS:
-      break;
   }
 }
 
@@ -343,8 +340,12 @@ static bool SCULPT_vertex_all_face_sets_visible_get(SculptSession *ss, int index
     }
     case PBVH_BMESH:
       return true;
-    case PBVH_GRIDS:
-      return true;
+    case PBVH_GRIDS: {
+      const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
+      const int grid_index = index / key->grid_area;
+      const int face_index = BKE_subdiv_cgg_grid_to_face_index(ss->subdiv_ccg, grid_index);
+      return ss->face_sets[face_index] > 0;
+    }
   }
   return true;
 }
@@ -362,8 +363,15 @@ static void SCULPT_vert

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list