diff --git a/src/db/db/dbCellVariants.cc b/src/db/db/dbCellVariants.cc index 9e274d6c5..b842b2585 100644 --- a/src/db/db/dbCellVariants.cc +++ b/src/db/db/dbCellVariants.cc @@ -230,32 +230,45 @@ VariantsCollectorBase::collect (const db::Layout &layout, const db::Cell &top_ce { tl_assert (mp_red != 0); - // The top cell gets a "variant" with unit transformation - m_variants [top_cell.cell_index ()].insert (std::make_pair (db::ICplxTrans (), 1)); + m_called.clear (); + m_called.insert (top_cell.cell_index ()); - std::set called; - top_cell.collect_called_cells (called); + top_cell.collect_called_cells (m_called); for (db::Layout::top_down_const_iterator c = layout.begin_top_down (); c != layout.end_top_down (); ++c) { - if (called.find (*c) == called.end ()) { + if (m_called.find (*c) == m_called.end ()) { continue; } // collect the parent variants per parent cell - std::map > variants_per_parent_cell; + std::map > variants_per_parent_cell; for (db::Cell::parent_inst_iterator pi = layout.cell (*c).begin_parent_insts (); ! pi.at_end (); ++pi) { - std::map &variants = variants_per_parent_cell [pi->inst ().object ().cell_index ()]; + std::set &variants = variants_per_parent_cell [pi->inst ().object ().cell_index ()]; add_variant (variants, pi->child_inst ().cell_inst (), mp_red->is_translation_invariant ()); } // compute the resulting variants - std::map &new_variants = m_variants [*c]; + std::set new_variants; - for (std::map >::const_iterator pv = variants_per_parent_cell.begin (); pv != variants_per_parent_cell.end (); ++pv) { - product (variants (pv->first), pv->second, new_variants); + auto vc = m_variants.find (*c); + if (vc != m_variants.end ()) { + new_variants = vc->second; + } + + for (auto pv = variants_per_parent_cell.begin (); pv != variants_per_parent_cell.end (); ++pv) { + auto v = m_variants.find (pv->first); + if (v != m_variants.end ()) { + product (v->second, pv->second, new_variants); + } else { + new_variants.insert (pv->second.begin (), pv->second.end ()); + } + } + + if (new_variants.size () > 1 || (new_variants.size () == 1 && ! new_variants.begin ()->is_unity ())) { + m_variants [*c] = std::move (new_variants); } } @@ -287,8 +300,8 @@ VariantsCollectorBase::separate_variants (db::Layout &layout, db::Cell &top_cell db::Cell &cell = layout.cell (*c); - std::map &vv = m_variants [*c]; - if (vv.size () > 1) { + auto vc = m_variants.find (*c); + if (vc != m_variants.end () && vc->second.size () > 1) { std::map &vt = (*var_table) [*c]; @@ -302,11 +315,11 @@ VariantsCollectorBase::separate_variants (db::Layout &layout, db::Cell &top_cell cell.clear_insts (); int index = 0; - for (std::map::const_iterator v = vv.begin (); v != vv.end (); ++v, ++index) { + for (auto v = vc->second.begin (); v != vc->second.end (); ++v, ++index) { db::cell_index_type ci_var; - if (v != vv.begin ()) { + if (v != vc->second.begin ()) { std::string var_name = layout.cell_name (*c); var_name += "$VAR" + tl::to_string (index); @@ -316,21 +329,27 @@ VariantsCollectorBase::separate_variants (db::Layout &layout, db::Cell &top_cell copy_shapes (layout, ci_var, *c); // a new entry for the variant - m_variants [ci_var].insert (*v); + if (! v->is_unity ()) { + m_variants [ci_var].insert (*v); + } } else { ci_var = *c; } - vt.insert (std::make_pair (v->first, ci_var)); - create_var_instances (layout.cell (ci_var), inst, v->first, *var_table, mp_red->is_translation_invariant ()); + vt.insert (std::make_pair (*v, ci_var)); + create_var_instances (layout.cell (ci_var), inst, *v, *var_table, mp_red->is_translation_invariant ()); } // correct the first (remaining) entry - std::pair v1 = *vt.begin (); - vv.clear (); - vv.insert (v1); + if (! vt.begin ()->first.is_unity ()) { + std::set &tv = m_variants [*c]; + tv.clear (); + tv.insert (vt.begin ()->first); + } else { + m_variants.erase (*c); + } } else { @@ -352,7 +371,12 @@ VariantsCollectorBase::separate_variants (db::Layout &layout, db::Cell &top_cell } cell.clear_insts (); - create_var_instances (cell, inst, vv.begin ()->first, *var_table, mp_red->is_translation_invariant ()); + + if (vc != m_variants.end ()) { + create_var_instances (cell, inst, *vc->second.begin (), *var_table, mp_red->is_translation_invariant ()); + } else { + create_var_instances (cell, inst, db::ICplxTrans (), *var_table, mp_red->is_translation_invariant ()); + } } @@ -387,14 +411,14 @@ VariantsCollectorBase::commit_shapes (db::Layout &layout, db::Cell &top_cell, un db::Cell &cell = layout.cell (*c); - std::map &vvc = m_variants [*c]; - if (vvc.size () > 1) { + auto vvc = m_variants.find (*c); + if (vvc != m_variants.end () && vvc->second.size () > 1) { - for (std::map::const_iterator vc = vvc.begin (); vc != vvc.end (); ++vc) { + for (auto vc = vvc->second.begin (); vc != vvc->second.end (); ++vc) { for (db::Cell::const_iterator i = cell.begin (); ! i.at_end (); ++i) { - std::map >::const_iterator tc = to_commit.find (i->cell_index ()); + auto tc = to_commit.find (i->cell_index ()); if (tc != to_commit.end ()) { const std::map &vt = tc->second; @@ -406,11 +430,11 @@ VariantsCollectorBase::commit_shapes (db::Layout &layout, db::Cell &top_cell, un for (db::CellInstArray::iterator ia = i->begin (); ! ia.at_end (); ++ia) { db::ICplxTrans t = i->complex_trans (*ia); - db::ICplxTrans rt = mp_red->reduce (vc->first * mp_red->reduce_trans (t)); + db::ICplxTrans rt = mp_red->reduce (*vc * mp_red->reduce_trans (t)); std::map::const_iterator v = vt.find (rt); if (v != vt.end ()) { - db::Shapes &ps = propagated [vc->first]; + db::Shapes &ps = propagated [*vc]; tl::ident_map pm; for (db::Shapes::shape_iterator si = v->second.begin (db::ShapeIterator::All); ! si.at_end (); ++si) { @@ -431,7 +455,7 @@ VariantsCollectorBase::commit_shapes (db::Layout &layout, db::Cell &top_cell, un // single variant -> we can commit any shapes we have kept for this cell directly to the cell - std::map >::iterator l = to_commit.find (*c); + auto l = to_commit.find (*c); if (l != to_commit.end ()) { tl_assert (l->second.size () == 1); cell.shapes (layer).insert (l->second.begin ()->second); @@ -442,7 +466,7 @@ VariantsCollectorBase::commit_shapes (db::Layout &layout, db::Cell &top_cell, un for (db::Cell::const_iterator i = cell.begin (); ! i.at_end (); ++i) { - std::map >::const_iterator tc = to_commit.find (i->cell_index ()); + auto tc = to_commit.find (i->cell_index ()); if (tc != to_commit.end ()) { const std::map &vt = tc->second; @@ -450,7 +474,10 @@ VariantsCollectorBase::commit_shapes (db::Layout &layout, db::Cell &top_cell, un for (db::CellInstArray::iterator ia = i->begin (); ! ia.at_end (); ++ia) { db::ICplxTrans t = i->complex_trans (*ia); - db::ICplxTrans rt = mp_red->reduce (vvc.begin ()->first * mp_red->reduce_trans (t)); + db::ICplxTrans rt = mp_red->reduce_trans (t); + if (vvc != m_variants.end ()) { + rt = mp_red->reduce (*vvc->second.begin () * rt); + } std::map::const_iterator v = vt.find (rt); if (v != vt.end ()) { @@ -474,22 +501,49 @@ VariantsCollectorBase::commit_shapes (db::Layout &layout, db::Cell &top_cell, un } } -const std::map & +static std::set make_once () +{ + std::set res; + res.insert (db::ICplxTrans ()); + return res; +} + +static std::set s_once (make_once ()); + +const std::set & VariantsCollectorBase::variants (db::cell_index_type ci) const { - std::map >::const_iterator v = m_variants.find (ci); - static std::map empty_set; + if (m_called.find (ci) == m_called.end ()) { + static std::set empty; + return empty; + } + + auto v = m_variants.find (ci); if (v == m_variants.end ()) { - return empty_set; + return s_once; } else { return v->second; } } +const db::ICplxTrans & +VariantsCollectorBase::single_variant_transformation (db::cell_index_type ci) const +{ + auto v = m_variants.find (ci); + + if (v == m_variants.end ()) { + static db::ICplxTrans tr1; + return tr1; + } else { + tl_assert (v->second.size () == 1); + return *v->second.begin (); + } +} + bool VariantsCollectorBase::has_variants () const { - for (std::map >::const_iterator i = m_variants.begin (); i != m_variants.end (); ++i) { + for (auto i = m_variants.begin (); i != m_variants.end (); ++i) { if (i->second.size () > 1) { return true; } @@ -498,7 +552,7 @@ VariantsCollectorBase::has_variants () const } void -VariantsCollectorBase::add_variant (std::map &variants, const db::CellInstArray &inst, bool tl_invariant) const +VariantsCollectorBase::add_variant (std::set &variants, const db::CellInstArray &inst, bool tl_invariant) const { if (tl_invariant) { add_variant_tl_invariant (variants, inst); @@ -508,35 +562,35 @@ VariantsCollectorBase::add_variant (std::map &variants, } void -VariantsCollectorBase::add_variant_non_tl_invariant (std::map &variants, const db::CellInstArray &inst) const +VariantsCollectorBase::add_variant_non_tl_invariant (std::set &variants, const db::CellInstArray &inst) const { if (inst.is_complex ()) { for (db::CellInstArray::iterator i = inst.begin (); ! i.at_end (); ++i) { - variants [mp_red->reduce_trans (inst.complex_trans (*i))] += 1; + variants.insert (mp_red->reduce_trans (inst.complex_trans (*i))); } } else { for (db::CellInstArray::iterator i = inst.begin (); ! i.at_end (); ++i) { - variants [db::ICplxTrans (mp_red->reduce_trans (*i))] += 1; + variants.insert (db::ICplxTrans (mp_red->reduce_trans (*i))); } } } void -VariantsCollectorBase::add_variant_tl_invariant (std::map &variants, const db::CellInstArray &inst) const +VariantsCollectorBase::add_variant_tl_invariant (std::set &variants, const db::CellInstArray &inst) const { if (inst.is_complex ()) { - variants [mp_red->reduce_trans (inst.complex_trans ())] += inst.size (); + variants.insert (mp_red->reduce_trans (inst.complex_trans ())); } else { - variants [db::ICplxTrans (mp_red->reduce_trans (inst.front ()))] += inst.size (); + variants.insert (db::ICplxTrans (mp_red->reduce_trans (inst.front ()))); } } void -VariantsCollectorBase::product (const std::map &v1, const std::map &v2, std::map &prod) const +VariantsCollectorBase::product (const std::set &v1, const std::set &v2, std::set &prod) const { - for (std::map::const_iterator i = v1.begin (); i != v1.end (); ++i) { - for (std::map::const_iterator j = v2.begin (); j != v2.end (); ++j) { - prod [mp_red->reduce (i->first * j->first)] += i->second * j->second; + for (auto i = v1.begin (); i != v1.end (); ++i) { + for (auto j = v2.begin (); j != v2.end (); ++j) { + prod.insert (mp_red->reduce (*i * *j)); } } } @@ -564,9 +618,9 @@ VariantsCollectorBase::create_var_instances (db::Cell &in_cell, std::vector &inst, const db::ICplxTrans &for_var, const std::map > &var_table) const { - for (std::vector::const_iterator i = inst.begin (); i != inst.end (); ++i) { + for (auto i = inst.begin (); i != inst.end (); ++i) { - std::map >::const_iterator f = var_table.find (i->object ().cell_index ()); + auto f = var_table.find (i->object ().cell_index ()); if (f == var_table.end ()) { in_cell.insert (*i); @@ -626,9 +680,9 @@ VariantsCollectorBase::create_var_instances_non_tl_invariant (db::Cell &in_cell, void VariantsCollectorBase::create_var_instances_tl_invariant (db::Cell &in_cell, std::vector &inst, const db::ICplxTrans &for_var, const std::map > &var_table) const { - for (std::vector::const_iterator i = inst.begin (); i != inst.end (); ++i) { + for (auto i = inst.begin (); i != inst.end (); ++i) { - std::map >::const_iterator f = var_table.find (i->object ().cell_index ()); + auto f = var_table.find (i->object ().cell_index ()); if (f == var_table.end ()) { in_cell.insert (*i); diff --git a/src/db/db/dbCellVariants.h b/src/db/db/dbCellVariants.h index 798771a6f..8375c1c11 100644 --- a/src/db/db/dbCellVariants.h +++ b/src/db/db/dbCellVariants.h @@ -216,7 +216,15 @@ public: * The keys of the map are the variants, the values is the instance count of the variant * (as seen from the top cell). */ - const std::map &variants (db::cell_index_type ci) const; + const std::set &variants (db::cell_index_type ci) const; + + /** + * @brief Gets the transformation for a single variant + * + * This requires the cell not to be a variant (i.e. already separated). + * It returns the corresponding transformation. + */ + const db::ICplxTrans &single_variant_transformation (db::cell_index_type ci) const; /** * @brief Returns true, if variants have been built @@ -229,13 +237,14 @@ public: static void copy_shapes (db::Layout &layout, db::cell_index_type ci_to, db::cell_index_type ci_from); private: - std::map > m_variants; + std::map > m_variants; + std::set m_called; const TransformationReducer *mp_red; - void add_variant (std::map &variants, const db::CellInstArray &inst, bool tl_invariant) const; - void add_variant_non_tl_invariant (std::map &variants, const db::CellInstArray &inst) const; - void add_variant_tl_invariant (std::map &variants, const db::CellInstArray &inst) const; - void product (const std::map &v1, const std::map &v2, std::map &prod) const; + void add_variant (std::set &variants, const db::CellInstArray &inst, bool tl_invariant) const; + void add_variant_non_tl_invariant (std::set &variants, const db::CellInstArray &inst) const; + void add_variant_tl_invariant (std::set &variants, const db::CellInstArray &inst) const; + void product (const std::set &v1, const std::set &v2, std::set &prod) const; void create_var_instances (db::Cell &in_cell, std::vector &inst, const db::ICplxTrans &for_var, const std::map > &var_table, bool tl_invariant) const; void create_var_instances_non_tl_invariant (db::Cell &in_cell, std::vector &inst, const db::ICplxTrans &for_var, const std::map > &var_table) const; void create_var_instances_tl_invariant (db::Cell &in_cell, std::vector &inst, const db::ICplxTrans &for_var, const std::map > &var_table) const; diff --git a/src/db/db/dbCompoundOperation.h b/src/db/db/dbCompoundOperation.h index 953768c18..39c2de489 100644 --- a/src/db/db/dbCompoundOperation.h +++ b/src/db/db/dbCompoundOperation.h @@ -432,7 +432,7 @@ public: virtual bool is_translation_invariant () const; // NOTE: equality does not really matter here as we use it only on leaf reducers - virtual bool equals (const TransformationReducer *other) const { return false; } + virtual bool equals (const TransformationReducer * /*other*/) const { return false; } private: std::vector m_vars; @@ -1161,9 +1161,7 @@ private: // in the presence of variants, handle the object in top level space - const std::map &vv = proc->vars ()->variants (cell->cell_index ()); - tl_assert (vv.size () == 1); - const db::ICplxTrans &tr = vv.begin ()->first; + const db::ICplxTrans &tr = proc->vars ()->single_variant_transformation (cell->cell_index ()); processed (layout, *p, tr, res); } else { @@ -1314,9 +1312,7 @@ private: // in the presence of variants, handle the object in top level space - const std::map &vv = proc->vars ()->variants (cell->cell_index ()); - tl_assert (vv.size () == 1); - const db::ICplxTrans &tr = vv.begin ()->first; + const db::ICplxTrans &tr = proc->vars ()->single_variant_transformation (cell->cell_index ()); processed (layout, tr * *p, res); if (! res.empty ()) { @@ -1383,9 +1379,7 @@ private: // in the presence of variants, handle the object in top level space - const std::map &vv = proc->vars ()->variants (cell->cell_index ()); - tl_assert (vv.size () == 1); - const db::ICplxTrans &tr = vv.begin ()->first; + const db::ICplxTrans &tr = proc->vars ()->single_variant_transformation (cell->cell_index ()); processed (layout, tr * *p, res); if (! res.empty ()) { @@ -1453,9 +1447,7 @@ private: // in the presence of variants, handle the object in top level space - const std::map &vv = proc->vars ()->variants (cell->cell_index ()); - tl_assert (vv.size () == 1); - const db::ICplxTrans &tr = vv.begin ()->first; + const db::ICplxTrans &tr = proc->vars ()->single_variant_transformation (cell->cell_index ()); processed (layout, tr * *p, res); if (! res.empty ()) { @@ -1520,9 +1512,7 @@ private: // in the presence of variants, handle the object in top level space - const std::map &vv = proc->vars ()->variants (cell->cell_index ()); - tl_assert (vv.size () == 1); - const db::ICplxTrans &tr = vv.begin ()->first; + const db::ICplxTrans &tr = proc->vars ()->single_variant_transformation (cell->cell_index ()); mp_proc->process (tr * *p, res); if (! res.empty ()) { @@ -1592,9 +1582,7 @@ private: // in the presence of variants, handle the object in top level space - const std::map &vv = proc->vars ()->variants (cell->cell_index ()); - tl_assert (vv.size () == 1); - const db::ICplxTrans &tr = vv.begin ()->first; + const db::ICplxTrans &tr = proc->vars ()->single_variant_transformation (cell->cell_index ()); processed (layout, *p, tr, res); } else { @@ -1667,9 +1655,7 @@ private: // in the presence of variants, handle the object in top level space - const std::map &vv = proc->vars ()->variants (cell->cell_index ()); - tl_assert (vv.size () == 1); - const db::ICplxTrans &tr = vv.begin ()->first; + const db::ICplxTrans &tr = proc->vars ()->single_variant_transformation (cell->cell_index ()); processed (layout, *p, tr, res); } else { diff --git a/src/db/db/dbDeepEdgePairs.cc b/src/db/db/dbDeepEdgePairs.cc index 0884a3d41..783727fa7 100644 --- a/src/db/db/dbDeepEdgePairs.cc +++ b/src/db/db/dbDeepEdgePairs.cc @@ -410,17 +410,17 @@ DeepEdgePairs::apply_filter (const EdgePairFilterBase &filter) const if (vars.get ()) { - const std::map &vv = vars->variants (c->cell_index ()); - for (std::map::const_iterator v = vv.begin (); v != vv.end (); ++v) { + const std::set &vv = vars->variants (c->cell_index ()); + for (auto v = vv.begin (); v != vv.end (); ++v) { db::Shapes *st; if (vv.size () == 1) { st = & c->shapes (res->deep_layer ().layer ()); } else { - st = & to_commit [c->cell_index ()] [v->first]; + st = & to_commit [c->cell_index ()] [*v]; } - const db::ICplxTrans &tr = v->first; + const db::ICplxTrans &tr = *v; for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::EdgePairs); ! si.at_end (); ++si) { if (filter.selected (si->edge_pair ().transformed (tr))) { diff --git a/src/db/db/dbDeepEdges.cc b/src/db/db/dbDeepEdges.cc index 6c1438a22..719534e7d 100644 --- a/src/db/db/dbDeepEdges.cc +++ b/src/db/db/dbDeepEdges.cc @@ -256,10 +256,8 @@ static void transform_deep_layer (db::DeepLayer &deep_layer, const Trans &t) for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) { - const std::map &v = vars.variants (c->cell_index ()); - tl_assert (v.size () == size_t (1)); - - db::Trans tr (v.begin ()->first.inverted () * t.disp ()); + const db::ICplxTrans &tv = vars.single_variant_transformation (c->cell_index ()); + db::ICplxTrans tr (tv.inverted () * t.disp ()); db::Shapes &shapes = c->shapes (deep_layer.layer ()); db::Shapes new_shapes (layout.manager (), c.operator-> (), layout.is_editable ()); @@ -750,10 +748,10 @@ DeepEdges::length_type DeepEdges::length (const db::Box &box) const for (db::ShapeIterator s = layout.cell (*c).shapes (edges.layer ()).begin (db::ShapeIterator::Edges); ! s.at_end (); ++s) { lc += s->edge ().length (); } - const std::map &vv = vars.variants (*c); - for (std::map::const_iterator v = vv.begin (); v != vv.end (); ++v) { - double mag = v->first.mag (); - l += v->second * lc * mag; + const std::set &vv = vars.variants (*c); + for (auto v = vv.begin (); v != vv.end (); ++v) { + double mag = v->mag (); + // @@@ l += v->second * lc * mag; } } @@ -836,20 +834,18 @@ DeepEdges::apply_filter (const EdgeFilterBase &filter) const if (vars.get ()) { - const std::map &vv = vars->variants (c->cell_index ()); - for (std::map::const_iterator v = vv.begin (); v != vv.end (); ++v) { + const std::set &vv = vars->variants (c->cell_index ()); + for (auto v = vv.begin (); v != vv.end (); ++v) { db::Shapes *st; if (vv.size () == 1) { st = & c->shapes (res->deep_layer ().layer ()); } else { - st = & to_commit [c->cell_index ()] [v->first]; + st = & to_commit [c->cell_index ()] [*v]; } - const db::ICplxTrans &tr = v->first; - for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Edges); ! si.at_end (); ++si) { - if (filter.selected (si->edge ().transformed (tr))) { + if (filter.selected (si->edge ().transformed (*v))) { st->insert (*si); } } @@ -1279,14 +1275,14 @@ RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_t // TODO: iterate only over the called cells? for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) { - const std::map &vv = vars.variants (c->cell_index ()); - for (std::map::const_iterator v = vv.begin (); v != vv.end (); ++v) { + const std::set &vv = vars.variants (c->cell_index ()); + for (auto v = vv.begin (); v != vv.end (); ++v) { db::Shapes *out; if (vv.size () == 1) { out = & c->shapes (res->deep_layer ().layer ()); } else { - out = & to_commit [c->cell_index ()][v->first]; + out = & to_commit [c->cell_index ()][*v]; } const db::connected_clusters &cc = hc.clusters_per_cell (c->cell_index ()); @@ -1295,12 +1291,12 @@ RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_t if (cc.is_root (*cl)) { PolygonRefToShapesGenerator prgen (&layout, out); - polygon_transformation_filter ptrans (&prgen, v->first.inverted ()); + polygon_transformation_filter ptrans (&prgen, v->inverted ()); JoinEdgesCluster jec (&ptrans, ext_b, ext_e, ext_o, ext_i); std::list heap; for (db::recursive_cluster_shape_iterator rcsi (hc, edges.layer (), c->cell_index (), *cl); ! rcsi.at_end (); ++rcsi) { - heap.push_back (rcsi->transformed (v->first * rcsi.trans ())); + heap.push_back (rcsi->transformed (*v * rcsi.trans ())); jec.add (&heap.back (), 0); } @@ -1318,20 +1314,20 @@ RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_t for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) { - const std::map &vv = vars.variants (c->cell_index ()); - for (std::map::const_iterator v = vv.begin (); v != vv.end (); ++v) { + const std::set &vv = vars.variants (c->cell_index ()); + for (auto v = vv.begin (); v != vv.end (); ++v) { db::Shapes *out; if (vv.size () == 1) { out = & c->shapes (res->deep_layer ().layer ()); } else { - out = & to_commit [c->cell_index ()][v->first]; + out = & to_commit [c->cell_index ()][*v]; } PolygonRefToShapesGenerator prgen (&layout, out); for (db::Shapes::shape_iterator si = c->shapes (edges.layer ()).begin (db::ShapeIterator::Edges); ! si.at_end (); ++si) { prgen.set_prop_id (si->prop_id ()); - prgen.put (extended_edge (si->edge ().transformed (v->first), ext_b, ext_e, ext_o, ext_i).transformed (v->first.inverted ())); + prgen.put (extended_edge (si->edge ().transformed (*v), ext_b, ext_e, ext_o, ext_i).transformed (v->inverted ())); } } diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index e21620e0c..ff96a0b42 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -264,10 +264,8 @@ static void transform_deep_layer (db::DeepLayer &deep_layer, const Trans &t) for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) { - const std::map &v = vars.variants (c->cell_index ()); - tl_assert (v.size () == size_t (1)); - - db::Trans tr (v.begin ()->first.inverted () * t.disp ()); + const db::ICplxTrans &tv = vars.single_variant_transformation (c->cell_index ()); + db::ICplxTrans tr (tv.inverted () * t.disp ()); db::Shapes &shapes = c->shapes (deep_layer.layer ()); db::Shapes new_shapes (layout.manager (), c.operator-> (), layout.is_editable ()); @@ -1122,10 +1120,10 @@ DeepRegion::area (const db::Box &box) const for (db::ShapeIterator s = layout.cell (*c).shapes (polygons.layer ()).begin (db::ShapeIterator::All); ! s.at_end (); ++s) { ac += s->area (); } - const std::map &vv = vars.variants (*c); - for (std::map::const_iterator v = vv.begin (); v != vv.end (); ++v) { - double mag = v->first.mag (); - a += v->second * ac * mag * mag; + const std::set &vv = vars.variants (*c); + for (auto v = vv.begin (); v != vv.end (); ++v) { + double mag = v->mag (); + // @@@ a += v->second * ac * mag * mag; } } @@ -1159,10 +1157,10 @@ DeepRegion::perimeter (const db::Box &box) const for (db::ShapeIterator s = layout.cell (*c).shapes (polygons.layer ()).begin (db::ShapeIterator::All); ! s.at_end (); ++s) { pc += s->perimeter (); } - const std::map &vv = vars.variants (*c); - for (std::map::const_iterator v = vv.begin (); v != vv.end (); ++v) { - double mag = v->first.mag (); - p += v->second * pc * mag; + const std::set &vv = vars.variants (*c); + for (auto v = vv.begin (); v != vv.end (); ++v) { + double mag = v->mag (); + // @@@ p += v->second * pc * mag; } } @@ -1219,14 +1217,14 @@ DeepRegion::grid_check (db::Coord gx, db::Coord gy) const const db::Shapes &shapes = c->shapes (polygons.layer ()); - const std::map &vv = vars.variants (c->cell_index ()); - for (std::map::const_iterator v = vv.begin (); v != vv.end (); ++v) { + const std::set &vv = vars.variants (c->cell_index ()); + for (auto v = vv.begin (); v != vv.end (); ++v) { db::Shapes *markers; if (vv.size () == 1) { markers = & c->shapes (res->deep_layer ().layer ()); } else { - markers = & to_commit [c->cell_index ()] [v->first]; + markers = & to_commit [c->cell_index ()] [*v]; } for (db::Shapes::shape_iterator si = shapes.begin (db::ShapeIterator::All); ! si.at_end (); ++si) { @@ -1234,7 +1232,7 @@ DeepRegion::grid_check (db::Coord gx, db::Coord gy) const db::Polygon poly; si->polygon (poly); - AsIfFlatRegion::produce_markers_for_grid_check (poly, v->first, gx, gy, *markers); + AsIfFlatRegion::produce_markers_for_grid_check (poly, *v, gx, gy, *markers); } @@ -1311,9 +1309,7 @@ DeepRegion::snapped (db::Coord gx, db::Coord gy) std::unique_ptr res (new db::DeepRegion (polygons.derived ())); for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) { - const std::map &v = vars.variants (c->cell_index ()); - tl_assert (v.size () == size_t (1)); - const db::ICplxTrans &tr = v.begin ()->first; + const db::ICplxTrans &tr = vars.single_variant_transformation (c->cell_index ()); db::ICplxTrans trinv = tr.inverted (); const db::Shapes &s = c->shapes (polygons.layer ()); @@ -1385,9 +1381,7 @@ DeepRegion::edges (const EdgeFilterBase *filter) const db::ICplxTrans tr; if (vars.get ()) { - const std::map &v = vars->variants (c->cell_index ()); - tl_assert (v.size () == size_t (1)); - tr = v.begin ()->first; + tr = vars->single_variant_transformation (c->cell_index ()); } const db::Shapes &s = c->shapes (polygons.layer ()); @@ -1506,22 +1500,20 @@ DeepRegion::apply_filter (const PolygonFilterBase &filter) const if (vars.get ()) { - const std::map &vv = vars->variants (c->cell_index ()); - for (std::map::const_iterator v = vv.begin (); v != vv.end (); ++v) { + const std::set &vv = vars->variants (c->cell_index ()); + for (auto v = vv.begin (); v != vv.end (); ++v) { db::Shapes *st; if (vv.size () == 1) { st = & c->shapes (res->deep_layer ().layer ()); } else { - st = & to_commit [c->cell_index ()] [v->first]; + st = & to_commit [c->cell_index ()] [*v]; } - const db::ICplxTrans &tr = v->first; - for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) { db::Polygon poly; si->polygon (poly); - if (filter.selected (poly.transformed (tr))) { + if (filter.selected (poly.transformed (*v))) { st->insert (*si); } } @@ -1663,9 +1655,8 @@ DeepRegion::sized (coord_type d, unsigned int mode) const std::unique_ptr res (new db::DeepRegion (polygons.derived ())); for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) { - const std::map &v = vars.variants (c->cell_index ()); - tl_assert (v.size () == size_t (1)); - double mag = v.begin ()->first.mag (); + const db::ICplxTrans &tr = vars.single_variant_transformation (c->cell_index ()); + double mag = tr.mag (); db::Coord d_with_mag = db::coord_traits::rounded (d / mag); const db::Shapes &s = c->shapes (polygons.layer ()); @@ -1719,10 +1710,9 @@ DeepRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const std::unique_ptr res (new db::DeepRegion (polygons.derived ())); for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) { - const std::map &v = vars.variants (c->cell_index ()); - tl_assert (v.size () == size_t (1)); - double mag = v.begin ()->first.mag (); - double angle = v.begin ()->first.angle (); + const db::ICplxTrans &tr = vars.single_variant_transformation (c->cell_index ()); + double mag = tr.mag (); + double angle = tr.angle (); db::Coord dx_with_mag = db::coord_traits::rounded (dx / mag); db::Coord dy_with_mag = db::coord_traits::rounded (dy / mag); @@ -2020,9 +2010,8 @@ DeepRegion::run_single_polygon_check (db::edge_relation_type rel, db::Coord d, c std::unique_ptr res (new db::DeepEdgePairs (polygons.derived ())); for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) { - const std::map &v = vars.variants (c->cell_index ()); - tl_assert (v.size () == size_t (1)); - double mag = v.begin ()->first.mag (); + const db::ICplxTrans &tr = vars.single_variant_transformation (c->cell_index ()); + double mag = tr.mag (); db::Coord d_with_mag = db::coord_traits::rounded (d / mag); EdgeRelationFilter check (rel, d_with_mag, options.metrics); diff --git a/src/db/db/dbDeepTexts.cc b/src/db/db/dbDeepTexts.cc index 0c1cc30e7..1fcac0e00 100644 --- a/src/db/db/dbDeepTexts.cc +++ b/src/db/db/dbDeepTexts.cc @@ -431,22 +431,20 @@ DeepTexts *DeepTexts::apply_filter (const TextFilterBase &filter) const if (vars.get ()) { - const std::map &vv = vars->variants (c->cell_index ()); - for (std::map::const_iterator v = vv.begin (); v != vv.end (); ++v) { + const std::set &vv = vars->variants (c->cell_index ()); + for (auto v = vv.begin (); v != vv.end (); ++v) { db::Shapes *st; if (vv.size () == 1) { st = & c->shapes (res->deep_layer ().layer ()); } else { - st = & to_commit [c->cell_index ()] [v->first]; + st = & to_commit [c->cell_index ()] [*v]; } - const db::ICplxTrans &tr = v->first; - for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Texts); ! si.at_end (); ++si) { db::Text text; si->text (text); - if (filter.selected (text.transformed (tr))) { + if (filter.selected (text.transformed (*v))) { st->insert (*si); } } diff --git a/src/db/db/dbHierProcessor.cc b/src/db/db/dbHierProcessor.cc index 636563fc0..bc3b890be 100644 --- a/src/db/db/dbHierProcessor.cc +++ b/src/db/db/dbHierProcessor.cc @@ -1491,10 +1491,8 @@ LocalProcessorBase::dist_for_cell (db::cell_index_type cell_index, db::Coord dis { if (mp_vars) { - const std::map &v = mp_vars->variants (cell_index); - tl_assert (v.size () == size_t (1)); - - double mag = v.begin ()->first.mag (); + const db::ICplxTrans &tr = mp_vars->single_variant_transformation (cell_index); + double mag = tr.mag (); return db::coord_traits::rounded (dist / mag); } else { diff --git a/src/db/db/dbLayoutUtils.cc b/src/db/db/dbLayoutUtils.cc index c3ec9efc2..266424ab1 100644 --- a/src/db/db/dbLayoutUtils.cc +++ b/src/db/db/dbLayoutUtils.cc @@ -543,9 +543,7 @@ scale_and_snap (db::Layout &layout, db::Cell &cell, db::Coord g, db::Coord m, db continue; } - const std::map &v = vars.variants (c->cell_index ()); - tl_assert (v.size () == size_t (1)); - db::ICplxTrans tr = v.begin ()->first; + db::ICplxTrans tr = vars.single_variant_transformation (c->cell_index ()); // NOTE: tr_disp is already multiplied with mag, so it can be an integer db::Vector tr_disp = tr.disp (); diff --git a/src/db/db/dbShapeCollectionUtils.h b/src/db/db/dbShapeCollectionUtils.h index 817fd8d3f..02092030f 100644 --- a/src/db/db/dbShapeCollectionUtils.h +++ b/src/db/db/dbShapeCollectionUtils.h @@ -198,20 +198,20 @@ shape_collection_processed_impl (const db::DeepLayer &input, const shape_collect if (vars.get ()) { - const std::map &vv = vars->variants (c->cell_index ()); - for (std::map::const_iterator v = vv.begin (); v != vv.end (); ++v) { + const std::set &vv = vars->variants (c->cell_index ()); + for (auto v = vv.begin (); v != vv.end (); ++v) { db::Shapes *st; if (vv.size () == 1) { st = & c->shapes (res->deep_layer ().layer ()); } else { - st = & to_commit [c->cell_index ()] [v->first]; + st = & to_commit [c->cell_index ()] [*v]; } shape_collection_processor_delivery delivery (&layout, st); shape_collection_processor_delivery > delivery_wp (&layout, st); - const db::ICplxTrans &tr = v->first; + const db::ICplxTrans &tr = *v; db::ICplxTrans trinv = tr.inverted (); for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) { diff --git a/src/db/unit_tests/dbCellVariantsTests.cc b/src/db/unit_tests/dbCellVariantsTests.cc index 22212954a..acddd9b80 100644 --- a/src/db/unit_tests/dbCellVariantsTests.cc +++ b/src/db/unit_tests/dbCellVariantsTests.cc @@ -27,17 +27,14 @@ #include "tlUnitTest.h" #include "tlStream.h" -std::string var2str (const std::map &vars) +std::string var2str (const std::set &vars) { std::string res; - for (std::map::const_iterator i = vars.begin (); i != vars.end (); ++i) { + for (auto i = vars.begin (); i != vars.end (); ++i) { if (! res.empty ()) { res += ";"; } - res += i->first.to_string (); - res += "["; - res += tl::to_string (i->second); - res += "]"; + res += i->to_string (); } return res; } @@ -94,8 +91,8 @@ TEST(1_Trivial) db::OrientationReducer red; db::cell_variants_collector vb (red); vb.collect (ly, a); - EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]"); - EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0[1]"); + EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0"); + EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0"); EXPECT_EQ (var2str (vb.variants (c.cell_index ())), ""); EXPECT_EQ (var2str (vb.variants (d.cell_index ())), ""); @@ -119,8 +116,8 @@ TEST(2_TwoVariants) db::OrientationReducer red; db::cell_variants_collector vb (red); vb.collect (ly, a); - EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]"); - EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "m0 *1 0,0[1];r0 *1 0,0[1]"); + EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0"); + EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "m0 *1 0,0;r0 *1 0,0"); EXPECT_EQ (var2str (vb.variants (c.cell_index ())), ""); EXPECT_EQ (var2str (vb.variants (d.cell_index ())), ""); @@ -148,9 +145,9 @@ TEST(3_TwoLevels) db::OrientationReducer red; db::cell_variants_collector vb (red); vb.collect (ly, a); - EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]"); - EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0[1];r90 *1 0,0[1]"); - EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0[1];r0 *1 0,0[1];m45 *1 0,0[1];r90 *1 0,0[1]"); + EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0"); + EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0;r90 *1 0,0"); + EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0;r0 *1 0,0;m45 *1 0,0;r90 *1 0,0"); EXPECT_EQ (var2str (vb.variants (d.cell_index ())), ""); EXPECT_EQ (inst2str (ly, a), "B:r0 *1 1,10;B:r90 *1 1,100"); @@ -182,10 +179,10 @@ TEST(4_ThreeLevels) db::OrientationReducer red; db::cell_variants_collector vb (red); vb.collect (ly, a); - EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]"); - EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0[1];r90 *1 0,0[1]"); - EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0[1];r0 *1 0,0[1];m45 *1 0,0[1];r90 *1 0,0[1]"); - EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "r270 *1 0,0[1];m90 *1 0,0[1];r0 *1 0,0[1];m45 *1 0,0[1]"); + EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0"); + EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0;r90 *1 0,0"); + EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0;r0 *1 0,0;m45 *1 0,0;r90 *1 0,0"); + EXPECT_EQ (var2str (vb.variants (d.cell_index ())), "r270 *1 0,0;m90 *1 0,0;r0 *1 0,0;m45 *1 0,0"); EXPECT_EQ (inst2str (ly, a), "B:r0 *1 1,10;B:r90 *1 1,100"); EXPECT_EQ (inst2str (ly, b), "C:r0 *1 2,10;C:m0 *1 2,100"); @@ -220,9 +217,9 @@ TEST(5_ComplexTrans) db::OrientationReducer red; db::cell_variants_collector vb (red); vb.collect (ly, a); - EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]"); - EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0[1];r90 *1 0,0[1]"); - EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0[1];r0 *1 0,0[1];m45 *1 0,0[1];r90 *1 0,0[1]"); + EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0"); + EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0;r90 *1 0,0"); + EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0;r0 *1 0,0;m45 *1 0,0;r90 *1 0,0"); EXPECT_EQ (var2str (vb.variants (d.cell_index ())), ""); } @@ -243,9 +240,9 @@ TEST(6_Arrays) db::OrientationReducer red; db::cell_variants_collector vb (red); vb.collect (ly, a); - EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]"); - EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0[100];r90 *1 0,0[1]"); - EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0[100];r0 *1 0,0[10000];m45 *1 0,0[1];r90 *1 0,0[100]"); + EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0"); + EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0;r90 *1 0,0"); + EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "m0 *1 0,0;r0 *1 0,0;m45 *1 0,0;r90 *1 0,0"); EXPECT_EQ (var2str (vb.variants (d.cell_index ())), ""); } @@ -265,9 +262,9 @@ TEST(7_ScalingVariants) db::MagnificationReducer red; db::cell_variants_collector vb (red); vb.collect (ly, a); - EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]"); - EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0[1];r0 *1.5 0,0[100]"); - EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "r0 *1 0,0[1];r0 *1.5 0,0[100];r0 *2 0,0[100];r0 *3 0,0[10000]"); + EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0"); + EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 0,0;r0 *1.5 0,0"); + EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "r0 *1 0,0;r0 *1.5 0,0;r0 *2 0,0;r0 *3 0,0"); EXPECT_EQ (var2str (vb.variants (d.cell_index ())), ""); } @@ -285,8 +282,8 @@ TEST(8_GridVariants) db::GridReducer red (10); db::cell_variants_collector vb (red); vb.collect (ly, a); - EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]"); - EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 1,0[1];r0 *1 3,0[1];r0 *1 1,1[1];r0 *1 3,1[1]"); + EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0"); + EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *1 1,0;r0 *1 3,0;r0 *1 1,1;r0 *1 3,1"); // placements are: // b in a: r0 *1 x=1,1+102 y=10,10+101 @@ -297,7 +294,7 @@ TEST(8_GridVariants) // expanded placements mod 10: // c in a: r0 *2 x=1,1+102 y=10,10+101 x r0 *1 x=2,y=3 // = (3,3),(5,3),(3,4),(5,4) - EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "r0 *1 -5,3[1];r0 *1 3,3[1];r0 *1 -5,4[1];r0 *1 3,4[1]"); + EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "r0 *1 -5,3;r0 *1 3,3;r0 *1 -5,4;r0 *1 3,4"); EXPECT_EQ (var2str (vb.variants (d.cell_index ())), ""); EXPECT_EQ (inst2str (ly, a), "B:r0 *1 1,10;B:r0 *1 1,111;B:r0 *1 103,10;B:r0 *1 103,111"); @@ -332,8 +329,8 @@ TEST(9_ComplexGridVariants) db::GridReducer red (10); db::cell_variants_collector vb (red); vb.collect (ly, a); - EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0[1]"); - EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *2 1,0[1];r90 *1 1,0[1];r0 *2 3,0[1];r0 *2 1,1[1];r0 *2 3,1[1]"); + EXPECT_EQ (var2str (vb.variants (a.cell_index ())), "r0 *1 0,0"); + EXPECT_EQ (var2str (vb.variants (b.cell_index ())), "r0 *2 1,0;r90 *1 1,0;r0 *2 3,0;r0 *2 1,1;r0 *2 3,1"); // placements are: // b in a: r0 *2 x=1,1+102 y=10,10+101 @@ -364,9 +361,9 @@ TEST(9_ComplexGridVariants) // (1,2),(1,-3),(-2,2),(-2,-3) // r90 *1 x=1,y=100 x m0 *1 x=2,y=100 // (1,2) - EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "r0 *4 -5,-4[2];r0 *4 -3,-4[2];r0 *4 -5,-3[2];r0 *4 -3,-3[2];r90 *2 -2,-3[1];" - "r90 *2 1,-3[1];m0 *2 -5,0[1];r0 *4 -5,0[2];m0 *2 -3,0[1];r0 *4 -3,0[2];" - "m0 *2 -5,1[1];r0 *4 -5,1[2];m0 *2 -3,1[1];r0 *4 -3,1[2];r90 *2 -2,2[1];m45 *1 1,2[1];r90 *2 1,2[1]"); + EXPECT_EQ (var2str (vb.variants (c.cell_index ())), "r0 *4 -5,-4;r0 *4 -3,-4;r0 *4 -5,-3;r0 *4 -3,-3;r90 *2 -2,-3;" + "r90 *2 1,-3;m0 *2 -5,0;r0 *4 -5,0;m0 *2 -3,0;r0 *4 -3,0;" + "m0 *2 -5,1;r0 *4 -5,1;m0 *2 -3,1;r0 *4 -3,1;r90 *2 -2,2;m45 *1 1,2;r90 *2 1,2"); EXPECT_EQ (var2str (vb.variants (d.cell_index ())), ""); } @@ -417,14 +414,14 @@ TEST(101_Propagation) for (db::Layout::const_iterator c = ly.begin (); c != ly.end (); ++c) { - const std::map &vv = vb.variants (c->cell_index ()); - for (std::map::const_iterator v = vv.begin (); v != vv.end (); ++v) { + const std::set &vv = vb.variants (c->cell_index ()); + for (auto v = vv.begin (); v != vv.end (); ++v) { - db::Shapes &out = to_commit [c->cell_index ()][v->first]; + db::Shapes &out = to_commit [c->cell_index ()][*v]; for (db::Shapes::shape_iterator s = c->shapes (l1).begin (db::ShapeIterator::All); ! s.at_end (); ++s) { - db::Box b = s->bbox ().transformed (v->first); + db::Box b = s->bbox ().transformed (*v); b.enlarge (db::Vector (-100, 0)); - out.insert (b.transformed (v->first.inverted ())); + out.insert (b.transformed (v->inverted ())); } }