Blender V4.3
node_geo_tool_set_selection.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BKE_mesh.hh"
7
8#include "NOD_rna_define.hh"
9
10#include "UI_interface.hh"
11#include "UI_resources.hh"
12
13#include "RNA_enum_types.hh"
14
15#include "node_geometry_util.hh"
16
18
20enum class SelectionType {
21 Boolean = 0,
22 Float = 1,
23};
24
26{
27 b.add_input<decl::Geometry>("Geometry");
28 if (const bNode *node = b.node_or_null()) {
29 switch (SelectionType(node->custom2)) {
31 b.add_input<decl::Bool>("Selection").default_value(true).field_on_all();
32 break;
34 b.add_input<decl::Float>("Selection").default_value(1.0f).field_on_all();
35 break;
36 }
37 }
38 b.add_output<decl::Geometry>("Geometry");
39}
40
41static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
42{
43 uiItemR(layout, ptr, "domain", UI_ITEM_NONE, "", ICON_NONE);
44 uiItemR(layout, ptr, "selection_type", UI_ITEM_NONE, "", ICON_NONE);
45}
46
47static void node_init(bNodeTree * /*tree*/, bNode *node)
48{
49 node->custom1 = int16_t(AttrDomain::Point);
50 node->custom2 = int16_t(SelectionType::Boolean);
51}
52
53static GField clamp_selection(const GField &selection)
54{
55 if (selection.cpp_type().is<bool>()) {
56 return selection;
57 }
58 static auto clamp = mf::build::SI1_SO<float, float>(
59 "Clamp", [](const float value) { return std::clamp(value, 0.0f, 1.0f); });
60 return Field<bool>(FieldOperation::Create(clamp, {selection}));
61}
62
63static GField invert_selection(const GField &selection)
64{
65 if (selection.cpp_type().is<bool>()) {
66 static auto invert = mf::build::SI1_SO<bool, bool>("Invert Selection",
67 [](const bool value) { return !value; });
68 return GField(FieldOperation::Create(invert, {selection}));
69 }
70
71 static auto invert = mf::build::SI1_SO<float, float>(
72 "Invert Selection", [](const float value) { return 1.0f - value; });
73 return GField(FieldOperation::Create(invert, {selection}));
74}
75
77{
79 return;
80 }
81 GeometrySet geometry = params.extract_input<GeometrySet>("Geometry");
82 const eObjectMode mode = params.user_data()->call_data->operator_data->mode;
83 if (mode == OB_MODE_OBJECT) {
84 params.error_message_add(NodeWarningType::Error,
85 "Selection control is not supported in object mode");
86 params.set_output("Geometry", std::move(geometry));
87 return;
88 }
89
90 const GField selection = params.extract_input<GField>("Selection");
91 const AttrDomain domain = AttrDomain(params.node().custom1);
93 geometry.modify_geometry_sets([&](GeometrySet &geometry) {
94 if (Mesh *mesh = geometry.get_mesh_for_write()) {
95 switch (mode) {
96 case OB_MODE_EDIT: {
97 const Field<bool> field = conversions.try_convert(selection, CPPType::get<bool>());
98 switch (domain) {
99 case AttrDomain::Point:
100 /* Remove attributes in case they are on the wrong domain, which can happen after
101 * conversion to and from other geometry types. */
102 mesh->attributes_for_write().remove(".select_edge");
103 mesh->attributes_for_write().remove(".select_poly");
104 bke::try_capture_field_on_geometry(geometry.get_component_for_write<MeshComponent>(),
105 ".select_vert",
106 AttrDomain::Point,
107 field);
108 bke::mesh_select_vert_flush(*mesh);
109 break;
110 case AttrDomain::Edge:
111 bke::try_capture_field_on_geometry(geometry.get_component_for_write<MeshComponent>(),
112 ".select_edge",
113 AttrDomain::Edge,
114 field);
115 bke::mesh_select_edge_flush(*mesh);
116 break;
117 case AttrDomain::Face:
118 /* Remove attributes in case they are on the wrong domain, which can happen after
119 * conversion to and from other geometry types. */
120 mesh->attributes_for_write().remove(".select_vert");
121 mesh->attributes_for_write().remove(".select_edge");
122 bke::try_capture_field_on_geometry(geometry.get_component_for_write<MeshComponent>(),
123 ".select_poly",
124 AttrDomain::Face,
125 field);
126 bke::mesh_select_face_flush(*mesh);
127 break;
128 default: {
129 break;
130 }
131 }
132 break;
133 }
134 case OB_MODE_SCULPT: {
135 GField on_domain = GField(
136 std::make_shared<bke::EvaluateOnDomainInput>(selection, domain));
137 GField clamped_and_inverted = invert_selection(clamp_selection(std::move(on_domain)));
138 const Field<float> field = conversions.try_convert(std::move(clamped_and_inverted),
139 CPPType::get<float>());
140 bke::try_capture_field_on_geometry(geometry.get_component_for_write<MeshComponent>(),
141 ".sculpt_mask",
142 AttrDomain::Point,
143 field);
144 break;
145 }
146 default: {
147 break;
148 }
149 }
150 }
151 if (geometry.has_curves()) {
152 const Field<float> field = clamp_selection(selection);
153 if (ELEM(domain, AttrDomain::Point, AttrDomain::Curve)) {
154 bke::try_capture_field_on_geometry(
155 geometry.get_component_for_write<CurveComponent>(), ".selection", domain, field);
156 }
157 }
158 if (geometry.has_pointcloud()) {
159 const Field<float> field = clamp_selection(selection);
160 if (domain == AttrDomain::Point) {
161 bke::try_capture_field_on_geometry(
162 geometry.get_component_for_write<PointCloudComponent>(), ".selection", domain, field);
163 }
164 }
165 });
166 params.set_output("Geometry", std::move(geometry));
167}
168
169static void node_rna(StructRNA *srna)
170{
172 "domain",
173 "Domain",
174 "",
177 int(AttrDomain::Point));
178 static EnumPropertyItem mode_items[] = {
179 {int(SelectionType::Boolean),
180 "BOOLEAN",
181 0,
182 "Boolean",
183 "Store true or false selection values in edit mode"},
184 {int(SelectionType::Float),
185 "FLOAT",
186 0,
187 "Float",
188 "Store floating point selection values. For mesh geometry, stored inverted as the sculpt "
189 "mode mask"},
190 {0, nullptr, 0, nullptr, nullptr},
191 };
193 "selection_type",
194 "Selection Type",
195 "",
196 mode_items,
198 int(SelectionType::Boolean));
199}
200
201static void node_register()
202{
203 static blender::bke::bNodeType ntype;
204 geo_node_type_base(&ntype, GEO_NODE_TOOL_SET_SELECTION, "Set Selection", NODE_CLASS_GEOMETRY);
205 ntype.declare = node_declare;
206 ntype.initfunc = node_init;
211
212 node_rna(ntype.rna_ext.srna);
213}
214NOD_REGISTER_NODE(node_register)
215
216} // namespace blender::nodes::node_geo_tool_set_selection_cc
#define NODE_CLASS_GEOMETRY
Definition BKE_node.hh:418
eObjectMode
@ OB_MODE_OBJECT
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define NOD_inline_enum_accessors(member)
#define UI_ITEM_NONE
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
static std::shared_ptr< FieldOperation > Create(std::shared_ptr< const mf::MultiFunction > function, Vector< GField > inputs={})
Definition FN_field.hh:244
local_group_size(16, 16) .push_constant(Type b
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
Definition invert.h:9
const DataTypeConversions & get_implicit_type_conversions()
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
static void node_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
static void node_declare(NodeDeclarationBuilder &b)
static GField invert_selection(const GField &selection)
static GField clamp_selection(const GField &selection)
void search_link_ops_for_tool_node(GatherLinkSearchOpParams &params)
PropertyRNA * RNA_def_node_enum(StructRNA *srna, const char *identifier, const char *ui_name, const char *ui_description, const EnumPropertyItem *static_items, const EnumRNAAccessors accessors, std::optional< int > default_value, const EnumPropertyItemFunc item_func, const bool allow_animation)
bool check_tool_context_and_error(GeoNodeExecParams &params)
void geo_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
GPU_SHADER_INTERFACE_INFO(overlay_edit_curve_handle_iface, "vert").flat(Type pos vertex_in(1, Type::UINT, "data") .vertex_out(overlay_edit_curve_handle_iface) .geometry_layout(PrimitiveIn Frequency::GEOMETRY storage_buf(1, Qualifier::READ, "uint", "data[]", Frequency::GEOMETRY) .push_constant(Type Frequency::GEOMETRY selection[]
const EnumPropertyItem rna_enum_attribute_domain_point_edge_face_curve_items[]
signed short int16_t
Definition stdint.h:76
StructRNA * srna
Definition RNA_types.hh:780
Defines a node type.
Definition BKE_node.hh:218
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:267
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:339
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:238
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
Definition BKE_node.hh:363
NodeDeclareFunction declare
Definition BKE_node.hh:347
PointerRNA * ptr
Definition wm_files.cc:4126