Blender  V3.3
NOD_geometry_exec.hh
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #pragma once
4 
5 #include "FN_field.hh"
7 
8 #include "BKE_geometry_fields.hh"
9 #include "BKE_geometry_set.hh"
10 
11 #include "DNA_node_types.h"
12 
13 #include "NOD_derived_node_tree.hh"
15 
16 struct Depsgraph;
17 struct ModifierData;
18 
19 namespace blender::nodes {
20 
21 using bke::AnonymousAttributeFieldInput;
22 using bke::AttributeAccessor;
23 using bke::AttributeFieldInput;
24 using bke::AttributeIDRef;
25 using bke::AttributeKind;
26 using bke::AttributeMetaData;
27 using bke::AttributeReader;
28 using bke::AttributeWriter;
29 using bke::GAttributeReader;
30 using bke::GAttributeWriter;
31 using bke::GeometryComponentFieldContext;
32 using bke::GeometryFieldInput;
33 using bke::GSpanAttributeWriter;
34 using bke::MutableAttributeAccessor;
35 using bke::SpanAttributeWriter;
38 using fn::Field;
39 using fn::FieldContext;
40 using fn::FieldEvaluator;
41 using fn::FieldInput;
42 using fn::FieldOperation;
43 using fn::GField;
44 using fn::ValueOrField;
47 
53  public:
55  const Object *self_object = nullptr;
56  const ModifierData *modifier = nullptr;
57  Depsgraph *depsgraph = nullptr;
59 
64  virtual bool can_get_input(StringRef identifier) const = 0;
65 
70  virtual bool can_set_output(StringRef identifier) const = 0;
71 
76  virtual GMutablePointer extract_input(StringRef identifier) = 0;
77 
82 
86  virtual GPointer get_input(StringRef identifier) const = 0;
87 
93 
97  virtual void set_output(StringRef identifier, GMutablePointer value) = 0;
98 
99  /* A description for these methods is provided in GeoNodeExecParams. */
100  virtual void set_input_unused(StringRef identifier) = 0;
101  virtual bool output_is_required(StringRef identifier) const = 0;
102  virtual bool lazy_require_input(StringRef identifier) = 0;
103  virtual bool lazy_output_is_required(StringRef identifier) const = 0;
104 
105  virtual void set_default_remaining_outputs() = 0;
106 };
107 
109  private:
110  GeoNodeExecParamsProvider *provider_;
111 
112  public:
113  GeoNodeExecParams(GeoNodeExecParamsProvider &provider) : provider_(&provider)
114  {
115  }
116 
117  template<typename T>
118  static inline constexpr bool is_field_base_type_v =
119  is_same_any_v<T, float, int, bool, ColorGeometry4f, float3, std::string>;
120 
128  {
129 #ifdef DEBUG
130  this->check_input_access(identifier);
131 #endif
132  return provider_->extract_input(identifier);
133  }
134 
140  template<typename T> T extract_input(StringRef identifier)
141  {
142  if constexpr (is_field_base_type_v<T>) {
143  ValueOrField<T> value_or_field = this->extract_input<ValueOrField<T>>(identifier);
144  return value_or_field.as_value();
145  }
146  else if constexpr (fn::is_field_v<T>) {
147  using BaseType = typename T::base_type;
148  ValueOrField<BaseType> value_or_field = this->extract_input<ValueOrField<BaseType>>(
149  identifier);
150  return value_or_field.as_field();
151  }
152  else {
153 #ifdef DEBUG
154  this->check_input_access(identifier, &CPPType::get<T>());
155 #endif
156  GMutablePointer gvalue = this->extract_input(identifier);
157  T value = gvalue.relocate_out<T>();
158  if constexpr (std::is_same_v<T, GeometrySet>) {
159  this->check_input_geometry_set(identifier, value);
160  }
161  return value;
162  }
163  }
164 
165  void check_input_geometry_set(StringRef identifier, const GeometrySet &geometry_set) const;
166  void check_output_geometry_set(const GeometrySet &geometry_set) const;
167 
173  template<typename T> Vector<T> extract_multi_input(StringRef identifier)
174  {
175  Vector<GMutablePointer> gvalues = provider_->extract_multi_input(identifier);
176  Vector<T> values;
177  for (GMutablePointer gvalue : gvalues) {
178  if constexpr (is_field_base_type_v<T>) {
179  const ValueOrField<T> value_or_field = gvalue.relocate_out<ValueOrField<T>>();
180  values.append(value_or_field.as_value());
181  }
182  else {
183  values.append(gvalue.relocate_out<T>());
184  }
185  }
186  return values;
187  }
188 
192  template<typename T> T get_input(StringRef identifier) const
193  {
194  if constexpr (is_field_base_type_v<T>) {
195  ValueOrField<T> value_or_field = this->get_input<ValueOrField<T>>(identifier);
196  return value_or_field.as_value();
197  }
198  else if constexpr (fn::is_field_v<T>) {
199  using BaseType = typename T::base_type;
200  ValueOrField<BaseType> value_or_field = this->get_input<ValueOrField<BaseType>>(identifier);
201  return value_or_field.as_field();
202  }
203  else {
204 #ifdef DEBUG
205  this->check_input_access(identifier, &CPPType::get<T>());
206 #endif
207  GPointer gvalue = provider_->get_input(identifier);
208  BLI_assert(gvalue.is_type<T>());
209  const T &value = *(const T *)gvalue.get();
210  if constexpr (std::is_same_v<T, GeometrySet>) {
211  this->check_input_geometry_set(identifier, value);
212  }
213  return value;
214  }
215  }
216 
220  template<typename T> void set_output(StringRef identifier, T &&value)
221  {
222  using StoredT = std::decay_t<T>;
223  if constexpr (is_field_base_type_v<StoredT>) {
224  this->set_output(identifier, ValueOrField<StoredT>(std::forward<T>(value)));
225  }
226  else if constexpr (fn::is_field_v<StoredT>) {
227  using BaseType = typename StoredT::base_type;
228  this->set_output(identifier, ValueOrField<BaseType>(std::forward<T>(value)));
229  }
230  else {
231  const CPPType &type = CPPType::get<StoredT>();
232 #ifdef DEBUG
233  this->check_output_access(identifier, type);
234 #endif
235  if constexpr (std::is_same_v<StoredT, GeometrySet>) {
236  this->check_output_geometry_set(value);
237  }
238  GMutablePointer gvalue = provider_->alloc_output_value(type);
239  new (gvalue.get()) StoredT(std::forward<T>(value));
240  provider_->set_output(identifier, gvalue);
241  }
242  }
243 
247  void set_input_unused(StringRef identifier)
248  {
249  provider_->set_input_unused(identifier);
250  }
251 
257  bool output_is_required(StringRef identifier) const
258  {
259  return provider_->output_is_required(identifier);
260  }
261 
268  bool lazy_require_input(StringRef identifier)
269  {
270  return provider_->lazy_require_input(identifier);
271  }
272 
279  {
280  return provider_->lazy_output_is_required(identifier);
281  }
282 
286  const bNode &node() const
287  {
288  return *provider_->dnode->bnode();
289  }
290 
291  const Object *self_object() const
292  {
293  return provider_->self_object;
294  }
295 
297  {
298  return provider_->depsgraph;
299  }
300 
305  void error_message_add(const NodeWarningType type, std::string message) const;
306 
307  std::string attribute_producer_name() const;
308 
310 
311  void used_named_attribute(std::string attribute_name, eNamedAttrUsage usage);
312 
313  private:
314  /* Utilities for detecting common errors at when using this class. */
315  void check_input_access(StringRef identifier, const CPPType *requested_type = nullptr) const;
316  void check_output_access(StringRef identifier, const CPPType &value_type) const;
317 
318  /* Find the active socket with the input name (not the identifier). */
319  const bNodeSocket *find_available_socket(const StringRef name) const;
320 };
321 
322 } // namespace blender::nodes
#define BLI_assert(a)
Definition: BLI_assert.h:46
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
const void * get() const
void append(const T &value)
Definition: BLI_vector.hh:433
virtual GMutablePointer alloc_output_value(const CPPType &type)=0
virtual bool lazy_output_is_required(StringRef identifier) const =0
virtual GMutablePointer extract_input(StringRef identifier)=0
geometry_nodes_eval_log::GeoLogger * logger
virtual void set_output(StringRef identifier, GMutablePointer value)=0
virtual bool lazy_require_input(StringRef identifier)=0
virtual GPointer get_input(StringRef identifier) const =0
virtual bool can_get_input(StringRef identifier) const =0
virtual void set_input_unused(StringRef identifier)=0
virtual bool can_set_output(StringRef identifier) const =0
virtual Vector< GMutablePointer > extract_multi_input(StringRef identifier)=0
virtual bool output_is_required(StringRef identifier) const =0
T extract_input(StringRef identifier)
GeoNodeExecParams(GeoNodeExecParamsProvider &provider)
GMutablePointer extract_input(StringRef identifier)
void used_named_attribute(std::string attribute_name, eNamedAttrUsage usage)
Vector< T > extract_multi_input(StringRef identifier)
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
T get_input(StringRef identifier) const
void check_input_geometry_set(StringRef identifier, const GeometrySet &geometry_set) const
static constexpr bool is_field_base_type_v
bool lazy_output_is_required(StringRef identifier)
void error_message_add(const NodeWarningType type, std::string message) const
bool lazy_require_input(StringRef identifier)
#define T
OwnedAnonymousAttributeID< false > WeakAnonymousAttributeID
OwnedAnonymousAttributeID< true > StrongAnonymousAttributeID
Field< T > as_field() const
Definition: FN_field.hh:552