[Bf-blender-cvs] [3a3d9488a16] master: Refactor: Const correct Custom Data API, prepare for CoW

Hans Goudey noreply at git.blender.org
Sat Jan 14 00:22:43 CET 2023


Commit: 3a3d9488a1633bfefabbab422dd22283bca02626
Author: Hans Goudey
Date:   Fri Jan 13 17:21:20 2023 -0600
Branches: master
https://developer.blender.org/rB3a3d9488a1633bfefabbab422dd22283bca02626

Refactor: Const correct Custom Data API, prepare for CoW

Currently you can retrieve a mutable array from a const CustomData.
That makes code unsafe since the compiler can't check for correctness
itself. Fix that by introducing a separate function to retrieve mutable
arrays from CustomData. The new functions have the `_for_write`
suffix that make the code's intention clearer.

Because it makes retrieving write access an explicit step, this change
also makes proper copy-on-write possible for attributes.

Notes:
- The previous "duplicate referenced layer" functions are redundant
  with retrieving layers with write access
- The custom data functions that give a specific index only have
  `for_write` to simplify the API

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

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

M	source/blender/blenkernel/BKE_customdata.h
M	source/blender/blenkernel/BKE_key.h
M	source/blender/blenkernel/BKE_mesh.h
M	source/blender/blenkernel/intern/DerivedMesh.cc
M	source/blender/blenkernel/intern/attribute_access.cc
M	source/blender/blenkernel/intern/cdderivedmesh.c
M	source/blender/blenkernel/intern/curves_geometry.cc
M	source/blender/blenkernel/intern/customdata.cc
M	source/blender/blenkernel/intern/data_transfer.cc
M	source/blender/blenkernel/intern/deform.c
M	source/blender/blenkernel/intern/dynamicpaint.c
M	source/blender/blenkernel/intern/key.cc
M	source/blender/blenkernel/intern/mesh.cc
M	source/blender/blenkernel/intern/mesh_boolean_convert.cc
M	source/blender/blenkernel/intern/mesh_evaluate.cc
M	source/blender/blenkernel/intern/mesh_legacy_convert.cc
M	source/blender/blenkernel/intern/mesh_merge_customdata.cc
M	source/blender/blenkernel/intern/mesh_mirror.cc
M	source/blender/blenkernel/intern/mesh_normals.cc
M	source/blender/blenkernel/intern/mesh_remap.cc
M	source/blender/blenkernel/intern/mesh_validate.cc
M	source/blender/blenkernel/intern/mesh_wrapper.cc
M	source/blender/blenkernel/intern/multires.cc
M	source/blender/blenkernel/intern/multires_reshape_subdivide.c
M	source/blender/blenkernel/intern/multires_reshape_util.c
M	source/blender/blenkernel/intern/multires_unsubdivide.c
M	source/blender/blenkernel/intern/object_facemap.c
M	source/blender/blenkernel/intern/paint.cc
M	source/blender/blenkernel/intern/particle.cc
M	source/blender/blenkernel/intern/particle_distribute.c
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/subdiv_mesh.cc
M	source/blender/blenkernel/intern/subsurf_ccg.c
M	source/blender/blenloader/intern/versioning_250.c
M	source/blender/blenloader/intern/versioning_290.c
M	source/blender/blenloader/intern/versioning_defaults.cc
M	source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc
M	source/blender/editors/mesh/editmesh_mask_extract.c
M	source/blender/editors/mesh/mesh_data.cc
M	source/blender/editors/mesh/meshtools.cc
M	source/blender/editors/object/object_facemap_ops.c
M	source/blender/editors/object/object_modifier.cc
M	source/blender/editors/sculpt_paint/paint_hide.c
M	source/blender/editors/sculpt_paint/paint_mask.c
M	source/blender/editors/sculpt_paint/sculpt_dyntopo.c
M	source/blender/editors/sculpt_paint/sculpt_face_set.cc
M	source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
M	source/blender/geometry/intern/mesh_split_edges.cc
M	source/blender/gpu/intern/gpu_shader_builder_stubs.cc
M	source/blender/io/alembic/exporter/abc_writer_hair.cc
M	source/blender/io/alembic/intern/abc_customdata.cc
M	source/blender/io/alembic/intern/abc_reader_mesh.cc
M	source/blender/io/collada/MeshImporter.cpp
M	source/blender/io/usd/intern/usd_reader_mesh.cc
M	source/blender/makesrna/intern/rna_curves.c
M	source/blender/makesrna/intern/rna_mesh.c
M	source/blender/makesrna/intern/rna_mesh_api.c
M	source/blender/makesrna/intern/rna_pointcloud.c
M	source/blender/modifiers/intern/MOD_array.cc
M	source/blender/modifiers/intern/MOD_cloth.c
M	source/blender/modifiers/intern/MOD_displace.cc
M	source/blender/modifiers/intern/MOD_explode.c
M	source/blender/modifiers/intern/MOD_multires.cc
M	source/blender/modifiers/intern/MOD_normal_edit.cc
M	source/blender/modifiers/intern/MOD_particleinstance.c
M	source/blender/modifiers/intern/MOD_screw.cc
M	source/blender/modifiers/intern/MOD_skin.c
M	source/blender/modifiers/intern/MOD_solidify_extrude.c
M	source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
M	source/blender/modifiers/intern/MOD_subsurf.cc
M	source/blender/modifiers/intern/MOD_triangulate.cc
M	source/blender/modifiers/intern/MOD_uvproject.cc
M	source/blender/modifiers/intern/MOD_uvwarp.cc
M	source/blender/modifiers/intern/MOD_weighted_normal.cc
M	source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
M	source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc

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

diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index b97ac9cc9b9..e7161722925 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -283,21 +283,6 @@ bool CustomData_has_layer(const struct CustomData *data, int type);
 int CustomData_number_of_layers(const struct CustomData *data, int type);
 int CustomData_number_of_layers_typemask(const struct CustomData *data, eCustomDataMask mask);
 
-/**
- * Duplicate data of a layer with flag NOFREE, and remove that flag.
- * \return the layer data.
- */
-void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type, int totelem);
-void *CustomData_duplicate_referenced_layer_n(struct CustomData *data,
-                                              int type,
-                                              int n,
-                                              int totelem);
-void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
-                                                  int type,
-                                                  const char *name,
-                                                  int totelem);
-bool CustomData_is_referenced_layer(struct CustomData *data, int type);
-
 /**
  * Duplicate all the layers with flag NOFREE, and remove the flag from duplicated layers.
  */
@@ -409,11 +394,15 @@ void CustomData_swap_corners(struct CustomData *data, int index, const int *corn
 void CustomData_swap(struct CustomData *data, int index_a, int index_b);
 
 /**
- * Gets a pointer to the data element at index from the first layer of type.
- * \return NULL if there is no layer of type.
+ * Retrieve a pointer to an element of the active layer of the given \a type, chosen by the
+ * \a index, if it exists.
  */
-void *CustomData_get(const struct CustomData *data, int index, int type);
-void *CustomData_get_n(const struct CustomData *data, int type, int index, int n);
+void *CustomData_get_for_write(struct CustomData *data, int index, int type, int totelem);
+/**
+ * Retrieve a pointer to an element of the \a nth layer of the given \a type, chosen by the
+ * \a index, if it exists.
+ */
+void *CustomData_get_n_for_write(struct CustomData *data, int type, int index, int n, int totelem);
 
 /* BMesh Custom Data Functions.
  * Should replace edit-mesh ones with these as well, due to more efficient memory alloc. */
@@ -431,12 +420,29 @@ bool CustomData_set_layer_name(struct CustomData *data, int type, int n, const c
 const char *CustomData_get_layer_name(const struct CustomData *data, int type, int n);
 
 /**
- * Gets a pointer to the active or first layer of type.
- * \return NULL if there is no layer of type.
+ * Retrieve the data array of the active layer of the given \a type, if it exists. Return null
+ * otherwise.
+ */
+const void *CustomData_get_layer(const struct CustomData *data, int type);
+void *CustomData_get_layer_for_write(struct CustomData *data, int type, int totelem);
+
+/**
+ * Retrieve the data array of the \a nth layer of the given \a type, if it exists. Return null
+ * otherwise.
+ */
+const void *CustomData_get_layer_n(const struct CustomData *data, int type, int n);
+void *CustomData_get_layer_n_for_write(struct CustomData *data, int type, int n, int totelem);
+
+/**
+ * Retrieve the data array of the layer with the given \a name and \a type, if it exists. Return
+ * null otherwise.
  */
-void *CustomData_get_layer(const struct CustomData *data, int type);
-void *CustomData_get_layer_n(const struct CustomData *data, int type, int n);
-void *CustomData_get_layer_named(const struct CustomData *data, int type, const char *name);
+const void *CustomData_get_layer_named(const struct CustomData *data, int type, const char *name);
+void *CustomData_get_layer_named_for_write(CustomData *data,
+                                           int type,
+                                           const char *name,
+                                           int totelem);
+
 int CustomData_get_offset(const struct CustomData *data, int type);
 int CustomData_get_offset_named(const CustomData *data, int type, const char *name);
 int CustomData_get_n_offset(const struct CustomData *data, int type, int n);
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index d89ef744449..d868969f9b9 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -145,7 +145,7 @@ void BKE_keyblock_convert_to_mesh(const struct KeyBlock *kb,
  * \param r_loop_normals: if non-NULL, an array of vectors, same length as number of loops.
  */
 void BKE_keyblock_mesh_calc_normals(const struct KeyBlock *kb,
-                                    const struct Mesh *mesh,
+                                    struct Mesh *mesh,
                                     float (*r_vert_normals)[3],
                                     float (*r_poly_normals)[3],
                                     float (*r_loop_normals)[3]);
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 4d81507ef1c..ad964184263 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -759,7 +759,8 @@ void BKE_mesh_polygon_flip_ex(const struct MPoly *mpoly,
                               bool use_loop_mdisp_flip);
 void BKE_mesh_polygon_flip(const struct MPoly *mpoly,
                            struct MLoop *mloop,
-                           struct CustomData *ldata);
+                           struct CustomData *ldata,
+                           int totloop);
 /**
  * Flip (invert winding of) all polygons (used to inverse their normals).
  *
@@ -983,7 +984,7 @@ BLI_INLINE const int *BKE_mesh_material_indices(const Mesh *mesh)
  */
 BLI_INLINE int *BKE_mesh_material_indices_for_write(Mesh *mesh)
 {
-  int *indices = (int *)CustomData_duplicate_referenced_layer_named(
+  int *indices = (int *)CustomData_get_layer_named_for_write(
       &mesh->pdata, CD_PROP_INT32, "material_index", mesh->totpoly);
   if (indices) {
     return indices;
@@ -998,7 +999,7 @@ BLI_INLINE const float (*BKE_mesh_vert_positions(const Mesh *mesh))[3]
 }
 BLI_INLINE float (*BKE_mesh_vert_positions_for_write(Mesh *mesh))[3]
 {
-  return (float(*)[3])CustomData_duplicate_referenced_layer_named(
+  return (float(*)[3])CustomData_get_layer_named_for_write(
       &mesh->vdata, CD_PROP_FLOAT3, "position", mesh->totvert);
 }
 
@@ -1008,7 +1009,7 @@ BLI_INLINE const MEdge *BKE_mesh_edges(const Mesh *mesh)
 }
 BLI_INLINE MEdge *BKE_mesh_edges_for_write(Mesh *mesh)
 {
-  return (MEdge *)CustomData_duplicate_referenced_layer(&mesh->edata, CD_MEDGE, mesh->totedge);
+  return (MEdge *)CustomData_get_layer_for_write(&mesh->edata, CD_MEDGE, mesh->totedge);
 }
 
 BLI_INLINE const MPoly *BKE_mesh_polys(const Mesh *mesh)
@@ -1017,7 +1018,7 @@ BLI_INLINE const MPoly *BKE_mesh_polys(const Mesh *mesh)
 }
 BLI_INLINE MPoly *BKE_mesh_polys_for_write(Mesh *mesh)
 {
-  return (MPoly *)CustomData_duplicate_referenced_layer(&mesh->pdata, CD_MPOLY, mesh->totpoly);
+  return (MPoly *)CustomData_get_layer_for_write(&mesh->pdata, CD_MPOLY, mesh->totpoly);
 }
 
 BLI_INLINE const MLoop *BKE_mesh_loops(const Mesh *mesh)
@@ -1026,7 +1027,7 @@ BLI_INLINE const MLoop *BKE_mesh_loops(const Mesh *mesh)
 }
 BLI_INLINE MLoop *BKE_mesh_loops_for_write(Mesh *mesh)
 {
-  return (MLoop *)CustomData_duplicate_referenced_layer(&mesh->ldata, CD_MLOOP, mesh->totloop);
+  return (MLoop *)CustomData_get_layer_for_write(&mesh->ldata, CD_MLOOP, mesh->totloop);
 }
 
 BLI_INLINE const MDeformVert *BKE_mesh_deform_verts(const Mesh *mesh)
@@ -1035,7 +1036,7 @@ BLI_INLINE const MDeformVert *BKE_mesh_deform_verts(const Mesh *mesh)
 }
 BLI_INLINE MDeformVert *BKE_mesh_deform_verts_for_write(Mesh *mesh)
 {
-  MDeformVert *dvert = (MDeformVert *)CustomData_duplicate_referenced_layer(
+  MDeformVert *dvert = (MDeformVert *)CustomData_get_layer_for_write(
       &mesh->vdata, CD_MDEFORMVERT, mesh->totvert);
   if (dvert) {
     return dvert;
diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc
index 709f52060fc..39a68b72d2a 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.cc
+++ b/source/blender/blenkernel/intern/DerivedMesh.cc
@@ -94,8 +94,8 @@ static void editbmesh_calc_modifier_final_normals_or_defer(
 
 static float *dm_getVertArray(DerivedMesh *dm)
 {
-  float(*positions)[3] = (float(*)[3])CustomData_get_layer_named(
-      &dm->vertData, CD_PROP_FLOAT3, "position");
+  float(*positions)[3] = (float(*)[3])CustomData_get_layer_named_for_write(
+      &dm->vertData, CD_PROP_FLOAT3, "position", dm->getNumVerts(dm));
 
   if (!positions) {
     positions = (float(*)[3])CustomData_add_layer_named(
@@ -109,7 +109,8 @@ static float *dm_getVertArray(DerivedMesh *dm)
 
 static MEdge *dm_getEdgeArray(DerivedMesh *dm)
 {
-  MEdge *medge = (MEdge *)CustomData_get_layer(&dm->edgeData, CD_MEDGE);
+  MEdge *medge = (MEdge *)CustomData_get_layer_for_write(
+      &dm->edgeData, CD_MEDGE, dm->getNumEdges(dm));
 
   if (!medge) {
     medge = (MEdge *)CustomData_add_layer(
@@ -123,7 +124,8 @@ static MEdge *dm_getEdgeArray(DerivedMesh *dm)
 
 static MLoop *dm_getLoopArray(DerivedMesh *dm)
 {
-  MLoop *mloop = (MLoop *)CustomData_get_layer(&dm->loopData, CD_MLOOP);
+  MLoop *mloop = (MLoop *)CustomData_get_layer_for_write(
+      &dm->loopData, CD_MLOOP, dm->getNumLoops(dm));
 
   if (!mloop) {
     mloop = (MLoop *)CustomData_add_layer(
@@ -137,7 +139,8 @@ static MLoop *dm_getLoopArray(DerivedMesh *dm)
 
 static MPoly *dm_getPolyArray(DerivedMesh *dm)
 {
-  MPoly *mpoly = (MPoly *)CustomData_get_layer(&dm->polyData, CD_MPOLY);
+  MPoly *mpoly = (MPoly *)CustomData_get_layer_for_write(
+      &dm->polyData, CD_MPOLY, dm->getNumPolys(dm));
 
   if (!mpoly) {
     mpoly = (MPoly *)CustomData_add_layer(
@@ -351,7 +354,7 @@ static void mesh_set_only_copy(Mesh *mesh, const CustomData_MeshMasks *mask)
 
 void *DM_get_vert_data_layer(DerivedMesh *dm, int type)
 {
-  return CustomData_get_layer(&dm->vertData, type);
+  return CustomData_get_layer_for_write(&dm->vertData, type, dm->getNumVerts(dm));
 }
 
 void *DM_get_ed

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list