mirror of https://github.com/KLayout/klayout.git
Some refactoring, Cell#dup for convenience
This commit is contained in:
parent
2a3fe08e7b
commit
d762074bc0
|
|
@ -26,6 +26,9 @@
|
|||
#include "dbManager.h"
|
||||
#include "dbBox.h"
|
||||
#include "dbPCellVariant.h"
|
||||
#include "dbLayoutUtils.h"
|
||||
#include "dbLayerMapping.h"
|
||||
#include "dbCellMapping.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
|
|
@ -726,5 +729,313 @@ Cell::set_name (const std::string &name)
|
|||
layout ()->rename_cell (cell_index (), name.c_str ());
|
||||
}
|
||||
|
||||
void
|
||||
Cell::copy_shapes (const db::Cell &source_cell, const db::LayerMapping &layer_mapping)
|
||||
{
|
||||
if (this == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot copy shapes within the same cell")));
|
||||
}
|
||||
|
||||
db::Layout *target_layout = layout ();
|
||||
if (! target_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
const db::Layout *source_layout = source_cell.layout ();
|
||||
if (! source_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
if (target_layout != source_layout) {
|
||||
db::PropertyMapper pm (*target_layout, *source_layout);
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
for (std::map<unsigned int, unsigned int>::const_iterator lm = layer_mapping.begin (); lm != layer_mapping.end (); ++lm) {
|
||||
shapes (lm->second).insert_transformed (source_cell.shapes (lm->first), trans, pm);
|
||||
}
|
||||
} else {
|
||||
for (std::map<unsigned int, unsigned int>::const_iterator lm = layer_mapping.begin (); lm != layer_mapping.end (); ++lm) {
|
||||
shapes (lm->second).insert (source_cell.shapes (lm->first));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Cell::copy_shapes (const db::Cell &source_cell)
|
||||
{
|
||||
if (this == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot copy shapes within the same cell")));
|
||||
}
|
||||
db::Layout *target_layout = layout ();
|
||||
if (! target_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
if (target_layout != source_cell.layout ()) {
|
||||
if (! source_cell.layout ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
db::LayerMapping lm;
|
||||
lm.create_full (*target_layout, *source_cell.layout ());
|
||||
this->copy_shapes (source_cell, lm);
|
||||
} else {
|
||||
for (db::Layout::layer_iterator l = target_layout->begin_layers (); l != target_layout->end_layers (); ++l) {
|
||||
shapes ((*l).first).insert (source_cell.shapes ((*l).first));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Cell::copy_instances (const db::Cell &source_cell)
|
||||
{
|
||||
if (this == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot copy instances within the same cell")));
|
||||
}
|
||||
if (layout () != source_cell.layout ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cells do not reside in the same layout")));
|
||||
}
|
||||
|
||||
for (db::Cell::const_iterator i = source_cell.begin (); ! i.at_end (); ++i) {
|
||||
insert (*i);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<db::cell_index_type>
|
||||
Cell::copy_tree (const db::Cell &source_cell)
|
||||
{
|
||||
if (this == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot copy shapes within the same cell")));
|
||||
}
|
||||
|
||||
db::Layout *target_layout = layout ();
|
||||
if (! target_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
const db::Layout *source_layout = source_cell.layout ();
|
||||
if (! source_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
||||
db::CellMapping cm;
|
||||
std::vector <db::cell_index_type> new_cells = cm.create_single_mapping_full (*target_layout, cell_index (), *source_layout, source_cell.cell_index ());
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.create_full (*target_layout, *source_cell.layout ());
|
||||
|
||||
std::vector <db::cell_index_type> source_cells;
|
||||
source_cells.push_back (source_cell.cell_index ());
|
||||
db::copy_shapes (*target_layout, *source_layout, trans, source_cells, cm.table (), lm.table ());
|
||||
|
||||
return new_cells;
|
||||
}
|
||||
|
||||
void
|
||||
Cell::copy_tree_shapes (const db::Cell &source_cell, const db::CellMapping &cm)
|
||||
{
|
||||
if (this == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot copy shapes within the same cell")));
|
||||
}
|
||||
|
||||
db::Layout *target_layout = layout ();
|
||||
if (! target_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
const db::Layout *source_layout = source_cell.layout ();
|
||||
if (! source_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.create_full (*target_layout, *source_cell.layout ());
|
||||
|
||||
std::vector <db::cell_index_type> source_cells;
|
||||
source_cells.push_back (source_cell.cell_index ());
|
||||
db::copy_shapes (*target_layout, *source_layout, trans, source_cells, cm.table (), lm.table ());
|
||||
}
|
||||
|
||||
void
|
||||
Cell::copy_tree_shapes (const db::Cell &source_cell, const db::CellMapping &cm, const db::LayerMapping &lm)
|
||||
{
|
||||
if (this == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot copy shapes within the same cell")));
|
||||
}
|
||||
|
||||
db::Layout *target_layout = layout ();
|
||||
if (! target_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
const db::Layout *source_layout = source_cell.layout ();
|
||||
if (! source_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
||||
std::vector <db::cell_index_type> source_cells;
|
||||
source_cells.push_back (source_cell.cell_index ());
|
||||
db::copy_shapes (*target_layout, *source_layout, trans, source_cells, cm.table (), lm.table ());
|
||||
}
|
||||
|
||||
void
|
||||
Cell::move_shapes (db::Cell &source_cell, const db::LayerMapping &layer_mapping)
|
||||
{
|
||||
if (this == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot move shapes within the same cell")));
|
||||
}
|
||||
|
||||
db::Layout *target_layout = layout ();
|
||||
if (! target_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
db::Layout *source_layout = source_cell.layout ();
|
||||
if (! source_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
if (target_layout != source_layout) {
|
||||
db::PropertyMapper pm (*target_layout, *source_layout);
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
for (std::map<unsigned int, unsigned int>::const_iterator lm = layer_mapping.begin (); lm != layer_mapping.end (); ++lm) {
|
||||
shapes (lm->second).insert_transformed (source_cell.shapes (lm->first), trans, pm);
|
||||
source_cell.shapes (lm->first).clear ();
|
||||
}
|
||||
} else {
|
||||
for (std::map<unsigned int, unsigned int>::const_iterator lm = layer_mapping.begin (); lm != layer_mapping.end (); ++lm) {
|
||||
shapes (lm->second).insert (source_cell.shapes (lm->first));
|
||||
source_cell.shapes (lm->first).clear ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Cell::move_shapes (db::Cell &source_cell)
|
||||
{
|
||||
if (this == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot move shapes within the same cell")));
|
||||
}
|
||||
db::Layout *target_layout = layout ();
|
||||
if (! target_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
if (target_layout != source_cell.layout ()) {
|
||||
if (! source_cell.layout ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
db::LayerMapping lm;
|
||||
lm.create_full (*target_layout, *source_cell.layout ());
|
||||
move_shapes (source_cell, lm);
|
||||
} else {
|
||||
for (db::Layout::layer_iterator l = target_layout->begin_layers (); l != target_layout->end_layers (); ++l) {
|
||||
shapes ((*l).first).insert (source_cell.shapes ((*l).first));
|
||||
source_cell.shapes ((*l).first).clear ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Cell::move_instances (db::Cell &source_cell)
|
||||
{
|
||||
if (this == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot move instances within the same cell")));
|
||||
}
|
||||
if (layout () != source_cell.layout ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cells do not reside in the same layout")));
|
||||
}
|
||||
|
||||
for (db::Cell::const_iterator i = source_cell.begin (); ! i.at_end (); ++i) {
|
||||
insert (*i);
|
||||
}
|
||||
|
||||
source_cell.clear_insts ();
|
||||
}
|
||||
|
||||
std::vector<db::cell_index_type>
|
||||
Cell::move_tree (db::Cell &source_cell)
|
||||
{
|
||||
if (this == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot move shapes within the same cell")));
|
||||
}
|
||||
|
||||
db::Layout *target_layout = layout ();
|
||||
if (! target_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
db::Layout *source_layout = source_cell.layout ();
|
||||
if (! source_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
db::PropertyMapper pm (*target_layout, *source_layout);
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
||||
db::CellMapping cm;
|
||||
std::vector <db::cell_index_type> new_cells = cm.create_single_mapping_full (*target_layout, cell_index (), *source_layout, source_cell.cell_index ());
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.create_full (*target_layout, *source_cell.layout ());
|
||||
|
||||
std::vector <db::cell_index_type> source_cells;
|
||||
source_cells.push_back (source_cell.cell_index ());
|
||||
db::move_shapes (*target_layout, *source_layout, trans, source_cells, cm.table (), lm.table ());
|
||||
|
||||
source_layout->prune_subcells (source_cell.cell_index ());
|
||||
|
||||
return new_cells;
|
||||
}
|
||||
|
||||
void
|
||||
Cell::move_tree_shapes (db::Cell &source_cell, const db::CellMapping &cm)
|
||||
{
|
||||
if (this == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot move shapes within the same cell")));
|
||||
}
|
||||
|
||||
db::Layout *target_layout = layout ();
|
||||
if (! target_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
db::Layout *source_layout = source_cell.layout ();
|
||||
if (! source_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
db::PropertyMapper pm (*target_layout, *source_layout);
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.create_full (*target_layout, *source_cell.layout ());
|
||||
|
||||
std::vector <db::cell_index_type> source_cells;
|
||||
source_cells.push_back (source_cell.cell_index ());
|
||||
db::move_shapes (*target_layout, *source_layout, trans, source_cells, cm.table (), lm.table ());
|
||||
}
|
||||
|
||||
void
|
||||
Cell::move_tree_shapes (db::Cell &source_cell, const db::CellMapping &cm, const db::LayerMapping &lm)
|
||||
{
|
||||
if (this == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot move shapes within the same cell")));
|
||||
}
|
||||
|
||||
db::Layout *target_layout = layout ();
|
||||
if (! target_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
db::Layout *source_layout = source_cell.layout ();
|
||||
if (! source_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
db::PropertyMapper pm (*target_layout, *source_layout);
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
||||
std::vector <db::cell_index_type> source_cells;
|
||||
source_cells.push_back (source_cell.cell_index ());
|
||||
db::move_shapes (*target_layout, *source_layout, trans, source_cells, cm.table (), lm.table ());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ template <class Coord> class generic_repository;
|
|||
class Layout;
|
||||
class Library;
|
||||
class ImportLayerMapping;
|
||||
class CellMapping;
|
||||
class LayerMapping;
|
||||
|
||||
/**
|
||||
* @brief The cell object
|
||||
|
|
@ -937,6 +939,84 @@ public:
|
|||
return mp_layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copies the shapes from the source cell's tree to this cell
|
||||
*
|
||||
* This variant uses the given cell mapping and layer mapping.
|
||||
*/
|
||||
void copy_tree_shapes (const db::Cell &source_cell, const db::CellMapping &cm);
|
||||
|
||||
/**
|
||||
* @brief Copies the shapes from the source cell's tree to this cell
|
||||
*
|
||||
* This variant uses the given cell mapping and layer mapping.
|
||||
*/
|
||||
void copy_tree_shapes (const db::Cell &source_cell, const db::CellMapping &cm, const db::LayerMapping &lm);
|
||||
|
||||
/**
|
||||
* @brief Copies instances and shapes from the source cell to this cell
|
||||
*
|
||||
* If the source and target layout are different ones, the whole cell tree of the source cell
|
||||
* will be copied.
|
||||
* This will create new cells in the target layout to accomodate the source cell tree.
|
||||
* Returns an array with the freshly created cells which acommodate the cell tree.
|
||||
*/
|
||||
std::vector<db::cell_index_type> copy_tree (const db::Cell &source_cell);
|
||||
|
||||
/**
|
||||
* @brief Copies the instances from the source to this cell.
|
||||
*/
|
||||
void copy_instances (const db::Cell &source_cell);
|
||||
|
||||
/**
|
||||
* @brief Copies all shapes from the source cell to this cell
|
||||
*/
|
||||
void copy_shapes (const db::Cell &source_cell);
|
||||
|
||||
/**
|
||||
* @brief Copies all shapes from the source cell to this cell using the given layer mapping
|
||||
*/
|
||||
void copy_shapes (const db::Cell &source_cell, const db::LayerMapping &layer_mapping);
|
||||
|
||||
/**
|
||||
* @brief Moves the shapes from the source cell's tree to this cell
|
||||
*
|
||||
* This variant uses the given cell mapping and layer mapping.
|
||||
*/
|
||||
void move_tree_shapes (db::Cell &source_cell, const db::CellMapping &cm);
|
||||
|
||||
/**
|
||||
* @brief Moves the shapes from the source cell's tree to this cell
|
||||
*
|
||||
* This variant uses the given cell mapping and layer mapping.
|
||||
*/
|
||||
void move_tree_shapes (db::Cell &source_cell, const db::CellMapping &cm, const db::LayerMapping &lm);
|
||||
|
||||
/**
|
||||
* @brief Moves instances and shapes from the source cell to this cell
|
||||
*
|
||||
* If the source and target layout are different ones, the whole cell tree of the source cell
|
||||
* will be copied.
|
||||
* This will create new cells in the target layout to accomodate the source cell tree.
|
||||
* Returns an array with the freshly created cells which acommodate the cell tree.
|
||||
*/
|
||||
std::vector<db::cell_index_type> move_tree (db::Cell &source_cell);
|
||||
|
||||
/**
|
||||
* @brief Moves the instances from the source to this cell.
|
||||
*/
|
||||
void move_instances (db::Cell &source_cell);
|
||||
|
||||
/**
|
||||
* @brief Moves all shapes from the source cell to this cell
|
||||
*/
|
||||
void move_shapes (db::Cell &source_cell);
|
||||
|
||||
/**
|
||||
* @brief Moves all shapes from the source cell to this cell using the given layer mapping
|
||||
*/
|
||||
void move_shapes (db::Cell &source_cell, const db::LayerMapping &layer_mapping);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Standard constructor: create an empty cell object
|
||||
|
|
|
|||
|
|
@ -1206,298 +1206,42 @@ begin_shapes_rec_overlapping_um (const db::Cell *cell, unsigned int layer, db::D
|
|||
|
||||
static void copy_shapes2 (db::Cell *cell, const db::Cell &source_cell, const db::LayerMapping &layer_mapping)
|
||||
{
|
||||
if (cell == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot copy shapes within the same cell")));
|
||||
}
|
||||
|
||||
db::Layout *target_layout = cell->layout ();
|
||||
if (! target_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
const db::Layout *source_layout = source_cell.layout ();
|
||||
if (! source_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
if (target_layout != source_layout) {
|
||||
db::PropertyMapper pm (*target_layout, *source_layout);
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
for (std::map<unsigned int, unsigned int>::const_iterator lm = layer_mapping.begin (); lm != layer_mapping.end (); ++lm) {
|
||||
cell->shapes (lm->second).insert_transformed (source_cell.shapes (lm->first), trans, pm);
|
||||
}
|
||||
} else {
|
||||
for (std::map<unsigned int, unsigned int>::const_iterator lm = layer_mapping.begin (); lm != layer_mapping.end (); ++lm) {
|
||||
cell->shapes (lm->second).insert (source_cell.shapes (lm->first));
|
||||
}
|
||||
}
|
||||
cell->copy_shapes (source_cell, layer_mapping);
|
||||
}
|
||||
|
||||
static void copy_shapes1 (db::Cell *cell, const db::Cell &source_cell)
|
||||
{
|
||||
if (cell == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot copy shapes within the same cell")));
|
||||
}
|
||||
db::Layout *layout = cell->layout ();
|
||||
if (! layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
if (layout != source_cell.layout ()) {
|
||||
if (! source_cell.layout ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
db::LayerMapping lm;
|
||||
lm.create_full (*layout, *source_cell.layout ());
|
||||
copy_shapes2 (cell, source_cell, lm);
|
||||
} else {
|
||||
for (db::Layout::layer_iterator l = layout->begin_layers (); l != layout->end_layers (); ++l) {
|
||||
cell->shapes ((*l).first).insert (source_cell.shapes ((*l).first));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void copy_instances (db::Cell *cell, const db::Cell &source_cell)
|
||||
{
|
||||
if (cell == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot copy instances within the same cell")));
|
||||
}
|
||||
if (cell->layout () != source_cell.layout ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cells do not reside in the same layout")));
|
||||
}
|
||||
|
||||
for (db::Cell::const_iterator i = source_cell.begin (); ! i.at_end (); ++i) {
|
||||
cell->insert (*i);
|
||||
}
|
||||
}
|
||||
|
||||
static std::vector<db::cell_index_type> copy_tree (db::Cell *cell, const db::Cell &source_cell)
|
||||
{
|
||||
if (cell == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot copy shapes within the same cell")));
|
||||
}
|
||||
|
||||
db::Layout *target_layout = cell->layout ();
|
||||
if (! target_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
const db::Layout *source_layout = source_cell.layout ();
|
||||
if (! source_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
||||
db::CellMapping cm;
|
||||
std::vector <db::cell_index_type> new_cells = cm.create_single_mapping_full (*target_layout, cell->cell_index (), *source_layout, source_cell.cell_index ());
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.create_full (*target_layout, *source_cell.layout ());
|
||||
|
||||
std::vector <db::cell_index_type> source_cells;
|
||||
source_cells.push_back (source_cell.cell_index ());
|
||||
db::copy_shapes (*target_layout, *source_layout, trans, source_cells, cm.table (), lm.table ());
|
||||
|
||||
return new_cells;
|
||||
cell->copy_shapes (source_cell);
|
||||
}
|
||||
|
||||
static void copy_tree_shapes2 (db::Cell *cell, const db::Cell &source_cell, const db::CellMapping &cm)
|
||||
{
|
||||
if (cell == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot copy shapes within the same cell")));
|
||||
}
|
||||
|
||||
db::Layout *target_layout = cell->layout ();
|
||||
if (! target_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
const db::Layout *source_layout = source_cell.layout ();
|
||||
if (! source_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.create_full (*target_layout, *source_cell.layout ());
|
||||
|
||||
std::vector <db::cell_index_type> source_cells;
|
||||
source_cells.push_back (source_cell.cell_index ());
|
||||
db::copy_shapes (*target_layout, *source_layout, trans, source_cells, cm.table (), lm.table ());
|
||||
cell->copy_tree_shapes (source_cell, cm);
|
||||
}
|
||||
|
||||
static void copy_tree_shapes3 (db::Cell *cell, const db::Cell &source_cell, const db::CellMapping &cm, const db::LayerMapping &lm)
|
||||
{
|
||||
if (cell == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot copy shapes within the same cell")));
|
||||
}
|
||||
|
||||
db::Layout *target_layout = cell->layout ();
|
||||
if (! target_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
const db::Layout *source_layout = source_cell.layout ();
|
||||
if (! source_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
||||
std::vector <db::cell_index_type> source_cells;
|
||||
source_cells.push_back (source_cell.cell_index ());
|
||||
db::copy_shapes (*target_layout, *source_layout, trans, source_cells, cm.table (), lm.table ());
|
||||
cell->copy_tree_shapes (source_cell, cm, lm);
|
||||
}
|
||||
|
||||
static void move_shapes2 (db::Cell *cell, db::Cell &source_cell, const db::LayerMapping &layer_mapping)
|
||||
{
|
||||
if (cell == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot move shapes within the same cell")));
|
||||
}
|
||||
|
||||
db::Layout *target_layout = cell->layout ();
|
||||
if (! target_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
db::Layout *source_layout = source_cell.layout ();
|
||||
if (! source_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
if (target_layout != source_layout) {
|
||||
db::PropertyMapper pm (*target_layout, *source_layout);
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
for (std::map<unsigned int, unsigned int>::const_iterator lm = layer_mapping.begin (); lm != layer_mapping.end (); ++lm) {
|
||||
cell->shapes (lm->second).insert_transformed (source_cell.shapes (lm->first), trans, pm);
|
||||
source_cell.shapes (lm->first).clear ();
|
||||
}
|
||||
} else {
|
||||
for (std::map<unsigned int, unsigned int>::const_iterator lm = layer_mapping.begin (); lm != layer_mapping.end (); ++lm) {
|
||||
cell->shapes (lm->second).insert (source_cell.shapes (lm->first));
|
||||
source_cell.shapes (lm->first).clear ();
|
||||
}
|
||||
}
|
||||
cell->move_shapes (source_cell, layer_mapping);
|
||||
}
|
||||
|
||||
static void move_shapes1 (db::Cell *cell, db::Cell &source_cell)
|
||||
{
|
||||
if (cell == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot move shapes within the same cell")));
|
||||
}
|
||||
db::Layout *layout = cell->layout ();
|
||||
if (! layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
if (layout != source_cell.layout ()) {
|
||||
if (! source_cell.layout ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
db::LayerMapping lm;
|
||||
lm.create_full (*layout, *source_cell.layout ());
|
||||
move_shapes2 (cell, source_cell, lm);
|
||||
} else {
|
||||
for (db::Layout::layer_iterator l = layout->begin_layers (); l != layout->end_layers (); ++l) {
|
||||
cell->shapes ((*l).first).insert (source_cell.shapes ((*l).first));
|
||||
source_cell.shapes ((*l).first).clear ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void move_instances (db::Cell *cell, db::Cell &source_cell)
|
||||
{
|
||||
if (cell == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot move instances within the same cell")));
|
||||
}
|
||||
if (cell->layout () != source_cell.layout ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cells do not reside in the same layout")));
|
||||
}
|
||||
|
||||
for (db::Cell::const_iterator i = source_cell.begin (); ! i.at_end (); ++i) {
|
||||
cell->insert (*i);
|
||||
}
|
||||
|
||||
source_cell.clear_insts ();
|
||||
}
|
||||
|
||||
static std::vector<db::cell_index_type> move_tree (db::Cell *cell, db::Cell &source_cell)
|
||||
{
|
||||
if (cell == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot move shapes within the same cell")));
|
||||
}
|
||||
|
||||
db::Layout *target_layout = cell->layout ();
|
||||
if (! target_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
db::Layout *source_layout = source_cell.layout ();
|
||||
if (! source_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
db::PropertyMapper pm (*target_layout, *source_layout);
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
||||
db::CellMapping cm;
|
||||
std::vector <db::cell_index_type> new_cells = cm.create_single_mapping_full (*target_layout, cell->cell_index (), *source_layout, source_cell.cell_index ());
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.create_full (*target_layout, *source_cell.layout ());
|
||||
|
||||
std::vector <db::cell_index_type> source_cells;
|
||||
source_cells.push_back (source_cell.cell_index ());
|
||||
db::move_shapes (*target_layout, *source_layout, trans, source_cells, cm.table (), lm.table ());
|
||||
|
||||
source_layout->prune_subcells (source_cell.cell_index ());
|
||||
|
||||
return new_cells;
|
||||
cell->move_shapes (source_cell);
|
||||
}
|
||||
|
||||
static void move_tree_shapes2 (db::Cell *cell, db::Cell &source_cell, const db::CellMapping &cm)
|
||||
{
|
||||
if (cell == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot move shapes within the same cell")));
|
||||
}
|
||||
|
||||
db::Layout *target_layout = cell->layout ();
|
||||
if (! target_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
db::Layout *source_layout = source_cell.layout ();
|
||||
if (! source_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
db::PropertyMapper pm (*target_layout, *source_layout);
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.create_full (*target_layout, *source_cell.layout ());
|
||||
|
||||
std::vector <db::cell_index_type> source_cells;
|
||||
source_cells.push_back (source_cell.cell_index ());
|
||||
db::move_shapes (*target_layout, *source_layout, trans, source_cells, cm.table (), lm.table ());
|
||||
cell->move_tree_shapes (source_cell, cm);
|
||||
}
|
||||
|
||||
static void move_tree_shapes3 (db::Cell *cell, db::Cell &source_cell, const db::CellMapping &cm, const db::LayerMapping &lm)
|
||||
{
|
||||
if (cell == &source_cell) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot move shapes within the same cell")));
|
||||
}
|
||||
|
||||
db::Layout *target_layout = cell->layout ();
|
||||
if (! target_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell does not reside in a layout")));
|
||||
}
|
||||
db::Layout *source_layout = source_cell.layout ();
|
||||
if (! source_layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
|
||||
}
|
||||
|
||||
db::PropertyMapper pm (*target_layout, *source_layout);
|
||||
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
|
||||
|
||||
std::vector <db::cell_index_type> source_cells;
|
||||
source_cells.push_back (source_cell.cell_index ());
|
||||
db::move_shapes (*target_layout, *source_layout, trans, source_cells, cm.table (), lm.table ());
|
||||
cell->move_tree_shapes (source_cell, cm, lm);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1686,6 +1430,21 @@ static const db::Shapes *shapes_of_cell_const (const db::Cell *cell, unsigned in
|
|||
return &cell->shapes (layer);
|
||||
}
|
||||
|
||||
static db::Cell *dup_cell (const db::Cell *cell)
|
||||
{
|
||||
if (! cell->layout ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot create a copy of a cell which is not part of a layout")));
|
||||
}
|
||||
|
||||
db::Layout *layout = const_cast<db::Layout *> (cell->layout ());
|
||||
db::Cell *new_cell = &layout->cell (layout->add_cell (layout->cell_name (cell->cell_index ())));
|
||||
|
||||
new_cell->copy_shapes (*cell);
|
||||
new_cell->copy_instances (*cell);
|
||||
|
||||
return new_cell;
|
||||
}
|
||||
|
||||
Class<db::Cell> decl_Cell ("db", "Cell",
|
||||
gsi::method ("name", &db::Cell::get_basic_name,
|
||||
"@brief Gets the cell's name\n"
|
||||
|
|
@ -1759,6 +1518,15 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||
"\n"
|
||||
"This method has been introduced in version 0.23.\n"
|
||||
) +
|
||||
gsi::method_ext ("dup", &dup_cell,
|
||||
"@brief Creates a copy of the cell\n"
|
||||
"\n"
|
||||
"This method will create a copy of the cell. The new cell will be member of the same layout the original cell "
|
||||
"was member of. The copy will inherit all shapes and instances, but get "
|
||||
"a different cell_index and a modified name as duplicate cell names are not allowed in the same layout.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.27.\n"
|
||||
) +
|
||||
gsi::method ("shapes", (db::Cell::shapes_type &(db::Cell::*) (unsigned int)) &db::Cell::shapes, gsi::arg ("layer_index"),
|
||||
"@brief Returns the shapes list of the given layer\n"
|
||||
"\n"
|
||||
|
|
@ -2092,7 +1860,7 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||
"\n"
|
||||
"This method has been added in version 0.23.\n"
|
||||
) +
|
||||
gsi::method_ext ("copy_instances", ©_instances, gsi::arg ("source_cell"),
|
||||
gsi::method ("copy_instances", &db::Cell::copy_instances, gsi::arg ("source_cell"),
|
||||
"@brief Copies the instances of child cells in the source cell to this cell\n"
|
||||
"@param source_cell The cell where the instances are copied from\n"
|
||||
"The source cell must reside in the same layout than this cell. The instances of "
|
||||
|
|
@ -2106,7 +1874,7 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||
"\n"
|
||||
"This method has been added in version 0.23.\n"
|
||||
) +
|
||||
gsi::method_ext ("copy_tree", ©_tree, gsi::arg ("source_cell"),
|
||||
gsi::method ("copy_tree", &db::Cell::copy_tree, gsi::arg ("source_cell"),
|
||||
"@brief Copies the cell tree of the given cell into this cell\n"
|
||||
"@param source_cell The cell from where to copy the cell tree\n"
|
||||
"@return A list of indexes of newly created cells\n"
|
||||
|
|
@ -2196,7 +1964,7 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||
"\n"
|
||||
"This method has been added in version 0.23.\n"
|
||||
) +
|
||||
gsi::method_ext ("move_instances", &move_instances, gsi::arg ("source_cell"),
|
||||
gsi::method ("move_instances", &db::Cell::move_instances, gsi::arg ("source_cell"),
|
||||
"@brief Moves the instances of child cells in the source cell to this cell\n"
|
||||
"@param source_cell The cell where the instances are moved from\n"
|
||||
"The source cell must reside in the same layout than this cell. The instances of "
|
||||
|
|
@ -2210,7 +1978,7 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||
"\n"
|
||||
"This method has been added in version 0.23.\n"
|
||||
) +
|
||||
gsi::method_ext ("move_tree", &move_tree, gsi::arg ("source_cell"),
|
||||
gsi::method ("move_tree", &db::Cell::move_tree, gsi::arg ("source_cell"),
|
||||
"@brief Moves the cell tree of the given cell into this cell\n"
|
||||
"@param source_cell The cell from where to move the cell tree\n"
|
||||
"@return A list of indexes of newly created cells\n"
|
||||
|
|
|
|||
|
|
@ -2143,6 +2143,45 @@ END
|
|||
|
||||
end
|
||||
|
||||
def test_21
|
||||
|
||||
# dup cells
|
||||
|
||||
l = RBA::Layout.new
|
||||
l.insert_layer_at(0, RBA::LayerInfo.new(1, 0))
|
||||
l.insert_layer_at(1, RBA::LayerInfo.new(2, 0))
|
||||
c0 = l.cell(l.add_cell("c0"))
|
||||
c1 = l.cell(l.add_cell("c1"))
|
||||
c2 = l.cell(l.add_cell("c2"))
|
||||
c3 = l.cell(l.add_cell("c3"))
|
||||
|
||||
b = RBA::Box.new(0, 100, 1000, 1200)
|
||||
c0.shapes(0).insert(b)
|
||||
c1.shapes(0).insert(b)
|
||||
c2.shapes(0).insert(b)
|
||||
c3.shapes(0).insert(b)
|
||||
b = RBA::Box.new(1, 101, 1001, 1201)
|
||||
s = c0.shapes(1).insert(b)
|
||||
s.set_property("p", 17)
|
||||
|
||||
tt = RBA::Trans.new
|
||||
s = c0.insert(RBA::CellInstArray.new(c1.cell_index, tt))
|
||||
s.set_property("p", 18)
|
||||
c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100))))
|
||||
c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1)))
|
||||
c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0))))
|
||||
|
||||
assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)")
|
||||
assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)")
|
||||
|
||||
c9 = c0.dup
|
||||
|
||||
assert_equal(c9.name, "c0$1")
|
||||
assert_equal(collect(c9.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)")
|
||||
assert_equal(collect(c9.begin_shapes_rec(1), l), "[c0$1](1,101;1001,1201)")
|
||||
|
||||
end
|
||||
|
||||
# Iterating while flatten
|
||||
def test_issue200
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue