mirror of https://github.com/KLayout/klayout.git
WIP: Implementing flat mode for sized inside/outside
This commit is contained in:
parent
c3d3dd6239
commit
128efd45e4
|
|
@ -1386,7 +1386,8 @@ AsIfFlatRegion::sized_inside (const Region &inside, bool outside, coord_type d,
|
|||
RegionDelegate *
|
||||
AsIfFlatRegion::sized_inside (const Region &inside, bool outside, coord_type dx, coord_type dy, int steps, unsigned int mode) const
|
||||
{
|
||||
// @@@ TODO: restrict max. number of steps in "outside" mode like for DeepRegion
|
||||
// empirical value
|
||||
const int max_steps = 25;
|
||||
|
||||
if (steps <= 0 || empty ()) {
|
||||
// Nothing to do - NOTE: don't return EmptyRegion because we want to
|
||||
|
|
@ -1398,27 +1399,68 @@ AsIfFlatRegion::sized_inside (const Region &inside, bool outside, coord_type dx,
|
|||
throw tl::Exception (tl::to_string (tr ("'sized_inside' operation does not make sense with negative sizing")));
|
||||
}
|
||||
|
||||
std::unique_ptr<FlatRegion> output (new FlatRegion ());
|
||||
std::vector<db::Shapes *> results;
|
||||
results.push_back (&output->raw_polygons ());
|
||||
|
||||
// NOTE: as we merge the inside region in the inside case, we can use distance 0
|
||||
db::Coord dist = outside ? std::max (dx, dy) : 0;
|
||||
bool inside_is_merged = outside ? inside.is_merged () : true;
|
||||
db::sized_inside_local_operation<db::Polygon, db::Polygon, db::Polygon> op (dx, dy, steps, mode, dist, outside, inside_is_merged, true /*split after*/);
|
||||
|
||||
db::local_processor<db::Polygon, db::Polygon, db::Polygon> proc;
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
proc.set_description (progress_desc ());
|
||||
proc.set_report_progress (report_progress ());
|
||||
|
||||
std::vector<db::generic_shape_iterator<db::Polygon> > others;
|
||||
// NOTE: it does not provide benefits to merge the outside region, so just don't
|
||||
others.push_back (outside ? inside.begin () : inside.begin_merged ());
|
||||
auto inside_polygons = outside ? inside.begin () : inside.begin_merged ();
|
||||
bool inside_polygons_is_merged = outside ? inside.is_merged () : true;
|
||||
|
||||
proc.run_flat (begin_merged (), others, std::vector<bool> (), &op, results);
|
||||
auto polygons = begin_merged ();
|
||||
|
||||
return output.release ();
|
||||
std::unique_ptr<FlatRegion> res (new FlatRegion ());
|
||||
std::unique_ptr<FlatRegion> prev;
|
||||
|
||||
int steps_from = 0;
|
||||
|
||||
while (steps > 0) {
|
||||
|
||||
db::Coord dx_chunk = dx, dy_chunk = dy;
|
||||
int steps_chunk = steps;
|
||||
|
||||
// We perform at most max_steps in one chunk.
|
||||
// This is supposed to limit the search range and merge shapes instead of creating
|
||||
// heavily overlapping ones.
|
||||
if (steps > max_steps) {
|
||||
steps_chunk = max_steps;
|
||||
dx_chunk = db::coord_traits<db::Coord>::rounded (dx * max_steps / double (steps));
|
||||
dy_chunk = db::coord_traits<db::Coord>::rounded (dy * max_steps / double (steps));
|
||||
}
|
||||
|
||||
steps -= steps_chunk;
|
||||
dx -= dx_chunk;
|
||||
dy -= dy_chunk;
|
||||
|
||||
// NOTE: as we merge the inside region in the inside case, we can use distance 0
|
||||
db::Coord dist = outside ? std::max (dx_chunk, dy_chunk) : 0;
|
||||
db::sized_inside_local_operation<db::Polygon, db::Polygon, db::Polygon> op (dx_chunk, dy_chunk, steps_chunk, mode, dist, outside, inside_polygons_is_merged);
|
||||
|
||||
db::local_processor<db::Polygon, db::Polygon, db::Polygon> proc;
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
proc.set_description (progress_desc ());
|
||||
proc.set_report_progress (report_progress ());
|
||||
|
||||
// indicate chunk in the progress description
|
||||
proc.set_description (proc.description (&op) + tl::sprintf (tl::to_string (tr (" (steps %d..%d)")), steps_from + 1, steps_from + steps_chunk + 1));
|
||||
|
||||
std::vector<db::generic_shape_iterator<db::Polygon> > others;
|
||||
others.push_back (inside_polygons);
|
||||
|
||||
std::vector<db::Shapes *> results;
|
||||
results.push_back (&res->raw_polygons ());
|
||||
proc.run_flat (prev.get () ? prev->begin () : polygons, others, std::vector<bool> (), &op, results);
|
||||
|
||||
// NOTE: in the last step we apply a polygon breaker in addition to "merge" so the
|
||||
// result is granular for better deep mode performance
|
||||
if (steps > 0) {
|
||||
prev.reset (dynamic_cast<db::FlatRegion *> (res->merged ()));
|
||||
tl_assert (prev.get () != 0);
|
||||
res.reset (new db::FlatRegion ());
|
||||
} else {
|
||||
res.reset (dynamic_cast<db::FlatRegion *> (res->processed (db::PolygonBreaker (proc.max_vertex_count (), proc.area_ratio ()))));
|
||||
tl_assert (res.get () != 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return res.release ();
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
|
|
|
|||
|
|
@ -1839,8 +1839,7 @@ DeepRegion::sized_inside (const Region &inside, bool outside, coord_type dx, coo
|
|||
|
||||
// NOTE: as we merge the inside region in the inside case, we can use distance 0
|
||||
db::Coord dist = outside ? std::max (dx_chunk, dy_chunk) : 0;
|
||||
bool split_after = (steps == 0);
|
||||
db::sized_inside_local_operation<db::PolygonRef, db::PolygonRef, db::PolygonRef> op (dx_chunk, dy_chunk, steps_chunk, mode, dist, outside, inside_polygons_is_merged, split_after);
|
||||
db::sized_inside_local_operation<db::PolygonRef, db::PolygonRef, db::PolygonRef> op (dx_chunk, dy_chunk, steps_chunk, mode, dist, outside, inside_polygons_is_merged);
|
||||
|
||||
db::local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef> proc (const_cast<db::Layout *> (&polygons.layout ()), const_cast<db::Cell *> (&polygons.initial_cell ()), &inside_polygons.layout (), &inside_polygons.initial_cell (), polygons.breakout_cells (), inside_polygons.breakout_cells ());
|
||||
configure_proc (proc);
|
||||
|
|
|
|||
|
|
@ -1948,8 +1948,8 @@ template class DB_PUBLIC two_bool_and_not_local_operation_with_properties<db::Po
|
|||
// sized_inside_local_operation implementation
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
sized_inside_local_operation<TS, TI, TR>::sized_inside_local_operation (db::Coord dx, db::Coord dy, int steps, unsigned int mode, db::Coord dist, bool outside, bool inside_is_merged, bool split_after)
|
||||
: m_dx (dx), m_dy (dy), m_dist (dist), m_steps (steps), m_mode (mode), m_outside (outside), m_inside_is_merged (inside_is_merged), m_split_after (split_after)
|
||||
sized_inside_local_operation<TS, TI, TR>::sized_inside_local_operation (db::Coord dx, db::Coord dy, int steps, unsigned int mode, db::Coord dist, bool outside, bool inside_is_merged)
|
||||
: m_dx (dx), m_dy (dy), m_dist (dist), m_steps (steps), m_mode (mode), m_outside (outside), m_inside_is_merged (inside_is_merged)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -2067,9 +2067,7 @@ sized_inside_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout,
|
|||
}
|
||||
|
||||
db::PolygonContainer pc (subjects, true /*clear*/);
|
||||
db::PolygonSplitter splitter (pc, proc->area_ratio (), proc->max_vertex_count ());
|
||||
// NOTE: we split in the last step if requested
|
||||
db::PolygonGenerator pg ((! m_split_after || step + 1 < m_steps) ? (PolygonSink &) pc : (PolygonSink &) splitter, false /*don't resolve holes*/, false /*min. coherence*/);
|
||||
db::PolygonGenerator pg (pc, false /*don't resolve holes*/, false /*min. coherence*/);
|
||||
db::BooleanOp op (m_outside ? db::BooleanOp::ANotB : db::BooleanOp::And);
|
||||
ep_and.process (pg, op);
|
||||
|
||||
|
|
|
|||
|
|
@ -471,7 +471,7 @@ class DB_PUBLIC sized_inside_local_operation
|
|||
: public local_operation<TS, TI, TR>
|
||||
{
|
||||
public:
|
||||
sized_inside_local_operation (db::Coord dx, db::Coord dy, int steps, unsigned int mode, db::Coord dist, bool outside, bool inside_is_merged, bool split_after);
|
||||
sized_inside_local_operation (db::Coord dx, db::Coord dy, int steps, unsigned int mode, db::Coord dist, bool outside, bool inside_is_merged);
|
||||
|
||||
virtual db::Coord dist () const;
|
||||
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
|
||||
|
|
@ -491,7 +491,6 @@ private:
|
|||
unsigned int m_mode;
|
||||
bool m_outside;
|
||||
bool m_inside_is_merged;
|
||||
bool m_split_after;
|
||||
db::MagnificationAndOrientationReducer m_vars_anisotropic;
|
||||
db::MagnificationReducer m_vars_isotropic;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue