Fix: Drag link search doesn't always connect to socket

Connecting to some sockets of a few nodes via the drag link search
would fail and trigger an assert, because the picked socket wasn't
available. This was due to some sockets only being available with
certain settings.

This patch fixes these cases by adding the availability conditions of
the socket to the node declaration with the `make_available` method
or manually adding a `node_link_gather_search` function.

Differential Revision: https://developer.blender.org/D14283
This commit is contained in:
Leon Schittek 2022-03-22 09:57:50 -05:00 committed by Hans Goudey
parent 6bbc3b5610
commit 7de3caa05d
8 changed files with 117 additions and 34 deletions

View File

@ -15,11 +15,20 @@ namespace blender::nodes::node_fn_rotate_euler_cc {
static void fn_node_rotate_euler_declare(NodeDeclarationBuilder &b)
{
auto enable_axis_angle = [](bNode &node) {
node.custom1 = FN_NODE_ROTATE_EULER_TYPE_AXIS_ANGLE;
};
b.is_function_node();
b.add_input<decl::Vector>(N_("Rotation")).subtype(PROP_EULER).hide_value();
b.add_input<decl::Vector>(N_("Rotate By")).subtype(PROP_EULER);
b.add_input<decl::Vector>(N_("Axis")).default_value({0.0, 0.0, 1.0}).subtype(PROP_XYZ);
b.add_input<decl::Float>(N_("Angle")).subtype(PROP_ANGLE);
b.add_input<decl::Vector>(N_("Rotate By")).subtype(PROP_EULER).make_available([](bNode &node) {
node.custom1 = FN_NODE_ROTATE_EULER_TYPE_EULER;
});
b.add_input<decl::Vector>(N_("Axis"))
.default_value({0.0, 0.0, 1.0})
.subtype(PROP_XYZ)
.make_available(enable_axis_angle);
b.add_input<decl::Float>(N_("Angle")).subtype(PROP_ANGLE).make_available(enable_axis_angle);
b.add_output<decl::Vector>(N_("Rotation"));
}

View File

@ -17,6 +17,13 @@ NODE_STORAGE_FUNCS(NodeGeometryCurvePrimitiveArc)
static void node_declare(NodeDeclarationBuilder &b)
{
auto enable_points = [](bNode &node) {
node_storage(node).mode = GEO_NODE_CURVE_PRIMITIVE_ARC_TYPE_POINTS;
};
auto enable_radius = [](bNode &node) {
node_storage(node).mode = GEO_NODE_CURVE_PRIMITIVE_ARC_TYPE_RADIUS;
};
b.add_input<decl::Int>(N_("Resolution"))
.default_value(16)
.min(2)
@ -26,34 +33,41 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Vector>(N_("Start"))
.default_value({-1.0f, 0.0f, 0.0f})
.subtype(PROP_TRANSLATION)
.description(N_("Position of the first control point"));
.description(N_("Position of the first control point"))
.make_available(enable_points);
b.add_input<decl::Vector>(N_("Middle"))
.default_value({0.0f, 2.0f, 0.0f})
.subtype(PROP_TRANSLATION)
.description(N_("Position of the middle control point"));
.description(N_("Position of the middle control point"))
.make_available(enable_points);
b.add_input<decl::Vector>(N_("End"))
.default_value({1.0f, 0.0f, 0.0f})
.subtype(PROP_TRANSLATION)
.description(N_("Position of the last control point"));
.description(N_("Position of the last control point"))
.make_available(enable_points);
b.add_input<decl::Float>(N_("Radius"))
.default_value(1.0f)
.min(0.0f)
.subtype(PROP_DISTANCE)
.description(N_("Distance of the points from the origin"));
.description(N_("Distance of the points from the origin"))
.make_available(enable_radius);
b.add_input<decl::Float>(N_("Start Angle"))
.default_value(0.0f)
.subtype(PROP_ANGLE)
.description(N_("Starting angle of the arc"));
.description(N_("Starting angle of the arc"))
.make_available(enable_radius);
b.add_input<decl::Float>(N_("Sweep Angle"))
.default_value(1.75f * M_PI)
.min(-2 * M_PI)
.max(2 * M_PI)
.subtype(PROP_ANGLE)
.description(N_("Length of the arc"));
.description(N_("Length of the arc"))
.make_available(enable_radius);
b.add_input<decl::Float>(N_("Offset Angle"))
.default_value(0.0f)
.subtype(PROP_ANGLE)
.description(N_("Offset angle of the arc"));
.description(N_("Offset angle of the arc"))
.make_available(enable_points);
b.add_input<decl::Bool>(N_("Connect Center"))
.default_value(false)
.description(N_("Connect the arc at the center"));
@ -64,17 +78,14 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Curve"));
b.add_output<decl::Vector>(N_("Center"))
.description(N_("The center of the circle described by the three points"))
.make_available(
[](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_PRIMITIVE_ARC_TYPE_POINTS; });
.make_available(enable_points);
b.add_output<decl::Vector>(N_("Normal"))
.description(N_("The normal direction of the plane described by the three points, pointing "
"towards the positive Z axis"))
.make_available(
[](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_PRIMITIVE_ARC_TYPE_POINTS; });
.make_available(enable_points);
b.add_output<decl::Float>(N_("Radius"))
.description(N_("The radius of the circle described by the three points"))
.make_available(
[](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_PRIMITIVE_ARC_TYPE_POINTS; });
.make_available(enable_points);
}
static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)

View File

@ -13,6 +13,13 @@ NODE_STORAGE_FUNCS(NodeGeometryCurvePrimitiveCircle)
static void node_declare(NodeDeclarationBuilder &b)
{
auto endable_points = [](bNode &node) {
node_storage(node).mode = GEO_NODE_CURVE_PRIMITIVE_CIRCLE_TYPE_POINTS;
};
auto enable_radius = [](bNode &node) {
node_storage(node).mode = GEO_NODE_CURVE_PRIMITIVE_CIRCLE_TYPE_RADIUS;
};
b.add_input<decl::Int>(N_("Resolution"))
.default_value(32)
.min(3)
@ -23,28 +30,30 @@ static void node_declare(NodeDeclarationBuilder &b)
.subtype(PROP_TRANSLATION)
.description(
N_("One of the three points on the circle. The point order determines the circle's "
"direction"));
"direction"))
.make_available(endable_points);
b.add_input<decl::Vector>(N_("Point 2"))
.default_value({0.0f, 1.0f, 0.0f})
.subtype(PROP_TRANSLATION)
.description(
N_("One of the three points on the circle. The point order determines the circle's "
"direction"));
"direction"))
.make_available(endable_points);
b.add_input<decl::Vector>(N_("Point 3"))
.default_value({1.0f, 0.0f, 0.0f})
.subtype(PROP_TRANSLATION)
.description(
N_("One of the three points on the circle. The point order determines the circle's "
"direction"));
"direction"))
.make_available(endable_points);
b.add_input<decl::Float>(N_("Radius"))
.default_value(1.0f)
.min(0.0f)
.subtype(PROP_DISTANCE)
.description(N_("Distance of the points from the origin"));
.description(N_("Distance of the points from the origin"))
.make_available(enable_radius);
b.add_output<decl::Geometry>(N_("Curve"));
b.add_output<decl::Vector>(N_("Center")).make_available([](bNode &node) {
node_storage(node).mode = GEO_NODE_CURVE_PRIMITIVE_CIRCLE_TYPE_POINTS;
});
b.add_output<decl::Vector>(N_("Center")).make_available(endable_points);
}
static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)

View File

@ -13,21 +13,29 @@ NODE_STORAGE_FUNCS(NodeGeometryCurvePrimitiveLine)
static void node_declare(NodeDeclarationBuilder &b)
{
auto enable_direction = [](bNode &node) {
node_storage(node).mode = GEO_NODE_CURVE_PRIMITIVE_LINE_MODE_DIRECTION;
};
b.add_input<decl::Vector>(N_("Start"))
.subtype(PROP_TRANSLATION)
.description(N_("Position of the first control point"));
b.add_input<decl::Vector>(N_("End"))
.default_value({0.0f, 0.0f, 1.0f})
.subtype(PROP_TRANSLATION)
.description(N_("Position of the second control point"));
.description(N_("Position of the second control point"))
.make_available([](bNode &node) {
node_storage(node).mode = GEO_NODE_CURVE_PRIMITIVE_LINE_MODE_POINTS;
});
b.add_input<decl::Vector>(N_("Direction"))
.default_value({0.0f, 0.0f, 1.0f})
.description(
N_("Direction the line is going in. The length of this vector does not matter"));
.description(N_("Direction the line is going in. The length of this vector does not matter"))
.make_available(enable_direction);
b.add_input<decl::Float>(N_("Length"))
.default_value(1.0f)
.subtype(PROP_DISTANCE)
.description(N_("Distance between the two points"));
.description(N_("Distance between the two points"))
.make_available(enable_direction);
b.add_output<decl::Geometry>(N_("Curve"));
}

View File

@ -26,17 +26,35 @@ namespace blender::nodes::node_geo_distribute_points_on_faces_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
auto enable_random = [](bNode &node) {
node.custom1 = GEO_NODE_POINT_DISTRIBUTE_POINTS_ON_FACES_RANDOM;
};
auto enable_poisson = [](bNode &node) {
node.custom1 = GEO_NODE_POINT_DISTRIBUTE_POINTS_ON_FACES_POISSON;
};
b.add_input<decl::Geometry>(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
b.add_input<decl::Float>(N_("Distance Min")).min(0.0f).subtype(PROP_DISTANCE);
b.add_input<decl::Float>(N_("Density Max")).default_value(10.0f).min(0.0f);
b.add_input<decl::Float>(N_("Density")).default_value(10.0f).min(0.0f).supports_field();
b.add_input<decl::Float>(N_("Distance Min"))
.min(0.0f)
.subtype(PROP_DISTANCE)
.make_available(enable_poisson);
b.add_input<decl::Float>(N_("Density Max"))
.default_value(10.0f)
.min(0.0f)
.make_available(enable_poisson);
b.add_input<decl::Float>(N_("Density"))
.default_value(10.0f)
.min(0.0f)
.supports_field()
.make_available(enable_random);
b.add_input<decl::Float>(N_("Density Factor"))
.default_value(1.0f)
.min(0.0f)
.max(1.0f)
.subtype(PROP_FACTOR)
.supports_field();
.supports_field()
.make_available(enable_poisson);
b.add_input<decl::Int>(N_("Seed"));
b.add_output<decl::Geometry>(N_("Points"));

View File

@ -31,7 +31,8 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Vector>(N_("Axis"))
.default_value({1.0f, 0.0f, 0.0f})
.supports_field()
.description(N_("Direction in which to scale the element"));
.description(N_("Direction in which to scale the element"))
.make_available([](bNode &node) { node.custom2 = GEO_NODE_SCALE_ELEMENTS_SINGLE_AXIS; });
b.add_output<decl::Geometry>(N_("Geometry"));
};

View File

@ -10,6 +10,8 @@
#include "UI_interface.h"
#include "UI_resources.h"
#include "NOD_socket_search_link.hh"
namespace blender::nodes::node_shader_tex_sky_cc {
static void node_declare(NodeDeclarationBuilder &b)
@ -229,6 +231,24 @@ static void node_shader_update_sky(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(ntree, sockVector, !(tex->sky_model == 2 && tex->sun_disc == 1));
}
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
if (params.in_out() == SOCK_OUT) {
search_link_ops_for_declarations(params, declaration.outputs());
return;
}
if (params.node_tree().typeinfo->validate_link(
static_cast<eNodeSocketDatatype>(params.other_socket().type), SOCK_FLOAT)) {
params.add_item(IFACE_("Vector"), [](LinkSearchOpParams &params) {
bNode &node = params.add_node("ShaderNodeTexSky");
NodeTexSky *tex = (NodeTexSky *)node.storage;
tex->sun_disc = false;
params.update_and_connect_available_socket(node, "Vector");
});
}
}
} // namespace blender::nodes::node_shader_tex_sky_cc
/* node type definition */
@ -247,6 +267,7 @@ void register_node_type_sh_tex_sky()
node_type_gpu(&ntype, file_ns::node_shader_gpu_tex_sky);
/* Remove vector input for Nishita sky model. */
node_type_update(&ntype, file_ns::node_shader_update_sky);
ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
nodeRegisterType(&ntype);
}

View File

@ -17,9 +17,15 @@ static void sh_node_vector_rotate_declare(NodeDeclarationBuilder &b)
b.is_function_node();
b.add_input<decl::Vector>(N_("Vector")).min(0.0f).max(1.0f).hide_value();
b.add_input<decl::Vector>(N_("Center"));
b.add_input<decl::Vector>(N_("Axis")).min(-1.0f).max(1.0f).default_value({0.0f, 0.0f, 1.0f});
b.add_input<decl::Vector>(N_("Axis"))
.min(-1.0f)
.max(1.0f)
.default_value({0.0f, 0.0f, 1.0f})
.make_available([](bNode &node) { node.custom1 = NODE_VECTOR_ROTATE_TYPE_AXIS; });
b.add_input<decl::Float>(N_("Angle")).subtype(PROP_ANGLE);
b.add_input<decl::Vector>(N_("Rotation")).subtype(PROP_EULER);
b.add_input<decl::Vector>(N_("Rotation")).subtype(PROP_EULER).make_available([](bNode &node) {
node.custom1 = NODE_VECTOR_ROTATE_TYPE_EULER_XYZ;
});
b.add_output<decl::Vector>(N_("Vector"));
}