From bfcb154531520d92041a4cad1639d6951c615397 Mon Sep 17 00:00:00 2001 From: vng Date: Sun, 16 Jan 2011 13:35:25 +0200 Subject: [PATCH] Build in stripified triangles in feature structure. --- indexer/feature.cpp | 28 +++++++++++- indexer/indexer_tool/feature_sorter.cpp | 60 +++++++++++++++++++++---- 2 files changed, 78 insertions(+), 10 deletions(-) diff --git a/indexer/feature.cpp b/indexer/feature.cpp index 9ddbc87aff..5b3ddbd7fa 100644 --- a/indexer/feature.cpp +++ b/indexer/feature.cpp @@ -48,6 +48,13 @@ void FeatureBuilder1::AddPoint(m2::PointD const & p) void FeatureBuilder1::SetAreaAddHoles(list > & holes) { + // this function is called from InitFeatureBuilder, when no geometry present + if (!m_Geometry.empty()) + { + ASSERT ( IsGeometryClosed(), () ); + m_Geometry.pop_back(); + } + m_bArea = true; m_Holes.swap(holes); @@ -377,7 +384,12 @@ void FeatureBuilder2::Serialize(buffers_holder_t & data) PushBackByteSink sink(data.m_buffer); uint8_t const ptsCount = static_cast(data.m_innerPts.size()); - uint8_t const trgCount = static_cast(data.m_innerTrg.size() / 3); + uint8_t trgCount = static_cast(data.m_innerTrg.size()); + if (trgCount > 0) + { + ASSERT_GREATER ( trgCount, 2, () ); + trgCount -= 2; + } BitSink< PushBackByteSink > bitSink(sink); @@ -775,7 +787,19 @@ void FeatureType::ParseHeader2() const if (commonH & HEADER_IS_AREA) { if (trgCount > 0) - ReadInnerPoints(src, m_Triangles, 3*trgCount); + { + trgCount += 2; + + points_t points; + ReadInnerPoints(src, points, trgCount); + + for (uint8_t i = 2; i < trgCount; ++i) + { + m_Triangles.push_back(points[i-2]); + m_Triangles.push_back(points[i-1]); + m_Triangles.push_back(points[i]); + } + } else ReadOffsets(src, trgMask, m_trgOffsets); } diff --git a/indexer/indexer_tool/feature_sorter.cpp b/indexer/indexer_tool/feature_sorter.cpp index f8492b0be4..04c7fad1de 100644 --- a/indexer/indexer_tool/feature_sorter.cpp +++ b/indexer/indexer_tool/feature_sorter.cpp @@ -10,6 +10,7 @@ #include "../../geometry/distance.hpp" #include "../../geometry/simplification.hpp" +#include "../../geometry/polygon.hpp" #include "../../platform/platform.hpp" @@ -213,6 +214,22 @@ namespace feature bool m_ptsInner, m_trgInner; + class strip_emitter + { + points_t const & m_src; + points_t & m_dest; + public: + strip_emitter(points_t const & src, points_t & dest) + : m_src(src), m_dest(dest) + { + m_dest.reserve(m_src.size()); + } + void operator() (size_t i) + { + m_dest.push_back(m_src[i]); + } + }; + public: GeometryHolder(FeaturesCollector2 & rMain, FeatureBuilder2 & fb) : m_rMain(rMain), m_rFB(fb), m_ptsInner(true), m_trgInner(true) @@ -246,18 +263,41 @@ namespace feature return (!m_trgInner || m_buffer.m_innerTrg.empty()); } - void AddTriangles(points_t & triangles, int scaleIndex) + bool TryToMakeStrip(points_t & points) { - if (m_trgInner && triangles.size() < 16) - { - if (m_buffer.m_innerTrg.empty()) - m_buffer.m_innerTrg.swap(triangles); - } - else + size_t const count = points.size(); + if (!m_trgInner || count > 15 + 2) { m_trgInner = false; - WriteOuterTriangles(triangles, scaleIndex); + return false; } + + ASSERT ( m_buffer.m_innerTrg.empty(), () ); + + if (!IsPolygonCCW(points.begin(), points.end())) + reverse(points.begin(), points.end()); + + size_t const index = FindSingleStrip(count, + IsDiagonalVisibleFunctor(points.begin(), points.end())); + + if (index == count) + { + m_trgInner = false; + return false; + } + + MakeSingleStripFromIndex(index, count, strip_emitter(points, m_buffer.m_innerTrg)); + + ASSERT_EQUAL ( count, m_buffer.m_innerTrg.size(), () ); + return true; + } + + void AddTriangles(points_t const & triangles, int scaleIndex) + { + ASSERT ( m_buffer.m_innerTrg.empty(), () ); + m_trgInner = false; + + WriteOuterTriangles(triangles, scaleIndex); } }; @@ -286,6 +326,10 @@ namespace feature // simplify and serialize triangles list const & holes = fb.GetHoles(); + + if (holes.empty() && holder.TryToMakeStrip(points)) + continue; + list simpleHoles; for (list::const_iterator iH = holes.begin(); iH != holes.end(); ++iH) {