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
Iliya Katushenock
commented
Can part of function be replaced by Can part of function be replaced by `search_link_ops_for_declarations(params, params.node_type().static_declaration->inputs);`?
Hans Goudey
commented
Not yet, since we don't handle multiple types like that for link drag search yet Not yet, since we don't handle multiple types like that for link drag search yet
Iliya Katushenock
commented
Ah yes, boolean a switch input is dynamic too! Ah yes, boolean a switch input is dynamic too!
|
||||
if (params.in_out() == SOCK_OUT) {
|
||||
|
@ -297,7 +238,6 @@ static void node_rna(StructRNA *srna)
|
|||
SOCK_GEOMETRY,
|
||||
SOCK_OBJECT,
|
||||
SOCK_COLLECTION,
|
||||
SOCK_TEXTURE,
|
||||
mod_moder marked this conversation as resolved
Outdated
Iliya Katushenock
commented
Unrelated change? Unrelated change?
Hans Goudey
commented
Required to not assert when switching to texture type in the UI enum. It's not supported anyway in geometry nodes, pure legacy stuff. Required to not assert when switching to texture type in the UI enum. It's not supported anyway in geometry nodes, pure legacy stuff.
|
||||
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
Is there the chance to note the type of value in anythere?