Blender  V3.3
node_socket_declarations.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
5 
6 #include "BKE_node.h"
7 #include "BKE_node_runtime.hh"
8 
9 #include "BLI_math_vector.h"
10 
12 
20 {
21  if (output.output_field_dependency().field_type() == OutputSocketFieldType::FieldSource) {
22  if (input.input_field_type() == InputSocketFieldType::None) {
23  return false;
24  }
25  }
26  return true;
27 }
28 
29 static bool sockets_can_connect(const SocketDeclaration &socket_decl,
30  const bNodeSocket &other_socket)
31 {
32  /* Input sockets cannot connect to input sockets, outputs cannot connect to outputs. */
33  if (socket_decl.in_out() == other_socket.in_out) {
34  return false;
35  }
36 
37  if (other_socket.runtime->declaration) {
38  if (socket_decl.in_out() == SOCK_IN) {
39  if (!field_types_are_compatible(socket_decl, *other_socket.runtime->declaration)) {
40  return false;
41  }
42  }
43  else {
44  if (!field_types_are_compatible(*other_socket.runtime->declaration, socket_decl)) {
45  return false;
46  }
47  }
48  }
49 
50  return true;
51 }
52 
53 static bool basic_types_can_connect(const SocketDeclaration &UNUSED(socket_decl),
54  const bNodeSocket &other_socket)
55 {
56  return ELEM(other_socket.type, SOCK_FLOAT, SOCK_INT, SOCK_BOOLEAN, SOCK_VECTOR, SOCK_RGBA);
57 }
58 
59 static void modify_subtype_except_for_storage(bNodeSocket &socket, int new_subtype)
60 {
61  const char *idname = nodeStaticSocketType(socket.type, new_subtype);
62  BLI_strncpy(socket.idname, idname, sizeof(socket.idname));
63  bNodeSocketType *socktype = nodeSocketTypeFind(idname);
64  socket.typeinfo = socktype;
65 }
66 
67 /* -------------------------------------------------------------------- */
72 {
74  &ntree, &node, in_out_, SOCK_FLOAT, subtype_, identifier_.c_str(), name_.c_str());
75  this->set_common_flags(socket);
77  value.min = soft_min_value_;
78  value.max = soft_max_value_;
79  value.value = default_value_;
80  return socket;
81 }
82 
83 bool Float::matches(const bNodeSocket &socket) const
84 {
85  if (!this->matches_common_data(socket)) {
86  return false;
87  }
88  if (socket.type != SOCK_FLOAT) {
89  return false;
90  }
91  if (socket.typeinfo->subtype != subtype_) {
92  return false;
93  }
95  if (value.min != soft_min_value_) {
96  return false;
97  }
98  if (value.max != soft_max_value_) {
99  return false;
100  }
101  return true;
102 }
103 
104 bool Float::can_connect(const bNodeSocket &socket) const
105 {
106  if (!sockets_can_connect(*this, socket)) {
107  return false;
108  }
109  return basic_types_can_connect(*this, socket);
110 }
111 
113 {
114  if (socket.type != SOCK_FLOAT) {
115  BLI_assert(socket.in_out == in_out_);
116  return this->build(ntree, node);
117  }
118  if (socket.typeinfo->subtype != subtype_) {
119  modify_subtype_except_for_storage(socket, subtype_);
120  }
121  this->set_common_flags(socket);
123  value.min = soft_min_value_;
124  value.max = soft_max_value_;
125  value.subtype = subtype_;
126  return socket;
127 }
128 
131 /* -------------------------------------------------------------------- */
136 {
137  bNodeSocket &socket = *nodeAddStaticSocket(
138  &ntree, &node, in_out_, SOCK_INT, subtype_, identifier_.c_str(), name_.c_str());
139  this->set_common_flags(socket);
141  value.min = soft_min_value_;
142  value.max = soft_max_value_;
143  value.value = default_value_;
144  return socket;
145 }
146 
147 bool Int::matches(const bNodeSocket &socket) const
148 {
149  if (!this->matches_common_data(socket)) {
150  return false;
151  }
152  if (socket.type != SOCK_INT) {
153  return false;
154  }
155  if (socket.typeinfo->subtype != subtype_) {
156  return false;
157  }
159  if (value.min != soft_min_value_) {
160  return false;
161  }
162  if (value.max != soft_max_value_) {
163  return false;
164  }
165  return true;
166 }
167 
168 bool Int::can_connect(const bNodeSocket &socket) const
169 {
170  if (!sockets_can_connect(*this, socket)) {
171  return false;
172  }
173  return basic_types_can_connect(*this, socket);
174 }
175 
177 {
178  if (socket.type != SOCK_INT) {
179  BLI_assert(socket.in_out == in_out_);
180  return this->build(ntree, node);
181  }
182  if (socket.typeinfo->subtype != subtype_) {
183  modify_subtype_except_for_storage(socket, subtype_);
184  }
185  this->set_common_flags(socket);
187  value.min = soft_min_value_;
188  value.max = soft_max_value_;
189  value.subtype = subtype_;
190  return socket;
191 }
192 
195 /* -------------------------------------------------------------------- */
200 {
201  bNodeSocket &socket = *nodeAddStaticSocket(
202  &ntree, &node, in_out_, SOCK_VECTOR, subtype_, identifier_.c_str(), name_.c_str());
203  this->set_common_flags(socket);
205  copy_v3_v3(value.value, default_value_);
206  value.min = soft_min_value_;
207  value.max = soft_max_value_;
208  return socket;
209 }
210 
211 bool Vector::matches(const bNodeSocket &socket) const
212 {
213  if (!this->matches_common_data(socket)) {
214  return false;
215  }
216  if (socket.type != SOCK_VECTOR) {
217  return false;
218  }
219  if (socket.typeinfo->subtype != subtype_) {
220  return false;
221  }
222  return true;
223 }
224 
225 bool Vector::can_connect(const bNodeSocket &socket) const
226 {
227  if (!sockets_can_connect(*this, socket)) {
228  return false;
229  }
230  return basic_types_can_connect(*this, socket);
231 }
232 
234 {
235  if (socket.type != SOCK_VECTOR) {
236  BLI_assert(socket.in_out == in_out_);
237  return this->build(ntree, node);
238  }
239  if (socket.typeinfo->subtype != subtype_) {
240  modify_subtype_except_for_storage(socket, subtype_);
241  }
242  this->set_common_flags(socket);
244  value.subtype = subtype_;
245  STRNCPY(socket.name, name_.c_str());
246  return socket;
247 }
248 
251 /* -------------------------------------------------------------------- */
256 {
257  bNodeSocket &socket = *nodeAddStaticSocket(
258  &ntree, &node, in_out_, SOCK_BOOLEAN, PROP_NONE, identifier_.c_str(), name_.c_str());
259  this->set_common_flags(socket);
261  value.value = default_value_;
262  return socket;
263 }
264 
265 bool Bool::matches(const bNodeSocket &socket) const
266 {
267  if (!this->matches_common_data(socket)) {
268  return false;
269  }
270  if (socket.type != SOCK_BOOLEAN) {
271  return false;
272  }
273  return true;
274 }
275 
276 bool Bool::can_connect(const bNodeSocket &socket) const
277 {
278  if (!sockets_can_connect(*this, socket)) {
279  return false;
280  }
281  return basic_types_can_connect(*this, socket);
282 }
283 
286 /* -------------------------------------------------------------------- */
291 {
292  bNodeSocket &socket = *nodeAddStaticSocket(
293  &ntree, &node, in_out_, SOCK_RGBA, PROP_NONE, identifier_.c_str(), name_.c_str());
294  this->set_common_flags(socket);
296  copy_v4_v4(value.value, default_value_);
297  return socket;
298 }
299 
300 bool Color::matches(const bNodeSocket &socket) const
301 {
302  if (!this->matches_common_data(socket)) {
303  if (socket.name != name_) {
304  return false;
305  }
306  if (socket.identifier != identifier_) {
307  return false;
308  }
309  }
310  if (socket.type != SOCK_RGBA) {
311  return false;
312  }
313  return true;
314 }
315 
316 bool Color::can_connect(const bNodeSocket &socket) const
317 {
318  if (!sockets_can_connect(*this, socket)) {
319  return false;
320  }
321  return basic_types_can_connect(*this, socket);
322 }
323 
326 /* -------------------------------------------------------------------- */
331 {
332  bNodeSocket &socket = *nodeAddStaticSocket(
333  &ntree, &node, in_out_, SOCK_STRING, PROP_NONE, identifier_.c_str(), name_.c_str());
334  STRNCPY(((bNodeSocketValueString *)socket.default_value)->value, default_value_.c_str());
335  this->set_common_flags(socket);
336  return socket;
337 }
338 
339 bool String::matches(const bNodeSocket &socket) const
340 {
341  if (!this->matches_common_data(socket)) {
342  return false;
343  }
344  if (socket.type != SOCK_STRING) {
345  return false;
346  }
347  return true;
348 }
349 
350 bool String::can_connect(const bNodeSocket &socket) const
351 {
352  return sockets_can_connect(*this, socket) && socket.type == SOCK_STRING;
353 }
354 
357 /* -------------------------------------------------------------------- */
362 {
363  bNodeSocket &socket = *nodeAddSocket(
364  &ntree, &node, in_out_, idname_, identifier_.c_str(), name_.c_str());
365  this->set_common_flags(socket);
366  return socket;
367 }
368 
369 bool IDSocketDeclaration::matches(const bNodeSocket &socket) const
370 {
371  if (!this->matches_common_data(socket)) {
372  return false;
373  }
374  if (!STREQ(socket.idname, idname_)) {
375  return false;
376  }
377  return true;
378 }
379 
381 {
382  return sockets_can_connect(*this, socket) && STREQ(socket.idname, idname_);
383 }
384 
386  bNode &node,
387  bNodeSocket &socket) const
388 {
389  if (StringRef(socket.idname) != idname_) {
390  BLI_assert(socket.in_out == in_out_);
391  return this->build(ntree, node);
392  }
393  this->set_common_flags(socket);
394  return socket;
395 }
396 
399 /* -------------------------------------------------------------------- */
404 {
405  bNodeSocket &socket = *nodeAddSocket(
406  &ntree, &node, in_out_, "NodeSocketGeometry", identifier_.c_str(), name_.c_str());
407  this->set_common_flags(socket);
408  return socket;
409 }
410 
411 bool Geometry::matches(const bNodeSocket &socket) const
412 {
413  if (!this->matches_common_data(socket)) {
414  return false;
415  }
416  if (socket.type != SOCK_GEOMETRY) {
417  return false;
418  }
419  return true;
420 }
421 
422 bool Geometry::can_connect(const bNodeSocket &socket) const
423 {
424  return sockets_can_connect(*this, socket) && socket.type == SOCK_GEOMETRY;
425 }
426 
428 {
429  return supported_types_;
430 }
431 
433 {
434  return only_realized_data_;
435 }
436 
438 {
439  return only_instances_;
440 }
441 
443 {
444  decl_->supported_types_ = {supported_type};
445  return *this;
446 }
447 
450 {
451  decl_->supported_types_ = std::move(supported_types);
452  return *this;
453 }
454 
456 {
457  decl_->only_realized_data_ = value;
458  return *this;
459 }
460 
462 {
463  decl_->only_instances_ = value;
464  return *this;
465 }
466 
469 /* -------------------------------------------------------------------- */
474 {
475  bNodeSocket &socket = *nodeAddSocket(
476  &ntree, &node, in_out_, "NodeSocketShader", identifier_.c_str(), name_.c_str());
477  this->set_common_flags(socket);
478  return socket;
479 }
480 
481 bool Shader::matches(const bNodeSocket &socket) const
482 {
483  if (!this->matches_common_data(socket)) {
484  return false;
485  }
486  if (socket.type != SOCK_SHADER) {
487  return false;
488  }
489  return true;
490 }
491 
492 bool Shader::can_connect(const bNodeSocket &socket) const
493 {
494  if (!sockets_can_connect(*this, socket)) {
495  return false;
496  }
497  /* Basic types can convert to shaders, but not the other way around. */
498  if (in_out_ == SOCK_IN) {
499  return ELEM(
501  }
502  return socket.type == SOCK_SHADER;
503 }
504 
507 } // namespace blender::nodes::decl
GeometryComponentType
struct bNodeSocket * nodeAddSocket(struct bNodeTree *ntree, struct bNode *node, eNodeSocketInOut in_out, const char *idname, const char *identifier, const char *name)
Definition: node.cc:1679
struct bNodeSocket * nodeAddStaticSocket(struct bNodeTree *ntree, struct bNode *node, eNodeSocketInOut in_out, int type, int subtype, const char *identifier, const char *name)
Definition: node.cc:1897
const char * nodeStaticSocketType(int type, int subtype)
Definition: node.cc:1710
struct bNodeSocketType * nodeSocketTypeFind(const char *idname)
Definition: node.cc:1395
#define BLI_assert(a)
Definition: BLI_assert.h:46
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define STRNCPY(dst, src)
Definition: BLI_string.h:483
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
@ SOCK_IN
@ SOCK_INT
@ SOCK_VECTOR
@ SOCK_BOOLEAN
@ SOCK_SHADER
@ SOCK_FLOAT
@ SOCK_GEOMETRY
@ SOCK_STRING
@ SOCK_RGBA
@ PROP_NONE
Definition: RNA_types.h:126
bool matches_common_data(const bNodeSocket &socket) const
void set_common_flags(bNodeSocket &socket) const
bNodeSocket & build(bNodeTree &ntree, bNode &node) const override
bool matches(const bNodeSocket &socket) const override
bool can_connect(const bNodeSocket &socket) const override
bool can_connect(const bNodeSocket &socket) const override
bNodeSocket & build(bNodeTree &ntree, bNode &node) const override
bool matches(const bNodeSocket &socket) const override
bool can_connect(const bNodeSocket &socket) const override
bNodeSocket & build(bNodeTree &ntree, bNode &node) const override
bNodeSocket & update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const override
bool matches(const bNodeSocket &socket) const override
GeometryBuilder & only_realized_data(bool value=true)
GeometryBuilder & only_instances(bool value=true)
GeometryBuilder & supported_type(GeometryComponentType supported_type)
Span< GeometryComponentType > supported_types() const
bNodeSocket & build(bNodeTree &ntree, bNode &node) const override
bool can_connect(const bNodeSocket &socket) const override
bool matches(const bNodeSocket &socket) const override
bool can_connect(const bNodeSocket &socket) const override
bNodeSocket & build(bNodeTree &ntree, bNode &node) const override
bNodeSocket & update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const override
bool matches(const bNodeSocket &socket) const override
bool can_connect(const bNodeSocket &socket) const override
bNodeSocket & build(bNodeTree &ntree, bNode &node) const override
bool matches(const bNodeSocket &socket) const override
bNodeSocket & update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const override
bool can_connect(const bNodeSocket &socket) const override
bNodeSocket & build(bNodeTree &ntree, bNode &node) const override
bool matches(const bNodeSocket &socket) const override
bool can_connect(const bNodeSocket &socket) const override
bool matches(const bNodeSocket &socket) const override
bNodeSocket & build(bNodeTree &ntree, bNode &node) const override
bool can_connect(const bNodeSocket &socket) const override
bool matches(const bNodeSocket &socket) const override
bNodeSocket & build(bNodeTree &ntree, bNode &node) const override
bNodeSocket & update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const override
OperationNode * node
bNodeTree * ntree
ccl_global KernelShaderEvalInput ccl_global float * output
ccl_global KernelShaderEvalInput * input
static bool basic_types_can_connect(const SocketDeclaration &UNUSED(socket_decl), const bNodeSocket &other_socket)
static void modify_subtype_except_for_storage(bNodeSocket &socket, int new_subtype)
static bool field_types_are_compatible(const SocketDeclaration &input, const SocketDeclaration &output)
static bool sockets_can_connect(const SocketDeclaration &socket_decl, const bNodeSocket &other_socket)
Defines a socket type.
Definition: BKE_node.h:143
char name[64]
bNodeSocketRuntimeHandle * runtime
void * default_value
struct bNodeSocketType * typeinfo
char identifier[64]
char idname[64]