blender/intern/cycles/render/graph.h

269 lines
6.7 KiB
C++

/*
* Copyright 2011-2013 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
#ifndef __GRAPH_H__
#define __GRAPH_H__
#include "kernel_types.h"
#include "util_list.h"
#include "util_map.h"
#include "util_param.h"
#include "util_set.h"
#include "util_types.h"
#include "util_vector.h"
CCL_NAMESPACE_BEGIN
class AttributeRequestSet;
class Shader;
class ShaderInput;
class ShaderOutput;
class ShaderNode;
class ShaderGraph;
class SVMCompiler;
class OSLCompiler;
class OutputNode;
/* Socket Type
*
* Data type for inputs and outputs */
enum ShaderSocketType {
SHADER_SOCKET_UNDEFINED,
SHADER_SOCKET_FLOAT,
SHADER_SOCKET_INT,
SHADER_SOCKET_COLOR,
SHADER_SOCKET_VECTOR,
SHADER_SOCKET_POINT,
SHADER_SOCKET_NORMAL,
SHADER_SOCKET_CLOSURE,
SHADER_SOCKET_STRING
};
/* Bump
*
* For bump mapping, a node may be evaluated multiple times, using different
* samples to reconstruct the normal, this indicates the sample position */
enum ShaderBump {
SHADER_BUMP_NONE,
SHADER_BUMP_CENTER,
SHADER_BUMP_DX,
SHADER_BUMP_DY
};
/* Identifiers for some special node types.
*
* The graph needs to identify these in the clean function.
* Cannot use dynamic_cast, as this is disabled for OSL. */
enum ShaderNodeSpecialType {
SHADER_SPECIAL_TYPE_NONE,
SHADER_SPECIAL_TYPE_PROXY,
SHADER_SPECIAL_TYPE_MIX_CLOSURE,
SHADER_SPECIAL_TYPE_AUTOCONVERT,
SHADER_SPECIAL_TYPE_GEOMETRY,
SHADER_SPECIAL_TYPE_SCRIPT
};
/* Enum
*
* Utility class for enum values. */
class ShaderEnum {
public:
bool empty() const { return left.empty(); }
void insert(const char *x, int y) {
left[ustring(x)] = y;
right[y] = ustring(x);
}
bool exists(ustring x) { return left.find(x) != left.end(); }
bool exists(int y) { return right.find(y) != right.end(); }
int operator[](const char *x) { return left[ustring(x)]; }
int operator[](ustring x) { return left[x]; }
ustring operator[](int y) { return right[y]; }
protected:
map<ustring, int> left;
map<int, ustring> right;
};
/* Input
*
* Input socket for a shader node. May be linked to an output or not. If not
* linked, it will either get a fixed default value, or e.g. a texture
* coordinate. */
class ShaderInput {
public:
enum DefaultValue {
TEXTURE_GENERATED,
TEXTURE_UV,
INCOMING,
NORMAL,
POSITION,
TANGENT,
NONE
};
enum Usage {
USE_SVM = 1,
USE_OSL = 2,
USE_ALL = USE_SVM|USE_OSL
};
ShaderInput(ShaderNode *parent, const char *name, ShaderSocketType type);
void set(const float3& v) { value = v; }
void set(float f) { value = make_float3(f, 0, 0); }
void set(const ustring v) { value_string = v; }
const char *name;
ShaderSocketType type;
ShaderNode *parent;
ShaderOutput *link;
DefaultValue default_value;
float3 value;
ustring value_string;
int stack_offset; /* for SVM compiler */
int usage;
};
/* Output
*
* Output socket for a shader node. */
class ShaderOutput {
public:
ShaderOutput(ShaderNode *parent, const char *name, ShaderSocketType type);
const char *name;
ShaderNode *parent;
ShaderSocketType type;
vector<ShaderInput*> links;
int stack_offset; /* for SVM compiler */
};
/* Node
*
* Shader node in graph, with input and output sockets. This is the virtual
* base class for all node types. */
class ShaderNode {
public:
ShaderNode(const char *name);
virtual ~ShaderNode();
ShaderInput *input(const char *name);
ShaderOutput *output(const char *name);
ShaderInput *add_input(const char *name, ShaderSocketType type, float value=0.0f, int usage=ShaderInput::USE_ALL);
ShaderInput *add_input(const char *name, ShaderSocketType type, float3 value, int usage=ShaderInput::USE_ALL);
ShaderInput *add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, int usage=ShaderInput::USE_ALL);
ShaderOutput *add_output(const char *name, ShaderSocketType type);
virtual ShaderNode *clone() const = 0;
virtual void attributes(Shader *shader, AttributeRequestSet *attributes);
virtual void compile(SVMCompiler& compiler) = 0;
virtual void compile(OSLCompiler& compiler) = 0;
virtual bool has_surface_emission() { return false; }
virtual bool has_surface_transparent() { return false; }
virtual bool has_surface_bssrdf() { return false; }
virtual bool has_converter_blackbody() { return false; }
virtual bool has_bssrdf_bump() { return false; }
vector<ShaderInput*> inputs;
vector<ShaderOutput*> outputs;
ustring name; /* name, not required to be unique */
int id; /* index in graph node array */
ShaderBump bump; /* for bump mapping utility */
ShaderNodeSpecialType special_type; /* special node type */
};
/* Node definition utility macros */
#define SHADER_NODE_CLASS(type) \
type(); \
virtual ShaderNode *clone() const { return new type(*this); } \
virtual void compile(SVMCompiler& compiler); \
virtual void compile(OSLCompiler& compiler); \
#define SHADER_NODE_NO_CLONE_CLASS(type) \
type(); \
virtual void compile(SVMCompiler& compiler); \
virtual void compile(OSLCompiler& compiler); \
#define SHADER_NODE_BASE_CLASS(type) \
virtual ShaderNode *clone() const { return new type(*this); } \
virtual void compile(SVMCompiler& compiler); \
virtual void compile(OSLCompiler& compiler); \
/* Graph
*
* Shader graph of nodes. Also does graph manipulations for default inputs,
* bump mapping from displacement, and possibly other things in the future. */
class ShaderGraph {
public:
list<ShaderNode*> nodes;
size_t num_node_ids;
bool finalized;
ShaderGraph();
~ShaderGraph();
ShaderGraph *copy();
ShaderNode *add(ShaderNode *node);
OutputNode *output();
void connect(ShaderOutput *from, ShaderInput *to);
void disconnect(ShaderInput *to);
void remove_unneeded_nodes();
void finalize(bool do_bump = false, bool do_osl = false, bool do_multi_closure = false);
protected:
typedef pair<ShaderNode* const, ShaderNode*> NodePair;
void find_dependencies(set<ShaderNode*>& dependencies, ShaderInput *input);
void copy_nodes(set<ShaderNode*>& nodes, map<ShaderNode*, ShaderNode*>& nnodemap);
void break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack);
void clean();
void bump_from_displacement();
void refine_bump_nodes();
void default_inputs(bool do_osl);
void transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume);
};
CCL_NAMESPACE_END
#endif /* __GRAPH_H__ */