Intersection boolen in triangle mesh mode is properly implemented

In addition the union operation in tiangle mesh mode is changed
to keep coplanar faces the same way as the NURBS union does.

Finalizes: https://github.com/solvespace/solvespace/issues/35
This commit is contained in:
ruevs 2020-05-10 03:35:53 +03:00 committed by phkahler
parent 3888909d02
commit 6245c63f2e
3 changed files with 37 additions and 25 deletions

View File

@ -62,14 +62,17 @@ void SBsp3::InsertInPlane(bool pos2, STriangle *tr, SMesh *m) {
ll = ll->more; ll = ll->more;
} }
if(m->flipNormal && ((!pos2 && !onFace) || if((!onFace && ((m->keepInsideOtherShell && !pos2) ||
(onFace && !sameNormal && m->keepCoplanar))) (!m->keepInsideOtherShell && pos2))) ||
{ (onFace && ((m->keepCoplanar && m->flipNormal && !sameNormal) ||
m->AddTriangle(tr->meta, tr->c, tr->b, tr->a); (m->keepCoplanar && !m->flipNormal && sameNormal)))) {
} else if(!(m->flipNormal) && ((pos2 && !onFace) || // We have decided that we need to keep a triangle either inside,
(onFace && sameNormal && m->keepCoplanar))) // outside or on the other shell. So add it and flip it if requested.
{ if(!(m->flipNormal)) {
m->AddTriangle(tr->meta, tr->a, tr->b, tr->c); m->AddTriangle(tr->meta, tr->a, tr->b, tr->c);
} else {
m->AddTriangle(tr->meta, tr->c, tr->b, tr->a);
}
} else { } else {
m->atLeastOneDiscarded = true; m->atLeastOneDiscarded = true;
} }
@ -101,10 +104,15 @@ void SBsp3::InsertHow(BspClass how, STriangle *tr, SMesh *instead) {
return; return;
alt: alt:
if(how == BspClass::POS && !(instead->flipNormal)) { if(((BspClass::POS == how) && !instead->keepInsideOtherShell) ||
instead->AddTriangle(tr->meta, tr->a, tr->b, tr->c); ((BspClass::NEG == how) && instead->keepInsideOtherShell)) {
} else if(how == BspClass::NEG && instead->flipNormal) { // We have decided that we need to keep a triangle (either inside or
instead->AddTriangle(tr->meta, tr->c, tr->b, tr->a); // outside the other shell. So add it and flip it if requested.
if(!(instead->flipNormal)) {
instead->AddTriangle(tr->meta, tr->a, tr->b, tr->c);
} else {
instead->AddTriangle(tr->meta, tr->c, tr->b, tr->a);
}
} else if(how == BspClass::COPLANAR) { } else if(how == BspClass::COPLANAR) {
if(edges) { if(edges) {
edges->InsertTriangle(tr, instead, this); edges->InsertTriangle(tr, instead, this);
@ -431,6 +439,9 @@ SBsp3 *SBsp3::InsertConvex(STriMeta meta, Vector *vertex, size_t cnt, SMesh *ins
SBsp3 *SBsp3::InsertOrCreate(SBsp3 *where, STriangle *tr, SMesh *instead) { SBsp3 *SBsp3::InsertOrCreate(SBsp3 *where, STriangle *tr, SMesh *instead) {
if(where == NULL) { if(where == NULL) {
if(instead) { if(instead) {
// ruevs: I do not think this code is reachable, but in
// principle should we use instead->keepInsideOtherShell
// in place of instead->flipNormal ?
if(instead->flipNormal) { if(instead->flipNormal) {
instead->atLeastOneDiscarded = true; instead->atLeastOneDiscarded = true;
} else { } else {

View File

@ -265,11 +265,12 @@ void SMesh::MakeFromUnionOf(SMesh *a, SMesh *b) {
SBsp3 *bspb = SBsp3::FromMesh(b); SBsp3 *bspb = SBsp3::FromMesh(b);
flipNormal = false; flipNormal = false;
keepCoplanar = false; keepInsideOtherShell = false;
keepCoplanar = true;
AddAgainstBsp(b, bspa); AddAgainstBsp(b, bspa);
flipNormal = false; keepCoplanar = false;
keepCoplanar = true;
AddAgainstBsp(a, bspb); AddAgainstBsp(a, bspb);
} }
@ -279,28 +280,27 @@ void SMesh::MakeFromDifferenceOf(SMesh *a, SMesh *b) {
flipNormal = true; flipNormal = true;
keepCoplanar = true; keepCoplanar = true;
keepInsideOtherShell = true;
AddAgainstBsp(b, bspa); AddAgainstBsp(b, bspa);
flipNormal = false; flipNormal = false;
keepCoplanar = false; keepCoplanar = false;
keepInsideOtherShell = false;
AddAgainstBsp(a, bspb); AddAgainstBsp(a, bspb);
} }
void SMesh::MakeFromIntersectionOf(SMesh *a, SMesh *b) { void SMesh::MakeFromIntersectionOf(SMesh *a, SMesh *b) {
// Emulate triangle mesh intersection with difference SBsp3 *bspa = SBsp3::FromMesh(a);
// by doing C=A-(A-B). Figure out how to do it properly later.
SMesh c = {};
c.MakeFromDifferenceOf(a, b);
MakeFromDifferenceOf(a, &c);
c.Clear();
/* SBsp3 *bspa = SBsp3::FromMesh(a);
SBsp3 *bspb = SBsp3::FromMesh(b); SBsp3 *bspb = SBsp3::FromMesh(b);
keepInsideOtherShell = true;
flipNormal = false;
keepCoplanar = false;
AddAgainstBsp(a, bspb); AddAgainstBsp(a, bspb);
keepCoplanar = true;
AddAgainstBsp(b, bspa); AddAgainstBsp(b, bspa);
*/
} }
void SMesh::MakeFromCopyOf(SMesh *a) { void SMesh::MakeFromCopyOf(SMesh *a) {

View File

@ -252,6 +252,7 @@ public:
List<STriangle> l; List<STriangle> l;
bool flipNormal; bool flipNormal;
bool keepInsideOtherShell;
bool keepCoplanar; bool keepCoplanar;
bool atLeastOneDiscarded; bool atLeastOneDiscarded;
bool isTransparent; bool isTransparent;