Blender V2.61 - r43446
|
00001 /* 00002 * Copyright 2011, Blender Foundation. 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "background.h" 00020 #include "graph.h" 00021 #include "light.h" 00022 #include "nodes.h" 00023 #include "scene.h" 00024 #include "shader.h" 00025 00026 #include "blender_sync.h" 00027 #include "blender_util.h" 00028 00029 #include "util_debug.h" 00030 00031 CCL_NAMESPACE_BEGIN 00032 00033 typedef map<void*, ShaderNode*> PtrNodeMap; 00034 typedef pair<ShaderNode*, std::string> SocketPair; 00035 typedef map<void*, SocketPair> PtrSockMap; 00036 00037 /* Find */ 00038 00039 void BlenderSync::find_shader(BL::ID id, vector<uint>& used_shaders, int default_shader) 00040 { 00041 Shader *shader = (id)? shader_map.find(id): scene->shaders[default_shader]; 00042 00043 for(size_t i = 0; i < scene->shaders.size(); i++) { 00044 if(scene->shaders[i] == shader) { 00045 used_shaders.push_back(i); 00046 break; 00047 } 00048 } 00049 } 00050 00051 /* Graph */ 00052 00053 static BL::NodeSocket get_node_output(BL::Node b_node, const string& name) 00054 { 00055 BL::Node::outputs_iterator b_out; 00056 00057 for(b_node.outputs.begin(b_out); b_out != b_node.outputs.end(); ++b_out) 00058 if(b_out->name() == name) 00059 return *b_out; 00060 00061 assert(0); 00062 00063 return *b_out; 00064 } 00065 00066 static float3 get_node_output_rgba(BL::Node b_node, const string& name) 00067 { 00068 BL::NodeSocketRGBA sock(get_node_output(b_node, name)); 00069 return get_float3(sock.default_value()); 00070 } 00071 00072 static float get_node_output_value(BL::Node b_node, const string& name) 00073 { 00074 BL::NodeSocketFloatNone sock(get_node_output(b_node, name)); 00075 return sock.default_value(); 00076 } 00077 00078 static void get_tex_mapping(TextureMapping *mapping, BL::TexMapping b_mapping) 00079 { 00080 if(!b_mapping) 00081 return; 00082 00083 mapping->translation = get_float3(b_mapping.location()); 00084 mapping->rotation = get_float3(b_mapping.rotation()); 00085 mapping->scale = get_float3(b_mapping.scale()); 00086 00087 mapping->x_mapping = (TextureMapping::Mapping)b_mapping.mapping_x(); 00088 mapping->y_mapping = (TextureMapping::Mapping)b_mapping.mapping_y(); 00089 mapping->z_mapping = (TextureMapping::Mapping)b_mapping.mapping_z(); 00090 } 00091 00092 static void get_tex_mapping(TextureMapping *mapping, BL::ShaderNodeMapping b_mapping) 00093 { 00094 if(!b_mapping) 00095 return; 00096 00097 mapping->translation = get_float3(b_mapping.location()); 00098 mapping->rotation = get_float3(b_mapping.rotation()); 00099 mapping->scale = get_float3(b_mapping.scale()); 00100 } 00101 00102 static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNode b_node) 00103 { 00104 ShaderNode *node = NULL; 00105 00106 switch(b_node.type()) { 00107 /* not supported */ 00108 case BL::ShaderNode::type_CURVE_RGB: break; 00109 case BL::ShaderNode::type_CURVE_VEC: break; 00110 case BL::ShaderNode::type_GEOMETRY: break; 00111 case BL::ShaderNode::type_MATERIAL: break; 00112 case BL::ShaderNode::type_MATERIAL_EXT: break; 00113 case BL::ShaderNode::type_OUTPUT: break; 00114 case BL::ShaderNode::type_SCRIPT: break; 00115 case BL::ShaderNode::type_SQUEEZE: break; 00116 case BL::ShaderNode::type_TEXTURE: break; 00117 case BL::ShaderNode::type_VALTORGB: break; 00118 /* handled outside this function */ 00119 case BL::ShaderNode::type_GROUP: break; 00120 /* existing blender nodes */ 00121 case BL::ShaderNode::type_RGB: { 00122 ColorNode *color = new ColorNode(); 00123 color->value = get_node_output_rgba(b_node, "Color"); 00124 node = color; 00125 break; 00126 } 00127 case BL::ShaderNode::type_VALUE: { 00128 ValueNode *value = new ValueNode(); 00129 value->value = get_node_output_value(b_node, "Value"); 00130 node = value; 00131 break; 00132 } 00133 case BL::ShaderNode::type_CAMERA: { 00134 node = new CameraNode(); 00135 break; 00136 } 00137 case BL::ShaderNode::type_INVERT: { 00138 node = new InvertNode(); 00139 break; 00140 } 00141 case BL::ShaderNode::type_GAMMA: { 00142 node = new GammaNode(); 00143 break; 00144 } 00145 case BL::ShaderNode::type_MIX_RGB: { 00146 BL::ShaderNodeMixRGB b_mix_node(b_node); 00147 MixNode *mix = new MixNode(); 00148 mix->type = MixNode::type_enum[b_mix_node.blend_type()]; 00149 node = mix; 00150 break; 00151 } 00152 case BL::ShaderNode::type_SEPRGB: { 00153 node = new SeparateRGBNode(); 00154 break; 00155 } 00156 case BL::ShaderNode::type_COMBRGB: { 00157 node = new CombineRGBNode(); 00158 break; 00159 } 00160 case BL::ShaderNode::type_HUE_SAT: { 00161 node = new HSVNode(); 00162 break; 00163 } 00164 case BL::ShaderNode::type_RGBTOBW: { 00165 node = new ConvertNode(SHADER_SOCKET_COLOR, SHADER_SOCKET_FLOAT); 00166 break; 00167 } 00168 case BL::ShaderNode::type_MATH: { 00169 BL::ShaderNodeMath b_math_node(b_node); 00170 MathNode *math = new MathNode(); 00171 math->type = MathNode::type_enum[b_math_node.operation()]; 00172 node = math; 00173 break; 00174 } 00175 case BL::ShaderNode::type_VECT_MATH: { 00176 BL::ShaderNodeVectorMath b_vector_math_node(b_node); 00177 VectorMathNode *vmath = new VectorMathNode(); 00178 vmath->type = VectorMathNode::type_enum[b_vector_math_node.operation()]; 00179 node = vmath; 00180 break; 00181 } 00182 case BL::ShaderNode::type_NORMAL: { 00183 BL::Node::outputs_iterator out_it; 00184 b_node.outputs.begin(out_it); 00185 BL::NodeSocketVectorNone vec_sock(*out_it); 00186 00187 NormalNode *norm = new NormalNode(); 00188 norm->direction = get_float3(vec_sock.default_value()); 00189 00190 node = norm; 00191 break; 00192 } 00193 case BL::ShaderNode::type_MAPPING: { 00194 BL::ShaderNodeMapping b_mapping_node(b_node); 00195 MappingNode *mapping = new MappingNode(); 00196 00197 get_tex_mapping(&mapping->tex_mapping, b_mapping_node); 00198 00199 node = mapping; 00200 break; 00201 } 00202 00203 /* new nodes */ 00204 case BL::ShaderNode::type_OUTPUT_MATERIAL: 00205 case BL::ShaderNode::type_OUTPUT_WORLD: 00206 case BL::ShaderNode::type_OUTPUT_LAMP: { 00207 node = graph->output(); 00208 break; 00209 } 00210 case BL::ShaderNode::type_FRESNEL: { 00211 node = new FresnelNode(); 00212 break; 00213 } 00214 case BL::ShaderNode::type_LAYER_WEIGHT: { 00215 node = new LayerWeightNode(); 00216 break; 00217 } 00218 case BL::ShaderNode::type_ADD_SHADER: { 00219 node = new AddClosureNode(); 00220 break; 00221 } 00222 case BL::ShaderNode::type_MIX_SHADER: { 00223 node = new MixClosureNode(); 00224 break; 00225 } 00226 case BL::ShaderNode::type_ATTRIBUTE: { 00227 BL::ShaderNodeAttribute b_attr_node(b_node); 00228 AttributeNode *attr = new AttributeNode(); 00229 attr->attribute = b_attr_node.attribute_name(); 00230 node = attr; 00231 break; 00232 } 00233 case BL::ShaderNode::type_BACKGROUND: { 00234 node = new BackgroundNode(); 00235 break; 00236 } 00237 case BL::ShaderNode::type_HOLDOUT: { 00238 node = new HoldoutNode(); 00239 break; 00240 } 00241 case BL::ShaderNode::type_BSDF_DIFFUSE: { 00242 node = new DiffuseBsdfNode(); 00243 break; 00244 } 00245 case BL::ShaderNode::type_BSDF_GLOSSY: { 00246 BL::ShaderNodeBsdfGlossy b_glossy_node(b_node); 00247 GlossyBsdfNode *glossy = new GlossyBsdfNode(); 00248 00249 switch(b_glossy_node.distribution()) { 00250 case BL::ShaderNodeBsdfGlossy::distribution_SHARP: 00251 glossy->distribution = ustring("Sharp"); 00252 break; 00253 case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN: 00254 glossy->distribution = ustring("Beckmann"); 00255 break; 00256 case BL::ShaderNodeBsdfGlossy::distribution_GGX: 00257 glossy->distribution = ustring("GGX"); 00258 break; 00259 } 00260 node = glossy; 00261 break; 00262 } 00263 case BL::ShaderNode::type_BSDF_GLASS: { 00264 BL::ShaderNodeBsdfGlass b_glass_node(b_node); 00265 GlassBsdfNode *glass = new GlassBsdfNode(); 00266 switch(b_glass_node.distribution()) { 00267 case BL::ShaderNodeBsdfGlass::distribution_SHARP: 00268 glass->distribution = ustring("Sharp"); 00269 break; 00270 case BL::ShaderNodeBsdfGlass::distribution_BECKMANN: 00271 glass->distribution = ustring("Beckmann"); 00272 break; 00273 case BL::ShaderNodeBsdfGlass::distribution_GGX: 00274 glass->distribution = ustring("GGX"); 00275 break; 00276 } 00277 node = glass; 00278 break; 00279 } 00280 case BL::ShaderNode::type_BSDF_TRANSLUCENT: { 00281 node = new TranslucentBsdfNode(); 00282 break; 00283 } 00284 case BL::ShaderNode::type_BSDF_TRANSPARENT: { 00285 node = new TransparentBsdfNode(); 00286 break; 00287 } 00288 case BL::ShaderNode::type_BSDF_VELVET: { 00289 node = new VelvetBsdfNode(); 00290 break; 00291 } 00292 case BL::ShaderNode::type_EMISSION: { 00293 node = new EmissionNode(); 00294 break; 00295 } 00296 case BL::ShaderNode::type_VOLUME_ISOTROPIC: { 00297 node = new IsotropicVolumeNode(); 00298 break; 00299 } 00300 case BL::ShaderNode::type_VOLUME_TRANSPARENT: { 00301 node = new TransparentVolumeNode(); 00302 break; 00303 } 00304 case BL::ShaderNode::type_NEW_GEOMETRY: { 00305 node = new GeometryNode(); 00306 break; 00307 } 00308 case BL::ShaderNode::type_LIGHT_PATH: { 00309 node = new LightPathNode(); 00310 break; 00311 } 00312 case BL::ShaderNode::type_TEX_IMAGE: { 00313 BL::ShaderNodeTexImage b_image_node(b_node); 00314 BL::Image b_image(b_image_node.image()); 00315 ImageTextureNode *image = new ImageTextureNode(); 00316 /* todo: handle generated/builtin images */ 00317 if(b_image) 00318 image->filename = blender_absolute_path(b_data, b_image, b_image.filepath()); 00319 image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()]; 00320 get_tex_mapping(&image->tex_mapping, b_image_node.texture_mapping()); 00321 node = image; 00322 break; 00323 } 00324 case BL::ShaderNode::type_TEX_ENVIRONMENT: { 00325 BL::ShaderNodeTexEnvironment b_env_node(b_node); 00326 BL::Image b_image(b_env_node.image()); 00327 EnvironmentTextureNode *env = new EnvironmentTextureNode(); 00328 if(b_image) 00329 env->filename = blender_absolute_path(b_data, b_image, b_image.filepath()); 00330 env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()]; 00331 get_tex_mapping(&env->tex_mapping, b_env_node.texture_mapping()); 00332 node = env; 00333 break; 00334 } 00335 case BL::ShaderNode::type_TEX_GRADIENT: { 00336 BL::ShaderNodeTexGradient b_gradient_node(b_node); 00337 GradientTextureNode *gradient = new GradientTextureNode(); 00338 gradient->type = GradientTextureNode::type_enum[(int)b_gradient_node.gradient_type()]; 00339 get_tex_mapping(&gradient->tex_mapping, b_gradient_node.texture_mapping()); 00340 node = gradient; 00341 break; 00342 } 00343 case BL::ShaderNode::type_TEX_VORONOI: { 00344 BL::ShaderNodeTexVoronoi b_voronoi_node(b_node); 00345 VoronoiTextureNode *voronoi = new VoronoiTextureNode(); 00346 voronoi->coloring = VoronoiTextureNode::coloring_enum[(int)b_voronoi_node.coloring()]; 00347 get_tex_mapping(&voronoi->tex_mapping, b_voronoi_node.texture_mapping()); 00348 node = voronoi; 00349 break; 00350 } 00351 case BL::ShaderNode::type_TEX_MAGIC: { 00352 BL::ShaderNodeTexMagic b_magic_node(b_node); 00353 MagicTextureNode *magic = new MagicTextureNode(); 00354 magic->depth = b_magic_node.turbulence_depth(); 00355 get_tex_mapping(&magic->tex_mapping, b_magic_node.texture_mapping()); 00356 node = magic; 00357 break; 00358 } 00359 case BL::ShaderNode::type_TEX_WAVE: { 00360 BL::ShaderNodeTexWave b_wave_node(b_node); 00361 WaveTextureNode *wave = new WaveTextureNode(); 00362 wave->type = WaveTextureNode::type_enum[(int)b_wave_node.wave_type()]; 00363 get_tex_mapping(&wave->tex_mapping, b_wave_node.texture_mapping()); 00364 node = wave; 00365 break; 00366 } 00367 case BL::ShaderNode::type_TEX_CHECKER: { 00368 BL::ShaderNodeTexChecker b_checker_node(b_node); 00369 CheckerTextureNode *checker = new CheckerTextureNode(); 00370 get_tex_mapping(&checker->tex_mapping, b_checker_node.texture_mapping()); 00371 node = checker; 00372 break; 00373 } 00374 case BL::ShaderNode::type_TEX_NOISE: { 00375 BL::ShaderNodeTexNoise b_noise_node(b_node); 00376 NoiseTextureNode *noise = new NoiseTextureNode(); 00377 get_tex_mapping(&noise->tex_mapping, b_noise_node.texture_mapping()); 00378 node = noise; 00379 break; 00380 } 00381 case BL::ShaderNode::type_TEX_MUSGRAVE: { 00382 BL::ShaderNodeTexMusgrave b_musgrave_node(b_node); 00383 MusgraveTextureNode *musgrave = new MusgraveTextureNode(); 00384 musgrave->type = MusgraveTextureNode::type_enum[(int)b_musgrave_node.musgrave_type()]; 00385 get_tex_mapping(&musgrave->tex_mapping, b_musgrave_node.texture_mapping()); 00386 node = musgrave; 00387 break; 00388 } 00389 case BL::ShaderNode::type_TEX_COORD: { 00390 node = new TextureCoordinateNode();; 00391 break; 00392 } 00393 case BL::ShaderNode::type_TEX_SKY: { 00394 BL::ShaderNodeTexSky b_sky_node(b_node); 00395 SkyTextureNode *sky = new SkyTextureNode(); 00396 sky->sun_direction = get_float3(b_sky_node.sun_direction()); 00397 sky->turbidity = b_sky_node.turbidity(); 00398 get_tex_mapping(&sky->tex_mapping, b_sky_node.texture_mapping()); 00399 node = sky; 00400 break; 00401 } 00402 } 00403 00404 if(node && node != graph->output()) 00405 graph->add(node); 00406 00407 return node; 00408 } 00409 00410 static SocketPair node_socket_map_pair(PtrNodeMap& node_map, BL::Node b_node, BL::NodeSocket b_socket) 00411 { 00412 BL::Node::inputs_iterator b_input; 00413 BL::Node::outputs_iterator b_output; 00414 string name = b_socket.name(); 00415 bool found = false; 00416 int counter = 0, total = 0; 00417 00418 /* find in inputs */ 00419 for(b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) { 00420 if(b_input->name() == name) { 00421 if(!found) 00422 counter++; 00423 total++; 00424 } 00425 00426 if(b_input->ptr.data == b_socket.ptr.data) 00427 found = true; 00428 } 00429 00430 if(!found) { 00431 /* find in outputs */ 00432 found = false; 00433 counter = 0; 00434 total = 0; 00435 00436 for(b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) { 00437 if(b_output->name() == name) { 00438 if(!found) 00439 counter++; 00440 total++; 00441 } 00442 00443 if(b_output->ptr.data == b_socket.ptr.data) 00444 found = true; 00445 } 00446 } 00447 00448 /* rename if needed */ 00449 if(name == "Shader") 00450 name = "Closure"; 00451 00452 if(total > 1) 00453 name = string_printf("%s%d", name.c_str(), counter); 00454 00455 return SocketPair(node_map[b_node.ptr.data], name); 00456 } 00457 00458 static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type) 00459 { 00460 switch (b_type) { 00461 case BL::NodeSocket::type_VALUE: 00462 return SHADER_SOCKET_FLOAT; 00463 case BL::NodeSocket::type_VECTOR: 00464 return SHADER_SOCKET_VECTOR; 00465 case BL::NodeSocket::type_RGBA: 00466 return SHADER_SOCKET_COLOR; 00467 case BL::NodeSocket::type_SHADER: 00468 return SHADER_SOCKET_CLOSURE; 00469 00470 case BL::NodeSocket::type_BOOLEAN: 00471 case BL::NodeSocket::type_MESH: 00472 case BL::NodeSocket::type_INT: 00473 default: 00474 return SHADER_SOCKET_FLOAT; 00475 } 00476 } 00477 00478 static void set_default_value(ShaderInput *input, BL::NodeSocket sock) 00479 { 00480 /* copy values for non linked inputs */ 00481 switch(input->type) { 00482 case SHADER_SOCKET_FLOAT: { 00483 BL::NodeSocketFloatNone value_sock(sock); 00484 input->set(value_sock.default_value()); 00485 break; 00486 } 00487 case SHADER_SOCKET_COLOR: { 00488 BL::NodeSocketRGBA rgba_sock(sock); 00489 input->set(get_float3(rgba_sock.default_value())); 00490 break; 00491 } 00492 case SHADER_SOCKET_NORMAL: 00493 case SHADER_SOCKET_POINT: 00494 case SHADER_SOCKET_VECTOR: { 00495 BL::NodeSocketVectorNone vec_sock(sock); 00496 input->set(get_float3(vec_sock.default_value())); 00497 break; 00498 } 00499 case SHADER_SOCKET_CLOSURE: 00500 break; 00501 } 00502 } 00503 00504 static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map) 00505 { 00506 /* add nodes */ 00507 BL::ShaderNodeTree::nodes_iterator b_node; 00508 PtrNodeMap node_map; 00509 PtrSockMap proxy_map; 00510 00511 for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) { 00512 if(b_node->is_a(&RNA_NodeGroup)) { 00513 /* add proxy converter nodes for inputs and outputs */ 00514 BL::NodeGroup b_gnode(*b_node); 00515 BL::ShaderNodeTree b_group_ntree(b_gnode.node_tree()); 00516 BL::Node::inputs_iterator b_input; 00517 BL::Node::outputs_iterator b_output; 00518 00519 PtrSockMap group_sockmap; 00520 00521 for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) { 00522 ShaderSocketType extern_type = convert_socket_type(b_input->type()); 00523 ShaderSocketType intern_type = convert_socket_type(b_input->group_socket().type()); 00524 ShaderNode *proxy = graph->add(new ProxyNode(extern_type, intern_type)); 00525 00526 /* map the external node socket to the proxy node socket */ 00527 proxy_map[b_input->ptr.data] = SocketPair(proxy, proxy->inputs[0]->name); 00528 /* map the internal group socket to the proxy node socket */ 00529 group_sockmap[b_input->group_socket().ptr.data] = SocketPair(proxy, proxy->outputs[0]->name); 00530 00531 /* default input values of the group node */ 00532 set_default_value(proxy->inputs[0], *b_input); 00533 } 00534 00535 for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) { 00536 ShaderSocketType extern_type = convert_socket_type(b_output->type()); 00537 ShaderSocketType intern_type = convert_socket_type(b_output->group_socket().type()); 00538 ShaderNode *proxy = graph->add(new ProxyNode(intern_type, extern_type)); 00539 00540 /* map the external node socket to the proxy node socket */ 00541 proxy_map[b_output->ptr.data] = SocketPair(proxy, proxy->outputs[0]->name); 00542 /* map the internal group socket to the proxy node socket */ 00543 group_sockmap[b_output->group_socket().ptr.data] = SocketPair(proxy, proxy->inputs[0]->name); 00544 00545 /* default input values of internal, unlinked group outputs */ 00546 set_default_value(proxy->inputs[0], b_output->group_socket()); 00547 } 00548 00549 add_nodes(b_data, graph, b_group_ntree, group_sockmap); 00550 } 00551 else { 00552 ShaderNode *node = add_node(b_data, graph, BL::ShaderNode(*b_node)); 00553 00554 if(node) { 00555 BL::Node::inputs_iterator b_input; 00556 00557 node_map[b_node->ptr.data] = node; 00558 00559 for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) { 00560 SocketPair pair = node_socket_map_pair(node_map, *b_node, *b_input); 00561 ShaderInput *input = pair.first->input(pair.second.c_str()); 00562 00563 assert(input); 00564 00565 /* copy values for non linked inputs */ 00566 set_default_value(input, *b_input); 00567 } 00568 } 00569 } 00570 } 00571 00572 /* connect nodes */ 00573 BL::NodeTree::links_iterator b_link; 00574 00575 for(b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) { 00576 /* get blender link data */ 00577 BL::Node b_from_node = b_link->from_node(); 00578 BL::Node b_to_node = b_link->to_node(); 00579 00580 BL::NodeSocket b_from_sock = b_link->from_socket(); 00581 BL::NodeSocket b_to_sock = b_link->to_socket(); 00582 00583 SocketPair from_pair, to_pair; 00584 00585 /* links without a node pointer are connections to group inputs/outputs */ 00586 00587 /* from sock */ 00588 if(b_from_node) { 00589 if (b_from_node.is_a(&RNA_NodeGroup)) 00590 from_pair = proxy_map[b_from_sock.ptr.data]; 00591 else 00592 from_pair = node_socket_map_pair(node_map, b_from_node, b_from_sock); 00593 } 00594 else 00595 from_pair = sockets_map[b_from_sock.ptr.data]; 00596 00597 /* to sock */ 00598 if(b_to_node) { 00599 if (b_to_node.is_a(&RNA_NodeGroup)) 00600 to_pair = proxy_map[b_to_sock.ptr.data]; 00601 else 00602 to_pair = node_socket_map_pair(node_map, b_to_node, b_to_sock); 00603 } 00604 else 00605 to_pair = sockets_map[b_to_sock.ptr.data]; 00606 00607 /* either node may be NULL when the node was not exported, typically 00608 because the node type is not supported */ 00609 if(from_pair.first && to_pair.first) { 00610 ShaderOutput *output = from_pair.first->output(from_pair.second.c_str()); 00611 ShaderInput *input = to_pair.first->input(to_pair.second.c_str()); 00612 00613 graph->connect(output, input); 00614 } 00615 } 00616 } 00617 00618 /* Sync Materials */ 00619 00620 void BlenderSync::sync_materials() 00621 { 00622 shader_map.set_default(scene->shaders[scene->default_surface]); 00623 00624 /* material loop */ 00625 BL::BlendData::materials_iterator b_mat; 00626 00627 for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat) { 00628 Shader *shader; 00629 00630 /* test if we need to sync */ 00631 if(shader_map.sync(&shader, *b_mat)) { 00632 ShaderGraph *graph = new ShaderGraph(); 00633 00634 shader->name = b_mat->name().c_str(); 00635 00636 /* create nodes */ 00637 if(b_mat->use_nodes() && b_mat->node_tree()) { 00638 PtrSockMap sock_to_node; 00639 BL::ShaderNodeTree b_ntree(b_mat->node_tree()); 00640 00641 add_nodes(b_data, graph, b_ntree, sock_to_node); 00642 } 00643 else { 00644 ShaderNode *closure, *out; 00645 00646 closure = graph->add(new DiffuseBsdfNode()); 00647 closure->input("Color")->value = get_float3(b_mat->diffuse_color()); 00648 out = graph->output(); 00649 00650 graph->connect(closure->output("BSDF"), out->input("Surface")); 00651 } 00652 00653 /* settings */ 00654 PointerRNA cmat = RNA_pointer_get(&b_mat->ptr, "cycles"); 00655 shader->sample_as_light = get_boolean(cmat, "sample_as_light"); 00656 shader->homogeneous_volume = get_boolean(cmat, "homogeneous_volume"); 00657 00658 shader->set_graph(graph); 00659 shader->tag_update(scene); 00660 } 00661 } 00662 } 00663 00664 /* Sync World */ 00665 00666 void BlenderSync::sync_world() 00667 { 00668 Background *background = scene->background; 00669 Background prevbackground = *background; 00670 00671 BL::World b_world = b_scene.world(); 00672 00673 if(world_recalc || b_world.ptr.data != world_map) { 00674 Shader *shader = scene->shaders[scene->default_background]; 00675 ShaderGraph *graph = new ShaderGraph(); 00676 00677 /* create nodes */ 00678 if(b_world && b_world.use_nodes() && b_world.node_tree()) { 00679 PtrSockMap sock_to_node; 00680 BL::ShaderNodeTree b_ntree(b_world.node_tree()); 00681 00682 add_nodes(b_data, graph, b_ntree, sock_to_node); 00683 } 00684 else if(b_world) { 00685 ShaderNode *closure, *out; 00686 00687 closure = graph->add(new BackgroundNode()); 00688 closure->input("Color")->value = get_float3(b_world.horizon_color()); 00689 out = graph->output(); 00690 00691 graph->connect(closure->output("Background"), out->input("Surface")); 00692 } 00693 00694 shader->set_graph(graph); 00695 shader->tag_update(scene); 00696 } 00697 00698 PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); 00699 background->transparent = get_boolean(cscene, "film_transparent"); 00700 00701 if(background->modified(prevbackground)) 00702 background->tag_update(scene); 00703 00704 world_map = b_world.ptr.data; 00705 world_recalc = false; 00706 } 00707 00708 /* Sync Lamps */ 00709 00710 void BlenderSync::sync_lamps() 00711 { 00712 shader_map.set_default(scene->shaders[scene->default_light]); 00713 00714 /* lamp loop */ 00715 BL::BlendData::lamps_iterator b_lamp; 00716 00717 for(b_data.lamps.begin(b_lamp); b_lamp != b_data.lamps.end(); ++b_lamp) { 00718 Shader *shader; 00719 00720 /* test if we need to sync */ 00721 if(shader_map.sync(&shader, *b_lamp)) { 00722 ShaderGraph *graph = new ShaderGraph(); 00723 00724 /* create nodes */ 00725 if(b_lamp->use_nodes() && b_lamp->node_tree()) { 00726 shader->name = b_lamp->name().c_str(); 00727 00728 PtrSockMap sock_to_node; 00729 BL::ShaderNodeTree b_ntree(b_lamp->node_tree()); 00730 00731 add_nodes(b_data, graph, b_ntree, sock_to_node); 00732 } 00733 else { 00734 ShaderNode *closure, *out; 00735 float strength = 1.0f; 00736 00737 if(b_lamp->type() == BL::Lamp::type_POINT || 00738 b_lamp->type() == BL::Lamp::type_SPOT || 00739 b_lamp->type() == BL::Lamp::type_AREA) 00740 strength = 100.0f; 00741 00742 closure = graph->add(new EmissionNode()); 00743 closure->input("Color")->value = get_float3(b_lamp->color()); 00744 closure->input("Strength")->value.x = strength; 00745 out = graph->output(); 00746 00747 graph->connect(closure->output("Emission"), out->input("Surface")); 00748 } 00749 00750 shader->set_graph(graph); 00751 shader->tag_update(scene); 00752 } 00753 } 00754 } 00755 00756 void BlenderSync::sync_shaders() 00757 { 00758 shader_map.pre_sync(); 00759 00760 sync_world(); 00761 sync_lamps(); 00762 sync_materials(); 00763 00764 /* false = don't delete unused shaders, not supported */ 00765 shader_map.post_sync(false); 00766 } 00767 00768 CCL_NAMESPACE_END 00769