mirror of https://github.com/KLayout/klayout.git
Generalization of code for twobool local operation
This commit is contained in:
parent
41fe04bbc8
commit
3637b15a74
|
|
@ -115,6 +115,86 @@ BoolAndOrNotLocalOperation::compute_local (db::Layout *layout, const shape_inter
|
|||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// TwoBoolAndNotLocalOperation implementation
|
||||
|
||||
TwoBoolAndNotLocalOperation::TwoBoolAndNotLocalOperation ()
|
||||
: db::local_operation<db::PolygonRef, db::PolygonRef, db::PolygonRef> ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void
|
||||
TwoBoolAndNotLocalOperation::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
|
||||
{
|
||||
tl_assert (results.size () == 2);
|
||||
|
||||
db::EdgeProcessor ep;
|
||||
|
||||
std::unordered_set<db::PolygonRef> &result0 = results [0];
|
||||
std::unordered_set<db::PolygonRef> &result1 = results [1];
|
||||
|
||||
size_t p1 = 0, p2 = 1;
|
||||
|
||||
std::set<db::PolygonRef> others;
|
||||
for (db::shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (db::shape_interactions<db::PolygonRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
others.insert (interactions.intruder_shape (*j).second);
|
||||
}
|
||||
}
|
||||
|
||||
for (db::shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
|
||||
const db::PolygonRef &subject = interactions.subject_shape (i->first);
|
||||
if (others.find (subject) != others.end ()) {
|
||||
result0.insert (subject);
|
||||
} else if (i->second.empty ()) {
|
||||
// shortcut (not: keep, and: drop)
|
||||
result1.insert (subject);
|
||||
} else {
|
||||
for (db::PolygonRef::polygon_edge_iterator e = subject.begin_edge (); ! e.at_end(); ++e) {
|
||||
ep.insert (*e, p1);
|
||||
}
|
||||
p1 += 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (! others.empty () || p1 > 0) {
|
||||
|
||||
for (std::set<db::PolygonRef>::const_iterator o = others.begin (); o != others.end (); ++o) {
|
||||
for (db::PolygonRef::polygon_edge_iterator e = o->begin_edge (); ! e.at_end(); ++e) {
|
||||
ep.insert (*e, p2);
|
||||
}
|
||||
p2 += 2;
|
||||
}
|
||||
|
||||
db::BooleanOp op0 (db::BooleanOp::And);
|
||||
db::PolygonRefGenerator pr0 (layout, result0);
|
||||
db::PolygonSplitter splitter0 (pr0, area_ratio, max_vertex_count);
|
||||
db::PolygonGenerator pg0 (splitter0, true, true);
|
||||
|
||||
db::BooleanOp op1 (db::BooleanOp::ANotB);
|
||||
db::PolygonRefGenerator pr1 (layout, result1);
|
||||
db::PolygonSplitter splitter1 (pr1, area_ratio, max_vertex_count);
|
||||
db::PolygonGenerator pg1 (splitter1, true, true);
|
||||
|
||||
ep.set_base_verbosity (50);
|
||||
|
||||
std::vector<std::pair<db::EdgeSink *, db::EdgeEvaluatorBase *> > procs;
|
||||
procs.push_back (std::make_pair (&pg0, &op0));
|
||||
procs.push_back (std::make_pair (&pg1, &op1));
|
||||
ep.process (procs);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::string TwoBoolAndNotLocalOperation::description () const
|
||||
{
|
||||
return tl::to_string (tr ("ANDNOT operation"));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
SelfOverlapMergeLocalOperation::SelfOverlapMergeLocalOperation (unsigned int wrap_count)
|
||||
|
|
|
|||
|
|
@ -126,6 +126,22 @@ private:
|
|||
bool m_is_and;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Implements a boolean AND plus NOT operation
|
||||
*
|
||||
* This processor delivers two outputs: the first one having the AND result, the second
|
||||
* one having the NOT result.
|
||||
*/
|
||||
class DB_PUBLIC TwoBoolAndNotLocalOperation
|
||||
: public local_operation<db::PolygonRef, db::PolygonRef, db::PolygonRef>
|
||||
{
|
||||
public:
|
||||
TwoBoolAndNotLocalOperation ();
|
||||
|
||||
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &result, size_t max_vertex_count, double area_ratio) const;
|
||||
virtual std::string description () const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Implements a merge operation with an overlap count
|
||||
* With a given wrap_count, the result will only contains shapes where
|
||||
|
|
|
|||
|
|
@ -84,90 +84,6 @@ private:
|
|||
db::Coord m_dist;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A new processor class providing two outputs for two inputs: one for AND and one for NOT
|
||||
*/
|
||||
class BoolAndPlusNotLocalOperation
|
||||
: public db::local_operation<db::PolygonRef, db::PolygonRef, db::PolygonRef>
|
||||
{
|
||||
public:
|
||||
BoolAndPlusNotLocalOperation ()
|
||||
: db::local_operation<db::PolygonRef, db::PolygonRef, db::PolygonRef> ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual std::string description () const
|
||||
{
|
||||
return std::string ();
|
||||
}
|
||||
|
||||
void compute_local (db::Layout *layout, const db::shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, size_t max_vertex_count, double area_ratio) const
|
||||
{
|
||||
tl_assert (results.size () == 2);
|
||||
|
||||
db::EdgeProcessor ep;
|
||||
|
||||
std::unordered_set<db::PolygonRef> &result0 = results [0];
|
||||
std::unordered_set<db::PolygonRef> &result1 = results [1];
|
||||
|
||||
size_t p1 = 0, p2 = 1;
|
||||
|
||||
std::set<db::PolygonRef> others;
|
||||
for (db::shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (db::shape_interactions<db::PolygonRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
others.insert (interactions.intruder_shape (*j).second);
|
||||
}
|
||||
}
|
||||
|
||||
for (db::shape_interactions<db::PolygonRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
|
||||
const db::PolygonRef &subject = interactions.subject_shape (i->first);
|
||||
if (others.find (subject) != others.end ()) {
|
||||
result0.insert (subject);
|
||||
} else if (i->second.empty ()) {
|
||||
// shortcut (not: keep, and: drop)
|
||||
result1.insert (subject);
|
||||
} else {
|
||||
for (db::PolygonRef::polygon_edge_iterator e = subject.begin_edge (); ! e.at_end(); ++e) {
|
||||
ep.insert (*e, p1);
|
||||
}
|
||||
p1 += 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (! others.empty () || p1 > 0) {
|
||||
|
||||
for (std::set<db::PolygonRef>::const_iterator o = others.begin (); o != others.end (); ++o) {
|
||||
for (db::PolygonRef::polygon_edge_iterator e = o->begin_edge (); ! e.at_end(); ++e) {
|
||||
ep.insert (*e, p2);
|
||||
}
|
||||
p2 += 2;
|
||||
}
|
||||
|
||||
db::BooleanOp op0 (db::BooleanOp::And);
|
||||
db::PolygonRefGenerator pr0 (layout, result0);
|
||||
db::PolygonSplitter splitter0 (pr0, area_ratio, max_vertex_count);
|
||||
db::PolygonGenerator pg0 (splitter0, true, true);
|
||||
|
||||
db::BooleanOp op1 (db::BooleanOp::ANotB);
|
||||
db::PolygonRefGenerator pr1 (layout, result1);
|
||||
db::PolygonSplitter splitter1 (pr1, area_ratio, max_vertex_count);
|
||||
db::PolygonGenerator pg1 (splitter1, true, true);
|
||||
|
||||
ep.set_base_verbosity (50);
|
||||
|
||||
std::vector<std::pair<db::EdgeSink *, db::EdgeEvaluatorBase *> > procs;
|
||||
procs.push_back (std::make_pair (&pg0, &op0));
|
||||
procs.push_back (std::make_pair (&pg1, &op1));
|
||||
ep.process (procs);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A new processor class which and/nots with a sized version of the intruder
|
||||
*/
|
||||
|
|
@ -318,7 +234,7 @@ static void run_test_bool_gen (tl::TestBase *_this, const char *file, TestMode m
|
|||
db::SelfOverlapMergeLocalOperation self_intersect_op (2);
|
||||
BoolAndOrNotWithSizedLocalOperation sized_bool_op (mode == TMAnd || mode == TMAndSwapped, dist);
|
||||
SelfOverlapWithSizedLocalOperation sized_self_intersect_op (2, dist);
|
||||
BoolAndPlusNotLocalOperation andnot;
|
||||
db::TwoBoolAndNotLocalOperation andnot;
|
||||
|
||||
if (mode == TMAndNot) {
|
||||
lop = &andnot;
|
||||
|
|
|
|||
Loading…
Reference in New Issue