Blender V5.0
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 bke::AttrType data_type)
21{
22 switch (data_type) {
24 static const bool value = true;
25 return &value;
26 }
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 bke::AttrType data_type)
39{
40 switch (data_type) {
42 static const bool value = false;
43 return &value;
44 }
46 static const float value = 0.0f;
47 return &value;
48 }
49 default: {
51 return nullptr;
52 }
53 }
54}
55
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::attribute_type_to_cpp_type(data_type), "Edit Selection")
76 {
78 }
79
81 const IndexMask & /*mask*/) const override
82 {
83 const AttrDomain domain = context.domain();
85 const AttributeAccessor attributes = *context.attributes();
86 switch (context.type()) {
87 case GeometryComponent::Type::Curve:
88 case GeometryComponent::Type::PointCloud:
89 case GeometryComponent::Type::GreasePencil:
90 return *attributes.lookup_or_default(
91 ".selection", domain, data_type, true_value(data_type));
92 case GeometryComponent::Type::Mesh:
93 return *attributes.lookup_or_default(
94 mesh_selection_name(domain), domain, data_type, false_value(data_type));
95 default:
96 return {};
97 }
98 }
99};
100
102 public:
104 : bke::GeometryFieldInput(bke::attribute_type_to_cpp_type(data_type), "Sculpt Selection")
105 {
107 }
108
110 const IndexMask &mask) const final
111 {
112 const AttrDomain domain = context.domain();
114 const AttributeAccessor attributes = *context.attributes();
115 switch (context.type()) {
116 case GeometryComponent::Type::Curve:
117 case GeometryComponent::Type::PointCloud:
118 case GeometryComponent::Type::GreasePencil:
119 return *attributes.lookup_or_default(
120 ".selection", domain, data_type, true_value(data_type));
121 case GeometryComponent::Type::Mesh: {
122 const VArraySpan<float> attribute = *attributes.lookup<float>(".sculpt_mask", domain);
123 if (attribute.is_empty()) {
124 return GVArray::from_single(*type_, mask.min_array_size(), true_value(data_type));
125 }
126 switch (data_type) {
127 case bke::AttrType::Bool: {
128 Array<bool> selection(mask.min_array_size());
129 mask.foreach_index_optimized<int>(
130 GrainSize(4096), [&](const int i) { selection[i] = attribute[i] < 1.0f; });
131 return VArray<bool>::from_container(std::move(selection));
132 }
134 Array<float> selection(mask.min_array_size());
135 mask.foreach_index_optimized<int>(
136 GrainSize(4096), [&](const int i) { selection[i] = 1.0f - attribute[i]; });
137 return VArray<float>::from_container(std::move(selection));
138 }
139 default: {
141 return {};
142 }
143 }
144 }
145 default:
146 return {};
147 }
148 }
149};
150
151static GField get_selection_field(const eObjectMode object_mode, const bke::AttrType data_type)
152{
153 switch (object_mode) {
154 case OB_MODE_OBJECT:
156 true_value(data_type));
157 case OB_MODE_EDIT:
158 return GField(std::make_shared<EditSelectionFieldInput>(data_type));
159 case OB_MODE_SCULPT:
162 return GField(std::make_shared<SculptSelectionFieldInput>(data_type));
165 true_value(data_type));
166 default:
168 false_value(data_type));
169 }
170}
171
173{
175 return;
176 }
177 const eObjectMode mode = params.user_data()->call_data->operator_data->mode;
178 params.set_output("Selection", get_selection_field(mode, bke::AttrType::Bool));
179 params.set_output("Float", get_selection_field(mode, bke::AttrType::Float));
180}
181
182static void node_register()
183{
184 static blender::bke::bNodeType ntype;
185 geo_node_type_base(&ntype, "GeometryNodeToolSelection", GEO_NODE_TOOL_SELECTION);
186 ntype.ui_name = "Selection";
187 ntype.ui_description = "User selection of the edited geometry, for tool execution";
188 ntype.enum_name_legacy = "TOOL_SELECTION";
189 ntype.nclass = NODE_CLASS_INPUT;
190 ntype.declare = node_declare;
194}
196
197} // namespace blender::nodes::node_geo_tool_selection_cc
#define NODE_CLASS_INPUT
Definition BKE_node.hh:447
#define GEO_NODE_TOOL_SELECTION
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define final(a, b, c)
Definition BLI_hash.h:19
eObjectMode
@ OB_MODE_EDIT
@ OB_MODE_SCULPT
@ OB_MODE_SCULPT_CURVES
@ OB_MODE_PAINT_GREASE_PENCIL
@ OB_MODE_SCULPT_GREASE_PENCIL
@ OB_MODE_OBJECT
#define NOD_REGISTER_NODE(REGISTER_FUNC)
static GVArray from_single(const CPPType &type, int64_t size, const void *value)
constexpr bool is_empty() const
Definition BLI_span.hh:260
static VArray from_container(ContainerT container)
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, AttrType data_type, const void *default_value=nullptr) const
GAttributeReader lookup(const StringRef attribute_id) const
const CPPType * type_
Definition FN_field.hh:270
GVArray get_varray_for_context(const bke::GeometryFieldContext &context, const IndexMask &) const override
GVArray get_varray_for_context(const bke::GeometryFieldContext &context, const IndexMask &mask) const final
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
AttrType cpp_type_to_attribute_type(const CPPType &type)
const CPPType & attribute_type_to_cpp_type(AttrType type)
GField make_constant_field(const CPPType &type, const void *value)
Definition field.cc:528
static const void * true_value(const bke::AttrType data_type)
static void node_declare(NodeDeclarationBuilder &b)
static void node_geo_exec(GeoNodeExecParams params)
static GField get_selection_field(const eObjectMode object_mode, const bke::AttrType data_type)
static StringRef mesh_selection_name(const AttrDomain domain)
static const void * false_value(const bke::AttrType data_type)
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, std::string idname, const std::optional< int16_t > legacy_type)
Defines a node type.
Definition BKE_node.hh:238
std::string ui_description
Definition BKE_node.hh:244
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:354
const char * enum_name_legacy
Definition BKE_node.hh:247
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
Definition BKE_node.hh:378
NodeDeclareFunction declare
Definition BKE_node.hh:362
i
Definition text_draw.cc:230