@@ -1209,10 +1209,23 @@ int main(int argc, char *argv[]) {
12091209 for (int c = 0 ; c < n_components; ++c) {
12101210 inverted[c] = !temp.checkInversion (true , chartTris[c]);
12111211 }
1212- bool anyInversion = false , allDisks = true ;
1212+
1213+ // zero area passes the inversion test and a point boundary evades
1214+ // the crossing test, but a collapsed chart cannot seed the solve
1215+ std::vector<bool > degenerate (n_components, false );
1216+ for (int triI = 0 ; triI < temp.F .rows (); ++triI) {
1217+ const Eigen::RowVector3i &tri = temp.F .row (triI);
1218+ const Eigen::RowVector2d e1 = temp.V .row (tri[1 ]) - temp.V .row (tri[0 ]);
1219+ const Eigen::RowVector2d e2 = temp.V .row (tri[2 ]) - temp.V .row (tri[0 ]);
1220+ if (e1 [0 ] * e2 [1 ] - e1 [1 ] * e2 [0 ] <= 0.0 )
1221+ degenerate[C[triI]] = true ;
1222+ }
1223+
1224+ bool anyInversion = false , allDisks = true , anyDegenerate = false ;
12131225 for (int c = 0 ; c < n_components; ++c) {
12141226 anyInversion = anyInversion || inverted[c];
12151227 allDisks = allDisks && isDisk[c];
1228+ anyDegenerate = anyDegenerate || degenerate[c];
12161229 }
12171230 // a stitch run can keep charts with holes: an interior split the
12181231 // engine never merged back leaves a slit, and the machinery is
@@ -1249,19 +1262,22 @@ int main(int argc, char *argv[]) {
12491262 // whole-map decision first, so a map that was kept before is still
12501263 // kept byte for byte
12511264 keepInputUV = (allDisks || stitchKeepable) && !anyInversion &&
1252- crossingVerts.empty ();
1265+ !anyDegenerate && crossingVerts.empty ();
12531266
1254- int badInverted = 0 , badOverlapping = 0 , badNonDisk = 0 ;
1267+ int badInverted = 0 , badOverlapping = 0 , badNonDisk = 0 ,
1268+ badDegenerate = 0 ;
12551269 if (keepInputUV) {
12561270 keepChart.assign (n_components, true );
12571271 keptCharts = n_components;
12581272 } else {
12591273 for (int c = 0 ; c < n_components; ++c) {
1260- keepChart[c] =
1261- isDisk[c] && !overlaps[c] && !inverted [c] && !pinched [c];
1274+ keepChart[c] = isDisk[c] && !overlaps[c] && !inverted[c] &&
1275+ !pinched [c] && !degenerate [c];
12621276 keptCharts += keepChart[c];
12631277 if (inverted[c]) {
12641278 ++badInverted;
1279+ } else if (degenerate[c]) {
1280+ ++badDegenerate;
12651281 } else if (overlaps[c]) {
12661282 ++badOverlapping;
12671283 } else if (!isDisk[c]) {
@@ -1280,8 +1296,8 @@ int main(int argc, char *argv[]) {
12801296 } else if (!keepInputUV) {
12811297 std::cout << " kept " << keptCharts << " of " << n_components
12821298 << " input UV charts, re-cutting " << badInverted
1283- << " inverted, " << badOverlapping
1284- << " self-intersecting, " << badNonDisk
1299+ << " inverted, " << badDegenerate << " degenerate, "
1300+ << badOverlapping << " self-intersecting, " << badNonDisk
12851301 << " not disk-topology" << std::endl;
12861302 }
12871303 }
0 commit comments