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