From 1dfa5abc9a4d920edc5631d7bdb213beade826ac Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 8 Jan 2023 19:27:41 +0100 Subject: [PATCH] WIP: introducing properties for FlatRegion and others --- src/db/db/dbAsIfFlatRegion.cc | 89 ++++++++++++++++ src/db/db/dbAsIfFlatRegion.h | 1 + src/db/db/dbDeepEdgePairs.cc | 11 +- src/db/db/dbDeepEdges.cc | 11 +- src/db/db/dbDeepRegion.cc | 26 ++++- src/db/db/dbDeepRegion.h | 3 +- src/db/db/dbDeepTexts.cc | 11 +- src/db/db/dbEmptyRegion.h | 1 + src/db/db/dbFlatRegion.cc | 100 +++++++++--------- src/db/db/dbFlatRegion.h | 3 +- src/db/db/dbGenericShapeIterator.h | 26 +++++ src/db/db/dbLayoutToNetlist.cc | 6 +- src/db/db/dbLayoutToNetlist.h | 6 -- src/db/db/dbMutableRegion.cc | 39 +++++-- src/db/db/dbMutableRegion.h | 10 +- src/db/db/dbOriginalLayerEdgePairs.cc | 13 ++- src/db/db/dbOriginalLayerEdges.cc | 14 ++- src/db/db/dbOriginalLayerRegion.cc | 43 +++----- src/db/db/dbOriginalLayerRegion.h | 1 + src/db/db/dbOriginalLayerTexts.cc | 11 +- src/db/db/dbRegion.cc | 4 + src/db/db/dbRegion.h | 47 ++++++++ src/db/db/dbRegionDelegate.h | 1 + src/db/db/dbShapeProcessor.h | 13 ++- src/db/unit_tests/dbHierNetsProcessorTests.cc | 2 +- 25 files changed, 367 insertions(+), 125 deletions(-) diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index 6cf9d2180..1b8deb2ca 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -260,6 +260,95 @@ void AsIfFlatRegion::invalidate_bbox () m_bbox_valid = false; } +void AsIfFlatRegion::merge_polygons_to (db::Shapes &output, bool min_coherence, unsigned int min_wc) const +{ + db::EdgeProcessor ep (report_progress (), progress_desc ()); + ep.set_base_verbosity (base_verbosity ()); + + // count edges and reserve memory + size_t n = 0; + db::properties_id_type prop_id = 0; + bool need_split_props = false; + for (RegionIterator s (begin ()); ! s.at_end (); ++s, ++n) { + if (n == 0) { + prop_id = s.prop_id (); + } else if (! need_split_props && prop_id != s.prop_id ()) { + need_split_props = true; + } + } + + if (need_split_props) { + + db::Shapes result; + + std::vector > polygons_by_prop_id; + polygons_by_prop_id.reserve (n); + + db::AddressablePolygonDelivery addressable_polygons (begin ()); + while (! addressable_polygons.at_end ()) { + polygons_by_prop_id.push_back (std::make_pair (addressable_polygons.prop_id (), addressable_polygons.operator-> ())); + addressable_polygons.inc (); + } + + std::sort (polygons_by_prop_id.begin (), polygons_by_prop_id.end ()); + + for (auto p = polygons_by_prop_id.begin (); p != polygons_by_prop_id.end (); ) { + + auto pp = p; + while (pp != polygons_by_prop_id.end () && pp->first == p->first) { + ++pp; + } + + ep.clear (); + + n = 0; + for (auto i = p; i != pp; ++i) { + n += i->second->vertices (); + } + ep.reserve (n); + + n = 0; + for (auto i = p; i != pp; ++i, ++n) { + ep.insert (*i->second, n); + } + + // and run the merge step + db::MergeOp op (min_wc); + db::ShapeGenerator pc (result, false /*don't clear*/, p->first); + db::PolygonGenerator pg (pc, false /*don't resolve holes*/, min_coherence); + ep.process (pg, op); + + p = pp; + + } + + output.swap (result); + + } else { + + n = 0; + for (RegionIterator p (begin ()); ! p.at_end (); ++p) { + n += p->vertices (); + } + ep.reserve (n); + + // insert the polygons into the processor + n = 0; + for (RegionIterator p (begin ()); ! p.at_end (); ++p, ++n) { + ep.insert (*p, n); + } + + output.clear (); + + // and run the merge step + db::MergeOp op (min_wc); + db::ShapeGenerator pc (output, false /*don't clear*/, prop_id); + db::PolygonGenerator pg (pc, false /*don't resolve holes*/, min_coherence); + ep.process (pg, op); + + } +} + RegionDelegate * AsIfFlatRegion::filtered (const PolygonFilterBase &filter) const { diff --git a/src/db/db/dbAsIfFlatRegion.h b/src/db/db/dbAsIfFlatRegion.h index 998730d2b..687e99742 100644 --- a/src/db/db/dbAsIfFlatRegion.h +++ b/src/db/db/dbAsIfFlatRegion.h @@ -283,6 +283,7 @@ public: protected: void update_bbox (const db::Box &box); void invalidate_bbox (); + void merge_polygons_to (db::Shapes &output, bool min_coherence, unsigned int min_wc) const; virtual EdgePairsDelegate *run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, const RegionCheckOptions &options) const; virtual EdgePairsDelegate *run_single_polygon_check (db::edge_relation_type rel, db::Coord d, const RegionCheckOptions &options) const; diff --git a/src/db/db/dbDeepEdgePairs.cc b/src/db/db/dbDeepEdgePairs.cc index 1bfd00358..d6b897e99 100644 --- a/src/db/db/dbDeepEdgePairs.cc +++ b/src/db/db/dbDeepEdgePairs.cc @@ -44,7 +44,7 @@ public: typedef db::EdgePair value_type; DeepEdgePairsIterator (const db::RecursiveShapeIterator &iter) - : m_iter (iter) + : m_iter (iter), m_prop_id (0) { set (); } @@ -72,6 +72,11 @@ public: return &m_edge_pair; } + virtual db::properties_id_type prop_id () const + { + return m_prop_id; + } + virtual bool equals (const generic_shape_iterator_delegate_base *other) const { const DeepEdgePairsIterator *o = dynamic_cast (other); @@ -100,12 +105,14 @@ private: db::RecursiveShapeIterator m_iter; mutable value_type m_edge_pair; + mutable db::properties_id_type m_prop_id; void set () const { if (! m_iter.at_end ()) { - m_iter.shape ().edge_pair (m_edge_pair); + m_iter->edge_pair (m_edge_pair); m_edge_pair.transform (m_iter.trans ()); + m_prop_id = m_iter->prop_id (); } } }; diff --git a/src/db/db/dbDeepEdges.cc b/src/db/db/dbDeepEdges.cc index 720863a31..d5c6f04f1 100644 --- a/src/db/db/dbDeepEdges.cc +++ b/src/db/db/dbDeepEdges.cc @@ -54,7 +54,7 @@ public: typedef db::Edge value_type; DeepEdgesIterator (const db::RecursiveShapeIterator &iter) - : m_iter (iter) + : m_iter (iter), m_prop_id (0) { set (); } @@ -82,6 +82,11 @@ public: return &m_edge; } + virtual db::properties_id_type prop_id () const + { + return m_prop_id; + } + virtual bool equals (const generic_shape_iterator_delegate_base *other) const { const DeepEdgesIterator *o = dynamic_cast (other); @@ -110,12 +115,14 @@ private: db::RecursiveShapeIterator m_iter; mutable value_type m_edge; + mutable db::properties_id_type m_prop_id; void set () const { if (! m_iter.at_end ()) { - m_iter.shape ().edge (m_edge); + m_iter->edge (m_edge); m_edge.transform (m_iter.trans ()); + m_prop_id = m_iter->prop_id (); } } }; diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 74402c33e..1691218eb 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -57,7 +57,7 @@ public: typedef db::Polygon value_type; DeepRegionIterator (const db::RecursiveShapeIterator &iter) - : m_iter (iter) + : m_iter (iter), m_prop_id (0) { set (); } @@ -85,6 +85,11 @@ public: return &m_polygon; } + virtual db::properties_id_type prop_id () const + { + return m_prop_id; + } + virtual bool equals (const generic_shape_iterator_delegate_base *other) const { const DeepRegionIterator *o = dynamic_cast (other); @@ -113,12 +118,14 @@ private: db::RecursiveShapeIterator m_iter; mutable value_type m_polygon; + mutable db::properties_id_type m_prop_id; void set () const { if (! m_iter.at_end ()) { - m_iter.shape ().polygon (m_polygon); + m_iter->polygon (m_polygon); m_polygon.transform (m_iter.trans (), false); + m_prop_id = m_iter->prop_id (); } } }; @@ -220,12 +227,17 @@ void DeepRegion::min_coherence_changed () set_is_merged (false); } -void DeepRegion::do_insert (const db::Polygon &polygon) +void DeepRegion::do_insert (const db::Polygon &polygon, db::properties_id_type prop_id) { db::Layout &layout = deep_layer ().layout (); if (layout.begin_top_down () != layout.end_top_down ()) { db::Cell &top_cell = layout.cell (*layout.begin_top_down ()); - top_cell.shapes (deep_layer ().layer ()).insert (db::PolygonRef (polygon, layout.shape_repository ())); + db::Shapes &shapes = top_cell.shapes (deep_layer ().layer ()); + if (prop_id == 0) { + shapes.insert (db::PolygonRef (polygon, layout.shape_repository ())); + } else { + shapes.insert (db::PolygonRefWithProperties (db::PolygonRef (polygon, layout.shape_repository ()), prop_id)); + } } invalidate_bbox (); @@ -439,6 +451,12 @@ DeepRegion::nth (size_t) const throw tl::Exception (tl::to_string (tr ("Random access to polygons is available only for flat regions"))); } +db::properties_id_type +DeepRegion::nth_prop_id (size_t) const +{ + throw tl::Exception (tl::to_string (tr ("Random access to polygons is available only for flat regions"))); +} + bool DeepRegion::has_valid_polygons () const { diff --git a/src/db/db/dbDeepRegion.h b/src/db/db/dbDeepRegion.h index 9b08a4bf2..9ff3d838d 100644 --- a/src/db/db/dbDeepRegion.h +++ b/src/db/db/dbDeepRegion.h @@ -53,7 +53,7 @@ public: RegionDelegate *clone () const; - virtual void do_insert (const db::Polygon &polygon); + virtual void do_insert (const db::Polygon &polygon, db::properties_id_type prop_id); virtual void do_transform (const db::Trans &t); virtual void do_transform (const db::ICplxTrans &t); @@ -74,6 +74,7 @@ public: virtual bool is_merged () const; virtual const db::Polygon *nth (size_t n) const; + virtual db::properties_id_type nth_prop_id (size_t n) const; virtual bool has_valid_polygons () const; virtual bool has_valid_merged_polygons () const; diff --git a/src/db/db/dbDeepTexts.cc b/src/db/db/dbDeepTexts.cc index b160f88ba..ef6779ccb 100644 --- a/src/db/db/dbDeepTexts.cc +++ b/src/db/db/dbDeepTexts.cc @@ -49,7 +49,7 @@ public: typedef db::Text value_type; DeepTextsIterator (const db::RecursiveShapeIterator &iter) - : m_iter (iter) + : m_iter (iter), m_prop_id (0) { set (); } @@ -77,6 +77,11 @@ public: return &m_text; } + virtual db::properties_id_type prop_id () const + { + return m_prop_id; + } + virtual bool equals (const generic_shape_iterator_delegate_base *other) const { const DeepTextsIterator *o = dynamic_cast (other); @@ -105,12 +110,14 @@ private: db::RecursiveShapeIterator m_iter; mutable value_type m_text; + mutable db::properties_id_type m_prop_id; void set () const { if (! m_iter.at_end ()) { - m_iter.shape ().text (m_text); + m_iter->text (m_text); m_text.transform (m_iter.trans ()); + m_prop_id = m_iter->prop_id (); } } }; diff --git a/src/db/db/dbEmptyRegion.h b/src/db/db/dbEmptyRegion.h index 44270bdbb..392c205b2 100644 --- a/src/db/db/dbEmptyRegion.h +++ b/src/db/db/dbEmptyRegion.h @@ -138,6 +138,7 @@ public: virtual bool has_valid_polygons () const { return true; } virtual bool has_valid_merged_polygons () const { return true; } virtual const db::Polygon *nth (size_t) const { tl_assert (false); } + virtual db::properties_id_type nth_prop_id (size_t) const { tl_assert (false); } virtual const db::RecursiveShapeIterator *iter () const { return 0; } diff --git a/src/db/db/dbFlatRegion.cc b/src/db/db/dbFlatRegion.cc index 72e884f02..481f3c3e8 100644 --- a/src/db/db/dbFlatRegion.cc +++ b/src/db/db/dbFlatRegion.cc @@ -25,6 +25,7 @@ #include "dbEmptyRegion.h" #include "dbRegion.h" #include "dbShapeProcessor.h" +#include "tlSList.h" namespace db { @@ -108,33 +109,8 @@ void FlatRegion::ensure_merged_polygons_valid () const { if (! m_merged_polygons_valid) { - - mp_merged_polygons->clear (); - - db::EdgeProcessor ep (report_progress (), progress_desc ()); - ep.set_base_verbosity (base_verbosity ()); - - // count edges and reserve memory - size_t n = 0; - for (RegionIterator p (begin ()); ! p.at_end (); ++p) { - n += p->vertices (); - } - ep.reserve (n); - - // insert the polygons into the processor - n = 0; - for (RegionIterator p (begin ()); ! p.at_end (); ++p, ++n) { - ep.insert (*p, n); - } - - // and run the merge step - db::MergeOp op (0); - db::ShapeGenerator pc (*mp_merged_polygons); - db::PolygonGenerator pg (pc, false /*don't resolve holes*/, min_coherence ()); - ep.process (pg, op); - + merge_polygons_to (*mp_merged_polygons, min_coherence (), 0); m_merged_polygons_valid = true; - } } @@ -279,28 +255,7 @@ RegionDelegate *FlatRegion::merged_in_place (bool min_coherence, unsigned int mi } else { invalidate_cache (); - - db::EdgeProcessor ep (report_progress (), progress_desc ()); - ep.set_base_verbosity (base_verbosity ()); - - // count edges and reserve memory - size_t n = 0; - for (RegionIterator p (begin ()); ! p.at_end (); ++p) { - n += p->vertices (); - } - ep.reserve (n); - - // insert the polygons into the processor - n = 0; - for (RegionIterator p (begin ()); ! p.at_end (); ++p, ++n) { - ep.insert (*p, n); - } - - // and run the merge step - db::MergeOp op (min_wc); - db::ShapeGenerator pc (*mp_polygons, true /*clear*/); - db::PolygonGenerator pg (pc, false /*don't resolve holes*/, min_coherence); - ep.process (pg, op); + merge_polygons_to (*mp_polygons, min_coherence, min_wc); m_is_merged = true; @@ -385,7 +340,46 @@ RegionDelegate *FlatRegion::add_in_place (const Region &other) const db::Polygon *FlatRegion::nth (size_t n) const { - return n < mp_polygons->size () ? &mp_polygons->get_layer ().begin () [n] : 0; + // NOTE: this assumes that we iterate over non-property polygons first and then over polygons with properties + + if (n >= mp_polygons->size ()) { + return 0; + } + + const db::layer &l = mp_polygons->get_layer (); + if (n < l.size ()) { + return &l.begin () [n]; + } + n -= l.size (); + + const db::layer &lp = mp_polygons->get_layer (); + if (n < lp.size ()) { + return &lp.begin () [n]; + } + + return 0; +} + +db::properties_id_type FlatRegion::nth_prop_id (size_t n) const +{ + // NOTE: this assumes that we iterate over non-property polygons first and then over polygons with properties + + if (n >= mp_polygons->size ()) { + return 0; + } + + const db::layer &l = mp_polygons->get_layer (); + if (n < l.size ()) { + return 0; + } + n -= l.size (); + + const db::layer &lp = mp_polygons->get_layer (); + if (n < lp.size ()) { + return lp.begin () [n].properties_id (); + } + + return 0; } bool FlatRegion::has_valid_polygons () const @@ -409,13 +403,17 @@ void FlatRegion::insert_into (Layout *layout, db::cell_index_type into_cell, uns } void -FlatRegion::do_insert (const db::Polygon &polygon) +FlatRegion::do_insert (const db::Polygon &polygon, properties_id_type prop_id) { if (polygon.holes () > 0 || polygon.vertices () > 0) { bool is_box = (empty () && polygon.is_box ()); - mp_polygons->insert (polygon); + if (prop_id != 0) { + mp_polygons->insert (db::PolygonWithProperties (polygon, prop_id)); + } else { + mp_polygons->insert (polygon); + } set_is_merged (is_box); invalidate_cache (); diff --git a/src/db/db/dbFlatRegion.h b/src/db/db/dbFlatRegion.h index 7ec9b9fbb..5c6c8c854 100644 --- a/src/db/db/dbFlatRegion.h +++ b/src/db/db/dbFlatRegion.h @@ -92,12 +92,13 @@ public: virtual RegionDelegate *add (const Region &other) const; virtual const db::Polygon *nth (size_t n) const; + virtual db::properties_id_type nth_prop_id (size_t) const; virtual bool has_valid_polygons () const; virtual bool has_valid_merged_polygons () const; virtual const db::RecursiveShapeIterator *iter () const; - void do_insert (const db::Polygon &polygon); + void do_insert (const db::Polygon &polygon, db::properties_id_type prop_id); void do_transform (const db::Trans &t) { diff --git a/src/db/db/dbGenericShapeIterator.h b/src/db/db/dbGenericShapeIterator.h index 20f280ce1..4510a0d39 100644 --- a/src/db/db/dbGenericShapeIterator.h +++ b/src/db/db/dbGenericShapeIterator.h @@ -46,6 +46,7 @@ public: virtual bool at_end () const = 0; virtual void increment () = 0; virtual const T *get () const = 0; + virtual db::properties_id_type prop_id () const = 0; virtual generic_shape_iterator_delegate_base *clone () const = 0; virtual bool equals (const generic_shape_iterator_delegate_base *other) const = 0; }; @@ -86,6 +87,11 @@ public: return m_iter.operator-> (); } + virtual db::properties_id_type prop_id () const + { + return 0; + } + generic_shape_iterator_delegate_base *clone () const { return new generic_shape_iterator_delegate2 (*this); @@ -141,6 +147,11 @@ public: return m_iter.operator-> (); } + virtual db::properties_id_type prop_id () const + { + return 0; + } + generic_shape_iterator_delegate_base *clone () const { return new generic_shape_iterator_delegate1 (*this); @@ -217,6 +228,11 @@ public: } } + virtual db::properties_id_type prop_id () const + { + return m_iter->prop_id (); + } + generic_shape_iterator_delegate_base *clone () const { return new generic_shapes_iterator_delegate (*this); @@ -319,6 +335,11 @@ public: return ! mp_delegate || mp_delegate->is_addressable (); } + db::properties_id_type prop_id () const + { + return mp_delegate ? mp_delegate->prop_id () : 0; + } + reference operator* () const { return *mp_delegate->get (); @@ -422,6 +443,11 @@ public: } } + db::properties_id_type prop_id () const + { + return m_iter.prop_id (); + } + private: Iter m_iter; bool m_iterator_is_addressable; diff --git a/src/db/db/dbLayoutToNetlist.cc b/src/db/db/dbLayoutToNetlist.cc index 78dbc813d..a18122ff4 100644 --- a/src/db/db/dbLayoutToNetlist.cc +++ b/src/db/db/dbLayoutToNetlist.cc @@ -986,11 +986,7 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout & db::properties_id_type LayoutToNetlist::make_netname_propid (db::Layout &ly, NetPropertyMode net_prop_mode, const tl::Variant &netname_prop, const db::Net &net) const { - if (net_prop_mode == FakePropId) { - - return reinterpret_cast (&net); - - } else if (net_prop_mode == NoProperties) { + if (net_prop_mode == NoProperties) { return 0; diff --git a/src/db/db/dbLayoutToNetlist.h b/src/db/db/dbLayoutToNetlist.h index 613f0edf6..5f8529821 100644 --- a/src/db/db/dbLayoutToNetlist.h +++ b/src/db/db/dbLayoutToNetlist.h @@ -727,12 +727,6 @@ public: * @brief Like NetNameOnly, but use a unique net ID (db::Net address actually) instead of name */ NetIDOnly, - - /** - * @brief Use the net ID (db::Net address) directly as property ID - * Caution: you need to know what you're doing if you use that mode. - */ - FakePropId }; /** diff --git a/src/db/db/dbMutableRegion.cc b/src/db/db/dbMutableRegion.cc index 9180b6f14..2b4042d02 100644 --- a/src/db/db/dbMutableRegion.cc +++ b/src/db/db/dbMutableRegion.cc @@ -50,7 +50,15 @@ void MutableRegion::insert (const db::Box &box) { if (! box.empty () && box.width () > 0 && box.height () > 0) { - do_insert (db::Polygon (box)); + do_insert (db::Polygon (box), 0); + } +} + +void +MutableRegion::insert (const db::BoxWithProperties &box) +{ + if (! box.empty () && box.width () > 0 && box.height () > 0) { + do_insert (db::Polygon (box), box.properties_id ()); } } @@ -58,7 +66,15 @@ void MutableRegion::insert (const db::Path &path) { if (path.points () > 0) { - do_insert (path.polygon ()); + do_insert (path.polygon (), 0); + } +} + +void +MutableRegion::insert (const db::PathWithProperties &path) +{ + if (path.points () > 0) { + do_insert (path.polygon (), path.properties_id ()); } } @@ -68,7 +84,17 @@ MutableRegion::insert (const db::SimplePolygon &polygon) if (polygon.vertices () > 0) { db::Polygon poly; poly.assign_hull (polygon.begin_hull (), polygon.end_hull ()); - do_insert (poly); + do_insert (poly, 0); + } +} + +void +MutableRegion::insert (const db::SimplePolygonWithProperties &polygon) +{ + if (polygon.vertices () > 0) { + db::Polygon poly; + poly.assign_hull (polygon.begin_hull (), polygon.end_hull ()); + do_insert (poly, polygon.properties_id ()); } } @@ -78,13 +104,8 @@ MutableRegion::insert (const db::Shape &shape) if (shape.is_polygon () || shape.is_path () || shape.is_box ()) { db::Polygon poly; shape.polygon (poly); - insert (poly); - } else if (shape.is_path ()) { - insert (shape.path ()); - } else if (shape.is_box ()) { - insert (shape.box ()); + do_insert (poly, shape.prop_id ()); } } } - diff --git a/src/db/db/dbMutableRegion.h b/src/db/db/dbMutableRegion.h index 94e8fd614..c6d8d0ab3 100644 --- a/src/db/db/dbMutableRegion.h +++ b/src/db/db/dbMutableRegion.h @@ -45,7 +45,7 @@ public: MutableRegion (const MutableRegion &other); virtual ~MutableRegion (); - virtual void do_insert (const db::Polygon &polygon) = 0; + virtual void do_insert (const db::Polygon &polygon, db::properties_id_type prop_id) = 0; void transform (const db::UnitTrans &) { } void transform (const db::Disp &t) { do_transform (db::Trans (t)); } @@ -63,10 +63,14 @@ public: virtual void reserve (size_t n) = 0; - void insert (const db::Polygon &polygon) { do_insert (polygon); } + void insert (const db::Polygon &polygon) { do_insert (polygon, 0); } + void insert (const db::PolygonWithProperties &polygon) { do_insert (polygon, polygon.properties_id ()); } void insert (const db::Box &box); + void insert (const db::BoxWithProperties &box); void insert (const db::Path &path); + void insert (const db::PathWithProperties &path); void insert (const db::SimplePolygon &polygon); + void insert (const db::SimplePolygonWithProperties &polygon); void insert (const db::Shape &shape); @@ -77,7 +81,7 @@ public: db::Polygon poly; shape.polygon (poly); poly.transform (trans); - insert (poly); + do_insert (poly, shape.prop_id ()); } } diff --git a/src/db/db/dbOriginalLayerEdgePairs.cc b/src/db/db/dbOriginalLayerEdgePairs.cc index 4904431ff..475e9e9a7 100644 --- a/src/db/db/dbOriginalLayerEdgePairs.cc +++ b/src/db/db/dbOriginalLayerEdgePairs.cc @@ -41,7 +41,7 @@ namespace typedef db::EdgePair value_type; OriginalLayerEdgePairsIterator (const db::RecursiveShapeIterator &iter, const db::ICplxTrans &trans) - : m_rec_iter (iter), m_iter_trans (trans) + : m_rec_iter (iter), m_iter_trans (trans), m_prop_id (0) { set (); } @@ -67,6 +67,11 @@ namespace return &m_shape; } + virtual db::properties_id_type prop_id () const + { + return m_prop_id; + } + virtual EdgePairsIteratorDelegate *clone () const { return new OriginalLayerEdgePairsIterator (*this); @@ -100,15 +105,17 @@ namespace db::RecursiveShapeIterator m_rec_iter; db::ICplxTrans m_iter_trans; value_type m_shape; + db::properties_id_type m_prop_id; void set () { - while (! m_rec_iter.at_end () && !m_rec_iter.shape ().is_edge_pair ()) { + while (! m_rec_iter.at_end () && !m_rec_iter->is_edge_pair ()) { ++m_rec_iter; } if (! m_rec_iter.at_end ()) { - m_rec_iter.shape ().edge_pair (m_shape); + m_rec_iter->edge_pair (m_shape); m_shape.transform (m_iter_trans * m_rec_iter.trans ()); + m_prop_id = (m_rec_iter.shape_flags () & db::ShapeIterator::Properties) != 0 ? m_rec_iter->prop_id () : 0; } } diff --git a/src/db/db/dbOriginalLayerEdges.cc b/src/db/db/dbOriginalLayerEdges.cc index 791ac0841..41a8ae769 100644 --- a/src/db/db/dbOriginalLayerEdges.cc +++ b/src/db/db/dbOriginalLayerEdges.cc @@ -42,7 +42,7 @@ namespace typedef db::Edge value_type; OriginalLayerEdgesIterator (const db::RecursiveShapeIterator &iter, const db::ICplxTrans &trans) - : m_rec_iter (iter), m_iter_trans (trans) + : m_rec_iter (iter), m_iter_trans (trans), m_prop_id (0) { set (); } @@ -68,6 +68,11 @@ namespace return &m_shape; } + virtual db::properties_id_type prop_id () const + { + return m_prop_id; + } + virtual EdgesIteratorDelegate *clone () const { return new OriginalLayerEdgesIterator (*this); @@ -101,15 +106,17 @@ namespace db::RecursiveShapeIterator m_rec_iter; db::ICplxTrans m_iter_trans; value_type m_shape; + db::properties_id_type m_prop_id; void set () { - while (! m_rec_iter.at_end () && !m_rec_iter.shape ().is_edge ()) { + while (! m_rec_iter.at_end () && !m_rec_iter->is_edge ()) { ++m_rec_iter; } if (! m_rec_iter.at_end ()) { - m_rec_iter.shape ().edge (m_shape); + m_rec_iter->edge (m_shape); m_shape.transform (m_iter_trans * m_rec_iter.trans ()); + m_prop_id = (m_rec_iter.shape_flags () & db::ShapeIterator::Properties) != 0 ? m_rec_iter->prop_id () : 0; } } @@ -120,7 +127,6 @@ namespace } } }; - } OriginalLayerEdges::OriginalLayerEdges () diff --git a/src/db/db/dbOriginalLayerRegion.cc b/src/db/db/dbOriginalLayerRegion.cc index ea870226e..7d30e8079 100644 --- a/src/db/db/dbOriginalLayerRegion.cc +++ b/src/db/db/dbOriginalLayerRegion.cc @@ -25,7 +25,6 @@ #include "dbFlatRegion.h" #include "dbFlatEdges.h" #include "dbRegion.h" -#include "dbShapeProcessor.h" #include "dbDeepEdges.h" #include "dbDeepRegion.h" #include "dbDeepShapeStore.h" @@ -46,7 +45,7 @@ namespace { public: OriginalLayerRegionIterator (const db::RecursiveShapeIterator &iter, const db::ICplxTrans &trans) - : m_rec_iter (iter), m_iter_trans (trans) + : m_rec_iter (iter), m_iter_trans (trans), m_prop_id (0) { set (); } @@ -72,6 +71,11 @@ namespace return &m_polygon; } + virtual db::properties_id_type prop_id () const + { + return m_prop_id; + } + virtual RegionIteratorDelegate *clone () const { return new OriginalLayerRegionIterator (*this); @@ -105,15 +109,17 @@ namespace db::RecursiveShapeIterator m_rec_iter; db::ICplxTrans m_iter_trans; db::Polygon m_polygon; + db::properties_id_type m_prop_id; void set () { - while (! m_rec_iter.at_end () && ! (m_rec_iter.shape ().is_polygon () || m_rec_iter.shape ().is_path () || m_rec_iter.shape ().is_box ())) { + while (! m_rec_iter.at_end () && ! (m_rec_iter->is_polygon () || m_rec_iter->is_path () || m_rec_iter->is_box ())) { ++m_rec_iter; } if (! m_rec_iter.at_end ()) { - m_rec_iter.shape ().polygon (m_polygon); + m_rec_iter->polygon (m_polygon); m_polygon.transform (m_iter_trans * m_rec_iter.trans (), false); + m_prop_id = (m_rec_iter.shape_flags () & db::ShapeIterator::Properties) != 0 ? m_rec_iter->prop_id () : 0; } } @@ -339,6 +345,12 @@ OriginalLayerRegion::nth (size_t) const throw tl::Exception (tl::to_string (tr ("Random access to polygons is available only for flat regions"))); } +db::properties_id_type +OriginalLayerRegion::nth_prop_id (size_t) const +{ + throw tl::Exception (tl::to_string (tr ("Random access to polygons is available only for flat regions"))); +} + bool OriginalLayerRegion::has_valid_polygons () const { @@ -412,28 +424,7 @@ OriginalLayerRegion::ensure_merged_polygons_valid () const if (! m_merged_polygons_valid) { m_merged_polygons.clear (); - - db::EdgeProcessor ep (report_progress (), progress_desc ()); - ep.set_base_verbosity (base_verbosity ()); - - // count edges and reserve memory - size_t n = 0; - for (RegionIterator p (begin ()); ! p.at_end (); ++p) { - n += p->vertices (); - } - ep.reserve (n); - - // insert the polygons into the processor - n = 0; - for (RegionIterator p (begin ()); ! p.at_end (); ++p, ++n) { - ep.insert (*p, n); - } - - // and run the merge step - db::MergeOp op (0); - db::ShapeGenerator pc (m_merged_polygons); - db::PolygonGenerator pg (pc, false /*don't resolve holes*/, min_coherence ()); - ep.process (pg, op); + merge_polygons_to (m_merged_polygons, min_coherence (), 0); m_merged_polygons_valid = true; diff --git a/src/db/db/dbOriginalLayerRegion.h b/src/db/db/dbOriginalLayerRegion.h index 702a36aca..cc6ccbfae 100644 --- a/src/db/db/dbOriginalLayerRegion.h +++ b/src/db/db/dbOriginalLayerRegion.h @@ -62,6 +62,7 @@ public: virtual size_t hier_count () const; virtual const db::Polygon *nth (size_t n) const; + virtual db::properties_id_type nth_prop_id (size_t) const; virtual bool has_valid_polygons () const; virtual bool has_valid_merged_polygons () const; diff --git a/src/db/db/dbOriginalLayerTexts.cc b/src/db/db/dbOriginalLayerTexts.cc index e80a994b4..739635791 100644 --- a/src/db/db/dbOriginalLayerTexts.cc +++ b/src/db/db/dbOriginalLayerTexts.cc @@ -41,7 +41,7 @@ namespace typedef db::Text value_type; OriginalLayerTextsIterator (const db::RecursiveShapeIterator &iter, const db::ICplxTrans &trans) - : m_rec_iter (iter), m_iter_trans (trans) + : m_rec_iter (iter), m_iter_trans (trans), m_prop_id (0) { set (); } @@ -67,6 +67,11 @@ namespace return &m_shape; } + virtual db::properties_id_type prop_id () const + { + return m_prop_id; + } + virtual OriginalLayerTextsIterator *clone () const { return new OriginalLayerTextsIterator (*this); @@ -100,6 +105,7 @@ namespace db::RecursiveShapeIterator m_rec_iter; db::ICplxTrans m_iter_trans; value_type m_shape; + db::properties_id_type m_prop_id; void set () { @@ -107,8 +113,9 @@ namespace ++m_rec_iter; } if (! m_rec_iter.at_end ()) { - m_rec_iter.shape ().text (m_shape); + m_rec_iter->text (m_shape); m_shape.transform (m_iter_trans * m_rec_iter.trans ()); + m_prop_id = (m_rec_iter.shape_flags () & db::ShapeIterator::Properties) != 0 ? m_rec_iter->prop_id () : 0; } } diff --git a/src/db/db/dbRegion.cc b/src/db/db/dbRegion.cc index 6e2cfc065..c40bcfdcb 100644 --- a/src/db/db/dbRegion.cc +++ b/src/db/db/dbRegion.cc @@ -155,9 +155,13 @@ void Region::insert (const Sh &shape) } template DB_PUBLIC void Region::insert (const db::Box &); +template DB_PUBLIC void Region::insert (const db::BoxWithProperties &); template DB_PUBLIC void Region::insert (const db::SimplePolygon &); +template DB_PUBLIC void Region::insert (const db::SimplePolygonWithProperties &); template DB_PUBLIC void Region::insert (const db::Polygon &); +template DB_PUBLIC void Region::insert (const db::PolygonWithProperties &); template DB_PUBLIC void Region::insert (const db::Path &); +template DB_PUBLIC void Region::insert (const db::PathWithProperties &); void Region::insert (const db::Shape &shape) { diff --git a/src/db/db/dbRegion.h b/src/db/db/dbRegion.h index ec1c0fc00..3cb23930e 100644 --- a/src/db/db/dbRegion.h +++ b/src/db/db/dbRegion.h @@ -168,6 +168,15 @@ public: insert (s); } + /** + * @brief Constructor from a box with properties + */ + explicit Region (const db::BoxWithProperties &s) + : mp_delegate (0) + { + insert (s); + } + /** * @brief Constructor from a polygon */ @@ -177,6 +186,15 @@ public: insert (s); } + /** + * @brief Constructor from a polygon with properties + */ + explicit Region (const db::PolygonWithProperties &s) + : mp_delegate (0) + { + insert (s); + } + /** * @brief Constructor from a simple polygon */ @@ -186,6 +204,15 @@ public: insert (s); } + /** + * @brief Constructor from a simple polygon with properties + */ + explicit Region (const db::SimplePolygonWithProperties &s) + : mp_delegate (0) + { + insert (s); + } + /** * @brief Constructor from a path */ @@ -195,6 +222,15 @@ public: insert (s); } + /** + * @brief Constructor from a path with properties + */ + explicit Region (const db::PathWithProperties &s) + : mp_delegate (0) + { + insert (s); + } + /** * @brief Sequence constructor * @@ -1652,6 +1688,17 @@ public: return mp_delegate->nth (n); } + /** + * @brief Returns the nth polygon's property ID + * + * This operation is available only for flat regions - i.e. such for which + * "has_valid_polygons" is true. + */ + db::properties_id_type nth_prop_id (size_t n) const + { + return mp_delegate->nth_prop_id (n); + } + /** * @brief Forces flattening of the region * diff --git a/src/db/db/dbRegionDelegate.h b/src/db/db/dbRegionDelegate.h index ed0d812ff..d3a590d0d 100644 --- a/src/db/db/dbRegionDelegate.h +++ b/src/db/db/dbRegionDelegate.h @@ -311,6 +311,7 @@ public: virtual std::pair in_and_out (const Region &other) const = 0; virtual const db::Polygon *nth (size_t n) const = 0; + virtual db::properties_id_type nth_prop_id (size_t n) const = 0; virtual bool has_valid_polygons () const = 0; virtual bool has_valid_merged_polygons () const = 0; diff --git a/src/db/db/dbShapeProcessor.h b/src/db/db/dbShapeProcessor.h index a532a69ec..a5aa2cc4b 100644 --- a/src/db/db/dbShapeProcessor.h +++ b/src/db/db/dbShapeProcessor.h @@ -56,10 +56,12 @@ public: * the start method is called and when the shape container is cleared if "clear_shapes" * is set. * + * @param shapes Where to store the shapes * @param clear_shapes If true, the shapes container is cleared on the start event. + * @param prop_id The properties ID to assign to all the output shapes (or 0 if no property shall be assigned) */ - ShapeGenerator (db::Shapes &shapes, bool clear_shapes = false) - : PolygonSink (), mp_shapes (&shapes), m_clear_shapes (clear_shapes) + ShapeGenerator (db::Shapes &shapes, bool clear_shapes = false, db::properties_id_type prop_id = 0) + : PolygonSink (), mp_shapes (&shapes), m_clear_shapes (clear_shapes), m_prop_id (prop_id) { } /** @@ -67,7 +69,11 @@ public: */ virtual void put (const db::Polygon &polygon) { - mp_shapes->insert (polygon); + if (m_prop_id) { + mp_shapes->insert (db::PolygonWithProperties (polygon, m_prop_id)); + } else { + mp_shapes->insert (polygon); + } } /** @@ -85,6 +91,7 @@ public: private: db::Shapes *mp_shapes; bool m_clear_shapes; + db::properties_id_type m_prop_id; }; /** diff --git a/src/db/unit_tests/dbHierNetsProcessorTests.cc b/src/db/unit_tests/dbHierNetsProcessorTests.cc index 8cec23abb..91b4d4441 100644 --- a/src/db/unit_tests/dbHierNetsProcessorTests.cc +++ b/src/db/unit_tests/dbHierNetsProcessorTests.cc @@ -210,7 +210,7 @@ TEST(0_Develop) lmap_write [wvia1 = ly2.insert_layer (db::LayerProperties (16, 0))] = l2n.layer_by_name ("via1"); lmap_write [wmetal2 = ly2.insert_layer (db::LayerProperties (17, 0))] = l2n.layer_by_name ("metal2"); - l2n.build_all_nets (cm, ly2, lmap_write, "NET_", db::LayoutToNetlist::FakePropId, tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "SC_", 0 /*don't produce devices*/); + l2n.build_all_nets (cm, ly2, lmap_write, "NET_", db::LayoutToNetlist::NetIDOnly, tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "SC_", 0 /*don't produce devices*/); unsigned int out = ly2.insert_layer (db::LayerProperties (1000, 0));