diff --git a/source/blender/blenkernel/BKE_customdata.hh b/source/blender/blenkernel/BKE_customdata.hh index 12a3f322ddb..a8ab61e9aaa 100644 --- a/source/blender/blenkernel/BKE_customdata.hh +++ b/source/blender/blenkernel/BKE_customdata.hh @@ -699,8 +699,7 @@ enum { CD_FAKE | CD_PROP_FLOAT2, /* UV flag, because we handle both loop's UVs and face's textures. */ - CD_FAKE_LNOR = CD_FAKE | - CD_CUSTOMLOOPNORMAL, /* Because we play with clnor and temp lnor layers here. */ + CD_FAKE_LNOR = CD_FAKE | 500, CD_FAKE_SHARP = CD_FAKE | 200, /* Sharp flag for edges, smooth flag for faces. */ diff --git a/source/blender/blenkernel/BKE_mesh.hh b/source/blender/blenkernel/BKE_mesh.hh index 947da0b6893..bb968be855a 100644 --- a/source/blender/blenkernel/BKE_mesh.hh +++ b/source/blender/blenkernel/BKE_mesh.hh @@ -180,7 +180,7 @@ void normals_calc_corners(Span vert_positions, Span face_normals, Span sharp_edges, Span sharp_faces, - const short2 *clnors_data, + Span custom_normals, CornerNormalSpaceArray *r_lnors_spacearr, MutableSpan r_corner_normals); diff --git a/source/blender/blenkernel/BKE_mesh_legacy_convert.hh b/source/blender/blenkernel/BKE_mesh_legacy_convert.hh index fdb1584e374..b1300add930 100644 --- a/source/blender/blenkernel/BKE_mesh_legacy_convert.hh +++ b/source/blender/blenkernel/BKE_mesh_legacy_convert.hh @@ -18,8 +18,13 @@ struct Mesh; struct MFace; namespace blender::bke { + +void mesh_custom_normals_to_legacy(MutableSpan corner_layers); +void mesh_custom_normals_to_generic(Mesh &mesh); + void mesh_sculpt_mask_to_legacy(MutableSpan vert_layers); void mesh_sculpt_mask_to_generic(Mesh &mesh); + } // namespace blender::bke void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh); diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index b7a949245f9..1c1884a62cd 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -2000,17 +2000,8 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { nullptr, layerSwap_flnor, nullptr}, - /* 41: CD_CUSTOMLOOPNORMAL */ - {sizeof(short[2]), - alignof(short[2]), - "vec2s", - 1, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr}, + /* 41: CD_CUSTOMLOOPNORMAL */ /* DEPRECATED */ + {sizeof(short[2]), alignof(short[2]), "vec2s", 1}, /* 42: CD_SCULPT_FACE_SETS */ /* DEPRECATED */ {sizeof(int), alignof(int), ""}, /* 43: CD_LOCATION */ @@ -2238,7 +2229,7 @@ const CustomData_MeshMasks CD_MASK_MESH = { /*pmask*/ (CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL), /*lmask*/ - (CD_MASK_MDISPS | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), + (CD_MASK_MDISPS | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), }; const CustomData_MeshMasks CD_MASK_DERIVEDMESH = { /*vmask*/ (CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | CD_MASK_SHAPEKEY | CD_MASK_MVERT_SKIN | @@ -2249,8 +2240,7 @@ const CustomData_MeshMasks CD_MASK_DERIVEDMESH = { /*pmask*/ (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL), /*lmask*/ - (CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_ORIGSPACE_MLOOP | - CD_MASK_PROP_ALL), /* XXX: MISSING #CD_MASK_MLOOPTANGENT ? */ + (CD_MASK_ORIGSPACE_MLOOP | CD_MASK_PROP_ALL), /* XXX: MISSING #CD_MASK_MLOOPTANGENT ? */ }; const CustomData_MeshMasks CD_MASK_BMESH = { /*vmask*/ (CD_MASK_MDEFORMVERT | CD_MASK_MVERT_SKIN | CD_MASK_SHAPEKEY | @@ -2260,7 +2250,7 @@ const CustomData_MeshMasks CD_MASK_BMESH = { /*pmask*/ (CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL), /*lmask*/ - (CD_MASK_MDISPS | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), + (CD_MASK_MDISPS | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), }; const CustomData_MeshMasks CD_MASK_EVERYTHING = { /*vmask*/ (CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | @@ -2274,8 +2264,8 @@ const CustomData_MeshMasks CD_MASK_EVERYTHING = { /*pmask*/ (CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL), /*lmask*/ - (CD_MASK_BM_ELEM_PYPTR | CD_MASK_MDISPS | CD_MASK_NORMAL | CD_MASK_CUSTOMLOOPNORMAL | - CD_MASK_MLOOPTANGENT | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), + (CD_MASK_BM_ELEM_PYPTR | CD_MASK_MDISPS | CD_MASK_NORMAL | CD_MASK_MLOOPTANGENT | + CD_MASK_ORIGSPACE_MLOOP | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), }; static const LayerTypeInfo *layerType_getInfo(const eCustomDataType type) diff --git a/source/blender/blenkernel/intern/data_transfer.cc b/source/blender/blenkernel/intern/data_transfer.cc index 5e23dc9f086..045e4d5f929 100644 --- a/source/blender/blenkernel/intern/data_transfer.cc +++ b/source/blender/blenkernel/intern/data_transfer.cc @@ -68,9 +68,6 @@ void BKE_object_data_transfer_dttypes_to_cdmask(const int dtdata_types, else if (cddata_type == CD_FAKE_UV) { r_data_masks->lmask |= CD_MASK_PROP_FLOAT2; } - else if (cddata_type == CD_FAKE_LNOR) { - r_data_masks->lmask |= CD_MASK_CUSTOMLOOPNORMAL; - } } } @@ -366,15 +363,13 @@ static void data_transfer_dtdata_type_postprocess(Mesh *me_dst, blender::float3 *loop_nors_dst = static_cast( CustomData_get_layer_for_write(ldata_dst, CD_NORMAL, me_dst->corners_num)); - blender::short2 *custom_nors_dst = static_cast( - CustomData_get_layer_for_write(ldata_dst, CD_CUSTOMLOOPNORMAL, me_dst->corners_num)); - - if (!custom_nors_dst) { - custom_nors_dst = static_cast(CustomData_add_layer( - ldata_dst, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, me_dst->corners_num)); - } bke::MutableAttributeAccessor attributes = me_dst->attributes_for_write(); + bke::SpanAttributeWriter custom_nors_dst = attributes.lookup_or_add_for_write_span( + "custom_normal", bke::AttrDomain::Corner); + if (!custom_nors_dst) { + return; + } bke::SpanAttributeWriter sharp_edges = attributes.lookup_or_add_for_write_span( "sharp_edge", bke::AttrDomain::Edge); const VArraySpan sharp_faces = *attributes.lookup("sharp_face", bke::AttrDomain::Face); @@ -389,7 +384,8 @@ static void data_transfer_dtdata_type_postprocess(Mesh *me_dst, sharp_faces, sharp_edges.span, {loop_nors_dst, me_dst->corners_num}, - {custom_nors_dst, me_dst->corners_num}); + custom_nors_dst.span); + custom_nors_dst.finish(); sharp_edges.finish(); CustomData_free_layers(ldata_dst, CD_NORMAL, me_dst->corners_num); } @@ -1054,7 +1050,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, else if (cddata_type == CD_FAKE_LNOR) { if (r_map) { /* Use #CD_NORMAL as a temporary storage for custom normals in 3D vector form. - * A post-process step will convert this layer to #CD_CUSTOMLOOPNORMAL. */ + * A post-process step will convert this layer to "custom_normal". */ float3 *dst_data = static_cast( CustomData_get_layer_for_write(&me_dst->corner_data, CD_NORMAL, me_dst->corners_num)); if (!dst_data) { @@ -1064,7 +1060,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, if (mix_factor != 1.0f || mix_weights) { MutableSpan(dst_data, me_dst->corners_num).copy_from(me_dst->corner_normals()); } - /* Post-process will convert it back to CD_CUSTOMLOOPNORMAL. */ + /* Post-process will convert it back to "custom_normal". */ data_transfer_layersmapping_add_item_cd(r_map, CD_NORMAL, mix_mode, diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index 659543bc41e..7ecd9d519f4 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -2263,11 +2263,11 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, {reinterpret_cast(vert_normals), mesh->verts_num}); } if (loop_normals_needed) { - const blender::short2 *clnors = static_cast( - CustomData_get_layer(&mesh->corner_data, CD_CUSTOMLOOPNORMAL)); const AttributeAccessor attributes = mesh->attributes(); const VArraySpan sharp_edges = *attributes.lookup("sharp_edge", AttrDomain::Edge); const VArraySpan sharp_faces = *attributes.lookup("sharp_face", AttrDomain::Face); + const VArraySpan custom_normals = *attributes.lookup("custom_normal", + AttrDomain::Corner); mesh::normals_calc_corners( positions, edges, @@ -2279,7 +2279,7 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, {reinterpret_cast(face_normals), faces.size()}, sharp_edges, sharp_faces, - clnors, + custom_normals, nullptr, {reinterpret_cast(r_loop_normals), corner_verts.size()}); } diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 59de24e1e42..ff261d7b88d 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -302,6 +302,7 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address CustomData_blend_write_prepare(mesh->face_data, face_layers, {}); if (!is_undo) { mesh_sculpt_mask_to_legacy(vert_layers); + mesh_custom_normals_to_legacy(loop_layers); } } @@ -471,10 +472,11 @@ void BKE_mesh_ensure_skin_customdata(Mesh *mesh) bool BKE_mesh_has_custom_loop_normals(Mesh *mesh) { if (mesh->runtime->edit_mesh) { - return CustomData_has_layer(&mesh->runtime->edit_mesh->bm->ldata, CD_CUSTOMLOOPNORMAL); + return CustomData_has_layer_named( + &mesh->runtime->edit_mesh->bm->ldata, CD_PROP_INT16_2D, "custom_normal"); } - return CustomData_has_layer(&mesh->corner_data, CD_CUSTOMLOOPNORMAL); + return mesh->attributes().contains("custom_normal"); } namespace blender::bke { diff --git a/source/blender/blenkernel/intern/mesh_attributes.cc b/source/blender/blenkernel/intern/mesh_attributes.cc index b0ceeaa4cc6..06905fbea71 100644 --- a/source/blender/blenkernel/intern/mesh_attributes.cc +++ b/source/blender/blenkernel/intern/mesh_attributes.cc @@ -837,6 +837,9 @@ static std::function get_tag_modified_function(void *owner, const String if (name.startswith(".hide")) { return [owner]() { (static_cast(owner))->tag_visibility_changed(); }; } + if (name == "custom_normal") { + return [owner]() { (static_cast(owner))->tag_custom_normals_changed(); }; + } return {}; } diff --git a/source/blender/blenkernel/intern/mesh_flip_faces.cc b/source/blender/blenkernel/intern/mesh_flip_faces.cc index 9a12cdfb394..d2c894f36f0 100644 --- a/source/blender/blenkernel/intern/mesh_flip_faces.cc +++ b/source/blender/blenkernel/intern/mesh_flip_faces.cc @@ -59,7 +59,6 @@ void mesh_flip_faces(Mesh &mesh, const IndexMask &selection) flip_custom_data_type(faces, mesh.corner_data, selection, CD_TANGENT); flip_custom_data_type(faces, mesh.corner_data, selection, CD_MLOOPTANGENT); - flip_custom_data_type(faces, mesh.corner_data, selection, CD_CUSTOMLOOPNORMAL); flip_custom_data_type(faces, mesh.corner_data, selection, CD_GRID_PAINT_MASK); flip_custom_data_type(faces, mesh.corner_data, selection, CD_ORIGSPACE_MLOOP); flip_custom_data_type(faces, mesh.corner_data, selection, CD_MDISPS); diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index acff1bac002..3ab649d4a46 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -2395,7 +2395,9 @@ void BKE_main_mesh_legacy_convert_auto_smooth(Main &bmain) /* Auto-smooth disabled sharp edge tagging when the evaluated mesh had custom normals. * When the original mesh has custom normals, that's a good sign the evaluated mesh will * have custom normals as well. */ - bool has_custom_normals = CustomData_has_layer(&mesh->corner_data, CD_CUSTOMLOOPNORMAL); + bool has_custom_normals = CustomData_has_layer(&mesh->corner_data, CD_CUSTOMLOOPNORMAL) || + CustomData_has_layer_named( + &mesh->corner_data, CD_PROP_INT16_2D, "custom_normal"); if (has_custom_normals) { continue; } @@ -2509,6 +2511,58 @@ void mesh_sculpt_mask_to_generic(Mesh &mesh) } } +void mesh_custom_normals_to_legacy(MutableSpan corner_layers) +{ + bool changed = false; + for (CustomDataLayer &layer : corner_layers) { + if (StringRef(layer.name) == "custom_normal" && layer.type == CD_PROP_INT16_2D) { + layer.type = CD_CUSTOMLOOPNORMAL; + layer.name[0] = '\0'; + changed = true; + break; + } + } + if (!changed) { + return; + } + /* #CustomData expects the layers to be sorted in increasing order based on type. */ + std::stable_sort( + corner_layers.begin(), + corner_layers.end(), + [](const CustomDataLayer &a, const CustomDataLayer &b) { return a.type < b.type; }); +} + +void mesh_custom_normals_to_generic(Mesh &mesh) +{ + if (mesh.attributes().contains("custom_normal")) { + return; + } + void *data = nullptr; + const ImplicitSharingInfo *sharing_info = nullptr; + for (const int i : IndexRange(mesh.corner_data.totlayer)) { + CustomDataLayer &layer = mesh.corner_data.layers[i]; + if (layer.type == CD_CUSTOMLOOPNORMAL) { + data = layer.data; + sharing_info = layer.sharing_info; + layer.data = nullptr; + layer.sharing_info = nullptr; + CustomData_free_layer(&mesh.corner_data, CD_CUSTOMLOOPNORMAL, mesh.corners_num, i); + break; + } + } + if (data != nullptr) { + CustomData_add_layer_named_with_data(&mesh.corner_data, + CD_PROP_INT16_2D, + data, + mesh.corners_num, + "custom_normal", + sharing_info); + } + if (sharing_info != nullptr) { + sharing_info->remove_user_and_delete_if_last(); + } +} + // } // namespace blender::bke diff --git a/source/blender/blenkernel/intern/mesh_mirror.cc b/source/blender/blenkernel/intern/mesh_mirror.cc index 3c99f214875..42276ee1401 100644 --- a/source/blender/blenkernel/intern/mesh_mirror.cc +++ b/source/blender/blenkernel/intern/mesh_mirror.cc @@ -390,12 +390,13 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, } /* handle custom split normals */ - if (ob->type == OB_MESH && CustomData_has_layer(&result->corner_data, CD_CUSTOMLOOPNORMAL) && - result->faces_num > 0) + bke::MutableAttributeAccessor attributes = result->attributes_for_write(); + bke::GAttributeWriter custom_normals = attributes.lookup_for_write("custom_normal"); + if (ob->type == OB_MESH && custom_normals && custom_normals.domain == bke::AttrDomain::Corner && + custom_normals.varray.type().is() && result->faces_num > 0) { blender::Array corner_normals(result_corner_verts.size()); - blender::short2 *clnors = static_cast(CustomData_get_layer_for_write( - &result->corner_data, CD_CUSTOMLOOPNORMAL, result->corners_num)); + MutableVArraySpan clnors(custom_normals.varray.typed()); blender::bke::mesh::CornerNormalSpaceArray lnors_spacearr; /* The transform matrix of a normal must be @@ -405,7 +406,6 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, transpose_m4(mtx_nor); /* calculate custom normals into corner_normals, then mirror first half into second half */ - const bke::AttributeAccessor attributes = result->attributes(); const VArraySpan sharp_edges = *attributes.lookup("sharp_edge", AttrDomain::Edge); const VArraySpan sharp_faces = *attributes.lookup("sharp_face", AttrDomain::Face); blender::bke::mesh::normals_calc_corners(result->vert_positions(), @@ -441,7 +441,10 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, lnors_spacearr.spaces[space_index], corner_normals[mirrorj]); } } + + clnors.save(); } + custom_normals.finish(); /* handle vgroup stuff */ if (BKE_object_supports_vertex_groups(ob)) { diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index 46d461c30e6..5a3bd78bb8a 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -202,11 +202,22 @@ blender::bke::MeshNormalDomain Mesh::normals_domain(const bool support_sharp_fac return MeshNormalDomain::Point; } - if (CustomData_has_layer(&this->corner_data, CD_CUSTOMLOOPNORMAL)) { - return MeshNormalDomain::Corner; + const bke::AttributeAccessor attributes = this->attributes(); + if (const std::optional custom = attributes.lookup_meta_data("custom_normal")) + { + switch (custom->domain) { + case AttrDomain::Point: + case AttrDomain::Edge: + case AttrDomain::Face: + /* Not supported yet. */ + break; + case AttrDomain::Corner: + return MeshNormalDomain::Corner; + default: + BLI_assert_unreachable(); + } } - const AttributeAccessor attributes = this->attributes(); const VArray sharp_faces = *attributes.lookup_or_default( "sharp_face", AttrDomain::Face, false); @@ -288,8 +299,8 @@ blender::Span Mesh::corner_normals() const const AttributeAccessor attributes = this->attributes(); const VArraySpan sharp_edges = *attributes.lookup("sharp_edge", AttrDomain::Edge); const VArraySpan sharp_faces = *attributes.lookup("sharp_face", AttrDomain::Face); - const short2 *custom_normals = static_cast( - CustomData_get_layer(&this->corner_data, CD_CUSTOMLOOPNORMAL)); + const VArraySpan custom_normals = *attributes.lookup("custom_normal", + AttrDomain::Corner); mesh::normals_calc_corners(this->vert_positions(), this->edges(), this->faces(), @@ -1173,7 +1184,7 @@ void normals_calc_corners(const Span vert_positions, const Span face_normals, const Span sharp_edges, const Span sharp_faces, - const short2 *clnors_data, + const Span custom_normals, CornerNormalSpaceArray *r_lnors_spacearr, MutableSpan r_corner_normals) { @@ -1199,7 +1210,7 @@ void normals_calc_corners(const Span vert_positions, SCOPED_TIMER_AVERAGED(__func__); #endif - if (!r_lnors_spacearr && clnors_data) { + if (!r_lnors_spacearr && !custom_normals.is_empty()) { /* We need to compute lnor spacearr if some custom lnor data are given to us! */ r_lnors_spacearr = &_lnors_spacearr; } @@ -1208,7 +1219,7 @@ void normals_calc_corners(const Span vert_positions, CornerSplitTaskDataCommon common_data; common_data.lnors_spacearr = r_lnors_spacearr; common_data.corner_normals = r_corner_normals; - common_data.clnors_data = {clnors_data, clnors_data ? corner_verts.size() : 0}; + common_data.clnors_data = custom_normals; common_data.positions = vert_positions; common_data.edges = edges; common_data.faces = faces; @@ -1306,7 +1317,7 @@ static void mesh_normals_corner_custom_set(const Span positions, face_normals, sharp_edges, sharp_faces, - r_clnors_data.data(), + r_clnors_data, &lnors_spacearr, corner_normals); @@ -1427,7 +1438,7 @@ static void mesh_normals_corner_custom_set(const Span positions, face_normals, sharp_edges, sharp_faces, - r_clnors_data.data(), + r_clnors_data, &lnors_spacearr, corner_normals); } @@ -1529,16 +1540,12 @@ void normals_corner_custom_set_from_verts(const Span vert_positions, static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const bool use_vertices) { - short2 *clnors = static_cast( - CustomData_get_layer_for_write(&mesh->corner_data, CD_CUSTOMLOOPNORMAL, mesh->corners_num)); - if (clnors != nullptr) { - memset(clnors, 0, sizeof(*clnors) * mesh->corners_num); - } - else { - clnors = static_cast(CustomData_add_layer( - &mesh->corner_data, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, mesh->corners_num)); - } MutableAttributeAccessor attributes = mesh->attributes_for_write(); + SpanAttributeWriter custom_normals = attributes.lookup_or_add_for_write_span( + "custom_normal", AttrDomain::Corner); + if (!custom_normals) { + return; + } SpanAttributeWriter sharp_edges = attributes.lookup_or_add_for_write_span( "sharp_edge", AttrDomain::Edge); const VArraySpan sharp_faces = *attributes.lookup("sharp_face", AttrDomain::Face); @@ -1555,9 +1562,10 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const {reinterpret_cast(r_custom_nors), use_vertices ? mesh->verts_num : mesh->corners_num}, sharp_edges.span, - {clnors, mesh->corners_num}); + custom_normals.span); sharp_edges.finish(); + custom_normals.finish(); } } // namespace blender::bke::mesh diff --git a/source/blender/blenkernel/intern/subdiv_modifier.cc b/source/blender/blenkernel/intern/subdiv_modifier.cc index 14117f02004..8c4fdfdec87 100644 --- a/source/blender/blenkernel/intern/subdiv_modifier.cc +++ b/source/blender/blenkernel/intern/subdiv_modifier.cc @@ -11,6 +11,7 @@ #include "DNA_object_types.h" #include "DNA_userdef_types.h" +#include "BKE_attribute.hh" #include "BKE_customdata.hh" #include "BKE_mesh.hh" #include "BKE_modifier.hh" @@ -84,8 +85,13 @@ static ModifierData *modifier_get_last_enabled_for_mode(const Scene *scene, bool BKE_subsurf_modifier_use_custom_loop_normals(const SubsurfModifierData *smd, const Mesh *mesh) { - return smd->flags & eSubsurfModifierFlag_UseCustomNormals && - CustomData_has_layer(&mesh->corner_data, CD_CUSTOMLOOPNORMAL); + if ((smd->flags & eSubsurfModifierFlag_UseCustomNormals) == 0) { + return false; + } + const std::optional meta_data = mesh->attributes().lookup_meta_data( + "custom_normal"); + return meta_data && meta_data->domain == AttrDomain::Corner && + meta_data->data_type == CD_PROP_INT16_2D; } bool BKE_subsurf_modifier_has_split_normals(const SubsurfModifierData *smd, const Mesh *mesh) diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index 2ebfd7efdef..c90cd5703c3 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -5187,6 +5187,7 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain) * breaking release. */ LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) { blender::bke::mesh_sculpt_mask_to_generic(*mesh); + blender::bke::mesh_custom_normals_to_generic(*mesh); } /** diff --git a/source/blender/bmesh/intern/bmesh_mesh_normals.cc b/source/blender/bmesh/intern/bmesh_mesh_normals.cc index 8c80dc3583e..90d35e61d06 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_normals.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_normals.cc @@ -1740,11 +1740,10 @@ void BM_lnorspacearr_store(BMesh *bm, MutableSpan r_lnors) { BLI_assert(bm->lnor_spacearr != nullptr); - if (!CustomData_has_layer(&bm->ldata, CD_CUSTOMLOOPNORMAL)) { - BM_data_layer_add(bm, &bm->ldata, CD_CUSTOMLOOPNORMAL); - } + BM_data_layer_ensure_named(bm, &bm->ldata, CD_PROP_INT16_2D, "custom_normal"); - int cd_loop_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + int cd_loop_clnors_offset = CustomData_get_offset_named( + &bm->ldata, CD_PROP_INT16_2D, "custom_normal"); BM_loops_calc_normal_vcos( bm, {}, {}, {}, true, r_lnors, bm->lnor_spacearr, nullptr, cd_loop_clnors_offset, false); @@ -1837,7 +1836,8 @@ void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor) Array r_lnors(bm->totloop, float3(0)); Array oldnors(preserve_clnor ? bm->totloop : 0, float3(0)); - int cd_loop_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + int cd_loop_clnors_offset = CustomData_get_offset_named( + &bm->ldata, CD_PROP_INT16_2D, "custom_normal"); BM_mesh_elem_index_ensure(bm, BM_LOOP); @@ -1928,7 +1928,8 @@ void BM_lnorspace_err(BMesh *bm) BKE_lnor_spacearr_init(temp, bm->totloop, MLNOR_SPACEARR_BMLOOP_PTR); - int cd_loop_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + int cd_loop_clnors_offset = CustomData_get_offset_named( + &bm->ldata, CD_PROP_INT16_2D, "custom_normal"); Array lnors(bm->totloop, float3(0)); BM_loops_calc_normal_vcos( bm, {}, {}, {}, true, lnors, temp, nullptr, cd_loop_clnors_offset, true); @@ -2151,10 +2152,9 @@ BMLoopNorEditDataArray *BM_loop_normal_editdata_array_init(BMesh *bm, BMLoopNorEditDataArray *lnors_ed_arr = MEM_cnew(__func__); lnors_ed_arr->lidx_to_lnor_editdata = MEM_cnew_array(bm->totloop, __func__); - if (!CustomData_has_layer(&bm->ldata, CD_CUSTOMLOOPNORMAL)) { - BM_data_layer_add(bm, &bm->ldata, CD_CUSTOMLOOPNORMAL); - } - const int cd_custom_normal_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + BM_data_layer_ensure_named(bm, &bm->ldata, CD_PROP_INT16_2D, "custom_normal"); + const int cd_custom_normal_offset = CustomData_get_offset_named( + &bm->ldata, CD_PROP_INT16_2D, "custom_normal"); BM_mesh_elem_index_ensure(bm, BM_LOOP); @@ -2203,7 +2203,7 @@ bool BM_custom_loop_normals_to_vector_layer(BMesh *bm) BMLoop *l; BMIter liter, fiter; - if (!CustomData_has_layer(&bm->ldata, CD_CUSTOMLOOPNORMAL)) { + if (!CustomData_has_layer_named(&bm->ldata, CD_PROP_INT16_2D, "custom_normal")) { return false; } @@ -2216,7 +2216,8 @@ bool BM_custom_loop_normals_to_vector_layer(BMesh *bm) CustomData_set_layer_flag(&bm->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); } - const int cd_custom_normal_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + const int cd_custom_normal_offset = CustomData_get_offset_named( + &bm->ldata, CD_PROP_INT16_2D, "custom_normal"); const int cd_normal_offset = CustomData_get_offset(&bm->ldata, CD_NORMAL); int l_index = 0; @@ -2237,14 +2238,15 @@ bool BM_custom_loop_normals_to_vector_layer(BMesh *bm) void BM_custom_loop_normals_from_vector_layer(BMesh *bm, bool add_sharp_edges) { - if (!CustomData_has_layer(&bm->ldata, CD_CUSTOMLOOPNORMAL) || - !CustomData_has_layer(&bm->ldata, CD_NORMAL)) - { + const int cd_custom_normal_offset = CustomData_get_offset_named( + &bm->ldata, CD_PROP_INT16_2D, "custom_normal"); + if (cd_custom_normal_offset == -1) { return; } - - const int cd_custom_normal_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); const int cd_normal_offset = CustomData_get_offset(&bm->ldata, CD_NORMAL); + if (cd_normal_offset == -1) { + return; + } if (bm->lnor_spacearr == nullptr) { bm->lnor_spacearr = MEM_cnew(__func__); diff --git a/source/blender/bmesh/tools/bmesh_bevel.cc b/source/blender/bmesh/tools/bmesh_bevel.cc index b0dc297616e..630799d416b 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.cc +++ b/source/blender/bmesh/tools/bmesh_bevel.cc @@ -2464,7 +2464,8 @@ static void bevel_harden_normals(BevelParams *bp, BMesh *bm) /* I suspect this is not necessary. TODO: test that guess. */ BM_mesh_normals_update(bm); - int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + int cd_clnors_offset = CustomData_get_offset_named( + &bm->ldata, CD_PROP_INT16_2D, "custom_normal"); /* If there is not already a custom split normal layer then making one * (with #BM_lnorspace_update) will not respect the auto-smooth angle between smooth faces. @@ -2479,7 +2480,7 @@ static void bevel_harden_normals(BevelParams *bp, BMesh *bm) BM_lnorspace_update(bm); if (cd_clnors_offset == -1) { - cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + cd_clnors_offset = CustomData_get_offset_named(&bm->ldata, CD_PROP_INT16_2D, "custom_normal"); } BMIter fiter; diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 8986d97f863..385c22f06ad 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1505,11 +1505,6 @@ void DepsgraphRelationBuilder::build_constraints(ID *id, /* Add dependency on normal layers if necessary. */ if (ct->tar->type == OB_MESH && scon->shrinkType != MOD_SHRINKWRAP_NEAREST_VERTEX) { - bool track = (scon->flag & CON_SHRINKWRAP_TRACK_NORMAL) != 0; - if (track || BKE_shrinkwrap_needs_normals(scon->shrinkType, scon->shrinkMode)) { - add_customdata_mask(ct->tar, - DEGCustomDataMeshMasks::MaskLoop(CD_MASK_CUSTOMLOOPNORMAL)); - } if (scon->shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) { add_special_eval_flag(&ct->tar->id, DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY); } diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc index 0018aa67344..a09e7254243 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc @@ -456,7 +456,7 @@ static bke::MeshNormalDomain bmesh_normals_domain(BMesh *bm) return bke::MeshNormalDomain::Point; } - if (CustomData_has_layer(&bm->ldata, CD_CUSTOMLOOPNORMAL)) { + if (CustomData_has_layer_named(&bm->ldata, CD_PROP_INT16_2D, "custom_normal")) { return bke::MeshNormalDomain::Corner; } @@ -492,7 +492,8 @@ void mesh_render_data_update_corner_normals(MeshRenderData &mr) } else { mr.bm_loop_normals.reinitialize(mr.corners_num); - const int clnors_offset = CustomData_get_offset(&mr.bm->ldata, CD_CUSTOMLOOPNORMAL); + const int clnors_offset = CustomData_get_offset_named( + &mr.bm->ldata, CD_PROP_INT16_2D, "custom_normal"); BM_loops_calc_normal_vcos(mr.bm, mr.bm_vert_coords, mr.bm_vert_normals, diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index 73859f9d44d..286c47cc0fe 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -2206,8 +2206,7 @@ static bool draw_subdiv_create_requested_buffers(Object &ob, runtime_data->stats_totloop = draw_cache.num_subdiv_loops; draw_cache.use_custom_loop_normals = (runtime_data->use_loop_normals) && - CustomData_has_layer(&mesh_eval->corner_data, - CD_CUSTOMLOOPNORMAL); + mesh_eval->attributes().contains("custom_normal"); if (DRW_ibo_requested(mbc.buff.ibo.tris)) { draw_subdiv_cache_ensure_mat_offsets(draw_cache, mesh_eval, batch_cache.mat_len); diff --git a/source/blender/editors/mesh/editmesh_tools.cc b/source/blender/editors/mesh/editmesh_tools.cc index 1203cbc582f..74d3adbede1 100644 --- a/source/blender/editors/mesh/editmesh_tools.cc +++ b/source/blender/editors/mesh/editmesh_tools.cc @@ -2062,7 +2062,7 @@ void MESH_OT_duplicate(wmOperatorType *ot) static BMLoopNorEditDataArray *flip_custom_normals_init_data(BMesh *bm) { BMLoopNorEditDataArray *lnors_ed_arr = nullptr; - if (CustomData_has_layer(&bm->ldata, CD_CUSTOMLOOPNORMAL)) { + if (CustomData_has_layer_named(&bm->ldata, CD_PROP_INT16_2D, "custom_normal")) { /* The mesh has custom normal data, update these too. * Otherwise they will be left in a mangled state. */ @@ -2155,7 +2155,7 @@ static bool flip_custom_normals(BMesh *bm, BMLoopNorEditDataArray *lnors_ed_arr) static void edbm_flip_normals_custom_loop_normals(Object *obedit, BMEditMesh *em) { - if (!CustomData_has_layer(&em->bm->ldata, CD_CUSTOMLOOPNORMAL)) { + if (!CustomData_has_layer_named(&em->bm->ldata, CD_PROP_INT16_2D, "custom_normal")) { return; } @@ -8616,7 +8616,8 @@ static void normals_split(BMesh *bm) BLI_SMALLSTACK_DECLARE(loop_stack, BMLoop *); - const int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + const int cd_clnors_offset = CustomData_get_offset_named( + &bm->ldata, CD_PROP_INT16_2D, "custom_normal"); BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { BLI_assert(BLI_SMALLSTACK_IS_EMPTY(loop_stack)); @@ -8830,7 +8831,8 @@ static int edbm_average_normals_exec(bContext *C, wmOperator *op) bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL; BKE_editmesh_lnorspace_update(em); - const int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + const int cd_clnors_offset = CustomData_get_offset_named( + &bm->ldata, CD_PROP_INT16_2D, "custom_normal"); float weight = absweight / 50.0f; if (absweight == 100.0f) { @@ -9310,7 +9312,8 @@ static int edbm_set_normals_from_faces_exec(bContext *C, wmOperator *op) } BLI_bitmap *loop_set = BLI_BITMAP_NEW(bm->totloop, __func__); - const int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + const int cd_clnors_offset = CustomData_get_offset_named( + &bm->ldata, CD_PROP_INT16_2D, "custom_normal"); BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { BM_ITER_ELEM (e, &eiter, f, BM_EDGES_OF_FACE) { diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index 7186770dd70..3e7683cfc00 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -719,11 +719,14 @@ static int mesh_customdata_custom_splitnormals_add_exec(bContext *C, wmOperator if (mesh->runtime->edit_mesh) { BMesh &bm = *mesh->runtime->edit_mesh->bm; - BM_data_layer_add(&bm, &bm.ldata, CD_CUSTOMLOOPNORMAL); + BM_data_layer_ensure_named(&bm, &bm.ldata, CD_PROP_INT16_2D, "custom_normal"); } else { - CustomData_add_layer( - &mesh->corner_data, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, mesh->corners_num); + if (!mesh->attributes_for_write().add( + "custom_normal", bke::AttrDomain::Corner, bke::AttributeInitDefaultValue())) + { + return OPERATOR_CANCELLED; + } } DEG_id_tag_update(&mesh->id, 0); @@ -753,19 +756,18 @@ static int mesh_customdata_custom_splitnormals_clear_exec(bContext *C, wmOperato if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { BMesh &bm = *em->bm; - if (!CustomData_has_layer(&bm.ldata, CD_CUSTOMLOOPNORMAL)) { + if (!CustomData_has_layer_named(&bm.ldata, CD_PROP_INT16_2D, "custom_normal")) { return OPERATOR_CANCELLED; } - BM_data_layer_free(&bm, &bm.ldata, CD_CUSTOMLOOPNORMAL); + BM_data_layer_free_named(&bm, &bm.ldata, "custom_normal"); if (bm.lnor_spacearr) { BKE_lnor_spacearr_clear(bm.lnor_spacearr); } } else { - if (!CustomData_has_layer(&mesh->corner_data, CD_CUSTOMLOOPNORMAL)) { + if (!mesh->attributes_for_write().remove("custom_normal")) { return OPERATOR_CANCELLED; } - CustomData_free_layers(&mesh->corner_data, CD_CUSTOMLOOPNORMAL, mesh->corners_num); } mesh->tag_custom_normals_changed(); diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index e369c0e2668..10a0068f5de 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -152,8 +152,8 @@ typedef enum eCustomDataType { CD_FREESTYLE_FACE = 38, CD_MLOOPTANGENT = 39, CD_TESSLOOPNORMAL = 40, - CD_CUSTOMLOOPNORMAL = 41, #ifdef DNA_DEPRECATED_ALLOW + CD_CUSTOMLOOPNORMAL = 41, CD_SCULPT_FACE_SETS = 42, #endif @@ -207,7 +207,6 @@ using eCustomDataMask = uint64_t; #define CD_MASK_FREESTYLE_FACE (1LL << CD_FREESTYLE_FACE) #define CD_MASK_MLOOPTANGENT (1LL << CD_MLOOPTANGENT) #define CD_MASK_TESSLOOPNORMAL (1LL << CD_TESSLOOPNORMAL) -#define CD_MASK_CUSTOMLOOPNORMAL (1LL << CD_CUSTOMLOOPNORMAL) #define CD_MASK_PROP_COLOR (1ULL << CD_PROP_COLOR) #define CD_MASK_PROP_FLOAT3 (1ULL << CD_PROP_FLOAT3) #define CD_MASK_PROP_FLOAT2 (1ULL << CD_PROP_FLOAT2) diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index ada4d4f6018..c54a4940843 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -419,7 +419,7 @@ typedef struct Mesh { void tag_positions_changed_no_normals(); /** Call when changing "sharp_face" or "sharp_edge" data. */ void tag_sharpness_changed(); - /** Call when changing #CD_CUSTOMLOOPNORMAL data. */ + /** Call when changing "custom_normal" data. */ void tag_custom_normals_changed(); /** Call when face vertex order has changed but positions and faces haven't changed. */ void tag_face_winding_changed(); diff --git a/source/blender/modifiers/intern/MOD_displace.cc b/source/blender/modifiers/intern/MOD_displace.cc index 1457bcd2843..2b7daf84221 100644 --- a/source/blender/modifiers/intern/MOD_displace.cc +++ b/source/blender/modifiers/intern/MOD_displace.cc @@ -20,6 +20,7 @@ #include "DNA_object_types.h" #include "DNA_screen_types.h" +#include "BKE_attribute.hh" #include "BKE_customdata.hh" #include "BKE_deform.hh" #include "BKE_image.hh" @@ -68,10 +69,6 @@ static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_ if (dmd->texmapping == MOD_DISP_MAP_UV) { r_cddata_masks->fmask |= CD_MASK_MTFACE; } - - if (dmd->direction == MOD_DISP_DIR_CLNOR) { - r_cddata_masks->lmask |= CD_MASK_CUSTOMLOOPNORMAL; - } } static bool depends_on_time(Scene * /*scene*/, ModifierData *md) @@ -296,7 +293,7 @@ static void displaceModifier_do(DisplaceModifierData *dmd, } if (direction == MOD_DISP_DIR_CLNOR) { - if (CustomData_has_layer(&mesh->corner_data, CD_CUSTOMLOOPNORMAL)) { + if (mesh->attributes().contains("custom_normal")) { vert_clnors = static_cast( MEM_malloc_arrayN(positions.size(), sizeof(*vert_clnors), __func__)); BKE_mesh_normals_loop_to_vertex( diff --git a/source/blender/modifiers/intern/MOD_grease_pencil_shrinkwrap.cc b/source/blender/modifiers/intern/MOD_grease_pencil_shrinkwrap.cc index 0176e499ddc..37df4e9a568 100644 --- a/source/blender/modifiers/intern/MOD_grease_pencil_shrinkwrap.cc +++ b/source/blender/modifiers/intern/MOD_grease_pencil_shrinkwrap.cc @@ -107,18 +107,12 @@ static bool is_disabled(const Scene * /*scene*/, ModifierData *md, bool /*use_re static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) { auto *smd = reinterpret_cast(md); - CustomData_MeshMasks mask = {0}; - - if (BKE_shrinkwrap_needs_normals(smd->shrink_type, smd->shrink_mode)) { - mask.lmask |= CD_MASK_CUSTOMLOOPNORMAL; - } if (smd->target != nullptr) { DEG_add_object_relation( ctx->node, smd->target, DEG_OB_COMP_TRANSFORM, "Grease Pencil Shrinkwrap Modifier"); DEG_add_object_relation( ctx->node, smd->target, DEG_OB_COMP_GEOMETRY, "Grease Pencil Shrinkwrap Modifier"); - DEG_add_customdata_mask(ctx->node, smd->target, &mask); if (smd->shrink_type == MOD_SHRINKWRAP_TARGET_PROJECT) { DEG_add_special_eval_flag(ctx->node, &smd->target->id, DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY); } @@ -128,7 +122,6 @@ static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphCont ctx->node, smd->aux_target, DEG_OB_COMP_TRANSFORM, "Grease Pencil Shrinkwrap Modifier"); DEG_add_object_relation( ctx->node, smd->aux_target, DEG_OB_COMP_GEOMETRY, "Grease Pencil Shrinkwrap Modifier"); - DEG_add_customdata_mask(ctx->node, smd->aux_target, &mask); if (smd->shrink_type == MOD_SHRINKWRAP_TARGET_PROJECT) { DEG_add_special_eval_flag( ctx->node, &smd->aux_target->id, DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY); diff --git a/source/blender/modifiers/intern/MOD_multires.cc b/source/blender/modifiers/intern/MOD_multires.cc index c28c143a64e..8683a768f7b 100644 --- a/source/blender/modifiers/intern/MOD_multires.cc +++ b/source/blender/modifiers/intern/MOD_multires.cc @@ -60,14 +60,6 @@ static void init_data(ModifierData *md) md->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT | UI_SUBPANEL_DATA_EXPAND_1; } -static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks) -{ - MultiresModifierData *mmd = (MultiresModifierData *)md; - if (mmd->flags & eMultiresModifierFlag_UseCustomNormals) { - r_cddata_masks->lmask |= CD_MASK_CUSTOMLOOPNORMAL; - } -} - static void copy_data(const ModifierData *md_src, ModifierData *md_dst, const int flag) { BKE_modifier_copydata_generic(md_src, md_dst, flag); @@ -484,7 +476,7 @@ ModifierTypeInfo modifierType_Multires = { /*modify_geometry_set*/ nullptr, /*init_data*/ init_data, - /*required_data_mask*/ required_data_mask, + /*required_data_mask*/ nullptr, /*free_data*/ free_data, /*is_disabled*/ nullptr, /*update_depsgraph*/ nullptr, diff --git a/source/blender/modifiers/intern/MOD_normal_edit.cc b/source/blender/modifiers/intern/MOD_normal_edit.cc index 69d453c9ec8..1cfa6ac1f77 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.cc +++ b/source/blender/modifiers/intern/MOD_normal_edit.cc @@ -497,17 +497,16 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, blender::Array corner_normals; - CustomData *ldata = &result->corner_data; - bke::MutableAttributeAccessor attributes = result->attributes_for_write(); bke::SpanAttributeWriter sharp_edges = attributes.lookup_or_add_for_write_span( "sharp_edge", bke::AttrDomain::Edge); - blender::short2 *clnors = static_cast( - CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, corner_verts.size())); + bke::SpanAttributeWriter custom_nors_dst = attributes.lookup_or_add_for_write_span( + "custom_normal", bke::AttrDomain::Corner); + if (!custom_nors_dst) { + return result; + } if (use_current_clnors) { - clnors = static_cast( - CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, corner_verts.size())); corner_normals.reinitialize(corner_verts.size()); const VArraySpan sharp_faces = *attributes.lookup("sharp_face", bke::AttrDomain::Face); blender::bke::mesh::normals_calc_corners(positions, @@ -520,16 +519,11 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, result->face_normals(), sharp_edges.span, sharp_faces, - clnors, + custom_nors_dst.span, nullptr, corner_normals); } - if (clnors == nullptr) { - clnors = static_cast( - CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, corner_verts.size())); - } - MOD_get_vgroup(ob, result, enmd->defgrp_name, &dvert, &defgrp_index); if (enmd->mode == MOD_NORMALEDIT_MODE_RADIAL) { @@ -537,7 +531,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, ctx, ob, result, - {clnors, result->corners_num}, + custom_nors_dst.span, corner_normals, enmd->mix_mode, enmd->mix_factor, @@ -557,7 +551,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, ctx, ob, result, - {clnors, result->corners_num}, + custom_nors_dst.span, corner_normals, enmd->mix_mode, enmd->mix_factor, @@ -575,6 +569,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, result->runtime->is_original_bmesh = false; + custom_nors_dst.finish(); sharp_edges.finish(); return result; @@ -593,8 +588,6 @@ static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_ { NormalEditModifierData *enmd = (NormalEditModifierData *)md; - r_cddata_masks->lmask |= CD_MASK_CUSTOMLOOPNORMAL; - /* Ask for vertex-groups if we need them. */ if (enmd->defgrp_name[0] != '\0') { r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.cc b/source/blender/modifiers/intern/MOD_shrinkwrap.cc index 51f546aead9..3238d6be146 100644 --- a/source/blender/modifiers/intern/MOD_shrinkwrap.cc +++ b/source/blender/modifiers/intern/MOD_shrinkwrap.cc @@ -102,16 +102,9 @@ static void deform_verts(ModifierData *md, static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) { ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md; - CustomData_MeshMasks mask = {0}; - - if (BKE_shrinkwrap_needs_normals(smd->shrinkType, smd->shrinkMode)) { - mask.lmask |= CD_MASK_CUSTOMLOOPNORMAL; - } - if (smd->target != nullptr) { DEG_add_object_relation(ctx->node, smd->target, DEG_OB_COMP_TRANSFORM, "Shrinkwrap Modifier"); DEG_add_object_relation(ctx->node, smd->target, DEG_OB_COMP_GEOMETRY, "Shrinkwrap Modifier"); - DEG_add_customdata_mask(ctx->node, smd->target, &mask); if (smd->shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) { DEG_add_special_eval_flag(ctx->node, &smd->target->id, DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY); } @@ -121,7 +114,6 @@ static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphCont ctx->node, smd->auxTarget, DEG_OB_COMP_TRANSFORM, "Shrinkwrap Modifier"); DEG_add_object_relation( ctx->node, smd->auxTarget, DEG_OB_COMP_GEOMETRY, "Shrinkwrap Modifier"); - DEG_add_customdata_mask(ctx->node, smd->auxTarget, &mask); if (smd->shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) { DEG_add_special_eval_flag(ctx->node, &smd->auxTarget->id, DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY); } diff --git a/source/blender/modifiers/intern/MOD_subsurf.cc b/source/blender/modifiers/intern/MOD_subsurf.cc index b4128de42b5..5673a98345a 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.cc +++ b/source/blender/modifiers/intern/MOD_subsurf.cc @@ -59,14 +59,6 @@ static void init_data(ModifierData *md) MEMCPY_STRUCT_AFTER(smd, DNA_struct_default_get(SubsurfModifierData), modifier); } -static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks) -{ - SubsurfModifierData *smd = (SubsurfModifierData *)md; - if (smd->flags & eSubsurfModifierFlag_UseCustomNormals) { - r_cddata_masks->lmask |= CD_MASK_CUSTOMLOOPNORMAL; - } -} - static void copy_data(const ModifierData *md, ModifierData *target, const int flag) { #if 0 @@ -497,7 +489,7 @@ ModifierTypeInfo modifierType_Subsurf = { /*modify_geometry_set*/ nullptr, /*init_data*/ init_data, - /*required_data_mask*/ required_data_mask, + /*required_data_mask*/ nullptr, /*free_data*/ free_data, /*is_disabled*/ is_disabled, /*update_depsgraph*/ nullptr, diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.cc b/source/blender/modifiers/intern/MOD_weighted_normal.cc index bc5f6ba83d0..2d302e46fec 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.cc +++ b/source/blender/modifiers/intern/MOD_weighted_normal.cc @@ -82,7 +82,6 @@ struct WeightedNormalData { blender::Span corner_edges; blender::Span loop_to_face; blender::MutableSpan clnors; - bool has_clnors; /* True if clnors already existed, false if we had to create them. */ blender::OffsetIndices faces; blender::Span face_normals; @@ -206,7 +205,6 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, const short mode = wn_data->mode; ModePair *mode_pair = wn_data->mode_pair; - const bool has_clnors = wn_data->has_clnors; bke::mesh::CornerNormalSpaceArray lnors_spacearr; const bool keep_sharp = (wnmd->flag & MOD_WEIGHTEDNORMAL_KEEP_SHARP) != 0; @@ -231,7 +229,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, wn_data->face_normals, wn_data->sharp_edges, wn_data->sharp_faces, - has_clnors ? clnors.data() : nullptr, + clnors, &lnors_spacearr, corner_normals); @@ -359,7 +357,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, face_normals, wn_data->sharp_edges, wn_data->sharp_faces, - has_clnors ? clnors.data() : nullptr, + clnors, nullptr, corner_normals); @@ -504,17 +502,6 @@ static Mesh *modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh weight = (weight - 1) * 25; } - blender::short2 *clnors = static_cast(CustomData_get_layer_for_write( - &result->corner_data, CD_CUSTOMLOOPNORMAL, mesh->corners_num)); - - /* Keep info whether we had clnors, - * it helps when generating clnor spaces and default normals. */ - const bool has_clnors = clnors != nullptr; - if (!clnors) { - clnors = static_cast(CustomData_add_layer( - &result->corner_data, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, corner_verts.size())); - } - const MDeformVert *dvert; int defgrp_index; MOD_get_vgroup(ctx->object, mesh, wnmd->defgrp_name, &dvert, &defgrp_index); @@ -524,6 +511,11 @@ static Mesh *modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh bke::MutableAttributeAccessor attributes = result->attributes_for_write(); bke::SpanAttributeWriter sharp_edges = attributes.lookup_or_add_for_write_span( "sharp_edge", bke::AttrDomain::Edge); + bke::SpanAttributeWriter clnors = attributes.lookup_or_add_for_write_span( + "custom_normal", bke::AttrDomain::Corner); + if (!clnors) { + return result; + } WeightedNormalData wn_data{}; wn_data.verts_num = verts_num; @@ -536,8 +528,7 @@ static Mesh *modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh wn_data.corner_verts = corner_verts; wn_data.corner_edges = corner_edges; wn_data.loop_to_face = loop_to_face_map; - wn_data.clnors = {clnors, mesh->corners_num}; - wn_data.has_clnors = has_clnors; + wn_data.clnors = clnors.span; wn_data.faces = faces; wn_data.face_normals = mesh->face_normals(); @@ -569,6 +560,7 @@ static Mesh *modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh result->runtime->is_original_bmesh = false; sharp_edges.finish(); + clnors.finish(); return result; } @@ -586,8 +578,6 @@ static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_ { WeightedNormalModifierData *wnmd = (WeightedNormalModifierData *)md; - r_cddata_masks->lmask = CD_MASK_CUSTOMLOOPNORMAL; - if (wnmd->defgrp_name[0] != '\0') { r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc index 324ebe16541..7ba068a22d8 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc @@ -125,7 +125,6 @@ static void remove_unsupported_corner_data(Mesh &mesh) CustomData_free_layers(&mesh.corner_data, CD_TANGENT, mesh.corners_num); CustomData_free_layers(&mesh.corner_data, CD_MLOOPTANGENT, mesh.corners_num); CustomData_free_layers(&mesh.corner_data, CD_GRID_PAINT_MASK, mesh.corners_num); - CustomData_free_layers(&mesh.corner_data, CD_CUSTOMLOOPNORMAL, mesh.corners_num); } static void expand_mesh(Mesh &mesh,