Blender V5.0
node_fn_random_value.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5// #include "BLI_hash.h"
6#include "BLI_noise.hh"
7
9
11
13#include "UI_resources.hh"
14
16
18
20{
21 b.is_function_node();
22 b.add_input<decl::Vector>("Min");
23 b.add_input<decl::Vector>("Max").default_value({1.0f, 1.0f, 1.0f});
24 b.add_input<decl::Float>("Min", "Min_001");
25 b.add_input<decl::Float>("Max", "Max_001").default_value(1.0f);
26 b.add_input<decl::Int>("Min", "Min_002").min(-100000).max(100000);
27 b.add_input<decl::Int>("Max", "Max_002").default_value(100).min(-100000).max(100000);
28 b.add_input<decl::Float>("Probability")
29 .min(0.0f)
30 .max(1.0f)
31 .default_value(0.5f)
32 .subtype(PROP_FACTOR)
33 .make_available([](bNode &node) { node_storage(node).data_type = CD_PROP_BOOL; });
34 b.add_input<decl::Int>("ID").implicit_field(NODE_DEFAULT_INPUT_ID_INDEX_FIELD);
35 b.add_input<decl::Int>("Seed").default_value(0).min(-10000).max(10000);
36
37 b.add_output<decl::Vector>("Value");
38 b.add_output<decl::Float>("Value", "Value_001");
39 b.add_output<decl::Int>("Value", "Value_002");
40 b.add_output<decl::Bool>("Value", "Value_003");
41}
42
43static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
44{
45 layout->prop(ptr, "data_type", UI_ITEM_NONE, "", ICON_NONE);
46}
47
48static void fn_node_random_value_init(bNodeTree * /*tree*/, bNode *node)
49{
51 data->data_type = CD_PROP_FLOAT;
52 node->storage = data;
53}
54
56{
57 const NodeRandomValue &storage = node_storage(*node);
58 const eCustomDataType data_type = eCustomDataType(storage.data_type);
59
60 bNodeSocket *sock_min_vector = (bNodeSocket *)node->inputs.first;
61 bNodeSocket *sock_max_vector = sock_min_vector->next;
62 bNodeSocket *sock_min_float = sock_max_vector->next;
63 bNodeSocket *sock_max_float = sock_min_float->next;
64 bNodeSocket *sock_min_int = sock_max_float->next;
65 bNodeSocket *sock_max_int = sock_min_int->next;
66 bNodeSocket *sock_probability = sock_max_int->next;
67
68 bNodeSocket *sock_out_vector = (bNodeSocket *)node->outputs.first;
69 bNodeSocket *sock_out_float = sock_out_vector->next;
70 bNodeSocket *sock_out_int = sock_out_float->next;
71 bNodeSocket *sock_out_bool = sock_out_int->next;
72
73 bke::node_set_socket_availability(*ntree, *sock_min_vector, data_type == CD_PROP_FLOAT3);
74 bke::node_set_socket_availability(*ntree, *sock_max_vector, data_type == CD_PROP_FLOAT3);
75 bke::node_set_socket_availability(*ntree, *sock_min_float, data_type == CD_PROP_FLOAT);
76 bke::node_set_socket_availability(*ntree, *sock_max_float, data_type == CD_PROP_FLOAT);
77 bke::node_set_socket_availability(*ntree, *sock_min_int, data_type == CD_PROP_INT32);
78 bke::node_set_socket_availability(*ntree, *sock_max_int, data_type == CD_PROP_INT32);
79 bke::node_set_socket_availability(*ntree, *sock_probability, data_type == CD_PROP_BOOL);
80
81 bke::node_set_socket_availability(*ntree, *sock_out_vector, data_type == CD_PROP_FLOAT3);
82 bke::node_set_socket_availability(*ntree, *sock_out_float, data_type == CD_PROP_FLOAT);
83 bke::node_set_socket_availability(*ntree, *sock_out_int, data_type == CD_PROP_INT32);
84 bke::node_set_socket_availability(*ntree, *sock_out_bool, data_type == CD_PROP_BOOL);
85}
86
87static std::optional<eCustomDataType> node_type_from_other_socket(const bNodeSocket &socket)
88{
89 switch (socket.type) {
90 case SOCK_FLOAT:
91 return CD_PROP_FLOAT;
92 case SOCK_BOOLEAN:
93 return CD_PROP_BOOL;
94 case SOCK_INT:
95 return CD_PROP_INT32;
96 case SOCK_VECTOR:
97 case SOCK_RGBA:
98 case SOCK_ROTATION:
99 return CD_PROP_FLOAT3;
100 default:
101 return {};
102 }
103}
104
106{
107 const NodeDeclaration &declaration = *params.node_type().static_declaration;
108 const std::optional<eCustomDataType> type = node_type_from_other_socket(params.other_socket());
109 if (!type) {
110 return;
111 }
112 if (params.in_out() == SOCK_IN) {
114 params.add_item(IFACE_("Min"), [type](LinkSearchOpParams &params) {
115 bNode &node = params.add_node("FunctionNodeRandomValue");
116 node_storage(node).data_type = *type;
117 params.update_and_connect_available_socket(node, "Min");
118 });
119 params.add_item(IFACE_("Max"), [type](LinkSearchOpParams &params) {
120 bNode &node = params.add_node("FunctionNodeRandomValue");
121 node_storage(node).data_type = *type;
122 params.update_and_connect_available_socket(node, "Max");
123 });
124 }
125 search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(3));
126 }
127 else {
128 params.add_item(IFACE_("Value"), [type](LinkSearchOpParams &params) {
129 bNode &node = params.add_node("FunctionNodeRandomValue");
130 node_storage(node).data_type = *type;
131 params.update_and_connect_available_socket(node, "Value");
132 });
133 }
134}
135
137{
138 const NodeRandomValue &storage = node_storage(builder.node());
139 const eCustomDataType data_type = eCustomDataType(storage.data_type);
140
141 switch (data_type) {
142 case CD_PROP_FLOAT3: {
143 static auto fn = mf::build::SI4_SO<float3, float3, int, int, float3>(
144 "Random Vector",
145 [](float3 min_value, float3 max_value, int id, int seed) -> float3 {
146 const float x = noise::hash_to_float(seed, id, 0);
147 const float y = noise::hash_to_float(seed, id, 1);
148 const float z = noise::hash_to_float(seed, id, 2);
149 return float3(x, y, z) * (max_value - min_value) + min_value;
150 },
151 mf::build::exec_presets::SomeSpanOrSingle<2>());
152 builder.set_matching_fn(fn);
153 break;
154 }
155 case CD_PROP_FLOAT: {
156 static auto fn = mf::build::SI4_SO<float, float, int, int, float>(
157 "Random Float",
158 [](float min_value, float max_value, int id, int seed) -> float {
159 const float value = noise::hash_to_float(seed, id);
160 return value * (max_value - min_value) + min_value;
161 },
162 mf::build::exec_presets::SomeSpanOrSingle<2>());
163 builder.set_matching_fn(fn);
164 break;
165 }
166 case CD_PROP_INT32: {
167 static auto fn = mf::build::SI4_SO<int, int, int, int, int>(
168 "Random Int",
169 [](int min_value, int max_value, int id, int seed) -> int {
170 if (min_value > max_value) {
171 std::swap(min_value, max_value);
172 }
173 const uint32_t hash = noise::hash(id, seed);
174 return min_value + hash % (max_value - min_value + 1);
175 },
176 mf::build::exec_presets::SomeSpanOrSingle<2>());
177 builder.set_matching_fn(fn);
178 break;
179 }
180 case CD_PROP_BOOL: {
181 static auto fn = mf::build::SI3_SO<float, int, int, bool>(
182 "Random Bool",
183 [](float probability, int id, int seed) -> bool {
184 return noise::hash_to_float(id, seed) <= probability;
185 },
186 mf::build::exec_presets::SomeSpanOrSingle<1>());
187 builder.set_matching_fn(fn);
188 break;
189 }
190 default: {
192 break;
193 }
194 }
195}
196
197static void node_register()
198{
199 static blender::bke::bNodeType ntype;
200
201 fn_node_type_base(&ntype, "FunctionNodeRandomValue", FN_NODE_RANDOM_VALUE);
202 ntype.ui_name = "Random Value";
203 ntype.ui_description = "Output a randomized value";
204 ntype.enum_name_legacy = "RANDOM_VALUE";
209 ntype.declare = node_declare;
213 ntype, "NodeRandomValue", node_free_standard_storage, node_copy_standard_storage);
215}
217
218} // namespace blender::nodes::node_fn_random_value_cc
#define NODE_CLASS_CONVERTER
Definition BKE_node.hh:453
#define NODE_STORAGE_FUNCS(StorageT)
Definition BKE_node.hh:1240
#define FN_NODE_RANDOM_VALUE
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define ELEM(...)
#define IFACE_(msgid)
@ CD_PROP_FLOAT
@ CD_PROP_FLOAT3
@ CD_PROP_INT32
@ NODE_DEFAULT_INPUT_ID_INDEX_FIELD
@ SOCK_IN
@ SOCK_INT
@ SOCK_VECTOR
@ SOCK_BOOLEAN
@ SOCK_FLOAT
@ SOCK_ROTATION
@ SOCK_RGBA
#define NOD_REGISTER_NODE(REGISTER_FUNC)
@ PROP_FACTOR
Definition RNA_types.hh:251
#define UI_ITEM_NONE
BMesh const char void * data
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
static unsigned long seed
Definition btSoftBody.h:39
Vector< SocketDeclaration * > inputs
void set_matching_fn(const mf::MultiFunction *fn)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
void node_set_socket_availability(bNodeTree &ntree, bNodeSocket &sock, bool is_available)
Definition node.cc:4739
void node_type_storage(bNodeType &ntype, std::optional< StringRefNull > storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
Definition node.cc:5414
static void node_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
static void node_declare(NodeDeclarationBuilder &b)
static void fn_node_random_value_update(bNodeTree *ntree, bNode *node)
static void node_gather_link_search_ops(GatherLinkSearchOpParams &params)
static void fn_node_random_value_init(bNodeTree *, bNode *node)
static std::optional< eCustomDataType > node_type_from_other_socket(const bNodeSocket &socket)
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
void search_link_ops_for_declarations(GatherLinkSearchOpParams &params, Span< SocketDeclaration * > declarations)
uint32_t hash(uint32_t kx)
Definition noise.cc:90
float hash_to_float(uint32_t kx)
Definition noise.cc:233
VecBase< float, 3 > float3
void fn_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
void node_free_standard_storage(bNode *node)
Definition node_util.cc:42
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
Definition node_util.cc:54
#define hash
Definition noise_c.cc:154
#define min(a, b)
Definition sort.cc:36
void * first
struct bNodeSocket * next
ListBase inputs
void * storage
ListBase outputs
Defines a node type.
Definition BKE_node.hh:238
std::string ui_description
Definition BKE_node.hh:244
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:289
NodeMultiFunctionBuildFunction build_multi_function
Definition BKE_node.hh:351
const char * enum_name_legacy
Definition BKE_node.hh:247
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:259
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
Definition BKE_node.hh:378
NodeDeclareFunction declare
Definition BKE_node.hh:362
void(* updatefunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:281
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
max
Definition text_draw.cc:251
PointerRNA * ptr
Definition wm_files.cc:4238