Code refactor: minor node and node type utility functions and changes.
This commit is contained in:
@@ -36,12 +36,8 @@ Node::Node(const NodeType *type_, ustring name_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* initialize default values */
|
/* initialize default values */
|
||||||
typedef unordered_map<ustring, SocketType, ustringHash> map_type;
|
foreach(const SocketType& socket, type->inputs) {
|
||||||
foreach(const map_type::value_type& it, type->inputs) {
|
set_default_value(socket);
|
||||||
const SocketType& socket = it.second;
|
|
||||||
const void *src = socket.default_value;
|
|
||||||
void *dst = ((char*)this) + socket.struct_offset;
|
|
||||||
memcpy(dst, src, socket.size());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,7 +293,8 @@ const array<Node*>& Node::get_node_array(const SocketType& input) const
|
|||||||
return get_socket_value<array<Node*> >(this, input);
|
return get_socket_value<array<Node*> >(this, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* default values */
|
/* generic value operations */
|
||||||
|
|
||||||
bool Node::has_default_value(const SocketType& input) const
|
bool Node::has_default_value(const SocketType& input) const
|
||||||
{
|
{
|
||||||
const void *src = input.default_value;
|
const void *src = input.default_value;
|
||||||
@@ -305,6 +302,48 @@ bool Node::has_default_value(const SocketType& input) const
|
|||||||
return memcmp(dst, src, input.size()) == 0;
|
return memcmp(dst, src, input.size()) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Node::set_default_value(const SocketType& socket)
|
||||||
|
{
|
||||||
|
const void *src = socket.default_value;
|
||||||
|
void *dst = ((char*)this) + socket.struct_offset;
|
||||||
|
memcpy(dst, src, socket.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static void copy_array(const Node *node, const SocketType& socket, const Node *other, const SocketType& other_socket)
|
||||||
|
{
|
||||||
|
const array<T>* src = (const array<T>*)(((char*)other) + other_socket.struct_offset);
|
||||||
|
array<T>* dst = (array<T>*)(((char*)node) + socket.struct_offset);
|
||||||
|
*dst = *src;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::copy_value(const SocketType& socket, const Node& other, const SocketType& other_socket)
|
||||||
|
{
|
||||||
|
assert(socket.type == other_socket.type);
|
||||||
|
|
||||||
|
if(socket.is_array()) {
|
||||||
|
switch(socket.type) {
|
||||||
|
case SocketType::BOOLEAN_ARRAY: copy_array<bool>(this, socket, &other, other_socket); break;
|
||||||
|
case SocketType::FLOAT_ARRAY: copy_array<float>(this, socket, &other, other_socket); break;
|
||||||
|
case SocketType::INT_ARRAY: copy_array<int>(this, socket, &other, other_socket); break;
|
||||||
|
case SocketType::COLOR_ARRAY: copy_array<float3>(this, socket, &other, other_socket); break;
|
||||||
|
case SocketType::VECTOR_ARRAY: copy_array<float3>(this, socket, &other, other_socket); break;
|
||||||
|
case SocketType::POINT_ARRAY: copy_array<float3>(this, socket, &other, other_socket); break;
|
||||||
|
case SocketType::NORMAL_ARRAY: copy_array<float3>(this, socket, &other, other_socket); break;
|
||||||
|
case SocketType::POINT2_ARRAY: copy_array<float2>(this, socket, &other, other_socket); break;
|
||||||
|
case SocketType::STRING_ARRAY: copy_array<ustring>(this, socket, &other, other_socket); break;
|
||||||
|
case SocketType::TRANSFORM_ARRAY: copy_array<Transform>(this, socket, &other, other_socket); break;
|
||||||
|
case SocketType::NODE_ARRAY: copy_array<void*>(this, socket, &other, other_socket); break;
|
||||||
|
default: assert(0); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const void *src = ((char*)&other) + other_socket.struct_offset;
|
||||||
|
void *dst = ((char*)this) + socket.struct_offset;
|
||||||
|
memcpy(dst, src, socket.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static bool is_array_equal(const Node *node, const Node *other, const SocketType& socket)
|
static bool is_array_equal(const Node *node, const Node *other, const SocketType& socket)
|
||||||
{
|
{
|
||||||
@@ -313,48 +352,43 @@ static bool is_array_equal(const Node *node, const Node *other, const SocketType
|
|||||||
return *a == *b;
|
return *a == *b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* modified */
|
bool Node::equals_value(const Node& other, const SocketType& socket) const
|
||||||
bool Node::modified(const Node& other)
|
{
|
||||||
|
if(socket.is_array()) {
|
||||||
|
switch(socket.type) {
|
||||||
|
case SocketType::BOOLEAN_ARRAY: return is_array_equal<bool>(this, &other, socket);
|
||||||
|
case SocketType::FLOAT_ARRAY: return is_array_equal<float>(this, &other, socket);
|
||||||
|
case SocketType::INT_ARRAY: return is_array_equal<int>(this, &other, socket);
|
||||||
|
case SocketType::COLOR_ARRAY: return is_array_equal<float3>(this, &other, socket);
|
||||||
|
case SocketType::VECTOR_ARRAY: return is_array_equal<float3>(this, &other, socket);
|
||||||
|
case SocketType::POINT_ARRAY: return is_array_equal<float3>(this, &other, socket);
|
||||||
|
case SocketType::NORMAL_ARRAY: return is_array_equal<float3>(this, &other, socket);
|
||||||
|
case SocketType::POINT2_ARRAY: return is_array_equal<float2>(this, &other, socket);
|
||||||
|
case SocketType::STRING_ARRAY: return is_array_equal<ustring>(this, &other, socket);
|
||||||
|
case SocketType::TRANSFORM_ARRAY: return is_array_equal<Transform>(this, &other, socket);
|
||||||
|
case SocketType::NODE_ARRAY: return is_array_equal<void*>(this, &other, socket);
|
||||||
|
default: assert(0); return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const void *a = ((char*)this) + socket.struct_offset;
|
||||||
|
const void *b = ((char*)&other) + socket.struct_offset;
|
||||||
|
return (memcmp(a, b, socket.size()) == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* equals */
|
||||||
|
|
||||||
|
bool Node::equals(const Node& other) const
|
||||||
{
|
{
|
||||||
assert(type == other.type);
|
assert(type == other.type);
|
||||||
|
|
||||||
typedef unordered_map<ustring, SocketType, ustringHash> map_type;
|
foreach(const SocketType& socket, type->inputs) {
|
||||||
foreach(const map_type::value_type& it, type->inputs) {
|
if(!equals_value(other, socket))
|
||||||
const SocketType& socket = it.second;
|
return false;
|
||||||
|
|
||||||
if(socket.is_array()) {
|
|
||||||
bool equal = true;
|
|
||||||
|
|
||||||
switch(socket.type)
|
|
||||||
{
|
|
||||||
case SocketType::BOOLEAN_ARRAY: equal = is_array_equal<bool>(this, &other, socket); break;
|
|
||||||
case SocketType::FLOAT_ARRAY: equal = is_array_equal<float>(this, &other, socket); break;
|
|
||||||
case SocketType::INT_ARRAY: equal = is_array_equal<int>(this, &other, socket); break;
|
|
||||||
case SocketType::COLOR_ARRAY: equal = is_array_equal<float3>(this, &other, socket); break;
|
|
||||||
case SocketType::VECTOR_ARRAY: equal = is_array_equal<float3>(this, &other, socket); break;
|
|
||||||
case SocketType::POINT_ARRAY: equal = is_array_equal<float3>(this, &other, socket); break;
|
|
||||||
case SocketType::NORMAL_ARRAY: equal = is_array_equal<float3>(this, &other, socket); break;
|
|
||||||
case SocketType::POINT2_ARRAY: equal = is_array_equal<float2>(this, &other, socket); break;
|
|
||||||
case SocketType::STRING_ARRAY: equal = is_array_equal<ustring>(this, &other, socket); break;
|
|
||||||
case SocketType::TRANSFORM_ARRAY: equal = is_array_equal<Transform>(this, &other, socket); break;
|
|
||||||
case SocketType::NODE_ARRAY: equal = is_array_equal<void*>(this, &other, socket); break;
|
|
||||||
default: assert(0); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!equal) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const void *a = ((char*)this) + socket.struct_offset;
|
|
||||||
const void *b = ((char*)&other) + socket.struct_offset;
|
|
||||||
if(memcmp(a, b, socket.size()) != 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
@@ -77,11 +77,14 @@ struct Node
|
|||||||
const array<Transform>& get_transform_array(const SocketType& input) const;
|
const array<Transform>& get_transform_array(const SocketType& input) const;
|
||||||
const array<Node*>& get_node_array(const SocketType& input) const;
|
const array<Node*>& get_node_array(const SocketType& input) const;
|
||||||
|
|
||||||
/* default values */
|
/* generic values operations */
|
||||||
bool has_default_value(const SocketType& input) const;
|
bool has_default_value(const SocketType& input) const;
|
||||||
|
void set_default_value(const SocketType& input);
|
||||||
|
bool equals_value(const Node& other, const SocketType& input) const;
|
||||||
|
void copy_value(const SocketType& input, const Node& other, const SocketType& other_input);
|
||||||
|
|
||||||
/* modified */
|
/* equals */
|
||||||
bool modified(const Node& other);
|
bool equals(const Node& other) const;
|
||||||
|
|
||||||
ustring name;
|
ustring name;
|
||||||
const NodeType *type;
|
const NodeType *type;
|
||||||
|
@@ -114,9 +114,15 @@ ustring SocketType::type_name(Type type)
|
|||||||
return names[(int)type];
|
return names[(int)type];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SocketType::is_float3(Type type)
|
||||||
|
{
|
||||||
|
return (type == COLOR || type == VECTOR || type == POINT || type == NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Node Type */
|
/* Node Type */
|
||||||
|
|
||||||
NodeType::NodeType()
|
NodeType::NodeType(Type type_)
|
||||||
|
: type(type_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +143,7 @@ void NodeType::register_input(ustring name, ustring ui_name, SocketType::Type ty
|
|||||||
socket.enum_values = enum_values;
|
socket.enum_values = enum_values;
|
||||||
socket.node_type = node_type;
|
socket.node_type = node_type;
|
||||||
socket.flags = flags | extra_flags;
|
socket.flags = flags | extra_flags;
|
||||||
inputs[name] = socket;
|
inputs.push_back(socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeType::register_output(ustring name, ustring ui_name, SocketType::Type type)
|
void NodeType::register_output(ustring name, ustring ui_name, SocketType::Type type)
|
||||||
@@ -151,7 +157,29 @@ void NodeType::register_output(ustring name, ustring ui_name, SocketType::Type t
|
|||||||
socket.enum_values = NULL;
|
socket.enum_values = NULL;
|
||||||
socket.node_type = NULL;
|
socket.node_type = NULL;
|
||||||
socket.flags = SocketType::LINKABLE;
|
socket.flags = SocketType::LINKABLE;
|
||||||
outputs[name] = socket;
|
outputs.push_back(socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SocketType *NodeType::find_input(ustring name) const
|
||||||
|
{
|
||||||
|
foreach(const SocketType& socket, inputs) {
|
||||||
|
if(socket.name == name) {
|
||||||
|
return &socket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SocketType *NodeType::find_output(ustring name) const
|
||||||
|
{
|
||||||
|
foreach(const SocketType& socket, outputs) {
|
||||||
|
if(socket.name == name) {
|
||||||
|
return &socket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Node Type Registry */
|
/* Node Type Registry */
|
||||||
@@ -162,7 +190,7 @@ unordered_map<ustring, NodeType, ustringHash>& NodeType::types()
|
|||||||
return _types;
|
return _types;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeType *NodeType::add(const char *name_, CreateFunc create_)
|
NodeType *NodeType::add(const char *name_, CreateFunc create_, Type type_)
|
||||||
{
|
{
|
||||||
ustring name(name_);
|
ustring name(name_);
|
||||||
|
|
||||||
@@ -172,7 +200,7 @@ NodeType *NodeType::add(const char *name_, CreateFunc create_)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
types()[name] = NodeType();
|
types()[name] = NodeType(type_);
|
||||||
|
|
||||||
NodeType *type = &types()[name];
|
NodeType *type = &types()[name];
|
||||||
type->name = name;
|
type->name = name;
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
#include "util_map.h"
|
#include "util_map.h"
|
||||||
#include "util_param.h"
|
#include "util_param.h"
|
||||||
#include "util_string.h"
|
#include "util_string.h"
|
||||||
|
#include "util_vector.h"
|
||||||
|
|
||||||
CCL_NAMESPACE_BEGIN
|
CCL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
@@ -94,13 +95,19 @@ struct SocketType
|
|||||||
static size_t max_size();
|
static size_t max_size();
|
||||||
static ustring type_name(Type type);
|
static ustring type_name(Type type);
|
||||||
static void *zero_default_value();
|
static void *zero_default_value();
|
||||||
|
static bool is_float3(Type type);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Node Type */
|
/* Node Type */
|
||||||
|
|
||||||
struct NodeType
|
struct NodeType
|
||||||
{
|
{
|
||||||
explicit NodeType();
|
enum Type {
|
||||||
|
NONE,
|
||||||
|
SHADER
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit NodeType(Type type = NONE);
|
||||||
~NodeType();
|
~NodeType();
|
||||||
|
|
||||||
void register_input(ustring name, ustring ui_name, SocketType::Type type,
|
void register_input(ustring name, ustring ui_name, SocketType::Type type,
|
||||||
@@ -110,15 +117,18 @@ struct NodeType
|
|||||||
int flags = 0, int extra_flags = 0);
|
int flags = 0, int extra_flags = 0);
|
||||||
void register_output(ustring name, ustring ui_name, SocketType::Type type);
|
void register_output(ustring name, ustring ui_name, SocketType::Type type);
|
||||||
|
|
||||||
|
const SocketType *find_input(ustring name) const;
|
||||||
|
const SocketType *find_output(ustring name) const;
|
||||||
|
|
||||||
typedef Node *(*CreateFunc)(const NodeType *type);
|
typedef Node *(*CreateFunc)(const NodeType *type);
|
||||||
typedef unordered_map<ustring, SocketType, ustringHash> SocketMap;
|
|
||||||
|
|
||||||
ustring name;
|
ustring name;
|
||||||
SocketMap inputs;
|
Type type;
|
||||||
SocketMap outputs;
|
std::vector<SocketType> inputs;
|
||||||
|
std::vector<SocketType> outputs;
|
||||||
CreateFunc create;
|
CreateFunc create;
|
||||||
|
|
||||||
static NodeType *add(const char *name, CreateFunc create);
|
static NodeType *add(const char *name, CreateFunc create, Type type = NONE);
|
||||||
static const NodeType *find(ustring name);
|
static const NodeType *find(ustring name);
|
||||||
static unordered_map<ustring, NodeType, ustringHash>& types();
|
static unordered_map<ustring, NodeType, ustringHash>& types();
|
||||||
};
|
};
|
||||||
|
@@ -58,9 +58,7 @@ void xml_read_node(XMLReader& reader, Node *node, pugi::xml_node xml_node)
|
|||||||
node->name = ustring(name_attr.value());
|
node->name = ustring(name_attr.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(const NodeType::SocketMap::value_type& it, node->type->inputs) {
|
foreach(const SocketType& socket, node->type->inputs) {
|
||||||
const SocketType& socket = it.second;
|
|
||||||
|
|
||||||
if(socket.type == SocketType::CLOSURE || socket.type == SocketType::UNDEFINED) {
|
if(socket.type == SocketType::CLOSURE || socket.type == SocketType::UNDEFINED) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -257,9 +255,7 @@ pugi::xml_node xml_write_node(Node *node, pugi::xml_node xml_root)
|
|||||||
|
|
||||||
xml_node.append_attribute("name") = node->name.c_str();
|
xml_node.append_attribute("name") = node->name.c_str();
|
||||||
|
|
||||||
foreach(const NodeType::SocketMap::value_type& it, node->type->inputs) {
|
foreach(const SocketType& socket, node->type->inputs) {
|
||||||
const SocketType& socket = it.second;
|
|
||||||
|
|
||||||
if(socket.type == SocketType::CLOSURE || socket.type == SocketType::UNDEFINED) {
|
if(socket.type == SocketType::CLOSURE || socket.type == SocketType::UNDEFINED) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@@ -116,6 +116,11 @@ void Background::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Background::modified(const Background& background)
|
||||||
|
{
|
||||||
|
return !Node::equals(background);
|
||||||
|
}
|
||||||
|
|
||||||
void Background::tag_update(Scene *scene)
|
void Background::tag_update(Scene *scene)
|
||||||
{
|
{
|
||||||
scene->integrator->tag_update(scene);
|
scene->integrator->tag_update(scene);
|
||||||
|
@@ -50,6 +50,7 @@ public:
|
|||||||
void device_update(Device *device, DeviceScene *dscene, Scene *scene);
|
void device_update(Device *device, DeviceScene *dscene, Scene *scene);
|
||||||
void device_free(Device *device, DeviceScene *dscene);
|
void device_free(Device *device, DeviceScene *dscene);
|
||||||
|
|
||||||
|
bool modified(const Background& background);
|
||||||
void tag_update(Scene *scene);
|
void tag_update(Scene *scene);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -482,6 +482,11 @@ void Camera::device_free(Device * /*device*/,
|
|||||||
scene->lookup_tables->remove_table(&shutter_table_offset);
|
scene->lookup_tables->remove_table(&shutter_table_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Camera::modified(const Camera& cam)
|
||||||
|
{
|
||||||
|
return !Node::equals(cam);
|
||||||
|
}
|
||||||
|
|
||||||
bool Camera::motion_modified(const Camera& cam)
|
bool Camera::motion_modified(const Camera& cam)
|
||||||
{
|
{
|
||||||
return !((motion == cam.motion) &&
|
return !((motion == cam.motion) &&
|
||||||
|
@@ -181,6 +181,7 @@ public:
|
|||||||
void device_update_volume(Device *device, DeviceScene *dscene, Scene *scene);
|
void device_update_volume(Device *device, DeviceScene *dscene, Scene *scene);
|
||||||
void device_free(Device *device, DeviceScene *dscene, Scene *scene);
|
void device_free(Device *device, DeviceScene *dscene, Scene *scene);
|
||||||
|
|
||||||
|
bool modified(const Camera& cam);
|
||||||
bool motion_modified(const Camera& cam);
|
bool motion_modified(const Camera& cam);
|
||||||
void tag_update();
|
void tag_update();
|
||||||
|
|
||||||
|
@@ -465,7 +465,7 @@ void Film::device_free(Device * /*device*/,
|
|||||||
|
|
||||||
bool Film::modified(const Film& film)
|
bool Film::modified(const Film& film)
|
||||||
{
|
{
|
||||||
return Node::modified(film) || !Pass::equals(passes, film.passes);
|
return !Node::equals(film) || !Pass::equals(passes, film.passes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Film::tag_passes_update(Scene *scene, const array<Pass>& passes_)
|
void Film::tag_passes_update(Scene *scene, const array<Pass>& passes_)
|
||||||
|
@@ -204,6 +204,11 @@ void Integrator::device_free(Device *device, DeviceScene *dscene)
|
|||||||
dscene->sobol_directions.clear();
|
dscene->sobol_directions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Integrator::modified(const Integrator& integrator)
|
||||||
|
{
|
||||||
|
return !Node::equals(integrator);
|
||||||
|
}
|
||||||
|
|
||||||
void Integrator::tag_update(Scene *scene)
|
void Integrator::tag_update(Scene *scene)
|
||||||
{
|
{
|
||||||
foreach(Shader *shader, scene->shaders) {
|
foreach(Shader *shader, scene->shaders) {
|
||||||
|
@@ -86,6 +86,7 @@ public:
|
|||||||
void device_update(Device *device, DeviceScene *dscene, Scene *scene);
|
void device_update(Device *device, DeviceScene *dscene, Scene *scene);
|
||||||
void device_free(Device *device, DeviceScene *dscene);
|
void device_free(Device *device, DeviceScene *dscene);
|
||||||
|
|
||||||
|
bool modified(const Integrator& integrator);
|
||||||
void tag_update(Scene *scene);
|
void tag_update(Scene *scene);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user