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