Cycles: make node with multiple input sockets with the same name work. Previously
[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)
40 {
41         Shader *shader = shader_map.find(id);
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_input(BL::Node *b_group_node, BL::NodeSocket b_in)
54 {
55         if(b_group_node) {
56
57                 BL::NodeTree b_ntree = BL::NodeGroup(*b_group_node).node_tree();
58                 BL::NodeTree::links_iterator b_link;
59
60                 for(b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
61                         if(b_link->to_socket().ptr.data == b_in.ptr.data) {
62                                 BL::Node::inputs_iterator b_gin;
63
64                                 for(b_group_node->inputs.begin(b_gin); b_gin != b_group_node->inputs.end(); ++b_gin)
65                                         if(b_gin->group_socket().ptr.data == b_link->from_socket().ptr.data)
66                                                 return *b_gin;
67
68                         }
69                 }
70         }
71
72         return b_in;
73 }
74
75 static BL::NodeSocket get_node_output(BL::Node b_node, const string& name)
76 {
77         BL::Node::outputs_iterator b_out;
78
79         for(b_node.outputs.begin(b_out); b_out != b_node.outputs.end(); ++b_out)
80                 if(b_out->name() == name)
81                         return *b_out;
82
83         assert(0);
84
85         return *b_out;
86 }
87
88 static float3 get_node_output_rgba(BL::Node b_node, const string& name)
89 {
90         BL::NodeSocketRGBA sock(get_node_output(b_node, name));
91         return get_float3(sock.default_value());
92 }
93
94 static float get_node_output_value(BL::Node b_node, const string& name)
95 {
96         BL::NodeSocketFloatNone sock(get_node_output(b_node, name));
97         return sock.default_value();
98 }
99
100 static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::Node *b_group_node, BL::ShaderNode b_node)
101 {
102         ShaderNode *node = NULL;
103
104         switch(b_node.type()) {
105                 /* not supported */
106                 case BL::ShaderNode::type_CAMERA: break;
107                 case BL::ShaderNode::type_COMBRGB: break;
108                 case BL::ShaderNode::type_CURVE_RGB: break;
109                 case BL::ShaderNode::type_CURVE_VEC: break;
110                 case BL::ShaderNode::type_GEOM: break;
111                 case BL::ShaderNode::type_HUE_SAT: break;
112                 case BL::ShaderNode::type_INVERT: break;
113                 case BL::ShaderNode::type_MATERIAL: break;
114                 case BL::ShaderNode::type_MATERIAL_EXT: break;
115                 case BL::ShaderNode::type_NORMAL: break;
116                 case BL::ShaderNode::type_OUTPUT: break;
117                 case BL::ShaderNode::type_SCRIPT: break;
118                 case BL::ShaderNode::type_SEPRGB: break;
119                 case BL::ShaderNode::type_SQUEEZE: break;
120                 case BL::ShaderNode::type_TEXTURE: break;
121                 case BL::ShaderNode::type_VALTORGB: break;
122                 /* handled outside this function */
123                 case BL::ShaderNode::type_GROUP: break;
124                 /* existing blender nodes */
125                 case BL::ShaderNode::type_RGB: {
126                         ColorNode *color = new ColorNode();
127                         color->value = get_node_output_rgba(b_node, "Color");
128                         node = color;
129                         break;
130                 }
131                 case BL::ShaderNode::type_VALUE: {
132                         ValueNode *value = new ValueNode();
133                         value->value = get_node_output_value(b_node, "Value");
134                         node = value;
135                         break;
136                 }
137                 case BL::ShaderNode::type_MIX_RGB: {
138                         BL::ShaderNodeMixRGB b_mix_node(b_node);
139                         MixNode *mix = new MixNode();
140                         mix->type = MixNode::type_enum[b_mix_node.blend_type()];
141                         node = mix;
142                         break;
143                 }
144                 case BL::ShaderNode::type_RGBTOBW: {
145                         node = new ConvertNode(SHADER_SOCKET_COLOR, SHADER_SOCKET_FLOAT);
146                         break;
147                 }
148                 case BL::ShaderNode::type_MATH: {
149                         BL::ShaderNodeMath b_math_node(b_node);
150                         MathNode *math = new MathNode();
151                         math->type = MathNode::type_enum[b_math_node.operation()];
152                         node = math;
153                         break;
154                 }
155                 case BL::ShaderNode::type_VECT_MATH: {
156                         BL::ShaderNodeVectorMath b_vector_math_node(b_node);
157                         VectorMathNode *vmath = new VectorMathNode();
158                         vmath->type = VectorMathNode::type_enum[b_vector_math_node.operation()];
159                         node = vmath;
160                         break;
161                 }
162                 case BL::ShaderNode::type_MAPPING: {
163                         BL::ShaderNodeMapping b_mapping_node(b_node);
164                         MappingNode *mapping = new MappingNode();
165                         mapping->translation = get_float3(b_mapping_node.location());
166                         mapping->rotation = get_float3(b_mapping_node.rotation());
167                         mapping->scale = get_float3(b_mapping_node.scale());
168                         node = mapping;
169                         break;
170                 }
171
172                 /* new nodes */
173                 case BL::ShaderNode::type_OUTPUT_MATERIAL:
174                 case BL::ShaderNode::type_OUTPUT_WORLD:
175                 case BL::ShaderNode::type_OUTPUT_LAMP: {
176                         node = graph->output();
177                         break;
178                 }
179                 case BL::ShaderNode::type_FRESNEL: {
180                         node = new FresnelNode();
181                         break;
182                 }
183                 case BL::ShaderNode::type_BLEND_WEIGHT: {
184                         node = new BlendWeightNode();
185                         break;
186                 }
187                 case BL::ShaderNode::type_ADD_SHADER: {
188                         node = new AddClosureNode();
189                         break;
190                 }
191                 case BL::ShaderNode::type_MIX_SHADER: {
192                         node = new MixClosureNode();
193                         break;
194                 }
195                 case BL::ShaderNode::type_ATTRIBUTE: {
196                         AttributeNode *attr = new AttributeNode();
197                         attr->attribute = "";
198                         node = attr;
199                         break;
200                 }
201                 case BL::ShaderNode::type_BACKGROUND: {
202                         node = new BackgroundNode();
203                         break;
204                 }
205                 case BL::ShaderNode::type_HOLDOUT: {
206                         node = new HoldoutNode();
207                         break;
208                 }
209                 case BL::ShaderNode::type_BSDF_ANISOTROPIC: {
210                         node = new WardBsdfNode();
211                         break;
212                 }
213                 case BL::ShaderNode::type_BSDF_DIFFUSE: {
214                         node = new DiffuseBsdfNode();
215                         break;
216                 }
217                 case BL::ShaderNode::type_BSDF_GLOSSY: {
218                         BL::ShaderNodeBsdfGlossy b_glossy_node(b_node);
219                         GlossyBsdfNode *glossy = new GlossyBsdfNode();
220
221                         switch(b_glossy_node.distribution()) {
222                                 case BL::ShaderNodeBsdfGlossy::distribution_SHARP:
223                                         glossy->distribution = ustring("Sharp");
224                                         break;
225                                 case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN:
226                                         glossy->distribution = ustring("Beckmann");
227                                         break;
228                                 case BL::ShaderNodeBsdfGlossy::distribution_GGX:
229                                         glossy->distribution = ustring("GGX");
230                                         break;
231                         }
232                         node = glossy;
233                         break;
234                 }
235                 case BL::ShaderNode::type_BSDF_GLASS: {
236                         BL::ShaderNodeBsdfGlass b_glass_node(b_node);
237                         GlassBsdfNode *glass = new GlassBsdfNode();
238                         switch(b_glass_node.distribution()) {
239                                 case BL::ShaderNodeBsdfGlass::distribution_SHARP:
240                                         glass->distribution = ustring("Sharp");
241                                         break;
242                                 case BL::ShaderNodeBsdfGlass::distribution_BECKMANN:
243                                         glass->distribution = ustring("Beckmann");
244                                         break;
245                                 case BL::ShaderNodeBsdfGlass::distribution_GGX:
246                                         glass->distribution = ustring("GGX");
247                                         break;
248                         }
249                         node = glass;
250                         break;
251                 }
252                 case BL::ShaderNode::type_BSDF_TRANSLUCENT: {
253                         node = new TranslucentBsdfNode();
254                         break;
255                 }
256                 case BL::ShaderNode::type_BSDF_TRANSPARENT: {
257                         node = new TransparentBsdfNode();
258                         break;
259                 }
260                 case BL::ShaderNode::type_BSDF_VELVET: {
261                         node = new VelvetBsdfNode();
262                         break;
263                 }
264                 case BL::ShaderNode::type_EMISSION: {
265                         node = new EmissionNode();
266                         break;
267                 }
268                 case BL::ShaderNode::type_VOLUME_ISOTROPIC: {
269                         node = new IsotropicVolumeNode();
270                         break;
271                 }
272                 case BL::ShaderNode::type_VOLUME_TRANSPARENT: {
273                         node = new TransparentVolumeNode();
274                         break;
275                 }
276                 case BL::ShaderNode::type_GEOMETRY: {
277                         node = new GeometryNode();
278                         break;
279                 }
280                 case BL::ShaderNode::type_LIGHT_PATH: {
281                         node = new LightPathNode();
282                         break;
283                 }
284                 case BL::ShaderNode::type_TEX_IMAGE: {
285                         BL::ShaderNodeTexImage b_image_node(b_node);
286                         BL::Image b_image(b_image_node.image());
287                         ImageTextureNode *image = new ImageTextureNode();
288                         /* todo: handle generated/builtin images */
289                         if(b_image)
290                                 image->filename = blender_absolute_path(b_data, b_image, b_image.filepath());
291                         image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()];
292                         node = image;
293                         break;
294                 }
295                 case BL::ShaderNode::type_TEX_ENVIRONMENT: {
296                         BL::ShaderNodeTexEnvironment b_env_node(b_node);
297                         BL::Image b_image(b_env_node.image());
298                         EnvironmentTextureNode *env = new EnvironmentTextureNode();
299                         if(b_image)
300                                 env->filename = blender_absolute_path(b_data, b_image, b_image.filepath());
301                         env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
302                         node = env;
303                         break;
304                 }
305                 case BL::ShaderNode::type_TEX_NOISE: {
306                         node = new NoiseTextureNode();
307                         break;
308                 }
309                 case BL::ShaderNode::type_TEX_BLEND: {
310                         BL::ShaderNodeTexBlend b_blend_node(b_node);
311                         BlendTextureNode *blend = new BlendTextureNode();
312                         blend->progression = BlendTextureNode::progression_enum[(int)b_blend_node.progression()];
313                         blend->axis = BlendTextureNode::axis_enum[(int)b_blend_node.axis()];
314                         node = blend;
315                         break;
316                 }
317                 case BL::ShaderNode::type_TEX_VORONOI: {
318                         BL::ShaderNodeTexVoronoi b_voronoi_node(b_node);
319                         VoronoiTextureNode *voronoi = new VoronoiTextureNode();
320                         voronoi->distance_metric = VoronoiTextureNode::distance_metric_enum[(int)b_voronoi_node.distance_metric()];
321                         voronoi->coloring = VoronoiTextureNode::coloring_enum[(int)b_voronoi_node.coloring()];
322                         node = voronoi;
323                         break;
324                 }
325                 case BL::ShaderNode::type_TEX_MAGIC: {
326                         BL::ShaderNodeTexMagic b_magic_node(b_node);
327                         MagicTextureNode *magic = new MagicTextureNode();
328                         magic->depth = b_magic_node.turbulence_depth();
329                         node = magic;
330                         break;
331                 }
332                 case BL::ShaderNode::type_TEX_MARBLE: {
333                         BL::ShaderNodeTexMarble b_marble_node(b_node);
334                         MarbleTextureNode *marble = new MarbleTextureNode();
335                         marble->depth = b_marble_node.turbulence_depth();
336                         marble->basis = MarbleTextureNode::basis_enum[(int)b_marble_node.noise_basis()];
337                         marble->type = MarbleTextureNode::type_enum[(int)b_marble_node.marble_type()];
338                         marble->wave = MarbleTextureNode::wave_enum[(int)b_marble_node.wave_type()];
339                         marble->hard = b_marble_node.noise_type() == BL::ShaderNodeTexMarble::noise_type_HARD;
340                         node = marble;
341                         break;
342                 }
343                 case BL::ShaderNode::type_TEX_CLOUDS: {
344                         BL::ShaderNodeTexClouds b_clouds_node(b_node);
345                         CloudsTextureNode *clouds = new CloudsTextureNode();
346                         clouds->depth = b_clouds_node.turbulence_depth();
347                         clouds->basis = CloudsTextureNode::basis_enum[(int)b_clouds_node.noise_basis()];
348                         clouds->hard = b_clouds_node.noise_type() == BL::ShaderNodeTexClouds::noise_type_HARD;
349                         node = clouds;
350                         break;
351                 }
352                 case BL::ShaderNode::type_TEX_WOOD: {
353                         BL::ShaderNodeTexWood b_wood_node(b_node);
354                         WoodTextureNode *wood = new WoodTextureNode();
355                         wood->type = WoodTextureNode::type_enum[(int)b_wood_node.wood_type()];
356                         wood->basis = WoodTextureNode::basis_enum[(int)b_wood_node.noise_basis()];
357                         wood->hard = b_wood_node.noise_type() == BL::ShaderNodeTexWood::noise_type_HARD;
358                         wood->wave = WoodTextureNode::wave_enum[(int)b_wood_node.wave_type()];
359                         node = wood;
360                         break;
361                 }
362                 case BL::ShaderNode::type_TEX_MUSGRAVE: {
363                         BL::ShaderNodeTexMusgrave b_musgrave_node(b_node);
364                         MusgraveTextureNode *musgrave = new MusgraveTextureNode();
365                         musgrave->type = MusgraveTextureNode::type_enum[(int)b_musgrave_node.musgrave_type()];
366                         musgrave->basis = MusgraveTextureNode::basis_enum[(int)b_musgrave_node.noise_basis()];
367                         node = musgrave;
368                         break;
369                 }
370                 case BL::ShaderNode::type_TEX_STUCCI: {
371                         BL::ShaderNodeTexStucci b_stucci_node(b_node);
372                         StucciTextureNode *stucci = new StucciTextureNode();
373                         stucci->type = StucciTextureNode::type_enum[(int)b_stucci_node.stucci_type()];
374                         stucci->basis = StucciTextureNode::basis_enum[(int)b_stucci_node.noise_basis()];
375                         stucci->hard = b_stucci_node.noise_type() == BL::ShaderNodeTexStucci::noise_type_HARD;
376                         node = stucci;
377                         break;
378                 }
379                 case BL::ShaderNode::type_TEX_DISTORTED_NOISE: {
380                         BL::ShaderNodeTexDistortedNoise b_distnoise_node(b_node);
381                         DistortedNoiseTextureNode *distnoise = new DistortedNoiseTextureNode();
382                         distnoise->basis = DistortedNoiseTextureNode::basis_enum[(int)b_distnoise_node.noise_basis()];
383                         distnoise->distortion_basis = DistortedNoiseTextureNode::basis_enum[(int)b_distnoise_node.noise_distortion()];
384                         node = distnoise;
385                         break;
386                 }
387                 case BL::ShaderNode::type_TEX_COORD: {
388                         node = new TextureCoordinateNode();;
389                         break;
390                 }
391                 case BL::ShaderNode::type_TEX_SKY: {
392                         BL::ShaderNodeTexSky b_sky_node(b_node);
393                         SkyTextureNode *sky = new SkyTextureNode();
394                         sky->sun_direction = get_float3(b_sky_node.sun_direction());
395                         sky->turbidity = b_sky_node.turbidity();
396                         node = sky;
397                         break;
398                 }
399         }
400
401         if(node && node != graph->output())
402                 graph->add(node);
403
404         return node;
405 }
406
407 static SocketPair node_socket_map_pair(PtrNodeMap& node_map, BL::Node b_node, BL::NodeSocket b_socket)
408 {
409         BL::Node::inputs_iterator b_input;
410         BL::Node::outputs_iterator b_output;
411         string name = b_socket.name();
412         bool found = false;
413         int counter = 0, total = 0;
414
415         /* find in inputs */
416         for(b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
417                 if(b_input->name() == name) {
418                         if(!found)
419                                 counter++;
420                         total++;
421                 }
422
423                 if(b_input->ptr.data == b_socket.ptr.data)
424                         found = true;
425         }
426
427         if(!found) {
428                 /* find in outputs */
429                 found = false;
430                 counter = 0;
431                 total = 0;
432
433                 for(b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
434                         if(b_output->name() == name) {
435                                 if(!found)
436                                         counter++;
437                                 total++;
438                         }
439
440                         if(b_output->ptr.data == b_socket.ptr.data)
441                                 found = true;
442                 }
443         }
444
445         /* rename if needed */
446         if(name == "Shader")
447                 name = "Closure";
448
449         if(total > 1)
450                 name = string_printf("%s%d", name.c_str(), counter);
451
452         return SocketPair(node_map[b_node.ptr.data], name);
453 }
454
455 static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, BL::Node *b_group_node, PtrSockMap& sockets_map)
456 {
457         /* add nodes */
458         BL::ShaderNodeTree::nodes_iterator b_node;
459         PtrNodeMap node_map;
460         map<void*, PtrSockMap> node_groups;
461
462         for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
463                 if(b_node->is_a(&RNA_NodeGroup)) {
464                         BL::NodeGroup b_gnode(*b_node);
465                         BL::ShaderNodeTree b_group_ntree(b_gnode.node_tree());
466
467                         node_groups[b_node->ptr.data] = PtrSockMap();
468                         add_nodes(b_data, graph, b_group_ntree, &b_gnode, node_groups[b_node->ptr.data]);
469                 }
470                 else {
471                         ShaderNode *node = add_node(b_data, graph, b_group_node, BL::ShaderNode(*b_node));
472
473                         if(node) {
474                                 BL::Node::inputs_iterator b_input;
475                                 BL::Node::outputs_iterator b_output;
476
477                                 node_map[b_node->ptr.data] = node;
478
479                                 for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
480                                         SocketPair pair = node_socket_map_pair(node_map, *b_node, *b_input);
481                                         ShaderInput *input = pair.first->input(pair.second.c_str());
482                                         BL::NodeSocket sock(get_node_input(b_group_node, *b_input));
483
484                                         assert(input);
485
486                                         /* copy values for non linked inputs */
487                                         switch(input->type) {
488                                                 case SHADER_SOCKET_FLOAT: {
489                                                         BL::NodeSocketFloatNone value_sock(sock);
490                                                         input->set(value_sock.default_value());
491                                                         break;
492                                                 }
493                                                 case SHADER_SOCKET_COLOR: {
494                                                         BL::NodeSocketRGBA rgba_sock(sock);
495                                                         input->set(get_float3(rgba_sock.default_value()));
496                                                         break;
497                                                 }
498                                                 case SHADER_SOCKET_NORMAL:
499                                                 case SHADER_SOCKET_POINT:
500                                                 case SHADER_SOCKET_VECTOR: {
501                                                         BL::NodeSocketVectorNone vec_sock(sock);
502                                                         input->set(get_float3(vec_sock.default_value()));
503                                                         break;
504                                                 }
505                                                 case SHADER_SOCKET_CLOSURE:
506                                                         break;
507                                         }
508                                 }
509                         }
510                 }
511         }
512
513         /* connect nodes */
514         BL::NodeTree::links_iterator b_link;
515
516         for(b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
517                 /* get blender link data */
518                 BL::Node b_from_node = b_link->from_node();
519                 BL::Node b_to_node = b_link->to_node();
520
521                 BL::NodeSocket b_from_sock = b_link->from_socket();
522                 BL::NodeSocket b_to_sock = b_link->to_socket();
523
524                 /* if link with group socket, add to map so we can connect it later */
525                 if(b_group_node) {
526                         if(!b_from_node) {
527                                 sockets_map[b_from_sock.ptr.data] =
528                                         node_socket_map_pair(node_map, b_to_node, b_to_sock);
529
530                                 continue;
531                         }
532                         else if(!b_to_node) {
533                                 sockets_map[b_to_sock.ptr.data] =
534                                         node_socket_map_pair(node_map, b_from_node, b_from_sock);
535
536                                 continue;
537                         }
538                 }
539
540                 SocketPair from_pair, to_pair;
541
542                 /* from sock */
543                 if(b_from_node.is_a(&RNA_NodeGroup)) {
544                         /* group node */
545                         BL::NodeSocket group_sock = b_from_sock.group_socket();
546                         from_pair = node_groups[b_from_node.ptr.data][group_sock.ptr.data];
547                 }
548                 else {
549                         /* regular node */
550                         from_pair = node_socket_map_pair(node_map, b_from_node, b_from_sock);
551                 }
552
553                 /* to sock */
554                 if(b_to_node.is_a(&RNA_NodeGroup)) {
555                         /* group node */
556                         BL::NodeSocket group_sock = b_to_sock.group_socket();
557                         to_pair = node_groups[b_to_node.ptr.data][group_sock.ptr.data];
558                 }
559                 else {
560                         /* regular node */
561                         to_pair = node_socket_map_pair(node_map, b_to_node, b_to_sock);
562                 }
563
564                 /* in case of groups there may not actually be a node inside the group
565                    that the group socket connects to, so from_node or to_node may be NULL */
566                 if(from_pair.first && to_pair.first) {
567                         ShaderOutput *output = from_pair.first->output(from_pair.second.c_str());
568                         ShaderInput *input = to_pair.first->input(to_pair.second.c_str());
569
570                         graph->connect(output, input);
571                 }
572         }
573 }
574
575 /* Sync Materials */
576
577 void BlenderSync::sync_materials()
578 {
579         shader_map.set_default(scene->shaders[scene->default_surface]);
580
581         /* material loop */
582         BL::BlendData::materials_iterator b_mat;
583
584         for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat) {
585                 Shader *shader;
586                 
587                 /* test if we need to sync */
588                 if(shader_map.sync(&shader, *b_mat)) {
589                         ShaderGraph *graph = new ShaderGraph();
590
591                         shader->name = b_mat->name().c_str();
592
593                         /* create nodes */
594                         if(b_mat->use_nodes() && b_mat->node_tree()) {
595                                 PtrSockMap sock_to_node;
596                                 BL::ShaderNodeTree b_ntree(b_mat->node_tree());
597
598                                 add_nodes(b_data, graph, b_ntree, NULL, sock_to_node);
599                         }
600                         else {
601                                 ShaderNode *closure, *out;
602
603                                 closure = graph->add(new DiffuseBsdfNode());
604                                 closure->input("Color")->value = get_float3(b_mat->diffuse_color());
605                                 out = graph->output();
606
607                                 graph->connect(closure->output("BSDF"), out->input("Closure"));
608                         }
609
610                         /* settings */
611                         PointerRNA cmat = RNA_pointer_get(&b_mat->ptr, "cycles");
612                         //shader->sample_as_light = get_boolean(cmat, "sample_as_light");
613                         shader->homogeneous_volume = get_boolean(cmat, "homogeneous_volume");
614
615                         shader->set_graph(graph);
616                         shader->tag_update(scene);
617                 }
618         }
619 }
620
621 /* Sync World */
622
623 void BlenderSync::sync_world()
624 {
625         Background *background = scene->background;
626         Background prevbackground = *background;
627
628         BL::World b_world = b_scene.world();
629
630         if(world_recalc || b_world.ptr.data != world_map) {
631                 Shader *shader = scene->shaders[scene->default_background];
632                 ShaderGraph *graph = new ShaderGraph();
633
634                 /* create nodes */
635                 if(b_world && b_world.use_nodes() && b_world.node_tree()) {
636                         PtrSockMap sock_to_node;
637                         BL::ShaderNodeTree b_ntree(b_world.node_tree());
638
639                         add_nodes(b_data, graph, b_ntree, NULL, sock_to_node);
640                 }
641                 else if(b_world) {
642                         ShaderNode *closure, *out;
643
644                         closure = graph->add(new BackgroundNode());
645                         closure->input("Color")->value = get_float3(b_world.horizon_color());
646                         out = graph->output();
647
648                         graph->connect(closure->output("Background"), out->input("Closure"));
649                 }
650
651                 shader->set_graph(graph);
652                 shader->tag_update(scene);
653         }
654
655         PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
656         background->transparent = get_boolean(cscene, "film_transparent");
657
658         if(background->modified(prevbackground))
659                 background->tag_update(scene);
660
661         world_map = b_world.ptr.data;
662         world_recalc = false;
663 }
664
665 /* Sync Lamps */
666
667 void BlenderSync::sync_lamps()
668 {
669         shader_map.set_default(scene->shaders[scene->default_light]);
670
671         /* lamp loop */
672         BL::BlendData::lamps_iterator b_lamp;
673
674         for(b_data.lamps.begin(b_lamp); b_lamp != b_data.lamps.end(); ++b_lamp) {
675                 Shader *shader;
676                 
677                 /* test if we need to sync */
678                 if(shader_map.sync(&shader, *b_lamp)) {
679                         ShaderGraph *graph = new ShaderGraph();
680
681                         /* create nodes */
682                         if(b_lamp->use_nodes() && b_lamp->node_tree()) {
683                                 shader->name = b_lamp->name().c_str();
684
685                                 PtrSockMap sock_to_node;
686                                 BL::ShaderNodeTree b_ntree(b_lamp->node_tree());
687
688                                 add_nodes(b_data, graph, b_ntree, NULL, sock_to_node);
689                         }
690                         else {
691                                 ShaderNode *closure, *out;
692
693                                 closure = graph->add(new EmissionNode());
694                                 closure->input("Color")->value = get_float3(b_lamp->color());
695                                 closure->input("Strength")->value.x = b_lamp->energy()*10.0f;
696                                 out = graph->output();
697
698                                 graph->connect(closure->output("Emission"), out->input("Closure"));
699                         }
700
701                         shader->set_graph(graph);
702                         shader->tag_update(scene);
703                 }
704         }
705 }
706
707 void BlenderSync::sync_shaders()
708 {
709         shader_map.pre_sync();
710
711         sync_world();
712         sync_lamps();
713         sync_materials();
714
715         /* false = don't delete unused shaders, not supported */
716         shader_map.post_sync(false);
717 }
718
719 CCL_NAMESPACE_END
720