From 817530642320c14dc591bfe0f95da9b27acfcadd Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 16 Nov 2020 23:21:58 +0100 Subject: [PATCH] WIP: compound operations. --- src/db/db/db.pro | 1 + src/db/db/dbAsIfFlatRegion.cc | 79 +++++ src/db/db/dbAsIfFlatRegion.h | 4 + src/db/db/dbCompoundOperation.cc | 326 +++++++++++------- src/db/db/dbCompoundOperation.h | 429 ++++++++++++++---------- src/db/db/dbDeepRegion.cc | 124 +++++++ src/db/db/dbDeepRegion.h | 21 +- src/db/db/dbEmptyRegion.cc | 18 + src/db/db/dbEmptyRegion.h | 4 + src/db/db/dbRegion.cc | 37 ++ src/db/db/dbRegion.h | 33 ++ src/db/db/dbRegionDelegate.h | 5 + src/db/db/dbRegionProcessors.h | 6 +- src/db/db/dbShapeCollectionUtils.h | 2 + src/db/db/gsiDeclDbCompoundOperation.cc | 179 ++++++++++ 15 files changed, 945 insertions(+), 323 deletions(-) create mode 100644 src/db/db/gsiDeclDbCompoundOperation.cc diff --git a/src/db/db/db.pro b/src/db/db/db.pro index 7670204ed..a911e1a03 100644 --- a/src/db/db/db.pro +++ b/src/db/db/db.pro @@ -94,6 +94,7 @@ SOURCES = \ gsiDeclDbCell.cc \ gsiDeclDbCellMapping.cc \ gsiDeclDbCommonStreamOptions.cc \ + gsiDeclDbCompoundOperation.cc \ gsiDeclDbEdge.cc \ gsiDeclDbEdgePair.cc \ gsiDeclDbEdgePairs.cc \ diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index 0cbd29585..ae6094aca 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -39,6 +39,7 @@ #include "dbHash.h" #include "dbRegionLocalOperations.h" #include "dbHierProcessor.h" +#include "dbCompoundOperation.h" #include @@ -1016,6 +1017,84 @@ AsIfFlatRegion::scaled_and_snapped (db::Coord gx, db::Coord mx, db::Coord dx, db return new_region.release (); } +EdgePairsDelegate * +AsIfFlatRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &node) +{ + db::local_processor proc; + proc.set_base_verbosity (base_verbosity ()); + + std::vector > others; + std::vector inputs = node.inputs (); + for (std::vector::const_iterator i = inputs.begin (); i != inputs.end (); ++i) { + // @@@ in case of *i == null - what to do? + others.push_back (*i ? (*i)->begin () : begin ()); + } + + // @@@ really always "merged"? + db::RegionIterator polygons (begin_merged ()); + + std::auto_ptr output (new FlatEdgePairs ()); + std::vector results; + results.push_back (&output->raw_edge_pairs ()); + + compound_local_operation op (&node); + proc.run_flat (polygons, others, &op, results); + + return output.release (); +} + +RegionDelegate * +AsIfFlatRegion::cop_to_region (db::CompoundRegionOperationNode &node) +{ + db::local_processor proc; + proc.set_base_verbosity (base_verbosity ()); + + std::vector > others; + std::vector inputs = node.inputs (); + for (std::vector::const_iterator i = inputs.begin (); i != inputs.end (); ++i) { + // @@@ in case of *i == null - what to do? + others.push_back (*i ? (*i)->begin () : begin ()); + } + + // @@@ really always "merged"? + db::RegionIterator polygons (begin_merged ()); + + std::auto_ptr output (new FlatRegion ()); + std::vector results; + results.push_back (&output->raw_polygons ()); + + compound_local_operation op (&node); + proc.run_flat (polygons, others, &op, results); + + return output.release (); +} + +EdgesDelegate * +AsIfFlatRegion::cop_to_edges (db::CompoundRegionOperationNode &node) +{ + db::local_processor proc; + proc.set_base_verbosity (base_verbosity ()); + + std::vector > others; + std::vector inputs = node.inputs (); + for (std::vector::const_iterator i = inputs.begin (); i != inputs.end (); ++i) { + // @@@ in case of *i == null - what to do? + others.push_back (*i ? (*i)->begin () : begin ()); + } + + // @@@ really always "merged"? + db::RegionIterator polygons (begin_merged ()); + + std::auto_ptr output (new FlatEdges ()); + std::vector results; + results.push_back (&output->raw_edges ()); + + compound_local_operation op (&node); + proc.run_flat (polygons, others, &op, results); + + return output.release (); +} + 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 { diff --git a/src/db/db/dbAsIfFlatRegion.h b/src/db/db/dbAsIfFlatRegion.h index dc1d25438..1559a826b 100644 --- a/src/db/db/dbAsIfFlatRegion.h +++ b/src/db/db/dbAsIfFlatRegion.h @@ -56,6 +56,10 @@ public: virtual std::string to_string (size_t nmax) const; + virtual EdgePairsDelegate *cop_to_edge_pairs (db::CompoundRegionOperationNode &node); + virtual RegionDelegate *cop_to_region (db::CompoundRegionOperationNode &node); + virtual EdgesDelegate *cop_to_edges (db::CompoundRegionOperationNode &node); + EdgePairsDelegate *width_check (db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const { return run_single_polygon_check (db::WidthRelation, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded); diff --git a/src/db/db/dbCompoundOperation.cc b/src/db/db/dbCompoundOperation.cc index 272fa0181..17235b0e1 100644 --- a/src/db/db/dbCompoundOperation.cc +++ b/src/db/db/dbCompoundOperation.cc @@ -32,13 +32,15 @@ TODO: * "requires raw input"? * Make nodes shared pointers/GSI objects for better compatibility with GSI, at least "keep" them. -* Edge generation nodes -* Boolean and interaction nodes (interact, bool with edge, bool with polygon ...) +* edge pair to edge generation nodes (first, second) * Interactions with shapes over some distance for neighborhood analysis * Sized subject shapes as inputs for other operations? how to compute distance then? +* how do the logical boolean ops work? +* what is the "multi_input" for case nodes? + */ namespace db @@ -56,42 +58,97 @@ CompoundRegionOperationNode::~CompoundRegionOperationNode () // .. nothing yet .. } +std::string CompoundRegionOperationNode::description() const +{ + if (m_description.empty ()) { + return generated_description (); + } else { + return m_description; + } +} + +void +CompoundRegionOperationNode::set_description (const std::string &d) +{ + m_description = d; +} + // --------------------------------------------------------------------------------------------- +static void translate (db::Layout *layout, const std::vector > &in, std::vector > &out) +{ + tl_assert (layout != 0); + for (std::vector >::const_iterator r = in.begin (); r != in.end (); ++r) { + out.push_back (std::unordered_set ()); + for (std::unordered_set::const_iterator p = r->begin (); p != r->end (); ++p) { + out.back ().insert (db::PolygonRef (*p, layout->shape_repository ())); + } + } +} + +static void translate (db::Layout *, const std::vector > &in, std::vector > &out) +{ + for (std::vector >::const_iterator r = in.begin (); r != in.end (); ++r) { + out.push_back (std::unordered_set ()); + for (std::unordered_set::const_iterator p = r->begin (); p != r->end (); ++p) { + out.back ().insert (p->obj ().transformed (p->trans ())); + } + } +} + 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 ())); - } - } + implement_compute_local (layout, interactions, intermediate, max_vertex_count, area_ratio); + translate (layout, intermediate, results); } 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); + implement_compute_local (layout, interactions, intermediate, max_vertex_count, area_ratio); + translate (layout, intermediate, results); +} - 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 ())); - } - } +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; + implement_compute_local (layout, interactions, intermediate, max_vertex_count, area_ratio); + translate (layout, intermediate, results); +} + +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; + implement_compute_local (layout, interactions, intermediate, max_vertex_count, area_ratio); + translate (layout, intermediate, results); +} + +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; + implement_compute_local (layout, interactions, intermediate, max_vertex_count, area_ratio); + translate (layout, intermediate, results); +} + +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; + implement_compute_local (layout, interactions, intermediate, max_vertex_count, area_ratio); + translate (layout, intermediate, results); } // --------------------------------------------------------------------------------------------- CompoundRegionOperationPrimaryNode::CompoundRegionOperationPrimaryNode () { - // .. nothing yet .. + set_description (std::string ("this")); } CompoundRegionOperationPrimaryNode::~CompoundRegionOperationPrimaryNode () @@ -99,11 +156,6 @@ CompoundRegionOperationPrimaryNode::~CompoundRegionOperationPrimaryNode () // .. nothing yet .. } -std::string CompoundRegionOperationPrimaryNode::description () const -{ - return std::string ("this"); -} - std::vector CompoundRegionOperationPrimaryNode::inputs () const { return std::vector (); @@ -128,7 +180,7 @@ void CompoundRegionOperationPrimaryNode::do_compute_local (db::Layout *, const s CompoundRegionOperationSecondaryNode::CompoundRegionOperationSecondaryNode (db::Region *input) : mp_input (input) { - // .. nothing yet .. + set_description ("other"); } CompoundRegionOperationSecondaryNode::~CompoundRegionOperationSecondaryNode () @@ -136,10 +188,6 @@ CompoundRegionOperationSecondaryNode::~CompoundRegionOperationSecondaryNode () // .. nothing yet .. } -std::string CompoundRegionOperationSecondaryNode::description () const -{ - return std::string ("other"); -} std::vector CompoundRegionOperationSecondaryNode::inputs () const { @@ -315,7 +363,7 @@ CompoundRegionMultiInputOperationNode::dist () const } std::string -CompoundRegionMultiInputOperationNode::description () const +CompoundRegionMultiInputOperationNode::generated_description () const { std::string r = "("; for (tl::shared_collection::const_iterator i = m_children.begin (); i != m_children.end (); ++i) { @@ -369,7 +417,7 @@ CompoundRegionLogicalBoolOperationNode::CompoundRegionLogicalBoolOperationNode ( // .. nothing yet .. } -std::string CompoundRegionLogicalBoolOperationNode::description () const +std::string CompoundRegionLogicalBoolOperationNode::generated_description () const { std::string r; if (m_invert) { @@ -413,6 +461,7 @@ void CompoundRegionLogicalBoolOperationNode::implement_compute_local (db::Layout } + // @@@ invert is not handled, this is not a boolean return value if (ok) { tl_assert (! results.empty ()); results.front ().insert (subject_shape); @@ -428,7 +477,7 @@ CompoundRegionGeometricalBoolOperationNode::CompoundRegionGeometricalBoolOperati } std::string -CompoundRegionGeometricalBoolOperationNode::description () const +CompoundRegionGeometricalBoolOperationNode::generated_description () const { std::string r; if (m_op == And) { @@ -688,106 +737,114 @@ CompoundRegionGeometricalBoolOperationNode::do_compute_local (db::Layout *layout implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); } - - -#if 0 // @@@ // --------------------------------------------------------------------------------------------- -class DB_PUBLIC CompoundRegionInteractOperationNode - : public CompoundRegionMultiInputOperationNode +namespace { -public: - enum GeometricalOp { And, Not, Or, Xor }; + template + struct generic_result_adaptor + { + public: + 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 ()); + } + } - CompoundRegionInteractOperationNode (GeometricalOp op, const CompoundRegionOperationNode *a, const CompoundRegionOperationNode *b, size_t min_count = 0, size_t max_count = std::numeric_limits::max ()); + static void insert (db::Layout *, const db::Shape &shape, std::unordered_set &result) + { + result.insert (shape.edge ()); + } - virtual std::string description () const; + static void insert (db::Layout *, const db::Shape &shape, std::unordered_set &result) + { + db::Polygon p; + shape.polygon (p); + result.insert (p); + } - // specifies the result type - virtual ResultType result_type () const; + 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 ())); + } - // 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; + const std::vector &results () + { + return m_intermediate; + } -private: - GeometricalOp m_op; -}; + 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; + }; -class DB_PUBLIC CompoundRegionPullOperationNode - : public CompoundRegionMultiInputOperationNode +} + +template +template +void compound_region_generic_operation_node::implement_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const { -public: - enum GeometricalOp { And, Not, Or, Xor }; + generic_result_adaptor adaptor (&results); - CompoundRegionPullOperationNode (GeometricalOp op, const CompoundRegionOperationNode *a, const CompoundRegionOperationNode *b); + if (! layout) { + layout = const_cast (&m_aux_layout); + } - virtual std::string description () const; + shape_interactions internal; - // specifies the result type - virtual ResultType result_type () const; + const CompoundRegionOperationNode *self = child (0); + std::vector > self_result; - // 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; + shape_interactions self_interactions_heap; + const shape_interactions &self_interactions = interactions_for_child (interactions, 0, self_interactions_heap); -private: - GeometricalOp m_op; -}; + 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 ()); -class DB_PUBLIC CompoundRegionSizeOperationNode - : public CompoundRegionMultiInputOperationNode -{ -public: - enum GeometricalOp { And, Not, Or, Xor }; + 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 - CompoundRegionSizeOperationNode (GeometricalOp op, const CompoundRegionOperationNode *input, db::Coord size_x, db::Coord size_y); + for (unsigned int ci = 1; ci < children (); ++ci) { - virtual std::string description () const; + const CompoundRegionOperationNode *intruder = child (ci); + std::vector > intruder_result; - // specifies the result type - virtual ResultType result_type () const; + shape_interactions intruder_interactions_heap; + const shape_interactions &intruder_interactions = interactions_for_child (interactions, ci, intruder_interactions_heap); - virtual db::Coord dist () const; - virtual const TransformationReducer *vars () const; + intruder->compute_local (layout, intruder_interactions, intruder_result, max_vertex_count, area_ratio); - // 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; + intruder_results.push_back (std::unordered_set ()); + intruder_results.back ().swap (intruder_result.front ()); -private: - GeometricalOp m_op; - CompoundTransformationReducer m_vars; -}; + iiv.push_back (db::generic_shape_iterator (intruder_results.back ().begin (), intruder_results.back ().end ())); -class DB_PUBLIC CompoundRegionMergeOperationNode - : public CompoundRegionMultiInputOperationNode -{ -public: - CompoundRegionMergeOperationNode (const CompoundRegionOperationNode *input, size_t min_wrap_count = 1); + } - virtual std::string description () const; + db::local_processor proc (layout); + proc.run_flat (is, iiv, m_op, adaptor.results ()); - // specifies the result type - virtual ResultType result_type () const; + adaptor.finish (layout); +} - // 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; -}; -#endif // --------------------------------------------------------------------------------------------- @@ -797,7 +854,7 @@ CompoundRegionLogicalCaseSelectOperationNode::CompoundRegionLogicalCaseSelectOpe // .. nothing yet .. } -std::string CompoundRegionLogicalCaseSelectOperationNode::description () const +std::string CompoundRegionLogicalCaseSelectOperationNode::generated_description () const { // TODO: could be nicer ... std::string r; @@ -849,17 +906,15 @@ void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local (db:: } +template void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local (db::Layout *, const shape_interactions &, std::vector > &, size_t, double) const; +template void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local (db::Layout *, const shape_interactions &, std::vector > &, size_t, double) const; + // --------------------------------------------------------------------------------------------- CompoundRegionFilterOperationNode::CompoundRegionFilterOperationNode (PolygonFilterBase *filter, CompoundRegionOperationNode *input) : CompoundRegionMultiInputOperationNode (input), mp_filter (filter) -{ } - -std::string -CompoundRegionFilterOperationNode::description () const { - // TODO: some description? - return "filter"; + set_description ("filter"); } void @@ -890,13 +945,8 @@ CompoundRegionFilterOperationNode::is_selected (const db::PolygonRef &p) const CompoundRegionProcessingOperationNode::CompoundRegionProcessingOperationNode (PolygonProcessorBase *proc, CompoundRegionOperationNode *input) : CompoundRegionMultiInputOperationNode (input), mp_proc (proc) -{ } - -std::string -CompoundRegionProcessingOperationNode::description () const { - // TODO: some description? - return "processor"; + set_description ("processor"); } void @@ -931,13 +981,8 @@ CompoundRegionProcessingOperationNode::processed (db::Layout *layout, const db:: CompoundRegionToEdgeProcessingOperationNode::CompoundRegionToEdgeProcessingOperationNode (PolygonToEdgeProcessorBase *proc, CompoundRegionOperationNode *input) : CompoundRegionMultiInputOperationNode (input), mp_proc (proc) -{ } - -std::string -CompoundRegionToEdgeProcessingOperationNode::description () const { - // TODO: some description? - return "processor"; + set_description ("processor"); } void @@ -968,13 +1013,8 @@ CompoundRegionToEdgeProcessingOperationNode::processed (db::Layout *, const db:: CompoundRegionToEdgePairProcessingOperationNode::CompoundRegionToEdgePairProcessingOperationNode (PolygonToEdgePairProcessorBase *proc, CompoundRegionOperationNode *input) : CompoundRegionMultiInputOperationNode (input), mp_proc (proc) -{ } - -std::string -CompoundRegionToEdgePairProcessingOperationNode::description () const { - // TODO: some description? - return "processor"; + set_description ("processor"); } void @@ -1001,5 +1041,33 @@ CompoundRegionToEdgePairProcessingOperationNode::processed (db::Layout *, const mp_proc->process (p.obj ().transformed (p.trans ()), res); } +// --------------------------------------------------------------------------------------------- + +CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegionOperationNode *input, db::edge_relation_type rel, bool different_polygons, db::Coord d, bool whole_edges, db::metrics_type metrics, double ignore_angle, db::coord_traits::distance_type min_projection, db::coord_traits::distance_type max_projection, bool shielded) + : CompoundRegionMultiInputOperationNode (input), m_check (rel, d, metrics), m_different_polygons (different_polygons), m_shielded (shielded) +{ + set_description ("check"); + + m_check.set_include_zero (false); + m_check.set_whole_edges (whole_edges); + m_check.set_ignore_angle (ignore_angle); + m_check.set_min_projection (min_projection); + m_check.set_max_projection (max_projection); +} + +void +CompoundRegionCheckOperationNode::do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const +{ + db::check_local_operation op (m_check, m_different_polygons, true, false, m_shielded); + op.compute_local (layout, interactions, results, max_vertex_count, area_ratio); +} + +void +CompoundRegionCheckOperationNode::do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const +{ + db::check_local_operation op (m_check, m_different_polygons, true, false, m_shielded); + op.compute_local (layout, interactions, results, max_vertex_count, area_ratio); +} + } diff --git a/src/db/db/dbCompoundOperation.h b/src/db/db/dbCompoundOperation.h index d5874058b..ce02ef6f1 100644 --- a/src/db/db/dbCompoundOperation.h +++ b/src/db/db/dbCompoundOperation.h @@ -32,6 +32,7 @@ #include "dbEdgePairs.h" #include "dbRegionProcessors.h" #include "dbRegionLocalOperations.h" +#include "dbTypes.h" #include "gsiObject.h" #include "tlObject.h" @@ -41,6 +42,16 @@ namespace db { +/** + * @brief A node of the compound operation tree + * + * A compound operation if formed of a tree of basic operations. The root node + * will act as the main entrance and is fed into a local processor for performing + * the complex operation. + * + * The tree nodes will + */ + class DB_PUBLIC CompoundRegionOperationNode : public gsi::ObjectBase, public tl::Object { @@ -50,8 +61,10 @@ public: CompoundRegionOperationNode (); virtual ~CompoundRegionOperationNode (); + std::string description () const; + void set_description (const std::string &d); + virtual db::Coord dist () const = 0; - virtual std::string description () const = 0; virtual std::vector inputs () const = 0; // specifies the result type @@ -71,36 +84,84 @@ public: 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); + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); } 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); + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); } 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); + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); } 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); + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); } 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); + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); } 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); + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); + } + + void 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 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 + { + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); + } + + 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 + { + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); + } + + void 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 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 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 + { + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); + } + + 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 + { + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); + } + + void 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); } template @@ -143,14 +204,25 @@ public: protected: // 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 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 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 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 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::string generated_description () const; private: + std::string m_description; mutable std::vector > m_cache_polyref; mutable bool m_cache_polyref_valid; mutable std::vector > m_cache_poly; @@ -165,10 +237,10 @@ private: void get_cache (std::vector > *&cache_ptr, bool *&valid) const { cache_ptr = &m_cache_edge; valid = &m_cache_edge_valid; } void get_cache (std::vector > *&cache_ptr, bool *&valid) const { cache_ptr = &m_cache_edge_pair; valid = &m_cache_edge_pair_valid; } - template - void implement_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) 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 > *cache = 0; + std::vector > *cache = 0; bool *valid = 0; get_cache (cache, valid); if (*valid) { @@ -220,7 +292,6 @@ public: CompoundRegionOperationPrimaryNode (); virtual ~CompoundRegionOperationPrimaryNode (); - virtual std::string description () const; virtual std::vector inputs () const; virtual db::Coord dist () const { return 0; } virtual ResultType result_type () const { return Region; } @@ -237,7 +308,6 @@ public: CompoundRegionOperationSecondaryNode (db::Region *input); virtual ~CompoundRegionOperationSecondaryNode (); - virtual std::string description () const; virtual std::vector inputs () const; virtual db::Coord dist () const { return 0; } virtual ResultType result_type () const { return Region; } @@ -280,7 +350,7 @@ public: ~CompoundRegionMultiInputOperationNode (); virtual db::Coord dist () const; - virtual std::string description () const; + virtual std::string generated_description () const; virtual std::vector inputs () const { @@ -357,7 +427,7 @@ public: CompoundRegionLogicalBoolOperationNode (LogicalOp op, bool invert, const std::vector &inputs); - virtual std::string description () const; + virtual std::string generated_description () const; // specifies the result type virtual ResultType result_type () const { return Region; } @@ -390,7 +460,7 @@ public: CompoundRegionGeometricalBoolOperationNode (GeometricalOp op, CompoundRegionOperationNode *a, CompoundRegionOperationNode *b); - virtual std::string description () const; + virtual std::string generated_description () const; // specifies the result type virtual ResultType result_type () const; @@ -410,61 +480,6 @@ 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 ()); - } - - 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 @@ -478,25 +493,24 @@ public: * 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) + compound_region_generic_operation_node (const db::local_operation *op, const std::vector &inputs, const db::TransformationReducer *vars = 0, bool want_variants = false) + : CompoundRegionMultiInputOperationNode (inputs), m_op (op), mp_vars (vars), m_wants_variants (want_variants) { // .. nothing yet .. } - 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) + compound_region_generic_operation_node (const db::local_operation *op, CompoundRegionOperationNode *input, const db::TransformationReducer *vars = 0, bool want_variants = false) + : CompoundRegionMultiInputOperationNode (input), m_op (op), mp_vars (vars), m_wants_variants (want_variants) { // .. nothing yet .. } - 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) + compound_region_generic_operation_node (const db::local_operation *op, CompoundRegionOperationNode *a, CompoundRegionOperationNode *b, const db::TransformationReducer *vars = 0, bool want_variants = false) + : CompoundRegionMultiInputOperationNode (a, b), m_op (op), 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; } @@ -511,102 +525,36 @@ public: } } - 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) + compound_region_generic_operation_node (const db::local_operation *op, const std::vector &inputs, const db::TransformationReducer *vars = 0, bool want_variants = false) + : CompoundRegionMultiInputOperationNode (), m_op (op), mp_vars (vars), m_wants_variants (want_variants), m_inputs (inputs) { // .. 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) + compound_region_generic_operation_node (const db::local_operation *op, db::Region *input, const db::TransformationReducer *vars = 0, bool want_variants = false) + : CompoundRegionMultiInputOperationNode (), m_op (op), 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) + 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) + : CompoundRegionMultiInputOperationNode (), m_op (op), mp_vars (vars), m_wants_variants (want_variants) { m_inputs.push_back (a); m_inputs.push_back (b); } + template + void implement_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const; + private: 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 @@ -625,11 +573,21 @@ public: // .. nothing yet .. } - virtual std::string description () const + std::string generated_description () const { return std::string ("interact") + compound_region_generic_operation_node::description (); } + 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); + } + private: db::interacting_local_operation m_op; }; @@ -644,38 +602,88 @@ public: // .. nothing yet .. } - virtual std::string description () const + std::string generated_description () const { return std::string ("interact") + compound_region_generic_operation_node::description (); } + 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); + } + private: db::interacting_local_operation m_op; }; class DB_PUBLIC CompoundRegionPullOperationNode - : public CompoundRegionMultiInputOperationNode + : public compound_region_generic_operation_node { public: - enum GeometricalOp { And, Not, Or, Xor }; + CompoundRegionPullOperationNode (CompoundRegionOperationNode *a, CompoundRegionOperationNode *b, int mode, bool touching) + : compound_region_generic_operation_node (&m_op, a, b), m_op (mode, touching) + { + // .. nothing yet .. + } - CompoundRegionPullOperationNode (GeometricalOp op, const CompoundRegionOperationNode *a, const CompoundRegionOperationNode *b); + CompoundRegionPullOperationNode (db::Region *a, db::Region *b, int mode, bool touching) + : compound_region_generic_operation_node (&m_op, a, b), m_op (mode, touching) + { + // .. nothing yet .. + } - virtual std::string description () const; + std::string generated_description () const + { + return std::string ("pull") + compound_region_generic_operation_node::description (); + } - // specifies the result type - virtual ResultType result_type () 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 + { + implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio); + } - // 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 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); + } private: - GeometricalOp m_op; + db::pull_local_operation m_op; }; +class DB_PUBLIC CompoundRegionPullWithEdgeOperationNode + : public compound_region_generic_operation_node +{ +public: + CompoundRegionPullWithEdgeOperationNode (CompoundRegionOperationNode *a, CompoundRegionOperationNode *b, int mode, bool touching) + : compound_region_generic_operation_node (&m_op, a, b), m_op (mode, touching) + { + // .. nothing yet .. + } + + std::string generated_description () const + { + return std::string ("pull") + compound_region_generic_operation_node::description (); + } + + 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); + } + +private: + db::pull_local_operation m_op; +}; /** @@ -694,7 +702,7 @@ class DB_PUBLIC CompoundRegionLogicalCaseSelectOperationNode public: CompoundRegionLogicalCaseSelectOperationNode (bool multi_layer, const std::vector &inputs); - virtual std::string description () const; + virtual std::string generated_description () const; // specifies the result type virtual ResultType result_type () const { return Region; } @@ -724,8 +732,6 @@ class DB_PUBLIC CompoundRegionFilterOperationNode public: CompoundRegionFilterOperationNode (PolygonFilterBase *filter, CompoundRegionOperationNode *input); - virtual std::string description () const; - // specifies the result type virtual ResultType result_type () const { return Region; } @@ -764,8 +770,6 @@ class DB_PUBLIC CompoundRegionProcessingOperationNode public: CompoundRegionProcessingOperationNode (PolygonProcessorBase *proc, CompoundRegionOperationNode *input); - virtual std::string description () const; - // specifies the result type virtual ResultType result_type () const { return Region; } @@ -825,8 +829,6 @@ class DB_PUBLIC CompoundRegionToEdgeProcessingOperationNode public: CompoundRegionToEdgeProcessingOperationNode (PolygonToEdgeProcessorBase *proc, CompoundRegionOperationNode *input); - virtual std::string description () const; - // specifies the result type virtual ResultType result_type () const { return Edges; } @@ -858,14 +860,22 @@ private: } }; +/** + * @brief A wrapper for a generic edge-pair producing node + * + * This node takes polygons for input. It will produce edge pairs by means of the PolygonToEdgePairProcessorBase object. + */ class DB_PUBLIC CompoundRegionToEdgePairProcessingOperationNode : public CompoundRegionMultiInputOperationNode { public: + /** + * @brief Constructor + * @param proc The processor which turns polygons into edge pairs (it's reimplementation) - the node will *not* take ownership + * @param input The node for the original (the node will take ownership) + */ CompoundRegionToEdgePairProcessingOperationNode (PolygonToEdgePairProcessorBase *proc, CompoundRegionOperationNode *input); - virtual std::string description () const; - // specifies the result type virtual ResultType result_type () const { return EdgePairs; } @@ -876,7 +886,7 @@ public: 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: - PolygonToEdgePairProcessorBase *mp_proc; + tl::weak_ptr mp_proc; void processed (db::Layout *, const db::Polygon &p, std::vector &res) const; void processed (db::Layout *layout, const db::PolygonRef &p, std::vector &res) const; @@ -897,16 +907,56 @@ private: } }; +/** + * @brief A wrapper for a generic DRC check node + * + * This node takes polygons for input. It will produce edge pairs as result of the DRC check. + */ +class DB_PUBLIC CompoundRegionCheckOperationNode + : public CompoundRegionMultiInputOperationNode +{ +public: + /** + * @brief Constructor + * @param input The node for the original (the node will take ownership) + */ + CompoundRegionCheckOperationNode (db::CompoundRegionOperationNode *input, db::edge_relation_type rel, bool different_polygons, db::Coord d, bool whole_edges, db::metrics_type metrics, double ignore_angle, db::coord_traits::distance_type min_projection, db::coord_traits::distance_type max_projection, bool shielded); + // 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; + +private: + db::EdgeRelationFilter m_check; + bool m_different_polygons; + bool m_shielded; +}; + + +/** + * @brief The generic local operation + * + * This local operation executes the operation tree within a local processor. + * When put into a local processor, the operation tree will be executed on each interaction. + */ template class DB_PUBLIC compound_local_operation : public local_operation { public: + /** + * @brief Constructor + * + * Creates a local operation which utilizes the operation tree. "node" is the root of the operation tree. + * Ownership of the node is *not* transferred to the local operation. + */ compound_local_operation (CompoundRegionOperationNode *node) : mp_node (node) { } +protected: virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const { for (typename shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { @@ -937,7 +987,20 @@ public: std::vector inputs () const { return mp_node->inputs (); } private: - std::auto_ptr mp_node; + tl::weak_ptr mp_node; +}; + +} + +namespace tl +{ + +template <> +struct tl::type_traits + : public tl::type_traits +{ + typedef false_tag has_copy_constructor; + typedef false_tag has_default_constructor; }; } diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 46a1463ad..86315648a 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -40,6 +40,7 @@ #include "dbCellVariants.h" #include "dbRegionLocalOperations.h" #include "dbLocalOperationUtils.h" +#include "dbCompoundOperation.h" #include "tlTimer.h" namespace db @@ -1342,6 +1343,129 @@ DeepRegion::in (const Region &other, bool invert) const return db::AsIfFlatRegion::in (other, invert); } +EdgePairsDelegate * +DeepRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &node) +{ + std::vector other_layers; + std::vector inputs = node.inputs (); + for (std::vector::const_iterator i = inputs.begin (); i != inputs.end (); ++i) { + + if (! *i) { + // @@@ in case of *i == null - what to do? + other_layers.push_back (deep_layer ().layer ()); + } else { + const db::DeepRegion *other_deep = dynamic_cast ((*i)->delegate ()); + if (! other_deep) { + return db::AsIfFlatRegion::cop_to_edge_pairs (node); + } + if (&other_deep->deep_layer ().layout () != &deep_layer ().layout () || &other_deep->deep_layer ().initial_cell () != &deep_layer ().initial_cell ()) { + throw tl::Exception (tl::to_string (tr ("Complex DeepRegion operations need to use the same layout and top cell for all inputs"))); + } + other_layers.push_back (other_deep->deep_layer ().layer ()); + } + + } + + // @@@ really always "merged"? + const db::DeepLayer &polygons = merged_deep_layer (); + + db::local_processor proc (const_cast (&deep_layer ().layout ()), + const_cast (&deep_layer ().initial_cell ()), + deep_layer ().breakout_cells ()); + + proc.set_base_verbosity (base_verbosity ()); + proc.set_threads (polygons.store ()->threads ()); + + compound_local_operation op (&node); + + std::auto_ptr res (new db::DeepEdgePairs (polygons.derived ())); + proc.run (&op, polygons.layer (), other_layers, res->deep_layer ().layer ()); + + return res.release (); +} + +RegionDelegate * +DeepRegion::cop_to_region (db::CompoundRegionOperationNode &node) +{ + std::vector other_layers; + std::vector inputs = node.inputs (); + for (std::vector::const_iterator i = inputs.begin (); i != inputs.end (); ++i) { + + if (! *i) { + // @@@ in case of *i == null - what to do? + other_layers.push_back (deep_layer ().layer ()); + } else { + const db::DeepRegion *other_deep = dynamic_cast ((*i)->delegate ()); + if (! other_deep) { + return db::AsIfFlatRegion::cop_to_region (node); + } + if (&other_deep->deep_layer ().layout () != &deep_layer ().layout () || &other_deep->deep_layer ().initial_cell () != &deep_layer ().initial_cell ()) { + throw tl::Exception (tl::to_string (tr ("Complex DeepRegion operations need to use the same layout and top cell for all inputs"))); + } + other_layers.push_back (other_deep->deep_layer ().layer ()); + } + + } + + // @@@ really always "merged"? + const db::DeepLayer &polygons = merged_deep_layer (); + + db::local_processor proc (const_cast (&deep_layer ().layout ()), + const_cast (&deep_layer ().initial_cell ()), + deep_layer ().breakout_cells ()); + + proc.set_base_verbosity (base_verbosity ()); + proc.set_threads (polygons.store ()->threads ()); + + compound_local_operation op (&node); + + std::auto_ptr res (new db::DeepRegion (polygons.derived ())); + proc.run (&op, polygons.layer (), other_layers, res->deep_layer ().layer ()); + + return res.release (); +} + +EdgesDelegate * +DeepRegion::cop_to_edges (db::CompoundRegionOperationNode &node) +{ + std::vector other_layers; + std::vector inputs = node.inputs (); + for (std::vector::const_iterator i = inputs.begin (); i != inputs.end (); ++i) { + + if (! *i) { + // @@@ in case of *i == null - what to do? + other_layers.push_back (deep_layer ().layer ()); + } else { + const db::DeepRegion *other_deep = dynamic_cast ((*i)->delegate ()); + if (! other_deep) { + return db::AsIfFlatRegion::cop_to_edges (node); + } + if (&other_deep->deep_layer ().layout () != &deep_layer ().layout () || &other_deep->deep_layer ().initial_cell () != &deep_layer ().initial_cell ()) { + throw tl::Exception (tl::to_string (tr ("Complex DeepRegion operations need to use the same layout and top cell for all inputs"))); + } + other_layers.push_back (other_deep->deep_layer ().layer ()); + } + + } + + // @@@ really always "merged"? + const db::DeepLayer &polygons = merged_deep_layer (); + + db::local_processor proc (const_cast (&deep_layer ().layout ()), + const_cast (&deep_layer ().initial_cell ()), + deep_layer ().breakout_cells ()); + + proc.set_base_verbosity (base_verbosity ()); + proc.set_threads (polygons.store ()->threads ()); + + compound_local_operation op (&node); + + std::auto_ptr res (new db::DeepEdges (polygons.derived ())); + proc.run (&op, polygons.layer (), other_layers, res->deep_layer ().layer ()); + + return res.release (); +} + EdgePairsDelegate * DeepRegion::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 { diff --git a/src/db/db/dbDeepRegion.h b/src/db/db/dbDeepRegion.h index c2a9d4d2e..f18442fa2 100644 --- a/src/db/db/dbDeepRegion.h +++ b/src/db/db/dbDeepRegion.h @@ -81,6 +81,10 @@ public: virtual std::string to_string (size_t nmax) const; + virtual EdgePairsDelegate *cop_to_edge_pairs (db::CompoundRegionOperationNode &node); + virtual RegionDelegate *cop_to_region (db::CompoundRegionOperationNode &node); + virtual EdgesDelegate *cop_to_edges (db::CompoundRegionOperationNode &node); + virtual RegionDelegate *and_with (const Region &other) const; virtual RegionDelegate *not_with (const Region &other) const; virtual RegionDelegate *xor_with (const Region &other) const; @@ -132,6 +136,15 @@ protected: virtual void merged_semantics_changed (); virtual void min_coherence_changed (); + virtual EdgePairsDelegate *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; + virtual EdgePairsDelegate *run_single_polygon_check (db::edge_relation_type rel, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const; + virtual RegionDelegate *selected_interacting_generic (const Region &other, int mode, bool touching, bool inverse, size_t min_count, size_t max_count) const; + virtual RegionDelegate *selected_interacting_generic (const Edges &other, bool inverse, size_t min_count, size_t max_count) const; + virtual RegionDelegate *selected_interacting_generic (const Texts &other, bool inverse, size_t min_count, size_t max_count) const; + virtual RegionDelegate *pull_generic (const Region &other, int mode, bool touching) const; + virtual EdgesDelegate *pull_generic (const Edges &other) const; + virtual TextsDelegate *pull_generic (const Texts &other) const; + private: friend class DeepEdges; friend class DeepTexts; @@ -147,14 +160,6 @@ private: const DeepLayer &merged_deep_layer () const; DeepLayer and_or_not_with(const DeepRegion *other, bool and_op) const; std::pair and_and_not_with (const DeepRegion *other) const; - EdgePairsDelegate *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; - EdgePairsDelegate *run_single_polygon_check (db::edge_relation_type rel, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const; - virtual RegionDelegate *selected_interacting_generic (const Region &other, int mode, bool touching, bool inverse, size_t min_count, size_t max_count) const; - virtual RegionDelegate *selected_interacting_generic (const Edges &other, bool inverse, size_t min_count, size_t max_count) const; - virtual RegionDelegate *selected_interacting_generic (const Texts &other, bool inverse, size_t min_count, size_t max_count) const; - virtual RegionDelegate *pull_generic (const Region &other, int mode, bool touching) const; - virtual EdgesDelegate *pull_generic (const Edges &other) const; - virtual TextsDelegate *pull_generic (const Texts &other) const; DeepRegion *apply_filter (const PolygonFilterBase &filter) const; template OutputContainer *processed_impl (const polygon_processor &filter) const; diff --git a/src/db/db/dbEmptyRegion.cc b/src/db/db/dbEmptyRegion.cc index 70865b7a2..07dd1134d 100644 --- a/src/db/db/dbEmptyRegion.cc +++ b/src/db/db/dbEmptyRegion.cc @@ -96,6 +96,24 @@ EmptyRegion::processed_to_edge_pairs (const PolygonToEdgePairProcessorBase &) co return new EmptyEdgePairs (); } +EdgePairsDelegate * +EmptyRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &) +{ + return new EmptyEdgePairs (); +} + +RegionDelegate * +EmptyRegion::cop_to_region (db::CompoundRegionOperationNode &) +{ + return new EmptyRegion (); +} + +EdgesDelegate * +EmptyRegion::cop_to_edges (db::CompoundRegionOperationNode &) +{ + return new EmptyEdges (); +} + EdgePairsDelegate * EmptyRegion::width_check (db::Coord, bool, metrics_type, double, distance_type, distance_type, bool) const { diff --git a/src/db/db/dbEmptyRegion.h b/src/db/db/dbEmptyRegion.h index c2e290f47..df1125145 100644 --- a/src/db/db/dbEmptyRegion.h +++ b/src/db/db/dbEmptyRegion.h @@ -62,6 +62,10 @@ public: virtual Box bbox () const { return Box (); } + virtual EdgePairsDelegate *cop_to_edge_pairs (db::CompoundRegionOperationNode &node); + virtual RegionDelegate *cop_to_region (db::CompoundRegionOperationNode &node); + virtual EdgesDelegate *cop_to_edges (db::CompoundRegionOperationNode &node); + virtual EdgePairsDelegate *width_check (db::Coord, bool, metrics_type, double, distance_type, distance_type, bool) const; virtual EdgePairsDelegate *space_check (db::Coord, bool, metrics_type, double, distance_type, distance_type, bool) const; virtual EdgePairsDelegate *isolated_check (db::Coord, bool, metrics_type, double, distance_type, distance_type, bool) const; diff --git a/src/db/db/dbRegion.cc b/src/db/db/dbRegion.cc index 08dfc495c..beb2efa01 100644 --- a/src/db/db/dbRegion.cc +++ b/src/db/db/dbRegion.cc @@ -29,6 +29,8 @@ #include "dbDeepEdges.h" #include "dbFlatEdges.h" #include "dbPolygonTools.h" +#include "dbCompoundOperation.h" +#include "gsiClassBase.h" #include "tlGlobPattern.h" namespace db @@ -327,6 +329,41 @@ Region::flat_region () return region; } +EdgePairs +Region::cop_to_edge_pairs (db::CompoundRegionOperationNode &node) +{ + tl_assert (node.result_type () == db::CompoundRegionOperationNode::EdgePairs); + return EdgePairs (mp_delegate->cop_to_edge_pairs (node)); +} + +Region +Region::cop_to_region (db::CompoundRegionOperationNode &node) +{ + tl_assert (node.result_type () == db::CompoundRegionOperationNode::Region); + return Region (mp_delegate->cop_to_region (node)); +} + +Edges +Region::cop_to_edges (db::CompoundRegionOperationNode &node) +{ + tl_assert (node.result_type () == db::CompoundRegionOperationNode::Edges); + return Edges (mp_delegate->cop_to_edges (node)); +} + +tl::Variant +Region::cop (db::CompoundRegionOperationNode &node) +{ + if (node.result_type () == db::CompoundRegionOperationNode::EdgePairs) { + return tl::Variant::make_variant (new EdgePairs (mp_delegate->cop_to_edge_pairs (node))); + } else if (node.result_type () == db::CompoundRegionOperationNode::Edges) { + return tl::Variant::make_variant (new Edges (mp_delegate->cop_to_edges (node))); + } else if (node.result_type () == db::CompoundRegionOperationNode::Region) { + return tl::Variant::make_variant (new Region (mp_delegate->cop_to_region (node))); + } else { + return tl::Variant (); + } +} + Region & Region::size (coord_type d, unsigned int mode) { diff --git a/src/db/db/dbRegion.h b/src/db/db/dbRegion.h index 6f77123fb..8c0fc035e 100644 --- a/src/db/db/dbRegion.h +++ b/src/db/db/dbRegion.h @@ -41,6 +41,7 @@ class FlatRegion; class EmptyRegion; class DeepShapeStore; class TransformationReducer; +class CompoundRegionOperationNode; /** * @brief A region iterator @@ -607,6 +608,38 @@ public: return EdgePairs (mp_delegate->processed_to_edge_pairs (filter)); } + /** + * @brief Performs a compound operation rendering edge pairs + * + * The compound operation needs to feature edge pair output, e.g. + * node.result_type() needs to be EdgePairs. + */ + EdgePairs cop_to_edge_pairs (db::CompoundRegionOperationNode &node); + + /** + * @brief Performs a compound operation rendering a region + * + * The compound operation needs to feature region output, e.g. + * node.result_type() needs to be Region. + */ + Region cop_to_region (db::CompoundRegionOperationNode &node); + + /** + * @brief Performs a compound operation rendering edges + * + * The compound operation needs to feature region output, e.g. + * node.result_type() needs to be Edges. + */ + Edges cop_to_edges (db::CompoundRegionOperationNode &node); + + /** + * @brief A universal form of the compound operation + * + * The returned variant will be of the type requested by the + * compound operation node. + */ + tl::Variant cop (db::CompoundRegionOperationNode &node); + /** * @brief Applies a width check and returns EdgePairs which correspond to violation markers * diff --git a/src/db/db/dbRegionDelegate.h b/src/db/db/dbRegionDelegate.h index 39492c6b9..dcdf858a1 100644 --- a/src/db/db/dbRegionDelegate.h +++ b/src/db/db/dbRegionDelegate.h @@ -42,6 +42,7 @@ class RecursiveShapeIterator; class EdgeFilterBase; class EdgesDelegate; class EdgePairsDelegate; +class CompoundRegionOperationNode; /** * @brief A base class for polygon filters @@ -215,6 +216,10 @@ public: virtual perimeter_type perimeter (const db::Box &box) const = 0; virtual Box bbox () const = 0; + virtual EdgePairsDelegate *cop_to_edge_pairs (db::CompoundRegionOperationNode &node) = 0; + virtual RegionDelegate *cop_to_region (db::CompoundRegionOperationNode &node) = 0; + virtual EdgesDelegate *cop_to_edges (db::CompoundRegionOperationNode &node) = 0; + virtual EdgePairsDelegate *width_check (db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const = 0; virtual EdgePairsDelegate *space_check (db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const = 0; virtual EdgePairsDelegate *isolated_check (db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const = 0; diff --git a/src/db/db/dbRegionProcessors.h b/src/db/db/dbRegionProcessors.h index 6ed660358..16a73f933 100644 --- a/src/db/db/dbRegionProcessors.h +++ b/src/db/db/dbRegionProcessors.h @@ -328,12 +328,12 @@ private: * @brief Computes the Minkowsky sum between the polygons and the given object * The object can be Edge, Polygon, Box and std::vector */ -template +template class DB_PUBLIC_TEMPLATE minkowsky_sum_computation : public db::PolygonProcessorBase { public: - minkowsky_sum_computation (const Object &q) + minkowsky_sum_computation (const K &q) : m_q (q) { // .. nothing yet .. @@ -352,7 +352,7 @@ public: virtual bool wants_variants () const { return true; } private: - Object m_q; + K m_q; db::MagnificationAndOrientationReducer m_vars; }; diff --git a/src/db/db/dbShapeCollectionUtils.h b/src/db/db/dbShapeCollectionUtils.h index 4f3fc8f0b..c176bb30b 100644 --- a/src/db/db/dbShapeCollectionUtils.h +++ b/src/db/db/dbShapeCollectionUtils.h @@ -32,6 +32,7 @@ #include "dbCellVariants.h" #include "dbShapeCollection.h" #include "dbDeepShapeStore.h" +#include "tlObject.h" #include @@ -44,6 +45,7 @@ namespace db { */ template class DB_PUBLIC_TEMPLATE shape_collection_processor + : public tl::Object { public: /** diff --git a/src/db/db/gsiDeclDbCompoundOperation.cc b/src/db/db/gsiDeclDbCompoundOperation.cc new file mode 100644 index 000000000..086f8d8d3 --- /dev/null +++ b/src/db/db/gsiDeclDbCompoundOperation.cc @@ -0,0 +1,179 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2020 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "gsiDecl.h" + +#include "dbCompoundOperation.h" + +namespace gsi +{ + +static db::CompoundRegionOperationNode *new_primary () +{ + return new db::CompoundRegionOperationPrimaryNode (); +} + +static db::CompoundRegionOperationNode *new_secondary (db::Region *region) +{ + return new db::CompoundRegionOperationSecondaryNode (region); +} + +static db::CompoundRegionOperationNode *new_logical_boolean (db::CompoundRegionLogicalBoolOperationNode::LogicalOp op, bool invert, const std::vector &inputs) +{ + return new db::CompoundRegionLogicalBoolOperationNode (op, invert, inputs); +} + +static db::CompoundRegionOperationNode *new_geometrical_boolean (db::CompoundRegionGeometricalBoolOperationNode::GeometricalOp op, db::CompoundRegionOperationNode *a, db::CompoundRegionOperationNode *b) +{ + // @@@ is this correct? + if ((a->result_type () != db::CompoundRegionOperationNode::Region && a->result_type () != db::CompoundRegionOperationNode::Edges) || + (b->result_type () != db::CompoundRegionOperationNode::Region && b->result_type () != db::CompoundRegionOperationNode::Edges)) { + throw tl::Exception ("Inputs for geometrical booleans must be either of Region or Edges type"); + } + return new db::CompoundRegionGeometricalBoolOperationNode (op, a, b); +} + +static db::CompoundRegionOperationNode *new_interacting (db::CompoundRegionOperationNode *a, db::CompoundRegionOperationNode *b, bool inverse, size_t min_count, size_t max_count) +{ + // @@@ is this correct? + if (a->result_type () != db::CompoundRegionOperationNode::Region) { + throw tl::Exception ("Primary input for interaction compound operation must be of Region type"); + } + if (b->result_type () == db::CompoundRegionOperationNode::Region) { + return new db::CompoundRegionInteractOperationNode (a, b, 0, true, inverse, min_count, max_count); + } else if (b->result_type () == db::CompoundRegionOperationNode::Edges) { + return new db::CompoundRegionInteractWithEdgeOperationNode (a, b, 0, true, inverse, min_count, max_count); + } else { + throw tl::Exception ("Secondary input for interaction compound operation must be either of Region or Edges type"); + } +} + +static db::CompoundRegionOperationNode *new_overlapping (db::CompoundRegionOperationNode *a, db::CompoundRegionOperationNode *b, bool inverse, size_t min_count, size_t max_count) +{ + // @@@ is this correct? + if (a->result_type () != db::CompoundRegionOperationNode::Region) { + throw tl::Exception ("Primary input for interaction compound operation must be of Region type"); + } + if (b->result_type () == db::CompoundRegionOperationNode::Region) { + return new db::CompoundRegionInteractOperationNode (a, b, 0, false, inverse, min_count, max_count); + } else { + throw tl::Exception ("Secondary input for overlapping compound operation must be of Region type"); + } +} + +static db::CompoundRegionOperationNode *new_inside (db::CompoundRegionOperationNode *a, db::CompoundRegionOperationNode *b, bool inverse) +{ + // @@@ is this correct? + if (a->result_type () != db::CompoundRegionOperationNode::Region) { + throw tl::Exception ("Primary input for interaction compound operation must be of Region type"); + } + if (b->result_type () == db::CompoundRegionOperationNode::Region) { + return new db::CompoundRegionInteractOperationNode (a, b, -1, false, inverse); + } else { + throw tl::Exception ("Secondary input for inside compound operation must be of Region type"); + } +} + +static db::CompoundRegionOperationNode *new_outside (db::CompoundRegionOperationNode *a, db::CompoundRegionOperationNode *b, bool inverse) +{ + // @@@ is this correct? + if (a->result_type () != db::CompoundRegionOperationNode::Region) { + throw tl::Exception ("Primary input for interaction compound operation must be of Region type"); + } + if (b->result_type () == db::CompoundRegionOperationNode::Region) { + return new db::CompoundRegionInteractOperationNode (a, b, 1, false, inverse); + } else { + throw tl::Exception ("Secondary input for outside compound operation must be of Region type"); + } +} + +static db::CompoundRegionOperationNode *new_case (const std::vector &inputs) +{ + return new db::CompoundRegionLogicalCaseSelectOperationNode (false, inputs); +} + +// @@@ more ... +// CompoundRegionProcessingOperationNode with various processors +// CompoundRegionSizeOperationNode +// CompoundRegionToEdgeProcessingOperationNode +// CompoundRegionToEdgePairProcessingOperationNode +// CompoundRegionCheckOperationNode + + +Class decl_CompoundRegionOperationNode ("db", "CompoundRegionOperationNode", + gsi::constructor ("new_primary", &new_primary, + "@brief Creates a node object representing the primary input" + ) + + gsi::constructor ("new_secondary", &new_secondary, gsi::arg ("region"), + "@brief Creates a node object representing the secondary input from the given region" + ) + + gsi::constructor ("new_logical_boolean", &new_logical_boolean, gsi::arg ("op"), gsi::arg ("invert"), gsi::arg ("inputs"), + "@brief Creates a node representing a logical boolean operation between the inputs.\n" + "\n" + "@@@ TODO.\n" + ) + + gsi::constructor ("new_geometrical_boolean", &new_geometrical_boolean, gsi::arg ("op"), gsi::arg ("a"), gsi::arg ("b"), + "@brief Creates a node representing a geometrical boolean operation between the inputs.\n" + "\n" + "@@@ TODO.\n" + ) + + gsi::constructor ("new_interacting", &new_interacting, gsi::arg ("a"), gsi::arg ("b"), gsi::arg ("inverse", false), gsi::arg ("min_count", size_t (0)), gsi::arg ("max_count", std::numeric_limits::max (), "unlimited"), + "@brief Creates a node representing an interacting selection operation between the inputs.\n" + "\n" + "@@@ TODO.\n" + ) + + gsi::constructor ("new_overlapping", &new_overlapping, gsi::arg ("a"), gsi::arg ("b"), gsi::arg ("inverse", false), gsi::arg ("min_count", size_t (0)), gsi::arg ("max_count", std::numeric_limits::max (), "unlimited"), + "@brief Creates a node representing an overlapping selection operation between the inputs.\n" + "\n" + "@@@ TODO.\n" + ) + + gsi::constructor ("new_inside", &new_inside, gsi::arg ("a"), gsi::arg ("b"), gsi::arg ("inverse", false), + "@brief Creates a node representing an inside selection operation between the inputs.\n" + "\n" + "@@@ TODO.\n" + ) + + gsi::constructor ("new_outside", &new_outside, gsi::arg ("a"), gsi::arg ("b"), gsi::arg ("inverse", false), + "@brief Creates a node representing an outside selection operation between the inputs.\n" + "\n" + "@@@ TODO.\n" + ) + + gsi::constructor ("new_case", &new_case, gsi::arg ("inputs"), + "@brief Creates a 'switch ladder' (case statement) compound operation node.\n" + "\n" + "@@@ TODO.\n" + ) + + method ("description=", &db::CompoundRegionOperationNode::set_description, gsi::arg ("d"), + "@brief Sets the description for this node" + ) + + method ("description", &db::CompoundRegionOperationNode::description, + "@brief Gets the description for this node" + ) + + method ("result_type", &db::CompoundRegionOperationNode::result_type, + "@brief Gets the result type of this node" + ), + "@brief A base class for compound operations\n" + "\n" + "This class has been introduced in version 0.27." +); + +} +