mirror of https://github.com/KLayout/klayout.git
WIP: Region, Edges, EdgePairs and Texts filters can filter by property now, first implementation of Region property filter.
This commit is contained in:
parent
54242bc848
commit
a219576296
|
|
@ -233,7 +233,7 @@ AsIfFlatEdgePairs::filtered (const EdgePairFilterBase &filter) const
|
|||
std::unique_ptr<FlatEdgePairs> new_edge_pairs (new FlatEdgePairs ());
|
||||
|
||||
for (EdgePairsIterator p (begin ()); ! p.at_end (); ++p) {
|
||||
if (filter.selected (*p)) {
|
||||
if (filter.selected (*p, p.prop_id ())) {
|
||||
db::properties_id_type prop_id = p.prop_id ();
|
||||
if (prop_id != 0) {
|
||||
new_edge_pairs->insert (db::EdgePairWithProperties (*p, prop_id));
|
||||
|
|
|
|||
|
|
@ -711,8 +711,12 @@ AsIfFlatEdges::filtered (const EdgeFilterBase &filter) const
|
|||
std::unique_ptr<FlatEdges> new_region (new FlatEdges ());
|
||||
|
||||
for (EdgesIterator p (begin_merged ()); ! p.at_end (); ++p) {
|
||||
if (filter.selected (*p)) {
|
||||
new_region->insert (*p);
|
||||
if (filter.selected (*p, p.prop_id ())) {
|
||||
if (p.prop_id () != 0) {
|
||||
new_region->insert (db::EdgeWithProperties (*p, p.prop_id ()));
|
||||
} else {
|
||||
new_region->insert (*p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ AsIfFlatRegion::edges (const EdgeFilterBase *filter, const PolygonToEdgeProcesso
|
|||
proc->process (*p, heap);
|
||||
|
||||
for (auto e = heap.begin (); e != heap.end (); ++e) {
|
||||
if (! filter || filter->selected (*e)) {
|
||||
if (! filter || filter->selected (*e, prop_id)) {
|
||||
if (prop_id != 0) {
|
||||
result->insert (db::EdgeWithProperties (*e, prop_id));
|
||||
} else {
|
||||
|
|
@ -179,7 +179,7 @@ AsIfFlatRegion::edges (const EdgeFilterBase *filter, const PolygonToEdgeProcesso
|
|||
} else {
|
||||
|
||||
for (db::Polygon::polygon_edge_iterator e = p->begin_edge (); ! e.at_end (); ++e) {
|
||||
if (! filter || filter->selected (*e)) {
|
||||
if (! filter || filter->selected (*e, prop_id)) {
|
||||
if (prop_id != 0) {
|
||||
result->insert (db::EdgeWithProperties (*e, prop_id));
|
||||
} else {
|
||||
|
|
@ -420,8 +420,12 @@ AsIfFlatRegion::filtered (const PolygonFilterBase &filter) const
|
|||
std::unique_ptr<FlatRegion> new_region (new FlatRegion ());
|
||||
|
||||
for (RegionIterator p (begin_merged ()); ! p.at_end (); ++p) {
|
||||
if (filter.selected (*p)) {
|
||||
new_region->insert (*p);
|
||||
if (filter.selected (*p, p.prop_id ())) {
|
||||
if (p.prop_id () != 0) {
|
||||
new_region->insert (db::PolygonWithProperties (*p, p.prop_id ()));
|
||||
} else {
|
||||
new_region->insert (*p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -159,8 +159,12 @@ AsIfFlatTexts::filtered (const TextFilterBase &filter) const
|
|||
std::unique_ptr<FlatTexts> new_texts (new FlatTexts ());
|
||||
|
||||
for (TextsIterator p (begin ()); ! p.at_end (); ++p) {
|
||||
if (filter.selected (*p)) {
|
||||
new_texts->insert (*p);
|
||||
if (filter.selected (*p, p.prop_id ())) {
|
||||
if (p.prop_id () != 0) {
|
||||
new_texts->insert (db::TextWithProperties (*p, p.prop_id ()));
|
||||
} else {
|
||||
new_texts->insert (*p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1260,7 +1260,13 @@ CompoundRegionEdgePairFilterOperationNode::do_compute_local (CompoundRegionOpera
|
|||
bool
|
||||
CompoundRegionEdgePairFilterOperationNode::is_selected (const db::EdgePair &p) const
|
||||
{
|
||||
return mp_filter->selected (p);
|
||||
return mp_filter->selected (p, db::properties_id_type (0));
|
||||
}
|
||||
|
||||
bool
|
||||
CompoundRegionEdgePairFilterOperationNode::is_selected (const db::EdgePairWithProperties &p) const
|
||||
{
|
||||
return mp_filter->selected (p, p.properties_id ());
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1015,14 +1015,12 @@ private:
|
|||
child (0)->compute_local (cache, layout, cell, interactions, one, proc);
|
||||
|
||||
if (m_sum_of_set) {
|
||||
std::unordered_set<T> wo_props;
|
||||
wo_props.insert (one.front ().begin (), one.front ().end ());
|
||||
if (mp_filter->selected_set (wo_props)) {
|
||||
if (mp_filter->selected_set (one.front ())) {
|
||||
results.front ().insert (one.front ().begin (), one.front ().end ());
|
||||
}
|
||||
} else {
|
||||
for (typename std::unordered_set<db::object_with_properties<T> >::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) {
|
||||
if (mp_filter->selected (*p)) {
|
||||
if (mp_filter->selected (*p, p->properties_id ())) {
|
||||
results.front ().insert (*p);
|
||||
}
|
||||
}
|
||||
|
|
@ -1066,14 +1064,12 @@ private:
|
|||
child (0)->compute_local (cache, layout, cell, interactions, one, proc);
|
||||
|
||||
if (m_sum_of) {
|
||||
std::unordered_set<db::Edge> wo_props;
|
||||
wo_props.insert (one.front ().begin (), one.front ().end ());
|
||||
if (mp_filter->selected (wo_props)) {
|
||||
if (mp_filter->selected (one.front ())) {
|
||||
results.front ().insert (one.front ().begin (), one.front ().end ());
|
||||
}
|
||||
} else {
|
||||
for (typename std::unordered_set<db::EdgeWithProperties>::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) {
|
||||
if (mp_filter->selected (*p)) {
|
||||
if (mp_filter->selected (*p, p->properties_id ())) {
|
||||
results.front ().insert (*p);
|
||||
}
|
||||
}
|
||||
|
|
@ -1108,6 +1104,7 @@ private:
|
|||
bool m_owns_filter;
|
||||
|
||||
bool is_selected (const db::EdgePair &p) const;
|
||||
bool is_selected (const db::EdgePairWithProperties &p) const;
|
||||
|
||||
template <class T, class TR>
|
||||
void implement_compute_local (db::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
|
||||
|
|
|
|||
|
|
@ -423,7 +423,7 @@ DeepEdgePairs::apply_filter (const EdgePairFilterBase &filter) const
|
|||
const db::ICplxTrans &tr = *v;
|
||||
|
||||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::EdgePairs); ! si.at_end (); ++si) {
|
||||
if (filter.selected (si->edge_pair ().transformed (tr))) {
|
||||
if (filter.selected (si->edge_pair ().transformed (tr), si->prop_id ())) {
|
||||
st->insert (*si);
|
||||
}
|
||||
}
|
||||
|
|
@ -435,7 +435,7 @@ DeepEdgePairs::apply_filter (const EdgePairFilterBase &filter) const
|
|||
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
||||
|
||||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::EdgePairs); ! si.at_end (); ++si) {
|
||||
if (filter.selected (si->edge_pair ())) {
|
||||
if (filter.selected (si->edge_pair (), si->prop_id ())) {
|
||||
st.insert (*si);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -848,7 +848,7 @@ DeepEdges::apply_filter (const EdgeFilterBase &filter) const
|
|||
}
|
||||
|
||||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Edges); ! si.at_end (); ++si) {
|
||||
if (filter.selected (si->edge ().transformed (*v))) {
|
||||
if (filter.selected (si->edge ().transformed (*v), si->prop_id ())) {
|
||||
st->insert (*si);
|
||||
}
|
||||
}
|
||||
|
|
@ -860,7 +860,7 @@ DeepEdges::apply_filter (const EdgeFilterBase &filter) const
|
|||
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
||||
|
||||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Edges); ! si.at_end (); ++si) {
|
||||
if (filter.selected (si->edge ())) {
|
||||
if (filter.selected (si->edge (), si->prop_id ())) {
|
||||
st.insert (*si);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1511,7 +1511,7 @@ DeepRegion::edges (const EdgeFilterBase *filter, const PolygonToEdgeProcessorBas
|
|||
proc->process (poly, heap);
|
||||
|
||||
for (auto e = heap.begin (); e != heap.end (); ++e) {
|
||||
if (! filter || filter->selected ((*e).transformed (tr))) {
|
||||
if (! filter || filter->selected ((*e).transformed (tr), si->prop_id ())) {
|
||||
st.insert (db::EdgeWithProperties (*e, si->prop_id ()));
|
||||
}
|
||||
}
|
||||
|
|
@ -1519,7 +1519,7 @@ DeepRegion::edges (const EdgeFilterBase *filter, const PolygonToEdgeProcessorBas
|
|||
} else {
|
||||
|
||||
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
|
||||
if (! filter || filter->selected ((*e).transformed (tr))) {
|
||||
if (! filter || filter->selected ((*e).transformed (tr), si->prop_id ())) {
|
||||
st.insert (db::EdgeWithProperties (*e, si->prop_id ()));
|
||||
}
|
||||
}
|
||||
|
|
@ -1641,7 +1641,7 @@ DeepRegion::apply_filter (const PolygonFilterBase &filter) const
|
|||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) {
|
||||
db::Polygon poly;
|
||||
si->polygon (poly);
|
||||
if (filter.selected (poly.transformed (*v))) {
|
||||
if (filter.selected (poly.transformed (*v), si->prop_id ())) {
|
||||
st->insert (*si);
|
||||
}
|
||||
}
|
||||
|
|
@ -1655,7 +1655,7 @@ DeepRegion::apply_filter (const PolygonFilterBase &filter) const
|
|||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) {
|
||||
db::Polygon poly;
|
||||
si->polygon (poly);
|
||||
if (filter.selected (poly)) {
|
||||
if (filter.selected (poly, si->prop_id ())) {
|
||||
st.insert (*si);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -442,7 +442,7 @@ DeepTexts *DeepTexts::apply_filter (const TextFilterBase &filter) const
|
|||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Texts); ! si.at_end (); ++si) {
|
||||
db::Text text;
|
||||
si->text (text);
|
||||
if (filter.selected (text.transformed (*v))) {
|
||||
if (filter.selected (text.transformed (*v), si->prop_id ())) {
|
||||
st->insert (*si);
|
||||
}
|
||||
}
|
||||
|
|
@ -456,7 +456,7 @@ DeepTexts *DeepTexts::apply_filter (const TextFilterBase &filter) const
|
|||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Texts); ! si.at_end (); ++si) {
|
||||
db::Text text;
|
||||
si->text (text);
|
||||
if (filter.selected (text)) {
|
||||
if (filter.selected (text, si->prop_id ())) {
|
||||
st.insert (*si);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,12 +43,12 @@ EdgeFilterBasedEdgePairFilter::~EdgeFilterBasedEdgePairFilter ()
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
bool EdgeFilterBasedEdgePairFilter::selected (const db::EdgePair &edge_pair) const
|
||||
bool EdgeFilterBasedEdgePairFilter::selected (const db::EdgePair &edge_pair, db::properties_id_type prop_id) const
|
||||
{
|
||||
if (m_one_must_match) {
|
||||
return mp_edge_filter->selected (edge_pair.first ()) || mp_edge_filter->selected (edge_pair.second ());
|
||||
return mp_edge_filter->selected (edge_pair.first (), prop_id) || mp_edge_filter->selected (edge_pair.second (), prop_id);
|
||||
} else {
|
||||
return mp_edge_filter->selected (edge_pair.first ()) && mp_edge_filter->selected (edge_pair.second ());
|
||||
return mp_edge_filter->selected (edge_pair.first (), prop_id) && mp_edge_filter->selected (edge_pair.second (), prop_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ EdgePairFilterByDistance::EdgePairFilterByDistance (distance_type min_distance,
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
bool EdgePairFilterByDistance::selected (const db::EdgePair &edge_pair) const
|
||||
bool EdgePairFilterByDistance::selected (const db::EdgePair &edge_pair, db::properties_id_type) const
|
||||
{
|
||||
distance_type dist = edge_pair.distance ();
|
||||
bool sel = (dist >= m_min_distance && dist < m_max_distance);
|
||||
|
|
@ -87,7 +87,7 @@ EdgePairFilterByArea::EdgePairFilterByArea (area_type min_area, area_type max_ar
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
bool EdgePairFilterByArea::selected (const db::EdgePair &edge_pair) const
|
||||
bool EdgePairFilterByArea::selected (const db::EdgePair &edge_pair, db::properties_id_type) const
|
||||
{
|
||||
area_type dist = edge_pair.to_simple_polygon (0).area ();
|
||||
bool sel = (dist >= m_min_area && dist < m_max_area);
|
||||
|
|
@ -110,7 +110,7 @@ InternalAngleEdgePairFilter::InternalAngleEdgePairFilter (double amin, bool incl
|
|||
}
|
||||
|
||||
bool
|
||||
InternalAngleEdgePairFilter::selected (const db::EdgePair &edge_pair) const
|
||||
InternalAngleEdgePairFilter::selected (const db::EdgePair &edge_pair, db::properties_id_type) const
|
||||
{
|
||||
db::Vector d1 = edge_pair.first ().d ();
|
||||
db::Vector d2 = edge_pair.second ().d ();
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ public:
|
|||
EdgeFilterBasedEdgePairFilter (EdgeFilterBase *edge_filter, bool one_must_match);
|
||||
virtual ~EdgeFilterBasedEdgePairFilter ();
|
||||
|
||||
virtual bool selected (const db::EdgePair &edge_pair) const;
|
||||
virtual bool selected (const db::EdgePair &edge_pair, properties_id_type prop_id) const;
|
||||
virtual const TransformationReducer *vars () const;
|
||||
virtual bool wants_variants () const;
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ public:
|
|||
|
||||
EdgePairFilterByDistance (distance_type min_distance, distance_type max_distance, bool inverted);
|
||||
|
||||
virtual bool selected (const db::EdgePair &edge_pair) const;
|
||||
virtual bool selected (const db::EdgePair &edge_pair, properties_id_type) const;
|
||||
virtual const TransformationReducer *vars () const { return &m_vars; }
|
||||
virtual bool wants_variants () const { return true; }
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ public:
|
|||
|
||||
EdgePairFilterByArea (area_type min_area, area_type max_area, bool inverted);
|
||||
|
||||
virtual bool selected (const db::EdgePair &edge_pair) const;
|
||||
virtual bool selected (const db::EdgePair &edge_pair, properties_id_type) const;
|
||||
virtual const TransformationReducer *vars () const { return &m_vars; }
|
||||
virtual bool wants_variants () const { return true; }
|
||||
|
||||
|
|
@ -114,7 +114,7 @@ public:
|
|||
InternalAngleEdgePairFilter (double a, bool inverted);
|
||||
InternalAngleEdgePairFilter (double amin, bool include_amin, double amax, bool include_amax, bool inverted);
|
||||
|
||||
virtual bool selected (const db::EdgePair &edge_pair) const;
|
||||
virtual bool selected (const db::EdgePair &edge_pair, properties_id_type) const;
|
||||
virtual const TransformationReducer *vars () const { return 0; }
|
||||
virtual bool wants_variants () const { return false; }
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ public:
|
|||
EdgePairFilterBase () { }
|
||||
virtual ~EdgePairFilterBase () { }
|
||||
|
||||
virtual bool selected (const db::EdgePair &edge_pair) const = 0;
|
||||
virtual bool selected (const db::EdgePair &edge_pair, db::properties_id_type prop_id) const = 0;
|
||||
virtual const TransformationReducer *vars () const = 0;
|
||||
virtual bool wants_variants () const = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -56,13 +56,13 @@ public:
|
|||
* @brief Filters the edge
|
||||
* If this method returns true, the edge is kept. Otherwise it's discarded.
|
||||
*/
|
||||
virtual bool selected (const db::Edge &edge) const = 0;
|
||||
virtual bool selected (const db::Edge &edge, db::properties_id_type prop_id) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Filters the edge set
|
||||
* If this method returns true, the edges are kept. Otherwise they are discarded.
|
||||
*/
|
||||
virtual bool selected (const std::unordered_set<db::Edge> &edge) const = 0;
|
||||
virtual bool selected (const std::unordered_set<db::EdgeWithProperties> &edge) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns the transformation reducer for building cell variants
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ EdgeOrientationFilter::EdgeOrientationFilter (double a, bool inverse, bool absol
|
|||
}
|
||||
|
||||
bool
|
||||
EdgeOrientationFilter::selected (const db::Edge &edge) const
|
||||
EdgeOrientationFilter::selected (const db::Edge &edge, db::properties_id_type) const
|
||||
{
|
||||
// NOTE: this edge normalization confines the angle to a range between (-90 .. 90] (-90 excluded).
|
||||
// A horizontal edge has 0 degree, a vertical one has 90 degree.
|
||||
|
|
@ -342,7 +342,7 @@ static EdgeAngleChecker s_orthodiagonal_checkers [] = {
|
|||
};
|
||||
|
||||
bool
|
||||
SpecialEdgeOrientationFilter::selected (const db::Edge &edge) const
|
||||
SpecialEdgeOrientationFilter::selected (const db::Edge &edge, properties_id_type) const
|
||||
{
|
||||
const EdgeAngleChecker *eb, *ee;
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ struct DB_PUBLIC EdgeLengthFilter
|
|||
/**
|
||||
* @brief Returns true if the edge length matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Edge &edge) const
|
||||
virtual bool selected (const db::Edge &edge, db::properties_id_type) const
|
||||
{
|
||||
return check (edge.length ());
|
||||
}
|
||||
|
|
@ -79,10 +79,10 @@ struct DB_PUBLIC EdgeLengthFilter
|
|||
/**
|
||||
* @brief Returns true if the total edge length matches the criterion
|
||||
*/
|
||||
bool selected (const std::unordered_set<db::Edge> &edges) const
|
||||
bool selected (const std::unordered_set<db::EdgeWithProperties> &edges) const
|
||||
{
|
||||
length_type l = 0;
|
||||
for (std::unordered_set<db::Edge>::const_iterator e = edges.begin (); e != edges.end (); ++e) {
|
||||
for (std::unordered_set<db::EdgeWithProperties>::const_iterator e = edges.begin (); e != edges.end (); ++e) {
|
||||
l += e->length ();
|
||||
}
|
||||
return check (l);
|
||||
|
|
@ -204,15 +204,15 @@ struct DB_PUBLIC EdgeOrientationFilter
|
|||
/**
|
||||
* @brief Returns true if the edge orientation matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Edge &edge) const;
|
||||
virtual bool selected (const db::Edge &edge, properties_id_type) const;
|
||||
|
||||
/**
|
||||
* @brief Returns true if all edge orientations match the criterion
|
||||
*/
|
||||
virtual bool selected (const std::unordered_set<db::Edge> &edges) const
|
||||
virtual bool selected (const std::unordered_set<db::EdgeWithProperties> &edges) const
|
||||
{
|
||||
for (std::unordered_set<db::Edge>::const_iterator e = edges.begin (); e != edges.end (); ++e) {
|
||||
if (! selected (*e)) {
|
||||
for (std::unordered_set<db::EdgeWithProperties>::const_iterator e = edges.begin (); e != edges.end (); ++e) {
|
||||
if (! selected (*e, e->properties_id ())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -274,15 +274,15 @@ struct DB_PUBLIC SpecialEdgeOrientationFilter
|
|||
/**
|
||||
* @brief Returns true if the edge orientation matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Edge &edge) const;
|
||||
virtual bool selected (const db::Edge &edge, db::properties_id_type) const;
|
||||
|
||||
/**
|
||||
* @brief Returns true if all edge orientations match the criterion
|
||||
*/
|
||||
virtual bool selected (const std::unordered_set<db::Edge> &edges) const
|
||||
virtual bool selected (const std::unordered_set<db::EdgeWithProperties> &edges) const
|
||||
{
|
||||
for (std::unordered_set<db::Edge>::const_iterator e = edges.begin (); e != edges.end (); ++e) {
|
||||
if (! selected (*e)) {
|
||||
for (std::unordered_set<db::EdgeWithProperties>::const_iterator e = edges.begin (); e != edges.end (); ++e) {
|
||||
if (! selected (*e, e->properties_id ())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ FlatEdgePairs::filter_in_place (const EdgePairFilterBase &filter)
|
|||
|
||||
edge_pair_iterator_type pw = ep.get_layer<db::EdgePair, db::unstable_layer_tag> ().begin ();
|
||||
for (EdgePairsIterator p (begin ()); ! p.at_end (); ++p) {
|
||||
if (filter.selected (*p)) {
|
||||
if (filter.selected (*p, p.prop_id ())) {
|
||||
if (pw == ep.get_layer<db::EdgePair, db::unstable_layer_tag> ().end ()) {
|
||||
ep.get_layer<db::EdgePair, db::unstable_layer_tag> ().insert (*p);
|
||||
pw = ep.get_layer<db::EdgePair, db::unstable_layer_tag> ().end ();
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ FlatEdges::filter_in_place (const EdgeFilterBase &filter)
|
|||
edge_iterator_wp_type pw_wp = e.get_layer<db::EdgeWithProperties, db::unstable_layer_tag> ().begin ();
|
||||
|
||||
for (EdgesIterator p (begin_merged ()); ! p.at_end (); ++p) {
|
||||
if (filter.selected (*p)) {
|
||||
if (filter.selected (*p, p.prop_id ())) {
|
||||
if (p.prop_id () != 0) {
|
||||
if (pw_wp == e.get_layer<db::EdgeWithProperties, db::unstable_layer_tag> ().end ()) {
|
||||
e.get_layer<db::EdgeWithProperties, db::unstable_layer_tag> ().insert (db::EdgeWithProperties (*p, p.prop_id ()));
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ RegionDelegate *FlatRegion::filter_in_place (const PolygonFilterBase &filter)
|
|||
polygon_iterator_wp_type pw_wp = poly_layer_wp.begin ();
|
||||
|
||||
for (RegionIterator p (filter.requires_raw_input () ? begin () : begin_merged ()); ! p.at_end (); ++p) {
|
||||
if (filter.selected (*p)) {
|
||||
if (filter.selected (*p, p.prop_id ())) {
|
||||
if (p.prop_id () != 0) {
|
||||
if (pw_wp == poly_layer_wp.end ()) {
|
||||
poly_layer_wp.insert (db::PolygonWithProperties (*p, p.prop_id ()));
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ FlatTexts::filter_in_place (const TextFilterBase &filter)
|
|||
|
||||
text_iterator_type pw = texts.get_layer<db::Text, db::unstable_layer_tag> ().begin ();
|
||||
for (TextsIterator p (begin ()); ! p.at_end (); ++p) {
|
||||
if (filter.selected (*p)) {
|
||||
if (filter.selected (*p, p.prop_id ())) {
|
||||
if (pw == texts.get_layer<db::Text, db::unstable_layer_tag> ().end ()) {
|
||||
texts.get_layer<db::Text, db::unstable_layer_tag> ().insert (*p);
|
||||
pw = texts.get_layer<db::Text, db::unstable_layer_tag> ().end ();
|
||||
|
|
|
|||
|
|
@ -68,25 +68,25 @@ public:
|
|||
* @brief Filters the polygon
|
||||
* If this method returns true, the polygon is kept. Otherwise it's discarded.
|
||||
*/
|
||||
virtual bool selected (const db::Polygon &polygon) const = 0;
|
||||
virtual bool selected (const db::Polygon &polygon, db::properties_id_type prop_id) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Filters the polygon reference
|
||||
* If this method returns true, the polygon is kept. Otherwise it's discarded.
|
||||
*/
|
||||
virtual bool selected (const db::PolygonRef &polygon) const = 0;
|
||||
virtual bool selected (const db::PolygonRef &polygon, db::properties_id_type prop_id) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Filters the set of polygons (taking the overall properties)
|
||||
* If this method returns true, the polygon is kept. Otherwise it's discarded.
|
||||
*/
|
||||
virtual bool selected_set (const std::unordered_set<db::Polygon> &polygons) const = 0;
|
||||
virtual bool selected_set (const std::unordered_set<db::PolygonWithProperties> &polygons) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Filters the set of polygon references (taking the overall properties)
|
||||
* If this method returns true, the polygon is kept. Otherwise it's discarded.
|
||||
*/
|
||||
virtual bool selected_set (const std::unordered_set<db::PolygonRef> &polygons) const = 0;
|
||||
virtual bool selected_set (const std::unordered_set<db::PolygonRefWithProperties> &polygons) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns the transformation reducer for building cell variants
|
||||
|
|
|
|||
|
|
@ -48,29 +48,29 @@ bool RegionPerimeterFilter::check (perimeter_type p) const
|
|||
}
|
||||
}
|
||||
|
||||
bool RegionPerimeterFilter::selected (const db::Polygon &poly) const
|
||||
bool RegionPerimeterFilter::selected (const db::Polygon &poly, db::properties_id_type) const
|
||||
{
|
||||
return check (poly.perimeter ());
|
||||
}
|
||||
|
||||
bool RegionPerimeterFilter::selected (const db::PolygonRef &poly) const
|
||||
bool RegionPerimeterFilter::selected (const db::PolygonRef &poly, db::properties_id_type) const
|
||||
{
|
||||
return check (poly.perimeter ());
|
||||
}
|
||||
|
||||
bool RegionPerimeterFilter::selected_set (const std::unordered_set<db::Polygon> &poly) const
|
||||
bool RegionPerimeterFilter::selected_set (const std::unordered_set<db::PolygonWithProperties> &poly) const
|
||||
{
|
||||
perimeter_type ps = 0;
|
||||
for (std::unordered_set<db::Polygon>::const_iterator p = poly.begin (); p != poly.end (); ++p) {
|
||||
for (std::unordered_set<db::PolygonWithProperties>::const_iterator p = poly.begin (); p != poly.end (); ++p) {
|
||||
ps += p->perimeter ();
|
||||
}
|
||||
return check (ps);
|
||||
}
|
||||
|
||||
bool RegionPerimeterFilter::selected_set (const std::unordered_set<db::PolygonRef> &poly) const
|
||||
bool RegionPerimeterFilter::selected_set (const std::unordered_set<PolygonRefWithProperties> &poly) const
|
||||
{
|
||||
perimeter_type ps = 0;
|
||||
for (std::unordered_set<db::PolygonRef>::const_iterator p = poly.begin (); p != poly.end (); ++p) {
|
||||
for (std::unordered_set<db::PolygonRefWithProperties>::const_iterator p = poly.begin (); p != poly.end (); ++p) {
|
||||
ps += p->perimeter ();
|
||||
}
|
||||
return check (ps);
|
||||
|
|
@ -99,29 +99,29 @@ bool RegionAreaFilter::check (area_type a) const
|
|||
}
|
||||
}
|
||||
|
||||
bool RegionAreaFilter::selected (const db::Polygon &poly) const
|
||||
bool RegionAreaFilter::selected (const db::Polygon &poly, db::properties_id_type) const
|
||||
{
|
||||
return check (poly.area ());
|
||||
}
|
||||
|
||||
bool RegionAreaFilter::selected (const db::PolygonRef &poly) const
|
||||
bool RegionAreaFilter::selected (const db::PolygonRef &poly, properties_id_type) const
|
||||
{
|
||||
return check (poly.area ());
|
||||
}
|
||||
|
||||
bool RegionAreaFilter::selected_set (const std::unordered_set<db::Polygon> &poly) const
|
||||
bool RegionAreaFilter::selected_set (const std::unordered_set<db::PolygonWithProperties> &poly) const
|
||||
{
|
||||
area_type as = 0;
|
||||
for (std::unordered_set<db::Polygon>::const_iterator p = poly.begin (); p != poly.end (); ++p) {
|
||||
for (std::unordered_set<db::PolygonWithProperties>::const_iterator p = poly.begin (); p != poly.end (); ++p) {
|
||||
as += p->area ();
|
||||
}
|
||||
return check (as);
|
||||
}
|
||||
|
||||
bool RegionAreaFilter::selected_set (const std::unordered_set<db::PolygonRef> &poly) const
|
||||
bool RegionAreaFilter::selected_set (const std::unordered_set<db::PolygonRefWithProperties> &poly) const
|
||||
{
|
||||
area_type as = 0;
|
||||
for (std::unordered_set<db::PolygonRef>::const_iterator p = poly.begin (); p != poly.end (); ++p) {
|
||||
for (std::unordered_set<db::PolygonRefWithProperties>::const_iterator p = poly.begin (); p != poly.end (); ++p) {
|
||||
as += p->area ();
|
||||
}
|
||||
return check (as);
|
||||
|
|
@ -143,13 +143,13 @@ RectilinearFilter::RectilinearFilter (bool inverse)
|
|||
}
|
||||
|
||||
bool
|
||||
RectilinearFilter::selected (const db::Polygon &poly) const
|
||||
RectilinearFilter::selected (const db::Polygon &poly, db::properties_id_type) const
|
||||
{
|
||||
return poly.is_rectilinear () != m_inverse;
|
||||
}
|
||||
|
||||
bool
|
||||
RectilinearFilter::selected (const db::PolygonRef &poly) const
|
||||
RectilinearFilter::selected (const db::PolygonRef &poly, db::properties_id_type) const
|
||||
{
|
||||
return poly.is_rectilinear () != m_inverse;
|
||||
}
|
||||
|
|
@ -170,14 +170,14 @@ HoleCountFilter::HoleCountFilter (size_t min_count, size_t max_count, bool inver
|
|||
}
|
||||
|
||||
bool
|
||||
HoleCountFilter::selected (const db::Polygon &poly) const
|
||||
HoleCountFilter::selected (const db::Polygon &poly, db::properties_id_type) const
|
||||
{
|
||||
bool ok = poly.holes () < m_max_count && poly.holes () >= m_min_count;
|
||||
return ok != m_inverse;
|
||||
}
|
||||
|
||||
bool
|
||||
HoleCountFilter::selected (const db::PolygonRef &poly) const
|
||||
HoleCountFilter::selected (const db::PolygonRef &poly, properties_id_type) const
|
||||
{
|
||||
bool ok = poly.obj ().holes () < m_max_count && poly.obj ().holes () >= m_min_count;
|
||||
return ok != m_inverse;
|
||||
|
|
@ -198,7 +198,7 @@ RectangleFilter::RectangleFilter (bool is_square, bool inverse)
|
|||
}
|
||||
|
||||
bool
|
||||
RectangleFilter::selected (const db::Polygon &poly) const
|
||||
RectangleFilter::selected (const db::Polygon &poly, properties_id_type) const
|
||||
{
|
||||
bool ok = poly.is_box ();
|
||||
if (ok && m_is_square) {
|
||||
|
|
@ -209,7 +209,7 @@ RectangleFilter::selected (const db::Polygon &poly) const
|
|||
}
|
||||
|
||||
bool
|
||||
RectangleFilter::selected (const db::PolygonRef &poly) const
|
||||
RectangleFilter::selected (const db::PolygonRef &poly, properties_id_type) const
|
||||
{
|
||||
bool ok = poly.is_box ();
|
||||
if (ok && m_is_square) {
|
||||
|
|
@ -256,13 +256,13 @@ RegionBBoxFilter::check (const db::Box &box) const
|
|||
}
|
||||
|
||||
bool
|
||||
RegionBBoxFilter::selected (const db::Polygon &poly) const
|
||||
RegionBBoxFilter::selected (const db::Polygon &poly, properties_id_type) const
|
||||
{
|
||||
return check (poly.box ());
|
||||
}
|
||||
|
||||
bool
|
||||
RegionBBoxFilter::selected (const db::PolygonRef &poly) const
|
||||
RegionBBoxFilter::selected (const db::PolygonRef &poly, properties_id_type) const
|
||||
{
|
||||
return check (poly.box ());
|
||||
}
|
||||
|
|
@ -322,7 +322,7 @@ static double compute_ratio_parameter (const P &poly, RegionRatioFilter::paramet
|
|||
return v;
|
||||
}
|
||||
|
||||
bool RegionRatioFilter::selected (const db::Polygon &poly) const
|
||||
bool RegionRatioFilter::selected (const db::Polygon &poly, properties_id_type) const
|
||||
{
|
||||
double v = compute_ratio_parameter (poly, m_parameter);
|
||||
|
||||
|
|
@ -330,7 +330,7 @@ bool RegionRatioFilter::selected (const db::Polygon &poly) const
|
|||
return ok != m_inverse;
|
||||
}
|
||||
|
||||
bool RegionRatioFilter::selected (const db::PolygonRef &poly) const
|
||||
bool RegionRatioFilter::selected (const db::PolygonRef &poly, properties_id_type) const
|
||||
{
|
||||
double v = compute_ratio_parameter (poly, m_parameter);
|
||||
|
||||
|
|
|
|||
|
|
@ -57,22 +57,22 @@ struct DB_PUBLIC RegionPerimeterFilter
|
|||
/**
|
||||
* @brief Returns true if the polygon's perimeter matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Polygon &poly) const;
|
||||
virtual bool selected (const db::Polygon &poly, properties_id_type) const;
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon's perimeter matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::PolygonRef &poly) const;
|
||||
virtual bool selected (const db::PolygonRef &poly, properties_id_type) const;
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon's perimeter sum matches the criterion
|
||||
*/
|
||||
virtual bool selected_set (const std::unordered_set<db::PolygonRef> &polygons) const;
|
||||
virtual bool selected_set (const std::unordered_set<db::PolygonRefWithProperties> &polygons) const;
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon's perimeter sum matches the criterion
|
||||
*/
|
||||
virtual bool selected_set (const std::unordered_set<db::Polygon> &polygons) const;
|
||||
virtual bool selected_set (const std::unordered_set<PolygonWithProperties> &polygons) const;
|
||||
|
||||
/**
|
||||
* @brief This filter is isotropic
|
||||
|
|
@ -123,22 +123,22 @@ struct DB_PUBLIC RegionAreaFilter
|
|||
/**
|
||||
* @brief Returns true if the polygon's area matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Polygon &poly) const;
|
||||
virtual bool selected (const db::Polygon &poly, properties_id_type) const;
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon's area matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::PolygonRef &poly) const;
|
||||
virtual bool selected (const db::PolygonRef &poly, properties_id_type) const;
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon's area sum matches the criterion
|
||||
*/
|
||||
virtual bool selected_set (const std::unordered_set<db::PolygonRef> &polygons) const;
|
||||
virtual bool selected_set (const std::unordered_set<db::PolygonRefWithProperties> &polygons) const;
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon's area sum matches the criterion
|
||||
*/
|
||||
virtual bool selected_set (const std::unordered_set<db::Polygon> &polygons) const;
|
||||
virtual bool selected_set (const std::unordered_set<PolygonWithProperties> &polygons) const;
|
||||
|
||||
/**
|
||||
* @brief This filter is isotropic
|
||||
|
|
@ -175,20 +175,20 @@ struct DB_PUBLIC AllMustMatchFilter
|
|||
*/
|
||||
AllMustMatchFilter () { }
|
||||
|
||||
virtual bool selected_set (const std::unordered_set<db::PolygonRef> &polygons) const
|
||||
virtual bool selected_set (const std::unordered_set<db::PolygonRefWithProperties> &polygons) const
|
||||
{
|
||||
for (std::unordered_set<db::PolygonRef>::const_iterator p = polygons.begin (); p != polygons.end (); ++p) {
|
||||
if (! selected (*p)) {
|
||||
for (std::unordered_set<db::PolygonRefWithProperties>::const_iterator p = polygons.begin (); p != polygons.end (); ++p) {
|
||||
if (! selected (*p, p->properties_id ())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool selected_set (const std::unordered_set<db::Polygon> &polygons) const
|
||||
virtual bool selected_set (const std::unordered_set<db::PolygonWithProperties> &polygons) const
|
||||
{
|
||||
for (std::unordered_set<db::Polygon>::const_iterator p = polygons.begin (); p != polygons.end (); ++p) {
|
||||
if (! selected (*p)) {
|
||||
for (std::unordered_set<db::PolygonWithProperties>::const_iterator p = polygons.begin (); p != polygons.end (); ++p) {
|
||||
if (! selected (*p, p->properties_id ())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -215,12 +215,12 @@ struct DB_PUBLIC RectilinearFilter
|
|||
/**
|
||||
* @brief Returns true if the polygon is rectilinear
|
||||
*/
|
||||
virtual bool selected (const db::Polygon &poly) const;
|
||||
virtual bool selected (const db::Polygon &poly, properties_id_type) const;
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon is rectilinear
|
||||
*/
|
||||
virtual bool selected (const db::PolygonRef &poly) const;
|
||||
virtual bool selected (const db::PolygonRef &poly, properties_id_type) const;
|
||||
|
||||
/**
|
||||
* @brief This filter does not need variants
|
||||
|
|
@ -259,12 +259,12 @@ struct DB_PUBLIC RectangleFilter
|
|||
/**
|
||||
* @brief Returns true if the polygon is a rectangle
|
||||
*/
|
||||
virtual bool selected (const db::Polygon &poly) const;
|
||||
virtual bool selected (const db::Polygon &poly, properties_id_type) const;
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon is a rectangle
|
||||
*/
|
||||
virtual bool selected (const db::PolygonRef &poly) const;
|
||||
virtual bool selected (const db::PolygonRef &poly, properties_id_type) const;
|
||||
|
||||
/**
|
||||
* @brief This filter does not need variants
|
||||
|
|
@ -304,12 +304,12 @@ struct DB_PUBLIC HoleCountFilter
|
|||
/**
|
||||
* @brief Returns true if the polygon is a rectangle
|
||||
*/
|
||||
virtual bool selected (const db::Polygon &poly) const;
|
||||
virtual bool selected (const db::Polygon &poly, properties_id_type) const;
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon is a rectangle
|
||||
*/
|
||||
virtual bool selected (const db::PolygonRef &poly) const;
|
||||
virtual bool selected (const db::PolygonRef &poly, properties_id_type) const;
|
||||
|
||||
/**
|
||||
* @brief This filter does not need variants
|
||||
|
|
@ -375,12 +375,12 @@ struct DB_PUBLIC RegionBBoxFilter
|
|||
/**
|
||||
* @brief Returns true if the polygon's bounding box matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Polygon &poly) const;
|
||||
virtual bool selected (const db::Polygon &poly, properties_id_type) const;
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon's bounding box matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::PolygonRef &poly) const;
|
||||
virtual bool selected (const db::PolygonRef &poly, properties_id_type) const;
|
||||
|
||||
/**
|
||||
* @brief This filter is isotropic unless the parameter is width or height
|
||||
|
|
@ -444,12 +444,12 @@ struct DB_PUBLIC RegionRatioFilter
|
|||
/**
|
||||
* @brief Returns true if the polygon's area matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Polygon &poly) const;
|
||||
virtual bool selected (const db::Polygon &poly, properties_id_type) const;
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon's area matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::PolygonRef &poly) const;
|
||||
virtual bool selected (const db::PolygonRef &poly, properties_id_type) const;
|
||||
|
||||
/**
|
||||
* @brief This filter is isotropic unless the parameter is width or height
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public:
|
|||
TextFilterBase () { }
|
||||
virtual ~TextFilterBase () { }
|
||||
|
||||
virtual bool selected (const db::Text &text) const = 0;
|
||||
virtual bool selected (const db::Text &text, db::properties_id_type prop_id) const = 0;
|
||||
virtual const TransformationReducer *vars () const = 0;
|
||||
virtual bool wants_variants () const = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ struct DB_PUBLIC TextStringFilter
|
|||
/**
|
||||
* @brief Returns true if the text matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Text &text) const
|
||||
virtual bool selected (const db::Text &text, db::properties_id_type) const
|
||||
{
|
||||
return (text.string () == m_text) != m_inverse;
|
||||
}
|
||||
|
|
@ -118,7 +118,7 @@ struct DB_PUBLIC TextPatternFilter
|
|||
/**
|
||||
* @brief Returns true if the text matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Text &text) const
|
||||
virtual bool selected (const db::Text &text, db::properties_id_type) const
|
||||
{
|
||||
return m_pattern.match (text.string ()) != m_inverse;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,17 +45,17 @@ class EdgePairFilterImpl
|
|||
public:
|
||||
EdgePairFilterImpl () { }
|
||||
|
||||
bool issue_selected (const db::EdgePair &) const
|
||||
bool issue_selected (const db::EdgePairWithProperties &) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool selected (const db::EdgePair &edge_pair) const
|
||||
virtual bool selected (const db::EdgePair &edge_pair, db::properties_id_type prop_id) const
|
||||
{
|
||||
if (f_selected.can_issue ()) {
|
||||
return f_selected.issue<EdgePairFilterImpl, bool, const db::EdgePair &> (&EdgePairFilterImpl::issue_selected, edge_pair);
|
||||
return f_selected.issue<EdgePairFilterImpl, bool, const db::EdgePairWithProperties &> (&EdgePairFilterImpl::issue_selected, db::EdgePairWithProperties (edge_pair, prop_id));
|
||||
} else {
|
||||
return issue_selected (edge_pair);
|
||||
return issue_selected (db::EdgePairWithProperties (edge_pair, prop_id));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -73,6 +73,8 @@ Class<gsi::EdgePairFilterImpl> decl_EdgePairFilterImpl ("db", "EdgePairFilter",
|
|||
"@brief Selects an edge pair\n"
|
||||
"This method is the actual payload. It needs to be reimplemented in a derived class.\n"
|
||||
"It needs to analyze the edge pair and return 'true' if it should be kept and 'false' if it should be discarded."
|
||||
"\n"
|
||||
"Since version 0.30, the edge pair carries properties."
|
||||
),
|
||||
"@brief A generic edge pair filter adaptor\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -46,26 +46,34 @@ class EdgeFilterImpl
|
|||
public:
|
||||
EdgeFilterImpl () { }
|
||||
|
||||
bool issue_selected (const db::Edge &) const
|
||||
bool issue_selected (const db::EdgeWithProperties &) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool selected (const db::Edge &edge) const
|
||||
virtual bool selected (const db::Edge &edge, db::properties_id_type prop_id) const
|
||||
{
|
||||
if (f_selected.can_issue ()) {
|
||||
return f_selected.issue<EdgeFilterImpl, bool, const db::Edge &> (&EdgeFilterImpl::issue_selected, edge);
|
||||
return f_selected.issue<EdgeFilterImpl, bool, const db::EdgeWithProperties &> (&EdgeFilterImpl::issue_selected, db::EdgeWithProperties (edge, prop_id));
|
||||
} else {
|
||||
return issue_selected (edge);
|
||||
return issue_selected (db::EdgeWithProperties (edge, prop_id));
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if all edges match the criterion
|
||||
virtual bool selected (const std::unordered_set<db::Edge> &edges) const
|
||||
virtual bool selected (const std::unordered_set<db::EdgeWithProperties> &edges) const
|
||||
{
|
||||
for (std::unordered_set<db::Edge>::const_iterator e = edges.begin (); e != edges.end (); ++e) {
|
||||
if (! selected (*e)) {
|
||||
return false;
|
||||
if (f_selected.can_issue ()) {
|
||||
for (std::unordered_set<db::EdgeWithProperties>::const_iterator e = edges.begin (); e != edges.end (); ++e) {
|
||||
if (! f_selected.issue<EdgeFilterImpl, bool, const db::EdgeWithProperties &> (&EdgeFilterImpl::issue_selected, *e)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (std::unordered_set<db::EdgeWithProperties>::const_iterator e = edges.begin (); e != edges.end (); ++e) {
|
||||
if (! issue_selected (*e)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
@ -85,6 +93,8 @@ Class<gsi::EdgeFilterImpl> decl_EdgeFilterImpl ("db", "EdgeFilter",
|
|||
"@brief Selects an edge\n"
|
||||
"This method is the actual payload. It needs to be reimplemented in a derived class.\n"
|
||||
"It needs to analyze the edge and return 'true' if it should be kept and 'false' if it should be discarded."
|
||||
"\n"
|
||||
"Since version 0.30, the edge carries properties."
|
||||
),
|
||||
"@brief A generic edge filter adaptor\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -263,6 +263,26 @@ define_terminal_by_names (GenericDeviceExtractor *extractor, db::Device *device,
|
|||
extractor->define_terminal (device, terminal_id, layer_id, shape);
|
||||
}
|
||||
|
||||
static void error1 (GenericDeviceExtractor *ext, const std::string &message, const db::DPolygonWithProperties &poly)
|
||||
{
|
||||
ext->error (message, poly);
|
||||
}
|
||||
|
||||
static void error2 (GenericDeviceExtractor *ext, const std::string &message, const db::PolygonWithProperties &poly)
|
||||
{
|
||||
ext->error (message, poly);
|
||||
}
|
||||
|
||||
static void warn1 (GenericDeviceExtractor *ext, const std::string &message, const db::DPolygonWithProperties &poly)
|
||||
{
|
||||
ext->warn (message, poly);
|
||||
}
|
||||
|
||||
static void warn2 (GenericDeviceExtractor *ext, const std::string &message, const db::PolygonWithProperties &poly)
|
||||
{
|
||||
ext->warn (message, poly);
|
||||
}
|
||||
|
||||
Class<GenericDeviceExtractor> decl_GenericDeviceExtractor (decl_dbNetlistDeviceExtractor, "db", "GenericDeviceExtractor",
|
||||
gsi::callback ("setup", &GenericDeviceExtractor::setup, &GenericDeviceExtractor::cb_setup,
|
||||
"@brief Sets up the extractor.\n"
|
||||
|
|
@ -397,10 +417,20 @@ Class<GenericDeviceExtractor> decl_GenericDeviceExtractor (decl_dbNetlistDeviceE
|
|||
gsi::arg ("message"), gsi::arg ("geometry"),
|
||||
"@brief Issues an error with the given message and micrometer-units polygon geometry\n"
|
||||
) +
|
||||
gsi::method_ext ("error", &error1,
|
||||
gsi::arg ("message"), gsi::arg ("geometry"),
|
||||
"@brief Issues an error with the given message and micrometer-units polygon geometry with properties\n"
|
||||
"This flavor has been introduced in version 0.30."
|
||||
) +
|
||||
gsi::method ("error", (void (GenericDeviceExtractor::*) (const std::string &, const db::Polygon &)) &GenericDeviceExtractor::error,
|
||||
gsi::arg ("message"), gsi::arg ("geometry"),
|
||||
"@brief Issues an error with the given message and database-unit polygon geometry\n"
|
||||
) +
|
||||
gsi::method_ext ("error", &error2,
|
||||
gsi::arg ("message"), gsi::arg ("geometry"),
|
||||
"@brief Issues an error with the given message and database-units polygon geometry with properties\n"
|
||||
"This flavor has been introduced in version 0.30."
|
||||
) +
|
||||
gsi::method ("error", (void (GenericDeviceExtractor::*) (const std::string &, const std::string &, const std::string &)) &GenericDeviceExtractor::error,
|
||||
gsi::arg ("category_name"), gsi::arg ("category_description"), gsi::arg ("message"),
|
||||
"@brief Issues an error with the given category name and description, message\n"
|
||||
|
|
@ -423,11 +453,21 @@ Class<GenericDeviceExtractor> decl_GenericDeviceExtractor (decl_dbNetlistDeviceE
|
|||
"@brief Issues a warning with the given message and micrometer-units polygon geometry\n"
|
||||
"Warnings have been introduced in version 0.28.13."
|
||||
) +
|
||||
gsi::method_ext ("warn", &warn1,
|
||||
gsi::arg ("message"), gsi::arg ("geometry"),
|
||||
"@brief Issues a warning with the given message and micrometer-units polygon geometry with properties\n"
|
||||
"This flavor has been introduced in version 0.30."
|
||||
) +
|
||||
gsi::method ("warn", (void (GenericDeviceExtractor::*) (const std::string &, const db::Polygon &)) &GenericDeviceExtractor::warn,
|
||||
gsi::arg ("message"), gsi::arg ("geometry"),
|
||||
"@brief Issues a warning with the given message and database-unit polygon geometry\n"
|
||||
"Warnings have been introduced in version 0.28.13."
|
||||
) +
|
||||
gsi::method_ext ("warn", &warn2,
|
||||
gsi::arg ("message"), gsi::arg ("geometry"),
|
||||
"@brief Issues a warning with the given message and database-unit polygon geometry\n"
|
||||
"This flavor has been introduced in version 0.30."
|
||||
) +
|
||||
gsi::method ("warn", (void (GenericDeviceExtractor::*) (const std::string &, const std::string &, const std::string &)) &GenericDeviceExtractor::warn,
|
||||
gsi::arg ("category_name"), gsi::arg ("category_description"), gsi::arg ("message"),
|
||||
"@brief Issues a warning with the given category name and description, message\n"
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "dbRegionProcessors.h"
|
||||
#include "dbCompoundOperation.h"
|
||||
#include "dbLayoutToNetlist.h"
|
||||
#include "dbPropertiesRepository.h"
|
||||
#include "tlGlobPattern.h"
|
||||
|
||||
#include "gsiDeclDbContainerHelpers.h"
|
||||
|
|
@ -50,31 +51,38 @@ namespace gsi
|
|||
// ---------------------------------------------------------------------------------
|
||||
// PolygonFilter binding
|
||||
|
||||
class PolygonFilterImpl
|
||||
class PolygonFilterBase
|
||||
: public shape_filter_impl<db::AllMustMatchFilter>
|
||||
{
|
||||
public:
|
||||
PolygonFilterBase () { }
|
||||
};
|
||||
|
||||
class PolygonFilterImpl
|
||||
: public PolygonFilterBase
|
||||
{
|
||||
public:
|
||||
PolygonFilterImpl () { }
|
||||
|
||||
bool issue_selected (const db::Polygon &) const
|
||||
bool issue_selected (const db::PolygonWithProperties &) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool selected (const db::Polygon &polygon) const
|
||||
virtual bool selected (const db::Polygon &polygon, db::properties_id_type prop_id) const
|
||||
{
|
||||
if (f_selected.can_issue ()) {
|
||||
return f_selected.issue<PolygonFilterImpl, bool, const db::Polygon &> (&PolygonFilterImpl::issue_selected, polygon);
|
||||
return f_selected.issue<PolygonFilterImpl, bool, const db::PolygonWithProperties &> (&PolygonFilterImpl::issue_selected, db::PolygonWithProperties (polygon, prop_id));
|
||||
} else {
|
||||
return issue_selected (polygon);
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool selected (const db::PolygonRef &polygon) const
|
||||
virtual bool selected (const db::PolygonRef &polygon, db::properties_id_type prop_id) const
|
||||
{
|
||||
db::Polygon p;
|
||||
polygon.instantiate (p);
|
||||
return selected (p);
|
||||
return selected (p, prop_id);
|
||||
}
|
||||
|
||||
gsi::Callback f_selected;
|
||||
|
|
@ -85,12 +93,164 @@ private:
|
|||
PolygonFilterImpl (const PolygonFilterImpl &);
|
||||
};
|
||||
|
||||
Class<gsi::PolygonFilterImpl> decl_PolygonFilterImpl ("db", "PolygonFilter",
|
||||
/**
|
||||
* @brief A properties filter
|
||||
*/
|
||||
class PropertiesFilter
|
||||
{
|
||||
public:
|
||||
PropertiesFilter (const tl::Variant &name, const tl::Variant &value, bool inverse)
|
||||
: m_name_id (db::property_names_id (name)), m_value_from (value), m_exact (true), m_glob (false), m_inverse (inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
PropertiesFilter (const tl::Variant &name, const tl::Variant &from, const tl::Variant &to, bool inverse)
|
||||
: m_name_id (db::property_names_id (name)), m_value_from (from), m_value_to (to), m_exact (false), m_glob (false), m_inverse (inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
PropertiesFilter (const tl::Variant &name, const std::string &pattern, bool inverse)
|
||||
: m_name_id (db::property_names_id (name)), m_pattern (pattern), m_exact (true), m_glob (true), m_inverse (inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
bool prop_selected (db::properties_id_type prop_id) const
|
||||
{
|
||||
auto c = m_cache.find (prop_id);
|
||||
if (c != m_cache.end ()) {
|
||||
return c->second;
|
||||
}
|
||||
|
||||
bool res = prop_selected_impl (prop_id);
|
||||
m_cache.insert (std::make_pair (prop_id, res));
|
||||
return res;
|
||||
}
|
||||
|
||||
private:
|
||||
bool prop_selected_impl (db::properties_id_type prop_id) const
|
||||
{
|
||||
const db::PropertiesSet &ps = db::properties (prop_id);
|
||||
if (ps.has_value (m_name_id)) {
|
||||
|
||||
const tl::Variant &value = ps.value (m_name_id);
|
||||
|
||||
if (m_glob) {
|
||||
return m_pattern.match (value.to_string ()) != m_inverse;
|
||||
} else if (m_exact) {
|
||||
return (value == m_value_from) != m_inverse;
|
||||
} else {
|
||||
return ((m_value_from.is_nil () || ! (value < m_value_from)) && (m_value_to.is_nil () || value < m_value_to)) != m_inverse;
|
||||
}
|
||||
|
||||
} else {
|
||||
return m_inverse;
|
||||
}
|
||||
}
|
||||
|
||||
mutable std::map<db::properties_id_type, bool> m_cache;
|
||||
db::property_names_id_type m_name_id;
|
||||
tl::Variant m_value_from, m_value_to;
|
||||
tl::GlobPattern m_pattern;
|
||||
bool m_exact;
|
||||
bool m_glob;
|
||||
bool m_inverse;
|
||||
};
|
||||
|
||||
class PolygonPropertiesFilter
|
||||
: public PolygonFilterBase, public PropertiesFilter
|
||||
{
|
||||
public:
|
||||
PolygonPropertiesFilter (const tl::Variant &name, const std::string &pattern, bool inverse)
|
||||
: PropertiesFilter (name, pattern, inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
PolygonPropertiesFilter (const tl::Variant &name, const tl::Variant &value, bool inverse)
|
||||
: PropertiesFilter (name, value, inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
PolygonPropertiesFilter (const tl::Variant &name, const tl::Variant &from, const tl::Variant &to, bool inverse)
|
||||
: PropertiesFilter (name, from, to, inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
bool selected (const db::Polygon &, db::properties_id_type prop_id) const
|
||||
{
|
||||
return PropertiesFilter::prop_selected (prop_id);
|
||||
}
|
||||
|
||||
bool selected (const db::PolygonRef &, db::properties_id_type prop_id) const
|
||||
{
|
||||
return PropertiesFilter::prop_selected (prop_id);
|
||||
}
|
||||
};
|
||||
|
||||
static PolygonFilterBase *make_ppf1 (const tl::Variant &name, const tl::Variant &value, bool inverse)
|
||||
{
|
||||
return new PolygonPropertiesFilter (name, value, inverse);
|
||||
}
|
||||
|
||||
static PolygonFilterBase *make_ppf2 (const tl::Variant &name, const tl::Variant &from, const tl::Variant &to, bool inverse)
|
||||
{
|
||||
return new PolygonPropertiesFilter (name, from, to, inverse);
|
||||
}
|
||||
|
||||
static PolygonFilterBase *make_pg (const tl::Variant &name, const std::string &glob, bool inverse)
|
||||
{
|
||||
return new PolygonPropertiesFilter (name, glob, inverse);
|
||||
}
|
||||
|
||||
Class<gsi::PolygonFilterBase> decl_PolygonFilterBase ("db", "PolygonFilterBase",
|
||||
gsi::constructor ("property_glob", &make_pg, gsi::arg ("name"), gsi::arg ("pattern"), gsi::arg ("inverse", false),
|
||||
"@brief Creates a single-valued property filter\n"
|
||||
"@param name The name of the property to use.\n"
|
||||
"@param value The glob pattern to match the property value against.\n"
|
||||
"@param inverse If true, inverts the selection - i.e. all polygons without a matching property are selected.\n"
|
||||
"\n"
|
||||
"Apply this filter with \\Region#filtered.\n"
|
||||
"\n"
|
||||
"This feature has been introduced in version 0.30."
|
||||
) +
|
||||
gsi::constructor ("property_filter", &make_ppf1, gsi::arg ("name"), gsi::arg ("value"), gsi::arg ("inverse", false),
|
||||
"@brief Creates a single-valued property filter\n"
|
||||
"@param name The name of the property to use.\n"
|
||||
"@param value The value against which the property is checked (exact match).\n"
|
||||
"@param inverse If true, inverts the selection - i.e. all polygons without a property with the given name and value are selected.\n"
|
||||
"\n"
|
||||
"Apply this filter with \\Region#filtered.\n"
|
||||
"\n"
|
||||
"This feature has been introduced in version 0.30."
|
||||
) +
|
||||
gsi::constructor ("property_filter_bounded", &make_ppf2, gsi::arg ("name"), gsi::arg ("from"), gsi::arg ("to"), gsi::arg ("inverse", false),
|
||||
"@brief Creates a single-valued property filter\n"
|
||||
"@param name The name of the property to use.\n"
|
||||
"@param from The lower value against which the property is checked or 'nil' if no lower bound shall be used.\n"
|
||||
"@param to The upper value against which the property is checked or 'nil' if no upper bound shall be used.\n"
|
||||
"@param inverse If true, inverts the selection - i.e. all polygons without a property with the given name and value range are selected.\n"
|
||||
"\n"
|
||||
"This version does a bounded match. The value of the propery needs to be larger or equal to 'from' and less than 'to'.\n"
|
||||
"Apply this filter with \\Region#filtered.\n"
|
||||
"\n"
|
||||
"This feature has been introduced in version 0.30."
|
||||
),
|
||||
"@hide"
|
||||
);
|
||||
|
||||
Class<gsi::PolygonFilterImpl> decl_PolygonFilterImpl (decl_PolygonFilterBase, "db", "PolygonFilter",
|
||||
PolygonFilterImpl::method_decls (true) +
|
||||
callback ("selected", &PolygonFilterImpl::issue_selected, &PolygonFilterImpl::f_selected, gsi::arg ("polygon"),
|
||||
"@brief Selects a polygon\n"
|
||||
"This method is the actual payload. It needs to be reimplemented in a derived class.\n"
|
||||
"It needs to analyze the polygon and return 'true' if it should be kept and 'false' if it should be discarded."
|
||||
"It needs to analyze the polygon and return 'true' if it should be kept and 'false' if it should be discarded.\n"
|
||||
"\n"
|
||||
"Since version 0.30, the polygon carries properties."
|
||||
),
|
||||
"@brief A generic polygon filter adaptor\n"
|
||||
"\n"
|
||||
|
|
@ -544,12 +704,12 @@ static db::Edges extent_refs_edges (const db::Region *r, double fx1, double fy1,
|
|||
return r->processed (db::RelativeExtentsAsEdges (fx1, fy1, fx2, fy2));
|
||||
}
|
||||
|
||||
static db::Region filtered (const db::Region *r, const PolygonFilterImpl *f)
|
||||
static db::Region filtered (const db::Region *r, const PolygonFilterBase *f)
|
||||
{
|
||||
return r->filtered (*f);
|
||||
}
|
||||
|
||||
static void filter (db::Region *r, const PolygonFilterImpl *f)
|
||||
static void filter (db::Region *r, const PolygonFilterBase *f)
|
||||
{
|
||||
r->filter (*f);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,17 +42,17 @@ class TextFilterImpl
|
|||
public:
|
||||
TextFilterImpl () { }
|
||||
|
||||
bool issue_selected (const db::Text &) const
|
||||
bool issue_selected (const db::TextWithProperties &) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool selected (const db::Text &text) const
|
||||
virtual bool selected (const db::Text &text, db::properties_id_type prop_id) const
|
||||
{
|
||||
if (f_selected.can_issue ()) {
|
||||
return f_selected.issue<TextFilterImpl, bool, const db::Text &> (&TextFilterImpl::issue_selected, text);
|
||||
return f_selected.issue<TextFilterImpl, bool, const db::TextWithProperties &> (&TextFilterImpl::issue_selected, db::TextWithProperties (text, prop_id));
|
||||
} else {
|
||||
return issue_selected (text);
|
||||
return issue_selected (db::TextWithProperties (text, prop_id));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,6 +70,8 @@ Class<gsi::TextFilterImpl> decl_TextFilterImpl ("db", "TextFilter",
|
|||
"@brief Selects a text\n"
|
||||
"This method is the actual payload. It needs to be reimplemented in a derived class.\n"
|
||||
"It needs to analyze the text and return 'true' if it should be kept and 'false' if it should be discarded."
|
||||
"\n"
|
||||
"Since version 0.30, the text carries properties."
|
||||
),
|
||||
"@brief A generic text filter adaptor\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ TEST(2)
|
|||
struct EPTestFilter
|
||||
: public db::EdgePairFilterBase
|
||||
{
|
||||
bool selected (const db::EdgePair &ep) const
|
||||
bool selected (const db::EdgePair &ep, db::properties_id_type) const
|
||||
{
|
||||
return ep.first ().double_length () < 50;
|
||||
}
|
||||
|
|
@ -171,44 +171,44 @@ TEST(5_InternalAngleFilter)
|
|||
db::EdgePair ep90 (db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 0), db::Point (0, 100)));
|
||||
db::EdgePair epm90 (db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 100), db::Point (0, 0)));
|
||||
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (ep0), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (ep180), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (ep90), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (epm90), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (ep45), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (ep0, 0), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (ep180, 0), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (ep90, 0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (epm90, 0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (ep45, 0), false);
|
||||
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (ep0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (ep180), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (ep90), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (epm90), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (ep45), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (ep0, 0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (ep180, 0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (ep90, 0), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (epm90, 0), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (ep45, 0), false);
|
||||
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (ep0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (ep180), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (ep90), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (epm90), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (ep45), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (ep45inv), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (ep0, 0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (ep180, 0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (ep90, 0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (epm90, 0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (ep45, 0), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (ep45inv, 0), true);
|
||||
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (ep0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (ep180), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (ep90), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (epm90), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (ep45), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (ep0, 0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (ep180, 0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (ep90, 0), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (epm90, 0), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (ep45, 0), true);
|
||||
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (ep0), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (ep180), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (ep90), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (epm90), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (ep45), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (ep45inv), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (ep0, 0), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (ep180, 0), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (ep90, 0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (epm90, 0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (ep45, 0), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (ep45inv, 0), true);
|
||||
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, true).selected (ep0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, true).selected (ep180), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, true).selected (ep90), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, true).selected (epm90), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, true).selected (ep45), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, true).selected (ep45inv), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, true).selected (ep0, 0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, true).selected (ep180, 0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, true).selected (ep90, 0), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, true).selected (epm90, 0), true);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, true).selected (ep45, 0), false);
|
||||
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, true).selected (ep45inv, 0), false);
|
||||
}
|
||||
|
||||
TEST(6_add_with_properties)
|
||||
|
|
|
|||
|
|
@ -1583,6 +1583,52 @@ class DBRegion_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
# properties
|
||||
def test_prop_filters
|
||||
|
||||
r = RBA::Region::new
|
||||
r.insert(RBA::PolygonWithProperties::new(RBA::Box::new(0, 0, 100, 200), { "one" => -1 }))
|
||||
r.insert(RBA::PolygonWithProperties::new(RBA::Box::new(1, 1, 101, 201), { "one" => 17 }))
|
||||
r.insert(RBA::PolygonWithProperties::new(RBA::Box::new(2, 2, 102, 202), { "one" => 42 }))
|
||||
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_filter("one", 11)).to_s, "")
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_filter("two", 17)).to_s, "")
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_filter("one", 17)).to_s, "(1,1;1,201;101,201;101,1){one=>17}")
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_filter("one", 17, true)).to_s, "(2,2;2,202;102,202;102,2){one=>42};(0,0;0,200;100,200;100,0){one=>-1}")
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_filter_bounded("one", 17, nil)).to_s, "(1,1;1,201;101,201;101,1){one=>17};(2,2;2,202;102,202;102,2){one=>42}")
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_filter_bounded("one", 17, 18)).to_s, "(1,1;1,201;101,201;101,1){one=>17}")
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_filter_bounded("one", 17, 18, true)).to_s, "(2,2;2,202;102,202;102,2){one=>42};(0,0;0,200;100,200;100,0){one=>-1}")
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_filter_bounded("one", nil, 18)).to_s, "(1,1;1,201;101,201;101,1){one=>17};(0,0;0,200;100,200;100,0){one=>-1}")
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_glob("one", "1*")).to_s, "(1,1;1,201;101,201;101,1){one=>17}")
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_glob("one", "1*", true)).to_s, "(2,2;2,202;102,202;102,2){one=>42};(0,0;0,200;100,200;100,0){one=>-1}")
|
||||
|
||||
ly = RBA::Layout::new
|
||||
top = ly.create_cell("TOP")
|
||||
l1 = ly.layer(1, 0)
|
||||
|
||||
s = top.shapes(l1)
|
||||
s.insert(RBA::PolygonWithProperties::new(RBA::Box::new(0, 0, 100, 200), { "one" => -1 }))
|
||||
s.insert(RBA::PolygonWithProperties::new(RBA::Box::new(1, 1, 101, 201), { "one" => 17 }))
|
||||
s.insert(RBA::PolygonWithProperties::new(RBA::Box::new(2, 2, 102, 202), { "one" => 42 }))
|
||||
|
||||
dss = RBA::DeepShapeStore::new
|
||||
iter = top.begin_shapes_rec(l1)
|
||||
iter.enable_properties()
|
||||
r = RBA::Region::new(iter, dss)
|
||||
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_filter("one", 11)).to_s, "")
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_filter("two", 17)).to_s, "")
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_filter("one", 17)).to_s, "(1,1;1,201;101,201;101,1){one=>17}")
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_filter("one", 17, true)).to_s, "(0,0;0,200;100,200;100,0){one=>-1};(2,2;2,202;102,202;102,2){one=>42}")
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_filter_bounded("one", 17, nil)).to_s, "(1,1;1,201;101,201;101,1){one=>17};(2,2;2,202;102,202;102,2){one=>42}")
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_filter_bounded("one", 17, 18)).to_s, "(1,1;1,201;101,201;101,1){one=>17}")
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_filter_bounded("one", 17, 18, true)).to_s, "(0,0;0,200;100,200;100,0){one=>-1};(2,2;2,202;102,202;102,2){one=>42}")
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_filter_bounded("one", nil, 18)).to_s, "(0,0;0,200;100,200;100,0){one=>-1};(1,1;1,201;101,201;101,1){one=>17}")
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_glob("one", "1*")).to_s, "(1,1;1,201;101,201;101,1){one=>17}")
|
||||
assert_equal(r.filtered(RBA::PolygonFilter::property_glob("one", "1*", true)).to_s, "(0,0;0,200;100,200;100,0){one=>-1};(2,2;2,202;102,202;102,2){one=>42}")
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
load("test_epilogue.rb")
|
||||
|
|
|
|||
Loading…
Reference in New Issue