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:
Diffstat (limited to 'intern/cycles/blender/blender_shader.cpp')
-rw-r--r--intern/cycles/blender/blender_shader.cpp1148
1 files changed, 532 insertions, 616 deletions
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;