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_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);

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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;
}

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 {
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;

View File

@@ -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 {

View File

@@ -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) */

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_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);

View File

@@ -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;