mirror of https://github.com/KLayout/klayout.git
Hierarchical implementation DRC functions (measurements)
This commit is contained in:
parent
5a994fef6d
commit
5dc833970b
|
|
@ -716,14 +716,14 @@ DeepRegion::to_string (size_t nmax) const
|
||||||
EdgePairs
|
EdgePairs
|
||||||
DeepRegion::grid_check (db::Coord gx, db::Coord gy) const
|
DeepRegion::grid_check (db::Coord gx, db::Coord gy) const
|
||||||
{
|
{
|
||||||
// NOTE: snap be optimized by forming grid variants etc.
|
// TODO: snap be optimized by forming grid variants etc.
|
||||||
return db::AsIfFlatRegion::grid_check (gx, gy);
|
return db::AsIfFlatRegion::grid_check (gx, gy);
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgePairs
|
EdgePairs
|
||||||
DeepRegion::angle_check (double min, double max, bool inverse) const
|
DeepRegion::angle_check (double min, double max, bool inverse) const
|
||||||
{
|
{
|
||||||
// NOTE: snap be optimized by forming rotation variants etc.
|
// TODO: snap be optimized by forming rotation variants etc.
|
||||||
return db::AsIfFlatRegion::angle_check (min, max, inverse);
|
return db::AsIfFlatRegion::angle_check (min, max, inverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1241,41 +1241,63 @@ class CheckLocalOperation
|
||||||
: public local_operation<db::PolygonRef, db::PolygonRef, db::EdgePair>
|
: public local_operation<db::PolygonRef, db::PolygonRef, db::EdgePair>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CheckLocalOperation (const EdgeRelationFilter &check, bool different_polygons)
|
CheckLocalOperation (const EdgeRelationFilter &check, bool different_polygons, bool has_other)
|
||||||
: m_check (check), m_different_polygons (different_polygons)
|
: m_check (check), m_different_polygons (different_polygons), m_has_other (has_other)
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::unordered_set<db::EdgePair> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
|
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::unordered_set<db::EdgePair> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
|
||||||
{
|
{
|
||||||
edge2edge_check<std::unordered_set<db::EdgePair> > edge_check (m_check, result, false, false);
|
edge2edge_check<std::unordered_set<db::EdgePair> > edge_check (m_check, result, m_different_polygons, m_has_other);
|
||||||
poly2poly_check<std::unordered_set<db::EdgePair> > poly_check (edge_check);
|
poly2poly_check<std::unordered_set<db::EdgePair> > poly_check (edge_check);
|
||||||
|
|
||||||
std::set<db::PolygonRef> others;
|
std::list<db::Polygon> heap;
|
||||||
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
|
||||||
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
|
||||||
others.insert (interactions.intruder_shape (*j));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t n = 0;
|
|
||||||
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i, ++n) {
|
|
||||||
const db::PolygonRef &subject = interactions.subject_shape (i->first);
|
|
||||||
db::Polygon poly = subject.obj ().transformed (subject.trans ());
|
|
||||||
poly_check.enter (poly, n);
|
|
||||||
n += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = 1;
|
|
||||||
for (std::set<db::PolygonRef>::const_iterator o = others.begin (); o != others.end (); ++o) {
|
|
||||||
db::Polygon poly = o->obj ().transformed (o->trans ());
|
|
||||||
poly_check.enter (poly, n);
|
|
||||||
n += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
db::box_scanner<db::Polygon, size_t> scanner;
|
db::box_scanner<db::Polygon, size_t> scanner;
|
||||||
|
|
||||||
|
if (m_has_other) {
|
||||||
|
|
||||||
|
std::set<db::PolygonRef> others;
|
||||||
|
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||||
|
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||||
|
others.insert (interactions.intruder_shape (*j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t n = 0;
|
||||||
|
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||||
|
const db::PolygonRef &subject = interactions.subject_shape (i->first);
|
||||||
|
heap.push_back (subject.obj ().transformed (subject.trans ()));
|
||||||
|
scanner.insert (& heap.back (), n);
|
||||||
|
n += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = 1;
|
||||||
|
for (std::set<db::PolygonRef>::const_iterator o = others.begin (); o != others.end (); ++o) {
|
||||||
|
heap.push_back (o->obj ().transformed (o->trans ()));
|
||||||
|
scanner.insert (& heap.back (), n);
|
||||||
|
n += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
std::set<db::PolygonRef> polygons;
|
||||||
|
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||||
|
polygons.insert (interactions.subject_shape (i->first));
|
||||||
|
for (shape_interactions<db::PolygonRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||||
|
polygons.insert (interactions.intruder_shape (*j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t n = 0;
|
||||||
|
for (std::set<db::PolygonRef>::const_iterator o = polygons.begin (); o != polygons.end (); ++o) {
|
||||||
|
heap.push_back (o->obj ().transformed (o->trans ()));
|
||||||
|
scanner.insert (& heap.back (), n);
|
||||||
|
n += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
scanner.process (poly_check, m_check.distance (), db::box_convert<db::Polygon> ());
|
scanner.process (poly_check, m_check.distance (), db::box_convert<db::Polygon> ());
|
||||||
} while (edge_check.prepare_next_pass ());
|
} while (edge_check.prepare_next_pass ());
|
||||||
|
|
@ -1283,7 +1305,7 @@ public:
|
||||||
|
|
||||||
virtual db::Coord dist () const
|
virtual db::Coord dist () const
|
||||||
{
|
{
|
||||||
// TODO: will the distance be sufficient? Or should be take somewhat more?
|
// TODO: will the distance be sufficient? Or should we take somewhat more?
|
||||||
return m_check.distance ();
|
return m_check.distance ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1300,6 +1322,7 @@ public:
|
||||||
private:
|
private:
|
||||||
EdgeRelationFilter m_check;
|
EdgeRelationFilter m_check;
|
||||||
bool m_different_polygons;
|
bool m_different_polygons;
|
||||||
|
bool m_has_other;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1307,9 +1330,12 @@ private:
|
||||||
EdgePairs
|
EdgePairs
|
||||||
DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection) const
|
DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection) const
|
||||||
{
|
{
|
||||||
const db::DeepRegion *other_deep = dynamic_cast<const db::DeepRegion *> (other->delegate ());
|
const db::DeepRegion *other_deep = 0;
|
||||||
if (! other_deep) {
|
if (other) {
|
||||||
return db::AsIfFlatRegion::run_check (rel, different_polygons, other, d, whole_edges, metrics, ignore_angle, min_projection, max_projection);
|
other_deep = dynamic_cast<const db::DeepRegion *> (other->delegate ());
|
||||||
|
if (! other_deep) {
|
||||||
|
return db::AsIfFlatRegion::run_check (rel, different_polygons, other, d, whole_edges, metrics, ignore_angle, min_projection, max_projection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ensure_merged_polygons_valid ();
|
ensure_merged_polygons_valid ();
|
||||||
|
|
@ -1320,16 +1346,19 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons
|
||||||
check.set_min_projection (min_projection);
|
check.set_min_projection (min_projection);
|
||||||
check.set_max_projection (max_projection);
|
check.set_max_projection (max_projection);
|
||||||
|
|
||||||
DeepLayer dl_out (m_deep_layer.derived ());
|
|
||||||
std::auto_ptr<db::DeepEdgePairs> res (new db::DeepEdgePairs (m_merged_polygons.derived ()));
|
std::auto_ptr<db::DeepEdgePairs> res (new db::DeepEdgePairs (m_merged_polygons.derived ()));
|
||||||
|
|
||||||
db::CheckLocalOperation op (check, different_polygons);
|
db::CheckLocalOperation op (check, different_polygons, other_deep != 0);
|
||||||
|
|
||||||
|
db::local_processor<db::PolygonRef, db::PolygonRef, db::EdgePair> proc (const_cast<db::Layout *> (&m_deep_layer.layout ()),
|
||||||
|
const_cast<db::Cell *> (&m_deep_layer.initial_cell ()),
|
||||||
|
other_deep ? &other_deep->deep_layer ().layout () : const_cast<db::Layout *> (&m_deep_layer.layout ()),
|
||||||
|
other_deep ? &other_deep->deep_layer ().initial_cell () : const_cast<db::Cell *> (&m_deep_layer.initial_cell ()));
|
||||||
|
|
||||||
db::local_processor<db::PolygonRef, db::PolygonRef, db::EdgePair> proc (const_cast<db::Layout *> (&m_deep_layer.layout ()), const_cast<db::Cell *> (&m_deep_layer.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ());
|
|
||||||
proc.set_base_verbosity (base_verbosity ());
|
proc.set_base_verbosity (base_verbosity ());
|
||||||
proc.set_threads (m_deep_layer.store ()->threads ());
|
proc.set_threads (m_deep_layer.store ()->threads ());
|
||||||
|
|
||||||
proc.run (&op, m_merged_polygons.layer (), other_deep->deep_layer ().layer (), dl_out.layer ());
|
proc.run (&op, m_merged_polygons.layer (), other_deep ? other_deep->deep_layer ().layer () : m_merged_polygons.layer (), res->deep_layer ().layer ());
|
||||||
|
|
||||||
return db::EdgePairs (res.release ());
|
return db::EdgePairs (res.release ());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -274,8 +274,18 @@ public:
|
||||||
*
|
*
|
||||||
* Creates an edge pair set representing a single instance of that object
|
* Creates an edge pair set representing a single instance of that object
|
||||||
*/
|
*/
|
||||||
template <class Sh>
|
explicit EdgePairs (const db::EdgePair &s)
|
||||||
explicit EdgePairs (const Sh &s)
|
: mp_delegate (0)
|
||||||
|
{
|
||||||
|
insert (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor from an object
|
||||||
|
*
|
||||||
|
* Creates an edge pair set representing a single instance of that object
|
||||||
|
*/
|
||||||
|
explicit EdgePairs (const db::Shape &s)
|
||||||
: mp_delegate (0)
|
: mp_delegate (0)
|
||||||
{
|
{
|
||||||
insert (s);
|
insert (s);
|
||||||
|
|
|
||||||
|
|
@ -315,10 +315,10 @@ local_processor_cell_context<TS, TI, TR>::propagate (const std::unordered_set<TR
|
||||||
|
|
||||||
template class DB_PUBLIC local_processor_cell_context<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
|
template class DB_PUBLIC local_processor_cell_context<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
|
||||||
template class DB_PUBLIC local_processor_cell_context<db::PolygonRef, db::Edge, db::PolygonRef>;
|
template class DB_PUBLIC local_processor_cell_context<db::PolygonRef, db::Edge, db::PolygonRef>;
|
||||||
template class DB_PUBLIC local_processor_cell_context<db::PolygonRef, db::Edge, db::EdgePair>;
|
template class DB_PUBLIC local_processor_cell_context<db::PolygonRef, db::PolygonRef, db::EdgePair>;
|
||||||
template class DB_PUBLIC local_processor_cell_context<db::Edge, db::Edge, db::Edge>;
|
template class DB_PUBLIC local_processor_cell_context<db::Edge, db::Edge, db::Edge>;
|
||||||
template class DB_PUBLIC local_processor_cell_context<db::Edge, db::Polygon, db::Edge>;
|
template class DB_PUBLIC local_processor_cell_context<db::Edge, db::Polygon, db::Edge>;
|
||||||
template class DB_PUBLIC local_processor_cell_context<db::Edge, db::Polygon, db::EdgePair>;
|
template class DB_PUBLIC local_processor_cell_context<db::Edge, db::Edge, db::EdgePair>;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------
|
||||||
// LocalProcessorCellContexts implementation
|
// LocalProcessorCellContexts implementation
|
||||||
|
|
@ -1033,7 +1033,7 @@ template class DB_PUBLIC local_processor_result_computation_task<db::PolygonRef,
|
||||||
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonRef, db::PolygonRef, db::EdgePair>;
|
template class DB_PUBLIC local_processor_result_computation_task<db::PolygonRef, db::PolygonRef, db::EdgePair>;
|
||||||
template class DB_PUBLIC local_processor_result_computation_task<db::Edge, db::Edge, db::Edge>;
|
template class DB_PUBLIC local_processor_result_computation_task<db::Edge, db::Edge, db::Edge>;
|
||||||
template class DB_PUBLIC local_processor_result_computation_task<db::Edge, db::PolygonRef, db::Edge>;
|
template class DB_PUBLIC local_processor_result_computation_task<db::Edge, db::PolygonRef, db::Edge>;
|
||||||
template class DB_PUBLIC local_processor_result_computation_task<db::Edge, db::PolygonRef, db::EdgePair>;
|
template class DB_PUBLIC local_processor_result_computation_task<db::Edge, db::Edge, db::EdgePair>;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------
|
||||||
// LocalProcessor implementation
|
// LocalProcessor implementation
|
||||||
|
|
@ -1610,10 +1610,10 @@ local_processor<TS, TI, TR>::compute_local_cell (const db::local_processor_conte
|
||||||
|
|
||||||
template class DB_PUBLIC local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
|
template class DB_PUBLIC local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
|
||||||
template class DB_PUBLIC local_processor<db::PolygonRef, db::Edge, db::PolygonRef>;
|
template class DB_PUBLIC local_processor<db::PolygonRef, db::Edge, db::PolygonRef>;
|
||||||
template class DB_PUBLIC local_processor<db::PolygonRef, db::Edge, db::EdgePair>;
|
template class DB_PUBLIC local_processor<db::PolygonRef, db::PolygonRef, db::EdgePair>;
|
||||||
template class DB_PUBLIC local_processor<db::Edge, db::Edge, db::Edge>;
|
template class DB_PUBLIC local_processor<db::Edge, db::Edge, db::Edge>;
|
||||||
template class DB_PUBLIC local_processor<db::Edge, db::PolygonRef, db::Edge>;
|
template class DB_PUBLIC local_processor<db::Edge, db::PolygonRef, db::Edge>;
|
||||||
template class DB_PUBLIC local_processor<db::Edge, db::PolygonRef, db::EdgePair>;
|
template class DB_PUBLIC local_processor<db::Edge, db::Edge, db::EdgePair>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -927,6 +927,92 @@ TEST(16_MergeWithMinWC)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(17_SinglePolygonChecks)
|
||||||
|
{
|
||||||
|
db::Layout ly;
|
||||||
|
{
|
||||||
|
std::string fn (tl::testsrc ());
|
||||||
|
fn += "/testdata/algo/deep_region_l1.gds";
|
||||||
|
tl::InputStream stream (fn);
|
||||||
|
db::Reader reader (stream);
|
||||||
|
reader.read (ly);
|
||||||
|
}
|
||||||
|
|
||||||
|
db::cell_index_type top_cell_index = *ly.begin_top_down ();
|
||||||
|
db::Cell &top_cell = ly.cell (top_cell_index);
|
||||||
|
|
||||||
|
db::DeepShapeStore dss;
|
||||||
|
|
||||||
|
unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0));
|
||||||
|
unsigned int l6 = ly.get_layer (db::LayerProperties (6, 0));
|
||||||
|
unsigned int l4 = ly.get_layer (db::LayerProperties (4, 0));
|
||||||
|
|
||||||
|
db::Region r3 (db::RecursiveShapeIterator (ly, top_cell, l3), dss);
|
||||||
|
db::Region r6 (db::RecursiveShapeIterator (ly, top_cell, l6), dss);
|
||||||
|
db::Region r4 (db::RecursiveShapeIterator (ly, top_cell, l4), dss);
|
||||||
|
|
||||||
|
{
|
||||||
|
db::Layout target;
|
||||||
|
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
|
||||||
|
|
||||||
|
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (3, 0)), r3);
|
||||||
|
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (4, 0)), r4);
|
||||||
|
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (6, 0)), r6);
|
||||||
|
|
||||||
|
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), r3.width_check (260, false, db::Euclidian, 90, 0));
|
||||||
|
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), r3.width_check (260, true, db::Projection, 90, 2000));
|
||||||
|
|
||||||
|
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (20, 0)), r6.notch_check (1300, false, db::Euclidian, 90, 0));
|
||||||
|
|
||||||
|
CHECKPOINT();
|
||||||
|
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au17.gds");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(18_Checks)
|
||||||
|
{
|
||||||
|
db::Layout ly;
|
||||||
|
{
|
||||||
|
std::string fn (tl::testsrc ());
|
||||||
|
fn += "/testdata/algo/deep_region_l1.gds";
|
||||||
|
tl::InputStream stream (fn);
|
||||||
|
db::Reader reader (stream);
|
||||||
|
reader.read (ly);
|
||||||
|
}
|
||||||
|
|
||||||
|
db::cell_index_type top_cell_index = *ly.begin_top_down ();
|
||||||
|
db::Cell &top_cell = ly.cell (top_cell_index);
|
||||||
|
|
||||||
|
db::DeepShapeStore dss;
|
||||||
|
|
||||||
|
unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0));
|
||||||
|
unsigned int l6 = ly.get_layer (db::LayerProperties (6, 0));
|
||||||
|
unsigned int l4 = ly.get_layer (db::LayerProperties (4, 0));
|
||||||
|
|
||||||
|
db::Region r3 (db::RecursiveShapeIterator (ly, top_cell, l3), dss);
|
||||||
|
db::Region r6 (db::RecursiveShapeIterator (ly, top_cell, l6), dss);
|
||||||
|
db::Region r4 (db::RecursiveShapeIterator (ly, top_cell, l4), dss);
|
||||||
|
|
||||||
|
{
|
||||||
|
db::Layout target;
|
||||||
|
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
|
||||||
|
|
||||||
|
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (3, 0)), r3);
|
||||||
|
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (4, 0)), r4);
|
||||||
|
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (6, 0)), r6);
|
||||||
|
|
||||||
|
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), r3.space_check (500, false, db::Projection, 90, 0));
|
||||||
|
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), r3.space_check (500, true, db::Projection, 90, 300));
|
||||||
|
|
||||||
|
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (20, 0)), r3.separation_check (r4, 200, false, db::Projection, 90, 0));
|
||||||
|
|
||||||
|
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (30, 0)), r6.enclosing_check (r4, 100, true, db::Projection, 90, 0));
|
||||||
|
|
||||||
|
CHECKPOINT();
|
||||||
|
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au18.gds");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(100_Integration)
|
TEST(100_Integration)
|
||||||
{
|
{
|
||||||
db::Layout ly;
|
db::Layout ly;
|
||||||
|
|
|
||||||
|
|
@ -296,7 +296,7 @@ GDS2WriterBase::write (db::Layout &layout, tl::OutputStream &stream, const db::S
|
||||||
int layer = l->second.layer;
|
int layer = l->second.layer;
|
||||||
int datatype = l->second.datatype;
|
int datatype = l->second.datatype;
|
||||||
|
|
||||||
db::ShapeIterator shape (cref.shapes (l->first).begin (db::ShapeIterator::Boxes | db::ShapeIterator::Polygons | db::ShapeIterator::Edges | db::ShapeIterator::Paths | db::ShapeIterator::Texts));
|
db::ShapeIterator shape (cref.shapes (l->first).begin (db::ShapeIterator::Boxes | db::ShapeIterator::Polygons | db::ShapeIterator::Edges | db::ShapeIterator::EdgePairs | db::ShapeIterator::Paths | db::ShapeIterator::Texts));
|
||||||
while (! shape.at_end ()) {
|
while (! shape.at_end ()) {
|
||||||
|
|
||||||
progress_checkpoint ();
|
progress_checkpoint ();
|
||||||
|
|
@ -307,6 +307,9 @@ GDS2WriterBase::write (db::Layout &layout, tl::OutputStream &stream, const db::S
|
||||||
write_polygon (layer, datatype, sf, *shape, multi_xy, max_vertex_count, layout, shape->prop_id ());
|
write_polygon (layer, datatype, sf, *shape, multi_xy, max_vertex_count, layout, shape->prop_id ());
|
||||||
} else if (shape->is_edge ()) {
|
} else if (shape->is_edge ()) {
|
||||||
write_edge (layer, datatype, sf, *shape, layout, shape->prop_id ());
|
write_edge (layer, datatype, sf, *shape, layout, shape->prop_id ());
|
||||||
|
} else if (shape->is_edge_pair ()) {
|
||||||
|
write_edge (layer, datatype, sf, shape->edge_pair ().first (), layout, shape->prop_id ());
|
||||||
|
write_edge (layer, datatype, sf, shape->edge_pair ().second (), layout, shape->prop_id ());
|
||||||
} else if (shape->is_path ()) {
|
} else if (shape->is_path ()) {
|
||||||
if (no_zero_length_paths && (shape->path_length () - shape->path_extensions ().first - shape->path_extensions ().second) == 0) {
|
if (no_zero_length_paths && (shape->path_length () - shape->path_extensions ().first - shape->path_extensions ().second) == 0) {
|
||||||
// eliminate the zero-width path
|
// eliminate the zero-width path
|
||||||
|
|
@ -580,8 +583,12 @@ GDS2WriterBase::write_path (int layer, int datatype, double sf, const db::Shape
|
||||||
void
|
void
|
||||||
GDS2WriterBase::write_edge (int layer, int datatype, double sf, const db::Shape &shape, const db::Layout &layout, db::properties_id_type prop_id)
|
GDS2WriterBase::write_edge (int layer, int datatype, double sf, const db::Shape &shape, const db::Layout &layout, db::properties_id_type prop_id)
|
||||||
{
|
{
|
||||||
db::Edge e (shape.edge ());
|
write_edge (layer, datatype, sf, shape.edge (), layout, prop_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GDS2WriterBase::write_edge (int layer, int datatype, double sf, const db::Edge &e, const db::Layout &layout, db::properties_id_type prop_id)
|
||||||
|
{
|
||||||
write_record_size (4);
|
write_record_size (4);
|
||||||
write_record (sPATH);
|
write_record (sPATH);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -134,6 +134,11 @@ protected:
|
||||||
*/
|
*/
|
||||||
void write_edge (int layer, int datatype, double sf, const db::Shape &shape, const db::Layout &layout, db::properties_id_type prop_id);
|
void write_edge (int layer, int datatype, double sf, const db::Shape &shape, const db::Layout &layout, db::properties_id_type prop_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Writes an edge
|
||||||
|
*/
|
||||||
|
void write_edge (int layer, int datatype, double sf, const db::Edge &edge, const db::Layout &layout, db::properties_id_type prop_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Write a shape as path
|
* @brief Write a shape as path
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue