Geometry Nodes: Find in String node
Add a node that finds the number of times a substring occurs in a string, and the position of the start of the first match. See the PR description for more rational and details. Pull Request: https://projects.blender.org/blender/blender/pulls/129270
This commit is contained in:
@@ -553,6 +553,7 @@ class NODE_MT_category_GEO_TEXT(Menu):
|
||||
node_add_menu.add_node_type(layout, "FunctionNodeSliceString")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "FunctionNodeStringLength")
|
||||
node_add_menu.add_node_type(layout, "FunctionNodeFindInString")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeStringToCurves")
|
||||
node_add_menu.add_node_type(layout, "FunctionNodeValueToString")
|
||||
layout.separator()
|
||||
|
||||
@@ -1412,6 +1412,7 @@ void node_tree_remove_layer_n(bNodeTree *ntree, Scene *scene, int layer_index);
|
||||
#define FN_NODE_HASH_VALUE 1245
|
||||
#define FN_NODE_INTEGER_MATH 1246
|
||||
#define FN_NODE_MATRIX_DETERMINANT 1247
|
||||
#define FN_NODE_FIND_IN_STRING 1248
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
@@ -304,6 +304,7 @@ DefNode(FunctionNode, FN_NODE_SEPARATE_MATRIX, 0, SeparateMatrix, "Separate Matr
|
||||
DefNode(FunctionNode, FN_NODE_SEPARATE_TRANSFORM, 0, SeparateTransform, "Separate Transform", "")
|
||||
DefNode(FunctionNode, FN_NODE_SLICE_STRING, 0, SliceString, "Slice String", "")
|
||||
DefNode(FunctionNode, FN_NODE_STRING_LENGTH, 0, StringLength, "String Length", "")
|
||||
DefNode(FunctionNode, FN_NODE_FIND_IN_STRING, 0, FindInString, "Find In String","")
|
||||
DefNode(FunctionNode, FN_NODE_TRANSFORM_DIRECTION, 0, TransformDirection, "Transform Direction", "")
|
||||
DefNode(FunctionNode, FN_NODE_TRANSFORM_POINT, 0, TransformPoint, "Transform Point", "")
|
||||
DefNode(FunctionNode, FN_NODE_TRANSPOSE_MATRIX, 0, TransposeMatrix, "Transpose Matrix", "")
|
||||
|
||||
@@ -60,6 +60,7 @@ set(SRC
|
||||
nodes/node_fn_transform_point.cc
|
||||
nodes/node_fn_transpose_matrix.cc
|
||||
nodes/node_fn_value_to_string.cc
|
||||
nodes/node_fn_find_in_string.cc
|
||||
|
||||
node_function_util.cc
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_string_utf8.h"
|
||||
|
||||
#include "node_function_util.hh"
|
||||
|
||||
namespace blender::nodes::node_fn_find_in_string_cc {
|
||||
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::String>("String").hide_label();
|
||||
b.add_input<decl::String>("Search");
|
||||
b.add_output<decl::Int>("First Found");
|
||||
b.add_output<decl::Int>("Count");
|
||||
}
|
||||
|
||||
static int string_find(const StringRef text, const StringRef token)
|
||||
{
|
||||
if (text.is_empty() || token.is_empty()) {
|
||||
return 0;
|
||||
}
|
||||
const int pos = text.find(token, 0);
|
||||
size_t r_len_bytes;
|
||||
const int pos_n = BLI_strnlen_utf8_ex(text.data(), pos, &r_len_bytes);
|
||||
return pos_n;
|
||||
}
|
||||
|
||||
static int string_count(const StringRef text, const StringRef token)
|
||||
{
|
||||
if (text.is_empty() || token.is_empty()) {
|
||||
return 0;
|
||||
}
|
||||
int count = 0;
|
||||
const int match_len = token.size();
|
||||
int pos = 0;
|
||||
while ((pos = text.find(token, pos)) != StringRef::not_found) {
|
||||
count++;
|
||||
pos += match_len;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
|
||||
{
|
||||
static auto token_position_count = mf::build::SI2_SO2<std::string, std::string, int, int>(
|
||||
"Find in String",
|
||||
[](const std::string &text, const std::string &token, int &first, int &count) -> void {
|
||||
first = string_find(text, token);
|
||||
count = string_count(text, token);
|
||||
});
|
||||
|
||||
builder.set_matching_fn(&token_position_count);
|
||||
}
|
||||
|
||||
static void node_register()
|
||||
{
|
||||
static blender::bke::bNodeType ntype;
|
||||
|
||||
fn_node_type_base(&ntype, FN_NODE_FIND_IN_STRING, "Find in String", NODE_CLASS_CONVERTER);
|
||||
ntype.declare = node_declare;
|
||||
ntype.build_multi_function = node_build_multi_function;
|
||||
blender::bke::node_register_type(&ntype);
|
||||
}
|
||||
NOD_REGISTER_NODE(node_register)
|
||||
|
||||
} // namespace blender::nodes::node_fn_find_in_string_cc
|
||||
Reference in New Issue
Block a user