diff --git a/src/db/db/dbDeepEdgePairs.cc b/src/db/db/dbDeepEdgePairs.cc index 123c72050..316da3271 100644 --- a/src/db/db/dbDeepEdgePairs.cc +++ b/src/db/db/dbDeepEdgePairs.cc @@ -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) diff --git a/src/db/db/dbDeepEdges.cc b/src/db/db/dbDeepEdges.cc index 6363e8ddc..29977a324 100644 --- a/src/db/db/dbDeepEdges.cc +++ b/src/db/db/dbDeepEdges.cc @@ -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); } diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index ce1b5a6e0..9e0f34f90 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -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); } diff --git a/src/db/db/dbDeepShapeStore.cc b/src/db/db/dbDeepShapeStore.cc index 2d43f7e8c..4bb5fb661 100644 --- a/src/db/db/dbDeepShapeStore.cc +++ b/src/db/db/dbDeepShapeStore.cc @@ -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; diff --git a/src/db/db/dbDeepShapeStore.h b/src/db/db/dbDeepShapeStore.h index cc6df29e1..0ea2bba60 100644 --- a/src/db/db/dbDeepShapeStore.h +++ b/src/db/db/dbDeepShapeStore.h @@ -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 &a, const std::pair &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 > &var_map); - typedef std::map layout_map_type; + typedef std::map, unsigned int, RecursiveShapeIteratorCompareForTargetHierarchy> layout_map_type; // no copying DeepShapeStore (const DeepShapeStore &); diff --git a/src/db/db/dbHierarchyBuilder.cc b/src/db/db/dbHierarchyBuilder.cc index 65206e91a..a9e239d88 100644 --- a/src/db/db/dbHierarchyBuilder.cc +++ b/src/db/db/dbHierarchyBuilder.cc @@ -135,14 +135,14 @@ static std::pair > 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::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::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::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 ®ion, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) +ClippingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box ®ion, 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 ®ion, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) +ClippingHierarchyBuilderShapeReceiver::push (const db::Box &shape, const db::ICplxTrans &trans, const db::Box ®ion, 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 ®ion, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) +ClippingHierarchyBuilderShapeReceiver::push (const db::Polygon &shape, const db::ICplxTrans &trans, const db::Box ®ion, 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 ®ion, 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 ®ion, 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 ()); ! 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 ®ion, 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 ®ion, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) { std::vector clipped_poly; static db::Box world = db::Box::world (); @@ -495,7 +497,7 @@ ClippingHierarchyBuilderShapeReceiver::insert_clipped (const db::Polygon &poly, } for (std::vector::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 ®ion, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) +ReducingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box ®ion, 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 ®ion, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) +ReducingHierarchyBuilderShapeReceiver::push (const db::Box &shape, const db::ICplxTrans &trans, const db::Box ®ion, 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 ®ion, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) +ReducingHierarchyBuilderShapeReceiver::push (const db::Polygon &shape, const db::ICplxTrans &trans, const db::Box ®ion, 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 ®ion, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) +ReducingHierarchyBuilderShapeReceiver::reduce (const db::Polygon &poly, const db::ICplxTrans &trans, const db::Box ®ion, 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 split_polygons; db::split_polygon (poly, split_polygons); for (std::vector ::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 ®ion, 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 ®ion, 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)); } } diff --git a/src/db/db/dbHierarchyBuilder.h b/src/db/db/dbHierarchyBuilder.h index 747a44819..a42e251bc 100644 --- a/src/db/db/dbHierarchyBuilder.h +++ b/src/db/db/dbHierarchyBuilder.h @@ -55,9 +55,9 @@ public: HierarchyBuilderShapeReceiver () { } virtual ~HierarchyBuilderShapeReceiver () { } - virtual void push (const db::Shape &shape, const db::Box ®ion, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) = 0; - virtual void push (const db::Box &shape, const db::Box ®ion, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target) = 0; - virtual void push (const db::Polygon &shape, const db::Box ®ion, 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 ®ion, 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 ®ion, 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 ®ion, 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 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) { - target->insert (shape); + 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 ®ion, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target); - void insert_clipped (const db::Polygon &poly, const db::Box ®ion, 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 ®ion, 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 ®ion, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target); static bool is_inside (const db::Box &box, const db::Box ®ion, const db::RecursiveShapeReceiver::box_tree_type *complex_region); static bool is_outside (const db::Box &box, const db::Box ®ion, 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 ®ion, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target); + void reduce (const db::Polygon &poly, const db::ICplxTrans &trans, const db::Box ®ion, 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 > original_target_to_variants_map_type; typedef std::map 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 > > m_cell_stack; db::Cell *mp_initial_cell; + + db::ICplxTrans m_trans; }; } diff --git a/src/db/unit_tests/dbDeepRegionTests.cc b/src/db/unit_tests/dbDeepRegionTests.cc index 8f10a29e1..365fb797c 100644 --- a/src/db/unit_tests/dbDeepRegionTests.cc +++ b/src/db/unit_tests/dbDeepRegionTests.cc @@ -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; diff --git a/src/db/unit_tests/dbHierarchyBuilderTests.cc b/src/db/unit_tests/dbHierarchyBuilderTests.cc index c5eb117ca..9bc86b860 100644 --- a/src/db/unit_tests/dbHierarchyBuilderTests.cc +++ b/src/db/unit_tests/dbHierarchyBuilderTests.cc @@ -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"); +} + diff --git a/testdata/algo/deep_region_area_peri_l1_dbu2.gds b/testdata/algo/deep_region_area_peri_l1_dbu2.gds new file mode 100644 index 000000000..bc2ecc13d Binary files /dev/null and b/testdata/algo/deep_region_area_peri_l1_dbu2.gds differ diff --git a/testdata/algo/deep_region_au22.gds b/testdata/algo/deep_region_au22.gds new file mode 100644 index 000000000..d6eb6242a Binary files /dev/null and b/testdata/algo/deep_region_au22.gds differ diff --git a/testdata/algo/hierarchy_builder_au8a.gds b/testdata/algo/hierarchy_builder_au8a.gds new file mode 100644 index 000000000..44fb9379b Binary files /dev/null and b/testdata/algo/hierarchy_builder_au8a.gds differ diff --git a/testdata/algo/hierarchy_builder_au8b.gds b/testdata/algo/hierarchy_builder_au8b.gds new file mode 100644 index 000000000..3e500867d Binary files /dev/null and b/testdata/algo/hierarchy_builder_au8b.gds differ