mirror of https://github.com/KLayout/klayout.git
WIP (shielding, various bug fixes)
This commit is contained in:
parent
9a55bdc687
commit
fd90e66ee1
|
|
@ -1601,11 +1601,11 @@ CompoundRegionCheckOperationNode::do_compute_local (db::Layout *layout, const sh
|
|||
|
||||
tl_assert (results.size () == 1);
|
||||
if (results.front ().empty ()) {
|
||||
op.compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
op.do_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
} else {
|
||||
std::vector<std::unordered_set<db::EdgePair> > r;
|
||||
r.resize (1);
|
||||
op.compute_local (layout, interactions, r, max_vertex_count, area_ratio);
|
||||
op.do_compute_local (layout, interactions, r, max_vertex_count, area_ratio);
|
||||
results.front ().insert (r.front ().begin (), r.front ().end ());
|
||||
}
|
||||
}
|
||||
|
|
@ -1617,11 +1617,11 @@ CompoundRegionCheckOperationNode::do_compute_local (db::Layout *layout, const sh
|
|||
|
||||
tl_assert (results.size () == 1);
|
||||
if (results.front ().empty ()) {
|
||||
op.compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
op.do_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
} else {
|
||||
std::vector<std::unordered_set<db::EdgePair> > r;
|
||||
r.resize (1);
|
||||
op.compute_local (layout, interactions, r, max_vertex_count, area_ratio);
|
||||
op.do_compute_local (layout, interactions, r, max_vertex_count, area_ratio);
|
||||
results.front ().insert (r.front ().begin (), r.front ().end ());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -680,7 +680,11 @@ public:
|
|||
virtual ResultType result_type () const { return compound_operation_type_traits<TR>::type (); }
|
||||
virtual const db::TransformationReducer *vars () const { return mp_vars; }
|
||||
virtual bool wants_variants () const { return m_wants_variants; }
|
||||
virtual db::Coord computed_dist () const { return m_op->dist (); }
|
||||
|
||||
virtual db::Coord computed_dist () const
|
||||
{
|
||||
return CompoundRegionMultiInputOperationNode::computed_dist () + m_op->dist ();
|
||||
}
|
||||
|
||||
virtual std::vector<db::Region *> inputs () const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -33,10 +33,74 @@
|
|||
#include "tlLog.h"
|
||||
#include "tlTimer.h"
|
||||
#include "tlInternational.h"
|
||||
#include "tlProgress.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// local_operations implementation
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
void 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, bool report_progress, const std::string &progress_desc) const
|
||||
{
|
||||
if (interactions.num_subjects () <= 1 || ! requests_single_subjects ()) {
|
||||
|
||||
do_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
|
||||
} else {
|
||||
|
||||
std::auto_ptr<tl::RelativeProgress> progress;
|
||||
if (report_progress) {
|
||||
progress.reset (new tl::RelativeProgress (progress_desc, interactions.size ()));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (progress.get ()) {
|
||||
++*progress;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// explicit instantiations
|
||||
template class DB_PUBLIC local_operation<db::Polygon, db::Polygon, db::Polygon>;
|
||||
template class DB_PUBLIC local_operation<db::Polygon, db::Text, db::Polygon>;
|
||||
template class DB_PUBLIC local_operation<db::Polygon, db::Text, db::Text>;
|
||||
template class DB_PUBLIC local_operation<db::Polygon, db::Edge, db::Polygon>;
|
||||
template class DB_PUBLIC local_operation<db::Polygon, db::Edge, db::Edge>;
|
||||
template class DB_PUBLIC local_operation<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
|
||||
template class DB_PUBLIC local_operation<db::PolygonRef, db::Edge, db::PolygonRef>;
|
||||
template class DB_PUBLIC local_operation<db::PolygonRef, db::PolygonRef, db::EdgePair>;
|
||||
template class DB_PUBLIC local_operation<db::Polygon, db::Polygon, db::EdgePair>;
|
||||
template class DB_PUBLIC local_operation<db::Edge, db::Edge, db::Edge>;
|
||||
template class DB_PUBLIC local_operation<db::Edge, db::PolygonRef, db::Edge>;
|
||||
template class DB_PUBLIC local_operation<db::Edge, db::Edge, db::EdgePair>;
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// BoolAndOrNotLocalOperation implementation
|
||||
|
||||
|
|
|
|||
|
|
@ -29,8 +29,6 @@
|
|||
|
||||
#include "dbLayout.h"
|
||||
#include "dbEdgeBoolean.h"
|
||||
#include "tlProgress.h"
|
||||
#include "tlInternational.h"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
|
@ -89,55 +87,10 @@ public:
|
|||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
* If the operation requests single subject mode, the interactions will be split into single subject/intruder clusters
|
||||
*/
|
||||
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, bool report_progress = false, const std::string &progress_desc = std::string ()) const
|
||||
{
|
||||
if (interactions.num_subjects () <= 1 || ! requests_single_subjects ()) {
|
||||
|
||||
do_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
|
||||
} else {
|
||||
|
||||
std::auto_ptr<tl::RelativeProgress> progress;
|
||||
if (report_progress) {
|
||||
progress.reset (new tl::RelativeProgress (progress_desc, interactions.size ()));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (progress.get ()) {
|
||||
++*progress;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
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, bool report_progress = false, const std::string &progress_desc = std::string ()) const;
|
||||
|
||||
/**
|
||||
* @brief Indicates the desired behaviour when a shape does not have an intruder
|
||||
|
|
|
|||
|
|
@ -200,9 +200,9 @@ void
|
|||
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;
|
||||
std::unordered_set<db::EdgePair> result, intra_polygon_result;
|
||||
|
||||
edge2edge_check_negative_or_positive<std::unordered_set<db::EdgePair> > edge_check (m_check, result, m_options.negative, true, true, m_options.shielded);
|
||||
edge2edge_check_negative_or_positive<std::unordered_set<db::EdgePair> > edge_check (m_check, result, intra_polygon_result, m_options.negative, m_different_polygons, m_has_other, m_options.shielded);
|
||||
poly2poly_check<TS> poly_check (edge_check);
|
||||
|
||||
std::list<TS> heap;
|
||||
|
|
@ -302,30 +302,6 @@ check_local_operation<TS, TI>::do_compute_local (db::Layout *layout, const shape
|
|||
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)
|
||||
|
|
@ -497,18 +473,13 @@ check_local_operation<TS, TI>::do_compute_local (db::Layout *layout, const shape
|
|||
for (std::unordered_set<db::EdgePair>::const_iterator i = result.begin (); i != result.end (); ++i) {
|
||||
results.front ().insert (db::EdgePair (i->first (), i->first ().swapped_points ()));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
results.front ().insert (result.begin (), result.end ());
|
||||
result.clear ();
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
results.front ().insert (result.begin (), result.end ());
|
||||
|
||||
}
|
||||
|
||||
results.front ().insert (result.begin (), result.end ());
|
||||
}
|
||||
|
||||
template <class TS, class TI>
|
||||
|
|
|
|||
|
|
@ -210,14 +210,14 @@ public:
|
|||
virtual bool requests_single_subjects () const { return true; }
|
||||
virtual std::string description () const;
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
EdgeRelationFilter m_check;
|
||||
bool m_different_polygons;
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ Edge2EdgeCheckBase::prepare_next_pass ()
|
|||
if (! m_ep.empty () && m_has_edge_pair_output) {
|
||||
|
||||
std::vector<bool>::const_iterator d = m_ep_discarded.begin ();
|
||||
std::vector<bool>::const_iterator i = m_ep_intra_polygon.begin ();
|
||||
std::vector<db::EdgePair>::const_iterator ep = m_ep.begin ();
|
||||
while (ep != m_ep.end () && size_t (ep - m_ep.begin ()) < m_first_pseudo) {
|
||||
bool use_result = true;
|
||||
|
|
@ -75,9 +76,10 @@ Edge2EdgeCheckBase::prepare_next_pass ()
|
|||
++d;
|
||||
}
|
||||
if (use_result) {
|
||||
put (*ep);
|
||||
put (*ep, *i);
|
||||
}
|
||||
++ep;
|
||||
++i;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -182,7 +184,10 @@ Edge2EdgeCheckBase::add (const db::Edge *o1, size_t p1, const db::Edge *o2, size
|
|||
// pass we will eliminate those which are shielded completely (with shielding)
|
||||
// and/or compute the negative edges.
|
||||
size_t n = m_ep.size ();
|
||||
|
||||
m_ep.push_back (ep);
|
||||
m_ep_intra_polygon.push_back (p1 == p2);
|
||||
|
||||
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));
|
||||
|
||||
|
|
@ -253,9 +258,12 @@ Edge2EdgeCheckBase::add (const db::Edge *o1, size_t p1, const db::Edge *o2, size
|
|||
}
|
||||
|
||||
// for negative output edges are cancelled by short interactions perpendicular to them
|
||||
// For this we have generated "pseudo edges" running along the sides of the original violation. We now check a real
|
||||
// edge vs. a pseudo edge with the same conditions as the normal interaction and add them to the results. In the
|
||||
// negative case this means we cancel a real edge.
|
||||
|
||||
if (m_has_negative_edge_output &&
|
||||
(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 ())) {
|
||||
|
||||
// Overlap or inside checks require input from different layers
|
||||
if ((! m_different_polygons || p1 != p2) && (! m_requires_different_layers || ((p1 ^ p2) & 1) != 0)) {
|
||||
|
|
@ -274,7 +282,10 @@ Edge2EdgeCheckBase::add (const db::Edge *o1, size_t p1, const db::Edge *o2, size
|
|||
if (mp_check->check (*o1, *o2, &ep)) {
|
||||
|
||||
size_t n = m_ep.size ();
|
||||
|
||||
m_ep.push_back (ep);
|
||||
m_ep_intra_polygon.push_back (p1 == p2); // not really required, but there for consistency
|
||||
|
||||
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));
|
||||
|
||||
|
|
|
|||
|
|
@ -612,7 +612,7 @@ protected:
|
|||
/**
|
||||
* @brief Normal edge pair output (violations)
|
||||
*/
|
||||
virtual void put (const db::EdgePair & /*edge*/) const { }
|
||||
virtual void put (const db::EdgePair & /*edge*/, bool /*intra-polygon*/) const { }
|
||||
|
||||
/**
|
||||
* @brief Negative edge output
|
||||
|
|
@ -628,7 +628,7 @@ private:
|
|||
std::multimap<std::pair<db::Edge, size_t>, size_t> m_e2ep;
|
||||
std::set<std::pair<db::Edge, size_t> > m_pseudo_edges;
|
||||
size_t m_first_pseudo;
|
||||
std::vector<bool> m_ep_discarded;
|
||||
std::vector<bool> m_ep_discarded, m_ep_intra_polygon;
|
||||
bool m_with_shielding;
|
||||
bool m_has_edge_pair_output;
|
||||
bool m_has_negative_edge_output;
|
||||
|
|
@ -646,19 +646,30 @@ class DB_PUBLIC_TEMPLATE edge2edge_check
|
|||
{
|
||||
public:
|
||||
edge2edge_check (const EdgeRelationFilter &check, Output &output, bool different_polygons, bool requires_different_layers, bool with_shielding)
|
||||
: Edge2EdgeCheckBase (check, different_polygons, requires_different_layers, with_shielding), mp_output (&output)
|
||||
: Edge2EdgeCheckBase (check, different_polygons, requires_different_layers, with_shielding), mp_output_inter (&output), mp_output_intra (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
edge2edge_check (const EdgeRelationFilter &check, Output &output_inter, Output &output_intra, bool different_polygons, bool requires_different_layers, bool with_shielding)
|
||||
: Edge2EdgeCheckBase (check, different_polygons, requires_different_layers, with_shielding), mp_output_inter (&output_inter), mp_output_intra (&output_intra)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
protected:
|
||||
void put (const db::EdgePair &edge) const
|
||||
void put (const db::EdgePair &edge, bool inter_polygon) const
|
||||
{
|
||||
mp_output->insert (edge);
|
||||
if (! inter_polygon || ! mp_output_intra) {
|
||||
mp_output_inter->insert (edge);
|
||||
} else {
|
||||
mp_output_intra->insert (edge);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Output *mp_output;
|
||||
Output *mp_output_inter;
|
||||
Output *mp_output_intra;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -669,24 +680,26 @@ private:
|
|||
*/
|
||||
template <class Output, class NegativeEdgeOutput>
|
||||
class DB_PUBLIC_TEMPLATE edge2edge_check_with_negative_output
|
||||
: public Edge2EdgeCheckBase
|
||||
: public edge2edge_check<Output>
|
||||
{
|
||||
public:
|
||||
edge2edge_check_with_negative_output (const EdgeRelationFilter &check, Output &output, NegativeEdgeOutput &l1_negative_output, NegativeEdgeOutput &l2_negative_output, bool different_polygons, bool requires_different_layers, bool with_shielding)
|
||||
: Edge2EdgeCheckBase (check, different_polygons, requires_different_layers, with_shielding),
|
||||
mp_output (&output),
|
||||
: edge2edge_check<Output> (check, output, different_polygons, requires_different_layers, with_shielding),
|
||||
mp_l1_negative_output (&l1_negative_output),
|
||||
mp_l2_negative_output (&l2_negative_output)
|
||||
{
|
||||
set_has_negative_edge_output (true);
|
||||
edge2edge_check<Output>::set_has_negative_edge_output (true);
|
||||
}
|
||||
|
||||
edge2edge_check_with_negative_output (const EdgeRelationFilter &check, Output &output_inter, Output &output_intra, NegativeEdgeOutput &l1_negative_output, NegativeEdgeOutput &l2_negative_output, bool different_polygons, bool requires_different_layers, bool with_shielding)
|
||||
: edge2edge_check<Output> (check, output_inter, output_intra, different_polygons, requires_different_layers, with_shielding),
|
||||
mp_l1_negative_output (&l1_negative_output),
|
||||
mp_l2_negative_output (&l2_negative_output)
|
||||
{
|
||||
edge2edge_check<Output>::set_has_negative_edge_output (true);
|
||||
}
|
||||
|
||||
protected:
|
||||
void put (const db::EdgePair &ep) const
|
||||
{
|
||||
mp_output->insert (ep);
|
||||
}
|
||||
|
||||
void put_negative (const db::Edge &edge, int layer) const
|
||||
{
|
||||
if (layer == 0) {
|
||||
|
|
@ -698,7 +711,6 @@ protected:
|
|||
}
|
||||
|
||||
private:
|
||||
Output *mp_output;
|
||||
NegativeEdgeOutput *mp_l1_negative_output, *mp_l2_negative_output;
|
||||
};
|
||||
|
||||
|
|
@ -746,35 +758,33 @@ private:
|
|||
*/
|
||||
template <class Output>
|
||||
class DB_PUBLIC_TEMPLATE edge2edge_check_negative_or_positive
|
||||
: public Edge2EdgeCheckBase
|
||||
: public edge2edge_check<Output>
|
||||
{
|
||||
public:
|
||||
edge2edge_check_negative_or_positive (const EdgeRelationFilter &check, Output &output, bool negative_output, bool different_polygons, bool requires_different_layers, bool with_shielding)
|
||||
: Edge2EdgeCheckBase (check, different_polygons, requires_different_layers, with_shielding),
|
||||
mp_output (&output)
|
||||
: edge2edge_check<Output> (check, output, different_polygons, requires_different_layers, with_shielding)
|
||||
{
|
||||
set_has_negative_edge_output (negative_output);
|
||||
set_has_edge_pair_output (! negative_output);
|
||||
edge2edge_check<Output>::set_has_negative_edge_output (negative_output);
|
||||
edge2edge_check<Output>::set_has_edge_pair_output (! negative_output);
|
||||
}
|
||||
|
||||
edge2edge_check_negative_or_positive (const EdgeRelationFilter &check, Output &output_inter, Output &output_intra, bool negative_output, bool different_polygons, bool requires_different_layers, bool with_shielding)
|
||||
: edge2edge_check<Output> (check, output_inter, output_intra, different_polygons, requires_different_layers, with_shielding)
|
||||
{
|
||||
edge2edge_check<Output>::set_has_negative_edge_output (negative_output);
|
||||
edge2edge_check<Output>::set_has_edge_pair_output (! negative_output);
|
||||
}
|
||||
|
||||
protected:
|
||||
void put_negative (const db::Edge &edge, int layer) const
|
||||
{
|
||||
if (layer == 0) {
|
||||
mp_output->insert (db::EdgePair (edge, edge.swapped_points ()));
|
||||
edge2edge_check<Output>::put (db::EdgePair (edge, edge.swapped_points ()), false);
|
||||
}
|
||||
if (layer == 1) {
|
||||
mp_output->insert (db::EdgePair (edge.swapped_points (), edge));
|
||||
edge2edge_check<Output>::put (db::EdgePair (edge.swapped_points (), edge), false);
|
||||
}
|
||||
}
|
||||
|
||||
void put (const db::EdgePair &edge) const
|
||||
{
|
||||
mp_output->insert (edge);
|
||||
}
|
||||
|
||||
private:
|
||||
Output *mp_output;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -426,13 +426,10 @@ static db::CompoundRegionOperationNode *new_width_check (db::Coord d, bool whole
|
|||
|
||||
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 || shielded) {
|
||||
// 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);
|
||||
}
|
||||
// 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. Having all intruders is crucial for the
|
||||
// semantics of the "drc" feature
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -218,3 +218,23 @@ TEST(15d)
|
|||
{
|
||||
run_test (_this, "15", true);
|
||||
}
|
||||
|
||||
TEST(16)
|
||||
{
|
||||
run_test (_this, "16", false);
|
||||
}
|
||||
|
||||
TEST(16d)
|
||||
{
|
||||
run_test (_this, "16", true);
|
||||
}
|
||||
|
||||
TEST(17)
|
||||
{
|
||||
run_test (_this, "17", false);
|
||||
}
|
||||
|
||||
TEST(17d)
|
||||
{
|
||||
run_test (_this, "17", true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1137,3 +1137,13 @@ TEST(26d_attributes)
|
|||
{
|
||||
run_test (_this, "26", true);
|
||||
}
|
||||
|
||||
TEST(27_advancedShielding)
|
||||
{
|
||||
run_test (_this, "27", false);
|
||||
}
|
||||
|
||||
TEST(27d_advancedShielding)
|
||||
{
|
||||
run_test (_this, "27", true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
source $drc_test_source
|
||||
target $drc_test_target
|
||||
|
||||
if $drc_test_deep
|
||||
deep
|
||||
end
|
||||
|
||||
l1 = input(1, 0)
|
||||
l2 = input(2, 0)
|
||||
l3 = input(3, 0)
|
||||
|
||||
l1.output(1, 0)
|
||||
l2.output(2, 0)
|
||||
l3.output(3, 0)
|
||||
|
||||
l1.drc(primary.interacting((space(shielded) < 1.0).polygons)).output(100, 0)
|
||||
l1.drc(primary.interacting((space(transparent) < 1.0).polygons)).output(101, 0)
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
source $drc_test_source
|
||||
target $drc_test_target
|
||||
|
||||
if $drc_test_deep
|
||||
deep
|
||||
end
|
||||
|
||||
l1 = input(1, 0)
|
||||
l2 = input(2, 0)
|
||||
l3 = input(3, 0)
|
||||
|
||||
l1.output(1, 0)
|
||||
l2.output(2, 0)
|
||||
l3.output(3, 0)
|
||||
|
||||
# advanced shielding (self, symmetric space)
|
||||
|
||||
l1.drc(width(projection, shielded) < 1.0).output(100, 0)
|
||||
l1.drc(width(projection, transparent) < 1.0).output(101, 0)
|
||||
|
||||
l1.drc(space(projection, shielded) < 1.0).output(110, 0)
|
||||
l1.drc(space(projection, transparent) < 1.0).output(111, 0)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
source $drc_test_source
|
||||
target $drc_test_target
|
||||
|
||||
if $drc_test_deep
|
||||
deep
|
||||
end
|
||||
|
||||
l1 = input(1, 0)
|
||||
l2 = input(2, 0)
|
||||
l3 = input(3, 0)
|
||||
|
||||
l1.output(1, 0)
|
||||
l2.output(2, 0)
|
||||
l3.output(3, 0)
|
||||
|
||||
# advanced shielding (self, symmetric space)
|
||||
|
||||
l1.width(1.0, projection, shielded).output(100, 0)
|
||||
l1.width(1.0, projection, transparent).output(101, 0)
|
||||
|
||||
l1.space(1.0, projection, shielded).output(110, 0)
|
||||
l1.space(1.0, projection, transparent).output(111, 0)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -321,19 +321,16 @@ def run_testsuite(dm, ic, tiled = false, hier = false)
|
|||
lb += 10 #230
|
||||
message "--- isolated #{lb}"
|
||||
|
||||
b.isolated(0.4).polygons.output(lb, dm)
|
||||
b.isolated(0.4).polygons.xor(b.iso(0.4).polygons).is_empty? == true || raise("xor not empty")
|
||||
b.isolated(0.4, euclidian).polygons.output(lb + 1, dm)
|
||||
b.isolated(0.4, square).polygons.output(lb + 2, dm)
|
||||
b.isolated(0.4, projection).polygons.output(lb + 3, dm)
|
||||
b.isolated(0.4, euclidian, whole_edges).polygons.output(lb + 4, dm)
|
||||
b.isolated(0.4, euclidian, projection_limits(0.4, nil)).polygons.output(lb + 5, dm)
|
||||
b.isolated(0.4, euclidian, projection_limits(nil, 0.4)).polygons.output(lb + 6, dm)
|
||||
if has_float_range
|
||||
b.isolated(0.4, euclidian, projection_limits(0..0.4)).polygons.output(lb + 7, dm)
|
||||
else
|
||||
b.isolated(0.4, euclidian, projection_limits(0, 0.4)).polygons.output(lb + 7, dm)
|
||||
end
|
||||
b.isolated(0.4, shielded).polygons.output(lb, dm)
|
||||
b.isolated(0.4, shielded).polygons.xor(b.iso(0.4, shielded).polygons).is_empty? == true || raise("xor not empty")
|
||||
b.isolated(0.4, shielded, euclidian).polygons.output(lb + 1, dm)
|
||||
b.isolated(0.4, shielded, square).polygons.output(lb + 2, dm)
|
||||
b.isolated(0.4, shielded, projection).polygons.output(lb + 3, dm)
|
||||
b.isolated(0.4, shielded, euclidian, whole_edges).polygons.output(lb + 4, dm)
|
||||
b.isolated(0.4, shielded, euclidian, projection_limits(0.4, nil)).polygons.output(lb + 5, dm)
|
||||
b.isolated(0.4, shielded, euclidian, projection_limits(nil, 0.4)).polygons.output(lb + 6, dm)
|
||||
b.isolated(0.4, shielded, euclidian, projecting < 0.4).polygons.output(lb + 7, dm)
|
||||
b.isolated(0.4, transparent).polygons.output(lb + 8, dm)
|
||||
|
||||
lb += 10 #240
|
||||
message "--- notch #{lb}"
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue