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_BRIGHTCONTRAST: {
146 node = new BrightContrastNode();
149 case BL::ShaderNode::type_MIX_RGB: {
150 BL::ShaderNodeMixRGB b_mix_node(b_node);
151 MixNode *mix = new MixNode();
152 mix->type = MixNode::type_enum[b_mix_node.blend_type()];
156 case BL::ShaderNode::type_SEPRGB: {
157 node = new SeparateRGBNode();
160 case BL::ShaderNode::type_COMBRGB: {
161 node = new CombineRGBNode();
164 case BL::ShaderNode::type_HUE_SAT: {
165 node = new HSVNode();
168 case BL::ShaderNode::type_RGBTOBW: {
169 node = new ConvertNode(SHADER_SOCKET_COLOR, SHADER_SOCKET_FLOAT);
172 case BL::ShaderNode::type_MATH: {
173 BL::ShaderNodeMath b_math_node(b_node);
174 MathNode *math = new MathNode();
175 math->type = MathNode::type_enum[b_math_node.operation()];
179 case BL::ShaderNode::type_VECT_MATH: {
180 BL::ShaderNodeVectorMath b_vector_math_node(b_node);
181 VectorMathNode *vmath = new VectorMathNode();
182 vmath->type = VectorMathNode::type_enum[b_vector_math_node.operation()];
186 case BL::ShaderNode::type_NORMAL: {
187 BL::Node::outputs_iterator out_it;
188 b_node.outputs.begin(out_it);
189 BL::NodeSocketVectorNone vec_sock(*out_it);
191 NormalNode *norm = new NormalNode();
192 norm->direction = get_float3(vec_sock.default_value());
197 case BL::ShaderNode::type_MAPPING: {
198 BL::ShaderNodeMapping b_mapping_node(b_node);
199 MappingNode *mapping = new MappingNode();
201 get_tex_mapping(&mapping->tex_mapping, b_mapping_node);
208 case BL::ShaderNode::type_OUTPUT_MATERIAL:
209 case BL::ShaderNode::type_OUTPUT_WORLD:
210 case BL::ShaderNode::type_OUTPUT_LAMP: {
211 node = graph->output();
214 case BL::ShaderNode::type_FRESNEL: {
215 node = new FresnelNode();
218 case BL::ShaderNode::type_LAYER_WEIGHT: {
219 node = new LayerWeightNode();
222 case BL::ShaderNode::type_ADD_SHADER: {
223 node = new AddClosureNode();
226 case BL::ShaderNode::type_MIX_SHADER: {
227 node = new MixClosureNode();
230 case BL::ShaderNode::type_ATTRIBUTE: {
231 BL::ShaderNodeAttribute b_attr_node(b_node);
232 AttributeNode *attr = new AttributeNode();
233 attr->attribute = b_attr_node.attribute_name();
237 case BL::ShaderNode::type_BACKGROUND: {
238 node = new BackgroundNode();
241 case BL::ShaderNode::type_HOLDOUT: {
242 node = new HoldoutNode();
245 case BL::ShaderNode::type_BSDF_DIFFUSE: {
246 node = new DiffuseBsdfNode();
249 case BL::ShaderNode::type_BSDF_GLOSSY: {
250 BL::ShaderNodeBsdfGlossy b_glossy_node(b_node);
251 GlossyBsdfNode *glossy = new GlossyBsdfNode();
253 switch(b_glossy_node.distribution()) {
254 case BL::ShaderNodeBsdfGlossy::distribution_SHARP:
255 glossy->distribution = ustring("Sharp");
257 case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN:
258 glossy->distribution = ustring("Beckmann");
260 case BL::ShaderNodeBsdfGlossy::distribution_GGX:
261 glossy->distribution = ustring("GGX");
267 case BL::ShaderNode::type_BSDF_GLASS: {
268 BL::ShaderNodeBsdfGlass b_glass_node(b_node);
269 GlassBsdfNode *glass = new GlassBsdfNode();
270 switch(b_glass_node.distribution()) {
271 case BL::ShaderNodeBsdfGlass::distribution_SHARP:
272 glass->distribution = ustring("Sharp");
274 case BL::ShaderNodeBsdfGlass::distribution_BECKMANN:
275 glass->distribution = ustring("Beckmann");
277 case BL::ShaderNodeBsdfGlass::distribution_GGX:
278 glass->distribution = ustring("GGX");
284 case BL::ShaderNode::type_BSDF_TRANSLUCENT: {
285 node = new TranslucentBsdfNode();
288 case BL::ShaderNode::type_BSDF_TRANSPARENT: {
289 node = new TransparentBsdfNode();
292 case BL::ShaderNode::type_BSDF_VELVET: {
293 node = new VelvetBsdfNode();
296 case BL::ShaderNode::type_EMISSION: {
297 node = new EmissionNode();
300 case BL::ShaderNode::type_VOLUME_ISOTROPIC: {
301 node = new IsotropicVolumeNode();
304 case BL::ShaderNode::type_VOLUME_TRANSPARENT: {
305 node = new TransparentVolumeNode();
308 case BL::ShaderNode::type_NEW_GEOMETRY: {
309 node = new GeometryNode();
312 case BL::ShaderNode::type_LIGHT_PATH: {
313 node = new LightPathNode();
316 case BL::ShaderNode::type_TEX_IMAGE: {
317 BL::ShaderNodeTexImage b_image_node(b_node);
318 BL::Image b_image(b_image_node.image());
319 ImageTextureNode *image = new ImageTextureNode();
320 /* todo: handle generated/builtin images */
322 image->filename = blender_absolute_path(b_data, b_image, b_image.filepath());
323 image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()];
324 get_tex_mapping(&image->tex_mapping, b_image_node.texture_mapping());
328 case BL::ShaderNode::type_TEX_ENVIRONMENT: {
329 BL::ShaderNodeTexEnvironment b_env_node(b_node);
330 BL::Image b_image(b_env_node.image());
331 EnvironmentTextureNode *env = new EnvironmentTextureNode();
333 env->filename = blender_absolute_path(b_data, b_image, b_image.filepath());
334 env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
335 get_tex_mapping(&env->tex_mapping, b_env_node.texture_mapping());
339 case BL::ShaderNode::type_TEX_GRADIENT: {
340 BL::ShaderNodeTexGradient b_gradient_node(b_node);
341 GradientTextureNode *gradient = new GradientTextureNode();
342 gradient->type = GradientTextureNode::type_enum[(int)b_gradient_node.gradient_type()];
343 get_tex_mapping(&gradient->tex_mapping, b_gradient_node.texture_mapping());
347 case BL::ShaderNode::type_TEX_VORONOI: {
348 BL::ShaderNodeTexVoronoi b_voronoi_node(b_node);
349 VoronoiTextureNode *voronoi = new VoronoiTextureNode();
350 voronoi->coloring = VoronoiTextureNode::coloring_enum[(int)b_voronoi_node.coloring()];
351 get_tex_mapping(&voronoi->tex_mapping, b_voronoi_node.texture_mapping());
355 case BL::ShaderNode::type_TEX_MAGIC: {
356 BL::ShaderNodeTexMagic b_magic_node(b_node);
357 MagicTextureNode *magic = new MagicTextureNode();
358 magic->depth = b_magic_node.turbulence_depth();
359 get_tex_mapping(&magic->tex_mapping, b_magic_node.texture_mapping());
363 case BL::ShaderNode::type_TEX_WAVE: {
364 BL::ShaderNodeTexWave b_wave_node(b_node);
365 WaveTextureNode *wave = new WaveTextureNode();
366 wave->type = WaveTextureNode::type_enum[(int)b_wave_node.wave_type()];
367 get_tex_mapping(&wave->tex_mapping, b_wave_node.texture_mapping());
371 case BL::ShaderNode::type_TEX_CHECKER: {
372 BL::ShaderNodeTexChecker b_checker_node(b_node);
373 CheckerTextureNode *checker = new CheckerTextureNode();
374 get_tex_mapping(&checker->tex_mapping, b_checker_node.texture_mapping());
378 case BL::ShaderNode::type_TEX_NOISE: {
379 BL::ShaderNodeTexNoise b_noise_node(b_node);
380 NoiseTextureNode *noise = new NoiseTextureNode();
381 get_tex_mapping(&noise->tex_mapping, b_noise_node.texture_mapping());
385 case BL::ShaderNode::type_TEX_MUSGRAVE: {
386 BL::ShaderNodeTexMusgrave b_musgrave_node(b_node);
387 MusgraveTextureNode *musgrave = new MusgraveTextureNode();
388 musgrave->type = MusgraveTextureNode::type_enum[(int)b_musgrave_node.musgrave_type()];
389 get_tex_mapping(&musgrave->tex_mapping, b_musgrave_node.texture_mapping());
393 case BL::ShaderNode::type_TEX_COORD: {
394 node = new TextureCoordinateNode();;
397 case BL::ShaderNode::type_TEX_SKY: {
398 BL::ShaderNodeTexSky b_sky_node(b_node);
399 SkyTextureNode *sky = new SkyTextureNode();
400 sky->sun_direction = get_float3(b_sky_node.sun_direction());
401 sky->turbidity = b_sky_node.turbidity();
402 get_tex_mapping(&sky->tex_mapping, b_sky_node.texture_mapping());
408 if(node && node != graph->output())
414 static SocketPair node_socket_map_pair(PtrNodeMap& node_map, BL::Node b_node, BL::NodeSocket b_socket)
416 BL::Node::inputs_iterator b_input;
417 BL::Node::outputs_iterator b_output;
418 string name = b_socket.name();
420 int counter = 0, total = 0;
423 for(b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
424 if(b_input->name() == name) {
430 if(b_input->ptr.data == b_socket.ptr.data)
435 /* find in outputs */
440 for(b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
441 if(b_output->name() == name) {
447 if(b_output->ptr.data == b_socket.ptr.data)
452 /* rename if needed */
457 name = string_printf("%s%d", name.c_str(), counter);
459 return SocketPair(node_map[b_node.ptr.data], name);
462 static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type)
465 case BL::NodeSocket::type_VALUE:
466 return SHADER_SOCKET_FLOAT;
467 case BL::NodeSocket::type_VECTOR:
468 return SHADER_SOCKET_VECTOR;
469 case BL::NodeSocket::type_RGBA:
470 return SHADER_SOCKET_COLOR;
471 case BL::NodeSocket::type_SHADER:
472 return SHADER_SOCKET_CLOSURE;
474 case BL::NodeSocket::type_BOOLEAN:
475 case BL::NodeSocket::type_MESH:
476 case BL::NodeSocket::type_INT:
478 return SHADER_SOCKET_FLOAT;
482 static void set_default_value(ShaderInput *input, BL::NodeSocket sock)
484 /* copy values for non linked inputs */
485 switch(input->type) {
486 case SHADER_SOCKET_FLOAT: {
487 BL::NodeSocketFloatNone value_sock(sock);
488 input->set(value_sock.default_value());
491 case SHADER_SOCKET_COLOR: {
492 BL::NodeSocketRGBA rgba_sock(sock);
493 input->set(get_float3(rgba_sock.default_value()));
496 case SHADER_SOCKET_NORMAL:
497 case SHADER_SOCKET_POINT:
498 case SHADER_SOCKET_VECTOR: {
499 BL::NodeSocketVectorNone vec_sock(sock);
500 input->set(get_float3(vec_sock.default_value()));
503 case SHADER_SOCKET_CLOSURE:
508 static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map)
511 BL::ShaderNodeTree::nodes_iterator b_node;
513 PtrSockMap proxy_map;
515 for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
516 if(b_node->is_a(&RNA_NodeGroup)) {
517 /* add proxy converter nodes for inputs and outputs */
518 BL::NodeGroup b_gnode(*b_node);
519 BL::ShaderNodeTree b_group_ntree(b_gnode.node_tree());
520 BL::Node::inputs_iterator b_input;
521 BL::Node::outputs_iterator b_output;
523 PtrSockMap group_sockmap;
525 for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
526 ShaderSocketType extern_type = convert_socket_type(b_input->type());
527 ShaderSocketType intern_type = convert_socket_type(b_input->group_socket().type());
528 ShaderNode *proxy = graph->add(new ProxyNode(extern_type, intern_type));
530 /* map the external node socket to the proxy node socket */
531 proxy_map[b_input->ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
532 /* map the internal group socket to the proxy node socket */
533 group_sockmap[b_input->group_socket().ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
535 /* default input values of the group node */
536 set_default_value(proxy->inputs[0], *b_input);
539 for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
540 ShaderSocketType extern_type = convert_socket_type(b_output->type());
541 ShaderSocketType intern_type = convert_socket_type(b_output->group_socket().type());
542 ShaderNode *proxy = graph->add(new ProxyNode(intern_type, extern_type));
544 /* map the external node socket to the proxy node socket */
545 proxy_map[b_output->ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
546 /* map the internal group socket to the proxy node socket */
547 group_sockmap[b_output->group_socket().ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
549 /* default input values of internal, unlinked group outputs */
550 set_default_value(proxy->inputs[0], b_output->group_socket());
553 add_nodes(b_data, graph, b_group_ntree, group_sockmap);
556 ShaderNode *node = add_node(b_data, graph, BL::ShaderNode(*b_node));
559 BL::Node::inputs_iterator b_input;
561 node_map[b_node->ptr.data] = node;
563 for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
564 SocketPair pair = node_socket_map_pair(node_map, *b_node, *b_input);
565 ShaderInput *input = pair.first->input(pair.second.c_str());
569 /* copy values for non linked inputs */
570 set_default_value(input, *b_input);
577 BL::NodeTree::links_iterator b_link;
579 for(b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
580 /* get blender link data */
581 BL::Node b_from_node = b_link->from_node();
582 BL::Node b_to_node = b_link->to_node();
584 BL::NodeSocket b_from_sock = b_link->from_socket();
585 BL::NodeSocket b_to_sock = b_link->to_socket();
587 SocketPair from_pair, to_pair;
589 /* links without a node pointer are connections to group inputs/outputs */
593 if (b_from_node.is_a(&RNA_NodeGroup))
594 from_pair = proxy_map[b_from_sock.ptr.data];
596 from_pair = node_socket_map_pair(node_map, b_from_node, b_from_sock);
599 from_pair = sockets_map[b_from_sock.ptr.data];
603 if (b_to_node.is_a(&RNA_NodeGroup))
604 to_pair = proxy_map[b_to_sock.ptr.data];
606 to_pair = node_socket_map_pair(node_map, b_to_node, b_to_sock);
609 to_pair = sockets_map[b_to_sock.ptr.data];
611 /* either node may be NULL when the node was not exported, typically
612 because the node type is not supported */
613 if(from_pair.first && to_pair.first) {
614 ShaderOutput *output = from_pair.first->output(from_pair.second.c_str());
615 ShaderInput *input = to_pair.first->input(to_pair.second.c_str());
617 graph->connect(output, input);
624 void BlenderSync::sync_materials()
626 shader_map.set_default(scene->shaders[scene->default_surface]);
629 BL::BlendData::materials_iterator b_mat;
631 for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat) {
634 /* test if we need to sync */
635 if(shader_map.sync(&shader, *b_mat)) {
636 ShaderGraph *graph = new ShaderGraph();
638 shader->name = b_mat->name().c_str();
639 shader->pass_id = b_mat->pass_index();
642 if(b_mat->use_nodes() && b_mat->node_tree()) {
643 PtrSockMap sock_to_node;
644 BL::ShaderNodeTree b_ntree(b_mat->node_tree());
646 add_nodes(b_data, graph, b_ntree, sock_to_node);
649 ShaderNode *closure, *out;
651 closure = graph->add(new DiffuseBsdfNode());
652 closure->input("Color")->value = get_float3(b_mat->diffuse_color());
653 out = graph->output();
655 graph->connect(closure->output("BSDF"), out->input("Surface"));
659 PointerRNA cmat = RNA_pointer_get(&b_mat->ptr, "cycles");
660 shader->sample_as_light = get_boolean(cmat, "sample_as_light");
661 shader->homogeneous_volume = get_boolean(cmat, "homogeneous_volume");
663 shader->set_graph(graph);
664 shader->tag_update(scene);
671 void BlenderSync::sync_world()
673 Background *background = scene->background;
674 Background prevbackground = *background;
676 BL::World b_world = b_scene.world();
678 if(world_recalc || b_world.ptr.data != world_map) {
679 Shader *shader = scene->shaders[scene->default_background];
680 ShaderGraph *graph = new ShaderGraph();
683 if(b_world && b_world.use_nodes() && b_world.node_tree()) {
684 PtrSockMap sock_to_node;
685 BL::ShaderNodeTree b_ntree(b_world.node_tree());
687 add_nodes(b_data, graph, b_ntree, sock_to_node);
690 ShaderNode *closure, *out;
692 closure = graph->add(new BackgroundNode());
693 closure->input("Color")->value = get_float3(b_world.horizon_color());
694 out = graph->output();
696 graph->connect(closure->output("Background"), out->input("Surface"));
701 BL::WorldLighting b_light = b_world.light_settings();
703 if(b_light.use_ambient_occlusion()) {
704 background->ao_factor = b_light.ao_factor();
705 background->ao_distance = b_light.distance();
708 background->ao_factor = 0.0f;
709 background->ao_distance = 0.0f;
713 shader->set_graph(graph);
714 shader->tag_update(scene);
717 PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
718 background->transparent = get_boolean(cscene, "film_transparent");
720 if(background->modified(prevbackground))
721 background->tag_update(scene);
726 void BlenderSync::sync_lamps()
728 shader_map.set_default(scene->shaders[scene->default_light]);
731 BL::BlendData::lamps_iterator b_lamp;
733 for(b_data.lamps.begin(b_lamp); b_lamp != b_data.lamps.end(); ++b_lamp) {
736 /* test if we need to sync */
737 if(shader_map.sync(&shader, *b_lamp)) {
738 ShaderGraph *graph = new ShaderGraph();
741 if(b_lamp->use_nodes() && b_lamp->node_tree()) {
742 shader->name = b_lamp->name().c_str();
744 PtrSockMap sock_to_node;
745 BL::ShaderNodeTree b_ntree(b_lamp->node_tree());
747 add_nodes(b_data, graph, b_ntree, sock_to_node);
750 ShaderNode *closure, *out;
751 float strength = 1.0f;
753 if(b_lamp->type() == BL::Lamp::type_POINT ||
754 b_lamp->type() == BL::Lamp::type_SPOT ||
755 b_lamp->type() == BL::Lamp::type_AREA)
758 closure = graph->add(new EmissionNode());
759 closure->input("Color")->value = get_float3(b_lamp->color());
760 closure->input("Strength")->value.x = strength;
761 out = graph->output();
763 graph->connect(closure->output("Emission"), out->input("Surface"));
766 shader->set_graph(graph);
767 shader->tag_update(scene);
772 void BlenderSync::sync_shaders()
774 shader_map.pre_sync();
780 /* false = don't delete unused shaders, not supported */
781 shader_map.post_sync(false);