static void array_hash(const Node *node, const SocketType& socket, MD5Hash& md5) { const array<T>& a = *(const array<T>*)(((char*)node) + socket.struct_offset); for (size_t i = 0; i < a.size(); i++) { md5.append((uint8_t*)&a[i], sizeof(T)); } }
static void float3_array_hash(const Node *node, const SocketType& socket, MD5Hash& md5) { /* Don't compare 4th element used for padding. */ const array<float3>& a = *(const array<float3>*)(((char*)node) + socket.struct_offset); for (size_t i = 0; i < a.size(); i++) { md5.append((uint8_t*)&a[i], sizeof(float) * 3); } }
const string& CacheData::get_filename() { if(!have_filename) { MD5Hash hash; foreach(const CacheBuffer& buffer, buffers) if(buffer.size) hash.append((uint8_t*)buffer.data, buffer.size); filename = name + "_" + hash.get_hex(); have_filename = true; }
void Node::hash(MD5Hash& md5) { md5.append(type->name.string()); foreach(const SocketType& socket, type->inputs) { md5.append(socket.name.string()); switch(socket.type) { case SocketType::BOOLEAN: value_hash<bool>(this, socket, md5); break; case SocketType::FLOAT: value_hash<float>(this, socket, md5); break; case SocketType::INT: value_hash<int>(this, socket, md5); break; case SocketType::UINT: value_hash<uint>(this, socket, md5); break; case SocketType::COLOR: float3_hash(this, socket, md5); break; case SocketType::VECTOR: float3_hash(this, socket, md5); break; case SocketType::POINT: float3_hash(this, socket, md5); break; case SocketType::NORMAL: float3_hash(this, socket, md5); break; case SocketType::POINT2: value_hash<float2>(this, socket, md5); break; case SocketType::CLOSURE: break; case SocketType::STRING: value_hash<ustring>(this, socket, md5); break; case SocketType::ENUM: value_hash<int>(this, socket, md5); break; case SocketType::TRANSFORM: value_hash<Transform>(this, socket, md5); break; case SocketType::NODE: value_hash<void*>(this, socket, md5); break; case SocketType::BOOLEAN_ARRAY: array_hash<bool>(this, socket, md5); break; case SocketType::FLOAT_ARRAY: array_hash<float>(this, socket, md5); break; case SocketType::INT_ARRAY: array_hash<int>(this, socket, md5); break; case SocketType::COLOR_ARRAY: float3_array_hash(this, socket, md5); break; case SocketType::VECTOR_ARRAY: float3_array_hash(this, socket, md5); break; case SocketType::POINT_ARRAY: float3_array_hash(this, socket, md5); break; case SocketType::NORMAL_ARRAY: float3_array_hash(this, socket, md5); break; case SocketType::POINT2_ARRAY: array_hash<float2>(this, socket, md5); break; case SocketType::STRING_ARRAY: array_hash<ustring>(this, socket, md5); break; case SocketType::TRANSFORM_ARRAY: array_hash<Transform>(this, socket, md5); break; case SocketType::NODE_ARRAY: array_hash<void*>(this, socket, md5); break; case SocketType::UNDEFINED: break; } } }
static void path_files_md5_hash_recursive(MD5Hash& hash, const string& dir) { if(path_exists(dir)) { directory_iterator it(dir), it_end; for(; it != it_end; ++it) { if(path_is_directory(it->path())) { path_files_md5_hash_recursive(hash, it->path()); } else { string filepath = it->path(); hash.append((const uint8_t*)filepath.c_str(), filepath.size()); hash.append_file(filepath); } } } }
static void path_files_md5_hash_recursive(MD5Hash& hash, const string& dir) { if(boost::filesystem::exists(dir)) { boost::filesystem::directory_iterator it(dir), it_end; for(; it != it_end; it++) { if(boost::filesystem::is_directory(it->status())) { path_files_md5_hash_recursive(hash, it->path().string()); } else { string filepath = it->path().string(); hash.append((const uint8_t*)filepath.c_str(), filepath.size()); hash.append_file(filepath); } } } }
static void float3_hash(const Node *node, const SocketType& socket, MD5Hash& md5) { /* Don't compare 4th element used for padding. */ md5.append(((uint8_t*)node) + socket.struct_offset, sizeof(float) * 3); }
static void value_hash(const Node *node, const SocketType& socket, MD5Hash& md5) { md5.append(((uint8_t*)node) + socket.struct_offset, socket.size()); }