Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/blender/addon/osl.py')
-rw-r--r--intern/cycles/blender/addon/osl.py127
1 files changed, 127 insertions, 0 deletions
diff --git a/intern/cycles/blender/addon/osl.py b/intern/cycles/blender/addon/osl.py
new file mode 100644
index 00000000000..aac1e2422b9
--- /dev/null
+++ b/intern/cycles/blender/addon/osl.py
@@ -0,0 +1,127 @@
+#
+# 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.
+#
+
+# <pep8 compliant>
+
+import bpy, _cycles, os, tempfile
+
+# compile .osl file with given filepath to temporary .oso file
+def osl_compile(input_path, report):
+ output_file = tempfile.NamedTemporaryFile(mode='w', suffix=".oso", delete=False)
+ output_path = output_file.name
+ output_file.close()
+
+ ok = _cycles.osl_compile(input_path, output_path)
+
+ if ok:
+ report({'INFO'}, "OSL shader compilation succeeded")
+
+ return ok, output_path
+
+# compile and update shader script node
+def update_script_node(node, report):
+ import os, shutil
+
+ if node.mode == 'EXTERNAL':
+ # compile external script file
+ script_path = bpy.path.abspath(node.filepath, library=node.id_data.library)
+ script_path_noext, script_ext = os.path.splitext(script_path)
+
+ if script_ext == ".oso":
+ # it's a .oso file, no need to compile
+ ok, oso_path = True, script_path
+ oso_file_remove = False
+ elif script_ext == ".osl":
+ # compile .osl file
+ ok, oso_path = osl_compile(script_path, report)
+ oso_file_remove = True
+
+ if ok:
+ # copy .oso from temporary path to .osl directory
+ dst_path = script_path_noext + ".oso"
+ try:
+ shutil.copy2(oso_path, dst_path)
+ except:
+ report({'ERROR'}, "Failed to write .oso file next to external .osl file at " + dst_path)
+ elif os.path.dirname(node.filepath) == "":
+ # module in search path
+ oso_path = node.filepath
+ oso_file_remove = False
+ ok = True
+ else:
+ # unknown
+ report({'ERROR'}, "External shader script must have .osl or .oso extension, or be a module name")
+ ok = False
+
+ if ok:
+ node.bytecode = ""
+ node.bytecode_hash = ""
+
+ elif node.mode == 'INTERNAL' and node.script:
+ # internal script, we will store bytecode in the node
+ script = node.script
+ osl_path = bpy.path.abspath(script.filepath, library=script.library)
+
+ if script.is_in_memory or script.is_dirty or script.is_modified or not os.path.exists(osl_path):
+ # write text datablock contents to temporary file
+ osl_file = tempfile.NamedTemporaryFile(mode='w', suffix=".osl", delete=True)
+ osl_file.write(script.as_string())
+ osl_file.flush()
+ ok, oso_path = osl_compile(osl_file.name, report)
+ oso_file_remove = False
+ osl_file.close()
+ else:
+ # compile text datablock from disk directly
+ ok, oso_path = osl_compile(osl_path, report)
+ oso_file_remove = False
+
+ if ok:
+ # read bytecode
+ try:
+ oso = open(oso_path, 'r')
+ node.bytecode = oso.read()
+ oso.close()
+ except:
+ import traceback
+ traceback.print_exc()
+
+ report({'ERROR'}, "Can't read OSO bytecode to store in node at %r" % oso_path)
+ ok = False
+
+ else:
+ report({'WARNING'}, "No text or file specified in node, nothing to compile")
+ return
+
+ if ok:
+ # now update node with new sockets
+ ok = _cycles.osl_update_node(node.id_data.as_pointer(), node.as_pointer(), oso_path)
+
+ if not ok:
+ report({'ERROR'}, "OSL query failed to open " + oso_path)
+ else:
+ report({'ERROR'}, "OSL script compilation failed, see console for errors")
+
+ # remove temporary oso file
+ if oso_file_remove:
+ try:
+ os.remove(oso_path)
+ except:
+ pass
+
+ return ok
+