Enabled transformations for deep regions/edges/edge pairs - important for handling layouts with different DBUs in DRC

This commit is contained in:
Matthias Koefferlein 2019-02-22 01:02:48 +01:00
parent d830318a1f
commit 18f74bac1e
13 changed files with 249 additions and 113 deletions

View File

@ -98,9 +98,9 @@ DeepEdgePairs::DeepEdgePairs (const RecursiveShapeIterator &si, DeepShapeStore &
} }
DeepEdgePairs::DeepEdgePairs (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans) DeepEdgePairs::DeepEdgePairs (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans)
: AsIfFlatEdgePairs (), m_deep_layer (dss.create_edge_pair_layer (si)) : AsIfFlatEdgePairs (), m_deep_layer (dss.create_edge_pair_layer (si, trans))
{ {
tl_assert (trans.is_unity ()); // TODO: implement // .. nothing yet ..
} }
DeepEdgePairs::DeepEdgePairs (const DeepEdgePairs &other) DeepEdgePairs::DeepEdgePairs (const DeepEdgePairs &other)

View File

@ -102,11 +102,9 @@ DeepEdges::DeepEdges (const RecursiveShapeIterator &si, DeepShapeStore &dss, boo
} }
DeepEdges::DeepEdges (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans, bool as_edges, bool merged_semantics) DeepEdges::DeepEdges (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans, bool as_edges, bool merged_semantics)
: AsIfFlatEdges (), m_deep_layer (dss.create_edge_layer (si, as_edges)), m_merged_edges () : AsIfFlatEdges (), m_deep_layer (dss.create_edge_layer (si, as_edges, trans)), m_merged_edges ()
{ {
init (); init ();
tl_assert (trans.is_unity ()); // TODO: implement
set_merged_semantics (merged_semantics); set_merged_semantics (merged_semantics);
} }

View File

@ -108,11 +108,9 @@ DeepRegion::DeepRegion (const RecursiveShapeIterator &si, DeepShapeStore &dss, d
} }
DeepRegion::DeepRegion (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans, bool merged_semantics, double area_ratio, size_t max_vertex_count) DeepRegion::DeepRegion (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans, bool merged_semantics, double area_ratio, size_t max_vertex_count)
: AsIfFlatRegion (), m_deep_layer (dss.create_polygon_layer (si, area_ratio, max_vertex_count)), m_merged_polygons () : AsIfFlatRegion (), m_deep_layer (dss.create_polygon_layer (si, area_ratio, max_vertex_count, trans)), m_merged_polygons ()
{ {
init (); init ();
tl_assert (trans.is_unity ()); // TODO: implement
set_merged_semantics (merged_semantics); set_merged_semantics (merged_semantics);
} }

View File

@ -221,8 +221,8 @@ DeepLayer::check_dss () const
struct DeepShapeStore::LayoutHolder struct DeepShapeStore::LayoutHolder
{ {
LayoutHolder () LayoutHolder (const db::ICplxTrans &trans)
: refs (0), layout (false), builder (&layout) : refs (0), layout (false), builder (&layout, trans)
{ {
// .. nothing yet .. // .. nothing yet ..
} }
@ -364,22 +364,22 @@ void DeepShapeStore::remove_ref (unsigned int layout, unsigned int layer)
} }
unsigned int unsigned int
DeepShapeStore::layout_for_iter (const db::RecursiveShapeIterator &si) DeepShapeStore::layout_for_iter (const db::RecursiveShapeIterator &si, const db::ICplxTrans &trans)
{ {
layout_map_type::iterator l = m_layout_map.find (si); layout_map_type::iterator l = m_layout_map.find (std::make_pair (si, trans));
if (l == m_layout_map.end ()) { if (l == m_layout_map.end ()) {
unsigned int layout_index = (unsigned int) m_layouts.size (); unsigned int layout_index = (unsigned int) m_layouts.size ();
m_layouts.push_back (new LayoutHolder ()); m_layouts.push_back (new LayoutHolder (trans));
db::Layout &layout = m_layouts.back ()->layout; db::Layout &layout = m_layouts.back ()->layout;
layout.hier_changed_event.add (this, &DeepShapeStore::invalidate_hier); layout.hier_changed_event.add (this, &DeepShapeStore::invalidate_hier);
if (si.layout ()) { if (si.layout ()) {
layout.dbu (si.layout ()->dbu ()); layout.dbu (si.layout ()->dbu () / trans.mag ());
} }
m_layout_map[si] = layout_index; m_layout_map[std::make_pair (si, trans)] = layout_index;
return layout_index; return layout_index;
} else { } else {
@ -387,7 +387,7 @@ DeepShapeStore::layout_for_iter (const db::RecursiveShapeIterator &si)
} }
} }
DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator &si, double max_area_ratio, size_t max_vertex_count) DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator &si, double max_area_ratio, size_t max_vertex_count, const db::ICplxTrans &trans)
{ {
if (max_area_ratio == 0.0) { if (max_area_ratio == 0.0) {
max_area_ratio = m_max_area_ratio; max_area_ratio = m_max_area_ratio;
@ -396,7 +396,7 @@ DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator
max_vertex_count = m_max_vertex_count; max_vertex_count = m_max_vertex_count;
} }
unsigned int layout_index = layout_for_iter (si); unsigned int layout_index = layout_for_iter (si, trans);
db::Layout &layout = m_layouts[layout_index]->layout; db::Layout &layout = m_layouts[layout_index]->layout;
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder; db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;
@ -426,9 +426,9 @@ DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator
return DeepLayer (this, layout_index, layer_index); return DeepLayer (this, layout_index, layer_index);
} }
DeepLayer DeepShapeStore::create_edge_layer (const db::RecursiveShapeIterator &si, bool as_edges) DeepLayer DeepShapeStore::create_edge_layer (const db::RecursiveShapeIterator &si, bool as_edges, const db::ICplxTrans &trans)
{ {
unsigned int layout_index = layout_for_iter (si); unsigned int layout_index = layout_for_iter (si, trans);
db::Layout &layout = m_layouts[layout_index]->layout; db::Layout &layout = m_layouts[layout_index]->layout;
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder; db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;
@ -456,9 +456,9 @@ DeepLayer DeepShapeStore::create_edge_layer (const db::RecursiveShapeIterator &s
return DeepLayer (this, layout_index, layer_index); return DeepLayer (this, layout_index, layer_index);
} }
DeepLayer DeepShapeStore::create_edge_pair_layer (const db::RecursiveShapeIterator &si) DeepLayer DeepShapeStore::create_edge_pair_layer (const db::RecursiveShapeIterator &si, const db::ICplxTrans &trans)
{ {
unsigned int layout_index = layout_for_iter (si); unsigned int layout_index = layout_for_iter (si, trans);
db::Layout &layout = m_layouts[layout_index]->layout; db::Layout &layout = m_layouts[layout_index]->layout;
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder; db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;

View File

@ -201,9 +201,13 @@ private:
struct DB_PUBLIC RecursiveShapeIteratorCompareForTargetHierarchy struct DB_PUBLIC RecursiveShapeIteratorCompareForTargetHierarchy
{ {
bool operator () (const db::RecursiveShapeIterator &a, const db::RecursiveShapeIterator &b) const bool operator () (const std::pair<db::RecursiveShapeIterator, db::ICplxTrans> &a, const std::pair<db::RecursiveShapeIterator, db::ICplxTrans> &b) const
{ {
return db::compare_iterators_with_respect_to_target_hierarchy (a, b) < 0; int cmp_iter = db::compare_iterators_with_respect_to_target_hierarchy (a.first, b.first);
if (cmp_iter != 0) {
return cmp_iter < 0;
}
return a.second < b.second;
} }
}; };
@ -257,7 +261,7 @@ public:
* into parts satisfying the area ratio (bounding box vs. polygon area) * into parts satisfying the area ratio (bounding box vs. polygon area)
* and maximum vertex count constraints. * and maximum vertex count constraints.
*/ */
DeepLayer create_polygon_layer (const db::RecursiveShapeIterator &si, double max_area_ratio = 0.0, size_t max_vertex_count = 0); DeepLayer create_polygon_layer (const db::RecursiveShapeIterator &si, double max_area_ratio = 0.0, size_t max_vertex_count = 0, const ICplxTrans &trans = db::ICplxTrans ());
/** /**
* @brief Inserts an edge layer into the deep shape store * @brief Inserts an edge layer into the deep shape store
@ -270,7 +274,7 @@ public:
* only edge objects are taken from the shape iterator. Note that the shape iterator * only edge objects are taken from the shape iterator. Note that the shape iterator
* must be configured to deliver all shape types if "as_edges" is true. * must be configured to deliver all shape types if "as_edges" is true.
*/ */
DeepLayer create_edge_layer (const db::RecursiveShapeIterator &si, bool as_edges); DeepLayer create_edge_layer (const db::RecursiveShapeIterator &si, bool as_edges, const ICplxTrans &trans = db::ICplxTrans ());
/** /**
* @brief Inserts an edge pair layer into the deep shape store * @brief Inserts an edge pair layer into the deep shape store
@ -279,7 +283,7 @@ public:
* working copy of the original layer. This method creates a layer * working copy of the original layer. This method creates a layer
* for edge pairs. * for edge pairs.
*/ */
DeepLayer create_edge_pair_layer (const db::RecursiveShapeIterator &si); DeepLayer create_edge_pair_layer (const db::RecursiveShapeIterator &si, const ICplxTrans &trans = db::ICplxTrans ());
/** /**
* @brief Inserts the deep layer's shapes into some target layout * @brief Inserts the deep layer's shapes into some target layout
@ -522,13 +526,13 @@ private:
void add_ref (unsigned int layout, unsigned int layer); void add_ref (unsigned int layout, unsigned int layer);
void remove_ref (unsigned int layout, unsigned int layer); void remove_ref (unsigned int layout, unsigned int layer);
unsigned int layout_for_iter (const db::RecursiveShapeIterator &si); unsigned int layout_for_iter (const db::RecursiveShapeIterator &si, const db::ICplxTrans &trans);
void require_singular () const; void require_singular () const;
void issue_variants (unsigned int layout, const std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > &var_map); void issue_variants (unsigned int layout, const std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > &var_map);
typedef std::map<db::RecursiveShapeIterator, unsigned int, RecursiveShapeIteratorCompareForTargetHierarchy> layout_map_type; typedef std::map<std::pair<db::RecursiveShapeIterator, db::ICplxTrans>, unsigned int, RecursiveShapeIteratorCompareForTargetHierarchy> layout_map_type;
// no copying // no copying
DeepShapeStore (const DeepShapeStore &); DeepShapeStore (const DeepShapeStore &);

View File

@ -135,14 +135,14 @@ static std::pair<bool, std::set<db::Box> > compute_clip_variant (const db::Box &
return std::make_pair (true, clip_variant); return std::make_pair (true, clip_variant);
} }
HierarchyBuilder::HierarchyBuilder (db::Layout *target, unsigned int target_layer, HierarchyBuilderShapeReceiver *pipe) HierarchyBuilder::HierarchyBuilder (db::Layout *target, unsigned int target_layer, const db::ICplxTrans &trans, HierarchyBuilderShapeReceiver *pipe)
: mp_target (target), m_initial_pass (true), m_cm_new_entry (false), m_target_layer (target_layer) : mp_target (target), m_initial_pass (true), m_cm_new_entry (false), m_target_layer (target_layer), m_trans (trans)
{ {
set_shape_receiver (pipe); set_shape_receiver (pipe);
} }
HierarchyBuilder::HierarchyBuilder (db::Layout *target, HierarchyBuilderShapeReceiver *pipe) HierarchyBuilder::HierarchyBuilder (db::Layout *target, const db::ICplxTrans &trans, HierarchyBuilderShapeReceiver *pipe)
: mp_target (target), m_initial_pass (true), m_cm_new_entry (false), m_target_layer (0) : mp_target (target), m_initial_pass (true), m_cm_new_entry (false), m_target_layer (0), m_trans (trans)
{ {
set_shape_receiver (pipe); set_shape_receiver (pipe);
} }
@ -283,6 +283,7 @@ HierarchyBuilder::new_inst (const RecursiveShapeIterator *iter, const db::CellIn
if (m_cell_stack.back ().first) { if (m_cell_stack.back ().first) {
db::CellInstArray new_inst (inst, &mp_target->array_repository ()); db::CellInstArray new_inst (inst, &mp_target->array_repository ());
new_inst.object () = db::CellInst (m_cm_entry->second); new_inst.object () = db::CellInst (m_cm_entry->second);
new_inst.transform_into (m_trans);
for (std::vector<db::Cell *>::const_iterator c = m_cell_stack.back ().second.begin (); c != m_cell_stack.back ().second.end (); ++c) { for (std::vector<db::Cell *>::const_iterator c = m_cell_stack.back ().second.begin (); c != m_cell_stack.back ().second.end (); ++c) {
(*c)->insert (new_inst); (*c)->insert (new_inst);
} }
@ -332,6 +333,7 @@ HierarchyBuilder::new_inst_member (const RecursiveShapeIterator *iter, const db:
// for a new cell, create this instance // for a new cell, create this instance
if (m_cell_stack.back ().first) { if (m_cell_stack.back ().first) {
db::CellInstArray new_inst (db::CellInst (m_cm_entry->second), trans); db::CellInstArray new_inst (db::CellInst (m_cm_entry->second), trans);
new_inst.transform_into (m_trans);
for (std::vector<db::Cell *>::const_iterator c = m_cell_stack.back ().second.begin (); c != m_cell_stack.back ().second.end (); ++c) { for (std::vector<db::Cell *>::const_iterator c = m_cell_stack.back ().second.begin (); c != m_cell_stack.back ().second.end (); ++c) {
(*c)->insert (new_inst); (*c)->insert (new_inst);
} }
@ -347,7 +349,7 @@ HierarchyBuilder::shape (const RecursiveShapeIterator * /*iter*/, const db::Shap
{ {
for (std::vector<db::Cell *>::const_iterator c = m_cell_stack.back ().second.begin (); c != m_cell_stack.back ().second.end (); ++c) { for (std::vector<db::Cell *>::const_iterator c = m_cell_stack.back ().second.begin (); c != m_cell_stack.back ().second.end (); ++c) {
db::Shapes &shapes = (*c)->shapes (m_target_layer); db::Shapes &shapes = (*c)->shapes (m_target_layer);
mp_pipe->push (shape, region, complex_region, &shapes); mp_pipe->push (shape, m_trans, region, complex_region, &shapes);
} }
} }
@ -360,54 +362,54 @@ ClippingHierarchyBuilderShapeReceiver::ClippingHierarchyBuilderShapeReceiver (Hi
} }
void void
ClippingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) ClippingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target)
{ {
static db::Box world = db::Box::world (); static db::Box world = db::Box::world ();
if (region == world || is_inside (shape.bbox (), region, complex_region)) { if (region == world || is_inside (shape.bbox (), region, complex_region)) {
mp_pipe->push (shape, world, 0, target); mp_pipe->push (shape, trans, world, 0, target);
} else if (! is_outside (shape.bbox (), region, complex_region)) { } else if (! is_outside (shape.bbox (), region, complex_region)) {
// clip the shape if required // clip the shape if required
if (shape.is_text () || shape.is_edge () || shape.is_edge_pair ()) { if (shape.is_text () || shape.is_edge () || shape.is_edge_pair ()) {
mp_pipe->push (shape, world, 0, target); mp_pipe->push (shape, trans, world, 0, target);
} else if (shape.is_box ()) { } else if (shape.is_box ()) {
insert_clipped (shape.box (), region, complex_region, target); insert_clipped (shape.box (), trans, region, complex_region, target);
} else if (shape.is_polygon () || shape.is_simple_polygon () || shape.is_path ()) { } else if (shape.is_polygon () || shape.is_simple_polygon () || shape.is_path ()) {
db::Polygon poly; db::Polygon poly;
shape.polygon (poly); shape.polygon (poly);
insert_clipped (poly, region, complex_region, target); insert_clipped (poly, trans, region, complex_region, target);
} }
} }
} }
void void
ClippingHierarchyBuilderShapeReceiver::push (const db::Box &shape, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) ClippingHierarchyBuilderShapeReceiver::push (const db::Box &shape, const db::ICplxTrans &trans, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target)
{ {
static db::Box world = db::Box::world (); static db::Box world = db::Box::world ();
if (! complex_region) { if (! complex_region) {
db::Box r = shape & region; db::Box r = shape & region;
if (! r.empty()) { if (! r.empty()) {
mp_pipe->push (r, world, 0, target); mp_pipe->push (r, trans, world, 0, target);
} }
} else { } else {
insert_clipped (shape, region, complex_region, target); insert_clipped (shape, trans, region, complex_region, target);
} }
} }
void void
ClippingHierarchyBuilderShapeReceiver::push (const db::Polygon &shape, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) ClippingHierarchyBuilderShapeReceiver::push (const db::Polygon &shape, const db::ICplxTrans &trans, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target)
{ {
static db::Box world = db::Box::world (); static db::Box world = db::Box::world ();
if (region == world || (shape.box ().inside (region) && ! complex_region)) { if (region == world || (shape.box ().inside (region) && ! complex_region)) {
mp_pipe->push (shape, world, 0, target); mp_pipe->push (shape, trans, world, 0, target);
} else { } else {
insert_clipped (shape, region, complex_region, target); insert_clipped (shape, trans, region, complex_region, target);
} }
} }
@ -465,22 +467,22 @@ ClippingHierarchyBuilderShapeReceiver::is_outside (const db::Box &box, const db:
} }
void void
ClippingHierarchyBuilderShapeReceiver::insert_clipped (const db::Box &box, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) ClippingHierarchyBuilderShapeReceiver::insert_clipped (const db::Box &box, const db::ICplxTrans &trans, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target)
{ {
db::Box bb = box & region; db::Box bb = box & region;
static db::Box world = db::Box::world (); static db::Box world = db::Box::world ();
if (complex_region) { if (complex_region) {
for (db::RecursiveShapeReceiver::box_tree_type::overlapping_iterator cr = complex_region->begin_overlapping (bb, db::box_convert<db::Box> ()); ! cr.at_end (); ++cr) { for (db::RecursiveShapeReceiver::box_tree_type::overlapping_iterator cr = complex_region->begin_overlapping (bb, db::box_convert<db::Box> ()); ! cr.at_end (); ++cr) {
mp_pipe->push (*cr & bb, world, 0, target); mp_pipe->push (*cr & bb, trans, world, 0, target);
} }
} else { } else {
mp_pipe->push (bb, world, 0, target); mp_pipe->push (bb, trans, world, 0, target);
} }
} }
void void
ClippingHierarchyBuilderShapeReceiver::insert_clipped (const db::Polygon &poly, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) ClippingHierarchyBuilderShapeReceiver::insert_clipped (const db::Polygon &poly, const db::ICplxTrans &trans, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target)
{ {
std::vector<db::Polygon> clipped_poly; std::vector<db::Polygon> clipped_poly;
static db::Box world = db::Box::world (); static db::Box world = db::Box::world ();
@ -495,7 +497,7 @@ ClippingHierarchyBuilderShapeReceiver::insert_clipped (const db::Polygon &poly,
} }
for (std::vector<db::Polygon>::const_iterator p = clipped_poly.begin (); p != clipped_poly.end (); ++p) { for (std::vector<db::Polygon>::const_iterator p = clipped_poly.begin (); p != clipped_poly.end (); ++p) {
mp_pipe->push (*p, world, 0, target); mp_pipe->push (*p, trans, world, 0, target);
} }
} }
@ -508,44 +510,44 @@ ReducingHierarchyBuilderShapeReceiver::ReducingHierarchyBuilderShapeReceiver (Hi
} }
void void
ReducingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) ReducingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target)
{ {
if (shape.is_text () || shape.is_edge () || shape.is_edge_pair ()) { if (shape.is_text () || shape.is_edge () || shape.is_edge_pair ()) {
mp_pipe->push (shape, region, complex_region, target); mp_pipe->push (shape, trans, region, complex_region, target);
} else if (shape.is_box ()) { } else if (shape.is_box ()) {
mp_pipe->push (shape.box (), region, complex_region, target); mp_pipe->push (shape.box (), trans, region, complex_region, target);
} else if (shape.is_polygon () || shape.is_simple_polygon () || shape.is_path ()) { } else if (shape.is_polygon () || shape.is_simple_polygon () || shape.is_path ()) {
db::Polygon poly; db::Polygon poly;
shape.polygon (poly); shape.polygon (poly);
reduce (poly, region, complex_region, target); reduce (poly, trans, region, complex_region, target);
} }
} }
void void
ReducingHierarchyBuilderShapeReceiver::push (const db::Box &shape, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) ReducingHierarchyBuilderShapeReceiver::push (const db::Box &shape, const db::ICplxTrans &trans, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target)
{ {
mp_pipe->push (shape, region, complex_region, target); mp_pipe->push (shape, trans, region, complex_region, target);
} }
void void
ReducingHierarchyBuilderShapeReceiver::push (const db::Polygon &shape, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) ReducingHierarchyBuilderShapeReceiver::push (const db::Polygon &shape, const db::ICplxTrans &trans, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target)
{ {
reduce (shape, region, complex_region, target); reduce (shape, trans, region, complex_region, target);
} }
void void
ReducingHierarchyBuilderShapeReceiver::reduce (const db::Polygon &poly, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) ReducingHierarchyBuilderShapeReceiver::reduce (const db::Polygon &poly, const db::ICplxTrans &trans, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target)
{ {
if (poly.vertices () > m_max_vertex_count || poly.area_ratio () > m_area_ratio) { if (poly.vertices () > m_max_vertex_count || poly.area_ratio () > m_area_ratio) {
std::vector <db::Polygon> split_polygons; std::vector <db::Polygon> split_polygons;
db::split_polygon (poly, split_polygons); db::split_polygon (poly, split_polygons);
for (std::vector <db::Polygon>::const_iterator sp = split_polygons.begin (); sp != split_polygons.end (); ++sp) { for (std::vector <db::Polygon>::const_iterator sp = split_polygons.begin (); sp != split_polygons.end (); ++sp) {
reduce (*sp, region, complex_region, target); reduce (*sp, trans, region, complex_region, target);
} }
} else { } else {
mp_pipe->push (poly, region, complex_region, target); mp_pipe->push (poly, trans, region, complex_region, target);
} }
} }
@ -560,17 +562,23 @@ PolygonReferenceHierarchyBuilderShapeReceiver::PolygonReferenceHierarchyBuilderS
} }
} }
void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Shape &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target) void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
{ {
if (shape.is_box () || shape.is_polygon () || shape.is_simple_polygon () || shape.is_path ()) { if (shape.is_box () || shape.is_polygon () || shape.is_simple_polygon () || shape.is_path ()) {
db::Polygon poly; db::Polygon poly;
shape.polygon (poly); shape.polygon (poly);
if (! trans.is_unity ()) {
poly.transform (trans);
}
target->insert (db::PolygonRef (poly, mp_layout->shape_repository ())); target->insert (db::PolygonRef (poly, mp_layout->shape_repository ()));
} else if (shape.is_text () && m_text_enlargement >= 0) { } else if (shape.is_text () && m_text_enlargement >= 0) {
db::Polygon poly (shape.text_trans () * db::Box (-m_text_enlargement, -m_text_enlargement, m_text_enlargement, m_text_enlargement)); db::Polygon poly (shape.text_trans () * db::Box (-m_text_enlargement, -m_text_enlargement, m_text_enlargement, m_text_enlargement));
if (! trans.is_unity ()) {
poly.transform (trans);
}
db::PolygonRef pref (poly, mp_layout->shape_repository ()); db::PolygonRef pref (poly, mp_layout->shape_repository ());
if (m_make_text_prop) { if (m_make_text_prop) {
@ -588,14 +596,14 @@ void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Shape &shape
} }
} }
void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Box &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target) void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Box &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
{ {
target->insert (db::PolygonRef (db::Polygon (shape), mp_layout->shape_repository ())); target->insert (db::PolygonRef (db::Polygon (shape.transformed (trans)), mp_layout->shape_repository ()));
} }
void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Polygon &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target) void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Polygon &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
{ {
target->insert (db::PolygonRef (shape, mp_layout->shape_repository ())); target->insert (db::PolygonRef (shape.transformed (trans), mp_layout->shape_repository ()));
} }
// --------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------
@ -606,34 +614,34 @@ EdgeBuildingHierarchyBuilderShapeReceiver::EdgeBuildingHierarchyBuilderShapeRece
// .. nothing yet .. // .. nothing yet ..
} }
void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target)
{ {
if (m_as_edges && (shape.is_polygon () || shape.is_simple_polygon () || shape.is_path ())) { if (m_as_edges && (shape.is_polygon () || shape.is_simple_polygon () || shape.is_path ())) {
db::Polygon poly; db::Polygon poly;
shape.polygon (poly); shape.polygon (poly);
push (poly, region, complex_region, target); push (poly, trans, region, complex_region, target);
} else if (m_as_edges && shape.is_box ()) { } else if (m_as_edges && shape.is_box ()) {
push (shape.box (), region, complex_region, target); push (shape.box (), trans, region, complex_region, target);
} else if (shape.is_edge ()) { } else if (shape.is_edge ()) {
target->insert (shape.edge ()); target->insert (shape.edge ());
} }
} }
void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Box &box, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target) void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Box &box, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
{ {
if (m_as_edges && ! box.empty ()) { if (m_as_edges && ! box.empty ()) {
target->insert (db::Edge (box.p1 (), box.upper_left ())); target->insert (db::Edge (box.p1 (), box.upper_left ()).transformed (trans));
target->insert (db::Edge (box.upper_left (), box.p2 ())); target->insert (db::Edge (box.upper_left (), box.p2 ()).transformed (trans));
target->insert (db::Edge (box.p2 (), box.lower_right ())); target->insert (db::Edge (box.p2 (), box.lower_right ()).transformed (trans));
target->insert (db::Edge (box.lower_right (), box.p1 ())); target->insert (db::Edge (box.lower_right (), box.p1 ()).transformed (trans));
} }
} }
void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Polygon &poly, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target) void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Polygon &poly, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
{ {
if (m_as_edges) { if (m_as_edges) {
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) { for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
target->insert (*e); target->insert ((*e).transformed (trans));
} }
} }
} }
@ -645,10 +653,10 @@ EdgePairBuildingHierarchyBuilderShapeReceiver::EdgePairBuildingHierarchyBuilderS
// .. nothing yet .. // .. nothing yet ..
} }
void EdgePairBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, const db::Box & /*region*/, const db::RecursiveShapeReceiver::box_tree_type * /*complex_region*/, db::Shapes *target) void EdgePairBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box & /*region*/, const db::RecursiveShapeReceiver::box_tree_type * /*complex_region*/, db::Shapes *target)
{ {
if (shape.is_edge_pair ()) { if (shape.is_edge_pair ()) {
target->insert (shape.edge_pair ()); target->insert (shape.edge_pair ().transformed (trans));
} }
} }

View File

@ -55,9 +55,9 @@ public:
HierarchyBuilderShapeReceiver () { } HierarchyBuilderShapeReceiver () { }
virtual ~HierarchyBuilderShapeReceiver () { } virtual ~HierarchyBuilderShapeReceiver () { }
virtual void push (const db::Shape &shape, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) = 0; virtual void push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) = 0;
virtual void push (const db::Box &shape, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) = 0; virtual void push (const db::Box &shape, const db::ICplxTrans &trans, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) = 0;
virtual void push (const db::Polygon &shape, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) = 0; virtual void push (const db::Polygon &shape, const db::ICplxTrans &trans, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) = 0;
}; };
/** /**
@ -69,19 +69,29 @@ class DB_PUBLIC HierarchyBuilderShapeInserter
public: public:
HierarchyBuilderShapeInserter () { } HierarchyBuilderShapeInserter () { }
virtual void push (const db::Shape &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target) virtual void push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
{ {
target->insert (shape); tl::ident_map<db::Layout::properties_id_type> pm;
target->insert (shape, trans, pm);
} }
virtual void push (const db::Box &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target) virtual void push (const db::Box &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
{ {
target->insert (shape); if (trans.is_ortho ()) {
target->insert (shape.transformed (trans));
} else {
db::Polygon poly (shape);
target->insert (poly.transformed (trans));
}
} }
virtual void push (const db::Polygon &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target) virtual void push (const db::Polygon &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
{ {
if (trans.is_unity ()) {
target->insert (shape); target->insert (shape);
} else {
target->insert (shape.transformed (trans));
}
} }
}; };
@ -94,13 +104,13 @@ class DB_PUBLIC ClippingHierarchyBuilderShapeReceiver
public: public:
ClippingHierarchyBuilderShapeReceiver (HierarchyBuilderShapeReceiver *pipe = 0); ClippingHierarchyBuilderShapeReceiver (HierarchyBuilderShapeReceiver *pipe = 0);
virtual void push (const db::Shape &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target); virtual void push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Box &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target); virtual void push (const db::Box &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Polygon &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target); virtual void push (const db::Polygon &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
private: private:
void insert_clipped (const db::Box &box, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target); void insert_clipped (const db::Box &box, const db::ICplxTrans &trans, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target);
void insert_clipped (const db::Polygon &poly, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target); void insert_clipped (const db::Polygon &poly, const db::ICplxTrans &trans, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target);
static bool is_inside (const db::Box &box, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region); static bool is_inside (const db::Box &box, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region);
static bool is_outside (const db::Box &box, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region); static bool is_outside (const db::Box &box, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region);
@ -116,12 +126,12 @@ class DB_PUBLIC ReducingHierarchyBuilderShapeReceiver
public: public:
ReducingHierarchyBuilderShapeReceiver (HierarchyBuilderShapeReceiver *pipe = 0, double area_ratio = 3.0, size_t max_vertex_count = 16); ReducingHierarchyBuilderShapeReceiver (HierarchyBuilderShapeReceiver *pipe = 0, double area_ratio = 3.0, size_t max_vertex_count = 16);
virtual void push (const db::Shape &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target); virtual void push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Box &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target); virtual void push (const db::Box &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Polygon &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target); virtual void push (const db::Polygon &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
private: private:
void reduce (const db::Polygon &poly, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target); void reduce (const db::Polygon &poly, const db::ICplxTrans &trans, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target);
HierarchyBuilderShapeReceiver *mp_pipe; HierarchyBuilderShapeReceiver *mp_pipe;
double m_area_ratio; double m_area_ratio;
@ -137,9 +147,9 @@ class DB_PUBLIC PolygonReferenceHierarchyBuilderShapeReceiver
public: public:
PolygonReferenceHierarchyBuilderShapeReceiver (db::Layout *layout, int text_enlargement = -1, const tl::Variant &text_prop_name = tl::Variant ()); PolygonReferenceHierarchyBuilderShapeReceiver (db::Layout *layout, int text_enlargement = -1, const tl::Variant &text_prop_name = tl::Variant ());
virtual void push (const db::Shape &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target); virtual void push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Box &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target); virtual void push (const db::Box &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Polygon &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target); virtual void push (const db::Polygon &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
private: private:
db::Layout *mp_layout; db::Layout *mp_layout;
@ -157,9 +167,9 @@ class DB_PUBLIC EdgeBuildingHierarchyBuilderShapeReceiver
public: public:
EdgeBuildingHierarchyBuilderShapeReceiver (bool as_edges); EdgeBuildingHierarchyBuilderShapeReceiver (bool as_edges);
virtual void push (const db::Shape &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target); virtual void push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Box &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target); virtual void push (const db::Box &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Polygon &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target); virtual void push (const db::Polygon &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
private: private:
bool m_as_edges; bool m_as_edges;
@ -174,9 +184,9 @@ class DB_PUBLIC EdgePairBuildingHierarchyBuilderShapeReceiver
public: public:
EdgePairBuildingHierarchyBuilderShapeReceiver (); EdgePairBuildingHierarchyBuilderShapeReceiver ();
virtual void push (const db::Shape &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target); virtual void push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Box &, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *) { } virtual void push (const db::Box &, const db::ICplxTrans &, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *) { }
virtual void push (const db::Polygon &, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *) { } virtual void push (const db::Polygon &, const db::ICplxTrans &, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *) { }
}; };
/** /**
@ -203,8 +213,8 @@ public:
typedef std::map<db::cell_index_type, std::vector<db::cell_index_type> > original_target_to_variants_map_type; typedef std::map<db::cell_index_type, std::vector<db::cell_index_type> > original_target_to_variants_map_type;
typedef std::map<db::cell_index_type, db::cell_index_type> variant_to_original_target_map_type; typedef std::map<db::cell_index_type, db::cell_index_type> variant_to_original_target_map_type;
HierarchyBuilder (db::Layout *target, unsigned int target_layer, HierarchyBuilderShapeReceiver *pipe = 0); HierarchyBuilder (db::Layout *target, unsigned int target_layer, const db::ICplxTrans &trans = db::ICplxTrans (), HierarchyBuilderShapeReceiver *pipe = 0);
HierarchyBuilder (db::Layout *target, HierarchyBuilderShapeReceiver *pipe = 0); HierarchyBuilder (db::Layout *target, const db::ICplxTrans &trans = db::ICplxTrans (), HierarchyBuilderShapeReceiver *pipe = 0);
virtual ~HierarchyBuilder (); virtual ~HierarchyBuilder ();
/** /**
@ -306,6 +316,8 @@ private:
unsigned int m_target_layer; unsigned int m_target_layer;
std::vector<std::pair<bool, std::vector<db::Cell *> > > m_cell_stack; std::vector<std::pair<bool, std::vector<db::Cell *> > > m_cell_stack;
db::Cell *mp_initial_cell; db::Cell *mp_initial_cell;
db::ICplxTrans m_trans;
}; };
} }

View File

@ -1135,6 +1135,49 @@ TEST(21_Processors)
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au21.gds"); db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au21.gds");
} }
TEST(22_TwoLayoutsWithDifferentDBU)
{
db::Layout ly1;
{
std::string fn (tl::testsrc ());
fn += "/testdata/algo/deep_region_area_peri_l1.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly1);
}
db::cell_index_type top_cell_index1 = *ly1.begin_top_down ();
db::Cell &top_cell1 = ly1.cell (top_cell_index1);
db::Layout ly2;
{
std::string fn (tl::testsrc ());
fn += "/testdata/algo/deep_region_area_peri_l1_dbu2.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly2);
}
db::cell_index_type top_cell_index2 = *ly2.begin_top_down ();
db::Cell &top_cell2 = ly2.cell (top_cell_index2);
db::DeepShapeStore dss;
unsigned int l11 = ly1.get_layer (db::LayerProperties (1, 0));
db::Region r11 (db::RecursiveShapeIterator (ly1, top_cell1, l11), dss);
unsigned int l12 = ly2.get_layer (db::LayerProperties (2, 0));
db::Region r12 (db::RecursiveShapeIterator (ly2, top_cell2, l12), dss, db::ICplxTrans (ly2.dbu () / ly1.dbu ()));
db::Layout target;
unsigned int target_top_cell_index = target.add_cell (ly1.cell_name (top_cell_index1));
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (1, 0)), r11.sized (1000) ^ r12);
CHECKPOINT();
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au22.gds");
}
TEST(100_Integration) TEST(100_Integration)
{ {
db::Layout ly; db::Layout ly;

View File

@ -144,7 +144,7 @@ TEST(2_WithClip)
db::Layout target; db::Layout target;
db::ClippingHierarchyBuilderShapeReceiver clip; db::ClippingHierarchyBuilderShapeReceiver clip;
db::HierarchyBuilder builder (&target, &clip); db::HierarchyBuilder builder (&target, db::ICplxTrans (), &clip);
db::cell_index_type target_top = target.add_cell ("CLIP_TOP"); db::cell_index_type target_top = target.add_cell ("CLIP_TOP");
@ -183,7 +183,7 @@ TEST(2_WithClipAndSimplification)
db::Layout target; db::Layout target;
db::ReducingHierarchyBuilderShapeReceiver red(0, 1.2, 4); db::ReducingHierarchyBuilderShapeReceiver red(0, 1.2, 4);
db::ClippingHierarchyBuilderShapeReceiver clip(&red); db::ClippingHierarchyBuilderShapeReceiver clip(&red);
db::HierarchyBuilder builder (&target, &clip); db::HierarchyBuilder builder (&target, db::ICplxTrans (), &clip);
db::cell_index_type target_top = target.add_cell ("CLIP_TOP"); db::cell_index_type target_top = target.add_cell ("CLIP_TOP");
@ -222,7 +222,7 @@ TEST(2_WithClipAndRefGeneration)
db::Layout target; db::Layout target;
db::PolygonReferenceHierarchyBuilderShapeReceiver ref(&target); db::PolygonReferenceHierarchyBuilderShapeReceiver ref(&target);
db::ClippingHierarchyBuilderShapeReceiver clip(&ref); db::ClippingHierarchyBuilderShapeReceiver clip(&ref);
db::HierarchyBuilder builder (&target, &clip); db::HierarchyBuilder builder (&target, db::ICplxTrans (), &clip);
db::cell_index_type target_top = target.add_cell ("CLIP_TOP"); db::cell_index_type target_top = target.add_cell ("CLIP_TOP");
@ -261,7 +261,7 @@ TEST(2_WithEmptyResult)
db::Layout target; db::Layout target;
db::PolygonReferenceHierarchyBuilderShapeReceiver ref(&target); db::PolygonReferenceHierarchyBuilderShapeReceiver ref(&target);
db::ClippingHierarchyBuilderShapeReceiver clip(&ref); db::ClippingHierarchyBuilderShapeReceiver clip(&ref);
db::HierarchyBuilder builder (&target, &clip); db::HierarchyBuilder builder (&target, db::ICplxTrans (), &clip);
db::cell_index_type target_top = target.add_cell ("CLIP_TOP"); db::cell_index_type target_top = target.add_cell ("CLIP_TOP");
@ -300,7 +300,7 @@ TEST(2_WithClipAndSimplificationAndEmptyLayer)
db::Layout target; db::Layout target;
db::ReducingHierarchyBuilderShapeReceiver red(0, 1.2, 4); db::ReducingHierarchyBuilderShapeReceiver red(0, 1.2, 4);
db::ClippingHierarchyBuilderShapeReceiver clip(&red); db::ClippingHierarchyBuilderShapeReceiver clip(&red);
db::HierarchyBuilder builder (&target, &clip); db::HierarchyBuilder builder (&target, db::ICplxTrans (), &clip);
db::cell_index_type target_top = target.add_cell ("CLIP_TOP"); db::cell_index_type target_top = target.add_cell ("CLIP_TOP");
@ -349,7 +349,7 @@ TEST(3_ComplexRegionWithClip)
db::Layout target; db::Layout target;
db::ClippingHierarchyBuilderShapeReceiver clip; db::ClippingHierarchyBuilderShapeReceiver clip;
db::HierarchyBuilder builder (&target, &clip); db::HierarchyBuilder builder (&target, db::ICplxTrans (), &clip);
db::cell_index_type target_top = target.add_cell ("CLIP_TOP"); db::cell_index_type target_top = target.add_cell ("CLIP_TOP");
@ -391,7 +391,7 @@ TEST(4_ComplexRegionAndLayoutWithClip)
db::Layout target; db::Layout target;
db::ClippingHierarchyBuilderShapeReceiver clip; db::ClippingHierarchyBuilderShapeReceiver clip;
db::HierarchyBuilder builder (&target, &clip); db::HierarchyBuilder builder (&target, db::ICplxTrans (), &clip);
db::cell_index_type target_top = target.add_cell ("CLIP_TOP"); db::cell_index_type target_top = target.add_cell ("CLIP_TOP");
@ -620,3 +620,76 @@ TEST(7_DetachFromOriginalLayout)
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/hierarchy_builder_au_l5.gds"); db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/hierarchy_builder_au_l5.gds");
} }
TEST(8a_SimpleWithTrans)
{
db::Layout ly;
{
std::string fn (tl::testsrc ());
fn += "/testdata/algo/hierarchy_builder_l1.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
}
db::Layout target;
db::HierarchyBuilder builder (&target, db::ICplxTrans (2.0, 45.0, false, db::Vector ()));
for (db::Layout::layer_iterator li = ly.begin_layers (); li != ly.end_layers (); ++li) {
unsigned int li1 = (*li).first;
unsigned int target_layer = target.insert_layer (*(*li).second);
builder.set_target_layer (target_layer);
db::cell_index_type top_cell_index = *ly.begin_top_down ();
db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), li1);
iter.push (&builder);
}
CHECKPOINT();
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/hierarchy_builder_au8a.gds");
}
TEST(8b_ComplexRegionWithTransformation)
{
db::Layout ly;
{
std::string fn (tl::testsrc ());
fn += "/testdata/algo/hierarchy_builder_l2.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
}
db::Layout target;
db::ClippingHierarchyBuilderShapeReceiver clip;
db::HierarchyBuilder builder (&target, db::ICplxTrans (2.0, 45.0, false, db::Vector ()), &clip);
db::cell_index_type target_top = target.add_cell ("CLIP_TOP");
for (db::Layout::layer_iterator li = ly.begin_layers (); li != ly.end_layers (); ++li) {
builder.reset ();
unsigned int li1 = (*li).first;
unsigned int target_layer = target.insert_layer (*(*li).second);
builder.set_target_layer (target_layer);
db::cell_index_type top_cell_index = *ly.begin_top_down ();
db::Region reg;
reg.insert (db::Box (5000, 13000, 18500, 20000));
reg.insert (db::Box (11000, 20000, 18500, 36000));
reg.merge ();
db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), li1, reg);
iter.push (&builder);
target.cell (target_top).insert (db::CellInstArray (db::CellInst (builder.initial_cell ()->cell_index ()), db::Trans ()));
}
CHECKPOINT();
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/hierarchy_builder_au8b.gds");
}

Binary file not shown.

BIN
testdata/algo/deep_region_au22.gds vendored Normal file

Binary file not shown.

BIN
testdata/algo/hierarchy_builder_au8a.gds vendored Normal file

Binary file not shown.

BIN
testdata/algo/hierarchy_builder_au8b.gds vendored Normal file

Binary file not shown.