diff options
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_rand.h | 6 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_rand.hh | 1 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_user_counter.hh | 158 | ||||
-rw-r--r-- | source/blender/blenlib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/blenlib/intern/rand.cc | 25 |
5 files changed, 191 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_rand.h b/source/blender/blenlib/BLI_rand.h index 78a323c2431..ec74cef9311 100644 --- a/source/blender/blenlib/BLI_rand.h +++ b/source/blender/blenlib/BLI_rand.h @@ -60,6 +60,12 @@ void BLI_rng_get_tri_sample_float_v2(struct RNG *rng, const float v2[2], const float v3[2], float r_pt[2]) ATTR_NONNULL(); +void BLI_rng_get_tri_sample_float_v3(RNG *rng, + const float v1[3], + const float v2[3], + const float v3[3], + float r_pt[3]) ATTR_NONNULL(); + void BLI_rng_shuffle_array(struct RNG *rng, void *data, unsigned int elem_size_i, diff --git a/source/blender/blenlib/BLI_rand.hh b/source/blender/blenlib/BLI_rand.hh index 1b321bd7bcd..0c0dd464d4d 100644 --- a/source/blender/blenlib/BLI_rand.hh +++ b/source/blender/blenlib/BLI_rand.hh @@ -118,6 +118,7 @@ class RandomNumberGenerator { float2 get_unit_float2(); float3 get_unit_float3(); float2 get_triangle_sample(float2 v1, float2 v2, float2 v3); + float3 get_triangle_sample_3d(float3 v1, float3 v2, float3 v3); void get_bytes(MutableSpan<char> r_bytes); /** diff --git a/source/blender/blenlib/BLI_user_counter.hh b/source/blender/blenlib/BLI_user_counter.hh new file mode 100644 index 00000000000..ef276814981 --- /dev/null +++ b/source/blender/blenlib/BLI_user_counter.hh @@ -0,0 +1,158 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#pragma once + +/** \file + * \ingroup bli + */ + +#include <atomic> + +namespace blender { + +/** + * A simple automatic reference counter. It is similar to std::shared_ptr, but expects that the + * reference count is inside the object. + */ +template<typename T> class UserCounter { + private: + T *data_ = nullptr; + + public: + UserCounter() = default; + + UserCounter(T *data) : data_(data) + { + } + + UserCounter(const UserCounter &other) : data_(other.data_) + { + this->user_add(data_); + } + + UserCounter(UserCounter &&other) : data_(other.data_) + { + other.data_ = nullptr; + } + + ~UserCounter() + { + this->user_remove(data_); + } + + UserCounter &operator=(const UserCounter &other) + { + if (this == &other) { + return *this; + } + + this->user_remove(data_); + data_ = other.data_; + this->user_add(data_); + return *this; + } + + UserCounter &operator=(UserCounter &&other) + { + if (this == &other) { + return *this; + } + + this->user_remove(data_); + data_ = other.data_; + other.data_ = nullptr; + return *this; + } + + T *operator->() + { + BLI_assert(data_ != nullptr); + return data_; + } + + T &operator*() + { + BLI_assert(data_ != nullptr); + return *data_; + } + + operator bool() const + { + return data_ != nullptr; + } + + T *get() + { + return data_; + } + + const T *get() const + { + return data_; + } + + T *release() + { + T *data = data_; + data_ = nullptr; + return data; + } + + void reset() + { + this->user_remove(data_); + data_ = nullptr; + } + + bool has_value() const + { + return data_ != nullptr; + } + + uint64_t hash() const + { + return DefaultHash<T *>{}(data_); + } + + friend bool operator==(const UserCounter &a, const UserCounter &b) + { + return a.data_ == b.data_; + } + + friend std::ostream &operator<<(std::ostream &stream, const UserCounter &value) + { + stream << value.data_; + return stream; + } + + private: + static void user_add(T *data) + { + if (data != nullptr) { + data->user_add(); + } + } + + static void user_remove(T *data) + { + if (data != nullptr) { + data->user_remove(); + } + } +}; + +} // namespace blender diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 9736d8f9b3b..46a3ad87dfe 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -279,6 +279,7 @@ set(SRC BLI_timecode.h BLI_timeit.hh BLI_timer.h + BLI_user_counter.hh BLI_utildefines.h BLI_utildefines_iter.h BLI_utildefines_stack.h diff --git a/source/blender/blenlib/intern/rand.cc b/source/blender/blenlib/intern/rand.cc index 224db31471d..c61e17e6627 100644 --- a/source/blender/blenlib/intern/rand.cc +++ b/source/blender/blenlib/intern/rand.cc @@ -141,6 +141,12 @@ void BLI_rng_get_tri_sample_float_v2( copy_v2_v2(r_pt, rng->rng.get_triangle_sample(v1, v2, v3)); } +void BLI_rng_get_tri_sample_float_v3( + RNG *rng, const float v1[3], const float v2[3], const float v3[3], float r_pt[3]) +{ + copy_v3_v3(r_pt, rng->rng.get_triangle_sample_3d(v1, v2, v3)); +} + void BLI_rng_shuffle_array(RNG *rng, void *data, unsigned int elem_size_i, unsigned int elem_tot) { const uint elem_size = elem_size_i; @@ -425,6 +431,25 @@ float2 RandomNumberGenerator::get_triangle_sample(float2 v1, float2 v2, float2 v return sample; } +float3 RandomNumberGenerator::get_triangle_sample_3d(float3 v1, float3 v2, float3 v3) +{ + float u = this->get_float(); + float v = this->get_float(); + + if (u + v > 1.0f) { + u = 1.0f - u; + v = 1.0f - v; + } + + float3 side_u = v2 - v1; + float3 side_v = v3 - v1; + + float3 sample = v1; + sample += side_u * u; + sample += side_v * v; + return sample; +} + void RandomNumberGenerator::get_bytes(MutableSpan<char> r_bytes) { constexpr int64_t mask_bytes = 2; |