Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the zebra polygon #832

Merged
merged 4 commits into from
Jun 8, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -83,7 +83,7 @@ if(CMAKE_EXPORT_COMPILE_COMMANDS AND NOT EMSCRIPTEN)
endif()

if (MSVC)
set(MANIFOLD_FLAGS ${MANIFOLD_FLAGS} /DNOMINMAX)
set(MANIFOLD_FLAGS ${MANIFOLD_FLAGS} /DNOMINMAX /bigobj)
else()
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(WARNING_FLAGS -Werror -Wall -Wno-sign-compare -Wno-unused -Wno-array-bounds
34 changes: 27 additions & 7 deletions src/polygon/src/polygon.cpp
Original file line number Diff line number Diff line change
@@ -344,6 +344,13 @@ class EarClip {
// it finds a clear geometric result. In the vast majority of cases the loop
// will only need one or two iterations.
bool IsConvex(float precision) const {
const int convexity = CCW(left->pos, pos, right->pos, precision);
if (convexity != 0) {
return convexity > 0;
}
if (glm::dot(left->pos - pos, right->pos - pos) <= 0) {
return true;
}
return left->InsideEdge(left->right, precision, true);
}

@@ -363,8 +370,8 @@ class EarClip {
const auto none = std::make_pair(left, false);
if (pos.y < start.y && right->pos.y >= start.y) {
return std::make_pair(left->right, true);
} else if (pos.x > start.x - precision && pos.y > start.y - precision &&
pos.y < start.y + precision &&
} else if (onTop != 0 && pos.x > start.x - precision &&
pos.y > start.y - precision && pos.y < start.y + precision &&
Interior(start, precision) >= 0) {
if (onTop > 0 && left->pos.x < pos.x &&
left->pos.y > start.y - precision) {
@@ -433,7 +440,7 @@ class EarClip {
float totalCost = glm::dot(left->rightDir, rightDir) - 1 - precision;
if (CCW(pos, left->pos, right->pos, precision) == 0) {
// Clip folded ears first
return totalCost < -1 ? kBest : 0;
return totalCost;
}

Vec<Box> earBox;
@@ -611,7 +618,7 @@ class EarClip {
areaCompensation += (area - t1) + area1;
area = t1;

if (!v->IsConvex(precision_) && v->pos.x > maxX) {
if (v->pos.x > maxX) {
maxX = v->pos.x;
start = v;
}
@@ -754,6 +761,8 @@ class EarClip {
} else if (v->IsConvex(precision_)) {
v->cost = v->EarCost(precision_, collider);
v->ear = earsQueue_.insert(v);
} else {
v->cost = 1; // not used, but marks reflex verts for debug
}
}

@@ -852,6 +861,15 @@ class EarClip {
std::cout << " [" << v->pos.x << ", " << v->pos.y << "],# " << v->mesh_idx
<< std::endl;
std::cout << "]))" << std::endl;

v = start;
std::cout << "polys.push_back({" << std::setprecision(9) << std::endl;
do {
std::cout << " {" << v->pos.x << ", " << v->pos.y << "}, //"
<< std::endl;
v = v->right;
} while (v != start);
std::cout << "});" << std::endl;
#endif
}
};
@@ -875,23 +893,25 @@ namespace manifold {
std::vector<glm::ivec3> TriangulateIdx(const PolygonsIdx &polys,
float precision) {
std::vector<glm::ivec3> triangles;
float updatedPrecision = precision;
try {
EarClip triangulator(polys, precision);
updatedPrecision = triangulator.GetPrecision();
triangles = triangulator.Triangulate();
#ifdef MANIFOLD_DEBUG
if (params.intermediateChecks) {
CheckTopology(triangles, polys);
if (!params.processOverlaps) {
CheckGeometry(triangles, polys, 2 * triangulator.GetPrecision());
CheckGeometry(triangles, polys, 2 * updatedPrecision);
}
}
} catch (const geometryErr &e) {
if (!params.suppressErrors) {
PrintFailure(e, polys, triangles, precision);
PrintFailure(e, polys, triangles, updatedPrecision);
}
throw;
} catch (const std::exception &e) {
PrintFailure(e, polys, triangles, precision);
PrintFailure(e, polys, triangles, updatedPrecision);
throw;
#else
} catch (const std::exception &e) {
2 changes: 1 addition & 1 deletion test/polygon_corpus.cpp
Original file line number Diff line number Diff line change
@@ -570,7 +570,7 @@ TEST(Polygon, Ugly) {
{2289.28784, 13251.1582}, //
{2379.03027, 13010.5566}, //
});
TestPoly(polys, 32);
TestPoly(polys, 36);
};

TEST(Polygon, Sponge4a) {
13 changes: 8 additions & 5 deletions test/polygon_test.cpp
Original file line number Diff line number Diff line change
@@ -56,21 +56,24 @@ Polygons Duplicate(Polygons polys) {
}

void TestPoly(const Polygons &polys, int expectedNumTri,
float precision = -1.0f) {
float precision = -1.0f, bool onlyBasic = false) {
PolygonParams().verbose = options.params.verbose;

std::vector<glm::ivec3> triangles;
EXPECT_NO_THROW(triangles = Triangulate(polys, precision));
EXPECT_EQ(triangles.size(), expectedNumTri) << "Basic";

EXPECT_NO_THROW(triangles = Triangulate(Turn180(polys), precision));
EXPECT_EQ(triangles.size(), expectedNumTri) << "Turn 180";
if (!onlyBasic) {
EXPECT_NO_THROW(triangles = Triangulate(Turn180(polys), precision));
EXPECT_EQ(triangles.size(), expectedNumTri) << "Turn 180";

EXPECT_NO_THROW(triangles = Triangulate(Duplicate(polys), precision));
EXPECT_EQ(triangles.size(), 2 * expectedNumTri) << "Duplicate";
EXPECT_NO_THROW(triangles = Triangulate(Duplicate(polys), precision));
EXPECT_EQ(triangles.size(), 2 * expectedNumTri) << "Duplicate";
}

PolygonParams().verbose = false;
}
} // namespace

#include "polygon_corpus.cpp"
#include "zebra.cpp"
2 changes: 1 addition & 1 deletion test/sdf_test.cpp
Original file line number Diff line number Diff line change
@@ -116,7 +116,7 @@ TEST(SDF, SineSurface) {
Mesh surface(LevelSet(
[](glm::vec3 p) {
float mid = glm::sin(p.x) + glm::sin(p.y);
return (p.z > mid - 0.5 && p.z < mid + 0.5) ? 1 : 0;
return (p.z > mid - 0.5 && p.z < mid + 0.5) ? 1.0f : 0.0f;
},
{glm::vec3(-4 * glm::pi<float>()), glm::vec3(4 * glm::pi<float>())}, 1));
Manifold smoothed = Manifold::Smooth(surface).Refine(2);
2 changes: 1 addition & 1 deletion test/smooth_test.cpp
Original file line number Diff line number Diff line change
@@ -323,7 +323,7 @@ TEST(Smooth, SineSurface) {
MeshGL surface = LevelSet(
[](glm::vec3 p) {
float mid = glm::sin(p.x) + glm::sin(p.y);
return (p.z > mid - 0.5 && p.z < mid + 0.5) ? 1 : -1;
return (p.z > mid - 0.5 && p.z < mid + 0.5) ? 1.0f : -1.0f;
},
{glm::vec3(-2 * glm::pi<float>() + 0.2),
glm::vec3(0 * glm::pi<float>() - 0.2)},
63,221 changes: 63,221 additions & 0 deletions test/zebra.cpp

Large diffs are not rendered by default.