diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index d1de9a7..cc83baf 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install dependencies - run: dnf install -yq cmake ninja-build clang-tools-extra python3-PyYAML + run: dnf install -yq cmake ninja-build gcc-c++ clang-tools-extra python3-PyYAML - name: Build with GCC run: | diff --git a/poly2tri/common/shapes.cc b/poly2tri/common/shapes.cc index c044311..6e65dc6 100644 --- a/poly2tri/common/shapes.cc +++ b/poly2tri/common/shapes.cc @@ -352,12 +352,18 @@ void Triangle::SetDelunayEdgeCW(const Point& p, bool e) // The neighbor across to given point Triangle& Triangle::NeighborAcross(const Point& opoint) { + Triangle* neighbor = nullptr; if (&opoint == points_[0]) { - return *neighbors_[0]; + neighbor = neighbors_[0]; } else if (&opoint == points_[1]) { - return *neighbors_[1]; + neighbor = neighbors_[1]; + } else { + neighbor = neighbors_[2]; } - return *neighbors_[2]; + if (neighbor == nullptr) { + throw std::runtime_error("NeighborAcross - null neighbor"); + } + return *neighbor; } void Triangle::DebugPrint() diff --git a/poly2tri/sweep/sweep.cc b/poly2tri/sweep/sweep.cc index cac7e69..1f51fee 100644 --- a/poly2tri/sweep/sweep.cc +++ b/poly2tri/sweep/sweep.cc @@ -54,8 +54,8 @@ void Sweep::SweepPoints(SweepContext& tcx) for (size_t i = 1; i < tcx.point_count(); i++) { Point& point = *tcx.GetPoint(i); Node* node = &PointEvent(tcx, point); - for (unsigned int i = 0; i < point.edge_list.size(); i++) { - EdgeEvent(tcx, point.edge_list[i], node); + for (unsigned int j = 0; j < point.edge_list.size(); j++) { + EdgeEvent(tcx, point.edge_list[j], node); } } } @@ -123,8 +123,7 @@ void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangl triangle = &triangle->NeighborAcross(point); EdgeEvent( tcx, ep, *p1, triangle, *p1 ); } else { - std::runtime_error("EdgeEvent - collinear points not supported"); - assert(0); + throw std::runtime_error("EdgeEvent - collinear points not supported"); } return; } @@ -140,8 +139,7 @@ void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangl triangle = &triangle->NeighborAcross(point); EdgeEvent( tcx, ep, *p2, triangle, *p2 ); } else { - std::runtime_error("EdgeEvent - collinear points not supported"); - assert(0); + throw std::runtime_error("EdgeEvent - collinear points not supported"); } return; } diff --git a/testbed/data/deadly_quad.dat b/testbed/data/deadly_quad.dat new file mode 100644 index 0000000..7e4b217 --- /dev/null +++ b/testbed/data/deadly_quad.dat @@ -0,0 +1,4 @@ +0.0 0.0 +1.0e-05 0.0 +1.1e-04 3.0e-07 +1.0e-04 3.0e-07 diff --git a/unittest/main.cpp b/unittest/main.cpp index 6978b33..671b216 100644 --- a/unittest/main.cpp +++ b/unittest/main.cpp @@ -5,6 +5,7 @@ #include #include #include +#include BOOST_AUTO_TEST_CASE(BasicTest) { @@ -40,6 +41,22 @@ BOOST_AUTO_TEST_CASE(QuadTest) } } +BOOST_AUTO_TEST_CASE(QuadTestThrow) +{ + // Very narrow quad that demonstrates a failure case during triangulation + std::vector polyline { + new p2t::Point(0.0, 0.0), + new p2t::Point(1.0e-05, 0.0), + new p2t::Point(1.1e-04, 3.0e-07), + new p2t::Point(1.0e-04, 3.0e-07) + }; + p2t::CDT cdt{ polyline }; + BOOST_CHECK_THROW(cdt.Triangulate(), std::runtime_error); + for (const auto p : polyline) { + delete p; + } +} + BOOST_AUTO_TEST_CASE(TestbedFilesTest) { for (const auto& filename : { "custom.dat", "diamond.dat", "star.dat", "test.dat" }) {