mirror of https://github.com/KLayout/klayout.git
WIP: complex DRC operations.
This commit is contained in:
parent
de97e2cde7
commit
8e4fd2f679
|
|
@ -20,6 +20,7 @@ SOURCES = \
|
|||
dbClipboardData.cc \
|
||||
dbClip.cc \
|
||||
dbCommonReader.cc \
|
||||
dbCompoundOperation.cc \
|
||||
dbEdge.cc \
|
||||
dbEdgePair.cc \
|
||||
dbEdgePairRelations.cc \
|
||||
|
|
@ -217,6 +218,7 @@ HEADERS = \
|
|||
dbClipboard.h \
|
||||
dbClip.h \
|
||||
dbCommonReader.h \
|
||||
dbCompoundOperation.h \
|
||||
dbEdge.h \
|
||||
dbEdgePair.h \
|
||||
dbEdgePairRelations.h \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,915 @@
|
|||
|
||||
#include "dbCompoundOperation.h"
|
||||
#include "dbRegion.h"
|
||||
|
||||
/*@@@@
|
||||
|
||||
TODO:
|
||||
|
||||
* Transform variants?
|
||||
* "result is merged"?
|
||||
* "requires raw input"?
|
||||
* Make nodes shared pointers/GSI objects for better compatibility with GSI, at least "keep" them.
|
||||
|
||||
* Edge generation nodes
|
||||
* Boolean and interaction nodes (interact, bool with edge, bool with polygon ...)
|
||||
|
||||
* Interactions with shapes over some distance for neighborhood analysis
|
||||
|
||||
* Sized subject shapes as inputs for other operations? how to compute distance then?
|
||||
|
||||
*/
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
CompoundRegionOperationPrimaryNode::CompoundRegionOperationPrimaryNode ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
std::vector<db::Region *> CompoundRegionOperationPrimaryNode::inputs () const
|
||||
{
|
||||
return std::vector<db::Region *> ();
|
||||
}
|
||||
|
||||
void CompoundRegionOperationPrimaryNode::do_compute_local (db::Layout *, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t, double) const
|
||||
{
|
||||
for (shape_interactions<db::Polygon, db::Polygon>::subject_iterator i = interactions.begin_subjects (); i != interactions.begin_subjects (); ++i) {
|
||||
results.front ().insert (i->second);
|
||||
}
|
||||
}
|
||||
|
||||
void CompoundRegionOperationPrimaryNode::do_compute_local (db::Layout *, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t, double) const
|
||||
{
|
||||
for (shape_interactions<db::PolygonRef, db::PolygonRef>::subject_iterator i = interactions.begin_subjects (); i != interactions.begin_subjects (); ++i) {
|
||||
results.front ().insert (i->second);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
CompoundRegionOperationSecondaryNode::CompoundRegionOperationSecondaryNode (db::Region *input)
|
||||
: mp_input (input)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
std::vector<db::Region *> CompoundRegionOperationSecondaryNode::inputs () const
|
||||
{
|
||||
std::vector<db::Region *> iv;
|
||||
iv.push_back (mp_input);
|
||||
return iv;
|
||||
}
|
||||
|
||||
void CompoundRegionOperationSecondaryNode::do_compute_local (db::Layout *, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t, double) const
|
||||
{
|
||||
for (shape_interactions<db::Polygon, db::Polygon>::intruder_iterator i = interactions.begin_intruders (); i != interactions.end_intruders (); ++i) {
|
||||
results.front ().insert (i->second.second);
|
||||
}
|
||||
}
|
||||
|
||||
void CompoundRegionOperationSecondaryNode::do_compute_local (db::Layout *, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t, double) const
|
||||
{
|
||||
for (shape_interactions<db::PolygonRef, db::PolygonRef>::intruder_iterator i = interactions.begin_intruders (); i != interactions.end_intruders (); ++i) {
|
||||
results.front ().insert (i->second.second);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
CompoundTransformationReducer::CompoundTransformationReducer ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void
|
||||
CompoundTransformationReducer::add (const db::TransformationReducer *reducer)
|
||||
{
|
||||
if (reducer) {
|
||||
m_vars.push_back (reducer);
|
||||
}
|
||||
}
|
||||
|
||||
db::Trans
|
||||
CompoundTransformationReducer::reduce_trans (const db::Trans &trans) const
|
||||
{
|
||||
db::Trans t = trans;
|
||||
for (std::vector<const db::TransformationReducer *>::const_iterator v = m_vars.begin (); v != m_vars.end (); ++v) {
|
||||
(*v)->reduce_trans (t);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
db::ICplxTrans
|
||||
CompoundTransformationReducer::reduce_trans (const db::ICplxTrans &trans) const
|
||||
{
|
||||
db::ICplxTrans t = trans;
|
||||
for (std::vector<const db::TransformationReducer *>::const_iterator v = m_vars.begin (); v != m_vars.end (); ++v) {
|
||||
(*v)->reduce_trans (t);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
db::Trans
|
||||
CompoundTransformationReducer::reduce (const db::Trans &trans) const
|
||||
{
|
||||
db::Trans t = trans;
|
||||
for (std::vector<const db::TransformationReducer *>::const_iterator v = m_vars.begin (); v != m_vars.end (); ++v) {
|
||||
(*v)->reduce (t);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
db::ICplxTrans
|
||||
CompoundTransformationReducer::reduce (const db::ICplxTrans &trans) const
|
||||
{
|
||||
db::ICplxTrans t = trans;
|
||||
for (std::vector<const db::TransformationReducer *>::const_iterator v = m_vars.begin (); v != m_vars.end (); ++v) {
|
||||
(*v)->reduce (t);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
bool
|
||||
CompoundTransformationReducer::is_translation_invariant () const
|
||||
{
|
||||
for (std::vector<const db::TransformationReducer *>::const_iterator v = m_vars.begin (); v != m_vars.end (); ++v) {
|
||||
if (! (*v)->is_translation_invariant ()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
CompoundRegionMultiInputOperationNode::CompoundRegionMultiInputOperationNode (const std::vector<CompoundRegionOperationNode *> &children)
|
||||
{
|
||||
for (std::vector<CompoundRegionOperationNode *>::const_iterator c = children.begin (); c != children.end (); ++c) {
|
||||
m_children.push_back (*c);
|
||||
}
|
||||
init ();
|
||||
}
|
||||
|
||||
CompoundRegionMultiInputOperationNode::CompoundRegionMultiInputOperationNode (CompoundRegionOperationNode *child)
|
||||
{
|
||||
m_children.push_back (child);
|
||||
init ();
|
||||
}
|
||||
|
||||
CompoundRegionMultiInputOperationNode::CompoundRegionMultiInputOperationNode (CompoundRegionOperationNode *a, CompoundRegionOperationNode *b)
|
||||
{
|
||||
m_children.push_back (a);
|
||||
m_children.push_back (b);
|
||||
init ();
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionMultiInputOperationNode::init ()
|
||||
{
|
||||
std::map<db::Region *, unsigned int> input_index;
|
||||
|
||||
for (tl::shared_collection<CompoundRegionOperationNode>::iterator i = m_children.begin (); i != m_children.end (); ++i) {
|
||||
|
||||
std::vector<db::Region *> child_inputs = i->inputs ();
|
||||
unsigned int child_index = 0;
|
||||
for (std::vector<db::Region *>::const_iterator ii = child_inputs.begin (); ii != child_inputs.end (); ++ii, ++child_index) {
|
||||
|
||||
std::map<db::Region *, unsigned int>::const_iterator im = input_index.find (*ii);
|
||||
unsigned int li = (unsigned int) m_inputs.size ();
|
||||
if (im != input_index.end ()) {
|
||||
li = im->second;
|
||||
} else {
|
||||
m_inputs.push_back (*ii);
|
||||
input_index.insert (std::make_pair (*ii, li));
|
||||
}
|
||||
|
||||
m_map_layer_to_child [std::make_pair (child_index, (unsigned int) (ii - child_inputs.begin ()))] = li;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// build the reducer
|
||||
for (tl::shared_collection<CompoundRegionOperationNode>::iterator i = m_children.begin (); i != m_children.end (); ++i) {
|
||||
m_vars.add (i->vars ());
|
||||
}
|
||||
}
|
||||
|
||||
CompoundRegionMultiInputOperationNode::~CompoundRegionMultiInputOperationNode ()
|
||||
{
|
||||
for (tl::shared_collection<CompoundRegionOperationNode>::iterator i = m_children.begin (); i != m_children.end (); ++i) {
|
||||
delete i.operator-> ();
|
||||
}
|
||||
m_children.clear ();
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionMultiInputOperationNode::invalidate_cache () const
|
||||
{
|
||||
for (tl::shared_collection<CompoundRegionOperationNode>::const_iterator i = m_children.begin (); i != m_children.end (); ++i) {
|
||||
i->invalidate_cache ();
|
||||
}
|
||||
}
|
||||
|
||||
db::Coord
|
||||
CompoundRegionMultiInputOperationNode::dist () const
|
||||
{
|
||||
db::Coord d = 0;
|
||||
for (tl::shared_collection<CompoundRegionOperationNode>::const_iterator i = m_children.begin (); i != m_children.end (); ++i) {
|
||||
d = std::max (d, i->dist ());
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
std::string
|
||||
CompoundRegionMultiInputOperationNode::description () const
|
||||
{
|
||||
std::string r = "(";
|
||||
for (tl::shared_collection<CompoundRegionOperationNode>::const_iterator i = m_children.begin (); i != m_children.end (); ++i) {
|
||||
if (i != m_children.begin ()) {
|
||||
r += ",";
|
||||
}
|
||||
r += i->description ();
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
CompoundRegionOperationNode *
|
||||
CompoundRegionMultiInputOperationNode::child (unsigned int index)
|
||||
{
|
||||
tl::shared_collection<CompoundRegionOperationNode>::iterator c = m_children.begin ();
|
||||
while (c != m_children.end () && index > 0) {
|
||||
++c;
|
||||
--index;
|
||||
}
|
||||
return c == m_children.end () ? 0 : c.operator-> ();
|
||||
}
|
||||
|
||||
const CompoundRegionOperationNode *
|
||||
CompoundRegionMultiInputOperationNode::child (unsigned int index) const
|
||||
{
|
||||
return const_cast<CompoundRegionMultiInputOperationNode *> (this)->child (index);
|
||||
}
|
||||
|
||||
const TransformationReducer *
|
||||
CompoundRegionMultiInputOperationNode::vars () const
|
||||
{
|
||||
return (m_vars.is_empty () ? &m_vars : 0);
|
||||
}
|
||||
|
||||
bool
|
||||
CompoundRegionMultiInputOperationNode::wants_variants () const
|
||||
{
|
||||
for (tl::shared_collection<CompoundRegionOperationNode>::const_iterator i = m_children.begin (); i != m_children.end (); ++i) {
|
||||
if (i->wants_variants ()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
CompoundRegionLogicalBoolOperationNode::CompoundRegionLogicalBoolOperationNode (LogicalOp op, bool invert, const std::vector<CompoundRegionOperationNode *> &inputs)
|
||||
: CompoundRegionMultiInputOperationNode (inputs), m_op (op), m_invert (invert)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
std::string CompoundRegionLogicalBoolOperationNode::description () const
|
||||
{
|
||||
std::string r;
|
||||
if (m_invert) {
|
||||
r = "!";
|
||||
}
|
||||
if (m_op == And) {
|
||||
r += "and";
|
||||
} else if (m_op == Or) {
|
||||
r += "or";
|
||||
}
|
||||
return r + CompoundRegionMultiInputOperationNode::description ();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CompoundRegionLogicalBoolOperationNode::implement_compute_local (db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<T> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
bool ok = (m_op == And ? true : false);
|
||||
|
||||
const T &subject_shape = interactions.subject_shape (interactions.begin ()->first);
|
||||
|
||||
for (unsigned int ci = 0; ci < children (); ++ci) {
|
||||
|
||||
shape_interactions<T, T> child_interactions_computed;
|
||||
const shape_interactions<T, T> &child_interactions = interactions_for_child<T, T> (interactions, ci, child_interactions_computed);
|
||||
|
||||
const CompoundRegionOperationNode *node = child (ci);
|
||||
|
||||
bool any = node->compute_local_bool<T> (layout, child_interactions, max_vertex_count, area_ratio);
|
||||
|
||||
if (m_op == And) {
|
||||
if (! any) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
} else if (m_op == Or) {
|
||||
if (any) {
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
tl_assert (! results.empty ());
|
||||
results.front ().insert (subject_shape);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
CompoundRegionGeometricalBoolOperationNode::CompoundRegionGeometricalBoolOperationNode (GeometricalOp op, CompoundRegionOperationNode *a, CompoundRegionOperationNode *b)
|
||||
: CompoundRegionMultiInputOperationNode (a, b), m_op (op)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
std::string
|
||||
CompoundRegionGeometricalBoolOperationNode::description () const
|
||||
{
|
||||
std::string r;
|
||||
if (m_op == And) {
|
||||
r = "and";
|
||||
} else if (m_op == Or) {
|
||||
r = "or";
|
||||
} else if (m_op == Xor) {
|
||||
r = "xor";
|
||||
} else if (m_op == Not) {
|
||||
r = "not";
|
||||
}
|
||||
r += CompoundRegionMultiInputOperationNode::description ();
|
||||
return r;
|
||||
}
|
||||
|
||||
CompoundRegionGeometricalBoolOperationNode::ResultType
|
||||
CompoundRegionGeometricalBoolOperationNode::result_type () const
|
||||
{
|
||||
ResultType res_a = child (0)->result_type ();
|
||||
ResultType res_b = child (1)->result_type ();
|
||||
|
||||
if (res_a == Region && res_b == Edges && m_op == And) {
|
||||
return Edges;
|
||||
} else {
|
||||
return res_a;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T1, class T2, class TR>
|
||||
static
|
||||
void run_bool (CompoundRegionGeometricalBoolOperationNode::GeometricalOp, db::Layout *, const std::unordered_set<T1> &, const std::unordered_set<T2> &, const std::unordered_set<TR> &)
|
||||
{
|
||||
tl_assert (false);
|
||||
}
|
||||
|
||||
static void
|
||||
init_region (db::Region &r, const std::unordered_set<db::PolygonRef> &p)
|
||||
{
|
||||
for (std::unordered_set<db::PolygonRef>::const_iterator i = p.begin (); i != p.end (); ++i) {
|
||||
r.insert (i->obj ().transformed (i->trans ()));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
init_region (db::Region &r, const std::unordered_set<db::Polygon> &p)
|
||||
{
|
||||
for (std::unordered_set<db::Polygon>::const_iterator i = p.begin (); i != p.end (); ++i) {
|
||||
r.insert (*i);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
init_edges (db::Edges &ee, const std::unordered_set<db::Edge> &e)
|
||||
{
|
||||
for (std::unordered_set<db::Edge>::const_iterator i = e.begin (); i != e.end (); ++i) {
|
||||
ee.insert (*i);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
write_result (db::Layout *layout, std::unordered_set<db::PolygonRef> &results, const db::Region &r)
|
||||
{
|
||||
for (db::Region::const_iterator p = r.begin (); ! p.at_end (); ++p) {
|
||||
results.insert (db::PolygonRef (*p, layout->shape_repository ()));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
write_result (db::Layout *, std::unordered_set<db::Polygon> &results, const db::Region &r)
|
||||
{
|
||||
for (db::Region::const_iterator p = r.begin (); ! p.at_end (); ++p) {
|
||||
results.insert (*p);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
write_result (db::Layout *, std::unordered_set<db::Edge> &results, const db::Edges &e)
|
||||
{
|
||||
for (db::Edges::const_iterator i = e.begin (); ! i.at_end (); ++i) {
|
||||
results.insert (*i);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void
|
||||
run_poly_bool (CompoundRegionGeometricalBoolOperationNode::GeometricalOp op, db::Layout *layout, const std::unordered_set<T> &a, const std::unordered_set<T> &b, std::unordered_set<T> &res)
|
||||
{
|
||||
// TODO: it's more efficient to feed the EP directly for polygon-to-polygon bools
|
||||
db::Region ra, rb;
|
||||
init_region (ra, a);
|
||||
init_region (rb, b);
|
||||
|
||||
if (op == CompoundRegionGeometricalBoolOperationNode::And) {
|
||||
write_result (layout, res, ra & rb);
|
||||
} else if (op == CompoundRegionGeometricalBoolOperationNode::Or) {
|
||||
write_result (layout, res, ra + rb);
|
||||
} else if (op == CompoundRegionGeometricalBoolOperationNode::Xor) {
|
||||
write_result (layout, res, ra ^ rb);
|
||||
} else if (op == CompoundRegionGeometricalBoolOperationNode::Not) {
|
||||
write_result (layout, res, ra - rb);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
run_bool (CompoundRegionGeometricalBoolOperationNode::GeometricalOp op, db::Layout *layout, const std::unordered_set<db::PolygonRef> &a, const std::unordered_set<db::PolygonRef> &b, std::unordered_set<db::PolygonRef> &res)
|
||||
{
|
||||
run_poly_bool (op, layout, a, b, res);
|
||||
}
|
||||
|
||||
static void
|
||||
run_bool (CompoundRegionGeometricalBoolOperationNode::GeometricalOp op, db::Layout *layout, const std::unordered_set<db::Polygon> &a, const std::unordered_set<db::Polygon> &b, std::unordered_set<db::Polygon> &res)
|
||||
{
|
||||
run_poly_bool (op, layout, a, b, res);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void
|
||||
run_poly_vs_edge_bool (CompoundRegionGeometricalBoolOperationNode::GeometricalOp op, db::Layout *layout, const std::unordered_set<T> &a, const std::unordered_set<db::Edge> &b, std::unordered_set<db::Edge> &res)
|
||||
{
|
||||
if (op != CompoundRegionGeometricalBoolOperationNode::And) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: it's more efficient to feed the EP directly for polygon-to-polygon bools
|
||||
db::Region ra;
|
||||
init_region (ra, a);
|
||||
|
||||
db::Edges eb;
|
||||
init_edges (eb, b);
|
||||
|
||||
write_result (layout, res, eb & ra);
|
||||
}
|
||||
|
||||
static void
|
||||
run_bool (CompoundRegionGeometricalBoolOperationNode::GeometricalOp op, db::Layout *layout, const std::unordered_set<db::Polygon> &a, const std::unordered_set<db::Edge> &b, std::unordered_set<db::Edge> &res)
|
||||
{
|
||||
run_poly_vs_edge_bool (op, layout, a, b, res);
|
||||
}
|
||||
|
||||
static void
|
||||
run_bool (CompoundRegionGeometricalBoolOperationNode::GeometricalOp op, db::Layout *layout, const std::unordered_set<db::PolygonRef> &a, const std::unordered_set<db::Edge> &b, std::unordered_set<db::Edge> &res)
|
||||
{
|
||||
run_poly_vs_edge_bool (op, layout, a, b, res);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void
|
||||
run_edge_vs_poly_bool (CompoundRegionGeometricalBoolOperationNode::GeometricalOp op, db::Layout *layout, const std::unordered_set<db::Edge> &a, const std::unordered_set<T> &b, std::unordered_set<db::Edge> &res)
|
||||
{
|
||||
if (op != CompoundRegionGeometricalBoolOperationNode::And) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: it's more efficient to feed the EP directly for polygon-to-polygon bools
|
||||
db::Region rb;
|
||||
init_region (rb, b);
|
||||
|
||||
db::Edges ea;
|
||||
init_edges (ea, a);
|
||||
|
||||
if (op != CompoundRegionGeometricalBoolOperationNode::And) {
|
||||
write_result (layout, res, ea & rb);
|
||||
} else if (op != CompoundRegionGeometricalBoolOperationNode::Not) {
|
||||
write_result (layout, res, ea - rb);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
run_bool (CompoundRegionGeometricalBoolOperationNode::GeometricalOp op, db::Layout *layout, const std::unordered_set<db::Edge> &a, const std::unordered_set<db::PolygonRef> &b, std::unordered_set<db::Edge> &res)
|
||||
{
|
||||
run_edge_vs_poly_bool (op, layout, a, b, res);
|
||||
}
|
||||
|
||||
static void
|
||||
run_bool (CompoundRegionGeometricalBoolOperationNode::GeometricalOp op, db::Layout *layout, const std::unordered_set<db::Edge> &a, const std::unordered_set<db::Polygon> &b, std::unordered_set<db::Edge> &res)
|
||||
{
|
||||
run_edge_vs_poly_bool (op, layout, a, b, res);
|
||||
}
|
||||
|
||||
static void
|
||||
run_bool (CompoundRegionGeometricalBoolOperationNode::GeometricalOp op, db::Layout *layout, const std::unordered_set<db::Edge> &a, const std::unordered_set<db::Edge> &b, std::unordered_set<db::Edge> &res)
|
||||
{
|
||||
db::Edges ea, eb;
|
||||
init_edges (ea, a);
|
||||
init_edges (eb, b);
|
||||
|
||||
if (op == CompoundRegionGeometricalBoolOperationNode::And) {
|
||||
write_result (layout, res, ea & eb);
|
||||
} else if (op == CompoundRegionGeometricalBoolOperationNode::Or) {
|
||||
write_result (layout, res, ea + eb);
|
||||
} else if (op == CompoundRegionGeometricalBoolOperationNode::Xor) {
|
||||
write_result (layout, res, ea ^ eb);
|
||||
} else if (op == CompoundRegionGeometricalBoolOperationNode::Not) {
|
||||
write_result (layout, res, ea - eb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T, class T1, class T2, class TR>
|
||||
void
|
||||
CompoundRegionGeometricalBoolOperationNode::implement_bool (db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
std::vector<std::unordered_set<T1> > one_a;
|
||||
one_a.push_back (std::unordered_set<T1> ());
|
||||
|
||||
shape_interactions<T, T> computed_a;
|
||||
child (0)->compute_local (layout, interactions_for_child (interactions, 0, computed_a), one_a, max_vertex_count, area_ratio);
|
||||
|
||||
std::vector<std::unordered_set<T2> > one_b;
|
||||
one_b.push_back (std::unordered_set<T2> ());
|
||||
|
||||
shape_interactions<T, T> computed_b;
|
||||
child (1)->compute_local (layout, interactions_for_child (interactions, 1, computed_b), one_b, max_vertex_count, area_ratio);
|
||||
|
||||
run_bool (m_op, layout, one_a.front (), one_b.front (), results.front ());
|
||||
}
|
||||
|
||||
template <class T, class TR>
|
||||
void
|
||||
CompoundRegionGeometricalBoolOperationNode::implement_compute_local (db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
ResultType res_a = child (0)->result_type ();
|
||||
ResultType res_b = child (1)->result_type ();
|
||||
|
||||
if (res_a == Region && res_b == Region) {
|
||||
implement_bool<T, T, T, TR> (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
} else if (res_a == Region && res_b == Edges) {
|
||||
implement_bool<T, T, db::Edge, TR> (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
} else if (res_a == Edges && res_b == Region) {
|
||||
implement_bool<T, db::Edge, T, TR> (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
} else if (res_a == Edges && res_b == Edges) {
|
||||
implement_bool<T, db::Edge, db::Edge, TR> (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionGeometricalBoolOperationNode::do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionGeometricalBoolOperationNode::do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionGeometricalBoolOperationNode::do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionGeometricalBoolOperationNode::do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0 // @@@
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
class DB_PUBLIC CompoundRegionInteractOperationNode
|
||||
: public CompoundRegionMultiInputOperationNode
|
||||
{
|
||||
public:
|
||||
enum GeometricalOp { And, Not, Or, Xor };
|
||||
|
||||
CompoundRegionInteractOperationNode (GeometricalOp op, const CompoundRegionOperationNode *a, const CompoundRegionOperationNode *b, size_t min_count = 0, size_t max_count = std::numeric_limits<size_t>::max ());
|
||||
|
||||
virtual std::string description () const;
|
||||
|
||||
// specifies the result type
|
||||
virtual ResultType result_type () const;
|
||||
|
||||
// the different computation slots
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
|
||||
private:
|
||||
GeometricalOp m_op;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
class DB_PUBLIC CompoundRegionPullOperationNode
|
||||
: public CompoundRegionMultiInputOperationNode
|
||||
{
|
||||
public:
|
||||
enum GeometricalOp { And, Not, Or, Xor };
|
||||
|
||||
CompoundRegionPullOperationNode (GeometricalOp op, const CompoundRegionOperationNode *a, const CompoundRegionOperationNode *b);
|
||||
|
||||
virtual std::string description () const;
|
||||
|
||||
// specifies the result type
|
||||
virtual ResultType result_type () const;
|
||||
|
||||
// the different computation slots
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
|
||||
private:
|
||||
GeometricalOp m_op;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
class DB_PUBLIC CompoundRegionSizeOperationNode
|
||||
: public CompoundRegionMultiInputOperationNode
|
||||
{
|
||||
public:
|
||||
enum GeometricalOp { And, Not, Or, Xor };
|
||||
|
||||
CompoundRegionSizeOperationNode (GeometricalOp op, const CompoundRegionOperationNode *input, db::Coord size_x, db::Coord size_y);
|
||||
|
||||
virtual std::string description () const;
|
||||
|
||||
// specifies the result type
|
||||
virtual ResultType result_type () const;
|
||||
|
||||
virtual db::Coord dist () const;
|
||||
virtual const TransformationReducer *vars () const;
|
||||
|
||||
// the different computation slots
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
|
||||
private:
|
||||
GeometricalOp m_op;
|
||||
CompoundTransformationReducer m_vars;
|
||||
};
|
||||
|
||||
class DB_PUBLIC CompoundRegionMergeOperationNode
|
||||
: public CompoundRegionMultiInputOperationNode
|
||||
{
|
||||
public:
|
||||
CompoundRegionMergeOperationNode (const CompoundRegionOperationNode *input, size_t min_wrap_count = 1);
|
||||
|
||||
virtual std::string description () const;
|
||||
|
||||
// specifies the result type
|
||||
virtual ResultType result_type () const;
|
||||
|
||||
// the different computation slots
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
};
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
CompoundRegionLogicalCaseSelectOperationNode::CompoundRegionLogicalCaseSelectOperationNode (bool multi_layer, const std::vector<CompoundRegionOperationNode *> &inputs)
|
||||
: CompoundRegionMultiInputOperationNode (inputs), m_multi_layer (multi_layer)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
std::string CompoundRegionLogicalCaseSelectOperationNode::description () const
|
||||
{
|
||||
// TODO: could be nicer ...
|
||||
std::string r;
|
||||
r = "if-then";
|
||||
return r + CompoundRegionMultiInputOperationNode::description ();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local (db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<T> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
for (unsigned int ci = 0; ci < children (); ++ci) {
|
||||
|
||||
if (! ok && ci % 2 == 1) {
|
||||
// skip false branches
|
||||
continue;
|
||||
}
|
||||
|
||||
shape_interactions<T, T> computed;
|
||||
const shape_interactions<T, T> &child_interactions = interactions_for_child<T, T> (interactions, ci, computed);
|
||||
|
||||
const CompoundRegionOperationNode *node = child (ci);
|
||||
|
||||
if (ci % 2 == 0) {
|
||||
|
||||
ok = node->compute_local_bool<T> (layout, child_interactions, max_vertex_count, area_ratio);
|
||||
|
||||
} else {
|
||||
|
||||
if (m_multi_layer && results.size () > size_t (ci / 2)) {
|
||||
|
||||
std::vector<std::unordered_set<T> > one;
|
||||
one.push_back (std::unordered_set<T> ());
|
||||
node->compute_local (layout, child_interactions, one, max_vertex_count, area_ratio);
|
||||
results[ci / 2].swap (one.front ());
|
||||
|
||||
} else {
|
||||
|
||||
node->compute_local (layout, child_interactions, results, max_vertex_count, area_ratio);
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
CompoundRegionFilterOperationNode::CompoundRegionFilterOperationNode (PolygonFilterBase *filter, CompoundRegionOperationNode *input)
|
||||
: CompoundRegionMultiInputOperationNode (input), mp_filter (filter)
|
||||
{ }
|
||||
|
||||
std::string
|
||||
CompoundRegionFilterOperationNode::description () const
|
||||
{
|
||||
// TODO: some description?
|
||||
return "filter";
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionFilterOperationNode::do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionFilterOperationNode::do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
bool
|
||||
CompoundRegionFilterOperationNode::is_selected (const db::Polygon &p) const
|
||||
{
|
||||
return mp_filter->selected (p);
|
||||
}
|
||||
|
||||
bool
|
||||
CompoundRegionFilterOperationNode::is_selected (const db::PolygonRef &p) const
|
||||
{
|
||||
return mp_filter->selected (p.obj ().transformed (p.trans ()));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
CompoundRegionProcessingOperationNode::CompoundRegionProcessingOperationNode (PolygonProcessorBase *proc, CompoundRegionOperationNode *input)
|
||||
: CompoundRegionMultiInputOperationNode (input), mp_proc (proc)
|
||||
{ }
|
||||
|
||||
std::string
|
||||
CompoundRegionProcessingOperationNode::description () const
|
||||
{
|
||||
// TODO: some description?
|
||||
return "processor";
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionProcessingOperationNode::do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionProcessingOperationNode::do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionProcessingOperationNode::processed (db::Layout *, const db::Polygon &p, std::vector<db::Polygon> &res) const
|
||||
{
|
||||
return mp_proc->process (p, res);
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionProcessingOperationNode::processed (db::Layout *layout, const db::PolygonRef &p, std::vector<db::PolygonRef> &res) const
|
||||
{
|
||||
std::vector<db::Polygon> poly;
|
||||
mp_proc->process (p.obj ().transformed (p.trans ()), poly);
|
||||
for (std::vector<db::Polygon>::const_iterator p = poly.begin (); p != poly.end (); ++p) {
|
||||
res.push_back (db::PolygonRef (*p, layout->shape_repository ()));
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
CompoundRegionToEdgeProcessingOperationNode::CompoundRegionToEdgeProcessingOperationNode (PolygonToEdgeProcessorBase *proc, CompoundRegionOperationNode *input)
|
||||
: CompoundRegionMultiInputOperationNode (input), mp_proc (proc)
|
||||
{ }
|
||||
|
||||
std::string
|
||||
CompoundRegionToEdgeProcessingOperationNode::description () const
|
||||
{
|
||||
// TODO: some description?
|
||||
return "processor";
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionToEdgeProcessingOperationNode::do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionToEdgeProcessingOperationNode::do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionToEdgeProcessingOperationNode::processed (db::Layout *, const db::Polygon &p, std::vector<db::Edge> &res) const
|
||||
{
|
||||
return mp_proc->process (p, res);
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionToEdgeProcessingOperationNode::processed (db::Layout *, const db::PolygonRef &p, std::vector<db::Edge> &res) const
|
||||
{
|
||||
mp_proc->process (p.obj ().transformed (p.trans ()), res);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
CompoundRegionToEdgePairProcessingOperationNode::CompoundRegionToEdgePairProcessingOperationNode (PolygonToEdgePairProcessorBase *proc, CompoundRegionOperationNode *input)
|
||||
: CompoundRegionMultiInputOperationNode (input), mp_proc (proc)
|
||||
{ }
|
||||
|
||||
std::string
|
||||
CompoundRegionToEdgePairProcessingOperationNode::description () const
|
||||
{
|
||||
// TODO: some description?
|
||||
return "processor";
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionToEdgePairProcessingOperationNode::do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionToEdgePairProcessingOperationNode::do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionToEdgePairProcessingOperationNode::processed (db::Layout *, const db::Polygon &p, std::vector<db::EdgePair> &res) const
|
||||
{
|
||||
return mp_proc->process (p, res);
|
||||
}
|
||||
|
||||
void
|
||||
CompoundRegionToEdgePairProcessingOperationNode::processed (db::Layout *, const db::PolygonRef &p, std::vector<db::EdgePair> &res) const
|
||||
{
|
||||
mp_proc->process (p.obj ().transformed (p.trans ()), res);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,776 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef HDR_dbCompoundOperation
|
||||
#define HDR_dbCompoundOperation
|
||||
|
||||
#include "dbLocalOperation.h"
|
||||
#include "dbHierProcessor.h"
|
||||
#include "dbRegionDelegate.h"
|
||||
#include "dbRegion.h"
|
||||
#include "dbEdges.h"
|
||||
#include "dbEdgePairs.h"
|
||||
|
||||
#include "gsiObject.h"
|
||||
#include "tlObject.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
class DB_PUBLIC CompoundRegionOperationNode
|
||||
: public gsi::ObjectBase, public tl::Object
|
||||
{
|
||||
public:
|
||||
enum ResultType { Region, Edges, EdgePairs };
|
||||
|
||||
CompoundRegionOperationNode ()
|
||||
{
|
||||
invalidate_cache ();
|
||||
}
|
||||
|
||||
virtual ~CompoundRegionOperationNode () { }
|
||||
|
||||
virtual db::Coord dist () const = 0;
|
||||
virtual std::string description () const = 0;
|
||||
virtual std::vector<db::Region *> inputs () const = 0;
|
||||
|
||||
// specifies the result type
|
||||
virtual ResultType result_type () const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns the transformation reducer for building cell variants
|
||||
* This method may return 0. In this case, not cell variants are built.
|
||||
*/
|
||||
virtual const TransformationReducer *vars () const { return 0; }
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the processor wants to build variants
|
||||
* If not true, the processor accepts shape propagation as variant resolution.
|
||||
*/
|
||||
virtual bool wants_variants () const { return false; }
|
||||
|
||||
virtual void compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
do_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
virtual void compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
do_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
virtual void compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
do_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
do_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
do_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
do_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool compute_local_bool (db::Layout *layout, const shape_interactions<T, T> &interactions, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
if (result_type () == Region) {
|
||||
|
||||
std::vector<std::unordered_set<T> > res;
|
||||
compute_local (layout, interactions, res, max_vertex_count, area_ratio);
|
||||
return ! res.empty ();
|
||||
|
||||
} else if (result_type () == Edges) {
|
||||
|
||||
std::vector<std::unordered_set<db::Edge> > res;
|
||||
compute_local (layout, interactions, res, max_vertex_count, area_ratio);
|
||||
return ! res.empty ();
|
||||
|
||||
} else if (result_type () == EdgePairs) {
|
||||
|
||||
std::vector<std::unordered_set<db::EdgePair> > res;
|
||||
compute_local (layout, interactions, res, max_vertex_count, area_ratio);
|
||||
return ! res.empty ();
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void invalidate_cache () const
|
||||
{
|
||||
m_cache_polyref.clear ();
|
||||
m_cache_polyref_valid = false;
|
||||
m_cache_poly.clear ();
|
||||
m_cache_poly_valid = false;
|
||||
m_cache_edge.clear ();
|
||||
m_cache_edge_valid = false;
|
||||
m_cache_edge_pair.clear ();
|
||||
m_cache_edge_pair_valid = false;
|
||||
}
|
||||
|
||||
protected:
|
||||
// the different computation slots
|
||||
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Polygon, db::Polygon> & /*interactions*/, std::vector<std::unordered_set<db::Polygon> > & /*results*/, size_t /*max_vertex_count*/, double /*area_ratio*/) const { }
|
||||
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Polygon, db::Polygon> & /*interactions*/, std::vector<std::unordered_set<db::Edge> > & /*results*/, size_t /*max_vertex_count*/, double /*area_ratio*/) const { }
|
||||
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Polygon, db::Polygon> & /*interactions*/, std::vector<std::unordered_set<db::EdgePair> > & /*results*/, size_t /*max_vertex_count*/, double /*area_ratio*/) const { }
|
||||
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::PolygonRef, db::PolygonRef> & /*interactions*/, std::vector<std::unordered_set<db::PolygonRef> > & /*results*/, size_t /*max_vertex_count*/, double /*area_ratio*/) const { }
|
||||
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::PolygonRef, db::PolygonRef> & /*interactions*/, std::vector<std::unordered_set<db::Edge> > & /*results*/, size_t /*max_vertex_count*/, double /*area_ratio*/) const { }
|
||||
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::PolygonRef, db::PolygonRef> & /*interactions*/, std::vector<std::unordered_set<db::EdgePair> > & /*results*/, size_t /*max_vertex_count*/, double /*area_ratio*/) const { }
|
||||
|
||||
private:
|
||||
mutable std::vector<std::unordered_set<db::PolygonRef> > m_cache_polyref;
|
||||
mutable bool m_cache_polyref_valid;
|
||||
mutable std::vector<std::unordered_set<db::Polygon> > m_cache_poly;
|
||||
mutable bool m_cache_poly_valid;
|
||||
mutable std::vector<std::unordered_set<db::Edge> > m_cache_edge;
|
||||
mutable bool m_cache_edge_valid;
|
||||
mutable std::vector<std::unordered_set<db::EdgePair> > m_cache_edge_pair;
|
||||
mutable bool m_cache_edge_pair_valid;
|
||||
|
||||
void get_cache (std::vector<std::unordered_set<db::PolygonRef> > *&cache_ptr, bool *&valid) const { cache_ptr = &m_cache_polyref; valid = &m_cache_polyref_valid; }
|
||||
void get_cache (std::vector<std::unordered_set<db::Polygon> > *&cache_ptr, bool *&valid) const { cache_ptr = &m_cache_poly; valid = &m_cache_poly_valid; }
|
||||
void get_cache (std::vector<std::unordered_set<db::Edge> > *&cache_ptr, bool *&valid) const { cache_ptr = &m_cache_edge; valid = &m_cache_edge_valid; }
|
||||
void get_cache (std::vector<std::unordered_set<db::EdgePair> > *&cache_ptr, bool *&valid) const { cache_ptr = &m_cache_edge_pair; valid = &m_cache_edge_pair_valid; }
|
||||
|
||||
template <class T, class TR>
|
||||
void implement_compute_local (db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
std::vector<std::unordered_set<db::PolygonRef> > *cache = 0;
|
||||
bool *valid = 0;
|
||||
get_cache (cache, valid);
|
||||
if (*valid) {
|
||||
results = *cache;
|
||||
} else {
|
||||
do_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
*cache = results;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct compound_operation_type_traits;
|
||||
|
||||
template <>
|
||||
struct compound_operation_type_traits<db::PolygonRef>
|
||||
{
|
||||
typedef db::Region container_type;
|
||||
static CompoundRegionOperationNode::ResultType type () { return CompoundRegionOperationNode::Region; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct compound_operation_type_traits<db::Polygon>
|
||||
{
|
||||
typedef db::Region container_type;
|
||||
static CompoundRegionOperationNode::ResultType type () { return CompoundRegionOperationNode::Region; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct compound_operation_type_traits<db::Edge>
|
||||
{
|
||||
typedef db::Edges container_type;
|
||||
static CompoundRegionOperationNode::ResultType type () { return CompoundRegionOperationNode::Edges; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct compound_operation_type_traits<db::EdgePair>
|
||||
{
|
||||
typedef db::EdgePairs container_type;
|
||||
static CompoundRegionOperationNode::ResultType type () { return CompoundRegionOperationNode::EdgePairs; }
|
||||
};
|
||||
|
||||
|
||||
class DB_PUBLIC CompoundRegionOperationPrimaryNode
|
||||
: public CompoundRegionOperationNode
|
||||
{
|
||||
public:
|
||||
CompoundRegionOperationPrimaryNode ();
|
||||
|
||||
virtual std::string description () const;
|
||||
|
||||
virtual std::vector<db::Region *> inputs () const;
|
||||
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
};
|
||||
|
||||
|
||||
class DB_PUBLIC CompoundRegionOperationSecondaryNode
|
||||
: public CompoundRegionOperationNode
|
||||
{
|
||||
public:
|
||||
CompoundRegionOperationSecondaryNode (db::Region *input);
|
||||
|
||||
virtual std::string description () const;
|
||||
|
||||
virtual std::vector<db::Region *> inputs () const;
|
||||
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
|
||||
private:
|
||||
db::Region *mp_input;
|
||||
};
|
||||
|
||||
|
||||
class DB_PUBLIC CompoundTransformationReducer
|
||||
: public db::TransformationReducer
|
||||
{
|
||||
public:
|
||||
CompoundTransformationReducer ();
|
||||
|
||||
void add (const db::TransformationReducer *reducer);
|
||||
bool is_empty () const { return m_vars.empty (); }
|
||||
|
||||
virtual db::Trans reduce_trans (const db::Trans &trans) const;
|
||||
virtual db::ICplxTrans reduce_trans (const db::ICplxTrans &trans) const;
|
||||
virtual db::Trans reduce (const db::Trans &trans) const;
|
||||
virtual db::ICplxTrans reduce (const db::ICplxTrans &trans) const;
|
||||
virtual bool is_translation_invariant () const;
|
||||
|
||||
private:
|
||||
std::vector<const db::TransformationReducer *> m_vars;
|
||||
};
|
||||
|
||||
class DB_PUBLIC CompoundRegionMultiInputOperationNode
|
||||
: public CompoundRegionOperationNode
|
||||
{
|
||||
public:
|
||||
CompoundRegionMultiInputOperationNode (const std::vector<CompoundRegionOperationNode *> &children);
|
||||
CompoundRegionMultiInputOperationNode (CompoundRegionOperationNode *child);
|
||||
CompoundRegionMultiInputOperationNode (CompoundRegionOperationNode *a, CompoundRegionOperationNode *b);
|
||||
~CompoundRegionMultiInputOperationNode ();
|
||||
|
||||
virtual db::Coord dist () const;
|
||||
virtual std::string description () const;
|
||||
|
||||
virtual std::vector<db::Region *> inputs () const
|
||||
{
|
||||
return m_inputs;
|
||||
}
|
||||
|
||||
virtual const TransformationReducer *vars () const;
|
||||
virtual bool wants_variants () const;
|
||||
|
||||
virtual void invalidate_cache () const;
|
||||
|
||||
protected:
|
||||
bool needs_reduce_interactions (unsigned int child_index) const
|
||||
{
|
||||
if (m_children.size () < 2 || child (child_index)->inputs ().empty ()) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
template <class TS, class TI>
|
||||
const shape_interactions<TS, TI> &interactions_for_child (const shape_interactions<TS, TI> &interactions, unsigned int child_index, shape_interactions<TS, TI> &child_interactions) const
|
||||
{
|
||||
if (! needs_reduce_interactions (child_index)) {
|
||||
return interactions;
|
||||
}
|
||||
|
||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
|
||||
child_interactions.add_subject_shape (i->first, interactions.subject_shape (i->first));
|
||||
|
||||
for (typename shape_interactions<TS, TI>::iterator2 ii = i->second.begin (); ii != i->second.end (); ++ii) {
|
||||
|
||||
const std::pair<unsigned int, TI> &is = interactions.intruder_shape (*ii);
|
||||
|
||||
std::map<std::pair<unsigned int, unsigned int>, unsigned int>::const_iterator lm = m_map_layer_to_child.find (std::make_pair (child_index, is.first));
|
||||
if (lm != m_map_layer_to_child.end ()) {
|
||||
child_interactions.add_intruder_shape (*ii, lm->second, is.second);
|
||||
child_interactions.add_interaction (i->first, *ii);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return child_interactions;
|
||||
}
|
||||
|
||||
unsigned int children () const
|
||||
{
|
||||
return m_children.size ();
|
||||
}
|
||||
|
||||
CompoundRegionOperationNode *child (unsigned int index);
|
||||
const CompoundRegionOperationNode *child (unsigned int index) const;
|
||||
|
||||
private:
|
||||
tl::shared_collection<CompoundRegionOperationNode> m_children;
|
||||
// maps child#,layer# to layer# of child:
|
||||
std::map<std::pair<unsigned int, unsigned int>, unsigned int> m_map_layer_to_child;
|
||||
std::vector<db::Region *> m_inputs;
|
||||
CompoundTransformationReducer m_vars;
|
||||
|
||||
void init ();
|
||||
};
|
||||
|
||||
|
||||
class DB_PUBLIC CompoundRegionLogicalBoolOperationNode
|
||||
: public CompoundRegionMultiInputOperationNode
|
||||
{
|
||||
public:
|
||||
enum LogicalOp { And, Or };
|
||||
|
||||
CompoundRegionLogicalBoolOperationNode (LogicalOp op, bool invert, const std::vector<CompoundRegionOperationNode *> &inputs);
|
||||
|
||||
virtual std::string description () const;
|
||||
|
||||
// specifies the result type
|
||||
virtual ResultType result_type () const { return Region; }
|
||||
|
||||
// the different computation slots
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
private:
|
||||
LogicalOp m_op;
|
||||
bool m_invert;
|
||||
|
||||
template <class T>
|
||||
void implement_compute_local (db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<T> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
};
|
||||
|
||||
|
||||
class DB_PUBLIC CompoundRegionGeometricalBoolOperationNode
|
||||
: public CompoundRegionMultiInputOperationNode
|
||||
{
|
||||
public:
|
||||
enum GeometricalOp { And, Not, Or, Xor };
|
||||
|
||||
CompoundRegionGeometricalBoolOperationNode (GeometricalOp op, CompoundRegionOperationNode *a, CompoundRegionOperationNode *b);
|
||||
|
||||
virtual std::string description () const;
|
||||
|
||||
// specifies the result type
|
||||
virtual ResultType result_type () const;
|
||||
|
||||
// the different computation slots
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
|
||||
private:
|
||||
GeometricalOp m_op;
|
||||
|
||||
template <class T, class TR>
|
||||
void implement_compute_local (db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
template <class T, class T1, class T2, class TR>
|
||||
void implement_bool (db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
};
|
||||
|
||||
|
||||
class DB_PUBLIC CompoundRegionInteractOperationNode
|
||||
: public CompoundRegionMultiInputOperationNode
|
||||
{
|
||||
public:
|
||||
enum GeometricalOp { And, Not, Or, Xor };
|
||||
|
||||
CompoundRegionInteractOperationNode (GeometricalOp op, const CompoundRegionOperationNode *a, const CompoundRegionOperationNode *b, size_t min_count = 0, size_t max_count = std::numeric_limits<size_t>::max ());
|
||||
|
||||
virtual std::string description () const;
|
||||
|
||||
// specifies the result type
|
||||
virtual ResultType result_type () const;
|
||||
|
||||
// the different computation slots
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
|
||||
private:
|
||||
GeometricalOp m_op;
|
||||
};
|
||||
|
||||
|
||||
class DB_PUBLIC CompoundRegionPullOperationNode
|
||||
: public CompoundRegionMultiInputOperationNode
|
||||
{
|
||||
public:
|
||||
enum GeometricalOp { And, Not, Or, Xor };
|
||||
|
||||
CompoundRegionPullOperationNode (GeometricalOp op, const CompoundRegionOperationNode *a, const CompoundRegionOperationNode *b);
|
||||
|
||||
virtual std::string description () const;
|
||||
|
||||
// specifies the result type
|
||||
virtual ResultType result_type () const;
|
||||
|
||||
// the different computation slots
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
|
||||
private:
|
||||
GeometricalOp m_op;
|
||||
};
|
||||
|
||||
|
||||
class DB_PUBLIC CompoundRegionSizeOperationNode
|
||||
: public CompoundRegionMultiInputOperationNode
|
||||
{
|
||||
public:
|
||||
enum GeometricalOp { And, Not, Or, Xor };
|
||||
|
||||
CompoundRegionSizeOperationNode (GeometricalOp op, const CompoundRegionOperationNode *input, db::Coord size_x, db::Coord size_y);
|
||||
|
||||
virtual std::string description () const;
|
||||
|
||||
// specifies the result type
|
||||
virtual ResultType result_type () const;
|
||||
|
||||
virtual db::Coord dist () const;
|
||||
virtual const TransformationReducer *vars () const;
|
||||
|
||||
// the different computation slots
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
|
||||
private:
|
||||
GeometricalOp m_op;
|
||||
CompoundTransformationReducer m_vars;
|
||||
};
|
||||
|
||||
|
||||
class DB_PUBLIC CompoundRegionMergeOperationNode
|
||||
: public CompoundRegionMultiInputOperationNode
|
||||
{
|
||||
public:
|
||||
CompoundRegionMergeOperationNode (const CompoundRegionOperationNode *input, size_t min_wrap_count = 1);
|
||||
|
||||
virtual std::string description () const;
|
||||
|
||||
// specifies the result type
|
||||
virtual ResultType result_type () const;
|
||||
|
||||
// the different computation slots
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
};
|
||||
|
||||
|
||||
... either all or no input ...
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
class DB_PUBLIC compound_region_generic_operation_node
|
||||
: public CompoundRegionMultiInputOperationNode
|
||||
{
|
||||
public:
|
||||
compound_region_generic_operation_node (const db::local_operation<TS, TI, TR> &op, const std::vector<CompoundRegionOperationNode *> &inputs, const db::TransformationReducer *vars = 0, bool want_variants = false, const std::string &description = "generic")
|
||||
: CompoundRegionMultiInputOperationNode (inputs), m_op (op), m_description (description), mp_vars (vars), m_wants_variants (want_variants)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual std::string description () const { return m_description; }
|
||||
virtual ResultType result_type () const { return compound_operation_type_traits<TR>::type (); }
|
||||
virtual const db::TransformationReducer *vars () const { return mp_vars; }
|
||||
virtual bool wants_variants () const { return m_wants_variants; }
|
||||
|
||||
// the different computation slots
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
|
||||
|
||||
|
||||
private:
|
||||
db::local_operation<TS, TI, TR> m_op;
|
||||
std::string m_description;
|
||||
const db::TransformationReducer *mp_vars;
|
||||
bool m_wants_variants;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Implements the case selection
|
||||
*
|
||||
* Case selection is a sequence of if/then nodes:
|
||||
* (if1 then1 if2 then2 ... default) or (if1 then1 if2 then2 ...)
|
||||
* The first condition is tested. If true, the "then1" result is taken. Otherwise, the
|
||||
* "if2" condition is tested and "then2" is taken if true etc. At the end the
|
||||
* default is evaluated if no other condition matched.
|
||||
*/
|
||||
|
||||
class DB_PUBLIC CompoundRegionLogicalCaseSelectOperationNode
|
||||
: public CompoundRegionMultiInputOperationNode
|
||||
{
|
||||
public:
|
||||
CompoundRegionLogicalCaseSelectOperationNode (bool multi_layer, const std::vector<CompoundRegionOperationNode *> &inputs);
|
||||
|
||||
virtual std::string description () const;
|
||||
|
||||
// specifies the result type
|
||||
virtual ResultType result_type () const { return Region; }
|
||||
|
||||
// the different computation slots
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
|
||||
}
|
||||
|
||||
private:
|
||||
template <class T>
|
||||
void implement_compute_local (db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<T> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
|
||||
bool m_multi_layer;
|
||||
};
|
||||
|
||||
|
||||
class DB_PUBLIC CompoundRegionFilterOperationNode
|
||||
: public CompoundRegionMultiInputOperationNode
|
||||
{
|
||||
public:
|
||||
CompoundRegionFilterOperationNode (PolygonFilterBase *filter, CompoundRegionOperationNode *input);
|
||||
|
||||
virtual std::string description () const;
|
||||
|
||||
// specifies the result type
|
||||
virtual ResultType result_type () const { return Region; }
|
||||
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
|
||||
virtual const TransformationReducer *vars () const { return mp_filter->vars (); }
|
||||
virtual bool wants_variants () const { return mp_filter->wants_variants (); }
|
||||
|
||||
private:
|
||||
PolygonFilterBase *mp_filter;
|
||||
|
||||
bool is_selected (const db::Polygon &p) const;
|
||||
bool is_selected (const db::PolygonRef &p) const;
|
||||
|
||||
template <class T>
|
||||
void implement_compute_local (db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<T> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
std::vector<std::unordered_set<T> > one;
|
||||
one.push_back (std::unordered_set<T> ());
|
||||
|
||||
child (0)->compute_local (layout, interactions, one, max_vertex_count, area_ratio);
|
||||
|
||||
for (typename std::unordered_set<T>::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) {
|
||||
if (is_selected (*p)) {
|
||||
results.front ().insert (*p);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class DB_PUBLIC CompoundRegionProcessingOperationNode
|
||||
: public CompoundRegionMultiInputOperationNode
|
||||
{
|
||||
public:
|
||||
CompoundRegionProcessingOperationNode (PolygonProcessorBase *proc, CompoundRegionOperationNode *input);
|
||||
|
||||
virtual std::string description () const;
|
||||
|
||||
// specifies the result type
|
||||
virtual ResultType result_type () const { return Region; }
|
||||
|
||||
virtual const TransformationReducer *vars () const { return mp_proc->vars (); }
|
||||
virtual bool wants_variants () const { return mp_proc->wants_variants (); }
|
||||
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
|
||||
private:
|
||||
PolygonProcessorBase *mp_proc;
|
||||
|
||||
void processed (db::Layout *, const db::Polygon &p, std::vector<db::Polygon> &res) const;
|
||||
void processed (db::Layout *layout, const db::PolygonRef &p, std::vector<db::PolygonRef> &res) const;
|
||||
|
||||
template <class T>
|
||||
void implement_compute_local (db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<T> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
std::vector<std::unordered_set<T> > one;
|
||||
one.push_back (std::unordered_set<T> ());
|
||||
|
||||
child (0)->compute_local (layout, interactions, one, max_vertex_count, area_ratio);
|
||||
|
||||
for (typename std::unordered_set<T>::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) {
|
||||
std::vector<T> res;
|
||||
processed (layout, *p, res);
|
||||
results.front ().insert (res.begin (), res.end ());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class DB_PUBLIC CompoundRegionToEdgeProcessingOperationNode
|
||||
: public CompoundRegionMultiInputOperationNode
|
||||
{
|
||||
public:
|
||||
CompoundRegionToEdgeProcessingOperationNode (PolygonToEdgeProcessorBase *proc, CompoundRegionOperationNode *input);
|
||||
|
||||
virtual std::string description () const;
|
||||
|
||||
// specifies the result type
|
||||
virtual ResultType result_type () const { return Edges; }
|
||||
|
||||
virtual const TransformationReducer *vars () const { return mp_proc->vars (); }
|
||||
virtual bool wants_variants () const { return mp_proc->wants_variants (); }
|
||||
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
|
||||
private:
|
||||
PolygonToEdgeProcessorBase *mp_proc;
|
||||
|
||||
void processed (db::Layout *, const db::Polygon &p, std::vector<db::Edge> &res) const;
|
||||
void processed (db::Layout *layout, const db::PolygonRef &p, std::vector<db::Edge> &res) const;
|
||||
|
||||
template <class T>
|
||||
void implement_compute_local (db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
std::vector<std::unordered_set<T> > one;
|
||||
one.push_back (std::unordered_set<T> ());
|
||||
|
||||
child (0)->compute_local (layout, interactions, one, max_vertex_count, area_ratio);
|
||||
|
||||
for (typename std::unordered_set<T>::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) {
|
||||
std::vector<db::Edge> res;
|
||||
processed (layout, *p, res);
|
||||
results.front ().insert (res.begin (), res.end ());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class DB_PUBLIC CompoundRegionToEdgePairProcessingOperationNode
|
||||
: public CompoundRegionMultiInputOperationNode
|
||||
{
|
||||
public:
|
||||
CompoundRegionToEdgePairProcessingOperationNode (PolygonToEdgePairProcessorBase *proc, CompoundRegionOperationNode *input);
|
||||
|
||||
virtual std::string description () const;
|
||||
|
||||
// specifies the result type
|
||||
virtual ResultType result_type () const { return EdgePairs; }
|
||||
|
||||
virtual const TransformationReducer *vars () const { return mp_proc->vars (); }
|
||||
virtual bool wants_variants () const { return mp_proc->wants_variants (); }
|
||||
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const;
|
||||
|
||||
private:
|
||||
PolygonToEdgePairProcessorBase *mp_proc;
|
||||
|
||||
void processed (db::Layout *, const db::Polygon &p, std::vector<db::EdgePair> &res) const;
|
||||
void processed (db::Layout *layout, const db::PolygonRef &p, std::vector<db::EdgePair> &res) const;
|
||||
|
||||
template <class T>
|
||||
void implement_compute_local (db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
std::vector<std::unordered_set<T> > one;
|
||||
one.push_back (std::unordered_set<T> ());
|
||||
|
||||
child (0)->compute_local (layout, interactions, one, max_vertex_count, area_ratio);
|
||||
|
||||
for (typename std::unordered_set<T>::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) {
|
||||
std::vector<db::EdgePair> res;
|
||||
processed (layout, *p, res);
|
||||
results.front ().insert (res.begin (), res.end ());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
class DB_PUBLIC compound_local_operation
|
||||
: public local_operation<TS, TI, TR>
|
||||
{
|
||||
public:
|
||||
compound_local_operation<TS, TI, TR> (CompoundRegionOperationNode *node)
|
||||
: mp_node (node)
|
||||
{ }
|
||||
|
||||
virtual void compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
|
||||
const TS &subject_shape = interactions.subject_shape (i->first);
|
||||
|
||||
shape_interactions<TS, TI> single_interactions;
|
||||
|
||||
single_interactions.add_subject_shape (i->first, subject_shape);
|
||||
const std::vector<unsigned int> &intruders = single_interactions.intruders_for (i->first);
|
||||
for (typename std::vector<unsigned int>::const_iterator ii = intruders.begin (); ii != intruders.end (); ++ii) {
|
||||
const std::pair<unsigned int, TI> &is = interactions.intruder_shape (*ii);
|
||||
single_interactions.add_intruder_shape (*ii, is.first, is.second);
|
||||
single_interactions.add_interaction (i->first, *ii);
|
||||
}
|
||||
|
||||
mp_node->compute_local (layout, single_interactions, results, max_vertex_count, area_ratio);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
virtual db::Coord dist () const;
|
||||
virtual typename local_operation<TS, TI, TR>::on_empty_intruder_mode on_empty_intruder_hint () const;
|
||||
virtual std::string description () const;
|
||||
|
||||
const TransformationReducer *vars () const { return mp_node->vars (); }
|
||||
bool wants_variants () const { return mp_node->wants_variants (); }
|
||||
|
||||
private:
|
||||
std::auto_ptr<CompoundRegionOperationNode> mp_node;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue