[Bf-blender-cvs] [2090b3e5ac4] master: Cleanup: internal sculpt refactoring related to multires, no user visible changes

Brecht Van Lommel noreply at git.blender.org
Tue Oct 1 16:15:37 CEST 2019


Commit: 2090b3e5ac41b5f5dffcdbd3d4c4b5ac0b84473d
Author: Brecht Van Lommel
Date:   Mon Sep 30 16:33:04 2019 +0200
Branches: master
https://developer.blender.org/rB2090b3e5ac41b5f5dffcdbd3d4c4b5ac0b84473d

Cleanup: internal sculpt refactoring related to multires, no user visible changes

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

M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/editors/sculpt_paint/sculpt.c

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

diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index fbf593496cf..dedf76ee839 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -214,7 +214,8 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
 /* multires level, only valid for type == PBVH_GRIDS */
 const struct CCGKey *BKE_pbvh_get_grid_key(const PBVH *pbvh);
 
-struct CCGElem **BKE_pbvh_get_grids(const PBVH *pbvh, int *num_grids);
+struct CCGElem **BKE_pbvh_get_grids(const PBVH *pbvh);
+int BKE_pbvh_get_grid_num_vertices(const PBVH *pbvh);
 
 /* Only valid for type == PBVH_BMESH */
 struct BMesh *BKE_pbvh_get_bmesh(PBVH *pbvh);
@@ -362,6 +363,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, PBVHVertexIter *vi, int mo
     if (vi.grids) { \
       vi.width = vi.gridsize; \
       vi.height = vi.gridsize; \
+      vi.index = vi.grid_indices[vi.g] * vi.key.grid_area - 1; \
       vi.grid = vi.grids[vi.grid_indices[vi.g]]; \
       if (mode == PBVH_ITER_UNIQUE) \
         vi.gh = vi.grid_hidden[vi.grid_indices[vi.g]]; \
@@ -378,6 +380,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, PBVHVertexIter *vi, int mo
           vi.fno = CCG_elem_no(&vi.key, vi.grid); \
           vi.mask = vi.key.has_mask ? CCG_elem_mask(&vi.key, vi.grid) : NULL; \
           vi.grid = CCG_elem_next(&vi.key, vi.grid); \
+          vi.index++; \
           if (vi.gh) { \
             if (BLI_BITMAP_TEST(vi.gh, vi.gy * vi.gridsize + vi.gx)) \
               continue; \
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index d185ed0d271..7ed986204d5 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -1484,13 +1484,18 @@ const CCGKey *BKE_pbvh_get_grid_key(const PBVH *bvh)
   return &bvh->gridkey;
 }
 
-struct CCGElem **BKE_pbvh_get_grids(const PBVH *bvh, int *num_grids)
+struct CCGElem **BKE_pbvh_get_grids(const PBVH *bvh)
 {
   BLI_assert(bvh->type == PBVH_GRIDS);
-  *num_grids = bvh->totgrid;
   return bvh->grids;
 }
 
+int BKE_pbvh_get_grid_num_vertices(const PBVH *bvh)
+{
+  BLI_assert(bvh->type == PBVH_GRIDS);
+  return bvh->totgrid * bvh->gridkey.grid_area;
+}
+
 BMesh *BKE_pbvh_get_bmesh(PBVH *bvh)
 {
   BLI_assert(bvh->type == PBVH_BMESH);
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index e9d4dba937d..ed468a7e41a 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -98,7 +98,8 @@
  * This is read-only, for writing use PBVH vertex iterators. There vd.index matches
  * the indices used here.
  *
- * Do not use these functions while working with PBVH_GRIDS data in SculptSession. */
+ * For multires, the same vertex in multiple grids is counted multiple times, with
+ * different index for each grid. */
 
 static void sculpt_vertex_random_access_init(SculptSession *ss)
 {
@@ -114,9 +115,11 @@ static int sculpt_vertex_count_get(SculptSession *ss)
       return ss->totvert;
     case PBVH_BMESH:
       return BM_mesh_elem_count(BKE_pbvh_get_bmesh(ss->pbvh), BM_VERT);
-    default:
-      return 0;
+    case PBVH_GRIDS:
+      return BKE_pbvh_get_grid_num_vertices(ss->pbvh);
   }
+
+  return 0;
 }
 
 const float *sculpt_vertex_co_get(SculptSession *ss, int index)
@@ -126,9 +129,13 @@ const float *sculpt_vertex_co_get(SculptSession *ss, int index)
       return ss->mvert[index].co;
     case PBVH_BMESH:
       return BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->co;
-    case PBVH_GRIDS:
-      BLI_assert(!"This fuction is not supposed to be used for PBVH_GRIDS");
-      break;
+    case PBVH_GRIDS: {
+      const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
+      const int grid_index = index / key->grid_area;
+      const int vertex_index = index - grid_index * key->grid_area;
+      CCGElem *elem = BKE_pbvh_get_grids(ss->pbvh)[grid_index];
+      return CCG_elem_co(key, CCG_elem_offset(key, elem, vertex_index));
+    }
   }
   return NULL;
 }
@@ -142,11 +149,17 @@ static void sculpt_vertex_normal_get(SculptSession *ss, int index, float no[3])
     case PBVH_BMESH:
       copy_v3_v3(no, BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->no);
       break;
-    default:
-      zero_v3(no);
-      return;
+    case PBVH_GRIDS: {
+      const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
+      const int grid_index = index / key->grid_area;
+      const int vertex_index = index - grid_index * key->grid_area;
+      CCGElem *elem = BKE_pbvh_get_grids(ss->pbvh)[grid_index];
+      copy_v3_v3(no, CCG_elem_no(key, CCG_elem_offset(key, elem, vertex_index)));
+      break;
+    }
   }
 }
+
 static float sculpt_vertex_mask_get(SculptSession *ss, int index)
 {
   BMVert *v;
@@ -158,9 +171,16 @@ static float sculpt_vertex_mask_get(SculptSession *ss, int index)
       v = BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index);
       mask = BM_ELEM_CD_GET_VOID_P(v, CustomData_get_offset(&ss->bm->vdata, CD_PAINT_MASK));
       return *mask;
-    default:
-      return 0;
+    case PBVH_GRIDS: {
+      const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
+      const int grid_index = index / key->grid_area;
+      const int vertex_index = index - grid_index * key->grid_area;
+      CCGElem *elem = BKE_pbvh_get_grids(ss->pbvh)[grid_index];
+      return *CCG_elem_mask(key, CCG_elem_offset(key, elem, vertex_index));
+    }
   }
+
+  return 0.0f;
 }
 
 static int sculpt_active_vertex_get(SculptSession *ss)
@@ -172,9 +192,9 @@ static int sculpt_active_vertex_get(SculptSession *ss)
     case PBVH_BMESH:
       return ss->active_vertex_index;
     case PBVH_GRIDS:
-      BLI_assert(!"This fuction is not supposed to be used for PBVH_GRIDS");
-      break;
+      return ss->active_vertex_index;
   }
+
   return 0;
 }
 
@@ -273,6 +293,18 @@ static void sculpt_vertex_neighbors_get_faces(SculptSession *ss,
   }
 }
 
+static void sculpt_vertex_neighbors_get_grids(SculptSession *UNUSED(ss),
+                                              int UNUSED(index),
+                                              SculptVertexNeighborIter *iter)
+{
+  /* TODO: implement this for multires. It might also be worth changing this
+   * iterator to provide a coordinate and mask pointer directly for effiency,
+   * rather than converting back and forth between CCGElem and global index. */
+  iter->size = 0;
+  iter->capacity = SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY;
+  iter->neighbors = iter->neighbors_fixed;
+}
+
 static void sculpt_vertex_neighbors_get(SculptSession *ss,
                                         int index,
                                         SculptVertexNeighborIter *iter)
@@ -284,8 +316,9 @@ static void sculpt_vertex_neighbors_get(SculptSession *ss,
     case PBVH_BMESH:
       sculpt_vertex_neighbors_get_bmesh(ss, index, iter);
       return;
-    default:
-      break;
+    case PBVH_GRIDS:
+      sculpt_vertex_neighbors_get_grids(ss, index, iter);
+      return;
   }
 }
 
@@ -493,6 +526,8 @@ static void sculpt_floodfill_execute(SculptSession *ss,
                                                   void *userdata),
                                      void *userdata)
 {
+  /* TODO: multires support, taking into account duplicate vertices and
+   * correctly handling them in the pose, automask and mask expand callbacks. */
   while (!BLI_gsqueue_is_empty(flood->queue)) {
     SculptFloodFillIterator from;
     BLI_gsqueue_pop(flood->queue, &from);
@@ -2356,6 +2391,48 @@ static float bmesh_neighbor_average_mask(BMVert *v, const int cd_vert_mask_offse
   }
 }
 
+static void grids_neighbor_average(SculptSession *ss, float result[3], int index)
+{
+  float avg[3] = {0.0f, 0.0f, 0.0f};
+  int total = 0;
+
+  SculptVertexNeighborIter ni;
+  sculpt_vertex_neighbors_iter_begin(ss, index, ni)
+  {
+    add_v3_v3(avg, sculpt_vertex_co_get(ss, ni.index));
+    total++;
+  }
+  sculpt_vertex_neighbors_iter_end(ni);
+
+  if (total > 0) {
+    mul_v3_v3fl(result, avg, 1.0f / (float)total);
+  }
+  else {
+    copy_v3_v3(result, sculpt_vertex_co_get(ss, index));
+  }
+}
+
+static float grids_neighbor_average_mask(SculptSession *ss, int index)
+{
+  float avg = 0.0f;
+  int total = 0;
+
+  SculptVertexNeighborIter ni;
+  sculpt_vertex_neighbors_iter_begin(ss, index, ni)
+  {
+    avg += sculpt_vertex_mask_get(ss, ni.index);
+    total++;
+  }
+  sculpt_vertex_neighbors_iter_end(ni);
+
+  if (total > 0) {
+    return avg / (float)total;
+  }
+  else {
+    return sculpt_vertex_mask_get(ss, index);
+  }
+}
+
 /* Note: uses after-struct allocated mem to store actual cache... */
 typedef struct SculptDoBrushSmoothGridDataChunk {
   size_t tmpgrid_size;
@@ -8266,11 +8343,16 @@ static void mesh_filter_task_cb(void *__restrict userdata,
     switch (filter_type) {
       case MESH_FILTER_SMOOTH:
         CLAMP(fade, -1.0f, 1.0f);
-        if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
-          neighbor_average(ss, avg, vd.index);
-        }
-        else if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
-          bmesh_neighbor_average(avg, vd.bm_vert);
+        switch (BKE_pbvh_type(ss->pbvh)) {
+          case PBVH_FACES:
+            neighbor_average(ss, avg, vd.index);
+            break;
+          case PBVH_BMESH:
+            bmesh_neighbor_average(avg, vd.bm_vert);
+            break;
+          case PBVH_GRIDS:
+            grids_neighbor_average(ss, avg, vd.index);
+            break;
         }
         sub_v3_v3v3(val, avg, orig_co);
         madd_v3_v3v3fl(val, orig_co, val, fade);
@@ -8309,11 +8391,16 @@ static void mesh_filter_task_cb(void *__restrict userdata,
 
         mid_v3_v3v3(disp, disp, disp2);
         break;
-      case MESH_FILTER_RANDOM:
+      case MESH_FILTER_RANDOM: {
         normal_short_to_float_v3(normal, orig_data.no);
-        mul_v3_fl(normal, BLI_hash_int_01(vd.index ^ ss->filter_cache->random_seed) - 0.5f);
+        /* Index is not unique for multires, so hash by vertex coordinates. */
+        const uint *hash_co = (const uint *)orig_co;
+        const uint hash = BLI_hash_int_2d(hash_co[0], hash_co[1]) ^
+                          BLI_hash_int_2d(hash_co[2], ss->filter_cache->random_seed);


@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list