Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/render/alembic.h')
-rw-r--r--intern/cycles/render/alembic.h92
1 files changed, 82 insertions, 10 deletions
diff --git a/intern/cycles/render/alembic.h b/intern/cycles/render/alembic.h
index 6552336e6ab..0fc02f1da23 100644
--- a/intern/cycles/render/alembic.h
+++ b/intern/cycles/render/alembic.h
@@ -50,6 +50,78 @@ template<typename> struct is_array : public std::false_type {
template<typename T> struct is_array<array<T>> : public std::true_type {
};
+/* Holds the data for a cache lookup at a given time, as well as informations to
+ * help disambiguate successes or failures to get data from the cache. */
+template<typename T> class CacheLookupResult {
+ enum class State {
+ NEW_DATA,
+ ALREADY_LOADED,
+ NO_DATA_FOR_TIME,
+ };
+
+ T *data;
+ State state;
+
+ protected:
+ /* Prevent default construction outside of the class: for a valid result, we
+ * should use the static functions below. */
+ CacheLookupResult() = default;
+
+ public:
+ static CacheLookupResult new_data(T *data_)
+ {
+ CacheLookupResult result;
+ result.data = data_;
+ result.state = State::NEW_DATA;
+ return result;
+ }
+
+ static CacheLookupResult no_data_found_for_time()
+ {
+ CacheLookupResult result;
+ result.data = nullptr;
+ result.state = State::NO_DATA_FOR_TIME;
+ return result;
+ }
+
+ static CacheLookupResult already_loaded()
+ {
+ CacheLookupResult result;
+ result.data = nullptr;
+ result.state = State::ALREADY_LOADED;
+ return result;
+ }
+
+ /* This should only be call if new data is available. */
+ const T &get_data() const
+ {
+ assert(state == State::NEW_DATA);
+ assert(data != nullptr);
+ return *data;
+ }
+
+ T *get_data_or_null() const
+ {
+ // data_ should already be null if there is no new data so no need to check
+ return data;
+ }
+
+ bool has_new_data() const
+ {
+ return state == State::NEW_DATA;
+ }
+
+ bool has_already_loaded() const
+ {
+ return state == State::ALREADY_LOADED;
+ }
+
+ bool has_no_data_for_time() const
+ {
+ return state == State::NO_DATA_FOR_TIME;
+ }
+};
+
/* Store the data set for an animation at every time points, or at the beginning of the animation
* for constant data.
*
@@ -79,10 +151,10 @@ template<typename T> class DataStore {
/* Get the data for the specified time.
* Return nullptr if there is no data or if the data for this time was already loaded. */
- T *data_for_time(double time)
+ CacheLookupResult<T> data_for_time(double time)
{
if (size() == 0) {
- return nullptr;
+ return CacheLookupResult<T>::no_data_found_for_time();
}
std::pair<size_t, Alembic::Abc::chrono_t> index_pair;
@@ -90,26 +162,26 @@ template<typename T> class DataStore {
DataTimePair &data_pair = data[index_pair.first];
if (last_loaded_time == data_pair.time) {
- return nullptr;
+ return CacheLookupResult<T>::already_loaded();
}
last_loaded_time = data_pair.time;
- return &data_pair.data;
+ return CacheLookupResult<T>::new_data(&data_pair.data);
}
/* get the data for the specified time, but do not check if the data was already loaded for this
* time return nullptr if there is no data */
- T *data_for_time_no_check(double time)
+ CacheLookupResult<T> data_for_time_no_check(double time)
{
if (size() == 0) {
- return nullptr;
+ return CacheLookupResult<T>::no_data_found_for_time();
}
std::pair<size_t, Alembic::Abc::chrono_t> index_pair;
index_pair = time_sampling.getNearIndex(time, data.size());
DataTimePair &data_pair = data[index_pair.first];
- return &data_pair.data;
+ return CacheLookupResult<T>::new_data(&data_pair.data);
}
void add_data(T &data_, double time)
@@ -149,15 +221,15 @@ template<typename T> class DataStore {
* data for this time or it was already loaded, do nothing. */
void copy_to_socket(double time, Node *node, const SocketType *socket)
{
- T *data_ = data_for_time(time);
+ CacheLookupResult<T> result = data_for_time(time);
- if (data_ == nullptr) {
+ if (!result.has_new_data()) {
return;
}
/* TODO(kevindietrich): arrays are emptied when passed to the sockets, so for now we copy the
* arrays to avoid reloading the data */
- T value = *data_;
+ T value = result.get_data();
node->set(*socket, value);
}
};