Blender V5.0
node_fn_hash_value.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_hash.h"
7#include "BLI_noise.hh"
8
9#include "NOD_rna_define.hh"
11
12#include "RNA_enum_types.hh"
13
14#include "node_function_util.hh"
15
17#include "UI_resources.hh"
18
20
22{
23 b.is_function_node();
24
25 const bNode *node = b.node_or_null();
26 if (node) {
27 const eNodeSocketDatatype data_type = eNodeSocketDatatype(node->custom1);
28 b.add_input(data_type, "Value");
29 }
30 b.add_input<decl::Int>("Seed", "Seed");
31 b.add_output<decl::Int>("Hash");
32}
33
34static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
35{
36 layout->prop(ptr, "data_type", UI_ITEM_NONE, "", ICON_NONE);
37}
38
39static void node_init(bNodeTree * /*tree*/, bNode *node)
40{
41 node->custom1 = SOCK_INT;
42}
43
44static const mf::MultiFunction *get_multi_function(const bNode &bnode)
45{
46 const eNodeSocketDatatype socket_type = eNodeSocketDatatype(bnode.custom1);
47
48 static auto exec_preset = mf::build::exec_presets::AllSpanOrSingle();
49
50 static auto fn_hash_float = mf::build::SI2_SO<float, int, int>(
51 "Hash Float",
52 [](float a, int seed) { return noise::hash(noise::hash_float(a), seed); },
53 exec_preset);
54 static auto fn_hash_vector = mf::build::SI2_SO<float3, int, int>(
55 "Hash Vector",
56 [](float3 a, int seed) { return noise::hash(noise::hash_float(a), seed); },
57 exec_preset);
58 static auto fn_hash_color = mf::build::SI2_SO<ColorGeometry4f, int, int>(
59 "Hash Color",
60 [](ColorGeometry4f a, int seed) { return noise::hash(noise::hash_float(float4(a)), seed); },
61 exec_preset);
62 static auto fn_hash_int = mf::build::SI2_SO<int, int, int>(
63 "Hash Integer",
64 [](int a, int seed) { return noise::hash(noise::hash(a), seed); },
65 exec_preset);
66 static auto fn_hash_string = mf::build::SI2_SO<std::string, int, int>(
67 "Hash String",
68 [](std::string a, int seed) { return noise::hash(BLI_hash_string(a.c_str()), seed); },
69 exec_preset);
70 static auto fn_hash_rotation = mf::build::SI2_SO<math::Quaternion, int, int>(
71 "Hash Rotation",
72 [](math::Quaternion a, int seed) { return noise::hash(noise::hash_float(float4(a)), seed); },
73 exec_preset);
74 static auto fn_hash_matrix = mf::build::SI2_SO<float4x4, int, int>(
75 "Hash Matrix",
76 [](float4x4 a, int seed) { return noise::hash(noise::hash_float(a), seed); },
77 exec_preset);
78
79 switch (socket_type) {
80 case SOCK_MATRIX:
81 return &fn_hash_matrix;
82 case SOCK_ROTATION:
83 return &fn_hash_rotation;
84 case SOCK_STRING:
85 return &fn_hash_string;
86 case SOCK_FLOAT:
87 return &fn_hash_float;
88 case SOCK_VECTOR:
89 return &fn_hash_vector;
90 case SOCK_RGBA:
91 return &fn_hash_color;
92 case SOCK_INT:
93 return &fn_hash_int;
94 default:
96 return nullptr;
97 }
98}
99
101 public:
105 {
106 bNode &node = params.add_node("FunctionNodeHashValue");
107 node.custom1 = socket_type;
108 params.update_and_connect_available_socket(node, socket_name);
109 }
110};
111
113{
114 const mf::MultiFunction *fn = get_multi_function(builder.node());
115 builder.set_matching_fn(fn);
116}
117
119{
120 eNodeSocketDatatype socket_type = eNodeSocketDatatype(params.other_socket().type);
121 if (!ELEM(socket_type,
124 SOCK_INT,
129 SOCK_RGBA))
130 {
131 return;
132 }
133
134 if (params.in_out() == SOCK_IN) {
135 if (socket_type == SOCK_BOOLEAN) {
136 socket_type = SOCK_INT;
137 }
138 params.add_item(IFACE_("Value"), SocketSearchOp{"Value", socket_type});
139 params.add_item(IFACE_("Seed"), SocketSearchOp{"Seed", SOCK_INT});
140 }
141 else {
142 if (!ELEM(socket_type, SOCK_STRING)) {
143 const int weight = ELEM(params.other_socket().type, SOCK_INT) ? 0 : -1;
144 params.add_item(IFACE_("Hash"), SocketSearchOp{"Hash", SOCK_INT}, weight);
145 }
146 }
147}
148
149static void node_rna(StructRNA *srna)
150{
152 srna,
153 "data_type",
154 "Data Type",
155 "",
158 SOCK_INT,
159 [](bContext * /*C*/, PointerRNA * /*ptr*/, PropertyRNA * /*prop*/, bool *r_free) {
160 *r_free = true;
162 [](const EnumPropertyItem &item) -> bool {
163 return ELEM(item.value,
165 SOCK_INT,
170 SOCK_RGBA);
171 });
172 });
173}
174
175static void node_register()
176{
177 static blender::bke::bNodeType ntype;
178 fn_node_type_base(&ntype, "FunctionNodeHashValue", FN_NODE_HASH_VALUE);
179 ntype.ui_name = "Hash Value";
180 ntype.ui_description = "Generate a randomized integer using the given input value as a seed";
181 ntype.enum_name_legacy = "HASH_VALUE";
183 ntype.declare = node_declare;
184 ntype.initfunc = node_init;
189
190 node_rna(ntype.rna_ext.srna);
191}
193
194} // namespace blender::nodes::node_fn_hash_value_cc
#define NODE_CLASS_CONVERTER
Definition BKE_node.hh:453
#define FN_NODE_HASH_VALUE
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
BLI_INLINE unsigned int BLI_hash_string(const char *str)
Definition BLI_hash.h:67
#define ELEM(...)
#define IFACE_(msgid)
@ SOCK_IN
eNodeSocketDatatype
@ SOCK_INT
@ SOCK_VECTOR
@ SOCK_BOOLEAN
@ SOCK_MATRIX
@ SOCK_FLOAT
@ SOCK_ROTATION
@ SOCK_STRING
@ SOCK_RGBA
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define NOD_inline_enum_accessors(member)
#define UI_ITEM_NONE
static unsigned long seed
Definition btSoftBody.h:39
void set_matching_fn(const mf::MultiFunction *fn)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
QuaternionBase< float > Quaternion
static const mf::MultiFunction * get_multi_function(const bNode &bnode)
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
static void node_init(bNodeTree *, bNode *node)
static void node_declare(NodeDeclarationBuilder &b)
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
static void node_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
static void node_rna(StructRNA *srna)
PropertyRNA * RNA_def_node_enum(StructRNA *srna, const char *identifier, const char *ui_name, const char *ui_description, const EnumPropertyItem *static_items, const EnumRNAAccessors accessors, std::optional< int > default_value, const EnumPropertyItemFunc item_func, const bool allow_animation)
const EnumPropertyItem * enum_items_filter(const EnumPropertyItem *original_item_array, FunctionRef< bool(const EnumPropertyItem &item)> fn)
uint32_t hash_float(float kx)
Definition noise.cc:201
uint32_t hash(uint32_t kx)
Definition noise.cc:90
MatBase< float, 4, 4 > float4x4
VecBase< float, 4 > float4
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
VecBase< float, 3 > float3
void fn_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
const EnumPropertyItem rna_enum_node_socket_data_type_items[]
StructRNA * srna
int16_t custom1
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 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)
PointerRNA * ptr
Definition wm_files.cc:4238