Fix triangulation issues when a polygon has more than two edges at
a vertex. [git-p4: depot-paths = "//depot/solvespace/": change = 1916]solver
parent
577cdf2255
commit
9ade574d36
|
@ -386,8 +386,11 @@ void SPolygon::FixContourDirections(void) {
|
|||
int i, j;
|
||||
for(i = 0; i < l.n; i++) {
|
||||
SContour *sc = &(l.elem[i]);
|
||||
if(sc->l.n < 1) continue;
|
||||
Vector pt = (sc->l.elem[0]).p;
|
||||
if(sc->l.n < 2) continue;
|
||||
// The contours may not intersect, but they may share vertices; so
|
||||
// testing a vertex for point-in-polygon may fail, but the midpoint
|
||||
// of an edge is okay.
|
||||
Vector pt = (((sc->l.elem[0]).p).Plus(sc->l.elem[1].p)).ScaledBy(0.5);
|
||||
|
||||
sc->timesEnclosed = 0;
|
||||
bool outer = true;
|
||||
|
|
|
@ -426,7 +426,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *agnst, SShell *parent,
|
|||
}
|
||||
final.l.RemoveTagged();
|
||||
|
||||
// if(I == 1) DEBUGEDGELIST(&final, &ret);
|
||||
// if(I == 10) DEBUGEDGELIST(&final, &ret);
|
||||
|
||||
// Use our reassembled edges to trim the new surface.
|
||||
ret.TrimFromEdgeList(&final);
|
||||
|
@ -485,13 +485,13 @@ void SShell::MakeFromBoolean(SShell *a, SShell *b, int type) {
|
|||
a->MakeIntersectionCurvesAgainst(b, this);
|
||||
|
||||
I = 100;
|
||||
if(b->surface.n == 0 || a->surface.n == 0) {
|
||||
if(b->surface.n == 0 || a->surface.n == 0 || a->surface.n == 6) {
|
||||
// Then trim and copy the surfaces
|
||||
a->CopySurfacesTrimAgainst(b, this, type, true);
|
||||
b->CopySurfacesTrimAgainst(a, this, type, false);
|
||||
} else {
|
||||
a->CopySurfacesTrimAgainst(b, this, type, true);
|
||||
I = 0;
|
||||
a->CopySurfacesTrimAgainst(b, this, type, true);
|
||||
b->CopySurfacesTrimAgainst(a, this, type, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,9 +42,14 @@ void SPolygon::UvTriangulateInto(SMesh *m) {
|
|||
SContour *sc;
|
||||
for(sc = l.First(); sc; sc = l.NextAfter(sc)) {
|
||||
if(sc->timesEnclosed != 1) continue;
|
||||
if(sc->l.n < 1) continue;
|
||||
if(sc->l.n < 2) continue;
|
||||
|
||||
if(top->ContainsPointProjdToNormal(normal, sc->l.elem[0].p)) {
|
||||
// Test the midpoint of an edge. Our polygon may not be self-
|
||||
// intersecting, but two countours may share a vertex; so a
|
||||
// vertex could be on the edge of another polygon, in which
|
||||
// case ContainsPointProjdToNormal returns indeterminate.
|
||||
Vector tp = ((sc->l.elem[0].p).Plus(sc->l.elem[1].p)).ScaledBy(0.5);
|
||||
if(top->ContainsPointProjdToNormal(normal, tp)) {
|
||||
sc->tag = 2;
|
||||
sc->MakeEdgesInto(&el);
|
||||
sc->FindPointWithMinX();
|
||||
|
@ -180,6 +185,12 @@ bool SContour::IsEar(int bp) {
|
|||
tr.b = l.elem[bp].p;
|
||||
tr.c = l.elem[cp].p;
|
||||
|
||||
if((tr.a).Equals(tr.c)) {
|
||||
// This is two coincident and anti-parallel edges. Zero-area, so
|
||||
// won't generate a real triangle, but we certainly can clip it.
|
||||
return true;
|
||||
}
|
||||
|
||||
Vector n = Vector::From(0, 0, -1);
|
||||
if((tr.Normal()).Dot(n) < LENGTH_EPS) {
|
||||
// This vertex is reflex, or between two collinear edges; either way,
|
||||
|
@ -222,7 +233,12 @@ void SContour::ClipEarInto(SMesh *m, int bp) {
|
|||
tr.a = l.elem[ap].p;
|
||||
tr.b = l.elem[bp].p;
|
||||
tr.c = l.elem[cp].p;
|
||||
if(tr.Normal().MagSquared() < LENGTH_EPS*LENGTH_EPS) {
|
||||
// A vertex with more than two edges will cause us to generate
|
||||
// zero-area triangles, which must be culled.
|
||||
} else {
|
||||
m->AddTriangle(&tr);
|
||||
}
|
||||
|
||||
// By deleting the point at bp, we may change the ear-ness of the points
|
||||
// on either side.
|
||||
|
@ -236,7 +252,17 @@ void SContour::ClipEarInto(SMesh *m, int bp) {
|
|||
|
||||
void SContour::UvTriangulateInto(SMesh *m) {
|
||||
int i;
|
||||
// First, calculate the ear-ness of all the points
|
||||
|
||||
// Clean the original contour by removing any zero-length edges.
|
||||
l.ClearTags();
|
||||
for(i = 1; i < l.n; i++) {
|
||||
if((l.elem[i].p).Equals(l.elem[i-1].p)) {
|
||||
l.elem[i].tag = 1;
|
||||
}
|
||||
}
|
||||
l.RemoveTagged();
|
||||
|
||||
// Now calculate the ear-ness of each vertex
|
||||
for(i = 0; i < l.n; i++) {
|
||||
(l.elem[i]).ear = IsEar(i) ? SPoint::EAR : SPoint::NOT_EAR;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue