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:
authorStefan Werner <stefan.werner@tangent-animation.com>2018-11-23 15:08:15 +0300
committerStefan Werner <stefan.werner@tangent-animation.com>2018-11-23 15:19:53 +0300
commit071f4f4ce0b9520ab0c73d6d68365ad449ca8b80 (patch)
tree9f37bfcac669366b9ad5fb7605f2fbbed9b71b0a /intern/cycles/util/util_vector.h
parent0a2b2d59a5897212ba3771503feb6770fb636bc8 (diff)
Cycles: Improved robustness of hair motion blur.motion_curve_fix
In some instances, the number of control vertices of a hair could change mid-frame. Cycles would then be unable to calculate proper motion blur for those hairs. This adds interpolated CVs to fill in for the missing data. While this will not necessarily result in a fully accurate reconstruction of the guide hair, it preserves motion blur instead of disabling it. Reviewers: #cycles, sergey Reviewed By: #cycles, sergey Subscribers: sergey, brecht, #cycles Tags: #cycles Differential Revision: https://developer.blender.org/D3695
Diffstat (limited to 'intern/cycles/util/util_vector.h')
-rw-r--r--intern/cycles/util/util_vector.h296
1 files changed, 9 insertions, 287 deletions
diff --git a/intern/cycles/util/util_vector.h b/intern/cycles/util/util_vector.h
index 0b33221ad4d..18fa231d6e7 100644
--- a/intern/cycles/util/util_vector.h
+++ b/intern/cycles/util/util_vector.h
@@ -17,8 +17,6 @@
#ifndef __UTIL_VECTOR_H__
#define __UTIL_VECTOR_H__
-/* Vector */
-
#include <cassert>
#include <cstring>
#include <vector>
@@ -29,12 +27,9 @@
CCL_NAMESPACE_BEGIN
-/* Vector
- *
- * Own subclass-ed vestion of std::vector. Subclass is needed because:
+/* Own subclass-ed vestion of std::vector. Subclass is needed because:
*
* - Use own allocator which keeps track of used/peak memory.
- *
* - Have method to ensure capacity is re-set to 0.
*/
template<typename value_type,
@@ -42,30 +37,16 @@ template<typename value_type,
class vector : public std::vector<value_type, allocator_type>
{
public:
- /* Default constructor. */
- explicit vector() : std::vector<value_type, allocator_type>() { }
-
- /* Fill constructor. */
- explicit vector(size_t n, const value_type& val = value_type())
- : std::vector<value_type, allocator_type>(n, val) { }
-
- /* Range constructor. */
- template <class InputIterator>
- vector(InputIterator first, InputIterator last)
- : std::vector<value_type, allocator_type>(first, last) { }
-
- /* Copy constructor. */
- vector(const vector &x) : std::vector<value_type, allocator_type>(x) { }
+ typedef std::vector<value_type, allocator_type> BaseClass;
- void shrink_to_fit(void)
- {
- std::vector<value_type, allocator_type>::shrink_to_fit();
- }
+ /* Inherit all constructors from base class. */
+ using BaseClass::vector;
- void free_memory(void)
+ /* Try as hard as possible to use zero memory. */
+ void free_memory()
{
- std::vector<value_type, allocator_type>::resize(0);
- shrink_to_fit();
+ BaseClass::resize(0);
+ BaseClass::shrink_to_fit();
}
/* Some external API might demand working with std::vector. */
@@ -75,265 +56,6 @@ public:
}
};
-/* Array
- *
- * Simplified version of vector, serving multiple purposes:
- * - somewhat faster in that it does not clear memory on resize/alloc,
- * this was actually showing up in profiles quite significantly. it
- * also does not run any constructors/destructors
- * - if this is used, we are not tempted to use inefficient operations
- * - aligned allocation for CPU native data types */
-
-template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES>
-class array
-{
-public:
- array()
- : data_(NULL),
- datasize_(0),
- capacity_(0)
- {}
-
- explicit array(size_t newsize)
- {
- if(newsize == 0) {
- data_ = NULL;
- datasize_ = 0;
- capacity_ = 0;
- }
- else {
- data_ = mem_allocate(newsize);
- datasize_ = newsize;
- capacity_ = datasize_;
- }
- }
-
- array(const array& from)
- {
- if(from.datasize_ == 0) {
- data_ = NULL;
- datasize_ = 0;
- capacity_ = 0;
- }
- else {
- data_ = mem_allocate(from.datasize_);
- memcpy(data_, from.data_, from.datasize_*sizeof(T));
- datasize_ = from.datasize_;
- capacity_ = datasize_;
- }
- }
-
- array& operator=(const array& from)
- {
- if(this != &from) {
- resize(from.size());
- memcpy((void*)data_, from.data_, datasize_*sizeof(T));
- }
-
- return *this;
- }
-
- array& operator=(const vector<T>& from)
- {
- resize(from.size());
-
- if(from.size() > 0) {
- memcpy(data_, &from[0], datasize_*sizeof(T));
- }
-
- return *this;
- }
-
- ~array()
- {
- mem_free(data_, capacity_);
- }
-
- bool operator==(const array<T>& other) const
- {
- if(datasize_ != other.datasize_) {
- return false;
- }
-
- return memcmp(data_, other.data_, datasize_*sizeof(T)) == 0;
- }
-
- bool operator!=(const array<T>& other) const
- {
- return !(*this == other);
- }
-
- void steal_data(array& from)
- {
- if(this != &from) {
- clear();
-
- data_ = from.data_;
- datasize_ = from.datasize_;
- capacity_ = from.capacity_;
-
- from.data_ = NULL;
- from.datasize_ = 0;
- from.capacity_ = 0;
- }
- }
-
- T *steal_pointer()
- {
- T *ptr = data_;
- data_ = NULL;
- clear();
- return ptr;
- }
-
- T* resize(size_t newsize)
- {
- if(newsize == 0) {
- clear();
- }
- else if(newsize != datasize_) {
- if(newsize > capacity_) {
- T *newdata = mem_allocate(newsize);
- if(newdata == NULL) {
- /* Allocation failed, likely out of memory. */
- clear();
- return NULL;
- }
- else if(data_ != NULL) {
- memcpy((void *)newdata,
- data_,
- ((datasize_ < newsize)? datasize_: newsize)*sizeof(T));
- mem_free(data_, capacity_);
- }
- data_ = newdata;
- capacity_ = newsize;
- }
- datasize_ = newsize;
- }
- return data_;
- }
-
- T* resize(size_t newsize, const T& value)
- {
- size_t oldsize = size();
- resize(newsize);
-
- for(size_t i = oldsize; i < size(); i++) {
- data_[i] = value;
- }
-
- return data_;
- }
-
- void clear()
- {
- if(data_ != NULL) {
- mem_free(data_, capacity_);
- data_ = NULL;
- }
- datasize_ = 0;
- capacity_ = 0;
- }
-
- size_t empty() const
- {
- return datasize_ == 0;
- }
-
- size_t size() const
- {
- return datasize_;
- }
-
- T* data()
- {
- return data_;
- }
-
- const T* data() const
- {
- return data_;
- }
-
- T& operator[](size_t i) const
- {
- assert(i < datasize_);
- return data_[i];
- }
-
- void reserve(size_t newcapacity)
- {
- if(newcapacity > capacity_) {
- T *newdata = mem_allocate(newcapacity);
- if(data_ != NULL) {
- memcpy(newdata, data_, ((datasize_ < newcapacity)? datasize_: newcapacity)*sizeof(T));
- mem_free(data_, capacity_);
- }
- data_ = newdata;
- capacity_ = newcapacity;
- }
- }
-
- size_t capacity() const
- {
- return capacity_;
- }
-
- // do not use this method unless you are sure the code is not performance critical
- void push_back_slow(const T& t)
- {
- if(capacity_ == datasize_)
- {
- reserve(datasize_ == 0 ? 1 : (size_t)((datasize_ + 1) * 1.2));
- }
-
- data_[datasize_++] = t;
- }
-
- void push_back_reserved(const T& t)
- {
- assert(datasize_ < capacity_);
- push_back_slow(t);
- }
-
- void append(const array<T>& from)
- {
- if(from.size()) {
- size_t old_size = size();
- resize(old_size + from.size());
- memcpy(data_ + old_size, from.data(), sizeof(T) * from.size());
- }
- }
-
-protected:
- inline T* mem_allocate(size_t N)
- {
- if(N == 0) {
- return NULL;
- }
- T *mem = (T*)util_aligned_malloc(sizeof(T)*N, alignment);
- if(mem != NULL) {
- util_guarded_mem_alloc(sizeof(T)*N);
- }
- else {
- throw std::bad_alloc();
- }
- return mem;
- }
-
- inline void mem_free(T *mem, size_t N)
- {
- if(mem != NULL) {
- util_guarded_mem_free(sizeof(T)*N);
- util_aligned_free(mem);
- }
- }
-
- T *data_;
- size_t datasize_;
- size_t capacity_;
-};
-
CCL_NAMESPACE_END
-#endif /* __UTIL_VECTOR_H__ */
+#endif /* __UTIL_VECTOR_H__ */