Dyntopo: code cleanup
This commit is contained in:
parent
71959181ad
commit
3d6ac0bd7b
Binary file not shown.
Binary file not shown.
|
@ -282,8 +282,7 @@ set(SRC
|
|||
intern/workspace.c
|
||||
intern/world.c
|
||||
intern/writeavi.c
|
||||
intern/closest_point_tri_sse.cc
|
||||
|
||||
|
||||
BKE_DerivedMesh.h
|
||||
BKE_action.h
|
||||
BKE_addon.h
|
||||
|
|
|
@ -1,398 +0,0 @@
|
|||
// see Fast Distance Queries for Triangles, Lines, and
|
||||
// Points using SSE Instructions
|
||||
// http://jcgt.org/published/0003/04/05/paper.pdf
|
||||
|
||||
typedef struct DistRet {
|
||||
float dist[4];
|
||||
} DistRet;
|
||||
|
||||
#if defined(__SSE2__) || defined(__SSE4__)
|
||||
# include <cstdint>
|
||||
# include <immintrin.h>
|
||||
# include <smmintrin.h>
|
||||
# include <xmmintrin.h>
|
||||
|
||||
struct sseb {
|
||||
// data
|
||||
union {
|
||||
__m128 m128;
|
||||
uint32_t v[4];
|
||||
};
|
||||
|
||||
sseb()
|
||||
{
|
||||
}
|
||||
|
||||
sseb(__m128 m)
|
||||
{
|
||||
m128 = m;
|
||||
}
|
||||
};
|
||||
|
||||
struct ssef {
|
||||
// data
|
||||
union {
|
||||
__m128 m128;
|
||||
float v[4];
|
||||
int i[4];
|
||||
};
|
||||
|
||||
ssef(float a, float b, float c, float d)
|
||||
{
|
||||
v[0] = a;
|
||||
v[1] = b;
|
||||
v[2] = c;
|
||||
v[3] = d;
|
||||
}
|
||||
|
||||
ssef()
|
||||
{
|
||||
}
|
||||
|
||||
ssef(__m128 f)
|
||||
{
|
||||
m128 = f;
|
||||
}
|
||||
|
||||
ssef(float f)
|
||||
{
|
||||
v[0] = v[1] = v[2] = v[3] = f;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(__SSE2__) && !defined(__SSE4__)
|
||||
|
||||
__m128 my_mm_blendv_ps(__m128 a, __m128 b, __m128 mask)
|
||||
{
|
||||
ssef fa(a);
|
||||
ssef fb(b);
|
||||
sseb fm(mask);
|
||||
|
||||
ssef ret;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (fm.v[i] & (1 << 31)) {
|
||||
ret.v[i] = fb.v[i];
|
||||
}
|
||||
else {
|
||||
ret.v[i] = fa.v[i];
|
||||
}
|
||||
}
|
||||
|
||||
return ret.m128;
|
||||
}
|
||||
# define _mm_blendv_ps my_mm_blendv_ps
|
||||
#endif
|
||||
|
||||
#ifdef __SSE2__
|
||||
|
||||
# include <array>
|
||||
# include <vector>
|
||||
|
||||
static inline struct sseb makeSSSEB(__m128 val)
|
||||
{
|
||||
sseb r;
|
||||
r.m128 = val;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// operations
|
||||
const sseb operator&(const sseb &a, const sseb &b)
|
||||
{
|
||||
return makeSSSEB(_mm_and_ps(a.m128, b.m128));
|
||||
}
|
||||
const sseb operator|(const sseb &a, const sseb &b)
|
||||
{
|
||||
return makeSSSEB(_mm_or_ps(a.m128, b.m128));
|
||||
}
|
||||
const sseb operator|=(const sseb &a, const sseb &b)
|
||||
{
|
||||
return a | b;
|
||||
}
|
||||
const sseb operator^(const sseb &a, const sseb &b)
|
||||
{
|
||||
return makeSSSEB(_mm_xor_ps(a.m128, b.m128));
|
||||
}
|
||||
bool all(const sseb &b)
|
||||
{
|
||||
return _mm_movemask_ps(b.m128) == 0xf;
|
||||
}
|
||||
bool any(const sseb &b)
|
||||
{
|
||||
return _mm_movemask_ps(b.m128) != 0x0;
|
||||
}
|
||||
bool none(const sseb &b)
|
||||
{
|
||||
return _mm_movemask_ps(b.m128) == 0x0;
|
||||
}
|
||||
static inline struct ssef makeSSSEF(__m128 val)
|
||||
{
|
||||
ssef r;
|
||||
r.m128 = val;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// operations
|
||||
const ssef operator+(const ssef &a, const ssef &b)
|
||||
{
|
||||
return makeSSSEF(_mm_add_ps(a.m128, b.m128));
|
||||
}
|
||||
const ssef operator-(const ssef &a, const ssef &b)
|
||||
{
|
||||
return makeSSSEF(_mm_sub_ps(a.m128, b.m128));
|
||||
}
|
||||
const ssef operator*(const ssef &a, const ssef &b)
|
||||
{
|
||||
return makeSSSEF(_mm_mul_ps(a.m128, b.m128));
|
||||
}
|
||||
const ssef operator/(const ssef &a, const ssef &b)
|
||||
{
|
||||
return makeSSSEF(_mm_div_ps(a.m128, b.m128));
|
||||
}
|
||||
|
||||
const sseb operator>=(const ssef &a, const ssef &b)
|
||||
{
|
||||
__m128 r1 = _mm_cmpgt_ss(a.m128, b.m128);
|
||||
__m128 r2 = _mm_cmpeq_ss(a.m128, b.m128);
|
||||
|
||||
return makeSSSEB(_mm_or_ps(r1, r2));
|
||||
}
|
||||
const sseb operator<=(const ssef &a, const ssef &b)
|
||||
{
|
||||
__m128 r1 = _mm_cmplt_ss(a.m128, b.m128);
|
||||
__m128 r2 = _mm_cmpeq_ss(a.m128, b.m128);
|
||||
|
||||
return makeSSSEB(_mm_or_ps(r1, r2));
|
||||
}
|
||||
|
||||
const sseb operator>(const ssef &a, const ssef &b)
|
||||
{
|
||||
return makeSSSEB(_mm_cmpgt_ss(a.m128, b.m128));
|
||||
}
|
||||
|
||||
const sseb operator<(const ssef &a, const ssef &b)
|
||||
{
|
||||
return makeSSSEB(_mm_cmplt_ss(a.m128, b.m128));
|
||||
}
|
||||
|
||||
const ssef min(const ssef &a, const ssef &b)
|
||||
{
|
||||
return makeSSSEF(_mm_min_ps(a.m128, b.m128));
|
||||
}
|
||||
const ssef sqr(const ssef &a)
|
||||
{
|
||||
return makeSSSEF(_mm_mul_ps(a.m128, a.m128));
|
||||
}
|
||||
const ssef sqrt(const ssef &a)
|
||||
{
|
||||
return makeSSSEF(_mm_sqrt_ps(a.m128));
|
||||
}
|
||||
const ssef select(const sseb &mask, const ssef &t, const ssef &f)
|
||||
{
|
||||
return makeSSSEF(_mm_blendv_ps(f.m128, t.m128, mask.m128));
|
||||
}
|
||||
|
||||
template<typename T> struct Vec3 {
|
||||
// data
|
||||
T x, y, z;
|
||||
|
||||
Vec3(T x, T y, T z) : x(x), y(y), z(z)
|
||||
{
|
||||
}
|
||||
|
||||
Vec3(T v) : x(v), y(v), z(v)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// operations
|
||||
template<typename T> Vec3<T> operator+(const Vec3<T> &a, const Vec3<T> &b)
|
||||
{
|
||||
return Vec3<T>(a.x + b.x, a.y + b.y, a.z + b.z);
|
||||
}
|
||||
template<typename T> Vec3<T> operator-(const Vec3<T> &a, const Vec3<T> &b)
|
||||
{
|
||||
return Vec3<T>(a.x - b.x, a.y - b.y, a.z - b.z);
|
||||
}
|
||||
template<typename T> Vec3<T> operator*(const Vec3<T> &a, const Vec3<T> &b)
|
||||
{
|
||||
return Vec3<T>(a.x * b.x, a.y * b.y, a.z * b.z);
|
||||
}
|
||||
template<typename T> Vec3<T> operator*(const T &a, const Vec3<T> &b)
|
||||
{
|
||||
return Vec3<T>(b.x * a, b.y * a, b.z * a);
|
||||
}
|
||||
template<typename T> Vec3<T> operator*(const Vec3<T> &b, const T &a)
|
||||
{
|
||||
return Vec3<T>(b.x * a, b.y * a, b.z * a);
|
||||
}
|
||||
|
||||
template<typename T> inline Vec3<T> rcp(const Vec3<T> &a)
|
||||
{
|
||||
return Vec3<T>(rcp(a.x), rcp(a.y), rcp(a.z));
|
||||
}
|
||||
template<typename T> inline Vec3<T> rsqrt(const Vec3<T> &a)
|
||||
{
|
||||
return Vec3<T>(rsqrt(a.x), rsqrt(a.y), rsqrt(a.z));
|
||||
}
|
||||
template<typename T> T dot(const Vec3<T> &a, const Vec3<T> &b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
}
|
||||
template<typename T> T length2b(const Vec3<T> &a)
|
||||
{
|
||||
return dot(a, a);
|
||||
}
|
||||
|
||||
typedef sseb simdBool;
|
||||
typedef ssef simdFloat;
|
||||
typedef Vec3<ssef> simdFloatVec;
|
||||
typedef std::array<simdFloatVec, 3> simdTriangle_type;
|
||||
typedef std::array<simdFloatVec, 2> simdLine_type;
|
||||
typedef simdFloatVec simdPoint_type;
|
||||
|
||||
static inline simdFloat length2(const simdFloatVec &a)
|
||||
{
|
||||
return a.x * a.x + a.y * a.y + a.z * a.z;
|
||||
}
|
||||
|
||||
static simdFloat zero = {0};
|
||||
static simdFloat one = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
|
||||
const simdFloatVec select(const sseb &mask, const simdFloatVec &t, const simdFloatVec &f)
|
||||
{
|
||||
simdFloatVec r2(select(mask, t.x, f.x), select(mask, t.y, f.y), select(mask, t.z, f.z));
|
||||
|
||||
return r2;
|
||||
}
|
||||
|
||||
template<typename T> T clamp(const T &x, const T &lower, const T &upper)
|
||||
{
|
||||
return max(lower, min(x, upper));
|
||||
}
|
||||
|
||||
const simdFloat simdTriPoint2(simdFloatVec &oTriPoint,
|
||||
const simdTriangle_type &iTri,
|
||||
const simdPoint_type &iPoint)
|
||||
{
|
||||
const simdFloatVec ab = iTri[1] - iTri[0];
|
||||
const simdFloatVec ac = iTri[2] - iTri[0];
|
||||
const simdFloatVec ap = iPoint - iTri[0];
|
||||
const simdFloat d1 = dot(ab, ap);
|
||||
const simdFloat d2 = dot(ac, ap);
|
||||
const simdBool mask1 = (d1 <= simdFloat(zero)) & (d2 <= simdFloat(zero));
|
||||
oTriPoint = iTri[0];
|
||||
simdBool exit(mask1);
|
||||
if (all(exit))
|
||||
return length2(oTriPoint - iPoint);
|
||||
|
||||
const simdFloatVec bp = iPoint - iTri[1];
|
||||
const simdFloat d3 = dot(ab, bp);
|
||||
const simdFloat d4 = dot(ac, bp);
|
||||
const simdBool mask2 = (d3 >= simdFloat(zero)) & (d4 <= d3);
|
||||
// Closest point is the point iTri[1]. Update if necessary.
|
||||
oTriPoint = select(exit, oTriPoint, select(mask2, iTri[1], oTriPoint));
|
||||
exit = exit | mask2;
|
||||
if (all(exit))
|
||||
return length2(oTriPoint - iPoint);
|
||||
|
||||
const simdFloatVec cp = iPoint - iTri[2];
|
||||
const simdFloat d5 = dot(ab, cp);
|
||||
const simdFloat d6 = dot(ac, cp);
|
||||
const simdBool mask3 = (d6 >= simdFloat(zero)) & (d5 <= d6);
|
||||
// Closest point is the point iTri[2]. Update if necessary.
|
||||
oTriPoint = select(exit, oTriPoint, select(mask3, iTri[2], oTriPoint));
|
||||
exit |= mask3;
|
||||
if (all(exit))
|
||||
return length2(oTriPoint - iPoint);
|
||||
|
||||
const simdFloat vc = d1 * d4 - d3 * d2;
|
||||
const simdBool mask4 = (vc <= simdFloat(zero)) & (d1 >= simdFloat(zero)) &
|
||||
(d3 <= simdFloat(zero));
|
||||
const simdFloat v1 = d1 / (d1 - d3);
|
||||
const simdFloatVec answer1 = iTri[0] + v1 * ab;
|
||||
// Closest point is on the line ab. Update if necessary.
|
||||
oTriPoint = select(exit, oTriPoint, select(mask4, answer1, oTriPoint));
|
||||
exit |= mask4;
|
||||
if (all(exit))
|
||||
return length2(oTriPoint - iPoint);
|
||||
|
||||
const simdFloat vb = d5 * d2 - d1 * d6;
|
||||
const simdBool mask5 = (vb <= simdFloat(zero)) & (d2 >= simdFloat(zero)) &
|
||||
(d6 <= simdFloat(zero));
|
||||
const simdFloat w1 = d2 / (d2 - d6);
|
||||
const simdFloatVec answer2 = iTri[0] + w1 * ac;
|
||||
// Closest point is on the line ac. Update if necessary.
|
||||
oTriPoint = select(exit, oTriPoint, select(mask5, answer2, oTriPoint));
|
||||
exit |= mask5;
|
||||
if (all(exit))
|
||||
return length2(oTriPoint - iPoint);
|
||||
|
||||
const simdFloat va = d3 * d6 - d5 * d4;
|
||||
const simdBool mask6 = (va <= simdFloat(zero)) & ((d4 - d3) >= simdFloat(zero)) &
|
||||
((d5 - d6) >= simdFloat(zero));
|
||||
simdFloat w2 = (d4 - d3) / ((d4 - d3) + (d5 - d6));
|
||||
const simdFloatVec answer3 = iTri[1] + w2 * (iTri[2] - iTri[1]);
|
||||
// Closest point is on the line bc. Update if necessary.
|
||||
oTriPoint = select(exit, oTriPoint, select(mask6, answer3, oTriPoint));
|
||||
exit |= mask6;
|
||||
if (all(exit))
|
||||
return length2(oTriPoint - iPoint);
|
||||
|
||||
const simdFloat denom = simdFloat(one) / (va + vb + vc);
|
||||
const simdFloat v2 = vb * denom;
|
||||
const simdFloat w3 = vc * denom;
|
||||
const simdFloatVec answer4 = iTri[0] + ab * v2 + ac * w3;
|
||||
const simdBool mask7 = length2(answer4 - iPoint) < length2(oTriPoint - iPoint);
|
||||
// Closest point is inside triangle. Update if necessary.
|
||||
oTriPoint = select(exit, oTriPoint, select(mask7, answer4, oTriPoint));
|
||||
return length2(oTriPoint - iPoint);
|
||||
}
|
||||
|
||||
extern "C" struct DistRet dist_to_tri_sphere_fast_4(
|
||||
float p[3], float v1[4][3], float v2[4][3], float v3[4][3], float n[4][3])
|
||||
{
|
||||
simdFloatVec mp((simdFloat(p[0]), simdFloat(p[1]), simdFloat(p[2])));
|
||||
simdFloatVec t1(simdFloat(v1[0][0], v1[1][0], v1[2][0], v1[3][0]),
|
||||
simdFloat(v1[0][1], v1[1][1], v1[2][1], v1[3][1]),
|
||||
simdFloat(v1[0][2], v1[1][2], v1[2][2], v1[3][2]));
|
||||
simdFloatVec t2(simdFloat(v2[0][0], v2[1][0], v2[2][0], v2[3][0]),
|
||||
simdFloat(v2[0][1], v2[1][1], v2[2][1], v2[3][1]),
|
||||
simdFloat(v2[0][2], v2[1][2], v2[2][2], v2[3][2]));
|
||||
simdFloatVec t3(simdFloat(v3[0][0], v3[1][0], v3[2][0], v3[3][0]),
|
||||
simdFloat(v3[0][1], v3[1][1], v3[2][1], v3[3][1]),
|
||||
simdFloat(v3[0][2], v3[1][2], v3[2][2], v3[3][2]));
|
||||
|
||||
simdTriangle_type tri = {t1, t2, t3};
|
||||
|
||||
struct DistRet ret;
|
||||
|
||||
ssef f = simdTriPoint2(mp, tri, mp);
|
||||
|
||||
ret.dist[0] = f.v[0];
|
||||
ret.dist[1] = f.v[1];
|
||||
ret.dist[2] = f.v[2];
|
||||
ret.dist[3] = f.v[3];
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#include "BLI_math.h"
|
||||
|
||||
extern "C" struct DistRet dist_to_tri_sphere_fast_4(
|
||||
float p[3], float v1[4][3], float v2[4][3], float v3[4][3], float n[4][3])
|
||||
{
|
||||
DistRet ret;
|
||||
float r[3];
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
closest_on_tri_to_point_v3(r, p, v1[i], v2[i], v3[i]);
|
||||
ret.dist[i] = len_squared_v3v3(r, p);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1445,95 +1445,10 @@ static bool edge_queue_vert_in_sphere(const EdgeQueue *q, BMVert *v)
|
|||
return len_squared_v3v3(q->center, v->co) <= q->radius_squared;
|
||||
}
|
||||
|
||||
/* reduce script
|
||||
|
||||
on factor;
|
||||
|
||||
ax := 0;
|
||||
ay := 0;
|
||||
|
||||
e1x := bx - ax;
|
||||
e1y := by - ay;
|
||||
e2x := cx - bx;
|
||||
e2y := cy - by;
|
||||
e3x := ax - cx;
|
||||
e3y := ay - cy;
|
||||
|
||||
l1 := (e1x**2 + e1y**2)**0.5;
|
||||
l2 := (e2x**2 + e2y**2)**0.5;
|
||||
l3 := (e3x**2 + e3y**2)**0.5;
|
||||
|
||||
load_package "avector";
|
||||
|
||||
e1 := avec(e1x / l1, e1y / l1, 0.0);
|
||||
e2 := avec(e2x / l2, e2y / l2, 0.0);
|
||||
e3 := avec(e3x / l3, e3y / l3, 0.0);
|
||||
|
||||
ax := 0;
|
||||
ay := 0;
|
||||
|
||||
d1 := x1*e1[1] - y1*e1[0];
|
||||
d2 := x1*e2[1] - y1*e2[0];
|
||||
d3 := x1*e3[1] - y1*e3[0];
|
||||
|
||||
d1 := d1**2;
|
||||
d2 := d2**2;
|
||||
d3 := d3**2;
|
||||
|
||||
on fort;
|
||||
d1;
|
||||
d2;
|
||||
d3;
|
||||
off fort;
|
||||
|
||||
fdis := (sqrt(dis)/nz)**2 + planedis**2;
|
||||
*/
|
||||
|
||||
/*
|
||||
static inline float dot_v3v3(const float a[3], const float b[3])
|
||||
{
|
||||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
||||
}
|
||||
|
||||
static inline void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
|
||||
{
|
||||
r[0] = a[0] - b[0];
|
||||
r[1] = a[1] - b[1];
|
||||
r[2] = a[2] - b[2];
|
||||
}
|
||||
|
||||
|
||||
static inline void add_v3_v3v3(float r[3], const float a[3], const float b[3])
|
||||
{
|
||||
r[0] = a[0] + b[0];
|
||||
r[1] = a[1] + b[1];
|
||||
r[2] = a[2] + b[2];
|
||||
}
|
||||
|
||||
static inline void add_v3_v3(float r[3], const float a[3])
|
||||
{
|
||||
r[0] += a[0];
|
||||
r[1] += a[1];
|
||||
r[2] += a[2];
|
||||
}
|
||||
|
||||
static inline void mul_v3_fl(float r[3], float f)
|
||||
{
|
||||
r[0] *= f;
|
||||
r[1] *= f;
|
||||
r[2] *= f;
|
||||
}
|
||||
|
||||
|
||||
static inline float len_squared_v3v3(const float a[3], const float b[3])
|
||||
{
|
||||
float d[3];
|
||||
|
||||
sub_v3_v3v3(d, b, a);
|
||||
return dot_v3v3(d, d);
|
||||
}
|
||||
*/
|
||||
|
||||
Profiling revealed the accurate distance to tri in blenlib was too slow,
|
||||
so we use a simpler version here
|
||||
*/
|
||||
static float dist_to_tri_sphere_simple(
|
||||
float p[3], float v1[3], float v2[3], float v3[3], float n[3])
|
||||
{
|
||||
|
@ -1563,205 +1478,6 @@ static float dist_to_tri_sphere_simple(
|
|||
return dis;
|
||||
}
|
||||
|
||||
//#include <cmath>
|
||||
|
||||
// int mask = (nx < ny) | ((nx < nz) << 1) | ((ny < nz) << 2) | ((nx < nz) << 3);
|
||||
|
||||
/*
|
||||
let axis1, axis2, axis3;
|
||||
|
||||
let tabx = new Array(8);
|
||||
let taby = new Array(8);
|
||||
let tabz = new Array(8);
|
||||
|
||||
let b1 = 1;//nx > ny;
|
||||
let b2 = 2;//nx > nz;
|
||||
let b3 = 4;//ny > nz;
|
||||
|
||||
m1 = 1 | 2;
|
||||
m2 = 4;
|
||||
|
||||
tabx[m1] = 1;
|
||||
taby[m1] = 2;
|
||||
tabz[m1] = 0;
|
||||
|
||||
tabx[m2] = 0;
|
||||
taby[m2] = 2;
|
||||
tabz[m2] = 1;
|
||||
|
||||
for (let i=0; i<tabx.length; i++) {
|
||||
if (tabx[i] === undefined) {
|
||||
tabx[i] = 0;
|
||||
taby[i] = 1;
|
||||
tabz[i] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
function format(tab) {
|
||||
let s = '';
|
||||
for (let i=0; i<tab.length; i++) {
|
||||
if (i > 0) {
|
||||
s += ', '
|
||||
}
|
||||
|
||||
s += tab[i];
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
let buf = `
|
||||
static int tritablex[${tabx.length}] = {${format(tabx)}};
|
||||
static int tritabley[${taby.length}] = {${format(taby)}};
|
||||
static int tritablez[${tabz.length}] = {${format(tabz)}};
|
||||
`;
|
||||
console.log(buf);
|
||||
*/
|
||||
|
||||
static int tritablex[8] = {0, 0, 0, 1, 0, 0, 0, 0};
|
||||
static int tritabley[8] = {1, 1, 1, 2, 2, 1, 1, 1};
|
||||
static int tritablez[8] = {2, 2, 2, 0, 1, 2, 2, 2};
|
||||
|
||||
float dist_to_tri_sphere(float p[3], float v1[3], float v2[3], float v3[3], float n[3])
|
||||
{
|
||||
|
||||
// find projection axis;
|
||||
int axis1, axis2, axis3;
|
||||
|
||||
// clang optimizes fabsf better
|
||||
double nx = fabsf(n[0]); // n[0] < 0.0 ? -n[0] : n[0];
|
||||
double ny = fabsf(n[1]); // n[1] < 0.0 ? -n[1] : n[1];
|
||||
double nz = fabsf(n[2]); // n[2] < 0.0 ? -n[2] : n[2];
|
||||
|
||||
const double feps = 0.000001;
|
||||
|
||||
#if 0
|
||||
if (nx > ny && nx > nz) {
|
||||
axis1 = 1;
|
||||
axis2 = 2;
|
||||
axis3 = 0;
|
||||
}
|
||||
else if (ny > nx && ny > nz) {
|
||||
axis1 = 0;
|
||||
axis2 = 2;
|
||||
axis3 = 1;
|
||||
}
|
||||
else {
|
||||
axis1 = 0;
|
||||
axis2 = 1;
|
||||
axis3 = 2;
|
||||
}
|
||||
#else
|
||||
int mask = 0;
|
||||
|
||||
//
|
||||
// let b1 = 1; // nx > ny;
|
||||
// let b2 = 2; // nx > nz;
|
||||
// let b3 = 4; // ny > nz;
|
||||
|
||||
mask = mask | (nx > ny);
|
||||
mask = mask | ((nx > nz) << 1);
|
||||
mask = mask | ((ny > nz) << 2);
|
||||
|
||||
axis1 = tritablex[mask];
|
||||
axis2 = tritabley[mask];
|
||||
axis3 = tritablez[mask];
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
double planedis = (p[0] - v1[0]) * n[0] + (p[1] - v1[1]) * n[1] + (p[2] - v1[2]) * n[2];
|
||||
planedis = planedis < 0.0 ? -planedis : planedis;
|
||||
|
||||
double ax = v1[axis1], ay = v1[axis2];
|
||||
double bx = v2[axis1] - ax, by = v2[axis2] - ay;
|
||||
double cx = v3[axis1] - ax, cy = v3[axis2] - ay;
|
||||
double bx2 = bx * bx, by2 = by * by, cx2 = cx * cx, cy2 = cy * cy;
|
||||
|
||||
double x1 = p[axis1] - ax;
|
||||
double y1 = p[axis2] - ay;
|
||||
|
||||
bool s1 = x1 * by - y1 * bx < 0.0;
|
||||
bool s2 = x1 * (cy - by) - y1 * (cx - bx) < 0.0;
|
||||
bool s3 = x1 * -cy - y1 * -cx < 0.0;
|
||||
|
||||
int side = 0;
|
||||
|
||||
mask = s1 | (s2 << 1) | (s3 << 2);
|
||||
if (mask == 0.0) {
|
||||
return planedis * planedis;
|
||||
}
|
||||
|
||||
double d1, d2, d3, div;
|
||||
|
||||
/*
|
||||
//\ 3|
|
||||
// \ |
|
||||
// b
|
||||
// | \
|
||||
// 1 | \ 2
|
||||
// | 0 \
|
||||
// ___a_______c___
|
||||
// 5 | 4 \ 6
|
||||
*/
|
||||
|
||||
double dis = 0.0;
|
||||
switch (mask) {
|
||||
case 1:
|
||||
div = (bx2 + by2);
|
||||
|
||||
if (div > feps) {
|
||||
d1 = (bx * y1 - by * x1);
|
||||
d1 = (d1 * d1) / div;
|
||||
}
|
||||
else {
|
||||
d1 = x1 * x1 + y1 * y1;
|
||||
}
|
||||
|
||||
dis = d1;
|
||||
break;
|
||||
case 3:
|
||||
dis = ((x1 - bx) * (x1 - bx) + (y1 - by) * (y1 - by));
|
||||
break;
|
||||
case 2:
|
||||
div = ((bx - cx) * (bx - cx) + (by - cy) * (by - cy));
|
||||
if (div > feps) {
|
||||
d2 = ((bx - cx) * y1 - (by - cy) * x1);
|
||||
d2 = (d2 * d2) / div;
|
||||
}
|
||||
else {
|
||||
d2 = (x1 - bx) * (x1 - bx) + (y1 - by) * (y1 - by);
|
||||
}
|
||||
dis = d2;
|
||||
break;
|
||||
case 6:
|
||||
dis = (x1 - cx) * (x1 - cx) + (y1 - cy) * (y1 - cy);
|
||||
break;
|
||||
case 4:
|
||||
div = (cx2 + cy2);
|
||||
|
||||
if (div > feps) {
|
||||
d3 = (cx * y1 - cy * x1);
|
||||
d3 = (d3 * d3) / div;
|
||||
}
|
||||
else {
|
||||
d3 = (x1 - cx) * (x1 - cx) + (y1 - cy) * (y1 - cy);
|
||||
}
|
||||
|
||||
dis = d3;
|
||||
break;
|
||||
case 5:
|
||||
dis = x1 * x1 + y1 * y1;
|
||||
break;
|
||||
}
|
||||
|
||||
nz = n[axis3] < 0.0 ? -n[axis3] : n[axis3];
|
||||
|
||||
return (float)(dis + nz * nz * planedis * planedis) / (nz * nz);
|
||||
#else
|
||||
return (float)axis1 + (float)axis2 + (float)axis3;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
|
||||
{
|
||||
float c[3];
|
||||
|
@ -1777,37 +1493,7 @@ static bool edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
|
|||
(float *)l->prev->v->co,
|
||||
(float *)f->no);
|
||||
|
||||
// closest_on_tri_to_point_v3(c, co, v1, v2, v3);
|
||||
|
||||
// float dis2 = len_squared_v3v3(q->center, c);
|
||||
// float dis3 = sqrtf(dis2);
|
||||
|
||||
return dis <= q->radius_squared;
|
||||
|
||||
/* Get closest point in triangle to sphere center */
|
||||
#if 0
|
||||
/*
|
||||
closest_on_tri_to_point_v3 is being slow
|
||||
*/
|
||||
|
||||
float mindis = 1e17;
|
||||
float dis;
|
||||
copy_v3_v3(c, q->center);
|
||||
|
||||
for (int i=0; i<3; i++) {
|
||||
dis = len_squared_v3v3(v_tri[i]->co, c);
|
||||
mindis = MIN2(mindis, dis);
|
||||
|
||||
dis = dist_squared_to_line_segment_v3(c, v_tri[i]->co, v_tri[(i+1)%3]->co);
|
||||
mindis = MIN2(mindis, dis);
|
||||
}
|
||||
return mindis <= q->radius_squared;
|
||||
#else
|
||||
closest_on_tri_to_point_v3(c, q->center, l->v->co, l->next->v->co, l->prev->v->co);
|
||||
|
||||
/* Check if triangle intersects the sphere */
|
||||
return len_squared_v3v3(q->center, c) <= q->radius_squared;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool edge_queue_tri_in_circle(const EdgeQueue *q, BMFace *f)
|
||||
|
|
|
@ -360,9 +360,9 @@ static void eval_displacement(SubdivDisplacement *displacement,
|
|||
BKE_multires_construct_tangent_matrix(tangent_matrix, dPdu, dPdv, corner_of_quad);
|
||||
mul_v3_m3v3(r_D, tangent_matrix, tangent_D);
|
||||
/* For the boundary points of grid average two (or all) neighbor grids. */
|
||||
//XXX
|
||||
//const int corner = displacement_get_face_corner(data, ptex_face_index, u, v);
|
||||
//average_displacement(displacement, average_with, ptex_face_index, corner, grid_u, grid_v, r_D);
|
||||
|
||||
const int corner = displacement_get_face_corner(data, ptex_face_index, u, v);
|
||||
average_displacement(displacement, average_with, ptex_face_index, corner, grid_u, grid_v, r_D);
|
||||
}
|
||||
|
||||
static void free_displacement(SubdivDisplacement *displacement)
|
||||
|
|
|
@ -755,15 +755,18 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES
|
|||
brush.sculpt.mask
|
||||
brush.sculpt.multiplane_scrape
|
||||
brush.sculpt.nudge
|
||||
brush.sculpt.paint
|
||||
brush.sculpt.pinch
|
||||
brush.sculpt.pose
|
||||
brush.sculpt.rotate
|
||||
brush.sculpt.scrape
|
||||
brush.sculpt.simplify
|
||||
brush.sculpt.smear
|
||||
brush.sculpt.smooth
|
||||
brush.sculpt.snake_hook
|
||||
brush.sculpt.thumb
|
||||
brush.sculpt.topology
|
||||
brush.sculpt.vcol_boundary
|
||||
brush.uv_sculpt.grab
|
||||
brush.uv_sculpt.pinch
|
||||
brush.uv_sculpt.relax
|
||||
|
|
|
@ -921,6 +921,7 @@ DEF_ICON_COLOR(BRUSH_THUMB)
|
|||
DEF_ICON_COLOR(BRUSH_ROTATE)
|
||||
DEF_ICON_COLOR(BRUSH_VCOL_BOUNDARY)
|
||||
DEF_ICON_COLOR(BRUSH_PAINT)
|
||||
DEF_ICON_COLOR(BRUSH_SCULPT_SMEAR)
|
||||
|
||||
/* grease pencil sculpt */
|
||||
DEF_ICON_COLOR(GPBRUSH_SMOOTH)
|
||||
|
|
|
@ -161,10 +161,10 @@ static SculptVertRef sculpt_boundary_get_closest_boundary_vertex(
|
|||
static int BOUNDARY_INDICES_BLOCK_SIZE = 300;
|
||||
|
||||
static void sculpt_boundary_index_add(SculptSession *ss,
|
||||
SculptBoundary *boundary,
|
||||
const SculptVertRef new_index,
|
||||
const float distance,
|
||||
GSet *included_vertices)
|
||||
SculptBoundary *boundary,
|
||||
const SculptVertRef new_index,
|
||||
const float distance,
|
||||
GSet *included_vertices)
|
||||
{
|
||||
|
||||
boundary->vertices[boundary->num_vertices] = new_index;
|
||||
|
@ -346,9 +346,9 @@ static void sculpt_boundary_indices_init(SculptSession *ss,
|
|||
* the closest one.
|
||||
*/
|
||||
static void sculpt_boundary_edit_data_init(SculptSession *ss,
|
||||
SculptBoundary *boundary,
|
||||
const SculptVertRef initial_vertex,
|
||||
const float radius)
|
||||
SculptBoundary *boundary,
|
||||
const SculptVertRef initial_vertex,
|
||||
const float radius)
|
||||
{
|
||||
const int totvert = SCULPT_vertex_count_get(ss);
|
||||
|
||||
|
@ -559,7 +559,7 @@ SculptBoundary *SCULPT_boundary_data_init(Object *object,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// XXX
|
||||
// XXX force update of BMVert->head.index
|
||||
if (ss->bm) {
|
||||
ss->bm->elem_index_dirty |= BM_VERT;
|
||||
}
|
||||
|
@ -648,24 +648,6 @@ static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *bo
|
|||
SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
|
||||
SCULPT_vertex_co_get(ss, vertex));
|
||||
|
||||
#if 0
|
||||
/*strategy to increase accuracy for non-quad topologies:
|
||||
use principle curvature direction. Since SCULPT_curvature_dir_get
|
||||
can also be somewhat noisy we average it with dir.
|
||||
*/
|
||||
|
||||
float cdir[3];
|
||||
SCULPT_curvature_dir_get(ss, vertex, cdir);
|
||||
normalize_v3(dir);
|
||||
normalize_v3(cdir);
|
||||
|
||||
if (dot_v3v3(dir, cdir) < 0.0f) {
|
||||
negate_v3(cdir);
|
||||
}
|
||||
|
||||
add_v3_v3(dir, cdir);
|
||||
#endif
|
||||
|
||||
cross_v3_v3v3(boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex_i],
|
||||
dir,
|
||||
normal);
|
||||
|
@ -772,10 +754,10 @@ static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *bo
|
|||
SculptVertRef vertex = BKE_pbvh_table_index_to_vertex(ss->pbvh, i);
|
||||
const float *co = SCULPT_vertex_co_get(ss, vertex);
|
||||
|
||||
//boundary->bend.pivot_positions[i][0] = co[0];
|
||||
//boundary->bend.pivot_positions[i][1] = co[1];
|
||||
//boundary->bend.pivot_positions[i][2] = co[2];
|
||||
//boundary->bend.pivot_positions[i][3] = 0.0f;
|
||||
// boundary->bend.pivot_positions[i][0] = co[0];
|
||||
// boundary->bend.pivot_positions[i][1] = co[1];
|
||||
// boundary->bend.pivot_positions[i][2] = co[2];
|
||||
// boundary->bend.pivot_positions[i][3] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ const EnumPropertyItem rna_enum_brush_sculpt_tool_items[] = {
|
|||
{SCULPT_TOOL_DISPLACEMENT_ERASER, "DISPLACEMENT_ERASER", ICON_BRUSH_SCULPT_DRAW, "Multires Displacement Eraser", ""},
|
||||
{SCULPT_TOOL_DISPLACEMENT_SMEAR, "DISPLACEMENT_SMEAR", ICON_BRUSH_SCULPT_DRAW, "Multires Displacement Smear", ""},
|
||||
{SCULPT_TOOL_PAINT, "PAINT", ICON_BRUSH_PAINT, "Paint", ""},
|
||||
{SCULPT_TOOL_SMEAR, "SMEAR", ICON_BRUSH_SCULPT_DRAW, "Smear", ""},
|
||||
{SCULPT_TOOL_SMEAR, "SMEAR", ICON_BRUSH_SCULPT_SMEAR, "Smear", ""},
|
||||
{SCULPT_TOOL_DRAW_FACE_SETS, "DRAW_FACE_SETS", ICON_BRUSH_MASK, "Draw Face Sets", ""},
|
||||
{SCULPT_TOOL_VCOL_BOUNDARY, "VCOL_BOUNDARY", ICON_BRUSH_VCOL_BOUNDARY, "Sharpen Color Boundary", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
|
|
Loading…
Reference in New Issue