Geometry Nodes: use dynamic declaration for switch node #113413
|
@ -1768,6 +1768,17 @@ static void versioning_nodes_dynamic_sockets(bNodeTree &ntree)
|
|||
}
|
||||
}
|
||||
|
||||
static void versioning_switch_node_dynamic_socket(bNodeTree &ntree)
|
||||
{
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
|
||||
if (node->type != GEO_NODE_SWITCH) {
|
||||
continue;
|
||||
}
|
||||
version_socket_identifier_suffixes_for_dynamic_types(node->inputs, "_");
|
||||
version_socket_identifier_suffixes_for_dynamic_types(node->outputs, "_");
|
||||
}
|
||||
}
|
||||
|
||||
static void versioning_grease_pencil_stroke_radii_scaling(GreasePencil *grease_pencil)
|
||||
{
|
||||
using namespace blender;
|
||||
|
@ -2578,6 +2589,7 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
|||
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
|
||||
if (ntree->type == NTREE_GEOMETRY) {
|
||||
version_geometry_nodes_use_rotation_socket(*ntree);
|
||||
versioning_switch_node_dynamic_socket(*ntree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,55 +19,27 @@ NODE_STORAGE_FUNCS(NodeSwitch)
|
|||
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::Bool>("Switch").default_value(false).supports_field();
|
||||
b.add_input<decl::Bool>("Switch", "Switch_001").default_value(false);
|
||||
auto &switch_decl = b.add_input<decl::Bool>("Switch");
|
||||
const bNode *node = b.node_or_null();
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
const NodeSwitch &storage = node_storage(*node);
|
||||
const eNodeSocketDatatype socket_type = eNodeSocketDatatype(storage.input_type);
|
||||
|
||||
b.add_input<decl::Float>("False").supports_field();
|
||||
b.add_input<decl::Float>("True").supports_field();
|
||||
b.add_input<decl::Int>("False", "False_001").min(-100000).max(100000).supports_field();
|
||||
b.add_input<decl::Int>("True", "True_001").min(-100000).max(100000).supports_field();
|
||||
b.add_input<decl::Bool>("False", "False_002").default_value(false).hide_value().supports_field();
|
||||
b.add_input<decl::Bool>("True", "True_002").default_value(true).hide_value().supports_field();
|
||||
b.add_input<decl::Vector>("False", "False_003").supports_field();
|
||||
b.add_input<decl::Vector>("True", "True_003").supports_field();
|
||||
auto &false_decl = b.add_input(socket_type, "False");
|
||||
auto &true_decl = b.add_input(socket_type, "True");
|
||||
auto &output_decl = b.add_output(socket_type, "Output");
|
||||
|
||||
b.add_input<decl::Color>("False", "False_004")
|
||||
.default_value({0.8f, 0.8f, 0.8f, 1.0f})
|
||||
.supports_field();
|
||||
b.add_input<decl::Color>("True", "True_004")
|
||||
.default_value({0.8f, 0.8f, 0.8f, 1.0f})
|
||||
.supports_field();
|
||||
b.add_input<decl::String>("False", "False_005").supports_field();
|
||||
b.add_input<decl::String>("True", "True_005").supports_field();
|
||||
|
||||
b.add_input<decl::Geometry>("False", "False_006");
|
||||
b.add_input<decl::Geometry>("True", "True_006");
|
||||
b.add_input<decl::Object>("False", "False_007");
|
||||
b.add_input<decl::Object>("True", "True_007");
|
||||
b.add_input<decl::Collection>("False", "False_008");
|
||||
b.add_input<decl::Collection>("True", "True_008");
|
||||
b.add_input<decl::Texture>("False", "False_009");
|
||||
b.add_input<decl::Texture>("True", "True_009");
|
||||
b.add_input<decl::Material>("False", "False_010");
|
||||
b.add_input<decl::Material>("True", "True_010");
|
||||
b.add_input<decl::Image>("False", "False_011");
|
||||
b.add_input<decl::Image>("True", "True_011");
|
||||
b.add_input<decl::Rotation>("False", "False_012").supports_field();
|
||||
b.add_input<decl::Rotation>("True", "True_012").supports_field();
|
||||
|
||||
b.add_output<decl::Float>("Output").dependent_field().reference_pass_all();
|
||||
b.add_output<decl::Int>("Output", "Output_001").dependent_field().reference_pass_all();
|
||||
b.add_output<decl::Bool>("Output", "Output_002").dependent_field().reference_pass_all();
|
||||
b.add_output<decl::Vector>("Output", "Output_003").dependent_field().reference_pass_all();
|
||||
b.add_output<decl::Color>("Output", "Output_004").dependent_field().reference_pass_all();
|
||||
b.add_output<decl::String>("Output", "Output_005").dependent_field().reference_pass_all();
|
||||
b.add_output<decl::Geometry>("Output", "Output_006").propagate_all();
|
||||
b.add_output<decl::Object>("Output", "Output_007");
|
||||
b.add_output<decl::Collection>("Output", "Output_008");
|
||||
b.add_output<decl::Texture>("Output", "Output_009");
|
||||
b.add_output<decl::Material>("Output", "Output_010");
|
||||
b.add_output<decl::Image>("Output", "Output_011");
|
||||
b.add_output<decl::Rotation>("Output", "Output_012").propagate_all().reference_pass_all();
|
||||
if (socket_type_supports_fields(socket_type)) {
|
||||
switch_decl.supports_field();
|
||||
false_decl.supports_field();
|
||||
true_decl.supports_field();
|
||||
output_decl.dependent_field().reference_pass_all();
|
||||
}
|
||||
if (socket_type == SOCK_GEOMETRY) {
|
||||
output_decl.propagate_all();
|
||||
}
|
||||
}
|
||||
|
||||
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
|
||||
|
@ -82,37 +54,6 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
|
|||
node->storage = data;
|
||||
}
|
||||
|
||||
static void node_update(bNodeTree *ntree, bNode *node)
|
||||
{
|
||||
const NodeSwitch &storage = node_storage(*node);
|
||||
int index = 0;
|
||||
bNodeSocket *field_switch = static_cast<bNodeSocket *>(node->inputs.first);
|
||||
bNodeSocket *non_field_switch = static_cast<bNodeSocket *>(field_switch->next);
|
||||
|
||||
const bool fields_type = ELEM(storage.input_type,
|
||||
SOCK_FLOAT,
|
||||
SOCK_INT,
|
||||
SOCK_BOOLEAN,
|
||||
SOCK_VECTOR,
|
||||
SOCK_RGBA,
|
||||
SOCK_STRING,
|
||||
SOCK_ROTATION);
|
||||
|
||||
bke::nodeSetSocketAvailability(ntree, field_switch, fields_type);
|
||||
bke::nodeSetSocketAvailability(ntree, non_field_switch, !fields_type);
|
||||
|
||||
LISTBASE_FOREACH_INDEX (bNodeSocket *, socket, &node->inputs, index) {
|
||||
if (index <= 1) {
|
||||
continue;
|
||||
}
|
||||
bke::nodeSetSocketAvailability(ntree, socket, socket->type == storage.input_type);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
|
||||
bke::nodeSetSocketAvailability(ntree, socket, socket->type == storage.input_type);
|
||||
}
|
||||
}
|
||||
|
||||
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
mod_moder marked this conversation as resolved
|
||||
if (params.in_out() == SOCK_OUT) {
|
||||
|
@ -297,7 +238,6 @@ static void node_rna(StructRNA *srna)
|
|||
SOCK_GEOMETRY,
|
||||
SOCK_OBJECT,
|
||||
SOCK_COLLECTION,
|
||||
SOCK_TEXTURE,
|
||||
SOCK_MATERIAL,
|
||||
SOCK_IMAGE);
|
||||
});
|
||||
|
@ -311,7 +251,6 @@ static void register_node()
|
|||
geo_node_type_base(&ntype, GEO_NODE_SWITCH, "Switch", NODE_CLASS_CONVERTER);
|
||||
ntype.declare = node_declare;
|
||||
ntype.initfunc = node_init;
|
||||
ntype.updatefunc = node_update;
|
||||
node_type_storage(&ntype, "NodeSwitch", node_free_standard_storage, node_copy_standard_storage);
|
||||
ntype.gather_link_search_ops = node_gather_link_searches;
|
||||
ntype.draw_buttons = node_layout;
|
||||
|
|
|
@ -3524,73 +3524,43 @@ struct GeometryNodesLazyFunctionBuilder {
|
|||
lf::FunctionNode &lf_node = graph_params.lf_graph.add_function(*lazy_function);
|
||||
scope_.add(std::move(lazy_function));
|
||||
|
||||
int input_index = 0;
|
||||
for (const bNodeSocket *bsocket : bnode.input_sockets()) {
|
||||
if (bsocket->is_available()) {
|
||||
lf::InputSocket &lf_socket = lf_node.input(input_index);
|
||||
graph_params.lf_inputs_by_bsocket.add(bsocket, &lf_socket);
|
||||
mapping_->bsockets_by_lf_socket_map.add(&lf_socket, bsocket);
|
||||
input_index++;
|
||||
}
|
||||
}
|
||||
for (const bNodeSocket *bsocket : bnode.output_sockets()) {
|
||||
if (bsocket->is_available()) {
|
||||
lf::OutputSocket &lf_socket = lf_node.output(0);
|
||||
graph_params.lf_output_by_bsocket.add(bsocket, &lf_socket);
|
||||
mapping_->bsockets_by_lf_socket_map.add(&lf_socket, bsocket);
|
||||
break;
|
||||
}
|
||||
for (const int i : bnode.input_sockets().index_range()) {
|
||||
graph_params.lf_inputs_by_bsocket.add(&bnode.input_socket(i), &lf_node.input(i));
|
||||
mapping_->bsockets_by_lf_socket_map.add(&lf_node.input(i), &bnode.input_socket(i));
|
||||
}
|
||||
|
||||
graph_params.lf_output_by_bsocket.add(&bnode.output_socket(0), &lf_node.output(0));
|
||||
mapping_->bsockets_by_lf_socket_map.add(&lf_node.output(0), &bnode.output_socket(0));
|
||||
|
||||
this->build_switch_node_socket_usage(bnode, graph_params);
|
||||
}
|
||||
|
||||
void build_switch_node_socket_usage(const bNode &bnode, BuildGraphParams &graph_params)
|
||||
{
|
||||
const bNodeSocket *switch_input_bsocket = nullptr;
|
||||
const bNodeSocket *false_input_bsocket = nullptr;
|
||||
const bNodeSocket *true_input_bsocket = nullptr;
|
||||
const bNodeSocket *output_bsocket = nullptr;
|
||||
for (const bNodeSocket *socket : bnode.input_sockets()) {
|
||||
if (!socket->is_available()) {
|
||||
continue;
|
||||
}
|
||||
if (socket->name == StringRef("Switch")) {
|
||||
switch_input_bsocket = socket;
|
||||
}
|
||||
else if (socket->name == StringRef("False")) {
|
||||
false_input_bsocket = socket;
|
||||
}
|
||||
else if (socket->name == StringRef("True")) {
|
||||
true_input_bsocket = socket;
|
||||
}
|
||||
}
|
||||
for (const bNodeSocket *socket : bnode.output_sockets()) {
|
||||
if (socket->is_available()) {
|
||||
output_bsocket = socket;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const bNodeSocket &switch_input_bsocket = bnode.input_socket(0);
|
||||
const bNodeSocket &false_input_bsocket = bnode.input_socket(1);
|
||||
const bNodeSocket &true_input_bsocket = bnode.input_socket(2);
|
||||
const bNodeSocket &output_bsocket = bnode.output_socket(0);
|
||||
lf::OutputSocket *output_is_used_socket = graph_params.usage_by_bsocket.lookup_default(
|
||||
output_bsocket, nullptr);
|
||||
&output_bsocket, nullptr);
|
||||
if (output_is_used_socket == nullptr) {
|
||||
return;
|
||||
}
|
||||
graph_params.usage_by_bsocket.add(switch_input_bsocket, output_is_used_socket);
|
||||
if (switch_input_bsocket->is_directly_linked()) {
|
||||
graph_params.usage_by_bsocket.add(&switch_input_bsocket, output_is_used_socket);
|
||||
if (switch_input_bsocket.is_directly_linked()) {
|
||||
/* The condition input is dynamic, so the usage of the other inputs is as well. */
|
||||
static const LazyFunctionForSwitchSocketUsage switch_socket_usage_fn;
|
||||
lf::Node &lf_node = graph_params.lf_graph.add_function(switch_socket_usage_fn);
|
||||
graph_params.lf_inputs_by_bsocket.add(switch_input_bsocket, &lf_node.input(0));
|
||||
graph_params.usage_by_bsocket.add(false_input_bsocket, &lf_node.output(0));
|
||||
graph_params.usage_by_bsocket.add(true_input_bsocket, &lf_node.output(1));
|
||||
graph_params.lf_inputs_by_bsocket.add(&switch_input_bsocket, &lf_node.input(0));
|
||||
graph_params.usage_by_bsocket.add(&false_input_bsocket, &lf_node.output(0));
|
||||
graph_params.usage_by_bsocket.add(&true_input_bsocket, &lf_node.output(1));
|
||||
}
|
||||
else {
|
||||
if (switch_input_bsocket->default_value_typed<bNodeSocketValueBoolean>()->value) {
|
||||
graph_params.usage_by_bsocket.add(true_input_bsocket, output_is_used_socket);
|
||||
if (switch_input_bsocket.default_value_typed<bNodeSocketValueBoolean>()->value) {
|
||||
graph_params.usage_by_bsocket.add(&true_input_bsocket, output_is_used_socket);
|
||||
}
|
||||
else {
|
||||
graph_params.usage_by_bsocket.add(false_input_bsocket, output_is_used_socket);
|
||||
graph_params.usage_by_bsocket.add(&false_input_bsocket, output_is_used_socket);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -371,24 +371,6 @@ static const char *get_current_socket_identifier_for_future_socket(
|
|||
const Span<const SocketDeclaration *> socket_decls)
|
||||
{
|
||||
switch (node.type) {
|
||||
case GEO_NODE_SWITCH: {
|
||||
const NodeSwitch &storage = *static_cast<const NodeSwitch *>(node.storage);
|
||||
const bool use_field_socket = ELEM(storage.input_type,
|
||||
SOCK_FLOAT,
|
||||
SOCK_INT,
|
||||
SOCK_BOOLEAN,
|
||||
SOCK_VECTOR,
|
||||
SOCK_RGBA,
|
||||
SOCK_STRING,
|
||||
SOCK_ROTATION);
|
||||
if (BLI_str_startswith(socket.identifier, "Switch")) {
|
||||
if (use_field_socket) {
|
||||
return "Switch";
|
||||
}
|
||||
return "Switch_001";
|
||||
}
|
||||
return get_identifier_from_decl({"False", "True", "Output"}, socket, socket_decls);
|
||||
}
|
||||
case GEO_NODE_SAMPLE_CURVE: {
|
||||
return get_identifier_from_decl("Value", socket, socket_decls);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Can part of function be replaced by
search_link_ops_for_declarations(params, params.node_type().static_declaration->inputs);
?Not yet, since we don't handle multiple types like that for link drag search yet
Ah yes, boolean a switch input is dynamic too!