[Bf-blender-cvs] [95767bade85] sculpt-mode-features: Sculpt: Mesh abstaction API [WIP]

Pablo Dobarro noreply at git.blender.org
Fri Jul 26 23:52:28 CEST 2019


Commit: 95767bade8520bdda8fe26e2a6329457fe37aa0e
Author: Pablo Dobarro
Date:   Fri Jul 26 23:53:32 2019 +0200
Branches: sculpt-mode-features
https://developer.blender.org/rB95767bade8520bdda8fe26e2a6329457fe37aa0e

Sculpt: Mesh abstaction API [WIP]

Using this API, all new tools for the sculpt branch should work with
both mesh and bmesh. I also ported mask by normal, mask expand and the
transform operator (with its mesh filter cache) in order to test it

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

M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/editors/sculpt_paint/paint_vertex.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 f9f06cb2fc8..ea2c24b632c 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -311,6 +311,7 @@ typedef struct PBVHVertexIter {
   int gx;
   int gy;
   int i;
+  int index;
 
   /* grid */
   struct CCGElem **grids;
@@ -381,6 +382,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, PBVHVertexIter *vi, int mo
             continue; \
           vi.co = vi.mvert->co; \
           vi.no = vi.mvert->no; \
+          vi.index = vi.vert_indices[vi.i]; \
           if (vi.vmask) \
             vi.mask = &vi.vmask[vi.vert_indices[vi.gx]]; \
           if (vi.vcol) \
@@ -399,6 +401,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, PBVHVertexIter *vi, int mo
             continue; \
           vi.co = vi.bm_vert->co; \
           vi.fno = vi.bm_vert->no; \
+          vi.index = BM_elem_index_get(vi.bm_vert); \
           vi.mask = BM_ELEM_CD_GET_VOID_P(vi.bm_vert, vi.cd_vert_mask_offset); \
         }
 
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index e58d95d86b4..868adb19afc 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -1550,6 +1550,7 @@ bool pbvh_bmesh_node_raycast(PBVHNode *node,
             if (len_squared_v3v3(location, v_tri[j]->co) <
                 len_squared_v3v3(location, output_data->nearest_vertex_co)) {
               copy_v3_v3(output_data->nearest_vertex_co, v_tri[j]->co);
+              output_data->active_vertex_mesh_index = BM_elem_index_get(v_tri[j]);
             }
           }
         }
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 7b50f35070d..d5e8c2a1825 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -1,4 +1,4 @@
-    /*
+/*
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 4c60a2df1aa..327fe2c2638 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -95,6 +95,223 @@
 #include <stdlib.h>
 #include <string.h>
 
+/* Sculpt PBVH abstraction API */
+
+typedef int VertexHandle;
+
+VertexHandle sculpt_active_vertex_get(SculptSession *ss)
+{
+  switch (BKE_pbvh_type(ss->pbvh)) {
+    case PBVH_FACES:
+      return ss->active_vertex_mesh_index;
+    case PBVH_BMESH:
+      return ss->active_vertex_mesh_index;
+    default:
+      return 0;
+  }
+}
+
+unsigned int sculpt_vertex_count_get(SculptSession *ss)
+{
+  switch (BKE_pbvh_type(ss->pbvh)) {
+    case PBVH_FACES:
+      return (unsigned int)ss->totvert;
+    case PBVH_BMESH:
+      return (unsigned int)BM_mesh_elem_count(BKE_pbvh_get_bmesh(ss->pbvh), BM_VERT);
+    default:
+      return 0;
+  }
+}
+
+void sculpt_vertex_normal_get(SculptSession *ss, VertexHandle index, float no[3])
+{
+  switch (BKE_pbvh_type(ss->pbvh)) {
+    case PBVH_FACES:
+      normal_short_to_float_v3(no, ss->mvert[(int)index].no);
+      return;
+    case PBVH_BMESH:
+      copy_v3_v3(no, BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->no);
+    default:
+      return;
+  }
+}
+
+float *sculpt_vertex_co_get(SculptSession *ss, int index)
+{
+  switch (BKE_pbvh_type(ss->pbvh)) {
+    case PBVH_FACES:
+      return ss->mvert[index].co;
+    case PBVH_BMESH:
+      return BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->co;
+    default:
+      return NULL;
+  }
+}
+
+void sculpt_vertex_co_set(SculptSession *ss, int index, float co[3])
+{
+  switch (BKE_pbvh_type(ss->pbvh)) {
+    case PBVH_FACES:
+      copy_v3_v3(ss->mvert[index].co, co);
+      return;
+    case PBVH_BMESH:
+      copy_v3_v3(BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->co, co);
+      return;
+    default:
+      return;
+  }
+}
+
+void sculpt_vertex_mask_set(SculptSession *ss, VertexHandle index, float mask)
+{
+  BMVert *v;
+  float *mask_p;
+  switch (BKE_pbvh_type(ss->pbvh)) {
+    case PBVH_FACES:
+      ss->vmask[(int)index] = mask;
+      return;
+    case PBVH_BMESH:
+      v = BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index);
+      mask_p = BM_ELEM_CD_GET_VOID_P(v, CustomData_get_offset(&ss->bm->vdata, CD_PAINT_MASK));
+      *(mask_p) = mask;
+      return;
+    default:
+      return;
+  }
+}
+
+float sculpt_vertex_mask_get(SculptSession *ss, int index)
+{
+  BMVert *v;
+  float *mask;
+  switch (BKE_pbvh_type(ss->pbvh)) {
+    case PBVH_FACES:
+      return ss->vmask[index];
+    case PBVH_BMESH:
+      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;
+  }
+}
+
+void sculpt_vertex_tag_update(SculptSession *ss, int index)
+{
+  switch (BKE_pbvh_type(ss->pbvh)) {
+    case PBVH_FACES:
+      ss->mvert[index].flag |= ME_VERT_PBVH_UPDATE;
+    case PBVH_BMESH:
+      break;
+    default:
+      break;
+  }
+}
+
+typedef struct SculptVertexNeighbourIter {
+  VertexHandle *neighbours;
+  int count;
+  VertexHandle index;
+  int i;
+} SculptVertexNeighbourIter;
+
+void sculpt_vertex_neighbours_get_bmesh(SculptSession *ss,
+                                        VertexHandle index,
+                                        SculptVertexNeighbourIter *iter)
+{
+  BMVert *v = BM_vert_at_index(ss->bm, index);
+  BMIter liter;
+  BMLoop *l;
+  GSet *n_set;
+  n_set = BLI_gset_new(BLI_ghashutil_uinthash, BLI_ghashutil_intcmp, "neighbour set");
+  int i = 0;
+  BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
+    const BMVert *adj_v[2] = {l->prev->v, l->next->v};
+    for (i = 0; i < ARRAY_SIZE(adj_v); i++) {
+      const BMVert *v_other = adj_v[i];
+      if (BM_elem_index_get(v_other) != (int)index) {
+        BLI_gset_add(n_set, BM_elem_index_get(v_other));
+      }
+    }
+  }
+
+  iter->count = BLI_gset_len(n_set);
+  iter->neighbours = MEM_mallocN(BLI_gset_len(n_set) * sizeof(int), "neighbour array");
+
+  int c_index = 0;
+  GSetIterator *gsi = BLI_gsetIterator_new(n_set);
+  for (BLI_gsetIterator_init(gsi, n_set); !BLI_gsetIterator_done(gsi);
+       BLI_gsetIterator_step(gsi)) {
+    iter->neighbours[c_index] = BLI_gsetIterator_getKey(gsi);
+    c_index++;
+  }
+  BLI_gsetIterator_free(gsi);
+  BLI_gset_free(n_set, NULL);
+}
+
+void sculpt_vertex_neighbours_get_faces(SculptSession *ss,
+                                        VertexHandle index,
+                                        SculptVertexNeighbourIter *iter)
+{
+  GSet *n_set;
+  int i;
+  MeshElemMap *vert_map = &ss->pmap[(int)index];
+  n_set = BLI_gset_new(BLI_ghashutil_uinthash, BLI_ghashutil_intcmp, "neighbour set");
+  for (i = 0; i < ss->pmap[(int)index].count; i++) {
+    const MPoly *p = &ss->mpoly[vert_map->indices[i]];
+    unsigned f_adj_v[2];
+    if (poly_get_adj_loops_from_vert(p, ss->mloop, (int)index, f_adj_v) != -1) {
+      int j;
+      for (j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) {
+        if (vert_map->count != 2 || ss->pmap[f_adj_v[j]].count <= 2) {
+          if (f_adj_v[j] != (int)index) {
+            BLI_gset_add(n_set, f_adj_v[j]);
+          }
+        }
+      }
+    }
+  }
+
+  iter->count = BLI_gset_len(n_set);
+  iter->neighbours = MEM_mallocN(BLI_gset_len(n_set) * sizeof(int), "neighbour array");
+
+  int c_index = 0;
+  GSetIterator *gsi = BLI_gsetIterator_new(n_set);
+  for (BLI_gsetIterator_init(gsi, n_set); !BLI_gsetIterator_done(gsi);
+       BLI_gsetIterator_step(gsi)) {
+    iter->neighbours[c_index] = BLI_gsetIterator_getKey(gsi);
+    c_index++;
+  }
+  BLI_gsetIterator_free(gsi);
+  BLI_gset_free(n_set, NULL);
+}
+
+void sculpt_vertex_neighbours_get(SculptSession *ss,
+                                  VertexHandle index,
+                                  SculptVertexNeighbourIter *iter)
+{
+  switch (BKE_pbvh_type(ss->pbvh)) {
+    case PBVH_FACES:
+      sculpt_vertex_neighbours_get_faces(ss, index, iter);
+      return;
+    case PBVH_BMESH:
+      sculpt_vertex_neighbours_get_bmesh(ss, index, iter);
+      return;
+    default:
+      break;
+  }
+}
+
+#define sculpt_vertex_neighbours_iter_begin(ss, v_index, neighbour_iterator) \
+  sculpt_vertex_neighbours_get(ss, v_index, &neighbour_iterator); \
+  for (neighbour_iterator.i = 0; neighbour_iterator.i < neighbour_iterator.count; \
+       neighbour_iterator.i++) { \
+    neighbour_iterator.index = ni.neighbours[ni.i];
+
+#define sculpt_vertex_neighbours_iter_end(neighbour_iterator) \
+  } \
+  MEM_freeN(neighbour_iterator.neighbours);
+
 /** \name Tool Capabilities
  *
  * Avoid duplicate checks, internal logic only,
@@ -4899,6 +5116,10 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
       update_brush_local_mat(sd, ob);
     }
 
+    if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
+      BM_mesh_elem_index_ensure(BKE_pbvh_get_bmesh(ss->pbvh), BM_VERT);
+    }
+
     /* Init topological automasking */
     if (sculpt_automasking_enabled(ss, brush)) {
       if (sculpt_automasking_needs_updates(brush) || ss->cache->first_time) {
@@ -6112,6 +6333,9 @@ bool sculpt_stroke_get_geometry_info(bContext *C, StrokeGeometryInfo *out, const
     return false;
   }
 
+  if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
+    BM_mesh_elem_index_ensure(ss->bm, BM_VERT);
+  }
   depth = sculpt_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, original);
   sculpt_stroke_modifiers_check(C, ob, brush);
 
@@ -7743,11 +7967,11 @@ static void filter_cache_init_task_cb(void *__restrict userdata,
   PBVHVertexIter vd;
   BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE)
   {
-    int vi = vd.vert_indices[vd.i];
-    if (vd.mask && (*vd.mask) < 1.0f) {
+    int vi = vd.index;
+    if (*vd.mask < 1.0f) {
       data->node_mask[i] = 1;
     }
-    copy_v3_v3(ss->filter_cache->orco[vi], ss->mvert[vi].co);
+    copy_v3_v3(ss->filt

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list