Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/graph/node.cpp
| Show All 33 Lines | |||||
| { | { | ||||
| assert(type); | assert(type); | ||||
| owner = nullptr; | owner = nullptr; | ||||
| tag_modified(); | tag_modified(); | ||||
| /* assign non-empty name, convenient for debugging */ | /* assign non-empty name, convenient for debugging */ | ||||
| if (name.empty()) { | if (name.empty()) { | ||||
| name = type->name; | name = type->get_name(); | ||||
| } | } | ||||
| /* initialize default values */ | /* initialize default values */ | ||||
| foreach (const SocketType &socket, type->inputs) { | foreach (const SocketType &socket, type->get_inputs()) { | ||||
| set_default_value(socket); | set_default_value(socket); | ||||
| } | } | ||||
| } | } | ||||
| Node::~Node() | Node::~Node() | ||||
| { | { | ||||
| } | } | ||||
| #ifndef NDEBUG | #ifndef NDEBUG | ||||
| static bool is_socket_float3(const SocketType &socket) | static bool is_socket_float3(const SocketType &socket) | ||||
| { | { | ||||
| return socket.type == SocketType::COLOR || socket.type == SocketType::POINT || | return socket.get_type() == SocketType::COLOR || socket.get_type() == SocketType::POINT || | ||||
| socket.type == SocketType::VECTOR || socket.type == SocketType::NORMAL; | socket.get_type() == SocketType::VECTOR || socket.get_type() == SocketType::NORMAL; | ||||
| } | } | ||||
| static bool is_socket_array_float3(const SocketType &socket) | static bool is_socket_array_float3(const SocketType &socket) | ||||
| { | { | ||||
| return socket.type == SocketType::COLOR_ARRAY || socket.type == SocketType::POINT_ARRAY || | return socket.get_type() == SocketType::COLOR_ARRAY || | ||||
| socket.type == SocketType::VECTOR_ARRAY || socket.type == SocketType::NORMAL_ARRAY; | socket.get_type() == SocketType::POINT_ARRAY || | ||||
| socket.get_type() == SocketType::VECTOR_ARRAY || | |||||
| socket.get_type() == SocketType::NORMAL_ARRAY; | |||||
| } | } | ||||
| #endif | #endif | ||||
| /* set values */ | /* set values */ | ||||
| void Node::set(const SocketType &input, bool value) | void Node::set(const SocketType &input, bool value) | ||||
| { | { | ||||
| assert(input.type == SocketType::BOOLEAN); | assert(input.get_type() == SocketType::BOOLEAN); | ||||
| set_if_different(input, value); | set_if_different(input, value); | ||||
| } | } | ||||
| void Node::set(const SocketType &input, int value) | void Node::set(const SocketType &input, int value) | ||||
| { | { | ||||
| assert((input.type == SocketType::INT || input.type == SocketType::ENUM)); | assert((input.get_type() == SocketType::INT || input.get_type() == SocketType::ENUM)); | ||||
| set_if_different(input, value); | set_if_different(input, value); | ||||
| } | } | ||||
| void Node::set(const SocketType &input, uint value) | void Node::set(const SocketType &input, uint value) | ||||
| { | { | ||||
| assert(input.type == SocketType::UINT); | assert(input.get_type() == SocketType::UINT); | ||||
| set_if_different(input, value); | set_if_different(input, value); | ||||
| } | } | ||||
| void Node::set(const SocketType &input, float value) | void Node::set(const SocketType &input, float value) | ||||
| { | { | ||||
| assert(input.type == SocketType::FLOAT); | assert(input.get_type() == SocketType::FLOAT); | ||||
| set_if_different(input, value); | set_if_different(input, value); | ||||
| } | } | ||||
| void Node::set(const SocketType &input, float2 value) | void Node::set(const SocketType &input, float2 value) | ||||
| { | { | ||||
| assert(input.type == SocketType::POINT2); | assert(input.get_type() == SocketType::POINT2); | ||||
| set_if_different(input, value); | set_if_different(input, value); | ||||
| } | } | ||||
| void Node::set(const SocketType &input, float3 value) | void Node::set(const SocketType &input, float3 value) | ||||
| { | { | ||||
| assert(is_socket_float3(input)); | assert(is_socket_float3(input)); | ||||
| set_if_different(input, value); | set_if_different(input, value); | ||||
| } | } | ||||
| void Node::set(const SocketType &input, const char *value) | void Node::set(const SocketType &input, const char *value) | ||||
| { | { | ||||
| set(input, ustring(value)); | set(input, ustring(value)); | ||||
| } | } | ||||
| void Node::set(const SocketType &input, ustring value) | void Node::set(const SocketType &input, ustring value) | ||||
| { | { | ||||
| if (input.type == SocketType::STRING) { | if (input.get_type() == SocketType::STRING) { | ||||
| set_if_different(input, value); | set_if_different(input, value); | ||||
| } | } | ||||
| else if (input.type == SocketType::ENUM) { | else if (input.get_type() == SocketType::ENUM) { | ||||
| const NodeEnum &enm = *input.enum_values; | const NodeEnum &enm = *input.get_enum_values(); | ||||
| if (enm.exists(value)) { | if (enm.exists(value)) { | ||||
| set_if_different(input, enm[value]); | set_if_different(input, enm[value]); | ||||
| } | } | ||||
| else { | else { | ||||
| assert(0); | assert(0); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| assert(0); | assert(0); | ||||
| } | } | ||||
| } | } | ||||
| void Node::set(const SocketType &input, const Transform &value) | void Node::set(const SocketType &input, const Transform &value) | ||||
| { | { | ||||
| assert(input.type == SocketType::TRANSFORM); | assert(input.get_type() == SocketType::TRANSFORM); | ||||
| set_if_different(input, value); | set_if_different(input, value); | ||||
| } | } | ||||
| void Node::set(const SocketType &input, Node *value) | void Node::set(const SocketType &input, Node *value) | ||||
| { | { | ||||
| assert(input.type == SocketType::NODE); | assert(input.get_type() == SocketType::NODE); | ||||
| set_if_different(input, value); | set_if_different(input, value); | ||||
| } | } | ||||
| /* set array values */ | /* set array values */ | ||||
| void Node::set(const SocketType &input, array<bool> &value) | void Node::set(const SocketType &input, array<bool> &value) | ||||
| { | { | ||||
| assert(input.type == SocketType::BOOLEAN_ARRAY); | assert(input.get_type() == SocketType::BOOLEAN_ARRAY); | ||||
| set_if_different(input, value); | set_if_different(input, value); | ||||
| } | } | ||||
| void Node::set(const SocketType &input, array<int> &value) | void Node::set(const SocketType &input, array<int> &value) | ||||
| { | { | ||||
| assert(input.type == SocketType::INT_ARRAY); | assert(input.get_type() == SocketType::INT_ARRAY); | ||||
| set_if_different(input, value); | set_if_different(input, value); | ||||
| } | } | ||||
| void Node::set(const SocketType &input, array<float> &value) | void Node::set(const SocketType &input, array<float> &value) | ||||
| { | { | ||||
| assert(input.type == SocketType::FLOAT_ARRAY); | assert(input.get_type() == SocketType::FLOAT_ARRAY); | ||||
| set_if_different(input, value); | set_if_different(input, value); | ||||
| } | } | ||||
| void Node::set(const SocketType &input, array<float2> &value) | void Node::set(const SocketType &input, array<float2> &value) | ||||
| { | { | ||||
| assert(input.type == SocketType::POINT2_ARRAY); | assert(input.get_type() == SocketType::POINT2_ARRAY); | ||||
| set_if_different(input, value); | set_if_different(input, value); | ||||
| } | } | ||||
| void Node::set(const SocketType &input, array<float3> &value) | void Node::set(const SocketType &input, array<float3> &value) | ||||
| { | { | ||||
| assert(is_socket_array_float3(input)); | assert(is_socket_array_float3(input)); | ||||
| set_if_different(input, value); | set_if_different(input, value); | ||||
| } | } | ||||
| void Node::set(const SocketType &input, array<ustring> &value) | void Node::set(const SocketType &input, array<ustring> &value) | ||||
| { | { | ||||
| assert(input.type == SocketType::STRING_ARRAY); | assert(input.get_type() == SocketType::STRING_ARRAY); | ||||
| set_if_different(input, value); | set_if_different(input, value); | ||||
| } | } | ||||
| void Node::set(const SocketType &input, array<Transform> &value) | void Node::set(const SocketType &input, array<Transform> &value) | ||||
| { | { | ||||
| assert(input.type == SocketType::TRANSFORM_ARRAY); | assert(input.get_type() == SocketType::TRANSFORM_ARRAY); | ||||
| set_if_different(input, value); | set_if_different(input, value); | ||||
| } | } | ||||
| void Node::set(const SocketType &input, array<Node *> &value) | void Node::set(const SocketType &input, array<Node *> &value) | ||||
| { | { | ||||
| assert(input.type == SocketType::NODE_ARRAY); | assert(input.get_type() == SocketType::NODE_ARRAY); | ||||
| set_if_different(input, value); | set_if_different(input, value); | ||||
| } | } | ||||
| /* get values */ | /* get values */ | ||||
| bool Node::get_bool(const SocketType &input) const | bool Node::get_bool(const SocketType &input) const | ||||
| { | { | ||||
| assert(input.type == SocketType::BOOLEAN); | assert(input.get_type() == SocketType::BOOLEAN); | ||||
| return get_socket_value<bool>(this, input); | return get_socket_value<bool>(this, input); | ||||
| } | } | ||||
| int Node::get_int(const SocketType &input) const | int Node::get_int(const SocketType &input) const | ||||
| { | { | ||||
| assert(input.type == SocketType::INT || input.type == SocketType::ENUM); | assert(input.get_type() == SocketType::INT || input.get_type() == SocketType::ENUM); | ||||
| return get_socket_value<int>(this, input); | return get_socket_value<int>(this, input); | ||||
| } | } | ||||
| uint Node::get_uint(const SocketType &input) const | uint Node::get_uint(const SocketType &input) const | ||||
| { | { | ||||
| assert(input.type == SocketType::UINT); | assert(input.get_type() == SocketType::UINT); | ||||
| return get_socket_value<uint>(this, input); | return get_socket_value<uint>(this, input); | ||||
| } | } | ||||
| float Node::get_float(const SocketType &input) const | float Node::get_float(const SocketType &input) const | ||||
| { | { | ||||
| assert(input.type == SocketType::FLOAT); | assert(input.get_type() == SocketType::FLOAT); | ||||
| return get_socket_value<float>(this, input); | return get_socket_value<float>(this, input); | ||||
| } | } | ||||
| float2 Node::get_float2(const SocketType &input) const | float2 Node::get_float2(const SocketType &input) const | ||||
| { | { | ||||
| assert(input.type == SocketType::POINT2); | assert(input.get_type() == SocketType::POINT2); | ||||
| return get_socket_value<float2>(this, input); | return get_socket_value<float2>(this, input); | ||||
| } | } | ||||
| float3 Node::get_float3(const SocketType &input) const | float3 Node::get_float3(const SocketType &input) const | ||||
| { | { | ||||
| assert(is_socket_float3(input)); | assert(is_socket_float3(input)); | ||||
| return get_socket_value<float3>(this, input); | return get_socket_value<float3>(this, input); | ||||
| } | } | ||||
| ustring Node::get_string(const SocketType &input) const | ustring Node::get_string(const SocketType &input) const | ||||
| { | { | ||||
| if (input.type == SocketType::STRING) { | if (input.get_type() == SocketType::STRING) { | ||||
| return get_socket_value<ustring>(this, input); | return get_socket_value<ustring>(this, input); | ||||
| } | } | ||||
| else if (input.type == SocketType::ENUM) { | else if (input.get_type() == SocketType::ENUM) { | ||||
| const NodeEnum &enm = *input.enum_values; | const NodeEnum &enm = *input.get_enum_values(); | ||||
| int intvalue = get_socket_value<int>(this, input); | int intvalue = get_socket_value<int>(this, input); | ||||
| return (enm.exists(intvalue)) ? enm[intvalue] : ustring(); | return (enm.exists(intvalue)) ? enm[intvalue] : ustring(); | ||||
| } | } | ||||
| else { | else { | ||||
| assert(0); | assert(0); | ||||
| return ustring(); | return ustring(); | ||||
| } | } | ||||
| } | } | ||||
| Transform Node::get_transform(const SocketType &input) const | Transform Node::get_transform(const SocketType &input) const | ||||
| { | { | ||||
| assert(input.type == SocketType::TRANSFORM); | assert(input.get_type() == SocketType::TRANSFORM); | ||||
| return get_socket_value<Transform>(this, input); | return get_socket_value<Transform>(this, input); | ||||
| } | } | ||||
| Node *Node::get_node(const SocketType &input) const | Node *Node::get_node(const SocketType &input) const | ||||
| { | { | ||||
| assert(input.type == SocketType::NODE); | assert(input.get_type() == SocketType::NODE); | ||||
| return get_socket_value<Node *>(this, input); | return get_socket_value<Node *>(this, input); | ||||
| } | } | ||||
| /* get array values */ | /* get array values */ | ||||
| const array<bool> &Node::get_bool_array(const SocketType &input) const | const array<bool> &Node::get_bool_array(const SocketType &input) const | ||||
| { | { | ||||
| assert(input.type == SocketType::BOOLEAN_ARRAY); | assert(input.get_type() == SocketType::BOOLEAN_ARRAY); | ||||
| return get_socket_value<array<bool>>(this, input); | return get_socket_value<array<bool>>(this, input); | ||||
| } | } | ||||
| const array<int> &Node::get_int_array(const SocketType &input) const | const array<int> &Node::get_int_array(const SocketType &input) const | ||||
| { | { | ||||
| assert(input.type == SocketType::INT_ARRAY); | assert(input.get_type() == SocketType::INT_ARRAY); | ||||
| return get_socket_value<array<int>>(this, input); | return get_socket_value<array<int>>(this, input); | ||||
| } | } | ||||
| const array<float> &Node::get_float_array(const SocketType &input) const | const array<float> &Node::get_float_array(const SocketType &input) const | ||||
| { | { | ||||
| assert(input.type == SocketType::FLOAT_ARRAY); | assert(input.get_type() == SocketType::FLOAT_ARRAY); | ||||
| return get_socket_value<array<float>>(this, input); | return get_socket_value<array<float>>(this, input); | ||||
| } | } | ||||
| const array<float2> &Node::get_float2_array(const SocketType &input) const | const array<float2> &Node::get_float2_array(const SocketType &input) const | ||||
| { | { | ||||
| assert(input.type == SocketType::POINT2_ARRAY); | assert(input.get_type() == SocketType::POINT2_ARRAY); | ||||
| return get_socket_value<array<float2>>(this, input); | return get_socket_value<array<float2>>(this, input); | ||||
| } | } | ||||
| const array<float3> &Node::get_float3_array(const SocketType &input) const | const array<float3> &Node::get_float3_array(const SocketType &input) const | ||||
| { | { | ||||
| assert(is_socket_array_float3(input)); | assert(is_socket_array_float3(input)); | ||||
| return get_socket_value<array<float3>>(this, input); | return get_socket_value<array<float3>>(this, input); | ||||
| } | } | ||||
| const array<ustring> &Node::get_string_array(const SocketType &input) const | const array<ustring> &Node::get_string_array(const SocketType &input) const | ||||
| { | { | ||||
| assert(input.type == SocketType::STRING_ARRAY); | assert(input.get_type() == SocketType::STRING_ARRAY); | ||||
| return get_socket_value<array<ustring>>(this, input); | return get_socket_value<array<ustring>>(this, input); | ||||
| } | } | ||||
| const array<Transform> &Node::get_transform_array(const SocketType &input) const | const array<Transform> &Node::get_transform_array(const SocketType &input) const | ||||
| { | { | ||||
| assert(input.type == SocketType::TRANSFORM_ARRAY); | assert(input.get_type() == SocketType::TRANSFORM_ARRAY); | ||||
| return get_socket_value<array<Transform>>(this, input); | return get_socket_value<array<Transform>>(this, input); | ||||
| } | } | ||||
| const array<Node *> &Node::get_node_array(const SocketType &input) const | const array<Node *> &Node::get_node_array(const SocketType &input) const | ||||
| { | { | ||||
| assert(input.type == SocketType::NODE_ARRAY); | assert(input.get_type() == SocketType::NODE_ARRAY); | ||||
| return get_socket_value<array<Node *>>(this, input); | return get_socket_value<array<Node *>>(this, input); | ||||
| } | } | ||||
| /* generic value operations */ | /* 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.get_default_value(); | ||||
| void *dst = &get_socket_value<char>(this, input); | void *dst = &get_socket_value<char>(this, input); | ||||
| return memcmp(dst, src, input.size()) == 0; | return memcmp(dst, src, input.size()) == 0; | ||||
| } | } | ||||
| void Node::set_default_value(const SocketType &socket) | void Node::set_default_value(const SocketType &socket) | ||||
| { | { | ||||
| const void *src = socket.default_value; | const void *src = socket.get_default_value(); | ||||
| void *dst = ((char *)this) + socket.struct_offset; | void *dst = ((char *)this) + socket.get_struct_offset(); | ||||
| if (socket.size() > 0) { | if (socket.size() > 0) { | ||||
| memcpy(dst, src, socket.size()); | memcpy(dst, src, socket.size()); | ||||
| } | } | ||||
| } | } | ||||
| template<typename T> | template<typename T> | ||||
| static void copy_array(const Node *node, | static void copy_array(const Node *node, | ||||
| const SocketType &socket, | const SocketType &socket, | ||||
| const Node *other, | const Node *other, | ||||
| const SocketType &other_socket) | const SocketType &other_socket) | ||||
| { | { | ||||
| const array<T> *src = (const array<T> *)(((char *)other) + other_socket.struct_offset); | const array<T> *src = (const array<T> *)(((char *)other) + other_socket.get_struct_offset()); | ||||
| array<T> *dst = (array<T> *)(((char *)node) + socket.struct_offset); | array<T> *dst = (array<T> *)(((char *)node) + socket.get_struct_offset()); | ||||
| *dst = *src; | *dst = *src; | ||||
| } | } | ||||
| void Node::copy_value(const SocketType &socket, const Node &other, const SocketType &other_socket) | void Node::copy_value(const SocketType &socket, const Node &other, const SocketType &other_socket) | ||||
| { | { | ||||
| assert(socket.type == other_socket.type); | assert(socket.get_type() == other_socket.get_type()); | ||||
| if (socket.is_array()) { | if (socket.is_array()) { | ||||
| switch (socket.type) { | switch (socket.get_type()) { | ||||
| case SocketType::BOOLEAN_ARRAY: | case SocketType::BOOLEAN_ARRAY: | ||||
| copy_array<bool>(this, socket, &other, other_socket); | copy_array<bool>(this, socket, &other, other_socket); | ||||
| break; | break; | ||||
| case SocketType::FLOAT_ARRAY: | case SocketType::FLOAT_ARRAY: | ||||
| copy_array<float>(this, socket, &other, other_socket); | copy_array<float>(this, socket, &other, other_socket); | ||||
| break; | break; | ||||
| case SocketType::INT_ARRAY: | case SocketType::INT_ARRAY: | ||||
| copy_array<int>(this, socket, &other, other_socket); | copy_array<int>(this, socket, &other, other_socket); | ||||
| Show All 23 Lines | switch (socket.get_type()) { | ||||
| copy_array<void *>(this, socket, &other, other_socket); | copy_array<void *>(this, socket, &other, other_socket); | ||||
| break; | break; | ||||
| default: | default: | ||||
| assert(0); | assert(0); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| const void *src = ((char *)&other) + other_socket.struct_offset; | const void *src = ((char *)&other) + other_socket.get_struct_offset(); | ||||
| void *dst = ((char *)this) + socket.struct_offset; | void *dst = ((char *)this) + socket.get_struct_offset(); | ||||
| memcpy(dst, src, socket.size()); | memcpy(dst, src, socket.size()); | ||||
| } | } | ||||
| } | } | ||||
| void Node::set_value(const SocketType &socket, const Node &other, const SocketType &other_socket) | void Node::set_value(const SocketType &socket, const Node &other, const SocketType &other_socket) | ||||
| { | { | ||||
| assert(socket.type == other_socket.type); | assert(socket.get_type() == other_socket.get_type()); | ||||
| (void)other_socket; | (void)other_socket; | ||||
| if (socket.is_array()) { | if (socket.is_array()) { | ||||
| switch (socket.type) { | switch (socket.get_type()) { | ||||
| case SocketType::BOOLEAN_ARRAY: | case SocketType::BOOLEAN_ARRAY: | ||||
| set(socket, get_socket_value<array<bool>>(&other, socket)); | set(socket, get_socket_value<array<bool>>(&other, socket)); | ||||
| break; | break; | ||||
| case SocketType::FLOAT_ARRAY: | case SocketType::FLOAT_ARRAY: | ||||
| set(socket, get_socket_value<array<float>>(&other, socket)); | set(socket, get_socket_value<array<float>>(&other, socket)); | ||||
| break; | break; | ||||
| case SocketType::INT_ARRAY: | case SocketType::INT_ARRAY: | ||||
| set(socket, get_socket_value<array<int>>(&other, socket)); | set(socket, get_socket_value<array<int>>(&other, socket)); | ||||
| Show All 17 Lines | switch (socket.get_type()) { | ||||
| set(socket, get_socket_value<array<Node *>>(&other, socket)); | set(socket, get_socket_value<array<Node *>>(&other, socket)); | ||||
| break; | break; | ||||
| default: | default: | ||||
| assert(0); | assert(0); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| switch (socket.type) { | switch (socket.get_type()) { | ||||
| case SocketType::BOOLEAN: | case SocketType::BOOLEAN: | ||||
| set(socket, get_socket_value<bool>(&other, socket)); | set(socket, get_socket_value<bool>(&other, socket)); | ||||
| break; | break; | ||||
| case SocketType::FLOAT: | case SocketType::FLOAT: | ||||
| set(socket, get_socket_value<float>(&other, socket)); | set(socket, get_socket_value<float>(&other, socket)); | ||||
| break; | break; | ||||
| case SocketType::INT: | case SocketType::INT: | ||||
| set(socket, get_socket_value<int>(&other, socket)); | set(socket, get_socket_value<int>(&other, socket)); | ||||
| Show All 27 Lines | switch (socket.get_type()) { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| 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) | ||||
| { | { | ||||
| const array<T> *a = (const array<T> *)(((char *)node) + socket.struct_offset); | const array<T> *a = (const array<T> *)(((char *)node) + socket.get_struct_offset()); | ||||
| const array<T> *b = (const array<T> *)(((char *)other) + socket.struct_offset); | const array<T> *b = (const array<T> *)(((char *)other) + socket.get_struct_offset()); | ||||
| return *a == *b; | return *a == *b; | ||||
| } | } | ||||
| template<typename T> | template<typename T> | ||||
| static bool is_value_equal(const Node *node, const Node *other, const SocketType &socket) | static bool is_value_equal(const Node *node, const Node *other, const SocketType &socket) | ||||
| { | { | ||||
| const T *a = (const T *)(((char *)node) + socket.struct_offset); | const T *a = (const T *)(((char *)node) + socket.get_struct_offset()); | ||||
| const T *b = (const T *)(((char *)other) + socket.struct_offset); | const T *b = (const T *)(((char *)other) + socket.get_struct_offset()); | ||||
| return *a == *b; | return *a == *b; | ||||
| } | } | ||||
| bool Node::equals_value(const Node &other, const SocketType &socket) const | bool Node::equals_value(const Node &other, const SocketType &socket) const | ||||
| { | { | ||||
| switch (socket.type) { | switch (socket.get_type()) { | ||||
| case SocketType::BOOLEAN: | case SocketType::BOOLEAN: | ||||
| return is_value_equal<bool>(this, &other, socket); | return is_value_equal<bool>(this, &other, socket); | ||||
| case SocketType::FLOAT: | case SocketType::FLOAT: | ||||
| return is_value_equal<float>(this, &other, socket); | return is_value_equal<float>(this, &other, socket); | ||||
| case SocketType::INT: | case SocketType::INT: | ||||
| return is_value_equal<int>(this, &other, socket); | return is_value_equal<int>(this, &other, socket); | ||||
| case SocketType::UINT: | case SocketType::UINT: | ||||
| return is_value_equal<uint>(this, &other, socket); | return is_value_equal<uint>(this, &other, socket); | ||||
| ▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | bool Node::equals_value(const Node &other, const SocketType &socket) const | ||||
| return true; | return true; | ||||
| } | } | ||||
| /* equals */ | /* equals */ | ||||
| bool Node::equals(const Node &other) const | bool Node::equals(const Node &other) const | ||||
| { | { | ||||
| assert(type == other.type); | assert(type == other.get_type()); | ||||
| foreach (const SocketType &socket, type->inputs) { | foreach (const SocketType &socket, type->get_inputs()) { | ||||
| if (!equals_value(other, socket)) | if (!equals_value(other, socket)) | ||||
| return false; | return false; | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| /* Hash */ | /* Hash */ | ||||
| namespace { | namespace { | ||||
| template<typename T> void value_hash(const Node *node, const SocketType &socket, MD5Hash &md5) | template<typename T> void value_hash(const Node *node, const SocketType &socket, MD5Hash &md5) | ||||
| { | { | ||||
| md5.append(((uint8_t *)node) + socket.struct_offset, socket.size()); | md5.append(((uint8_t *)node) + socket.get_struct_offset(), socket.size()); | ||||
| } | } | ||||
| void float3_hash(const Node *node, const SocketType &socket, MD5Hash &md5) | void float3_hash(const Node *node, const SocketType &socket, MD5Hash &md5) | ||||
| { | { | ||||
| /* Don't compare 4th element used for padding. */ | /* Don't compare 4th element used for padding. */ | ||||
| md5.append(((uint8_t *)node) + socket.struct_offset, sizeof(float) * 3); | md5.append(((uint8_t *)node) + socket.get_struct_offset(), sizeof(float) * 3); | ||||
| } | } | ||||
| template<typename T> void array_hash(const Node *node, const SocketType &socket, MD5Hash &md5) | template<typename T> void array_hash(const Node *node, const SocketType &socket, MD5Hash &md5) | ||||
| { | { | ||||
| const array<T> &a = *(const array<T> *)(((char *)node) + socket.struct_offset); | const array<T> &a = *(const array<T> *)(((char *)node) + socket.get_struct_offset()); | ||||
| for (size_t i = 0; i < a.size(); i++) { | for (size_t i = 0; i < a.size(); i++) { | ||||
| md5.append((uint8_t *)&a[i], sizeof(T)); | md5.append((uint8_t *)&a[i], sizeof(T)); | ||||
| } | } | ||||
| } | } | ||||
| void float3_array_hash(const Node *node, const SocketType &socket, MD5Hash &md5) | void float3_array_hash(const Node *node, const SocketType &socket, MD5Hash &md5) | ||||
| { | { | ||||
| /* Don't compare 4th element used for padding. */ | /* Don't compare 4th element used for padding. */ | ||||
| const array<float3> &a = *(const array<float3> *)(((char *)node) + socket.struct_offset); | const array<float3> &a = *(const array<float3> *)(((char *)node) + socket.get_struct_offset()); | ||||
| for (size_t i = 0; i < a.size(); i++) { | for (size_t i = 0; i < a.size(); i++) { | ||||
| md5.append((uint8_t *)&a[i], sizeof(float) * 3); | md5.append((uint8_t *)&a[i], sizeof(float) * 3); | ||||
| } | } | ||||
| } | } | ||||
| } // namespace | } // namespace | ||||
| void Node::hash(MD5Hash &md5) | void Node::hash(MD5Hash &md5) | ||||
| { | { | ||||
| md5.append(type->name.string()); | md5.append(type->get_name().string()); | ||||
| foreach (const SocketType &socket, type->inputs) { | foreach (const SocketType &socket, type->get_inputs()) { | ||||
| md5.append(socket.name.string()); | md5.append(socket.get_name().string()); | ||||
| switch (socket.type) { | switch (socket.get_type()) { | ||||
| case SocketType::BOOLEAN: | case SocketType::BOOLEAN: | ||||
| value_hash<bool>(this, socket, md5); | value_hash<bool>(this, socket, md5); | ||||
| break; | break; | ||||
| case SocketType::FLOAT: | case SocketType::FLOAT: | ||||
| value_hash<float>(this, socket, md5); | value_hash<float>(this, socket, md5); | ||||
| break; | break; | ||||
| case SocketType::INT: | case SocketType::INT: | ||||
| value_hash<int>(this, socket, md5); | value_hash<int>(this, socket, md5); | ||||
| ▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | foreach (const SocketType &socket, type->get_inputs()) { | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| namespace { | namespace { | ||||
| template<typename T> size_t array_size_in_bytes(const Node *node, const SocketType &socket) | template<typename T> size_t array_size_in_bytes(const Node *node, const SocketType &socket) | ||||
| { | { | ||||
| const array<T> &a = *(const array<T> *)(((char *)node) + socket.struct_offset); | const array<T> &a = *(const array<T> *)(((char *)node) + socket.get_struct_offset()); | ||||
| return a.size() * sizeof(T); | return a.size() * sizeof(T); | ||||
| } | } | ||||
| } // namespace | } // namespace | ||||
| size_t Node::get_total_size_in_bytes() const | size_t Node::get_total_size_in_bytes() const | ||||
| { | { | ||||
| size_t total_size = 0; | size_t total_size = 0; | ||||
| foreach (const SocketType &socket, type->inputs) { | foreach (const SocketType &socket, type->get_inputs()) { | ||||
| switch (socket.type) { | switch (socket.get_type()) { | ||||
| case SocketType::BOOLEAN: | case SocketType::BOOLEAN: | ||||
| case SocketType::FLOAT: | case SocketType::FLOAT: | ||||
| case SocketType::INT: | case SocketType::INT: | ||||
| case SocketType::UINT: | case SocketType::UINT: | ||||
| case SocketType::COLOR: | case SocketType::COLOR: | ||||
| case SocketType::VECTOR: | case SocketType::VECTOR: | ||||
| case SocketType::POINT: | case SocketType::POINT: | ||||
| case SocketType::NORMAL: | case SocketType::NORMAL: | ||||
| ▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | switch (socket.get_type()) { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| return total_size; | return total_size; | ||||
| } | } | ||||
| bool Node::is_a(const NodeType *type_) | bool Node::is_a(const NodeType *type_) | ||||
| { | { | ||||
| for (const NodeType *base = type; base; base = base->base) { | for (const NodeType *base = type; base; base = base->get_base()) { | ||||
| if (base == type_) { | if (base == type_) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| const NodeOwner *Node::get_owner() const | const NodeOwner *Node::get_owner() const | ||||
| { | { | ||||
| return owner; | return owner; | ||||
| } | } | ||||
| void Node::set_owner(const NodeOwner *owner_) | void Node::set_owner(const NodeOwner *owner_) | ||||
| { | { | ||||
| assert(owner_); | assert(owner_); | ||||
| owner = owner_; | owner = owner_; | ||||
| } | } | ||||
| bool Node::socket_is_modified(const SocketType &input) const | bool Node::socket_is_modified(const SocketType &input) const | ||||
| { | { | ||||
| return (socket_modified & input.modified_flag_bit) != 0; | return (socket_modified & input.get_modified_flag_bit()) != 0; | ||||
| } | } | ||||
| bool Node::is_modified() | bool Node::is_modified() | ||||
| { | { | ||||
| return socket_modified != 0; | return socket_modified != 0; | ||||
| } | } | ||||
| void Node::tag_modified() | void Node::tag_modified() | ||||
| { | { | ||||
| socket_modified = ~0ull; | socket_modified = ~0ull; | ||||
| } | } | ||||
| void Node::clear_modified() | void Node::clear_modified() | ||||
| { | { | ||||
| socket_modified = 0; | socket_modified = 0; | ||||
| } | } | ||||
| template<typename T> void Node::set_if_different(const SocketType &input, T value) | template<typename T> void Node::set_if_different(const SocketType &input, T value) | ||||
| { | { | ||||
| if (get_socket_value<T>(this, input) == value) { | if (get_socket_value<T>(this, input) == value) { | ||||
| return; | return; | ||||
| } | } | ||||
| get_socket_value<T>(this, input) = value; | get_socket_value<T>(this, input) = value; | ||||
| socket_modified |= input.modified_flag_bit; | socket_modified |= input.get_modified_flag_bit(); | ||||
| } | } | ||||
| template<typename T> void Node::set_if_different(const SocketType &input, array<T> &value) | template<typename T> void Node::set_if_different(const SocketType &input, array<T> &value) | ||||
| { | { | ||||
| if (!socket_is_modified(input)) { | if (!socket_is_modified(input)) { | ||||
| if (get_socket_value<array<T>>(this, input) == value) { | if (get_socket_value<array<T>>(this, input) == value) { | ||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| get_socket_value<array<T>>(this, input).steal_data(value); | get_socket_value<array<T>>(this, input).steal_data(value); | ||||
| socket_modified |= input.modified_flag_bit; | socket_modified |= input.get_modified_flag_bit(); | ||||
| } | } | ||||
| void Node::print_modified_sockets() const | void Node::print_modified_sockets() const | ||||
| { | { | ||||
| printf("Node : %s\n", name.c_str()); | printf("Node : %s\n", name.c_str()); | ||||
| for (auto &socket : type->inputs) { | for (auto &socket : type->get_inputs()) { | ||||
| if (socket_is_modified(socket)) { | if (socket_is_modified(socket)) { | ||||
| printf("-- socket modified : %s\n", socket.name.c_str()); | printf("-- socket modified : %s\n", socket.get_name().c_str()); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| CCL_NAMESPACE_END | CCL_NAMESPACE_END | ||||