From 0f2d0605a9412f8dba0a980e3d143d18e22b4374 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 20 Feb 2019 01:17:14 +0100 Subject: [PATCH] Some more refactoring - generalized polygon processing in region. --- src/db/db/dbDeepRegion.cc | 103 ++++++++++++++++++++++++----------- src/db/db/dbRegion.cc | 5 ++ src/db/db/dbRegionDelegate.h | 52 ++++++++++++++++++ src/db/db/dbRegionUtils.h | 50 +++++++++++++++++ 4 files changed, 178 insertions(+), 32 deletions(-) diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index de053396a..9fdb131f6 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -926,41 +926,57 @@ DeepRegion::processed (const PolygonProcessorBase &filter) const vars->collect (m_deep_layer.layout (), m_deep_layer.initial_cell ()); - const_cast (m_deep_layer).separate_variants (*vars); + if (filter.wants_variants ()) { + const_cast (m_deep_layer).separate_variants (*vars); + } } db::Layout &layout = const_cast (m_deep_layer.layout ()); std::vector poly_res; + std::map > to_commit; std::auto_ptr res (new db::DeepRegion (m_deep_layer.derived ())); for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) { const db::Shapes &s = c->shapes (filter.requires_raw_input () ? m_deep_layer.layer () : m_merged_polygons.layer ()); - db::Shapes &st = c->shapes (res->deep_layer ().layer ()); - db::PolygonRefToShapesGenerator pr (&layout, &st); if (vars.get ()) { - const std::map &v = vars->variants (c->cell_index ()); - tl_assert (v.size () == size_t (1)); - const db::ICplxTrans &tr = v.begin ()->first; - db::ICplxTrans trinv = tr.inverted (); + const std::map &vv = vars->variants (c->cell_index ()); + for (std::map::const_iterator v = vv.begin (); v != vv.end (); ++v) { - for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) { - db::Polygon poly; - si->polygon (poly); - poly.transform (tr); - poly_res.clear (); - filter.process (poly, poly_res); - for (std::vector::const_iterator p = poly_res.begin (); p != poly_res.end (); ++p) { - pr.put (p->transformed (trinv)); + db::Shapes *st; + if (vv.size () == 1) { + st = & c->shapes (res->deep_layer ().layer ()); + } else { + st = & to_commit [c->cell_index ()] [v->first]; } + + db::PolygonRefToShapesGenerator pr (&layout, st); + + const db::ICplxTrans &tr = v->first; + db::ICplxTrans trinv = tr.inverted (); + + for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) { + db::Polygon poly; + si->polygon (poly); + poly.transform (tr); + poly_res.clear (); + filter.process (poly, poly_res); + for (std::vector::const_iterator p = poly_res.begin (); p != poly_res.end (); ++p) { + pr.put (p->transformed (trinv)); + } + } + } } else { + db::Shapes &st = c->shapes (res->deep_layer ().layer ()); + db::PolygonRefToShapesGenerator pr (&layout, &st); + for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) { db::Polygon poly; si->polygon (poly); @@ -975,6 +991,10 @@ DeepRegion::processed (const PolygonProcessorBase &filter) const } + if (! to_commit.empty () && vars.get ()) { + res->deep_layer ().commit_shapes (*vars, to_commit); + } + if (filter.result_is_merged ()) { res->set_is_merged (true); } @@ -991,45 +1011,58 @@ DeepRegion::filter_in_place (const PolygonFilterBase &filter) RegionDelegate * DeepRegion::filtered (const PolygonFilterBase &filter) const { - ensure_merged_polygons_valid (); + if (! filter.requires_raw_input ()) { + ensure_merged_polygons_valid (); + } std::auto_ptr vars; if (filter.vars ()) { vars.reset (new db::VariantsCollectorBase (filter.vars ())); - vars->collect (m_merged_polygons.layout (), m_merged_polygons.initial_cell ()); + vars->collect (m_deep_layer.layout (), m_deep_layer.initial_cell ()); // NOTE: m_merged_polygons is mutable, so why is the const_cast needed? - const_cast (m_merged_polygons).separate_variants (*vars); + if (filter.wants_variants ()) { + const_cast (m_deep_layer).separate_variants (*vars); + } } - db::Layout &layout = m_merged_polygons.layout (); + db::Layout &layout = const_cast (m_deep_layer.layout ()); + std::map > to_commit; - std::auto_ptr res (new db::DeepRegion (m_merged_polygons.derived ())); + std::auto_ptr res (new db::DeepRegion (m_deep_layer.derived ())); for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) { - const db::Shapes &s = c->shapes (m_merged_polygons.layer ()); - db::Shapes &st = c->shapes (res->deep_layer ().layer ()); + const db::Shapes &s = c->shapes (filter.requires_raw_input () ? m_deep_layer.layer () : m_merged_polygons.layer ()); if (vars.get ()) { - const std::map &v = vars->variants (c->cell_index ()); - tl_assert (v.size () == size_t (1)); - const db::ICplxTrans &tr = v.begin ()->first; + const std::map &vv = vars->variants (c->cell_index ()); + for (std::map::const_iterator v = vv.begin (); v != vv.end (); ++v) { - for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) { - db::Polygon poly; - si->polygon (poly); - if (filter.selected (poly.transformed (tr))) { - st.insert (*si); + db::Shapes *st; + if (vv.size () == 1) { + st = & c->shapes (res->deep_layer ().layer ()); + } else { + st = & to_commit [c->cell_index ()] [v->first]; } + + const db::ICplxTrans &tr = v->first; + + for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) { + db::Polygon poly; + si->polygon (poly); + if (filter.selected (poly.transformed (tr))) { + st->insert (*si); + } + } + } } else { - const db::Shapes &s = c->shapes (m_merged_polygons.layer ()); db::Shapes &st = c->shapes (res->deep_layer ().layer ()); for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) { @@ -1044,7 +1077,13 @@ DeepRegion::filtered (const PolygonFilterBase &filter) const } - res->set_is_merged (true); + if (! to_commit.empty () && vars.get ()) { + res->deep_layer ().commit_shapes (*vars, to_commit); + } + + if (! filter.requires_raw_input ()) { + res->set_is_merged (true); + } return res.release (); } diff --git a/src/db/db/dbRegion.cc b/src/db/db/dbRegion.cc index c81df5f28..323b6c601 100644 --- a/src/db/db/dbRegion.cc +++ b/src/db/db/dbRegion.cc @@ -69,6 +69,7 @@ public: virtual const TransformationReducer *vars () const { return 0; } virtual bool result_is_merged () const { return false; } virtual bool requires_raw_input () const { return true; } + virtual bool wants_variants () const { return true; } }; // ------------------------------------------------------------------------------------------------------------- @@ -88,6 +89,7 @@ public: virtual const TransformationReducer *vars () const { return &m_vars; } virtual bool result_is_merged () const { return false; } virtual bool requires_raw_input () const { return false; } + virtual bool wants_variants () const { return true; } private: db::Coord m_d; @@ -113,6 +115,7 @@ public: virtual const TransformationReducer *vars () const { return &m_vars; } virtual bool result_is_merged () const { return true; } // we believe so ... virtual bool requires_raw_input () const { return false; } + virtual bool wants_variants () const { return true; } private: double m_rinner, m_router; @@ -140,6 +143,7 @@ public: virtual const TransformationReducer *vars () const { return 0; } virtual bool result_is_merged () const { return true; } // we believe so ... virtual bool requires_raw_input () const { return false; } + virtual bool wants_variants () const { return true; } }; // ------------------------------------------------------------------------------------------------------------- @@ -160,6 +164,7 @@ public: virtual const TransformationReducer *vars () const { return 0; } virtual bool result_is_merged () const { return true; } // we believe so ... virtual bool requires_raw_input () const { return false; } + virtual bool wants_variants () const { return true; } }; } diff --git a/src/db/db/dbRegionDelegate.h b/src/db/db/dbRegionDelegate.h index ed52b56d9..9c2d5a294 100644 --- a/src/db/db/dbRegionDelegate.h +++ b/src/db/db/dbRegionDelegate.h @@ -44,11 +44,35 @@ class EdgeFilterBase; class DB_PUBLIC PolygonFilterBase { public: + /** + * @brief Constructor + */ PolygonFilterBase () { } + virtual ~PolygonFilterBase () { } + /** + * @brief Filters the polygon + * If this method returns true, the polygon is kept. Otherwise it's discarded. + */ virtual bool selected (const db::Polygon &polygon) const = 0; + + /** + * @brief Returns the transformation reducer for building cell variants + * This method may return 0. In this case, not cell variants are built. + */ virtual const TransformationReducer *vars () const = 0; + + /** + * @brief Returns true, if the filter wants raw (not merged) input + */ + virtual bool requires_raw_input () const = 0; + + /** + * @brief Returns true, if the filter wants to build variants + * If not true, the filter accepts shape propagation as variant resolution. + */ + virtual bool wants_variants () const = 0; }; /** @@ -57,13 +81,41 @@ public: class DB_PUBLIC PolygonProcessorBase { public: + /** + * @brief Constructor + */ PolygonProcessorBase () { } + virtual ~PolygonProcessorBase () { } + /** + * @brief Performs the actual processing + * This method will take the input polygon from "polygon" and puts the results into "res". + * "res" can be empty - in this case, the polygon will be skipped. + */ virtual void process (const db::Polygon &polygon, std::vector &res) const = 0; + + /** + * @brief Returns the transformation reducer for building cell variants + * This method may return 0. In this case, not cell variants are built. + */ virtual const TransformationReducer *vars () const = 0; + + /** + * @brief Returns true, if the result of this operation can be regarded "merged" always. + */ virtual bool result_is_merged () const = 0; + + /** + * @brief Returns true, if the processor wants raw (not merged) input + */ virtual bool requires_raw_input () const = 0; + + /** + * @brief Returns true, if the processor wants to build variants + * If not true, the processor accepts shape propagation as variant resolution. + */ + virtual bool wants_variants () const = 0; }; /** diff --git a/src/db/db/dbRegionUtils.h b/src/db/db/dbRegionUtils.h index 32d9b58b4..64890799b 100644 --- a/src/db/db/dbRegionUtils.h +++ b/src/db/db/dbRegionUtils.h @@ -83,6 +83,16 @@ struct DB_PUBLIC RegionPerimeterFilter return &m_vars; } + /** + * @brief This filter prefers producing variants + */ + virtual bool wants_variants () const { return true; } + + /** + * @brief This filter wants merged input + */ + virtual bool requires_raw_input () const { return false; } + private: perimeter_type m_pmin, m_pmax; bool m_inverse; @@ -137,6 +147,16 @@ struct DB_PUBLIC RegionAreaFilter return &m_vars; } + /** + * @brief This filter prefers producing variants + */ + virtual bool wants_variants () const { return true; } + + /** + * @brief This filter wants merged input + */ + virtual bool requires_raw_input () const { return false; } + private: area_type m_amin, m_amax; bool m_inverse; @@ -178,6 +198,16 @@ struct DB_PUBLIC RectilinearFilter return 0; } + /** + * @brief This filter prefers producing variants + */ + virtual bool wants_variants () const { return true; } + + /** + * @brief This filter wants merged input + */ + virtual bool requires_raw_input () const { return false; } + private: bool m_inverse; }; @@ -217,6 +247,16 @@ struct DB_PUBLIC RectangleFilter return 0; } + /** + * @brief This filter prefers producing variants + */ + virtual bool wants_variants () const { return true; } + + /** + * @brief This filter wants merged input + */ + virtual bool requires_raw_input () const { return false; } + private: bool m_inverse; }; @@ -303,6 +343,16 @@ struct DB_PUBLIC RegionBBoxFilter } } + /** + * @brief This filter prefers producing variants + */ + virtual bool wants_variants () const { return true; } + + /** + * @brief This filter wants merged input + */ + virtual bool requires_raw_input () const { return false; } + private: value_type m_vmin, m_vmax; bool m_inverse;