mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
a983603dbc
commit
422c88207c
|
|
@ -23,6 +23,7 @@ SOURCES = \
|
|||
dbCommonReader.cc \
|
||||
dbCompoundOperation.cc \
|
||||
dbEdge.cc \
|
||||
dbEdgeNeighborhood.cc \
|
||||
dbEdgePair.cc \
|
||||
dbEdgePairFilters.cc \
|
||||
dbEdgePairRelations.cc \
|
||||
|
|
@ -119,6 +120,7 @@ SOURCES = \
|
|||
gsiDeclDbCommonStreamOptions.cc \
|
||||
gsiDeclDbCompoundOperation.cc \
|
||||
gsiDeclDbEdge.cc \
|
||||
gsiDeclDbEdgeNeighborhood.cc \
|
||||
gsiDeclDbEdgePair.cc \
|
||||
gsiDeclDbEdgePairs.cc \
|
||||
gsiDeclDbEdgeProcessor.cc \
|
||||
|
|
@ -249,6 +251,7 @@ HEADERS = \
|
|||
dbCommonReader.h \
|
||||
dbCompoundOperation.h \
|
||||
dbEdge.h \
|
||||
dbEdgeNeighborhood.h \
|
||||
dbEdgePair.h \
|
||||
dbEdgePairFilters.h \
|
||||
dbEdgePairRelations.h \
|
||||
|
|
|
|||
|
|
@ -266,6 +266,7 @@ protected:
|
|||
virtual db::Coord computed_dist () const = 0;
|
||||
|
||||
virtual std::string generated_description () const;
|
||||
virtual bool wants_caching () const { return true; }
|
||||
|
||||
private:
|
||||
std::string m_description;
|
||||
|
|
@ -276,23 +277,32 @@ private:
|
|||
{
|
||||
// TODO: confine caching to those nodes which need it.
|
||||
|
||||
std::pair<bool, std::vector<std::unordered_set<TR> > *> cp = cache->get<TR> (this);
|
||||
if (wants_caching ()) {
|
||||
|
||||
if (! cp.first) {
|
||||
std::pair<bool, std::vector<std::unordered_set<TR> > *> cp = cache->get<TR> (this);
|
||||
|
||||
std::vector<std::unordered_set<TR> > uncached_results;
|
||||
uncached_results.resize (results.size ());
|
||||
if (! cp.first) {
|
||||
|
||||
do_compute_local (cache, layout, cell, interactions, uncached_results, proc);
|
||||
std::vector<std::unordered_set<TR> > uncached_results;
|
||||
uncached_results.resize (results.size ());
|
||||
|
||||
cp.second->swap (uncached_results);
|
||||
do_compute_local (cache, layout, cell, interactions, uncached_results, proc);
|
||||
|
||||
cp.second->swap (uncached_results);
|
||||
|
||||
}
|
||||
|
||||
tl_assert (results.size () == cp.second->size ());
|
||||
for (size_t r = 0; r < results.size (); ++r) {
|
||||
results[r].insert ((*cp.second)[r].begin (), (*cp.second)[r].end ());
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
do_compute_local (cache, layout, cell, interactions, results, proc);
|
||||
|
||||
}
|
||||
|
||||
tl_assert (results.size () == cp.second->size ());
|
||||
for (size_t r = 0; r < results.size (); ++r) {
|
||||
results[r].insert ((*cp.second)[r].begin (), (*cp.second)[r].end ());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,107 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2024 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 "dbEdgeNeighborhood.h"
|
||||
#include "dbBoxScanner.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
EdgeNeighborhoodCompoundOperationNode::EdgeNeighborhoodCompoundOperationNode (const std::vector<CompoundRegionOperationNode *> &children, EdgeNeighborhoodVisitor *visitor, db::Coord bext, db::Coord eext, db::Coord din, db::Coord dout)
|
||||
: CompoundRegionMultiInputOperationNode (children), m_bext (bext), m_eext (eext), m_din (din), m_dout (dout), mp_visitor (visitor)
|
||||
{
|
||||
tl_assert (visitor != 0);
|
||||
visitor->keep ();
|
||||
}
|
||||
|
||||
db::Coord
|
||||
EdgeNeighborhoodCompoundOperationNode::computed_dist () const
|
||||
{
|
||||
return std::max (std::max (m_bext, m_eext), std::max (m_din, m_dout));
|
||||
}
|
||||
|
||||
std::string
|
||||
EdgeNeighborhoodCompoundOperationNode::generated_description () const
|
||||
{
|
||||
return tl::to_string (tr ("Neighborhood collector"));
|
||||
}
|
||||
|
||||
void
|
||||
EdgeNeighborhoodCompoundOperationNode::do_collect_neighbors (db::box_scanner2<db::Edge, unsigned int, db::Polygon, unsigned int> &scanner, const db::Layout *layout, const db::Cell *cell) const
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
EdgeNeighborhoodCompoundOperationNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *layout, db::Cell *cell, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > & /*results*/, const db::LocalProcessorBase * /*proc*/) const
|
||||
{
|
||||
tl_assert (interactions.num_subjects () == 1);
|
||||
|
||||
db::box_scanner2<db::Edge, unsigned int, db::Polygon, unsigned int> scanner;
|
||||
|
||||
std::list<db::Edge> edges;
|
||||
std::list<db::Polygon> polygons;
|
||||
|
||||
for (auto i = interactions.begin_intruders (); i != interactions.end_intruders (); ++i) {
|
||||
db::PolygonRef pr (i->second.second);
|
||||
polygons.push_back (pr.instantiate ());
|
||||
scanner.insert2 (&polygons.back (), i->second.first);
|
||||
}
|
||||
|
||||
const db::PolygonRef &pr = interactions.begin_subjects ()->second;
|
||||
unsigned int ie = 0;
|
||||
for (auto e = pr.begin_edge (); ! e.at_end (); ++e, ++ie) {
|
||||
edges.push_back (*e);
|
||||
scanner.insert1 (&edges.back (), ie);
|
||||
}
|
||||
|
||||
do_collect_neighbors (scanner, layout, cell);
|
||||
}
|
||||
|
||||
void
|
||||
EdgeNeighborhoodCompoundOperationNode::do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout *layout, db::Cell *cell, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > & /*results*/, const db::LocalProcessorBase * /*proc*/) const
|
||||
{
|
||||
tl_assert (interactions.num_subjects () == 1);
|
||||
|
||||
db::box_scanner2<db::Edge, unsigned int, db::Polygon, unsigned int> scanner;
|
||||
|
||||
std::list<db::Edge> edges;
|
||||
std::list<db::Polygon> polygons;
|
||||
|
||||
for (auto i = interactions.begin_intruders (); i != interactions.end_intruders (); ++i) {
|
||||
polygons.push_back (i->second.second);
|
||||
scanner.insert2 (&polygons.back (), i->second.first);
|
||||
}
|
||||
|
||||
const db::Polygon &pr = interactions.begin_subjects ()->second;
|
||||
unsigned int ie = 0;
|
||||
for (auto e = pr.begin_edge (); ! e.at_end (); ++e, ++ie) {
|
||||
edges.push_back (*e);
|
||||
scanner.insert1 (&edges.back (), ie);
|
||||
}
|
||||
|
||||
do_collect_neighbors (scanner, layout, cell);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2024 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_dbEdgeNeighborhood
|
||||
#define HDR_dbEdgeNeighborhood
|
||||
|
||||
#include "dbCommon.h"
|
||||
#include "dbCompoundOperation.h"
|
||||
#include "dbBoxScanner.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief A visitor for the neighbors of an edge
|
||||
*/
|
||||
class DB_PUBLIC EdgeNeighborhoodVisitor
|
||||
: public gsi::ObjectBase, public tl::Object
|
||||
{
|
||||
public:
|
||||
typedef std::pair<double, double> position_interval_type;
|
||||
typedef unsigned int input_key_type;
|
||||
typedef std::list<db::Polygon> neighbor_shapes_type;
|
||||
typedef std::map<input_key_type, neighbor_shapes_type> neighbors_per_interval_type;
|
||||
typedef std::vector<std::pair<position_interval_type, neighbors_per_interval_type> > neighbors_type;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
EdgeNeighborhoodVisitor () { }
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~EdgeNeighborhoodVisitor () { }
|
||||
|
||||
/**
|
||||
* @brief Event handler for each edge plus it's neighborhood
|
||||
*/
|
||||
void on_edge (const db::Layout *layout, const db::Cell *cell, const db::Edge &edge, const neighbors_type &neighbors);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A local operation for implementation of the neighborhood visitor
|
||||
*/
|
||||
class DB_PUBLIC EdgeNeighborhoodCompoundOperationNode
|
||||
: public CompoundRegionMultiInputOperationNode
|
||||
{
|
||||
public:
|
||||
EdgeNeighborhoodCompoundOperationNode (const std::vector<CompoundRegionOperationNode *> &children, EdgeNeighborhoodVisitor *visitor, const db::Coord bext, db::Coord eext, db::Coord din, db::Coord dout);
|
||||
|
||||
virtual ResultType result_type () const
|
||||
{
|
||||
return CompoundRegionOperationNode::Edges;
|
||||
}
|
||||
|
||||
virtual bool wants_caching () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual db::Coord computed_dist () const;
|
||||
virtual std::string generated_description () const;
|
||||
|
||||
virtual void do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::Polygon, db::Polygon> & /*interactions*/, std::vector<std::unordered_set<db::Edge> > & /*results*/, const db::LocalProcessorBase * /*proc*/) const;
|
||||
virtual void do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::PolygonRef, db::PolygonRef> & /*interactions*/, std::vector<std::unordered_set<db::Edge> > & /*results*/, const db::LocalProcessorBase * /*proc*/) const;
|
||||
|
||||
// not implemented
|
||||
virtual void do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::Polygon, db::Polygon> & /*interactions*/, std::vector<std::unordered_set<db::Polygon> > & /*results*/, const db::LocalProcessorBase * /*proc*/) const { }
|
||||
virtual void do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::Polygon, db::Polygon> & /*interactions*/, std::vector<std::unordered_set<db::EdgePair> > & /*results*/, const db::LocalProcessorBase * /*proc*/) const { }
|
||||
virtual void do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::PolygonRef, db::PolygonRef> & /*interactions*/, std::vector<std::unordered_set<db::PolygonRef> > & /*results*/, const db::LocalProcessorBase * /*proc*/) const { }
|
||||
virtual void do_compute_local (CompoundRegionOperationCache * /*cache*/, db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::PolygonRef, db::PolygonRef> & /*interactions*/, std::vector<std::unordered_set<db::EdgePair> > & /*results*/, const db::LocalProcessorBase * /*proc*/) const { }
|
||||
|
||||
private:
|
||||
db::Coord m_bext, m_eext, m_din, m_dout;
|
||||
tl::weak_ptr<EdgeNeighborhoodVisitor> mp_visitor;
|
||||
|
||||
void do_collect_neighbors (db::box_scanner2<db::Edge, unsigned int, db::Polygon, unsigned int> &scanner, const db::Layout *layout, const db::Cell *cell) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2024 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "gsiDecl.h"
|
||||
#include "gsiEnums.h"
|
||||
|
||||
#include "tlThreads.h"
|
||||
#include "dbEdgeNeighborhood.h"
|
||||
|
||||
namespace gsi
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// EdgeFilter binding
|
||||
|
||||
class EdgeNeighborhoodVisitorImpl
|
||||
: public db::EdgeNeighborhoodVisitor
|
||||
{
|
||||
public:
|
||||
EdgeNeighborhoodVisitorImpl () { }
|
||||
|
||||
void issue_on_edge (const db::Layout *, const db::Cell *, const db::Edge &, const tl::Variant &)
|
||||
{
|
||||
// just for signature
|
||||
}
|
||||
|
||||
void on_edge (const db::Layout *layout, const db::Cell *cell, const db::Edge &edge, const db::EdgeNeighborhoodVisitor::neighbors_type &neighbors)
|
||||
{
|
||||
if (f_on_edge.can_issue ()) {
|
||||
|
||||
tl::Variant neighborhood = build_neighbors (neighbors);
|
||||
|
||||
// NOTE: as scripts are potentially thread unsafe, we lock here
|
||||
tl::MutexLocker locker (&m_lock);
|
||||
return f_on_edge.issue<EdgeNeighborhoodVisitorImpl, const db::Layout *, const db::Cell *, const db::Edge &, const tl::Variant &> (&EdgeNeighborhoodVisitorImpl::issue_on_edge, layout, cell, edge, neighborhood);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
gsi::Callback f_on_edge;
|
||||
|
||||
static tl::Variant build_neighbors (const db::EdgeNeighborhoodVisitor::neighbors_type &neighbors)
|
||||
{
|
||||
tl::Variant result;
|
||||
result.set_list ();
|
||||
|
||||
for (auto n = neighbors.begin (); n != neighbors.end (); ++n) {
|
||||
|
||||
tl::Variant row;
|
||||
row.set_list ();
|
||||
|
||||
tl::Variant interval;
|
||||
interval.set_list ();
|
||||
interval.push (n->first.first);
|
||||
interval.push (n->first.second);
|
||||
row.push (interval);
|
||||
|
||||
tl::Variant nmap;
|
||||
nmap.set_array ();
|
||||
|
||||
for (auto nn = n->second.begin (); nn != n->second.end (); ++nn) {
|
||||
nmap.insert (tl::Variant (nn->first), tl::Variant (nn->second));
|
||||
}
|
||||
|
||||
row.push (nmap);
|
||||
|
||||
result.push (row);
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
// No copying
|
||||
EdgeNeighborhoodVisitorImpl &operator= (const EdgeNeighborhoodVisitorImpl &);
|
||||
EdgeNeighborhoodVisitorImpl (const EdgeNeighborhoodVisitorImpl &);
|
||||
|
||||
tl::Mutex m_lock;
|
||||
};
|
||||
|
||||
Class<gsi::EdgeNeighborhoodVisitorImpl> decl_EdgeNeighborhoodVisitorImpl ("db", "EdgeNeighborhoodVisitor",
|
||||
gsi::callback ("on_edge", &EdgeNeighborhoodVisitorImpl::issue_on_edge, &EdgeNeighborhoodVisitorImpl::f_on_edge, gsi::arg ("layout"), gsi::arg ("cell"), gsi::arg ("edge"), gsi::arg ("neighborhood"),
|
||||
"@brief Is called for each edge with the edge neighbors\n"
|
||||
"This method is called for every edge on the input region. It delivers the edge and the edge neighborhood. "
|
||||
"The edge neighborhood is classified in intervals along the edge. The intervals are given by a range of "
|
||||
"positions along the edge - 0.0 being the beginning of the edge and positive values towards the end of the edge. "
|
||||
"For 'bext' and 'eext' larger than zero (see "
|
||||
"\\EdgeNeighborhoodCompoundOperationNode), the position can be negative or larger than the edge length.\n"
|
||||
"\n"
|
||||
"The structure of the neighbors is:\n"
|
||||
"\n"
|
||||
"@code\n"
|
||||
"[\n"
|
||||
" [ [ from, to ], { input_index => polygons }\n"
|
||||
"]\n"
|
||||
"@/code\n"
|
||||
"\n"
|
||||
"'from' and 'to' are the positions of the interval, 'input_index' is the index of the input the neighbors are on "
|
||||
"(see 'children' argument of \\EdgeNeighborhoodCompoundOperationNode constructor), 'prop_id' is the properties ID of "
|
||||
"the neighbors and 'polygons' is a list of polygons describing the neighborhood.\n"
|
||||
"The polygons are projected on the edge - i.e. they are in a coordinate system where the edge is horizonal and "
|
||||
"goes from (0,0) to (length,0).\n"
|
||||
"\n"
|
||||
"The polygons are boxes for manhattan input and trapezoids in the general case.\n"
|
||||
),
|
||||
"@brief A visitor for the neighborhood of edges in the input\n"
|
||||
"\n"
|
||||
"Objects of this class are passed to \\EdgeNeighborhoodCompoundOperationNode constructor to handle "
|
||||
"events on each edge of the primary input along with the neighborhood taken from the additional inputs.\n"
|
||||
"\n"
|
||||
"See \\on_edge for the description of the events delivered."
|
||||
"\n"
|
||||
"This class has been introduced in version 0.xx.\n" // @@@
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// EdgeProcessor binding
|
||||
|
||||
static db::CompoundRegionOperationNode *new_edge_neighborhood (const std::vector<db::CompoundRegionOperationNode *> &children, db::EdgeNeighborhoodVisitor *visitor, const db::Coord bext, db::Coord eext, db::Coord din, db::Coord dout)
|
||||
{
|
||||
return new db::EdgeNeighborhoodCompoundOperationNode (children, visitor, bext, eext, din, dout);
|
||||
}
|
||||
|
||||
gsi::ClassExt<db::CompoundRegionOperationNode> decl_CompoundRegionOperationNode_ext (
|
||||
gsi::constructor ("new_edge_neighborhood", &new_edge_neighborhood, gsi::arg ("children"), gsi::arg ("visitor"), gsi::arg ("bext", 0), gsi::arg ("eext", 0), gsi::arg ("din", 0), gsi::arg ("dout", 0),
|
||||
"@brief Creates a new edge neighborhood collector\n"
|
||||
"\n"
|
||||
"@param children The inputs to use. The first one in the primary input, the others are neighbors.\n"
|
||||
"@param visitor The visitor object (see \\EdgeNeighborhoodVisitor) receiving the edge events.\n"
|
||||
"@param bext The search window extension to use at the edge beginning.\n"
|
||||
"@param eext The search window extension to use at the edge beginning.\n"
|
||||
"@param din The search window extension to use at the edge beginning.\n"
|
||||
"@param dout The search window extension to use at the edge beginning.\n"
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue