Blender  V2.93
NOD_node_tree_multi_function.hh
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #pragma once
18 
27 
28 #include "NOD_derived_node_tree.hh"
29 #include "NOD_type_callbacks.hh"
30 
31 #include "BLI_multi_value_map.hh"
32 #include "BLI_resource_scope.hh"
33 
34 namespace blender::nodes {
35 
42  private:
49  const DerivedNodeTree &tree_;
50  fn::MFNetwork &network_;
51  MultiValueMap<DSocket, fn::MFSocket *> sockets_by_dsocket_;
52 
53  public:
55  : tree_(tree), network_(network)
56  {
57  }
58 
59  const DerivedNodeTree &tree() const
60  {
61  return tree_;
62  }
63 
64  const fn::MFNetwork &network() const
65  {
66  return network_;
67  }
68 
70  {
71  return network_;
72  }
73 
74  void add(const DSocket &dsocket, fn::MFSocket &socket)
75  {
76  BLI_assert(dsocket->is_input() == socket.is_input());
77  BLI_assert(dsocket->is_input() || sockets_by_dsocket_.lookup(dsocket).is_empty());
78  sockets_by_dsocket_.add(dsocket, &socket);
79  }
80 
81  void add(const DInputSocket &dsocket, fn::MFInputSocket &socket)
82  {
83  sockets_by_dsocket_.add(dsocket, &socket);
84  }
85 
86  void add(const DOutputSocket &dsocket, fn::MFOutputSocket &socket)
87  {
88  /* There can be at most one matching output socket. */
89  BLI_assert(sockets_by_dsocket_.lookup(dsocket).is_empty());
90  sockets_by_dsocket_.add(dsocket, &socket);
91  }
92 
93  void add(const DTreeContext &context,
96  {
97  assert_same_size(dsockets, sockets);
98  for (int i : dsockets.index_range()) {
99  this->add(DInputSocket(&context, dsockets[i]), *sockets[i]);
100  }
101  }
102 
103  void add(const DTreeContext &context,
106  {
107  assert_same_size(dsockets, sockets);
108  for (int i : dsockets.index_range()) {
109  this->add(DOutputSocket(&context, dsockets[i]), *sockets[i]);
110  }
111  }
112 
113  void add_try_match(const DNode &dnode, fn::MFNode &node)
114  {
115  this->add_try_match(*dnode.context(),
116  dnode->inputs().cast<const SocketRef *>(),
117  node.inputs().cast<fn::MFSocket *>());
118  this->add_try_match(*dnode.context(),
119  dnode->outputs().cast<const SocketRef *>(),
120  node.outputs().cast<fn::MFSocket *>());
121  }
122 
126  {
127  this->add_try_match(
128  context, dsockets.cast<const SocketRef *>(), sockets.cast<fn::MFSocket *>());
129  }
130 
134  {
135  this->add_try_match(
136  context, dsockets.cast<const SocketRef *>(), sockets.cast<fn::MFSocket *>());
137  }
138 
140  Span<const SocketRef *> dsockets,
141  Span<fn::MFSocket *> sockets)
142  {
143  int used_sockets = 0;
144  for (const SocketRef *dsocket : dsockets) {
145  if (!dsocket->is_available()) {
146  continue;
147  }
148  if (!socket_is_mf_data_socket(*dsocket->typeinfo())) {
149  continue;
150  }
151  fn::MFSocket *socket = sockets[used_sockets];
152  this->add(DSocket(&context, dsocket), *socket);
153  used_sockets++;
154  }
155  }
156 
158  {
159  return sockets_by_dsocket_.lookup(dsocket)[0]->as_output();
160  }
161 
163  {
164  return sockets_by_dsocket_.lookup(dsocket).cast<fn::MFInputSocket *>();
165  }
166 
168  {
169  Span<fn::MFInputSocket *> sockets = this->lookup(dsocket);
170  BLI_assert(sockets.size() == 1);
171  fn::MFInputSocket &socket = *sockets[0];
172  BLI_assert(socket.node().is_dummy());
173  return socket;
174  }
175 
177  {
178  fn::MFOutputSocket &socket = this->lookup(dsocket);
179  BLI_assert(socket.node().is_dummy());
180  return socket;
181  }
182 
183  bool is_mapped(const DSocket &dsocket) const
184  {
185  return !sockets_by_dsocket_.lookup(dsocket).is_empty();
186  }
187 };
188 
197 };
198 
200  protected:
202 
203  public:
205  {
206  }
207 
212  {
213  return common_.network;
214  }
215 
220  {
221  return common_.network_map;
222  }
223 
229  {
230  return common_.scope;
231  }
232 
236  template<typename T, typename... Args> T &construct_fn(Args &&... args)
237  {
238  BLI_STATIC_ASSERT((std::is_base_of_v<fn::MultiFunction, T>), "");
239  void *buffer = common_.scope.linear_allocator().allocate(sizeof(T), alignof(T));
240  T *fn = new (buffer) T(std::forward<Args>(args)...);
241  common_.scope.add(destruct_ptr<T>(fn), fn->name().c_str());
242  return *fn;
243  }
244 };
245 
251  private:
252  bNodeSocket *bsocket_;
253  fn::MFOutputSocket *built_socket_ = nullptr;
254 
255  public:
257  : MFNetworkBuilderBase(common), bsocket_(dsocket->bsocket())
258  {
259  }
260 
265  {
266  return *bsocket_;
267  }
268 
272  template<typename T> T *socket_default_value()
273  {
274  return static_cast<T *>(bsocket_->default_value);
275  }
276 
280  template<typename T> void set_constant_value(T value)
281  {
282  this->construct_generator_fn<fn::CustomMF_Constant<T>>(std::move(value));
283  }
284  void set_constant_value(const CPPType &type, const void *value)
285  {
286  /* The value has live as long as the generated mf network. */
287  this->construct_generator_fn<fn::CustomMF_GenericConstant>(type, value);
288  }
289 
290  template<typename T, typename... Args> void construct_generator_fn(Args &&... args)
291  {
292  const fn::MultiFunction &fn = this->construct_fn<T>(std::forward<Args>(args)...);
293  this->set_generator_fn(fn);
294  }
295 
300  {
302  this->set_socket(node.output(0));
303  }
304 
309  {
310  built_socket_ = &socket;
311  }
312 
314  {
315  return built_socket_;
316  }
317 };
318 
324  private:
325  DNode dnode_;
326 
327  public:
329  : MFNetworkBuilderBase(common), dnode_(dnode)
330  {
331  }
332 
337  template<typename T, typename... Args> T &construct_and_set_matching_fn(Args &&... args)
338  {
339  T &function = this->construct_fn<T>(std::forward<Args>(args)...);
340  this->set_matching_fn(function);
341  return function;
342  }
343 
345  {
346  return this->get_default_fn("Not Implemented (" + dnode_->name() + ")");
347  }
348 
350 
351  const void set_not_implemented()
352  {
354  }
355 
360  void set_matching_fn(const fn::MultiFunction &function)
361  {
364  }
365 
370  {
371  return *dnode_->bnode();
372  }
373 
377  const DNode &dnode() const
378  {
379  return dnode_;
380  }
381 };
382 
383 MFNetworkTreeMap insert_node_tree_into_mf_network(fn::MFNetwork &network,
384  const DerivedNodeTree &tree,
385  ResourceScope &scope);
386 
389 
390 } // namespace blender::nodes
#define BLI_STATIC_ASSERT(a, msg)
Definition: BLI_assert.h:86
#define BLI_assert(a)
Definition: BLI_assert.h:58
_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
void * allocate(const int64_t size, const int64_t alignment)
Span< Value > lookup(const Key &key) const
void add(const Key &key, const Value &value)
LinearAllocator & linear_allocator()
T * add(std::unique_ptr< T > resource, const char *name)
constexpr int64_t size() const
Definition: BLI_span.hh:254
constexpr Span< NewT > cast() const
Definition: BLI_span.hh:422
constexpr IndexRange index_range() const
Definition: BLI_span.hh:414
MFFunctionNode & add_function(const MultiFunction &function)
MFOutputSocket & output(int index)
const DTreeContext * context() const
MFNetworkBuilderBase(CommonMFNetworkBuilderData &common)
void add(const DSocket &dsocket, fn::MFSocket &socket)
void add_try_match(const DTreeContext &context, Span< const OutputSocketRef * > dsockets, Span< fn::MFOutputSocket * > sockets)
bool is_mapped(const DSocket &dsocket) const
MFNetworkTreeMap(const DerivedNodeTree &tree, fn::MFNetwork &network)
fn::MFOutputSocket & lookup_dummy(const DOutputSocket &dsocket)
fn::MFOutputSocket & lookup(const DOutputSocket &dsocket)
void add(const DTreeContext &context, Span< const OutputSocketRef * > dsockets, Span< fn::MFOutputSocket * > sockets)
void add(const DTreeContext &context, Span< const InputSocketRef * > dsockets, Span< fn::MFInputSocket * > sockets)
void add_try_match(const DTreeContext &context, Span< const SocketRef * > dsockets, Span< fn::MFSocket * > sockets)
fn::MFInputSocket & lookup_dummy(const DInputSocket &dsocket)
const DerivedNodeTree & tree() const
void add(const DInputSocket &dsocket, fn::MFInputSocket &socket)
Span< fn::MFInputSocket * > lookup(const DInputSocket &dsocket)
void add_try_match(const DTreeContext &context, Span< const InputSocketRef * > dsockets, Span< fn::MFInputSocket * > sockets)
void add_try_match(const DNode &dnode, fn::MFNode &node)
void add(const DOutputSocket &dsocket, fn::MFOutputSocket &socket)
NodeMFNetworkBuilder(CommonMFNetworkBuilderData &common, DNode dnode)
const fn::MultiFunction & get_default_fn(StringRef name)
void set_matching_fn(const fn::MultiFunction &function)
Span< const InputSocketRef * > inputs() const
Span< const OutputSocketRef * > outputs() const
StringRefNull name() const
void set_constant_value(const CPPType &type, const void *value)
void set_generator_fn(const fn::MultiFunction &fn)
SocketMFNetworkBuilder(CommonMFNetworkBuilderData &common, const DSocket &dsocket)
OperationNode * node
void * tree
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
#define T
bool socket_is_mf_data_socket(const bNodeSocketType &stype)
MultiFunctionByNode get_multi_function_per_node(const DerivedNodeTree &tree, ResourceScope &scope)
MFNetworkTreeMap insert_node_tree_into_mf_network(fn::MFNetwork &network, const DerivedNodeTree &tree, ResourceScope &scope)
constexpr void assert_same_size(const T1 &v1, const T2 &v2)
Definition: BLI_span.hh:715
std::unique_ptr< T, DestructValueAtAddress< T > > destruct_ptr
struct SELECTID_Context context
Definition: select_engine.c:47
void * default_value