diff --git a/src/edt/edt/edtService.cc b/src/edt/edt/edtService.cc index 9492b4ed0..e17f5ee71 100644 --- a/src/edt/edt/edtService.cc +++ b/src/edt/edt/edtService.cc @@ -1115,7 +1115,7 @@ Service::click_proximity (const db::DPoint &pos, lay::Editable::SelectionMode mo lay::InstFinder finder (true, view ()->is_editable () && m_top_level_sel, view ()->is_editable () /*full arrays in editable mode*/, true /*enclose_inst*/, exclude, true /*visible layers*/); // go through all cell views - std::set< std::pair > variants = view ()->cv_transform_variants (); + std::set< std::pair > variants = view ()->cv_transform_variants_with_empty(); for (std::set< std::pair >::const_iterator v = variants.begin (); v != variants.end (); ++v) { finder.find (view (), v->second, v->first, search_box); } @@ -1164,7 +1164,7 @@ Service::transient_select (const db::DPoint &pos) lay::InstFinder finder (true, view ()->is_editable () && m_top_level_sel, view ()->is_editable () /*full arrays in editable mode*/, true /*enclose instances*/, &m_previous_selection, true /*visible layers only*/); // go through all transform variants - std::set< std::pair > variants = view ()->cv_transform_variants (); + std::set< std::pair > variants = view ()->cv_transform_variants_with_empty (); for (std::set< std::pair >::const_iterator v = variants.begin (); v != variants.end (); ++v) { finder.find (view (), v->second, v->first, search_box); } @@ -1185,7 +1185,7 @@ Service::transient_select (const db::DPoint &pos) db::Instance inst = r->back ().inst_ptr; - std::vector tv = mp_view->cv_transform_variants (r->cv_index ()); + std::vector tv = mp_view->cv_transform_variants_with_empty (r->cv_index ()); if (view ()->is_editable ()) { #if 0 @@ -1498,7 +1498,7 @@ Service::select (const db::DBox &box, lay::Editable::SelectionMode mode) lay::InstFinder finder (box.is_point (), view ()->is_editable () && m_top_level_sel, view ()->is_editable () /*full arrays in editable mode*/, true /*enclose_inst*/, exclude, true /*only visible layers*/); // go through all cell views - std::set< std::pair > variants = view ()->cv_transform_variants (); + std::set< std::pair > variants = view ()->cv_transform_variants_with_empty (); for (std::set< std::pair >::const_iterator v = variants.begin (); v != variants.end (); ++v) { finder.find (view (), v->second, v->first, search_box); } @@ -1754,6 +1754,10 @@ Service::do_selection_to_view () // build the transformation variants cache TransformationVariants tv (view ()); + // prepare a default transformation for empty variants + std::vector empty_tv; + empty_tv.push_back (db::DCplxTrans ()); + // Build markers for (EditableSelectionIterator r = begin_selection (); ! r.at_end (); ++r) { @@ -1769,39 +1773,39 @@ Service::do_selection_to_view () if (m_cell_inst_service) { const std::vector *tv_list = tv.per_cv (r->cv_index ()); - if (tv_list != 0) { + if (tv_list == 0) { + tv_list = &empty_tv; + } - if (view ()->is_editable ()) { + if (view ()->is_editable ()) { #if 0 - // to show the content of the cell when the instance is selected: - lay::InstanceMarker *marker = new lay::InstanceMarker (view (), r->cv_index (), ! show_shapes_of_instances (), show_shapes_of_instances () ? max_shapes_of_instances () : 0); + // to show the content of the cell when the instance is selected: + lay::InstanceMarker *marker = new lay::InstanceMarker (view (), r->cv_index (), ! show_shapes_of_instances (), show_shapes_of_instances () ? max_shapes_of_instances () : 0); #else - lay::InstanceMarker *marker = new lay::InstanceMarker (view (), r->cv_index ()); + lay::InstanceMarker *marker = new lay::InstanceMarker (view (), r->cv_index ()); #endif - marker->set_vertex_shape (lay::ViewOp::Cross); - marker->set_vertex_size (9 /*cross vertex size*/); - - if (r->seq () > 0 && m_indicate_secondary_selection) { - marker->set_dither_pattern (3); - } - marker->set (r->back ().inst_ptr, gt, *tv_list); - m_markers.push_back (std::make_pair (r.operator-> (), marker)); - - } else { - - lay::Marker *marker = new lay::Marker (view (), r->cv_index ()); - marker->set_vertex_shape (lay::ViewOp::Cross); - marker->set_vertex_size (9 /*cross vertex size*/); - - if (r->seq () > 0 && m_indicate_secondary_selection) { - marker->set_dither_pattern (3); - } - db::box_convert bc (cv->layout ()); - marker->set (bc (r->back ().inst_ptr.cell_inst ().object ()), gt * r->back ().inst_ptr.cell_inst ().complex_trans (*r->back ().array_inst), *tv_list); - m_markers.push_back (std::make_pair (r.operator-> (), marker)); + marker->set_vertex_shape (lay::ViewOp::Cross); + marker->set_vertex_size (9 /*cross vertex size*/); + if (r->seq () > 0 && m_indicate_secondary_selection) { + marker->set_dither_pattern (3); } + marker->set (r->back ().inst_ptr, gt, *tv_list); + m_markers.push_back (std::make_pair (r.operator-> (), marker)); + + } else { + + lay::Marker *marker = new lay::Marker (view (), r->cv_index ()); + marker->set_vertex_shape (lay::ViewOp::Cross); + marker->set_vertex_size (9 /*cross vertex size*/); + + if (r->seq () > 0 && m_indicate_secondary_selection) { + marker->set_dither_pattern (3); + } + db::box_convert bc (cv->layout ()); + marker->set (bc (r->back ().inst_ptr.cell_inst ().object ()), gt * r->back ().inst_ptr.cell_inst ().complex_trans (*r->back ().array_inst), *tv_list); + m_markers.push_back (std::make_pair (r.operator-> (), marker)); } diff --git a/src/laybasic/laybasic/layFinder.cc b/src/laybasic/laybasic/layFinder.cc index 69d54f08d..72884fa33 100644 --- a/src/laybasic/laybasic/layFinder.cc +++ b/src/laybasic/laybasic/layFinder.cc @@ -735,7 +735,7 @@ InstFinder::find (lay::LayoutViewBase *view, const db::DBox ®ion_mu) progress.set_format (""); mp_progress = &progress; - std::set< std::pair > variants = view->cv_transform_variants (); + std::set< std::pair > variants = view->cv_transform_variants_with_empty (); for (std::set< std::pair >::const_iterator v = variants.begin (); v != variants.end (); ++v) { find (view, v->second, v->first, region_mu); } diff --git a/src/laybasic/laybasic/layLayoutViewBase.cc b/src/laybasic/laybasic/layLayoutViewBase.cc index 285e1b5c5..6077a392f 100644 --- a/src/laybasic/laybasic/layLayoutViewBase.cc +++ b/src/laybasic/laybasic/layLayoutViewBase.cc @@ -3864,8 +3864,13 @@ LayoutViewBase::full_box () const db::DBox bbox; - for (LayerPropertiesConstIterator l = get_properties ().begin_const_recursive (); ! l.at_end (); ++l) { - bbox += l->overall_bbox (); + auto tv = cv_transform_variants_with_empty (); + for (auto i = tv.begin (); i != tv.end (); ++i) { + const lay::CellView &cv = cellview (i->second); + if (cv.is_valid ()) { + double dbu = cv->layout ().dbu (); + bbox += (i->first * db::CplxTrans (dbu) * cv.context_trans ()) * cv.cell ()->bbox_with_empty (); + } } for (lay::AnnotationShapes::iterator a = annotation_shapes ().begin (); ! a.at_end (); ++a) { @@ -5986,6 +5991,16 @@ LayoutViewBase::cv_transform_variants (int cv_index) const return std::vector (trns_variants.begin (), trns_variants.end ()); } +std::vector +LayoutViewBase::cv_transform_variants_with_empty (int cv_index) const +{ + std::vector trns_variants = cv_transform_variants (cv_index); + if (trns_variants.empty ()) { + trns_variants.push_back (db::DCplxTrans ()); + } + return trns_variants; +} + std::vector LayoutViewBase::cv_transform_variants (int cv_index, unsigned int layer) const { @@ -6046,7 +6061,30 @@ LayoutViewBase::cv_transform_variants () const return box_variants; } -db::InstElement +std::set< std::pair > +LayoutViewBase::cv_transform_variants_with_empty () const +{ + std::set< std::pair > box_variants = cv_transform_variants (); + + // add a default box variant for the CVs not present in the layer list to + // draw boxes at least. + + std::vector cv_present; + cv_present.resize (m_cellviews.size ()); + for (auto bv = box_variants.begin (); bv != box_variants.end (); ++bv) { + if (bv->second >= 0 && bv->second < int (cv_present.size ())) { + cv_present[bv->second] = true; + } + } + + for (auto i = cv_present.begin (); i != cv_present.end (); ++i) { + box_variants.insert (std::make_pair (db::DCplxTrans (), int (i - cv_present.begin ()))); + } + + return box_variants; +} + +db::InstElement LayoutViewBase::ascend (int index) { tl_assert (int (m_cellviews.size ()) > index && cellview_iter (index)->is_valid ()); diff --git a/src/laybasic/laybasic/layLayoutViewBase.h b/src/laybasic/laybasic/layLayoutViewBase.h index ddc8a047b..245afbf7c 100644 --- a/src/laybasic/laybasic/layLayoutViewBase.h +++ b/src/laybasic/laybasic/layLayoutViewBase.h @@ -1674,11 +1674,27 @@ public: */ std::set< std::pair > cv_transform_variants () const; + /** + * @brief Get a list of cellview index and transform variants including empty cellviews + * + * This version delivers a unit-transformation variant for cell views for which + * no layer is present. This version is used for instance box drawing. + */ + std::set< std::pair > cv_transform_variants_with_empty () const; + /** * @brief Get the global transform variants for a given cellview index */ std::vector cv_transform_variants (int cv_index) const; + /** + * @brief Get the global transform variants for a given cellview index including empty cellviews + * + * This version delivers a unit-transformation variant for cell views for which + * no layer is present. This version is used for instance box drawing. + */ + std::vector cv_transform_variants_with_empty (int cv_index) const; + /** * @brief Get the global transform variants for a given cellview index and layer */ diff --git a/src/laybasic/laybasic/layRedrawThreadWorker.cc b/src/laybasic/laybasic/layRedrawThreadWorker.cc index 68bf6e700..0edd3abb0 100644 --- a/src/laybasic/laybasic/layRedrawThreadWorker.cc +++ b/src/laybasic/laybasic/layRedrawThreadWorker.cc @@ -575,7 +575,7 @@ RedrawThreadWorker::setup (LayoutViewBase *view, RedrawThreadCanvas *canvas, con m_nlayers = mp_redraw_thread->num_layers (); - m_box_variants = view->cv_transform_variants (); + m_box_variants = view->cv_transform_variants_with_empty (); } void