mirror of https://github.com/KLayout/klayout.git
WIP: introducing properties for FlatRegion and others
This commit is contained in:
parent
f9ccb60dd9
commit
1dfa5abc9a
|
|
@ -260,6 +260,95 @@ void AsIfFlatRegion::invalidate_bbox ()
|
|||
m_bbox_valid = false;
|
||||
}
|
||||
|
||||
void AsIfFlatRegion::merge_polygons_to (db::Shapes &output, bool min_coherence, unsigned int min_wc) const
|
||||
{
|
||||
db::EdgeProcessor ep (report_progress (), progress_desc ());
|
||||
ep.set_base_verbosity (base_verbosity ());
|
||||
|
||||
// count edges and reserve memory
|
||||
size_t n = 0;
|
||||
db::properties_id_type prop_id = 0;
|
||||
bool need_split_props = false;
|
||||
for (RegionIterator s (begin ()); ! s.at_end (); ++s, ++n) {
|
||||
if (n == 0) {
|
||||
prop_id = s.prop_id ();
|
||||
} else if (! need_split_props && prop_id != s.prop_id ()) {
|
||||
need_split_props = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (need_split_props) {
|
||||
|
||||
db::Shapes result;
|
||||
|
||||
std::vector<std::pair<db::properties_id_type, const db::Polygon *> > polygons_by_prop_id;
|
||||
polygons_by_prop_id.reserve (n);
|
||||
|
||||
db::AddressablePolygonDelivery addressable_polygons (begin ());
|
||||
while (! addressable_polygons.at_end ()) {
|
||||
polygons_by_prop_id.push_back (std::make_pair (addressable_polygons.prop_id (), addressable_polygons.operator-> ()));
|
||||
addressable_polygons.inc ();
|
||||
}
|
||||
|
||||
std::sort (polygons_by_prop_id.begin (), polygons_by_prop_id.end ());
|
||||
|
||||
for (auto p = polygons_by_prop_id.begin (); p != polygons_by_prop_id.end (); ) {
|
||||
|
||||
auto pp = p;
|
||||
while (pp != polygons_by_prop_id.end () && pp->first == p->first) {
|
||||
++pp;
|
||||
}
|
||||
|
||||
ep.clear ();
|
||||
|
||||
n = 0;
|
||||
for (auto i = p; i != pp; ++i) {
|
||||
n += i->second->vertices ();
|
||||
}
|
||||
ep.reserve (n);
|
||||
|
||||
n = 0;
|
||||
for (auto i = p; i != pp; ++i, ++n) {
|
||||
ep.insert (*i->second, n);
|
||||
}
|
||||
|
||||
// and run the merge step
|
||||
db::MergeOp op (min_wc);
|
||||
db::ShapeGenerator pc (result, false /*don't clear*/, p->first);
|
||||
db::PolygonGenerator pg (pc, false /*don't resolve holes*/, min_coherence);
|
||||
ep.process (pg, op);
|
||||
|
||||
p = pp;
|
||||
|
||||
}
|
||||
|
||||
output.swap (result);
|
||||
|
||||
} else {
|
||||
|
||||
n = 0;
|
||||
for (RegionIterator p (begin ()); ! p.at_end (); ++p) {
|
||||
n += p->vertices ();
|
||||
}
|
||||
ep.reserve (n);
|
||||
|
||||
// insert the polygons into the processor
|
||||
n = 0;
|
||||
for (RegionIterator p (begin ()); ! p.at_end (); ++p, ++n) {
|
||||
ep.insert (*p, n);
|
||||
}
|
||||
|
||||
output.clear ();
|
||||
|
||||
// and run the merge step
|
||||
db::MergeOp op (min_wc);
|
||||
db::ShapeGenerator pc (output, false /*don't clear*/, prop_id);
|
||||
db::PolygonGenerator pg (pc, false /*don't resolve holes*/, min_coherence);
|
||||
ep.process (pg, op);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
AsIfFlatRegion::filtered (const PolygonFilterBase &filter) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@ public:
|
|||
protected:
|
||||
void update_bbox (const db::Box &box);
|
||||
void invalidate_bbox ();
|
||||
void merge_polygons_to (db::Shapes &output, bool min_coherence, unsigned int min_wc) const;
|
||||
|
||||
virtual EdgePairsDelegate *run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, const RegionCheckOptions &options) const;
|
||||
virtual EdgePairsDelegate *run_single_polygon_check (db::edge_relation_type rel, db::Coord d, const RegionCheckOptions &options) const;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public:
|
|||
typedef db::EdgePair value_type;
|
||||
|
||||
DeepEdgePairsIterator (const db::RecursiveShapeIterator &iter)
|
||||
: m_iter (iter)
|
||||
: m_iter (iter), m_prop_id (0)
|
||||
{
|
||||
set ();
|
||||
}
|
||||
|
|
@ -72,6 +72,11 @@ public:
|
|||
return &m_edge_pair;
|
||||
}
|
||||
|
||||
virtual db::properties_id_type prop_id () const
|
||||
{
|
||||
return m_prop_id;
|
||||
}
|
||||
|
||||
virtual bool equals (const generic_shape_iterator_delegate_base<value_type> *other) const
|
||||
{
|
||||
const DeepEdgePairsIterator *o = dynamic_cast<const DeepEdgePairsIterator *> (other);
|
||||
|
|
@ -100,12 +105,14 @@ private:
|
|||
|
||||
db::RecursiveShapeIterator m_iter;
|
||||
mutable value_type m_edge_pair;
|
||||
mutable db::properties_id_type m_prop_id;
|
||||
|
||||
void set () const
|
||||
{
|
||||
if (! m_iter.at_end ()) {
|
||||
m_iter.shape ().edge_pair (m_edge_pair);
|
||||
m_iter->edge_pair (m_edge_pair);
|
||||
m_edge_pair.transform (m_iter.trans ());
|
||||
m_prop_id = m_iter->prop_id ();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ public:
|
|||
typedef db::Edge value_type;
|
||||
|
||||
DeepEdgesIterator (const db::RecursiveShapeIterator &iter)
|
||||
: m_iter (iter)
|
||||
: m_iter (iter), m_prop_id (0)
|
||||
{
|
||||
set ();
|
||||
}
|
||||
|
|
@ -82,6 +82,11 @@ public:
|
|||
return &m_edge;
|
||||
}
|
||||
|
||||
virtual db::properties_id_type prop_id () const
|
||||
{
|
||||
return m_prop_id;
|
||||
}
|
||||
|
||||
virtual bool equals (const generic_shape_iterator_delegate_base<value_type> *other) const
|
||||
{
|
||||
const DeepEdgesIterator *o = dynamic_cast<const DeepEdgesIterator *> (other);
|
||||
|
|
@ -110,12 +115,14 @@ private:
|
|||
|
||||
db::RecursiveShapeIterator m_iter;
|
||||
mutable value_type m_edge;
|
||||
mutable db::properties_id_type m_prop_id;
|
||||
|
||||
void set () const
|
||||
{
|
||||
if (! m_iter.at_end ()) {
|
||||
m_iter.shape ().edge (m_edge);
|
||||
m_iter->edge (m_edge);
|
||||
m_edge.transform (m_iter.trans ());
|
||||
m_prop_id = m_iter->prop_id ();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public:
|
|||
typedef db::Polygon value_type;
|
||||
|
||||
DeepRegionIterator (const db::RecursiveShapeIterator &iter)
|
||||
: m_iter (iter)
|
||||
: m_iter (iter), m_prop_id (0)
|
||||
{
|
||||
set ();
|
||||
}
|
||||
|
|
@ -85,6 +85,11 @@ public:
|
|||
return &m_polygon;
|
||||
}
|
||||
|
||||
virtual db::properties_id_type prop_id () const
|
||||
{
|
||||
return m_prop_id;
|
||||
}
|
||||
|
||||
virtual bool equals (const generic_shape_iterator_delegate_base<value_type> *other) const
|
||||
{
|
||||
const DeepRegionIterator *o = dynamic_cast<const DeepRegionIterator *> (other);
|
||||
|
|
@ -113,12 +118,14 @@ private:
|
|||
|
||||
db::RecursiveShapeIterator m_iter;
|
||||
mutable value_type m_polygon;
|
||||
mutable db::properties_id_type m_prop_id;
|
||||
|
||||
void set () const
|
||||
{
|
||||
if (! m_iter.at_end ()) {
|
||||
m_iter.shape ().polygon (m_polygon);
|
||||
m_iter->polygon (m_polygon);
|
||||
m_polygon.transform (m_iter.trans (), false);
|
||||
m_prop_id = m_iter->prop_id ();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -220,12 +227,17 @@ void DeepRegion::min_coherence_changed ()
|
|||
set_is_merged (false);
|
||||
}
|
||||
|
||||
void DeepRegion::do_insert (const db::Polygon &polygon)
|
||||
void DeepRegion::do_insert (const db::Polygon &polygon, db::properties_id_type prop_id)
|
||||
{
|
||||
db::Layout &layout = deep_layer ().layout ();
|
||||
if (layout.begin_top_down () != layout.end_top_down ()) {
|
||||
db::Cell &top_cell = layout.cell (*layout.begin_top_down ());
|
||||
top_cell.shapes (deep_layer ().layer ()).insert (db::PolygonRef (polygon, layout.shape_repository ()));
|
||||
db::Shapes &shapes = top_cell.shapes (deep_layer ().layer ());
|
||||
if (prop_id == 0) {
|
||||
shapes.insert (db::PolygonRef (polygon, layout.shape_repository ()));
|
||||
} else {
|
||||
shapes.insert (db::PolygonRefWithProperties (db::PolygonRef (polygon, layout.shape_repository ()), prop_id));
|
||||
}
|
||||
}
|
||||
|
||||
invalidate_bbox ();
|
||||
|
|
@ -439,6 +451,12 @@ DeepRegion::nth (size_t) const
|
|||
throw tl::Exception (tl::to_string (tr ("Random access to polygons is available only for flat regions")));
|
||||
}
|
||||
|
||||
db::properties_id_type
|
||||
DeepRegion::nth_prop_id (size_t) const
|
||||
{
|
||||
throw tl::Exception (tl::to_string (tr ("Random access to polygons is available only for flat regions")));
|
||||
}
|
||||
|
||||
bool
|
||||
DeepRegion::has_valid_polygons () const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ public:
|
|||
|
||||
RegionDelegate *clone () const;
|
||||
|
||||
virtual void do_insert (const db::Polygon &polygon);
|
||||
virtual void do_insert (const db::Polygon &polygon, db::properties_id_type prop_id);
|
||||
|
||||
virtual void do_transform (const db::Trans &t);
|
||||
virtual void do_transform (const db::ICplxTrans &t);
|
||||
|
|
@ -74,6 +74,7 @@ public:
|
|||
virtual bool is_merged () const;
|
||||
|
||||
virtual const db::Polygon *nth (size_t n) const;
|
||||
virtual db::properties_id_type nth_prop_id (size_t n) const;
|
||||
virtual bool has_valid_polygons () const;
|
||||
virtual bool has_valid_merged_polygons () const;
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ public:
|
|||
typedef db::Text value_type;
|
||||
|
||||
DeepTextsIterator (const db::RecursiveShapeIterator &iter)
|
||||
: m_iter (iter)
|
||||
: m_iter (iter), m_prop_id (0)
|
||||
{
|
||||
set ();
|
||||
}
|
||||
|
|
@ -77,6 +77,11 @@ public:
|
|||
return &m_text;
|
||||
}
|
||||
|
||||
virtual db::properties_id_type prop_id () const
|
||||
{
|
||||
return m_prop_id;
|
||||
}
|
||||
|
||||
virtual bool equals (const generic_shape_iterator_delegate_base<value_type> *other) const
|
||||
{
|
||||
const DeepTextsIterator *o = dynamic_cast<const DeepTextsIterator *> (other);
|
||||
|
|
@ -105,12 +110,14 @@ private:
|
|||
|
||||
db::RecursiveShapeIterator m_iter;
|
||||
mutable value_type m_text;
|
||||
mutable db::properties_id_type m_prop_id;
|
||||
|
||||
void set () const
|
||||
{
|
||||
if (! m_iter.at_end ()) {
|
||||
m_iter.shape ().text (m_text);
|
||||
m_iter->text (m_text);
|
||||
m_text.transform (m_iter.trans ());
|
||||
m_prop_id = m_iter->prop_id ();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ public:
|
|||
virtual bool has_valid_polygons () const { return true; }
|
||||
virtual bool has_valid_merged_polygons () const { return true; }
|
||||
virtual const db::Polygon *nth (size_t) const { tl_assert (false); }
|
||||
virtual db::properties_id_type nth_prop_id (size_t) const { tl_assert (false); }
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const { return 0; }
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "dbEmptyRegion.h"
|
||||
#include "dbRegion.h"
|
||||
#include "dbShapeProcessor.h"
|
||||
#include "tlSList.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
|
@ -108,33 +109,8 @@ void
|
|||
FlatRegion::ensure_merged_polygons_valid () const
|
||||
{
|
||||
if (! m_merged_polygons_valid) {
|
||||
|
||||
mp_merged_polygons->clear ();
|
||||
|
||||
db::EdgeProcessor ep (report_progress (), progress_desc ());
|
||||
ep.set_base_verbosity (base_verbosity ());
|
||||
|
||||
// count edges and reserve memory
|
||||
size_t n = 0;
|
||||
for (RegionIterator p (begin ()); ! p.at_end (); ++p) {
|
||||
n += p->vertices ();
|
||||
}
|
||||
ep.reserve (n);
|
||||
|
||||
// insert the polygons into the processor
|
||||
n = 0;
|
||||
for (RegionIterator p (begin ()); ! p.at_end (); ++p, ++n) {
|
||||
ep.insert (*p, n);
|
||||
}
|
||||
|
||||
// and run the merge step
|
||||
db::MergeOp op (0);
|
||||
db::ShapeGenerator pc (*mp_merged_polygons);
|
||||
db::PolygonGenerator pg (pc, false /*don't resolve holes*/, min_coherence ());
|
||||
ep.process (pg, op);
|
||||
|
||||
merge_polygons_to (*mp_merged_polygons, min_coherence (), 0);
|
||||
m_merged_polygons_valid = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -279,28 +255,7 @@ RegionDelegate *FlatRegion::merged_in_place (bool min_coherence, unsigned int mi
|
|||
} else {
|
||||
|
||||
invalidate_cache ();
|
||||
|
||||
db::EdgeProcessor ep (report_progress (), progress_desc ());
|
||||
ep.set_base_verbosity (base_verbosity ());
|
||||
|
||||
// count edges and reserve memory
|
||||
size_t n = 0;
|
||||
for (RegionIterator p (begin ()); ! p.at_end (); ++p) {
|
||||
n += p->vertices ();
|
||||
}
|
||||
ep.reserve (n);
|
||||
|
||||
// insert the polygons into the processor
|
||||
n = 0;
|
||||
for (RegionIterator p (begin ()); ! p.at_end (); ++p, ++n) {
|
||||
ep.insert (*p, n);
|
||||
}
|
||||
|
||||
// and run the merge step
|
||||
db::MergeOp op (min_wc);
|
||||
db::ShapeGenerator pc (*mp_polygons, true /*clear*/);
|
||||
db::PolygonGenerator pg (pc, false /*don't resolve holes*/, min_coherence);
|
||||
ep.process (pg, op);
|
||||
merge_polygons_to (*mp_polygons, min_coherence, min_wc);
|
||||
|
||||
m_is_merged = true;
|
||||
|
||||
|
|
@ -385,7 +340,46 @@ RegionDelegate *FlatRegion::add_in_place (const Region &other)
|
|||
|
||||
const db::Polygon *FlatRegion::nth (size_t n) const
|
||||
{
|
||||
return n < mp_polygons->size () ? &mp_polygons->get_layer<db::Polygon, db::unstable_layer_tag> ().begin () [n] : 0;
|
||||
// NOTE: this assumes that we iterate over non-property polygons first and then over polygons with properties
|
||||
|
||||
if (n >= mp_polygons->size ()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const db::layer<db::Polygon, db::unstable_layer_tag> &l = mp_polygons->get_layer<db::Polygon, db::unstable_layer_tag> ();
|
||||
if (n < l.size ()) {
|
||||
return &l.begin () [n];
|
||||
}
|
||||
n -= l.size ();
|
||||
|
||||
const db::layer<db::PolygonWithProperties, db::unstable_layer_tag> &lp = mp_polygons->get_layer<db::PolygonWithProperties, db::unstable_layer_tag> ();
|
||||
if (n < lp.size ()) {
|
||||
return &lp.begin () [n];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
db::properties_id_type FlatRegion::nth_prop_id (size_t n) const
|
||||
{
|
||||
// NOTE: this assumes that we iterate over non-property polygons first and then over polygons with properties
|
||||
|
||||
if (n >= mp_polygons->size ()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const db::layer<db::Polygon, db::unstable_layer_tag> &l = mp_polygons->get_layer<db::Polygon, db::unstable_layer_tag> ();
|
||||
if (n < l.size ()) {
|
||||
return 0;
|
||||
}
|
||||
n -= l.size ();
|
||||
|
||||
const db::layer<db::PolygonWithProperties, db::unstable_layer_tag> &lp = mp_polygons->get_layer<db::PolygonWithProperties, db::unstable_layer_tag> ();
|
||||
if (n < lp.size ()) {
|
||||
return lp.begin () [n].properties_id ();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FlatRegion::has_valid_polygons () const
|
||||
|
|
@ -409,13 +403,17 @@ void FlatRegion::insert_into (Layout *layout, db::cell_index_type into_cell, uns
|
|||
}
|
||||
|
||||
void
|
||||
FlatRegion::do_insert (const db::Polygon &polygon)
|
||||
FlatRegion::do_insert (const db::Polygon &polygon, properties_id_type prop_id)
|
||||
{
|
||||
if (polygon.holes () > 0 || polygon.vertices () > 0) {
|
||||
|
||||
bool is_box = (empty () && polygon.is_box ());
|
||||
|
||||
mp_polygons->insert (polygon);
|
||||
if (prop_id != 0) {
|
||||
mp_polygons->insert (db::PolygonWithProperties (polygon, prop_id));
|
||||
} else {
|
||||
mp_polygons->insert (polygon);
|
||||
}
|
||||
set_is_merged (is_box);
|
||||
|
||||
invalidate_cache ();
|
||||
|
|
|
|||
|
|
@ -92,12 +92,13 @@ public:
|
|||
virtual RegionDelegate *add (const Region &other) const;
|
||||
|
||||
virtual const db::Polygon *nth (size_t n) const;
|
||||
virtual db::properties_id_type nth_prop_id (size_t) const;
|
||||
virtual bool has_valid_polygons () const;
|
||||
virtual bool has_valid_merged_polygons () const;
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const;
|
||||
|
||||
void do_insert (const db::Polygon &polygon);
|
||||
void do_insert (const db::Polygon &polygon, db::properties_id_type prop_id);
|
||||
|
||||
void do_transform (const db::Trans &t)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ public:
|
|||
virtual bool at_end () const = 0;
|
||||
virtual void increment () = 0;
|
||||
virtual const T *get () const = 0;
|
||||
virtual db::properties_id_type prop_id () const = 0;
|
||||
virtual generic_shape_iterator_delegate_base<T> *clone () const = 0;
|
||||
virtual bool equals (const generic_shape_iterator_delegate_base<T> *other) const = 0;
|
||||
};
|
||||
|
|
@ -86,6 +87,11 @@ public:
|
|||
return m_iter.operator-> ();
|
||||
}
|
||||
|
||||
virtual db::properties_id_type prop_id () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
generic_shape_iterator_delegate_base<value_type> *clone () const
|
||||
{
|
||||
return new generic_shape_iterator_delegate2<Iter> (*this);
|
||||
|
|
@ -141,6 +147,11 @@ public:
|
|||
return m_iter.operator-> ();
|
||||
}
|
||||
|
||||
virtual db::properties_id_type prop_id () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
generic_shape_iterator_delegate_base<value_type> *clone () const
|
||||
{
|
||||
return new generic_shape_iterator_delegate1<Iter> (*this);
|
||||
|
|
@ -217,6 +228,11 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
virtual db::properties_id_type prop_id () const
|
||||
{
|
||||
return m_iter->prop_id ();
|
||||
}
|
||||
|
||||
generic_shape_iterator_delegate_base<T> *clone () const
|
||||
{
|
||||
return new generic_shapes_iterator_delegate<T> (*this);
|
||||
|
|
@ -319,6 +335,11 @@ public:
|
|||
return ! mp_delegate || mp_delegate->is_addressable ();
|
||||
}
|
||||
|
||||
db::properties_id_type prop_id () const
|
||||
{
|
||||
return mp_delegate ? mp_delegate->prop_id () : 0;
|
||||
}
|
||||
|
||||
reference operator* () const
|
||||
{
|
||||
return *mp_delegate->get ();
|
||||
|
|
@ -422,6 +443,11 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
db::properties_id_type prop_id () const
|
||||
{
|
||||
return m_iter.prop_id ();
|
||||
}
|
||||
|
||||
private:
|
||||
Iter m_iter;
|
||||
bool m_iterator_is_addressable;
|
||||
|
|
|
|||
|
|
@ -986,11 +986,7 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
|
|||
db::properties_id_type
|
||||
LayoutToNetlist::make_netname_propid (db::Layout &ly, NetPropertyMode net_prop_mode, const tl::Variant &netname_prop, const db::Net &net) const
|
||||
{
|
||||
if (net_prop_mode == FakePropId) {
|
||||
|
||||
return reinterpret_cast<db::properties_id_type> (&net);
|
||||
|
||||
} else if (net_prop_mode == NoProperties) {
|
||||
if (net_prop_mode == NoProperties) {
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -727,12 +727,6 @@ public:
|
|||
* @brief Like NetNameOnly, but use a unique net ID (db::Net address actually) instead of name
|
||||
*/
|
||||
NetIDOnly,
|
||||
|
||||
/**
|
||||
* @brief Use the net ID (db::Net address) directly as property ID
|
||||
* Caution: you need to know what you're doing if you use that mode.
|
||||
*/
|
||||
FakePropId
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -50,7 +50,15 @@ void
|
|||
MutableRegion::insert (const db::Box &box)
|
||||
{
|
||||
if (! box.empty () && box.width () > 0 && box.height () > 0) {
|
||||
do_insert (db::Polygon (box));
|
||||
do_insert (db::Polygon (box), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MutableRegion::insert (const db::BoxWithProperties &box)
|
||||
{
|
||||
if (! box.empty () && box.width () > 0 && box.height () > 0) {
|
||||
do_insert (db::Polygon (box), box.properties_id ());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -58,7 +66,15 @@ void
|
|||
MutableRegion::insert (const db::Path &path)
|
||||
{
|
||||
if (path.points () > 0) {
|
||||
do_insert (path.polygon ());
|
||||
do_insert (path.polygon (), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MutableRegion::insert (const db::PathWithProperties &path)
|
||||
{
|
||||
if (path.points () > 0) {
|
||||
do_insert (path.polygon (), path.properties_id ());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -68,7 +84,17 @@ MutableRegion::insert (const db::SimplePolygon &polygon)
|
|||
if (polygon.vertices () > 0) {
|
||||
db::Polygon poly;
|
||||
poly.assign_hull (polygon.begin_hull (), polygon.end_hull ());
|
||||
do_insert (poly);
|
||||
do_insert (poly, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MutableRegion::insert (const db::SimplePolygonWithProperties &polygon)
|
||||
{
|
||||
if (polygon.vertices () > 0) {
|
||||
db::Polygon poly;
|
||||
poly.assign_hull (polygon.begin_hull (), polygon.end_hull ());
|
||||
do_insert (poly, polygon.properties_id ());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -78,13 +104,8 @@ MutableRegion::insert (const db::Shape &shape)
|
|||
if (shape.is_polygon () || shape.is_path () || shape.is_box ()) {
|
||||
db::Polygon poly;
|
||||
shape.polygon (poly);
|
||||
insert (poly);
|
||||
} else if (shape.is_path ()) {
|
||||
insert (shape.path ());
|
||||
} else if (shape.is_box ()) {
|
||||
insert (shape.box ());
|
||||
do_insert (poly, shape.prop_id ());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ public:
|
|||
MutableRegion (const MutableRegion &other);
|
||||
virtual ~MutableRegion ();
|
||||
|
||||
virtual void do_insert (const db::Polygon &polygon) = 0;
|
||||
virtual void do_insert (const db::Polygon &polygon, db::properties_id_type prop_id) = 0;
|
||||
|
||||
void transform (const db::UnitTrans &) { }
|
||||
void transform (const db::Disp &t) { do_transform (db::Trans (t)); }
|
||||
|
|
@ -63,10 +63,14 @@ public:
|
|||
|
||||
virtual void reserve (size_t n) = 0;
|
||||
|
||||
void insert (const db::Polygon &polygon) { do_insert (polygon); }
|
||||
void insert (const db::Polygon &polygon) { do_insert (polygon, 0); }
|
||||
void insert (const db::PolygonWithProperties &polygon) { do_insert (polygon, polygon.properties_id ()); }
|
||||
void insert (const db::Box &box);
|
||||
void insert (const db::BoxWithProperties &box);
|
||||
void insert (const db::Path &path);
|
||||
void insert (const db::PathWithProperties &path);
|
||||
void insert (const db::SimplePolygon &polygon);
|
||||
void insert (const db::SimplePolygonWithProperties &polygon);
|
||||
|
||||
void insert (const db::Shape &shape);
|
||||
|
||||
|
|
@ -77,7 +81,7 @@ public:
|
|||
db::Polygon poly;
|
||||
shape.polygon (poly);
|
||||
poly.transform (trans);
|
||||
insert (poly);
|
||||
do_insert (poly, shape.prop_id ());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ namespace
|
|||
typedef db::EdgePair value_type;
|
||||
|
||||
OriginalLayerEdgePairsIterator (const db::RecursiveShapeIterator &iter, const db::ICplxTrans &trans)
|
||||
: m_rec_iter (iter), m_iter_trans (trans)
|
||||
: m_rec_iter (iter), m_iter_trans (trans), m_prop_id (0)
|
||||
{
|
||||
set ();
|
||||
}
|
||||
|
|
@ -67,6 +67,11 @@ namespace
|
|||
return &m_shape;
|
||||
}
|
||||
|
||||
virtual db::properties_id_type prop_id () const
|
||||
{
|
||||
return m_prop_id;
|
||||
}
|
||||
|
||||
virtual EdgePairsIteratorDelegate *clone () const
|
||||
{
|
||||
return new OriginalLayerEdgePairsIterator (*this);
|
||||
|
|
@ -100,15 +105,17 @@ namespace
|
|||
db::RecursiveShapeIterator m_rec_iter;
|
||||
db::ICplxTrans m_iter_trans;
|
||||
value_type m_shape;
|
||||
db::properties_id_type m_prop_id;
|
||||
|
||||
void set ()
|
||||
{
|
||||
while (! m_rec_iter.at_end () && !m_rec_iter.shape ().is_edge_pair ()) {
|
||||
while (! m_rec_iter.at_end () && !m_rec_iter->is_edge_pair ()) {
|
||||
++m_rec_iter;
|
||||
}
|
||||
if (! m_rec_iter.at_end ()) {
|
||||
m_rec_iter.shape ().edge_pair (m_shape);
|
||||
m_rec_iter->edge_pair (m_shape);
|
||||
m_shape.transform (m_iter_trans * m_rec_iter.trans ());
|
||||
m_prop_id = (m_rec_iter.shape_flags () & db::ShapeIterator::Properties) != 0 ? m_rec_iter->prop_id () : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ namespace
|
|||
typedef db::Edge value_type;
|
||||
|
||||
OriginalLayerEdgesIterator (const db::RecursiveShapeIterator &iter, const db::ICplxTrans &trans)
|
||||
: m_rec_iter (iter), m_iter_trans (trans)
|
||||
: m_rec_iter (iter), m_iter_trans (trans), m_prop_id (0)
|
||||
{
|
||||
set ();
|
||||
}
|
||||
|
|
@ -68,6 +68,11 @@ namespace
|
|||
return &m_shape;
|
||||
}
|
||||
|
||||
virtual db::properties_id_type prop_id () const
|
||||
{
|
||||
return m_prop_id;
|
||||
}
|
||||
|
||||
virtual EdgesIteratorDelegate *clone () const
|
||||
{
|
||||
return new OriginalLayerEdgesIterator (*this);
|
||||
|
|
@ -101,15 +106,17 @@ namespace
|
|||
db::RecursiveShapeIterator m_rec_iter;
|
||||
db::ICplxTrans m_iter_trans;
|
||||
value_type m_shape;
|
||||
db::properties_id_type m_prop_id;
|
||||
|
||||
void set ()
|
||||
{
|
||||
while (! m_rec_iter.at_end () && !m_rec_iter.shape ().is_edge ()) {
|
||||
while (! m_rec_iter.at_end () && !m_rec_iter->is_edge ()) {
|
||||
++m_rec_iter;
|
||||
}
|
||||
if (! m_rec_iter.at_end ()) {
|
||||
m_rec_iter.shape ().edge (m_shape);
|
||||
m_rec_iter->edge (m_shape);
|
||||
m_shape.transform (m_iter_trans * m_rec_iter.trans ());
|
||||
m_prop_id = (m_rec_iter.shape_flags () & db::ShapeIterator::Properties) != 0 ? m_rec_iter->prop_id () : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -120,7 +127,6 @@ namespace
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
OriginalLayerEdges::OriginalLayerEdges ()
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
#include "dbFlatRegion.h"
|
||||
#include "dbFlatEdges.h"
|
||||
#include "dbRegion.h"
|
||||
#include "dbShapeProcessor.h"
|
||||
#include "dbDeepEdges.h"
|
||||
#include "dbDeepRegion.h"
|
||||
#include "dbDeepShapeStore.h"
|
||||
|
|
@ -46,7 +45,7 @@ namespace
|
|||
{
|
||||
public:
|
||||
OriginalLayerRegionIterator (const db::RecursiveShapeIterator &iter, const db::ICplxTrans &trans)
|
||||
: m_rec_iter (iter), m_iter_trans (trans)
|
||||
: m_rec_iter (iter), m_iter_trans (trans), m_prop_id (0)
|
||||
{
|
||||
set ();
|
||||
}
|
||||
|
|
@ -72,6 +71,11 @@ namespace
|
|||
return &m_polygon;
|
||||
}
|
||||
|
||||
virtual db::properties_id_type prop_id () const
|
||||
{
|
||||
return m_prop_id;
|
||||
}
|
||||
|
||||
virtual RegionIteratorDelegate *clone () const
|
||||
{
|
||||
return new OriginalLayerRegionIterator (*this);
|
||||
|
|
@ -105,15 +109,17 @@ namespace
|
|||
db::RecursiveShapeIterator m_rec_iter;
|
||||
db::ICplxTrans m_iter_trans;
|
||||
db::Polygon m_polygon;
|
||||
db::properties_id_type m_prop_id;
|
||||
|
||||
void set ()
|
||||
{
|
||||
while (! m_rec_iter.at_end () && ! (m_rec_iter.shape ().is_polygon () || m_rec_iter.shape ().is_path () || m_rec_iter.shape ().is_box ())) {
|
||||
while (! m_rec_iter.at_end () && ! (m_rec_iter->is_polygon () || m_rec_iter->is_path () || m_rec_iter->is_box ())) {
|
||||
++m_rec_iter;
|
||||
}
|
||||
if (! m_rec_iter.at_end ()) {
|
||||
m_rec_iter.shape ().polygon (m_polygon);
|
||||
m_rec_iter->polygon (m_polygon);
|
||||
m_polygon.transform (m_iter_trans * m_rec_iter.trans (), false);
|
||||
m_prop_id = (m_rec_iter.shape_flags () & db::ShapeIterator::Properties) != 0 ? m_rec_iter->prop_id () : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -339,6 +345,12 @@ OriginalLayerRegion::nth (size_t) const
|
|||
throw tl::Exception (tl::to_string (tr ("Random access to polygons is available only for flat regions")));
|
||||
}
|
||||
|
||||
db::properties_id_type
|
||||
OriginalLayerRegion::nth_prop_id (size_t) const
|
||||
{
|
||||
throw tl::Exception (tl::to_string (tr ("Random access to polygons is available only for flat regions")));
|
||||
}
|
||||
|
||||
bool
|
||||
OriginalLayerRegion::has_valid_polygons () const
|
||||
{
|
||||
|
|
@ -412,28 +424,7 @@ OriginalLayerRegion::ensure_merged_polygons_valid () const
|
|||
if (! m_merged_polygons_valid) {
|
||||
|
||||
m_merged_polygons.clear ();
|
||||
|
||||
db::EdgeProcessor ep (report_progress (), progress_desc ());
|
||||
ep.set_base_verbosity (base_verbosity ());
|
||||
|
||||
// count edges and reserve memory
|
||||
size_t n = 0;
|
||||
for (RegionIterator p (begin ()); ! p.at_end (); ++p) {
|
||||
n += p->vertices ();
|
||||
}
|
||||
ep.reserve (n);
|
||||
|
||||
// insert the polygons into the processor
|
||||
n = 0;
|
||||
for (RegionIterator p (begin ()); ! p.at_end (); ++p, ++n) {
|
||||
ep.insert (*p, n);
|
||||
}
|
||||
|
||||
// and run the merge step
|
||||
db::MergeOp op (0);
|
||||
db::ShapeGenerator pc (m_merged_polygons);
|
||||
db::PolygonGenerator pg (pc, false /*don't resolve holes*/, min_coherence ());
|
||||
ep.process (pg, op);
|
||||
merge_polygons_to (m_merged_polygons, min_coherence (), 0);
|
||||
|
||||
m_merged_polygons_valid = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ public:
|
|||
virtual size_t hier_count () const;
|
||||
|
||||
virtual const db::Polygon *nth (size_t n) const;
|
||||
virtual db::properties_id_type nth_prop_id (size_t) const;
|
||||
virtual bool has_valid_polygons () const;
|
||||
virtual bool has_valid_merged_polygons () const;
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ namespace
|
|||
typedef db::Text value_type;
|
||||
|
||||
OriginalLayerTextsIterator (const db::RecursiveShapeIterator &iter, const db::ICplxTrans &trans)
|
||||
: m_rec_iter (iter), m_iter_trans (trans)
|
||||
: m_rec_iter (iter), m_iter_trans (trans), m_prop_id (0)
|
||||
{
|
||||
set ();
|
||||
}
|
||||
|
|
@ -67,6 +67,11 @@ namespace
|
|||
return &m_shape;
|
||||
}
|
||||
|
||||
virtual db::properties_id_type prop_id () const
|
||||
{
|
||||
return m_prop_id;
|
||||
}
|
||||
|
||||
virtual OriginalLayerTextsIterator *clone () const
|
||||
{
|
||||
return new OriginalLayerTextsIterator (*this);
|
||||
|
|
@ -100,6 +105,7 @@ namespace
|
|||
db::RecursiveShapeIterator m_rec_iter;
|
||||
db::ICplxTrans m_iter_trans;
|
||||
value_type m_shape;
|
||||
db::properties_id_type m_prop_id;
|
||||
|
||||
void set ()
|
||||
{
|
||||
|
|
@ -107,8 +113,9 @@ namespace
|
|||
++m_rec_iter;
|
||||
}
|
||||
if (! m_rec_iter.at_end ()) {
|
||||
m_rec_iter.shape ().text (m_shape);
|
||||
m_rec_iter->text (m_shape);
|
||||
m_shape.transform (m_iter_trans * m_rec_iter.trans ());
|
||||
m_prop_id = (m_rec_iter.shape_flags () & db::ShapeIterator::Properties) != 0 ? m_rec_iter->prop_id () : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -155,9 +155,13 @@ void Region::insert (const Sh &shape)
|
|||
}
|
||||
|
||||
template DB_PUBLIC void Region::insert (const db::Box &);
|
||||
template DB_PUBLIC void Region::insert (const db::BoxWithProperties &);
|
||||
template DB_PUBLIC void Region::insert (const db::SimplePolygon &);
|
||||
template DB_PUBLIC void Region::insert (const db::SimplePolygonWithProperties &);
|
||||
template DB_PUBLIC void Region::insert (const db::Polygon &);
|
||||
template DB_PUBLIC void Region::insert (const db::PolygonWithProperties &);
|
||||
template DB_PUBLIC void Region::insert (const db::Path &);
|
||||
template DB_PUBLIC void Region::insert (const db::PathWithProperties &);
|
||||
|
||||
void Region::insert (const db::Shape &shape)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -168,6 +168,15 @@ public:
|
|||
insert (s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructor from a box with properties
|
||||
*/
|
||||
explicit Region (const db::BoxWithProperties &s)
|
||||
: mp_delegate (0)
|
||||
{
|
||||
insert (s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructor from a polygon
|
||||
*/
|
||||
|
|
@ -177,6 +186,15 @@ public:
|
|||
insert (s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructor from a polygon with properties
|
||||
*/
|
||||
explicit Region (const db::PolygonWithProperties &s)
|
||||
: mp_delegate (0)
|
||||
{
|
||||
insert (s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructor from a simple polygon
|
||||
*/
|
||||
|
|
@ -186,6 +204,15 @@ public:
|
|||
insert (s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructor from a simple polygon with properties
|
||||
*/
|
||||
explicit Region (const db::SimplePolygonWithProperties &s)
|
||||
: mp_delegate (0)
|
||||
{
|
||||
insert (s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructor from a path
|
||||
*/
|
||||
|
|
@ -195,6 +222,15 @@ public:
|
|||
insert (s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructor from a path with properties
|
||||
*/
|
||||
explicit Region (const db::PathWithProperties &s)
|
||||
: mp_delegate (0)
|
||||
{
|
||||
insert (s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sequence constructor
|
||||
*
|
||||
|
|
@ -1652,6 +1688,17 @@ public:
|
|||
return mp_delegate->nth (n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the nth polygon's property ID
|
||||
*
|
||||
* This operation is available only for flat regions - i.e. such for which
|
||||
* "has_valid_polygons" is true.
|
||||
*/
|
||||
db::properties_id_type nth_prop_id (size_t n) const
|
||||
{
|
||||
return mp_delegate->nth_prop_id (n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Forces flattening of the region
|
||||
*
|
||||
|
|
|
|||
|
|
@ -311,6 +311,7 @@ public:
|
|||
virtual std::pair<RegionDelegate *, RegionDelegate *> in_and_out (const Region &other) const = 0;
|
||||
|
||||
virtual const db::Polygon *nth (size_t n) const = 0;
|
||||
virtual db::properties_id_type nth_prop_id (size_t n) const = 0;
|
||||
virtual bool has_valid_polygons () const = 0;
|
||||
virtual bool has_valid_merged_polygons () const = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -56,10 +56,12 @@ public:
|
|||
* the start method is called and when the shape container is cleared if "clear_shapes"
|
||||
* is set.
|
||||
*
|
||||
* @param shapes Where to store the shapes
|
||||
* @param clear_shapes If true, the shapes container is cleared on the start event.
|
||||
* @param prop_id The properties ID to assign to all the output shapes (or 0 if no property shall be assigned)
|
||||
*/
|
||||
ShapeGenerator (db::Shapes &shapes, bool clear_shapes = false)
|
||||
: PolygonSink (), mp_shapes (&shapes), m_clear_shapes (clear_shapes)
|
||||
ShapeGenerator (db::Shapes &shapes, bool clear_shapes = false, db::properties_id_type prop_id = 0)
|
||||
: PolygonSink (), mp_shapes (&shapes), m_clear_shapes (clear_shapes), m_prop_id (prop_id)
|
||||
{ }
|
||||
|
||||
/**
|
||||
|
|
@ -67,7 +69,11 @@ public:
|
|||
*/
|
||||
virtual void put (const db::Polygon &polygon)
|
||||
{
|
||||
mp_shapes->insert (polygon);
|
||||
if (m_prop_id) {
|
||||
mp_shapes->insert (db::PolygonWithProperties (polygon, m_prop_id));
|
||||
} else {
|
||||
mp_shapes->insert (polygon);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -85,6 +91,7 @@ public:
|
|||
private:
|
||||
db::Shapes *mp_shapes;
|
||||
bool m_clear_shapes;
|
||||
db::properties_id_type m_prop_id;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ TEST(0_Develop)
|
|||
lmap_write [wvia1 = ly2.insert_layer (db::LayerProperties (16, 0))] = l2n.layer_by_name ("via1");
|
||||
lmap_write [wmetal2 = ly2.insert_layer (db::LayerProperties (17, 0))] = l2n.layer_by_name ("metal2");
|
||||
|
||||
l2n.build_all_nets (cm, ly2, lmap_write, "NET_", db::LayoutToNetlist::FakePropId, tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "SC_", 0 /*don't produce devices*/);
|
||||
l2n.build_all_nets (cm, ly2, lmap_write, "NET_", db::LayoutToNetlist::NetIDOnly, tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "SC_", 0 /*don't produce devices*/);
|
||||
|
||||
unsigned int out = ly2.insert_layer (db::LayerProperties (1000, 0));
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue