WIP: property mapping between layouts

This commit is contained in:
Matthias Koefferlein 2023-01-15 11:56:41 +01:00
parent 311d9c6eb5
commit 33b5723068
45 changed files with 274 additions and 60 deletions

View File

@ -314,6 +314,11 @@ const db::RecursiveShapeIterator *DeepEdgePairs::iter () const
return 0;
}
const db::Layout *DeepEdgePairs::layout () const
{
return &deep_layer ().layout ();
}
EdgePairsDelegate *
DeepEdgePairs::add_in_place (const EdgePairs &other)
{

View File

@ -72,6 +72,7 @@ public:
virtual const db::EdgePair *nth (size_t n) const;
virtual bool has_valid_edge_pairs () const;
virtual const db::RecursiveShapeIterator *iter () const;
virtual const db::Layout *layout () const;
virtual EdgePairsDelegate *filter_in_place (const EdgePairFilterBase &filter);
virtual EdgePairsDelegate *filtered (const EdgePairFilterBase &) const;

View File

@ -448,6 +448,12 @@ DeepEdges::iter () const
return 0;
}
const db::Layout *
DeepEdges::layout () const
{
return &deep_layer ().layout ();
}
bool DeepEdges::equals (const Edges &other) const
{
const DeepEdges *other_delegate = dynamic_cast<const DeepEdges *> (other.delegate ());

View File

@ -80,6 +80,7 @@ public:
virtual bool has_valid_merged_edges () const;
virtual const db::RecursiveShapeIterator *iter () const;
virtual const db::Layout *layout () const;
virtual bool equals (const Edges &other) const;
virtual bool less (const Edges &other) const;

View File

@ -475,6 +475,12 @@ DeepRegion::iter () const
return 0;
}
const db::Layout *
DeepRegion::layout () const
{
return &deep_layer ().layout ();
}
bool
DeepRegion::equals (const Region &other) const
{

View File

@ -79,6 +79,7 @@ public:
virtual bool has_valid_merged_polygons () const;
virtual const db::RecursiveShapeIterator *iter () const;
virtual const db::Layout *layout () const;
virtual bool equals (const Region &other) const;
virtual bool less (const Region &other) const;

View File

@ -475,14 +475,15 @@ DeepLayer DeepShapeStore::create_from_flat (const db::Region &region, bool for_n
db::Shapes *shapes = &initial_cell ().shapes (layer);
db::Box world = db::Box::world ();
// The chain of operators for producing clipped and reduced polygon references
db::PolygonReferenceHierarchyBuilderShapeReceiver refs (&layout (), text_enlargement (), text_property_name ());
db::ReducingHierarchyBuilderShapeReceiver red (&refs, max_area_ratio, max_vertex_count, m_state.reject_odd_polygons ());
// try to maintain the texts on top level - go through shape iterator
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> ii = region.begin_iter ();
bool regard_props = ((ii.first.shape_flags () & db::ShapeIterator::RegardProperties) != 0);
db::ICplxTrans ttop = trans * ii.second;
// The chain of operators for producing clipped and reduced polygon references
db::PolygonReferenceHierarchyBuilderShapeReceiver refs (&layout (), ii.first.layout (), text_enlargement (), text_property_name ());
db::ReducingHierarchyBuilderShapeReceiver red (&refs, max_area_ratio, max_vertex_count, m_state.reject_odd_polygons ());
while (! ii.first.at_end ()) {
if (for_netlist && ii.first->is_text () && ii.first.layout () && ii.first.cell () != ii.first.top_cell ()) {
@ -516,11 +517,11 @@ DeepLayer DeepShapeStore::create_from_flat (const db::Edges &edges, const db::IC
db::Shapes *shapes = &initial_cell ().shapes (layer);
db::Box world = db::Box::world ();
db::EdgeBuildingHierarchyBuilderShapeReceiver eb (false);
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> ii = edges.begin_iter ();
bool regard_props = ((ii.first.shape_flags () & db::ShapeIterator::RegardProperties) != 0);
db::ICplxTrans ttop = trans * ii.second;
db::EdgeBuildingHierarchyBuilderShapeReceiver eb (&layout (), ii.first.layout (), false);
while (! ii.first.at_end ()) {
eb.push (*ii.first, regard_props ? ii.first->prop_id () : 0, ttop * ii.first.trans (), world, 0, shapes);
++ii.first;
@ -547,11 +548,12 @@ DeepLayer DeepShapeStore::create_from_flat (const db::Texts &texts, const db::IC
db::Shapes *shapes = &initial_cell ().shapes (layer);
db::Box world = db::Box::world ();
db::TextBuildingHierarchyBuilderShapeReceiver tb (&layout ());
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> ii = texts.begin_iter ();
bool regard_props = ((ii.first.shape_flags () & db::ShapeIterator::RegardProperties) != 0);
db::ICplxTrans ttop = trans * ii.second;
db::TextBuildingHierarchyBuilderShapeReceiver tb (&layout (), ii.first.layout ());
while (! ii.first.at_end ()) {
tb.push (*ii.first, regard_props ? ii.first->prop_id () : 0, ttop * ii.first.trans (), world, 0, shapes);
++ii.first;
@ -839,7 +841,7 @@ DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator
builder.set_target_layer (layer_index);
// The chain of operators for producing clipped and reduced polygon references
db::PolygonReferenceHierarchyBuilderShapeReceiver refs (& layout, text_enlargement (), text_property_name ());
db::PolygonReferenceHierarchyBuilderShapeReceiver refs (&layout, si.layout (), text_enlargement (), text_property_name ());
db::ReducingHierarchyBuilderShapeReceiver red (&refs, max_area_ratio, max_vertex_count, m_state.reject_odd_polygons ());
db::ClippingHierarchyBuilderShapeReceiver clip (&red);
@ -917,13 +919,19 @@ DeepLayer DeepShapeStore::create_copy (const DeepLayer &source, HierarchyBuilder
DeepLayer DeepShapeStore::create_edge_layer (const db::RecursiveShapeIterator &si, bool as_edges, const db::ICplxTrans &trans)
{
db::EdgeBuildingHierarchyBuilderShapeReceiver refs (as_edges);
unsigned int layout_index = layout_for_iter (si, trans);
db::Layout &layout = m_layouts[layout_index]->layout;
db::EdgeBuildingHierarchyBuilderShapeReceiver refs (&layout, si.layout (), as_edges);
return create_custom_layer (si, &refs, trans);
}
DeepLayer DeepShapeStore::create_edge_pair_layer (const db::RecursiveShapeIterator &si, const db::ICplxTrans &trans)
{
db::EdgePairBuildingHierarchyBuilderShapeReceiver refs;
unsigned int layout_index = layout_for_iter (si, trans);
db::Layout &layout = m_layouts[layout_index]->layout;
db::EdgePairBuildingHierarchyBuilderShapeReceiver refs (&layout, si.layout ());
return create_custom_layer (si, &refs, trans);
}
@ -932,7 +940,7 @@ DeepLayer DeepShapeStore::create_text_layer (const db::RecursiveShapeIterator &s
unsigned int layout_index = layout_for_iter (si, trans);
db::Layout &layout = m_layouts[layout_index]->layout;
db::TextBuildingHierarchyBuilderShapeReceiver refs (&layout);
db::TextBuildingHierarchyBuilderShapeReceiver refs (&layout, si.layout ());
return create_custom_layer (si, &refs, trans);
}

View File

@ -338,6 +338,11 @@ const db::RecursiveShapeIterator *DeepTexts::iter () const
return 0;
}
const db::Layout *DeepTexts::layout () const
{
return &deep_layer ().layout ();
}
TextsDelegate *
DeepTexts::add_in_place (const Texts &other)
{

View File

@ -73,6 +73,7 @@ public:
virtual const db::Text *nth (size_t n) const;
virtual bool has_valid_texts () const;
virtual const db::RecursiveShapeIterator *iter () const;
virtual const db::Layout *layout () const;
virtual TextsDelegate *filter_in_place (const TextFilterBase &filter);
virtual TextsDelegate *filtered (const TextFilterBase &) const;

View File

@ -149,10 +149,16 @@ const db::RecursiveShapeIterator &
EdgePairs::iter () const
{
static db::RecursiveShapeIterator def_iter;
const db::RecursiveShapeIterator *i = mp_delegate->iter ();
const db::RecursiveShapeIterator *i = mp_delegate ? mp_delegate->iter () : 0;
return *(i ? i : &def_iter);
}
const db::Layout *
EdgePairs::layout () const
{
return mp_delegate ? mp_delegate->layout () : 0;
}
void EdgePairs::processed (Region &output, const EdgePairToPolygonProcessorBase &filter) const
{
output = Region (mp_delegate->processed_to_polygons (filter));

View File

@ -498,6 +498,14 @@ public:
*/
const db::RecursiveShapeIterator &iter () const;
/**
* @brief Gets the source layout for the polygons
*
* Use this layout to decode property IDs. This layout may be null, in which case the
* source layout is outside the scope of this region.
*/
const db::Layout *layout () const;
/**
* @brief Equality
*/

View File

@ -205,6 +205,7 @@ public:
virtual bool has_valid_edge_pairs () const = 0;
virtual const db::RecursiveShapeIterator *iter () const = 0;
virtual const db::Layout *layout () const = 0;
virtual bool equals (const EdgePairs &other) const = 0;
virtual bool less (const EdgePairs &other) const = 0;

View File

@ -108,10 +108,16 @@ const db::RecursiveShapeIterator &
Edges::iter () const
{
static db::RecursiveShapeIterator def_iter;
const db::RecursiveShapeIterator *i = mp_delegate->iter ();
const db::RecursiveShapeIterator *i = mp_delegate ? mp_delegate->iter () : 0;
return *(i ? i : &def_iter);
}
const db::Layout *
Edges::layout () const
{
return mp_delegate ? mp_delegate->layout () : 0;
}
void
Edges::set_delegate (EdgesDelegate *delegate, bool keep_attributes)
{

View File

@ -1470,6 +1470,14 @@ public:
*/
const db::RecursiveShapeIterator &iter () const;
/**
* @brief Gets the source layout for the polygons
*
* Use this layout to decode property IDs. This layout may be null, in which case the
* source layout is outside the scope of this region.
*/
const db::Layout *layout () const;
/**
* @brief Equality
*/

View File

@ -340,6 +340,7 @@ public:
virtual bool has_valid_merged_edges () const = 0;
virtual const db::RecursiveShapeIterator *iter () const = 0;
virtual const db::Layout *layout () const = 0;
virtual bool equals (const Edges &other) const = 0;
virtual bool less (const Edges &other) const = 0;

View File

@ -73,6 +73,7 @@ public:
virtual bool has_valid_edge_pairs () const { return true; }
virtual const db::RecursiveShapeIterator *iter () const { return 0; }
virtual const db::Layout *layout () const { return 0; }
virtual bool equals (const EdgePairs &other) const;
virtual bool less (const EdgePairs &other) const;

View File

@ -122,6 +122,7 @@ public:
virtual bool has_valid_merged_edges () const { return true; }
virtual const db::RecursiveShapeIterator *iter () const { return 0; }
virtual const db::Layout *layout () const { return 0; }
virtual bool equals (const Edges &other) const;
virtual bool less (const Edges &other) const;

View File

@ -141,6 +141,7 @@ public:
virtual db::properties_id_type nth_prop_id (size_t) const { tl_assert (false); }
virtual const db::RecursiveShapeIterator *iter () const { return 0; }
virtual const db::Layout *layout () const { return 0; }
virtual bool equals (const Region &other) const;
virtual bool less (const Region &other) const;

View File

@ -71,6 +71,7 @@ public:
virtual bool has_valid_texts () const { return true; }
virtual const db::RecursiveShapeIterator *iter () const { return 0; }
virtual const db::Layout *layout () const { return 0; }
virtual bool equals (const Texts &other) const;
virtual bool less (const Texts &other) const;

View File

@ -188,6 +188,11 @@ const db::RecursiveShapeIterator *FlatEdgePairs::iter () const
return 0;
}
const db::Layout *FlatEdgePairs::layout () const
{
return 0;
}
void
FlatEdgePairs::insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const
{

View File

@ -78,6 +78,7 @@ public:
virtual bool has_valid_edge_pairs () const;
virtual const db::RecursiveShapeIterator *iter () const;
virtual const db::Layout *layout () const;
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const;
virtual void insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const;

View File

@ -318,6 +318,11 @@ const db::RecursiveShapeIterator *FlatEdges::iter () const
return 0;
}
const db::Layout *FlatEdges::layout () const
{
return 0;
}
void
FlatEdges::do_insert (const db::Edge &edge)
{

View File

@ -91,6 +91,7 @@ public:
virtual bool has_valid_merged_edges () const;
virtual const db::RecursiveShapeIterator *iter () const;
virtual const db::Layout *layout () const;
void do_insert (const db::Edge &edge);

View File

@ -397,6 +397,11 @@ const db::RecursiveShapeIterator *FlatRegion::iter () const
return 0;
}
const db::Layout *FlatRegion::layout () const
{
return 0;
}
void FlatRegion::insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
{
layout->cell (into_cell).shapes (into_layer).insert (*mp_polygons);

View File

@ -97,6 +97,7 @@ public:
virtual bool has_valid_merged_polygons () const;
virtual const db::RecursiveShapeIterator *iter () const;
virtual const db::Layout *layout () const;
void do_insert (const db::Polygon &polygon, db::properties_id_type prop_id);

View File

@ -188,6 +188,11 @@ const db::RecursiveShapeIterator *FlatTexts::iter () const
return 0;
}
const db::Layout *FlatTexts::layout () const
{
return 0;
}
void
FlatTexts::insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const
{

View File

@ -79,6 +79,7 @@ public:
virtual bool has_valid_texts () const;
virtual const db::RecursiveShapeIterator *iter () const;
virtual const db::Layout *layout () const;
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const;
virtual void insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const;

View File

@ -634,13 +634,28 @@ ReducingHierarchyBuilderShapeReceiver::reduce (const db::Polygon &poly, db::prop
// ---------------------------------------------------------------------------------------------
PolygonReferenceHierarchyBuilderShapeReceiver::PolygonReferenceHierarchyBuilderShapeReceiver (db::Layout *layout, int text_enlargement, const tl::Variant &text_prop_name)
PolygonReferenceHierarchyBuilderShapeReceiver::PolygonReferenceHierarchyBuilderShapeReceiver (db::Layout *layout, const db::Layout *source_layout, int text_enlargement, const tl::Variant &text_prop_name)
: mp_layout (layout), m_text_enlargement (text_enlargement), m_make_text_prop (false), m_text_prop_id (0)
{
if (! text_prop_name.is_nil ()) {
m_text_prop_id = layout->properties_repository ().prop_name_id (text_prop_name);
m_make_text_prop = true;
}
if (source_layout && source_layout != layout) {
m_pm.set_source (*source_layout);
m_pm.set_target (*layout);
}
}
void PolygonReferenceHierarchyBuilderShapeReceiver::make_pref (db::Shapes *target, const db::Polygon &poly, db::properties_id_type prop_id)
{
prop_id = m_pm (prop_id);
if (prop_id != 0) {
target->insert (db::PolygonRefWithProperties (db::PolygonRef (poly, mp_layout->shape_repository ()), prop_id));
} else {
target->insert (db::PolygonRef (poly, mp_layout->shape_repository ()));
}
}
void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Shape &shape, db::properties_id_type prop_id, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
@ -656,36 +671,37 @@ void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Shape &shape
// NOTE: as this is a specialized receiver for the purpose of building region
// representations we don't need empty polygons here
if (poly.area2 () > 0) {
if (prop_id != 0) {
target->insert (db::PolygonRefWithProperties (db::PolygonRef (poly, mp_layout->shape_repository ()), prop_id));
} else {
target->insert (db::PolygonRef (poly, mp_layout->shape_repository ()));
}
make_pref (target, poly, prop_id);
}
} else if (shape.is_text () && m_text_enlargement >= 0) {
// Texts generate small marker shapes with text_enlargement defining the box
db::Polygon poly (shape.text_trans () * db::Box (-m_text_enlargement, -m_text_enlargement, m_text_enlargement, m_text_enlargement));
if (! trans.is_unity ()) {
poly.transform (trans);
}
db::PolygonRef pref (poly, mp_layout->shape_repository ());
db::properties_id_type pid;
if (m_make_text_prop) {
// NOTE: text properties override the prop_id passed down from the hierarchy builder when generating the
// text marker shape
db::PropertiesRepository::properties_set ps;
ps.insert (std::make_pair (m_text_prop_id, tl::Variant (shape.text_string ())));
db::properties_id_type pid = mp_layout->properties_repository ().properties_id (ps);
target->insert (db::PolygonRefWithProperties (pref, pid));
pid = mp_layout->properties_repository ().properties_id (ps);
} else {
pid = m_pm (prop_id);
}
if (prop_id != 0) {
target->insert (db::PolygonRefWithProperties (pref, prop_id));
} else {
target->insert (pref);
}
if (pid != 0) {
target->insert (db::PolygonRefWithProperties (pref, pid));
} else {
target->insert (pref);
}
}
@ -694,31 +710,26 @@ void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Shape &shape
void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Box &shape, db::properties_id_type prop_id, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
{
if (shape.area () > 0) {
if (prop_id != 0) {
target->insert (db::PolygonRefWithProperties (db::PolygonRef (db::Polygon (shape.transformed (trans)), mp_layout->shape_repository ()), prop_id));
} else {
target->insert (db::PolygonRef (db::Polygon (shape.transformed (trans)), mp_layout->shape_repository ()));
}
make_pref (target, db::Polygon (shape).transformed (trans), prop_id);
}
}
void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Polygon &shape, properties_id_type prop_id, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
{
if (shape.area2 () > 0) {
if (prop_id != 0) {
target->insert (db::PolygonRefWithProperties (db::PolygonRef (shape.transformed (trans), mp_layout->shape_repository ()), prop_id));
} else {
target->insert (db::PolygonRef (shape.transformed (trans), mp_layout->shape_repository ()));
}
make_pref (target, shape.transformed (trans), prop_id);
}
}
// ---------------------------------------------------------------------------------------------
EdgeBuildingHierarchyBuilderShapeReceiver::EdgeBuildingHierarchyBuilderShapeReceiver (bool as_edges)
EdgeBuildingHierarchyBuilderShapeReceiver::EdgeBuildingHierarchyBuilderShapeReceiver (db::Layout *layout, const db::Layout *source_layout, bool as_edges)
: m_as_edges (as_edges)
{
// .. nothing yet ..
if (source_layout && source_layout != layout) {
m_pm.set_source (*source_layout);
m_pm.set_target (*layout);
}
}
void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, db::properties_id_type prop_id, const db::ICplxTrans &trans, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target)
@ -730,6 +741,7 @@ void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, db
} else if (m_as_edges && shape.is_box ()) {
push (shape.box (), prop_id, trans, region, complex_region, target);
} else if (shape.is_edge ()) {
prop_id = m_pm (prop_id);
if (prop_id != 0) {
target->insert (db::EdgeWithProperties (shape.edge (), shape.prop_id ()));
} else {
@ -741,6 +753,7 @@ void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, db
void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Box &box, db::properties_id_type prop_id, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
{
if (m_as_edges && ! box.empty ()) {
prop_id = m_pm (prop_id);
if (prop_id != 0) {
target->insert (db::EdgeWithProperties (db::Edge (box.p1 (), box.upper_left ()).transformed (trans), prop_id));
target->insert (db::EdgeWithProperties (db::Edge (box.upper_left (), box.p2 ()).transformed (trans), prop_id));
@ -758,6 +771,7 @@ void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Box &box, db::pr
void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Polygon &poly, db::properties_id_type prop_id, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
{
if (m_as_edges) {
prop_id = m_pm (prop_id);
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
if (prop_id != 0) {
target->insert (db::EdgeWithProperties ((*e).transformed (trans), prop_id));
@ -770,14 +784,18 @@ void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Polygon &poly, d
// ---------------------------------------------------------------------------------------------
EdgePairBuildingHierarchyBuilderShapeReceiver::EdgePairBuildingHierarchyBuilderShapeReceiver ()
EdgePairBuildingHierarchyBuilderShapeReceiver::EdgePairBuildingHierarchyBuilderShapeReceiver (db::Layout *layout, const db::Layout *source_layout)
{
// .. nothing yet ..
if (source_layout && source_layout != layout) {
m_pm.set_source (*source_layout);
m_pm.set_target (*layout);
}
}
void EdgePairBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, db::properties_id_type prop_id, const db::ICplxTrans &trans, const db::Box & /*region*/, const db::RecursiveShapeReceiver::box_tree_type * /*complex_region*/, db::Shapes *target)
{
if (shape.is_edge_pair ()) {
prop_id = m_pm (prop_id);
if (prop_id != 0) {
target->insert (db::EdgePairWithProperties (shape.edge_pair ().transformed (trans), prop_id));
} else {
@ -788,10 +806,13 @@ void EdgePairBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape
// ---------------------------------------------------------------------------------------------
TextBuildingHierarchyBuilderShapeReceiver::TextBuildingHierarchyBuilderShapeReceiver (db::Layout *layout)
TextBuildingHierarchyBuilderShapeReceiver::TextBuildingHierarchyBuilderShapeReceiver (db::Layout *layout, const db::Layout *source_layout)
: mp_layout (layout)
{
// .. nothing yet ..
if (source_layout && source_layout != layout) {
m_pm.set_source (*source_layout);
m_pm.set_target (*layout);
}
}
void TextBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, db::properties_id_type prop_id, const db::ICplxTrans &trans, const db::Box & /*region*/, const db::RecursiveShapeReceiver::box_tree_type * /*complex_region*/, db::Shapes *target)
@ -800,6 +821,7 @@ void TextBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, db
// NOTE: we intentionally skip all the text attributes (font etc.) here because in the context
// of a text collections we're only interested in the locations.
db::Text t (shape.text_string (), shape.text_trans ());
prop_id = m_pm (prop_id);
if (prop_id != 0) {
target->insert (db::TextRefWithProperties (db::TextRef (t.transformed (trans), mp_layout->shape_repository ()), prop_id));
} else {

View File

@ -27,6 +27,7 @@
#include "dbRecursiveShapeIterator.h"
#include "dbLayout.h"
#include "dbLayoutUtils.h"
#include <map>
#include <vector>
@ -163,17 +164,20 @@ class DB_PUBLIC PolygonReferenceHierarchyBuilderShapeReceiver
: public HierarchyBuilderShapeReceiver
{
public:
PolygonReferenceHierarchyBuilderShapeReceiver (db::Layout *layout, int text_enlargement = -1, const tl::Variant &text_prop_name = tl::Variant ());
PolygonReferenceHierarchyBuilderShapeReceiver (db::Layout *layout, const Layout *source_layout, int text_enlargement = -1, const tl::Variant &text_prop_name = tl::Variant ());
virtual void push (const db::Shape &shape, properties_id_type prop_id, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Shape &shape, db::properties_id_type prop_id, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Box &shape, db::properties_id_type prop_id, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Polygon &shape, db::properties_id_type prop_id, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
private:
void make_pref (db::Shapes *target, const db::Polygon &polygon, db::properties_id_type prop_id);
db::Layout *mp_layout;
int m_text_enlargement;
bool m_make_text_prop;
db::property_names_id_type m_text_prop_id;
db::PropertyMapper m_pm;
};
/**
@ -183,7 +187,7 @@ class DB_PUBLIC EdgeBuildingHierarchyBuilderShapeReceiver
: public HierarchyBuilderShapeReceiver
{
public:
EdgeBuildingHierarchyBuilderShapeReceiver (bool as_edges);
EdgeBuildingHierarchyBuilderShapeReceiver (db::Layout *layout, const Layout *source_layout, bool as_edges);
virtual void push (const db::Shape &shape, properties_id_type prop_id, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Box &shape, db::properties_id_type prop_id, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
@ -191,6 +195,7 @@ public:
private:
bool m_as_edges;
db::PropertyMapper m_pm;
};
/**
@ -200,11 +205,14 @@ class DB_PUBLIC EdgePairBuildingHierarchyBuilderShapeReceiver
: public HierarchyBuilderShapeReceiver
{
public:
EdgePairBuildingHierarchyBuilderShapeReceiver ();
EdgePairBuildingHierarchyBuilderShapeReceiver (db::Layout *layout, const Layout *source_layout);
virtual void push (const db::Shape &shape, properties_id_type prop_id, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Box &, db::properties_id_type, const db::ICplxTrans &, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *) { }
virtual void push (const db::Polygon &, db::properties_id_type, const db::ICplxTrans &, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *) { }
private:
db::PropertyMapper m_pm;
};
/**
@ -214,7 +222,7 @@ class DB_PUBLIC TextBuildingHierarchyBuilderShapeReceiver
: public HierarchyBuilderShapeReceiver
{
public:
TextBuildingHierarchyBuilderShapeReceiver (db::Layout *layout);
TextBuildingHierarchyBuilderShapeReceiver (db::Layout *layout, const Layout *source_layout);
virtual void push (const db::Shape &shape, properties_id_type prop_id, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Box &, db::properties_id_type, const db::ICplxTrans &, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *) { }
@ -222,6 +230,7 @@ public:
private:
db::Layout *mp_layout;
db::PropertyMapper m_pm;
};
/**

View File

@ -202,6 +202,12 @@ OriginalLayerEdgePairs::iter () const
return &m_iter;
}
const db::Layout *
OriginalLayerEdgePairs::layout () const
{
return m_iter.layout ();
}
bool
OriginalLayerEdgePairs::equals (const EdgePairs &other) const
{

View File

@ -56,6 +56,7 @@ public:
virtual bool has_valid_edge_pairs () const;
virtual const db::RecursiveShapeIterator *iter () const;
virtual const db::Layout *layout () const;
virtual bool equals (const EdgePairs &other) const;
virtual bool less (const EdgePairs &other) const;

View File

@ -251,6 +251,12 @@ OriginalLayerEdges::iter () const
return &m_iter;
}
const db::Layout *
OriginalLayerEdges::layout () const
{
return m_iter.layout ();
}
bool
OriginalLayerEdges::equals (const Edges &other) const
{

View File

@ -62,6 +62,7 @@ public:
virtual bool has_valid_merged_edges () const;
virtual const db::RecursiveShapeIterator *iter () const;
virtual const db::Layout *layout () const;
virtual bool equals (const Edges &other) const;
virtual bool less (const Edges &other) const;

View File

@ -369,6 +369,12 @@ OriginalLayerRegion::iter () const
return &m_iter;
}
const db::Layout *
OriginalLayerRegion::layout () const
{
return m_iter.layout ();
}
bool
OriginalLayerRegion::equals (const Region &other) const
{

View File

@ -67,6 +67,7 @@ public:
virtual bool has_valid_merged_polygons () const;
virtual const db::RecursiveShapeIterator *iter () const;
virtual const db::Layout *layout () const;
virtual bool equals (const Region &other) const;
virtual bool less (const Region &other) const;

View File

@ -202,6 +202,12 @@ OriginalLayerTexts::iter () const
return &m_iter;
}
const db::Layout *
OriginalLayerTexts::layout () const
{
return m_iter.layout ();
}
bool
OriginalLayerTexts::equals (const Texts &other) const
{

View File

@ -56,6 +56,7 @@ public:
virtual bool has_valid_texts () const;
virtual const db::RecursiveShapeIterator *iter () const;
virtual const db::Layout *layout () const;
virtual bool equals (const Texts &other) const;
virtual bool less (const Texts &other) const;

View File

@ -105,10 +105,16 @@ const db::RecursiveShapeIterator &
Region::iter () const
{
static db::RecursiveShapeIterator def_iter;
const db::RecursiveShapeIterator *i = mp_delegate->iter ();
const db::RecursiveShapeIterator *i = mp_delegate ? mp_delegate->iter () : 0;
return *(i ? i : &def_iter);
}
const db::Layout *
Region::layout () const
{
return mp_delegate ? mp_delegate->layout () : 0;
}
void
Region::set_delegate (RegionDelegate *delegate, bool keep_attributes)
{

View File

@ -1756,6 +1756,14 @@ public:
*/
const db::RecursiveShapeIterator &iter () const;
/**
* @brief Gets the source layout for the polygons
*
* Use this layout to decode property IDs. This layout may be null, in which case the
* source layout is outside the scope of this region.
*/
const db::Layout *layout () const;
/**
* @brief Equality
*/

View File

@ -316,6 +316,7 @@ public:
virtual bool has_valid_merged_polygons () const = 0;
virtual const db::RecursiveShapeIterator *iter () const = 0;
virtual const db::Layout *layout () const = 0;
virtual bool equals (const Region &other) const = 0;
virtual bool less (const Region &other) const = 0;

View File

@ -146,10 +146,16 @@ const db::RecursiveShapeIterator &
Texts::iter () const
{
static db::RecursiveShapeIterator def_iter;
const db::RecursiveShapeIterator *i = mp_delegate->iter ();
const db::RecursiveShapeIterator *i = mp_delegate ? mp_delegate->iter () : 0;
return *(i ? i : &def_iter);
}
const db::Layout *
Texts::layout () const
{
return mp_delegate ? mp_delegate->layout () : 0;
}
void Texts::polygons (Region &output, db::Coord e) const
{
output.set_delegate (mp_delegate->polygons (e));

View File

@ -524,6 +524,14 @@ public:
*/
const db::RecursiveShapeIterator &iter () const;
/**
* @brief Gets the source layout for the polygons
*
* Use this layout to decode property IDs. This layout may be null, in which case the
* source layout is outside the scope of this region.
*/
const db::Layout *layout () const;
/**
* @brief Equality
*/

View File

@ -102,6 +102,7 @@ public:
virtual bool has_valid_texts () const = 0;
virtual const db::RecursiveShapeIterator *iter () const = 0;
virtual const db::Layout *layout () const = 0;
virtual bool equals (const Texts &other) const = 0;
virtual bool less (const Texts &other) const = 0;

View File

@ -220,7 +220,7 @@ TEST(2_WithClipAndRefGeneration)
}
db::Layout target;
db::PolygonReferenceHierarchyBuilderShapeReceiver ref(&target);
db::PolygonReferenceHierarchyBuilderShapeReceiver ref(&target, 0);
db::ClippingHierarchyBuilderShapeReceiver clip(&ref);
db::HierarchyBuilder builder (&target, db::ICplxTrans (), &clip);
@ -259,7 +259,7 @@ TEST(2_WithEmptyResult)
}
db::Layout target;
db::PolygonReferenceHierarchyBuilderShapeReceiver ref(&target);
db::PolygonReferenceHierarchyBuilderShapeReceiver ref(&target, 0);
db::ClippingHierarchyBuilderShapeReceiver clip(&ref);
db::HierarchyBuilder builder (&target, db::ICplxTrans (), &clip);

View File

@ -2254,19 +2254,52 @@ TEST(52_PropertiesDeep)
EXPECT_EQ (s.at_end (), true);
}
// TODO: should go somewhere central
static std::string prop2string (const db::Layout *layout, db::properties_id_type prop_id)
{
if (! layout) {
return std::string ("(no layout)");
}
const db::PropertiesRepository::properties_set &ps = layout->properties_repository ().properties (prop_id);
std::string res;
for (auto i = ps.begin (); i != ps.end (); ++i) {
if (i != ps.begin ()) {
res += "\n";
}
res += layout->properties_repository ().prop_name (i->first).to_string ();
res += "=";
res += i->second.to_string ();
}
return res;
}
TEST(53_PropertiesDeepFromLayout)
{
db::DeepShapeStore dss ("TOP", 0.001);
db::DeepShapeStore dss;
db::Layout ly;
unsigned int li = ly.insert_layer ();
db::Cell &top = ly.cell (ly.add_cell ("TOP"));
tl::Variant pname ("VALUE");
db::property_names_id_type pname_id = ly.properties_repository ().prop_name_id (pname);
db::PropertiesRepository::properties_set ps42;
ps42.insert (std::make_pair (pname_id, tl::Variant (42)));
db::properties_id_type pid42 = ly.properties_repository ().properties_id (ps42);
db::PropertiesRepository::properties_set ps1;
ps1.insert (std::make_pair (pname_id, tl::Variant (1)));
db::properties_id_type pid1 = ly.properties_repository ().properties_id (ps1);
db::Shapes &si = top.shapes (li);
si.insert (db::Box (0, 0, 100, 200));
si.insert (db::BoxWithProperties (db::Box (1, 2, 101, 202), 1));
si.insert (db::BoxWithProperties (db::Box (1, 2, 101, 202), pid1));
si.insert (db::Box (10, 20, 110, 220));
si.insert (db::BoxWithProperties (db::Box (11, 12, 111, 212), 42));
si.insert (db::BoxWithProperties (db::Box (11, 12, 111, 212), pid42));
// NOTE: without specific "property only" selector -> properties are ignored.
@ -2344,11 +2377,11 @@ TEST(53_PropertiesDeepFromLayout)
EXPECT_EQ (s->to_string (), "(10,20;10,220;110,220;110,20)");
++s;
EXPECT_EQ (s.at_end (), false);
EXPECT_EQ (s.prop_id (), db::properties_id_type (1));
EXPECT_EQ (prop2string (r.layout (), s.prop_id ()), "VALUE=1");
EXPECT_EQ (s->to_string (), "(1,2;1,202;101,202;101,2)");
++s;
EXPECT_EQ (s.at_end (), false);
EXPECT_EQ (s.prop_id (), db::properties_id_type (42));
EXPECT_EQ (prop2string (r.layout (), s.prop_id ()), "VALUE=42");
EXPECT_EQ (s->to_string (), "(11,12;11,212;111,212;111,12)");
++s;
EXPECT_EQ (s.at_end (), true);
@ -2361,13 +2394,13 @@ TEST(53_PropertiesDeepFromLayout)
++s;
EXPECT_EQ (s.at_end (), false);
EXPECT_EQ (s.prop_id (), db::properties_id_type (1));
EXPECT_EQ (prop2string (r.layout (), s.prop_id ()), "VALUE=1");
// a single property #1 element
EXPECT_EQ (s->to_string (), "(1,2;1,202;101,202;101,2)");
++s;
EXPECT_EQ (s.at_end (), false);
EXPECT_EQ (s.prop_id (), db::properties_id_type (42));
EXPECT_EQ (prop2string (r.layout (), s.prop_id ()), "VALUE=42");
// a single property #42 element
EXPECT_EQ (s->to_string (), "(11,12;11,212;111,212;111,12)");
++s;