[Bf-blender-cvs] [ed8ffec61f8] sculpt-dev: Sculpt-dev: Cleanup sculpt temp attribute API

Joseph Eagar noreply at git.blender.org
Sat Jul 16 05:24:02 CEST 2022


Commit: ed8ffec61f88ab5970028b75aa0ad79fa088f1c2
Author: Joseph Eagar
Date:   Fri Jul 15 20:18:44 2022 -0700
Branches: sculpt-dev
https://developer.blender.org/rBed8ffec61f88ab5970028b75aa0ad79fa088f1c2

Sculpt-dev: Cleanup sculpt temp attribute API

* The sculpt code now handles lifetime ownership
  of SculptCustomLayer structs.  This removes the
  need to create temp attributes and get their
  SculptCustomLayer reference structs in seperate
  steps, as the code can internally update e.g. bmesh
  block offsets for all SculptCustomLayer instances.
* Removed ss->custom_layers.  The SCULPT_SCL_XXX enums
  are no longer used to reference standard attributes
  (though they are used, at the moment, to provide names
   for them).  Instead a new accessor struct, ss->scl,
   has pointers to standard attributes (e.g. ss->scl.automasking_factor,
   ss->scl.fairing_mask, etc).

This is the final version of the API that will be ported to master
(possibly minus the SCULPT_xxx alias functions that simply call
BKE_sculptsession_XXX equivalents).

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

M	intern/guardedalloc/intern/mallocn_guarded_impl.c
M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/intern/brush_engine_presets.c
M	source/blender/blenkernel/intern/object.cc
M	source/blender/blenkernel/intern/paint.c
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/editors/sculpt_paint/paint_vertex.cc
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_array.c
M	source/blender/editors/sculpt_paint/sculpt_automasking.cc
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_face_set.c
M	source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
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_smooth.c
M	source/blender/gpu/intern/gpu_buffers.c
M	source/blender/python/bmesh/bmesh_py_types.c

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

diff --git a/intern/guardedalloc/intern/mallocn_guarded_impl.c b/intern/guardedalloc/intern/mallocn_guarded_impl.c
index 31687808e05..4f9a2a6f47b 100644
--- a/intern/guardedalloc/intern/mallocn_guarded_impl.c
+++ b/intern/guardedalloc/intern/mallocn_guarded_impl.c
@@ -1037,7 +1037,7 @@ static void MemorY_ErroR(const char *block, const char *error)
   print_error("Memoryblock %s: %s\n", block, error);
 
 #ifdef WITH_ASSERT_ABORT
-  abort();
+    abort();
 #endif
 }
 
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 2f9740b9c78..8dd03c1d62b 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -641,10 +641,16 @@ typedef struct SculptFakeNeighbors {
 /* Custom Temporary Attributes */
 
 typedef struct SculptLayerParams {
-  int simple_array : 1;  // cannot be combined with permanent
-  int permanent : 1;     // cannot be combined with simple_array
+  /* Allocate a flat array outside the CustomData system.  Cannot be combined with permanent. */
+  int simple_array : 1;
+
+  /* Do not mark CustomData layer as temporary.  Cannot be combined with simple_array.  Doesn't
+   * work with PBVH_GRIDS.
+   */
+  int permanent : 1;  // cannot be combined with simple_array
   int nocopy : 1;
   int nointerp : 1;
+  int stroke_only : 1; /* release layer at end of struct, except for PBVH_BMESH */
 } SculptLayerParams;
 
 typedef struct SculptCustomLayer {
@@ -665,10 +671,7 @@ typedef struct SculptCustomLayer {
   bool ready;
 } SculptCustomLayer;
 
-/* These custom attributes have references
-  (SculptCustomLayer pointers) inside of ss->custom_layers
-  that are kept up to date with SCULPT_update_customdata_refs.
-  */
+/* Standard names for sculpt attributes. */
 typedef enum {
   SCULPT_SCL_FAIRING_MASK,
   SCULPT_SCL_FAIRING_FADE,
@@ -688,6 +691,8 @@ typedef enum {
 
 #define SCULPT_SCL_GET_NAME(stdattr) ("__" #stdattr)
 
+#define SCULPT_MAX_TEMP_LAYERS 64
+
 typedef struct SculptSession {
   /* Mesh data (not copied) can come either directly from a Mesh, or from a MultiresDM */
   struct { /* Special handling for multires meshes */
@@ -897,17 +902,41 @@ typedef struct SculptSession {
   struct MSculptVert *mdyntopo_verts;  // for non-bmesh
   int mdyntopo_verts_size;
 
-  /*list of up to date custom layer references,
-    note that entries can be NULL if layer doesn't
-    exist.  See SCULPT_SCL_XXX enum above.*/
-  struct SculptCustomLayer *custom_layers[SCULPT_SCL_LAYER_MAX];
+  /* This is a fixed-size array so we can pass pointers to its elements
+   * to client code. This is important to keep bmesh offsets up to date.
+   */
+  struct SculptCustomLayer temp_layers[SCULPT_MAX_TEMP_LAYERS];
+
+  /* Convienence SculptCusotmLayer pointers. */
+
+  struct {
+    /* Persistent base. */
+    SculptCustomLayer *persistent_co;
+    SculptCustomLayer *persistent_no;
+    SculptCustomLayer *persistent_disp;
+
+    /* Fairing. */
+    SculptCustomLayer *fairing_fade;
+    SculptCustomLayer *fairing_mask;
+    SculptCustomLayer *prefairing_co;
+
+    /* Automasking. */
+    SculptCustomLayer *automasking_factor;
+
+    /* Layer brush. */
+    SculptCustomLayer *layer_disp;
+    SculptCustomLayer *layer_id;
+
+    /* Limit Surface */
+    SculptCustomLayer *limit_surface;
+
+    /* Smooth */
+    SculptCustomLayer *smooth_bdist;
+    SculptCustomLayer *smooth_vel;
 
-  /*
-  PBVH_GRIDS cannot store customdata layers in real CustomDataLayers,
-  so we queue the memory allocated for them to free later
-  */
-  struct SculptCustomLayer **layers_to_free;
-  int tot_layers_to_free;
+    /* Face Sets */
+    SculptCustomLayer *orig_fsets;
+  } scl;
 
   bool save_temp_layers;
 
@@ -943,12 +972,12 @@ void BKE_sculptsession_bmesh_attr_update_internal(struct Object *ob);
 void BKE_sculptsession_sync_attributes(struct Object *ob, struct Mesh *me);
 
 void BKE_sculptsession_bmesh_add_layers(struct Object *ob);
-bool BKE_sculptsession_attr_get_layer(struct Object *ob,
-                                      eAttrDomain domain,
-                                      int proptype,
-                                      const char *name,
-                                      SculptCustomLayer *scl,
-                                      SculptLayerParams *params);
+SculptCustomLayer *BKE_sculptsession_attr_layer_get(struct Object *ob,
+                                                    eAttrDomain domain,
+                                                    int proptype,
+                                                    const char *name,
+                                                    SculptLayerParams *params,
+                                                    bool *r_is_new);
 bool BKE_sculptsession_attr_release_layer(struct Object *ob, SculptCustomLayer *scl);
 void BKE_sculptsession_update_attr_refs(struct Object *ob);
 
diff --git a/source/blender/blenkernel/intern/brush_engine_presets.c b/source/blender/blenkernel/intern/brush_engine_presets.c
index 7638baa8484..5427aa2a666 100644
--- a/source/blender/blenkernel/intern/brush_engine_presets.c
+++ b/source/blender/blenkernel/intern/brush_engine_presets.c
@@ -1104,7 +1104,7 @@ void reset_clay_mappings(BrushChannelSet *chset, bool strips)
 }
 
 // adds any missing channels to brushes
-ATTR_NO_OPT void BKE_brush_builtin_patch(Brush *brush, int tool)
+void BKE_brush_builtin_patch(Brush *brush, int tool)
 {
   check_builtin_init();
 
diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc
index 9899c1d6970..aebdce1a7b7 100644
--- a/source/blender/blenkernel/intern/object.cc
+++ b/source/blender/blenkernel/intern/object.cc
@@ -4245,6 +4245,10 @@ void BKE_object_sculpt_data_create(Object *ob)
   BLI_assert((ob->sculpt == nullptr) && (ob->mode & OB_MODE_ALL_SCULPT));
   ob->sculpt = MEM_cnew<SculptSession>(__func__);
   ob->sculpt->mode_type = (eObjectMode)ob->mode;
+
+  for (int i = 0; i < SCULPT_MAX_TEMP_LAYERS; i++) {
+    ob->sculpt->temp_layers[i].released = true;
+  }
 }
 
 bool BKE_object_obdata_texspace_get(Object *ob, char **r_texflag, float **r_loc, float **r_size)
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index dfa13e866f0..ecc130ea5dc 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1543,28 +1543,18 @@ void BKE_sculptsession_free(Object *ob)
 
     sculptsession_free_pbvh(ob);
 
-    for (int i = 0; i < SCULPT_SCL_LAYER_MAX; i++) {
-      MEM_SAFE_FREE(ss->custom_layers[i]);
-    }
-
     MEM_SAFE_FREE(ss->epmap);
     MEM_SAFE_FREE(ss->epmap_mem);
 
     MEM_SAFE_FREE(ss->vemap);
     MEM_SAFE_FREE(ss->vemap_mem);
 
-    bool SCULPT_attr_release_layer(
-        SculptSession * ss, Object * ob, struct SculptCustomLayer * scl);
+    for (int i = 0; i < SCULPT_MAX_TEMP_LAYERS; i++) {
+      SculptCustomLayer *scl = ss->temp_layers + i;
 
-    if (ss->layers_to_free) {
-      for (int i = 0; i < ss->tot_layers_to_free; i++) {
-        if (ss->layers_to_free[i]) {
-          SCULPT_attr_release_layer(ss, ob, ss->layers_to_free[i]);
-          // SCULPT_attr_release_layer frees layers_to_free[i] itself
-        }
+      if (!scl->released && !scl->is_cdlayer) {
+        BKE_sculptsession_attr_release_layer(ob, scl);
       }
-
-      MEM_freeN(ss->layers_to_free);
     }
 
     if (ss->tex_pool) {
@@ -2192,6 +2182,8 @@ void BKE_sculpt_color_layer_create_if_needed(struct Object *object)
   if (object->sculpt && object->sculpt->pbvh) {
     BKE_pbvh_update_active_vcol(object->sculpt->pbvh, orig_me);
   }
+
+  BKE_sculptsession_update_attr_refs(object);
 }
 
 void BKE_sculpt_update_object_for_edit(
@@ -3264,31 +3256,6 @@ static bool sculpt_attr_get_layer(SculptSession *ss,
     out->elemsize = elemsize;
     out->ready = true;
 
-    /*grids cannot store normal customdata layers, and thus
-      we cannot rely on the customdata api to keep track of
-      and free their memory for us.
-
-      so instead we queue them in a dynamic array inside of
-      SculptSession.
-      */
-    if (ss->pbvh && BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
-      ss->tot_layers_to_free++;
-
-      if (!ss->layers_to_free) {
-        ss->layers_to_free = MEM_calloc_arrayN(
-            ss->tot_layers_to_free, sizeof(void *), "ss->layers_to_free");
-      }
-      else {
-        ss->layers_to_free = MEM_recallocN(ss->layers_to_free,
-                                           sizeof(void *) * ss->tot_layers_to_free);
-      }
-
-      SculptCustomLayer *cpy = MEM_callocN(sizeof(SculptCustomLayer), "SculptCustomLayer cpy");
-      *cpy = *out;
-
-      ss->layers_to_free[ss->tot_layers_to_free - 1] = cpy;
-    }
-
     return true;
   }
 
@@ -3446,23 +3413,51 @@ static bool sculpt_attr_get_layer(SculptSession *ss,
   }
 
   out->ready = true;
+  out->released = false;
 
   return true;
 }
 
-bool BKE_sculptsession_attr_get_layer(Object *ob,
-                                      eAttrDomain domain,
-                                      int proptype,
-                                      const char *name,
-                                      SculptCustomLayer *scl,
-                                      SculptLayerParams *params)
+SculptCustomLayer *BKE_sculptsession_attr_layer_get(Object *ob,
+                                                    eAttrDomain domain,
+                                                    int proptype,
+                                                    const char *name,
+                                                    SculptLayerParams *params,
+                                                    bool *r_is_new)
 {
   SculptSession *ss = ob->sculpt;
 
-  bool ret = sculpt_attr_get_layer(ss, ob, domain, proptype, name, scl, true, params);
+  for (int i = 0; i < SCULPT_MAX_TEMP_LAYERS; i++) {
+    SculptCustomLayer *scl = ss->temp_layers + i;
+
+    if (!scl->released && STREQ(scl->name, name) && scl->proptype == proptype &&
+        scl->domain == domain) {
+      if (r_is_new) {
+        *r_is_new = true;
+      }
+
+      return scl;
+    }
+  }
+
+  SculptCustomLayer *scl = NULL;
+  for (int i = 0; i < SCULPT_MAX_TEMP_LAYERS; i++) {
+    if (ss->temp_layers[

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list