a88bcaf3ace1b46c1d9f059956a960eead9449e9
[blender.git] / intern / cycles / blender / blender_shader.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 #include "background.h"
20 #include "graph.h"
21 #include "light.h"
22 #include "nodes.h"
23 #include "scene.h"
24 #include "shader.h"
25
26 #include "blender_sync.h"
27 #include "blender_util.h"
28
29 #include "util_debug.h"
30
31 CCL_NAMESPACE_BEGIN
32
33 typedef map<void*, ShaderNode*> PtrNodeMap;
34 typedef pair<ShaderNode*, std::string> SocketPair;
35 typedef map<void*, SocketPair> PtrSockMap;
36
37 /* Find */
38
39 void BlenderSync::find_shader(BL::ID id, vector<uint>& used_shaders, int default_shader)
40 {
41         Shader *shader = (id)? shader_map.find(id): scene->shaders[default_shader];
42
43         for(size_t i = 0; i < scene->shaders.size(); i++) {
44                 if(scene->shaders[i] == shader) {
45                         used_shaders.push_back(i);
46                         break;
47                 }
48         }
49 }
50
51 /* Graph */
52
53 static BL::NodeSocket get_node_output(BL::Node b_node, const string& name)
54 {
55         BL::Node::outputs_iterator b_out;
56
57         for(b_node.outputs.begin(b_out); b_out != b_node.outputs.end(); ++b_out)
58                 if(b_out->name() == name)
59                         return *b_out;
60
61         assert(0);
62
63         return *b_out;
64 }
65
66 static float3 get_node_output_rgba(BL::Node b_node, const string& name)
67 {
68         BL::NodeSocketRGBA sock(get_node_output(b_node, name));
69         return get_float3(sock.default_value());
70 }
71
72 static float get_node_output_value(BL::Node b_node, const string& name)
73 {
74         BL::NodeSocketFloatNone sock(get_node_output(b_node, name));
75         return sock.default_value();
76 }
77
78 static void get_tex_mapping(TextureMapping *mapping, BL::TexMapping b_mapping)
79 {
80         if(!b_mapping)
81                 return;
82
83         mapping->translation = get_float3(b_mapping.location());
84         mapping->rotation = get_float3(b_mapping.rotation());
85         mapping->scale = get_float3(b_mapping.scale());
86
87         mapping->x_mapping = (TextureMapping::Mapping)b_mapping.mapping_x();
88         mapping->y_mapping = (TextureMapping::Mapping)b_mapping.mapping_y();
89         mapping->z_mapping = (TextureMapping::Mapping)b_mapping.mapping_z();
90 }
91
92 static void get_tex_mapping(TextureMapping *mapping, BL::ShaderNodeMapping b_mapping)
93 {
94         if(!b_mapping)
95                 return;
96
97         mapping->translation = get_float3(b_mapping.location());
98         mapping->rotation = get_float3(b_mapping.rotation());
99         mapping->scale = get_float3(b_mapping.scale());
100 }
101
102 static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNode b_node)
103 {
104         ShaderNode *node = NULL;
105
106         switch(b_node.type()) {
107                 /* not supported */
108                 case BL::ShaderNode::type_CURVE_RGB: break;
109                 case BL::ShaderNode::type_CURVE_VEC: break;
110                 case BL::ShaderNode::type_GEOMETRY: break;
111                 case BL::ShaderNode::type_MATERIAL: break;
112                 case BL::ShaderNode::type_MATERIAL_EXT: break;
113                 case BL::ShaderNode::type_OUTPUT: break;
114                 case BL::ShaderNode::type_SCRIPT: break;
115                 case BL::ShaderNode::type_SQUEEZE: break;
116                 case BL::ShaderNode::type_TEXTURE: break;
117                 case BL::ShaderNode::type_VALTORGB: break;
118                 /* handled outside this function */
119                 case BL::ShaderNode::type_GROUP: break;
120                 /* existing blender nodes */
121                 case BL::ShaderNode::type_RGB: {
122                         ColorNode *color = new ColorNode();
123                         color->value = get_node_output_rgba(b_node, "Color");
124                         node = color;
125                         break;
126                 }
127                 case BL::ShaderNode::type_VALUE: {
128                         ValueNode *value = new ValueNode();
129                         value->value = get_node_output_value(b_node, "Value");
130                         node = value;
131                         break;
132                 }
133                 case BL::ShaderNode::type_CAMERA: {
134                         node = new CameraNode();
135                         break;
136                 }
137                 case BL::ShaderNode::type_INVERT: {
138                         node = new InvertNode();
139                         break;
140                 }
141                 case BL::ShaderNode::type_GAMMA: {
142                         node = new GammaNode();
143                         break;
144                 }
145                 case BL::ShaderNode::type_BRIGHTCONTRAST: {
146                         node = new BrightContrastNode();
147                         break;
148                 }
149                 case BL::ShaderNode::type_MIX_RGB: {
150                         BL::ShaderNodeMixRGB b_mix_node(b_node);
151                         MixNode *mix = new MixNode();
152                         mix->type = MixNode::type_enum[b_mix_node.blend_type()];
153                         node = mix;
154                         break;
155                 }
156                 case BL::ShaderNode::type_SEPRGB: {
157                         node = new SeparateRGBNode();
158                         break;
159                 }
160                 case BL::ShaderNode::type_COMBRGB: {
161                         node = new CombineRGBNode();
162                         break;
163                 }
164                 case BL::ShaderNode::type_HUE_SAT: {
165                         node = new HSVNode();
166                         break;
167                 }
168                 case BL::ShaderNode::type_RGBTOBW: {
169                         node = new ConvertNode(SHADER_SOCKET_COLOR, SHADER_SOCKET_FLOAT);
170                         break;
171                 }
172                 case BL::ShaderNode::type_MATH: {
173                         BL::ShaderNodeMath b_math_node(b_node);
174                         MathNode *math = new MathNode();
175                         math->type = MathNode::type_enum[b_math_node.operation()];
176                         node = math;
177                         break;
178                 }
179                 case BL::ShaderNode::type_VECT_MATH: {
180                         BL::ShaderNodeVectorMath b_vector_math_node(b_node);
181                         VectorMathNode *vmath = new VectorMathNode();
182                         vmath->type = VectorMathNode::type_enum[b_vector_math_node.operation()];
183                         node = vmath;
184                         break;
185                 }
186                 case BL::ShaderNode::type_NORMAL: {
187                         BL::Node::outputs_iterator out_it;
188                         b_node.outputs.begin(out_it);
189                         BL::NodeSocketVectorNone vec_sock(*out_it);
190
191                         NormalNode *norm = new NormalNode();
192                         norm->direction = get_float3(vec_sock.default_value());
193
194                         node = norm;
195                         break;
196                 }
197                 case BL::ShaderNode::type_MAPPING: {
198                         BL::ShaderNodeMapping b_mapping_node(b_node);
199                         MappingNode *mapping = new MappingNode();
200
201                         get_tex_mapping(&mapping->tex_mapping, b_mapping_node);
202
203                         node = mapping;
204                         break;
205                 }
206
207                 /* new nodes */
208                 case BL::ShaderNode::type_OUTPUT_MATERIAL:
209                 case BL::ShaderNode::type_OUTPUT_WORLD:
210                 case BL::ShaderNode::type_OUTPUT_LAMP: {
211                         node = graph->output();
212                         break;
213                 }
214                 case BL::ShaderNode::type_FRESNEL: {
215                         node = new FresnelNode();
216                         break;
217                 }
218                 case BL::ShaderNode::type_LAYER_WEIGHT: {
219                         node = new LayerWeightNode();
220                         break;
221                 }
222                 case BL::ShaderNode::type_ADD_SHADER: {
223                         node = new AddClosureNode();
224                         break;
225                 }
226                 case BL::ShaderNode::type_MIX_SHADER: {
227                         node = new MixClosureNode();
228                         break;
229                 }
230                 case BL::ShaderNode::type_ATTRIBUTE: {
231                         BL::ShaderNodeAttribute b_attr_node(b_node);
232                         AttributeNode *attr = new AttributeNode();
233                         attr->attribute = b_attr_node.attribute_name();
234                         node = attr;
235                         break;
236                 }
237                 case BL::ShaderNode::type_BACKGROUND: {
238                         node = new BackgroundNode();
239                         break;
240                 }
241                 case BL::ShaderNode::type_HOLDOUT: {
242                         node = new HoldoutNode();
243                         break;
244                 }
245                 case BL::ShaderNode::type_BSDF_DIFFUSE: {
246                         node = new DiffuseBsdfNode();
247                         break;
248                 }
249                 case BL::ShaderNode::type_BSDF_GLOSSY: {
250                         BL::ShaderNodeBsdfGlossy b_glossy_node(b_node);
251                         GlossyBsdfNode *glossy = new GlossyBsdfNode();
252
253                         switch(b_glossy_node.distribution()) {
254                                 case BL::ShaderNodeBsdfGlossy::distribution_SHARP:
255                                         glossy->distribution = ustring("Sharp");
256                                         break;
257                                 case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN:
258                                         glossy->distribution = ustring("Beckmann");
259                                         break;
260                                 case BL::ShaderNodeBsdfGlossy::distribution_GGX:
261                                         glossy->distribution = ustring("GGX");
262                                         break;
263                         }
264                         node = glossy;
265                         break;
266                 }
267                 case BL::ShaderNode::type_BSDF_GLASS: {
268                         BL::ShaderNodeBsdfGlass b_glass_node(b_node);
269                         GlassBsdfNode *glass = new GlassBsdfNode();
270                         switch(b_glass_node.distribution()) {
271                                 case BL::ShaderNodeBsdfGlass::distribution_SHARP:
272                                         glass->distribution = ustring("Sharp");
273                                         break;
274                                 case BL::ShaderNodeBsdfGlass::distribution_BECKMANN:
275                                         glass->distribution = ustring("Beckmann");
276                                         break;
277                                 case BL::ShaderNodeBsdfGlass::distribution_GGX:
278                                         glass->distribution = ustring("GGX");
279                                         break;
280                         }
281                         node = glass;
282                         break;
283                 }
284                 case BL::ShaderNode::type_BSDF_TRANSLUCENT: {
285                         node = new TranslucentBsdfNode();
286                         break;
287                 }
288                 case BL::ShaderNode::type_BSDF_TRANSPARENT: {
289                         node = new TransparentBsdfNode();
290                         break;
291                 }
292                 case BL::ShaderNode::type_BSDF_VELVET: {
293                         node = new VelvetBsdfNode();
294                         break;
295                 }
296                 case BL::ShaderNode::type_EMISSION: {
297                         node = new EmissionNode();
298                         break;
299                 }
300                 case BL::ShaderNode::type_VOLUME_ISOTROPIC: {
301                         node = new IsotropicVolumeNode();
302                         break;
303                 }
304                 case BL::ShaderNode::type_VOLUME_TRANSPARENT: {
305                         node = new TransparentVolumeNode();
306                         break;
307                 }
308                 case BL::ShaderNode::type_NEW_GEOMETRY: {
309                         node = new GeometryNode();
310                         break;
311                 }
312                 case BL::ShaderNode::type_LIGHT_PATH: {
313                         node = new LightPathNode();
314                         break;
315                 }
316                 case BL::ShaderNode::type_TEX_IMAGE: {
317                         BL::ShaderNodeTexImage b_image_node(b_node);
318                         BL::Image b_image(b_image_node.image());
319                         ImageTextureNode *image = new ImageTextureNode();
320                         /* todo: handle generated/builtin images */
321                         if(b_image)
322                                 image->filename = blender_absolute_path(b_data, b_image, b_image.filepath());
323                         image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()];
324                         get_tex_mapping(&image->tex_mapping, b_image_node.texture_mapping());
325                         node = image;
326                         break;
327                 }
328                 case BL::ShaderNode::type_TEX_ENVIRONMENT: {
329                         BL::ShaderNodeTexEnvironment b_env_node(b_node);
330                         BL::Image b_image(b_env_node.image());
331                         EnvironmentTextureNode *env = new EnvironmentTextureNode();
332                         if(b_image)
333                                 env->filename = blender_absolute_path(b_data, b_image, b_image.filepath());
334                         env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
335                         get_tex_mapping(&env->tex_mapping, b_env_node.texture_mapping());
336                         node = env;
337                         break;
338                 }
339                 case BL::ShaderNode::type_TEX_GRADIENT: {
340                         BL::ShaderNodeTexGradient b_gradient_node(b_node);
341                         GradientTextureNode *gradient = new GradientTextureNode();
342                         gradient->type = GradientTextureNode::type_enum[(int)b_gradient_node.gradient_type()];
343                         get_tex_mapping(&gradient->tex_mapping, b_gradient_node.texture_mapping());
344                         node = gradient;
345                         break;
346                 }
347                 case BL::ShaderNode::type_TEX_VORONOI: {
348                         BL::ShaderNodeTexVoronoi b_voronoi_node(b_node);
349                         VoronoiTextureNode *voronoi = new VoronoiTextureNode();
350                         voronoi->coloring = VoronoiTextureNode::coloring_enum[(int)b_voronoi_node.coloring()];
351                         get_tex_mapping(&voronoi->tex_mapping, b_voronoi_node.texture_mapping());
352                         node = voronoi;
353                         break;
354                 }
355                 case BL::ShaderNode::type_TEX_MAGIC: {
356                         BL::ShaderNodeTexMagic b_magic_node(b_node);
357                         MagicTextureNode *magic = new MagicTextureNode();
358                         magic->depth = b_magic_node.turbulence_depth();
359                         get_tex_mapping(&magic->tex_mapping, b_magic_node.texture_mapping());
360                         node = magic;
361                         break;
362                 }
363                 case BL::ShaderNode::type_TEX_WAVE: {
364                         BL::ShaderNodeTexWave b_wave_node(b_node);
365                         WaveTextureNode *wave = new WaveTextureNode();
366                         wave->type = WaveTextureNode::type_enum[(int)b_wave_node.wave_type()];
367                         get_tex_mapping(&wave->tex_mapping, b_wave_node.texture_mapping());
368                         node = wave;
369                         break;
370                 }
371                 case BL::ShaderNode::type_TEX_CHECKER: {
372                         BL::ShaderNodeTexChecker b_checker_node(b_node);
373                         CheckerTextureNode *checker = new CheckerTextureNode();
374                         get_tex_mapping(&checker->tex_mapping, b_checker_node.texture_mapping());
375                         node = checker;
376                         break;
377                 }
378                 case BL::ShaderNode::type_TEX_NOISE: {
379                         BL::ShaderNodeTexNoise b_noise_node(b_node);
380                         NoiseTextureNode *noise = new NoiseTextureNode();
381                         get_tex_mapping(&noise->tex_mapping, b_noise_node.texture_mapping());
382                         node = noise;
383                         break;
384                 }
385                 case BL::ShaderNode::type_TEX_MUSGRAVE: {
386                         BL::ShaderNodeTexMusgrave b_musgrave_node(b_node);
387                         MusgraveTextureNode *musgrave = new MusgraveTextureNode();
388                         musgrave->type = MusgraveTextureNode::type_enum[(int)b_musgrave_node.musgrave_type()];
389                         get_tex_mapping(&musgrave->tex_mapping, b_musgrave_node.texture_mapping());
390                         node = musgrave;
391                         break;
392                 }
393                 case BL::ShaderNode::type_TEX_COORD: {
394                         node = new TextureCoordinateNode();;
395                         break;
396                 }
397                 case BL::ShaderNode::type_TEX_SKY: {
398                         BL::ShaderNodeTexSky b_sky_node(b_node);
399                         SkyTextureNode *sky = new SkyTextureNode();
400                         sky->sun_direction = get_float3(b_sky_node.sun_direction());
401                         sky->turbidity = b_sky_node.turbidity();
402                         get_tex_mapping(&sky->tex_mapping, b_sky_node.texture_mapping());
403                         node = sky;
404                         break;
405                 }
406         }
407
408         if(node && node != graph->output())
409                 graph->add(node);
410
411         return node;
412 }
413
414 static SocketPair node_socket_map_pair(PtrNodeMap& node_map, BL::Node b_node, BL::NodeSocket b_socket)
415 {
416         BL::Node::inputs_iterator b_input;
417         BL::Node::outputs_iterator b_output;
418         string name = b_socket.name();
419         bool found = false;
420         int counter = 0, total = 0;
421
422         /* find in inputs */
423         for(b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
424                 if(b_input->name() == name) {
425                         if(!found)
426                                 counter++;
427                         total++;
428                 }
429
430                 if(b_input->ptr.data == b_socket.ptr.data)
431                         found = true;
432         }
433
434         if(!found) {
435                 /* find in outputs */
436                 found = false;
437                 counter = 0;
438                 total = 0;
439
440                 for(b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
441                         if(b_output->name() == name) {
442                                 if(!found)
443                                         counter++;
444                                 total++;
445                         }
446
447                         if(b_output->ptr.data == b_socket.ptr.data)
448                                 found = true;
449                 }
450         }
451
452         /* rename if needed */
453         if(name == "Shader")
454                 name = "Closure";
455
456         if(total > 1)
457                 name = string_printf("%s%d", name.c_str(), counter);
458
459         return SocketPair(node_map[b_node.ptr.data], name);
460 }
461
462 static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type)
463 {
464         switch (b_type) {
465         case BL::NodeSocket::type_VALUE:
466                 return SHADER_SOCKET_FLOAT;
467         case BL::NodeSocket::type_VECTOR:
468                 return SHADER_SOCKET_VECTOR;
469         case BL::NodeSocket::type_RGBA:
470                 return SHADER_SOCKET_COLOR;
471         case BL::NodeSocket::type_SHADER:
472                 return SHADER_SOCKET_CLOSURE;
473         
474         case BL::NodeSocket::type_BOOLEAN:
475         case BL::NodeSocket::type_MESH:
476         case BL::NodeSocket::type_INT:
477         default:
478                 return SHADER_SOCKET_FLOAT;
479         }
480 }
481
482 static void set_default_value(ShaderInput *input, BL::NodeSocket sock)
483 {
484         /* copy values for non linked inputs */
485         switch(input->type) {
486         case SHADER_SOCKET_FLOAT: {
487                 BL::NodeSocketFloatNone value_sock(sock);
488                 input->set(value_sock.default_value());
489                 break;
490         }
491         case SHADER_SOCKET_COLOR: {
492                 BL::NodeSocketRGBA rgba_sock(sock);
493                 input->set(get_float3(rgba_sock.default_value()));
494                 break;
495         }
496         case SHADER_SOCKET_NORMAL:
497         case SHADER_SOCKET_POINT:
498         case SHADER_SOCKET_VECTOR: {
499                 BL::NodeSocketVectorNone vec_sock(sock);
500                 input->set(get_float3(vec_sock.default_value()));
501                 break;
502         }
503         case SHADER_SOCKET_CLOSURE:
504                 break;
505         }
506 }
507
508 static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map)
509 {
510         /* add nodes */
511         BL::ShaderNodeTree::nodes_iterator b_node;
512         PtrNodeMap node_map;
513         PtrSockMap proxy_map;
514
515         for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
516                 if(b_node->is_a(&RNA_NodeGroup)) {
517                         /* add proxy converter nodes for inputs and outputs */
518                         BL::NodeGroup b_gnode(*b_node);
519                         BL::ShaderNodeTree b_group_ntree(b_gnode.node_tree());
520                         BL::Node::inputs_iterator b_input;
521                         BL::Node::outputs_iterator b_output;
522                         
523                         PtrSockMap group_sockmap;
524                         
525                         for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
526                                 ShaderSocketType extern_type = convert_socket_type(b_input->type());
527                                 ShaderSocketType intern_type = convert_socket_type(b_input->group_socket().type());
528                                 ShaderNode *proxy = graph->add(new ProxyNode(extern_type, intern_type));
529                                 
530                                 /* map the external node socket to the proxy node socket */
531                                 proxy_map[b_input->ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
532                                 /* map the internal group socket to the proxy node socket */
533                                 group_sockmap[b_input->group_socket().ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
534                                 
535                                 /* default input values of the group node */
536                                 set_default_value(proxy->inputs[0], *b_input);
537                         }
538                         
539                         for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
540                                 ShaderSocketType extern_type = convert_socket_type(b_output->type());
541                                 ShaderSocketType intern_type = convert_socket_type(b_output->group_socket().type());
542                                 ShaderNode *proxy = graph->add(new ProxyNode(intern_type, extern_type));
543                                 
544                                 /* map the external node socket to the proxy node socket */
545                                 proxy_map[b_output->ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
546                                 /* map the internal group socket to the proxy node socket */
547                                 group_sockmap[b_output->group_socket().ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
548                                 
549                                 /* default input values of internal, unlinked group outputs */
550                                 set_default_value(proxy->inputs[0], b_output->group_socket());
551                         }
552                         
553                         add_nodes(b_data, graph, b_group_ntree, group_sockmap);
554                 }
555                 else {
556                         ShaderNode *node = add_node(b_data, graph, BL::ShaderNode(*b_node));
557                         
558                         if(node) {
559                                 BL::Node::inputs_iterator b_input;
560                                 
561                                 node_map[b_node->ptr.data] = node;
562                                 
563                                 for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
564                                         SocketPair pair = node_socket_map_pair(node_map, *b_node, *b_input);
565                                         ShaderInput *input = pair.first->input(pair.second.c_str());
566                                         
567                                         assert(input);
568                                         
569                                         /* copy values for non linked inputs */
570                                         set_default_value(input, *b_input);
571                                 }
572                         }
573                 }
574         }
575
576         /* connect nodes */
577         BL::NodeTree::links_iterator b_link;
578
579         for(b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
580                 /* get blender link data */
581                 BL::Node b_from_node = b_link->from_node();
582                 BL::Node b_to_node = b_link->to_node();
583
584                 BL::NodeSocket b_from_sock = b_link->from_socket();
585                 BL::NodeSocket b_to_sock = b_link->to_socket();
586
587                 SocketPair from_pair, to_pair;
588
589                 /* links without a node pointer are connections to group inputs/outputs */
590
591                 /* from sock */
592                 if(b_from_node) {
593                         if (b_from_node.is_a(&RNA_NodeGroup))
594                                 from_pair = proxy_map[b_from_sock.ptr.data];
595                         else
596                                 from_pair = node_socket_map_pair(node_map, b_from_node, b_from_sock);
597                 }
598                 else
599                         from_pair = sockets_map[b_from_sock.ptr.data];
600
601                 /* to sock */
602                 if(b_to_node) {
603                         if (b_to_node.is_a(&RNA_NodeGroup))
604                                 to_pair = proxy_map[b_to_sock.ptr.data];
605                         else
606                                 to_pair = node_socket_map_pair(node_map, b_to_node, b_to_sock);
607                 }
608                 else
609                         to_pair = sockets_map[b_to_sock.ptr.data];
610
611                 /* either node may be NULL when the node was not exported, typically
612                    because the node type is not supported */
613                 if(from_pair.first && to_pair.first) {
614                         ShaderOutput *output = from_pair.first->output(from_pair.second.c_str());
615                         ShaderInput *input = to_pair.first->input(to_pair.second.c_str());
616
617                         graph->connect(output, input);
618                 }
619         }
620 }
621
622 /* Sync Materials */
623
624 void BlenderSync::sync_materials()
625 {
626         shader_map.set_default(scene->shaders[scene->default_surface]);
627
628         /* material loop */
629         BL::BlendData::materials_iterator b_mat;
630
631         for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat) {
632                 Shader *shader;
633                 
634                 /* test if we need to sync */
635                 if(shader_map.sync(&shader, *b_mat)) {
636                         ShaderGraph *graph = new ShaderGraph();
637
638                         shader->name = b_mat->name().c_str();
639                         shader->pass_id = b_mat->pass_index();
640
641                         /* create nodes */
642                         if(b_mat->use_nodes() && b_mat->node_tree()) {
643                                 PtrSockMap sock_to_node;
644                                 BL::ShaderNodeTree b_ntree(b_mat->node_tree());
645
646                                 add_nodes(b_data, graph, b_ntree, sock_to_node);
647                         }
648                         else {
649                                 ShaderNode *closure, *out;
650
651                                 closure = graph->add(new DiffuseBsdfNode());
652                                 closure->input("Color")->value = get_float3(b_mat->diffuse_color());
653                                 out = graph->output();
654
655                                 graph->connect(closure->output("BSDF"), out->input("Surface"));
656                         }
657
658                         /* settings */
659                         PointerRNA cmat = RNA_pointer_get(&b_mat->ptr, "cycles");
660                         shader->sample_as_light = get_boolean(cmat, "sample_as_light");
661                         shader->homogeneous_volume = get_boolean(cmat, "homogeneous_volume");
662
663                         shader->set_graph(graph);
664                         shader->tag_update(scene);
665                 }
666         }
667 }
668
669 /* Sync World */
670
671 void BlenderSync::sync_world()
672 {
673         Background *background = scene->background;
674         Background prevbackground = *background;
675
676         BL::World b_world = b_scene.world();
677
678         if(world_recalc || b_world.ptr.data != world_map) {
679                 Shader *shader = scene->shaders[scene->default_background];
680                 ShaderGraph *graph = new ShaderGraph();
681
682                 /* create nodes */
683                 if(b_world && b_world.use_nodes() && b_world.node_tree()) {
684                         PtrSockMap sock_to_node;
685                         BL::ShaderNodeTree b_ntree(b_world.node_tree());
686
687                         add_nodes(b_data, graph, b_ntree, sock_to_node);
688                 }
689                 else if(b_world) {
690                         ShaderNode *closure, *out;
691
692                         closure = graph->add(new BackgroundNode());
693                         closure->input("Color")->value = get_float3(b_world.horizon_color());
694                         out = graph->output();
695
696                         graph->connect(closure->output("Background"), out->input("Surface"));
697                 }
698
699                 /* AO */
700                 if(b_world) {
701                         BL::WorldLighting b_light = b_world.light_settings();
702
703                         if(b_light.use_ambient_occlusion()) {
704                                 background->ao_factor = b_light.ao_factor();
705                                 background->ao_distance = b_light.distance();
706                         }
707                         else {
708                                 background->ao_factor = 0.0f;
709                                 background->ao_distance = 0.0f;
710                         }
711                 }
712
713                 shader->set_graph(graph);
714                 shader->tag_update(scene);
715         }
716
717         PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
718         background->transparent = get_boolean(cscene, "film_transparent");
719
720         if(background->modified(prevbackground))
721                 background->tag_update(scene);
722 }
723
724 /* Sync Lamps */
725
726 void BlenderSync::sync_lamps()
727 {
728         shader_map.set_default(scene->shaders[scene->default_light]);
729
730         /* lamp loop */
731         BL::BlendData::lamps_iterator b_lamp;
732
733         for(b_data.lamps.begin(b_lamp); b_lamp != b_data.lamps.end(); ++b_lamp) {
734                 Shader *shader;
735                 
736                 /* test if we need to sync */
737                 if(shader_map.sync(&shader, *b_lamp)) {
738                         ShaderGraph *graph = new ShaderGraph();
739
740                         /* create nodes */
741                         if(b_lamp->use_nodes() && b_lamp->node_tree()) {
742                                 shader->name = b_lamp->name().c_str();
743
744                                 PtrSockMap sock_to_node;
745                                 BL::ShaderNodeTree b_ntree(b_lamp->node_tree());
746
747                                 add_nodes(b_data, graph, b_ntree, sock_to_node);
748                         }
749                         else {
750                                 ShaderNode *closure, *out;
751                                 float strength = 1.0f;
752
753                                 if(b_lamp->type() == BL::Lamp::type_POINT ||
754                                    b_lamp->type() == BL::Lamp::type_SPOT ||
755                                    b_lamp->type() == BL::Lamp::type_AREA)
756                                         strength = 100.0f;
757
758                                 closure = graph->add(new EmissionNode());
759                                 closure->input("Color")->value = get_float3(b_lamp->color());
760                                 closure->input("Strength")->value.x = strength;
761                                 out = graph->output();
762
763                                 graph->connect(closure->output("Emission"), out->input("Surface"));
764                         }
765
766                         shader->set_graph(graph);
767                         shader->tag_update(scene);
768                 }
769         }
770 }
771
772 void BlenderSync::sync_shaders()
773 {
774         shader_map.pre_sync();
775
776         sync_world();
777         sync_lamps();
778         sync_materials();
779
780         /* false = don't delete unused shaders, not supported */
781         shader_map.post_sync(false);
782 }
783
784 CCL_NAMESPACE_END
785