Refactor SKdNode::FindEdgeOn.
Extract output parameters into a separate structure.pull/4/head
parent
7c60be8203
commit
7e6a11c958
52
src/mesh.cpp
52
src/mesh.cpp
|
@ -782,16 +782,15 @@ void SKdNode::OcclusionTestLine(SEdge orig, SEdgeList *sel, int cnt) {
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Search the mesh for a triangle with an edge from b to a (i.e., the mate
|
// Search the mesh for a triangle with an edge from b to a (i.e., the mate
|
||||||
// for the edge from a to b), and increment *n each time that we find one.
|
// for the edge from a to b), and increment info->count each time that we
|
||||||
// If a triangle is found, then report whether it is front- or back-facing
|
// find one. If a triangle is found, then report whether it is front- or
|
||||||
// using *fwd. And regardless of whether a mate is found, report whether
|
// back-facing using info->frontFacing. And regardless of whether a mate is
|
||||||
// the edge intersects the mesh with *inter; if coplanarIsInter then we
|
// found, report whether the edge intersects the mesh with info->intersectsMesh;
|
||||||
// count the edge as intersecting if it's coplanar with a triangle in the
|
// if coplanarIsInter then we count the edge as intersecting if it's coplanar
|
||||||
// mesh, otherwise not.
|
// with a triangle in the mesh, otherwise not.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void SKdNode::FindEdgeOn(Vector a, Vector b, int *n, int cnt,
|
void SKdNode::FindEdgeOn(Vector a, Vector b, int cnt, bool coplanarIsInter,
|
||||||
bool coplanarIsInter, bool *inter, bool *fwd,
|
EdgeOnInfo *info)
|
||||||
uint32_t *face)
|
|
||||||
{
|
{
|
||||||
if(gt && lt) {
|
if(gt && lt) {
|
||||||
double ac = a.Element(which),
|
double ac = a.Element(which),
|
||||||
|
@ -799,12 +798,12 @@ void SKdNode::FindEdgeOn(Vector a, Vector b, int *n, int cnt,
|
||||||
if(ac < c + KDTREE_EPS ||
|
if(ac < c + KDTREE_EPS ||
|
||||||
bc < c + KDTREE_EPS)
|
bc < c + KDTREE_EPS)
|
||||||
{
|
{
|
||||||
lt->FindEdgeOn(a, b, n, cnt, coplanarIsInter, inter, fwd, face);
|
lt->FindEdgeOn(a, b, cnt, coplanarIsInter, info);
|
||||||
}
|
}
|
||||||
if(ac > c - KDTREE_EPS ||
|
if(ac > c - KDTREE_EPS ||
|
||||||
bc > c - KDTREE_EPS)
|
bc > c - KDTREE_EPS)
|
||||||
{
|
{
|
||||||
gt->FindEdgeOn(a, b, n, cnt, coplanarIsInter, inter, fwd, face);
|
gt->FindEdgeOn(a, b, cnt, coplanarIsInter, info);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -822,15 +821,15 @@ void SKdNode::FindEdgeOn(Vector a, Vector b, int *n, int cnt,
|
||||||
(a.Equals(tr->c) && b.Equals(tr->b)) ||
|
(a.Equals(tr->c) && b.Equals(tr->b)) ||
|
||||||
(a.Equals(tr->a) && b.Equals(tr->c)))
|
(a.Equals(tr->a) && b.Equals(tr->c)))
|
||||||
{
|
{
|
||||||
(*n)++;
|
info->count++;
|
||||||
// Record whether this triangle is front- or back-facing.
|
// Record whether this triangle is front- or back-facing.
|
||||||
if(tr->Normal().z > LENGTH_EPS) {
|
if(tr->Normal().z > LENGTH_EPS) {
|
||||||
*fwd = true;
|
info->frontFacing = true;
|
||||||
} else {
|
} else {
|
||||||
*fwd = false;
|
info->frontFacing = false;
|
||||||
}
|
}
|
||||||
// And record the triangle's face
|
// And record the triangle's face
|
||||||
*face = tr->meta.face;
|
info->face = tr->meta.face;
|
||||||
} else if(((a.Equals(tr->a) && b.Equals(tr->b)) ||
|
} else if(((a.Equals(tr->a) && b.Equals(tr->b)) ||
|
||||||
(a.Equals(tr->b) && b.Equals(tr->c)) ||
|
(a.Equals(tr->b) && b.Equals(tr->c)) ||
|
||||||
(a.Equals(tr->c) && b.Equals(tr->a))))
|
(a.Equals(tr->c) && b.Equals(tr->a))))
|
||||||
|
@ -852,7 +851,7 @@ void SKdNode::FindEdgeOn(Vector a, Vector b, int *n, int cnt,
|
||||||
// it crosses inside the triangle.
|
// it crosses inside the triangle.
|
||||||
if(tr->ContainsPointProjd(b.Minus(a), a)) {
|
if(tr->ContainsPointProjd(b.Minus(a), a)) {
|
||||||
if(coplanarIsInter) {
|
if(coplanarIsInter) {
|
||||||
*inter = true;
|
info->intersectsMesh = true;
|
||||||
} else {
|
} else {
|
||||||
Vector p = Vector::AtIntersectionOfPlaneAndLine(
|
Vector p = Vector::AtIntersectionOfPlaneAndLine(
|
||||||
n, d, a, b, NULL);
|
n, d, a, b, NULL);
|
||||||
|
@ -871,7 +870,7 @@ void SKdNode::FindEdgeOn(Vector a, Vector b, int *n, int cnt,
|
||||||
// the coplanar triangle's neighbours, which we
|
// the coplanar triangle's neighbours, which we
|
||||||
// will intersect on their edges.
|
// will intersect on their edges.
|
||||||
} else {
|
} else {
|
||||||
*inter = true;
|
info->intersectsMesh = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -912,26 +911,23 @@ void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, int how,
|
||||||
Vector a = (j == 0) ? tr->a : ((j == 1) ? tr->b : tr->c);
|
Vector a = (j == 0) ? tr->a : ((j == 1) ? tr->b : tr->c);
|
||||||
Vector b = (j == 0) ? tr->b : ((j == 1) ? tr->c : tr->a);
|
Vector b = (j == 0) ? tr->b : ((j == 1) ? tr->c : tr->a);
|
||||||
|
|
||||||
int n = 0;
|
SKdNode::EdgeOnInfo info = {};
|
||||||
bool thisIntersects = false, fwd;
|
FindEdgeOn(a, b, cnt, coplanarIsInter, &info);
|
||||||
uint32_t face;
|
|
||||||
FindEdgeOn(a, b, &n, cnt, coplanarIsInter,
|
|
||||||
&thisIntersects, &fwd, &face);
|
|
||||||
|
|
||||||
switch(how) {
|
switch(how) {
|
||||||
case NAKED_OR_SELF_INTER_EDGES:
|
case NAKED_OR_SELF_INTER_EDGES:
|
||||||
if(n != 1) {
|
if(info.count != 1) {
|
||||||
sel->AddEdge(a, b);
|
sel->AddEdge(a, b);
|
||||||
if(leaky) *leaky = true;
|
if(leaky) *leaky = true;
|
||||||
}
|
}
|
||||||
if(thisIntersects) {
|
if(info.intersectsMesh) {
|
||||||
sel->AddEdge(a, b);
|
sel->AddEdge(a, b);
|
||||||
if(inter) *inter = true;
|
if(inter) *inter = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SELF_INTER_EDGES:
|
case SELF_INTER_EDGES:
|
||||||
if(thisIntersects) {
|
if(info.intersectsMesh) {
|
||||||
sel->AddEdge(a, b);
|
sel->AddEdge(a, b);
|
||||||
if(inter) *inter = true;
|
if(inter) *inter = true;
|
||||||
}
|
}
|
||||||
|
@ -939,8 +935,8 @@ void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, int how,
|
||||||
|
|
||||||
case TURNING_EDGES:
|
case TURNING_EDGES:
|
||||||
if((tr->Normal().z < LENGTH_EPS) &&
|
if((tr->Normal().z < LENGTH_EPS) &&
|
||||||
(n == 1) &&
|
(info.count == 1) &&
|
||||||
fwd)
|
info.frontFacing)
|
||||||
{
|
{
|
||||||
// This triangle is back-facing (or on edge), and
|
// This triangle is back-facing (or on edge), and
|
||||||
// this edge has exactly one mate, and that mate is
|
// this edge has exactly one mate, and that mate is
|
||||||
|
@ -950,7 +946,7 @@ void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, int how,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EMPHASIZED_EDGES:
|
case EMPHASIZED_EDGES:
|
||||||
if(tr->meta.face != face && n == 1) {
|
if(tr->meta.face != info.face && info.count == 1) {
|
||||||
// The two triangles that join at this edge come from
|
// The two triangles that join at this edge come from
|
||||||
// different faces; either really different faces,
|
// different faces; either really different faces,
|
||||||
// or one is from a face and the other is zero (i.e.,
|
// or one is from a face and the other is zero (i.e.,
|
||||||
|
|
|
@ -269,6 +269,13 @@ public:
|
||||||
|
|
||||||
class SKdNode {
|
class SKdNode {
|
||||||
public:
|
public:
|
||||||
|
struct EdgeOnInfo {
|
||||||
|
int count;
|
||||||
|
bool frontFacing;
|
||||||
|
bool intersectsMesh;
|
||||||
|
uint32_t face;
|
||||||
|
};
|
||||||
|
|
||||||
int which; // whether c is x, y, or z
|
int which; // whether c is x, y, or z
|
||||||
double c;
|
double c;
|
||||||
|
|
||||||
|
@ -285,9 +292,7 @@ public:
|
||||||
void MakeMeshInto(SMesh *m);
|
void MakeMeshInto(SMesh *m);
|
||||||
void ClearTags(void);
|
void ClearTags(void);
|
||||||
|
|
||||||
void FindEdgeOn(Vector a, Vector b, int *n, int cnt, bool coplanarIsInter,
|
void FindEdgeOn(Vector a, Vector b, int cnt, bool coplanarIsInter, EdgeOnInfo *info);
|
||||||
bool *inter, bool *fwd,
|
|
||||||
uint32_t *face);
|
|
||||||
enum {
|
enum {
|
||||||
NAKED_OR_SELF_INTER_EDGES = 100,
|
NAKED_OR_SELF_INTER_EDGES = 100,
|
||||||
SELF_INTER_EDGES = 200,
|
SELF_INTER_EDGES = 200,
|
||||||
|
|
Loading…
Reference in New Issue