Refactor SKdNode::FindEdgeOn.

Extract output parameters into a separate structure.
pull/4/head
EvilSpirit 2016-03-22 11:03:12 +06:00 committed by whitequark
parent 7c60be8203
commit 7e6a11c958
2 changed files with 32 additions and 31 deletions

View File

@ -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.,

View File

@ -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,