Blender  V3.3
node_fn_random_value.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 // #include "BLI_hash.h"
4 #include "BLI_noise.hh"
5 
6 #include "node_function_util.hh"
7 
9 
10 #include "UI_interface.h"
11 #include "UI_resources.h"
12 
14 
16 
18 {
19  b.add_input<decl::Vector>(N_("Min")).supports_field();
20  b.add_input<decl::Vector>(N_("Max")).default_value({1.0f, 1.0f, 1.0f}).supports_field();
21  b.add_input<decl::Float>(N_("Min"), "Min_001").supports_field();
22  b.add_input<decl::Float>(N_("Max"), "Max_001").default_value(1.0f).supports_field();
23  b.add_input<decl::Int>(N_("Min"), "Min_002").min(-100000).max(100000).supports_field();
24  b.add_input<decl::Int>(N_("Max"), "Max_002")
25  .default_value(100)
26  .min(-100000)
27  .max(100000)
28  .supports_field();
29  b.add_input<decl::Float>(N_("Probability"))
30  .min(0.0f)
31  .max(1.0f)
32  .default_value(0.5f)
33  .subtype(PROP_FACTOR)
34  .supports_field()
35  .make_available([](bNode &node) { node_storage(node).data_type = CD_PROP_BOOL; });
36  b.add_input<decl::Int>(N_("ID")).implicit_field();
37  b.add_input<decl::Int>(N_("Seed")).default_value(0).min(-10000).max(10000).supports_field();
38 
39  b.add_output<decl::Vector>(N_("Value")).dependent_field();
40  b.add_output<decl::Float>(N_("Value"), "Value_001").dependent_field();
41  b.add_output<decl::Int>(N_("Value"), "Value_002").dependent_field();
42  b.add_output<decl::Bool>(N_("Value"), "Value_003").dependent_field();
43 }
44 
46 {
47  uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
48 }
49 
51 {
52  NodeRandomValue *data = MEM_cnew<NodeRandomValue>(__func__);
53  data->data_type = CD_PROP_FLOAT;
54  node->storage = data;
55 }
56 
58 {
59  const NodeRandomValue &storage = node_storage(*node);
60  const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
61 
62  bNodeSocket *sock_min_vector = (bNodeSocket *)node->inputs.first;
63  bNodeSocket *sock_max_vector = sock_min_vector->next;
64  bNodeSocket *sock_min_float = sock_max_vector->next;
65  bNodeSocket *sock_max_float = sock_min_float->next;
66  bNodeSocket *sock_min_int = sock_max_float->next;
67  bNodeSocket *sock_max_int = sock_min_int->next;
68  bNodeSocket *sock_probability = sock_max_int->next;
69 
70  bNodeSocket *sock_out_vector = (bNodeSocket *)node->outputs.first;
71  bNodeSocket *sock_out_float = sock_out_vector->next;
72  bNodeSocket *sock_out_int = sock_out_float->next;
73  bNodeSocket *sock_out_bool = sock_out_int->next;
74 
75  nodeSetSocketAvailability(ntree, sock_min_vector, data_type == CD_PROP_FLOAT3);
76  nodeSetSocketAvailability(ntree, sock_max_vector, data_type == CD_PROP_FLOAT3);
77  nodeSetSocketAvailability(ntree, sock_min_float, data_type == CD_PROP_FLOAT);
78  nodeSetSocketAvailability(ntree, sock_max_float, data_type == CD_PROP_FLOAT);
79  nodeSetSocketAvailability(ntree, sock_min_int, data_type == CD_PROP_INT32);
80  nodeSetSocketAvailability(ntree, sock_max_int, data_type == CD_PROP_INT32);
81  nodeSetSocketAvailability(ntree, sock_probability, data_type == CD_PROP_BOOL);
82 
83  nodeSetSocketAvailability(ntree, sock_out_vector, data_type == CD_PROP_FLOAT3);
84  nodeSetSocketAvailability(ntree, sock_out_float, data_type == CD_PROP_FLOAT);
85  nodeSetSocketAvailability(ntree, sock_out_int, data_type == CD_PROP_INT32);
86  nodeSetSocketAvailability(ntree, sock_out_bool, data_type == CD_PROP_BOOL);
87 }
88 
89 static std::optional<eCustomDataType> node_type_from_other_socket(const bNodeSocket &socket)
90 {
91  switch (socket.type) {
92  case SOCK_FLOAT:
93  return CD_PROP_FLOAT;
94  case SOCK_BOOLEAN:
95  return CD_PROP_BOOL;
96  case SOCK_INT:
97  return CD_PROP_INT32;
98  case SOCK_VECTOR:
99  case SOCK_RGBA:
100  return CD_PROP_FLOAT3;
101  default:
102  return {};
103  }
104 }
105 
107 {
108  const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
109  const std::optional<eCustomDataType> type = node_type_from_other_socket(params.other_socket());
110  if (!type) {
111  return;
112  }
113  if (params.in_out() == SOCK_IN) {
115  params.add_item(IFACE_("Min"), [type](LinkSearchOpParams &params) {
116  bNode &node = params.add_node("FunctionNodeRandomValue");
117  node_storage(node).data_type = *type;
118  params.update_and_connect_available_socket(node, "Min");
119  });
120  params.add_item(IFACE_("Max"), [type](LinkSearchOpParams &params) {
121  bNode &node = params.add_node("FunctionNodeRandomValue");
122  node_storage(node).data_type = *type;
123  params.update_and_connect_available_socket(node, "Max");
124  });
125  }
126  search_link_ops_for_declarations(params, declaration.inputs().take_back(3));
127  }
128  else {
129  params.add_item(IFACE_("Value"), [type](LinkSearchOpParams &params) {
130  bNode &node = params.add_node("FunctionNodeRandomValue");
131  node_storage(node).data_type = *type;
132  params.update_and_connect_available_socket(node, "Value");
133  });
134  }
135 }
136 
138 {
139  const NodeRandomValue &storage = node_storage(builder.node());
140  const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type);
141 
142  switch (data_type) {
143  case CD_PROP_FLOAT3: {
149  fn{"Random Vector",
150  [](float3 min_value, float3 max_value, int id, int seed, float3 *r_value) {
151  const float x = noise::hash_to_float(seed, id, 0);
152  const float y = noise::hash_to_float(seed, id, 1);
153  const float z = noise::hash_to_float(seed, id, 2);
154  *r_value = float3(x, y, z) * (max_value - min_value) + min_value;
155  },
157  builder.set_matching_fn(fn);
158  break;
159  }
160  case CD_PROP_FLOAT: {
166  fn{"Random Float",
167  [](float min_value, float max_value, int id, int seed, float *r_value) {
168  const float value = noise::hash_to_float(seed, id);
169  *r_value = value * (max_value - min_value) + min_value;
170  },
172  builder.set_matching_fn(fn);
173  break;
174  }
175  case CD_PROP_INT32: {
181  fn{"Random Int",
182  [](int min_value, int max_value, int id, int seed, int *r_value) {
183  const float value = noise::hash_to_float(id, seed);
184  /* Add one to the maximum and use floor to produce an even
185  * distribution for the first and last values (See T93591). */
186  *r_value = floor(value * (max_value + 1 - min_value) + min_value);
187  },
189  builder.set_matching_fn(fn);
190  break;
191  }
192  case CD_PROP_BOOL: {
197  fn{"Random Bool",
198  [](float probability, int id, int seed, bool *r_value) {
199  *r_value = noise::hash_to_float(id, seed) <= probability;
200  },
202  builder.set_matching_fn(fn);
203  break;
204  }
205  default: {
207  break;
208  }
209  }
210 }
211 
212 } // namespace blender::nodes::node_fn_random_value_cc
213 
215 {
216  namespace file_ns = blender::nodes::node_fn_random_value_cc;
217 
218  static bNodeType ntype;
219 
228  &ntype, "NodeRandomValue", node_free_standard_storage, node_copy_standard_storage);
229  nodeRegisterType(&ntype);
230 }
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4443
#define NODE_CLASS_CONVERTER
Definition: BKE_node.h:351
#define NODE_STORAGE_FUNCS(StorageT)
Definition: BKE_node.h:1563
#define FN_NODE_RANDOM_VALUE
Definition: BKE_node.h:1529
void nodeSetSocketAvailability(struct bNodeTree *ntree, struct bNodeSocket *sock, bool is_available)
Definition: node.cc:3664
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4390
void node_type_storage(struct bNodeType *ntype, const char *storagename, void(*freefunc)(struct bNode *node), void(*copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, const struct bNode *src_node))
Definition: node.cc:4426
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define UNUSED(x)
#define ELEM(...)
#define IFACE_(msgid)
eCustomDataType
@ CD_PROP_FLOAT
@ CD_PROP_FLOAT3
@ CD_PROP_INT32
@ CD_PROP_BOOL
@ SOCK_IN
@ SOCK_INT
@ SOCK_VECTOR
@ SOCK_BOOLEAN
@ SOCK_FLOAT
@ SOCK_RGBA
_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 const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_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 const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_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
@ PROP_FACTOR
Definition: RNA_types.h:144
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
static unsigned long seed
Definition: btSoftBody.h:39
Span< SocketDeclarationPtr > inputs() const
void set_matching_fn(const MultiFunction *fn)
OperationNode * node
void * tree
bNodeTree * ntree
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
T floor(const T &a)
static void fn_node_random_value_gather_link_search(GatherLinkSearchOpParams &params)
static std::optional< eCustomDataType > node_type_from_other_socket(const bNodeSocket &socket)
static void fn_node_random_value_init(bNodeTree *UNUSED(tree), bNode *node)
static void fn_node_random_value_build_multi_function(NodeMultiFunctionBuilder &builder)
static void fn_node_random_value_declare(NodeDeclarationBuilder &b)
static void fn_node_random_value_update(bNodeTree *ntree, bNode *node)
static void fn_node_random_value_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
void search_link_ops_for_declarations(GatherLinkSearchOpParams &params, Span< SocketDeclarationPtr > declarations)
float hash_to_float(uint32_t kx)
Definition: noise.cc:156
vec_base< float, 3 > float3
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
void register_node_type_fn_random_value()
void fn_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
Definition: node_util.c:55
void node_free_standard_storage(bNode *node)
Definition: node_util.c:43
#define min(a, b)
Definition: sort.c:35
struct bNodeSocket * next
Defines a node type.
Definition: BKE_node.h:226
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
Definition: BKE_node.h:335
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:244
NodeMultiFunctionBuildFunction build_multi_function
Definition: BKE_node.h:313
NodeDeclareFunction declare
Definition: BKE_node.h:324
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480