1
1

Compare commits

...

11 Commits

Author SHA1 Message Date
5d0bd68cc0 Merge branch 'master' into bli-math-basic-types 2022-02-16 09:02:30 -06:00
6d89120248 Remove redundant template type parameter 2022-02-15 12:22:56 -06:00
e9beb6827a Rename to is_math_float_type 2022-02-15 12:20:10 -06:00
e8c181e6fe Small cleanups 2022-02-15 11:54:54 -06:00
401de3d483 Cleanup: Remove unnecessary #undef 2022-02-15 11:54:22 -06:00
f4074f3191 Correct naming 2022-02-15 11:51:28 -06:00
25f67f3d93 Use vec_base directly in vector operations 2022-02-15 11:50:01 -06:00
ff89665ad1 Merge branch 'master' into bli-math-basic-types 2022-02-15 10:28:57 -06:00
f3fd69067a Fix ambiguous definitions 2022-02-14 17:27:44 -06:00
ce570dd434 BLI: Implement templated math functions for basic types
This is meant to complement the `blender::math` functions recently
added by D13791. It's sometimes desired to template an operation to work
on vector types, but also basic types like `float` and `int`. This patch
adds that ability with a new `BLI_math_base.hh` header. Particularly
useful examples are `midpoint` and `interpolate`, but I'm sure others
will be added in the future.

Implementing the functions separately, rather than as `if constexpr`
branches in the existing header is meant to be more scalable, for
the possibility of even more math types in the future.
2022-02-14 16:54:07 -06:00
8a9a7199ab BLI: Change dependencies in vector math files
This patch reverses the dependency between `BLI_math_vec_types.hh` and
`BLI_math_vector.hh`. Now the higher level `blender::math` functions
depend on the header that defines the types they work with, rather than
the other way around.

This required changing the includes some files used from the type
header to the math implementation header. I took that change a bit
further removing the C vector math header from the C++ header;
I think that helps to make the transition between the two systems
clearer.
2022-02-14 16:12:37 -06:00
6 changed files with 275 additions and 119 deletions

View File

@@ -0,0 +1,104 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2022 Blender Foundation. */
#pragma once
/** \file
* \ingroup bli
*/
#include <algorithm>
#include <cmath>
#include <type_traits>
#include "BLI_math_base_safe.h"
#include "BLI_math_vec_types.hh"
#include "BLI_utildefines.h"
#ifdef WITH_GMP
# include "BLI_math_mpq.hh"
#endif
namespace blender::math {
template<typename T> inline bool is_zero(const T &a)
{
return a == T(0);
}
template<typename T> inline bool is_any_zero(const T &a)
{
return is_zero(a);
}
template<typename T> inline T abs(const T &a)
{
return std::abs(a);
}
template<typename T> inline T min(const T &a, const T &b)
{
return std::min(a, b);
}
template<typename T> inline T max(const T &a, const T &b)
{
return std::max(a, b);
}
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((is_math_float_type<T>))> inline T mod(const T &a, const T &b)
{
return std::fmod(a, b);
}
template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))>
inline T safe_mod(const T &a, const T &b)
{
return (b != 0) ? std::fmod(a, b) : 0;
}
template<typename T> inline void min_max(const T &value, T &min, T &max)
{
min = math::min(value, min);
max = math::max(value, max);
}
template<typename T, BLI_ENABLE_IF((is_math_float_type<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((is_math_float_type<T>))> inline T floor(const T &a)
{
return std::floor(a);
}
template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> inline T ceil(const T &a)
{
return std::ceil(a);
}
template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> inline T fract(const T &a)
{
return a - std::floor(a);
}
template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))>
inline T interpolate(const T &a, const T &b, const T &t)
{
return a * (1 - t) + b * t;
}
template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))>
inline T midpoint(const T &a, const T &b)
{
return (a + b) * T(0.5);
}
} // namespace blender::math

View File

@@ -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] == typename T::base_type(0)) {
for (int i = 0; i < Size; i++) {
if (a[i] == T(0)) {
return true;
}
}
@@ -579,4 +583,13 @@ using double2 = vec_base<double, 2>;
using double3 = vec_base<double, 3>;
using double4 = vec_base<double, 4>;
template<typename T>
inline constexpr bool is_math_float_type = (std::is_floating_point_v<T>
#ifdef WITH_GMP
|| std::is_same_v<T, mpq_class>
#endif
);
template<typename T> inline constexpr bool is_math_integral_type = std::is_integral_v<T>;
} // namespace blender

View File

@@ -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,277 +29,293 @@ namespace blender::math {
# define BLI_ASSERT_UNIT(v) (void)(v)
#endif
#define bT typename T::base_type
#ifdef WITH_GMP
# define BLI_ENABLE_IF_FLT_VEC(T) \
BLI_ENABLE_IF((std::is_floating_point_v<typename T::base_type> || \
std::is_same_v<typename T::base_type, mpq_class>))
#else
# define BLI_ENABLE_IF_FLT_VEC(T) BLI_ENABLE_IF((std::is_floating_point_v<typename T::base_type>))
#endif
#define BLI_ENABLE_IF_INT_VEC(T) BLI_ENABLE_IF((std::is_integral_v<typename T::base_type>))
template<typename 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> 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> 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> 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> 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> 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++) {
std::clamp(result[i], min, max);
}
return result;
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T mod(const T &a, const T &b)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline vec_base<T, Size> mod(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++) {
BLI_assert(b[i] != 0);
result[i] = std::fmod(a[i], b[i]);
}
return result;
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T mod(const T &a, bT b)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline vec_base<T, Size> mod(const vec_base<T, Size> &a, const T &b)
{
BLI_assert(b != 0);
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] = std::fmod(a[i], b);
}
return result;
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T safe_mod(const T &a, const T &b)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline T safe_mod(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] = (b[i] != 0) ? std::fmod(a[i], b[i]) : 0;
}
return result;
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T safe_mod(const T &a, bT b)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline T safe_mod(const vec_base<T, Size> &a, const T &b)
{
if (b == 0) {
return T(0.0f);
return vec_base<T, Size>(0);
}
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] = std::fmod(a[i], b);
}
return result;
}
template<typename T> inline void min_max(const T &vector, T &min_vec, T &max_vec)
template<typename T, int Size>
inline void min_max(const vec_base<T, Size> &vector,
vec_base<T, Size> &min,
vec_base<T, Size> &max)
{
min_vec = min(vector, min_vec);
max_vec = max(vector, max_vec);
min = math::min(vector, min);
max = math::max(vector, max);
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T safe_divide(const T &a, const T &b)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline vec_base<T, Size> safe_divide(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] = (b[i] == 0) ? 0 : a[i] / b[i];
}
return result;
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T safe_divide(const T &a, const bT b)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline vec_base<T, Size> safe_divide(const vec_base<T, Size> &a, const T &b)
{
return (b != 0) ? a / b : T(0.0f);
return (b != 0) ? a / b : vec_base<T, Size>(0.0f);
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T floor(const T &a)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline vec_base<T, Size> floor(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] = std::floor(a[i]);
}
return result;
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T ceil(const T &a)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline vec_base<T, Size> ceil(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] = std::ceil(a[i]);
}
return result;
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T fract(const T &a)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline vec_base<T, Size> fract(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] - std::floor(a[i]);
}
return result;
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT dot(const T &a, const T &b)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline T dot(const vec_base<T, Size> &a, const vec_base<T, Size> &b)
{
bT result = a[0] * b[0];
for (int i = 1; i < T::type_length; i++) {
T result = a[0] * b[0];
for (int i = 1; i < Size; i++) {
result += a[i] * b[i];
}
return result;
}
template<typename T> inline bT length_manhattan(const T &a)
template<typename T, int Size> inline T length_manhattan(const vec_base<T, Size> &a)
{
bT result = std::abs(a[0]);
for (int i = 1; i < T::type_length; i++) {
T result = std::abs(a[0]);
for (int i = 1; i < Size; i++) {
result += std::abs(a[i]);
}
return result;
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT length_squared(const T &a)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline T length_squared(const vec_base<T, Size> &a)
{
return dot(a, a);
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT length(const T &a)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline T length(const vec_base<T, Size> &a)
{
return std::sqrt(length_squared(a));
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT distance_manhattan(const T &a, const T &b)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline T distance_manhattan(const vec_base<T, Size> &a, const vec_base<T, Size> &b)
{
return length_manhattan(a - b);
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT distance_squared(const T &a, const T &b)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline T distance_squared(const vec_base<T, Size> &a, const vec_base<T, Size> &b)
{
return length_squared(a - b);
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline bT distance(const T &a, const T &b)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline T distance(const vec_base<T, Size> &a, const vec_base<T, Size> &b)
{
return length(a - b);
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T reflect(const T &incident, const T &normal)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline vec_base<T, Size> reflect(const vec_base<T, Size> &incident,
const vec_base<T, Size> &normal)
{
BLI_ASSERT_UNIT(normal);
return incident - 2.0 * dot(normal, incident) * normal;
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)>
inline T refract(const T &incident, const T &normal, const bT eta)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline vec_base<T, Size> refract(const vec_base<T, Size> &incident,
const vec_base<T, Size> &normal,
const T &eta)
{
float dot_ni = dot(normal, incident);
float k = 1.0f - eta * eta * (1.0f - dot_ni * dot_ni);
if (k < 0.0f) {
return T(0.0f);
return vec_base<T, Size>(0.0f);
}
return eta * incident - (eta * dot_ni + sqrt(k)) * normal;
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T project(const T &p, const T &v_proj)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline vec_base<T, Size> project(const vec_base<T, Size> &p, const vec_base<T, Size> &v_proj)
{
if (UNLIKELY(is_zero(v_proj))) {
return T(0.0f);
return vec_base<T, Size>(0.0f);
}
return v_proj * (dot(p, v_proj) / dot(v_proj, v_proj));
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)>
inline T normalize_and_get_length(const T &v, bT &out_length)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline vec_base<T, Size> normalize_and_get_length(const vec_base<T, Size> &v, T &out_length)
{
out_length = length_squared(v);
/* A larger value causes normalize errors in a scaled down models with camera extreme close. */
constexpr bT threshold = std::is_same_v<bT, double> ? 1.0e-70 : 1.0e-35f;
constexpr T threshold = std::is_same_v<T, double> ? 1.0e-70 : 1.0e-35f;
if (out_length > threshold) {
out_length = sqrt(out_length);
return v / out_length;
}
/* Either the vector is small or one of it's values contained `nan`. */
out_length = 0.0;
return T(0.0);
return vec_base<T, Size>(0.0);
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T normalize(const T &v)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline vec_base<T, Size> normalize(const vec_base<T, Size> &v)
{
bT len;
T len;
return normalize_and_get_length(v, len);
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T), BLI_ENABLE_IF((T::type_length == 3))>
inline T cross(const T &a, const T &b)
template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))>
inline vec_base<T, 3> cross(const vec_base<T, 3> &a, const vec_base<T, 3> &b)
{
return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x};
}
template<typename T,
BLI_ENABLE_IF((std::is_same_v<bT, float>)),
BLI_ENABLE_IF((T::type_length == 3))>
inline T cross_high_precision(const T &a, const T &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)};
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T), BLI_ENABLE_IF((T::type_length == 3))>
inline T cross_poly(Span<T> poly)
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());
if (nv < 3) {
return T(0, 0, 0);
return vec_base<T, 3>(0, 0, 0);
}
const T *v_prev = &poly[nv - 1];
const T *v_curr = &poly[0];
T n(0, 0, 0);
const vec_base<T, 3> *v_prev = &poly[nv - 1];
const vec_base<T, 3> *v_curr = &poly[0];
vec_base<T, 3> n(0, 0, 0);
for (int i = 0; i < nv;) {
n[0] = n[0] + ((*v_prev)[1] - (*v_curr)[1]) * ((*v_prev)[2] + (*v_curr)[2]);
n[1] = n[1] + ((*v_prev)[2] - (*v_curr)[2]) * ((*v_prev)[0] + (*v_curr)[0]);
@@ -317,25 +329,31 @@ inline T cross_poly(Span<T> poly)
return n;
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T interpolate(const T &a, const T &b, bT t)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline vec_base<T, Size> interpolate(const vec_base<T, Size> &a,
const vec_base<T, Size> &b,
const T &t)
{
return a * (1 - t) + b * t;
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T midpoint(const T &a, const T &b)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline vec_base<T, Size> midpoint(const vec_base<T, Size> &a, const vec_base<T, Size> &b)
{
return (a + b) * 0.5;
}
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)>
inline T faceforward(const T &vector, const T &incident, const T &reference)
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
inline vec_base<T, Size> faceforward(const vec_base<T, Size> &vector,
const vec_base<T, Size> &incident,
const vec_base<T, Size> &reference)
{
return (dot(reference, incident) < 0) ? vector : -vector;
}
template<typename T> inline int dominant_axis(const T &a)
template<typename T> inline int dominant_axis(const vec_base<T, 3> &a)
{
T b = abs(a);
vec_base<T, 3> b = abs(a);
return ((b.x > b.y) ? ((b.x > b.z) ? 0 : 2) : ((b.y > b.z) ? 1 : 2));
}
@@ -348,14 +366,13 @@ template<typename T> struct isect_result {
LINE_LINE_EXACT = 1,
LINE_LINE_CROSS = 2,
} kind;
bT lambda;
typename T::base_type lambda;
};
template<typename T, BLI_ENABLE_IF_FLT_VEC(T)>
isect_result<T> isect_seg_seg(const T &v1, const T &v2, const T &v3, const T &v4);
#undef BLI_ENABLE_IF_FLT_VEC
#undef BLI_ENABLE_IF_INT_VEC
#undef bT
template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
isect_result<vec_base<T, Size>> isect_seg_seg(const vec_base<T, Size> &v1,
const vec_base<T, Size> &v2,
const vec_base<T, Size> &v3,
const vec_base<T, Size> &v4);
} // namespace blender::math

View File

@@ -220,6 +220,7 @@ set(SRC
BLI_map.hh
BLI_map_slots.hh
BLI_math.h
BLI_math_base.hh
BLI_math_base.h
BLI_math_base_safe.h
BLI_math_bits.h

View File

@@ -1691,7 +1691,7 @@ void fill_crossdata_for_intersect(const FatCo<T> &curco,
BLI_assert(se_vcva->vert == vc && se_vcva->next->vert == va);
BLI_assert(se_vcvb->vert == vc && se_vcvb->next->vert == vb);
UNUSED_VARS_NDEBUG(vc);
auto isect = isect_seg_seg<vec2<T>>(va->co.exact, vb->co.exact, curco.exact, v2->co.exact);
auto isect = isect_seg_seg(va->co.exact, vb->co.exact, curco.exact, v2->co.exact);
T &lambda = isect.lambda;
switch (isect.kind) {
case isect_result<vec2<T>>::LINE_LINE_CROSS: {
@@ -2556,7 +2556,7 @@ template<typename T> void detect_holes(CDT_state<T> *cdt_state)
if (e->symedges[0].face->visit_index == e->symedges[1].face->visit_index) {
continue; /* Don't count hits on edges between faces in same region. */
}
auto isect = isect_seg_seg<vec2<T>>(ray_end.exact,
auto isect = isect_seg_seg(ray_end.exact,
mid.exact,
e->symedges[0].vert->co.exact,
e->symedges[1].vert->co.exact);

View File

@@ -3,6 +3,10 @@
#include "testing/testing.h"
#include "BLI_math.h"
#include "BLI_math_base.hh"
#include "BLI_math_vector.hh"
namespace blender::tests {
/* In tests below, when we are using -1.0f as max_diff value, we actually turn the function into a
* pure-ULP one. */
@@ -131,3 +135,20 @@ TEST(math_base, FloorPowerOf10)
EXPECT_NEAR(floor_power_of_10(100.1f), 100.0f, 1e-4f);
EXPECT_NEAR(floor_power_of_10(99.9f), 10.0f, 1e-4f);
}
TEST(math_base, MinVectorAndFloat)
{
EXPECT_EQ(math::min(1.0f, 2.0f), 1.0f);
}
TEST(math_base, ClampInt)
{
EXPECT_EQ(math::clamp(111, -50, 101), 101);
}
TEST(math_base, Midpoint)
{
EXPECT_NEAR(math::midpoint(100.0f, 200.0f), 150.0f, 1e-4f);
}
} // namespace blender::tests