mirror of https://github.com/KLayout/klayout.git
Partial segments of edges converted to hierarchical operations.
This commit is contained in:
parent
74006b6208
commit
7ef0451ca8
|
|
@ -424,8 +424,31 @@ AsIfFlatEdges::extended (coord_type ext_b, coord_type ext_e, coord_type ext_o, c
|
|||
}
|
||||
}
|
||||
|
||||
db::Edge
|
||||
AsIfFlatEdges::compute_partial (const db::Edge &edge, int mode, length_type length, double fraction)
|
||||
{
|
||||
double l = std::max (edge.double_length () * fraction, double (length));
|
||||
|
||||
if (mode < 0) {
|
||||
|
||||
return db::Edge (edge.p1 (), db::Point (db::DPoint (edge.p1 ()) + db::DVector (edge.d ()) * (l / edge.double_length ())));
|
||||
|
||||
} else if (mode > 0) {
|
||||
|
||||
return db::Edge (db::Point (db::DPoint (edge.p2 ()) - db::DVector (edge.d ()) * (l / edge.double_length ())), edge.p2 ());
|
||||
|
||||
} else {
|
||||
|
||||
db::DVector dl = db::DVector (edge.d ()) * (0.5 * l / edge.double_length ());
|
||||
db::DPoint center = db::DPoint (edge.p1 ()) + db::DVector (edge.p2 () - edge.p1 ()) * 0.5;
|
||||
|
||||
return db::Edge (db::Point (center - dl), db::Point (center + dl));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::start_segments (length_type length, double fraction) const
|
||||
AsIfFlatEdges::segments (int mode, length_type length, double fraction) const
|
||||
{
|
||||
std::auto_ptr<FlatEdges> edges (new FlatEdges ());
|
||||
edges->reserve (size ());
|
||||
|
|
@ -436,51 +459,28 @@ AsIfFlatEdges::start_segments (length_type length, double fraction) const
|
|||
}
|
||||
|
||||
for (EdgesIterator e (begin_merged ()); ! e.at_end (); ++e) {
|
||||
double l = std::max (e->double_length () * fraction, double (length));
|
||||
edges->insert (db::Edge (e->p1 (), db::Point (db::DPoint (e->p1 ()) + db::DVector (e->d()) * (l / e->double_length ()))));
|
||||
edges->insert (compute_partial (*e, mode, length, fraction));
|
||||
}
|
||||
|
||||
return edges.release ();
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::start_segments (length_type length, double fraction) const
|
||||
{
|
||||
return segments (-1, length, fraction);
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::end_segments (length_type length, double fraction) const
|
||||
{
|
||||
std::auto_ptr<FlatEdges> edges (new FlatEdges ());
|
||||
edges->reserve (size ());
|
||||
|
||||
// zero-length edges would vanish in merged sematics, so we don't set it now
|
||||
if (length == 0) {
|
||||
edges->set_merged_semantics (false);
|
||||
}
|
||||
|
||||
for (EdgesIterator e (begin_merged ()); ! e.at_end (); ++e) {
|
||||
double l = std::max (e->double_length () * fraction, double (length));
|
||||
edges->insert (db::Edge (db::Point (db::DPoint (e->p2 ()) - db::DVector (e->d()) * (l / e->double_length ())), e->p2 ()));
|
||||
}
|
||||
|
||||
return edges.release ();
|
||||
return segments (1, length, fraction);
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::centers (length_type length, double fraction) const
|
||||
{
|
||||
std::auto_ptr<FlatEdges> edges (new FlatEdges ());
|
||||
edges->reserve (size ());
|
||||
|
||||
// zero-length edges would vanish in merged sematics, so we don't set it now
|
||||
if (length == 0) {
|
||||
edges->set_merged_semantics (false);
|
||||
}
|
||||
|
||||
for (EdgesIterator e (begin_merged ()); ! e.at_end (); ++e) {
|
||||
double l = std::max (e->double_length () * fraction, double (length));
|
||||
db::DVector dl = db::DVector (e->d()) * (0.5 * l / e->double_length ());
|
||||
db::DPoint center = db::DPoint (e->p1 ()) + db::DVector (e->p2 () - e->p1 ()) * 0.5;
|
||||
edges->insert (db::Edge (db::Point (center - dl), db::Point (center + dl)));
|
||||
}
|
||||
|
||||
return edges.release ();
|
||||
return segments (0, length, fraction);
|
||||
}
|
||||
|
||||
namespace
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ protected:
|
|||
void invalidate_bbox ();
|
||||
EdgePairs run_check (db::edge_relation_type rel, const Edges *other, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection) const;
|
||||
static db::Polygon extended_edge (const db::Edge &edge, coord_type ext_b, coord_type ext_e, coord_type ext_o, coord_type ext_i);
|
||||
static db::Edge compute_partial (const db::Edge &edge, int mode, length_type length, double fraction);
|
||||
|
||||
private:
|
||||
AsIfFlatEdges &operator= (const AsIfFlatEdges &other);
|
||||
|
|
@ -195,6 +196,7 @@ private:
|
|||
virtual db::Box compute_bbox () const;
|
||||
EdgesDelegate *boolean (const Edges *other, EdgeBoolOp op) const;
|
||||
EdgesDelegate *edge_region_op (const Region &other, bool outside, bool include_borders) const;
|
||||
EdgesDelegate *segments (int mode, length_type length, double fraction) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -900,22 +900,60 @@ RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_t
|
|||
return res.release ();
|
||||
}
|
||||
|
||||
EdgesDelegate *DeepEdges::segments (int mode, length_type length, double fraction) const
|
||||
{
|
||||
ensure_merged_edges_valid ();
|
||||
|
||||
std::auto_ptr<db::DeepEdges> res (new db::DeepEdges (m_merged_edges.derived ()));
|
||||
|
||||
db::Layout &layout = const_cast<db::Layout &> (m_merged_edges.layout ());
|
||||
db::Cell &top_cell = const_cast<db::Cell &> (m_merged_edges.initial_cell ());
|
||||
|
||||
db::MagnificationReducer red;
|
||||
db::cell_variants_collector<db::MagnificationReducer> vars (red);
|
||||
vars.collect (m_merged_edges.layout (), m_merged_edges.initial_cell ());
|
||||
|
||||
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > to_commit;
|
||||
|
||||
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
|
||||
|
||||
const std::map<db::ICplxTrans, size_t> &vv = vars.variants (c->cell_index ());
|
||||
for (std::map<db::ICplxTrans, size_t>::const_iterator v = vv.begin (); v != vv.end (); ++v) {
|
||||
|
||||
db::Shapes *out;
|
||||
if (vv.size () == 1) {
|
||||
out = & c->shapes (res->deep_layer ().layer ());
|
||||
} else {
|
||||
out = & to_commit [c->cell_index ()][v->first];
|
||||
}
|
||||
|
||||
for (db::Shapes::shape_iterator si = c->shapes (m_merged_edges.layer ()).begin (db::ShapeIterator::Edges); ! si.at_end (); ++si) {
|
||||
out->insert (compute_partial (si->edge ().transformed (v->first), mode, length, fraction).transformed (v->first.inverted ()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// propagate results from variants
|
||||
vars.commit_shapes (layout, top_cell, res->deep_layer ().layer (), to_commit);
|
||||
|
||||
return res.release ();
|
||||
}
|
||||
|
||||
EdgesDelegate *DeepEdges::start_segments (length_type length, double fraction) const
|
||||
{
|
||||
// TODO: implement
|
||||
return AsIfFlatEdges::start_segments (length, fraction);
|
||||
return segments (-1, length, fraction);
|
||||
}
|
||||
|
||||
EdgesDelegate *DeepEdges::end_segments (length_type length, double fraction) const
|
||||
{
|
||||
// TODO: implement
|
||||
return AsIfFlatEdges::end_segments (length, fraction);
|
||||
return segments (1, length, fraction);
|
||||
}
|
||||
|
||||
EdgesDelegate *DeepEdges::centers (length_type length, double fraction) const
|
||||
{
|
||||
// TODO: implement
|
||||
return AsIfFlatEdges::centers (length, fraction);
|
||||
return segments (0, length, fraction);
|
||||
}
|
||||
|
||||
EdgesDelegate *DeepEdges::selected_interacting (const Edges &other) const
|
||||
|
|
|
|||
|
|
@ -173,6 +173,7 @@ private:
|
|||
DeepLayer and_or_not_with(const DeepEdges *other, bool and_op) const;
|
||||
DeepLayer edge_region_op (const DeepRegion *other, bool outside, bool include_borders) const;
|
||||
EdgePairs run_check (db::edge_relation_type rel, const Edges *other, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection) const;
|
||||
EdgesDelegate *segments (int mode, length_type length, double fraction) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -294,3 +294,51 @@ TEST(6_Extended)
|
|||
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_edges_au6.gds");
|
||||
}
|
||||
|
||||
TEST(7_Partial)
|
||||
{
|
||||
db::Layout ly;
|
||||
{
|
||||
std::string fn (tl::testsrc ());
|
||||
fn += "/testdata/algo/deep_region_area_peri_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 l2 = ly.get_layer (db::LayerProperties (2, 0));
|
||||
|
||||
db::Region r2 (db::RecursiveShapeIterator (ly, top_cell, l2), dss);
|
||||
db::Edges e2 = r2.edges ();
|
||||
|
||||
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 (2, 0)), r2);
|
||||
|
||||
db::EdgeLengthFilter elf1 (0, 40000, false);
|
||||
db::Edges e2f = e2.filtered (elf1);
|
||||
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), e2.start_segments (1000, 0.0));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), e2.start_segments (0, 0.2));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (12, 0)), e2f.start_segments (1000, 0.0));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (13, 0)), e2f.start_segments (0, 0.2));
|
||||
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (20, 0)), e2.end_segments (1000, 0.0));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (21, 0)), e2.end_segments (0, 0.2));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (22, 0)), e2f.end_segments (1000, 0.0));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (23, 0)), e2f.end_segments (0, 0.2));
|
||||
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (30, 0)), e2.centers (1000, 0.0));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (31, 0)), e2.centers (0, 0.2));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (32, 0)), e2f.centers (1000, 0.0));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (33, 0)), e2f.centers (0, 0.2));
|
||||
|
||||
CHECKPOINT();
|
||||
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_edges_au7.gds");
|
||||
}
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue