From 7ef0451ca8a4b03bc2b062a2efa11079348d59fa Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 17 Feb 2019 17:53:21 +0100 Subject: [PATCH] Partial segments of edges converted to hierarchical operations. --- src/db/db/dbAsIfFlatEdges.cc | 66 +++++++++++++------------- src/db/db/dbAsIfFlatEdges.h | 2 + src/db/db/dbDeepEdges.cc | 50 ++++++++++++++++--- src/db/db/dbDeepEdges.h | 1 + src/db/unit_tests/dbDeepEdgesTests.cc | 48 +++++++++++++++++++ testdata/algo/deep_edges_au7.gds | Bin 0 -> 16206 bytes 6 files changed, 128 insertions(+), 39 deletions(-) create mode 100644 testdata/algo/deep_edges_au7.gds diff --git a/src/db/db/dbAsIfFlatEdges.cc b/src/db/db/dbAsIfFlatEdges.cc index 991c6c9b2..6d4fed452 100644 --- a/src/db/db/dbAsIfFlatEdges.cc +++ b/src/db/db/dbAsIfFlatEdges.cc @@ -424,8 +424,31 @@ AsIfFlatEdges::extended (coord_type ext_b, coord_type ext_e, coord_type ext_o, c } } +db::Edge +AsIfFlatEdges::compute_partial (const db::Edge &edge, int mode, length_type length, double fraction) +{ + double l = std::max (edge.double_length () * fraction, double (length)); + + if (mode < 0) { + + return db::Edge (edge.p1 (), db::Point (db::DPoint (edge.p1 ()) + db::DVector (edge.d ()) * (l / edge.double_length ()))); + + } else if (mode > 0) { + + return db::Edge (db::Point (db::DPoint (edge.p2 ()) - db::DVector (edge.d ()) * (l / edge.double_length ())), edge.p2 ()); + + } else { + + db::DVector dl = db::DVector (edge.d ()) * (0.5 * l / edge.double_length ()); + db::DPoint center = db::DPoint (edge.p1 ()) + db::DVector (edge.p2 () - edge.p1 ()) * 0.5; + + return db::Edge (db::Point (center - dl), db::Point (center + dl)); + + } +} + EdgesDelegate * -AsIfFlatEdges::start_segments (length_type length, double fraction) const +AsIfFlatEdges::segments (int mode, length_type length, double fraction) const { std::auto_ptr edges (new FlatEdges ()); edges->reserve (size ()); @@ -436,51 +459,28 @@ AsIfFlatEdges::start_segments (length_type length, double fraction) const } for (EdgesIterator e (begin_merged ()); ! e.at_end (); ++e) { - double l = std::max (e->double_length () * fraction, double (length)); - edges->insert (db::Edge (e->p1 (), db::Point (db::DPoint (e->p1 ()) + db::DVector (e->d()) * (l / e->double_length ())))); + edges->insert (compute_partial (*e, mode, length, fraction)); } return edges.release (); } +EdgesDelegate * +AsIfFlatEdges::start_segments (length_type length, double fraction) const +{ + return segments (-1, length, fraction); +} + EdgesDelegate * AsIfFlatEdges::end_segments (length_type length, double fraction) const { - std::auto_ptr edges (new FlatEdges ()); - edges->reserve (size ()); - - // zero-length edges would vanish in merged sematics, so we don't set it now - if (length == 0) { - edges->set_merged_semantics (false); - } - - for (EdgesIterator e (begin_merged ()); ! e.at_end (); ++e) { - double l = std::max (e->double_length () * fraction, double (length)); - edges->insert (db::Edge (db::Point (db::DPoint (e->p2 ()) - db::DVector (e->d()) * (l / e->double_length ())), e->p2 ())); - } - - return edges.release (); + return segments (1, length, fraction); } EdgesDelegate * AsIfFlatEdges::centers (length_type length, double fraction) const { - std::auto_ptr edges (new FlatEdges ()); - edges->reserve (size ()); - - // zero-length edges would vanish in merged sematics, so we don't set it now - if (length == 0) { - edges->set_merged_semantics (false); - } - - for (EdgesIterator e (begin_merged ()); ! e.at_end (); ++e) { - double l = std::max (e->double_length () * fraction, double (length)); - db::DVector dl = db::DVector (e->d()) * (0.5 * l / e->double_length ()); - db::DPoint center = db::DPoint (e->p1 ()) + db::DVector (e->p2 () - e->p1 ()) * 0.5; - edges->insert (db::Edge (db::Point (center - dl), db::Point (center + dl))); - } - - return edges.release (); + return segments (0, length, fraction); } namespace diff --git a/src/db/db/dbAsIfFlatEdges.h b/src/db/db/dbAsIfFlatEdges.h index d67b87080..c47911ab2 100644 --- a/src/db/db/dbAsIfFlatEdges.h +++ b/src/db/db/dbAsIfFlatEdges.h @@ -185,6 +185,7 @@ protected: void invalidate_bbox (); EdgePairs run_check (db::edge_relation_type rel, const Edges *other, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection) const; static db::Polygon extended_edge (const db::Edge &edge, coord_type ext_b, coord_type ext_e, coord_type ext_o, coord_type ext_i); + static db::Edge compute_partial (const db::Edge &edge, int mode, length_type length, double fraction); private: AsIfFlatEdges &operator= (const AsIfFlatEdges &other); @@ -195,6 +196,7 @@ private: virtual db::Box compute_bbox () const; EdgesDelegate *boolean (const Edges *other, EdgeBoolOp op) const; EdgesDelegate *edge_region_op (const Region &other, bool outside, bool include_borders) const; + EdgesDelegate *segments (int mode, length_type length, double fraction) const; }; } diff --git a/src/db/db/dbDeepEdges.cc b/src/db/db/dbDeepEdges.cc index ad95737c8..55129a374 100644 --- a/src/db/db/dbDeepEdges.cc +++ b/src/db/db/dbDeepEdges.cc @@ -900,22 +900,60 @@ RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_t return res.release (); } +EdgesDelegate *DeepEdges::segments (int mode, length_type length, double fraction) const +{ + ensure_merged_edges_valid (); + + std::auto_ptr res (new db::DeepEdges (m_merged_edges.derived ())); + + db::Layout &layout = const_cast (m_merged_edges.layout ()); + db::Cell &top_cell = const_cast (m_merged_edges.initial_cell ()); + + db::MagnificationReducer red; + db::cell_variants_collector vars (red); + vars.collect (m_merged_edges.layout (), m_merged_edges.initial_cell ()); + + std::map > to_commit; + + for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) { + + const std::map &vv = vars.variants (c->cell_index ()); + for (std::map::const_iterator v = vv.begin (); v != vv.end (); ++v) { + + db::Shapes *out; + if (vv.size () == 1) { + out = & c->shapes (res->deep_layer ().layer ()); + } else { + out = & to_commit [c->cell_index ()][v->first]; + } + + for (db::Shapes::shape_iterator si = c->shapes (m_merged_edges.layer ()).begin (db::ShapeIterator::Edges); ! si.at_end (); ++si) { + out->insert (compute_partial (si->edge ().transformed (v->first), mode, length, fraction).transformed (v->first.inverted ())); + } + + } + + } + + // propagate results from variants + vars.commit_shapes (layout, top_cell, res->deep_layer ().layer (), to_commit); + + return res.release (); +} + EdgesDelegate *DeepEdges::start_segments (length_type length, double fraction) const { - // TODO: implement - return AsIfFlatEdges::start_segments (length, fraction); + return segments (-1, length, fraction); } EdgesDelegate *DeepEdges::end_segments (length_type length, double fraction) const { - // TODO: implement - return AsIfFlatEdges::end_segments (length, fraction); + return segments (1, length, fraction); } EdgesDelegate *DeepEdges::centers (length_type length, double fraction) const { - // TODO: implement - return AsIfFlatEdges::centers (length, fraction); + return segments (0, length, fraction); } EdgesDelegate *DeepEdges::selected_interacting (const Edges &other) const diff --git a/src/db/db/dbDeepEdges.h b/src/db/db/dbDeepEdges.h index bdc7a67bc..3df914ad6 100644 --- a/src/db/db/dbDeepEdges.h +++ b/src/db/db/dbDeepEdges.h @@ -173,6 +173,7 @@ private: DeepLayer and_or_not_with(const DeepEdges *other, bool and_op) const; DeepLayer edge_region_op (const DeepRegion *other, bool outside, bool include_borders) const; EdgePairs run_check (db::edge_relation_type rel, const Edges *other, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection) const; + EdgesDelegate *segments (int mode, length_type length, double fraction) const; }; } diff --git a/src/db/unit_tests/dbDeepEdgesTests.cc b/src/db/unit_tests/dbDeepEdgesTests.cc index cf4c00e68..b3177d6ca 100644 --- a/src/db/unit_tests/dbDeepEdgesTests.cc +++ b/src/db/unit_tests/dbDeepEdgesTests.cc @@ -294,3 +294,51 @@ TEST(6_Extended) db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_edges_au6.gds"); } +TEST(7_Partial) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/deep_region_area_peri_l1.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::cell_index_type top_cell_index = *ly.begin_top_down (); + db::Cell &top_cell = ly.cell (top_cell_index); + + db::DeepShapeStore dss; + + unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); + + db::Region r2 (db::RecursiveShapeIterator (ly, top_cell, l2), dss); + db::Edges e2 = r2.edges (); + + db::Layout target; + unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index)); + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (2, 0)), r2); + + db::EdgeLengthFilter elf1 (0, 40000, false); + db::Edges e2f = e2.filtered (elf1); + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), e2.start_segments (1000, 0.0)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), e2.start_segments (0, 0.2)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (12, 0)), e2f.start_segments (1000, 0.0)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (13, 0)), e2f.start_segments (0, 0.2)); + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (20, 0)), e2.end_segments (1000, 0.0)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (21, 0)), e2.end_segments (0, 0.2)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (22, 0)), e2f.end_segments (1000, 0.0)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (23, 0)), e2f.end_segments (0, 0.2)); + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (30, 0)), e2.centers (1000, 0.0)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (31, 0)), e2.centers (0, 0.2)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (32, 0)), e2f.centers (1000, 0.0)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (33, 0)), e2f.centers (0, 0.2)); + + CHECKPOINT(); + db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_edges_au7.gds"); +} + diff --git a/testdata/algo/deep_edges_au7.gds b/testdata/algo/deep_edges_au7.gds new file mode 100644 index 0000000000000000000000000000000000000000..ec135e2c28a7f486228aba201a909b6829e87e2b GIT binary patch literal 16206 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 literal 0 HcmV?d00001