Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 2 additions & 11 deletions src/db/db/dbBoxConvert.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,7 @@ DB_PUBLIC db::Box cellinst_box_convert_impl (const db::CellInst &inst, const db:
} else if (allow_empty) {
return inst.bbox (*layout);
} else {
db::Box box = inst.bbox (*layout);
if (box.empty ()) {
return db::Box (db::Point (0, 0), db::Point (0, 0));
} else {
return box;
}
return inst.bbox_with_empty (*layout);
}
}

Expand All @@ -52,11 +47,7 @@ DB_PUBLIC db::Box cell_box_convert_impl (const db::Cell &c, int layer, bool allo
} else if (allow_empty) {
return c.bbox ();
} else {
if (c.bbox ().empty ()) {
return db::Box (db::Point (0, 0), db::Point (0, 0));
} else {
return c.bbox ();
}
return c.bbox_with_empty ();
}
}

Expand Down
37 changes: 31 additions & 6 deletions src/db/db/dbCell.cc
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ Cell::Cell (cell_index_type ci, db::Layout &l)
m_bbox_needs_update (false), m_locked (false), m_ghost_cell (false),
mp_last (0), mp_next (0)
{
// .. nothing yet
m_bbox_with_empty = box_type (box_type::point_type (), box_type::point_type ());
}

Cell::Cell (const Cell &d)
Expand Down Expand Up @@ -128,6 +128,7 @@ Cell::operator= (const Cell &d)
m_locked = d.m_locked;
m_instances = d.m_instances;
m_bbox = d.m_bbox;
m_bbox_with_empty = d.m_bbox_with_empty;
m_bboxes = d.m_bboxes;
m_hier_levels = d.m_hier_levels;
m_prop_id = d.m_prop_id;
Expand Down Expand Up @@ -282,6 +283,10 @@ Cell::update_bbox (unsigned int layers)
box_type org_bbox = m_bbox;
m_bbox = box_type ();

// determine the bounding box with empty cells
box_type org_bbox_with_empty = m_bbox_with_empty;
m_bbox_with_empty = box_type ();

// save the original boxes for simple compare
box_map org_bboxes;
org_bboxes.swap (m_bboxes);
Expand Down Expand Up @@ -313,16 +318,21 @@ Cell::update_bbox (unsigned int layers)
m_bbox += lbox;
box_map::iterator b = m_bboxes.find (l);
if (b == m_bboxes.end ()) {
m_bboxes.insert (std::make_pair (l, lbox));
m_bboxes.insert (std::make_pair (l, lbox));
} else {
b->second += lbox;
b->second += lbox;
}
}

}

db::box_convert <cell_inst_type, false> bc_we (*mp_layout);
m_bbox_with_empty += o1_inst->bbox_from_raw_bbox (raw_box, bc_we);

}

box_type sbox_all;

// update the bboxes of the shapes lists
for (shapes_map::iterator s = m_shapes_map.begin (); s != m_shapes_map.end (); ++s) {

Expand All @@ -331,7 +341,7 @@ Cell::update_bbox (unsigned int layers)
box_type sbox (s->second.bbox ());

if (! sbox.empty ()) {
m_bbox += sbox;
sbox_all += sbox;
box_map::iterator b = m_bboxes.find (s->first);
if (b == m_bboxes.end ()) {
m_bboxes.insert (std::make_pair (s->first, sbox));
Expand All @@ -342,12 +352,20 @@ Cell::update_bbox (unsigned int layers)

}

// combine shapes in all-layer boxes
m_bbox += sbox_all;
m_bbox_with_empty += sbox_all;

// no empty box
if (m_bbox_with_empty.empty ()) {
m_bbox_with_empty = box_type (box_type::point_type (), box_type::point_type ());
}

// reset "dirty child instances" flag
m_bbox_needs_update = false;

// return true, if anything has changed with the box
return (org_bbox != m_bbox || org_bboxes != m_bboxes);

return (org_bbox != m_bbox || org_bbox_with_empty != m_bbox_with_empty || org_bboxes != m_bboxes);
}

void
Expand Down Expand Up @@ -442,6 +460,13 @@ Cell::prop_id (db::properties_id_type id)
}
}

const Cell::box_type &
Cell::bbox_with_empty () const
{
mp_layout->update ();
return m_bbox_with_empty;
}

const Cell::box_type &
Cell::bbox () const
{
Expand Down
13 changes: 12 additions & 1 deletion src/db/db/dbCell.h
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,17 @@ class DB_PUBLIC Cell
*/
const box_type &bbox () const;

/**
* @brief Retrieve the bounding box of the cell, including empty cells
*
* This method behaves like "bbox", but includes empty cells as single-point
* boxes (0,0;0,0). This bounding box is used for drawing and allows
* including empty cells.
*
* @return The bounding box that was computed by update_bbox
*/
const box_type &bbox_with_empty () const;

/**
* @brief Retrieve the per-layer bounding box of the cell
*
Expand Down Expand Up @@ -1098,7 +1109,7 @@ class DB_PUBLIC Cell
mutable db::Layout *mp_layout;
shapes_map m_shapes_map;
instances_type m_instances;
box_type m_bbox;
box_type m_bbox, m_bbox_with_empty;
box_map m_bboxes;
db::properties_id_type m_prop_id;

Expand Down
6 changes: 6 additions & 0 deletions src/db/db/dbCellInst.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ CellInst::bbox (const db::Layout &g) const
return g.cell (m_cell_index).bbox ();
}

CellInst::box_type
CellInst::bbox_with_empty (const db::Layout &g) const
{
return g.cell (m_cell_index).bbox_with_empty ();
}

CellInst::box_type
CellInst::bbox (const db::Layout &g, unsigned int l) const
{
Expand Down
9 changes: 9 additions & 0 deletions src/db/db/dbCellInst.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,15 @@ class DB_PUBLIC CellInst
*/
box_type bbox (const Layout &g) const;

/**
* @brief Compute the bounding box, including empty cells
*
* This method computes the bbox of the cell instance.
* As a requirement, the cell's bounding box must have been
* computed before.
*/
box_type bbox_with_empty (const Layout &g) const;

/**
* @brief Compute the bounding box
*
Expand Down
3 changes: 2 additions & 1 deletion src/db/db/dbInstElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ struct DB_PUBLIC InstElement
*
* @param bc The bounding box converter for the cell instance (db::box_convert<db::CellInst>)
*/
db::Box bbox (const db::box_convert<db::CellInst> &bc) const
template <class BoxConvert>
db::Box bbox (const BoxConvert &bc) const
{
if (whole_array ()) {
// this is the whole array
Expand Down
13 changes: 13 additions & 0 deletions src/db/db/dbInstances.cc
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,19 @@ Instance::bbox () const
}
}

Instance::box_type
Instance::bbox_with_empty () const
{
const db::Instances *i = instances ();
const db::Cell *c = i ? i->cell () : 0;
const db::Layout *g = c ? c->layout () : 0;
if (g) {
return bbox (db::box_convert<cell_inst_type, false> (*g));
} else {
return db::Instance::box_type ();
}
}

// -------------------------------------------------------------------------------------
// Instances implementation

Expand Down
9 changes: 9 additions & 0 deletions src/db/db/dbInstances.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,15 @@ class DB_PUBLIC Instance
*/
cell_inst_array_type::box_type bbox () const;

/**
* @brief Returns the bounding box of this array, including empty instances
*
* This method uses the pointers provided internally to identify container and cell.
* In constrast to normal "bbox", this bounding box considers empty cells as
* point-like with a box of (0,0;0,0).
*/
cell_inst_array_type::box_type bbox_with_empty () const;

/**
* @brief Return the iterator for the instances of the array
*
Expand Down
11 changes: 11 additions & 0 deletions src/db/unit_tests/dbCellTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,18 @@ TEST(1)
db::Cell &c1 (g.cell (g.add_cell ()));
db::Cell &c2 (g.cell (g.add_cell ()));

EXPECT_EQ (c1.bbox (), db::Box ());
EXPECT_EQ (c1.bbox_with_empty (), db::Box (db::Point(), db::Point ()));

db::Box b (0, 100, 1000, 1200);
c1.shapes (0).insert (b);
EXPECT_EQ (c1.bbox (), b);
EXPECT_EQ (c1.bbox_with_empty (), b);

db::Box bb (0, -100, 2000, 2200);
c1.shapes (1).insert (bb);
EXPECT_EQ (c1.bbox (), b + bb);
EXPECT_EQ (c1.bbox_with_empty (), b + bb);
EXPECT_EQ (c1.bbox (0), b);
EXPECT_EQ (c1.bbox (1), bb);

Expand All @@ -52,6 +57,7 @@ TEST(1)
EXPECT_EQ (c2.bbox (0), t * b);
EXPECT_EQ (c2.bbox (1), t * bb);
EXPECT_EQ (c1.bbox (), (b + bb));
EXPECT_EQ (c1.bbox_with_empty (), (b + bb));

// some basic testing of the instance trees
int n;
Expand Down Expand Up @@ -715,6 +721,11 @@ TEST(3a)
db::Trans t (db::Vector (100, -100));
db::Instance inst = c0.insert (db::CellInstArray (db::CellInst (c1.cell_index ()), t));
EXPECT_EQ (inst.to_string (), "cell_index=1 r0 100,-100");
EXPECT_EQ (inst.bbox ().to_string (), "()");
EXPECT_EQ (inst.bbox (db::box_convert<db::CellInst, false> (g)).to_string (), "(100,-100;100,-100)");
EXPECT_EQ (inst.bbox_with_empty ().to_string (), "(100,-100;100,-100)");
EXPECT_EQ (c0.bbox ().to_string (), "()");
EXPECT_EQ (c0.bbox_with_empty ().to_string (), "(100,-100;100,-100)");

inst = c0.transform (inst, db::Trans (5));
EXPECT_EQ (inst.to_string (), "cell_index=1 m45 -100,100");
Expand Down
60 changes: 32 additions & 28 deletions src/edt/edt/edtService.cc
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ Service::selection_bbox ()

db::CplxTrans ctx_trans = db::CplxTrans (layout.dbu ()) * cv.context_trans () * r->trans ();

db::box_convert<db::CellInst> bc (layout);
db::box_convert<db::CellInst, false> bc (layout);
if (! r->is_cell_inst ()) {

const std::vector<db::DCplxTrans> *tv_list = tv.per_cv_and_layer (r->cv_index (), r->layer ());
Expand Down Expand Up @@ -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<db::DCplxTrans, int> > variants = view ()->cv_transform_variants ();
std::set< std::pair<db::DCplxTrans, int> > variants = view ()->cv_transform_variants_with_empty();
for (std::set< std::pair<db::DCplxTrans, int> >::const_iterator v = variants.begin (); v != variants.end (); ++v) {
finder.find (view (), v->second, v->first, search_box);
}
Expand Down Expand Up @@ -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<db::DCplxTrans, int> > variants = view ()->cv_transform_variants ();
std::set< std::pair<db::DCplxTrans, int> > variants = view ()->cv_transform_variants_with_empty ();
for (std::set< std::pair<db::DCplxTrans, int> >::const_iterator v = variants.begin (); v != variants.end (); ++v) {
finder.find (view (), v->second, v->first, search_box);
}
Expand All @@ -1185,7 +1185,7 @@ Service::transient_select (const db::DPoint &pos)

db::Instance inst = r->back ().inst_ptr;

std::vector<db::DCplxTrans> tv = mp_view->cv_transform_variants (r->cv_index ());
std::vector<db::DCplxTrans> tv = mp_view->cv_transform_variants_with_empty (r->cv_index ());
if (view ()->is_editable ()) {

#if 0
Expand Down Expand Up @@ -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<db::DCplxTrans, int> > variants = view ()->cv_transform_variants ();
std::set< std::pair<db::DCplxTrans, int> > variants = view ()->cv_transform_variants_with_empty ();
for (std::set< std::pair<db::DCplxTrans, int> >::const_iterator v = variants.begin (); v != variants.end (); ++v) {
finder.find (view (), v->second, v->first, search_box);
}
Expand Down Expand Up @@ -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<db::DCplxTrans> empty_tv;
empty_tv.push_back (db::DCplxTrans ());

// Build markers

for (EditableSelectionIterator r = begin_selection (); ! r.at_end (); ++r) {
Expand All @@ -1769,39 +1773,39 @@ Service::do_selection_to_view ()
if (m_cell_inst_service) {

const std::vector<db::DCplxTrans> *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));
marker->set_vertex_shape (lay::ViewOp::Cross);
marker->set_vertex_size (9 /*cross vertex size*/);

} else {
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));

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*/);
} else {

if (r->seq () > 0 && m_indicate_secondary_selection) {
marker->set_dither_pattern (3);
}
db::box_convert<db::CellInst> 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));
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<db::CellInst> 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));

}

Expand Down
Loading
Loading