[Bf-blender-cvs] [b5f7af31d6d] master: When these features aren't used, there is no sense in storing the corresponding data layers and using their values for computations. Avoiding that should increase performance in many operations that would otherwise have to read, write, or propagate these values. It also means decreased memory usage-- not just for sculpt mode but for any mesh that was in sculpt mode. Previously the mask, face set, and hide status layers were *always* allocated by sculpt mode.

Hans Goudey noreply at git.blender.org
Mon Sep 12 19:50:14 CEST 2022


Commit: b5f7af31d6d474c3b455bacda079969fde7c0962
Author: Hans Goudey
Date:   Mon Sep 12 12:48:35 2022 -0500
Branches: master
https://developer.blender.org/rBb5f7af31d6d474c3b455bacda079969fde7c0962

When these features aren't used, there is no sense in storing the
corresponding data layers and using their values for computations.
Avoiding that should increase performance in many operations that
would otherwise have to read, write, or propagate these values.
It also means decreased memory usage-- not just for sculpt mode
but for any mesh that was in sculpt mode. Previously the mask, face set,
and hide status layers were *always* allocated by sculpt mode.

Here are a few basic tests when masking and face sets are not used:

| Test | Before | After |
| Subsurf Modifier | 148 ms | 126 ms |
| Sculpt Overlay Extraction | 24 ms every redraw | 0 ms |
| Memory usage | 252 MB | 236 MB |

I wouldn't expect any difference when they are used though.

The code changes are mostly just making sculpt features safe for when
the layers aren't stored, and some changes to the conversion to and
from the hide layers. Use of the ".hide_poly" attribute replaces testing
whether face sets are negative in many places.

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

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

M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/DerivedMesh.cc
M	source/blender/blenkernel/intern/paint.cc
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/editors/object/object_remesh.cc
M	source/blender/editors/sculpt_paint/paint_mask.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_dyntopo.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_mask.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_ops.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
M	source/blender/gpu/intern/gpu_shader_builder_stubs.cc
M	source/blender/makesrna/intern/rna_object.c

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

diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 9a067e761d7..b2ecd28e884 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -213,9 +213,7 @@ bool BKE_paint_always_hide_test(struct Object *ob);
 /**
  * Returns non-zero if any of the face's vertices are hidden, zero otherwise.
  */
-bool paint_is_face_hidden(const struct MLoopTri *lt,
-                          const bool *hide_vert,
-                          const struct MLoop *mloop);
+bool paint_is_face_hidden(const struct MLoopTri *lt, const bool *hide_poly);
 /**
  * Returns non-zero if any of the corners of the grid
  * face whose inner corner is at (x, y) are hidden, zero otherwise.
@@ -689,7 +687,7 @@ void BKE_sculpt_update_object_for_edit(struct Depsgraph *depsgraph,
                                        bool need_pmap,
                                        bool need_mask,
                                        bool is_paint_tool);
-void BKE_sculpt_update_object_before_eval(const struct Scene *scene, struct Object *ob_eval);
+void BKE_sculpt_update_object_before_eval(struct Object *ob_eval);
 void BKE_sculpt_update_object_after_eval(struct Depsgraph *depsgraph, struct Object *ob_eval);
 
 /**
@@ -698,6 +696,7 @@ void BKE_sculpt_update_object_after_eval(struct Depsgraph *depsgraph, struct Obj
  */
 struct MultiresModifierData *BKE_sculpt_multires_active(const struct Scene *scene,
                                                         struct Object *ob);
+int *BKE_sculpt_face_sets_ensure(struct Mesh *mesh);
 int BKE_sculpt_mask_layers_ensure(struct Object *ob, struct MultiresModifierData *mmd);
 void BKE_sculpt_toolsettings_data_ensure(struct Scene *scene);
 
@@ -719,18 +718,17 @@ void BKE_sculpt_sync_face_sets_visibility_to_grids(struct Mesh *mesh,
                                                    struct SubdivCCG *subdiv_ccg);
 
 /**
- * Ensures that a Face Set data-layers exists. If it does not, it creates one respecting the
- * visibility stored in the vertices of the mesh. If it does, it copies the visibility from the
- * mesh to the Face Sets. */
-void BKE_sculpt_face_sets_ensure_from_base_mesh_visibility(struct Mesh *mesh);
+ * If a face set layer exists, initialize its visiblity (sign) from the mesh's hidden values.
+ */
+void BKE_sculpt_face_sets_update_from_base_mesh_visibility(struct Mesh *mesh);
 
 /**
- * Ensures we do have expected mesh data in original mesh for the sculpt mode.
+ * Makes sculpt data consistent with other data on the mesh.
  *
  * \note IDs are expected to be original ones here, and calling code should ensure it updates its
  * depsgraph properly after calling this function if it needs up-to-date evaluated data.
  */
-void BKE_sculpt_ensure_orig_mesh_data(struct Scene *scene, struct Object *object);
+void BKE_sculpt_ensure_orig_mesh_data(struct Object *object);
 
 /**
  * Test if PBVH can be used directly for drawing, which is faster than
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 716ee7d2a21..403f3a31ba0 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -674,6 +674,8 @@ const float (*BKE_pbvh_get_vert_normals(const PBVH *pbvh))[3];
 const bool *BKE_pbvh_get_vert_hide(const PBVH *pbvh);
 bool *BKE_pbvh_get_vert_hide_for_write(PBVH *pbvh);
 
+const bool *BKE_pbvh_get_poly_hide(const PBVH *pbvh);
+
 PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node);
 void BKE_pbvh_node_color_buffer_free(PBVH *pbvh);
 bool BKE_pbvh_get_color_layer(const struct Mesh *me,
diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc
index 986e10b3a16..d7db0ad765c 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.cc
+++ b/source/blender/blenkernel/intern/DerivedMesh.cc
@@ -1720,7 +1720,7 @@ void makeDerivedMesh(struct Depsgraph *depsgraph,
 
   BKE_object_free_derived_caches(ob);
   if (DEG_is_active(depsgraph)) {
-    BKE_sculpt_update_object_before_eval(scene, ob);
+    BKE_sculpt_update_object_before_eval(ob);
   }
 
   /* NOTE: Access the `edit_mesh` after freeing the derived caches, so that `ob->data` is restored
diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc
index f5f460c6ed4..fd4696f97fb 100644
--- a/source/blender/blenkernel/intern/paint.cc
+++ b/source/blender/blenkernel/intern/paint.cc
@@ -1247,13 +1247,12 @@ void BKE_paint_blend_read_lib(BlendLibReader *reader, Scene *sce, Paint *p)
   }
 }
 
-bool paint_is_face_hidden(const MLoopTri *lt, const bool *hide_vert, const MLoop *mloop)
+bool paint_is_face_hidden(const MLoopTri *lt, const bool *hide_poly)
 {
-  if (!hide_vert) {
+  if (!hide_poly) {
     return false;
   }
-  return ((hide_vert[mloop[lt->tri[0]].v]) || (hide_vert[mloop[lt->tri[1]].v]) ||
-          (hide_vert[mloop[lt->tri[2]].v]));
+  return hide_poly[lt->poly];
 }
 
 bool paint_is_grid_face_hidden(const uint *grid_hidden, int gridsize, int x, int y)
@@ -1632,15 +1631,8 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
   return false;
 }
 
-/**
- * \param need_mask: So that the evaluated mesh that is returned has mask data.
- */
-static void sculpt_update_object(Depsgraph *depsgraph,
-                                 Object *ob,
-                                 Object *ob_eval,
-                                 bool need_pmap,
-                                 bool need_mask,
-                                 bool is_paint_tool)
+static void sculpt_update_object(
+    Depsgraph *depsgraph, Object *ob, Object *ob_eval, bool need_pmap, bool is_paint_tool)
 {
   Scene *scene = DEG_get_input_scene(depsgraph);
   Sculpt *sd = scene->toolsettings->sculpt;
@@ -1662,15 +1654,6 @@ static void sculpt_update_object(Depsgraph *depsgraph,
 
   ss->scene = scene;
 
-  if (need_mask) {
-    if (mmd == nullptr) {
-      BLI_assert(CustomData_has_layer(&me->vdata, CD_PAINT_MASK));
-    }
-    else {
-      BLI_assert(CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK));
-    }
-  }
-
   ss->shapekey_active = (mmd == nullptr) ? BKE_keyblock_from_object(ob) : nullptr;
 
   /* NOTE: Weight pPaint require mesh info for loop lookup, but it never uses multires code path,
@@ -1726,7 +1709,6 @@ static void sculpt_update_object(Depsgraph *depsgraph,
 
   /* Sculpt Face Sets. */
   if (use_face_sets) {
-    BLI_assert(CustomData_has_layer(&me->pdata, CD_SCULPT_FACE_SETS));
     ss->face_sets = static_cast<int *>(CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS));
   }
   else {
@@ -1859,24 +1841,7 @@ static void sculpt_update_object(Depsgraph *depsgraph,
   }
 }
 
-static void sculpt_face_sets_ensure(Mesh *mesh)
-{
-  if (CustomData_has_layer(&mesh->pdata, CD_SCULPT_FACE_SETS)) {
-    return;
-  }
-
-  int *new_face_sets = static_cast<int *>(CustomData_add_layer(
-      &mesh->pdata, CD_SCULPT_FACE_SETS, CD_CONSTRUCT, nullptr, mesh->totpoly));
-
-  /* Initialize the new Face Set data-layer with a default valid visible ID and set the default
-   * color to render it white. */
-  for (int i = 0; i < mesh->totpoly; i++) {
-    new_face_sets[i] = 1;
-  }
-  mesh->face_sets_color_default = 1;
-}
-
-void BKE_sculpt_update_object_before_eval(const Scene *scene, Object *ob_eval)
+void BKE_sculpt_update_object_before_eval(Object *ob_eval)
 {
   /* Update before mesh evaluation in the dependency graph. */
   SculptSession *ss = ob_eval->sculpt;
@@ -1906,16 +1871,6 @@ void BKE_sculpt_update_object_before_eval(const Scene *scene, Object *ob_eval)
       MEM_freeN(nodes);
     }
   }
-
-  if (ss) {
-    Object *ob_orig = DEG_get_original_object(ob_eval);
-    Mesh *mesh = BKE_object_get_original_mesh(ob_orig);
-    MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob_orig);
-
-    /* Ensure attribute layout is still correct. */
-    sculpt_face_sets_ensure(mesh);
-    BKE_sculpt_mask_layers_ensure(ob_orig, mmd);
-  }
 }
 
 void BKE_sculpt_update_object_after_eval(Depsgraph *depsgraph, Object *ob_eval)
@@ -1924,7 +1879,7 @@ void BKE_sculpt_update_object_after_eval(Depsgraph *depsgraph, Object *ob_eval)
    * other data when modifiers change the mesh. */
   Object *ob_orig = DEG_get_original_object(ob_eval);
 
-  sculpt_update_object(depsgraph, ob_orig, ob_eval, false, false, false);
+  sculpt_update_object(depsgraph, ob_orig, ob_eval, false, false);
 }
 
 void BKE_sculpt_color_layer_create_if_needed(Object *object)
@@ -1962,13 +1917,53 @@ void BKE_sculpt_color_layer_create_if_needed(Object *object)
 }
 
 void BKE_sculpt_update_object_for_edit(
-    Depsgraph *depsgraph, Object *ob_orig, bool need_pmap, bool need_mask, bool is_paint_tool)
+    Depsgraph *depsgraph, Object *ob_orig, bool need_pmap, bool /*need_mask*/, bool is_paint_tool)
 {
   BLI_assert(ob_orig == DEG_get_original_object(ob_orig));
 
   Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob_orig);
 
-  sculpt_update_object(depsgraph, ob_orig, ob_eval, need_pmap, need_mask, is_paint_tool);
+  sculpt_update_object(depsgraph, ob_orig, ob_eval, need_pmap, is_paint_tool);
+}
+
+int *BKE_sculpt_face_sets_ensure(Mesh *mesh)
+{
+  using namespace blender;
+  using namespace blender::bke;
+  if (CustomData_has_layer(&mesh->pdata, CD_SCULPT_FACE_SETS)) {
+    return static_cast<int *>(CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS));
+  }
+
+  const AttributeAccessor attributes = mesh->attributes_for_write();
+  const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
+      ".hide_poly", ATTR_DOMAIN_FACE, false);
+
+  MutableSpan<int> face_sets = {
+      static_cast<int *>(CustomData_add_layer(
+          &mesh->pdata, CD_SCULPT_FACE_SETS, CD_CONSTRUCT, nullptr, mesh->totpoly)),
+      mesh->totpoly};
+
+  /* Initialize the new face sets with a default valid visible ID and set the default
+   * color to render it white. */
+  if (hide_poly.is_single() && !hide_poly.get_internal_single()) {
+    face_sets.fill(1);
+  }
+  else {
+    const int face_sets_default_visible_id = 1;
+    const int face_sets_default_hidden_id = -(face_sets_default_visible_id + 1);
+
+    const VArraySpan<bool> hide_poly_span{hide_poly};
+    for (const int i : face_sets.index

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list