Blender V4.3
node_geo_tool_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
6
8
10
12{
13 b.add_output<decl::Bool>("Boolean", "Selection")
14 .field_source()
15 .description("The selection of each element as a true or false value");
16 b.add_output<decl::Float>("Float").field_source().description(
17 "The selection of each element as a floating point value");
18}
19
20static const void *true_value(const eCustomDataType data_type)
21{
22 switch (data_type) {
23 case CD_PROP_BOOL: {
24 static const bool value = true;
25 return &value;
26 }
27 case CD_PROP_FLOAT: {
28 static const float value = 1.0f;
29 return &value;
30 }
31 default: {
33 return nullptr;
34 }
35 }
36}
37
38static const void *false_value(const eCustomDataType data_type)
39{
40 switch (data_type) {
41 case CD_PROP_BOOL: {
42 static const bool value = false;
43 return &value;
44 }
45 case CD_PROP_FLOAT: {
46 static const float value = 0.0f;
47 return &value;
48 }
49 default: {
51 return nullptr;
52 }
53 }
54}
55
56static StringRef mesh_selection_name(const AttrDomain domain)
57{
58 switch (domain) {
59 case AttrDomain::Point:
60 return ".select_vert";
61 case AttrDomain::Edge:
62 return ".select_edge";
63 case AttrDomain::Face:
64 case AttrDomain::Corner:
65 return ".select_poly";
66 default:
68 return "";
69 }
70}
71
73 public:
75 : bke::GeometryFieldInput(*bke::custom_data_type_to_cpp_type(data_type), "Edit Selection")
76 {
78 }
79
81 const IndexMask & /*mask*/) const
82 {
83 const AttrDomain domain = context.domain();
85 const AttributeAccessor attributes = *context.attributes();
86 switch (context.type()) {
89 return *attributes.lookup_or_default(
90 ".selection", domain, data_type, true_value(data_type));
92 return *attributes.lookup_or_default(
93 mesh_selection_name(domain), domain, data_type, false_value(data_type));
94 default:
95 return {};
96 }
97 }
98};
99
101 public:
103 : bke::GeometryFieldInput(*bke::custom_data_type_to_cpp_type(data_type), "Sculpt Selection")
104 {
106 }
107
109 const IndexMask &mask) const final
110 {
111 const AttrDomain domain = context.domain();
113 const AttributeAccessor attributes = *context.attributes();
114 switch (context.type()) {
117 return *attributes.lookup_or_default(
118 ".selection", domain, data_type, true_value(data_type));
120 const VArraySpan<float> attribute = *attributes.lookup<float>(".sculpt_mask", domain);
121 if (attribute.is_empty()) {
122 return GVArray::ForSingle(*type_, mask.min_array_size(), true_value(data_type));
123 }
124 switch (data_type) {
125 case CD_PROP_BOOL: {
126 Array<bool> selection(mask.min_array_size());
127 mask.foreach_index_optimized<int>(
128 GrainSize(4096), [&](const int i) { selection[i] = attribute[i] < 1.0f; });
129 return VArray<bool>::ForContainer(std::move(selection));
130 }
131 case CD_PROP_FLOAT: {
132 Array<float> selection(mask.min_array_size());
133 mask.foreach_index_optimized<int>(
134 GrainSize(4096), [&](const int i) { selection[i] = 1.0f - attribute[i]; });
135 return VArray<float>::ForContainer(std::move(selection));
136 }
137 default: {
139 return {};
140 }
141 }
142 }
143 default:
144 return {};
145 }
146 }
147};
148
149static GField get_selection_field(const eObjectMode object_mode, const eCustomDataType data_type)
150{
151 switch (object_mode) {
152 case OB_MODE_OBJECT:
154 case OB_MODE_EDIT:
155 return GField(std::make_shared<EditSelectionFieldInput>(data_type));
156 case OB_MODE_SCULPT:
158 return GField(std::make_shared<SculptSelectionFieldInput>(data_type));
159 default:
160 return fn::make_constant_field<bool>(false);
161 }
162}
163
165{
167 return;
168 }
169 const eObjectMode mode = params.user_data()->call_data->operator_data->mode;
170 params.set_output("Selection", get_selection_field(mode, CD_PROP_BOOL));
171 params.set_output("Float", get_selection_field(mode, CD_PROP_FLOAT));
172}
173
174static void node_register()
175{
176 static blender::bke::bNodeType ntype;
177 geo_node_type_base(&ntype, GEO_NODE_TOOL_SELECTION, "Selection", NODE_CLASS_INPUT);
178 ntype.declare = node_declare;
182}
184
185} // namespace blender::nodes::node_geo_tool_selection_cc
#define NODE_CLASS_INPUT
Definition BKE_node.hh:404
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
@ CD_PROP_FLOAT
eObjectMode
@ OB_MODE_EDIT
@ OB_MODE_SCULPT
@ OB_MODE_SCULPT_CURVES
@ OB_MODE_OBJECT
#define NOD_REGISTER_NODE(REGISTER_FUNC)
static GVArray ForSingle(const CPPType &type, int64_t size, const void *value)
static VArray ForContainer(ContainerT container)
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
const CPPType * type_
Definition FN_field.hh:272
GVArray get_varray_for_context(const bke::GeometryFieldContext &context, const IndexMask &) const
GVArray get_varray_for_context(const bke::GeometryFieldContext &context, const IndexMask &mask) const final
local_group_size(16, 16) .push_constant(Type b
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
eCustomDataType cpp_type_to_custom_data_type(const CPPType &type)
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
GField make_constant_field(const CPPType &type, const void *value)
Definition field.cc:533
static const void * false_value(const eCustomDataType data_type)
static void node_declare(NodeDeclarationBuilder &b)
static const void * true_value(const eCustomDataType data_type)
static void node_geo_exec(GeoNodeExecParams params)
static GField get_selection_field(const eObjectMode object_mode, const eCustomDataType data_type)
static StringRef mesh_selection_name(const AttrDomain domain)
void search_link_ops_for_tool_node(GatherLinkSearchOpParams &params)
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[]
Defines a node type.
Definition BKE_node.hh:218
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:339
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
Definition BKE_node.hh:363
NodeDeclareFunction declare
Definition BKE_node.hh:347