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:
authorLukas Stockner <lukas.stockner@freenet.de>2022-10-30 00:41:21 +0300
committerLukas Stockner <lukas.stockner@freenet.de>2022-10-30 01:14:59 +0300
commitbc37e8d8399eef686b71341aa90eced9bc117786 (patch)
tree92e4af388150209df9bc44e2cba6f2f303aa7baf /source/blender/blenlib
parent552abb838c76d44a0d7d1226b59a1ab381e88386 (diff)
parentd1d2f002c7caaf4ab457ec27bbc44666d7aac624 (diff)
Merge remote-tracking branch 'origin/master' into principled-v2
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r--source/blender/blenlib/BLI_allocator.hh11
-rw-r--r--source/blender/blenlib/BLI_any.hh13
-rw-r--r--source/blender/blenlib/BLI_array.hh3
-rw-r--r--source/blender/blenlib/BLI_array_store.h1
-rw-r--r--source/blender/blenlib/BLI_array_utils.hh115
-rw-r--r--source/blender/blenlib/BLI_assert.h2
-rw-r--r--source/blender/blenlib/BLI_bit_vector.hh529
-rw-r--r--source/blender/blenlib/BLI_compiler_attrs.h8
-rw-r--r--source/blender/blenlib/BLI_compute_context.hh173
-rw-r--r--source/blender/blenlib/BLI_convexhull_2d.h37
-rw-r--r--source/blender/blenlib/BLI_cpp_type.hh4
-rw-r--r--source/blender/blenlib/BLI_cpp_type_make.hh8
-rw-r--r--source/blender/blenlib/BLI_dot_export.hh2
-rw-r--r--source/blender/blenlib/BLI_endian_switch_inline.h2
-rw-r--r--source/blender/blenlib/BLI_fileops.h1
-rw-r--r--source/blender/blenlib/BLI_float3x3.hh16
-rw-r--r--source/blender/blenlib/BLI_float4x4.hh2
-rw-r--r--source/blender/blenlib/BLI_function_ref.hh3
-rw-r--r--source/blender/blenlib/BLI_generic_array.hh6
-rw-r--r--source/blender/blenlib/BLI_generic_span.hh57
-rw-r--r--source/blender/blenlib/BLI_generic_virtual_array.hh35
-rw-r--r--source/blender/blenlib/BLI_generic_virtual_vector_array.hh4
-rw-r--r--source/blender/blenlib/BLI_hash.hh10
-rw-r--r--source/blender/blenlib/BLI_hash_tables.hh18
-rw-r--r--source/blender/blenlib/BLI_index_range.hh36
-rw-r--r--source/blender/blenlib/BLI_lazy_threading.hh83
-rw-r--r--source/blender/blenlib/BLI_linear_allocator.hh8
-rw-r--r--source/blender/blenlib/BLI_listbase.h23
-rw-r--r--source/blender/blenlib/BLI_listbase_wrapper.hh4
-rw-r--r--source/blender/blenlib/BLI_map.hh33
-rw-r--r--source/blender/blenlib/BLI_map_slots.hh8
-rw-r--r--source/blender/blenlib/BLI_math_color.h4
-rw-r--r--source/blender/blenlib/BLI_math_geom.h4
-rw-r--r--source/blender/blenlib/BLI_math_inline.h4
-rw-r--r--source/blender/blenlib/BLI_math_matrix.h275
-rw-r--r--source/blender/blenlib/BLI_math_rotation.h93
-rw-r--r--source/blender/blenlib/BLI_math_vec_types.hh243
-rw-r--r--source/blender/blenlib/BLI_math_vector.h88
-rw-r--r--source/blender/blenlib/BLI_math_vector.hh8
-rw-r--r--source/blender/blenlib/BLI_memory_utils.hh4
-rw-r--r--source/blender/blenlib/BLI_mesh_intersect.hh12
-rw-r--r--source/blender/blenlib/BLI_multi_value_map.hh13
-rw-r--r--source/blender/blenlib/BLI_path_util.h136
-rw-r--r--source/blender/blenlib/BLI_pool.hh84
-rw-r--r--source/blender/blenlib/BLI_probing_strategies.hh8
-rw-r--r--source/blender/blenlib/BLI_rand.hh8
-rw-r--r--source/blender/blenlib/BLI_resource_scope.hh2
-rw-r--r--source/blender/blenlib/BLI_scanfill.h2
-rw-r--r--source/blender/blenlib/BLI_serialize.hh2
-rw-r--r--source/blender/blenlib/BLI_set.hh28
-rw-r--r--source/blender/blenlib/BLI_set_slots.hh10
-rw-r--r--source/blender/blenlib/BLI_span.hh8
-rw-r--r--source/blender/blenlib/BLI_strict_flags.h10
-rw-r--r--source/blender/blenlib/BLI_string.h22
-rw-r--r--source/blender/blenlib/BLI_string_cursor_utf8.h3
-rw-r--r--source/blender/blenlib/BLI_string_ref.hh56
-rw-r--r--source/blender/blenlib/BLI_string_utf8.h16
-rw-r--r--source/blender/blenlib/BLI_task.hh20
-rw-r--r--source/blender/blenlib/BLI_utildefines.h13
-rw-r--r--source/blender/blenlib/BLI_vector.hh24
-rw-r--r--source/blender/blenlib/BLI_vector_adaptor.hh88
-rw-r--r--source/blender/blenlib/BLI_vector_set.hh27
-rw-r--r--source/blender/blenlib/BLI_vector_set_slots.hh4
-rw-r--r--source/blender/blenlib/BLI_virtual_array.hh98
-rw-r--r--source/blender/blenlib/BLI_winstuff.h5
-rw-r--r--source/blender/blenlib/CMakeLists.txt26
-rw-r--r--source/blender/blenlib/intern/BLI_args.c4
-rw-r--r--source/blender/blenlib/intern/BLI_filelist.c16
-rw-r--r--source/blender/blenlib/intern/BLI_ghash_utils.c6
-rw-r--r--source/blender/blenlib/intern/BLI_index_range.cc30
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c8
-rw-r--r--source/blender/blenlib/intern/BLI_memarena.c11
-rw-r--r--source/blender/blenlib/intern/BLI_memblock.c1
-rw-r--r--source/blender/blenlib/intern/array_store.c10
-rw-r--r--source/blender/blenlib/intern/array_store_utils.c4
-rw-r--r--source/blender/blenlib/intern/array_utils.cc36
-rw-r--r--source/blender/blenlib/intern/boxpack_2d.c9
-rw-r--r--source/blender/blenlib/intern/compute_context.cc48
-rw-r--r--source/blender/blenlib/intern/convexhull_2d.c71
-rw-r--r--source/blender/blenlib/intern/cpp_type.cc1
-rw-r--r--source/blender/blenlib/intern/delaunay_2d.cc18
-rw-r--r--source/blender/blenlib/intern/dot_export.cc4
-rw-r--r--source/blender/blenlib/intern/endian_switch.c4
-rw-r--r--source/blender/blenlib/intern/fileops.c4
-rw-r--r--source/blender/blenlib/intern/generic_virtual_array.cc12
-rw-r--r--source/blender/blenlib/intern/generic_virtual_vector_array.cc8
-rw-r--r--source/blender/blenlib/intern/hash_mm2a.c8
-rw-r--r--source/blender/blenlib/intern/hash_mm3.c2
-rw-r--r--source/blender/blenlib/intern/jitter_2d.c8
-rw-r--r--source/blender/blenlib/intern/lasso_2d.c10
-rw-r--r--source/blender/blenlib/intern/lazy_threading.cc30
-rw-r--r--source/blender/blenlib/intern/math_base.c4
-rw-r--r--source/blender/blenlib/intern/math_boolean.cc82
-rw-r--r--source/blender/blenlib/intern/math_color.c60
-rw-r--r--source/blender/blenlib/intern/math_geom.c52
-rw-r--r--source/blender/blenlib/intern/math_interp.c98
-rw-r--r--source/blender/blenlib/intern/math_matrix.c200
-rw-r--r--source/blender/blenlib/intern/math_rotation.c199
-rw-r--r--source/blender/blenlib/intern/math_solvers.c4
-rw-r--r--source/blender/blenlib/intern/math_vec.cc2
-rw-r--r--source/blender/blenlib/intern/math_vector.c2
-rw-r--r--source/blender/blenlib/intern/mesh_boolean.cc36
-rw-r--r--source/blender/blenlib/intern/mesh_intersect.cc24
-rw-r--r--source/blender/blenlib/intern/noise.c36
-rw-r--r--source/blender/blenlib/intern/noise.cc107
-rw-r--r--source/blender/blenlib/intern/path_util.c169
-rw-r--r--source/blender/blenlib/intern/polyfill_2d.c8
-rw-r--r--source/blender/blenlib/intern/rand.cc83
-rw-r--r--source/blender/blenlib/intern/scanfill.c39
-rw-r--r--source/blender/blenlib/intern/scanfill_utils.c22
-rw-r--r--source/blender/blenlib/intern/smallhash.c3
-rw-r--r--source/blender/blenlib/intern/stack.c4
-rw-r--r--source/blender/blenlib/intern/storage.c2
-rw-r--r--source/blender/blenlib/intern/string.c36
-rw-r--r--source/blender/blenlib/intern/string_cursor_utf8.c59
-rw-r--r--source/blender/blenlib/intern/string_search.cc23
-rw-r--r--source/blender/blenlib/intern/string_utf8.c70
-rw-r--r--source/blender/blenlib/intern/system.c18
-rw-r--r--source/blender/blenlib/intern/task_graph.cc2
-rw-r--r--source/blender/blenlib/intern/task_iterator.c4
-rw-r--r--source/blender/blenlib/intern/task_pool.cc8
-rw-r--r--source/blender/blenlib/intern/task_range.cc5
-rw-r--r--source/blender/blenlib/intern/threads.cc38
-rw-r--r--source/blender/blenlib/intern/timecode.c2
-rw-r--r--source/blender/blenlib/intern/uuid.cc8
-rw-r--r--source/blender/blenlib/intern/winstuff.c33
-rw-r--r--source/blender/blenlib/tests/BLI_array_store_test.cc35
-rw-r--r--source/blender/blenlib/tests/BLI_bit_vector_test.cc186
-rw-r--r--source/blender/blenlib/tests/BLI_cpp_type_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_delaunay_2d_test.cc20
-rw-r--r--source/blender/blenlib/tests/BLI_edgehash_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_exception_safety_test_utils.hh2
-rw-r--r--source/blender/blenlib/tests/BLI_float3x3_test.cc16
-rw-r--r--source/blender/blenlib/tests/BLI_generic_array_test.cc17
-rw-r--r--source/blender/blenlib/tests/BLI_ghash_test.cc14
-rw-r--r--source/blender/blenlib/tests/BLI_hash_mm2a_test.cc12
-rw-r--r--source/blender/blenlib/tests/BLI_heap_simple_test.cc8
-rw-r--r--source/blender/blenlib/tests/BLI_heap_test.cc20
-rw-r--r--source/blender/blenlib/tests/BLI_index_range_test.cc57
-rw-r--r--source/blender/blenlib/tests/BLI_kdopbvh_test.cc4
-rw-r--r--source/blender/blenlib/tests/BLI_linear_allocator_test.cc18
-rw-r--r--source/blender/blenlib/tests/BLI_listbase_test.cc4
-rw-r--r--source/blender/blenlib/tests/BLI_map_test.cc22
-rw-r--r--source/blender/blenlib/tests/BLI_math_color_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_math_rotation_test.cc103
-rw-r--r--source/blender/blenlib/tests/BLI_memory_utils_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_mesh_boolean_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_mesh_intersect_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_path_util_test.cc13
-rw-r--r--source/blender/blenlib/tests/BLI_polyfill_2d_test.cc122
-rw-r--r--source/blender/blenlib/tests/BLI_pool_test.cc51
-rw-r--r--source/blender/blenlib/tests/BLI_set_test.cc23
-rw-r--r--source/blender/blenlib/tests/BLI_span_test.cc4
-rw-r--r--source/blender/blenlib/tests/BLI_stack_cxx_test.cc10
-rw-r--r--source/blender/blenlib/tests/BLI_stack_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_string_ref_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_string_search_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_string_test.cc103
-rw-r--r--source/blender/blenlib/tests/BLI_string_utf8_test.cc492
-rw-r--r--source/blender/blenlib/tests/BLI_task_test.cc13
-rw-r--r--source/blender/blenlib/tests/BLI_vector_set_test.cc13
-rw-r--r--source/blender/blenlib/tests/BLI_vector_test.cc19
-rw-r--r--source/blender/blenlib/tests/BLI_virtual_array_test.cc6
-rw-r--r--source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc40
-rw-r--r--source/blender/blenlib/tests/performance/BLI_task_performance_test.cc16
-rw-r--r--source/blender/blenlib/tests/performance/CMakeLists.txt8
166 files changed, 4292 insertions, 1805 deletions
diff --git a/source/blender/blenlib/BLI_allocator.hh b/source/blender/blenlib/BLI_allocator.hh
index f19292fffd8..db3caf2eeb7 100644
--- a/source/blender/blenlib/BLI_allocator.hh
+++ b/source/blender/blenlib/BLI_allocator.hh
@@ -63,15 +63,14 @@ class RawAllocator {
};
public:
- void *allocate(size_t size, size_t alignment, const char *UNUSED(name))
+ void *allocate(size_t size, size_t alignment, const char * /*name*/)
{
- BLI_assert(is_power_of_2_i(static_cast<int>(alignment)));
+ BLI_assert(is_power_of_2_i(int(alignment)));
void *ptr = malloc(size + alignment + sizeof(MemHead));
void *used_ptr = reinterpret_cast<void *>(
- reinterpret_cast<uintptr_t>(POINTER_OFFSET(ptr, alignment + sizeof(MemHead))) &
- ~(static_cast<uintptr_t>(alignment) - 1));
- int offset = static_cast<int>((intptr_t)used_ptr - (intptr_t)ptr);
- BLI_assert(offset >= static_cast<int>(sizeof(MemHead)));
+ uintptr_t(POINTER_OFFSET(ptr, alignment + sizeof(MemHead))) & ~(uintptr_t(alignment) - 1));
+ int offset = int(intptr_t(used_ptr) - intptr_t(ptr));
+ BLI_assert(offset >= int(sizeof(MemHead)));
(static_cast<MemHead *>(used_ptr) - 1)->offset = offset;
return used_ptr;
}
diff --git a/source/blender/blenlib/BLI_any.hh b/source/blender/blenlib/BLI_any.hh
index a20239f214f..df67a090e92 100644
--- a/source/blender/blenlib/BLI_any.hh
+++ b/source/blender/blenlib/BLI_any.hh
@@ -39,15 +39,16 @@ template<typename ExtraInfo> struct AnyTypeInfo {
* Used when #T is stored directly in the inline buffer of the #Any.
*/
template<typename ExtraInfo, typename T>
-static constexpr AnyTypeInfo<ExtraInfo> info_for_inline = {
+inline constexpr AnyTypeInfo<ExtraInfo> info_for_inline = {
is_trivially_copy_constructible_extended_v<T> ?
nullptr :
- +[](void *dst, const void *src) { new (dst) T(*(const T *)src); },
+ +[](void *dst, const void *src) { new (dst) T(*static_cast<const T *>(src)); },
is_trivially_move_constructible_extended_v<T> ?
nullptr :
- +[](void *dst, void *src) { new (dst) T(std::move(*(T *)src)); },
- is_trivially_destructible_extended_v<T> ? nullptr :
- +[](void *src) { std::destroy_at(((T *)src)); },
+ +[](void *dst, void *src) { new (dst) T(std::move(*static_cast<T *>(src))); },
+ is_trivially_destructible_extended_v<T> ?
+ nullptr :
+ +[](void *src) { std::destroy_at((static_cast<T *>(src))); },
nullptr,
ExtraInfo::template get<T>()};
@@ -57,7 +58,7 @@ static constexpr AnyTypeInfo<ExtraInfo> info_for_inline = {
*/
template<typename T> using Ptr = std::unique_ptr<T>;
template<typename ExtraInfo, typename T>
-static constexpr AnyTypeInfo<ExtraInfo> info_for_unique_ptr = {
+inline constexpr AnyTypeInfo<ExtraInfo> info_for_unique_ptr = {
[](void *dst, const void *src) { new (dst) Ptr<T>(new T(**(const Ptr<T> *)src)); },
[](void *dst, void *src) { new (dst) Ptr<T>(new T(std::move(**(Ptr<T> *)src))); },
[](void *src) { std::destroy_at((Ptr<T> *)src); },
diff --git a/source/blender/blenlib/BLI_array.hh b/source/blender/blenlib/BLI_array.hh
index 813277d9968..200381048c9 100644
--- a/source/blender/blenlib/BLI_array.hh
+++ b/source/blender/blenlib/BLI_array.hh
@@ -424,8 +424,7 @@ class Array {
T *allocate(int64_t size)
{
- return static_cast<T *>(
- allocator_.allocate(static_cast<size_t>(size) * sizeof(T), alignof(T), AT));
+ return static_cast<T *>(allocator_.allocate(size_t(size) * sizeof(T), alignof(T), AT));
}
void deallocate_if_not_inline(T *ptr)
diff --git a/source/blender/blenlib/BLI_array_store.h b/source/blender/blenlib/BLI_array_store.h
index 8a91825da6f..c04c392627d 100644
--- a/source/blender/blenlib/BLI_array_store.h
+++ b/source/blender/blenlib/BLI_array_store.h
@@ -57,7 +57,6 @@ size_t BLI_array_store_calc_size_expanded_get(const BArrayStore *bs);
size_t BLI_array_store_calc_size_compacted_get(const BArrayStore *bs);
/**
- *
* \param data: Data used to create
* \param state_reference: The state to use as a reference when adding the new state,
* typically this is the previous state,
diff --git a/source/blender/blenlib/BLI_array_utils.hh b/source/blender/blenlib/BLI_array_utils.hh
new file mode 100644
index 00000000000..264ac00e034
--- /dev/null
+++ b/source/blender/blenlib/BLI_array_utils.hh
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include "BLI_generic_span.hh"
+#include "BLI_generic_virtual_array.hh"
+#include "BLI_index_mask.hh"
+#include "BLI_task.hh"
+#include "BLI_virtual_array.hh"
+
+namespace blender::array_utils {
+
+/**
+ * Fill the destination span by copying masked values from the `src` array. Threaded based on
+ * grain-size.
+ */
+void copy(const GVArray &src, IndexMask selection, GMutableSpan dst, int64_t grain_size = 4096);
+
+/**
+ * Fill the destination span by copying values from the `src` array. Threaded based on
+ * grain-size.
+ */
+template<typename T>
+inline void copy(const Span<T> src,
+ const IndexMask selection,
+ MutableSpan<T> dst,
+ const int64_t grain_size = 4096)
+{
+ BLI_assert(src.size() == dst.size());
+ threading::parallel_for(selection.index_range(), grain_size, [&](const IndexRange range) {
+ for (const int64_t index : selection.slice(range)) {
+ dst[index] = src[index];
+ }
+ });
+}
+
+/**
+ * Fill the destination span by gathering indexed values from the `src` array.
+ */
+void gather(const GVArray &src, IndexMask indices, GMutableSpan dst, int64_t grain_size = 4096);
+
+/**
+ * Fill the destination span by gathering indexed values from the `src` array.
+ */
+void gather(GSpan src, IndexMask indices, GMutableSpan dst, int64_t grain_size = 4096);
+
+/**
+ * Fill the destination span by gathering indexed values from the `src` array.
+ */
+template<typename T>
+inline void gather(const VArray<T> &src,
+ const IndexMask indices,
+ MutableSpan<T> dst,
+ const int64_t grain_size = 4096)
+{
+ BLI_assert(indices.size() == dst.size());
+ threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) {
+ src.materialize_compressed_to_uninitialized(indices.slice(range), dst.slice(range).data());
+ });
+}
+
+/**
+ * Fill the destination span by gathering indexed values from the `src` array.
+ */
+template<typename T, typename IndexT>
+inline void gather(const Span<T> src,
+ const IndexMask indices,
+ MutableSpan<T> dst,
+ const int64_t grain_size = 4096)
+{
+ BLI_assert(indices.size() == dst.size());
+ threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) {
+ for (const int64_t i : range) {
+ dst[i] = src[indices[i]];
+ }
+ });
+}
+
+/**
+ * Fill the destination span by gathering indexed values from the `src` array.
+ */
+template<typename T, typename IndexT>
+inline void gather(const Span<T> src,
+ const Span<IndexT> indices,
+ MutableSpan<T> dst,
+ const int64_t grain_size = 4096)
+{
+ BLI_assert(indices.size() == dst.size());
+ threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) {
+ for (const int64_t i : range) {
+ dst[i] = src[indices[i]];
+ }
+ });
+}
+
+/**
+ * Fill the destination span by gathering indexed values from the `src` array.
+ */
+template<typename T, typename IndexT>
+inline void gather(const VArray<T> &src,
+ const Span<IndexT> indices,
+ MutableSpan<T> dst,
+ const int64_t grain_size = 4096)
+{
+ BLI_assert(indices.size() == dst.size());
+ devirtualize_varray(src, [&](const auto &src) {
+ threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) {
+ for (const int64_t i : range) {
+ dst[i] = src[indices[i]];
+ }
+ });
+ });
+}
+
+} // namespace blender::array_utils
diff --git a/source/blender/blenlib/BLI_assert.h b/source/blender/blenlib/BLI_assert.h
index 4a7fae6e98c..4292620e462 100644
--- a/source/blender/blenlib/BLI_assert.h
+++ b/source/blender/blenlib/BLI_assert.h
@@ -67,7 +67,7 @@ void _BLI_assert_unreachable_print(const char *file, int line, const char *funct
# define BLI_STATIC_ASSERT(a, msg) static_assert(a, msg);
#elif defined(_MSC_VER)
/* Visual Studio */
-# if (_MSC_VER > 1910) && !defined(__clang__)
+# if !defined(__clang__)
# define BLI_STATIC_ASSERT(a, msg) static_assert(a, msg);
# else
# define BLI_STATIC_ASSERT(a, msg) _STATIC_ASSERT(a);
diff --git a/source/blender/blenlib/BLI_bit_vector.hh b/source/blender/blenlib/BLI_bit_vector.hh
new file mode 100644
index 00000000000..ca6c6b2cd2a
--- /dev/null
+++ b/source/blender/blenlib/BLI_bit_vector.hh
@@ -0,0 +1,529 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+/** \file
+ * \ingroup bli
+ *
+ * A `blender::BitVector` is a dynamically growing contiguous arrays of bits. Its main purpose is
+ * to provide a compact way to map indices to bools. It requires 8 times less memory compared to a
+ * `blender::Vector<bool>`.
+ *
+ * Advantages of using a bit- instead of byte-vector are:
+ * - Uses less memory.
+ * - Allows checking the state of many elements at the same time (8 times more bits than bytes fit
+ * into a CPU register). This can improve performance.
+ *
+ * The compact nature of storing bools in individual bits has some downsides that have to be kept
+ * in mind:
+ * - Writing to separate bits in the same byte is not thread-safe. Therefore, an existing vector of
+ * bool can't easily be replaced with a bit vector, if it is written to from multiple threads.
+ * Read-only access from multiple threads is fine though.
+ * - Writing individual elements is more expensive when the array is in cache already. That is
+ * because changing a bit is always a read-modify-write operation on the byte the bit resides in.
+ * - Reading individual elements is more expensive when the array is in cache already. That is
+ * because additional bit-wise operations have to be applied after the corresponding byte is
+ * read.
+ *
+ * Comparison to `std::vector<bool>`:
+ * - `blender::BitVector` has an interface that is more optimized for dealing with bits.
+ * - `blender::BitVector` has an inline buffer that is used to avoid allocations when the vector is
+ * small.
+ *
+ * Comparison to `BLI_bitmap`:
+ * - `blender::BitVector` offers a more C++ friendly interface.
+ * - `BLI_bitmap` should only be used in C code that can not use `blender::BitVector`.
+ */
+
+#include <cstring>
+
+#include "BLI_allocator.hh"
+#include "BLI_index_range.hh"
+#include "BLI_memory_utils.hh"
+#include "BLI_span.hh"
+
+namespace blender {
+
+/**
+ * This is a read-only pointer to a specific bit. The value of the bit can be retrieved, but not
+ * changed.
+ */
+class BitRef {
+ private:
+ /** Points to the exact byte that the bit is in. */
+ const uint8_t *byte_ptr_;
+ /** All zeros except for a single one at the bit that is referenced. */
+ uint8_t mask_;
+
+ friend class MutableBitRef;
+
+ public:
+ BitRef() = default;
+
+ /**
+ * Reference a specific bit in a byte array. Note that #byte_ptr does *not* have to point to the
+ * exact byte the bit is in.
+ */
+ BitRef(const uint8_t *byte_ptr, const int64_t bit_index)
+ {
+ byte_ptr_ = byte_ptr + (bit_index >> 3);
+ mask_ = 1 << (bit_index & 7);
+ }
+
+ /**
+ * Return true when the bit is currently 1 and false otherwise.
+ */
+ bool test() const
+ {
+ const uint8_t byte = *byte_ptr_;
+ const uint8_t masked_byte = byte & mask_;
+ return masked_byte != 0;
+ }
+
+ operator bool() const
+ {
+ return this->test();
+ }
+};
+
+/**
+ * Similar to #BitRef, but also allows changing the referenced bit.
+ */
+class MutableBitRef {
+ private:
+ /** Points to the exact byte that the bit is in. */
+ uint8_t *byte_ptr_;
+ /** All zeros except for a single one at the bit that is referenced. */
+ uint8_t mask_;
+
+ public:
+ MutableBitRef() = default;
+
+ /**
+ * Reference a specific bit in a byte array. Note that #byte_ptr does *not* have to point to the
+ * exact byte the bit is in.
+ */
+ MutableBitRef(uint8_t *byte_ptr, const int64_t bit_index)
+ {
+ byte_ptr_ = byte_ptr + (bit_index >> 3);
+ mask_ = 1 << uint8_t(bit_index & 7);
+ }
+
+ /**
+ * Support implicitly casting to a read-only #BitRef.
+ */
+ operator BitRef() const
+ {
+ BitRef bit_ref;
+ bit_ref.byte_ptr_ = byte_ptr_;
+ bit_ref.mask_ = mask_;
+ return bit_ref;
+ }
+
+ /**
+ * Return true when the bit is currently 1 and false otherwise.
+ */
+ bool test() const
+ {
+ const uint8_t byte = *byte_ptr_;
+ const uint8_t masked_byte = byte & mask_;
+ return masked_byte != 0;
+ }
+
+ operator bool() const
+ {
+ return this->test();
+ }
+
+ /**
+ * Change the bit to a 1.
+ */
+ void set()
+ {
+ *byte_ptr_ |= mask_;
+ }
+
+ /**
+ * Change the bit to a 0.
+ */
+ void reset()
+ {
+ *byte_ptr_ &= ~mask_;
+ }
+
+ /**
+ * Change the bit to a 1 if #value is true and 0 otherwise.
+ */
+ void set(const bool value)
+ {
+ if (value) {
+ this->set();
+ }
+ else {
+ this->reset();
+ }
+ }
+};
+
+template<
+ /**
+ * Number of bits that can be stored in the vector without doing an allocation.
+ */
+ int64_t InlineBufferCapacity = 32,
+ /**
+ * The allocator used by this vector. Should rarely be changed, except when you don't want that
+ * MEM_* is used internally.
+ */
+ typename Allocator = GuardedAllocator>
+class BitVector {
+ private:
+ static constexpr int64_t required_bytes_for_bits(const int64_t number_of_bits)
+ {
+ return (number_of_bits + BitsPerByte - 1) / BitsPerByte;
+ }
+
+ static constexpr int64_t BitsPerByte = 8;
+ static constexpr int64_t BytesInInlineBuffer = required_bytes_for_bits(InlineBufferCapacity);
+ static constexpr int64_t BitsInInlineBuffer = BytesInInlineBuffer * BitsPerByte;
+ static constexpr int64_t AllocationAlignment = 8;
+
+ /**
+ * Points to the first byte used by the vector. It might point to the memory in the inline
+ * buffer.
+ */
+ uint8_t *data_;
+
+ /** Current size of the vector in bits. */
+ int64_t size_in_bits_;
+
+ /** Number of bits that fit into the vector until a reallocation has to occur. */
+ int64_t capacity_in_bits_;
+
+ /** Used for allocations when the inline buffer is too small. */
+ Allocator allocator_;
+
+ /** Contains the bits as long as the vector is small enough. */
+ TypedBuffer<uint8_t, BytesInInlineBuffer> inline_buffer_;
+
+ public:
+ BitVector(Allocator allocator = {}) noexcept : allocator_(allocator)
+ {
+ data_ = inline_buffer_;
+ size_in_bits_ = 0;
+ capacity_in_bits_ = BitsInInlineBuffer;
+ uninitialized_fill_n(data_, BytesInInlineBuffer, uint8_t(0));
+ }
+
+ BitVector(NoExceptConstructor, Allocator allocator = {}) noexcept : BitVector(allocator)
+ {
+ }
+
+ BitVector(const BitVector &other) : BitVector(NoExceptConstructor(), other.allocator_)
+ {
+ const int64_t bytes_to_copy = other.used_bytes_amount();
+ if (other.size_in_bits_ <= BitsInInlineBuffer) {
+ /* The data is copied into the owned inline buffer. */
+ data_ = inline_buffer_;
+ capacity_in_bits_ = BitsInInlineBuffer;
+ }
+ else {
+ /* Allocate a new byte array because the inline buffer is too small. */
+ data_ = static_cast<uint8_t *>(
+ allocator_.allocate(bytes_to_copy, AllocationAlignment, __func__));
+ capacity_in_bits_ = bytes_to_copy * BitsPerByte;
+ }
+ size_in_bits_ = other.size_in_bits_;
+ uninitialized_copy_n(other.data_, bytes_to_copy, data_);
+ }
+
+ BitVector(BitVector &&other) noexcept : BitVector(NoExceptConstructor(), other.allocator_)
+ {
+ if (other.is_inline()) {
+ /* Copy the data into the inline buffer. */
+ const int64_t bytes_to_copy = other.used_bytes_amount();
+ data_ = inline_buffer_;
+ uninitialized_copy_n(other.data_, bytes_to_copy, data_);
+ }
+ else {
+ /* Steal the pointer. */
+ data_ = other.data_;
+ }
+ size_in_bits_ = other.size_in_bits_;
+ capacity_in_bits_ = other.capacity_in_bits_;
+
+ /* Clear the other vector because it has been moved from. */
+ other.data_ = other.inline_buffer_;
+ other.size_in_bits_ = 0;
+ other.capacity_in_bits_ = BitsInInlineBuffer;
+ }
+
+ /**
+ * Create a new vector with the given size and fill it with #value.
+ */
+ BitVector(const int64_t size_in_bits, const bool value = false, Allocator allocator = {})
+ : BitVector(NoExceptConstructor(), allocator)
+ {
+ this->resize(size_in_bits, value);
+ }
+
+ /**
+ * Create a bit vector based on an array of bools. Each byte of the input array maps to one bit.
+ */
+ explicit BitVector(const Span<bool> values, Allocator allocator = {})
+ : BitVector(NoExceptConstructor(), allocator)
+ {
+ this->resize(values.size());
+ for (const int64_t i : this->index_range()) {
+ (*this)[i].set(values[i]);
+ }
+ }
+
+ ~BitVector()
+ {
+ if (!this->is_inline()) {
+ allocator_.deallocate(data_);
+ }
+ }
+
+ BitVector &operator=(const BitVector &other)
+ {
+ return copy_assign_container(*this, other);
+ }
+
+ BitVector &operator=(BitVector &&other)
+ {
+ return move_assign_container(*this, std::move(other));
+ }
+
+ /**
+ * Number of bits in the bit vector.
+ */
+ int64_t size() const
+ {
+ return size_in_bits_;
+ }
+
+ /**
+ * Get a read-only reference to a specific bit.
+ */
+ BitRef operator[](const int64_t index) const
+ {
+ BLI_assert(index >= 0);
+ BLI_assert(index < size_in_bits_);
+ return {data_, index};
+ }
+
+ /**
+ * Get a mutable reference to a specific bit.
+ */
+ MutableBitRef operator[](const int64_t index)
+ {
+ BLI_assert(index >= 0);
+ BLI_assert(index < size_in_bits_);
+ return {data_, index};
+ }
+
+ IndexRange index_range() const
+ {
+ return {0, size_in_bits_};
+ }
+
+ /**
+ * Add a new bit to the end of the vector.
+ */
+ void append(const bool value)
+ {
+ this->ensure_space_for_one();
+ MutableBitRef bit{data_, size_in_bits_};
+ bit.set(value);
+ size_in_bits_++;
+ }
+
+ class Iterator {
+ private:
+ const BitVector *vector_;
+ int64_t index_;
+
+ public:
+ Iterator(const BitVector &vector, const int64_t index) : vector_(&vector), index_(index)
+ {
+ }
+
+ Iterator &operator++()
+ {
+ index_++;
+ return *this;
+ }
+
+ friend bool operator!=(const Iterator &a, const Iterator &b)
+ {
+ BLI_assert(a.vector_ == b.vector_);
+ return a.index_ != b.index_;
+ }
+
+ BitRef operator*() const
+ {
+ return (*vector_)[index_];
+ }
+ };
+
+ class MutableIterator {
+ private:
+ BitVector *vector_;
+ int64_t index_;
+
+ public:
+ MutableIterator(BitVector &vector, const int64_t index) : vector_(&vector), index_(index)
+ {
+ }
+
+ MutableIterator &operator++()
+ {
+ index_++;
+ return *this;
+ }
+
+ friend bool operator!=(const MutableIterator &a, const MutableIterator &b)
+ {
+ BLI_assert(a.vector_ == b.vector_);
+ return a.index_ != b.index_;
+ }
+
+ MutableBitRef operator*() const
+ {
+ return (*vector_)[index_];
+ }
+ };
+
+ Iterator begin() const
+ {
+ return {*this, 0};
+ }
+
+ Iterator end() const
+ {
+ return {*this, size_in_bits_};
+ }
+
+ MutableIterator begin()
+ {
+ return {*this, 0};
+ }
+
+ MutableIterator end()
+ {
+ return {*this, size_in_bits_};
+ }
+
+ /**
+ * Change the size of the vector. If the new vector is larger than the old one, the new elements
+ * are filled with #value.
+ */
+ void resize(const int64_t new_size_in_bits, const bool value = false)
+ {
+ BLI_assert(new_size_in_bits >= 0);
+ const int64_t old_size_in_bits = size_in_bits_;
+ if (new_size_in_bits > old_size_in_bits) {
+ this->reserve(new_size_in_bits);
+ }
+ size_in_bits_ = new_size_in_bits;
+ if (old_size_in_bits < new_size_in_bits) {
+ this->fill_range(IndexRange(old_size_in_bits, new_size_in_bits - old_size_in_bits), value);
+ }
+ }
+
+ /**
+ * Set #value for every element in #range.
+ */
+ void fill_range(const IndexRange range, const bool value)
+ {
+ const AlignedIndexRanges aligned_ranges = split_index_range_by_alignment(range, BitsPerByte);
+
+ /* Fill first few bits. */
+ for (const int64_t i : aligned_ranges.prefix) {
+ (*this)[i].set(value);
+ }
+
+ /* Fill entire bytes at once. */
+ const int64_t start_fill_byte_index = aligned_ranges.aligned.start() / BitsPerByte;
+ const int64_t bytes_to_fill = aligned_ranges.aligned.size() / BitsPerByte;
+ const uint8_t fill_value = value ? uint8_t(0xff) : uint8_t(0x00);
+ initialized_fill_n(data_ + start_fill_byte_index, bytes_to_fill, fill_value);
+
+ /* Fill bits in the end that don't cover a full byte. */
+ for (const int64_t i : aligned_ranges.suffix) {
+ (*this)[i].set(value);
+ }
+ }
+
+ /**
+ * Set #value on every element.
+ */
+ void fill(const bool value)
+ {
+ this->fill_range(IndexRange(0, size_in_bits_), value);
+ }
+
+ /**
+ * Make sure that the capacity of the vector is large enough to hold the given amount of bits.
+ * The actual size is not changed.
+ */
+ void reserve(const int new_capacity_in_bits)
+ {
+ this->realloc_to_at_least(new_capacity_in_bits);
+ }
+
+ private:
+ void ensure_space_for_one()
+ {
+ if (UNLIKELY(size_in_bits_ >= capacity_in_bits_)) {
+ this->realloc_to_at_least(size_in_bits_ + 1);
+ }
+ }
+
+ BLI_NOINLINE void realloc_to_at_least(const int64_t min_capacity_in_bits,
+ const uint8_t initial_value_for_new_bytes = 0x00)
+ {
+ if (capacity_in_bits_ >= min_capacity_in_bits) {
+ return;
+ }
+
+ const int64_t min_capacity_in_bytes = this->required_bytes_for_bits(min_capacity_in_bits);
+
+ /* At least double the size of the previous allocation. */
+ const int64_t min_new_capacity_in_bytes = capacity_in_bits_ * 2;
+
+ const int64_t new_capacity_in_bytes = std::max(min_capacity_in_bytes,
+ min_new_capacity_in_bytes);
+ const int64_t bytes_to_copy = this->used_bytes_amount();
+
+ uint8_t *new_data = static_cast<uint8_t *>(
+ allocator_.allocate(new_capacity_in_bytes, AllocationAlignment, __func__));
+ uninitialized_copy_n(data_, bytes_to_copy, new_data);
+ /* Always initialize new capacity even if it isn't used yet. That's necessary to avoid warnings
+ * caused by using uninitialized memory. This happens when e.g. setting a clearing a bit in an
+ * uninitialized byte. */
+ uninitialized_fill_n(new_data + bytes_to_copy,
+ new_capacity_in_bytes - bytes_to_copy,
+ uint8_t(initial_value_for_new_bytes));
+
+ if (!this->is_inline()) {
+ allocator_.deallocate(data_);
+ }
+
+ data_ = new_data;
+ capacity_in_bits_ = new_capacity_in_bytes * BitsPerByte;
+ }
+
+ bool is_inline() const
+ {
+ return data_ == inline_buffer_;
+ }
+
+ int64_t used_bytes_amount() const
+ {
+ return this->required_bytes_for_bits(size_in_bits_);
+ }
+};
+
+} // namespace blender
diff --git a/source/blender/blenlib/BLI_compiler_attrs.h b/source/blender/blenlib/BLI_compiler_attrs.h
index 99f0aa9f049..f0566e0b3e2 100644
--- a/source/blender/blenlib/BLI_compiler_attrs.h
+++ b/source/blender/blenlib/BLI_compiler_attrs.h
@@ -25,7 +25,7 @@
#endif
/* never returns NULL */
-#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409 /* gcc4.9+ only */
+#ifdef __GNUC__
# define ATTR_RETURNS_NONNULL __attribute__((returns_nonnull))
#else
# define ATTR_RETURNS_NONNULL
@@ -39,14 +39,14 @@
#endif
/* hint to treat any non-null function return value cannot alias any other pointer */
-#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 403))
+#ifdef __GNUC__
# define ATTR_MALLOC __attribute__((malloc))
#else
# define ATTR_MALLOC
#endif
/* the function return value points to memory (2 args for 'size * tot') */
-#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 403))
+#if defined(__GNUC__) && !defined(__clang__)
# define ATTR_ALLOC_SIZE(args...) __attribute__((alloc_size(args)))
#else
# define ATTR_ALLOC_SIZE(...)
@@ -69,7 +69,7 @@
/* Use to suppress '-Wimplicit-fallthrough' (in place of 'break'). */
#ifndef ATTR_FALLTHROUGH
-# if defined(__GNUC__) && (__GNUC__ >= 7) /* gcc7.0+ only */
+# ifdef __GNUC__
# define ATTR_FALLTHROUGH __attribute__((fallthrough))
# else
# define ATTR_FALLTHROUGH ((void)0)
diff --git a/source/blender/blenlib/BLI_compute_context.hh b/source/blender/blenlib/BLI_compute_context.hh
new file mode 100644
index 00000000000..e3e5b6f9e85
--- /dev/null
+++ b/source/blender/blenlib/BLI_compute_context.hh
@@ -0,0 +1,173 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+/** \file
+ * \ingroup bli
+ *
+ * When logging computed values, we generally want to know where the value was computed. For
+ * example, geometry nodes logs socket values so that they can be displayed in the ui. For that we
+ * can combine the logged value with a `ComputeContext`, which identifies the place where the value
+ * was computed.
+ *
+ * This is not a trivial problem because e.g. just storing a pointer to the socket a value
+ * belongs to is not enough. That's because the same socket may correspond to many different values
+ * when the socket is used in a node group that is used multiple times. In this case, not only does
+ * the socket have to be stored but also the entire nested node group path that led to the
+ * evaluation of the socket.
+ *
+ * Storing the entire "context path" for every logged value is not feasible, because that path can
+ * become quite long. So that would need much more memory, more compute overhead and makes it
+ * complicated to compare if two contexts are the same. If the identifier for a compute context
+ * would have a variable size, it would also be much harder to create a map from context to values.
+ *
+ * The solution implemented below uses the following key ideas:
+ * - Every compute context can be hashed to a unique fixed size value (`ComputeContextHash`). While
+ * technically there could be hash collisions, the hashing algorithm has to be chosen to make
+ * that practically impossible. This way an entire context path, possibly consisting of many
+ * nested contexts, is represented by a single value that can be stored easily.
+ * - A nested compute context is build as singly linked list, where every compute context has a
+ * pointer to the parent compute context. Note that a link in the other direction is not possible
+ * because the same parent compute context may be used by many different children which possibly
+ * run on different threads.
+ */
+
+#include "BLI_array.hh"
+#include "BLI_linear_allocator.hh"
+#include "BLI_stack.hh"
+#include "BLI_string_ref.hh"
+
+namespace blender {
+
+/**
+ * A hash that uniquely identifies a specific (non-fixed-size) compute context. The hash has to
+ * have enough bits to make collisions practically impossible.
+ */
+struct ComputeContextHash {
+ static constexpr int64_t HashSizeInBytes = 16;
+ uint64_t v1 = 0;
+ uint64_t v2 = 0;
+
+ uint64_t hash() const
+ {
+ return v1;
+ }
+
+ friend bool operator==(const ComputeContextHash &a, const ComputeContextHash &b)
+ {
+ return a.v1 == b.v1 && a.v2 == b.v2;
+ }
+
+ void mix_in(const void *data, int64_t len);
+
+ friend std::ostream &operator<<(std::ostream &stream, const ComputeContextHash &hash);
+};
+
+static_assert(sizeof(ComputeContextHash) == ComputeContextHash::HashSizeInBytes);
+
+/**
+ * Identifies the context in which a computation happens. This context can be used to identify
+ * values logged during the computation. For more details, see the comment at the top of the file.
+ *
+ * This class should be subclassed to implement specific contexts.
+ */
+class ComputeContext {
+ private:
+ /**
+ * Only used for debugging currently.
+ */
+ const char *static_type_;
+ /**
+ * Pointer to the context that this context is child of. That allows nesting compute contexts.
+ */
+ const ComputeContext *parent_ = nullptr;
+
+ protected:
+ /**
+ * The hash that uniquely identifies this context. It's a combined hash of this context as well
+ * as all the parent contexts.
+ */
+ ComputeContextHash hash_;
+
+ public:
+ ComputeContext(const char *static_type, const ComputeContext *parent)
+ : static_type_(static_type), parent_(parent)
+ {
+ if (parent != nullptr) {
+ hash_ = parent_->hash_;
+ }
+ }
+ virtual ~ComputeContext() = default;
+
+ const ComputeContextHash &hash() const
+ {
+ return hash_;
+ }
+
+ const char *static_type() const
+ {
+ return static_type_;
+ }
+
+ const ComputeContext *parent() const
+ {
+ return parent_;
+ }
+
+ /**
+ * Print the entire nested context stack.
+ */
+ void print_stack(std::ostream &stream, StringRef name) const;
+
+ /**
+ * Print information about this specific context. This has to be implemented by each subclass.
+ */
+ virtual void print_current_in_line(std::ostream &stream) const = 0;
+
+ friend std::ostream &operator<<(std::ostream &stream, const ComputeContext &compute_context);
+};
+
+/**
+ * Utility class to build a context stack in one place. This is typically used to get the hash that
+ * corresponds to a specific nested compute context, in order to look up corresponding logged
+ * values.
+ */
+class ComputeContextBuilder {
+ private:
+ LinearAllocator<> allocator_;
+ Stack<destruct_ptr<ComputeContext>> contexts_;
+
+ public:
+ bool is_empty() const
+ {
+ return contexts_.is_empty();
+ }
+
+ const ComputeContext *current() const
+ {
+ if (contexts_.is_empty()) {
+ return nullptr;
+ }
+ return contexts_.peek().get();
+ }
+
+ const ComputeContextHash hash() const
+ {
+ BLI_assert(!contexts_.is_empty());
+ return this->current()->hash();
+ }
+
+ template<typename T, typename... Args> void push(Args &&...args)
+ {
+ const ComputeContext *current = this->current();
+ destruct_ptr<T> context = allocator_.construct<T>(current, std::forward<Args>(args)...);
+ contexts_.push(std::move(context));
+ }
+
+ void pop()
+ {
+ contexts_.pop();
+ }
+};
+
+} // namespace blender
diff --git a/source/blender/blenlib/BLI_convexhull_2d.h b/source/blender/blenlib/BLI_convexhull_2d.h
index 0b4c3d486fb..044c1da6925 100644
--- a/source/blender/blenlib/BLI_convexhull_2d.h
+++ b/source/blender/blenlib/BLI_convexhull_2d.h
@@ -11,43 +11,26 @@ extern "C" {
#endif
/**
- * A.M. Andrew's monotone chain 2D convex hull algorithm.
- *
- * \param points: An array of 2D points presorted by increasing x and y-coords.
- * \param n: The number of points in points.
- * \param r_points: An array of the convex hull vertex indices (max is n).
- * \returns the number of points in r_points.
- */
-int BLI_convexhull_2d_sorted(const float (*points)[2], int n, int r_points[]);
-/**
- * A.M. Andrew's monotone chain 2D convex hull algorithm.
+ * Extract 2D convex hull.
*
* \param points: An array of 2D points.
* \param n: The number of points in points.
* \param r_points: An array of the convex hull vertex indices (max is n).
- * _must_ be allocated as `n * 2` because of how its used internally,
- * even though the final result will be no more than \a n in size.
- * \returns the number of points in r_points.
- */
-int BLI_convexhull_2d(const float (*points)[2], int n, int r_points[]);
-
-/**
- * \return The best angle for fitting the convex hull to an axis aligned bounding box.
- *
- * Intended to be used with #BLI_convexhull_2d
+ * \return The number of indices in r_points.
*
- * \param points_hull: Ordered hull points
- * (result of #BLI_convexhull_2d mapped to a contiguous array).
+ * \note Performance is `O(n.log(n))`, same as `qsort`.
*
- * \note we could return the index of the best edge too if its needed.
*/
-float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned int n);
+int BLI_convexhull_2d(const float (*points)[2], int n, int r_points[/* n */]);
+
/**
- * Wrap #BLI_convexhull_aabb_fit_hull_2d and do the convex hull calculation.
+ * \return The best angle for fitting the points to an axis aligned bounding box.
+ *
+ * \note We could return the index of the best edge too if its needed.
*
- * \param points: arbitrary 2d points.
+ * \param points: Arbitrary 2d points.
*/
-float BLI_convexhull_aabb_fit_points_2d(const float (*points)[2], unsigned int n);
+float BLI_convexhull_aabb_fit_points_2d(const float (*points)[2], int n);
#ifdef __cplusplus
}
diff --git a/source/blender/blenlib/BLI_cpp_type.hh b/source/blender/blenlib/BLI_cpp_type.hh
index cc48b456da7..568ccbb5a64 100644
--- a/source/blender/blenlib/BLI_cpp_type.hh
+++ b/source/blender/blenlib/BLI_cpp_type.hh
@@ -20,7 +20,7 @@
* cost of longer compile time, a larger binary and the complexity that comes from using
* templates).
* - If the code is not performance sensitive, it usually makes sense to use #CPPType instead.
- * - Sometimes a combination can make sense. Optimized code can be be generated at compile-time for
+ * - Sometimes a combination can make sense. Optimized code can be generated at compile-time for
* some types, while there is a fallback code path using #CPPType for all other types.
* #CPPType::to_static_type allows dispatching between both versions based on the type.
*
@@ -297,7 +297,7 @@ class CPPType : NonCopyable, NonMovable {
*/
bool pointer_has_valid_alignment(const void *ptr) const
{
- return ((uintptr_t)ptr & alignment_mask_) == 0;
+ return (uintptr_t(ptr) & alignment_mask_) == 0;
}
bool pointer_can_point_to_instance(const void *ptr) const
diff --git a/source/blender/blenlib/BLI_cpp_type_make.hh b/source/blender/blenlib/BLI_cpp_type_make.hh
index b0dbbff7ca8..1f494624821 100644
--- a/source/blender/blenlib/BLI_cpp_type_make.hh
+++ b/source/blender/blenlib/BLI_cpp_type_make.hh
@@ -211,8 +211,8 @@ CPPType::CPPType(CPPTypeParam<T, Flags> /* unused */, StringRef debug_name)
using namespace cpp_type_util;
debug_name_ = debug_name;
- size_ = (int64_t)sizeof(T);
- alignment_ = (int64_t)alignof(T);
+ size_ = int64_t(sizeof(T));
+ alignment_ = int64_t(alignof(T));
is_trivial_ = std::is_trivial_v<T>;
is_trivially_destructible_ = std::is_trivially_destructible_v<T>;
if constexpr (std::is_default_constructible_v<T>) {
@@ -221,7 +221,7 @@ CPPType::CPPType(CPPTypeParam<T, Flags> /* unused */, StringRef debug_name)
value_initialize_ = value_initialize_cb<T>;
value_initialize_indices_ = value_initialize_indices_cb<T>;
static T default_value;
- default_value_ = (void *)&default_value;
+ default_value_ = &default_value;
}
if constexpr (std::is_destructible_v<T>) {
destruct_ = destruct_cb<T>;
@@ -271,7 +271,7 @@ CPPType::CPPType(CPPTypeParam<T, Flags> /* unused */, StringRef debug_name)
is_equal_ = is_equal_cb<T>;
}
- alignment_mask_ = (uintptr_t)alignment_ - (uintptr_t)1;
+ alignment_mask_ = uintptr_t(alignment_) - uintptr_t(1);
has_special_member_functions_ = (default_construct_ && copy_construct_ && copy_assign_ &&
move_construct_ && move_assign_ && destruct_);
}
diff --git a/source/blender/blenlib/BLI_dot_export.hh b/source/blender/blenlib/BLI_dot_export.hh
index b6decca0720..454f3c8412c 100644
--- a/source/blender/blenlib/BLI_dot_export.hh
+++ b/source/blender/blenlib/BLI_dot_export.hh
@@ -98,7 +98,7 @@ class Cluster {
std::string name() const
{
- return "cluster_" + std::to_string((uintptr_t)this);
+ return "cluster_" + std::to_string(uintptr_t(this));
}
void set_parent_cluster(Cluster *new_parent);
diff --git a/source/blender/blenlib/BLI_endian_switch_inline.h b/source/blender/blenlib/BLI_endian_switch_inline.h
index ce44348d4dd..32cb0f234f2 100644
--- a/source/blender/blenlib/BLI_endian_switch_inline.h
+++ b/source/blender/blenlib/BLI_endian_switch_inline.h
@@ -26,7 +26,7 @@ BLI_INLINE void BLI_endian_switch_int16(short *val)
}
BLI_INLINE void BLI_endian_switch_uint16(unsigned short *val)
{
-#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 408)) /* gcc4.8+ only */
+#ifdef __GNUC__
*val = __builtin_bswap16(*val);
#else
unsigned short tval = *val;
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index 063e60ecf03..0ff75ca16e5 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -101,6 +101,7 @@ typedef enum eFileAttributes {
FILE_ATTR_MOUNT_POINT = 1 << 14, /* Volume mounted as a folder. */
FILE_ATTR_HARDLINK = 1 << 15, /* Duplicated directory entry. */
} eFileAttributes;
+ENUM_OPERATORS(eFileAttributes, FILE_ATTR_HARDLINK);
#define FILE_ATTR_ANY_LINK \
(FILE_ATTR_ALIAS | FILE_ATTR_REPARSE_POINT | FILE_ATTR_SYMLINK | FILE_ATTR_JUNCTION_POINT | \
diff --git a/source/blender/blenlib/BLI_float3x3.hh b/source/blender/blenlib/BLI_float3x3.hh
index 6a9e7dd04f0..178973c155d 100644
--- a/source/blender/blenlib/BLI_float3x3.hh
+++ b/source/blender/blenlib/BLI_float3x3.hh
@@ -63,6 +63,15 @@ struct float3x3 {
return result;
}
+ static float3x3 from_scale(const float2 scale)
+ {
+ float3x3 result = zero();
+ result.values[0][0] = scale.x;
+ result.values[1][1] = scale.y;
+ result.values[2][2] = 1.0f;
+ return result;
+ }
+
static float3x3 from_translation_rotation_scale(const float2 translation,
float rotation,
const float2 scale)
@@ -190,6 +199,13 @@ struct float3x3 {
return result;
}
+ float2 scale_2d() const
+ {
+ float2 scale;
+ mat3_to_size_2d(scale, values);
+ return scale;
+ }
+
friend bool operator==(const float3x3 &a, const float3x3 &b)
{
return equals_m3m3(a.values, b.values);
diff --git a/source/blender/blenlib/BLI_float4x4.hh b/source/blender/blenlib/BLI_float4x4.hh
index 64e6e68432f..ca0d9ea0028 100644
--- a/source/blender/blenlib/BLI_float4x4.hh
+++ b/source/blender/blenlib/BLI_float4x4.hh
@@ -266,7 +266,7 @@ struct float4x4 {
for (int j = 0; j < 4; j++) {
snprintf(fchar, sizeof(fchar), "%11.6f", mat[j][i]);
stream << fchar;
- if (i != 3) {
+ if (j != 3) {
stream << ", ";
}
}
diff --git a/source/blender/blenlib/BLI_function_ref.hh b/source/blender/blenlib/BLI_function_ref.hh
index 5f18e994991..bc386322c5d 100644
--- a/source/blender/blenlib/BLI_function_ref.hh
+++ b/source/blender/blenlib/BLI_function_ref.hh
@@ -63,7 +63,6 @@
*
* void some_function(FunctionRef<int()> f);
* some_function([]() { return 0; });
- *
*/
#include "BLI_memory_utils.hh"
@@ -117,7 +116,7 @@ template<typename Ret, typename... Params> class FunctionRef<Ret(Params...)> {
!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Callable>>, FunctionRef>))>
FunctionRef(Callable &&callable)
: callback_(callback_fn<typename std::remove_reference_t<Callable>>),
- callable_(reinterpret_cast<intptr_t>(&callable))
+ callable_(intptr_t(&callable))
{
}
diff --git a/source/blender/blenlib/BLI_generic_array.hh b/source/blender/blenlib/BLI_generic_array.hh
index 4b917434264..03dc8814309 100644
--- a/source/blender/blenlib/BLI_generic_array.hh
+++ b/source/blender/blenlib/BLI_generic_array.hh
@@ -231,7 +231,9 @@ class GArray {
this->deallocate(new_data);
throw;
}
- this->deallocate(data_);
+ if (this->data_) {
+ this->deallocate(data_);
+ }
data_ = new_data;
}
@@ -243,7 +245,7 @@ class GArray {
{
const int64_t item_size = type_->size();
const int64_t alignment = type_->alignment();
- return allocator_.allocate(static_cast<size_t>(size) * item_size, alignment, AT);
+ return allocator_.allocate(size_t(size) * item_size, alignment, AT);
}
void deallocate(void *ptr)
diff --git a/source/blender/blenlib/BLI_generic_span.hh b/source/blender/blenlib/BLI_generic_span.hh
index 143ab235d2e..e7a08988c46 100644
--- a/source/blender/blenlib/BLI_generic_span.hh
+++ b/source/blender/blenlib/BLI_generic_span.hh
@@ -100,6 +100,34 @@ class GSpan {
{
return this->slice(range.start(), range.size());
}
+
+ GSpan drop_front(const int64_t n) const
+ {
+ BLI_assert(n >= 0);
+ const int64_t new_size = std::max<int64_t>(0, size_ - n);
+ return GSpan(*type_, POINTER_OFFSET(data_, type_->size() * n), new_size);
+ }
+
+ GSpan drop_back(const int64_t n) const
+ {
+ BLI_assert(n >= 0);
+ const int64_t new_size = std::max<int64_t>(0, size_ - n);
+ return GSpan(*type_, data_, new_size);
+ }
+
+ GSpan take_front(const int64_t n) const
+ {
+ BLI_assert(n >= 0);
+ const int64_t new_size = std::min<int64_t>(size_, n);
+ return GSpan(*type_, data_, new_size);
+ }
+
+ GSpan take_back(const int64_t n) const
+ {
+ BLI_assert(n >= 0);
+ const int64_t new_size = std::min<int64_t>(size_, n);
+ return GSpan(*type_, POINTER_OFFSET(data_, type_->size() * (size_ - new_size)), new_size);
+ }
};
/**
@@ -199,6 +227,35 @@ class GMutableSpan {
return this->slice(range.start(), range.size());
}
+ GMutableSpan drop_front(const int64_t n) const
+ {
+ BLI_assert(n >= 0);
+ const int64_t new_size = std::max<int64_t>(0, size_ - n);
+ return GMutableSpan(*type_, POINTER_OFFSET(data_, type_->size() * n), new_size);
+ }
+
+ GMutableSpan drop_back(const int64_t n) const
+ {
+ BLI_assert(n >= 0);
+ const int64_t new_size = std::max<int64_t>(0, size_ - n);
+ return GMutableSpan(*type_, data_, new_size);
+ }
+
+ GMutableSpan take_front(const int64_t n) const
+ {
+ BLI_assert(n >= 0);
+ const int64_t new_size = std::min<int64_t>(size_, n);
+ return GMutableSpan(*type_, data_, new_size);
+ }
+
+ GMutableSpan take_back(const int64_t n) const
+ {
+ BLI_assert(n >= 0);
+ const int64_t new_size = std::min<int64_t>(size_, n);
+ return GMutableSpan(
+ *type_, POINTER_OFFSET(data_, type_->size() * (size_ - new_size)), new_size);
+ }
+
/**
* Copy all values from another span into this span. This invokes undefined behavior when the
* destination contains uninitialized data and T is not trivially copy constructible.
diff --git a/source/blender/blenlib/BLI_generic_virtual_array.hh b/source/blender/blenlib/BLI_generic_virtual_array.hh
index 43ca16a894f..e8a27cea6d8 100644
--- a/source/blender/blenlib/BLI_generic_virtual_array.hh
+++ b/source/blender/blenlib/BLI_generic_virtual_array.hh
@@ -78,7 +78,7 @@ class GVMutableArrayImpl : public GVArrayImpl {
namespace detail {
struct GVArrayAnyExtraInfo {
const GVArrayImpl *(*get_varray)(const void *buffer) =
- [](const void *UNUSED(buffer)) -> const GVArrayImpl * { return nullptr; };
+ [](const void * /*buffer*/) -> const GVArrayImpl * { return nullptr; };
template<typename StorageT> static constexpr GVArrayAnyExtraInfo get();
};
@@ -315,7 +315,7 @@ template<typename T> class GVArrayImpl_For_VArray : public GVArrayImpl {
protected:
void get(const int64_t index, void *r_value) const override
{
- *(T *)r_value = varray_[index];
+ *static_cast<T *>(r_value) = varray_[index];
}
void get_to_uninitialized(const int64_t index, void *r_value) const override
@@ -325,22 +325,24 @@ template<typename T> class GVArrayImpl_For_VArray : public GVArrayImpl {
void materialize(const IndexMask mask, void *dst) const override
{
- varray_.materialize(mask, MutableSpan((T *)dst, mask.min_array_size()));
+ varray_.materialize(mask, MutableSpan(static_cast<T *>(dst), mask.min_array_size()));
}
void materialize_to_uninitialized(const IndexMask mask, void *dst) const override
{
- varray_.materialize_to_uninitialized(mask, MutableSpan((T *)dst, mask.min_array_size()));
+ varray_.materialize_to_uninitialized(
+ mask, MutableSpan(static_cast<T *>(dst), mask.min_array_size()));
}
void materialize_compressed(const IndexMask mask, void *dst) const override
{
- varray_.materialize_compressed(mask, MutableSpan((T *)dst, mask.size()));
+ varray_.materialize_compressed(mask, MutableSpan(static_cast<T *>(dst), mask.size()));
}
void materialize_compressed_to_uninitialized(const IndexMask mask, void *dst) const override
{
- varray_.materialize_compressed_to_uninitialized(mask, MutableSpan((T *)dst, mask.size()));
+ varray_.materialize_compressed_to_uninitialized(
+ mask, MutableSpan(static_cast<T *>(dst), mask.size()));
}
bool try_assign_VArray(void *varray) const override
@@ -422,7 +424,7 @@ template<typename T> class GVMutableArrayImpl_For_VMutableArray : public GVMutab
protected:
void get(const int64_t index, void *r_value) const override
{
- *(T *)r_value = varray_[index];
+ *static_cast<T *>(r_value) = varray_[index];
}
void get_to_uninitialized(const int64_t index, void *r_value) const override
@@ -443,40 +445,42 @@ template<typename T> class GVMutableArrayImpl_For_VMutableArray : public GVMutab
void set_by_relocate(const int64_t index, void *value) override
{
- T &value_ = *(T *)value;
+ T &value_ = *static_cast<T *>(value);
varray_.set(index, std::move(value_));
value_.~T();
}
void set_by_move(const int64_t index, void *value) override
{
- T &value_ = *(T *)value;
+ T &value_ = *static_cast<T *>(value);
varray_.set(index, std::move(value_));
}
void set_all(const void *src) override
{
- varray_.set_all(Span((T *)src, size_));
+ varray_.set_all(Span(static_cast<const T *>(src), size_));
}
void materialize(const IndexMask mask, void *dst) const override
{
- varray_.materialize(mask, MutableSpan((T *)dst, mask.min_array_size()));
+ varray_.materialize(mask, MutableSpan(static_cast<T *>(dst), mask.min_array_size()));
}
void materialize_to_uninitialized(const IndexMask mask, void *dst) const override
{
- varray_.materialize_to_uninitialized(mask, MutableSpan((T *)dst, mask.min_array_size()));
+ varray_.materialize_to_uninitialized(
+ mask, MutableSpan(static_cast<T *>(dst), mask.min_array_size()));
}
void materialize_compressed(const IndexMask mask, void *dst) const override
{
- varray_.materialize_compressed(mask, MutableSpan((T *)dst, mask.size()));
+ varray_.materialize_compressed(mask, MutableSpan(static_cast<T *>(dst), mask.size()));
}
void materialize_compressed_to_uninitialized(const IndexMask mask, void *dst) const override
{
- varray_.materialize_compressed_to_uninitialized(mask, MutableSpan((T *)dst, mask.size()));
+ varray_.materialize_compressed_to_uninitialized(
+ mask, MutableSpan(static_cast<T *>(dst), mask.size()));
}
bool try_assign_VArray(void *varray) const override
@@ -709,7 +713,7 @@ inline bool GVMutableArray::try_assign_VMutableArray(VMutableArray<T> &varray) c
inline GVMutableArrayImpl *GVMutableArray::get_impl() const
{
- return (GVMutableArrayImpl *)impl_;
+ return const_cast<GVMutableArrayImpl *>(static_cast<const GVMutableArrayImpl *>(impl_));
}
/** \} */
@@ -860,6 +864,7 @@ template<typename T> inline GVArray::GVArray(const VArray<T> &varray)
* #this is destructed. */
if (info.type == CommonVArrayInfo::Type::Span && !info.may_have_ownership) {
*this = GVArray::ForSpan(GSpan(CPPType::get<T>(), info.data, varray.size()));
+ return;
}
if (varray.try_assign_GVArray(*this)) {
return;
diff --git a/source/blender/blenlib/BLI_generic_virtual_vector_array.hh b/source/blender/blenlib/BLI_generic_virtual_vector_array.hh
index 364b1ab33c7..373d010d926 100644
--- a/source/blender/blenlib/BLI_generic_virtual_vector_array.hh
+++ b/source/blender/blenlib/BLI_generic_virtual_vector_array.hh
@@ -133,8 +133,8 @@ class GVVectorArray_For_SingleGSpan : public GVVectorArray {
}
protected:
- int64_t get_vector_size_impl(int64_t UNUSED(index)) const override;
- void get_vector_element_impl(int64_t UNUSED(index),
+ int64_t get_vector_size_impl(int64_t /*index*/) const override;
+ void get_vector_element_impl(int64_t /*index*/,
int64_t index_in_vector,
void *r_value) const override;
diff --git a/source/blender/blenlib/BLI_hash.hh b/source/blender/blenlib/BLI_hash.hh
index 25d7cd6aaf8..693d4a8a71c 100644
--- a/source/blender/blenlib/BLI_hash.hh
+++ b/source/blender/blenlib/BLI_hash.hh
@@ -85,7 +85,7 @@ template<typename T> struct DefaultHash {
{
if constexpr (std::is_enum_v<T>) {
/* For enums use the value as hash directly. */
- return (uint64_t)value;
+ return uint64_t(value);
}
else {
/* Try to call the `hash()` function on the value. */
@@ -119,7 +119,7 @@ template<typename T> struct DefaultHash<const T> {
template<> struct DefaultHash<TYPE> { \
uint64_t operator()(TYPE value) const \
{ \
- return static_cast<uint64_t>(value); \
+ return uint64_t(value); \
} \
}
@@ -158,7 +158,7 @@ template<> struct DefaultHash<double> {
template<> struct DefaultHash<bool> {
uint64_t operator()(bool value) const
{
- return static_cast<uint64_t>((value != false) * 1298191);
+ return uint64_t((value != false) * 1298191);
}
};
@@ -209,8 +209,8 @@ template<> struct DefaultHash<std::string_view> {
template<typename T> struct DefaultHash<T *> {
uint64_t operator()(const T *value) const
{
- uintptr_t ptr = reinterpret_cast<uintptr_t>(value);
- uint64_t hash = static_cast<uint64_t>(ptr >> 4);
+ uintptr_t ptr = uintptr_t(value);
+ uint64_t hash = uint64_t(ptr >> 4);
return hash;
}
};
diff --git a/source/blender/blenlib/BLI_hash_tables.hh b/source/blender/blenlib/BLI_hash_tables.hh
index 156fe481828..de65c58d4db 100644
--- a/source/blender/blenlib/BLI_hash_tables.hh
+++ b/source/blender/blenlib/BLI_hash_tables.hh
@@ -43,8 +43,7 @@ inline constexpr int64_t log2_floor_constexpr(const int64_t x)
inline constexpr int64_t log2_ceil_constexpr(const int64_t x)
{
BLI_assert(x >= 0);
- return (is_power_of_2_constexpr(static_cast<int>(x))) ? log2_floor_constexpr(x) :
- log2_floor_constexpr(x) + 1;
+ return (is_power_of_2_constexpr(int(x))) ? log2_floor_constexpr(x) : log2_floor_constexpr(x) + 1;
}
inline constexpr int64_t power_of_2_max_constexpr(const int64_t x)
@@ -71,17 +70,14 @@ inline constexpr int64_t ceil_division_by_fraction(const int64_t x,
const int64_t numerator,
const int64_t denominator)
{
- return static_cast<int64_t>(
- ceil_division(static_cast<uint64_t>(x) * static_cast<uint64_t>(denominator),
- static_cast<uint64_t>(numerator)));
+ return int64_t(ceil_division(uint64_t(x) * uint64_t(denominator), uint64_t(numerator)));
}
inline constexpr int64_t floor_multiplication_with_fraction(const int64_t x,
const int64_t numerator,
const int64_t denominator)
{
- return static_cast<int64_t>((static_cast<uint64_t>(x) * static_cast<uint64_t>(numerator) /
- static_cast<uint64_t>(denominator)));
+ return int64_t((uint64_t(x) * uint64_t(numerator) / uint64_t(denominator)));
}
inline constexpr int64_t total_slot_amount_for_usable_slots(
@@ -121,7 +117,7 @@ class LoadFactor {
int64_t *r_total_slots,
int64_t *r_usable_slots) const
{
- BLI_assert(is_power_of_2_i(static_cast<int>(min_total_slots)));
+ BLI_assert(is_power_of_2_i(int(min_total_slots)));
int64_t total_slots = this->compute_total_slots(min_usable_slots, numerator_, denominator_);
total_slots = std::max(total_slots, min_total_slots);
@@ -229,17 +225,17 @@ template<typename Pointer> struct PointerKeyInfo {
static bool is_empty(Pointer pointer)
{
- return (uintptr_t)pointer == UINTPTR_MAX;
+ return uintptr_t(pointer) == UINTPTR_MAX;
}
static bool is_removed(Pointer pointer)
{
- return (uintptr_t)pointer == UINTPTR_MAX - 1;
+ return uintptr_t(pointer) == UINTPTR_MAX - 1;
}
static bool is_not_empty_or_removed(Pointer pointer)
{
- return (uintptr_t)pointer < UINTPTR_MAX - 1;
+ return uintptr_t(pointer) < UINTPTR_MAX - 1;
}
};
diff --git a/source/blender/blenlib/BLI_index_range.hh b/source/blender/blenlib/BLI_index_range.hh
index 6fcc560d856..c259282ca64 100644
--- a/source/blender/blenlib/BLI_index_range.hh
+++ b/source/blender/blenlib/BLI_index_range.hh
@@ -90,10 +90,10 @@ class IndexRange {
return *this;
}
- constexpr Iterator operator++(int) const
+ constexpr Iterator operator++(int)
{
Iterator copied_iterator = *this;
- ++copied_iterator;
+ ++(*this);
return copied_iterator;
}
@@ -140,6 +140,10 @@ class IndexRange {
{
return (a.size_ == b.size_) && (a.start_ == b.start_ || a.size_ == 0);
}
+ constexpr friend bool operator!=(IndexRange a, IndexRange b)
+ {
+ return !(a == b);
+ }
/**
* Get the amount of numbers in the range.
@@ -248,6 +252,19 @@ class IndexRange {
}
/**
+ * Returns a new IndexRange that contains the intersection of the current one with the given
+ * range. Returns empty range if there are no overlapping indices. The returned range is always
+ * a valid slice of this range.
+ */
+ constexpr IndexRange intersect(IndexRange other) const
+ {
+ const int64_t old_end = start_ + size_;
+ const int64_t new_start = std::min(old_end, std::max(start_, other.start_));
+ const int64_t new_end = std::max(new_start, std::min(old_end, other.start_ + other.size_));
+ return IndexRange(new_start, new_end - new_start);
+ }
+
+ /**
* Returns a new IndexRange with n elements removed from the beginning of the range.
* This invokes undefined behavior when n is negative.
*/
@@ -318,4 +335,19 @@ class IndexRange {
Span<int64_t> as_span_internal() const;
};
+struct AlignedIndexRanges {
+ IndexRange prefix;
+ IndexRange aligned;
+ IndexRange suffix;
+};
+
+/**
+ * Split a range into three parts so that the boundaries of the middle part are aligned to some
+ * power of two.
+ *
+ * This can be used when an algorithm can be optimized on aligned indices/memory. The algorithm
+ * then needs a slow path for the beginning and end, and a fast path for the aligned elements.
+ */
+AlignedIndexRanges split_index_range_by_alignment(const IndexRange range, const int64_t alignment);
+
} // namespace blender
diff --git a/source/blender/blenlib/BLI_lazy_threading.hh b/source/blender/blenlib/BLI_lazy_threading.hh
new file mode 100644
index 00000000000..b5a15919c89
--- /dev/null
+++ b/source/blender/blenlib/BLI_lazy_threading.hh
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+/** \file
+ * \ingroup bli
+ *
+ * The goal of "lazy threading" is to avoid using threads unless one can reasonably assume that it
+ * is worth distributing work over multiple threads. Using threads can lead to worse overall
+ * performance by introducing inter-thread communication overhead. Keeping all work on a single
+ * thread reduces this overhead to zero and also makes better use of the CPU cache.
+ *
+ * Functions like #parallel_for also solve this to some degree by using a "grain size". When the
+ * number of individual tasks is too small, no multi-threading is used. This works very well when
+ * there are many homogeneous tasks that can be expected to take approximately the same time.
+ *
+ * The situation becomes more difficult when:
+ * - The individual tasks are not homogeneous, i.e. they take different amounts of time to compute.
+ * - It is practically impossible to guess how long each task will take in advance.
+ *
+ * Given those constraints, a single grain size cannot be determined. One could just schedule all
+ * tasks individually but that would create a lot of overhead when the tasks happen to be very
+ * small. While TBB will keep all tasks on a single thread if the other threads are busy, if they
+ * are idle they will start stealing the work even if that's not beneficial for overall
+ * performance.
+ *
+ * This file provides a simple API that allows a task scheduler to properly handle tasks whose size
+ * is not known in advance. The key idea is this:
+ *
+ * > By default, all work stays on a single thread. If an individual task notices that it is about
+ * > start a computation that will take a while, it notifies the task scheduler further up on the
+ * > stack. The scheduler then allows other threads to take over other tasks that were originally
+ * > meant for the current thread.
+ *
+ * This way, when all tasks are small, no threading overhead has to be paid for. Whenever there is
+ * a task that keeps the current thread busy for a while, the other tasks are moved to a separate
+ * thread so that they can be executed without waiting for the long computation to finish.
+ *
+ * Consequently, the earlier a task knows during it execution that it will take a while, the
+ * better. That's because if it is blocking anyway, it's more efficient to move the other tasks to
+ * another thread earlier.
+ *
+ * To make this work, three things have to be solved:
+ * 1. The task scheduler has to be able to start single-threaded and become multi-threaded after
+ * tasks have started executing. This has to be solved in the specific task scheduler.
+ * 2. There has to be a way for the currently running task to tell the task scheduler that it is
+ * about to perform a computation that will take a while and that it would be reasonable to move
+ * other tasks to other threads. This part is implemented in the API provided by this file.
+ * 3. Individual tasks have to decide when a computation is long enough to justify talking to the
+ * scheduler. This is always based on heuristics that have to be fine tuned over time. One could
+ * assume that this means adding new work-size checks to many parts in Blender, but that's
+ * actually not necessary, because these checks exist already in the form of grain sizes passed
+ * to e.g. #parallel_for. The assumption here is that when the task thinks the current work load
+ * is big enough to justify using threads, it's also big enough to justify using another thread
+ * for waiting tasks on the current thread.
+ */
+
+#include "BLI_function_ref.hh"
+
+namespace blender::lazy_threading {
+
+/**
+ * Tell task schedulers on the current thread that it is about to start a long computation
+ * and that other waiting tasks should better be moved to another thread if possible.
+ */
+void send_hint();
+
+/**
+ * Used by the task scheduler to receive hints from current tasks that they will take a while.
+ * This should only be allocated on the stack.
+ */
+class HintReceiver {
+ public:
+ /**
+ * The passed in function is called when a task signals that it will take a while.
+ * \note The function has to stay alive after the call to the constructor. So one must not pass a
+ * lambda directly into this constructor but store it in a separate variable on the stack first.
+ */
+ HintReceiver(FunctionRef<void()> fn);
+ ~HintReceiver();
+};
+
+} // namespace blender::lazy_threading
diff --git a/source/blender/blenlib/BLI_linear_allocator.hh b/source/blender/blenlib/BLI_linear_allocator.hh
index deb6ea3b5fd..a897845db45 100644
--- a/source/blender/blenlib/BLI_linear_allocator.hh
+++ b/source/blender/blenlib/BLI_linear_allocator.hh
@@ -161,7 +161,7 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
void *pointer_buffer = this->allocate(element_amount * sizeof(void *), alignof(void *));
void *elements_buffer = this->allocate(element_amount * element_size, element_alignment);
- MutableSpan<void *> pointers((void **)pointer_buffer, element_amount);
+ MutableSpan<void *> pointers(static_cast<void **>(pointer_buffer), element_amount);
void *next_element_buffer = elements_buffer;
for (int64_t i : IndexRange(element_amount)) {
pointers[i] = next_element_buffer;
@@ -207,8 +207,8 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
Span<char> buffer = unused_borrowed_buffers_[i];
if (buffer.size() >= min_allocation_size) {
unused_borrowed_buffers_.remove_and_reorder(i);
- current_begin_ = (uintptr_t)buffer.begin();
- current_end_ = (uintptr_t)buffer.end();
+ current_begin_ = uintptr_t(buffer.begin());
+ current_end_ = uintptr_t(buffer.end());
return;
}
}
@@ -226,7 +226,7 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
void *buffer = allocator_.allocate(size_in_bytes, min_alignment, __func__);
owned_buffers_.append(buffer);
- current_begin_ = (uintptr_t)buffer;
+ current_begin_ = uintptr_t(buffer);
current_end_ = current_begin_ + size_in_bytes;
}
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index 237fcdae8b9..6a41fce27b3 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -301,32 +301,33 @@ struct LinkData *BLI_genericNodeN(void *data);
*
* \code{.c}
*
- * LISTBASE_CIRCULAR_FORWARD_BEGIN(listbase, item, item_init)
+ * LISTBASE_CIRCULAR_FORWARD_BEGIN(type, listbase, item, item_init)
* {
* ...operate on marker...
* }
- * LISTBASE_CIRCULAR_FORWARD_END (listbase, item, item_init);
+ * LISTBASE_CIRCULAR_FORWARD_END (type, listbase, item, item_init);
*
* \endcode
*/
-#define LISTBASE_CIRCULAR_FORWARD_BEGIN(lb, lb_iter, lb_init) \
- if ((lb)->first && (lb_init || (lb_init = (lb)->first))) { \
- lb_iter = lb_init; \
+#define LISTBASE_CIRCULAR_FORWARD_BEGIN(type, lb, lb_iter, lb_init) \
+ if ((lb)->first && (lb_init || (lb_init = (type)(lb)->first))) { \
+ lb_iter = (type)(lb_init); \
do {
-#define LISTBASE_CIRCULAR_FORWARD_END(lb, lb_iter, lb_init) \
+#define LISTBASE_CIRCULAR_FORWARD_END(type, lb, lb_iter, lb_init) \
} \
- while ((lb_iter = (lb_iter)->next ? (lb_iter)->next : (lb)->first), (lb_iter != lb_init)) \
+ while ((lb_iter = (lb_iter)->next ? (type)(lb_iter)->next : (type)(lb)->first), \
+ (lb_iter != lb_init)) \
; \
} \
((void)0)
-#define LISTBASE_CIRCULAR_BACKWARD_BEGIN(lb, lb_iter, lb_init) \
- if ((lb)->last && (lb_init || (lb_init = (lb)->last))) { \
+#define LISTBASE_CIRCULAR_BACKWARD_BEGIN(type, lb, lb_iter, lb_init) \
+ if ((lb)->last && (lb_init || (lb_init = (type)(lb)->last))) { \
lb_iter = lb_init; \
do {
-#define LISTBASE_CIRCULAR_BACKWARD_END(lb, lb_iter, lb_init) \
+#define LISTBASE_CIRCULAR_BACKWARD_END(type, lb, lb_iter, lb_init) \
} \
- while ((lb_iter = (lb_iter)->prev ? (lb_iter)->prev : (lb)->last), (lb_iter != lb_init)) \
+ while ((lb_iter = (lb_iter)->prev ? (lb_iter)->prev : (type)(lb)->last), (lb_iter != lb_init)) \
; \
} \
((void)0)
diff --git a/source/blender/blenlib/BLI_listbase_wrapper.hh b/source/blender/blenlib/BLI_listbase_wrapper.hh
index 25e029a5616..a32243bc411 100644
--- a/source/blender/blenlib/BLI_listbase_wrapper.hh
+++ b/source/blender/blenlib/BLI_listbase_wrapper.hh
@@ -42,7 +42,7 @@ template<typename T> class ListBaseWrapper {
Iterator &operator++()
{
- /* Some types store next/prev using `void *`, so cast is necessary. */
+ /* Some types store `next/prev` using `void *`, so cast is necessary. */
current_ = static_cast<T *>(current_->next);
return *this;
}
@@ -50,7 +50,7 @@ template<typename T> class ListBaseWrapper {
Iterator operator++(int)
{
Iterator iterator = *this;
- ++*this;
+ ++(*this);
return iterator;
}
diff --git a/source/blender/blenlib/BLI_map.hh b/source/blender/blenlib/BLI_map.hh
index 55233676ed8..6d281420c47 100644
--- a/source/blender/blenlib/BLI_map.hh
+++ b/source/blender/blenlib/BLI_map.hh
@@ -669,10 +669,10 @@ class Map {
return *this;
}
- BaseIterator operator++(int) const
+ BaseIterator operator++(int)
{
BaseIterator copied_iterator = *this;
- ++copied_iterator;
+ ++(*this);
return copied_iterator;
}
@@ -887,6 +887,25 @@ class Map {
}
/**
+ * Remove all key-value-pairs for that the given predicate is true.
+ *
+ * This is similar to std::erase_if.
+ */
+ template<typename Predicate> void remove_if(Predicate &&predicate)
+ {
+ for (Slot &slot : slots_) {
+ if (slot.is_occupied()) {
+ const Key &key = *slot.key();
+ Value &value = *slot.value();
+ if (predicate(MutableItem{key, value})) {
+ slot.remove();
+ removed_slots_++;
+ }
+ }
+ }
+ }
+
+ /**
* Print common statistics like size and collision count. This is useful for debugging purposes.
*/
void print_stats(StringRef name = "") const
@@ -943,7 +962,7 @@ class Map {
*/
int64_t size_in_bytes() const
{
- return static_cast<int64_t>(sizeof(Slot) * slots_.size());
+ return int64_t(sizeof(Slot) * slots_.size());
}
/**
@@ -987,7 +1006,7 @@ class Map {
max_load_factor_.compute_total_and_usable_slots(
SlotArray::inline_buffer_capacity(), min_usable_slots, &total_slots, &usable_slots);
BLI_assert(total_slots >= 1);
- const uint64_t new_slot_mask = static_cast<uint64_t>(total_slots) - 1;
+ const uint64_t new_slot_mask = uint64_t(total_slots) - 1;
/**
* Optimize the case when the map was empty beforehand. We can avoid some copies here.
@@ -1261,7 +1280,7 @@ template<typename Key, typename Value> class StdUnorderedMapWrapper {
public:
int64_t size() const
{
- return static_cast<int64_t>(map_.size());
+ return int64_t(map_.size());
}
bool is_empty() const
@@ -1295,7 +1314,7 @@ template<typename Key, typename Value> class StdUnorderedMapWrapper {
bool remove(const Key &key)
{
- return (bool)map_.erase(key);
+ return bool(map_.erase(key));
}
Value &lookup(const Key &key)
@@ -1313,7 +1332,7 @@ template<typename Key, typename Value> class StdUnorderedMapWrapper {
map_.clear();
}
- void print_stats(StringRef UNUSED(name) = "") const
+ void print_stats(StringRef /*name*/ = "") const
{
}
};
diff --git a/source/blender/blenlib/BLI_map_slots.hh b/source/blender/blenlib/BLI_map_slots.hh
index 6426216913f..eb2c1a7f5cf 100644
--- a/source/blender/blenlib/BLI_map_slots.hh
+++ b/source/blender/blenlib/BLI_map_slots.hh
@@ -169,7 +169,7 @@ template<typename Key, typename Value> class SimpleMapSlot {
* key. The hash can be used by other slot implementations to determine inequality faster.
*/
template<typename ForwardKey, typename IsEqual>
- bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t UNUSED(hash)) const
+ bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t /*hash*/) const
{
if (state_ == Occupied) {
return is_equal(key, *key_buffer_);
@@ -194,7 +194,7 @@ template<typename Key, typename Value> class SimpleMapSlot {
* Change the state of this slot from empty/removed to occupied. The value is assumed to be
* constructed already.
*/
- template<typename ForwardKey> void occupy_no_value(ForwardKey &&key, uint64_t UNUSED(hash))
+ template<typename ForwardKey> void occupy_no_value(ForwardKey &&key, uint64_t /*hash*/)
{
BLI_assert(!this->is_occupied());
try {
@@ -295,7 +295,7 @@ template<typename Key, typename Value, typename KeyInfo> class IntrusiveMapSlot
}
template<typename ForwardKey, typename IsEqual>
- bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t UNUSED(hash)) const
+ bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t /*hash*/) const
{
BLI_assert(KeyInfo::is_not_empty_or_removed(key));
return is_equal(key, key_);
@@ -310,7 +310,7 @@ template<typename Key, typename Value, typename KeyInfo> class IntrusiveMapSlot
this->occupy_no_value(std::forward<ForwardKey>(key), hash);
}
- template<typename ForwardKey> void occupy_no_value(ForwardKey &&key, uint64_t UNUSED(hash))
+ template<typename ForwardKey> void occupy_no_value(ForwardKey &&key, uint64_t /*hash*/)
{
BLI_assert(!this->is_occupied());
BLI_assert(KeyInfo::is_not_empty_or_removed(key));
diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h
index 6386a7f76f8..3aa2e35476d 100644
--- a/source/blender/blenlib/BLI_math_color.h
+++ b/source/blender/blenlib/BLI_math_color.h
@@ -164,7 +164,9 @@ void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4]);
MINLINE float rgb_to_grayscale(const float rgb[3]);
MINLINE unsigned char rgb_to_grayscale_byte(const unsigned char rgb[3]);
-MINLINE int compare_rgb_uchar(const unsigned char a[3], const unsigned char b[3], int limit);
+MINLINE int compare_rgb_uchar(const unsigned char col_a[3],
+ const unsigned char col_b[3],
+ int limit);
/**
* Return triangle noise in [-0.5..1.5] range.
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index 93b413ab755..d056c42e019 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -1270,8 +1270,8 @@ MINLINE void mul_sh_fl(float r[9], float f);
MINLINE void add_sh_shsh(float r[9], const float a[9], const float b[9]);
MINLINE float dot_shsh(const float a[9], const float b[9]);
-MINLINE float eval_shv3(float r[9], const float v[3]);
-MINLINE float diffuse_shv3(const float r[9], const float v[3]);
+MINLINE float eval_shv3(float sh[9], const float v[3]);
+MINLINE float diffuse_shv3(const float sh[9], const float v[3]);
MINLINE void vec_fac_to_sh(float r[9], const float v[3], float f);
MINLINE void madd_sh_shfl(float r[9], const float sh[9], float f);
diff --git a/source/blender/blenlib/BLI_math_inline.h b/source/blender/blenlib/BLI_math_inline.h
index bf91c9108a9..b190b022a88 100644
--- a/source/blender/blenlib/BLI_math_inline.h
+++ b/source/blender/blenlib/BLI_math_inline.h
@@ -28,8 +28,8 @@ extern "C" {
# define MALWAYS_INLINE
#endif
-/* gcc 4.6 (supports push/pop) */
-#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 406))
+/* Check for GCC push/pop pragma support. */
+#ifdef __GNUC__
# define BLI_MATH_GCC_WARN_PRAGMA 1
#endif
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h
index c2dafbe3a1a..7e1b7c2ba56 100644
--- a/source/blender/blenlib/BLI_math_matrix.h
+++ b/source/blender/blenlib/BLI_math_matrix.h
@@ -98,110 +98,110 @@ void mul_m4_m4_post(float R[4][4], const float B[4][4]);
/* Implement #mul_m3_series macro. */
-void _va_mul_m3_series_3(float R[3][3], const float M1[3][3], const float M2[3][3]) ATTR_NONNULL();
-void _va_mul_m3_series_4(float R[3][3],
- const float M1[3][3],
- const float M2[3][3],
- const float M3[3][3]) ATTR_NONNULL();
-void _va_mul_m3_series_5(float R[3][3],
- const float M1[3][3],
- const float M2[3][3],
- const float M3[3][3],
- const float M4[3][3]) ATTR_NONNULL();
-void _va_mul_m3_series_6(float R[3][3],
- const float M1[3][3],
- const float M2[3][3],
- const float M3[3][3],
- const float M4[3][3],
- const float M5[3][3]) ATTR_NONNULL();
-void _va_mul_m3_series_7(float R[3][3],
- const float M1[3][3],
- const float M2[3][3],
- const float M3[3][3],
- const float M4[3][3],
- const float M5[3][3],
- const float M6[3][3]) ATTR_NONNULL();
-void _va_mul_m3_series_8(float R[3][3],
- const float M1[3][3],
- const float M2[3][3],
- const float M3[3][3],
- const float M4[3][3],
- const float M5[3][3],
- const float M6[3][3],
- const float M7[3][3]) ATTR_NONNULL();
-void _va_mul_m3_series_9(float R[3][3],
- const float M1[3][3],
- const float M2[3][3],
- const float M3[3][3],
- const float M4[3][3],
- const float M5[3][3],
- const float M6[3][3],
- const float M7[3][3],
- const float M8[3][3]) ATTR_NONNULL();
+void _va_mul_m3_series_3(float r[3][3], const float m1[3][3], const float m2[3][3]) ATTR_NONNULL();
+void _va_mul_m3_series_4(float r[3][3],
+ const float m1[3][3],
+ const float m2[3][3],
+ const float m3[3][3]) ATTR_NONNULL();
+void _va_mul_m3_series_5(float r[3][3],
+ const float m1[3][3],
+ const float m2[3][3],
+ const float m3[3][3],
+ const float m4[3][3]) ATTR_NONNULL();
+void _va_mul_m3_series_6(float r[3][3],
+ const float m1[3][3],
+ const float m2[3][3],
+ const float m3[3][3],
+ const float m4[3][3],
+ const float m5[3][3]) ATTR_NONNULL();
+void _va_mul_m3_series_7(float r[3][3],
+ const float m1[3][3],
+ const float m2[3][3],
+ const float m3[3][3],
+ const float m4[3][3],
+ const float m5[3][3],
+ const float m6[3][3]) ATTR_NONNULL();
+void _va_mul_m3_series_8(float r[3][3],
+ const float m1[3][3],
+ const float m2[3][3],
+ const float m3[3][3],
+ const float m4[3][3],
+ const float m5[3][3],
+ const float m6[3][3],
+ const float m7[3][3]) ATTR_NONNULL();
+void _va_mul_m3_series_9(float r[3][3],
+ const float m1[3][3],
+ const float m2[3][3],
+ const float m3[3][3],
+ const float m4[3][3],
+ const float m5[3][3],
+ const float m6[3][3],
+ const float m7[3][3],
+ const float m8[3][3]) ATTR_NONNULL();
/* Implement #mul_m4_series macro. */
-void _va_mul_m4_series_3(float R[4][4], const float M1[4][4], const float M2[4][4]) ATTR_NONNULL();
-void _va_mul_m4_series_4(float R[4][4],
- const float M1[4][4],
- const float M2[4][4],
- const float M3[4][4]) ATTR_NONNULL();
-void _va_mul_m4_series_5(float R[4][4],
- const float M1[4][4],
- const float M2[4][4],
- const float M3[4][4],
- const float M4[4][4]) ATTR_NONNULL();
-void _va_mul_m4_series_6(float R[4][4],
- const float M1[4][4],
- const float M2[4][4],
- const float M3[4][4],
- const float M4[4][4],
- const float M5[4][4]) ATTR_NONNULL();
-void _va_mul_m4_series_7(float R[4][4],
- const float M1[4][4],
- const float M2[4][4],
- const float M3[4][4],
- const float M4[4][4],
- const float M5[4][4],
- const float M6[4][4]) ATTR_NONNULL();
-void _va_mul_m4_series_8(float R[4][4],
- const float M1[4][4],
- const float M2[4][4],
- const float M3[4][4],
- const float M4[4][4],
- const float M5[4][4],
- const float M6[4][4],
- const float M7[4][4]) ATTR_NONNULL();
-void _va_mul_m4_series_9(float R[4][4],
- const float M1[4][4],
- const float M2[4][4],
- const float M3[4][4],
- const float M4[4][4],
- const float M5[4][4],
- const float M6[4][4],
- const float M7[4][4],
- const float M8[4][4]) ATTR_NONNULL();
+void _va_mul_m4_series_3(float r[4][4], const float m1[4][4], const float m2[4][4]) ATTR_NONNULL();
+void _va_mul_m4_series_4(float r[4][4],
+ const float m1[4][4],
+ const float m2[4][4],
+ const float m3[4][4]) ATTR_NONNULL();
+void _va_mul_m4_series_5(float r[4][4],
+ const float m1[4][4],
+ const float m2[4][4],
+ const float m3[4][4],
+ const float m4[4][4]) ATTR_NONNULL();
+void _va_mul_m4_series_6(float r[4][4],
+ const float m1[4][4],
+ const float m2[4][4],
+ const float m3[4][4],
+ const float m4[4][4],
+ const float m5[4][4]) ATTR_NONNULL();
+void _va_mul_m4_series_7(float r[4][4],
+ const float m1[4][4],
+ const float m2[4][4],
+ const float m3[4][4],
+ const float m4[4][4],
+ const float m5[4][4],
+ const float m6[4][4]) ATTR_NONNULL();
+void _va_mul_m4_series_8(float r[4][4],
+ const float m1[4][4],
+ const float m2[4][4],
+ const float m3[4][4],
+ const float m4[4][4],
+ const float m5[4][4],
+ const float m6[4][4],
+ const float m7[4][4]) ATTR_NONNULL();
+void _va_mul_m4_series_9(float r[4][4],
+ const float m1[4][4],
+ const float m2[4][4],
+ const float m3[4][4],
+ const float m4[4][4],
+ const float m5[4][4],
+ const float m6[4][4],
+ const float m7[4][4],
+ const float m8[4][4]) ATTR_NONNULL();
#define mul_m3_series(...) VA_NARGS_CALL_OVERLOAD(_va_mul_m3_series_, __VA_ARGS__)
#define mul_m4_series(...) VA_NARGS_CALL_OVERLOAD(_va_mul_m4_series_, __VA_ARGS__)
void mul_m4_v3(const float M[4][4], float r[3]);
-void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3]);
+void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3]);
void mul_v3_m4v3_db(double r[3], const double mat[4][4], const double vec[3]);
void mul_v4_m4v3_db(double r[4], const double mat[4][4], const double vec[3]);
-void mul_v2_m4v3(float r[2], const float M[4][4], const float v[3]);
-void mul_v2_m2v2(float r[2], const float M[2][2], const float v[2]);
-void mul_m2_v2(const float M[2][2], float v[2]);
+void mul_v2_m4v3(float r[2], const float mat[4][4], const float vec[3]);
+void mul_v2_m2v2(float r[2], const float mat[2][2], const float vec[2]);
+void mul_m2_v2(const float mat[2][2], float vec[2]);
/** Same as #mul_m4_v3() but doesn't apply translation component. */
-void mul_mat3_m4_v3(const float M[4][4], float r[3]);
-void mul_v3_mat3_m4v3(float r[3], const float M[4][4], const float v[3]);
-void mul_v3_mat3_m4v3_db(double r[3], const double M[4][4], const double v[3]);
-void mul_m4_v4(const float M[4][4], float r[4]);
-void mul_v4_m4v4(float r[4], const float M[4][4], const float v[4]);
+void mul_mat3_m4_v3(const float mat[4][4], float r[3]);
+void mul_v3_mat3_m4v3(float r[3], const float mat[4][4], const float vec[3]);
+void mul_v3_mat3_m4v3_db(double r[3], const double mat[4][4], const double vec[3]);
+void mul_m4_v4(const float mat[4][4], float r[4]);
+void mul_v4_m4v4(float r[4], const float mat[4][4], const float v[4]);
void mul_v4_m4v3(float r[4], const float M[4][4], const float v[3]); /* v has implicit w = 1.0f */
-void mul_project_m4_v3(const float M[4][4], float vec[3]);
+void mul_project_m4_v3(const float mat[4][4], float vec[3]);
void mul_v3_project_m4_v3(float r[3], const float mat[4][4], const float vec[3]);
-void mul_v2_project_m4_v3(float r[2], const float M[4][4], const float vec[3]);
+void mul_v2_project_m4_v3(float r[2], const float mat[4][4], const float vec[3]);
void mul_m3_v2(const float m[3][3], float r[2]);
void mul_v2_m3v2(float r[2], const float m[3][3], const float v[2]);
@@ -234,14 +234,14 @@ void negate_m3(float R[3][3]);
void negate_mat3_m4(float R[4][4]);
void negate_m4(float R[4][4]);
-bool invert_m3_ex(float m[3][3], float epsilon);
-bool invert_m3_m3_ex(float m1[3][3], const float m2[3][3], float epsilon);
+bool invert_m3_ex(float mat[3][3], float epsilon);
+bool invert_m3_m3_ex(float inverse[3][3], const float mat[3][3], float epsilon);
-bool invert_m3(float R[3][3]);
-bool invert_m2_m2(float R[2][2], const float A[2][2]);
-bool invert_m3_m3(float R[3][3], const float A[3][3]);
-bool invert_m4(float R[4][4]);
-bool invert_m4_m4(float R[4][4], const float A[4][4]);
+bool invert_m3(float mat[3][3]);
+bool invert_m2_m2(float inverse[2][2], const float mat[2][2]);
+bool invert_m3_m3(float inverse[3][3], const float mat[3][3]);
+bool invert_m4(float mat[4][4]);
+bool invert_m4_m4(float inverse[4][4], const float mat[4][4]);
/**
* Computes the inverse of mat and puts it in inverse.
* Uses Gaussian Elimination with partial (maximal column) pivoting.
@@ -252,12 +252,12 @@ bool invert_m4_m4(float R[4][4], const float A[4][4]);
* for non-invertible scale matrices, finding a partial solution can
* be useful to have a valid local transform center, see T57767.
*/
-bool invert_m4_m4_fallback(float R[4][4], const float A[4][4]);
+bool invert_m4_m4_fallback(float inverse[4][4], const float mat[4][4]);
/* Double arithmetic (mixed float/double). */
-void mul_m4_v4d(const float M[4][4], double r[4]);
-void mul_v4d_m4v4d(double r[4], const float M[4][4], const double v[4]);
+void mul_m4_v4d(const float mat[4][4], double r[4]);
+void mul_v4d_m4v4d(double r[4], const float mat[4][4], const double v[4]);
/* Double matrix functions (no mixing types). */
@@ -291,8 +291,8 @@ void normalize_m3_m3_ex(float R[3][3], const float M[3][3], float r_scale[3]) AT
void normalize_m3_m3(float R[3][3], const float M[3][3]) ATTR_NONNULL();
void normalize_m4_ex(float R[4][4], float r_scale[3]) ATTR_NONNULL();
void normalize_m4(float R[4][4]) ATTR_NONNULL();
-void normalize_m4_m4_ex(float R[4][4], const float M[4][4], float r_scale[3]) ATTR_NONNULL();
-void normalize_m4_m4(float R[4][4], const float M[4][4]) ATTR_NONNULL();
+void normalize_m4_m4_ex(float rmat[4][4], const float mat[4][4], float r_scale[3]) ATTR_NONNULL();
+void normalize_m4_m4(float rmat[4][4], const float mat[4][4]) ATTR_NONNULL();
/**
* Make an orthonormal matrix around the selected axis of the given matrix.
@@ -326,15 +326,15 @@ void orthogonalize_m3_stable(float R[3][3], int axis, bool normalize);
*/
void orthogonalize_m4_stable(float R[4][4], int axis, bool normalize);
-bool orthogonalize_m3_zero_axes(float R[3][3], float unit_length);
-bool orthogonalize_m4_zero_axes(float R[4][4], float unit_length);
+bool orthogonalize_m3_zero_axes(float m[3][3], float unit_length);
+bool orthogonalize_m4_zero_axes(float m[4][4], float unit_length);
-bool is_orthogonal_m3(const float mat[3][3]);
-bool is_orthogonal_m4(const float mat[4][4]);
-bool is_orthonormal_m3(const float mat[3][3]);
-bool is_orthonormal_m4(const float mat[4][4]);
+bool is_orthogonal_m3(const float m[3][3]);
+bool is_orthogonal_m4(const float m[4][4]);
+bool is_orthonormal_m3(const float m[3][3]);
+bool is_orthonormal_m4(const float m[4][4]);
-bool is_uniform_scaled_m3(const float mat[3][3]);
+bool is_uniform_scaled_m3(const float m[3][3]);
bool is_uniform_scaled_m4(const float m[4][4]);
/* NOTE: 'adjoint' here means the adjugate (adjunct, "classical adjoint") matrix!
@@ -362,22 +362,24 @@ float determinant_m4(const float m[4][4]);
* From this decomposition it is trivial to compute the (pseudo-inverse)
* of `A` as `Ainv = V.Winv.transpose(U)`.
*/
-void svd_m4(float U[4][4], float s[4], float V[4][4], float A[4][4]);
-void pseudoinverse_m4_m4(float Ainv[4][4], const float A[4][4], float epsilon);
-void pseudoinverse_m3_m3(float Ainv[3][3], const float A[3][3], float epsilon);
+void svd_m4(float U[4][4], float s[4], float V[4][4], float A_[4][4]);
+void pseudoinverse_m4_m4(float inverse[4][4], const float mat[4][4], float epsilon);
+void pseudoinverse_m3_m3(float inverse[3][3], const float mat[3][3], float epsilon);
bool has_zero_axis_m4(const float matrix[4][4]);
+/** Fix any zero scale axis adding a small bias orthogonal to the other valid axis. */
+void zero_axis_bias_m4(float mat[4][4]);
-void invert_m4_m4_safe(float Ainv[4][4], const float A[4][4]);
+void invert_m4_m4_safe(float inverse[4][4], const float mat[4][4]);
-void invert_m3_m3_safe_ortho(float Ainv[3][3], const float A[3][3]);
+void invert_m3_m3_safe_ortho(float inverse[3][3], const float mat[3][3]);
/**
* A safe version of invert that uses valid axes, calculating the zero'd axis
* based on the non-zero ones.
*
* This works well for transformation matrices, when a single axis is zeroed.
*/
-void invert_m4_m4_safe_ortho(float Ainv[4][4], const float A[4][4]);
+void invert_m4_m4_safe_ortho(float inverse[4][4], const float mat[4][4]);
/** \} */
@@ -394,22 +396,24 @@ void scale_m4_v2(float R[4][4], const float scale[2]);
* For an orthogonal matrix, it is the product of all three scale values.
* Returns a negative value if the transform is flipped by negative scale.
*/
-float mat3_to_volume_scale(const float M[3][3]);
-float mat4_to_volume_scale(const float M[4][4]);
+float mat3_to_volume_scale(const float mat[3][3]);
+float mat4_to_volume_scale(const float mat[4][4]);
/**
* This gets the average scale of a matrix, only use when your scaling
* data that has no idea of scale axis, examples are bone-envelope-radius
* and curve radius.
*/
-float mat3_to_scale(const float M[3][3]);
-float mat4_to_scale(const float M[4][4]);
+float mat3_to_scale(const float mat[3][3]);
+float mat4_to_scale(const float mat[4][4]);
/** Return 2D scale (in XY plane) of given mat4. */
-float mat4_to_xy_scale(const float M[4][4]);
+float mat4_to_xy_scale(const float mat[4][4]);
void size_to_mat3(float R[3][3], const float size[3]);
void size_to_mat4(float R[4][4], const float size[3]);
+/** Return 2D size assuming the given matrix is a 2D affine matrix. */
+void mat3_to_size_2d(float size[2], const float M[3][3]);
void mat3_to_size(float size[3], const float M[3][3]);
void mat4_to_size(float size[3], const float M[4][4]);
@@ -433,7 +437,7 @@ float mat4_to_size_max_axis(const float M[4][4]);
*/
void mat4_to_size_fix_shear(float size[3], const float M[4][4]);
-void translate_m4(float mat[4][4], float tx, float ty, float tz);
+void translate_m4(float mat[4][4], float Tx, float Ty, float Tz);
/**
* Rotate a matrix in-place.
*
@@ -454,8 +458,20 @@ void rescale_m4(float mat[4][4], const float scale[3]);
*/
void transform_pivot_set_m4(float mat[4][4], const float pivot[3]);
+/**
+ * \param rot: A 3x3 rotation matrix, normalized never negative.
+ */
void mat4_to_rot(float rot[3][3], const float wmat[4][4]);
+
+/**
+ * \param rot: A 3x3 rotation matrix, normalized never negative.
+ * \param size: The scale, negative if `mat3` is negative.
+ */
void mat3_to_rot_size(float rot[3][3], float size[3], const float mat3[3][3]);
+/**
+ * \param rot: A 3x3 rotation matrix, normalized never negative.
+ * \param size: The scale, negative if `mat3` is negative.
+ */
void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], const float wmat[4][4]);
void mat4_to_loc_quat(float loc[3], float quat[4], const float wmat[4][4]);
void mat4_decompose(float loc[3], float quat[4], float size[3], const float wmat[4][4]);
@@ -528,7 +544,18 @@ void interp_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3], flo
*/
void interp_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4], float t);
+/**
+ * Return true when the matrices determinant is less than zero.
+ *
+ * \note This is often used to check if a matrix flips content in 3D space,
+ * where transforming geometry (for example) would flip the direction of polygon normals
+ * from pointing outside a closed volume, to pointing inside (or the reverse).
+ *
+ * When the matrix is constructed from location, rotation & scale
+ * as matrix will be negative when it has an odd number of negative scales.
+ */
bool is_negative_m3(const float mat[3][3]);
+/** A version of #is_negative_m3 that takes a 4x4 matrix. */
bool is_negative_m4(const float mat[4][4]);
bool is_zero_m3(const float mat[3][3]);
@@ -605,8 +632,8 @@ void BLI_space_transform_invert_normal(const struct SpaceTransform *data, float
/** \name Other
* \{ */
-void print_m3(const char *str, const float M[3][3]);
-void print_m4(const char *str, const float M[4][4]);
+void print_m3(const char *str, const float m[3][3]);
+void print_m4(const char *str, const float m[4][4]);
#define print_m3_id(M) print_m3(STRINGIFY(M), M)
#define print_m4_id(M) print_m4(STRINGIFY(M), M)
diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h
index fef51fa780e..7fb7085360b 100644
--- a/source/blender/blenlib/BLI_math_rotation.h
+++ b/source/blender/blenlib/BLI_math_rotation.h
@@ -71,7 +71,7 @@ void mul_qt_fl(float q[4], float f);
/**
* Raise a unit quaternion to the specified power.
*/
-void pow_qt_fl_normalized(float q[4], float f);
+void pow_qt_fl_normalized(float q[4], float fac);
void sub_qt_qtqt(float q[4], const float a[4], const float b[4]);
@@ -109,8 +109,8 @@ void add_qt_qtqt(float q[4], const float a[4], const float b[4], float t);
/* Conversion. */
-void quat_to_mat3(float mat[3][3], const float q[4]);
-void quat_to_mat4(float mat[4][4], const float q[4]);
+void quat_to_mat3(float m[3][3], const float q[4]);
+void quat_to_mat4(float m[4][4], const float q[4]);
/**
* Apply the rotation of \a a to \a q keeping the values compatible with \a old.
@@ -118,6 +118,11 @@ void quat_to_mat4(float mat[4][4], const float q[4]);
*/
void quat_to_compatible_quat(float q[4], const float a[4], const float old[4]);
+/**
+ * A version of #mat3_normalized_to_quat that skips error checking.
+ */
+void mat3_normalized_to_quat_fast(float q[4], const float mat[3][3]);
+
void mat3_normalized_to_quat(float q[4], const float mat[3][3]);
void mat4_normalized_to_quat(float q[4], const float mat[4][4]);
void mat3_to_quat(float q[4], const float mat[3][3]);
@@ -157,7 +162,10 @@ void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q
* \param r_twist: if not NULL, receives the twist quaternion.
* \returns twist angle.
*/
-float quat_split_swing_and_twist(const float q[4], int axis, float r_swing[4], float r_twist[4]);
+float quat_split_swing_and_twist(const float q_in[4],
+ int axis,
+ float r_swing[4],
+ float r_twist[4]);
float angle_normalized_qt(const float q[4]);
float angle_normalized_qtqt(const float q1[4], const float q2[4]);
@@ -170,17 +178,17 @@ float angle_signed_qt(const float q[4]);
float angle_signed_qtqt(const float q1[4], const float q2[4]);
/**
- * TODO: don't what this is, but it's not the same as #mat3_to_quat.
+ * Legacy matrix to quaternion conversion, keep to prevent changes to existing
+ * boids & particle-system behavior. Use #mat3_to_quat for new code.
*/
-void mat3_to_quat_is_ok(float q[4], const float mat[3][3]);
+void mat3_to_quat_legacy(float q[4], const float wmat[3][3]);
/* Other. */
/**
- * Utility function that performs `sinf` & `cosf` where the quadrants of the circle
- * will have exactly matching values when their sign is flipped.
- * This works as long as the denominator can be divided by 2 or 4,
- * otherwise `sinf` & `cosf` are used without any additional logic.
+ * Utility that performs `sinf` & `cosf` intended for plotting a 2D circle,
+ * where the values of the coordinates with are exactly symmetrical although this
+ * favors even numbers as odd numbers can only be symmetrical on a single axis.
*
* Besides adjustments to precision, this function is the equivalent of:
* \code {.c}
@@ -190,11 +198,11 @@ void mat3_to_quat_is_ok(float q[4], const float mat[3][3]);
* \endcode
*
* \param numerator: An integer factor in [0..denominator] (inclusive).
- * \param denominator: The faction denominator (typically the number of segments of the circle).
+ * \param denominator: The fraction denominator (typically the number of segments of the circle).
* \param r_sin: The resulting sine.
* \param r_cos: The resulting cosine.
*/
-void sin_cos_from_fraction(const int numerator, const int denominator, float *r_sin, float *r_cos);
+void sin_cos_from_fraction(int numerator, int denominator, float *r_sin, float *r_cos);
void print_qt(const char *str, const float q[4]);
@@ -236,16 +244,16 @@ void axis_angle_to_mat4(float R[4][4], const float axis[3], float angle);
/**
* 3x3 matrix to axis angle.
*/
-void mat3_normalized_to_axis_angle(float axis[3], float *angle, const float M[3][3]);
+void mat3_normalized_to_axis_angle(float axis[3], float *angle, const float mat[3][3]);
/**
* 4x4 matrix to axis angle.
*/
-void mat4_normalized_to_axis_angle(float axis[3], float *angle, const float M[4][4]);
-void mat3_to_axis_angle(float axis[3], float *angle, const float M[3][3]);
+void mat4_normalized_to_axis_angle(float axis[3], float *angle, const float mat[4][4]);
+void mat3_to_axis_angle(float axis[3], float *angle, const float mat[3][3]);
/**
* 4x4 matrix to axis angle.
*/
-void mat4_to_axis_angle(float axis[3], float *angle, const float M[4][4]);
+void mat4_to_axis_angle(float axis[3], float *angle, const float mat[4][4]);
/**
* Quaternions to Axis Angle.
*/
@@ -284,19 +292,19 @@ void eul_to_mat3(float mat[3][3], const float eul[3]);
void eul_to_mat4(float mat[4][4], const float eul[3]);
void mat3_normalized_to_eul(float eul[3], const float mat[3][3]);
-void mat4_normalized_to_eul(float eul[3], const float mat[4][4]);
+void mat4_normalized_to_eul(float eul[3], const float m[4][4]);
void mat3_to_eul(float eul[3], const float mat[3][3]);
void mat4_to_eul(float eul[3], const float mat[4][4]);
void quat_to_eul(float eul[3], const float quat[4]);
-void mat3_normalized_to_compatible_eul(float eul[3], const float old[3], float mat[3][3]);
-void mat3_to_compatible_eul(float eul[3], const float old[3], float mat[3][3]);
+void mat3_normalized_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3]);
+void mat3_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3]);
void quat_to_compatible_eul(float eul[3], const float oldrot[3], const float quat[4]);
-void rotate_eul(float eul[3], char axis, float angle);
+void rotate_eul(float beul[3], char axis, float angle);
/* Order independent. */
-void compatible_eul(float eul[3], const float old[3]);
+void compatible_eul(float eul[3], const float oldrot[3]);
void add_eul_euleul(float r_eul[3], float a[3], float b[3], short order);
void sub_eul_euleul(float r_eul[3], float a[3], float b[3], short order);
@@ -324,15 +332,15 @@ typedef enum eEulerRotationOrders {
/**
* Construct quaternion from Euler angles (in radians).
*/
-void eulO_to_quat(float quat[4], const float eul[3], short order);
+void eulO_to_quat(float q[4], const float e[3], short order);
/**
* Construct 3x3 matrix from Euler angles (in radians).
*/
-void eulO_to_mat3(float mat[3][3], const float eul[3], short order);
+void eulO_to_mat3(float M[3][3], const float e[3], short order);
/**
* Construct 4x4 matrix from Euler angles (in radians).
*/
-void eulO_to_mat4(float mat[4][4], const float eul[3], short order);
+void eulO_to_mat4(float mat[4][4], const float e[3], short order);
/**
* Euler Rotation to Axis Angle.
*/
@@ -345,17 +353,17 @@ void eulO_to_gimbal_axis(float gmat[3][3], const float eul[3], short order);
/**
* Convert 3x3 matrix to Euler angles (in radians).
*/
-void mat3_normalized_to_eulO(float eul[3], short order, const float mat[3][3]);
+void mat3_normalized_to_eulO(float eul[3], short order, const float m[3][3]);
/**
* Convert 4x4 matrix to Euler angles (in radians).
*/
-void mat4_normalized_to_eulO(float eul[3], short order, const float mat[4][4]);
-void mat3_to_eulO(float eul[3], short order, const float mat[3][3]);
-void mat4_to_eulO(float eul[3], short order, const float mat[4][4]);
+void mat4_normalized_to_eulO(float eul[3], short order, const float m[4][4]);
+void mat3_to_eulO(float eul[3], short order, const float m[3][3]);
+void mat4_to_eulO(float eul[3], short order, const float m[4][4]);
/**
* Convert quaternion to Euler angles (in radians).
*/
-void quat_to_eulO(float eul[3], short order, const float quat[4]);
+void quat_to_eulO(float e[3], short order, const float q[4]);
/**
* Axis Angle to Euler Rotation.
*/
@@ -364,18 +372,27 @@ void axis_angle_to_eulO(float eul[3], short order, const float axis[3], float an
/* Uses 2 methods to retrieve eulers, and picks the closest. */
void mat3_normalized_to_compatible_eulO(float eul[3],
- const float old[3],
+ const float oldrot[3],
short order,
const float mat[3][3]);
void mat4_normalized_to_compatible_eulO(float eul[3],
- const float old[3],
+ const float oldrot[3],
short order,
const float mat[4][4]);
-void mat3_to_compatible_eulO(float eul[3], const float old[3], short order, const float mat[3][3]);
-void mat4_to_compatible_eulO(float eul[3], const float old[3], short order, const float mat[4][4]);
-void quat_to_compatible_eulO(float eul[3], const float old[3], short order, const float quat[4]);
-
-void rotate_eulO(float eul[3], short order, char axis, float angle);
+void mat3_to_compatible_eulO(float eul[3],
+ const float oldrot[3],
+ short order,
+ const float mat[3][3]);
+void mat4_to_compatible_eulO(float eul[3],
+ const float oldrot[3],
+ short order,
+ const float mat[4][4]);
+void quat_to_compatible_eulO(float eul[3],
+ const float oldrot[3],
+ short order,
+ const float quat[4]);
+
+void rotate_eulO(float beul[3], short order, char axis, float angle);
/** \} */
@@ -384,7 +401,7 @@ void rotate_eulO(float eul[3], short order, char axis, float angle);
* \{ */
void copy_dq_dq(DualQuat *r, const DualQuat *dq);
-void normalize_dq(DualQuat *dq, float totw);
+void normalize_dq(DualQuat *dq, float totweight);
void add_weighted_dq_dq(DualQuat *dq_sum, const DualQuat *dq, float weight);
void mul_v3m3_dq(float r[3], float R[3][3], DualQuat *dq);
@@ -401,7 +418,7 @@ void vec_apply_track(float vec[3], short axis);
* Lens/angle conversion (radians).
*/
float focallength_to_fov(float focal_length, float sensor);
-float fov_to_focallength(float fov, float sensor);
+float fov_to_focallength(float hfov, float sensor);
float angle_wrap_rad(float angle);
float angle_wrap_deg(float angle);
diff --git a/source/blender/blenlib/BLI_math_vec_types.hh b/source/blender/blenlib/BLI_math_vec_types.hh
index 7f20881dfa3..0387d0b0440 100644
--- a/source/blender/blenlib/BLI_math_vec_types.hh
+++ b/source/blender/blenlib/BLI_math_vec_types.hh
@@ -40,6 +40,21 @@ template<typename T> struct vec_struct_base<T, 4> {
T x, y, z, w;
};
+template<class Fn, size_t... I> void unroll_impl(Fn fn, std::index_sequence<I...> /*indices*/)
+{
+ (fn(I), ...);
+}
+
+/**
+ * Variadic templates are used to unroll loops manually. This helps GCC avoid branching during math
+ * operations and makes the code generation more explicit and predictable. Unrolling should always
+ * be worth it because the vector size is expected to be small.
+ */
+template<int N, class Fn> void unroll(Fn fn)
+{
+ unroll_impl(fn, std::make_index_sequence<N>());
+}
+
namespace math {
template<typename T> uint64_t vector_hash(const T &vec)
@@ -74,28 +89,28 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
explicit vec_base(uint value)
{
for (int i = 0; i < Size; i++) {
- (*this)[i] = static_cast<T>(value);
+ (*this)[i] = T(value);
}
}
explicit vec_base(int value)
{
for (int i = 0; i < Size; i++) {
- (*this)[i] = static_cast<T>(value);
+ (*this)[i] = T(value);
}
}
explicit vec_base(float value)
{
for (int i = 0; i < Size; i++) {
- (*this)[i] = static_cast<T>(value);
+ (*this)[i] = T(value);
}
}
explicit vec_base(double value)
{
for (int i = 0; i < Size; i++) {
- (*this)[i] = static_cast<T>(value);
+ (*this)[i] = T(value);
}
}
@@ -126,53 +141,42 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
/** Mixed scalar-vector constructors. */
template<typename U, BLI_ENABLE_IF_VEC(Size, == 3)>
- constexpr vec_base(const vec_base<U, 2> &xy, T z)
- : vec_base(static_cast<T>(xy.x), static_cast<T>(xy.y), z)
+ constexpr vec_base(const vec_base<U, 2> &xy, T z) : vec_base(T(xy.x), T(xy.y), z)
{
}
template<typename U, BLI_ENABLE_IF_VEC(Size, == 3)>
- constexpr vec_base(T x, const vec_base<U, 2> &yz)
- : vec_base(x, static_cast<T>(yz.x), static_cast<T>(yz.y))
+ constexpr vec_base(T x, const vec_base<U, 2> &yz) : vec_base(x, T(yz.x), T(yz.y))
{
}
template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)>
- vec_base(vec_base<U, 3> xyz, T w)
- : vec_base(
- static_cast<T>(xyz.x), static_cast<T>(xyz.y), static_cast<T>(xyz.z), static_cast<T>(w))
+ vec_base(vec_base<U, 3> xyz, T w) : vec_base(T(xyz.x), T(xyz.y), T(xyz.z), T(w))
{
}
template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)>
- vec_base(T x, vec_base<U, 3> yzw)
- : vec_base(
- static_cast<T>(x), static_cast<T>(yzw.x), static_cast<T>(yzw.y), static_cast<T>(yzw.z))
+ vec_base(T x, vec_base<U, 3> yzw) : vec_base(T(x), T(yzw.x), T(yzw.y), T(yzw.z))
{
}
template<typename U, typename V, BLI_ENABLE_IF_VEC(Size, == 4)>
- vec_base(vec_base<U, 2> xy, vec_base<V, 2> zw)
- : vec_base(
- static_cast<T>(xy.x), static_cast<T>(xy.y), static_cast<T>(zw.x), static_cast<T>(zw.y))
+ vec_base(vec_base<U, 2> xy, vec_base<V, 2> zw) : vec_base(T(xy.x), T(xy.y), T(zw.x), T(zw.y))
{
}
template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)>
- vec_base(vec_base<U, 2> xy, T z, T w)
- : vec_base(static_cast<T>(xy.x), static_cast<T>(xy.y), static_cast<T>(z), static_cast<T>(w))
+ vec_base(vec_base<U, 2> xy, T z, T w) : vec_base(T(xy.x), T(xy.y), T(z), T(w))
{
}
template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)>
- vec_base(T x, vec_base<U, 2> yz, T w)
- : vec_base(static_cast<T>(x), static_cast<T>(yz.x), static_cast<T>(yz.y), static_cast<T>(w))
+ vec_base(T x, vec_base<U, 2> yz, T w) : vec_base(T(x), T(yz.x), T(yz.y), T(w))
{
}
template<typename U, BLI_ENABLE_IF_VEC(Size, == 4)>
- vec_base(T x, T y, vec_base<U, 2> zw)
- : vec_base(static_cast<T>(x), static_cast<T>(y), static_cast<T>(zw.x), static_cast<T>(zw.y))
+ vec_base(T x, T y, vec_base<U, 2> zw) : vec_base(T(x), T(y), T(zw.x), T(zw.y))
{
}
@@ -182,7 +186,7 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
explicit vec_base(const vec_base<U, OtherSize> &other)
{
for (int i = 0; i < Size; i++) {
- (*this)[i] = static_cast<T>(other[i]);
+ (*this)[i] = T(other[i]);
}
}
@@ -192,17 +196,13 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
vec_base(const T *ptr)
{
- for (int i = 0; i < Size; i++) {
- (*this)[i] = ptr[i];
- }
+ unroll<Size>([&](auto i) { (*this)[i] = ptr[i]; });
}
template<typename U, BLI_ENABLE_IF((std::is_convertible_v<U, T>))>
explicit vec_base(const U *ptr)
{
- for (int i = 0; i < Size; i++) {
- (*this)[i] = ptr[i];
- }
+ unroll<Size>([&](auto i) { (*this)[i] = ptr[i]; });
}
vec_base(const T (*ptr)[Size]) : vec_base(static_cast<const T *>(ptr[0]))
@@ -213,9 +213,7 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
template<typename U> explicit vec_base(const vec_base<U, Size> &vec)
{
- for (int i = 0; i < Size; i++) {
- (*this)[i] = static_cast<T>(vec[i]);
- }
+ unroll<Size>([&](auto i) { (*this)[i] = T(vec[i]); });
}
/** C-style pointer dereference. */
@@ -250,29 +248,20 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
#define BLI_INT_OP(_T) template<typename U = _T, BLI_ENABLE_IF((std::is_integral_v<U>))>
-#define BLI_VEC_OP_IMPL(_result, _i, _op) \
- vec_base _result; \
- for (int _i = 0; _i < Size; _i++) { \
- _op; \
- } \
- return _result;
-
-#define BLI_VEC_OP_IMPL_SELF(_i, _op) \
- for (int _i = 0; _i < Size; _i++) { \
- _op; \
- } \
- return *this;
-
/** Arithmetic operators. */
friend vec_base operator+(const vec_base &a, const vec_base &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] + b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] + b[i]; });
+ return result;
}
friend vec_base operator+(const vec_base &a, const T &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] + b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] + b; });
+ return result;
}
friend vec_base operator+(const T &a, const vec_base &b)
@@ -282,52 +271,69 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
vec_base &operator+=(const vec_base &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] += b[i]);
+ unroll<Size>([&](auto i) { (*this)[i] += b[i]; });
+ return *this;
}
vec_base &operator+=(const T &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] += b);
+ vec_base result;
+ unroll<Size>([&](auto i) { (*this)[i] += b; });
+ return result;
}
friend vec_base operator-(const vec_base &a)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = -a[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = -a[i]; });
+ return result;
}
friend vec_base operator-(const vec_base &a, const vec_base &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] - b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] - b[i]; });
+ return result;
}
friend vec_base operator-(const vec_base &a, const T &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] - b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] - b; });
+ return result;
}
friend vec_base operator-(const T &a, const vec_base &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a - b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a - b[i]; });
+ return result;
}
vec_base &operator-=(const vec_base &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] -= b[i]);
+ unroll<Size>([&](auto i) { (*this)[i] -= b[i]; });
+ return *this;
}
vec_base &operator-=(const T &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] -= b);
+ unroll<Size>([&](auto i) { (*this)[i] -= b; });
+ return *this;
}
friend vec_base operator*(const vec_base &a, const vec_base &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] * b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] * b[i]; });
+ return result;
}
template<typename FactorT> friend vec_base operator*(const vec_base &a, FactorT b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] * b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] * b; });
+ return result;
}
friend vec_base operator*(T a, const vec_base &b)
@@ -337,12 +343,14 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
vec_base &operator*=(T b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] *= b);
+ unroll<Size>([&](auto i) { (*this)[i] *= b; });
+ return *this;
}
vec_base &operator*=(const vec_base &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] *= b[i]);
+ unroll<Size>([&](auto i) { (*this)[i] *= b[i]; });
+ return *this;
}
friend vec_base operator/(const vec_base &a, const vec_base &b)
@@ -350,13 +358,17 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
for (int i = 0; i < Size; i++) {
BLI_assert(b[i] != T(0));
}
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] / b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] / b[i]; });
+ return result;
}
friend vec_base operator/(const vec_base &a, T b)
{
BLI_assert(b != T(0));
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] / b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] / b; });
+ return result;
}
friend vec_base operator/(T a, const vec_base &b)
@@ -364,31 +376,39 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
for (int i = 0; i < Size; i++) {
BLI_assert(b[i] != T(0));
}
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a / b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a / b[i]; });
+ return result;
}
vec_base &operator/=(T b)
{
BLI_assert(b != T(0));
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] /= b);
+ unroll<Size>([&](auto i) { (*this)[i] /= b; });
+ return *this;
}
vec_base &operator/=(const vec_base &b)
{
BLI_assert(b != T(0));
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] /= b[i]);
+ unroll<Size>([&](auto i) { (*this)[i] /= b[i]; });
+ return *this;
}
/** Binary operators. */
BLI_INT_OP(T) friend vec_base operator&(const vec_base &a, const vec_base &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] & b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] & b[i]; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator&(const vec_base &a, T b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] & b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] & b; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator&(T a, const vec_base &b)
@@ -398,22 +418,28 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
BLI_INT_OP(T) vec_base &operator&=(T b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] &= b);
+ unroll<Size>([&](auto i) { (*this)[i] &= b; });
+ return *this;
}
BLI_INT_OP(T) vec_base &operator&=(const vec_base &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] &= b[i]);
+ unroll<Size>([&](auto i) { (*this)[i] &= b[i]; });
+ return *this;
}
BLI_INT_OP(T) friend vec_base operator|(const vec_base &a, const vec_base &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] | b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] | b[i]; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator|(const vec_base &a, T b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] | b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] | b; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator|(T a, const vec_base &b)
@@ -423,22 +449,28 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
BLI_INT_OP(T) vec_base &operator|=(T b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] |= b);
+ unroll<Size>([&](auto i) { (*this)[i] |= b; });
+ return *this;
}
BLI_INT_OP(T) vec_base &operator|=(const vec_base &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] |= b[i]);
+ unroll<Size>([&](auto i) { (*this)[i] |= b[i]; });
+ return *this;
}
BLI_INT_OP(T) friend vec_base operator^(const vec_base &a, const vec_base &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] ^ b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] ^ b[i]; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator^(const vec_base &a, T b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] ^ b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] ^ b; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator^(T a, const vec_base &b)
@@ -448,59 +480,75 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
BLI_INT_OP(T) vec_base &operator^=(T b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] ^= b);
+ unroll<Size>([&](auto i) { (*this)[i] ^= b; });
+ return *this;
}
BLI_INT_OP(T) vec_base &operator^=(const vec_base &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] ^= b[i]);
+ unroll<Size>([&](auto i) { (*this)[i] ^= b[i]; });
+ return *this;
}
BLI_INT_OP(T) friend vec_base operator~(const vec_base &a)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = ~a[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = ~a[i]; });
+ return result;
}
/** Bit-shift operators. */
BLI_INT_OP(T) friend vec_base operator<<(const vec_base &a, const vec_base &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] << b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] << b[i]; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator<<(const vec_base &a, T b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] << b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] << b; });
+ return result;
}
BLI_INT_OP(T) vec_base &operator<<=(T b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] <<= b);
+ unroll<Size>([&](auto i) { (*this)[i] <<= b; });
+ return *this;
}
BLI_INT_OP(T) vec_base &operator<<=(const vec_base &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] <<= b[i]);
+ unroll<Size>([&](auto i) { (*this)[i] <<= b[i]; });
+ return *this;
}
BLI_INT_OP(T) friend vec_base operator>>(const vec_base &a, const vec_base &b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] >> b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] >> b[i]; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator>>(const vec_base &a, T b)
{
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] >> b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] >> b; });
+ return result;
}
BLI_INT_OP(T) vec_base &operator>>=(T b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] >>= b);
+ unroll<Size>([&](auto i) { (*this)[i] >>= b; });
+ return *this;
}
BLI_INT_OP(T) vec_base &operator>>=(const vec_base &b)
{
- BLI_VEC_OP_IMPL_SELF(i, (*this)[i] >>= b[i]);
+ unroll<Size>([&](auto i) { (*this)[i] >>= b[i]; });
+ return *this;
}
/** Modulo operators. */
@@ -510,24 +558,28 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
for (int i = 0; i < Size; i++) {
BLI_assert(b[i] != T(0));
}
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] % b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] % b[i]; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator%(const vec_base &a, T b)
{
BLI_assert(b != 0);
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] % b);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a[i] % b; });
+ return result;
}
BLI_INT_OP(T) friend vec_base operator%(T a, const vec_base &b)
{
BLI_assert(b != T(0));
- BLI_VEC_OP_IMPL(ret, i, ret[i] = a % b[i]);
+ vec_base result;
+ unroll<Size>([&](auto i) { result[i] = a % b[i]; });
+ return result;
}
#undef BLI_INT_OP
-#undef BLI_VEC_OP_IMPL
-#undef BLI_VEC_OP_IMPL_SELF
/** Compare. */
@@ -567,6 +619,11 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
}
};
+using char3 = blender::vec_base<int8_t, 3>;
+
+using uchar3 = blender::vec_base<uint8_t, 3>;
+using uchar4 = blender::vec_base<uint8_t, 4>;
+
using int2 = vec_base<int32_t, 2>;
using int3 = vec_base<int32_t, 3>;
using int4 = vec_base<int32_t, 4>;
@@ -575,7 +632,11 @@ using uint2 = vec_base<uint32_t, 2>;
using uint3 = vec_base<uint32_t, 3>;
using uint4 = vec_base<uint32_t, 4>;
+using short3 = blender::vec_base<int16_t, 3>;
+
using ushort2 = vec_base<uint16_t, 2>;
+using ushort3 = blender::vec_base<uint16_t, 3>;
+using ushort4 = blender::vec_base<uint16_t, 4>;
using float2 = vec_base<float, 2>;
using float3 = vec_base<float, 3>;
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 0b178064a4c..17fe25ec67b 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -155,7 +155,7 @@ MINLINE void mul_v3_v3db_db(double r[3], const double a[3], double f);
MINLINE void mul_v2_v2(float r[2], const float a[2]);
MINLINE void mul_v2_v2v2(float r[2], const float a[2], const float b[2]);
MINLINE void mul_v3_v3(float r[3], const float a[3]);
-MINLINE void mul_v3_v3v3(float r[3], const float a[3], const float b[3]);
+MINLINE void mul_v3_v3v3(float r[3], const float v1[3], const float v2[3]);
MINLINE void mul_v4_fl(float r[4], float f);
MINLINE void mul_v4_v4(float r[4], const float a[4]);
MINLINE void mul_v4_v4fl(float r[4], const float a[4], float f);
@@ -271,10 +271,10 @@ MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT;
MINLINE float len_manhattan_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT;
MINLINE int len_manhattan_v2_int(const int v[2]) ATTR_WARN_UNUSED_RESULT;
MINLINE float len_manhattan_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT;
-MINLINE float len_v2(const float a[2]) ATTR_WARN_UNUSED_RESULT;
+MINLINE float len_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT;
MINLINE double len_v2_db(const double v[2]) ATTR_WARN_UNUSED_RESULT;
-MINLINE float len_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT;
-MINLINE double len_v2v2_db(const double a[2], const double b[2]) ATTR_WARN_UNUSED_RESULT;
+MINLINE float len_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT;
+MINLINE double len_v2v2_db(const double v1[2], const double v2[2]) ATTR_WARN_UNUSED_RESULT;
MINLINE float len_v2v2_int(const int v1[2], const int v2[2]);
MINLINE float len_squared_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT;
MINLINE double len_squared_v2v2_db(const double a[2], const double b[2]) ATTR_WARN_UNUSED_RESULT;
@@ -288,22 +288,22 @@ MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESU
MINLINE double len_v3_db(const double a[3]) ATTR_WARN_UNUSED_RESULT;
MINLINE double len_squared_v3_db(const double v[3]) ATTR_WARN_UNUSED_RESULT;
-MINLINE float normalize_v2_length(float r[2], float unit_scale);
+MINLINE float normalize_v2_length(float n[2], float unit_length);
/**
* \note any vectors containing `nan` will be zeroed out.
*/
-MINLINE float normalize_v2_v2_length(float r[2], const float a[2], float unit_scale);
-MINLINE float normalize_v3_length(float r[3], float unit_scale);
+MINLINE float normalize_v2_v2_length(float r[2], const float a[2], float unit_length);
+MINLINE float normalize_v3_length(float n[3], float unit_length);
/**
* \note any vectors containing `nan` will be zeroed out.
*/
-MINLINE float normalize_v3_v3_length(float r[3], const float a[3], float unit_scale);
-MINLINE double normalize_v3_length_db(double n[3], double unit_scale);
-MINLINE double normalize_v3_v3_length_db(double r[3], const double a[3], double unit_scale);
+MINLINE float normalize_v3_v3_length(float r[3], const float a[3], float unit_length);
+MINLINE double normalize_v3_length_db(double n[3], double unit_length);
+MINLINE double normalize_v3_v3_length_db(double r[3], const double a[3], double unit_length);
-MINLINE float normalize_v2(float r[2]);
+MINLINE float normalize_v2(float n[2]);
MINLINE float normalize_v2_v2(float r[2], const float a[2]);
-MINLINE float normalize_v3(float r[3]);
+MINLINE float normalize_v3(float n[3]);
MINLINE float normalize_v3_v3(float r[3], const float a[3]);
MINLINE double normalize_v3_v3_db(double r[3], const double a[3]);
MINLINE double normalize_v3_db(double n[3]);
@@ -424,45 +424,51 @@ void flip_v2_v2v2(float v[2], const float v1[2], const float v2[2]);
/** \name Comparison
* \{ */
-MINLINE bool is_zero_v2(const float a[2]) ATTR_WARN_UNUSED_RESULT;
-MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT;
-MINLINE bool is_zero_v4(const float a[4]) ATTR_WARN_UNUSED_RESULT;
+MINLINE bool is_zero_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT;
+MINLINE bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT;
+MINLINE bool is_zero_v4(const float v[4]) ATTR_WARN_UNUSED_RESULT;
-MINLINE bool is_zero_v2_db(const double a[2]) ATTR_WARN_UNUSED_RESULT;
-MINLINE bool is_zero_v3_db(const double a[3]) ATTR_WARN_UNUSED_RESULT;
-MINLINE bool is_zero_v4_db(const double a[4]) ATTR_WARN_UNUSED_RESULT;
+MINLINE bool is_zero_v2_db(const double v[2]) ATTR_WARN_UNUSED_RESULT;
+MINLINE bool is_zero_v3_db(const double v[3]) ATTR_WARN_UNUSED_RESULT;
+MINLINE bool is_zero_v4_db(const double v[4]) ATTR_WARN_UNUSED_RESULT;
-bool is_finite_v2(const float a[2]) ATTR_WARN_UNUSED_RESULT;
-bool is_finite_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT;
-bool is_finite_v4(const float a[4]) ATTR_WARN_UNUSED_RESULT;
+bool is_finite_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT;
+bool is_finite_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT;
+bool is_finite_v4(const float v[4]) ATTR_WARN_UNUSED_RESULT;
-MINLINE bool is_one_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT;
+MINLINE bool is_one_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT;
MINLINE bool equals_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT;
-MINLINE bool equals_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT;
-MINLINE bool equals_v4v4(const float a[4], const float b[4]) ATTR_WARN_UNUSED_RESULT;
+MINLINE bool equals_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT;
+MINLINE bool equals_v4v4(const float v1[4], const float v2[4]) ATTR_WARN_UNUSED_RESULT;
MINLINE bool equals_v2v2_int(const int v1[2], const int v2[2]) ATTR_WARN_UNUSED_RESULT;
MINLINE bool equals_v3v3_int(const int v1[3], const int v2[3]) ATTR_WARN_UNUSED_RESULT;
MINLINE bool equals_v4v4_int(const int v1[4], const int v2[4]) ATTR_WARN_UNUSED_RESULT;
-MINLINE bool compare_v2v2(const float a[2], const float b[2], float limit) ATTR_WARN_UNUSED_RESULT;
-MINLINE bool compare_v3v3(const float a[3], const float b[3], float limit) ATTR_WARN_UNUSED_RESULT;
-MINLINE bool compare_v4v4(const float a[4], const float b[4], float limit) ATTR_WARN_UNUSED_RESULT;
-
-MINLINE bool compare_v2v2_relative(const float a[2], const float b[2], float limit, int max_ulps)
+MINLINE bool compare_v2v2(const float v1[2],
+ const float v2[2],
+ float limit) ATTR_WARN_UNUSED_RESULT;
+MINLINE bool compare_v3v3(const float v1[3],
+ const float v2[3],
+ float limit) ATTR_WARN_UNUSED_RESULT;
+MINLINE bool compare_v4v4(const float v1[4],
+ const float v2[4],
+ float limit) ATTR_WARN_UNUSED_RESULT;
+
+MINLINE bool compare_v2v2_relative(const float v1[2], const float v2[2], float limit, int max_ulps)
ATTR_WARN_UNUSED_RESULT;
-MINLINE bool compare_v3v3_relative(const float a[3], const float b[3], float limit, int max_ulps)
+MINLINE bool compare_v3v3_relative(const float v1[3], const float v2[3], float limit, int max_ulps)
ATTR_WARN_UNUSED_RESULT;
-MINLINE bool compare_v4v4_relative(const float a[4], const float b[4], float limit, int max_ulps)
+MINLINE bool compare_v4v4_relative(const float v1[4], const float v2[4], float limit, int max_ulps)
ATTR_WARN_UNUSED_RESULT;
-MINLINE bool compare_len_v3v3(const float a[3],
- const float b[3],
+MINLINE bool compare_len_v3v3(const float v1[3],
+ const float v2[3],
float limit) ATTR_WARN_UNUSED_RESULT;
-MINLINE bool compare_size_v3v3(const float a[3],
- const float b[3],
+MINLINE bool compare_size_v3v3(const float v1[3],
+ const float v2[3],
float limit) ATTR_WARN_UNUSED_RESULT;
/**
@@ -606,8 +612,8 @@ void project_v3_plane(float out[3], const float plane_no[3], const float plane_c
* out: result (negate for a 'bounce').
* </pre>
*/
-void reflect_v3_v3v3(float out[3], const float vec[3], const float normal[3]);
-void reflect_v3_v3v3_db(double out[3], const double vec[3], const double normal[3]);
+void reflect_v3_v3v3(float out[3], const float v[3], const float normal[3]);
+void reflect_v3_v3v3_db(double out[3], const double v[3], const double normal[3]);
/**
* Takes a vector and computes 2 orthogonal directions.
*
@@ -655,10 +661,10 @@ void print_vn(const char *str, const float v[], int n);
#define print_v4_id(v) print_v4(STRINGIFY(v), v)
#define print_vn_id(v, n) print_vn(STRINGIFY(v), v, n)
-MINLINE void normal_float_to_short_v2(short r[2], const float n[2]);
-MINLINE void normal_short_to_float_v3(float r[3], const short n[3]);
-MINLINE void normal_float_to_short_v3(short r[3], const float n[3]);
-MINLINE void normal_float_to_short_v4(short r[4], const float n[4]);
+MINLINE void normal_float_to_short_v2(short out[2], const float in[2]);
+MINLINE void normal_short_to_float_v3(float out[3], const short in[3]);
+MINLINE void normal_float_to_short_v3(short out[3], const float in[3]);
+MINLINE void normal_float_to_short_v4(short out[4], const float in[4]);
void minmax_v4v4_v4(float min[4], float max[4], const float vec[4]);
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3]);
diff --git a/source/blender/blenlib/BLI_math_vector.hh b/source/blender/blenlib/BLI_math_vector.hh
index 384c4b49070..e8303aa858b 100644
--- a/source/blender/blenlib/BLI_math_vector.hh
+++ b/source/blender/blenlib/BLI_math_vector.hh
@@ -357,16 +357,16 @@ inline vec_base<T, 3> cross(const vec_base<T, 3> &a, const vec_base<T, 3> &b)
inline vec_base<float, 3> cross_high_precision(const vec_base<float, 3> &a,
const vec_base<float, 3> &b)
{
- return {(float)((double)a.y * b.z - (double)a.z * b.y),
- (float)((double)a.z * b.x - (double)a.x * b.z),
- (float)((double)a.x * b.y - (double)a.y * b.x)};
+ return {float(double(a.y) * double(b.z) - double(a.z) * double(b.y)),
+ float(double(a.z) * double(b.x) - double(a.x) * double(b.z)),
+ float(double(a.x) * double(b.y) - double(a.y) * double(b.x))};
}
template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))>
inline vec_base<T, 3> cross_poly(Span<vec_base<T, 3>> poly)
{
/* Newell's Method. */
- int nv = static_cast<int>(poly.size());
+ int nv = int(poly.size());
if (nv < 3) {
return vec_base<T, 3>(0, 0, 0);
}
diff --git a/source/blender/blenlib/BLI_memory_utils.hh b/source/blender/blenlib/BLI_memory_utils.hh
index c2ad3ea761a..b6ffa6d8b4a 100644
--- a/source/blender/blenlib/BLI_memory_utils.hh
+++ b/source/blender/blenlib/BLI_memory_utils.hh
@@ -372,7 +372,7 @@ template<size_t Size, size_t Alignment> class AlignedBuffer {
*/
template<typename T, int64_t Size = 1> class TypedBuffer {
private:
- BLI_NO_UNIQUE_ADDRESS AlignedBuffer<sizeof(T) * (size_t)Size, alignof(T)> buffer_;
+ BLI_NO_UNIQUE_ADDRESS AlignedBuffer<sizeof(T) * size_t(Size), alignof(T)> buffer_;
public:
operator T *()
@@ -516,7 +516,7 @@ inline constexpr bool is_same_any_v = (std::is_same_v<T, Args> || ...);
*/
inline constexpr int64_t default_inline_buffer_capacity(size_t element_size)
{
- return (static_cast<int64_t>(element_size) < 100) ? 4 : 0;
+ return (int64_t(element_size) < 100) ? 4 : 0;
}
/**
diff --git a/source/blender/blenlib/BLI_mesh_intersect.hh b/source/blender/blenlib/BLI_mesh_intersect.hh
index 22ea83760aa..4ed1fe5f513 100644
--- a/source/blender/blenlib/BLI_mesh_intersect.hh
+++ b/source/blender/blenlib/BLI_mesh_intersect.hh
@@ -354,12 +354,12 @@ struct BoundingBox {
void combine(const double3 &p)
{
- min.x = min_ff(min.x, static_cast<float>(p.x));
- min.y = min_ff(min.y, static_cast<float>(p.y));
- min.z = min_ff(min.z, static_cast<float>(p.z));
- max.x = max_ff(max.x, static_cast<float>(p.x));
- max.y = max_ff(max.y, static_cast<float>(p.y));
- max.z = max_ff(max.z, static_cast<float>(p.z));
+ min.x = min_ff(min.x, float(p.x));
+ min.y = min_ff(min.y, float(p.y));
+ min.z = min_ff(min.z, float(p.z));
+ max.x = max_ff(max.x, float(p.x));
+ max.y = max_ff(max.y, float(p.y));
+ max.z = max_ff(max.z, float(p.z));
}
void combine(const BoundingBox &bb)
diff --git a/source/blender/blenlib/BLI_multi_value_map.hh b/source/blender/blenlib/BLI_multi_value_map.hh
index 4b6300c09aa..81b536e7d3c 100644
--- a/source/blender/blenlib/BLI_multi_value_map.hh
+++ b/source/blender/blenlib/BLI_multi_value_map.hh
@@ -115,6 +115,14 @@ template<typename Key, typename Value> class MultiValueMap {
}
/**
+ * Get the number of keys.
+ */
+ int64_t size() const
+ {
+ return map_.size();
+ }
+
+ /**
* NOTE: This signature will change when the implementation changes.
*/
typename MapType::ItemIterator items() const
@@ -137,6 +145,11 @@ template<typename Key, typename Value> class MultiValueMap {
{
return map_.values();
}
+
+ void clear()
+ {
+ map_.clear();
+ }
};
} // namespace blender
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index 06dd9ab0db9..d4d2ddead71 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -7,7 +7,9 @@
*/
#include "BLI_compiler_attrs.h"
+#include "BLI_compiler_compat.h"
#include "BLI_utildefines.h"
+#include "BLI_utildefines_variadic.h"
#ifdef __cplusplus
extern "C" {
@@ -36,16 +38,6 @@ void BLI_setenv_if_new(const char *env, const char *val) ATTR_NONNULL(1);
const char *BLI_getenv(const char *env) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
/**
- * Returns in `string` the concatenation of `dir` and `file` (also with `relabase` on the
- * front if specified and `dir` begins with "//"). Normalizes all occurrences of path
- * separators, including ensuring there is exactly one between the copies of `dir` and `file`,
- * and between the copies of `relabase` and `dir`.
- *
- * \param relabase: Optional prefix to substitute for "//" on front of `dir`.
- * \param string: Area to return result.
- */
-void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file);
-/**
* Ensures that the parent directory of `name` exists.
*
* \return true on success (i.e. given path now exists on file-system), false otherwise.
@@ -79,26 +71,116 @@ const char *BLI_path_extension(const char *filepath) ATTR_NONNULL();
*/
void BLI_path_append(char *__restrict dst, size_t maxlen, const char *__restrict file)
ATTR_NONNULL();
+
/**
- * Simple appending of filename to dir, does not check for valid path!
- * Puts result into `dst`, which may be same area as `dir`.
- *
- * \note Consider using #BLI_path_join for more general path joining
- * that de-duplicates separators and can handle an arbitrary number of paths.
+ * See #BLI_path_join doc-string.
*/
-void BLI_join_dirfile(char *__restrict dst,
- size_t maxlen,
- const char *__restrict dir,
- const char *__restrict file) ATTR_NONNULL();
+size_t BLI_path_join_array(char *__restrict dst,
+ const size_t dst_len,
+ const char *path_array[],
+ const int path_array_num);
+
/**
* Join multiple strings into a path, ensuring only a single path separator between each,
* and trailing slash is kept.
*
+ * \param path: The first patch which has special treatment,
+ * allowing `//` prefix which is kept intact unlike double-slashes which are stripped
+ * from the bounds of all other paths passed in.
+ * Passing in the following paths all result in the same output (`//a/b/c`):
+ * - `"//", "a", "b", "c"`.
+ * - `"//", "/a/", "/b/", "/c"`.
+ * - `"//a", "b/c"`.
+ *
* \note If you want a trailing slash, add `SEP_STR` as the last path argument,
* duplicate slashes will be cleaned up.
*/
-size_t BLI_path_join(char *__restrict dst, size_t dst_len, const char *path_first, ...)
- ATTR_NONNULL(1, 3) ATTR_SENTINEL(0);
+#define BLI_path_join(...) VA_NARGS_CALL_OVERLOAD(_BLI_path_join_, __VA_ARGS__)
+
+#define _BLI_PATH_JOIN_ARGS_1 char *__restrict dst, size_t dst_len, const char *a
+#define _BLI_PATH_JOIN_ARGS_2 _BLI_PATH_JOIN_ARGS_1, const char *b
+#define _BLI_PATH_JOIN_ARGS_3 _BLI_PATH_JOIN_ARGS_2, const char *c
+#define _BLI_PATH_JOIN_ARGS_4 _BLI_PATH_JOIN_ARGS_3, const char *d
+#define _BLI_PATH_JOIN_ARGS_5 _BLI_PATH_JOIN_ARGS_4, const char *e
+#define _BLI_PATH_JOIN_ARGS_6 _BLI_PATH_JOIN_ARGS_5, const char *f
+#define _BLI_PATH_JOIN_ARGS_7 _BLI_PATH_JOIN_ARGS_6, const char *g
+#define _BLI_PATH_JOIN_ARGS_8 _BLI_PATH_JOIN_ARGS_7, const char *h
+#define _BLI_PATH_JOIN_ARGS_9 _BLI_PATH_JOIN_ARGS_8, const char *i
+#define _BLI_PATH_JOIN_ARGS_10 _BLI_PATH_JOIN_ARGS_9, const char *j
+
+BLI_INLINE size_t _BLI_path_join_3(_BLI_PATH_JOIN_ARGS_1) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_path_join_4(_BLI_PATH_JOIN_ARGS_2) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_path_join_5(_BLI_PATH_JOIN_ARGS_3) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_path_join_6(_BLI_PATH_JOIN_ARGS_4) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_path_join_7(_BLI_PATH_JOIN_ARGS_5) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_path_join_8(_BLI_PATH_JOIN_ARGS_6) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_path_join_9(_BLI_PATH_JOIN_ARGS_7) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_path_join_10(_BLI_PATH_JOIN_ARGS_8) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_path_join_11(_BLI_PATH_JOIN_ARGS_9) ATTR_NONNULL();
+BLI_INLINE size_t _BLI_path_join_12(_BLI_PATH_JOIN_ARGS_10) ATTR_NONNULL();
+
+BLI_INLINE size_t _BLI_path_join_3(_BLI_PATH_JOIN_ARGS_1)
+{
+ const char *path_array[] = {a};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+BLI_INLINE size_t _BLI_path_join_4(_BLI_PATH_JOIN_ARGS_2)
+{
+ const char *path_array[] = {a, b};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+BLI_INLINE size_t _BLI_path_join_5(_BLI_PATH_JOIN_ARGS_3)
+{
+ const char *path_array[] = {a, b, c};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+BLI_INLINE size_t _BLI_path_join_6(_BLI_PATH_JOIN_ARGS_4)
+{
+ const char *path_array[] = {a, b, c, d};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+BLI_INLINE size_t _BLI_path_join_7(_BLI_PATH_JOIN_ARGS_5)
+{
+ const char *path_array[] = {a, b, c, d, e};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+BLI_INLINE size_t _BLI_path_join_8(_BLI_PATH_JOIN_ARGS_6)
+{
+ const char *path_array[] = {a, b, c, d, e, f};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+BLI_INLINE size_t _BLI_path_join_9(_BLI_PATH_JOIN_ARGS_7)
+{
+ const char *path_array[] = {a, b, c, d, e, f, g};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+BLI_INLINE size_t _BLI_path_join_10(_BLI_PATH_JOIN_ARGS_8)
+{
+ const char *path_array[] = {a, b, c, d, e, f, g, h};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+BLI_INLINE size_t _BLI_path_join_11(_BLI_PATH_JOIN_ARGS_9)
+{
+ const char *path_array[] = {a, b, c, d, e, f, g, h, i};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+BLI_INLINE size_t _BLI_path_join_12(_BLI_PATH_JOIN_ARGS_10)
+{
+ const char *path_array[] = {a, b, c, d, e, f, g, h, i, j};
+ return BLI_path_join_array(dst, dst_len, path_array, ARRAY_SIZE(path_array));
+}
+
+#undef _BLI_PATH_JOIN_ARGS_1
+#undef _BLI_PATH_JOIN_ARGS_2
+#undef _BLI_PATH_JOIN_ARGS_3
+#undef _BLI_PATH_JOIN_ARGS_4
+#undef _BLI_PATH_JOIN_ARGS_5
+#undef _BLI_PATH_JOIN_ARGS_6
+#undef _BLI_PATH_JOIN_ARGS_7
+#undef _BLI_PATH_JOIN_ARGS_8
+#undef _BLI_PATH_JOIN_ARGS_9
+#undef _BLI_PATH_JOIN_ARGS_10
+
/**
* Like Python's `os.path.basename()`
*
@@ -108,10 +190,10 @@ size_t BLI_path_join(char *__restrict dst, size_t dst_len, const char *path_firs
const char *BLI_path_basename(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
/**
* Get an element of the path at an index, eg:
- * "/some/path/file.txt" where an index of:
- * - 0 or -3: "some"
- * - 1 or -2: "path"
- * - 2 or -1: "file.txt"
+ * `/some/path/file.txt` where an index of:
+ * - 0 or -3: `some`
+ * - 1 or -2: `path`
+ * - 2 or -1: `file.txt`
*
* Ignores multiple slashes at any point in the path (including start/end).
*/
@@ -367,8 +449,8 @@ void BLI_path_normalize_unc(char *path_16, int maxlen);
/**
* Appends a suffix to the string, fitting it before the extension
*
- * string = Foo.png, suffix = 123, separator = _
- * Foo.png -> Foo_123.png
+ * string = `Foo.png`, suffix = `123`, separator = `_`.
+ * `Foo.png` -> `Foo_123.png`.
*
* \param string: original (and final) string
* \param maxlen: Maximum length of string
diff --git a/source/blender/blenlib/BLI_pool.hh b/source/blender/blenlib/BLI_pool.hh
new file mode 100644
index 00000000000..8745c019db5
--- /dev/null
+++ b/source/blender/blenlib/BLI_pool.hh
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup bli
+ *
+ * A `blender::Pool` allows fast allocation and deallocation of many elements of the same type.
+ *
+ * It is compatible with types that are not movable.
+ *
+ * Freed elements memory will be reused by next allocations.
+ * Elements are allocated in chunks to reduce memory fragmentation and avoid reallocation.
+ */
+
+#pragma once
+
+#include "BLI_stack.hh"
+#include "BLI_utility_mixins.hh"
+#include "BLI_vector.hh"
+
+namespace blender {
+
+template<typename T, int64_t ChunkLen = 64> class Pool : NonCopyable {
+ private:
+ using Chunk = TypedBuffer<T, ChunkLen>;
+
+ /** Allocated item buffer. */
+ Vector<std::unique_ptr<Chunk>> values_;
+ /** List of freed elements to be use for the next allocations. A Stack is best here to avoid
+ * overhead when growing the free list. It also offers better cache performance than a queue
+ * since last added entries will be reused first. */
+ Stack<T *, 0> free_list_;
+
+ public:
+ ~Pool()
+ {
+ /* All elements need to be freed before freeing the pool. */
+ BLI_assert(this->size() == 0);
+ }
+
+ /**
+ * Construct an object inside this pool's memory.
+ */
+ template<typename... ForwardT> T &construct(ForwardT &&...value)
+ {
+ if (free_list_.is_empty()) {
+ values_.append(std::make_unique<Chunk>());
+ T *chunk_start = values_.last()->ptr();
+ for (auto i : IndexRange(ChunkLen)) {
+ free_list_.push(chunk_start + i);
+ }
+ }
+ T *ptr = free_list_.pop();
+ new (ptr) T(std::forward<ForwardT>(value)...);
+ return *ptr;
+ }
+
+ /**
+ * Destroy the given element inside this memory pool. Memory will be reused by next element
+ * construction. This invokes undefined behavior if the item is not from this pool.
+ */
+ void destruct(T &value)
+ {
+ value.~T();
+ free_list_.push(&value);
+ }
+
+ /**
+ * Return the number of constructed elements in this pool.
+ */
+ int64_t size() const
+ {
+ return values_.size() * ChunkLen - free_list_.size();
+ }
+
+ /**
+ * Returns true when the pool contains no elements, otherwise false.
+ */
+ bool is_empty() const
+ {
+ return this->size() == 0;
+ }
+};
+
+} // namespace blender
diff --git a/source/blender/blenlib/BLI_probing_strategies.hh b/source/blender/blenlib/BLI_probing_strategies.hh
index c6152e4d03d..d11bed9208e 100644
--- a/source/blender/blenlib/BLI_probing_strategies.hh
+++ b/source/blender/blenlib/BLI_probing_strategies.hh
@@ -2,6 +2,8 @@
#pragma once
+#include <numeric>
+
/** \file
* \ingroup bli
*
@@ -20,7 +22,7 @@
* clustering issues. However, more linear steps can also make things slower when the initial hash
* produces many collisions.
*
- * Every probing strategy has to guarantee, that every possible uint64_t is returned eventually.
+ * Every probing strategy has to guarantee that every possible uint64_t is returned eventually.
* This is necessary for correctness. If this is not the case, empty slots might not be found.
*
* The SLOT_PROBING_BEGIN and SLOT_PROBING_END macros can be used to implement a loop that iterates
@@ -69,7 +71,7 @@ class LinearProbingStrategy {
int64_t linear_steps() const
{
- return UINT32_MAX;
+ return std::numeric_limits<int64_t>::max();
}
};
@@ -221,7 +223,7 @@ using DefaultProbingStrategy = PythonProbingStrategy<>;
int64_t linear_offset = 0; \
uint64_t current_hash = probing_strategy.get(); \
do { \
- int64_t R_SLOT_INDEX = static_cast<int64_t>((current_hash + static_cast<uint64_t>(linear_offset)) & MASK);
+ int64_t R_SLOT_INDEX = int64_t((current_hash + uint64_t(linear_offset)) & MASK);
#define SLOT_PROBING_END() \
} while (++linear_offset < probing_strategy.linear_steps()); \
diff --git a/source/blender/blenlib/BLI_rand.hh b/source/blender/blenlib/BLI_rand.hh
index 2c4484bd63f..e4f35bef217 100644
--- a/source/blender/blenlib/BLI_rand.hh
+++ b/source/blender/blenlib/BLI_rand.hh
@@ -29,7 +29,7 @@ class RandomNumberGenerator {
void seed(uint32_t seed)
{
constexpr uint64_t lowseed = 0x330E;
- x_ = (static_cast<uint64_t>(seed) << 16) | lowseed;
+ x_ = (uint64_t(seed) << 16) | lowseed;
}
/**
@@ -40,13 +40,13 @@ class RandomNumberGenerator {
uint32_t get_uint32()
{
this->step();
- return static_cast<uint32_t>(x_ >> 17);
+ return uint32_t(x_ >> 17);
}
int32_t get_int32()
{
this->step();
- return static_cast<int32_t>(x_ >> 17);
+ return int32_t(x_ >> 17);
}
/**
@@ -63,7 +63,7 @@ class RandomNumberGenerator {
*/
double get_double()
{
- return (double)this->get_int32() / 0x80000000;
+ return double(this->get_int32()) / 0x80000000;
}
/**
diff --git a/source/blender/blenlib/BLI_resource_scope.hh b/source/blender/blenlib/BLI_resource_scope.hh
index 9826b694e16..d3f6d5e3f13 100644
--- a/source/blender/blenlib/BLI_resource_scope.hh
+++ b/source/blender/blenlib/BLI_resource_scope.hh
@@ -128,7 +128,7 @@ template<typename Func> inline void ResourceScope::add_destruct_call(Func func)
{
void *buffer = allocator_.allocate(sizeof(Func), alignof(Func));
new (buffer) Func(std::move(func));
- this->add(buffer, [](void *data) { (*(Func *)data)(); });
+ this->add(buffer, [](void *data) { (*static_cast<Func *>(data))(); });
}
/**
diff --git a/source/blender/blenlib/BLI_scanfill.h b/source/blender/blenlib/BLI_scanfill.h
index 04ac7cb05e4..b5b100ac27d 100644
--- a/source/blender/blenlib/BLI_scanfill.h
+++ b/source/blender/blenlib/BLI_scanfill.h
@@ -82,7 +82,7 @@ struct ScanFillEdge *BLI_scanfill_edge_add(ScanFillContext *sf_ctx,
struct ScanFillVert *v2);
enum {
- /* NOTE(campbell): using BLI_SCANFILL_CALC_REMOVE_DOUBLES
+ /* NOTE(@campbellbarton): using #BLI_SCANFILL_CALC_REMOVE_DOUBLES
* Assumes ordered edges, otherwise we risk an eternal loop
* removing double verts. */
BLI_SCANFILL_CALC_REMOVE_DOUBLES = (1 << 1),
diff --git a/source/blender/blenlib/BLI_serialize.hh b/source/blender/blenlib/BLI_serialize.hh
index bd91c522d06..e23d7d20d0b 100644
--- a/source/blender/blenlib/BLI_serialize.hh
+++ b/source/blender/blenlib/BLI_serialize.hh
@@ -55,7 +55,6 @@
*
* To add a new formatter a new sub-class of `Formatter` must be created and the
* `serialize`/`deserialize` methods should be implemented.
- *
*/
#include <ostream>
@@ -110,7 +109,6 @@ using ArrayValue = ContainerValue<Vector<std::shared_ptr<Value>>, eValueType::Ar
* - `DoubleValue`: contains a double precision floating point number.
* - `DictionaryValue`: represents an object (key value pairs where keys are strings and values can
* be of different types.
- *
*/
class Value {
private:
diff --git a/source/blender/blenlib/BLI_set.hh b/source/blender/blenlib/BLI_set.hh
index 62de4b79e41..8fb618edeb6 100644
--- a/source/blender/blenlib/BLI_set.hh
+++ b/source/blender/blenlib/BLI_set.hh
@@ -427,10 +427,10 @@ class Set {
return *this;
}
- Iterator operator++(int) const
+ Iterator operator++(int)
{
Iterator copied_iterator = *this;
- ++copied_iterator;
+ ++(*this);
return copied_iterator;
}
@@ -493,6 +493,24 @@ class Set {
}
/**
+ * Remove all values for which the given predicate is true.
+ *
+ * This is similar to std::erase_if.
+ */
+ template<typename Predicate> void remove_if(Predicate &&predicate)
+ {
+ for (Slot &slot : slots_) {
+ if (slot.is_occupied()) {
+ const Key &key = *slot.key();
+ if (predicate(key)) {
+ slot.remove();
+ removed_slots_++;
+ }
+ }
+ }
+ }
+
+ /**
* Print common statistics like size and collision count. This is useful for debugging purposes.
*/
void print_stats(StringRef name = "") const
@@ -626,7 +644,7 @@ class Set {
max_load_factor_.compute_total_and_usable_slots(
SlotArray::inline_buffer_capacity(), min_usable_slots, &total_slots, &usable_slots);
BLI_assert(total_slots >= 1);
- const uint64_t new_slot_mask = static_cast<uint64_t>(total_slots) - 1;
+ const uint64_t new_slot_mask = uint64_t(total_slots) - 1;
/**
* Optimize the case when the set was empty beforehand. We can avoid some copies here.
@@ -854,7 +872,7 @@ template<typename Key> class StdUnorderedSetWrapper {
public:
int64_t size() const
{
- return static_cast<int64_t>(set_.size());
+ return int64_t(set_.size());
}
bool is_empty() const
@@ -899,7 +917,7 @@ template<typename Key> class StdUnorderedSetWrapper {
bool remove(const Key &key)
{
- return (bool)set_.erase(key);
+ return bool(set_.erase(key));
}
void remove_contained(const Key &key)
diff --git a/source/blender/blenlib/BLI_set_slots.hh b/source/blender/blenlib/BLI_set_slots.hh
index 805c194ac90..8ef49e0a2d0 100644
--- a/source/blender/blenlib/BLI_set_slots.hh
+++ b/source/blender/blenlib/BLI_set_slots.hh
@@ -129,7 +129,7 @@ template<typename Key> class SimpleSetSlot {
* key. The hash is used by other slot implementations to determine inequality faster.
*/
template<typename ForwardKey, typename IsEqual>
- bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t UNUSED(hash)) const
+ bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t /*hash*/) const
{
if (state_ == Occupied) {
return is_equal(key, *key_buffer_);
@@ -141,7 +141,7 @@ template<typename Key> class SimpleSetSlot {
* Change the state of this slot from empty/removed to occupied. The key has to be constructed
* by calling the constructor with the given key as parameter.
*/
- template<typename ForwardKey> void occupy(ForwardKey &&key, uint64_t UNUSED(hash))
+ template<typename ForwardKey> void occupy(ForwardKey &&key, uint64_t /*hash*/)
{
BLI_assert(!this->is_occupied());
new (&key_buffer_) Key(std::forward<ForwardKey>(key));
@@ -226,7 +226,7 @@ template<typename Key> class HashedSetSlot {
return state_ == Empty;
}
- template<typename Hash> uint64_t get_hash(const Hash &UNUSED(hash)) const
+ template<typename Hash> uint64_t get_hash(const Hash & /*hash*/) const
{
BLI_assert(this->is_occupied());
return hash_;
@@ -306,13 +306,13 @@ template<typename Key, typename KeyInfo> class IntrusiveSetSlot {
}
template<typename ForwardKey, typename IsEqual>
- bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint64_t UNUSED(hash)) const
+ bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint64_t /*hash*/) const
{
BLI_assert(KeyInfo::is_not_empty_or_removed(key));
return is_equal(key_, key);
}
- template<typename ForwardKey> void occupy(ForwardKey &&key, const uint64_t UNUSED(hash))
+ template<typename ForwardKey> void occupy(ForwardKey &&key, const uint64_t /*hash*/)
{
BLI_assert(!this->is_occupied());
BLI_assert(KeyInfo::is_not_empty_or_removed(key));
diff --git a/source/blender/blenlib/BLI_span.hh b/source/blender/blenlib/BLI_span.hh
index 0f3fcea1270..adfccd8d6fe 100644
--- a/source/blender/blenlib/BLI_span.hh
+++ b/source/blender/blenlib/BLI_span.hh
@@ -112,13 +112,11 @@ template<typename T> class Span {
* Span<int> span = {1, 2, 3, 4};
* call_function_with_array(span);
*/
- constexpr Span(const std::initializer_list<T> &list)
- : Span(list.begin(), static_cast<int64_t>(list.size()))
+ constexpr Span(const std::initializer_list<T> &list) : Span(list.begin(), int64_t(list.size()))
{
}
- constexpr Span(const std::vector<T> &vector)
- : Span(vector.data(), static_cast<int64_t>(vector.size()))
+ constexpr Span(const std::vector<T> &vector) : Span(vector.data(), int64_t(vector.size()))
{
}
@@ -718,7 +716,7 @@ template<typename T> class MutableSpan {
{
BLI_assert((size_ * sizeof(T)) % sizeof(NewT) == 0);
int64_t new_size = size_ * sizeof(T) / sizeof(NewT);
- return MutableSpan<NewT>((NewT *)data_, new_size);
+ return MutableSpan<NewT>(reinterpret_cast<NewT *>(data_), new_size);
}
};
diff --git a/source/blender/blenlib/BLI_strict_flags.h b/source/blender/blenlib/BLI_strict_flags.h
index 8489871d5da..cc5b5dce363 100644
--- a/source/blender/blenlib/BLI_strict_flags.h
+++ b/source/blender/blenlib/BLI_strict_flags.h
@@ -9,16 +9,12 @@
*/
#ifdef __GNUC__
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 /* gcc4.6+ only */
+/* NOTE(@campbellbarton): CLANG behaves slightly differently to GCC,
+ * these can be enabled but do so carefully as they can introduce build-errors. */
+# if !defined(__clang__)
# pragma GCC diagnostic error "-Wsign-compare"
-# endif
-# if __GNUC__ >= 6 /* gcc6+ only */
# pragma GCC diagnostic error "-Wconversion"
-# endif
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 408
-/* gcc4.8+ only (behavior changed to ignore globals). */
# pragma GCC diagnostic error "-Wshadow"
-/* older gcc changed behavior with ternary */
# pragma GCC diagnostic error "-Wsign-conversion"
# endif
/* pedantic gives too many issues, developers can define this for own use */
diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h
index 15926e8f2d2..17abcf52ecc 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -309,6 +309,28 @@ void BLI_str_format_byte_unit(char dst[15], long long int bytes, bool base_10) A
*/
void BLI_str_format_decimal_unit(char dst[7], int number_to_format) ATTR_NONNULL();
/**
+ * Format a count to up to 3 places (plus minus sign, plus '\0' terminator) string using long
+ * number names abbreviations. Used to produce a compact representation of large numbers as
+ * integers.
+ *
+ * It shows a lower bound instead of rounding the number.
+ *
+ * 1 -> 1
+ * 15 -> 15
+ * 155 -> 155
+ * 1555 -> 1K
+ * 15555 -> 15K
+ * 155555 -> .1M
+ * 1555555 -> 1M
+ * 15555555 -> 15M
+ * 155555555 -> .1B
+ * 1000000000 -> 1B
+ * ...
+ *
+ * Length of 5 is the maximum of the resulting string, for example, `-15K\0`.
+ */
+void BLI_str_format_integer_unit(char dst[5], int number_to_format) ATTR_NONNULL();
+/**
* Compare two strings without regard to case.
*
* \retval True if the strings are equal, false otherwise.
diff --git a/source/blender/blenlib/BLI_string_cursor_utf8.h b/source/blender/blenlib/BLI_string_cursor_utf8.h
index 70ba5da8e5a..9c0589b230a 100644
--- a/source/blender/blenlib/BLI_string_cursor_utf8.h
+++ b/source/blender/blenlib/BLI_string_cursor_utf8.h
@@ -25,6 +25,9 @@ typedef enum eStrCursorJumpDirection {
bool BLI_str_cursor_step_next_utf8(const char *str, size_t maxlen, int *pos);
bool BLI_str_cursor_step_prev_utf8(const char *str, size_t maxlen, int *pos);
+bool BLI_str_cursor_step_next_utf32(const char32_t *str, size_t maxlen, int *pos);
+bool BLI_str_cursor_step_prev_utf32(const char32_t *str, size_t maxlen, int *pos);
+
void BLI_str_cursor_step_utf8(const char *str,
size_t maxlen,
int *pos,
diff --git a/source/blender/blenlib/BLI_string_ref.hh b/source/blender/blenlib/BLI_string_ref.hh
index 3823bd02630..14dee54d730 100644
--- a/source/blender/blenlib/BLI_string_ref.hh
+++ b/source/blender/blenlib/BLI_string_ref.hh
@@ -178,12 +178,12 @@ constexpr StringRefBase::operator Span<char>() const
*/
inline StringRefBase::operator std::string() const
{
- return std::string(data_, static_cast<size_t>(size_));
+ return std::string(data_, size_t(size_));
}
constexpr StringRefBase::operator std::string_view() const
{
- return std::string_view(data_, static_cast<size_t>(size_));
+ return std::string_view(data_, size_t(size_));
}
constexpr const char *StringRefBase::begin() const
@@ -209,7 +209,7 @@ constexpr IndexRange StringRefBase::index_range() const
inline void StringRefBase::unsafe_copy(char *dst) const
{
if (size_ > 0) {
- memcpy(dst, data_, static_cast<size_t>(size_));
+ memcpy(dst, data_, size_t(size_));
}
dst[size_] = '\0';
}
@@ -308,86 +308,79 @@ constexpr int64_t index_or_npos_to_int64(size_t index)
if (index == std::string_view::npos) {
return StringRef::not_found;
}
- return static_cast<int64_t>(index);
+ return int64_t(index);
}
constexpr int64_t StringRefBase::find(char c, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(std::string_view(*this).find(c, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find(c, size_t(pos)));
}
constexpr int64_t StringRefBase::find(StringRef str, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(std::string_view(*this).find(str, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find(str, size_t(pos)));
}
constexpr int64_t StringRefBase::rfind(char c, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(std::string_view(*this).rfind(c, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).rfind(c, size_t(pos)));
}
constexpr int64_t StringRefBase::rfind(StringRef str, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(std::string_view(*this).rfind(str, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).rfind(str, size_t(pos)));
}
constexpr int64_t StringRefBase::find_first_of(StringRef chars, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(
- std::string_view(*this).find_first_of(chars, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find_first_of(chars, size_t(pos)));
}
constexpr int64_t StringRefBase::find_first_of(char c, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(
- std::string_view(*this).find_first_of(c, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find_first_of(c, size_t(pos)));
}
constexpr int64_t StringRefBase::find_last_of(StringRef chars, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(
- std::string_view(*this).find_last_of(chars, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find_last_of(chars, size_t(pos)));
}
constexpr int64_t StringRefBase::find_last_of(char c, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(std::string_view(*this).find_last_of(c, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find_last_of(c, size_t(pos)));
}
constexpr int64_t StringRefBase::find_first_not_of(StringRef chars, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(
- std::string_view(*this).find_first_not_of(chars, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find_first_not_of(chars, size_t(pos)));
}
constexpr int64_t StringRefBase::find_first_not_of(char c, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(
- std::string_view(*this).find_first_not_of(c, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find_first_not_of(c, size_t(pos)));
}
constexpr int64_t StringRefBase::find_last_not_of(StringRef chars, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(
- std::string_view(*this).find_last_not_of(chars, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find_last_not_of(chars, size_t(pos)));
}
constexpr int64_t StringRefBase::find_last_not_of(char c, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(
- std::string_view(*this).find_last_not_of(c, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find_last_not_of(c, size_t(pos)));
}
constexpr StringRef StringRefBase::trim() const
@@ -440,15 +433,14 @@ constexpr StringRefNull::StringRefNull() : StringRefBase("", 0)
constexpr StringRefNull::StringRefNull(const char *str, const int64_t size)
: StringRefBase(str, size)
{
- BLI_assert(static_cast<int64_t>(strlen(str)) == size);
+ BLI_assert(int64_t(strlen(str)) == size);
}
/**
* Construct a StringRefNull from a null terminated c-string. The pointer must not point to
* NULL.
*/
-inline StringRefNull::StringRefNull(const char *str)
- : StringRefBase(str, static_cast<int64_t>(strlen(str)))
+inline StringRefNull::StringRefNull(const char *str) : StringRefBase(str, int64_t(strlen(str)))
{
BLI_assert(str != nullptr);
BLI_assert(data_[size_] == '\0');
@@ -504,7 +496,7 @@ constexpr StringRef::StringRef(StringRefNull other) : StringRefBase(other.data()
* Create a StringRef from a null-terminated c-string.
*/
constexpr StringRef::StringRef(const char *str)
- : StringRefBase(str, str ? static_cast<int64_t>(std::char_traits<char>::length(str)) : 0)
+ : StringRefBase(str, str ? int64_t(std::char_traits<char>::length(str)) : 0)
{
}
@@ -560,7 +552,7 @@ constexpr char StringRef::operator[](int64_t index) const
* second point points to a smaller address than the first one.
*/
constexpr StringRef::StringRef(const char *begin, const char *one_after_end)
- : StringRefBase(begin, static_cast<int64_t>(one_after_end - begin))
+ : StringRefBase(begin, int64_t(one_after_end - begin))
{
BLI_assert(begin <= one_after_end);
}
@@ -570,12 +562,12 @@ constexpr StringRef::StringRef(const char *begin, const char *one_after_end)
* will point to uninitialized memory.
*/
inline StringRef::StringRef(const std::string &str)
- : StringRefBase(str.data(), static_cast<int64_t>(str.size()))
+ : StringRefBase(str.data(), int64_t(str.size()))
{
}
constexpr StringRef::StringRef(std::string_view view)
- : StringRefBase(view.data(), static_cast<int64_t>(view.size()))
+ : StringRefBase(view.data(), int64_t(view.size()))
{
}
@@ -593,7 +585,7 @@ inline std::ostream &operator<<(std::ostream &stream, StringRef ref)
inline std::ostream &operator<<(std::ostream &stream, StringRefNull ref)
{
- stream << std::string(ref.data(), (size_t)ref.size());
+ stream << std::string(ref.data(), size_t(ref.size()));
return stream;
}
@@ -619,7 +611,7 @@ constexpr bool operator==(StringRef a, StringRef b)
/* This also avoids passing null to the call below, which would results in an ASAN warning. */
return true;
}
- return STREQLEN(a.data(), b.data(), (size_t)a.size());
+ return STREQLEN(a.data(), b.data(), size_t(a.size()));
}
constexpr bool operator!=(StringRef a, StringRef b)
diff --git a/source/blender/blenlib/BLI_string_utf8.h b/source/blender/blenlib/BLI_string_utf8.h
index 4c5cc3fd9c5..61a21fd8bbf 100644
--- a/source/blender/blenlib/BLI_string_utf8.h
+++ b/source/blender/blenlib/BLI_string_utf8.h
@@ -157,8 +157,8 @@ size_t BLI_strnlen_utf8(const char *strc, size_t maxlen) ATTR_NONNULL(1) ATTR_WA
size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst,
const wchar_t *__restrict src,
size_t maxncpy) ATTR_NONNULL(1, 2);
-size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst,
- const char *__restrict src,
+size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst_w,
+ const char *__restrict src_c,
size_t maxncpy) ATTR_NONNULL(1, 2);
/**
@@ -174,17 +174,17 @@ int BLI_str_utf8_char_width_safe(const char *p) ATTR_WARN_UNUSED_RESULT ATTR_NON
size_t BLI_str_partition_utf8(const char *str,
const unsigned int delim[],
- const char **sep,
- const char **suf) ATTR_NONNULL(1, 2, 3, 4);
+ const char **r_sep,
+ const char **r_suf) ATTR_NONNULL(1, 2, 3, 4);
size_t BLI_str_rpartition_utf8(const char *str,
const unsigned int delim[],
- const char **sep,
- const char **suf) ATTR_NONNULL(1, 2, 3, 4);
+ const char **r_sep,
+ const char **r_suf) ATTR_NONNULL(1, 2, 3, 4);
size_t BLI_str_partition_ex_utf8(const char *str,
const char *end,
const unsigned int delim[],
- const char **sep,
- const char **suf,
+ const char **r_sep,
+ const char **r_suf,
bool from_right) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 3, 4, 5);
int BLI_str_utf8_offset_to_index(const char *str, int offset) ATTR_WARN_UNUSED_RESULT
diff --git a/source/blender/blenlib/BLI_task.hh b/source/blender/blenlib/BLI_task.hh
index 904dea66f7a..9f9a57be634 100644
--- a/source/blender/blenlib/BLI_task.hh
+++ b/source/blender/blenlib/BLI_task.hh
@@ -31,6 +31,7 @@
#endif
#include "BLI_index_range.hh"
+#include "BLI_lazy_threading.hh"
#include "BLI_utildefines.h"
namespace blender::threading {
@@ -56,6 +57,7 @@ void parallel_for(IndexRange range, int64_t grain_size, const Function &function
#ifdef WITH_TBB
/* Invoking tbb for small workloads has a large overhead. */
if (range.size() >= grain_size) {
+ lazy_threading::send_hint();
tbb::parallel_for(
tbb::blocked_range<int64_t>(range.first(), range.one_after_last(), grain_size),
[&](const tbb::blocked_range<int64_t> &subrange) {
@@ -78,6 +80,7 @@ Value parallel_reduce(IndexRange range,
{
#ifdef WITH_TBB
if (range.size() >= grain_size) {
+ lazy_threading::send_hint();
return tbb::parallel_reduce(
tbb::blocked_range<int64_t>(range.first(), range.one_after_last(), grain_size),
identity,
@@ -105,6 +108,23 @@ template<typename... Functions> void parallel_invoke(Functions &&...functions)
#endif
}
+/**
+ * Same #parallel_invoke, but allows disabling threading dynamically. This is useful because when
+ * the individual functions do very little work, there is a lot of overhead from starting parallel
+ * tasks.
+ */
+template<typename... Functions>
+void parallel_invoke(const bool use_threading, Functions &&...functions)
+{
+ if (use_threading) {
+ lazy_threading::send_hint();
+ parallel_invoke(std::forward<Functions>(functions)...);
+ }
+ else {
+ (functions(), ...);
+ }
+}
+
/** See #BLI_task_isolate for a description of what isolating a task means. */
template<typename Function> void isolate_task(const Function &function)
{
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index 7f9470a9111..98177876f87 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -589,7 +589,7 @@ extern "C" {
/** Performs `offsetof(typeof(data), member) + sizeof((data)->member)` for non-gcc compilers. */
#define OFFSETOF_STRUCT_AFTER(_struct, _member) \
- ((((const char *)&((_struct)->_member)) - ((const char *)(_struct))) + \
+ ((size_t)(((const char *)&((_struct)->_member)) - ((const char *)(_struct))) + \
sizeof((_struct)->_member))
/**
@@ -786,24 +786,23 @@ extern bool BLI_memory_is_zero(const void *arr, size_t arr_size);
extern "C++" { \
inline constexpr _enum_type operator|(_enum_type a, _enum_type b) \
{ \
- return static_cast<_enum_type>(static_cast<uint64_t>(a) | static_cast<uint64_t>(b)); \
+ return (_enum_type)(uint64_t(a) | uint64_t(b)); \
} \
inline constexpr _enum_type operator&(_enum_type a, _enum_type b) \
{ \
- return static_cast<_enum_type>(static_cast<uint64_t>(a) & static_cast<uint64_t>(b)); \
+ return (_enum_type)(uint64_t(a) & uint64_t(b)); \
} \
inline constexpr _enum_type operator~(_enum_type a) \
{ \
- return static_cast<_enum_type>(~static_cast<uint64_t>(a) & \
- (2 * static_cast<uint64_t>(_max_enum_value) - 1)); \
+ return (_enum_type)(~uint64_t(a) & (2 * uint64_t(_max_enum_value) - 1)); \
} \
inline _enum_type &operator|=(_enum_type &a, _enum_type b) \
{ \
- return a = static_cast<_enum_type>(static_cast<uint64_t>(a) | static_cast<uint64_t>(b)); \
+ return a = (_enum_type)(uint64_t(a) | uint64_t(b)); \
} \
inline _enum_type &operator&=(_enum_type &a, _enum_type b) \
{ \
- return a = static_cast<_enum_type>(static_cast<uint64_t>(a) & static_cast<uint64_t>(b)); \
+ return a = (_enum_type)(uint64_t(a) & uint64_t(b)); \
} \
} /* extern "C++" */
diff --git a/source/blender/blenlib/BLI_vector.hh b/source/blender/blenlib/BLI_vector.hh
index 1f5f97d754d..cba58945546 100644
--- a/source/blender/blenlib/BLI_vector.hh
+++ b/source/blender/blenlib/BLI_vector.hh
@@ -96,8 +96,7 @@ class Vector {
*/
#ifndef NDEBUG
int64_t debug_size_;
-# define UPDATE_VECTOR_SIZE(ptr) \
- (ptr)->debug_size_ = static_cast<int64_t>((ptr)->end_ - (ptr)->begin_)
+# define UPDATE_VECTOR_SIZE(ptr) (ptr)->debug_size_ = int64_t((ptr)->end_ - (ptr)->begin_)
#else
# define UPDATE_VECTOR_SIZE(ptr) ((void)0)
#endif
@@ -244,7 +243,7 @@ class Vector {
/* Copy from inline buffer to newly allocated buffer. */
const int64_t capacity = size;
begin_ = static_cast<T *>(
- allocator_.allocate(sizeof(T) * static_cast<size_t>(capacity), alignof(T), AT));
+ allocator_.allocate(sizeof(T) * size_t(capacity), alignof(T), AT));
capacity_end_ = begin_ + capacity;
uninitialized_relocate_n(other.begin_, size, begin_);
end_ = begin_ + size;
@@ -693,7 +692,7 @@ class Vector {
*/
int64_t size() const
{
- const int64_t current_size = static_cast<int64_t>(end_ - begin_);
+ const int64_t current_size = int64_t(end_ - begin_);
BLI_assert(debug_size_ == current_size);
return current_size;
}
@@ -806,6 +805,17 @@ class Vector {
}
/**
+ * Remove all values for which the given predicate is true.
+ *
+ * This is similar to std::erase_if.
+ */
+ template<typename Predicate> void remove_if(Predicate &&predicate)
+ {
+ end_ = std::remove_if(this->begin(), this->end(), predicate);
+ UPDATE_VECTOR_SIZE(this);
+ }
+
+ /**
* Do a linear search to find the value in the vector.
* When found, return the first index, otherwise return -1.
*/
@@ -813,7 +823,7 @@ class Vector {
{
for (const T *current = begin_; current != end_; current++) {
if (*current == value) {
- return static_cast<int64_t>(current - begin_);
+ return int64_t(current - begin_);
}
}
return -1;
@@ -905,7 +915,7 @@ class Vector {
*/
int64_t capacity() const
{
- return static_cast<int64_t>(capacity_end_ - begin_);
+ return int64_t(capacity_end_ - begin_);
}
/**
@@ -975,7 +985,7 @@ class Vector {
const int64_t size = this->size();
T *new_array = static_cast<T *>(
- allocator_.allocate(static_cast<size_t>(new_capacity) * sizeof(T), alignof(T), AT));
+ allocator_.allocate(size_t(new_capacity) * sizeof(T), alignof(T), AT));
try {
uninitialized_relocate_n(begin_, size, new_array);
}
diff --git a/source/blender/blenlib/BLI_vector_adaptor.hh b/source/blender/blenlib/BLI_vector_adaptor.hh
deleted file mode 100644
index 82d731aacd8..00000000000
--- a/source/blender/blenlib/BLI_vector_adaptor.hh
+++ /dev/null
@@ -1,88 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#pragma once
-
-/** \file
- * \ingroup bli
- *
- * A `blender::VectorAdaptor` is a container with a fixed maximum size and does not own the
- * underlying memory. When an adaptor is constructed, you have to provide it with an uninitialized
- * array that will be filled when elements are added to the vector. The vector adaptor is not able
- * to grow. Therefore, it is undefined behavior to add more elements than fit into the provided
- * buffer.
- */
-
-#include "BLI_span.hh"
-
-namespace blender {
-
-template<typename T> class VectorAdaptor {
- private:
- T *begin_;
- T *end_;
- T *capacity_end_;
-
- public:
- VectorAdaptor() : begin_(nullptr), end_(nullptr), capacity_end_(nullptr)
- {
- }
-
- VectorAdaptor(T *data, int64_t capacity, int64_t size = 0)
- : begin_(data), end_(data + size), capacity_end_(data + capacity)
- {
- }
-
- VectorAdaptor(MutableSpan<T> span) : VectorAdaptor(span.data(), span.size(), 0)
- {
- }
-
- void append(const T &value)
- {
- BLI_assert(end_ < capacity_end_);
- new (end_) T(value);
- end_++;
- }
-
- void append(T &&value)
- {
- BLI_assert(end_ < capacity_end_);
- new (end_) T(std::move(value));
- end_++;
- }
-
- void append_n_times(const T &value, int64_t n)
- {
- BLI_assert(end_ + n <= capacity_end_);
- uninitialized_fill_n(end_, n, value);
- end_ += n;
- }
-
- void extend(Span<T> values)
- {
- BLI_assert(end_ + values.size() <= capacity_end_);
- uninitialized_copy_n(values.data(), values.size(), end_);
- end_ += values.size();
- }
-
- int64_t capacity() const
- {
- return capacity_end_ - begin_;
- }
-
- int64_t size() const
- {
- return end_ - begin_;
- }
-
- bool is_empty() const
- {
- return begin_ == end_;
- }
-
- bool is_full() const
- {
- return end_ == capacity_end_;
- }
-};
-
-} // namespace blender
diff --git a/source/blender/blenlib/BLI_vector_set.hh b/source/blender/blenlib/BLI_vector_set.hh
index b0a3696f245..d182e1f1678 100644
--- a/source/blender/blenlib/BLI_vector_set.hh
+++ b/source/blender/blenlib/BLI_vector_set.hh
@@ -349,6 +349,25 @@ class VectorSet {
}
/**
+ * Remove all values for which the given predicate is true. This may change the order of elements
+ * in the vector.
+ *
+ * This is similar to std::erase_if.
+ */
+ template<typename Predicate> void remove_if(Predicate &&predicate)
+ {
+ for (Slot &slot : slots_) {
+ if (slot.is_occupied()) {
+ const int64_t index = slot.index();
+ const Key &key = keys_[index];
+ if (predicate(key)) {
+ this->remove_key_internal(slot);
+ }
+ }
+ }
+ }
+
+ /**
* Delete and return a key from the set. This will remove the last element in the vector. The
* order of the remaining elements in the set is not changed.
*/
@@ -358,7 +377,7 @@ class VectorSet {
}
/**
- * Return the location of the key in the vector. It is assumed, that the key is in the vector
+ * Return the location of the key in the vector. It is assumed that the key is in the vector
* set. If this is not necessarily the case, use `index_of_try`.
*/
int64_t index_of(const Key &key) const
@@ -513,7 +532,7 @@ class VectorSet {
*/
int64_t size_in_bytes() const
{
- return static_cast<int64_t>(sizeof(Slot) * slots_.size() + sizeof(Key) * usable_slots_);
+ return int64_t(sizeof(Slot) * slots_.size() + sizeof(Key) * usable_slots_);
}
/**
@@ -557,7 +576,7 @@ class VectorSet {
max_load_factor_.compute_total_and_usable_slots(
SlotArray::inline_buffer_capacity(), min_usable_slots, &total_slots, &usable_slots);
BLI_assert(total_slots >= 1);
- const uint64_t new_slot_mask = static_cast<uint64_t>(total_slots) - 1;
+ const uint64_t new_slot_mask = uint64_t(total_slots) - 1;
/* Optimize the case when the set was empty beforehand. We can avoid some copies here. */
if (this->size() == 0) {
@@ -839,7 +858,7 @@ class VectorSet {
Key *allocate_keys_array(const int64_t size)
{
return static_cast<Key *>(
- slots_.allocator().allocate(sizeof(Key) * static_cast<size_t>(size), alignof(Key), AT));
+ slots_.allocator().allocate(sizeof(Key) * size_t(size), alignof(Key), AT));
}
void deallocate_keys_array(Key *keys)
diff --git a/source/blender/blenlib/BLI_vector_set_slots.hh b/source/blender/blenlib/BLI_vector_set_slots.hh
index 35dedd57705..cc7f5d1ff1e 100644
--- a/source/blender/blenlib/BLI_vector_set_slots.hh
+++ b/source/blender/blenlib/BLI_vector_set_slots.hh
@@ -73,7 +73,7 @@ template<typename Key> class SimpleVectorSetSlot {
template<typename ForwardKey, typename IsEqual>
bool contains(const ForwardKey &key,
const IsEqual &is_equal,
- uint64_t UNUSED(hash),
+ uint64_t /*hash*/,
const Key *keys) const
{
if (state_ >= 0) {
@@ -86,7 +86,7 @@ template<typename Key> class SimpleVectorSetSlot {
* Change the state of this slot from empty/removed to occupied. The hash can be used by other
* slot implementations.
*/
- void occupy(int64_t index, uint64_t UNUSED(hash))
+ void occupy(int64_t index, uint64_t /*hash*/)
{
BLI_assert(!this->is_occupied());
state_ = index;
diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh
index 438fcc4b8f7..36f5065c022 100644
--- a/source/blender/blenlib/BLI_virtual_array.hh
+++ b/source/blender/blenlib/BLI_virtual_array.hh
@@ -23,6 +23,8 @@
* see of the increased compile time and binary size is worth it.
*/
+#include <optional>
+
#include "BLI_any.hh"
#include "BLI_array.hh"
#include "BLI_index_mask.hh"
@@ -106,25 +108,7 @@ template<typename T> class VArrayImpl {
*/
virtual void materialize(IndexMask mask, MutableSpan<T> r_span) const
{
- T *dst = r_span.data();
- /* Optimize for a few different common cases. */
- const CommonVArrayInfo info = this->common_info();
- switch (info.type) {
- case CommonVArrayInfo::Type::Any: {
- mask.foreach_index([&](const int64_t i) { dst[i] = this->get(i); });
- break;
- }
- case CommonVArrayInfo::Type::Span: {
- const T *src = static_cast<const T *>(info.data);
- mask.foreach_index([&](const int64_t i) { dst[i] = src[i]; });
- break;
- }
- case CommonVArrayInfo::Type::Single: {
- const T single = *static_cast<const T *>(info.data);
- mask.foreach_index([&](const int64_t i) { dst[i] = single; });
- break;
- }
- }
+ mask.foreach_index([&](const int64_t i) { r_span[i] = this->get(i); });
}
/**
@@ -133,24 +117,7 @@ template<typename T> class VArrayImpl {
virtual void materialize_to_uninitialized(IndexMask mask, MutableSpan<T> r_span) const
{
T *dst = r_span.data();
- /* Optimize for a few different common cases. */
- const CommonVArrayInfo info = this->common_info();
- switch (info.type) {
- case CommonVArrayInfo::Type::Any: {
- mask.foreach_index([&](const int64_t i) { new (dst + i) T(this->get(i)); });
- break;
- }
- case CommonVArrayInfo::Type::Span: {
- const T *src = static_cast<const T *>(info.data);
- mask.foreach_index([&](const int64_t i) { new (dst + i) T(src[i]); });
- break;
- }
- case CommonVArrayInfo::Type::Single: {
- const T single = *static_cast<const T *>(info.data);
- mask.foreach_index([&](const int64_t i) { new (dst + i) T(single); });
- break;
- }
- }
+ mask.foreach_index([&](const int64_t i) { new (dst + i) T(this->get(i)); });
}
/**
@@ -188,7 +155,7 @@ template<typename T> class VArrayImpl {
* arrays in all cases.
* Return true when the virtual array was assigned and false when nothing was done.
*/
- virtual bool try_assign_GVArray(GVArray &UNUSED(varray)) const
+ virtual bool try_assign_GVArray(GVArray & /*varray*/) const
{
return false;
}
@@ -197,7 +164,7 @@ template<typename T> class VArrayImpl {
* Return true when the other virtual array should be considered to be the same, e.g. because it
* shares the same underlying memory.
*/
- virtual bool is_same(const VArrayImpl<T> &UNUSED(other)) const
+ virtual bool is_same(const VArrayImpl<T> & /*other*/) const
{
return false;
}
@@ -234,7 +201,7 @@ template<typename T> class VMutableArrayImpl : public VArrayImpl<T> {
/**
* Similar to #VArrayImpl::try_assign_GVArray but for mutable virtual arrays.
*/
- virtual bool try_assign_GVMutableArray(GVMutableArray &UNUSED(varray)) const
+ virtual bool try_assign_GVMutableArray(GVMutableArray & /*varray*/) const
{
return false;
}
@@ -286,8 +253,20 @@ template<typename T> class VArrayImpl_For_Span : public VMutableArrayImpl<T> {
return data_ == static_cast<const T *>(other_info.data);
}
+ void materialize(IndexMask mask, MutableSpan<T> r_span) const override
+ {
+ mask.foreach_index([&](const int64_t i) { r_span[i] = data_[i]; });
+ }
+
+ void materialize_to_uninitialized(IndexMask mask, MutableSpan<T> r_span) const override
+ {
+ T *dst = r_span.data();
+ mask.foreach_index([&](const int64_t i) { new (dst + i) T(data_[i]); });
+ }
+
void materialize_compressed(IndexMask mask, MutableSpan<T> r_span) const override
{
+ BLI_assert(mask.size() == r_span.size());
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
r_span[i] = data_[best_mask[i]];
@@ -298,6 +277,7 @@ template<typename T> class VArrayImpl_For_Span : public VMutableArrayImpl<T> {
void materialize_compressed_to_uninitialized(IndexMask mask,
MutableSpan<T> r_span) const override
{
+ BLI_assert(mask.size() == r_span.size());
T *dst = r_span.data();
mask.to_best_mask_type([&](auto best_mask) {
for (const int64_t i : IndexRange(best_mask.size())) {
@@ -315,6 +295,12 @@ template<typename T> class VArrayImpl_For_Span_final final : public VArrayImpl_F
public:
using VArrayImpl_For_Span<T>::VArrayImpl_For_Span;
+ VArrayImpl_For_Span_final(const Span<T> data)
+ /* Cast const away, because the implementation for const and non const spans is shared. */
+ : VArrayImpl_For_Span<T>({const_cast<T *>(data.data()), data.size()})
+ {
+ }
+
private:
CommonVArrayInfo common_info() const final
{
@@ -338,7 +324,7 @@ class VArrayImpl_For_ArrayContainer : public VArrayImpl_For_Span<T> {
public:
VArrayImpl_For_ArrayContainer(Container container)
- : VArrayImpl_For_Span<T>((int64_t)container.size()), container_(std::move(container))
+ : VArrayImpl_For_Span<T>(int64_t(container.size())), container_(std::move(container))
{
this->data_ = const_cast<T *>(container_.data());
}
@@ -360,7 +346,7 @@ template<typename T> class VArrayImpl_For_Single final : public VArrayImpl<T> {
}
protected:
- T get(const int64_t UNUSED(index)) const override
+ T get(const int64_t /*index*/) const override
{
return value_;
}
@@ -370,6 +356,17 @@ template<typename T> class VArrayImpl_For_Single final : public VArrayImpl<T> {
return CommonVArrayInfo(CommonVArrayInfo::Type::Single, true, &value_);
}
+ void materialize(IndexMask mask, MutableSpan<T> r_span) const override
+ {
+ r_span.fill_indices(mask, value_);
+ }
+
+ void materialize_to_uninitialized(IndexMask mask, MutableSpan<T> r_span) const override
+ {
+ T *dst = r_span.data();
+ mask.foreach_index([&](const int64_t i) { new (dst + i) T(value_); });
+ }
+
void materialize_compressed(IndexMask mask, MutableSpan<T> r_span) const override
{
BLI_assert(mask.size() == r_span.size());
@@ -797,6 +794,18 @@ template<typename T> class VArrayCommon {
}
/**
+ * Return the value that is returned for every index, if the array is stored as a single value.
+ */
+ std::optional<T> get_if_single() const
+ {
+ const CommonVArrayInfo info = impl_->common_info();
+ if (info.type != CommonVArrayInfo::Type::Single) {
+ return std::nullopt;
+ }
+ return *static_cast<const T *>(info.data);
+ }
+
+ /**
* Return true when the other virtual references the same underlying memory.
*/
bool is_same(const VArrayCommon<T> &other) const
@@ -898,10 +907,7 @@ template<typename T> class VArray : public VArrayCommon<T> {
VArray(varray_tag::span /* tag */, Span<T> span)
{
- /* Cast const away, because the virtual array implementation for const and non const spans is
- * shared. */
- MutableSpan<T> mutable_span{const_cast<T *>(span.data()), span.size()};
- this->template emplace<VArrayImpl_For_Span_final<T>>(mutable_span);
+ this->template emplace<VArrayImpl_For_Span_final<T>>(span);
}
VArray(varray_tag::single /* tag */, T value, const int64_t size)
diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h
index 7201e1bb4a1..34f1b1a68f1 100644
--- a/source/blender/blenlib/BLI_winstuff.h
+++ b/source/blender/blenlib/BLI_winstuff.h
@@ -48,11 +48,6 @@ extern "C" {
# define S_ISDIR(x) (((x)&_S_IFDIR) == _S_IFDIR)
#endif
-/* Defines for using ISO C++ conferment names. */
-#if !defined(_MSC_VER) || _MSC_VER < 1900
-# define snprintf _snprintf
-#endif
-
#if defined(_MSC_VER)
# define R_OK 4
# define W_OK 2
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index d39a586206f..2ac77f000e9 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -1,8 +1,13 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright 2006 Blender Foundation. All rights reserved.
+if(HAVE_EXECINFO_H)
+ add_definitions(-DHAVE_EXECINFO_H)
+endif()
+
set(INC
.
+ ..
# ../blenkernel # don't add this back!
../makesdna
../../../intern/atomic
@@ -19,7 +24,6 @@ set(INC_SYS
)
set(SRC
- intern/BLI_args.c
intern/BLI_array.c
intern/BLI_assert.c
intern/BLI_color.cc
@@ -44,11 +48,13 @@ set(SRC
intern/array_store.c
intern/array_store_utils.c
intern/array_utils.c
+ intern/array_utils.cc
intern/astar.c
intern/bitmap.c
intern/bitmap_draw_2d.c
intern/boxpack_2d.c
intern/buffer.c
+ intern/compute_context.cc
intern/convexhull_2d.c
intern/cpp_type.cc
intern/delaunay_2d.cc
@@ -79,6 +85,7 @@ set(SRC
intern/kdtree_3d.c
intern/kdtree_4d.c
intern/lasso_2d.c
+ intern/lazy_threading.cc
intern/length_parameterize.cc
intern/listbase.c
intern/math_base.c
@@ -155,15 +162,16 @@ set(SRC
BLI_alloca.h
BLI_allocator.hh
BLI_any.hh
- BLI_args.h
BLI_array.h
BLI_array.hh
BLI_array_store.h
BLI_array_store_utils.h
BLI_array_utils.h
+ BLI_array_utils.hh
BLI_asan.h
BLI_assert.h
BLI_astar.h
+ BLI_bit_vector.hh
BLI_bitmap.h
BLI_bitmap_draw_2d.h
BLI_blenlib.h
@@ -175,6 +183,7 @@ set(SRC
BLI_compiler_attrs.h
BLI_compiler_compat.h
BLI_compiler_typecheck.h
+ BLI_compute_context.hh
BLI_console.h
BLI_convexhull_2d.h
BLI_cpp_type.hh
@@ -230,6 +239,7 @@ set(SRC
BLI_kdtree.h
BLI_kdtree_impl.h
BLI_lasso_2d.h
+ BLI_lazy_threading.hh
BLI_length_parameterize.hh
BLI_linear_allocator.hh
BLI_link_utils.h
@@ -279,6 +289,7 @@ set(SRC
BLI_path_util.h
BLI_polyfill_2d.h
BLI_polyfill_2d_beautify.h
+ BLI_pool.hh
BLI_probing_strategies.hh
BLI_quadric.h
BLI_rand.h
@@ -323,7 +334,6 @@ set(SRC
BLI_uuid.h
BLI_uvproject.h
BLI_vector.hh
- BLI_vector_adaptor.hh
BLI_vector_set.hh
BLI_vector_set_slots.hh
BLI_virtual_array.hh
@@ -347,6 +357,14 @@ set(LIB
${ZSTD_LIBRARIES}
)
+if(NOT WITH_PYTHON_MODULE)
+ list(APPEND SRC
+ intern/BLI_args.c
+
+ BLI_args.h
+ )
+endif()
+
if(WITH_MEM_VALGRIND)
add_definitions(-DWITH_MEM_VALGRIND)
endif()
@@ -424,6 +442,7 @@ if(WITH_GTESTS)
tests/BLI_array_store_test.cc
tests/BLI_array_test.cc
tests/BLI_array_utils_test.cc
+ tests/BLI_bit_vector_test.cc
tests/BLI_bitmap_test.cc
tests/BLI_bounds_test.cc
tests/BLI_color_test.cc
@@ -470,6 +489,7 @@ if(WITH_GTESTS)
tests/BLI_multi_value_map_test.cc
tests/BLI_path_util_test.cc
tests/BLI_polyfill_2d_test.cc
+ tests/BLI_pool_test.cc
tests/BLI_ressource_strings.h
tests/BLI_serialize_test.cc
tests/BLI_session_uuid_test.cc
diff --git a/source/blender/blenlib/intern/BLI_args.c b/source/blender/blenlib/intern/BLI_args.c
index 61447ab1a9e..ceb7f7f0aba 100644
--- a/source/blender/blenlib/intern/BLI_args.c
+++ b/source/blender/blenlib/intern/BLI_args.c
@@ -57,7 +57,7 @@ static uint case_strhash(const void *ptr)
{
const char *s = ptr;
uint i = 0;
- unsigned char c;
+ uchar c;
while ((c = tolower(*s++))) {
i = i * 37 + c;
@@ -80,7 +80,7 @@ static bool keycmp(const void *a, const void *b)
if (ka->case_str == 1 || kb->case_str == 1) {
return (BLI_strcasecmp(ka->arg, kb->arg) != 0);
}
- return (!STREQ(ka->arg, kb->arg));
+ return !STREQ(ka->arg, kb->arg);
}
return BLI_ghashutil_intcmp((const void *)ka->pass, (const void *)kb->pass);
}
diff --git a/source/blender/blenlib/intern/BLI_filelist.c b/source/blender/blenlib/intern/BLI_filelist.c
index c6178ebb3a0..4bcb023691a 100644
--- a/source/blender/blenlib/intern/BLI_filelist.c
+++ b/source/blender/blenlib/intern/BLI_filelist.c
@@ -93,7 +93,7 @@ static int bli_compare(struct direntry *entry1, struct direntry *entry2)
return 1;
}
- return (BLI_strcasecmp_natural(entry1->relname, entry2->relname));
+ return BLI_strcasecmp_natural(entry1->relname, entry2->relname);
}
struct BuildDirCtx {
@@ -174,10 +174,10 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname)
struct direntry *file = &dir_ctx->files[dir_ctx->files_num];
while (dlink) {
char fullname[PATH_MAX];
+ BLI_path_join(fullname, sizeof(fullname), dirname, dlink->name);
memset(file, 0, sizeof(struct direntry));
file->relname = dlink->name;
- file->path = BLI_strdupcat(dirname, dlink->name);
- BLI_join_dirfile(fullname, sizeof(fullname), dirname, dlink->name);
+ file->path = BLI_strdup(fullname);
if (BLI_stat(fullname, &file->s) != -1) {
file->type = file->s.st_mode;
}
@@ -215,7 +215,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname)
}
}
-unsigned int BLI_filelist_dir_contents(const char *dirname, struct direntry **r_filelist)
+uint BLI_filelist_dir_contents(const char *dirname, struct direntry **r_filelist)
{
struct BuildDirCtx dir_ctx;
@@ -395,9 +395,9 @@ void BLI_filelist_entry_duplicate(struct direntry *dst, const struct direntry *s
void BLI_filelist_duplicate(struct direntry **dest_filelist,
struct direntry *const src_filelist,
- const unsigned int nrentries)
+ const uint nrentries)
{
- unsigned int i;
+ uint i;
*dest_filelist = MEM_mallocN(sizeof(**dest_filelist) * (size_t)(nrentries), __func__);
for (i = 0; i < nrentries; i++) {
@@ -417,9 +417,9 @@ void BLI_filelist_entry_free(struct direntry *entry)
}
}
-void BLI_filelist_free(struct direntry *filelist, const unsigned int nrentries)
+void BLI_filelist_free(struct direntry *filelist, const uint nrentries)
{
- unsigned int i;
+ uint i;
for (i = 0; i < nrentries; i++) {
BLI_filelist_entry_free(&filelist[i]);
}
diff --git a/source/blender/blenlib/intern/BLI_ghash_utils.c b/source/blender/blenlib/intern/BLI_ghash_utils.c
index e12e272832f..806d58df260 100644
--- a/source/blender/blenlib/intern/BLI_ghash_utils.c
+++ b/source/blender/blenlib/intern/BLI_ghash_utils.c
@@ -63,7 +63,7 @@ uint BLI_ghashutil_uinthash_v4(const uint key[4])
uint BLI_ghashutil_uinthash_v4_murmur(const uint key[4])
{
- return BLI_hash_mm2((const unsigned char *)key, sizeof(int[4]) /* sizeof(key) */, 0);
+ return BLI_hash_mm2((const uchar *)key, sizeof(int[4]) /* sizeof(key) */, 0);
}
bool BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b)
@@ -101,7 +101,7 @@ uint BLI_ghashutil_inthash_p_murmur(const void *ptr)
{
uintptr_t key = (uintptr_t)ptr;
- return BLI_hash_mm2((const unsigned char *)&key, sizeof(key), 0);
+ return BLI_hash_mm2((const uchar *)&key, sizeof(key), 0);
}
uint BLI_ghashutil_inthash_p_simple(const void *ptr)
@@ -143,7 +143,7 @@ uint BLI_ghashutil_strhash_p(const void *ptr)
}
uint BLI_ghashutil_strhash_p_murmur(const void *ptr)
{
- const unsigned char *key = ptr;
+ const uchar *key = ptr;
return BLI_hash_mm2(key, strlen((const char *)key) + 1, 0);
}
diff --git a/source/blender/blenlib/intern/BLI_index_range.cc b/source/blender/blenlib/intern/BLI_index_range.cc
index 398228ab461..624dcc39fc5 100644
--- a/source/blender/blenlib/intern/BLI_index_range.cc
+++ b/source/blender/blenlib/intern/BLI_index_range.cc
@@ -44,4 +44,34 @@ Span<int64_t> IndexRange::as_span_internal() const
return Span<int64_t>(s_current_array + start_, size_);
}
+AlignedIndexRanges split_index_range_by_alignment(const IndexRange range, const int64_t alignment)
+{
+ BLI_assert(is_power_of_2_i(alignment));
+ const int64_t mask = alignment - 1;
+
+ AlignedIndexRanges aligned_ranges;
+
+ const int64_t start_chunk = range.start() & ~mask;
+ const int64_t end_chunk = range.one_after_last() & ~mask;
+ if (start_chunk == end_chunk) {
+ aligned_ranges.prefix = range;
+ }
+ else {
+ int64_t prefix_size = 0;
+ int64_t suffix_size = 0;
+ if (range.start() != start_chunk) {
+ prefix_size = alignment - (range.start() & mask);
+ }
+ if (range.one_after_last() != end_chunk) {
+ suffix_size = range.one_after_last() - end_chunk;
+ }
+ aligned_ranges.prefix = IndexRange(range.start(), prefix_size);
+ aligned_ranges.suffix = IndexRange(end_chunk, suffix_size);
+ aligned_ranges.aligned = IndexRange(aligned_ranges.prefix.one_after_last(),
+ range.size() - prefix_size - suffix_size);
+ }
+
+ return aligned_ranges;
+}
+
} // namespace blender
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index 62bf17bd415..de71147f015 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -58,7 +58,7 @@
/** \name Struct Definitions
* \{ */
-typedef unsigned char axis_t;
+typedef uchar axis_t;
typedef struct BVHNode {
struct BVHNode **children;
@@ -386,12 +386,12 @@ static void refit_kdop_hull(const BVHTree *tree, BVHNode *node, int start, int e
/* for all Axes. */
for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
newmin = node_bv[(2 * axis_iter)];
- if ((newmin < bv[(2 * axis_iter)])) {
+ if (newmin < bv[(2 * axis_iter)]) {
bv[(2 * axis_iter)] = newmin;
}
newmax = node_bv[(2 * axis_iter) + 1];
- if ((newmax > bv[(2 * axis_iter) + 1])) {
+ if (newmax > bv[(2 * axis_iter) + 1]) {
bv[(2 * axis_iter) + 1] = newmax;
}
}
@@ -1385,7 +1385,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap(
static bool tree_intersect_plane_test(const float *bv, const float plane[4])
{
- /* TODO(germano): Support other KDOP geometries. */
+ /* TODO(@germano): Support other KDOP geometries. */
const float bb_min[3] = {bv[0], bv[2], bv[4]};
const float bb_max[3] = {bv[1], bv[3], bv[5]};
float bb_near[3], bb_far[3];
diff --git a/source/blender/blenlib/intern/BLI_memarena.c b/source/blender/blenlib/intern/BLI_memarena.c
index 3b73a81012d..3c353a1c8c8 100644
--- a/source/blender/blenlib/intern/BLI_memarena.c
+++ b/source/blender/blenlib/intern/BLI_memarena.c
@@ -38,7 +38,7 @@ struct MemBuf {
};
struct MemArena {
- unsigned char *curbuf;
+ uchar *curbuf;
const char *name;
struct MemBuf *bufs;
@@ -53,7 +53,7 @@ static void memarena_buf_free_all(struct MemBuf *mb)
while (mb != NULL) {
struct MemBuf *mb_next = mb->next;
- /* Unpoison memory because MEM_freeN might overwrite it. */
+ /* Unpoison memory because #MEM_freeN might overwrite it. */
BLI_asan_unpoison(mb, (uint)MEM_allocN_len(mb));
MEM_freeN(mb);
@@ -106,9 +106,9 @@ void BLI_memarena_free(MemArena *ma)
/** Align alloc'ed memory (needed if `align > 8`). */
static void memarena_curbuf_align(MemArena *ma)
{
- unsigned char *tmp;
+ uchar *tmp;
- tmp = (unsigned char *)PADUP((intptr_t)ma->curbuf, (int)ma->align);
+ tmp = (uchar *)PADUP((intptr_t)ma->curbuf, (int)ma->align);
ma->cursize -= (size_t)(tmp - ma->curbuf);
ma->curbuf = tmp;
}
@@ -158,6 +158,7 @@ void *BLI_memarena_calloc(MemArena *ma, size_t size)
BLI_assert(ma->use_calloc == false);
ptr = BLI_memarena_alloc(ma, size);
+ BLI_assert(ptr != NULL);
memset(ptr, 0, size);
return ptr;
@@ -208,7 +209,7 @@ void BLI_memarena_merge(MemArena *ma_dst, MemArena *ma_src)
void BLI_memarena_clear(MemArena *ma)
{
if (ma->bufs) {
- unsigned char *curbuf_prev;
+ uchar *curbuf_prev;
size_t curbuf_used;
if (ma->bufs->next) {
diff --git a/source/blender/blenlib/intern/BLI_memblock.c b/source/blender/blenlib/intern/BLI_memblock.c
index f780d520301..b03efd2b8a2 100644
--- a/source/blender/blenlib/intern/BLI_memblock.c
+++ b/source/blender/blenlib/intern/BLI_memblock.c
@@ -5,7 +5,6 @@
* \ingroup bli
*
* Dead simple, fast memory allocator for allocating many elements of the same size.
- *
*/
#include <stdlib.h>
diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c
index 9a8bda48c8d..65518427656 100644
--- a/source/blender/blenlib/intern/array_store.c
+++ b/source/blender/blenlib/intern/array_store.c
@@ -736,17 +736,17 @@ static void bchunk_list_fill_from_array(const BArrayInfo *info,
BLI_INLINE uint hash_data_single(const uchar p)
{
- return ((HASH_INIT << 5) + HASH_INIT) + (unsigned int)(*((signed char *)&p));
+ return ((HASH_INIT << 5) + HASH_INIT) + (uint)(*((signed char *)&p));
}
/* hash bytes, from BLI_ghashutil_strhash_n */
static uint hash_data(const uchar *key, size_t n)
{
const signed char *p;
- unsigned int h = HASH_INIT;
+ uint h = HASH_INIT;
for (p = (const signed char *)key; n--; p++) {
- h = ((h << 5) + h) + (unsigned int)*p;
+ h = (uint)((h << 5) + h) + (uint)*p;
}
return h;
@@ -805,7 +805,7 @@ static void hash_array_from_cref(const BArrayInfo *info,
static void hash_accum(hash_key *hash_array, const size_t hash_array_len, size_t iter_steps)
{
/* _very_ unlikely, can happen if you select a chunk-size of 1 for example. */
- if (UNLIKELY((iter_steps > hash_array_len))) {
+ if (UNLIKELY(iter_steps > hash_array_len)) {
iter_steps = hash_array_len;
}
@@ -1403,7 +1403,7 @@ BArrayStore *BLI_array_store_create(uint stride, uint chunk_count)
/* Triangle number, identifying now much read-ahead we need:
* https://en.wikipedia.org/wiki/Triangular_number (+ 1) */
bs->info.accum_read_ahead_len =
- (uint)((((bs->info.accum_steps * (bs->info.accum_steps + 1))) / 2) + 1);
+ (uint)(((bs->info.accum_steps * (bs->info.accum_steps + 1)) / 2) + 1);
bs->info.accum_read_ahead_bytes = bs->info.accum_read_ahead_len * stride;
#else
bs->info.accum_read_ahead_bytes = BCHUNK_HASH_LEN * stride;
diff --git a/source/blender/blenlib/intern/array_store_utils.c b/source/blender/blenlib/intern/array_store_utils.c
index 9ac8630204a..51b5ce0519f 100644
--- a/source/blender/blenlib/intern/array_store_utils.c
+++ b/source/blender/blenlib/intern/array_store_utils.c
@@ -27,9 +27,9 @@ BArrayStore *BLI_array_store_at_size_ensure(struct BArrayStore_AtSize *bs_stride
if ((*bs_p) == NULL) {
/* calculate best chunk-count to fit a power of two */
- unsigned int chunk_count = chunk_size;
+ uint chunk_count = chunk_size;
{
- unsigned int size = chunk_count * stride;
+ uint size = chunk_count * stride;
size = power_of_2_max_u(size);
size = MEM_SIZE_OPTIMAL(size);
chunk_count = size / stride;
diff --git a/source/blender/blenlib/intern/array_utils.cc b/source/blender/blenlib/intern/array_utils.cc
new file mode 100644
index 00000000000..2a231228dcb
--- /dev/null
+++ b/source/blender/blenlib/intern/array_utils.cc
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BLI_array_utils.hh"
+
+namespace blender::array_utils {
+
+void copy(const GVArray &src,
+ const IndexMask selection,
+ GMutableSpan dst,
+ const int64_t grain_size)
+{
+ BLI_assert(src.type() == dst.type());
+ BLI_assert(src.size() == dst.size());
+ threading::parallel_for(selection.index_range(), grain_size, [&](const IndexRange range) {
+ src.materialize_to_uninitialized(selection.slice(range), dst.data());
+ });
+}
+
+void gather(const GVArray &src,
+ const IndexMask indices,
+ GMutableSpan dst,
+ const int64_t grain_size)
+{
+ BLI_assert(src.type() == dst.type());
+ BLI_assert(indices.size() == dst.size());
+ threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) {
+ src.materialize_compressed_to_uninitialized(indices.slice(range), dst.slice(range).data());
+ });
+}
+
+void gather(const GSpan src, const IndexMask indices, GMutableSpan dst, const int64_t grain_size)
+{
+ gather(GVArray::ForSpan(src), indices, dst, grain_size);
+}
+
+} // namespace blender::array_utils
diff --git a/source/blender/blenlib/intern/boxpack_2d.c b/source/blender/blenlib/intern/boxpack_2d.c
index 78f5088e8b1..309ae624305 100644
--- a/source/blender/blenlib/intern/boxpack_2d.c
+++ b/source/blender/blenlib/intern/boxpack_2d.c
@@ -491,7 +491,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const uint len, float *r_tot_x, float *r
* flag verts on one or both of the boxes
* as being used by checking the width or
* height of both boxes */
- if (vert->tlb && vert->trb && (ELEM(box, vert->tlb, vert->trb))) {
+ if (vert->tlb && vert->trb && ELEM(box, vert->tlb, vert->trb)) {
if (UNLIKELY(fabsf(vert->tlb->h - vert->trb->h) < EPSILON_MERGE)) {
#ifdef USE_MERGE
# define A (vert->trb->v[TL])
@@ -522,7 +522,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const uint len, float *r_tot_x, float *r
vert->tlb->v[TR]->free &= ~(TRF | BRF);
}
}
- else if (vert->blb && vert->brb && (ELEM(box, vert->blb, vert->brb))) {
+ else if (vert->blb && vert->brb && ELEM(box, vert->blb, vert->brb)) {
if (UNLIKELY(fabsf(vert->blb->h - vert->brb->h) < EPSILON_MERGE)) {
#ifdef USE_MERGE
# define A (vert->blb->v[BR])
@@ -554,7 +554,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const uint len, float *r_tot_x, float *r
}
}
/* Horizontal */
- if (vert->tlb && vert->blb && (ELEM(box, vert->tlb, vert->blb))) {
+ if (vert->tlb && vert->blb && ELEM(box, vert->tlb, vert->blb)) {
if (UNLIKELY(fabsf(vert->tlb->w - vert->blb->w) < EPSILON_MERGE)) {
#ifdef USE_MERGE
# define A (vert->blb->v[TL])
@@ -585,7 +585,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const uint len, float *r_tot_x, float *r
vert->tlb->v[BL]->free &= ~(BLF | BRF);
}
}
- else if (vert->trb && vert->brb && (ELEM(box, vert->trb, vert->brb))) {
+ else if (vert->trb && vert->brb && ELEM(box, vert->trb, vert->brb)) {
if (UNLIKELY(fabsf(vert->trb->w - vert->brb->w) < EPSILON_MERGE)) {
#ifdef USE_MERGE
@@ -712,7 +712,6 @@ void BLI_box_pack_2d_fixedarea(ListBase *boxes, int width, int height, ListBase
* # Box * Small # # Box * #
* # * # # * #
* ################### ###################
- *
*/
int area_hsplit_large = space->w * (space->h - box->h);
int area_vsplit_large = (space->w - box->w) * space->h;
diff --git a/source/blender/blenlib/intern/compute_context.cc b/source/blender/blenlib/intern/compute_context.cc
new file mode 100644
index 00000000000..50a4a90a4a9
--- /dev/null
+++ b/source/blender/blenlib/intern/compute_context.cc
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BLI_compute_context.hh"
+#include "BLI_hash_md5.h"
+
+namespace blender {
+
+void ComputeContextHash::mix_in(const void *data, int64_t len)
+{
+ DynamicStackBuffer<> buffer_owner(HashSizeInBytes + len, 8);
+ char *buffer = static_cast<char *>(buffer_owner.buffer());
+ memcpy(buffer, this, HashSizeInBytes);
+ memcpy(buffer + HashSizeInBytes, data, len);
+
+ BLI_hash_md5_buffer(buffer, HashSizeInBytes + len, this);
+}
+
+std::ostream &operator<<(std::ostream &stream, const ComputeContextHash &hash)
+{
+ std::stringstream ss;
+ ss << "0x" << std::hex << hash.v1 << hash.v2;
+ stream << ss.str();
+ return stream;
+}
+
+void ComputeContext::print_stack(std::ostream &stream, StringRef name) const
+{
+ Stack<const ComputeContext *> stack;
+ for (const ComputeContext *current = this; current; current = current->parent_) {
+ stack.push(current);
+ }
+ stream << "Context Stack: " << name << "\n";
+ while (!stack.is_empty()) {
+ const ComputeContext *current = stack.pop();
+ stream << "-> ";
+ current->print_current_in_line(stream);
+ const ComputeContextHash &current_hash = current->hash_;
+ stream << " \t(hash: " << current_hash << ")\n";
+ }
+}
+
+std::ostream &operator<<(std::ostream &stream, const ComputeContext &compute_context)
+{
+ compute_context.print_stack(stream, "");
+ return stream;
+}
+
+} // namespace blender
diff --git a/source/blender/blenlib/intern/convexhull_2d.c b/source/blender/blenlib/intern/convexhull_2d.c
index 33d1a68a76e..9e3fb230d3c 100644
--- a/source/blender/blenlib/intern/convexhull_2d.c
+++ b/source/blender/blenlib/intern/convexhull_2d.c
@@ -39,8 +39,9 @@ static float is_left(const float p0[2], const float p1[2], const float p2[2])
return (p1[0] - p0[0]) * (p2[1] - p0[1]) - (p2[0] - p0[0]) * (p1[1] - p0[1]);
}
-int BLI_convexhull_2d_sorted(const float (*points)[2], const int n, int r_points[])
+static int BLI_convexhull_2d_sorted(const float (*points)[2], const int n, int r_points[])
{
+ BLI_assert(n >= 2); /* Doesn't handle trivial cases. */
/* the output array r_points[] will be used as the stack */
int bot = 0;
int top = -1; /* indices for bottom and top of the stack */
@@ -66,6 +67,7 @@ int BLI_convexhull_2d_sorted(const float (*points)[2], const int n, int r_points
r_points[++top] = minmax;
}
r_points[++top] = minmin; /* add polygon endpoint */
+ BLI_assert(top + 1 <= n);
return top + 1;
}
@@ -122,16 +124,18 @@ int BLI_convexhull_2d_sorted(const float (*points)[2], const int n, int r_points
}
if (points[i][0] == points[r_points[0]][0] && points[i][1] == points[r_points[0]][1]) {
+ BLI_assert(top + 1 <= n);
return top + 1; /* special case (mgomes) */
}
r_points[++top] = i; /* push points[i] onto stack */
}
- if (minmax != minmin) {
+ if (minmax != minmin && r_points[0] != minmin) {
r_points[++top] = minmin; /* push joining endpoint onto stack */
}
+ BLI_assert(top + 1 <= n);
return top + 1;
}
@@ -162,35 +166,38 @@ static int pointref_cmp_yx(const void *a_, const void *b_)
int BLI_convexhull_2d(const float (*points)[2], const int n, int r_points[])
{
+ BLI_assert(n >= 0);
+ if (n < 2) {
+ if (n == 1) {
+ r_points[0] = 0;
+ }
+ return n;
+ }
struct PointRef *points_ref = MEM_mallocN(sizeof(*points_ref) * (size_t)n, __func__);
float(*points_sort)[2] = MEM_mallocN(sizeof(*points_sort) * (size_t)n, __func__);
- int *points_map;
- int points_hull_num, i;
- for (i = 0; i < n; i++) {
+ for (int i = 0; i < n; i++) {
points_ref[i].pt = points[i];
}
- /* Sort the points by X, then by Y (required by the algorithm) */
+ /* Sort the points by X, then by Y. */
qsort(points_ref, (size_t)n, sizeof(struct PointRef), pointref_cmp_yx);
- for (i = 0; i < n; i++) {
+ for (int i = 0; i < n; i++) {
memcpy(points_sort[i], points_ref[i].pt, sizeof(float[2]));
}
- points_hull_num = BLI_convexhull_2d_sorted(points_sort, n, r_points);
+ int points_hull_num = BLI_convexhull_2d_sorted(points_sort, n, r_points);
- /* map back to the original index values */
- points_map = (int *)points_sort; /* abuse float array for temp storage */
- for (i = 0; i < points_hull_num; i++) {
- points_map[i] = (int)((const float(*)[2])points_ref[r_points[i]].pt - points);
+ /* Map back to the unsorted index values. */
+ for (int i = 0; i < points_hull_num; i++) {
+ r_points[i] = (int)((const float(*)[2])points_ref[r_points[i]].pt - points);
}
- memcpy(r_points, points_map, (size_t)points_hull_num * sizeof(*points_map));
-
MEM_freeN(points_ref);
MEM_freeN(points_sort);
+ BLI_assert(points_hull_num <= n);
return points_hull_num;
}
@@ -202,14 +209,13 @@ int BLI_convexhull_2d(const float (*points)[2], const int n, int r_points[])
/** \name Utility Convex-Hull Functions
* \{ */
-float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned int n)
+static float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], int n)
{
- unsigned int i, i_prev;
float area_best = FLT_MAX;
float dvec_best[2]; /* best angle, delay atan2 */
- i_prev = n - 1;
- for (i = 0; i < n; i++) {
+ int i_prev = n - 1;
+ for (int i = 0; i < n; i++) {
const float *ev_a = points_hull[i];
const float *ev_b = points_hull[i_prev];
float dvec[2]; /* 2d rotation matrix */
@@ -218,10 +224,9 @@ float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned in
if (normalize_v2(dvec) != 0.0f) {
/* rotation matrix */
float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX};
- unsigned int j;
float area;
- for (j = 0; j < n; j++) {
+ for (int j = 0; j < n; j++) {
float tvec[2];
mul_v2_v2_cw(tvec, dvec, points_hull[j]);
@@ -249,32 +254,24 @@ float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned in
return (area_best != FLT_MAX) ? atan2f(dvec_best[0], dvec_best[1]) : 0.0f;
}
-float BLI_convexhull_aabb_fit_points_2d(const float (*points)[2], unsigned int n)
+float BLI_convexhull_aabb_fit_points_2d(const float (*points)[2], int n)
{
- int *index_map;
- int points_hull_num;
+ BLI_assert(n >= 0);
+ float angle = 0.0f;
- float angle;
+ int *index_map = MEM_mallocN(sizeof(*index_map) * (size_t)n, __func__);
- index_map = MEM_mallocN(sizeof(*index_map) * n * 2, __func__);
+ int points_hull_num = BLI_convexhull_2d(points, n, index_map);
- points_hull_num = BLI_convexhull_2d(points, (int)n, index_map);
-
- if (points_hull_num) {
- float(*points_hull)[2];
- int j;
-
- points_hull = MEM_mallocN(sizeof(*points_hull) * (size_t)points_hull_num, __func__);
- for (j = 0; j < points_hull_num; j++) {
+ if (points_hull_num > 1) {
+ float(*points_hull)[2] = MEM_mallocN(sizeof(*points_hull) * (size_t)points_hull_num, __func__);
+ for (int j = 0; j < points_hull_num; j++) {
copy_v2_v2(points_hull[j], points[index_map[j]]);
}
- angle = BLI_convexhull_aabb_fit_hull_2d(points_hull, (unsigned int)points_hull_num);
+ angle = BLI_convexhull_aabb_fit_hull_2d(points_hull, points_hull_num);
MEM_freeN(points_hull);
}
- else {
- angle = 0.0f;
- }
MEM_freeN(index_map);
diff --git a/source/blender/blenlib/intern/cpp_type.cc b/source/blender/blenlib/intern/cpp_type.cc
index d6a087cf175..38de32d3ec8 100644
--- a/source/blender/blenlib/intern/cpp_type.cc
+++ b/source/blender/blenlib/intern/cpp_type.cc
@@ -26,3 +26,4 @@ BLI_CPP_TYPE_MAKE(ColorGeometry4f, blender::ColorGeometry4f, CPPTypeFlags::Basic
BLI_CPP_TYPE_MAKE(ColorGeometry4b, blender::ColorGeometry4b, CPPTypeFlags::BasicType)
BLI_CPP_TYPE_MAKE(string, std::string, CPPTypeFlags::BasicType)
+BLI_CPP_TYPE_MAKE(StringVector, blender::Vector<std::string>, CPPTypeFlags::None)
diff --git a/source/blender/blenlib/intern/delaunay_2d.cc b/source/blender/blenlib/intern/delaunay_2d.cc
index db6cb0824dc..afecf9ea838 100644
--- a/source/blender/blenlib/intern/delaunay_2d.cc
+++ b/source/blender/blenlib/intern/delaunay_2d.cc
@@ -45,7 +45,7 @@ template<> double math_abs<double>(const double v)
return fabs(v);
}
-template<typename T> double math_to_double(const T UNUSED(v))
+template<typename T> double math_to_double(const T /*v*/)
{
BLI_assert(false); /* Need implementation for other type. */
return 0.0;
@@ -520,10 +520,10 @@ template<typename T> void cdt_draw(const std::string &label, const CDTArrangemen
double height = maxy - miny;
double aspect = height / width;
int view_width = max_draw_width;
- int view_height = static_cast<int>(view_width * aspect);
+ int view_height = int(view_width * aspect);
if (view_height > max_draw_height) {
view_height = max_draw_height;
- view_width = static_cast<int>(view_height / aspect);
+ view_width = int(view_height / aspect);
}
double scale = view_width / width;
@@ -2645,7 +2645,7 @@ void prepare_cdt_for_output(CDT_state<T> *cdt_state, const CDT_output_type outpu
template<typename T>
CDT_result<T> get_cdt_output(CDT_state<T> *cdt_state,
- const CDT_input<T> UNUSED(input),
+ const CDT_input<T> /*input*/,
CDT_output_type output_type)
{
CDT_output_type oty = output_type;
@@ -2822,8 +2822,8 @@ extern "C" ::CDT_result *BLI_delaunay_2d_cdt_calc(const ::CDT_input *input,
in.edge = blender::Array<std::pair<int, int>>(input->edges_len);
in.face = blender::Array<blender::Vector<int>>(input->faces_len);
for (int v = 0; v < input->verts_len; ++v) {
- double x = static_cast<double>(input->vert_coords[v][0]);
- double y = static_cast<double>(input->vert_coords[v][1]);
+ double x = double(input->vert_coords[v][0]);
+ double y = double(input->vert_coords[v][1]);
in.vert[v] = blender::meshintersect::vec2<double>(x, y);
}
for (int e = 0; e < input->edges_len; ++e) {
@@ -2836,7 +2836,7 @@ extern "C" ::CDT_result *BLI_delaunay_2d_cdt_calc(const ::CDT_input *input,
in.face[f][j] = input->faces[fstart + j];
}
}
- in.epsilon = static_cast<double>(input->epsilon);
+ in.epsilon = double(input->epsilon);
in.need_ids = input->need_ids;
blender::meshintersect::CDT_result<double> res = blender::meshintersect::delaunay_2d_calc(
@@ -2903,8 +2903,8 @@ extern "C" ::CDT_result *BLI_delaunay_2d_cdt_calc(const ::CDT_input *input,
int v_orig_index = 0;
for (int v = 0; v < nv; ++v) {
- output->vert_coords[v][0] = static_cast<float>(res.vert[v][0]);
- output->vert_coords[v][1] = static_cast<float>(res.vert[v][1]);
+ output->vert_coords[v][0] = float(res.vert[v][0]);
+ output->vert_coords[v][1] = float(res.vert[v][1]);
if (input->need_ids) {
int this_start = v_orig_index;
output->verts_orig_start_table[v] = this_start;
diff --git a/source/blender/blenlib/intern/dot_export.cc b/source/blender/blenlib/intern/dot_export.cc
index 796fd6a934a..d577de9bc34 100644
--- a/source/blender/blenlib/intern/dot_export.cc
+++ b/source/blender/blenlib/intern/dot_export.cc
@@ -93,7 +93,7 @@ void Graph::set_random_cluster_bgcolors()
void Cluster::set_random_cluster_bgcolors()
{
- float hue = rand() / (float)RAND_MAX;
+ float hue = rand() / float(RAND_MAX);
float staturation = 0.3f;
float value = 0.8f;
this->attributes.set("bgcolor", color_attr_from_hsv(hue, staturation, value));
@@ -227,7 +227,7 @@ void Attributes::export__as_bracket_list(std::stringstream &ss) const
void Node::export__as_id(std::stringstream &ss) const
{
- ss << '"' << (uintptr_t)this << '"';
+ ss << '"' << uintptr_t(this) << '"';
}
void Node::export__as_declaration(std::stringstream &ss) const
diff --git a/source/blender/blenlib/intern/endian_switch.c b/source/blender/blenlib/intern/endian_switch.c
index 10d0bfb815b..c1a5b69fb23 100644
--- a/source/blender/blenlib/intern/endian_switch.c
+++ b/source/blender/blenlib/intern/endian_switch.c
@@ -18,7 +18,7 @@ void BLI_endian_switch_int16_array(short *val, const int size)
}
}
-void BLI_endian_switch_uint16_array(unsigned short *val, const int size)
+void BLI_endian_switch_uint16_array(ushort *val, const int size)
{
if (size > 0) {
int i = size;
@@ -38,7 +38,7 @@ void BLI_endian_switch_int32_array(int *val, const int size)
}
}
-void BLI_endian_switch_uint32_array(unsigned int *val, const int size)
+void BLI_endian_switch_uint32_array(uint *val, const int size)
{
if (size > 0) {
int i = size;
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index 3abd482d6b3..a157302e51e 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -627,7 +627,7 @@ static void join_dirfile_alloc(char **dst, size_t *alloc_len, const char *dir, c
*alloc_len = len;
- BLI_join_dirfile(*dst, len + 1, dir, file);
+ BLI_path_join(*dst, len + 1, dir, file);
}
static char *strip_last_slash(const char *dir)
@@ -1184,7 +1184,7 @@ static const char *check_destination(const char *file, const char *to)
len = strlen(to) + strlen(filename) + 1;
path = MEM_callocN(len + 1, "check_destination path");
- BLI_join_dirfile(path, len + 1, to, filename);
+ BLI_path_join(path, len + 1, to, filename);
MEM_freeN(str);
diff --git a/source/blender/blenlib/intern/generic_virtual_array.cc b/source/blender/blenlib/intern/generic_virtual_array.cc
index f66b1e14fc6..b0623175dc7 100644
--- a/source/blender/blenlib/intern/generic_virtual_array.cc
+++ b/source/blender/blenlib/intern/generic_virtual_array.cc
@@ -51,7 +51,7 @@ CommonVArrayInfo GVArrayImpl::common_info() const
return {};
}
-bool GVArrayImpl::try_assign_VArray(void *UNUSED(varray)) const
+bool GVArrayImpl::try_assign_VArray(void * /*varray*/) const
{
return false;
}
@@ -102,7 +102,7 @@ void GVMutableArray::fill(const void *value)
}
}
-bool GVMutableArrayImpl::try_assign_VMutableArray(void *UNUSED(varray)) const
+bool GVMutableArrayImpl::try_assign_VMutableArray(void * /*varray*/) const
{
return false;
}
@@ -172,11 +172,11 @@ void GVArrayImpl_For_GSpan::materialize_compressed_to_uninitialized(const IndexM
/* Generic virtual array where each element has the same value. The value is not owned. */
-void GVArrayImpl_For_SingleValueRef::get(const int64_t UNUSED(index), void *r_value) const
+void GVArrayImpl_For_SingleValueRef::get(const int64_t /*index*/, void *r_value) const
{
type_->copy_assign(value_, r_value);
}
-void GVArrayImpl_For_SingleValueRef::get_to_uninitialized(const int64_t UNUSED(index),
+void GVArrayImpl_For_SingleValueRef::get_to_uninitialized(const int64_t /*index*/,
void *r_value) const
{
type_->copy_construct(value_, r_value);
@@ -261,11 +261,11 @@ template<int BufferSize> class GVArrayImpl_For_SmallTrivialSingleValue : public
}
private:
- void get(const int64_t UNUSED(index), void *r_value) const override
+ void get(const int64_t /*index*/, void *r_value) const override
{
this->copy_value_to(r_value);
}
- void get_to_uninitialized(const int64_t UNUSED(index), void *r_value) const override
+ void get_to_uninitialized(const int64_t /*index*/, void *r_value) const override
{
this->copy_value_to(r_value);
}
diff --git a/source/blender/blenlib/intern/generic_virtual_vector_array.cc b/source/blender/blenlib/intern/generic_virtual_vector_array.cc
index 8fd1fb50b72..5d6985e16c8 100644
--- a/source/blender/blenlib/intern/generic_virtual_vector_array.cc
+++ b/source/blender/blenlib/intern/generic_virtual_vector_array.cc
@@ -16,12 +16,12 @@ void GVArray_For_GVVectorArrayIndex::get_to_uninitialized(const int64_t index_in
vector_array_.get_vector_element(index_, index_in_vector, r_value);
}
-int64_t GVVectorArray_For_SingleGVArray::get_vector_size_impl(const int64_t UNUSED(index)) const
+int64_t GVVectorArray_For_SingleGVArray::get_vector_size_impl(const int64_t /*index*/) const
{
return varray_.size();
}
-void GVVectorArray_For_SingleGVArray::get_vector_element_impl(const int64_t UNUSED(index),
+void GVVectorArray_For_SingleGVArray::get_vector_element_impl(const int64_t /*index*/,
const int64_t index_in_vector,
void *r_value) const
{
@@ -33,12 +33,12 @@ bool GVVectorArray_For_SingleGVArray::is_single_vector_impl() const
return true;
}
-int64_t GVVectorArray_For_SingleGSpan::get_vector_size_impl(const int64_t UNUSED(index)) const
+int64_t GVVectorArray_For_SingleGSpan::get_vector_size_impl(const int64_t /*index*/) const
{
return span_.size();
}
-void GVVectorArray_For_SingleGSpan::get_vector_element_impl(const int64_t UNUSED(index),
+void GVVectorArray_For_SingleGSpan::get_vector_element_impl(const int64_t /*index*/,
const int64_t index_in_vector,
void *r_value) const
{
diff --git a/source/blender/blenlib/intern/hash_mm2a.c b/source/blender/blenlib/intern/hash_mm2a.c
index 8411b49ef38..d13c20e4edb 100644
--- a/source/blender/blenlib/intern/hash_mm2a.c
+++ b/source/blender/blenlib/intern/hash_mm2a.c
@@ -41,7 +41,7 @@
} \
(void)0
-static void mm2a_mix_tail(BLI_HashMurmur2A *mm2, const unsigned char **data, size_t *len)
+static void mm2a_mix_tail(BLI_HashMurmur2A *mm2, const uchar **data, size_t *len)
{
while (*len && ((*len < 4) || mm2->count)) {
mm2->tail |= (uint32_t)(**data) << (mm2->count * 8);
@@ -66,7 +66,7 @@ void BLI_hash_mm2a_init(BLI_HashMurmur2A *mm2, uint32_t seed)
mm2->size = 0;
}
-void BLI_hash_mm2a_add(BLI_HashMurmur2A *mm2, const unsigned char *data, size_t len)
+void BLI_hash_mm2a_add(BLI_HashMurmur2A *mm2, const uchar *data, size_t len)
{
mm2->size += (uint32_t)len;
@@ -83,7 +83,7 @@ void BLI_hash_mm2a_add(BLI_HashMurmur2A *mm2, const unsigned char *data, size_t
void BLI_hash_mm2a_add_int(BLI_HashMurmur2A *mm2, int data)
{
- BLI_hash_mm2a_add(mm2, (const unsigned char *)&data, sizeof(data));
+ BLI_hash_mm2a_add(mm2, (const uchar *)&data, sizeof(data));
}
uint32_t BLI_hash_mm2a_end(BLI_HashMurmur2A *mm2)
@@ -96,7 +96,7 @@ uint32_t BLI_hash_mm2a_end(BLI_HashMurmur2A *mm2)
return mm2->hash;
}
-uint32_t BLI_hash_mm2(const unsigned char *data, size_t len, uint32_t seed)
+uint32_t BLI_hash_mm2(const uchar *data, size_t len, uint32_t seed)
{
/* Initialize the hash to a 'random' value */
uint32_t h = seed ^ len;
diff --git a/source/blender/blenlib/intern/hash_mm3.c b/source/blender/blenlib/intern/hash_mm3.c
index cc1143bf55f..3c05ead5e62 100644
--- a/source/blender/blenlib/intern/hash_mm3.c
+++ b/source/blender/blenlib/intern/hash_mm3.c
@@ -69,7 +69,7 @@ BLI_INLINE uint64_t fmix64(uint64_t k)
return k;
}
-uint32_t BLI_hash_mm3(const unsigned char *data, size_t len, uint32_t seed)
+uint32_t BLI_hash_mm3(const uchar *data, size_t len, uint32_t seed)
{
const uint8_t *in_data = (const uint8_t *)data;
const int nblocks = len / 4;
diff --git a/source/blender/blenlib/intern/jitter_2d.c b/source/blender/blenlib/intern/jitter_2d.c
index 8fa0f2c1e15..4b86f3cfeef 100644
--- a/source/blender/blenlib/intern/jitter_2d.c
+++ b/source/blender/blenlib/intern/jitter_2d.c
@@ -70,7 +70,7 @@ void BLI_jitterate1(float (*jit1)[2], float (*jit2)[2], int num, float radius1)
jit2[i][0] = x;
jit2[i][1] = y;
}
- memcpy(jit1, jit2, 2 * (unsigned int)num * sizeof(float));
+ memcpy(jit1, jit2, 2 * (uint)num * sizeof(float));
}
void BLI_jitterate2(float (*jit1)[2], float (*jit2)[2], int num, float radius2)
@@ -120,7 +120,7 @@ void BLI_jitterate2(float (*jit1)[2], float (*jit2)[2], int num, float radius2)
jit2[i][0] = x;
jit2[i][1] = y;
}
- memcpy(jit1, jit2, (unsigned int)num * sizeof(float[2]));
+ memcpy(jit1, jit2, (uint)num * sizeof(float[2]));
}
void BLI_jitter_init(float (*jitarr)[2], int num)
@@ -138,12 +138,12 @@ void BLI_jitter_init(float (*jitarr)[2], int num)
number_fl = (float)num;
number_fl_sqrt = sqrtf(number_fl);
- jit2 = MEM_mallocN(12 + (unsigned int)num * sizeof(float[2]), "initjit");
+ jit2 = MEM_mallocN(12 + (uint)num * sizeof(float[2]), "initjit");
rad1 = 1.0f / number_fl_sqrt;
rad2 = 1.0f / number_fl;
rad3 = number_fl_sqrt / number_fl;
- rng = BLI_rng_new(31415926 + (unsigned int)num);
+ rng = BLI_rng_new(31415926 + (uint)num);
x = 0;
for (i = 0; i < num; i++) {
diff --git a/source/blender/blenlib/intern/lasso_2d.c b/source/blender/blenlib/intern/lasso_2d.c
index 13b0e416b76..4752864ea3a 100644
--- a/source/blender/blenlib/intern/lasso_2d.c
+++ b/source/blender/blenlib/intern/lasso_2d.c
@@ -12,9 +12,9 @@
#include "BLI_lasso_2d.h" /* own include */
-void BLI_lasso_boundbox(rcti *rect, const int mcoords[][2], const unsigned int mcoords_len)
+void BLI_lasso_boundbox(rcti *rect, const int mcoords[][2], const uint mcoords_len)
{
- unsigned int a;
+ uint a;
rect->xmin = rect->xmax = mcoords[0][0];
rect->ymin = rect->ymax = mcoords[0][1];
@@ -36,7 +36,7 @@ void BLI_lasso_boundbox(rcti *rect, const int mcoords[][2], const unsigned int m
}
bool BLI_lasso_is_point_inside(const int mcoords[][2],
- const unsigned int mcoords_len,
+ const uint mcoords_len,
const int sx,
const int sy,
const int error_value)
@@ -50,7 +50,7 @@ bool BLI_lasso_is_point_inside(const int mcoords[][2],
}
bool BLI_lasso_is_edge_inside(const int mcoords[][2],
- const unsigned int mcoords_len,
+ const uint mcoords_len,
int x0,
int y0,
int x1,
@@ -77,7 +77,7 @@ bool BLI_lasso_is_edge_inside(const int mcoords[][2],
if (isect_seg_seg_v2_int(mcoords[0], mcoords[mcoords_len - 1], v1, v2) > 0) {
return true;
}
- for (unsigned int a = 0; a < mcoords_len - 1; a++) {
+ for (uint a = 0; a < mcoords_len - 1; a++) {
if (isect_seg_seg_v2_int(mcoords[a], mcoords[a + 1], v1, v2) > 0) {
return true;
}
diff --git a/source/blender/blenlib/intern/lazy_threading.cc b/source/blender/blenlib/intern/lazy_threading.cc
new file mode 100644
index 00000000000..803fd81a96d
--- /dev/null
+++ b/source/blender/blenlib/intern/lazy_threading.cc
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BLI_lazy_threading.hh"
+#include "BLI_vector.hh"
+
+namespace blender::lazy_threading {
+
+/**
+ * This is a #RawVector so that it can be destructed after Blender checks for memory leaks.
+ */
+thread_local RawVector<FunctionRef<void()>, 0> hint_receivers;
+
+void send_hint()
+{
+ for (const FunctionRef<void()> &fn : hint_receivers) {
+ fn();
+ }
+}
+
+HintReceiver::HintReceiver(const FunctionRef<void()> fn)
+{
+ hint_receivers.append(fn);
+}
+
+HintReceiver::~HintReceiver()
+{
+ hint_receivers.pop_last();
+}
+
+} // namespace blender::lazy_threading
diff --git a/source/blender/blenlib/intern/math_base.c b/source/blender/blenlib/intern/math_base.c
index 257153dc6fe..8a791030fce 100644
--- a/source/blender/blenlib/intern/math_base.c
+++ b/source/blender/blenlib/intern/math_base.c
@@ -65,7 +65,7 @@ float floor_power_of_10(float f)
{
BLI_assert(!(f < 0.0f));
if (f != 0.0f) {
- return 1.0f / (powf(10.0f, ceilf(log10f(1.0f / f))));
+ return 1.0f / powf(10.0f, ceilf(log10f(1.0f / f)));
}
return 0.0f;
}
@@ -74,7 +74,7 @@ float ceil_power_of_10(float f)
{
BLI_assert(!(f < 0.0f));
if (f != 0.0f) {
- return 1.0f / (powf(10.0f, floorf(log10f(1.0f / f))));
+ return 1.0f / powf(10.0f, floorf(log10f(1.0f / f)));
}
return 0.0f;
}
diff --git a/source/blender/blenlib/intern/math_boolean.cc b/source/blender/blenlib/intern/math_boolean.cc
index 132d5dfda65..e5352540dd6 100644
--- a/source/blender/blenlib/intern/math_boolean.cc
+++ b/source/blender/blenlib/intern/math_boolean.cc
@@ -193,7 +193,7 @@ static RobustInitCaller init_caller;
y = b - bvirt
#define Fast_Two_Sum(a, b, x, y) \
- x = (double)(a + b); \
+ x = double(a + b); \
Fast_Two_Sum_Tail(a, b, x, y)
#define Fast_Two_Diff_Tail(a, b, x, y) \
@@ -205,30 +205,30 @@ static RobustInitCaller init_caller;
Fast_Two_Diff_Tail(a, b, x, y)
#define Two_Sum_Tail(a, b, x, y) \
- bvirt = (double)(x - a); \
+ bvirt = double(x - a); \
avirt = x - bvirt; \
bround = b - bvirt; \
around = a - avirt; \
y = around + bround
#define Two_Sum(a, b, x, y) \
- x = (double)(a + b); \
+ x = double(a + b); \
Two_Sum_Tail(a, b, x, y)
#define Two_Diff_Tail(a, b, x, y) \
- bvirt = (double)(a - x); \
+ bvirt = double(a - x); \
avirt = x + bvirt; \
bround = bvirt - b; \
around = a - avirt; \
y = around + bround
#define Two_Diff(a, b, x, y) \
- x = (double)(a - b); \
+ x = double(a - b); \
Two_Diff_Tail(a, b, x, y)
#define Split(a, ahi, alo) \
- c = (double)(splitter * a); \
- abig = (double)(c - a); \
+ c = double(splitter * a); \
+ abig = double(c - a); \
ahi = c - abig; \
alo = a - ahi
@@ -241,11 +241,11 @@ static RobustInitCaller init_caller;
y = (alo * blo) - err3
#define Two_Product(a, b, x, y) \
- x = (double)(a * b); \
+ x = double(a * b); \
Two_Product_Tail(a, b, x, y)
#define Two_Product_Presplit(a, b, bhi, blo, x, y) \
- x = (double)(a * b); \
+ x = double(a * b); \
Split(a, ahi, alo); \
err1 = x - (ahi * bhi); \
err2 = err1 - (alo * bhi); \
@@ -266,7 +266,7 @@ static RobustInitCaller init_caller;
y = (alo * alo) - err3
#define Square(a, x, y) \
- x = (double)(a * a); \
+ x = double(a * a); \
Square_Tail(a, x, y)
#define Two_One_Sum(a1, a0, b, x2, x1, x0) \
@@ -647,10 +647,10 @@ static double orient2dadapt(const double *pa, const double *pb, const double *pc
INEXACT double _i, _j;
double _0;
- acx = (double)(pa[0] - pc[0]);
- bcx = (double)(pb[0] - pc[0]);
- acy = (double)(pa[1] - pc[1]);
- bcy = (double)(pb[1] - pc[1]);
+ acx = double(pa[0] - pc[0]);
+ bcx = double(pb[0] - pc[0]);
+ acy = double(pa[1] - pc[1]);
+ bcy = double(pb[1] - pc[1]);
Two_Product(acx, bcy, detleft, detlefttail);
Two_Product(acy, bcx, detright, detrighttail);
@@ -834,15 +834,15 @@ static double orient3dadapt(
INEXACT double _i, _j, _k;
double _0;
- adx = (double)(pa[0] - pd[0]);
- bdx = (double)(pb[0] - pd[0]);
- cdx = (double)(pc[0] - pd[0]);
- ady = (double)(pa[1] - pd[1]);
- bdy = (double)(pb[1] - pd[1]);
- cdy = (double)(pc[1] - pd[1]);
- adz = (double)(pa[2] - pd[2]);
- bdz = (double)(pb[2] - pd[2]);
- cdz = (double)(pc[2] - pd[2]);
+ adx = double(pa[0] - pd[0]);
+ bdx = double(pb[0] - pd[0]);
+ cdx = double(pc[0] - pd[0]);
+ ady = double(pa[1] - pd[1]);
+ bdy = double(pb[1] - pd[1]);
+ cdy = double(pc[1] - pd[1]);
+ adz = double(pa[2] - pd[2]);
+ bdz = double(pb[2] - pd[2]);
+ cdz = double(pc[2] - pd[2]);
Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
@@ -1358,12 +1358,12 @@ static double incircleadapt(
INEXACT double _i, _j;
double _0;
- adx = (double)(pa[0] - pd[0]);
- bdx = (double)(pb[0] - pd[0]);
- cdx = (double)(pc[0] - pd[0]);
- ady = (double)(pa[1] - pd[1]);
- bdy = (double)(pb[1] - pd[1]);
- cdy = (double)(pc[1] - pd[1]);
+ adx = double(pa[0] - pd[0]);
+ bdx = double(pb[0] - pd[0]);
+ cdx = double(pc[0] - pd[0]);
+ ady = double(pa[1] - pd[1]);
+ bdy = double(pb[1] - pd[1]);
+ cdy = double(pc[1] - pd[1]);
Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
@@ -2191,18 +2191,18 @@ static double insphereadapt(const double *pa,
INEXACT double _i, _j;
double _0;
- aex = (double)(pa[0] - pe[0]);
- bex = (double)(pb[0] - pe[0]);
- cex = (double)(pc[0] - pe[0]);
- dex = (double)(pd[0] - pe[0]);
- aey = (double)(pa[1] - pe[1]);
- bey = (double)(pb[1] - pe[1]);
- cey = (double)(pc[1] - pe[1]);
- dey = (double)(pd[1] - pe[1]);
- aez = (double)(pa[2] - pe[2]);
- bez = (double)(pb[2] - pe[2]);
- cez = (double)(pc[2] - pe[2]);
- dez = (double)(pd[2] - pe[2]);
+ aex = double(pa[0] - pe[0]);
+ bex = double(pb[0] - pe[0]);
+ cex = double(pc[0] - pe[0]);
+ dex = double(pd[0] - pe[0]);
+ aey = double(pa[1] - pe[1]);
+ bey = double(pb[1] - pe[1]);
+ cey = double(pc[1] - pe[1]);
+ dey = double(pd[1] - pe[1]);
+ aez = double(pa[2] - pe[2]);
+ bez = double(pb[2] - pe[2]);
+ cez = double(pc[2] - pe[2]);
+ dez = double(pd[2] - pe[2]);
Two_Product(aex, bey, aexbey1, aexbey0);
Two_Product(bex, aey, bexaey1, bexaey0);
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index bdcf52ec521..51860c1abdb 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -176,7 +176,7 @@ void ycc_to_rgb(float y, float cb, float cr, float *r_r, float *r_g, float *r_b,
void hex_to_rgb(const char *hexcol, float *r_r, float *r_g, float *r_b)
{
- unsigned int ri, gi, bi;
+ uint ri, gi, bi;
if (hexcol[0] == '#') {
hexcol++;
@@ -329,29 +329,29 @@ void hsv_clamp_v(float hsv[3], float v_max)
CLAMP(hsv[2], 0.0f, v_max);
}
-unsigned int hsv_to_cpack(float h, float s, float v)
+uint hsv_to_cpack(float h, float s, float v)
{
- unsigned int r, g, b;
+ uint r, g, b;
float rf, gf, bf;
- unsigned int col;
+ uint col;
hsv_to_rgb(h, s, v, &rf, &gf, &bf);
- r = (unsigned int)(rf * 255.0f);
- g = (unsigned int)(gf * 255.0f);
- b = (unsigned int)(bf * 255.0f);
+ r = (uint)(rf * 255.0f);
+ g = (uint)(gf * 255.0f);
+ b = (uint)(bf * 255.0f);
col = (r + (g * 256) + (b * 256 * 256));
return col;
}
-unsigned int rgb_to_cpack(float r, float g, float b)
+uint rgb_to_cpack(float r, float g, float b)
{
- unsigned int ir, ig, ib;
+ uint ir, ig, ib;
- ir = (unsigned int)floorf(255.0f * max_ff(r, 0.0f));
- ig = (unsigned int)floorf(255.0f * max_ff(g, 0.0f));
- ib = (unsigned int)floorf(255.0f * max_ff(b, 0.0f));
+ ir = (uint)floorf(255.0f * max_ff(r, 0.0f));
+ ig = (uint)floorf(255.0f * max_ff(g, 0.0f));
+ ib = (uint)floorf(255.0f * max_ff(b, 0.0f));
if (ir > 255) {
ir = 255;
@@ -366,21 +366,21 @@ unsigned int rgb_to_cpack(float r, float g, float b)
return (ir + (ig * 256) + (ib * 256 * 256));
}
-void cpack_to_rgb(unsigned int col, float *r_r, float *r_g, float *r_b)
+void cpack_to_rgb(uint col, float *r_r, float *r_g, float *r_b)
{
- *r_r = ((float)(((col)) & 0xFF)) * (1.0f / 255.0f);
- *r_g = ((float)(((col) >> 8) & 0xFF)) * (1.0f / 255.0f);
- *r_b = ((float)(((col) >> 16) & 0xFF)) * (1.0f / 255.0f);
+ *r_r = (float)(col & 0xFF) * (1.0f / 255.0f);
+ *r_g = (float)((col >> 8) & 0xFF) * (1.0f / 255.0f);
+ *r_b = (float)((col >> 16) & 0xFF) * (1.0f / 255.0f);
}
-void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3])
+void rgb_uchar_to_float(float r_col[3], const uchar col_ub[3])
{
r_col[0] = ((float)col_ub[0]) * (1.0f / 255.0f);
r_col[1] = ((float)col_ub[1]) * (1.0f / 255.0f);
r_col[2] = ((float)col_ub[2]) * (1.0f / 255.0f);
}
-void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4])
+void rgba_uchar_to_float(float r_col[4], const uchar col_ub[4])
{
r_col[0] = ((float)col_ub[0]) * (1.0f / 255.0f);
r_col[1] = ((float)col_ub[1]) * (1.0f / 255.0f);
@@ -388,12 +388,12 @@ void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4])
r_col[3] = ((float)col_ub[3]) * (1.0f / 255.0f);
}
-void rgb_float_to_uchar(unsigned char r_col[3], const float col_f[3])
+void rgb_float_to_uchar(uchar r_col[3], const float col_f[3])
{
unit_float_to_uchar_clamp_v3(r_col, col_f);
}
-void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
+void rgba_float_to_uchar(uchar r_col[4], const float col_f[4])
{
unit_float_to_uchar_clamp_v4(r_col, col_f);
}
@@ -500,7 +500,7 @@ void rgb_float_set_hue_float_offset(float rgb[3], float hue_offset)
hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb + 1, rgb + 2);
}
-void rgb_byte_set_hue_float_offset(unsigned char rgb[3], float hue_offset)
+void rgb_byte_set_hue_float_offset(uchar rgb[3], float hue_offset)
{
float rgb_float[3];
@@ -515,13 +515,13 @@ void rgb_byte_set_hue_float_offset(unsigned char rgb[3], float hue_offset)
*/
float BLI_color_from_srgb_table[256];
-unsigned short BLI_color_to_srgb_table[0x10000];
+ushort BLI_color_to_srgb_table[0x10000];
-static unsigned short hipart(const float f)
+static ushort hipart(const float f)
{
union {
float f;
- unsigned short us[2];
+ ushort us[2];
} tmp;
tmp.f = f;
@@ -533,12 +533,12 @@ static unsigned short hipart(const float f)
#endif
}
-static float index_to_float(const unsigned short i)
+static float index_to_float(const ushort i)
{
union {
float f;
- unsigned short us[2];
+ ushort us[2];
} tmp;
/* positive and negative zeros, and all gradual underflow, turn into zero: */
@@ -567,7 +567,7 @@ static float index_to_float(const unsigned short i)
void BLI_init_srgb_conversion(void)
{
static bool initialized = false;
- unsigned int i, b;
+ uint i, b;
if (initialized) {
return;
@@ -576,12 +576,12 @@ void BLI_init_srgb_conversion(void)
/* Fill in the lookup table to convert floats to bytes: */
for (i = 0; i < 0x10000; i++) {
- float f = linearrgb_to_srgb(index_to_float((unsigned short)i)) * 255.0f;
+ float f = linearrgb_to_srgb(index_to_float((ushort)i)) * 255.0f;
if (f <= 0) {
BLI_color_to_srgb_table[i] = 0;
}
else if (f < 255) {
- BLI_color_to_srgb_table[i] = (unsigned short)(f * 0x100 + 0.5f);
+ BLI_color_to_srgb_table[i] = (ushort)(f * 0x100 + 0.5f);
}
else {
BLI_color_to_srgb_table[i] = 0xff00;
@@ -594,6 +594,6 @@ void BLI_init_srgb_conversion(void)
BLI_color_from_srgb_table[b] = f;
i = hipart(f);
/* replace entries so byte->float->byte does not change the data: */
- BLI_color_to_srgb_table[i] = (unsigned short)(b * 0x100);
+ BLI_color_to_srgb_table[i] = (ushort)(b * 0x100);
}
}
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index e7ccdeab80a..08152976f7d 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -68,7 +68,7 @@ float normal_quad_v3(
return normalize_v3(n);
}
-float normal_poly_v3(float n[3], const float verts[][3], unsigned int nr)
+float normal_poly_v3(float n[3], const float verts[][3], uint nr)
{
cross_poly_v3(n, verts, nr);
return normalize_v3(n);
@@ -122,14 +122,14 @@ float area_tri_signed_v3(const float v1[3],
return area;
}
-float area_poly_v3(const float verts[][3], unsigned int nr)
+float area_poly_v3(const float verts[][3], uint nr)
{
float n[3];
cross_poly_v3(n, verts, nr);
return len_v3(n) * 0.5f;
}
-float area_squared_poly_v3(const float verts[][3], unsigned int nr)
+float area_squared_poly_v3(const float verts[][3], uint nr)
{
float n[3];
@@ -138,9 +138,9 @@ float area_squared_poly_v3(const float verts[][3], unsigned int nr)
return len_squared_v3(n);
}
-float cross_poly_v2(const float verts[][2], unsigned int nr)
+float cross_poly_v2(const float verts[][2], uint nr)
{
- unsigned int a;
+ uint a;
float cross;
const float *co_curr, *co_prev;
@@ -157,11 +157,11 @@ float cross_poly_v2(const float verts[][2], unsigned int nr)
return cross;
}
-void cross_poly_v3(float n[3], const float verts[][3], unsigned int nr)
+void cross_poly_v3(float n[3], const float verts[][3], uint nr)
{
const float *v_prev = verts[nr - 1];
const float *v_curr = verts[0];
- unsigned int i;
+ uint i;
zero_v3(n);
@@ -171,17 +171,17 @@ void cross_poly_v3(float n[3], const float verts[][3], unsigned int nr)
}
}
-float area_poly_v2(const float verts[][2], unsigned int nr)
+float area_poly_v2(const float verts[][2], uint nr)
{
return fabsf(0.5f * cross_poly_v2(verts, nr));
}
-float area_poly_signed_v2(const float verts[][2], unsigned int nr)
+float area_poly_signed_v2(const float verts[][2], uint nr)
{
return (0.5f * cross_poly_v2(verts, nr));
}
-float area_squared_poly_v2(const float verts[][2], unsigned int nr)
+float area_squared_poly_v2(const float verts[][2], uint nr)
{
float area = area_poly_signed_v2(verts, nr);
return area * area;
@@ -527,7 +527,7 @@ float dist_signed_squared_to_corner_v3v3v3(const float p[3],
cross_v3_v3v3(axis, dir_a, dir_b);
- if ((len_squared_v3(axis) < FLT_EPSILON)) {
+ if (len_squared_v3(axis) < FLT_EPSILON) {
copy_v3_v3(axis, axis_ref);
}
else if (dot_v3v3(axis, axis_ref) < 0.0f) {
@@ -1458,12 +1458,12 @@ int isect_line_sphere_v2(const float l1[2],
bool isect_point_poly_v2(const float pt[2],
const float verts[][2],
- const unsigned int nr,
+ const uint nr,
const bool UNUSED(use_holes))
{
/* Keep in sync with #isect_point_poly_v2_int. */
- unsigned int i, j;
+ uint i, j;
bool isect = false;
for (i = 0, j = nr - 1; i < nr; j = i++) {
if (((verts[i][1] > pt[1]) != (verts[j][1] > pt[1])) &&
@@ -1477,12 +1477,12 @@ bool isect_point_poly_v2(const float pt[2],
}
bool isect_point_poly_v2_int(const int pt[2],
const int verts[][2],
- const unsigned int nr,
+ const uint nr,
const bool UNUSED(use_holes))
{
/* Keep in sync with #isect_point_poly_v2. */
- unsigned int i, j;
+ uint i, j;
bool isect = false;
for (i = 0, j = nr - 1; i < nr; j = i++) {
if (((verts[i][1] > pt[1]) != (verts[j][1] > pt[1])) &&
@@ -1667,8 +1667,8 @@ bool isect_ray_tri_v3(const float ray_origin[3],
float *r_lambda,
float r_uv[2])
{
- /* NOTE(campbell): these values were 0.000001 in 2.4x but for projection snapping on
- * a human head (1BU == 1m), subsurf level 2, this gave many errors. */
+ /* NOTE(@campbellbarton): these values were 0.000001 in 2.4x but for projection snapping on
+ * a human head `(1BU == 1m)`, subdivision-surface level 2, this gave many errors. */
const float epsilon = 0.00000001f;
float p[3], s[3], e1[3], e2[3], q[3];
float a, f, u, v;
@@ -2208,7 +2208,7 @@ bool isect_planes_v3_fn(
int i_test;
for (i_test = 0; i_test < planes_len; i_test++) {
const float *np_test = planes[i_test];
- if (((dot_v3v3(np_test, co_test) + np_test[3]) > eps_isect)) {
+ if ((dot_v3v3(np_test, co_test) + np_test[3]) > eps_isect) {
/* For low epsilon values the point could intersect its own plane. */
if (!ELEM(i_test, i, j, k)) {
break;
@@ -2696,7 +2696,7 @@ bool isect_sweeping_sphere_tri_v3(const float p1[3],
z = x + y - (a * c - b * b);
if (z <= 0.0f && (x >= 0.0f && y >= 0.0f)) {
- //(((unsigned int)z)& ~(((unsigned int)x)|((unsigned int)y))) & 0x80000000) {
+ //(((uint)z)& ~(((uint)x)|((uint)y))) & 0x80000000) {
*r_lambda = t0;
copy_v3_v3(ipoint, point);
return true;
@@ -2748,7 +2748,7 @@ bool isect_sweeping_sphere_tri_v3(const float p1[3],
edotv = dot_v3v3(e1, vel);
edotbv = dot_v3v3(e1, bv);
- a = elen2 * (-dot_v3v3(vel, vel)) + edotv * edotv;
+ a = elen2 * -dot_v3v3(vel, vel) + edotv * edotv;
b = 2.0f * (elen2 * dot_v3v3(vel, bv) - edotv * edotbv);
c = elen2 * (radius2 - dot_v3v3(bv, bv)) + edotbv * edotbv;
@@ -2770,7 +2770,7 @@ bool isect_sweeping_sphere_tri_v3(const float p1[3],
edotv = dot_v3v3(e2, vel);
edotbv = dot_v3v3(e2, bv);
- a = elen2 * (-dot_v3v3(vel, vel)) + edotv * edotv;
+ a = elen2 * -dot_v3v3(vel, vel) + edotv * edotv;
b = 2.0f * (elen2 * dot_v3v3(vel, bv) - edotv * edotbv);
c = elen2 * (radius2 - dot_v3v3(bv, bv)) + edotbv * edotbv;
@@ -2797,7 +2797,7 @@ bool isect_sweeping_sphere_tri_v3(const float p1[3],
edotv = dot_v3v3(e3, vel);
edotbv = dot_v3v3(e3, bv);
- a = elen2 * (-dot_v3v3(vel, vel)) + edotv * edotv;
+ a = elen2 * -dot_v3v3(vel, vel) + edotv * edotv;
b = 2.0f * (elen2 * dot_v3v3(vel, bv) - edotv * edotbv);
c = elen2 * (radius2 - dot_v3v3(bv, bv)) + edotbv * edotbv;
@@ -3773,7 +3773,7 @@ void barycentric_weights_v2_quad(const float v1[2],
const float co[2],
float w[4])
{
- /* NOTE(campbell): fabsf() here is not needed for convex quads
+ /* NOTE(@campbellbarton): fabsf() here is not needed for convex quads
* (and not used in #interp_weights_poly_v2).
* But in the case of concave/bow-tie quads for the mask rasterizer it
* gives unreliable results without adding `absf()`. If this becomes an issue for more general
@@ -5803,10 +5803,10 @@ bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2],
return (isect_seg_seg_v2(v1, v3, v2, v4) > 0);
}
-bool is_poly_convex_v2(const float verts[][2], unsigned int nr)
+bool is_poly_convex_v2(const float verts[][2], uint nr)
{
- unsigned int sign_flag = 0;
- unsigned int a;
+ uint sign_flag = 0;
+ uint a;
const float *co_curr, *co_prev;
float dir_curr[2], dir_prev[2];
diff --git a/source/blender/blenlib/intern/math_interp.c b/source/blender/blenlib/intern/math_interp.c
index 34fcb583232..29907924bd8 100644
--- a/source/blender/blenlib/intern/math_interp.c
+++ b/source/blender/blenlib/intern/math_interp.c
@@ -56,7 +56,7 @@ static void vector_from_float(const float *data, float vector[4], int components
}
}
-static void vector_from_byte(const unsigned char *data, float vector[4], int components)
+static void vector_from_byte(const uchar *data, float vector[4], int components)
{
if (components == 1) {
vector[0] = data[0];
@@ -75,9 +75,9 @@ static void vector_from_byte(const unsigned char *data, float vector[4], int com
}
/* BICUBIC INTERPOLATION */
-BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer,
+BLI_INLINE void bicubic_interpolation(const uchar *byte_buffer,
const float *float_buffer,
- unsigned char *byte_output,
+ uchar *byte_output,
float *float_output,
int width,
int height,
@@ -135,7 +135,7 @@ BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer,
vector_from_float(float_data, data, components);
}
else {
- const unsigned char *byte_data = byte_buffer + width * y1 * components + components * x1;
+ const uchar *byte_data = byte_buffer + width * y1 * components + components * x1;
vector_from_byte(byte_data, data, components);
}
@@ -174,7 +174,7 @@ BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer,
vector_from_float(float_data, data, components);
}
else {
- const unsigned char *byte_data = byte_buffer + width * y1 * components + components * x1;
+ const uchar *byte_data = byte_buffer + width * y1 * components + components * x1;
vector_from_byte(byte_data, data, components);
}
@@ -211,18 +211,18 @@ BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer,
}
else {
if (components == 1) {
- byte_output[0] = (unsigned char)(out[0] + 0.5f);
+ byte_output[0] = (uchar)(out[0] + 0.5f);
}
else if (components == 3) {
- byte_output[0] = (unsigned char)(out[0] + 0.5f);
- byte_output[1] = (unsigned char)(out[1] + 0.5f);
- byte_output[2] = (unsigned char)(out[2] + 0.5f);
+ byte_output[0] = (uchar)(out[0] + 0.5f);
+ byte_output[1] = (uchar)(out[1] + 0.5f);
+ byte_output[2] = (uchar)(out[2] + 0.5f);
}
else {
- byte_output[0] = (unsigned char)(out[0] + 0.5f);
- byte_output[1] = (unsigned char)(out[1] + 0.5f);
- byte_output[2] = (unsigned char)(out[2] + 0.5f);
- byte_output[3] = (unsigned char)(out[3] + 0.5f);
+ byte_output[0] = (uchar)(out[0] + 0.5f);
+ byte_output[1] = (uchar)(out[1] + 0.5f);
+ byte_output[2] = (uchar)(out[2] + 0.5f);
+ byte_output[3] = (uchar)(out[3] + 0.5f);
}
}
}
@@ -233,21 +233,16 @@ void BLI_bicubic_interpolation_fl(
bicubic_interpolation(NULL, buffer, NULL, output, width, height, components, u, v);
}
-void BLI_bicubic_interpolation_char(const unsigned char *buffer,
- unsigned char *output,
- int width,
- int height,
- int components,
- float u,
- float v)
+void BLI_bicubic_interpolation_char(
+ const uchar *buffer, uchar *output, int width, int height, int components, float u, float v)
{
bicubic_interpolation(buffer, NULL, output, NULL, width, height, components, u, v);
}
/* BILINEAR INTERPOLATION */
-BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer,
+BLI_INLINE void bilinear_interpolation(const uchar *byte_buffer,
const float *float_buffer,
- unsigned char *byte_output,
+ uchar *byte_output,
float *float_output,
int width,
int height,
@@ -351,8 +346,8 @@ BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer,
}
}
else {
- const unsigned char *row1, *row2, *row3, *row4;
- unsigned char empty[4] = {0, 0, 0, 0};
+ const uchar *row1, *row2, *row3, *row4;
+ uchar empty[4] = {0, 0, 0, 0};
/* pixel value must be already wrapped, however values at boundaries may flip */
if (wrap_x) {
@@ -418,26 +413,26 @@ BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer,
ma_mb = (1.0f - a) * (1.0f - b);
if (components == 1) {
- byte_output[0] = (unsigned char)(ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] +
- a_b * row4[0] + 0.5f);
+ byte_output[0] = (uchar)(ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0] +
+ 0.5f);
}
else if (components == 3) {
- byte_output[0] = (unsigned char)(ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] +
- a_b * row4[0] + 0.5f);
- byte_output[1] = (unsigned char)(ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] +
- a_b * row4[1] + 0.5f);
- byte_output[2] = (unsigned char)(ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] +
- a_b * row4[2] + 0.5f);
+ byte_output[0] = (uchar)(ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0] +
+ 0.5f);
+ byte_output[1] = (uchar)(ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1] +
+ 0.5f);
+ byte_output[2] = (uchar)(ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2] +
+ 0.5f);
}
else {
- byte_output[0] = (unsigned char)(ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] +
- a_b * row4[0] + 0.5f);
- byte_output[1] = (unsigned char)(ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] +
- a_b * row4[1] + 0.5f);
- byte_output[2] = (unsigned char)(ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] +
- a_b * row4[2] + 0.5f);
- byte_output[3] = (unsigned char)(ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] +
- a_b * row4[3] + 0.5f);
+ byte_output[0] = (uchar)(ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0] +
+ 0.5f);
+ byte_output[1] = (uchar)(ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1] +
+ 0.5f);
+ byte_output[2] = (uchar)(ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2] +
+ 0.5f);
+ byte_output[3] = (uchar)(ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] + a_b * row4[3] +
+ 0.5f);
}
}
}
@@ -449,13 +444,8 @@ void BLI_bilinear_interpolation_fl(
NULL, buffer, NULL, output, width, height, components, u, v, false, false);
}
-void BLI_bilinear_interpolation_char(const unsigned char *buffer,
- unsigned char *output,
- int width,
- int height,
- int components,
- float u,
- float v)
+void BLI_bilinear_interpolation_char(
+ const uchar *buffer, uchar *output, int width, int height, int components, float u, float v)
{
bilinear_interpolation(
buffer, NULL, output, NULL, width, height, components, u, v, false, false);
@@ -475,8 +465,8 @@ void BLI_bilinear_interpolation_wrap_fl(const float *buffer,
NULL, buffer, NULL, output, width, height, components, u, v, wrap_x, wrap_y);
}
-void BLI_bilinear_interpolation_wrap_char(const unsigned char *buffer,
- unsigned char *output,
+void BLI_bilinear_interpolation_wrap_char(const uchar *buffer,
+ uchar *output,
int width,
int height,
int components,
@@ -634,10 +624,10 @@ void BLI_ewa_filter(const int width,
U0 = uv[0] * (float)width;
V0 = uv[1] * (float)height;
- u1 = (int)(floorf(U0 - ue));
- u2 = (int)(ceilf(U0 + ue));
- v1 = (int)(floorf(V0 - ve));
- v2 = (int)(ceilf(V0 + ve));
+ u1 = (int)floorf(U0 - ue);
+ u2 = (int)ceilf(U0 + ue);
+ v1 = (int)floorf(V0 - ve);
+ v2 = (int)ceilf(V0 + ve);
/* sane clamping to avoid unnecessarily huge loops */
/* NOTE: if eccentricity gets clamped (see above),
@@ -679,7 +669,7 @@ void BLI_ewa_filter(const int width,
for (u = u1; u <= u2; u++) {
if (Q < (float)(EWA_MAXIDX + 1)) {
float tc[4];
- const float wt = EWA_WTS[(Q < 0.0f) ? 0 : (unsigned int)Q];
+ const float wt = EWA_WTS[(Q < 0.0f) ? 0 : (uint)Q];
read_pixel_cb(userdata, u, v, tc);
madd_v3_v3fl(result, tc, wt);
result[3] += use_alpha ? tc[3] * wt : 0.0f;
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index fcd017b3082..d997eae26fb 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -113,7 +113,6 @@ void copy_m4_m3(float m1[4][4], const float m2[3][3]) /* no clear */
m1[2][1] = m2[2][1];
m1[2][2] = m2[2][2];
- /* Reevan's Bugfix */
m1[0][3] = 0.0f;
m1[1][3] = 0.0f;
m1[2][3] = 0.0f;
@@ -787,14 +786,14 @@ void mul_m2_v2(const float mat[2][2], float vec[2])
mul_v2_m2v2(vec, mat, vec);
}
-void mul_mat3_m4_v3(const float M[4][4], float r[3])
+void mul_mat3_m4_v3(const float mat[4][4], float r[3])
{
const float x = r[0];
const float y = r[1];
- r[0] = x * M[0][0] + y * M[1][0] + M[2][0] * r[2];
- r[1] = x * M[0][1] + y * M[1][1] + M[2][1] * r[2];
- r[2] = x * M[0][2] + y * M[1][2] + M[2][2] * r[2];
+ r[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * r[2];
+ r[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * r[2];
+ r[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * r[2];
}
void mul_v3_mat3_m4v3(float r[3], const float mat[4][4], const float vec[3])
@@ -1116,32 +1115,32 @@ double determinant_m3_array_db(const double m[3][3])
m[2][0] * (m[0][1] * m[1][2] - m[0][2] * m[1][1]));
}
-bool invert_m2_m2(float m1[2][2], const float m2[2][2])
+bool invert_m2_m2(float inverse[2][2], const float mat[2][2])
{
- adjoint_m2_m2(m1, m2);
- float det = determinant_m2(m2[0][0], m2[1][0], m2[0][1], m2[1][1]);
+ adjoint_m2_m2(inverse, mat);
+ float det = determinant_m2(mat[0][0], mat[1][0], mat[0][1], mat[1][1]);
bool success = (det != 0.0f);
if (success) {
- m1[0][0] /= det;
- m1[1][0] /= det;
- m1[0][1] /= det;
- m1[1][1] /= det;
+ inverse[0][0] /= det;
+ inverse[1][0] /= det;
+ inverse[0][1] /= det;
+ inverse[1][1] /= det;
}
return success;
}
-bool invert_m3_ex(float m[3][3], const float epsilon)
+bool invert_m3_ex(float mat[3][3], const float epsilon)
{
- float tmp[3][3];
- const bool success = invert_m3_m3_ex(tmp, m, epsilon);
+ float mat_tmp[3][3];
+ const bool success = invert_m3_m3_ex(mat_tmp, mat, epsilon);
- copy_m3_m3(m, tmp);
+ copy_m3_m3(mat, mat_tmp);
return success;
}
-bool invert_m3_m3_ex(float m1[3][3], const float m2[3][3], const float epsilon)
+bool invert_m3_m3_ex(float inverse[3][3], const float mat[3][3], const float epsilon)
{
float det;
int a, b;
@@ -1150,10 +1149,10 @@ bool invert_m3_m3_ex(float m1[3][3], const float m2[3][3], const float epsilon)
BLI_assert(epsilon >= 0.0f);
/* calc adjoint */
- adjoint_m3_m3(m1, m2);
+ adjoint_m3_m3(inverse, mat);
/* then determinant old matrix! */
- det = determinant_m3_array(m2);
+ det = determinant_m3_array(mat);
success = (fabsf(det) > epsilon);
@@ -1161,33 +1160,33 @@ bool invert_m3_m3_ex(float m1[3][3], const float m2[3][3], const float epsilon)
det = 1.0f / det;
for (a = 0; a < 3; a++) {
for (b = 0; b < 3; b++) {
- m1[a][b] *= det;
+ inverse[a][b] *= det;
}
}
}
return success;
}
-bool invert_m3(float m[3][3])
+bool invert_m3(float mat[3][3])
{
- float tmp[3][3];
- const bool success = invert_m3_m3(tmp, m);
+ float mat_tmp[3][3];
+ const bool success = invert_m3_m3(mat_tmp, mat);
- copy_m3_m3(m, tmp);
+ copy_m3_m3(mat, mat_tmp);
return success;
}
-bool invert_m3_m3(float m1[3][3], const float m2[3][3])
+bool invert_m3_m3(float inverse[3][3], const float mat[3][3])
{
float det;
int a, b;
bool success;
/* calc adjoint */
- adjoint_m3_m3(m1, m2);
+ adjoint_m3_m3(inverse, mat);
/* then determinant old matrix! */
- det = determinant_m3_array(m2);
+ det = determinant_m3_array(mat);
success = (det != 0.0f);
@@ -1195,7 +1194,7 @@ bool invert_m3_m3(float m1[3][3], const float m2[3][3])
det = 1.0f / det;
for (a = 0; a < 3; a++) {
for (b = 0; b < 3; b++) {
- m1[a][b] *= det;
+ inverse[a][b] *= det;
}
}
}
@@ -1203,12 +1202,12 @@ bool invert_m3_m3(float m1[3][3], const float m2[3][3])
return success;
}
-bool invert_m4(float m[4][4])
+bool invert_m4(float mat[4][4])
{
- float tmp[4][4];
- const bool success = invert_m4_m4(tmp, m);
+ float mat_tmp[4][4];
+ const bool success = invert_m4_m4(mat_tmp, mat);
- copy_m4_m4(m, tmp);
+ copy_m4_m4(mat, mat_tmp);
return success;
}
@@ -2128,6 +2127,12 @@ void size_to_mat4(float R[4][4], const float size[3])
R[3][3] = 1.0f;
}
+void mat3_to_size_2d(float size[2], const float M[3][3])
+{
+ size[0] = len_v2(M[0]);
+ size[1] = len_v2(M[1]);
+}
+
void mat3_to_size(float size[3], const float M[3][3])
{
size[0] = len_v3(M[0]);
@@ -2191,11 +2196,11 @@ float mat4_to_scale(const float mat[4][4])
return len_v3(unit_vec);
}
-float mat4_to_xy_scale(const float M[4][4])
+float mat4_to_xy_scale(const float mat[4][4])
{
/* unit length vector in xy plane */
float unit_vec[3] = {(float)M_SQRT1_2, (float)M_SQRT1_2, 0.0f};
- mul_mat3_m4_v3(M, unit_vec);
+ mul_mat3_m4_v3(mat, unit_vec);
return len_v3(unit_vec);
}
@@ -2240,12 +2245,6 @@ void mat4_to_loc_quat(float loc[3], float quat[4], const float wmat[4][4])
copy_m3_m4(mat3, wmat);
normalize_m3_m3(mat3_n, mat3);
- /* So scale doesn't interfere with rotation T24291. */
- /* FIXME: this is a workaround for negative matrix not working for rotation conversion. */
- if (is_negative_m3(mat3)) {
- negate_m3(mat3_n);
- }
-
mat3_normalized_to_quat(quat, mat3_n);
copy_v3_v3(loc, wmat[3]);
}
@@ -2254,7 +2253,7 @@ void mat4_decompose(float loc[3], float quat[4], float size[3], const float wmat
{
float rot[3][3];
mat4_to_loc_rot_size(loc, rot, size, wmat);
- mat3_normalized_to_quat(quat, rot);
+ mat3_normalized_to_quat_fast(quat, rot);
}
/**
@@ -2393,8 +2392,8 @@ void blend_m3_m3m3(float out[3][3],
mat3_to_rot_size(drot, dscale, dst);
mat3_to_rot_size(srot, sscale, src);
- mat3_normalized_to_quat(dquat, drot);
- mat3_normalized_to_quat(squat, srot);
+ mat3_normalized_to_quat_fast(dquat, drot);
+ mat3_normalized_to_quat_fast(squat, srot);
/* do blending */
interp_qt_qtqt(fquat, dquat, squat, srcweight);
@@ -2419,8 +2418,8 @@ void blend_m4_m4m4(float out[4][4],
mat4_to_loc_rot_size(dloc, drot, dscale, dst);
mat4_to_loc_rot_size(sloc, srot, sscale, src);
- mat3_normalized_to_quat(dquat, drot);
- mat3_normalized_to_quat(squat, srot);
+ mat3_normalized_to_quat_fast(dquat, drot);
+ mat3_normalized_to_quat_fast(squat, srot);
/* do blending */
interp_v3_v3v3(floc, dloc, sloc, srcweight);
@@ -2456,11 +2455,11 @@ void interp_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3], con
* Note that a flip of two axes is just a rotation of 180 degrees around the third axis, and
* three flipped axes are just an 180 degree rotation + a single axis flip. It is thus sufficient
* to solve this problem for single axis flips. */
- if (determinant_m3_array(U_A) < 0) {
+ if (is_negative_m3(U_A)) {
mul_m3_fl(U_A, -1.0f);
mul_m3_fl(P_A, -1.0f);
}
- if (determinant_m3_array(U_B) < 0) {
+ if (is_negative_m3(U_B)) {
mul_m3_fl(U_B, -1.0f);
mul_m3_fl(P_B, -1.0f);
}
@@ -2501,16 +2500,14 @@ void interp_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4], con
bool is_negative_m3(const float mat[3][3])
{
- float vec[3];
- cross_v3_v3v3(vec, mat[0], mat[1]);
- return (dot_v3v3(vec, mat[2]) < 0.0f);
+ return determinant_m3_array(mat) < 0.0f;
}
bool is_negative_m4(const float mat[4][4])
{
- float vec[3];
- cross_v3_v3v3(vec, mat[0], mat[1]);
- return (dot_v3v3(vec, mat[2]) < 0.0f);
+ /* Don't use #determinant_m4 as only the 3x3 components are needed
+ * when the matrix is used as a transformation to represent location/scale/rotation. */
+ return determinant_m4_mat3_array(mat) < 0.0f;
}
bool is_zero_m3(const float mat[3][3])
@@ -2568,11 +2565,8 @@ void loc_eul_size_to_mat4(float R[4][4],
R[3][2] = loc[2];
}
-void loc_eulO_size_to_mat4(float R[4][4],
- const float loc[3],
- const float eul[3],
- const float size[3],
- const short rotOrder)
+void loc_eulO_size_to_mat4(
+ float R[4][4], const float loc[3], const float eul[3], const float size[3], const short order)
{
float rmat[3][3], smat[3][3], tmat[3][3];
@@ -2580,7 +2574,7 @@ void loc_eulO_size_to_mat4(float R[4][4],
unit_m4(R);
/* Make rotation + scaling part. */
- eulO_to_mat3(rmat, eul, rotOrder);
+ eulO_to_mat3(rmat, eul, order);
size_to_mat3(smat, size);
mul_m3_m3m3(tmat, rmat, smat);
@@ -3082,14 +3076,14 @@ void svd_m4(float U[4][4], float s[4], float V[4][4], float A_[4][4])
}
}
-void pseudoinverse_m4_m4(float Ainv[4][4], const float A_[4][4], float epsilon)
+void pseudoinverse_m4_m4(float inverse[4][4], const float mat[4][4], float epsilon)
{
/* compute Moore-Penrose pseudo inverse of matrix, singular values
* below epsilon are ignored for stability (truncated SVD) */
float A[4][4], V[4][4], W[4], Wm[4][4], U[4][4];
int i;
- transpose_m4_m4(A, A_);
+ transpose_m4_m4(A, mat);
svd_m4(V, W, U, A);
transpose_m4(U);
transpose_m4(V);
@@ -3101,18 +3095,18 @@ void pseudoinverse_m4_m4(float Ainv[4][4], const float A_[4][4], float epsilon)
transpose_m4(V);
- mul_m4_series(Ainv, U, Wm, V);
+ mul_m4_series(inverse, U, Wm, V);
}
-void pseudoinverse_m3_m3(float Ainv[3][3], const float A[3][3], float epsilon)
+void pseudoinverse_m3_m3(float inverse[3][3], const float mat[3][3], float epsilon)
{
/* try regular inverse when possible, otherwise fall back to slow svd */
- if (!invert_m3_m3(Ainv, A)) {
- float tmp[4][4], tmpinv[4][4];
+ if (!invert_m3_m3(inverse, mat)) {
+ float mat_tmp[4][4], tmpinv[4][4];
- copy_m4_m3(tmp, A);
- pseudoinverse_m4_m4(tmpinv, tmp, epsilon);
- copy_m3_m4(Ainv, tmpinv);
+ copy_m4_m3(mat_tmp, mat);
+ pseudoinverse_m4_m4(tmpinv, mat_tmp, epsilon);
+ copy_m3_m4(inverse, tmpinv);
}
}
@@ -3122,22 +3116,50 @@ bool has_zero_axis_m4(const float matrix[4][4])
len_squared_v3(matrix[2]) < FLT_EPSILON;
}
-void invert_m4_m4_safe(float Ainv[4][4], const float A[4][4])
+void zero_axis_bias_m4(float mat[4][4])
+{
+ const bool axis_x_degenerate = len_squared_v3(mat[0]) < FLT_EPSILON;
+ const bool axis_y_degenerate = len_squared_v3(mat[1]) < FLT_EPSILON;
+ const bool axis_z_degenerate = len_squared_v3(mat[2]) < FLT_EPSILON;
+
+ /* X Axis. */
+ if (axis_x_degenerate && !axis_y_degenerate && !axis_z_degenerate) {
+ cross_v3_v3v3(mat[0], mat[1], mat[2]);
+ mul_v3_fl(mat[0], FLT_EPSILON);
+ return;
+ }
+
+ /* Y Axis. */
+ if (!axis_x_degenerate && axis_y_degenerate && !axis_z_degenerate) {
+ cross_v3_v3v3(mat[1], mat[2], mat[0]);
+ mul_v3_fl(mat[1], FLT_EPSILON);
+ return;
+ }
+
+ /* Z Axis. */
+ if (!axis_x_degenerate && !axis_y_degenerate && axis_z_degenerate) {
+ cross_v3_v3v3(mat[2], mat[0], mat[1]);
+ mul_v3_fl(mat[2], FLT_EPSILON);
+ return;
+ }
+}
+
+void invert_m4_m4_safe(float inverse[4][4], const float mat[4][4])
{
- if (!invert_m4_m4(Ainv, A)) {
- float Atemp[4][4];
+ if (!invert_m4_m4(inverse, mat)) {
+ float mat_tmp[4][4];
- copy_m4_m4(Atemp, A);
+ copy_m4_m4(mat_tmp, mat);
/* Matrix is degenerate (e.g. 0 scale on some axis), ideally we should
* never be in this situation, but try to invert it anyway with tweak.
*/
- Atemp[0][0] += 1e-8f;
- Atemp[1][1] += 1e-8f;
- Atemp[2][2] += 1e-8f;
+ mat_tmp[0][0] += 1e-8f;
+ mat_tmp[1][1] += 1e-8f;
+ mat_tmp[2][2] += 1e-8f;
- if (!invert_m4_m4(Ainv, Atemp)) {
- unit_m4(Ainv);
+ if (!invert_m4_m4(inverse, mat_tmp)) {
+ unit_m4(inverse);
}
}
}
@@ -3157,24 +3179,24 @@ void invert_m4_m4_safe(float Ainv[4][4], const float A[4][4])
* where we want to specify the length of the degenerate axes.
* \{ */
-void invert_m4_m4_safe_ortho(float Ainv[4][4], const float A[4][4])
+void invert_m4_m4_safe_ortho(float inverse[4][4], const float mat[4][4])
{
- if (UNLIKELY(!invert_m4_m4(Ainv, A))) {
- float Atemp[4][4];
- copy_m4_m4(Atemp, A);
- if (UNLIKELY(!(orthogonalize_m4_zero_axes(Atemp, 1.0f) && invert_m4_m4(Ainv, Atemp)))) {
- unit_m4(Ainv);
+ if (UNLIKELY(!invert_m4_m4(inverse, mat))) {
+ float mat_tmp[4][4];
+ copy_m4_m4(mat_tmp, mat);
+ if (UNLIKELY(!(orthogonalize_m4_zero_axes(mat_tmp, 1.0f) && invert_m4_m4(inverse, mat_tmp)))) {
+ unit_m4(inverse);
}
}
}
-void invert_m3_m3_safe_ortho(float Ainv[3][3], const float A[3][3])
+void invert_m3_m3_safe_ortho(float inverse[3][3], const float mat[3][3])
{
- if (UNLIKELY(!invert_m3_m3(Ainv, A))) {
- float Atemp[3][3];
- copy_m3_m3(Atemp, A);
- if (UNLIKELY(!(orthogonalize_m3_zero_axes(Atemp, 1.0f) && invert_m3_m3(Ainv, Atemp)))) {
- unit_m3(Ainv);
+ if (UNLIKELY(!invert_m3_m3(inverse, mat))) {
+ float mat_tmp[3][3];
+ copy_m3_m3(mat_tmp, mat);
+ if (UNLIKELY(!(orthogonalize_m3_zero_axes(mat_tmp, 1.0f) && invert_m3_m3(inverse, mat_tmp)))) {
+ unit_m3(inverse);
}
}
}
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index f0bfc7c21e1..ff45bbee5c9 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -176,7 +176,7 @@ void quat_to_compatible_quat(float q[4], const float a[4], const float old[4])
}
}
-/* skip error check, currently only needed by mat3_to_quat_is_ok */
+/* Skip error check, currently only needed by #mat3_to_quat_legacy. */
static void quat_to_mat3_no_error(float m[3][3], const float q[4])
{
double q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc;
@@ -269,9 +269,11 @@ void quat_to_mat4(float m[4][4], const float q[4])
m[3][3] = 1.0f;
}
-void mat3_normalized_to_quat(float q[4], const float mat[3][3])
+void mat3_normalized_to_quat_fast(float q[4], const float mat[3][3])
{
BLI_ASSERT_UNIT_M3(mat);
+ /* Caller must ensure matrices aren't negative for valid results, see: T24291, T94231. */
+ BLI_assert(!is_negative_m3(mat));
/* Check the trace of the matrix - bad precision if close to -1. */
const float trace = mat[0][0] + mat[1][1] + mat[2][2];
@@ -332,34 +334,54 @@ void mat3_normalized_to_quat(float q[4], const float mat[3][3])
normalize_qt(q);
}
-void mat3_to_quat(float q[4], const float m[3][3])
-{
- float unit_mat[3][3];
- /* work on a copy */
- /* this is needed AND a 'normalize_qt' in the end */
- normalize_m3_m3(unit_mat, m);
- mat3_normalized_to_quat(q, unit_mat);
+static void mat3_normalized_to_quat_with_checks(float q[4], float mat[3][3])
+{
+ const float det = determinant_m3_array(mat);
+ if (UNLIKELY(!isfinite(det))) {
+ unit_m3(mat);
+ }
+ else if (UNLIKELY(det < 0.0f)) {
+ negate_m3(mat);
+ }
+ mat3_normalized_to_quat_fast(q, mat);
}
-void mat4_normalized_to_quat(float q[4], const float m[4][4])
+void mat3_normalized_to_quat(float q[4], const float mat[3][3])
{
- float mat3[3][3];
+ float unit_mat_abs[3][3];
+ copy_m3_m3(unit_mat_abs, mat);
+ mat3_normalized_to_quat_with_checks(q, unit_mat_abs);
+}
- copy_m3_m4(mat3, m);
- mat3_normalized_to_quat(q, mat3);
+void mat3_to_quat(float q[4], const float mat[3][3])
+{
+ float unit_mat_abs[3][3];
+ normalize_m3_m3(unit_mat_abs, mat);
+ mat3_normalized_to_quat_with_checks(q, unit_mat_abs);
}
-void mat4_to_quat(float q[4], const float m[4][4])
+void mat4_normalized_to_quat(float q[4], const float mat[4][4])
{
- float mat3[3][3];
+ float unit_mat_abs[3][3];
+ copy_m3_m4(unit_mat_abs, mat);
+ mat3_normalized_to_quat_with_checks(q, unit_mat_abs);
+}
- copy_m3_m4(mat3, m);
- mat3_to_quat(q, mat3);
+void mat4_to_quat(float q[4], const float mat[4][4])
+{
+ float unit_mat_abs[3][3];
+ copy_m3_m4(unit_mat_abs, mat);
+ normalize_m3(unit_mat_abs);
+ mat3_normalized_to_quat_with_checks(q, unit_mat_abs);
}
-void mat3_to_quat_is_ok(float q[4], const float wmat[3][3])
+void mat3_to_quat_legacy(float q[4], const float wmat[3][3])
{
+ /* Legacy version of #mat3_to_quat which has slightly different behavior.
+ * Keep for particle-system & boids since replacing this will make subtle changes
+ * that impact hair in existing files. See: D15772. */
+
float mat[3][3], matr[3][3], matn[3][3], q1[4], q2[4], angle, si, co, nor[3];
/* work on a copy */
@@ -498,7 +520,10 @@ void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q
mul_qt_qtqt(q, tquat, q2);
}
-float quat_split_swing_and_twist(const float q_in[4], int axis, float r_swing[4], float r_twist[4])
+float quat_split_swing_and_twist(const float q_in[4],
+ const int axis,
+ float r_swing[4],
+ float r_twist[4])
{
BLI_assert(axis >= 0 && axis <= 2);
@@ -915,53 +940,63 @@ float tri_to_quat(float q[4], const float a[3], const float b[3], const float c[
return len;
}
-void sin_cos_from_fraction(const int numerator, const int denominator, float *r_sin, float *r_cos)
+void sin_cos_from_fraction(int numerator, int denominator, float *r_sin, float *r_cos)
{
- BLI_assert((numerator <= denominator) && (denominator > 0));
- if ((denominator & 3) == 0) {
- const int denominator_4 = denominator / 4;
- if (numerator <= denominator_4) {
- /* Fall through. */
- }
- else {
- if (numerator <= denominator_4 * 2) {
- const float phi = (float)(2.0 * M_PI) *
- ((float)(numerator - denominator_4) / (float)denominator);
- *r_sin = cosf(phi);
- *r_cos = -sinf(phi);
- }
- else if (numerator <= denominator_4 * 3) {
- const float phi = (float)(2.0 * M_PI) *
- ((float)(numerator - (denominator_4 * 2)) / (float)denominator);
- *r_sin = -sinf(phi);
- *r_cos = -cosf(phi);
- }
- else {
- const float phi = (float)(2.0 * M_PI) *
- ((float)(numerator - (denominator_4 * 3)) / (float)denominator);
- *r_cos = sinf(phi);
- *r_sin = -cosf(phi);
- }
- return;
- }
- }
- else if ((denominator & 1) == 0) {
- const int denominator_2 = denominator / 2;
- if (numerator <= denominator_2) {
- /* Fall through. */
- }
- else {
- const float phi = (float)(2.0 * M_PI) *
- ((float)(numerator - denominator_2) / (float)denominator);
- *r_sin = -sinf(phi);
- *r_cos = -cosf(phi);
- return;
- }
+ /* By default, creating a circle from an integer: calling #sinf & #cosf on the fraction doesn't
+ * create symmetrical values (because floats can't represent Pi exactly).
+ * Resolve this when the rotation is calculated from a fraction by mapping the `numerator`
+ * to lower values so X/Y values for points around a circle are exactly symmetrical, see T87779.
+ *
+ * Multiply both the `numerator` and `denominator` by eight to ensure we can divide the circle
+ * into 8 octants. For each octant, we then use symmetry and negation to bring the `numerator`
+ * closer to the origin where precision is highest.
+ *
+ * Cases 2, 4, 5 and 7, use the trigonometric identity sin(-x) == -sin(x).
+ * Cases 1, 2, 5 and 6, swap the pointers `r_sin` and `r_cos`.
+ */
+ BLI_assert(0 <= numerator);
+ BLI_assert(numerator <= denominator);
+ BLI_assert(denominator > 0);
+
+ numerator *= 8; /* Multiply numerator the same as denominator. */
+ const int octant = numerator / denominator; /* Determine the octant. */
+ denominator *= 8; /* Ensure denominator is a multiple of eight. */
+ float cos_sign = 1.0f; /* Either 1.0f or -1.0f. */
+
+ switch (octant) {
+ case 0:
+ /* Primary octant, nothing to do. */
+ break;
+ case 1:
+ case 2:
+ numerator = (denominator / 4) - numerator;
+ SWAP(float *, r_sin, r_cos);
+ break;
+ case 3:
+ case 4:
+ numerator = (denominator / 2) - numerator;
+ cos_sign = -1.0f;
+ break;
+ case 5:
+ case 6:
+ numerator = numerator - (denominator * 3 / 4);
+ SWAP(float *, r_sin, r_cos);
+ cos_sign = -1.0f;
+ break;
+ case 7:
+ numerator = numerator - denominator;
+ break;
+ default:
+ BLI_assert_unreachable();
}
- const float phi = (float)(2.0 * M_PI) * ((float)numerator / (float)denominator);
- *r_sin = sinf(phi);
- *r_cos = cosf(phi);
+ BLI_assert(-denominator / 4 <= numerator); /* Numerator may be negative. */
+ BLI_assert(numerator <= denominator / 4);
+ BLI_assert(cos_sign == -1.0f || cos_sign == 1.0f);
+
+ const float angle = (float)(2.0 * M_PI) * ((float)numerator / (float)denominator);
+ *r_sin = sinf(angle);
+ *r_cos = cosf(angle) * cos_sign;
}
void print_qt(const char *str, const float q[4])
@@ -1371,10 +1406,10 @@ void mat4_normalized_to_eul(float eul[3], const float m[4][4])
copy_m3_m4(mat3, m);
mat3_normalized_to_eul(eul, mat3);
}
-void mat4_to_eul(float eul[3], const float m[4][4])
+void mat4_to_eul(float eul[3], const float mat[4][4])
{
float mat3[3][3];
- copy_m3_m4(mat3, m);
+ copy_m3_m4(mat3, mat);
mat3_to_eul(eul, mat3);
}
@@ -1409,7 +1444,7 @@ void eul_to_quat(float quat[4], const float eul[3])
quat[3] = cj * cs - sj * sc;
}
-void rotate_eul(float beul[3], const char axis, const float ang)
+void rotate_eul(float beul[3], const char axis, const float angle)
{
float eul[3], mat1[3][3], mat2[3][3], totmat[3][3];
@@ -1417,13 +1452,13 @@ void rotate_eul(float beul[3], const char axis, const float ang)
eul[0] = eul[1] = eul[2] = 0.0f;
if (axis == 'X') {
- eul[0] = ang;
+ eul[0] = angle;
}
else if (axis == 'Y') {
- eul[1] = ang;
+ eul[1] = angle;
}
else {
- eul[2] = ang;
+ eul[2] = angle;
}
eul_to_mat3(mat1, eul);
@@ -1442,7 +1477,7 @@ void compatible_eul(float eul[3], const float oldrot[3])
const float pi_x2 = (2.0f * (float)M_PI);
float deul[3];
- unsigned int i;
+ uint i;
/* correct differences of about 360 degrees first */
for (i = 0; i < 3; i++) {
@@ -1779,23 +1814,23 @@ void mat3_to_compatible_eulO(float eul[3],
void mat4_normalized_to_compatible_eulO(float eul[3],
const float oldrot[3],
const short order,
- const float m[4][4])
+ const float mat[4][4])
{
float mat3[3][3];
/* for now, we'll just do this the slow way (i.e. copying matrices) */
- copy_m3_m4(mat3, m);
+ copy_m3_m4(mat3, mat);
mat3_normalized_to_compatible_eulO(eul, oldrot, order, mat3);
}
void mat4_to_compatible_eulO(float eul[3],
const float oldrot[3],
const short order,
- const float m[4][4])
+ const float mat[4][4])
{
float mat3[3][3];
/* for now, we'll just do this the slow way (i.e. copying matrices) */
- copy_m3_m4(mat3, m);
+ copy_m3_m4(mat3, mat);
normalize_m3(mat3);
mat3_normalized_to_compatible_eulO(eul, oldrot, order, mat3);
}
@@ -1814,7 +1849,7 @@ void quat_to_compatible_eulO(float eul[3],
/* rotate the given euler by the given angle on the specified axis */
/* NOTE: is this safe to do with different axis orders? */
-void rotate_eulO(float beul[3], const short order, char axis, float ang)
+void rotate_eulO(float beul[3], const short order, const char axis, const float angle)
{
float eul[3], mat1[3][3], mat2[3][3], totmat[3][3];
@@ -1823,13 +1858,13 @@ void rotate_eulO(float beul[3], const short order, char axis, float ang)
zero_v3(eul);
if (axis == 'X') {
- eul[0] = ang;
+ eul[0] = angle;
}
else if (axis == 'Y') {
- eul[1] = ang;
+ eul[1] = angle;
}
else {
- eul[2] = ang;
+ eul[2] = angle;
}
eulO_to_mat3(mat1, eul, order);
@@ -2143,8 +2178,8 @@ void quat_apply_track(float quat[4], short axis, short upflag)
* up axis is used X->Y, Y->X, Z->X, if this first up axis isn't used then rotate 90d
* the strange bit shift below just find the low axis {X:Y, Y:X, Z:X} */
if (upflag != (2 - axis) >> 1) {
- float q[4] = {sqrt_1_2, 0.0, 0.0, 0.0}; /* assign 90d rotation axis */
- q[axis + 1] = ((axis == 1)) ? sqrt_1_2 : -sqrt_1_2; /* flip non Y axis */
+ float q[4] = {sqrt_1_2, 0.0, 0.0, 0.0}; /* assign 90d rotation axis */
+ q[axis + 1] = (axis == 1) ? sqrt_1_2 : -sqrt_1_2; /* flip non Y axis */
mul_qt_qtqt(quat, quat, q);
}
}
@@ -2325,8 +2360,8 @@ bool mat3_from_axis_conversion(
value = ((src_forward << (0 * 3)) | (src_up << (1 * 3)) | (dst_forward << (2 * 3)) |
(dst_up << (3 * 3)));
- for (uint i = 0; i < (ARRAY_SIZE(_axis_convert_matrix)); i++) {
- for (uint j = 0; j < (ARRAY_SIZE(*_axis_convert_lut)); j++) {
+ for (uint i = 0; i < ARRAY_SIZE(_axis_convert_matrix); i++) {
+ for (uint j = 0; j < ARRAY_SIZE(*_axis_convert_lut); j++) {
if (_axis_convert_lut[i][j] == value) {
copy_m3_m3(r_mat, _axis_convert_matrix[i]);
return true;
diff --git a/source/blender/blenlib/intern/math_solvers.c b/source/blender/blenlib/intern/math_solvers.c
index b5650410a70..1196c0bed7f 100644
--- a/source/blender/blenlib/intern/math_solvers.c
+++ b/source/blender/blenlib/intern/math_solvers.c
@@ -45,7 +45,7 @@ bool BLI_tridiagonal_solve(
return false;
}
- size_t bytes = sizeof(double) * (unsigned)count;
+ size_t bytes = sizeof(double) * (uint)count;
double *c1 = (double *)MEM_mallocN(bytes * 2, "tridiagonal_c1d1");
double *d1 = c1 + count;
@@ -112,7 +112,7 @@ bool BLI_tridiagonal_solve_cyclic(
return BLI_tridiagonal_solve(a, b, c, d, r_x, count);
}
- size_t bytes = sizeof(float) * (unsigned)count;
+ size_t bytes = sizeof(float) * (uint)count;
float *tmp = (float *)MEM_mallocN(bytes * 2, "tridiagonal_ex");
float *b2 = tmp + count;
diff --git a/source/blender/blenlib/intern/math_vec.cc b/source/blender/blenlib/intern/math_vec.cc
index 99c873299fe..8d1f850d8e5 100644
--- a/source/blender/blenlib/intern/math_vec.cc
+++ b/source/blender/blenlib/intern/math_vec.cc
@@ -108,7 +108,7 @@ isect_result<mpq2> isect_seg_seg(const mpq2 &v1, const mpq2 &v2, const mpq2 &v3,
uint64_t hash_mpq_class(const mpq_class &value)
{
/* TODO: better/faster implementation of this. */
- return get_default_hash(static_cast<float>(value.get_d()));
+ return get_default_hash(float(value.get_d()));
}
#endif
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index 5dcdabaf760..f65a5acceae 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -499,7 +499,7 @@ float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const f
/* calculate the sign (reuse 'tproj') */
cross_v3_v3v3(tproj, v2_proj, v1_proj);
if (dot_v3v3(tproj, axis) < 0.0f) {
- angle = ((float)(M_PI * 2.0)) - angle;
+ angle = (float)(M_PI * 2.0) - angle;
}
return angle;
diff --git a/source/blender/blenlib/intern/mesh_boolean.cc b/source/blender/blenlib/intern/mesh_boolean.cc
index 700c126ca4c..3efe62d2984 100644
--- a/source/blender/blenlib/intern/mesh_boolean.cc
+++ b/source/blender/blenlib/intern/mesh_boolean.cc
@@ -1675,7 +1675,7 @@ static Edge find_good_sorting_edge(const Vert *testp,
* The algorithm is similar to the one for find_ambient_cell, except that
* instead of an arbitrary point known to be outside the whole mesh, we
* have a particular point (v) and we just want to determine the patches
- * that that point is between in sorting-around-an-edge order.
+ * that point is between in sorting-around-an-edge order.
*/
static int find_containing_cell(const Vert *v,
int t,
@@ -2527,7 +2527,7 @@ class InsideShapeTestData {
static void inside_shape_callback(void *userdata,
int index,
const BVHTreeRay *ray,
- BVHTreeRayHit *UNUSED(hit))
+ BVHTreeRayHit * /*hit*/)
{
const int dbg_level = 0;
if (dbg_level > 0) {
@@ -2966,6 +2966,11 @@ static std::ostream &operator<<(std::ostream &os, const FaceMergeState &fms)
* \a tris all have the same original face.
* Find the 2d edge/triangle topology for these triangles, but only the ones facing in the
* norm direction, and whether each edge is dissolvable or not.
+ * If we did the initial triangulation properly, and any Delaunay triangulations of intersections
+ * properly, then each triangle edge should have at most one neighbor.
+ * However, there can be anomalies. For example, if an input face is self-intersecting, we fall
+ * back on the floating point poly-fill triangulation, which, after which all bets are off.
+ * Hence, try to be tolerant of such unexpected topology.
*/
static void init_face_merge_state(FaceMergeState *fms,
const Vector<int> &tris,
@@ -3053,16 +3058,35 @@ static void init_face_merge_state(FaceMergeState *fms,
std::cout << "me.v1 == mf.vert[i] so set edge[" << me_index << "].left_face = " << f
<< "\n";
}
- BLI_assert(me.left_face == -1);
- fms->edge[me_index].left_face = f;
+ if (me.left_face != -1) {
+ /* Unexpected in the normal case: this means more than one triangle shares this
+ * edge in the same orientation. But be tolerant of this case. By making this
+ * edge not dissolvable, we'll avoid future problems due to this non-manifold topology.
+ */
+ if (dbg_level > 1) {
+ std::cout << "me.left_face was already occupied, so triangulation wasn't good\n";
+ }
+ me.dissolvable = false;
+ }
+ else {
+ fms->edge[me_index].left_face = f;
+ }
}
else {
if (dbg_level > 1) {
std::cout << "me.v1 != mf.vert[i] so set edge[" << me_index << "].right_face = " << f
<< "\n";
}
- BLI_assert(me.right_face == -1);
- fms->edge[me_index].right_face = f;
+ if (me.right_face != -1) {
+ /* Unexpected, analogous to the me.left_face != -1 case above. */
+ if (dbg_level > 1) {
+ std::cout << "me.right_face was already occupied, so triangulation wasn't good\n";
+ }
+ me.dissolvable = false;
+ }
+ else {
+ fms->edge[me_index].right_face = f;
+ }
}
fms->face[f].edge.append(me_index);
}
diff --git a/source/blender/blenlib/intern/mesh_intersect.cc b/source/blender/blenlib/intern/mesh_intersect.cc
index d5585f953ec..ee29662698a 100644
--- a/source/blender/blenlib/intern/mesh_intersect.cc
+++ b/source/blender/blenlib/intern/mesh_intersect.cc
@@ -710,7 +710,7 @@ bool IMesh::erase_face_positions(int f_index, Span<bool> face_pos_erase, IMeshAr
* mark with null pointer and caller should call remove_null_faces().
* the loop is done.
*/
- this->face_[f_index] = NULL;
+ this->face_[f_index] = nullptr;
return true;
}
Array<const Vert *> new_vert(new_len);
@@ -829,13 +829,13 @@ struct BBPadData {
static void pad_face_bb_range_func(void *__restrict userdata,
const int iter,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
BBPadData *pad_data = static_cast<BBPadData *>(userdata);
(*pad_data->face_bounding_box)[iter].expand(pad_data->pad);
}
-static void calc_face_bb_reduce(const void *__restrict UNUSED(userdata),
+static void calc_face_bb_reduce(const void *__restrict /*userdata*/,
void *__restrict chunk_join,
void *__restrict chunk)
{
@@ -2032,10 +2032,10 @@ static Array<Face *> polyfill_triangulate_poly(Face *f, IMeshArena *arena)
}
/* Project along negative face normal so (x,y) can be used in 2d. */ float axis_mat[3][3];
float(*projverts)[2];
- unsigned int(*tris)[3];
+ uint(*tris)[3];
const int totfilltri = flen - 2;
/* Prepare projected vertices and array to receive triangles in tessellation. */
- tris = static_cast<unsigned int(*)[3]>(MEM_malloc_arrayN(totfilltri, sizeof(*tris), __func__));
+ tris = static_cast<uint(*)[3]>(MEM_malloc_arrayN(totfilltri, sizeof(*tris), __func__));
projverts = static_cast<float(*)[2]>(MEM_malloc_arrayN(flen, sizeof(*projverts), __func__));
axis_dominant_v3_to_m3_negate(axis_mat, no);
for (int j = 0; j < flen; ++j) {
@@ -2047,7 +2047,7 @@ static Array<Face *> polyfill_triangulate_poly(Face *f, IMeshArena *arena)
/* Put tessellation triangles into Face form. Record original edges where they exist. */
Array<Face *> ans(totfilltri);
for (int t = 0; t < totfilltri; ++t) {
- unsigned int *tri = tris[t];
+ uint *tri = tris[t];
int eo[3];
const Vert *v[3];
for (int k = 0; k < 3; k++) {
@@ -2419,7 +2419,7 @@ class TriOverlaps {
}
}
first_overlap_ = Array<int>(tm.face_size(), -1);
- for (int i = 0; i < static_cast<int>(overlap_num_); ++i) {
+ for (int i = 0; i < int(overlap_num_); ++i) {
int t = overlap_[i].indexA;
if (first_overlap_[t] == -1) {
first_overlap_[t] = i;
@@ -2451,7 +2451,7 @@ class TriOverlaps {
}
private:
- static bool only_different_shapes(void *userdata, int index_a, int index_b, int UNUSED(thread))
+ static bool only_different_shapes(void *userdata, int index_a, int index_b, int /*thread*/)
{
CBData *cbdata = static_cast<CBData *>(userdata);
return cbdata->tm.face(index_a)->orig != cbdata->tm.face(index_b)->orig;
@@ -2487,7 +2487,7 @@ static std::pair<int, int> canon_int_pair(int a, int b)
static void calc_overlap_itts_range_func(void *__restrict userdata,
const int iter,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
constexpr int dbg_level = 0;
OverlapIttsData *data = static_cast<OverlapIttsData *>(userdata);
@@ -2682,7 +2682,7 @@ static CDT_data calc_cluster_subdivided(const CoplanarClusterInfo &clinfo,
const IMesh &tm,
const TriOverlaps &ov,
const Map<std::pair<int, int>, ITT_value> &itt_map,
- IMeshArena *UNUSED(arena))
+ IMeshArena * /*arena*/)
{
constexpr int dbg_level = 0;
BLI_assert(c < clinfo.tot_cluster());
@@ -2889,7 +2889,7 @@ static void degenerate_range_func(void *__restrict userdata,
chunk_data->has_degenerate_tri |= is_degenerate;
}
-static void degenerate_reduce(const void *__restrict UNUSED(userdata),
+static void degenerate_reduce(const void *__restrict /*userdata*/,
void *__restrict chunk_join,
void *__restrict chunk)
{
@@ -2931,7 +2931,7 @@ static IMesh remove_degenerate_tris(const IMesh &tm_in)
IMesh trimesh_self_intersect(const IMesh &tm_in, IMeshArena *arena)
{
return trimesh_nary_intersect(
- tm_in, 1, [](int UNUSED(t)) { return 0; }, true, arena);
+ tm_in, 1, [](int /*t*/) { return 0; }, true, arena);
}
IMesh trimesh_nary_intersect(const IMesh &tm_in,
diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c
index c39a2b5a27e..8da35e5ab56 100644
--- a/source/blender/blenlib/intern/noise.c
+++ b/source/blender/blenlib/intern/noise.c
@@ -115,8 +115,8 @@ static const float hashpntf[768] = {
0.713870, 0.555261, 0.951333,
};
-extern const unsigned char BLI_noise_hash_uchar_512[512]; /* Quiet warning. */
-const unsigned char BLI_noise_hash_uchar_512[512] = {
+extern const uchar BLI_noise_hash_uchar_512[512]; /* Quiet warning. */
+const uchar BLI_noise_hash_uchar_512[512] = {
0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE,
0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32,
0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7,
@@ -939,9 +939,9 @@ void BLI_noise_voronoi(float x, float y, float z, float *da, float *pa, float me
break;
}
- int xi = (int)(floor(x));
- int yi = (int)(floor(y));
- int zi = (int)(floor(z));
+ int xi = (int)floor(x);
+ int yi = (int)floor(y);
+ int zi = (int)floor(z);
da[0] = da[1] = da[2] = da[3] = 1e10f;
for (int xx = xi - 1; xx <= xi + 1; xx++) {
for (int yy = yi - 1; yy <= yi + 1; yy++) {
@@ -1112,10 +1112,10 @@ static float BLI_cellNoiseU(float x, float y, float z)
y = (y + 0.000001f) * 1.00001f;
z = (z + 0.000001f) * 1.00001f;
- int xi = (int)(floor(x));
- int yi = (int)(floor(y));
- int zi = (int)(floor(z));
- unsigned int n = xi + yi * 1301 + zi * 314159;
+ int xi = (int)floor(x);
+ int yi = (int)floor(y);
+ int zi = (int)floor(z);
+ uint n = xi + yi * 1301 + zi * 314159;
n ^= (n << 13);
return ((float)(n * (n * n * 15731 + 789221) + 1376312589) / 4294967296.0f);
}
@@ -1125,20 +1125,20 @@ float BLI_noise_cell(float x, float y, float z)
return (2.0f * BLI_cellNoiseU(x, y, z) - 1.0f);
}
-void BLI_noise_cell_v3(float x, float y, float z, float ca[3])
+void BLI_noise_cell_v3(float x, float y, float z, float r_ca[3])
{
/* avoid precision issues on unit coordinates */
x = (x + 0.000001f) * 1.00001f;
y = (y + 0.000001f) * 1.00001f;
z = (z + 0.000001f) * 1.00001f;
- int xi = (int)(floor(x));
- int yi = (int)(floor(y));
- int zi = (int)(floor(z));
+ int xi = (int)floor(x);
+ int yi = (int)floor(y);
+ int zi = (int)floor(z);
const float *p = HASHPNT(xi, yi, zi);
- ca[0] = p[0];
- ca[1] = p[1];
- ca[2] = p[2];
+ r_ca[0] = p[0];
+ r_ca[1] = p[1];
+ r_ca[2] = p[2];
}
/** \} */
@@ -1329,8 +1329,8 @@ float BLI_noise_mg_fbm(
float BLI_noise_mg_multi_fractal(
float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis)
{
- /* This one is in fact rather confusing,
- * there seem to be errors in the original source code (in all three versions of proc.text&mod),
+ /* This one is in fact rather confusing, there seem to be errors in the original source code
+ * (in all three versions of `proc.text & mod`),
* I modified it to something that made sense to me, so it might be wrong. */
float (*noisefunc)(float, float, float);
diff --git a/source/blender/blenlib/intern/noise.cc b/source/blender/blenlib/intern/noise.cc
index a514c9e5183..65a6f102a7b 100644
--- a/source/blender/blenlib/intern/noise.cc
+++ b/source/blender/blenlib/intern/noise.cc
@@ -150,7 +150,7 @@ uint32_t hash_float(float4 k)
BLI_INLINE float uint_to_float_01(uint32_t k)
{
- return static_cast<float>(k) / static_cast<float>(0xFFFFFFFFu);
+ return float(k) / float(0xFFFFFFFFu);
}
float hash_to_float(uint32_t kx)
@@ -263,7 +263,6 @@ BLI_INLINE float mix(float v0, float v1, float x)
* + + |
* @ + + + + @ @------> x
* v0 v1
- *
*/
BLI_INLINE float mix(float v0, float v1, float v2, float v3, float x, float y)
{
@@ -380,7 +379,7 @@ BLI_INLINE float noise_grad(uint32_t hash, float x, float y, float z, float w)
BLI_INLINE float floor_fraction(float x, int &i)
{
- i = (int)x - ((x < 0) ? 1 : 0);
+ i = int(x) - ((x < 0) ? 1 : 0);
return x - i;
}
@@ -537,7 +536,7 @@ template<typename T> float perlin_fractal_template(T position, float octaves, fl
float maxamp = 0.0f;
float sum = 0.0f;
octaves = CLAMPIS(octaves, 0.0f, 15.0f);
- int n = static_cast<int>(octaves);
+ int n = int(octaves);
for (int i = 0; i <= n; i++) {
float t = perlin(fscale * position);
sum += t * amp;
@@ -730,7 +729,7 @@ float musgrave_fBm(const float co,
const float pwHL = std::pow(lacunarity, -H);
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; i < (int)octaves; i++) {
+ for (int i = 0; i < int(octaves); i++) {
value += perlin_signed(p) * pwr;
pwr *= pwHL;
p *= lacunarity;
@@ -755,7 +754,7 @@ float musgrave_multi_fractal(const float co,
const float pwHL = std::pow(lacunarity, -H);
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; i < (int)octaves; i++) {
+ for (int i = 0; i < int(octaves); i++) {
value *= (pwr * perlin_signed(p) + 1.0f);
pwr *= pwHL;
p *= lacunarity;
@@ -784,7 +783,7 @@ float musgrave_hetero_terrain(const float co,
float value = offset + perlin_signed(p);
p *= lacunarity;
- for (int i = 1; i < (int)octaves; i++) {
+ for (int i = 1; i < int(octaves); i++) {
float increment = (perlin_signed(p) + offset) * pwr * value;
value += increment;
pwr *= pwHL;
@@ -809,15 +808,14 @@ float musgrave_hybrid_multi_fractal(const float co,
{
float p = co;
const float pwHL = std::pow(lacunarity, -H);
- float pwr = pwHL;
- float value = perlin_signed(p) + offset;
- float weight = gain * value;
- p *= lacunarity;
+ float pwr = 1.0f;
+ float value = 0.0f;
+ float weight = 1.0f;
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 1; (weight > 0.001f) && (i < (int)octaves); i++) {
+ for (int i = 0; (weight > 0.001f) && (i < int(octaves)); i++) {
if (weight > 1.0f) {
weight = 1.0f;
}
@@ -830,8 +828,12 @@ float musgrave_hybrid_multi_fractal(const float co,
}
const float rmd = octaves - floorf(octaves);
- if (rmd != 0.0f) {
- value += rmd * ((perlin_signed(p) + offset) * pwr);
+ if ((rmd != 0.0f) && (weight > 0.001f)) {
+ if (weight > 1.0f) {
+ weight = 1.0f;
+ }
+ float signal = (perlin_signed(p) + offset) * pwr;
+ value += rmd * weight * signal;
}
return value;
@@ -855,7 +857,7 @@ float musgrave_ridged_multi_fractal(const float co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 1; i < (int)octaves; i++) {
+ for (int i = 1; i < int(octaves); i++) {
p *= lacunarity;
weight = CLAMPIS(signal * gain, 0.0f, 1.0f);
signal = offset - std::abs(perlin_signed(p));
@@ -881,7 +883,7 @@ float musgrave_fBm(const float2 co,
const float pwHL = std::pow(lacunarity, -H);
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; i < (int)octaves; i++) {
+ for (int i = 0; i < int(octaves); i++) {
value += perlin_signed(p) * pwr;
pwr *= pwHL;
p *= lacunarity;
@@ -906,7 +908,7 @@ float musgrave_multi_fractal(const float2 co,
const float pwHL = std::pow(lacunarity, -H);
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; i < (int)octaves; i++) {
+ for (int i = 0; i < int(octaves); i++) {
value *= (pwr * perlin_signed(p) + 1.0f);
pwr *= pwHL;
p *= lacunarity;
@@ -936,7 +938,7 @@ float musgrave_hetero_terrain(const float2 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 1; i < (int)octaves; i++) {
+ for (int i = 1; i < int(octaves); i++) {
float increment = (perlin_signed(p) + offset) * pwr * value;
value += increment;
pwr *= pwHL;
@@ -961,15 +963,14 @@ float musgrave_hybrid_multi_fractal(const float2 co,
{
float2 p = co;
const float pwHL = std::pow(lacunarity, -H);
- float pwr = pwHL;
- float value = perlin_signed(p) + offset;
- float weight = gain * value;
- p *= lacunarity;
+ float pwr = 1.0f;
+ float value = 0.0f;
+ float weight = 1.0f;
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 1; (weight > 0.001f) && (i < (int)octaves); i++) {
+ for (int i = 0; (weight > 0.001f) && (i < int(octaves)); i++) {
if (weight > 1.0f) {
weight = 1.0f;
}
@@ -982,8 +983,12 @@ float musgrave_hybrid_multi_fractal(const float2 co,
}
const float rmd = octaves - floorf(octaves);
- if (rmd != 0.0f) {
- value += rmd * ((perlin_signed(p) + offset) * pwr);
+ if ((rmd != 0.0f) && (weight > 0.001f)) {
+ if (weight > 1.0f) {
+ weight = 1.0f;
+ }
+ float signal = (perlin_signed(p) + offset) * pwr;
+ value += rmd * weight * signal;
}
return value;
@@ -1007,7 +1012,7 @@ float musgrave_ridged_multi_fractal(const float2 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 1; i < (int)octaves; i++) {
+ for (int i = 1; i < int(octaves); i++) {
p *= lacunarity;
weight = CLAMPIS(signal * gain, 0.0f, 1.0f);
signal = offset - std::abs(perlin_signed(p));
@@ -1034,7 +1039,7 @@ float musgrave_fBm(const float3 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; i < (int)octaves; i++) {
+ for (int i = 0; i < int(octaves); i++) {
value += perlin_signed(p) * pwr;
pwr *= pwHL;
p *= lacunarity;
@@ -1060,7 +1065,7 @@ float musgrave_multi_fractal(const float3 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; i < (int)octaves; i++) {
+ for (int i = 0; i < int(octaves); i++) {
value *= (pwr * perlin_signed(p) + 1.0f);
pwr *= pwHL;
p *= lacunarity;
@@ -1090,7 +1095,7 @@ float musgrave_hetero_terrain(const float3 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 1; i < (int)octaves; i++) {
+ for (int i = 1; i < int(octaves); i++) {
float increment = (perlin_signed(p) + offset) * pwr * value;
value += increment;
pwr *= pwHL;
@@ -1115,15 +1120,14 @@ float musgrave_hybrid_multi_fractal(const float3 co,
{
float3 p = co;
const float pwHL = std::pow(lacunarity, -H);
- float pwr = pwHL;
- float value = perlin_signed(p) + offset;
- float weight = gain * value;
- p *= lacunarity;
+ float pwr = 1.0f;
+ float value = 0.0f;
+ float weight = 1.0f;
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 1; (weight > 0.001f) && (i < (int)octaves); i++) {
+ for (int i = 0; (weight > 0.001f) && (i < int(octaves)); i++) {
if (weight > 1.0f) {
weight = 1.0f;
}
@@ -1136,8 +1140,12 @@ float musgrave_hybrid_multi_fractal(const float3 co,
}
const float rmd = octaves - floorf(octaves);
- if (rmd != 0.0f) {
- value += rmd * ((perlin_signed(p) + offset) * pwr);
+ if ((rmd != 0.0f) && (weight > 0.001f)) {
+ if (weight > 1.0f) {
+ weight = 1.0f;
+ }
+ float signal = (perlin_signed(p) + offset) * pwr;
+ value += rmd * weight * signal;
}
return value;
@@ -1161,7 +1169,7 @@ float musgrave_ridged_multi_fractal(const float3 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 1; i < (int)octaves; i++) {
+ for (int i = 1; i < int(octaves); i++) {
p *= lacunarity;
weight = CLAMPIS(signal * gain, 0.0f, 1.0f);
signal = offset - std::abs(perlin_signed(p));
@@ -1188,7 +1196,7 @@ float musgrave_fBm(const float4 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; i < (int)octaves; i++) {
+ for (int i = 0; i < int(octaves); i++) {
value += perlin_signed(p) * pwr;
pwr *= pwHL;
p *= lacunarity;
@@ -1214,7 +1222,7 @@ float musgrave_multi_fractal(const float4 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 0; i < (int)octaves; i++) {
+ for (int i = 0; i < int(octaves); i++) {
value *= (pwr * perlin_signed(p) + 1.0f);
pwr *= pwHL;
p *= lacunarity;
@@ -1244,7 +1252,7 @@ float musgrave_hetero_terrain(const float4 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 1; i < (int)octaves; i++) {
+ for (int i = 1; i < int(octaves); i++) {
float increment = (perlin_signed(p) + offset) * pwr * value;
value += increment;
pwr *= pwHL;
@@ -1269,15 +1277,14 @@ float musgrave_hybrid_multi_fractal(const float4 co,
{
float4 p = co;
const float pwHL = std::pow(lacunarity, -H);
- float pwr = pwHL;
- float value = perlin_signed(p) + offset;
- float weight = gain * value;
- p *= lacunarity;
+ float pwr = 1.0f;
+ float value = 0.0f;
+ float weight = 1.0f;
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 1; (weight > 0.001f) && (i < (int)octaves); i++) {
+ for (int i = 0; (weight > 0.001f) && (i < int(octaves)); i++) {
if (weight > 1.0f) {
weight = 1.0f;
}
@@ -1290,8 +1297,12 @@ float musgrave_hybrid_multi_fractal(const float4 co,
}
const float rmd = octaves - floorf(octaves);
- if (rmd != 0.0f) {
- value += rmd * ((perlin_signed(p) + offset) * pwr);
+ if ((rmd != 0.0f) && (weight > 0.001f)) {
+ if (weight > 1.0f) {
+ weight = 1.0f;
+ }
+ float signal = (perlin_signed(p) + offset) * pwr;
+ value += rmd * weight * signal;
}
return value;
@@ -1315,7 +1326,7 @@ float musgrave_ridged_multi_fractal(const float4 co,
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
- for (int i = 1; i < (int)octaves; i++) {
+ for (int i = 1; i < int(octaves); i++) {
p *= lacunarity;
weight = CLAMPIS(signal * gain, 0.0f, 1.0f);
signal = offset - std::abs(perlin_signed(p));
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 5a96221c8d1..afe8c3cc033 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -121,7 +121,7 @@ int BLI_path_sequence_decode(const char *string, char *head, char *tail, ushort
}
void BLI_path_sequence_encode(
- char *string, const char *head, const char *tail, unsigned short numlen, int pic)
+ char *string, const char *head, const char *tail, ushort numlen, int pic)
{
sprintf(string, "%s%.*d%s", head, numlen, MAX2(0, pic), tail);
}
@@ -466,8 +466,8 @@ void BLI_path_rel(char *file, const char *relfile)
#ifdef WIN32
if (BLI_strnlen(relfile, 3) > 2 && !BLI_path_is_abs(relfile)) {
char *ptemp;
- /* fix missing volume name in relative base,
- * can happen with old recent-files.txt files */
+ /* Fix missing volume name in relative base,
+ * can happen with old `recent-files.txt` files. */
BLI_windows_get_default_root_dir(temp);
ptemp = &temp[2];
if (!ELEM(relfile[0], '\\', '/')) {
@@ -625,7 +625,7 @@ bool BLI_path_parent_dir(char *path)
const char parent_dir[] = {'.', '.', SEP, '\0'}; /* "../" or "..\\" */
char tmp[FILE_MAX + 4];
- BLI_join_dirfile(tmp, sizeof(tmp), path, parent_dir);
+ BLI_path_join(tmp, sizeof(tmp), path, parent_dir);
BLI_path_normalize(NULL, tmp); /* does all the work of normalizing the path for us */
if (!BLI_path_extension_check(tmp, parent_dir)) {
@@ -1025,7 +1025,7 @@ bool BLI_path_abs_from_cwd(char *path, const size_t maxlen)
if (BLI_current_working_dir(cwd, sizeof(cwd))) {
char origpath[FILE_MAX];
BLI_strncpy(origpath, path, FILE_MAX);
- BLI_join_dirfile(path, maxlen, cwd, origpath);
+ BLI_path_join(path, maxlen, cwd, origpath);
}
else {
printf("Could not get the current working directory - $PWD for an unknown reason.\n");
@@ -1105,29 +1105,29 @@ bool BLI_path_program_search(char *fullname, const size_t maxlen, const char *na
path = BLI_getenv("PATH");
if (path) {
- char filename[FILE_MAX];
+ char filepath_test[FILE_MAX];
const char *temp;
do {
temp = strchr(path, separator);
if (temp) {
- memcpy(filename, path, temp - path);
- filename[temp - path] = 0;
+ memcpy(filepath_test, path, temp - path);
+ filepath_test[temp - path] = 0;
path = temp + 1;
}
else {
- BLI_strncpy(filename, path, sizeof(filename));
+ BLI_strncpy(filepath_test, path, sizeof(filepath_test));
}
- BLI_path_append(filename, maxlen, name);
+ BLI_path_append(filepath_test, maxlen, name);
if (
#ifdef _WIN32
- BLI_path_program_extensions_add_win32(filename, maxlen)
+ BLI_path_program_extensions_add_win32(filepath_test, maxlen)
#else
- BLI_exists(filename)
+ BLI_exists(filepath_test)
#endif
) {
- BLI_strncpy(fullname, filename, maxlen);
+ BLI_strncpy(fullname, filepath_test, maxlen);
retval = true;
break;
}
@@ -1204,87 +1204,6 @@ bool BLI_make_existing_file(const char *name)
return BLI_dir_create_recursive(di);
}
-void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file)
-{
- int sl;
-
- if (string) {
- /* ensure this is always set even if dir/file are NULL */
- string[0] = '\0';
-
- if (ELEM(NULL, dir, file)) {
- return; /* We don't want any NULLs */
- }
- }
- else {
- return; /* string is NULL, probably shouldn't happen but return anyway */
- }
-
- /* Resolve relative references */
- if (relabase && dir[0] == '/' && dir[1] == '/') {
- char *lslash;
-
- /* Get the file name, chop everything past the last slash (ie. the filename) */
- strcpy(string, relabase);
-
- lslash = (char *)BLI_path_slash_rfind(string);
- if (lslash) {
- *(lslash + 1) = 0;
- }
-
- dir += 2; /* Skip over the relative reference */
- }
-#ifdef WIN32
- else {
- if (BLI_strnlen(dir, 3) >= 2 && dir[1] == ':') {
- BLI_strncpy(string, dir, 3);
- dir += 2;
- }
- else if (BLI_strnlen(dir, 3) >= 2 && BLI_path_is_unc(dir)) {
- string[0] = 0;
- }
- else { /* no drive specified */
- /* first option: get the drive from the relabase if it has one */
- if (relabase && BLI_strnlen(relabase, 3) >= 2 && relabase[1] == ':') {
- BLI_strncpy(string, relabase, 3);
- string[2] = '\\';
- string[3] = '\0';
- }
- else { /* we're out of luck here, guessing the first valid drive, usually c:\ */
- BLI_windows_get_default_root_dir(string);
- }
-
- /* ignore leading slashes */
- while (ELEM(*dir, '/', '\\')) {
- dir++;
- }
- }
- }
-#endif
-
- strcat(string, dir);
-
- /* Make sure string ends in one (and only one) slash */
- /* first trim all slashes from the end of the string */
- sl = strlen(string);
- while ((sl > 0) && ELEM(string[sl - 1], '/', '\\')) {
- string[sl - 1] = '\0';
- sl--;
- }
- /* since we've now removed all slashes, put back one slash at the end. */
- strcat(string, "/");
-
- while (ELEM(*file, '/', '\\')) {
- /* Trim slashes from the front of file */
- file++;
- }
-
- strcat(string, file);
-
- /* Push all slashes to the system preferred direction */
- BLI_path_slash_native(string);
-}
-
static bool path_extension_check_ex(const char *str,
const size_t str_len,
const char *ext,
@@ -1428,7 +1347,7 @@ bool BLI_path_extension_ensure(char *path, size_t maxlen, const char *ext)
ssize_t a;
/* first check the extension is already there */
- if ((ext_len <= path_len) && (STREQ(path + (path_len - ext_len), ext))) {
+ if ((ext_len <= path_len) && STREQ(path + (path_len - ext_len), ext)) {
return true;
}
@@ -1529,56 +1448,20 @@ void BLI_path_append(char *__restrict dst, const size_t maxlen, const char *__re
BLI_strncpy(dst + dirlen, file, maxlen - dirlen);
}
-void BLI_join_dirfile(char *__restrict dst,
- const size_t maxlen,
- const char *__restrict dir,
- const char *__restrict file)
-{
-#ifdef DEBUG_STRSIZE
- memset(dst, 0xff, sizeof(*dst) * maxlen);
-#endif
- size_t dirlen = BLI_strnlen(dir, maxlen);
-
- /* Arguments can't match. */
- BLI_assert(!ELEM(dst, dir, file));
-
- /* Files starting with a separator cause a double-slash which could later be interpreted
- * as a relative path where: `dir == "/"` and `file == "/file"` would result in "//file". */
- BLI_assert(file[0] != SEP);
-
- if (dirlen == maxlen) {
- memcpy(dst, dir, dirlen);
- dst[dirlen - 1] = '\0';
- return; /* dir fills the path */
- }
-
- memcpy(dst, dir, dirlen + 1);
-
- if (dirlen + 1 >= maxlen) {
- return; /* fills the path */
- }
-
- /* inline BLI_path_slash_ensure */
- if ((dirlen > 0) && !ELEM(dst[dirlen - 1], SEP, ALTSEP)) {
- dst[dirlen++] = SEP;
- dst[dirlen] = '\0';
- }
-
- if (dirlen >= maxlen) {
- return; /* fills the path */
- }
-
- BLI_strncpy(dst + dirlen, file, maxlen - dirlen);
-}
-
-size_t BLI_path_join(char *__restrict dst, const size_t dst_len, const char *path, ...)
+size_t BLI_path_join_array(char *__restrict dst,
+ const size_t dst_len,
+ const char *path_array[],
+ const int path_array_num)
{
+ BLI_assert(path_array_num > 0);
#ifdef DEBUG_STRSIZE
memset(dst, 0xff, sizeof(*dst) * dst_len);
#endif
if (UNLIKELY(dst_len == 0)) {
return 0;
}
+ const char *path = path_array[0];
+
const size_t dst_last = dst_len - 1;
size_t ofs = BLI_strncpy_rlen(dst, path, dst_len);
@@ -1586,8 +1469,8 @@ size_t BLI_path_join(char *__restrict dst, const size_t dst_len, const char *pat
return ofs;
}
- /* remove trailing slashes, unless there are _only_ trailing slashes
- * (allow "//" as the first argument). */
+ /* Remove trailing slashes, unless there are *only* trailing slashes
+ * (allow `//` or `//some_path` as the first argument). */
bool has_trailing_slash = false;
if (ofs != 0) {
size_t len = ofs;
@@ -1600,9 +1483,8 @@ size_t BLI_path_join(char *__restrict dst, const size_t dst_len, const char *pat
has_trailing_slash = (path[len] != '\0');
}
- va_list args;
- va_start(args, path);
- while ((path = (const char *)va_arg(args, const char *))) {
+ for (int path_index = 1; path_index < path_array_num; path_index++) {
+ path = path_array[path_index];
has_trailing_slash = false;
const char *path_init = path;
while (ELEM(path[0], SEP, ALTSEP)) {
@@ -1637,7 +1519,6 @@ size_t BLI_path_join(char *__restrict dst, const size_t dst_len, const char *pat
has_trailing_slash = (path_init != path);
}
}
- va_end(args);
if (has_trailing_slash) {
if ((ofs != dst_last) && (ofs != 0) && (ELEM(dst[ofs - 1], SEP, ALTSEP) == 0)) {
diff --git a/source/blender/blenlib/intern/polyfill_2d.c b/source/blender/blenlib/intern/polyfill_2d.c
index eed87eda436..2b59de5b569 100644
--- a/source/blender/blenlib/intern/polyfill_2d.c
+++ b/source/blender/blenlib/intern/polyfill_2d.c
@@ -373,12 +373,12 @@ static bool kdtree2d_isect_tri_recursive(const struct KDTree2D *tree,
# define KDTREE2D_ISECT_TRI_RECURSE_NEG \
(((node->neg != KDNODE_UNSET) && (co[node->axis] >= bounds[node->axis].min)) && \
- (kdtree2d_isect_tri_recursive( \
- tree, tri_index, tri_coords, tri_center, bounds, &tree->nodes[node->neg])))
+ kdtree2d_isect_tri_recursive( \
+ tree, tri_index, tri_coords, tri_center, bounds, &tree->nodes[node->neg]))
# define KDTREE2D_ISECT_TRI_RECURSE_POS \
(((node->pos != KDNODE_UNSET) && (co[node->axis] <= bounds[node->axis].max)) && \
- (kdtree2d_isect_tri_recursive( \
- tree, tri_index, tri_coords, tri_center, bounds, &tree->nodes[node->pos])))
+ kdtree2d_isect_tri_recursive( \
+ tree, tri_index, tri_coords, tri_center, bounds, &tree->nodes[node->pos]))
if (tri_center[node->axis] > co[node->axis]) {
if (KDTREE2D_ISECT_TRI_RECURSE_POS) {
diff --git a/source/blender/blenlib/intern/rand.cc b/source/blender/blenlib/intern/rand.cc
index f6d91cdcc4f..2e9b15c623e 100644
--- a/source/blender/blenlib/intern/rand.cc
+++ b/source/blender/blenlib/intern/rand.cc
@@ -24,7 +24,7 @@
#include "BLI_strict_flags.h"
#include "BLI_sys_types.h"
-extern "C" unsigned char BLI_noise_hash_uchar_512[512]; /* noise.c */
+extern "C" uchar BLI_noise_hash_uchar_512[512]; /* noise.c */
#define hash BLI_noise_hash_uchar_512
/**
@@ -36,14 +36,14 @@ struct RNG {
MEM_CXX_CLASS_ALLOC_FUNCS("RNG")
};
-RNG *BLI_rng_new(unsigned int seed)
+RNG *BLI_rng_new(uint seed)
{
RNG *rng = new RNG();
rng->rng.seed(seed);
return rng;
}
-RNG *BLI_rng_new_srandom(unsigned int seed)
+RNG *BLI_rng_new_srandom(uint seed)
{
RNG *rng = new RNG();
rng->rng.seed_random(seed);
@@ -60,19 +60,19 @@ void BLI_rng_free(RNG *rng)
delete rng;
}
-void BLI_rng_seed(RNG *rng, unsigned int seed)
+void BLI_rng_seed(RNG *rng, uint seed)
{
rng->rng.seed(seed);
}
-void BLI_rng_srandom(RNG *rng, unsigned int seed)
+void BLI_rng_srandom(RNG *rng, uint seed)
{
rng->rng.seed_random(seed);
}
void BLI_rng_get_char_n(RNG *rng, char *bytes, size_t bytes_len)
{
- rng->rng.get_bytes(blender::MutableSpan(bytes, static_cast<int64_t>(bytes_len)));
+ rng->rng.get_bytes(blender::MutableSpan(bytes, int64_t(bytes_len)));
}
int BLI_rng_get_int(RNG *rng)
@@ -80,7 +80,7 @@ int BLI_rng_get_int(RNG *rng)
return rng->rng.get_int32();
}
-unsigned int BLI_rng_get_uint(RNG *rng)
+uint BLI_rng_get_uint(RNG *rng)
{
return rng->rng.get_uint32();
}
@@ -117,21 +117,21 @@ void BLI_rng_get_tri_sample_float_v3(
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_num)
+void BLI_rng_shuffle_array(RNG *rng, void *data, uint elem_size_i, uint elem_num)
{
if (elem_num <= 1) {
return;
}
const uint elem_size = elem_size_i;
- unsigned int i = elem_num;
+ uint i = elem_num;
void *temp = malloc(elem_size);
while (i--) {
- const unsigned int j = BLI_rng_get_uint(rng) % elem_num;
+ const uint j = BLI_rng_get_uint(rng) % elem_num;
if (i != j) {
- void *iElem = (unsigned char *)data + i * elem_size_i;
- void *jElem = (unsigned char *)data + j * elem_size_i;
+ void *iElem = (uchar *)data + i * elem_size_i;
+ void *jElem = (uchar *)data + j * elem_size_i;
memcpy(temp, iElem, elem_size);
memcpy(iElem, jElem, elem_size);
memcpy(jElem, temp, elem_size);
@@ -141,15 +141,15 @@ void BLI_rng_shuffle_array(RNG *rng, void *data, unsigned int elem_size_i, unsig
free(temp);
}
-void BLI_rng_shuffle_bitmap(struct RNG *rng, BLI_bitmap *bitmap, unsigned int bits_num)
+void BLI_rng_shuffle_bitmap(struct RNG *rng, BLI_bitmap *bitmap, uint bits_num)
{
if (bits_num <= 1) {
return;
}
- unsigned int i = bits_num;
+ uint i = bits_num;
while (i--) {
- const unsigned int j = BLI_rng_get_uint(rng) % bits_num;
+ const uint j = BLI_rng_get_uint(rng) % bits_num;
if (i != j) {
const bool i_bit = BLI_BITMAP_TEST(bitmap, i);
const bool j_bit = BLI_BITMAP_TEST(bitmap, j);
@@ -161,12 +161,12 @@ void BLI_rng_shuffle_bitmap(struct RNG *rng, BLI_bitmap *bitmap, unsigned int bi
void BLI_rng_skip(RNG *rng, int n)
{
- rng->rng.skip((uint)n);
+ rng->rng.skip(uint(n));
}
/***/
-void BLI_array_frand(float *ar, int count, unsigned int seed)
+void BLI_array_frand(float *ar, int count, uint seed)
{
RNG rng;
@@ -177,7 +177,7 @@ void BLI_array_frand(float *ar, int count, unsigned int seed)
}
}
-float BLI_hash_frand(unsigned int seed)
+float BLI_hash_frand(uint seed)
{
RNG rng;
@@ -185,10 +185,7 @@ float BLI_hash_frand(unsigned int seed)
return BLI_rng_get_float(&rng);
}
-void BLI_array_randomize(void *data,
- unsigned int elem_size,
- unsigned int elem_num,
- unsigned int seed)
+void BLI_array_randomize(void *data, uint elem_size, uint elem_num, uint seed)
{
RNG rng;
@@ -196,7 +193,7 @@ void BLI_array_randomize(void *data,
BLI_rng_shuffle_array(&rng, data, elem_size, elem_num);
}
-void BLI_bitmap_randomize(BLI_bitmap *bitmap, unsigned int bits_num, unsigned int seed)
+void BLI_bitmap_randomize(BLI_bitmap *bitmap, uint bits_num, uint seed)
{
RNG rng;
@@ -208,7 +205,7 @@ void BLI_bitmap_randomize(BLI_bitmap *bitmap, unsigned int bits_num, unsigned in
static RNG rng_tab[BLENDER_MAX_THREADS];
-void BLI_thread_srandom(int thread, unsigned int seed)
+void BLI_thread_srandom(int thread, uint seed)
{
if (thread >= BLENDER_MAX_THREADS) {
thread = 0;
@@ -237,12 +234,12 @@ struct RNG_THREAD_ARRAY {
RNG_THREAD_ARRAY *BLI_rng_threaded_new()
{
- unsigned int i;
+ uint i;
RNG_THREAD_ARRAY *rngarr = (RNG_THREAD_ARRAY *)MEM_mallocN(sizeof(RNG_THREAD_ARRAY),
"random_array");
for (i = 0; i < BLENDER_MAX_THREADS; i++) {
- BLI_rng_srandom(&rngarr->rng_tab[i], (unsigned int)clock());
+ BLI_rng_srandom(&rngarr->rng_tab[i], uint(clock()));
}
return rngarr;
@@ -284,9 +281,9 @@ BLI_INLINE double halton_ex(double invprimes, double *offset)
return *offset;
}
-void BLI_halton_1d(unsigned int prime, double offset, int n, double *r)
+void BLI_halton_1d(uint prime, double offset, int n, double *r)
{
- const double invprime = 1.0 / (double)prime;
+ const double invprime = 1.0 / double(prime);
*r = 0.0;
@@ -295,9 +292,9 @@ void BLI_halton_1d(unsigned int prime, double offset, int n, double *r)
}
}
-void BLI_halton_2d(const unsigned int prime[2], double offset[2], int n, double *r)
+void BLI_halton_2d(const uint prime[2], double offset[2], int n, double *r)
{
- const double invprimes[2] = {1.0 / (double)prime[0], 1.0 / (double)prime[1]};
+ const double invprimes[2] = {1.0 / double(prime[0]), 1.0 / double(prime[1])};
r[0] = r[1] = 0.0;
@@ -308,10 +305,10 @@ void BLI_halton_2d(const unsigned int prime[2], double offset[2], int n, double
}
}
-void BLI_halton_3d(const unsigned int prime[3], double offset[3], int n, double *r)
+void BLI_halton_3d(const uint prime[3], double offset[3], int n, double *r)
{
const double invprimes[3] = {
- 1.0 / (double)prime[0], 1.0 / (double)prime[1], 1.0 / (double)prime[2]};
+ 1.0 / double(prime[0]), 1.0 / double(prime[1]), 1.0 / double(prime[2])};
r[0] = r[1] = r[2] = 0.0;
@@ -322,9 +319,9 @@ void BLI_halton_3d(const unsigned int prime[3], double offset[3], int n, double
}
}
-void BLI_halton_2d_sequence(const unsigned int prime[2], double offset[2], int n, double *r)
+void BLI_halton_2d_sequence(const uint prime[2], double offset[2], int n, double *r)
{
- const double invprimes[2] = {1.0 / (double)prime[0], 1.0 / (double)prime[1]};
+ const double invprimes[2] = {1.0 / double(prime[0]), 1.0 / double(prime[1])};
for (int s = 0; s < n; s++) {
for (int i = 0; i < 2; i++) {
@@ -335,7 +332,7 @@ void BLI_halton_2d_sequence(const unsigned int prime[2], double offset[2], int n
/* From "Sampling with Hammersley and Halton Points" TT Wong
* Appendix: Source Code 1 */
-BLI_INLINE double radical_inverse(unsigned int n)
+BLI_INLINE double radical_inverse(uint n)
{
double u = 0;
@@ -350,15 +347,15 @@ BLI_INLINE double radical_inverse(unsigned int n)
return u;
}
-void BLI_hammersley_1d(unsigned int n, double *r)
+void BLI_hammersley_1d(uint n, double *r)
{
*r = radical_inverse(n);
}
-void BLI_hammersley_2d_sequence(unsigned int n, double *r)
+void BLI_hammersley_2d_sequence(uint n, double *r)
{
- for (unsigned int s = 0; s < n; s++) {
- r[s * 2 + 0] = (double)(s + 0.5) / (double)n;
+ for (uint s = 0; s < n; s++) {
+ r[s * 2 + 0] = double(s + 0.5) / double(n);
r[s * 2 + 1] = radical_inverse(s);
}
}
@@ -380,12 +377,12 @@ int RandomNumberGenerator::round_probabilistic(float x)
BLI_assert(x >= 0.0f);
const float round_up_probability = fractf(x);
const bool round_up = round_up_probability > this->get_float();
- return (int)x + (int)round_up;
+ return int(x) + int(round_up);
}
float2 RandomNumberGenerator::get_unit_float2()
{
- float a = (float)(M_PI * 2.0) * this->get_float();
+ float a = float(M_PI * 2.0) * this->get_float();
return {cosf(a), sinf(a)};
}
@@ -394,7 +391,7 @@ float3 RandomNumberGenerator::get_unit_float3()
float z = (2.0f * this->get_float()) - 1.0f;
float r = 1.0f - z * z;
if (r > 0.0f) {
- float a = (float)(M_PI * 2.0) * this->get_float();
+ float a = float(M_PI * 2.0) * this->get_float();
r = sqrtf(r);
float x = r * cosf(a);
float y = r * sinf(a);
@@ -444,7 +441,7 @@ float3 RandomNumberGenerator::get_triangle_sample_3d(float3 v1, float3 v2, float
void RandomNumberGenerator::get_bytes(MutableSpan<char> r_bytes)
{
constexpr int64_t mask_bytes = 2;
- constexpr int64_t rand_stride = static_cast<int64_t>(sizeof(x_)) - mask_bytes;
+ constexpr int64_t rand_stride = int64_t(sizeof(x_)) - mask_bytes;
int64_t last_len = 0;
int64_t trim_len = r_bytes.size();
diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c
index 92fd7f5937b..4145125c1d7 100644
--- a/source/blender/blenlib/intern/scanfill.c
+++ b/source/blender/blenlib/intern/scanfill.c
@@ -33,9 +33,9 @@
/* local types */
typedef struct PolyFill {
- unsigned int edges, verts;
+ uint edges, verts;
float min_xy[2], max_xy[2];
- unsigned short nr;
+ ushort nr;
bool f;
} PolyFill;
@@ -44,7 +44,7 @@ typedef struct ScanFillVertLink {
ScanFillEdge *edge_first, *edge_last;
} ScanFillVertLink;
-/* local funcs */
+/* Local functions. */
#define SF_EPSILON 0.00003f
#define SF_EPSILON_SQ (SF_EPSILON * SF_EPSILON)
@@ -304,9 +304,7 @@ static bool addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed)
return true;
}
-static ScanFillVertLink *addedgetoscanlist(ScanFillVertLink *scdata,
- ScanFillEdge *eed,
- unsigned int len)
+static ScanFillVertLink *addedgetoscanlist(ScanFillVertLink *scdata, ScanFillEdge *eed, uint len)
{
/* inserts edge at correct location in ScanFillVertLink list */
/* returns sc when edge already exists */
@@ -428,10 +426,7 @@ static void testvertexnearedge(ScanFillContext *sf_ctx)
}
}
-static void splitlist(ScanFillContext *sf_ctx,
- ListBase *tempve,
- ListBase *temped,
- unsigned short nr)
+static void splitlist(ScanFillContext *sf_ctx, ListBase *tempve, ListBase *temped, ushort nr)
{
/* Everything is in temp-list, write only poly nr to fill-list. */
ScanFillVert *eve, *eve_next;
@@ -457,14 +452,14 @@ static void splitlist(ScanFillContext *sf_ctx,
}
}
-static unsigned int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
+static uint scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
{
ScanFillVertLink *scdata;
ScanFillVertLink *sc = NULL, *sc1;
ScanFillVert *eve, *v1, *v2, *v3;
ScanFillEdge *eed, *eed_next, *ed1, *ed2, *ed3;
- unsigned int a, b, verts, maxface, totface;
- const unsigned short nr = pf->nr;
+ uint a, b, verts, maxface, totface;
+ const ushort nr = pf->nr;
bool twoconnected = false;
/* PRINTS */
@@ -810,7 +805,7 @@ void BLI_scanfill_end_arena(ScanFillContext *sf_ctx, MemArena *arena)
BLI_listbase_clear(&sf_ctx->fillfacebase);
}
-unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float nor_proj[3])
+uint BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float nor_proj[3])
{
/*
* - fill works with its own lists, so create that first (no faces!)
@@ -825,8 +820,8 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
ScanFillEdge *eed, *eed_next;
PolyFill *pflist, *pf;
float *min_xy_p, *max_xy_p;
- unsigned int totfaces = 0; /* total faces added */
- unsigned short a, c, poly = 0;
+ uint totfaces = 0; /* total faces added */
+ ushort a, c, poly = 0;
bool ok;
float mat_2d[3][3];
@@ -895,7 +890,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
/* STEP 1: COUNT POLYS */
if (sf_ctx->poly_nr != SF_POLY_UNSET) {
- poly = (unsigned short)(sf_ctx->poly_nr + 1);
+ poly = (ushort)(sf_ctx->poly_nr + 1);
sf_ctx->poly_nr = SF_POLY_UNSET;
}
@@ -905,7 +900,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
/* get first vertex with no poly number */
if (eve->poly_nr == SF_POLY_UNSET) {
- unsigned int toggle = 0;
+ uint toggle = 0;
/* now a sort of select connected */
ok = true;
eve->poly_nr = poly;
@@ -962,7 +957,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
/* STEP 2: remove loose edges and strings of edges */
if (flag & BLI_SCANFILL_CALC_LOOSE) {
- unsigned int toggle = 0;
+ uint toggle = 0;
for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
if (eed->v1->edge_count++ > 250) {
break;
@@ -1069,7 +1064,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
* WATCH IT: ONLY WORKS WITH SORTED POLYS!!! */
if ((flag & BLI_SCANFILL_CALC_HOLES) && (poly > 1)) {
- unsigned short *polycache, *pc;
+ ushort *polycache, *pc;
/* so, sort first */
qsort(pflist, (size_t)poly, sizeof(PolyFill), vergpoly);
@@ -1086,7 +1081,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
polycache = pc = MEM_callocN(sizeof(*polycache) * (size_t)poly, "polycache");
pf = pflist;
for (a = 0; a < poly; a++, pf++) {
- for (c = (unsigned short)(a + 1); c < poly; c++) {
+ for (c = (ushort)(a + 1); c < poly; c++) {
/* if 'a' inside 'c': join (bbox too)
* Careful: 'a' can also be inside another poly.
@@ -1142,7 +1137,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
return totfaces;
}
-unsigned int BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag)
+uint BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag)
{
return BLI_scanfill_calc_ex(sf_ctx, flag, NULL);
}
diff --git a/source/blender/blenlib/intern/scanfill_utils.c b/source/blender/blenlib/intern/scanfill_utils.c
index 1d2225a5b56..6bf3c4719f6 100644
--- a/source/blender/blenlib/intern/scanfill_utils.c
+++ b/source/blender/blenlib/intern/scanfill_utils.c
@@ -41,14 +41,14 @@ typedef struct ScanFillIsect {
#define EFLAG_SET(eed, val) \
{ \
CHECK_TYPE(eed, ScanFillEdge *); \
- (eed)->user_flag = (eed)->user_flag | (unsigned int)val; \
+ (eed)->user_flag = (eed)->user_flag | (uint)val; \
} \
(void)0
#if 0
# define EFLAG_CLEAR(eed, val) \
{ \
CHECK_TYPE(eed, ScanFillEdge *); \
- (eed)->user_flag = (eed)->user_flag & ~(unsigned int)val; \
+ (eed)->user_flag = (eed)->user_flag & ~(uint)val; \
} \
(void)0
#endif
@@ -56,14 +56,14 @@ typedef struct ScanFillIsect {
#define VFLAG_SET(eve, val) \
{ \
CHECK_TYPE(eve, ScanFillVert *); \
- (eve)->user_flag = (eve)->user_flag | (unsigned int)val; \
+ (eve)->user_flag = (eve)->user_flag | (uint)val; \
} \
(void)0
#if 0
# define VFLAG_CLEAR(eve, val) \
{ \
CHECK_TYPE(eve, ScanFillVert *); \
- (eve)->user_flags = (eve)->user_flag & ~(unsigned int)val; \
+ (eve)->user_flags = (eve)->user_flag & ~(uint)val; \
} \
(void)0
#endif
@@ -72,7 +72,7 @@ typedef struct ScanFillIsect {
void BLI_scanfill_obj_dump(ScanFillContext *sf_ctx)
{
FILE *f = fopen("test.obj", "w");
- unsigned int i = 1;
+ uint i = 1;
ScanFillVert *eve;
ScanFillEdge *eed;
@@ -130,7 +130,7 @@ static int edge_isect_ls_sort_cb(void *thunk, const void *def_a_ptr, const void
}
static ScanFillEdge *edge_step(PolyInfo *poly_info,
- const unsigned short poly_nr,
+ const ushort poly_nr,
ScanFillVert *v_prev,
ScanFillVert *v_curr,
ScanFillEdge *e_curr)
@@ -158,7 +158,7 @@ static ScanFillEdge *edge_step(PolyInfo *poly_info,
static bool scanfill_preprocess_self_isect(ScanFillContext *sf_ctx,
PolyInfo *poly_info,
- const unsigned short poly_nr,
+ const ushort poly_nr,
ListBase *filledgebase)
{
PolyInfo *pi = &poly_info[poly_nr];
@@ -359,8 +359,8 @@ bool BLI_scanfill_calc_self_isect(ScanFillContext *sf_ctx,
ListBase *remvertbase,
ListBase *remedgebase)
{
- const unsigned int poly_num = (unsigned int)sf_ctx->poly_nr + 1;
- unsigned int eed_index = 0;
+ const uint poly_num = (uint)sf_ctx->poly_nr + 1;
+ uint eed_index = 0;
int totvert_new = 0;
bool changed = false;
@@ -378,7 +378,7 @@ bool BLI_scanfill_calc_self_isect(ScanFillContext *sf_ctx,
poly_info->edge_last = sf_ctx->filledgebase.last;
}
else {
- unsigned short poly_nr;
+ ushort poly_nr;
ScanFillEdge *eed;
poly_nr = 0;
@@ -407,7 +407,7 @@ bool BLI_scanfill_calc_self_isect(ScanFillContext *sf_ctx,
/* self-intersect each polygon */
{
- unsigned short poly_nr;
+ ushort poly_nr;
for (poly_nr = 0; poly_nr < poly_num; poly_nr++) {
changed |= scanfill_preprocess_self_isect(sf_ctx, poly_info, poly_nr, remedgebase);
}
diff --git a/source/blender/blenlib/intern/smallhash.c b/source/blender/blenlib/intern/smallhash.c
index 2d76f662611..8263f8ff34e 100644
--- a/source/blender/blenlib/intern/smallhash.c
+++ b/source/blender/blenlib/intern/smallhash.c
@@ -329,8 +329,7 @@ void **BLI_smallhash_iternew_p(const SmallHash *sh, SmallHashIter *iter, uintptr
/** \name Debugging & Introspection
* \{ */
-/* NOTE(campbell): this was called _print_smhash in knifetool.c
- * it may not be intended for general use. */
+/* NOTE(@campbellbarton): useful for debugging but may not be intended for general use. */
#if 0
void BLI_smallhash_print(SmallHash *sh)
{
diff --git a/source/blender/blenlib/intern/stack.c b/source/blender/blenlib/intern/stack.c
index ff34cfe41cb..1a83e8cd86c 100644
--- a/source/blender/blenlib/intern/stack.c
+++ b/source/blender/blenlib/intern/stack.c
@@ -141,7 +141,7 @@ void BLI_stack_pop(BLI_Stack *stack, void *dst)
BLI_stack_discard(stack);
}
-void BLI_stack_pop_n(BLI_Stack *stack, void *dst, unsigned int n)
+void BLI_stack_pop_n(BLI_Stack *stack, void *dst, uint n)
{
BLI_assert(n <= BLI_stack_count(stack));
@@ -151,7 +151,7 @@ void BLI_stack_pop_n(BLI_Stack *stack, void *dst, unsigned int n)
}
}
-void BLI_stack_pop_n_reverse(BLI_Stack *stack, void *dst, unsigned int n)
+void BLI_stack_pop_n_reverse(BLI_Stack *stack, void *dst, uint n)
{
BLI_assert(n <= BLI_stack_count(stack));
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index 4fa5ca0c088..c04fc41ab4d 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -259,7 +259,7 @@ eFileAttributes BLI_file_attributes(const char *path)
#ifndef __APPLE__
bool BLI_file_alias_target(const char *filepath,
/* This parameter can only be `const` on Linux since
- * redirections are not supported there.
+ * redirection is not supported there.
* NOLINTNEXTLINE: readability-non-const-parameter. */
char r_targetpath[/*FILE_MAXDIR*/])
{
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index 976b9a5cd02..755d2dbd55d 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -314,7 +314,7 @@ size_t BLI_str_unescape_ex(char *__restrict dst,
break;
}
char c = *src;
- if (UNLIKELY(c == '\\') && (str_unescape_pair(*(src + 1), &c))) {
+ if (UNLIKELY(c == '\\') && str_unescape_pair(*(src + 1), &c)) {
src++;
}
dst[len++] = c;
@@ -329,7 +329,7 @@ size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, const
size_t len = 0;
for (const char *src_end = src + src_maxncpy; (src < src_end) && *src; src++) {
char c = *src;
- if (UNLIKELY(c == '\\') && (str_unescape_pair(*(src + 1), &c))) {
+ if (UNLIKELY(c == '\\') && str_unescape_pair(*(src + 1), &c)) {
src++;
}
dst[len++] = c;
@@ -1121,7 +1121,7 @@ size_t BLI_str_format_int_grouped(char dst[16], int num)
size_t BLI_str_format_uint64_grouped(char dst[16], uint64_t num)
{
- /* NOTE: Buffer to hold maximum unsigned int64, which is 1.8e+19. but
+ /* NOTE: Buffer to hold maximum `uint64`, which is 1.8e+19. but
* we also need space for commas and null-terminator. */
char src[27];
int num_len = sprintf(src, "%" PRIu64 "", num);
@@ -1176,4 +1176,34 @@ void BLI_str_format_decimal_unit(char dst[7], int number_to_format)
BLI_snprintf(dst, dst_len, "%.*f%s", decimals, number_to_format_converted, units[order]);
}
+void BLI_str_format_integer_unit(char dst[5], const int number_to_format)
+{
+ float number_to_format_converted = number_to_format;
+ int order = 0;
+ const float base = 1000;
+ const char *units[] = {"", "K", "M", "B"};
+ const int units_num = ARRAY_SIZE(units);
+
+ while ((fabsf(number_to_format_converted) >= base) && ((order + 1) < units_num)) {
+ number_to_format_converted /= base;
+ order++;
+ }
+
+ const bool add_dot = (abs(number_to_format) > 99999) && fabsf(number_to_format_converted) > 99;
+
+ if (add_dot) {
+ number_to_format_converted /= 100;
+ order++;
+ }
+
+ const size_t dst_len = 5;
+ BLI_snprintf(dst,
+ dst_len,
+ "%s%s%d%s",
+ number_to_format < 0 ? "-" : "",
+ add_dot ? "." : "",
+ (int)floorf(fabsf(number_to_format_converted)),
+ units[order]);
+}
+
/** \} */
diff --git a/source/blender/blenlib/intern/string_cursor_utf8.c b/source/blender/blenlib/intern/string_cursor_utf8.c
index 7a23b4bb4ad..2405b134428 100644
--- a/source/blender/blenlib/intern/string_cursor_utf8.c
+++ b/source/blender/blenlib/intern/string_cursor_utf8.c
@@ -96,27 +96,35 @@ static eStrCursorDelimType cursor_delim_type_utf8(const char *ch_utf8,
return cursor_delim_type_unicode(uch);
}
+/* Keep in sync with BLI_str_cursor_step_next_utf32. */
bool BLI_str_cursor_step_next_utf8(const char *str, size_t maxlen, int *pos)
{
+ if ((*pos) >= (int)maxlen) {
+ return false;
+ }
const char *str_end = str + (maxlen + 1);
const char *str_pos = str + (*pos);
- const char *str_next = BLI_str_find_next_char_utf8(str_pos, str_end);
- if (str_next != str_end) {
- (*pos) += (str_next - str_pos);
- if ((*pos) > (int)maxlen) {
- (*pos) = (int)maxlen;
- }
- return true;
+ const char *str_next = str_pos;
+ do {
+ str_next = BLI_str_find_next_char_utf8(str_next, str_end);
+ } while (str_next < str_end && str_next[0] != 0 && BLI_str_utf8_char_width(str_next) < 1);
+ (*pos) += (str_next - str_pos);
+ if ((*pos) > (int)maxlen) {
+ (*pos) = (int)maxlen;
}
- return false;
+ return true;
}
-bool BLI_str_cursor_step_prev_utf8(const char *str, size_t UNUSED(maxlen), int *pos)
+/* Keep in sync with BLI_str_cursor_step_prev_utf32. */
+bool BLI_str_cursor_step_prev_utf8(const char *str, size_t maxlen, int *pos)
{
- if ((*pos) > 0) {
+ if ((*pos) > 0 && (*pos) <= maxlen) {
const char *str_pos = str + (*pos);
- const char *str_prev = BLI_str_find_prev_char_utf8(str_pos, str);
+ const char *str_prev = str_pos;
+ do {
+ str_prev = BLI_str_find_prev_char_utf8(str_prev, str);
+ } while (str_prev > str && BLI_str_utf8_char_width(str_prev) == 0);
(*pos) -= (str_pos - str_prev);
return true;
}
@@ -202,26 +210,29 @@ void BLI_str_cursor_step_utf8(const char *str,
}
}
-/* UTF32 version of BLI_str_cursor_step_utf8 (keep in sync!)
- * less complex since it doesn't need to do multi-byte stepping.
- */
-
-/* helper funcs so we can match BLI_str_cursor_step_utf8 */
-static bool cursor_step_next_utf32(const char32_t *UNUSED(str), size_t maxlen, int *pos)
+/* Keep in sync with BLI_str_cursor_step_next_utf8. */
+bool BLI_str_cursor_step_next_utf32(const char32_t *str, size_t maxlen, int *pos)
{
if ((*pos) >= (int)maxlen) {
return false;
}
- (*pos)++;
+ do {
+ (*pos)++;
+ } while (*pos < (int)maxlen && str[*pos] != 0 && BLI_wcwidth(str[*pos]) == 0);
+
return true;
}
-static bool cursor_step_prev_utf32(const char32_t *UNUSED(str), size_t UNUSED(maxlen), int *pos)
+/* Keep in sync with BLI_str_cursor_step_prev_utf8. */
+bool BLI_str_cursor_step_prev_utf32(const char32_t *str, size_t UNUSED(maxlen), int *pos)
{
if ((*pos) <= 0) {
return false;
}
- (*pos)--;
+ do {
+ (*pos)--;
+ } while (*pos > 0 && BLI_wcwidth(str[*pos]) == 0);
+
return true;
}
@@ -236,7 +247,7 @@ void BLI_str_cursor_step_utf32(const char32_t *str,
if (direction == STRCUR_DIR_NEXT) {
if (use_init_step) {
- cursor_step_next_utf32(str, maxlen, pos);
+ BLI_str_cursor_step_next_utf32(str, maxlen, pos);
}
else {
BLI_assert(jump == STRCUR_JUMP_DELIM);
@@ -250,7 +261,7 @@ void BLI_str_cursor_step_utf32(const char32_t *str,
* look at function cursor_delim_type_unicode() for complete
* list of special character, ctr -> */
while ((*pos) < maxlen) {
- if (cursor_step_next_utf32(str, maxlen, pos)) {
+ if (BLI_str_cursor_step_next_utf32(str, maxlen, pos)) {
if ((jump != STRCUR_JUMP_ALL) &&
(delim_type != cursor_delim_type_unicode((uint)str[*pos]))) {
break;
@@ -264,7 +275,7 @@ void BLI_str_cursor_step_utf32(const char32_t *str,
}
else if (direction == STRCUR_DIR_PREV) {
if (use_init_step) {
- cursor_step_prev_utf32(str, maxlen, pos);
+ BLI_str_cursor_step_prev_utf32(str, maxlen, pos);
}
else {
BLI_assert(jump == STRCUR_JUMP_DELIM);
@@ -279,7 +290,7 @@ void BLI_str_cursor_step_utf32(const char32_t *str,
* list of special character, ctr -> */
while ((*pos) > 0) {
const int pos_prev = *pos;
- if (cursor_step_prev_utf32(str, maxlen, pos)) {
+ if (BLI_str_cursor_step_prev_utf32(str, maxlen, pos)) {
if ((jump != STRCUR_JUMP_ALL) &&
(delim_type != cursor_delim_type_unicode((uint)str[*pos]))) {
/* left only: compensate for index/change in direction */
diff --git a/source/blender/blenlib/intern/string_search.cc b/source/blender/blenlib/intern/string_search.cc
index 14d85b99739..f87304863c9 100644
--- a/source/blender/blenlib/intern/string_search.cc
+++ b/source/blender/blenlib/intern/string_search.cc
@@ -11,14 +11,14 @@
#include "BLI_timeit.hh"
/* Right arrow, keep in sync with #UI_MENU_ARROW_SEP in `UI_interface.h`. */
-#define UI_MENU_ARROW_SEP "\xe2\x96\xb6"
-#define UI_MENU_ARROW_SEP_UNICODE 0x25b6
+#define UI_MENU_ARROW_SEP "\xe2\x96\xb8"
+#define UI_MENU_ARROW_SEP_UNICODE 0x25b8
namespace blender::string_search {
static int64_t count_utf8_code_points(StringRef str)
{
- return static_cast<int64_t>(BLI_strnlen_utf8(str.data(), static_cast<size_t>(str.size())));
+ return int64_t(BLI_strnlen_utf8(str.data(), size_t(str.size())));
}
int damerau_levenshtein_distance(StringRef a, StringRef b)
@@ -205,7 +205,7 @@ static bool match_word_initials(StringRef query,
StringRef word = words[word_index];
/* Try to match the current character with the current word. */
- if (static_cast<int>(char_index) < word.size()) {
+ if (int(char_index) < word.size()) {
const uint32_t char_unicode = BLI_str_utf8_as_unicode_step(
word.data(), word.size(), &char_index);
if (query_unicode == char_unicode) {
@@ -345,7 +345,7 @@ void extract_normalized_words(StringRef str,
LinearAllocator<> &allocator,
Vector<StringRef, 64> &r_words)
{
- const uint32_t unicode_space = (uint32_t)' ';
+ const uint32_t unicode_space = uint32_t(' ');
const uint32_t unicode_right_triangle = UI_MENU_ARROW_SEP_UNICODE;
BLI_assert(unicode_space == BLI_str_utf8_as_unicode(" "));
@@ -358,7 +358,7 @@ void extract_normalized_words(StringRef str,
/* Make a copy of the string so that we can edit it. */
StringRef str_copy = allocator.copy_string(str);
char *mutable_copy = const_cast<char *>(str_copy.data());
- const size_t str_size_in_bytes = static_cast<size_t>(str.size());
+ const size_t str_size_in_bytes = size_t(str.size());
BLI_str_tolower_ascii(mutable_copy, str_size_in_bytes);
/* Iterate over all unicode code points to split individual words. */
@@ -371,8 +371,7 @@ void extract_normalized_words(StringRef str,
size -= offset;
if (is_separator(unicode)) {
if (is_in_word) {
- r_words.append(
- str_copy.substr(static_cast<int>(word_start), static_cast<int>(offset - word_start)));
+ r_words.append(str_copy.substr(int(word_start), int(offset - word_start)));
is_in_word = false;
}
}
@@ -386,7 +385,7 @@ void extract_normalized_words(StringRef str,
}
/* If the last word is not followed by a separator, it has to be handled separately. */
if (is_in_word) {
- r_words.append(str_copy.drop_prefix(static_cast<int>(word_start)));
+ r_words.append(str_copy.drop_prefix(int(word_start)));
}
}
@@ -419,7 +418,7 @@ void BLI_string_search_add(StringSearch *search,
StringRef str_ref{str};
string_search::extract_normalized_words(str_ref, search->allocator, words);
search->items.append({search->allocator.construct_array_copy(words.as_span()),
- (int)str_ref.size(),
+ int(str_ref.size()),
user_data,
weight});
}
@@ -458,7 +457,7 @@ int BLI_string_search_query(StringSearch *search, const char *query, void ***r_d
if (score == found_scores[0] && !query_str.is_empty()) {
/* Sort items with best score by length. Shorter items are more likely the ones you are
* looking for. This also ensures that exact matches will be at the top, even if the query is
- * a substring of another item. */
+ * a sub-string of another item. */
std::sort(indices.begin(), indices.end(), [&](int a, int b) {
return search->items[a].length < search->items[b].length;
});
@@ -472,7 +471,7 @@ int BLI_string_search_query(StringSearch *search, const char *query, void ***r_d
}
void **sorted_data = static_cast<void **>(
- MEM_malloc_arrayN(static_cast<size_t>(sorted_result_indices.size()), sizeof(void *), AT));
+ MEM_malloc_arrayN(size_t(sorted_result_indices.size()), sizeof(void *), AT));
for (const int i : sorted_result_indices.index_range()) {
const int result_index = sorted_result_indices[i];
SearchItem &item = search->items[result_index];
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index 0cbf62cce03..26facda7abf 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -55,11 +55,11 @@ ptrdiff_t BLI_str_utf8_invalid_byte(const char *str, size_t length)
* length is in bytes, since without knowing whether the string is valid
* it's hard to know how many characters there are! */
- const unsigned char *p, *perr, *pend = (const unsigned char *)str + length;
- unsigned char c;
+ const uchar *p, *perr, *pend = (const uchar *)str + length;
+ uchar c;
int ab;
- for (p = (const unsigned char *)str; p < pend; p++, length--) {
+ for (p = (const uchar *)str; p < pend; p++, length--) {
c = *p;
perr = p; /* Erroneous char is always the first of an invalid utf8 sequence... */
if (ELEM(c, 0xfe, 0xff, 0x00)) {
@@ -403,7 +403,7 @@ int BLI_str_utf8_char_width_safe(const char *p)
/* copied from glib's gutf8.c, added 'Err' arg */
-/* NOTE(campbell): glib uses uint for unicode, best we do the same,
+/* NOTE(@campbellbarton): glib uses uint for unicode, best we do the same,
* though we don't typedef it. */
#define UTF8_COMPUTE(Char, Mask, Len, Err) \
@@ -454,7 +454,7 @@ int BLI_str_utf8_size(const char *p)
/* NOTE: uses glib functions but not from GLIB. */
int mask = 0, len;
- const unsigned char c = (unsigned char)*p;
+ const uchar c = (uchar)*p;
UTF8_COMPUTE(c, mask, len, -1);
@@ -466,7 +466,7 @@ int BLI_str_utf8_size(const char *p)
int BLI_str_utf8_size_safe(const char *p)
{
int mask = 0, len;
- const unsigned char c = (unsigned char)*p;
+ const uchar c = (uchar)*p;
UTF8_COMPUTE(c, mask, len, 1);
@@ -482,7 +482,7 @@ uint BLI_str_utf8_as_unicode(const char *p)
int i, len;
uint mask = 0;
uint result;
- const unsigned char c = (unsigned char)*p;
+ const uchar c = (uchar)*p;
UTF8_COMPUTE(c, mask, len, -1);
if (UNLIKELY(len == -1)) {
@@ -500,7 +500,7 @@ uint BLI_str_utf8_as_unicode_step_or_error(const char *__restrict p,
int i, len;
uint mask = 0;
uint result;
- const unsigned char c = (unsigned char)*(p += *index);
+ const uchar c = (uchar) * (p += *index);
BLI_assert(*index < p_len);
BLI_assert(c != '\0');
@@ -692,25 +692,25 @@ const char *BLI_str_find_next_char_utf8(const char *p, const char *str_end)
size_t BLI_str_partition_utf8(const char *str,
const uint delim[],
- const char **sep,
- const char **suf)
+ const char **r_sep,
+ const char **r_suf)
{
- return BLI_str_partition_ex_utf8(str, NULL, delim, sep, suf, false);
+ return BLI_str_partition_ex_utf8(str, NULL, delim, r_sep, r_suf, false);
}
size_t BLI_str_rpartition_utf8(const char *str,
const uint delim[],
- const char **sep,
- const char **suf)
+ const char **r_sep,
+ const char **r_suf)
{
- return BLI_str_partition_ex_utf8(str, NULL, delim, sep, suf, true);
+ return BLI_str_partition_ex_utf8(str, NULL, delim, r_sep, r_suf, true);
}
size_t BLI_str_partition_ex_utf8(const char *str,
const char *end,
const uint delim[],
- const char **sep,
- const char **suf,
+ const char **r_sep,
+ const char **r_suf,
const bool from_right)
{
const size_t str_len = end ? (size_t)(end - str) : strlen(str);
@@ -721,36 +721,32 @@ size_t BLI_str_partition_ex_utf8(const char *str,
/* Note that here, we assume end points to a valid utf8 char! */
BLI_assert((end >= str) && (BLI_str_utf8_as_unicode(end) != BLI_UTF8_ERR));
- *suf = (char *)(str + str_len);
-
- size_t index;
- for (*sep = (char *)(from_right ? BLI_str_find_prev_char_utf8(end, str) : str), index = 0;
- from_right ? (*sep > str) : ((*sep < end) && (**sep != '\0'));
- *sep = (char *)(from_right ? (str != *sep ? BLI_str_find_prev_char_utf8(*sep, str) : NULL) :
- str + index)) {
+ char *suf = (char *)(str + str_len);
+ size_t index = 0;
+ for (char *sep = (char *)(from_right ? BLI_str_find_prev_char_utf8(end, str) : str);
+ from_right ? (sep > str) : ((sep < end) && (*sep != '\0'));
+ sep = (char *)(from_right ? (str != sep ? BLI_str_find_prev_char_utf8(sep, str) : NULL) :
+ str + index)) {
size_t index_ofs = 0;
- const uint c = BLI_str_utf8_as_unicode_step_or_error(*sep, (size_t)(end - *sep), &index_ofs);
- index += index_ofs;
-
- if (c == BLI_UTF8_ERR) {
- *suf = *sep = NULL;
+ const uint c = BLI_str_utf8_as_unicode_step_or_error(sep, (size_t)(end - sep), &index_ofs);
+ if (UNLIKELY(c == BLI_UTF8_ERR)) {
break;
}
+ index += index_ofs;
for (const uint *d = delim; *d != '\0'; d++) {
if (*d == c) {
- /* *suf is already correct in case from_right is true. */
- if (!from_right) {
- *suf = (char *)(str + index);
- }
- return (size_t)(*sep - str);
+ /* `suf` is already correct in case from_right is true. */
+ *r_sep = sep;
+ *r_suf = from_right ? suf : (char *)(str + index);
+ return (size_t)(sep - str);
}
}
- *suf = *sep; /* Useful in 'from_right' case! */
+ suf = sep; /* Useful in 'from_right' case! */
}
- *suf = *sep = NULL;
+ *r_suf = *r_sep = NULL;
return str_len;
}
@@ -790,9 +786,9 @@ int BLI_str_utf8_offset_to_column(const char *str, int offset)
int BLI_str_utf8_offset_from_column(const char *str, int column)
{
- int offset = 0, pos = 0, col;
+ int offset = 0, pos = 0;
while (*(str + offset) && pos < column) {
- col = BLI_str_utf8_char_width_safe(str + offset);
+ const int col = BLI_str_utf8_char_width_safe(str + offset);
if (pos + col > column) {
break;
}
diff --git a/source/blender/blenlib/intern/system.c b/source/blender/blenlib/intern/system.c
index 35e26e0cb33..40a8fa24570 100644
--- a/source/blender/blenlib/intern/system.c
+++ b/source/blender/blenlib/intern/system.c
@@ -21,7 +21,9 @@
# include "BLI_winstuff.h"
#else
-# include <execinfo.h>
+# if defined(HAVE_EXECINFO_H)
+# include <execinfo.h>
+# endif
# include <unistd.h>
#endif
@@ -32,7 +34,7 @@ int BLI_cpu_support_sse2(void)
return 1;
#elif defined(__GNUC__) && defined(i386)
/* for GCC x86 we check cpuid */
- unsigned int d;
+ uint d;
__asm__(
"pushl %%ebx\n\t"
"cpuid\n\t"
@@ -42,7 +44,7 @@ int BLI_cpu_support_sse2(void)
return (d & 0x04000000) != 0;
#elif (defined(_MSC_VER) && defined(_M_IX86))
/* also check cpuid for MSVC x86 */
- unsigned int d;
+ uint d;
__asm {
xor eax, eax
inc eax
@@ -61,9 +63,9 @@ int BLI_cpu_support_sse2(void)
#if !defined(_MSC_VER)
void BLI_system_backtrace(FILE *fp)
{
- /* ------------- */
- /* Linux / Apple */
-# if defined(__linux__) || defined(__APPLE__)
+ /* ----------------------- */
+ /* If system as execinfo.h */
+# if defined(HAVE_EXECINFO_H)
# define SIZE 100
void *buffer[SIZE];
@@ -152,12 +154,12 @@ void BLI_hostname_get(char *buffer, size_t bufsize)
if (gethostname(buffer, bufsize - 1) < 0) {
BLI_strncpy(buffer, "-unknown-", bufsize);
}
- /* When gethostname() truncates, it doesn't guarantee the trailing \0. */
+ /* When `gethostname()` truncates, it doesn't guarantee the trailing `\0`. */
buffer[bufsize - 1] = '\0';
#else
DWORD bufsize_inout = bufsize;
if (!GetComputerName(buffer, &bufsize_inout)) {
- strncpy(buffer, "-unknown-", bufsize);
+ BLI_strncpy(buffer, "-unknown-", bufsize);
}
#endif
}
diff --git a/source/blender/blenlib/intern/task_graph.cc b/source/blender/blenlib/intern/task_graph.cc
index 6c1cc818d75..5bc84bf7573 100644
--- a/source/blender/blenlib/intern/task_graph.cc
+++ b/source/blender/blenlib/intern/task_graph.cc
@@ -75,7 +75,7 @@ struct TaskNode {
}
#ifdef WITH_TBB
- tbb::flow::continue_msg run(const tbb::flow::continue_msg UNUSED(input))
+ tbb::flow::continue_msg run(const tbb::flow::continue_msg /*input*/)
{
run_func(task_data);
return tbb::flow::continue_msg();
diff --git a/source/blender/blenlib/intern/task_iterator.c b/source/blender/blenlib/intern/task_iterator.c
index d5afbb2b117..99e966de975 100644
--- a/source/blender/blenlib/intern/task_iterator.c
+++ b/source/blender/blenlib/intern/task_iterator.c
@@ -26,10 +26,10 @@
* \{ */
/* Allows to avoid using malloc for userdata_chunk in tasks, when small enough. */
-#define MALLOCA(_size) ((_size) <= 8192) ? alloca((_size)) : MEM_mallocN((_size), __func__)
+#define MALLOCA(_size) ((_size) <= 8192) ? alloca(_size) : MEM_mallocN((_size), __func__)
#define MALLOCA_FREE(_mem, _size) \
if (((_mem) != NULL) && ((_size) > 8192)) { \
- MEM_freeN((_mem)); \
+ MEM_freeN(_mem); \
} \
((void)0)
diff --git a/source/blender/blenlib/intern/task_pool.cc b/source/blender/blenlib/intern/task_pool.cc
index a29dbe95ba9..c335d04413c 100644
--- a/source/blender/blenlib/intern/task_pool.cc
+++ b/source/blender/blenlib/intern/task_pool.cc
@@ -84,11 +84,11 @@ class Task {
free_taskdata(other.free_taskdata),
freedata(other.freedata)
{
- ((Task &)other).pool = NULL;
- ((Task &)other).run = NULL;
- ((Task &)other).taskdata = NULL;
+ ((Task &)other).pool = nullptr;
+ ((Task &)other).run = nullptr;
+ ((Task &)other).taskdata = nullptr;
((Task &)other).free_taskdata = false;
- ((Task &)other).freedata = NULL;
+ ((Task &)other).freedata = nullptr;
}
#else
Task(const Task &other) = delete;
diff --git a/source/blender/blenlib/intern/task_range.cc b/source/blender/blenlib/intern/task_range.cc
index 7e405529f03..20551aba93b 100644
--- a/source/blender/blenlib/intern/task_range.cc
+++ b/source/blender/blenlib/intern/task_range.cc
@@ -12,6 +12,7 @@
#include "DNA_listBase.h"
+#include "BLI_lazy_threading.hh"
#include "BLI_task.h"
#include "BLI_threads.h"
@@ -104,6 +105,8 @@ void BLI_task_parallel_range(const int start,
const size_t grainsize = MAX2(settings->min_iter_per_thread, 1);
const tbb::blocked_range<int> range(start, stop, grainsize);
+ blender::lazy_threading::send_hint();
+
if (settings->func_reduce) {
parallel_reduce(range, task);
if (settings->userdata_chunk) {
@@ -129,7 +132,7 @@ void BLI_task_parallel_range(const int start,
}
}
-int BLI_task_parallel_thread_id(const TaskParallelTLS *UNUSED(tls))
+int BLI_task_parallel_thread_id(const TaskParallelTLS * /*tls*/)
{
#ifdef WITH_TBB
/* Get a unique thread ID for texture nodes. In the future we should get rid
diff --git a/source/blender/blenlib/intern/threads.cc b/source/blender/blenlib/intern/threads.cc
index 37fccf6f4fe..f99a27c2475 100644
--- a/source/blender/blenlib/intern/threads.cc
+++ b/source/blender/blenlib/intern/threads.cc
@@ -37,17 +37,6 @@
#include "atomic_ops.h"
-#if defined(__APPLE__) && defined(_OPENMP) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2) && \
- !defined(__clang__)
-# define USE_APPLE_OMP_FIX
-#endif
-
-#ifdef USE_APPLE_OMP_FIX
-/* ************** libgomp (Apple gcc 4.2.1) TLS bug workaround *************** */
-extern pthread_key_t gomp_tls_key;
-static void *thread_tls_data;
-#endif
-
/**
* Basic Thread Control API
* ========================
@@ -108,7 +97,7 @@ static pthread_mutex_t _colormanage_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _fftw_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _view3d_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_t mainid;
-static unsigned int thread_levels = 0; /* threads can be invoked inside threads */
+static uint thread_levels = 0; /* threads can be invoked inside threads */
static int threads_override_num = 0;
/* just a max for security reasons */
@@ -153,15 +142,7 @@ void BLI_threadpool_init(ListBase *threadbase, void *(*do_thread)(void *), int t
}
}
- unsigned int level = atomic_fetch_and_add_u(&thread_levels, 1);
- if (level == 0) {
-#ifdef USE_APPLE_OMP_FIX
- /* Workaround for Apple gcc 4.2.1 OMP vs background thread bug,
- * we copy GOMP thread local storage pointer to setting it again
- * inside the thread that we start. */
- thread_tls_data = pthread_getspecific(gomp_tls_key);
-#endif
- }
+ atomic_fetch_and_add_u(&thread_levels, 1);
}
int BLI_available_threads(ListBase *threadbase)
@@ -194,13 +175,6 @@ int BLI_threadpool_available_thread_index(ListBase *threadbase)
static void *tslot_thread_start(void *tslot_p)
{
ThreadSlot *tslot = (ThreadSlot *)tslot_p;
-
-#ifdef USE_APPLE_OMP_FIX
- /* Workaround for Apple gcc 4.2.1 OMP vs background thread bug,
- * set GOMP thread local storage pointer which was copied beforehand */
- pthread_setspecific(gomp_tls_key, thread_tls_data);
-#endif
-
return tslot->do_thread(tslot->callerdata);
}
@@ -293,7 +267,7 @@ int BLI_system_thread_count()
#ifdef WIN32
SYSTEM_INFO info;
GetSystemInfo(&info);
- t = (int)info.dwNumberOfProcessors;
+ t = int(info.dwNumberOfProcessors);
#else
# ifdef __APPLE__
int mib[2];
@@ -304,7 +278,7 @@ int BLI_system_thread_count()
len = sizeof(t);
sysctl(mib, 2, &t, &len, nullptr, 0);
# else
- t = (int)sysconf(_SC_NPROCESSORS_ONLN);
+ t = int(sysconf(_SC_NPROCESSORS_ONLN));
# endif
#endif
}
@@ -524,7 +498,7 @@ void BLI_rw_mutex_free(ThreadRWMutex *mutex)
struct TicketMutex {
pthread_cond_t cond;
pthread_mutex_t mutex;
- unsigned int queue_head, queue_tail;
+ uint queue_head, queue_tail;
};
TicketMutex *BLI_ticket_mutex_alloc()
@@ -547,7 +521,7 @@ void BLI_ticket_mutex_free(TicketMutex *ticket)
void BLI_ticket_mutex_lock(TicketMutex *ticket)
{
- unsigned int queue_me;
+ uint queue_me;
pthread_mutex_lock(&ticket->mutex);
queue_me = ticket->queue_tail++;
diff --git a/source/blender/blenlib/intern/timecode.c b/source/blender/blenlib/intern/timecode.c
index fc78b0ad98d..ecaa469984d 100644
--- a/source/blender/blenlib/intern/timecode.c
+++ b/source/blender/blenlib/intern/timecode.c
@@ -176,7 +176,7 @@ size_t BLI_timecode_string_from_time_simple(char *str,
const int hr = ((int)time_seconds) / (60 * 60);
const int min = (((int)time_seconds) / 60) % 60;
const int sec = ((int)time_seconds) % 60;
- const int hun = ((int)(fmod(time_seconds, 1.0) * 100));
+ const int hun = (int)(fmod(time_seconds, 1.0) * 100);
if (hr) {
rlen = BLI_snprintf_rlen(str, maxncpy, "%.2d:%.2d:%.2d.%.2d", hr, min, sec, hun);
diff --git a/source/blender/blenlib/intern/uuid.cc b/source/blender/blenlib/intern/uuid.cc
index 890a721a9d1..023dd1ec409 100644
--- a/source/blender/blenlib/intern/uuid.cc
+++ b/source/blender/blenlib/intern/uuid.cc
@@ -136,10 +136,10 @@ bUUID::bUUID(const std::initializer_list<uint32_t> field_values)
const auto *field_iter = field_values.begin();
this->time_low = *field_iter++;
- this->time_mid = static_cast<uint16_t>(*field_iter++);
- this->time_hi_and_version = static_cast<uint16_t>(*field_iter++);
- this->clock_seq_hi_and_reserved = static_cast<uint8_t>(*field_iter++);
- this->clock_seq_low = static_cast<uint8_t>(*field_iter++);
+ this->time_mid = uint16_t(*field_iter++);
+ this->time_hi_and_version = uint16_t(*field_iter++);
+ this->clock_seq_hi_and_reserved = uint8_t(*field_iter++);
+ this->clock_seq_low = uint8_t(*field_iter++);
std::copy(field_iter, field_values.end(), this->node);
}
diff --git a/source/blender/blenlib/intern/winstuff.c b/source/blender/blenlib/intern/winstuff.c
index e90a0ee02db..7e2c5e8f1dd 100644
--- a/source/blender/blenlib/intern/winstuff.c
+++ b/source/blender/blenlib/intern/winstuff.c
@@ -63,23 +63,17 @@ bool BLI_windows_register_blend_extension(const bool background)
char buffer[256];
char BlPath[MAX_PATH];
- char InstallDir[FILE_MAXDIR];
- char SysDir[FILE_MAXDIR];
- const char *ThumbHandlerDLL;
- char RegCmd[MAX_PATH * 2];
char MBox[256];
- char *blender_app;
-# ifndef _WIN64
- BOOL IsWOW64;
-# endif
printf("Registering file extension...");
GetModuleFileName(0, BlPath, MAX_PATH);
/* Replace the actual app name with the wrapper. */
- blender_app = strstr(BlPath, "blender.exe");
- if (blender_app != NULL) {
- strcpy(blender_app, "blender-launcher.exe");
+ {
+ char *blender_app = strstr(BlPath, "blender.exe");
+ if (blender_app != NULL) {
+ strcpy(blender_app, "blender-launcher.exe");
+ }
}
/* root is HKLM by default */
@@ -157,12 +151,17 @@ bool BLI_windows_register_blend_extension(const bool background)
}
# ifdef WITH_BLENDER_THUMBNAILER
- BLI_windows_get_executable_dir(InstallDir);
- GetSystemDirectory(SysDir, FILE_MAXDIR);
- ThumbHandlerDLL = "BlendThumb.dll";
- snprintf(
- RegCmd, MAX_PATH * 2, "%s\\regsvr32 /s \"%s\\%s\"", SysDir, InstallDir, ThumbHandlerDLL);
- system(RegCmd);
+ {
+ char RegCmd[MAX_PATH * 2];
+ char InstallDir[FILE_MAXDIR];
+ char SysDir[FILE_MAXDIR];
+ BLI_windows_get_executable_dir(InstallDir);
+ GetSystemDirectory(SysDir, FILE_MAXDIR);
+ const char *ThumbHandlerDLL = "BlendThumb.dll";
+ snprintf(
+ RegCmd, MAX_PATH * 2, "%s\\regsvr32 /s \"%s\\%s\"", SysDir, InstallDir, ThumbHandlerDLL);
+ system(RegCmd);
+ }
# endif
RegCloseKey(root);
diff --git a/source/blender/blenlib/tests/BLI_array_store_test.cc b/source/blender/blenlib/tests/BLI_array_store_test.cc
index 20e2a4d88f8..c52d439308f 100644
--- a/source/blender/blenlib/tests/BLI_array_store_test.cc
+++ b/source/blender/blenlib/tests/BLI_array_store_test.cc
@@ -168,7 +168,7 @@ static void testbuffer_list_state_from_data__stride_expand(ListBase *lb,
#define testbuffer_list_state_from_string_array(lb, data_array) \
{ \
- unsigned int i_ = 0; \
+ uint i_ = 0; \
const char *data; \
while ((data = data_array[i_++])) { \
testbuffer_list_state_from_data(lb, data, strlen(data)); \
@@ -181,7 +181,7 @@ static void testbuffer_list_state_from_data__stride_expand(ListBase *lb,
#define TESTBUFFER_STRINGS_CREATE(lb, ...) \
{ \
BLI_listbase_clear(lb); \
- const char *data_array[] = {__VA_ARGS__ NULL}; \
+ const char *data_array[] = {__VA_ARGS__ nullptr}; \
testbuffer_list_state_from_string_array((lb), data_array); \
} \
((void)0)
@@ -224,7 +224,7 @@ static bool testbuffer_list_validate(const ListBase *lb)
return true;
}
-static void testbuffer_list_data_randomize(ListBase *lb, unsigned int random_seed)
+static void testbuffer_list_data_randomize(ListBase *lb, uint random_seed)
{
for (TestBuffer *tb = (TestBuffer *)lb->first; tb; tb = tb->next) {
BLI_array_randomize((void *)tb->data, 1, tb->data_len, random_seed++);
@@ -301,7 +301,7 @@ TEST(array_store, Nop)
TEST(array_store, NopState)
{
BArrayStore *bs = BLI_array_store_create(1, 32);
- const unsigned char data[] = "test";
+ const uchar data[] = "test";
BArrayState *state = BLI_array_store_state_add(bs, data, sizeof(data) - 1, nullptr);
EXPECT_EQ(BLI_array_store_state_size_get(state), sizeof(data) - 1);
BLI_array_store_state_remove(bs, state);
@@ -556,18 +556,15 @@ TEST(array_store, TextSentencesRandom_Stride128_Chunk6)
/* -------------------------------------------------------------------- */
/* Random Data Tests */
-static unsigned int rand_range_i(RNG *rng,
- unsigned int min_i,
- unsigned int max_i,
- unsigned int step)
+static uint rand_range_i(RNG *rng, uint min_i, uint max_i, uint step)
{
if (min_i == max_i) {
return min_i;
}
BLI_assert(min_i <= max_i);
BLI_assert(((min_i % step) == 0) && ((max_i % step) == 0));
- unsigned int range = (max_i - min_i);
- unsigned int value = BLI_rng_get_uint(rng) % range;
+ uint range = (max_i - min_i);
+ uint value = BLI_rng_get_uint(rng) % range;
value = (value / step) * step;
return min_i + value;
}
@@ -577,7 +574,7 @@ static void testbuffer_list_state_random_data(ListBase *lb,
const size_t data_min_len,
const size_t data_max_len,
- const unsigned int mutate,
+ const uint mutate,
RNG *rng)
{
size_t data_len = rand_range_i(rng, data_min_len, data_max_len + stride, stride);
@@ -607,12 +604,12 @@ static void testbuffer_list_state_random_data(ListBase *lb,
MUTATE_TOTAL,
};
- switch ((BLI_rng_get_uint(rng) % MUTATE_TOTAL)) {
+ switch (BLI_rng_get_uint(rng) % MUTATE_TOTAL) {
case MUTATE_NOP: {
break;
}
case MUTATE_ADD: {
- const unsigned int offset = rand_range_i(rng, 0, data_len, stride);
+ const uint offset = rand_range_i(rng, 0, data_len, stride);
if (data_len < data_max_len) {
data_len += stride;
data = (char *)MEM_reallocN((void *)data, data_len);
@@ -622,7 +619,7 @@ static void testbuffer_list_state_random_data(ListBase *lb,
break;
}
case MUTATE_REMOVE: {
- const unsigned int offset = rand_range_i(rng, 0, data_len, stride);
+ const uint offset = rand_range_i(rng, 0, data_len, stride);
if (data_len > data_min_len) {
memmove(&data[offset], &data[offset + stride], data_len - (offset + stride));
data_len -= stride;
@@ -638,7 +635,7 @@ static void testbuffer_list_state_random_data(ListBase *lb,
}
case MUTATE_RANDOMIZE: {
if (data_len > 0) {
- const unsigned int offset = rand_range_i(rng, 0, data_len - stride, stride);
+ const uint offset = rand_range_i(rng, 0, data_len - stride, stride);
BLI_rng_get_char_n(rng, &data[offset], stride);
}
break;
@@ -795,10 +792,10 @@ TEST(array_store, TestChunk_Rand31_Stride11_Chunk21)
/* Test From Files (disabled, keep for local tests.) */
-void *file_read_binary_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size)
+static void *file_read_binary_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size)
{
FILE *fp = fopen(filepath, "rb");
- void *mem = NULL;
+ void *mem = nullptr;
if (fp) {
long int filelen_read;
@@ -810,14 +807,14 @@ void *file_read_binary_as_mem(const char *filepath, size_t pad_bytes, size_t *r_
fseek(fp, 0L, SEEK_SET);
mem = MEM_mallocN(filelen + pad_bytes, __func__);
- if (mem == NULL) {
+ if (mem == nullptr) {
goto finally;
}
filelen_read = fread(mem, 1, filelen, fp);
if ((filelen_read != filelen) || ferror(fp)) {
MEM_freeN(mem);
- mem = NULL;
+ mem = nullptr;
goto finally;
}
diff --git a/source/blender/blenlib/tests/BLI_bit_vector_test.cc b/source/blender/blenlib/tests/BLI_bit_vector_test.cc
new file mode 100644
index 00000000000..210f2be012d
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_bit_vector_test.cc
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#include "BLI_bit_vector.hh"
+#include "BLI_exception_safety_test_utils.hh"
+#include "BLI_strict_flags.h"
+
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(bit_vector, DefaultConstructor)
+{
+ BitVector vec;
+ EXPECT_EQ(vec.size(), 0);
+}
+
+TEST(bit_vector, CopyConstructorInline)
+{
+ BitVector<> vec({false, false, true, true, false});
+ BitVector<> vec2 = vec;
+
+ EXPECT_EQ(vec.size(), 5);
+ EXPECT_EQ(vec2.size(), 5);
+
+ vec2[1].set();
+ EXPECT_FALSE(vec[1]);
+
+ EXPECT_FALSE(vec2[0]);
+ EXPECT_TRUE(vec2[1]);
+ EXPECT_TRUE(vec2[2]);
+ EXPECT_TRUE(vec2[3]);
+ EXPECT_FALSE(vec2[4]);
+}
+
+TEST(bit_vector, CopyConstructorLarge)
+{
+ BitVector<> vec(500, false);
+ vec[1].set();
+
+ BitVector<> vec2 = vec;
+
+ EXPECT_EQ(vec.size(), 500);
+ EXPECT_EQ(vec2.size(), 500);
+
+ vec2[2].set();
+ EXPECT_FALSE(vec[2]);
+
+ EXPECT_FALSE(vec2[0]);
+ EXPECT_TRUE(vec2[1]);
+ EXPECT_TRUE(vec2[2]);
+}
+
+TEST(bit_vector, MoveConstructorInline)
+{
+ BitVector<> vec({false, false, true, true, false});
+ BitVector<> vec2 = std::move(vec);
+
+ EXPECT_EQ(vec.size(), 0);
+ EXPECT_EQ(vec2.size(), 5);
+
+ EXPECT_FALSE(vec2[0]);
+ EXPECT_FALSE(vec2[1]);
+ EXPECT_TRUE(vec2[2]);
+ EXPECT_TRUE(vec2[3]);
+ EXPECT_FALSE(vec2[4]);
+}
+
+TEST(bit_vector, MoveConstructorLarge)
+{
+ BitVector<> vec(500, false);
+ vec[3].set();
+
+ BitVector<> vec2 = std::move(vec);
+
+ EXPECT_EQ(vec.size(), 0);
+ EXPECT_EQ(vec2.size(), 500);
+
+ EXPECT_FALSE(vec2[0]);
+ EXPECT_FALSE(vec2[1]);
+ EXPECT_FALSE(vec2[2]);
+ EXPECT_TRUE(vec2[3]);
+ EXPECT_FALSE(vec2[4]);
+}
+
+TEST(bit_vector, SizeConstructor)
+{
+ {
+ BitVector<> vec(0);
+ EXPECT_EQ(vec.size(), 0);
+ }
+ {
+ BitVector<> vec(5);
+ EXPECT_EQ(vec.size(), 5);
+ for (BitRef bit : vec) {
+ EXPECT_FALSE(bit);
+ }
+ }
+ {
+ BitVector<> vec(123);
+ EXPECT_EQ(vec.size(), 123);
+ for (BitRef bit : vec) {
+ EXPECT_FALSE(bit);
+ }
+ }
+}
+
+TEST(bit_vector, SizeFillConstructor)
+{
+ {
+ BitVector<> vec(5, false);
+ for (const int64_t i : IndexRange(5)) {
+ EXPECT_FALSE(vec[i]);
+ }
+ }
+ {
+ BitVector<> vec(123, true);
+ for (const int64_t i : IndexRange(123)) {
+ EXPECT_TRUE(vec[i]);
+ }
+ }
+}
+
+TEST(bit_vector, IndexAccess)
+{
+ BitVector<> vec(100, false);
+ vec[55].set();
+ EXPECT_FALSE(vec[50]);
+ EXPECT_FALSE(vec[51]);
+ EXPECT_FALSE(vec[52]);
+ EXPECT_FALSE(vec[53]);
+ EXPECT_FALSE(vec[54]);
+ EXPECT_TRUE(vec[55]);
+ EXPECT_FALSE(vec[56]);
+ EXPECT_FALSE(vec[57]);
+ EXPECT_FALSE(vec[58]);
+}
+
+TEST(bit_vector, Iterator)
+{
+ BitVector<> vec(100, false);
+ {
+ int64_t index = 0;
+ for (MutableBitRef bit : vec) {
+ bit.set(ELEM(index, 0, 4, 7, 10, 11));
+ index++;
+ }
+ }
+ {
+ int64_t index = 0;
+ for (BitRef bit : const_cast<const BitVector<> &>(vec)) {
+ EXPECT_EQ(bit, ELEM(index, 0, 4, 7, 10, 11));
+ index++;
+ }
+ }
+}
+
+TEST(bit_vector, Append)
+{
+ BitVector<> vec;
+ vec.append(false);
+ vec.append(true);
+ vec.append(true);
+ vec.append(false);
+
+ EXPECT_EQ(vec.size(), 4);
+ EXPECT_FALSE(vec[0]);
+ EXPECT_TRUE(vec[1]);
+ EXPECT_TRUE(vec[2]);
+ EXPECT_FALSE(vec[3]);
+}
+
+TEST(bit_vector, AppendMany)
+{
+ BitVector<> vec;
+ for (const int64_t i : IndexRange(1000)) {
+ vec.append(i % 2);
+ }
+ EXPECT_FALSE(vec[0]);
+ EXPECT_TRUE(vec[1]);
+ EXPECT_FALSE(vec[2]);
+ EXPECT_TRUE(vec[3]);
+ EXPECT_FALSE(vec[4]);
+ EXPECT_TRUE(vec[5]);
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_cpp_type_test.cc b/source/blender/blenlib/tests/BLI_cpp_type_test.cc
index 6a59bedc649..5823d54f51b 100644
--- a/source/blender/blenlib/tests/BLI_cpp_type_test.cc
+++ b/source/blender/blenlib/tests/BLI_cpp_type_test.cc
@@ -63,7 +63,7 @@ struct TestType {
return stream;
}
- friend bool operator==(const TestType &UNUSED(a), const TestType &UNUSED(b))
+ friend bool operator==(const TestType & /*a*/, const TestType & /*b*/)
{
return false;
}
diff --git a/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc b/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc
index 25ee523ebc0..ca99c678754 100644
--- a/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc
+++ b/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc
@@ -99,7 +99,7 @@ template<typename T> CDT_input<T> fill_input_from_string(const char *spec)
*/
static int get_orig_index(const Array<Vector<int>> &out_to_orig, int orig_index)
{
- int n = static_cast<int>(out_to_orig.size());
+ int n = int(out_to_orig.size());
for (int i = 0; i < n; ++i) {
for (int orig : out_to_orig[i]) {
if (orig == orig_index) {
@@ -110,7 +110,7 @@ static int get_orig_index(const Array<Vector<int>> &out_to_orig, int orig_index)
return -1;
}
-template<typename T> static double math_to_double(const T UNUSED(v))
+template<typename T> static double math_to_double(const T /*v*/)
{
BLI_assert(false); /* Need implementation for other type. */
return 0.0;
@@ -147,7 +147,7 @@ template<> double math_abs(const double v)
*/
template<typename T> int get_vertex_by_coord(const CDT_result<T> &out, double x, double y)
{
- int nv = static_cast<int>(out.vert.size());
+ int nv = int(out.vert.size());
for (int i = 0; i < nv; ++i) {
double vx = math_to_double(out.vert[i][0]);
double vy = math_to_double(out.vert[i][1]);
@@ -162,7 +162,7 @@ template<typename T> int get_vertex_by_coord(const CDT_result<T> &out, double x,
template<typename T>
int get_output_edge_index(const CDT_result<T> &out, int out_index_1, int out_index_2)
{
- int ne = static_cast<int>(out.edge.size());
+ int ne = int(out.edge.size());
for (int i = 0; i < ne; ++i) {
if ((out.edge[i].first == out_index_1 && out.edge[i].second == out_index_2) ||
(out.edge[i].first == out_index_2 && out.edge[i].second == out_index_1)) {
@@ -175,7 +175,7 @@ int get_output_edge_index(const CDT_result<T> &out, int out_index_1, int out_ind
template<typename T>
bool output_edge_has_input_id(const CDT_result<T> &out, int out_edge_index, int in_edge_index)
{
- return out_edge_index < static_cast<int>(out.edge_orig.size()) &&
+ return out_edge_index < int(out.edge_orig.size()) &&
out.edge_orig[out_edge_index].contains(in_edge_index);
}
@@ -184,8 +184,8 @@ bool output_edge_has_input_id(const CDT_result<T> &out, int out_edge_index, int
*/
template<typename T> int get_output_face_index(const CDT_result<T> &out, const Array<int> &poly)
{
- int nf = static_cast<int>(out.face.size());
- int npolyv = static_cast<int>(poly.size());
+ int nf = int(out.face.size());
+ int npolyv = int(poly.size());
for (int f = 0; f < nf; ++f) {
if (out.face[f].size() != poly.size()) {
continue;
@@ -218,7 +218,7 @@ int get_output_tri_index(const CDT_result<T> &out,
template<typename T>
bool output_face_has_input_id(const CDT_result<T> &out, int out_face_index, int in_face_index)
{
- return out_face_index < static_cast<int>(out.face_orig.size()) &&
+ return out_face_index < int(out.face_orig.size()) &&
out.face_orig[out_face_index].contains(in_face_index);
}
@@ -310,10 +310,10 @@ void graph_draw(const std::string &label,
double height = maxy - miny;
double aspect = height / width;
int view_width = max_draw_width;
- int view_height = static_cast<int>(view_width * aspect);
+ int view_height = int(view_width * aspect);
if (view_height > max_draw_height) {
view_height = max_draw_height;
- view_width = static_cast<int>(view_height / aspect);
+ view_width = int(view_height / aspect);
}
double scale = view_width / width;
diff --git a/source/blender/blenlib/tests/BLI_edgehash_test.cc b/source/blender/blenlib/tests/BLI_edgehash_test.cc
index 301fa226016..f6e987c7060 100644
--- a/source/blender/blenlib/tests/BLI_edgehash_test.cc
+++ b/source/blender/blenlib/tests/BLI_edgehash_test.cc
@@ -308,7 +308,7 @@ TEST(edgehash, StressTest)
std::vector<Edge> edges;
for (int i = 0; i < amount; i++) {
- edges.push_back({(uint)i, amount + (uint)std::rand() % 12345});
+ edges.push_back({uint(i), amount + uint(std::rand()) % 12345});
}
EdgeHash *eh = BLI_edgehash_new(__func__);
diff --git a/source/blender/blenlib/tests/BLI_exception_safety_test_utils.hh b/source/blender/blenlib/tests/BLI_exception_safety_test_utils.hh
index 63943e48f0e..367d8508a20 100644
--- a/source/blender/blenlib/tests/BLI_exception_safety_test_utils.hh
+++ b/source/blender/blenlib/tests/BLI_exception_safety_test_utils.hh
@@ -87,7 +87,7 @@ class ExceptionThrower {
uint64_t hash() const
{
- return static_cast<uint64_t>(value);
+ return uint64_t(value);
}
friend bool operator==(const ExceptionThrower &a, const ExceptionThrower &b)
diff --git a/source/blender/blenlib/tests/BLI_float3x3_test.cc b/source/blender/blenlib/tests/BLI_float3x3_test.cc
index d22993ee69e..cd823b6e368 100644
--- a/source/blender/blenlib/tests/BLI_float3x3_test.cc
+++ b/source/blender/blenlib/tests/BLI_float3x3_test.cc
@@ -34,6 +34,15 @@ TEST(float3x3, Rotation)
EXPECT_FLOAT_EQ(result[1], 1.0f);
}
+TEST(float3x3, Scale)
+{
+ float2 point(1.0f, 2.0f);
+ float3x3 transformation = float3x3::from_scale(float2(2.0f, 3.0f));
+ float2 result = transformation * point;
+ EXPECT_FLOAT_EQ(result[0], 2.0f);
+ EXPECT_FLOAT_EQ(result[1], 6.0f);
+}
+
TEST(float3x3, TranslationRotationScale)
{
float2 point(1.0f, 2.0f);
@@ -116,4 +125,11 @@ TEST(float3x3, Origin)
EXPECT_FLOAT_EQ(result[1], 3.0f);
}
+TEST(float3x3, GetScale2D)
+{
+ float2 scale(2.0f, 3.0f);
+ float3x3 transformation = float3x3::from_scale(scale);
+ EXPECT_EQ(scale, transformation.scale_2d());
+}
+
} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_generic_array_test.cc b/source/blender/blenlib/tests/BLI_generic_array_test.cc
index 52bc7728a6a..8e32430eede 100644
--- a/source/blender/blenlib/tests/BLI_generic_array_test.cc
+++ b/source/blender/blenlib/tests/BLI_generic_array_test.cc
@@ -20,7 +20,7 @@ TEST(generic_array, TypeConstructor)
TEST(generic_array, MoveConstructor)
{
- GArray array_a(CPPType::get<int32_t>(), (int64_t)10);
+ GArray array_a(CPPType::get<int32_t>(), int64_t(10));
GMutableSpan span_a = array_a.as_mutable_span();
MutableSpan<int32_t> typed_span_a = span_a.typed<int32_t>();
typed_span_a.fill(42);
@@ -40,7 +40,7 @@ TEST(generic_array, MoveConstructor)
TEST(generic_array, CopyConstructor)
{
- GArray array_a(CPPType::get<int32_t>(), (int64_t)10);
+ GArray array_a(CPPType::get<int32_t>(), int64_t(10));
GMutableSpan span_a = array_a.as_mutable_span();
MutableSpan<int32_t> typed_span_a = span_a.typed<int32_t>();
typed_span_a.fill(42);
@@ -79,7 +79,7 @@ TEST(generic_array, BufferAndSizeConstructor)
TEST(generic_array, Reinitialize)
{
- GArray array(CPPType::get<int32_t>(), (int64_t)5);
+ GArray array(CPPType::get<int32_t>(), int64_t(5));
EXPECT_FALSE(array.data() == nullptr);
GMutableSpan span = array.as_mutable_span();
MutableSpan<int32_t> typed_span = span.typed<int32_t>();
@@ -106,7 +106,7 @@ TEST(generic_array, InContainer)
{
blender::Array<GArray<>> arrays;
for (GArray<> &array : arrays) {
- array = GArray(CPPType::get<int32_t>(), (int64_t)5);
+ array = GArray(CPPType::get<int32_t>(), int64_t(5));
array.as_mutable_span().typed<int32_t>().fill(55);
}
for (GArray<> &array : arrays) {
@@ -114,4 +114,13 @@ TEST(generic_array, InContainer)
}
}
+TEST(generic_array, ReinitEmpty)
+{
+ GArray<> array(CPPType::get<int>());
+ array.reinitialize(10);
+ array.as_mutable_span().typed<int>()[9] = 7;
+ EXPECT_EQ(array.size(), 10);
+ EXPECT_EQ(array.as_span().typed<int>()[9], 7);
+}
+
} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_ghash_test.cc b/source/blender/blenlib/tests/BLI_ghash_test.cc
index da5207cb3f8..5e763dc928f 100644
--- a/source/blender/blenlib/tests/BLI_ghash_test.cc
+++ b/source/blender/blenlib/tests/BLI_ghash_test.cc
@@ -34,10 +34,10 @@
/* NOTE: for pure-ghash testing, nature of the keys and data have absolutely no importance! So here
* we just use mere random integers stored in pointers. */
-static void init_keys(unsigned int keys[TESTCASE_SIZE], const int seed)
+static void init_keys(uint keys[TESTCASE_SIZE], const int seed)
{
RNG *rng = BLI_rng_new(seed);
- unsigned int *k;
+ uint *k;
int i;
for (i = 0, k = keys; i < TESTCASE_SIZE;) {
@@ -61,7 +61,7 @@ static void init_keys(unsigned int keys[TESTCASE_SIZE], const int seed)
TEST(ghash, InsertLookup)
{
GHash *ghash = BLI_ghash_new(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__);
- unsigned int keys[TESTCASE_SIZE], *k;
+ uint keys[TESTCASE_SIZE], *k;
int i;
init_keys(keys, 0);
@@ -85,7 +85,7 @@ TEST(ghash, InsertLookup)
TEST(ghash, InsertRemove)
{
GHash *ghash = BLI_ghash_new(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__);
- unsigned int keys[TESTCASE_SIZE], *k;
+ uint keys[TESTCASE_SIZE], *k;
int i, bkt_size;
init_keys(keys, 10);
@@ -112,7 +112,7 @@ TEST(ghash, InsertRemove)
TEST(ghash, InsertRemoveShrink)
{
GHash *ghash = BLI_ghash_new(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__);
- unsigned int keys[TESTCASE_SIZE], *k;
+ uint keys[TESTCASE_SIZE], *k;
int i, bkt_size;
BLI_ghash_flag_set(ghash, GHASH_FLAG_ALLOW_SHRINK);
@@ -141,7 +141,7 @@ TEST(ghash, Copy)
{
GHash *ghash = BLI_ghash_new(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__);
GHash *ghash_copy;
- unsigned int keys[TESTCASE_SIZE], *k;
+ uint keys[TESTCASE_SIZE], *k;
int i;
init_keys(keys, 30);
@@ -170,7 +170,7 @@ TEST(ghash, Copy)
TEST(ghash, Pop)
{
GHash *ghash = BLI_ghash_new(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__);
- unsigned int keys[TESTCASE_SIZE], *k;
+ uint keys[TESTCASE_SIZE], *k;
int i;
BLI_ghash_flag_set(ghash, GHASH_FLAG_ALLOW_SHRINK);
diff --git a/source/blender/blenlib/tests/BLI_hash_mm2a_test.cc b/source/blender/blenlib/tests/BLI_hash_mm2a_test.cc
index 99bb107840f..90f5aa6189f 100644
--- a/source/blender/blenlib/tests/BLI_hash_mm2a_test.cc
+++ b/source/blender/blenlib/tests/BLI_hash_mm2a_test.cc
@@ -16,7 +16,7 @@ TEST(hash_mm2a, MM2ABasic)
const char *data = "Blender";
BLI_hash_mm2a_init(&mm2, 0);
- BLI_hash_mm2a_add(&mm2, (const unsigned char *)data, strlen(data));
+ BLI_hash_mm2a_add(&mm2, (const uchar *)data, strlen(data));
#ifdef __LITTLE_ENDIAN__
EXPECT_EQ(BLI_hash_mm2a_end(&mm2), 1633988145);
#else
@@ -35,12 +35,12 @@ TEST(hash_mm2a, MM2AConcatenateStrings)
const char *data123 = "Blender is FaNtAsTiC";
BLI_hash_mm2a_init(&mm2, 0);
- BLI_hash_mm2a_add(&mm2, (const unsigned char *)data1, strlen(data1));
- BLI_hash_mm2a_add(&mm2, (const unsigned char *)data2, strlen(data2));
- BLI_hash_mm2a_add(&mm2, (const unsigned char *)data3, strlen(data3));
+ BLI_hash_mm2a_add(&mm2, (const uchar *)data1, strlen(data1));
+ BLI_hash_mm2a_add(&mm2, (const uchar *)data2, strlen(data2));
+ BLI_hash_mm2a_add(&mm2, (const uchar *)data3, strlen(data3));
hash = BLI_hash_mm2a_end(&mm2);
BLI_hash_mm2a_init(&mm2, 0);
- BLI_hash_mm2a_add(&mm2, (const unsigned char *)data123, strlen(data123));
+ BLI_hash_mm2a_add(&mm2, (const uchar *)data123, strlen(data123));
#ifdef __LITTLE_ENDIAN__
EXPECT_EQ(hash, 1545105348);
#else
@@ -63,7 +63,7 @@ TEST(hash_mm2a, MM2AIntegers)
BLI_hash_mm2a_add_int(&mm2, ints[3]);
hash = BLI_hash_mm2a_end(&mm2);
BLI_hash_mm2a_init(&mm2, 0);
- BLI_hash_mm2a_add(&mm2, (const unsigned char *)ints, sizeof(ints));
+ BLI_hash_mm2a_add(&mm2, (const uchar *)ints, sizeof(ints));
/* Yes, same hash here on little and big endian. */
#ifdef __LITTLE_ENDIAN__
EXPECT_EQ(hash, 405493096);
diff --git a/source/blender/blenlib/tests/BLI_heap_simple_test.cc b/source/blender/blenlib/tests/BLI_heap_simple_test.cc
index 818de67740b..96a5e42374e 100644
--- a/source/blender/blenlib/tests/BLI_heap_simple_test.cc
+++ b/source/blender/blenlib/tests/BLI_heap_simple_test.cc
@@ -18,7 +18,7 @@ static void range_fl(float *array_tar, const int size)
float *array_pt = array_tar + (size - 1);
int i = size;
while (i--) {
- *(array_pt--) = (float)i;
+ *(array_pt--) = float(i);
}
}
@@ -53,7 +53,7 @@ TEST(heap, SimpleRange)
const int items_total = SIZE;
HeapSimple *heap = BLI_heapsimple_new();
for (int in = 0; in < items_total; in++) {
- BLI_heapsimple_insert(heap, (float)in, POINTER_FROM_INT(in));
+ BLI_heapsimple_insert(heap, float(in), POINTER_FROM_INT(in));
}
for (int out_test = 0; out_test < items_total; out_test++) {
EXPECT_EQ(out_test, POINTER_AS_INT(BLI_heapsimple_pop_min(heap)));
@@ -67,7 +67,7 @@ TEST(heap, SimpleRangeReverse)
const int items_total = SIZE;
HeapSimple *heap = BLI_heapsimple_new();
for (int in = 0; in < items_total; in++) {
- BLI_heapsimple_insert(heap, (float)-in, POINTER_FROM_INT(-in));
+ BLI_heapsimple_insert(heap, float(-in), POINTER_FROM_INT(-in));
}
for (int out_test = items_total - 1; out_test >= 0; out_test--) {
EXPECT_EQ(-out_test, POINTER_AS_INT(BLI_heapsimple_pop_min(heap)));
@@ -97,7 +97,7 @@ static void random_heapsimple_helper(const int items_total, const int random_see
range_fl(values, items_total);
BLI_array_randomize(values, sizeof(float), items_total, random_seed);
for (int i = 0; i < items_total; i++) {
- BLI_heapsimple_insert(heap, values[i], POINTER_FROM_INT((int)values[i]));
+ BLI_heapsimple_insert(heap, values[i], POINTER_FROM_INT(int(values[i])));
}
for (int out_test = 0; out_test < items_total; out_test++) {
EXPECT_EQ(out_test, POINTER_AS_INT(BLI_heapsimple_pop_min(heap)));
diff --git a/source/blender/blenlib/tests/BLI_heap_test.cc b/source/blender/blenlib/tests/BLI_heap_test.cc
index 333a1530b6d..f2368ce4abf 100644
--- a/source/blender/blenlib/tests/BLI_heap_test.cc
+++ b/source/blender/blenlib/tests/BLI_heap_test.cc
@@ -17,7 +17,7 @@ static void range_fl(float *array_tar, const int size)
float *array_pt = array_tar + (size - 1);
int i = size;
while (i--) {
- *(array_pt--) = (float)i;
+ *(array_pt--) = float(i);
}
}
@@ -52,7 +52,7 @@ TEST(heap, Range)
const int items_total = SIZE;
Heap *heap = BLI_heap_new();
for (int in = 0; in < items_total; in++) {
- BLI_heap_insert(heap, (float)in, POINTER_FROM_INT(in));
+ BLI_heap_insert(heap, float(in), POINTER_FROM_INT(in));
}
for (int out_test = 0; out_test < items_total; out_test++) {
EXPECT_EQ(out_test, POINTER_AS_INT(BLI_heap_pop_min(heap)));
@@ -66,7 +66,7 @@ TEST(heap, RangeReverse)
const int items_total = SIZE;
Heap *heap = BLI_heap_new();
for (int in = 0; in < items_total; in++) {
- BLI_heap_insert(heap, (float)-in, POINTER_FROM_INT(-in));
+ BLI_heap_insert(heap, float(-in), POINTER_FROM_INT(-in));
}
for (int out_test = items_total - 1; out_test >= 0; out_test--) {
EXPECT_EQ(-out_test, POINTER_AS_INT(BLI_heap_pop_min(heap)));
@@ -81,7 +81,7 @@ TEST(heap, RangeRemove)
Heap *heap = BLI_heap_new();
HeapNode **nodes = (HeapNode **)MEM_mallocN(sizeof(HeapNode *) * items_total, __func__);
for (int in = 0; in < items_total; in++) {
- nodes[in] = BLI_heap_insert(heap, (float)in, POINTER_FROM_INT(in));
+ nodes[in] = BLI_heap_insert(heap, float(in), POINTER_FROM_INT(in));
}
for (int i = 0; i < items_total; i += 2) {
BLI_heap_remove(heap, nodes[i]);
@@ -116,7 +116,7 @@ static void random_heap_helper(const int items_total, const int random_seed)
range_fl(values, items_total);
BLI_array_randomize(values, sizeof(float), items_total, random_seed);
for (int i = 0; i < items_total; i++) {
- BLI_heap_insert(heap, values[i], POINTER_FROM_INT((int)values[i]));
+ BLI_heap_insert(heap, values[i], POINTER_FROM_INT(int(values[i])));
}
for (int out_test = 0; out_test < items_total; out_test++) {
EXPECT_EQ(out_test, POINTER_AS_INT(BLI_heap_pop_min(heap)));
@@ -145,10 +145,10 @@ TEST(heap, ReInsertSimple)
Heap *heap = BLI_heap_new();
HeapNode **nodes = (HeapNode **)MEM_mallocN(sizeof(HeapNode *) * items_total, __func__);
for (int in = 0; in < items_total; in++) {
- nodes[in] = BLI_heap_insert(heap, (float)in, POINTER_FROM_INT(in));
+ nodes[in] = BLI_heap_insert(heap, float(in), POINTER_FROM_INT(in));
}
for (int i = 0; i < items_total; i++) {
- BLI_heap_node_value_update(heap, nodes[i], (float)(items_total + i));
+ BLI_heap_node_value_update(heap, nodes[i], float(items_total + i));
}
for (int out_test = 0; out_test < items_total; out_test++) {
@@ -165,11 +165,11 @@ static void random_heap_reinsert_helper(const int items_total, const int random_
Heap *heap = BLI_heap_new();
HeapNode **nodes = (HeapNode **)MEM_mallocN(sizeof(HeapNode *) * items_total, __func__);
for (int in = 0; in < items_total; in++) {
- nodes[in] = BLI_heap_insert(heap, (float)in, POINTER_FROM_INT(in));
+ nodes[in] = BLI_heap_insert(heap, float(in), POINTER_FROM_INT(in));
}
BLI_array_randomize(nodes, sizeof(HeapNode *), items_total, random_seed);
for (int i = 0; i < items_total; i++) {
- BLI_heap_node_value_update(heap, nodes[i], (float)i);
+ BLI_heap_node_value_update(heap, nodes[i], float(i));
}
EXPECT_TRUE(BLI_heap_is_valid(heap));
@@ -177,7 +177,7 @@ static void random_heap_reinsert_helper(const int items_total, const int random_
HeapNode *node_top = BLI_heap_top(heap);
float out = BLI_heap_node_value(node_top);
EXPECT_EQ(out, BLI_heap_top_value(heap));
- EXPECT_EQ((float)out_test, out);
+ EXPECT_EQ(float(out_test), out);
BLI_heap_pop_min(heap);
}
EXPECT_TRUE(BLI_heap_is_empty(heap));
diff --git a/source/blender/blenlib/tests/BLI_index_range_test.cc b/source/blender/blenlib/tests/BLI_index_range_test.cc
index f5b994d409a..8ec7ad85d9c 100644
--- a/source/blender/blenlib/tests/BLI_index_range_test.cc
+++ b/source/blender/blenlib/tests/BLI_index_range_test.cc
@@ -126,6 +126,17 @@ TEST(index_range, Slice)
EXPECT_EQ(slice.last(), 12);
}
+TEST(index_range, Intersect)
+{
+ IndexRange range = IndexRange(5, 15);
+ EXPECT_EQ(range.intersect(IndexRange(2, 2)), IndexRange(5, 0));
+ EXPECT_EQ(range.intersect(IndexRange(4, 2)), IndexRange(5, 1));
+ EXPECT_EQ(range.intersect(IndexRange(3, 20)), IndexRange(5, 15));
+ EXPECT_EQ(range.intersect(IndexRange(5, 15)), IndexRange(5, 15));
+ EXPECT_EQ(range.intersect(IndexRange(15, 10)), IndexRange(15, 5));
+ EXPECT_EQ(range.intersect(IndexRange(22, 2)), IndexRange(20, 0));
+}
+
TEST(index_range, SliceRange)
{
IndexRange range = IndexRange(5, 15);
@@ -235,4 +246,50 @@ TEST(index_range, GenericAlgorithms)
EXPECT_EQ(std::count_if(range.begin(), range.end(), [](int v) { return v < 7; }), 3);
}
+TEST(index_range, SplitByAlignment)
+{
+ {
+ AlignedIndexRanges ranges = split_index_range_by_alignment(IndexRange(0, 0), 16);
+ EXPECT_EQ(ranges.prefix, IndexRange());
+ EXPECT_EQ(ranges.aligned, IndexRange());
+ EXPECT_EQ(ranges.suffix, IndexRange());
+ }
+ {
+ AlignedIndexRanges ranges = split_index_range_by_alignment(IndexRange(0, 24), 8);
+ EXPECT_EQ(ranges.prefix, IndexRange());
+ EXPECT_EQ(ranges.aligned, IndexRange(0, 24));
+ EXPECT_EQ(ranges.suffix, IndexRange());
+ }
+ {
+ AlignedIndexRanges ranges = split_index_range_by_alignment(IndexRange(1, 2), 4);
+ EXPECT_EQ(ranges.prefix, IndexRange(1, 2));
+ EXPECT_EQ(ranges.aligned, IndexRange());
+ EXPECT_EQ(ranges.suffix, IndexRange());
+ }
+ {
+ AlignedIndexRanges ranges = split_index_range_by_alignment(IndexRange(3, 50), 8);
+ EXPECT_EQ(ranges.prefix, IndexRange(3, 5));
+ EXPECT_EQ(ranges.aligned, IndexRange(8, 40));
+ EXPECT_EQ(ranges.suffix, IndexRange(48, 5));
+ }
+ {
+ AlignedIndexRanges ranges = split_index_range_by_alignment(IndexRange(3, 50), 1);
+ EXPECT_EQ(ranges.prefix, IndexRange());
+ EXPECT_EQ(ranges.aligned, IndexRange(3, 50));
+ EXPECT_EQ(ranges.suffix, IndexRange());
+ }
+ {
+ AlignedIndexRanges ranges = split_index_range_by_alignment(IndexRange(64, 16), 16);
+ EXPECT_EQ(ranges.prefix, IndexRange());
+ EXPECT_EQ(ranges.aligned, IndexRange(64, 16));
+ EXPECT_EQ(ranges.suffix, IndexRange());
+ }
+ {
+ AlignedIndexRanges ranges = split_index_range_by_alignment(IndexRange(3, 5), 8);
+ EXPECT_EQ(ranges.prefix, IndexRange(3, 5));
+ EXPECT_EQ(ranges.aligned, IndexRange());
+ EXPECT_EQ(ranges.suffix, IndexRange());
+ }
+}
+
} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_kdopbvh_test.cc b/source/blender/blenlib/tests/BLI_kdopbvh_test.cc
index 756219cd733..83eeabaea40 100644
--- a/source/blender/blenlib/tests/BLI_kdopbvh_test.cc
+++ b/source/blender/blenlib/tests/BLI_kdopbvh_test.cc
@@ -18,7 +18,7 @@ static void rng_v3_round(float *coords, int coords_len, struct RNG *rng, int rou
{
for (int i = 0; i < coords_len; i++) {
float f = BLI_rng_get_float(rng) * 2.0f - 1.0f;
- coords[i] = ((float)((int)(f * round)) / (float)round) * scale;
+ coords[i] = (float(int(f * round)) / float(round)) * scale;
}
}
@@ -90,7 +90,7 @@ static void find_nearest_points_test(
if (j != i) {
#if 0
const float dist = len_v3v3(points[i], points[j]);
- if (dist > (1.0f / (float)round)) {
+ if (dist > (1.0f / float(round))) {
printf("%.15f (%d %d)\n", dist, i, j);
print_v3_id(points[i]);
print_v3_id(points[j]);
diff --git a/source/blender/blenlib/tests/BLI_linear_allocator_test.cc b/source/blender/blenlib/tests/BLI_linear_allocator_test.cc
index b67683d0558..2ed1786f9e0 100644
--- a/source/blender/blenlib/tests/BLI_linear_allocator_test.cc
+++ b/source/blender/blenlib/tests/BLI_linear_allocator_test.cc
@@ -9,7 +9,7 @@ namespace blender::tests {
static bool is_aligned(void *ptr, uint alignment)
{
- BLI_assert(is_power_of_2_i(static_cast<int>(alignment)));
+ BLI_assert(is_power_of_2_i(int(alignment)));
return (POINTER_AS_UINT(ptr) & (alignment - 1)) == 0;
}
@@ -36,13 +36,13 @@ TEST(linear_allocator, PackedAllocation)
blender::AlignedBuffer<256, 32> buffer;
allocator.provide_buffer(buffer);
- uintptr_t ptr1 = (uintptr_t)allocator.allocate(10, 4); /* 0 - 10 */
- uintptr_t ptr2 = (uintptr_t)allocator.allocate(10, 4); /* 12 - 22 */
- uintptr_t ptr3 = (uintptr_t)allocator.allocate(8, 32); /* 32 - 40 */
- uintptr_t ptr4 = (uintptr_t)allocator.allocate(16, 8); /* 40 - 56 */
- uintptr_t ptr5 = (uintptr_t)allocator.allocate(1, 8); /* 56 - 57 */
- uintptr_t ptr6 = (uintptr_t)allocator.allocate(1, 4); /* 60 - 61 */
- uintptr_t ptr7 = (uintptr_t)allocator.allocate(1, 1); /* 61 - 62 */
+ uintptr_t ptr1 = uintptr_t(allocator.allocate(10, 4)); /* 0 - 10 */
+ uintptr_t ptr2 = uintptr_t(allocator.allocate(10, 4)); /* 12 - 22 */
+ uintptr_t ptr3 = uintptr_t(allocator.allocate(8, 32)); /* 32 - 40 */
+ uintptr_t ptr4 = uintptr_t(allocator.allocate(16, 8)); /* 40 - 56 */
+ uintptr_t ptr5 = uintptr_t(allocator.allocate(1, 8)); /* 56 - 57 */
+ uintptr_t ptr6 = uintptr_t(allocator.allocate(1, 4)); /* 60 - 61 */
+ uintptr_t ptr7 = uintptr_t(allocator.allocate(1, 1)); /* 61 - 62 */
EXPECT_EQ(ptr2 - ptr1, 12); /* 12 - 0 = 12 */
EXPECT_EQ(ptr3 - ptr2, 20); /* 32 - 12 = 20 */
@@ -130,7 +130,7 @@ TEST(linear_allocator, ManyAllocations)
RandomNumberGenerator rng;
for (int i = 0; i < 1000; i++) {
int size = rng.get_int32(10000);
- int alignment = 1 << (rng.get_int32(7));
+ int alignment = 1 << rng.get_int32(7);
void *buffer = allocator.allocate(size, alignment);
EXPECT_NE(buffer, nullptr);
}
diff --git a/source/blender/blenlib/tests/BLI_listbase_test.cc b/source/blender/blenlib/tests/BLI_listbase_test.cc
index aa2f885e39d..abdd4f90221 100644
--- a/source/blender/blenlib/tests/BLI_listbase_test.cc
+++ b/source/blender/blenlib/tests/BLI_listbase_test.cc
@@ -222,7 +222,7 @@ static bool testsort_listbase_array_str_cmp(ListBase *lb, char **arr, int arr_nu
link_step = (LinkData *)lb->first;
for (i = 0; i < arr_num; i++) {
- if (strcmp(arr[i], (char *)link_step->data) != 0) {
+ if (!STREQ(arr[i], (char *)link_step->data)) {
return false;
}
link_step = link_step->next;
@@ -241,7 +241,7 @@ static bool testsort_listbase_sort_is_stable(ListBase *lb, bool forward)
link_step = (LinkData *)lb->first;
while (link_step && link_step->next) {
- if (strcmp((const char *)link_step->data, (const char *)link_step->next->data) == 0) {
+ if (STREQ((const char *)link_step->data, (const char *)link_step->next->data)) {
if ((link_step < link_step->next) != forward) {
return false;
}
diff --git a/source/blender/blenlib/tests/BLI_map_test.cc b/source/blender/blenlib/tests/BLI_map_test.cc
index dbbd4843abc..69ae82d6f05 100644
--- a/source/blender/blenlib/tests/BLI_map_test.cc
+++ b/source/blender/blenlib/tests/BLI_map_test.cc
@@ -560,8 +560,8 @@ TEST(map, PopExceptions)
TEST(map, AddOrModifyExceptions)
{
Map<ExceptionThrower, ExceptionThrower> map;
- auto create_fn = [](ExceptionThrower *UNUSED(v)) { throw std::runtime_error(""); };
- auto modify_fn = [](ExceptionThrower *UNUSED(v)) {};
+ auto create_fn = [](ExceptionThrower * /*v*/) { throw std::runtime_error(""); };
+ auto modify_fn = [](ExceptionThrower * /*v*/) {};
EXPECT_ANY_THROW({ map.add_or_modify(3, create_fn, modify_fn); });
}
@@ -640,6 +640,24 @@ TEST(map, RemoveDuringIteration)
EXPECT_EQ(map.lookup(3), 3);
}
+TEST(map, RemoveIf)
+{
+ Map<int64_t, int64_t> map;
+ for (const int64_t i : IndexRange(100)) {
+ map.add(i * i, i);
+ }
+ map.remove_if([](auto item) { return item.key > 100; });
+ EXPECT_EQ(map.size(), 11);
+ for (const int64_t i : IndexRange(100)) {
+ if (i <= 10) {
+ EXPECT_EQ(map.lookup(i * i), i);
+ }
+ else {
+ EXPECT_FALSE(map.contains(i * i));
+ }
+ }
+}
+
TEST(map, LookupKey)
{
Map<std::string, int> map;
diff --git a/source/blender/blenlib/tests/BLI_math_color_test.cc b/source/blender/blenlib/tests/BLI_math_color_test.cc
index 4d928477870..0b6f9340379 100644
--- a/source/blender/blenlib/tests/BLI_math_color_test.cc
+++ b/source/blender/blenlib/tests/BLI_math_color_test.cc
@@ -68,7 +68,7 @@ TEST(math_color, LinearRGBTosRGBRoundtrip)
const int N = 50;
int i;
for (i = 0; i < N; ++i) {
- float orig_linear_color = (float)i / N;
+ float orig_linear_color = float(i) / N;
float srgb_color = linearrgb_to_srgb(orig_linear_color);
float linear_color = srgb_to_linearrgb(srgb_color);
EXPECT_NEAR(orig_linear_color, linear_color, 1e-5);
diff --git a/source/blender/blenlib/tests/BLI_math_rotation_test.cc b/source/blender/blenlib/tests/BLI_math_rotation_test.cc
index a283118bea2..e37b212e1df 100644
--- a/source/blender/blenlib/tests/BLI_math_rotation_test.cc
+++ b/source/blender/blenlib/tests/BLI_math_rotation_test.cc
@@ -7,6 +7,8 @@
#include "BLI_math_rotation.hh"
#include "BLI_math_vector.hh"
+#include "BLI_vector.hh"
+
#include <cmath>
/* Test that quaternion converts to itself via matrix. */
@@ -150,6 +152,107 @@ TEST(math_rotation, quat_split_swing_and_twist_negative)
EXPECT_V4_NEAR(twist, expected_twist, FLT_EPSILON);
}
+/* -------------------------------------------------------------------- */
+/** \name Test `sin_cos_from_fraction` Accuracy & Exact Symmetry
+ * \{ */
+
+static void test_sin_cos_from_fraction_accuracy(const int range, const float expected_eps)
+{
+ for (int i = 0; i < range; i++) {
+ float sin_cos_fl[2];
+ sin_cos_from_fraction(i, range, &sin_cos_fl[0], &sin_cos_fl[1]);
+ const float phi = float(2.0 * M_PI) * (float(i) / float(range));
+ const float sin_cos_test_fl[2] = {sinf(phi), cosf(phi)};
+ EXPECT_V2_NEAR(sin_cos_fl, sin_cos_test_fl, expected_eps);
+ }
+}
+
+/** Ensure the result of #sin_cos_from_fraction match #sinf & #cosf. */
+TEST(math_rotation, sin_cos_from_fraction_accuracy)
+{
+ for (int range = 1; range <= 64; range++) {
+ test_sin_cos_from_fraction_accuracy(range, 1e-6f);
+ }
+}
+
+/** Ensure values are exactly symmetrical where possible. */
+static void test_sin_cos_from_fraction_symmetry(const int range)
+{
+ /* The expected number of unique numbers depends on the range being a multiple of 4/2/1. */
+ const enum {
+ MULTIPLE_OF_1 = 1,
+ MULTIPLE_OF_2 = 2,
+ MULTIPLE_OF_4 = 3,
+ } multiple_of = (range & 1) ? MULTIPLE_OF_1 : ((range & 3) ? MULTIPLE_OF_2 : MULTIPLE_OF_4);
+
+ blender::Vector<blender::float2> coords;
+ coords.reserve(range);
+ for (int i = 0; i < range; i++) {
+ float sin_cos_fl[2];
+ sin_cos_from_fraction(i, range, &sin_cos_fl[0], &sin_cos_fl[1]);
+ switch (multiple_of) {
+ case MULTIPLE_OF_1: {
+ sin_cos_fl[0] = fabsf(sin_cos_fl[0]);
+ break;
+ }
+ case MULTIPLE_OF_2: {
+ sin_cos_fl[0] = fabsf(sin_cos_fl[0]);
+ sin_cos_fl[1] = fabsf(sin_cos_fl[1]);
+ break;
+ }
+ case MULTIPLE_OF_4: {
+ sin_cos_fl[0] = fabsf(sin_cos_fl[0]);
+ sin_cos_fl[1] = fabsf(sin_cos_fl[1]);
+ if (sin_cos_fl[0] > sin_cos_fl[1]) {
+ SWAP(float, sin_cos_fl[0], sin_cos_fl[1]);
+ }
+ break;
+ }
+ }
+ coords.append_unchecked(sin_cos_fl);
+ }
+ /* Sort, then count unique items. */
+ std::sort(coords.begin(), coords.end(), [](const blender::float2 &a, const blender::float2 &b) {
+ float delta = b[0] - a[0];
+ if (delta == 0.0f) {
+ delta = b[1] - a[1];
+ }
+ return delta > 0.0f;
+ });
+ int unique_coords_count = 1;
+ if (range > 1) {
+ int i_prev = 0;
+ for (int i = 1; i < range; i_prev = i++) {
+ if (coords[i_prev] != coords[i]) {
+ unique_coords_count += 1;
+ }
+ }
+ }
+ switch (multiple_of) {
+ case MULTIPLE_OF_1: {
+ EXPECT_EQ(unique_coords_count, (range / 2) + 1);
+ break;
+ }
+ case MULTIPLE_OF_2: {
+ EXPECT_EQ(unique_coords_count, (range / 4) + 1);
+ break;
+ }
+ case MULTIPLE_OF_4: {
+ EXPECT_EQ(unique_coords_count, (range / 8) + 1);
+ break;
+ }
+ }
+}
+
+TEST(math_rotation, sin_cos_from_fraction_symmetry)
+{
+ for (int range = 1; range <= 64; range++) {
+ test_sin_cos_from_fraction_symmetry(range);
+ }
+}
+
+/** \} */
+
namespace blender::math::tests {
TEST(math_rotation, RotateDirectionAroundAxis)
diff --git a/source/blender/blenlib/tests/BLI_memory_utils_test.cc b/source/blender/blenlib/tests/BLI_memory_utils_test.cc
index ab716e5d011..939ac6151b0 100644
--- a/source/blender/blenlib/tests/BLI_memory_utils_test.cc
+++ b/source/blender/blenlib/tests/BLI_memory_utils_test.cc
@@ -20,7 +20,7 @@ struct MyValue {
alive++;
}
- MyValue(const MyValue &UNUSED(other))
+ MyValue(const MyValue & /*other*/)
{
if (alive == 15) {
throw std::exception();
diff --git a/source/blender/blenlib/tests/BLI_mesh_boolean_test.cc b/source/blender/blenlib/tests/BLI_mesh_boolean_test.cc
index fabc2412828..ea324534d78 100644
--- a/source/blender/blenlib/tests/BLI_mesh_boolean_test.cc
+++ b/source/blender/blenlib/tests/BLI_mesh_boolean_test.cc
@@ -106,7 +106,7 @@ class IMeshBuilder {
}
};
-static int all_shape_zero(int UNUSED(t))
+static int all_shape_zero(int /*t*/)
{
return 0;
}
diff --git a/source/blender/blenlib/tests/BLI_mesh_intersect_test.cc b/source/blender/blenlib/tests/BLI_mesh_intersect_test.cc
index c155068b94a..67a5771593a 100644
--- a/source/blender/blenlib/tests/BLI_mesh_intersect_test.cc
+++ b/source/blender/blenlib/tests/BLI_mesh_intersect_test.cc
@@ -153,7 +153,7 @@ static int find_edge_pos_in_tri(const Vert *v0, const Vert *v1, const Face *f)
for (int pos : f->index_range()) {
int nextpos = f->next_pos(pos);
if (((*f)[pos] == v0 && (*f)[nextpos] == v1) || ((*f)[pos] == v1 && (*f)[nextpos] == v0)) {
- return static_cast<int>(pos);
+ return int(pos);
}
}
return -1;
diff --git a/source/blender/blenlib/tests/BLI_path_util_test.cc b/source/blender/blenlib/tests/BLI_path_util_test.cc
index 4f6f4a5c413..89e537235db 100644
--- a/source/blender/blenlib/tests/BLI_path_util_test.cc
+++ b/source/blender/blenlib/tests/BLI_path_util_test.cc
@@ -207,7 +207,7 @@ TEST(path_util, NameAtIndex_NoneComplexNeg)
char result[(out_size) + 1024]; \
/* check we don't write past the last byte */ \
result[out_size] = '\0'; \
- BLI_path_join(result, out_size, __VA_ARGS__, NULL); \
+ BLI_path_join(result, out_size, __VA_ARGS__); \
/* simplify expected string */ \
BLI_str_replace_char(result, '\\', '/'); \
EXPECT_STREQ(result, expect); \
@@ -298,6 +298,13 @@ TEST(path_util, JoinComplex)
JOIN("1/2/3/", 100, "1", "////////", "", "2", "3\\");
}
+TEST(path_util, JoinRelativePrefix)
+{
+ JOIN("//a/b/c", 100, "//a", "b", "c");
+ JOIN("//a/b/c", 100, "//", "//a//", "//b//", "//c");
+ JOIN("//a/b/c", 100, "//", "//", "a", "//", "b", "//", "c");
+}
+
#undef JOIN
/* BLI_path_frame */
@@ -459,7 +466,7 @@ TEST(path_util, PathFrameStrip)
#define PATH_EXTENSION_CHECK(input_path, input_ext, expect_ext) \
{ \
const bool ret = BLI_path_extension_check(input_path, input_ext); \
- if (strcmp(input_ext, expect_ext) == 0) { \
+ if (STREQ(input_ext, expect_ext)) { \
EXPECT_TRUE(ret); \
} \
else { \
@@ -644,7 +651,7 @@ TEST(path_util, PathRelPath)
abs_path_in[FILE_MAX - 1] = '\0';
abs_path_out[0] = '/';
abs_path_out[1] = '/';
- for (int i = 2; i < FILE_MAX - ((int)ref_path_in_len - 1); i++) {
+ for (int i = 2; i < FILE_MAX - (int(ref_path_in_len) - 1); i++) {
abs_path_out[i] = 'A';
}
abs_path_out[FILE_MAX - (ref_path_in_len - 1)] = '\0';
diff --git a/source/blender/blenlib/tests/BLI_polyfill_2d_test.cc b/source/blender/blenlib/tests/BLI_polyfill_2d_test.cc
index db2fb1ba671..f3b66bedf88 100644
--- a/source/blender/blenlib/tests/BLI_polyfill_2d_test.cc
+++ b/source/blender/blenlib/tests/BLI_polyfill_2d_test.cc
@@ -29,20 +29,20 @@
static void polyfill_to_obj(const char *id,
const float poly[][2],
- const unsigned int poly_num,
- const unsigned int tris[][3],
- const unsigned int tris_num);
+ const uint poly_num,
+ const uint tris[][3],
+ const uint tris_num);
/* -------------------------------------------------------------------- */
/* test utility functions */
-#define TRI_ERROR_VALUE (unsigned int)-1
+#define TRI_ERROR_VALUE (uint) - 1
-static void test_valid_polyfill_prepare(unsigned int tris[][3], unsigned int tris_num)
+static void test_valid_polyfill_prepare(uint tris[][3], uint tris_num)
{
- unsigned int i;
+ uint i;
for (i = 0; i < tris_num; i++) {
- unsigned int j;
+ uint j;
for (j = 0; j < 3; j++) {
tris[i][j] = TRI_ERROR_VALUE;
}
@@ -57,14 +57,14 @@ static void test_valid_polyfill_prepare(unsigned int tris[][3], unsigned int tri
* - all verts used at least once.
*/
static void test_polyfill_simple(const float /*poly*/[][2],
- const unsigned int poly_num,
- const unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ const uint tris[][3],
+ const uint tris_num)
{
- unsigned int i;
+ uint i;
int *used_num = (int *)MEM_callocN(poly_num * sizeof(int), __func__);
for (i = 0; i < tris_num; i++) {
- unsigned int j;
+ uint j;
for (j = 0; j < 3; j++) {
EXPECT_NE(TRI_ERROR_VALUE, tris[i][j]);
used_num[tris[i][j]] += 1;
@@ -80,41 +80,41 @@ static void test_polyfill_simple(const float /*poly*/[][2],
}
static void test_polyfill_topology(const float /*poly*/[][2],
- const unsigned int poly_num,
- const unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ const uint tris[][3],
+ const uint tris_num)
{
EdgeHash *edgehash = BLI_edgehash_new(__func__);
EdgeHashIterator *ehi;
- unsigned int i;
+ uint i;
for (i = 0; i < tris_num; i++) {
- unsigned int j;
+ uint j;
for (j = 0; j < 3; j++) {
- const unsigned int v1 = tris[i][j];
- const unsigned int v2 = tris[i][(j + 1) % 3];
+ const uint v1 = tris[i][j];
+ const uint v2 = tris[i][(j + 1) % 3];
void **p = BLI_edgehash_lookup_p(edgehash, v1, v2);
if (p) {
- *p = (void *)((intptr_t)*p + (intptr_t)1);
+ *p = (void *)(intptr_t(*p) + intptr_t(1));
}
else {
- BLI_edgehash_insert(edgehash, v1, v2, (void *)(intptr_t)1);
+ BLI_edgehash_insert(edgehash, v1, v2, (void *)intptr_t(1));
}
}
}
EXPECT_EQ(BLI_edgehash_len(edgehash), poly_num + (poly_num - 3));
for (i = 0; i < poly_num; i++) {
- const unsigned int v1 = i;
- const unsigned int v2 = (i + 1) % poly_num;
+ const uint v1 = i;
+ const uint v2 = (i + 1) % poly_num;
void **p = BLI_edgehash_lookup_p(edgehash, v1, v2);
EXPECT_NE((void *)p, nullptr);
- EXPECT_EQ((intptr_t)*p, 1);
+ EXPECT_EQ(intptr_t(*p), 1);
}
for (ehi = BLI_edgehashIterator_new(edgehash), i = 0; BLI_edgehashIterator_isDone(ehi) == false;
BLI_edgehashIterator_step(ehi), i++) {
void **p = BLI_edgehashIterator_getValue_p(ehi);
- EXPECT_TRUE(ELEM((intptr_t)*p, 1, 2));
+ EXPECT_TRUE(ELEM(intptr_t(*p), 1, 2));
}
BLI_edgehashIterator_free(ehi);
@@ -125,12 +125,12 @@ static void test_polyfill_topology(const float /*poly*/[][2],
* Check all faces are flipped the same way
*/
static void test_polyfill_winding(const float poly[][2],
- const unsigned int /*poly_num*/,
- const unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint /*poly_num*/,
+ const uint tris[][3],
+ const uint tris_num)
{
- unsigned int i;
- unsigned int count[2] = {0, 0};
+ uint i;
+ uint count[2] = {0, 0};
for (i = 0; i < tris_num; i++) {
float winding_test = cross_tri_v2(poly[tris[i][0]], poly[tris[i][1]], poly[tris[i][2]]);
if (fabsf(winding_test) > FLT_EPSILON) {
@@ -144,11 +144,11 @@ static void test_polyfill_winding(const float poly[][2],
* Check the accumulated triangle area is close to the original area.
*/
static void test_polyfill_area(const float poly[][2],
- const unsigned int poly_num,
- const unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ const uint tris[][3],
+ const uint tris_num)
{
- unsigned int i;
+ uint i;
const float area_total = area_poly_v2(poly, poly_num);
float area_total_tris = 0.0f;
const float eps_abs = 0.00001f;
@@ -167,9 +167,9 @@ static void test_polyfill_area(const float poly[][2],
static void test_polyfill_template_check(const char *id,
bool is_degenerate,
const float poly[][2],
- const unsigned int poly_num,
- const unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ const uint tris[][3],
+ const uint tris_num)
{
test_polyfill_simple(poly, poly_num, tris, tris_num);
test_polyfill_topology(poly, poly_num, tris, tris_num);
@@ -184,9 +184,9 @@ static void test_polyfill_template_check(const char *id,
static void test_polyfill_template(const char *id,
bool is_degenerate,
const float poly[][2],
- const unsigned int poly_num,
- unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ uint tris[][3],
+ const uint tris_num)
{
test_valid_polyfill_prepare(tris, tris_num);
BLI_polyfill_calc(poly, poly_num, 0, tris);
@@ -213,9 +213,9 @@ static void test_polyfill_template(const char *id,
static void test_polyfill_template_flip_sign(const char *id,
bool is_degenerate,
const float poly[][2],
- const unsigned int poly_num,
- unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ uint tris[][3],
+ const uint tris_num)
{
float(*poly_copy)[2] = (float(*)[2])MEM_mallocN(sizeof(float[2]) * poly_num, id);
for (int flip_x = 0; flip_x < 2; flip_x++) {
@@ -236,19 +236,19 @@ static void test_polyfill_template_flip_sign(const char *id,
static void test_polyfill_template_main(const char *id,
bool is_degenerate,
const float poly[][2],
- const unsigned int poly_num,
- unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ uint tris[][3],
+ const uint tris_num)
{
/* overkill? - try at _every_ offset & reverse */
- unsigned int poly_reverse;
+ uint poly_reverse;
float(*poly_copy)[2] = (float(*)[2])MEM_mallocN(sizeof(float[2]) * poly_num, id);
float tmp[2];
memcpy(poly_copy, poly, sizeof(float[2]) * poly_num);
for (poly_reverse = 0; poly_reverse < 2; poly_reverse++) {
- unsigned int poly_cycle;
+ uint poly_cycle;
if (poly_reverse) {
BLI_array_reverse(poly_copy, poly_num);
@@ -271,9 +271,9 @@ static void test_polyfill_template_main(const char *id,
static void test_polyfill_template_main(const char *id,
bool is_degenerate,
const float poly[][2],
- const unsigned int poly_num,
- unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ uint tris[][3],
+ const uint tris_num)
{
test_polyfill_template_flip_sign(id, is_degenerate, poly, poly_num, tris, tris_num);
}
@@ -281,9 +281,9 @@ static void test_polyfill_template_main(const char *id,
#define TEST_POLYFILL_TEMPLATE_STATIC(poly, is_degenerate) \
{ \
- unsigned int tris[POLY_TRI_COUNT(ARRAY_SIZE(poly))][3]; \
- const unsigned int poly_num = ARRAY_SIZE(poly); \
- const unsigned int tris_num = ARRAY_SIZE(tris); \
+ uint tris[POLY_TRI_COUNT(ARRAY_SIZE(poly))][3]; \
+ const uint poly_num = ARRAY_SIZE(poly); \
+ const uint tris_num = ARRAY_SIZE(tris); \
const char *id = typeid(*this).name(); \
\
test_polyfill_template_main(id, is_degenerate, poly, poly_num, tris, tris_num); \
@@ -296,13 +296,13 @@ static void test_polyfill_template_main(const char *id,
#ifdef USE_OBJ_PREVIEW
static void polyfill_to_obj(const char *id,
const float poly[][2],
- const unsigned int poly_num,
- const unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ const uint tris[][3],
+ const uint tris_num)
{
char path[1024];
FILE *f;
- unsigned int i;
+ uint i;
BLI_snprintf(path, sizeof(path), "%s.obj", id);
@@ -324,9 +324,9 @@ static void polyfill_to_obj(const char *id,
#else
static void polyfill_to_obj(const char *id,
const float poly[][2],
- const unsigned int poly_num,
- const unsigned int tris[][3],
- const unsigned int tris_num)
+ const uint poly_num,
+ const uint tris[][3],
+ const uint tris_num)
{
(void)id;
(void)poly, (void)poly_num;
diff --git a/source/blender/blenlib/tests/BLI_pool_test.cc b/source/blender/blenlib/tests/BLI_pool_test.cc
new file mode 100644
index 00000000000..31cb255d997
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_pool_test.cc
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#include "BLI_exception_safety_test_utils.hh"
+#include "BLI_pool.hh"
+#include "BLI_strict_flags.h"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(pool, DefaultConstructor)
+{
+ Pool<int> pool;
+ EXPECT_EQ(pool.size(), 0);
+}
+
+TEST(pool, Allocation)
+{
+ Vector<int *> ptrs;
+ Pool<int> pool;
+ for (int i = 0; i < 100; i++) {
+ ptrs.append(&pool.construct(i));
+ }
+ EXPECT_EQ(pool.size(), 100);
+
+ for (int *ptr : ptrs) {
+ pool.destruct(*ptr);
+ }
+ EXPECT_EQ(pool.size(), 0);
+}
+
+TEST(pool, Reuse)
+{
+ Vector<int *> ptrs;
+ Pool<int> pool;
+ for (int i = 0; i < 32; i++) {
+ ptrs.append(&pool.construct(i));
+ }
+
+ int *freed_ptr = ptrs[6];
+ pool.destruct(*freed_ptr);
+
+ ptrs[6] = &pool.construct(0);
+
+ EXPECT_EQ(ptrs[6], freed_ptr);
+
+ for (int *ptr : ptrs) {
+ pool.destruct(*ptr);
+ }
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_set_test.cc b/source/blender/blenlib/tests/BLI_set_test.cc
index 5a97b2c7999..79439eb9079 100644
--- a/source/blender/blenlib/tests/BLI_set_test.cc
+++ b/source/blender/blenlib/tests/BLI_set_test.cc
@@ -532,8 +532,14 @@ TEST(set, ForwardIterator)
Set<int>::iterator iter1 = set.begin();
int value1 = *iter1;
Set<int>::iterator iter2 = iter1++;
- EXPECT_EQ(*iter1, value1);
- EXPECT_EQ(*iter2, *(++iter1));
+ EXPECT_EQ(*iter2, value1);
+ EXPECT_EQ(*(++iter2), *iter1);
+ /* Interesting find: On GCC & MSVC this will succeed, as the 2nd argument is evaluated before the
+ * 1st. On Apple Clang it's the other way around, and the test fails. */
+ // EXPECT_EQ(*iter1, *(++iter1));
+ Set<int>::iterator iter3 = ++iter1;
+ /* Check that #iter1 itself changed. */
+ EXPECT_EQ(*iter3, *iter1);
}
TEST(set, GenericAlgorithms)
@@ -570,6 +576,19 @@ TEST(set, RemoveDuringIteration)
EXPECT_TRUE(set.contains(3));
}
+TEST(set, RemoveIf)
+{
+ Set<int64_t> set;
+ for (const int64_t i : IndexRange(100)) {
+ set.add(i * i);
+ }
+ set.remove_if([](const int64_t key) { return key > 100; });
+ EXPECT_EQ(set.size(), 11);
+ for (const int64_t i : IndexRange(100)) {
+ EXPECT_EQ(set.contains(i * i), i <= 10);
+ }
+}
+
/**
* Set this to 1 to activate the benchmark. It is disabled by default, because it prints a lot.
*/
diff --git a/source/blender/blenlib/tests/BLI_span_test.cc b/source/blender/blenlib/tests/BLI_span_test.cc
index 0bd34250deb..2dec84c4206 100644
--- a/source/blender/blenlib/tests/BLI_span_test.cc
+++ b/source/blender/blenlib/tests/BLI_span_test.cc
@@ -237,7 +237,7 @@ TEST(span, SizeInBytes)
{
std::array<int, 10> a{};
Span<int> a_span(a);
- EXPECT_EQ(a_span.size_in_bytes(), static_cast<int64_t>(sizeof(a)));
+ EXPECT_EQ(a_span.size_in_bytes(), int64_t(sizeof(a)));
EXPECT_EQ(a_span.size_in_bytes(), 40);
}
@@ -280,7 +280,7 @@ TEST(span, ContainsPtr)
EXPECT_TRUE(a_span.contains_ptr(&a[0] + 1));
EXPECT_TRUE(a_span.contains_ptr(&a[0] + 2));
EXPECT_FALSE(a_span.contains_ptr(&a[0] + 3));
- int *ptr_before = reinterpret_cast<int *>(reinterpret_cast<uintptr_t>(a.data()) - 1);
+ int *ptr_before = reinterpret_cast<int *>(uintptr_t(a.data()) - 1);
EXPECT_FALSE(a_span.contains_ptr(ptr_before));
EXPECT_FALSE(a_span.contains_ptr(&other));
}
diff --git a/source/blender/blenlib/tests/BLI_stack_cxx_test.cc b/source/blender/blenlib/tests/BLI_stack_cxx_test.cc
index 0707759666d..13d417d4374 100644
--- a/source/blender/blenlib/tests/BLI_stack_cxx_test.cc
+++ b/source/blender/blenlib/tests/BLI_stack_cxx_test.cc
@@ -118,19 +118,19 @@ TEST(stack, PushPopMany)
Stack<int> stack;
for (int i = 0; i < 1000; i++) {
stack.push(i);
- EXPECT_EQ(stack.size(), static_cast<unsigned int>(i + 1));
+ EXPECT_EQ(stack.size(), uint(i + 1));
}
for (int i = 999; i > 50; i--) {
EXPECT_EQ(stack.pop(), i);
- EXPECT_EQ(stack.size(), static_cast<unsigned int>(i));
+ EXPECT_EQ(stack.size(), uint(i));
}
for (int i = 51; i < 5000; i++) {
stack.push(i);
- EXPECT_EQ(stack.size(), static_cast<unsigned int>(i + 1));
+ EXPECT_EQ(stack.size(), uint(i + 1));
}
for (int i = 4999; i >= 0; i--) {
EXPECT_EQ(stack.pop(), i);
- EXPECT_EQ(stack.size(), static_cast<unsigned int>(i));
+ EXPECT_EQ(stack.size(), uint(i));
}
}
@@ -191,7 +191,7 @@ TEST(stack, OveralignedValues)
Stack<AlignedBuffer<1, 512>, 2> stack;
for (int i = 0; i < 100; i++) {
stack.push({});
- EXPECT_EQ((uintptr_t)&stack.peek() % 512, 0);
+ EXPECT_EQ(uintptr_t(&stack.peek()) % 512, 0);
}
}
diff --git a/source/blender/blenlib/tests/BLI_stack_test.cc b/source/blender/blenlib/tests/BLI_stack_test.cc
index 216c8bd6d55..5f361a78929 100644
--- a/source/blender/blenlib/tests/BLI_stack_test.cc
+++ b/source/blender/blenlib/tests/BLI_stack_test.cc
@@ -28,7 +28,7 @@ TEST(stack, Empty)
TEST(stack, One)
{
BLI_Stack *stack;
- unsigned int in = -1, out = 1;
+ uint in = -1, out = 1;
stack = BLI_stack_new(sizeof(in), __func__);
diff --git a/source/blender/blenlib/tests/BLI_string_ref_test.cc b/source/blender/blenlib/tests/BLI_string_ref_test.cc
index c3bb53f39d5..478b68a005e 100644
--- a/source/blender/blenlib/tests/BLI_string_ref_test.cc
+++ b/source/blender/blenlib/tests/BLI_string_ref_test.cc
@@ -357,7 +357,7 @@ TEST(string_ref, Constexpr)
constexpr StringRef sref("World");
BLI_STATIC_ASSERT(sref[2] == 'r', "");
BLI_STATIC_ASSERT(sref.size() == 5, "");
- std::array<int, static_cast<std::size_t>(sref.find_first_of('o'))> compiles = {1};
+ std::array<int, std::size_t(sref.find_first_of('o'))> compiles = {1};
EXPECT_EQ(compiles[0], 1);
}
} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_string_search_test.cc b/source/blender/blenlib/tests/BLI_string_search_test.cc
index aa6adae8d76..ab1d073ed33 100644
--- a/source/blender/blenlib/tests/BLI_string_search_test.cc
+++ b/source/blender/blenlib/tests/BLI_string_search_test.cc
@@ -9,7 +9,7 @@
namespace blender::string_search::tests {
/* Right arrow, keep in sync with #UI_MENU_ARROW_SEP in `UI_interface.h`. */
-#define UI_MENU_ARROW_SEP "\xe2\x96\xb6"
+#define UI_MENU_ARROW_SEP "\xe2\x96\xb8"
TEST(string_search, damerau_levenshtein_distance)
{
diff --git a/source/blender/blenlib/tests/BLI_string_test.cc b/source/blender/blenlib/tests/BLI_string_test.cc
index eaaa65dd39f..d726fbccf20 100644
--- a/source/blender/blenlib/tests/BLI_string_test.cc
+++ b/source/blender/blenlib/tests/BLI_string_test.cc
@@ -174,7 +174,7 @@ TEST(string, StrPartitionEx)
/* BLI_str_partition_utf8 */
TEST(string, StrPartitionUtf8)
{
- const unsigned int delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
+ const uint delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
const char *sep, *suf;
size_t pre_len;
@@ -233,7 +233,7 @@ TEST(string, StrPartitionUtf8)
/* BLI_str_rpartition_utf8 */
TEST(string, StrRPartitionUtf8)
{
- const unsigned int delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
+ const uint delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
const char *sep, *suf;
size_t pre_len;
@@ -292,7 +292,7 @@ TEST(string, StrRPartitionUtf8)
/* BLI_str_partition_ex_utf8 */
TEST(string, StrPartitionExUtf8)
{
- const unsigned int delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
+ const uint delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
const char *sep, *suf;
size_t pre_len;
@@ -515,6 +515,103 @@ TEST(string, StrFormatDecimalUnits)
EXPECT_STREQ("-2.1B", size_str);
}
+/* BLI_str_format_integer_unit */
+TEST(string, StrFormatIntegerUnits)
+{
+ char size_str[7];
+ int size;
+
+ BLI_str_format_integer_unit(size_str, size = 0);
+ EXPECT_STREQ("0", size_str);
+ BLI_str_format_integer_unit(size_str, size = 1);
+ EXPECT_STREQ("1", size_str);
+ BLI_str_format_integer_unit(size_str, size = 10);
+ EXPECT_STREQ("10", size_str);
+ BLI_str_format_integer_unit(size_str, size = 15);
+ EXPECT_STREQ("15", size_str);
+ BLI_str_format_integer_unit(size_str, size = 100);
+ EXPECT_STREQ("100", size_str);
+ BLI_str_format_integer_unit(size_str, size = 155);
+ EXPECT_STREQ("155", size_str);
+ BLI_str_format_integer_unit(size_str, size = 1000);
+ EXPECT_STREQ("1K", size_str);
+ BLI_str_format_integer_unit(size_str, size = 1555);
+ EXPECT_STREQ("1K", size_str);
+ BLI_str_format_integer_unit(size_str, size = 10000);
+ EXPECT_STREQ("10K", size_str);
+ BLI_str_format_integer_unit(size_str, size = 15555);
+ EXPECT_STREQ("15K", size_str);
+ BLI_str_format_integer_unit(size_str, size = 100000);
+ EXPECT_STREQ(".1M", size_str);
+ BLI_str_format_integer_unit(size_str, size = 155555);
+ EXPECT_STREQ(".1M", size_str);
+ BLI_str_format_integer_unit(size_str, size = 1000000);
+ EXPECT_STREQ("1M", size_str);
+ BLI_str_format_integer_unit(size_str, size = 1555555);
+ EXPECT_STREQ("1M", size_str);
+ BLI_str_format_integer_unit(size_str, size = 2555555);
+ EXPECT_STREQ("2M", size_str);
+ BLI_str_format_integer_unit(size_str, size = 10000000);
+ EXPECT_STREQ("10M", size_str);
+ BLI_str_format_integer_unit(size_str, size = 15555555);
+ EXPECT_STREQ("15M", size_str);
+ BLI_str_format_integer_unit(size_str, size = 100000000);
+ EXPECT_STREQ(".1B", size_str);
+ BLI_str_format_integer_unit(size_str, size = 155555555);
+ EXPECT_STREQ(".1B", size_str);
+ BLI_str_format_integer_unit(size_str, size = 255555555);
+ EXPECT_STREQ(".2B", size_str);
+ BLI_str_format_integer_unit(size_str, size = 1000000000);
+ EXPECT_STREQ("1B", size_str);
+
+ /* Largest possible value. */
+ BLI_str_format_integer_unit(size_str, size = INT32_MAX);
+ EXPECT_STREQ("2B", size_str);
+
+ BLI_str_format_integer_unit(size_str, size = -0);
+ EXPECT_STREQ("0", size_str);
+ BLI_str_format_integer_unit(size_str, size = -1);
+ EXPECT_STREQ("-1", size_str);
+ BLI_str_format_integer_unit(size_str, size = -10);
+ EXPECT_STREQ("-10", size_str);
+ BLI_str_format_integer_unit(size_str, size = -15);
+ EXPECT_STREQ("-15", size_str);
+ BLI_str_format_integer_unit(size_str, size = -100);
+ EXPECT_STREQ("-100", size_str);
+ BLI_str_format_integer_unit(size_str, size = -155);
+ EXPECT_STREQ("-155", size_str);
+ BLI_str_format_integer_unit(size_str, size = -1000);
+ EXPECT_STREQ("-1K", size_str);
+ BLI_str_format_integer_unit(size_str, size = -1555);
+ EXPECT_STREQ("-1K", size_str);
+ BLI_str_format_integer_unit(size_str, size = -10000);
+ EXPECT_STREQ("-10K", size_str);
+ BLI_str_format_integer_unit(size_str, size = -15555);
+ EXPECT_STREQ("-15K", size_str);
+ BLI_str_format_integer_unit(size_str, size = -100000);
+ EXPECT_STREQ("-.1M", size_str);
+ BLI_str_format_integer_unit(size_str, size = -155555);
+ EXPECT_STREQ("-.1M", size_str);
+ BLI_str_format_integer_unit(size_str, size = -1000000);
+ EXPECT_STREQ("-1M", size_str);
+ BLI_str_format_integer_unit(size_str, size = -1555555);
+ EXPECT_STREQ("-1M", size_str);
+ BLI_str_format_integer_unit(size_str, size = -10000000);
+ EXPECT_STREQ("-10M", size_str);
+ BLI_str_format_integer_unit(size_str, size = -15555555);
+ EXPECT_STREQ("-15M", size_str);
+ BLI_str_format_integer_unit(size_str, size = -100000000);
+ EXPECT_STREQ("-.1B", size_str);
+ BLI_str_format_integer_unit(size_str, size = -155555555);
+ EXPECT_STREQ("-.1B", size_str);
+ BLI_str_format_integer_unit(size_str, size = -1000000000);
+ EXPECT_STREQ("-1B", size_str);
+
+ /* Smallest possible value. */
+ BLI_str_format_integer_unit(size_str, size = -INT32_MAX);
+ EXPECT_STREQ("-2B", size_str);
+}
+
struct WordInfo {
WordInfo() = default;
WordInfo(int start, int end) : start(start), end(end)
diff --git a/source/blender/blenlib/tests/BLI_string_utf8_test.cc b/source/blender/blenlib/tests/BLI_string_utf8_test.cc
index 2da439dad18..d66bade40ed 100644
--- a/source/blender/blenlib/tests/BLI_string_utf8_test.cc
+++ b/source/blender/blenlib/tests/BLI_string_utf8_test.cc
@@ -4,6 +4,7 @@
#include "BLI_rand.h"
#include "BLI_string.h"
+#include "BLI_string_cursor_utf8.h"
#include "BLI_string_utf8.h"
#include "BLI_utildefines.h"
@@ -274,7 +275,7 @@ TEST(string, Utf8InvalidBytes)
for (int i = 0; utf8_invalid_tests[i][0] != nullptr; i++) {
const char *tst = utf8_invalid_tests[i][0];
const char *tst_stripped = utf8_invalid_tests[i][1];
- const int errors_num = (int)utf8_invalid_tests[i][2][0];
+ const int errors_num = int(utf8_invalid_tests[i][2][0]);
char buff[80];
memcpy(buff, tst, sizeof(buff));
@@ -352,13 +353,13 @@ template<size_t Size> void utf8_as_char32_test_at_buffer_size()
/* Offset trailing bytes up and down in steps of 1, 2, 4 .. etc. */
if (Size > 1) {
for (int mul = 1; mul < 256; mul *= 2) {
- for (int ofs = 1; ofs < (int)Size; ofs++) {
- utf8_src[ofs] = (char)(i + (ofs * mul));
+ for (int ofs = 1; ofs < int(Size); ofs++) {
+ utf8_src[ofs] = char(i + (ofs * mul));
}
utf8_as_char32_test_compare<Size>(utf8_src);
- for (int ofs = 1; ofs < (int)Size; ofs++) {
- utf8_src[ofs] = (char)(i - (ofs * mul));
+ for (int ofs = 1; ofs < int(Size); ofs++) {
+ utf8_src[ofs] = char(i - (ofs * mul));
}
utf8_as_char32_test_compare<Size>(utf8_src);
}
@@ -393,3 +394,484 @@ TEST(string, Utf8AsUnicodeStep)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf32_empty
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf32Empty)
+{
+ const char32_t empty[] = U"";
+ const size_t len = 0;
+ int pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf32(empty, len, &pos));
+ pos = 1;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf32(empty, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf32_single
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf32Single)
+
+{
+ const char32_t single[] = U"0";
+ const size_t len = 1;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(single, len, &pos) && pos == 1);
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf32(single, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf32_simple
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf32Simple)
+{
+ const char32_t simple[] = U"012";
+ const size_t len = 3;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(simple, len, &pos) && pos == 1);
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(simple, len, &pos) && pos == 2);
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf32(simple, len - 1, &pos));
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(simple, len, &pos) && pos == 3);
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf32(simple, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf32_allcombining
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf32AllCombining)
+{
+ const char32_t allcombining[] = U"\u0300\u0300\u0300";
+ const size_t len = 3;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(allcombining, len, &pos) && pos == 3);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(allcombining, len, &pos) && pos == 3);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(allcombining, len, &pos) && pos == 3);
+ pos = 3;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf32(allcombining, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf32_complex
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf32Complex)
+{
+ /* Combining character, "A", two combining characters, "B".*/
+ const char32_t complex[] = U"\u0300\u0041\u0300\u0320\u0042";
+ const size_t len = 5;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(complex, len, &pos) && pos == 1);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(complex, len, &pos) && pos == 4);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(complex, len, &pos) && pos == 4);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(complex, len, &pos) && pos == 4);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(complex, len, &pos) && pos == 5);
+ pos = 5;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf32(complex, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf32_invalid
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf32Invalid)
+{
+ /* Latin1 "À", tab, carriage return, linefeed, separated by combining characters.*/
+ const char32_t invalid[] = U"\u00C0\u0300\u0009\u0300\u000D\u0300\u000A\u0300";
+ const size_t len = 8;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(invalid, len, &pos) && pos == 2);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(invalid, len, &pos) && pos == 2);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(invalid, len, &pos) && pos == 4);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(invalid, len, &pos) && pos == 4);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(invalid, len, &pos) && pos == 6);
+ pos = 5;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(invalid, len, &pos) && pos == 6);
+ pos = 6;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(invalid, len, &pos) && pos == 8);
+ pos = 7;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf32(invalid, len, &pos) && pos == 8);
+ pos = 8;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf32(invalid, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf32_empty
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf32Empty)
+{
+ const char32_t emtpy[] = U"";
+ const size_t len = 0;
+ int pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf32(emtpy, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf32_single
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf32Single)
+{
+ const char32_t single[] = U"0";
+ const size_t len = 1;
+ int pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(single, len, &pos) && pos == 0);
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf32(single, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf32_simple
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf32Simple)
+{
+ const char32_t simple[] = U"012";
+ const size_t len = 3;
+ int pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(simple, len, &pos) && pos == 2);
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(simple, len, &pos) && pos == 1);
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(simple, len, &pos) && pos == 0);
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf32(simple, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf32_allcombining
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf32AllCombining)
+{
+ const char32_t allcombining[] = U"\u0300\u0300\u0300";
+ const size_t len = 3;
+ int pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(allcombining, len, &pos) && pos == 0);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(allcombining, len, &pos) && pos == 0);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(allcombining, len, &pos) && pos == 0);
+ pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf32(allcombining, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf32_complex
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf32Complex)
+{
+ /* Combining character, "A", two combining characters, "B".*/
+ const char32_t complex[] = U"\u0300\u0041\u0300\u0320\u0042";
+ const size_t len = 5;
+ int pos = 5;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(complex, len, &pos) && pos == 4);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(complex, len, &pos) && pos == 1);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(complex, len, &pos) && pos == 1);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(complex, len, &pos) && pos == 1);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(complex, len, &pos) && pos == 0);
+ pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf32(complex, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf32_invalid
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf32Invalid)
+{
+ /* Latin1 "À", tab, carriage return, linefeed, separated by combining characters.*/
+ const char32_t invalid[] = U"\u00C0\u0300\u0009\u0300\u000D\u0300\u000A\u0300";
+ const size_t len = 8;
+ int pos = 8;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(invalid, len, &pos) && pos == 6);
+ pos = 7;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(invalid, len, &pos) && pos == 6);
+ pos = 6;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(invalid, len, &pos) && pos == 4);
+ pos = 5;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(invalid, len, &pos) && pos == 4);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(invalid, len, &pos) && pos == 2);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(invalid, len, &pos) && pos == 2);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(invalid, len, &pos) && pos == 0);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf32(invalid, len, &pos) && pos == 0);
+ pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf32(invalid, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf8_empty
+ * \{ */
+TEST(string, StrCursorStepNextUtf8Empty)
+{
+ const char empty[] = "";
+ const size_t len = 0;
+ int pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf8(empty, len, &pos));
+ pos = 1;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf8(empty, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf8_single
+ * \{ */
+TEST(string, StrCursorStepNextUtf8Single)
+{
+ const char single[] = "0";
+ const size_t len = 1;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(single, len, &pos) && pos == 1);
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf8(single, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf8_simple
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf8Simple)
+{
+ const char simple[] = "012";
+ const size_t len = 3;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(simple, len, &pos) && pos == 1);
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(simple, len, &pos) && pos == 2);
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf8(simple, len - 1, &pos));
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(simple, len, &pos) && pos == 3);
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf8(simple, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf8_allcombining
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf8AllCombining)
+{
+ const char allcombining[] = "\xCC\x80\xCC\x80\xCC\x80";
+ const size_t len = 6;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(allcombining, len, &pos) && pos == 6);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(allcombining, len, &pos) && pos == 6);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(allcombining, len, &pos) && pos == 6);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(allcombining, len, &pos) && pos == 6);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(allcombining, len, &pos) && pos == 6);
+ pos = 5;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(allcombining, len, &pos) && pos == 6);
+ pos = 6;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf8(allcombining, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf8_complex
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf8AllComplex)
+{
+ /* Combining character, "A", "©", two combining characters, "B".*/
+ const char complex[] = "\xCC\x80\x41\xC2\xA9\xCC\x80\xCC\xA0\x42";
+ const size_t len = 10;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 2);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 2);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 3);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 9);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 9);
+ pos = 5;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 9);
+ pos = 6;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 9);
+ pos = 7;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 9);
+ pos = 8;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 9);
+ pos = 9;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(complex, len, &pos) && pos == 10);
+ pos = 10;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf8(complex, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_next_utf8_invalid
+ * \{ */
+
+TEST(string, StrCursorStepNextUtf8Invalid)
+{
+ /* Latin1 "À", combining, tab, carriage return, linefeed, combining.*/
+ const char invalid[] = "\xC0\xCC\x80\x09\x0D\x0A\xCC\x80";
+ const size_t len = 8;
+ int pos = 0;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(invalid, len, &pos) && pos == 8);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(invalid, len, &pos) && pos == 8);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(invalid, len, &pos) && pos == 8);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(invalid, len, &pos) && pos == 8);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(invalid, len, &pos) && pos == 8);
+ pos = 5;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(invalid, len, &pos) && pos == 8);
+ pos = 6;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(invalid, len, &pos) && pos == 8);
+ pos = 7;
+ EXPECT_TRUE(BLI_str_cursor_step_next_utf8(invalid, len, &pos) && pos == 8);
+ pos = 8;
+ EXPECT_FALSE(BLI_str_cursor_step_next_utf8(invalid, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf8_empty
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf8Empty)
+{
+ const char empty[] = "";
+ const size_t len = 0;
+ int pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf8(empty, len, &pos));
+ pos = 1;
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf8(empty, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf8_single
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf8Single)
+{
+ const char single[] = "0";
+ const size_t len = 1;
+ int pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(single, len, &pos) && pos == 0);
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf8(single, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf8_single
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf8Simple)
+{
+ const char simple[] = "012";
+ const size_t len = 3;
+ int pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(simple, len, &pos) && pos == 2);
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(simple, len, &pos) && pos == 1);
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(simple, len, &pos) && pos == 0);
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf8(simple, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf8_allcombining
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf8AllCombining)
+{
+ const char allcombining[] = "\xCC\x80\xCC\x80\xCC\x80";
+ const size_t len = 6;
+ int pos = 6;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(allcombining, len, &pos) && pos == 0);
+ pos = 5;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(allcombining, len, &pos) && pos == 0);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(allcombining, len, &pos) && pos == 0);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(allcombining, len, &pos) && pos == 0);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(allcombining, len, &pos) && pos == 0);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(allcombining, len, &pos) && pos == 0);
+ pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf8(allcombining, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf8_complex
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf8Complex)
+{
+ /* Combining character, "A", "©", two combining characters, "B".*/
+ const char complex[] = "\xCC\x80\x41\xC2\xA9\xCC\x80\xCC\xA0\x42";
+ const size_t len = 10;
+ int pos = 10;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 9);
+ pos = 9;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 3);
+ pos = 8;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 3);
+ pos = 7;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 3);
+ pos = 6;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 3);
+ pos = 5;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 3);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 3);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 2);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 0);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(complex, len, &pos) && pos == 0);
+ pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf8(complex, len, &pos));
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Test #BLI_str_cursor_step_prev_utf8_invalid
+ * \{ */
+
+TEST(string, StrCursorStepPrevUtf8Invalid)
+{
+ /* Latin1 "À", combining, tab, carriage return, linefeed, combining.*/
+ const char invalid[] = "\xC0\xCC\x80\x09\x0D\x0A\xCC\x80";
+ const size_t len = 8;
+ int pos = 8;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(invalid, len, &pos) && pos == 5);
+ pos = 7;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(invalid, len, &pos) && pos == 5);
+ pos = 6;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(invalid, len, &pos) && pos == 5);
+ pos = 5;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(invalid, len, &pos) && pos == 4);
+ pos = 4;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(invalid, len, &pos) && pos == 3);
+ pos = 3;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(invalid, len, &pos) && pos == 0);
+ pos = 2;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(invalid, len, &pos) && pos == 0);
+ pos = 1;
+ EXPECT_TRUE(BLI_str_cursor_step_prev_utf8(invalid, len, &pos) && pos == 0);
+ pos = 0;
+ EXPECT_FALSE(BLI_str_cursor_step_prev_utf8(invalid, len, &pos));
+}
+
+/** \} */
diff --git a/source/blender/blenlib/tests/BLI_task_test.cc b/source/blender/blenlib/tests/BLI_task_test.cc
index a933d45e7cd..63bb767466f 100644
--- a/source/blender/blenlib/tests/BLI_task_test.cc
+++ b/source/blender/blenlib/tests/BLI_task_test.cc
@@ -27,7 +27,7 @@ static void task_range_iter_func(void *userdata, int index, const TaskParallelTL
// printf("%d, %d, %d\n", index, data[index], *((int *)tls->userdata_chunk));
}
-static void task_range_iter_reduce_func(const void *__restrict UNUSED(userdata),
+static void task_range_iter_reduce_func(const void *__restrict /*userdata*/,
void *__restrict join_v,
void *__restrict userdata_chunk)
{
@@ -71,7 +71,7 @@ TEST(task, RangeIter)
static void task_mempool_iter_func(void *userdata,
MempoolIterData *item,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
int *data = (int *)item;
int *count = (int *)userdata;
@@ -147,7 +147,7 @@ using TaskMemPool_Chunk = struct TaskMemPool_Chunk {
ListBase *accumulate_items;
};
-static void task_mempool_iter_tls_func(void *UNUSED(userdata),
+static void task_mempool_iter_tls_func(void * /*userdata*/,
MempoolIterData *item,
const TaskParallelTLS *__restrict tls)
{
@@ -165,7 +165,7 @@ static void task_mempool_iter_tls_func(void *UNUSED(userdata),
BLI_addtail(task_data->accumulate_items, BLI_genericNodeN(data));
}
-static void task_mempool_iter_tls_reduce(const void *__restrict UNUSED(userdata),
+static void task_mempool_iter_tls_reduce(const void *__restrict /*userdata*/,
void *__restrict chunk_join,
void *__restrict chunk)
{
@@ -180,8 +180,7 @@ static void task_mempool_iter_tls_reduce(const void *__restrict UNUSED(userdata)
}
}
-static void task_mempool_iter_tls_free(const void *UNUSED(userdata),
- void *__restrict userdata_chunk)
+static void task_mempool_iter_tls_free(const void * /*userdata*/, void *__restrict userdata_chunk)
{
TaskMemPool_Chunk *task_data = (TaskMemPool_Chunk *)userdata_chunk;
MEM_freeN(task_data->accumulate_items);
@@ -240,7 +239,7 @@ TEST(task, MempoolIterTLS)
static void task_listbase_iter_func(void *userdata,
void *item,
int index,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
LinkData *data = (LinkData *)item;
int *count = (int *)userdata;
diff --git a/source/blender/blenlib/tests/BLI_vector_set_test.cc b/source/blender/blenlib/tests/BLI_vector_set_test.cc
index 34685c76e00..c3fbac1200a 100644
--- a/source/blender/blenlib/tests/BLI_vector_set_test.cc
+++ b/source/blender/blenlib/tests/BLI_vector_set_test.cc
@@ -128,6 +128,19 @@ TEST(vector_set, RemoveContained)
EXPECT_EQ(set.size(), 0);
}
+TEST(vector_set, RemoveIf)
+{
+ VectorSet<int64_t> set;
+ for (const int64_t i : IndexRange(100)) {
+ set.add(i * i);
+ }
+ set.remove_if([](const int64_t key) { return key % 2 == 0; });
+ EXPECT_EQ(set.size(), 50);
+ for (const int64_t i : IndexRange(100)) {
+ EXPECT_EQ(set.contains(i * i), i % 2 == 1);
+ }
+}
+
TEST(vector_set, AddMultipleTimes)
{
VectorSet<int> set;
diff --git a/source/blender/blenlib/tests/BLI_vector_test.cc b/source/blender/blenlib/tests/BLI_vector_test.cc
index 3a12fe14de3..29bf6c0cfb1 100644
--- a/source/blender/blenlib/tests/BLI_vector_test.cc
+++ b/source/blender/blenlib/tests/BLI_vector_test.cc
@@ -317,7 +317,7 @@ TEST(vector, BecomeLarge)
}
EXPECT_EQ(vec.size(), 100);
for (int i = 0; i < 100; i++) {
- EXPECT_EQ(vec[i], static_cast<int>(i * 5));
+ EXPECT_EQ(vec[i], int(i * 5));
}
}
@@ -416,7 +416,16 @@ TEST(vector, Remove)
vec.remove(1);
EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2}).begin()));
vec.remove(0);
- EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({}).begin()));
+ EXPECT_EQ(vec.begin(), vec.end());
+}
+
+TEST(vector, RemoveIf)
+{
+ Vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8};
+ vec.remove_if([](const int x) { return x % 2 == 0; });
+ const Vector<int> expected_vec = {1, 3, 5, 7};
+ EXPECT_EQ(vec.size(), expected_vec.size());
+ EXPECT_EQ_ARRAY(vec.data(), expected_vec.data(), size_t(vec.size()));
}
TEST(vector, ExtendSmallVector)
@@ -497,11 +506,11 @@ class TypeConstructMock {
{
}
- TypeConstructMock(const TypeConstructMock &UNUSED(other)) : copy_constructed(true)
+ TypeConstructMock(const TypeConstructMock & /*other*/) : copy_constructed(true)
{
}
- TypeConstructMock(TypeConstructMock &&UNUSED(other)) noexcept : move_constructed(true)
+ TypeConstructMock(TypeConstructMock && /*other*/) noexcept : move_constructed(true)
{
}
@@ -635,7 +644,7 @@ TEST(vector, OveralignedValues)
Vector<AlignedBuffer<1, 512>, 2> vec;
for (int i = 0; i < 100; i++) {
vec.append({});
- EXPECT_EQ((uintptr_t)&vec.last() % 512, 0);
+ EXPECT_EQ(uintptr_t(&vec.last()) % 512, 0);
}
}
diff --git a/source/blender/blenlib/tests/BLI_virtual_array_test.cc b/source/blender/blenlib/tests/BLI_virtual_array_test.cc
index 14f5480f751..6d6580c52d4 100644
--- a/source/blender/blenlib/tests/BLI_virtual_array_test.cc
+++ b/source/blender/blenlib/tests/BLI_virtual_array_test.cc
@@ -98,7 +98,7 @@ TEST(virtual_array, VectorSet)
TEST(virtual_array, Func)
{
- auto func = [](int64_t index) { return (int)(index * index); };
+ auto func = [](int64_t index) { return int(index * index); };
VArray<int> varray = VArray<int>::ForFunc(10, func);
EXPECT_EQ(varray.size(), 10);
EXPECT_EQ(varray[0], 0);
@@ -108,7 +108,7 @@ TEST(virtual_array, Func)
TEST(virtual_array, AsSpan)
{
- auto func = [](int64_t index) { return (int)(10 * index); };
+ auto func = [](int64_t index) { return int(10 * index); };
VArray<int> func_varray = VArray<int>::ForFunc(10, func);
VArraySpan span_varray{func_varray};
EXPECT_EQ(span_varray.size(), 10);
@@ -210,7 +210,7 @@ TEST(virtual_array, MaterializeCompressed)
EXPECT_EQ(compressed_array[2], 4);
}
{
- VArray<int> varray = VArray<int>::ForFunc(10, [](const int64_t i) { return (int)(i * i); });
+ VArray<int> varray = VArray<int>::ForFunc(10, [](const int64_t i) { return int(i * i); });
std::array<int, 3> compressed_array;
varray.materialize_compressed({5, 7, 8}, compressed_array);
EXPECT_EQ(compressed_array[0], 25);
diff --git a/source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc b/source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc
index 09bb1e7239f..efcf8dea922 100644
--- a/source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc
+++ b/source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc
@@ -177,12 +177,12 @@ TEST(ghash, TextMurmur2a)
/* Int: uniform 100M first integers. */
-static void int_ghash_tests(GHash *ghash, const char *id, const unsigned int count)
+static void int_ghash_tests(GHash *ghash, const char *id, const uint count)
{
printf("\n========== STARTING %s ==========\n", id);
{
- unsigned int i = count;
+ uint i = count;
TIMEIT_START(int_insert);
@@ -200,7 +200,7 @@ static void int_ghash_tests(GHash *ghash, const char *id, const unsigned int cou
PRINTF_GHASH_STATS(ghash);
{
- unsigned int i = count;
+ uint i = count;
TIMEIT_START(int_lookup);
@@ -266,13 +266,13 @@ TEST(ghash, IntMurmur2a100000000)
/* Int: random 50M integers. */
-static void randint_ghash_tests(GHash *ghash, const char *id, const unsigned int count)
+static void randint_ghash_tests(GHash *ghash, const char *id, const uint count)
{
printf("\n========== STARTING %s ==========\n", id);
- unsigned int *data = (unsigned int *)MEM_mallocN(sizeof(*data) * (size_t)count, __func__);
- unsigned int *dt;
- unsigned int i;
+ uint *data = (uint *)MEM_mallocN(sizeof(*data) * size_t(count), __func__);
+ uint *dt;
+ uint i;
{
RNG *rng = BLI_rng_new(1);
@@ -347,7 +347,7 @@ TEST(ghash, IntRandMurmur2a50000000)
}
#endif
-static unsigned int ghashutil_tests_nohash_p(const void *p)
+static uint ghashutil_tests_nohash_p(const void *p)
{
return POINTER_AS_UINT(p);
}
@@ -375,14 +375,14 @@ TEST(ghash, Int4NoHash50000000)
/* Int_v4: 20M of randomly-generated integer vectors. */
-static void int4_ghash_tests(GHash *ghash, const char *id, const unsigned int count)
+static void int4_ghash_tests(GHash *ghash, const char *id, const uint count)
{
printf("\n========== STARTING %s ==========\n", id);
- void *data_v = MEM_mallocN(sizeof(unsigned int[4]) * (size_t)count, __func__);
- unsigned int(*data)[4] = (unsigned int(*)[4])data_v;
- unsigned int(*dt)[4];
- unsigned int i, j;
+ void *data_v = MEM_mallocN(sizeof(uint[4]) * size_t(count), __func__);
+ uint(*data)[4] = (uint(*)[4])data_v;
+ uint(*dt)[4];
+ uint i, j;
{
RNG *rng = BLI_rng_new(1);
@@ -483,11 +483,11 @@ TEST(ghash, Int2NoHash50000000)
/* MultiSmall: create and manipulate a lot of very small ghash's
* (90% < 10 items, 9% < 100 items, 1% < 1000 items). */
-static void multi_small_ghash_tests_one(GHash *ghash, RNG *rng, const unsigned int count)
+static void multi_small_ghash_tests_one(GHash *ghash, RNG *rng, const uint count)
{
- unsigned int *data = (unsigned int *)MEM_mallocN(sizeof(*data) * (size_t)count, __func__);
- unsigned int *dt;
- unsigned int i;
+ uint *data = (uint *)MEM_mallocN(sizeof(*data) * size_t(count), __func__);
+ uint *dt;
+ uint i;
for (i = count, dt = data; i--; dt++) {
*dt = BLI_rng_get_uint(rng);
@@ -510,7 +510,7 @@ static void multi_small_ghash_tests_one(GHash *ghash, RNG *rng, const unsigned i
MEM_freeN(data);
}
-static void multi_small_ghash_tests(GHash *ghash, const char *id, const unsigned int count)
+static void multi_small_ghash_tests(GHash *ghash, const char *id, const uint count)
{
printf("\n========== STARTING %s ==========\n", id);
@@ -518,7 +518,7 @@ static void multi_small_ghash_tests(GHash *ghash, const char *id, const unsigned
TIMEIT_START(multi_small_ghash);
- unsigned int i = count;
+ uint i = count;
while (i--) {
const int count = 1 + (BLI_rng_get_int(rng) % TESTCASE_SIZE_SMALL) *
(!(i % 100) ? 100 : (!(i % 10) ? 10 : 1));
@@ -529,7 +529,7 @@ static void multi_small_ghash_tests(GHash *ghash, const char *id, const unsigned
TIMEIT_START(multi_small2_ghash);
- unsigned int i = count;
+ uint i = count;
while (i--) {
const int count = 1 + (BLI_rng_get_int(rng) % TESTCASE_SIZE_SMALL) / 2 *
(!(i % 100) ? 100 : (!(i % 10) ? 10 : 1));
diff --git a/source/blender/blenlib/tests/performance/BLI_task_performance_test.cc b/source/blender/blenlib/tests/performance/BLI_task_performance_test.cc
index a86e9b0b86d..68fdf4031ab 100644
--- a/source/blender/blenlib/tests/performance/BLI_task_performance_test.cc
+++ b/source/blender/blenlib/tests/performance/BLI_task_performance_test.cc
@@ -36,10 +36,10 @@ static uint gen_pseudo_random_number(uint num)
/* *** Parallel iterations over double-linked list items. *** */
-static void task_listbase_light_iter_func(void *UNUSED(userdata),
+static void task_listbase_light_iter_func(void * /*userdata*/,
void *item,
int index,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
LinkData *data = (LinkData *)item;
@@ -50,7 +50,7 @@ static void task_listbase_light_iter_func(void *UNUSED(userdata),
static void task_listbase_light_membarrier_iter_func(void *userdata,
void *item,
int index,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
LinkData *data = (LinkData *)item;
@@ -60,16 +60,16 @@ static void task_listbase_light_membarrier_iter_func(void *userdata,
atomic_sub_and_fetch_uint32((uint32_t *)count, 1);
}
-static void task_listbase_heavy_iter_func(void *UNUSED(userdata),
+static void task_listbase_heavy_iter_func(void * /*userdata*/,
void *item,
int index,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
LinkData *data = (LinkData *)item;
/* 'Random' number of iterations. */
- const uint num = gen_pseudo_random_number((uint)index);
+ const uint num = gen_pseudo_random_number(uint(index));
for (uint i = 0; i < num; i++) {
data->data = POINTER_FROM_INT(POINTER_AS_INT(data->data) + ((i % 2) ? -index : index));
@@ -79,14 +79,14 @@ static void task_listbase_heavy_iter_func(void *UNUSED(userdata),
static void task_listbase_heavy_membarrier_iter_func(void *userdata,
void *item,
int index,
- const TaskParallelTLS *__restrict UNUSED(tls))
+ const TaskParallelTLS *__restrict /*tls*/)
{
LinkData *data = (LinkData *)item;
int *count = (int *)userdata;
/* 'Random' number of iterations. */
- const uint num = gen_pseudo_random_number((uint)index);
+ const uint num = gen_pseudo_random_number(uint(index));
for (uint i = 0; i < num; i++) {
data->data = POINTER_FROM_INT(POINTER_AS_INT(data->data) + ((i % 2) ? -index : index));
diff --git a/source/blender/blenlib/tests/performance/CMakeLists.txt b/source/blender/blenlib/tests/performance/CMakeLists.txt
index c4f03255a11..aa26f796e0d 100644
--- a/source/blender/blenlib/tests/performance/CMakeLists.txt
+++ b/source/blender/blenlib/tests/performance/CMakeLists.txt
@@ -4,9 +4,13 @@
set(INC
.
..
+ ../..
+ ../../../makesdna
+ ../../../../../intern/atomic
+ ../../../../../intern/guardedalloc
)
include_directories(${INC})
-BLENDER_TEST_PERFORMANCE(BLI_ghash_performance "bf_blenlib")
-BLENDER_TEST_PERFORMANCE(BLI_task_performance "bf_blenlib")
+blender_test_performance(BLI_ghash_performance "bf_blenlib")
+blender_test_performance(BLI_task_performance "bf_blenlib")