Cycles: svn merge -r41627:41650 ^/trunk/blender
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 8 Nov 2011 12:33:17 +0000 (12:33 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 8 Nov 2011 12:33:17 +0000 (12:33 +0000)
16 files changed:
1  2 
intern/cycles/blender/blender_shader.cpp
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/node.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/space_image/space_image.c
source/blender/editors/space_node/CMakeLists.txt
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_node/node_templates.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/nodes/shader/node_shader_util.c
source/blenderplayer/bad_level_call_stubs/stubs.c

index 2e558cf3e97e833774ae77db32f30e5e31934930,0000000000000000000000000000000000000000..f1b032b5cc8c28ae9962cee0135794d70bc2c2ab
mode 100644,000000..100644
--- /dev/null
@@@ -1,700 -1,0 +1,696 @@@
-               case BL::ShaderNode::type_GEOM: break;
 +/*
 + * Copyright 2011, Blender Foundation.
 + *
 + * This program is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU General Public License
 + * as published by the Free Software Foundation; either version 2
 + * of the License, or (at your option) any later version.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software Foundation,
 + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 + */
 +
 +#include "background.h"
 +#include "graph.h"
 +#include "light.h"
 +#include "nodes.h"
 +#include "scene.h"
 +#include "shader.h"
 +
 +#include "blender_sync.h"
 +#include "blender_util.h"
 +
 +#include "util_debug.h"
 +
 +CCL_NAMESPACE_BEGIN
 +
 +typedef map<void*, ShaderNode*> PtrNodeMap;
 +typedef pair<ShaderNode*, std::string> SocketPair;
 +typedef map<void*, SocketPair> PtrSockMap;
 +
 +/* Find */
 +
 +void BlenderSync::find_shader(BL::ID id, vector<uint>& used_shaders)
 +{
 +      Shader *shader = shader_map.find(id);
 +
 +      for(size_t i = 0; i < scene->shaders.size(); i++) {
 +              if(scene->shaders[i] == shader) {
 +                      used_shaders.push_back(i);
 +                      break;
 +              }
 +      }
 +}
 +
 +/* Graph */
 +
 +static BL::NodeSocket get_node_input(BL::Node *b_group_node, BL::NodeSocket b_in)
 +{
 +      if(b_group_node) {
 +
 +              BL::NodeTree b_ntree = BL::NodeGroup(*b_group_node).node_tree();
 +              BL::NodeTree::links_iterator b_link;
 +
 +              for(b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
 +                      if(b_link->to_socket().ptr.data == b_in.ptr.data) {
 +                              BL::Node::inputs_iterator b_gin;
 +
 +                              for(b_group_node->inputs.begin(b_gin); b_gin != b_group_node->inputs.end(); ++b_gin)
 +                                      if(b_gin->group_socket().ptr.data == b_link->from_socket().ptr.data)
 +                                              return *b_gin;
 +
 +                      }
 +              }
 +      }
 +
 +      return b_in;
 +}
 +
 +static BL::NodeSocket get_node_output(BL::Node b_node, const string& name)
 +{
 +      BL::Node::outputs_iterator b_out;
 +
 +      for(b_node.outputs.begin(b_out); b_out != b_node.outputs.end(); ++b_out)
 +              if(b_out->name() == name)
 +                      return *b_out;
 +
 +      assert(0);
 +
 +      return *b_out;
 +}
 +
 +static float3 get_node_output_rgba(BL::Node b_node, const string& name)
 +{
 +      BL::NodeSocketRGBA sock(get_node_output(b_node, name));
 +      return get_float3(sock.default_value());
 +}
 +
 +static float get_node_output_value(BL::Node b_node, const string& name)
 +{
 +      BL::NodeSocketFloatNone sock(get_node_output(b_node, name));
 +      return sock.default_value();
 +}
 +
 +static void get_tex_mapping(TextureMapping *mapping, BL::TexMapping b_mapping)
 +{
 +      mapping->translation = get_float3(b_mapping.location());
 +      mapping->rotation = get_float3(b_mapping.rotation())*(M_PI/180.0f); /* in degrees! */
 +      mapping->scale = get_float3(b_mapping.scale());
 +
 +      mapping->x_mapping = (TextureMapping::Mapping)b_mapping.mapping_x();
 +      mapping->y_mapping = (TextureMapping::Mapping)b_mapping.mapping_y();
 +      mapping->z_mapping = (TextureMapping::Mapping)b_mapping.mapping_z();
 +}
 +
 +static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::Node *b_group_node, BL::ShaderNode b_node)
 +{
 +      ShaderNode *node = NULL;
 +
 +      switch(b_node.type()) {
 +              /* not supported */
 +              case BL::ShaderNode::type_CAMERA: break;
 +              case BL::ShaderNode::type_COMBRGB: break;
 +              case BL::ShaderNode::type_CURVE_RGB: break;
 +              case BL::ShaderNode::type_CURVE_VEC: break;
-               case BL::ShaderNode::type_BSDF_ANISOTROPIC: {
-                       node = new WardBsdfNode();
-                       break;
-               }
++              case BL::ShaderNode::type_GEOMETRY: break;
 +              case BL::ShaderNode::type_HUE_SAT: break;
 +              case BL::ShaderNode::type_INVERT: break;
 +              case BL::ShaderNode::type_MATERIAL: break;
 +              case BL::ShaderNode::type_MATERIAL_EXT: break;
 +              case BL::ShaderNode::type_NORMAL: break;
 +              case BL::ShaderNode::type_OUTPUT: break;
 +              case BL::ShaderNode::type_SCRIPT: break;
 +              case BL::ShaderNode::type_SEPRGB: break;
 +              case BL::ShaderNode::type_SQUEEZE: break;
 +              case BL::ShaderNode::type_TEXTURE: break;
 +              case BL::ShaderNode::type_VALTORGB: break;
 +              /* handled outside this function */
 +              case BL::ShaderNode::type_GROUP: break;
 +              /* existing blender nodes */
 +              case BL::ShaderNode::type_RGB: {
 +                      ColorNode *color = new ColorNode();
 +                      color->value = get_node_output_rgba(b_node, "Color");
 +                      node = color;
 +                      break;
 +              }
 +              case BL::ShaderNode::type_VALUE: {
 +                      ValueNode *value = new ValueNode();
 +                      value->value = get_node_output_value(b_node, "Value");
 +                      node = value;
 +                      break;
 +              }
 +              case BL::ShaderNode::type_MIX_RGB: {
 +                      BL::ShaderNodeMixRGB b_mix_node(b_node);
 +                      MixNode *mix = new MixNode();
 +                      mix->type = MixNode::type_enum[b_mix_node.blend_type()];
 +                      node = mix;
 +                      break;
 +              }
 +              case BL::ShaderNode::type_RGBTOBW: {
 +                      node = new ConvertNode(SHADER_SOCKET_COLOR, SHADER_SOCKET_FLOAT);
 +                      break;
 +              }
 +              case BL::ShaderNode::type_MATH: {
 +                      BL::ShaderNodeMath b_math_node(b_node);
 +                      MathNode *math = new MathNode();
 +                      math->type = MathNode::type_enum[b_math_node.operation()];
 +                      node = math;
 +                      break;
 +              }
 +              case BL::ShaderNode::type_VECT_MATH: {
 +                      BL::ShaderNodeVectorMath b_vector_math_node(b_node);
 +                      VectorMathNode *vmath = new VectorMathNode();
 +                      vmath->type = VectorMathNode::type_enum[b_vector_math_node.operation()];
 +                      node = vmath;
 +                      break;
 +              }
 +              case BL::ShaderNode::type_MAPPING: {
 +                      BL::ShaderNodeMapping b_mapping_node(b_node);
 +                      MappingNode *mapping = new MappingNode();
 +
 +                      get_tex_mapping(&mapping->tex_mapping, b_mapping_node.mapping());
 +
 +                      node = mapping;
 +                      break;
 +              }
 +
 +              /* new nodes */
 +              case BL::ShaderNode::type_OUTPUT_MATERIAL:
 +              case BL::ShaderNode::type_OUTPUT_WORLD:
 +              case BL::ShaderNode::type_OUTPUT_LAMP: {
 +                      node = graph->output();
 +                      break;
 +              }
 +              case BL::ShaderNode::type_FRESNEL: {
 +                      node = new FresnelNode();
 +                      break;
 +              }
 +              case BL::ShaderNode::type_LAYER_WEIGHT: {
 +                      node = new LayerWeightNode();
 +                      break;
 +              }
 +              case BL::ShaderNode::type_ADD_SHADER: {
 +                      node = new AddClosureNode();
 +                      break;
 +              }
 +              case BL::ShaderNode::type_MIX_SHADER: {
 +                      node = new MixClosureNode();
 +                      break;
 +              }
 +              case BL::ShaderNode::type_ATTRIBUTE: {
 +                      BL::ShaderNodeAttribute b_attr_node(b_node);
 +                      AttributeNode *attr = new AttributeNode();
 +                      attr->attribute = b_attr_node.attribute_name();
 +                      node = attr;
 +                      break;
 +              }
 +              case BL::ShaderNode::type_BACKGROUND: {
 +                      node = new BackgroundNode();
 +                      break;
 +              }
 +              case BL::ShaderNode::type_HOLDOUT: {
 +                      node = new HoldoutNode();
 +                      break;
 +              }
-               case BL::ShaderNode::type_GEOMETRY: {
 +              case BL::ShaderNode::type_BSDF_DIFFUSE: {
 +                      node = new DiffuseBsdfNode();
 +                      break;
 +              }
 +              case BL::ShaderNode::type_BSDF_GLOSSY: {
 +                      BL::ShaderNodeBsdfGlossy b_glossy_node(b_node);
 +                      GlossyBsdfNode *glossy = new GlossyBsdfNode();
 +
 +                      switch(b_glossy_node.distribution()) {
 +                              case BL::ShaderNodeBsdfGlossy::distribution_SHARP:
 +                                      glossy->distribution = ustring("Sharp");
 +                                      break;
 +                              case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN:
 +                                      glossy->distribution = ustring("Beckmann");
 +                                      break;
 +                              case BL::ShaderNodeBsdfGlossy::distribution_GGX:
 +                                      glossy->distribution = ustring("GGX");
 +                                      break;
 +                      }
 +                      node = glossy;
 +                      break;
 +              }
 +              case BL::ShaderNode::type_BSDF_GLASS: {
 +                      BL::ShaderNodeBsdfGlass b_glass_node(b_node);
 +                      GlassBsdfNode *glass = new GlassBsdfNode();
 +                      switch(b_glass_node.distribution()) {
 +                              case BL::ShaderNodeBsdfGlass::distribution_SHARP:
 +                                      glass->distribution = ustring("Sharp");
 +                                      break;
 +                              case BL::ShaderNodeBsdfGlass::distribution_BECKMANN:
 +                                      glass->distribution = ustring("Beckmann");
 +                                      break;
 +                              case BL::ShaderNodeBsdfGlass::distribution_GGX:
 +                                      glass->distribution = ustring("GGX");
 +                                      break;
 +                      }
 +                      node = glass;
 +                      break;
 +              }
 +              case BL::ShaderNode::type_BSDF_TRANSLUCENT: {
 +                      node = new TranslucentBsdfNode();
 +                      break;
 +              }
 +              case BL::ShaderNode::type_BSDF_TRANSPARENT: {
 +                      node = new TransparentBsdfNode();
 +                      break;
 +              }
 +              case BL::ShaderNode::type_BSDF_VELVET: {
 +                      node = new VelvetBsdfNode();
 +                      break;
 +              }
 +              case BL::ShaderNode::type_EMISSION: {
 +                      node = new EmissionNode();
 +                      break;
 +              }
 +              case BL::ShaderNode::type_VOLUME_ISOTROPIC: {
 +                      node = new IsotropicVolumeNode();
 +                      break;
 +              }
 +              case BL::ShaderNode::type_VOLUME_TRANSPARENT: {
 +                      node = new TransparentVolumeNode();
 +                      break;
 +              }
++              case BL::ShaderNode::type_NEW_GEOMETRY: {
 +                      node = new GeometryNode();
 +                      break;
 +              }
 +              case BL::ShaderNode::type_LIGHT_PATH: {
 +                      node = new LightPathNode();
 +                      break;
 +              }
 +              case BL::ShaderNode::type_TEX_IMAGE: {
 +                      BL::ShaderNodeTexImage b_image_node(b_node);
 +                      BL::Image b_image(b_image_node.image());
 +                      ImageTextureNode *image = new ImageTextureNode();
 +                      /* todo: handle generated/builtin images */
 +                      if(b_image)
 +                              image->filename = blender_absolute_path(b_data, b_image, b_image.filepath());
 +                      image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()];
 +                      get_tex_mapping(&image->tex_mapping, b_image_node.texture_mapping());
 +                      node = image;
 +                      break;
 +              }
 +              case BL::ShaderNode::type_TEX_ENVIRONMENT: {
 +                      BL::ShaderNodeTexEnvironment b_env_node(b_node);
 +                      BL::Image b_image(b_env_node.image());
 +                      EnvironmentTextureNode *env = new EnvironmentTextureNode();
 +                      if(b_image)
 +                              env->filename = blender_absolute_path(b_data, b_image, b_image.filepath());
 +                      env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
 +                      get_tex_mapping(&env->tex_mapping, b_env_node.texture_mapping());
 +                      node = env;
 +                      break;
 +              }
 +              case BL::ShaderNode::type_TEX_GRADIENT: {
 +                      BL::ShaderNodeTexGradient b_gradient_node(b_node);
 +                      GradientTextureNode *gradient = new GradientTextureNode();
 +                      gradient->type = GradientTextureNode::type_enum[(int)b_gradient_node.gradient_type()];
 +                      get_tex_mapping(&gradient->tex_mapping, b_gradient_node.texture_mapping());
 +                      node = gradient;
 +                      break;
 +              }
 +              case BL::ShaderNode::type_TEX_VORONOI: {
 +                      BL::ShaderNodeTexVoronoi b_voronoi_node(b_node);
 +                      VoronoiTextureNode *voronoi = new VoronoiTextureNode();
 +                      voronoi->coloring = VoronoiTextureNode::coloring_enum[(int)b_voronoi_node.coloring()];
 +                      get_tex_mapping(&voronoi->tex_mapping, b_voronoi_node.texture_mapping());
 +                      node = voronoi;
 +                      break;
 +              }
 +              case BL::ShaderNode::type_TEX_MAGIC: {
 +                      BL::ShaderNodeTexMagic b_magic_node(b_node);
 +                      MagicTextureNode *magic = new MagicTextureNode();
 +                      magic->depth = b_magic_node.turbulence_depth();
 +                      get_tex_mapping(&magic->tex_mapping, b_magic_node.texture_mapping());
 +                      node = magic;
 +                      break;
 +              }
 +              case BL::ShaderNode::type_TEX_WAVE: {
 +                      BL::ShaderNodeTexWave b_wave_node(b_node);
 +                      WaveTextureNode *wave = new WaveTextureNode();
 +                      wave->type = WaveTextureNode::type_enum[(int)b_wave_node.wave_type()];
 +                      get_tex_mapping(&wave->tex_mapping, b_wave_node.texture_mapping());
 +                      node = wave;
 +                      break;
 +              }
 +              case BL::ShaderNode::type_TEX_NOISE: {
 +                      BL::ShaderNodeTexNoise b_noise_node(b_node);
 +                      NoiseTextureNode *noise = new NoiseTextureNode();
 +                      get_tex_mapping(&noise->tex_mapping, b_noise_node.texture_mapping());
 +                      node = noise;
 +                      break;
 +              }
 +              case BL::ShaderNode::type_TEX_MUSGRAVE: {
 +                      BL::ShaderNodeTexMusgrave b_musgrave_node(b_node);
 +                      MusgraveTextureNode *musgrave = new MusgraveTextureNode();
 +                      musgrave->type = MusgraveTextureNode::type_enum[(int)b_musgrave_node.musgrave_type()];
 +                      get_tex_mapping(&musgrave->tex_mapping, b_musgrave_node.texture_mapping());
 +                      node = musgrave;
 +                      break;
 +              }
 +              case BL::ShaderNode::type_TEX_COORD: {
 +                      node = new TextureCoordinateNode();;
 +                      break;
 +              }
 +              case BL::ShaderNode::type_TEX_SKY: {
 +                      BL::ShaderNodeTexSky b_sky_node(b_node);
 +                      SkyTextureNode *sky = new SkyTextureNode();
 +                      sky->sun_direction = get_float3(b_sky_node.sun_direction());
 +                      sky->turbidity = b_sky_node.turbidity();
 +                      get_tex_mapping(&sky->tex_mapping, b_sky_node.texture_mapping());
 +                      node = sky;
 +                      break;
 +              }
 +      }
 +
 +      if(node && node != graph->output())
 +              graph->add(node);
 +
 +      return node;
 +}
 +
 +static SocketPair node_socket_map_pair(PtrNodeMap& node_map, BL::Node b_node, BL::NodeSocket b_socket)
 +{
 +      BL::Node::inputs_iterator b_input;
 +      BL::Node::outputs_iterator b_output;
 +      string name = b_socket.name();
 +      bool found = false;
 +      int counter = 0, total = 0;
 +
 +      /* find in inputs */
 +      for(b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
 +              if(b_input->name() == name) {
 +                      if(!found)
 +                              counter++;
 +                      total++;
 +              }
 +
 +              if(b_input->ptr.data == b_socket.ptr.data)
 +                      found = true;
 +      }
 +
 +      if(!found) {
 +              /* find in outputs */
 +              found = false;
 +              counter = 0;
 +              total = 0;
 +
 +              for(b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
 +                      if(b_output->name() == name) {
 +                              if(!found)
 +                                      counter++;
 +                              total++;
 +                      }
 +
 +                      if(b_output->ptr.data == b_socket.ptr.data)
 +                              found = true;
 +              }
 +      }
 +
 +      /* rename if needed */
 +      if(name == "Shader")
 +              name = "Closure";
 +
 +      if(total > 1)
 +              name = string_printf("%s%d", name.c_str(), counter);
 +
 +      return SocketPair(node_map[b_node.ptr.data], name);
 +}
 +
 +static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, BL::Node *b_group_node, PtrSockMap& sockets_map)
 +{
 +      /* add nodes */
 +      BL::ShaderNodeTree::nodes_iterator b_node;
 +      PtrNodeMap node_map;
 +      map<void*, PtrSockMap> node_groups;
 +
 +      for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
 +              if(b_node->is_a(&RNA_NodeGroup)) {
 +                      BL::NodeGroup b_gnode(*b_node);
 +                      BL::ShaderNodeTree b_group_ntree(b_gnode.node_tree());
 +
 +                      node_groups[b_node->ptr.data] = PtrSockMap();
 +                      add_nodes(b_data, graph, b_group_ntree, &b_gnode, node_groups[b_node->ptr.data]);
 +              }
 +              else {
 +                      ShaderNode *node = add_node(b_data, graph, b_group_node, BL::ShaderNode(*b_node));
 +
 +                      if(node) {
 +                              BL::Node::inputs_iterator b_input;
 +                              BL::Node::outputs_iterator b_output;
 +
 +                              node_map[b_node->ptr.data] = node;
 +
 +                              for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
 +                                      SocketPair pair = node_socket_map_pair(node_map, *b_node, *b_input);
 +                                      ShaderInput *input = pair.first->input(pair.second.c_str());
 +                                      BL::NodeSocket sock(get_node_input(b_group_node, *b_input));
 +
 +                                      assert(input);
 +
 +                                      /* copy values for non linked inputs */
 +                                      switch(input->type) {
 +                                              case SHADER_SOCKET_FLOAT: {
 +                                                      BL::NodeSocketFloatNone value_sock(sock);
 +                                                      input->set(value_sock.default_value());
 +                                                      break;
 +                                              }
 +                                              case SHADER_SOCKET_COLOR: {
 +                                                      BL::NodeSocketRGBA rgba_sock(sock);
 +                                                      input->set(get_float3(rgba_sock.default_value()));
 +                                                      break;
 +                                              }
 +                                              case SHADER_SOCKET_NORMAL:
 +                                              case SHADER_SOCKET_POINT:
 +                                              case SHADER_SOCKET_VECTOR: {
 +                                                      BL::NodeSocketVectorNone vec_sock(sock);
 +                                                      input->set(get_float3(vec_sock.default_value()));
 +                                                      break;
 +                                              }
 +                                              case SHADER_SOCKET_CLOSURE:
 +                                                      break;
 +                                      }
 +                              }
 +                      }
 +              }
 +      }
 +
 +      /* connect nodes */
 +      BL::NodeTree::links_iterator b_link;
 +
 +      for(b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
 +              /* get blender link data */
 +              BL::Node b_from_node = b_link->from_node();
 +              BL::Node b_to_node = b_link->to_node();
 +
 +              BL::NodeSocket b_from_sock = b_link->from_socket();
 +              BL::NodeSocket b_to_sock = b_link->to_socket();
 +
 +              /* if link with group socket, add to map so we can connect it later */
 +              if(b_group_node) {
 +                      if(!b_from_node) {
 +                              sockets_map[b_from_sock.ptr.data] =
 +                                      node_socket_map_pair(node_map, b_to_node, b_to_sock);
 +
 +                              continue;
 +                      }
 +                      else if(!b_to_node) {
 +                              sockets_map[b_to_sock.ptr.data] =
 +                                      node_socket_map_pair(node_map, b_from_node, b_from_sock);
 +
 +                              continue;
 +                      }
 +              }
 +
 +              SocketPair from_pair, to_pair;
 +
 +              /* from sock */
 +              if(b_from_node.is_a(&RNA_NodeGroup)) {
 +                      /* group node */
 +                      BL::NodeSocket group_sock = b_from_sock.group_socket();
 +                      from_pair = node_groups[b_from_node.ptr.data][group_sock.ptr.data];
 +              }
 +              else {
 +                      /* regular node */
 +                      from_pair = node_socket_map_pair(node_map, b_from_node, b_from_sock);
 +              }
 +
 +              /* to sock */
 +              if(b_to_node.is_a(&RNA_NodeGroup)) {
 +                      /* group node */
 +                      BL::NodeSocket group_sock = b_to_sock.group_socket();
 +                      to_pair = node_groups[b_to_node.ptr.data][group_sock.ptr.data];
 +              }
 +              else {
 +                      /* regular node */
 +                      to_pair = node_socket_map_pair(node_map, b_to_node, b_to_sock);
 +              }
 +
 +              /* in case of groups there may not actually be a node inside the group
 +                 that the group socket connects to, so from_node or to_node may be NULL */
 +              if(from_pair.first && to_pair.first) {
 +                      ShaderOutput *output = from_pair.first->output(from_pair.second.c_str());
 +                      ShaderInput *input = to_pair.first->input(to_pair.second.c_str());
 +
 +                      graph->connect(output, input);
 +              }
 +      }
 +}
 +
 +/* Sync Materials */
 +
 +void BlenderSync::sync_materials()
 +{
 +      shader_map.set_default(scene->shaders[scene->default_surface]);
 +
 +      /* material loop */
 +      BL::BlendData::materials_iterator b_mat;
 +
 +      for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat) {
 +              Shader *shader;
 +              
 +              /* test if we need to sync */
 +              if(shader_map.sync(&shader, *b_mat)) {
 +                      ShaderGraph *graph = new ShaderGraph();
 +
 +                      shader->name = b_mat->name().c_str();
 +
 +                      /* create nodes */
 +                      if(b_mat->use_nodes() && b_mat->node_tree()) {
 +                              PtrSockMap sock_to_node;
 +                              BL::ShaderNodeTree b_ntree(b_mat->node_tree());
 +
 +                              add_nodes(b_data, graph, b_ntree, NULL, sock_to_node);
 +                      }
 +                      else {
 +                              ShaderNode *closure, *out;
 +
 +                              closure = graph->add(new DiffuseBsdfNode());
 +                              closure->input("Color")->value = get_float3(b_mat->diffuse_color());
 +                              out = graph->output();
 +
 +                              graph->connect(closure->output("BSDF"), out->input("Surface"));
 +                      }
 +
 +                      /* settings */
 +                      PointerRNA cmat = RNA_pointer_get(&b_mat->ptr, "cycles");
 +                      shader->sample_as_light = get_boolean(cmat, "sample_as_light");
 +                      shader->homogeneous_volume = get_boolean(cmat, "homogeneous_volume");
 +
 +                      shader->set_graph(graph);
 +                      shader->tag_update(scene);
 +              }
 +      }
 +}
 +
 +/* Sync World */
 +
 +void BlenderSync::sync_world()
 +{
 +      Background *background = scene->background;
 +      Background prevbackground = *background;
 +
 +      BL::World b_world = b_scene.world();
 +
 +      if(world_recalc || b_world.ptr.data != world_map) {
 +              Shader *shader = scene->shaders[scene->default_background];
 +              ShaderGraph *graph = new ShaderGraph();
 +
 +              /* create nodes */
 +              if(b_world && b_world.use_nodes() && b_world.node_tree()) {
 +                      PtrSockMap sock_to_node;
 +                      BL::ShaderNodeTree b_ntree(b_world.node_tree());
 +
 +                      add_nodes(b_data, graph, b_ntree, NULL, sock_to_node);
 +              }
 +              else if(b_world) {
 +                      ShaderNode *closure, *out;
 +
 +                      closure = graph->add(new BackgroundNode());
 +                      closure->input("Color")->value = get_float3(b_world.horizon_color());
 +                      out = graph->output();
 +
 +                      graph->connect(closure->output("Background"), out->input("Surface"));
 +              }
 +
 +              shader->set_graph(graph);
 +              shader->tag_update(scene);
 +      }
 +
 +      PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
 +      background->transparent = get_boolean(cscene, "film_transparent");
 +
 +      if(background->modified(prevbackground))
 +              background->tag_update(scene);
 +
 +      world_map = b_world.ptr.data;
 +      world_recalc = false;
 +}
 +
 +/* Sync Lamps */
 +
 +void BlenderSync::sync_lamps()
 +{
 +      shader_map.set_default(scene->shaders[scene->default_light]);
 +
 +      /* lamp loop */
 +      BL::BlendData::lamps_iterator b_lamp;
 +
 +      for(b_data.lamps.begin(b_lamp); b_lamp != b_data.lamps.end(); ++b_lamp) {
 +              Shader *shader;
 +              
 +              /* test if we need to sync */
 +              if(shader_map.sync(&shader, *b_lamp)) {
 +                      ShaderGraph *graph = new ShaderGraph();
 +
 +                      /* create nodes */
 +                      if(b_lamp->use_nodes() && b_lamp->node_tree()) {
 +                              shader->name = b_lamp->name().c_str();
 +
 +                              PtrSockMap sock_to_node;
 +                              BL::ShaderNodeTree b_ntree(b_lamp->node_tree());
 +
 +                              add_nodes(b_data, graph, b_ntree, NULL, sock_to_node);
 +                      }
 +                      else {
 +                              ShaderNode *closure, *out;
 +
 +                              closure = graph->add(new EmissionNode());
 +                              closure->input("Color")->value = get_float3(b_lamp->color());
 +                              closure->input("Strength")->value.x = b_lamp->energy()*10.0f;
 +                              out = graph->output();
 +
 +                              graph->connect(closure->output("Emission"), out->input("Surface"));
 +                      }
 +
 +                      shader->set_graph(graph);
 +                      shader->tag_update(scene);
 +              }
 +      }
 +}
 +
 +void BlenderSync::sync_shaders()
 +{
 +      shader_map.pre_sync();
 +
 +      sync_world();
 +      sync_lamps();
 +      sync_materials();
 +
 +      /* false = don't delete unused shaders, not supported */
 +      shader_map.post_sync(false);
 +}
 +
 +CCL_NAMESPACE_END
 +
Simple merge
index b0f597ba47770bcd40ca28d80f2694411b92412e,96fbe3929221926a4a2c3c717d6201633fe7be53..d756e4f90995d853788fe46ca5a5f66ad8e1d6f1
@@@ -2122,98 -2122,6 +2122,106 @@@ static void lib_link_nodetree(FileData 
        }
  }
  
 +static void ntree_tmp_cycles_emission_version_patch(FileData *fd, Library *lib, bNodeTree *ntree)
 +{
 +      bNode *node;
 +      bNodeSocket *sock;
 +      bNodeSocketValueFloat *valfloat;
 +
 +      for(node=ntree->nodes.first; node; node=node->next) {
 +              if(node->type == SH_NODE_EMISSION) {
 +                      for(sock=node->inputs.first; sock; sock=sock->next) {
 +                              if(strcmp(sock->name, "Strength") == 0) {
 +                                      valfloat= sock->default_value;
 +                                      valfloat->value /= M_PI;
 +                              }
 +                      }
 +              }
 +              else if(node->type == NODE_GROUP) {
 +                      bNodeTree *ntree= newlibadr(fd, lib, node->id);
 +
 +                      if(ntree)
 +                              ntree_tmp_cycles_emission_version_patch(fd, lib, ntree);
 +              }
 +      }
 +}
 +
 +static void ntree_tmp_cycles_version_patch(bNodeTree *ntree)
 +{
 +      bNode *node;
 +      bNodeSocket *sock;
 +
 +      for(node=ntree->nodes.first; node; node=node->next) {
 +              if(node->type == SH_NODE_FRESNEL) {
 +
 +                      for(sock=node->inputs.first; sock; sock=sock->next) {
 +                              if(strcmp(sock->name, "Fresnel") == 0) {
 +                                      bNodeSocket *osock;
 +
 +                                      node->type = SH_NODE_LAYER_WEIGHT;
 +                                      strcpy(sock->name, "Blend");
 +
 +                                      for(osock=node->outputs.first; osock; osock=osock->next)
 +                                              if(strcmp(osock->name, "Fac") == 0)
 +                                                      strcpy(osock->name, "Fresnel");
 +                              }
 +                      }
 +              }
++              else if(node->type == SH_NODE_MIX_RGB) {
++                      bNodeSocket *sock = node->inputs.first;
++
++                      sock=sock->next;
++                      strcpy(sock->name, "Color1");
++                      sock=sock->next;
++                      strcpy(sock->name, "Color2");
++              }
 +              else {
 +                      for(sock=node->inputs.first; sock; sock=sock->next) {
 +                              if(strcmp(sock->name, "Closure1") == 0)
 +                                      strcpy(sock->name, "Shader1");
 +                              if(strcmp(sock->name, "Closure2") == 0)
 +                                      strcpy(sock->name, "Shader2");
 +
 +                              if(strcmp(sock->name, "Color1") == 0)
 +                                      strcpy(sock->name, "Color");
 +                              if(strcmp(sock->name, "Color2") == 0)
 +                                      strcpy(sock->name, "Color");
 +
 +                              if(strcmp(sock->name, "Vector1") == 0)
 +                                      strcpy(sock->name, "Vector");
 +                              if(strcmp(sock->name, "Vector2") == 0)
 +                                      strcpy(sock->name, "Vector");
 +
 +                              if(strcmp(sock->name, "Value1") == 0)
 +                                      strcpy(sock->name, "Value");
 +                              if(strcmp(sock->name, "Value2") == 0)
 +                                      strcpy(sock->name, "Value");
 +
 +                              if(strcmp(sock->name, "Shader1") == 0)
 +                                      strcpy(sock->name, "Shader");
 +                              if(strcmp(sock->name, "Shader2") == 0)
 +                                      strcpy(sock->name, "Shader");
 +
 +                              if(node->type == SH_NODE_OUTPUT_MATERIAL ||
 +                                 node->type == SH_NODE_OUTPUT_WORLD ||
 +                                 node->type == SH_NODE_OUTPUT_LAMP) {
 +                                      if(strcmp(sock->name, "Shader") == 0)
 +                                              strcpy(sock->name, "Surface");
 +                              }
 +
 +                              if(strcmp(sock->name, "Fresnel") == 0) {
 +                                      strcpy(sock->name, "IOR");
 +                                      sock->ns.vec[0] = 1.0f/MAX2(1.0f - sock->ns.vec[0], 1e-5f);
 +                              }
 +                      }
 +
 +                      for(sock=node->outputs.first; sock; sock=sock->next)
 +                              if(strcmp(sock->name, "Closure") == 0)
 +                                      strcpy(sock->name, "Shader");
 +              }
 +      }
 +}
 +
  static void lib_nodetree_init_types_cb(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree)
  {
        bNode *node;
index 677ec0ae9bda1be96e937e0591bf0cd08444eeaf,02b8cc9e2c65e8e9733b82b9e0305c173f817661..db71d055c8620d845c26b15947f3d13c85796ad1
@@@ -131,11 -135,11 +135,11 @@@ typedef struct uiLayout uiLayout
  #define UI_ICON_LEFT  128
  #define UI_ICON_SUBMENU       256
  #define UI_ICON_PREVIEW       512
-       /* control for button type block */
- #define UI_MAKE_TOP           1024
- #define UI_MAKE_DOWN  2048
- #define UI_MAKE_LEFT  4096
- #define UI_MAKE_RIGHT 8192
 -#define UI_TEXT_RIGHT         1024
 -#define UI_BUT_NODE_LINK      2048
 -#define UI_BUT_NODE_ACTIVE    4096
 -#define UI_FLAG_UNUSED                8192
++#define UI_BUT_NODE_LINK      1024
++#define UI_BUT_NODE_ACTIVE    2048
++#define UI_FLAG_UNUSED                4096
++#define UI_FLAG_UNUSED2               8192
  
        /* button align flag, for drawing groups together */
  #define UI_BUT_ALIGN          (UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT|UI_BUT_ALIGN_RIGHT|UI_BUT_ALIGN_DOWN)
index 3f5344d3214f3578913cda1bd2788021f287a2ff,aa407bbf6d4f780cbd0bca015f76317834967a0f..0abe7a04a97349d877028ae076c1416fb2ca7899
@@@ -2554,14 -2551,12 +2552,8 @@@ static void widget_menunodebut(uiWidget
        /* half rounded */
        round_box_edges(&wtb, roundboxalign, rect, 4.0f);
  
-       memcpy(tmp, wcol->inner, sizeof(char)*4);
-       memcpy(tmp2, wcol->outline, sizeof(char)*4);
--      wcol->inner[0] += 15;
--      wcol->inner[1] += 15;
--      wcol->inner[2] += 15;
--      wcol->outline[0] += 15;
--      wcol->outline[1] += 15;
--      wcol->outline[2] += 15;
++      wcol->inner[0] += 15; wcol->inner[1] += 15; wcol->inner[2] += 15;
++      wcol->outline[0] += 15; wcol->outline[1] += 15; wcol->outline[2] += 15;
        
        /* decoration */
        widgetbase_draw(&wtb, wcol);
index e817565c5093cdced00ad37fd478528b723abee3,3b9876329ec4e87d3abfec42ce639d665df36d2b..c29553a9c875ff2dfde47b6e1205e7f265b61c8c
@@@ -84,7 -81,7 +84,7 @@@ Image *ED_space_image(SpaceImage *sima
  /* called to assign images to UV faces */
  void ED_space_image_set(bContext *C, SpaceImage *sima, Scene *scene, Object *obedit, Image *ima)
  {
-       ED_uvedit_assign_image(G.main, scene, obedit, ima, sima->image);
 -      ED_uvedit_assign_image(scene, obedit, ima, sima->image);
++      ED_uvedit_assign_image(CTX_data_main(C), scene, obedit, ima, sima->image);
        
        /* change the space ima after because uvedit_face_visible uses the space ima
         * to check if the face is displayed in UV-localview */
index 982f33bd60055b4aa524c922d94eb930f3fd8b9c,806a6f988283a7966c95051282e34eb594ac81cd..5aa15cc68d645ad9782376f054ba287056c75299
@@@ -251,19 -213,13 +213,18 @@@ static void node_socket_add_replace(Mai
                                        }
                                }
                        }
-                       /* also preserve mapping for texture nodes */
-                       if(node_from->typeinfo->nclass == NODE_CLASS_TEXTURE &&
-                          node_prev->typeinfo->nclass == NODE_CLASS_TEXTURE)
-                               memcpy(node_from->storage, node_prev->storage, sizeof(NodeTexBase));
-                       /* remove node */
-                       ui_node_remove_linked(ntree, node_prev);
                }
  
-               nodeUpdate(ntree, node_from);
++              /* also preserve mapping for texture nodes */
++              if(node_from->typeinfo->nclass == NODE_CLASS_TEXTURE &&
++                 node_prev->typeinfo->nclass == NODE_CLASS_TEXTURE)
++                      memcpy(node_from->storage, node_prev->storage, sizeof(NodeTexBase));
++
+               /* remove node */
+               node_remove_linked(ntree, node_prev);
        }
  
+       nodeUpdate(ntree, node_from);
        nodeUpdate(ntree, node_to);
        ntreeUpdateTree(ntree);
  
@@@ -475,13 -503,9 +508,13 @@@ void uiTemplateNodeLink(uiLayout *layou
        but->flag |= UI_TEXT_LEFT|UI_BUT_NODE_LINK;
        but->poin= (char*)but;
        but->func_argN = arg;
 +
 +      if(sock->link && sock->link->fromnode)
 +              if(sock->link->fromnode->flag & NODE_ACTIVE_TEXTURE)
 +                      but->flag |= UI_BUT_NODE_ACTIVE;
  }
  
- /************************* Node Tree Layout **************************/
+ /**************************** Node Tree Layout *******************************/
  
  static void ui_node_draw_input(uiLayout *layout, bContext *C,
        bNodeTree *ntree, bNode *node, bNodeSocket *input, int depth);
index 5c8e170dfc7a8edf34426cabdd0900df644a7a16,51bbf591bb3863ac56029857e394a38cbf308be8..8e20f331698930b752b5daa4eff2ffbf3574c667
@@@ -2229,18 -2229,11 +2229,17 @@@ CustomDataMask ED_view3d_datamask(Scen
  {
        CustomDataMask mask= 0;
  
 -      if((v3d->drawtype == OB_TEXTURE) || ((v3d->drawtype == OB_SOLID) && (v3d->flag2 & V3D_SOLID_TEX))) {
 +      if(ELEM(v3d->drawtype, OB_TEXTURE, OB_MATERIAL) || ((v3d->drawtype == OB_SOLID) && (v3d->flag2 & V3D_SOLID_TEX))) {
                mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
  
 -              if(scene->gm.matmode == GAME_MAT_GLSL)
 -                      mask |= CD_MASK_ORCO;
 +              if(scene_use_new_shading_nodes(scene)) {
-                       /* todo: use orco in textured draw mode */
 +                      if(v3d->drawtype == OB_MATERIAL)
 +                              mask |= CD_MASK_ORCO;
 +              }
 +              else {
 +                      if(scene->gm.matmode == GAME_MAT_GLSL)
 +                              mask |= CD_MASK_ORCO;
 +              }
        }
  
        return mask;