diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c index 8168b917b5e..f0bc910889b 100644 --- a/source/blender/blenloader/intern/versioning_300.c +++ b/source/blender/blenloader/intern/versioning_300.c @@ -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. */ } diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc index 15930508e78..1b6b6a5bdd7 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc @@ -25,14 +25,14 @@ static void geo_node_set_position_declare(NodeDeclarationBuilder &b) b.add_input("Geometry"); b.add_input("Selection").default_value(true).hide_value().supports_field(); b.add_input("Position").implicit_field(); - b.add_input("Offset").default_value(false).supports_field(); + b.add_input("Offset").supports_field().subtype(PROP_TRANSLATION); b.add_output("Geometry"); } static void set_position_in_component(GeometryComponent &component, const Field &selection_field, const Field &position_field, - const Field &offset_field) + const Field &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 &positions_input = position_evaluator.get_evaluated(0); - const VArray &offsets_input = position_evaluator.get_evaluated(1); + const VArray &offsets_input = position_evaluator.get_evaluated(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("Geometry"); Field selection_field = params.extract_input>("Selection"); - Field offset_field = params.extract_input>("Offset"); + Field offset_field = params.extract_input>("Offset"); Field position_field = params.extract_input>("Position"); for (const GeometryComponentType type : {GEO_COMPONENT_TYPE_MESH,