diff --git a/src/db/db/dbCompoundOperation.cc b/src/db/db/dbCompoundOperation.cc index 81e3a6ad7..d5df599f4 100644 --- a/src/db/db/dbCompoundOperation.cc +++ b/src/db/db/dbCompoundOperation.cc @@ -25,6 +25,37 @@ namespace db // --------------------------------------------------------------------------------------------- +void +CompoundRegionOperationNode::compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const +{ + std::vector > intermediate; + do_compute_local (layout, interactions, intermediate, max_vertex_count, area_ratio); + + tl_assert (layout != 0); + for (std::vector >::const_iterator r = intermediate.begin (); r != intermediate.end (); ++r) { + results.push_back (std::unordered_set ()); + for (std::unordered_set::const_iterator p = r->begin (); p != r->end (); ++p) { + results.back ().insert (db::PolygonRef (*p, layout->shape_repository ())); + } + } +} + +void +CompoundRegionOperationNode::compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const +{ + std::vector > intermediate; + do_compute_local (layout, interactions, intermediate, max_vertex_count, area_ratio); + + for (std::vector >::const_iterator r = intermediate.begin (); r != intermediate.end (); ++r) { + results.push_back (std::unordered_set ()); + for (std::unordered_set::const_iterator p = r->begin (); p != r->end (); ++p) { + results.back ().insert (p->obj ().transformed (p->trans ())); + } + } +} + +// --------------------------------------------------------------------------------------------- + CompoundRegionOperationPrimaryNode::CompoundRegionOperationPrimaryNode () { // .. nothing yet .. @@ -154,6 +185,11 @@ CompoundRegionMultiInputOperationNode::CompoundRegionMultiInputOperationNode (co init (); } +CompoundRegionMultiInputOperationNode::CompoundRegionMultiInputOperationNode () +{ + init (); +} + CompoundRegionMultiInputOperationNode::CompoundRegionMultiInputOperationNode (CompoundRegionOperationNode *child) { m_children.push_back (child); diff --git a/src/db/db/dbCompoundOperation.h b/src/db/db/dbCompoundOperation.h index 428f503cd..f5e4cbf1c 100644 --- a/src/db/db/dbCompoundOperation.h +++ b/src/db/db/dbCompoundOperation.h @@ -29,6 +29,8 @@ #include "dbRegion.h" #include "dbEdges.h" #include "dbEdgePairs.h" +#include "dbRegionProcessors.h" +#include "dbRegionLocalOperations.h" #include "gsiObject.h" #include "tlObject.h" @@ -70,32 +72,36 @@ public: */ virtual bool wants_variants () const { return false; } - virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const + void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const { do_compute_local (layout, interactions, results, max_vertex_count, area_ratio); } - virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const + void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; + + void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const { do_compute_local (layout, interactions, results, max_vertex_count, area_ratio); } - virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const + void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const { do_compute_local (layout, interactions, results, max_vertex_count, area_ratio); } - virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const + void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const { do_compute_local (layout, interactions, results, max_vertex_count, area_ratio); } - virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const + void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; + + void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const { do_compute_local (layout, interactions, results, max_vertex_count, area_ratio); } - virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const + void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const { do_compute_local (layout, interactions, results, max_vertex_count, area_ratio); } @@ -267,6 +273,7 @@ class DB_PUBLIC CompoundRegionMultiInputOperationNode { public: CompoundRegionMultiInputOperationNode (const std::vector &children); + CompoundRegionMultiInputOperationNode (); CompoundRegionMultiInputOperationNode (CompoundRegionOperationNode *child); CompoundRegionMultiInputOperationNode (CompoundRegionOperationNode *a, CompoundRegionOperationNode *b); ~CompoundRegionMultiInputOperationNode (); @@ -402,30 +409,248 @@ private: void implement_bool (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; }; + // @@@ move to .cc + template + struct generic_result_adaptor + { + public: + static void insert (db::Layout *, const db::Shape &shape, std::unordered_set &result) + { + result.insert (shape.edge ()); + } -class DB_PUBLIC CompoundRegionInteractOperationNode + static void insert (db::Layout *, const db::Shape &shape, std::unordered_set &result) + { + db::Polygon p; + shape.polygon (p); + result.insert (p); + } + + static void insert (db::Layout *layout, const db::Shape &shape, std::unordered_set &result) + { + db::Polygon p; + shape.polygon (p); + result.insert (db::PolygonRef (p, layout->shape_repository ())); + } + + generic_result_adaptor (std::vector > *results) + : mp_results (results) + { + m_intermediate.reserve (results->size ()); + for (size_t i = 0; i < results->size (); ++i) { + m_shapes.push_back (db::Shapes ()); + m_intermediate.push_back (&m_shapes.back ()); + } + } + + const std::vector &results () + { + return m_intermediate; + } + + void finish (db::Layout *layout) + { + for (size_t i = 0; i < m_intermediate.size (); ++i) { + for (db::Shapes::shape_iterator s = m_intermediate [i]->begin (db::ShapeIterator::All); ! s.at_end (); ++s) { + insert (layout, *s, (*mp_results)[i]); + } + } + } + + private: + std::vector > *mp_results; + std::vector m_intermediate; + std::list m_shapes; + }; + + +template +class DB_PUBLIC compound_region_generic_operation_node : public CompoundRegionMultiInputOperationNode { public: - enum GeometricalOp { And, Not, Or, Xor }; + /** + * @brief Constructor + * NOTE: the inputs must be given for subjects and one to many intruder layers. + * Input 0 is for the subject, input 1 for the first intruder etc. + * If original layers are required for input, CompoundRegionOperationPrimaryNode or + * CompoundRegionOperationSecondaryNode nodes need to be provided. If no derived node + * is requested for input, the input-less constructor may be used which is more efficient. + */ + compound_region_generic_operation_node (const db::local_operation *op, const std::vector &inputs, const db::TransformationReducer *vars = 0, bool want_variants = false, const std::string &description = "generic") + : CompoundRegionMultiInputOperationNode (inputs), m_op (op), m_description (description), mp_vars (vars), m_wants_variants (want_variants) + { + // .. nothing yet .. + } - CompoundRegionInteractOperationNode (GeometricalOp op, const CompoundRegionOperationNode *a, const CompoundRegionOperationNode *b, size_t min_count = 0, size_t max_count = std::numeric_limits::max ()); + compound_region_generic_operation_node (const db::local_operation *op, CompoundRegionOperationNode *input, const db::TransformationReducer *vars = 0, bool want_variants = false, const std::string &description = "generic") + : CompoundRegionMultiInputOperationNode (input), m_op (op), m_description (description), mp_vars (vars), m_wants_variants (want_variants) + { + // .. nothing yet .. + } - virtual std::string description () const; + compound_region_generic_operation_node (const db::local_operation *op, CompoundRegionOperationNode *a, CompoundRegionOperationNode *b, const db::TransformationReducer *vars = 0, bool want_variants = false, const std::string &description = "generic") + : CompoundRegionMultiInputOperationNode (a, b), m_op (op), m_description (description), mp_vars (vars), m_wants_variants (want_variants) + { + // .. nothing yet .. + } - // specifies the result type - virtual ResultType result_type () const; + virtual std::string description () const { return m_description; } + virtual ResultType result_type () const { return compound_operation_type_traits::type (); } + 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 (); } - // the different computation slots - 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 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 std::vector inputs () const + { + if (! m_inputs.empty ()) { + return m_inputs; + } else { + return CompoundRegionMultiInputOperationNode::inputs (); + } + } + + virtual void 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); + } + + virtual void 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); + } + + virtual void 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); + } + + virtual void 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); + } + +protected: + compound_region_generic_operation_node (const db::local_operation *op, const std::vector &inputs, const db::TransformationReducer *vars = 0, bool want_variants = false, const std::string &description = "generic") + : CompoundRegionMultiInputOperationNode (), m_inputs (inputs), m_op (op), m_description (description), mp_vars (vars), m_wants_variants (want_variants) + { + // .. nothing yet .. + } + + compound_region_generic_operation_node (const db::local_operation *op, db::Region *input, const db::TransformationReducer *vars = 0, bool want_variants = false, const std::string &description = "generic") + : CompoundRegionMultiInputOperationNode (), m_op (op), m_description (description), mp_vars (vars), m_wants_variants (want_variants) + { + m_inputs.push_back (input); + } + + compound_region_generic_operation_node (const db::local_operation *op, db::Region *a, db::Region *b, const db::TransformationReducer *vars = 0, bool want_variants = false, const std::string &description = "generic") + : CompoundRegionMultiInputOperationNode (), m_op (op), m_description (description), mp_vars (vars), m_wants_variants (want_variants) + { + m_inputs.push_back (a); + m_inputs.push_back (b); + } private: - GeometricalOp m_op; + const db::local_operation *m_op; + std::string m_description; + const db::TransformationReducer *mp_vars; + bool m_wants_variants; + std::vector m_inputs; + // required if the inner processor is a PolygonRef type while the outer interface needs Polygon + db::Layout m_aux_layout; + + template + void implement_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const + { + generic_result_adaptor adaptor (&results); + + if (! layout) { + layout = const_cast (&m_aux_layout); + } + + shape_interactions internal; + + const CompoundRegionOperationNode *self = child (0); + std::vector > self_result; + + shape_interactions self_interactions_heap; + const shape_interactions &self_interactions = interactions_for_child (interactions, 0, self_interactions_heap); + + self->compute_local (layout, self_interactions, self_result, max_vertex_count, area_ratio); + + db::generic_shape_iterator is (self_result.front ().begin (), self_result.front ().end ()); + + std::vector > iiv; + std::vector > intruder_results; + intruder_results.reserve (children () - 1); // important, so that the memory layout will not change while we generate them + + for (unsigned int ci = 1; ci < children (); ++ci) { + + const CompoundRegionOperationNode *intruder = child (ci); + std::vector > intruder_result; + + shape_interactions intruder_interactions_heap; + const shape_interactions &intruder_interactions = interactions_for_child (interactions, ci, intruder_interactions_heap); + + intruder->compute_local (layout, intruder_interactions, intruder_result, max_vertex_count, area_ratio); + + intruder_results.push_back (std::unordered_set ()); + intruder_results.back ().swap (intruder_result.front ()); + + iiv.push_back (db::generic_shape_iterator (intruder_results.back ().begin (), intruder_results.back ().end ())); + + } + + db::local_processor proc (layout); + proc.run_flat (is, iiv, m_op, adaptor.results ()); + + adaptor.finish (layout); + } }; +class DB_PUBLIC CompoundRegionInteractOperationNode + : public compound_region_generic_operation_node +{ +public: + CompoundRegionInteractOperationNode (CompoundRegionOperationNode *a, CompoundRegionOperationNode *b, int mode, bool touching, bool inverse, size_t min_count = 0, size_t max_count = std::numeric_limits::max ()) + : compound_region_generic_operation_node (&m_op, a, b), m_op (mode, touching, inverse, min_count, max_count) + { + // .. nothing yet .. + } + + CompoundRegionInteractOperationNode (db::Region *a, db::Region *b, int mode, bool touching, bool inverse, size_t min_count = 0, size_t max_count = std::numeric_limits::max ()) + : compound_region_generic_operation_node (&m_op, a, b), m_op (mode, touching, inverse, min_count, max_count) + { + // .. nothing yet .. + } + + virtual std::string description () const + { + return std::string ("interact") + compound_region_generic_operation_node::description (); + } + +private: + db::interacting_local_operation m_op; +}; + +class DB_PUBLIC CompoundRegionInteractWithEdgeOperationNode + : public compound_region_generic_operation_node +{ +public: + CompoundRegionInteractWithEdgeOperationNode (CompoundRegionOperationNode *a, CompoundRegionOperationNode *b, int mode, bool touching, bool inverse, size_t min_count = 0, size_t max_count = std::numeric_limits::max ()) + : compound_region_generic_operation_node (&m_op, a, b), m_op (mode, touching, inverse, min_count, max_count) + { + // .. nothing yet .. + } + + virtual std::string description () const + { + return std::string ("interact") + compound_region_generic_operation_node::description (); + } + +private: + db::interacting_local_operation m_op; +}; class DB_PUBLIC CompoundRegionPullOperationNode : public CompoundRegionMultiInputOperationNode @@ -451,86 +676,6 @@ private: }; -class DB_PUBLIC CompoundRegionSizeOperationNode - : public CompoundRegionMultiInputOperationNode -{ -public: - enum GeometricalOp { And, Not, Or, Xor }; - - CompoundRegionSizeOperationNode (GeometricalOp op, const CompoundRegionOperationNode *input, db::Coord size_x, db::Coord size_y); - - virtual std::string description () const; - - // specifies the result type - virtual ResultType result_type () const; - - virtual db::Coord dist () const; - virtual const TransformationReducer *vars () const; - - // the different computation slots - 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 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: - GeometricalOp m_op; - CompoundTransformationReducer m_vars; -}; - - -class DB_PUBLIC CompoundRegionMergeOperationNode - : public CompoundRegionMultiInputOperationNode -{ -public: - CompoundRegionMergeOperationNode (const CompoundRegionOperationNode *input, size_t min_wrap_count = 1); - - virtual std::string description () const; - - // specifies the result type - virtual ResultType result_type () const; - - // the different computation slots - 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 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; -}; - - -... either all or no input ... - -template -class DB_PUBLIC compound_region_generic_operation_node - : public CompoundRegionMultiInputOperationNode -{ -public: - compound_region_generic_operation_node (const db::local_operation &op, const std::vector &inputs, const db::TransformationReducer *vars = 0, bool want_variants = false, const std::string &description = "generic") - : CompoundRegionMultiInputOperationNode (inputs), m_op (op), m_description (description), mp_vars (vars), m_wants_variants (want_variants) - { - // .. nothing yet .. - } - - virtual std::string description () const { return m_description; } - virtual ResultType result_type () const { return compound_operation_type_traits::type (); } - virtual const db::TransformationReducer *vars () const { return mp_vars; } - virtual bool wants_variants () const { return m_wants_variants; } - - // the different computation slots - 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 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: - db::local_operation m_op; - std::string m_description; - const db::TransformationReducer *mp_vars; - bool m_wants_variants; -}; - /** * @brief Implements the case selection @@ -651,6 +796,28 @@ private: } }; +class DB_PUBLIC CompoundRegionSizeOperationNode + : public CompoundRegionProcessingOperationNode +{ +public: + CompoundRegionSizeOperationNode (db::Coord dx, db::Coord dy, unsigned int mode, CompoundRegionOperationNode *input) + : CompoundRegionProcessingOperationNode (& m_proc, input), m_proc (dx, dy, mode) + { } + + CompoundRegionSizeOperationNode (db::Coord d, unsigned int mode, CompoundRegionOperationNode *input) + : CompoundRegionProcessingOperationNode (& m_proc, input), m_proc (d, d, mode) + { } + + virtual std::string description () const + { + return std::string ("sized") + CompoundRegionProcessingOperationNode::description (); + } + +private: + db::PolygonSizer m_proc; + CompoundTransformationReducer m_vars; +}; + class DB_PUBLIC CompoundRegionToEdgeProcessingOperationNode : public CompoundRegionMultiInputOperationNode { @@ -766,6 +933,7 @@ public: const TransformationReducer *vars () const { return mp_node->vars (); } bool wants_variants () const { return mp_node->wants_variants (); } + std::vector inputs () const { return mp_node->inputs (); } private: std::auto_ptr mp_node; diff --git a/src/db/db/dbRegionProcessors.cc b/src/db/db/dbRegionProcessors.cc index c03f76185..63c1f9651 100644 --- a/src/db/db/dbRegionProcessors.cc +++ b/src/db/db/dbRegionProcessors.cc @@ -181,4 +181,35 @@ void PolygonBreaker::process (const db::Polygon &poly, std::vector } } +// ----------------------------------------------------------------------------------- +// PolygonSizer implementation + +PolygonSizer::PolygonSizer (db::Coord dx, db::Coord dy, unsigned int mode) + : m_dx (dx), m_dy (dy), m_mode (mode) +{ + if (dx == dy) { + m_vars = new db::MagnificationReducer (); + } else { + m_vars = new db::XYAnisotropyAndMagnificationReducer (); + } +} + +PolygonSizer::~PolygonSizer () +{ + delete m_vars; +} + +void PolygonSizer::process (const db::Polygon &poly, std::vector &result) const +{ + db::PolygonContainer pr (result); + db::PolygonGenerator pg2 (pr, false /*don't resolve holes*/, true /*min. coherence*/); + db::SizingPolygonFilter siz (pg2, m_dx, m_dy, m_mode); + siz.put (poly); +} + +bool PolygonSizer::result_is_merged () const +{ + return (m_dx < 0 && m_dy < 0); +} + } diff --git a/src/db/db/dbRegionProcessors.h b/src/db/db/dbRegionProcessors.h index 8d185075f..6ed660358 100644 --- a/src/db/db/dbRegionProcessors.h +++ b/src/db/db/dbRegionProcessors.h @@ -299,6 +299,31 @@ private: double m_max_area_ratio; }; +/** + * @brief A sizing processor + */ +class DB_PUBLIC PolygonSizer + : public db::PolygonProcessorBase +{ +public: + PolygonSizer (db::Coord dx, db::Coord dy, unsigned int mode); + ~PolygonSizer (); + + virtual const TransformationReducer *vars () const { return m_vars; } + + void process (const db::Polygon &poly, std::vector &result) const; + + virtual bool result_is_merged () const; + virtual bool result_must_not_be_merged () const { return false; } + virtual bool requires_raw_input () const { return false; } + virtual bool wants_variants () const { return true; } + +private: + TransformationReducer *m_vars; + db::Coord m_dx, m_dy; + unsigned int m_mode; +}; + /** * @brief Computes the Minkowsky sum between the polygons and the given object * The object can be Edge, Polygon, Box and std::vector