mirror of https://github.com/KLayout/klayout.git
WIP: some development, bugfixing on DRC implementation - mainly about correct opposite filter operation
This commit is contained in:
parent
9c95bed67e
commit
d1868a4b23
|
|
@ -1093,6 +1093,66 @@ AsIfFlatRegion::cop_to_edges (db::CompoundRegionOperationNode &node)
|
|||
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 *
|
||||
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_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;
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
|
||||
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::vector<db::Shapes *> results;
|
||||
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 ();
|
||||
|
||||
|
|
|
|||
|
|
@ -60,45 +60,14 @@ public:
|
|||
virtual RegionDelegate *cop_to_region (db::CompoundRegionOperationNode &node);
|
||||
virtual EdgesDelegate *cop_to_edges (db::CompoundRegionOperationNode &node);
|
||||
|
||||
EdgePairsDelegate *width_check (db::Coord d, const RegionCheckOptions &options) const
|
||||
{
|
||||
return run_single_polygon_check (db::WidthRelation, d, options);
|
||||
}
|
||||
|
||||
EdgePairsDelegate *space_check (db::Coord d, const RegionCheckOptions &options) const
|
||||
{
|
||||
return run_check (db::SpaceRelation, false, 0, d, options);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
EdgePairsDelegate *width_check (db::Coord d, const RegionCheckOptions &options) const;
|
||||
EdgePairsDelegate *space_check (db::Coord d, const RegionCheckOptions &options) const;
|
||||
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 *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;
|
||||
EdgePairsDelegate *inside_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const;
|
||||
|
||||
virtual EdgePairsDelegate *grid_check (db::Coord gx, db::Coord gy) const;
|
||||
virtual EdgePairsDelegate *angle_check (double min, double max, bool inverse) const;
|
||||
|
|
@ -298,6 +267,7 @@ private:
|
|||
|
||||
virtual db::Box compute_bbox () const;
|
||||
static RegionDelegate *region_from_box (const db::Box &b);
|
||||
EdgePairsDelegate *space_or_isolated_check (db::Coord d, const RegionCheckOptions &options, bool isolated) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
: 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");
|
||||
|
||||
|
|
@ -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)
|
||||
: 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");
|
||||
|
||||
|
|
@ -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)
|
||||
: 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");
|
||||
|
||||
m_check.set_include_zero (false);
|
||||
|
|
@ -1525,7 +1537,7 @@ CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegi
|
|||
db::OnEmptyIntruderHint
|
||||
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
|
||||
|
|
@ -1543,9 +1555,7 @@ CompoundRegionCheckOperationNode::wants_merged () const
|
|||
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
|
||||
{
|
||||
bool other_merged = (children () > 0 && is_subject_regionptr (inputs ()[0]));
|
||||
|
||||
db::check_local_operation<db::Polygon, db::Polygon> op (m_check, m_different_polygons, children () > 0, other_merged, m_options);
|
||||
db::check_local_operation<db::Polygon, db::Polygon> op (m_check, m_different_polygons, m_has_other, m_is_other_merged, m_options);
|
||||
|
||||
tl_assert (results.size () == 1);
|
||||
if (results.front ().empty ()) {
|
||||
|
|
@ -1561,9 +1571,7 @@ CompoundRegionCheckOperationNode::do_compute_local (db::Layout *layout, const sh
|
|||
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
|
||||
{
|
||||
bool other_merged = (children () > 0 && is_subject_regionptr (inputs ()[0]));
|
||||
|
||||
db::check_local_operation<db::PolygonRef, db::PolygonRef> op (m_check, m_different_polygons, children () > 0, other_merged, m_options);
|
||||
db::check_local_operation<db::PolygonRef, db::PolygonRef> op (m_check, m_different_polygons, m_has_other, m_is_other_merged, m_options);
|
||||
|
||||
tl_assert (results.size () == 1);
|
||||
if (results.front ().empty ()) {
|
||||
|
|
|
|||
|
|
@ -1410,6 +1410,8 @@ private:
|
|||
db::EdgeRelationFilter m_check;
|
||||
bool m_different_polygons;
|
||||
db::RegionCheckOptions m_options;
|
||||
bool m_has_other;
|
||||
bool m_is_other_merged;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1435,35 +1437,14 @@ public:
|
|||
{ }
|
||||
|
||||
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) {
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
mp_node->compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
virtual db::Coord dist () const { return mp_node->dist (); }
|
||||
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 (); }
|
||||
|
||||
const TransformationReducer *vars () const { return mp_node->vars (); }
|
||||
|
|
|
|||
|
|
@ -1078,7 +1078,7 @@ public:
|
|||
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);
|
||||
std::unordered_set<db::Edge> &result = results.front ();
|
||||
|
|
@ -1156,7 +1156,7 @@ public:
|
|||
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);
|
||||
std::unordered_set<db::Edge> &result = results.front ();
|
||||
|
|
@ -1211,7 +1211,7 @@ public:
|
|||
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);
|
||||
std::unordered_set<db::Edge> &result = results.front ();
|
||||
|
|
@ -1310,7 +1310,7 @@ public:
|
|||
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);
|
||||
std::unordered_set<db::PolygonRef> &result = results.front ();
|
||||
|
|
@ -1476,7 +1476,7 @@ public:
|
|||
// .. 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);
|
||||
std::unordered_set<db::EdgePair> &result = results.front ();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
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 ());
|
||||
if (! other_deep) {
|
||||
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 ();
|
||||
|
|
@ -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 ()));
|
||||
|
||||
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 ()),
|
||||
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_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 ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -465,7 +465,7 @@ public:
|
|||
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);
|
||||
std::unordered_set<db::TextRef> &result = results.front ();
|
||||
|
|
@ -564,7 +564,7 @@ public:
|
|||
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);
|
||||
std::unordered_set<db::PolygonRef> &result = results.front ();
|
||||
|
|
|
|||
|
|
@ -77,6 +77,11 @@ public:
|
|||
return m_interactions.end ();
|
||||
}
|
||||
|
||||
size_t num_interactions () const
|
||||
{
|
||||
return m_interactions.size ();
|
||||
}
|
||||
|
||||
subject_iterator begin_subjects () const
|
||||
{
|
||||
return m_subject_shapes.begin ();
|
||||
|
|
@ -87,6 +92,11 @@ public:
|
|||
return m_subject_shapes.end ();
|
||||
}
|
||||
|
||||
size_t num_subjects () const
|
||||
{
|
||||
return m_subject_shapes.size ();
|
||||
}
|
||||
|
||||
intruder_iterator begin_intruders () const
|
||||
{
|
||||
return m_intruder_shapes.begin ();
|
||||
|
|
@ -97,6 +107,11 @@ public:
|
|||
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_subject_shape_id (unsigned int id) const;
|
||||
void add_intruder_shape (unsigned int id, unsigned int layer, const TI &shape);
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ BoolAndOrNotLocalOperation::description () const
|
|||
}
|
||||
|
||||
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);
|
||||
std::unordered_set<db::PolygonRef> &result = results.front ();
|
||||
|
|
@ -125,7 +125,7 @@ TwoBoolAndNotLocalOperation::TwoBoolAndNotLocalOperation ()
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
|
|
@ -204,7 +204,7 @@ SelfOverlapMergeLocalOperation::SelfOverlapMergeLocalOperation (unsigned int wra
|
|||
}
|
||||
|
||||
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);
|
||||
std::unordered_set<db::PolygonRef> &result = results.front ();
|
||||
|
|
@ -291,7 +291,7 @@ EdgeBoolAndOrNotLocalOperation::description () const
|
|||
}
|
||||
|
||||
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);
|
||||
std::unordered_set<db::Edge> &result = results.front ();
|
||||
|
|
@ -362,7 +362,7 @@ EdgeToPolygonLocalOperation::description () const
|
|||
}
|
||||
|
||||
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);
|
||||
std::unordered_set<db::Edge> &result = results.front ();
|
||||
|
|
|
|||
|
|
@ -89,14 +89,54 @@ public:
|
|||
* @param layout The layout to which the shapes belong
|
||||
* @param interactions The interaction set
|
||||
* @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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
|
|
@ -107,6 +147,15 @@ public:
|
|||
* A distance of means the shapes must overlap in order to interact.
|
||||
*/
|
||||
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:
|
||||
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 std::string description () const;
|
||||
|
||||
|
|
@ -138,7 +187,7 @@ class DB_PUBLIC TwoBoolAndNotLocalOperation
|
|||
public:
|
||||
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;
|
||||
};
|
||||
|
||||
|
|
@ -153,7 +202,7 @@ class DB_PUBLIC SelfOverlapMergeLocalOperation
|
|||
public:
|
||||
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 std::string description () const;
|
||||
|
||||
|
|
@ -170,7 +219,7 @@ class DB_PUBLIC EdgeBoolAndOrNotLocalOperation
|
|||
public:
|
||||
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 std::string description () const;
|
||||
|
||||
|
|
@ -193,7 +242,7 @@ class DB_PUBLIC EdgeToPolygonLocalOperation
|
|||
public:
|
||||
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 std::string description () const;
|
||||
|
||||
|
|
|
|||
|
|
@ -147,13 +147,12 @@ void insert_into_hash (std::unordered_set<T> &hash, const T &shape)
|
|||
|
||||
template <class TS, class TI>
|
||||
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);
|
||||
std::unordered_set<db::EdgePair> &result = results.front ();
|
||||
tl_assert (result.empty ());
|
||||
std::unordered_set<db::EdgePair> result;
|
||||
|
||||
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);
|
||||
|
||||
std::list<TS> heap;
|
||||
|
|
@ -234,6 +233,8 @@ check_local_operation<TS, TI>::compute_local (db::Layout *layout, const shape_in
|
|||
n += 2;
|
||||
}
|
||||
|
||||
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 ()) {
|
||||
|
|
@ -248,60 +249,156 @@ check_local_operation<TS, TI>::compute_local (db::Layout *layout, const shape_in
|
|||
scanner.process (poly_check, m_check.distance (), db::box_convert<TS> ());
|
||||
} 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"
|
||||
// ("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);
|
||||
|
||||
std::vector<db::Edge> projections;
|
||||
std::unordered_set<db::EdgePair> cleaned_result;
|
||||
|
||||
// filter out opposite edges
|
||||
for (std::unordered_set<db::EdgePair>::const_iterator ep1 = result.begin (); ep1 != result.end (); ++ep1) {
|
||||
if (m_has_other) {
|
||||
|
||||
projections.clear ();
|
||||
// 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.
|
||||
|
||||
for (std::unordered_set<db::EdgePair>::const_iterator ep2 = result.begin (); ep2 != result.end (); ++ep2) {
|
||||
std::vector<db::Edge> projections;
|
||||
for (std::unordered_set<db::EdgePair>::const_iterator ep1 = result.begin (); ep1 != result.end (); ++ep1) {
|
||||
|
||||
projections.clear ();
|
||||
|
||||
for (std::unordered_set<db::EdgePair>::const_iterator ep2 = result.begin (); ep2 != result.end (); ++ep2) {
|
||||
|
||||
if (ep1 == ep2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
db::EdgePair ep_opp;
|
||||
if (opp.check (ep1->first (), ep2->first (), &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 (ep1 == ep2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
db::EdgePair ep_opp;
|
||||
if (opp.check (ep1->first (), ep2->first (), &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 (! projections.empty ()) {
|
||||
db::Edges ce;
|
||||
if (m_options.opposite_filter == db::OnlyOpposite) {
|
||||
ce = db::Edges (ep1->first ()) & db::Edges (projections.begin (), projections.end ());
|
||||
} else if (m_options.opposite_filter == db::NotOpposite) {
|
||||
ce = db::Edges (ep1->first ()) - db::Edges (projections.begin (), projections.end ());
|
||||
}
|
||||
|
||||
if (! shielded) {
|
||||
projections.push_back (ep_opp.first ());
|
||||
for (db::Edges::const_iterator re = ce.begin (); ! re.at_end (); ++re) {
|
||||
cleaned_result.insert (db::EdgePair (*re, ep1->second ()));
|
||||
}
|
||||
|
||||
} else if (m_options.opposite_filter == db::NotOpposite) {
|
||||
cleaned_result.insert (*ep1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (! projections.empty ()) {
|
||||
db::Edges ce;
|
||||
if (m_options.opposite_filter == db::OnlyOpposite) {
|
||||
ce = db::Edges (ep1->first ()) & db::Edges (projections.begin (), projections.end ());
|
||||
} 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) {
|
||||
ce = db::Edges (ep1->first ()) - db::Edges (projections.begin (), projections.end ());
|
||||
cleaned_result.insert (db::EdgePair (*e1, e1->swapped_points ()));
|
||||
}
|
||||
for (db::Edges::const_iterator re = ce.begin (); ! re.at_end (); ++re) {
|
||||
cleaned_result.insert (db::EdgePair (*re, ep1->second ()));
|
||||
}
|
||||
} else if (m_options.opposite_filter == db::NotOpposite) {
|
||||
cleaned_result.insert (*ep1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
result.swap (cleaned_result);
|
||||
|
||||
} else {
|
||||
|
||||
result.insert (intra_polygon_result.begin (), intra_polygon_result.end ());
|
||||
|
||||
}
|
||||
|
||||
// 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>
|
||||
|
|
@ -418,7 +517,7 @@ db::Coord interacting_local_operation<TS, TI, TR>::dist () const
|
|||
}
|
||||
|
||||
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);
|
||||
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>
|
||||
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);
|
||||
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>
|
||||
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;
|
||||
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>
|
||||
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);
|
||||
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>
|
||||
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);
|
||||
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>
|
||||
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;
|
||||
bool counting = !(m_min_count == 1 && m_max_count == std::numeric_limits<size_t>::max ());
|
||||
|
|
|
|||
|
|
@ -202,10 +202,9 @@ class check_local_operation
|
|||
public:
|
||||
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 OnEmptyIntruderHint on_empty_intruder_hint () const;
|
||||
virtual bool requests_single_subjects () const { return true; }
|
||||
virtual std::string description () const;
|
||||
|
||||
private:
|
||||
|
|
@ -214,6 +213,8 @@ private:
|
|||
bool m_has_other;
|
||||
bool m_other_is_merged;
|
||||
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;
|
||||
|
|
@ -226,7 +227,7 @@ public:
|
|||
interacting_local_operation (int mode, bool touching, bool inverse, size_t min_count, size_t max_count);
|
||||
|
||||
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 std::string description () const;
|
||||
|
||||
|
|
@ -247,7 +248,7 @@ public:
|
|||
pull_local_operation (int mode, bool touching);
|
||||
|
||||
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 std::string description () const;
|
||||
|
||||
|
|
@ -266,7 +267,7 @@ public:
|
|||
interacting_with_edge_local_operation (bool inverse, size_t min_count, size_t max_count);
|
||||
|
||||
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 std::string description () const;
|
||||
|
||||
|
|
@ -285,7 +286,7 @@ public:
|
|||
pull_with_edge_local_operation ();
|
||||
|
||||
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 std::string description () const;
|
||||
};
|
||||
|
|
@ -300,7 +301,7 @@ public:
|
|||
interacting_with_text_local_operation (bool inverse, size_t min_count, size_t max_count);
|
||||
|
||||
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 std::string description () const;
|
||||
|
||||
|
|
@ -319,7 +320,7 @@ public:
|
|||
pull_with_text_local_operation ();
|
||||
|
||||
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 std::string description () const;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -152,7 +152,6 @@ Edge2EdgeCheckBase::feed_pseudo_edges (db::box_scanner<db::Edge, size_t> &scanne
|
|||
{
|
||||
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) {
|
||||
//printf("@@@ PSEUDO %s[%d]\n", e->first.to_string().c_str(), int(e->second)); fflush(stdout);
|
||||
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 ())) {
|
||||
|
||||
//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
|
||||
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 (p1, p2);
|
||||
}
|
||||
//printf("@@@1\n"); fflush(stdout);
|
||||
|
||||
db::EdgePair 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_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));
|
||||
//printf("@@@ CANCEL %s\n", ep.to_string().c_str()); fflush(stdout);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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*/);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ public:
|
|||
// .. 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;
|
||||
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
|
||||
|
|
@ -97,7 +97,7 @@ public:
|
|||
// .. 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;
|
||||
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
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#include "lymMacro.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 ();
|
||||
rs += "/testdata/drc/drcGenericTests_" + number + ".drc";
|
||||
|
|
@ -71,20 +71,20 @@ static void runTest (tl::TestBase *_this, const std::string &number, bool deep)
|
|||
|
||||
TEST(1)
|
||||
{
|
||||
runTest (_this, "1", false);
|
||||
run_test (_this, "1", false);
|
||||
}
|
||||
|
||||
TEST(1d)
|
||||
{
|
||||
runTest (_this, "1", true);
|
||||
run_test (_this, "1", true);
|
||||
}
|
||||
|
||||
TEST(2)
|
||||
{
|
||||
runTest (_this, "2", false);
|
||||
run_test (_this, "2", false);
|
||||
}
|
||||
|
||||
TEST(2d)
|
||||
{
|
||||
runTest (_this, "2", true);
|
||||
run_test (_this, "2", true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1077,3 +1077,53 @@ TEST(24_enclosing)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(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(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
|
||||
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)
|
||||
|
||||
# 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
|
||||
l2.drc(enclosing(l1, projection) < 1.0).polygons.output(150, 0)
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue