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:
Dalai Felinto
2012-11-06 21:36:44 +00:00
parent d68981158b
commit 0890c2a4a0
10 changed files with 136 additions and 8 deletions

View File

@@ -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_float4[4] = {0.0f, 0.0f, 0.0f, 1.0f};
float default_float = 0.0f; float default_float = 0.0f;
int default_int = 0; int default_int = 0;
std::string default_string = "";
if(param->isclosure) { if(param->isclosure) {
socket_type = BL::NodeSocket::type_SHADER; socket_type = BL::NodeSocket::type_SHADER;
@@ -252,6 +253,11 @@ static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
if(param->validdefault) if(param->validdefault)
default_float = param->fdefault[0]; 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 else
continue; continue;
@@ -286,6 +292,10 @@ static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
BL::NodeSocketVectorNone b_vector_sock(b_sock.ptr); BL::NodeSocketVectorNone b_vector_sock(b_sock.ptr);
b_vector_sock.default_value(default_float4); 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); used_sockets.insert(b_sock.ptr.data);

View File

@@ -90,6 +90,8 @@ static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type)
return SHADER_SOCKET_COLOR; return SHADER_SOCKET_COLOR;
case BL::NodeSocket::type_SHADER: case BL::NodeSocket::type_SHADER:
return SHADER_SOCKET_CLOSURE; return SHADER_SOCKET_CLOSURE;
case BL::NodeSocket::type_STRING:
return SHADER_SOCKET_STRING;
case BL::NodeSocket::type_BOOLEAN: case BL::NodeSocket::type_BOOLEAN:
case BL::NodeSocket::type_MESH: 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 */ /* copy values for non linked inputs */
switch(input->type) { 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())); input->set(get_float3(vec_sock.default_value()));
break; 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: case SHADER_SOCKET_CLOSURE:
break; 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) { 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())); 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())); 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; 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); group_sockmap[b_input->group_socket().ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
/* default input values of the group node */ /* 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) { 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); group_sockmap[b_output->group_socket().ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
/* default input values of internal, unlinked group outputs */ /* 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); 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); assert(input);
/* copy values for non linked inputs */ /* copy values for non linked inputs */
set_default_value(input, *b_input); set_default_value(input, *b_input, b_data, b_ntree);
} }
} }
} }

View File

@@ -326,6 +326,7 @@ void ShaderGraph::remove_proxy_nodes(vector<bool>& removed)
/* transfer the default input value to the target socket */ /* transfer the default input value to the target socket */
to->set(input->value); to->set(input->value);
to->set(input->value_string);
} }
} }

View File

@@ -49,7 +49,8 @@ enum ShaderSocketType {
SHADER_SOCKET_VECTOR, SHADER_SOCKET_VECTOR,
SHADER_SOCKET_POINT, SHADER_SOCKET_POINT,
SHADER_SOCKET_NORMAL, SHADER_SOCKET_NORMAL,
SHADER_SOCKET_CLOSURE SHADER_SOCKET_CLOSURE,
SHADER_SOCKET_STRING
}; };
/* Bump /* Bump
@@ -120,6 +121,7 @@ public:
ShaderInput(ShaderNode *parent, const char *name, ShaderSocketType type); ShaderInput(ShaderNode *parent, const char *name, ShaderSocketType type);
void set(const float3& v) { value = v; } void set(const float3& v) { value = v; }
void set(float f) { value = make_float3(f, 0, 0); } void set(float f) { value = make_float3(f, 0, 0); }
void set(const ustring v) { value_string = v; }
const char *name; const char *name;
ShaderSocketType type; ShaderSocketType type;
@@ -129,6 +131,7 @@ public:
DefaultValue default_value; DefaultValue default_value;
float3 value; float3 value;
ustring value_string;
int stack_offset; /* for SVM compiler */ int stack_offset; /* for SVM compiler */
bool osl_only; bool osl_only;

View File

@@ -403,6 +403,9 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
case SHADER_SOCKET_INT: case SHADER_SOCKET_INT:
parameter(param_name.c_str(), (int)input->value.x); parameter(param_name.c_str(), (int)input->value.x);
break; break;
case SHADER_SOCKET_STRING:
parameter(param_name.c_str(), input->value_string);
break;
case SHADER_SOCKET_CLOSURE: case SHADER_SOCKET_CLOSURE:
break; break;
} }

View File

@@ -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 { typedef struct SocketComponentMenuArgs {
PointerRNA ptr; PointerRNA ptr;
int x, y, width; int x, y, width;
@@ -3136,6 +3173,9 @@ void ED_node_init_butfuncs(void)
case SOCK_BOOLEAN: case SOCK_BOOLEAN:
stype->buttonfunc = node_socket_button_default; stype->buttonfunc = node_socket_button_default;
break; break;
case SOCK_STRING:
stype->buttonfunc = node_socket_button_string;
break;
case SOCK_VECTOR: case SOCK_VECTOR:
stype->buttonfunc = node_socket_button_components; stype->buttonfunc = node_socket_button_components;
break; break;

View File

@@ -118,7 +118,8 @@ typedef struct bNodeSocket {
#define SOCK_BOOLEAN 4 #define SOCK_BOOLEAN 4
#define SOCK_MESH 5 #define SOCK_MESH 5
#define SOCK_INT 6 #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) */ /* socket side (input/output) */
#define SOCK_IN 1 #define SOCK_IN 1
@@ -353,6 +354,11 @@ typedef struct bNodeSocketValueRGBA {
float value[4]; float value[4];
} bNodeSocketValueRGBA; } bNodeSocketValueRGBA;
typedef struct bNodeSocketValueString {
int subtype;
int pad;
char value[1024]; /* 1024 = FILEMAX */
} bNodeSocketValueString;
/* data structs, for node->storage */ /* data structs, for node->storage */
enum { enum {

View File

@@ -92,6 +92,7 @@ EnumPropertyItem node_socket_type_items[] = {
{SOCK_BOOLEAN, "BOOLEAN", 0, "Boolean", ""}, {SOCK_BOOLEAN, "BOOLEAN", 0, "Boolean", ""},
{SOCK_MESH, "MESH", 0, "Mesh", ""}, {SOCK_MESH, "MESH", 0, "Mesh", ""},
{SOCK_INT, "INT", 0, "Int", ""}, {SOCK_INT, "INT", 0, "Int", ""},
{SOCK_STRING, "STRING", 0, "String", ""},
{0, NULL, 0, NULL, NULL} {0, NULL, 0, NULL, NULL}
}; };
@@ -192,6 +193,10 @@ EnumPropertyItem prop_wave_items[] = {
SUBTYPE(FLOAT, Float, TIME, Time) \ SUBTYPE(FLOAT, Float, TIME, Time) \
SUBTYPE(FLOAT, Float, DISTANCE, Distance) 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 \ #define NODE_DEFINE_SUBTYPES_VECTOR \
SUBTYPE(VECTOR, Vector, NONE, None) \ SUBTYPE(VECTOR, Vector, NONE, None) \
SUBTYPE(VECTOR, Vector, TRANSLATION, Translation) \ SUBTYPE(VECTOR, Vector, TRANSLATION, Translation) \
@@ -204,7 +209,8 @@ EnumPropertyItem prop_wave_items[] = {
#define NODE_DEFINE_SUBTYPES \ #define NODE_DEFINE_SUBTYPES \
NODE_DEFINE_SUBTYPES_INT \ NODE_DEFINE_SUBTYPES_INT \
NODE_DEFINE_SUBTYPES_FLOAT \ NODE_DEFINE_SUBTYPES_FLOAT \
NODE_DEFINE_SUBTYPES_VECTOR NODE_DEFINE_SUBTYPES_STRING \
NODE_DEFINE_SUBTYPES_VECTOR \
#ifdef RNA_RUNTIME #ifdef RNA_RUNTIME
@@ -292,6 +298,9 @@ static StructRNA *rna_NodeSocket_refine(PointerRNA *ptr)
case SOCK_VECTOR: case SOCK_VECTOR:
NODE_DEFINE_SUBTYPES_VECTOR NODE_DEFINE_SUBTYPES_VECTOR
break; break;
case SOCK_STRING:
NODE_DEFINE_SUBTYPES_STRING
break;
case SOCK_RGBA: case SOCK_RGBA:
return &RNA_NodeSocketRGBA; return &RNA_NodeSocketRGBA;
case SOCK_SHADER: 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_ui_text(prop, "Default Value", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update");
break; 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) */ /* XXX need to reset the from-type here, so subtype subclasses cast correctly! (RNA bug) */

View File

@@ -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_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_shader(void *default_value);
void node_socket_set_default_value_mesh(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_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); struct bNodeSocket *node_add_output_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp);

View File

@@ -41,6 +41,7 @@
#include "BLI_listbase.h" #include "BLI_listbase.h"
#include "BLI_math.h" #include "BLI_math.h"
#include "BLI_utildefines.h" #include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BKE_DerivedMesh.h" #include "BKE_DerivedMesh.h"
#include "BKE_node.h" #include "BKE_node.h"
@@ -157,6 +158,20 @@ static bNodeSocketType node_socket_type_mesh = {
/* buttonfunc */ NULL, /* 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[]) void node_socket_type_init(bNodeSocketType *types[])
{ {
@@ -169,6 +184,7 @@ void node_socket_type_init(bNodeSocketType *types[])
INIT_TYPE(boolean); INIT_TYPE(boolean);
INIT_TYPE(shader); INIT_TYPE(shader);
INIT_TYPE(mesh); INIT_TYPE(mesh);
INIT_TYPE(string);
#undef INIT_TYPE #undef INIT_TYPE
} }
@@ -218,6 +234,9 @@ void node_socket_init_default_value(int type, void *default_value)
case SOCK_MESH: case SOCK_MESH:
node_socket_set_default_value_mesh(default_value); node_socket_set_default_value_mesh(default_value);
break; 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; 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)) 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; bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from_default_value;
bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from_default_value; bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from_default_value;
bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from_default_value; bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from_default_value;
bNodeSocketValueString *fromstring= (bNodeSocketValueString*)from_default_value;
bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to_default_value; bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to_default_value;
bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to_default_value; bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to_default_value;
bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to_default_value; bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to_default_value;
bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to_default_value; bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to_default_value;
bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to_default_value; bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to_default_value;
bNodeSocketValueString *tostring= (bNodeSocketValueString*)to_default_value;
switch (type) { switch (type) {
case SOCK_FLOAT: case SOCK_FLOAT:
@@ -305,6 +333,9 @@ void node_socket_copy_default_value(int type, void *to_default_value, void *from
case SOCK_RGBA: case SOCK_RGBA:
*torgba = *fromrgba; *torgba = *fromrgba;
break; 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: case SOCK_MESH:
node_socket_set_default_value_mesh(sock->default_value); node_socket_set_default_value_mesh(sock->default_value);
break; break;
case SOCK_STRING:
node_socket_set_default_value_string(sock->default_value, stemp->subtype, (char *)"");
break;
} }
return sock; return sock;