[Bf-blender-cvs] [3152d68b700] master: Cleanup: Simplify custom data file writing process

Hans Goudey noreply at git.blender.org
Sun May 29 11:02:13 CEST 2022


Commit: 3152d68b7006f5e5279be01badb4c494ccc9e928
Author: Hans Goudey
Date:   Sun May 29 11:02:10 2022 +0200
Branches: master
https://developer.blender.org/rB3152d68b7006f5e5279be01badb4c494ccc9e928

Cleanup: Simplify custom data file writing process

Previously the function had a fair amount of ugly boilerplate to avoid
allocating the temporary layers array, and then free it if necessary.
`blender::Vector` solves that problem more elegantly. Passing a span,
using references in a few cases, and using a switch statement also make
the functions simpler.

This refactoring is in preparation for D14583 and D14685.

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

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

M	source/blender/blenkernel/BKE_customdata.h
M	source/blender/blenkernel/intern/curves.cc
M	source/blender/blenkernel/intern/customdata.cc
M	source/blender/blenkernel/intern/mesh.cc
M	source/blender/blenkernel/intern/pointcloud.cc
M	source/blender/makesdna/DNA_customdata_types.h

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

diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index f05dfb164cf..64c49830dc5 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -10,6 +10,10 @@
 
 #include "BLI_sys_types.h"
 #include "BLI_utildefines.h"
+#ifdef __cplusplus
+#  include "BLI_span.hh"
+#  include "BLI_vector.hh"
+#endif
 
 #include "DNA_customdata_types.h"
 
@@ -700,39 +704,33 @@ void CustomData_data_transfer(const struct MeshPairRemap *me_remap,
 
 /* .blend file I/O */
 
+#ifdef __cplusplus
+
 /**
  * Prepare given custom data for file writing.
  *
- * \param data: the custom-data to tweak for .blend file writing (modified in place).
- * \param r_write_layers: contains a reduced set of layers to be written to file,
- * use it with #writestruct_at_address()
- * (caller must free it if != \a write_layers_buff).
- *
- * \param write_layers_buff: An optional buffer for r_write_layers (to avoid allocating it).
- * \param write_layers_size: The size of pre-allocated \a write_layer_buff.
+ * \param data: The custom-data to tweak for .blend file writing (modified in place).
+ * \param layers_to_write: A reduced set of layers to be written to file.
  *
- * \warning After this function has ran, given custom data is no more valid from Blender POV
- * (its `totlayer` is invalid). This function shall always be called with localized data
- * (as it is in write_meshes()).
- *
- * \note `data->typemap` is not updated here, since it is always rebuilt on file read anyway.
- * This means written `typemap` does not match written layers (as returned by \a r_write_layers).
- * Trivial to fix is ever needed.
+ * \warning This function invalidates the custom data struct by changing the layer counts and the
+ * #layers pointer, and by invalidating the type map. It expects to work on a shallow copy of
+ * the struct.
  */
-void CustomData_blend_write_prepare(struct CustomData *data,
-                                    struct CustomDataLayer **r_write_layers,
-                                    struct CustomDataLayer *write_layers_buff,
-                                    size_t write_layers_size);
+void CustomData_blend_write_prepare(CustomData &data,
+                                    blender::Vector<CustomDataLayer, 16> &layers_to_write);
 
 /**
- * \param layers: The layers argument assigned by #CustomData_blend_write_prepare.
+ * \param layers_to_write: Layers created by #CustomData_blend_write_prepare.
  */
-void CustomData_blend_write(struct BlendWriter *writer,
-                            struct CustomData *data,
-                            CustomDataLayer *layers,
+void CustomData_blend_write(BlendWriter *writer,
+                            CustomData *data,
+                            blender::Span<CustomDataLayer> layers_to_write,
                             int count,
                             CustomDataMask cddata_mask,
-                            struct ID *id);
+                            ID *id);
+
+#endif
+
 void CustomData_blend_read(struct BlendDataReader *reader, struct CustomData *data, int count);
 
 #ifndef NDEBUG
diff --git a/source/blender/blenkernel/intern/curves.cc b/source/blender/blenkernel/intern/curves.cc
index d38bc790978..ab9dd702630 100644
--- a/source/blender/blenkernel/intern/curves.cc
+++ b/source/blender/blenkernel/intern/curves.cc
@@ -23,6 +23,7 @@
 #include "BLI_span.hh"
 #include "BLI_string.h"
 #include "BLI_utildefines.h"
+#include "BLI_vector.hh"
 
 #include "BKE_anim_data.h"
 #include "BKE_curves.hh"
@@ -48,6 +49,7 @@ using blender::IndexRange;
 using blender::MutableSpan;
 using blender::RandomNumberGenerator;
 using blender::Span;
+using blender::Vector;
 
 static const char *ATTR_POSITION = "position";
 
@@ -121,12 +123,10 @@ static void curves_blend_write(BlendWriter *writer, ID *id, const void *id_addre
 {
   Curves *curves = (Curves *)id;
 
-  CustomDataLayer *players = nullptr, players_buff[CD_TEMP_CHUNK_SIZE];
-  CustomDataLayer *clayers = nullptr, clayers_buff[CD_TEMP_CHUNK_SIZE];
-  CustomData_blend_write_prepare(
-      &curves->geometry.point_data, &players, players_buff, ARRAY_SIZE(players_buff));
-  CustomData_blend_write_prepare(
-      &curves->geometry.curve_data, &clayers, clayers_buff, ARRAY_SIZE(clayers_buff));
+  Vector<CustomDataLayer, 16> point_layers;
+  Vector<CustomDataLayer, 16> curve_layers;
+  CustomData_blend_write_prepare(curves->geometry.point_data, point_layers);
+  CustomData_blend_write_prepare(curves->geometry.curve_data, curve_layers);
 
   /* Write LibData */
   BLO_write_id_struct(writer, Curves, id_address, &curves->id);
@@ -135,13 +135,13 @@ static void curves_blend_write(BlendWriter *writer, ID *id, const void *id_addre
   /* Direct data */
   CustomData_blend_write(writer,
                          &curves->geometry.point_data,
-                         players,
+                         point_layers,
                          curves->geometry.point_num,
                          CD_MASK_ALL,
                          &curves->id);
   CustomData_blend_write(writer,
                          &curves->geometry.curve_data,
-                         clayers,
+                         curve_layers,
                          curves->geometry.curve_num,
                          CD_MASK_ALL,
                          &curves->id);
@@ -152,14 +152,6 @@ static void curves_blend_write(BlendWriter *writer, ID *id, const void *id_addre
   if (curves->adt) {
     BKE_animdata_blend_write(writer, curves->adt);
   }
-
-  /* Remove temporary data. */
-  if (players && players != players_buff) {
-    MEM_freeN(players);
-  }
-  if (clayers && clayers != clayers_buff) {
-    MEM_freeN(clayers);
-  }
 }
 
 static void curves_blend_read_data(BlendDataReader *reader, ID *id)
diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc
index 27e8bf96dc6..da5c8389be2 100644
--- a/source/blender/blenkernel/intern/customdata.cc
+++ b/source/blender/blenkernel/intern/customdata.cc
@@ -25,6 +25,7 @@
 #include "BLI_math_vector.hh"
 #include "BLI_mempool.h"
 #include "BLI_path_util.h"
+#include "BLI_span.hh"
 #include "BLI_string.h"
 #include "BLI_string_utils.h"
 #include "BLI_utildefines.h"
@@ -54,6 +55,9 @@
 /* only for customdata_data_transfer_interp_normal_normals */
 #include "data_transfer_intern.h"
 
+using blender::Span;
+using blender::Vector;
+
 /* number of layers to add when growing a CustomData object */
 #define CUSTOMDATA_GROW 5
 
@@ -4349,45 +4353,19 @@ void CustomData_file_write_info(int type, const char **r_struct_name, int *r_str
   *r_struct_num = typeInfo->structnum;
 }
 
-void CustomData_blend_write_prepare(CustomData *data,
-                                    CustomDataLayer **r_write_layers,
-                                    CustomDataLayer *write_layers_buff,
-                                    size_t write_layers_size)
+void CustomData_blend_write_prepare(CustomData &data, Vector<CustomDataLayer, 16> &layers_to_write)
 {
-  CustomDataLayer *write_layers = write_layers_buff;
-  const size_t chunk_size = (write_layers_size > 0) ? write_layers_size : CD_TEMP_CHUNK_SIZE;
-
-  const int totlayer = data->totlayer;
-  int i, j;
-
-  for (i = 0, j = 0; i < totlayer; i++) {
-    CustomDataLayer *layer = &data->layers[i];
-    /* Layers with this flag set are not written to file. */
-    if ((layer->flag & CD_FLAG_NOCOPY) || layer->anonymous_id != nullptr) {
-      data->totlayer--;
-      // CLOG_WARN(&LOG, "skipping layer %p (%s)", layer, layer->name);
+  for (const CustomDataLayer &layer : Span(data.layers, data.totlayer)) {
+    if (layer.flag & CD_FLAG_NOCOPY) {
+      continue;
     }
-    else {
-      if (UNLIKELY((size_t)j >= write_layers_size)) {
-        if (write_layers == write_layers_buff) {
-          write_layers = (CustomDataLayer *)MEM_malloc_arrayN(
-              (write_layers_size + chunk_size), sizeof(*write_layers), __func__);
-          if (write_layers_buff) {
-            memcpy(write_layers, write_layers_buff, sizeof(*write_layers) * write_layers_size);
-          }
-        }
-        else {
-          write_layers = (CustomDataLayer *)MEM_reallocN(
-              write_layers, sizeof(*write_layers) * (write_layers_size + chunk_size));
-        }
-        write_layers_size += chunk_size;
-      }
-      write_layers[j++] = *layer;
+    if (layer.anonymous_id != nullptr) {
+      continue;
     }
+    layers_to_write.append(layer);
   }
-  BLI_assert(j == data->totlayer);
-  data->maxlayer = data->totlayer; /* We only write that much of data! */
-  *r_write_layers = write_layers;
+  data.totlayer = layers_to_write.size();
+  data.maxlayer = data.totlayer;
 }
 
 int CustomData_sizeof(int type)
@@ -5186,7 +5164,7 @@ static void write_grid_paint_mask(BlendWriter *writer,
 
 void CustomData_blend_write(BlendWriter *writer,
                             CustomData *data,
-                            CustomDataLayer *layers,
+                            Span<CustomDataLayer> layers_to_write,
                             int count,
                             CustomDataMask cddata_mask,
                             ID *id)
@@ -5196,55 +5174,50 @@ void CustomData_blend_write(BlendWriter *writer,
     CustomData_external_write(data, id, cddata_mask, count, 0);
   }
 
-  BLO_write_struct_array_at_address(writer, CustomDataLayer, data->totlayer, data->layers, layers);
-
-  for (int i = 0; i < data->totlayer; i++) {
-    CustomDataLayer *layer = &layers[i];
+  BLO_write_struct_array_at_address(
+      writer, CustomDataLayer, data->totlayer, data->layers, layers_to_write.data());
 
-    if (layer->type == CD_MDEFORMVERT) {
-      /* layer types that allocate own memory need special handling */
-      BKE_defvert_blend_write(writer, count, static_cast<const MDeformVert *>(layer->data));
-    }
-    else if (layer->type == CD_MDISPS) {
-      write_mdisps(
-          writer, count, static_cast<const MDisps *>(layer->data), layer->flag & CD_FLAG_EXTERNAL);
-    }
-    else if (layer->type == CD_PAINT_MASK) {
-      const float *layer_data = static_cast<const float *>(layer->data);
-      BLO_write_raw(writer, sizeof(*layer_data) * count, lay

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list