Blender  V2.93
NOD_derived_node_tree.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 
28 #include "BLI_function_ref.hh"
29 #include "BLI_vector_set.hh"
30 
31 #include "NOD_node_tree_ref.hh"
32 
33 namespace blender::nodes {
34 
35 class DTreeContext;
36 class DerivedNodeTree;
37 
38 class DNode;
39 class DSocket;
40 class DInputSocket;
41 class DOutputSocket;
42 
50 class DTreeContext {
51  private:
52  /* Null when this context is for the root node group. Otherwise it points to the context one
53  * level up. */
54  DTreeContext *parent_context_;
55  /* Null when this context is for the root node group. Otherwise it points to the group node in
56  * the parent node group that contains this context. */
57  const NodeRef *parent_node_;
58  /* The current node tree. */
59  const NodeTreeRef *tree_;
60  /* All the children contexts of this context. */
62  DerivedNodeTree *derived_tree_;
63 
64  friend DerivedNodeTree;
65 
66  public:
67  const NodeTreeRef &tree() const;
68  const DTreeContext *parent_context() const;
69  const NodeRef *parent_node() const;
70  const DTreeContext *child_context(const NodeRef &node) const;
71  const DerivedNodeTree &derived_tree() const;
72  bool is_root() const;
73 };
74 
75 /* A (nullable) reference to a node and the context it is in. It is unique within an entire nested
76  * node group hierarchy. This type is small and can be passed around by value. */
77 class DNode {
78  private:
79  const DTreeContext *context_ = nullptr;
80  const NodeRef *node_ref_ = nullptr;
81 
82  public:
83  DNode() = default;
84  DNode(const DTreeContext *context, const NodeRef *node);
85 
86  const DTreeContext *context() const;
87  const NodeRef *node_ref() const;
88  const NodeRef *operator->() const;
89 
90  friend bool operator==(const DNode &a, const DNode &b);
91  friend bool operator!=(const DNode &a, const DNode &b);
92  operator bool() const;
93 
94  uint64_t hash() const;
95 };
96 
97 /* A (nullable) reference to a socket and the context it is in. It is unique within an entire
98  * nested node group hierarchy. This type is small and can be passed around by value.
99  *
100  * A #DSocket can represent an input or an output socket. If the type of a socket is known at
101  * compile time is is preferable to use #DInputSocket or #DOutputSocket instead. */
102 class DSocket {
103  protected:
104  const DTreeContext *context_ = nullptr;
105  const SocketRef *socket_ref_ = nullptr;
106 
107  public:
108  DSocket() = default;
109  DSocket(const DTreeContext *context, const SocketRef *socket);
110  DSocket(const DInputSocket &input_socket);
111  DSocket(const DOutputSocket &output_socket);
112 
113  const DTreeContext *context() const;
114  const SocketRef *socket_ref() const;
115  const SocketRef *operator->() const;
116 
117  friend bool operator==(const DSocket &a, const DSocket &b);
118  friend bool operator!=(const DSocket &a, const DSocket &b);
119  operator bool() const;
120 
121  uint64_t hash() const;
122 
123  DNode node() const;
124 };
125 
126 /* A (nullable) reference to an input socket and the context it is in. */
127 class DInputSocket : public DSocket {
128  public:
129  DInputSocket() = default;
130  DInputSocket(const DTreeContext *context, const InputSocketRef *socket);
131  explicit DInputSocket(const DSocket &base_socket);
132 
133  const InputSocketRef *socket_ref() const;
134  const InputSocketRef *operator->() const;
135 
138 
139  void foreach_origin_socket(FunctionRef<void(DSocket)> origin_fn) const;
140 };
141 
142 /* A (nullable) reference to an output socket and the context it is in. */
143 class DOutputSocket : public DSocket {
144  public:
145  DOutputSocket() = default;
146  DOutputSocket(const DTreeContext *context, const OutputSocketRef *socket);
147  explicit DOutputSocket(const DSocket &base_socket);
148 
149  const OutputSocketRef *socket_ref() const;
150  const OutputSocketRef *operator->() const;
151 
154 
155  void foreach_target_socket(FunctionRef<void(DInputSocket)> target_fn,
156  FunctionRef<void(DSocket)> skipped_fn) const;
157 };
158 
160  private:
161  LinearAllocator<> allocator_;
162  DTreeContext *root_context_;
163  VectorSet<const NodeTreeRef *> used_node_tree_refs_;
164 
165  public:
166  DerivedNodeTree(bNodeTree &btree, NodeTreeRefMap &node_tree_refs);
168 
169  const DTreeContext &root_context() const;
171 
172  bool has_link_cycles() const;
173  bool has_undefined_nodes_or_sockets() const;
174  void foreach_node(FunctionRef<void(DNode)> callback) const;
175 
176  std::string to_dot() const;
177 
178  private:
179  DTreeContext &construct_context_recursively(DTreeContext *parent_context,
180  const NodeRef *parent_node,
181  bNodeTree &btree,
182  NodeTreeRefMap &node_tree_refs);
183  void destruct_context_recursively(DTreeContext *context);
184 
185  void foreach_node_in_context_recursive(const DTreeContext &context,
186  FunctionRef<void(DNode)> callback) const;
187 };
188 
189 namespace derived_node_tree_types {
190 using namespace node_tree_ref_types;
192 using nodes::DInputSocket;
193 using nodes::DNode;
195 using nodes::DSocket;
196 using nodes::DTreeContext;
197 } // namespace derived_node_tree_types
198 
199 /* --------------------------------------------------------------------
200  * DTreeContext inline methods.
201  */
202 
203 inline const NodeTreeRef &DTreeContext::tree() const
204 {
205  return *tree_;
206 }
207 
209 {
210  return parent_context_;
211 }
212 
213 inline const NodeRef *DTreeContext::parent_node() const
214 {
215  return parent_node_;
216 }
217 
219 {
220  return children_.lookup_default(&node, nullptr);
221 }
222 
224 {
225  return *derived_tree_;
226 }
227 
228 inline bool DTreeContext::is_root() const
229 {
230  return parent_context_ == nullptr;
231 }
232 
233 /* --------------------------------------------------------------------
234  * DNode inline methods.
235  */
236 
237 inline DNode::DNode(const DTreeContext *context, const NodeRef *node_ref)
238  : context_(context), node_ref_(node_ref)
239 {
240  BLI_assert(node_ref == nullptr || &node_ref->tree() == &context->tree());
241 }
242 
243 inline const DTreeContext *DNode::context() const
244 {
245  return context_;
246 }
247 
248 inline const NodeRef *DNode::node_ref() const
249 {
250  return node_ref_;
251 }
252 
253 inline bool operator==(const DNode &a, const DNode &b)
254 {
255  return a.context_ == b.context_ && a.node_ref_ == b.node_ref_;
256 }
257 
258 inline bool operator!=(const DNode &a, const DNode &b)
259 {
260  return !(a == b);
261 }
262 
263 inline DNode::operator bool() const
264 {
265  return node_ref_ != nullptr;
266 }
267 
268 inline const NodeRef *DNode::operator->() const
269 {
270  return node_ref_;
271 }
272 
273 inline uint64_t DNode::hash() const
274 {
275  return get_default_hash_2(context_, node_ref_);
276 }
277 
278 /* --------------------------------------------------------------------
279  * DSocket inline methods.
280  */
281 
282 inline DSocket::DSocket(const DTreeContext *context, const SocketRef *socket_ref)
283  : context_(context), socket_ref_(socket_ref)
284 {
285  BLI_assert(socket_ref == nullptr || &socket_ref->tree() == &context->tree());
286 }
287 
288 inline DSocket::DSocket(const DInputSocket &input_socket)
289  : DSocket(input_socket.context_, input_socket.socket_ref_)
290 {
291 }
292 
293 inline DSocket::DSocket(const DOutputSocket &output_socket)
294  : DSocket(output_socket.context_, output_socket.socket_ref_)
295 {
296 }
297 
298 inline const DTreeContext *DSocket::context() const
299 {
300  return context_;
301 }
302 
303 inline const SocketRef *DSocket::socket_ref() const
304 {
305  return socket_ref_;
306 }
307 
308 inline bool operator==(const DSocket &a, const DSocket &b)
309 {
310  return a.context_ == b.context_ && a.socket_ref_ == b.socket_ref_;
311 }
312 
313 inline bool operator!=(const DSocket &a, const DSocket &b)
314 {
315  return !(a == b);
316 }
317 
318 inline DSocket::operator bool() const
319 {
320  return socket_ref_ != nullptr;
321 }
322 
323 inline const SocketRef *DSocket::operator->() const
324 {
325  return socket_ref_;
326 }
327 
328 inline uint64_t DSocket::hash() const
329 {
331 }
332 
333 inline DNode DSocket::node() const
334 {
335  BLI_assert(socket_ref_ != nullptr);
336  return {context_, &socket_ref_->node()};
337 }
338 
339 /* --------------------------------------------------------------------
340  * DInputSocket inline methods.
341  */
342 
344  : DSocket(context, socket_ref)
345 {
346 }
347 
348 inline DInputSocket::DInputSocket(const DSocket &base_socket) : DSocket(base_socket)
349 {
350  BLI_assert(base_socket->is_input());
351 }
352 
354 {
355  return (const InputSocketRef *)socket_ref_;
356 }
357 
359 {
360  return (const InputSocketRef *)socket_ref_;
361 }
362 
363 /* --------------------------------------------------------------------
364  * DOutputSocket inline methods.
365  */
366 
368  : DSocket(context, socket_ref)
369 {
370 }
371 
372 inline DOutputSocket::DOutputSocket(const DSocket &base_socket) : DSocket(base_socket)
373 {
374  BLI_assert(base_socket->is_output());
375 }
376 
378 {
379  return (const OutputSocketRef *)socket_ref_;
380 }
381 
383 {
384  return (const OutputSocketRef *)socket_ref_;
385 }
386 
387 /* --------------------------------------------------------------------
388  * DerivedNodeTree inline methods.
389  */
390 
392 {
393  return *root_context_;
394 }
395 
397 {
398  return used_node_tree_refs_;
399 }
400 
401 } // namespace blender::nodes
#define BLI_assert(a)
Definition: BLI_assert.h:58
void foreach_origin_socket(FunctionRef< void(DSocket)> origin_fn) const
const InputSocketRef * operator->() const
const InputSocketRef * socket_ref() const
DOutputSocket get_corresponding_group_node_output() const
Vector< DOutputSocket, 4 > get_corresponding_group_input_sockets() const
const DTreeContext * context() const
const NodeRef * operator->() const
friend bool operator==(const DNode &a, const DNode &b)
const NodeRef * node_ref() const
friend bool operator!=(const DNode &a, const DNode &b)
void foreach_target_socket(FunctionRef< void(DInputSocket)> target_fn, FunctionRef< void(DSocket)> skipped_fn) const
DInputSocket get_corresponding_group_node_input() const
DInputSocket get_active_corresponding_group_output_socket() const
const OutputSocketRef * operator->() const
const OutputSocketRef * socket_ref() const
const SocketRef * socket_ref() const
const DTreeContext * context() const
const SocketRef * operator->() const
const DTreeContext * context_
friend bool operator==(const DSocket &a, const DSocket &b)
friend bool operator!=(const DSocket &a, const DSocket &b)
const DTreeContext * parent_context() const
const DTreeContext * child_context(const NodeRef &node) const
const NodeRef * parent_node() const
const DerivedNodeTree & derived_tree() const
const NodeTreeRef & tree() const
Span< const NodeTreeRef * > used_node_tree_refs() const
DerivedNodeTree(bNodeTree &btree, NodeTreeRefMap &node_tree_refs)
const DTreeContext & root_context() const
void foreach_node(FunctionRef< void(DNode)> callback) const
const NodeTreeRef & tree() const
const NodeRef & node() const
const NodeTreeRef & tree() const
OperationNode * node
DEGForeachIDComponentCallback callback
static unsigned a[3]
Definition: RandGen.cpp:92
bool operator!=(const DNode &a, const DNode &b)
bool operator==(const DNode &a, const DNode &b)
uint64_t get_default_hash_2(const T1 &v1, const T2 &v2)
Definition: BLI_hash.hh:214
struct SELECTID_Context context
Definition: select_engine.c:47
unsigned __int64 uint64_t
Definition: stdint.h:93