diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index 6fd2073df..f55f09987 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -1013,6 +1013,34 @@ AsIfFlatRegion::scaled_and_snapped (db::Coord gx, db::Coord mx, db::Coord dx, db EdgePairsDelegate * AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const { +#if defined(USE_LOCAL_PROCESSOR) + + db::RegionIterator polygons (begin_merged ()); + + EdgeRelationFilter check (rel, d, metrics); + check.set_include_zero (false); + check.set_whole_edges (whole_edges); + check.set_ignore_angle (ignore_angle); + check.set_min_projection (min_projection); + check.set_max_projection (max_projection); + + db::check_local_operation op (check, different_polygons, other != 0, shielded); + + db::local_processor proc; + proc.set_base_verbosity (base_verbosity ()); + + std::vector > others; + others.push_back (other ? other->begin () : begin_merged ()); + + std::auto_ptr output (new FlatEdgePairs ()); + std::vector results; + results.push_back (&output->raw_edge_pairs ()); + + proc.run_flat (polygons, others, &op, results); + + return output.release (); + +#else std::auto_ptr result (new FlatEdgePairs ()); db::box_scanner scanner (report_progress (), progress_desc ()); @@ -1055,6 +1083,7 @@ AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons, } while (edge_check.prepare_next_pass ()); return result.release (); +#endif } EdgePairsDelegate * @@ -1070,7 +1099,7 @@ AsIfFlatRegion::run_single_polygon_check (db::edge_relation_type rel, db::Coord check.set_max_projection (max_projection); edge2edge_check edge_check (check, *result, false /*=same polygons*/, false /*=same layers*/, shielded); - poly2poly_check poly_check (edge_check); + poly2poly_check poly_check (edge_check); do { diff --git a/src/db/db/dbDeepEdgePairs.cc b/src/db/db/dbDeepEdgePairs.cc index 200ae1456..6b55df25e 100644 --- a/src/db/db/dbDeepEdgePairs.cc +++ b/src/db/db/dbDeepEdgePairs.cc @@ -87,6 +87,7 @@ public: { m_iter.set_region (region); m_iter.set_overlapping (overlapping); + set (); } virtual db::Box bbox () const diff --git a/src/db/db/dbDeepEdges.cc b/src/db/db/dbDeepEdges.cc index 069b39bc6..4a5ca66b0 100644 --- a/src/db/db/dbDeepEdges.cc +++ b/src/db/db/dbDeepEdges.cc @@ -94,6 +94,7 @@ public: { m_iter.set_region (region); m_iter.set_overlapping (overlapping); + set (); } virtual db::Box bbox () const diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index c3d3d9d1d..00e2352cd 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -99,6 +99,7 @@ public: { m_iter.set_region (region); m_iter.set_overlapping (overlapping); + set (); } virtual db::Box bbox () const @@ -1390,7 +1391,7 @@ DeepRegion::run_single_polygon_check (db::edge_relation_type rel, db::Coord d, b for (db::Shapes::shape_iterator s = shapes.begin (db::ShapeIterator::Polygons); ! s.at_end (); ++s) { edge2edge_check edge_check (check, result, false, false, shielded); - poly2poly_check poly_check (edge_check); + poly2poly_check poly_check (edge_check); db::Polygon poly; s->polygon (poly); diff --git a/src/db/db/dbDeepTexts.cc b/src/db/db/dbDeepTexts.cc index 605fd1533..e0598f046 100644 --- a/src/db/db/dbDeepTexts.cc +++ b/src/db/db/dbDeepTexts.cc @@ -92,6 +92,7 @@ public: { m_iter.set_region (region); m_iter.set_overlapping (overlapping); + set (); } virtual db::Box bbox () const diff --git a/src/db/db/dbHierProcessor.cc b/src/db/db/dbHierProcessor.cc index d759e0837..736f7e4bd 100644 --- a/src/db/db/dbHierProcessor.cc +++ b/src/db/db/dbHierProcessor.cc @@ -338,6 +338,7 @@ local_processor_cell_context::propagate (unsigned int output_layer, } } +// explicit instantiations template class DB_PUBLIC local_processor_cell_context; template class DB_PUBLIC local_processor_cell_context; template class DB_PUBLIC local_processor_cell_context; @@ -346,6 +347,7 @@ 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; template class DB_PUBLIC local_processor_cell_context; template class DB_PUBLIC local_processor_cell_context; @@ -588,6 +590,7 @@ local_processor_cell_contexts::compute_results (const local_processo } } +// explicit instantiations template class DB_PUBLIC local_processor_cell_contexts; template class DB_PUBLIC local_processor_cell_contexts; template class DB_PUBLIC local_processor_cell_contexts; @@ -596,6 +599,7 @@ template class DB_PUBLIC local_processor_cell_contexts; template class DB_PUBLIC local_processor_cell_contexts; template class DB_PUBLIC local_processor_cell_contexts; +template class DB_PUBLIC local_processor_cell_contexts; template class DB_PUBLIC local_processor_cell_contexts; template class DB_PUBLIC local_processor_cell_contexts; template class DB_PUBLIC local_processor_cell_contexts; @@ -691,6 +695,7 @@ shape_interactions::intruder_shape (unsigned int id) const } } +// explicit instantiations template class DB_PUBLIC shape_interactions; template class DB_PUBLIC shape_interactions; template class DB_PUBLIC shape_interactions; @@ -1048,6 +1053,7 @@ local_processor_context_computation_task::perform () mp_proc->compute_contexts (*mp_contexts, mp_parent_context, mp_subject_parent, mp_subject_cell, m_subject_cell_inst, mp_intruder_cell, m_intruders, m_dist); } +// explicit instantiations 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; @@ -1056,6 +1062,7 @@ 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; template class DB_PUBLIC local_processor_context_computation_task; template class DB_PUBLIC local_processor_context_computation_task; @@ -1100,6 +1107,7 @@ local_processor_result_computation_task::perform () } } +// explicit instantiations 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; @@ -1108,6 +1116,7 @@ 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; template class DB_PUBLIC local_processor_result_computation_task; template class DB_PUBLIC local_processor_result_computation_task; @@ -2048,6 +2057,7 @@ local_processor::run_flat (const generic_shape_iterator &subject } } +// explicit instantiations template class DB_PUBLIC local_processor; template class DB_PUBLIC local_processor; template class DB_PUBLIC local_processor; @@ -2059,6 +2069,7 @@ 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; template class DB_PUBLIC local_processor; template class DB_PUBLIC local_processor; template class DB_PUBLIC local_processor; diff --git a/src/db/db/dbOriginalLayerEdgePairs.cc b/src/db/db/dbOriginalLayerEdgePairs.cc index a6907a0af..1b2d09a98 100644 --- a/src/db/db/dbOriginalLayerEdgePairs.cc +++ b/src/db/db/dbOriginalLayerEdgePairs.cc @@ -86,6 +86,7 @@ namespace m_rec_iter.set_region (m_iter_trans.inverted () * region); } m_rec_iter.set_overlapping (overlapping); + set (); } virtual db::Box bbox () const diff --git a/src/db/db/dbOriginalLayerEdges.cc b/src/db/db/dbOriginalLayerEdges.cc index 8e66b5583..257f99206 100644 --- a/src/db/db/dbOriginalLayerEdges.cc +++ b/src/db/db/dbOriginalLayerEdges.cc @@ -87,6 +87,7 @@ namespace m_rec_iter.set_region (m_iter_trans.inverted () * region); } m_rec_iter.set_overlapping (overlapping); + set (); } virtual db::Box bbox () const diff --git a/src/db/db/dbOriginalLayerRegion.cc b/src/db/db/dbOriginalLayerRegion.cc index 301694b1c..19f342df8 100644 --- a/src/db/db/dbOriginalLayerRegion.cc +++ b/src/db/db/dbOriginalLayerRegion.cc @@ -90,6 +90,7 @@ namespace m_rec_iter.set_region (m_iter_trans.inverted () * region); } m_rec_iter.set_overlapping (overlapping); + set (); } virtual db::Box bbox () const diff --git a/src/db/db/dbOriginalLayerTexts.cc b/src/db/db/dbOriginalLayerTexts.cc index 3ad474650..69a4aa57c 100644 --- a/src/db/db/dbOriginalLayerTexts.cc +++ b/src/db/db/dbOriginalLayerTexts.cc @@ -86,6 +86,7 @@ namespace m_rec_iter.set_region (m_iter_trans.inverted () * region); } m_rec_iter.set_overlapping (overlapping); + set (); } virtual db::Box bbox () const diff --git a/src/db/db/dbRegionLocalOperations.cc b/src/db/db/dbRegionLocalOperations.cc index 004c63bfb..35322f17b 100644 --- a/src/db/db/dbRegionLocalOperations.cc +++ b/src/db/db/dbRegionLocalOperations.cc @@ -116,91 +116,96 @@ private: // --------------------------------------------------------------------------------------------------------------- -CheckLocalOperation::CheckLocalOperation (const EdgeRelationFilter &check, bool different_polygons, bool has_other, bool shielded) +template +check_local_operation::check_local_operation (const EdgeRelationFilter &check, bool different_polygons, bool has_other, bool shielded) : m_check (check), m_different_polygons (different_polygons), m_has_other (has_other), m_shielded (shielded) { // .. nothing yet .. } +template void -CheckLocalOperation::compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const +check_local_operation::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 (); + std::unordered_set &result = results.front (); - edge2edge_check > edge_check (m_check, result, m_different_polygons, m_has_other, m_shielded); - poly2poly_check > poly_check (edge_check); + edge2edge_check > edge_check (m_check, result, m_different_polygons, m_has_other, m_shielded); + poly2poly_check > poly_check (edge_check); - std::list heap; - db::box_scanner scanner; + std::list heap; + db::box_scanner scanner; + std::unordered_set polygons; if (m_has_other) { - std::set others; - for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { - for (shape_interactions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { - others.insert (interactions.intruder_shape (*j).second); - } - } - - size_t n = 0; - 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.insert (& heap.back (), n); - n += 2; - } - - n = 1; - for (std::set::const_iterator o = others.begin (); o != others.end (); ++o) { - heap.push_back (o->obj ().transformed (o->trans ())); - scanner.insert (& heap.back (), n); - n += 2; - } - - } else { - - std::set polygons; - for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { - polygons.insert (interactions.subject_shape (i->first)); - 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) { polygons.insert (interactions.intruder_shape (*j).second); } } size_t n = 0; - for (std::set::const_iterator o = polygons.begin (); o != polygons.end (); ++o) { - heap.push_back (o->obj ().transformed (o->trans ())); - scanner.insert (& heap.back (), n); + for (typename shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { + const TS &subject = interactions.subject_shape (i->first); + scanner.insert (push_polygon_to_heap (layout, subject, heap), n); + n += 2; + } + + n = 1; + for (typename std::unordered_set::const_iterator o = polygons.begin (); o != polygons.end (); ++o) { + scanner.insert (push_polygon_to_heap (layout, *o, heap), n); + n += 2; + } + + } else { + + for (typename shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { + polygons.insert (interactions.subject_shape (i->first)); + for (typename shape_interactions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { + polygons.insert (interactions.intruder_shape (*j).second); + } + } + + size_t n = 0; + for (typename std::unordered_set::const_iterator o = polygons.begin (); o != polygons.end (); ++o) { + scanner.insert (push_polygon_to_heap (layout, *o, heap), n); n += 2; } } do { - scanner.process (poly_check, m_check.distance (), db::box_convert ()); + scanner.process (poly_check, m_check.distance (), db::box_convert ()); } while (edge_check.prepare_next_pass ()); } +template db::Coord -CheckLocalOperation::dist () const +check_local_operation::dist () const { // TODO: will the distance be sufficient? Or should we take somewhat more? return m_check.distance (); } -CheckLocalOperation::on_empty_intruder_mode -CheckLocalOperation::on_empty_intruder_hint () const +template +typename db::local_operation::on_empty_intruder_mode +check_local_operation::on_empty_intruder_hint () const { - return m_different_polygons ? Drop : Ignore; + return m_different_polygons ? db::local_operation::Drop : db::local_operation::Ignore; } +template std::string -CheckLocalOperation::description () const +check_local_operation::description () const { return tl::to_string (tr ("Generic DRC check")); } +// explicit instantiations +template class check_local_operation; +template class check_local_operation; + // --------------------------------------------------------------------------------------------------------------- template diff --git a/src/db/db/dbRegionLocalOperations.h b/src/db/db/dbRegionLocalOperations.h index 0fa0aa865..eed1a9a04 100644 --- a/src/db/db/dbRegionLocalOperations.h +++ b/src/db/db/dbRegionLocalOperations.h @@ -31,16 +31,17 @@ namespace db { -class CheckLocalOperation - : public local_operation +template +class check_local_operation + : public local_operation { public: - CheckLocalOperation (const EdgeRelationFilter &check, bool different_polygons, bool has_other, bool shielded); + check_local_operation (const EdgeRelationFilter &check, bool different_polygons, bool has_other, bool shielded); - virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) 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 db::Coord dist () const; - virtual on_empty_intruder_mode on_empty_intruder_hint () const; + virtual typename local_operation::on_empty_intruder_mode on_empty_intruder_hint () const; virtual std::string description () const; private: @@ -50,6 +51,8 @@ private: bool m_shielded; }; +typedef check_local_operation CheckLocalOperation; + template class interacting_local_operation : public local_operation diff --git a/src/db/db/dbRegionUtils.cc b/src/db/db/dbRegionUtils.cc index 861051766..e68f28139 100644 --- a/src/db/db/dbRegionUtils.cc +++ b/src/db/db/dbRegionUtils.cc @@ -282,71 +282,86 @@ Edge2EdgeCheckBase::distance () const // ------------------------------------------------------------------------------------- // Poly2PolyCheckBase implementation -Poly2PolyCheckBase::Poly2PolyCheckBase (Edge2EdgeCheckBase &output) +template +poly2poly_check_base::poly2poly_check_base (Edge2EdgeCheckBase &output) : mp_output (& output) { // .. nothing yet .. } +template void -Poly2PolyCheckBase::finish (const db::Polygon *o, size_t p) +poly2poly_check_base::finish (const PolygonType *o, size_t p) { enter (*o, p); } +static size_t vertices (const db::Polygon &p) +{ + return p.vertices (); +} + +static size_t vertices (const db::PolygonRef &p) +{ + return p.obj ().vertices (); +} + +template void -Poly2PolyCheckBase::enter (const db::Polygon &o, size_t p) +poly2poly_check_base::enter (const PolygonType &o, size_t p) { if (! mp_output->requires_different_layers () && ! mp_output->different_polygons ()) { // finally we check the polygons vs. itself for checks involving intra-polygon interactions m_scanner.clear (); - m_scanner.reserve (o.vertices ()); + m_scanner.reserve (vertices (o)); m_edges.clear (); - m_edges.reserve (o.vertices ()); + m_edges.reserve (vertices (o)); - for (db::Polygon::polygon_edge_iterator e = o.begin_edge (); ! e.at_end (); ++e) { + for (typename PolygonType::polygon_edge_iterator e = o.begin_edge (); ! e.at_end (); ++e) { m_edges.push_back (*e); m_scanner.insert (& m_edges.back (), p); } - tl_assert (m_edges.size () == o.vertices ()); + tl_assert (m_edges.size () == vertices (o)); m_scanner.process (*mp_output, mp_output->distance (), db::box_convert ()); } } +template void -Poly2PolyCheckBase::add (const db::Polygon *o1, size_t p1, const db::Polygon *o2, size_t p2) +poly2poly_check_base::add (const PolygonType *o1, size_t p1, const PolygonType *o2, size_t p2) { enter (*o1, p1, *o2, p2); } +template void -Poly2PolyCheckBase::enter (const db::Polygon &o1, size_t p1, const db::Polygon &o2, size_t p2) +poly2poly_check_base::enter (const PolygonType &o1, size_t p1, const PolygonType &o2, size_t p2) { if ((! mp_output->different_polygons () || p1 != p2) && (! mp_output->requires_different_layers () || ((p1 ^ p2) & 1) != 0)) { m_scanner.clear (); - m_scanner.reserve (o1.vertices () + o2.vertices ()); + m_scanner.reserve (vertices (o1) + vertices (o2)); m_edges.clear (); - m_edges.reserve (o1.vertices () + o2.vertices ()); + m_edges.reserve (vertices (o1) + vertices (o2)); - for (db::Polygon::polygon_edge_iterator e = o1.begin_edge (); ! e.at_end (); ++e) { + for (typename PolygonType::polygon_edge_iterator e = o1.begin_edge (); ! e.at_end (); ++e) { m_edges.push_back (*e); m_scanner.insert (& m_edges.back (), p1); } - for (db::Polygon::polygon_edge_iterator e = o2.begin_edge (); ! e.at_end (); ++e) { + for (typename PolygonType::polygon_edge_iterator e = o2.begin_edge (); ! e.at_end (); ++e) { m_edges.push_back (*e); m_scanner.insert (& m_edges.back (), p2); } - tl_assert (m_edges.size () == o1.vertices () + o2.vertices ()); + tl_assert (m_edges.size () == vertices (o1) + vertices (o2)); // temporarily disable intra-polygon check in that step .. we do that later in finish() // if required (#650). @@ -360,6 +375,10 @@ Poly2PolyCheckBase::enter (const db::Polygon &o1, size_t p1, const db::Polygon & } } +// explicit instantiations +template class poly2poly_check_base; +template class poly2poly_check_base; + // ------------------------------------------------------------------------------------- // RegionToEdgeInteractionFilterBase implementation diff --git a/src/db/db/dbRegionUtils.h b/src/db/db/dbRegionUtils.h index 3496a8d47..abda1c309 100644 --- a/src/db/db/dbRegionUtils.h +++ b/src/db/db/dbRegionUtils.h @@ -556,16 +556,17 @@ private: /** * @brief A helper class for the DRC functionality which acts as an edge pair receiver */ -class DB_PUBLIC Poly2PolyCheckBase - : public db::box_scanner_receiver +template +class DB_PUBLIC poly2poly_check_base + : public db::box_scanner_receiver { public: - Poly2PolyCheckBase (Edge2EdgeCheckBase &output); + poly2poly_check_base (Edge2EdgeCheckBase &output); - void finish (const db::Polygon *o, size_t p); - void enter (const db::Polygon &o, size_t p); - void add (const db::Polygon *o1, size_t p1, const db::Polygon *o2, size_t p2); - void enter (const db::Polygon &o1, size_t p1, const db::Polygon &o2, size_t p2); + void finish (const PolygonType *o, size_t p); + void enter (const PolygonType&o, size_t p); + void add (const PolygonType *o1, size_t p1, const PolygonType *o2, size_t p2); + void enter (const PolygonType &o1, size_t p1, const PolygonType &o2, size_t p2); private: db::Edge2EdgeCheckBase *mp_output; @@ -576,13 +577,13 @@ private: /** * @brief A helper class for the DRC functionality which acts as an edge pair receiver */ -template +template class DB_PUBLIC_TEMPLATE poly2poly_check - : public Poly2PolyCheckBase + : public poly2poly_check_base { public: poly2poly_check (edge2edge_check &output) - : Poly2PolyCheckBase (output) + : poly2poly_check_base (output) { // .. nothing yet .. }