mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
a54365a9a7
commit
8d630e723a
|
|
@ -1378,14 +1378,16 @@ AsIfFlatRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const
|
|||
}
|
||||
|
||||
RegionDelegate *
|
||||
AsIfFlatRegion::sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode) const
|
||||
AsIfFlatRegion::sized_inside (const Region &inside, bool outside, coord_type d, int steps, unsigned int mode) const
|
||||
{
|
||||
return sized_inside (inside, d, d, steps, mode);
|
||||
return sized_inside (inside, outside, d, d, steps, mode);
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
AsIfFlatRegion::sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode) const
|
||||
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
|
||||
|
||||
if (steps <= 0 || empty ()) {
|
||||
// Nothing to do - NOTE: don't return EmptyRegion because we want to
|
||||
// maintain "deepness"
|
||||
|
|
@ -1400,7 +1402,10 @@ AsIfFlatRegion::sized_inside (const Region &inside, coord_type dx, coord_type dy
|
|||
std::vector<db::Shapes *> results;
|
||||
results.push_back (&output->raw_polygons ());
|
||||
|
||||
db::sized_inside_local_operation<db::Polygon, db::Polygon, db::Polygon> op (dx, dy, steps, mode, true /*inside layer is merged*/);
|
||||
// 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 ());
|
||||
|
|
@ -1408,7 +1413,8 @@ AsIfFlatRegion::sized_inside (const Region &inside, coord_type dx, coord_type dy
|
|||
proc.set_report_progress (report_progress ());
|
||||
|
||||
std::vector<db::generic_shape_iterator<db::Polygon> > others;
|
||||
others.push_back (inside.begin_merged ());
|
||||
// NOTE: it does not provide benefits to merge the outside region, so just don't
|
||||
others.push_back (outside ? inside.begin () : inside.begin_merged ());
|
||||
|
||||
proc.run_flat (begin_merged (), others, std::vector<bool> (), &op, results);
|
||||
|
||||
|
|
|
|||
|
|
@ -121,8 +121,8 @@ public:
|
|||
|
||||
virtual RegionDelegate *sized (coord_type d, unsigned int mode) const;
|
||||
virtual RegionDelegate *sized (coord_type dx, coord_type dy, unsigned int mode) const;
|
||||
virtual RegionDelegate *sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode) const;
|
||||
virtual RegionDelegate *sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode) const;
|
||||
virtual RegionDelegate *sized_inside (const Region &inside, bool outside, coord_type d, int steps, unsigned int mode) const;
|
||||
virtual RegionDelegate *sized_inside (const Region &inside, bool outside, coord_type dx, coord_type dy, int steps, unsigned int mode) const;
|
||||
|
||||
virtual RegionDelegate *and_with (const Region &other, PropertyConstraint property_constraint) const;
|
||||
virtual RegionDelegate *not_with (const Region &other, PropertyConstraint property_constraint) const;
|
||||
|
|
|
|||
|
|
@ -1782,14 +1782,17 @@ DeepRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const
|
|||
}
|
||||
|
||||
RegionDelegate *
|
||||
DeepRegion::sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode) const
|
||||
DeepRegion::sized_inside (const Region &inside, bool outside, coord_type d, int steps, unsigned int mode) const
|
||||
{
|
||||
return sized_inside (inside, d, d, steps, mode);
|
||||
return sized_inside (inside, outside, d, d, steps, mode);
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
DeepRegion::sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode) const
|
||||
DeepRegion::sized_inside (const Region &inside, bool outside, coord_type dx, coord_type dy, int steps, unsigned int mode) const
|
||||
{
|
||||
// empirical value
|
||||
const int max_steps = 25;
|
||||
|
||||
if (steps <= 0 || empty ()) {
|
||||
// Nothing to do - NOTE: don't return EmptyRegion because we want to
|
||||
// maintain "deepness"
|
||||
|
|
@ -1805,20 +1808,58 @@ DeepRegion::sized_inside (const Region &inside, coord_type dx, coord_type dy, in
|
|||
return db::AsIfFlatRegion::sized_inside (inside, dx, dy, steps, mode);
|
||||
}
|
||||
|
||||
// NOTE: it does not provide benefits to merge the outside region, so just don't
|
||||
const db::DeepLayer &inside_polygons = outside ? inside_deep->deep_layer () : inside_deep->merged_deep_layer ();
|
||||
bool inside_polygons_is_merged = outside ? inside_deep->is_merged () : true;
|
||||
|
||||
const db::DeepLayer &polygons = merged_deep_layer ();
|
||||
const db::DeepLayer &inside_polygons = inside_deep->merged_deep_layer ();
|
||||
|
||||
db::sized_inside_local_operation<db::PolygonRef, db::PolygonRef, db::PolygonRef> op (dx, dy, steps, mode, true /*inside layer 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);
|
||||
proc.set_threads (polygons.store ()->threads ());
|
||||
proc.set_area_ratio (polygons.store ()->max_area_ratio ());
|
||||
proc.set_max_vertex_count (polygons.store ()->max_vertex_count ());
|
||||
|
||||
std::unique_ptr<db::DeepRegion> res (new db::DeepRegion (polygons.derived ()));
|
||||
std::unique_ptr<db::DeepRegion> prev;
|
||||
|
||||
proc.run (&op, polygons.layer (), inside_polygons.layer (), res->deep_layer ().layer ());
|
||||
int steps_from = 0;
|
||||
|
||||
while (steps > 0) {
|
||||
|
||||
db::Coord dx_chunk = dx, dy_chunk = dy;
|
||||
int steps_chunk = steps;
|
||||
|
||||
// In outside mode, we perform at most max_steps in one chunk.
|
||||
// This is supposed to limit the search range.
|
||||
if (outside && 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;
|
||||
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::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);
|
||||
proc.set_threads (polygons.store ()->threads ());
|
||||
proc.set_area_ratio (polygons.store ()->max_area_ratio ());
|
||||
proc.set_max_vertex_count (polygons.store ()->max_vertex_count ());
|
||||
|
||||
// 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));
|
||||
|
||||
proc.run (&op, prev.get () ? prev->deep_layer ().layer () : polygons.layer (), inside_polygons.layer (), res->deep_layer ().layer ());
|
||||
|
||||
// @@@ TODO: should we also merge in the last step and consider splitting?
|
||||
if (steps > 0) {
|
||||
prev.reset (dynamic_cast<db::DeepRegion *> (res->merged ()));
|
||||
tl_assert (prev.get () != 0);
|
||||
res.reset (new db::DeepRegion (polygons.derived ()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return res.release ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,8 +136,8 @@ public:
|
|||
|
||||
virtual RegionDelegate *sized (coord_type d, unsigned int mode) const;
|
||||
virtual RegionDelegate *sized (coord_type dx, coord_type dy, unsigned int mode) const;
|
||||
virtual RegionDelegate *sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode) const;
|
||||
virtual RegionDelegate *sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode) const;
|
||||
virtual RegionDelegate *sized_inside (const Region &inside, bool outside, coord_type d, int steps, unsigned int mode) const;
|
||||
virtual RegionDelegate *sized_inside (const Region &inside, bool outside, coord_type dx, coord_type dy, int steps, unsigned int mode) const;
|
||||
|
||||
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -97,8 +97,8 @@ public:
|
|||
|
||||
virtual RegionDelegate *sized (coord_type, unsigned int) const { return new EmptyRegion (); }
|
||||
virtual RegionDelegate *sized (coord_type, coord_type, unsigned int) const { return new EmptyRegion (); }
|
||||
virtual RegionDelegate *sized_inside (const Region &, coord_type, int, unsigned int) const { return new EmptyRegion (); }
|
||||
virtual RegionDelegate *sized_inside (const Region &, coord_type, coord_type, int, unsigned int) const { return new EmptyRegion (); }
|
||||
virtual RegionDelegate *sized_inside (const Region &, bool, coord_type, int, unsigned int) const { return new EmptyRegion (); }
|
||||
virtual RegionDelegate *sized_inside (const Region &, bool, coord_type, coord_type, int, unsigned int) const { return new EmptyRegion (); }
|
||||
|
||||
virtual RegionDelegate *and_with (const Region &, db::PropertyConstraint) const { return new EmptyRegion (); }
|
||||
virtual RegionDelegate *not_with (const Region &, db::PropertyConstraint) const { return new EmptyRegion (); }
|
||||
|
|
|
|||
|
|
@ -310,29 +310,29 @@ Region::sized (coord_type dx, coord_type dy, unsigned int mode) const
|
|||
}
|
||||
|
||||
Region &
|
||||
Region::size_inside (const db::Region &inside, coord_type d, int steps, unsigned int mode)
|
||||
Region::size_inside (const db::Region &inside, bool outside, coord_type d, int steps, unsigned int mode)
|
||||
{
|
||||
set_delegate (mp_delegate->sized_inside (inside, d, steps, mode));
|
||||
set_delegate (mp_delegate->sized_inside (inside, outside, d, steps, mode));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Region &
|
||||
Region::size_inside (const db::Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode)
|
||||
Region::size_inside (const db::Region &inside, bool outside, coord_type dx, coord_type dy, int steps, unsigned int mode)
|
||||
{
|
||||
set_delegate (mp_delegate->sized_inside (inside, dx, dy, steps, mode));
|
||||
set_delegate (mp_delegate->sized_inside (inside, outside, dx, dy, steps, mode));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Region
|
||||
Region::sized_inside (const db::Region &inside, coord_type d, int steps, unsigned int mode) const
|
||||
Region::sized_inside (const db::Region &inside, bool outside, coord_type d, int steps, unsigned int mode) const
|
||||
{
|
||||
return Region (mp_delegate->sized_inside (inside, d, steps, mode));
|
||||
return Region (mp_delegate->sized_inside (inside, outside, d, steps, mode));
|
||||
}
|
||||
|
||||
Region
|
||||
Region::sized_inside (const db::Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode) const
|
||||
Region::sized_inside (const db::Region &inside, bool outside, coord_type dx, coord_type dy, int steps, unsigned int mode) const
|
||||
{
|
||||
return Region (mp_delegate->sized_inside (inside, dx, dy, steps, mode));
|
||||
return Region (mp_delegate->sized_inside (inside, outside, dx, dy, steps, mode));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -1035,12 +1035,13 @@ public:
|
|||
* Only positive or zero sizing values are supported.
|
||||
*
|
||||
* @param inside The confinement region
|
||||
* @param outside If true, "inside" is negative - i.e. sizing is performed outside the "inside" region
|
||||
* @param d The (isotropic) sizing value
|
||||
* @param steps The number of steps to take
|
||||
* @param mode The sizing mode (see EdgeProcessor) for a description of the sizing mode which controls the miter distance.
|
||||
* @return A reference to self
|
||||
*/
|
||||
Region &size_inside (const db::Region &inside, coord_type d, int steps, unsigned int mode = 2);
|
||||
Region &size_inside (const db::Region &inside, bool outside, coord_type d, int steps, unsigned int mode = 2);
|
||||
|
||||
/**
|
||||
* @brief Size the region incrementally and anisotropically
|
||||
|
|
@ -1050,13 +1051,14 @@ public:
|
|||
* Only positive or zero sizing values are supported.
|
||||
*
|
||||
* @param inside The confinement region
|
||||
* @param outside If true, "inside" is negative - i.e. sizing is performed outside the "inside" region
|
||||
* @param dx The x sizing value
|
||||
* @param dy The y sizing value
|
||||
* @param steps The number of steps to take
|
||||
* @param mode The sizing mode (see EdgeProcessor) for a description of the sizing mode which controls the miter distance.
|
||||
* @return A reference to self
|
||||
*/
|
||||
Region &size_inside (const db::Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode = 2);
|
||||
Region &size_inside (const db::Region &inside, bool outside, coord_type dx, coord_type dy, int steps, unsigned int mode = 2);
|
||||
|
||||
/**
|
||||
* @brief Returns the sized region
|
||||
|
|
@ -1066,7 +1068,7 @@ public:
|
|||
*
|
||||
* Merged semantics applies.
|
||||
*/
|
||||
Region sized_inside (const db::Region &inside, coord_type d, int steps, unsigned int mode = 2) const;
|
||||
Region sized_inside (const db::Region &inside, bool outside, coord_type d, int steps, unsigned int mode = 2) const;
|
||||
|
||||
/**
|
||||
* @brief Returns the sized region
|
||||
|
|
@ -1076,7 +1078,7 @@ public:
|
|||
*
|
||||
* Merged semantics applies.
|
||||
*/
|
||||
Region sized_inside (const db::Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode = 2) const;
|
||||
Region sized_inside (const db::Region &inside, bool outside, coord_type dx, coord_type dy, int steps, unsigned int mode = 2) const;
|
||||
|
||||
/**
|
||||
* @brief Boolean AND operator
|
||||
|
|
|
|||
|
|
@ -226,8 +226,8 @@ public:
|
|||
|
||||
virtual RegionDelegate *sized (coord_type d, unsigned int mode) const = 0;
|
||||
virtual RegionDelegate *sized (coord_type dx, coord_type dy, unsigned int mode) const = 0;
|
||||
virtual RegionDelegate *sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode) const = 0;
|
||||
virtual RegionDelegate *sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode) const = 0;
|
||||
virtual RegionDelegate *sized_inside (const Region &inside, bool outside, coord_type d, int steps, unsigned int mode) const = 0;
|
||||
virtual RegionDelegate *sized_inside (const Region &inside, bool outside, coord_type dx, coord_type dy, int steps, unsigned int mode) const = 0;
|
||||
|
||||
virtual RegionDelegate *and_with (const Region &other, PropertyConstraint prop_constraint) const = 0;
|
||||
virtual RegionDelegate *not_with (const Region &other, PropertyConstraint prop_constraint) const = 0;
|
||||
|
|
|
|||
|
|
@ -1948,13 +1948,10 @@ 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, bool inside_is_merged)
|
||||
: m_dx (dx), m_dy (dy), m_steps (steps), m_mode (mode), m_dist (0)
|
||||
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)
|
||||
{
|
||||
m_dist = 0;
|
||||
if (! inside_is_merged) {
|
||||
m_dist = std::max (0, std::max (m_dx, m_dy));
|
||||
}
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
|
|
@ -2011,6 +2008,24 @@ sized_inside_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout,
|
|||
}
|
||||
}
|
||||
|
||||
// Merge the inside region shapes as we are going to use them multiple times
|
||||
std::vector<db::Edge> inside_merged;
|
||||
if (inside.size () > 1 && ! m_inside_is_merged && m_steps > 1) {
|
||||
|
||||
db::EdgeProcessor ep;
|
||||
db::SimpleMerge op;
|
||||
db::EdgeContainer ec (inside_merged);
|
||||
|
||||
db::EdgeProcessor::property_type p = 0;
|
||||
for (auto i = inside.begin (); i != inside.end (); ++i, ++p) {
|
||||
ep.insert (**i, p);
|
||||
}
|
||||
ep.process (ec, op);
|
||||
|
||||
inside.clear ();
|
||||
|
||||
}
|
||||
|
||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
subjects.push_back (db::Polygon ());
|
||||
interactions.subject_shape (i->first).instantiate (subjects.back ());
|
||||
|
|
@ -2021,9 +2036,6 @@ sized_inside_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout,
|
|||
db::EdgeProcessor ep_and;
|
||||
ep_and.set_base_verbosity (50);
|
||||
|
||||
db::EdgeProcessor ep_interact;
|
||||
ep_interact.set_base_verbosity (50);
|
||||
|
||||
// the main sizing loop
|
||||
|
||||
db::Coord sx_last = 0, sy_last = 0;
|
||||
|
|
@ -2050,10 +2062,15 @@ sized_inside_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout,
|
|||
ep_and.insert (**i, p);
|
||||
p += 2;
|
||||
}
|
||||
for (auto i = inside_merged.begin (); i != inside_merged.end (); ++i) {
|
||||
ep_and.insert (*i, p);
|
||||
}
|
||||
|
||||
db::PolygonContainer pc (subjects, true /*clear*/);
|
||||
db::PolygonGenerator pg (pc, false /*don't resolve holes*/, false /*min. coherence*/);
|
||||
db::BooleanOp op (db::BooleanOp::And);
|
||||
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::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, bool inside_is_merged);
|
||||
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);
|
||||
|
||||
virtual db::Coord dist () const;
|
||||
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
|
||||
|
|
@ -489,6 +489,9 @@ private:
|
|||
db::Coord m_dist;
|
||||
int m_steps;
|
||||
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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1008,16 +1008,81 @@ size_dvm (db::Region *region, const db::Vector &dv, unsigned int mode)
|
|||
return *region;
|
||||
}
|
||||
|
||||
static db::Region
|
||||
sized_inside_ddm (const db::Region *region, const db::Region &inside, db::Coord dx, db::Coord dy, int steps, unsigned int mode)
|
||||
{
|
||||
return region->sized_inside (inside, false, dx, dy, steps, mode);
|
||||
}
|
||||
|
||||
static db::Region
|
||||
sized_inside_dvm (const db::Region *region, const db::Region &inside, const db::Vector &dv, int steps, unsigned int mode)
|
||||
{
|
||||
return region->sized_inside (inside, dv.x (), dv.y (), steps, mode);
|
||||
return region->sized_inside (inside, false, dv.x (), dv.y (), steps, mode);
|
||||
}
|
||||
|
||||
static db::Region
|
||||
sized_inside_dm (const db::Region *region, const db::Region &inside, db::Coord d, int steps, unsigned int mode)
|
||||
{
|
||||
return region->sized_inside (inside, false, d, steps, mode);
|
||||
}
|
||||
|
||||
static db::Region &
|
||||
size_inside_ddm (db::Region *region, const db::Region &inside, db::Coord dx, db::Coord dy, int steps, unsigned int mode)
|
||||
{
|
||||
region->size_inside (inside, false, dx, dy, steps, mode);
|
||||
return *region;
|
||||
}
|
||||
|
||||
static db::Region &
|
||||
size_inside_dvm (db::Region *region, const db::Region &inside, const db::Vector &dv, int steps, unsigned int mode)
|
||||
{
|
||||
region->sized_inside (inside, dv.x (), dv.y (), steps, mode);
|
||||
region->size_inside (inside, false, dv.x (), dv.y (), steps, mode);
|
||||
return *region;
|
||||
}
|
||||
|
||||
static db::Region &
|
||||
size_inside_dm (db::Region *region, const db::Region &inside, db::Coord d, int steps, unsigned int mode)
|
||||
{
|
||||
region->size_inside (inside, false, d, steps, mode);
|
||||
return *region;
|
||||
}
|
||||
|
||||
static db::Region
|
||||
sized_outside_ddm (const db::Region *region, const db::Region &inside, db::Coord dx, db::Coord dy, int steps, unsigned int mode)
|
||||
{
|
||||
return region->sized_inside (inside, true, dx, dy, steps, mode);
|
||||
}
|
||||
|
||||
static db::Region
|
||||
sized_outside_dvm (const db::Region *region, const db::Region &inside, const db::Vector &dv, int steps, unsigned int mode)
|
||||
{
|
||||
return region->sized_inside (inside, true, dv.x (), dv.y (), steps, mode);
|
||||
}
|
||||
|
||||
static db::Region
|
||||
sized_outside_dm (const db::Region *region, const db::Region &inside, db::Coord d, int steps, unsigned int mode)
|
||||
{
|
||||
return region->sized_inside (inside, true, d, steps, mode);
|
||||
}
|
||||
|
||||
static db::Region &
|
||||
size_outside_ddm (db::Region *region, const db::Region &inside, db::Coord dx, db::Coord dy, int steps, unsigned int mode)
|
||||
{
|
||||
region->size_inside (inside, true, dx, dy, steps, mode);
|
||||
return *region;
|
||||
}
|
||||
|
||||
static db::Region &
|
||||
size_outside_dvm (db::Region *region, const db::Region &inside, const db::Vector &dv, int steps, unsigned int mode)
|
||||
{
|
||||
region->size_inside (inside, true, dv.x (), dv.y (), steps, mode);
|
||||
return *region;
|
||||
}
|
||||
|
||||
static db::Region &
|
||||
size_outside_dm (db::Region *region, const db::Region &inside, db::Coord d, int steps, unsigned int mode)
|
||||
{
|
||||
region->size_inside (inside, true, d, steps, mode);
|
||||
return *region;
|
||||
}
|
||||
|
||||
|
|
@ -1942,7 +2007,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
) +
|
||||
method ("size_inside", (db::Region & (db::Region::*) (const db::Region &, db::Coord, db::Coord, int, unsigned int)) &db::Region::size_inside, gsi::arg ("inside"), gsi::arg ("dx"), gsi::arg ("dy"), gsi::arg ("steps"), gsi::arg ("mode"),
|
||||
method_ext ("size_inside", &size_inside_ddm, gsi::arg ("inside"), gsi::arg ("dx"), gsi::arg ("dy"), gsi::arg ("steps"), gsi::arg ("mode"),
|
||||
"@brief Incremental, anisotropic sizing inside of another region\n"
|
||||
"\n"
|
||||
"@param inside The region the incremental sizing will stay inside.\n"
|
||||
|
|
@ -1967,6 +2032,14 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"This method has been introduced in version 0.29.3."
|
||||
) +
|
||||
method_ext ("size_outside", &size_outside_ddm, gsi::arg ("outside"), gsi::arg ("dx"), gsi::arg ("dy"), gsi::arg ("steps"), gsi::arg ("mode"),
|
||||
"@brief Incremental, anisotropic sizing outside of another region\n"
|
||||
"\n"
|
||||
"This method is equivalent to \\size_inside, except that sizing is performed outside the given 'outside' region. "
|
||||
"Technically this corresponds to a boolean 'NOT' operation instead of a boolean 'AND'.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.29.3."
|
||||
) +
|
||||
method_ext ("size_inside", &size_inside_dvm, gsi::arg ("inside"), gsi::arg ("dv"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2),
|
||||
"@brief Incremental, anisotropic sizing inside of another region\n"
|
||||
"\n"
|
||||
|
|
@ -1978,7 +2051,15 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"This method has been introduced in version 0.29.3."
|
||||
) +
|
||||
method ("size_inside", (db::Region & (db::Region::*) (const db::Region &, db::Coord, int, unsigned int)) &db::Region::size_inside, gsi::arg ("inside"), gsi::arg ("d"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2),
|
||||
method_ext ("size_outside", &size_outside_dvm, gsi::arg ("outside"), gsi::arg ("dv"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2),
|
||||
"@brief Incremental, anisotropic sizing outside of another region\n"
|
||||
"\n"
|
||||
"This method is equivalent to \\size_inside, except that sizing is performed outside the given 'outside' region. "
|
||||
"Technically this corresponds to a boolean 'NOT' operation instead of a boolean 'AND'.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.29.3."
|
||||
) +
|
||||
method_ext ("size_inside", &size_inside_dm, gsi::arg ("inside"), gsi::arg ("d"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2),
|
||||
"@brief Incremental, isotropic sizing inside of another region\n"
|
||||
"\n"
|
||||
"@return The region after the sizing has applied (self)\n"
|
||||
|
|
@ -1989,7 +2070,15 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"This method has been introduced in version 0.29.3."
|
||||
) +
|
||||
method ("sized_inside", (db::Region (db::Region::*) (const db::Region &, db::Coord, db::Coord, int, unsigned int) const) &db::Region::sized_inside, gsi::arg ("inside"), gsi::arg ("dx"), gsi::arg ("dy"), gsi::arg ("steps"), gsi::arg ("mode"),
|
||||
method_ext ("size_outside", &size_outside_dm, gsi::arg ("outside"), gsi::arg ("d"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2),
|
||||
"@brief Incremental, anisotropic sizing outside of another region\n"
|
||||
"\n"
|
||||
"This method is equivalent to \\size_inside, except that sizing is performed outside the given 'outside' region. "
|
||||
"Technically this corresponds to a boolean 'NOT' operation instead of a boolean 'AND'.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.29.3."
|
||||
) +
|
||||
method_ext ("sized_inside", &sized_inside_ddm, gsi::arg ("inside"), gsi::arg ("dx"), gsi::arg ("dy"), gsi::arg ("steps"), gsi::arg ("mode"),
|
||||
"@brief Returns the incrementally and anisotropically sized region\n"
|
||||
"\n"
|
||||
"@return The sized region\n"
|
||||
|
|
@ -1998,6 +2087,14 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
) +
|
||||
method_ext ("sized_outside", &sized_outside_ddm, gsi::arg ("outside"), gsi::arg ("dx"), gsi::arg ("dy"), gsi::arg ("steps"), gsi::arg ("mode"),
|
||||
"@brief Incremental, anisotropic sizing outside of another region\n"
|
||||
"\n"
|
||||
"This method is equivalent to \\size_inside, except that sizing is performed outside the given 'outside' region. "
|
||||
"Technically this corresponds to a boolean 'NOT' operation instead of a boolean 'AND'.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.29.3."
|
||||
) +
|
||||
method_ext ("sized_inside", &sized_inside_dvm, gsi::arg ("inside"), gsi::arg ("dv"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2),
|
||||
"@brief Returns the incrementally and anisotropically sized region\n"
|
||||
"\n"
|
||||
|
|
@ -2009,7 +2106,15 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"This variant has been introduced in version 0.28."
|
||||
) +
|
||||
method ("sized_inside", (db::Region (db::Region::*) (const db::Region &, db::Coord, int, unsigned int) const) &db::Region::sized_inside, gsi::arg ("inside"), gsi::arg ("d"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2),
|
||||
method_ext ("sized_outside", &sized_outside_dvm, gsi::arg ("outside"), gsi::arg ("dv"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2),
|
||||
"@brief Incremental, anisotropic sizing outside of another region\n"
|
||||
"\n"
|
||||
"This method is equivalent to \\size_inside, except that sizing is performed outside the given 'outside' region. "
|
||||
"Technically this corresponds to a boolean 'NOT' operation instead of a boolean 'AND'.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.29.3."
|
||||
) +
|
||||
method_ext ("sized_inside", &sized_inside_dm, gsi::arg ("inside"), gsi::arg ("d"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2),
|
||||
"@brief Returns the incrementally sized region\n"
|
||||
"\n"
|
||||
"@return The sized region\n"
|
||||
|
|
@ -2018,6 +2123,14 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
) +
|
||||
method_ext ("sized_outside", &sized_outside_dm, gsi::arg ("outside"), gsi::arg ("d"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2),
|
||||
"@brief Incremental, anisotropic sizing outside of another region\n"
|
||||
"\n"
|
||||
"This method is equivalent to \\size_inside, except that sizing is performed outside the given 'outside' region. "
|
||||
"Technically this corresponds to a boolean 'NOT' operation instead of a boolean 'AND'.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.29.3."
|
||||
) +
|
||||
method_ext ("andnot", &andnot, gsi::arg ("other"), gsi::arg ("property_constraint", db::IgnoreProperties, "IgnoreProperties"),
|
||||
"@brief Returns the boolean AND and NOT between self and the other region\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -321,6 +321,10 @@ module DRC
|
|||
DRCSizingInside::new(arg)
|
||||
end
|
||||
|
||||
def outside(arg)
|
||||
DRCSizingOutside::new(arg)
|
||||
end
|
||||
|
||||
def padding_zero
|
||||
DRCDensityPadding::new(:zero)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4333,7 +4333,7 @@ CODE
|
|||
value && raise("Value already specified")
|
||||
value = @engine._make_value(a)
|
||||
else
|
||||
raise("Parameter #" + n.to_s + " does not have an expected type")
|
||||
raise("Parameter #" + n.to_s + " if of unexpected type")
|
||||
end
|
||||
n += 1
|
||||
end
|
||||
|
|
@ -4518,7 +4518,7 @@ CODE
|
|||
limits = [ @engine._make_numeric_value_with_nil(a.begin), @engine._make_numeric_value_with_nil(a.end) ]
|
||||
nlimits = 2
|
||||
else
|
||||
raise("Parameter #" + n.to_s + " does not have an expected type")
|
||||
raise("Parameter #" + n.to_s + " is of unexpected type")
|
||||
end
|
||||
n += 1
|
||||
end
|
||||
|
|
@ -4679,7 +4679,11 @@ TP_SCRIPT
|
|||
# @name sized
|
||||
# @brief Polygon sizing (per-edge biasing)
|
||||
# @synopsis layer.sized(d [, mode] [, inside(l) [, steps(n)]])
|
||||
# @synopsis layer.sized(dx, dy [, mode] [, inside(l) [, steps(n)]]))
|
||||
# @synopsis layer.sized(d, inside(l) [, steps(n)] [, mode])
|
||||
# @synopsis layer.sized(d, outside(l) [, steps(n)] [, mode])
|
||||
# @synopsis layer.sized(dx, dy [, mode])
|
||||
# @synopsis layer.sized(dx, dy, inside(l) [, steps(n)] [, mode])
|
||||
# @synopsis layer.sized(dx, dy, outside(l) [, steps(n)] [, mode])
|
||||
#
|
||||
# This method requires a polygon layer. It will apply a bias per edge of the polygons
|
||||
# and return the biased layer. The layer that this method is called on is not modified.
|
||||
|
|
@ -4725,6 +4729,10 @@ TP_SCRIPT
|
|||
#
|
||||
# "inside" and "steps" can be used with positive sizing values only.
|
||||
#
|
||||
# "outside" acts like "inside", but instead of confining the sized region to the
|
||||
# inside of the given layer, it is confined to be outside of that layer. Technically,
|
||||
# a boolean "NOT" is performed instead of a boolean "AND".
|
||||
#
|
||||
# An example for the "inside" option is this:
|
||||
#
|
||||
# @code
|
||||
|
|
@ -4753,8 +4761,12 @@ TP_SCRIPT
|
|||
# %DRC%
|
||||
# @name size
|
||||
# @brief Polygon sizing (per-edge biasing, modifies the layer)
|
||||
# @synopsis layer.size(d [, mode] [, inside(l) [, steps(n)]])
|
||||
# @synopsis layer.size(dx, dy [, mode] [, inside(l) [, steps(n)]]))
|
||||
# @synopsis layer.size(d [, mode])
|
||||
# @synopsis layer.size(d, inside(l) [, steps(n)] [, mode])
|
||||
# @synopsis layer.size(d, outside(l) [, steps(n)] [, mode])
|
||||
# @synopsis layer.size(dx, dy [, mode])
|
||||
# @synopsis layer.size(dx, dy, inside(l) [, steps(n)] [, mode])
|
||||
# @synopsis layer.size(dx, dy, outside(l) [, steps(n)] [, mode])
|
||||
#
|
||||
# See \sized for a description of the options.
|
||||
# The size method basically does the same but modifies the layer
|
||||
|
|
@ -4772,8 +4784,11 @@ TP_SCRIPT
|
|||
|
||||
steps = nil
|
||||
inside = nil
|
||||
outside = nil
|
||||
mode = 2
|
||||
values = []
|
||||
|
||||
n = 1
|
||||
args.each do |a|
|
||||
if a.is_a?(1.class) || a.is_a?(Float)
|
||||
v = @engine._make_value(a)
|
||||
|
|
@ -4785,7 +4800,12 @@ TP_SCRIPT
|
|||
steps = a.value
|
||||
elsif a.is_a?(DRCSizingInside)
|
||||
inside = a.value
|
||||
elsif a.is_a?(DRCSizingOutside)
|
||||
outside = a.value
|
||||
else
|
||||
raise("Parameter #" + n.to_s + " is of unexpected type")
|
||||
end
|
||||
n += 1
|
||||
end
|
||||
|
||||
aa = []
|
||||
|
|
@ -4793,8 +4813,12 @@ TP_SCRIPT
|
|||
f_size = :size
|
||||
f_sized = :sized
|
||||
|
||||
if inside && outside
|
||||
raise "Cannot use 'inside' and 'outside' together"
|
||||
end
|
||||
|
||||
if steps
|
||||
if !inside
|
||||
if !inside && !outside
|
||||
raise "'steps' is only allowed with 'inside'"
|
||||
end
|
||||
if !steps.is_a?(1.class)
|
||||
|
|
@ -4802,17 +4826,30 @@ TP_SCRIPT
|
|||
end
|
||||
end
|
||||
|
||||
if inside
|
||||
if inside || outside
|
||||
|
||||
inside.is_a?(DRCLayer) || raise("'inside' argument needs to be a DRC layer")
|
||||
inside.data.is_a?(RBA::Region) || raise("'inside' requires a polygon layer")
|
||||
aa.push(inside.data)
|
||||
if inside
|
||||
|
||||
inside.is_a?(DRCLayer) || raise("'inside' argument needs to be a DRC layer")
|
||||
inside.data.is_a?(RBA::Region) || raise("'inside' requires a polygon layer")
|
||||
aa.push(inside.data)
|
||||
|
||||
f_size = :size_inside
|
||||
f_sized = :sized_inside
|
||||
|
||||
else
|
||||
|
||||
outside.is_a?(DRCLayer) || raise("'outside' argument needs to be a DRC layer")
|
||||
outside.data.is_a?(RBA::Region) || raise("'outside' requires a polygon layer")
|
||||
aa.push(outside.data)
|
||||
|
||||
f_size = :size_outside
|
||||
f_sized = :sized_outside
|
||||
|
||||
end
|
||||
|
||||
steps ||= 1
|
||||
|
||||
f_size = :size_inside
|
||||
f_sized = :sized_inside
|
||||
|
||||
end
|
||||
|
||||
if values.size < 1
|
||||
|
|
@ -4824,7 +4861,7 @@ TP_SCRIPT
|
|||
aa.push(values[-1])
|
||||
end
|
||||
|
||||
if inside
|
||||
if inside || outside
|
||||
aa.push(steps)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,14 @@ module DRC
|
|||
end
|
||||
end
|
||||
|
||||
# A wrapper for the sizing "outside" value
|
||||
class DRCSizingOutside
|
||||
attr_accessor :value
|
||||
def initialize(v)
|
||||
self.value = v
|
||||
end
|
||||
end
|
||||
|
||||
# A wrapper for the edge mode value for Region#edges
|
||||
class DRCEdgeMode
|
||||
attr_accessor :value
|
||||
|
|
|
|||
Loading…
Reference in New Issue