WIP: refactoring, preparing polygon-to-edge with properties

This commit is contained in:
Matthias Koefferlein 2023-01-17 17:08:36 +01:00
parent f0e20ad258
commit 8fb4e36809
19 changed files with 415 additions and 177 deletions

View File

@ -266,10 +266,7 @@ void AsIfFlatRegion::invalidate_bbox ()
void AsIfFlatRegion::merge_polygons_to (db::Shapes &output, bool min_coherence, unsigned int min_wc, db::PropertiesRepository *target_rp) const
{
db::PropertyMapper pm;
if (target_rp && properties_repository ()) {
pm = db::PropertyMapper (*target_rp, *properties_repository ());
}
db::PropertyMapper pm (target_rp, properties_repository ());
db::EdgeProcessor ep (report_progress (), progress_desc ());
ep.set_base_verbosity (base_verbosity ());

View File

@ -766,7 +766,7 @@ Cell::copy_shapes (const db::Cell &source_cell, const db::LayerMapping &layer_ma
}
if (target_layout != source_layout) {
db::PropertyMapper pm (*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);
@ -915,7 +915,7 @@ Cell::move_shapes (db::Cell &source_cell, const db::LayerMapping &layer_mapping)
}
if (target_layout != source_layout) {
db::PropertyMapper pm (*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);
@ -988,7 +988,7 @@ Cell::move_tree (db::Cell &source_cell)
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
}
db::PropertyMapper pm (*target_layout, *source_layout);
db::PropertyMapper pm (target_layout, source_layout);
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
db::CellMapping cm;
@ -1022,7 +1022,7 @@ Cell::move_tree_shapes (db::Cell &source_cell, const db::CellMapping &cm)
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
}
db::PropertyMapper pm (*target_layout, *source_layout);
db::PropertyMapper pm (target_layout, source_layout);
db::ICplxTrans trans (source_layout->dbu () / target_layout->dbu ());
db::LayerMapping lm;
@ -1049,7 +1049,7 @@ Cell::move_tree_shapes (db::Cell &source_cell, const db::CellMapping &cm, const
throw tl::Exception (tl::to_string (tr ("Source cell does not reside in a layout")));
}
db::PropertyMapper pm (*target_layout, *source_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;

View File

@ -371,7 +371,7 @@ CellMapping::do_create_missing_mapping (db::Layout &layout_a, const db::Layout &
if (! new_cells.empty ()) {
db::PropertyMapper pm (layout_a, layout_b);
db::PropertyMapper pm (&layout_a, &layout_b);
// Note: this avoids frequent cell index table rebuilds if source and target layout are identical
layout_a.start_changes ();

View File

@ -29,7 +29,7 @@ namespace db
ClipboardData::ClipboardData ()
: m_layout (), m_incomplete_cells ()
{
m_prop_id_map.set_target (m_layout);
m_prop_id_map.set_target (&m_layout);
m_container_cell_index = m_layout.add_cell ("");
}
@ -47,7 +47,7 @@ ClipboardData::add (const db::Layout &layout, unsigned int layer, const db::Shap
m_layout.insert_layer (layer, layout.get_properties (layer));
}
m_prop_id_map.set_source (layout);
m_prop_id_map.set_source (&layout);
m_layout.cell (m_container_cell_index).shapes (layer).insert (shape, m_prop_id_map);
}
@ -60,7 +60,7 @@ ClipboardData::add (const db::Layout &layout, unsigned int layer, const db::Shap
m_layout.insert_layer (layer, layout.get_properties (layer));
}
m_prop_id_map.set_source (layout);
m_prop_id_map.set_source (&layout);
db::Shape new_shape = m_layout.cell (m_container_cell_index).shapes (layer).insert (shape, m_prop_id_map);
m_layout.cell (m_container_cell_index).shapes (layer).transform (new_shape, trans);
}
@ -80,7 +80,7 @@ ClipboardData::add (const db::Layout &layout, const db::Instance &inst, unsigned
}
// Insert the instance mapping the cell to the target cell_index and the property ID using the map
m_prop_id_map.set_source (layout);
m_prop_id_map.set_source (&layout);
tl::const_map<db::cell_index_type> im (target_cell_index);
m_layout.cell (m_container_cell_index).insert (inst, im, m_prop_id_map);
}
@ -102,7 +102,7 @@ ClipboardData::add (const db::Layout &layout, const db::Instance &inst, unsigned
}
// Insert the instance mapping the cell to the target cell_index and the property ID using the map
m_prop_id_map.set_source (layout);
m_prop_id_map.set_source (&layout);
tl::const_map<db::cell_index_type> im (target_cell_index);
db::Instance new_inst = m_layout.cell (m_container_cell_index).insert (inst, im, m_prop_id_map);
m_layout.cell (m_container_cell_index).transform (new_inst, trans);
@ -123,7 +123,7 @@ ClipboardData::add (const db::Layout &layout, const db::Cell &cell, unsigned int
m_context_info.erase (target_cell_index);
}
m_prop_id_map.set_source (layout);
m_prop_id_map.set_source (&layout);
// copy the shapes
for (unsigned int l = 0; l < layout.layers (); ++l) {
@ -157,7 +157,7 @@ std::vector<unsigned int>
ClipboardData::do_insert (db::Layout &layout, const db::ICplxTrans *trans, db::Cell *cell, std::vector<db::cell_index_type> *new_tops, ClipboardDataInsertReceiver *insert_receiver) const
{
std::vector <unsigned int> new_layers;
PropertyMapper prop_id_map (layout, m_layout);
PropertyMapper prop_id_map (&layout, &m_layout);
std::map <db::LayerProperties, unsigned int, db::LPLogicalLessFunc> layer_map;
for (unsigned int l = 0; l < layout.layers (); ++l) {

View File

@ -1285,12 +1285,41 @@ DeepRegion::snapped (db::Coord gx, db::Coord gy)
namespace
{
template <class TS, class TI>
static
std::map<db::properties_id_type, std::pair<std::vector<const TS *>, std::vector<const TI *> > >
separate_by_same_properties (const shape_interactions<db::object_with_properties<TS>, db::object_with_properties<TI> > &interactions, db::PropertyMapper &pms, db::PropertyMapper &pmi)
{
std::map<db::properties_id_type, std::pair<std::vector<const TS *>, std::vector<const TI *> > > by_prop_id;
for (auto i = interactions.begin (); i != interactions.end (); ++i) {
const db::object_with_properties<TS> &subject = interactions.subject_shape (i->first);
std::pair<std::vector<const TS *>, std::vector<const TI *> > &s2p = by_prop_id [pms (subject.properties_id ())];
s2p.first.push_back (&subject);
for (auto ii = i->second.begin (); ii != i->second.end (); ++ii) {
const std::pair<unsigned int, db::object_with_properties<TI> > &intruder = interactions.intruder_shape (*ii);
if (subject.properties_id () == pmi (intruder.second.properties_id ())) {
s2p.second.push_back (&intruder.second);
}
}
}
return by_prop_id;
}
class PolygonToEdgeLocalOperation
: public local_operation<db::PolygonRef, db::PolygonRef, db::Edge>
: public local_operation<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgeWithProperties>
{
public:
PolygonToEdgeLocalOperation ()
: local_operation<db::PolygonRef, db::PolygonRef, db::Edge> ()
PolygonToEdgeLocalOperation (db::PropertiesRepository *target_pr, const db::PropertiesRepository *source_pr)
: local_operation<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgeWithProperties> (), m_pm (target_pr, source_pr)
{
// .. nothing yet ..
}
@ -1299,63 +1328,75 @@ public:
virtual bool requests_single_subjects () const { return true; }
virtual std::string description () const { return std::string ("polygon to edges"); }
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::PolygonRefWithProperties, db::PolygonRefWithProperties> &interactions, std::vector<std::unordered_set<db::EdgeWithProperties> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{
db::EdgeProcessor ep;
ep.set_base_verbosity (50);
for (shape_interactions<db::PolygonRef, db::PolygonRef>::subject_iterator s = interactions.begin_subjects (); s != interactions.end_subjects (); ++s) {
ep.insert (s->second);
}
auto by_prop_id = separate_by_same_properties (interactions, m_pm, m_pm);
for (auto shapes_by_prop_id = by_prop_id.begin (); shapes_by_prop_id != by_prop_id.end (); ++shapes_by_prop_id) {
if (interactions.num_intruders () == 0) {
db::properties_id_type prop_id = shapes_by_prop_id->first;
db::EdgeToEdgeSetGenerator eg (results.front ());
db::MergeOp op (0);
ep.process (eg, op);
} else {
// With intruders: to compute our local contribution we take the edges without and with intruders
// and deliver what is in both sets
db::MergeOp op (0);
std::vector<Edge> edges1;
db::EdgeContainer ec1 (edges1);
ep.process (ec1, op);
ep.clear ();
for (shape_interactions<db::PolygonRef, db::PolygonRef>::subject_iterator s = interactions.begin_subjects (); s != interactions.end_subjects (); ++s) {
ep.insert (s->second);
}
for (shape_interactions<db::PolygonRef, db::PolygonRef>::intruder_iterator i = interactions.begin_intruders (); i != interactions.end_intruders (); ++i) {
ep.insert (i->second.second);
for (auto s = shapes_by_prop_id->second.first.begin (); s != shapes_by_prop_id->second.first.end (); ++s) {
ep.insert (**s);
}
std::vector<Edge> edges2;
db::EdgeContainer ec2 (edges2);
ep.process (ec2, op);
db::property_injector<db::Edge, std::unordered_set<db::EdgeWithProperties> > results_with_properties (&results.front (), prop_id);
// Runs the boolean AND between the result with and without intruders
if (shapes_by_prop_id->second.second.empty ()) {
db::box_scanner<db::Edge, size_t> scanner;
scanner.reserve (edges1.size () + edges2.size ());
db::edge_to_edge_set_generator<db::property_injector<db::Edge, std::unordered_set<db::EdgeWithProperties> > > eg (results_with_properties, prop_id);
db::MergeOp op (0);
ep.process (eg, op);
} else {
// With intruders: to compute our local contribution we take the edges without and with intruders
// and deliver what is in both sets
db::MergeOp op (0);
std::vector<Edge> edges1;
db::EdgeContainer ec1 (edges1);
ep.process (ec1, op);
ep.clear ();
for (auto s = interactions.begin_subjects (); s != interactions.end_subjects (); ++s) {
ep.insert (s->second);
}
for (auto i = interactions.begin_intruders (); i != interactions.end_intruders (); ++i) {
ep.insert (i->second.second);
}
std::vector<Edge> edges2;
db::EdgeContainer ec2 (edges2);
ep.process (ec2, op);
// Runs the boolean AND between the result with and without intruders
db::box_scanner<db::Edge, size_t> scanner;
scanner.reserve (edges1.size () + edges2.size ());
for (std::vector<Edge>::const_iterator i = edges1.begin (); i != edges1.end (); ++i) {
scanner.insert (i.operator-> (), 0);
}
for (std::vector<Edge>::const_iterator i = edges2.begin (); i != edges2.end (); ++i) {
scanner.insert (i.operator-> (), 1);
}
EdgeBooleanClusterCollector<db::property_injector<Edge, std::unordered_set<db::EdgeWithProperties> > > cluster_collector (&results_with_properties, EdgeAnd);
scanner.process (cluster_collector, 1, db::box_convert<db::Edge> ());
for (std::vector<Edge>::const_iterator i = edges1.begin (); i != edges1.end (); ++i) {
scanner.insert (i.operator-> (), 0);
}
for (std::vector<Edge>::const_iterator i = edges2.begin (); i != edges2.end (); ++i) {
scanner.insert (i.operator-> (), 1);
}
EdgeBooleanClusterCollector<std::unordered_set<db::Edge> > cluster_collector (&results.front (), EdgeAnd);
scanner.process (cluster_collector, 1, db::box_convert<db::Edge> ());
}
}
private:
mutable db::PropertyMapper m_pm;
};
}
@ -1363,8 +1404,10 @@ public:
EdgesDelegate *
DeepRegion::edges (const EdgeFilterBase *filter) const
{
std::unique_ptr<db::DeepEdges> res (new db::DeepEdges (deep_layer ().derived ()));
if (empty ()) {
return new db::DeepEdges (deep_layer ().derived ());
return res.release ();
}
if (! filter && merged_semantics () && ! merged_polygons_available ()) {
@ -1373,11 +1416,9 @@ DeepRegion::edges (const EdgeFilterBase *filter) const
const db::DeepLayer &polygons = deep_layer ();
db::PolygonToEdgeLocalOperation op;
db::PolygonToEdgeLocalOperation op (res->properties_repository (), &polygons.layout ().properties_repository ());
db::local_processor<db::PolygonRef, db::PolygonRef, db::Edge> proc (const_cast<db::Layout *> (&polygons.layout ()),
const_cast<db::Cell *> (&polygons.initial_cell ()),
polygons.breakout_cells ());
db::local_processor<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgeWithProperties> proc (&res->deep_layer ().layout (), &res->deep_layer ().initial_cell (), polygons.breakout_cells ());
proc.set_description (progress_desc ());
proc.set_report_progress (report_progress ());
@ -1387,15 +1428,12 @@ DeepRegion::edges (const EdgeFilterBase *filter) const
// a boolean core makes somewhat better hierarchy
proc.set_boolean_core (true);
std::unique_ptr<db::DeepEdges> res (new db::DeepEdges (polygons.derived ()));
proc.run (&op, polygons.layer (), foreign_idlayer (), res->deep_layer ().layer ());
return res.release ();
} else {
const db::DeepLayer &polygons = merged_deep_layer ();
db::PropertyMapper pm (res->properties_repository (), &polygons.layout ().properties_repository ());
std::unique_ptr<VariantsCollectorBase> vars;
@ -1412,7 +1450,6 @@ DeepRegion::edges (const EdgeFilterBase *filter) const
db::Layout &layout = const_cast<db::Layout &> (polygons.layout ());
std::unique_ptr<db::DeepEdges> res (new db::DeepEdges (polygons.derived ()));
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
db::ICplxTrans tr;
@ -1432,7 +1469,7 @@ DeepRegion::edges (const EdgeFilterBase *filter) const
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
if (! filter || filter->selected ((*e).transformed (tr))) {
st.insert (*e);
st.insert (db::EdgeWithProperties (*e, pm (si->prop_id ())));
}
}
@ -1441,9 +1478,10 @@ DeepRegion::edges (const EdgeFilterBase *filter) const
}
res->set_is_merged (merged_semantics () || is_merged ());
return res.release ();
}
return res.release ();
}
RegionDelegate *

View File

@ -431,7 +431,7 @@ const db::PropertiesRepository *FlatRegion::properties_repository () const
void FlatRegion::insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
{
db::PropertyMapper pm (layout->properties_repository (), *mp_properties_repository.get_const ());
db::PropertyMapper pm (&layout->properties_repository (), mp_properties_repository.get_const ());
layout->cell (into_cell).shapes (into_layer).insert (*mp_polygons, pm);
}

View File

@ -542,6 +542,62 @@ subtract (std::unordered_set<db::PolygonRef> &res, const std::unordered_set<db::
ep.process (pg, op);
}
template <class TS, class TI>
static void
subtract (std::unordered_set<db::PolygonRefWithProperties> &res, const std::unordered_set<db::PolygonRefWithProperties> &other, db::Layout *layout, const db::local_processor<TS, TI, db::PolygonRefWithProperties> *proc)
{
if (other.empty ()) {
return;
}
if (! proc->boolean_core ()) {
subtract_set (res, other);
return;
}
size_t max_vertex_count = proc->max_vertex_count ();
double area_ratio = proc->area_ratio ();
std::unordered_set<db::PolygonRefWithProperties> first;
first.swap (res);
std::map<db::properties_id_type, std::pair<std::vector<const db::PolygonRefWithProperties *>, std::vector<const db::PolygonRefWithProperties *> > > by_prop_id;
for (auto i = first.begin (); i != first.end (); ++i) {
by_prop_id [i->properties_id ()].first.push_back (i.operator-> ());
}
for (auto i = other.begin (); i != other.end (); ++i) {
by_prop_id [i->properties_id ()].second.push_back (i.operator-> ());
}
db::EdgeProcessor ep;
ep.set_base_verbosity (proc->base_verbosity () + 30);
for (auto s2p = by_prop_id.begin (); s2p != by_prop_id.end (); ++s2p) {
db::properties_id_type prop_id = s2p->first;
size_t p1 = 0, p2 = 1;
ep.clear ();
for (auto i = s2p->second.first.begin (); i != s2p->second.first.end (); ++i) {
ep.insert (**i, p1);
p1 += 2;
}
for (auto i = s2p->second.second.begin (); i != s2p->second.second.end (); ++i) {
ep.insert (**i, p2);
p2 += 2;
}
db::BooleanOp op (db::BooleanOp::ANotB);
db::polygon_ref_generator_with_properties<db::PolygonRefWithProperties> pr (layout, res, prop_id);
db::PolygonSplitter splitter (pr, area_ratio, max_vertex_count);
db::PolygonGenerator pg (splitter, true, true);
ep.process (pg, op);
}
}
template <class TS, class TI>
static void
subtract (std::unordered_set<db::Edge> &res, const std::unordered_set<db::Edge> &other, db::Layout * /*layout*/, const db::local_processor<TS, TI, db::Edge> *proc)
@ -572,6 +628,59 @@ subtract (std::unordered_set<db::Edge> &res, const std::unordered_set<db::Edge>
res.swap (result);
}
template <class TS, class TI>
static void
subtract (std::unordered_set<db::EdgeWithProperties> &res, const std::unordered_set<db::EdgeWithProperties> &other, db::Layout * /*layout*/, const db::local_processor<TS, TI, db::EdgeWithProperties> *proc)
{
if (other.empty ()) {
return;
}
if (! proc->boolean_core ()) {
subtract_set (res, other);
return;
}
std::unordered_set<db::EdgeWithProperties> first;
first.swap (res);
std::map<db::properties_id_type, std::pair<std::vector<const db::EdgeWithProperties *>, std::vector<const db::EdgeWithProperties *> > > by_prop_id;
for (auto i = first.begin (); i != first.end (); ++i) {
by_prop_id [i->properties_id ()].first.push_back (i.operator-> ());
}
for (auto i = other.begin (); i != other.end (); ++i) {
by_prop_id [i->properties_id ()].second.push_back (i.operator-> ());
}
for (auto s2p = by_prop_id.begin (); s2p != by_prop_id.end (); ++s2p) {
if (s2p->second.second.empty ()) {
for (auto i = s2p->second.first.begin (); i != s2p->second.first.end (); ++i) {
res.insert (**i);
}
} else {
db::box_scanner<db::Edge, size_t> scanner;
scanner.reserve (s2p->second.first.size () + s2p->second.second.size ());
for (auto i = s2p->second.first.begin (); i != s2p->second.first.end (); ++i) {
scanner.insert (*i, 0);
}
for (auto i = s2p->second.second.begin (); i != s2p->second.second.end (); ++i) {
scanner.insert (*i, 1);
}
db::property_injector<db::Edge, std::unordered_set<db::EdgeWithProperties> > prop_inject (&res, s2p->first);
EdgeBooleanClusterCollector<db::property_injector<db::Edge, std::unordered_set<db::EdgeWithProperties> > > cluster_collector (&prop_inject, EdgeNot);
scanner.process (cluster_collector, 1, db::box_convert<db::Edge> ());
}
}
}
template <class TS, class TI, class TR>
static void
subtract (std::unordered_set<TR> &res, const std::unordered_set<TR> &other, db::Layout * /*layout*/, const db::local_processor<TS, TI, TR> * /*proc*/)
@ -761,7 +870,9 @@ template class DB_PUBLIC local_processor_cell_contexts<db::Polygon, db::Edge, db
template class DB_PUBLIC local_processor_cell_contexts<db::Polygon, db::Text, db::Polygon>;
template class DB_PUBLIC local_processor_cell_contexts<db::Polygon, db::Text, db::Text>;
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::PolygonRefWithProperties>;
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonWithProperties, db::PolygonWithProperties, db::PolygonWithProperties>;
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonRef, db::Edge, db::PolygonRef>;
template class DB_PUBLIC local_processor_cell_contexts<db::PolygonRef, db::PolygonRef, db::EdgePair>;
@ -1340,7 +1451,9 @@ template class DB_PUBLIC local_processor_context_computation_task<db::Polygon, d
template class DB_PUBLIC local_processor_context_computation_task<db::Polygon, db::Edge, db::Polygon>;
template class DB_PUBLIC local_processor_context_computation_task<db::Polygon, db::Edge, db::Edge>;
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::PolygonRefWithProperties>;
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonWithProperties, db::PolygonWithProperties, db::PolygonWithProperties>;
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::TextRef, db::TextRef>;
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::TextRef, db::PolygonRef>;
@ -1403,8 +1516,10 @@ template class DB_PUBLIC local_processor_result_computation_task<db::Polygon, db
template class DB_PUBLIC local_processor_result_computation_task<db::Polygon, db::Text, db::Text>;
template class DB_PUBLIC local_processor_result_computation_task<db::Polygon, db::Edge, db::Polygon>;
template class DB_PUBLIC local_processor_result_computation_task<db::Polygon, db::Edge, db::Edge>;
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::PolygonRefWithProperties>;
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonWithProperties, db::PolygonWithProperties, db::PolygonWithProperties>;
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonRef, db::Edge, db::PolygonRef>;
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonRef, db::PolygonRef, db::EdgePair>;
@ -2421,7 +2536,9 @@ template class DB_PUBLIC local_processor<db::Polygon, db::Text, db::Text>;
template class DB_PUBLIC local_processor<db::Polygon, db::Edge, db::Polygon>;
template class DB_PUBLIC local_processor<db::Polygon, db::Edge, db::Edge>;
template class DB_PUBLIC local_processor<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::PolygonRefWithProperties>;
template class DB_PUBLIC local_processor<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_processor<db::PolygonWithProperties, db::PolygonWithProperties, db::PolygonWithProperties>;
template class DB_PUBLIC local_processor<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
template class DB_PUBLIC local_processor<db::PolygonRef, db::Edge, db::PolygonRef>;
template class DB_PUBLIC local_processor<db::PolygonRef, db::Edge, db::Edge>;

View File

@ -643,8 +643,8 @@ PolygonReferenceHierarchyBuilderShapeReceiver::PolygonReferenceHierarchyBuilderS
}
if (source_layout && source_layout != layout) {
m_pm.set_source (*source_layout);
m_pm.set_target (*layout);
m_pm.set_source (source_layout);
m_pm.set_target (layout);
}
}
@ -727,8 +727,8 @@ EdgeBuildingHierarchyBuilderShapeReceiver::EdgeBuildingHierarchyBuilderShapeRece
: m_as_edges (as_edges)
{
if (source_layout && source_layout != layout) {
m_pm.set_source (*source_layout);
m_pm.set_target (*layout);
m_pm.set_source (source_layout);
m_pm.set_target (layout);
}
}
@ -787,8 +787,8 @@ void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Polygon &poly, d
EdgePairBuildingHierarchyBuilderShapeReceiver::EdgePairBuildingHierarchyBuilderShapeReceiver (db::Layout *layout, const db::Layout *source_layout)
{
if (source_layout && source_layout != layout) {
m_pm.set_source (*source_layout);
m_pm.set_target (*layout);
m_pm.set_source (source_layout);
m_pm.set_target (layout);
}
}
@ -810,8 +810,8 @@ TextBuildingHierarchyBuilderShapeReceiver::TextBuildingHierarchyBuilderShapeRece
: mp_layout (layout)
{
if (source_layout && source_layout != layout) {
m_pm.set_source (*source_layout);
m_pm.set_target (*layout);
m_pm.set_source (source_layout);
m_pm.set_target (layout);
}
}

View File

@ -670,11 +670,11 @@ do_compare_layouts (const db::Layout &a, const db::Cell *top_a, const db::Layout
na.properties_repository () = a.properties_repository ();
nb.properties_repository () = b.properties_repository ();
db::PropertyMapper prop_normalize_a (n, a);
db::PropertyMapper prop_normalize_b (n, b);
db::PropertyMapper prop_normalize_a (&n, &a);
db::PropertyMapper prop_normalize_b (&n, &b);
db::PropertyMapper prop_remap_to_a (na, n);
db::PropertyMapper prop_remap_to_b (nb, n);
db::PropertyMapper prop_remap_to_a (&na, &n);
db::PropertyMapper prop_remap_to_b (&nb, &n);
// compare layers

View File

@ -26,6 +26,7 @@
#include "dbPolygonTools.h"
#include "tlProgress.h"
#include "tlTimer.h"
#include "tlThreads.h"
namespace db
{
@ -60,14 +61,14 @@ DirectLayerMapping::map_layer (const LayerProperties &lprops)
// ------------------------------------------------------------------------------------
// PropertyMapper implementation
PropertyMapper::PropertyMapper (db::Layout &target, const db::Layout &source)
: mp_target (&target.properties_repository ()), mp_source (&source.properties_repository ())
PropertyMapper::PropertyMapper (db::Layout *target, const db::Layout *source)
: mp_target (target ? &target->properties_repository () : 0), mp_source (source ? &source->properties_repository () : 0)
{
// .. nothing yet ..
}
PropertyMapper::PropertyMapper (db::PropertiesRepository &target, const db::PropertiesRepository &source)
: mp_target (&target), mp_source (&source)
PropertyMapper::PropertyMapper (db::PropertiesRepository *target, const db::PropertiesRepository *source)
: mp_target (target), mp_source (source)
{
// .. nothing yet ..
}
@ -88,11 +89,12 @@ PropertyMapper::PropertyMapper ()
* @brief Specify the source layout
*/
void
PropertyMapper::set_source (const db::Layout &source)
PropertyMapper::set_source (const db::Layout *source)
{
if (&source.properties_repository () != mp_source) {
const db::PropertiesRepository *pr = source ? &source->properties_repository () : 0;
if (pr != mp_source) {
m_prop_id_map.clear ();
mp_source = &source.properties_repository ();
mp_source = pr;
}
}
@ -100,11 +102,11 @@ PropertyMapper::set_source (const db::Layout &source)
* @brief Specify the source property repository
*/
void
PropertyMapper::set_source (const db::PropertiesRepository &source)
PropertyMapper::set_source (const db::PropertiesRepository *source)
{
if (&source != mp_source) {
if (source != mp_source) {
m_prop_id_map.clear ();
mp_source = &source;
mp_source = source;
}
}
@ -112,11 +114,12 @@ PropertyMapper::set_source (const db::PropertiesRepository &source)
* @brief Specify the target layout
*/
void
PropertyMapper::set_target (db::Layout &target)
PropertyMapper::set_target (db::Layout *target)
{
if (&target.properties_repository () != mp_target) {
db::PropertiesRepository *pr = target ? &target->properties_repository () : 0;
if (pr != mp_target) {
m_prop_id_map.clear ();
mp_target = &target.properties_repository ();
mp_target = pr;
}
}
@ -124,11 +127,11 @@ PropertyMapper::set_target (db::Layout &target)
* @brief Specify the target property repository
*/
void
PropertyMapper::set_target (db::PropertiesRepository &target)
PropertyMapper::set_target (db::PropertiesRepository *target)
{
if (&target != mp_target) {
if (target != mp_target) {
m_prop_id_map.clear ();
mp_target = &target;
mp_target = target;
}
}
@ -138,13 +141,16 @@ PropertyMapper::set_target (db::PropertiesRepository &target)
db::Layout::properties_id_type
PropertyMapper::operator() (db::Layout::properties_id_type source_id)
{
if (source_id == 0 || mp_source == mp_target) {
if (source_id == 0 || mp_source == mp_target || ! mp_source || ! mp_target) {
return source_id;
}
tl_assert (mp_source != 0);
tl_assert (mp_target != 0);
static tl::Mutex s_mutex;
tl::MutexLocker locker (&s_mutex);
std::map <db::Layout::properties_id_type, db::Layout::properties_id_type>::const_iterator p = m_prop_id_map.find (source_id);
if (p == m_prop_id_map.end ()) {
@ -226,7 +232,7 @@ merge_layouts (db::Layout &target,
}
// provide the property mapper
db::PropertyMapper pm (target, source);
db::PropertyMapper pm (&target, &source);
tl::RelativeProgress progress (tl::to_string (tr ("Merge cells")), all_cells_to_copy.size (), 1);
@ -338,7 +344,7 @@ copy_or_move_shapes (db::Layout &target,
collect_cells_to_copy (source, source_cells, cell_mapping, all_top_level_cells, all_cells_to_copy);
// provide the property mapper
db::PropertyMapper pm (target, source);
db::PropertyMapper pm (&target, &source);
tl::RelativeProgress progress (tl::to_string (tr ("Merge cells")), all_cells_to_copy.size () * layer_mapping.size (), 1);

View File

@ -80,7 +80,7 @@ public:
* @param source The source layout
* @param target The target layout
*/
PropertyMapper (db::Layout &target, const db::Layout &source);
PropertyMapper (db::Layout *target, const db::Layout *source);
/**
* @brief Instantiate a property mapper for mapping of property ids from the source to the target property repository
@ -88,7 +88,7 @@ public:
* @param source The source property repository
* @param target The target property repository
*/
PropertyMapper (db::PropertiesRepository &target, const db::PropertiesRepository &source);
PropertyMapper (db::PropertiesRepository *target, const db::PropertiesRepository *source);
/**
* @brief Instantiate a property mapper for mapping of property ids from the source to the target layout
@ -101,22 +101,22 @@ public:
/**
* @brief Specify the source layout
*/
void set_source (const db::Layout &source);
void set_source (const db::Layout *source);
/**
* @brief Specify the source property repository
*/
void set_source (const db::PropertiesRepository &source);
void set_source (const db::PropertiesRepository *source);
/**
* @brief Specify the target layout
*/
void set_target (db::Layout &target);
void set_target (db::Layout *target);
/**
* @brief Specify the target property repository
*/
void set_target (db::PropertiesRepository &target);
void set_target (db::PropertiesRepository *target);
/**
* @brief The actual mapping function

View File

@ -224,7 +224,7 @@ LibraryProxy::update (db::ImportLayerMapping *layer_mapping)
clear_shapes ();
clear_insts ();
PropertyMapper prop_id_map (*layout (), lib->layout ());
PropertyMapper prop_id_map (layout (), &lib->layout ());
for (unsigned int l = 0; l < lib->layout ().layers (); ++l) {
if (layer_indices [l] >= 0) {

View File

@ -95,7 +95,9 @@ template class DB_PUBLIC local_operation<db::Polygon, db::Text, db::Text>;
template class DB_PUBLIC local_operation<db::Polygon, db::Edge, db::Polygon>;
template class DB_PUBLIC local_operation<db::Polygon, db::Edge, db::Edge>;
template class DB_PUBLIC local_operation<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::PolygonRefWithProperties>;
template class DB_PUBLIC local_operation<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_operation<db::PolygonWithProperties, db::PolygonWithProperties, db::PolygonWithProperties>;
template class DB_PUBLIC local_operation<db::PolygonWithProperties, db::PolygonWithProperties, db::EdgeWithProperties>;
template class DB_PUBLIC local_operation<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
template class DB_PUBLIC local_operation<db::PolygonRef, db::Text, db::PolygonRef>;
template class DB_PUBLIC local_operation<db::PolygonRef, db::TextRef, db::PolygonRef>;
@ -203,7 +205,7 @@ template class DB_PUBLIC bool_and_or_not_local_operation<db::Polygon, db::Polygo
template <class TS, class TI, class TR>
bool_and_or_not_local_operation_with_properties<TS, TI, TR>::bool_and_or_not_local_operation_with_properties (bool is_and, db::PropertiesRepository *target_pr, const db::PropertiesRepository *subject_pr, const db::PropertiesRepository *intruder_pr, db::PropertyConstraint property_constraint)
: m_is_and (is_and), m_property_constraint (property_constraint), mp_target_pr (target_pr), mp_subject_pr (subject_pr), mp_intruder_pr (intruder_pr)
: m_is_and (is_and), m_property_constraint (property_constraint), m_pms (target_pr, subject_pr), m_pmi (target_pr, intruder_pr)
{
// .. nothing yet ..
}
@ -226,9 +228,6 @@ template <class TS, class TI, class TR>
void
bool_and_or_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (db::Layout *layout, const shape_interactions<db::object_with_properties<TS>, db::object_with_properties<TI> > &interactions, std::vector<std::unordered_set<db::object_with_properties<TR> > > &results, size_t max_vertex_count, double area_ratio) const
{
db::PropertyMapper pms (*mp_target_pr, *mp_subject_pr);
db::PropertyMapper pmi (*mp_target_pr, *mp_intruder_pr);
tl_assert (results.size () == 1);
std::unordered_set<db::object_with_properties<TR> > &result = results.front ();
@ -243,19 +242,19 @@ bool_and_or_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (d
if (i->second.empty ()) {
if (! m_is_and) {
result.insert (db::object_with_properties<TR> (subject, pms (subject.properties_id ())));
result.insert (db::object_with_properties<TR> (subject, m_pms (subject.properties_id ())));
}
} else {
db::properties_id_type prop_id_s = pms (subject.properties_id ());
db::properties_id_type prop_id_s = m_pms (subject.properties_id ());
auto &shapes_by_prop = by_prop_id [prop_id_s];
shapes_by_prop.first.push_front (subject);
for (auto j = i->second.begin (); j != i->second.end (); ++j) {
const db::object_with_properties<TI> &intruder = interactions.intruder_shape (*j).second;
db::properties_id_type prop_id_i = (m_property_constraint != db::NoPropertyConstraint ? pmi (intruder.properties_id ()) : prop_id_s);
db::properties_id_type prop_id_i = (m_property_constraint != db::NoPropertyConstraint ? m_pmi (intruder.properties_id ()) : prop_id_s);
if ((prop_id_i != prop_id_s) == (m_property_constraint == db::DifferentPropertiesConstraint)) {
shapes_by_prop.second.insert (intruder);
}
@ -303,19 +302,13 @@ bool_and_or_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (d
p2 += 2;
}
std::unordered_set<TR> result_wo_props;
db::BooleanOp op (m_is_and ? db::BooleanOp::And : db::BooleanOp::ANotB);
db::polygon_ref_generator<TR> pr (layout, result_wo_props);
db::polygon_ref_generator_with_properties<db::object_with_properties<TR> > pr (layout, result, prop_id);
db::PolygonSplitter splitter (pr, area_ratio, max_vertex_count);
db::PolygonGenerator pg (splitter, true, true);
ep.set_base_verbosity (50);
ep.process (pg, op);
for (auto r = result_wo_props.begin (); r != result_wo_props.end (); ++r) {
result.insert (db::object_with_properties<TR> (*r, prop_id));
}
}
}
@ -416,7 +409,7 @@ template class DB_PUBLIC two_bool_and_not_local_operation<db::Polygon, db::Polyg
template <class TS, class TI, class TR>
two_bool_and_not_local_operation_with_properties<TS, TI, TR>::two_bool_and_not_local_operation_with_properties (db::PropertiesRepository *target1_pr, db::PropertiesRepository *target2_pr, const db::PropertiesRepository *subject_pr, const db::PropertiesRepository *intruder_pr, db::PropertyConstraint property_constraint)
: db::local_operation<db::object_with_properties<TS>, db::object_with_properties<TI>, db::object_with_properties<TR> > (),
m_property_constraint (property_constraint), mp_target1_pr (target1_pr), mp_target2_pr (target2_pr), mp_subject_pr (subject_pr), mp_intruder_pr (intruder_pr)
m_property_constraint (property_constraint), m_pms (target1_pr, subject_pr), m_pmi (target1_pr, intruder_pr), m_pm12 (target2_pr, target1_pr)
{
// .. nothing yet ..
}
@ -425,10 +418,6 @@ template <class TS, class TI, class TR>
void
two_bool_and_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (db::Layout *layout, const shape_interactions<db::object_with_properties<TS>, db::object_with_properties<TI> > &interactions, std::vector<std::unordered_set<db::object_with_properties<TR> > > &results, size_t max_vertex_count, double area_ratio) const
{
db::PropertyMapper pms (*mp_target1_pr, *mp_subject_pr);
db::PropertyMapper pmi (*mp_target1_pr, *mp_intruder_pr);
db::PropertyMapper pm12 (*mp_target2_pr, *mp_target1_pr);
tl_assert (results.size () == 2);
std::unordered_set<db::object_with_properties<TR> > &result0 = results [0];
std::unordered_set<db::object_with_properties<TR> > &result1 = results [1];
@ -443,18 +432,18 @@ two_bool_and_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (
if (i->second.empty ()) {
result1.insert (db::object_with_properties<TR> (subject, pms (subject.properties_id ())));
result1.insert (db::object_with_properties<TR> (subject, m_pms (subject.properties_id ())));
} else {
db::properties_id_type prop_id_s = pms (subject.properties_id ());
db::properties_id_type prop_id_s = m_pms (subject.properties_id ());
auto &shapes_by_prop = by_prop_id [prop_id_s];
shapes_by_prop.first.push_front (subject);
for (auto j = i->second.begin (); j != i->second.end (); ++j) {
const db::object_with_properties<TI> &intruder = interactions.intruder_shape (*j).second;
db::properties_id_type prop_id_i = (m_property_constraint != db::NoPropertyConstraint ? pmi (intruder.properties_id ()) : prop_id_s);
db::properties_id_type prop_id_i = (m_property_constraint != db::NoPropertyConstraint ? m_pmi (intruder.properties_id ()) : prop_id_s);
if ((prop_id_i != prop_id_s) == (m_property_constraint == db::DifferentPropertiesConstraint)) {
shapes_by_prop.second.insert (intruder);
}
@ -479,7 +468,7 @@ two_bool_and_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (
result0.insert (db::object_with_properties<TR> (subject, prop_id));
} else if (others.empty ()) {
// shortcut (not: keep, and: drop)
result1.insert (db::object_with_properties<TR> (subject, pm12 (prop_id)));
result1.insert (db::object_with_properties<TR> (subject, m_pm12 (prop_id)));
} else {
for (auto e = subject.begin_edge (); ! e.at_end(); ++e) {
ep.insert (*e, p1);
@ -522,7 +511,7 @@ two_bool_and_not_local_operation_with_properties<TS, TI, TR>::do_compute_local (
result0.insert (db::object_with_properties<TR> (*r, prop_id));
}
for (auto r = result1_wo_props.begin (); r != result1_wo_props.end (); ++r) {
result1.insert (db::object_with_properties<TR> (*r, pm12 (prop_id)));
result1.insert (db::object_with_properties<TR> (*r, m_pm12 (prop_id)));
}
}

View File

@ -31,6 +31,7 @@
#include "dbEdgeBoolean.h"
#include "dbEdgeProcessor.h"
#include "dbPropertyConstraint.h"
#include "dbLayoutUtils.h"
#include <unordered_map>
#include <unordered_set>
@ -168,8 +169,8 @@ public:
private:
bool m_is_and;
db::PropertyConstraint m_property_constraint;
db::PropertiesRepository *mp_target_pr;
const db::PropertiesRepository *mp_subject_pr, *mp_intruder_pr;
mutable db::PropertyMapper m_pms;
mutable db::PropertyMapper m_pmi;
};
typedef bool_and_or_not_local_operation_with_properties<db::PolygonRef, db::PolygonRef, db::PolygonRef> BoolAndOrNotLocalOperationWithProperties;
@ -212,8 +213,7 @@ public:
private:
db::PropertyConstraint m_property_constraint;
db::PropertiesRepository *mp_target1_pr, *mp_target2_pr;
const db::PropertiesRepository *mp_subject_pr, *mp_intruder_pr;
mutable db::PropertyMapper m_pms, m_pmi, m_pm12;
};
typedef two_bool_and_not_local_operation_with_properties<db::PolygonRef, db::PolygonRef, db::PolygonRef> TwoBoolAndNotLocalOperationWithProperties;

View File

@ -27,33 +27,6 @@
namespace db
{
// -----------------------------------------------------------------------------------------------
// class EdgeToEdgeSetGenerator
EdgeToEdgeSetGenerator::EdgeToEdgeSetGenerator (std::unordered_set<db::Edge> &edges, int tag, EdgeToEdgeSetGenerator *chained)
: mp_edges (&edges), m_tag (tag), mp_chained (chained)
{
// .. nothing yet ..
}
void EdgeToEdgeSetGenerator::put (const db::Edge &edge)
{
mp_edges->insert (edge);
if (mp_chained) {
mp_chained->put (edge);
}
}
void EdgeToEdgeSetGenerator::put (const db::Edge &edge, int tag)
{
if (m_tag == 0 || m_tag == tag) {
mp_edges->insert (edge);
}
if (mp_chained) {
mp_chained->put (edge, tag);
}
}
// -----------------------------------------------------------------------------------------------
// class PolygonRefGenerator

View File

@ -123,31 +123,117 @@ private:
typedef polygon_ref_generator<db::PolygonRef> PolygonRefGenerator;
class DB_PUBLIC EdgeToEdgeSetGenerator
template <class T>
class DB_PUBLIC polygon_ref_generator_with_properties;
template <>
class DB_PUBLIC polygon_ref_generator_with_properties<db::PolygonRefWithProperties>
: public PolygonSink
{
public:
/**
* @brief Constructor
*/
polygon_ref_generator_with_properties (db::Layout *layout, std::unordered_set<db::PolygonRefWithProperties> &polyrefs, db::properties_id_type prop_id)
: PolygonSink (), mp_layout (layout), mp_polyrefs (&polyrefs), m_prop_id (prop_id)
{
// .. nothing yet ..
}
/**
* @brief Implementation of the PolygonSink interface
*/
void put (const db::Polygon &polygon)
{
tl::MutexLocker locker (&mp_layout->lock ());
mp_polyrefs->insert (db::PolygonRefWithProperties (db::PolygonRef (polygon, mp_layout->shape_repository ()), m_prop_id));
}
private:
db::Layout *mp_layout;
std::unordered_set<db::PolygonRefWithProperties> *mp_polyrefs;
db::properties_id_type m_prop_id;
};
template <>
class DB_PUBLIC polygon_ref_generator_with_properties<db::PolygonWithProperties>
: public PolygonSink
{
public:
/**
* @brief Constructor
*/
polygon_ref_generator_with_properties (db::Layout *, std::unordered_set<db::PolygonWithProperties> &polygons, db::properties_id_type prop_id)
: mp_polygons (&polygons), m_prop_id (prop_id)
{
// .. nothing yet ..
}
/**
* @brief Implementation of the PolygonSink interface
*/
virtual void put (const db::Polygon &polygon)
{
mp_polygons->insert (db::PolygonWithProperties (polygon, m_prop_id));
}
private:
std::unordered_set<db::PolygonWithProperties> *mp_polygons;
db::properties_id_type m_prop_id;
};
typedef polygon_ref_generator<db::PolygonRef> PolygonRefGenerator;
template <class Container>
class DB_PUBLIC edge_to_edge_set_generator
: public EdgeSink
{
public:
/**
* @brief Constructor
*/
EdgeToEdgeSetGenerator (std::unordered_set<db::Edge> &edges, int tag = 0, EdgeToEdgeSetGenerator *chained = 0);
edge_to_edge_set_generator (Container &edges, int tag = 0, EdgeSink *chained = 0)
: mp_edges (&edges), m_tag (tag), mp_chained (chained)
{
// .. nothing yet ..
}
/**
* @brief Implementation of the PolygonSink interface
*/
virtual void put (const db::Edge &edge);
virtual void put (const db::Edge &edge)
{
if (mp_edges) {
mp_edges->insert (edge);
}
if (mp_chained) {
mp_chained->put (edge);
}
}
/**
* @brief Implementation of the PolygonSink interface
*/
virtual void put (const db::Edge &edge, int tag);
virtual void put (const db::Edge &edge, int tag)
{
if (m_tag == 0 || m_tag == tag) {
if (mp_edges) {
mp_edges->insert (edge);
}
}
if (mp_chained) {
mp_chained->put (edge, tag);
}
}
private:
std::unordered_set<db::Edge> *mp_edges;
Container *mp_edges;
int m_tag;
EdgeToEdgeSetGenerator *mp_chained;
EdgeSink *mp_chained;
};
typedef edge_to_edge_set_generator<std::unordered_set<db::Edge> > EdgeToEdgeSetGenerator;
class DB_PUBLIC PolygonRefToShapesGenerator
: public PolygonSink
{
@ -185,6 +271,38 @@ private:
size_t m_max_vertex_count;
};
template <class T, class Container>
class DB_PUBLIC property_injector
{
public:
typedef typename Container::const_iterator const_iterator;
property_injector (Container *container, db::properties_id_type prop_id)
: mp_container (container), m_prop_id (prop_id)
{
// .. nothing yet ..
}
const_iterator begin () const
{
return mp_container->begin ();
}
const_iterator end () const
{
return mp_container->end ();
}
void insert (const T &t)
{
mp_container->insert (db::object_with_properties<T> (t, m_prop_id));
}
private:
Container *mp_container;
db::properties_id_type m_prop_id;
};
}
#endif

View File

@ -423,7 +423,7 @@ OriginalLayerRegion::insert_into (Layout *layout, db::cell_index_type into_cell,
db::PropertyMapper pm;
if (m_iter.layout ()) {
pm = db::PropertyMapper (*layout, *m_iter.layout ());
pm = db::PropertyMapper (layout, m_iter.layout ());
}
// NOTE: if the source (r) is from the same layout than the shapes live in, we better

View File

@ -1192,7 +1192,7 @@ static void move_or_copy_from_other_cell (db::Cell *cell, db::Cell *src_cell, un
} else if (cell->layout () != src_cell->layout ()) {
db::PropertyMapper pm (*cell->layout (), *src_cell->layout ());
db::PropertyMapper pm (cell->layout (), src_cell->layout ());
db::ICplxTrans tr (src_cell->layout ()->dbu () / cell->layout ()->dbu ());
cell->shapes (dest_layer).insert_transformed (src_cell->shapes (src_layer), tr, pm);

View File

@ -1646,7 +1646,7 @@ LayoutViewFunctions::cm_copy_layer ()
if (! same_layout) {
// flat mode (different layouts)
db::PropertyMapper pm (view ()->cellview (m_copy_cvr)->layout (), view ()->cellview (m_copy_cva)->layout ());
db::PropertyMapper pm (&view ()->cellview (m_copy_cvr)->layout (), &view ()->cellview (m_copy_cva)->layout ());
for (db::RecursiveShapeIterator si (view ()->cellview (m_copy_cva)->layout (), *view ()->cellview (m_copy_cva).cell (), m_copy_layera); ! si.at_end (); ++si) {
target_cell.shapes (m_copy_layerr).insert (*si, si.trans (), pm);
}
@ -1693,7 +1693,7 @@ LayoutViewFunctions::cm_copy_layer ()
} else if (! same_layout) {
// current cell only mode (different layouts)
db::PropertyMapper pm (view ()->cellview (m_copy_cvr)->layout (), view ()->cellview (m_copy_cva)->layout ());
db::PropertyMapper pm (&view ()->cellview (m_copy_cvr)->layout (), &view ()->cellview (m_copy_cva)->layout ());
for (db::Shapes::shape_iterator si = view ()->cellview (m_copy_cva).cell ()->shapes (m_copy_layera).begin (db::ShapeIterator::All); ! si.at_end (); ++si) {
target_cell.shapes (m_copy_layerr).insert (*si, pm);
}