mirror of https://github.com/KLayout/klayout.git
WIP: provide a way to report user properties to RDB, added antenna rule measurements as user properties.
This commit is contained in:
parent
2cb3e037a9
commit
e4131b45a3
|
|
@ -1366,10 +1366,38 @@ compute_area_and_perimeter_of_net_shapes (const db::hier_clusters<db::NetShape>
|
|||
perimeter = ap_collector.perimeter ();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class AntennaShapeGenerator
|
||||
: public PolygonSink
|
||||
{
|
||||
public:
|
||||
AntennaShapeGenerator (db::Layout *layout, db::Shapes &shapes, db::properties_id_type prop_id)
|
||||
: PolygonSink (), mp_layout (layout), mp_shapes (&shapes), m_prop_id (prop_id)
|
||||
{ }
|
||||
|
||||
virtual void put (const db::Polygon &polygon)
|
||||
{
|
||||
if (m_prop_id != 0) {
|
||||
mp_shapes->insert (db::PolygonRefWithProperties (db::PolygonRef (polygon, mp_layout->shape_repository ()), m_prop_id));
|
||||
} else {
|
||||
mp_shapes->insert (db::PolygonRef (polygon, mp_layout->shape_repository ()));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
db::Layout *mp_layout;
|
||||
db::Shapes *mp_shapes;
|
||||
db::properties_id_type m_prop_id;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
static db::Point
|
||||
get_merged_shapes_of_net (const db::hier_clusters<db::NetShape> &clusters, db::cell_index_type ci, size_t cid, unsigned int layer_id, db::Shapes &shapes)
|
||||
get_merged_shapes_of_net (const db::hier_clusters<db::NetShape> &clusters, db::cell_index_type ci, size_t cid, unsigned int layer_id, db::Layout *layout, db::Shapes &shapes, db::properties_id_type prop_id)
|
||||
{
|
||||
db::Point ref;
|
||||
bool any_ref = false;
|
||||
db::EdgeProcessor ep;
|
||||
|
||||
// count vertices and reserve space
|
||||
|
|
@ -1386,7 +1414,10 @@ get_merged_shapes_of_net (const db::hier_clusters<db::NetShape> &clusters, db::c
|
|||
db::PolygonRef::polygon_edge_iterator e = pr.begin_edge ();
|
||||
if (! e.at_end ()) {
|
||||
// pick one reference point for the label
|
||||
ref = (*e).p1 ();
|
||||
if (! any_ref && (*e).p1 () < ref) {
|
||||
ref = (*e).p1 ();
|
||||
any_ref = true;
|
||||
}
|
||||
ep.insert (pr, ++p);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1394,7 +1425,7 @@ get_merged_shapes_of_net (const db::hier_clusters<db::NetShape> &clusters, db::c
|
|||
}
|
||||
}
|
||||
|
||||
db::ShapeGenerator sg (shapes);
|
||||
db::AntennaShapeGenerator sg (layout, shapes, prop_id);
|
||||
db::PolygonGenerator pg (sg, false);
|
||||
db::SimpleMerge op;
|
||||
ep.process (pg, op);
|
||||
|
|
@ -1402,52 +1433,51 @@ get_merged_shapes_of_net (const db::hier_clusters<db::NetShape> &clusters, db::c
|
|||
return ref;
|
||||
}
|
||||
|
||||
static std::string
|
||||
create_antenna_msg (double agate, db::Polygon::area_type agate_int, double gate_area_factor, db::Polygon::perimeter_type pgate_int, double gate_perimeter_factor,
|
||||
double ametal, db::Polygon::area_type ametal_int, double metal_area_factor, db::Polygon::perimeter_type pmetal_int, double metal_perimeter_factor,
|
||||
const std::vector<std::pair<const db::Region *, double> > &diodes,
|
||||
const std::vector<db::Polygon::area_type> &adiodes_int,
|
||||
double r, double ratio, double dbu)
|
||||
static std::vector<std::pair<std::string, tl::Variant> >
|
||||
create_antenna_values (double agate, db::Polygon::area_type agate_int, double gate_area_factor, db::Polygon::perimeter_type pgate_int, double gate_perimeter_factor,
|
||||
double ametal, db::Polygon::area_type ametal_int, double metal_area_factor, db::Polygon::perimeter_type pmetal_int, double metal_perimeter_factor,
|
||||
const std::vector<std::pair<const db::Region *, double> > &diodes,
|
||||
const std::vector<db::Polygon::area_type> &adiodes_int,
|
||||
double r, double ratio, double dbu)
|
||||
{
|
||||
std::string msg;
|
||||
msg += tl::sprintf ("agate_eff: %.12g, ", agate);
|
||||
std::vector<std::pair<std::string, tl::Variant> > values;
|
||||
|
||||
values.push_back (std::make_pair ("agate_eff", agate));
|
||||
if (fabs (gate_area_factor) > 1e-6) {
|
||||
msg += tl::sprintf ("agate: %.12g, agate_factor: %.12g, ", agate_int * dbu * dbu, gate_area_factor);
|
||||
values.push_back (std::make_pair ("agate", agate_int * dbu * dbu));
|
||||
values.push_back (std::make_pair ("agate_factor", gate_area_factor));
|
||||
}
|
||||
if (fabs (gate_perimeter_factor) > 1e-6) {
|
||||
msg += tl::sprintf ("pgate: %.12g, pgate_factor: %.12g, ", pgate_int * dbu * dbu, gate_perimeter_factor);
|
||||
values.push_back (std::make_pair ("pgate", pgate_int * dbu));
|
||||
values.push_back (std::make_pair ("pgate_factor", gate_perimeter_factor));
|
||||
}
|
||||
msg += tl::sprintf ("ametal_eff: %.12g, ", ametal);
|
||||
values.push_back (std::make_pair ("ametal_eff", ametal));
|
||||
if (fabs (metal_area_factor) > 1e-6) {
|
||||
msg += tl::sprintf ("ametal: %.12g, ametal_factor: %.12g, ", ametal_int * dbu * dbu, metal_area_factor);
|
||||
values.push_back (std::make_pair ("ametal", ametal_int * dbu * dbu));
|
||||
values.push_back (std::make_pair ("ametal_factor", metal_area_factor));
|
||||
}
|
||||
if (fabs (metal_perimeter_factor) > 1e-6) {
|
||||
msg += tl::sprintf ("pmetal: %.12g, pmetal_factor: %.12g, ", pmetal_int * dbu * dbu, metal_perimeter_factor);
|
||||
values.push_back (std::make_pair ("pmetal", pmetal_int * dbu));
|
||||
values.push_back (std::make_pair ("pmetal_factor", metal_perimeter_factor));
|
||||
}
|
||||
if (! adiodes_int.empty ()) {
|
||||
msg += "adiodes: [";
|
||||
tl::Variant adiodes;
|
||||
for (auto d = adiodes_int.begin (); d != adiodes_int.end (); ++d) {
|
||||
if (d != adiodes_int.begin ()) {
|
||||
msg += ", ";
|
||||
}
|
||||
msg += tl::sprintf ("%.12g", *d * dbu * dbu);
|
||||
adiodes.push (*d * dbu * dbu);
|
||||
}
|
||||
msg += "], ";
|
||||
values.push_back (std::make_pair ("adiodes", adiodes));
|
||||
}
|
||||
if (! diodes.empty ()) {
|
||||
msg += "diode_factors: [";
|
||||
tl::Variant diode_factors;
|
||||
for (auto d = diodes.begin (); d != diodes.end (); ++d) {
|
||||
if (d != diodes.begin ()) {
|
||||
msg += ", ";
|
||||
}
|
||||
msg += tl::sprintf ("%.12g", d->second);
|
||||
diode_factors.push (d->second);
|
||||
}
|
||||
msg += "], ";
|
||||
values.push_back (std::make_pair ("diode_factors", diode_factors));
|
||||
}
|
||||
msg += tl::sprintf ("ratio: %.12g, ", ametal / agate);
|
||||
msg += tl::sprintf ("max_ratio_eff: %.12g, ", r);
|
||||
msg += tl::sprintf ("max_ratio: %.12g", ratio);
|
||||
return msg;
|
||||
values.push_back (std::make_pair ("ratio", ametal / agate));
|
||||
values.push_back (std::make_pair ("max_ratio_eff", r));
|
||||
values.push_back (std::make_pair ("max_ratio", ratio));
|
||||
return values;
|
||||
}
|
||||
|
||||
db::Region LayoutToNetlist::antenna_check (const db::Region &gate, double gate_area_factor, double gate_perimeter_factor, const db::Region &metal, double metal_area_factor, double metal_perimeter_factor, double ratio, const std::vector<std::pair<const db::Region *, double> > &diodes, db::Texts *values)
|
||||
|
|
@ -1538,25 +1568,50 @@ db::Region LayoutToNetlist::antenna_check (const db::Region &gate, double gate_a
|
|||
}
|
||||
|
||||
if (tl::verbosity () >= 50) {
|
||||
tl::info << "cell [" << ly.cell_name (*cid) << "]: " <<
|
||||
create_antenna_msg (agate, agate_int, gate_area_factor, pgate_int, gate_perimeter_factor,
|
||||
ametal, ametal_int, metal_area_factor, pmetal_int, metal_perimeter_factor,
|
||||
diodes, adiodes_int, r, ratio, dbu);
|
||||
std::vector<std::pair<std::string, tl::Variant> > antenna_values =
|
||||
create_antenna_values (agate, agate_int, gate_area_factor, pgate_int, gate_perimeter_factor,
|
||||
ametal, ametal_int, metal_area_factor, pmetal_int, metal_perimeter_factor,
|
||||
diodes, adiodes_int, r, ratio, dbu);
|
||||
tl::info << "cell [" << ly.cell_name (*cid) << "]: ";
|
||||
for (auto v = antenna_values.begin (); v != antenna_values.end (); ++v) {
|
||||
tl::info << " " << v->first << ": " << v->second.to_string ();
|
||||
}
|
||||
}
|
||||
|
||||
if (ametal / agate > r + db::epsilon) {
|
||||
|
||||
db::Shapes &shapes = ly.cell (*cid).shapes (dl.layer ());
|
||||
db::Point ref = get_merged_shapes_of_net (m_net_clusters, *cid, *c, layer_of (metal), shapes);
|
||||
|
||||
std::vector<std::pair<std::string, tl::Variant> > antenna_values =
|
||||
create_antenna_values (agate, agate_int, gate_area_factor, pgate_int, gate_perimeter_factor,
|
||||
ametal, ametal_int, metal_area_factor, pmetal_int, metal_perimeter_factor,
|
||||
diodes, adiodes_int, r, ratio, dbu);
|
||||
|
||||
db::properties_id_type prop_id = 0;
|
||||
if (! values) {
|
||||
db::PropertiesRepository::properties_set ps;
|
||||
for (auto v = antenna_values.begin (); v != antenna_values.end (); ++v) {
|
||||
ps.insert (std::make_pair (ly.properties_repository ().prop_name_id (v->first), v->second));
|
||||
}
|
||||
prop_id = ly.properties_repository ().properties_id (ps);
|
||||
}
|
||||
|
||||
db::Point ref = get_merged_shapes_of_net (m_net_clusters, *cid, *c, layer_of (metal), &ly, shapes, prop_id);
|
||||
|
||||
if (values) {
|
||||
|
||||
// generate a data string with the details of the antenna computation (intentionally like JSON)
|
||||
std::string msg = create_antenna_msg (agate, agate_int, gate_area_factor, pgate_int, gate_perimeter_factor,
|
||||
ametal, ametal_int, metal_area_factor, pmetal_int, metal_perimeter_factor,
|
||||
diodes, adiodes_int, r, ratio, dbu);
|
||||
|
||||
db::Shapes &shapesv = ly.cell (*cid).shapes (dlv.layer ());
|
||||
|
||||
std::string msg;
|
||||
for (auto v = antenna_values.begin (); v != antenna_values.end (); ++v) {
|
||||
if (v != antenna_values.begin ()) {
|
||||
msg += ", ";
|
||||
}
|
||||
msg += v->first;
|
||||
msg += ": ";
|
||||
msg += v->second.to_string ();
|
||||
}
|
||||
|
||||
shapesv.insert (db::Text (msg, db::Trans (ref - db::Point ())));
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -248,42 +248,32 @@ ItemRefUnwrappingIterator category_items_end (const rdb::Category *cat)
|
|||
return cat->database ()->items_by_category (cat->id ()).second;
|
||||
}
|
||||
|
||||
static void scan_layer1 (rdb::Category *cat, const db::Layout &layout, unsigned int layer)
|
||||
static void scan_layer (rdb::Category *cat, const db::Layout &layout, unsigned int layer, const db::Cell *from_cell, int levels, bool with_properties)
|
||||
{
|
||||
rdb::scan_layer (cat, layout, layer);
|
||||
rdb::scan_layer (cat, layout, layer, from_cell, levels, with_properties);
|
||||
}
|
||||
|
||||
static void scan_layer2 (rdb::Category *cat, const db::Layout &layout, unsigned int layer, const db::Cell *from_cell)
|
||||
static void scan_shapes (rdb::Category *cat, const db::RecursiveShapeIterator &iter, bool flat, bool with_properties)
|
||||
{
|
||||
rdb::scan_layer (cat, layout, layer, from_cell);
|
||||
rdb::scan_layer (cat, iter, flat, with_properties);
|
||||
}
|
||||
|
||||
static void scan_layer3 (rdb::Category *cat, const db::Layout &layout, unsigned int layer, const db::Cell *from_cell, int levels)
|
||||
{
|
||||
rdb::scan_layer (cat, layout, layer, from_cell, levels);
|
||||
}
|
||||
|
||||
static void scan_shapes (rdb::Category *cat, const db::RecursiveShapeIterator &iter, bool flat)
|
||||
{
|
||||
rdb::scan_layer (cat, iter, flat);
|
||||
}
|
||||
|
||||
static void scan_region (rdb::Category *cat, rdb::Cell *cell, const db::CplxTrans &trans, const db::Region ®ion, bool flat)
|
||||
static void scan_region (rdb::Category *cat, rdb::Cell *cell, const db::CplxTrans &trans, const db::Region ®ion, bool flat, bool with_properties)
|
||||
{
|
||||
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> it = region.begin_iter ();
|
||||
rdb::scan_layer (cat, cell, trans * it.second, it.first, flat);
|
||||
rdb::scan_layer (cat, cell, trans * it.second, it.first, flat, with_properties);
|
||||
}
|
||||
|
||||
static void scan_edges (rdb::Category *cat, rdb::Cell *cell, const db::CplxTrans &trans, const db::Edges &edges, bool flat)
|
||||
static void scan_edges (rdb::Category *cat, rdb::Cell *cell, const db::CplxTrans &trans, const db::Edges &edges, bool flat, bool with_properties)
|
||||
{
|
||||
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> it = edges.begin_iter ();
|
||||
rdb::scan_layer (cat, cell, trans * it.second, it.first, flat);
|
||||
rdb::scan_layer (cat, cell, trans * it.second, it.first, flat, with_properties);
|
||||
}
|
||||
|
||||
static void scan_edge_pairs (rdb::Category *cat, rdb::Cell *cell, const db::CplxTrans &trans, const db::EdgePairs &edge_pairs, bool flat)
|
||||
static void scan_edge_pairs (rdb::Category *cat, rdb::Cell *cell, const db::CplxTrans &trans, const db::EdgePairs &edge_pairs, bool flat, bool with_properties)
|
||||
{
|
||||
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> it = edge_pairs.begin_iter ();
|
||||
rdb::scan_layer (cat, cell, trans * it.second, it.first, flat);
|
||||
rdb::scan_layer (cat, cell, trans * it.second, it.first, flat, with_properties);
|
||||
}
|
||||
|
||||
Class<rdb::Category> decl_RdbCategory ("rdb", "RdbCategory",
|
||||
|
|
@ -303,7 +293,7 @@ Class<rdb::Category> decl_RdbCategory ("rdb", "RdbCategory",
|
|||
"\n"
|
||||
"This method has been introduced in version 0.23."
|
||||
) +
|
||||
gsi::method_ext ("scan_shapes", &scan_shapes, gsi::arg ("iter"), gsi::arg ("flat", false),
|
||||
gsi::method_ext ("scan_shapes", &scan_shapes, gsi::arg ("iter"), gsi::arg ("flat", false), gsi::arg ("with_properties", true),
|
||||
"@brief Scans the polygon or edge shapes from the shape iterator into the category\n"
|
||||
"Creates RDB items for each polygon or edge shape read from the iterator and puts them into this category.\n"
|
||||
"A similar, but lower-level method is \\ReportDatabase#create_items with a \\RecursiveShapeIterator argument.\n"
|
||||
|
|
@ -311,9 +301,11 @@ Class<rdb::Category> decl_RdbCategory ("rdb", "RdbCategory",
|
|||
"if the \\flat argument is false. In this case, the hierarchy the recursive shape iterator traverses is "
|
||||
"copied into the report database using sample references.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.23. The flat mode argument has been added in version 0.26.\n"
|
||||
"If 'with_properties' is true, user properties will be turned into tagged values as well.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.23. The flat mode argument has been added in version 0.26. The 'with_properties' argument has been added in version 0.28.\n"
|
||||
) +
|
||||
gsi::method_ext ("scan_collection", &scan_region, gsi::arg ("cell"), gsi::arg ("trans"), gsi::arg ("region"), gsi::arg ("flat", false),
|
||||
gsi::method_ext ("scan_collection", &scan_region, gsi::arg ("cell"), gsi::arg ("trans"), gsi::arg ("region"), gsi::arg ("flat", false), gsi::arg ("with_properties", true),
|
||||
"@brief Turns the given region into a hierarchical or flat report database\n"
|
||||
"The exact behavior depends on the nature of the region. If the region is a hierarchical (original or deep) region "
|
||||
"and the 'flat' argument is false, this method will produce a hierarchical report database in the given category. "
|
||||
|
|
@ -325,44 +317,36 @@ Class<rdb::Category> decl_RdbCategory ("rdb", "RdbCategory",
|
|||
"\n"
|
||||
"The transformation argument needs to supply the dbu-to-micron transformation.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.26.\n"
|
||||
"If 'with_properties' is true, user properties will be turned into tagged values as well.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.26. The 'with_properties' argument has been added in version 0.28.\n"
|
||||
) +
|
||||
gsi::method_ext ("scan_collection", &scan_edges, gsi::arg ("cell"), gsi::arg ("trans"), gsi::arg ("edges"), gsi::arg ("flat", false),
|
||||
gsi::method_ext ("scan_collection", &scan_edges, gsi::arg ("cell"), gsi::arg ("trans"), gsi::arg ("edges"), gsi::arg ("flat", false), gsi::arg ("with_properties", true),
|
||||
"@brief Turns the given edge collection into a hierarchical or flat report database\n"
|
||||
"This a another flavour of \\scan_collection accepting an edge collection.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.26.\n"
|
||||
"If 'with_properties' is true, user properties will be turned into tagged values as well.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.26. The 'with_properties' argument has been added in version 0.28.\n"
|
||||
) +
|
||||
gsi::method_ext ("scan_collection", &scan_edge_pairs, gsi::arg ("cell"), gsi::arg ("trans"), gsi::arg ("edge_pairs"), gsi::arg ("flat", false),
|
||||
gsi::method_ext ("scan_collection", &scan_edge_pairs, gsi::arg ("cell"), gsi::arg ("trans"), gsi::arg ("edge_pairs"), gsi::arg ("flat", false), gsi::arg ("with_properties", true),
|
||||
"@brief Turns the given edge pair collection into a hierarchical or flat report database\n"
|
||||
"This a another flavour of \\scan_collection accepting an edge pair collection.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.26.\n"
|
||||
) +
|
||||
gsi::method_ext ("scan_layer", &scan_layer1, gsi::arg ("layout"), gsi::arg ("layer"),
|
||||
"@brief Scans a layer from a layout into this category\n"
|
||||
"Creates RDB items for each polygon or edge shape read from the each cell in the layout on the given layer and puts them into this category.\n"
|
||||
"New cells will be generated for every cell encountered in the layout.\n"
|
||||
"Other settings like database unit, description, top cell etc. are not made in the RDB.\n"
|
||||
"If 'with_properties' is true, user properties will be turned into tagged values as well.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.23.\n"
|
||||
"This method has been introduced in version 0.26. The 'with_properties' argument has been added in version 0.28.\n"
|
||||
) +
|
||||
gsi::method_ext ("scan_layer", &scan_layer2, gsi::arg ("layout"), gsi::arg ("layer"), gsi::arg ("cell"),
|
||||
"@brief Scans a layer from a layout into this category, starting with a given cell\n"
|
||||
"Creates RDB items for each polygon or edge shape read from the cell and it's children in the layout on the given layer and puts them into this category.\n"
|
||||
"New cells will be generated when required.\n"
|
||||
"Other settings like database unit, description, top cell etc. are not made in the RDB.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.23.\n"
|
||||
) +
|
||||
gsi::method_ext ("scan_layer", &scan_layer3, gsi::arg ("layout"), gsi::arg ("layer"), gsi::arg ("cell"), gsi::arg ("levels"),
|
||||
gsi::method_ext ("scan_layer", &scan_layer, gsi::arg ("layout"), gsi::arg ("layer"), gsi::arg ("cell", (const db::Cell *) 0, "nil"), gsi::arg ("levels", -1), gsi::arg ("with_properties", true),
|
||||
"@brief Scans a layer from a layout into this category, starting with a given cell and a depth specification\n"
|
||||
"Creates RDB items for each polygon or edge shape read from the cell and it's children in the layout on the given layer and puts them into this category.\n"
|
||||
"New cells will be generated when required.\n"
|
||||
"\"levels\" is the number of hierarchy levels to take the child cells from. 0 means to use only \"cell\" and don't descend, -1 means \"all levels\".\n"
|
||||
"Other settings like database unit, description, top cell etc. are not made in the RDB.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.23.\n"
|
||||
"If 'with_properties' is true, user properties will be turned into tagged values as well.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.23. The 'with_properties' argument has been added in version 0.28.\n"
|
||||
) +
|
||||
gsi::method ("name", &rdb::Category::name,
|
||||
"@brief Gets the category name\n"
|
||||
|
|
@ -1209,7 +1193,7 @@ Class<rdb::Database> decl_ReportDatabase ("rdb", "ReportDatabase",
|
|||
"\n"
|
||||
"This convenience method has been added in version 0.25.\n"
|
||||
) +
|
||||
gsi::method_ext ("create_items", &rdb::create_items_from_iterator, gsi::arg ("cell_id"), gsi::arg ("category_id"), gsi::arg ("iter"),
|
||||
gsi::method_ext ("create_items", &rdb::create_items_from_iterator, gsi::arg ("cell_id"), gsi::arg ("category_id"), gsi::arg ("iter"), gsi::arg ("with_properties", true),
|
||||
"@brief Creates new items from a shape iterator\n"
|
||||
"This method takes the shapes from the given iterator and produces items from them.\n"
|
||||
"It accepts various kind of shapes, such as texts, polygons, boxes and paths and "
|
||||
|
|
@ -1217,39 +1201,42 @@ Class<rdb::Database> decl_ReportDatabase ("rdb", "ReportDatabase",
|
|||
"A similar method, which is intended for production of polygon or edge error layers and also provides hierarchical database "
|
||||
"construction is \\RdbCategory#scan_shapes.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.25.3.\n"
|
||||
"This method has been introduced in version 0.25.3. The 'with_properties' argument has been added in version 0.28.\n"
|
||||
"\n"
|
||||
"@param cell_id The ID of the cell to which the item is associated\n"
|
||||
"@param category_id The ID of the category to which the item is associated\n"
|
||||
"@param iter The iterator (a \\RecursiveShapeIterator object) from which to take the items\n"
|
||||
"@param with_properties If true, user properties will be turned into tagged values as well\n"
|
||||
) +
|
||||
gsi::method_ext ("create_item", &rdb::create_item_from_shape, gsi::arg ("cell_id"), gsi::arg ("category_id"), gsi::arg ("trans"), gsi::arg ("shape"),
|
||||
gsi::method_ext ("create_item", &rdb::create_item_from_shape, gsi::arg ("cell_id"), gsi::arg ("category_id"), gsi::arg ("trans"), gsi::arg ("shape"), gsi::arg ("with_properties", true),
|
||||
"@brief Creates a new item from a single shape\n"
|
||||
"This method produces an item from the given shape.\n"
|
||||
"It accepts various kind of shapes, such as texts, polygons, boxes and paths and "
|
||||
"converts them to a corresponding item. The transformation argument can be used to "
|
||||
"supply the transformation that applies the database unit for example.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.25.3.\n"
|
||||
"This method has been introduced in version 0.25.3. The 'with_properties' argument has been added in version 0.28.\n"
|
||||
"\n"
|
||||
"@param cell_id The ID of the cell to which the item is associated\n"
|
||||
"@param category_id The ID of the category to which the item is associated\n"
|
||||
"@param shape The shape to take the geometrical object from\n"
|
||||
"@param trans The transformation to apply\n"
|
||||
"@param with_properties If true, user properties will be turned into tagged values as well\n"
|
||||
) +
|
||||
gsi::method_ext ("create_items", &rdb::create_items_from_shapes, gsi::arg ("cell_id"), gsi::arg ("category_id"), gsi::arg ("trans"), gsi::arg ("shapes"),
|
||||
gsi::method_ext ("create_items", &rdb::create_items_from_shapes, gsi::arg ("cell_id"), gsi::arg ("category_id"), gsi::arg ("trans"), gsi::arg ("shapes"), gsi::arg ("with_properties", true),
|
||||
"@brief Creates new items from a shape container\n"
|
||||
"This method takes the shapes from the given container and produces items from them.\n"
|
||||
"It accepts various kind of shapes, such as texts, polygons, boxes and paths and "
|
||||
"converts them to corresponding items. The transformation argument can be used to "
|
||||
"supply the transformation that applies the database unit for example.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.25.3.\n"
|
||||
"This method has been introduced in version 0.25.3. The 'with_properties' argument has been added in version 0.28.\n"
|
||||
"\n"
|
||||
"@param cell_id The ID of the cell to which the item is associated\n"
|
||||
"@param category_id The ID of the category to which the item is associated\n"
|
||||
"@param shapes The shape container from which to take the items\n"
|
||||
"@param trans The transformation to apply\n"
|
||||
"@param with_properties If true, user properties will be turned into tagged values as well\n"
|
||||
) +
|
||||
gsi::method_ext ("create_items", &rdb::create_items_from_region, gsi::arg ("cell_id"), gsi::arg ("category_id"), gsi::arg ("trans"), gsi::arg ("region"),
|
||||
"@brief Creates new polygon items for the given cell/category combination\n"
|
||||
|
|
|
|||
|
|
@ -860,9 +860,11 @@ public:
|
|||
* @brief Add a value in a generic way
|
||||
*/
|
||||
template <class V>
|
||||
void add_value (const V &v)
|
||||
ValueBase *add_value (const V &v, id_type tag_id = 0)
|
||||
{
|
||||
values ().add (new Value<V> (v));
|
||||
ValueBase *value = new Value<V> (v);
|
||||
values ().add (value, tag_id);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ namespace rdb
|
|||
{
|
||||
|
||||
void
|
||||
scan_layer (rdb::Category *cat, const db::Layout &layout, unsigned int layer, const db::Cell *from, int levels)
|
||||
scan_layer (rdb::Category *cat, const db::Layout &layout, unsigned int layer, const db::Cell *from, int levels, bool with_properties)
|
||||
{
|
||||
rdb::Database *rdb = cat->database ();
|
||||
if (! rdb) {
|
||||
|
|
@ -78,7 +78,7 @@ scan_layer (rdb::Category *cat, const db::Layout &layout, unsigned int layer, co
|
|||
|
||||
}
|
||||
|
||||
create_items_from_shapes (rdb, rdb_cell->id (), cat->id (), db::CplxTrans (layout.dbu ()), cell.shapes (layer));
|
||||
create_items_from_shapes (rdb, rdb_cell->id (), cat->id (), db::CplxTrans (layout.dbu ()), cell.shapes (layer), with_properties);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -92,8 +92,8 @@ class CreateItemsRecursiveReceiver
|
|||
: public db::RecursiveShapeReceiver
|
||||
{
|
||||
public:
|
||||
CreateItemsRecursiveReceiver (rdb::Category *cat, const db::CplxTrans &trans, rdb::Cell *cell)
|
||||
: mp_cat (cat), mp_rdb (cat->database ()), m_trans (trans), mp_rdb_cell (cell)
|
||||
CreateItemsRecursiveReceiver (rdb::Category *cat, const db::CplxTrans &trans, rdb::Cell *cell, bool with_properties)
|
||||
: mp_cat (cat), mp_rdb (cat->database ()), m_trans (trans), mp_rdb_cell (cell), m_with_properties (with_properties)
|
||||
{
|
||||
// just in case the iterator is non-hierarchical
|
||||
if (cell) {
|
||||
|
|
@ -159,7 +159,7 @@ public:
|
|||
virtual void shape (const db::RecursiveShapeIterator * /*iter*/, const db::Shape &shape, const db::ICplxTrans & /*always_apply*/, const db::ICplxTrans & /*trans*/, const db::Box & /*region*/, const box_tree_type * /*complex_region*/)
|
||||
{
|
||||
tl_assert (! m_cell_stack.empty ());
|
||||
create_item_from_shape (mp_rdb, m_cell_stack.back ()->id (), mp_cat->id (), m_trans, shape);
|
||||
create_item_from_shape (mp_rdb, m_cell_stack.back ()->id (), mp_cat->id (), m_trans, shape, m_with_properties);
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
@ -169,6 +169,7 @@ public:
|
|||
std::map<db::cell_index_type, const rdb::Cell *> m_id_to_cell;
|
||||
db::CplxTrans m_trans;
|
||||
rdb::Cell *mp_rdb_cell;
|
||||
bool m_with_properties;
|
||||
|
||||
const rdb::Cell *cell_for_id (const db::Layout *layout, db::cell_index_type ci)
|
||||
{
|
||||
|
|
@ -187,8 +188,8 @@ class CreateItemsFlatReceiver
|
|||
: public db::RecursiveShapeReceiver
|
||||
{
|
||||
public:
|
||||
CreateItemsFlatReceiver (rdb::Category *cat, const db::CplxTrans &trans, rdb::Cell *cell)
|
||||
: mp_cat (cat), mp_rdb (cat->database ()), m_trans (trans), mp_rdb_cell (cell)
|
||||
CreateItemsFlatReceiver (rdb::Category *cat, const db::CplxTrans &trans, rdb::Cell *cell, bool with_properties)
|
||||
: mp_cat (cat), mp_rdb (cat->database ()), m_trans (trans), mp_rdb_cell (cell), m_with_properties (with_properties)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -211,7 +212,7 @@ public:
|
|||
|
||||
virtual void shape (const db::RecursiveShapeIterator * /*iter*/, const db::Shape &shape, const db::ICplxTrans & /*always_apply*/, const db::ICplxTrans &trans, const db::Box & /*region*/, const box_tree_type * /*complex_region*/)
|
||||
{
|
||||
create_item_from_shape (mp_rdb, mp_rdb_cell->id (), mp_cat->id (), m_trans * trans, shape);
|
||||
create_item_from_shape (mp_rdb, mp_rdb_cell->id (), mp_cat->id (), m_trans * trans, shape, m_with_properties);
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
@ -219,23 +220,24 @@ public:
|
|||
rdb::Database *mp_rdb;
|
||||
db::CplxTrans m_trans;
|
||||
const rdb::Cell *mp_rdb_cell;
|
||||
bool m_with_properties;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
scan_layer (rdb::Category *cat, const db::RecursiveShapeIterator &iter, bool flat)
|
||||
scan_layer (rdb::Category *cat, const db::RecursiveShapeIterator &iter, bool flat, bool with_properties)
|
||||
{
|
||||
if (! iter.top_cell () || ! iter.layout ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
db::CplxTrans trans (iter.layout ()->dbu ());
|
||||
scan_layer (cat, 0, trans, iter, flat);
|
||||
scan_layer (cat, 0, trans, iter, flat, with_properties);
|
||||
}
|
||||
|
||||
void
|
||||
scan_layer (rdb::Category *cat, rdb::Cell *cell, const db::CplxTrans &trans, const db::RecursiveShapeIterator &iter, bool flat)
|
||||
scan_layer (rdb::Category *cat, rdb::Cell *cell, const db::CplxTrans &trans, const db::RecursiveShapeIterator &iter, bool flat, bool with_properties)
|
||||
{
|
||||
if (! cat->database ()) {
|
||||
return;
|
||||
|
|
@ -243,9 +245,9 @@ scan_layer (rdb::Category *cat, rdb::Cell *cell, const db::CplxTrans &trans, con
|
|||
|
||||
std::unique_ptr<db::RecursiveShapeReceiver> rec;
|
||||
if (flat) {
|
||||
rec.reset (new CreateItemsFlatReceiver (cat, trans, cell));
|
||||
rec.reset (new CreateItemsFlatReceiver (cat, trans, cell, with_properties));
|
||||
} else {
|
||||
rec.reset (new CreateItemsRecursiveReceiver (cat, trans, cell));
|
||||
rec.reset (new CreateItemsRecursiveReceiver (cat, trans, cell, with_properties));
|
||||
}
|
||||
|
||||
db::RecursiveShapeIterator (iter).push (rec.get ());
|
||||
|
|
@ -253,37 +255,47 @@ scan_layer (rdb::Category *cat, rdb::Cell *cell, const db::CplxTrans &trans, con
|
|||
|
||||
// ------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void create_items_from_iterator (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id, const db::RecursiveShapeIterator &iter)
|
||||
void create_items_from_iterator (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id, const db::RecursiveShapeIterator &iter, bool with_properties)
|
||||
{
|
||||
tl_assert (iter.layout ());
|
||||
double dbu = iter.layout ()->dbu ();
|
||||
|
||||
for (db::RecursiveShapeIterator i = iter; !i.at_end (); ++i) {
|
||||
std::unique_ptr<rdb::ValueBase> value (rdb::ValueBase::create_from_shape (*i, db::CplxTrans (dbu) * i.trans ()));
|
||||
if (value.get ()) {
|
||||
rdb::Item *item = db->create_item (cell_id, cat_id);
|
||||
item->values ().add (value.release ());
|
||||
}
|
||||
create_item_from_shape (db, cell_id, cat_id, db::CplxTrans (dbu) * i.trans (), *i, with_properties);
|
||||
}
|
||||
}
|
||||
|
||||
void create_items_from_shapes (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id, const db::CplxTrans &trans, const db::Shapes &shapes)
|
||||
void create_items_from_shapes (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id, const db::CplxTrans &trans, const db::Shapes &shapes, bool with_properties)
|
||||
{
|
||||
for (db::Shapes::shape_iterator s = shapes.begin (db::ShapeIterator::All); !s.at_end (); ++s) {
|
||||
std::unique_ptr<rdb::ValueBase> value (rdb::ValueBase::create_from_shape (*s, trans));
|
||||
if (value.get ()) {
|
||||
rdb::Item *item = db->create_item (cell_id, cat_id);
|
||||
item->values ().add (value.release ());
|
||||
}
|
||||
create_item_from_shape (db, cell_id, cat_id, trans, *s, with_properties);
|
||||
}
|
||||
}
|
||||
|
||||
void create_item_from_shape (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id, const db::CplxTrans &trans, const db::Shape &shape)
|
||||
void create_item_from_shape (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id, const db::CplxTrans &trans, const db::Shape &shape, bool with_properties)
|
||||
{
|
||||
std::unique_ptr<rdb::ValueBase> value (rdb::ValueBase::create_from_shape (shape, trans));
|
||||
if (value.get ()) {
|
||||
rdb::Item *item = db->create_item (cell_id, cat_id);
|
||||
item->values ().add (value.release ());
|
||||
if (! value.get ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
rdb::Item *item = db->create_item (cell_id, cat_id);
|
||||
item->values ().add (value.release ());
|
||||
|
||||
// translate properties
|
||||
if (with_properties && shape.has_prop_id () && shape.shapes () && shape.shapes ()->cell ()) {
|
||||
|
||||
const db::Layout *layout = shape.shapes ()->cell ()->layout ();
|
||||
if (layout) {
|
||||
|
||||
auto ps = layout->properties_repository ().properties (shape.prop_id ());
|
||||
for (auto i = ps.begin (); i != ps.end (); ++i) {
|
||||
id_type tag_id = db->tags ().tag (layout->properties_repository ().prop_name (i->first).to_string (), true /*user tag*/).id ();
|
||||
add_item_value (item, i->second, trans, tag_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -317,50 +329,97 @@ void create_items_from_edge_pairs (rdb::Database *db, rdb::id_type cell_id, rdb:
|
|||
}
|
||||
}
|
||||
|
||||
void add_item_value (rdb::Item *item, const tl::Variant &v, double dbu)
|
||||
ValueBase *add_item_value (rdb::Item *item, const tl::Variant &v, const db::CplxTrans &trans, rdb::id_type tag_id)
|
||||
{
|
||||
if (dbu > 0 && v.is_user<db::Box> ()) {
|
||||
item->add_value (db::CplxTrans (dbu) * v.to_user<db::Box> ());
|
||||
} else if (dbu > 0 && v.is_user<db::Point> ()) {
|
||||
db::DPoint p = db::CplxTrans (dbu) * v.to_user<db::Point> ();
|
||||
item->add_value (db::DEdge (p, p));
|
||||
} else if (dbu > 0 && v.is_user<db::Polygon> ()) {
|
||||
item->add_value (db::CplxTrans (dbu) * v.to_user<db::Polygon> ());
|
||||
} else if (dbu > 0 && v.is_user<db::SimplePolygon> ()) {
|
||||
if (v.is_user<db::Box> ()) {
|
||||
return item->add_value (trans * v.to_user<db::Box> (), tag_id);
|
||||
} else if (v.is_user<db::Point> ()) {
|
||||
db::DPoint p = trans * v.to_user<db::Point> ();
|
||||
return item->add_value (db::DEdge (p, p), tag_id);
|
||||
} else if (v.is_user<db::Polygon> ()) {
|
||||
return item->add_value (trans * v.to_user<db::Polygon> (), tag_id);
|
||||
} else if (v.is_user<db::SimplePolygon> ()) {
|
||||
db::DPolygon p;
|
||||
db::DSimplePolygon sp = db::CplxTrans (dbu) * v.to_user<db::SimplePolygon> ();
|
||||
db::DSimplePolygon sp = trans * v.to_user<db::SimplePolygon> ();
|
||||
p.assign_hull (sp.begin_hull (), sp.end_hull ());
|
||||
item->add_value (p);
|
||||
} else if (dbu > 0 && v.is_user<db::Edge> ()) {
|
||||
item->add_value (db::CplxTrans (dbu) * v.to_user<db::Edge> ());
|
||||
} else if (dbu > 0 && v.is_user<db::EdgePair> ()) {
|
||||
item->add_value (db::CplxTrans (dbu) * v.to_user<db::EdgePair> ());
|
||||
} else if (dbu > 0 && v.is_user<db::Path> ()) {
|
||||
item->add_value (db::CplxTrans (dbu) * v.to_user<db::Path> ());
|
||||
} else if (dbu > 0 && v.is_user<db::Text> ()) {
|
||||
item->add_value (db::CplxTrans (dbu) * v.to_user<db::Text> ());
|
||||
return item->add_value (p, tag_id);
|
||||
} else if (v.is_user<db::Edge> ()) {
|
||||
return item->add_value (trans * v.to_user<db::Edge> (), tag_id);
|
||||
} else if (v.is_user<db::EdgePair> ()) {
|
||||
return item->add_value (trans * v.to_user<db::EdgePair> (), tag_id);
|
||||
} else if (v.is_user<db::Path> ()) {
|
||||
return item->add_value (trans * v.to_user<db::Path> (), tag_id);
|
||||
} else if (v.is_user<db::Text> ()) {
|
||||
return item->add_value (trans * v.to_user<db::Text> (), tag_id);
|
||||
} else if (v.is_user<db::DBox> ()) {
|
||||
item->add_value (v.to_user<db::DBox> ());
|
||||
return item->add_value (v.to_user<db::DBox> (), tag_id);
|
||||
} else if (v.is_user<db::DPoint> ()) {
|
||||
db::DPoint p = v.to_user<db::DPoint> ();
|
||||
item->add_value (db::DEdge (p, p));
|
||||
return item->add_value (db::DEdge (p, p), tag_id);
|
||||
} else if (v.is_user<db::DPolygon> ()) {
|
||||
item->add_value (v.to_user<db::DPolygon> ());
|
||||
return item->add_value (v.to_user<db::DPolygon> (), tag_id);
|
||||
} else if (v.is_user<db::DSimplePolygon> ()) {
|
||||
db::DPolygon p;
|
||||
db::DSimplePolygon sp = v.to_user<db::DSimplePolygon> ();
|
||||
p.assign_hull (sp.begin_hull (), sp.end_hull ());
|
||||
item->add_value (p);
|
||||
return item->add_value (p, tag_id);
|
||||
} else if (v.is_user<db::DEdge> ()) {
|
||||
item->add_value (v.to_user<db::DEdge> ());
|
||||
return item->add_value (v.to_user<db::DEdge> (), tag_id);
|
||||
} else if (v.is_user<db::DEdgePair> ()) {
|
||||
item->add_value (v.to_user<db::DEdgePair> ());
|
||||
return item->add_value (v.to_user<db::DEdgePair> (), tag_id);
|
||||
} else if (v.is_user<db::DPath> ()) {
|
||||
item->add_value (v.to_user<db::DPath> ());
|
||||
return item->add_value (v.to_user<db::DPath> (), tag_id);
|
||||
} else if (v.is_user<db::DText> ()) {
|
||||
item->add_value (v.to_user<db::DText> ());
|
||||
return item->add_value (v.to_user<db::DText> (), tag_id);
|
||||
} else {
|
||||
item->add_value (std::string (v.to_string ()));
|
||||
return item->add_value (std::string (v.to_string ()), tag_id);
|
||||
}
|
||||
}
|
||||
|
||||
ValueBase *add_item_value(rdb::Item *item, const tl::Variant &v, double dbu, rdb::id_type tag_id)
|
||||
{
|
||||
if (dbu > 0 && v.is_user<db::Box> ()) {
|
||||
return item->add_value (db::CplxTrans (dbu) * v.to_user<db::Box> (), tag_id);
|
||||
} else if (dbu > 0 && v.is_user<db::Point> ()) {
|
||||
db::DPoint p = db::CplxTrans (dbu) * v.to_user<db::Point> ();
|
||||
return item->add_value (db::DEdge (p, p), tag_id);
|
||||
} else if (dbu > 0 && v.is_user<db::Polygon> ()) {
|
||||
return item->add_value (db::CplxTrans (dbu) * v.to_user<db::Polygon> (), tag_id);
|
||||
} else if (dbu > 0 && v.is_user<db::SimplePolygon> ()) {
|
||||
db::DPolygon p;
|
||||
db::DSimplePolygon sp = db::CplxTrans (dbu) * v.to_user<db::SimplePolygon> ();
|
||||
p.assign_hull (sp.begin_hull (), sp.end_hull ());
|
||||
return item->add_value (p, tag_id);
|
||||
} else if (dbu > 0 && v.is_user<db::Edge> ()) {
|
||||
return item->add_value (db::CplxTrans (dbu) * v.to_user<db::Edge> (), tag_id);
|
||||
} else if (dbu > 0 && v.is_user<db::EdgePair> ()) {
|
||||
return item->add_value (db::CplxTrans (dbu) * v.to_user<db::EdgePair> (), tag_id);
|
||||
} else if (dbu > 0 && v.is_user<db::Path> ()) {
|
||||
return item->add_value (db::CplxTrans (dbu) * v.to_user<db::Path> (), tag_id);
|
||||
} else if (dbu > 0 && v.is_user<db::Text> ()) {
|
||||
return item->add_value (db::CplxTrans (dbu) * v.to_user<db::Text> (), tag_id);
|
||||
} else if (v.is_user<db::DBox> ()) {
|
||||
return item->add_value (v.to_user<db::DBox> (), tag_id);
|
||||
} else if (v.is_user<db::DPoint> ()) {
|
||||
db::DPoint p = v.to_user<db::DPoint> ();
|
||||
return item->add_value (db::DEdge (p, p), tag_id);
|
||||
} else if (v.is_user<db::DPolygon> ()) {
|
||||
return item->add_value (v.to_user<db::DPolygon> (), tag_id);
|
||||
} else if (v.is_user<db::DSimplePolygon> ()) {
|
||||
db::DPolygon p;
|
||||
db::DSimplePolygon sp = v.to_user<db::DSimplePolygon> ();
|
||||
p.assign_hull (sp.begin_hull (), sp.end_hull ());
|
||||
return item->add_value (p, tag_id);
|
||||
} else if (v.is_user<db::DEdge> ()) {
|
||||
return item->add_value (v.to_user<db::DEdge> (), tag_id);
|
||||
} else if (v.is_user<db::DEdgePair> ()) {
|
||||
return item->add_value (v.to_user<db::DEdgePair> (), tag_id);
|
||||
} else if (v.is_user<db::DPath> ()) {
|
||||
return item->add_value (v.to_user<db::DPath> (), tag_id);
|
||||
} else if (v.is_user<db::DText> ()) {
|
||||
return item->add_value (v.to_user<db::DText> (), tag_id);
|
||||
} else {
|
||||
return item->add_value (std::string (v.to_string ()), tag_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,45 +51,63 @@ namespace rdb
|
|||
*
|
||||
* If "from" is 0, all cells will be scanned. Levels are the number of hierarchy levels scanned if
|
||||
* "from" is given. -1 means "all levels".
|
||||
*
|
||||
* If "with_properties" is true, user properties are translated into values with tags corresponding
|
||||
* to the property names.
|
||||
*/
|
||||
RDB_PUBLIC void scan_layer (rdb::Category *cat, const db::Layout &layout, unsigned int layer, const db::Cell *from_cell = 0, int levels = -1);
|
||||
RDB_PUBLIC void scan_layer (rdb::Category *cat, const db::Layout &layout, unsigned int layer, const db::Cell *from_cell = 0, int levels = -1, bool with_properties = true);
|
||||
|
||||
/**
|
||||
* @brief Scans a recursive shape iterator into a RDB category
|
||||
*
|
||||
* If "with_properties" is true, user properties are translated into values with tags corresponding
|
||||
* to the property names.
|
||||
*/
|
||||
RDB_PUBLIC void scan_layer (rdb::Category *cat, const db::RecursiveShapeIterator &iter, bool flat = false);
|
||||
RDB_PUBLIC void scan_layer (rdb::Category *cat, const db::RecursiveShapeIterator &iter, bool flat = false, bool with_properties = true);
|
||||
|
||||
/**
|
||||
* @brief Scans a recursive shape iterator into a RDB category
|
||||
*
|
||||
* This version allows supplying a cell and a transformation. With this information, the function can also handle
|
||||
* pseudo-iterators which don't deliver the information from a layout from from a plain shape collection.
|
||||
*
|
||||
* If "with_properties" is true, user properties are translated into values with tags corresponding
|
||||
* to the property names.
|
||||
*/
|
||||
RDB_PUBLIC void scan_layer (rdb::Category *cat, rdb::Cell *cell, const db::CplxTrans &trans, const db::RecursiveShapeIterator &iter, bool flat = false);
|
||||
RDB_PUBLIC void scan_layer (rdb::Category *cat, rdb::Cell *cell, const db::CplxTrans &trans, const db::RecursiveShapeIterator &iter, bool flat = false, bool with_properties = true);
|
||||
|
||||
/**
|
||||
* @brief Creates RDB items from a recursive shape iterator
|
||||
*
|
||||
* This function will produce items from the flattened shape iterator. The items will be stored under
|
||||
* the given cell.
|
||||
*
|
||||
* If "with_properties" is true, user properties are translated into values with tags corresponding
|
||||
* to the property names.
|
||||
*/
|
||||
RDB_PUBLIC void create_items_from_iterator (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id, const db::RecursiveShapeIterator &iter);
|
||||
RDB_PUBLIC void create_items_from_iterator (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id, const db::RecursiveShapeIterator &iter, bool with_properties = true);
|
||||
|
||||
/**
|
||||
* @brief Creates RDB items from a shape collection
|
||||
*
|
||||
* An arbitrary transformation can be applied to translate the shapes before turning them to items.
|
||||
* This transformation is useful for providing the DBU-to-micron conversion.
|
||||
*
|
||||
* If "with_properties" is true, user properties are translated into values with tags corresponding
|
||||
* to the property names.
|
||||
*/
|
||||
RDB_PUBLIC void create_items_from_shapes (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id, const db::CplxTrans &trans, const db::Shapes &shapes);
|
||||
RDB_PUBLIC void create_items_from_shapes (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id, const db::CplxTrans &trans, const db::Shapes &shapes, bool with_properties = true);
|
||||
|
||||
/**
|
||||
* @brief Creates RDB items from a single shape
|
||||
*
|
||||
* An arbitrary transformation can be applied to translate the shapes before turning them to items.
|
||||
* This transformation is useful for providing the DBU-to-micron conversion.
|
||||
*
|
||||
* If "with_properties" is true, user properties are translated into values with tags corresponding
|
||||
* to the property names.
|
||||
*/
|
||||
RDB_PUBLIC void create_item_from_shape (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id, const db::CplxTrans &trans, const db::Shape &shape);
|
||||
RDB_PUBLIC void create_item_from_shape (rdb::Database *db, rdb::id_type cell_id, rdb::id_type cat_id, const db::CplxTrans &trans, const db::Shape &shape, bool with_properties = true);
|
||||
|
||||
/**
|
||||
* @brief Creates RDB items from a region
|
||||
|
|
@ -146,7 +164,14 @@ RDB_PUBLIC_TEMPLATE void create_items_from_sequence (rdb::Database *db, rdb::id_
|
|||
*
|
||||
* Unknown types are converted to strings.
|
||||
*/
|
||||
RDB_PUBLIC void add_item_value (rdb::Item *item, const tl::Variant &v, double dbu = 0.0);
|
||||
RDB_PUBLIC ValueBase *add_item_value (rdb::Item *item, const tl::Variant &v, double dbu = 0.0, rdb::id_type tag_id = 0);
|
||||
|
||||
/**
|
||||
* @brief Creates a value from a tl::Variant
|
||||
*
|
||||
* This version takes a db::CplxTrans for converting integer-unit geometry objects to micron-unit ones.
|
||||
*/
|
||||
RDB_PUBLIC ValueBase *add_item_value(rdb::Item *item, const tl::Variant &v, const db::CplxTrans &trans, rdb::id_type tag_id = 0);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue