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