diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index 6a48ed09c..0e8d42386 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -42,6 +42,8 @@ #include +#define USE_LOCAL_PROCESSOR // @@@ + namespace db { @@ -394,7 +396,7 @@ AsIfFlatRegion::selected_interacting_generic (const Edges &other, bool inverse, scanner.reserve2 (other.size ()); std::auto_ptr output (new FlatRegion (false)); - region_to_edge_interaction_filter filter (inserter, false, counting /*get all in counting mode*/); + region_to_edge_interaction_filter filter (inserter, false, counting /*get all in counting mode*/); AddressablePolygonDelivery p (begin_merged ()); @@ -440,6 +442,27 @@ AsIfFlatRegion::selected_interacting_generic (const Texts &other, bool inverse, return clone (); } +#if defined(USE_LOCAL_PROCESSOR) + + db::RegionIterator polygons (begin_merged ()); + + db::interacting_with_text_local_operation op (inverse, min_count, max_count); + + db::local_processor proc; + proc.set_base_verbosity (base_verbosity ()); + + std::vector > others; + others.push_back (other.begin ()); + + std::auto_ptr output (new FlatRegion (merged_semantics ())); + std::vector results; + results.push_back (&output->raw_polygons ()); + + proc.run_flat (polygons, others, &op, results); + + return output.release (); + +#else bool counting = !(min_count == 1 && max_count == std::numeric_limits::max ()); std::unordered_map > counted_results; @@ -480,6 +503,7 @@ AsIfFlatRegion::selected_interacting_generic (const Texts &other, bool inverse, } return output.release (); +#endif } RegionDelegate * @@ -501,7 +525,7 @@ AsIfFlatRegion::selected_interacting_generic (const Region &other, int mode, boo } } -#if 1 +#if defined(USE_LOCAL_PROCESSOR) bool counting = !(min_count == 1 && max_count == std::numeric_limits::max ()); @@ -624,7 +648,7 @@ AsIfFlatRegion::pull_generic (const Edges &other) const scanner.reserve2 (other.size ()); std::auto_ptr output (new FlatEdges (false)); - region_to_edge_interaction_filter filter (output->raw_edges (), false); + region_to_edge_interaction_filter filter (output->raw_edges (), false); AddressablePolygonDelivery p (begin ()); @@ -657,7 +681,7 @@ AsIfFlatRegion::pull_generic (const Texts &other) const scanner.reserve2 (other.size ()); std::auto_ptr output (new FlatTexts (false)); - region_to_text_interaction_filter filter (output->raw_texts (), false); + region_to_text_interaction_filter filter (output->raw_texts (), false); AddressablePolygonDelivery p (begin ()); diff --git a/src/db/db/dbHierProcessor.cc b/src/db/db/dbHierProcessor.cc index 600373f90..64a79dcec 100644 --- a/src/db/db/dbHierProcessor.cc +++ b/src/db/db/dbHierProcessor.cc @@ -135,13 +135,13 @@ private: mutable std::unordered_map m_cache_by_shape; }; -template <> -class shape_reference_translator +template +class simple_shape_reference_translator { public: - typedef db::Edge shape_type; + typedef Shape shape_type; - shape_reference_translator (db::Layout * /*target_layout*/) + simple_shape_reference_translator () { // .. nothing yet .. } @@ -159,26 +159,27 @@ public: }; template <> -class shape_reference_translator +class shape_reference_translator + : public simple_shape_reference_translator { public: - typedef db::Polygon shape_type; + shape_reference_translator (db::Layout * /*target_layout*/) { } +}; - shape_reference_translator (db::Layout * /*target_layout*/) - { - // .. nothing yet .. - } +template <> +class shape_reference_translator + : public simple_shape_reference_translator +{ +public: + shape_reference_translator (db::Layout * /*target_layout*/) { } +}; - const shape_type &operator() (const shape_type &s) const - { - return s; - } - - template - shape_type operator() (const shape_type &s, const Trans &tr) const - { - return s.transformed (tr); - } +template <> +class shape_reference_translator + : public simple_shape_reference_translator +{ +public: + shape_reference_translator (db::Layout * /*target_layout*/) { } }; template @@ -338,6 +339,7 @@ local_processor_cell_context::propagate (unsigned int output_layer, } template class DB_PUBLIC local_processor_cell_context; +template class DB_PUBLIC local_processor_cell_context; template class DB_PUBLIC local_processor_cell_context; template class DB_PUBLIC local_processor_cell_context; template class DB_PUBLIC local_processor_cell_context; @@ -683,6 +685,7 @@ shape_interactions::intruder_shape (unsigned int id) const } template class DB_PUBLIC shape_interactions; +template class DB_PUBLIC shape_interactions; template class DB_PUBLIC shape_interactions; template class DB_PUBLIC shape_interactions; template class DB_PUBLIC shape_interactions; @@ -1038,6 +1041,7 @@ local_processor_context_computation_task::perform () } template class DB_PUBLIC local_processor_context_computation_task; +template class DB_PUBLIC local_processor_context_computation_task; template class DB_PUBLIC local_processor_context_computation_task; template class DB_PUBLIC local_processor_context_computation_task; template class DB_PUBLIC local_processor_context_computation_task; @@ -1086,6 +1090,7 @@ local_processor_result_computation_task::perform () } template class DB_PUBLIC local_processor_result_computation_task; +template class DB_PUBLIC local_processor_result_computation_task; template class DB_PUBLIC local_processor_result_computation_task; template class DB_PUBLIC local_processor_result_computation_task; template class DB_PUBLIC local_processor_result_computation_task; @@ -2030,6 +2035,7 @@ local_processor::run_flat (const generic_shape_iterator &subject } template class DB_PUBLIC local_processor; +template class DB_PUBLIC local_processor; template class DB_PUBLIC local_processor; template class DB_PUBLIC local_processor; template class DB_PUBLIC local_processor; diff --git a/src/db/db/dbRegionLocalOperations.cc b/src/db/db/dbRegionLocalOperations.cc index b9f05679e..ce226e1a5 100644 --- a/src/db/db/dbRegionLocalOperations.cc +++ b/src/db/db/dbRegionLocalOperations.cc @@ -34,6 +34,19 @@ namespace // --------------------------------------------------------------------------------------------------------------- +static inline const db::Polygon *push_polygon_to_heap (db::Layout *, const db::Polygon &p, std::list &) +{ + return &p; +} + +static inline const db::PolygonRef *push_polygon_to_heap (db::Layout *layout, const db::PolygonRef &p, std::list &heap) +{ + db::PolygonRef ref = db::PolygonRef (p, layout->shape_repository ()); + heap.push_back (ref); + return &heap.back (); +} + + struct ResultInserter { typedef db::Polygon value_type; @@ -54,29 +67,29 @@ private: std::unordered_set *mp_result; }; -struct ResultCountingInserter +template +struct result_counting_inserter { - typedef db::Polygon value_type; + typedef TR value_type; - ResultCountingInserter (db::Layout *layout, std::unordered_map &result) - : mp_layout (layout), mp_result (&result) + result_counting_inserter (std::unordered_map &result) + : mp_result (&result) { // .. nothing yet .. } - void insert (const db::Polygon &p) + void insert (const TR &p) { - (*mp_result)[db::PolygonRef (p, mp_layout->shape_repository ())] += 1; + (*mp_result)[p] += 1; } - void init (const db::Polygon &p) + void init (const TR &p) { - (*mp_result)[db::PolygonRef (p, mp_layout->shape_repository ())] = 0; + (*mp_result)[p] = 0; } private: - db::Layout *mp_layout; - std::unordered_map *mp_result; + std::unordered_map *mp_result; }; struct EdgeResultInserter @@ -405,10 +418,10 @@ void InteractingWithEdgeLocalOperation::compute_local (db::Layout *layout, const std::unordered_map counted_results; bool counting = !(m_min_count == 1 && m_max_count == std::numeric_limits::max ()); - db::box_scanner2 scanner; + db::box_scanner2 scanner; - ResultCountingInserter inserter (layout, counted_results); - region_to_edge_interaction_filter filter (inserter, false, counting /*get all in counting mode*/); + result_counting_inserter inserter (counted_results); + region_to_edge_interaction_filter > filter (inserter, false, counting /*get all in counting mode*/); std::set intruder_ids; for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { @@ -421,20 +434,21 @@ void InteractingWithEdgeLocalOperation::compute_local (db::Layout *layout, const scanner.insert2 (& interactions.intruder_shape (*j).second, 0); } - std::list heap; + std::list heap; for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { const db::PolygonRef &subject = interactions.subject_shape (i->first); - heap.push_back (subject.obj ().transformed (subject.trans ())); - scanner.insert1 (&heap.back (), 0); + const db::PolygonRef *addressable = push_polygon_to_heap (layout, subject, heap); + + scanner.insert1 (addressable, 0); if (m_inverse) { - inserter.init (heap.back ()); + inserter.init (*addressable); } } - scanner.process (filter, 1, db::box_convert (), db::box_convert ()); + scanner.process (filter, 1, db::box_convert (), db::box_convert ()); // select hits based on their count @@ -476,15 +490,15 @@ db::Coord PullWithEdgeLocalOperation::dist () const return 1; } -void PullWithEdgeLocalOperation::compute_local (db::Layout *, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const +void PullWithEdgeLocalOperation::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 () == 1); std::unordered_set &result = results.front (); - db::box_scanner2 scanner; + db::box_scanner2 scanner; EdgeResultInserter inserter (result); - region_to_edge_interaction_filter filter (inserter, false); + region_to_edge_interaction_filter filter (inserter, false); for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { @@ -492,17 +506,13 @@ void PullWithEdgeLocalOperation::compute_local (db::Layout *, const shape_intera } } - std::list heap; + std::list heap; for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { - const db::PolygonRef &subject = interactions.subject_shape (i->first); - heap.push_back (subject.obj ().transformed (subject.trans ())); - - scanner.insert1 (&heap.back (), 0); - + scanner.insert1 (push_polygon_to_heap (layout, subject, heap), 0); } - scanner.process (filter, 1, db::box_convert (), db::box_convert ()); + scanner.process (filter, 1, db::box_convert (), db::box_convert ()); } PullWithEdgeLocalOperation::on_empty_intruder_mode PullWithEdgeLocalOperation::on_empty_intruder_hint () const @@ -536,7 +546,7 @@ void PullWithTextLocalOperation::compute_local (db::Layout *, const shape_intera db::box_scanner2 scanner; TextResultInserter inserter (result); - region_to_text_interaction_filter filter (inserter, false); + region_to_text_interaction_filter filter (inserter, false); for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { @@ -580,31 +590,35 @@ std::string PullWithTextLocalOperation::description () const // --------------------------------------------------------------------------------------------------------------- -InteractingWithTextLocalOperation::InteractingWithTextLocalOperation (bool inverse, size_t min_count, size_t max_count) +template +interacting_with_text_local_operation::interacting_with_text_local_operation (bool inverse, size_t min_count, size_t max_count) : m_inverse (inverse), m_min_count (std::max (size_t (1), min_count)), m_max_count (max_count) { // .. nothing yet .. } -db::Coord InteractingWithTextLocalOperation::dist () const +template +db::Coord interacting_with_text_local_operation::dist () const { // touching is sufficient return 1; } -void InteractingWithTextLocalOperation::compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const + +template +void interacting_with_text_local_operation::compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { - std::unordered_map counted_results; + std::unordered_map counted_results; bool counting = !(m_min_count == 1 && m_max_count == std::numeric_limits::max ()); - db::box_scanner2 scanner; + db::box_scanner2 scanner; - ResultCountingInserter inserter (layout, counted_results); - region_to_text_interaction_filter filter (inserter, false, counting /*get all in counting mode*/); + result_counting_inserter inserter (counted_results); + region_to_text_interaction_filter > filter (inserter, false, counting /*get all in counting mode*/); std::set intruder_ids; - for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { - for (shape_interactions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { + for (typename shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { + for (typename shape_interactions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { intruder_ids.insert (*j); } } @@ -613,27 +627,26 @@ void InteractingWithTextLocalOperation::compute_local (db::Layout *layout, const scanner.insert2 (& interactions.intruder_shape (*j).second, 0); } - std::list heap; - for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { + std::list heap; + for (typename shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { - const db::PolygonRef &subject = interactions.subject_shape (i->first); - heap.push_back (subject.obj ().transformed (subject.trans ())); + const TR *addressable = push_polygon_to_heap (layout, interactions.subject_shape (i->first), heap); - scanner.insert1 (&heap.back (), 0); + scanner.insert1 (addressable, 0); if (m_inverse) { - inserter.init (heap.back ()); + inserter.init (*addressable); } } - scanner.process (filter, 1, db::box_convert (), db::box_convert ()); + scanner.process (filter, 1, db::box_convert (), db::box_convert ()); // select hits based on their count tl_assert (results.size () == 1); - std::unordered_set &result = results.front (); + std::unordered_set &result = results.front (); - for (std::unordered_map::const_iterator r = counted_results.begin (); r != counted_results.end (); ++r) { + for (typename std::unordered_map::const_iterator r = counted_results.begin (); r != counted_results.end (); ++r) { bool hit = r->second >= m_min_count && r->second <= m_max_count; if (hit != m_inverse) { result.insert (r->first); @@ -641,18 +654,24 @@ void InteractingWithTextLocalOperation::compute_local (db::Layout *layout, const } } -InteractingWithTextLocalOperation::on_empty_intruder_mode InteractingWithTextLocalOperation::on_empty_intruder_hint () const +template +typename local_operation::on_empty_intruder_mode interacting_with_text_local_operation::on_empty_intruder_hint () const { if (!m_inverse) { - return Drop; + return local_operation::Drop; } else { - return Copy; + return local_operation::Copy; } } -std::string InteractingWithTextLocalOperation::description () const +template +std::string interacting_with_text_local_operation::description () const { return tl::to_string (tr ("Select regions by their geometric relation to texts")); } +// explicit instantiations +template class interacting_with_text_local_operation; +template class interacting_with_text_local_operation; + } diff --git a/src/db/db/dbRegionLocalOperations.h b/src/db/db/dbRegionLocalOperations.h index 464c80988..4713a63d0 100644 --- a/src/db/db/dbRegionLocalOperations.h +++ b/src/db/db/dbRegionLocalOperations.h @@ -127,15 +127,16 @@ public: virtual std::string description () const; }; -class InteractingWithTextLocalOperation - : public local_operation +template +class interacting_with_text_local_operation + : public local_operation { public: - InteractingWithTextLocalOperation (bool inverse, size_t min_count, size_t max_count); + interacting_with_text_local_operation (bool inverse, size_t min_count, size_t max_count); virtual db::Coord dist () const; - virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const; - virtual on_empty_intruder_mode on_empty_intruder_hint () const; + virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const; + virtual typename local_operation::on_empty_intruder_mode on_empty_intruder_hint () const; virtual std::string description () const; private: @@ -143,6 +144,8 @@ private: size_t m_min_count, m_max_count; }; +typedef interacting_with_text_local_operation InteractingWithTextLocalOperation; + } // namespace db #endif diff --git a/src/db/db/dbRegionUtils.cc b/src/db/db/dbRegionUtils.cc index ee2e54f4d..861051766 100644 --- a/src/db/db/dbRegionUtils.cc +++ b/src/db/db/dbRegionUtils.cc @@ -363,23 +363,23 @@ Poly2PolyCheckBase::enter (const db::Polygon &o1, size_t p1, const db::Polygon & // ------------------------------------------------------------------------------------- // RegionToEdgeInteractionFilterBase implementation -template -region_to_edge_interaction_filter_base::region_to_edge_interaction_filter_base (bool inverse, bool get_all) +template +region_to_edge_interaction_filter_base::region_to_edge_interaction_filter_base (bool inverse, bool get_all) : m_inverse (inverse), m_get_all (get_all) { // .. nothing yet .. } -template +template void -region_to_edge_interaction_filter_base::preset (const OutputType *s) +region_to_edge_interaction_filter_base::preset (const OutputType *s) { m_seen.insert (s); } -template +template void -region_to_edge_interaction_filter_base::add (const db::Polygon *p, size_t, const db::Edge *e, size_t) +region_to_edge_interaction_filter_base::add (const PolygonType *p, size_t, const EdgeType *e, size_t) { const OutputType *o = 0; tl::select (o, p, e); @@ -392,7 +392,7 @@ region_to_edge_interaction_filter_base::add (const db::Polygon *p, s if (p->box ().contains (e->p1 ()) && db::inside_poly (p->begin_edge (), e->p1 ()) >= 0) { interacts = true; } else { - for (db::Polygon::polygon_edge_iterator pe = p->begin_edge (); ! pe.at_end () && ! interacts; ++pe) { + for (typename PolygonType::polygon_edge_iterator pe = p->begin_edge (); ! pe.at_end () && ! interacts; ++pe) { if ((*pe).intersect (*e)) { interacts = true; } @@ -413,9 +413,9 @@ region_to_edge_interaction_filter_base::add (const db::Polygon *p, s } } -template +template void -region_to_edge_interaction_filter_base::fill_output () +region_to_edge_interaction_filter_base::fill_output () { for (typename std::set::const_iterator s = m_seen.begin (); s != m_seen.end (); ++s) { put (**s); @@ -423,29 +423,31 @@ region_to_edge_interaction_filter_base::fill_output () } // explicit instantiations -template class region_to_edge_interaction_filter_base; -template class region_to_edge_interaction_filter_base; +template class region_to_edge_interaction_filter_base; +template class region_to_edge_interaction_filter_base; +template class region_to_edge_interaction_filter_base; +template class region_to_edge_interaction_filter_base; // ------------------------------------------------------------------------------------- // RegionToTextInteractionFilterBase implementation -template -region_to_text_interaction_filter_base::region_to_text_interaction_filter_base (bool inverse, bool get_all) +template +region_to_text_interaction_filter_base::region_to_text_interaction_filter_base (bool inverse, bool get_all) : m_inverse (inverse), m_get_all (get_all) { // .. nothing yet .. } -template +template void -region_to_text_interaction_filter_base::preset (const OutputType *s) +region_to_text_interaction_filter_base::preset (const OutputType *s) { m_seen.insert (s); } -template +template void -region_to_text_interaction_filter_base::add (const db::Polygon *p, size_t, const TextType *t, size_t) +region_to_text_interaction_filter_base::add (const PolygonType *p, size_t, const TextType *t, size_t) { const OutputType *o = 0; tl::select (o, p, t); @@ -469,9 +471,9 @@ region_to_text_interaction_filter_base::add (const db::Pol } } -template +template void -region_to_text_interaction_filter_base::fill_output () +region_to_text_interaction_filter_base::fill_output () { for (typename std::set::const_iterator s = m_seen.begin (); s != m_seen.end (); ++s) { put (**s); @@ -479,10 +481,11 @@ region_to_text_interaction_filter_base::fill_output () } // explicit instantiations -template class region_to_text_interaction_filter_base; -template class region_to_text_interaction_filter_base; -template class region_to_text_interaction_filter_base; -template class region_to_text_interaction_filter_base; +template class region_to_text_interaction_filter_base; +template class region_to_text_interaction_filter_base; +template class region_to_text_interaction_filter_base; +template class region_to_text_interaction_filter_base; +template class region_to_text_interaction_filter_base; // ------------------------------------------------------------------------------------- // Polygon snapping diff --git a/src/db/db/dbRegionUtils.h b/src/db/db/dbRegionUtils.h index 2f9f31bc5..3496a8d47 100644 --- a/src/db/db/dbRegionUtils.h +++ b/src/db/db/dbRegionUtils.h @@ -591,15 +591,15 @@ public: /** * @brief A helper class for the region to edge interaction functionality */ -template +template class DB_PUBLIC region_to_edge_interaction_filter_base - : public db::box_scanner_receiver2 + : public db::box_scanner_receiver2 { public: region_to_edge_interaction_filter_base (bool inverse, bool get_all); void preset (const OutputType *s); - void add (const db::Polygon *p, size_t, const db::Edge *e, size_t); + void add (const PolygonType *p, size_t, const EdgeType *e, size_t); void fill_output (); protected: @@ -613,21 +613,21 @@ private: /** * @brief A helper class for the region to edge interaction functionality */ -template +template class DB_PUBLIC_TEMPLATE region_to_edge_interaction_filter - : public region_to_edge_interaction_filter_base + : public region_to_edge_interaction_filter_base { public: region_to_edge_interaction_filter (OutputContainer &output, bool inverse, bool get_all = false) - : region_to_edge_interaction_filter_base (inverse, get_all), mp_output (&output) + : region_to_edge_interaction_filter_base (inverse, get_all), mp_output (&output) { // .. nothing yet .. } protected: - virtual void put (const OutputType &poly) const + virtual void put (const OutputType &res) const { - mp_output->insert (poly); + mp_output->insert (res); } private: @@ -637,15 +637,15 @@ private: /** * @brief A helper class for the region to text interaction functionality */ -template +template class DB_PUBLIC region_to_text_interaction_filter_base - : public db::box_scanner_receiver2 + : public db::box_scanner_receiver2 { public: region_to_text_interaction_filter_base (bool inverse, bool get_all); void preset (const OutputType *s); - void add (const db::Polygon *p, size_t, const TextType *e, size_t); + void add (const PolygonType *p, size_t, const TextType *e, size_t); void fill_output (); protected: @@ -659,13 +659,13 @@ private: /** * @brief A helper class for the region to text interaction functionality */ -template +template class DB_PUBLIC_TEMPLATE region_to_text_interaction_filter - : public region_to_text_interaction_filter_base + : public region_to_text_interaction_filter_base { public: region_to_text_interaction_filter (OutputContainer &output, bool inverse, bool get_all = false) - : region_to_text_interaction_filter_base (inverse, get_all), mp_output (&output) + : region_to_text_interaction_filter_base (inverse, get_all), mp_output (&output) { // .. nothing yet .. }