mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
25165c46a3
commit
55fc4a8728
|
|
@ -1378,13 +1378,13 @@ 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 Region *stop_at) const
|
||||
AsIfFlatRegion::sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode, const Region *stop_at) const
|
||||
{
|
||||
return sized_inside (inside, d, d, steps, mode, stop_at);
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
AsIfFlatRegion::sized_inside (const Region *inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const Region *stop_at) const
|
||||
AsIfFlatRegion::sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const Region *stop_at) const
|
||||
{
|
||||
if (steps <= 0) {
|
||||
return clone ();
|
||||
|
|
|
|||
|
|
@ -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 Region *stop_at) const;
|
||||
virtual RegionDelegate *sized_inside (const Region *inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const Region *stop_at) const;
|
||||
virtual RegionDelegate *sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode, const Region *stop_at) const;
|
||||
virtual RegionDelegate *sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const Region *stop_at) const;
|
||||
|
||||
virtual RegionDelegate *and_with (const Region &other, PropertyConstraint property_constraint) const;
|
||||
virtual RegionDelegate *not_with (const Region &other, PropertyConstraint property_constraint) const;
|
||||
|
|
|
|||
|
|
@ -1782,19 +1782,13 @@ 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 Region *stop_at) const
|
||||
DeepRegion::sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode, const Region *stop_at) const
|
||||
{
|
||||
if (steps <= 0) {
|
||||
return clone ();
|
||||
}
|
||||
|
||||
|
||||
return 0; // @@@
|
||||
|
||||
return sized_inside (inside, d, d, steps, mode, stop_at);
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
DeepRegion::sized_inside (const Region *inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const Region *stop_at) const
|
||||
DeepRegion::sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const Region *stop_at) const
|
||||
{
|
||||
if (steps <= 0 || empty ()) {
|
||||
// Nothing to do - NOTE: don't return EmptyRegion because we want to
|
||||
|
|
@ -1802,13 +1796,49 @@ DeepRegion::sized_inside (const Region *inside, coord_type dx, coord_type dy, in
|
|||
return clone ();
|
||||
}
|
||||
|
||||
if (dx == dy) {
|
||||
return sized_inside (inside, dx, steps, mode, stop_at);
|
||||
const db::DeepRegion *inside_deep = dynamic_cast<const db::DeepRegion *> (inside.delegate ());
|
||||
if (! inside_deep) {
|
||||
return db::AsIfFlatRegion::sized_inside (inside, dx, dy, steps, mode, stop_at);
|
||||
}
|
||||
|
||||
const db::DeepRegion *stop_at_deep = 0;
|
||||
if (stop_at) {
|
||||
|
||||
return 0; // @@@
|
||||
stop_at_deep = dynamic_cast<const db::DeepRegion *> (stop_at->delegate ());
|
||||
if (! stop_at_deep) {
|
||||
return db::AsIfFlatRegion::sized_inside (inside, dx, dy, steps, mode, stop_at);
|
||||
}
|
||||
|
||||
if (&inside_deep->deep_layer ().layout () != &stop_at_deep->deep_layer ().layout ()
|
||||
|| &inside_deep->deep_layer ().initial_cell () != &stop_at_deep->deep_layer ().initial_cell ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("'sized_inside' operation needs to use the same layout and top cell "
|
||||
"for 'inside' and 'stop_at' arguments")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const db::DeepLayer &polygons = merged_deep_layer ();
|
||||
const db::DeepLayer &inside_polygons = inside_deep->deep_layer ();
|
||||
|
||||
db::sized_inside_local_operation<db::PolygonRef, db::PolygonRef, db::PolygonRef> op (dx, dy, steps, mode);
|
||||
|
||||
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::vector<unsigned int> other_layers;
|
||||
other_layers.push_back (inside_polygons.layer ());
|
||||
if (stop_at_deep) {
|
||||
other_layers.push_back (stop_at_deep->deep_layer ().layer ());
|
||||
}
|
||||
|
||||
proc.run (&op, polygons.layer (), other_layers, res->deep_layer ().layer ());
|
||||
|
||||
return res.release ();
|
||||
}
|
||||
|
||||
template <class TR, class Output>
|
||||
|
|
|
|||
|
|
@ -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 Region *stop_at) const;
|
||||
virtual RegionDelegate *sized_inside (const Region *inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const Region *stop_at) const;
|
||||
virtual RegionDelegate *sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode, const Region *stop_at) const;
|
||||
virtual RegionDelegate *sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const Region *stop_at) const;
|
||||
|
||||
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ public:
|
|||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~EdgeSink () { };
|
||||
virtual ~EdgeSink () { }
|
||||
|
||||
/**
|
||||
* @brief Start event
|
||||
|
|
@ -1095,6 +1095,34 @@ private:
|
|||
void redo_or_process (const std::vector<std::pair<db::EdgeSink *, db::EdgeEvaluatorBase *> > &gen, bool redo);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An edge sink feeding into an EdgeProcessor
|
||||
*/
|
||||
class DB_PUBLIC EdgesToEdgeProcessor
|
||||
: public EdgeSink
|
||||
{
|
||||
public:
|
||||
EdgesToEdgeProcessor (db::EdgeProcessor &ep, db::EdgeProcessor::property_type prop)
|
||||
: mp_ep (&ep), m_prop (prop)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual void put (const db::Edge &edge)
|
||||
{
|
||||
mp_ep->insert (edge, m_prop);
|
||||
}
|
||||
|
||||
virtual void put (const db::Edge &edge, int /*tag*/)
|
||||
{
|
||||
mp_ep->insert (edge, m_prop);
|
||||
}
|
||||
|
||||
private:
|
||||
db::EdgeProcessor *mp_ep;
|
||||
db::EdgeProcessor::property_type m_prop;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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 Region *) const { return new EmptyRegion (); }
|
||||
virtual RegionDelegate *sized_inside (const Region *, coord_type, coord_type, int, unsigned int, const Region *) const { return new EmptyRegion (); }
|
||||
virtual RegionDelegate *sized_inside (const Region &, coord_type, int, unsigned int, const Region *) const { return new EmptyRegion (); }
|
||||
virtual RegionDelegate *sized_inside (const Region &, coord_type, coord_type, int, unsigned int, const Region *) 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 (); }
|
||||
|
|
|
|||
|
|
@ -294,6 +294,22 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compatibility with path_ref
|
||||
*/
|
||||
path<C> instantiate () const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compatibility with path_ref
|
||||
*/
|
||||
void instantiate (path<C> &p) const
|
||||
{
|
||||
p = *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The (dummy) translation operator
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1667,6 +1667,22 @@ public:
|
|||
return !equal (b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compatibility with polygon_ref
|
||||
*/
|
||||
polygon<C> instantiate () const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compatibility with polygon_ref
|
||||
*/
|
||||
void instantiate (polygon<C> &poly) const
|
||||
{
|
||||
poly = *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the polygon is a simple box
|
||||
*/
|
||||
|
|
@ -2508,6 +2524,22 @@ public:
|
|||
m_hull.assign (p.begin_hull (), p.end_hull (), tr, false, compress, true /*normalize*/, remove_reflected);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compatibility with polygon_ref
|
||||
*/
|
||||
simple_polygon<C> instantiate () const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compatibility with polygon_ref
|
||||
*/
|
||||
void instantiate (simple_polygon<C> &poly) const
|
||||
{
|
||||
poly = *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The (dummy) translation operator
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -531,6 +531,30 @@ private:
|
|||
unsigned int m_mode;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A polygon sink feeding into an EdgeProcessor
|
||||
*/
|
||||
class DB_PUBLIC PolygonsToEdgeProcessor
|
||||
: public PolygonSink
|
||||
{
|
||||
public:
|
||||
PolygonsToEdgeProcessor (db::EdgeProcessor &ep, db::EdgeProcessor::property_type prop, db::EdgeProcessor::property_type prop_step)
|
||||
: mp_ep (&ep), m_prop (prop), m_prop_step (prop_step)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual void put (const db::Polygon &polygon)
|
||||
{
|
||||
mp_ep->insert (polygon, m_prop);
|
||||
m_prop += m_prop_step;
|
||||
}
|
||||
|
||||
private:
|
||||
db::EdgeProcessor *mp_ep;
|
||||
db::EdgeProcessor::property_type m_prop, m_prop_step;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -310,27 +310,27 @@ 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, const db::Region *stop_at)
|
||||
Region::size_inside (const db::Region &inside, coord_type d, int steps, unsigned int mode, const db::Region *stop_at)
|
||||
{
|
||||
set_delegate (mp_delegate->sized_inside (inside, d, steps, mode, stop_at));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Region &
|
||||
Region::size_inside (const db::Region *inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const db::Region *stop_at)
|
||||
Region::size_inside (const db::Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const db::Region *stop_at)
|
||||
{
|
||||
set_delegate (mp_delegate->sized_inside (inside, dx, dy, steps, mode, stop_at));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Region
|
||||
Region::sized_inside (const db::Region *inside, coord_type d, int steps, unsigned int mode, const db::Region *stop_at) const
|
||||
Region::sized_inside (const db::Region &inside, coord_type d, int steps, unsigned int mode, const db::Region *stop_at) const
|
||||
{
|
||||
return Region (mp_delegate->sized_inside (inside, d, steps, mode, stop_at));
|
||||
}
|
||||
|
||||
Region
|
||||
Region::sized_inside (const db::Region *inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const db::Region *stop_at) const
|
||||
Region::sized_inside (const db::Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const db::Region *stop_at) const
|
||||
{
|
||||
return Region (mp_delegate->sized_inside (inside, dx, dy, steps, mode, stop_at));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1037,14 +1037,14 @@ public:
|
|||
* can be supplied. With a stop condition, sizing will stop when the sized region touches
|
||||
* a shape on the "stop_at" region.
|
||||
*
|
||||
* @param inside The confinement region or 0 for "no confinement"
|
||||
* @param inside The confinement 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.
|
||||
* @param stop_at The stop condition or 0 for "not stopping"
|
||||
* @return A reference to self
|
||||
*/
|
||||
Region &size_inside (const db::Region *inside, coord_type d, int steps, unsigned int mode = 2, const db::Region *stop_at = 0);
|
||||
Region &size_inside (const db::Region &inside, coord_type d, int steps, unsigned int mode = 2, const db::Region *stop_at = 0);
|
||||
|
||||
/**
|
||||
* @brief Size the region incrementally and anisotropically
|
||||
|
|
@ -1056,7 +1056,7 @@ public:
|
|||
* can be supplied. With a stop condition, sizing will stop when the sized region touches
|
||||
* a shape on the "stop_at" region.
|
||||
*
|
||||
* @param inside The confinement region or 0 for "no confinement"
|
||||
* @param inside The confinement region
|
||||
* @param dx The x sizing value
|
||||
* @param dy The y sizing value
|
||||
* @param steps The number of steps to take
|
||||
|
|
@ -1064,7 +1064,7 @@ public:
|
|||
* @param stop_at The stop condition or 0 for "not stopping"
|
||||
* @return A reference to self
|
||||
*/
|
||||
Region &size_inside (const db::Region *inside, coord_type dx, coord_type dy, int steps, unsigned int mode = 2, const db::Region *stop_at = 0);
|
||||
Region &size_inside (const db::Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode = 2, const db::Region *stop_at = 0);
|
||||
|
||||
/**
|
||||
* @brief Returns the sized region
|
||||
|
|
@ -1074,7 +1074,7 @@ public:
|
|||
*
|
||||
* Merged semantics applies.
|
||||
*/
|
||||
Region sized_inside (const db::Region *inside, coord_type d, int steps, unsigned int mode = 2, const db::Region *stop_at = 0) const;
|
||||
Region sized_inside (const db::Region &inside, coord_type d, int steps, unsigned int mode = 2, const db::Region *stop_at = 0) const;
|
||||
|
||||
/**
|
||||
* @brief Returns the sized region
|
||||
|
|
@ -1084,7 +1084,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 db::Region *stop_at = 0) const;
|
||||
Region sized_inside (const db::Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode = 2, const db::Region *stop_at = 0) 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 Region *stop_at) const = 0;
|
||||
virtual RegionDelegate *sized_inside (const Region *inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const Region *stop_at) const = 0;
|
||||
virtual RegionDelegate *sized_inside (const Region &inside, coord_type d, int steps, unsigned int mode, const Region *stop_at) const = 0;
|
||||
virtual RegionDelegate *sized_inside (const Region &inside, coord_type dx, coord_type dy, int steps, unsigned int mode, const Region *stop_at) 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;
|
||||
|
|
|
|||
|
|
@ -1944,6 +1944,172 @@ std::string two_bool_and_not_local_operation_with_properties<TS, TI, TR>::descri
|
|||
template class DB_PUBLIC two_bool_and_not_local_operation_with_properties<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
|
||||
template class DB_PUBLIC two_bool_and_not_local_operation_with_properties<db::Polygon, db::Polygon, db::Polygon>;
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// 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)
|
||||
: m_dx (dx), m_dy (dy), m_steps (steps), m_mode (mode)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
db::Coord
|
||||
sized_inside_local_operation<TS, TI, TR>::dist () const
|
||||
{
|
||||
return std::max (0, std::max (m_dx, m_dy));
|
||||
}
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
OnEmptyIntruderHint
|
||||
sized_inside_local_operation<TS, TI, TR>::on_empty_intruder_hint () const
|
||||
{
|
||||
return Drop;
|
||||
}
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
std::string
|
||||
sized_inside_local_operation<TS, TI, TR>::description () const
|
||||
{
|
||||
return tl::to_string (tr ("Sized inside"));
|
||||
}
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
void
|
||||
sized_inside_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase *proc) const
|
||||
{
|
||||
tl_assert (results.size () == 1);
|
||||
std::unordered_set<TR> &result = results.front ();
|
||||
|
||||
const db::ICplxTrans &tr = proc->vars ()->single_variant_transformation (subject_cell->cell_index ());
|
||||
double mag = tr.mag ();
|
||||
double angle = tr.angle ();
|
||||
|
||||
double dx_with_mag = m_dx / mag;
|
||||
double dy_with_mag = m_dy / mag;
|
||||
if (fabs (angle - 90.0) < 45.0) {
|
||||
// TODO: how to handle x/y swapping on arbitrary angles?
|
||||
std::swap (dx_with_mag, dy_with_mag);
|
||||
}
|
||||
|
||||
// collect subjects and intruder shapes
|
||||
|
||||
std::vector<db::Polygon> subjects;
|
||||
std::set<const TI *> inside;
|
||||
std::set<const TI *> stop_at;
|
||||
|
||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (typename shape_interactions<TS, TI>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
const std::pair<unsigned int, TI> &is = interactions.intruder_shape (*j);
|
||||
if (is.first == 0) {
|
||||
inside.insert (&is.second);
|
||||
} else if (is.first == 1) {
|
||||
stop_at.insert (&is.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 ());
|
||||
}
|
||||
|
||||
// prepare the edge processors involved
|
||||
|
||||
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;
|
||||
|
||||
for (int step = 0; step < m_steps && ! subjects.empty (); ++step) {
|
||||
|
||||
db::Coord sx = db::coord_traits<db::Coord>::rounded (dx_with_mag * (step + 1) / double (m_steps));
|
||||
db::Coord sy = db::coord_traits<db::Coord>::rounded (dy_with_mag * (step + 1) / double (m_steps));
|
||||
db::Coord dx = sx - sx_last;
|
||||
db::Coord dy = sy - sy_last;
|
||||
sx_last = sx;
|
||||
sy_last = sy;
|
||||
|
||||
ep_and.clear ();
|
||||
|
||||
db::EdgesToEdgeProcessor e2ep (ep_and, 0);
|
||||
db::SizingPolygonFilter siz (e2ep, dx, dy, m_mode);
|
||||
for (auto i = subjects.begin (); i != subjects.end (); ++i) {
|
||||
siz.put (*i);
|
||||
}
|
||||
|
||||
db::EdgeProcessor::property_type p = 1;
|
||||
for (auto i = inside.begin (); i != inside.end (); ++i) {
|
||||
ep_and.insert (**i, p);
|
||||
p += 2;
|
||||
}
|
||||
|
||||
db::PolygonContainer pc (subjects, true /*clear*/);
|
||||
db::PolygonGenerator pg (pc, false /*don't resolve holes*/, false /*min. coherence*/);
|
||||
db::BooleanOp op (db::BooleanOp::And);
|
||||
ep_and.process (pg, op);
|
||||
|
||||
if (! subjects.empty () && ! stop_at.empty ()) {
|
||||
|
||||
// compute interations with "stop_at"
|
||||
|
||||
ep_interact.clear ();
|
||||
|
||||
db::EdgeProcessor::property_type p = 0;
|
||||
for (auto i = subjects.begin (); i != subjects.end (); ++i, ++p) {
|
||||
ep_interact.insert (*i, p);
|
||||
}
|
||||
|
||||
db::EdgeProcessor::property_type nstart = p;
|
||||
for (auto i = stop_at.begin (); i != stop_at.end (); ++i, ++p) {
|
||||
ep_interact.insert (**i, p);
|
||||
}
|
||||
|
||||
db::InteractionDetector id (0 /*interacting*/, nstart - 1);
|
||||
id.set_include_touching (true);
|
||||
db::EdgeSink es;
|
||||
ep_interact.process (es, id);
|
||||
id.finish ();
|
||||
|
||||
std::set<size_t> interacting;
|
||||
for (db::InteractionDetector::iterator i = id.begin (); i != id.end (); ++i) {
|
||||
interacting.insert (i->first);
|
||||
}
|
||||
|
||||
// drop interacting subjects
|
||||
|
||||
if (! interacting.empty ()) {
|
||||
std::vector<db::Polygon>::iterator iw = subjects.begin ();
|
||||
for (auto i = subjects.begin (); i != subjects.end (); ++i) {
|
||||
if (interacting.find (i - subjects.begin ()) == interacting.end ()) {
|
||||
if (iw != i) {
|
||||
iw->swap (*i);
|
||||
}
|
||||
++iw;
|
||||
}
|
||||
}
|
||||
subjects.erase (iw, subjects.end ());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
db::polygon_ref_generator<TR> gen (layout, result);
|
||||
for (auto i = subjects.begin (); i != subjects.end (); ++i) {
|
||||
gen.put (*i);
|
||||
}
|
||||
}
|
||||
|
||||
template class DB_PUBLIC sized_inside_local_operation<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
|
||||
template class DB_PUBLIC sized_inside_local_operation<db::Polygon, db::Polygon, db::Polygon>;
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
SelfOverlapMergeLocalOperation::SelfOverlapMergeLocalOperation (unsigned int wrap_count)
|
||||
|
|
|
|||
|
|
@ -463,6 +463,35 @@ private:
|
|||
|
||||
typedef two_bool_and_not_local_operation_with_properties<db::PolygonRef, db::PolygonRef, db::PolygonRef> TwoBoolAndNotLocalOperationWithProperties;
|
||||
|
||||
/**
|
||||
* @brief Implements "sized_inside"
|
||||
*/
|
||||
template <class TS, class TI, class TR>
|
||||
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);
|
||||
|
||||
virtual db::Coord dist () const;
|
||||
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
|
||||
virtual std::string description () const;
|
||||
|
||||
virtual void do_compute_local (db::Layout *layout, db::Cell *subject_cell, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, const db::LocalProcessorBase * /*proc*/) const;
|
||||
|
||||
virtual const db::TransformationReducer *vars () const
|
||||
{
|
||||
return m_dx != m_dy ? (const db::TransformationReducer *) &m_vars_anisotropic : (const db::TransformationReducer *) &m_vars_isotropic;
|
||||
}
|
||||
|
||||
private:
|
||||
db::Coord m_dx, m_dy;
|
||||
int m_steps;
|
||||
unsigned int m_mode;
|
||||
db::MagnificationAndOrientationReducer m_vars_anisotropic;
|
||||
db::MagnificationReducer m_vars_isotropic;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Implements a merge operation with an overlap count
|
||||
* With a given wrap_count, the result will only contains shapes where
|
||||
|
|
|
|||
|
|
@ -1009,13 +1009,13 @@ size_dvm (db::Region *region, const db::Vector &dv, unsigned int mode)
|
|||
}
|
||||
|
||||
static db::Region
|
||||
sized_inside_dvm (const db::Region *region, const db::Region *inside, const db::Vector &dv, int steps, unsigned int mode, const db::Region *stop_at)
|
||||
sized_inside_dvm (const db::Region *region, const db::Region &inside, const db::Vector &dv, int steps, unsigned int mode, const db::Region *stop_at)
|
||||
{
|
||||
return region->sized_inside (inside, dv.x (), dv.y (), steps, mode, stop_at);
|
||||
}
|
||||
|
||||
static db::Region &
|
||||
size_inside_dvm (db::Region *region, const db::Region *inside, const db::Vector &dv, int steps, unsigned int mode, const db::Region *stop_at)
|
||||
size_inside_dvm (db::Region *region, const db::Region &inside, const db::Vector &dv, int steps, unsigned int mode, const db::Region *stop_at)
|
||||
{
|
||||
region->sized_inside (inside, dv.x (), dv.y (), steps, mode, stop_at);
|
||||
return *region;
|
||||
|
|
@ -1942,10 +1942,10 @@ 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, const db::Region *)) &db::Region::size_inside, gsi::arg ("inside"), gsi::arg ("dx"), gsi::arg ("dy"), gsi::arg ("steps"), gsi::arg ("mode"), gsi::arg ("stop_at", (db::Region *) 0, "nil"),
|
||||
method ("size_inside", (db::Region & (db::Region::*) (const db::Region &, db::Coord, db::Coord, int, unsigned int, const db::Region *)) &db::Region::size_inside, gsi::arg ("inside"), gsi::arg ("dx"), gsi::arg ("dy"), gsi::arg ("steps"), gsi::arg ("mode"), gsi::arg ("stop_at", (db::Region *) 0, "nil"),
|
||||
"@brief Incremental, anisotropic sizing inside of another region\n"
|
||||
"\n"
|
||||
"@param inside The region the incremental sizing will stay inside. Can be nil to skip the inside condition.\n"
|
||||
"@param inside The region the incremental sizing will stay inside.\n"
|
||||
"@param dx The x sizing value\n"
|
||||
"@param dy The y sizing value\n"
|
||||
"@param steps The number of steps to take\n"
|
||||
|
|
@ -1960,12 +1960,13 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"This is repeated until the full sizing value is applied.\n"
|
||||
"\n"
|
||||
"This operaton is employed to implement latch-up rules where a device needs to be close to a well tap within the "
|
||||
"same will. For this, the incremental size of the device active region with the well as the 'inside' region is applied. The step is chosen as "
|
||||
"same well. For this, the incremental size of the device active region with the well as the 'inside' region is applied. The step is chosen as "
|
||||
"somewhat less than the minimum well space, so sizing the active region results in a growing footprint that "
|
||||
"follows the well contours.\n"
|
||||
"\n"
|
||||
"A stop region can be specified, meaning that the sizing propagation will stop if the sized region "
|
||||
"touches a shape from the stop region. In case of the latch-up rule application this will be the well tap layer.\n"
|
||||
"A stop region can be specified, meaning that the sizing propagation will stop if the sized shape "
|
||||
"touches a shape from the stop region. If that happens, the sized shape is discarded. "
|
||||
"In case of the latch-up rule application, the stop region will be the well tap layer.\n"
|
||||
"\n"
|
||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
"\n"
|
||||
|
|
@ -1982,7 +1983,7 @@ 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, const db::Region *)) &db::Region::size_inside, gsi::arg ("inside"), gsi::arg ("d"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2), gsi::arg ("stop_at", (db::Region *) 0, "nil"),
|
||||
method ("size_inside", (db::Region & (db::Region::*) (const db::Region &, db::Coord, int, unsigned int, const db::Region *)) &db::Region::size_inside, gsi::arg ("inside"), gsi::arg ("d"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2), gsi::arg ("stop_at", (db::Region *) 0, "nil"),
|
||||
"@brief Incremental, isotropic sizing inside of another region\n"
|
||||
"\n"
|
||||
"@return The region after the sizing has applied (self)\n"
|
||||
|
|
@ -1993,7 +1994,7 @@ 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 *) const) &db::Region::sized_inside, gsi::arg ("inside"), gsi::arg ("dx"), gsi::arg ("dy"), gsi::arg ("steps"), gsi::arg ("mode"), gsi::arg ("stop_at", (db::Region *) 0, "nil"),
|
||||
method ("sized_inside", (db::Region (db::Region::*) (const db::Region &, db::Coord, db::Coord, int, unsigned int, const db::Region *) const) &db::Region::sized_inside, gsi::arg ("inside"), gsi::arg ("dx"), gsi::arg ("dy"), gsi::arg ("steps"), gsi::arg ("mode"), gsi::arg ("stop_at", (db::Region *) 0, "nil"),
|
||||
"@brief Returns the incrementally and anisotropically sized region\n"
|
||||
"\n"
|
||||
"@return The sized region\n"
|
||||
|
|
@ -2013,7 +2014,7 @@ 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 *) const) &db::Region::sized_inside, gsi::arg ("inside"), gsi::arg ("d"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2), gsi::arg ("stop_at", (db::Region *) 0, "nil"),
|
||||
method ("sized_inside", (db::Region (db::Region::*) (const db::Region &, db::Coord, int, unsigned int, const db::Region *) const) &db::Region::sized_inside, gsi::arg ("inside"), gsi::arg ("d"), gsi::arg ("steps"), gsi::arg ("mode", (unsigned int) 2), gsi::arg ("stop_at", (db::Region *) 0, "nil"),
|
||||
"@brief Returns the incrementally sized region\n"
|
||||
"\n"
|
||||
"@return The sized region\n"
|
||||
|
|
|
|||
Loading…
Reference in New Issue