Compare commits
6 Commits
temp-texpa
...
temp-exper
Author | SHA1 | Date | |
---|---|---|---|
b3d34a6690 | |||
3c112c5e46 | |||
28f99dda6c | |||
98262bb8cf | |||
3e251da3aa | |||
a37164e11b |
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "BLI_double3.hh"
|
||||
|
||||
namespace blender {
|
||||
namespace blender::math {
|
||||
|
||||
struct double2 {
|
||||
double x, y;
|
||||
@@ -50,94 +50,98 @@ struct double2 {
|
||||
{
|
||||
return &x;
|
||||
}
|
||||
|
||||
double length() const
|
||||
{
|
||||
return len_v2_db(*this);
|
||||
}
|
||||
|
||||
friend double2 operator+(const double2 &a, const double2 &b)
|
||||
{
|
||||
return {a.x + b.x, a.y + b.y};
|
||||
}
|
||||
|
||||
friend double2 operator-(const double2 &a, const double2 &b)
|
||||
{
|
||||
return {a.x - b.x, a.y - b.y};
|
||||
}
|
||||
|
||||
friend double2 operator*(const double2 &a, double b)
|
||||
{
|
||||
return {a.x * b, a.y * b};
|
||||
}
|
||||
|
||||
friend double2 operator/(const double2 &a, double b)
|
||||
{
|
||||
BLI_assert(b != 0.0);
|
||||
return {a.x / b, a.y / b};
|
||||
}
|
||||
|
||||
friend double2 operator*(double a, const double2 &b)
|
||||
{
|
||||
return b * a;
|
||||
}
|
||||
|
||||
friend bool operator==(const double2 &a, const double2 &b)
|
||||
{
|
||||
return a.x == b.x && a.y == b.y;
|
||||
}
|
||||
|
||||
friend bool operator!=(const double2 &a, const double2 &b)
|
||||
{
|
||||
return a.x != b.x || a.y != b.y;
|
||||
}
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &stream, const double2 &v)
|
||||
{
|
||||
stream << "(" << v.x << ", " << v.y << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
static double dot(const double2 &a, const double2 &b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y;
|
||||
}
|
||||
|
||||
static double2 interpolate(const double2 &a, const double2 &b, double t)
|
||||
{
|
||||
return a * (1 - t) + b * t;
|
||||
}
|
||||
|
||||
static double2 abs(const double2 &a)
|
||||
{
|
||||
return double2(fabs(a.x), fabs(a.y));
|
||||
}
|
||||
|
||||
static double distance(const double2 &a, const double2 &b)
|
||||
{
|
||||
return (a - b).length();
|
||||
}
|
||||
|
||||
static double distance_squared(const double2 &a, const double2 &b)
|
||||
{
|
||||
double2 diff = a - b;
|
||||
return double2::dot(diff, diff);
|
||||
}
|
||||
|
||||
struct isect_result {
|
||||
enum {
|
||||
LINE_LINE_COLINEAR = -1,
|
||||
LINE_LINE_NONE = 0,
|
||||
LINE_LINE_EXACT = 1,
|
||||
LINE_LINE_CROSS = 2,
|
||||
} kind;
|
||||
double lambda;
|
||||
};
|
||||
|
||||
static isect_result isect_seg_seg(const double2 &v1,
|
||||
const double2 &v2,
|
||||
const double2 &v3,
|
||||
const double2 &v4);
|
||||
};
|
||||
|
||||
} // namespace blender
|
||||
inline double length(const double2 &a)
|
||||
{
|
||||
return len_v2_db(a);
|
||||
}
|
||||
|
||||
inline double2 operator+(const double2 &a, const double2 &b)
|
||||
{
|
||||
return {a.x + b.x, a.y + b.y};
|
||||
}
|
||||
|
||||
inline double2 operator-(const double2 &a, const double2 &b)
|
||||
{
|
||||
return {a.x - b.x, a.y - b.y};
|
||||
}
|
||||
|
||||
inline double2 operator*(const double2 &a, double b)
|
||||
{
|
||||
return {a.x * b, a.y * b};
|
||||
}
|
||||
|
||||
inline double2 operator/(const double2 &a, double b)
|
||||
{
|
||||
BLI_assert(b != 0.0);
|
||||
return {a.x / b, a.y / b};
|
||||
}
|
||||
|
||||
inline double2 operator*(double a, const double2 &b)
|
||||
{
|
||||
return b * a;
|
||||
}
|
||||
|
||||
inline bool operator==(const double2 &a, const double2 &b)
|
||||
{
|
||||
return a.x == b.x && a.y == b.y;
|
||||
}
|
||||
|
||||
inline bool operator!=(const double2 &a, const double2 &b)
|
||||
{
|
||||
return a.x != b.x || a.y != b.y;
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &stream, const double2 &v)
|
||||
{
|
||||
stream << "(" << v.x << ", " << v.y << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline double dot(const double2 &a, const double2 &b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y;
|
||||
}
|
||||
|
||||
inline double2 lerp(const double2 &a, const double2 &b, double t)
|
||||
{
|
||||
return a * (1 - t) + b * t;
|
||||
}
|
||||
|
||||
inline double2 abs(const double2 &a)
|
||||
{
|
||||
return double2(fabs(a.x), fabs(a.y));
|
||||
}
|
||||
|
||||
inline double distance(const double2 &a, const double2 &b)
|
||||
{
|
||||
return length(a - b);
|
||||
}
|
||||
|
||||
inline double distance_squared(const double2 &a, const double2 &b)
|
||||
{
|
||||
double2 diff = a - b;
|
||||
return dot(diff, diff);
|
||||
}
|
||||
|
||||
struct isect_result_double2 {
|
||||
enum {
|
||||
LINE_LINE_COLINEAR = -1,
|
||||
LINE_LINE_NONE = 0,
|
||||
LINE_LINE_EXACT = 1,
|
||||
LINE_LINE_CROSS = 2,
|
||||
} kind;
|
||||
double lambda;
|
||||
};
|
||||
|
||||
isect_result_double2 isect_seg_seg(const double2 &v1,
|
||||
const double2 &v2,
|
||||
const double2 &v3,
|
||||
const double2 &v4);
|
||||
|
||||
} // namespace blender::math
|
||||
|
||||
namespace blender {
|
||||
using blender::math::double2;
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_span.hh"
|
||||
|
||||
namespace blender {
|
||||
namespace blender::math {
|
||||
|
||||
struct double3 {
|
||||
double x, y, z;
|
||||
@@ -61,186 +61,190 @@ struct double3 {
|
||||
{
|
||||
return &x;
|
||||
}
|
||||
|
||||
double normalize_and_get_length()
|
||||
{
|
||||
return normalize_v3_db(*this);
|
||||
}
|
||||
|
||||
double3 normalized() const
|
||||
{
|
||||
double3 result;
|
||||
normalize_v3_v3_db(result, *this);
|
||||
return result;
|
||||
}
|
||||
|
||||
double length() const
|
||||
{
|
||||
return len_v3_db(*this);
|
||||
}
|
||||
|
||||
double length_squared() const
|
||||
{
|
||||
return len_squared_v3_db(*this);
|
||||
}
|
||||
|
||||
void reflect(const double3 &normal)
|
||||
{
|
||||
*this = this->reflected(normal);
|
||||
}
|
||||
|
||||
double3 reflected(const double3 &normal) const
|
||||
{
|
||||
double3 result;
|
||||
reflect_v3_v3v3_db(result, *this, normal);
|
||||
return result;
|
||||
}
|
||||
|
||||
static double3 safe_divide(const double3 &a, const double3 &b)
|
||||
{
|
||||
double3 result;
|
||||
result.x = (b.x == 0.0) ? 0.0 : a.x / b.x;
|
||||
result.y = (b.y == 0.0) ? 0.0 : a.y / b.y;
|
||||
result.z = (b.z == 0.0) ? 0.0 : a.z / b.z;
|
||||
return result;
|
||||
}
|
||||
|
||||
void invert()
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
z = -z;
|
||||
}
|
||||
|
||||
friend double3 operator+(const double3 &a, const double3 &b)
|
||||
{
|
||||
return {a.x + b.x, a.y + b.y, a.z + b.z};
|
||||
}
|
||||
|
||||
void operator+=(const double3 &b)
|
||||
{
|
||||
this->x += b.x;
|
||||
this->y += b.y;
|
||||
this->z += b.z;
|
||||
}
|
||||
|
||||
friend double3 operator-(const double3 &a, const double3 &b)
|
||||
{
|
||||
return {a.x - b.x, a.y - b.y, a.z - b.z};
|
||||
}
|
||||
|
||||
friend double3 operator-(const double3 &a)
|
||||
{
|
||||
return {-a.x, -a.y, -a.z};
|
||||
}
|
||||
|
||||
void operator-=(const double3 &b)
|
||||
{
|
||||
this->x -= b.x;
|
||||
this->y -= b.y;
|
||||
this->z -= b.z;
|
||||
}
|
||||
|
||||
void operator*=(const double &scalar)
|
||||
{
|
||||
this->x *= scalar;
|
||||
this->y *= scalar;
|
||||
this->z *= scalar;
|
||||
}
|
||||
|
||||
void operator*=(const double3 &other)
|
||||
{
|
||||
this->x *= other.x;
|
||||
this->y *= other.y;
|
||||
this->z *= other.z;
|
||||
}
|
||||
|
||||
friend double3 operator*(const double3 &a, const double3 &b)
|
||||
{
|
||||
return {a.x * b.x, a.y * b.y, a.z * b.z};
|
||||
}
|
||||
|
||||
friend double3 operator*(const double3 &a, const double &b)
|
||||
{
|
||||
return {a.x * b, a.y * b, a.z * b};
|
||||
}
|
||||
|
||||
friend double3 operator*(const double &a, const double3 &b)
|
||||
{
|
||||
return b * a;
|
||||
}
|
||||
|
||||
friend double3 operator/(const double3 &a, const double &b)
|
||||
{
|
||||
BLI_assert(b != 0.0);
|
||||
return {a.x / b, a.y / b, a.z / b};
|
||||
}
|
||||
|
||||
friend bool operator==(const double3 &a, const double3 &b)
|
||||
{
|
||||
return a.x == b.x && a.y == b.y && a.z == b.z;
|
||||
}
|
||||
|
||||
friend bool operator!=(const double3 &a, const double3 &b)
|
||||
{
|
||||
return a.x != b.x || a.y != b.y || a.z != b.z;
|
||||
}
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &stream, const double3 &v)
|
||||
{
|
||||
stream << "(" << v.x << ", " << v.y << ", " << v.z << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
static double dot(const double3 &a, const double3 &b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
}
|
||||
|
||||
static double3 cross_high_precision(const double3 &a, const double3 &b)
|
||||
{
|
||||
double3 result;
|
||||
cross_v3_v3v3_db(result, a, b);
|
||||
return result;
|
||||
}
|
||||
|
||||
static double3 project(const double3 &a, const double3 &b)
|
||||
{
|
||||
double3 result;
|
||||
project_v3_v3v3_db(result, a, b);
|
||||
return result;
|
||||
}
|
||||
|
||||
static double distance(const double3 &a, const double3 &b)
|
||||
{
|
||||
return (a - b).length();
|
||||
}
|
||||
|
||||
static double distance_squared(const double3 &a, const double3 &b)
|
||||
{
|
||||
double3 diff = a - b;
|
||||
return double3::dot(diff, diff);
|
||||
}
|
||||
|
||||
static double3 interpolate(const double3 &a, const double3 &b, double t)
|
||||
{
|
||||
return a * (1 - t) + b * t;
|
||||
}
|
||||
|
||||
static double3 abs(const double3 &a)
|
||||
{
|
||||
return double3(fabs(a.x), fabs(a.y), fabs(a.z));
|
||||
}
|
||||
|
||||
static int dominant_axis(const double3 &a)
|
||||
{
|
||||
double x = (a.x >= 0) ? a.x : -a.x;
|
||||
double y = (a.y >= 0) ? a.y : -a.y;
|
||||
double z = (a.z >= 0) ? a.z : -a.z;
|
||||
return ((x > y) ? ((x > z) ? 0 : 2) : ((y > z) ? 1 : 2));
|
||||
}
|
||||
|
||||
static double3 cross_poly(Span<double3> poly);
|
||||
};
|
||||
|
||||
} // namespace blender
|
||||
inline double normalize_and_get_length(double3 &a)
|
||||
{
|
||||
return normalize_v3_db(a);
|
||||
}
|
||||
|
||||
inline double3 normalized(const double3 &a)
|
||||
{
|
||||
double3 result;
|
||||
normalize_v3_v3_db(result, a);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline double length(const double3 &a)
|
||||
{
|
||||
return len_v3_db(a);
|
||||
}
|
||||
|
||||
inline double length_squared(const double3 &a)
|
||||
{
|
||||
return len_squared_v3_db(a);
|
||||
}
|
||||
|
||||
inline double3 reflected(const double3 &a, const double3 &normal)
|
||||
{
|
||||
double3 result;
|
||||
reflect_v3_v3v3_db(result, a, normal);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void reflect(double3 &a, const double3 &normal)
|
||||
{
|
||||
a = reflected(a, normal);
|
||||
}
|
||||
|
||||
inline double3 safe_divide(const double3 &a, const double3 &b)
|
||||
{
|
||||
double3 result;
|
||||
result.x = (b.x == 0.0) ? 0.0 : a.x / b.x;
|
||||
result.y = (b.y == 0.0) ? 0.0 : a.y / b.y;
|
||||
result.z = (b.z == 0.0) ? 0.0 : a.z / b.z;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void negate(double3 &a)
|
||||
{
|
||||
a.x = -a.x;
|
||||
a.y = -a.y;
|
||||
a.z = -a.z;
|
||||
}
|
||||
|
||||
inline double3 operator+(const double3 &a, const double3 &b)
|
||||
{
|
||||
return {a.x + b.x, a.y + b.y, a.z + b.z};
|
||||
}
|
||||
|
||||
inline void operator+=(double3 &a, const double3 &b)
|
||||
{
|
||||
a.x += b.x;
|
||||
a.y += b.y;
|
||||
a.z += b.z;
|
||||
}
|
||||
|
||||
inline double3 operator-(const double3 &a, const double3 &b)
|
||||
{
|
||||
return {a.x - b.x, a.y - b.y, a.z - b.z};
|
||||
}
|
||||
|
||||
inline double3 operator-(const double3 &a)
|
||||
{
|
||||
return {-a.x, -a.y, -a.z};
|
||||
}
|
||||
|
||||
inline void operator-=(double3 &a, const double3 &b)
|
||||
{
|
||||
a.x -= b.x;
|
||||
a.y -= b.y;
|
||||
a.z -= b.z;
|
||||
}
|
||||
|
||||
inline void operator*=(double3 &a, const double &scalar)
|
||||
{
|
||||
a.x *= scalar;
|
||||
a.y *= scalar;
|
||||
a.z *= scalar;
|
||||
}
|
||||
|
||||
inline void operator*=(double3 &a, const double3 &other)
|
||||
{
|
||||
a.x *= other.x;
|
||||
a.y *= other.y;
|
||||
a.z *= other.z;
|
||||
}
|
||||
|
||||
inline double3 operator*(const double3 &a, const double3 &b)
|
||||
{
|
||||
return {a.x * b.x, a.y * b.y, a.z * b.z};
|
||||
}
|
||||
|
||||
inline double3 operator*(const double3 &a, const double &b)
|
||||
{
|
||||
return {a.x * b, a.y * b, a.z * b};
|
||||
}
|
||||
|
||||
inline double3 operator*(const double &a, const double3 &b)
|
||||
{
|
||||
return b * a;
|
||||
}
|
||||
|
||||
inline double3 operator/(const double3 &a, const double &b)
|
||||
{
|
||||
BLI_assert(b != 0.0);
|
||||
return {a.x / b, a.y / b, a.z / b};
|
||||
}
|
||||
|
||||
inline bool operator==(const double3 &a, const double3 &b)
|
||||
{
|
||||
return a.x == b.x && a.y == b.y && a.z == b.z;
|
||||
}
|
||||
|
||||
inline bool operator!=(const double3 &a, const double3 &b)
|
||||
{
|
||||
return a.x != b.x || a.y != b.y || a.z != b.z;
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &stream, const double3 &v)
|
||||
{
|
||||
stream << "(" << v.x << ", " << v.y << ", " << v.z << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline double dot(const double3 &a, const double3 &b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
}
|
||||
|
||||
inline double3 cross_high_precision(const double3 &a, const double3 &b)
|
||||
{
|
||||
double3 result;
|
||||
cross_v3_v3v3_db(result, a, b);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline double3 project(const double3 &a, const double3 &b)
|
||||
{
|
||||
double3 result;
|
||||
project_v3_v3v3_db(result, a, b);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline double distance(const double3 &a, const double3 &b)
|
||||
{
|
||||
return length(a - b);
|
||||
}
|
||||
|
||||
inline double distance_squared(const double3 &a, const double3 &b)
|
||||
{
|
||||
const double3 diff = a - b;
|
||||
return dot(diff, diff);
|
||||
}
|
||||
|
||||
inline double3 lerp(const double3 &a, const double3 &b, double t)
|
||||
{
|
||||
return a * (1 - t) + b * t;
|
||||
}
|
||||
|
||||
inline double3 abs(const double3 &a)
|
||||
{
|
||||
return double3(fabs(a.x), fabs(a.y), fabs(a.z));
|
||||
}
|
||||
|
||||
inline int dominant_axis(const double3 &a)
|
||||
{
|
||||
double x = (a.x >= 0) ? a.x : -a.x;
|
||||
double y = (a.y >= 0) ? a.y : -a.y;
|
||||
double z = (a.z >= 0) ? a.z : -a.z;
|
||||
return ((x > y) ? ((x > z) ? 0 : 2) : ((y > z) ? 1 : 2));
|
||||
}
|
||||
|
||||
double3 cross_poly(Span<double3> poly);
|
||||
|
||||
} // namespace blender::math
|
||||
|
||||
namespace blender {
|
||||
using math::double3;
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "BLI_float3.hh"
|
||||
|
||||
namespace blender {
|
||||
namespace blender::math {
|
||||
|
||||
struct float2 {
|
||||
float x, y;
|
||||
@@ -47,129 +47,133 @@ struct float2 {
|
||||
return &x;
|
||||
}
|
||||
|
||||
float length() const
|
||||
{
|
||||
return len_v2(*this);
|
||||
}
|
||||
|
||||
float2 &operator+=(const float2 &other)
|
||||
{
|
||||
x += other.x;
|
||||
y += other.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
float2 &operator-=(const float2 &other)
|
||||
{
|
||||
x -= other.x;
|
||||
y -= other.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
float2 &operator*=(float factor)
|
||||
{
|
||||
x *= factor;
|
||||
y *= factor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
float2 &operator/=(float divisor)
|
||||
{
|
||||
x /= divisor;
|
||||
y /= divisor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint64_t hash() const
|
||||
{
|
||||
uint64_t x1 = *reinterpret_cast<const uint32_t *>(&x);
|
||||
uint64_t x2 = *reinterpret_cast<const uint32_t *>(&y);
|
||||
return (x1 * 812519) ^ (x2 * 707951);
|
||||
}
|
||||
|
||||
friend float2 operator+(const float2 &a, const float2 &b)
|
||||
{
|
||||
return {a.x + b.x, a.y + b.y};
|
||||
}
|
||||
|
||||
friend float2 operator-(const float2 &a, const float2 &b)
|
||||
{
|
||||
return {a.x - b.x, a.y - b.y};
|
||||
}
|
||||
|
||||
friend float2 operator*(const float2 &a, float b)
|
||||
{
|
||||
return {a.x * b, a.y * b};
|
||||
}
|
||||
|
||||
friend float2 operator/(const float2 &a, float b)
|
||||
{
|
||||
BLI_assert(b != 0.0f);
|
||||
return {a.x / b, a.y / b};
|
||||
}
|
||||
|
||||
friend float2 operator*(float a, const float2 &b)
|
||||
{
|
||||
return b * a;
|
||||
}
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &stream, const float2 &v)
|
||||
{
|
||||
stream << "(" << v.x << ", " << v.y << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
static float dot(const float2 &a, const float2 &b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y;
|
||||
}
|
||||
|
||||
static float2 interpolate(const float2 &a, const float2 &b, float t)
|
||||
{
|
||||
return a * (1 - t) + b * t;
|
||||
}
|
||||
|
||||
static float2 abs(const float2 &a)
|
||||
{
|
||||
return float2(fabsf(a.x), fabsf(a.y));
|
||||
}
|
||||
|
||||
static float distance(const float2 &a, const float2 &b)
|
||||
{
|
||||
return (a - b).length();
|
||||
}
|
||||
|
||||
static float distance_squared(const float2 &a, const float2 &b)
|
||||
{
|
||||
float2 diff = a - b;
|
||||
return float2::dot(diff, diff);
|
||||
}
|
||||
|
||||
struct isect_result {
|
||||
enum {
|
||||
LINE_LINE_COLINEAR = -1,
|
||||
LINE_LINE_NONE = 0,
|
||||
LINE_LINE_EXACT = 1,
|
||||
LINE_LINE_CROSS = 2,
|
||||
} kind;
|
||||
float lambda;
|
||||
float mu;
|
||||
};
|
||||
|
||||
static isect_result isect_seg_seg(const float2 &v1,
|
||||
const float2 &v2,
|
||||
const float2 &v3,
|
||||
const float2 &v4);
|
||||
|
||||
friend bool operator==(const float2 &a, const float2 &b)
|
||||
{
|
||||
return a.x == b.x && a.y == b.y;
|
||||
}
|
||||
|
||||
friend bool operator!=(const float2 &a, const float2 &b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace blender
|
||||
inline bool operator==(const float2 &a, const float2 &b)
|
||||
{
|
||||
return a.x == b.x && a.y == b.y;
|
||||
}
|
||||
|
||||
inline bool operator!=(const float2 &a, const float2 &b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline float2 &operator+=(float2 &a, const float2 &other)
|
||||
{
|
||||
a.x += other.x;
|
||||
a.y += other.y;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline float2 &operator-=(float2 &a, const float2 &other)
|
||||
{
|
||||
a.x -= other.x;
|
||||
a.y -= other.y;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline float2 &operator*=(float2 &a, float factor)
|
||||
{
|
||||
a.x *= factor;
|
||||
a.y *= factor;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline float2 &operator/=(float2 &a, float divisor)
|
||||
{
|
||||
a.x /= divisor;
|
||||
a.y /= divisor;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline float2 operator+(const float2 &a, const float2 &b)
|
||||
{
|
||||
return {a.x + b.x, a.y + b.y};
|
||||
}
|
||||
|
||||
inline float2 operator-(const float2 &a, const float2 &b)
|
||||
{
|
||||
return {a.x - b.x, a.y - b.y};
|
||||
}
|
||||
|
||||
inline float2 operator*(const float2 &a, float b)
|
||||
{
|
||||
return {a.x * b, a.y * b};
|
||||
}
|
||||
|
||||
inline float2 operator/(const float2 &a, float b)
|
||||
{
|
||||
BLI_assert(b != 0.0f);
|
||||
return {a.x / b, a.y / b};
|
||||
}
|
||||
|
||||
inline float2 operator*(float a, const float2 &b)
|
||||
{
|
||||
return b * a;
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &stream, const float2 &v)
|
||||
{
|
||||
stream << "(" << v.x << ", " << v.y << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline float length(const float2 &a)
|
||||
{
|
||||
return len_v2(a);
|
||||
}
|
||||
|
||||
inline float dot(const float2 &a, const float2 &b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y;
|
||||
}
|
||||
|
||||
inline float2 lerp(const float2 &a, const float2 &b, float t)
|
||||
{
|
||||
return a * (1 - t) + b * t;
|
||||
}
|
||||
|
||||
inline float2 abs(const float2 &a)
|
||||
{
|
||||
return float2(fabsf(a.x), fabsf(a.y));
|
||||
}
|
||||
|
||||
inline float distance(const float2 &a, const float2 &b)
|
||||
{
|
||||
return length(a - b);
|
||||
}
|
||||
|
||||
inline float distance_squared(const float2 &a, const float2 &b)
|
||||
{
|
||||
const float2 diff = a - b;
|
||||
return dot(diff, diff);
|
||||
}
|
||||
|
||||
struct isect_result_float2 {
|
||||
enum {
|
||||
LINE_LINE_COLINEAR = -1,
|
||||
LINE_LINE_NONE = 0,
|
||||
LINE_LINE_EXACT = 1,
|
||||
LINE_LINE_CROSS = 2,
|
||||
} kind;
|
||||
float lambda;
|
||||
float mu;
|
||||
};
|
||||
|
||||
isect_result_float2 isect_seg_seg(const float2 &v1,
|
||||
const float2 &v2,
|
||||
const float2 &v3,
|
||||
const float2 &v4);
|
||||
|
||||
} // namespace blender::math
|
||||
|
||||
namespace blender {
|
||||
using math::float2;
|
||||
}
|
||||
|
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "BLI_math_vector.h"
|
||||
|
||||
namespace blender {
|
||||
namespace blender::math {
|
||||
|
||||
struct float3 {
|
||||
float x, y, z;
|
||||
@@ -57,151 +57,6 @@ struct float3 {
|
||||
return &x;
|
||||
}
|
||||
|
||||
friend float3 operator+(const float3 &a, const float3 &b)
|
||||
{
|
||||
return {a.x + b.x, a.y + b.y, a.z + b.z};
|
||||
}
|
||||
|
||||
float3 &operator+=(const float3 &b)
|
||||
{
|
||||
this->x += b.x;
|
||||
this->y += b.y;
|
||||
this->z += b.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend float3 operator-(const float3 &a, const float3 &b)
|
||||
{
|
||||
return {a.x - b.x, a.y - b.y, a.z - b.z};
|
||||
}
|
||||
|
||||
friend float3 operator-(const float3 &a)
|
||||
{
|
||||
return {-a.x, -a.y, -a.z};
|
||||
}
|
||||
|
||||
float3 &operator-=(const float3 &b)
|
||||
{
|
||||
this->x -= b.x;
|
||||
this->y -= b.y;
|
||||
this->z -= b.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
float3 &operator*=(float scalar)
|
||||
{
|
||||
this->x *= scalar;
|
||||
this->y *= scalar;
|
||||
this->z *= scalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
float3 &operator*=(const float3 &other)
|
||||
{
|
||||
this->x *= other.x;
|
||||
this->y *= other.y;
|
||||
this->z *= other.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend float3 operator*(const float3 &a, const float3 &b)
|
||||
{
|
||||
return {a.x * b.x, a.y * b.y, a.z * b.z};
|
||||
}
|
||||
|
||||
friend float3 operator*(const float3 &a, float b)
|
||||
{
|
||||
return {a.x * b, a.y * b, a.z * b};
|
||||
}
|
||||
|
||||
friend float3 operator*(float a, const float3 &b)
|
||||
{
|
||||
return b * a;
|
||||
}
|
||||
|
||||
friend float3 operator/(const float3 &a, float b)
|
||||
{
|
||||
BLI_assert(b != 0.0f);
|
||||
return {a.x / b, a.y / b, a.z / b};
|
||||
}
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &stream, const float3 &v)
|
||||
{
|
||||
stream << "(" << v.x << ", " << v.y << ", " << v.z << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
friend bool operator==(const float3 &a, const float3 &b)
|
||||
{
|
||||
return a.x == b.x && a.y == b.y && a.z == b.z;
|
||||
}
|
||||
|
||||
friend bool operator!=(const float3 &a, const float3 &b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
float normalize_and_get_length()
|
||||
{
|
||||
return normalize_v3(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the vector in place.
|
||||
*/
|
||||
void normalize()
|
||||
{
|
||||
normalize_v3(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a normalized vector. The original vector is not changed.
|
||||
*/
|
||||
float3 normalized() const
|
||||
{
|
||||
float3 result;
|
||||
normalize_v3_v3(result, *this);
|
||||
return result;
|
||||
}
|
||||
|
||||
float length() const
|
||||
{
|
||||
return len_v3(*this);
|
||||
}
|
||||
|
||||
float length_squared() const
|
||||
{
|
||||
return len_squared_v3(*this);
|
||||
}
|
||||
|
||||
void reflect(const float3 &normal)
|
||||
{
|
||||
*this = this->reflected(normal);
|
||||
}
|
||||
|
||||
float3 reflected(const float3 &normal) const
|
||||
{
|
||||
float3 result;
|
||||
reflect_v3_v3v3(result, *this, normal);
|
||||
return result;
|
||||
}
|
||||
|
||||
static float3 safe_divide(const float3 &a, const float3 &b)
|
||||
{
|
||||
float3 result;
|
||||
result.x = (b.x == 0.0f) ? 0.0f : a.x / b.x;
|
||||
result.y = (b.y == 0.0f) ? 0.0f : a.y / b.y;
|
||||
result.z = (b.z == 0.0f) ? 0.0f : a.z / b.z;
|
||||
return result;
|
||||
}
|
||||
|
||||
void invert()
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
z = -z;
|
||||
}
|
||||
|
||||
uint64_t hash() const
|
||||
{
|
||||
uint64_t x1 = *reinterpret_cast<const uint32_t *>(&x);
|
||||
@@ -209,46 +64,189 @@ struct float3 {
|
||||
uint64_t x3 = *reinterpret_cast<const uint32_t *>(&z);
|
||||
return (x1 * 435109) ^ (x2 * 380867) ^ (x3 * 1059217);
|
||||
}
|
||||
|
||||
static float dot(const float3 &a, const float3 &b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
}
|
||||
|
||||
static float3 cross_high_precision(const float3 &a, const float3 &b)
|
||||
{
|
||||
float3 result;
|
||||
cross_v3_v3v3_hi_prec(result, a, b);
|
||||
return result;
|
||||
}
|
||||
|
||||
static float3 project(const float3 &a, const float3 &b)
|
||||
{
|
||||
float3 result;
|
||||
project_v3_v3v3(result, a, b);
|
||||
return result;
|
||||
}
|
||||
|
||||
static float distance(const float3 &a, const float3 &b)
|
||||
{
|
||||
return (a - b).length();
|
||||
}
|
||||
|
||||
static float distance_squared(const float3 &a, const float3 &b)
|
||||
{
|
||||
float3 diff = a - b;
|
||||
return float3::dot(diff, diff);
|
||||
}
|
||||
|
||||
static float3 interpolate(const float3 &a, const float3 &b, float t)
|
||||
{
|
||||
return a * (1 - t) + b * t;
|
||||
}
|
||||
|
||||
static float3 abs(const float3 &a)
|
||||
{
|
||||
return float3(fabsf(a.x), fabsf(a.y), fabsf(a.z));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace blender
|
||||
inline float3 operator+(const float3 &a, const float3 &b)
|
||||
{
|
||||
return {a.x + b.x, a.y + b.y, a.z + b.z};
|
||||
}
|
||||
|
||||
inline float3 &operator+=(float3 &a, const float3 &b)
|
||||
{
|
||||
a.x += b.x;
|
||||
a.y += b.y;
|
||||
a.z += b.z;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline float3 operator-(const float3 &a, const float3 &b)
|
||||
{
|
||||
return {a.x - b.x, a.y - b.y, a.z - b.z};
|
||||
}
|
||||
|
||||
inline float3 &operator-=(float3 &a, const float3 &b)
|
||||
{
|
||||
a.x -= b.x;
|
||||
a.y -= b.y;
|
||||
a.z -= b.z;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline float3 &operator*=(float3 &a, float scalar)
|
||||
{
|
||||
a.x *= scalar;
|
||||
a.y *= scalar;
|
||||
a.z *= scalar;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline float3 &operator*=(float3 &a, const float3 &other)
|
||||
{
|
||||
a.x *= other.x;
|
||||
a.y *= other.y;
|
||||
a.z *= other.z;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline float3 operator*(const float3 &a, const float3 &b)
|
||||
{
|
||||
return {a.x * b.x, a.y * b.y, a.z * b.z};
|
||||
}
|
||||
|
||||
inline float3 operator/(const float3 &a, float b)
|
||||
{
|
||||
BLI_assert(b != 0.0f);
|
||||
return {a.x / b, a.y / b, a.z / b};
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &stream, const float3 &v)
|
||||
{
|
||||
stream << "(" << v.x << ", " << v.y << ", " << v.z << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline float3 operator-(const float3 &a)
|
||||
{
|
||||
return {-a.x, -a.y, -a.z};
|
||||
}
|
||||
|
||||
inline bool operator==(const float3 &a, const float3 &b)
|
||||
{
|
||||
return a.x == b.x && a.y == b.y && a.z == b.z;
|
||||
}
|
||||
|
||||
inline bool operator!=(const float3 &a, const float3 &b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline float3 operator*(const float3 &a, float b)
|
||||
{
|
||||
return {a.x * b, a.y * b, a.z * b};
|
||||
}
|
||||
|
||||
inline float3 operator*(float a, const float3 &b)
|
||||
{
|
||||
return b * a;
|
||||
}
|
||||
|
||||
inline float normalize_and_get_length(float3 &a)
|
||||
{
|
||||
return normalize_v3(a);
|
||||
}
|
||||
|
||||
inline void normalize(float3 &a)
|
||||
{
|
||||
normalize_v3(a);
|
||||
}
|
||||
|
||||
inline float3 normalized(const float3 &a)
|
||||
{
|
||||
float3 result;
|
||||
normalize_v3_v3(result, a);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline float length(const float3 &a)
|
||||
{
|
||||
return len_v3(a);
|
||||
}
|
||||
|
||||
inline float length_squared(const float3 &a)
|
||||
{
|
||||
return len_squared_v3(a);
|
||||
}
|
||||
|
||||
inline float3 reflected(const float3 &a, const float3 &normal)
|
||||
{
|
||||
float3 result;
|
||||
reflect_v3_v3v3(result, a, normal);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void reflect(float3 &a, const float3 &normal)
|
||||
{
|
||||
a = reflected(a, normal);
|
||||
}
|
||||
|
||||
inline float3 safe_divide(const float3 &a, const float3 &b)
|
||||
{
|
||||
float3 result;
|
||||
result.x = (b.x == 0.0f) ? 0.0f : a.x / b.x;
|
||||
result.y = (b.y == 0.0f) ? 0.0f : a.y / b.y;
|
||||
result.z = (b.z == 0.0f) ? 0.0f : a.z / b.z;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void negate(float3 &a)
|
||||
{
|
||||
a.x = -a.x;
|
||||
a.y = -a.y;
|
||||
a.z = -a.z;
|
||||
}
|
||||
|
||||
inline float dot(const float3 &a, const float3 &b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
}
|
||||
|
||||
inline float3 cross_high_precision(const float3 &a, const float3 &b)
|
||||
{
|
||||
float3 result;
|
||||
cross_v3_v3v3_hi_prec(result, a, b);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline float3 project(const float3 &a, const float3 &b)
|
||||
{
|
||||
float3 result;
|
||||
project_v3_v3v3(result, a, b);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline float distance(const float3 &a, const float3 &b)
|
||||
{
|
||||
return length(a - b);
|
||||
}
|
||||
|
||||
inline float distance_squared(const float3 &a, const float3 &b)
|
||||
{
|
||||
const float3 diff = a - b;
|
||||
return dot(diff, diff);
|
||||
}
|
||||
|
||||
inline float3 lerp(const float3 &a, const float3 &b, float t)
|
||||
{
|
||||
return a * (1 - t) + b * t;
|
||||
}
|
||||
|
||||
inline float3 abs(const float3 &a)
|
||||
{
|
||||
return float3(fabsf(a.x), fabsf(a.y), fabsf(a.z));
|
||||
}
|
||||
|
||||
} // namespace blender::math
|
||||
|
||||
namespace blender {
|
||||
using math::float3;
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@
|
||||
# include "BLI_math_mpq.hh"
|
||||
# include "BLI_mpq3.hh"
|
||||
|
||||
namespace blender {
|
||||
namespace blender::math {
|
||||
|
||||
struct mpq2 {
|
||||
mpq_class x, y;
|
||||
@@ -80,105 +80,106 @@ struct mpq2 {
|
||||
return &x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cannot do this exactly in rational arithmetic!
|
||||
* Approximate by going in and out of doubles.
|
||||
*/
|
||||
mpq_class length() const
|
||||
{
|
||||
mpq_class lsquared = dot(*this, *this);
|
||||
return mpq_class(sqrt(lsquared.get_d()));
|
||||
}
|
||||
|
||||
friend mpq2 operator+(const mpq2 &a, const mpq2 &b)
|
||||
{
|
||||
return {a.x + b.x, a.y + b.y};
|
||||
}
|
||||
|
||||
friend mpq2 operator-(const mpq2 &a, const mpq2 &b)
|
||||
{
|
||||
return {a.x - b.x, a.y - b.y};
|
||||
}
|
||||
|
||||
friend mpq2 operator*(const mpq2 &a, mpq_class b)
|
||||
{
|
||||
return {a.x * b, a.y * b};
|
||||
}
|
||||
|
||||
friend mpq2 operator/(const mpq2 &a, mpq_class b)
|
||||
{
|
||||
BLI_assert(b != 0);
|
||||
return {a.x / b, a.y / b};
|
||||
}
|
||||
|
||||
friend mpq2 operator*(mpq_class a, const mpq2 &b)
|
||||
{
|
||||
return b * a;
|
||||
}
|
||||
|
||||
friend bool operator==(const mpq2 &a, const mpq2 &b)
|
||||
{
|
||||
return a.x == b.x && a.y == b.y;
|
||||
}
|
||||
|
||||
friend bool operator!=(const mpq2 &a, const mpq2 &b)
|
||||
{
|
||||
return a.x != b.x || a.y != b.y;
|
||||
}
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &stream, const mpq2 &v)
|
||||
{
|
||||
stream << "(" << v.x << ", " << v.y << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
static mpq_class dot(const mpq2 &a, const mpq2 &b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y;
|
||||
}
|
||||
|
||||
static mpq2 interpolate(const mpq2 &a, const mpq2 &b, mpq_class t)
|
||||
{
|
||||
return a * (1 - t) + b * t;
|
||||
}
|
||||
|
||||
static mpq2 abs(const mpq2 &a)
|
||||
{
|
||||
mpq_class abs_x = (a.x >= 0) ? a.x : -a.x;
|
||||
mpq_class abs_y = (a.y >= 0) ? a.y : -a.y;
|
||||
return mpq2(abs_x, abs_y);
|
||||
}
|
||||
|
||||
static mpq_class distance(const mpq2 &a, const mpq2 &b)
|
||||
{
|
||||
return (a - b).length();
|
||||
}
|
||||
|
||||
static mpq_class distance_squared(const mpq2 &a, const mpq2 &b)
|
||||
{
|
||||
mpq2 diff = a - b;
|
||||
return dot(diff, diff);
|
||||
}
|
||||
|
||||
struct isect_result {
|
||||
enum {
|
||||
LINE_LINE_COLINEAR = -1,
|
||||
LINE_LINE_NONE = 0,
|
||||
LINE_LINE_EXACT = 1,
|
||||
LINE_LINE_CROSS = 2,
|
||||
} kind;
|
||||
mpq_class lambda;
|
||||
};
|
||||
|
||||
static isect_result isect_seg_seg(const mpq2 &v1,
|
||||
const mpq2 &v2,
|
||||
const mpq2 &v3,
|
||||
const mpq2 &v4);
|
||||
|
||||
/** There is a sensible use for hashing on exact arithmetic types. */
|
||||
uint64_t hash() const;
|
||||
};
|
||||
|
||||
} // namespace blender
|
||||
inline mpq2 operator+(const mpq2 &a, const mpq2 &b)
|
||||
{
|
||||
return {a.x + b.x, a.y + b.y};
|
||||
}
|
||||
|
||||
inline mpq2 operator-(const mpq2 &a, const mpq2 &b)
|
||||
{
|
||||
return {a.x - b.x, a.y - b.y};
|
||||
}
|
||||
|
||||
inline mpq2 operator*(const mpq2 &a, mpq_class b)
|
||||
{
|
||||
return {a.x * b, a.y * b};
|
||||
}
|
||||
|
||||
inline mpq2 operator/(const mpq2 &a, mpq_class b)
|
||||
{
|
||||
BLI_assert(b != 0);
|
||||
return {a.x / b, a.y / b};
|
||||
}
|
||||
|
||||
inline mpq2 operator*(mpq_class a, const mpq2 &b)
|
||||
{
|
||||
return b * a;
|
||||
}
|
||||
|
||||
inline bool operator==(const mpq2 &a, const mpq2 &b)
|
||||
{
|
||||
return a.x == b.x && a.y == b.y;
|
||||
}
|
||||
|
||||
inline bool operator!=(const mpq2 &a, const mpq2 &b)
|
||||
{
|
||||
return a.x != b.x || a.y != b.y;
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &stream, const mpq2 &v)
|
||||
{
|
||||
stream << "(" << v.x << ", " << v.y << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline mpq_class dot(const mpq2 &a, const mpq2 &b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cannot do this exactly in rational arithmetic!
|
||||
* Approximate by going in and out of doubles.
|
||||
*/
|
||||
inline mpq_class length(const mpq2 &a)
|
||||
{
|
||||
mpq_class lsquared = dot(a, a);
|
||||
return mpq_class(sqrt(lsquared.get_d()));
|
||||
}
|
||||
|
||||
inline mpq2 lerp(const mpq2 &a, const mpq2 &b, mpq_class t)
|
||||
{
|
||||
return a * (1 - t) + b * t;
|
||||
}
|
||||
|
||||
inline mpq2 abs(const mpq2 &a)
|
||||
{
|
||||
mpq_class abs_x = (a.x >= 0) ? a.x : -a.x;
|
||||
mpq_class abs_y = (a.y >= 0) ? a.y : -a.y;
|
||||
return mpq2(abs_x, abs_y);
|
||||
}
|
||||
|
||||
inline mpq_class distance(const mpq2 &a, const mpq2 &b)
|
||||
{
|
||||
return length(a - b);
|
||||
}
|
||||
|
||||
inline mpq_class distance_squared(const mpq2 &a, const mpq2 &b)
|
||||
{
|
||||
const mpq2 diff = a - b;
|
||||
return dot(diff, diff);
|
||||
}
|
||||
|
||||
struct isect_result_mpq2 {
|
||||
enum {
|
||||
LINE_LINE_COLINEAR = -1,
|
||||
LINE_LINE_NONE = 0,
|
||||
LINE_LINE_EXACT = 1,
|
||||
LINE_LINE_CROSS = 2,
|
||||
} kind;
|
||||
mpq_class lambda;
|
||||
};
|
||||
|
||||
isect_result_mpq2 isect_seg_seg(const mpq2 &v1, const mpq2 &v2, const mpq2 &v3, const mpq2 &v4);
|
||||
|
||||
} // namespace blender::math
|
||||
|
||||
namespace blender {
|
||||
using math::mpq2;
|
||||
}
|
||||
|
||||
#endif /* WITH_GMP */
|
||||
|
@@ -28,7 +28,7 @@
|
||||
# include "BLI_math_mpq.hh"
|
||||
# include "BLI_span.hh"
|
||||
|
||||
namespace blender {
|
||||
namespace blender::math {
|
||||
|
||||
struct mpq3 {
|
||||
mpq_class x, y, z;
|
||||
@@ -65,217 +65,219 @@ struct mpq3 {
|
||||
return &x;
|
||||
}
|
||||
|
||||
/* Cannot do this exactly in rational arithmetic!
|
||||
* Approximate by going in and out of doubles.
|
||||
*/
|
||||
mpq_class normalize_and_get_length()
|
||||
{
|
||||
double dv[3] = {x.get_d(), y.get_d(), z.get_d()};
|
||||
double len = normalize_v3_db(dv);
|
||||
this->x = mpq_class(dv[0]);
|
||||
this->y = mpq_class(dv[1]);
|
||||
this->z = mpq_class(dv[2]);
|
||||
return len;
|
||||
}
|
||||
|
||||
mpq3 normalized() const
|
||||
{
|
||||
double dv[3] = {x.get_d(), y.get_d(), z.get_d()};
|
||||
double dr[3];
|
||||
normalize_v3_v3_db(dr, dv);
|
||||
return mpq3(mpq_class(dr[0]), mpq_class(dr[1]), mpq_class(dr[2]));
|
||||
}
|
||||
|
||||
/* Cannot do this exactly in rational arithmetic!
|
||||
* Approximate by going in and out of double.
|
||||
*/
|
||||
mpq_class length() const
|
||||
{
|
||||
mpq_class lsquared = this->length_squared();
|
||||
double dsquared = lsquared.get_d();
|
||||
double d = sqrt(dsquared);
|
||||
return mpq_class(d);
|
||||
}
|
||||
|
||||
mpq_class length_squared() const
|
||||
{
|
||||
return x * x + y * y + z * z;
|
||||
}
|
||||
|
||||
void reflect(const mpq3 &normal)
|
||||
{
|
||||
*this = this->reflected(normal);
|
||||
}
|
||||
|
||||
mpq3 reflected(const mpq3 &normal) const
|
||||
{
|
||||
mpq3 result;
|
||||
const mpq_class dot2 = 2 * dot(*this, normal);
|
||||
result.x = this->x - (dot2 * normal.x);
|
||||
result.y = this->y - (dot2 * normal.y);
|
||||
result.z = this->z - (dot2 * normal.z);
|
||||
return result;
|
||||
}
|
||||
|
||||
static mpq3 safe_divide(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
mpq3 result;
|
||||
result.x = (b.x == 0) ? mpq_class(0) : a.x / b.x;
|
||||
result.y = (b.y == 0) ? mpq_class(0) : a.y / b.y;
|
||||
result.z = (b.z == 0) ? mpq_class(0) : a.z / b.z;
|
||||
return result;
|
||||
}
|
||||
|
||||
void invert()
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
z = -z;
|
||||
}
|
||||
|
||||
friend mpq3 operator+(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
return mpq3(a.x + b.x, a.y + b.y, a.z + b.z);
|
||||
}
|
||||
|
||||
void operator+=(const mpq3 &b)
|
||||
{
|
||||
this->x += b.x;
|
||||
this->y += b.y;
|
||||
this->z += b.z;
|
||||
}
|
||||
|
||||
friend mpq3 operator-(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
return mpq3(a.x - b.x, a.y - b.y, a.z - b.z);
|
||||
}
|
||||
|
||||
friend mpq3 operator-(const mpq3 &a)
|
||||
{
|
||||
return mpq3(-a.x, -a.y, -a.z);
|
||||
}
|
||||
|
||||
void operator-=(const mpq3 &b)
|
||||
{
|
||||
this->x -= b.x;
|
||||
this->y -= b.y;
|
||||
this->z -= b.z;
|
||||
}
|
||||
|
||||
void operator*=(mpq_class scalar)
|
||||
{
|
||||
this->x *= scalar;
|
||||
this->y *= scalar;
|
||||
this->z *= scalar;
|
||||
}
|
||||
|
||||
void operator*=(const mpq3 &other)
|
||||
{
|
||||
this->x *= other.x;
|
||||
this->y *= other.y;
|
||||
this->z *= other.z;
|
||||
}
|
||||
|
||||
friend mpq3 operator*(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
return {a.x * b.x, a.y * b.y, a.z * b.z};
|
||||
}
|
||||
|
||||
friend mpq3 operator*(const mpq3 &a, const mpq_class &b)
|
||||
{
|
||||
return mpq3(a.x * b, a.y * b, a.z * b);
|
||||
}
|
||||
|
||||
friend mpq3 operator*(const mpq_class &a, const mpq3 &b)
|
||||
{
|
||||
return mpq3(a * b.x, a * b.y, a * b.z);
|
||||
}
|
||||
|
||||
friend mpq3 operator/(const mpq3 &a, const mpq_class &b)
|
||||
{
|
||||
BLI_assert(b != 0);
|
||||
return mpq3(a.x / b, a.y / b, a.z / b);
|
||||
}
|
||||
|
||||
friend bool operator==(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
return a.x == b.x && a.y == b.y && a.z == b.z;
|
||||
}
|
||||
|
||||
friend bool operator!=(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
return a.x != b.x || a.y != b.y || a.z != b.z;
|
||||
}
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &stream, const mpq3 &v)
|
||||
{
|
||||
stream << "(" << v.x << ", " << v.y << ", " << v.z << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
static mpq_class dot(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
}
|
||||
|
||||
static mpq3 cross(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
return mpq3(a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]);
|
||||
}
|
||||
|
||||
static mpq3 cross_high_precision(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
return cross(a, b);
|
||||
}
|
||||
|
||||
static mpq3 project(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
const mpq_class mul = mpq3::dot(a, b) / mpq3::dot(b, b);
|
||||
return mpq3(mul * b[0], mul * b[1], mul * b[2]);
|
||||
}
|
||||
|
||||
static mpq_class distance(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
mpq3 diff(a.x - b.x, a.y - b.y, a.z - b.z);
|
||||
return diff.length();
|
||||
}
|
||||
|
||||
static mpq_class distance_squared(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
mpq3 diff(a.x - b.x, a.y - b.y, a.z - b.z);
|
||||
return mpq3::dot(diff, diff);
|
||||
}
|
||||
|
||||
static mpq3 interpolate(const mpq3 &a, const mpq3 &b, mpq_class t)
|
||||
{
|
||||
mpq_class s = 1 - t;
|
||||
return mpq3(a.x * s + b.x * t, a.y * s + b.y * t, a.z * s + b.z * t);
|
||||
}
|
||||
|
||||
static mpq3 abs(const mpq3 &a)
|
||||
{
|
||||
mpq_class abs_x = (a.x >= 0) ? a.x : -a.x;
|
||||
mpq_class abs_y = (a.y >= 0) ? a.y : -a.y;
|
||||
mpq_class abs_z = (a.z >= 0) ? a.z : -a.z;
|
||||
return mpq3(abs_x, abs_y, abs_z);
|
||||
}
|
||||
|
||||
static int dominant_axis(const mpq3 &a)
|
||||
{
|
||||
mpq_class x = (a.x >= 0) ? a.x : -a.x;
|
||||
mpq_class y = (a.y >= 0) ? a.y : -a.y;
|
||||
mpq_class z = (a.z >= 0) ? a.z : -a.z;
|
||||
return ((x > y) ? ((x > z) ? 0 : 2) : ((y > z) ? 1 : 2));
|
||||
}
|
||||
|
||||
static mpq3 cross_poly(Span<mpq3> poly);
|
||||
|
||||
/** There is a sensible use for hashing on exact arithmetic types. */
|
||||
uint64_t hash() const;
|
||||
};
|
||||
|
||||
/* Cannot do this exactly in rational arithmetic!
|
||||
* Approximate by going in and out of doubles.
|
||||
*/
|
||||
inline mpq_class normalize_and_get_length(mpq3 &a)
|
||||
{
|
||||
double dv[3] = {a.x.get_d(), a.y.get_d(), a.z.get_d()};
|
||||
double len = normalize_v3_db(dv);
|
||||
a.x = mpq_class(dv[0]);
|
||||
a.y = mpq_class(dv[1]);
|
||||
a.z = mpq_class(dv[2]);
|
||||
return len;
|
||||
}
|
||||
|
||||
inline mpq3 normalized(const mpq3 &a)
|
||||
{
|
||||
double dv[3] = {a.x.get_d(), a.y.get_d(), a.z.get_d()};
|
||||
double dr[3];
|
||||
normalize_v3_v3_db(dr, dv);
|
||||
return mpq3(mpq_class(dr[0]), mpq_class(dr[1]), mpq_class(dr[2]));
|
||||
}
|
||||
|
||||
inline mpq_class length_squared(const mpq3 &a)
|
||||
{
|
||||
return a.x * a.x + a.y * a.y + a.z * a.z;
|
||||
}
|
||||
|
||||
/* Cannot do this exactly in rational arithmetic!
|
||||
* Approximate by going in and out of double.
|
||||
*/
|
||||
inline mpq_class length(const mpq3 &a)
|
||||
{
|
||||
mpq_class lsquared = length_squared(a);
|
||||
double dsquared = lsquared.get_d();
|
||||
double d = sqrt(dsquared);
|
||||
return mpq_class(d);
|
||||
}
|
||||
|
||||
inline mpq_class dot(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
}
|
||||
|
||||
inline mpq3 reflected(const mpq3 &a, const mpq3 &normal)
|
||||
{
|
||||
mpq3 result;
|
||||
const mpq_class dot2 = 2 * dot(a, normal);
|
||||
result.x = a.x - (dot2 * normal.x);
|
||||
result.y = a.y - (dot2 * normal.y);
|
||||
result.z = a.z - (dot2 * normal.z);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void reflect(mpq3 &a, const mpq3 &normal)
|
||||
{
|
||||
a = reflected(a, normal);
|
||||
}
|
||||
|
||||
inline mpq3 safe_divide(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
mpq3 result;
|
||||
result.x = (b.x == 0) ? mpq_class(0) : a.x / b.x;
|
||||
result.y = (b.y == 0) ? mpq_class(0) : a.y / b.y;
|
||||
result.z = (b.z == 0) ? mpq_class(0) : a.z / b.z;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void negate(mpq3 &a)
|
||||
{
|
||||
a.x = -a.x;
|
||||
a.y = -a.y;
|
||||
a.z = -a.z;
|
||||
}
|
||||
|
||||
inline mpq3 operator+(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
return mpq3(a.x + b.x, a.y + b.y, a.z + b.z);
|
||||
}
|
||||
|
||||
inline void operator+=(mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
a.x += b.x;
|
||||
a.y += b.y;
|
||||
a.z += b.z;
|
||||
}
|
||||
|
||||
inline mpq3 operator-(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
return mpq3(a.x - b.x, a.y - b.y, a.z - b.z);
|
||||
}
|
||||
|
||||
inline mpq3 operator-(const mpq3 &a)
|
||||
{
|
||||
return mpq3(-a.x, -a.y, -a.z);
|
||||
}
|
||||
|
||||
inline void operator-=(mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
a.x -= b.x;
|
||||
a.y -= b.y;
|
||||
a.z -= b.z;
|
||||
}
|
||||
|
||||
inline void operator*=(mpq3 &a, mpq_class scalar)
|
||||
{
|
||||
a.x *= scalar;
|
||||
a.y *= scalar;
|
||||
a.z *= scalar;
|
||||
}
|
||||
|
||||
inline void operator*=(mpq3 &a, const mpq3 &other)
|
||||
{
|
||||
a.x *= other.x;
|
||||
a.y *= other.y;
|
||||
a.z *= other.z;
|
||||
}
|
||||
|
||||
inline mpq3 operator*(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
return {a.x * b.x, a.y * b.y, a.z * b.z};
|
||||
}
|
||||
|
||||
inline mpq3 operator*(const mpq3 &a, const mpq_class &b)
|
||||
{
|
||||
return mpq3(a.x * b, a.y * b, a.z * b);
|
||||
}
|
||||
|
||||
inline mpq3 operator*(const mpq_class &a, const mpq3 &b)
|
||||
{
|
||||
return mpq3(a * b.x, a * b.y, a * b.z);
|
||||
}
|
||||
|
||||
inline mpq3 operator/(const mpq3 &a, const mpq_class &b)
|
||||
{
|
||||
BLI_assert(b != 0);
|
||||
return mpq3(a.x / b, a.y / b, a.z / b);
|
||||
}
|
||||
|
||||
inline bool operator==(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
return a.x == b.x && a.y == b.y && a.z == b.z;
|
||||
}
|
||||
|
||||
inline bool operator!=(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
return a.x != b.x || a.y != b.y || a.z != b.z;
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &stream, const mpq3 &v)
|
||||
{
|
||||
stream << "(" << v.x << ", " << v.y << ", " << v.z << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline mpq3 cross(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
return mpq3(a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]);
|
||||
}
|
||||
|
||||
inline mpq3 cross_high_precision(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
return cross(a, b);
|
||||
}
|
||||
|
||||
inline mpq3 project(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
const mpq_class mul = dot(a, b) / dot(b, b);
|
||||
return mpq3(mul * b[0], mul * b[1], mul * b[2]);
|
||||
}
|
||||
|
||||
inline mpq_class distance(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
return length(a - b);
|
||||
}
|
||||
|
||||
inline mpq_class distance_squared(const mpq3 &a, const mpq3 &b)
|
||||
{
|
||||
mpq3 diff(a.x - b.x, a.y - b.y, a.z - b.z);
|
||||
return dot(diff, diff);
|
||||
}
|
||||
|
||||
inline mpq3 lerp(const mpq3 &a, const mpq3 &b, mpq_class t)
|
||||
{
|
||||
mpq_class s = 1 - t;
|
||||
return mpq3(a.x * s + b.x * t, a.y * s + b.y * t, a.z * s + b.z * t);
|
||||
}
|
||||
|
||||
inline mpq3 abs(const mpq3 &a)
|
||||
{
|
||||
mpq_class abs_x = (a.x >= 0) ? a.x : -a.x;
|
||||
mpq_class abs_y = (a.y >= 0) ? a.y : -a.y;
|
||||
mpq_class abs_z = (a.z >= 0) ? a.z : -a.z;
|
||||
return mpq3(abs_x, abs_y, abs_z);
|
||||
}
|
||||
|
||||
inline int dominant_axis(const mpq3 &a)
|
||||
{
|
||||
mpq_class x = (a.x >= 0) ? a.x : -a.x;
|
||||
mpq_class y = (a.y >= 0) ? a.y : -a.y;
|
||||
mpq_class z = (a.z >= 0) ? a.z : -a.z;
|
||||
return ((x > y) ? ((x > z) ? 0 : 2) : ((y > z) ? 1 : 2));
|
||||
}
|
||||
|
||||
mpq3 cross_poly(Span<mpq3> poly);
|
||||
uint64_t hash_mpq_class(const mpq_class &value);
|
||||
|
||||
} // namespace blender
|
||||
} // namespace blender::math
|
||||
|
||||
namespace blender {
|
||||
using math::mpq3;
|
||||
}
|
||||
|
||||
#endif /* WITH_GMP */
|
||||
|
@@ -730,11 +730,11 @@ bool in_line<mpq_class>(const FatCo<mpq_class> &a,
|
||||
}
|
||||
vec2<mpq_class> exact_ab = b.exact - a.exact;
|
||||
vec2<mpq_class> exact_ac = c.exact - a.exact;
|
||||
if (vec2<mpq_class>::dot(exact_ab, exact_ac) < 0) {
|
||||
if (dot(exact_ab, exact_ac) < 0) {
|
||||
return false;
|
||||
}
|
||||
vec2<mpq_class> exact_bc = c.exact - b.exact;
|
||||
return vec2<mpq_class>::dot(exact_bc, exact_ac) >= 0;
|
||||
return dot(exact_bc, exact_ac) >= 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -743,11 +743,11 @@ bool in_line<double>(const FatCo<double> &a, const FatCo<double> &b, const FatCo
|
||||
{
|
||||
vec2<double> ab = b.approx - a.approx;
|
||||
vec2<double> ac = c.approx - a.approx;
|
||||
if (vec2<double>::dot(ab, ac) < 0) {
|
||||
if (dot(ab, ac) < 0) {
|
||||
return false;
|
||||
}
|
||||
vec2<double> bc = c.approx - b.approx;
|
||||
return vec2<double>::dot(bc, ac) >= 0;
|
||||
return dot(bc, ac) >= 0;
|
||||
}
|
||||
|
||||
template<> CDTVert<double>::CDTVert(const vec2<double> &pt)
|
||||
@@ -1041,7 +1041,7 @@ template<typename T> CDTEdge<T> *CDTArrangement<T>::split_edge(SymEdge<T> *se, T
|
||||
SymEdge<T> *sesymprev = prev(sesym);
|
||||
SymEdge<T> *sesymprevsym = sym(sesymprev);
|
||||
SymEdge<T> *senext = se->next;
|
||||
CDTVert<T> *v = this->add_vert(vec2<T>::interpolate(*a, *b, lambda));
|
||||
CDTVert<T> *v = this->add_vert(lerp(*a, *b, lambda));
|
||||
CDTEdge<T> *e = this->add_edge(v, se->next->vert, se->face, sesym->face);
|
||||
sesym->vert = v;
|
||||
SymEdge<T> *newse = &e->symedges[0];
|
||||
@@ -1664,16 +1664,17 @@ 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 = vec2<T>::isect_seg_seg(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);
|
||||
using isect_result = decltype(isect);
|
||||
T &lambda = isect.lambda;
|
||||
switch (isect.kind) {
|
||||
case vec2<T>::isect_result::LINE_LINE_CROSS: {
|
||||
case isect_result::LINE_LINE_CROSS: {
|
||||
#ifdef WITH_GMP
|
||||
if (!std::is_same<T, mpq_class>::value) {
|
||||
#else
|
||||
if (true) {
|
||||
#endif
|
||||
double len_ab = vec2<double>::distance(va->co.approx, vb->co.approx);
|
||||
double len_ab = distance(va->co.approx, vb->co.approx);
|
||||
if (lambda * len_ab <= epsilon) {
|
||||
fill_crossdata_for_through_vert(va, se_vcva, cd, cd_next);
|
||||
}
|
||||
@@ -1695,7 +1696,7 @@ void fill_crossdata_for_intersect(const FatCo<T> &curco,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case vec2<T>::isect_result::LINE_LINE_EXACT: {
|
||||
case isect_result::LINE_LINE_EXACT: {
|
||||
if (lambda == 0) {
|
||||
fill_crossdata_for_through_vert(va, se_vcva, cd, cd_next);
|
||||
}
|
||||
@@ -1710,7 +1711,7 @@ void fill_crossdata_for_intersect(const FatCo<T> &curco,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case vec2<T>::isect_result::LINE_LINE_NONE: {
|
||||
case isect_result::LINE_LINE_NONE: {
|
||||
#ifdef WITH_GMP
|
||||
if (std::is_same<T, mpq_class>::value) {
|
||||
BLI_assert(false);
|
||||
@@ -1726,9 +1727,9 @@ void fill_crossdata_for_intersect(const FatCo<T> &curco,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case vec2<T>::isect_result::LINE_LINE_COLINEAR: {
|
||||
if (vec2<double>::distance_squared(va->co.approx, v2->co.approx) <=
|
||||
vec2<double>::distance_squared(vb->co.approx, v2->co.approx)) {
|
||||
case isect_result::LINE_LINE_COLINEAR: {
|
||||
if (distance_squared(va->co.approx, v2->co.approx) <=
|
||||
distance_squared(vb->co.approx, v2->co.approx)) {
|
||||
fill_crossdata_for_through_vert(va, se_vcva, cd, cd_next);
|
||||
}
|
||||
else {
|
||||
@@ -1805,7 +1806,7 @@ void get_next_crossing_from_edge(CrossData<T> *cd,
|
||||
{
|
||||
CDTVert<T> *va = cd->in->vert;
|
||||
CDTVert<T> *vb = cd->in->next->vert;
|
||||
vec2<T> curco = vec2<T>::interpolate(va->co.exact, vb->co.exact, cd->lambda);
|
||||
vec2<T> curco = lerp(va->co.exact, vb->co.exact, cd->lambda);
|
||||
FatCo<T> fat_curco(curco);
|
||||
SymEdge<T> *se_ac = sym(cd->in)->next;
|
||||
CDTVert<T> *vc = se_ac->next->vert;
|
||||
@@ -2332,7 +2333,7 @@ template<typename T> void remove_non_constraint_edges_leave_valid_bmesh(CDT_stat
|
||||
dissolvable_edges[i].e = e;
|
||||
const vec2<double> &co1 = e->symedges[0].vert->co.approx;
|
||||
const vec2<double> &co2 = e->symedges[1].vert->co.approx;
|
||||
dissolvable_edges[i].len_squared = vec2<double>::distance_squared(co1, co2);
|
||||
dissolvable_edges[i].len_squared = distance_squared(co1, co2);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
@@ -29,78 +29,75 @@
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
namespace blender {
|
||||
namespace blender::math {
|
||||
|
||||
float2::isect_result float2::isect_seg_seg(const float2 &v1,
|
||||
const float2 &v2,
|
||||
const float2 &v3,
|
||||
const float2 &v4)
|
||||
isect_result_float2 isect_seg_seg(const float2 &v1,
|
||||
const float2 &v2,
|
||||
const float2 &v3,
|
||||
const float2 &v4)
|
||||
{
|
||||
float2::isect_result ans;
|
||||
isect_result_float2 ans;
|
||||
float div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]);
|
||||
if (div == 0.0f) {
|
||||
ans.lambda = 0.0f;
|
||||
ans.mu = 0.0f;
|
||||
ans.kind = float2::isect_result::LINE_LINE_COLINEAR;
|
||||
ans.kind = isect_result_float2::LINE_LINE_COLINEAR;
|
||||
}
|
||||
else {
|
||||
ans.lambda = ((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
|
||||
ans.mu = ((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
|
||||
if (ans.lambda >= 0.0f && ans.lambda <= 1.0f && ans.mu >= 0.0f && ans.mu <= 1.0f) {
|
||||
if (ans.lambda == 0.0f || ans.lambda == 1.0f || ans.mu == 0.0f || ans.mu == 1.0f) {
|
||||
ans.kind = float2::isect_result::LINE_LINE_EXACT;
|
||||
ans.kind = isect_result_float2::LINE_LINE_EXACT;
|
||||
}
|
||||
else {
|
||||
ans.kind = float2::isect_result::LINE_LINE_CROSS;
|
||||
ans.kind = isect_result_float2::LINE_LINE_CROSS;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ans.kind = float2::isect_result::LINE_LINE_NONE;
|
||||
ans.kind = isect_result_float2::LINE_LINE_NONE;
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
double2::isect_result double2::isect_seg_seg(const double2 &v1,
|
||||
const double2 &v2,
|
||||
const double2 &v3,
|
||||
const double2 &v4)
|
||||
isect_result_double2 isect_seg_seg(const double2 &v1,
|
||||
const double2 &v2,
|
||||
const double2 &v3,
|
||||
const double2 &v4)
|
||||
{
|
||||
double2::isect_result ans;
|
||||
isect_result_double2 ans;
|
||||
double div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]);
|
||||
if (div == 0.0) {
|
||||
ans.lambda = 0.0;
|
||||
ans.kind = double2::isect_result::LINE_LINE_COLINEAR;
|
||||
ans.kind = isect_result_double2::LINE_LINE_COLINEAR;
|
||||
}
|
||||
else {
|
||||
ans.lambda = ((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
|
||||
double mu = ((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
|
||||
if (ans.lambda >= 0.0 && ans.lambda <= 1.0 && mu >= 0.0 && mu <= 1.0) {
|
||||
if (ans.lambda == 0.0 || ans.lambda == 1.0 || mu == 0.0 || mu == 1.0) {
|
||||
ans.kind = double2::isect_result::LINE_LINE_EXACT;
|
||||
ans.kind = isect_result_double2::LINE_LINE_EXACT;
|
||||
}
|
||||
else {
|
||||
ans.kind = double2::isect_result::LINE_LINE_CROSS;
|
||||
ans.kind = isect_result_double2::LINE_LINE_CROSS;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ans.kind = double2::isect_result::LINE_LINE_NONE;
|
||||
ans.kind = isect_result_double2::LINE_LINE_NONE;
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
#ifdef WITH_GMP
|
||||
mpq2::isect_result mpq2::isect_seg_seg(const mpq2 &v1,
|
||||
const mpq2 &v2,
|
||||
const mpq2 &v3,
|
||||
const mpq2 &v4)
|
||||
isect_result_mpq2 isect_seg_seg(const mpq2 &v1, const mpq2 &v2, const mpq2 &v3, const mpq2 &v4)
|
||||
{
|
||||
mpq2::isect_result ans;
|
||||
isect_result_mpq2 ans;
|
||||
mpq_class div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]);
|
||||
if (div == 0.0) {
|
||||
ans.lambda = 0.0;
|
||||
ans.kind = mpq2::isect_result::LINE_LINE_COLINEAR;
|
||||
ans.kind = isect_result_mpq2::LINE_LINE_COLINEAR;
|
||||
}
|
||||
else {
|
||||
ans.lambda = ((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
|
||||
@@ -109,21 +106,21 @@ mpq2::isect_result mpq2::isect_seg_seg(const mpq2 &v1,
|
||||
if (ans.lambda >= 0 && ans.lambda <= 1 &&
|
||||
((div > 0 && mudiv >= 0 && mudiv <= div) || (div < 0 && mudiv <= 0 && mudiv >= div))) {
|
||||
if (ans.lambda == 0 || ans.lambda == 1 || mudiv == 0 || mudiv == div) {
|
||||
ans.kind = mpq2::isect_result::LINE_LINE_EXACT;
|
||||
ans.kind = isect_result_mpq2::LINE_LINE_EXACT;
|
||||
}
|
||||
else {
|
||||
ans.kind = mpq2::isect_result::LINE_LINE_CROSS;
|
||||
ans.kind = isect_result_mpq2::LINE_LINE_CROSS;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ans.kind = mpq2::isect_result::LINE_LINE_NONE;
|
||||
ans.kind = isect_result_mpq2::LINE_LINE_NONE;
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
} // namespace math
|
||||
#endif
|
||||
|
||||
double3 double3::cross_poly(Span<double3> poly)
|
||||
double3 cross_poly(Span<double3> poly)
|
||||
{
|
||||
/* Newell's Method. */
|
||||
int nv = static_cast<int>(poly.size());
|
||||
@@ -147,7 +144,7 @@ double3 double3::cross_poly(Span<double3> poly)
|
||||
}
|
||||
|
||||
#ifdef WITH_GMP
|
||||
mpq3 mpq3::cross_poly(Span<mpq3> poly)
|
||||
mpq3 cross_poly(Span<mpq3> poly)
|
||||
{
|
||||
/* Newell's Method. */
|
||||
int nv = static_cast<int>(poly.size());
|
||||
@@ -192,4 +189,4 @@ uint64_t mpq3::hash() const
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace blender
|
||||
} // namespace blender::math
|
||||
|
@@ -1561,13 +1561,13 @@ static Edge find_good_sorting_edge(const Vert *testp,
|
||||
ordinate[axis_next] = -abscissa[axis];
|
||||
ordinate[axis_next_next] = 0;
|
||||
/* By construction, dot(abscissa, ordinate) == 0, so they are perpendicular. */
|
||||
mpq3 normal = mpq3::cross(abscissa, ordinate);
|
||||
mpq3 normal = cross(abscissa, ordinate);
|
||||
if (dbg_level > 0) {
|
||||
std::cout << "abscissa = " << abscissa << "\n";
|
||||
std::cout << "ordinate = " << ordinate << "\n";
|
||||
std::cout << "normal = " << normal << "\n";
|
||||
}
|
||||
mpq_class nlen2 = normal.length_squared();
|
||||
mpq_class nlen2 = length_squared(normal);
|
||||
mpq_class max_abs_slope = -1;
|
||||
Edge esort;
|
||||
const Vector<Edge> &edges = tmtopo.vert_edges(closestp);
|
||||
@@ -1576,12 +1576,12 @@ static Edge find_good_sorting_edge(const Vert *testp,
|
||||
const mpq3 &co_other = v_other->co_exact;
|
||||
mpq3 evec = co_other - co_closest;
|
||||
/* Get projection of evec onto plane of abscissa and ordinate. */
|
||||
mpq3 proj_evec = evec - (mpq3::dot(evec, normal) / nlen2) * normal;
|
||||
mpq3 proj_evec = evec - (dot(evec, normal) / nlen2) * normal;
|
||||
/* The projection calculations along the abscissa and ordinate should
|
||||
* be scaled by 1/abscissa and 1/ordinate respectively,
|
||||
* but we can skip: it won't affect which `evec` has the maximum slope. */
|
||||
mpq_class evec_a = mpq3::dot(proj_evec, abscissa);
|
||||
mpq_class evec_o = mpq3::dot(proj_evec, ordinate);
|
||||
mpq_class evec_a = dot(proj_evec, abscissa);
|
||||
mpq_class evec_o = dot(proj_evec, ordinate);
|
||||
if (dbg_level > 0) {
|
||||
std::cout << "e = " << e << "\n";
|
||||
std::cout << "v_other = " << v_other << "\n";
|
||||
@@ -1700,8 +1700,8 @@ static mpq_class closest_on_tri_to_point(
|
||||
mpq3 ab = b - a;
|
||||
mpq3 ac = c - a;
|
||||
mpq3 ap = p - a;
|
||||
mpq_class d1 = mpq3::dot(ab, ap);
|
||||
mpq_class d2 = mpq3::dot(ac, ap);
|
||||
mpq_class d1 = dot(ab, ap);
|
||||
mpq_class d2 = dot(ac, ap);
|
||||
if (d1 <= 0 && d2 <= 0) {
|
||||
/* Barycentric coordinates (1,0,0). */
|
||||
*r_edge = -1;
|
||||
@@ -1709,12 +1709,12 @@ static mpq_class closest_on_tri_to_point(
|
||||
if (dbg_level > 0) {
|
||||
std::cout << " answer = a\n";
|
||||
}
|
||||
return mpq3::distance_squared(p, a);
|
||||
return distance_squared(p, a);
|
||||
}
|
||||
/* Check if p in vertex region outside b. */
|
||||
mpq3 bp = p - b;
|
||||
mpq_class d3 = mpq3::dot(ab, bp);
|
||||
mpq_class d4 = mpq3::dot(ac, bp);
|
||||
mpq_class d3 = dot(ab, bp);
|
||||
mpq_class d4 = dot(ac, bp);
|
||||
if (d3 >= 0 && d4 <= d3) {
|
||||
/* Barycentric coordinates (0,1,0). */
|
||||
*r_edge = -1;
|
||||
@@ -1722,7 +1722,7 @@ static mpq_class closest_on_tri_to_point(
|
||||
if (dbg_level > 0) {
|
||||
std::cout << " answer = b\n";
|
||||
}
|
||||
return mpq3::distance_squared(p, b);
|
||||
return distance_squared(p, b);
|
||||
}
|
||||
/* Check if p in region of ab. */
|
||||
mpq_class vc = d1 * d4 - d3 * d2;
|
||||
@@ -1735,12 +1735,12 @@ static mpq_class closest_on_tri_to_point(
|
||||
if (dbg_level > 0) {
|
||||
std::cout << " answer = on ab at " << r << "\n";
|
||||
}
|
||||
return mpq3::distance_squared(p, r);
|
||||
return distance_squared(p, r);
|
||||
}
|
||||
/* Check if p in vertex region outside c. */
|
||||
mpq3 cp = p - c;
|
||||
mpq_class d5 = mpq3::dot(ab, cp);
|
||||
mpq_class d6 = mpq3::dot(ac, cp);
|
||||
mpq_class d5 = dot(ab, cp);
|
||||
mpq_class d6 = dot(ac, cp);
|
||||
if (d6 >= 0 && d5 <= d6) {
|
||||
/* Barycentric coordinates (0,0,1). */
|
||||
*r_edge = -1;
|
||||
@@ -1748,7 +1748,7 @@ static mpq_class closest_on_tri_to_point(
|
||||
if (dbg_level > 0) {
|
||||
std::cout << " answer = c\n";
|
||||
}
|
||||
return mpq3::distance_squared(p, c);
|
||||
return distance_squared(p, c);
|
||||
}
|
||||
/* Check if p in edge region of ac. */
|
||||
mpq_class vb = d5 * d2 - d1 * d6;
|
||||
@@ -1761,7 +1761,7 @@ static mpq_class closest_on_tri_to_point(
|
||||
if (dbg_level > 0) {
|
||||
std::cout << " answer = on ac at " << r << "\n";
|
||||
}
|
||||
return mpq3::distance_squared(p, r);
|
||||
return distance_squared(p, r);
|
||||
}
|
||||
/* Check if p in edge region of bc. */
|
||||
mpq_class va = d3 * d6 - d5 * d4;
|
||||
@@ -1776,7 +1776,7 @@ static mpq_class closest_on_tri_to_point(
|
||||
if (dbg_level > 0) {
|
||||
std::cout << " answer = on bc at " << r << "\n";
|
||||
}
|
||||
return mpq3::distance_squared(p, r);
|
||||
return distance_squared(p, r);
|
||||
}
|
||||
/* p inside face region. Compute barycentric coordinates (u,v,w). */
|
||||
mpq_class denom = 1 / (va + vb + vc);
|
||||
@@ -1790,7 +1790,7 @@ static mpq_class closest_on_tri_to_point(
|
||||
if (dbg_level > 0) {
|
||||
std::cout << " answer = inside at " << r << "\n";
|
||||
}
|
||||
return mpq3::distance_squared(p, r);
|
||||
return distance_squared(p, r);
|
||||
}
|
||||
|
||||
struct ComponentContainer {
|
||||
@@ -2375,13 +2375,12 @@ static double generalized_winding_number(const IMesh &tm,
|
||||
/* Calculate the solid angle of abc relative to origin.
|
||||
* See "The Solid Angle of a Plane Triangle" by Oosterom and Strackee
|
||||
* for the derivation of the formula. */
|
||||
double alen = a.length();
|
||||
double blen = b.length();
|
||||
double clen = c.length();
|
||||
double3 bxc = double3::cross_high_precision(b, c);
|
||||
double num = double3::dot(a, bxc);
|
||||
double denom = alen * blen * clen + double3::dot(a, b) * clen + double3::dot(a, c) * blen +
|
||||
double3::dot(b, c) * alen;
|
||||
double alen = length(a);
|
||||
double blen = length(b);
|
||||
double clen = length(c);
|
||||
double3 bxc = cross_high_precision(b, c);
|
||||
double num = dot(a, bxc);
|
||||
double denom = alen * blen * clen + dot(a, b) * clen + dot(a, c) * blen + dot(b, c) * alen;
|
||||
if (denom == 0.0) {
|
||||
if (dbg_level > 0) {
|
||||
std::cout << "denom == 0, skipping this tri\n";
|
||||
@@ -2569,7 +2568,7 @@ static Array<Face *> triangulate_poly(Face *f, IMeshArena *arena)
|
||||
f->populate_plane(false);
|
||||
}
|
||||
const double3 &poly_normal = f->plane->norm;
|
||||
int axis = double3::dominant_axis(poly_normal);
|
||||
int axis = dominant_axis(poly_normal);
|
||||
/* If project down y axis as opposed to x or z, the orientation
|
||||
* of the polygon will be reversed.
|
||||
* Yet another reversal happens if the poly normal in the dominant
|
||||
@@ -2783,7 +2782,7 @@ static void init_face_merge_state(FaceMergeState *fms,
|
||||
std::cout << "process tri = " << &tri << "\n";
|
||||
}
|
||||
BLI_assert(tri.plane_populated());
|
||||
if (double3::dot(norm, tri.plane->norm) <= 0.0) {
|
||||
if (dot(norm, tri.plane->norm) <= 0.0) {
|
||||
if (dbg_level > 0) {
|
||||
std::cout << "triangle has wrong orientation, skipping\n";
|
||||
}
|
||||
@@ -2808,7 +2807,7 @@ static void init_face_merge_state(FaceMergeState *fms,
|
||||
}
|
||||
if (me_index == -1) {
|
||||
double3 vec = new_me.v2->co - new_me.v1->co;
|
||||
new_me.len_squared = vec.length_squared();
|
||||
new_me.len_squared = length_squared(vec);
|
||||
new_me.orig = tri.edge_orig[i];
|
||||
new_me.is_intersect = tri.is_intersect[i];
|
||||
new_me.dissolvable = (new_me.orig == NO_INDEX && !new_me.is_intersect);
|
||||
@@ -3048,7 +3047,7 @@ static Vector<Face *> merge_tris_for_face(Vector<int> tris,
|
||||
bool done = false;
|
||||
double3 first_tri_normal = tm.face(tris[0])->plane->norm;
|
||||
double3 second_tri_normal = tm.face(tris[1])->plane->norm;
|
||||
if (tris.size() == 2 && double3::dot(first_tri_normal, second_tri_normal) > 0.0) {
|
||||
if (tris.size() == 2 && dot(first_tri_normal, second_tri_normal) > 0.0) {
|
||||
/* Is this a case where quad with one diagonal remained unchanged?
|
||||
* Worth special handling because this case will be very common. */
|
||||
Face &tri1 = *tm.face(tris[0]);
|
||||
|
@@ -193,14 +193,14 @@ void Face::populate_plane(bool need_exact)
|
||||
for (int i : index_range()) {
|
||||
co[i] = vert[i]->co_exact;
|
||||
}
|
||||
normal_exact = mpq3::cross_poly(co);
|
||||
normal_exact = cross_poly(co);
|
||||
}
|
||||
else {
|
||||
mpq3 tr02 = vert[0]->co_exact - vert[2]->co_exact;
|
||||
mpq3 tr12 = vert[1]->co_exact - vert[2]->co_exact;
|
||||
normal_exact = mpq3::cross(tr02, tr12);
|
||||
normal_exact = cross(tr02, tr12);
|
||||
}
|
||||
mpq_class d_exact = -mpq3::dot(normal_exact, vert[0]->co_exact);
|
||||
mpq_class d_exact = -dot(normal_exact, vert[0]->co_exact);
|
||||
plane = new Plane(normal_exact, d_exact);
|
||||
}
|
||||
else {
|
||||
@@ -210,14 +210,14 @@ void Face::populate_plane(bool need_exact)
|
||||
for (int i : index_range()) {
|
||||
co[i] = vert[i]->co;
|
||||
}
|
||||
normal = double3::cross_poly(co);
|
||||
normal = cross_poly(co);
|
||||
}
|
||||
else {
|
||||
double3 tr02 = vert[0]->co - vert[2]->co;
|
||||
double3 tr12 = vert[1]->co - vert[2]->co;
|
||||
normal = double3::cross_high_precision(tr02, tr12);
|
||||
normal = cross_high_precision(tr02, tr12);
|
||||
}
|
||||
double d = -double3::dot(normal, vert[0]->co);
|
||||
double d = -dot(normal, vert[0]->co);
|
||||
plane = new Plane(normal, d);
|
||||
}
|
||||
}
|
||||
@@ -1174,15 +1174,15 @@ static mpq2 project_3d_to_2d(const mpq3 &p3d, int proj_axis)
|
||||
*/
|
||||
static double supremum_dot_cross(const double3 &a, const double3 &b)
|
||||
{
|
||||
double3 abs_a = double3::abs(a);
|
||||
double3 abs_b = double3::abs(b);
|
||||
double3 abs_a = abs(a);
|
||||
double3 abs_b = abs(b);
|
||||
double3 c;
|
||||
/* This is dot(cross(a, b), cross(a,b)) but using absolute values for a and b
|
||||
* and always using + when operation is + or -. */
|
||||
c[0] = abs_a[1] * abs_b[2] + abs_a[2] * abs_b[1];
|
||||
c[1] = abs_a[2] * abs_b[0] + abs_a[0] * abs_b[2];
|
||||
c[2] = abs_a[0] * abs_b[1] + abs_a[1] * abs_b[0];
|
||||
return double3::dot(c, c);
|
||||
return dot(c, c);
|
||||
}
|
||||
|
||||
/* The index of dot when inputs are plane_coords with index 1 is much higher.
|
||||
@@ -1219,11 +1219,11 @@ static int filter_plane_side(const double3 &p,
|
||||
const double3 &abs_plane_p,
|
||||
const double3 &abs_plane_no)
|
||||
{
|
||||
double d = double3::dot(p - plane_p, plane_no);
|
||||
double d = dot(p - plane_p, plane_no);
|
||||
if (d == 0.0) {
|
||||
return 0;
|
||||
}
|
||||
double supremum = double3::dot(abs_p + abs_plane_p, abs_plane_no);
|
||||
double supremum = dot(abs_p + abs_plane_p, abs_plane_no);
|
||||
double err_bound = supremum * index_plane_side * DBL_EPSILON;
|
||||
if (fabs(d) > err_bound) {
|
||||
return d > 0 ? 1 : -1;
|
||||
@@ -1248,9 +1248,9 @@ static int filter_plane_side(const double3 &p,
|
||||
static inline mpq3 tti_interp(const mpq3 &a, const mpq3 &b, const mpq3 &c, const mpq3 &n)
|
||||
{
|
||||
mpq3 ab = a - b;
|
||||
mpq_class den = mpq3::dot(ab, n);
|
||||
mpq_class den = dot(ab, n);
|
||||
BLI_assert(den != 0);
|
||||
mpq_class alpha = mpq3::dot(a - c, n) / den;
|
||||
mpq_class alpha = dot(a - c, n) / den;
|
||||
return a - alpha * ab;
|
||||
}
|
||||
|
||||
@@ -1261,8 +1261,8 @@ static inline mpq3 tti_interp(const mpq3 &a, const mpq3 &b, const mpq3 &c, const
|
||||
*/
|
||||
static inline int tti_above(const mpq3 &a, const mpq3 &b, const mpq3 &c, const mpq3 &ad)
|
||||
{
|
||||
mpq3 n = mpq3::cross(b - a, c - a);
|
||||
return sgn(mpq3::dot(ad, n));
|
||||
mpq3 n = cross(b - a, c - a);
|
||||
return sgn(dot(ad, n));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1480,11 +1480,11 @@ static ITT_value intersect_tri_tri(const IMesh &tm, int t1, int t2)
|
||||
const double3 &d_r2 = vr2->co;
|
||||
const double3 &d_n2 = tri2.plane->norm;
|
||||
|
||||
const double3 &abs_d_p1 = double3::abs(d_p1);
|
||||
const double3 &abs_d_q1 = double3::abs(d_q1);
|
||||
const double3 &abs_d_r1 = double3::abs(d_r1);
|
||||
const double3 &abs_d_r2 = double3::abs(d_r2);
|
||||
const double3 &abs_d_n2 = double3::abs(d_n2);
|
||||
const double3 &abs_d_p1 = abs(d_p1);
|
||||
const double3 &abs_d_q1 = abs(d_q1);
|
||||
const double3 &abs_d_r1 = abs(d_r1);
|
||||
const double3 &abs_d_r2 = abs(d_r2);
|
||||
const double3 &abs_d_n2 = abs(d_n2);
|
||||
|
||||
int sp1 = filter_plane_side(d_p1, d_r2, d_n2, abs_d_p1, abs_d_r2, abs_d_n2);
|
||||
int sq1 = filter_plane_side(d_q1, d_r2, d_n2, abs_d_q1, abs_d_r2, abs_d_n2);
|
||||
@@ -1500,9 +1500,9 @@ static ITT_value intersect_tri_tri(const IMesh &tm, int t1, int t2)
|
||||
}
|
||||
|
||||
const double3 &d_n1 = tri1.plane->norm;
|
||||
const double3 &abs_d_p2 = double3::abs(d_p2);
|
||||
const double3 &abs_d_q2 = double3::abs(d_q2);
|
||||
const double3 &abs_d_n1 = double3::abs(d_n1);
|
||||
const double3 &abs_d_p2 = abs(d_p2);
|
||||
const double3 &abs_d_q2 = abs(d_q2);
|
||||
const double3 &abs_d_n1 = abs(d_n1);
|
||||
|
||||
int sp2 = filter_plane_side(d_p2, d_r1, d_n1, abs_d_p2, abs_d_r1, abs_d_n1);
|
||||
int sq2 = filter_plane_side(d_q2, d_r1, d_n1, abs_d_q2, abs_d_r1, abs_d_n1);
|
||||
@@ -1526,13 +1526,13 @@ static ITT_value intersect_tri_tri(const IMesh &tm, int t1, int t2)
|
||||
|
||||
const mpq3 &n2 = tri2.plane->norm_exact;
|
||||
if (sp1 == 0) {
|
||||
sp1 = sgn(mpq3::dot(p1 - r2, n2));
|
||||
sp1 = sgn(dot(p1 - r2, n2));
|
||||
}
|
||||
if (sq1 == 0) {
|
||||
sq1 = sgn(mpq3::dot(q1 - r2, n2));
|
||||
sq1 = sgn(dot(q1 - r2, n2));
|
||||
}
|
||||
if (sr1 == 0) {
|
||||
sr1 = sgn(mpq3::dot(r1 - r2, n2));
|
||||
sr1 = sgn(dot(r1 - r2, n2));
|
||||
}
|
||||
|
||||
if (dbg_level > 1) {
|
||||
@@ -1552,13 +1552,13 @@ static ITT_value intersect_tri_tri(const IMesh &tm, int t1, int t2)
|
||||
/* Repeat for signs of t2's vertices with respect to plane of t1. */
|
||||
const mpq3 &n1 = tri1.plane->norm_exact;
|
||||
if (sp2 == 0) {
|
||||
sp2 = sgn(mpq3::dot(p2 - r1, n1));
|
||||
sp2 = sgn(dot(p2 - r1, n1));
|
||||
}
|
||||
if (sq2 == 0) {
|
||||
sq2 = sgn(mpq3::dot(q2 - r1, n1));
|
||||
sq2 = sgn(dot(q2 - r1, n1));
|
||||
}
|
||||
if (sr2 == 0) {
|
||||
sr2 = sgn(mpq3::dot(r2 - r1, n1));
|
||||
sr2 = sgn(dot(r2 - r1, n1));
|
||||
}
|
||||
|
||||
if (dbg_level > 1) {
|
||||
@@ -1757,7 +1757,7 @@ static CDT_data prepare_cdt_input(const IMesh &tm, int t, const Vector<ITT_value
|
||||
BLI_assert(tm.face(t)->plane_populated());
|
||||
ans.t_plane = tm.face(t)->plane;
|
||||
BLI_assert(ans.t_plane->exact_populated());
|
||||
ans.proj_axis = mpq3::dominant_axis(ans.t_plane->norm_exact);
|
||||
ans.proj_axis = dominant_axis(ans.t_plane->norm_exact);
|
||||
prepare_need_tri(ans, tm, t);
|
||||
for (const ITT_value &itt : itts) {
|
||||
switch (itt.kind) {
|
||||
@@ -1793,7 +1793,7 @@ static CDT_data prepare_cdt_input_for_cluster(const IMesh &tm,
|
||||
BLI_assert(tm.face(t0)->plane_populated());
|
||||
ans.t_plane = tm.face(t0)->plane;
|
||||
BLI_assert(ans.t_plane->exact_populated());
|
||||
ans.proj_axis = mpq3::dominant_axis(ans.t_plane->norm_exact);
|
||||
ans.proj_axis = dominant_axis(ans.t_plane->norm_exact);
|
||||
for (const int t : cl) {
|
||||
prepare_need_tri(ans, tm, t);
|
||||
}
|
||||
@@ -2535,15 +2535,15 @@ static bool face_is_degenerate(const Face *f)
|
||||
}
|
||||
double3 da = v2->co - v0->co;
|
||||
double3 db = v2->co - v1->co;
|
||||
double3 dab = double3::cross_high_precision(da, db);
|
||||
double dab_length_squared = dab.length_squared();
|
||||
double3 dab = cross_high_precision(da, db);
|
||||
double dab_length_squared = length_squared(dab);
|
||||
double err_bound = supremum_dot_cross(dab, dab) * index_dot_cross * DBL_EPSILON;
|
||||
if (dab_length_squared > err_bound) {
|
||||
return false;
|
||||
}
|
||||
mpq3 a = v2->co_exact - v0->co_exact;
|
||||
mpq3 b = v2->co_exact - v1->co_exact;
|
||||
mpq3 ab = mpq3::cross(a, b);
|
||||
mpq3 ab = cross(a, b);
|
||||
if (ab.x == 0 && ab.y == 0 && ab.z == 0) {
|
||||
return true;
|
||||
}
|
||||
|
@@ -196,8 +196,7 @@ static float compute_voxel_size(const ModifierEvalContext *ctx,
|
||||
/* Compute the voxel size based on the desired number of voxels and the approximated bounding box
|
||||
* of the volume. */
|
||||
const BoundBox *bb = BKE_object_boundbox_get(mvmd->object);
|
||||
const float diagonal = float3::distance(transform * float3(bb->vec[6]),
|
||||
transform * float3(bb->vec[0]));
|
||||
const float diagonal = distance(transform * float3(bb->vec[6]), transform * float3(bb->vec[0]));
|
||||
const float approximate_volume_side_length = diagonal + mvmd->exterior_band_width * 2.0f;
|
||||
const float voxel_size = approximate_volume_side_length / mvmd->voxel_amount / volume_simplify;
|
||||
return voxel_size;
|
||||
|
@@ -39,7 +39,7 @@ namespace blender::nodes {
|
||||
|
||||
static bool use_translate(const float3 rotation, const float3 scale)
|
||||
{
|
||||
if (compare_ff(rotation.length_squared(), 0.0f, 1e-9f) != 1) {
|
||||
if (compare_ff(length_squared(rotation), 0.0f, 1e-9f) != 1) {
|
||||
return false;
|
||||
}
|
||||
if (compare_ff(scale.x, 1.0f, 1e-9f) != 1 || compare_ff(scale.y, 1.0f, 1e-9f) != 1 ||
|
||||
|
@@ -197,7 +197,7 @@ static DataTypeConversions create_implicit_conversions()
|
||||
add_implicit_conversion<float, bool>(conversions);
|
||||
add_implicit_conversion<bool, float>(conversions);
|
||||
add_implicit_conversion<float3, float>(
|
||||
conversions, "Vector Length", [](float3 a) { return a.length(); });
|
||||
conversions, "Vector Length", [](float3 a) { return length(a); });
|
||||
add_implicit_conversion<int32_t, float3>(
|
||||
conversions, "int32 to float3", [](int32_t a) { return float3((float)a); });
|
||||
add_implicit_conversion<float3, Color4f>(
|
||||
@@ -209,7 +209,7 @@ static DataTypeConversions create_implicit_conversions()
|
||||
add_implicit_conversion<Color4f, float>(
|
||||
conversions, "Color4f to float", [](Color4f a) { return rgb_to_grayscale(a); });
|
||||
add_implicit_conversion<float3, bool>(
|
||||
conversions, "float3 to boolean", [](float3 a) { return a.length_squared() == 0.0f; });
|
||||
conversions, "float3 to boolean", [](float3 a) { return length_squared(a) == 0.0f; });
|
||||
add_implicit_conversion<bool, float3>(
|
||||
conversions, "boolean to float3", [](bool a) { return (a) ? float3(1.0f) : float3(0.0f); });
|
||||
return conversions;
|
||||
|
@@ -183,37 +183,39 @@ static const blender::fn::MultiFunction &get_multi_function(
|
||||
}
|
||||
case NODE_VECTOR_MATH_DIVIDE: {
|
||||
static blender::fn::CustomMF_SI_SI_SO<float3, float3, float3> fn{
|
||||
"Divide", [](float3 a, float3 b) { return float3::safe_divide(a, b); }};
|
||||
"Divide", [](float3 a, float3 b) { return safe_divide(a, b); }};
|
||||
return fn;
|
||||
}
|
||||
|
||||
case NODE_VECTOR_MATH_CROSS_PRODUCT: {
|
||||
static blender::fn::CustomMF_SI_SI_SO<float3, float3, float3> fn{
|
||||
"Cross Product", float3::cross_high_precision};
|
||||
"Cross Product", [](float3 a, float3 b) { return cross_high_precision(a, b); }};
|
||||
return fn;
|
||||
}
|
||||
case NODE_VECTOR_MATH_PROJECT: {
|
||||
static blender::fn::CustomMF_SI_SI_SO<float3, float3, float3> fn{"Project", float3::project};
|
||||
static blender::fn::CustomMF_SI_SI_SO<float3, float3, float3> fn{
|
||||
"Project", [](float3 a, float3 b) { return project(a, b); }};
|
||||
return fn;
|
||||
}
|
||||
case NODE_VECTOR_MATH_REFLECT: {
|
||||
static blender::fn::CustomMF_SI_SI_SO<float3, float3, float3> fn{
|
||||
"Reflect", [](float3 a, float3 b) { return a.reflected(b); }};
|
||||
"Reflect", [](float3 a, float3 b) { return reflected(a, b); }};
|
||||
return fn;
|
||||
}
|
||||
case NODE_VECTOR_MATH_DOT_PRODUCT: {
|
||||
static blender::fn::CustomMF_SI_SI_SO<float3, float3, float> fn{"Dot Product", float3::dot};
|
||||
static blender::fn::CustomMF_SI_SI_SO<float3, float3, float> fn{
|
||||
"Dot Product", [](float3 a, float3 b) { return dot(a, b); }};
|
||||
return fn;
|
||||
}
|
||||
|
||||
case NODE_VECTOR_MATH_DISTANCE: {
|
||||
static blender::fn::CustomMF_SI_SI_SO<float3, float3, float> fn{"Distance",
|
||||
float3::distance};
|
||||
static blender::fn::CustomMF_SI_SI_SO<float3, float3, float> fn{
|
||||
"Distance", [](float3 a, float3 b) { return distance(a, b); }};
|
||||
return fn;
|
||||
}
|
||||
case NODE_VECTOR_MATH_LENGTH: {
|
||||
static blender::fn::CustomMF_SI_SO<float3, float> fn{"Length",
|
||||
[](float3 a) { return a.length(); }};
|
||||
[](float3 a) { return length(a); }};
|
||||
return fn;
|
||||
}
|
||||
case NODE_VECTOR_MATH_SCALE: {
|
||||
@@ -223,7 +225,7 @@ static const blender::fn::MultiFunction &get_multi_function(
|
||||
}
|
||||
case NODE_VECTOR_MATH_NORMALIZE: {
|
||||
static blender::fn::CustomMF_SI_SO<float3, float3> fn{
|
||||
"Normalize", [](float3 a) { return a.normalized(); }};
|
||||
"Normalize", [](float3 a) { return normalized(a); }};
|
||||
return fn;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user