clip method variants with dboxes and cell references in Layout

This commit is contained in:
Matthias Koefferlein 2022-02-08 23:49:28 +01:00
parent 3a422f2c38
commit 98dd0de139
2 changed files with 253 additions and 4 deletions

View File

@ -353,6 +353,33 @@ static db::cell_index_type clip (db::Layout *l, db::cell_index_type c, const db:
return cc [0];
}
static db::cell_index_type clip_dbox (db::Layout *l, db::cell_index_type c, const db::DBox &box)
{
std::vector <db::Box> boxes;
boxes.push_back (db::CplxTrans (l->dbu ()).inverted () * box);
std::vector <db::cell_index_type> cc = db::clip_layout(*l, *l, c, boxes, true);
tl_assert (! cc.empty ());
return cc [0];
}
static db::Cell *clip_cell_dbox (db::Layout *l, const db::Cell &c, const db::DBox &box)
{
std::vector <db::Box> boxes;
boxes.push_back (db::CplxTrans (l->dbu ()).inverted () * box);
std::vector <db::cell_index_type> cc = db::clip_layout(*l, *l, c.cell_index (), boxes, true);
tl_assert (! cc.empty ());
return &l->cell (cc [0]);
}
static db::Cell *clip_cell (db::Layout *l, const db::Cell &c, const db::Box &box)
{
std::vector <db::Box> boxes;
boxes.push_back (box);
std::vector <db::cell_index_type> cc = db::clip_layout(*l, *l, c.cell_index (), boxes, true);
tl_assert (! cc.empty ());
return &l->cell (cc [0]);
}
static db::cell_index_type clip_into (const db::Layout *l, db::cell_index_type c, db::Layout *t, const db::Box &box)
{
std::vector <db::Box> boxes;
@ -362,14 +389,92 @@ static db::cell_index_type clip_into (const db::Layout *l, db::cell_index_type c
return cc [0];
}
static db::cell_index_type clip_into_dbox (const db::Layout *l, db::cell_index_type c, db::Layout *t, const db::DBox &box)
{
std::vector <db::Box> boxes;
boxes.push_back (db::CplxTrans (l->dbu ()).inverted () * box);
std::vector <db::cell_index_type> cc = db::clip_layout(*l, *t, c, boxes, true);
tl_assert (! cc.empty ());
return cc [0];
}
static db::Cell *clip_into_cell (const db::Layout *l, const db::Cell &c, db::Layout *t, const db::Box &box)
{
std::vector <db::Box> boxes;
boxes.push_back (box);
std::vector <db::cell_index_type> cc = db::clip_layout(*l, *t, c.cell_index (), boxes, true);
tl_assert (! cc.empty ());
return &t->cell (cc [0]);
}
static db::Cell *clip_into_cell_dbox (const db::Layout *l, const db::Cell &c, db::Layout *t, const db::DBox &box)
{
std::vector <db::Box> boxes;
boxes.push_back (db::CplxTrans (l->dbu ()).inverted () * box);
std::vector <db::cell_index_type> cc = db::clip_layout(*l, *t, c.cell_index (), boxes, true);
tl_assert (! cc.empty ());
return &t->cell (cc [0]);
}
static std::vector<db::Box> transform_boxes (const db::Layout *l, const std::vector<db::DBox> &boxes)
{
std::vector<db::Box> result;
result.reserve (boxes.size ());
db::VCplxTrans t = db::CplxTrans (l->dbu ()).inverted ();
for (std::vector<db::DBox>::const_iterator i = boxes.begin (); i != boxes.end (); ++i) {
result.push_back (t * *i);
}
return result;
}
static std::vector<db::Cell *> to_cell_refs (db::Layout *l, const std::vector<db::cell_index_type> &cell_indexes)
{
std::vector<db::Cell *> result;
result.reserve (cell_indexes.size ());
for (std::vector<db::cell_index_type>::const_iterator i = cell_indexes.begin (); i != cell_indexes.end (); ++i) {
result.push_back (&l->cell (*i));
}
return result;
}
static std::vector<db::cell_index_type> multi_clip (db::Layout *l, db::cell_index_type c, const std::vector<db::Box> &boxes)
{
return db::clip_layout(*l, *l, c, boxes, true);
return db::clip_layout (*l, *l, c, boxes, true);
}
static std::vector<db::Cell *> multi_clip_cells (db::Layout *l, const db::Cell &c, const std::vector<db::Box> &boxes)
{
return to_cell_refs (l, db::clip_layout (*l, *l, c.cell_index (), boxes, true));
}
static std::vector<db::cell_index_type> multi_clip_dboxes (db::Layout *l, db::cell_index_type c, const std::vector<db::DBox> &boxes)
{
return db::clip_layout (*l, *l, c, transform_boxes (l, boxes), true);
}
static std::vector<db::Cell *> multi_clip_cells_dboxes (db::Layout *l, const db::Cell &c, const std::vector<db::DBox> &boxes)
{
return to_cell_refs (l, db::clip_layout (*l, *l, c.cell_index (), transform_boxes (l, boxes), true));
}
static std::vector<db::cell_index_type> multi_clip_into (db::Layout *l, db::cell_index_type c, db::Layout *t, const std::vector<db::Box> &boxes)
{
return db::clip_layout(*l, *t, c, boxes, true);
return db::clip_layout (*l, *t, c, boxes, true);
}
static std::vector<db::Cell *> multi_clip_into_cells (db::Layout *l, const db::Cell &c, db::Layout *t, const std::vector<db::Box> &boxes)
{
return to_cell_refs (l, db::clip_layout (*l, *t, c.cell_index (), boxes, true));
}
static std::vector<db::cell_index_type> multi_clip_into_dboxes (db::Layout *l, db::cell_index_type c, db::Layout *t, const std::vector<db::DBox> &boxes)
{
return db::clip_layout (*l, *t, c, transform_boxes (l, boxes), true);
}
static std::vector<db::Cell *> multi_clip_into_cells_dboxes (db::Layout *l, const db::Cell &c, db::Layout *t, const std::vector<db::DBox> &boxes)
{
return to_cell_refs (l, db::clip_layout (*l, *t, c.cell_index (), transform_boxes (l, boxes), true));
}
static unsigned int get_layer0 (db::Layout *l)
@ -1946,6 +2051,30 @@ Class<db::Layout> decl_Layout ("db", "Layout",
"\n"
"This method has been added in version 0.21.\n"
) +
gsi::method_ext ("clip", &clip_dbox, gsi::arg ("cell"), gsi::arg ("box"),
"@brief Clips the given cell by the given rectangle and produce a new cell with the clip\n"
"@param cell The cell index of the cell to clip\n"
"@param box The clip box in micrometer units\n"
"@return The index of the new cell\n"
"\n"
"This variant which takes a micrometer-unit box has been added in version 0.28."
) +
gsi::method_ext ("clip", &clip_cell, gsi::arg ("cell"), gsi::arg ("box"),
"@brief Clips the given cell by the given rectangle and produce a new cell with the clip\n"
"@param cell The cell reference of the cell to clip\n"
"@param box The clip box in database units\n"
"@return The reference to the new cell\n"
"\n"
"This variant which takes cell references instead of cell indexes has been added in version 0.28."
) +
gsi::method_ext ("clip", &clip_cell_dbox, gsi::arg ("cell"), gsi::arg ("box"),
"@brief Clips the given cell by the given rectangle and produce a new cell with the clip\n"
"@param cell The cell reference of the cell to clip\n"
"@param box The clip box in micrometer units\n"
"@return The reference to the new cell\n"
"\n"
"This variant which takes a micrometer-unit box and cell references has been added in version 0.28."
) +
gsi::method_ext ("clip_into", &clip_into, gsi::arg ("cell"), gsi::arg ("target"), gsi::arg ("box"),
"@brief Clips the given cell by the given rectangle and produce a new cell with the clip\n"
"@param cell The cell index of the cell to clip\n"
@ -1965,8 +2094,35 @@ Class<db::Layout> decl_Layout ("db", "Layout",
"\n"
"This method has been added in version 0.21.\n"
) +
gsi::method_ext ("clip_into", &clip_into_dbox, gsi::arg ("cell"), gsi::arg ("target"), gsi::arg ("box"),
"@brief Clips the given cell by the given rectangle and produce a new cell with the clip\n"
"@param cell The cell index of the cell to clip\n"
"@param box The clip box in micrometer units\n"
"@param target The target layout\n"
"@return The index of the new cell in the target layout\n"
"\n"
"This variant which takes a micrometer-unit box has been added in version 0.28."
) +
gsi::method_ext ("clip_into", &clip_into_cell, gsi::arg ("cell"), gsi::arg ("target"), gsi::arg ("box"),
"@brief Clips the given cell by the given rectangle and produce a new cell with the clip\n"
"@param cell The reference to the cell to clip\n"
"@param box The clip box in database units\n"
"@param target The target layout\n"
"@return The reference to the new cell in the target layout\n"
"\n"
"This variant which takes cell references instead of cell indexes has been added in version 0.28."
) +
gsi::method_ext ("clip_into", &clip_into_cell_dbox, gsi::arg ("cell"), gsi::arg ("target"), gsi::arg ("box"),
"@brief Clips the given cell by the given rectangle and produce a new cell with the clip\n"
"@param cell The reference to the cell to clip\n"
"@param box The clip box in micrometer units\n"
"@param target The target layout\n"
"@return The reference to the new cell in the target layout\n"
"\n"
"This variant which takes a micrometer-unit box and cell references has been added in version 0.28."
) +
gsi::method_ext ("multi_clip", &multi_clip, gsi::arg ("cell"), gsi::arg ("boxes"),
"@brief Clips the given cell by the given rectangles and produce new cells with the clips, one for each rectangle.\n"
"@brief Clips the given cell by the given rectangles and produces new cells with the clips, one for each rectangle.\n"
"@param cell The cell index of the cell to clip\n"
"@param boxes The clip boxes in database units\n"
"@return The indexes of the new cells\n"
@ -1979,8 +2135,32 @@ Class<db::Layout> decl_Layout ("db", "Layout",
"\n"
"This method has been added in version 0.21.\n"
) +
gsi::method_ext ("multi_clip", &multi_clip_dboxes, gsi::arg ("cell"), gsi::arg ("boxes"),
"@brief Clips the given cell by the given rectangles and produces new cells with the clips, one for each rectangle.\n"
"@param cell The cell index of the cell to clip\n"
"@param boxes The clip boxes in micrometer units\n"
"@return The indexes of the new cells\n"
"\n"
"This variant which takes micrometer-unit boxes has been added in version 0.28."
) +
gsi::method_ext ("multi_clip", &multi_clip_cells, gsi::arg ("cell"), gsi::arg ("boxes"),
"@brief Clips the given cell by the given rectangles and produces new cells with the clips, one for each rectangle.\n"
"@param cell The reference to the cell to clip\n"
"@param boxes The clip boxes in database units\n"
"@return The references to the new cells\n"
"\n"
"This variant which takes cell references has been added in version 0.28."
) +
gsi::method_ext ("multi_clip", &multi_clip_cells_dboxes, gsi::arg ("cell"), gsi::arg ("boxes"),
"@brief Clips the given cell by the given rectangles and produces new cells with the clips, one for each rectangle.\n"
"@param cell The reference to the cell to clip\n"
"@param boxes The clip boxes in micrometer units\n"
"@return The references to the new cells\n"
"\n"
"This variant which takes cell references and micrometer-unit boxes has been added in version 0.28."
) +
gsi::method_ext ("multi_clip_into", &multi_clip_into, gsi::arg ("cell"), gsi::arg ("target"), gsi::arg ("boxes"),
"@brief Clips the given cell by the given rectangles and produce new cells with the clips, one for each rectangle.\n"
"@brief Clips the given cell by the given rectangles and produces new cells with the clips, one for each rectangle.\n"
"@param cell The cell index of the cell to clip\n"
"@param boxes The clip boxes in database units\n"
"@param target The target layout\n"
@ -1999,6 +2179,33 @@ Class<db::Layout> decl_Layout ("db", "Layout",
"\n"
"This method has been added in version 0.21.\n"
) +
gsi::method_ext ("multi_clip_into", &multi_clip_into_dboxes, gsi::arg ("cell"), gsi::arg ("target"), gsi::arg ("boxes"),
"@brief Clips the given cell by the given rectangles and produces new cells with the clips, one for each rectangle.\n"
"@param cell The cell index of the cell to clip\n"
"@param boxes The clip boxes in database units\n"
"@param target The target layout\n"
"@return The indexes of the new cells\n"
"\n"
"This variant which takes micrometer-unit boxes has been added in version 0.28."
) +
gsi::method_ext ("multi_clip_into", &multi_clip_into_cells, gsi::arg ("cell"), gsi::arg ("target"), gsi::arg ("boxes"),
"@brief Clips the given cell by the given rectangles and produces new cells with the clips, one for each rectangle.\n"
"@param cell The reference the cell to clip\n"
"@param boxes The clip boxes in database units\n"
"@param target The target layout\n"
"@return The references to the new cells\n"
"\n"
"This variant which takes cell references boxes has been added in version 0.28."
) +
gsi::method_ext ("multi_clip_into", &multi_clip_into_cells_dboxes, gsi::arg ("cell"), gsi::arg ("target"), gsi::arg ("boxes"),
"@brief Clips the given cell by the given rectangles and produces new cells with the clips, one for each rectangle.\n"
"@param cell The reference the cell to clip\n"
"@param boxes The clip boxes in micrometer units\n"
"@param target The target layout\n"
"@return The references to the new cells\n"
"\n"
"This variant which takes cell references and micrometer-unit boxes has been added in version 0.28."
) +
gsi::method ("convert_cell_to_static", &db::Layout::convert_cell_to_static, gsi::arg ("cell_index"),
"@brief Converts a PCell or library cell to a usual (static) cell\n"
"@return The index of the new cell\n"

View File

@ -1043,10 +1043,31 @@ class DBLayout_TestClass < TestBase
ci = l.clip(c0.cell_index, RBA::Box.new(0, 0, 200, 200))
assert_equal(dump_layer_i(l, 0, ci), "(0,100;200,200); (0,100;200,200); (100,0;200,200)")
cic = l.clip(c0, RBA::Box.new(0, 0, 200, 200))
assert_equal(dump_layer_i(l, 0, cic.cell_index), "(0,100;200,200); (0,100;200,200); (100,0;200,200)")
cid = l.clip(c0.cell_index, RBA::DBox.new(0, 0, 0.2, 0.2))
assert_equal(dump_layer_i(l, 0, cid), "(0,100;200,200); (0,100;200,200); (100,0;200,200)")
cicd = l.clip(c0, RBA::DBox.new(0, 0, 0.2, 0.2))
assert_equal(dump_layer_i(l, 0, cicd.cell_index), "(0,100;200,200); (0,100;200,200); (100,0;200,200)")
ci = l.multi_clip(c0.cell_index, [RBA::Box.new(0, 0, 200, 200),RBA::Box.new(1000, 0, 1300, 200)])
assert_equal(dump_layer_i(l, 0, ci[0]), "(0,100;200,200); (0,100;200,200); (100,0;200,200)")
assert_equal(dump_layer_i(l, 0, ci[1]), "(1000,0;1100,200); (1200,0;1300,200)")
cic = l.multi_clip(c0, [RBA::Box.new(0, 0, 200, 200),RBA::Box.new(1000, 0, 1300, 200)])
assert_equal(dump_layer_i(l, 0, cic[0].cell_index), "(0,100;200,200); (0,100;200,200); (100,0;200,200)")
assert_equal(dump_layer_i(l, 0, cic[1].cell_index), "(1000,0;1100,200); (1200,0;1300,200)")
cid = l.multi_clip(c0.cell_index, [RBA::DBox.new(0, 0, 0.2, 0.2),RBA::DBox.new(1.0, 0, 1.3, 0.2)])
assert_equal(dump_layer_i(l, 0, cid[0]), "(0,100;200,200); (0,100;200,200); (100,0;200,200)")
assert_equal(dump_layer_i(l, 0, cid[1]), "(1000,0;1100,200); (1200,0;1300,200)")
cidc = l.multi_clip(c0, [RBA::DBox.new(0, 0, 0.2, 0.2),RBA::DBox.new(1.0, 0, 1.3, 0.2)])
assert_equal(dump_layer_i(l, 0, cidc[0].cell_index), "(0,100;200,200); (0,100;200,200); (100,0;200,200)")
assert_equal(dump_layer_i(l, 0, cidc[1].cell_index), "(1000,0;1100,200); (1200,0;1300,200)")
ll = RBA::Layout.new
ll.dbu = l.dbu
ll.insert_layer_at(0, RBA::LayerInfo.new(2, 0))
@ -1054,10 +1075,31 @@ class DBLayout_TestClass < TestBase
ci = l.clip_into(c0.cell_index, ll, RBA::Box.new(0, 0, 200, 200))
assert_equal(dump_layer_i(ll, 0, ci), "(0,100;200,200); (0,100;200,200); (100,0;200,200)")
cic = l.clip_into(c0, ll, RBA::Box.new(0, 0, 200, 200))
assert_equal(dump_layer_i(ll, 0, cic.cell_index), "(0,100;200,200); (0,100;200,200); (100,0;200,200)")
cid = l.clip_into(c0.cell_index, ll, RBA::DBox.new(0, 0, 0.2, 0.2))
assert_equal(dump_layer_i(ll, 0, cid), "(0,100;200,200); (0,100;200,200); (100,0;200,200)")
cicd = l.clip_into(c0, ll, RBA::DBox.new(0, 0, 0.2, 0.2))
assert_equal(dump_layer_i(ll, 0, cicd.cell_index), "(0,100;200,200); (0,100;200,200); (100,0;200,200)")
ci = l.multi_clip_into(c0.cell_index, ll, [RBA::Box.new(0, 0, 200, 200),RBA::Box.new(1000, 0, 1300, 200)])
assert_equal(dump_layer_i(ll, 0, ci[0]), "(0,100;200,200); (0,100;200,200); (100,0;200,200)")
assert_equal(dump_layer_i(ll, 0, ci[1]), "(1000,0;1100,200); (1200,0;1300,200)")
cic = l.multi_clip_into(c0, ll, [RBA::Box.new(0, 0, 200, 200),RBA::Box.new(1000, 0, 1300, 200)])
assert_equal(dump_layer_i(ll, 0, cic[0]), "(0,100;200,200); (0,100;200,200); (100,0;200,200)")
assert_equal(dump_layer_i(ll, 0, cic[1]), "(1000,0;1100,200); (1200,0;1300,200)")
cid = l.multi_clip_into(c0.cell_index, ll, [RBA::DBox.new(0, 0, 0.2, 0.2),RBA::DBox.new(1.0, 0, 1.3, 0.2)])
assert_equal(dump_layer_i(ll, 0, cid[0]), "(0,100;200,200); (0,100;200,200); (100,0;200,200)")
assert_equal(dump_layer_i(ll, 0, cid[1]), "(1000,0;1100,200); (1200,0;1300,200)")
cicd = l.multi_clip_into(c0, ll, [RBA::DBox.new(0, 0, 0.2, 0.2),RBA::DBox.new(1.0, 0, 1.3, 0.2)])
assert_equal(dump_layer_i(ll, 0, cicd[0]), "(0,100;200,200); (0,100;200,200); (100,0;200,200)")
assert_equal(dump_layer_i(ll, 0, cicd[1]), "(1000,0;1100,200); (1200,0;1300,200)")
end
def test_8