diff --git a/src/db/db/dbLocalOperation.cc b/src/db/db/dbLocalOperation.cc index 20a77e6f4..b0e340c60 100644 --- a/src/db/db/dbLocalOperation.cc +++ b/src/db/db/dbLocalOperation.cc @@ -115,6 +115,86 @@ BoolAndOrNotLocalOperation::compute_local (db::Layout *layout, const shape_inter } } +// --------------------------------------------------------------------------------------------- +// TwoBoolAndNotLocalOperation implementation + +TwoBoolAndNotLocalOperation::TwoBoolAndNotLocalOperation () + : db::local_operation () +{ + // .. nothing yet .. +} + +void +TwoBoolAndNotLocalOperation::compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const +{ + tl_assert (results.size () == 2); + + db::EdgeProcessor ep; + + std::unordered_set &result0 = results [0]; + std::unordered_set &result1 = results [1]; + + size_t p1 = 0, p2 = 1; + + std::set others; + for (db::shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { + for (db::shape_interactions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { + others.insert (interactions.intruder_shape (*j).second); + } + } + + for (db::shape_interactions::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::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 > 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) diff --git a/src/db/db/dbLocalOperation.h b/src/db/db/dbLocalOperation.h index 5cb21d691..dc577781a 100644 --- a/src/db/db/dbLocalOperation.h +++ b/src/db/db/dbLocalOperation.h @@ -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 +{ +public: + TwoBoolAndNotLocalOperation (); + + virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &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 diff --git a/src/db/unit_tests/dbHierProcessorTests.cc b/src/db/unit_tests/dbHierProcessorTests.cc index 5672f0522..05ac5b94f 100644 --- a/src/db/unit_tests/dbHierProcessorTests.cc +++ b/src/db/unit_tests/dbHierProcessorTests.cc @@ -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 -{ -public: - BoolAndPlusNotLocalOperation () - : db::local_operation () - { - // .. nothing yet .. - } - - virtual std::string description () const - { - return std::string (); - } - - void compute_local (db::Layout *layout, const db::shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const - { - tl_assert (results.size () == 2); - - db::EdgeProcessor ep; - - std::unordered_set &result0 = results [0]; - std::unordered_set &result1 = results [1]; - - size_t p1 = 0, p2 = 1; - - std::set others; - for (db::shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { - for (db::shape_interactions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { - others.insert (interactions.intruder_shape (*j).second); - } - } - - for (db::shape_interactions::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::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 > 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;