Blender V2.61 - r43446

blender_shader.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright 2011, Blender Foundation.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 
00019 #include "background.h"
00020 #include "graph.h"
00021 #include "light.h"
00022 #include "nodes.h"
00023 #include "scene.h"
00024 #include "shader.h"
00025 
00026 #include "blender_sync.h"
00027 #include "blender_util.h"
00028 
00029 #include "util_debug.h"
00030 
00031 CCL_NAMESPACE_BEGIN
00032 
00033 typedef map<void*, ShaderNode*> PtrNodeMap;
00034 typedef pair<ShaderNode*, std::string> SocketPair;
00035 typedef map<void*, SocketPair> PtrSockMap;
00036 
00037 /* Find */
00038 
00039 void BlenderSync::find_shader(BL::ID id, vector<uint>& used_shaders, int default_shader)
00040 {
00041     Shader *shader = (id)? shader_map.find(id): scene->shaders[default_shader];
00042 
00043     for(size_t i = 0; i < scene->shaders.size(); i++) {
00044         if(scene->shaders[i] == shader) {
00045             used_shaders.push_back(i);
00046             break;
00047         }
00048     }
00049 }
00050 
00051 /* Graph */
00052 
00053 static BL::NodeSocket get_node_output(BL::Node b_node, const string& name)
00054 {
00055     BL::Node::outputs_iterator b_out;
00056 
00057     for(b_node.outputs.begin(b_out); b_out != b_node.outputs.end(); ++b_out)
00058         if(b_out->name() == name)
00059             return *b_out;
00060 
00061     assert(0);
00062 
00063     return *b_out;
00064 }
00065 
00066 static float3 get_node_output_rgba(BL::Node b_node, const string& name)
00067 {
00068     BL::NodeSocketRGBA sock(get_node_output(b_node, name));
00069     return get_float3(sock.default_value());
00070 }
00071 
00072 static float get_node_output_value(BL::Node b_node, const string& name)
00073 {
00074     BL::NodeSocketFloatNone sock(get_node_output(b_node, name));
00075     return sock.default_value();
00076 }
00077 
00078 static void get_tex_mapping(TextureMapping *mapping, BL::TexMapping b_mapping)
00079 {
00080     if(!b_mapping)
00081         return;
00082 
00083     mapping->translation = get_float3(b_mapping.location());
00084     mapping->rotation = get_float3(b_mapping.rotation());
00085     mapping->scale = get_float3(b_mapping.scale());
00086 
00087     mapping->x_mapping = (TextureMapping::Mapping)b_mapping.mapping_x();
00088     mapping->y_mapping = (TextureMapping::Mapping)b_mapping.mapping_y();
00089     mapping->z_mapping = (TextureMapping::Mapping)b_mapping.mapping_z();
00090 }
00091 
00092 static void get_tex_mapping(TextureMapping *mapping, BL::ShaderNodeMapping b_mapping)
00093 {
00094     if(!b_mapping)
00095         return;
00096 
00097     mapping->translation = get_float3(b_mapping.location());
00098     mapping->rotation = get_float3(b_mapping.rotation());
00099     mapping->scale = get_float3(b_mapping.scale());
00100 }
00101 
00102 static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNode b_node)
00103 {
00104     ShaderNode *node = NULL;
00105 
00106     switch(b_node.type()) {
00107         /* not supported */
00108         case BL::ShaderNode::type_CURVE_RGB: break;
00109         case BL::ShaderNode::type_CURVE_VEC: break;
00110         case BL::ShaderNode::type_GEOMETRY: break;
00111         case BL::ShaderNode::type_MATERIAL: break;
00112         case BL::ShaderNode::type_MATERIAL_EXT: break;
00113         case BL::ShaderNode::type_OUTPUT: break;
00114         case BL::ShaderNode::type_SCRIPT: break;
00115         case BL::ShaderNode::type_SQUEEZE: break;
00116         case BL::ShaderNode::type_TEXTURE: break;
00117         case BL::ShaderNode::type_VALTORGB: break;
00118         /* handled outside this function */
00119         case BL::ShaderNode::type_GROUP: break;
00120         /* existing blender nodes */
00121         case BL::ShaderNode::type_RGB: {
00122             ColorNode *color = new ColorNode();
00123             color->value = get_node_output_rgba(b_node, "Color");
00124             node = color;
00125             break;
00126         }
00127         case BL::ShaderNode::type_VALUE: {
00128             ValueNode *value = new ValueNode();
00129             value->value = get_node_output_value(b_node, "Value");
00130             node = value;
00131             break;
00132         }
00133         case BL::ShaderNode::type_CAMERA: {
00134             node = new CameraNode();
00135             break;
00136         }
00137         case BL::ShaderNode::type_INVERT: {
00138             node = new InvertNode();
00139             break;
00140         }
00141         case BL::ShaderNode::type_GAMMA: {
00142             node = new GammaNode();
00143             break;
00144         }
00145         case BL::ShaderNode::type_MIX_RGB: {
00146             BL::ShaderNodeMixRGB b_mix_node(b_node);
00147             MixNode *mix = new MixNode();
00148             mix->type = MixNode::type_enum[b_mix_node.blend_type()];
00149             node = mix;
00150             break;
00151         }
00152         case BL::ShaderNode::type_SEPRGB: {
00153             node = new SeparateRGBNode();
00154             break;
00155         }
00156         case BL::ShaderNode::type_COMBRGB: {
00157             node = new CombineRGBNode();
00158             break;
00159         }
00160         case BL::ShaderNode::type_HUE_SAT: {
00161             node = new HSVNode();
00162             break;
00163         }
00164         case BL::ShaderNode::type_RGBTOBW: {
00165             node = new ConvertNode(SHADER_SOCKET_COLOR, SHADER_SOCKET_FLOAT);
00166             break;
00167         }
00168         case BL::ShaderNode::type_MATH: {
00169             BL::ShaderNodeMath b_math_node(b_node);
00170             MathNode *math = new MathNode();
00171             math->type = MathNode::type_enum[b_math_node.operation()];
00172             node = math;
00173             break;
00174         }
00175         case BL::ShaderNode::type_VECT_MATH: {
00176             BL::ShaderNodeVectorMath b_vector_math_node(b_node);
00177             VectorMathNode *vmath = new VectorMathNode();
00178             vmath->type = VectorMathNode::type_enum[b_vector_math_node.operation()];
00179             node = vmath;
00180             break;
00181         }
00182         case BL::ShaderNode::type_NORMAL: {
00183             BL::Node::outputs_iterator out_it;
00184             b_node.outputs.begin(out_it);
00185             BL::NodeSocketVectorNone vec_sock(*out_it);
00186 
00187             NormalNode *norm = new NormalNode();
00188             norm->direction = get_float3(vec_sock.default_value());
00189 
00190             node = norm;
00191             break;
00192         }
00193         case BL::ShaderNode::type_MAPPING: {
00194             BL::ShaderNodeMapping b_mapping_node(b_node);
00195             MappingNode *mapping = new MappingNode();
00196 
00197             get_tex_mapping(&mapping->tex_mapping, b_mapping_node);
00198 
00199             node = mapping;
00200             break;
00201         }
00202 
00203         /* new nodes */
00204         case BL::ShaderNode::type_OUTPUT_MATERIAL:
00205         case BL::ShaderNode::type_OUTPUT_WORLD:
00206         case BL::ShaderNode::type_OUTPUT_LAMP: {
00207             node = graph->output();
00208             break;
00209         }
00210         case BL::ShaderNode::type_FRESNEL: {
00211             node = new FresnelNode();
00212             break;
00213         }
00214         case BL::ShaderNode::type_LAYER_WEIGHT: {
00215             node = new LayerWeightNode();
00216             break;
00217         }
00218         case BL::ShaderNode::type_ADD_SHADER: {
00219             node = new AddClosureNode();
00220             break;
00221         }
00222         case BL::ShaderNode::type_MIX_SHADER: {
00223             node = new MixClosureNode();
00224             break;
00225         }
00226         case BL::ShaderNode::type_ATTRIBUTE: {
00227             BL::ShaderNodeAttribute b_attr_node(b_node);
00228             AttributeNode *attr = new AttributeNode();
00229             attr->attribute = b_attr_node.attribute_name();
00230             node = attr;
00231             break;
00232         }
00233         case BL::ShaderNode::type_BACKGROUND: {
00234             node = new BackgroundNode();
00235             break;
00236         }
00237         case BL::ShaderNode::type_HOLDOUT: {
00238             node = new HoldoutNode();
00239             break;
00240         }
00241         case BL::ShaderNode::type_BSDF_DIFFUSE: {
00242             node = new DiffuseBsdfNode();
00243             break;
00244         }
00245         case BL::ShaderNode::type_BSDF_GLOSSY: {
00246             BL::ShaderNodeBsdfGlossy b_glossy_node(b_node);
00247             GlossyBsdfNode *glossy = new GlossyBsdfNode();
00248 
00249             switch(b_glossy_node.distribution()) {
00250                 case BL::ShaderNodeBsdfGlossy::distribution_SHARP:
00251                     glossy->distribution = ustring("Sharp");
00252                     break;
00253                 case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN:
00254                     glossy->distribution = ustring("Beckmann");
00255                     break;
00256                 case BL::ShaderNodeBsdfGlossy::distribution_GGX:
00257                     glossy->distribution = ustring("GGX");
00258                     break;
00259             }
00260             node = glossy;
00261             break;
00262         }
00263         case BL::ShaderNode::type_BSDF_GLASS: {
00264             BL::ShaderNodeBsdfGlass b_glass_node(b_node);
00265             GlassBsdfNode *glass = new GlassBsdfNode();
00266             switch(b_glass_node.distribution()) {
00267                 case BL::ShaderNodeBsdfGlass::distribution_SHARP:
00268                     glass->distribution = ustring("Sharp");
00269                     break;
00270                 case BL::ShaderNodeBsdfGlass::distribution_BECKMANN:
00271                     glass->distribution = ustring("Beckmann");
00272                     break;
00273                 case BL::ShaderNodeBsdfGlass::distribution_GGX:
00274                     glass->distribution = ustring("GGX");
00275                     break;
00276             }
00277             node = glass;
00278             break;
00279         }
00280         case BL::ShaderNode::type_BSDF_TRANSLUCENT: {
00281             node = new TranslucentBsdfNode();
00282             break;
00283         }
00284         case BL::ShaderNode::type_BSDF_TRANSPARENT: {
00285             node = new TransparentBsdfNode();
00286             break;
00287         }
00288         case BL::ShaderNode::type_BSDF_VELVET: {
00289             node = new VelvetBsdfNode();
00290             break;
00291         }
00292         case BL::ShaderNode::type_EMISSION: {
00293             node = new EmissionNode();
00294             break;
00295         }
00296         case BL::ShaderNode::type_VOLUME_ISOTROPIC: {
00297             node = new IsotropicVolumeNode();
00298             break;
00299         }
00300         case BL::ShaderNode::type_VOLUME_TRANSPARENT: {
00301             node = new TransparentVolumeNode();
00302             break;
00303         }
00304         case BL::ShaderNode::type_NEW_GEOMETRY: {
00305             node = new GeometryNode();
00306             break;
00307         }
00308         case BL::ShaderNode::type_LIGHT_PATH: {
00309             node = new LightPathNode();
00310             break;
00311         }
00312         case BL::ShaderNode::type_TEX_IMAGE: {
00313             BL::ShaderNodeTexImage b_image_node(b_node);
00314             BL::Image b_image(b_image_node.image());
00315             ImageTextureNode *image = new ImageTextureNode();
00316             /* todo: handle generated/builtin images */
00317             if(b_image)
00318                 image->filename = blender_absolute_path(b_data, b_image, b_image.filepath());
00319             image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()];
00320             get_tex_mapping(&image->tex_mapping, b_image_node.texture_mapping());
00321             node = image;
00322             break;
00323         }
00324         case BL::ShaderNode::type_TEX_ENVIRONMENT: {
00325             BL::ShaderNodeTexEnvironment b_env_node(b_node);
00326             BL::Image b_image(b_env_node.image());
00327             EnvironmentTextureNode *env = new EnvironmentTextureNode();
00328             if(b_image)
00329                 env->filename = blender_absolute_path(b_data, b_image, b_image.filepath());
00330             env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
00331             get_tex_mapping(&env->tex_mapping, b_env_node.texture_mapping());
00332             node = env;
00333             break;
00334         }
00335         case BL::ShaderNode::type_TEX_GRADIENT: {
00336             BL::ShaderNodeTexGradient b_gradient_node(b_node);
00337             GradientTextureNode *gradient = new GradientTextureNode();
00338             gradient->type = GradientTextureNode::type_enum[(int)b_gradient_node.gradient_type()];
00339             get_tex_mapping(&gradient->tex_mapping, b_gradient_node.texture_mapping());
00340             node = gradient;
00341             break;
00342         }
00343         case BL::ShaderNode::type_TEX_VORONOI: {
00344             BL::ShaderNodeTexVoronoi b_voronoi_node(b_node);
00345             VoronoiTextureNode *voronoi = new VoronoiTextureNode();
00346             voronoi->coloring = VoronoiTextureNode::coloring_enum[(int)b_voronoi_node.coloring()];
00347             get_tex_mapping(&voronoi->tex_mapping, b_voronoi_node.texture_mapping());
00348             node = voronoi;
00349             break;
00350         }
00351         case BL::ShaderNode::type_TEX_MAGIC: {
00352             BL::ShaderNodeTexMagic b_magic_node(b_node);
00353             MagicTextureNode *magic = new MagicTextureNode();
00354             magic->depth = b_magic_node.turbulence_depth();
00355             get_tex_mapping(&magic->tex_mapping, b_magic_node.texture_mapping());
00356             node = magic;
00357             break;
00358         }
00359         case BL::ShaderNode::type_TEX_WAVE: {
00360             BL::ShaderNodeTexWave b_wave_node(b_node);
00361             WaveTextureNode *wave = new WaveTextureNode();
00362             wave->type = WaveTextureNode::type_enum[(int)b_wave_node.wave_type()];
00363             get_tex_mapping(&wave->tex_mapping, b_wave_node.texture_mapping());
00364             node = wave;
00365             break;
00366         }
00367         case BL::ShaderNode::type_TEX_CHECKER: {
00368             BL::ShaderNodeTexChecker b_checker_node(b_node);
00369             CheckerTextureNode *checker = new CheckerTextureNode();
00370             get_tex_mapping(&checker->tex_mapping, b_checker_node.texture_mapping());
00371             node = checker;
00372             break;
00373         }
00374         case BL::ShaderNode::type_TEX_NOISE: {
00375             BL::ShaderNodeTexNoise b_noise_node(b_node);
00376             NoiseTextureNode *noise = new NoiseTextureNode();
00377             get_tex_mapping(&noise->tex_mapping, b_noise_node.texture_mapping());
00378             node = noise;
00379             break;
00380         }
00381         case BL::ShaderNode::type_TEX_MUSGRAVE: {
00382             BL::ShaderNodeTexMusgrave b_musgrave_node(b_node);
00383             MusgraveTextureNode *musgrave = new MusgraveTextureNode();
00384             musgrave->type = MusgraveTextureNode::type_enum[(int)b_musgrave_node.musgrave_type()];
00385             get_tex_mapping(&musgrave->tex_mapping, b_musgrave_node.texture_mapping());
00386             node = musgrave;
00387             break;
00388         }
00389         case BL::ShaderNode::type_TEX_COORD: {
00390             node = new TextureCoordinateNode();;
00391             break;
00392         }
00393         case BL::ShaderNode::type_TEX_SKY: {
00394             BL::ShaderNodeTexSky b_sky_node(b_node);
00395             SkyTextureNode *sky = new SkyTextureNode();
00396             sky->sun_direction = get_float3(b_sky_node.sun_direction());
00397             sky->turbidity = b_sky_node.turbidity();
00398             get_tex_mapping(&sky->tex_mapping, b_sky_node.texture_mapping());
00399             node = sky;
00400             break;
00401         }
00402     }
00403 
00404     if(node && node != graph->output())
00405         graph->add(node);
00406 
00407     return node;
00408 }
00409 
00410 static SocketPair node_socket_map_pair(PtrNodeMap& node_map, BL::Node b_node, BL::NodeSocket b_socket)
00411 {
00412     BL::Node::inputs_iterator b_input;
00413     BL::Node::outputs_iterator b_output;
00414     string name = b_socket.name();
00415     bool found = false;
00416     int counter = 0, total = 0;
00417 
00418     /* find in inputs */
00419     for(b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
00420         if(b_input->name() == name) {
00421             if(!found)
00422                 counter++;
00423             total++;
00424         }
00425 
00426         if(b_input->ptr.data == b_socket.ptr.data)
00427             found = true;
00428     }
00429 
00430     if(!found) {
00431         /* find in outputs */
00432         found = false;
00433         counter = 0;
00434         total = 0;
00435 
00436         for(b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
00437             if(b_output->name() == name) {
00438                 if(!found)
00439                     counter++;
00440                 total++;
00441             }
00442 
00443             if(b_output->ptr.data == b_socket.ptr.data)
00444                 found = true;
00445         }
00446     }
00447 
00448     /* rename if needed */
00449     if(name == "Shader")
00450         name = "Closure";
00451 
00452     if(total > 1)
00453         name = string_printf("%s%d", name.c_str(), counter);
00454 
00455     return SocketPair(node_map[b_node.ptr.data], name);
00456 }
00457 
00458 static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type)
00459 {
00460     switch (b_type) {
00461     case BL::NodeSocket::type_VALUE:
00462         return SHADER_SOCKET_FLOAT;
00463     case BL::NodeSocket::type_VECTOR:
00464         return SHADER_SOCKET_VECTOR;
00465     case BL::NodeSocket::type_RGBA:
00466         return SHADER_SOCKET_COLOR;
00467     case BL::NodeSocket::type_SHADER:
00468         return SHADER_SOCKET_CLOSURE;
00469     
00470     case BL::NodeSocket::type_BOOLEAN:
00471     case BL::NodeSocket::type_MESH:
00472     case BL::NodeSocket::type_INT:
00473     default:
00474         return SHADER_SOCKET_FLOAT;
00475     }
00476 }
00477 
00478 static void set_default_value(ShaderInput *input, BL::NodeSocket sock)
00479 {
00480     /* copy values for non linked inputs */
00481     switch(input->type) {
00482     case SHADER_SOCKET_FLOAT: {
00483         BL::NodeSocketFloatNone value_sock(sock);
00484         input->set(value_sock.default_value());
00485         break;
00486     }
00487     case SHADER_SOCKET_COLOR: {
00488         BL::NodeSocketRGBA rgba_sock(sock);
00489         input->set(get_float3(rgba_sock.default_value()));
00490         break;
00491     }
00492     case SHADER_SOCKET_NORMAL:
00493     case SHADER_SOCKET_POINT:
00494     case SHADER_SOCKET_VECTOR: {
00495         BL::NodeSocketVectorNone vec_sock(sock);
00496         input->set(get_float3(vec_sock.default_value()));
00497         break;
00498     }
00499     case SHADER_SOCKET_CLOSURE:
00500         break;
00501     }
00502 }
00503 
00504 static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map)
00505 {
00506     /* add nodes */
00507     BL::ShaderNodeTree::nodes_iterator b_node;
00508     PtrNodeMap node_map;
00509     PtrSockMap proxy_map;
00510 
00511     for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
00512         if(b_node->is_a(&RNA_NodeGroup)) {
00513             /* add proxy converter nodes for inputs and outputs */
00514             BL::NodeGroup b_gnode(*b_node);
00515             BL::ShaderNodeTree b_group_ntree(b_gnode.node_tree());
00516             BL::Node::inputs_iterator b_input;
00517             BL::Node::outputs_iterator b_output;
00518             
00519             PtrSockMap group_sockmap;
00520             
00521             for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
00522                 ShaderSocketType extern_type = convert_socket_type(b_input->type());
00523                 ShaderSocketType intern_type = convert_socket_type(b_input->group_socket().type());
00524                 ShaderNode *proxy = graph->add(new ProxyNode(extern_type, intern_type));
00525                 
00526                 /* map the external node socket to the proxy node socket */
00527                 proxy_map[b_input->ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
00528                 /* map the internal group socket to the proxy node socket */
00529                 group_sockmap[b_input->group_socket().ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
00530                 
00531                 /* default input values of the group node */
00532                 set_default_value(proxy->inputs[0], *b_input);
00533             }
00534             
00535             for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
00536                 ShaderSocketType extern_type = convert_socket_type(b_output->type());
00537                 ShaderSocketType intern_type = convert_socket_type(b_output->group_socket().type());
00538                 ShaderNode *proxy = graph->add(new ProxyNode(intern_type, extern_type));
00539                 
00540                 /* map the external node socket to the proxy node socket */
00541                 proxy_map[b_output->ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
00542                 /* map the internal group socket to the proxy node socket */
00543                 group_sockmap[b_output->group_socket().ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
00544                 
00545                 /* default input values of internal, unlinked group outputs */
00546                 set_default_value(proxy->inputs[0], b_output->group_socket());
00547             }
00548             
00549             add_nodes(b_data, graph, b_group_ntree, group_sockmap);
00550         }
00551         else {
00552             ShaderNode *node = add_node(b_data, graph, BL::ShaderNode(*b_node));
00553             
00554             if(node) {
00555                 BL::Node::inputs_iterator b_input;
00556                 
00557                 node_map[b_node->ptr.data] = node;
00558                 
00559                 for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
00560                     SocketPair pair = node_socket_map_pair(node_map, *b_node, *b_input);
00561                     ShaderInput *input = pair.first->input(pair.second.c_str());
00562                     
00563                     assert(input);
00564                     
00565                     /* copy values for non linked inputs */
00566                     set_default_value(input, *b_input);
00567                 }
00568             }
00569         }
00570     }
00571 
00572     /* connect nodes */
00573     BL::NodeTree::links_iterator b_link;
00574 
00575     for(b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
00576         /* get blender link data */
00577         BL::Node b_from_node = b_link->from_node();
00578         BL::Node b_to_node = b_link->to_node();
00579 
00580         BL::NodeSocket b_from_sock = b_link->from_socket();
00581         BL::NodeSocket b_to_sock = b_link->to_socket();
00582 
00583         SocketPair from_pair, to_pair;
00584 
00585         /* links without a node pointer are connections to group inputs/outputs */
00586 
00587         /* from sock */
00588         if(b_from_node) {
00589             if (b_from_node.is_a(&RNA_NodeGroup))
00590                 from_pair = proxy_map[b_from_sock.ptr.data];
00591             else
00592                 from_pair = node_socket_map_pair(node_map, b_from_node, b_from_sock);
00593         }
00594         else
00595             from_pair = sockets_map[b_from_sock.ptr.data];
00596 
00597         /* to sock */
00598         if(b_to_node) {
00599             if (b_to_node.is_a(&RNA_NodeGroup))
00600                 to_pair = proxy_map[b_to_sock.ptr.data];
00601             else
00602                 to_pair = node_socket_map_pair(node_map, b_to_node, b_to_sock);
00603         }
00604         else
00605             to_pair = sockets_map[b_to_sock.ptr.data];
00606 
00607         /* either node may be NULL when the node was not exported, typically
00608            because the node type is not supported */
00609         if(from_pair.first && to_pair.first) {
00610             ShaderOutput *output = from_pair.first->output(from_pair.second.c_str());
00611             ShaderInput *input = to_pair.first->input(to_pair.second.c_str());
00612 
00613             graph->connect(output, input);
00614         }
00615     }
00616 }
00617 
00618 /* Sync Materials */
00619 
00620 void BlenderSync::sync_materials()
00621 {
00622     shader_map.set_default(scene->shaders[scene->default_surface]);
00623 
00624     /* material loop */
00625     BL::BlendData::materials_iterator b_mat;
00626 
00627     for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat) {
00628         Shader *shader;
00629         
00630         /* test if we need to sync */
00631         if(shader_map.sync(&shader, *b_mat)) {
00632             ShaderGraph *graph = new ShaderGraph();
00633 
00634             shader->name = b_mat->name().c_str();
00635 
00636             /* create nodes */
00637             if(b_mat->use_nodes() && b_mat->node_tree()) {
00638                 PtrSockMap sock_to_node;
00639                 BL::ShaderNodeTree b_ntree(b_mat->node_tree());
00640 
00641                 add_nodes(b_data, graph, b_ntree, sock_to_node);
00642             }
00643             else {
00644                 ShaderNode *closure, *out;
00645 
00646                 closure = graph->add(new DiffuseBsdfNode());
00647                 closure->input("Color")->value = get_float3(b_mat->diffuse_color());
00648                 out = graph->output();
00649 
00650                 graph->connect(closure->output("BSDF"), out->input("Surface"));
00651             }
00652 
00653             /* settings */
00654             PointerRNA cmat = RNA_pointer_get(&b_mat->ptr, "cycles");
00655             shader->sample_as_light = get_boolean(cmat, "sample_as_light");
00656             shader->homogeneous_volume = get_boolean(cmat, "homogeneous_volume");
00657 
00658             shader->set_graph(graph);
00659             shader->tag_update(scene);
00660         }
00661     }
00662 }
00663 
00664 /* Sync World */
00665 
00666 void BlenderSync::sync_world()
00667 {
00668     Background *background = scene->background;
00669     Background prevbackground = *background;
00670 
00671     BL::World b_world = b_scene.world();
00672 
00673     if(world_recalc || b_world.ptr.data != world_map) {
00674         Shader *shader = scene->shaders[scene->default_background];
00675         ShaderGraph *graph = new ShaderGraph();
00676 
00677         /* create nodes */
00678         if(b_world && b_world.use_nodes() && b_world.node_tree()) {
00679             PtrSockMap sock_to_node;
00680             BL::ShaderNodeTree b_ntree(b_world.node_tree());
00681 
00682             add_nodes(b_data, graph, b_ntree, sock_to_node);
00683         }
00684         else if(b_world) {
00685             ShaderNode *closure, *out;
00686 
00687             closure = graph->add(new BackgroundNode());
00688             closure->input("Color")->value = get_float3(b_world.horizon_color());
00689             out = graph->output();
00690 
00691             graph->connect(closure->output("Background"), out->input("Surface"));
00692         }
00693 
00694         shader->set_graph(graph);
00695         shader->tag_update(scene);
00696     }
00697 
00698     PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
00699     background->transparent = get_boolean(cscene, "film_transparent");
00700 
00701     if(background->modified(prevbackground))
00702         background->tag_update(scene);
00703 
00704     world_map = b_world.ptr.data;
00705     world_recalc = false;
00706 }
00707 
00708 /* Sync Lamps */
00709 
00710 void BlenderSync::sync_lamps()
00711 {
00712     shader_map.set_default(scene->shaders[scene->default_light]);
00713 
00714     /* lamp loop */
00715     BL::BlendData::lamps_iterator b_lamp;
00716 
00717     for(b_data.lamps.begin(b_lamp); b_lamp != b_data.lamps.end(); ++b_lamp) {
00718         Shader *shader;
00719         
00720         /* test if we need to sync */
00721         if(shader_map.sync(&shader, *b_lamp)) {
00722             ShaderGraph *graph = new ShaderGraph();
00723 
00724             /* create nodes */
00725             if(b_lamp->use_nodes() && b_lamp->node_tree()) {
00726                 shader->name = b_lamp->name().c_str();
00727 
00728                 PtrSockMap sock_to_node;
00729                 BL::ShaderNodeTree b_ntree(b_lamp->node_tree());
00730 
00731                 add_nodes(b_data, graph, b_ntree, sock_to_node);
00732             }
00733             else {
00734                 ShaderNode *closure, *out;
00735                 float strength = 1.0f;
00736 
00737                 if(b_lamp->type() == BL::Lamp::type_POINT ||
00738                    b_lamp->type() == BL::Lamp::type_SPOT ||
00739                    b_lamp->type() == BL::Lamp::type_AREA)
00740                     strength = 100.0f;
00741 
00742                 closure = graph->add(new EmissionNode());
00743                 closure->input("Color")->value = get_float3(b_lamp->color());
00744                 closure->input("Strength")->value.x = strength;
00745                 out = graph->output();
00746 
00747                 graph->connect(closure->output("Emission"), out->input("Surface"));
00748             }
00749 
00750             shader->set_graph(graph);
00751             shader->tag_update(scene);
00752         }
00753     }
00754 }
00755 
00756 void BlenderSync::sync_shaders()
00757 {
00758     shader_map.pre_sync();
00759 
00760     sync_world();
00761     sync_lamps();
00762     sync_materials();
00763 
00764     /* false = don't delete unused shaders, not supported */
00765     shader_map.post_sync(false);
00766 }
00767 
00768 CCL_NAMESPACE_END
00769