diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index f2fa65d1b..7129440a2 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -167,22 +167,6 @@ AsIfFlatRegion::in (const Region &other, bool invert) const return new_region.release (); } -size_t -AsIfFlatRegion::count () const -{ - size_t n = 0; - for (RegionIterator p (begin ()); ! p.at_end (); ++p) { - ++n; - } - return n; -} - -size_t -AsIfFlatRegion::hier_count () const -{ - return count (); -} - bool AsIfFlatRegion::is_box () const { diff --git a/src/db/db/dbAsIfFlatRegion.h b/src/db/db/dbAsIfFlatRegion.h index d2b8ff9e3..e7b54659b 100644 --- a/src/db/db/dbAsIfFlatRegion.h +++ b/src/db/db/dbAsIfFlatRegion.h @@ -47,8 +47,6 @@ public: virtual ~AsIfFlatRegion (); virtual bool is_box () const; - virtual size_t count () const; - virtual size_t hier_count () const; virtual area_type area (const db::Box &box) const; virtual perimeter_type perimeter (const db::Box &box) const; diff --git a/src/db/db/dbOriginalLayerRegion.cc b/src/db/db/dbOriginalLayerRegion.cc index 57b2a4380..24cac3333 100644 --- a/src/db/db/dbOriginalLayerRegion.cc +++ b/src/db/db/dbOriginalLayerRegion.cc @@ -29,6 +29,7 @@ #include "dbDeepEdges.h" #include "dbDeepRegion.h" #include "dbDeepShapeStore.h" +#include "dbCellGraphUtils.h" #include "tlGlobPattern.h" namespace db @@ -186,6 +187,78 @@ OriginalLayerRegion::min_coherence_changed () m_merged_polygons_valid = false; } +size_t +OriginalLayerRegion::count () const +{ + if (m_iter.has_complex_region () || m_iter.region () != db::Box::world ()) { + + // complex case with a search region - use the iterator to determine the count (expensive) + size_t n = 0; + for (db::RecursiveShapeIterator i = m_iter; ! i.at_end (); ++i) { + ++n; + } + + return n; + + } else { + + // otherwise we can utilize the CellCounter + + size_t n = 0; + + const db::Layout &layout = *m_iter.layout (); + + std::set cells; + m_iter.top_cell ()->collect_called_cells (cells); + + db::CellCounter cc (&layout); + for (db::Layout::top_down_const_iterator c = layout.begin_top_down (); c != layout.end_top_down (); ++c) { + if (cells.find (*c) == cells.end ()) { + continue; + } + size_t nn = 0; + for (std::vector::const_iterator l = m_iter.layers ().begin (); l != m_iter.layers ().end (); ++l) { + nn += layout.cell (*c).shapes (*l).size (m_iter.shape_flags ()); + } + n += cc.weight (*c) * nn; + } + + return n; + + } +} + +size_t +OriginalLayerRegion::hier_count () const +{ + if (m_iter.has_complex_region () || m_iter.region () != db::Box::world ()) { + + // TODO: how to establish a "hierarchical" interpretation in this case? + return count (); + + } else { + + size_t n = 0; + + const db::Layout &layout = *m_iter.layout (); + + std::set cells; + m_iter.top_cell ()->collect_called_cells (cells); + + for (db::Layout::top_down_const_iterator c = layout.begin_top_down (); c != layout.end_top_down (); ++c) { + if (cells.find (*c) == cells.end ()) { + continue; + } + for (std::vector::const_iterator l = m_iter.layers ().begin (); l != m_iter.layers ().end (); ++l) { + n += layout.cell (*c).shapes (*l).size (m_iter.shape_flags ()); + } + } + + return n; + + } +} + RegionIteratorDelegate * OriginalLayerRegion::begin () const { diff --git a/src/db/db/dbOriginalLayerRegion.h b/src/db/db/dbOriginalLayerRegion.h index 23af03bc9..1ea81d966 100644 --- a/src/db/db/dbOriginalLayerRegion.h +++ b/src/db/db/dbOriginalLayerRegion.h @@ -58,6 +58,8 @@ public: virtual bool empty () const; virtual bool is_merged () const; + virtual size_t count () const; + virtual size_t hier_count () const; virtual const db::Polygon *nth (size_t n) const; virtual bool has_valid_polygons () const; diff --git a/src/db/db/dbShapes.h b/src/db/db/dbShapes.h index 0fba8e9d8..41b05af42 100644 --- a/src/db/db/dbShapes.h +++ b/src/db/db/dbShapes.h @@ -1250,6 +1250,20 @@ public: return n; } + /** + * @brief Report the number of shapes stored for a given type mask + */ + size_t size (unsigned int flags) const + { + size_t n = 0; + for (tl::vector::const_iterator l = m_layers.begin (); l != m_layers.end (); ++l) { + if ((flags & (*l)->type_mask ()) != 0) { + n += (*l)->size (); + } + } + return n; + } + /** * @brief Report the shape count for a certain type */