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)
: 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)

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)
: 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 ();
tl_assert (trans.is_unity ()); // TODO: implement
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)
: 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 ();
tl_assert (trans.is_unity ()); // TODO: implement
set_merged_semantics (merged_semantics);
}

View File

@ -221,8 +221,8 @@ DeepLayer::check_dss () const
struct DeepShapeStore::LayoutHolder
{
LayoutHolder ()
: refs (0), layout (false), builder (&layout)
LayoutHolder (const db::ICplxTrans &trans)
: refs (0), layout (false), builder (&layout, trans)
{
// .. nothing yet ..
}
@ -364,22 +364,22 @@ void DeepShapeStore::remove_ref (unsigned int layout, unsigned int layer)
}
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 ()) {
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;
layout.hier_changed_event.add (this, &DeepShapeStore::invalidate_hier);
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;
} 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) {
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;
}
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::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);
}
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::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);
}
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::HierarchyBuilder &builder = m_layouts[layout_index]->builder;

View File

@ -201,9 +201,13 @@ private:
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)
* 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
@ -270,7 +274,7 @@ public:
* 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.
*/
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
@ -279,7 +283,7 @@ public:
* working copy of the original layer. This method creates a layer
* 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
@ -522,13 +526,13 @@ private:
void add_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 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
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);
}
HierarchyBuilder::HierarchyBuilder (db::Layout *target, unsigned int target_layer, HierarchyBuilderShapeReceiver *pipe)
: mp_target (target), m_initial_pass (true), m_cm_new_entry (false), m_target_layer (target_layer)
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), m_trans (trans)
{
set_shape_receiver (pipe);
}
HierarchyBuilder::HierarchyBuilder (db::Layout *target, HierarchyBuilderShapeReceiver *pipe)
: mp_target (target), m_initial_pass (true), m_cm_new_entry (false), m_target_layer (0)
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), m_trans (trans)
{
set_shape_receiver (pipe);
}
@ -283,6 +283,7 @@ HierarchyBuilder::new_inst (const RecursiveShapeIterator *iter, const db::CellIn
if (m_cell_stack.back ().first) {
db::CellInstArray new_inst (inst, &mp_target->array_repository ());
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) {
(*c)->insert (new_inst);
}
@ -332,6 +333,7 @@ HierarchyBuilder::new_inst_member (const RecursiveShapeIterator *iter, const db:
// for a new cell, create this instance
if (m_cell_stack.back ().first) {
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) {
(*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) {
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
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 ();
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)) {
// clip the shape if required
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 ()) {
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 ()) {
db::Polygon poly;
shape.polygon (poly);
insert_clipped (poly, region, complex_region, target);
insert_clipped (poly, trans, region, complex_region, target);
}
}
}
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 ();
if (! complex_region) {
db::Box r = shape & region;
if (! r.empty()) {
mp_pipe->push (r, world, 0, target);
mp_pipe->push (r, trans, world, 0, target);
}
} else {
insert_clipped (shape, region, complex_region, target);
insert_clipped (shape, trans, region, complex_region, target);
}
}
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 ();
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 {
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
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;
static db::Box world = db::Box::world ();
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) {
mp_pipe->push (*cr & bb, world, 0, target);
mp_pipe->push (*cr & bb, trans, world, 0, target);
}
} else {
mp_pipe->push (bb, world, 0, target);
mp_pipe->push (bb, trans, world, 0, target);
}
}
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;
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) {
mp_pipe->push (*p, world, 0, target);
mp_pipe->push (*p, trans, world, 0, target);
}
}
@ -508,44 +510,44 @@ ReducingHierarchyBuilderShapeReceiver::ReducingHierarchyBuilderShapeReceiver (Hi
}
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 ()) {
mp_pipe->push (shape, region, complex_region, target);
mp_pipe->push (shape, trans, region, complex_region, target);
} 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 ()) {
db::Polygon poly;
shape.polygon (poly);
reduce (poly, region, complex_region, target);
reduce (poly, trans, region, complex_region, target);
}
}
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
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
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) {
std::vector <db::Polygon> split_polygons;
db::split_polygon (poly, split_polygons);
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 {
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 ()) {
db::Polygon poly;
shape.polygon (poly);
if (! trans.is_unity ()) {
poly.transform (trans);
}
target->insert (db::PolygonRef (poly, mp_layout->shape_repository ()));
} 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));
if (! trans.is_unity ()) {
poly.transform (trans);
}
db::PolygonRef pref (poly, mp_layout->shape_repository ());
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 ..
}
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 ())) {
db::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 ()) {
push (shape.box (), region, complex_region, target);
push (shape.box (), trans, region, complex_region, target);
} else if (shape.is_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 ()) {
target->insert (db::Edge (box.p1 (), box.upper_left ()));
target->insert (db::Edge (box.upper_left (), box.p2 ()));
target->insert (db::Edge (box.p2 (), box.lower_right ()));
target->insert (db::Edge (box.lower_right (), box.p1 ()));
target->insert (db::Edge (box.p1 (), box.upper_left ()).transformed (trans));
target->insert (db::Edge (box.upper_left (), box.p2 ()).transformed (trans));
target->insert (db::Edge (box.p2 (), box.lower_right ()).transformed (trans));
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) {
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 ..
}
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 ()) {
target->insert (shape.edge_pair ());
target->insert (shape.edge_pair ().transformed (trans));
}
}

View File

@ -55,9 +55,9 @@ public:
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::Box &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::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::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::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:
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);
} else {
target->insert (shape.transformed (trans));
}
}
};
@ -94,13 +104,13 @@ class DB_PUBLIC ClippingHierarchyBuilderShapeReceiver
public:
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::Box &shape, 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::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::ICplxTrans &trans, 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:
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::Polygon &poly, 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::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_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:
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::Box &shape, 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::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::ICplxTrans &trans, 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:
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;
double m_area_ratio;
@ -137,9 +147,9 @@ class DB_PUBLIC PolygonReferenceHierarchyBuilderShapeReceiver
public:
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::Box &shape, 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::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::ICplxTrans &trans, 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:
db::Layout *mp_layout;
@ -157,9 +167,9 @@ class DB_PUBLIC EdgeBuildingHierarchyBuilderShapeReceiver
public:
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::Box &shape, 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::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::ICplxTrans &trans, 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:
bool m_as_edges;
@ -174,9 +184,9 @@ class DB_PUBLIC EdgePairBuildingHierarchyBuilderShapeReceiver
public:
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::Box &, 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::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::ICplxTrans &, 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, 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, HierarchyBuilderShapeReceiver *pipe = 0);
HierarchyBuilder (db::Layout *target, unsigned int target_layer, const db::ICplxTrans &trans = db::ICplxTrans (), HierarchyBuilderShapeReceiver *pipe = 0);
HierarchyBuilder (db::Layout *target, const db::ICplxTrans &trans = db::ICplxTrans (), HierarchyBuilderShapeReceiver *pipe = 0);
virtual ~HierarchyBuilder ();
/**
@ -306,6 +316,8 @@ private:
unsigned int m_target_layer;
std::vector<std::pair<bool, std::vector<db::Cell *> > > m_cell_stack;
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");
}
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)
{
db::Layout ly;

View File

@ -144,7 +144,7 @@ TEST(2_WithClip)
db::Layout target;
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");
@ -183,7 +183,7 @@ TEST(2_WithClipAndSimplification)
db::Layout target;
db::ReducingHierarchyBuilderShapeReceiver red(0, 1.2, 4);
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");
@ -222,7 +222,7 @@ TEST(2_WithClipAndRefGeneration)
db::Layout target;
db::PolygonReferenceHierarchyBuilderShapeReceiver ref(&target);
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");
@ -261,7 +261,7 @@ TEST(2_WithEmptyResult)
db::Layout target;
db::PolygonReferenceHierarchyBuilderShapeReceiver ref(&target);
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");
@ -300,7 +300,7 @@ TEST(2_WithClipAndSimplificationAndEmptyLayer)
db::Layout target;
db::ReducingHierarchyBuilderShapeReceiver red(0, 1.2, 4);
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");
@ -349,7 +349,7 @@ TEST(3_ComplexRegionWithClip)
db::Layout target;
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");
@ -391,7 +391,7 @@ TEST(4_ComplexRegionAndLayoutWithClip)
db::Layout target;
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");
@ -620,3 +620,76 @@ TEST(7_DetachFromOriginalLayout)
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.