diff --git a/src/db/db/db.pro b/src/db/db/db.pro index 62e31b56a..ff156a235 100644 --- a/src/db/db/db.pro +++ b/src/db/db/db.pro @@ -135,7 +135,8 @@ SOURCES = \ dbEmptyEdgePairs.cc \ dbFlatEdgePairs.cc \ dbOriginalLayerEdgePairs.cc \ - dbEdgePairsDelegate.cc + dbEdgePairsDelegate.cc \ + dbDeepShapeStore.cc HEADERS = \ dbArray.h \ @@ -240,7 +241,8 @@ HEADERS = \ dbEmptyEdgePairs.h \ dbFlatEdgePairs.h \ dbOriginalLayerEdgePairs.h \ - dbEdgePairsDelegate.h + dbEdgePairsDelegate.h \ + dbDeepShapeStore.h !equals(HAVE_QT, "0") { diff --git a/src/db/db/dbAsIfFlatEdges.cc b/src/db/db/dbAsIfFlatEdges.cc index a97bb9fa9..2b709189a 100644 --- a/src/db/db/dbAsIfFlatEdges.cc +++ b/src/db/db/dbAsIfFlatEdges.cc @@ -781,7 +781,7 @@ EdgesDelegate * AsIfFlatEdges::boolean (const Edges *other, EdgeBoolOp op) const { std::auto_ptr output (new FlatEdges (true)); - EdgeBooleanClusterCollector cluster_collector (output.get (), op); + EdgeBooleanClusterCollector cluster_collector (&output->raw_edges (), op); db::box_scanner scanner (report_progress (), progress_desc ()); scanner.reserve (size () + (other ? other->size () : 0)); diff --git a/src/db/db/dbDeepShapeStore.cc b/src/db/db/dbDeepShapeStore.cc new file mode 100644 index 000000000..e51bd5a3a --- /dev/null +++ b/src/db/db/dbDeepShapeStore.cc @@ -0,0 +1,24 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2018 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 + +*/ + + +// ... diff --git a/src/db/db/dbDeepShapeStore.h b/src/db/db/dbDeepShapeStore.h new file mode 100644 index 000000000..2a32c2439 --- /dev/null +++ b/src/db/db/dbDeepShapeStore.h @@ -0,0 +1,122 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2018 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 + +*/ + + +#ifndef HDR_dbDeepShapeStore +#define HDR_dbDeepShapeStore + +#include "dbCommon.h" + +#include "tlObject.h" +#include "dbLayout.h" +#include "dbRecursiveShapeIterator.h" + +namespace db { + +class DeepShapeStore; + +/** + * @brief Represents a shape collection from the deep shape store + * + * This is a lightweight class pointing into the deep shape store. + * DeepLayer objects are issued by the DeepShapeStore class. + */ +class DB_PUBLIC DeepLayer +{ +public: + /** + * @brief Destructor + */ + ~DeepLayer (); + + /** + * @brief Copy constructor + */ + DeepLayer (const DeepLayer &other); + + /** + * @brief Assignment + */ + DeepLayer &operator= (const DeepLayer &other); + + /** + * @brief Gets the layout object + * + * The return value is guaranteed to be non-null. + */ + db::Layout *layout (); + + /** + * @brief Gets the layer + */ + unsigned int layer () const + { + return m_layer; + } + +private: + friend class DeepShapeStore; + + /** + * @brief The constructor + */ + DeepLayer (DeepShapeStore *store, unsigned int layout, unsigned int layer); + + unsigned int layout () const { return m_layout; } + unsigned int layer () const { return m_layer; } + + tl::weak_ptr mp_store; + unsigned int m_layout; + unsigned int m_layer; +}; + +/** + * @brief The "deep shape store" is a working model for the hierarchical ("deep") processor + * + * The deep shape store keep temporary data for the deep shape processor. + * It mainly consists of layout objects holding the hierarchy trees and layers + * for the actual shapes. + * + * The deep shape store provides the basis for working with deep regions. On preparation, + * shapes are copied into the deep shape store. After fininishing, the shapes are copied + * back into the original layout. The deep shape store provides the methods and + * algorithms for doing the preparation and transfer. + */ +class DB_PUBLIC DeepShapeStore + : public tl::Object +{ +public: + /** + * @brief The default constructor + */ + DeepShapeStore (); + +private: + // no copying + DeepShapeStore (const DeepShapeStore &); + DeepShapeStore &operator= (const DeepShapeStore &); +}; + +} + +#endif + diff --git a/src/db/db/dbEdgePairs.h b/src/db/db/dbEdgePairs.h index 55b14bd8b..93b9efa1a 100644 --- a/src/db/db/dbEdgePairs.h +++ b/src/db/db/dbEdgePairs.h @@ -493,14 +493,24 @@ public: /** * @brief Returns the nth edge pair * - * This operation is only cheap if "has_valid_edge_pairs" is true. Otherwise, the - * complexity is O(n). + * This operation is available only for flat regions - i.e. such for which + * "has_valid_edge_pairs" is true. */ const db::EdgePair *nth (size_t n) const { return mp_delegate->nth (n); } + /** + * @brief Forces flattening of the edge pair collection + * + * This method will turn any edge pair collection into a flat one. + */ + void flatten () + { + flat_edge_pairs (); + } + /** * @brief Returns true, if the edge pair set has valid edges stored within itself * diff --git a/src/db/db/dbEdges.h b/src/db/db/dbEdges.h index d3d6f9333..df85cdac9 100644 --- a/src/db/db/dbEdges.h +++ b/src/db/db/dbEdges.h @@ -1172,14 +1172,23 @@ public: /** * @brief Returns the nth edge * - * This operation is only cheap if "has_valid_edges" is true. Otherwise, the - * complexity is O(n). + * This operation is available only for flat regions - i.e. such for which "has_valid_edges" is true. */ const db::Edge *nth (size_t n) const { return mp_delegate->nth (n); } + /** + * @brief Forces flattening of the edge collection + * + * This method will turn any edge collection into a flat one. + */ + void flatten () + { + flat_edges (); + } + /** * @brief Returns true, if the edge set has valid edges stored within itself * diff --git a/src/db/db/dbFlatEdgePairs.cc b/src/db/db/dbFlatEdgePairs.cc index 2db48f554..9c4c66747 100644 --- a/src/db/db/dbFlatEdgePairs.cc +++ b/src/db/db/dbFlatEdgePairs.cc @@ -184,6 +184,7 @@ void FlatEdgePairs::insert (const db::EdgePair &ep) { m_edge_pairs.insert (ep); + invalidate_cache (); } void diff --git a/src/db/db/dbFlatEdges.cc b/src/db/db/dbFlatEdges.cc index 4c33b6575..c1e3e4606 100644 --- a/src/db/db/dbFlatEdges.cc +++ b/src/db/db/dbFlatEdges.cc @@ -338,7 +338,12 @@ FlatEdges::insert (const db::SimplePolygon &polygon) void FlatEdges::insert (const db::Edge &edge) { + if (! empty ()) { + m_is_merged = false; + } + m_edges.insert (edge); + invalidate_cache (); } void diff --git a/src/db/db/dbOriginalLayerEdgePairs.cc b/src/db/db/dbOriginalLayerEdgePairs.cc index 14e92019a..6791e069e 100644 --- a/src/db/db/dbOriginalLayerEdgePairs.cc +++ b/src/db/db/dbOriginalLayerEdgePairs.cc @@ -23,6 +23,7 @@ #include "dbOriginalLayerEdgePairs.h" #include "dbEdgePairs.h" +#include "tlInternational.h" namespace db { @@ -150,7 +151,7 @@ OriginalLayerEdgePairs::empty () const const db::EdgePair * OriginalLayerEdgePairs::nth (size_t) const { - tl_assert (false); + throw tl::Exception (tl::to_string (tr ("Random access to edge pairs is available only for flat collections"))); } bool diff --git a/src/db/db/dbOriginalLayerEdges.cc b/src/db/db/dbOriginalLayerEdges.cc index 5b33e4f02..52e00afa7 100644 --- a/src/db/db/dbOriginalLayerEdges.cc +++ b/src/db/db/dbOriginalLayerEdges.cc @@ -195,7 +195,7 @@ OriginalLayerEdges::is_merged () const const db::Edge * OriginalLayerEdges::nth (size_t) const { - tl_assert (false); + throw tl::Exception (tl::to_string (tr ("Random access to edges is available only for flat collections"))); } bool diff --git a/src/db/db/dbOriginalLayerRegion.cc b/src/db/db/dbOriginalLayerRegion.cc index a043ab411..b1bd13585 100644 --- a/src/db/db/dbOriginalLayerRegion.cc +++ b/src/db/db/dbOriginalLayerRegion.cc @@ -195,7 +195,7 @@ OriginalLayerRegion::is_merged () const const db::Polygon * OriginalLayerRegion::nth (size_t) const { - tl_assert (false); + throw tl::Exception (tl::to_string (tr ("Random access to polygons is available only for flat regions"))); } bool diff --git a/src/db/db/dbRegion.h b/src/db/db/dbRegion.h index 3ef7d0223..c0772dc89 100644 --- a/src/db/db/dbRegion.h +++ b/src/db/db/dbRegion.h @@ -1576,14 +1576,24 @@ public: /** * @brief Returns the nth polygon * - * This operation is only cheap if "has_valid_polygons" is true. Otherwise, the - * complexity is O(n). + * This operation is available only for flat regions - i.e. such for which + * "has_valid_polygons" is true. */ const db::Polygon *nth (size_t n) const { return mp_delegate->nth (n); } + /** + * @brief Forces flattening of the region + * + * This method will turn any region into a flat shape collection. + */ + void flatten () + { + flat_region (); + } + /** * @brief Returns true, if the region has valid polygons stored within itself * diff --git a/src/db/db/gsiDeclDbEdgePairs.cc b/src/db/db/gsiDeclDbEdgePairs.cc index 03df7340b..b8277d2e3 100644 --- a/src/db/db/gsiDeclDbEdgePairs.cc +++ b/src/db/db/gsiDeclDbEdgePairs.cc @@ -35,6 +35,35 @@ static db::EdgePairs *new_v () return new db::EdgePairs (); } +static db::EdgePairs *new_a (const std::vector &pairs) +{ + return new db::EdgePairs (pairs.begin (), pairs.end ()); +} + +static db::EdgePairs *new_ep (const db::EdgePair &pair) +{ + return new db::EdgePairs (pair); +} + +static db::EdgePairs *new_shapes (const db::Shapes &s) +{ + db::EdgePairs *r = new db::EdgePairs (); + for (db::Shapes::shape_iterator i = s.begin (db::ShapeIterator::EdgePairs); !i.at_end (); ++i) { + r->insert (*i); + } + return r; +} + +static db::EdgePairs *new_si (const db::RecursiveShapeIterator &si) +{ + return new db::EdgePairs (si); +} + +static db::EdgePairs *new_si2 (const db::RecursiveShapeIterator &si, const db::ICplxTrans &trans) +{ + return new db::EdgePairs (si, trans); +} + static std::string to_string0 (const db::EdgePairs *r) { return r->to_string (); @@ -135,6 +164,67 @@ Class decl_EdgePairs ("db", "EdgePairs", "\n" "This constructor creates an empty edge pair collection.\n" ) + + constructor ("new", &new_a, + "@brief Constructor from an edge pair array\n" + "@args array\n" + "\n" + "This constructor creates an edge pair collection from an array of \\EdgePair objects.\n" + "\n" + "This constructor has been introduced in version 0.26." + ) + + constructor ("new", &new_ep, + "@brief Constructor from a single edge pair object\n" + "@args edge_pair\n" + "\n" + "This constructor creates an edge pair collection with a single edge pair.\n" + "\n" + "This constructor has been introduced in version 0.26." + ) + + constructor ("new", &new_shapes, + "@brief Shapes constructor\n" + "@args shapes\n" + "\n" + "This constructor creates an edge pair collection from a \\Shapes collection.\n" + "\n" + "This constructor has been introduced in version 0.26." + ) + + constructor ("new", &new_si, + "@brief Constructor from a hierarchical shape set\n" + "@args shape_iterator\n" + "\n" + "This constructor creates an edge pair collection from the shapes delivered by the given recursive shape iterator.\n" + "Only edge pairs are taken from the shape set and other shapes are ignored.\n" + "This method allows feeding the edge pair collection from a hierarchy of cells.\n" + "\n" + "@code\n" + "layout = ... # a layout\n" + "cell = ... # the index of the initial cell\n" + "layer = ... # the index of the layer from where to take the shapes from\n" + "r = RBA::EdgePairs::new(layout.begin_shapes(cell, layer))\n" + "@/code\n" + "\n" + "This constructor has been introduced in version 0.26." + ) + + constructor ("new", &new_si2, + "@brief Constructor from a hierarchical shape set with a transformation\n" + "@args shape_iterator, trans\n" + "\n" + "This constructor creates an edge pair collection from the shapes delivered by the given recursive shape iterator.\n" + "Only edge pairs are taken from the shape set and other shapes are ignored.\n" + "The given transformation is applied to each edge pair taken.\n" + "This method allows feeding the edge pair collection from a hierarchy of cells.\n" + "The transformation is useful to scale to a specific database unit for example.\n" + "\n" + "@code\n" + "layout = ... # a layout\n" + "cell = ... # the index of the initial cell\n" + "layer = ... # the index of the layer from where to take the shapes from\n" + "dbu = 0.1 # the target database unit\n" + "r = RBA::EdgePairs::new(layout.begin_shapes(cell, layer), RBA::ICplxTrans::new(layout.dbu / dbu))\n" + "@/code\n" + "\n" + "This constructor 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" @@ -337,7 +427,23 @@ Class decl_EdgePairs ("db", "EdgePairs", "@brief Returns the nth edge pair\n" "@args n\n" "\n" - "This method returns nil if the index is out of range.\n" + "This method returns nil if the index is out of range. It is available for flat edge pairs only - i.e. " + "those for which \\has_valid_edge_pairs? is true. Use \\flatten to explicitly flatten an edge pair collection.\n" + "\n" + "The \\each iterator is the more general approach to access the edge pairs." + ) + + method ("flatten", &db::EdgePairs::flatten, + "@brief Explicitly flattens an edge pair collection\n" + "\n" + "If the collection is already flat (i.e. \\has_valid_edge_pairs? returns true), this method will " + "not change the collection.\n" + "\n" + "This method has been introduced in version 0.26." + ) + + method ("has_valid_edge_pairs?", &db::EdgePairs::has_valid_edge_pairs, + "@brief Returns true if the edge pair collection is flat and individual edge pairs can be accessed randomly\n" + "\n" + "This method has been introduced in version 0.26." ) + method ("enable_progress", &db::EdgePairs::enable_progress, "@brief Enable progress reporting\n" diff --git a/src/db/db/gsiDeclDbEdges.cc b/src/db/db/gsiDeclDbEdges.cc index 85b22a2f8..9166a6f68 100644 --- a/src/db/db/gsiDeclDbEdges.cc +++ b/src/db/db/gsiDeclDbEdges.cc @@ -1433,10 +1433,27 @@ Class dec_Edges ("db", "Edges", "This method has been introduced in version 0.25." ) + method ("[]", &db::Edges::nth, - "@brief Returns the nth edge of the edge collection\n" + "@brief Returns the nth edge of the collection\n" "@args n\n" "\n" - "This method returns nil if the index is out of range.\n" + "This method returns nil if the index is out of range. It is available for flat edge collections only - i.e. " + "those for which \\has_valid_edges? is true. Use \\flatten to explicitly flatten an edge collection.\n" + "This method returns the raw edge (not merged edges, even if merged semantics is enabled).\n" + "\n" + "The \\each iterator is the more general approach to access the edges." + ) + + method ("flatten", &db::Edges::flatten, + "@brief Explicitly flattens an edge collection\n" + "\n" + "If the collection is already flat (i.e. \\has_valid_edges? returns true), this method will " + "not change it.\n" + "\n" + "This method has been introduced in version 0.26." + ) + + method ("has_valid_edges?", &db::Edges::has_valid_edges, + "@brief Returns true if the edge collection is flat and individual edges can be accessed randomly\n" + "\n" + "This method has been introduced in version 0.26." ) + method_ext ("to_s", &to_string0, "@brief Converts the edge collection to a string\n" diff --git a/src/db/db/gsiDeclDbRegion.cc b/src/db/db/gsiDeclDbRegion.cc index 6bb770ebb..7cb106fa8 100644 --- a/src/db/db/gsiDeclDbRegion.cc +++ b/src/db/db/gsiDeclDbRegion.cc @@ -797,7 +797,7 @@ Class decl_Region ("db", "Region", "@param as_pattern If true, the selection string is treated as a glob pattern. Otherwise the match is exact.\n" "\n" "This special constructor will create a region from the text objects delivered by the shape iterator. " - "Each text object will deliver a small (non-empty) box that represents the text origin.\n" + "Each text object will give a small (non-empty) box that represents the text origin.\n" "Texts can be selected by their strings - either through a glob pattern or by exact comparison with " "the given string. The following options are available:\n" "\n" @@ -2320,11 +2320,24 @@ Class decl_Region ("db", "Region", "@brief Returns the nth polygon of the region\n" "@args n\n" "\n" - "This method returns nil if the index is out of range.\n" - "This returns the raw polygon (not merged polygons if merged semantics is enabled).\n" + "This method returns nil if the index is out of range. It is available for flat regions only - i.e. " + "those for which \\has_valid_polygons? is true. Use \\flatten to explicitly flatten a region.\n" + "This method returns the raw polygon (not merged polygons, even if merged semantics is enabled).\n" "\n" - "Using this method may be costly in terms of memory since it will load the polygons into an array if they have been " - "stored in an hierarchical layout before. It is recommended to use the \\each iterator instead if possible." + "The \\each iterator is the more general approach to access the polygons." + ) + + method ("flatten", &db::Region::flatten, + "@brief Explicitly flattens a region\n" + "\n" + "If the region is already flat (i.e. \\has_valid_polygons? returns true), this method will " + "not change it.\n" + "\n" + "This method has been introduced in version 0.26." + ) + + method ("has_valid_polygons?", &db::Region::has_valid_polygons, + "@brief Returns true if the region is flat and individual polygons can be accessed randomly\n" + "\n" + "This method has been introduced in version 0.26." ) + method_ext ("to_s", &to_string0, "@brief Converts the region to a string\n" diff --git a/src/db/db/gsiDeclDbShape.cc b/src/db/db/gsiDeclDbShape.cc index 309adeae2..35aa60cff 100644 --- a/src/db/db/gsiDeclDbShape.cc +++ b/src/db/db/gsiDeclDbShape.cc @@ -689,6 +689,26 @@ static tl::Variant get_dedge (const db::Shape *s) } } +static tl::Variant get_edge_pair (const db::Shape *s) +{ + db::Shape::edge_pair_type p; + if (s->edge_pair (p)) { + return tl::Variant (p); + } else { + return tl::Variant (); + } +} + +static tl::Variant get_dedge_pair (const db::Shape *s) +{ + db::Shape::edge_pair_type p; + if (s->edge_pair (p)) { + return tl::Variant (db::CplxTrans (shape_dbu (s)) * p); + } else { + return tl::Variant (); + } +} + static tl::Variant get_text (const db::Shape *s) { db::Shape::text_type p; @@ -1087,6 +1107,7 @@ static int t_simplePolygonRef () { return db::Shape::SimplePolygonRef static int t_simplePolygonPtrArray () { return db::Shape::SimplePolygonPtrArray; } static int t_simplePolygonPtrArrayMember () { return db::Shape::SimplePolygonPtrArrayMember; } static int t_edge () { return db::Shape::Edge; } +static int t_edge_pair () { return db::Shape::EdgePair; } static int t_path () { return db::Shape::Path; } static int t_pathRef () { return db::Shape::PathRef; } static int t_pathPtrArray () { return db::Shape::PathPtrArray; } @@ -1218,7 +1239,7 @@ Class decl_Shape ("db", "Shape", "\n" "This method has been introduced in version 0.25." ) + - gsi::method_ext ("edge=", &set_shape, + gsi::method_ext ("edge=", &set_shape, gsi::arg("edge"), "@brief Replaces the shape by the given edge\n" "@args box\n" "This method replaces the shape by the given edge. This method can only be called " @@ -1235,6 +1256,23 @@ Class decl_Shape ("db", "Shape", "\n" "This method has been introduced in version 0.25." ) + + gsi::method_ext ("edge_pair=", &set_shape, gsi::arg("edge_pair"), + "@brief Replaces the shape by the given edge pair\n" + "@args box\n" + "This method replaces the shape by the given edge pair. This method can only be called " + "for editable layouts. It does not change the user properties of the shape.\n" + "Calling this method will invalidate any iterators. It should not be called inside a " + "loop iterating over shapes.\n" + "\n" + "This method has been introduced in version 0.26." + ) + + gsi::method_ext ("edge_pair=|dedge_pair=", &set_dshape, gsi::arg("edge_pair"), + "@brief Replaces the shape by the given edge pair (in micrometer units)\n" + "This method replaces the shape by the given edge pair, like \\edge_pair= with a \\EdgePair argument does. " + "This version translates the edge pair from micrometer units to database units internally.\n" + "\n" + "This method has been introduced in version 0.26." + ) + gsi::method_ext ("delete_property", &delete_property, "@brief Deletes the user property with the given key\n" "@args key\n" @@ -1713,12 +1751,29 @@ Class decl_Shape ("db", "Shape", "Starting with version 0.23, this method returns nil, if the shape does not represent an edge." ) + gsi::method_ext ("dedge", &get_dedge, - "@brief Returns the path object as a \\DEdge object in micrometer units\n" + "@brief Returns the edge object as a \\DEdge object in micrometer units\n" "See \\edge for a description of this method. This method returns the edge after translation to " "micrometer units.\n" "\n" "This method has been added in version 0.25.\n" ) + + gsi::method ("is_edge_pair?", &db::Shape::is_edge_pair, + "@brief Returns true, if the object is an edge pair\n" + "\n" + "This method has been introduced in version 0.26." + ) + + gsi::method_ext ("edge_pair", &get_edge_pair, + "@brief Returns the edge pair object\n" + "\n" + "This method has been introduced in version 0.26." + ) + + gsi::method_ext ("dedge_pair", &get_dedge_pair, + "@brief Returns the edge pair object as a \\DEdgePair object in micrometer units\n" + "See \\edge_pair for a description of this method. This method returns the edge pair after translation to " + "micrometer units.\n" + "\n" + "This method has been added in version 0.26.\n" + ) + gsi::method ("is_text?", &db::Shape::is_text, "@brief Returns true, if the object is a text\n" ) + @@ -1729,7 +1784,7 @@ Class decl_Shape ("db", "Shape", ) + gsi::method_ext ("dtext", &get_dtext, "@brief Returns the path object as a \\DText object in micrometer units\n" - "See \\edge for a description of this method. This method returns the text after translation to " + "See \\text for a description of this method. This method returns the text after translation to " "micrometer units.\n" "\n" "This method has been added in version 0.25.\n" @@ -2026,6 +2081,7 @@ Class decl_Shape ("db", "Shape", gsi::method ("TSimplePolygonPtrArray|#t_simple_polygon_ptr_array", &t_simplePolygonPtrArray) + gsi::method ("TSimplePolygonPtrArrayMember|#t_simple_polygon_ptr_array_member", &t_simplePolygonPtrArrayMember) + gsi::method ("TEdge|#t_edge", &t_edge) + + gsi::method ("TEdgePair|#t_edge_pair", &t_edge_pair) + gsi::method ("TPath|#t_path", &t_path) + gsi::method ("TPathRef|#t_path_ref", &t_pathRef) + gsi::method ("TPathPtrArray|#t_path_ptr_array", &t_pathPtrArray) + diff --git a/src/db/db/gsiDeclDbShapes.cc b/src/db/db/gsiDeclDbShapes.cc index 24291e3cf..27653f9b3 100644 --- a/src/db/db/gsiDeclDbShapes.cc +++ b/src/db/db/gsiDeclDbShapes.cc @@ -423,6 +423,7 @@ static unsigned int s_properties () { return db::ShapeIterator::Propert static unsigned int s_polygons () { return db::ShapeIterator::Polygons; } static unsigned int s_boxes () { return db::ShapeIterator::Boxes; } static unsigned int s_edges () { return db::ShapeIterator::Edges; } +static unsigned int s_edge_pairs () { return db::ShapeIterator::EdgePairs; } static unsigned int s_paths () { return db::ShapeIterator::Paths; } static unsigned int s_texts () { return db::ShapeIterator::Texts; } static unsigned int s_user_objects () { return db::ShapeIterator::UserObjects; } @@ -780,9 +781,8 @@ Class decl_Shapes ("db", "Shapes", "\n" "This variant has been introduced in version 0.25." ) + - gsi::method_ext ("replace", &replace, + gsi::method_ext ("replace", &replace, gsi::arg ("shape"), gsi::arg ("edge"), "@brief Replaces the given shape with an edge object\n" - "@args shape,edge\n" "\n" "This method has been introduced with version 0.16. It replaces the given shape with the " "object specified. It does not change the property Id. To change the property Id, " @@ -792,7 +792,7 @@ Class decl_Shapes ("db", "Shapes", "This method is permitted in editable mode only." ) + gsi::method_ext ("replace", &dreplace, gsi::arg ("shape"), gsi::arg ("edge"), - "@brief Replaces the given shape with a edge given in micrometer units\n" + "@brief Replaces the given shape with an edge given in micrometer units\n" "@return A reference to the new shape (a \\Shape object)\n" "\n" "This method behaves like the \\replace version with an \\Edge argument, except that it will " @@ -800,6 +800,27 @@ Class decl_Shapes ("db", "Shapes", "\n" "This variant has been introduced in version 0.25." ) + + gsi::method_ext ("replace", &replace, gsi::arg ("shape"), gsi::arg ("edge_pair"), + "@brief Replaces the given shape with an edge pair object\n" + "\n" + "It replaces the given shape with the " + "object specified. It does not change the property Id. To change the property Id, " + "use the \\replace_prop_id method. To replace a shape and discard the property Id, erase the " + "shape and insert a new shape." + "\n" + "This method is permitted in editable mode only.\n" + "\n" + "This method has been introduced in version 0.26.\n" + ) + + gsi::method_ext ("replace", &dreplace, gsi::arg ("shape"), gsi::arg ("edge_pair"), + "@brief Replaces the given shape with an edge pair given in micrometer units\n" + "@return A reference to the new shape (a \\Shape object)\n" + "\n" + "This method behaves like the \\replace version with an \\EdgePair argument, except that it will " + "internally translate the edge pair from micrometer to database units.\n" + "\n" + "This variant has been introduced in version 0.26.\n" + ) + gsi::method_ext ("replace", &replace, "@brief Replaces the given shape with a text object\n" "@return A reference to the new shape (a \\Shape object)\n" @@ -893,9 +914,8 @@ Class decl_Shapes ("db", "Shapes", "\n" "This variant has been introduced in version 0.25." ) + - gsi::method_ext ("insert|#insert_edge", &insert, - "@brief Inserts a edge into the shapes list\n" - "@args edge\n" + gsi::method_ext ("insert|#insert_edge", &insert, gsi::arg ("edge"), + "@brief Inserts an edge into the shapes list\n" "\n" "Starting with version 0.16, this method returns a reference to the newly created shape\n" ) + @@ -907,6 +927,19 @@ Class decl_Shapes ("db", "Shapes", "\n" "This variant has been introduced in version 0.25." ) + + gsi::method_ext ("insert", &insert, gsi::arg ("edge_pair"), + "@brief Inserts an edge pair into the shapes list\n" + "\n" + "This method has been introduced in version 0.26.\n" + ) + + gsi::method_ext ("insert", &dinsert, gsi::arg ("edge_pair"), + "@brief Inserts a micrometer-unit edge pair into the shapes list\n" + "@return A reference to the new shape (a \\Shape object)\n" + "This method behaves like the \\insert version with a \\EdgePair argument, except that it will " + "internally translate the edge pair from micrometer to database units.\n" + "\n" + "This variant has been introduced in version 0.26." + ) + gsi::method_ext ("insert|#insert_text", &insert, "@brief Inserts a text into the shapes list\n" "@return A reference to the new shape (a \\Shape object)\n" @@ -986,14 +1019,13 @@ Class decl_Shapes ("db", "Shapes", "\n" "This variant has been introduced in version 0.25." ) + - gsi::method_ext ("insert|#insert_edge_with_properties", &insert_with_properties, - "@brief Inserts a edge with properties into the shapes list\n" - "@args edge, property_id\n" + gsi::method_ext ("insert|#insert_edge_with_properties", &insert_with_properties, gsi::arg ("edge"), gsi::arg ("property_id"), + "@brief Inserts an edge with properties into the shapes list\n" "@return A reference to the new shape (a \\Shape object)\n" "The property Id must be obtained from the \\Layout object's property_id method which " "associates a property set with a property Id." "\n" - "Starting with version 0.16, this method returns a reference to the newly created shape\n" + "Starting with version 0.16, this method returns a reference to the newly created shape.\n" ) + gsi::method_ext ("insert", &dinsert_with_properties, gsi::arg ("edge"), gsi::arg ("property_id"), "@brief Inserts a micrometer-unit edge with properties into the shapes list\n" @@ -1003,6 +1035,22 @@ Class decl_Shapes ("db", "Shapes", "\n" "This variant has been introduced in version 0.25." ) + + gsi::method_ext ("insert", &insert_with_properties, gsi::arg ("edge_pair"), gsi::arg ("property_id"), + "@brief Inserts an edge pair with properties into the shapes list\n" + "@return A reference to the new shape (a \\Shape object)\n" + "The property Id must be obtained from the \\Layout object's property_id method which " + "associates a property set with a property Id." + "\n" + "This method has been introduced in version 0.26.\n" + ) + + gsi::method_ext ("insert", &dinsert_with_properties, gsi::arg ("edge_pair"), gsi::arg ("property_id"), + "@brief Inserts a micrometer-unit edge pair with properties into the shapes list\n" + "@return A reference to the new shape (a \\Shape object)\n" + "This method behaves like the \\insert version with a \\EdgePair argument and a property ID, except that it will " + "internally translate the edge pair from micrometer to database units.\n" + "\n" + "This variant has been introduced in version 0.26." + ) + gsi::method_ext ("insert|#insert_text_with_properties", &insert_with_properties, "@brief Inserts a text with properties into the shapes list\n" "@args text, property_id\n" @@ -1185,6 +1233,9 @@ Class decl_Shapes ("db", "Shapes", gsi::method ("SEdges|#s_edges", &s_edges, "@brief Indicates that edges shall be retrieved" ) + + gsi::method ("SEdgePairs|#s_edge_pairs", &s_edge_pairs, + "@brief Indicates that edge pairs shall be retrieved" + ) + gsi::method ("SPaths|#s_paths", &s_paths, "@brief Indicates that paths shall be retrieved" ) + @@ -1203,7 +1254,7 @@ Class decl_Shapes ("db", "Shapes", "@brief A collection of shapes\n" "\n" "A shapes collection is a collection of geometrical objects, such as " - "polygons, boxes, paths, edges or text objects.\n" + "polygons, boxes, paths, edges, edge pairs or text objects.\n" "\n" "Shapes objects are the basic containers for geometrical objects of a cell. Inside a cell, there is " "one Shapes object per layer.\n" diff --git a/src/db/unit_tests/dbTilingProcessor.cc b/src/db/unit_tests/dbTilingProcessor.cc index c352cb19a..516e5f613 100644 --- a/src/db/unit_tests/dbTilingProcessor.cc +++ b/src/db/unit_tests/dbTilingProcessor.cc @@ -238,6 +238,7 @@ TEST(3) tp.input ("i2", ir2.begin_iter ().first, ir2.begin_iter ().second); EXPECT_EQ (ir2.has_valid_polygons (), false); db::Region ir3 (db::RecursiveShapeIterator (ly, ly.cell (top), l3)); + ir3.flatten (); tp.input ("i3", ir3.begin_iter ().first, ir3.begin_iter ().second); EXPECT_EQ (ir3.has_valid_polygons (), true); tp.output ("o1", ly, top, o1); diff --git a/testdata/ruby/dbEdgePairsTest.rb b/testdata/ruby/dbEdgePairsTest.rb index b983a6f03..da529901b 100644 --- a/testdata/ruby/dbEdgePairsTest.rb +++ b/testdata/ruby/dbEdgePairsTest.rb @@ -108,6 +108,51 @@ class DBEdgePairs_TestClass < TestBase end + def test_3 + + ep1 = RBA::EdgePair::new(RBA::Edge::new(0, 1, 2, 3), RBA::Edge::new(10, 11, 12, 13)) + ep2 = RBA::EdgePair::new(RBA::Edge::new(20, 21, 22, 23), RBA::Edge::new(30, 31, 32, 33)) + + r1 = RBA::EdgePairs::new([ ep1, ep2 ]) + assert_equal(r1.to_s, "(0,1;2,3)/(10,11;12,13);(20,21;22,23)/(30,31;32,33)") + + r1 = RBA::EdgePairs::new(ep1) + assert_equal(r1.to_s, "(0,1;2,3)/(10,11;12,13)") + + s = RBA::Shapes::new + s.insert(ep1) + s.insert(ep2) + r1 = RBA::EdgePairs::new(s) + assert_equal(r1.to_s, "(0,1;2,3)/(10,11;12,13);(20,21;22,23)/(30,31;32,33)") + + ly = RBA::Layout::new + l1 = ly.layer("l1") + l2 = ly.layer("l2") + c1 = ly.create_cell("C1") + c2 = ly.create_cell("C2") + c1.insert(RBA::CellInstArray::new(c2.cell_index, RBA::Trans::new(0, 0))) + c1.insert(RBA::CellInstArray::new(c2.cell_index, RBA::Trans::new(0, 100))) + c1.insert(RBA::CellInstArray::new(c2.cell_index, RBA::Trans::new(200, 100))) + c2.shapes(l1).insert(ep1) + c2.shapes(l2).insert(ep2) + + r = RBA::EdgePairs::new(ly.begin_shapes(c1.cell_index, l1)) + assert_equal(r.to_s(30), "(0,1;2,3)/(10,11;12,13);(0,101;2,103)/(10,111;12,113);(200,101;202,103)/(210,111;212,113)") + assert_equal(r.to_s(2), "(0,1;2,3)/(10,11;12,13);(0,101;2,103)/(10,111;12,113)...") + assert_equal(r.is_empty?, false) + assert_equal(r.size, 3) + + assert_equal(r.has_valid_edge_pairs?, false) + assert_equal(r.bbox.to_s, "(0,1;212,113)") + + r.flatten + assert_equal(r.has_valid_edge_pairs?, true) + assert_equal(r[1].to_s, "(0,101;2,103)/(10,111;12,113)") + assert_equal(r[100].inspect, "nil") + assert_equal(r.bbox.to_s, "(0,1;212,113)") + + end + end diff --git a/testdata/ruby/dbEdgesTest.rb b/testdata/ruby/dbEdgesTest.rb index b8a2e567c..4fea31683 100644 --- a/testdata/ruby/dbEdgesTest.rb +++ b/testdata/ruby/dbEdgesTest.rb @@ -40,6 +40,13 @@ class DBEdges_TestClass < TestBase assert_equal(r.is_empty?, false) assert_equal(r.size, 1) assert_equal(r.bbox.to_s, "(10,20;100,200)") + assert_equal(r.is_merged?, true) + + r.assign(RBA::Edges::new([RBA::Edge::new(10, 20, 100, 200), RBA::Edge::new(11, 21, 101, 201)])) + assert_equal(r.to_s, "(10,20;100,200);(11,21;101,201)") + assert_equal(r.is_empty?, false) + assert_equal(r.size, 2) + assert_equal(r.bbox.to_s, "(10,20;101,201)") assert_equal(r.is_merged?, false) r.assign(RBA::Edges::new(RBA::Edge::new(10, 20, 100, 200))) @@ -47,7 +54,7 @@ class DBEdges_TestClass < TestBase assert_equal(r.is_empty?, false) assert_equal(r.size, 1) assert_equal(r.bbox.to_s, "(10,20;100,200)") - assert_equal(r.is_merged?, false) + assert_equal(r.is_merged?, true) r.assign(RBA::Edges::new(RBA::Box::new(10, 20, 100, 200))) assert_equal(r.to_s, "(10,20;10,200);(10,200;100,200);(100,200;100,20);(100,20;10,20)") @@ -60,7 +67,7 @@ class DBEdges_TestClass < TestBase assert_equal(r.is_empty?, false) assert_equal(r.size, 4) assert_equal(r.bbox.to_s, "(10,20;100,200)") - assert_equal(r.is_merged?, false) + assert_equal(r.is_merged?, true) assert_equal(r.moved(RBA::Point::new(10, 20)).bbox.to_s, "(20,40;110,220)") assert_equal(r.moved(10, 20).bbox.to_s, "(20,40;110,220)") @@ -163,6 +170,12 @@ class DBEdges_TestClass < TestBase assert_equal(r.to_s(2), "(-10,-20;10,20);(-10,80;10,120)...") assert_equal(r.is_empty?, false) assert_equal(r.size, 3) + assert_equal(r.bbox.to_s, "(-10,-20;210,120)") + assert_equal(r.is_merged?, false) + assert_equal(r.has_valid_edges?, false) + + r.flatten + assert_equal(r.has_valid_edges?, true) assert_equal(r[1].to_s, "(-10,80;10,120)") assert_equal(r[100].to_s, "") assert_equal(r.bbox.to_s, "(-10,-20;210,120)") diff --git a/testdata/ruby/dbRegionTest.rb b/testdata/ruby/dbRegionTest.rb index e9bdc6452..01d4ea556 100644 --- a/testdata/ruby/dbRegionTest.rb +++ b/testdata/ruby/dbRegionTest.rb @@ -41,7 +41,7 @@ class DBRegion_TestClass < TestBase assert_equal(r.is_empty?, false) assert_equal(r.size, 1) assert_equal(r.bbox.to_s, "(10,20;100,200)") - assert_equal(r.is_merged?, false) + assert_equal(r.is_merged?, true) assert_equal(r.is_box?, true) assert_equal(r.edges.to_s, "(10,20;10,200);(10,200;100,200);(100,200;100,20);(100,20;10,20)") @@ -149,6 +149,12 @@ class DBRegion_TestClass < TestBase assert_equal(r.to_s, "(-10,-20;-10,20;10,20;10,-20);(-10,80;-10,120;10,120;10,80);(190,80;190,120;210,120;210,80)") assert_equal(r.is_empty?, false) assert_equal(r.size, 3) + assert_equal(r.bbox.to_s, "(-10,-20;210,120)") + assert_equal(r.is_merged?, false) + assert_equal(r.has_valid_polygons?, false) + + r.flatten + assert_equal(r.has_valid_polygons?, true) assert_equal(r[1].to_s, "(-10,80;-10,120;10,120;10,80)") assert_equal(r[4].to_s, "") assert_equal(r.bbox.to_s, "(-10,-20;210,120)") diff --git a/testdata/ruby/dbShapesTest.rb b/testdata/ruby/dbShapesTest.rb index 00ce28bf6..27fbcd36c 100644 --- a/testdata/ruby/dbShapesTest.rb +++ b/testdata/ruby/dbShapesTest.rb @@ -155,6 +155,7 @@ class DBShapes_TestClass < TestBase assert_equal( arr[0].polygon.inspect, "(10,-10;10,40;50,40;50,-10)" ) assert_equal( arr[0].simple_polygon.inspect, "(10,-10;10,40;50,40;50,-10)" ) assert_equal( arr[0].edge.inspect, "nil" ) + assert_equal( arr[0].edge_pair.inspect, "nil" ) assert_equal( arr[0].box.inspect, "(10,-10;50,40)" ) assert_equal( arr[0].path.inspect, "nil" ) assert_equal( arr[0].text.inspect, "nil" ) @@ -178,6 +179,7 @@ class DBShapes_TestClass < TestBase assert_equal( arr[0].polygon.inspect, "nil" ) assert_equal( arr[0].simple_polygon.inspect, "nil" ) assert_equal( arr[0].edge.inspect, "(-1,2;5,2)" ) + assert_equal( arr[0].edge_pair.inspect, "nil" ) assert_equal( arr[0].box.inspect, "nil" ) assert_equal( arr[0].path.inspect, "nil" ) assert_equal( arr[0].text.inspect, "nil" ) @@ -188,6 +190,32 @@ class DBShapes_TestClass < TestBase assert_equal( arr.size, 1 ) assert_equal( arr[0].is_box?, true ) + # edge pairs + + a = RBA::EdgePair::new(RBA::Edge::new(RBA::Point::new(-1, 2), RBA::Point::new(5, 2)), RBA::Edge::new(RBA::Point::new(-1, 5), RBA::Point::new(5, 5))) + c1.shapes( lindex ).insert( a ) + arr = [] + shapes.each( RBA::Shapes::SEdgePairs ) { |s| arr.push( s ) } + assert_equal( arr.size, 1 ) + assert_equal( arr[0].prop_id, 0 ) + assert_equal( arr[0].has_prop_id?, false ) + assert_equal( arr[0].is_null?, false ) + assert_equal( arr[0].type, RBA::Shape::t_edge_pair ) + assert_equal( arr[0].is_edge_pair?, true ) + assert_equal( arr[0].polygon.inspect, "nil" ) + assert_equal( arr[0].simple_polygon.inspect, "nil" ) + assert_equal( arr[0].edge_pair.inspect, "(-1,2;5,2)/(-1,5;5,5)" ) + assert_equal( arr[0].edge.inspect, "nil" ) + assert_equal( arr[0].box.inspect, "nil" ) + assert_equal( arr[0].path.inspect, "nil" ) + assert_equal( arr[0].text.inspect, "nil" ) + assert_equal( arr[0].edge_pair == a, true ) + assert_equal( arr[0].bbox == a.bbox, true ) + arr = [] + shapes.each( RBA::Shapes::SBoxes ) { |s| arr.push( s ) } + assert_equal( arr.size, 1 ) + assert_equal( arr[0].is_box?, true ) + # paths a = RBA::Path::new( [ RBA::Point::new( 0, 10 ), RBA::Point::new( 10, 50 ) ], 25 ) @@ -203,6 +231,7 @@ class DBShapes_TestClass < TestBase assert_equal( arr[0].polygon.inspect, "(12,7;-12,13;-2,53;22,47)" ) assert_equal( arr[0].simple_polygon.inspect, "(12,7;-12,13;-2,53;22,47)" ) assert_equal( arr[0].edge.inspect, "nil" ) + assert_equal( arr[0].edge_pair.inspect, "nil" ) assert_equal( arr[0].box.inspect, "nil" ) assert_equal( arr[0].path.inspect, "(0,10;10,50) w=25 bx=0 ex=0 r=false" ) assert_equal( arr[0].text.inspect, "nil" ) @@ -238,6 +267,7 @@ class DBShapes_TestClass < TestBase assert_equal( arr[0].polygon.inspect, "(0,1;1,5;5,5)" ) assert_equal( arr[0].simple_polygon.inspect, "(0,1;1,5;5,5)" ) assert_equal( arr[0].edge.inspect, "nil" ) + assert_equal( arr[0].edge_pair.inspect, "nil" ) assert_equal( arr[0].box.inspect, "nil" ) assert_equal( arr[0].path.inspect, "nil" ) assert_equal( arr[0].text.inspect, "nil" ) @@ -419,6 +449,7 @@ class DBShapes_TestClass < TestBase assert_equal( arr[0].dpolygon.inspect, "(0.01,-0.01;0.01,0.04;0.05,0.04;0.05,-0.01)" ) assert_equal( arr[0].dsimple_polygon.inspect, "(0.01,-0.01;0.01,0.04;0.05,0.04;0.05,-0.01)" ) assert_equal( arr[0].dedge.inspect, "nil" ) + assert_equal( arr[0].dedge_pair.inspect, "nil" ) assert_equal( arr[0].dbox.inspect, "(0.01,-0.01;0.05,0.04)" ) assert_equal( arr[0].dpath.inspect, "nil" ) assert_equal( arr[0].dtext.inspect, "nil" ) @@ -442,6 +473,7 @@ class DBShapes_TestClass < TestBase assert_equal( arr[0].dpolygon.inspect, "nil" ) assert_equal( arr[0].dsimple_polygon.inspect, "nil" ) assert_equal( arr[0].dedge.inspect, "(-0.001,0.002;0.005,0.002)" ) + assert_equal( arr[0].dedge_pair.inspect, "nil" ) assert_equal( arr[0].dbox.inspect, "nil" ) assert_equal( arr[0].dpath.inspect, "nil" ) assert_equal( arr[0].dtext.inspect, "nil" ) @@ -451,6 +483,31 @@ class DBShapes_TestClass < TestBase assert_equal( arr.size, 1 ) assert_equal( arr[0].is_box?, true ) + # edge pairs + + a = RBA::DEdgePair::new(RBA::DEdge::new(RBA::DPoint::new(-0.001, 0.002), RBA::DPoint::new(0.005, 0.002)), RBA::DEdge::new(RBA::DPoint::new(-0.001, 0.005), RBA::DPoint::new(0.005, 0.005))) + c1.shapes( lindex ).insert( a ) + arr = [] + shapes.each( RBA::Shapes::SEdgePairs ) { |s| arr.push( s ) } + assert_equal( arr.size, 1 ) + assert_equal( arr[0].prop_id, 0 ) + assert_equal( arr[0].has_prop_id?, false ) + assert_equal( arr[0].is_null?, false ) + assert_equal( arr[0].type, RBA::Shape::t_edge_pair ) + assert_equal( arr[0].is_edge_pair?, true ) + assert_equal( arr[0].dpolygon.inspect, "nil" ) + assert_equal( arr[0].dsimple_polygon.inspect, "nil" ) + assert_equal( arr[0].dedge_pair.inspect, "(-0.001,0.002;0.005,0.002)/(-0.001,0.005;0.005,0.005)" ) + assert_equal( arr[0].dedge.inspect, "nil" ) + assert_equal( arr[0].dbox.inspect, "nil" ) + assert_equal( arr[0].dpath.inspect, "nil" ) + assert_equal( arr[0].dtext.inspect, "nil" ) + assert_equal( arr[0].dbbox.inspect, "(-0.001,0.002;0.005,0.005)" ) + arr = [] + shapes.each( RBA::Shapes::SBoxes ) { |s| arr.push( s ) } + assert_equal( arr.size, 1 ) + assert_equal( arr[0].is_box?, true ) + # paths a = RBA::DPath::new( [ RBA::DPoint::new( 0, 0.010 ), RBA::DPoint::new( 0.010, 0.050 ) ], 0.025 ) @@ -466,6 +523,7 @@ class DBShapes_TestClass < TestBase assert_equal( arr[0].dpolygon.inspect, "(0.012,0.007;-0.012,0.013;-0.002,0.053;0.022,0.047)" ) assert_equal( arr[0].dsimple_polygon.inspect, "(0.012,0.007;-0.012,0.013;-0.002,0.053;0.022,0.047)" ) assert_equal( arr[0].dedge.inspect, "nil" ) + assert_equal( arr[0].dedge_pair.inspect, "nil" ) assert_equal( arr[0].dbox.inspect, "nil" ) assert_equal( arr[0].dpath.inspect, "(0,0.01;0.01,0.05) w=0.025 bx=0 ex=0 r=false" ) assert_equal( arr[0].dtext.inspect, "nil" ) @@ -499,6 +557,7 @@ class DBShapes_TestClass < TestBase assert_equal( arr[0].dpolygon.inspect, "(0,0.001;0.001,0.005;0.005,0.005)" ) assert_equal( arr[0].dsimple_polygon.inspect, "(0,0.001;0.001,0.005;0.005,0.005)" ) assert_equal( arr[0].dedge.inspect, "nil" ) + assert_equal( arr[0].dedge_pair.inspect, "nil" ) assert_equal( arr[0].dbox.inspect, "nil" ) assert_equal( arr[0].dpath.inspect, "nil" ) assert_equal( arr[0].dtext.inspect, "nil" ) @@ -720,6 +779,18 @@ class DBShapes_TestClass < TestBase shapes.each( RBA::Shapes::SAll ) { |s| arr.push( s.to_s ) } assert_equal( arr, ["simple_polygon (14,0;-21,35;7,64;42,28)", "box (10,-10;50,40) prop_id=17"] ) + s2 = shapes.replace( s2, RBA::Edge::new( 10, -10, 50, 40 ) ) + + arr = [] + shapes.each( RBA::Shapes::SAll ) { |s| arr.push( s.to_s ) } + assert_equal( arr, ["simple_polygon (14,0;-21,35;7,64;42,28)", "edge (10,-10;50,40) prop_id=17"] ) + + s2 = shapes.replace( s2, RBA::EdgePair::new( RBA::Edge::new( 10, -10, 50, 40 ), RBA::Edge::new( 10, 0, 50, 30 ) ) ) + + arr = [] + shapes.each( RBA::Shapes::SAll ) { |s| arr.push( s.to_s ) } + assert_equal( arr, ["simple_polygon (14,0;-21,35;7,64;42,28)", "edge_pair (10,-10;50,40)/(10,0;50,30) prop_id=17"] ) + shapes.erase( s2 ) arr = [] @@ -775,6 +846,7 @@ class DBShapes_TestClass < TestBase assert_equal(s2.simple_polygon.inspect, "nil") assert_equal(s2.text.inspect, "('text',r0 100,200)") assert_equal(s2.edge.inspect, "nil") + assert_equal(s2.edge_pair.inspect, "nil") assert_equal(s2.path.inspect, "nil") assert_equal(s2.box.inspect, "nil") @@ -784,6 +856,18 @@ class DBShapes_TestClass < TestBase shapes.each( RBA::Shapes::SAll ) { |s| arr.push( s.to_s ) } assert_equal( arr, ["box (11,-11;51,41)", "box (200,-10;250,40)", "text ('text',r0 100,200)"] ) + s3.edge_pair = RBA::EdgePair::new(RBA::Edge::new(RBA::Point::new(1, 2), RBA::Point::new(3, 4)), RBA::Edge::new(RBA::Point::new(1, 12), RBA::Point::new(3, 14))) + + shapes = c1.shapes( lindex ) + + arr = [] + shapes.each( RBA::Shapes::SAll ) { |s| arr.push( s.to_s ) } + assert_equal( arr, ["edge_pair (1,2;3,4)/(1,12;3,14)", "box (11,-11;51,41)", "text ('text',r0 100,200)"] ) + + arr = [] + shapes.each( RBA::Shapes::SEdgePairs ) { |s| arr.push( s.to_s ) } + assert_equal( arr, ["edge_pair (1,2;3,4)/(1,12;3,14)"] ) + s3.edge = RBA::Edge::new( RBA::Point::new( 1, 2 ), RBA::Point::new( 3, 4 ) ) shapes = c1.shapes( lindex ) @@ -792,6 +876,10 @@ class DBShapes_TestClass < TestBase shapes.each( RBA::Shapes::SAll ) { |s| arr.push( s.to_s ) } assert_equal( arr, ["edge (1,2;3,4)", "box (11,-11;51,41)", "text ('text',r0 100,200)"] ) + arr = [] + shapes.each( RBA::Shapes::SEdges ) { |s| arr.push( s.to_s ) } + assert_equal( arr, ["edge (1,2;3,4)"] ) + pts = [ RBA::Point::new( 100, 200 ), RBA::Point::new( 400, 300 ), RBA::Point::new( 500, 600 ) ] s1.polygon = RBA::Polygon::new( pts ) @@ -990,6 +1078,14 @@ class DBShapes_TestClass < TestBase shapes.each( RBA::Shapes::SAll ) { |s| arr.push( s.to_s ) } assert_equal( arr, ["box (11,-11;51,41)", "box (200,-10;250,40)", "text ('text',r0 100,200)"] ) + s3.edge_pair = RBA::DEdgePair::new(RBA::DEdge::new(RBA::DPoint::new(0.001, 0.002), RBA::DPoint::new(0.003, 0.004)), RBA::DEdge::new(RBA::DPoint::new(0.001, 0.012), RBA::DPoint::new(0.003, 0.014))) + + shapes = c1.shapes( lindex ) + + arr = [] + shapes.each( RBA::Shapes::SAll ) { |s| arr.push( s.to_s ) } + assert_equal( arr, ["edge_pair (1,2;3,4)/(1,12;3,14)", "box (11,-11;51,41)", "text ('text',r0 100,200)"] ) + s3.edge = RBA::DEdge::new( RBA::DPoint::new( 0.001, 0.002 ), RBA::DPoint::new( 0.003, 0.004 ) ) shapes = c1.shapes( lindex )