Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/nodeitems_builtins.py4
-rw-r--r--source/blender/blenkernel/BKE_node.h3
-rw-r--r--source/blender/blenkernel/intern/node.cc6
-rw-r--r--source/blender/blenloader/intern/versioning_290.c2
-rw-r--r--source/blender/makesdna/DNA_node_types.h5
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c28
-rw-r--r--source/blender/modifiers/intern/MOD_nodes_evaluator.cc4
-rw-r--r--source/blender/nodes/CMakeLists.txt6
-rw-r--r--source/blender/nodes/NOD_function.h4
-rw-r--r--source/blender/nodes/NOD_geometry.h2
-rw-r--r--source/blender/nodes/NOD_static_types.h4
-rw-r--r--source/blender/nodes/function/nodes/legacy/node_fn_random_float.cc (renamed from source/blender/nodes/function/nodes/node_fn_random_float.cc)12
-rw-r--r--source/blender/nodes/function/nodes/node_fn_random_value.cc299
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_randomize.cc (renamed from source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc)26
14 files changed, 376 insertions, 29 deletions
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 715874545a5..e658706a946 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -554,9 +554,10 @@ geometry_node_categories = [
NodeItem("GeometryNodeRealizeInstances", poll=geometry_nodes_fields_poll),
]),
GeometryNodeCategory("GEO_INPUT", "Input", items=[
+ NodeItem("FunctionNodeLegacyRandomFloat", poll=geometry_nodes_fields_legacy_poll),
+
NodeItem("GeometryNodeObjectInfo"),
NodeItem("GeometryNodeCollectionInfo"),
- NodeItem("FunctionNodeRandomFloat"),
NodeItem("ShaderNodeValue"),
NodeItem("FunctionNodeInputString"),
NodeItem("FunctionNodeInputVector"),
@@ -617,6 +618,7 @@ geometry_node_categories = [
NodeItem("FunctionNodeFloatCompare"),
NodeItem("FunctionNodeFloatToInt"),
NodeItem("GeometryNodeSwitch"),
+ NodeItem("FunctionNodeRandomValue", poll=geometry_nodes_fields_poll),
]),
GeometryNodeCategory("GEO_TEXTURE", "Texture", items=[
NodeItem("ShaderNodeTexNoise", poll=geometry_nodes_fields_poll),
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 90285d9fc7c..52f8a3d8136 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1511,7 +1511,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define FN_NODE_BOOLEAN_MATH 1200
#define FN_NODE_FLOAT_COMPARE 1202
-#define FN_NODE_RANDOM_FLOAT 1206
+#define FN_NODE_LEGACY_RANDOM_FLOAT 1206
#define FN_NODE_INPUT_VECTOR 1207
#define FN_NODE_INPUT_STRING 1208
#define FN_NODE_FLOAT_TO_INT 1209
@@ -1519,6 +1519,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define FN_NODE_STRING_LENGTH 1211
#define FN_NODE_STRING_SUBSTRING 1212
#define FN_NODE_INPUT_SPECIAL_CHARACTERS 1213
+#define FN_NODE_RANDOM_VALUE 1214
/** \} */
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index bf7c47e9cf0..c10aa3bbc5a 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -5713,6 +5713,7 @@ static void registerGeometryNodes()
{
register_node_type_geo_group();
+ register_node_type_geo_legacy_attribute_randomize();
register_node_type_geo_legacy_material_assign();
register_node_type_geo_legacy_select_by_material();
@@ -5729,7 +5730,6 @@ static void registerGeometryNodes()
register_node_type_geo_attribute_math();
register_node_type_geo_attribute_mix();
register_node_type_geo_attribute_proximity();
- register_node_type_geo_attribute_randomize();
register_node_type_geo_attribute_remove();
register_node_type_geo_attribute_separate_xyz();
register_node_type_geo_attribute_statistic();
@@ -5810,13 +5810,15 @@ static void registerGeometryNodes()
static void registerFunctionNodes()
{
+ register_node_type_fn_legacy_random_float();
+
register_node_type_fn_boolean_math();
register_node_type_fn_float_compare();
register_node_type_fn_float_to_int();
register_node_type_fn_input_special_characters();
register_node_type_fn_input_string();
register_node_type_fn_input_vector();
- register_node_type_fn_random_float();
+ register_node_type_fn_random_value();
register_node_type_fn_string_length();
register_node_type_fn_string_substring();
register_node_type_fn_value_to_string();
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index be8c4b735be..bf5b0bdbf3c 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -1540,7 +1540,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (STREQ(node->idname, "GeometryNodeRandomAttribute")) {
- STRNCPY(node->idname, "GeometryNodeAttributeRandomize");
+ STRNCPY(node->idname, "GeometryLegacyNodeAttributeRandomize");
}
}
}
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 35a2dba627a..38f38b4ba1e 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1230,6 +1230,11 @@ typedef struct NodeAttributeMix {
uint8_t input_type_b;
} NodeAttributeMix;
+typedef struct NodeRandomValue {
+ /* CustomDataType. */
+ uint8_t data_type;
+} NodeRandomValue;
+
typedef struct NodeAttributeRandomize {
/* CustomDataType. */
uint8_t data_type;
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 333f1584800..1cf0684448d 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -2092,6 +2092,19 @@ static const EnumPropertyItem *rna_GeometryNodeAttributeRandom_type_itemf(
return itemf_function_check(rna_enum_attribute_type_items, attribute_random_type_supported);
}
+static bool random_value_type_supported(const EnumPropertyItem *item)
+{
+ return ELEM(item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3, CD_PROP_BOOL, CD_PROP_INT32);
+}
+static const EnumPropertyItem *rna_FunctionNodeRandomValue_type_itemf(bContext *UNUSED(C),
+ PointerRNA *UNUSED(ptr),
+ PropertyRNA *UNUSED(prop),
+ bool *r_free)
+{
+ *r_free = true;
+ return itemf_function_check(rna_enum_attribute_type_items, random_value_type_supported);
+}
+
static const EnumPropertyItem *rna_GeometryNodeAttributeRandomize_operation_itemf(
bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
{
@@ -9168,6 +9181,21 @@ static void def_geo_subdivision_surface(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
+static void def_fn_random_value(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ RNA_def_struct_sdna_from(srna, "NodeRandomValue", "storage");
+
+ prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "data_type");
+ RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_FunctionNodeRandomValue_type_itemf");
+ RNA_def_property_enum_default(prop, CD_PROP_FLOAT);
+ RNA_def_property_ui_text(prop, "Data Type", "Type of data stored in attribute");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+}
+
static void def_geo_attribute_randomize(StructRNA *srna)
{
PropertyRNA *prop;
diff --git a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
index e50c07ce6f2..9f296f4cfe9 100644
--- a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
+++ b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
@@ -334,6 +334,10 @@ static void get_socket_value(const SocketRef &socket, void *r_value)
std::make_shared<bke::AttributeFieldInput>("position", CPPType::get<float3>()));
return;
}
+ if (bsocket.type == SOCK_INT && bnode.type == FN_NODE_RANDOM_VALUE) {
+ new (r_value) Field<int>(std::make_shared<fn::IndexFieldInput>());
+ return;
+ }
}
const bNodeSocketType *typeinfo = socket.typeinfo();
typeinfo->get_geometry_nodes_cpp_value(*socket.bsocket(), r_value);
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 5056c0889bc..e1cceae2964 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -133,18 +133,21 @@ set(SRC
composite/node_composite_tree.c
composite/node_composite_util.c
+ function/nodes/legacy/node_fn_random_float.cc
+
function/nodes/node_fn_boolean_math.cc
function/nodes/node_fn_float_compare.cc
function/nodes/node_fn_float_to_int.cc
function/nodes/node_fn_input_special_characters.cc
function/nodes/node_fn_input_string.cc
function/nodes/node_fn_input_vector.cc
- function/nodes/node_fn_random_float.cc
+ function/nodes/node_fn_random_value.cc
function/nodes/node_fn_string_length.cc
function/nodes/node_fn_string_substring.cc
function/nodes/node_fn_value_to_string.cc
function/node_function_util.cc
+ geometry/nodes/legacy/node_geo_attribute_randomize.cc
geometry/nodes/legacy/node_geo_material_assign.cc
geometry/nodes/legacy/node_geo_select_by_material.cc
geometry/nodes/legacy/node_geo_point_distribute.cc
@@ -162,7 +165,6 @@ set(SRC
geometry/nodes/node_geo_attribute_math.cc
geometry/nodes/node_geo_attribute_mix.cc
geometry/nodes/node_geo_attribute_proximity.cc
- geometry/nodes/node_geo_attribute_randomize.cc
geometry/nodes/node_geo_attribute_remove.cc
geometry/nodes/node_geo_attribute_sample_texture.cc
geometry/nodes/node_geo_attribute_separate_xyz.cc
diff --git a/source/blender/nodes/NOD_function.h b/source/blender/nodes/NOD_function.h
index b922b36686e..9aa4c04000e 100644
--- a/source/blender/nodes/NOD_function.h
+++ b/source/blender/nodes/NOD_function.h
@@ -20,13 +20,15 @@
extern "C" {
#endif
+void register_node_type_fn_legacy_random_float(void);
+
void register_node_type_fn_boolean_math(void);
void register_node_type_fn_float_compare(void);
void register_node_type_fn_float_to_int(void);
void register_node_type_fn_input_special_characters(void);
void register_node_type_fn_input_string(void);
void register_node_type_fn_input_vector(void);
-void register_node_type_fn_random_float(void);
+void register_node_type_fn_random_value(void);
void register_node_type_fn_string_length(void);
void register_node_type_fn_string_substring(void);
void register_node_type_fn_value_to_string(void);
diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h
index 823c48f71e3..b37d4956e7a 100644
--- a/source/blender/nodes/NOD_geometry.h
+++ b/source/blender/nodes/NOD_geometry.h
@@ -29,6 +29,7 @@ void register_node_tree_type_geo(void);
void register_node_type_geo_group(void);
void register_node_type_geo_custom_group(bNodeType *ntype);
+void register_node_type_geo_legacy_attribute_randomize(void);
void register_node_type_geo_legacy_material_assign(void);
void register_node_type_geo_legacy_select_by_material(void);
@@ -45,7 +46,6 @@ void register_node_type_geo_attribute_map_range(void);
void register_node_type_geo_attribute_math(void);
void register_node_type_geo_attribute_mix(void);
void register_node_type_geo_attribute_proximity(void);
-void register_node_type_geo_attribute_randomize(void);
void register_node_type_geo_attribute_remove(void);
void register_node_type_geo_attribute_separate_xyz(void);
void register_node_type_geo_attribute_statistic(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 6d71cb8d0b6..6af9a7b4e98 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -262,13 +262,15 @@ DefNode(TextureNode, TEX_NODE_PROC+TEX_NOISE, 0, "TEX_NO
DefNode(TextureNode, TEX_NODE_PROC+TEX_STUCCI, 0, "TEX_STUCCI", TexStucci, "Stucci", "" )
DefNode(TextureNode, TEX_NODE_PROC+TEX_DISTNOISE, 0, "TEX_DISTNOISE", TexDistNoise, "Distorted Noise", "" )
+DefNode(FunctionNode, FN_NODE_LEGACY_RANDOM_FLOAT, 0, "LEGACY_RANDOM_FLOAT", LegacyRandomFloat, "Random Float", "")
+
DefNode(FunctionNode, FN_NODE_BOOLEAN_MATH, def_boolean_math, "BOOLEAN_MATH", BooleanMath, "Boolean Math", "")
DefNode(FunctionNode, FN_NODE_FLOAT_COMPARE, def_float_compare, "FLOAT_COMPARE", FloatCompare, "Float Compare", "")
DefNode(FunctionNode, FN_NODE_FLOAT_TO_INT, def_float_to_int, "FLOAT_TO_INT", FloatToInt, "Float to Integer", "")
DefNode(FunctionNode, FN_NODE_INPUT_SPECIAL_CHARACTERS, 0, "INPUT_SPECIAL_CHARACTERS", InputSpecialCharacters, "Special Characters", "")
DefNode(FunctionNode, FN_NODE_INPUT_STRING, def_fn_input_string, "INPUT_STRING", InputString, "String", "")
DefNode(FunctionNode, FN_NODE_INPUT_VECTOR, def_fn_input_vector, "INPUT_VECTOR", InputVector, "Vector", "")
-DefNode(FunctionNode, FN_NODE_RANDOM_FLOAT, 0, "RANDOM_FLOAT", RandomFloat, "Random Float", "")
+DefNode(FunctionNode, FN_NODE_RANDOM_VALUE, def_fn_random_value, "RANDOM_VALUE", RandomValue, "Random Value", "")
DefNode(FunctionNode, FN_NODE_VALUE_TO_STRING, 0, "VALUE_TO_STRING", ValueToString, "Value to String", "")
DefNode(FunctionNode, FN_NODE_STRING_LENGTH, 0, "STRING_LENGTH", StringLength, "String Length", "")
DefNode(FunctionNode, FN_NODE_STRING_SUBSTRING, 0, "STRING_SUBSTRING", StringSubstring, "String Substring", "")
diff --git a/source/blender/nodes/function/nodes/node_fn_random_float.cc b/source/blender/nodes/function/nodes/legacy/node_fn_random_float.cc
index 20f5fa87685..7f6f554ba93 100644
--- a/source/blender/nodes/function/nodes/node_fn_random_float.cc
+++ b/source/blender/nodes/function/nodes/legacy/node_fn_random_float.cc
@@ -20,7 +20,7 @@
namespace blender::nodes {
-static void fn_node_random_float_declare(NodeDeclarationBuilder &b)
+static void fn_node_legacy_random_float_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.add_input<decl::Float>("Min").min(-10000.0f).max(10000.0f);
@@ -68,19 +68,19 @@ class RandomFloatFunction : public blender::fn::MultiFunction {
}
};
-static void fn_node_random_float_build_multi_function(
+static void fn_node_legacy_random_float_build_multi_function(
blender::nodes::NodeMultiFunctionBuilder &builder)
{
static RandomFloatFunction fn;
builder.set_matching_fn(fn);
}
-void register_node_type_fn_random_float()
+void register_node_type_fn_legacy_random_float()
{
static bNodeType ntype;
- fn_node_type_base(&ntype, FN_NODE_RANDOM_FLOAT, "Random Float", 0, 0);
- ntype.declare = blender::nodes::fn_node_random_float_declare;
- ntype.build_multi_function = fn_node_random_float_build_multi_function;
+ fn_node_type_base(&ntype, FN_NODE_LEGACY_RANDOM_FLOAT, "Random Float", 0, 0);
+ ntype.declare = blender::nodes::fn_node_legacy_random_float_declare;
+ ntype.build_multi_function = fn_node_legacy_random_float_build_multi_function;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/function/nodes/node_fn_random_value.cc b/source/blender/nodes/function/nodes/node_fn_random_value.cc
new file mode 100644
index 00000000000..53ca77aab0c
--- /dev/null
+++ b/source/blender/nodes/function/nodes/node_fn_random_value.cc
@@ -0,0 +1,299 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+// #include "BLI_hash.h"
+#include "BLI_noise.hh"
+
+#include "node_function_util.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+namespace blender::nodes {
+
+static void fn_node_random_value_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Vector>("Min").supports_field();
+ b.add_input<decl::Vector>("Max").default_value({1.0f, 1.0f, 1.0f}).supports_field();
+ b.add_input<decl::Float>("Min", "Min_001").supports_field();
+ b.add_input<decl::Float>("Max", "Max_001").default_value(1.0f).supports_field();
+ b.add_input<decl::Int>("Min", "Min_002").min(-100000).max(100000).supports_field();
+ b.add_input<decl::Int>("Max", "Max_002")
+ .default_value(100)
+ .min(-100000)
+ .max(100000)
+ .supports_field();
+ b.add_input<decl::Float>("Probability")
+ .min(0.0f)
+ .max(1.0f)
+ .default_value(0.5f)
+ .subtype(PROP_FACTOR)
+ .supports_field();
+ b.add_input<decl::Int>("ID").implicit_field();
+ b.add_input<decl::Int>("Seed").default_value(0).min(-10000).max(10000).supports_field();
+
+ b.add_output<decl::Vector>("Value").dependent_field();
+ b.add_output<decl::Float>("Value", "Value_001").dependent_field();
+ b.add_output<decl::Int>("Value", "Value_002").dependent_field();
+ b.add_output<decl::Bool>("Value", "Value_003").dependent_field();
+}
+
+static void fn_node_random_value_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
+}
+
+static void fn_node_random_value_init(bNodeTree *UNUSED(tree), bNode *node)
+{
+ NodeRandomValue *data = (NodeRandomValue *)MEM_callocN(sizeof(NodeRandomValue), __func__);
+ data->data_type = CD_PROP_FLOAT;
+ node->storage = data;
+}
+
+static void fn_node_random_value_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ const NodeRandomValue &storage = *(const NodeRandomValue *)node->storage;
+ const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
+
+ bNodeSocket *sock_min_vector = (bNodeSocket *)node->inputs.first;
+ bNodeSocket *sock_max_vector = sock_min_vector->next;
+ bNodeSocket *sock_min_float = sock_max_vector->next;
+ bNodeSocket *sock_max_float = sock_min_float->next;
+ bNodeSocket *sock_min_int = sock_max_float->next;
+ bNodeSocket *sock_max_int = sock_min_int->next;
+ bNodeSocket *sock_probability = sock_max_int->next;
+
+ bNodeSocket *sock_out_vector = (bNodeSocket *)node->outputs.first;
+ bNodeSocket *sock_out_float = sock_out_vector->next;
+ bNodeSocket *sock_out_int = sock_out_float->next;
+ bNodeSocket *sock_out_bool = sock_out_int->next;
+
+ nodeSetSocketAvailability(sock_min_vector, data_type == CD_PROP_FLOAT3);
+ nodeSetSocketAvailability(sock_max_vector, data_type == CD_PROP_FLOAT3);
+ nodeSetSocketAvailability(sock_min_float, data_type == CD_PROP_FLOAT);
+ nodeSetSocketAvailability(sock_max_float, data_type == CD_PROP_FLOAT);
+ nodeSetSocketAvailability(sock_min_int, data_type == CD_PROP_INT32);
+ nodeSetSocketAvailability(sock_max_int, data_type == CD_PROP_INT32);
+ nodeSetSocketAvailability(sock_probability, data_type == CD_PROP_BOOL);
+
+ nodeSetSocketAvailability(sock_out_vector, data_type == CD_PROP_FLOAT3);
+ nodeSetSocketAvailability(sock_out_float, data_type == CD_PROP_FLOAT);
+ nodeSetSocketAvailability(sock_out_int, data_type == CD_PROP_INT32);
+ nodeSetSocketAvailability(sock_out_bool, data_type == CD_PROP_BOOL);
+}
+
+class RandomVectorFunction : public fn::MultiFunction {
+ public:
+ RandomVectorFunction()
+ {
+ static fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static fn::MFSignature create_signature()
+ {
+ fn::MFSignatureBuilder signature{"Random Value"};
+ signature.single_input<float3>("Min");
+ signature.single_input<float3>("Max");
+ signature.single_input<int>("ID");
+ signature.single_input<int>("Seed");
+ signature.single_output<float3>("Value");
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ {
+ const VArray<float3> &min_values = params.readonly_single_input<float3>(0, "Min");
+ const VArray<float3> &max_values = params.readonly_single_input<float3>(1, "Max");
+ const VArray<int> &ids = params.readonly_single_input<int>(2, "ID");
+ const VArray<int> &seeds = params.readonly_single_input<int>(3, "Seed");
+ MutableSpan<float3> values = params.uninitialized_single_output<float3>(4, "Value");
+
+ for (int64_t i : mask) {
+ const float3 min_value = min_values[i];
+ const float3 max_value = max_values[i];
+ const int seed = seeds[i];
+ const int id = ids[i];
+
+ const float x = noise::hash_to_float(seed, id, 0);
+ const float y = noise::hash_to_float(seed, id, 1);
+ const float z = noise::hash_to_float(seed, id, 2);
+
+ values[i] = float3(x, y, z) * (max_value - min_value) + min_value;
+ }
+ }
+};
+
+class RandomFloatFunction : public fn::MultiFunction {
+ public:
+ RandomFloatFunction()
+ {
+ static fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static fn::MFSignature create_signature()
+ {
+ fn::MFSignatureBuilder signature{"Random Value"};
+ signature.single_input<float>("Min");
+ signature.single_input<float>("Max");
+ signature.single_input<int>("ID");
+ signature.single_input<int>("Seed");
+ signature.single_output<float>("Value");
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ {
+ const VArray<float> &min_values = params.readonly_single_input<float>(0, "Min");
+ const VArray<float> &max_values = params.readonly_single_input<float>(1, "Max");
+ const VArray<int> &ids = params.readonly_single_input<int>(2, "ID");
+ const VArray<int> &seeds = params.readonly_single_input<int>(3, "Seed");
+ MutableSpan<float> values = params.uninitialized_single_output<float>(4, "Value");
+
+ for (int64_t i : mask) {
+ const float min_value = min_values[i];
+ const float max_value = max_values[i];
+ const int seed = seeds[i];
+ const int id = ids[i];
+
+ const float value = noise::hash_to_float(seed, id);
+ values[i] = value * (max_value - min_value) + min_value;
+ }
+ }
+};
+
+class RandomIntFunction : public fn::MultiFunction {
+ public:
+ RandomIntFunction()
+ {
+ static fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static fn::MFSignature create_signature()
+ {
+ fn::MFSignatureBuilder signature{"Random Value"};
+ signature.single_input<int>("Min");
+ signature.single_input<int>("Max");
+ signature.single_input<int>("ID");
+ signature.single_input<int>("Seed");
+ signature.single_output<int>("Value");
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ {
+ const VArray<int> &min_values = params.readonly_single_input<int>(0, "Min");
+ const VArray<int> &max_values = params.readonly_single_input<int>(1, "Max");
+ const VArray<int> &ids = params.readonly_single_input<int>(2, "ID");
+ const VArray<int> &seeds = params.readonly_single_input<int>(3, "Seed");
+ MutableSpan<int> values = params.uninitialized_single_output<int>(4, "Value");
+
+ for (int64_t i : mask) {
+ const float min_value = min_values[i];
+ const float max_value = max_values[i];
+ const int seed = seeds[i];
+ const int id = ids[i];
+
+ const float value = noise::hash_to_float(id, seed);
+ values[i] = round_fl_to_int(value * (max_value - min_value) + min_value);
+ }
+ }
+};
+
+class RandomBoolFunction : public fn::MultiFunction {
+ public:
+ RandomBoolFunction()
+ {
+ static fn::MFSignature signature = create_signature();
+ this->set_signature(&signature);
+ }
+
+ static fn::MFSignature create_signature()
+ {
+ fn::MFSignatureBuilder signature{"Random Value"};
+ signature.single_input<float>("Probability");
+ signature.single_input<int>("ID");
+ signature.single_input<int>("Seed");
+ signature.single_output<bool>("Value");
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ {
+ const VArray<float> &probabilities = params.readonly_single_input<float>(0, "Probability");
+ const VArray<int> &ids = params.readonly_single_input<int>(1, "ID");
+ const VArray<int> &seeds = params.readonly_single_input<int>(2, "Seed");
+ MutableSpan<bool> values = params.uninitialized_single_output<bool>(3, "Value");
+
+ for (int64_t i : mask) {
+ const int seed = seeds[i];
+ const int id = ids[i];
+ const float probability = probabilities[i];
+ values[i] = noise::hash_to_float(id, seed) <= probability;
+ }
+ }
+};
+
+static void fn_node_random_value_build_multi_function(NodeMultiFunctionBuilder &builder)
+{
+ const NodeRandomValue &storage = *(const NodeRandomValue *)builder.node().storage;
+ const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
+
+ switch (data_type) {
+ case CD_PROP_FLOAT3: {
+ static RandomVectorFunction fn;
+ builder.set_matching_fn(fn);
+ break;
+ }
+ case CD_PROP_FLOAT: {
+ static RandomFloatFunction fn;
+ builder.set_matching_fn(fn);
+ break;
+ }
+ case CD_PROP_INT32: {
+ static RandomIntFunction fn;
+ builder.set_matching_fn(fn);
+ break;
+ }
+ case CD_PROP_BOOL: {
+ static RandomBoolFunction fn;
+ builder.set_matching_fn(fn);
+ break;
+ }
+ default: {
+ BLI_assert_unreachable();
+ break;
+ }
+ }
+}
+
+} // namespace blender::nodes
+
+void register_node_type_fn_random_value()
+{
+ static bNodeType ntype;
+ fn_node_type_base(&ntype, FN_NODE_RANDOM_VALUE, "Random Value", NODE_CLASS_CONVERTER, 0);
+ node_type_init(&ntype, blender::nodes::fn_node_random_value_init);
+ node_type_update(&ntype, blender::nodes::fn_node_random_value_update);
+ ntype.draw_buttons = blender::nodes::fn_node_random_value_layout;
+ ntype.declare = blender::nodes::fn_node_random_value_declare;
+ ntype.build_multi_function = blender::nodes::fn_node_random_value_build_multi_function;
+ node_type_storage(
+ &ntype, "NodeRandomValue", node_free_standard_storage, node_copy_standard_storage);
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_randomize.cc
index 60b9910399c..2e6ba456725 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_randomize.cc
@@ -25,7 +25,7 @@
namespace blender::nodes {
-static void geo_node_attribute_randomize_declare(NodeDeclarationBuilder &b)
+static void geo_node_legacy_attribute_randomize_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Geometry");
b.add_input<decl::String>("Attribute");
@@ -39,15 +39,15 @@ static void geo_node_attribute_randomize_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>("Geometry");
}
-static void geo_node_attribute_random_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void geo_node_legacy_attribute_random_layout(uiLayout *layout,
+ bContext *UNUSED(C),
+ PointerRNA *ptr)
{
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
}
-static void geo_node_attribute_randomize_init(bNodeTree *UNUSED(tree), bNode *node)
+static void geo_node_legacy_attribute_randomize_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeAttributeRandomize *data = (NodeAttributeRandomize *)MEM_callocN(
sizeof(NodeAttributeRandomize), __func__);
@@ -57,7 +57,7 @@ static void geo_node_attribute_randomize_init(bNodeTree *UNUSED(tree), bNode *no
node->storage = data;
}
-static void geo_node_attribute_randomize_update(bNodeTree *UNUSED(ntree), bNode *node)
+static void geo_node_legacy_attribute_randomize_update(bNodeTree *UNUSED(ntree), bNode *node)
{
bNodeSocket *sock_min_vector = (bNodeSocket *)BLI_findlink(&node->inputs, 2);
bNodeSocket *sock_max_vector = sock_min_vector->next;
@@ -280,7 +280,7 @@ static void randomize_attribute_on_component(GeometryComponent &component,
attribute.save();
}
-static void geo_node_random_attribute_exec(GeoNodeExecParams params)
+static void geo_node_legacy_random_attribute_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
const std::string attribute_name = params.get_input<std::string>("Attribute");
@@ -326,18 +326,18 @@ static void geo_node_random_attribute_exec(GeoNodeExecParams params)
} // namespace blender::nodes
-void register_node_type_geo_attribute_randomize()
+void register_node_type_geo_legacy_attribute_randomize()
{
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_LEGACY_ATTRIBUTE_RANDOMIZE, "Attribute Randomize", NODE_CLASS_ATTRIBUTE, 0);
- node_type_init(&ntype, blender::nodes::geo_node_attribute_randomize_init);
- node_type_update(&ntype, blender::nodes::geo_node_attribute_randomize_update);
+ node_type_init(&ntype, blender::nodes::geo_node_legacy_attribute_randomize_init);
+ node_type_update(&ntype, blender::nodes::geo_node_legacy_attribute_randomize_update);
- ntype.declare = blender::nodes::geo_node_attribute_randomize_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_random_attribute_exec;
- ntype.draw_buttons = blender::nodes::geo_node_attribute_random_layout;
+ ntype.declare = blender::nodes::geo_node_legacy_attribute_randomize_declare;
+ ntype.geometry_node_execute = blender::nodes::geo_node_legacy_random_attribute_exec;
+ ntype.draw_buttons = blender::nodes::geo_node_legacy_attribute_random_layout;
node_type_storage(
&ntype, "NodeAttributeRandomize", node_free_standard_storage, node_copy_standard_storage);
nodeRegisterType(&ntype);