~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to intern/cycles/blender/addon/osl.py

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# Copyright 2011, Blender Foundation.
 
3
#
 
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.
 
8
#
 
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.
 
13
#
 
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.
 
17
#
 
18
 
 
19
# <pep8 compliant>
 
20
 
 
21
import bpy
 
22
import _cycles
 
23
 
 
24
 
 
25
def osl_compile(input_path, report):
 
26
    """compile .osl file with given filepath to temporary .oso file"""
 
27
    import tempfile
 
28
    output_file = tempfile.NamedTemporaryFile(mode='w', suffix=".oso", delete=False)
 
29
    output_path = output_file.name
 
30
    output_file.close()
 
31
 
 
32
    ok = _cycles.osl_compile(input_path, output_path)
 
33
 
 
34
    if ok:
 
35
        report({'INFO'}, "OSL shader compilation succeeded")
 
36
 
 
37
    return ok, output_path
 
38
 
 
39
 
 
40
def update_script_node(node, report):
 
41
    """compile and update shader script node"""
 
42
    import os
 
43
    import shutil
 
44
    import tempfile
 
45
 
 
46
    if node.mode == 'EXTERNAL':
 
47
        # compile external script file
 
48
        script_path = bpy.path.abspath(node.filepath, library=node.id_data.library)
 
49
        script_path_noext, script_ext = os.path.splitext(script_path)
 
50
 
 
51
        if script_ext == ".oso":
 
52
            # it's a .oso file, no need to compile
 
53
            ok, oso_path = True, script_path
 
54
            oso_file_remove = False
 
55
        elif script_ext == ".osl":
 
56
            # compile .osl file
 
57
            ok, oso_path = osl_compile(script_path, report)
 
58
            oso_file_remove = True
 
59
 
 
60
            if ok:
 
61
                # copy .oso from temporary path to .osl directory
 
62
                dst_path = script_path_noext + ".oso"
 
63
                try:
 
64
                    shutil.copy2(oso_path, dst_path)
 
65
                except:
 
66
                    report({'ERROR'}, "Failed to write .oso file next to external .osl file at " + dst_path)
 
67
        elif os.path.dirname(node.filepath) == "":
 
68
            # module in search path
 
69
            oso_path = node.filepath
 
70
            oso_file_remove = False
 
71
            ok = True
 
72
        else:
 
73
            # unknown
 
74
            report({'ERROR'}, "External shader script must have .osl or .oso extension, or be a module name")
 
75
            ok = False
 
76
 
 
77
        if ok:
 
78
            node.bytecode = ""
 
79
            node.bytecode_hash = ""
 
80
 
 
81
    elif node.mode == 'INTERNAL' and node.script:
 
82
        # internal script, we will store bytecode in the node
 
83
        script = node.script
 
84
        osl_path = bpy.path.abspath(script.filepath, library=script.library)
 
85
 
 
86
        if script.is_in_memory or script.is_dirty or script.is_modified or not os.path.exists(osl_path):
 
87
            # write text datablock contents to temporary file
 
88
            osl_file = tempfile.NamedTemporaryFile(mode='w', suffix=".osl", delete=False)
 
89
            osl_file.write(script.as_string())
 
90
            osl_file.close()
 
91
 
 
92
            ok, oso_path = osl_compile(osl_file.name, report)
 
93
            oso_file_remove = False
 
94
            os.remove(osl_file.name)
 
95
        else:
 
96
            # compile text datablock from disk directly
 
97
            ok, oso_path = osl_compile(osl_path, report)
 
98
            oso_file_remove = False
 
99
 
 
100
        if ok:
 
101
            # read bytecode
 
102
            try:
 
103
                oso = open(oso_path, 'r')
 
104
                node.bytecode = oso.read()
 
105
                oso.close()
 
106
            except:
 
107
                import traceback
 
108
                traceback.print_exc()
 
109
 
 
110
                report({'ERROR'}, "Can't read OSO bytecode to store in node at %r" % oso_path)
 
111
                ok = False
 
112
 
 
113
    else:
 
114
        report({'WARNING'}, "No text or file specified in node, nothing to compile")
 
115
        return
 
116
 
 
117
    if ok:
 
118
        # now update node with new sockets
 
119
        ok = _cycles.osl_update_node(node.id_data.as_pointer(), node.as_pointer(), oso_path)
 
120
 
 
121
        if not ok:
 
122
            report({'ERROR'}, "OSL query failed to open " + oso_path)
 
123
    else:
 
124
        report({'ERROR'}, "OSL script compilation failed, see console for errors")
 
125
 
 
126
    # remove temporary oso file
 
127
    if oso_file_remove:
 
128
        try:
 
129
            os.remove(oso_path)
 
130
        except:
 
131
            pass
 
132
 
 
133
    return ok