From f4308aa2d06e99f131e5eebbbcf9844d1106b78e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Oct 2025 15:03:06 +1100 Subject: [PATCH] UV: remove per-UV-map selection data Replace per UV map selection with a single UV selection for all UV's. This uses the same data as UV sync select, meaning that it's no longer possible to keep a different selection when sync-select is disabled. There is a minor improvement to functionality - previously not possible to de-select a single face surrounding by selected faces. Now this is possible because true face selection is supported. The selection from the active UV-map is converted to use the shared selection data. Ref !147523 Co-authored-by: Hans Goudey --- source/blender/blenkernel/BKE_attribute.h | 4 - .../blender/blenkernel/BKE_blender_version.h | 2 +- source/blender/blenkernel/BKE_customdata.hh | 8 +- .../blenkernel/BKE_mesh_legacy_convert.hh | 2 + source/blender/blenkernel/intern/attribute.cc | 39 -- .../blenkernel/intern/attribute_access.cc | 6 - .../blender/blenkernel/intern/customdata.cc | 4 +- .../blenkernel/intern/geometry_compare.cc | 8 +- .../blenkernel/intern/mesh_legacy_convert.cc | 107 ++-- .../blender/blenkernel/intern/mesh_runtime.cc | 2 +- .../blenloader/intern/versioning_280.cc | 5 +- .../blenloader/intern/versioning_500.cc | 6 + source/blender/bmesh/intern/bmesh_interp.cc | 37 +- source/blender/bmesh/intern/bmesh_interp.hh | 8 +- .../bmesh/intern/bmesh_mesh_convert.cc | 72 +-- source/blender/bmesh/intern/bmesh_query_uv.cc | 4 - .../intern/mesh_extractors/extract_mesh.cc | 2 +- source/blender/editors/include/ED_mesh.hh | 6 - source/blender/editors/include/ED_uvedit.hh | 64 +-- source/blender/editors/mesh/mesh_data.cc | 36 +- .../blender/editors/uvedit/uvedit_intern.hh | 23 + .../blender/editors/uvedit/uvedit_islands.cc | 8 +- source/blender/editors/uvedit/uvedit_ops.cc | 111 ++-- source/blender/editors/uvedit/uvedit_path.cc | 2 +- source/blender/editors/uvedit/uvedit_rip.cc | 18 +- .../blender/editors/uvedit/uvedit_select.cc | 534 ++++++++++-------- .../editors/uvedit/uvedit_smart_stitch.cc | 2 +- .../editors/uvedit/uvedit_unwrap_ops.cc | 39 +- source/blender/makesdna/DNA_mesh_types.h | 6 +- source/blender/makesrna/intern/rna_mesh.cc | 155 ----- .../node_geo_mesh_primitive_ico_sphere.cc | 2 +- .../python/bmesh/bmesh_py_types_customdata.cc | 4 +- .../python/bmesh/bmesh_py_types_meshdata.cc | 65 --- 33 files changed, 535 insertions(+), 856 deletions(-) diff --git a/source/blender/blenkernel/BKE_attribute.h b/source/blender/blenkernel/BKE_attribute.h index 1d6e75d9607..2ea342b6615 100644 --- a/source/blender/blenkernel/BKE_attribute.h +++ b/source/blender/blenkernel/BKE_attribute.h @@ -161,9 +161,5 @@ bool BKE_color_attribute_supported(const struct Mesh &mesh, blender::StringRef n std::string BKE_attribute_calc_unique_name(const AttributeOwner &owner, blender::StringRef name); -[[nodiscard]] blender::StringRef BKE_uv_map_vert_select_name_get(blender::StringRef uv_map_name, - char *buffer); -[[nodiscard]] blender::StringRef BKE_uv_map_edge_select_name_get(blender::StringRef uv_map_name, - char *buffer); [[nodiscard]] blender::StringRef BKE_uv_map_pin_name_get(blender::StringRef uv_map_name, char *buffer); diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index bb1e5a1304a..3f5807ec4a3 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -27,7 +27,7 @@ /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 104 +#define BLENDER_FILE_SUBVERSION 105 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and cancel loading the file, showing a warning to diff --git a/source/blender/blenkernel/BKE_customdata.hh b/source/blender/blenkernel/BKE_customdata.hh index 88204fd5c60..7c3f3e6c1f2 100644 --- a/source/blender/blenkernel/BKE_customdata.hh +++ b/source/blender/blenkernel/BKE_customdata.hh @@ -41,9 +41,7 @@ enum class AttrDomain : int8_t; * has 4 extra bytes above what can be used for the base layer name, and these * prefixes are placed between 2 '.'s at the start of the layer name. * For example The uv vert selection layer of a layer named `UVMap.001` - * will be called `.vs.UVMap.001`. */ -#define UV_VERTSEL_NAME "vs" -#define UV_EDGESEL_NAME "es" + * will be called `.pn.UVMap.001`. */ #define UV_PINNED_NAME "pn" /** @@ -53,13 +51,11 @@ enum class AttrDomain : int8_t; */ struct BMUVOffsets { int uv; - int select_vert; - int select_edge; int pin; }; /** All values reference none layers. */ -#define BMUVOFFSETS_NONE {-1, -1, -1, -1} +#define BMUVOFFSETS_NONE {-1, -1} /* A data type large enough to hold 1 element from any custom-data layer type. */ struct CDBlockBytes { diff --git a/source/blender/blenkernel/BKE_mesh_legacy_convert.hh b/source/blender/blenkernel/BKE_mesh_legacy_convert.hh index 179fa248938..295c4347cfd 100644 --- a/source/blender/blenkernel/BKE_mesh_legacy_convert.hh +++ b/source/blender/blenkernel/BKE_mesh_legacy_convert.hh @@ -20,6 +20,8 @@ struct CustomDataLayer; namespace blender::bke { +void mesh_uv_select_to_single_attribute(Mesh &mesh); + void mesh_custom_normals_to_generic(Mesh &mesh); void mesh_sculpt_mask_to_generic(Mesh &mesh); diff --git a/source/blender/blenkernel/intern/attribute.cc b/source/blender/blenkernel/intern/attribute.cc index 52f4a3c2e7d..ed31cbcddd2 100644 --- a/source/blender/blenkernel/intern/attribute.cc +++ b/source/blender/blenkernel/intern/attribute.cc @@ -324,14 +324,6 @@ bool BKE_attribute_rename(AttributeOwner &owner, char buffer_src[MAX_CUSTOMDATA_LAYER_NAME]; char buffer_dst[MAX_CUSTOMDATA_LAYER_NAME]; - bke_attribute_rename_if_exists(owner, - BKE_uv_map_vert_select_name_get(layer->name, buffer_src), - BKE_uv_map_vert_select_name_get(result_name, buffer_dst), - reports); - bke_attribute_rename_if_exists(owner, - BKE_uv_map_edge_select_name_get(layer->name, buffer_src), - BKE_uv_map_edge_select_name_get(result_name, buffer_dst), - reports); bke_attribute_rename_if_exists(owner, BKE_uv_map_pin_name_get(layer->name, buffer_src), BKE_uv_map_pin_name_get(result_name, buffer_dst), @@ -489,13 +481,6 @@ CustomDataLayer *BKE_attribute_duplicate(AttributeOwner &owner, /* Duplicate UV sub-attributes. */ char buffer_src[MAX_CUSTOMDATA_LAYER_NAME]; char buffer_dst[MAX_CUSTOMDATA_LAYER_NAME]; - - bke_attribute_copy_if_exists(owner, - BKE_uv_map_vert_select_name_get(name, buffer_src), - BKE_uv_map_vert_select_name_get(uniquename, buffer_dst)); - bke_attribute_copy_if_exists(owner, - BKE_uv_map_edge_select_name_get(name, buffer_src), - BKE_uv_map_edge_select_name_get(uniquename, buffer_dst)); bke_attribute_copy_if_exists(owner, BKE_uv_map_pin_name_get(name, buffer_src), BKE_uv_map_pin_name_get(uniquename, buffer_dst)); @@ -575,10 +560,6 @@ bool BKE_attribute_remove(AttributeOwner &owner, const StringRef name, ReportLis if (type == CD_PROP_FLOAT2 && domain == int(AttrDomain::Corner)) { char buffer[MAX_CUSTOMDATA_LAYER_NAME]; - BM_data_layer_free_named( - em->bm, data, BKE_uv_map_vert_select_name_get(name_copy, buffer)); - BM_data_layer_free_named( - em->bm, data, BKE_uv_map_edge_select_name_get(name_copy, buffer)); BM_data_layer_free_named(em->bm, data, BKE_uv_map_pin_name_get(name_copy, buffer)); } return true; @@ -622,8 +603,6 @@ bool BKE_attribute_remove(AttributeOwner &owner, const StringRef name, ReportLis if (metadata->data_type == AttrType::Float2 && metadata->domain == AttrDomain::Corner) { char buffer[MAX_CUSTOMDATA_LAYER_NAME]; - attributes->remove(BKE_uv_map_vert_select_name_get(name_copy, buffer)); - attributes->remove(BKE_uv_map_edge_select_name_get(name_copy, buffer)); attributes->remove(BKE_uv_map_pin_name_get(name_copy, buffer)); } return true; @@ -1070,24 +1049,6 @@ bool BKE_color_attribute_supported(const Mesh &mesh, const StringRef name) return true; } -StringRef BKE_uv_map_vert_select_name_get(const StringRef uv_map_name, char *buffer) -{ - BLI_assert(strlen(UV_VERTSEL_NAME) == 2); - BLI_assert(uv_map_name.size() < MAX_CUSTOMDATA_LAYER_NAME - 4); - const auto result = fmt::format_to_n( - buffer, MAX_CUSTOMDATA_LAYER_NAME, ".{}.{}", UV_VERTSEL_NAME, uv_map_name); - return StringRef(buffer, result.size); -} - -StringRef BKE_uv_map_edge_select_name_get(const StringRef uv_map_name, char *buffer) -{ - BLI_assert(strlen(UV_EDGESEL_NAME) == 2); - BLI_assert(uv_map_name.size() < MAX_CUSTOMDATA_LAYER_NAME - 4); - const auto result = fmt::format_to_n( - buffer, MAX_CUSTOMDATA_LAYER_NAME, ".{}.{}", UV_EDGESEL_NAME, uv_map_name); - return StringRef(buffer, result.size); -} - StringRef BKE_uv_map_pin_name_get(const StringRef uv_map_name, char *buffer) { BLI_assert(strlen(UV_PINNED_NAME) == 2); diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index 8310986bc23..0ea228a7a05 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -219,12 +219,6 @@ bool allow_procedural_attribute_access(StringRef attribute_name) if (attribute_name == ".reference_index") { return false; } - if (attribute_name.startswith("." UV_VERTSEL_NAME ".")) { - return false; - } - if (attribute_name.startswith("." UV_EDGESEL_NAME ".")) { - return false; - } if (attribute_name.startswith("." UV_PINNED_NAME ".")) { return false; } diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index 602597ed52c..8bb9a50ebd6 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -4272,9 +4272,7 @@ int CustomData_name_maxncpy_calc(const blender::StringRef name) if (name.startswith(".")) { return MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX; } - for (const blender::StringRef prefix : - {"." UV_VERTSEL_NAME, UV_EDGESEL_NAME ".", UV_PINNED_NAME "."}) - { + for (const blender::StringRef prefix : {UV_PINNED_NAME "."}) { if (name.startswith(prefix)) { return MAX_CUSTOMDATA_LAYER_NAME; } diff --git a/source/blender/blenkernel/intern/geometry_compare.cc b/source/blender/blenkernel/intern/geometry_compare.cc index 5bb5a3924dc..5f75edb90d7 100644 --- a/source/blender/blenkernel/intern/geometry_compare.cc +++ b/source/blender/blenkernel/intern/geometry_compare.cc @@ -526,8 +526,8 @@ static bool sort_faces_based_on_corners(const IndexMapping &corners, return true; } -/* - * The uv selection / pin layers are ignored in the comparisons because +/** + * The UV selection & pin layers are ignored in the comparisons because * the original flags they replace were ignored as well. Because of the * lazy creation of these layers it would need careful handling of the * test files to compare these layers. For now it has been decided to @@ -535,8 +535,8 @@ static bool sort_faces_based_on_corners(const IndexMapping &corners, */ static bool ignored_attribute(const StringRef id) { - return attribute_name_is_anonymous(id) || id.startswith(".vs.") || id.startswith(".es.") || - id.startswith(".pn."); + return attribute_name_is_anonymous(id) || id.startswith(".pn.") || + ELEM(id, ".uv_select_vert", ".uv_select_edge", ".uv_select_face"); } /** diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 2c0b85da548..cbb2a52eb4e 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -1710,15 +1710,7 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh) [](const uint32_t a, const uint32_t b) { return a | b; }); float2 *coords = MEM_malloc_arrayN(size_t(mesh->corners_num), __func__); - bool *vert_selection = nullptr; - bool *edge_selection = nullptr; bool *pin = nullptr; - if (needed_boolean_attributes & MLOOPUV_VERTSEL) { - vert_selection = MEM_malloc_arrayN(size_t(mesh->corners_num), __func__); - } - if (needed_boolean_attributes & MLOOPUV_EDGESEL) { - edge_selection = MEM_malloc_arrayN(size_t(mesh->corners_num), __func__); - } if (needed_boolean_attributes & MLOOPUV_PINNED) { pin = MEM_malloc_arrayN(size_t(mesh->corners_num), __func__); } @@ -1727,16 +1719,6 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh) for (const int i : range) { coords[i] = mloopuv[i].uv; } - if (vert_selection) { - for (const int i : range) { - vert_selection[i] = mloopuv[i].flag & MLOOPUV_VERTSEL; - } - } - if (edge_selection) { - for (const int i : range) { - edge_selection[i] = mloopuv[i].flag & MLOOPUV_EDGESEL; - } - } if (pin) { for (const int i : range) { pin[i] = mloopuv[i].flag & MLOOPUV_PINNED; @@ -1753,22 +1735,6 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh) CustomData_add_layer_named_with_data( &mesh->corner_data, CD_PROP_FLOAT2, coords, mesh->corners_num, new_name, nullptr); char buffer[MAX_CUSTOMDATA_LAYER_NAME]; - if (vert_selection) { - CustomData_add_layer_named_with_data(&mesh->corner_data, - CD_PROP_BOOL, - vert_selection, - mesh->corners_num, - BKE_uv_map_vert_select_name_get(new_name, buffer), - nullptr); - } - if (edge_selection) { - CustomData_add_layer_named_with_data(&mesh->corner_data, - CD_PROP_BOOL, - edge_selection, - mesh->corners_num, - BKE_uv_map_edge_select_name_get(new_name, buffer), - nullptr); - } if (pin) { CustomData_add_layer_named_with_data(&mesh->corner_data, CD_PROP_BOOL, @@ -2621,7 +2587,78 @@ void mesh_custom_normals_to_generic(Mesh &mesh) } } -// +void mesh_uv_select_to_single_attribute(Mesh &mesh) +{ + const char *name = CustomData_get_active_layer_name(&mesh.corner_data, CD_PROP_FLOAT2); + if (!name) { + return; + } + const std::string uv_select_vert_name_shared = ".uv_select_vert"; + const std::string uv_select_edge_name_shared = ".uv_select_edge"; + const std::string uv_select_face_name_shared = ".uv_select_face"; + + const std::string uv_select_vert_prefix = ".vs."; + const std::string uv_select_edge_prefix = ".es."; + + const std::string uv_select_vert_name = uv_select_vert_prefix + name; + const std::string uv_select_edge_name = uv_select_edge_prefix + name; + + const int uv_select_vert = CustomData_get_named_layer_index( + &mesh.corner_data, CD_PROP_BOOL, uv_select_vert_name); + const int uv_select_edge = CustomData_get_named_layer_index( + &mesh.corner_data, CD_PROP_BOOL, uv_select_edge_name); + + if (uv_select_vert != -1 && uv_select_edge != -1) { + /* Unlikely either exist but ensure there are no duplicate names. */ + CustomData_free_layer_named(&mesh.corner_data, uv_select_vert_name_shared); + CustomData_free_layer_named(&mesh.corner_data, uv_select_edge_name_shared); + CustomData_free_layer_named(&mesh.face_data, uv_select_face_name_shared); + + STRNCPY_UTF8(mesh.corner_data.layers[uv_select_vert].name, uv_select_vert_name_shared.c_str()); + STRNCPY_UTF8(mesh.corner_data.layers[uv_select_edge].name, uv_select_edge_name_shared.c_str()); + + bool *uv_select_face = MEM_malloc_arrayN(mesh.faces_num, __func__); + CustomData_add_layer_named_with_data(&mesh.face_data, + CD_PROP_BOOL, + uv_select_face, + mesh.faces_num, + uv_select_face_name_shared, + nullptr); + + /* Create a face selection layer (flush from edges). */ + if (mesh.faces_num > 0) { + const OffsetIndices faces = mesh.faces(); + const Span uv_select_edge_data( + static_cast(mesh.corner_data.layers[uv_select_edge].data), mesh.corners_num); + threading::parallel_for(faces.index_range(), 1024, [&](const IndexRange range) { + for (const int face : range) { + uv_select_face[face] = !uv_select_edge_data.slice(faces[face]).contains(false); + } + }); + } + } + + /* Logically a set as names are expected to be unique. + * If there are duplicates, this will remove those too. */ + Vector attributes_to_remove; + for (const int i : IndexRange(mesh.corner_data.totlayer)) { + const CustomDataLayer &layer = mesh.corner_data.layers[i]; + if (layer.type != CD_PROP_BOOL) { + continue; + } + StringRef layer_name = StringRef(layer.name); + if (layer_name.startswith(uv_select_vert_prefix) || + layer_name.startswith(uv_select_edge_prefix)) + { + attributes_to_remove.append(layer.name); + } + } + + for (const StringRef name_to_remove : attributes_to_remove) { + CustomData_free_layer_named(&mesh.corner_data, name_to_remove); + } +} + } // namespace blender::bke /** \} */ diff --git a/source/blender/blenkernel/intern/mesh_runtime.cc b/source/blender/blenkernel/intern/mesh_runtime.cc index 8182aa3383b..f9ab55f9d0d 100644 --- a/source/blender/blenkernel/intern/mesh_runtime.cc +++ b/source/blender/blenkernel/intern/mesh_runtime.cc @@ -335,7 +335,7 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh) mesh->runtime->subsurf_face_dot_tags.clear_and_shrink(); mesh->runtime->subsurf_optimal_display_edges.clear_and_shrink(); mesh->runtime->spatial_groups.reset(); - mesh->flag &= ~ME_NO_OVERLAPPING_TOPOLOGY; + mesh->flag &= ~(ME_NO_OVERLAPPING_TOPOLOGY | ME_FLAG_UV_SELECT_SYNC_VALID); } void Mesh::tag_edges_split() diff --git a/source/blender/blenloader/intern/versioning_280.cc b/source/blender/blenloader/intern/versioning_280.cc index 9618e58007a..97fc0cb3881 100644 --- a/source/blender/blenloader/intern/versioning_280.cc +++ b/source/blender/blenloader/intern/versioning_280.cc @@ -4662,8 +4662,9 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain) } LISTBASE_FOREACH (Mesh *, me, &bmain->meshes) { - me->flag &= ~(ME_FLAG_UNUSED_0 | ME_FLAG_UNUSED_1 | ME_FLAG_UNUSED_3 | ME_FLAG_UNUSED_4 | - ME_FLAG_UNUSED_6 | ME_FLAG_UNUSED_7 | ME_REMESH_REPROJECT_ATTRIBUTES); + me->flag &= ~(ME_FLAG_UNUSED_0 | ME_FLAG_UNUSED_1 | ME_FLAG_UV_SELECT_SYNC_VALID | + ME_FLAG_UNUSED_4 | ME_FLAG_UNUSED_6 | ME_FLAG_UNUSED_7 | + ME_REMESH_REPROJECT_ATTRIBUTES); } LISTBASE_FOREACH (Material *, mat, &bmain->materials) { diff --git a/source/blender/blenloader/intern/versioning_500.cc b/source/blender/blenloader/intern/versioning_500.cc index 4f49f99a4a4..224b18f8838 100644 --- a/source/blender/blenloader/intern/versioning_500.cc +++ b/source/blender/blenloader/intern/versioning_500.cc @@ -3935,6 +3935,12 @@ void blo_do_versions_500(FileData *fd, Library * /*lib*/, Main *bmain) } } + if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 105)) { + LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) { + bke::mesh_uv_select_to_single_attribute(*mesh); + } + } + /** * Always bump subversion in BKE_blender_version.h when adding versioning * code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check. diff --git a/source/blender/bmesh/intern/bmesh_interp.cc b/source/blender/bmesh/intern/bmesh_interp.cc index 83f28e96324..45a7cb59cdb 100644 --- a/source/blender/bmesh/intern/bmesh_interp.cc +++ b/source/blender/bmesh/intern/bmesh_interp.cc @@ -878,25 +878,13 @@ void BM_data_layer_ensure_named(BMesh *bm, CustomData *data, int type, const Str } } -void BM_uv_map_attr_select_and_pin_ensure(BMesh *bm) +void BM_uv_map_attr_pin_ensure_for_all_layers(BMesh *bm) { const int nr_uv_layers = CustomData_number_of_layers(&bm->ldata, CD_PROP_FLOAT2); for (int l = 0; l < nr_uv_layers; l++) { /* NOTE: you can't re-use the return-value of #CustomData_get_layer_name() * because adding layers can invalidate that. */ char name[MAX_CUSTOMDATA_LAYER_NAME]; - BM_data_layer_ensure_named( - bm, - &bm->ldata, - CD_PROP_BOOL, - BKE_uv_map_vert_select_name_get(CustomData_get_layer_name(&bm->ldata, CD_PROP_FLOAT2, l), - name)); - BM_data_layer_ensure_named( - bm, - &bm->ldata, - CD_PROP_BOOL, - BKE_uv_map_edge_select_name_get(CustomData_get_layer_name(&bm->ldata, CD_PROP_FLOAT2, l), - name)); BM_data_layer_ensure_named( bm, &bm->ldata, @@ -905,34 +893,13 @@ void BM_uv_map_attr_select_and_pin_ensure(BMesh *bm) } } -void BM_uv_map_attr_vert_select_ensure(BMesh *bm, const StringRef uv_map_name) -{ - char name[MAX_CUSTOMDATA_LAYER_NAME]; - BM_data_layer_ensure_named( - bm, &bm->ldata, CD_PROP_BOOL, BKE_uv_map_vert_select_name_get(uv_map_name, name)); -} - -void BM_uv_map_attr_edge_select_ensure(BMesh *bm, const StringRef uv_map_name) -{ - char name[MAX_CUSTOMDATA_LAYER_NAME]; - BM_data_layer_ensure_named( - bm, &bm->ldata, CD_PROP_BOOL, BKE_uv_map_edge_select_name_get(uv_map_name, name)); -} - -void BM_uv_map_attr_pin_ensure(BMesh *bm, const StringRef uv_map_name) +void BM_uv_map_attr_pin_ensure_named(BMesh *bm, const StringRef uv_map_name) { char name[MAX_CUSTOMDATA_LAYER_NAME]; BM_data_layer_ensure_named( bm, &bm->ldata, CD_PROP_BOOL, BKE_uv_map_pin_name_get(uv_map_name, name)); } -bool BM_uv_map_attr_vert_select_exists(const BMesh *bm, const StringRef uv_map_name) -{ - char name[MAX_CUSTOMDATA_LAYER_NAME]; - return (CustomData_get_named_layer_index( - &bm->ldata, CD_PROP_BOOL, BKE_uv_map_vert_select_name_get(uv_map_name, name)) != -1); -} - bool BM_uv_map_attr_pin_exists(const BMesh *bm, const StringRef uv_map_name) { char name[MAX_CUSTOMDATA_LAYER_NAME]; diff --git a/source/blender/bmesh/intern/bmesh_interp.hh b/source/blender/bmesh/intern/bmesh_interp.hh index cbd3d92ebb6..3dc5d79cea1 100644 --- a/source/blender/bmesh/intern/bmesh_interp.hh +++ b/source/blender/bmesh/intern/bmesh_interp.hh @@ -77,13 +77,9 @@ bool BM_data_layer_has_named(const BMesh *bm, void BM_data_layer_free(BMesh *bm, CustomData *data, int type); /** Ensure the dependent boolean layers exist for all face corner #CD_PROP_FLOAT2 layers. */ -void BM_uv_map_attr_select_and_pin_ensure(BMesh *bm); +void BM_uv_map_attr_pin_ensure_for_all_layers(BMesh *bm); -void BM_uv_map_attr_vert_select_ensure(BMesh *bm, blender::StringRef uv_map_name); -void BM_uv_map_attr_edge_select_ensure(BMesh *bm, blender::StringRef uv_map_name); -void BM_uv_map_attr_pin_ensure(BMesh *bm, blender::StringRef uv_map_name); - -bool BM_uv_map_attr_vert_select_exists(const BMesh *bm, blender::StringRef uv_map_name); +void BM_uv_map_attr_pin_ensure_named(BMesh *bm, blender::StringRef uv_map_name); bool BM_uv_map_attr_pin_exists(const BMesh *bm, blender::StringRef uv_map_name); /** diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 3a4554eb613..96d062fb467 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -243,24 +243,6 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *mesh, const BMeshFromMeshParams * IndexRange(CustomData_number_of_layers(&mesh_ldata, CD_PROP_FLOAT2))) { char buffer[MAX_CUSTOMDATA_LAYER_NAME]; - { - const StringRef name = BKE_uv_map_vert_select_name_get( - CustomData_get_layer_name(&mesh_ldata, CD_PROP_FLOAT2, layer_index), buffer); - if (CustomData_get_named_layer_index(&mesh_ldata, CD_PROP_BOOL, name) < 0) { - CustomData_add_layer_named( - &mesh_ldata, CD_PROP_BOOL, CD_SET_DEFAULT, mesh->corners_num, name); - temporary_layers_to_delete.append(std::string(name)); - } - } - { - const StringRef name = BKE_uv_map_edge_select_name_get( - CustomData_get_layer_name(&mesh_ldata, CD_PROP_FLOAT2, layer_index), buffer); - if (CustomData_get_named_layer_index(&mesh_ldata, CD_PROP_BOOL, name) < 0) { - CustomData_add_layer_named( - &mesh_ldata, CD_PROP_BOOL, CD_SET_DEFAULT, mesh->corners_num, name); - temporary_layers_to_delete.append(std::string(name)); - } - } { const StringRef name = BKE_uv_map_pin_name_get( CustomData_get_layer_name(&mesh_ldata, CD_PROP_FLOAT2, layer_index), buffer); @@ -596,7 +578,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *mesh, const BMeshFromMeshParams * bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); /* Added in order, clear dirty flag. */ } - bm->uv_select_sync_valid = need_uv_select; + bm->uv_select_sync_valid = (need_uv_select && (mesh->flag & ME_FLAG_UV_SELECT_SYNC_VALID)) != 0; /* -------------------------------------------------------------------- */ /* MSelect clears the array elements (to avoid adding multiple times). @@ -1187,8 +1169,6 @@ static void bm_face_loop_table_build(BMesh &bm, Vector &loop_layers_not_to_copy) { const CustomData &ldata = bm.ldata; - Vector vert_sel_layers; - Vector edge_sel_layers; Vector pin_layers; for (const int i : IndexRange(CustomData_number_of_layers(&ldata, CD_PROP_FLOAT2))) { char const *layer_name = CustomData_get_layer_name(&ldata, CD_PROP_FLOAT2, i); @@ -1199,25 +1179,13 @@ static void bm_face_loop_table_build(BMesh &bm, layers.append(layer_index); } }; - add_bool_layer(vert_sel_layers, BKE_uv_map_vert_select_name_get(layer_name, sub_layer_name)); - add_bool_layer(edge_sel_layers, BKE_uv_map_edge_select_name_get(layer_name, sub_layer_name)); add_bool_layer(pin_layers, BKE_uv_map_pin_name_get(layer_name, sub_layer_name)); } - Array vert_sel_offsets(vert_sel_layers.size()); - Array edge_sel_offsets(edge_sel_layers.size()); Array pin_offsets(pin_layers.size()); - for (const int i : vert_sel_layers.index_range()) { - vert_sel_offsets[i] = ldata.layers[vert_sel_layers[i]].offset; - } - for (const int i : edge_sel_layers.index_range()) { - edge_sel_offsets[i] = ldata.layers[edge_sel_layers[i]].offset; - } for (const int i : pin_layers.index_range()) { pin_offsets[i] = ldata.layers[pin_layers[i]].offset; } - Array need_vert_sel(vert_sel_layers.size(), false); - Array need_edge_sel(edge_sel_layers.size(), false); Array need_pin(pin_layers.size(), false); char hflag = 0; BMIter iter; @@ -1235,16 +1203,6 @@ static void bm_face_loop_table_build(BMesh &bm, for ([[maybe_unused]] const int i : IndexRange(face->len)) { BM_elem_index_set(loop, loop_i); /* set_inline */ loop_table[loop_i] = loop; - for (const int i : vert_sel_offsets.index_range()) { - if (BM_ELEM_CD_GET_BOOL(loop, vert_sel_offsets[i])) { - need_vert_sel[i] = true; - } - } - for (const int i : edge_sel_offsets.index_range()) { - if (BM_ELEM_CD_GET_BOOL(loop, edge_sel_offsets[i])) { - need_edge_sel[i] = true; - } - } for (const int i : pin_offsets.index_range()) { if (BM_ELEM_CD_GET_BOOL(loop, pin_offsets[i])) { need_pin[i] = true; @@ -1257,16 +1215,6 @@ static void bm_face_loop_table_build(BMesh &bm, need_select_poly = (hflag & BM_ELEM_SELECT) != 0; need_hide_poly = (hflag & BM_ELEM_HIDDEN) != 0; - for (const int i : vert_sel_layers.index_range()) { - if (!need_vert_sel[i]) { - loop_layers_not_to_copy.append(vert_sel_layers[i]); - } - } - for (const int i : edge_sel_layers.index_range()) { - if (!need_edge_sel[i]) { - loop_layers_not_to_copy.append(edge_sel_layers[i]); - } - } for (const int i : pin_layers.index_range()) { if (!need_pin[i]) { loop_layers_not_to_copy.append(pin_layers[i]); @@ -1477,6 +1425,12 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *mesh, const BMeshToMeshParam mesh->faces_num = bm->totface; mesh->act_face = -1; + /* Will have been cleared when clearing geometry. */ + const bool need_uv_select = CustomData_has_layer(&bm->ldata, CD_PROP_FLOAT2); + if (need_uv_select & bm->uv_select_sync_valid) { + mesh->flag |= ME_FLAG_UV_SELECT_SYNC_VALID; + } + bool need_select_vert = false; bool need_select_edge = false; bool need_select_poly = false; @@ -1487,11 +1441,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *mesh, const BMeshToMeshParam bool need_sharp_edge = false; bool need_sharp_face = false; bool need_uv_seams = false; - const bool need_uv_select = (bm->uv_select_sync_valid && - /* Avoid redundant layer creation if there is no selection, - * although a "Select All" / "De-select All" clears - * #BMesh::uv_select_sync_valid so it's often not needed. */ - (bm->totvertsel != 0)); Array vert_table; Array edge_table; Array face_table; @@ -1716,6 +1665,12 @@ void BM_mesh_bm_to_me_compact(BMesh &bm, mesh.corners_num = bm.totloop; mesh.faces_num = bm.totface; + /* Will have been cleared when clearing geometry. */ + const bool need_uv_select = CustomData_has_layer(&bm.ldata, CD_PROP_FLOAT2); + if (need_uv_select && bm.uv_select_sync_valid) { + mesh.flag |= ME_FLAG_UV_SELECT_SYNC_VALID; + } + mesh.runtime->deformed_only = true; const bool use_threading = (mesh.faces_num + mesh.edges_num) > 1024; @@ -1733,7 +1688,6 @@ void BM_mesh_bm_to_me_compact(BMesh &bm, bool need_sharp_edge = false; bool need_sharp_face = false; bool need_uv_seams = false; - const bool need_uv_select = bm.uv_select_sync_valid; Array vert_table; Array edge_table; diff --git a/source/blender/bmesh/intern/bmesh_query_uv.cc b/source/blender/bmesh/intern/bmesh_query_uv.cc index d14d095725d..b5f78568dc0 100644 --- a/source/blender/bmesh/intern/bmesh_query_uv.cc +++ b/source/blender/bmesh/intern/bmesh_query_uv.cc @@ -31,10 +31,6 @@ BMUVOffsets BM_uv_map_offsets_from_layer(const BMesh *bm, const int layer) BMUVOffsets offsets; offsets.uv = bm->ldata.layers[layer_index].offset; - offsets.select_vert = CustomData_get_offset_named( - &bm->ldata, CD_PROP_BOOL, BKE_uv_map_vert_select_name_get(name, buffer)); - offsets.select_edge = CustomData_get_offset_named( - &bm->ldata, CD_PROP_BOOL, BKE_uv_map_edge_select_name_get(name, buffer)); offsets.pin = CustomData_get_offset_named( &bm->ldata, CD_PROP_BOOL, BKE_uv_map_pin_name_get(name, buffer)); diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh.cc index c94a2abd65e..219f92831fd 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.cc @@ -38,7 +38,7 @@ void mesh_render_data_face_flag(const MeshRenderData &mr, eattr.v_flag |= VFLAG_FACE_UV_ACTIVE; } if ((offsets.uv != -1) && (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) && - uvedit_face_select_test_ex(mr.toolsettings, mr.bm, efa, offsets)) + uvedit_face_select_test_ex(mr.toolsettings, mr.bm, efa)) { eattr.v_flag |= VFLAG_FACE_UV_SELECT; } diff --git a/source/blender/editors/include/ED_mesh.hh b/source/blender/editors/include/ED_mesh.hh index 2b639240b5f..658b340f75c 100644 --- a/source/blender/editors/include/ED_mesh.hh +++ b/source/blender/editors/include/ED_mesh.hh @@ -520,13 +520,7 @@ void ED_mesh_faces_remove(Mesh *mesh, ReportList *reports, int count); void ED_mesh_geometry_clear(Mesh *mesh); -blender::bke::AttributeWriter ED_mesh_uv_map_vert_select_layer_ensure(Mesh *mesh, - int uv_index); -blender::bke::AttributeWriter ED_mesh_uv_map_edge_select_layer_ensure(Mesh *mesh, - int uv_index); blender::bke::AttributeWriter ED_mesh_uv_map_pin_layer_ensure(Mesh *mesh, int uv_index); -blender::VArray ED_mesh_uv_map_vert_select_layer_get(const Mesh *mesh, int uv_index); -blender::VArray ED_mesh_uv_map_edge_select_layer_get(const Mesh *mesh, int uv_index); blender::VArray ED_mesh_uv_map_pin_layer_get(const Mesh *mesh, int uv_index); void ED_mesh_uv_ensure(Mesh *mesh, const char *name); diff --git a/source/blender/editors/include/ED_uvedit.hh b/source/blender/editors/include/ED_uvedit.hh index 30cee804842..a3630b6e2bc 100644 --- a/source/blender/editors/include/ED_uvedit.hh +++ b/source/blender/editors/include/ED_uvedit.hh @@ -46,7 +46,7 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf); /** * Be careful when using this, it bypasses all synchronization options. */ -void ED_uvedit_select_all(BMesh *bm); +void ED_uvedit_select_all(const ToolSettings *ts, BMesh *bm); void ED_uvedit_foreach_uv(const Scene *scene, BMesh *bm, @@ -149,10 +149,7 @@ void ED_uvedit_sync_uvselect_ensure_if_needed(const ToolSettings *ts, BMesh *bm) /* Visibility and selection tests. */ bool uvedit_face_visible_test_ex(const ToolSettings *ts, const BMFace *efa); -bool uvedit_face_select_test_ex(const ToolSettings *ts, - const BMesh *bm, - const BMFace *efa, - const BMUVOffsets &offsets); +bool uvedit_face_select_test_ex(const ToolSettings *ts, const BMesh *bm, const BMFace *efa); bool uvedit_edge_select_test_ex(const ToolSettings *ts, const BMesh *bm, @@ -164,10 +161,7 @@ bool uvedit_uv_select_test_ex(const ToolSettings *ts, const BMUVOffsets &offsets); bool uvedit_face_visible_test(const Scene *scene, const BMFace *efa); -bool uvedit_face_select_test(const Scene *scene, - const BMesh *bm, - const BMFace *efa, - const BMUVOffsets &offsets); +bool uvedit_face_select_test(const Scene *scene, const BMesh *bm, const BMFace *efa); bool uvedit_edge_select_test(const Scene *scene, const BMesh *bm, const BMLoop *l, @@ -179,24 +173,16 @@ bool uvedit_uv_select_test(const Scene *scene, /* Low level loop selection, this ignores the selection modes. */ -bool uvedit_loop_vert_select_get(const ToolSettings *ts, - const BMesh *bm, - const BMLoop *l, - const BMUVOffsets &offsets); -bool uvedit_loop_edge_select_get(const ToolSettings *ts, - const BMesh *bm, - const BMLoop *l, - const BMUVOffsets &offsets); +bool uvedit_loop_vert_select_get(const ToolSettings *ts, const BMesh *bm, const BMLoop *l); +bool uvedit_loop_edge_select_get(const ToolSettings *ts, const BMesh *bm, const BMLoop *l); void uvedit_loop_vert_select_set(const ToolSettings *ts, const BMesh *bm, BMLoop *l, - const bool select, - const BMUVOffsets &offsets); + const bool select); void uvedit_loop_edge_select_set(const ToolSettings *ts, const BMesh *bm, BMLoop *l, - const bool select, - const BMUVOffsets &offsets); + const bool select); /* Individual UV element selection functions. */ @@ -205,49 +191,31 @@ void uvedit_loop_edge_select_set(const ToolSettings *ts, * * Changes selection state of a single UV Face. */ -void uvedit_face_select_set( - const Scene *scene, BMesh *bm, BMFace *efa, bool select, const BMUVOffsets &offsets); +void uvedit_face_select_set(const Scene *scene, BMesh *bm, BMFace *efa, bool select); /** * \brief Select UV Edge * * Changes selection state of a single UV Edge. */ -void uvedit_edge_select_set( - const Scene *scene, BMesh *bm, BMLoop *l, bool select, const BMUVOffsets &offsets); +void uvedit_edge_select_set(const Scene *scene, BMesh *bm, BMLoop *l, bool select); /** * \brief Select UV Vertex * * Changes selection state of a single UV vertex. */ -void uvedit_uv_select_set( - const Scene *scene, BMesh *bm, BMLoop *l, bool select, const BMUVOffsets &offsets); +void uvedit_uv_select_set(const Scene *scene, BMesh *bm, BMLoop *l, bool select); /* Low level functions for (de)selecting individual UV elements. Ensure UV face visibility before * use. */ -void uvedit_face_select_enable(const Scene *scene, - BMesh *bm, - BMFace *efa, - const BMUVOffsets &offsets); -void uvedit_face_select_disable(const Scene *scene, - BMesh *bm, - BMFace *efa, - const BMUVOffsets &offsets); +void uvedit_face_select_enable(const Scene *scene, BMesh *bm, BMFace *efa); +void uvedit_face_select_disable(const Scene *scene, BMesh *bm, BMFace *efa); -void uvedit_edge_select_enable(const Scene *scene, - BMesh *bm, - BMLoop *l, - const BMUVOffsets &offsets); -void uvedit_edge_select_disable(const Scene *scene, - BMesh *bm, - BMLoop *l, - const BMUVOffsets &offsets); +void uvedit_edge_select_enable(const Scene *scene, BMesh *bm, BMLoop *l); +void uvedit_edge_select_disable(const Scene *scene, BMesh *bm, BMLoop *l); -void uvedit_uv_select_enable(const Scene *scene, BMesh *bm, BMLoop *l, const BMUVOffsets &offsets); -void uvedit_uv_select_disable(const Scene *scene, - BMesh *bm, - BMLoop *l, - const BMUVOffsets &offsets); +void uvedit_uv_select_enable(const Scene *scene, BMesh *bm, BMLoop *l); +void uvedit_uv_select_disable(const Scene *scene, BMesh *bm, BMLoop *l); /* Sticky mode UV element selection functions. */ diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index 6432556aad2..99adf695230 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -238,7 +238,7 @@ int ED_mesh_uv_add( } BM_data_layer_add_named(em->bm, &em->bm->ldata, CD_PROP_FLOAT2, unique_name.c_str()); - BM_uv_map_attr_select_and_pin_ensure(em->bm); + BM_uv_map_attr_pin_ensure_for_all_layers(em->bm); /* copy data from active UV */ if (layernum_dst && do_init) { const int layernum_src = CustomData_get_active_layer(&em->bm->ldata, CD_PROP_FLOAT2); @@ -295,24 +295,6 @@ static blender::VArray get_corner_boolean_attribute(const Mesh &mesh, cons return *attributes.lookup_or_default(name, blender::bke::AttrDomain::Corner, false); } -blender::VArray ED_mesh_uv_map_vert_select_layer_get(const Mesh *mesh, const int uv_index) -{ - using namespace blender::bke; - char buffer[MAX_CUSTOMDATA_LAYER_NAME]; - const char *uv_name = CustomData_get_layer_name(&mesh->corner_data, CD_PROP_FLOAT2, uv_index); - return get_corner_boolean_attribute(*mesh, BKE_uv_map_vert_select_name_get(uv_name, buffer)); -} -blender::VArray ED_mesh_uv_map_edge_select_layer_get(const Mesh *mesh, const int uv_index) -{ - /* UV map edge selections are stored on face corners (loops) and not on edges - * because we need selections per face edge, even when the edge is split in UV space. */ - - using namespace blender::bke; - char buffer[MAX_CUSTOMDATA_LAYER_NAME]; - const char *uv_name = CustomData_get_layer_name(&mesh->corner_data, CD_PROP_FLOAT2, uv_index); - return get_corner_boolean_attribute(*mesh, BKE_uv_map_edge_select_name_get(uv_name, buffer)); -} - blender::VArray ED_mesh_uv_map_pin_layer_get(const Mesh *mesh, const int uv_index) { using namespace blender::bke; @@ -329,22 +311,6 @@ static blender::bke::AttributeWriter ensure_corner_boolean_attribute(Mesh name, blender::bke::AttrDomain::Corner, blender::bke::AttributeInitDefaultValue()); } -blender::bke::AttributeWriter ED_mesh_uv_map_vert_select_layer_ensure(Mesh *mesh, - const int uv_index) -{ - using namespace blender::bke; - char buffer[MAX_CUSTOMDATA_LAYER_NAME]; - const char *uv_name = CustomData_get_layer_name(&mesh->corner_data, CD_PROP_FLOAT2, uv_index); - return ensure_corner_boolean_attribute(*mesh, BKE_uv_map_vert_select_name_get(uv_name, buffer)); -} -blender::bke::AttributeWriter ED_mesh_uv_map_edge_select_layer_ensure(Mesh *mesh, - const int uv_index) -{ - using namespace blender::bke; - char buffer[MAX_CUSTOMDATA_LAYER_NAME]; - const char *uv_name = CustomData_get_layer_name(&mesh->corner_data, CD_PROP_FLOAT2, uv_index); - return ensure_corner_boolean_attribute(*mesh, BKE_uv_map_edge_select_name_get(uv_name, buffer)); -} blender::bke::AttributeWriter ED_mesh_uv_map_pin_layer_ensure(Mesh *mesh, const int uv_index) { using namespace blender::bke; diff --git a/source/blender/editors/uvedit/uvedit_intern.hh b/source/blender/editors/uvedit/uvedit_intern.hh index 04fefd592bc..4bfe976a91a 100644 --- a/source/blender/editors/uvedit/uvedit_intern.hh +++ b/source/blender/editors/uvedit/uvedit_intern.hh @@ -104,6 +104,29 @@ bool uvedit_vert_is_all_other_faces_selected(const ToolSettings *ts, const BMLoop *l, const BMUVOffsets &offsets); +[[nodiscard]] bool uvedit_vert_select_get_no_sync(const ToolSettings *ts, + const BMesh *bm, + const BMLoop *l); +[[nodiscard]] bool uvedit_edge_select_get_no_sync(const ToolSettings *ts, + const BMesh *bm, + const BMLoop *l); +[[nodiscard]] bool uvedit_face_select_get_no_sync(const ToolSettings *ts, + const BMesh *bm, + const BMFace *f); + +void uvedit_vert_select_set_no_sync(const ToolSettings *ts, + const BMesh *bm, + BMLoop *l, + bool select); +void uvedit_edge_select_set_no_sync(const ToolSettings *ts, + const BMesh *bm, + BMLoop *l, + bool select); +void uvedit_face_select_set_no_sync(const ToolSettings *ts, + const BMesh *bm, + BMFace *f, + bool select); + /* utility tool functions */ void uvedit_live_unwrap_update(SpaceImage *sima, Scene *scene, Object *obedit); diff --git a/source/blender/editors/uvedit/uvedit_islands.cc b/source/blender/editors/uvedit/uvedit_islands.cc index 962b49dc016..a734f07cfd1 100644 --- a/source/blender/editors/uvedit/uvedit_islands.cc +++ b/source/blender/editors/uvedit/uvedit_islands.cc @@ -92,16 +92,14 @@ static bool uvedit_is_face_affected_for_calc_uv_islands(const Scene *scene, const BMesh *bm, BMFace *efa, const bool only_selected_faces, - const bool only_selected_uvs, - const BMUVOffsets &uv_offsets) + const bool only_selected_uvs) { if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { return false; } if (only_selected_faces) { if (only_selected_uvs) { - return BM_elem_flag_test(efa, BM_ELEM_SELECT) && - uvedit_face_select_test(scene, bm, efa, uv_offsets); + return BM_elem_flag_test(efa, BM_ELEM_SELECT) && uvedit_face_select_test(scene, bm, efa); } return BM_elem_flag_test(efa, BM_ELEM_SELECT); } @@ -130,7 +128,7 @@ int bm_mesh_calc_uv_islands(const Scene *scene, BMIter iter; BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { const bool face_affected = uvedit_is_face_affected_for_calc_uv_islands( - scene, bm, f, only_selected_faces, only_selected_uvs, uv_offsets); + scene, bm, f, only_selected_faces, only_selected_uvs); BM_elem_flag_set(f, BM_ELEM_TAG, face_affected); } diff --git a/source/blender/editors/uvedit/uvedit_ops.cc b/source/blender/editors/uvedit/uvedit_ops.cc index ef67c0066b4..e34abdc620e 100644 --- a/source/blender/editors/uvedit/uvedit_ops.cc +++ b/source/blender/editors/uvedit/uvedit_ops.cc @@ -257,17 +257,17 @@ bool ED_uvedit_minmax_multi(const Scene *scene, return changed; } -void ED_uvedit_select_all(BMesh *bm) +void ED_uvedit_select_all(const ToolSettings *ts, BMesh *bm) { BMFace *efa; BMLoop *l; BMIter iter, liter; - const BMUVOffsets offsets = BM_uv_map_offsets_get(bm); BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + uvedit_face_select_set_no_sync(ts, bm, efa, true); BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true); - BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true); + uvedit_vert_select_set_no_sync(ts, bm, l, true); + uvedit_edge_select_set_no_sync(ts, bm, l, true); } } } @@ -1724,10 +1724,8 @@ static wmOperatorStatus uv_pin_exec(bContext *C, wmOperator *op) BMFace *efa; BMLoop *l; BMIter iter, liter; - const ToolSettings *ts = scene->toolsettings; const bool clear = RNA_boolean_get(op->ptr, "clear"); const bool invert = RNA_boolean_get(op->ptr, "invert"); - const bool synced_selection = (ts->uv_flag & UV_FLAG_SELECT_SYNC) != 0; Vector objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs( scene, view_layer, nullptr); @@ -1741,20 +1739,12 @@ static wmOperatorStatus uv_pin_exec(bContext *C, wmOperator *op) if (em->bm->totvertsel == 0) { continue; } - if (synced_selection) { - /* Pass. */ - } - else { - if (!BM_uv_map_attr_vert_select_exists(em->bm, active_uv_name)) { - continue; - } - } if (clear && !BM_uv_map_attr_pin_exists(em->bm, active_uv_name)) { continue; } - BM_uv_map_attr_pin_ensure(em->bm, active_uv_name); + BM_uv_map_attr_pin_ensure_named(em->bm, active_uv_name); const BMUVOffsets offsets = BM_uv_map_offsets_get(em->bm); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { @@ -1820,19 +1810,24 @@ static void UV_OT_pin(wmOperatorType *ot) /* check if we are selected or unselected based on 'bool_test' arg, * needed for select swap support */ -#define UV_VERT_SEL_TEST(l, bool_test) (BM_ELEM_CD_GET_BOOL(l, offsets.select_vert) == bool_test) +#define UV_VERT_SEL_TEST(ts, bm, l, bool_test) \ + (uvedit_vert_select_get_no_sync(ts, bm, l) == bool_test) -#define UV_EDGE_SEL_TEST(l, bool_test) (BM_ELEM_CD_GET_BOOL(l, offsets.select_edge) == bool_test) +#define UV_EDGE_SEL_TEST(ts, bm, l, bool_test) \ + (uvedit_edge_select_get_no_sync(ts, bm, l) == bool_test) /* is every UV vert selected or unselected depending on bool_test */ -static bool bm_face_is_all_uv_sel(BMFace *f, bool select_test, const BMUVOffsets &offsets) +static bool bm_face_is_all_uv_sel(const ToolSettings *ts, + const BMesh *bm, + BMFace *f, + bool select_test) { BMLoop *l_iter; BMLoop *l_first; l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { - if (!UV_EDGE_SEL_TEST(l_iter, select_test)) { + if (!UV_EDGE_SEL_TEST(ts, bm, l_iter, select_test)) { return false; } } while ((l_iter = l_iter->next) != l_first); @@ -1979,17 +1974,6 @@ static wmOperatorStatus uv_hide_exec(bContext *C, wmOperator *op) BMLoop *l; BMIter iter, liter; - if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { - /* Pass. */ - } - else { - const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, - CD_PROP_FLOAT2); - BM_uv_map_attr_vert_select_ensure(em->bm, active_uv_name); - BM_uv_map_attr_edge_select_ensure(em->bm, active_uv_name); - } - const BMUVOffsets offsets = BM_uv_map_offsets_get(em->bm); - if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { uv_mesh_hide_sync_select(ts, ob, em, swap); continue; @@ -2004,7 +1988,7 @@ static wmOperatorStatus uv_hide_exec(bContext *C, wmOperator *op) BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (UV_VERT_SEL_TEST(l, !swap) || UV_EDGE_SEL_TEST(l, !swap)) { + if (UV_VERT_SEL_TEST(ts, em->bm, l, !swap) || UV_EDGE_SEL_TEST(ts, em->bm, l, !swap)) { hide = 1; break; } @@ -2014,26 +1998,29 @@ static wmOperatorStatus uv_hide_exec(bContext *C, wmOperator *op) if (use_face_center) { if (em->selectmode == SCE_SELECT_FACE) { /* Deselect BMesh face if UV face is (de)selected depending on #swap. */ - if (bm_face_is_all_uv_sel(efa, !swap, offsets)) { + if (bm_face_is_all_uv_sel(ts, em->bm, efa, !swap)) { BM_face_select_set(em->bm, efa, false); } - uvedit_face_select_disable(scene, em->bm, efa, offsets); + uvedit_face_select_disable(scene, em->bm, efa); } else { - if (bm_face_is_all_uv_sel(efa, true, offsets) == !swap) { + if (bm_face_is_all_uv_sel(ts, em->bm, efa, true) == !swap) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { /* For both cases rely on edge sel tests, since all vert sel tests are invalid in * case of sticky selections. */ - if (UV_EDGE_SEL_TEST(l, !swap) && (em->selectmode == SCE_SELECT_EDGE)) { + if (UV_EDGE_SEL_TEST(ts, em->bm, l, !swap) && (em->selectmode == SCE_SELECT_EDGE)) + { BM_edge_select_set(em->bm, l->e, false); } - else if (UV_EDGE_SEL_TEST(l, !swap) && (em->selectmode == SCE_SELECT_VERTEX)) { + else if (UV_EDGE_SEL_TEST(ts, em->bm, l, !swap) && + (em->selectmode == SCE_SELECT_VERTEX)) + { BM_vert_select_set(em->bm, l->v, false); } } } if (!swap) { - uvedit_face_select_disable(scene, em->bm, efa, offsets); + uvedit_face_select_disable(scene, em->bm, efa); } } } @@ -2041,11 +2028,11 @@ static wmOperatorStatus uv_hide_exec(bContext *C, wmOperator *op) /* Deselect BMesh face depending on the type of UV selectmode and the type of UV element * being considered. */ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (UV_EDGE_SEL_TEST(l, !swap) && (ts->uv_selectmode == UV_SELECT_EDGE)) { + if (UV_EDGE_SEL_TEST(ts, em->bm, l, !swap) && (ts->uv_selectmode == UV_SELECT_EDGE)) { BM_face_select_set(em->bm, efa, false); break; } - if (UV_VERT_SEL_TEST(l, !swap) && (ts->uv_selectmode == UV_SELECT_VERT)) { + if (UV_VERT_SEL_TEST(ts, em->bm, l, !swap) && (ts->uv_selectmode == UV_SELECT_VERT)) { BM_face_select_set(em->bm, efa, false); break; } @@ -2054,11 +2041,11 @@ static wmOperatorStatus uv_hide_exec(bContext *C, wmOperator *op) break; } } - uvedit_face_select_disable(scene, em->bm, efa, offsets); + uvedit_face_select_disable(scene, em->bm, efa); } else { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (UV_EDGE_SEL_TEST(l, !swap) && (ts->uv_selectmode == UV_SELECT_EDGE)) { + if (UV_EDGE_SEL_TEST(ts, em->bm, l, !swap) && (ts->uv_selectmode == UV_SELECT_EDGE)) { if (em->selectmode == SCE_SELECT_EDGE) { BM_edge_select_set(em->bm, l->e, false); } @@ -2067,7 +2054,9 @@ static wmOperatorStatus uv_hide_exec(bContext *C, wmOperator *op) BM_vert_select_set(em->bm, l->next->v, false); } } - else if (UV_VERT_SEL_TEST(l, !swap) && (ts->uv_selectmode != UV_SELECT_EDGE)) { + else if (UV_VERT_SEL_TEST(ts, em->bm, l, !swap) && + (ts->uv_selectmode != UV_SELECT_EDGE)) + { if (em->selectmode == SCE_SELECT_EDGE) { BM_edge_select_set(em->bm, l->e, false); } @@ -2077,7 +2066,7 @@ static wmOperatorStatus uv_hide_exec(bContext *C, wmOperator *op) } } if (!swap) { - uvedit_face_select_disable(scene, em->bm, efa, offsets); + uvedit_face_select_disable(scene, em->bm, efa); } } } @@ -2145,17 +2134,6 @@ static wmOperatorStatus uv_reveal_exec(bContext *C, wmOperator *op) BMLoop *l; BMIter iter, liter; - if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { - /* Pass. */ - } - else { - const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, - CD_PROP_FLOAT2); - BM_uv_map_attr_vert_select_ensure(em->bm, active_uv_name); - BM_uv_map_attr_edge_select_ensure(em->bm, active_uv_name); - } - const BMUVOffsets offsets = BM_uv_map_offsets_get(em->bm); - /* NOTE: Selecting faces is delayed so that it doesn't select verts/edges and confuse certain * UV selection checks. * This creates a temporary state which breaks certain UV selection functions that do face @@ -2184,9 +2162,10 @@ static wmOperatorStatus uv_reveal_exec(bContext *C, wmOperator *op) BM_elem_flag_disable(efa, BM_ELEM_TAG); if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select); - BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select); + uvedit_vert_select_set_no_sync(ts, em->bm, l, select); + uvedit_edge_select_set_no_sync(ts, em->bm, l, select); } + uvedit_face_select_set_no_sync(ts, em->bm, efa, select); // BM_face_select_set(em->bm, efa, true); BM_elem_flag_enable(efa, BM_ELEM_TAG); } @@ -2209,10 +2188,11 @@ static wmOperatorStatus uv_reveal_exec(bContext *C, wmOperator *op) if (!totsel) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select); - BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select); + uvedit_vert_select_set_no_sync(ts, em->bm, l, select); + uvedit_edge_select_set_no_sync(ts, em->bm, l, select); } } + uvedit_face_select_set_no_sync(ts, em->bm, efa, select); // BM_face_select_set(em->bm, efa, true); BM_elem_flag_enable(efa, BM_ELEM_TAG); } @@ -2224,9 +2204,10 @@ static wmOperatorStatus uv_reveal_exec(bContext *C, wmOperator *op) BM_elem_flag_disable(efa, BM_ELEM_TAG); if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select); - BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select); + uvedit_vert_select_set_no_sync(ts, em->bm, l, select); + uvedit_edge_select_set_no_sync(ts, em->bm, l, select); } + uvedit_face_select_set_no_sync(ts, em->bm, efa, select); // BM_face_select_set(em->bm, efa, true); BM_elem_flag_enable(efa, BM_ELEM_TAG); } @@ -2237,9 +2218,10 @@ static wmOperatorStatus uv_reveal_exec(bContext *C, wmOperator *op) BM_elem_flag_disable(efa, BM_ELEM_TAG); if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select); - BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select); + uvedit_vert_select_set_no_sync(ts, em->bm, l, select); + uvedit_edge_select_set_no_sync(ts, em->bm, l, select); } + uvedit_face_select_set_no_sync(ts, em->bm, efa, select); // BM_face_select_set(em->bm, efa, true); BM_elem_flag_enable(efa, BM_ELEM_TAG); } @@ -2553,6 +2535,7 @@ static bool uv_copy_mirrored_faces( const BMUVOffsets offsets = BM_uv_map_offsets_get(bm); BLI_assert(offsets.uv != -1); + UNUSED_VARS_NDEBUG(offsets); BMVert *v; BMIter iter; @@ -2632,9 +2615,7 @@ static bool uv_copy_mirrored_faces( for (const auto &[f_dst, f_src] : face_map.items()) { /* Skip unless both faces have all their UVs selected. */ - if (!uvedit_face_select_test(scene, bm, f_dst, offsets) || - !uvedit_face_select_test(scene, bm, f_src, offsets)) - { + if (!uvedit_face_select_test(scene, bm, f_dst) || !uvedit_face_select_test(scene, bm, f_src)) { continue; } diff --git a/source/blender/editors/uvedit/uvedit_path.cc b/source/blender/editors/uvedit/uvedit_path.cc index 2c8328d4bb2..7accf36f380 100644 --- a/source/blender/editors/uvedit/uvedit_path.cc +++ b/source/blender/editors/uvedit/uvedit_path.cc @@ -150,7 +150,7 @@ static void verttag_set_cb(BMLoop *l, bool val, void *user_data_v) if (verttag_filter_cb(l_iter, user_data)) { const float *luv_iter = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_loop_uv_offset); if (equals_v2v2(luv, luv_iter)) { - uvedit_uv_select_set(scene, bm, l_iter, val, user_data->offsets); + uvedit_uv_select_set(scene, bm, l_iter, val); } } } diff --git a/source/blender/editors/uvedit/uvedit_rip.cc b/source/blender/editors/uvedit/uvedit_rip.cc index 66b29397136..9b17bdce4cf 100644 --- a/source/blender/editors/uvedit/uvedit_rip.cc +++ b/source/blender/editors/uvedit/uvedit_rip.cc @@ -776,11 +776,11 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { bool is_all = true; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_loop_vert_select_get(ts, bm, l, offsets)) { - if (uvedit_loop_edge_select_get(ts, bm, l, offsets)) { + if (uvedit_loop_vert_select_get(ts, bm, l)) { + if (uvedit_loop_edge_select_get(ts, bm, l)) { UL(l)->is_select_edge = true; } - else if (!uvedit_loop_edge_select_get(ts, bm, l->prev, offsets)) { + else if (!uvedit_loop_edge_select_get(ts, bm, l->prev)) { /* #bm_loop_uv_select_single_vert_validate validates below. */ UL(l)->is_select_vert_single = true; is_all = false; @@ -824,12 +824,12 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (!UL(l)->is_select_all) { - if (uvedit_loop_vert_select_get(ts, bm, l, offsets)) { - uvedit_loop_vert_select_set(ts, bm, l, false, offsets); + if (uvedit_loop_vert_select_get(ts, bm, l)) { + uvedit_loop_vert_select_set(ts, bm, l, false); changed = true; } - if (uvedit_loop_edge_select_get(ts, bm, l, offsets)) { - uvedit_loop_edge_select_set(ts, bm, l, false, offsets); + if (uvedit_loop_edge_select_get(ts, bm, l)) { + uvedit_loop_edge_select_set(ts, bm, l, false); changed = true; } } @@ -862,7 +862,7 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const BMLoop *l_iter = static_cast(BLI_gsetIterator_getKey(&gs_iter)); ULData *ul = UL(l_iter); if (ul->side == side_from_cursor) { - uvedit_uv_select_disable(scene, bm, l_iter, offsets); + uvedit_uv_select_disable(scene, bm, l_iter); changed = true; } /* Ensure we don't operate on these again. */ @@ -880,7 +880,7 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const BMLoop *l_iter = static_cast(BLI_gsetIterator_getKey(&gs_iter)); ULData *ul = UL(l_iter); if (ul->side == side_from_cursor) { - uvedit_uv_select_disable(scene, bm, l_iter, offsets); + uvedit_uv_select_disable(scene, bm, l_iter); changed = true; } /* Ensure we don't operate on these again. */ diff --git a/source/blender/editors/uvedit/uvedit_select.cc b/source/blender/editors/uvedit/uvedit_select.cc index e6cd441f74a..d9b09dd0630 100644 --- a/source/blender/editors/uvedit/uvedit_select.cc +++ b/source/blender/editors/uvedit/uvedit_select.cc @@ -382,10 +382,7 @@ void ED_uvedit_select_sync_flush(const ToolSettings *ts, BMesh *bm, const bool s } } -static void uvedit_vertex_select_tagged(BMesh *bm, - Scene *scene, - bool select, - const BMUVOffsets &offsets) +static void uvedit_vertex_select_tagged(BMesh *bm, Scene *scene, bool select) { BMFace *efa; BMLoop *l; @@ -394,7 +391,7 @@ static void uvedit_vertex_select_tagged(BMesh *bm, BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (BM_elem_flag_test(l->v, BM_ELEM_TAG)) { - uvedit_uv_select_set(scene, bm, l, select, offsets); + uvedit_uv_select_set(scene, bm, l, select); } } } @@ -412,13 +409,8 @@ bool uvedit_face_visible_test(const Scene *scene, const BMFace *efa) return uvedit_face_visible_test_ex(scene->toolsettings, efa); } -bool uvedit_face_select_test_ex(const ToolSettings *ts, - const BMesh *bm, - const BMFace *efa, - const BMUVOffsets &offsets) +bool uvedit_face_select_test_ex(const ToolSettings *ts, const BMesh *bm, const BMFace *efa) { - BLI_assert(offsets.select_vert >= 0); - BLI_assert(offsets.select_edge >= 0); if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { if (bm->uv_select_sync_valid == false || ED_uvedit_sync_uvselect_ignore(ts)) { return BM_elem_flag_test(efa, BM_ELEM_SELECT); @@ -428,23 +420,26 @@ bool uvedit_face_select_test_ex(const ToolSettings *ts, return BM_elem_flag_test(efa, BM_ELEM_SELECT_UV); } - const int cd_offset = (ts->uv_selectmode & UV_SELECT_VERT) ? offsets.select_vert : - offsets.select_edge; + if (ts->uv_selectmode == UV_SELECT_FACE) { + if (!BM_elem_flag_test(efa, BM_ELEM_SELECT_UV)) { + return false; + } + return true; + } + const char hflag_test = (ts->uv_selectmode & UV_SELECT_VERT) ? BM_ELEM_SELECT_UV : + BM_ELEM_SELECT_UV_EDGE; const BMLoop *l_first = BM_FACE_FIRST_LOOP(efa); const BMLoop *l_iter = l_first; do { - if (!BM_ELEM_CD_GET_BOOL(l_iter, cd_offset)) { + if (!BM_elem_flag_test(l_iter, hflag_test)) { return false; } } while ((l_iter = l_iter->next) != l_first); return true; } -bool uvedit_face_select_test(const Scene *scene, - const BMesh *bm, - const BMFace *efa, - const BMUVOffsets &offsets) +bool uvedit_face_select_test(const Scene *scene, const BMesh *bm, const BMFace *efa) { - return uvedit_face_select_test_ex(scene->toolsettings, bm, efa, offsets); + return uvedit_face_select_test_ex(scene->toolsettings, bm, efa); } void uvedit_face_select_set_with_sticky( @@ -454,7 +449,7 @@ void uvedit_face_select_set_with_sticky( const char sticky = ts->uv_sticky; if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { if (ED_uvedit_sync_uvselect_ignore(ts)) { - uvedit_face_select_set(scene, bm, efa, select, offsets); + uvedit_face_select_set(scene, bm, efa, select); return; } BLI_assert(ED_uvedit_sync_uvselect_is_valid_or_ignore(ts, bm)); @@ -466,7 +461,7 @@ void uvedit_face_select_set_with_sticky( * (not part of any face selections). This now uses the sticky location mode logic instead. */ switch (sticky) { case UV_STICKY_DISABLE: { - uvedit_face_select_set(scene, bm, efa, select, offsets); + uvedit_face_select_set(scene, bm, efa, select); break; } default: { @@ -530,8 +525,9 @@ void uvedit_face_select_shared_vert(const Scene *scene, return; } + uvedit_face_select_set_no_sync(ts, bm, efa, select); BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select); + uvedit_edge_select_set_no_sync(ts, bm, l, select); if (select) { uvedit_uv_select_shared_vert(scene, bm, l, select, UV_STICKY_LOCATION, offsets); @@ -544,24 +540,18 @@ void uvedit_face_select_shared_vert(const Scene *scene, } } -void uvedit_face_select_set( - const Scene *scene, BMesh *bm, BMFace *efa, const bool select, const BMUVOffsets &offsets) +void uvedit_face_select_set(const Scene *scene, BMesh *bm, BMFace *efa, const bool select) { if (select) { - uvedit_face_select_enable(scene, bm, efa, offsets); + uvedit_face_select_enable(scene, bm, efa); } else { - uvedit_face_select_disable(scene, bm, efa, offsets); + uvedit_face_select_disable(scene, bm, efa); } } -void uvedit_face_select_enable(const Scene *scene, - BMesh *bm, - BMFace *efa, - const BMUVOffsets &offsets) +void uvedit_face_select_enable(const Scene *scene, BMesh *bm, BMFace *efa) { - BLI_assert(offsets.select_vert >= 0); - BLI_assert(offsets.select_edge >= 0); const ToolSettings *ts = scene->toolsettings; if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { @@ -576,20 +566,16 @@ void uvedit_face_select_enable(const Scene *scene, BMLoop *l; BMIter liter; + uvedit_face_select_set_no_sync(ts, bm, efa, true); BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true); - BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true); + uvedit_vert_select_set_no_sync(ts, bm, l, true); + uvedit_edge_select_set_no_sync(ts, bm, l, true); } } } -void uvedit_face_select_disable(const Scene *scene, - BMesh *bm, - BMFace *efa, - const BMUVOffsets &offsets) +void uvedit_face_select_disable(const Scene *scene, BMesh *bm, BMFace *efa) { - BLI_assert(offsets.select_vert >= 0); - BLI_assert(offsets.select_edge >= 0); const ToolSettings *ts = scene->toolsettings; if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { @@ -604,9 +590,10 @@ void uvedit_face_select_disable(const Scene *scene, BMLoop *l; BMIter liter; + uvedit_face_select_set_no_sync(ts, bm, efa, false); BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false); - BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false); + uvedit_vert_select_set_no_sync(ts, bm, l, false); + uvedit_edge_select_set_no_sync(ts, bm, l, false); } } } @@ -616,8 +603,6 @@ bool uvedit_edge_select_test_ex(const ToolSettings *ts, const BMLoop *l, const BMUVOffsets &offsets) { - BLI_assert(offsets.select_vert >= 0); - BLI_assert(offsets.select_edge >= 0); if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { if ((bm->uv_select_sync_valid == false) && (ts->selectmode == SCE_SELECT_FACE)) { /* Face only is a special case that can respect sticky modes. */ @@ -657,10 +642,10 @@ bool uvedit_edge_select_test_ex(const ToolSettings *ts, } if (ts->uv_selectmode & UV_SELECT_VERT) { - return BM_ELEM_CD_GET_BOOL(l, offsets.select_vert) && - BM_ELEM_CD_GET_BOOL(l->next, offsets.select_vert); + return uvedit_vert_select_get_no_sync(ts, bm, l) && + uvedit_vert_select_get_no_sync(ts, bm, l->next); } - return BM_ELEM_CD_GET_BOOL(l, offsets.select_edge); + return uvedit_edge_select_get_no_sync(ts, bm, l); } bool uvedit_edge_select_test(const Scene *scene, @@ -681,7 +666,7 @@ void uvedit_edge_select_set_with_sticky(const Scene *scene, const ToolSettings *ts = scene->toolsettings; if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { if (ED_uvedit_sync_uvselect_ignore(ts)) { - uvedit_edge_select_set(scene, bm, l, select, offsets); + uvedit_edge_select_set(scene, bm, l, select); return; } BLI_assert(ED_uvedit_sync_uvselect_is_valid_or_ignore(ts, bm)); @@ -691,7 +676,7 @@ void uvedit_edge_select_set_with_sticky(const Scene *scene, switch (sticky) { case UV_STICKY_DISABLE: { if (uvedit_face_visible_test(scene, l->f)) { - uvedit_edge_select_set(scene, bm, l, select, offsets); + uvedit_edge_select_set(scene, bm, l, select); } break; } @@ -709,8 +694,7 @@ void uvedit_edge_select_set_with_sticky(const Scene *scene, static bool UNUSED_FUNCTION(bm_loop_select_vert_check_internal)(const Scene *scene, BMesh *bm, - BMLoop *l, - const BMUVOffsets &offsets) + BMLoop *l) { const ToolSettings *ts = scene->toolsettings; if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { @@ -722,13 +706,10 @@ static bool UNUSED_FUNCTION(bm_loop_select_vert_check_internal)(const Scene *sce BLI_assert(!BM_elem_flag_test(l->f, BM_ELEM_HIDDEN)); return BM_elem_flag_test_bool(l, BM_ELEM_SELECT_UV); } - return BM_ELEM_CD_GET_BOOL(l, offsets.select_vert); + return uvedit_vert_select_get_no_sync(ts, bm, l); } -static bool bm_loop_select_edge_check_internal(const Scene *scene, - BMesh *bm, - BMLoop *l, - const BMUVOffsets &offsets) +static bool bm_loop_select_edge_check_internal(const Scene *scene, BMesh *bm, BMLoop *l) { const ToolSettings *ts = scene->toolsettings; if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { @@ -740,7 +721,7 @@ static bool bm_loop_select_edge_check_internal(const Scene *scene, BLI_assert(!BM_elem_flag_test(l->f, BM_ELEM_HIDDEN)); return BM_elem_flag_test_bool(l, BM_ELEM_SELECT_UV_EDGE); } - return BM_ELEM_CD_GET_BOOL(l, offsets.select_edge); + return uvedit_edge_select_get_no_sync(ts, bm, l); } void uvedit_edge_select_shared_vert(const Scene *scene, @@ -758,13 +739,13 @@ void uvedit_edge_select_shared_vert(const Scene *scene, BMLoop *l_iter = l; do { if (select) { - if (bm_loop_select_edge_check_internal(scene, bm, l_iter, offsets)) { + if (bm_loop_select_edge_check_internal(scene, bm, l_iter)) { uvedit_uv_select_shared_vert(scene, bm, l_iter, true, UV_STICKY_LOCATION, offsets); uvedit_uv_select_shared_vert(scene, bm, l_iter->next, true, UV_STICKY_LOCATION, offsets); } } else { - if (!bm_loop_select_edge_check_internal(scene, bm, l_iter, offsets)) { + if (!bm_loop_select_edge_check_internal(scene, bm, l_iter)) { if (!uvedit_vert_is_edge_select_any_other(scene->toolsettings, bm, l, offsets)) { uvedit_uv_select_shared_vert(scene, bm, l_iter, false, UV_STICKY_LOCATION, offsets); } @@ -787,7 +768,6 @@ void uvedit_edge_select_set_noflush(const Scene *scene, const ToolSettings *ts = scene->toolsettings; if ((ts->uv_flag & UV_FLAG_SELECT_SYNC) == 0) { BLI_assert(offsets.uv >= 0); - BLI_assert(offsets.select_edge >= 0); } BMLoop *l_iter = l; do { @@ -797,38 +777,27 @@ void uvedit_edge_select_set_noflush(const Scene *scene, BM_loop_edge_uvselect_set_noflush(bm, l_iter, select); } else { - BM_ELEM_CD_SET_BOOL(l_iter, offsets.select_edge, select); + uvedit_edge_select_set_no_sync(ts, bm, l, select); } } } } while (((l_iter = l_iter->radial_next) != l) && (sticky_flag != UV_STICKY_DISABLE)); } -void uvedit_edge_select_set(const Scene *scene, - BMesh *bm, - BMLoop *l, - const bool select, - - const BMUVOffsets &offsets) +void uvedit_edge_select_set(const Scene *scene, BMesh *bm, BMLoop *l, const bool select) { if (select) { - uvedit_edge_select_enable(scene, bm, l, offsets); + uvedit_edge_select_enable(scene, bm, l); } else { - uvedit_edge_select_disable(scene, bm, l, offsets); + uvedit_edge_select_disable(scene, bm, l); } } -void uvedit_edge_select_enable(const Scene *scene, - BMesh *bm, - BMLoop *l, - const BMUVOffsets &offsets) +void uvedit_edge_select_enable(const Scene *scene, BMesh *bm, BMLoop *l) { const ToolSettings *ts = scene->toolsettings; - BLI_assert(offsets.select_vert >= 0); - BLI_assert(offsets.select_edge >= 0); - if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { if (ED_uvedit_sync_uvselect_ignore(ts)) { if (ts->selectmode & SCE_SELECT_FACE) { @@ -847,16 +816,13 @@ void uvedit_edge_select_enable(const Scene *scene, } } else { - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true); - BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true); - BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, true); + uvedit_vert_select_set_no_sync(ts, bm, l, true); + uvedit_vert_select_set_no_sync(ts, bm, l->next, true); + uvedit_edge_select_set_no_sync(ts, bm, l, true); } } -void uvedit_edge_select_disable(const Scene *scene, - BMesh *bm, - BMLoop *l, - const BMUVOffsets &offsets) +void uvedit_edge_select_disable(const Scene *scene, BMesh *bm, BMLoop *l) { const ToolSettings *ts = scene->toolsettings; @@ -891,22 +857,19 @@ void uvedit_edge_select_disable(const Scene *scene, } } else { - BLI_assert(offsets.select_vert >= 0); - BLI_assert(offsets.select_edge >= 0); - - BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false); + uvedit_edge_select_set_no_sync(ts, bm, l, false); if ((ts->uv_selectmode & UV_SELECT_VERT) == 0) { /* Deselect UV vertex if not part of another edge selection */ - if (!BM_ELEM_CD_GET_BOOL(l->next, offsets.select_edge)) { - BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, false); + if (!uvedit_edge_select_get_no_sync(ts, bm, l->next)) { + uvedit_vert_select_set_no_sync(ts, bm, l->next, false); } - if (!BM_ELEM_CD_GET_BOOL(l->prev, offsets.select_edge)) { - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false); + if (!uvedit_edge_select_get_no_sync(ts, bm, l->prev)) { + uvedit_vert_select_set_no_sync(ts, bm, l, false); } } else { - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false); - BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, false); + uvedit_vert_select_set_no_sync(ts, bm, l, false); + uvedit_vert_select_set_no_sync(ts, bm, l->next, false); } } } @@ -916,7 +879,6 @@ bool uvedit_uv_select_test_ex(const ToolSettings *ts, const BMLoop *l, const BMUVOffsets &offsets) { - BLI_assert(offsets.select_vert >= 0); if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { if ((bm->uv_select_sync_valid == false) && (ts->selectmode == SCE_SELECT_FACE)) { @@ -989,7 +951,7 @@ bool uvedit_uv_select_test_ex(const ToolSettings *ts, /* Are you looking for `uvedit_edge_select_test(...)` instead? */ } - return BM_ELEM_CD_GET_BOOL(l, offsets.select_vert); + return uvedit_vert_select_get_no_sync(ts, bm, l); } bool uvedit_uv_select_test(const Scene *scene, @@ -1006,7 +968,7 @@ void uvedit_uv_select_set_with_sticky( const ToolSettings *ts = scene->toolsettings; if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { if (ED_uvedit_sync_uvselect_ignore(ts)) { - uvedit_uv_select_set(scene, bm, l, select, offsets); + uvedit_uv_select_set(scene, bm, l, select); return; } } @@ -1015,7 +977,7 @@ void uvedit_uv_select_set_with_sticky( switch (sticky) { case UV_STICKY_DISABLE: { if (uvedit_face_visible_test(scene, l->f)) { - uvedit_uv_select_set(scene, bm, l, select, offsets); + uvedit_uv_select_set(scene, bm, l, select); } break; } @@ -1061,7 +1023,7 @@ void uvedit_uv_select_shared_vert(const Scene *scene, } if (do_select) { - uvedit_uv_select_set(scene, bm, l_radial_iter, select, offsets); + uvedit_uv_select_set(scene, bm, l_radial_iter, select); } } } @@ -1069,22 +1031,17 @@ void uvedit_uv_select_shared_vert(const Scene *scene, } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, l->v)) != e_first); } -void uvedit_uv_select_set(const Scene *scene, - BMesh *bm, - BMLoop *l, - const bool select, - - const BMUVOffsets &offsets) +void uvedit_uv_select_set(const Scene *scene, BMesh *bm, BMLoop *l, const bool select) { if (select) { - uvedit_uv_select_enable(scene, bm, l, offsets); + uvedit_uv_select_enable(scene, bm, l); } else { - uvedit_uv_select_disable(scene, bm, l, offsets); + uvedit_uv_select_disable(scene, bm, l); } } -void uvedit_uv_select_enable(const Scene *scene, BMesh *bm, BMLoop *l, const BMUVOffsets &offsets) +void uvedit_uv_select_enable(const Scene *scene, BMesh *bm, BMLoop *l) { const ToolSettings *ts = scene->toolsettings; @@ -1106,12 +1063,11 @@ void uvedit_uv_select_enable(const Scene *scene, BMesh *bm, BMLoop *l, const BMU } } else { - BLI_assert(offsets.select_vert >= 0); - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true); + uvedit_vert_select_set_no_sync(ts, bm, l, true); } } -void uvedit_uv_select_disable(const Scene *scene, BMesh *bm, BMLoop *l, const BMUVOffsets &offsets) +void uvedit_uv_select_disable(const Scene *scene, BMesh *bm, BMLoop *l) { const ToolSettings *ts = scene->toolsettings; @@ -1129,8 +1085,7 @@ void uvedit_uv_select_disable(const Scene *scene, BMesh *bm, BMLoop *l, const BM } } else { - BLI_assert(offsets.select_vert >= 0); - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false); + uvedit_vert_select_set_no_sync(ts, bm, l, false); } } @@ -1195,23 +1150,17 @@ static BMLoop *uvedit_loop_find_other_boundary_loop_with_visible_face(const Scen /** \name Low Level Selection API * \{ */ -bool uvedit_loop_vert_select_get(const ToolSettings *ts, - const BMesh *bm, - const BMLoop *l, - const BMUVOffsets &offsets) +bool uvedit_loop_vert_select_get(const ToolSettings *ts, const BMesh *bm, const BMLoop *l) { if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { BLI_assert(bm->uv_select_sync_valid); UNUSED_VARS_NDEBUG(bm); return BM_elem_flag_test_bool(l, BM_ELEM_SELECT_UV); } - return BM_ELEM_CD_GET_BOOL(l, offsets.select_vert); + return uvedit_vert_select_get_no_sync(ts, bm, l); } -bool uvedit_loop_edge_select_get(const ToolSettings *ts, - const BMesh *bm, - const BMLoop *l, - const BMUVOffsets &offsets) +bool uvedit_loop_edge_select_get(const ToolSettings *ts, const BMesh *bm, const BMLoop *l) { if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { BLI_assert(bm->uv_select_sync_valid); @@ -1220,14 +1169,13 @@ bool uvedit_loop_edge_select_get(const ToolSettings *ts, BLI_assert(!BM_elem_flag_test(l->f, BM_ELEM_HIDDEN)); return BM_elem_flag_test_bool(l, BM_ELEM_SELECT_UV_EDGE); } - return BM_ELEM_CD_GET_BOOL(l, offsets.select_edge); + return uvedit_edge_select_get_no_sync(ts, bm, l); } void uvedit_loop_vert_select_set(const ToolSettings *ts, const BMesh *bm, BMLoop *l, - const bool select, - const BMUVOffsets &offsets) + const bool select) { if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { BLI_assert(bm->uv_select_sync_valid); @@ -1235,14 +1183,13 @@ void uvedit_loop_vert_select_set(const ToolSettings *ts, BM_elem_flag_set(l, BM_ELEM_SELECT_UV, select); return; } - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select); + uvedit_vert_select_set_no_sync(ts, bm, l, select); } void uvedit_loop_edge_select_set(const ToolSettings *ts, const BMesh *bm, BMLoop *l, - const bool select, - const BMUVOffsets &offsets) + const bool select) { if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { BLI_assert(bm->uv_select_sync_valid); @@ -1250,7 +1197,7 @@ void uvedit_loop_edge_select_set(const ToolSettings *ts, BM_elem_flag_set(l, BM_ELEM_SELECT_UV_EDGE, select); return; } - BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select); + uvedit_edge_select_set_no_sync(ts, bm, l, select); } /** \} */ @@ -1650,8 +1597,8 @@ void uvedit_select_prepare_custom_data(const Scene *scene, BMesh *bm) BLI_assert((ts->uv_flag & UV_FLAG_SELECT_SYNC) == 0); UNUSED_VARS_NDEBUG(ts); const char *active_uv_name = CustomData_get_active_layer_name(&bm->ldata, CD_PROP_FLOAT2); - BM_uv_map_attr_vert_select_ensure(bm, active_uv_name); - BM_uv_map_attr_edge_select_ensure(bm, active_uv_name); + BLI_assert(active_uv_name); + UNUSED_VARS_NDEBUG(active_uv_name); } void uvedit_select_prepare_sync_select(const Scene *scene, BMesh *bm) @@ -1716,7 +1663,7 @@ bool uvedit_edge_is_face_select_any_other(const ToolSettings *ts, continue; } if (BM_loop_uv_share_edge_check(l, l_radial_iter, offsets.uv) && - uvedit_face_select_test_ex(ts, bm, l_radial_iter->f, offsets)) + uvedit_face_select_test_ex(ts, bm, l_radial_iter->f)) { return true; } @@ -1738,7 +1685,7 @@ bool uvedit_vert_is_face_select_any_other(const ToolSettings *ts, continue; } if (BM_loop_uv_share_vert_check(l, l_iter, offsets.uv) && - uvedit_face_select_test_ex(ts, bm, l_iter->f, offsets)) + uvedit_face_select_test_ex(ts, bm, l_iter->f)) { return true; } @@ -1759,7 +1706,7 @@ bool uvedit_vert_is_all_other_faces_selected(const ToolSettings *ts, continue; } if (BM_loop_uv_share_vert_check(l, l_iter, offsets.uv) && - !uvedit_face_select_test_ex(ts, bm, l_iter->f, offsets)) + !uvedit_face_select_test_ex(ts, bm, l_iter->f)) { return false; } @@ -1767,11 +1714,9 @@ bool uvedit_vert_is_all_other_faces_selected(const ToolSettings *ts, return true; } -static void bm_clear_uv_vert_selection(const Scene *scene, BMesh *bm, const BMUVOffsets &offsets) +static void bm_clear_uv_vert_selection(const Scene *scene, BMesh *bm) { - if (offsets.select_vert == -1) { - return; - } + const ToolSettings *ts = scene->toolsettings; BMFace *efa; BMLoop *l; BMIter iter, liter; @@ -1780,13 +1725,75 @@ static void bm_clear_uv_vert_selection(const Scene *scene, BMesh *bm, const BMUV continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false); + uvedit_vert_select_set_no_sync(ts, bm, l, false); } } } /** \} */ +/* -------------------------------------------------------------------- */ +/** \name UV Selection Non-Sync API + * + * \note this is for non-sync selection, + * where different rules apply and there is no expectation a selected UV + * implies it's base mesh selection flag also be set. + * + * \{ */ + +bool uvedit_vert_select_get_no_sync(const ToolSettings *ts, const BMesh *bm, const BMLoop *l) +{ + BLI_assert(bm && (ts->uv_flag & UV_FLAG_SELECT_SYNC) == 0); + UNUSED_VARS_NDEBUG(ts, bm); + return BM_elem_flag_test_bool(l, BM_ELEM_SELECT_UV); +} +bool uvedit_edge_select_get_no_sync(const ToolSettings *ts, const BMesh *bm, const BMLoop *l) +{ + BLI_assert(bm && (ts->uv_flag & UV_FLAG_SELECT_SYNC) == 0); + UNUSED_VARS_NDEBUG(ts, bm); + return BM_elem_flag_test_bool(l, BM_ELEM_SELECT_UV_EDGE); +} +bool uvedit_face_select_get_no_sync(const ToolSettings *ts, const BMesh *bm, const BMFace *f) +{ + BLI_assert(bm && (ts->uv_flag & UV_FLAG_SELECT_SYNC) == 0); + UNUSED_VARS_NDEBUG(ts, bm); + return BM_elem_flag_test_bool(f, BM_ELEM_SELECT_UV); +} + +void uvedit_vert_select_set_no_sync(const ToolSettings *ts, + const BMesh *bm, + BMLoop *l, + bool select) +{ + BLI_assert(bm && (ts->uv_flag & UV_FLAG_SELECT_SYNC) == 0); + BLI_assert(BM_elem_flag_test(l->f, BM_ELEM_HIDDEN) == 0); + UNUSED_VARS_NDEBUG(ts, bm); + BM_elem_flag_set(l, BM_ELEM_SELECT_UV, select); +} +void uvedit_edge_select_set_no_sync(const ToolSettings *ts, + const BMesh *bm, + BMLoop *l, + bool select) +{ + BLI_assert(bm && (ts->uv_flag & UV_FLAG_SELECT_SYNC) == 0); + BLI_assert(BM_elem_flag_test(l->f, BM_ELEM_HIDDEN) == 0); + UNUSED_VARS_NDEBUG(ts, bm); + BM_elem_flag_set(l, BM_ELEM_SELECT_UV_EDGE, select); +} + +void uvedit_face_select_set_no_sync(const ToolSettings *ts, + const BMesh *bm, + BMFace *f, + bool select) +{ + BLI_assert(bm && (ts->uv_flag & UV_FLAG_SELECT_SYNC) == 0); + BLI_assert(BM_elem_flag_test(f, BM_ELEM_HIDDEN) == 0); + UNUSED_VARS_NDEBUG(ts, bm); + BM_elem_flag_set(f, BM_ELEM_SELECT_UV, select); +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name UV Select Abstraction API * @@ -1909,7 +1916,6 @@ void ED_uvedit_selectmode_flush(const Scene *scene, BMesh *bm) UNUSED_VARS_NDEBUG(ts); uvedit_select_prepare_custom_data(scene, bm); - const BMUVOffsets offsets = BM_uv_map_offsets_get(bm); /* Vertex Mode only. */ if (ts->uv_selectmode & UV_SELECT_VERT) { @@ -1920,11 +1926,34 @@ void ED_uvedit_selectmode_flush(const Scene *scene, BMesh *bm) if (!uvedit_face_visible_test(scene, efa)) { continue; } + bool select_all = true; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - bool edge_selected = BM_ELEM_CD_GET_BOOL(l, offsets.select_vert) && - BM_ELEM_CD_GET_BOOL(l->next, offsets.select_vert); - BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, edge_selected); + bool edge_selected = uvedit_vert_select_get_no_sync(ts, bm, l) && + uvedit_vert_select_get_no_sync(ts, bm, l->next); + uvedit_edge_select_set_no_sync(ts, bm, l, edge_selected); + if (!edge_selected) { + select_all = false; + } } + uvedit_face_select_set_no_sync(ts, bm, efa, select_all); + } + } + else if (ts->uv_selectmode & UV_SELECT_EDGE) { + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + if (!uvedit_face_visible_test(scene, efa)) { + continue; + } + bool select_all = true; + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + if (!uvedit_edge_select_get_no_sync(ts, bm, l)) { + select_all = false; + break; + } + } + uvedit_face_select_set_no_sync(ts, bm, efa, select_all); } } } @@ -1941,7 +1970,6 @@ void uvedit_select_flush_from_verts(const Scene *scene, BMesh *bm, const bool se BLI_assert((ts->uv_flag & UV_FLAG_SELECT_SYNC) == 0); UNUSED_VARS_NDEBUG(ts); uvedit_select_prepare_custom_data(scene, bm); - const BMUVOffsets offsets = BM_uv_map_offsets_get(bm); if (select) { /* Careful when using this in face select mode. @@ -1953,12 +1981,19 @@ void uvedit_select_flush_from_verts(const Scene *scene, BMesh *bm, const bool se if (!uvedit_face_visible_test(scene, efa)) { continue; } + bool select_all = true; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (BM_ELEM_CD_GET_BOOL(l, offsets.select_vert) && - BM_ELEM_CD_GET_BOOL(l->next, offsets.select_vert)) + if (uvedit_vert_select_get_no_sync(ts, bm, l) && + uvedit_vert_select_get_no_sync(ts, bm, l->next)) { - BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true); + uvedit_edge_select_set_no_sync(ts, bm, l, true); } + else { + select_all = false; + } + } + if (select_all) { + uvedit_face_select_set_no_sync(ts, bm, efa, true); } } } @@ -1970,13 +2005,18 @@ void uvedit_select_flush_from_verts(const Scene *scene, BMesh *bm, const bool se if (!uvedit_face_visible_test(scene, efa)) { continue; } + bool select_all = true; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (!BM_ELEM_CD_GET_BOOL(l, offsets.select_vert) || - !BM_ELEM_CD_GET_BOOL(l->next, offsets.select_vert)) + if (!uvedit_vert_select_get_no_sync(ts, bm, l) || + !uvedit_vert_select_get_no_sync(ts, bm, l->next)) { - BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false); + uvedit_edge_select_set_no_sync(ts, bm, l, false); + select_all = false; } } + if (select_all == false) { + uvedit_face_select_set_no_sync(ts, bm, efa, false); + } } } } @@ -2157,9 +2197,6 @@ static int uv_select_edgeloop(Scene *scene, Object *obedit, UvNearestHit *hit, c /* NOTE: this is a special case, even when sync select is enabled, * the flags are used then flushed to the vertices. * So these need to be ensured even though the layers aren't used afterwards. */ - const char *active_uv_name = CustomData_get_active_layer_name(&bm->ldata, CD_PROP_FLOAT2); - BM_uv_map_attr_vert_select_ensure(bm, active_uv_name); - BM_uv_map_attr_edge_select_ensure(bm, active_uv_name); const BMUVOffsets offsets = BM_uv_map_offsets_get(bm); if (extend) { @@ -2268,7 +2305,7 @@ static int uv_select_faceloop(Scene *scene, Object *obedit, UvNearestHit *hit, c BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false); if (extend) { - select = !uvedit_face_select_test(scene, bm, hit->l->f, offsets); + select = !uvedit_face_select_test(scene, bm, hit->l->f); } else { select = true; @@ -2505,7 +2542,7 @@ static void uv_select_linked_multi(Scene *scene, * - There are no connected fully selected faces UV-connected to this loop. */ BLI_assert(!select_faces); - if (uvedit_face_select_test(scene, bm, l->f, offsets)) { + if (uvedit_face_select_test(scene, bm, l->f)) { /* pass */ } else { @@ -2513,7 +2550,7 @@ static void uv_select_linked_multi(Scene *scene, BMLoop *l_other; BM_ITER_ELEM (l_other, &liter_other, l->v, BM_LOOPS_OF_VERT) { if ((l != l_other) && !BM_loop_uv_share_vert_check(l, l_other, offsets.uv) && - uvedit_face_select_test(scene, bm, l_other->f, offsets)) + uvedit_face_select_test(scene, bm, l_other->f)) { add_to_stack = false; break; @@ -2622,7 +2659,7 @@ static void uv_select_linked_multi(Scene *scene, } \ } \ else { \ - uvedit_face_select_set(scene, bm, efa, value, offsets); \ + uvedit_face_select_set(scene, bm, efa, value); \ } \ (void)0 @@ -2815,14 +2852,14 @@ static wmOperatorStatus uv_select_more_less(bContext *C, const bool select) int sel_state = 0; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_loop_vert_select_get(ts, bm, l, offsets)) { + if (uvedit_loop_vert_select_get(ts, bm, l)) { sel_state |= NEIGHBORING_FACE_IS_SEL; } else { sel_state |= CURR_FACE_IS_UNSEL; } - if (!uvedit_loop_edge_select_get(ts, bm, l, offsets)) { + if (!uvedit_loop_edge_select_get(ts, bm, l)) { sel_state |= CURR_FACE_IS_UNSEL; } @@ -2839,7 +2876,7 @@ static wmOperatorStatus uv_select_more_less(bContext *C, const bool select) #undef CURR_FACE_IS_UNSEL } else { - if (!uvedit_face_select_test(scene, bm, efa, offsets)) { + if (!uvedit_face_select_test(scene, bm, efa)) { continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -2868,7 +2905,7 @@ static wmOperatorStatus uv_select_more_less(bContext *C, const bool select) if (uvedit_face_visible_test(scene, efa)) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_loop_vert_select_get(ts, bm, l, offsets) == select) { + if (uvedit_loop_vert_select_get(ts, bm, l) == select) { BM_elem_flag_enable(l->next, BM_ELEM_TAG); BM_elem_flag_enable(l->prev, BM_ELEM_TAG); changed = true; @@ -2967,14 +3004,12 @@ bool uvedit_select_is_any_selected(const Scene *scene, BMesh *bm) return (bm->totvertsel || bm->totedgesel || bm->totfacesel); } - const BMUVOffsets offsets = BM_uv_map_offsets_get(bm); - BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (!uvedit_face_visible_test(scene, efa)) { continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (BM_ELEM_CD_GET_BOOL(l, offsets.select_vert)) { + if (uvedit_vert_select_get_no_sync(ts, bm, l)) { return true; } } @@ -3018,15 +3053,15 @@ static void uv_select_all(const Scene *scene, BMEditMesh *em, bool select_all) BMIter iter, liter; uvedit_select_prepare_custom_data(scene, bm); - const BMUVOffsets offsets = BM_uv_map_offsets_get(bm); BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (!uvedit_face_visible_test(scene, efa)) { continue; } + uvedit_face_select_set_no_sync(ts, bm, efa, select_all); BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select_all); - BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select_all); + uvedit_vert_select_set_no_sync(ts, bm, l, select_all); + uvedit_edge_select_set_no_sync(ts, bm, l, select_all); } } } @@ -3134,7 +3169,6 @@ static void uv_select_invert(const Scene *scene, BMEditMesh *em) } uvedit_select_prepare_custom_data(scene, bm); - const BMUVOffsets offsets = BM_uv_map_offsets_get(bm); BMFace *efa; BMLoop *l; BMIter iter, liter; @@ -3143,21 +3177,29 @@ static void uv_select_invert(const Scene *scene, BMEditMesh *em) if (!uvedit_face_visible_test(scene, efa)) { continue; } + bool select_all = true; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (uv_selectmode & (UV_SELECT_EDGE | UV_SELECT_FACE)) { /* Use UV edge selection to find vertices and edges that must be selected. */ - bool es = BM_ELEM_CD_GET_BOOL(l, offsets.select_edge); - BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, !es); - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false); + bool es = !uvedit_edge_select_get_no_sync(ts, bm, l); + uvedit_edge_select_set_no_sync(ts, bm, l, es); + uvedit_vert_select_set_no_sync(ts, bm, l, false); + if (es == false) { + select_all = false; + } } /* Use UV vertex selection to find vertices and edges that must be selected. */ else { BLI_assert(uv_selectmode & UV_SELECT_VERT); - bool vs = BM_ELEM_CD_GET_BOOL(l, offsets.select_vert); - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, !vs); - BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false); + bool vs = !uvedit_vert_select_get_no_sync(ts, bm, l); + uvedit_vert_select_set_no_sync(ts, bm, l, vs); + uvedit_edge_select_set_no_sync(ts, bm, l, false); + if (vs == false) { + select_all = false; + } } } + uvedit_face_select_set_no_sync(ts, bm, efa, select_all); } /* Flush based on uv vert/edge flags and current UV select mode */ @@ -3373,7 +3415,7 @@ static bool uv_mouse_select_multi(bContext *C, const BMUVOffsets offsets = BM_uv_map_offsets_get(bm); if (selectmode == UV_SELECT_FACE) { - is_selected = uvedit_face_select_test(scene, bm, hit.efa, offsets); + is_selected = uvedit_face_select_test(scene, bm, hit.efa); } else if (selectmode == UV_SELECT_EDGE) { is_selected = uvedit_edge_select_test(scene, bm, hit.l, offsets); @@ -3385,7 +3427,7 @@ static bool uv_mouse_select_multi(bContext *C, is_selected = uvedit_uv_select_test(scene, bm, hit.l, offsets); } else { - is_selected = uvedit_face_select_test(scene, bm, hit.efa, offsets); + is_selected = uvedit_face_select_test(scene, bm, hit.efa); } } } @@ -4042,7 +4084,6 @@ static wmOperatorStatus uv_select_split_exec(bContext *C, wmOperator *op) else { uvedit_select_prepare_custom_data(scene, bm); } - const BMUVOffsets offsets = BM_uv_map_offsets_get(bm); BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { bool is_sel = false; @@ -4054,8 +4095,8 @@ static wmOperatorStatus uv_select_split_exec(bContext *C, wmOperator *op) /* are we all selected? */ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - const bool select_vert = uvedit_loop_vert_select_get(ts, bm, l, offsets); - const bool select_edge = uvedit_loop_edge_select_get(ts, bm, l, offsets); + const bool select_vert = uvedit_loop_vert_select_get(ts, bm, l); + const bool select_edge = uvedit_loop_edge_select_get(ts, bm, l); if (select_vert || select_edge) { is_sel = true; @@ -4074,8 +4115,8 @@ static wmOperatorStatus uv_select_split_exec(bContext *C, wmOperator *op) /* No need to deselect the face (with sync-select) as it wont be selected, * since it already has a mixed selection. */ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - uvedit_loop_vert_select_set(ts, bm, l, false, offsets); - uvedit_loop_edge_select_set(ts, bm, l, false, offsets); + uvedit_loop_vert_select_set(ts, bm, l, false); + uvedit_loop_edge_select_set(ts, bm, l, false); } changed = true; @@ -4136,7 +4177,7 @@ static void uv_select_tag_update_for_object(Depsgraph *depsgraph, static void uvedit_uv_select_flush_from_tag_sticky_loc_internal( const Scene *scene, BMesh *bm, BMLoop *l, const bool select, const BMUVOffsets &offsets) { - uvedit_uv_select_set(scene, bm, l, select, offsets); + uvedit_uv_select_set(scene, bm, l, select); BMVert *v = l->v; BLI_assert(v->e); @@ -4156,7 +4197,7 @@ static void uvedit_uv_select_flush_from_tag_sticky_loc_internal( continue; } if (BM_loop_uv_share_vert_check(l, l_iter, offsets.uv)) { - uvedit_uv_select_set(scene, bm, l_iter, select, offsets); + uvedit_uv_select_set(scene, bm, l_iter, select); } } while ((l_iter = l_iter->radial_next) != l_first); } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v)) != e_first); @@ -4215,9 +4256,12 @@ static void uv_select_flush_from_tag_face(const Scene *scene, Object *obedit, co if (ts->uv_flag & UV_FLAG_SELECT_SYNC) { BM_face_uvselect_set_noflush(bm, efa, select); } + else { + uvedit_face_select_set_no_sync(ts, bm, efa, select); + } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - uvedit_loop_edge_select_set(ts, bm, l, select, offsets); + uvedit_loop_edge_select_set(ts, bm, l, select); if (select) { uvedit_uv_select_flush_from_tag_sticky_loc_internal(scene, bm, l, select, offsets); @@ -4235,7 +4279,7 @@ static void uv_select_flush_from_tag_face(const Scene *scene, Object *obedit, co if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) { continue; } - uvedit_face_select_set(scene, bm, efa, select, offsets); + uvedit_face_select_set(scene, bm, efa, select); } } } @@ -4290,18 +4334,50 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co /* now select tagged verts */ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + bool tag_all = true; + bool tag_any = false; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (BM_elem_flag_test(l->v, BM_ELEM_TAG)) { - uvedit_uv_select_set(scene, bm, l, select, offsets); + uvedit_uv_select_set(scene, bm, l, select); + tag_any = true; + } + else { + tag_all = false; + } + } + if (select) { + if (tag_all && uvedit_face_visible_test(scene, efa)) { + uvedit_face_select_set_no_sync(ts, bm, efa, true); + } + } + else { + if (tag_any && uvedit_face_visible_test(scene, efa)) { + uvedit_face_select_set_no_sync(ts, bm, efa, false); } } } } else if ((use_mesh_select == false) && (ts->uv_sticky == UV_STICKY_LOCATION)) { BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + bool tag_all = true; + bool tag_any = false; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (BM_elem_flag_test(l, BM_ELEM_TAG)) { uvedit_uv_select_flush_from_tag_sticky_loc_internal(scene, bm, l, select, offsets); + tag_any = true; + } + else { + tag_all = false; + } + } + if (select) { + if (tag_all && uvedit_face_visible_test(scene, efa)) { + uvedit_face_select_set_no_sync(ts, bm, efa, true); + } + } + else { + if (tag_any && uvedit_face_visible_test(scene, efa)) { + uvedit_face_select_set_no_sync(ts, bm, efa, false); } } } @@ -4310,7 +4386,7 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (BM_elem_flag_test(l, BM_ELEM_TAG)) { - uvedit_uv_select_set(scene, bm, l, select, offsets); + uvedit_uv_select_set(scene, bm, l, select); } } } @@ -4358,7 +4434,7 @@ static void uv_select_flush_from_loop_edge_flag(const Scene *scene, BMesh *bm) /* Use UV edge selection to identify which verts must to be selected */ /* Clear UV vert flags */ - bm_clear_uv_vert_selection(scene, bm, offsets); + bm_clear_uv_vert_selection(scene, bm); BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (!uvedit_face_visible_test(scene, efa)) { @@ -4368,7 +4444,7 @@ static void uv_select_flush_from_loop_edge_flag(const Scene *scene, BMesh *bm) } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { /* Select verts based on UV edge flag. */ - if (BM_ELEM_CD_GET_BOOL(l, offsets.select_edge)) { + if (uvedit_edge_select_get_no_sync(ts, bm, l)) { uvedit_uv_select_flush_from_tag_sticky_loc_internal(scene, bm, l, true, offsets); uvedit_uv_select_flush_from_tag_sticky_loc_internal(scene, bm, l->next, true, offsets); } @@ -4381,16 +4457,18 @@ static void uv_select_flush_from_loop_edge_flag(const Scene *scene, BMesh *bm) } else { BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + bool select_all = true; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - - if (BM_ELEM_CD_GET_BOOL(l, offsets.select_edge)) { - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true); - BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, true); + if (uvedit_edge_select_get_no_sync(ts, bm, l)) { + uvedit_vert_select_set_no_sync(ts, bm, l, true); + uvedit_vert_select_set_no_sync(ts, bm, l->next, true); } - else if (!BM_ELEM_CD_GET_BOOL(l->prev, offsets.select_edge)) { - BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, false); + else if (!uvedit_edge_select_get_no_sync(ts, bm, l->prev)) { + uvedit_vert_select_set_no_sync(ts, bm, l->next, false); + select_all = false; } } + uvedit_face_select_set_no_sync(ts, bm, efa, select_all); } } } @@ -4455,7 +4533,7 @@ static wmOperatorStatus uv_box_select_exec(bContext *C, wmOperator *op) uvedit_select_prepare_custom_data(scene, bm); if (pinned) { const char *active_uv_name = CustomData_get_active_layer_name(&bm->ldata, CD_PROP_FLOAT2); - BM_uv_map_attr_pin_ensure(bm, active_uv_name); + BM_uv_map_attr_pin_ensure_named(bm, active_uv_name); } } const BMUVOffsets offsets = BM_uv_map_offsets_get(bm); @@ -4570,14 +4648,14 @@ static wmOperatorStatus uv_box_select_exec(bContext *C, wmOperator *op) if (!pinned || (ts->uv_flag & UV_FLAG_SELECT_SYNC)) { /* UV_FLAG_SELECT_SYNC - can't do pinned selection */ if (BLI_rctf_isect_pt_v(&rectf, luv)) { - uvedit_uv_select_set(scene, bm, l, select, offsets); + uvedit_uv_select_set(scene, bm, l, select); BM_elem_flag_enable(l->v, BM_ELEM_TAG); has_selected = true; } } else if (pinned) { if (BM_ELEM_CD_GET_BOOL(l, offsets.pin) && BLI_rctf_isect_pt_v(&rectf, luv)) { - uvedit_uv_select_set(scene, bm, l, select, offsets); + uvedit_uv_select_set(scene, bm, l, select); BM_elem_flag_enable(l->v, BM_ELEM_TAG); } } @@ -4590,7 +4668,7 @@ static wmOperatorStatus uv_box_select_exec(bContext *C, wmOperator *op) } if (ts->uv_sticky == UV_STICKY_VERT) { - uvedit_vertex_select_tagged(bm, scene, select, offsets); + uvedit_vertex_select_tagged(bm, scene, select); } } @@ -4749,7 +4827,7 @@ static wmOperatorStatus uv_circle_select_exec(bContext *C, wmOperator *op) } else { BM_elem_flag_disable(efa, BM_ELEM_TAG); - if (select == uvedit_face_select_test(scene, bm, efa, offsets)) { + if (select == uvedit_face_select_test(scene, bm, efa)) { continue; } } @@ -4813,7 +4891,7 @@ static wmOperatorStatus uv_circle_select_exec(bContext *C, wmOperator *op) luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); if (uv_circle_select_is_point_inside(luv, offset, ellipse)) { changed = true; - uvedit_uv_select_set(scene, bm, l, select, offsets); + uvedit_uv_select_set(scene, bm, l, select); BM_elem_flag_enable(l->v, BM_ELEM_TAG); has_selected = true; } @@ -4826,7 +4904,7 @@ static wmOperatorStatus uv_circle_select_exec(bContext *C, wmOperator *op) } if (ts->uv_sticky == UV_STICKY_VERT) { - uvedit_vertex_select_tagged(bm, scene, select, offsets); + uvedit_vertex_select_tagged(bm, scene, select); } } @@ -4968,7 +5046,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const Span mcoords, const } else { BM_elem_flag_disable(efa, BM_ELEM_TAG); - if (select == uvedit_face_select_test(scene, bm, efa, offsets)) { + if (select == uvedit_face_select_test(scene, bm, efa)) { continue; } } @@ -5062,7 +5140,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const Span mcoords, const if (select != uvedit_uv_select_test(scene, bm, l, offsets)) { float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); if (do_lasso_select_mesh_uv_is_point_inside(region, &rect, mcoords, luv)) { - uvedit_uv_select_set(scene, bm, l, select, offsets); + uvedit_uv_select_set(scene, bm, l, select); changed = true; BM_elem_flag_enable(l->v, BM_ELEM_TAG); has_selected = true; @@ -5076,7 +5154,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const Span mcoords, const } if (ts->uv_sticky == UV_STICKY_VERT) { - uvedit_vertex_select_tagged(bm, scene, select, offsets); + uvedit_vertex_select_tagged(bm, scene, select); } } @@ -5182,7 +5260,7 @@ static wmOperatorStatus uv_select_pinned_exec(bContext *C, wmOperator *op) BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (BM_ELEM_CD_GET_BOOL(l, offsets.pin)) { - uvedit_uv_select_enable(scene, bm, l, offsets); + uvedit_uv_select_enable(scene, bm, l); changed = true; } } @@ -5446,20 +5524,9 @@ static wmOperatorStatus uv_select_overlap(bContext *C, const bool extend) if (scene->toolsettings->uv_flag & UV_FLAG_SELECT_SYNC) { /* Pass. */ } - else { - const char *uv_a_name = CustomData_get_active_layer_name(&bm_a->ldata, CD_PROP_FLOAT2); - const char *uv_b_name = CustomData_get_active_layer_name(&bm_b->ldata, CD_PROP_FLOAT2); - BM_uv_map_attr_vert_select_ensure(bm_a, uv_a_name); - BM_uv_map_attr_vert_select_ensure(bm_b, uv_b_name); - BM_uv_map_attr_edge_select_ensure(bm_a, uv_a_name); - BM_uv_map_attr_edge_select_ensure(bm_b, uv_b_name); - } - const BMUVOffsets offsets_a = BM_uv_map_offsets_get(bm_a); - const BMUVOffsets offsets_b = BM_uv_map_offsets_get(bm_b); - /* Skip if both faces are already selected. */ - if (uvedit_face_select_test(scene, bm_a, face_a, offsets_a) && - uvedit_face_select_test(scene, bm_b, face_b, offsets_b)) + if (uvedit_face_select_test(scene, bm_a, face_a) && + uvedit_face_select_test(scene, bm_b, face_b)) { continue; } @@ -5467,8 +5534,8 @@ static wmOperatorStatus uv_select_overlap(bContext *C, const bool extend) /* Main tri-tri overlap test. */ const float endpoint_bias = -1e-4f; if (overlap_tri_tri_uv_test(o_a->tri, o_b->tri, endpoint_bias)) { - uvedit_face_select_enable(scene, bm_a, face_a, offsets_a); - uvedit_face_select_enable(scene, bm_b, face_b, offsets_b); + uvedit_face_select_enable(scene, bm_a, face_a); + uvedit_face_select_enable(scene, bm_b, face_b); } } @@ -5786,7 +5853,7 @@ static wmOperatorStatus uv_select_similar_vert_exec(bContext *C, wmOperator *op) const float needle = get_uv_vert_needle(type, l->v, ob_m3, l, offsets); bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare); if (select) { - uvedit_uv_select_set(scene, bm, l, select, offsets); + uvedit_uv_select_set(scene, bm, l, select); changed = true; } } @@ -5913,7 +5980,7 @@ static wmOperatorStatus uv_select_similar_edge_exec(bContext *C, wmOperator *op) float needle = get_uv_edge_needle(type, l->e, ob_m3, l, l->next, offsets); bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare); if (select) { - uvedit_edge_select_set(scene, bm, l, select, offsets); + uvedit_edge_select_set(scene, bm, l, select); changed = true; } } @@ -5981,7 +6048,7 @@ static wmOperatorStatus uv_select_similar_face_exec(bContext *C, wmOperator *op) if (!uvedit_face_visible_test(scene, face)) { continue; } - if (!uvedit_face_select_test(scene, bm, face, offsets)) { + if (!uvedit_face_select_test(scene, bm, face)) { continue; } @@ -6023,7 +6090,7 @@ static wmOperatorStatus uv_select_similar_face_exec(bContext *C, wmOperator *op) if (!uvedit_face_visible_test(scene, face)) { continue; } - if (uvedit_face_select_test(scene, bm, face, offsets)) { + if (uvedit_face_select_test(scene, bm, face)) { continue; } @@ -6031,7 +6098,7 @@ static wmOperatorStatus uv_select_similar_face_exec(bContext *C, wmOperator *op) bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare); if (select) { - uvedit_face_select_set(scene, bm, face, select, offsets); + uvedit_face_select_set(scene, bm, face, select); changed = true; } } @@ -6059,7 +6126,7 @@ static wmOperatorStatus uv_select_similar_face_exec(bContext *C, wmOperator *op) static bool uv_island_selected(const Scene *scene, const BMesh *bm, FaceIsland *island) { BLI_assert(island && island->faces_len); - return uvedit_face_select_test(scene, bm, island->faces[0], island->offsets); + return uvedit_face_select_test(scene, bm, island->faces[0]); } static wmOperatorStatus uv_select_similar_island_exec(bContext *C, wmOperator *op) @@ -6146,7 +6213,7 @@ static wmOperatorStatus uv_select_similar_island_exec(bContext *C, wmOperator *o continue; } for (int j = 0; j < island->faces_len; j++) { - uvedit_face_select_set(scene, bm, island->faces[j], select, island->offsets); + uvedit_face_select_set(scene, bm, island->faces[j], select); } changed = true; } @@ -6312,8 +6379,6 @@ void UV_OT_select_similar(wmOperatorType *ot) BMFace **ED_uvedit_selected_faces(const Scene *scene, BMesh *bm, int len_max, int *r_faces_len) { - const BMUVOffsets offsets = BM_uv_map_offsets_get(bm); - CLAMP_MAX(len_max, bm->totface); int faces_len = 0; BMFace **faces = MEM_malloc_arrayN(len_max, __func__); @@ -6322,7 +6387,7 @@ BMFace **ED_uvedit_selected_faces(const Scene *scene, BMesh *bm, int len_max, in BMFace *f; BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { if (uvedit_face_visible_test(scene, f)) { - if (uvedit_face_select_test(scene, bm, f, offsets)) { + if (uvedit_face_select_test(scene, bm, f)) { faces[faces_len++] = f; if (faces_len == len_max) { goto finally; @@ -6399,8 +6464,8 @@ finally: BMLoop **ED_uvedit_selected_verts(const Scene *scene, BMesh *bm, int len_max, int *r_verts_len) { + const ToolSettings *ts = scene->toolsettings; const BMUVOffsets offsets = BM_uv_map_offsets_get(bm); - BLI_assert(offsets.select_vert >= 0); BLI_assert(offsets.uv >= 0); CLAMP_MAX(len_max, bm->totloop); @@ -6425,7 +6490,7 @@ BMLoop **ED_uvedit_selected_verts(const Scene *scene, BMesh *bm, int len_max, in BMLoop *l_iter; BM_ITER_ELEM (l_iter, &liter, f, BM_LOOPS_OF_FACE) { if (!BM_elem_flag_test(l_iter, BM_ELEM_TAG)) { - if (BM_ELEM_CD_GET_BOOL(l_iter, offsets.select_vert)) { + if (uvedit_vert_select_get_no_sync(ts, bm, l_iter)) { BM_elem_flag_enable(l_iter->v, BM_ELEM_TAG); verts[verts_len++] = l_iter; @@ -6514,10 +6579,10 @@ void ED_uvedit_selectmode_clean(const Scene *scene, Object *obedit) BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { BM_elem_flag_disable(efa, BM_ELEM_TAG); if (uvedit_face_visible_test(scene, efa)) { - if (uvedit_face_select_test(scene, bm, efa, offsets)) { + if (uvedit_face_select_test(scene, bm, efa)) { BM_elem_flag_enable(efa, BM_ELEM_TAG); } - uvedit_face_select_set(scene, bm, efa, false, offsets); + uvedit_face_select_set(scene, bm, efa, false); } } uv_select_flush_from_tag_face(scene, obedit, true); @@ -6525,7 +6590,6 @@ void ED_uvedit_selectmode_clean(const Scene *scene, Object *obedit) ED_uvedit_selectmode_flush(scene, bm); } - void ED_uvedit_selectmode_clean_multi(bContext *C) { Scene *scene = CTX_data_scene(C); diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.cc b/source/blender/editors/uvedit/uvedit_smart_stitch.cc index 59c94c11fa8..995cc921134 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.cc +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.cc @@ -920,7 +920,7 @@ static void stitch_propagate_uv_final_position(Scene *scene, if (final) { copy_v2_v2(luv, final_position[index].uv); - uvedit_uv_select_enable(scene, state->em->bm, l, offsets); + uvedit_uv_select_enable(scene, state->em->bm, l); } else { int face_preview_pos = diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc index ac68cf07805..89a101ba858 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc @@ -104,19 +104,16 @@ static bool uvedit_ensure_uvs(Object *obedit) return false; } - const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); - BM_uv_map_attr_vert_select_ensure(em->bm, active_uv_name); - BM_uv_map_attr_edge_select_ensure(em->bm, active_uv_name); - const BMUVOffsets offsets = BM_uv_map_offsets_get(em->bm); - /* select new UVs (ignore UV_FLAG_SELECT_SYNC in this case) */ + em->bm->uv_select_sync_valid = false; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BMIter liter; BMLoop *l; + BM_elem_flag_enable(l->f, BM_ELEM_SELECT_UV); BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true); - BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true); + BM_elem_flag_enable(l, BM_ELEM_SELECT_UV); + BM_elem_flag_enable(l, BM_ELEM_SELECT_UV_EDGE); } } @@ -2667,7 +2664,7 @@ static void uv_map_clip_correct(const Scene *scene, continue; } - if (only_selected_uvs && !uvedit_face_select_test(scene, em->bm, efa, offsets)) { + if (only_selected_uvs && !uvedit_face_select_test(scene, em->bm, efa)) { continue; } @@ -2684,7 +2681,7 @@ static void uv_map_clip_correct(const Scene *scene, continue; } - if (only_selected_uvs && !uvedit_face_select_test(scene, em->bm, efa, offsets)) { + if (only_selected_uvs && !uvedit_face_select_test(scene, em->bm, efa)) { continue; } @@ -2722,7 +2719,7 @@ static void uv_map_clip_correct(const Scene *scene, continue; } - if (only_selected_uvs && !uvedit_face_select_test(scene, em->bm, efa, offsets)) { + if (only_selected_uvs && !uvedit_face_select_test(scene, em->bm, efa)) { continue; } @@ -3258,8 +3255,8 @@ static wmOperatorStatus smart_project_exec(bContext *C, wmOperator *op) } if (only_selected_uvs) { - if (!uvedit_face_select_test(scene, em->bm, efa, offsets)) { - uvedit_face_select_disable(scene, em->bm, efa, offsets); + if (!uvedit_face_select_test(scene, em->bm, efa)) { + uvedit_face_select_disable(scene, em->bm, efa); continue; } } @@ -3851,8 +3848,8 @@ static float uv_sphere_project(const Scene *scene, } if (only_selected_uvs) { - if (!uvedit_face_select_test(scene, bm, efa, offsets)) { - uvedit_face_select_disable(scene, bm, efa, offsets); + if (!uvedit_face_select_test(scene, bm, efa)) { + uvedit_face_select_disable(scene, bm, efa); continue; /* Unselected UV, ignore. */ } } @@ -4027,8 +4024,8 @@ static float uv_cylinder_project(const Scene *scene, } if (only_selected_uvs) { - if (!uvedit_face_select_test(scene, bm, efa, offsets)) { - uvedit_face_select_disable(scene, bm, efa, offsets); + if (!uvedit_face_select_test(scene, bm, efa)) { + uvedit_face_select_disable(scene, bm, efa); continue; /* Unselected UV, ignore. */ } } @@ -4123,8 +4120,8 @@ static wmOperatorStatus cylinder_project_exec(bContext *C, wmOperator *op) continue; } - if (only_selected_uvs && !uvedit_face_select_test(scene, em->bm, efa, offsets)) { - uvedit_face_select_disable(scene, em->bm, efa, offsets); + if (only_selected_uvs && !uvedit_face_select_test(scene, em->bm, efa)) { + uvedit_face_select_disable(scene, em->bm, efa); continue; } @@ -4208,8 +4205,8 @@ static void uvedit_unwrap_cube_project(const Scene *scene, if (use_select && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) { continue; } - if (only_selected_uvs && !uvedit_face_select_test(scene, bm, efa, offsets)) { - uvedit_face_select_disable(scene, bm, efa, offsets); + if (only_selected_uvs && !uvedit_face_select_test(scene, bm, efa)) { + uvedit_face_select_disable(scene, bm, efa); continue; } @@ -4340,7 +4337,7 @@ void ED_uvedit_add_simple_uvs(Main *bmain, const Scene *scene, Object *ob) BM_mesh_bm_from_me(bm, mesh, &bm_from_me_params); /* Select all UVs for cube_project. */ - ED_uvedit_select_all(bm); + ED_uvedit_select_all(scene->toolsettings, bm); /* A cube size of 2.0 maps [-1..1] vertex coords to [0.0..1.0] in UV coords. */ uvedit_unwrap_cube_project(scene, bm, 2.0, false, false, nullptr); diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index d75c6bf8f4d..23fd23b556b 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -514,7 +514,11 @@ enum { ME_FLAG_UNUSED_0 = 1 << 0, /* cleared */ ME_FLAG_UNUSED_1 = 1 << 1, /* cleared */ ME_FLAG_DEPRECATED_2 = 1 << 2, /* deprecated */ - ME_FLAG_UNUSED_3 = 1 << 3, /* cleared */ + /** + * The UV selection is marked as synchronized. + * See #BMesh::uv_select_sync_valid for details. + */ + ME_FLAG_UV_SELECT_SYNC_VALID = 1 << 3, ME_FLAG_UNUSED_4 = 1 << 4, /* cleared */ ME_AUTOSMOOTH_LEGACY = 1 << 5, /* deprecated */ ME_FLAG_UNUSED_6 = 1 << 6, /* cleared */ diff --git a/source/blender/makesrna/intern/rna_mesh.cc b/source/blender/makesrna/intern/rna_mesh.cc index 46ab322de9b..6347afa85c9 100644 --- a/source/blender/makesrna/intern/rna_mesh.cc +++ b/source/blender/makesrna/intern/rna_mesh.cc @@ -951,54 +951,6 @@ static PointerRNA bool_layer_ensure(PointerRNA *ptr, return RNA_pointer_create_discrete(&mesh->id, &RNA_BoolAttribute, bool_layer); } -/* Collection accessors for vert_select. */ -static void rna_MeshUVLoopLayer_vert_select_begin(CollectionPropertyIterator *iter, - PointerRNA *ptr) -{ - bool_layer_begin(iter, ptr, BKE_uv_map_vert_select_name_get); -} - -static bool rna_MeshUVLoopLayer_vert_select_lookup_int(PointerRNA *ptr, - int index, - PointerRNA *r_ptr) -{ - return bool_layer_lookup_int(ptr, index, r_ptr, BKE_uv_map_vert_select_name_get); -} - -static int rna_MeshUVLoopLayer_vert_select_length(PointerRNA *ptr) -{ - return bool_layer_length(ptr, BKE_uv_map_vert_select_name_get); -} - -static PointerRNA rna_MeshUVLoopLayer_vert_select_ensure(PointerRNA ptr) -{ - return bool_layer_ensure(&ptr, BKE_uv_map_vert_select_name_get); -} - -/* Collection accessors for edge_select. */ -static void rna_MeshUVLoopLayer_edge_select_begin(CollectionPropertyIterator *iter, - PointerRNA *ptr) -{ - bool_layer_begin(iter, ptr, BKE_uv_map_edge_select_name_get); -} - -static bool rna_MeshUVLoopLayer_edge_select_lookup_int(PointerRNA *ptr, - int index, - PointerRNA *r_ptr) -{ - return bool_layer_lookup_int(ptr, index, r_ptr, BKE_uv_map_edge_select_name_get); -} - -static int rna_MeshUVLoopLayer_edge_select_length(PointerRNA *ptr) -{ - return bool_layer_length(ptr, BKE_uv_map_edge_select_name_get); -} - -static PointerRNA rna_MeshUVLoopLayer_edge_selection_ensure(PointerRNA ptr) -{ - return bool_layer_ensure(&ptr, BKE_uv_map_edge_select_name_get); -} - /* Collection accessors for pin. */ static void rna_MeshUVLoopLayer_pin_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { @@ -1722,56 +1674,6 @@ static bool get_uv_index_and_layer(const PointerRNA *ptr, return false; } -static bool rna_MeshUVLoop_select_get(PointerRNA *ptr) -{ - const Mesh *mesh = rna_mesh(ptr); - int uv_map_index; - int loop_index; - blender::VArray select; - if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) { - select = ED_mesh_uv_map_vert_select_layer_get(mesh, uv_map_index); - } - return select ? select[loop_index] : false; -} - -static void rna_MeshUVLoop_select_set(PointerRNA *ptr, const bool value) -{ - Mesh *mesh = rna_mesh(ptr); - int uv_map_index; - int loop_index; - if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) { - blender::bke::AttributeWriter select = ED_mesh_uv_map_vert_select_layer_ensure( - mesh, uv_map_index); - select.varray.set(loop_index, value); - select.finish(); - } -} - -static bool rna_MeshUVLoop_select_edge_get(PointerRNA *ptr) -{ - const Mesh *mesh = rna_mesh(ptr); - int uv_map_index; - int loop_index; - blender::VArray select_edge; - if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) { - select_edge = ED_mesh_uv_map_edge_select_layer_get(mesh, uv_map_index); - } - return select_edge ? select_edge[loop_index] : false; -} - -static void rna_MeshUVLoop_select_edge_set(PointerRNA *ptr, const bool value) -{ - Mesh *mesh = rna_mesh(ptr); - int uv_map_index; - int loop_index; - if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) { - blender::bke::AttributeWriter select_edge = ED_mesh_uv_map_edge_select_layer_ensure( - mesh, uv_map_index); - select_edge.varray.set(loop_index, value); - select_edge.finish(); - } -} - static bool rna_MeshUVLoop_pin_uv_get(PointerRNA *ptr) { const Mesh *mesh = rna_mesh(ptr); @@ -2400,52 +2302,6 @@ static void rna_def_mloopuv(BlenderRNA *brna) nullptr, nullptr); - prop = RNA_def_property(srna, "vertex_selection", PROP_COLLECTION, PROP_NONE); - RNA_def_property_struct_type(prop, "BoolAttributeValue"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text( - prop, "UV Vertex Selection", "Selection state of the face corner the UV editor"); - RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); - RNA_def_property_collection_funcs(prop, - "rna_MeshUVLoopLayer_vert_select_begin", - "rna_iterator_array_next", - "rna_iterator_array_end", - "rna_iterator_array_get", - "rna_MeshUVLoopLayer_vert_select_length", - "rna_MeshUVLoopLayer_vert_select_lookup_int", - nullptr, - nullptr); - - func = RNA_def_function( - srna, "vertex_selection_ensure", "rna_MeshUVLoopLayer_vert_select_ensure"); - RNA_def_function_flag(func, FUNC_SELF_AS_RNA); - parm = RNA_def_pointer(func, "layer", "BoolAttribute", "", "The boolean attribute"); - RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_RNAPTR); - RNA_def_function_return(func, parm); - - prop = RNA_def_property(srna, "edge_selection", PROP_COLLECTION, PROP_NONE); - RNA_def_property_struct_type(prop, "BoolAttributeValue"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text( - prop, "UV Edge Selection", "Selection state of the edge in the UV editor"); - RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); - RNA_def_property_collection_funcs(prop, - "rna_MeshUVLoopLayer_edge_select_begin", - "rna_iterator_array_next", - "rna_iterator_array_end", - "rna_iterator_array_get", - "rna_MeshUVLoopLayer_edge_select_length", - "rna_MeshUVLoopLayer_edge_select_lookup_int", - nullptr, - nullptr); - - func = RNA_def_function( - srna, "edge_selection_ensure", "rna_MeshUVLoopLayer_edge_selection_ensure"); - RNA_def_function_flag(func, FUNC_SELF_AS_RNA); - parm = RNA_def_pointer(func, "layer", "BoolAttribute", "", "The boolean attribute"); - RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_RNAPTR); - RNA_def_function_return(func, parm); - prop = RNA_def_property(srna, "pin", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "BoolAttributeValue"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); @@ -2481,17 +2337,6 @@ static void rna_def_mloopuv(BlenderRNA *brna) RNA_def_property_boolean_funcs(prop, "rna_MeshUVLoop_pin_uv_get", "rna_MeshUVLoop_pin_uv_set"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "UV Pinned", ""); - - prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_MeshUVLoop_select_get", "rna_MeshUVLoop_select_set"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "UV Select", ""); - - prop = RNA_def_property(srna, "select_edge", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs( - prop, "rna_MeshUVLoop_select_edge_get", "rna_MeshUVLoop_select_edge_set"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "UV Edge Select", ""); } static void rna_def_mloopcol(BlenderRNA *brna) diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc index 6365df60c3a..1165f919b88 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc @@ -84,7 +84,7 @@ static Mesh *create_ico_sphere_mesh(const int subdivisions, /* Make sure the associated boolean layers exists as well. Normally this would be done when * adding a UV layer via python or when copying from Mesh, but when we 'manually' create the UV * layer we need to make sure the boolean layers exist as well. */ - BM_uv_map_attr_select_and_pin_ensure(bm); + BM_uv_map_attr_pin_ensure_for_all_layers(bm); BMO_op_callf(bm, BMO_FLAG_DEFAULTS, diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.cc b/source/blender/python/bmesh/bmesh_py_types_customdata.cc index 8f0e173563a..16b58e947dc 100644 --- a/source/blender/python/bmesh/bmesh_py_types_customdata.cc +++ b/source/blender/python/bmesh/bmesh_py_types_customdata.cc @@ -493,7 +493,7 @@ static PyObject *bpy_bmlayercollection_verify(BPy_BMLayerCollection *self) /* Because adding CustomData layers to a bmesh will invalidate any existing pointers * in Py objects we can't lazily add the associated bool layers. So add them all right * now. */ - BM_uv_map_attr_select_and_pin_ensure(self->bm); + BM_uv_map_attr_pin_ensure_for_all_layers(self->bm); } BLI_assert(index >= 0); @@ -544,7 +544,7 @@ static PyObject *bpy_bmlayercollection_new(BPy_BMLayerCollection *self, PyObject /* Because adding CustomData layers to a bmesh will invalidate any existing pointers * in Py objects we can't lazily add the associated bool layers. So add them all right * now. */ - BM_uv_map_attr_select_and_pin_ensure(self->bm); + BM_uv_map_attr_pin_ensure_for_all_layers(self->bm); } index = CustomData_number_of_layers(data, eCustomDataType(self->type)) - 1; diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.cc b/source/blender/python/bmesh/bmesh_py_types_meshdata.cc index 7e993ba9e39..d3601c313f6 100644 --- a/source/blender/python/bmesh/bmesh_py_types_meshdata.cc +++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.cc @@ -52,8 +52,6 @@ struct BPy_BMLoopUV { * datablocks (adding a layer re-generates all blocks). But eventually the plan is to lazily * allocate the bool layers 'on demand'. Therefore the code tries to handle all cases where * the layers don't exist. */ - bool *vert_select; - bool *edge_select; bool *pin; BMLoop *loop; }; @@ -124,46 +122,6 @@ static int bpy_bmloopuv_pin_uv_set(BPy_BMLoopUV *self, PyObject *value, void * / return 0; } -static PyObject *bpy_bmloopuv_select_get(BPy_BMLoopUV *self, void * /*closure*/) -{ - /* A non existing vert_select layer means nothing is currently selected */ - return self->vert_select ? PyBool_FromLong(*self->vert_select) : nullptr; -} -static int bpy_bmloopuv_select_set(BPy_BMLoopUV *self, PyObject *value, void * /*closure*/) -{ - /* TODO: see comment above on bpy_bmloopuv_pin_uv_set(), the same applies here. */ - BLI_assert(self->vert_select); - if (self->vert_select) { - *self->vert_select = PyC_Long_AsBool(value); - } - else { - PyErr_SetString(PyExc_RuntimeError, - "active uv layer has no associated vertex selection layer. This is a bug!"); - return -1; - } - return 0; -} - -static PyObject *bpy_bmloopuv_select_edge_get(BPy_BMLoopUV *self, void * /*closure*/) -{ - /* A non existing edge_select layer means nothing is currently selected */ - return self->edge_select ? PyBool_FromLong(*self->edge_select) : nullptr; -} -static int bpy_bmloopuv_select_edge_set(BPy_BMLoopUV *self, PyObject *value, void * /*closure*/) -{ - /* TODO: see comment above on bpy_bmloopuv_pin_uv_set(), the same applies here. */ - BLI_assert(self->edge_select); - if (self->edge_select) { - *self->edge_select = PyC_Long_AsBool(value); - } - else { - PyErr_SetString(PyExc_RuntimeError, - "active uv layer has no associated edge selection layer. This is a bug!"); - return -1; - } - return 0; -} - static PyGetSetDef bpy_bmloopuv_getseters[] = { /* attributes match rna_def_mloopuv. */ {"uv", (getter)bpy_bmloopuv_uv_get, (setter)bpy_bmloopuv_uv_set, bpy_bmloopuv_uv_doc, nullptr}, @@ -172,17 +130,6 @@ static PyGetSetDef bpy_bmloopuv_getseters[] = { (setter)bpy_bmloopuv_pin_uv_set, bpy_bmloopuv_pin_uv_doc, nullptr}, - {"select", - (getter)bpy_bmloopuv_select_get, - (setter)bpy_bmloopuv_select_set, - bpy_bmloopuv_select_doc, - nullptr}, - {"select_edge", - (getter)bpy_bmloopuv_select_edge_get, - (setter)bpy_bmloopuv_select_edge_set, - bpy_bmloopuv_select_edge_doc, - nullptr}, - {nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */ }; @@ -215,14 +162,6 @@ int BPy_BMLoopUV_AssignPyObject(BMesh *bm, BMLoop *loop, PyObject *value) float *luv = BM_ELEM_CD_GET_FLOAT_P(loop, offsets.uv); copy_v2_v2(luv, src->uv); - - if (src->vert_select) { - BM_ELEM_CD_SET_BOOL(loop, offsets.select_vert, *src->vert_select); - } - - if (src->edge_select) { - BM_ELEM_CD_SET_BOOL(loop, offsets.select_edge, *src->edge_select); - } if (src->pin) { BM_ELEM_CD_SET_BOOL(loop, offsets.pin, *src->pin); } @@ -236,10 +175,6 @@ PyObject *BPy_BMLoopUV_CreatePyObject(BMesh *bm, BMLoop *loop, int layer) const BMUVOffsets offsets = BM_uv_map_offsets_from_layer(bm, layer); self->uv = BM_ELEM_CD_GET_FLOAT_P(loop, offsets.uv); - self->vert_select = offsets.select_vert >= 0 ? BM_ELEM_CD_GET_BOOL_P(loop, offsets.select_vert) : - nullptr; - self->edge_select = offsets.select_edge >= 0 ? BM_ELEM_CD_GET_BOOL_P(loop, offsets.select_edge) : - nullptr; self->pin = offsets.pin >= 0 ? BM_ELEM_CD_GET_BOOL_P(loop, offsets.pin) : nullptr; return (PyObject *)self;