Generalization of code for twobool local operation

This commit is contained in:
Matthias Koefferlein 2020-06-14 17:06:53 +02:00
parent 41fe04bbc8
commit 3637b15a74
3 changed files with 97 additions and 85 deletions

View File

@ -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)

View File

@ -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

View File

@ -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;