mirror of https://github.com/KLayout/klayout.git
Allowing the polygon neighborhood visitor to specify a variant type for deep mode
This commit is contained in:
parent
010fa2d5ba
commit
0cb5f35659
|
|
@ -712,6 +712,28 @@ VariantsCollectorBase::create_var_instances_tl_invariant (db::Cell &in_cell, std
|
|||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
TransformationReducer *
|
||||
make_reducer (ReducerType type)
|
||||
{
|
||||
|
||||
switch (type) {
|
||||
case Orientation:
|
||||
return new OrientationReducer ();
|
||||
case Orthogonal:
|
||||
return new OrthogonalTransformationReducer ();
|
||||
case Magnification:
|
||||
return new MagnificationReducer ();
|
||||
case XYAnisotropyAndMagnification:
|
||||
return new XYAnisotropyAndMagnificationReducer ();
|
||||
case MagnificationAndOrientation:
|
||||
return new MagnificationAndOrientationReducer ();
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
VariantStatistics::VariantStatistics ()
|
||||
: mp_red ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -166,6 +166,51 @@ private:
|
|||
int64_t m_grid;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An enum describing a reducer type
|
||||
*
|
||||
* This enum is used to create a generic reducer (parameterless) from the code.
|
||||
*/
|
||||
enum ReducerType
|
||||
{
|
||||
/**
|
||||
* @brief No specific reducer
|
||||
*/
|
||||
NoReducer = 0,
|
||||
|
||||
/**
|
||||
* @brief Rotation/mirror variants
|
||||
*/
|
||||
Orientation = 1,
|
||||
|
||||
/**
|
||||
* @brief Orthogonal transformations (rotations of multiple of 90 degree) variants
|
||||
*/
|
||||
Orthogonal = 2,
|
||||
|
||||
/**
|
||||
* @brief Scaling variants
|
||||
*/
|
||||
Magnification = 3,
|
||||
|
||||
/**
|
||||
* @brief Scaling and x/y assymmetry variants (i.e. anisotropic size)
|
||||
*/
|
||||
XYAnisotropyAndMagnification = 4,
|
||||
|
||||
/**
|
||||
* @brief Scaling and orientation variants
|
||||
*/
|
||||
MagnificationAndOrientation = 5
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates a TransformationReducer from the type enum
|
||||
*
|
||||
* This function returns 0 if the type is NoReducer or invalid.
|
||||
*/
|
||||
DB_PUBLIC TransformationReducer *make_reducer (ReducerType type);
|
||||
|
||||
/**
|
||||
* @brief A class computing variants for cells according to a given criterion
|
||||
*
|
||||
|
|
|
|||
|
|
@ -302,7 +302,7 @@ CompoundTransformationReducer::is_translation_invariant () const
|
|||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
CompoundRegionMultiInputOperationNode::CompoundRegionMultiInputOperationNode (const std::vector<CompoundRegionOperationNode *> &children)
|
||||
CompoundRegionMultiInputOperationNode::CompoundRegionMultiInputOperationNode (const std::vector<CompoundRegionOperationNode *> &children, bool no_init)
|
||||
{
|
||||
for (std::vector<CompoundRegionOperationNode *>::const_iterator c = children.begin (); c != children.end (); ++c) {
|
||||
(*c)->keep ();
|
||||
|
|
@ -362,6 +362,11 @@ CompoundRegionMultiInputOperationNode::init ()
|
|||
for (tl::shared_collection<CompoundRegionOperationNode>::iterator i = m_children.begin (); i != m_children.end (); ++i) {
|
||||
m_vars.add (i->vars ());
|
||||
}
|
||||
|
||||
// add the local variant reducer
|
||||
if (local_vars ()) {
|
||||
m_vars.add (local_vars ());
|
||||
}
|
||||
}
|
||||
|
||||
CompoundRegionMultiInputOperationNode::~CompoundRegionMultiInputOperationNode ()
|
||||
|
|
|
|||
|
|
@ -453,7 +453,7 @@ class DB_PUBLIC CompoundRegionMultiInputOperationNode
|
|||
: public CompoundRegionOperationNode
|
||||
{
|
||||
public:
|
||||
CompoundRegionMultiInputOperationNode (const std::vector<CompoundRegionOperationNode *> &children);
|
||||
CompoundRegionMultiInputOperationNode (const std::vector<CompoundRegionOperationNode *> &children, bool no_init = false);
|
||||
CompoundRegionMultiInputOperationNode ();
|
||||
CompoundRegionMultiInputOperationNode (CompoundRegionOperationNode *child);
|
||||
CompoundRegionMultiInputOperationNode (CompoundRegionOperationNode *a, CompoundRegionOperationNode *b);
|
||||
|
|
@ -521,14 +521,16 @@ protected:
|
|||
CompoundRegionOperationNode *child (unsigned int index);
|
||||
const CompoundRegionOperationNode *child (unsigned int index) const;
|
||||
|
||||
virtual const TransformationReducer *local_vars () const { return 0; }
|
||||
|
||||
void init ();
|
||||
|
||||
private:
|
||||
tl::shared_collection<CompoundRegionOperationNode> m_children;
|
||||
// maps child#,layer# to layer# of child:
|
||||
std::map<std::pair<unsigned int, unsigned int>, unsigned int> m_map_layer_to_child;
|
||||
std::vector<db::Region *> m_inputs;
|
||||
CompoundTransformationReducer m_vars;
|
||||
|
||||
void init ();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -28,38 +28,42 @@ namespace db
|
|||
{
|
||||
|
||||
PolygonNeighborhoodVisitor::PolygonNeighborhoodVisitor ()
|
||||
: m_result_type (db::CompoundRegionOperationNode::ResultType::Edges)
|
||||
: m_result_type (db::CompoundRegionOperationNode::ResultType::Edges), m_variant_type (db::NoReducer)
|
||||
{
|
||||
disconnect_outputs ();
|
||||
}
|
||||
|
||||
void
|
||||
PolygonNeighborhoodVisitor::connect_output (Layout * /*layout*/, std::unordered_set<db::PolygonWithProperties> *polygons) const
|
||||
PolygonNeighborhoodVisitor::connect_output (Layout * /*layout*/, std::unordered_set<db::PolygonWithProperties> *polygons, const db::ICplxTrans &trans) const
|
||||
{
|
||||
disconnect_outputs ();
|
||||
mp_polygons = polygons;
|
||||
m_trans = trans;
|
||||
}
|
||||
|
||||
void
|
||||
PolygonNeighborhoodVisitor::connect_output (db::Layout *layout, std::unordered_set<db::PolygonRefWithProperties> *polygons) const
|
||||
PolygonNeighborhoodVisitor::connect_output (db::Layout *layout, std::unordered_set<db::PolygonRefWithProperties> *polygons, const db::ICplxTrans &trans) const
|
||||
{
|
||||
disconnect_outputs ();
|
||||
mp_layout = layout;
|
||||
mp_polygon_refs = polygons;
|
||||
m_trans = trans;
|
||||
}
|
||||
|
||||
void
|
||||
PolygonNeighborhoodVisitor::connect_output (db::Layout * /*layout*/, std::unordered_set<db::EdgeWithProperties> *edges) const
|
||||
PolygonNeighborhoodVisitor::connect_output (db::Layout * /*layout*/, std::unordered_set<db::EdgeWithProperties> *edges, const db::ICplxTrans &trans) const
|
||||
{
|
||||
disconnect_outputs ();
|
||||
mp_edges = edges;
|
||||
m_trans = trans;
|
||||
}
|
||||
|
||||
void
|
||||
PolygonNeighborhoodVisitor::connect_output (Layout * /*layout*/, std::unordered_set<db::EdgePairWithProperties> *edge_pairs) const
|
||||
PolygonNeighborhoodVisitor::connect_output (Layout * /*layout*/, std::unordered_set<db::EdgePairWithProperties> *edge_pairs, const db::ICplxTrans &trans) const
|
||||
{
|
||||
disconnect_outputs ();
|
||||
mp_edge_pairs = edge_pairs;
|
||||
m_trans = trans;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -76,10 +80,10 @@ void
|
|||
PolygonNeighborhoodVisitor::output_polygon (const db::PolygonWithProperties &poly)
|
||||
{
|
||||
if (mp_polygons) {
|
||||
mp_polygons->insert (poly);
|
||||
mp_polygons->insert (poly.transformed (m_trans));
|
||||
} else if (mp_polygon_refs) {
|
||||
tl_assert (mp_layout != 0);
|
||||
mp_polygon_refs->insert (db::PolygonRefWithProperties (db::PolygonRef (poly, mp_layout->shape_repository ()), poly.properties_id ()));
|
||||
mp_polygon_refs->insert (db::PolygonRefWithProperties (db::PolygonRef (poly.transformed (m_trans), mp_layout->shape_repository ()), poly.properties_id ()));
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (tr ("PolygonNeighborhoodVisitor is not configured for edge output (use 'result_type=Edges')")));
|
||||
}
|
||||
|
|
@ -91,7 +95,7 @@ PolygonNeighborhoodVisitor::output_edge (const db::EdgeWithProperties &edge)
|
|||
if (mp_edges == 0) {
|
||||
throw tl::Exception (tl::to_string (tr ("PolygonNeighborhoodVisitor is not configured for edge output (use 'result_type=Edges')")));
|
||||
}
|
||||
mp_edges->insert (edge);
|
||||
mp_edges->insert (edge.transformed (m_trans));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -100,16 +104,22 @@ PolygonNeighborhoodVisitor::output_edge_pair (const db::EdgePairWithProperties &
|
|||
if (mp_edge_pairs == 0) {
|
||||
throw tl::Exception (tl::to_string (tr ("PolygonNeighborhoodVisitor is not configured for edge pair output (use 'result_type=EdgePairs')")));
|
||||
}
|
||||
mp_edge_pairs->insert (edge_pair);
|
||||
mp_edge_pairs->insert (edge_pair.transformed (m_trans));
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------------
|
||||
|
||||
PolygonNeighborhoodCompoundOperationNode::PolygonNeighborhoodCompoundOperationNode (const std::vector<CompoundRegionOperationNode *> &children, PolygonNeighborhoodVisitor *visitor, db::Coord dist)
|
||||
: CompoundRegionMultiInputOperationNode (children), m_dist (dist), mp_visitor (visitor)
|
||||
: CompoundRegionMultiInputOperationNode (children, true /*no implicit init()*/),
|
||||
m_dist (dist), mp_visitor (visitor)
|
||||
{
|
||||
tl_assert (visitor != 0);
|
||||
visitor->keep ();
|
||||
|
||||
m_vars.reset (db::make_reducer (visitor->variant_type ()));
|
||||
|
||||
// must be called after local_vars() is available
|
||||
init ();
|
||||
}
|
||||
|
||||
db::Coord
|
||||
|
|
@ -170,12 +180,19 @@ PolygonNeighborhoodCompoundOperationNode::compute_local_impl (CompoundRegionOper
|
|||
tl_assert (interactions.num_subjects () == 1);
|
||||
tl_assert (! results.empty ());
|
||||
|
||||
db::ICplxTrans var_trans, var_trans_inv;
|
||||
if (proc->vars ()) {
|
||||
var_trans_inv = proc->vars ()->single_variant_transformation (cell->cell_index ());
|
||||
var_trans = var_trans_inv.inverted ();
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
mp_visitor->connect_output (layout, &results.front ());
|
||||
mp_visitor->connect_output (layout, &results.front (), var_trans_inv);
|
||||
|
||||
const T &pr = interactions.begin_subjects ()->second;
|
||||
db::PolygonWithProperties subject (pr.instantiate (), pr.properties_id ());
|
||||
subject.transform (var_trans);
|
||||
|
||||
PolygonNeighborhoodVisitor::neighbors_type neighbors;
|
||||
|
||||
|
|
@ -191,6 +208,7 @@ PolygonNeighborhoodCompoundOperationNode::compute_local_impl (CompoundRegionOper
|
|||
|
||||
for (auto p = others.front ().begin (); p != others.front ().end (); ++p) {
|
||||
n.push_back (db::PolygonWithProperties (p->instantiate (), p->properties_id ()));
|
||||
n.back ().transform (var_trans);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,22 +58,22 @@ public:
|
|||
/**
|
||||
* @brief Configure the polygon output
|
||||
*/
|
||||
void connect_output (db::Layout * /*layout*/, std::unordered_set<db::PolygonWithProperties> *polygons) const;
|
||||
void connect_output (db::Layout * /*layout*/, std::unordered_set<db::PolygonWithProperties> *polygons, const db::ICplxTrans &trans) const;
|
||||
|
||||
/**
|
||||
* @brief Configure the polygon ref output
|
||||
*/
|
||||
void connect_output (db::Layout *layout, std::unordered_set<db::PolygonRefWithProperties> *polygons) const;
|
||||
void connect_output (db::Layout *layout, std::unordered_set<db::PolygonRefWithProperties> *polygons, const db::ICplxTrans &trans) const;
|
||||
|
||||
/**
|
||||
* @brief Configure the edge output
|
||||
*/
|
||||
void connect_output (db::Layout * /*layout*/, std::unordered_set<db::EdgeWithProperties> *edges) const;
|
||||
void connect_output (db::Layout * /*layout*/, std::unordered_set<db::EdgeWithProperties> *edges, const db::ICplxTrans &trans) const;
|
||||
|
||||
/**
|
||||
* @brief Configure the edge pair output
|
||||
*/
|
||||
void connect_output (db::Layout * /*layout*/, std::unordered_set<db::EdgePairWithProperties> *edge_pairs) const;
|
||||
void connect_output (db::Layout * /*layout*/, std::unordered_set<db::EdgePairWithProperties> *edge_pairs, const db::ICplxTrans &trans) const;
|
||||
|
||||
/**
|
||||
* @brief Disconnects output
|
||||
|
|
@ -102,6 +102,22 @@ public:
|
|||
return m_result_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the variant type
|
||||
*/
|
||||
void set_variant_type (db::ReducerType variant_type)
|
||||
{
|
||||
m_variant_type = variant_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the variant type
|
||||
*/
|
||||
db::ReducerType variant_type () const
|
||||
{
|
||||
return m_variant_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delivers a polygon
|
||||
* This function is only permitted if the result type is Region.
|
||||
|
|
@ -122,11 +138,13 @@ public:
|
|||
|
||||
private:
|
||||
db::CompoundRegionOperationNode::ResultType m_result_type;
|
||||
db::ReducerType m_variant_type;
|
||||
mutable std::unordered_set<db::PolygonWithProperties> *mp_polygons;
|
||||
mutable std::unordered_set<db::PolygonRefWithProperties> *mp_polygon_refs;
|
||||
mutable std::unordered_set<db::EdgeWithProperties> *mp_edges;
|
||||
mutable std::unordered_set<db::EdgePairWithProperties> *mp_edge_pairs;
|
||||
mutable db::Layout *mp_layout;
|
||||
mutable db::ICplxTrans m_trans;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -148,6 +166,11 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
virtual const TransformationReducer *local_vars () const
|
||||
{
|
||||
return m_vars.get ();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual db::Coord computed_dist () const;
|
||||
virtual std::string generated_description () const;
|
||||
|
|
@ -162,6 +185,7 @@ protected:
|
|||
private:
|
||||
db::Coord m_dist;
|
||||
tl::weak_ptr<PolygonNeighborhoodVisitor> mp_visitor;
|
||||
std::unique_ptr<db::TransformationReducer> m_vars;
|
||||
|
||||
template <class T, class TR>
|
||||
void compute_local_impl (CompoundRegionOperationCache * /*cache*/, db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<T, T> & /*interactions*/, std::vector<std::unordered_set<TR> > & /*results*/, const db::LocalProcessorBase * /*proc*/) const;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "gsiDecl.h"
|
||||
#include "gsiDeclDbMetaInfo.h"
|
||||
#include "gsiEnums.h"
|
||||
|
||||
#include "gsiDeclDbHelpers.h"
|
||||
#include "dbLayout.h"
|
||||
|
|
@ -4655,5 +4656,39 @@ Class<db::DCellInstArray> decl_DCellInstArray ("db", "DCellInstArray",
|
|||
"This class has been introduced in version 0.25."
|
||||
);
|
||||
|
||||
gsi::Enum<db::ReducerType> decl_VariantType ("db", "VariantType",
|
||||
gsi::enum_const ("NoVariants", db::NoReducer,
|
||||
"@brief No variants needed."
|
||||
) +
|
||||
gsi::enum_const ("Orientation", db::Orientation,
|
||||
"@brief Orientation variants needed.\n"
|
||||
"For example, the edge orientation selection operation needs this variant type."
|
||||
) +
|
||||
gsi::enum_const ("Orthogonal", db::Orthogonal,
|
||||
"@brief Orthogonal transformations (rotations by multiples of 90 degree) need variants.\n"
|
||||
"For example, the diagonal edge selection operation needs this variant type."
|
||||
) +
|
||||
gsi::enum_const ("Magnification", db::Magnification,
|
||||
"@brief Scaling variants needed.\n"
|
||||
"For example, distance measurements or the isotropic sizing operations needs this variant type."
|
||||
) +
|
||||
gsi::enum_const ("XYAnisotropyAndMagnification", db::XYAnisotropyAndMagnification,
|
||||
"@brief Scaling and anisotropy variants needed.\n"
|
||||
"For example, the anisotropic sizing operation needs this variant type."
|
||||
) +
|
||||
gsi::enum_const ("MagnificationAndOrientation", db::MagnificationAndOrientation,
|
||||
"@brief Scaling and orientation variants needed.\n"
|
||||
"For example, the 'move' operation needs this variant type."
|
||||
),
|
||||
"@brief This class represents the cell variant type for various methods.\n"
|
||||
"\n"
|
||||
"Cell variants are needed in hierarchical applications, when operations are to be "
|
||||
"performed on cell level, but the operations are not transformation invariant.\n"
|
||||
"In that case, a variant type needs to be specified in order to make the algorithm "
|
||||
"separate the cells by their absolute orientation or by their accumulated magnification.\n"
|
||||
"\n"
|
||||
"This enum has been introduced in version 0.30.2."
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,6 +109,20 @@ Class<gsi::PolygonNeighborhoodVisitorImpl> decl_PolygonNeighborhoodVisitorImpl (
|
|||
) +
|
||||
gsi::method ("result_type", &PolygonNeighborhoodVisitorImpl::result_type,
|
||||
"@brief Gets the result type\n"
|
||||
) +
|
||||
gsi::method ("variant_type=", &PolygonNeighborhoodVisitorImpl::set_variant_type, gsi::arg ("variant_type"),
|
||||
"@brief Configures the variant type\n"
|
||||
"The variant type configures transformation variant formation. The polygons presented to the visitor are "
|
||||
"normalized to the given variant type. For example, specify \\VariantType#Orientation to force orientation variants "
|
||||
"in the cell tree. Polygons presented to the visitor are normalized to 'as if top' orientation with this variant type.\n"
|
||||
"\n"
|
||||
"This property was introduced in version 0.30.2."
|
||||
) +
|
||||
gsi::method ("variant_type", &PolygonNeighborhoodVisitorImpl::variant_type,
|
||||
"@brief Gets the variant type\n"
|
||||
"See \\variant_type= for a description of this property.\n"
|
||||
"\n"
|
||||
"This property was introduced in version 0.30.2."
|
||||
),
|
||||
"@brief A visitor for the neighborhood of polygons in the input\n"
|
||||
"\n"
|
||||
|
|
|
|||
Loading…
Reference in New Issue