Geometry Nodes: Add string input node

This commit adds a simple string input node, intended for use in the
attribute workflow to make using the same attribute name in multiple
places easier. The node is function node similar to the existing vector
input node.

Ref T84971

Differential Revision: https://developer.blender.org/D10316
This commit is contained in:
Edgar Roman Cervantes 2021-02-19 16:03:14 -06:00 committed by Hans Goudey
parent ee1c674775
commit a961a2189c
Notes: blender-bot 2023-02-14 07:18:54 +01:00
Referenced by issue #84971, Create a string input node
9 changed files with 153 additions and 0 deletions

View File

@ -508,6 +508,7 @@ geometry_node_categories = [
NodeItem("GeometryNodeCollectionInfo"),
NodeItem("FunctionNodeRandomFloat"),
NodeItem("ShaderNodeValue"),
NodeItem("FunctionNodeInputString"),
NodeItem("FunctionNodeInputVector"),
NodeItem("GeometryNodeIsViewport"),
]),

View File

@ -1388,6 +1388,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define FN_NODE_OBJECT_TRANSFORMS 1205
#define FN_NODE_RANDOM_FLOAT 1206
#define FN_NODE_INPUT_VECTOR 1207
#define FN_NODE_INPUT_STRING 1208
/** \} */

View File

@ -523,6 +523,13 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree)
BLO_write_struct_by_name(writer, node->typeinfo->storagename, node->storage);
MEM_SAFE_FREE(nc->matte_id);
}
else if (node->type == FN_NODE_INPUT_STRING) {
NodeInputString *storage = (NodeInputString *)node->storage;
if (storage->string) {
BLO_write_string(writer, storage->string);
}
BLO_write_struct_by_name(writer, node->typeinfo->storagename, storage);
}
else if (node->typeinfo != &NodeTypeUndefined) {
BLO_write_struct_by_name(writer, node->typeinfo->storagename, node->storage);
}
@ -685,6 +692,11 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
iuser->scene = nullptr;
break;
}
case FN_NODE_INPUT_STRING: {
NodeInputString *storage = (NodeInputString *)node->storage;
BLO_read_data_address(reader, &storage->string);
break;
}
default:
break;
}
@ -4806,6 +4818,7 @@ static void registerFunctionNodes()
register_node_type_fn_combine_strings();
register_node_type_fn_float_compare();
register_node_type_fn_group_instance_id();
register_node_type_fn_input_string();
register_node_type_fn_input_vector();
register_node_type_fn_object_transforms();
register_node_type_fn_random_float();

View File

@ -1140,6 +1140,10 @@ typedef struct NodeInputVector {
float vector[3];
} NodeInputVector;
typedef struct NodeInputString {
char *string;
} NodeInputString;
typedef struct NodeGeometryRotatePoints {
/* GeometryNodeRotatePointsType */
uint8_t type;

View File

@ -4113,6 +4113,38 @@ void rna_ShaderNodePointDensity_density_minmax(bNode *self,
RE_point_density_minmax(depsgraph, pd, r_min, r_max);
}
static void rna_NodeInputString_string_get(PointerRNA *ptr, char *value)
{
bNode *node = (bNode *)ptr->data;
NodeInputString *storage = node->storage;
strcpy(value, (storage->string) ? storage->string : "");
}
static int rna_NodeInputString_string_length(PointerRNA *ptr)
{
bNode *node = (bNode *)ptr->data;
NodeInputString *storage = node->storage;
return (storage->string) ? strlen(storage->string) : 0;
}
static void rna_NodeInputString_string_set(PointerRNA *ptr, const char *value)
{
bNode *node = (bNode *)ptr->data;
NodeInputString *storage = node->storage;
if (storage->string) {
MEM_freeN(storage->string);
}
if (value && value[0]) {
storage->string = BLI_strdup(value);
}
else {
storage->string = NULL;
}
}
#else
static const EnumPropertyItem prop_image_layer_items[] = {
@ -4539,6 +4571,21 @@ static void def_fn_input_vector(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_fn_input_string(StructRNA *srna)
{
PropertyRNA *prop;
RNA_def_struct_sdna_from(srna, "NodeInputString", "storage");
prop = RNA_def_property(srna, "string", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop,
"rna_NodeInputString_string_get",
"rna_NodeInputString_string_length",
"rna_NodeInputString_string_set");
RNA_def_property_ui_text(prop, "String", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
/* -- Shader Nodes ---------------------------------------------------------- */
static void def_sh_output(StructRNA *srna)

View File

@ -135,6 +135,7 @@ set(SRC
function/nodes/node_fn_combine_strings.cc
function/nodes/node_fn_float_compare.cc
function/nodes/node_fn_group_instance_id.cc
function/nodes/node_fn_input_string.cc
function/nodes/node_fn_input_vector.cc
function/nodes/node_fn_object_transforms.cc
function/nodes/node_fn_random_float.cc

View File

@ -24,6 +24,7 @@ void register_node_type_fn_boolean_math(void);
void register_node_type_fn_combine_strings(void);
void register_node_type_fn_float_compare(void);
void register_node_type_fn_group_instance_id(void);
void register_node_type_fn_input_string(void);
void register_node_type_fn_input_vector(void);
void register_node_type_fn_object_transforms(void);
void register_node_type_fn_random_float(void);

View File

@ -267,6 +267,7 @@ DefNode(FunctionNode, FN_NODE_COMBINE_STRINGS, 0, "COMBINE_STRINGS
DefNode(FunctionNode, FN_NODE_OBJECT_TRANSFORMS, 0, "OBJECT_TRANSFORMS", ObjectTransforms, "Object Transforms", "")
DefNode(FunctionNode, FN_NODE_RANDOM_FLOAT, 0, "RANDOM_FLOAT", RandomFloat, "Random Float", "")
DefNode(FunctionNode, FN_NODE_INPUT_VECTOR, def_fn_input_vector, "INPUT_VECTOR", InputVector, "Vector", "")
DefNode(FunctionNode, FN_NODE_INPUT_STRING, def_fn_input_string, "INPUT_STRING", InputString, "String", "")
DefNode(GeometryNode, GEO_NODE_TRIANGULATE, def_geo_triangulate, "TRIANGULATE", Triangulate, "Triangulate", "")
DefNode(GeometryNode, GEO_NODE_EDGE_SPLIT, 0, "EDGE_SPLIT", EdgeSplit, "Edge Split", "")

View File

@ -0,0 +1,84 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "node_function_util.hh"
#include "UI_interface.h"
#include "UI_resources.h"
static bNodeSocketTemplate fn_node_input_string_out[] = {
{SOCK_STRING, N_("String")},
{-1, ""},
};
static void fn_node_input_string_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "string", 0, "", ICON_NONE);
}
static void fn_node_input_string_expand_in_mf_network(
blender::nodes::NodeMFNetworkBuilder &builder)
{
bNode &bnode = builder.bnode();
NodeInputString *node_storage = static_cast<NodeInputString *>(bnode.storage);
std::string string = std::string((node_storage->string) ? node_storage->string : "");
builder.construct_and_set_matching_fn<blender::fn::CustomMF_Constant<std::string>>(string);
}
static void fn_node_input_string_init(bNodeTree *UNUSED(ntree), bNode *node)
{
node->storage = MEM_callocN(sizeof(NodeInputString), __func__);
}
static void fn_node_input_string_free(bNode *node)
{
NodeInputString *storage = (NodeInputString *)node->storage;
if (storage == nullptr) {
return;
}
if (storage->string != nullptr) {
MEM_freeN(storage->string);
}
MEM_freeN(storage);
}
static void fn_node_string_copy(bNodeTree *UNUSED(dest_ntree),
bNode *dest_node,
const bNode *src_node)
{
NodeInputString *source_storage = (NodeInputString *)src_node->storage;
NodeInputString *destination_storage = (NodeInputString *)MEM_dupallocN(source_storage);
if (source_storage->string) {
destination_storage->string = (char *)MEM_dupallocN(source_storage->string);
}
dest_node->storage = destination_storage;
}
void register_node_type_fn_input_string()
{
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_INPUT_STRING, "String", NODE_CLASS_INPUT, 0);
node_type_socket_templates(&ntype, nullptr, fn_node_input_string_out);
node_type_init(&ntype, fn_node_input_string_init);
node_type_storage(&ntype, "NodeInputString", fn_node_input_string_free, fn_node_string_copy);
ntype.expand_in_mf_network = fn_node_input_string_expand_in_mf_network;
ntype.draw_buttons = fn_node_input_string_layout;
nodeRegisterType(&ntype);
}