Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Toenne <lukas.toenne@googlemail.com>2013-03-18 20:34:57 +0400
committerLukas Toenne <lukas.toenne@googlemail.com>2013-03-18 20:34:57 +0400
commit4638e5f99a9ba59ad0b8a1fd52b12e876480b9e8 (patch)
tree2444f12b4612440f44cf02835cdf5951b6564e92 /intern/cycles
parent7bfef29f2f2a1b262d28abdc6e30fcd9c1f1caad (diff)
Merge of the PyNodes branch (aka "custom nodes") into trunk.
PyNodes opens up the node system in Blender to scripters and adds a number of UI-level improvements. === Dynamic node type registration === Node types can now be added at runtime, using the RNA registration mechanism from python. This enables addons such as render engines to create a complete user interface with nodes. Examples of how such nodes can be defined can be found in my personal wiki docs atm [1] and as a script template in release/scripts/templates_py/custom_nodes.py [2]. === Node group improvements === Each node editor now has a tree history of edited node groups, which allows opening and editing nested node groups. The node editor also supports pinning now, so that different spaces can be used to edit different node groups simultaneously. For more ramblings and rationale see (really old) blog post on code.blender.org [3]. The interface of node groups has been overhauled. Sockets of a node group are no longer displayed in columns on either side, but instead special input/output nodes are used to mirror group sockets inside a node tree. This solves the problem of long node lines in groups and allows more adaptable node layout. Internal sockets can be exposed from a group by either connecting to the extension sockets in input/output nodes (shown as empty circle) or by adding sockets from the node property bar in the "Interface" panel. Further details such as the socket name can also be changed there. [1] http://wiki.blender.org/index.php/User:Phonybone/Python_Nodes [2] http://projects.blender.org/scm/viewvc.php/trunk/blender/release/scripts/templates_py/custom_nodes.py?view=markup&root=bf-blender [3] http://code.blender.org/index.php/2012/01/improving-node-group-interface-editing/
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/blender/blender_python.cpp93
-rw-r--r--intern/cycles/blender/blender_shader.cpp1148
-rw-r--r--intern/cycles/blender/blender_util.h60
-rw-r--r--intern/cycles/render/graph.h2
-rw-r--r--intern/cycles/render/nodes.cpp9
-rw-r--r--intern/cycles/render/nodes.h4
6 files changed, 655 insertions, 661 deletions
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index a10f3b63033..f7a05463f66 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -207,6 +207,7 @@ static PyObject *available_devices_func(PyObject *self, PyObject *args)
}
#ifdef WITH_OSL
+
static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
{
PyObject *pynodegroup, *pynode;
@@ -248,17 +249,19 @@ static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
continue;
/* determine socket type */
- BL::NodeSocket::type_enum socket_type;
- float default_float4[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ std::string socket_type;
+ BL::NodeSocket::type_enum data_type = BL::NodeSocket::type_VALUE;
+ float4 default_float4 = make_float4(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;
+ socket_type = "NodeSocketShader";
}
else if(param->type.vecsemantics == TypeDesc::COLOR) {
- socket_type = BL::NodeSocket::type_RGBA;
+ socket_type = "NodeSocketColor";
+ data_type = BL::NodeSocket::type_RGBA;
if(param->validdefault) {
default_float4[0] = param->fdefault[0];
@@ -269,7 +272,8 @@ static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
else if(param->type.vecsemantics == TypeDesc::POINT ||
param->type.vecsemantics == TypeDesc::VECTOR ||
param->type.vecsemantics == TypeDesc::NORMAL) {
- socket_type = BL::NodeSocket::type_VECTOR;
+ socket_type = "NodeSocketVector";
+ data_type = BL::NodeSocket::type_VECTOR;
if(param->validdefault) {
default_float4[0] = param->fdefault[0];
@@ -279,17 +283,20 @@ static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
}
else if(param->type.aggregate == TypeDesc::SCALAR) {
if(param->type.basetype == TypeDesc::INT) {
- socket_type = BL::NodeSocket::type_INT;
+ socket_type = "NodeSocketInt";
+ data_type = BL::NodeSocket::type_INT;
if(param->validdefault)
default_int = param->idefault[0];
}
else if(param->type.basetype == TypeDesc::FLOAT) {
- socket_type = BL::NodeSocket::type_VALUE;
+ socket_type = "NodeSocketFloat";
+ data_type = BL::NodeSocket::type_VALUE;
if(param->validdefault)
default_float = param->fdefault[0];
}
else if(param->type.basetype == TypeDesc::STRING) {
- socket_type = BL::NodeSocket::type_STRING;
+ socket_type = "NodeSocketString";
+ data_type = BL::NodeSocket::type_STRING;
if(param->validdefault)
default_string = param->sdefault[0];
}
@@ -300,38 +307,52 @@ static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
continue;
/* find socket socket */
- BL::NodeSocket b_sock = b_node.find_socket(param->name.c_str(), param->isoutput);
-
- /* remove if type no longer matches */
- if(b_sock && b_sock.type() != socket_type) {
- b_node.remove_socket(b_sock);
- b_sock = BL::NodeSocket(PointerRNA_NULL);
+ BL::NodeSocket b_sock(PointerRNA_NULL);
+ if (param->isoutput) {
+ b_sock = b_node.outputs[param->name];
+
+ /* remove if type no longer matches */
+ if(b_sock && b_sock.bl_idname() != socket_type) {
+ b_node.outputs.remove(b_sock);
+ b_sock = BL::NodeSocket(PointerRNA_NULL);
+ }
+
+ if (!b_sock) {
+ /* create new socket */
+ b_sock = b_node.outputs.create(socket_type.c_str(), param->name.c_str(), param->name.c_str());
+ }
+ }
+ else {
+ b_sock = b_node.inputs[param->name];
+
+ /* remove if type no longer matches */
+ if(b_sock && b_sock.bl_idname() != socket_type) {
+ b_node.inputs.remove(b_sock);
+ b_sock = BL::NodeSocket(PointerRNA_NULL);
+ }
+
+ if (!b_sock) {
+ /* create new socket */
+ b_sock = b_node.inputs.create(socket_type.c_str(), param->name.c_str(), param->name.c_str());
+ }
}
- /* create new socket */
- if(!b_sock) {
- b_sock = b_node.add_socket(param->name.c_str(), socket_type, param->isoutput);
-
- /* set default value */
- if(socket_type == BL::NodeSocket::type_VALUE) {
- BL::NodeSocketFloatNone b_float_sock(b_sock.ptr);
- b_float_sock.default_value(default_float);
+ /* set default value */
+ if(b_sock) {
+ if(data_type == BL::NodeSocket::type_VALUE) {
+ set_float(b_sock.ptr, "default_value", default_float);
}
- else if(socket_type == BL::NodeSocket::type_INT) {
- BL::NodeSocketIntNone b_int_sock(b_sock.ptr);
- b_int_sock.default_value(default_int);
+ else if(data_type == BL::NodeSocket::type_INT) {
+ set_int(b_sock.ptr, "default_value", default_int);
}
- else if(socket_type == BL::NodeSocket::type_RGBA) {
- BL::NodeSocketRGBA b_rgba_sock(b_sock.ptr);
- b_rgba_sock.default_value(default_float4);
+ else if(data_type == BL::NodeSocket::type_RGBA) {
+ set_float4(b_sock.ptr, "default_value", default_float4);
}
- else if(socket_type == BL::NodeSocket::type_VECTOR) {
- BL::NodeSocketVectorNone b_vector_sock(b_sock.ptr);
- b_vector_sock.default_value(default_float4);
+ else if(data_type == BL::NodeSocket::type_VECTOR) {
+ set_float3(b_sock.ptr, "default_value", float4_to_float3(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);
+ else if(data_type == BL::NodeSocket::type_STRING) {
+ set_string(b_sock.ptr, "default_value", default_string);
}
}
@@ -349,7 +370,7 @@ static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
for (b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
if(used_sockets.find(b_input->ptr.data) == used_sockets.end()) {
- b_node.remove_socket(*b_input);
+ b_node.inputs.remove(*b_input);
removed = true;
break;
}
@@ -357,7 +378,7 @@ static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
for (b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
if(used_sockets.find(b_output->ptr.data) == used_sockets.end()) {
- b_node.remove_socket(*b_output);
+ b_node.outputs.remove(*b_output);
removed = true;
break;
}
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 0f7dc15db19..45a97f1d530 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -31,9 +31,9 @@
CCL_NAMESPACE_BEGIN
-typedef map<void*, ShaderNode*> PtrNodeMap;
-typedef pair<ShaderNode*, std::string> SocketPair;
-typedef map<void*, SocketPair> PtrSockMap;
+typedef map<void*, ShaderInput*> PtrInputMap;
+typedef map<void*, ShaderOutput*> PtrOutputMap;
+typedef map<std::string, ProxyNode*> ProxyMap;
/* Find */
@@ -55,83 +55,88 @@ void BlenderSync::find_shader(BL::ID id, vector<uint>& used_shaders, int default
static BL::NodeSocket get_node_output(BL::Node b_node, const string& name)
{
BL::Node::outputs_iterator b_out;
-
+
for(b_node.outputs.begin(b_out); b_out != b_node.outputs.end(); ++b_out)
if(b_out->name() == name)
return *b_out;
-
+
assert(0);
-
+
return *b_out;
}
static float3 get_node_output_rgba(BL::Node b_node, const string& name)
{
- BL::NodeSocketRGBA sock(get_node_output(b_node, name));
- return get_float3(sock.default_value());
+ BL::NodeSocket b_sock = get_node_output(b_node, name);
+ float value[4];
+ RNA_float_get_array(&b_sock.ptr, "default_value", value);
+ return make_float3(value[0], value[1], value[2]);
}
static float get_node_output_value(BL::Node b_node, const string& name)
{
- BL::NodeSocketFloatNone sock(get_node_output(b_node, name));
- return sock.default_value();
+ BL::NodeSocket b_sock = get_node_output(b_node, name);
+ return RNA_float_get(&b_sock.ptr, "default_value");
}
-static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type)
+static float3 get_node_output_vector(BL::Node b_node, const string& name)
{
- switch (b_type) {
- case BL::NodeSocket::type_VALUE:
- return SHADER_SOCKET_FLOAT;
- case BL::NodeSocket::type_INT:
- return SHADER_SOCKET_INT;
- case BL::NodeSocket::type_VECTOR:
- return SHADER_SOCKET_VECTOR;
- case BL::NodeSocket::type_RGBA:
- 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:
- default:
- return SHADER_SOCKET_FLOAT;
+ BL::NodeSocket b_sock = get_node_output(b_node, name);
+ float value[3];
+ RNA_float_get_array(&b_sock.ptr, "default_value", value);
+ return make_float3(value[0], value[1], value[2]);
+}
+
+static ShaderSocketType convert_socket_type(BL::NodeSocket b_socket)
+{
+ switch (b_socket.type()) {
+ case BL::NodeSocket::type_VALUE:
+ return SHADER_SOCKET_FLOAT;
+ case BL::NodeSocket::type_INT:
+ return SHADER_SOCKET_INT;
+ case BL::NodeSocket::type_VECTOR:
+ return SHADER_SOCKET_VECTOR;
+ case BL::NodeSocket::type_RGBA:
+ return SHADER_SOCKET_COLOR;
+ case BL::NodeSocket::type_STRING:
+ return SHADER_SOCKET_STRING;
+ case BL::NodeSocket::type_SHADER:
+ return SHADER_SOCKET_CLOSURE;
+
+ default:
+ return SHADER_SOCKET_UNDEFINED;
}
}
-static void set_default_value(ShaderInput *input, BL::NodeSocket sock, BL::BlendData b_data, BL::ID b_id)
+static void set_default_value(ShaderInput *input, BL::Node b_node, BL::NodeSocket b_sock, BL::BlendData b_data, BL::ID b_id)
{
/* copy values for non linked inputs */
switch(input->type) {
case SHADER_SOCKET_FLOAT: {
- BL::NodeSocketFloatNone value_sock(sock);
- input->set(value_sock.default_value());
+ input->set(get_float(b_sock.ptr, "default_value"));
break;
}
case SHADER_SOCKET_INT: {
- BL::NodeSocketIntNone value_sock(sock);
- input->set((float)value_sock.default_value());
+ input->set((float)get_int(b_sock.ptr, "default_value"));
break;
}
case SHADER_SOCKET_COLOR: {
- BL::NodeSocketRGBA rgba_sock(sock);
- input->set(get_float3(rgba_sock.default_value()));
+ input->set(float4_to_float3(get_float4(b_sock.ptr, "default_value")));
break;
}
case SHADER_SOCKET_NORMAL:
case SHADER_SOCKET_POINT:
case SHADER_SOCKET_VECTOR: {
- BL::NodeSocketVectorNone vec_sock(sock);
- input->set(get_float3(vec_sock.default_value()));
+ input->set(get_float3(b_sock.ptr, "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()));
+ input->set((ustring)blender_absolute_path(b_data, b_id, get_string(b_sock.ptr, "default_value")));
break;
}
+
case SHADER_SOCKET_CLOSURE:
+ case SHADER_SOCKET_UNDEFINED:
break;
}
}
@@ -171,295 +176,226 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
{
ShaderNode *node = NULL;
- switch(b_node.type()) {
- /* not supported */
- case BL::ShaderNode::type_GEOMETRY: break;
- case BL::ShaderNode::type_MATERIAL: break;
- case BL::ShaderNode::type_MATERIAL_EXT: break;
- case BL::ShaderNode::type_OUTPUT: break;
- case BL::ShaderNode::type_SQUEEZE: break;
- case BL::ShaderNode::type_TEXTURE: break;
- case BL::ShaderNode::type_FRAME: break;
- /* handled outside this function */
- case BL::ShaderNode::type_GROUP: break;
- /* existing blender nodes */
- case BL::ShaderNode::type_REROUTE: {
- BL::Node::inputs_iterator b_input;
- b_node.inputs.begin(b_input);
- BL::Node::outputs_iterator b_output;
- b_node.outputs.begin(b_output);
- ProxyNode *proxy = new ProxyNode(convert_socket_type(b_input->type()), convert_socket_type(b_output->type()));
- node = proxy;
- break;
- }
- case BL::ShaderNode::type_CURVE_VEC: {
- BL::ShaderNodeVectorCurve b_curve_node(b_node);
- VectorCurvesNode *curves = new VectorCurvesNode();
- curvemapping_color_to_array(b_curve_node.mapping(), curves->curves, RAMP_TABLE_SIZE, false);
- node = curves;
- break;
- }
- case BL::ShaderNode::type_CURVE_RGB: {
- BL::ShaderNodeRGBCurve b_curve_node(b_node);
- RGBCurvesNode *curves = new RGBCurvesNode();
- curvemapping_color_to_array(b_curve_node.mapping(), curves->curves, RAMP_TABLE_SIZE, true);
- node = curves;
- break;
- }
- case BL::ShaderNode::type_VALTORGB: {
- RGBRampNode *ramp = new RGBRampNode();
- BL::ShaderNodeValToRGB b_ramp_node(b_node);
- colorramp_to_array(b_ramp_node.color_ramp(), ramp->ramp, RAMP_TABLE_SIZE);
- node = ramp;
- break;
- }
- case BL::ShaderNode::type_RGB: {
- ColorNode *color = new ColorNode();
- color->value = get_node_output_rgba(b_node, "Color");
- node = color;
- break;
- }
- case BL::ShaderNode::type_VALUE: {
- ValueNode *value = new ValueNode();
- value->value = get_node_output_value(b_node, "Value");
- node = value;
- break;
- }
- case BL::ShaderNode::type_CAMERA: {
- node = new CameraNode();
- break;
- }
- case BL::ShaderNode::type_INVERT: {
- node = new InvertNode();
- break;
- }
- case BL::ShaderNode::type_GAMMA: {
- node = new GammaNode();
- break;
- }
- case BL::ShaderNode::type_BRIGHTCONTRAST: {
- node = new BrightContrastNode();
- break;
- }
- case BL::ShaderNode::type_MIX_RGB: {
- BL::ShaderNodeMixRGB b_mix_node(b_node);
- MixNode *mix = new MixNode();
- mix->type = MixNode::type_enum[b_mix_node.blend_type()];
+ /* existing blender nodes */
+ if (b_node.is_a(&RNA_ShaderNodeRGBCurve)) {
+ BL::ShaderNodeRGBCurve b_curve_node(b_node);
+ RGBCurvesNode *curves = new RGBCurvesNode();
+ curvemapping_color_to_array(b_curve_node.mapping(), curves->curves, RAMP_TABLE_SIZE, true);
+ node = curves;
+ }
+ if (b_node.is_a(&RNA_ShaderNodeVectorCurve)) {
+ BL::ShaderNodeVectorCurve b_curve_node(b_node);
+ VectorCurvesNode *curves = new VectorCurvesNode();
+ curvemapping_color_to_array(b_curve_node.mapping(), curves->curves, RAMP_TABLE_SIZE, false);
+ node = curves;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeValToRGB)) {
+ RGBRampNode *ramp = new RGBRampNode();
+ BL::ShaderNodeValToRGB b_ramp_node(b_node);
+ colorramp_to_array(b_ramp_node.color_ramp(), ramp->ramp, RAMP_TABLE_SIZE);
+ node = ramp;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeRGB)) {
+ ColorNode *color = new ColorNode();
+ color->value = get_node_output_rgba(b_node, "Color");
+ node = color;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeValue)) {
+ ValueNode *value = new ValueNode();
+ value->value = get_node_output_value(b_node, "Value");
+ node = value;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeCameraData)) {
+ node = new CameraNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeInvert)) {
+ node = new InvertNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeGamma)) {
+ node = new GammaNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBrightContrast)) {
+ node = new BrightContrastNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeMixRGB)) {
+ BL::ShaderNodeMixRGB b_mix_node(b_node);
+ MixNode *mix = new MixNode();
+ mix->type = MixNode::type_enum[b_mix_node.blend_type()];
mix->use_clamp = b_mix_node.use_clamp();
- node = mix;
- break;
- }
- case BL::ShaderNode::type_SEPRGB: {
- node = new SeparateRGBNode();
- break;
- }
- case BL::ShaderNode::type_COMBRGB: {
- node = new CombineRGBNode();
- break;
- }
- case BL::ShaderNode::type_HUE_SAT: {
- node = new HSVNode();
- break;
- }
- case BL::ShaderNode::type_RGBTOBW: {
- node = new ConvertNode(SHADER_SOCKET_COLOR, SHADER_SOCKET_FLOAT);
- break;
- }
- case BL::ShaderNode::type_MATH: {
- BL::ShaderNodeMath b_math_node(b_node);
- MathNode *math = new MathNode();
- math->type = MathNode::type_enum[b_math_node.operation()];
+ node = mix;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeSeparateRGB)) {
+ node = new SeparateRGBNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeCombineRGB)) {
+ node = new CombineRGBNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeHueSaturation)) {
+ node = new HSVNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeRGBToBW)) {
+ node = new ConvertNode(SHADER_SOCKET_COLOR, SHADER_SOCKET_FLOAT);
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeMath)) {
+ BL::ShaderNodeMath b_math_node(b_node);
+ MathNode *math = new MathNode();
+ math->type = MathNode::type_enum[b_math_node.operation()];
math->use_clamp = b_math_node.use_clamp();
- node = math;
- break;
- }
- case BL::ShaderNode::type_VECT_MATH: {
- BL::ShaderNodeVectorMath b_vector_math_node(b_node);
- VectorMathNode *vmath = new VectorMathNode();
- vmath->type = VectorMathNode::type_enum[b_vector_math_node.operation()];
- node = vmath;
- break;
- }
- case BL::ShaderNode::type_NORMAL: {
- BL::Node::outputs_iterator out_it;
- b_node.outputs.begin(out_it);
- BL::NodeSocketVectorNone vec_sock(*out_it);
-
- NormalNode *norm = new NormalNode();
- norm->direction = get_float3(vec_sock.default_value());
-
- node = norm;
- break;
- }
- case BL::ShaderNode::type_MAPPING: {
- BL::ShaderNodeMapping b_mapping_node(b_node);
- MappingNode *mapping = new MappingNode();
-
- get_tex_mapping(&mapping->tex_mapping, b_mapping_node);
-
- node = mapping;
- break;
- }
-
- /* new nodes */
- case BL::ShaderNode::type_OUTPUT_MATERIAL:
- case BL::ShaderNode::type_OUTPUT_WORLD:
- case BL::ShaderNode::type_OUTPUT_LAMP: {
- node = graph->output();
- break;
- }
- case BL::ShaderNode::type_FRESNEL: {
- node = new FresnelNode();
- break;
- }
- case BL::ShaderNode::type_LAYER_WEIGHT: {
- node = new LayerWeightNode();
- break;
- }
- case BL::ShaderNode::type_ADD_SHADER: {
- node = new AddClosureNode();
- break;
- }
- case BL::ShaderNode::type_MIX_SHADER: {
- node = new MixClosureNode();
- break;
- }
- case BL::ShaderNode::type_ATTRIBUTE: {
- BL::ShaderNodeAttribute b_attr_node(b_node);
- AttributeNode *attr = new AttributeNode();
- attr->attribute = b_attr_node.attribute_name();
- node = attr;
- break;
- }
- case BL::ShaderNode::type_BACKGROUND: {
- node = new BackgroundNode();
- break;
- }
- case BL::ShaderNode::type_HOLDOUT: {
- node = new HoldoutNode();
- break;
- }
- case BL::ShaderNode::type_BSDF_ANISOTROPIC: {
- node = new WardBsdfNode();
- break;
- }
- case BL::ShaderNode::type_BSDF_DIFFUSE: {
- node = new DiffuseBsdfNode();
- break;
- }
- case BL::ShaderNode::type_BSDF_GLOSSY: {
- BL::ShaderNodeBsdfGlossy b_glossy_node(b_node);
- GlossyBsdfNode *glossy = new GlossyBsdfNode();
-
- switch(b_glossy_node.distribution()) {
- case BL::ShaderNodeBsdfGlossy::distribution_SHARP:
- glossy->distribution = ustring("Sharp");
- break;
- case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN:
- glossy->distribution = ustring("Beckmann");
- break;
- case BL::ShaderNodeBsdfGlossy::distribution_GGX:
- glossy->distribution = ustring("GGX");
- break;
- }
- node = glossy;
- break;
- }
- case BL::ShaderNode::type_BSDF_GLASS: {
- BL::ShaderNodeBsdfGlass b_glass_node(b_node);
- GlassBsdfNode *glass = new GlassBsdfNode();
- switch(b_glass_node.distribution()) {
- case BL::ShaderNodeBsdfGlass::distribution_SHARP:
- glass->distribution = ustring("Sharp");
- break;
- case BL::ShaderNodeBsdfGlass::distribution_BECKMANN:
- glass->distribution = ustring("Beckmann");
- break;
- case BL::ShaderNodeBsdfGlass::distribution_GGX:
- glass->distribution = ustring("GGX");
- break;
- }
- node = glass;
- break;
- }
- case BL::ShaderNode::type_BSDF_REFRACTION: {
- BL::ShaderNodeBsdfRefraction b_refraction_node(b_node);
- RefractionBsdfNode *refraction = new RefractionBsdfNode();
- switch(b_refraction_node.distribution()) {
- case BL::ShaderNodeBsdfRefraction::distribution_SHARP:
- refraction->distribution = ustring("Sharp");
- break;
- case BL::ShaderNodeBsdfRefraction::distribution_BECKMANN:
- refraction->distribution = ustring("Beckmann");
- break;
- case BL::ShaderNodeBsdfRefraction::distribution_GGX:
- refraction->distribution = ustring("GGX");
- break;
- }
- node = refraction;
- break;
- }
- case BL::ShaderNode::type_BSDF_TRANSLUCENT: {
- node = new TranslucentBsdfNode();
- break;
- }
- case BL::ShaderNode::type_BSDF_TRANSPARENT: {
- node = new TransparentBsdfNode();
- break;
- }
- case BL::ShaderNode::type_BSDF_VELVET: {
- node = new VelvetBsdfNode();
- break;
- }
- case BL::ShaderNode::type_EMISSION: {
- node = new EmissionNode();
- break;
- }
- case BL::ShaderNode::type_AMBIENT_OCCLUSION: {
- node = new AmbientOcclusionNode();
- break;
- }
- case BL::ShaderNode::type_VOLUME_ISOTROPIC: {
- node = new IsotropicVolumeNode();
- break;
- }
- case BL::ShaderNode::type_VOLUME_TRANSPARENT: {
- node = new TransparentVolumeNode();
- break;
- }
- case BL::ShaderNode::type_NEW_GEOMETRY: {
- node = new GeometryNode();
+ node = math;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeVectorMath)) {
+ BL::ShaderNodeVectorMath b_vector_math_node(b_node);
+ VectorMathNode *vmath = new VectorMathNode();
+ vmath->type = VectorMathNode::type_enum[b_vector_math_node.operation()];
+ node = vmath;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeNormal)) {
+ BL::Node::outputs_iterator out_it;
+ b_node.outputs.begin(out_it);
+ BL::NodeSocket vec_sock(*out_it);
+
+ NormalNode *norm = new NormalNode();
+ norm->direction = get_node_output_vector(b_node, "Normal");
+ node = norm;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeMapping)) {
+ BL::ShaderNodeMapping b_mapping_node(b_node);
+ MappingNode *mapping = new MappingNode();
+
+ get_tex_mapping(&mapping->tex_mapping, b_mapping_node);
+
+ node = mapping;
+ }
+ /* new nodes */
+ else if (b_node.is_a(&RNA_ShaderNodeOutputMaterial)
+ || b_node.is_a(&RNA_ShaderNodeOutputWorld)
+ || b_node.is_a(&RNA_ShaderNodeOutputLamp)) {
+ node = graph->output();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeFresnel)) {
+ node = new FresnelNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeLayerWeight)) {
+ node = new LayerWeightNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeAddShader)) {
+ node = new AddClosureNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeMixShader)) {
+ node = new MixClosureNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeAttribute)) {
+ BL::ShaderNodeAttribute b_attr_node(b_node);
+ AttributeNode *attr = new AttributeNode();
+ attr->attribute = b_attr_node.attribute_name();
+ node = attr;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBackground)) {
+ node = new BackgroundNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeHoldout)) {
+ node = new HoldoutNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfAnisotropic)) {
+ node = new WardBsdfNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfDiffuse)) {
+ node = new DiffuseBsdfNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfGlossy)) {
+ BL::ShaderNodeBsdfGlossy b_glossy_node(b_node);
+ GlossyBsdfNode *glossy = new GlossyBsdfNode();
+
+ switch(b_glossy_node.distribution()) {
+ case BL::ShaderNodeBsdfGlossy::distribution_SHARP:
+ glossy->distribution = ustring("Sharp");
break;
- }
- case BL::ShaderNode::type_LIGHT_PATH: {
- node = new LightPathNode();
+ case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN:
+ glossy->distribution = ustring("Beckmann");
break;
- }
- case BL::ShaderNode::type_LIGHT_FALLOFF: {
- node = new LightFalloffNode();
+ case BL::ShaderNodeBsdfGlossy::distribution_GGX:
+ glossy->distribution = ustring("GGX");
break;
}
- case BL::ShaderNode::type_OBJECT_INFO: {
- node = new ObjectInfoNode();
+ node = glossy;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfGlass)) {
+ BL::ShaderNodeBsdfGlass b_glass_node(b_node);
+ GlassBsdfNode *glass = new GlassBsdfNode();
+ switch(b_glass_node.distribution()) {
+ case BL::ShaderNodeBsdfGlass::distribution_SHARP:
+ glass->distribution = ustring("Sharp");
break;
- }
- case BL::ShaderNode::type_PARTICLE_INFO: {
- node = new ParticleInfoNode();
+ case BL::ShaderNodeBsdfGlass::distribution_BECKMANN:
+ glass->distribution = ustring("Beckmann");
break;
- }
- case BL::ShaderNode::type_HAIR_INFO: {
- node = new HairInfoNode();
+ case BL::ShaderNodeBsdfGlass::distribution_GGX:
+ glass->distribution = ustring("GGX");
break;
}
- case BL::ShaderNode::type_BUMP: {
- node = new BumpNode();
- break;
+ node = glass;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfRefraction)) {
+ BL::ShaderNodeBsdfRefraction b_refraction_node(b_node);
+ RefractionBsdfNode *refraction = new RefractionBsdfNode();
+ switch(b_refraction_node.distribution()) {
+ case BL::ShaderNodeBsdfRefraction::distribution_SHARP:
+ refraction->distribution = ustring("Sharp");
+ break;
+ case BL::ShaderNodeBsdfRefraction::distribution_BECKMANN:
+ refraction->distribution = ustring("Beckmann");
+ break;
+ case BL::ShaderNodeBsdfRefraction::distribution_GGX:
+ refraction->distribution = ustring("GGX");
+ break;
}
- case BL::ShaderNode::type_SCRIPT: {
+ node = refraction;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfTranslucent)) {
+ node = new TranslucentBsdfNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfTransparent)) {
+ node = new TransparentBsdfNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBsdfVelvet)) {
+ node = new VelvetBsdfNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeEmission)) {
+ node = new EmissionNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeAmbientOcclusion)) {
+ node = new AmbientOcclusionNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeVolumeIsotropic)) {
+ node = new IsotropicVolumeNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeVolumeTransparent)) {
+ node = new TransparentVolumeNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeNewGeometry)) {
+ node = new GeometryNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeLightPath)) {
+ node = new LightPathNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeLightFalloff)) {
+ node = new LightFalloffNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeObjectInfo)) {
+ node = new ObjectInfoNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeParticleInfo)) {
+ node = new ParticleInfoNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeHairInfo)) {
+ node = new HairInfoNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeBump)) {
+ node = new BumpNode();
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeScript)) {
#ifdef WITH_OSL
- if(!scene->shader_manager->use_osl())
- break;
-
+ if(scene->shader_manager->use_osl()) {
/* create script node */
BL::ShaderNodeScript b_script_node(b_node);
OSLScriptNode *script_node = new OSLScriptNode();
@@ -472,29 +408,31 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
* Note 2: ShaderInput/ShaderOutput store shallow string copies only!
* Socket names must be stored in the extra lists instead. */
BL::Node::inputs_iterator 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()));
- 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, b_data, b_ntree);
+ ShaderInput *input = script_node->add_input(script_node->input_names.back().c_str(),
+ convert_socket_type(*b_input));
+ set_default_value(input, b_node, *b_input, b_data, b_ntree);
}
-
+
BL::Node::outputs_iterator b_output;
-
+
for (b_script_node.outputs.begin(b_output); b_output != b_script_node.outputs.end(); ++b_output) {
script_node->output_names.push_back(ustring(b_output->name()));
- script_node->add_output(script_node->output_names.back().c_str(), convert_socket_type(b_output->type()));
+ script_node->add_output(script_node->output_names.back().c_str(),
+ convert_socket_type(*b_output));
}
-
+
/* load bytecode or filepath */
OSLShaderManager *manager = (OSLShaderManager*)scene->shader_manager;
string bytecode_hash = b_script_node.bytecode_hash();
-
+
if(!bytecode_hash.empty()) {
/* loaded bytecode if not already done */
if(!manager->shader_test_loaded(bytecode_hash))
manager->shader_load_bytecode(bytecode_hash, b_script_node.bytecode());
-
+
script_node->bytecode_hash = bytecode_hash;
}
else {
@@ -503,173 +441,157 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
}
node = script_node;
-#endif
-
- break;
}
- case BL::ShaderNode::type_TEX_IMAGE: {
- BL::ShaderNodeTexImage b_image_node(b_node);
- BL::Image b_image(b_image_node.image());
- ImageTextureNode *image = new ImageTextureNode();
- if(b_image) {
- /* builtin images will use callback-based reading because
- * they could only be loaded correct from blender side
+#endif
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexImage)) {
+ BL::ShaderNodeTexImage b_image_node(b_node);
+ BL::Image b_image(b_image_node.image());
+ ImageTextureNode *image = new ImageTextureNode();
+ if(b_image) {
+ /* builtin images will use callback-based reading because
+ * they could only be loaded correct from blender side
+ */
+ bool is_builtin = b_image.packed_file() ||
+ b_image.source() == BL::Image::source_GENERATED ||
+ b_image.source() == BL::Image::source_MOVIE;
+
+ if(is_builtin) {
+ /* for builtin images we're using image datablock name to find an image to
+ * read pixels from later
+ *
+ * also store frame number as well, so there's no differences in handling
+ * builtin names for packed images and movies
*/
- bool is_builtin = b_image.packed_file() ||
- b_image.source() == BL::Image::source_GENERATED ||
- b_image.source() == BL::Image::source_MOVIE;
-
- if(is_builtin) {
- /* for builtin images we're using image datablock name to find an image to
- * read pixels from later
- *
- * also store frame number as well, so there's no differences in handling
- * builtin names for packed images and movies
- */
- int scene_frame = b_scene.frame_current();
- int image_frame = image_user_frame_number(b_image_node.image_user(), scene_frame);
- image->filename = b_image.name() + "@" + string_printf("%d", image_frame);
- image->builtin_data = b_image.ptr.data;
- }
- else {
- image->filename = image_user_file_path(b_image_node.image_user(), b_image, b_scene.frame_current());
- image->builtin_data = NULL;
- }
-
- image->animated = b_image_node.image_user().use_auto_refresh();
+ int scene_frame = b_scene.frame_current();
+ int image_frame = image_user_frame_number(b_image_node.image_user(), scene_frame);
+ image->filename = b_image.name() + "@" + string_printf("%d", image_frame);
+ image->builtin_data = b_image.ptr.data;
}
- image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()];
- image->projection = ImageTextureNode::projection_enum[(int)b_image_node.projection()];
- image->projection_blend = b_image_node.projection_blend();
- get_tex_mapping(&image->tex_mapping, b_image_node.texture_mapping());
- node = image;
- break;
- }
- case BL::ShaderNode::type_TEX_ENVIRONMENT: {
- BL::ShaderNodeTexEnvironment b_env_node(b_node);
- BL::Image b_image(b_env_node.image());
- EnvironmentTextureNode *env = new EnvironmentTextureNode();
- if(b_image) {
- bool is_builtin = b_image.packed_file() ||
- b_image.source() == BL::Image::source_GENERATED ||
- b_image.source() == BL::Image::source_MOVIE;
-
- if(is_builtin) {
- int scene_frame = b_scene.frame_current();
- int image_frame = image_user_frame_number(b_env_node.image_user(), scene_frame);
- env->filename = b_image.name() + "@" + string_printf("%d", image_frame);
- env->builtin_data = b_image.ptr.data;
- }
- else {
- env->filename = image_user_file_path(b_env_node.image_user(), b_image, b_scene.frame_current());
- env->animated = b_env_node.image_user().use_auto_refresh();
- env->builtin_data = NULL;
- }
+ else {
+ image->filename = image_user_file_path(b_image_node.image_user(), b_image, b_scene.frame_current());
+ image->builtin_data = NULL;
}
- env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
- env->projection = EnvironmentTextureNode::projection_enum[(int)b_env_node.projection()];
- get_tex_mapping(&env->tex_mapping, b_env_node.texture_mapping());
- node = env;
- break;
- }
- case BL::ShaderNode::type_TEX_GRADIENT: {
- BL::ShaderNodeTexGradient b_gradient_node(b_node);
- GradientTextureNode *gradient = new GradientTextureNode();
- gradient->type = GradientTextureNode::type_enum[(int)b_gradient_node.gradient_type()];
- get_tex_mapping(&gradient->tex_mapping, b_gradient_node.texture_mapping());
- node = gradient;
- break;
- }
- case BL::ShaderNode::type_TEX_VORONOI: {
- BL::ShaderNodeTexVoronoi b_voronoi_node(b_node);
- VoronoiTextureNode *voronoi = new VoronoiTextureNode();
- voronoi->coloring = VoronoiTextureNode::coloring_enum[(int)b_voronoi_node.coloring()];
- get_tex_mapping(&voronoi->tex_mapping, b_voronoi_node.texture_mapping());
- node = voronoi;
- break;
- }
- case BL::ShaderNode::type_TEX_MAGIC: {
- BL::ShaderNodeTexMagic b_magic_node(b_node);
- MagicTextureNode *magic = new MagicTextureNode();
- magic->depth = b_magic_node.turbulence_depth();
- get_tex_mapping(&magic->tex_mapping, b_magic_node.texture_mapping());
- node = magic;
- break;
- }
- case BL::ShaderNode::type_TEX_WAVE: {
- BL::ShaderNodeTexWave b_wave_node(b_node);
- WaveTextureNode *wave = new WaveTextureNode();
- wave->type = WaveTextureNode::type_enum[(int)b_wave_node.wave_type()];
- get_tex_mapping(&wave->tex_mapping, b_wave_node.texture_mapping());
- node = wave;
- break;
- }
- case BL::ShaderNode::type_TEX_CHECKER: {
- BL::ShaderNodeTexChecker b_checker_node(b_node);
- CheckerTextureNode *checker = new CheckerTextureNode();
- get_tex_mapping(&checker->tex_mapping, b_checker_node.texture_mapping());
- node = checker;
- break;
- }
- case BL::ShaderNode::type_TEX_BRICK: {
- BL::ShaderNodeTexBrick b_brick_node(b_node);
- BrickTextureNode *brick = new BrickTextureNode();
- brick->offset = b_brick_node.offset();
- brick->offset_frequency = b_brick_node.offset_frequency();
- brick->squash = b_brick_node.squash();
- brick->squash_frequency = b_brick_node.squash_frequency();
- get_tex_mapping(&brick->tex_mapping, b_brick_node.texture_mapping());
- node = brick;
- break;
- }
- case BL::ShaderNode::type_TEX_NOISE: {
- BL::ShaderNodeTexNoise b_noise_node(b_node);
- NoiseTextureNode *noise = new NoiseTextureNode();
- get_tex_mapping(&noise->tex_mapping, b_noise_node.texture_mapping());
- node = noise;
- break;
- }
- case BL::ShaderNode::type_TEX_MUSGRAVE: {
- BL::ShaderNodeTexMusgrave b_musgrave_node(b_node);
- MusgraveTextureNode *musgrave = new MusgraveTextureNode();
- musgrave->type = MusgraveTextureNode::type_enum[(int)b_musgrave_node.musgrave_type()];
- get_tex_mapping(&musgrave->tex_mapping, b_musgrave_node.texture_mapping());
- node = musgrave;
- break;
- }
- case BL::ShaderNode::type_TEX_COORD: {
- BL::ShaderNodeTexCoord b_tex_coord_node(b_node);
- TextureCoordinateNode *tex_coord = new TextureCoordinateNode();
- tex_coord->from_dupli = b_tex_coord_node.from_dupli();
- node = tex_coord;
- break;
- }
- case BL::ShaderNode::type_TEX_SKY: {
- BL::ShaderNodeTexSky b_sky_node(b_node);
- SkyTextureNode *sky = new SkyTextureNode();
- sky->sun_direction = get_float3(b_sky_node.sun_direction());
- sky->turbidity = b_sky_node.turbidity();
- get_tex_mapping(&sky->tex_mapping, b_sky_node.texture_mapping());
- node = sky;
- break;
- }
- case BL::ShaderNode::type_NORMAL_MAP: {
- BL::ShaderNodeNormalMap b_normal_map_node(b_node);
- NormalMapNode *nmap = new NormalMapNode();
- nmap->space = NormalMapNode::space_enum[(int)b_normal_map_node.space()];
- nmap->attribute = b_normal_map_node.uv_map();
- node = nmap;
- break;
+
+ image->animated = b_image_node.image_user().use_auto_refresh();
}
- case BL::ShaderNode::type_TANGENT: {
- BL::ShaderNodeTangent b_tangent_node(b_node);
- TangentNode *tangent = new TangentNode();
- tangent->direction_type = TangentNode::direction_type_enum[(int)b_tangent_node.direction_type()];
- tangent->axis = TangentNode::axis_enum[(int)b_tangent_node.axis()];
- tangent->attribute = b_tangent_node.uv_map();
- node = tangent;
- break;
+ image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()];
+ image->projection = ImageTextureNode::projection_enum[(int)b_image_node.projection()];
+ image->projection_blend = b_image_node.projection_blend();
+ get_tex_mapping(&image->tex_mapping, b_image_node.texture_mapping());
+ node = image;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexEnvironment)) {
+ BL::ShaderNodeTexEnvironment b_env_node(b_node);
+ BL::Image b_image(b_env_node.image());
+ EnvironmentTextureNode *env = new EnvironmentTextureNode();
+ if(b_image) {
+ bool is_builtin = b_image.packed_file() ||
+ b_image.source() == BL::Image::source_GENERATED ||
+ b_image.source() == BL::Image::source_MOVIE;
+
+ if(is_builtin) {
+ int scene_frame = b_scene.frame_current();
+ int image_frame = image_user_frame_number(b_env_node.image_user(), scene_frame);
+ env->filename = b_image.name() + "@" + string_printf("%d", image_frame);
+ env->builtin_data = b_image.ptr.data;
+ }
+ else {
+ env->filename = image_user_file_path(b_env_node.image_user(), b_image, b_scene.frame_current());
+ env->animated = b_env_node.image_user().use_auto_refresh();
+ env->builtin_data = NULL;
+ }
}
+ env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
+ env->projection = EnvironmentTextureNode::projection_enum[(int)b_env_node.projection()];
+ get_tex_mapping(&env->tex_mapping, b_env_node.texture_mapping());
+ node = env;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexGradient)) {
+ BL::ShaderNodeTexGradient b_gradient_node(b_node);
+ GradientTextureNode *gradient = new GradientTextureNode();
+ gradient->type = GradientTextureNode::type_enum[(int)b_gradient_node.gradient_type()];
+ get_tex_mapping(&gradient->tex_mapping, b_gradient_node.texture_mapping());
+ node = gradient;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexVoronoi)) {
+ BL::ShaderNodeTexVoronoi b_voronoi_node(b_node);
+ VoronoiTextureNode *voronoi = new VoronoiTextureNode();
+ voronoi->coloring = VoronoiTextureNode::coloring_enum[(int)b_voronoi_node.coloring()];
+ get_tex_mapping(&voronoi->tex_mapping, b_voronoi_node.texture_mapping());
+ node = voronoi;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexMagic)) {
+ BL::ShaderNodeTexMagic b_magic_node(b_node);
+ MagicTextureNode *magic = new MagicTextureNode();
+ magic->depth = b_magic_node.turbulence_depth();
+ get_tex_mapping(&magic->tex_mapping, b_magic_node.texture_mapping());
+ node = magic;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexWave)) {
+ BL::ShaderNodeTexWave b_wave_node(b_node);
+ WaveTextureNode *wave = new WaveTextureNode();
+ wave->type = WaveTextureNode::type_enum[(int)b_wave_node.wave_type()];
+ get_tex_mapping(&wave->tex_mapping, b_wave_node.texture_mapping());
+ node = wave;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexChecker)) {
+ BL::ShaderNodeTexChecker b_checker_node(b_node);
+ CheckerTextureNode *checker = new CheckerTextureNode();
+ get_tex_mapping(&checker->tex_mapping, b_checker_node.texture_mapping());
+ node = checker;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexBrick)) {
+ BL::ShaderNodeTexBrick b_brick_node(b_node);
+ BrickTextureNode *brick = new BrickTextureNode();
+ brick->offset = b_brick_node.offset();
+ brick->offset_frequency = b_brick_node.offset_frequency();
+ brick->squash = b_brick_node.squash();
+ brick->squash_frequency = b_brick_node.squash_frequency();
+ get_tex_mapping(&brick->tex_mapping, b_brick_node.texture_mapping());
+ node = brick;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexNoise)) {
+ BL::ShaderNodeTexNoise b_noise_node(b_node);
+ NoiseTextureNode *noise = new NoiseTextureNode();
+ get_tex_mapping(&noise->tex_mapping, b_noise_node.texture_mapping());
+ node = noise;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexMusgrave)) {
+ BL::ShaderNodeTexMusgrave b_musgrave_node(b_node);
+ MusgraveTextureNode *musgrave = new MusgraveTextureNode();
+ musgrave->type = MusgraveTextureNode::type_enum[(int)b_musgrave_node.musgrave_type()];
+ get_tex_mapping(&musgrave->tex_mapping, b_musgrave_node.texture_mapping());
+ node = musgrave;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexCoord)) {
+ BL::ShaderNodeTexCoord b_tex_coord_node(b_node);
+ TextureCoordinateNode *tex_coord = new TextureCoordinateNode();
+ tex_coord->from_dupli = b_tex_coord_node.from_dupli();
+ node = tex_coord;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTexSky)) {
+ BL::ShaderNodeTexSky b_sky_node(b_node);
+ SkyTextureNode *sky = new SkyTextureNode();
+ sky->sun_direction = get_float3(b_sky_node.sun_direction());
+ sky->turbidity = b_sky_node.turbidity();
+ get_tex_mapping(&sky->tex_mapping, b_sky_node.texture_mapping());
+ node = sky;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeNormalMap)) {
+ BL::ShaderNodeNormalMap b_normal_map_node(b_node);
+ NormalMapNode *nmap = new NormalMapNode();
+ nmap->space = NormalMapNode::space_enum[(int)b_normal_map_node.space()];
+ nmap->attribute = b_normal_map_node.uv_map();
+ node = nmap;
+ }
+ else if (b_node.is_a(&RNA_ShaderNodeTangent)) {
+ BL::ShaderNodeTangent b_tangent_node(b_node);
+ TangentNode *tangent = new TangentNode();
+ tangent->direction_type = TangentNode::direction_type_enum[(int)b_tangent_node.direction_type()];
+ tangent->axis = TangentNode::axis_enum[(int)b_tangent_node.axis()];
+ tangent->attribute = b_tangent_node.uv_map();
+ node = tangent;
}
if(node && node != graph->output())
@@ -678,18 +600,16 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
return node;
}
-static SocketPair node_socket_map_pair(PtrNodeMap& node_map, BL::Node b_node, BL::NodeSocket b_socket)
+static ShaderInput *node_find_input_by_name(ShaderNode *node, BL::Node b_node, BL::NodeSocket b_socket)
{
BL::Node::inputs_iterator b_input;
- BL::Node::outputs_iterator b_output;
string name = b_socket.name();
bool found = false;
int counter = 0, total = 0;
-
- /* find in inputs */
- for(b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
- if(b_input->name() == name) {
- if(!found)
+
+ for (b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
+ if (b_input->name() == name) {
+ if (!found)
counter++;
total++;
}
@@ -697,128 +617,145 @@ static SocketPair node_socket_map_pair(PtrNodeMap& node_map, BL::Node b_node, BL
if(b_input->ptr.data == b_socket.ptr.data)
found = true;
}
+
+ /* rename if needed */
+ if (name == "Shader")
+ name = "Closure";
+
+ if (total > 1)
+ name = string_printf("%s%d", name.c_str(), counter);
+
+ return node->input(name.c_str());
+}
- if(!found) {
- /* find in outputs */
- found = false;
- counter = 0;
- total = 0;
-
- for(b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
- if(b_output->name() == name) {
- if(!found)
- counter++;
- total++;
- }
-
- if(b_output->ptr.data == b_socket.ptr.data)
- found = true;
+static ShaderOutput *node_find_output_by_name(ShaderNode *node, BL::Node b_node, BL::NodeSocket b_socket)
+{
+ BL::Node::outputs_iterator b_output;
+ string name = b_socket.name();
+ bool found = false;
+ int counter = 0, total = 0;
+
+ for (b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
+ if (b_output->name() == name) {
+ if (!found)
+ counter++;
+ total++;
}
- }
+ if(b_output->ptr.data == b_socket.ptr.data)
+ found = true;
+ }
+
/* rename if needed */
- if(name == "Shader")
+ if (name == "Shader")
name = "Closure";
-
- if(total > 1)
+
+ if (total > 1)
name = string_printf("%s%d", name.c_str(), counter);
-
- return SocketPair(node_map[b_node.ptr.data], name);
+
+ return node->output(name.c_str());
}
-static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map)
+static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, ProxyMap &proxy_map)
{
/* add nodes */
BL::ShaderNodeTree::nodes_iterator b_node;
- PtrNodeMap node_map;
- PtrSockMap proxy_map;
+ PtrInputMap input_map;
+ PtrOutputMap output_map;
+
+ BL::Node::inputs_iterator b_input;
+ BL::Node::outputs_iterator b_output;
for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
- if(b_node->mute()) {
- BL::Node::inputs_iterator b_input;
- BL::Node::outputs_iterator b_output;
- bool found_match = false;
-
- /* this is slightly different than blender logic, we just connect a
- * single pair for of input/output, but works ok for the node we have */
- for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
- if(b_input->is_linked()) {
- for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
- if(b_output->is_linked() && b_input->type() == b_output->type()) {
- ProxyNode *proxy = new ProxyNode(convert_socket_type(b_input->type()), convert_socket_type(b_output->type()));
- graph->add(proxy);
-
- proxy_map[b_input->ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
- proxy_map[b_output->ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
- found_match = true;
-
- break;
- }
- }
- }
-
- if(found_match)
- break;
+ if (b_node->mute() || b_node->is_a(&RNA_NodeReroute)) {
+ /* replace muted node with internal links */
+ BL::Node::internal_links_iterator b_link;
+ for (b_node->internal_links.begin(b_link); b_link != b_node->internal_links.end(); ++b_link) {
+ ProxyNode *proxy = new ProxyNode(convert_socket_type(b_link->to_socket()));
+
+ input_map[b_link->from_socket().ptr.data] = proxy->inputs[0];
+ output_map[b_link->to_socket().ptr.data] = proxy->outputs[0];
+
+ graph->add(proxy);
}
}
- else if(b_node->is_a(&RNA_NodeGroup)) {
- /* add proxy converter nodes for inputs and outputs */
+ else if (b_node->is_a(&RNA_ShaderNodeGroup)) {
BL::NodeGroup b_gnode(*b_node);
BL::ShaderNodeTree b_group_ntree(b_gnode.node_tree());
+ ProxyMap group_proxy_map;
+
if (!b_group_ntree)
continue;
-
- BL::Node::inputs_iterator b_input;
- BL::Node::outputs_iterator b_output;
- PtrSockMap group_sockmap;
+ add_nodes(scene, b_data, b_scene, graph, b_group_ntree, group_proxy_map);
+ /* map the outer socket to the internal proxy nodes */
for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
- ShaderSocketType extern_type = convert_socket_type(b_input->type());
- ShaderSocketType intern_type = convert_socket_type(b_input->group_socket().type());
- ShaderNode *proxy = graph->add(new ProxyNode(extern_type, intern_type));
- /* map the external node socket to the proxy node socket */
- proxy_map[b_input->ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
- /* map the internal group socket to the proxy node socket */
- group_sockmap[b_input->group_socket().ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
+ /* get internal proxy node from group proxy map */
+ assert(group_proxy_map.find(b_input->identifier()) != group_proxy_map.end());
+ assert(group_proxy_map[b_input->identifier()]->special_type == SHADER_SPECIAL_TYPE_PROXY);
+ ProxyNode *proxy = group_proxy_map[b_input->identifier()];
+
+ input_map[b_input->ptr.data] = proxy->inputs[0];
- /* default input values of the group node */
- set_default_value(proxy->inputs[0], *b_input, b_data, b_group_ntree);
+ /* input value for proxy inputs is defined by group node */
+ set_default_value(proxy->inputs[0], *b_node, *b_input, b_data, b_ntree);
}
+ /* map the outer socket to the internal proxy nodes */
for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
- ShaderSocketType extern_type = convert_socket_type(b_output->type());
- ShaderSocketType intern_type = convert_socket_type(b_output->group_socket().type());
- ShaderNode *proxy = graph->add(new ProxyNode(intern_type, extern_type));
- /* map the external node socket to the proxy node socket */
- proxy_map[b_output->ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
- /* map the internal group socket to the proxy node socket */
- group_sockmap[b_output->group_socket().ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
+ /* get internal proxy node from group node map */
+ assert(group_proxy_map.find(b_output->identifier()) != group_proxy_map.end());
+ assert(group_proxy_map[b_output->identifier()]->special_type == SHADER_SPECIAL_TYPE_PROXY);
+ ProxyNode *proxy = group_proxy_map[b_output->identifier()];
- /* default input values of internal, unlinked group outputs */
- set_default_value(proxy->inputs[0], b_output->group_socket(), b_data, b_group_ntree);
+ output_map[b_output->ptr.data] = proxy->outputs[0];
+ }
+ }
+ else if (b_node->is_a(&RNA_NodeGroupInput)) {
+ /* add a proxy node for each socket */
+ for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
+ ProxyNode *proxy = new ProxyNode(convert_socket_type(*b_output));
+
+ output_map[b_output->ptr.data] = proxy->outputs[0];
+
+ /* register the proxy node for external binding */
+ proxy_map[b_output->identifier()] = proxy;
+
+ graph->add(proxy);
+ }
+ }
+ else if (b_node->is_a(&RNA_NodeGroupOutput)) {
+ /* add a proxy node for each socket */
+ for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
+ ProxyNode *proxy = new ProxyNode(convert_socket_type(*b_input));
+
+ input_map[b_input->ptr.data] = proxy->inputs[0];
+
+ set_default_value(proxy->inputs[0], *b_node, *b_input, b_data, b_ntree);
+
+ /* register the proxy node for external binding */
+ proxy_map[b_input->identifier()] = proxy;
+
+ graph->add(proxy);
}
-
- add_nodes(scene, b_data, b_scene, graph, b_group_ntree, group_sockmap);
}
else {
ShaderNode *node = add_node(scene, b_data, b_scene, graph, b_ntree, BL::ShaderNode(*b_node));
if(node) {
- BL::Node::inputs_iterator b_input;
-
- node_map[b_node->ptr.data] = node;
-
+ /* map node sockets for linking */
for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
- SocketPair pair = node_socket_map_pair(node_map, *b_node, *b_input);
- ShaderInput *input = pair.first->input(pair.second.c_str());
+ ShaderInput *input = node_find_input_by_name(node, *b_node, *b_input);
+ input_map[b_input->ptr.data] = input;
- assert(input);
-
- /* copy values for non linked inputs */
- set_default_value(input, *b_input, b_data, b_ntree);
+ set_default_value(input, *b_node, *b_input, b_data, b_ntree);
+ }
+ for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
+ ShaderOutput *output = node_find_output_by_name(node, *b_node, *b_output);
+ output_map[b_output->ptr.data] = output;
}
}
}
@@ -829,44 +766,23 @@ static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, Sha
for(b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
/* get blender link data */
- BL::Node b_from_node = b_link->from_node();
- BL::Node b_to_node = b_link->to_node();
-
BL::NodeSocket b_from_sock = b_link->from_socket();
BL::NodeSocket b_to_sock = b_link->to_socket();
- SocketPair from_pair, to_pair;
-
- /* links without a node pointer are connections to group inputs/outputs */
-
- /* from sock */
- if(b_from_node) {
- if (b_from_node.mute() || b_from_node.is_a(&RNA_NodeGroup))
- from_pair = proxy_map[b_from_sock.ptr.data];
- else
- from_pair = node_socket_map_pair(node_map, b_from_node, b_from_sock);
- }
- else
- from_pair = sockets_map[b_from_sock.ptr.data];
-
- /* to sock */
- if(b_to_node) {
- if (b_to_node.mute() || b_to_node.is_a(&RNA_NodeGroup))
- to_pair = proxy_map[b_to_sock.ptr.data];
- else
- to_pair = node_socket_map_pair(node_map, b_to_node, b_to_sock);
- }
- else
- to_pair = sockets_map[b_to_sock.ptr.data];
+ ShaderOutput *output = 0;
+ ShaderInput *input = 0;
+
+ PtrOutputMap::iterator output_it = output_map.find(b_from_sock.ptr.data);
+ if (output_it != output_map.end())
+ output = output_it->second;
+ PtrInputMap::iterator input_it = input_map.find(b_to_sock.ptr.data);
+ if (input_it != input_map.end())
+ input = input_it->second;
/* either node may be NULL when the node was not exported, typically
* because the node type is not supported */
- if(from_pair.first && to_pair.first) {
- ShaderOutput *output = from_pair.first->output(from_pair.second.c_str());
- ShaderInput *input = to_pair.first->input(to_pair.second.c_str());
-
+ if(output && input)
graph->connect(output, input);
- }
}
}
@@ -891,10 +807,10 @@ void BlenderSync::sync_materials(bool update_all)
/* create nodes */
if(b_mat->use_nodes() && b_mat->node_tree()) {
- PtrSockMap sock_to_node;
+ ProxyMap proxy_map;
BL::ShaderNodeTree b_ntree(b_mat->node_tree());
- add_nodes(scene, b_data, b_scene, graph, b_ntree, sock_to_node);
+ add_nodes(scene, b_data, b_scene, graph, b_ntree, proxy_map);
}
else {
ShaderNode *closure, *out;
@@ -932,10 +848,10 @@ void BlenderSync::sync_world(bool update_all)
/* create nodes */
if(b_world && b_world.use_nodes() && b_world.node_tree()) {
- PtrSockMap sock_to_node;
+ ProxyMap proxy_map;
BL::ShaderNodeTree b_ntree(b_world.node_tree());
- add_nodes(scene, b_data, b_scene, graph, b_ntree, sock_to_node);
+ add_nodes(scene, b_data, b_scene, graph, b_ntree, proxy_map);
}
else if(b_world) {
ShaderNode *closure, *out;
@@ -991,10 +907,10 @@ void BlenderSync::sync_lamps(bool update_all)
if(b_lamp->use_nodes() && b_lamp->node_tree()) {
shader->name = b_lamp->name().c_str();
- PtrSockMap sock_to_node;
+ ProxyMap proxy_map;
BL::ShaderNodeTree b_ntree(b_lamp->node_tree());
- add_nodes(scene, b_data, b_scene, graph, b_ntree, sock_to_node);
+ add_nodes(scene, b_data, b_scene, graph, b_ntree, proxy_map);
}
else {
ShaderNode *closure, *out;
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index 976ed875211..bd4852d08e1 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -202,30 +202,60 @@ static inline uint get_layer(BL::Array<int, 20> array, BL::Array<int, 8> local_a
return layer;
}
-#if 0
static inline float3 get_float3(PointerRNA& ptr, const char *name)
{
float3 f;
RNA_float_get_array(&ptr, name, &f.x);
return f;
}
-#endif
+
+static inline void set_float3(PointerRNA& ptr, const char *name, float3 value)
+{
+ RNA_float_set_array(&ptr, name, &value.x);
+}
+
+static inline float4 get_float4(PointerRNA& ptr, const char *name)
+{
+ float4 f;
+ RNA_float_get_array(&ptr, name, &f.x);
+ return f;
+}
+
+static inline void set_float4(PointerRNA& ptr, const char *name, float4 value)
+{
+ RNA_float_set_array(&ptr, name, &value.x);
+}
static inline bool get_boolean(PointerRNA& ptr, const char *name)
{
return RNA_boolean_get(&ptr, name)? true: false;
}
+static inline void set_boolean(PointerRNA& ptr, const char *name, bool value)
+{
+ RNA_boolean_set(&ptr, name, (int)value);
+}
+
static inline float get_float(PointerRNA& ptr, const char *name)
{
return RNA_float_get(&ptr, name);
}
+static inline void set_float(PointerRNA& ptr, const char *name, float value)
+{
+ RNA_float_set(&ptr, name, value);
+}
+
static inline int get_int(PointerRNA& ptr, const char *name)
{
return RNA_int_get(&ptr, name);
}
+static inline void set_int(PointerRNA& ptr, const char *name, int value)
+{
+ RNA_int_set(&ptr, name, value);
+}
+
static inline int get_enum(PointerRNA& ptr, const char *name)
{
return RNA_enum_get(&ptr, name);
@@ -242,6 +272,32 @@ static inline string get_enum_identifier(PointerRNA& ptr, const char *name)
return string(identifier);
}
+static inline void set_enum(PointerRNA& ptr, const char *name, int value)
+{
+ RNA_enum_set(&ptr, name, value);
+}
+
+static inline void set_enum(PointerRNA& ptr, const char *name, const string &identifier)
+{
+ RNA_enum_set_identifier(&ptr, name, identifier.c_str());
+}
+
+static inline string get_string(PointerRNA& ptr, const char *name)
+{
+ char cstrbuf[1024];
+ char *cstr = RNA_string_get_alloc(&ptr, name, cstrbuf, sizeof(cstrbuf));
+ string str(cstr);
+ if (cstr != cstrbuf)
+ MEM_freeN(cstr);
+
+ return str;
+}
+
+static inline void set_string(PointerRNA& ptr, const char *name, const string &value)
+{
+ RNA_string_set(&ptr, name, value.c_str());
+}
+
/* Relative Paths */
static inline string blender_absolute_path(BL::BlendData b_data, BL::ID b_id, const string& path)
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index 61b5bd83534..c6b9ae08508 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -43,6 +43,8 @@ class OSLCompiler;
* Data type for inputs and outputs */
enum ShaderSocketType {
+ SHADER_SOCKET_UNDEFINED,
+
SHADER_SOCKET_FLOAT,
SHADER_SOCKET_INT,
SHADER_SOCKET_COLOR,
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 8ac12242e15..398b9f0a758 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -1242,15 +1242,14 @@ void ConvertNode::compile(OSLCompiler& compiler)
/* Proxy */
-ProxyNode::ProxyNode(ShaderSocketType from_, ShaderSocketType to_)
+ProxyNode::ProxyNode(ShaderSocketType type_)
: ShaderNode("proxy")
{
- from = from_;
- to = to_;
+ type = type_;
special_type = SHADER_SPECIAL_TYPE_PROXY;
- add_input("Input", from);
- add_output("Output", to);
+ add_input("Input", type);
+ add_output("Output", type);
}
void ProxyNode::compile(SVMCompiler& compiler)
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 3609497e5ce..1efe4ae076d 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -190,10 +190,10 @@ public:
class ProxyNode : public ShaderNode {
public:
- ProxyNode(ShaderSocketType from, ShaderSocketType to);
+ ProxyNode(ShaderSocketType type);
SHADER_NODE_BASE_CLASS(ProxyNode)
- ShaderSocketType from, to;
+ ShaderSocketType type;
};
class BsdfNode : public ShaderNode {