Blender V4.5
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
12#include "UI_interface.hh"
13#include "UI_resources.hh"
14
16
18
20{
21 b.add_input<decl::Vector>("Min").supports_field();
22 b.add_input<decl::Vector>("Max").default_value({1.0f, 1.0f, 1.0f}).supports_field();
23 b.add_input<decl::Float>("Min", "Min_001").supports_field();
24 b.add_input<decl::Float>("Max", "Max_001").default_value(1.0f).supports_field();
25 b.add_input<decl::Int>("Min", "Min_002").min(-100000).max(100000).supports_field();
26 b.add_input<decl::Int>("Max", "Max_002")
27 .default_value(100)
28 .min(-100000)
29 .max(100000)
30 .supports_field();
31 b.add_input<decl::Float>("Probability")
32 .min(0.0f)
33 .max(1.0f)
34 .default_value(0.5f)
35 .subtype(PROP_FACTOR)
36 .supports_field()
37 .make_available([](bNode &node) { node_storage(node).data_type = CD_PROP_BOOL; });
38 b.add_input<decl::Int>("ID").implicit_field(NODE_DEFAULT_INPUT_ID_INDEX_FIELD);
39 b.add_input<decl::Int>("Seed").default_value(0).min(-10000).max(10000).supports_field();
40
41 b.add_output<decl::Vector>("Value").dependent_field();
42 b.add_output<decl::Float>("Value", "Value_001").dependent_field();
43 b.add_output<decl::Int>("Value", "Value_002").dependent_field();
44 b.add_output<decl::Bool>("Value", "Value_003").dependent_field();
45}
46
47static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
48{
49 layout->prop(ptr, "data_type", UI_ITEM_NONE, "", ICON_NONE);
50}
51
52static void fn_node_random_value_init(bNodeTree * /*tree*/, bNode *node)
53{
55 data->data_type = CD_PROP_FLOAT;
56 node->storage = data;
57}
58
60{
61 const NodeRandomValue &storage = node_storage(*node);
62 const eCustomDataType data_type = eCustomDataType(storage.data_type);
63
64 bNodeSocket *sock_min_vector = (bNodeSocket *)node->inputs.first;
65 bNodeSocket *sock_max_vector = sock_min_vector->next;
66 bNodeSocket *sock_min_float = sock_max_vector->next;
67 bNodeSocket *sock_max_float = sock_min_float->next;
68 bNodeSocket *sock_min_int = sock_max_float->next;
69 bNodeSocket *sock_max_int = sock_min_int->next;
70 bNodeSocket *sock_probability = sock_max_int->next;
71
72 bNodeSocket *sock_out_vector = (bNodeSocket *)node->outputs.first;
73 bNodeSocket *sock_out_float = sock_out_vector->next;
74 bNodeSocket *sock_out_int = sock_out_float->next;
75 bNodeSocket *sock_out_bool = sock_out_int->next;
76
77 bke::node_set_socket_availability(*ntree, *sock_min_vector, data_type == CD_PROP_FLOAT3);
78 bke::node_set_socket_availability(*ntree, *sock_max_vector, data_type == CD_PROP_FLOAT3);
79 bke::node_set_socket_availability(*ntree, *sock_min_float, data_type == CD_PROP_FLOAT);
80 bke::node_set_socket_availability(*ntree, *sock_max_float, data_type == CD_PROP_FLOAT);
81 bke::node_set_socket_availability(*ntree, *sock_min_int, data_type == CD_PROP_INT32);
82 bke::node_set_socket_availability(*ntree, *sock_max_int, data_type == CD_PROP_INT32);
83 bke::node_set_socket_availability(*ntree, *sock_probability, data_type == CD_PROP_BOOL);
84
85 bke::node_set_socket_availability(*ntree, *sock_out_vector, data_type == CD_PROP_FLOAT3);
86 bke::node_set_socket_availability(*ntree, *sock_out_float, data_type == CD_PROP_FLOAT);
87 bke::node_set_socket_availability(*ntree, *sock_out_int, data_type == CD_PROP_INT32);
88 bke::node_set_socket_availability(*ntree, *sock_out_bool, data_type == CD_PROP_BOOL);
89}
90
91static std::optional<eCustomDataType> node_type_from_other_socket(const bNodeSocket &socket)
92{
93 switch (socket.type) {
94 case SOCK_FLOAT:
95 return CD_PROP_FLOAT;
96 case SOCK_BOOLEAN:
97 return CD_PROP_BOOL;
98 case SOCK_INT:
99 return CD_PROP_INT32;
100 case SOCK_VECTOR:
101 case SOCK_RGBA:
102 case SOCK_ROTATION:
103 return CD_PROP_FLOAT3;
104 default:
105 return {};
106 }
107}
108
110{
111 const NodeDeclaration &declaration = *params.node_type().static_declaration;
112 const std::optional<eCustomDataType> type = node_type_from_other_socket(params.other_socket());
113 if (!type) {
114 return;
115 }
116 if (params.in_out() == SOCK_IN) {
118 params.add_item(IFACE_("Min"), [type](LinkSearchOpParams &params) {
119 bNode &node = params.add_node("FunctionNodeRandomValue");
120 node_storage(node).data_type = *type;
121 params.update_and_connect_available_socket(node, "Min");
122 });
123 params.add_item(IFACE_("Max"), [type](LinkSearchOpParams &params) {
124 bNode &node = params.add_node("FunctionNodeRandomValue");
125 node_storage(node).data_type = *type;
126 params.update_and_connect_available_socket(node, "Max");
127 });
128 }
129 search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(3));
130 }
131 else {
132 params.add_item(IFACE_("Value"), [type](LinkSearchOpParams &params) {
133 bNode &node = params.add_node("FunctionNodeRandomValue");
134 node_storage(node).data_type = *type;
135 params.update_and_connect_available_socket(node, "Value");
136 });
137 }
138}
139
141{
142 const NodeRandomValue &storage = node_storage(builder.node());
143 const eCustomDataType data_type = eCustomDataType(storage.data_type);
144
145 switch (data_type) {
146 case CD_PROP_FLOAT3: {
147 static auto fn = mf::build::SI4_SO<float3, float3, int, int, float3>(
148 "Random Vector",
149 [](float3 min_value, float3 max_value, int id, int seed) -> float3 {
150 const float x = noise::hash_to_float(seed, id, 0);
151 const float y = noise::hash_to_float(seed, id, 1);
152 const float z = noise::hash_to_float(seed, id, 2);
153 return float3(x, y, z) * (max_value - min_value) + min_value;
154 },
155 mf::build::exec_presets::SomeSpanOrSingle<2>());
156 builder.set_matching_fn(fn);
157 break;
158 }
159 case CD_PROP_FLOAT: {
160 static auto fn = mf::build::SI4_SO<float, float, int, int, float>(
161 "Random Float",
162 [](float min_value, float max_value, int id, int seed) -> float {
163 const float value = noise::hash_to_float(seed, id);
164 return value * (max_value - min_value) + min_value;
165 },
166 mf::build::exec_presets::SomeSpanOrSingle<2>());
167 builder.set_matching_fn(fn);
168 break;
169 }
170 case CD_PROP_INT32: {
171 static auto fn = mf::build::SI4_SO<int, int, int, int, int>(
172 "Random Int",
173 [](int min_value, int max_value, int id, int seed) -> int {
174 const float value = noise::hash_to_float(id, seed);
175 /* Add one to the maximum and use floor to produce an even
176 * distribution for the first and last values (See #93591). */
177 return floor(value * (max_value + 1 - min_value) + min_value);
178 },
179 mf::build::exec_presets::SomeSpanOrSingle<2>());
180 builder.set_matching_fn(fn);
181 break;
182 }
183 case CD_PROP_BOOL: {
184 static auto fn = mf::build::SI3_SO<float, int, int, bool>(
185 "Random Bool",
186 [](float probability, int id, int seed) -> bool {
187 return noise::hash_to_float(id, seed) <= probability;
188 },
189 mf::build::exec_presets::SomeSpanOrSingle<1>());
190 builder.set_matching_fn(fn);
191 break;
192 }
193 default: {
195 break;
196 }
197 }
198}
199
200static void node_register()
201{
202 static blender::bke::bNodeType ntype;
203
204 fn_node_type_base(&ntype, "FunctionNodeRandomValue", FN_NODE_RANDOM_VALUE);
205 ntype.ui_name = "Random Value";
206 ntype.enum_name_legacy = "RANDOM_VALUE";
211 ntype.declare = node_declare;
215 ntype, "NodeRandomValue", node_free_standard_storage, node_copy_standard_storage);
217}
219
220} // namespace blender::nodes::node_fn_random_value_cc
#define NODE_CLASS_CONVERTER
Definition BKE_node.hh:439
#define NODE_STORAGE_FUNCS(StorageT)
Definition BKE_node.hh:1215
#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:239
#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)
#define floor
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:2748
void node_set_socket_availability(bNodeTree &ntree, bNodeSocket &sock, bool is_available)
Definition node.cc:5011
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:5603
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)
float hash_to_float(uint32_t kx)
Definition noise.cc:171
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 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:226
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:277
NodeMultiFunctionBuildFunction build_multi_function
Definition BKE_node.hh:344
const char * enum_name_legacy
Definition BKE_node.hh:235
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:247
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
Definition BKE_node.hh:371
NodeDeclareFunction declare
Definition BKE_node.hh:355
void(* updatefunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:269
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:4227