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 *
|
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);
|
return sized_inside (inside, d, d, steps, mode, stop_at);
|
||||||
}
|
}
|
||||||
|
|
||||||
RegionDelegate *
|
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) {
|
if (steps <= 0) {
|
||||||
return clone ();
|
return clone ();
|
||||||
|
|
|
||||||
|
|
@ -121,8 +121,8 @@ public:
|
||||||
|
|
||||||
virtual RegionDelegate *sized (coord_type d, unsigned int mode) const;
|
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 (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 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 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 *and_with (const Region &other, PropertyConstraint property_constraint) const;
|
||||||
virtual RegionDelegate *not_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 *
|
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 sized_inside (inside, d, d, steps, mode, stop_at);
|
||||||
return clone ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return 0; // @@@
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RegionDelegate *
|
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 ()) {
|
if (steps <= 0 || empty ()) {
|
||||||
// Nothing to do - NOTE: don't return EmptyRegion because we want to
|
// 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 ();
|
return clone ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dx == dy) {
|
const db::DeepRegion *inside_deep = dynamic_cast<const db::DeepRegion *> (inside.delegate ());
|
||||||
return sized_inside (inside, dx, steps, mode, stop_at);
|
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>
|
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 d, unsigned int mode) const;
|
||||||
virtual RegionDelegate *sized (coord_type dx, coord_type dy, 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 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 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;
|
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Destructor
|
* @brief Destructor
|
||||||
*/
|
*/
|
||||||
virtual ~EdgeSink () { };
|
virtual ~EdgeSink () { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Start event
|
* @brief Start event
|
||||||
|
|
@ -1095,6 +1095,34 @@ private:
|
||||||
void redo_or_process (const std::vector<std::pair<db::EdgeSink *, db::EdgeEvaluatorBase *> > &gen, bool redo);
|
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
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -97,8 +97,8 @@ public:
|
||||||
|
|
||||||
virtual RegionDelegate *sized (coord_type, unsigned int) const { return new EmptyRegion (); }
|
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 (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, 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, 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 *and_with (const Region &, db::PropertyConstraint) const { return new EmptyRegion (); }
|
||||||
virtual RegionDelegate *not_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
|
* @brief The (dummy) translation operator
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1667,6 +1667,22 @@ public:
|
||||||
return !equal (b);
|
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
|
* @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);
|
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
|
* @brief The (dummy) translation operator
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -531,6 +531,30 @@ private:
|
||||||
unsigned int m_mode;
|
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
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -310,27 +310,27 @@ Region::sized (coord_type dx, coord_type dy, unsigned int mode) const
|
||||||
}
|
}
|
||||||
|
|
||||||
Region &
|
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));
|
set_delegate (mp_delegate->sized_inside (inside, d, steps, mode, stop_at));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Region &
|
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));
|
set_delegate (mp_delegate->sized_inside (inside, dx, dy, steps, mode, stop_at));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Region
|
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));
|
return Region (mp_delegate->sized_inside (inside, d, steps, mode, stop_at));
|
||||||
}
|
}
|
||||||
|
|
||||||
Region
|
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));
|
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
|
* can be supplied. With a stop condition, sizing will stop when the sized region touches
|
||||||
* a shape on the "stop_at" region.
|
* 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 d The (isotropic) sizing value
|
||||||
* @param steps The number of steps to take
|
* @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 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"
|
* @param stop_at The stop condition or 0 for "not stopping"
|
||||||
* @return A reference to self
|
* @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
|
* @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
|
* can be supplied. With a stop condition, sizing will stop when the sized region touches
|
||||||
* a shape on the "stop_at" region.
|
* 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 dx The x sizing value
|
||||||
* @param dy The y sizing value
|
* @param dy The y sizing value
|
||||||
* @param steps The number of steps to take
|
* @param steps The number of steps to take
|
||||||
|
|
@ -1064,7 +1064,7 @@ public:
|
||||||
* @param stop_at The stop condition or 0 for "not stopping"
|
* @param stop_at The stop condition or 0 for "not stopping"
|
||||||
* @return A reference to self
|
* @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
|
* @brief Returns the sized region
|
||||||
|
|
@ -1074,7 +1074,7 @@ public:
|
||||||
*
|
*
|
||||||
* Merged semantics applies.
|
* 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
|
* @brief Returns the sized region
|
||||||
|
|
@ -1084,7 +1084,7 @@ public:
|
||||||
*
|
*
|
||||||
* Merged semantics applies.
|
* 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
|
* @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 d, unsigned int mode) const = 0;
|
||||||
virtual RegionDelegate *sized (coord_type dx, coord_type dy, 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 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 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 *and_with (const Region &other, PropertyConstraint prop_constraint) const = 0;
|
||||||
virtual RegionDelegate *not_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::PolygonRef, db::PolygonRef, db::PolygonRef>;
|
||||||
template class DB_PUBLIC two_bool_and_not_local_operation_with_properties<db::Polygon, db::Polygon, db::Polygon>;
|
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)
|
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;
|
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
|
* @brief Implements a merge operation with an overlap count
|
||||||
* With a given wrap_count, the result will only contains shapes where
|
* 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
|
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);
|
return region->sized_inside (inside, dv.x (), dv.y (), steps, mode, stop_at);
|
||||||
}
|
}
|
||||||
|
|
||||||
static db::Region &
|
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);
|
region->sized_inside (inside, dv.x (), dv.y (), steps, mode, stop_at);
|
||||||
return *region;
|
return *region;
|
||||||
|
|
@ -1942,10 +1942,10 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
||||||
"\n"
|
"\n"
|
||||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\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"
|
"@brief Incremental, anisotropic sizing inside of another region\n"
|
||||||
"\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 dx The x sizing value\n"
|
||||||
"@param dy The y sizing value\n"
|
"@param dy The y sizing value\n"
|
||||||
"@param steps The number of steps to take\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"
|
"This is repeated until the full sizing value is applied.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This operaton is employed to implement latch-up rules where a device needs to be close to a well tap within the "
|
"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 "
|
"somewhat less than the minimum well space, so sizing the active region results in a growing footprint that "
|
||||||
"follows the well contours.\n"
|
"follows the well contours.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"A stop region can be specified, meaning that the sizing propagation will stop if the sized region "
|
"A stop region can be specified, meaning that the sizing propagation will stop if the sized shape "
|
||||||
"touches a shape from the stop region. In case of the latch-up rule application this will be the well tap layer.\n"
|
"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"
|
"\n"
|
||||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
@ -1982,7 +1983,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.29.3."
|
"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"
|
"@brief Incremental, isotropic sizing inside of another region\n"
|
||||||
"\n"
|
"\n"
|
||||||
"@return The region after the sizing has applied (self)\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"
|
"\n"
|
||||||
"This method has been introduced in version 0.29.3."
|
"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"
|
"@brief Returns the incrementally and anisotropically sized region\n"
|
||||||
"\n"
|
"\n"
|
||||||
"@return The sized region\n"
|
"@return The sized region\n"
|
||||||
|
|
@ -2013,7 +2014,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
||||||
"\n"
|
"\n"
|
||||||
"This variant has been introduced in version 0.28."
|
"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"
|
"@brief Returns the incrementally sized region\n"
|
||||||
"\n"
|
"\n"
|
||||||
"@return The sized region\n"
|
"@return The sized region\n"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue