WIP: some development, bugfixing on DRC implementation - mainly about correct opposite filter operation

This commit is contained in:
Matthias Koefferlein 2021-01-06 23:39:51 +01:00
parent 9c95bed67e
commit d1868a4b23
21 changed files with 426 additions and 160 deletions

View File

@ -1093,6 +1093,66 @@ AsIfFlatRegion::cop_to_edges (db::CompoundRegionOperationNode &node)
return output.release (); return output.release ();
} }
EdgePairsDelegate *
AsIfFlatRegion::width_check (db::Coord d, const RegionCheckOptions &options) const
{
return run_single_polygon_check (db::WidthRelation, d, options);
}
EdgePairsDelegate *
AsIfFlatRegion::space_or_isolated_check (db::Coord d, const RegionCheckOptions &options, bool isolated) const
{
if (options.opposite_filter != NoOppositeFilter || options.rect_filter != NoSideAllowed) {
// NOTE: we have to use the "foreign" scheme with a filter because only this scheme
// guarantees that all subject shapes are visited.
return run_check (db::SpaceRelation, isolated, foreign_regionptr (), d, options);
} else {
return run_check (db::SpaceRelation, isolated, subject_regionptr (), d, options);
}
}
EdgePairsDelegate *
AsIfFlatRegion::space_check (db::Coord d, const RegionCheckOptions &options) const
{
return space_or_isolated_check (d, options, false);
}
EdgePairsDelegate *
AsIfFlatRegion::isolated_check (db::Coord d, const RegionCheckOptions &options) const
{
return space_or_isolated_check (d, options, true);
}
EdgePairsDelegate *
AsIfFlatRegion::notch_check (db::Coord d, const RegionCheckOptions &options) const
{
return run_single_polygon_check (db::SpaceRelation, d, options);
}
EdgePairsDelegate *
AsIfFlatRegion::enclosing_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const
{
return run_check (db::OverlapRelation, true, &other, d, options);
}
EdgePairsDelegate *
AsIfFlatRegion::overlap_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const
{
return run_check (db::WidthRelation, true, &other, d, options);
}
EdgePairsDelegate *
AsIfFlatRegion::separation_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const
{
return run_check (db::SpaceRelation, true, &other, d, options);
}
EdgePairsDelegate *
AsIfFlatRegion::inside_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const
{
return run_check (db::InsideRelation, true, &other, d, options);
}
EdgePairsDelegate * EdgePairsDelegate *
AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, const RegionCheckOptions &options) const AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, const RegionCheckOptions &options) const
{ {
@ -1107,19 +1167,31 @@ AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons,
check.set_min_projection (options.min_projection); check.set_min_projection (options.min_projection);
check.set_max_projection (options.max_projection); check.set_max_projection (options.max_projection);
db::check_local_operation<db::Polygon, db::Polygon> op (check, different_polygons, other != 0, other && other->is_merged (), options);
db::local_processor<db::Polygon, db::Polygon, db::EdgePair> proc; db::local_processor<db::Polygon, db::Polygon, db::EdgePair> proc;
proc.set_base_verbosity (base_verbosity ()); proc.set_base_verbosity (base_verbosity ());
std::vector<generic_shape_iterator<db::Polygon> > others; std::vector<generic_shape_iterator<db::Polygon> > others;
others.push_back (other ? other->begin () : begin_merged ()); std::vector<bool> foreign;
bool has_other = false;
bool other_is_merged = true;
if (other == subject_regionptr () || other == foreign_regionptr ()) {
foreign.push_back (other == foreign_regionptr ());
others.push_back (begin_merged ());
} else {
foreign.push_back (false);
others.push_back (other->begin ());
other_is_merged = other->is_merged ();
has_other = true;
}
db::check_local_operation<db::Polygon, db::Polygon> op (check, different_polygons, has_other, other_is_merged, options);
std::auto_ptr<FlatEdgePairs> output (new FlatEdgePairs ()); std::auto_ptr<FlatEdgePairs> output (new FlatEdgePairs ());
std::vector<db::Shapes *> results; std::vector<db::Shapes *> results;
results.push_back (&output->raw_edge_pairs ()); results.push_back (&output->raw_edge_pairs ());
proc.run_flat (polygons, others, std::vector<bool> (), &op, results); proc.run_flat (polygons, others, foreign, &op, results);
return output.release (); return output.release ();

View File

@ -60,45 +60,14 @@ public:
virtual RegionDelegate *cop_to_region (db::CompoundRegionOperationNode &node); virtual RegionDelegate *cop_to_region (db::CompoundRegionOperationNode &node);
virtual EdgesDelegate *cop_to_edges (db::CompoundRegionOperationNode &node); virtual EdgesDelegate *cop_to_edges (db::CompoundRegionOperationNode &node);
EdgePairsDelegate *width_check (db::Coord d, const RegionCheckOptions &options) const EdgePairsDelegate *width_check (db::Coord d, const RegionCheckOptions &options) const;
{ EdgePairsDelegate *space_check (db::Coord d, const RegionCheckOptions &options) const;
return run_single_polygon_check (db::WidthRelation, d, options); EdgePairsDelegate *isolated_check (db::Coord d, const RegionCheckOptions &options) const;
} EdgePairsDelegate *notch_check (db::Coord d, const RegionCheckOptions &options) const;
EdgePairsDelegate *enclosing_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const;
EdgePairsDelegate *space_check (db::Coord d, const RegionCheckOptions &options) const EdgePairsDelegate *overlap_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const;
{ EdgePairsDelegate *separation_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const;
return run_check (db::SpaceRelation, false, 0, d, options); EdgePairsDelegate *inside_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const;
}
EdgePairsDelegate *isolated_check (db::Coord d, const RegionCheckOptions &options) const
{
return run_check (db::SpaceRelation, true, 0, d, options);
}
EdgePairsDelegate *notch_check (db::Coord d, const RegionCheckOptions &options) const
{
return run_single_polygon_check (db::SpaceRelation, d, options);
}
EdgePairsDelegate *enclosing_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const
{
return run_check (db::OverlapRelation, true, &other, d, options);
}
EdgePairsDelegate *overlap_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const
{
return run_check (db::WidthRelation, true, &other, d, options);
}
EdgePairsDelegate *separation_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const
{
return run_check (db::SpaceRelation, true, &other, d, options);
}
EdgePairsDelegate *inside_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const
{
return run_check (db::InsideRelation, true, &other, d, options);
}
virtual EdgePairsDelegate *grid_check (db::Coord gx, db::Coord gy) const; virtual EdgePairsDelegate *grid_check (db::Coord gx, db::Coord gy) const;
virtual EdgePairsDelegate *angle_check (double min, double max, bool inverse) const; virtual EdgePairsDelegate *angle_check (double min, double max, bool inverse) const;
@ -298,6 +267,7 @@ private:
virtual db::Box compute_bbox () const; virtual db::Box compute_bbox () const;
static RegionDelegate *region_from_box (const db::Box &b); static RegionDelegate *region_from_box (const db::Box &b);
EdgePairsDelegate *space_or_isolated_check (db::Coord d, const RegionCheckOptions &options, bool isolated) const;
}; };
} }

View File

@ -1487,7 +1487,7 @@ CompoundRegionEdgePairToEdgeProcessingOperationNode::do_compute_local (db::Layou
// --------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------
CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (db::edge_relation_type rel, bool different_polygons, db::Coord d, const db::RegionCheckOptions &options) CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (db::edge_relation_type rel, bool different_polygons, db::Coord d, const db::RegionCheckOptions &options)
: CompoundRegionMultiInputOperationNode (), m_check (rel, d, options.metrics), m_different_polygons (different_polygons), m_options (options) : CompoundRegionMultiInputOperationNode (), m_check (rel, d, options.metrics), m_different_polygons (different_polygons), m_options (options), m_has_other (false), m_is_other_merged (false)
{ {
set_description ("check"); set_description ("check");
@ -1499,7 +1499,7 @@ CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (db::edge_rel
} }
CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegionOperationNode *input, db::edge_relation_type rel, bool different_polygons, db::Coord d, const db::RegionCheckOptions &options) CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegionOperationNode *input, db::edge_relation_type rel, bool different_polygons, db::Coord d, const db::RegionCheckOptions &options)
: CompoundRegionMultiInputOperationNode (input), m_check (rel, d, options.metrics), m_different_polygons (different_polygons), m_options (options) : CompoundRegionMultiInputOperationNode (input), m_check (rel, d, options.metrics), m_different_polygons (different_polygons), m_options (options), m_has_other (false), m_is_other_merged (false)
{ {
set_description ("check"); set_description ("check");
@ -1513,6 +1513,18 @@ CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegi
CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegionOperationNode * /*input*/, CompoundRegionOperationNode *other, db::edge_relation_type rel, bool different_polygons, db::Coord d, const db::RegionCheckOptions &options) CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegionOperationNode * /*input*/, CompoundRegionOperationNode *other, db::edge_relation_type rel, bool different_polygons, db::Coord d, const db::RegionCheckOptions &options)
: CompoundRegionMultiInputOperationNode (other), m_check (rel, d, options.metrics), m_different_polygons (different_polygons), m_options (options) : CompoundRegionMultiInputOperationNode (other), m_check (rel, d, options.metrics), m_different_polygons (different_polygons), m_options (options)
{ {
m_has_other = false;
std::vector<db::Region *> other_inputs = other->inputs ();
if (other_inputs.size () > 1) {
m_has_other = true;
m_is_other_merged = false; // or do we know better?
} else if (other_inputs.size () == 1) {
if (! is_subject_regionptr (other_inputs.front ())) {
m_has_other = true;
m_is_other_merged = other_inputs.front ()->is_merged ();
}
}
set_description ("check"); set_description ("check");
m_check.set_include_zero (false); m_check.set_include_zero (false);
@ -1525,7 +1537,7 @@ CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegi
db::OnEmptyIntruderHint db::OnEmptyIntruderHint
CompoundRegionCheckOperationNode::on_empty_intruder_hint () const CompoundRegionCheckOperationNode::on_empty_intruder_hint () const
{ {
return (m_different_polygons || !inputs ().empty ()) ? OnEmptyIntruderHint::Drop : OnEmptyIntruderHint::Ignore; return (m_different_polygons || m_has_other) ? OnEmptyIntruderHint::Drop : OnEmptyIntruderHint::Ignore;
} }
db::Coord db::Coord
@ -1543,9 +1555,7 @@ CompoundRegionCheckOperationNode::wants_merged () const
void void
CompoundRegionCheckOperationNode::do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const CompoundRegionCheckOperationNode::do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const
{ {
bool other_merged = (children () > 0 && is_subject_regionptr (inputs ()[0])); db::check_local_operation<db::Polygon, db::Polygon> op (m_check, m_different_polygons, m_has_other, m_is_other_merged, m_options);
db::check_local_operation<db::Polygon, db::Polygon> op (m_check, m_different_polygons, children () > 0, other_merged, m_options);
tl_assert (results.size () == 1); tl_assert (results.size () == 1);
if (results.front ().empty ()) { if (results.front ().empty ()) {
@ -1561,9 +1571,7 @@ CompoundRegionCheckOperationNode::do_compute_local (db::Layout *layout, const sh
void void
CompoundRegionCheckOperationNode::do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const CompoundRegionCheckOperationNode::do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const
{ {
bool other_merged = (children () > 0 && is_subject_regionptr (inputs ()[0])); db::check_local_operation<db::PolygonRef, db::PolygonRef> op (m_check, m_different_polygons, m_has_other, m_is_other_merged, m_options);
db::check_local_operation<db::PolygonRef, db::PolygonRef> op (m_check, m_different_polygons, children () > 0, other_merged, m_options);
tl_assert (results.size () == 1); tl_assert (results.size () == 1);
if (results.front ().empty ()) { if (results.front ().empty ()) {

View File

@ -1410,6 +1410,8 @@ private:
db::EdgeRelationFilter m_check; db::EdgeRelationFilter m_check;
bool m_different_polygons; bool m_different_polygons;
db::RegionCheckOptions m_options; db::RegionCheckOptions m_options;
bool m_has_other;
bool m_is_other_merged;
}; };
@ -1435,35 +1437,14 @@ public:
{ } { }
protected: protected:
virtual void compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio) const virtual void do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio) const
{ {
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) { mp_node->compute_local (layout, interactions, results, max_vertex_count, area_ratio);
const TS &subject_shape = interactions.subject_shape (i->first);
shape_interactions<TS, TI> single_interactions;
if (on_empty_intruder_hint () == OnEmptyIntruderHint::Drop) {
single_interactions.add_subject_shape (i->first, subject_shape);
} else {
// this includes the subject-without-intruder "interaction"
single_interactions.add_subject (i->first, subject_shape);
}
const std::vector<unsigned int> &intruders = interactions.intruders_for (i->first);
for (typename std::vector<unsigned int>::const_iterator ii = intruders.begin (); ii != intruders.end (); ++ii) {
const std::pair<unsigned int, TI> &is = interactions.intruder_shape (*ii);
single_interactions.add_intruder_shape (*ii, is.first, is.second);
single_interactions.add_interaction (i->first, *ii);
}
mp_node->compute_local (layout, single_interactions, results, max_vertex_count, area_ratio);
}
} }
virtual db::Coord dist () const { return mp_node->dist (); } virtual db::Coord dist () const { return mp_node->dist (); }
virtual OnEmptyIntruderHint on_empty_intruder_hint () const { return mp_node->on_empty_intruder_hint (); } virtual OnEmptyIntruderHint on_empty_intruder_hint () const { return mp_node->on_empty_intruder_hint (); }
virtual bool requests_single_subjects () const { return true; }
virtual std::string description () const { return mp_node->description (); } virtual std::string description () const { return mp_node->description (); }
const TransformationReducer *vars () const { return mp_node->vars (); } const TransformationReducer *vars () const { return mp_node->vars (); }

View File

@ -1078,7 +1078,7 @@ public:
return 1; return 1;
} }
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &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::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == 1);
std::unordered_set<db::Edge> &result = results.front (); std::unordered_set<db::Edge> &result = results.front ();
@ -1156,7 +1156,7 @@ public:
return 1; return 1;
} }
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &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::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == 1);
std::unordered_set<db::Edge> &result = results.front (); std::unordered_set<db::Edge> &result = results.front ();
@ -1211,7 +1211,7 @@ public:
return 1; return 1;
} }
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, 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::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == 1);
std::unordered_set<db::Edge> &result = results.front (); std::unordered_set<db::Edge> &result = results.front ();
@ -1310,7 +1310,7 @@ public:
return 1; return 1;
} }
virtual void compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == 1);
std::unordered_set<db::PolygonRef> &result = results.front (); std::unordered_set<db::PolygonRef> &result = results.front ();
@ -1476,7 +1476,7 @@ public:
// .. nothing yet .. // .. nothing yet ..
} }
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == 1);
std::unordered_set<db::EdgePair> &result = results.front (); std::unordered_set<db::EdgePair> &result = results.front ();

View File

@ -1429,11 +1429,20 @@ EdgePairsDelegate *
DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, const RegionCheckOptions &options) const DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, const RegionCheckOptions &options) const
{ {
const db::DeepRegion *other_deep = 0; const db::DeepRegion *other_deep = 0;
if (other) { unsigned int other_layer = 0;
bool other_is_merged = true;
if (other == subject_regionptr ()) {
other_layer = subject_idlayer ();
} else if (other == foreign_regionptr ()) {
other_layer = foreign_idlayer ();
} else {
other_deep = dynamic_cast<const db::DeepRegion *> (other->delegate ()); other_deep = dynamic_cast<const db::DeepRegion *> (other->delegate ());
if (! other_deep) { if (! other_deep) {
return db::AsIfFlatRegion::run_check (rel, different_polygons, other, d, options); return db::AsIfFlatRegion::run_check (rel, different_polygons, other, d, options);
} }
other_layer = other_deep->deep_layer ().layer ();
other_is_merged = other->is_merged ();
} }
const db::DeepLayer &polygons = merged_deep_layer (); const db::DeepLayer &polygons = merged_deep_layer ();
@ -1447,7 +1456,7 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons
std::auto_ptr<db::DeepEdgePairs> res (new db::DeepEdgePairs (polygons.derived ())); std::auto_ptr<db::DeepEdgePairs> res (new db::DeepEdgePairs (polygons.derived ()));
db::CheckLocalOperation op (check, different_polygons, other_deep != 0, other && other->is_merged (), options); db::CheckLocalOperation op (check, different_polygons, other_deep != 0, other_is_merged, options);
db::local_processor<db::PolygonRef, db::PolygonRef, db::EdgePair> proc (const_cast<db::Layout *> (&polygons.layout ()), db::local_processor<db::PolygonRef, db::PolygonRef, db::EdgePair> proc (const_cast<db::Layout *> (&polygons.layout ()),
const_cast<db::Cell *> (&polygons.initial_cell ()), const_cast<db::Cell *> (&polygons.initial_cell ()),
@ -1459,7 +1468,7 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons
proc.set_base_verbosity (base_verbosity ()); proc.set_base_verbosity (base_verbosity ());
proc.set_threads (polygons.store ()->threads ()); proc.set_threads (polygons.store ()->threads ());
proc.run (&op, polygons.layer (), other_deep ? other_deep->deep_layer ().layer () : polygons.layer (), res->deep_layer ().layer ()); proc.run (&op, polygons.layer (), other_layer, res->deep_layer ().layer ());
return res.release (); return res.release ();
} }

View File

@ -465,7 +465,7 @@ public:
return 1; return 1;
} }
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::TextRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::TextRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::TextRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::TextRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == 1);
std::unordered_set<db::TextRef> &result = results.front (); std::unordered_set<db::TextRef> &result = results.front ();
@ -564,7 +564,7 @@ public:
return 1; return 1;
} }
virtual void compute_local (db::Layout *layout, const shape_interactions<db::TextRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::TextRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == 1);
std::unordered_set<db::PolygonRef> &result = results.front (); std::unordered_set<db::PolygonRef> &result = results.front ();

View File

@ -77,6 +77,11 @@ public:
return m_interactions.end (); return m_interactions.end ();
} }
size_t num_interactions () const
{
return m_interactions.size ();
}
subject_iterator begin_subjects () const subject_iterator begin_subjects () const
{ {
return m_subject_shapes.begin (); return m_subject_shapes.begin ();
@ -87,6 +92,11 @@ public:
return m_subject_shapes.end (); return m_subject_shapes.end ();
} }
size_t num_subjects () const
{
return m_subject_shapes.size ();
}
intruder_iterator begin_intruders () const intruder_iterator begin_intruders () const
{ {
return m_intruder_shapes.begin (); return m_intruder_shapes.begin ();
@ -97,6 +107,11 @@ public:
return m_intruder_shapes.end (); return m_intruder_shapes.end ();
} }
size_t num_intruders () const
{
return m_intruder_shapes.size ();
}
bool has_intruder_shape_id (unsigned int id) const; bool has_intruder_shape_id (unsigned int id) const;
bool has_subject_shape_id (unsigned int id) const; bool has_subject_shape_id (unsigned int id) const;
void add_intruder_shape (unsigned int id, unsigned int layer, const TI &shape); void add_intruder_shape (unsigned int id, unsigned int layer, const TI &shape);

View File

@ -59,7 +59,7 @@ BoolAndOrNotLocalOperation::description () const
} }
void void
BoolAndOrNotLocalOperation::compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const BoolAndOrNotLocalOperation::do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == 1);
std::unordered_set<db::PolygonRef> &result = results.front (); std::unordered_set<db::PolygonRef> &result = results.front ();
@ -125,7 +125,7 @@ TwoBoolAndNotLocalOperation::TwoBoolAndNotLocalOperation ()
} }
void void
TwoBoolAndNotLocalOperation::compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const TwoBoolAndNotLocalOperation::do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
{ {
tl_assert (results.size () == 2); tl_assert (results.size () == 2);
@ -204,7 +204,7 @@ SelfOverlapMergeLocalOperation::SelfOverlapMergeLocalOperation (unsigned int wra
} }
void void
SelfOverlapMergeLocalOperation::compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const SelfOverlapMergeLocalOperation::do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == 1);
std::unordered_set<db::PolygonRef> &result = results.front (); std::unordered_set<db::PolygonRef> &result = results.front ();
@ -291,7 +291,7 @@ EdgeBoolAndOrNotLocalOperation::description () const
} }
void void
EdgeBoolAndOrNotLocalOperation::compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const EdgeBoolAndOrNotLocalOperation::do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == 1);
std::unordered_set<db::Edge> &result = results.front (); std::unordered_set<db::Edge> &result = results.front ();
@ -362,7 +362,7 @@ EdgeToPolygonLocalOperation::description () const
} }
void void
EdgeToPolygonLocalOperation::compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const EdgeToPolygonLocalOperation::do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == 1);
std::unordered_set<db::Edge> &result = results.front (); std::unordered_set<db::Edge> &result = results.front ();

View File

@ -89,14 +89,54 @@ public:
* @param layout The layout to which the shapes belong * @param layout The layout to which the shapes belong
* @param interactions The interaction set * @param interactions The interaction set
* @param result The container to which the results are written * @param result The container to which the results are written
*
* If the operation requests single subject mode, the interactions will be split into single subject/intruder clusters
*/ */
virtual void compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &result, size_t max_vertex_count, double area_ratio) const = 0; void compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio) const
{
if (interactions.num_subjects () <= 1 || ! requests_single_subjects ()) {
do_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
} else {
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
const TS &subject_shape = interactions.subject_shape (i->first);
shape_interactions<TS, TI> single_interactions;
if (on_empty_intruder_hint () == OnEmptyIntruderHint::Drop) {
single_interactions.add_subject_shape (i->first, subject_shape);
} else {
// this includes the subject-without-intruder "interaction"
single_interactions.add_subject (i->first, subject_shape);
}
const std::vector<unsigned int> &intruders = interactions.intruders_for (i->first);
for (typename std::vector<unsigned int>::const_iterator ii = intruders.begin (); ii != intruders.end (); ++ii) {
const std::pair<unsigned int, TI> &is = interactions.intruder_shape (*ii);
single_interactions.add_intruder_shape (*ii, is.first, is.second);
single_interactions.add_interaction (i->first, *ii);
}
do_compute_local (layout, single_interactions, results, max_vertex_count, area_ratio);
}
}
}
/** /**
* @brief Indicates the desired behaviour when a shape does not have an intruder * @brief Indicates the desired behaviour when a shape does not have an intruder
*/ */
virtual OnEmptyIntruderHint on_empty_intruder_hint () const { return Ignore; } virtual OnEmptyIntruderHint on_empty_intruder_hint () const { return Ignore; }
/**
* @brief If this method returns true, this operation requests single subjects for meal
*/
virtual bool requests_single_subjects () const { return false; }
/** /**
* @brief Gets a description text for this operation * @brief Gets a description text for this operation
*/ */
@ -107,6 +147,15 @@ public:
* A distance of means the shapes must overlap in order to interact. * A distance of means the shapes must overlap in order to interact.
*/ */
virtual db::Coord dist () const { return 0; } virtual db::Coord dist () const { return 0; }
protected:
/**
* @brief Computes the results from a given set of interacting shapes
* @param layout The layout to which the shapes belong
* @param interactions The interaction set
* @param result The container to which the results are written
*/
virtual void do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &result, size_t max_vertex_count, double area_ratio) const = 0;
}; };
/** /**
@ -118,7 +167,7 @@ class DB_PUBLIC BoolAndOrNotLocalOperation
public: public:
BoolAndOrNotLocalOperation (bool is_and); BoolAndOrNotLocalOperation (bool is_and);
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &result, size_t max_vertex_count, double area_ratio) const; virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &result, size_t max_vertex_count, double area_ratio) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const; virtual std::string description () const;
@ -138,7 +187,7 @@ class DB_PUBLIC TwoBoolAndNotLocalOperation
public: public:
TwoBoolAndNotLocalOperation (); TwoBoolAndNotLocalOperation ();
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &result, size_t max_vertex_count, double area_ratio) const; virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &result, size_t max_vertex_count, double area_ratio) const;
virtual std::string description () const; virtual std::string description () const;
}; };
@ -153,7 +202,7 @@ class DB_PUBLIC SelfOverlapMergeLocalOperation
public: public:
SelfOverlapMergeLocalOperation (unsigned int wrap_count); SelfOverlapMergeLocalOperation (unsigned int wrap_count);
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &result, size_t max_vertex_count, double area_ratio) const; virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &result, size_t max_vertex_count, double area_ratio) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const; virtual std::string description () const;
@ -170,7 +219,7 @@ class DB_PUBLIC EdgeBoolAndOrNotLocalOperation
public: public:
EdgeBoolAndOrNotLocalOperation (EdgeBoolOp op); EdgeBoolAndOrNotLocalOperation (EdgeBoolOp op);
virtual void compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &result, size_t max_vertex_count, double area_ratio) const; virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &result, size_t max_vertex_count, double area_ratio) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const; virtual std::string description () const;
@ -193,7 +242,7 @@ class DB_PUBLIC EdgeToPolygonLocalOperation
public: public:
EdgeToPolygonLocalOperation (bool outside, bool include_borders); EdgeToPolygonLocalOperation (bool outside, bool include_borders);
virtual void compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &result, size_t max_vertex_count, double area_ratio) const; virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &result, size_t max_vertex_count, double area_ratio) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const; virtual std::string description () const;

View File

@ -147,13 +147,12 @@ void insert_into_hash (std::unordered_set<T> &hash, const T &shape)
template <class TS, class TI> template <class TS, class TI>
void void
check_local_operation<TS, TI>::compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const check_local_operation<TS, TI>::do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == 1);
std::unordered_set<db::EdgePair> &result = results.front (); std::unordered_set<db::EdgePair> result;
tl_assert (result.empty ());
edge2edge_check_negative_or_positive<std::unordered_set<db::EdgePair> > edge_check (m_check, result, m_options.negative, m_different_polygons, m_has_other, m_options.shielded); edge2edge_check_negative_or_positive<std::unordered_set<db::EdgePair> > edge_check (m_check, result, m_options.negative, true, true, m_options.shielded);
poly2poly_check<TS> poly_check (edge_check); poly2poly_check<TS> poly_check (edge_check);
std::list<TS> heap; std::list<TS> heap;
@ -234,6 +233,8 @@ check_local_operation<TS, TI>::compute_local (db::Layout *layout, const shape_in
n += 2; n += 2;
} }
n = 1;
for (std::set<unsigned int>::const_iterator id = ids.begin (); id != ids.end (); ++id) { for (std::set<unsigned int>::const_iterator id = ids.begin (); id != ids.end (); ++id) {
const TI &ti = interactions.intruder_shape (*id).second; const TI &ti = interactions.intruder_shape (*id).second;
if (polygons.find (ti) == polygons.end ()) { if (polygons.find (ti) == polygons.end ()) {
@ -248,16 +249,45 @@ check_local_operation<TS, TI>::compute_local (db::Layout *layout, const shape_in
scanner.process (poly_check, m_check.distance (), db::box_convert<TS> ()); scanner.process (poly_check, m_check.distance (), db::box_convert<TS> ());
} while (edge_check.prepare_next_pass ()); } while (edge_check.prepare_next_pass ());
// now also handle the intra-polygon interactions if required
std::unordered_set<db::EdgePair> intra_polygon_result;
if (! m_different_polygons && ! m_has_other) {
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
std::list<TS> heap;
const TS &subject = interactions.subject_shape (i->first);
scanner.clear ();
scanner.insert (push_polygon_to_heap (layout, subject, heap), 0);
edge2edge_check_negative_or_positive<std::unordered_set<db::EdgePair> > edge_check_intra (m_check, intra_polygon_result, m_options.negative, false, false, m_options.shielded);
poly2poly_check<TS> poly_check_intra (edge_check_intra);
do {
scanner.process (poly_check_intra, m_check.distance (), db::box_convert<TS> ());
} while (edge_check_intra.prepare_next_pass ());
}
}
// detect and remove parts of the result which have or do not have results "opposite" // detect and remove parts of the result which have or do not have results "opposite"
// ("opposite" is defined by the projection of edges "through" the subject shape) // ("opposite" is defined by the projection of edges "through" the subject shape)
if (m_options.opposite_filter != db::NoOppositeFilter && ! result.empty ()) { if (m_options.opposite_filter != db::NoOppositeFilter && (! result.empty () || ! intra_polygon_result.empty ())) {
db::EdgeRelationFilter opp (db::WidthRelation, std::numeric_limits<db::EdgeRelationFilter::distance_type>::max (), db::Projection); db::EdgeRelationFilter opp (db::WidthRelation, std::numeric_limits<db::EdgeRelationFilter::distance_type>::max (), db::Projection);
std::vector<db::Edge> projections;
std::unordered_set<db::EdgePair> cleaned_result; std::unordered_set<db::EdgePair> cleaned_result;
// filter out opposite edges if (m_has_other) {
// filter out opposite edges: this is the case of two-layer checks where we can maintain the edge pairs but
// strip them of the filtered-out part.
std::vector<db::Edge> projections;
for (std::unordered_set<db::EdgePair>::const_iterator ep1 = result.begin (); ep1 != result.end (); ++ep1) { for (std::unordered_set<db::EdgePair>::const_iterator ep1 = result.begin (); ep1 != result.end (); ++ep1) {
projections.clear (); projections.clear ();
@ -300,8 +330,75 @@ check_local_operation<TS, TI>::compute_local (db::Layout *layout, const shape_in
} }
} else {
// this is the single-layer case where we cannot maintain the edge pairs as we don't know how the
// other side will be filtered. For the filtering we only need the first edges and both edges of the
// intra-polygon checks
std::unordered_set<db::Edge> edges;
for (std::unordered_set<db::EdgePair>::const_iterator ep = result.begin (); ep != result.end (); ++ep) {
edges.insert (ep->first ());
}
for (std::unordered_set<db::EdgePair>::const_iterator ep = intra_polygon_result.begin (); ep != intra_polygon_result.end (); ++ep) {
edges.insert (ep->first ());
edges.insert (ep->second ());
}
// filter out opposite edges
std::vector<db::Edge> projections;
for (std::unordered_set<db::Edge>::const_iterator e1 = edges.begin (); e1 != edges.end (); ++e1) {
projections.clear ();
for (std::unordered_set<db::Edge>::const_iterator e2 = edges.begin (); e2 != edges.end (); ++e2) {
if (e1 == e2) {
continue;
}
db::EdgePair ep_opp;
if (opp.check (*e1, *e2, &ep_opp)) {
bool shielded = false;
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end () && ! shielded; ++i) {
shielded = shields_interaction (ep_opp, interactions.subject_shape (i->first));
}
if (! shielded) {
projections.push_back (ep_opp.first ());
}
}
}
if (! projections.empty ()) {
db::Edges ce;
if (m_options.opposite_filter == db::OnlyOpposite) {
ce = db::Edges (*e1) & db::Edges (projections.begin (), projections.end ());
} else if (m_options.opposite_filter == db::NotOpposite) {
ce = db::Edges (*e1) - db::Edges (projections.begin (), projections.end ());
}
for (db::Edges::const_iterator re = ce.begin (); ! re.at_end (); ++re) {
cleaned_result.insert (db::EdgePair (*re, re->swapped_points ()));
}
} else if (m_options.opposite_filter == db::NotOpposite) {
cleaned_result.insert (db::EdgePair (*e1, e1->swapped_points ()));
}
}
}
result.swap (cleaned_result); result.swap (cleaned_result);
} else {
result.insert (intra_polygon_result.begin (), intra_polygon_result.end ());
} }
// implements error filtering on rectangles // implements error filtering on rectangles
@ -374,6 +471,8 @@ check_local_operation<TS, TI>::compute_local (db::Layout *layout, const shape_in
} }
} }
results.front ().insert (result.begin (), result.end ());
} }
template <class TS, class TI> template <class TS, class TI>
@ -418,7 +517,7 @@ db::Coord interacting_local_operation<TS, TI, TR>::dist () const
} }
template <class TS, class TI, class TR> template <class TS, class TI, class TR>
void interacting_local_operation<TS, TI, TR>::compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const void interacting_local_operation<TS, TI, TR>::do_compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == 1);
std::unordered_set<TR> &result = results.front (); std::unordered_set<TR> &result = results.front ();
@ -546,7 +645,7 @@ db::Coord pull_local_operation<TS, TI, TR>::dist () const
} }
template <class TS, class TI, class TR> template <class TS, class TI, class TR>
void pull_local_operation<TS, TI, TR>::compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const void pull_local_operation<TS, TI, TR>::do_compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == 1);
std::unordered_set<TR> &result = results.front (); std::unordered_set<TR> &result = results.front ();
@ -625,7 +724,7 @@ db::Coord interacting_with_edge_local_operation<TS, TI, TR>::dist () const
} }
template <class TS, class TI, class TR> template <class TS, class TI, class TR>
void interacting_with_edge_local_operation<TS, TI, TR>::compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const void interacting_with_edge_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
std::unordered_map<TR, size_t> counted_results; std::unordered_map<TR, size_t> counted_results;
bool counting = !(m_min_count == 1 && m_max_count == std::numeric_limits<size_t>::max ()); bool counting = !(m_min_count == 1 && m_max_count == std::numeric_limits<size_t>::max ());
@ -710,7 +809,7 @@ db::Coord pull_with_edge_local_operation<TS, TI, TR>::dist () const
} }
template <class TS, class TI, class TR> template <class TS, class TI, class TR>
void pull_with_edge_local_operation<TS, TI, TR>::compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const void pull_with_edge_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == 1);
std::unordered_set<TR> &result = results.front (); std::unordered_set<TR> &result = results.front ();
@ -771,7 +870,7 @@ db::Coord pull_with_text_local_operation<TS, TI, TR>::dist () const
} }
template <class TS, class TI, class TR> template <class TS, class TI, class TR>
void pull_with_text_local_operation<TS, TI, TR>::compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const void pull_with_text_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == 1);
std::unordered_set<TR> &result = results.front (); std::unordered_set<TR> &result = results.front ();
@ -840,7 +939,7 @@ db::Coord interacting_with_text_local_operation<TS, TI, TR>::dist () const
template <class TS, class TI, class TR> template <class TS, class TI, class TR>
void interacting_with_text_local_operation<TS, TI, TR>::compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const void interacting_with_text_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
std::unordered_map<TR, size_t> counted_results; std::unordered_map<TR, size_t> counted_results;
bool counting = !(m_min_count == 1 && m_max_count == std::numeric_limits<size_t>::max ()); bool counting = !(m_min_count == 1 && m_max_count == std::numeric_limits<size_t>::max ());

View File

@ -202,10 +202,9 @@ class check_local_operation
public: public:
check_local_operation (const EdgeRelationFilter &check, bool different_polygons, bool has_other, bool other_is_merged, const db::RegionCheckOptions &options); check_local_operation (const EdgeRelationFilter &check, bool different_polygons, bool has_other, bool other_is_merged, const db::RegionCheckOptions &options);
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
virtual db::Coord dist () const; virtual db::Coord dist () const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual bool requests_single_subjects () const { return true; }
virtual std::string description () const; virtual std::string description () const;
private: private:
@ -214,6 +213,8 @@ private:
bool m_has_other; bool m_has_other;
bool m_other_is_merged; bool m_other_is_merged;
db::RegionCheckOptions m_options; db::RegionCheckOptions m_options;
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
}; };
typedef check_local_operation<db::PolygonRef, db::PolygonRef> CheckLocalOperation; typedef check_local_operation<db::PolygonRef, db::PolygonRef> CheckLocalOperation;
@ -226,7 +227,7 @@ public:
interacting_local_operation (int mode, bool touching, bool inverse, size_t min_count, size_t max_count); interacting_local_operation (int mode, bool touching, bool inverse, size_t min_count, size_t max_count);
virtual db::Coord dist () const; virtual db::Coord dist () const;
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const; virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const; virtual std::string description () const;
@ -247,7 +248,7 @@ public:
pull_local_operation (int mode, bool touching); pull_local_operation (int mode, bool touching);
virtual db::Coord dist () const; virtual db::Coord dist () const;
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const; virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const; virtual std::string description () const;
@ -266,7 +267,7 @@ public:
interacting_with_edge_local_operation (bool inverse, size_t min_count, size_t max_count); interacting_with_edge_local_operation (bool inverse, size_t min_count, size_t max_count);
virtual db::Coord dist () const; virtual db::Coord dist () const;
virtual void compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const; virtual void do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const; virtual std::string description () const;
@ -285,7 +286,7 @@ public:
pull_with_edge_local_operation (); pull_with_edge_local_operation ();
virtual db::Coord dist () const; virtual db::Coord dist () const;
virtual void compute_local (db::Layout *, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const; virtual void do_compute_local (db::Layout *, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const; virtual std::string description () const;
}; };
@ -300,7 +301,7 @@ public:
interacting_with_text_local_operation (bool inverse, size_t min_count, size_t max_count); interacting_with_text_local_operation (bool inverse, size_t min_count, size_t max_count);
virtual db::Coord dist () const; virtual db::Coord dist () const;
virtual void compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const; virtual void do_compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const; virtual std::string description () const;
@ -319,7 +320,7 @@ public:
pull_with_text_local_operation (); pull_with_text_local_operation ();
virtual db::Coord dist () const; virtual db::Coord dist () const;
virtual void compute_local (db::Layout *, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const; virtual void do_compute_local (db::Layout *, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
virtual std::string description () const; virtual std::string description () const;
}; };

View File

@ -152,7 +152,6 @@ Edge2EdgeCheckBase::feed_pseudo_edges (db::box_scanner<db::Edge, size_t> &scanne
{ {
if (m_pass == 1) { if (m_pass == 1) {
for (std::set<std::pair<db::Edge, size_t> >::const_iterator e = m_pseudo_edges.begin (); e != m_pseudo_edges.end (); ++e) { for (std::set<std::pair<db::Edge, size_t> >::const_iterator e = m_pseudo_edges.begin (); e != m_pseudo_edges.end (); ++e) {
//printf("@@@ PSEUDO %s[%d]\n", e->first.to_string().c_str(), int(e->second)); fflush(stdout);
scanner.insert (&e->first, e->second); scanner.insert (&e->first, e->second);
} }
} }
@ -258,7 +257,6 @@ Edge2EdgeCheckBase::add (const db::Edge *o1, size_t p1, const db::Edge *o2, size
(m_pseudo_edges.find (std::make_pair (*o1, p1)) != m_pseudo_edges.end () || m_pseudo_edges.find (std::make_pair (*o2, p2)) != m_pseudo_edges.end ()) && (m_pseudo_edges.find (std::make_pair (*o1, p1)) != m_pseudo_edges.end () || m_pseudo_edges.find (std::make_pair (*o2, p2)) != m_pseudo_edges.end ()) &&
! (m_pseudo_edges.find (std::make_pair (*o1, p1)) != m_pseudo_edges.end () && m_pseudo_edges.find (std::make_pair (*o2, p2)) != m_pseudo_edges.end ())) { ! (m_pseudo_edges.find (std::make_pair (*o1, p1)) != m_pseudo_edges.end () && m_pseudo_edges.find (std::make_pair (*o2, p2)) != m_pseudo_edges.end ())) {
//printf("@@@ PASS %d -> %s[%d] x %s[%d]\n", m_pass, o1->to_string().c_str(), int(p1), o2->to_string().c_str(), int(p2)); fflush(stdout);
// Overlap or inside checks require input from different layers // Overlap or inside checks require input from different layers
if ((! m_different_polygons || p1 != p2) && (! m_requires_different_layers || ((p1 ^ p2) & 1) != 0)) { if ((! m_different_polygons || p1 != p2) && (! m_requires_different_layers || ((p1 ^ p2) & 1) != 0)) {
@ -271,7 +269,6 @@ Edge2EdgeCheckBase::add (const db::Edge *o1, size_t p1, const db::Edge *o2, size
std::swap (o1, o2); std::swap (o1, o2);
std::swap (p1, p2); std::swap (p1, p2);
} }
//printf("@@@1\n"); fflush(stdout);
db::EdgePair ep; db::EdgePair ep;
if (mp_check->check (*o1, *o2, &ep)) { if (mp_check->check (*o1, *o2, &ep)) {
@ -280,7 +277,6 @@ Edge2EdgeCheckBase::add (const db::Edge *o1, size_t p1, const db::Edge *o2, size
m_ep.push_back (ep); m_ep.push_back (ep);
m_e2ep.insert (std::make_pair (std::make_pair (*o1, p1), n * 2)); m_e2ep.insert (std::make_pair (std::make_pair (*o1, p1), n * 2));
m_e2ep.insert (std::make_pair (std::make_pair (*o2, p2), n * 2 + 1)); m_e2ep.insert (std::make_pair (std::make_pair (*o2, p2), n * 2 + 1));
//printf("@@@ CANCEL %s\n", ep.to_string().c_str()); fflush(stdout);
} }

View File

@ -418,14 +418,25 @@ static db::CompoundRegionOperationNode *new_width_check (db::Coord d, bool whole
return new db::CompoundRegionToEdgePairProcessingOperationNode (new db::SinglePolygonCheck (db::WidthRelation, d, options), new_primary (), true /*processor is owned*/); return new db::CompoundRegionToEdgePairProcessingOperationNode (new db::SinglePolygonCheck (db::WidthRelation, d, options), new_primary (), true /*processor is owned*/);
} }
static db::CompoundRegionOperationNode *new_space_or_isolated_check (db::Coord d, bool whole_edges, db::metrics_type metrics, const tl::Variant &ignore_angle, const tl::Variant &min_projection, const tl::Variant &max_projection, bool shielded, db::OppositeFilter opposite_filter, db::RectFilter rect_filter, bool negative, bool isolated)
{
if (opposite_filter != db::NoOppositeFilter || rect_filter != db::NoSideAllowed) {
// NOTE: we have to use the "foreign" scheme with a filter because only this scheme
// guarantees that all subject shapes are visited and receive all intruders.
return new_check_node (new_foreign (), db::SpaceRelation, isolated, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter, negative);
} else {
return new_check_node (db::SpaceRelation, isolated, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter, negative);
}
}
static db::CompoundRegionOperationNode *new_space_check (db::Coord d, bool whole_edges, db::metrics_type metrics, const tl::Variant &ignore_angle, const tl::Variant &min_projection, const tl::Variant &max_projection, bool shielded, db::OppositeFilter opposite_filter, db::RectFilter rect_filter, bool negative) static db::CompoundRegionOperationNode *new_space_check (db::Coord d, bool whole_edges, db::metrics_type metrics, const tl::Variant &ignore_angle, const tl::Variant &min_projection, const tl::Variant &max_projection, bool shielded, db::OppositeFilter opposite_filter, db::RectFilter rect_filter, bool negative)
{ {
return new_check_node (db::SpaceRelation, false, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter, negative); return new_space_or_isolated_check (d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter, negative, false);
} }
static db::CompoundRegionOperationNode *new_isolated_check (db::Coord d, bool whole_edges, db::metrics_type metrics, const tl::Variant &ignore_angle, const tl::Variant &min_projection, const tl::Variant &max_projection, bool shielded, db::OppositeFilter opposite_filter, db::RectFilter rect_filter, bool negative) static db::CompoundRegionOperationNode *new_isolated_check (db::Coord d, bool whole_edges, db::metrics_type metrics, const tl::Variant &ignore_angle, const tl::Variant &min_projection, const tl::Variant &max_projection, bool shielded, db::OppositeFilter opposite_filter, db::RectFilter rect_filter, bool negative)
{ {
return new_check_node (db::SpaceRelation, true, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter, negative); return new_space_or_isolated_check (d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter, negative, true);
} }
static db::CompoundRegionOperationNode *new_notch_check (db::Coord d, bool whole_edges, db::metrics_type metrics, const tl::Variant &ignore_angle, const tl::Variant &min_projection, const tl::Variant &max_projection, bool shielded, bool negative) static db::CompoundRegionOperationNode *new_notch_check (db::Coord d, bool whole_edges, db::metrics_type metrics, const tl::Variant &ignore_angle, const tl::Variant &min_projection, const tl::Variant &max_projection, bool shielded, bool negative)

View File

@ -60,7 +60,7 @@ public:
// .. nothing yet .. // .. nothing yet ..
} }
virtual void compute_local (db::Layout *layout, const db::shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const virtual void do_compute_local (db::Layout *layout, const db::shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
{ {
db::shape_interactions<db::PolygonRef, db::PolygonRef> sized_interactions = interactions; db::shape_interactions<db::PolygonRef, db::PolygonRef> sized_interactions = interactions;
for (db::shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) { for (db::shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) {
@ -72,7 +72,7 @@ public:
} }
} }
BoolAndOrNotLocalOperation::compute_local (layout, sized_interactions, results, max_vertex_count, area_ratio); BoolAndOrNotLocalOperation::do_compute_local (layout, sized_interactions, results, max_vertex_count, area_ratio);
} }
db::Coord dist () const db::Coord dist () const
@ -97,7 +97,7 @@ public:
// .. nothing yet .. // .. nothing yet ..
} }
virtual void compute_local (db::Layout *layout, const db::shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const virtual void do_compute_local (db::Layout *layout, const db::shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
{ {
db::shape_interactions<db::PolygonRef, db::PolygonRef> sized_interactions = interactions; db::shape_interactions<db::PolygonRef, db::PolygonRef> sized_interactions = interactions;
for (db::shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) { for (db::shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) {
@ -118,7 +118,7 @@ public:
} }
SelfOverlapMergeLocalOperation::compute_local (layout, sized_interactions, results, max_vertex_count, area_ratio); SelfOverlapMergeLocalOperation::do_compute_local (layout, sized_interactions, results, max_vertex_count, area_ratio);
} }
db::Coord dist () const db::Coord dist () const

View File

@ -28,7 +28,7 @@
#include "lymMacro.h" #include "lymMacro.h"
#include "tlFileUtils.h" #include "tlFileUtils.h"
static void runTest (tl::TestBase *_this, const std::string &number, bool deep) static void run_test (tl::TestBase *_this, const std::string &number, bool deep)
{ {
std::string rs = tl::testsrc (); std::string rs = tl::testsrc ();
rs += "/testdata/drc/drcGenericTests_" + number + ".drc"; rs += "/testdata/drc/drcGenericTests_" + number + ".drc";
@ -71,20 +71,20 @@ static void runTest (tl::TestBase *_this, const std::string &number, bool deep)
TEST(1) TEST(1)
{ {
runTest (_this, "1", false); run_test (_this, "1", false);
} }
TEST(1d) TEST(1d)
{ {
runTest (_this, "1", true); run_test (_this, "1", true);
} }
TEST(2) TEST(2)
{ {
runTest (_this, "2", false); run_test (_this, "2", false);
} }
TEST(2d) TEST(2d)
{ {
runTest (_this, "2", true); run_test (_this, "2", true);
} }

View File

@ -1077,3 +1077,53 @@ TEST(24_enclosing)
db::compare_layouts (_this, layout, au, db::NoNormalization); db::compare_layouts (_this, layout, au, db::NoNormalization);
} }
static void run_test (tl::TestBase *_this, const std::string &number, bool deep)
{
std::string rs = tl::testsrc ();
rs += "/testdata/drc/drcSimpleTests_" + number + ".drc";
std::string input = tl::testsrc ();
input += "/testdata/drc/drcSimpleTests_" + number + ".gds";
std::string au = tl::testsrc ();
au += "/testdata/drc/drcSimpleTests_au" + number + std::string (deep ? "d" : "") + ".gds";
std::string output = _this->tmp_file ("tmp.gds");
{
// Set some variables
lym::Macro config;
config.set_text (tl::sprintf (
"$drc_test_source = '%s'\n"
"$drc_test_target = '%s'\n"
"$drc_test_deep = %s\n"
, input, output, deep ? "true" : "false")
);
config.set_interpreter (lym::Macro::Ruby);
EXPECT_EQ (config.run (), 0);
}
lym::Macro drc;
drc.load_from (rs);
EXPECT_EQ (drc.run (), 0);
db::Layout layout;
{
tl::InputStream stream (output);
db::Reader reader (stream);
reader.read (layout);
}
db::compare_layouts (_this, layout, au, db::NoNormalization);
}
TEST(25_spaceWithOptions)
{
run_test (_this, "25", false);
}
TEST(25d_spaceWithOptions)
{
run_test (_this, "25", true);
}

View File

@ -21,7 +21,8 @@ l1.drc(space(projection) < 1.0).polygons.output(100, 0)
l1.drc(space(euclidian) < 1.0).polygons.output(110, 0) l1.drc(space(euclidian) < 1.0).polygons.output(110, 0)
l1.drc(space(projection, projection_limits(0..2.0)) < 1.0).polygons.output(111, 0) l1.drc(space(projection, projection_limits(0..2.0)) < 1.0).polygons.output(111, 0)
l1.drc(space(projection, whole_edges) < 1.0).polygons.output(112, 0) l1.drc(space(projection, whole_edges) < 1.0).polygons.output(112, 0)
l1.drc(separation(foreign, projection, only_opposite) < 1.0).polygons.output(113, 0) l1.drc(space(projection, only_opposite) < 1.0).output(113, 0)
l1.drc(space(projection, not_opposite) < 1.0).output(114, 0)
# notch # notch
l1.drc(notch(projection) <= 1.0).polygons.output(120, 0) l1.drc(notch(projection) <= 1.0).polygons.output(120, 0)
@ -33,7 +34,11 @@ l1.drc(separation(projection, l2) < 1.0).polygons.output(132, 0)
l1.drc(sep(projection, l2) < 1.0).polygons.output(133, 0) l1.drc(sep(projection, l2) < 1.0).polygons.output(133, 0)
# isolation # isolation
l1.drc(isolated(projection) < 1.0).polygons.output(140, 0) l1.drc(isolated(euclidian) < 1.0).polygons.output(140, 0)
l1.drc(isolated(projection, projection_limits(0..2.0)) < 1.0).polygons.output(141, 0)
l1.drc(isolated(projection, whole_edges) < 1.0).polygons.output(142, 0)
l1.drc(isolated(projection, only_opposite) < 1.0).output(143, 0)
l1.drc(isolated(projection, not_opposite) < 1.0).output(144, 0)
# enclosing, overlap # enclosing, overlap
l2.drc(enclosing(l1, projection) < 1.0).polygons.output(150, 0) l2.drc(enclosing(l1, projection) < 1.0).polygons.output(150, 0)

Binary file not shown.

Binary file not shown.

Binary file not shown.