add BLI_strcpy_rlen, replace strcat, which was used in misleading way.
[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 };
80
81 /* Enum
82  *
83  * Utility class for enum values. */
84
85 class ShaderEnum {
86 public:
87         bool empty() const { return left.empty(); }
88         void insert(const char *x, int y) {
89                 left[ustring(x)] = y;
90                 right[y] = ustring(x);
91         }
92
93         bool exists(ustring x) { return left.find(x) != left.end(); }
94         bool exists(int y) { return right.find(y) != right.end(); }
95
96         int operator[](const char *x) { return left[ustring(x)]; }
97         int operator[](ustring x) { return left[x]; }
98         ustring operator[](int y) { return right[y]; }
99
100 protected:
101         map<ustring, int> left;
102         map<int, ustring> right;
103 };
104
105 /* Input
106  *
107  * Input socket for a shader node. May be linked to an output or not. If not
108  * linked, it will either get a fixed default value, or e.g. a texture
109  * coordinate. */
110
111 class ShaderInput {
112 public:
113         enum DefaultValue {
114                 TEXTURE_GENERATED,
115                 TEXTURE_UV,
116                 INCOMING,
117                 NORMAL,
118                 POSITION,
119                 TANGENT,
120                 NONE
121         };
122
123         enum Usage {
124                 USE_SVM = 1,
125                 USE_OSL = 2,
126                 USE_ALL = USE_SVM|USE_OSL
127         };
128
129         ShaderInput(ShaderNode *parent, const char *name, ShaderSocketType type);
130         void set(const float3& v) { value = v; }
131         void set(float f) { value = make_float3(f, 0, 0); }
132         void set(const ustring v) { value_string = v; }
133
134         const char *name;
135         ShaderSocketType type;
136
137         ShaderNode *parent;
138         ShaderOutput *link;
139
140         DefaultValue default_value;
141         float3 value;
142         ustring value_string;
143
144         int stack_offset; /* for SVM compiler */
145         int usage;
146 };
147
148 /* Output
149  *
150  * Output socket for a shader node. */
151
152 class ShaderOutput {
153 public:
154         ShaderOutput(ShaderNode *parent, const char *name, ShaderSocketType type);
155
156         const char *name;
157         ShaderNode *parent;
158         ShaderSocketType type;
159
160         vector<ShaderInput*> links;
161
162         int stack_offset; /* for SVM compiler */
163 };
164
165 /* Node
166  *
167  * Shader node in graph, with input and output sockets. This is the virtual
168  * base class for all node types. */
169
170 class ShaderNode {
171 public:
172         ShaderNode(const char *name);
173         virtual ~ShaderNode();
174
175         ShaderInput *input(const char *name);
176         ShaderOutput *output(const char *name);
177
178         ShaderInput *add_input(const char *name, ShaderSocketType type, float value=0.0f, int usage=ShaderInput::USE_ALL);
179         ShaderInput *add_input(const char *name, ShaderSocketType type, float3 value, int usage=ShaderInput::USE_ALL);
180         ShaderInput *add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, int usage=ShaderInput::USE_ALL);
181         ShaderOutput *add_output(const char *name, ShaderSocketType type);
182
183         virtual ShaderNode *clone() const = 0;
184         virtual void attributes(AttributeRequestSet *attributes);
185         virtual void compile(SVMCompiler& compiler) = 0;
186         virtual void compile(OSLCompiler& compiler) = 0;
187
188         virtual bool has_surface_emission() { return false; }
189         virtual bool has_surface_transparent() { return false; }
190         virtual bool has_surface_bssrdf() { return false; }
191
192         vector<ShaderInput*> inputs;
193         vector<ShaderOutput*> outputs;
194
195         ustring name; /* name, not required to be unique */
196         int id; /* index in graph node array */
197         ShaderBump bump; /* for bump mapping utility */
198         
199         ShaderNodeSpecialType special_type;     /* special node type */
200 };
201
202
203 /* Node definition utility macros */
204
205 #define SHADER_NODE_CLASS(type) \
206         type(); \
207         virtual ShaderNode *clone() const { return new type(*this); } \
208         virtual void compile(SVMCompiler& compiler); \
209         virtual void compile(OSLCompiler& compiler); \
210
211 #define SHADER_NODE_NO_CLONE_CLASS(type) \
212         type(); \
213         virtual void compile(SVMCompiler& compiler); \
214         virtual void compile(OSLCompiler& compiler); \
215
216 #define SHADER_NODE_BASE_CLASS(type) \
217         virtual ShaderNode *clone() const { return new type(*this); } \
218         virtual void compile(SVMCompiler& compiler); \
219         virtual void compile(OSLCompiler& compiler); \
220
221 /* Graph
222  *
223  * Shader graph of nodes. Also does graph manipulations for default inputs,
224  * bump mapping from displacement, and possibly other things in the future. */
225
226 class ShaderGraph {
227 public:
228         list<ShaderNode*> nodes;
229         size_t num_node_ids;
230         bool finalized;
231
232         ShaderGraph();
233         ~ShaderGraph();
234
235         ShaderGraph *copy();
236
237         ShaderNode *add(ShaderNode *node);
238         ShaderNode *output();
239
240         void connect(ShaderOutput *from, ShaderInput *to);
241         void disconnect(ShaderInput *to);
242
243         void remove_unneeded_nodes();
244         void finalize(bool do_bump = false, bool do_osl = false, bool do_multi_closure = false);
245
246 protected:
247         typedef pair<ShaderNode* const, ShaderNode*> NodePair;
248
249         void find_dependencies(set<ShaderNode*>& dependencies, ShaderInput *input);
250         void copy_nodes(set<ShaderNode*>& nodes, map<ShaderNode*, ShaderNode*>& nnodemap);
251
252         void break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack);
253         void clean();
254         void bump_from_displacement();
255         void refine_bump_nodes();
256         void default_inputs(bool do_osl);
257         void transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume);
258 };
259
260 CCL_NAMESPACE_END
261
262 #endif /* __GRAPH_H__ */
263