The goal is to solve confusion of the "All rights reserved" for licensing
code under an open-source license.
The phrase "All rights reserved" comes from a historical convention that
required this phrase for the copyright protection to apply. This convention
is no longer relevant.
However, even though the phrase has no meaning in establishing the copyright
it has not lost meaning in terms of licensing.
This change makes it so code under the Blender Foundation copyright does
not use "all rights reserved". This is also how the GPL license itself
states how to apply it to the source code:
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software ...
This change does not change copyright notice in cases when the copyright
is dual (BF and an author), or just an author of the code. It also does
mot change copyright which is inherited from NaN Holding BV as it needs
some further investigation about what is the proper way to handle it.
141 lines
4.4 KiB
C++
141 lines
4.4 KiB
C++
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
* Copyright 2020 Blender Foundation */
|
|
|
|
/** \file
|
|
* \ingroup bke
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <optional>
|
|
#include <string>
|
|
|
|
#include "BKE_cryptomatte.h"
|
|
|
|
#include "BLI_hash_mm3.h"
|
|
#include "BLI_map.hh"
|
|
#include "BLI_string_ref.hh"
|
|
|
|
#include "BKE_cryptomatte.h"
|
|
|
|
struct ID;
|
|
|
|
namespace blender::bke::cryptomatte {
|
|
|
|
/**
|
|
* Format to a cryptomatte meta data key.
|
|
*
|
|
* Cryptomatte stores meta data. The keys are formatted containing a hash that
|
|
* is generated from its layer name.
|
|
*
|
|
* The output of this function is:
|
|
* 'cryptomatte/{hash of layer_name}/{key_name}'.
|
|
*/
|
|
std::string BKE_cryptomatte_meta_data_key(const StringRef layer_name,
|
|
const StringRefNull key_name);
|
|
|
|
/**
|
|
* Extract the cryptomatte layer name from the given `render_pass_name`.
|
|
*
|
|
* Cryptomatte passes are formatted with a trailing number for storing multiple samples that belong
|
|
* to the same cryptomatte layer. This function would remove the trailing numbers to determine the
|
|
* cryptomatte layer name.
|
|
*
|
|
* # Example
|
|
*
|
|
* A render_pass_name could be 'View Layer.CryptoMaterial02'. The cryptomatte layer would be 'View
|
|
* Layer.CryptoMaterial'.
|
|
*
|
|
* \note The return type is a sub-string of `render_pass_name` and therefore cannot outlive the
|
|
* `render_pass_name` internal data.
|
|
*/
|
|
StringRef BKE_cryptomatte_extract_layer_name(const StringRef render_pass_name);
|
|
|
|
struct CryptomatteHash {
|
|
uint32_t hash;
|
|
|
|
CryptomatteHash(uint32_t hash);
|
|
CryptomatteHash(const char *name, int name_len)
|
|
{
|
|
hash = BLI_hash_mm3((const unsigned char *)name, name_len, 0);
|
|
}
|
|
|
|
static CryptomatteHash from_hex_encoded(blender::StringRef hex_encoded);
|
|
std::string hex_encoded() const;
|
|
|
|
/**
|
|
* Convert a cryptomatte hash to a float.
|
|
*
|
|
* Cryptomatte hashes are stored in float textures and images. The conversion is taken from the
|
|
* cryptomatte specification. See Floating point conversion section in
|
|
* https://github.com/Psyop/Cryptomatte/blob/master/specification/cryptomatte_specification.pdf.
|
|
*
|
|
* The conversion uses as many 32 bit floating point values as possible to minimize hash
|
|
* collisions. Unfortunately not all 32 bits can be used as NaN and Inf can be problematic.
|
|
*
|
|
* Note that this conversion assumes to be running on a L-endian system.
|
|
*/
|
|
float float_encoded() const
|
|
{
|
|
uint32_t mantissa = hash & ((1 << 23) - 1);
|
|
uint32_t exponent = (hash >> 23) & ((1 << 8) - 1);
|
|
exponent = MAX2(exponent, uint32_t(1));
|
|
exponent = MIN2(exponent, uint32_t(254));
|
|
exponent = exponent << 23;
|
|
uint32_t sign = (hash >> 31);
|
|
sign = sign << 31;
|
|
uint32_t float_bits = sign | exponent | mantissa;
|
|
float f;
|
|
memcpy(&f, &float_bits, sizeof(uint32_t));
|
|
return f;
|
|
}
|
|
};
|
|
|
|
struct CryptomatteLayer {
|
|
blender::Map<std::string, CryptomatteHash> hashes;
|
|
|
|
#ifdef WITH_CXX_GUARDEDALLOC
|
|
MEM_CXX_CLASS_ALLOC_FUNCS("cryptomatte:CryptomatteLayer")
|
|
#endif
|
|
|
|
static std::unique_ptr<CryptomatteLayer> read_from_manifest(blender::StringRefNull manifest);
|
|
uint32_t add_ID(const struct ID &id);
|
|
void add_hash(blender::StringRef name, CryptomatteHash cryptomatte_hash);
|
|
std::string manifest() const;
|
|
|
|
std::optional<std::string> operator[](float encoded_hash) const;
|
|
};
|
|
|
|
struct CryptomatteStampDataCallbackData {
|
|
struct CryptomatteSession *session;
|
|
blender::Map<std::string, std::string> hash_to_layer_name;
|
|
|
|
/**
|
|
* Extract the hash from a stamp data key.
|
|
*
|
|
* Cryptomatte keys are formatted as "cryptomatte/{layer_hash}/{attribute}".
|
|
*/
|
|
static blender::StringRef extract_layer_hash(blender::StringRefNull key);
|
|
|
|
/* C type callback function (StampCallback). */
|
|
static void extract_layer_names(void *_data, const char *propname, char *propvalue, int len);
|
|
/* C type callback function (StampCallback). */
|
|
static void extract_layer_manifest(void *_data, const char *propname, char *propvalue, int len);
|
|
};
|
|
|
|
const blender::Vector<std::string> &BKE_cryptomatte_layer_names_get(
|
|
const CryptomatteSession &session);
|
|
CryptomatteLayer *BKE_cryptomatte_layer_get(CryptomatteSession &session,
|
|
const StringRef layer_name);
|
|
|
|
struct CryptomatteSessionDeleter {
|
|
void operator()(CryptomatteSession *session)
|
|
{
|
|
BKE_cryptomatte_free(session);
|
|
}
|
|
};
|
|
|
|
using CryptomatteSessionPtr = std::unique_ptr<CryptomatteSession, CryptomatteSessionDeleter>;
|
|
|
|
} // namespace blender::bke::cryptomatte
|