Fix incorrect FLT_MIN use
[blender.git] / intern / cycles / render / graph.h
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef __GRAPH_H__
18 #define __GRAPH_H__
19
20 #include "kernel_types.h"
21
22 #include "util_list.h"
23 #include "util_map.h"
24 #include "util_param.h"
25 #include "util_set.h"
26 #include "util_types.h"
27 #include "util_vector.h"
28
29 CCL_NAMESPACE_BEGIN
30
31 class AttributeRequestSet;
32 class Scene;
33 class Shader;
34 class ShaderInput;
35 class ShaderOutput;
36 class ShaderNode;
37 class ShaderGraph;
38 class SVMCompiler;
39 class OSLCompiler;
40 class OutputNode;
41
42 /* Socket Type
43  *
44  * Data type for inputs and outputs */
45
46 enum ShaderSocketType {
47         SHADER_SOCKET_UNDEFINED,
48         
49         SHADER_SOCKET_FLOAT,
50         SHADER_SOCKET_INT,
51         SHADER_SOCKET_COLOR,
52         SHADER_SOCKET_VECTOR,
53         SHADER_SOCKET_POINT,
54         SHADER_SOCKET_NORMAL,
55         SHADER_SOCKET_CLOSURE,
56         SHADER_SOCKET_STRING
57 };
58
59 /* Bump
60  *
61  * For bump mapping, a node may be evaluated multiple times, using different
62  * samples to reconstruct the normal, this indicates the sample position */
63
64 enum ShaderBump {
65         SHADER_BUMP_NONE,
66         SHADER_BUMP_CENTER,
67         SHADER_BUMP_DX,
68         SHADER_BUMP_DY
69 };
70
71 /* Identifiers for some special node types.
72  *
73  * The graph needs to identify these in the clean function.
74  * Cannot use dynamic_cast, as this is disabled for OSL. */
75
76 enum ShaderNodeSpecialType {
77         SHADER_SPECIAL_TYPE_NONE,
78         SHADER_SPECIAL_TYPE_PROXY,
79         SHADER_SPECIAL_TYPE_AUTOCONVERT,
80         SHADER_SPECIAL_TYPE_GEOMETRY,
81         SHADER_SPECIAL_TYPE_SCRIPT,
82         SHADER_SPECIAL_TYPE_IMAGE_SLOT,
83         SHADER_SPECIAL_TYPE_CLOSURE,
84         SHADER_SPECIAL_TYPE_COMBINE_CLOSURE,
85         SHADER_SPECIAL_TYPE_OUTPUT,
86         SHADER_SPECIAL_TYPE_BUMP,
87 };
88
89 /* Enum
90  *
91  * Utility class for enum values. */
92
93 class ShaderEnum {
94 public:
95         bool empty() const { return left.empty(); }
96         void insert(const char *x, int y) {
97                 left[ustring(x)] = y;
98                 right[y] = ustring(x);
99         }
100
101         bool exists(ustring x) { return left.find(x) != left.end(); }
102         bool exists(int y) { return right.find(y) != right.end(); }
103
104         int operator[](const char *x) { return left[ustring(x)]; }
105         int operator[](ustring x) { return left[x]; }
106         ustring operator[](int y) { return right[y]; }
107
108 protected:
109         map<ustring, int> left;
110         map<int, ustring> right;
111 };
112
113 /* Input
114  *
115  * Input socket for a shader node. May be linked to an output or not. If not
116  * linked, it will either get a fixed default value, or e.g. a texture
117  * coordinate. */
118
119 class ShaderInput {
120 public:
121         enum DefaultValue {
122                 TEXTURE_GENERATED,
123                 TEXTURE_UV,
124                 INCOMING,
125                 NORMAL,
126                 POSITION,
127                 TANGENT,
128                 NONE
129         };
130
131         enum Usage {
132                 USE_SVM = 1,
133                 USE_OSL = 2,
134                 USE_ALL = USE_SVM|USE_OSL
135         };
136
137         ShaderInput(ShaderNode *parent, const char *name, ShaderSocketType type);
138         void set(const float3& v) { value = v; }
139         void set(float f) { value = make_float3(f, 0, 0); }
140         void set(const ustring v) { value_string = v; }
141
142         const char *name;
143         ShaderSocketType type;
144
145         ShaderNode *parent;
146         ShaderOutput *link;
147
148         DefaultValue default_value;
149         float3 value;
150         ustring value_string;
151
152         int stack_offset; /* for SVM compiler */
153         int usage;
154 };
155
156 /* Output
157  *
158  * Output socket for a shader node. */
159
160 class ShaderOutput {
161 public:
162         ShaderOutput(ShaderNode *parent, const char *name, ShaderSocketType type);
163
164         const char *name;
165         ShaderNode *parent;
166         ShaderSocketType type;
167
168         vector<ShaderInput*> links;
169
170         int stack_offset; /* for SVM compiler */
171 };
172
173 /* Node
174  *
175  * Shader node in graph, with input and output sockets. This is the virtual
176  * base class for all node types. */
177
178 class ShaderNode {
179 public:
180         ShaderNode(const char *name);
181         virtual ~ShaderNode();
182
183         ShaderInput *input(const char *name);
184         ShaderOutput *output(const char *name);
185
186         ShaderInput *add_input(const char *name, ShaderSocketType type, float value=0.0f, int usage=ShaderInput::USE_ALL);
187         ShaderInput *add_input(const char *name, ShaderSocketType type, float3 value, int usage=ShaderInput::USE_ALL);
188         ShaderInput *add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, int usage=ShaderInput::USE_ALL);
189         ShaderOutput *add_output(const char *name, ShaderSocketType type);
190
191         virtual ShaderNode *clone() const = 0;
192         virtual void attributes(Shader *shader, AttributeRequestSet *attributes);
193         virtual void compile(SVMCompiler& compiler) = 0;
194         virtual void compile(OSLCompiler& compiler) = 0;
195
196         /* ** Node optimization ** */
197         /* Check whether the node can be replaced with single constant. */
198         virtual bool constant_fold(ShaderGraph * /*graph*/, ShaderOutput * /*socket*/, float3 * /*optimized_value*/) { return false; }
199
200         /* Simplify settings used by artists to the ones which are simpler to
201          * evaluate in the kernel but keep the final result unchanged.
202          */
203         virtual void simplify_settings(Scene * /*scene*/) {};
204
205         virtual bool has_surface_emission() { return false; }
206         virtual bool has_surface_transparent() { return false; }
207         virtual bool has_surface_bssrdf() { return false; }
208         virtual bool has_bssrdf_bump() { return false; }
209         virtual bool has_spatial_varying() { return false; }
210         virtual bool has_object_dependency() { return false; }
211         virtual bool has_integrator_dependency() { return false; }
212
213         vector<ShaderInput*> inputs;
214         vector<ShaderOutput*> outputs;
215
216         ustring name; /* name, not required to be unique */
217         int id; /* index in graph node array */
218         ShaderBump bump; /* for bump mapping utility */
219         
220         ShaderNodeSpecialType special_type;     /* special node type */
221
222         /* ** Selective nodes compilation ** */
223
224         /* TODO(sergey): More explicitly mention in the function names
225          * that those functions are for selective compilation only?
226          */
227
228         /* Nodes are split into several groups, group of level 0 contains
229          * nodes which are most commonly used, further levels are extension
230          * of previous one and includes less commonly used nodes.
231          */
232         virtual int get_group() { return NODE_GROUP_LEVEL_0; }
233
234         /* Node feature are used to disable huge nodes inside the group,
235          * so it's possible to disable huge nodes inside of the required
236          * nodes group.
237          */
238         virtual int get_feature() { return bump == SHADER_BUMP_NONE ? 0 : NODE_FEATURE_BUMP; }
239
240         /* Check whether settings of the node equals to another one.
241          *
242          * This is mainly used to check whether two nodes can be merged
243          * together. Meaning, runtime stuff like node id and unbound slots
244          * will be ignored for comparison.
245          *
246          * NOTE: If some node can't be de-duplicated for whatever reason it
247          * is to be handled in the subclass.
248          */
249         virtual bool equals(const ShaderNode *other)
250         {
251                 return name == other->name &&
252                        bump == other->bump;
253         }
254 };
255
256
257 /* Node definition utility macros */
258
259 #define SHADER_NODE_CLASS(type) \
260         type(); \
261         virtual ShaderNode *clone() const { return new type(*this); } \
262         virtual void compile(SVMCompiler& compiler); \
263         virtual void compile(OSLCompiler& compiler); \
264
265 #define SHADER_NODE_NO_CLONE_CLASS(type) \
266         type(); \
267         virtual void compile(SVMCompiler& compiler); \
268         virtual void compile(OSLCompiler& compiler); \
269
270 #define SHADER_NODE_BASE_CLASS(type) \
271         virtual ShaderNode *clone() const { return new type(*this); } \
272         virtual void compile(SVMCompiler& compiler); \
273         virtual void compile(OSLCompiler& compiler); \
274
275 class ShaderNodeIDComparator
276 {
277 public:
278         bool operator()(const ShaderNode *n1, const ShaderNode *n2) const
279         {
280                 return n1->id < n2->id;
281         }
282 };
283
284 typedef set<ShaderNode*, ShaderNodeIDComparator> ShaderNodeSet;
285 typedef map<ShaderNode*, ShaderNode*, ShaderNodeIDComparator> ShaderNodeMap;
286
287 /* Graph
288  *
289  * Shader graph of nodes. Also does graph manipulations for default inputs,
290  * bump mapping from displacement, and possibly other things in the future. */
291
292 class ShaderGraph {
293 public:
294         list<ShaderNode*> nodes;
295         size_t num_node_ids;
296         bool finalized;
297
298         ShaderGraph();
299         ~ShaderGraph();
300
301         ShaderGraph *copy();
302
303         ShaderNode *add(ShaderNode *node);
304         OutputNode *output();
305
306         void connect(ShaderOutput *from, ShaderInput *to);
307         void disconnect(ShaderInput *to);
308         void relink(ShaderNode *node, ShaderOutput *from, ShaderOutput *to);
309
310         void remove_proxy_nodes();
311         void finalize(Scene *scene,
312                       bool do_bump = false,
313                       bool do_osl = false,
314                       bool do_simplify = false);
315
316         int get_num_closures();
317
318         void dump_graph(const char *filename);
319
320 protected:
321         typedef pair<ShaderNode* const, ShaderNode*> NodePair;
322
323         void find_dependencies(ShaderNodeSet& dependencies, ShaderInput *input);
324         void clear_nodes();
325         void copy_nodes(ShaderNodeSet& nodes, ShaderNodeMap& nnodemap);
326
327         void break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack);
328         void bump_from_displacement();
329         void refine_bump_nodes();
330         void default_inputs(bool do_osl);
331         void transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume);
332
333         /* Graph simplification routines. */
334         void clean(Scene *scene);
335         void constant_fold();
336         void simplify_settings(Scene *scene);
337         void deduplicate_nodes();
338 };
339
340 CCL_NAMESPACE_END
341
342 #endif /* __GRAPH_H__ */
343