mirror of https://github.com/KLayout/klayout.git
First attempt to implement DRC checks without merging - still required with certain options and not enabled to generic DRC function yet.
This commit is contained in:
parent
959b5fe799
commit
1930018f8f
|
|
@ -1037,7 +1037,10 @@ AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons,
|
|||
{
|
||||
#if defined(USE_LOCAL_PROCESSOR)
|
||||
|
||||
db::RegionIterator polygons (begin_merged ());
|
||||
bool needs_merged_primary = different_polygons || options.needs_merged ();
|
||||
|
||||
db::RegionIterator polygons (needs_merged_primary ? begin_merged () : begin ());
|
||||
bool primary_is_merged = ! merged_semantics () || needs_merged_primary || is_merged ();
|
||||
|
||||
EdgeRelationFilter check (rel, d, options.metrics);
|
||||
check.set_include_zero (false);
|
||||
|
|
@ -1059,9 +1062,12 @@ AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons,
|
|||
if (other == subject_regionptr () || other == foreign_regionptr ()) {
|
||||
foreign.push_back (other == foreign_regionptr ());
|
||||
others.push_back (begin_merged ());
|
||||
other_is_merged = primary_is_merged;
|
||||
} else {
|
||||
foreign.push_back (false);
|
||||
if (options.whole_edges) {
|
||||
if (! other->merged_semantics ()) {
|
||||
other_is_merged = true;
|
||||
} else if (options.whole_edges) {
|
||||
// NOTE: whole edges needs both inputs merged
|
||||
others.push_back (other->begin_merged ());
|
||||
other_is_merged = true;
|
||||
|
|
@ -1072,7 +1078,7 @@ AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons,
|
|||
has_other = true;
|
||||
}
|
||||
|
||||
db::check_local_operation<db::Polygon, db::Polygon> op (check, different_polygons, has_other, other_is_merged, options);
|
||||
db::check_local_operation<db::Polygon, db::Polygon> op (check, different_polygons, primary_is_merged, has_other, other_is_merged, options);
|
||||
|
||||
std::unique_ptr<FlatEdgePairs> output (new FlatEdgePairs ());
|
||||
std::vector<db::Shapes *> results;
|
||||
|
|
|
|||
|
|
@ -1555,10 +1555,13 @@ CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegi
|
|||
m_check.set_max_projection (options.max_projection);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
tl_assert (input == 0); // input is a dummy parameter
|
||||
|
||||
m_has_other = other->has_external_inputs ();
|
||||
// @@@ needs a concept to deal with merged/non-merged inputs
|
||||
m_is_other_merged = other->is_merged ();
|
||||
|
||||
set_description ("check");
|
||||
|
|
@ -1585,7 +1588,9 @@ CompoundRegionCheckOperationNode::computed_dist () const
|
|||
void
|
||||
CompoundRegionCheckOperationNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, 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
|
||||
{
|
||||
db::check_local_operation<db::Polygon, db::Polygon> op (m_check, m_different_polygons, m_has_other, m_is_other_merged, m_options);
|
||||
// @@@ needs a concept to deal with merged/non-merged primary
|
||||
bool is_merged = true;
|
||||
db::check_local_operation<db::Polygon, db::Polygon> op (m_check, m_different_polygons, is_merged, m_has_other, m_is_other_merged, m_options);
|
||||
|
||||
tl_assert (results.size () == 1);
|
||||
if (results.front ().empty ()) {
|
||||
|
|
@ -1601,7 +1606,9 @@ CompoundRegionCheckOperationNode::do_compute_local (CompoundRegionOperationCache
|
|||
void
|
||||
CompoundRegionCheckOperationNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, 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
|
||||
{
|
||||
db::check_local_operation<db::PolygonRef, db::PolygonRef> op (m_check, m_different_polygons, m_has_other, m_is_other_merged, m_options);
|
||||
// @@@ needs a concept to deal with merged/non-merged primary
|
||||
bool is_merged = true;
|
||||
db::check_local_operation<db::PolygonRef, db::PolygonRef> op (m_check, m_different_polygons, is_merged, m_has_other, m_is_other_merged, m_options);
|
||||
|
||||
tl_assert (results.size () == 1);
|
||||
if (results.front ().empty ()) {
|
||||
|
|
|
|||
|
|
@ -1647,16 +1647,23 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons
|
|||
unsigned int other_layer = 0;
|
||||
bool other_is_merged = true;
|
||||
|
||||
bool needs_merged_primary = different_polygons || options.needs_merged ();
|
||||
bool primary_is_merged = ! merged_semantics () || needs_merged_primary || is_merged ();
|
||||
|
||||
if (other == subject_regionptr ()) {
|
||||
other_layer = subject_idlayer ();
|
||||
other_is_merged = primary_is_merged;
|
||||
} else if (other == foreign_regionptr ()) {
|
||||
other_layer = foreign_idlayer ();
|
||||
other_is_merged = primary_is_merged;
|
||||
} else {
|
||||
other_deep = dynamic_cast<const db::DeepRegion *> (other->delegate ());
|
||||
if (! other_deep) {
|
||||
return db::AsIfFlatRegion::run_check (rel, different_polygons, other, d, options);
|
||||
}
|
||||
if (options.whole_edges) {
|
||||
if (! other->merged_semantics ()) {
|
||||
other_is_merged = true;
|
||||
} else if (options.whole_edges) {
|
||||
// NOTE: whole edges needs both inputs merged
|
||||
other_layer = other_deep->merged_deep_layer ().layer ();
|
||||
other_is_merged = true;
|
||||
|
|
@ -1666,7 +1673,7 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons
|
|||
}
|
||||
}
|
||||
|
||||
const db::DeepLayer &polygons = merged_deep_layer ();
|
||||
const db::DeepLayer &polygons = needs_merged_primary ? merged_deep_layer () : deep_layer ();
|
||||
|
||||
EdgeRelationFilter check (rel, d, options.metrics);
|
||||
check.set_include_zero (false);
|
||||
|
|
@ -1677,7 +1684,7 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons
|
|||
|
||||
std::unique_ptr<db::DeepEdgePairs> res (new db::DeepEdgePairs (polygons.derived ()));
|
||||
|
||||
db::CheckLocalOperation op (check, different_polygons, other_deep != 0, other_is_merged, options);
|
||||
db::CheckLocalOperation op (check, different_polygons, primary_is_merged, other_deep != 0, other_is_merged, options);
|
||||
|
||||
db::local_processor<db::PolygonRef, db::PolygonRef, db::EdgePair> proc (const_cast<db::Layout *> (&polygons.layout ()),
|
||||
const_cast<db::Cell *> (&polygons.initial_cell ()),
|
||||
|
|
|
|||
|
|
@ -122,8 +122,8 @@ static bool shields_interaction (const db::EdgePair &ep, const P &poly)
|
|||
}
|
||||
|
||||
template <class TS, class TI>
|
||||
check_local_operation<TS, TI>::check_local_operation (const EdgeRelationFilter &check, bool different_polygons, bool has_other, bool other_is_merged, const db::RegionCheckOptions &options)
|
||||
: m_check (check), m_different_polygons (different_polygons), m_has_other (has_other), m_other_is_merged (other_is_merged), m_options (options)
|
||||
check_local_operation<TS, TI>::check_local_operation (const EdgeRelationFilter &check, bool different_polygons, bool is_merged, bool has_other, bool other_is_merged, const db::RegionCheckOptions &options)
|
||||
: m_check (check), m_different_polygons (different_polygons), m_is_merged (is_merged), m_has_other (has_other), m_other_is_merged (other_is_merged), m_options (options)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -210,6 +210,10 @@ check_local_operation<TS, TI>::do_compute_local (db::Layout *layout, const shape
|
|||
|
||||
std::list<TS> heap;
|
||||
std::unordered_set<TI> polygons;
|
||||
std::unordered_set<TS> spolygons;
|
||||
|
||||
db::EdgeProcessor ep;
|
||||
ep.set_base_verbosity (50);
|
||||
|
||||
std::set<unsigned int> ids;
|
||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
|
|
@ -245,14 +249,50 @@ check_local_operation<TS, TI>::do_compute_local (db::Layout *layout, const shape
|
|||
if (m_has_other) {
|
||||
|
||||
size_t n = 0;
|
||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const TS &subject = interactions.subject_shape (i->first);
|
||||
if (! take_all) {
|
||||
poly_check.enter (subject, n, common_box);
|
||||
} else {
|
||||
poly_check.enter (subject, n);
|
||||
|
||||
if (m_is_merged) {
|
||||
|
||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const TS &subject = interactions.subject_shape (i->first);
|
||||
if (! take_all) {
|
||||
poly_check.enter (subject, n, common_box);
|
||||
} else {
|
||||
poly_check.enter (subject, n);
|
||||
}
|
||||
n += 2;
|
||||
}
|
||||
n += 2;
|
||||
|
||||
} else {
|
||||
|
||||
// merge needed for the subject shapes
|
||||
|
||||
ep.clear ();
|
||||
size_t nn = 0;
|
||||
|
||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const TS &is = interactions.subject_shape (i->first);
|
||||
for (typename TS::polygon_edge_iterator e = is.begin_edge (); ! e.at_end (); ++e) {
|
||||
ep.insert (*e, nn);
|
||||
}
|
||||
++nn;
|
||||
}
|
||||
|
||||
spolygons.clear ();
|
||||
|
||||
db::polygon_ref_generator<TS> ps (layout, spolygons);
|
||||
db::PolygonGenerator pg (ps, false /*don't resolve holes*/, false);
|
||||
db::SimpleMerge op (1 /*wc>0*/);
|
||||
ep.process (pg, op);
|
||||
|
||||
for (typename std::unordered_set<TS>::const_iterator o = spolygons.begin (); o != spolygons.end (); ++o) {
|
||||
if (! take_all) {
|
||||
poly_check.enter (*o, n, common_box);
|
||||
} else {
|
||||
poly_check.enter (*o, n);
|
||||
}
|
||||
n += 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// merge the intruders to remove inner edges
|
||||
|
|
@ -266,18 +306,16 @@ check_local_operation<TS, TI>::do_compute_local (db::Layout *layout, const shape
|
|||
// NOTE: this local merge is not necessarily giving the same results than a global merge before running
|
||||
// the processor. Reason: the search range is limited, hence not all necessary components may have been
|
||||
// captured.
|
||||
db::EdgeProcessor ep;
|
||||
ep.set_base_verbosity (50);
|
||||
|
||||
ep.clear ();
|
||||
size_t i = 0;
|
||||
size_t nn = 0;
|
||||
|
||||
for (std::set<unsigned int>::const_iterator id = ids.begin (); id != ids.end (); ++id) {
|
||||
const TI &is = interactions.intruder_shape (*id).second;
|
||||
for (typename TI::polygon_edge_iterator e = is.begin_edge (); ! e.at_end (); ++e) {
|
||||
ep.insert (*e, i);
|
||||
ep.insert (*e, nn);
|
||||
}
|
||||
++i;
|
||||
++nn;
|
||||
}
|
||||
|
||||
polygons.clear ();
|
||||
|
|
@ -317,30 +355,71 @@ check_local_operation<TS, TI>::do_compute_local (db::Layout *layout, const shape
|
|||
|
||||
size_t n = 0;
|
||||
|
||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
// we can't directly insert because TS may be != TI
|
||||
const TS &ts = interactions.subject_shape (i->first);
|
||||
insert_into_hash (polygons, ts);
|
||||
if (! take_all) {
|
||||
poly_check.enter (ts, n, common_box);
|
||||
} else {
|
||||
poly_check.enter (ts, n);
|
||||
}
|
||||
n += 2;
|
||||
}
|
||||
if (m_is_merged) {
|
||||
|
||||
n = 1;
|
||||
|
||||
for (std::set<unsigned int>::const_iterator id = ids.begin (); id != ids.end (); ++id) {
|
||||
const TI &ti = interactions.intruder_shape (*id).second;
|
||||
if (polygons.find (ti) == polygons.end ()) {
|
||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
// we can't directly insert because TS may be != TI
|
||||
const TS &ts = interactions.subject_shape (i->first);
|
||||
insert_into_hash (polygons, ts);
|
||||
if (! take_all) {
|
||||
poly_check.enter (ti, n, common_box);
|
||||
poly_check.enter (ts, n, common_box);
|
||||
} else {
|
||||
poly_check.enter (ti, n);
|
||||
poly_check.enter (ts, n);
|
||||
}
|
||||
n += 2;
|
||||
++n;
|
||||
}
|
||||
|
||||
for (std::set<unsigned int>::const_iterator id = ids.begin (); id != ids.end (); ++id) {
|
||||
const TI &ti = interactions.intruder_shape (*id).second;
|
||||
if (polygons.find (ti) == polygons.end ()) {
|
||||
if (! take_all) {
|
||||
poly_check.enter (ti, n, common_box);
|
||||
} else {
|
||||
poly_check.enter (ti, n);
|
||||
}
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// merge needed for the subject shapes
|
||||
|
||||
ep.clear ();
|
||||
size_t nn = 0;
|
||||
|
||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const TS &ts = interactions.subject_shape (i->first);
|
||||
for (typename TS::polygon_edge_iterator e = ts.begin_edge (); ! e.at_end (); ++e) {
|
||||
ep.insert (*e, nn);
|
||||
}
|
||||
++nn;
|
||||
}
|
||||
|
||||
for (std::set<unsigned int>::const_iterator id = ids.begin (); id != ids.end (); ++id) {
|
||||
const TI &ti = interactions.intruder_shape (*id).second;
|
||||
for (typename TI::polygon_edge_iterator e = ti.begin_edge (); ! e.at_end (); ++e) {
|
||||
ep.insert (*e, nn);
|
||||
}
|
||||
++nn;
|
||||
}
|
||||
|
||||
spolygons.clear ();
|
||||
|
||||
db::polygon_ref_generator<TS> ps (layout, spolygons);
|
||||
db::PolygonGenerator pg (ps, false /*don't resolve holes*/, false);
|
||||
db::SimpleMerge op (1 /*wc>0*/);
|
||||
ep.process (pg, op);
|
||||
|
||||
for (typename std::unordered_set<TS>::const_iterator o = spolygons.begin (); o != spolygons.end (); ++o) {
|
||||
if (! take_all) {
|
||||
poly_check.enter (*o, n, common_box);
|
||||
} else {
|
||||
poly_check.enter (*o, n);
|
||||
}
|
||||
++n;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -197,6 +197,19 @@ struct DB_PUBLIC RegionCheckOptions
|
|||
* @brief Specifies whether to produce negative output
|
||||
*/
|
||||
bool negative;
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether merged primary input is required
|
||||
*/
|
||||
bool needs_merged () const
|
||||
{
|
||||
return negative
|
||||
|| rect_filter != NoRectFilter
|
||||
|| opposite_filter != NoOppositeFilter
|
||||
|| max_projection != std::numeric_limits<distance_type>::max ()
|
||||
|| min_projection != 0
|
||||
|| whole_edges;
|
||||
}
|
||||
};
|
||||
|
||||
template <class TS, class TI>
|
||||
|
|
@ -204,7 +217,7 @@ class check_local_operation
|
|||
: public local_operation<TS, TI, db::EdgePair>
|
||||
{
|
||||
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 is_merged, bool has_other, bool other_is_merged, const db::RegionCheckOptions &options);
|
||||
|
||||
virtual db::Coord dist () const;
|
||||
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
|
||||
|
|
@ -216,6 +229,7 @@ public:
|
|||
private:
|
||||
EdgeRelationFilter m_check;
|
||||
bool m_different_polygons;
|
||||
bool m_is_merged;
|
||||
bool m_has_other;
|
||||
bool m_other_is_merged;
|
||||
db::RegionCheckOptions m_options;
|
||||
|
|
|
|||
|
|
@ -390,7 +390,7 @@ static db::CompoundRegionOperationNode *new_edge_pair_to_second_edges (db::Compo
|
|||
static db::CompoundRegionOperationNode *new_check_node (db::CompoundRegionOperationNode *other, db::edge_relation_type rel, bool different_polygons, 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)
|
||||
{
|
||||
check_non_null (other, "other");
|
||||
return new db::CompoundRegionCheckOperationNode (new_primary (), other, rel, different_polygons, d,
|
||||
return new db::CompoundRegionCheckOperationNode (0, other, rel, different_polygons, d,
|
||||
db::RegionCheckOptions (whole_edges,
|
||||
metrics,
|
||||
ignore_angle.is_nil () ? 90 : ignore_angle.to_double (),
|
||||
|
|
|
|||
Loading…
Reference in New Issue