Refactoring: Nodes: Dynamic declaration for dynamically-typed nodes #113553
@ -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
|
||||
|
@ -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"));
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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;
|
||||
mod_moder marked this conversation as resolved
Outdated
|
||||
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 ¶ms)
|
||||
{
|
||||
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 ¶ms)
|
||||
params.update_and_connect_available_socket(node, "Value");
|
||||
},
|
||||
0);
|
||||
|
||||
params.add_item(
|
||||
IFACE_("Group ID"),
|
||||
[type](LinkSearchOpParams ¶ms) {
|
||||
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;
|
||||
|
@ -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 ¶ms)
|
||||
{
|
||||
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;
|
||||
|
@ -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 ¶ms)
|
||||
{
|
||||
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;
|
||||
|
@ -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 ¶ms)
|
||||
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 ¶ms)
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -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 ¶ms)
|
||||
{
|
||||
const bNodeType &node_type = params.node_type();
|
||||
@ -144,42 +104,14 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
missing
break
.