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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs