diff --git a/src/db/db/dbAsIfFlatEdgePairs.cc b/src/db/db/dbAsIfFlatEdgePairs.cc index a84f268c9..7803bbb23 100644 --- a/src/db/db/dbAsIfFlatEdgePairs.cc +++ b/src/db/db/dbAsIfFlatEdgePairs.cc @@ -284,5 +284,17 @@ AsIfFlatEdgePairs::insert_into (Layout *layout, db::cell_index_type into_cell, u } } +void +AsIfFlatEdgePairs::insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const +{ + // improves performance when inserting an original layout into the same layout + db::LayoutLocker locker (layout); + + db::Shapes &shapes = layout->cell (into_cell).shapes (into_layer); + for (EdgePairsIterator e (begin ()); ! e.at_end (); ++e) { + shapes.insert (e->to_simple_polygon (enl)); + } +} + } diff --git a/src/db/db/dbAsIfFlatEdgePairs.h b/src/db/db/dbAsIfFlatEdgePairs.h index 4dae9954e..b8a292f44 100644 --- a/src/db/db/dbAsIfFlatEdgePairs.h +++ b/src/db/db/dbAsIfFlatEdgePairs.h @@ -69,6 +69,7 @@ public: virtual bool less (const EdgePairs &other) const; virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const; + virtual void insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const; protected: void update_bbox (const db::Box &box); diff --git a/src/db/db/dbDeepEdgePairs.cc b/src/db/db/dbDeepEdgePairs.cc index 62f95a4f2..123c72050 100644 --- a/src/db/db/dbDeepEdgePairs.cc +++ b/src/db/db/dbDeepEdgePairs.cc @@ -327,4 +327,10 @@ void DeepEdgePairs::insert_into (Layout *layout, db::cell_index_type into_cell, m_deep_layer.insert_into (layout, into_cell, into_layer); } +void DeepEdgePairs::insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const +{ + m_deep_layer.insert_into_as_polygons (layout, into_cell, into_layer, enl); +} + + } diff --git a/src/db/db/dbDeepEdgePairs.h b/src/db/db/dbDeepEdgePairs.h index 52210ccc0..34360ea86 100644 --- a/src/db/db/dbDeepEdgePairs.h +++ b/src/db/db/dbDeepEdgePairs.h @@ -78,6 +78,7 @@ public: virtual bool less (const EdgePairs &other) const; virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const; + virtual void insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const; const DeepLayer &deep_layer () const { diff --git a/src/db/db/dbDeepShapeStore.cc b/src/db/db/dbDeepShapeStore.cc index fa4f9d355..a3d869c4a 100644 --- a/src/db/db/dbDeepShapeStore.cc +++ b/src/db/db/dbDeepShapeStore.cc @@ -146,6 +146,13 @@ DeepLayer::insert_into (db::Layout *into_layout, db::cell_index_type into_cell, const_cast (mp_store.get ())->insert (*this, into_layout, into_cell, into_layer); } +void +DeepLayer::insert_into_as_polygons (db::Layout *into_layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const +{ + check_dss (); + const_cast (mp_store.get ())->insert_as_polygons (*this, into_layout, into_cell, into_layer, enl); +} + bool DeepLayer::operator< (const DeepLayer &other) const { if (mp_store.get () != other.mp_store.get ()) { @@ -596,5 +603,38 @@ DeepShapeStore::insert (const DeepLayer &deep_layer, db::Layout *into_layout, db db::copy_shapes (*into_layout, source_layout, trans, source_cells, cm.table (), lm); } +void +DeepShapeStore::insert_as_polygons (const DeepLayer &deep_layer, db::Layout *into_layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) +{ + // prepare a temporary layer with the polygons + DeepLayer tmp = deep_layer.derived (); + + db::Layout &layout = const_cast (deep_layer.layout ()); + + for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) { + + db::Shapes &out = c->shapes (tmp.layer ()); + for (db::Shapes::shape_iterator s = c->shapes (deep_layer.layer ()); ! s.at_end (); ++s) { + + if (s->is_edge_pair ()) { + + out.insert (s->edge_pair ().to_simple_polygon (enl)); + + } else if (s->is_path () || s->is_polygon () || s->is_box ()) { + + db::Polygon poly; + s->polygon (poly); + out.insert (poly); + + } + + } + + } + + // and insert this one + insert (tmp, into_layout, into_cell, into_layer); +} + } diff --git a/src/db/db/dbDeepShapeStore.h b/src/db/db/dbDeepShapeStore.h index b76d44510..cc6df29e1 100644 --- a/src/db/db/dbDeepShapeStore.h +++ b/src/db/db/dbDeepShapeStore.h @@ -136,6 +136,12 @@ public: */ void insert_into (Layout *into_layout, db::cell_index_type into_cell, unsigned int into_layer) const; + /** + * @brief Inserts the edge pairs layer into the given layout, starting from the given cell and into the given layer + * The edge pairs are converted to polygons with the given enlargement. + */ + void insert_into_as_polygons (db::Layout *into_layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const; + /** * @brief Creates a derived new deep layer * Derived layers use the same layout and context, but are initially @@ -280,6 +286,13 @@ public: */ void insert (const DeepLayer &layer, db::Layout *into_layout, db::cell_index_type into_cell, unsigned int into_layer); + /** + * @brief Inserts the deep layer's edge pairs into some target layout + * + * The edge pairs are converted to polygons with the given enlargement. + */ + void insert_as_polygons (const DeepLayer &deep_layer, db::Layout *into_layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl); + /** * @brief Gets the cell mapping suitable to returning a layout from the deep shape store into the original layout hierarchy * diff --git a/src/db/db/dbEdgePairs.h b/src/db/db/dbEdgePairs.h index dc48c3e61..ca8688d96 100644 --- a/src/db/db/dbEdgePairs.h +++ b/src/db/db/dbEdgePairs.h @@ -662,6 +662,16 @@ public: return mp_delegate->insert_into (layout, into_cell, into_layer); } + /** + * @brief Inserts the edge pair collection into the given layout, cell and layer as polygons with the given enlargement + * If the edge pair collection is a hierarchical region, the hierarchy is copied into the + * layout's hierarchy. + */ + void insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const + { + return mp_delegate->insert_into_as_polygons (layout, into_cell, into_layer, enl); + } + private: EdgePairsDelegate *mp_delegate; diff --git a/src/db/db/dbEdgePairsDelegate.h b/src/db/db/dbEdgePairsDelegate.h index 459861d0c..42fd86522 100644 --- a/src/db/db/dbEdgePairsDelegate.h +++ b/src/db/db/dbEdgePairsDelegate.h @@ -110,6 +110,7 @@ public: virtual bool less (const EdgePairs &other) const = 0; virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const = 0; + virtual void insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const = 0; protected: const std::string &progress_desc () const diff --git a/src/db/db/dbEmptyEdgePairs.h b/src/db/db/dbEmptyEdgePairs.h index e39a802e7..428cab421 100644 --- a/src/db/db/dbEmptyEdgePairs.h +++ b/src/db/db/dbEmptyEdgePairs.h @@ -75,6 +75,7 @@ public: virtual bool less (const EdgePairs &other) const; virtual void insert_into (Layout *, db::cell_index_type, unsigned int) const { } + virtual void insert_into_as_polygons (Layout *, db::cell_index_type, unsigned int, db::Coord) const { } private: EmptyEdgePairs &operator= (const EmptyEdgePairs &other); diff --git a/src/db/db/dbFlatEdgePairs.cc b/src/db/db/dbFlatEdgePairs.cc index 4af33fb87..e4a8d50f8 100644 --- a/src/db/db/dbFlatEdgePairs.cc +++ b/src/db/db/dbFlatEdgePairs.cc @@ -180,6 +180,15 @@ const db::RecursiveShapeIterator *FlatEdgePairs::iter () const return 0; } +void +FlatEdgePairs::insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const +{ + db::Shapes &out = layout->cell (into_cell).shapes (into_layer); + for (EdgePairsIterator p (begin ()); ! p.at_end (); ++p) { + out.insert (p->to_simple_polygon (enl)); + } +} + void FlatEdgePairs::insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const { diff --git a/src/db/db/dbFlatEdgePairs.h b/src/db/db/dbFlatEdgePairs.h index b1d5cfef6..bb21fb64f 100644 --- a/src/db/db/dbFlatEdgePairs.h +++ b/src/db/db/dbFlatEdgePairs.h @@ -114,6 +114,7 @@ public: virtual const db::RecursiveShapeIterator *iter () const; virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const; + virtual void insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const; void insert (const db::EdgePair &edge_pair); void insert (const db::Shape &shape); diff --git a/src/db/db/gsiDeclDbEdgePairs.cc b/src/db/db/gsiDeclDbEdgePairs.cc index 7c940734c..c3ef30cf7 100644 --- a/src/db/db/gsiDeclDbEdgePairs.cc +++ b/src/db/db/gsiDeclDbEdgePairs.cc @@ -26,6 +26,7 @@ #include "dbEdgePairs.h" #include "dbEdges.h" #include "dbRegion.h" +#include "dbDeepEdgePairs.h" namespace gsi { @@ -158,6 +159,11 @@ static void insert_e (db::EdgePairs *e, const db::EdgePairs &a) } } +static bool is_deep (const db::EdgePairs *ep) +{ + return dynamic_cast (ep->delegate ()) != 0; +} + Class decl_EdgePairs ("db", "EdgePairs", constructor ("new", &new_v, "@brief Default constructor\n" @@ -225,6 +231,22 @@ Class decl_EdgePairs ("db", "EdgePairs", "\n" "This constructor has been introduced in version 0.26." ) + + method ("insert_into", &db::EdgePairs::insert_into, gsi::arg ("layout"), gsi::arg ("cell_index"), gsi::arg ("layer"), + "@brief Inserts this edge pairs into the given layout, below the given cell and into the given layer.\n" + "If the edge pair collection is a hierarchical one, a suitable hierarchy will be built below the top cell or " + "and existing hierarchy will be reused.\n" + "\n" + "This method has been introduced in version 0.26." + ) + + method ("insert_into_as_polygons", &db::EdgePairs::insert_into_as_polygons, gsi::arg ("layout"), gsi::arg ("cell_index"), gsi::arg ("layer"), gsi::arg ("e"), + "@brief Inserts this edge pairs into the given layout, below the given cell and into the given layer.\n" + "If the edge pair collection is a hierarchical one, a suitable hierarchy will be built below the top cell or " + "and existing hierarchy will be reused.\n" + "\n" + "The edge pairs will be converted to polygons with the enlargement value given be 'e'.\n" + "\n" + "This method has been introduced in version 0.26." + ) + method ("insert", (void (db::EdgePairs::*) (const db::Edge &, const db::Edge &)) &db::EdgePairs::insert, "@brief Inserts an edge pair into the collection\n" "@args first, second\n" @@ -233,6 +255,11 @@ Class decl_EdgePairs ("db", "EdgePairs", "@brief Inserts an edge pair into the collection\n" "@args edge_pair\n" ) + + method_ext ("is_deep?", &is_deep, + "@brief Returns true if the edge pair collection is a deep (hierarchical) one\n" + "\n" + "This method has been added in version 0.26." + ) + method ("+", &db::EdgePairs::operator+, "@brief Returns the combined edge pair collection of self and the other one\n" "\n" diff --git a/src/db/db/gsiDeclDbEdges.cc b/src/db/db/gsiDeclDbEdges.cc index 2177dca76..d6e6ea66f 100644 --- a/src/db/db/gsiDeclDbEdges.cc +++ b/src/db/db/gsiDeclDbEdges.cc @@ -25,6 +25,7 @@ #include "dbDeepShapeStore.h" #include "dbEdges.h" +#include "dbDeepEdges.h" #include "dbRegion.h" #include "dbLayoutUtils.h" @@ -373,6 +374,11 @@ static void insert_s (db::Edges *e, const db::Shapes &a) insert_st (e, a, db::UnitTrans ()); } +static bool is_deep (const db::Edges *e) +{ + return dynamic_cast (e->delegate ()) != 0; +} + Class dec_Edges ("db", "Edges", constructor ("new", &new_v, "@brief Default constructor\n" @@ -495,6 +501,13 @@ Class dec_Edges ("db", "Edges", "r = RBA::Edges::new(layout.begin_shapes(cell, layer), dss, RBA::ICplxTrans::new(layout.dbu / dbu), false)\n" "@/code\n" ) + + method ("insert_into", &db::Edges::insert_into, gsi::arg ("layout"), gsi::arg ("cell_index"), gsi::arg ("layer"), + "@brief Inserts this edge collection into the given layout, below the given cell and into the given layer.\n" + "If the edge collection is a hierarchical one, a suitable hierarchy will be built below the top cell or " + "and existing hierarchy will be reused.\n" + "\n" + "This method has been introduced in version 0.26." + ) + method_ext ("with_length", with_length1, gsi::arg ("length"), gsi::arg ("inverse"), "@brief Filter the edges by length\n" "Filters the edges in the edge collection by length. If \"inverse\" is false, only " @@ -1377,6 +1390,11 @@ Class dec_Edges ("db", "Edges", "This method returns all edges in self which can not be found in the other edge collection with exactly the same " "geometry." ) + + method_ext ("is_deep?", &is_deep, + "@brief Returns true if the edge collection is a deep (hierarchical) one\n" + "\n" + "This method has been added in version 0.26." + ) + method ("is_merged?", &db::Edges::is_merged, "@brief Returns true if the edge collection is merged\n" "If the region is merged, coincident edges have been merged into single edges. You can ensure merged state " diff --git a/src/db/db/gsiDeclDbRegion.cc b/src/db/db/gsiDeclDbRegion.cc index 5b7c47b31..54820cd39 100644 --- a/src/db/db/gsiDeclDbRegion.cc +++ b/src/db/db/gsiDeclDbRegion.cc @@ -23,6 +23,7 @@ #include "gsiDecl.h" #include "dbRegion.h" +#include "dbDeepRegion.h" #include "dbPolygonTools.h" #include "dbLayoutUtils.h" #include "dbShapes.h" @@ -715,6 +716,11 @@ static Container *decompose_trapezoids (const db::Region *r, int mode) return shapes.release (); } +static bool is_deep (const db::Region *region) +{ + return dynamic_cast (region->delegate ()) != 0; +} + // provided by gsiDeclDbPolygon.cc: int td_simple (); int po_any (); @@ -832,6 +838,13 @@ Class decl_Region ("db", "Region", "\n" "This method has been introduced in version 0.25." ) + + method ("insert_into", &db::Region::insert_into, gsi::arg ("layout"), gsi::arg ("cell_index"), gsi::arg ("layer"), + "@brief Inserts this region into the given layout, below the given cell and into the given layer.\n" + "If the region is a hierarchical one, a suitable hierarchy will be built below the top cell or " + "and existing hierarchy will be reused.\n" + "\n" + "This method has been introduced in version 0.26." + ) + factory_ext ("texts", &texts, gsi::arg ("expr", std::string ("*")), gsi::arg ("as_pattern", true), "@hide\n" "This method is provided for DRC implementation only." @@ -2316,6 +2329,11 @@ Class decl_Region ("db", "Region", "@brief Return the bounding box of the region\n" "The bounding box is the box enclosing all points of all polygons.\n" ) + + method_ext ("is_deep?", &is_deep, + "@brief Returns true if the region is a deep (hierarchical) one\n" + "\n" + "This method has been added in version 0.26." + ) + method ("is_merged?", &db::Region::is_merged, "@brief Returns true if the region is merged\n" "If the region is merged, polygons will not touch or overlap. You can ensure merged state " diff --git a/src/drc/drc/built-in-macros/drc.lym b/src/drc/drc/built-in-macros/drc.lym index 5bdb3de1b..786a4666e 100644 --- a/src/drc/drc/built-in-macros/drc.lym +++ b/src/drc/drc/built-in-macros/drc.lym @@ -2280,6 +2280,15 @@ CODE @data.is_a?(RBA::EdgePairs) end + # %DRC% + # @name is_deep? + # @brief Returns true, if the layer is a deep (hierarchical) layer + # @synopsis layer.is_deep? + + def is_deep? + @data.is_deep? + end + # %DRC% # @name area # @brief Returns the total area of the polygons in the region @@ -2347,6 +2356,20 @@ CODE @engine._cmd(@data, :length) * @engine.dbu.to_f end + # %DRC% + # @name flatten + # @brief Flattens the layer + # @synopsis layer.flatten + # + # If the layer already is a flat one, this method does nothing. + # If the layer is a hierarchical layer (an original layer or + # a derived layer in deep mode), this method will convert it + # to a flat collection of polygons, edges or edge pairs. + + def flatten + @engine._cmd(@data, :flatten) + end + # %DRC% # @name is_merged? # @brief Returns true, if the polygons of the layer are merged @@ -3596,13 +3619,15 @@ CODE @output_layout = nil @output_rdb = nil @output_rdb_file = nil - @output_rdb_cell_id = nil + @output_rdb_cell = nil @used_output_layers = {} @output_layers = [] @vnum = 1 @layout_sources = {} @lnum = 1 @log_file = nil + @dss = nil + @deep = false @verbose = false @@ -3821,11 +3846,14 @@ CODE # # In tiling mode, the memory requirements are usually smaller (depending on the # choice of the tile size) and multi-CPU support is enabled (see \threads). - # To disable tiling mode use \flat. + # To disable tiling mode use \flat or \deep. + # + # Tiling mode will disable deep mode (see \deep). def tiles(tx, ty = nil) @tx = tx.to_f @ty = (ty || tx).to_f + @deep = false end # %DRC% @@ -3837,6 +3865,38 @@ CODE @tx != nil end + # %DRC% + # @name deep + # @brief Enters deep (hierarchical) mode + # @synopsis deep + # + # In deep mode, the operations will be performed in a hierarchical fashion. + # Sometimes this reduces the time and memory required for an operation, but this + # will also add some overhead for the hierarchical analysis. + # + # "deepness" is a property of layers. Layers created with "input" while in + # deep mode carry hierarchy. Operations involving such layers at the only + # or the first argument are carried out in hierarchical mode. + # + # Hierarchical mode has some more implications, like "merged_semantics" being + # implied always. Sometimes cell variants will be created. + # + # Deep mode can be cancelled with \tiles or \flat. + + def deep + @deep = true + @tx = @ty = nil + end + + # %DRC% + # @name is_deep? + # @brief Returns true, if in deep mode + # @synopsis is_deep? + + def is_deep? + @deep + end + # %DRC% # @name tile_borders # @brief Specifies a minimum tile border @@ -3878,6 +3938,7 @@ CODE def flat @tx = @ty = nil + @deep = false end # %DRC% @@ -4131,7 +4192,7 @@ CODE cn || raise("No cell name specified - either the source was not specified before 'report' or there is no default source. In the latter case, specify a cell name as the third parameter of 'report'") - @output_rdb_cell_id = @output_rdb.create_cell(cn).rdb_id + @output_rdb_cell = @output_rdb.create_cell(cn) @output_rdb.generator = $0 @output_rdb.top_cell_name = cn @output_rdb.description = description @@ -4153,15 +4214,15 @@ CODE if @output_rdb - cell_id = nil + cell = nil @output_rdb.each_cell do |c| if c.name == cellname - cell_id = c.rdb_id + cell = c end end - cell_id ||= @output_rdb.create_cell(cellname).rdb_id - @output_rdb_cell_id = cell_id + cell ||= @output_rdb.create_cell(cellname) + @output_rdb_cell = cell else @@ -4716,7 +4777,13 @@ CODE sf = layout.dbu / self.dbu if (sf - 1.0).abs > 1e-6 + if @deep + raise("DBU scaling (" + ("%.12g" % layout.dbu) + " to " + ("%.12g" % self.dbu) + ") is not supported in deep mode currently") + end r = RBA::Region::new(iter, RBA::ICplxTrans::new(sf.to_f)) + elsif @deep + @dss ||= RBA::DeepShapeStore::new + r = RBA::Region::new(iter, @dss) else r = RBA::Region::new(iter) end @@ -4750,9 +4817,9 @@ CODE args[1] && cat.description = args[1] if data.is_a?(RBA::RecursiveShapeIterator) - @output_rdb.create_items(@output_rdb_cell_id, cat.rdb_id, data) + cat.scan_shapes(data) else - @output_rdb.create_items(@output_rdb_cell_id, cat.rdb_id, RBA::CplxTrans::new(self.dbu), data) + cat.scan_collection(@output_rdb_cell, RBA::CplxTrans::new(self.dbu), data) end else @@ -4793,40 +4860,59 @@ CODE li = output.insert_layer(info) end - tmp = li + # make sure the output has the right database unit + output.dbu = self.dbu - begin + if data.is_deep? + # mark the layer as used if !@used_output_layers[li] @output_layers.push(li) - # Note: to avoid issues with output onto the input layer, we - # output to a temp layer and later swap both. The simple implementation - # did a clear here and the effect of that was that the data potentially - # got invalidated. - tmp = output.insert_layer(RBA::LayerInfo::new) @used_output_layers[li] = true end - # make sure the output has the right database unit - output.dbu = self.dbu - # insert the data into the output layer if data.is_a?(RBA::EdgePairs) - output_cell.shapes(tmp).insert_as_polygons(data, 1) + data.insert_into_as_polygons(output, output_cell.cell_index, li, 1) else - output_cell.shapes(tmp).insert(data) + data.insert_into(output, output_cell.cell_index, li) end - # make the temp layer the output layer - if tmp != li - output.swap_layers(tmp, li) + else + + tmp = li + + begin + + if !@used_output_layers[li] + @output_layers.push(li) + # Note: to avoid issues with output onto the input layer, we + # output to a temp layer and later swap both. The simple implementation + # did a clear here and the effect of that was that the data potentially + # got invalidated. + tmp = output.insert_layer(RBA::LayerInfo::new) + @used_output_layers[li] = true + end + + # insert the data into the output layer + if data.is_a?(RBA::EdgePairs) + output_cell.shapes(tmp).insert_as_polygons(data, 1) + else + output_cell.shapes(tmp).insert(data) + end + + # make the temp layer the output layer + if tmp != li + output.swap_layers(tmp, li) + end + + ensure + # clean up the original layer if requested + if tmp != li + output.delete_layer(tmp) + end end - ensure - # clean up the original layer if requested - if tmp != li - output.delete_layer(tmp) - end end end diff --git a/src/rdb/rdb/gsiDeclRdb.cc b/src/rdb/rdb/gsiDeclRdb.cc index df2f8645f..16cee465b 100644 --- a/src/rdb/rdb/gsiDeclRdb.cc +++ b/src/rdb/rdb/gsiDeclRdb.cc @@ -317,7 +317,7 @@ Class decl_RdbCategory ("rdb", "RdbCategory", "\n" "This method has been introduced in version 0.23. The flat mode argument has been added in version 0.26.\n" ) + - gsi::method_ext ("scan_region", &scan_region, gsi::arg ("cell"), gsi::arg ("trans"), gsi::arg ("region"), gsi::arg ("flat", false), + gsi::method_ext ("scan_collection", &scan_region, gsi::arg ("cell"), gsi::arg ("trans"), gsi::arg ("region"), gsi::arg ("flat", false), "@brief Turns the given region into a hierarchical or flat report database\n" "The exact behavior depends on the nature of the region. If the region is a hierarchical (original or deep) region " "and the 'flat' argument is false, this method will produce a hierarchical report database in the given category. " @@ -331,15 +331,15 @@ Class decl_RdbCategory ("rdb", "RdbCategory", "\n" "This method has been introduced in version 0.26.\n" ) + - gsi::method_ext ("scan_edges", &scan_edges, gsi::arg ("cell"), gsi::arg ("trans"), gsi::arg ("edges"), gsi::arg ("flat", false), + gsi::method_ext ("scan_collection", &scan_edges, gsi::arg ("cell"), gsi::arg ("trans"), gsi::arg ("edges"), gsi::arg ("flat", false), "@brief Turns the given edge collection into a hierarchical or flat report database\n" - "This method behaves like the \\scan_region method, except that is accepts an edge collection.\n" + "This a another flavour of \\scan_collection accepting an edge collection.\n" "\n" "This method has been introduced in version 0.26.\n" ) + - gsi::method_ext ("scan_edge_pairs", &scan_edge_pairs, gsi::arg ("cell"), gsi::arg ("trans"), gsi::arg ("edge_pairs"), gsi::arg ("flat", false), + gsi::method_ext ("scan_collection", &scan_edge_pairs, gsi::arg ("cell"), gsi::arg ("trans"), gsi::arg ("edge_pairs"), gsi::arg ("flat", false), "@brief Turns the given edge pair collection into a hierarchical or flat report database\n" - "This method behaves like the \\scan_region method, except that is accepts an edge pair collection.\n" + "This a another flavour of \\scan_collection accepting an edge pair collection.\n" "\n" "This method has been introduced in version 0.26.\n" ) + diff --git a/src/rdb/rdb/rdb.cc b/src/rdb/rdb/rdb.cc index 2fe130fa1..e715462a5 100644 --- a/src/rdb/rdb/rdb.cc +++ b/src/rdb/rdb/rdb.cc @@ -279,6 +279,12 @@ ValueBase::create_from_shape (const db::Shape &shape, const db::CplxTrans &trans shape.edge (edge); return new rdb::Value (edge.transformed (trans)); + } else if (shape.is_edge_pair ()) { + + db::EdgePair edge_pair; + shape.edge_pair (edge_pair); + return new rdb::Value (edge_pair.transformed (trans)); + } else { return 0; } diff --git a/src/rdb/rdb/rdbUtils.cc b/src/rdb/rdb/rdbUtils.cc index bd905d100..9c50609c8 100644 --- a/src/rdb/rdb/rdbUtils.cc +++ b/src/rdb/rdb/rdbUtils.cc @@ -103,6 +103,10 @@ public: virtual void begin (const db::RecursiveShapeIterator *iter) { + if (! iter->top_cell () || ! iter->layout ()) { + return; + } + db::cell_index_type ci = iter->top_cell ()->cell_index (); const rdb::Cell *rdb_cell = cell_for_id (iter->layout (), ci); diff --git a/testdata/ruby/rdbTest.rb b/testdata/ruby/rdbTest.rb index 6ff765ce9..975f1155f 100644 --- a/testdata/ruby/rdbTest.rb +++ b/testdata/ruby/rdbTest.rb @@ -793,7 +793,7 @@ class RDB_TestClass < TestBase rdb = RBA::ReportDatabase.new("neu") cat = rdb.create_category("l1") r = RBA::Region::new(c1.begin_shapes_rec(l1)) - cat.scan_region(rdb.create_cell("TOP"), RBA::CplxTrans::new(0.001), r) # hierarchical scan + cat.scan_collection(rdb.create_cell("TOP"), RBA::CplxTrans::new(0.001), r) # hierarchical scan assert_equal(cat.num_items, 3) cn = [] rdb.each_cell { |c| cn << c.to_s_test } @@ -805,7 +805,7 @@ class RDB_TestClass < TestBase rdb = RBA::ReportDatabase.new("neu") cat = rdb.create_category("l1") r = RBA::Region::new(c1.begin_shapes_rec(l1)) - cat.scan_region(rdb.create_cell("TOP"), RBA::CplxTrans::new(0.001), r, true) # flat scan + cat.scan_collection(rdb.create_cell("TOP"), RBA::CplxTrans::new(0.001), r, true) # flat scan assert_equal(cat.num_items, 3) cn = [] rdb.each_cell { |c| cn << c.to_s_test } @@ -817,7 +817,7 @@ class RDB_TestClass < TestBase rdb = RBA::ReportDatabase.new("neu") cat = rdb.create_category("l1") r = RBA::Region::new(c1.begin_shapes_rec(l1)).merged - cat.scan_region(rdb.create_cell("TOP"), RBA::CplxTrans::new(0.001), r, true) # flat scan + cat.scan_collection(rdb.create_cell("TOP"), RBA::CplxTrans::new(0.001), r, true) # flat scan assert_equal(cat.num_items, 1) cn = [] rdb.each_cell { |c| cn << c.to_s_test }