[Bf-blender-cvs] [d7cfb6ac71e] master: Sculpt: Opaque vertex type for sculpt

Joseph Eagar noreply at git.blender.org
Sat Jul 30 04:08:09 CEST 2022


Commit: d7cfb6ac71e4225a654487ab134c89051dad03ed
Author: Joseph Eagar
Date:   Fri Jul 29 19:01:32 2022 -0700
Branches: master
https://developer.blender.org/rBd7cfb6ac71e4225a654487ab134c89051dad03ed

Sculpt: Opaque vertex type for sculpt

This is a port of sculpt-dev's `SculptVertRef` refactor
(note that `SculptVertRef was renamed to PBVHVertRef`)
to master. `PBVHVertRef` is a structure that abstracts
the concept of a vertex in the sculpt code; it's simply
an `intptr_t` wrapped in a struct.

For `PBVH_FACES` and `PBVH_GRIDS` this struct stores a
vertex index, but for `BMesh` it stores a direct pointer
to a BMVert.  The intptr_t is wrapped in a struct to prevent
the accidental usage of it as an index.

There are many reasons to do this:

* Right now `BMesh` verts are not logical sculpt verts;
  to use the sculpt API they must first be converted to indices.
  This requires a lot of indirect lookups into tables, leading to performance
  loss.  It has also led to greater code complexity and duplication.
* Having an abstract vertex type makes it feasible to have one unified
  temporary attribute API for all three PBVH modes, which in turn
  made it rather trivial to port sculpt brushes to DynTopo in
  sculpt-dev (e.g. the layer brush, draw sharp, the smooth brushes,
  the paint brushes, etc).  This attribute API will be in a future patch.
* We need to do this anyway for the eventual move to C++.

Differential Revision: https://developer.blender.org/D14272
Reviewed By: Brecht Van Lommel
Ref D14272

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

M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/paint.c
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/pbvh.cc
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/blenloader/CMakeLists.txt
M	source/blender/editors/curves/CMakeLists.txt
M	source/blender/editors/geometry/CMakeLists.txt
M	source/blender/editors/gpencil/CMakeLists.txt
M	source/blender/editors/interface/CMakeLists.txt
M	source/blender/editors/sculpt_paint/paint_cursor.c
M	source/blender/editors/sculpt_paint/paint_mask.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_automasking.cc
M	source/blender/editors/sculpt_paint/sculpt_boundary.c
M	source/blender/editors/sculpt_paint/sculpt_brush_types.c
M	source/blender/editors/sculpt_paint/sculpt_cloth.c
M	source/blender/editors/sculpt_paint/sculpt_detail.c
M	source/blender/editors/sculpt_paint/sculpt_expand.c
M	source/blender/editors/sculpt_paint/sculpt_face_set.c
M	source/blender/editors/sculpt_paint/sculpt_filter_color.c
M	source/blender/editors/sculpt_paint/sculpt_filter_mask.c
M	source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
M	source/blender/editors/sculpt_paint/sculpt_geodesic.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/editors/sculpt_paint/sculpt_mask_expand.c
M	source/blender/editors/sculpt_paint/sculpt_mask_init.c
M	source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
M	source/blender/editors/sculpt_paint/sculpt_ops.c
M	source/blender/editors/sculpt_paint/sculpt_paint_color.c
M	source/blender/editors/sculpt_paint/sculpt_paint_image.cc
M	source/blender/editors/sculpt_paint/sculpt_pose.c
M	source/blender/editors/sculpt_paint/sculpt_smooth.c
M	source/blender/editors/sculpt_paint/sculpt_transform.c
M	source/blender/editors/sculpt_paint/sculpt_undo.c
M	source/blender/editors/space_buttons/CMakeLists.txt
M	source/blender/editors/undo/CMakeLists.txt
M	source/blender/nodes/texture/CMakeLists.txt
M	source/blender/windowmanager/CMakeLists.txt

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

diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 162459d2005..8b9deadc960 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -13,6 +13,7 @@
 #include "DNA_object_enums.h"
 
 #include "BKE_attribute.h"
+#include "BKE_pbvh.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -397,7 +398,7 @@ typedef struct SculptVertexInfo {
 
 typedef struct SculptBoundaryEditInfo {
   /* Vertex index from where the topology propagation reached this vertex. */
-  int original_vertex;
+  int original_vertex_i;
 
   /* How many steps were needed to reach this vertex from the boundary. */
   int num_propagation_steps;
@@ -408,13 +409,14 @@ typedef struct SculptBoundaryEditInfo {
 
 /* Edge for drawing the boundary preview in the cursor. */
 typedef struct SculptBoundaryPreviewEdge {
-  int v1;
-  int v2;
+  PBVHVertRef v1;
+  PBVHVertRef v2;
 } SculptBoundaryPreviewEdge;
 
 typedef struct SculptBoundary {
   /* Vertex indices of the active boundary. */
-  int *vertices;
+  PBVHVertRef *vertices;
+  int *vertices_i;
   int vertices_capacity;
   int num_vertices;
 
@@ -432,12 +434,13 @@ typedef struct SculptBoundary {
   bool forms_loop;
 
   /* Initial vertex in the boundary which is closest to the current sculpt active vertex. */
-  int initial_vertex;
+  PBVHVertRef initial_vertex;
+  int initial_vertex_i;
 
   /* Vertex that at max_propagation_steps from the boundary and closest to the original active
    * vertex that was used to initialize the boundary. This is used as a reference to check how much
    * the deformation will go into the mesh and to calculate the strength of the brushes. */
-  int pivot_vertex;
+  PBVHVertRef pivot_vertex;
 
   /* Stores the initial positions of the pivot and boundary initial vertex as they may be deformed
    * during the brush action. This allows to use them as a reference positions and vectors for some
@@ -565,7 +568,7 @@ typedef struct SculptSession {
   struct ExpandCache *expand_cache;
 
   /* Cursor data and active vertex for tools */
-  int active_vertex_index;
+  PBVHVertRef active_vertex;
 
   int active_face_index;
   int active_grid_index;
@@ -591,8 +594,8 @@ typedef struct SculptSession {
   struct Scene *scene;
 
   /* Dynamic mesh preview */
-  int *preview_vert_index_list;
-  int preview_vert_index_count;
+  PBVHVertRef *preview_vert_list;
+  int preview_vert_count;
 
   /* Pose Brush Preview */
   float pose_origin[3];
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index f517ff3a949..2f4618e6f7a 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -8,8 +8,11 @@
  */
 
 #include "BLI_bitmap.h"
+#include "BLI_compiler_compat.h"
 #include "BLI_ghash.h"
 
+#include "bmesh.h"
+
 /* For embedding CCGKey in iterator. */
 #include "BKE_attribute.h"
 #include "BKE_ccg.h"
@@ -43,6 +46,41 @@ struct MeshElemMap;
 typedef struct PBVH PBVH;
 typedef struct PBVHNode PBVHNode;
 
+typedef enum {
+  PBVH_FACES,
+  PBVH_GRIDS,
+  PBVH_BMESH,
+} PBVHType;
+
+/* Public members of PBVH, used for inlined functions. */
+struct PBVHPublic {
+  PBVHType type;
+  BMesh *bm;
+};
+
+/*
+ * These structs represent logical verts/edges/faces.
+ * for PBVH_GRIDS and PBVH_FACES they store integer
+ * offsets, PBVH_BMESH stores pointers.
+ *
+ * The idea is to enforce stronger type checking by encapsulating
+ * intptr_t's in structs.
+ */
+
+typedef struct PBVHVertRef {
+  intptr_t i;
+} PBVHVertRef;
+
+typedef struct PBVHEdgeRef {
+  intptr_t i;
+} PBVHEdgeRef;
+
+typedef struct PBVHFaceRef {
+  intptr_t i;
+} PBVHFaceRef;
+
+#define PBVH_REF_NONE -1LL
+
 typedef struct {
   float (*co)[3];
 } PBVHProxyNode;
@@ -87,9 +125,97 @@ typedef struct PBVHFrustumPlanes {
   int num_planes;
 } PBVHFrustumPlanes;
 
+BLI_INLINE PBVHType BKE_pbvh_type(const PBVH *pbvh)
+{
+  return ((const struct PBVHPublic *)pbvh)->type;
+}
+
+BLI_INLINE BMesh *BKE_pbvh_get_bmesh(PBVH *pbvh)
+{
+  return ((struct PBVHPublic *)pbvh)->bm;
+}
+
 void BKE_pbvh_set_frustum_planes(PBVH *pbvh, PBVHFrustumPlanes *planes);
 void BKE_pbvh_get_frustum_planes(PBVH *pbvh, PBVHFrustumPlanes *planes);
 
+BLI_INLINE PBVHVertRef BKE_pbvh_make_vref(intptr_t i)
+{
+  PBVHVertRef ret = {i};
+  return ret;
+}
+
+BLI_INLINE PBVHEdgeRef BKE_pbvh_make_eref(intptr_t i)
+{
+  PBVHEdgeRef ret = {i};
+  return ret;
+}
+
+BLI_INLINE PBVHFaceRef BKE_pbvh_make_fref(intptr_t i)
+{
+  PBVHFaceRef ret = {i};
+  return ret;
+}
+
+BLI_INLINE int BKE_pbvh_vertex_to_index(PBVH *pbvh, PBVHVertRef v)
+{
+  return (BKE_pbvh_type(pbvh) == PBVH_BMESH && v.i != PBVH_REF_NONE ?
+              BM_elem_index_get((BMVert *)(v.i)) :
+              (v.i));
+}
+
+BLI_INLINE PBVHVertRef BKE_pbvh_index_to_vertex(PBVH *pbvh, int index)
+{
+  switch (BKE_pbvh_type(pbvh)) {
+    case PBVH_FACES:
+    case PBVH_GRIDS:
+      return BKE_pbvh_make_vref(index);
+    case PBVH_BMESH:
+      return BKE_pbvh_make_vref((intptr_t)BKE_pbvh_get_bmesh(pbvh)->vtable[index]);
+  }
+
+  return BKE_pbvh_make_vref(PBVH_REF_NONE);
+}
+
+BLI_INLINE int BKE_pbvh_edge_to_index(PBVH *pbvh, PBVHEdgeRef e)
+{
+  return (BKE_pbvh_type(pbvh) == PBVH_BMESH && e.i != PBVH_REF_NONE ?
+              BM_elem_index_get((BMEdge *)(e.i)) :
+              (e.i));
+}
+
+BLI_INLINE PBVHEdgeRef BKE_pbvh_index_to_edge(PBVH *pbvh, int index)
+{
+  switch (BKE_pbvh_type(pbvh)) {
+    case PBVH_FACES:
+    case PBVH_GRIDS:
+      return BKE_pbvh_make_eref(index);
+    case PBVH_BMESH:
+      return BKE_pbvh_make_eref((intptr_t)BKE_pbvh_get_bmesh(pbvh)->etable[index]);
+  }
+
+  return BKE_pbvh_make_eref(PBVH_REF_NONE);
+}
+
+BLI_INLINE int BKE_pbvh_face_to_index(PBVH *pbvh, PBVHFaceRef f)
+{
+  return (BKE_pbvh_type(pbvh) == PBVH_BMESH && f.i != PBVH_REF_NONE ?
+              BM_elem_index_get((BMFace *)(f.i)) :
+              (f.i));
+}
+
+BLI_INLINE PBVHFaceRef BKE_pbvh_index_to_face(PBVH *pbvh, int index)
+{
+  switch (BKE_pbvh_type(pbvh)) {
+    case PBVH_FACES:
+    case PBVH_GRIDS:
+      return BKE_pbvh_make_fref(index);
+    case PBVH_BMESH:
+      return BKE_pbvh_make_fref((intptr_t)BKE_pbvh_get_bmesh(pbvh)->ftable[index]);
+  }
+
+  return BKE_pbvh_make_fref(PBVH_REF_NONE);
+}
+
 /* Callbacks */
 
 /**
@@ -181,7 +307,7 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh,
                            const float ray_normal[3],
                            struct IsectRayPrecalc *isect_precalc,
                            float *depth,
-                           int *active_vertex_index,
+                           PBVHVertRef *active_vertex,
                            int *active_face_grid_index,
                            float *face_normal);
 
@@ -230,13 +356,7 @@ void BKE_pbvh_draw_debug_cb(
     void *user_data);
 
 /* PBVH Access */
-typedef enum {
-  PBVH_FACES,
-  PBVH_GRIDS,
-  PBVH_BMESH,
-} PBVHType;
 
-PBVHType BKE_pbvh_type(const PBVH *pbvh);
 bool BKE_pbvh_has_faces(const PBVH *pbvh);
 
 /**
@@ -272,7 +392,6 @@ int BKE_pbvh_get_grid_num_faces(const PBVH *pbvh);
 /**
  * Only valid for type == #PBVH_BMESH.
  */
-struct BMesh *BKE_pbvh_get_bmesh(PBVH *pbvh);
 void BKE_pbvh_bmesh_detail_size_set(PBVH *pbvh, float detail_size);
 
 typedef enum {
@@ -308,7 +427,7 @@ void BKE_pbvh_node_fully_unmasked_set(PBVHNode *node, int fully_masked);
 bool BKE_pbvh_node_fully_unmasked_get(PBVHNode *node);
 
 void BKE_pbvh_mark_rebuild_pixels(PBVH *pbvh);
-void BKE_pbvh_vert_mark_update(PBVH *pbvh, int index);
+void BKE_pbvh_vert_mark_update(PBVH *pbvh, PBVHVertRef vertex);
 
 void BKE_pbvh_node_get_grids(PBVH *pbvh,
                              PBVHNode *node,
@@ -399,6 +518,7 @@ typedef struct PBVHVertexIter {
   int gy;
   int i;
   int index;
+  PBVHVertRef vertex;
   bool respect_hide;
 
   /* grid */
@@ -443,7 +563,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
     if (vi.grids) { \
       vi.width = vi.gridsize; \
       vi.height = vi.gridsize; \
-      vi.index = vi.grid_indices[vi.g] * vi.key.grid_area - 1; \
+      vi.index = vi.vertex.i = 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]]; \
@@ -462,6 +582,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
           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++; \
+          vi.vertex.i++; \
           vi.visible = true; \
           if (vi.gh) { \
             if (BLI_BITMAP_TEST(vi.gh, vi.gy * vi.gridsize + vi.gx)) { \
@@ -482,7 +603,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
           } \
           vi.co = vi.mvert->co; \
           vi.no = vi.vert_normals[vi.vert_indices[vi.gx]]; \
-          vi.index = vi.vert_indices[vi.i]; \
+          vi.index = vi.vertex.i = vi.vert_indices[vi.i]; \
           if (vi.vmask) { \
             vi.mask = &vi.vmask[vi.index]; \
           } \
@@ -502,6 +623,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
           } \
           vi.co = vi.bm_vert->co; \
           vi.fno = vi.bm_vert->no; \
+          vi.vertex = BKE_pbvh_make_vref((intptr_t)vi.bm_vert); \
           vi.index = BM_elem_index_get(vi.bm_vert); \
           vi.mask = (float *)BM_ELEM_CD_GET_VOID_P(vi.bm_vert, vi.cd_vert_mask_offset); \
         }
@@ -581,8 +703,8 @@ void BKE_pbvh_node_num_loops(PBVH *pbvh, PBVHNode *node, int *r_totloop);
 void BKE_pbvh_update_active_vcol(PBVH *pbvh, const struct Mesh *mesh);
 void BKE_pbvh_pmap_set(PBVH *pbvh, const struct MeshElemMap *pmap);
 
-void BKE_pbvh_vertex_color_set(PBVH *pbvh, int vertex, const float color[4]);
-void BKE_pbvh_vertex_color_get(const PBVH *pbvh, int vertex, float r_color[4]);
+void BKE_pbvh_vertex_color_set(PBVH *pbvh, PBVHVertRef vertex, const float color[4]);
+void BKE_pbvh_vertex_color_get(const PBVH *pbvh, PBVHVertRef vertex, float r_color[4]);
 
 void BKE_pbvh_ensure_node_loops(PBVH *pbvh);
 bool BKE_pbvh_draw_cache_invalid(const PBVH *pbvh);
diff --git a/source/blender/blenkernel/i

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list