Commit: 25f67f3d93b49a1903724670fd4b051a2c8bc19d Author: Hans Goudey Date: Tue Feb 15 11:50:01 2022 -0600 Branches: bli-math-basic-types https://developer.blender.org/rB25f67f3d93b49a1903724670fd4b051a2c8bc19d
Use `vec_base` directly in vector operations =================================================================== M source/blender/blenlib/BLI_math_base.hh M source/blender/blenlib/BLI_math_vec_types.hh M source/blender/blenlib/BLI_math_vector.hh M source/blender/blenlib/intern/delaunay_2d.cc =================================================================== diff --git a/source/blender/blenlib/BLI_math_base.hh b/source/blender/blenlib/BLI_math_base.hh index 89a3fd3b826..bb88770ce2f 100644 --- a/source/blender/blenlib/BLI_math_base.hh +++ b/source/blender/blenlib/BLI_math_base.hh @@ -21,97 +21,85 @@ namespace blender::math { -/* To avoid being overly specific about what a "basic" type is, for now simply allow anything that - * isn't a `vec_base` type. In the future, if another implementation of these functions is needed, - * this would have to become more specific. */ -#define BLI_ENABLE_IF_BASE(T) BLI_ENABLE_IF((!is_math_vec_type<T>)) - -#ifdef WITH_GMP -# define BLI_ENABLE_IF_FLT(T) \ - BLI_ENABLE_IF_BASE(T), \ - BLI_ENABLE_IF((std::is_floating_point_v<T> || std::is_same_v<T, mpq_class>)) -#else -# define BLI_ENABLE_IF_FLT(T) BLI_ENABLE_IF_BASE(T), BLI_ENABLE_IF((std::is_floating_point_v<T>)) -#endif - -#define BLI_ENABLE_IF_INT(T) BLI_ENABLE_IF_BASE(T), BLI_ENABLE_IF((std::is_integral_v<T>)) - -template<typename T, BLI_ENABLE_IF_BASE(T)> inline bool is_zero(const T &a) +template<typename T> inline bool is_zero(const T &a) { return a == T(0); } -template<typename T, BLI_ENABLE_IF_BASE(T)> inline bool is_any_zero(const T &a) +template<typename T> inline bool is_any_zero(const T &a) { return is_zero(a); } -template<typename T, BLI_ENABLE_IF_BASE(T)> inline T abs(const T &a) +template<typename T> inline T abs(const T &a) { return std::abs(a); } -template<typename T, BLI_ENABLE_IF_BASE(T)> inline T min(const T &a, const T &b) +template<typename T> inline T min(const T &a, const T &b) { return std::min(a, b); } -template<typename T, BLI_ENABLE_IF_BASE(T)> inline T max(const T &a, const T &b) +template<typename T> inline T max(const T &a, const T &b) { return std::max(a, b); } -template<typename T, BLI_ENABLE_IF_BASE(T)> inline T clamp(const T &a, const T &min, const T &max) +template<typename T> inline T clamp(const T &a, const T &min, const T &max) { return std::clamp(a, min, max); } -template<typename T, BLI_ENABLE_IF_FLT(T)> inline T mod(const T &a, const T &b) +template<typename T, BLI_ENABLE_IF((math_is_float<T>))> inline T mod(const T &a, const T &b) { return std::fmod(a, b); } -template<typename T, BLI_ENABLE_IF_FLT(T)> inline T safe_mod(const T &a, const T &b) +template<typename T, BLI_ENABLE_IF((math_is_float<T>))> inline T safe_mod(const T &a, const T &b) { return (b != 0) ? std::fmod(a, b) : 0; } -template<typename T, BLI_ENABLE_IF_BASE(T)> -inline void min_max(const T &vector, T &min_vec, T &max_vec) +template<typename T> inline void min_max(const T &vector, T &min_vec, T &max_vec) { min_vec = min(vector, min_vec); max_vec = max(vector, max_vec); } -template<typename T, BLI_ENABLE_IF_FLT(T)> inline T safe_divide(const T &a, const T &b) +template<typename T, BLI_ENABLE_IF((math_is_float<T>))> +inline T safe_divide(const T &a, const T &b) { return (b != 0) ? a / b : T(0.0f); } -template<typename T, BLI_ENABLE_IF_FLT(T)> inline T floor(const T &a) +template<typename T, BLI_ENABLE_IF((math_is_float<T>))> inline T floor(const T &a) { return std::floor(a); } -template<typename T, BLI_ENABLE_IF_FLT(T)> inline T ceil(const T &a) +template<typename T, BLI_ENABLE_IF((math_is_float<T>))> inline T ceil(const T &a) { return std::ceil(a); } -template<typename T, BLI_ENABLE_IF_FLT(T)> inline T fract(const T &a) +template<typename T, BLI_ENABLE_IF((math_is_float<T>))> inline T fract(const T &a) { return a - std::floor(a); } -template<typename T, typename FactorT, BLI_ENABLE_IF_FLT(T), BLI_ENABLE_IF_FLT(FactorT)> +template<typename T, + typename FactorT, + BLI_ENABLE_IF((math_is_float<T>)), + BLI_ENABLE_IF((math_is_float<T>))> inline T interpolate(const T &a, const T &b, const FactorT &t) { return a * (1 - t) + b * t; } -template<typename T, BLI_ENABLE_IF_FLT(T)> inline T midpoint(const T &a, const T &b) +template<typename T, BLI_ENABLE_IF((math_is_float<T>))> inline T midpoint(const T &a, const T &b) { - return (a + b) * 0.5; + return (a + b) * T(0.5); } #undef BLI_ENABLE_IF_BASE diff --git a/source/blender/blenlib/BLI_math_vec_types.hh b/source/blender/blenlib/BLI_math_vec_types.hh index b8a208f0a0d..a11e3907fcb 100644 --- a/source/blender/blenlib/BLI_math_vec_types.hh +++ b/source/blender/blenlib/BLI_math_vec_types.hh @@ -14,6 +14,10 @@ #include "BLI_utildefines.h" +#ifdef WITH_GMP +# include "BLI_math_mpq.hh" +#endif + namespace blender { /* clang-format off */ @@ -60,10 +64,10 @@ template<typename T> uint64_t vector_hash(const T &vec) return result; } -template<typename T> inline bool is_any_zero(const T &a) +template<typename T, int Size> inline bool is_any_zero(const vec_struct_base<T, Size> &a) { - for (int i = 0; i < T::type_length; i++) { - if (a[i] == T::base_type(0)) { + for (int i = 0; i < Size; i++) { + if (a[i] == T(0)) { return true; } } @@ -265,16 +269,6 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size> } \ return *this; - bool is_any_zero() const - { - for (int i = 0; i < Size; i++) { - if ((*this)[i] == T(0)) { - return true; - } - } - return false; - } - /** Arithmetic operators. */ friend vec_base operator+(const vec_base &a, const vec_base &b) @@ -377,7 +371,7 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size> vec_base &operator/=(T b) { - BLI_assert(!b.is_any_zero()); + BLI_assert(b != T(0)); BLI_VEC_OP_IMPL_SELF(i, (*this)[i] /= b); } @@ -589,15 +583,13 @@ using double2 = vec_base<double, 2>; using double3 = vec_base<double, 3>; using double4 = vec_base<double, 4>; -template<typename T> constexpr bool is_math_vec_type = false; -template<typename BaseType, int Size> -constexpr bool is_math_vec_type<vec_base<BaseType, Size>> = true; +template<typename T> +inline constexpr bool math_is_float = (std::is_floating_point_v<T> +#ifdef WITH_GMP + || std::is_same_v<T, mpq_class> +#endif +); -static_assert(is_math_vec_type<int2>); -static_assert(is_math_vec_type<uint4>); -static_assert(is_math_vec_type<float2>); -static_assert(is_math_vec_type<vec_base<float, 20>>); -static_assert(!is_math_vec_type<int>); -static_assert(!is_math_vec_type<float>); +template<typename T> inline constexpr bool math_is_integral = std::is_integral_v<T>; } // namespace blender diff --git a/source/blender/blenlib/BLI_math_vector.hh b/source/blender/blenlib/BLI_math_vector.hh index 32cc15e44a4..a34888f8ad0 100644 --- a/source/blender/blenlib/BLI_math_vector.hh +++ b/source/blender/blenlib/BLI_math_vector.hh @@ -15,10 +15,6 @@ #include "BLI_span.hh" #include "BLI_utildefines.h" -#ifdef WITH_GMP -# include "BLI_math_mpq.hh" -#endif - namespace blender::math { #ifndef NDEBUG @@ -33,288 +29,293 @@ namespace blender::math { # define BLI_ASSERT_UNIT(v) (void)(v) #endif -#define bT typename T::base_type - -template<typename T> -inline constexpr bool is_float_vector = (std::is_floating_point_v<typename T::base_type> -#ifdef WITH_GMP - || std::is_same_v<typename T::base_type, mpq_class> -#endif -); - -template<typename T> -inline constexpr bool is_integral_vector = std::is_integral_v<typename T::base_type>; - -/* In this file, only implement math functions for the vector types. This allows other - * files to use overloading to implement the same functions with different types. */ -#define BLI_ENABLE_IF_VEC(T) BLI_ENABLE_IF((is_math_vec_type<T>)) - -#define BLI_ENABLE_IF_FLT_VEC(T) BLI_ENABLE_IF_VEC(T), BLI_ENABLE_IF((is_float_vector<T>)) - -#define BLI_ENABLE_IF_INT_VEC(T) BLI_ENABLE_IF_VEC(T), BLI_ENABLE_IF((is_integral_vector<T>)) - -template<typename T, BLI_ENABLE_IF_VEC(T)> inline bool is_zero(const T &a) +template<typename T, int Size> inline bool is_zero(const vec_base<T, Size> &a) { - for (int i = 0; i < T::type_length; i++) { - if (a[i] != bT(0)) { + for (int i = 0; i < Size; i++) { + if (a[i] != T(0)) { return false; } } return true; } -template<typename T, BLI_ENABLE_IF_VEC(T)> inline T abs(const T &a) +template<typename T, int Size> inline vec_base<T, Size> abs(const vec_base<T, Size> &a) { - T result; - for (int i = 0; i < T::type_length; i++) { + vec_base<T, Size> result; + for (int i = 0; i < Size; i++) { result[i] = a[i] >= 0 ? a[i] : -a[i]; } return result; } -template<typename T, BLI_ENABLE_IF_VEC(T)> inline T min(const T &a, const T &b) +template<typename T, int Size> +inline vec_base<T, Size> min(const vec_base<T, Size> &a, const vec_base<T, Size> &b) { - T result; - for (int i = 0; i < T::type_length; i++) { + vec_base<T, Size> result; + for (int i = 0; i < Size; i++) { result[i] = a[i] < b[i] ? a[i] : b[i]; } return result; } -template<typename T, BLI_ENABLE_IF_VEC(T)> inline T max(const T &a, const T &b) +template<typename T, int Size> +inline vec_base<T, Size> max(const vec_base<T, Size> &a, const vec_base<T, Size> &b) { - T result; - for (int i = 0; i < T::type_length; i++) { + vec_base<T, Size> result; + for (int i = 0; i < Size; i++) { result[i] = a[i] > b[i] ? a[i] : b[i]; } return result; } -template<typename T, BLI_ENABLE_IF_VEC(T)> -inline T clamp(const T &a, const T &min_v, const T &max_v) +template<typename T, int Size> +inline T clamp(const vec_base<T, Size> &a, + const vec_base<T, Size> &min, + const vec_base<T, Size> &max) { - T result = a; - for (int i = 0; i < T::type_length; i++) { - CLAMP(result[i], min_v[i], max_v[i]); + vec_base<T, Size> result = a; + for (int i = 0; i < Size; i++) { + std::clamp(result[i], min[i], max[i]); } return result; } -template<typename T, BLI_ENABLE_IF_VEC(T)> -inline T clamp(const T &a, const bT &min_v, const bT &max_v) +template<typename T, int Size> +inline vec_base<T, Size> clamp(const vec_base<T, Size> &a, const T &min, const T &max) { - T result = a; - for (int i = 0; i < T::type_length; i++) { - CLAMP(result[i], min_v, max_v); + vec_base<T, Size> result = a; + for (int i = 0; i < Size; i++) { + @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs