Geometry Nodes: new Trim String node

This adds a new Trim String node. It removes specific characters at the
beginning and end of a string. Most often this is used to remove unnecessary
whitespace but it can be used with other characters too.

Since it's the most common use-case, and it's tricky to type in manually, there
is a special "Whitespace" option on the node which includes spaces, newlines,
tabs and carriage-return (` \t\n\r`).

I originally used this while working on the physics system to "fix" tag names
provided by the user in a comma-separated-list.

Pull Request: https://projects.blender.org/blender/blender/pulls/154465
This commit is contained in:
Jacques Lucke 2026-03-11 12:49:59 +01:00
parent 1c209733c8
commit 8e699aa94b
5 changed files with 85 additions and 0 deletions

View file

@ -660,6 +660,7 @@ class NODE_MT_gn_utilities_text_base(node_add_menu.NodeMenu):
self.node_operator(layout, "FunctionNodeSliceString")
if context.preferences.experimental.use_geometry_nodes_lists:
self.node_operator(layout, "FunctionNodeSplitString")
self.node_operator(layout, "FunctionNodeTrimString")
layout.separator()
self.node_operator(layout, "FunctionNodeFindInString")
self.node_operator(layout, "FunctionNodeStringLength")

View file

@ -10342,6 +10342,7 @@ static void rna_def_nodes(BlenderRNA *brna)
define("FunctionNode", "FunctionNodeTransformDirection");
define("FunctionNode", "FunctionNodeTransformPoint");
define("FunctionNode", "FunctionNodeTransposeMatrix");
define("FunctionNode", "FunctionNodeTrimString");
define("FunctionNode", "FunctionNodeValueToString");
define("GeometryNode", "GeometryNodeAccumulateField");

View file

@ -69,6 +69,7 @@ set(SRC
nodes/node_fn_transform_direction.cc
nodes/node_fn_transform_point.cc
nodes/node_fn_transpose_matrix.cc
nodes/node_fn_trim_string.cc
nodes/node_fn_value_to_string.cc
node_function_util.cc

View file

@ -0,0 +1,79 @@
/* SPDX-FileCopyrightText: 2026 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_function_util.hh"
namespace blender::nodes::node_fn_trim_string_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.use_custom_socket_order();
b.allow_any_socket_order();
b.add_input<decl::String>("String").optional_label();
b.add_output<decl::String>("String").align_with_previous();
b.add_input<decl::String>("Characters")
.optional_label()
.description("Individual characters to trim. The order of characters does not matter");
b.add_input<decl::Bool>("Whitespace")
.default_value(true)
.description("Trim whitespace characters in addition to the provided characters");
{
auto &p = b.add_panel("Limit"_ustr).default_closed(true);
p.add_input<decl::Bool>("Start").default_value(true).description(
"Trim the beginning of the string");
p.add_input<decl::Bool>("End").default_value(true).description(
"Trim at the end of the string");
}
}
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
static auto trim_fn = mf::build::SI5_SO<std::string, std::string, bool, bool, bool, std::string>(
"Trim",
[](const std::string &input_str,
const std::string &characters,
const bool trim_whitespace,
const bool trim_start,
const bool trim_end) {
std::string characters_to_trim = characters;
if (trim_whitespace) {
characters_to_trim.append(" \t\n\r");
}
StringRef str = input_str;
int64_t start = 0;
int64_t end = str.size();
if (trim_start) {
const int64_t i = str.find_first_not_of(characters_to_trim);
if (i != StringRef::not_found) {
start = i;
}
}
if (trim_end) {
const int64_t i = str.find_last_not_of(characters_to_trim);
if (i != StringRef::not_found) {
end = i + 1;
}
}
std::string result = str.substr(start, end - start);
return result;
});
builder.set_matching_fn(&trim_fn);
}
static void node_register()
{
static bke::bNodeType ntype;
fn_node_type_base(&ntype, "FunctionNodeTrimString");
ntype.ui_name = "Trim String";
ntype.ui_description = "Remove characters from the beginning and end of a string";
ntype.nclass = NODE_CLASS_CONVERTER;
ntype.declare = node_declare;
ntype.build_multi_function = node_build_multi_function;
bke::node_register_type(ntype);
}
NOD_REGISTER_NODE(node_register)
} // namespace blender::nodes::node_fn_trim_string_cc

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7e43ffeb6150b0ce2e2ed6711dfe87527408d021901ff683620e6c14a1820ef6
size 101062