mirror of https://github.com/KLayout/klayout.git
WIP: refactoring, preparing polygon-to-edge with properties
This commit is contained in:
parent
f0e20ad258
commit
8fb4e36809
|
|
@ -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 ());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 = ⌖
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue