mirror of https://github.com/KLayout/klayout.git
WIP: debugging
This commit is contained in:
parent
45a8f7aa20
commit
4974a81af6
|
|
@ -1039,81 +1039,50 @@ AsIfFlatRegion::scaled_and_snapped (db::Coord gx, db::Coord mx, db::Coord dx, db
|
|||
return new_region.release ();
|
||||
}
|
||||
|
||||
EdgePairsDelegate *
|
||||
AsIfFlatRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &node)
|
||||
template <class TR>
|
||||
static
|
||||
void region_cop_impl (AsIfFlatRegion *region, db::Shapes *output_to, db::CompoundRegionOperationNode &node)
|
||||
{
|
||||
db::local_processor<db::Polygon, db::Polygon, db::EdgePair> proc;
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
db::local_processor<db::Polygon, db::Polygon, TR> proc;
|
||||
proc.set_base_verbosity (region->base_verbosity ());
|
||||
|
||||
bool needs_merged = node.wants_merged ();
|
||||
db::RegionIterator polygons (needs_merged ? region->begin_merged () : region->begin ());
|
||||
|
||||
std::vector<generic_shape_iterator<db::Polygon> > others;
|
||||
std::vector<db::Region *> inputs = node.inputs ();
|
||||
for (std::vector<db::Region *>::const_iterator i = inputs.begin (); i != inputs.end (); ++i) {
|
||||
// @@@ in case of *i == null - what to do?
|
||||
others.push_back (*i ? (*i)->begin () : begin ());
|
||||
others.push_back (*i ? (*i)->begin () : (needs_merged ? region->begin_merged () : region->begin ()));
|
||||
}
|
||||
|
||||
// @@@ really always "merged"?
|
||||
db::RegionIterator polygons (begin_merged ());
|
||||
|
||||
std::auto_ptr<FlatEdgePairs> output (new FlatEdgePairs ());
|
||||
std::vector<db::Shapes *> results;
|
||||
results.push_back (&output->raw_edge_pairs ());
|
||||
results.push_back (output_to);
|
||||
|
||||
compound_local_operation<db::Polygon, db::Polygon, db::EdgePair> op (&node);
|
||||
compound_local_operation<db::Polygon, db::Polygon, TR> op (&node);
|
||||
proc.run_flat (polygons, others, &op, results);
|
||||
}
|
||||
|
||||
EdgePairsDelegate *
|
||||
AsIfFlatRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &node)
|
||||
{
|
||||
std::auto_ptr<FlatEdgePairs> output (new FlatEdgePairs ());
|
||||
region_cop_impl<db::EdgePair> (this, &output->raw_edge_pairs (), node);
|
||||
return output.release ();
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
AsIfFlatRegion::cop_to_region (db::CompoundRegionOperationNode &node)
|
||||
{
|
||||
db::local_processor<db::Polygon, db::Polygon, db::Polygon> proc;
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
|
||||
std::vector<generic_shape_iterator<db::Polygon> > others;
|
||||
std::vector<db::Region *> inputs = node.inputs ();
|
||||
for (std::vector<db::Region *>::const_iterator i = inputs.begin (); i != inputs.end (); ++i) {
|
||||
// @@@ in case of *i == null - what to do?
|
||||
others.push_back (*i ? (*i)->begin () : begin ());
|
||||
}
|
||||
|
||||
// @@@ really always "merged"?
|
||||
db::RegionIterator polygons (begin_merged ());
|
||||
|
||||
std::auto_ptr<FlatRegion> output (new FlatRegion ());
|
||||
std::vector<db::Shapes *> results;
|
||||
results.push_back (&output->raw_polygons ());
|
||||
|
||||
compound_local_operation<db::Polygon, db::Polygon, db::Polygon> op (&node);
|
||||
proc.run_flat (polygons, others, &op, results);
|
||||
|
||||
region_cop_impl<db::Polygon> (this, &output->raw_polygons (), node);
|
||||
return output.release ();
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatRegion::cop_to_edges (db::CompoundRegionOperationNode &node)
|
||||
{
|
||||
db::local_processor<db::Polygon, db::Polygon, db::Edge> proc;
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
|
||||
std::vector<generic_shape_iterator<db::Polygon> > others;
|
||||
std::vector<db::Region *> inputs = node.inputs ();
|
||||
for (std::vector<db::Region *>::const_iterator i = inputs.begin (); i != inputs.end (); ++i) {
|
||||
// @@@ in case of *i == null - what to do?
|
||||
others.push_back (*i ? (*i)->begin () : begin ());
|
||||
}
|
||||
|
||||
// @@@ really always "merged"?
|
||||
db::RegionIterator polygons (begin_merged ());
|
||||
|
||||
std::auto_ptr<FlatEdges> output (new FlatEdges ());
|
||||
std::vector<db::Shapes *> results;
|
||||
results.push_back (&output->raw_edges ());
|
||||
|
||||
compound_local_operation<db::Polygon, db::Polygon, db::Edge> op (&node);
|
||||
proc.run_flat (polygons, others, &op, results);
|
||||
|
||||
region_cop_impl<db::Edge> (this, &output->raw_edges (), node);
|
||||
return output.release ();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -163,7 +163,9 @@ CompoundRegionOperationPrimaryNode::~CompoundRegionOperationPrimaryNode ()
|
|||
|
||||
std::vector<db::Region *> CompoundRegionOperationPrimaryNode::inputs () const
|
||||
{
|
||||
return std::vector<db::Region *> ();
|
||||
std::vector<db::Region *> is;
|
||||
is.push_back (0);
|
||||
return is;
|
||||
}
|
||||
|
||||
void CompoundRegionOperationPrimaryNode::do_compute_local (db::Layout *, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t, double) const
|
||||
|
|
@ -299,13 +301,16 @@ CompoundRegionMultiInputOperationNode::CompoundRegionMultiInputOperationNode ()
|
|||
|
||||
CompoundRegionMultiInputOperationNode::CompoundRegionMultiInputOperationNode (CompoundRegionOperationNode *child)
|
||||
{
|
||||
child->keep ();
|
||||
m_children.push_back (child);
|
||||
init ();
|
||||
}
|
||||
|
||||
CompoundRegionMultiInputOperationNode::CompoundRegionMultiInputOperationNode (CompoundRegionOperationNode *a, CompoundRegionOperationNode *b)
|
||||
{
|
||||
a->keep ();
|
||||
m_children.push_back (a);
|
||||
b->keep ();
|
||||
m_children.push_back (b);
|
||||
init ();
|
||||
}
|
||||
|
|
@ -415,6 +420,17 @@ CompoundRegionMultiInputOperationNode::wants_variants () const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CompoundRegionMultiInputOperationNode::wants_merged () const
|
||||
{
|
||||
for (tl::shared_collection<CompoundRegionOperationNode>::const_iterator i = m_children.begin (); i != m_children.end (); ++i) {
|
||||
if (i->wants_merged ()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
CompoundRegionLogicalBoolOperationNode::CompoundRegionLogicalBoolOperationNode (LogicalOp op, bool invert, const std::vector<CompoundRegionOperationNode *> &inputs)
|
||||
|
|
@ -1113,18 +1129,58 @@ CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (db::edge_rel
|
|||
m_check.set_max_projection (options.max_projection);
|
||||
}
|
||||
|
||||
db::OnEmptyIntruderHint
|
||||
CompoundRegionCheckOperationNode::on_empty_intruder_hint () const
|
||||
{
|
||||
return (m_different_polygons || !inputs ().empty ()) ? OnEmptyIntruderHint::Drop : OnEmptyIntruderHint::Ignore;
|
||||
}
|
||||
|
||||
db::Coord
|
||||
CompoundRegionCheckOperationNode::dist () const
|
||||
{
|
||||
return m_check.distance ();
|
||||
}
|
||||
|
||||
bool
|
||||
CompoundRegionCheckOperationNode::wants_merged () const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
db::check_local_operation<db::Polygon, db::Polygon> op (m_check, m_different_polygons, true, false, m_options.shielded, m_options.opposite_filter, m_options.rect_filter);
|
||||
op.compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
bool other_merged = (children () > 0 && !inputs ()[0]);
|
||||
|
||||
db::check_local_operation<db::Polygon, db::Polygon> op (m_check, m_different_polygons, children () > 0, other_merged, m_options.shielded, m_options.opposite_filter, m_options.rect_filter);
|
||||
|
||||
tl_assert (results.size () == 1);
|
||||
if (results.front ().empty ()) {
|
||||
op.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);
|
||||
results.front ().insert (r.front ().begin (), r.front ().end ());
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
db::check_local_operation<db::PolygonRef, db::PolygonRef> op (m_check, m_different_polygons, true, false, m_options.shielded, m_options.opposite_filter, m_options.rect_filter);
|
||||
op.compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
bool other_merged = (children () > 0 && !inputs ()[0]);
|
||||
|
||||
db::check_local_operation<db::PolygonRef, db::PolygonRef> op (m_check, m_different_polygons, children () > 0, other_merged, m_options.shielded, m_options.opposite_filter, m_options.rect_filter);
|
||||
|
||||
tl_assert (results.size () == 1);
|
||||
if (results.front ().empty ()) {
|
||||
op.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);
|
||||
results.front ().insert (r.front ().begin (), r.front ().end ());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,11 @@ public:
|
|||
*/
|
||||
virtual bool wants_variants () const { return false; }
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the processor wants to have merged primary inputs
|
||||
*/
|
||||
virtual bool wants_merged () const { return false; }
|
||||
|
||||
void compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
|
|
@ -362,6 +367,7 @@ public:
|
|||
|
||||
virtual const TransformationReducer *vars () const;
|
||||
virtual bool wants_variants () const;
|
||||
virtual bool wants_merged () const;
|
||||
|
||||
virtual void invalidate_cache () const;
|
||||
|
||||
|
|
@ -384,7 +390,12 @@ protected:
|
|||
|
||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
|
||||
child_interactions.add_subject_shape (i->first, interactions.subject_shape (i->first));
|
||||
if (child (child_index)->on_empty_intruder_hint () == OnEmptyIntruderHint::Drop) {
|
||||
child_interactions.add_subject_shape (i->first, interactions.subject_shape (i->first));
|
||||
} else {
|
||||
// this includes the subject-without-intruder "interaction"
|
||||
child_interactions.add_subject (i->first, interactions.subject_shape (i->first));
|
||||
}
|
||||
|
||||
for (typename shape_interactions<TS, TI>::iterator2 ii = i->second.begin (); ii != i->second.end (); ++ii) {
|
||||
|
||||
|
|
@ -941,6 +952,10 @@ public:
|
|||
// specifies the result type
|
||||
virtual ResultType result_type () const { return EdgePairs; }
|
||||
|
||||
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
|
||||
virtual db::Coord dist () const;
|
||||
virtual bool wants_merged () const;
|
||||
|
||||
virtual void 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;
|
||||
virtual void 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;
|
||||
|
||||
|
|
@ -981,8 +996,14 @@ protected:
|
|||
|
||||
shape_interactions<TS, TI> single_interactions;
|
||||
|
||||
single_interactions.add_subject_shape (i->first, subject_shape);
|
||||
const std::vector<unsigned int> &intruders = single_interactions.intruders_for (i->first);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -1763,6 +1763,23 @@ local_processor<TS, TI, TR>::compute_local_cell (const db::local_processor_conte
|
|||
|
||||
shape_interactions<TS, TI> interactions;
|
||||
|
||||
// insert dummy interactions to accommodate subject vs. nothing and assign an ID
|
||||
// range for the subject shapes.
|
||||
unsigned int subject_id0 = 0;
|
||||
for (db::Shapes::shape_iterator i = subject_shapes->begin (shape_flags<TS> ()); !i.at_end (); ++i) {
|
||||
|
||||
unsigned int id = interactions.next_id ();
|
||||
if (subject_id0 == 0) {
|
||||
subject_id0 = id;
|
||||
}
|
||||
|
||||
if (op->on_empty_intruder_hint () != OnEmptyIntruderHint::Drop) {
|
||||
const TS *ref = i->basic_ptr (typename TS::tag ());
|
||||
interactions.add_subject (id, *ref);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (std::vector<unsigned int>::const_iterator il = contexts.intruder_layers ().begin (); il != contexts.intruder_layers ().end (); ++il) {
|
||||
|
||||
const db::Shapes *intruder_shapes = 0;
|
||||
|
|
@ -1777,23 +1794,6 @@ local_processor<TS, TI, TR>::compute_local_cell (const db::local_processor_conte
|
|||
|
||||
db::box_convert<db::CellInstArray, true> inst_bci (*mp_intruder_layout, *il);
|
||||
|
||||
// insert dummy interactions to accommodate subject vs. nothing and assign an ID
|
||||
// range for the subject shapes.
|
||||
unsigned int subject_id0 = 0;
|
||||
for (db::Shapes::shape_iterator i = subject_shapes->begin (shape_flags<TS> ()); !i.at_end (); ++i) {
|
||||
|
||||
unsigned int id = interactions.next_id ();
|
||||
if (subject_id0 == 0) {
|
||||
subject_id0 = id;
|
||||
}
|
||||
|
||||
if (op->on_empty_intruder_hint () != OnEmptyIntruderHint::Drop) {
|
||||
const TS *ref = i->basic_ptr (typename TS::tag ());
|
||||
interactions.add_subject (id, *ref);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
typename std::map<unsigned int, std::set<TI> >::const_iterator ipl = intruders.second.find (*il);
|
||||
static std::set<TI> empty_intruders;
|
||||
|
||||
|
|
@ -1900,7 +1900,7 @@ template <class TS, class TI>
|
|||
struct scan_shape2shape_same_layer_flat
|
||||
{
|
||||
void
|
||||
operator () (const generic_shape_iterator<TS> &, bool, unsigned int, shape_interactions<TS, TI> &, db::Coord) const
|
||||
operator () (const generic_shape_iterator<TS> &, unsigned int, shape_interactions<TS, TI> &, db::Coord) const
|
||||
{
|
||||
// cannot have different types on the same layer
|
||||
tl_assert (false);
|
||||
|
|
@ -1911,7 +1911,7 @@ template <class T>
|
|||
struct scan_shape2shape_same_layer_flat<T, T>
|
||||
{
|
||||
void
|
||||
operator () (const generic_shape_iterator<T> &subjects, bool needs_isolated_subjects, unsigned int intruder_layer, shape_interactions<T, T> &interactions, db::Coord dist) const
|
||||
operator () (const generic_shape_iterator<T> &subjects, unsigned int intruder_layer, shape_interactions<T, T> &interactions, db::Coord dist) const
|
||||
{
|
||||
db::box_scanner<T, int> scanner;
|
||||
interaction_registration_shape1<T, T> rec (&interactions, intruder_layer);
|
||||
|
|
@ -1924,22 +1924,32 @@ struct scan_shape2shape_same_layer_flat<T, T>
|
|||
const T *shape = is.operator-> ();
|
||||
scanner.insert (shape, id);
|
||||
|
||||
// create subject for subject vs. nothing interactions
|
||||
if (needs_isolated_subjects) {
|
||||
interactions.add_subject (id, *shape);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
scanner.process (rec, dist, db::box_convert<T> ());
|
||||
}
|
||||
};
|
||||
|
||||
template <class TS, class TI>
|
||||
struct add_subjects_vs_nothing_flat
|
||||
{
|
||||
void
|
||||
operator () (const generic_shape_iterator<TS> &subjects, shape_interactions<TS, TI> &interactions) const
|
||||
{
|
||||
addressable_shape_delivery<TS> is (subjects);
|
||||
for ( ; !is.at_end (); ++is) {
|
||||
unsigned int id = interactions.next_id ();
|
||||
const TS *shape = is.operator-> ();
|
||||
interactions.add_subject (id, *shape);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class TS, class TI>
|
||||
struct scan_shape2shape_different_layers_flat
|
||||
{
|
||||
void
|
||||
operator () (const generic_shape_iterator<TS> &subjects, const generic_shape_iterator<TI> &intruders, bool needs_isolated_subjects, unsigned int intruder_layer, shape_interactions<TS, TI> &interactions, db::Coord dist) const
|
||||
operator () (const generic_shape_iterator<TS> &subjects, const generic_shape_iterator<TI> &intruders, unsigned int intruder_layer, shape_interactions<TS, TI> &interactions, db::Coord dist) const
|
||||
{
|
||||
db::box_scanner2<TS, int, TI, int> scanner;
|
||||
interaction_registration_shape2shape<TS, TI> rec (0 /*layout*/, &interactions, intruder_layer);
|
||||
|
|
@ -1956,46 +1966,14 @@ struct scan_shape2shape_different_layers_flat
|
|||
|
||||
db::Box common_box = intruders_box & subjects_box;
|
||||
if (common_box.empty ()) {
|
||||
|
||||
if (needs_isolated_subjects) {
|
||||
for (generic_shape_iterator<TS> is = subjects; ! is.at_end (); ++is) {
|
||||
// create subject for subject vs. nothing interactions
|
||||
interactions.add_subject (interactions.next_id (), *is);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
addressable_shape_delivery<TS> is;
|
||||
|
||||
if (needs_isolated_subjects) {
|
||||
|
||||
box_convert<TS> bcs;
|
||||
|
||||
is = addressable_shape_delivery<TS> (subjects);
|
||||
for ( ; !is.at_end (); ++is) {
|
||||
|
||||
unsigned int id = interactions.next_id ();
|
||||
const TS *shape = is.operator-> ();
|
||||
|
||||
if (bcs (*shape).overlaps (common_box)) {
|
||||
scanner.insert1 (shape, id);
|
||||
}
|
||||
|
||||
// create subject for subject vs. nothing interactions
|
||||
interactions.add_subject (id, *shape);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
is = addressable_shape_delivery<TS> (subjects.confined (common_box, true));
|
||||
for ( ; !is.at_end (); ++is) {
|
||||
scanner.insert1 (is.operator-> (), interactions.next_id ());
|
||||
}
|
||||
|
||||
is = addressable_shape_delivery<TS> (subjects.confined (common_box, true));
|
||||
for ( ; !is.at_end (); ++is) {
|
||||
scanner.insert1 (is.operator-> (), interactions.next_id ());
|
||||
}
|
||||
|
||||
addressable_shape_delivery<TI> ii (intruders.confined (common_box, true));
|
||||
|
|
@ -2022,13 +2000,16 @@ local_processor<TS, TI, TR>::run_flat (const generic_shape_iterator<TS> &subject
|
|||
tl_assert (mp_intruder_top == 0);
|
||||
|
||||
shape_interactions<TS, TI> interactions;
|
||||
bool needs_isolated_subjects = (op->on_empty_intruder_hint () != OnEmptyIntruderHint::Drop);
|
||||
|
||||
if (op->on_empty_intruder_hint () != OnEmptyIntruderHint::Drop) {
|
||||
add_subjects_vs_nothing_flat<TS, TI> () (subjects, interactions);
|
||||
}
|
||||
|
||||
for (typename std::vector<generic_shape_iterator<TI> >::const_iterator il = intruders.begin (); il != intruders.end (); ++il) {
|
||||
if (*il == subjects) {
|
||||
scan_shape2shape_same_layer_flat<TS, TI> () (subjects, needs_isolated_subjects, (unsigned int) (il - intruders.begin ()), interactions, op->dist ());
|
||||
scan_shape2shape_same_layer_flat<TS, TI> () (subjects, (unsigned int) (il - intruders.begin ()), interactions, op->dist ());
|
||||
} else {
|
||||
scan_shape2shape_different_layers_flat<TS, TI> () (subjects, *il, needs_isolated_subjects, (unsigned int) (il - intruders.begin ()), interactions, op->dist ());
|
||||
scan_shape2shape_different_layers_flat<TS, TI> () (subjects, *il, (unsigned int) (il - intruders.begin ()), interactions, op->dist ());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "tlUnitTest.h"
|
||||
|
||||
#include "dbRegion.h"
|
||||
#include "dbCompoundOperation.h"
|
||||
#include "dbReader.h"
|
||||
#include "dbRecursiveShapeIterator.h"
|
||||
#include "dbTestSupport.h"
|
||||
|
||||
#include "tlStream.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
TEST(1_Basic)
|
||||
{
|
||||
db::Layout ly;
|
||||
{
|
||||
std::string fn (tl::testsrc ());
|
||||
fn += "/testdata/drc/compound_1.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (ly);
|
||||
}
|
||||
|
||||
db::RegionCheckOptions check_options;
|
||||
check_options.metrics = db::Projection;
|
||||
|
||||
db::CompoundRegionCheckOperationNode width_check (db::WidthRelation, false /*==same polygon*/, 1050, check_options);
|
||||
|
||||
unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0));
|
||||
db::Region r (db::RecursiveShapeIterator (ly, ly.cell (*ly.begin_top_down ()), l1));
|
||||
|
||||
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
|
||||
db::Region r2 (db::RecursiveShapeIterator (ly, ly.cell (*ly.begin_top_down ()), l2));
|
||||
|
||||
db::EdgePairs res = r.cop_to_edge_pairs (width_check);
|
||||
|
||||
unsigned int l1000 = ly.get_layer (db::LayerProperties (1000, 0));
|
||||
res.insert_into (&ly, *ly.begin_top_down (), l1000);
|
||||
|
||||
db::CompoundRegionOperationPrimaryNode *primary = new db::CompoundRegionOperationPrimaryNode ();
|
||||
db::CompoundRegionCheckOperationNode space_check (primary, db::SpaceRelation, true /*==different polygons*/, 1050, check_options);
|
||||
|
||||
res = r.cop_to_edge_pairs (space_check);
|
||||
|
||||
unsigned int l1001 = ly.get_layer (db::LayerProperties (1001, 0));
|
||||
res.insert_into (&ly, *ly.begin_top_down (), l1001);
|
||||
|
||||
db::CompoundRegionOperationSecondaryNode *secondary = new db::CompoundRegionOperationSecondaryNode (&r2);
|
||||
db::CompoundRegionCheckOperationNode sep_check (secondary, db::SpaceRelation, true /*==different polygons*/, 1050, check_options);
|
||||
|
||||
res = r.cop_to_edge_pairs (sep_check);
|
||||
|
||||
unsigned int l1002 = ly.get_layer (db::LayerProperties (1002, 0));
|
||||
res.insert_into (&ly, *ly.begin_top_down (), l1002);
|
||||
|
||||
CHECKPOINT();
|
||||
db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/drc/compound_au1.gds");
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ TARGET = db_tests
|
|||
include($$PWD/../../lib_ut.pri)
|
||||
|
||||
SOURCES = \
|
||||
dbCompoundOperationTests.cc \
|
||||
dbWriterTools.cc \
|
||||
dbLoadLayoutOptionsTests.cc \
|
||||
dbSaveLayoutOptionsTests.cc \
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue