diff --git a/indexer/indexer_tests/indexer_tests.pro b/indexer/indexer_tests/indexer_tests.pro index 0a15358af6..52fe3fbdea 100644 --- a/indexer/indexer_tests/indexer_tests.pro +++ b/indexer/indexer_tests/indexer_tests.pro @@ -34,3 +34,5 @@ SOURCES += \ scales_test.cpp \ test_polylines.cpp \ geometry_serialization_test.cpp \ + tesselator_test.cpp + diff --git a/indexer/indexer_tests/tesselator_test.cpp b/indexer/indexer_tests/tesselator_test.cpp new file mode 100644 index 0000000000..ad155001f1 --- /dev/null +++ b/indexer/indexer_tests/tesselator_test.cpp @@ -0,0 +1,45 @@ +#include "../../testing/testing.hpp" + +#include "../tesselator.hpp" + +#include "../../base/logging.hpp" + + +namespace +{ + typedef m2::PointD P; + + class DoDump + { + size_t & m_count; + public: + DoDump(size_t & count) : m_count(count) + { + m_count = 0; + } + void operator() (P const & p1, P const & p2, P const & p3) + { + ++m_count; + LOG(LINFO, (p1, p2, p3)); + } + }; + + size_t RunTess(P const * arr, size_t count) + { + list > l; + l.push_back(vector

()); + l.back().assign(arr, arr + count); + + tesselator::TrianglesInfo info; + tesselator::TesselateInterior(l, info); + + info.ForEachTriangle(DoDump(count)); + return count; + } +} + +UNIT_TEST(TesselatorSelfISect_Smoke) +{ + P arr[] = { P(0, 0), P(0, 4), P(4, 4), P(1, 1), P(1, 3), P(4, 0), P(0, 0) }; + TEST_EQUAL(6, RunTess(arr, ARRAY_SIZE(arr)), ()); +} diff --git a/indexer/tesselator.hpp b/indexer/tesselator.hpp index 27f847e8a6..0fcdf9d0fc 100644 --- a/indexer/tesselator.hpp +++ b/indexer/tesselator.hpp @@ -105,6 +105,7 @@ namespace tesselator public: void MakeTrianglesChain(PointsInfo const & points, iter_t start, vector & chain, bool goodOrder) const; + size_t GetCount() const { return m_triangles.size(); } Triangle GetTriangle(int i) const { return m_triangles[i]; } }; @@ -134,6 +135,19 @@ namespace tesselator inline bool IsEmpty() const { return m_triangles.empty(); } + template void ForEachTriangle(ToDo toDo) const + { + for (list::const_iterator i = m_triangles.begin(); i != m_triangles.end(); ++i) + { + size_t const count = i->GetCount(); + for (size_t j = 0; j < count; ++j) + { + Triangle const t = i->GetTriangle(j); + toDo(m_points[t.m_p[0]], m_points[t.m_p[1]], m_points[t.m_p[2]]); + } + } + } + // Convert points from double to uint. void GetPointsInfo(m2::PointU const & baseP, m2::PointU const & maxP, function const & convert, PointsInfo & info) const;