support for string parameters in OSL nodes
for now subtype is not defined, but once we start parsing the metadata we can set texture inputs as FILEPATH also, it takes relative strings and convert to absolute for all strings (which is arguably a good solution, but should work for now)
This commit is contained in:
@@ -217,6 +217,7 @@ static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
|
||||
float default_float4[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
float default_float = 0.0f;
|
||||
int default_int = 0;
|
||||
std::string default_string = "";
|
||||
|
||||
if(param->isclosure) {
|
||||
socket_type = BL::NodeSocket::type_SHADER;
|
||||
@@ -252,6 +253,11 @@ static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
|
||||
if(param->validdefault)
|
||||
default_float = param->fdefault[0];
|
||||
}
|
||||
else if(param->type.basetype == TypeDesc::STRING) {
|
||||
socket_type = BL::NodeSocket::type_STRING;
|
||||
if(param->validdefault)
|
||||
default_string = param->sdefault[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
continue;
|
||||
@@ -286,6 +292,10 @@ static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
|
||||
BL::NodeSocketVectorNone b_vector_sock(b_sock.ptr);
|
||||
b_vector_sock.default_value(default_float4);
|
||||
}
|
||||
else if(socket_type == BL::NodeSocket::type_STRING) {
|
||||
BL::NodeSocketStringNone b_string_sock(b_sock.ptr);
|
||||
b_string_sock.default_value(default_string);
|
||||
}
|
||||
}
|
||||
|
||||
used_sockets.insert(b_sock.ptr.data);
|
||||
|
@@ -90,6 +90,8 @@ static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type)
|
||||
return SHADER_SOCKET_COLOR;
|
||||
case BL::NodeSocket::type_SHADER:
|
||||
return SHADER_SOCKET_CLOSURE;
|
||||
case BL::NodeSocket::type_STRING:
|
||||
return SHADER_SOCKET_STRING;
|
||||
|
||||
case BL::NodeSocket::type_BOOLEAN:
|
||||
case BL::NodeSocket::type_MESH:
|
||||
@@ -98,7 +100,7 @@ static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type)
|
||||
}
|
||||
}
|
||||
|
||||
static void set_default_value(ShaderInput *input, BL::NodeSocket sock)
|
||||
static void set_default_value(ShaderInput *input, BL::NodeSocket sock, BL::BlendData b_data, BL::ID b_id)
|
||||
{
|
||||
/* copy values for non linked inputs */
|
||||
switch(input->type) {
|
||||
@@ -124,6 +126,11 @@ static void set_default_value(ShaderInput *input, BL::NodeSocket sock)
|
||||
input->set(get_float3(vec_sock.default_value()));
|
||||
break;
|
||||
}
|
||||
case SHADER_SOCKET_STRING: {
|
||||
BL::NodeSocketStringNone string_sock(sock);
|
||||
input->set((ustring)blender_absolute_path(b_data, b_id, string_sock.default_value()));
|
||||
break;
|
||||
}
|
||||
case SHADER_SOCKET_CLOSURE:
|
||||
break;
|
||||
}
|
||||
@@ -457,7 +464,7 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
|
||||
for (b_script_node.inputs.begin(b_input); b_input != b_script_node.inputs.end(); ++b_input) {
|
||||
script_node->input_names.push_back(ustring(b_input->name()));
|
||||
ShaderInput *input = script_node->add_input(script_node->input_names.back().c_str(), convert_socket_type(b_input->type()));
|
||||
set_default_value(input, *b_input);
|
||||
set_default_value(input, *b_input, b_data, b_ntree);
|
||||
}
|
||||
|
||||
BL::Node::outputs_iterator b_output;
|
||||
@@ -726,7 +733,7 @@ static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, Sha
|
||||
group_sockmap[b_input->group_socket().ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
|
||||
|
||||
/* default input values of the group node */
|
||||
set_default_value(proxy->inputs[0], *b_input);
|
||||
set_default_value(proxy->inputs[0], *b_input, b_data, b_group_ntree);
|
||||
}
|
||||
|
||||
for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
|
||||
@@ -740,7 +747,7 @@ static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, Sha
|
||||
group_sockmap[b_output->group_socket().ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
|
||||
|
||||
/* default input values of internal, unlinked group outputs */
|
||||
set_default_value(proxy->inputs[0], b_output->group_socket());
|
||||
set_default_value(proxy->inputs[0], b_output->group_socket(), b_data, b_group_ntree);
|
||||
}
|
||||
|
||||
add_nodes(scene, b_data, b_scene, graph, b_group_ntree, group_sockmap);
|
||||
@@ -760,7 +767,7 @@ static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, Sha
|
||||
assert(input);
|
||||
|
||||
/* copy values for non linked inputs */
|
||||
set_default_value(input, *b_input);
|
||||
set_default_value(input, *b_input, b_data, b_ntree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -326,6 +326,7 @@ void ShaderGraph::remove_proxy_nodes(vector<bool>& removed)
|
||||
|
||||
/* transfer the default input value to the target socket */
|
||||
to->set(input->value);
|
||||
to->set(input->value_string);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -49,7 +49,8 @@ enum ShaderSocketType {
|
||||
SHADER_SOCKET_VECTOR,
|
||||
SHADER_SOCKET_POINT,
|
||||
SHADER_SOCKET_NORMAL,
|
||||
SHADER_SOCKET_CLOSURE
|
||||
SHADER_SOCKET_CLOSURE,
|
||||
SHADER_SOCKET_STRING
|
||||
};
|
||||
|
||||
/* Bump
|
||||
@@ -120,6 +121,7 @@ public:
|
||||
ShaderInput(ShaderNode *parent, const char *name, ShaderSocketType type);
|
||||
void set(const float3& v) { value = v; }
|
||||
void set(float f) { value = make_float3(f, 0, 0); }
|
||||
void set(const ustring v) { value_string = v; }
|
||||
|
||||
const char *name;
|
||||
ShaderSocketType type;
|
||||
@@ -129,6 +131,7 @@ public:
|
||||
|
||||
DefaultValue default_value;
|
||||
float3 value;
|
||||
ustring value_string;
|
||||
|
||||
int stack_offset; /* for SVM compiler */
|
||||
bool osl_only;
|
||||
|
@@ -403,6 +403,9 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
|
||||
case SHADER_SOCKET_INT:
|
||||
parameter(param_name.c_str(), (int)input->value.x);
|
||||
break;
|
||||
case SHADER_SOCKET_STRING:
|
||||
parameter(param_name.c_str(), input->value_string);
|
||||
break;
|
||||
case SHADER_SOCKET_CLOSURE:
|
||||
break;
|
||||
}
|
||||
|
@@ -108,6 +108,43 @@ static void node_socket_button_default(const bContext *C, uiBlock *block,
|
||||
}
|
||||
}
|
||||
|
||||
static void node_socket_button_string(const bContext *C, uiBlock *block,
|
||||
bNodeTree *ntree, bNode *node, bNodeSocket *sock,
|
||||
const char *name, int x, int y, int width)
|
||||
{
|
||||
if (sock->link || (sock->flag & SOCK_HIDE_VALUE))
|
||||
node_socket_button_label(C, block, ntree, node, sock, name, x, y, width);
|
||||
else {
|
||||
PointerRNA ptr;
|
||||
uiBut *bt;
|
||||
|
||||
SpaceNode *snode = CTX_wm_space_node(C);
|
||||
const char *ui_name = IFACE_(name);
|
||||
float slen;
|
||||
|
||||
UI_ThemeColor(TH_TEXT);
|
||||
slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt;
|
||||
while (slen > (width * 0.5) && *ui_name) {
|
||||
ui_name = BLI_str_find_next_char_utf8(ui_name, NULL);
|
||||
slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt;
|
||||
}
|
||||
|
||||
RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr);
|
||||
|
||||
if (name[0] == '\0')
|
||||
slen = 0.0;
|
||||
|
||||
bt = uiDefButR(block, TEX, B_NODE_EXEC, "",
|
||||
x, y + 1, width - slen, NODE_DY - 2,
|
||||
&ptr, "default_value", 0, 0, 0, -1, -1, "");
|
||||
if (node)
|
||||
uiButSetFunc(bt, node_sync_cb, CTX_wm_space_node(C), node);
|
||||
|
||||
if (slen > 0.0)
|
||||
uiDefBut(block, LABEL, 0, IFACE_(name), x + (width - slen), y + 2, slen, NODE_DY - 2, NULL, 0, 0, 0, 0, "");
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct SocketComponentMenuArgs {
|
||||
PointerRNA ptr;
|
||||
int x, y, width;
|
||||
@@ -3136,6 +3173,9 @@ void ED_node_init_butfuncs(void)
|
||||
case SOCK_BOOLEAN:
|
||||
stype->buttonfunc = node_socket_button_default;
|
||||
break;
|
||||
case SOCK_STRING:
|
||||
stype->buttonfunc = node_socket_button_string;
|
||||
break;
|
||||
case SOCK_VECTOR:
|
||||
stype->buttonfunc = node_socket_button_components;
|
||||
break;
|
||||
|
@@ -118,7 +118,8 @@ typedef struct bNodeSocket {
|
||||
#define SOCK_BOOLEAN 4
|
||||
#define SOCK_MESH 5
|
||||
#define SOCK_INT 6
|
||||
#define NUM_SOCKET_TYPES 7 /* must be last! */
|
||||
#define SOCK_STRING 7
|
||||
#define NUM_SOCKET_TYPES 8 /* must be last! */
|
||||
|
||||
/* socket side (input/output) */
|
||||
#define SOCK_IN 1
|
||||
@@ -353,6 +354,11 @@ typedef struct bNodeSocketValueRGBA {
|
||||
float value[4];
|
||||
} bNodeSocketValueRGBA;
|
||||
|
||||
typedef struct bNodeSocketValueString {
|
||||
int subtype;
|
||||
int pad;
|
||||
char value[1024]; /* 1024 = FILEMAX */
|
||||
} bNodeSocketValueString;
|
||||
|
||||
/* data structs, for node->storage */
|
||||
enum {
|
||||
|
@@ -92,6 +92,7 @@ EnumPropertyItem node_socket_type_items[] = {
|
||||
{SOCK_BOOLEAN, "BOOLEAN", 0, "Boolean", ""},
|
||||
{SOCK_MESH, "MESH", 0, "Mesh", ""},
|
||||
{SOCK_INT, "INT", 0, "Int", ""},
|
||||
{SOCK_STRING, "STRING", 0, "String", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
@@ -192,6 +193,10 @@ EnumPropertyItem prop_wave_items[] = {
|
||||
SUBTYPE(FLOAT, Float, TIME, Time) \
|
||||
SUBTYPE(FLOAT, Float, DISTANCE, Distance)
|
||||
|
||||
#define NODE_DEFINE_SUBTYPES_STRING \
|
||||
SUBTYPE(STRING, String, NONE, None) \
|
||||
SUBTYPE(STRING, String, FILEPATH, Filepath)
|
||||
|
||||
#define NODE_DEFINE_SUBTYPES_VECTOR \
|
||||
SUBTYPE(VECTOR, Vector, NONE, None) \
|
||||
SUBTYPE(VECTOR, Vector, TRANSLATION, Translation) \
|
||||
@@ -204,7 +209,8 @@ EnumPropertyItem prop_wave_items[] = {
|
||||
#define NODE_DEFINE_SUBTYPES \
|
||||
NODE_DEFINE_SUBTYPES_INT \
|
||||
NODE_DEFINE_SUBTYPES_FLOAT \
|
||||
NODE_DEFINE_SUBTYPES_VECTOR
|
||||
NODE_DEFINE_SUBTYPES_STRING \
|
||||
NODE_DEFINE_SUBTYPES_VECTOR \
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
|
||||
@@ -292,6 +298,9 @@ static StructRNA *rna_NodeSocket_refine(PointerRNA *ptr)
|
||||
case SOCK_VECTOR:
|
||||
NODE_DEFINE_SUBTYPES_VECTOR
|
||||
break;
|
||||
case SOCK_STRING:
|
||||
NODE_DEFINE_SUBTYPES_STRING
|
||||
break;
|
||||
case SOCK_RGBA:
|
||||
return &RNA_NodeSocketRGBA;
|
||||
case SOCK_SHADER:
|
||||
@@ -4533,6 +4542,20 @@ static void rna_def_node_socket_subtype(BlenderRNA *brna, int type, int subtype,
|
||||
RNA_def_property_ui_text(prop, "Default Value", "");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update");
|
||||
break;
|
||||
case SOCK_STRING:
|
||||
RNA_def_struct_sdna_from(srna, "bNodeSocketValueString", "default_value");
|
||||
|
||||
prop = RNA_def_property(srna, "subtype", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "subtype");
|
||||
RNA_def_property_enum_items(prop, subtype_items);
|
||||
RNA_def_property_ui_text(prop, "Subtype", "Subtype defining the socket value details");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update");
|
||||
|
||||
prop = RNA_def_property(srna, "default_value", PROP_STRING, PROP_FILEPATH);
|
||||
RNA_def_property_string_sdna(prop, NULL, "value");
|
||||
RNA_def_property_ui_text(prop, "Default Value", "");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update");
|
||||
break;
|
||||
}
|
||||
|
||||
/* XXX need to reset the from-type here, so subtype subclasses cast correctly! (RNA bug) */
|
||||
|
@@ -60,6 +60,7 @@ void node_socket_set_default_value_vector(void *default_value, PropertySubType s
|
||||
void node_socket_set_default_value_rgba(void *default_value, float r, float g, float b, float a);
|
||||
void node_socket_set_default_value_shader(void *default_value);
|
||||
void node_socket_set_default_value_mesh(void *default_value);
|
||||
void node_socket_set_default_value_string(void *default_value, PropertySubType subtype, const char *value);
|
||||
|
||||
struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp);
|
||||
struct bNodeSocket *node_add_output_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp);
|
||||
|
@@ -41,6 +41,7 @@
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_node.h"
|
||||
@@ -157,6 +158,20 @@ static bNodeSocketType node_socket_type_mesh = {
|
||||
/* buttonfunc */ NULL,
|
||||
};
|
||||
|
||||
/****************** STRING ******************/
|
||||
|
||||
static bNodeSocketType node_socket_type_string = {
|
||||
/* type */ SOCK_STRING,
|
||||
/* ui_name */ "String",
|
||||
/* ui_description */ "String",
|
||||
/* ui_icon */ 0,
|
||||
/* ui_color */ {255, 255, 255, 255},
|
||||
|
||||
/* value_structname */ "bNodeSocketValueString",
|
||||
/* value_structsize */ sizeof(bNodeSocketValueString),
|
||||
|
||||
/* buttonfunc */ NULL,
|
||||
};
|
||||
|
||||
void node_socket_type_init(bNodeSocketType *types[])
|
||||
{
|
||||
@@ -169,6 +184,7 @@ void node_socket_type_init(bNodeSocketType *types[])
|
||||
INIT_TYPE(boolean);
|
||||
INIT_TYPE(shader);
|
||||
INIT_TYPE(mesh);
|
||||
INIT_TYPE(string);
|
||||
|
||||
#undef INIT_TYPE
|
||||
}
|
||||
@@ -218,6 +234,9 @@ void node_socket_init_default_value(int type, void *default_value)
|
||||
case SOCK_MESH:
|
||||
node_socket_set_default_value_mesh(default_value);
|
||||
break;
|
||||
case SOCK_STRING:
|
||||
node_socket_set_default_value_string(default_value, PROP_NONE, (char *)"");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,6 +284,13 @@ void node_socket_set_default_value_rgba(void *default_value, float r, float g, f
|
||||
val->value[3] = a;
|
||||
}
|
||||
|
||||
void node_socket_set_default_value_string(void *default_value, PropertySubType subtype, const char *value)
|
||||
{
|
||||
bNodeSocketValueString *val = default_value;
|
||||
val->subtype = subtype;
|
||||
BLI_strncpy(val->value, value, 1024);//FILE_MAX
|
||||
}
|
||||
|
||||
void node_socket_set_default_value_shader(void *UNUSED(default_value))
|
||||
{
|
||||
}
|
||||
@@ -282,12 +308,14 @@ void node_socket_copy_default_value(int type, void *to_default_value, void *from
|
||||
bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from_default_value;
|
||||
bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from_default_value;
|
||||
bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from_default_value;
|
||||
bNodeSocketValueString *fromstring= (bNodeSocketValueString*)from_default_value;
|
||||
|
||||
bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to_default_value;
|
||||
bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to_default_value;
|
||||
bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to_default_value;
|
||||
bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to_default_value;
|
||||
bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to_default_value;
|
||||
bNodeSocketValueString *tostring= (bNodeSocketValueString*)to_default_value;
|
||||
|
||||
switch (type) {
|
||||
case SOCK_FLOAT:
|
||||
@@ -305,6 +333,9 @@ void node_socket_copy_default_value(int type, void *to_default_value, void *from
|
||||
case SOCK_RGBA:
|
||||
*torgba = *fromrgba;
|
||||
break;
|
||||
case SOCK_STRING:
|
||||
*tostring = *fromstring;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,6 +501,9 @@ struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct
|
||||
case SOCK_MESH:
|
||||
node_socket_set_default_value_mesh(sock->default_value);
|
||||
break;
|
||||
case SOCK_STRING:
|
||||
node_socket_set_default_value_string(sock->default_value, stemp->subtype, (char *)"");
|
||||
break;
|
||||
}
|
||||
|
||||
return sock;
|
||||
|
Reference in New Issue
Block a user