As we break things against the BSP, keep an arbitrary convex

polygon, not just triangles. This helps to avoid needless
splitting. Also test if an entire triangle got inserted in multiple
pieces; if yes, back things out, and just insert the triangle.

Also remove the extra partition stuff, since it didn't seem to help
consistently, and this does.

Still could do some better merging, in the case where an inserted
triangle does not get fully inserted, but we can find a better
triangulation than what the BSP naturally gives.

[git-p4: depot-paths = "//depot/solvespace/": change = 1739]
This commit is contained in:
Jonathan Westhues 2008-05-24 15:10:00 -08:00
parent 097d0ddfa9
commit 0ad8644df4
3 changed files with 236 additions and 184 deletions

View File

@ -1189,12 +1189,11 @@ void GraphicsWindow::Paint(int w, int h) {
SBsp3 *pb = SBsp3::FromMesh(mb); SBsp3 *pb = SBsp3::FromMesh(mb);
SMesh br; ZERO(&br); SMesh br; ZERO(&br);
for(i = 0; i < mb->l.n; i++) { br.flipNormal = true; br.keepCoplanar = false;
pa->Insert(&(mb->l.elem[i]), &br, true, false); br.AddAgainstBsp(mb, pa);
} br.flipNormal = false; br.keepCoplanar = false;
for(i = 0; i < ma->l.n; i++) { br.AddAgainstBsp(ma, pb);
pb->Insert(&(ma->l.elem[i]), &br, false, false);
}
dbp("triangles in = %d %d out = %d", ma->l.n, mb->l.n, br.l.n); dbp("triangles in = %d %d out = %d", ma->l.n, mb->l.n, br.l.n);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);

366
mesh.cpp
View File

@ -49,125 +49,37 @@ void SMesh::GetBounding(Vector *vmax, Vector *vmin) {
} }
} }
void SMesh::AddAgainstBsp(SMesh *srcm, SBsp3 *bsp3) {
int i;
for(i = 0; i < srcm->l.n; i++) {
STriangle *st = &(srcm->l.elem[i]);
int pn = l.n;
atLeastOneDiscarded = false;
bsp3->Insert(st, this);
if(!atLeastOneDiscarded && (l.n != (pn+1))) {
l.n = pn;
if(flipNormal) {
AddTriangle(st->c, st->b, st->a);
} else {
AddTriangle(st->a, st->b, st->c);
}
continue;
}
}
}
SBsp2 *SBsp2::Alloc(void) { return (SBsp2 *)AllocTemporary(sizeof(SBsp2)); } SBsp2 *SBsp2::Alloc(void) { return (SBsp2 *)AllocTemporary(sizeof(SBsp2)); }
SBsp3 *SBsp3::Alloc(void) { return (SBsp3 *)AllocTemporary(sizeof(SBsp3)); } SBsp3 *SBsp3::Alloc(void) { return (SBsp3 *)AllocTemporary(sizeof(SBsp3)); }
double SBsp3::SplitFactor(int npos, int nneg, int nsplit) {
double r, ntot = npos + nneg + nsplit;
// A larger split factor is more desirable; best possible is 0.5
r = (min(npos, nneg)) / ntot;
r *= pow((npos + nneg) / ntot, 3);
return r;
}
SBsp3 *SBsp3::ChoosePartition(SMesh *m) {
if(m->l.n < 20) return NULL;
Vector vmax, vmin;
m->GetBounding(&vmax, &vmin);
double x = (vmax.x + vmin.x)/2;
double y = (vmax.y + vmin.y)/2;
double z = (vmax.z + vmin.z)/2;
int px = 0, nx = 0, sx = 0;
int py = 0, ny = 0, sy = 0;
int pz = 0, nz = 0, sz = 0;
int i, j;
for(i = 0; i < m->l.n; i++) {
STriangle *tr = &(m->l.elem[i]);
int vx = 0, vy = 0, vz = 0;
for(j = 0; j < 3; j++) {
Vector a = (j == 0) ? tr->a : ((j == 1) ? tr->b : tr->c);
if(a.x < x) vx++;
if(a.y < y) vy++;
if(a.z < z) vz++;
}
if(vx == 3) { px++; } else if(vx == 0) { nx++; } else { sx++; }
if(vy == 3) { py++; } else if(vy == 0) { ny++; } else { sy++; }
if(vz == 3) { pz++; } else if(vz == 0) { nz++; } else { sz++; }
}
double fx = SplitFactor(px, nx, sx);
double fy = SplitFactor(py, ny, sy);
double fz = SplitFactor(pz, nz, sz);
double fmax = max(fx, max(fy, fz));
Vector nn;
double dd;
if(fmax == fx) {
nn = Vector::MakeFrom(1, 0, 0);
dd = x;
} else if(fmax == fy) {
nn = Vector::MakeFrom(0, 1, 0);
dd = y;
} else if(fmax == fz) {
nn = Vector::MakeFrom(0, 0, 1);
dd = z;
} else oops();
SBsp3 *r = Alloc();
r->n = nn;
r->d = dd;
SMesh mpos, mneg;
ZERO(&mpos); ZERO(&mneg);
for(i = 0; i < m->l.n; i++) {
STriangle *tr = &(m->l.elem[i]);
double da = (tr->a).Dot(nn);
double db = (tr->b).Dot(nn);
double dc = (tr->c).Dot(nn);
if(da > dd && db > dd && dc > dd) {
mpos.AddTriangle(tr);
}
if(da < dd && db < dd && dc < dd) {
mneg.AddTriangle(tr);
}
}
if(mpos.l.n >= m->l.n || mneg.l.n >= m->l.n) {
// We show no signs of terminating; bad.
oops();
}
r->pos = ChoosePartition(&mpos);
r->neg = ChoosePartition(&mneg);
mpos.Clear(); mneg.Clear();
return r;
}
SBsp3 *SBsp3::FromMesh(SMesh *m) { SBsp3 *SBsp3::FromMesh(SMesh *m) {
SBsp3 *bsp3 = ChoosePartition(m); SBsp3 *bsp3 = NULL;
Vector vmax, vmin;
m->GetBounding(&vmax, &vmin);
Vector adj = { 1, 1, 1 };
vmax = vmax.Plus(adj); vmin = vmin.Minus(adj);
int i; int i;
for(i = 0; i < m->l.n; i++) { for(i = 0; i < m->l.n; i++) {
bsp3 = bsp3->Insert(&(m->l.elem[i]), NULL, false, false); bsp3 = bsp3->Insert(&(m->l.elem[i]), NULL);
} }
bsp3 = bsp3->InsertExtraSplit(Vector::MakeFrom( 1, 0, 0), vmax.x);
bsp3 = bsp3->InsertExtraSplit(Vector::MakeFrom( 0, 1, 0), vmax.y);
bsp3 = bsp3->InsertExtraSplit(Vector::MakeFrom( 0, 0, 1), vmax.z);
bsp3 = bsp3->InsertExtraSplit(Vector::MakeFrom(-1, 0, 0), -vmin.x);
bsp3 = bsp3->InsertExtraSplit(Vector::MakeFrom( 0, -1, 0), -vmin.y);
bsp3 = bsp3->InsertExtraSplit(Vector::MakeFrom( 0, 0, -1), -vmin.z);
return bsp3; return bsp3;
} }
SBsp3 *SBsp3::InsertExtraSplit(Vector nn, double dd) {
SBsp3 *r = Alloc();
r->n = nn;
r->d = dd;
r->neg = this;
r->pos = NULL;
return r;
}
Vector SBsp3::IntersectionWith(Vector a, Vector b) { Vector SBsp3::IntersectionWith(Vector a, Vector b) {
double da = a.Dot(n) - d; double da = a.Dot(n) - d;
double db = b.Dot(n) - d; double db = b.Dot(n) - d;
@ -177,9 +89,7 @@ Vector SBsp3::IntersectionWith(Vector a, Vector b) {
return (a.ScaledBy(db/dab)).Plus(b.ScaledBy(-da/dab)); return (a.ScaledBy(db/dab)).Plus(b.ScaledBy(-da/dab));
} }
void SBsp3::InsertInPlane(bool pos2, STriangle *tr, void SBsp3::InsertInPlane(bool pos2, STriangle *tr, SMesh *m) {
SMesh *m, bool flip, bool cpl)
{
Vector tc = ((tr->a).Plus(tr->b).Plus(tr->c)).ScaledBy(1.0/3); Vector tc = ((tr->a).Plus(tr->b).Plus(tr->c)).ScaledBy(1.0/3);
bool onFace = false; bool onFace = false;
@ -195,30 +105,27 @@ void SBsp3::InsertInPlane(bool pos2, STriangle *tr,
ll = ll->more; ll = ll->more;
} }
if(flip) { if(m->flipNormal && !pos2 && (!onFace || !sameNormal)) {
if(cpl) oops();
if(!pos2 && (!onFace || !sameNormal)) {
m->AddTriangle(tr->c, tr->b, tr->a); m->AddTriangle(tr->c, tr->b, tr->a);
} } else if(!(m->flipNormal) && (pos2 ||
} else { (onFace && sameNormal && m->keepCoplanar)))
if(pos2 || (onFace && sameNormal && cpl)) { {
m->AddTriangle(tr->a, tr->b, tr->c); m->AddTriangle(tr->a, tr->b, tr->c);
} } else {
m->atLeastOneDiscarded = true;
} }
} }
void SBsp3::InsertHow(int how, STriangle *tr, void SBsp3::InsertHow(int how, STriangle *tr, SMesh *instead) {
SMesh *instead, bool flip, bool cpl)
{
switch(how) { switch(how) {
case POS: case POS:
if(instead && !pos) goto alt; if(instead && !pos) goto alt;
pos = pos->Insert(tr, instead, flip, cpl); pos = pos->Insert(tr, instead);
break; break;
case NEG: case NEG:
if(instead && !neg) goto alt; if(instead && !neg) goto alt;
neg = neg->Insert(tr, instead, flip, cpl); neg = neg->Insert(tr, instead);
break; break;
case COPLANAR: { case COPLANAR: {
@ -236,24 +143,153 @@ void SBsp3::InsertHow(int how, STriangle *tr,
return; return;
alt: alt:
if(how == POS && !flip) { if(how == POS && !(instead->flipNormal)) {
instead->AddTriangle(tr->a, tr->b, tr->c); instead->AddTriangle(tr->a, tr->b, tr->c);
} } else if(how == NEG && instead->flipNormal) {
if(how == NEG && flip) {
instead->AddTriangle(tr->c, tr->b, tr->a); instead->AddTriangle(tr->c, tr->b, tr->a);
} } else if(how == COPLANAR) {
if(how == COPLANAR) {
if(edges) { if(edges) {
edges->InsertTriangle(tr, instead, this, flip, cpl); edges->InsertTriangle(tr, instead, this);
} else { } else {
// I suppose this actually is allowed to happen, if the coplanar // I suppose this actually is allowed to happen, if the coplanar
// face is the leaf, and all of its neighbors are earlier in tree? // face is the leaf, and all of its neighbors are earlier in tree?
InsertInPlane(false, tr, instead, flip, cpl); InsertInPlane(false, tr, instead);
} }
} else {
instead->atLeastOneDiscarded = true;
} }
} }
SBsp3 *SBsp3::Insert(STriangle *tr, SMesh *instead, bool flip, bool cpl) { void SBsp3::InsertConvexHow(int how, Vector *vertex, int n, SMesh *instead) {
switch(how) {
case POS:
if(pos) {
pos = pos->InsertConvex(vertex, n, instead);
return;
}
break;
case NEG:
if(neg) {
neg = neg->InsertConvex(vertex, n, instead);
return;
}
break;
default: oops();
}
int i;
for(i = 0; i < n - 2; i++) {
STriangle tr = { 0, vertex[0], vertex[i+1], vertex[i+2] };
InsertHow(how, &tr, instead);
}
}
SBsp3 *SBsp3::InsertConvex(Vector *vertex, int cnt, SMesh *instead) {
Vector e01 = (vertex[1]).Minus(vertex[0]);
Vector e12 = (vertex[2]).Minus(vertex[1]);
Vector out = e01.Cross(e12);
int i;
Vector on[2];
bool *isPos = (bool *)AllocTemporary(cnt*sizeof(bool));
bool *isNeg = (bool *)AllocTemporary(cnt*sizeof(bool));
bool *isOn = (bool *)AllocTemporary(cnt*sizeof(bool));
int posc = 0, negc = 0, onc = 0;
for(i = 0; i < cnt; i++) {
double dt = n.Dot(vertex[i]);
isPos[i] = isNeg[i] = isOn[i] = false;
if(fabs(dt - d) < LENGTH_EPS) {
isOn[i] = true;
if(onc < 2) {
on[onc] = vertex[i];
}
onc++;
} else if(dt > d) {
isPos[i] = true;
posc++;
} else {
isNeg[i] = true;
negc++;
}
}
if(onc != 2 && onc != 1 && onc != 0) goto triangulate;
if(onc == 2) {
if(!instead) {
SEdge se = { 0, on[0], on[1] };
edges = edges->InsertEdge(&se, n, out);
}
}
if(posc == 0) {
InsertConvexHow(NEG, vertex, cnt, instead);
return this;
}
if(negc == 0) {
InsertConvexHow(POS, vertex, cnt, instead);
return this;
}
Vector *vpos = (Vector *)AllocTemporary((cnt+1)*sizeof(Vector));
Vector *vneg = (Vector *)AllocTemporary((cnt+1)*sizeof(Vector));
int npos = 0, nneg = 0;
Vector inter[2];
int inters = 0;
for(i = 0; i < cnt; i++) {
int ip = (i + 1) % cnt;
if(isPos[i]) {
vpos[npos++] = vertex[i];
}
if(isNeg[i]) {
vneg[nneg++] = vertex[i];
}
if(isOn[i]) {
vneg[nneg++] = vertex[i];
vpos[npos++] = vertex[i];
}
if((isPos[i] && isNeg[ip]) || (isNeg[i] && isPos[ip])) {
Vector vi = IntersectionWith(vertex[i], vertex[ip]);
vpos[npos++] = vi;
vneg[nneg++] = vi;
if(inters >= 2) oops();
inter[inters++] = vi;
}
}
if(npos > cnt + 1 || nneg > cnt + 1) oops();
if(!instead) {
if(inters == 2) {
SEdge se = { 0, inter[0], inter[1] };
edges = edges->InsertEdge(&se, n, out);
} else if(inters == 1 && onc == 1) {
SEdge se = { 0, inter[0], on[0] };
edges = edges->InsertEdge(&se, n, out);
} else if(inters == 0 && onc == 2) {
// We already handled this on-plane existing edge
} else oops();
}
if(nneg < 3 || npos < 3) oops();
InsertConvexHow(NEG, vneg, nneg, instead);
InsertConvexHow(POS, vpos, npos, instead);
return this;
triangulate:
// We don't handle the special case for this; do it as triangles
SBsp3 *r = this;
for(i = 0; i < cnt - 2; i++) {
STriangle tr = { 0, vertex[0], vertex[i+1], vertex[i+2] };
r = r->Insert(&tr, instead);
}
return r;
}
SBsp3 *SBsp3::Insert(STriangle *tr, SMesh *instead) {
if(!this) { if(!this) {
// Brand new node; so allocate for it, and fill us in. // Brand new node; so allocate for it, and fill us in.
SBsp3 *r = Alloc(); SBsp3 *r = Alloc();
@ -284,7 +320,7 @@ SBsp3 *SBsp3::Insert(STriangle *tr, SMesh *instead, bool flip, bool cpl) {
// All vertices in-plane // All vertices in-plane
if(inc == 3) { if(inc == 3) {
InsertHow(COPLANAR, tr, instead, flip, cpl); InsertHow(COPLANAR, tr, instead);
return this; return this;
} }
@ -303,9 +339,9 @@ SBsp3 *SBsp3::Insert(STriangle *tr, SMesh *instead, bool flip, bool cpl) {
} }
if(posc > 0) { if(posc > 0) {
InsertHow(POS, tr, instead, flip, cpl); InsertHow(POS, tr, instead);
} else { } else {
InsertHow(NEG, tr, instead, flip, cpl); InsertHow(NEG, tr, instead);
} }
return this; return this;
} }
@ -326,11 +362,11 @@ SBsp3 *SBsp3::Insert(STriangle *tr, SMesh *instead, bool flip, bool cpl) {
STriangle ctri = { 0, c, a, bPc }; STriangle ctri = { 0, c, a, bPc };
if(bpos) { if(bpos) {
InsertHow(POS, &btri, instead, flip, cpl); InsertHow(POS, &btri, instead);
InsertHow(NEG, &ctri, instead, flip, cpl); InsertHow(NEG, &ctri, instead);
} else { } else {
InsertHow(POS, &ctri, instead, flip, cpl); InsertHow(POS, &ctri, instead);
InsertHow(NEG, &btri, instead, flip, cpl); InsertHow(NEG, &btri, instead);
} }
if(!instead) { if(!instead) {
@ -359,17 +395,17 @@ SBsp3 *SBsp3::Insert(STriangle *tr, SMesh *instead, bool flip, bool cpl) {
Vector cPa = IntersectionWith(c, a); Vector cPa = IntersectionWith(c, a);
STriangle alone = { 0, a, aPb, cPa }; STriangle alone = { 0, a, aPb, cPa };
Vector quad[4] = { aPb, b, c, cPa };
STriangle quad1 = { 0, aPb, b, c }; STriangle quad1 = { 0, aPb, b, c };
STriangle quad2 = { 0, aPb, c, cPa }; STriangle quad2 = { 0, aPb, c, cPa };
if(posc == 2 && negc == 1) { if(posc == 2 && negc == 1) {
InsertHow(POS, &quad1, instead, flip, cpl); InsertConvexHow(POS, quad, 4, instead);
InsertHow(POS, &quad2, instead, flip, cpl); InsertHow(NEG, &alone, instead);
InsertHow(NEG, &alone, instead, flip, cpl);
} else { } else {
InsertHow(NEG, &quad1, instead, flip, cpl); InsertConvexHow(NEG, quad, 4, instead);
InsertHow(NEG, &quad2, instead, flip, cpl); InsertHow(POS, &alone, instead);
InsertHow(POS, &alone, instead, flip, cpl);
} }
if(!instead) { if(!instead) {
SEdge se = { 0, aPb, cPa }; SEdge se = { 0, aPb, cPa };
@ -502,23 +538,21 @@ SBsp2 *SBsp2::InsertEdge(SEdge *nedge, Vector nnp, Vector out) {
oops(); oops();
} }
void SBsp2::InsertTriangleHow(int how, STriangle *tr, void SBsp2::InsertTriangleHow(int how, STriangle *tr, SMesh *m, SBsp3 *bsp3) {
SMesh *m, SBsp3 *bsp3, bool flip, bool cpl)
{
switch(how) { switch(how) {
case POS: case POS:
if(pos) { if(pos) {
pos->InsertTriangle(tr, m, bsp3, flip, cpl); pos->InsertTriangle(tr, m, bsp3);
} else { } else {
bsp3->InsertInPlane(true, tr, m, flip, cpl); bsp3->InsertInPlane(true, tr, m);
} }
break; break;
case NEG: case NEG:
if(neg) { if(neg) {
neg->InsertTriangle(tr, m, bsp3, flip, cpl); neg->InsertTriangle(tr, m, bsp3);
} else { } else {
bsp3->InsertInPlane(false, tr, m, flip, cpl); bsp3->InsertInPlane(false, tr, m);
} }
break; break;
@ -526,9 +560,7 @@ void SBsp2::InsertTriangleHow(int how, STriangle *tr,
} }
} }
void SBsp2::InsertTriangle(STriangle *tr, void SBsp2::InsertTriangle(STriangle *tr, SMesh *m, SBsp3 *bsp3) {
SMesh *m, SBsp3 *bsp3, bool flip, bool cpl)
{
double dt[3] = { (tr->a).Dot(no), (tr->b).Dot(no), (tr->c).Dot(no) }; double dt[3] = { (tr->a).Dot(no), (tr->b).Dot(no), (tr->c).Dot(no) };
bool isPos[3], isNeg[3], isOn[3]; bool isPos[3], isNeg[3], isOn[3];
@ -555,9 +587,9 @@ void SBsp2::InsertTriangle(STriangle *tr,
// No split required // No split required
if(posc == 0 || negc == 0) { if(posc == 0 || negc == 0) {
if(posc > 0) { if(posc > 0) {
InsertTriangleHow(POS, tr, m, bsp3, flip, cpl); InsertTriangleHow(POS, tr, m, bsp3);
} else { } else {
InsertTriangleHow(NEG, tr, m, bsp3, flip, cpl); InsertTriangleHow(NEG, tr, m, bsp3);
} }
return; return;
} }
@ -578,11 +610,11 @@ void SBsp2::InsertTriangle(STriangle *tr,
STriangle ctri = { 0, c, a, bPc }; STriangle ctri = { 0, c, a, bPc };
if(bpos) { if(bpos) {
InsertTriangleHow(POS, &btri, m, bsp3, flip, cpl); InsertTriangleHow(POS, &btri, m, bsp3);
InsertTriangleHow(NEG, &ctri, m, bsp3, flip, cpl); InsertTriangleHow(NEG, &ctri, m, bsp3);
} else { } else {
InsertTriangleHow(POS, &ctri, m, bsp3, flip, cpl); InsertTriangleHow(POS, &ctri, m, bsp3);
InsertTriangleHow(NEG, &btri, m, bsp3, flip, cpl); InsertTriangleHow(NEG, &btri, m, bsp3);
} }
return; return;
@ -610,13 +642,13 @@ void SBsp2::InsertTriangle(STriangle *tr,
STriangle quad2 = { 0, aPb, c, cPa }; STriangle quad2 = { 0, aPb, c, cPa };
if(posc == 2 && negc == 1) { if(posc == 2 && negc == 1) {
InsertTriangleHow(POS, &quad1, m, bsp3, flip, cpl); InsertTriangleHow(POS, &quad1, m, bsp3);
InsertTriangleHow(POS, &quad2, m, bsp3, flip, cpl); InsertTriangleHow(POS, &quad2, m, bsp3);
InsertTriangleHow(NEG, &alone, m, bsp3, flip, cpl); InsertTriangleHow(NEG, &alone, m, bsp3);
} else { } else {
InsertTriangleHow(NEG, &quad1, m, bsp3, flip, cpl); InsertTriangleHow(NEG, &quad1, m, bsp3);
InsertTriangleHow(NEG, &quad2, m, bsp3, flip, cpl); InsertTriangleHow(NEG, &quad2, m, bsp3);
InsertTriangleHow(POS, &alone, m, bsp3, flip, cpl); InsertTriangleHow(POS, &alone, m, bsp3);
} }
return; return;

View File

@ -33,6 +33,23 @@ public:
elem = NULL; elem = NULL;
n = elemsAllocated = 0; n = elemsAllocated = 0;
} }
void RemoveTagged(void) {
int src, dest;
dest = 0;
for(src = 0; src < n; src++) {
if(elem[src].tag) {
// this item should be deleted
} else {
if(src != dest) {
elem[dest] = elem[src];
}
dest++;
}
}
n = dest;
// and elemsAllocated is untouched, because we didn't resize
}
}; };
class SEdge { class SEdge {
@ -105,10 +122,8 @@ public:
SBsp2 *more; SBsp2 *more;
static const int POS = 100, NEG = 101, COPLANAR = 200; static const int POS = 100, NEG = 101, COPLANAR = 200;
void InsertTriangleHow(int how, STriangle *tr, void InsertTriangleHow(int how, STriangle *tr, SMesh *m, SBsp3 *bsp3);
SMesh *m, SBsp3 *bsp3, bool flip, bool cpl); void InsertTriangle(STriangle *tr, SMesh *m, SBsp3 *bsp3);
void InsertTriangle(STriangle *tr,
SMesh *m, SBsp3 *bsp3, bool flip, bool cpl);
Vector IntersectionWith(Vector a, Vector b); Vector IntersectionWith(Vector a, Vector b);
SBsp2 *InsertEdge(SEdge *nedge, Vector nnp, Vector out); SBsp2 *InsertEdge(SEdge *nedge, Vector nnp, Vector out);
static SBsp2 *Alloc(void); static SBsp2 *Alloc(void);
@ -130,18 +145,18 @@ public:
SBsp2 *edges; SBsp2 *edges;
static SBsp3 *Alloc(void); static SBsp3 *Alloc(void);
static double SplitFactor(int npos, int nneg, int nsplit);
static SBsp3 *ChoosePartition(SMesh *m);
SBsp3 *InsertExtraSplit(Vector nn, double dd);
static SBsp3 *FromMesh(SMesh *m); static SBsp3 *FromMesh(SMesh *m);
Vector IntersectionWith(Vector a, Vector b); Vector IntersectionWith(Vector a, Vector b);
static const int POS = 100, NEG = 101, COPLANAR = 200; static const int POS = 100, NEG = 101, COPLANAR = 200;
void InsertHow(int how, STriangle *str, SMesh *instead, bool flip,bool cpl); void InsertHow(int how, STriangle *str, SMesh *instead);
SBsp3 *Insert(STriangle *str, SMesh *instead, bool flip, bool cpl); SBsp3 *Insert(STriangle *str, SMesh *instead);
void InsertInPlane(bool pos2, STriangle *tr, SMesh *m, bool flip, bool cpl); void InsertConvexHow(int how, Vector *vertex, int n, SMesh *instead);
SBsp3 *InsertConvex(Vector *vertex, int n, SMesh *instead);
void InsertInPlane(bool pos2, STriangle *tr, SMesh *m);
void DebugDraw(void); void DebugDraw(void);
}; };
@ -151,12 +166,18 @@ class SMesh {
public: public:
SList<STriangle> l; SList<STriangle> l;
bool flipNormal;
bool keepCoplanar;
bool atLeastOneDiscarded;
void Clear(void); void Clear(void);
void AddTriangle(STriangle *st); void AddTriangle(STriangle *st);
void AddTriangle(Vector a, Vector b, Vector c); void AddTriangle(Vector a, Vector b, Vector c);
void AddTriangle(Vector n, Vector a, Vector b, Vector c); void AddTriangle(Vector n, Vector a, Vector b, Vector c);
void DoBounding(Vector v, Vector *vmax, Vector *vmin); void DoBounding(Vector v, Vector *vmax, Vector *vmin);
void GetBounding(Vector *vmax, Vector *vmin); void GetBounding(Vector *vmax, Vector *vmin);
void AddAgainstBsp(SMesh *srcm, SBsp3 *bsp3);
}; };
#endif #endif