Commit: 56f89666eefe064f00cef2af270f0d014eb673f7
Author: Brecht Van Lommel
Date:   Sun May 29 15:10:34 2016 +0200
Branches: compositor-2016
https://developer.blender.org/rB56f89666eefe064f00cef2af270f0d014eb673f7

Code refactor: centralize OSL node creation in shader manager.

===================================================================

M       intern/cycles/app/cycles_xml.cpp
M       intern/cycles/blender/blender_shader.cpp
M       intern/cycles/render/nodes.cpp
M       intern/cycles/render/nodes.h
M       intern/cycles/render/osl.cpp
M       intern/cycles/render/osl.h

===================================================================

diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp
index f501a01..60fa2fc 100644
--- a/intern/cycles/app/cycles_xml.cpp
+++ b/intern/cycles/app/cycles_xml.cpp
@@ -31,6 +31,7 @@
 #include "mesh.h"
 #include "nodes.h"
 #include "object.h"
+#include "osl.h"
 #include "shader.h"
 #include "scene.h"
 
@@ -250,35 +251,6 @@ static bool xml_read_enum_value(int *value, NodeEnum& enm, 
pugi::xml_node node,
        return false;
 }
 
-static SocketType::Type xml_read_socket_type(pugi::xml_node node, const char 
*name)
-{
-       pugi::xml_attribute attr = node.attribute(name);
-
-       if(attr) {
-               string value = attr.value();
-               if(string_iequals(value, "float"))
-                       return SocketType::FLOAT;
-               else if(string_iequals(value, "int"))
-                       return SocketType::INT;
-               else if(string_iequals(value, "color"))
-                       return SocketType::COLOR;
-               else if(string_iequals(value, "vector"))
-                       return SocketType::VECTOR;
-               else if(string_iequals(value, "point"))
-                       return SocketType::POINT;
-               else if(string_iequals(value, "normal"))
-                       return SocketType::NORMAL;
-               else if(string_iequals(value, "closure color"))
-                       return SocketType::CLOSURE;
-               else if(string_iequals(value, "string"))
-                       return SocketType::STRING;
-               else
-                       fprintf(stderr, "Unknown shader socket type \"%s\" for 
attribute \"%s\".\n", value.c_str(), name);
-       }
-       
-       return SocketType::UNDEFINED;
-}
-
 /* Camera */
 
 static void xml_read_camera(XMLReadState& state, pugi::xml_node node)
@@ -313,6 +285,7 @@ static void xml_read_shader_graph(XMLReadState& state, 
Shader *shader, pugi::xml
 {
        xml_read_node(state, shader, graph_node);
 
+       ShaderManager *manager = state.scene->shader_manager;
        ShaderGraph *graph = new ShaderGraph();
 
        map<string, ShaderNode*> nodemap;
@@ -352,45 +325,27 @@ static void xml_read_shader_graph(XMLReadState& state, 
Shader *shader, pugi::xml
                        snode = env;
                }
                else if(string_iequals(node.name(), "osl_shader")) {
-                       OSLScriptNode *osl = new OSLScriptNode();
+                       if(manager->use_osl()) {
+                               std::string filepath;
 
-                       /* Source */
-                       xml_read_string(&osl->filepath, node, "src");
-                       if(path_is_relative(osl->filepath)) {
-                               osl->filepath = path_join(state.base, 
osl->filepath);
-                       }
+                               if(xml_read_string(&filepath, node, "src")) {
+                                       if(path_is_relative(filepath)) {
+                                               filepath = 
path_join(state.base, filepath);
+                                       }
 
-                       /* Generate inputs/outputs from node sockets
-                        *
-                        * Note: ShaderInput/ShaderOutput store shallow string 
copies only!
-                        * So we register them as ustring to ensure the pointer 
stays valid. */
-                       /* read input values */
-                       for(pugi::xml_node param = node.first_child(); param; 
param = param.next_sibling()) {
-                               if(string_iequals(param.name(), "input")) {
-                                       string name;
-                                       if(!xml_read_string(&name, param, 
"name"))
-                                               continue;
-                                       
-                                       SocketType::Type type = 
xml_read_socket_type(param, "type");
-                                       if(type == SocketType::UNDEFINED)
-                                               continue;
-                                       
-                                       osl->add_input(ustring(name).c_str(), 
type);
+                                       snode = 
((OSLShaderManager*)manager)->osl_node(filepath);
+
+                                       if(!snode) {
+                                               fprintf(stderr, "Failed to 
create OSL node from \"%s\".\n", filepath.c_str());
+                                       }
                                }
-                               else if(string_iequals(param.name(), "output")) 
{
-                                       string name;
-                                       if(!xml_read_string(&name, param, 
"name"))
-                                               continue;
-                                       
-                                       SocketType::Type type = 
xml_read_socket_type(param, "type");
-                                       if(type == SocketType::UNDEFINED)
-                                               continue;
-                                       
-                                       osl->add_output(ustring(name).c_str(), 
type);
+                               else {
+                                       fprintf(stderr, "OSL node missing 
\"src\" attribute.\n");
                                }
                        }
-                       
-                       snode = osl;
+                       else {
+                               fprintf(stderr, "OSL node without using 
--shadingsys osl.\n");
+                       }
                }
                else if(string_iequals(node.name(), "sky_texture")) {
                        SkyTextureNode *sky = new SkyTextureNode();
diff --git a/intern/cycles/blender/blender_shader.cpp 
b/intern/cycles/blender/blender_shader.cpp
index 5f16c1b..eb96756 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -148,29 +148,6 @@ static SocketType::Type 
convert_socket_type(BL::NodeSocket& b_socket)
        }
 }
 
-#ifdef WITH_OSL
-static SocketType::Type convert_osl_socket_type(OSL::OSLQuery& query,
-                                                BL::NodeSocket& b_socket)
-{
-       SocketType::Type socket_type = convert_socket_type(b_socket);
-       if(socket_type == SocketType::VECTOR) {
-               /* TODO(sergey): Do we need compatible_name() here? */
-               const OSL::OSLQuery::Parameter *param = 
query.getparam(b_socket.name());
-               assert(param != NULL);
-               if(param != NULL) {
-                       if(param->type.vecsemantics == TypeDesc::POINT) {
-                               socket_type = SocketType::POINT;
-                       }
-                       else if(param->type.vecsemantics == TypeDesc::NORMAL) {
-                               socket_type = SocketType::NORMAL;
-                       }
-               }
-       }
-
-       return socket_type;
-}
-#endif  /* WITH_OSL */
-
 static void set_default_value(ShaderInput *input,
                               BL::NodeSocket& b_sock,
                               BL::BlendData& b_data,
@@ -582,62 +559,17 @@ static ShaderNode *add_node(Scene *scene,
                if(scene->shader_manager->use_osl()) {
                        /* create script node */
                        BL::ShaderNodeScript b_script_node(b_node);
-                       OSLScriptNode *script_node = new OSLScriptNode();
 
                        OSLShaderManager *manager = 
(OSLShaderManager*)scene->shader_manager;
                        string bytecode_hash = b_script_node.bytecode_hash();
 
-                       /* Gather additional information from the shader, such 
as
-                        * input/output type info needed for proper node 
construction.
-                        */
-                       OSL::OSLQuery query;
-                       string absolute_filepath;
-
                        if(!bytecode_hash.empty()) {
-                               query.open_bytecode(b_script_node.bytecode());
+                               node = manager->osl_node("", bytecode_hash, 
b_script_node.bytecode());
                        }
                        else {
-                               absolute_filepath = 
blender_absolute_path(b_data, b_ntree, b_script_node.filepath());
-                               OSLShaderManager::osl_query(query, 
absolute_filepath);
+                               string absolute_filepath = 
blender_absolute_path(b_data, b_ntree, b_script_node.filepath());
+                               node = manager->osl_node(absolute_filepath, "");
                        }
-                       /* TODO(sergey): Add proper query info error parsing. */
-
-                       /* Generate inputs/outputs from node sockets
-                        *
-                        * Note: the node sockets are generated from OSL 
parameters,
-                        * so the names match those of the corresponding 
parameters exactly.
-                        *
-                        * Note 2: ShaderInput/ShaderOutput store shallow 
string copies only!
-                        * So we register them as ustring to ensure the pointer 
stays valid. */
-                       BL::Node::inputs_iterator b_input;
-
-                       for(b_script_node.inputs.begin(b_input); b_input != 
b_script_node.inputs.end(); ++b_input) {
-                               ShaderInput *input = 
script_node->add_input(ustring(b_input->name()).c_str(),
-                                                                           
convert_osl_socket_type(query, *b_input));
-                               set_default_value(input, *b_input, b_data, 
b_ntree);
-                       }
-
-                       BL::Node::outputs_iterator b_output;
-
-                       for(b_script_node.outputs.begin(b_output); b_output != 
b_script_node.outputs.end(); ++b_output) {
-                               
script_node->add_output(ustring(b_output->name()).c_str(),
-                                                       
convert_osl_socket_type(query, *b_output));
-                       }
-
-                       /* load bytecode or filepath */
-                       if(!bytecode_hash.empty()) {
-                               /* loaded bytecode if not already done */
-                               if(!manager->shader_test_loaded(bytecode_hash))
-                                       
manager->shader_load_bytecode(bytecode_hash, b_script_node.bytecode());
-
-                               script_node->bytecode_hash = bytecode_hash;
-                       }
-                       else {
-                               /* set filepath */
-                               script_node->filepath = absolute_filepath;
-                       }
-
-                       node = script_node;
                }
 #else
                (void)b_data;
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index ea68a67..a73204b 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -4516,20 +4516,29 @@ void SetNormalNode::compile(OSLCompiler& compiler)
        compiler.add(this, "node_set_normal"); 
 }
 
-/* OSLScriptNode */
+/* OSLNode */
 
-OSLScriptNode::OSLScriptNode()
-: ShaderNode("osl_script")
+OSLNode::OSLNode()
+: ShaderNode("osl_shader")
 {
        special_type = SHADER_SPECIAL_TYPE_SCRIPT;
 }
 
-void OSLScriptNode::compile(SVMCompiler& /*compiler*/)
+OSLNode::~OSLNode()
+{
+}
+
+OSLNode* OSLNode::create(size_t)
+{
+       return new OSLNode();
+}
+
+void OSLNode::compile(SVMCompiler&)
 {
        /* doesn't work for SVM, obviously ... */
 }
 
-void OSLScriptNode::compile(OSLCompiler& compiler)
+void OSLNode::compile(OSLCompiler& compiler)
 {
        if(!filepath.empty())
                compiler.add(this, filepath.c_str(), true);
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 43dc1dd..9ece9b8 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -966,17 +966,22 @@ public:
        SHADER_NODE_CLASS(SetNormalNode)
 };
 
-class OSLScriptNode : public ShaderNode {
+class OSLNode : public ShaderNode {
 public:
-       SHADER_NODE_CLASS(OSLScriptNode)
+       static OSLNode *create(size_t num_inputs);
+       ~OSLNode();
+
+       SHADER_NODE_BASE_CLASS(OSLNode)
 
        /* ideally we could beter detect this, but we can't query this now */
        bool has_spatial_varying() { return true; }
+       virtual bool equals(const ShaderNode * /*other*/) { return false; }
 
        string filepath;
        string bytecode_hash;
 
-       virtual bool equals(const ShaderNode * /*other*/) { return false; }
+private:
+       OSLNode();
 };
 
 class NormalMapNode : public ShaderNode {
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index c1112ce..1cfe3fb 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -394,16 +394,143 @@ const char *OSLShaderManager::shader_load_bytecode(const 
string& hash, const str
 {
        ss->LoadMemoryCompiledShader(hash.c_str(), bytecode.c_str());
 
-       /* this is a bit weak, but works */
        OSLShaderInfo info;
+
+       if(!info.query.open_bytecode(bytecode)) {
+               fprintf(stderr, "OSL query error: %s\n", 
info.query.geterror().c_str());
+       }
+
+       /* this is a bit weak, but works */
        info.has_surface_emission = (bytecode.find("\"emission\"") != 
string::npos);
        info.has_surface_transparent = (bytecode.find("\"transparent\"") != 
string::npos);
        info.has_surface_bssrdf = (bytecode.find("\"bssrdf\"") != string::npos);
+
        loaded_shaders[hash] = info;
 
        return loaded_shad

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to