diff --git a/src/db/db/dbDeepEdges.cc b/src/db/db/dbDeepEdges.cc index c0fc78fc4..55aee834b 100644 --- a/src/db/db/dbDeepEdges.cc +++ b/src/db/db/dbDeepEdges.cc @@ -476,14 +476,50 @@ std::string DeepEdges::to_string (size_t nmax) const EdgesDelegate *DeepEdges::filter_in_place (const EdgeFilterBase &filter) { - // TODO: implement - return AsIfFlatEdges::filter_in_place (filter); + // TODO: implement to be really in-place + return filtered (filter); } EdgesDelegate *DeepEdges::filtered (const EdgeFilterBase &filter) const { - // TODO: implement - return AsIfFlatEdges::filtered (filter); + ensure_merged_edges_valid (); + + std::auto_ptr vars; + + if (filter.isotropic ()) { + vars.reset (new db::cell_variants_collector ()); + } else { + vars.reset (new db::cell_variants_collector ()); + } + + vars->collect (m_merged_edges.layout (), m_merged_edges.initial_cell ()); + + // NOTE: m_merged_polygons is mutable, so why is the const_cast needed? + const_cast (m_merged_edges).separate_variants (*vars); + + db::Layout &layout = m_merged_edges.layout (); + + std::auto_ptr res (new db::DeepEdges (m_merged_edges.derived ())); + for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) { + + const std::map &v = vars->variants (c->cell_index ()); + tl_assert (v.size () == size_t (1)); + const db::ICplxTrans &tr = v.begin ()->first; + + const db::Shapes &s = c->shapes (m_merged_edges.layer ()); + db::Shapes &st = c->shapes (res->deep_layer ().layer ()); + + for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Edges); ! si.at_end (); ++si) { + db::Edge edge = si->edge (); + if (filter.selected (edge.transformed (tr))) { + st.insert (edge); + } + } + + } + + res->set_is_merged (true); + return res.release (); } EdgesDelegate *DeepEdges::merged_in_place () diff --git a/src/db/unit_tests/dbDeepEdgesTests.cc b/src/db/unit_tests/dbDeepEdgesTests.cc index f1ea9b6bd..2c14840b6 100644 --- a/src/db/unit_tests/dbDeepEdgesTests.cc +++ b/src/db/unit_tests/dbDeepEdgesTests.cc @@ -193,3 +193,57 @@ TEST(4_Edge2PolygonBooleans) db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_edges_au4.gds"); } +TEST(5_Filters) +{ + 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::EdgeLengthFilter elf2 (0, 30000, true); + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), e2.filtered (elf1)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), e2.filtered (elf2)); + + CHECKPOINT(); + db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_edges_au5a.gds"); + } + + { + 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::EdgeOrientationFilter eof1 (0, 1, false); + db::EdgeOrientationFilter eof2 (0, 1, true); + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), e2.filtered (eof1)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), e2.filtered (eof2)); + + CHECKPOINT(); + db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_edges_au5b.gds"); + } +} + diff --git a/testdata/algo/deep_edges_au5a.gds b/testdata/algo/deep_edges_au5a.gds new file mode 100644 index 000000000..28805aa0d Binary files /dev/null and b/testdata/algo/deep_edges_au5a.gds differ diff --git a/testdata/algo/deep_edges_au5b.gds b/testdata/algo/deep_edges_au5b.gds new file mode 100644 index 000000000..538b90698 Binary files /dev/null and b/testdata/algo/deep_edges_au5b.gds differ