Geometry Nodes: use dynamic declaration for some nodes

This changes a bunch of nodes that have a data type drop-down to using a dynamic
node declaration that changes based on the selected data type instead of always having
all sockets. This greatly simplifies the code and is less weird than having suffixes on
socket identifiers.

Backward compatibility and forward compatibility remain due to #113497 and #113984.

One user-visible change is that changing the data type in these nodes does not break
the link anymore.

It may be necessary to bring back some functionality from link-drag-search afterwards.

Pull Request: https://projects.blender.org/blender/blender/pulls/113553
This commit is contained in:
Iliya Katueshenock
2023-11-17 16:23:34 +01:00
committed by Jacques Lucke
parent a4f086ec1b
commit 8149678d5e
19 changed files with 367 additions and 1264 deletions

View File

@@ -29,7 +29,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 7
#define BLENDER_FILE_SUBVERSION 8
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and cancel loading the file, showing a warning to

View File

@@ -95,6 +95,8 @@
#include "SEQ_sequencer.hh"
#include "SEQ_time.hh"
#include "NOD_socket.hh"
#include "versioning_common.hh"
static CLG_LogRef LOG = {"blo.readfile.doversion"};
@@ -712,11 +714,11 @@ static void version_geometry_nodes_replace_transfer_attribute_node(bNodeTree *nt
sample_nearest_surface->locy = node->locy;
static auto socket_remap = []() {
Map<std::string, std::string> map;
map.add_new("Attribute", "Value_Vector");
map.add_new("Attribute_001", "Value_Float");
map.add_new("Attribute_002", "Value_Color");
map.add_new("Attribute_003", "Value_Bool");
map.add_new("Attribute_004", "Value_Int");
map.add_new("Attribute", "Value");
map.add_new("Attribute_001", "Value");
map.add_new("Attribute_002", "Value");
map.add_new("Attribute_003", "Value");
map.add_new("Attribute_004", "Value");
map.add_new("Source", "Mesh");
map.add_new("Source Position", "Sample Position");
return map;
@@ -769,11 +771,11 @@ static void version_geometry_nodes_replace_transfer_attribute_node(bNodeTree *nt
static auto sample_index_remap = []() {
Map<std::string, std::string> map;
map.add_new("Attribute", "Value_Vector");
map.add_new("Attribute_001", "Value_Float");
map.add_new("Attribute_002", "Value_Color");
map.add_new("Attribute_003", "Value_Bool");
map.add_new("Attribute_004", "Value_Int");
map.add_new("Attribute", "Value");
map.add_new("Attribute_001", "Value");
map.add_new("Attribute_002", "Value");
map.add_new("Attribute_003", "Value");
map.add_new("Attribute_004", "Value");
map.add_new("Source Position", "Sample Position");
return map;
}();
@@ -799,11 +801,11 @@ static void version_geometry_nodes_replace_transfer_attribute_node(bNodeTree *nt
const bool index_was_linked = nodeFindSocket(node, SOCK_IN, "Index")->link != nullptr;
static auto socket_remap = []() {
Map<std::string, std::string> map;
map.add_new("Attribute", "Value_Vector");
map.add_new("Attribute_001", "Value_Float");
map.add_new("Attribute_002", "Value_Color");
map.add_new("Attribute_003", "Value_Bool");
map.add_new("Attribute_004", "Value_Int");
map.add_new("Attribute", "Value");
map.add_new("Attribute_001", "Value");
map.add_new("Attribute_002", "Value");
map.add_new("Attribute_003", "Value");
map.add_new("Attribute_004", "Value");
map.add_new("Source", "Geometry");
map.add_new("Index", "Index");
return map;
@@ -881,16 +883,13 @@ static void version_geometry_nodes_primitive_uv_maps(bNodeTree &ntree)
* releases and would make the file crash when trying to open it. */
storage.data_type = CD_PROP_FLOAT3;
blender::nodes::update_node_declaration_and_sockets(ntree, *store_attribute_node);
bNodeSocket *store_attribute_geometry_input = static_cast<bNodeSocket *>(
store_attribute_node->inputs.first);
bNodeSocket *store_attribute_name_input = store_attribute_geometry_input->next->next;
bNodeSocket *store_attribute_value_input = nullptr;
LISTBASE_FOREACH (bNodeSocket *, socket, &store_attribute_node->inputs) {
if (socket->type == SOCK_VECTOR) {
store_attribute_value_input = socket;
break;
}
}
bNodeSocket *store_attribute_value_input = store_attribute_geometry_input->next->next->next;
BLI_assert(store_attribute_value_input->type == SOCK_VECTOR);
bNodeSocket *store_attribute_geometry_output = static_cast<bNodeSocket *>(
store_attribute_node->outputs.first);
LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
@@ -1017,7 +1016,7 @@ static void version_geometry_nodes_extrude_smooth_propagation(bNodeTree &ntree)
is_smooth_node,
nodeFindSocket(is_smooth_node, SOCK_OUT, "Smooth"),
capture_node,
nodeFindSocket(capture_node, SOCK_IN, "Value_003"));
nodeFindSocket(capture_node, SOCK_IN, "Value"));
nodeAddLink(&ntree,
capture_node,
nodeFindSocket(capture_node, SOCK_OUT, "Geometry"),
@@ -1044,7 +1043,7 @@ static void version_geometry_nodes_extrude_smooth_propagation(bNodeTree &ntree)
}
nodeAddLink(&ntree,
capture_node,
nodeFindSocket(capture_node, SOCK_OUT, "Attribute_003"),
nodeFindSocket(capture_node, SOCK_OUT, "Attribute"),
set_smooth_node,
nodeFindSocket(set_smooth_node, SOCK_IN, "Shade Smooth"));
}

View File

@@ -1237,6 +1237,61 @@ static void enable_geometry_nodes_is_modifier(Main &bmain)
}
}
static void version_socket_identifier_suffixes_for_dynamic_types(
ListBase sockets, const char *separator, const std::optional<int> total = std::nullopt)
{
int index = 0;
LISTBASE_FOREACH (bNodeSocket *, socket, &sockets) {
if (socket->is_available()) {
if (char *pos = strstr(socket->identifier, separator)) {
/* End the identifier at the separator so that the old suffix is ignored. */
*pos = '\0';
if (total.has_value()) {
index++;
if (index == *total) {
return;
}
}
}
}
else {
/* Rename existing identifiers so that they don't conflict with the renamed one. Those will
* be removed after versioning code. */
BLI_strncat(socket->identifier, "_deprecated", sizeof(socket->identifier));
}
}
}
static void versioning_nodes_dynamic_sockets(bNodeTree &ntree)
{
LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
switch (node->type) {
case GEO_NODE_ACCUMULATE_FIELD:
/* This node requires the extra `total` parameter, because the `Group Index` identifier
* also has a space in the name, that should not be treated as separator. */
version_socket_identifier_suffixes_for_dynamic_types(node->inputs, " ", 1);
version_socket_identifier_suffixes_for_dynamic_types(node->outputs, " ", 3);
break;
case GEO_NODE_CAPTURE_ATTRIBUTE:
case GEO_NODE_ATTRIBUTE_STATISTIC:
case GEO_NODE_BLUR_ATTRIBUTE:
case GEO_NODE_EVALUATE_AT_INDEX:
case GEO_NODE_EVALUATE_ON_DOMAIN:
case GEO_NODE_INPUT_NAMED_ATTRIBUTE:
case GEO_NODE_RAYCAST:
case GEO_NODE_SAMPLE_INDEX:
case GEO_NODE_SAMPLE_NEAREST_SURFACE:
case GEO_NODE_SAMPLE_UV_SURFACE:
case GEO_NODE_STORE_NAMED_ATTRIBUTE:
case GEO_NODE_VIEWER:
version_socket_identifier_suffixes_for_dynamic_types(node->inputs, "_");
version_socket_identifier_suffixes_for_dynamic_types(node->outputs, "_");
break;
}
}
}
static void versioning_grease_pencil_stroke_radii_scaling(GreasePencil *grease_pencil)
{
using namespace blender;
@@ -1965,6 +2020,14 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
}
}
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 8)) {
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
if (ntree->type != NTREE_GEOMETRY) {
continue;
}
versioning_nodes_dynamic_sockets(*ntree);
}
}
/**
* Versioning code until next subversion bump goes here.
*

View File

@@ -541,9 +541,15 @@ class NodeDeclarationBuilder {
BaseSocketDeclarationBuilder &add_input(eNodeSocketDatatype socket_type,
StringRef name,
StringRef identifier = "");
BaseSocketDeclarationBuilder &add_input(eCustomDataType data_type,
StringRef name,
StringRef identifier = "");
BaseSocketDeclarationBuilder &add_output(eNodeSocketDatatype socket_type,
StringRef name,
StringRef identifier = "");
BaseSocketDeclarationBuilder &add_output(eCustomDataType data_type,
StringRef name,
StringRef identifier = "");
aal::RelationsInNode &get_anonymous_attribute_relations()
{

View File

@@ -24,59 +24,46 @@ NODE_STORAGE_FUNCS(NodeAccumulateField)
static void node_declare(NodeDeclarationBuilder &b)
{
std::string value_in_description = N_("The values to be accumulated");
std::string leading_out_description = N_(
"The running total of values in the corresponding group, starting at the first value");
std::string trailing_out_description = N_(
"The running total of values in the corresponding group, starting at zero");
std::string total_out_description = N_(
"The total of all of the values in the corresponding group");
const bNode *node = b.node_or_null();
if (node != nullptr) {
const eCustomDataType data_type = eCustomDataType(node_storage(*node).data_type);
BaseSocketDeclarationBuilder *value_declaration = nullptr;
switch (data_type) {
case CD_PROP_FLOAT3:
value_declaration = &b.add_input<decl::Vector>("Value").default_value({1.0f, 1.0f, 1.0f});
break;
case CD_PROP_FLOAT:
value_declaration = &b.add_input<decl::Float>("Value").default_value(1.0f);
break;
case CD_PROP_INT32:
value_declaration = &b.add_input<decl::Int>("Value").default_value(1);
break;
default:
BLI_assert_unreachable();
break;
}
value_declaration->supports_field().description(N_("The values to be accumulated"));
}
b.add_input<decl::Vector>("Value", "Value Vector")
.default_value({1.0f, 1.0f, 1.0f})
.supports_field()
.description(value_in_description);
b.add_input<decl::Float>("Value", "Value Float")
.default_value(1.0f)
.supports_field()
.description(value_in_description);
b.add_input<decl::Int>("Value", "Value Int")
.default_value(1)
.supports_field()
.description(value_in_description);
b.add_input<decl::Int>("Group ID", "Group Index")
.supports_field()
.description("An index used to group values together for multiple separate accumulations");
b.add_output<decl::Vector>("Leading", "Leading Vector")
.field_source_reference_all()
.description(leading_out_description);
b.add_output<decl::Float>("Leading", "Leading Float")
.field_source_reference_all()
.description(leading_out_description);
b.add_output<decl::Int>("Leading", "Leading Int")
.field_source_reference_all()
.description(leading_out_description);
b.add_output<decl::Vector>("Trailing", "Trailing Vector")
.field_source_reference_all()
.description(trailing_out_description);
b.add_output<decl::Float>("Trailing", "Trailing Float")
.field_source_reference_all()
.description(trailing_out_description);
b.add_output<decl::Int>("Trailing", "Trailing Int")
.field_source_reference_all()
.description(trailing_out_description);
b.add_output<decl::Vector>("Total", "Total Vector")
.field_source_reference_all()
.description(total_out_description);
b.add_output<decl::Float>("Total", "Total Float")
.field_source_reference_all()
.description(total_out_description);
b.add_output<decl::Int>("Total", "Total Int")
.field_source_reference_all()
.description(total_out_description);
if (node != nullptr) {
const eCustomDataType data_type = eCustomDataType(node_storage(*node).data_type);
b.add_output(data_type, "Leading")
.field_source_reference_all()
.description(N_("The running total of values in the corresponding group, starting at the "
"first value"));
b.add_output(data_type, "Trailing")
.field_source_reference_all()
.description(
N_("The running total of values in the corresponding group, starting at zero"));
b.add_output(data_type, "Total")
.field_source_reference_all()
.description(N_("The total of all of the values in the corresponding group"));
}
}
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
@@ -93,43 +80,6 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
node->storage = data;
}
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeAccumulateField &storage = node_storage(*node);
const eCustomDataType data_type = eCustomDataType(storage.data_type);
bNodeSocket *sock_in_vector = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *sock_in_float = sock_in_vector->next;
bNodeSocket *sock_in_int = sock_in_float->next;
bNodeSocket *sock_out_vector = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *sock_out_float = sock_out_vector->next;
bNodeSocket *sock_out_int = sock_out_float->next;
bNodeSocket *sock_out_first_vector = sock_out_int->next;
bNodeSocket *sock_out_first_float = sock_out_first_vector->next;
bNodeSocket *sock_out_first_int = sock_out_first_float->next;
bNodeSocket *sock_out_total_vector = sock_out_first_int->next;
bNodeSocket *sock_out_total_float = sock_out_total_vector->next;
bNodeSocket *sock_out_total_int = sock_out_total_float->next;
bke::nodeSetSocketAvailability(ntree, sock_in_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, sock_in_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, sock_in_int, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, sock_out_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, sock_out_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, sock_out_int, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, sock_out_first_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, sock_out_first_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, sock_out_first_int, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, sock_out_total_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, sock_out_total_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, sock_out_total_int, data_type == CD_PROP_INT32);
}
enum class AccumulationMode { Leading = 0, Trailing = 1 };
static std::optional<eCustomDataType> node_type_from_other_socket(const bNodeSocket &socket)
@@ -150,6 +100,9 @@ static std::optional<eCustomDataType> node_type_from_other_socket(const bNodeSoc
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.inputs);
const std::optional<eCustomDataType> type = node_type_from_other_socket(params.other_socket());
if (!type) {
return;
@@ -189,15 +142,6 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
params.update_and_connect_available_socket(node, "Value");
},
0);
params.add_item(
IFACE_("Group ID"),
[type](LinkSearchOpParams &params) {
bNode &node = params.add_node("GeometryNodeAccumulateField");
node_storage(node).data_type = *type;
params.update_and_connect_available_socket(node, "Group Index");
},
-1);
}
}
@@ -395,50 +339,30 @@ class TotalFieldInput final : public bke::GeometryFieldInput {
}
};
template<typename T> std::string identifier_suffix()
{
if constexpr (std::is_same_v<T, int>) {
return "Int";
}
if constexpr (std::is_same_v<T, float>) {
return "Float";
}
if constexpr (std::is_same_v<T, float3>) {
return "Vector";
}
}
static void node_geo_exec(GeoNodeExecParams params)
{
const NodeAccumulateField &storage = node_storage(params.node());
const eCustomDataType data_type = eCustomDataType(storage.data_type);
const eAttrDomain source_domain = eAttrDomain(storage.domain);
Field<int> group_index_field = params.extract_input<Field<int>>("Group Index");
bke::attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
if constexpr (is_same_any_v<T, int, float, float3>) {
const std::string suffix = " " + identifier_suffix<T>();
GField input_field = params.extract_input<GField>("Value" + suffix);
if (params.output_is_required("Leading" + suffix)) {
params.set_output(
"Leading" + suffix,
Field<T>{std::make_shared<AccumulateFieldInput>(
source_domain, input_field, group_index_field, AccumulationMode::Leading)});
}
if (params.output_is_required("Trailing" + suffix)) {
params.set_output(
"Trailing" + suffix,
Field<T>{std::make_shared<AccumulateFieldInput>(
source_domain, input_field, group_index_field, AccumulationMode::Trailing)});
}
if (params.output_is_required("Total" + suffix)) {
params.set_output("Total" + suffix,
Field<T>{std::make_shared<TotalFieldInput>(
source_domain, input_field, group_index_field)});
}
}
});
const Field<int> group_index_field = params.extract_input<Field<int>>("Group Index");
const GField input_field = params.extract_input<GField>("Value");
if (params.output_is_required("Leading")) {
params.set_output<GField>(
"Leading",
GField{std::make_shared<AccumulateFieldInput>(
source_domain, input_field, group_index_field, AccumulationMode::Leading)});
}
if (params.output_is_required("Trailing")) {
params.set_output<GField>(
"Trailing",
GField{std::make_shared<AccumulateFieldInput>(
source_domain, input_field, group_index_field, AccumulationMode::Trailing)});
}
if (params.output_is_required("Total")) {
params.set_output<GField>(
"Total",
GField{std::make_shared<TotalFieldInput>(source_domain, input_field, group_index_field)});
}
}
static void node_rna(StructRNA *srna)
@@ -475,7 +399,6 @@ static void node_register()
geo_node_type_base(&ntype, GEO_NODE_ACCUMULATE_FIELD, "Accumulate Field", NODE_CLASS_CONVERTER);
ntype.geometry_node_execute = node_geo_exec;
ntype.initfunc = node_init;
ntype.updatefunc = node_update;
ntype.draw_buttons = node_layout;
ntype.declare = node_declare;
ntype.gather_link_search_ops = node_gather_link_searches;

View File

@@ -21,21 +21,19 @@ NODE_STORAGE_FUNCS(NodeGeometryAttributeCapture)
static void node_declare(NodeDeclarationBuilder &b)
{
const bNode *node = b.node_or_null();
b.add_input<decl::Geometry>("Geometry");
b.add_input<decl::Vector>("Value").field_on_all();
b.add_input<decl::Float>("Value", "Value_001").field_on_all();
b.add_input<decl::Color>("Value", "Value_002").field_on_all();
b.add_input<decl::Bool>("Value", "Value_003").field_on_all();
b.add_input<decl::Int>("Value", "Value_004").field_on_all();
b.add_input<decl::Rotation>("Value", "Value_005").field_on_all();
if (node != nullptr) {
const eCustomDataType data_type = eCustomDataType(node_storage(*node).data_type);
b.add_input(data_type, "Value").field_on_all();
}
b.add_output<decl::Geometry>("Geometry").propagate_all();
b.add_output<decl::Vector>("Attribute").field_on_all();
b.add_output<decl::Float>("Attribute", "Attribute_001").field_on_all();
b.add_output<decl::Color>("Attribute", "Attribute_002").field_on_all();
b.add_output<decl::Bool>("Attribute", "Attribute_003").field_on_all();
b.add_output<decl::Int>("Attribute", "Attribute_004").field_on_all();
b.add_output<decl::Rotation>("Attribute", "Attribute_005").field_on_all();
if (node != nullptr) {
const eCustomDataType data_type = eCustomDataType(node_storage(*node).data_type);
b.add_output(data_type, "Attribute").field_on_all();
}
}
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
@@ -55,47 +53,11 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
node->storage = data;
}
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryAttributeCapture &storage = node_storage(*node);
const eCustomDataType data_type = eCustomDataType(storage.data_type);
bNodeSocket *socket_value_geometry = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *socket_value_vector = socket_value_geometry->next;
bNodeSocket *socket_value_float = socket_value_vector->next;
bNodeSocket *socket_value_color4f = socket_value_float->next;
bNodeSocket *socket_value_boolean = socket_value_color4f->next;
bNodeSocket *socket_value_int32 = socket_value_boolean->next;
bNodeSocket *socket_value_quat = socket_value_int32->next;
bke::nodeSetSocketAvailability(ntree, socket_value_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, socket_value_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, socket_value_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, socket_value_boolean, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, socket_value_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, socket_value_quat, data_type == CD_PROP_QUATERNION);
bNodeSocket *out_socket_value_geometry = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *out_socket_value_vector = out_socket_value_geometry->next;
bNodeSocket *out_socket_value_float = out_socket_value_vector->next;
bNodeSocket *out_socket_value_color4f = out_socket_value_float->next;
bNodeSocket *out_socket_value_boolean = out_socket_value_color4f->next;
bNodeSocket *out_socket_value_int32 = out_socket_value_boolean->next;
bNodeSocket *out_socket_value_quat = out_socket_value_int32->next;
bke::nodeSetSocketAvailability(ntree, out_socket_value_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, out_socket_value_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, out_socket_value_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, out_socket_value_boolean, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, out_socket_value_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, out_socket_value_quat, data_type == CD_PROP_QUATERNION);
}
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));
search_link_ops_for_declarations(params, declaration.outputs.as_span().take_front(1));
search_link_ops_for_declarations(params, declaration.inputs);
search_link_ops_for_declarations(params, declaration.outputs);
const bNodeType &node_type = params.node_type();
const std::optional<eCustomDataType> type = bke::socket_type_to_custom_data_type(
@@ -147,27 +109,6 @@ static void clean_unused_attributes(const AnonymousAttributePropagationInfo &pro
}
}
static StringRefNull identifier_suffix(eCustomDataType data_type)
{
switch (data_type) {
case CD_PROP_FLOAT:
return "_001";
case CD_PROP_INT32:
return "_004";
case CD_PROP_QUATERNION:
return "_005";
case CD_PROP_COLOR:
return "_002";
case CD_PROP_BOOL:
return "_003";
case CD_PROP_FLOAT3:
return "";
default:
BLI_assert_unreachable();
return "";
}
}
static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
@@ -181,44 +122,17 @@ static void node_geo_exec(GeoNodeExecParams params)
}
const NodeGeometryAttributeCapture &storage = node_storage(params.node());
const eCustomDataType data_type = eCustomDataType(storage.data_type);
const eAttrDomain domain = eAttrDomain(storage.domain);
const std::string output_identifier = "Attribute" + identifier_suffix(data_type);
AnonymousAttributeIDPtr attribute_id = params.get_output_anonymous_attribute_id_if_needed(
output_identifier);
"Attribute");
if (!attribute_id) {
params.set_output("Geometry", geometry_set);
params.set_default_remaining_outputs();
return;
}
const std::string input_identifier = "Value" + identifier_suffix(data_type);
GField field;
switch (data_type) {
case CD_PROP_FLOAT:
field = params.extract_input<GField>(input_identifier);
break;
case CD_PROP_FLOAT3:
field = params.extract_input<GField>(input_identifier);
break;
case CD_PROP_COLOR:
field = params.extract_input<GField>(input_identifier);
break;
case CD_PROP_BOOL:
field = params.extract_input<GField>(input_identifier);
break;
case CD_PROP_INT32:
field = params.extract_input<GField>(input_identifier);
break;
case CD_PROP_QUATERNION:
field = params.extract_input<GField>(input_identifier);
break;
default:
break;
}
const GField field = params.extract_input<GField>("Value");
const auto capture_on = [&](GeometryComponent &component) {
bke::try_capture_field_on_geometry(component, *attribute_id, domain, field);
@@ -284,7 +198,6 @@ static void node_register()
node_free_standard_storage,
node_copy_standard_storage);
ntype.initfunc = node_init;
ntype.updatefunc = node_update;
ntype.declare = node_declare;
ntype.geometry_node_execute = node_geo_exec;
ntype.draw_buttons = node_layout;

View File

@@ -23,28 +23,24 @@ namespace blender::nodes::node_geo_attribute_statistic_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
const bNode *node = b.node_or_null();
b.add_input<decl::Geometry>("Geometry");
b.add_input<decl::Bool>("Selection").default_value(true).field_on_all().hide_value();
b.add_input<decl::Float>("Attribute").hide_value().field_on_all();
b.add_input<decl::Vector>("Attribute", "Attribute_001").hide_value().field_on_all();
b.add_output<decl::Float>("Mean");
b.add_output<decl::Float>("Median");
b.add_output<decl::Float>("Sum");
b.add_output<decl::Float>("Min");
b.add_output<decl::Float>("Max");
b.add_output<decl::Float>("Range");
b.add_output<decl::Float>("Standard Deviation");
b.add_output<decl::Float>("Variance");
if (node != nullptr) {
const eCustomDataType data_type = eCustomDataType(node->custom1);
b.add_input(data_type, "Attribute").hide_value().field_on_all();
b.add_output<decl::Vector>("Mean", "Mean_001");
b.add_output<decl::Vector>("Median", "Median_001");
b.add_output<decl::Vector>("Sum", "Sum_001");
b.add_output<decl::Vector>("Min", "Min_001");
b.add_output<decl::Vector>("Max", "Max_001");
b.add_output<decl::Vector>("Range", "Range_001");
b.add_output<decl::Vector>("Standard Deviation", "Standard Deviation_001");
b.add_output<decl::Vector>("Variance", "Variance_001");
b.add_output(data_type, "Mean");
b.add_output(data_type, "Median");
b.add_output(data_type, "Sum");
b.add_output(data_type, "Min");
b.add_output(data_type, "Max");
b.add_output(data_type, "Range");
b.add_output(data_type, "Standard Deviation");
b.add_output(data_type, "Variance");
}
}
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
@@ -59,54 +55,6 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
node->custom2 = ATTR_DOMAIN_POINT;
}
static void node_update(bNodeTree *ntree, bNode *node)
{
bNodeSocket *socket_geo = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *socket_selection = socket_geo->next;
bNodeSocket *socket_float_attr = socket_selection->next;
bNodeSocket *socket_float3_attr = socket_float_attr->next;
bNodeSocket *socket_float_mean = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *socket_float_median = socket_float_mean->next;
bNodeSocket *socket_float_sum = socket_float_median->next;
bNodeSocket *socket_float_min = socket_float_sum->next;
bNodeSocket *socket_float_max = socket_float_min->next;
bNodeSocket *socket_float_range = socket_float_max->next;
bNodeSocket *socket_float_std = socket_float_range->next;
bNodeSocket *socket_float_variance = socket_float_std->next;
bNodeSocket *socket_vector_mean = socket_float_variance->next;
bNodeSocket *socket_vector_median = socket_vector_mean->next;
bNodeSocket *socket_vector_sum = socket_vector_median->next;
bNodeSocket *socket_vector_min = socket_vector_sum->next;
bNodeSocket *socket_vector_max = socket_vector_min->next;
bNodeSocket *socket_vector_range = socket_vector_max->next;
bNodeSocket *socket_vector_std = socket_vector_range->next;
bNodeSocket *socket_vector_variance = socket_vector_std->next;
const eCustomDataType data_type = eCustomDataType(node->custom1);
bke::nodeSetSocketAvailability(ntree, socket_float_attr, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, socket_float_mean, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, socket_float_median, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, socket_float_sum, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, socket_float_min, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, socket_float_max, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, socket_float_range, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, socket_float_std, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, socket_float_variance, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, socket_float3_attr, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, socket_vector_mean, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, socket_vector_median, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, socket_vector_sum, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, socket_vector_min, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, socket_vector_max, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, socket_vector_range, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, socket_vector_std, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, socket_vector_variance, data_type == CD_PROP_FLOAT3);
}
static std::optional<eCustomDataType> node_type_from_other_socket(const bNodeSocket &socket)
{
switch (socket.type) {
@@ -126,7 +74,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const bNodeType &node_type = params.node_type();
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(2));
search_link_ops_for_declarations(params, declaration.inputs);
const std::optional<eCustomDataType> type = node_type_from_other_socket(params.other_socket());
if (!type) {
@@ -278,7 +226,7 @@ static void node_geo_exec(GeoNodeExecParams params)
break;
}
case CD_PROP_FLOAT3: {
const Field<float3> input_field = params.get_input<Field<float3>>("Attribute_001");
const Field<float3> input_field = params.get_input<Field<float3>>("Attribute");
Vector<float3> data;
for (const GeometryComponent *component : components) {
const std::optional<AttributeAccessor> attributes = component->attributes();
@@ -310,14 +258,14 @@ static void node_geo_exec(GeoNodeExecParams params)
float3 mean{0};
float3 variance{0};
float3 standard_deviation{0};
const bool sort_required = params.output_is_required("Min_001") ||
params.output_is_required("Max_001") ||
params.output_is_required("Range_001") ||
params.output_is_required("Median_001");
const bool sum_required = params.output_is_required("Sum_001") ||
params.output_is_required("Mean_001");
const bool variance_required = params.output_is_required("Standard Deviation_001") ||
params.output_is_required("Variance_001");
const bool sort_required = params.output_is_required("Min") ||
params.output_is_required("Max") ||
params.output_is_required("Range") ||
params.output_is_required("Median");
const bool sum_required = params.output_is_required("Sum") ||
params.output_is_required("Mean");
const bool variance_required = params.output_is_required("Standard Deviation") ||
params.output_is_required("Variance");
Array<float> data_x;
Array<float> data_y;
@@ -364,18 +312,18 @@ static void node_geo_exec(GeoNodeExecParams params)
}
if (sum_required) {
params.set_output("Sum_001", sum);
params.set_output("Mean_001", mean);
params.set_output("Sum", sum);
params.set_output("Mean", mean);
}
if (sort_required) {
params.set_output("Min_001", min);
params.set_output("Max_001", max);
params.set_output("Range_001", range);
params.set_output("Median_001", median);
params.set_output("Min", min);
params.set_output("Max", max);
params.set_output("Range", range);
params.set_output("Median", median);
}
if (variance_required) {
params.set_output("Standard Deviation_001", standard_deviation);
params.set_output("Variance_001", variance);
params.set_output("Standard Deviation", standard_deviation);
params.set_output("Variance", variance);
}
break;
}
@@ -418,9 +366,8 @@ static void node_register()
geo_node_type_base(
&ntype, GEO_NODE_ATTRIBUTE_STATISTIC, "Attribute Statistic", NODE_CLASS_ATTRIBUTE);
ntype.declare = node_declare;
ntype.initfunc = node_init;
ntype.updatefunc = node_update;
ntype.declare = node_declare;
ntype.geometry_node_execute = node_geo_exec;
ntype.draw_buttons = node_layout;
ntype.gather_link_search_ops = node_gather_link_searches;

View File

@@ -36,23 +36,12 @@ namespace blender::nodes::node_geo_blur_attribute_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Float>("Value", "Value_Float")
.supports_field()
.hide_value()
.is_default_link_socket();
b.add_input<decl::Int>("Value", "Value_Int")
.supports_field()
.hide_value()
.is_default_link_socket();
b.add_input<decl::Vector>("Value", "Value_Vector")
.supports_field()
.hide_value()
.is_default_link_socket();
b.add_input<decl::Color>("Value", "Value_Color")
.supports_field()
.hide_value()
.is_default_link_socket();
const bNode *node = b.node_or_null();
if (node != nullptr) {
const eCustomDataType data_type = eCustomDataType(node->custom1);
b.add_input(data_type, "Value").supports_field().hide_value().is_default_link_socket();
}
b.add_input<decl::Int>("Iterations")
.default_value(1)
.min(0)
@@ -65,12 +54,10 @@ static void node_declare(NodeDeclarationBuilder &b)
.supports_field()
.description("Relative mix weight of neighboring elements");
b.add_output<decl::Float>("Value", "Value_Float").field_source_reference_all().dependent_field();
b.add_output<decl::Int>("Value", "Value_Int").field_source_reference_all().dependent_field();
b.add_output<decl::Vector>("Value", "Value_Vector")
.field_source_reference_all()
.dependent_field();
b.add_output<decl::Color>("Value", "Value_Color").field_source_reference_all().dependent_field();
if (node != nullptr) {
const eCustomDataType data_type = eCustomDataType(node->custom1);
b.add_output(data_type, "Value").field_source_reference_all().dependent_field();
}
}
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
@@ -89,7 +76,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
const NodeDeclaration &declaration = *node_type.static_declaration;
/* Weight and Iterations inputs don't change based on the data type. */
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(2));
search_link_ops_for_declarations(params, declaration.inputs);
const std::optional<eCustomDataType> new_node_type = bke::socket_type_to_custom_data_type(
eNodeSocketDatatype(params.other_socket().type));
@@ -115,31 +102,6 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
});
}
static void node_update(bNodeTree *ntree, bNode *node)
{
const eCustomDataType data_type = static_cast<eCustomDataType>(node->custom1);
bNodeSocket *socket_value_float = (bNodeSocket *)node->inputs.first;
bNodeSocket *socket_value_int32 = socket_value_float->next;
bNodeSocket *socket_value_vector = socket_value_int32->next;
bNodeSocket *socket_value_color4f = socket_value_vector->next;
bke::nodeSetSocketAvailability(ntree, socket_value_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, socket_value_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, socket_value_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, socket_value_color4f, data_type == CD_PROP_COLOR);
bNodeSocket *out_socket_value_float = (bNodeSocket *)node->outputs.first;
bNodeSocket *out_socket_value_int32 = out_socket_value_float->next;
bNodeSocket *out_socket_value_vector = out_socket_value_int32->next;
bNodeSocket *out_socket_value_color4f = out_socket_value_vector->next;
bke::nodeSetSocketAvailability(ntree, out_socket_value_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, out_socket_value_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, out_socket_value_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, out_socket_value_color4f, data_type == CD_PROP_COLOR);
}
static void build_vert_to_vert_by_edge_map(const Span<int2> edges,
const int verts_num,
Array<int> &r_offsets,
@@ -494,38 +456,15 @@ class BlurAttributeFieldInput final : public bke::GeometryFieldInput {
}
};
static StringRefNull identifier_suffix(eCustomDataType data_type)
{
switch (data_type) {
case CD_PROP_FLOAT:
return "Float";
case CD_PROP_INT32:
return "Int";
case CD_PROP_COLOR:
return "Color";
case CD_PROP_FLOAT3:
return "Vector";
default:
BLI_assert_unreachable();
return "";
}
}
static void node_geo_exec(GeoNodeExecParams params)
{
const eCustomDataType data_type = static_cast<eCustomDataType>(params.node().custom1);
const int iterations = params.extract_input<int>("Iterations");
Field<float> weight_field = params.extract_input<Field<float>>("Weight");
bke::attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
static const std::string identifier = "Value_" + identifier_suffix(data_type);
Field<T> value_field = params.extract_input<Field<T>>(identifier);
Field<T> output_field{std::make_shared<BlurAttributeFieldInput>(
std::move(weight_field), std::move(value_field), iterations)};
params.set_output(identifier, std::move(output_field));
});
GField value_field = params.extract_input<GField>("Value");
GField output_field{std::make_shared<BlurAttributeFieldInput>(
std::move(weight_field), std::move(value_field), iterations)};
params.set_output<GField>("Value", std::move(output_field));
}
static void node_rna(StructRNA *srna)
@@ -550,9 +489,8 @@ static void node_register()
{
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_BLUR_ATTRIBUTE, "Blur Attribute", NODE_CLASS_ATTRIBUTE);
ntype.declare = node_declare;
ntype.initfunc = node_init;
ntype.updatefunc = node_update;
ntype.declare = node_declare;
ntype.draw_buttons = node_layout;
ntype.geometry_node_execute = node_geo_exec;
ntype.gather_link_search_ops = node_gather_link_searches;

View File

@@ -59,21 +59,15 @@ namespace blender::nodes::node_geo_evaluate_at_index_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
const bNode *node = b.node_or_null();
b.add_input<decl::Int>("Index").min(0).supports_field();
if (node != nullptr) {
const eCustomDataType data_type = eCustomDataType(node->custom2);
b.add_input(data_type, "Value").hide_value().supports_field();
b.add_input<decl::Float>("Value", "Value_Float").hide_value().supports_field();
b.add_input<decl::Int>("Value", "Value_Int").hide_value().supports_field();
b.add_input<decl::Vector>("Value", "Value_Vector").hide_value().supports_field();
b.add_input<decl::Color>("Value", "Value_Color").hide_value().supports_field();
b.add_input<decl::Bool>("Value", "Value_Bool").hide_value().supports_field();
b.add_input<decl::Rotation>("Value", "Value_Rotation").hide_value().supports_field();
b.add_output<decl::Float>("Value", "Value_Float").field_source_reference_all();
b.add_output<decl::Int>("Value", "Value_Int").field_source_reference_all();
b.add_output<decl::Vector>("Value", "Value_Vector").field_source_reference_all();
b.add_output<decl::Color>("Value", "Value_Color").field_source_reference_all();
b.add_output<decl::Bool>("Value", "Value_Bool").field_source_reference_all();
b.add_output<decl::Rotation>("Value", "Value_Rotation").field_source_reference_all();
b.add_output(data_type, "Value").field_source_reference_all();
}
}
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
@@ -88,40 +82,6 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
node->custom2 = CD_PROP_FLOAT;
}
static void node_update(bNodeTree *ntree, bNode *node)
{
const eCustomDataType data_type = eCustomDataType(node->custom2);
bNodeSocket *sock_index = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *sock_in_float = sock_index->next;
bNodeSocket *sock_in_int = sock_in_float->next;
bNodeSocket *sock_in_vector = sock_in_int->next;
bNodeSocket *sock_in_color = sock_in_vector->next;
bNodeSocket *sock_in_bool = sock_in_color->next;
bNodeSocket *sock_in_quat = sock_in_bool->next;
bNodeSocket *sock_out_float = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *sock_out_int = sock_out_float->next;
bNodeSocket *sock_out_vector = sock_out_int->next;
bNodeSocket *sock_out_color = sock_out_vector->next;
bNodeSocket *sock_out_bool = sock_out_color->next;
bNodeSocket *sock_out_quat = sock_out_bool->next;
bke::nodeSetSocketAvailability(ntree, sock_in_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, sock_in_int, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, sock_in_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, sock_in_color, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, sock_in_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, sock_in_quat, data_type == CD_PROP_QUATERNION);
bke::nodeSetSocketAvailability(ntree, sock_out_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, sock_out_int, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, sock_out_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, sock_out_color, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, sock_out_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, sock_out_quat, data_type == CD_PROP_QUATERNION);
}
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const bNodeType &node_type = params.node_type();
@@ -144,42 +104,14 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
}
}
static StringRefNull identifier_suffix(eCustomDataType data_type)
{
switch (data_type) {
case CD_PROP_BOOL:
return "Bool";
case CD_PROP_FLOAT:
return "Float";
case CD_PROP_INT32:
return "Int";
case CD_PROP_COLOR:
return "Color";
case CD_PROP_FLOAT3:
return "Vector";
case CD_PROP_QUATERNION:
return "Rotation";
default:
BLI_assert_unreachable();
return "";
}
}
static void node_geo_exec(GeoNodeExecParams params)
{
const bNode &node = params.node();
const eAttrDomain domain = eAttrDomain(node.custom1);
const eCustomDataType data_type = eCustomDataType(node.custom2);
bke::attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
static const std::string identifier = "Value_" + identifier_suffix(data_type);
Field<T> output_field{
std::make_shared<EvaluateAtIndexInput>(params.extract_input<Field<int>>("Index"),
params.extract_input<Field<T>>(identifier),
domain)};
params.set_output(identifier, std::move(output_field));
});
GField output_field{std::make_shared<EvaluateAtIndexInput>(
params.extract_input<Field<int>>("Index"), params.extract_input<GField>("Value"), domain)};
params.set_output<GField>("Value", std::move(output_field));
}
static void node_rna(StructRNA *srna)
@@ -210,10 +142,9 @@ static void node_register()
geo_node_type_base(
&ntype, GEO_NODE_EVALUATE_AT_INDEX, "Evaluate at Index", NODE_CLASS_CONVERTER);
ntype.geometry_node_execute = node_geo_exec;
ntype.declare = node_declare;
ntype.draw_buttons = node_layout;
ntype.initfunc = node_init;
ntype.updatefunc = node_update;
ntype.declare = node_declare;
ntype.gather_link_search_ops = node_gather_link_searches;
nodeRegisterType(&ntype);

View File

@@ -22,19 +22,14 @@ namespace blender::nodes::node_geo_evaluate_on_domain_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Float>("Value", "Value_Float").supports_field();
b.add_input<decl::Int>("Value", "Value_Int").supports_field();
b.add_input<decl::Vector>("Value", "Value_Vector").supports_field();
b.add_input<decl::Color>("Value", "Value_Color").supports_field();
b.add_input<decl::Bool>("Value", "Value_Bool").supports_field();
b.add_input<decl::Rotation>("Value", "Value_Rotation").supports_field();
const bNode *node = b.node_or_null();
b.add_output<decl::Float>("Value", "Value_Float").field_source_reference_all();
b.add_output<decl::Int>("Value", "Value_Int").field_source_reference_all();
b.add_output<decl::Vector>("Value", "Value_Vector").field_source_reference_all();
b.add_output<decl::Color>("Value", "Value_Color").field_source_reference_all();
b.add_output<decl::Bool>("Value", "Value_Bool").field_source_reference_all();
b.add_output<decl::Rotation>("Value", "Value_Rotation").field_source_reference_all();
if (node != nullptr) {
const eCustomDataType data_type = eCustomDataType(node->custom2);
b.add_input(data_type, "Value").supports_field();
b.add_output(data_type, "Value").field_source_reference_all();
}
}
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
@@ -49,39 +44,6 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
node->custom2 = CD_PROP_FLOAT;
}
static void node_update(bNodeTree *ntree, bNode *node)
{
const eCustomDataType data_type = eCustomDataType(node->custom2);
bNodeSocket *sock_in_float = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *sock_in_int = sock_in_float->next;
bNodeSocket *sock_in_vector = sock_in_int->next;
bNodeSocket *sock_in_color = sock_in_vector->next;
bNodeSocket *sock_in_bool = sock_in_color->next;
bNodeSocket *sock_in_quat = sock_in_bool->next;
bNodeSocket *sock_out_float = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *sock_out_int = sock_out_float->next;
bNodeSocket *sock_out_vector = sock_out_int->next;
bNodeSocket *sock_out_color = sock_out_vector->next;
bNodeSocket *sock_out_bool = sock_out_color->next;
bNodeSocket *sock_out_quat = sock_out_bool->next;
bke::nodeSetSocketAvailability(ntree, sock_in_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, sock_in_int, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, sock_in_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, sock_in_color, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, sock_in_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, sock_in_quat, data_type == CD_PROP_QUATERNION);
bke::nodeSetSocketAvailability(ntree, sock_out_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, sock_out_int, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, sock_out_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, sock_out_color, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, sock_out_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, sock_out_quat, data_type == CD_PROP_QUATERNION);
}
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const bNodeType &node_type = params.node_type();
@@ -163,40 +125,14 @@ class EvaluateOnDomainInput final : public bke::GeometryFieldInput {
}
};
static StringRefNull identifier_suffix(eCustomDataType data_type)
{
switch (data_type) {
case CD_PROP_BOOL:
return "Bool";
case CD_PROP_FLOAT:
return "Float";
case CD_PROP_INT32:
return "Int";
case CD_PROP_COLOR:
return "Color";
case CD_PROP_FLOAT3:
return "Vector";
case CD_PROP_QUATERNION:
return "Rotation";
default:
BLI_assert_unreachable();
return "";
}
}
static void node_geo_exec(GeoNodeExecParams params)
{
const bNode &node = params.node();
const eAttrDomain domain = eAttrDomain(node.custom1);
const eCustomDataType data_type = eCustomDataType(node.custom2);
bke::attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
static const std::string identifier = "Value_" + identifier_suffix(data_type);
Field<T> src_field = params.extract_input<Field<T>>(identifier);
Field<T> dst_field{std::make_shared<EvaluateOnDomainInput>(std::move(src_field), domain)};
params.set_output(identifier, std::move(dst_field));
});
GField src_field = params.extract_input<GField>("Value");
GField dst_field{std::make_shared<EvaluateOnDomainInput>(std::move(src_field), domain)};
params.set_output<GField>("Value", std::move(dst_field));
}
static void node_rna(StructRNA *srna)
@@ -227,10 +163,9 @@ static void node_register()
geo_node_type_base(
&ntype, GEO_NODE_EVALUATE_ON_DOMAIN, "Evaluate on Domain", NODE_CLASS_CONVERTER);
ntype.geometry_node_execute = node_geo_exec;
ntype.declare = node_declare;
ntype.draw_buttons = node_layout;
ntype.initfunc = node_init;
ntype.updatefunc = node_update;
ntype.declare = node_declare;
ntype.gather_link_search_ops = node_gather_link_searches;
nodeRegisterType(&ntype);

View File

@@ -19,15 +19,15 @@ NODE_STORAGE_FUNCS(NodeGeometryInputNamedAttribute)
static void node_declare(NodeDeclarationBuilder &b)
{
const bNode *node = b.node_or_null();
b.add_input<decl::String>("Name").is_attribute_name();
b.add_output<decl::Vector>("Attribute", "Attribute_Vector").field_source();
b.add_output<decl::Float>("Attribute", "Attribute_Float").field_source();
b.add_output<decl::Color>("Attribute", "Attribute_Color").field_source();
b.add_output<decl::Bool>("Attribute", "Attribute_Bool").field_source();
b.add_output<decl::Int>("Attribute", "Attribute_Int").field_source();
b.add_output<decl::Rotation>("Attribute", "Attribute_Rotation").field_source();
if (node != nullptr) {
const NodeGeometryInputNamedAttribute &storage = node_storage(*node);
const eCustomDataType data_type = eCustomDataType(storage.data_type);
b.add_output(data_type, "Attribute").field_source();
}
b.add_output<decl::Bool>("Exists").field_source();
}
@@ -43,26 +43,6 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
node->storage = data;
}
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryInputNamedAttribute &storage = node_storage(*node);
const eCustomDataType data_type = eCustomDataType(storage.data_type);
bNodeSocket *socket_vector = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *socket_float = socket_vector->next;
bNodeSocket *socket_color4f = socket_float->next;
bNodeSocket *socket_boolean = socket_color4f->next;
bNodeSocket *socket_int32 = socket_boolean->next;
bNodeSocket *socket_quat = socket_int32->next;
bke::nodeSetSocketAvailability(ntree, socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, socket_boolean, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, socket_quat, data_type == CD_PROP_QUATERNION);
}
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().static_declaration;
@@ -113,29 +93,9 @@ static void node_geo_exec(GeoNodeExecParams params)
params.used_named_attribute(name, NamedAttributeUsage::Read);
switch (data_type) {
case CD_PROP_FLOAT:
params.set_output("Attribute_Float", AttributeFieldInput::Create<float>(name));
break;
case CD_PROP_FLOAT3:
params.set_output("Attribute_Vector", AttributeFieldInput::Create<float3>(name));
break;
case CD_PROP_COLOR:
params.set_output("Attribute_Color", AttributeFieldInput::Create<ColorGeometry4f>(name));
break;
case CD_PROP_BOOL:
params.set_output("Attribute_Bool", AttributeFieldInput::Create<bool>(name));
break;
case CD_PROP_INT32:
params.set_output("Attribute_Int", AttributeFieldInput::Create<int>(name));
break;
case CD_PROP_QUATERNION:
params.set_output("Attribute_Rotation", AttributeFieldInput::Create<math::Quaternion>(name));
break;
default:
break;
}
const CPPType &type = *bke::custom_data_type_to_cpp_type(data_type);
params.set_output<GField>("Attribute", AttributeFieldInput::Create(name, type));
params.set_output("Exists", bke::AttributeExistsFieldInput::Create(std::move(name)));
}
@@ -157,10 +117,9 @@ static void node_register()
geo_node_type_base(&ntype, GEO_NODE_INPUT_NAMED_ATTRIBUTE, "Named Attribute", NODE_CLASS_INPUT);
ntype.geometry_node_execute = node_geo_exec;
ntype.declare = node_declare;
ntype.draw_buttons = node_layout;
ntype.gather_link_search_ops = node_gather_link_searches;
ntype.updatefunc = node_update;
ntype.declare = node_declare;
ntype.initfunc = node_init;
node_type_storage(&ntype,
"NodeGeometryInputNamedAttribute",

View File

@@ -26,16 +26,16 @@ NODE_STORAGE_FUNCS(NodeGeometryRaycast)
static void node_declare(NodeDeclarationBuilder &b)
{
const bNode *node = b.node_or_null();
b.add_input<decl::Geometry>("Target Geometry")
.only_realized_data()
.supported_type(GeometryComponent::Type::Mesh);
b.add_input<decl::Vector>("Attribute").hide_value().field_on_all();
b.add_input<decl::Float>("Attribute", "Attribute_001").hide_value().field_on_all();
b.add_input<decl::Color>("Attribute", "Attribute_002").hide_value().field_on_all();
b.add_input<decl::Bool>("Attribute", "Attribute_003").hide_value().field_on_all();
b.add_input<decl::Int>("Attribute", "Attribute_004").hide_value().field_on_all();
b.add_input<decl::Rotation>("Attribute", "Attribute_005").hide_value().field_on_all();
if (node != nullptr) {
const eCustomDataType data_type = eCustomDataType(node_storage(*node).data_type);
/* TODO: Field interfacind is depend in offsetd of next declrations! */
b.add_input(data_type, "Attribute").hide_value().field_on_all();
}
b.add_input<decl::Vector>("Source Position").implicit_field(implicit_field_inputs::position);
b.add_input<decl::Vector>("Ray Direction").default_value({0.0f, 0.0f, -1.0f}).supports_field();
@@ -45,17 +45,15 @@ static void node_declare(NodeDeclarationBuilder &b)
.subtype(PROP_DISTANCE)
.supports_field();
b.add_output<decl::Bool>("Is Hit").dependent_field({7, 8, 9});
b.add_output<decl::Vector>("Hit Position").dependent_field({7, 8, 9});
b.add_output<decl::Vector>("Hit Normal").dependent_field({7, 8, 9});
b.add_output<decl::Float>("Hit Distance").dependent_field({7, 8, 9});
b.add_output<decl::Bool>("Is Hit").dependent_field({2, 3, 4});
b.add_output<decl::Vector>("Hit Position").dependent_field({2, 3, 4});
b.add_output<decl::Vector>("Hit Normal").dependent_field({2, 3, 4});
b.add_output<decl::Float>("Hit Distance").dependent_field({2, 3, 4});
b.add_output<decl::Vector>("Attribute").dependent_field({7, 8, 9});
b.add_output<decl::Float>("Attribute", "Attribute_001").dependent_field({7, 8, 9});
b.add_output<decl::Color>("Attribute", "Attribute_002").dependent_field({7, 8, 9});
b.add_output<decl::Bool>("Attribute", "Attribute_003").dependent_field({7, 8, 9});
b.add_output<decl::Int>("Attribute", "Attribute_004").dependent_field({7, 8, 9});
b.add_output<decl::Rotation>("Attribute", "Attribute_005").dependent_field({7, 8, 9});
if (node != nullptr) {
const eCustomDataType data_type = eCustomDataType(node_storage(*node).data_type);
b.add_output(data_type, "Attribute").dependent_field({2, 3, 4});
}
}
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
@@ -72,46 +70,11 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
node->storage = data;
}
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryRaycast &storage = node_storage(*node);
const eCustomDataType data_type = eCustomDataType(storage.data_type);
bNodeSocket *socket_vector = static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 1));
bNodeSocket *socket_float = socket_vector->next;
bNodeSocket *socket_color4f = socket_float->next;
bNodeSocket *socket_boolean = socket_color4f->next;
bNodeSocket *socket_int32 = socket_boolean->next;
bNodeSocket *socket_quat = socket_int32->next;
bke::nodeSetSocketAvailability(ntree, socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, socket_boolean, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, socket_quat, data_type == CD_PROP_QUATERNION);
bNodeSocket *out_socket_vector = static_cast<bNodeSocket *>(BLI_findlink(&node->outputs, 4));
bNodeSocket *out_socket_float = out_socket_vector->next;
bNodeSocket *out_socket_color4f = out_socket_float->next;
bNodeSocket *out_socket_boolean = out_socket_color4f->next;
bNodeSocket *out_socket_int32 = out_socket_boolean->next;
bNodeSocket *out_socket_quat = out_socket_int32->next;
bke::nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, out_socket_boolean, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, out_socket_quat, data_type == CD_PROP_QUATERNION);
}
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(3));
search_link_ops_for_declarations(params, declaration.outputs.as_span().take_front(4));
search_link_ops_for_declarations(params, declaration.inputs);
search_link_ops_for_declarations(params, declaration.outputs);
const std::optional<eCustomDataType> type = bke::socket_type_to_custom_data_type(
eNodeSocketDatatype(params.other_socket().type));
@@ -241,83 +204,11 @@ class RaycastFunction : public mf::MultiFunction {
}
};
static GField get_input_attribute_field(GeoNodeExecParams &params, const eCustomDataType data_type)
{
switch (data_type) {
case CD_PROP_FLOAT:
if (params.output_is_required("Attribute_001")) {
return params.extract_input<GField>("Attribute_001");
}
break;
case CD_PROP_FLOAT3:
if (params.output_is_required("Attribute")) {
return params.extract_input<GField>("Attribute");
}
break;
case CD_PROP_COLOR:
if (params.output_is_required("Attribute_002")) {
return params.extract_input<GField>("Attribute_002");
}
break;
case CD_PROP_BOOL:
if (params.output_is_required("Attribute_003")) {
return params.extract_input<GField>("Attribute_003");
}
break;
case CD_PROP_INT32:
if (params.output_is_required("Attribute_004")) {
return params.extract_input<GField>("Attribute_004");
}
break;
case CD_PROP_QUATERNION:
if (params.output_is_required("Attribute_005")) {
return params.extract_input<GField>("Attribute_005");
}
break;
default:
BLI_assert_unreachable();
}
return {};
}
static void output_attribute_field(GeoNodeExecParams &params, GField field)
{
switch (bke::cpp_type_to_custom_data_type(field.cpp_type())) {
case CD_PROP_FLOAT: {
params.set_output("Attribute_001", field);
break;
}
case CD_PROP_FLOAT3: {
params.set_output("Attribute", field);
break;
}
case CD_PROP_COLOR: {
params.set_output("Attribute_002", field);
break;
}
case CD_PROP_BOOL: {
params.set_output("Attribute_003", field);
break;
}
case CD_PROP_INT32: {
params.set_output("Attribute_004", field);
break;
}
case CD_PROP_QUATERNION: {
params.set_output("Attribute_005", field);
break;
}
default:
break;
}
}
static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet target = params.extract_input<GeometrySet>("Target Geometry");
const NodeGeometryRaycast &storage = node_storage(params.node());
const GeometryNodeRaycastMapMode mapping = GeometryNodeRaycastMapMode(storage.mapping);
const eCustomDataType data_type = eCustomDataType(storage.data_type);
if (target.is_empty()) {
params.set_default_remaining_outputs();
@@ -353,26 +244,30 @@ static void node_geo_exec(GeoNodeExecParams params)
params.set_output("Hit Normal", Field<float3>(op, 2));
params.set_output("Hit Distance", Field<float>(op, 3));
if (GField field = get_input_attribute_field(params, data_type)) {
Field<int> triangle_index(op, 4);
Field<float3> bary_weights;
switch (mapping) {
case GEO_NODE_RAYCAST_INTERPOLATED:
bary_weights = Field<float3>(FieldOperation::Create(
std::make_shared<bke::mesh_surface_sample::BaryWeightFromPositionFn>(target),
{hit_position, triangle_index}));
break;
case GEO_NODE_RAYCAST_NEAREST:
bary_weights = Field<float3>(FieldOperation::Create(
std::make_shared<bke::mesh_surface_sample::CornerBaryWeightFromPositionFn>(target),
{hit_position, triangle_index}));
}
auto sample_op = FieldOperation::Create(
std::make_shared<bke::mesh_surface_sample::BaryWeightSampleFn>(std::move(target),
std::move(field)),
{triangle_index, bary_weights});
output_attribute_field(params, GField(sample_op));
if (!params.output_is_required("Attribute")) {
return;
}
GField field = params.extract_input<GField>("Attribute");
Field<int> triangle_index(op, 4);
Field<float3> bary_weights;
switch (mapping) {
case GEO_NODE_RAYCAST_INTERPOLATED:
bary_weights = Field<float3>(FieldOperation::Create(
std::make_shared<bke::mesh_surface_sample::BaryWeightFromPositionFn>(target),
{hit_position, triangle_index}));
break;
case GEO_NODE_RAYCAST_NEAREST:
bary_weights = Field<float3>(FieldOperation::Create(
std::make_shared<bke::mesh_surface_sample::CornerBaryWeightFromPositionFn>(target),
{hit_position, triangle_index}));
break;
}
auto sample_op = FieldOperation::Create(
std::make_shared<bke::mesh_surface_sample::BaryWeightSampleFn>(std::move(target),
std::move(field)),
{triangle_index, bary_weights});
params.set_output("Attribute", GField(sample_op));
}
static void node_rna(StructRNA *srna)
@@ -415,7 +310,6 @@ static void node_register()
geo_node_type_base(&ntype, GEO_NODE_RAYCAST, "Raycast", NODE_CLASS_GEOMETRY);
bke::node_type_size_preset(&ntype, bke::eNodeSizePreset::MIDDLE);
ntype.initfunc = node_init;
ntype.updatefunc = node_update;
node_type_storage(
&ntype, "NodeGeometryRaycast", node_free_standard_storage, node_copy_standard_storage);
ntype.declare = node_declare;

View File

@@ -54,27 +54,23 @@ NODE_STORAGE_FUNCS(NodeGeometrySampleIndex);
static void node_declare(NodeDeclarationBuilder &b)
{
const bNode *node = b.node_or_null();
b.add_input<decl::Geometry>("Geometry")
.supported_type({GeometryComponent::Type::Mesh,
GeometryComponent::Type::PointCloud,
GeometryComponent::Type::Curve,
GeometryComponent::Type::Instance});
b.add_input<decl::Float>("Value", "Value_Float").hide_value().field_on_all();
b.add_input<decl::Int>("Value", "Value_Int").hide_value().field_on_all();
b.add_input<decl::Vector>("Value", "Value_Vector").hide_value().field_on_all();
b.add_input<decl::Color>("Value", "Value_Color").hide_value().field_on_all();
b.add_input<decl::Bool>("Value", "Value_Bool").hide_value().field_on_all();
b.add_input<decl::Rotation>("Value", "Value_Rotation").hide_value().field_on_all();
if (node != nullptr) {
const eCustomDataType data_type = eCustomDataType(node_storage(*node).data_type);
b.add_input(data_type, "Value").hide_value().field_on_all();
}
b.add_input<decl::Int>("Index").supports_field().description(
"Which element to retrieve a value from on the geometry");
b.add_output<decl::Float>("Value", "Value_Float").dependent_field({7});
b.add_output<decl::Int>("Value", "Value_Int").dependent_field({7});
b.add_output<decl::Vector>("Value", "Value_Vector").dependent_field({7});
b.add_output<decl::Color>("Value", "Value_Color").dependent_field({7});
b.add_output<decl::Bool>("Value", "Value_Bool").dependent_field({7});
b.add_output<decl::Rotation>("Value", "Value_Rotation").dependent_field({7});
if (node != nullptr) {
const eCustomDataType data_type = eCustomDataType(node_storage(*node).data_type);
b.add_output(data_type, "Value").dependent_field({2});
}
}
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
@@ -93,45 +89,10 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
node->storage = data;
}
static void node_update(bNodeTree *ntree, bNode *node)
{
const eCustomDataType data_type = eCustomDataType(node_storage(*node).data_type);
bNodeSocket *in_socket_geometry = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *in_socket_float = in_socket_geometry->next;
bNodeSocket *in_socket_int32 = in_socket_float->next;
bNodeSocket *in_socket_vector = in_socket_int32->next;
bNodeSocket *in_socket_color4f = in_socket_vector->next;
bNodeSocket *in_socket_bool = in_socket_color4f->next;
bNodeSocket *in_socket_quat = in_socket_bool->next;
bke::nodeSetSocketAvailability(ntree, in_socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, in_socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, in_socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, in_socket_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, in_socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, in_socket_quat, data_type == CD_PROP_QUATERNION);
bNodeSocket *out_socket_float = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *out_socket_int32 = out_socket_float->next;
bNodeSocket *out_socket_vector = out_socket_int32->next;
bNodeSocket *out_socket_color4f = out_socket_vector->next;
bNodeSocket *out_socket_bool = out_socket_color4f->next;
bNodeSocket *out_socket_quat = out_socket_bool->next;
bke::nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, out_socket_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, out_socket_quat, data_type == CD_PROP_QUATERNION);
}
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(1));
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));
search_link_ops_for_declarations(params, declaration.inputs);
const std::optional<eCustomDataType> type = bke::socket_type_to_custom_data_type(
eNodeSocketDatatype(params.other_socket().type));
@@ -264,78 +225,23 @@ class SampleIndexFunction : public mf::MultiFunction {
}
};
static GField get_input_attribute_field(GeoNodeExecParams &params, const eCustomDataType data_type)
{
switch (data_type) {
case CD_PROP_FLOAT:
return params.extract_input<GField>("Value_Float");
case CD_PROP_FLOAT3:
return params.extract_input<GField>("Value_Vector");
case CD_PROP_COLOR:
return params.extract_input<GField>("Value_Color");
case CD_PROP_BOOL:
return params.extract_input<GField>("Value_Bool");
case CD_PROP_INT32:
return params.extract_input<GField>("Value_Int");
case CD_PROP_QUATERNION:
return params.extract_input<GField>("Value_Rotation");
default:
BLI_assert_unreachable();
}
return {};
}
static void output_attribute_field(GeoNodeExecParams &params, GField field)
{
switch (bke::cpp_type_to_custom_data_type(field.cpp_type())) {
case CD_PROP_FLOAT: {
params.set_output("Value_Float", field);
break;
}
case CD_PROP_FLOAT3: {
params.set_output("Value_Vector", field);
break;
}
case CD_PROP_COLOR: {
params.set_output("Value_Color", field);
break;
}
case CD_PROP_BOOL: {
params.set_output("Value_Bool", field);
break;
}
case CD_PROP_INT32: {
params.set_output("Value_Int", field);
break;
}
case CD_PROP_QUATERNION: {
params.set_output("Value_Rotation", field);
break;
}
default:
break;
}
}
static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry = params.extract_input<GeometrySet>("Geometry");
const NodeGeometrySampleIndex &storage = node_storage(params.node());
const eCustomDataType data_type = eCustomDataType(storage.data_type);
const eAttrDomain domain = eAttrDomain(storage.domain);
const bool use_clamp = bool(storage.clamp);
GField value_field = get_input_attribute_field(params, data_type);
GField value_field = params.extract_input<GField>("Value");
ValueOrField<int> index_value_or_field = params.extract_input<ValueOrField<int>>("Index");
const CPPType &cpp_type = value_field.cpp_type();
GField output_field;
if (index_value_or_field.is_field()) {
/* If the index is a field, the output has to be a field that still depends on the input. */
auto fn = std::make_shared<SampleIndexFunction>(
std::move(geometry), std::move(value_field), domain, use_clamp);
auto op = FieldOperation::Create(std::move(fn), {index_value_or_field.as_field()});
output_field = GField(std::move(op));
params.set_output("Value", GField(std::move(op)));
}
else if (const GeometryComponent *component = find_source_component(geometry, domain)) {
/* Optimization for the case when the index is a single value. Here only that one index has to
@@ -354,19 +260,17 @@ static void node_geo_exec(GeoNodeExecParams params)
const GVArray &data = evaluator.get_evaluated(0);
BUFFER_FOR_CPP_TYPE_VALUE(cpp_type, buffer);
data.get_to_uninitialized(index, buffer);
output_field = fn::make_constant_field(cpp_type, buffer);
params.set_output("Value", fn::make_constant_field(cpp_type, buffer));
cpp_type.destruct(buffer);
}
else {
output_field = fn::make_constant_field(cpp_type, cpp_type.default_value());
params.set_output("Value", fn::make_constant_field(cpp_type, cpp_type.default_value()));
}
}
else {
/* Output default value if there is no geometry. */
output_field = fn::make_constant_field(cpp_type, cpp_type.default_value());
params.set_output("Value", fn::make_constant_field(cpp_type, cpp_type.default_value()));
}
output_attribute_field(params, std::move(output_field));
}
static void node_register()
@@ -375,7 +279,6 @@ static void node_register()
geo_node_type_base(&ntype, GEO_NODE_SAMPLE_INDEX, "Sample Index", NODE_CLASS_GEOMETRY);
ntype.initfunc = node_init;
ntype.updatefunc = node_update;
ntype.declare = node_declare;
node_type_storage(
&ntype, "NodeGeometrySampleIndex", node_free_standard_storage, node_copy_standard_storage);

View File

@@ -26,23 +26,19 @@ using namespace blender::bke::mesh_surface_sample;
static void node_declare(NodeDeclarationBuilder &b)
{
const bNode *node = b.node_or_null();
b.add_input<decl::Geometry>("Mesh").supported_type(GeometryComponent::Type::Mesh);
b.add_input<decl::Float>("Value", "Value_Float").hide_value().field_on_all();
b.add_input<decl::Int>("Value", "Value_Int").hide_value().field_on_all();
b.add_input<decl::Vector>("Value", "Value_Vector").hide_value().field_on_all();
b.add_input<decl::Color>("Value", "Value_Color").hide_value().field_on_all();
b.add_input<decl::Bool>("Value", "Value_Bool").hide_value().field_on_all();
b.add_input<decl::Rotation>("Value", "Value_Rotation").hide_value().field_on_all();
if (node != nullptr) {
const eCustomDataType data_type = eCustomDataType(node->custom1);
b.add_input(data_type, "Value").hide_value().field_on_all();
}
b.add_input<decl::Vector>("Sample Position").implicit_field(implicit_field_inputs::position);
b.add_output<decl::Float>("Value", "Value_Float").dependent_field({7});
b.add_output<decl::Int>("Value", "Value_Int").dependent_field({7});
b.add_output<decl::Vector>("Value", "Value_Vector").dependent_field({7});
b.add_output<decl::Color>("Value", "Value_Color").dependent_field({7});
b.add_output<decl::Bool>("Value", "Value_Bool").dependent_field({7});
b.add_output<decl::Rotation>("Value", "Value_Rotation").dependent_field({7});
if (node != nullptr) {
const eCustomDataType data_type = eCustomDataType(node->custom1);
b.add_output(data_type, "Value").dependent_field({2});
}
}
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
@@ -55,45 +51,10 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
node->custom1 = CD_PROP_FLOAT;
}
static void node_update(bNodeTree *ntree, bNode *node)
{
const eCustomDataType data_type = eCustomDataType(node->custom1);
bNodeSocket *in_socket_mesh = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *in_socket_float = in_socket_mesh->next;
bNodeSocket *in_socket_int32 = in_socket_float->next;
bNodeSocket *in_socket_vector = in_socket_int32->next;
bNodeSocket *in_socket_color4f = in_socket_vector->next;
bNodeSocket *in_socket_bool = in_socket_color4f->next;
bNodeSocket *in_socket_quat = in_socket_bool->next;
bke::nodeSetSocketAvailability(ntree, in_socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, in_socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, in_socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, in_socket_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, in_socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, in_socket_quat, data_type == CD_PROP_QUATERNION);
bNodeSocket *out_socket_float = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *out_socket_int32 = out_socket_float->next;
bNodeSocket *out_socket_vector = out_socket_int32->next;
bNodeSocket *out_socket_color4f = out_socket_vector->next;
bNodeSocket *out_socket_bool = out_socket_color4f->next;
bNodeSocket *out_socket_quat = out_socket_bool->next;
bke::nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, out_socket_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, out_socket_quat, data_type == CD_PROP_QUATERNION);
}
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(2));
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));
search_link_ops_for_declarations(params, declaration.inputs);
const std::optional<eCustomDataType> type = bke::socket_type_to_custom_data_type(
eNodeSocketDatatype(params.other_socket().type));
@@ -158,63 +119,9 @@ class SampleNearestSurfaceFunction : public mf::MultiFunction {
}
};
static GField get_input_attribute_field(GeoNodeExecParams &params, const eCustomDataType data_type)
{
switch (data_type) {
case CD_PROP_FLOAT:
return params.extract_input<GField>("Value_Float");
case CD_PROP_FLOAT3:
return params.extract_input<GField>("Value_Vector");
case CD_PROP_COLOR:
return params.extract_input<GField>("Value_Color");
case CD_PROP_BOOL:
return params.extract_input<GField>("Value_Bool");
case CD_PROP_INT32:
return params.extract_input<GField>("Value_Int");
case CD_PROP_QUATERNION:
return params.extract_input<GField>("Value_Rotation");
default:
BLI_assert_unreachable();
}
return {};
}
static void output_attribute_field(GeoNodeExecParams &params, GField field)
{
switch (bke::cpp_type_to_custom_data_type(field.cpp_type())) {
case CD_PROP_FLOAT: {
params.set_output("Value_Float", field);
break;
}
case CD_PROP_FLOAT3: {
params.set_output("Value_Vector", field);
break;
}
case CD_PROP_COLOR: {
params.set_output("Value_Color", field);
break;
}
case CD_PROP_BOOL: {
params.set_output("Value_Bool", field);
break;
}
case CD_PROP_INT32: {
params.set_output("Value_Int", field);
break;
}
case CD_PROP_QUATERNION: {
params.set_output("Value_Rotation", field);
break;
}
default:
break;
}
}
static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry = params.extract_input<GeometrySet>("Mesh");
const eCustomDataType data_type = eCustomDataType(params.node().custom1);
const Mesh *mesh = geometry.get_mesh();
if (mesh == nullptr) {
params.set_default_remaining_outputs();
@@ -240,12 +147,12 @@ static void node_geo_exec(GeoNodeExecParams params)
std::make_shared<bke::mesh_surface_sample::BaryWeightFromPositionFn>(geometry),
{nearest_positions, triangle_indices}));
GField field = get_input_attribute_field(params, data_type);
GField field = params.extract_input<GField>("Value");
auto sample_op = FieldOperation::Create(
std::make_shared<bke::mesh_surface_sample::BaryWeightSampleFn>(geometry, std::move(field)),
{triangle_indices, bary_weights});
output_attribute_field(params, GField(sample_op));
params.set_output("Value", GField(sample_op));
}
static void node_rna(StructRNA *srna)
@@ -267,7 +174,6 @@ static void node_register()
geo_node_type_base(
&ntype, GEO_NODE_SAMPLE_NEAREST_SURFACE, "Sample Nearest Surface", NODE_CLASS_GEOMETRY);
ntype.initfunc = node_init;
ntype.updatefunc = node_update;
ntype.declare = node_declare;
blender::bke::node_type_size_preset(&ntype, blender::bke::eNodeSizePreset::MIDDLE);
ntype.geometry_node_execute = node_geo_exec;

View File

@@ -25,15 +25,13 @@ using geometry::ReverseUVSampler;
static void node_declare(NodeDeclarationBuilder &b)
{
const bNode *node = b.node_or_null();
b.add_input<decl::Geometry>("Mesh").supported_type(GeometryComponent::Type::Mesh);
b.add_input<decl::Float>("Value", "Value_Float").hide_value().field_on_all();
b.add_input<decl::Int>("Value", "Value_Int").hide_value().field_on_all();
b.add_input<decl::Vector>("Value", "Value_Vector").hide_value().field_on_all();
b.add_input<decl::Color>("Value", "Value_Color").hide_value().field_on_all();
b.add_input<decl::Bool>("Value", "Value_Bool").hide_value().field_on_all();
b.add_input<decl::Rotation>("Value", "Value_Rotation").hide_value().field_on_all();
if (node != nullptr) {
const eCustomDataType data_type = eCustomDataType(node->custom1);
b.add_input(data_type, "Value").hide_value().field_on_all();
}
b.add_input<decl::Vector>("Source UV Map")
.hide_value()
.field_on_all()
@@ -42,15 +40,12 @@ static void node_declare(NodeDeclarationBuilder &b)
.supports_field()
.description("The coordinates to sample within the UV map");
b.add_output<decl::Float>("Value", "Value_Float").dependent_field({8});
b.add_output<decl::Int>("Value", "Value_Int").dependent_field({8});
b.add_output<decl::Vector>("Value", "Value_Vector").dependent_field({8});
b.add_output<decl::Color>("Value", "Value_Color").dependent_field({8});
b.add_output<decl::Bool>("Value", "Value_Bool").dependent_field({8});
b.add_output<decl::Rotation>("Value", "Value_Rotation").dependent_field({8});
if (node != nullptr) {
const eCustomDataType data_type = eCustomDataType(node->custom1);
b.add_output(data_type, "Value").dependent_field({3});
}
b.add_output<decl::Bool>("Is Valid")
.dependent_field({8})
.dependent_field({3})
.description("Whether the node could find a single face to sample at the UV coordinate");
}
@@ -64,46 +59,11 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
node->custom1 = CD_PROP_FLOAT;
}
static void node_update(bNodeTree *ntree, bNode *node)
{
const eCustomDataType data_type = eCustomDataType(node->custom1);
bNodeSocket *in_socket_mesh = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *in_socket_float = in_socket_mesh->next;
bNodeSocket *in_socket_int32 = in_socket_float->next;
bNodeSocket *in_socket_vector = in_socket_int32->next;
bNodeSocket *in_socket_color4f = in_socket_vector->next;
bNodeSocket *in_socket_bool = in_socket_color4f->next;
bNodeSocket *in_socket_quat = in_socket_bool->next;
bke::nodeSetSocketAvailability(ntree, in_socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, in_socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, in_socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, in_socket_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, in_socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, in_socket_quat, data_type == CD_PROP_QUATERNION);
bNodeSocket *out_socket_float = static_cast<bNodeSocket *>(node->outputs.first);
bNodeSocket *out_socket_int32 = out_socket_float->next;
bNodeSocket *out_socket_vector = out_socket_int32->next;
bNodeSocket *out_socket_color4f = out_socket_vector->next;
bNodeSocket *out_socket_bool = out_socket_color4f->next;
bNodeSocket *out_socket_quat = out_socket_bool->next;
bke::nodeSetSocketAvailability(ntree, out_socket_vector, data_type == CD_PROP_FLOAT3);
bke::nodeSetSocketAvailability(ntree, out_socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(ntree, out_socket_color4f, data_type == CD_PROP_COLOR);
bke::nodeSetSocketAvailability(ntree, out_socket_bool, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, out_socket_quat, data_type == CD_PROP_QUATERNION);
}
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(2));
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));
search_link_ops_for_declarations(params, declaration.outputs.as_span().take_back(1));
search_link_ops_for_declarations(params, declaration.inputs);
search_link_ops_for_declarations(params, declaration.outputs);
const std::optional<eCustomDataType> type = bke::socket_type_to_custom_data_type(
eNodeSocketDatatype(params.other_socket().type));
@@ -184,63 +144,9 @@ class ReverseUVSampleFunction : public mf::MultiFunction {
}
};
static GField get_input_attribute_field(GeoNodeExecParams &params, const eCustomDataType data_type)
{
switch (data_type) {
case CD_PROP_FLOAT:
return params.extract_input<GField>("Value_Float");
case CD_PROP_FLOAT3:
return params.extract_input<GField>("Value_Vector");
case CD_PROP_COLOR:
return params.extract_input<GField>("Value_Color");
case CD_PROP_BOOL:
return params.extract_input<GField>("Value_Bool");
case CD_PROP_INT32:
return params.extract_input<GField>("Value_Int");
case CD_PROP_QUATERNION:
return params.extract_input<GField>("Value_Rotation");
default:
BLI_assert_unreachable();
}
return {};
}
static void output_attribute_field(GeoNodeExecParams &params, GField field)
{
switch (bke::cpp_type_to_custom_data_type(field.cpp_type())) {
case CD_PROP_FLOAT: {
params.set_output("Value_Float", field);
break;
}
case CD_PROP_FLOAT3: {
params.set_output("Value_Vector", field);
break;
}
case CD_PROP_COLOR: {
params.set_output("Value_Color", field);
break;
}
case CD_PROP_BOOL: {
params.set_output("Value_Bool", field);
break;
}
case CD_PROP_INT32: {
params.set_output("Value_Int", field);
break;
}
case CD_PROP_QUATERNION: {
params.set_output("Value_Rotation", field);
break;
}
default:
break;
}
}
static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry = params.extract_input<GeometrySet>("Mesh");
const eCustomDataType data_type = eCustomDataType(params.node().custom1);
const Mesh *mesh = geometry.get_mesh();
if (mesh == nullptr) {
params.set_default_remaining_outputs();
@@ -265,12 +171,13 @@ static void node_geo_exec(GeoNodeExecParams params)
params.set_output("Is Valid", Field<bool>(uv_op, 0));
/* Use the output of the UV sampling to interpolate the mesh attribute. */
GField field = get_input_attribute_field(params, data_type);
GField field = params.extract_input<GField>("Value");
;
auto sample_op = FieldOperation::Create(
std::make_shared<bke::mesh_surface_sample::BaryWeightSampleFn>(std::move(geometry),
std::move(field)),
{Field<int>(uv_op, 1), Field<float3>(uv_op, 2)});
output_attribute_field(params, GField(sample_op, 0));
params.set_output("Value", GField(sample_op, 0));
}
static void node_rna(StructRNA *srna)
@@ -291,7 +198,6 @@ static void node_register()
geo_node_type_base(&ntype, GEO_NODE_SAMPLE_UV_SURFACE, "Sample UV Surface", NODE_CLASS_GEOMETRY);
ntype.initfunc = node_init;
ntype.updatefunc = node_update;
ntype.declare = node_declare;
ntype.geometry_node_execute = node_geo_exec;
ntype.draw_buttons = node_layout;

View File

@@ -27,15 +27,17 @@ NODE_STORAGE_FUNCS(NodeGeometryStoreNamedAttribute)
static void node_declare(NodeDeclarationBuilder &b)
{
const bNode *node = b.node_or_null();
b.add_input<decl::Geometry>("Geometry");
b.add_input<decl::Bool>("Selection").default_value(true).hide_value().field_on_all();
b.add_input<decl::String>("Name").is_attribute_name();
b.add_input<decl::Vector>("Value", "Value_Vector").field_on_all();
b.add_input<decl::Float>("Value", "Value_Float").field_on_all();
b.add_input<decl::Color>("Value", "Value_Color").field_on_all();
b.add_input<decl::Bool>("Value", "Value_Bool").field_on_all();
b.add_input<decl::Int>("Value", "Value_Int").field_on_all();
b.add_input<decl::Rotation>("Value", "Value_Rotation").field_on_all();
if (node != nullptr) {
const NodeGeometryStoreNamedAttribute &storage = node_storage(*node);
const eCustomDataType data_type = eCustomDataType(storage.data_type);
b.add_input(data_type, "Value").field_on_all();
}
b.add_output<decl::Geometry>("Geometry").propagate_all();
}
@@ -56,35 +58,11 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
node->storage = data;
}
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryStoreNamedAttribute &storage = node_storage(*node);
const eCustomDataType data_type = eCustomDataType(storage.data_type);
bNodeSocket *socket_geometry = static_cast<bNodeSocket *>(node->inputs.first);
bNodeSocket *socket_name = socket_geometry->next->next;
bNodeSocket *socket_vector = socket_name->next;
bNodeSocket *socket_float = socket_vector->next;
bNodeSocket *socket_color4f = socket_float->next;
bNodeSocket *socket_boolean = socket_color4f->next;
bNodeSocket *socket_int32 = socket_boolean->next;
bNodeSocket *socket_quat = socket_int32->next;
bke::nodeSetSocketAvailability(
ntree, socket_vector, ELEM(data_type, CD_PROP_FLOAT2, CD_PROP_FLOAT3));
bke::nodeSetSocketAvailability(ntree, socket_float, data_type == CD_PROP_FLOAT);
bke::nodeSetSocketAvailability(
ntree, socket_color4f, ELEM(data_type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR));
bke::nodeSetSocketAvailability(ntree, socket_boolean, data_type == CD_PROP_BOOL);
bke::nodeSetSocketAvailability(ntree, socket_int32, data_type == CD_PROP_INT32);
bke::nodeSetSocketAvailability(ntree, socket_quat, data_type == CD_PROP_QUATERNION);
}
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().static_declaration;
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(2));
search_link_ops_for_declarations(params, declaration.outputs.as_span().take_front(1));
search_link_ops_for_declarations(params, declaration.inputs);
search_link_ops_for_declarations(params, declaration.outputs);
if (params.in_out() == SOCK_IN) {
const std::optional<eCustomDataType> type = bke::socket_type_to_custom_data_type(
@@ -123,39 +101,14 @@ static void node_geo_exec(GeoNodeExecParams params)
const Field<bool> selection = params.extract_input<Field<bool>>("Selection");
GField field;
switch (data_type) {
case CD_PROP_FLOAT:
field = params.extract_input<GField>("Value_Float");
break;
case CD_PROP_FLOAT2: {
field = params.extract_input<GField>("Value_Vector");
field = bke::get_implicit_type_conversions().try_convert(field, CPPType::get<float2>());
break;
}
case CD_PROP_FLOAT3:
field = params.extract_input<GField>("Value_Vector");
break;
case CD_PROP_COLOR:
field = params.extract_input<GField>("Value_Color");
break;
case CD_PROP_BYTE_COLOR: {
field = params.extract_input<GField>("Value_Color");
field = bke::get_implicit_type_conversions().try_convert(field,
CPPType::get<ColorGeometry4b>());
break;
}
case CD_PROP_BOOL:
field = params.extract_input<GField>("Value_Bool");
break;
case CD_PROP_INT32:
field = params.extract_input<GField>("Value_Int");
break;
case CD_PROP_QUATERNION:
field = params.extract_input<GField>("Value_Rotation");
break;
default:
break;
GField field = params.extract_input<GField>("Value");
if (data_type == CD_PROP_FLOAT2) {
field = bke::get_implicit_type_conversions().try_convert(std::move(field),
CPPType::get<float2>());
}
if (data_type == CD_PROP_BYTE_COLOR) {
field = bke::get_implicit_type_conversions().try_convert(std::move(field),
CPPType::get<ColorGeometry4b>());
}
std::atomic<bool> failure = false;
@@ -245,7 +198,6 @@ static void node_register()
node_copy_standard_storage);
blender::bke::node_type_size(&ntype, 140, 100, 700);
ntype.initfunc = node_init;
ntype.updatefunc = node_update;
ntype.declare = node_declare;
ntype.gather_link_search_ops = node_gather_link_searches;
ntype.geometry_node_execute = node_geo_exec;

View File

@@ -23,13 +23,13 @@ NODE_STORAGE_FUNCS(NodeGeometryViewer)
static void node_declare(NodeDeclarationBuilder &b)
{
const bNode *node = b.node_or_null();
b.add_input<decl::Geometry>("Geometry");
b.add_input<decl::Float>("Value").field_on_all().hide_value();
b.add_input<decl::Vector>("Value", "Value_001").field_on_all().hide_value();
b.add_input<decl::Color>("Value", "Value_002").field_on_all().hide_value();
b.add_input<decl::Int>("Value", "Value_003").field_on_all().hide_value();
b.add_input<decl::Bool>("Value", "Value_004").field_on_all().hide_value();
b.add_input<decl::Rotation>("Value", "Value_005").field_on_all().hide_value();
if (node != nullptr) {
const eCustomDataType data_type = eCustomDataType(node_storage(*node).data_type);
b.add_input(data_type, "Value").field_on_all().hide_value();
}
}
static void node_init(bNodeTree * /*tree*/, bNode *node)
@@ -51,41 +51,6 @@ static void node_layout_ex(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
uiItemR(layout, ptr, "data_type", UI_ITEM_NONE, "", ICON_NONE);
}
static eNodeSocketDatatype custom_data_type_to_socket_type(const eCustomDataType type)
{
switch (type) {
case CD_PROP_FLOAT:
return SOCK_FLOAT;
case CD_PROP_INT32:
return SOCK_INT;
case CD_PROP_FLOAT3:
return SOCK_VECTOR;
case CD_PROP_BOOL:
return SOCK_BOOLEAN;
case CD_PROP_COLOR:
return SOCK_RGBA;
case CD_PROP_QUATERNION:
return SOCK_ROTATION;
default:
BLI_assert_unreachable();
return SOCK_FLOAT;
}
}
static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeGeometryViewer &storage = node_storage(*node);
const eCustomDataType data_type = eCustomDataType(storage.data_type);
const eNodeSocketDatatype socket_type = custom_data_type_to_socket_type(data_type);
LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
if (socket->type == SOCK_GEOMETRY) {
continue;
}
bke::nodeSetSocketAvailability(ntree, socket, socket->type == socket_type);
}
}
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
auto set_active_fn = [](LinkSearchOpParams &params, bNode &viewer_node) {
@@ -165,9 +130,8 @@ static void node_register()
geo_node_type_base(&ntype, GEO_NODE_VIEWER, "Viewer", NODE_CLASS_OUTPUT);
node_type_storage(
&ntype, "NodeGeometryViewer", node_free_standard_storage, node_copy_standard_storage);
ntype.updatefunc = node_update;
ntype.initfunc = node_init;
ntype.declare = node_declare;
ntype.initfunc = node_init;
ntype.draw_buttons = node_layout;
ntype.draw_buttons_ex = node_layout_ex;
ntype.gather_link_search_ops = node_gather_link_searches;

View File

@@ -479,6 +479,13 @@ BaseSocketDeclarationBuilder &NodeDeclarationBuilder::add_input(
}
}
BaseSocketDeclarationBuilder &NodeDeclarationBuilder::add_input(const eCustomDataType data_type,
const StringRef name,
const StringRef identifier)
{
return this->add_input(*bke::custom_data_type_to_socket_type(data_type), name, identifier);
}
BaseSocketDeclarationBuilder &NodeDeclarationBuilder::add_output(
const eNodeSocketDatatype socket_type, const StringRef name, const StringRef identifier)
{
@@ -513,6 +520,13 @@ BaseSocketDeclarationBuilder &NodeDeclarationBuilder::add_output(
}
}
BaseSocketDeclarationBuilder &NodeDeclarationBuilder::add_output(const eCustomDataType data_type,
const StringRef name,
const StringRef identifier)
{
return this->add_output(*bke::custom_data_type_to_socket_type(data_type), name, identifier);
}
BaseSocketDeclarationBuilder &BaseSocketDeclarationBuilder::supports_field()
{
if (decl_in_base_) {

View File

@@ -390,62 +390,12 @@ static const char *get_current_socket_identifier_for_future_socket(
}
return get_identifier_from_decl({"False", "True", "Output"}, socket, socket_decls);
}
case GEO_NODE_ACCUMULATE_FIELD: {
return get_identifier_from_decl(
{"Value", "Leading", "Trailing", "Total"}, socket, socket_decls);
}
case GEO_NODE_CAPTURE_ATTRIBUTE: {
return get_identifier_from_decl({"Value", "Attribute"}, socket, socket_decls);
}
case GEO_NODE_ATTRIBUTE_STATISTIC: {
return get_identifier_from_decl({"Attribute",
"Mean",
"Median",
"Sum",
"Min",
"Max",
"Range",
"Standard Deviation",
"Variance"},
socket,
socket_decls);
}
case GEO_NODE_BLUR_ATTRIBUTE: {
return get_identifier_from_decl("Value", socket, socket_decls);
}
case GEO_NODE_SAMPLE_CURVE: {
return get_identifier_from_decl("Value", socket, socket_decls);
}
case GEO_NODE_EVALUATE_AT_INDEX: {
return get_identifier_from_decl("Value", socket, socket_decls);
}
case GEO_NODE_EVALUATE_ON_DOMAIN: {
return get_identifier_from_decl("Value", socket, socket_decls);
}
case GEO_NODE_INPUT_NAMED_ATTRIBUTE: {
return get_identifier_from_decl("Attribute", socket, socket_decls);
}
case GEO_NODE_RAYCAST: {
return get_identifier_from_decl("Attribute", socket, socket_decls);
}
case GEO_NODE_SAMPLE_INDEX: {
return get_identifier_from_decl("Value", socket, socket_decls);
}
case GEO_NODE_SAMPLE_NEAREST_SURFACE: {
return get_identifier_from_decl("Value", socket, socket_decls);
}
case FN_NODE_RANDOM_VALUE: {
return get_identifier_from_decl({"Min", "Max", "Value"}, socket, socket_decls);
}
case GEO_NODE_SAMPLE_UV_SURFACE: {
return get_identifier_from_decl("Value", socket, socket_decls);
}
case GEO_NODE_STORE_NAMED_ATTRIBUTE: {
return get_identifier_from_decl("Value", socket, socket_decls);
}
case GEO_NODE_VIEWER: {
return get_identifier_from_decl("Value", socket, socket_decls);
}
case SH_NODE_MIX: {
return get_identifier_from_decl({"A", "B", "Result"}, socket, socket_decls);
}