diff --git a/src/db/db/dbAsIfFlatEdgePairs.cc b/src/db/db/dbAsIfFlatEdgePairs.cc index 1d6c8a53c..c9319c9f1 100644 --- a/src/db/db/dbAsIfFlatEdgePairs.cc +++ b/src/db/db/dbAsIfFlatEdgePairs.cc @@ -159,6 +159,28 @@ AsIfFlatEdgePairs::processed_to_polygons (const EdgePairToPolygonProcessorBase & return region.release (); } +EdgesDelegate * +AsIfFlatEdgePairs::processed_to_edges (const EdgePairToEdgeProcessorBase &filter) const +{ + std::auto_ptr edges (new FlatEdges ()); + + if (filter.result_must_not_be_merged ()) { + edges->set_merged_semantics (false); + } + + std::vector res_edges; + + for (EdgePairsIterator e (begin ()); ! e.at_end (); ++e) { + res_edges.clear (); + filter.process (*e, res_edges); + for (std::vector::const_iterator pr = res_edges.begin (); pr != res_edges.end (); ++pr) { + edges->insert (*pr); + } + } + + return edges.release (); +} + EdgePairsDelegate * AsIfFlatEdgePairs::filtered (const EdgePairFilterBase &filter) const { diff --git a/src/db/db/dbAsIfFlatEdgePairs.h b/src/db/db/dbAsIfFlatEdgePairs.h index 35e3cba12..9f09c9392 100644 --- a/src/db/db/dbAsIfFlatEdgePairs.h +++ b/src/db/db/dbAsIfFlatEdgePairs.h @@ -54,6 +54,7 @@ public: virtual EdgePairsDelegate *filtered (const EdgePairFilterBase &) const; virtual RegionDelegate *processed_to_polygons (const EdgePairToPolygonProcessorBase &filter) const; + virtual EdgesDelegate *processed_to_edges (const EdgePairToEdgeProcessorBase &filter) const; virtual EdgePairsDelegate *add_in_place (const EdgePairs &other) { diff --git a/src/db/db/dbCompoundOperation.cc b/src/db/db/dbCompoundOperation.cc index 0af279624..e9c79a2cc 100644 --- a/src/db/db/dbCompoundOperation.cc +++ b/src/db/db/dbCompoundOperation.cc @@ -981,6 +981,74 @@ CompoundRegionFilterOperationNode::is_selected (const db::PolygonRef &p) const // --------------------------------------------------------------------------------------------- +CompoundRegionEdgeFilterOperationNode::CompoundRegionEdgeFilterOperationNode (EdgeFilterBase *filter, CompoundRegionOperationNode *input, bool owns_filter) + : CompoundRegionMultiInputOperationNode (input), mp_filter (filter), m_owns_filter (owns_filter) +{ + set_description ("filter"); +} + +CompoundRegionEdgeFilterOperationNode::~CompoundRegionEdgeFilterOperationNode () +{ + if (m_owns_filter) { + delete mp_filter; + } + mp_filter = 0; +} + +void +CompoundRegionEdgeFilterOperationNode::do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const +{ + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); +} + +void +CompoundRegionEdgeFilterOperationNode::do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const +{ + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); +} + +bool +CompoundRegionEdgeFilterOperationNode::is_selected (const db::Edge &p) const +{ + return mp_filter->selected (p); +} + +// --------------------------------------------------------------------------------------------- + +CompoundRegionEdgePairFilterOperationNode::CompoundRegionEdgePairFilterOperationNode (EdgePairFilterBase *filter, CompoundRegionOperationNode *input, bool owns_filter) + : CompoundRegionMultiInputOperationNode (input), mp_filter (filter), m_owns_filter (owns_filter) +{ + set_description ("filter"); +} + +CompoundRegionEdgePairFilterOperationNode::~CompoundRegionEdgePairFilterOperationNode () +{ + if (m_owns_filter) { + delete mp_filter; + } + mp_filter = 0; +} + +void +CompoundRegionEdgePairFilterOperationNode::do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const +{ + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); +} + +void +CompoundRegionEdgePairFilterOperationNode::do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const +{ + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); +} + +bool +CompoundRegionEdgePairFilterOperationNode::is_selected (const db::EdgePair &p) const +{ + return mp_filter->selected (p); +} + +// --------------------------------------------------------------------------------------------- + CompoundRegionProcessingOperationNode::CompoundRegionProcessingOperationNode (PolygonProcessorBase *proc, CompoundRegionOperationNode *input, bool owns_proc) : CompoundRegionMultiInputOperationNode (input), mp_proc (proc), m_owns_proc (owns_proc) { @@ -1010,7 +1078,7 @@ CompoundRegionProcessingOperationNode::do_compute_local (db::Layout *layout, con void CompoundRegionProcessingOperationNode::processed (db::Layout *, const db::Polygon &p, std::vector &res) const { - return mp_proc->process (p, res); + mp_proc->process (p, res); } void @@ -1054,7 +1122,7 @@ CompoundRegionToEdgeProcessingOperationNode::do_compute_local (db::Layout *layou void CompoundRegionToEdgeProcessingOperationNode::processed (db::Layout *, const db::Polygon &p, std::vector &res) const { - return mp_proc->process (p, res); + mp_proc->process (p, res); } void @@ -1065,6 +1133,51 @@ CompoundRegionToEdgeProcessingOperationNode::processed (db::Layout *, const db:: // --------------------------------------------------------------------------------------------- +CompoundRegionEdgeToPolygonProcessingOperationNode::CompoundRegionEdgeToPolygonProcessingOperationNode (EdgeToPolygonProcessorBase *proc, CompoundRegionOperationNode *input, bool owns_proc) + : CompoundRegionMultiInputOperationNode (input), mp_proc (proc), m_owns_proc (owns_proc) +{ + set_description ("processor"); +} + +CompoundRegionEdgeToPolygonProcessingOperationNode::~CompoundRegionEdgeToPolygonProcessingOperationNode () +{ + if (m_owns_proc) { + delete mp_proc; + mp_proc = 0; + } +} + +void +CompoundRegionEdgeToPolygonProcessingOperationNode::do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const +{ + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); +} + +void +CompoundRegionEdgeToPolygonProcessingOperationNode::do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const +{ + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); +} + +void +CompoundRegionEdgeToPolygonProcessingOperationNode::processed (db::Layout *, const db::Edge &e, std::vector &res) const +{ + mp_proc->process (e, res); +} + +void +CompoundRegionEdgeToPolygonProcessingOperationNode::processed (db::Layout *layout, const db::Edge &e, std::vector &res) const +{ + std::vector polygons; + mp_proc->process (e, polygons); + + for (std::vector::const_iterator p = polygons.begin (); p != polygons.end (); ++p) { + res.push_back (db::PolygonRef (*p, layout->shape_repository ())); + } +} + +// --------------------------------------------------------------------------------------------- + CompoundRegionToEdgePairProcessingOperationNode::CompoundRegionToEdgePairProcessingOperationNode (PolygonToEdgePairProcessorBase *proc, CompoundRegionOperationNode *input, bool owns_proc) : CompoundRegionMultiInputOperationNode (input), mp_proc (proc), m_owns_proc (owns_proc) { @@ -1094,7 +1207,7 @@ CompoundRegionToEdgePairProcessingOperationNode::do_compute_local (db::Layout *l void CompoundRegionToEdgePairProcessingOperationNode::processed (db::Layout *, const db::Polygon &p, std::vector &res) const { - return mp_proc->process (p, res); + mp_proc->process (p, res); } void @@ -1105,6 +1218,79 @@ CompoundRegionToEdgePairProcessingOperationNode::processed (db::Layout *, const // --------------------------------------------------------------------------------------------- +CompoundRegionEdgePairToPolygonProcessingOperationNode::CompoundRegionEdgePairToPolygonProcessingOperationNode (EdgePairToPolygonProcessorBase *proc, CompoundRegionOperationNode *input, bool owns_proc) + : CompoundRegionMultiInputOperationNode (input), mp_proc (proc), m_owns_proc (owns_proc) +{ + set_description ("processor"); +} + +CompoundRegionEdgePairToPolygonProcessingOperationNode::~CompoundRegionEdgePairToPolygonProcessingOperationNode () +{ + if (m_owns_proc) { + delete mp_proc; + mp_proc = 0; + } +} + +void +CompoundRegionEdgePairToPolygonProcessingOperationNode::do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const +{ + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); +} + +void +CompoundRegionEdgePairToPolygonProcessingOperationNode::do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const +{ + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); +} + +void +CompoundRegionEdgePairToPolygonProcessingOperationNode::processed (db::Layout *, const db::EdgePair &e, std::vector &res) const +{ + mp_proc->process (e, res); +} + +void +CompoundRegionEdgePairToPolygonProcessingOperationNode::processed (db::Layout *layout, const db::EdgePair &e, std::vector &res) const +{ + std::vector polygons; + mp_proc->process (e, polygons); + + for (std::vector::const_iterator p = polygons.begin (); p != polygons.end (); ++p) { + res.push_back (db::PolygonRef (*p, layout->shape_repository ())); + } +} + +// --------------------------------------------------------------------------------------------- + +CompoundRegionEdgePairToEdgeProcessingOperationNode::CompoundRegionEdgePairToEdgeProcessingOperationNode (EdgePairToEdgeProcessorBase *proc, CompoundRegionOperationNode *input, bool owns_proc) + : CompoundRegionMultiInputOperationNode (input), mp_proc (proc), m_owns_proc (owns_proc) +{ + set_description ("processor"); +} + +CompoundRegionEdgePairToEdgeProcessingOperationNode::~CompoundRegionEdgePairToEdgeProcessingOperationNode () +{ + if (m_owns_proc) { + delete mp_proc; + mp_proc = 0; + } +} + +void +CompoundRegionEdgePairToEdgeProcessingOperationNode::do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const +{ + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); +} + +void +CompoundRegionEdgePairToEdgeProcessingOperationNode::do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const +{ + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); +} + +// --------------------------------------------------------------------------------------------- + CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegionOperationNode *input, db::edge_relation_type rel, bool different_polygons, db::Coord d, const db::RegionCheckOptions &options) : CompoundRegionMultiInputOperationNode (input), m_check (rel, d, options.metrics), m_different_polygons (different_polygons), m_options (options) { diff --git a/src/db/db/dbCompoundOperation.h b/src/db/db/dbCompoundOperation.h index bf2b67505..6048cdeb8 100644 --- a/src/db/db/dbCompoundOperation.h +++ b/src/db/db/dbCompoundOperation.h @@ -529,6 +529,7 @@ public: virtual const db::TransformationReducer *vars () const { return mp_vars; } virtual bool wants_variants () const { return m_wants_variants; } virtual db::Coord dist () const { return m_op->dist (); } + virtual bool wants_merged () const { return true; } virtual std::vector inputs () const { @@ -755,6 +756,7 @@ public: virtual const TransformationReducer *vars () const { return mp_filter->vars (); } virtual bool wants_variants () const { return mp_filter->wants_variants (); } + virtual bool wants_merged () const { return true; } private: PolygonFilterBase *mp_filter; @@ -779,6 +781,83 @@ private: } }; +class DB_PUBLIC CompoundRegionEdgeFilterOperationNode + : public CompoundRegionMultiInputOperationNode +{ +public: + CompoundRegionEdgeFilterOperationNode (EdgeFilterBase *filter, CompoundRegionOperationNode *input, bool owns_filter = false); + ~CompoundRegionEdgeFilterOperationNode (); + + // specifies the result type + virtual ResultType result_type () const { return Edges; } + + virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; + virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; + + virtual const TransformationReducer *vars () const { return mp_filter->vars (); } + virtual bool wants_variants () const { return mp_filter->wants_variants (); } + virtual bool wants_merged () const { return true; } + +private: + EdgeFilterBase *mp_filter; + bool m_owns_filter; + + bool is_selected (const db::Edge &p) const; + + template + void implement_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const + { + std::vector > one; + one.push_back (std::unordered_set ()); + + child (0)->compute_local (layout, interactions, one, max_vertex_count, area_ratio); + + for (typename std::unordered_set::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) { + if (is_selected (*p)) { + results.front ().insert (*p); + } + } + } +}; + +class DB_PUBLIC CompoundRegionEdgePairFilterOperationNode + : public CompoundRegionMultiInputOperationNode +{ +public: + CompoundRegionEdgePairFilterOperationNode (EdgePairFilterBase *filter, CompoundRegionOperationNode *input, bool owns_filter = false); + ~CompoundRegionEdgePairFilterOperationNode (); + + // specifies the result type + virtual ResultType result_type () const { return EdgePairs; } + + virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; + virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; + + virtual const TransformationReducer *vars () const { return mp_filter->vars (); } + virtual bool wants_variants () const { return mp_filter->wants_variants (); } + virtual bool wants_merged () const { return true; } + +private: + EdgePairFilterBase *mp_filter; + bool m_owns_filter; + + bool is_selected (const db::EdgePair &p) const; + + template + void implement_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const + { + std::vector > one; + one.push_back (std::unordered_set ()); + + child (0)->compute_local (layout, interactions, one, max_vertex_count, area_ratio); + + for (typename std::unordered_set::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) { + if (is_selected (*p)) { + results.front ().insert (*p); + } + } + } +}; class DB_PUBLIC CompoundRegionProcessingOperationNode : public CompoundRegionMultiInputOperationNode @@ -792,6 +871,7 @@ public: virtual const TransformationReducer *vars () const { return mp_proc->vars (); } virtual bool wants_variants () const { return mp_proc->wants_variants (); } + virtual bool wants_merged () const { return true; } virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; @@ -841,6 +921,123 @@ private: CompoundTransformationReducer m_vars; }; +class DB_PUBLIC CompoundRegionEdgeToPolygonProcessingOperationNode + : public CompoundRegionMultiInputOperationNode +{ +public: + CompoundRegionEdgeToPolygonProcessingOperationNode (EdgeToPolygonProcessorBase *proc, CompoundRegionOperationNode *input, bool owns_proc = false); + ~CompoundRegionEdgeToPolygonProcessingOperationNode (); + + // specifies the result type + virtual ResultType result_type () const { return Region; } + + virtual const TransformationReducer *vars () const { return mp_proc->vars (); } + virtual bool wants_variants () const { return mp_proc->wants_variants (); } + virtual bool wants_merged () const { return true; } + + virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; + virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; + +private: + EdgeToPolygonProcessorBase *mp_proc; + bool m_owns_proc; + + void processed (db::Layout *, const db::Edge &p, std::vector &res) const; + void processed (db::Layout *layout, const db::Edge &p, std::vector &res) const; + + template + void implement_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const + { + std::vector > one; + one.push_back (std::unordered_set ()); + + child (0)->compute_local (layout, interactions, one, max_vertex_count, area_ratio); + + for (typename std::unordered_set::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) { + std::vector res; + processed (layout, *p, res); + results.front ().insert (res.begin (), res.end ()); + } + } +}; + +class DB_PUBLIC CompoundRegionEdgePairToPolygonProcessingOperationNode + : public CompoundRegionMultiInputOperationNode +{ +public: + CompoundRegionEdgePairToPolygonProcessingOperationNode (EdgePairToPolygonProcessorBase *proc, CompoundRegionOperationNode *input, bool owns_proc = false); + ~CompoundRegionEdgePairToPolygonProcessingOperationNode (); + + // specifies the result type + virtual ResultType result_type () const { return Region; } + + virtual const TransformationReducer *vars () const { return mp_proc->vars (); } + virtual bool wants_variants () const { return mp_proc->wants_variants (); } + virtual bool wants_merged () const { return true; } + + virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; + virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; + +private: + EdgePairToPolygonProcessorBase *mp_proc; + bool m_owns_proc; + + void processed (db::Layout *, const db::EdgePair &p, std::vector &res) const; + void processed (db::Layout *layout, const db::EdgePair &p, std::vector &res) const; + + template + void implement_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const + { + std::vector > one; + one.push_back (std::unordered_set ()); + + child (0)->compute_local (layout, interactions, one, max_vertex_count, area_ratio); + + for (typename std::unordered_set::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) { + std::vector res; + processed (layout, *p, res); + results.front ().insert (res.begin (), res.end ()); + } + } +}; + +class DB_PUBLIC CompoundRegionEdgePairToEdgeProcessingOperationNode + : public CompoundRegionMultiInputOperationNode +{ +public: + CompoundRegionEdgePairToEdgeProcessingOperationNode (EdgePairToEdgeProcessorBase *proc, CompoundRegionOperationNode *input, bool owns_proc = false); + ~CompoundRegionEdgePairToEdgeProcessingOperationNode (); + + // specifies the result type + virtual ResultType result_type () const { return Edges; } + + virtual const TransformationReducer *vars () const { return mp_proc->vars (); } + virtual bool wants_variants () const { return mp_proc->wants_variants (); } + virtual bool wants_merged () const { return true; } + + virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; + virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; + +private: + EdgePairToEdgeProcessorBase *mp_proc; + bool m_owns_proc; + + template + void implement_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const + { + std::vector > one; + one.push_back (std::unordered_set ()); + + child (0)->compute_local (layout, interactions, one, max_vertex_count, area_ratio); + + for (typename std::unordered_set::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) { + std::vector res; + mp_proc->process (*p, res); + results.front ().insert (res.begin (), res.end ()); + } + } +}; + class DB_PUBLIC CompoundRegionToEdgeProcessingOperationNode : public CompoundRegionMultiInputOperationNode { @@ -853,6 +1050,7 @@ public: virtual const TransformationReducer *vars () const { return mp_proc->vars (); } virtual bool wants_variants () const { return mp_proc->wants_variants (); } + virtual bool wants_merged () const { return true; } virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; @@ -902,6 +1100,7 @@ public: virtual const TransformationReducer *vars () const { return mp_proc->vars (); } virtual bool wants_variants () const { return mp_proc->wants_variants (); } + virtual bool wants_merged () const { return true; } virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; diff --git a/src/db/db/dbDeepEdgePairs.cc b/src/db/db/dbDeepEdgePairs.cc index 7c33e6e91..9c739e84c 100644 --- a/src/db/db/dbDeepEdgePairs.cc +++ b/src/db/db/dbDeepEdgePairs.cc @@ -284,6 +284,12 @@ DeepEdgePairs::processed_to_polygons (const EdgePairToPolygonProcessorBase &filt return shape_collection_processed_impl (deep_layer (), filter); } +EdgesDelegate * +DeepEdgePairs::processed_to_edges (const EdgePairToEdgeProcessorBase &filter) const +{ + return shape_collection_processed_impl (deep_layer (), filter); +} + RegionDelegate *DeepEdgePairs::polygons (db::Coord e) const { db::DeepLayer new_layer = deep_layer ().derived (); diff --git a/src/db/db/dbDeepEdgePairs.h b/src/db/db/dbDeepEdgePairs.h index 2f4ca096d..dbb53a239 100644 --- a/src/db/db/dbDeepEdgePairs.h +++ b/src/db/db/dbDeepEdgePairs.h @@ -65,6 +65,7 @@ public: virtual EdgePairsDelegate *filter_in_place (const EdgePairFilterBase &filter); virtual EdgePairsDelegate *filtered (const EdgePairFilterBase &) const; virtual RegionDelegate *processed_to_polygons (const EdgePairToPolygonProcessorBase &filter) const; + virtual EdgesDelegate *processed_to_edges (const EdgePairToEdgeProcessorBase &filter) const; virtual EdgePairsDelegate *add_in_place (const EdgePairs &other); virtual EdgePairsDelegate *add (const EdgePairs &other) const; diff --git a/src/db/db/dbEdgePairs.cc b/src/db/db/dbEdgePairs.cc index 36cd42b9d..6a6c2f27d 100644 --- a/src/db/db/dbEdgePairs.cc +++ b/src/db/db/dbEdgePairs.cc @@ -148,6 +148,11 @@ void EdgePairs::processed (Region &output, const EdgePairToPolygonProcessorBase output = Region (mp_delegate->processed_to_polygons (filter)); } +void EdgePairs::processed (Edges &output, const EdgePairToEdgeProcessorBase &filter) const +{ + output = Edges (mp_delegate->processed_to_edges (filter)); +} + void EdgePairs::polygons (Region &output, db::Coord e) const { output.set_delegate (mp_delegate->polygons (e)); diff --git a/src/db/db/dbEdgePairs.h b/src/db/db/dbEdgePairs.h index 07265b0cb..ca6174bad 100644 --- a/src/db/db/dbEdgePairs.h +++ b/src/db/db/dbEdgePairs.h @@ -119,6 +119,7 @@ public: virtual bool selected (const db::EdgePair &edge) const = 0; virtual const TransformationReducer *vars () const = 0; + virtual bool wants_variants () const = 0; }; /** @@ -386,6 +387,14 @@ public: */ void processed (Region &output, const EdgePairToPolygonProcessorBase &filter) const; + /** + * @brief Processes the edge pairs into edges + * + * This method will run the processor over all edge pairs and return a edge collection + * with the outputs of the processor. + */ + void processed (Edges &output, const EdgePairToEdgeProcessorBase &filter) const; + /** * @brief Transforms the edge pair set */ diff --git a/src/db/db/dbEdgePairsDelegate.h b/src/db/db/dbEdgePairsDelegate.h index 41bfd73ca..e9f2fbb63 100644 --- a/src/db/db/dbEdgePairsDelegate.h +++ b/src/db/db/dbEdgePairsDelegate.h @@ -40,6 +40,71 @@ class EdgesDelegate; class Layout; typedef shape_collection_processor EdgePairToPolygonProcessorBase; +typedef shape_collection_processor EdgePairToEdgeProcessorBase; + +class DB_PUBLIC +EdgePairToPolygonProcessor + : public EdgePairToPolygonProcessorBase +{ +public: + EdgePairToPolygonProcessor (db::Coord e) + : m_e (e) + { } + + void process(const EdgePair &ep, std::vector &res) const + { + db::Polygon poly = ep.normalized ().to_polygon (m_e); + if (poly.vertices () >= 3) { + res.push_back (poly); + } + } + +private: + db::Coord m_e; +}; + +class DB_PUBLIC +EdgePairToEdgesProcessor + : public EdgePairToEdgeProcessorBase +{ +public: + EdgePairToEdgesProcessor () + { } + + void process(const EdgePair &ep, std::vector &res) const + { + res.push_back (ep.first ()); + res.push_back (ep.second ()); + } +}; + +class DB_PUBLIC +EdgePairToFirstEdgesProcessor + : public EdgePairToEdgeProcessorBase +{ +public: + EdgePairToFirstEdgesProcessor () + { } + + void process(const EdgePair &ep, std::vector &res) const + { + res.push_back (ep.first ()); + } +}; + +class DB_PUBLIC +EdgePairToSecondEdgesProcessor + : public EdgePairToEdgeProcessorBase +{ +public: + EdgePairToSecondEdgesProcessor () + { } + + void process(const EdgePair &ep, std::vector &res) const + { + res.push_back (ep.second ()); + } +}; /** * @brief The edge pair set iterator delegate @@ -91,6 +156,7 @@ public: virtual EdgePairsDelegate *filter_in_place (const EdgePairFilterBase &filter) = 0; virtual EdgePairsDelegate *filtered (const EdgePairFilterBase &filter) const = 0; virtual RegionDelegate *processed_to_polygons (const EdgePairToPolygonProcessorBase &filter) const = 0; + virtual EdgesDelegate *processed_to_edges (const EdgePairToEdgeProcessorBase &filter) const = 0; virtual RegionDelegate *polygons (db::Coord e) const = 0; virtual EdgesDelegate *edges () const = 0; diff --git a/src/db/db/dbEmptyEdgePairs.cc b/src/db/db/dbEmptyEdgePairs.cc index 9ea8afb3c..641822b4a 100644 --- a/src/db/db/dbEmptyEdgePairs.cc +++ b/src/db/db/dbEmptyEdgePairs.cc @@ -59,6 +59,12 @@ EmptyEdgePairs::processed_to_polygons (const EdgePairToPolygonProcessorBase &) c return new EmptyRegion (); } +EdgesDelegate * +EmptyEdgePairs::processed_to_edges (const EdgePairToEdgeProcessorBase &) const +{ + return new EmptyEdges (); +} + EdgesDelegate * EmptyEdgePairs::edges () const { diff --git a/src/db/db/dbEmptyEdgePairs.h b/src/db/db/dbEmptyEdgePairs.h index 85dba4e33..0056a60da 100644 --- a/src/db/db/dbEmptyEdgePairs.h +++ b/src/db/db/dbEmptyEdgePairs.h @@ -57,6 +57,7 @@ public: virtual EdgePairsDelegate *filter_in_place (const EdgePairFilterBase &) { return this; } virtual EdgePairsDelegate *filtered (const EdgePairFilterBase &) const { return new EmptyEdgePairs (); } virtual RegionDelegate *processed_to_polygons (const EdgePairToPolygonProcessorBase &filter) const; + virtual EdgesDelegate *processed_to_edges (const EdgePairToEdgeProcessorBase &filter) const; virtual RegionDelegate *polygons (db::Coord e) const; virtual EdgesDelegate *edges () const; diff --git a/src/db/db/dbShapeCollectionUtils.h b/src/db/db/dbShapeCollectionUtils.h index c176bb30b..ad3d04cc9 100644 --- a/src/db/db/dbShapeCollectionUtils.h +++ b/src/db/db/dbShapeCollectionUtils.h @@ -69,30 +69,30 @@ public: * @brief Returns the transformation reducer for building cell variants * This method may return 0. In this case, not cell variants are built. */ - virtual const TransformationReducer *vars () const = 0; + virtual const TransformationReducer *vars () const { return 0; } /** * @brief Returns true, if the result of this operation can be regarded "merged" always. */ - virtual bool result_is_merged () const = 0; + virtual bool result_is_merged () const { return false; } /** * @brief Returns true, if the result of this operation must not be merged. * This feature can be used, if the result represents "degenerated" objects such * as point-like edges. These must not be merged. Otherwise they disappear. */ - virtual bool result_must_not_be_merged () const = 0; + virtual bool result_must_not_be_merged () const { return false; } /** * @brief Returns true, if the processor wants raw (not merged) input */ - virtual bool requires_raw_input () const = 0; + virtual bool requires_raw_input () const { return false; } /** * @brief Returns true, if the processor wants to build variants * If not true, the processor accepts shape propagation as variant resolution. */ - virtual bool wants_variants () const = 0; + virtual bool wants_variants () const { return false; } }; /** diff --git a/src/db/unit_tests/dbCompoundOperationTests.cc b/src/db/unit_tests/dbCompoundOperationTests.cc index 79921532d..f8ca88eea 100644 --- a/src/db/unit_tests/dbCompoundOperationTests.cc +++ b/src/db/unit_tests/dbCompoundOperationTests.cc @@ -24,6 +24,8 @@ #include "tlUnitTest.h" #include "dbRegion.h" +#include "dbEdgePairs.h" +#include "dbEdges.h" #include "dbCompoundOperation.h" #include "dbReader.h" #include "dbRecursiveShapeIterator.h" @@ -79,3 +81,48 @@ TEST(1_Basic) CHECKPOINT(); db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/drc/compound_au1.gds"); } + +TEST(2_ChainedOperations) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/drc/compound_2.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::RegionCheckOptions check_options; + check_options.metrics = db::Projection; + + unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); + db::Region r (db::RecursiveShapeIterator (ly, ly.cell (*ly.begin_top_down ()), l1)); + + unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); + db::Region r2 (db::RecursiveShapeIterator (ly, ly.cell (*ly.begin_top_down ()), l2)); + + db::CompoundRegionCheckOperationNode *width_check = new db::CompoundRegionCheckOperationNode (db::WidthRelation, false /*==same polygon*/, 1050, check_options); + + db::CompoundRegionEdgePairToPolygonProcessingOperationNode ep2p (new db::EdgePairToPolygonProcessor (0), width_check, true); + db::Region res = r.cop_to_region (ep2p); + + unsigned int l1000 = ly.get_layer (db::LayerProperties (1000, 0)); + res.insert_into (&ly, *ly.begin_top_down (), l1000); + + db::CompoundRegionEdgePairToEdgeProcessingOperationNode ep2e1 (new db::EdgePairToFirstEdgesProcessor (), width_check, true); + db::Edges eres = r.cop_to_edges (ep2e1); + + unsigned int l1001 = ly.get_layer (db::LayerProperties (1001, 0)); + eres.insert_into (&ly, *ly.begin_top_down (), l1001); + + db::CompoundRegionEdgePairToEdgeProcessingOperationNode ep2e2 (new db::EdgePairToSecondEdgesProcessor (), width_check, true); + eres = r.cop_to_edges (ep2e2); + + unsigned int l1002 = ly.get_layer (db::LayerProperties (1002, 0)); + eres.insert_into (&ly, *ly.begin_top_down (), l1002); + + CHECKPOINT(); + db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/drc/compound_au2.gds"); +} + diff --git a/src/db/unit_tests/dbEdgePairsTests.cc b/src/db/unit_tests/dbEdgePairsTests.cc index d70eeb7c0..cdf33d882 100644 --- a/src/db/unit_tests/dbEdgePairsTests.cc +++ b/src/db/unit_tests/dbEdgePairsTests.cc @@ -123,6 +123,11 @@ struct EPTestFilter return &m_vars; } + bool wants_variants () const + { + return false; + } + private: db::MagnificationReducer m_vars; };