Geometry Nodes: use vector socket for offset in Set Position node

This replaces the boolean Offset input in the Set Position node with
a vector input. This makes the node easier to use. Using a "Position"
input as an "Offset" sounds wrong anyway.

The Position and Offset inputs are evaluated at the same time.

The versioning only works correctly when the Offset input was not connected
to something else before.

Differential Revision: https://developer.blender.org/D12983
This commit is contained in:
Jacques Lucke 2021-10-25 11:37:45 +02:00
parent 1ecb4e6fd8
commit b3ca926aa8
Notes: blender-bot 2023-05-03 10:14:48 +02:00
Referenced by issue #92348, Geometry Nodes: Set Position node uses implicit position for "Offset" mode, causing unintended displacement
2 changed files with 52 additions and 6 deletions

View File

@ -1218,6 +1218,52 @@ static void do_version_bones_roll(ListBase *lb)
}
}
static void version_geometry_nodes_set_position_node_offset(bNodeTree *ntree)
{
/* Add the new Offset socket. */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->type != GEO_NODE_SET_POSITION) {
continue;
}
bNodeSocket *old_offset_socket = BLI_findlink(&node->inputs, 3);
if (old_offset_socket->type == SOCK_VECTOR) {
/* Versioning happened already. */
return;
}
/* Change identifier of old socket, so that the there is no name collision. */
STRNCPY(old_offset_socket->identifier, "Offset_old");
nodeAddStaticSocket(ntree, node, SOCK_IN, SOCK_VECTOR, PROP_TRANSLATION, "Offset", "Offset");
}
/* Relink links that were connected to Position while Offset was enabled. */
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
if (link->tonode->type != GEO_NODE_SET_POSITION) {
continue;
}
if (!STREQ(link->tosock->identifier, "Position")) {
continue;
}
bNodeSocket *old_offset_socket = BLI_findlink(&link->tonode->inputs, 3);
/* This assumes that the offset is not linked to something else. That seems to be a reasonable
* assumption, because the node is probably only ever used in one or the other mode. */
const bool offset_enabled =
((bNodeSocketValueBoolean *)old_offset_socket->default_value)->value;
if (offset_enabled) {
/* Relink to new offset socket. */
link->tosock = old_offset_socket->next;
}
}
/* Remove old Offset socket. */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->type != GEO_NODE_SET_POSITION) {
continue;
}
bNodeSocket *old_offset_socket = BLI_findlink(&node->inputs, 3);
nodeRemoveSocket(ntree, node, old_offset_socket);
}
}
/* NOLINTNEXTLINE: readability-function-size */
void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
{
@ -2038,6 +2084,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
continue;
}
version_node_id(ntree, FN_NODE_SLICE_STRING, "FunctionNodeSliceString");
version_geometry_nodes_set_position_node_offset(ntree);
}
/* Keep this block, even when empty. */
}

View File

@ -25,14 +25,14 @@ static void geo_node_set_position_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Geometry>("Geometry");
b.add_input<decl::Bool>("Selection").default_value(true).hide_value().supports_field();
b.add_input<decl::Vector>("Position").implicit_field();
b.add_input<decl::Bool>("Offset").default_value(false).supports_field();
b.add_input<decl::Vector>("Offset").supports_field().subtype(PROP_TRANSLATION);
b.add_output<decl::Geometry>("Geometry");
}
static void set_position_in_component(GeometryComponent &component,
const Field<bool> &selection_field,
const Field<float3> &position_field,
const Field<bool> &offset_field)
const Field<float3> &offset_field)
{
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
@ -58,11 +58,10 @@ static void set_position_in_component(GeometryComponent &component,
* value or not */
const VArray<float3> &positions_input = position_evaluator.get_evaluated<float3>(0);
const VArray<bool> &offsets_input = position_evaluator.get_evaluated<bool>(1);
const VArray<float3> &offsets_input = position_evaluator.get_evaluated<float3>(1);
for (int i : selection) {
position_mutable[i] = offsets_input[i] ? position_mutable[i] + positions_input[i] :
positions_input[i];
position_mutable[i] = positions_input[i] + offsets_input[i];
}
positions.save();
}
@ -71,7 +70,7 @@ static void geo_node_set_position_exec(GeoNodeExecParams params)
{
GeometrySet geometry = params.extract_input<GeometrySet>("Geometry");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
Field<bool> offset_field = params.extract_input<Field<bool>>("Offset");
Field<float3> offset_field = params.extract_input<Field<float3>>("Offset");
Field<float3> position_field = params.extract_input<Field<float3>>("Position");
for (const GeometryComponentType type : {GEO_COMPONENT_TYPE_MESH,