2 * Copyright 2011, Blender Foundation.
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.
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.
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.
19 #include "background.h"
26 #include "blender_sync.h"
27 #include "blender_util.h"
29 #include "util_debug.h"
33 typedef map<void*, ShaderNode*> PtrNodeMap;
34 typedef pair<ShaderNode*, std::string> SocketPair;
35 typedef map<void*, SocketPair> PtrSockMap;
39 void BlenderSync::find_shader(BL::ID id, vector<uint>& used_shaders, int default_shader)
41 Shader *shader = (id)? shader_map.find(id): scene->shaders[default_shader];
43 for(size_t i = 0; i < scene->shaders.size(); i++) {
44 if(scene->shaders[i] == shader) {
45 used_shaders.push_back(i);
53 static BL::NodeSocket get_node_output(BL::Node b_node, const string& name)
55 BL::Node::outputs_iterator b_out;
57 for(b_node.outputs.begin(b_out); b_out != b_node.outputs.end(); ++b_out)
58 if(b_out->name() == name)
66 static float3 get_node_output_rgba(BL::Node b_node, const string& name)
68 BL::NodeSocketRGBA sock(get_node_output(b_node, name));
69 return get_float3(sock.default_value());
72 static float get_node_output_value(BL::Node b_node, const string& name)
74 BL::NodeSocketFloatNone sock(get_node_output(b_node, name));
75 return sock.default_value();
78 static void get_tex_mapping(TextureMapping *mapping, BL::TexMapping b_mapping)
83 mapping->translation = get_float3(b_mapping.location());
84 mapping->rotation = get_float3(b_mapping.rotation());
85 mapping->scale = get_float3(b_mapping.scale());
87 mapping->x_mapping = (TextureMapping::Mapping)b_mapping.mapping_x();
88 mapping->y_mapping = (TextureMapping::Mapping)b_mapping.mapping_y();
89 mapping->z_mapping = (TextureMapping::Mapping)b_mapping.mapping_z();
92 static void get_tex_mapping(TextureMapping *mapping, BL::ShaderNodeMapping b_mapping)
97 mapping->translation = get_float3(b_mapping.location());
98 mapping->rotation = get_float3(b_mapping.rotation());
99 mapping->scale = get_float3(b_mapping.scale());
102 static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNode b_node)
104 ShaderNode *node = NULL;
106 switch(b_node.type()) {
108 case BL::ShaderNode::type_CURVE_RGB: break;
109 case BL::ShaderNode::type_CURVE_VEC: break;
110 case BL::ShaderNode::type_GEOMETRY: break;
111 case BL::ShaderNode::type_MATERIAL: break;
112 case BL::ShaderNode::type_MATERIAL_EXT: break;
113 case BL::ShaderNode::type_OUTPUT: break;
114 case BL::ShaderNode::type_SCRIPT: break;
115 case BL::ShaderNode::type_SQUEEZE: break;
116 case BL::ShaderNode::type_TEXTURE: break;
117 case BL::ShaderNode::type_VALTORGB: break;
118 /* handled outside this function */
119 case BL::ShaderNode::type_GROUP: break;
120 /* existing blender nodes */
121 case BL::ShaderNode::type_RGB: {
122 ColorNode *color = new ColorNode();
123 color->value = get_node_output_rgba(b_node, "Color");
127 case BL::ShaderNode::type_VALUE: {
128 ValueNode *value = new ValueNode();
129 value->value = get_node_output_value(b_node, "Value");
133 case BL::ShaderNode::type_CAMERA: {
134 node = new CameraNode();
137 case BL::ShaderNode::type_INVERT: {
138 node = new InvertNode();
141 case BL::ShaderNode::type_GAMMA: {
142 node = new GammaNode();
145 case BL::ShaderNode::type_MIX_RGB: {
146 BL::ShaderNodeMixRGB b_mix_node(b_node);
147 MixNode *mix = new MixNode();
148 mix->type = MixNode::type_enum[b_mix_node.blend_type()];
152 case BL::ShaderNode::type_SEPRGB: {
153 node = new SeparateRGBNode();
156 case BL::ShaderNode::type_COMBRGB: {
157 node = new CombineRGBNode();
160 case BL::ShaderNode::type_HUE_SAT: {
161 node = new HSVNode();
164 case BL::ShaderNode::type_RGBTOBW: {
165 node = new ConvertNode(SHADER_SOCKET_COLOR, SHADER_SOCKET_FLOAT);
168 case BL::ShaderNode::type_MATH: {
169 BL::ShaderNodeMath b_math_node(b_node);
170 MathNode *math = new MathNode();
171 math->type = MathNode::type_enum[b_math_node.operation()];
175 case BL::ShaderNode::type_VECT_MATH: {
176 BL::ShaderNodeVectorMath b_vector_math_node(b_node);
177 VectorMathNode *vmath = new VectorMathNode();
178 vmath->type = VectorMathNode::type_enum[b_vector_math_node.operation()];
182 case BL::ShaderNode::type_NORMAL: {
183 BL::Node::outputs_iterator out_it;
184 b_node.outputs.begin(out_it);
185 BL::NodeSocketVectorNone vec_sock(*out_it);
187 NormalNode *norm = new NormalNode();
188 norm->direction = get_float3(vec_sock.default_value());
193 case BL::ShaderNode::type_MAPPING: {
194 BL::ShaderNodeMapping b_mapping_node(b_node);
195 MappingNode *mapping = new MappingNode();
197 get_tex_mapping(&mapping->tex_mapping, b_mapping_node);
204 case BL::ShaderNode::type_OUTPUT_MATERIAL:
205 case BL::ShaderNode::type_OUTPUT_WORLD:
206 case BL::ShaderNode::type_OUTPUT_LAMP: {
207 node = graph->output();
210 case BL::ShaderNode::type_FRESNEL: {
211 node = new FresnelNode();
214 case BL::ShaderNode::type_LAYER_WEIGHT: {
215 node = new LayerWeightNode();
218 case BL::ShaderNode::type_ADD_SHADER: {
219 node = new AddClosureNode();
222 case BL::ShaderNode::type_MIX_SHADER: {
223 node = new MixClosureNode();
226 case BL::ShaderNode::type_ATTRIBUTE: {
227 BL::ShaderNodeAttribute b_attr_node(b_node);
228 AttributeNode *attr = new AttributeNode();
229 attr->attribute = b_attr_node.attribute_name();
233 case BL::ShaderNode::type_BACKGROUND: {
234 node = new BackgroundNode();
237 case BL::ShaderNode::type_HOLDOUT: {
238 node = new HoldoutNode();
241 case BL::ShaderNode::type_BSDF_DIFFUSE: {
242 node = new DiffuseBsdfNode();
245 case BL::ShaderNode::type_BSDF_GLOSSY: {
246 BL::ShaderNodeBsdfGlossy b_glossy_node(b_node);
247 GlossyBsdfNode *glossy = new GlossyBsdfNode();
249 switch(b_glossy_node.distribution()) {
250 case BL::ShaderNodeBsdfGlossy::distribution_SHARP:
251 glossy->distribution = ustring("Sharp");
253 case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN:
254 glossy->distribution = ustring("Beckmann");
256 case BL::ShaderNodeBsdfGlossy::distribution_GGX:
257 glossy->distribution = ustring("GGX");
263 case BL::ShaderNode::type_BSDF_GLASS: {
264 BL::ShaderNodeBsdfGlass b_glass_node(b_node);
265 GlassBsdfNode *glass = new GlassBsdfNode();
266 switch(b_glass_node.distribution()) {
267 case BL::ShaderNodeBsdfGlass::distribution_SHARP:
268 glass->distribution = ustring("Sharp");
270 case BL::ShaderNodeBsdfGlass::distribution_BECKMANN:
271 glass->distribution = ustring("Beckmann");
273 case BL::ShaderNodeBsdfGlass::distribution_GGX:
274 glass->distribution = ustring("GGX");
280 case BL::ShaderNode::type_BSDF_TRANSLUCENT: {
281 node = new TranslucentBsdfNode();
284 case BL::ShaderNode::type_BSDF_TRANSPARENT: {
285 node = new TransparentBsdfNode();
288 case BL::ShaderNode::type_BSDF_VELVET: {
289 node = new VelvetBsdfNode();
292 case BL::ShaderNode::type_EMISSION: {
293 node = new EmissionNode();
296 case BL::ShaderNode::type_VOLUME_ISOTROPIC: {
297 node = new IsotropicVolumeNode();
300 case BL::ShaderNode::type_VOLUME_TRANSPARENT: {
301 node = new TransparentVolumeNode();
304 case BL::ShaderNode::type_NEW_GEOMETRY: {
305 node = new GeometryNode();
308 case BL::ShaderNode::type_LIGHT_PATH: {
309 node = new LightPathNode();
312 case BL::ShaderNode::type_TEX_IMAGE: {
313 BL::ShaderNodeTexImage b_image_node(b_node);
314 BL::Image b_image(b_image_node.image());
315 ImageTextureNode *image = new ImageTextureNode();
316 /* todo: handle generated/builtin images */
318 image->filename = blender_absolute_path(b_data, b_image, b_image.filepath());
319 image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()];
320 get_tex_mapping(&image->tex_mapping, b_image_node.texture_mapping());
324 case BL::ShaderNode::type_TEX_ENVIRONMENT: {
325 BL::ShaderNodeTexEnvironment b_env_node(b_node);
326 BL::Image b_image(b_env_node.image());
327 EnvironmentTextureNode *env = new EnvironmentTextureNode();
329 env->filename = blender_absolute_path(b_data, b_image, b_image.filepath());
330 env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
331 get_tex_mapping(&env->tex_mapping, b_env_node.texture_mapping());
335 case BL::ShaderNode::type_TEX_GRADIENT: {
336 BL::ShaderNodeTexGradient b_gradient_node(b_node);
337 GradientTextureNode *gradient = new GradientTextureNode();
338 gradient->type = GradientTextureNode::type_enum[(int)b_gradient_node.gradient_type()];
339 get_tex_mapping(&gradient->tex_mapping, b_gradient_node.texture_mapping());
343 case BL::ShaderNode::type_TEX_VORONOI: {
344 BL::ShaderNodeTexVoronoi b_voronoi_node(b_node);
345 VoronoiTextureNode *voronoi = new VoronoiTextureNode();
346 voronoi->coloring = VoronoiTextureNode::coloring_enum[(int)b_voronoi_node.coloring()];
347 get_tex_mapping(&voronoi->tex_mapping, b_voronoi_node.texture_mapping());
351 case BL::ShaderNode::type_TEX_MAGIC: {
352 BL::ShaderNodeTexMagic b_magic_node(b_node);
353 MagicTextureNode *magic = new MagicTextureNode();
354 magic->depth = b_magic_node.turbulence_depth();
355 get_tex_mapping(&magic->tex_mapping, b_magic_node.texture_mapping());
359 case BL::ShaderNode::type_TEX_WAVE: {
360 BL::ShaderNodeTexWave b_wave_node(b_node);
361 WaveTextureNode *wave = new WaveTextureNode();
362 wave->type = WaveTextureNode::type_enum[(int)b_wave_node.wave_type()];
363 get_tex_mapping(&wave->tex_mapping, b_wave_node.texture_mapping());
367 case BL::ShaderNode::type_TEX_NOISE: {
368 BL::ShaderNodeTexNoise b_noise_node(b_node);
369 NoiseTextureNode *noise = new NoiseTextureNode();
370 get_tex_mapping(&noise->tex_mapping, b_noise_node.texture_mapping());
374 case BL::ShaderNode::type_TEX_MUSGRAVE: {
375 BL::ShaderNodeTexMusgrave b_musgrave_node(b_node);
376 MusgraveTextureNode *musgrave = new MusgraveTextureNode();
377 musgrave->type = MusgraveTextureNode::type_enum[(int)b_musgrave_node.musgrave_type()];
378 get_tex_mapping(&musgrave->tex_mapping, b_musgrave_node.texture_mapping());
382 case BL::ShaderNode::type_TEX_COORD: {
383 node = new TextureCoordinateNode();;
386 case BL::ShaderNode::type_TEX_SKY: {
387 BL::ShaderNodeTexSky b_sky_node(b_node);
388 SkyTextureNode *sky = new SkyTextureNode();
389 sky->sun_direction = get_float3(b_sky_node.sun_direction());
390 sky->turbidity = b_sky_node.turbidity();
391 get_tex_mapping(&sky->tex_mapping, b_sky_node.texture_mapping());
397 if(node && node != graph->output())
403 static SocketPair node_socket_map_pair(PtrNodeMap& node_map, BL::Node b_node, BL::NodeSocket b_socket)
405 BL::Node::inputs_iterator b_input;
406 BL::Node::outputs_iterator b_output;
407 string name = b_socket.name();
409 int counter = 0, total = 0;
412 for(b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
413 if(b_input->name() == name) {
419 if(b_input->ptr.data == b_socket.ptr.data)
424 /* find in outputs */
429 for(b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
430 if(b_output->name() == name) {
436 if(b_output->ptr.data == b_socket.ptr.data)
441 /* rename if needed */
446 name = string_printf("%s%d", name.c_str(), counter);
448 return SocketPair(node_map[b_node.ptr.data], name);
451 static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type)
454 case BL::NodeSocket::type_VALUE:
455 return SHADER_SOCKET_FLOAT;
456 case BL::NodeSocket::type_VECTOR:
457 return SHADER_SOCKET_VECTOR;
458 case BL::NodeSocket::type_RGBA:
459 return SHADER_SOCKET_COLOR;
460 case BL::NodeSocket::type_SHADER:
461 return SHADER_SOCKET_CLOSURE;
463 case BL::NodeSocket::type_BOOLEAN:
464 case BL::NodeSocket::type_MESH:
465 case BL::NodeSocket::type_INT:
467 return SHADER_SOCKET_FLOAT;
471 static void set_default_value(ShaderInput *input, BL::NodeSocket sock)
473 /* copy values for non linked inputs */
474 switch(input->type) {
475 case SHADER_SOCKET_FLOAT: {
476 BL::NodeSocketFloatNone value_sock(sock);
477 input->set(value_sock.default_value());
480 case SHADER_SOCKET_COLOR: {
481 BL::NodeSocketRGBA rgba_sock(sock);
482 input->set(get_float3(rgba_sock.default_value()));
485 case SHADER_SOCKET_NORMAL:
486 case SHADER_SOCKET_POINT:
487 case SHADER_SOCKET_VECTOR: {
488 BL::NodeSocketVectorNone vec_sock(sock);
489 input->set(get_float3(vec_sock.default_value()));
492 case SHADER_SOCKET_CLOSURE:
497 static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map)
500 BL::ShaderNodeTree::nodes_iterator b_node;
502 PtrSockMap proxy_map;
504 for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
505 if(b_node->is_a(&RNA_NodeGroup)) {
506 /* add proxy converter nodes for inputs and outputs */
507 BL::NodeGroup b_gnode(*b_node);
508 BL::ShaderNodeTree b_group_ntree(b_gnode.node_tree());
509 BL::Node::inputs_iterator b_input;
510 BL::Node::outputs_iterator b_output;
512 PtrSockMap group_sockmap;
514 for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
515 ShaderSocketType extern_type = convert_socket_type(b_input->type());
516 ShaderSocketType intern_type = convert_socket_type(b_input->group_socket().type());
517 ShaderNode *proxy = graph->add(new ProxyNode(extern_type, intern_type));
519 /* map the external node socket to the proxy node socket */
520 proxy_map[b_input->ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
521 /* map the internal group socket to the proxy node socket */
522 group_sockmap[b_input->group_socket().ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
524 /* default input values of the group node */
525 set_default_value(proxy->inputs[0], *b_input);
528 for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
529 ShaderSocketType extern_type = convert_socket_type(b_output->type());
530 ShaderSocketType intern_type = convert_socket_type(b_output->group_socket().type());
531 ShaderNode *proxy = graph->add(new ProxyNode(intern_type, extern_type));
533 /* map the external node socket to the proxy node socket */
534 proxy_map[b_output->ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
535 /* map the internal group socket to the proxy node socket */
536 group_sockmap[b_output->group_socket().ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
538 /* default input values of internal, unlinked group outputs */
539 set_default_value(proxy->inputs[0], b_output->group_socket());
542 add_nodes(b_data, graph, b_group_ntree, group_sockmap);
545 ShaderNode *node = add_node(b_data, graph, BL::ShaderNode(*b_node));
548 BL::Node::inputs_iterator b_input;
550 node_map[b_node->ptr.data] = node;
552 for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
553 SocketPair pair = node_socket_map_pair(node_map, *b_node, *b_input);
554 ShaderInput *input = pair.first->input(pair.second.c_str());
558 /* copy values for non linked inputs */
559 set_default_value(input, *b_input);
566 BL::NodeTree::links_iterator b_link;
568 for(b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
569 /* get blender link data */
570 BL::Node b_from_node = b_link->from_node();
571 BL::Node b_to_node = b_link->to_node();
573 BL::NodeSocket b_from_sock = b_link->from_socket();
574 BL::NodeSocket b_to_sock = b_link->to_socket();
576 SocketPair from_pair, to_pair;
578 /* links without a node pointer are connections to group inputs/outputs */
582 if (b_from_node.is_a(&RNA_NodeGroup))
583 from_pair = proxy_map[b_from_sock.ptr.data];
585 from_pair = node_socket_map_pair(node_map, b_from_node, b_from_sock);
588 from_pair = sockets_map[b_from_sock.ptr.data];
592 if (b_to_node.is_a(&RNA_NodeGroup))
593 to_pair = proxy_map[b_to_sock.ptr.data];
595 to_pair = node_socket_map_pair(node_map, b_to_node, b_to_sock);
598 to_pair = sockets_map[b_to_sock.ptr.data];
600 /* either node may be NULL when the node was not exported, typically
601 because the node type is not supported */
602 if(from_pair.first && to_pair.first) {
603 ShaderOutput *output = from_pair.first->output(from_pair.second.c_str());
604 ShaderInput *input = to_pair.first->input(to_pair.second.c_str());
606 graph->connect(output, input);
613 void BlenderSync::sync_materials()
615 shader_map.set_default(scene->shaders[scene->default_surface]);
618 BL::BlendData::materials_iterator b_mat;
620 for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat) {
623 /* test if we need to sync */
624 if(shader_map.sync(&shader, *b_mat)) {
625 ShaderGraph *graph = new ShaderGraph();
627 shader->name = b_mat->name().c_str();
630 if(b_mat->use_nodes() && b_mat->node_tree()) {
631 PtrSockMap sock_to_node;
632 BL::ShaderNodeTree b_ntree(b_mat->node_tree());
634 add_nodes(b_data, graph, b_ntree, sock_to_node);
637 ShaderNode *closure, *out;
639 closure = graph->add(new DiffuseBsdfNode());
640 closure->input("Color")->value = get_float3(b_mat->diffuse_color());
641 out = graph->output();
643 graph->connect(closure->output("BSDF"), out->input("Surface"));
647 PointerRNA cmat = RNA_pointer_get(&b_mat->ptr, "cycles");
648 shader->sample_as_light = get_boolean(cmat, "sample_as_light");
649 shader->homogeneous_volume = get_boolean(cmat, "homogeneous_volume");
651 shader->set_graph(graph);
652 shader->tag_update(scene);
659 void BlenderSync::sync_world()
661 Background *background = scene->background;
662 Background prevbackground = *background;
664 BL::World b_world = b_scene.world();
666 if(world_recalc || b_world.ptr.data != world_map) {
667 Shader *shader = scene->shaders[scene->default_background];
668 ShaderGraph *graph = new ShaderGraph();
671 if(b_world && b_world.use_nodes() && b_world.node_tree()) {
672 PtrSockMap sock_to_node;
673 BL::ShaderNodeTree b_ntree(b_world.node_tree());
675 add_nodes(b_data, graph, b_ntree, sock_to_node);
678 ShaderNode *closure, *out;
680 closure = graph->add(new BackgroundNode());
681 closure->input("Color")->value = get_float3(b_world.horizon_color());
682 out = graph->output();
684 graph->connect(closure->output("Background"), out->input("Surface"));
687 shader->set_graph(graph);
688 shader->tag_update(scene);
691 PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
692 background->transparent = get_boolean(cscene, "film_transparent");
694 if(background->modified(prevbackground))
695 background->tag_update(scene);
697 world_map = b_world.ptr.data;
698 world_recalc = false;
703 void BlenderSync::sync_lamps()
705 shader_map.set_default(scene->shaders[scene->default_light]);
708 BL::BlendData::lamps_iterator b_lamp;
710 for(b_data.lamps.begin(b_lamp); b_lamp != b_data.lamps.end(); ++b_lamp) {
713 /* test if we need to sync */
714 if(shader_map.sync(&shader, *b_lamp)) {
715 ShaderGraph *graph = new ShaderGraph();
718 if(b_lamp->use_nodes() && b_lamp->node_tree()) {
719 shader->name = b_lamp->name().c_str();
721 PtrSockMap sock_to_node;
722 BL::ShaderNodeTree b_ntree(b_lamp->node_tree());
724 add_nodes(b_data, graph, b_ntree, sock_to_node);
727 ShaderNode *closure, *out;
728 float strength = 1.0f;
730 if(b_lamp->type() == BL::Lamp::type_POINT ||
731 b_lamp->type() == BL::Lamp::type_SPOT ||
732 b_lamp->type() == BL::Lamp::type_AREA)
735 closure = graph->add(new EmissionNode());
736 closure->input("Color")->value = get_float3(b_lamp->color());
737 closure->input("Strength")->value.x = strength;
738 out = graph->output();
740 graph->connect(closure->output("Emission"), out->input("Surface"));
743 shader->set_graph(graph);
744 shader->tag_update(scene);
749 void BlenderSync::sync_shaders()
751 shader_map.pre_sync();
757 /* false = don't delete unused shaders, not supported */
758 shader_map.post_sync(false);