Blender V4.3
NOD_geometry_exec.hh
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#pragma once
6
7#include "BLI_color.hh"
9
10#include "FN_field.hh"
11#include "FN_lazy_function.hh"
13
15#include "BKE_attribute_math.hh"
17#include "BKE_geometry_set.hh"
20
21#include "DNA_node_types.h"
22
25
26namespace blender::nodes {
27
28using bke::AttrDomain;
29using bke::AttributeAccessor;
30using bke::AttributeFieldInput;
31using bke::AttributeFilter;
32using bke::AttributeIter;
33using bke::AttributeKind;
34using bke::AttributeMetaData;
35using bke::AttributeReader;
36using bke::AttributeWriter;
37using bke::CurveComponent;
38using bke::GAttributeReader;
39using bke::GAttributeWriter;
40using bke::GeometryComponent;
41using bke::GeometryComponentEditData;
42using bke::GeometrySet;
43using bke::GreasePencilComponent;
44using bke::GSpanAttributeWriter;
45using bke::InstancesComponent;
46using bke::MeshComponent;
47using bke::MutableAttributeAccessor;
48using bke::PointCloudComponent;
49using bke::SocketValueVariant;
50using bke::SpanAttributeWriter;
51using bke::VolumeComponent;
52using fn::Field;
53using fn::FieldContext;
54using fn::FieldEvaluator;
55using fn::FieldInput;
56using fn::FieldOperation;
57using fn::GField;
60
62 private:
64
65 public:
67
68 Result filter(StringRef attribute_name) const override;
69};
70
72 private:
73 const bNode &node_;
74 lf::Params &params_;
75 const lf::Context &lf_context_;
76 const Span<int> lf_input_for_output_bsocket_usage_;
77 const Span<int> lf_input_for_attribute_propagation_to_output_;
78 const FunctionRef<std::string(int)> get_output_attribute_id_;
79
80 public:
83 const lf::Context &lf_context,
84 const Span<int> lf_input_for_output_bsocket_usage,
85 const Span<int> lf_input_for_attribute_propagation_to_output,
86 const FunctionRef<std::string(int)> get_output_attribute_id)
87 : node_(node),
88 params_(params),
89 lf_context_(lf_context),
90 lf_input_for_output_bsocket_usage_(lf_input_for_output_bsocket_usage),
91 lf_input_for_attribute_propagation_to_output_(
92 lf_input_for_attribute_propagation_to_output),
93 get_output_attribute_id_(get_output_attribute_id)
94 {
95 }
96
97 template<typename T>
98 static inline constexpr bool is_field_base_type_v = is_same_any_v<T,
99 float,
100 int,
101 bool,
103 float3,
104 std::string,
106 float4x4>;
107
108 template<typename T>
109 static inline constexpr bool stored_as_SocketValueVariant_v =
110 is_field_base_type_v<T> || fn::is_field_v<T> || bke::is_VolumeGrid_v<T> ||
112
118 template<typename T> T extract_input(StringRef identifier)
119 {
120 if constexpr (stored_as_SocketValueVariant_v<T>) {
121 SocketValueVariant value_variant = this->extract_input<SocketValueVariant>(identifier);
122 return value_variant.extract<T>();
123 }
124 else {
125#ifndef NDEBUG
126 this->check_input_access(identifier, &CPPType::get<T>());
127#endif
128 const int index = this->get_input_index(identifier);
129 T value = params_.extract_input<T>(index);
130 if constexpr (std::is_same_v<T, GeometrySet>) {
131 this->check_input_geometry_set(identifier, value);
132 }
133 if constexpr (std::is_same_v<T, SocketValueVariant>) {
134 BLI_assert(value.valid_for_socket(
135 eNodeSocketDatatype(node_.input_by_identifier(identifier).type)));
136 }
137 return value;
138 }
139 }
140
141 void check_input_geometry_set(StringRef identifier, const GeometrySet &geometry_set) const;
142 void check_output_geometry_set(const GeometrySet &geometry_set) const;
143
147 template<typename T> T get_input(StringRef identifier) const
148 {
149 if constexpr (stored_as_SocketValueVariant_v<T>) {
150 auto value_variant = this->get_input<SocketValueVariant>(identifier);
151 return value_variant.extract<T>();
152 }
153 else {
154#ifndef NDEBUG
155 this->check_input_access(identifier, &CPPType::get<T>());
156#endif
157 const int index = this->get_input_index(identifier);
158 const T &value = params_.get_input<T>(index);
159 if constexpr (std::is_same_v<T, GeometrySet>) {
160 this->check_input_geometry_set(identifier, value);
161 }
162 if constexpr (std::is_same_v<T, SocketValueVariant>) {
163 BLI_assert(value.valid_for_socket(
164 eNodeSocketDatatype(node_.input_by_identifier(identifier).type)));
165 }
166 return value;
167 }
168 }
169
173 template<typename T> void set_output(StringRef identifier, T &&value)
174 {
175 using StoredT = std::decay_t<T>;
177 SocketValueVariant value_variant(std::forward<T>(value));
178 this->set_output(identifier, std::move(value_variant));
179 }
180 else {
181#ifndef NDEBUG
182 const CPPType &type = CPPType::get<StoredT>();
183 this->check_output_access(identifier, type);
184 if constexpr (std::is_same_v<StoredT, SocketValueVariant>) {
185 BLI_assert(value.valid_for_socket(
186 eNodeSocketDatatype(node_.output_by_identifier(identifier).type)));
187 }
188#endif
189 if constexpr (std::is_same_v<StoredT, GeometrySet>) {
190 this->check_output_geometry_set(value);
191 }
192 const int index = this->get_output_index(identifier);
193 params_.set_output(index, std::forward<T>(value));
194 }
195 }
196
201
206 {
207 const int index = this->get_input_index(identifier);
208 params_.set_input_unused(index);
209 }
210
214 bool output_is_required(StringRef identifier) const
215 {
216 const int index = this->get_output_index(identifier);
217 return params_.get_output_usage(index) != lf::ValueUsage::Unused;
218 }
219
223 const bNode &node() const
224 {
225 return node_;
226 }
227
228 const Object *self_object() const
229 {
230 if (const auto *data = this->user_data()) {
231 return data->call_data->self_object();
232 }
233 return nullptr;
234 }
235
236 const Depsgraph *depsgraph() const
237 {
238 if (const auto *data = this->user_data()) {
239 if (data->call_data->modifier_data) {
240 return data->call_data->modifier_data->depsgraph;
241 }
242 if (data->call_data->operator_data) {
243 return data->call_data->operator_data->depsgraphs->active;
244 }
245 }
246 return nullptr;
247 }
248
249 Main *bmain() const;
250
252 {
253 return static_cast<GeoNodesLFUserData *>(lf_context_.user_data);
254 }
255
257 {
258 return static_cast<GeoNodesLFLocalUserData *>(lf_context_.local_user_data);
259 }
260
265 void error_message_add(const NodeWarningType type, StringRef message) const;
266
268
269 void used_named_attribute(StringRef attribute_name, NamedAttributeUsage usage);
270
275 {
276 const int lf_index =
277 lf_input_for_output_bsocket_usage_[node_.output_by_identifier(output_identifier)
278 .index_in_all_outputs()];
279 return params_.get_input<bool>(lf_index);
280 }
281
287 const StringRef output_identifier, const bool force_create = false)
288 {
289 if (!this->anonymous_attribute_output_is_required(output_identifier) && !force_create) {
290 return std::nullopt;
291 }
292 const bNodeSocket &output_socket = node_.output_by_identifier(output_identifier);
293 return get_output_attribute_id_(output_socket.index());
294 }
295
300 {
301 const int lf_index =
302 lf_input_for_attribute_propagation_to_output_[node_.output_by_identifier(output_identifier)
303 .index_in_all_outputs()];
305 lf_index);
306 return NodeAttributeFilter(set);
307 }
308
309 private:
310 /* Utilities for detecting common errors at when using this class. */
311 void check_input_access(StringRef identifier, const CPPType *requested_type = nullptr) const;
312 void check_output_access(StringRef identifier, const CPPType &value_type) const;
313
314 /* Find the active socket with the input name (not the identifier). */
315 const bNodeSocket *find_available_socket(const StringRef name) const;
316
317 int get_input_index(const StringRef identifier) const
318 {
319 int counter = 0;
320 for (const bNodeSocket *socket : node_.input_sockets()) {
321 if (!socket->is_available()) {
322 continue;
323 }
324 if (socket->identifier == identifier) {
325 return counter;
326 }
327 counter++;
328 }
330 return -1;
331 }
332
333 int get_output_index(const StringRef identifier) const
334 {
335 int counter = 0;
336 for (const bNodeSocket *socket : node_.output_sockets()) {
337 if (!socket->is_available()) {
338 continue;
339 }
340 if (socket->identifier == identifier) {
341 return counter;
342 }
343 counter++;
344 }
346 return -1;
347 }
348};
349
350} // namespace blender::nodes
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
eNodeSocketDatatype
static const CPPType & get()
void set_output(int index, T &&value)
ValueUsage get_output_usage(int index) const
T extract_input(StringRef identifier)
geo_eval_log::GeoTreeLogger * get_local_tree_logger() const
void error_message_add(const NodeWarningType type, StringRef message) const
void set_output(StringRef identifier, T &&value)
void set_input_unused(StringRef identifier)
void check_output_geometry_set(const GeometrySet &geometry_set) const
bool output_is_required(StringRef identifier) const
GeoNodeExecParams(const bNode &node, lf::Params &params, const lf::Context &lf_context, const Span< int > lf_input_for_output_bsocket_usage, const Span< int > lf_input_for_attribute_propagation_to_output, const FunctionRef< std::string(int)> get_output_attribute_id)
GeoNodesLFLocalUserData * local_user_data() const
T get_input(StringRef identifier) const
void check_input_geometry_set(StringRef identifier, const GeometrySet &geometry_set) const
bool anonymous_attribute_output_is_required(const StringRef output_identifier)
void used_named_attribute(StringRef attribute_name, NamedAttributeUsage usage)
std::optional< std::string > get_output_anonymous_attribute_id_if_needed(const StringRef output_identifier, const bool force_create=false)
GeoNodesLFUserData * user_data() const
NodeAttributeFilter get_attribute_filter(const StringRef output_identifier) const
const Depsgraph * depsgraph() const
static constexpr bool is_field_base_type_v
static constexpr bool stored_as_SocketValueVariant_v
Result filter(StringRef attribute_name) const override
NodeAttributeFilter(const bke::AnonymousAttributeSet &set)
draw_view in_light_buf[] float
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]
#define T
static constexpr bool is_field_v
Definition FN_field.hh:217
QuaternionBase< float > Quaternion
constexpr bool is_same_any_v
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
Definition BLI_color.hh:337
VecBase< float, 3 > float3
int16_t type
geo_eval_log::GeoTreeLogger * try_get_tree_logger(const GeoNodesLFUserData &user_data) const