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:
parent
3888909d02
commit
6245c63f2e
29
src/bsp.cpp
29
src/bsp.cpp
@ -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) ||
|
||||||
|
((BspClass::NEG == how) && instead->keepInsideOtherShell)) {
|
||||||
|
// We have decided that we need to keep a triangle (either inside or
|
||||||
|
// 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);
|
instead->AddTriangle(tr->meta, tr->a, tr->b, tr->c);
|
||||||
} else if(how == BspClass::NEG && instead->flipNormal) {
|
} else {
|
||||||
instead->AddTriangle(tr->meta, tr->c, tr->b, tr->a);
|
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 {
|
||||||
|
26
src/mesh.cpp
26
src/mesh.cpp
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user