| 610 | } |
| 611 | |
| 612 | FeatureType::GeomStat FeatureType::GetOuterTrianglesStats() |
| 613 | { |
| 614 | CHECK(m_loadInfo && m_parsed.m_relations && !m_parsed.m_triangles, ()); |
| 615 | int const scalesCount = m_loadInfo->GetScalesCount(); |
| 616 | ASSERT_LESS_OR_EQUAL(scalesCount, static_cast<int>(DataHeader::kMaxScalesCount), ()); |
| 617 | FeatureType::GeomStat res; |
| 618 | |
| 619 | auto const headerGeomType = static_cast<HeaderGeomType>(Header(m_data) & HEADER_MASK_GEOMTYPE); |
| 620 | if (headerGeomType == HeaderGeomType::Area) |
| 621 | { |
| 622 | if (m_triangles.empty()) |
| 623 | { |
| 624 | for (int ind = 0; ind < scalesCount; ++ind) |
| 625 | { |
| 626 | uint32_t const scaleOffset = m_offsets.m_trg[ind]; |
| 627 | if (IsRealGeomOffset(scaleOffset)) |
| 628 | { |
| 629 | m_triangles.clear(); |
| 630 | |
| 631 | ReaderSource<FilesContainerR::TReader> src(m_loadInfo->GetTrianglesReader(ind)); |
| 632 | src.Skip(scaleOffset); |
| 633 | serial::LoadOuterTriangles(src, m_loadInfo->GetGeometryCodingParams(ind), m_triangles); |
| 634 | |
| 635 | res.m_sizes[ind] = static_cast<uint32_t>(src.Pos() - scaleOffset); |
| 636 | res.m_elements[ind] = static_cast<uint32_t>(m_triangles.size() / 3); |
| 637 | } |
| 638 | } |
| 639 | // The best geometry is retained in m_triangles. |
| 640 | } |
| 641 | CalcRect(m_triangles, m_limitRect); |
| 642 | } |
| 643 | m_parsed.m_triangles = true; |
| 644 | |
| 645 | // Triangles count can come from the inner geometry. |
| 646 | res.m_elements[scalesCount - 1] = static_cast<uint32_t>(m_triangles.size() / 3); |
| 647 | return res; |
| 648 | } |
| 649 | |
| 650 | void FeatureType::ParseMetadata() |
| 651 | { |