Merged revision(s) 57671-57767 from trunk/blender into soc-2013-dingto
[blender.git] / intern / cycles / render / graph.h
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 #ifndef __GRAPH_H__
20 #define __GRAPH_H__
21
22 #include "kernel_types.h"
23
24 #include "util_list.h"
25 #include "util_map.h"
26 #include "util_param.h"
27 #include "util_set.h"
28 #include "util_types.h"
29 #include "util_vector.h"
30
31 CCL_NAMESPACE_BEGIN
32
33 class AttributeRequestSet;
34 class ShaderInput;
35 class ShaderOutput;
36 class ShaderNode;
37 class ShaderGraph;
38 class SVMCompiler;
39 class OSLCompiler;
40
41 /* Socket Type
42  *
43  * Data type for inputs and outputs */
44
45 enum ShaderSocketType {
46         SHADER_SOCKET_UNDEFINED,
47         
48         SHADER_SOCKET_FLOAT,
49         SHADER_SOCKET_INT,
50         SHADER_SOCKET_COLOR,
51         SHADER_SOCKET_VECTOR,
52         SHADER_SOCKET_POINT,
53         SHADER_SOCKET_NORMAL,
54         SHADER_SOCKET_CLOSURE,
55         SHADER_SOCKET_STRING
56 };
57
58 /* Bump
59  *
60  * For bump mapping, a node may be evaluated multiple times, using different
61  * samples to reconstruct the normal, this indicates the sample position */
62
63 enum ShaderBump {
64         SHADER_BUMP_NONE,
65         SHADER_BUMP_CENTER,
66         SHADER_BUMP_DX,
67         SHADER_BUMP_DY
68 };
69
70 /* Identifiers for some special node types.
71  *
72  * The graph needs to identify these in the clean function.
73  * Cannot use dynamic_cast, as this is disabled for OSL. */
74
75 enum ShaderNodeSpecialType {
76         SHADER_SPECIAL_TYPE_NONE,
77         SHADER_SPECIAL_TYPE_PROXY,
78         SHADER_SPECIAL_TYPE_MIX_CLOSURE,
79         SHADER_SPECIAL_TYPE_AUTOCONVERT
80 };
81
82 /* Enum
83  *
84  * Utility class for enum values. */
85
86 class ShaderEnum {
87 public:
88         bool empty() const { return left.empty(); }
89         void insert(const char *x, int y) {
90                 left[ustring(x)] = y;
91                 right[y] = ustring(x);
92         }
93
94         bool exists(ustring x) { return left.find(x) != left.end(); }
95         bool exists(int y) { return right.find(y) != right.end(); }
96
97         int operator[](const char *x) { return left[ustring(x)]; }
98         int operator[](ustring x) { return left[x]; }
99         ustring operator[](int y) { return right[y]; }
100
101 protected:
102         map<ustring, int> left;
103         map<int, ustring> right;
104 };
105
106 /* Input
107  *
108  * Input socket for a shader node. May be linked to an output or not. If not
109  * linked, it will either get a fixed default value, or e.g. a texture
110  * coordinate. */
111
112 class ShaderInput {
113 public:
114         enum DefaultValue {
115                 TEXTURE_GENERATED,
116                 TEXTURE_UV,
117                 INCOMING,
118                 NORMAL,
119                 POSITION,
120                 TANGENT,
121                 NONE
122         };
123
124         enum Usage {
125                 USE_SVM = 1,
126                 USE_OSL = 2,
127                 USE_ALL = USE_SVM|USE_OSL
128         };
129
130         ShaderInput(ShaderNode *parent, const char *name, ShaderSocketType type);
131         void set(const float3& v) { value = v; }
132         void set(float f) { value = make_float3(f, 0, 0); }
133         void set(const ustring v) { value_string = v; }
134
135         const char *name;
136         ShaderSocketType type;
137
138         ShaderNode *parent;
139         ShaderOutput *link;
140
141         DefaultValue default_value;
142         float3 value;
143         ustring value_string;
144
145         int stack_offset; /* for SVM compiler */
146         int usage;
147 };
148
149 /* Output
150  *
151  * Output socket for a shader node. */
152
153 class ShaderOutput {
154 public:
155         ShaderOutput(ShaderNode *parent, const char *name, ShaderSocketType type);
156
157         const char *name;
158         ShaderNode *parent;
159         ShaderSocketType type;
160
161         vector<ShaderInput*> links;
162
163         int stack_offset; /* for SVM compiler */
164 };
165
166 /* Node
167  *
168  * Shader node in graph, with input and output sockets. This is the virtual
169  * base class for all node types. */
170
171 class ShaderNode {
172 public:
173         ShaderNode(const char *name);
174         virtual ~ShaderNode();
175
176         ShaderInput *input(const char *name);
177         ShaderOutput *output(const char *name);
178
179         ShaderInput *add_input(const char *name, ShaderSocketType type, float value=0.0f, int usage=ShaderInput::USE_ALL);
180         ShaderInput *add_input(const char *name, ShaderSocketType type, float3 value, int usage=ShaderInput::USE_ALL);
181         ShaderInput *add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, int usage=ShaderInput::USE_ALL);
182         ShaderOutput *add_output(const char *name, ShaderSocketType type);
183
184         virtual ShaderNode *clone() const = 0;
185         virtual void attributes(AttributeRequestSet *attributes);
186         virtual void compile(SVMCompiler& compiler) = 0;
187         virtual void compile(OSLCompiler& compiler) = 0;
188
189         virtual bool has_surface_emission() { return false; }
190         virtual bool has_surface_transparent() { return false; }
191         virtual bool has_surface_bssrdf() { return false; }
192         virtual bool has_converter_blackbody() { return false; }
193
194         vector<ShaderInput*> inputs;
195         vector<ShaderOutput*> outputs;
196
197         ustring name; /* name, not required to be unique */
198         int id; /* index in graph node array */
199         ShaderBump bump; /* for bump mapping utility */
200         
201         ShaderNodeSpecialType special_type;     /* special node type */
202 };
203
204
205 /* Node definition utility macros */
206
207 #define SHADER_NODE_CLASS(type) \
208         type(); \
209         virtual ShaderNode *clone() const { return new type(*this); } \
210         virtual void compile(SVMCompiler& compiler); \
211         virtual void compile(OSLCompiler& compiler); \
212
213 #define SHADER_NODE_NO_CLONE_CLASS(type) \
214         type(); \
215         virtual void compile(SVMCompiler& compiler); \
216         virtual void compile(OSLCompiler& compiler); \
217
218 #define SHADER_NODE_BASE_CLASS(type) \
219         virtual ShaderNode *clone() const { return new type(*this); } \
220         virtual void compile(SVMCompiler& compiler); \
221         virtual void compile(OSLCompiler& compiler); \
222
223 /* Graph
224  *
225  * Shader graph of nodes. Also does graph manipulations for default inputs,
226  * bump mapping from displacement, and possibly other things in the future. */
227
228 class ShaderGraph {
229 public:
230         list<ShaderNode*> nodes;
231         size_t num_node_ids;
232         bool finalized;
233
234         ShaderGraph();
235         ~ShaderGraph();
236
237         ShaderGraph *copy();
238
239         ShaderNode *add(ShaderNode *node);
240         ShaderNode *output();
241
242         void connect(ShaderOutput *from, ShaderInput *to);
243         void disconnect(ShaderInput *to);
244
245         void remove_unneeded_nodes();
246         void finalize(bool do_bump = false, bool do_osl = false, bool do_multi_closure = false);
247
248 protected:
249         typedef pair<ShaderNode* const, ShaderNode*> NodePair;
250
251         void find_dependencies(set<ShaderNode*>& dependencies, ShaderInput *input);
252         void copy_nodes(set<ShaderNode*>& nodes, map<ShaderNode*, ShaderNode*>& nnodemap);
253
254         void break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack);
255         void clean();
256         void bump_from_displacement();
257         void refine_bump_nodes();
258         void default_inputs(bool do_osl);
259         void transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume);
260 };
261
262 CCL_NAMESPACE_END
263
264 #endif /* __GRAPH_H__ */
265