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;
|
int i, j;
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
SContour *sc = &(l.elem[i]);
|
SContour *sc = &(l.elem[i]);
|
||||||
if(sc->l.n < 1) continue;
|
if(sc->l.n < 2) continue;
|
||||||
Vector pt = (sc->l.elem[0]).p;
|
// 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;
|
sc->timesEnclosed = 0;
|
||||||
bool outer = true;
|
bool outer = true;
|
||||||
|
|
|
@ -426,7 +426,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *agnst, SShell *parent,
|
||||||
}
|
}
|
||||||
final.l.RemoveTagged();
|
final.l.RemoveTagged();
|
||||||
|
|
||||||
// if(I == 1) DEBUGEDGELIST(&final, &ret);
|
// if(I == 10) DEBUGEDGELIST(&final, &ret);
|
||||||
|
|
||||||
// Use our reassembled edges to trim the new surface.
|
// Use our reassembled edges to trim the new surface.
|
||||||
ret.TrimFromEdgeList(&final);
|
ret.TrimFromEdgeList(&final);
|
||||||
|
@ -485,13 +485,13 @@ void SShell::MakeFromBoolean(SShell *a, SShell *b, int type) {
|
||||||
a->MakeIntersectionCurvesAgainst(b, this);
|
a->MakeIntersectionCurvesAgainst(b, this);
|
||||||
|
|
||||||
I = 100;
|
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
|
// Then trim and copy the surfaces
|
||||||
a->CopySurfacesTrimAgainst(b, this, type, true);
|
a->CopySurfacesTrimAgainst(b, this, type, true);
|
||||||
b->CopySurfacesTrimAgainst(a, this, type, false);
|
b->CopySurfacesTrimAgainst(a, this, type, false);
|
||||||
} else {
|
} else {
|
||||||
a->CopySurfacesTrimAgainst(b, this, type, true);
|
|
||||||
I = 0;
|
I = 0;
|
||||||
|
a->CopySurfacesTrimAgainst(b, this, type, true);
|
||||||
b->CopySurfacesTrimAgainst(a, this, type, false);
|
b->CopySurfacesTrimAgainst(a, this, type, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,9 +42,14 @@ void SPolygon::UvTriangulateInto(SMesh *m) {
|
||||||
SContour *sc;
|
SContour *sc;
|
||||||
for(sc = l.First(); sc; sc = l.NextAfter(sc)) {
|
for(sc = l.First(); sc; sc = l.NextAfter(sc)) {
|
||||||
if(sc->timesEnclosed != 1) continue;
|
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->tag = 2;
|
||||||
sc->MakeEdgesInto(&el);
|
sc->MakeEdgesInto(&el);
|
||||||
sc->FindPointWithMinX();
|
sc->FindPointWithMinX();
|
||||||
|
@ -180,6 +185,12 @@ bool SContour::IsEar(int bp) {
|
||||||
tr.b = l.elem[bp].p;
|
tr.b = l.elem[bp].p;
|
||||||
tr.c = l.elem[cp].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);
|
Vector n = Vector::From(0, 0, -1);
|
||||||
if((tr.Normal()).Dot(n) < LENGTH_EPS) {
|
if((tr.Normal()).Dot(n) < LENGTH_EPS) {
|
||||||
// This vertex is reflex, or between two collinear edges; either way,
|
// 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.a = l.elem[ap].p;
|
||||||
tr.b = l.elem[bp].p;
|
tr.b = l.elem[bp].p;
|
||||||
tr.c = l.elem[cp].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);
|
m->AddTriangle(&tr);
|
||||||
|
}
|
||||||
|
|
||||||
// By deleting the point at bp, we may change the ear-ness of the points
|
// By deleting the point at bp, we may change the ear-ness of the points
|
||||||
// on either side.
|
// on either side.
|
||||||
|
@ -236,7 +252,17 @@ void SContour::ClipEarInto(SMesh *m, int bp) {
|
||||||
|
|
||||||
void SContour::UvTriangulateInto(SMesh *m) {
|
void SContour::UvTriangulateInto(SMesh *m) {
|
||||||
int i;
|
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++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
(l.elem[i]).ear = IsEar(i) ? SPoint::EAR : SPoint::NOT_EAR;
|
(l.elem[i]).ear = IsEar(i) ? SPoint::EAR : SPoint::NOT_EAR;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue