From bd4c310a1905f53645aa0fd969ed8999a6a881e7 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 17 Oct 2023 09:56:24 +0200 Subject: [PATCH] Fix: Missing edge domain in node tool set selection node This wasn't implemented in the initial commit because we didn't have a function to flush edge selections to vertices and faces. But using the existing domain interpolations makes that trivial, so it may as well be added now to avoid the arbitrary limitation from the user perspective. See https://devtalk.blender.org/t/node-tools-feedback/31388/5 Pull Request: https://projects.blender.org/blender/blender/pulls/113367 --- source/blender/blenkernel/BKE_mesh.h | 1 + .../blenkernel/intern/mesh_evaluate.cc | 38 +++++++++++++++++++ source/blender/makesrna/RNA_enum_items.hh | 2 +- .../blender/makesrna/intern/rna_attribute.cc | 3 +- .../nodes/node_geo_tool_set_selection.cc | 9 ++++- 5 files changed, 50 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 6798616c82b..1ab2a3a7647 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -539,6 +539,7 @@ void BKE_mesh_flush_hidden_from_faces(struct Mesh *me); void BKE_mesh_flush_select_from_faces(struct Mesh *me); void BKE_mesh_flush_select_from_verts(struct Mesh *me); +void BKE_mesh_flush_select_from_edges(struct Mesh *me); /* spatial evaluation */ /** diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc index 6a650780c9c..2b5d0e63d1b 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.cc +++ b/source/blender/blenkernel/intern/mesh_evaluate.cc @@ -683,6 +683,44 @@ void BKE_mesh_flush_select_from_verts(Mesh *me) select_poly.finish(); } +void BKE_mesh_flush_select_from_edges(Mesh *me) +{ + using namespace blender; + using namespace blender::bke; + MutableAttributeAccessor attributes = me->attributes_for_write(); + const VArray select_edge = *attributes.lookup_or_default( + ".select_edge", ATTR_DOMAIN_POINT, false); + if (select_edge.is_single() && !select_edge.get_internal_single()) { + attributes.remove(".select_vert"); + attributes.remove(".select_poly"); + return; + } + SpanAttributeWriter select_vert = attributes.lookup_or_add_for_write_only_span( + ".select_vert", ATTR_DOMAIN_POINT); + SpanAttributeWriter select_poly = attributes.lookup_or_add_for_write_only_span( + ".select_poly", ATTR_DOMAIN_FACE); + { + IndexMaskMemory memory; + const VArray hide_vert = *attributes.lookup_or_default( + ".hide_vert", ATTR_DOMAIN_POINT, false); + array_utils::copy( + *attributes.lookup_or_default(".select_vert", ATTR_DOMAIN_POINT, false), + IndexMask::from_bools(hide_vert, memory).complement(hide_vert.index_range(), memory), + select_vert.span); + } + { + IndexMaskMemory memory; + const VArray hide_poly = *attributes.lookup_or_default( + ".hide_poly", ATTR_DOMAIN_FACE, false); + array_utils::copy( + *attributes.lookup_or_default(".select_vert", ATTR_DOMAIN_FACE, false), + IndexMask::from_bools(hide_poly, memory).complement(hide_poly.index_range(), memory), + select_poly.span); + } + select_vert.finish(); + select_poly.finish(); +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/makesrna/RNA_enum_items.hh b/source/blender/makesrna/RNA_enum_items.hh index 273739a1c54..5cc1fefc547 100644 --- a/source/blender/makesrna/RNA_enum_items.hh +++ b/source/blender/makesrna/RNA_enum_items.hh @@ -225,7 +225,7 @@ DEF_ENUM(rna_enum_attribute_type_with_auto_items) DEF_ENUM(rna_enum_attribute_domain_items) DEF_ENUM(rna_enum_attribute_domain_edge_face_items) DEF_ENUM(rna_enum_attribute_domain_only_mesh_items) -DEF_ENUM(rna_enum_attribute_domain_point_face_curve_items) +DEF_ENUM(rna_enum_attribute_domain_point_edge_face_curve_items) DEF_ENUM(rna_enum_attribute_curves_domain_items) DEF_ENUM(rna_enum_color_attribute_domain_items) DEF_ENUM(rna_enum_attribute_domain_without_corner_items) diff --git a/source/blender/makesrna/intern/rna_attribute.cc b/source/blender/makesrna/intern/rna_attribute.cc index 1f534a26be0..d22d08ddc87 100644 --- a/source/blender/makesrna/intern/rna_attribute.cc +++ b/source/blender/makesrna/intern/rna_attribute.cc @@ -99,8 +99,9 @@ const EnumPropertyItem rna_enum_attribute_domain_only_mesh_items[] = { {0, nullptr, 0, nullptr, nullptr}, }; -const EnumPropertyItem rna_enum_attribute_domain_point_face_curve_items[] = { +const EnumPropertyItem rna_enum_attribute_domain_point_edge_face_curve_items[] = { {ATTR_DOMAIN_POINT, "POINT", 0, "Point", "Attribute on point"}, + {ATTR_DOMAIN_EDGE, "EDGE", 0, "Edge", "Attribute on mesh edge"}, {ATTR_DOMAIN_FACE, "FACE", 0, "Face", "Attribute on mesh faces"}, {ATTR_DOMAIN_CURVE, "CURVE", 0, "Spline", "Attribute on spline"}, {0, nullptr, 0, nullptr, nullptr}, diff --git a/source/blender/nodes/geometry/nodes/node_geo_tool_set_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_tool_set_selection.cc index c583f193143..58b9ff246cd 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_tool_set_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_tool_set_selection.cc @@ -54,6 +54,13 @@ static void node_geo_exec(GeoNodeExecParams params) selection); BKE_mesh_flush_select_from_verts(mesh); break; + case ATTR_DOMAIN_EDGE: + bke::try_capture_field_on_geometry(geometry.get_component_for_write(), + ".select_edge", + ATTR_DOMAIN_EDGE, + selection); + BKE_mesh_flush_select_from_edges(mesh); + break; case ATTR_DOMAIN_FACE: /* Remove attributes in case they are on the wrong domain, which can happen after * conversion to and from other geometry types. */ @@ -93,7 +100,7 @@ static void node_rna(StructRNA *srna) "domain", "Domain", "", - rna_enum_attribute_domain_point_face_curve_items, + rna_enum_attribute_domain_point_edge_face_curve_items, NOD_inline_enum_accessors(custom1), ATTR_DOMAIN_POINT); }