mirror of https://github.com/KLayout/klayout.git
WIP: refactoring - texts for net extractor.
This commit is contained in:
parent
371009ba80
commit
4c13bb96a0
|
|
@ -193,7 +193,8 @@ SOURCES = \
|
|||
dbEmptyTexts.cc \
|
||||
dbFlatTexts.cc \
|
||||
dbTextsUtils.cc \
|
||||
dbOriginalLayerTexts.cc
|
||||
dbOriginalLayerTexts.cc \
|
||||
dbNetShape.cc
|
||||
|
||||
HEADERS = \
|
||||
dbArray.h \
|
||||
|
|
@ -348,7 +349,8 @@ HEADERS = \
|
|||
dbEmptyTexts.h \
|
||||
dbFlatTexts.h \
|
||||
dbTextsUtils.h \
|
||||
dbOriginalLayerTexts.h
|
||||
dbOriginalLayerTexts.h \
|
||||
dbNetShape.h
|
||||
|
||||
!equals(HAVE_QT, "0") {
|
||||
|
||||
|
|
|
|||
|
|
@ -394,7 +394,7 @@ AsIfFlatRegion::selected_interacting_generic (const Texts &other, bool inverse)
|
|||
scanner.reserve2 (other.size ());
|
||||
|
||||
std::auto_ptr<FlatRegion> output (new FlatRegion (false));
|
||||
region_to_text_interaction_filter<Shapes, db::Polygon> filter (output->raw_polygons (), inverse);
|
||||
region_to_text_interaction_filter<Shapes, db::Text, db::Polygon> filter (output->raw_polygons (), inverse);
|
||||
|
||||
AddressablePolygonDelivery p (begin_merged (), has_valid_merged_polygons ());
|
||||
|
||||
|
|
@ -527,7 +527,7 @@ AsIfFlatRegion::pull_generic (const Texts &other) const
|
|||
scanner.reserve2 (other.size ());
|
||||
|
||||
std::auto_ptr<FlatTexts> output (new FlatTexts (false));
|
||||
region_to_text_interaction_filter<Shapes, db::Text> filter (output->raw_texts (), false);
|
||||
region_to_text_interaction_filter<Shapes, db::Text, db::Text> filter (output->raw_texts (), false);
|
||||
|
||||
AddressablePolygonDelivery p (begin (), has_valid_merged_polygons ());
|
||||
|
||||
|
|
|
|||
|
|
@ -312,13 +312,13 @@ AsIfFlatTexts::selected_interacting_generic (const Region &other, bool inverse)
|
|||
|
||||
if (! inverse) {
|
||||
|
||||
text_to_region_interaction_filter<FlatTexts> filter (*output);
|
||||
text_to_region_interaction_filter<FlatTexts, db::Text> filter (*output);
|
||||
scanner.process (filter, 1, db::box_convert<db::Text> (), db::box_convert<db::Polygon> ());
|
||||
|
||||
} else {
|
||||
|
||||
std::set<db::Text> interacting;
|
||||
text_to_region_interaction_filter<std::set<db::Text> > filter (interacting);
|
||||
text_to_region_interaction_filter<std::set<db::Text>, db::Text> filter (interacting);
|
||||
scanner.process (filter, 1, db::box_convert<db::Text> (), db::box_convert<db::Polygon> ());
|
||||
|
||||
for (TextsIterator o (begin ()); ! o.at_end (); ++o) {
|
||||
|
|
@ -356,7 +356,7 @@ AsIfFlatTexts::pull_generic (const Region &other) const
|
|||
|
||||
std::auto_ptr<FlatRegion> output (new FlatRegion (true));
|
||||
|
||||
text_to_region_interaction_filter<FlatRegion> filter (*output);
|
||||
text_to_region_interaction_filter<FlatRegion, db::Text> filter (*output);
|
||||
scanner.process (filter, 1, db::box_convert<db::Text> (), db::box_convert<db::Polygon> ());
|
||||
|
||||
return output.release ();
|
||||
|
|
|
|||
|
|
@ -417,7 +417,7 @@ DeepEdges::ensure_merged_edges_valid () const
|
|||
db::Connectivity conn;
|
||||
conn.connect (m_deep_layer);
|
||||
hc.set_base_verbosity (base_verbosity() + 10);
|
||||
hc.build (layout, m_deep_layer.initial_cell (), db::ShapeIterator::Edges, conn);
|
||||
hc.build (layout, m_deep_layer.initial_cell (), conn);
|
||||
|
||||
// collect the clusters and merge them into big polygons
|
||||
// NOTE: using the ClusterMerger we merge bottom-up forming bigger and bigger polygons. This is
|
||||
|
|
@ -1077,7 +1077,7 @@ RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_t
|
|||
db::Connectivity conn (db::Connectivity::EdgesConnectByPoints);
|
||||
conn.connect (edges);
|
||||
hc.set_base_verbosity (base_verbosity () + 10);
|
||||
hc.build (layout, edges.initial_cell (), db::ShapeIterator::Edges, conn);
|
||||
hc.build (layout, edges.initial_cell (), conn);
|
||||
|
||||
// TODO: iterate only over the called cells?
|
||||
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
|
||||
|
|
|
|||
|
|
@ -455,7 +455,7 @@ DeepRegion::ensure_merged_polygons_valid () const
|
|||
db::Connectivity conn;
|
||||
conn.connect (m_deep_layer);
|
||||
hc.set_base_verbosity (base_verbosity () + 10);
|
||||
hc.build (layout, m_deep_layer.initial_cell (), db::ShapeIterator::Polygons, conn);
|
||||
hc.build (layout, m_deep_layer.initial_cell (), conn);
|
||||
|
||||
// collect the clusters and merge them into big polygons
|
||||
// NOTE: using the ClusterMerger we merge bottom-up forming bigger and bigger polygons. This is
|
||||
|
|
@ -1238,7 +1238,7 @@ DeepRegion::merged (bool min_coherence, unsigned int min_wc) const
|
|||
db::Connectivity conn;
|
||||
conn.connect (m_deep_layer);
|
||||
hc.set_base_verbosity (base_verbosity () + 10);
|
||||
hc.build (layout, m_deep_layer.initial_cell (), db::ShapeIterator::Polygons, conn);
|
||||
hc.build (layout, m_deep_layer.initial_cell (), conn);
|
||||
|
||||
// collect the clusters and merge them into big polygons
|
||||
// NOTE: using the ClusterMerger we merge bottom-up forming bigger and bigger polygons. This is
|
||||
|
|
@ -1899,25 +1899,25 @@ public:
|
|||
|
||||
struct TextResultInserter
|
||||
{
|
||||
typedef db::Text value_type;
|
||||
typedef db::TextRef value_type;
|
||||
|
||||
TextResultInserter (std::unordered_set<db::Text> &result)
|
||||
TextResultInserter (std::unordered_set<db::TextRef> &result)
|
||||
: mp_result (&result)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void insert (const db::Text &e)
|
||||
void insert (const db::TextRef &e)
|
||||
{
|
||||
(*mp_result).insert (e);
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_set<db::Text> *mp_result;
|
||||
std::unordered_set<db::TextRef> *mp_result;
|
||||
};
|
||||
|
||||
class PullWithTextLocalOperation
|
||||
: public local_operation<db::PolygonRef, db::Text, db::Text>
|
||||
: public local_operation<db::PolygonRef, db::TextRef, db::TextRef>
|
||||
{
|
||||
public:
|
||||
PullWithTextLocalOperation ()
|
||||
|
|
@ -1931,15 +1931,15 @@ public:
|
|||
return 1;
|
||||
}
|
||||
|
||||
virtual void compute_local (db::Layout *, const shape_interactions<db::PolygonRef, db::Text> &interactions, std::unordered_set<db::Text> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
|
||||
virtual void compute_local (db::Layout *, const shape_interactions<db::PolygonRef, db::TextRef> &interactions, std::unordered_set<db::TextRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
|
||||
{
|
||||
db::box_scanner2<db::Polygon, size_t, db::Text, size_t> scanner;
|
||||
db::box_scanner2<db::Polygon, size_t, db::TextRef, size_t> scanner;
|
||||
|
||||
TextResultInserter inserter (result);
|
||||
region_to_text_interaction_filter<TextResultInserter> filter (inserter, false);
|
||||
region_to_text_interaction_filter<TextResultInserter, db::TextRef> filter (inserter, false);
|
||||
|
||||
for (shape_interactions<db::PolygonRef, db::Text>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (shape_interactions<db::PolygonRef, db::Text>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
for (shape_interactions<db::PolygonRef, db::TextRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (shape_interactions<db::PolygonRef, db::TextRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
scanner.insert2 (& interactions.intruder_shape (*j), 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -1954,7 +1954,7 @@ public:
|
|||
|
||||
}
|
||||
|
||||
scanner.process (filter, 1, db::box_convert<db::Polygon> (), db::box_convert<db::Text> ());
|
||||
scanner.process (filter, 1, db::box_convert<db::Polygon> (), db::box_convert<db::TextRef> ());
|
||||
}
|
||||
|
||||
virtual on_empty_intruder_mode on_empty_intruder_hint () const
|
||||
|
|
@ -1969,7 +1969,7 @@ public:
|
|||
};
|
||||
|
||||
class InteractingWithTextLocalOperation
|
||||
: public local_operation<db::PolygonRef, db::Text, db::PolygonRef>
|
||||
: public local_operation<db::PolygonRef, db::TextRef, db::PolygonRef>
|
||||
{
|
||||
public:
|
||||
InteractingWithTextLocalOperation (bool inverse)
|
||||
|
|
@ -1984,12 +1984,12 @@ public:
|
|||
return 1;
|
||||
}
|
||||
|
||||
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::Text> &interactions, std::unordered_set<db::PolygonRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
|
||||
virtual void compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::TextRef> &interactions, std::unordered_set<db::PolygonRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
|
||||
{
|
||||
db::box_scanner2<db::Polygon, size_t, db::Text, size_t> scanner;
|
||||
db::box_scanner2<db::Polygon, size_t, db::TextRef, size_t> scanner;
|
||||
|
||||
ResultInserter inserter (layout, result);
|
||||
region_to_text_interaction_filter<ResultInserter> filter (inserter, m_inverse);
|
||||
region_to_text_interaction_filter<ResultInserter, db::TextRef> filter (inserter, m_inverse);
|
||||
|
||||
for (shape_interactions<db::PolygonRef, db::Text>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (shape_interactions<db::PolygonRef, db::Text>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
|
|
@ -2010,7 +2010,7 @@ public:
|
|||
|
||||
}
|
||||
|
||||
scanner.process (filter, 1, db::box_convert<db::Polygon> (), db::box_convert<db::Text> ());
|
||||
scanner.process (filter, 1, db::box_convert<db::Polygon> (), db::box_convert<db::TextRef> ());
|
||||
if (m_inverse) {
|
||||
filter.fill_output ();
|
||||
}
|
||||
|
|
@ -2199,7 +2199,7 @@ DeepRegion::pull_generic (const Texts &other) const
|
|||
|
||||
db::PullWithTextLocalOperation op;
|
||||
|
||||
db::local_processor<db::PolygonRef, db::Text, db::Text> proc (const_cast<db::Layout *> (&polygons.layout ()), const_cast<db::Cell *> (&polygons.initial_cell ()), &other_texts.layout (), &other_texts.initial_cell (), polygons.breakout_cells (), other_texts.breakout_cells ());
|
||||
db::local_processor<db::PolygonRef, db::TextRef, db::TextRef> proc (const_cast<db::Layout *> (&polygons.layout ()), const_cast<db::Cell *> (&polygons.initial_cell ()), &other_texts.layout (), &other_texts.initial_cell (), polygons.breakout_cells (), other_texts.breakout_cells ());
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
proc.set_threads (polygons.store ()->threads ());
|
||||
proc.run (&op, polygons.layer (), other_texts.layer (), dl_out.layer ());
|
||||
|
|
@ -2229,7 +2229,7 @@ DeepRegion::selected_interacting_generic (const Texts &other, bool inverse) cons
|
|||
|
||||
db::InteractingWithTextLocalOperation op (inverse);
|
||||
|
||||
db::local_processor<db::PolygonRef, db::Text, db::PolygonRef> proc (const_cast<db::Layout *> (&polygons.layout ()), const_cast<db::Cell *> (&polygons.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), polygons.breakout_cells (), other_deep->deep_layer ().breakout_cells ());
|
||||
db::local_processor<db::PolygonRef, db::TextRef, db::PolygonRef> proc (const_cast<db::Layout *> (&polygons.layout ()), const_cast<db::Cell *> (&polygons.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), polygons.breakout_cells (), other_deep->deep_layer ().breakout_cells ());
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
proc.set_threads (polygons.store ()->threads ());
|
||||
if (split_after) {
|
||||
|
|
|
|||
|
|
@ -474,7 +474,7 @@ DeepLayer DeepShapeStore::create_from_flat (const db::Texts &texts, const db::IC
|
|||
db::Shapes *shapes = &initial_cell ().shapes (layer);
|
||||
db::Box world = db::Box::world ();
|
||||
|
||||
db::TextBuildingHierarchyBuilderShapeReceiver tb;
|
||||
db::TextBuildingHierarchyBuilderShapeReceiver tb (&layout ());
|
||||
|
||||
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> ii = texts.begin_iter ();
|
||||
db::ICplxTrans ttop = trans * ii.second;
|
||||
|
|
@ -849,7 +849,10 @@ DeepLayer DeepShapeStore::create_edge_pair_layer (const db::RecursiveShapeIterat
|
|||
|
||||
DeepLayer DeepShapeStore::create_text_layer (const db::RecursiveShapeIterator &si, const db::ICplxTrans &trans)
|
||||
{
|
||||
db::TextBuildingHierarchyBuilderShapeReceiver refs;
|
||||
unsigned int layout_index = layout_for_iter (si, trans);
|
||||
db::Layout &layout = m_layouts[layout_index]->layout;
|
||||
|
||||
db::TextBuildingHierarchyBuilderShapeReceiver refs (&layout);
|
||||
return create_custom_layer (si, &refs, trans);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -408,7 +408,7 @@ void DeepTexts::insert_into_as_polygons (Layout *layout, db::cell_index_type int
|
|||
namespace {
|
||||
|
||||
class Text2PolygonInteractingLocalOperation
|
||||
: public local_operation<db::Text, db::PolygonRef, db::Text>
|
||||
: public local_operation<db::TextRef, db::PolygonRef, db::TextRef>
|
||||
{
|
||||
public:
|
||||
Text2PolygonInteractingLocalOperation (bool inverse)
|
||||
|
|
@ -423,19 +423,19 @@ public:
|
|||
return 1;
|
||||
}
|
||||
|
||||
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::Text, db::PolygonRef> &interactions, std::unordered_set<db::Text> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
|
||||
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<db::TextRef, db::PolygonRef> &interactions, std::unordered_set<db::TextRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
|
||||
{
|
||||
db::box_scanner2<db::Text, size_t, db::Polygon, size_t> scanner;
|
||||
db::box_scanner2<db::TextRef, size_t, db::Polygon, size_t> scanner;
|
||||
|
||||
std::set<db::PolygonRef> others;
|
||||
for (shape_interactions<db::Text, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (shape_interactions<db::Text, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
for (shape_interactions<db::TextRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (shape_interactions<db::TextRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
others.insert (interactions.intruder_shape (*j));
|
||||
}
|
||||
}
|
||||
|
||||
for (shape_interactions<db::Text, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const db::Text &subject = interactions.subject_shape (i->first);
|
||||
for (shape_interactions<db::TextRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const db::TextRef &subject = interactions.subject_shape (i->first);
|
||||
scanner.insert1 (&subject, 0);
|
||||
}
|
||||
|
||||
|
|
@ -447,12 +447,12 @@ public:
|
|||
|
||||
if (m_inverse) {
|
||||
|
||||
std::unordered_set<db::Text> interacting;
|
||||
text_to_region_interaction_filter<std::unordered_set<db::Text> > filter (interacting);
|
||||
scanner.process (filter, 1, db::box_convert<db::Text> (), db::box_convert<db::Polygon> ());
|
||||
std::unordered_set<db::TextRef> interacting;
|
||||
text_to_region_interaction_filter<std::unordered_set<db::TextRef>, db::TextRef> filter (interacting);
|
||||
scanner.process (filter, 1, db::box_convert<db::TextRef> (), db::box_convert<db::Polygon> ());
|
||||
|
||||
for (shape_interactions<db::Text, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const db::Text &subject = interactions.subject_shape (i->first);
|
||||
for (shape_interactions<db::TextRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const db::TextRef &subject = interactions.subject_shape (i->first);
|
||||
if (interacting.find (subject) == interacting.end ()) {
|
||||
result.insert (subject);
|
||||
}
|
||||
|
|
@ -460,8 +460,8 @@ public:
|
|||
|
||||
} else {
|
||||
|
||||
text_to_region_interaction_filter<std::unordered_set<db::Text> > filter (result);
|
||||
scanner.process (filter, 1, db::box_convert<db::Text> (), db::box_convert<db::Polygon> ());
|
||||
text_to_region_interaction_filter<std::unordered_set<db::TextRef>, db::TextRef> filter (result);
|
||||
scanner.process (filter, 1, db::box_convert<db::TextRef> (), db::box_convert<db::Polygon> ());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -505,7 +505,7 @@ private:
|
|||
};
|
||||
|
||||
class Text2PolygonPullLocalOperation
|
||||
: public local_operation<db::Text, db::PolygonRef, db::PolygonRef>
|
||||
: public local_operation<db::TextRef, db::PolygonRef, db::PolygonRef>
|
||||
{
|
||||
public:
|
||||
Text2PolygonPullLocalOperation ()
|
||||
|
|
@ -519,19 +519,19 @@ public:
|
|||
return 1;
|
||||
}
|
||||
|
||||
virtual void compute_local (db::Layout *layout, const shape_interactions<db::Text, db::PolygonRef> &interactions, std::unordered_set<db::PolygonRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
|
||||
virtual void compute_local (db::Layout *layout, const shape_interactions<db::TextRef, db::PolygonRef> &interactions, std::unordered_set<db::PolygonRef> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
|
||||
{
|
||||
db::box_scanner2<db::Text, size_t, db::Polygon, size_t> scanner;
|
||||
db::box_scanner2<db::TextRef, size_t, db::Polygon, size_t> scanner;
|
||||
|
||||
std::set<db::PolygonRef> others;
|
||||
for (shape_interactions<db::Text, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (shape_interactions<db::Text, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
for (shape_interactions<db::TextRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (shape_interactions<db::TextRef, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
others.insert (interactions.intruder_shape (*j));
|
||||
}
|
||||
}
|
||||
|
||||
for (shape_interactions<db::Text, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const db::Text &subject = interactions.subject_shape (i->first);
|
||||
for (shape_interactions<db::TextRef, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const db::TextRef &subject = interactions.subject_shape (i->first);
|
||||
scanner.insert1 (&subject, 1);
|
||||
}
|
||||
|
||||
|
|
@ -542,8 +542,8 @@ public:
|
|||
}
|
||||
|
||||
ResultInserter inserter (layout, result);
|
||||
text_to_region_interaction_filter<ResultInserter> filter (inserter);
|
||||
scanner.process (filter, 1, db::box_convert<db::Text> (), db::box_convert<db::Polygon> ());
|
||||
text_to_region_interaction_filter<ResultInserter, db::TextRef> filter (inserter);
|
||||
scanner.process (filter, 1, db::box_convert<db::TextRef> (), db::box_convert<db::Polygon> ());
|
||||
}
|
||||
|
||||
virtual on_empty_intruder_mode on_empty_intruder_hint () const
|
||||
|
|
@ -576,7 +576,7 @@ DeepTexts::selected_interacting_generic (const Region &other, bool inverse) cons
|
|||
|
||||
db::Text2PolygonInteractingLocalOperation op (inverse);
|
||||
|
||||
db::local_processor<db::Text, db::PolygonRef, db::Text> proc (const_cast<db::Layout *> (&texts.layout ()), const_cast<db::Cell *> (&texts.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ());
|
||||
db::local_processor<db::TextRef, db::PolygonRef, db::TextRef> proc (const_cast<db::Layout *> (&texts.layout ()), const_cast<db::Cell *> (&texts.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ());
|
||||
proc.set_base_verbosity (other.base_verbosity ());
|
||||
proc.set_threads (texts.store ()->threads ());
|
||||
|
||||
|
|
@ -602,7 +602,7 @@ RegionDelegate *DeepTexts::pull_generic (const Region &other) const
|
|||
|
||||
db::Text2PolygonPullLocalOperation op;
|
||||
|
||||
db::local_processor<db::Text, db::PolygonRef, db::PolygonRef> proc (const_cast<db::Layout *> (&texts.layout ()), const_cast<db::Cell *> (&texts.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell ());
|
||||
db::local_processor<db::TextRef, db::PolygonRef, db::PolygonRef> proc (const_cast<db::Layout *> (&texts.layout ()), const_cast<db::Cell *> (&texts.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell ());
|
||||
proc.set_base_verbosity (other.base_verbosity ());
|
||||
proc.set_threads (texts.store ()->threads ());
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "dbPolygonTools.h"
|
||||
#include "dbBoxScanner.h"
|
||||
#include "dbDeepRegion.h"
|
||||
#include "dbNetShape.h"
|
||||
#include "tlProgress.h"
|
||||
#include "tlLog.h"
|
||||
#include "tlTimer.h"
|
||||
|
|
@ -43,9 +44,9 @@ namespace db
|
|||
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
template <class Container, class Shape, class Trans> void insert_transformed (db::Layout &layout, Container &shapes, const Shape &s, const Trans &t);
|
||||
template <class Shape, class Trans> void insert_transformed (db::Layout &layout, db::Shapes &shapes, const Shape &s, const Trans &t);
|
||||
|
||||
template <class Container, class Trans> void insert_transformed (db::Layout &layout, Container &shapes, const db::PolygonRef &s, const Trans &t)
|
||||
template <class Trans> void insert_transformed (db::Layout &layout, db::Shapes &shapes, const db::PolygonRef &s, const Trans &t)
|
||||
{
|
||||
db::Polygon poly = s.obj ();
|
||||
poly.transform (s.trans ());
|
||||
|
|
@ -55,7 +56,32 @@ template <class Container, class Trans> void insert_transformed (db::Layout &lay
|
|||
shapes.insert (db::PolygonRef (poly, layout.shape_repository ()));
|
||||
}
|
||||
|
||||
template <class Container, class Trans> void insert_transformed (db::Layout & /*layout*/, Container &shapes, const db::Edge &s, const Trans &t)
|
||||
template <class Trans> void insert_transformed (db::Layout &layout, db::Shapes &shapes, const db::NetShape &s, const Trans &t)
|
||||
{
|
||||
if (s.type () == db::NetShape::Polygon) {
|
||||
|
||||
db::PolygonRef pr = s.polygon_ref ();
|
||||
db::Polygon poly = pr.obj ();
|
||||
poly.transform (pr.trans ());
|
||||
if (! t.is_unity ()) {
|
||||
poly.transform (t);
|
||||
}
|
||||
shapes.insert (db::PolygonRef (poly, layout.shape_repository ()));
|
||||
|
||||
} else if (s.type () == db::NetShape::Text) {
|
||||
|
||||
db::TextRef tr = s.text_ref ();
|
||||
db::Text text = tr.obj ();
|
||||
text.transform (tr.trans ());
|
||||
if (! t.is_unity ()) {
|
||||
text.transform (t);
|
||||
}
|
||||
shapes.insert (db::TextRef (text, layout.shape_repository ()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
template <class Trans> void insert_transformed (db::Layout & /*layout*/, db::Shapes &shapes, const db::Edge &s, const Trans &t)
|
||||
{
|
||||
shapes.insert (s.transformed (t));
|
||||
}
|
||||
|
|
@ -237,6 +263,20 @@ interaction_test (const db::PolygonRef &a, const db::PolygonRef &b, const db::un
|
|||
}
|
||||
}
|
||||
|
||||
template <class Trans>
|
||||
static bool
|
||||
interaction_test (const db::NetShape &a, const db::NetShape &b, const Trans &trans, db::Connectivity::edge_connectivity_type)
|
||||
{
|
||||
return a.interacts_with_transformed (b, trans);
|
||||
}
|
||||
|
||||
template <class C>
|
||||
static bool
|
||||
interaction_test (const db::NetShape &a, const db::NetShape &b, const db::unit_trans<C> &, db::Connectivity::edge_connectivity_type)
|
||||
{
|
||||
return a.interacts_with (b);
|
||||
}
|
||||
|
||||
template <class Trans>
|
||||
static bool
|
||||
interaction_test (const db::Edge &a, const db::Edge &b, const Trans &trans, db::Connectivity::edge_connectivity_type ec)
|
||||
|
|
@ -272,6 +312,8 @@ bool Connectivity::interacts (const T &a, unsigned int la, const T &b, unsigned
|
|||
}
|
||||
|
||||
// explicit instantiations
|
||||
template DB_PUBLIC bool Connectivity::interacts<db::NetShape> (const db::NetShape &a, unsigned int la, const db::NetShape &b, unsigned int lb, const db::UnitTrans &trans) const;
|
||||
template DB_PUBLIC bool Connectivity::interacts<db::NetShape> (const db::NetShape &a, unsigned int la, const db::NetShape &b, unsigned int lb, const db::ICplxTrans &trans) const;
|
||||
template DB_PUBLIC bool Connectivity::interacts<db::PolygonRef> (const db::PolygonRef &a, unsigned int la, const db::PolygonRef &b, unsigned int lb, const db::UnitTrans &trans) const;
|
||||
template DB_PUBLIC bool Connectivity::interacts<db::PolygonRef> (const db::PolygonRef &a, unsigned int la, const db::PolygonRef &b, unsigned int lb, const db::ICplxTrans &trans) const;
|
||||
template DB_PUBLIC bool Connectivity::interacts<db::Edge> (const db::Edge &a, unsigned int la, const db::Edge &b, unsigned int lb, const db::UnitTrans &trans) const;
|
||||
|
|
@ -630,8 +672,10 @@ size_t local_cluster<T>::split (double max_area_ratio, Iter &output) const
|
|||
}
|
||||
|
||||
// explicit instantiations
|
||||
template class DB_PUBLIC local_cluster<db::NetShape>;
|
||||
template class DB_PUBLIC local_cluster<db::PolygonRef>;
|
||||
template class DB_PUBLIC local_cluster<db::Edge>;
|
||||
template DB_PUBLIC size_t local_cluster<db::NetShape>::split<std::back_insert_iterator<std::list<local_cluster<db::NetShape> > > > (double, std::back_insert_iterator<std::list<local_cluster<db::NetShape> > > &) const;
|
||||
template DB_PUBLIC size_t local_cluster<db::PolygonRef>::split<std::back_insert_iterator<std::list<local_cluster<db::PolygonRef> > > > (double, std::back_insert_iterator<std::list<local_cluster<db::PolygonRef> > > &) const;
|
||||
template DB_PUBLIC size_t local_cluster<db::Edge>::split<std::back_insert_iterator<std::list<local_cluster<db::Edge> > > > (double, std::back_insert_iterator<std::list<local_cluster<db::Edge> > > &) const;
|
||||
|
||||
|
|
@ -886,22 +930,112 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct addressable_shape_delivery
|
||||
{
|
||||
const T *operator () (const db::Shape &shape)
|
||||
{
|
||||
typename T::tag object_tag;
|
||||
return shape.basic_ptr (object_tag);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct addressable_shape_delivery<db::NetShape>
|
||||
{
|
||||
const NetShape *operator () (const db::Shape &shape)
|
||||
{
|
||||
if (shape.type () == db::Shape::TextRef) {
|
||||
m_heap.push_back (db::NetShape (shape.text_ref ()));
|
||||
return &m_heap.back ();
|
||||
} else if (shape.type () == db::Shape::PolygonRef) {
|
||||
m_heap.push_back (db::NetShape (shape.polygon_ref ()));
|
||||
return &m_heap.back ();
|
||||
} else {
|
||||
tl_assert (false);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::list<NetShape> m_heap;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct attr_accessor
|
||||
{
|
||||
size_t operator() (const db::Shape &shape) const
|
||||
{
|
||||
return shape.prop_id ();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct attr_accessor<db::NetShape>
|
||||
{
|
||||
size_t operator() (const db::Shape &shape) const
|
||||
{
|
||||
// NOTE: the attribute is
|
||||
// * odd: a StringRef pointer's value
|
||||
// * even: a Property ID times 2
|
||||
if (shape.type () == db::Shape::TextRef) {
|
||||
return db::text_ref_to_attr (&shape.text_ref ().obj ());
|
||||
} else {
|
||||
return db::prop_id_to_attr (shape.prop_id ());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> struct get_shape_flags { };
|
||||
|
||||
template <>
|
||||
struct get_shape_flags<db::Edge>
|
||||
{
|
||||
db::ShapeIterator::flags_type operator() (bool /*with_attr*/) const
|
||||
{
|
||||
return db::ShapeIterator::Edges;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct get_shape_flags<db::PolygonRef>
|
||||
{
|
||||
db::ShapeIterator::flags_type operator() (bool /*with_attr*/) const
|
||||
{
|
||||
return db::ShapeIterator::Polygons;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct get_shape_flags<db::NetShape>
|
||||
{
|
||||
db::ShapeIterator::flags_type operator() (bool with_attr) const
|
||||
{
|
||||
if (with_attr) {
|
||||
return db::ShapeIterator::flags_type (db::ShapeIterator::Polygons | db::ShapeIterator::Texts);
|
||||
} else {
|
||||
return db::ShapeIterator::flags_type (db::ShapeIterator::Polygons);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void
|
||||
local_clusters<T>::build_clusters (const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence, bool report_progress)
|
||||
local_clusters<T>::build_clusters (const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *attr_equivalence, bool report_progress)
|
||||
{
|
||||
static std::string desc = tl::to_string (tr ("Building local clusters"));
|
||||
|
||||
db::box_scanner<T, std::pair<unsigned int, unsigned int> > bs (report_progress, desc);
|
||||
typename T::tag object_tag;
|
||||
db::box_scanner<T, std::pair<unsigned int, size_t> > bs (report_progress, desc);
|
||||
db::box_convert<T> bc;
|
||||
addressable_shape_delivery<T> heap;
|
||||
attr_accessor<T> attr;
|
||||
db::ShapeIterator::flags_type shape_flags = get_shape_flags<T> () (attr_equivalence != 0 /*with attributes*/);
|
||||
|
||||
for (db::Connectivity::layer_iterator l = conn.begin_layers (); l != conn.end_layers (); ++l) {
|
||||
const db::Shapes &shapes = cell.shapes (*l);
|
||||
for (db::Shapes::shape_iterator s = shapes.begin (shape_flags); ! s.at_end (); ++s) {
|
||||
bs.insert (s->basic_ptr (object_tag), std::make_pair (*l, (unsigned int) s->prop_id ()));
|
||||
bs.insert (heap (*s), std::make_pair (*l, attr (*s)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -916,9 +1050,9 @@ local_clusters<T>::build_clusters (const db::Cell &cell, db::ShapeIterator::flag
|
|||
|
||||
template <class T>
|
||||
void
|
||||
local_clusters<T>::apply_attr_equivalences (const tl::equivalence_clusters<unsigned int> &attr_equivalence)
|
||||
local_clusters<T>::apply_attr_equivalences (const tl::equivalence_clusters<size_t> &attr_equivalence)
|
||||
{
|
||||
tl::equivalence_clusters<unsigned int> eq;
|
||||
tl::equivalence_clusters<size_t> eq;
|
||||
|
||||
// collect all local attributes (the ones which are present in attr_equivalence) into "eq"
|
||||
// and form equivalences for multi-attribute clusters.
|
||||
|
|
@ -939,18 +1073,18 @@ local_clusters<T>::apply_attr_equivalences (const tl::equivalence_clusters<unsig
|
|||
|
||||
// identify the layout clusters joined into one attribute cluster and join them
|
||||
|
||||
std::map<tl::equivalence_clusters<unsigned int>::cluster_id_type, std::set<size_t> > c2c;
|
||||
std::map<tl::equivalence_clusters<size_t>::cluster_id_type, std::set<size_t> > c2c;
|
||||
|
||||
for (const_iterator c = begin (); c != end (); ++c) {
|
||||
for (typename local_cluster<T>::attr_iterator a = c->begin_attr (); a != c->end_attr (); ++a) {
|
||||
tl::equivalence_clusters<unsigned int>::cluster_id_type cl = attr_equivalence.cluster_id (*a);
|
||||
tl::equivalence_clusters<size_t>::cluster_id_type cl = attr_equivalence.cluster_id (*a);
|
||||
if (cl > 0) {
|
||||
c2c [cl].insert (c->id ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (std::map<tl::equivalence_clusters<unsigned int>::cluster_id_type, std::set<size_t> >::const_iterator c = c2c.begin (); c != c2c.end (); ++c) {
|
||||
for (std::map<tl::equivalence_clusters<size_t>::cluster_id_type, std::set<size_t> >::const_iterator c = c2c.begin (); c != c2c.end (); ++c) {
|
||||
if (c->second.size () > 1) {
|
||||
std::set<size_t>::const_iterator cl0 = c->second.begin ();
|
||||
std::set<size_t>::const_iterator cl = cl0;
|
||||
|
|
@ -962,6 +1096,7 @@ local_clusters<T>::apply_attr_equivalences (const tl::equivalence_clusters<unsig
|
|||
}
|
||||
|
||||
// explicit instantiations
|
||||
template class DB_PUBLIC local_clusters<db::NetShape>;
|
||||
template class DB_PUBLIC local_clusters<db::PolygonRef>;
|
||||
template class DB_PUBLIC local_clusters<db::Edge>;
|
||||
|
||||
|
|
@ -984,6 +1119,7 @@ connected_clusters_iterator<T>::connected_clusters_iterator (const connected_clu
|
|||
}
|
||||
|
||||
// explicit instantiations
|
||||
template class DB_PUBLIC connected_clusters_iterator<db::NetShape>;
|
||||
template class DB_PUBLIC connected_clusters_iterator<db::PolygonRef>;
|
||||
template class DB_PUBLIC connected_clusters_iterator<db::Edge>;
|
||||
|
||||
|
|
@ -1053,6 +1189,7 @@ connected_clusters<T>::find_cluster_with_connection (const ClusterInstance &inst
|
|||
}
|
||||
|
||||
// explicit instantiations
|
||||
template class DB_PUBLIC connected_clusters<db::NetShape>;
|
||||
template class DB_PUBLIC connected_clusters<db::PolygonRef>;
|
||||
template class DB_PUBLIC connected_clusters<db::Edge>;
|
||||
|
||||
|
|
@ -1133,11 +1270,11 @@ void hier_clusters<T>::clear ()
|
|||
|
||||
template <class T>
|
||||
void
|
||||
hier_clusters<T>::build (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<unsigned int> > *attr_equivalence, const std::set<db::cell_index_type> *breakout_cells)
|
||||
hier_clusters<T>::build (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<size_t> > *attr_equivalence, const std::set<db::cell_index_type> *breakout_cells)
|
||||
{
|
||||
clear ();
|
||||
cell_clusters_box_converter<T> cbc (layout, *this);
|
||||
do_build (cbc, layout, cell, shape_flags, conn, attr_equivalence, breakout_cells);
|
||||
do_build (cbc, layout, cell, conn, attr_equivalence, breakout_cells);
|
||||
}
|
||||
|
||||
namespace
|
||||
|
|
@ -1939,7 +2076,7 @@ hier_clusters<T>::propagate_cluster_inst (const db::Layout &layout, const db::Ce
|
|||
|
||||
template <class T>
|
||||
void
|
||||
hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<unsigned int> > *attr_equivalence, const std::set<db::cell_index_type> *breakout_cells)
|
||||
hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<size_t> > *attr_equivalence, const std::set<db::cell_index_type> *breakout_cells)
|
||||
{
|
||||
tl::SelfTimer timer (tl::verbosity () > m_base_verbosity, tl::to_string (tr ("Computing shape clusters")));
|
||||
|
||||
|
|
@ -1957,8 +2094,8 @@ hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layou
|
|||
|
||||
// look for the net label joining spec - for the top cell the "top_cell_index" entry is looked for.
|
||||
// If there is no such entry or the cell is not the top cell, look for the entry by cell index.
|
||||
std::map<db::cell_index_type, tl::equivalence_clusters<unsigned int> >::const_iterator ae;
|
||||
const tl::equivalence_clusters<unsigned int> *ec = 0;
|
||||
std::map<db::cell_index_type, tl::equivalence_clusters<size_t> >::const_iterator ae;
|
||||
const tl::equivalence_clusters<size_t> *ec = 0;
|
||||
if (attr_equivalence) {
|
||||
if (*c == cell.cell_index ()) {
|
||||
ae = attr_equivalence->find (top_cell_index);
|
||||
|
|
@ -1974,7 +2111,7 @@ hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layou
|
|||
}
|
||||
}
|
||||
|
||||
build_local_cluster (layout, layout.cell (*c), shape_flags, conn, ec);
|
||||
build_local_cluster (layout, layout.cell (*c), conn, ec);
|
||||
|
||||
++progress;
|
||||
|
||||
|
|
@ -2021,7 +2158,7 @@ hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layou
|
|||
|
||||
template <class T>
|
||||
void
|
||||
hier_clusters<T>::build_local_cluster (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence)
|
||||
hier_clusters<T>::build_local_cluster (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *attr_equivalence)
|
||||
{
|
||||
std::string msg = tl::to_string (tr ("Computing local clusters for cell: ")) + std::string (layout.cell_name (cell.cell_index ()));
|
||||
if (tl::verbosity () >= m_base_verbosity + 20) {
|
||||
|
|
@ -2030,7 +2167,7 @@ hier_clusters<T>::build_local_cluster (const db::Layout &layout, const db::Cell
|
|||
tl::SelfTimer timer (tl::verbosity () > m_base_verbosity + 20, msg);
|
||||
|
||||
connected_clusters<T> &local = m_per_cell_clusters [cell.cell_index ()];
|
||||
local.build_clusters (cell, shape_flags, conn, attr_equivalence, true);
|
||||
local.build_clusters (cell, conn, attr_equivalence, true);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
|
@ -2336,6 +2473,7 @@ hier_clusters<T>::return_to_hierarchy (db::Layout &layout, const std::map<unsign
|
|||
}
|
||||
|
||||
// explicit instantiations
|
||||
template class DB_PUBLIC hier_clusters<db::NetShape>;
|
||||
template class DB_PUBLIC hier_clusters<db::PolygonRef>;
|
||||
template class DB_PUBLIC hier_clusters<db::Edge>;
|
||||
|
||||
|
|
@ -2460,6 +2598,7 @@ void recursive_cluster_shape_iterator<T>::down (db::cell_index_type ci, typename
|
|||
}
|
||||
|
||||
// explicit instantiations
|
||||
template class DB_PUBLIC recursive_cluster_shape_iterator<db::NetShape>;
|
||||
template class DB_PUBLIC recursive_cluster_shape_iterator<db::PolygonRef>;
|
||||
template class DB_PUBLIC recursive_cluster_shape_iterator<db::Edge>;
|
||||
|
||||
|
|
@ -2533,6 +2672,7 @@ void recursive_cluster_iterator<T>::down (db::cell_index_type ci, typename db::l
|
|||
}
|
||||
|
||||
// explicit instantiations
|
||||
template class DB_PUBLIC recursive_cluster_iterator<db::NetShape>;
|
||||
template class DB_PUBLIC recursive_cluster_iterator<db::PolygonRef>;
|
||||
template class DB_PUBLIC recursive_cluster_iterator<db::Edge>;
|
||||
|
||||
|
|
@ -2614,6 +2754,7 @@ incoming_cluster_connections<T>::ensure_computed_parent (db::cell_index_type ci)
|
|||
}
|
||||
|
||||
// explicit instantiations
|
||||
template class DB_PUBLIC incoming_cluster_connections<db::NetShape>;
|
||||
template class DB_PUBLIC incoming_cluster_connections<db::PolygonRef>;
|
||||
template class DB_PUBLIC incoming_cluster_connections<db::Edge>;
|
||||
|
||||
|
|
|
|||
|
|
@ -505,7 +505,7 @@ public:
|
|||
* cluster joining may happen in this case, because multi-attribute
|
||||
* assignment might create connections too.
|
||||
*/
|
||||
void build_clusters (const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence = 0, bool report_progress = false);
|
||||
void build_clusters (const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *attr_equivalence = 0, bool report_progress = false);
|
||||
|
||||
/**
|
||||
* @brief Creates and inserts a new clusters
|
||||
|
|
@ -540,7 +540,7 @@ private:
|
|||
tree_type m_clusters;
|
||||
size_t m_next_dummy_id;
|
||||
|
||||
void apply_attr_equivalences (const tl::equivalence_clusters<unsigned int> &attr_equivalence);
|
||||
void apply_attr_equivalences (const tl::equivalence_clusters<size_t> &attr_equivalence);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -998,7 +998,7 @@ public:
|
|||
/**
|
||||
* @brief Builds a hierarchy of clusters from a cell hierarchy and given connectivity
|
||||
*/
|
||||
void build (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<unsigned int> > *attr_equivalence = 0, const std::set<cell_index_type> *breakout_cells = 0);
|
||||
void build (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<size_t> > *attr_equivalence = 0, const std::set<cell_index_type> *breakout_cells = 0);
|
||||
|
||||
/**
|
||||
* @brief Gets the connected clusters for a given cell
|
||||
|
|
@ -1036,10 +1036,10 @@ public:
|
|||
size_t propagate_cluster_inst (const db::Layout &layout, const Cell &cell, const ClusterInstance &ci, db::cell_index_type parent_ci, bool with_self);
|
||||
|
||||
private:
|
||||
void build_local_cluster (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence);
|
||||
void build_local_cluster (const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const tl::equivalence_clusters<size_t> *attr_equivalence);
|
||||
void build_hier_connections (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set<cell_index_type> *breakout_cells, instance_interaction_cache_type &instance_interaction_cache);
|
||||
void build_hier_connections_for_cells (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const std::vector<db::cell_index_type> &cells, const db::Connectivity &conn, const std::set<cell_index_type> *breakout_cells, tl::RelativeProgress &progress, instance_interaction_cache_type &instance_interaction_cache);
|
||||
void do_build (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const std::map<db::cell_index_type, tl::equivalence_clusters<unsigned int> > *attr_equivalence, const std::set<cell_index_type> *breakout_cells);
|
||||
void do_build (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::map<cell_index_type, tl::equivalence_clusters<size_t> > *attr_equivalence, const std::set<cell_index_type> *breakout_cells);
|
||||
|
||||
std::map<db::cell_index_type, connected_clusters<T> > m_per_cell_clusters;
|
||||
int m_base_verbosity;
|
||||
|
|
@ -1335,6 +1335,39 @@ private:
|
|||
void ensure_computed_parent (db::cell_index_type ci) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A helper function generating an attribute ID from a property ID
|
||||
* This function is used to provide a generic attribute wrapping a property ID and a text ID.
|
||||
*/
|
||||
inline size_t prop_id_to_attr (db::properties_id_type id)
|
||||
{
|
||||
return size_t (id) * 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether the attribute is a property ID
|
||||
*/
|
||||
inline bool is_prop_id_attr (size_t attr)
|
||||
{
|
||||
return (attr & 1) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the property ID from an attribute
|
||||
*/
|
||||
inline db::properties_id_type prop_id_from_attr (size_t attr)
|
||||
{
|
||||
return attr / 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A helper function generating an attribute from a StringRef
|
||||
*/
|
||||
inline size_t text_ref_to_attr (const db::Text *tr)
|
||||
{
|
||||
return size_t (tr) * 2 + 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -157,29 +157,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class shape_reference_translator<db::Text>
|
||||
{
|
||||
public:
|
||||
typedef db::Text shape_type;
|
||||
|
||||
shape_reference_translator (db::Layout * /*target_layout*/)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
const shape_type &operator() (const shape_type &s) const
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
template <class Trans>
|
||||
shape_type operator() (const shape_type &s, const Trans &tr) const
|
||||
{
|
||||
return s.transformed (tr);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Ref, class Trans>
|
||||
class shape_reference_translator_with_trans_from_shape_ref
|
||||
{
|
||||
|
|
@ -656,11 +633,11 @@ shape_interactions<TS, TI>::intruder_shape (unsigned int id) const
|
|||
|
||||
template class DB_PUBLIC shape_interactions<db::PolygonRef, db::PolygonRef>;
|
||||
template class DB_PUBLIC shape_interactions<db::PolygonRef, db::Edge>;
|
||||
template class DB_PUBLIC shape_interactions<db::PolygonRef, db::Text>;
|
||||
template class DB_PUBLIC shape_interactions<db::PolygonRef, db::TextRef>;
|
||||
template class DB_PUBLIC shape_interactions<db::Edge, db::Edge>;
|
||||
template class DB_PUBLIC shape_interactions<db::Edge, db::PolygonRef>;
|
||||
template class DB_PUBLIC shape_interactions<db::Text, db::Text>;
|
||||
template class DB_PUBLIC shape_interactions<db::Text, db::PolygonRef>;
|
||||
template class DB_PUBLIC shape_interactions<db::TextRef, db::TextRef>;
|
||||
template class DB_PUBLIC shape_interactions<db::TextRef, db::PolygonRef>;
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// Helper classes for the LocalProcessor
|
||||
|
|
@ -683,7 +660,7 @@ inline unsigned int shape_flags<db::Edge> ()
|
|||
}
|
||||
|
||||
template <>
|
||||
inline unsigned int shape_flags<db::Text> ()
|
||||
inline unsigned int shape_flags<db::TextRef> ()
|
||||
{
|
||||
return db::ShapeIterator::Texts;
|
||||
}
|
||||
|
|
@ -1780,15 +1757,15 @@ local_processor<TS, TI, TR>::compute_local_cell (const db::local_processor_conte
|
|||
template class DB_PUBLIC local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
|
||||
template class DB_PUBLIC local_processor<db::PolygonRef, db::Edge, db::PolygonRef>;
|
||||
template class DB_PUBLIC local_processor<db::PolygonRef, db::Edge, db::Edge>;
|
||||
template class DB_PUBLIC local_processor<db::PolygonRef, db::Text, db::PolygonRef>;
|
||||
template class DB_PUBLIC local_processor<db::PolygonRef, db::Text, db::Text>;
|
||||
template class DB_PUBLIC local_processor<db::PolygonRef, db::TextRef, db::PolygonRef>;
|
||||
template class DB_PUBLIC local_processor<db::PolygonRef, db::TextRef, db::TextRef>;
|
||||
template class DB_PUBLIC local_processor<db::PolygonRef, db::PolygonRef, db::EdgePair>;
|
||||
template class DB_PUBLIC local_processor<db::Edge, db::Edge, db::Edge>;
|
||||
template class DB_PUBLIC local_processor<db::Edge, db::PolygonRef, db::Edge>;
|
||||
template class DB_PUBLIC local_processor<db::Edge, db::PolygonRef, db::PolygonRef>;
|
||||
template class DB_PUBLIC local_processor<db::Edge, db::Edge, db::EdgePair>;
|
||||
template class DB_PUBLIC local_processor<db::Text, db::PolygonRef, db::Text>;
|
||||
template class DB_PUBLIC local_processor<db::Text, db::PolygonRef, db::PolygonRef>;
|
||||
template class DB_PUBLIC local_processor<db::TextRef, db::PolygonRef, db::TextRef>;
|
||||
template class DB_PUBLIC local_processor<db::TextRef, db::PolygonRef, db::PolygonRef>;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -706,7 +706,8 @@ void EdgePairBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape
|
|||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
TextBuildingHierarchyBuilderShapeReceiver::TextBuildingHierarchyBuilderShapeReceiver ()
|
||||
TextBuildingHierarchyBuilderShapeReceiver::TextBuildingHierarchyBuilderShapeReceiver (db::Layout *layout)
|
||||
: mp_layout (layout)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -714,10 +715,10 @@ TextBuildingHierarchyBuilderShapeReceiver::TextBuildingHierarchyBuilderShapeRece
|
|||
void TextBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box & /*region*/, const db::RecursiveShapeReceiver::box_tree_type * /*complex_region*/, db::Shapes *target)
|
||||
{
|
||||
if (shape.is_text ()) {
|
||||
db::Text t;
|
||||
shape.text (t);
|
||||
t.transform (trans);
|
||||
target->insert (t);
|
||||
// NOTE: we intentionally skip all the text attributes (font etc.) here because in the context
|
||||
// of a text collections we're only interested in the locations.
|
||||
db::Text t (shape.text_string (), shape.text_trans ());
|
||||
target->insert (db::TextRef (t.transformed (trans), mp_layout->shape_repository ()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -196,11 +196,14 @@ class DB_PUBLIC TextBuildingHierarchyBuilderShapeReceiver
|
|||
: public HierarchyBuilderShapeReceiver
|
||||
{
|
||||
public:
|
||||
TextBuildingHierarchyBuilderShapeReceiver ();
|
||||
TextBuildingHierarchyBuilderShapeReceiver (db::Layout *layout);
|
||||
|
||||
virtual void push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
|
||||
virtual void push (const db::Box &, const db::ICplxTrans &, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *) { }
|
||||
virtual void push (const db::Polygon &, const db::ICplxTrans &, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *) { }
|
||||
|
||||
private:
|
||||
db::Layout *mp_layout;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -558,6 +558,14 @@ public:
|
|||
return m_string_repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Accessor to the string repository (const version)
|
||||
*/
|
||||
const StringRepository &string_repository () const
|
||||
{
|
||||
return m_string_repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Accessor to the shape repository
|
||||
*/
|
||||
|
|
@ -566,6 +574,14 @@ public:
|
|||
return m_shape_repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Accessor to the shape repository (const version)
|
||||
*/
|
||||
const GenericRepository &shape_repository () const
|
||||
{
|
||||
return m_shape_repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Accessor to the properties repository
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ void LayoutToNetlist::link_nets (const db::Net *net, const db::Net *with)
|
|||
return;
|
||||
}
|
||||
|
||||
connected_clusters<db::PolygonRef> &clusters = m_net_clusters.clusters_per_cell (net->circuit ()->cell_index ());
|
||||
connected_clusters<db::NetShape> &clusters = m_net_clusters.clusters_per_cell (net->circuit ()->cell_index ());
|
||||
clusters.join_cluster_with (net->cluster_id (), with->cluster_id ());
|
||||
}
|
||||
|
||||
|
|
@ -221,7 +221,7 @@ size_t LayoutToNetlist::link_net_to_parent_circuit (const Net *subcircuit_net, C
|
|||
db::CplxTrans dbu_trans (internal_layout ()->dbu ());
|
||||
db::ICplxTrans trans = dbu_trans.inverted () * dtrans * dbu_trans;
|
||||
|
||||
connected_clusters<db::PolygonRef> &parent_net_clusters = m_net_clusters.clusters_per_cell (parent_circuit->cell_index ());
|
||||
connected_clusters<db::NetShape> &parent_net_clusters = m_net_clusters.clusters_per_cell (parent_circuit->cell_index ());
|
||||
|
||||
size_t id = parent_net_clusters.insert_dummy ();
|
||||
|
||||
|
|
@ -613,49 +613,84 @@ namespace
|
|||
}
|
||||
|
||||
template <class Tr>
|
||||
static bool deliver_shape (const db::PolygonRef &, StopOnFirst, const Tr &, db::properties_id_type)
|
||||
static bool deliver_shape (const db::NetShape &, StopOnFirst, const Tr &, db::properties_id_type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class Tr>
|
||||
static bool deliver_shape (const db::PolygonRef &pr, db::Region ®ion, const Tr &tr, db::properties_id_type /*propid*/)
|
||||
static bool deliver_shape (const db::NetShape &s, db::Region ®ion, const Tr &tr, db::properties_id_type /*propid*/)
|
||||
{
|
||||
if (pr.obj ().is_box ()) {
|
||||
region.insert (pr.obj ().box ().transformed (pr.trans ()).transformed (tr));
|
||||
} else {
|
||||
region.insert (pr.obj ().transformed (pr.trans ()).transformed (tr));
|
||||
if (s.type () == db::NetShape::Polygon) {
|
||||
|
||||
db::PolygonRef pr = s.polygon_ref ();
|
||||
|
||||
if (pr.obj ().is_box ()) {
|
||||
region.insert (pr.obj ().box ().transformed (pr.trans ()).transformed (tr));
|
||||
} else {
|
||||
region.insert (pr.obj ().transformed (pr.trans ()).transformed (tr));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class Tr>
|
||||
static bool deliver_shape (const db::PolygonRef &pr, db::Shapes &shapes, const Tr &tr, db::properties_id_type propid)
|
||||
static bool deliver_shape (const db::NetShape &s, db::Shapes &shapes, const Tr &tr, db::properties_id_type propid)
|
||||
{
|
||||
if (pr.obj ().is_box ()) {
|
||||
if (propid) {
|
||||
shapes.insert (db::BoxWithProperties (pr.obj ().box ().transformed (pr.trans ()).transformed (tr), propid));
|
||||
if (s.type () == db::NetShape::Polygon) {
|
||||
|
||||
db::PolygonRef pr = s.polygon_ref ();
|
||||
|
||||
if (pr.obj ().is_box ()) {
|
||||
if (propid) {
|
||||
shapes.insert (db::BoxWithProperties (pr.obj ().box ().transformed (pr.trans ()).transformed (tr), propid));
|
||||
} else {
|
||||
shapes.insert (pr.obj ().box ().transformed (pr.trans ()).transformed (tr));
|
||||
}
|
||||
} else {
|
||||
shapes.insert (pr.obj ().box ().transformed (pr.trans ()).transformed (tr));
|
||||
db::Layout *layout = shapes.layout ();
|
||||
if (layout) {
|
||||
db::PolygonRef polygon_ref (pr.obj ().transformed (pr.trans ()).transformed (tr), layout->shape_repository ());
|
||||
if (propid) {
|
||||
shapes.insert (db::PolygonRefWithProperties (polygon_ref, propid));
|
||||
} else {
|
||||
shapes.insert (polygon_ref);
|
||||
}
|
||||
} else {
|
||||
db::Polygon polygon (pr.obj ().transformed (pr.trans ()).transformed (tr));
|
||||
if (propid) {
|
||||
shapes.insert (db::PolygonWithProperties (polygon, propid));
|
||||
} else {
|
||||
shapes.insert (polygon);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
} else if (s.type () == db::NetShape::Text) {
|
||||
|
||||
db::TextRef pr = s.text_ref ();
|
||||
|
||||
db::Layout *layout = shapes.layout ();
|
||||
if (layout) {
|
||||
db::PolygonRef polygon_ref (pr.obj ().transformed (pr.trans ()).transformed (tr), layout->shape_repository ());
|
||||
db::TextRef text_ref (pr.obj ().transformed (pr.trans ()).transformed (tr), layout->shape_repository ());
|
||||
if (propid) {
|
||||
shapes.insert (db::PolygonRefWithProperties (polygon_ref, propid));
|
||||
shapes.insert (db::TextRefWithProperties (text_ref, propid));
|
||||
} else {
|
||||
shapes.insert (polygon_ref);
|
||||
shapes.insert (text_ref);
|
||||
}
|
||||
} else {
|
||||
db::Polygon polygon (pr.obj ().transformed (pr.trans ()).transformed (tr));
|
||||
db::Text text (pr.obj ().transformed (pr.trans ()).transformed (tr));
|
||||
if (propid) {
|
||||
shapes.insert (db::PolygonWithProperties (polygon, propid));
|
||||
shapes.insert (db::TextWithProperties (text, propid));
|
||||
} else {
|
||||
shapes.insert (polygon);
|
||||
shapes.insert (text);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -759,7 +794,7 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
|
|||
|
||||
if (net_cell_name_prefix) {
|
||||
|
||||
const db::connected_clusters<db::PolygonRef> &ccl = m_net_clusters.clusters_per_cell (ci);
|
||||
const db::connected_clusters<db::NetShape> &ccl = m_net_clusters.clusters_per_cell (ci);
|
||||
|
||||
bool any_connections = circuit_cell_name_prefix && ! ccl.connections_for_cluster (cid).empty ();
|
||||
if (! any_connections) {
|
||||
|
|
@ -805,8 +840,8 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
|
|||
db::ICplxTrans tr_wo_mag = tr * db::ICplxTrans (1.0 / tr.mag ());
|
||||
db::ICplxTrans tr_mag (tr.mag ());
|
||||
|
||||
const db::connected_clusters<db::PolygonRef> &clusters = m_net_clusters.clusters_per_cell (ci);
|
||||
typedef db::connected_clusters<db::PolygonRef>::connections_type connections_type;
|
||||
const db::connected_clusters<db::NetShape> &clusters = m_net_clusters.clusters_per_cell (ci);
|
||||
typedef db::connected_clusters<db::NetShape>::connections_type connections_type;
|
||||
const connections_type &connections = clusters.connections_for_cluster (cid);
|
||||
for (connections_type::const_iterator c = connections.begin (); c != connections.end (); ++c) {
|
||||
|
||||
|
|
@ -1007,13 +1042,13 @@ db::Net *LayoutToNetlist::probe_net (const db::Region &of_region, const db::DPoi
|
|||
return probe_net (of_region, db::CplxTrans (internal_layout ()->dbu ()).inverted () * point);
|
||||
}
|
||||
|
||||
size_t LayoutToNetlist::search_net (const db::ICplxTrans &trans, const db::Cell *cell, const db::local_cluster<db::PolygonRef> &test_cluster, std::vector<db::InstElement> &rev_inst_path)
|
||||
size_t LayoutToNetlist::search_net (const db::ICplxTrans &trans, const db::Cell *cell, const db::local_cluster<db::NetShape> &test_cluster, std::vector<db::InstElement> &rev_inst_path)
|
||||
{
|
||||
db::Box local_box = trans * test_cluster.bbox ();
|
||||
|
||||
const db::local_clusters<db::PolygonRef> &lcc = net_clusters ().clusters_per_cell (cell->cell_index ());
|
||||
for (db::local_clusters<db::PolygonRef>::touching_iterator i = lcc.begin_touching (local_box); ! i.at_end (); ++i) {
|
||||
const db::local_cluster<db::PolygonRef> &lc = *i;
|
||||
const db::local_clusters<db::NetShape> &lcc = net_clusters ().clusters_per_cell (cell->cell_index ());
|
||||
for (db::local_clusters<db::NetShape>::touching_iterator i = lcc.begin_touching (local_box); ! i.at_end (); ++i) {
|
||||
const db::local_cluster<db::NetShape> &lc = *i;
|
||||
if (lc.interacts (test_cluster, trans, m_conn)) {
|
||||
return lc.id ();
|
||||
}
|
||||
|
|
@ -1053,7 +1088,7 @@ db::Net *LayoutToNetlist::probe_net (const db::Region &of_region, const db::Poin
|
|||
// Prepare a test cluster
|
||||
db::Box box (point - db::Vector (1, 1), point + db::Vector (1, 1));
|
||||
db::GenericRepository sr;
|
||||
db::local_cluster<db::PolygonRef> test_cluster;
|
||||
db::local_cluster<db::NetShape> test_cluster;
|
||||
test_cluster.add (db::PolygonRef (db::Polygon (box), sr), layer);
|
||||
|
||||
std::vector<db::InstElement> inst_path;
|
||||
|
|
@ -1155,12 +1190,12 @@ db::Region LayoutToNetlist::antenna_check (const db::Region &gate, const db::Reg
|
|||
|
||||
for (db::Layout::bottom_up_const_iterator cid = ly.begin_bottom_up (); cid != ly.end_bottom_up (); ++cid) {
|
||||
|
||||
const connected_clusters<db::PolygonRef> &clusters = m_net_clusters.clusters_per_cell (*cid);
|
||||
const connected_clusters<db::NetShape> &clusters = m_net_clusters.clusters_per_cell (*cid);
|
||||
if (clusters.empty ()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (connected_clusters<db::PolygonRef>::all_iterator c = clusters.begin_all (); ! c.at_end (); ++c) {
|
||||
for (connected_clusters<db::NetShape>::all_iterator c = clusters.begin_all (); ! c.at_end (); ++c) {
|
||||
|
||||
if (! clusters.is_root (*c)) {
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -522,7 +522,7 @@ public:
|
|||
* NOTE: the layer and cell indexes used inside this structure refer to the
|
||||
* internal layout.
|
||||
*/
|
||||
const db::hier_clusters<db::PolygonRef> &net_clusters () const
|
||||
const db::hier_clusters<db::NetShape> &net_clusters () const
|
||||
{
|
||||
return m_net_clusters;
|
||||
}
|
||||
|
|
@ -530,7 +530,7 @@ public:
|
|||
/**
|
||||
* @brief Gets the hierarchical shape clusters derived in the net extraction (non-conver version)
|
||||
*/
|
||||
db::hier_clusters<db::PolygonRef> &net_clusters ()
|
||||
db::hier_clusters<db::NetShape> &net_clusters ()
|
||||
{
|
||||
return m_net_clusters;
|
||||
}
|
||||
|
|
@ -744,7 +744,7 @@ private:
|
|||
tl::weak_ptr<db::DeepShapeStore> mp_dss;
|
||||
unsigned int m_layout_index;
|
||||
db::Connectivity m_conn;
|
||||
db::hier_clusters<db::PolygonRef> m_net_clusters;
|
||||
db::hier_clusters<db::NetShape> m_net_clusters;
|
||||
std::auto_ptr<db::Netlist> mp_netlist;
|
||||
std::set<db::DeepLayer> m_dlrefs;
|
||||
std::map<std::string, db::DeepLayer> m_named_regions;
|
||||
|
|
@ -786,7 +786,7 @@ private:
|
|||
|
||||
void init ();
|
||||
void ensure_netlist ();
|
||||
size_t search_net (const db::ICplxTrans &trans, const db::Cell *cell, const db::local_cluster<db::PolygonRef> &test_cluster, std::vector<db::InstElement> &rev_inst_path);
|
||||
size_t search_net (const db::ICplxTrans &trans, const db::Cell *cell, const db::local_cluster<NetShape> &test_cluster, std::vector<db::InstElement> &rev_inst_path);
|
||||
void build_net_rec (const db::Net &net, db::Layout &target, cell_index_type circuit_cell, const db::CellMapping &cmap, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const ICplxTrans &tr) const;
|
||||
void build_net_rec (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const ICplxTrans &tr) const;
|
||||
void build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const Net *net, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const ICplxTrans &tr) const;
|
||||
|
|
|
|||
|
|
@ -524,7 +524,7 @@ LayoutToNetlistStandardReader::read_polygon ()
|
|||
}
|
||||
|
||||
void
|
||||
LayoutToNetlistStandardReader::read_geometries (db::NetlistObject *obj, Brace &br, db::LayoutToNetlist *l2n, db::local_cluster<db::PolygonRef> &lc, db::Cell &cell)
|
||||
LayoutToNetlistStandardReader::read_geometries (db::NetlistObject *obj, Brace &br, db::LayoutToNetlist *l2n, db::local_cluster<db::NetShape> &lc, db::Cell &cell)
|
||||
{
|
||||
m_ref = db::Point ();
|
||||
|
||||
|
|
@ -561,8 +561,8 @@ LayoutToNetlistStandardReader::read_net (db::Netlist * /*netlist*/, db::LayoutTo
|
|||
|
||||
if (l2n) {
|
||||
|
||||
db::connected_clusters<db::PolygonRef> &cc = l2n->net_clusters ().clusters_per_cell (circuit->cell_index ());
|
||||
db::local_cluster<db::PolygonRef> &lc = *cc.insert ();
|
||||
db::connected_clusters<db::NetShape> &cc = l2n->net_clusters ().clusters_per_cell (circuit->cell_index ());
|
||||
db::local_cluster<db::NetShape> &lc = *cc.insert ();
|
||||
net->set_cluster_id (lc.id ());
|
||||
|
||||
db::Cell &cell = l2n->internal_layout ()->cell (circuit->cell_index ());
|
||||
|
|
@ -1025,8 +1025,8 @@ LayoutToNetlistStandardReader::read_abstract_terminal (db::LayoutToNetlist *l2n,
|
|||
|
||||
if (l2n) {
|
||||
|
||||
db::connected_clusters<db::PolygonRef> &cc = l2n->net_clusters ().clusters_per_cell (dm->cell_index ());
|
||||
db::local_cluster<db::PolygonRef> &lc = *cc.insert ();
|
||||
db::connected_clusters<db::NetShape> &cc = l2n->net_clusters ().clusters_per_cell (dm->cell_index ());
|
||||
db::local_cluster<db::NetShape> &lc = *cc.insert ();
|
||||
dm->set_cluster_id_for_terminal (tid, lc.id ());
|
||||
|
||||
db::Cell &cell = l2n->internal_layout ()->cell (dm->cell_index ());
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ protected:
|
|||
void read_property (db::NetlistObject *obj);
|
||||
db::Polygon read_polygon ();
|
||||
db::Box read_rect ();
|
||||
void read_geometries (db::NetlistObject *obj, Brace &br, db::LayoutToNetlist *l2n, db::local_cluster<db::PolygonRef> &lc, db::Cell &cell);
|
||||
void read_geometries (db::NetlistObject *obj, Brace &br, db::LayoutToNetlist *l2n, db::local_cluster<NetShape> &lc, db::Cell &cell);
|
||||
db::Point read_point ();
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -397,11 +397,16 @@ void std_writer_impl<Keys>::reset_geometry_ref ()
|
|||
}
|
||||
|
||||
template <class Keys>
|
||||
void std_writer_impl<Keys>::write (const db::PolygonRef *s, const db::ICplxTrans &tr, const std::string &lname, bool relative)
|
||||
void std_writer_impl<Keys>::write (const db::NetShape *s, const db::ICplxTrans &tr, const std::string &lname, bool relative)
|
||||
{
|
||||
db::ICplxTrans t = tr * db::ICplxTrans (s->trans ());
|
||||
if (s->type () != db::NetShape::Polygon) {
|
||||
return;
|
||||
}
|
||||
|
||||
const db::Polygon &poly = s->obj ();
|
||||
db::PolygonRef pr = s->polygon_ref ();
|
||||
db::ICplxTrans t = tr * db::ICplxTrans (pr.trans ());
|
||||
|
||||
const db::Polygon &poly = pr.obj ();
|
||||
if (poly.is_box ()) {
|
||||
|
||||
db::Box box = t * poly.box ();
|
||||
|
|
@ -435,7 +440,7 @@ bool std_writer_impl<Keys>::new_cell (cell_index_type ci) const
|
|||
template <class Keys>
|
||||
void std_writer_impl<Keys>::write (const db::Net &net, unsigned int id, const std::string &indent)
|
||||
{
|
||||
const db::hier_clusters<db::PolygonRef> &clusters = mp_l2n->net_clusters ();
|
||||
const db::hier_clusters<db::NetShape> &clusters = mp_l2n->net_clusters ();
|
||||
const db::Circuit *circuit = net.circuit ();
|
||||
const db::Connectivity &conn = mp_l2n->connectivity ();
|
||||
|
||||
|
|
@ -450,7 +455,7 @@ void std_writer_impl<Keys>::write (const db::Net &net, unsigned int id, const st
|
|||
db::cell_index_type cci = circuit->cell_index ();
|
||||
db::cell_index_type prev_ci = cci;
|
||||
|
||||
for (db::recursive_cluster_shape_iterator<db::PolygonRef> si (clusters, *l, cci, net.cluster_id (), this); ! si.at_end (); ) {
|
||||
for (db::recursive_cluster_shape_iterator<db::NetShape> si (clusters, *l, cci, net.cluster_id (), this); ! si.at_end (); ) {
|
||||
|
||||
// NOTE: we don't recursive into circuits which will later be output. However, as circuits may
|
||||
// vanish in "purge" but the clusters will still be there we need to recursive into clusters from
|
||||
|
|
@ -570,7 +575,7 @@ void std_writer_impl<Keys>::write (const db::DeviceAbstract &device_abstract, co
|
|||
{
|
||||
const std::vector<db::DeviceTerminalDefinition> &td = device_abstract.device_class ()->terminal_definitions ();
|
||||
|
||||
const db::hier_clusters<db::PolygonRef> &clusters = mp_l2n->net_clusters ();
|
||||
const db::hier_clusters<db::NetShape> &clusters = mp_l2n->net_clusters ();
|
||||
const db::Connectivity &conn = mp_l2n->connectivity ();
|
||||
|
||||
for (std::vector<db::DeviceTerminalDefinition>::const_iterator t = td.begin (); t != td.end (); ++t) {
|
||||
|
|
@ -587,8 +592,8 @@ void std_writer_impl<Keys>::write (const db::DeviceAbstract &device_abstract, co
|
|||
continue;
|
||||
}
|
||||
|
||||
const db::local_cluster<db::PolygonRef> &lc = clusters.clusters_per_cell (device_abstract.cell_index ()).cluster_by_id (cid);
|
||||
for (db::local_cluster<db::PolygonRef>::shape_iterator s = lc.begin (*l); ! s.at_end (); ++s) {
|
||||
const db::local_cluster<db::NetShape> &lc = clusters.clusters_per_cell (device_abstract.cell_index ()).cluster_by_id (cid);
|
||||
for (db::local_cluster<db::NetShape>::shape_iterator s = lc.begin (*l); ! s.at_end (); ++s) {
|
||||
|
||||
*mp_stream << indent << indent2;
|
||||
write (s.operator-> (), db::ICplxTrans (), name_for_layer (mp_l2n, *l), true);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ class DeviceAbstract;
|
|||
class Net;
|
||||
class Netlist;
|
||||
class LayoutToNetlist;
|
||||
class NetShape;
|
||||
|
||||
namespace l2n_std_format
|
||||
{
|
||||
|
|
@ -75,7 +76,7 @@ private:
|
|||
void write (const db::SubCircuit &subcircuit, std::map<const Net *, unsigned int> &net2id, const std::string &indent);
|
||||
void write (const db::Device &device, std::map<const Net *, unsigned int> &net2id, const std::string &indent);
|
||||
void write (const db::DeviceAbstract &device_abstract, const std::string &indent);
|
||||
void write (const db::PolygonRef *s, const db::ICplxTrans &tr, const std::string &lname, bool relative);
|
||||
void write (const db::NetShape *s, const db::ICplxTrans &tr, const std::string &lname, bool relative);
|
||||
void write (const db::DCplxTrans &trans);
|
||||
void reset_geometry_ref ();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include "dbNetShape.h"
|
||||
#include "dbShapes.h"
|
||||
#include "dbPolygonTools.h"
|
||||
|
||||
namespace db {
|
||||
|
||||
NetShape::NetShape ()
|
||||
: m_ptr (0), m_dx (0), m_dy (0)
|
||||
{ }
|
||||
|
||||
NetShape::NetShape (const db::PolygonRef &pr)
|
||||
{
|
||||
m_ptr = size_t (&pr.obj ()) + 1;
|
||||
m_dx = pr.trans ().disp ().x ();
|
||||
m_dy = pr.trans ().disp ().y ();
|
||||
}
|
||||
|
||||
NetShape::NetShape (const db::Polygon &poly, db::GenericRepository &repo)
|
||||
{
|
||||
db::PolygonRef pr (poly, repo);
|
||||
m_ptr = size_t (&pr.obj ()) + 1;
|
||||
m_dx = pr.trans ().disp ().x ();
|
||||
m_dy = pr.trans ().disp ().y ();
|
||||
}
|
||||
|
||||
NetShape::NetShape (const db::TextRef &tr)
|
||||
{
|
||||
m_ptr = size_t (&tr.obj ());
|
||||
m_dx = tr.trans ().disp ().x ();
|
||||
m_dy = tr.trans ().disp ().y ();
|
||||
}
|
||||
|
||||
NetShape::NetShape (const db::Text &text, db::GenericRepository &repo)
|
||||
{
|
||||
db::TextRef tr (text, repo);
|
||||
m_ptr = size_t (&tr.obj ());
|
||||
m_dx = tr.trans ().disp ().x ();
|
||||
m_dy = tr.trans ().disp ().y ();
|
||||
}
|
||||
|
||||
NetShape::shape_type NetShape::type () const
|
||||
{
|
||||
if (m_ptr == 0) {
|
||||
return None;
|
||||
} else if ((m_ptr & 1) != 0) {
|
||||
return Polygon;
|
||||
} else {
|
||||
return Text;
|
||||
}
|
||||
}
|
||||
|
||||
db::PolygonRef NetShape::polygon_ref () const
|
||||
{
|
||||
if ((size_t (m_ptr) & 1) != 0) {
|
||||
return db::PolygonRef (reinterpret_cast<db::Polygon *> (m_ptr - 1), db::Disp (db::Vector (m_dx, m_dy)));
|
||||
}
|
||||
tl_assert (false);
|
||||
}
|
||||
|
||||
db::TextRef NetShape::text_ref () const
|
||||
{
|
||||
if ((size_t (m_ptr) & 1) == 0) {
|
||||
return db::TextRef (reinterpret_cast<db::Text *> (m_ptr), db::Disp (db::Vector (m_dx, m_dy)));
|
||||
}
|
||||
tl_assert (false);
|
||||
}
|
||||
|
||||
void NetShape::transform (const db::Disp &tr)
|
||||
{
|
||||
m_dx += tr.disp ().x ();
|
||||
m_dy += tr.disp ().y ();
|
||||
}
|
||||
|
||||
NetShape::box_type NetShape::bbox () const
|
||||
{
|
||||
if ((m_ptr & 1) != 0) {
|
||||
return polygon_ref ().box ();
|
||||
} else if (m_ptr != 0) {
|
||||
return text_ref ().box ();
|
||||
} else {
|
||||
return box_type ();
|
||||
}
|
||||
}
|
||||
|
||||
void NetShape::insert_into (db::Shapes &shapes) const
|
||||
{
|
||||
if ((m_ptr & 1) != 0) {
|
||||
shapes.insert (polygon_ref ());
|
||||
} else if (m_ptr != 0) {
|
||||
shapes.insert (text_ref ());
|
||||
}
|
||||
}
|
||||
|
||||
void NetShape::insert_into (db::Shapes &shapes, db::properties_id_type pi) const
|
||||
{
|
||||
if ((m_ptr & 1) != 0) {
|
||||
shapes.insert (db::PolygonRefWithProperties (polygon_ref (), pi));
|
||||
} else if (m_ptr != 0) {
|
||||
shapes.insert (db::TextRefWithProperties (text_ref (), pi));
|
||||
}
|
||||
}
|
||||
|
||||
bool NetShape::interacts_with (const db::NetShape &other) const
|
||||
{
|
||||
if (m_ptr == 0 || other.m_ptr == 0 || ! bbox ().touches (other.bbox ())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((m_ptr & 1) != 0) {
|
||||
|
||||
if ((other.m_ptr & 1) != 0) {
|
||||
|
||||
// Polygon vs. polygon
|
||||
db::PolygonRef pr_other = other.polygon_ref ();
|
||||
db::PolygonRef pr = polygon_ref ();
|
||||
db::Polygon p = pr_other.obj ().transformed (pr.trans ().inverted () * pr_other.trans ());
|
||||
return db::interact_pp (pr.obj (), p);
|
||||
|
||||
} else {
|
||||
|
||||
// NOTE: we assume that the text ref's target is at 0,0
|
||||
db::PolygonRef pr = polygon_ref ();
|
||||
db::Point pt = db::Point (other.m_dx, other.m_dy) - pr.trans ().disp ();
|
||||
return db::inside_poly (pr.obj ().begin_edge (), pt) >= 0;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ((other.m_ptr & 1) == 0) {
|
||||
|
||||
// Text vs. text
|
||||
return m_dx == other.m_dx && m_dy == other.m_dy;
|
||||
|
||||
} else {
|
||||
|
||||
// NOTE: we assume that the text ref's target is at 0,0
|
||||
db::PolygonRef pr_other = other.polygon_ref ();
|
||||
db::Point pt = db::Point (m_dx, m_dy) - pr_other.trans ().disp ();
|
||||
return db::inside_poly (pr_other.obj ().begin_edge (), pt) >= 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
template <class Tr>
|
||||
bool NetShape::interacts_with_transformed (const db::NetShape &other, const Tr &trans) const
|
||||
{
|
||||
if (m_ptr == 0 || other.m_ptr == 0 || ! bbox ().touches (other.bbox ().transformed (trans))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((m_ptr & 1) != 0) {
|
||||
|
||||
if ((other.m_ptr & 1) != 0) {
|
||||
|
||||
// Polygon vs. polygon
|
||||
db::PolygonRef pr_other = other.polygon_ref ();
|
||||
db::PolygonRef pr = polygon_ref ();
|
||||
db::Polygon p = pr_other.obj ().transformed (Tr (pr.trans ().inverted ()) * trans * Tr (pr_other.trans ()));
|
||||
return db::interact_pp (pr.obj (), p);
|
||||
|
||||
} else {
|
||||
|
||||
// NOTE: we assume that the text ref's target is at 0,0
|
||||
db::PolygonRef pr = polygon_ref ();
|
||||
db::Point pt = trans * db::Point (other.m_dx, other.m_dy) - pr.trans ().disp ();
|
||||
return db::inside_poly (pr.obj ().begin_edge (), pt) >= 0;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ((other.m_ptr & 1) == 0) {
|
||||
|
||||
// Text vs. text
|
||||
db::Point pt = trans * db::Point (other.m_dx, other.m_dy);
|
||||
return db::Point (m_dx, m_dy) == pt;
|
||||
|
||||
} else {
|
||||
|
||||
// NOTE: we assume that the text ref's target is at 0,0
|
||||
db::PolygonRef pr_other = other.polygon_ref ();
|
||||
db::Point pt = trans.inverted () * db::Point (m_dx, m_dy) - pr_other.trans ().disp ();
|
||||
return db::inside_poly (pr_other.obj ().begin_edge (), pt) >= 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// explicit instantiations
|
||||
template bool NetShape::interacts_with_transformed<db::ICplxTrans> (const db::NetShape &other, const db::ICplxTrans &trans) const;
|
||||
template bool NetShape::interacts_with_transformed<db::Trans> (const db::NetShape &other, const db::Trans &trans) const;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HDR_dbNetShape
|
||||
#define HDR_dbNetShape
|
||||
|
||||
#include "dbPolygon.h"
|
||||
#include "dbText.h"
|
||||
#include "dbShapeRepository.h"
|
||||
#include "dbBoxConvert.h"
|
||||
|
||||
namespace db {
|
||||
|
||||
class Shapes;
|
||||
|
||||
/**
|
||||
* @brief Provides a union of a PolygonRef and a TextRef
|
||||
*
|
||||
* This object is used in the netlist extractor and represents either a polygon or a text.
|
||||
* The TextRef shall utilize a StringRef to represent the string.
|
||||
*/
|
||||
class DB_PUBLIC NetShape
|
||||
{
|
||||
public:
|
||||
enum shape_type { None, Text, Polygon };
|
||||
|
||||
typedef db::Point point_type;
|
||||
typedef db::Box box_type;
|
||||
typedef db::Coord coord_type;
|
||||
typedef db::Disp trans_type;
|
||||
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
NetShape ();
|
||||
|
||||
/**
|
||||
* @brief A NetShape object representing a PolygonRef
|
||||
*/
|
||||
NetShape (const db::PolygonRef &pr);
|
||||
|
||||
/**
|
||||
* @brief A NetShape object representing a Polygon from the given shape repository
|
||||
*/
|
||||
NetShape (const db::Polygon &poly, db::GenericRepository &repo);
|
||||
|
||||
/**
|
||||
* @brief A NetShape object representing a TextRef
|
||||
*/
|
||||
NetShape (const db::TextRef &tr);
|
||||
|
||||
/**
|
||||
* @brief A NetShape object representing a Text from the given shape repository
|
||||
*/
|
||||
NetShape (const db::Text &text, db::GenericRepository &repo);
|
||||
|
||||
/**
|
||||
* @brief Gets a code indicating the type of object stored herein
|
||||
*/
|
||||
shape_type type () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the PolygonRef object
|
||||
* Asserts if the object stored is not a polygon.
|
||||
*/
|
||||
db::PolygonRef polygon_ref () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the TextRef object
|
||||
* Asserts if the object stored is not a text.
|
||||
*/
|
||||
db::TextRef text_ref () const;
|
||||
|
||||
/**
|
||||
* @brief In-place transformation
|
||||
*/
|
||||
void transform (const db::Disp &tr);
|
||||
|
||||
/**
|
||||
* @brief Equality
|
||||
*/
|
||||
bool operator== (const NetShape &net_shape) const
|
||||
{
|
||||
return m_ptr == net_shape.m_ptr && m_dx == net_shape.m_dx && m_dy == net_shape.m_dy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inequality
|
||||
*/
|
||||
bool operator!= (const NetShape &net_shape) const
|
||||
{
|
||||
return ! operator== (net_shape);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Less operator
|
||||
*/
|
||||
bool operator< (const NetShape &net_shape) const
|
||||
{
|
||||
if (m_ptr != net_shape.m_ptr) {
|
||||
return m_ptr < net_shape.m_ptr;
|
||||
}
|
||||
if (m_dx != net_shape.m_dx) {
|
||||
return m_dx < net_shape.m_dx;
|
||||
}
|
||||
return m_dy < net_shape.m_dy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the bounding box of the object
|
||||
*/
|
||||
box_type bbox () const;
|
||||
|
||||
/**
|
||||
* @brief Inserts the object into a Shapes collection
|
||||
*/
|
||||
void insert_into (db::Shapes &shapes) const;
|
||||
|
||||
/**
|
||||
* @brief Inserts the object into a Shapes collection with the given properties ID
|
||||
*/
|
||||
void insert_into (db::Shapes &shapes, db::properties_id_type pi) const;
|
||||
|
||||
/**
|
||||
* @brief Returns true if the object interacts with another NetShape object
|
||||
*/
|
||||
bool interacts_with (const db::NetShape &other) const;
|
||||
|
||||
/**
|
||||
* @brief Returns true if the object interacts with another NetShape object after transforming it
|
||||
*/
|
||||
template <class Tr>
|
||||
bool interacts_with_transformed (const db::NetShape &other, const Tr &trans) const;
|
||||
|
||||
public:
|
||||
size_t m_ptr;
|
||||
coord_type m_dx, m_dy;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A box converter implementation for NetShape
|
||||
*/
|
||||
template <>
|
||||
struct box_convert<db::NetShape>
|
||||
{
|
||||
typedef db::NetShape::box_type box_type;
|
||||
typedef db::NetShape::coord_type coord_type;
|
||||
typedef db::complex_bbox_tag complexity;
|
||||
|
||||
box_type operator() (const db::NetShape &net_shape) const
|
||||
{
|
||||
return net_shape.bbox ();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -119,9 +119,12 @@ void NetlistDeviceExtractor::initialize (db::Netlist *nl)
|
|||
setup ();
|
||||
}
|
||||
|
||||
static void insert_into_region (const db::PolygonRef &s, const db::ICplxTrans &tr, db::Region ®ion)
|
||||
static void insert_into_region (const db::NetShape &s, const db::ICplxTrans &tr, db::Region ®ion)
|
||||
{
|
||||
region.insert (s.obj ().transformed (tr * db::ICplxTrans (s.trans ())));
|
||||
if (s.type () == db::NetShape::Polygon) {
|
||||
db::PolygonRef pr = s.polygon_ref ();
|
||||
region.insert (pr.obj ().transformed (tr * db::ICplxTrans (pr.trans ())));
|
||||
}
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::extract (db::DeepShapeStore &dss, unsigned int layout_index, const NetlistDeviceExtractor::input_layers &layer_map, db::Netlist &nl, hier_clusters_type &clusters, double device_scaling)
|
||||
|
|
@ -207,8 +210,7 @@ void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db:
|
|||
{
|
||||
tl_assert (layers.size () == m_layer_definitions.size ());
|
||||
|
||||
typedef db::PolygonRef shape_type;
|
||||
db::ShapeIterator::flags_type shape_iter_flags = db::ShapeIterator::Polygons;
|
||||
typedef db::NetShape shape_type;
|
||||
|
||||
mp_layout = &layout;
|
||||
m_layers = layers;
|
||||
|
|
@ -247,7 +249,7 @@ void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db:
|
|||
|
||||
db::Connectivity device_conn = get_connectivity (layout, layers);
|
||||
db::hier_clusters<shape_type> device_clusters;
|
||||
device_clusters.build (layout, cell, shape_iter_flags, device_conn, 0, breakout_cells);
|
||||
device_clusters.build (layout, cell, device_conn, 0, breakout_cells);
|
||||
|
||||
tl::SelfTimer timer (tl::verbosity () >= 21, tl::to_string (tr ("Extracting devices")));
|
||||
|
||||
|
|
@ -365,12 +367,12 @@ void NetlistDeviceExtractor::push_new_devices (const db::Vector &disp_cache)
|
|||
DeviceCellKey key;
|
||||
|
||||
for (geometry_per_terminal_type::const_iterator t = d->second.second.begin (); t != d->second.second.end (); ++t) {
|
||||
std::map<unsigned int, std::set<db::PolygonRef> > > = key.geometry [t->first];
|
||||
std::map<unsigned int, std::set<db::NetShape> > > = key.geometry [t->first];
|
||||
for (geometry_per_layer_type::const_iterator l = t->second.begin (); l != t->second.end (); ++l) {
|
||||
std::set<db::PolygonRef> &gl = gt [l->first];
|
||||
for (std::vector<db::PolygonRef>::const_iterator p = l->second.begin (); p != l->second.end (); ++p) {
|
||||
db::PolygonRef pr = *p;
|
||||
pr.transform (db::PolygonRef::trans_type (-disp));
|
||||
std::set<db::NetShape> &gl = gt [l->first];
|
||||
for (std::vector<db::NetShape>::const_iterator p = l->second.begin (); p != l->second.end (); ++p) {
|
||||
db::NetShape pr = *p;
|
||||
pr.transform (db::NetShape::trans_type (-disp));
|
||||
gl.insert (pr);
|
||||
}
|
||||
}
|
||||
|
|
@ -411,10 +413,10 @@ void NetlistDeviceExtractor::push_new_devices (const db::Vector &disp_cache)
|
|||
for (geometry_per_layer_type::const_iterator l = t->second.begin (); l != t->second.end (); ++l) {
|
||||
|
||||
db::Shapes &shapes = device_cell.shapes (l->first);
|
||||
for (std::vector<db::PolygonRef>::const_iterator s = l->second.begin (); s != l->second.end (); ++s) {
|
||||
db::PolygonRef pr = *s;
|
||||
pr.transform (db::PolygonRef::trans_type (-disp));
|
||||
shapes.insert (db::PolygonRefWithProperties (pr, pi));
|
||||
for (std::vector<db::NetShape>::const_iterator s = l->second.begin (); s != l->second.end (); ++s) {
|
||||
db::NetShape pr = *s;
|
||||
pr.transform (db::NetShape::trans_type (-disp));
|
||||
pr.insert_into (shapes, pi);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -542,10 +544,10 @@ void NetlistDeviceExtractor::define_terminal (Device *device, size_t terminal_id
|
|||
|
||||
std::pair<db::Device *, geometry_per_terminal_type> &dd = m_new_devices[device->id ()];
|
||||
dd.first = device;
|
||||
std::vector<db::PolygonRef> &geo = dd.second[terminal_id][layer_index];
|
||||
std::vector<db::NetShape> &geo = dd.second[terminal_id][layer_index];
|
||||
|
||||
for (db::Region::const_iterator p = region.begin_merged (); !p.at_end (); ++p) {
|
||||
geo.push_back (db::PolygonRef (*p, mp_layout->shape_repository ()));
|
||||
geo.push_back (db::NetShape (*p, mp_layout->shape_repository ()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -555,7 +557,7 @@ void NetlistDeviceExtractor::define_terminal (Device *device, size_t terminal_id
|
|||
tl_assert (geometry_index < m_layers.size ());
|
||||
unsigned int layer_index = m_layers [geometry_index];
|
||||
|
||||
db::PolygonRef pr (polygon, mp_layout->shape_repository ());
|
||||
db::NetShape pr (polygon, mp_layout->shape_repository ());
|
||||
std::pair<db::Device *, geometry_per_terminal_type> &dd = m_new_devices[device->id ()];
|
||||
dd.first = device;
|
||||
dd.second[terminal_id][layer_index].push_back (pr);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "dbHierNetworkProcessor.h"
|
||||
#include "dbDeepShapeStore.h"
|
||||
#include "dbRegion.h"
|
||||
#include "dbNetShape.h"
|
||||
|
||||
#include "gsiObject.h"
|
||||
|
||||
|
|
@ -205,7 +206,7 @@ public:
|
|||
typedef std::vector<db::NetlistDeviceExtractorLayerDefinition> layer_definitions;
|
||||
typedef layer_definitions::const_iterator layer_definitions_iterator;
|
||||
typedef std::map<std::string, db::Region *> input_layers;
|
||||
typedef db::hier_clusters<db::PolygonRef> hier_clusters_type;
|
||||
typedef db::hier_clusters<db::NetShape> hier_clusters_type;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
|
|
@ -260,8 +261,6 @@ public:
|
|||
* the nets later to associate nets with device terminals.
|
||||
*
|
||||
* The definition of the input layers is device class specific.
|
||||
*
|
||||
* NOTE: The extractor expects "PolygonRef" type layers.
|
||||
*/
|
||||
void extract (Layout &layout, Cell &cell, const std::vector<unsigned int> &layers, Netlist *netlist, hier_clusters_type &clusters, double device_scaling = 1.0, const std::set<cell_index_type> *breakout_cells = 0);
|
||||
|
||||
|
|
@ -521,11 +520,11 @@ private:
|
|||
return false;
|
||||
}
|
||||
|
||||
std::map<size_t, std::map<unsigned int, std::set<db::PolygonRef> > > geometry;
|
||||
std::map<size_t, std::map<unsigned int, std::set<db::NetShape> > > geometry;
|
||||
std::map<size_t, double> parameters;
|
||||
};
|
||||
|
||||
typedef std::map<unsigned int, std::vector<db::PolygonRef> > geometry_per_layer_type;
|
||||
typedef std::map<unsigned int, std::vector<db::NetShape> > geometry_per_layer_type;
|
||||
typedef std::map<size_t, geometry_per_layer_type> geometry_per_terminal_type;
|
||||
|
||||
tl::weak_ptr<db::Netlist> m_netlist;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "dbNetlistExtractor.h"
|
||||
#include "dbDeepShapeStore.h"
|
||||
#include "dbNetlistDeviceExtractor.h"
|
||||
#include "dbShapeRepository.h"
|
||||
#include "tlGlobPattern.h"
|
||||
|
||||
namespace db
|
||||
|
|
@ -50,9 +51,9 @@ void NetlistExtractor::set_include_floating_subcircuits (bool f)
|
|||
}
|
||||
|
||||
static void
|
||||
build_net_name_equivalence (const db::Layout *layout, db::property_names_id_type net_name_id, const std::string &joined_net_names, tl::equivalence_clusters<unsigned int> &eq)
|
||||
build_net_name_equivalence (const db::Layout *layout, db::property_names_id_type net_name_id, const std::string &joined_net_names, tl::equivalence_clusters<size_t> &eq)
|
||||
{
|
||||
std::map<std::string, std::set<unsigned int> > prop_by_name;
|
||||
std::map<std::string, std::set<size_t> > prop_by_name;
|
||||
tl::GlobPattern jn_pattern (joined_net_names);
|
||||
|
||||
for (db::PropertiesRepository::iterator i = layout->properties_repository ().begin (); i != layout->properties_repository ().end (); ++i) {
|
||||
|
|
@ -60,15 +61,23 @@ build_net_name_equivalence (const db::Layout *layout, db::property_names_id_type
|
|||
if (p->first == net_name_id) {
|
||||
std::string nn = p->second.to_string ();
|
||||
if (jn_pattern.match (nn)) {
|
||||
prop_by_name [nn].insert (i->first);
|
||||
prop_by_name [nn].insert (db::prop_id_to_attr (i->first));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (std::map<std::string, std::set<unsigned int> >::const_iterator pn = prop_by_name.begin (); pn != prop_by_name.end (); ++pn) {
|
||||
std::set<unsigned int>::const_iterator p = pn->second.begin ();
|
||||
std::set<unsigned int>::const_iterator p0 = p;
|
||||
const db::repository<db::Text> &text_repository = layout->shape_repository ().repository (db::object_tag<db::Text> ());
|
||||
for (db::repository<db::Text>::iterator t = text_repository.begin (); t != text_repository.end (); ++t) {
|
||||
std::string nn = t->string ();
|
||||
if (jn_pattern.match (nn)) {
|
||||
prop_by_name [nn].insert (db::text_ref_to_attr (t.operator-> ()));
|
||||
}
|
||||
}
|
||||
|
||||
for (std::map<std::string, std::set<size_t> >::const_iterator pn = prop_by_name.begin (); pn != prop_by_name.end (); ++pn) {
|
||||
std::set<size_t>::const_iterator p = pn->second.begin ();
|
||||
std::set<size_t>::const_iterator p0 = p;
|
||||
while (p != pn->second.end ()) {
|
||||
eq.same (*p0, *p);
|
||||
++p;
|
||||
|
|
@ -93,9 +102,9 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, unsigned int layo
|
|||
m_terminal_annot_name_id = mp_layout->properties_repository ().get_id_of_name (db::NetlistDeviceExtractor::terminal_id_property_name ());
|
||||
m_device_annot_name_id = mp_layout->properties_repository ().get_id_of_name (db::NetlistDeviceExtractor::device_id_property_name ());
|
||||
|
||||
// the big part: actually extract the nets
|
||||
// build an attribute equivalence map which lists the "attribute IDs" which are identical in terms of net names
|
||||
|
||||
std::map<db::cell_index_type, tl::equivalence_clusters<unsigned int> > net_name_equivalence;
|
||||
std::map<db::cell_index_type, tl::equivalence_clusters<size_t> > net_name_equivalence;
|
||||
if (m_text_annot_name_id.first) {
|
||||
if (! m_joined_net_names.empty ()) {
|
||||
build_net_name_equivalence (mp_layout, m_text_annot_name_id.second, m_joined_net_names, net_name_equivalence [hier_clusters_type::top_cell_index]);
|
||||
|
|
@ -107,7 +116,10 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, unsigned int layo
|
|||
}
|
||||
}
|
||||
}
|
||||
mp_clusters->build (*mp_layout, *mp_cell, db::ShapeIterator::Polygons, conn, &net_name_equivalence);
|
||||
|
||||
// the big part: actually extract the nets
|
||||
|
||||
mp_clusters->build (*mp_layout, *mp_cell, conn, &net_name_equivalence);
|
||||
|
||||
// reverse lookup for Circuit vs. cell index
|
||||
std::map<db::cell_index_type, db::Circuit *> circuits;
|
||||
|
|
@ -181,7 +193,7 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, unsigned int layo
|
|||
|
||||
for (connected_clusters_type::all_iterator c = clusters.begin_all (); ! c.at_end (); ++c) {
|
||||
|
||||
const db::local_cluster<db::PolygonRef> &lc = clusters.cluster_by_id (*c);
|
||||
const db::local_cluster<db::NetShape> &lc = clusters.cluster_by_id (*c);
|
||||
if (clusters.connections_for_cluster (*c).empty () && lc.empty ()) {
|
||||
// this is an entirely empty cluster so we skip it.
|
||||
// Such clusters are left over when joining clusters.
|
||||
|
|
@ -204,8 +216,8 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, unsigned int layo
|
|||
|
||||
// add the global names as second priority
|
||||
if (net_names.empty ()) {
|
||||
const db::local_cluster<db::PolygonRef>::global_nets &gn = lc.get_global_nets ();
|
||||
for (db::local_cluster<db::PolygonRef>::global_nets::const_iterator g = gn.begin (); g != gn.end (); ++g) {
|
||||
const db::local_cluster<db::NetShape>::global_nets &gn = lc.get_global_nets ();
|
||||
for (db::local_cluster<db::NetShape>::global_nets::const_iterator g = gn.begin (); g != gn.end (); ++g) {
|
||||
net_names.insert (conn.global_net_name (*g));
|
||||
}
|
||||
}
|
||||
|
|
@ -250,7 +262,13 @@ NetlistExtractor::make_device_abstract_connections (db::DeviceAbstract *dm, cons
|
|||
|
||||
for (local_cluster_type::attr_iterator a = dc->begin_attr (); a != dc->end_attr (); ++a) {
|
||||
|
||||
const db::PropertiesRepository::properties_set &ps = mp_layout->properties_repository ().properties (*a);
|
||||
if (! db::is_prop_id_attr (*a)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
db::properties_id_type pi = db::prop_id_from_attr (*a);
|
||||
|
||||
const db::PropertiesRepository::properties_set &ps = mp_layout->properties_repository ().properties (pi);
|
||||
for (db::PropertiesRepository::properties_set::const_iterator j = ps.begin (); j != ps.end (); ++j) {
|
||||
if (j->first == m_terminal_annot_name_id.second) {
|
||||
dm->set_cluster_id_for_terminal (j->second.to<size_t> (), dc->id ());
|
||||
|
|
@ -282,7 +300,13 @@ void NetlistExtractor::collect_labels (const connected_clusters_type &clusters,
|
|||
const local_cluster_type &lc = clusters.cluster_by_id (cid);
|
||||
for (local_cluster_type::attr_iterator a = lc.begin_attr (); a != lc.end_attr (); ++a) {
|
||||
|
||||
const db::PropertiesRepository::properties_set &ps = mp_layout->properties_repository ().properties (*a);
|
||||
if (! db::is_prop_id_attr (*a)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
db::properties_id_type pi = db::prop_id_from_attr (*a);
|
||||
|
||||
const db::PropertiesRepository::properties_set &ps = mp_layout->properties_repository ().properties (pi);
|
||||
for (db::PropertiesRepository::properties_set::const_iterator j = ps.begin (); j != ps.end (); ++j) {
|
||||
|
||||
if (m_text_annot_name_id.first && j->first == m_text_annot_name_id.second) {
|
||||
|
|
@ -343,13 +367,19 @@ void NetlistExtractor::connect_devices (db::Circuit *circuit,
|
|||
continue;
|
||||
}
|
||||
|
||||
const db::local_cluster<db::PolygonRef> &dc = mp_clusters->clusters_per_cell (inst_cell_index).cluster_by_id (i->id ());
|
||||
const db::local_cluster<db::NetShape> &dc = mp_clusters->clusters_per_cell (inst_cell_index).cluster_by_id (i->id ());
|
||||
|
||||
// connect the net to the terminal of the device: take the terminal ID from the properties on the
|
||||
// device cluster
|
||||
for (local_cluster_type::attr_iterator a = dc.begin_attr (); a != dc.end_attr (); ++a) {
|
||||
|
||||
const db::PropertiesRepository::properties_set &ps = mp_layout->properties_repository ().properties (*a);
|
||||
if (! db::is_prop_id_attr (*a)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
db::properties_id_type pi = db::prop_id_from_attr (*a);
|
||||
|
||||
const db::PropertiesRepository::properties_set &ps = mp_layout->properties_repository ().properties (pi);
|
||||
for (db::PropertiesRepository::properties_set::const_iterator j = ps.begin (); j != ps.end (); ++j) {
|
||||
|
||||
if (m_terminal_annot_name_id.first && j->first == m_terminal_annot_name_id.second) {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "dbCommon.h"
|
||||
#include "dbHierNetworkProcessor.h"
|
||||
#include "dbNetShape.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
|
@ -71,9 +72,9 @@ class DeviceAbstract;
|
|||
class DB_PUBLIC NetlistExtractor
|
||||
{
|
||||
public:
|
||||
typedef db::hier_clusters<db::PolygonRef> hier_clusters_type;
|
||||
typedef db::connected_clusters<db::PolygonRef> connected_clusters_type;
|
||||
typedef db::local_cluster<db::PolygonRef> local_cluster_type;
|
||||
typedef db::hier_clusters<db::NetShape> hier_clusters_type;
|
||||
typedef db::connected_clusters<db::NetShape> connected_clusters_type;
|
||||
typedef db::local_cluster<db::NetShape> local_cluster_type;
|
||||
|
||||
/**
|
||||
* @brief NetExtractor constructor
|
||||
|
|
|
|||
|
|
@ -353,23 +353,23 @@ template class region_to_edge_interaction_filter_base<db::Edge>;
|
|||
// -------------------------------------------------------------------------------------
|
||||
// RegionToTextInteractionFilterBase implementation
|
||||
|
||||
template <class OutputType>
|
||||
region_to_text_interaction_filter_base<OutputType>::region_to_text_interaction_filter_base (bool inverse)
|
||||
template <class OutputType, class TextType>
|
||||
region_to_text_interaction_filter_base<OutputType, TextType>::region_to_text_interaction_filter_base (bool inverse)
|
||||
: m_inverse (inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
template <class OutputType>
|
||||
template <class OutputType, class TextType>
|
||||
void
|
||||
region_to_text_interaction_filter_base<OutputType>::preset (const OutputType *s)
|
||||
region_to_text_interaction_filter_base<OutputType, TextType>::preset (const OutputType *s)
|
||||
{
|
||||
m_seen.insert (s);
|
||||
}
|
||||
|
||||
template <class OutputType>
|
||||
template <class OutputType, class TextType>
|
||||
void
|
||||
region_to_text_interaction_filter_base<OutputType>::add (const db::Polygon *p, size_t, const db::Text *t, size_t)
|
||||
region_to_text_interaction_filter_base<OutputType, TextType>::add (const db::Polygon *p, size_t, const TextType *t, size_t)
|
||||
{
|
||||
const OutputType *o = 0;
|
||||
tl::select (o, p, t);
|
||||
|
|
@ -378,8 +378,7 @@ region_to_text_interaction_filter_base<OutputType>::add (const db::Polygon *p, s
|
|||
|
||||
// A polygon and an text interact if the text is either inside completely
|
||||
// of at least one text of the polygon intersects with the text
|
||||
db::Point pt;
|
||||
pt += t->trans ().disp ();
|
||||
db::Point pt = db::box_convert<TextType> () (*t).p1 ();
|
||||
if (p->box ().contains (pt) && db::inside_poly (p->begin_edge (), pt) >= 0) {
|
||||
if (m_inverse) {
|
||||
m_seen.erase (o);
|
||||
|
|
@ -392,9 +391,9 @@ region_to_text_interaction_filter_base<OutputType>::add (const db::Polygon *p, s
|
|||
}
|
||||
}
|
||||
|
||||
template <class OutputType>
|
||||
template <class OutputType, class TextType>
|
||||
void
|
||||
region_to_text_interaction_filter_base<OutputType>::fill_output ()
|
||||
region_to_text_interaction_filter_base<OutputType, TextType>::fill_output ()
|
||||
{
|
||||
for (typename std::set<const OutputType *>::const_iterator s = m_seen.begin (); s != m_seen.end (); ++s) {
|
||||
put (**s);
|
||||
|
|
@ -402,8 +401,9 @@ region_to_text_interaction_filter_base<OutputType>::fill_output ()
|
|||
}
|
||||
|
||||
// explicit instantiations
|
||||
template class region_to_text_interaction_filter_base<db::Polygon>;
|
||||
template class region_to_text_interaction_filter_base<db::Text>;
|
||||
template class region_to_text_interaction_filter_base<db::Polygon, db::TextRef>;
|
||||
template class region_to_text_interaction_filter_base<db::Text, db::Text>;
|
||||
template class region_to_text_interaction_filter_base<db::TextRef, db::TextRef>;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
// Polygon snapping
|
||||
|
|
|
|||
|
|
@ -527,15 +527,15 @@ private:
|
|||
/**
|
||||
* @brief A helper class for the region to text interaction functionality
|
||||
*/
|
||||
template <class OutputType>
|
||||
template <class OutputType, class TextType>
|
||||
class DB_PUBLIC region_to_text_interaction_filter_base
|
||||
: public db::box_scanner_receiver2<db::Polygon, size_t, db::Text, size_t>
|
||||
: public db::box_scanner_receiver2<db::Polygon, size_t, TextType, size_t>
|
||||
{
|
||||
public:
|
||||
region_to_text_interaction_filter_base (bool inverse);
|
||||
|
||||
void preset (const OutputType *s);
|
||||
void add (const db::Polygon *p, size_t, const db::Text *e, size_t);
|
||||
void add (const db::Polygon *p, size_t, const TextType *e, size_t);
|
||||
void fill_output ();
|
||||
|
||||
protected:
|
||||
|
|
@ -549,13 +549,13 @@ private:
|
|||
/**
|
||||
* @brief A helper class for the region to text interaction functionality
|
||||
*/
|
||||
template <class OutputContainer, class OutputType = typename OutputContainer::value_type>
|
||||
template <class OutputContainer, class TextType, class OutputType = typename OutputContainer::value_type>
|
||||
class DB_PUBLIC_TEMPLATE region_to_text_interaction_filter
|
||||
: public region_to_text_interaction_filter_base<OutputType>
|
||||
: public region_to_text_interaction_filter_base<OutputType, TextType>
|
||||
{
|
||||
public:
|
||||
region_to_text_interaction_filter (OutputContainer &output, bool inverse)
|
||||
: region_to_text_interaction_filter_base<OutputType> (inverse), mp_output (&output)
|
||||
: region_to_text_interaction_filter_base<OutputType, TextType> (inverse), mp_output (&output)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,6 +176,15 @@ public:
|
|||
return m_text_repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the repository by tag
|
||||
*/
|
||||
template <class Sh>
|
||||
const db::repository<Sh> &repository (db::object_tag<Sh> tag) const
|
||||
{
|
||||
return const_cast<generic_repository<C> *> (this)->repository (tag);
|
||||
}
|
||||
|
||||
void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const
|
||||
{
|
||||
db::mem_stat (stat, purpose, cat, m_polygon_repository, no_self, parent);
|
||||
|
|
|
|||
|
|
@ -234,6 +234,20 @@ Shapes::swap (Shapes &d)
|
|||
m_layers.swap (d.m_layers);
|
||||
}
|
||||
|
||||
static
|
||||
Shapes::shape_type safe_insert_text (Shapes &shapes, const Shapes::shape_type &shape, tl::func_delegate_base <db::properties_id_type> &pm)
|
||||
{
|
||||
// for texts referring to a string repository we go the safe way and
|
||||
// simply instantiate and re-insert the text:
|
||||
Shapes::shape_type::text_type p;
|
||||
shape.text (p);
|
||||
if (! shape.has_prop_id ()) {
|
||||
return shapes.insert (p);
|
||||
} else {
|
||||
return shapes.insert (db::object_with_properties<Shapes::shape_type::text_type> (p, pm (shape.prop_id ())));
|
||||
}
|
||||
}
|
||||
|
||||
Shapes::shape_type
|
||||
Shapes::do_insert (const Shapes::shape_type &shape, const Shapes::unit_trans_type & /*t*/, tl::func_delegate_base <db::properties_id_type> &pm)
|
||||
{
|
||||
|
|
@ -352,19 +366,23 @@ Shapes::do_insert (const Shapes::shape_type &shape, const Shapes::unit_trans_typ
|
|||
case shape_type::ShortBoxArray:
|
||||
return (insert_by_tag (shape_type::short_box_array_type::tag (), shape, pm));
|
||||
case shape_type::Text:
|
||||
case shape_type::TextRef:
|
||||
case shape_type::TextPtrArrayMember:
|
||||
{
|
||||
// because texts can refer to a string repository we go the safe way and
|
||||
// simply instantiate and re-insert the text:
|
||||
shape_type::text_type p;
|
||||
shape.text (p);
|
||||
if (! shape.has_prop_id ()) {
|
||||
return insert (p);
|
||||
if (shape.text ().string_ref () != 0) {
|
||||
return safe_insert_text (*this, shape, pm);
|
||||
} else {
|
||||
return insert (db::object_with_properties<shape_type::text_type> (p, pm (shape.prop_id ())));
|
||||
return (insert_by_tag (shape_type::text_type::tag (), shape, pm));
|
||||
}
|
||||
}
|
||||
case shape_type::TextRef:
|
||||
{
|
||||
if (shape.text_ref ().obj ().string_ref () != 0) {
|
||||
return safe_insert_text (*this, shape, pm);
|
||||
} else {
|
||||
return (insert_by_tag (shape_type::text_ref_type::tag (), shape, pm));
|
||||
}
|
||||
}
|
||||
case shape_type::TextPtrArrayMember:
|
||||
return safe_insert_text (*this, shape, pm);
|
||||
case shape_type::TextPtrArray:
|
||||
tl_assert (layout () != 0); // cannot translate the array members
|
||||
return insert_array_by_tag (shape_type::text_ptr_array_type::tag (), shape, shape_repository (), pm);
|
||||
|
|
|
|||
|
|
@ -159,6 +159,9 @@ inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int
|
|||
class DB_PUBLIC StringRepository
|
||||
{
|
||||
public:
|
||||
typedef std::set<StringRef *> string_refs_type;
|
||||
typedef string_refs_type::const_iterator iterator;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
|
|
@ -216,6 +219,22 @@ public:
|
|||
return m_string_refs.size ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterates over the string refs (begin)
|
||||
*/
|
||||
iterator begin () const
|
||||
{
|
||||
return m_string_refs.begin ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterates over the string refs (end)
|
||||
*/
|
||||
iterator end () const
|
||||
{
|
||||
return m_string_refs.end ();
|
||||
}
|
||||
|
||||
void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const
|
||||
{
|
||||
if (! no_self) {
|
||||
|
|
@ -559,6 +578,21 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the StringRef object is there is one
|
||||
*
|
||||
* If the string is a plain text kept internally, this method returns 0.
|
||||
*/
|
||||
const StringRef *string_ref () const
|
||||
{
|
||||
size_t p = (size_t) mp_ptr;
|
||||
if (p & 1) {
|
||||
return reinterpret_cast<const StringRef *> (p - 1);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The transformation write accessor
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ private:
|
|||
};
|
||||
|
||||
/**
|
||||
* @brief A helper class for the text to region interaction functionality which acts as an text receiver
|
||||
* @brief A helper class for the text ref to region interaction functionality which acts as an text receiver
|
||||
*
|
||||
* Note: This special scanner uses pointers to two different objects: texts and polygons.
|
||||
* It uses odd value pointers to indicate pointers to polygons and even value pointers to indicate
|
||||
|
|
@ -161,9 +161,9 @@ private:
|
|||
*
|
||||
* There is a special box converter which is able to sort that out as well.
|
||||
*/
|
||||
template <class OutputContainer, class OutputType = typename OutputContainer::value_type>
|
||||
template <class OutputContainer, class TextType, class OutputType = typename OutputContainer::value_type>
|
||||
class text_to_region_interaction_filter
|
||||
: public db::box_scanner_receiver2<db::Text, size_t, db::Polygon, size_t>
|
||||
: public db::box_scanner_receiver2<TextType, size_t, db::Polygon, size_t>
|
||||
{
|
||||
public:
|
||||
text_to_region_interaction_filter (OutputContainer &output)
|
||||
|
|
@ -172,6 +172,19 @@ public:
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void add (const db::TextRef *t, size_t, const db::Polygon *p, size_t)
|
||||
{
|
||||
const OutputType *tt = 0;
|
||||
tl::select (tt, t, p);
|
||||
|
||||
if (m_seen.find (tt) == m_seen.end ()) {
|
||||
if (db::interact (*p, t->obj ().transformed (t->trans ()))) {
|
||||
m_seen.insert (tt);
|
||||
mp_output->insert (*tt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void add (const db::Text *t, size_t, const db::Polygon *p, size_t)
|
||||
{
|
||||
const OutputType *tt = 0;
|
||||
|
|
|
|||
|
|
@ -369,21 +369,21 @@ TEST(20_LocalClustersBasic)
|
|||
db::local_clusters<db::PolygonRef> clusters;
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn), "");
|
||||
|
||||
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
|
||||
clusters.build_clusters (cell, conn);
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn), "#1:[0](0,0;0,1000;1000,1000;1000,0)");
|
||||
|
||||
// one more shape
|
||||
cell.shapes (0).insert (db::PolygonRef (poly.transformed (db::Trans (db::Vector (10, 20))), repo));
|
||||
|
||||
clusters.clear ();
|
||||
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
|
||||
clusters.build_clusters (cell, conn);
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn), "#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20)");
|
||||
|
||||
// one more shape creating a new cluster
|
||||
cell.shapes (2).insert (db::PolygonRef (poly.transformed (db::Trans (db::Vector (0, 1100))), repo));
|
||||
|
||||
clusters.clear ();
|
||||
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
|
||||
clusters.build_clusters (cell, conn);
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn),
|
||||
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20)\n"
|
||||
"#2:[2](0,1100;0,2100;1000,2100;1000,1100)"
|
||||
|
|
@ -393,7 +393,7 @@ TEST(20_LocalClustersBasic)
|
|||
cell.shapes (2).insert (db::PolygonRef (poly.transformed (db::Trans (db::Vector (0, 1000))), repo));
|
||||
|
||||
clusters.clear ();
|
||||
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
|
||||
clusters.build_clusters (cell, conn);
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn),
|
||||
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20);[2](0,1000;0,2000;1000,2000;1000,1000);[2](0,1100;0,2100;1000,2100;1000,1100)"
|
||||
);
|
||||
|
|
@ -402,7 +402,7 @@ TEST(20_LocalClustersBasic)
|
|||
cell.shapes (1).insert (db::PolygonRef (poly.transformed (db::Trans (db::Vector (0, 1100))), repo));
|
||||
|
||||
clusters.clear ();
|
||||
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
|
||||
clusters.build_clusters (cell, conn);
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn),
|
||||
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20);[2](0,1000;0,2000;1000,2000;1000,1000);[2](0,1100;0,2100;1000,2100;1000,1100)\n"
|
||||
"#2:[1](0,1100;0,2100;1000,2100;1000,1100)"
|
||||
|
|
@ -430,21 +430,21 @@ TEST(21_LocalClustersBasicWithAttributes)
|
|||
db::local_clusters<db::PolygonRef> clusters;
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn), "");
|
||||
|
||||
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
|
||||
clusters.build_clusters (cell, conn);
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn), "#1:[0](0,0;0,1000;1000,1000;1000,0)");
|
||||
|
||||
// one more shape
|
||||
cell.shapes (0).insert (db::PolygonRefWithProperties (db::PolygonRef (poly.transformed (db::Trans (db::Vector (10, 20))), repo), 1));
|
||||
|
||||
clusters.clear ();
|
||||
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
|
||||
clusters.build_clusters (cell, conn);
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn), "#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20)%1");
|
||||
|
||||
// one more shape creating a new cluster
|
||||
cell.shapes (2).insert (db::PolygonRefWithProperties (db::PolygonRef (poly.transformed (db::Trans (db::Vector (0, 1100))), repo), 2));
|
||||
|
||||
clusters.clear ();
|
||||
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
|
||||
clusters.build_clusters (cell, conn);
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn),
|
||||
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20)%1\n"
|
||||
"#2:[2](0,1100;0,2100;1000,2100;1000,1100)%2"
|
||||
|
|
@ -454,7 +454,7 @@ TEST(21_LocalClustersBasicWithAttributes)
|
|||
cell.shapes (2).insert (db::PolygonRefWithProperties (db::PolygonRef (poly.transformed (db::Trans (db::Vector (0, 1000))), repo), 3));
|
||||
|
||||
clusters.clear ();
|
||||
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
|
||||
clusters.build_clusters (cell, conn);
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn),
|
||||
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20);[2](0,1000;0,2000;1000,2000;1000,1000);[2](0,1100;0,2100;1000,2100;1000,1100)%1%2%3"
|
||||
);
|
||||
|
|
@ -463,7 +463,7 @@ TEST(21_LocalClustersBasicWithAttributes)
|
|||
cell.shapes (1).insert (db::PolygonRefWithProperties (db::PolygonRef (poly.transformed (db::Trans (db::Vector (0, 1100))), repo), 4));
|
||||
|
||||
clusters.clear ();
|
||||
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
|
||||
clusters.build_clusters (cell, conn);
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn),
|
||||
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20);[2](0,1000;0,2000;1000,2000;1000,1000);[2](0,1100;0,2100;1000,2100;1000,1100)%1%2%3\n"
|
||||
"#2:[1](0,1100;0,2100;1000,2100;1000,1100)%4"
|
||||
|
|
@ -491,21 +491,21 @@ TEST(22_LocalClustersWithGlobal)
|
|||
db::local_clusters<db::PolygonRef> clusters;
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn), "");
|
||||
|
||||
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
|
||||
clusters.build_clusters (cell, conn);
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn), "#1:[0](0,0;0,1000;1000,1000;1000,0)");
|
||||
|
||||
// one more shape
|
||||
cell.shapes (0).insert (db::PolygonRefWithProperties (db::PolygonRef (poly.transformed (db::Trans (db::Vector (10, 20))), repo), 1));
|
||||
|
||||
clusters.clear ();
|
||||
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
|
||||
clusters.build_clusters (cell, conn);
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn), "#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20)%1");
|
||||
|
||||
// one more shape creating a new cluster
|
||||
cell.shapes (2).insert (db::PolygonRefWithProperties (db::PolygonRef (poly.transformed (db::Trans (db::Vector (0, 1100))), repo), 2));
|
||||
|
||||
clusters.clear ();
|
||||
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
|
||||
clusters.build_clusters (cell, conn);
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn),
|
||||
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20)%1\n"
|
||||
"#2:[2](0,1100;0,2100;1000,2100;1000,1100)%2"
|
||||
|
|
@ -514,7 +514,7 @@ TEST(22_LocalClustersWithGlobal)
|
|||
conn.connect_global (0, "GLOBAL");
|
||||
|
||||
clusters.clear ();
|
||||
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
|
||||
clusters.build_clusters (cell, conn);
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn),
|
||||
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20)%1+GLOBAL\n"
|
||||
"#2:[2](0,1100;0,2100;1000,2100;1000,1100)%2"
|
||||
|
|
@ -523,7 +523,7 @@ TEST(22_LocalClustersWithGlobal)
|
|||
conn.connect_global (2, "GLOBAL2");
|
||||
|
||||
clusters.clear ();
|
||||
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
|
||||
clusters.build_clusters (cell, conn);
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn),
|
||||
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20)%1+GLOBAL\n"
|
||||
"#2:[2](0,1100;0,2100;1000,2100;1000,1100)%2+GLOBAL2"
|
||||
|
|
@ -533,7 +533,7 @@ TEST(22_LocalClustersWithGlobal)
|
|||
|
||||
// now, GLOBAL2 will connect these clusters
|
||||
clusters.clear ();
|
||||
clusters.build_clusters (cell, db::ShapeIterator::Polygons, conn);
|
||||
clusters.build_clusters (cell, conn);
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn),
|
||||
"#1:[0](0,0;0,1000;1000,1000;1000,0);[0](10,20;10,1020;1010,1020;1010,20);[2](0,1100;0,2100;1000,2100;1000,1100)%1%2+GLOBAL+GLOBAL2"
|
||||
);
|
||||
|
|
@ -570,7 +570,7 @@ TEST(23_LocalClustersWithEdges)
|
|||
conn.connect (0);
|
||||
|
||||
db::local_clusters<db::Edge> clusters;
|
||||
clusters.build_clusters (cell, db::ShapeIterator::Edges, conn);
|
||||
clusters.build_clusters (cell, conn);
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn),
|
||||
"#1:[0](0,0;0,500);[0](0,500;0,1000)\n"
|
||||
"#2:[0](2000,500;1000,250);[0](1500,375;0,0)\n"
|
||||
|
|
@ -585,7 +585,7 @@ TEST(23_LocalClustersWithEdges)
|
|||
conn.connect (0);
|
||||
|
||||
db::local_clusters<db::Edge> clusters;
|
||||
clusters.build_clusters (cell, db::ShapeIterator::Edges, conn);
|
||||
clusters.build_clusters (cell, conn);
|
||||
EXPECT_EQ (local_clusters_to_string (clusters, conn), "#1:[0](0,0;0,500);[0](0,500;0,1000);[0](1500,375;0,0);[0](0,1000;2000,1000);[0](2000,1000;2000,500);[0](2000,500;1000,250)");
|
||||
}
|
||||
}
|
||||
|
|
@ -700,7 +700,7 @@ TEST(40_HierClustersBasic)
|
|||
db::Connectivity conn;
|
||||
conn.connect (l1, l1);
|
||||
|
||||
hc.build (ly, top, db::ShapeIterator::Polygons, conn);
|
||||
hc.build (ly, top, conn);
|
||||
|
||||
int n, nc;
|
||||
const db::connected_clusters<db::PolygonRef> *cluster;
|
||||
|
|
@ -815,7 +815,7 @@ TEST(41_HierClustersRecursiveClusterShapeIterator)
|
|||
db::Connectivity conn;
|
||||
conn.connect (l1, l1);
|
||||
|
||||
hc.build (ly, top, db::ShapeIterator::Polygons, conn);
|
||||
hc.build (ly, top, conn);
|
||||
|
||||
std::string res;
|
||||
int n = 0;
|
||||
|
|
@ -860,7 +860,7 @@ TEST(41_HierClustersRecursiveClusterIterator)
|
|||
db::Connectivity conn;
|
||||
conn.connect (l1, l1);
|
||||
|
||||
hc.build (ly, top, db::ShapeIterator::Polygons, conn);
|
||||
hc.build (ly, top, conn);
|
||||
|
||||
std::string res;
|
||||
int n = 0;
|
||||
|
|
@ -1020,7 +1020,7 @@ static void run_hc_test (tl::TestBase *_this, const std::string &file, const std
|
|||
conn.connect_global (l6, "BULK2");
|
||||
|
||||
db::hier_clusters<db::PolygonRef> hc;
|
||||
hc.build (ly, ly.cell (*ly.begin_top_down ()), db::ShapeIterator::Polygons, conn);
|
||||
hc.build (ly, ly.cell (*ly.begin_top_down ()), conn);
|
||||
|
||||
std::vector<std::pair<db::Polygon::area_type, unsigned int> > net_layers;
|
||||
|
||||
|
|
@ -1153,7 +1153,7 @@ static void run_hc_test_with_backannotation (tl::TestBase *_this, const std::str
|
|||
conn.connect_global (l6, "BULK2");
|
||||
|
||||
db::hier_clusters<db::PolygonRef> hc;
|
||||
hc.build (ly, ly.cell (*ly.begin_top_down ()), db::ShapeIterator::Polygons, conn);
|
||||
hc.build (ly, ly.cell (*ly.begin_top_down ()), conn);
|
||||
|
||||
std::map<unsigned int, unsigned int> lm;
|
||||
lm[l1] = ly.insert_layer (db::LayerProperties (101, 0));
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ static void dump_recursive_nets_to_layout (const db::LayoutToNetlist &l2n, db::L
|
|||
|
||||
bool any = false;
|
||||
for (std::map<const db::Region *, unsigned int>::const_iterator m = lmap.begin (); m != lmap.end () && !any; ++m) {
|
||||
any = !db::recursive_cluster_shape_iterator<db::PolygonRef> (l2n.net_clusters (), l2n.layer_of (*m->first), c->cell_index (), n->cluster_id ()).at_end ();
|
||||
any = !db::recursive_cluster_shape_iterator<db::NetShape> (l2n.net_clusters (), l2n.layer_of (*m->first), c->cell_index (), n->cluster_id ()).at_end ();
|
||||
}
|
||||
|
||||
if (!any) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,187 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "dbNetShape.h"
|
||||
#include "dbShapes.h"
|
||||
#include "tlUnitTest.h"
|
||||
|
||||
|
||||
TEST(1)
|
||||
{
|
||||
db::GenericRepository repo;
|
||||
|
||||
db::NetShape s;
|
||||
EXPECT_EQ (s.type () == db::NetShape::None, true);
|
||||
EXPECT_EQ (s.bbox ().to_string (), "()");
|
||||
|
||||
db::Polygon p (db::Box (0, 0, 100, 200));
|
||||
s = db::NetShape (p, repo);
|
||||
EXPECT_EQ (s.type () == db::NetShape::Polygon, true);
|
||||
EXPECT_EQ (s.bbox ().to_string (), "(0,0;100,200)");
|
||||
EXPECT_EQ (s.polygon_ref ().obj ().to_string (), "(0,0;0,200;100,200;100,0)");
|
||||
EXPECT_EQ (db::NetShape (s.polygon_ref ()).type () == db::NetShape::Polygon, true);
|
||||
EXPECT_EQ (db::NetShape (s.polygon_ref ()).polygon_ref ().obj ().to_string (), "(0,0;0,200;100,200;100,0)");
|
||||
|
||||
db::Text t ("abc", db::Trans (db::Vector (100, 200)));
|
||||
s = db::NetShape (t, repo);
|
||||
EXPECT_EQ (s.type () == db::NetShape::Text, true);
|
||||
EXPECT_EQ (s.bbox ().to_string (), "(100,200;100,200)");
|
||||
EXPECT_EQ (s.text_ref ().obj ().to_string (), "('abc',r0 0,0)");
|
||||
EXPECT_EQ (db::NetShape (s.text_ref ()).type () == db::NetShape::Text, true);
|
||||
EXPECT_EQ (db::NetShape (s.text_ref ()).text_ref ().obj ().to_string (), "('abc',r0 0,0)");
|
||||
}
|
||||
|
||||
TEST(2)
|
||||
{
|
||||
db::GenericRepository repo;
|
||||
|
||||
db::NetShape s;
|
||||
EXPECT_EQ (s.type () == db::NetShape::None, true);
|
||||
EXPECT_EQ (s.bbox ().to_string (), "()");
|
||||
|
||||
db::Polygon p (db::Box (0, 0, 100, 200));
|
||||
s = db::NetShape (p, repo);
|
||||
EXPECT_EQ (s.polygon_ref ().obj ().to_string (), "(0,0;0,200;100,200;100,0)");
|
||||
|
||||
s.transform (db::Disp (db::Vector (10, 20)));
|
||||
EXPECT_EQ (s.bbox ().to_string (), "(10,20;110,220)");
|
||||
|
||||
db::Text t ("abc", db::Trans (db::Vector (100, 200)));
|
||||
s = db::NetShape (t, repo);
|
||||
EXPECT_EQ (s.text_ref ().obj ().to_string (), "('abc',r0 0,0)");
|
||||
|
||||
s.transform (db::Disp (db::Vector (10, 20)));
|
||||
EXPECT_EQ (s.text_ref ().obj ().transformed (s.text_ref ().trans ()).to_string (), "('abc',r0 110,220)");
|
||||
}
|
||||
|
||||
TEST(3)
|
||||
{
|
||||
db::GenericRepository repo;
|
||||
|
||||
db::NetShape s, s2;
|
||||
EXPECT_EQ (s == db::NetShape (), true);
|
||||
EXPECT_EQ (s != db::NetShape (), false);
|
||||
EXPECT_EQ (s < db::NetShape (), false);
|
||||
|
||||
db::Polygon p (db::Box (0, 0, 100, 200));
|
||||
s = db::NetShape (p, repo);
|
||||
s2 = s;
|
||||
EXPECT_EQ (s == db::NetShape (), false);
|
||||
EXPECT_EQ (s != db::NetShape (), true);
|
||||
EXPECT_EQ (s < db::NetShape (), false);
|
||||
EXPECT_EQ (s == s2, true);
|
||||
EXPECT_EQ (s != s2, false);
|
||||
EXPECT_EQ (s < s2, false);
|
||||
EXPECT_EQ (s2 < s, false);
|
||||
s.transform (db::Disp (db::Vector (10, 20)));
|
||||
EXPECT_EQ (s == s2, false);
|
||||
EXPECT_EQ (s != s2, true);
|
||||
EXPECT_EQ (s < s2, false);
|
||||
EXPECT_EQ (s2 < s, true);
|
||||
|
||||
db::Text t ("abc", db::Trans (db::Vector (100, 200)));
|
||||
s = db::NetShape (t, repo);
|
||||
EXPECT_EQ (s == s2, false);
|
||||
EXPECT_EQ (s != s2, true);
|
||||
EXPECT_EQ (s < s2, true);
|
||||
EXPECT_EQ (s2 < s, false);
|
||||
|
||||
s2 = s;
|
||||
EXPECT_EQ (s == db::NetShape (), false);
|
||||
EXPECT_EQ (s != db::NetShape (), true);
|
||||
EXPECT_EQ (s < db::NetShape (), false);
|
||||
EXPECT_EQ (s == s2, true);
|
||||
EXPECT_EQ (s != s2, false);
|
||||
EXPECT_EQ (s < s2, false);
|
||||
EXPECT_EQ (s2 < s, false);
|
||||
s.transform (db::Disp (db::Vector (10, 20)));
|
||||
EXPECT_EQ (s == s2, false);
|
||||
EXPECT_EQ (s != s2, true);
|
||||
EXPECT_EQ (s < s2, false);
|
||||
EXPECT_EQ (s2 < s, true);
|
||||
}
|
||||
|
||||
TEST(4)
|
||||
{
|
||||
db::GenericRepository repo;
|
||||
|
||||
db::NetShape s;
|
||||
EXPECT_EQ (s.type () == db::NetShape::None, true);
|
||||
EXPECT_EQ (s.bbox ().to_string (), "()");
|
||||
|
||||
db::Polygon p (db::Box (0, 0, 100, 200));
|
||||
s = db::NetShape (p, repo);
|
||||
|
||||
db::Shapes shapes;
|
||||
s.insert_into (shapes);
|
||||
|
||||
db::Text t ("abc", db::Trans (db::Vector (100, 200)));
|
||||
s = db::NetShape (t, repo);
|
||||
s.insert_into (shapes);
|
||||
|
||||
db::ShapeIterator si = shapes.begin (db::ShapeIterator::All);
|
||||
EXPECT_EQ (si->to_string (), "polygon (0,0;0,200;100,200;100,0)");
|
||||
++si;
|
||||
EXPECT_NE (si.at_end (), true);
|
||||
EXPECT_EQ (si->to_string (), "text ('abc',r0 100,200)");
|
||||
++si;
|
||||
EXPECT_EQ (si.at_end (), true);
|
||||
}
|
||||
|
||||
TEST(5)
|
||||
{
|
||||
db::GenericRepository repo;
|
||||
|
||||
db::NetShape sp1 (db::Polygon (db::Box (10, 20, 100, 200)), repo);
|
||||
db::NetShape sp2 (db::Polygon (db::Box (80, 20, 180, 200)), repo);
|
||||
db::NetShape sp3 (db::Polygon (db::Box (10, 320, 100, 500)), repo);
|
||||
|
||||
db::NetShape st1 (db::Text ("abc", db::Trans (db::Vector (0, 0))), repo);
|
||||
db::NetShape st2 (db::Text ("xyz", db::Trans (db::Vector (50, 60))), repo);
|
||||
|
||||
EXPECT_EQ (sp1.interacts_with (db::NetShape ()), false);
|
||||
EXPECT_EQ (sp1.interacts_with_transformed (db::NetShape (), db::Trans (db::Vector (1000, 0))), false);
|
||||
EXPECT_EQ (sp1.interacts_with (sp1), true);
|
||||
EXPECT_EQ (sp1.interacts_with_transformed (sp1, db::Trans (db::Vector (1000, 0))), false);
|
||||
EXPECT_EQ (sp1.interacts_with (sp2), true);
|
||||
EXPECT_EQ (sp2.interacts_with (sp1), true);
|
||||
EXPECT_EQ (sp1.interacts_with (sp3), false);
|
||||
EXPECT_EQ (sp1.interacts_with_transformed (sp3, db::Trans (db::Vector (50, -200))), true);
|
||||
EXPECT_EQ (sp3.interacts_with (sp1), false);
|
||||
EXPECT_EQ (sp3.interacts_with_transformed (sp1, db::Trans (db::Vector (50, 200))), true);
|
||||
|
||||
EXPECT_EQ (sp1.interacts_with (st1), false);
|
||||
EXPECT_EQ (sp1.interacts_with_transformed (st1, db::Trans (db::Vector (10, 20))), true);
|
||||
EXPECT_EQ (sp1.interacts_with_transformed (st1, db::Trans (db::Vector (5, 20))), false);
|
||||
EXPECT_EQ (sp1.interacts_with (st2), true);
|
||||
|
||||
EXPECT_EQ (st1.interacts_with (sp1), false);
|
||||
EXPECT_EQ (st1.interacts_with_transformed (sp1, db::Trans (db::Vector (-10, -20))), true);
|
||||
EXPECT_EQ (st1.interacts_with_transformed (sp1, db::Trans (db::Vector (-5, -20))), false);
|
||||
EXPECT_EQ (st2.interacts_with (sp1), true);
|
||||
|
||||
EXPECT_EQ (st1.interacts_with (st1), true);
|
||||
EXPECT_EQ (st1.interacts_with_transformed (st1, db::Trans (db::Vector (-5, -20))), false);
|
||||
EXPECT_EQ (st2.interacts_with (st1), false);
|
||||
EXPECT_EQ (st2.interacts_with_transformed (st1, db::Trans (db::Vector (50, 60))), true);
|
||||
}
|
||||
|
|
@ -123,7 +123,7 @@ TEST(10_MOS3DeviceExtractorTest)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS3Transistor ex ("MOS3");
|
||||
|
||||
|
|
@ -179,7 +179,7 @@ TEST(11_MOS3DeviceExtractorTestNotRectangularGate)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS3Transistor ex ("MOS3");
|
||||
|
||||
|
|
@ -235,7 +235,7 @@ TEST(12_MOS3DeviceExtractorTestCircular)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS3Transistor ex ("MOS3");
|
||||
|
||||
|
|
@ -293,7 +293,7 @@ TEST(20_MOS4DeviceExtractorTest)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS4Transistor ex ("MOS4");
|
||||
|
||||
|
|
@ -354,7 +354,7 @@ TEST(21_MOS4DeviceExtractorTestNotRectangularGate)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS4Transistor ex ("MOS4");
|
||||
|
||||
|
|
@ -415,7 +415,7 @@ TEST(22_MOS4DeviceExtractorTestCircular)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS4Transistor ex ("MOS4");
|
||||
|
||||
|
|
@ -475,7 +475,7 @@ TEST(30_DMOS3DeviceExtractorTest)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS3Transistor ex ("DMOS3", true);
|
||||
|
||||
|
|
@ -533,7 +533,7 @@ TEST(31_DMOS3DeviceExtractorTestNotRectangularGate)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS3Transistor ex ("DMOS3", true);
|
||||
|
||||
|
|
@ -591,7 +591,7 @@ TEST(32_DMOS3DeviceExtractorTestCircular)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS3Transistor ex ("DMOS3", true);
|
||||
|
||||
|
|
@ -651,7 +651,7 @@ TEST(40_DMOS4DeviceExtractorTest)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS4Transistor ex ("DMOS4", true);
|
||||
|
||||
|
|
@ -714,7 +714,7 @@ TEST(41_DMOS4DeviceExtractorTestNotRectangularGate)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS4Transistor ex ("DMOS4", true);
|
||||
|
||||
|
|
@ -777,7 +777,7 @@ TEST(42_DMOS4DeviceExtractorTestCircular)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS4Transistor ex ("DMOS4", true);
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ static unsigned int define_layer (db::Layout &ly, db::LayerMap &lmap, int gds_la
|
|||
return lid;
|
||||
}
|
||||
|
||||
static void dump_nets_to_layout (const db::Netlist &nl, const db::hier_clusters<db::PolygonRef> &clusters, db::Layout &ly, const std::map<unsigned int, unsigned int> &lmap, const db::CellMapping &cmap, bool with_device_cells = false)
|
||||
static void dump_nets_to_layout (const db::Netlist &nl, const db::hier_clusters<db::NetShape> &clusters, db::Layout &ly, const std::map<unsigned int, unsigned int> &lmap, const db::CellMapping &cmap, bool with_device_cells = false)
|
||||
{
|
||||
std::set<db::cell_index_type> device_cells_seen;
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ static void dump_nets_to_layout (const db::Netlist &nl, const db::hier_clusters<
|
|||
|
||||
for (db::Circuit::const_net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) {
|
||||
|
||||
const db::local_cluster<db::PolygonRef> &lc = clusters.clusters_per_cell (c->cell_index ()).cluster_by_id (n->cluster_id ());
|
||||
const db::local_cluster<db::NetShape> &lc = clusters.clusters_per_cell (c->cell_index ()).cluster_by_id (n->cluster_id ());
|
||||
|
||||
bool any_shapes = false;
|
||||
for (std::map<unsigned int, unsigned int>::const_iterator m = lmap.begin (); m != lmap.end () && !any_shapes; ++m) {
|
||||
|
|
@ -84,8 +84,8 @@ static void dump_nets_to_layout (const db::Netlist &nl, const db::hier_clusters<
|
|||
|
||||
for (std::map<unsigned int, unsigned int>::const_iterator m = lmap.begin (); m != lmap.end (); ++m) {
|
||||
db::Shapes &target = net_cell.shapes (m->second);
|
||||
for (db::local_cluster<db::PolygonRef>::shape_iterator s = lc.begin (m->first); !s.at_end (); ++s) {
|
||||
target.insert (*s);
|
||||
for (db::local_cluster<db::NetShape>::shape_iterator s = lc.begin (m->first); !s.at_end (); ++s) {
|
||||
s->insert_into (target);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -137,12 +137,12 @@ static void dump_nets_to_layout (const db::Netlist &nl, const db::hier_clusters<
|
|||
const std::vector<db::DeviceTerminalDefinition> &td = d->device_class ()->terminal_definitions ();
|
||||
for (std::vector<db::DeviceTerminalDefinition>::const_iterator t = td.begin (); t != td.end (); ++t) {
|
||||
|
||||
const db::local_cluster<db::PolygonRef> &dc = clusters.clusters_per_cell (dci).cluster_by_id (d->device_abstract ()->cluster_id_for_terminal (t->id ()));
|
||||
const db::local_cluster<db::NetShape> &dc = clusters.clusters_per_cell (dci).cluster_by_id (d->device_abstract ()->cluster_id_for_terminal (t->id ()));
|
||||
|
||||
for (std::map<unsigned int, unsigned int>::const_iterator m = lmap.begin (); m != lmap.end (); ++m) {
|
||||
db::Shapes &target = device_cell.shapes (m->second);
|
||||
for (db::local_cluster<db::PolygonRef>::shape_iterator s = dc.begin (m->first); !s.at_end (); ++s) {
|
||||
target.insert (*s);
|
||||
for (db::local_cluster<db::NetShape>::shape_iterator s = dc.begin (m->first); !s.at_end (); ++s) {
|
||||
s->insert_into (target);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -233,7 +233,7 @@ TEST(1_DeviceAndNetExtraction)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS");
|
||||
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS");
|
||||
|
|
@ -452,7 +452,7 @@ TEST(2_DeviceAndNetExtractionFlat)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS");
|
||||
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS");
|
||||
|
|
@ -686,7 +686,7 @@ TEST(3_DeviceAndNetExtractionWithImplicitConnections)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS");
|
||||
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS");
|
||||
|
|
@ -935,7 +935,7 @@ TEST(4_ResAndCapExtraction)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS");
|
||||
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS");
|
||||
|
|
@ -1182,7 +1182,7 @@ TEST(5_ResAndCapWithBulkExtraction)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS4Transistor pmos_ex ("PMOS");
|
||||
db::NetlistDeviceExtractorMOS4Transistor nmos_ex ("NMOS");
|
||||
|
|
@ -1449,7 +1449,7 @@ TEST(6_BJT3TransistorExtraction)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS4Transistor pmos_ex ("PMOS");
|
||||
db::NetlistDeviceExtractorMOS4Transistor nmos_ex ("NMOS");
|
||||
|
|
@ -1656,7 +1656,7 @@ TEST(7_DiodeExtraction)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorDiode diode_ex ("DIODE");
|
||||
|
||||
|
|
@ -1790,7 +1790,7 @@ TEST(8_DiodeExtractionScaled)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorDiode diode_ex ("DIODE");
|
||||
|
||||
|
|
@ -1951,7 +1951,7 @@ TEST(9_StrictDeviceExtraction)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS", true /*strict*/);
|
||||
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS", true /*strict*/);
|
||||
|
|
@ -2184,7 +2184,7 @@ TEST(10_DeviceExtractionWithBreakoutCells)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS");
|
||||
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS");
|
||||
|
|
@ -2352,7 +2352,7 @@ TEST(11_DeviceExtractionWithSameClass)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorResistor polyres_ex ("RES", 50.0);
|
||||
db::NetlistDeviceExtractorResistor diffres_ex ("RES", 150.0);
|
||||
|
|
@ -2474,7 +2474,7 @@ TEST(12_FloatingSubcircuitExtraction)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS");
|
||||
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS");
|
||||
|
|
@ -2628,7 +2628,7 @@ TEST(13_RemoveDummyPins)
|
|||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
db::hier_clusters<db::NetShape> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS");
|
||||
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS");
|
||||
|
|
|
|||
|
|
@ -75,7 +75,8 @@ SOURCES = \
|
|||
dbBoxScannerTests.cc \
|
||||
dbBoxTests.cc \
|
||||
dbArrayTests.cc \
|
||||
dbDeepTextsTests.cc
|
||||
dbDeepTextsTests.cc \
|
||||
dbNetShapeTests.cc
|
||||
|
||||
INCLUDEPATH += $$TL_INC $$DB_INC $$GSI_INC
|
||||
DEPENDPATH += $$TL_INC $$DB_INC $$GSI_INC
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ size_t count_shapes (db::LayoutToNetlist *l2ndb, db::Net *net, unsigned int laye
|
|||
size_t cluster_id = net->cluster_id ();
|
||||
|
||||
size_t n = 0;
|
||||
for (db::recursive_cluster_shape_iterator<db::PolygonRef> shapes (l2ndb->net_clusters (), layer, cell_index, cluster_id); ! shapes.at_end (); ++shapes) {
|
||||
for (db::recursive_cluster_shape_iterator<db::NetShape> shapes (l2ndb->net_clusters (), layer, cell_index, cluster_id); ! shapes.at_end (); ++shapes) {
|
||||
++n;
|
||||
}
|
||||
return n;
|
||||
|
|
@ -278,7 +278,11 @@ void NetInfoDialog::update_info_text ()
|
|||
|
||||
std::string l = layer_string (mp_l2ndb.get (), *layer);
|
||||
|
||||
for (db::recursive_cluster_shape_iterator<db::PolygonRef> si (mp_l2ndb->net_clusters (), *layer, cell_index, cluster_id); ! si.at_end (); ++si) {
|
||||
for (db::recursive_cluster_shape_iterator<db::NetShape> si (mp_l2ndb->net_clusters (), *layer, cell_index, cluster_id); ! si.at_end (); ++si) {
|
||||
|
||||
if (si->type () != db::NetShape::Polygon) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tot_shapes++ >= max_shapes) {
|
||||
incomplete = true;
|
||||
|
|
@ -295,7 +299,7 @@ void NetInfoDialog::update_info_text ()
|
|||
statinfo_area.insert (std::make_pair (*layer, db::coord_traits<db::Coord>::area_type (0)));
|
||||
}
|
||||
|
||||
s->second.push_back (si->instantiate ());
|
||||
s->second.push_back (si->polygon_ref ().instantiate ());
|
||||
|
||||
std::string c (ly->cell_name (si.cell_index ()));
|
||||
c += " (with ";
|
||||
|
|
|
|||
|
|
@ -987,9 +987,9 @@ NetlistBrowserPage::adjust_view ()
|
|||
for (db::Connectivity::layer_iterator layer = conn.begin_layers (); layer != conn.end_layers (); ++layer) {
|
||||
|
||||
db::Box layer_bbox;
|
||||
db::recursive_cluster_shape_iterator<db::PolygonRef> shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id);
|
||||
db::recursive_cluster_shape_iterator<db::NetShape> shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id);
|
||||
while (! shapes.at_end ()) {
|
||||
layer_bbox += shapes.trans () * shapes->box ();
|
||||
layer_bbox += shapes->bbox ();
|
||||
++shapes;
|
||||
}
|
||||
|
||||
|
|
@ -1187,15 +1187,19 @@ NetlistBrowserPage::produce_highlights_for_net (const db::Net *net, size_t &n_ma
|
|||
db::LayerProperties lp = layout->get_properties (*layer);
|
||||
std::map<db::LayerProperties, lay::LayerPropertiesConstIterator>::const_iterator display = display_by_lp.find (lp);
|
||||
|
||||
db::recursive_cluster_shape_iterator<db::PolygonRef> shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id);
|
||||
db::recursive_cluster_shape_iterator<db::NetShape> shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id);
|
||||
while (! shapes.at_end ()) {
|
||||
|
||||
if (shapes->type () != db::NetShape::Polygon) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n_markers == m_max_shape_count) {
|
||||
return true;
|
||||
}
|
||||
|
||||
mp_markers.push_back (new lay::Marker (mp_view, m_cv_index));
|
||||
mp_markers.back ()->set (*shapes, net_trans * shapes.trans (), tv);
|
||||
mp_markers.back ()->set (shapes->polygon_ref (), net_trans * shapes.trans (), tv);
|
||||
|
||||
if (net_color.isValid ()) {
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue