mirror of https://github.com/KLayout/klayout.git
Refactoring: new concept for edge/polygon filters
This commit is contained in:
parent
7143e75310
commit
90c1d212a4
|
|
@ -169,7 +169,9 @@ SOURCES = \
|
|||
dbNetlistWriter.cc \
|
||||
dbCellVariants.cc \
|
||||
dbDeepEdges.cc \
|
||||
dbDeepEdgePairs.cc
|
||||
dbDeepEdgePairs.cc \
|
||||
dbRegionUtils.cc \
|
||||
dbEdgesUtils.cc
|
||||
|
||||
HEADERS = \
|
||||
dbArray.h \
|
||||
|
|
@ -303,7 +305,9 @@ HEADERS = \
|
|||
dbNetlistWriter.h \
|
||||
dbCellVariants.h \
|
||||
dbDeepEdges.h \
|
||||
dbDeepEdgePairs.h
|
||||
dbDeepEdgePairs.h \
|
||||
dbRegionUtils.h \
|
||||
dbEdgesUtils.h
|
||||
|
||||
!equals(HAVE_QT, "0") {
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ VariantsCollectorBase::VariantsCollectorBase ()
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
VariantsCollectorBase::VariantsCollectorBase (TransformationReducer *red)
|
||||
VariantsCollectorBase::VariantsCollectorBase (const TransformationReducer *red)
|
||||
: mp_red (red)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
|
|
@ -42,7 +42,7 @@ VariantsCollectorBase::VariantsCollectorBase (TransformationReducer *red)
|
|||
void
|
||||
VariantsCollectorBase::collect (const db::Layout &layout, const db::Cell &top_cell)
|
||||
{
|
||||
tl_assert (mp_red.get () != 0);
|
||||
tl_assert (mp_red != 0);
|
||||
|
||||
// The top cell gets a "variant" with unit transformation
|
||||
m_variants [top_cell.cell_index ()].insert (std::make_pair (db::ICplxTrans (), 1));
|
||||
|
|
@ -78,7 +78,7 @@ VariantsCollectorBase::collect (const db::Layout &layout, const db::Cell &top_ce
|
|||
void
|
||||
VariantsCollectorBase::separate_variants (db::Layout &layout, db::Cell &top_cell, std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > *var_table)
|
||||
{
|
||||
tl_assert (mp_red.get () != 0);
|
||||
tl_assert (mp_red != 0);
|
||||
|
||||
db::LayoutLocker locker (&layout);
|
||||
|
||||
|
|
@ -177,6 +177,8 @@ VariantsCollectorBase::separate_variants (db::Layout &layout, db::Cell &top_cell
|
|||
void
|
||||
VariantsCollectorBase::commit_shapes (db::Layout &layout, db::Cell &top_cell, unsigned int layer, std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > &to_commit)
|
||||
{
|
||||
tl_assert (mp_red != 0);
|
||||
|
||||
if (to_commit.empty ()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,8 +44,9 @@ namespace db
|
|||
*
|
||||
* reduce(A*B) = reduce(reduce(A)*reduce(B))
|
||||
*/
|
||||
struct DB_PUBLIC TransformationReducer
|
||||
class DB_PUBLIC TransformationReducer
|
||||
{
|
||||
public:
|
||||
TransformationReducer () { }
|
||||
virtual ~TransformationReducer () { }
|
||||
|
||||
|
|
@ -183,10 +184,8 @@ public:
|
|||
|
||||
/**
|
||||
* @brief Creates a variant collector with the given reducer
|
||||
*
|
||||
* The collector will take ownership over the reducer
|
||||
*/
|
||||
VariantsCollectorBase (TransformationReducer *red);
|
||||
VariantsCollectorBase (const TransformationReducer *red);
|
||||
|
||||
/**
|
||||
* @brief Collects cell variants for the given layout starting from the top cell
|
||||
|
|
@ -228,7 +227,7 @@ public:
|
|||
|
||||
private:
|
||||
std::map<db::cell_index_type, std::map<db::ICplxTrans, size_t> > m_variants;
|
||||
std::auto_ptr<TransformationReducer> mp_red;
|
||||
const TransformationReducer *mp_red;
|
||||
|
||||
void add_variant (std::map<db::ICplxTrans, size_t> &variants, const db::CellInstArray &inst, bool tl_invariant) const;
|
||||
void add_variant_non_tl_invariant (std::map<db::ICplxTrans, size_t> &variants, const db::CellInstArray &inst) const;
|
||||
|
|
@ -252,7 +251,7 @@ public:
|
|||
* @brief Creates a variant collector without a transformation reducer
|
||||
*/
|
||||
cell_variants_collector ()
|
||||
: VariantsCollectorBase (new RED ())
|
||||
: VariantsCollectorBase (&m_red)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -263,10 +262,13 @@ public:
|
|||
* The collector will take ownership over the reducer
|
||||
*/
|
||||
cell_variants_collector (const RED &red)
|
||||
: VariantsCollectorBase (new RED (red))
|
||||
: VariantsCollectorBase (&m_red), m_red (red)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
private:
|
||||
RED m_red;
|
||||
};
|
||||
|
||||
} // namespace db
|
||||
|
|
|
|||
|
|
@ -488,34 +488,50 @@ EdgesDelegate *DeepEdges::filtered (const EdgeFilterBase &filter) const
|
|||
|
||||
std::auto_ptr<VariantsCollectorBase> vars;
|
||||
|
||||
if (filter.isotropic ()) {
|
||||
vars.reset (new db::cell_variants_collector<db::MagnificationReducer> ());
|
||||
} else {
|
||||
vars.reset (new db::cell_variants_collector<db::MagnificationAndOrientationReducer> ());
|
||||
if (filter.vars ()) {
|
||||
|
||||
vars.reset (new db::VariantsCollectorBase (filter.vars ()));
|
||||
|
||||
vars->collect (m_merged_edges.layout (), m_merged_edges.initial_cell ());
|
||||
|
||||
// NOTE: m_merged_polygons is mutable, so why is the const_cast needed?
|
||||
const_cast<db::DeepLayer &> (m_merged_edges).separate_variants (*vars);
|
||||
|
||||
}
|
||||
|
||||
vars->collect (m_merged_edges.layout (), m_merged_edges.initial_cell ());
|
||||
|
||||
// NOTE: m_merged_polygons is mutable, so why is the const_cast needed?
|
||||
const_cast<db::DeepLayer &> (m_merged_edges).separate_variants (*vars);
|
||||
|
||||
db::Layout &layout = m_merged_edges.layout ();
|
||||
|
||||
std::auto_ptr<db::DeepEdges> res (new db::DeepEdges (m_merged_edges.derived ()));
|
||||
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
|
||||
|
||||
const std::map<db::ICplxTrans, size_t> &v = vars->variants (c->cell_index ());
|
||||
tl_assert (v.size () == size_t (1));
|
||||
const db::ICplxTrans &tr = v.begin ()->first;
|
||||
if (vars.get ()) {
|
||||
|
||||
const db::Shapes &s = c->shapes (m_merged_edges.layer ());
|
||||
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
||||
const std::map<db::ICplxTrans, size_t> &v = vars->variants (c->cell_index ());
|
||||
tl_assert (v.size () == size_t (1));
|
||||
const db::ICplxTrans &tr = v.begin ()->first;
|
||||
|
||||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Edges); ! si.at_end (); ++si) {
|
||||
db::Edge edge = si->edge ();
|
||||
if (filter.selected (edge.transformed (tr))) {
|
||||
st.insert (edge);
|
||||
const db::Shapes &s = c->shapes (m_merged_edges.layer ());
|
||||
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
||||
|
||||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Edges); ! si.at_end (); ++si) {
|
||||
db::Edge edge = si->edge ();
|
||||
if (filter.selected (edge.transformed (tr))) {
|
||||
st.insert (edge);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
const db::Shapes &s = c->shapes (m_merged_edges.layer ());
|
||||
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
||||
|
||||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Edges); ! si.at_end (); ++si) {
|
||||
db::Edge edge = si->edge ();
|
||||
if (filter.selected (edge)) {
|
||||
st.insert (edge);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -857,13 +857,9 @@ DeepRegion::edges (const EdgeFilterBase *filter) const
|
|||
|
||||
std::auto_ptr<VariantsCollectorBase> vars;
|
||||
|
||||
if (filter) {
|
||||
if (filter && filter->vars ()) {
|
||||
|
||||
if (filter->isotropic ()) {
|
||||
vars.reset (new db::cell_variants_collector<db::MagnificationReducer> ());
|
||||
} else {
|
||||
vars.reset (new db::cell_variants_collector<db::MagnificationAndOrientationReducer> ());
|
||||
}
|
||||
vars.reset (new db::VariantsCollectorBase (filter->vars ()));
|
||||
|
||||
vars->collect (m_merged_polygons.layout (), m_merged_polygons.initial_cell ());
|
||||
|
||||
|
|
@ -919,36 +915,52 @@ DeepRegion::filtered (const PolygonFilterBase &filter) const
|
|||
ensure_merged_polygons_valid ();
|
||||
|
||||
std::auto_ptr<VariantsCollectorBase> vars;
|
||||
if (filter.vars ()) {
|
||||
|
||||
vars.reset (new db::VariantsCollectorBase (filter.vars ()));
|
||||
|
||||
vars->collect (m_merged_polygons.layout (), m_merged_polygons.initial_cell ());
|
||||
|
||||
// NOTE: m_merged_polygons is mutable, so why is the const_cast needed?
|
||||
const_cast<db::DeepLayer &> (m_merged_polygons).separate_variants (*vars);
|
||||
|
||||
if (filter.isotropic ()) {
|
||||
vars.reset (new db::cell_variants_collector<db::MagnificationReducer> ());
|
||||
} else {
|
||||
vars.reset (new db::cell_variants_collector<db::MagnificationAndOrientationReducer> ());
|
||||
}
|
||||
|
||||
vars->collect (m_merged_polygons.layout (), m_merged_polygons.initial_cell ());
|
||||
|
||||
// NOTE: m_merged_polygons is mutable, so why is the const_cast needed?
|
||||
const_cast<db::DeepLayer &> (m_merged_polygons).separate_variants (*vars);
|
||||
|
||||
db::Layout &layout = m_merged_polygons.layout ();
|
||||
|
||||
std::auto_ptr<db::DeepRegion> res (new db::DeepRegion (m_merged_polygons.derived ()));
|
||||
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
|
||||
|
||||
const std::map<db::ICplxTrans, size_t> &v = vars->variants (c->cell_index ());
|
||||
tl_assert (v.size () == size_t (1));
|
||||
const db::ICplxTrans &tr = v.begin ()->first;
|
||||
if (vars.get ()) {
|
||||
|
||||
const db::Shapes &s = c->shapes (m_merged_polygons.layer ());
|
||||
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
||||
const std::map<db::ICplxTrans, size_t> &v = vars->variants (c->cell_index ());
|
||||
tl_assert (v.size () == size_t (1));
|
||||
const db::ICplxTrans &tr = v.begin ()->first;
|
||||
|
||||
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 (tr))) {
|
||||
st.insert (poly);
|
||||
const db::Shapes &s = c->shapes (m_merged_polygons.layer ());
|
||||
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
||||
|
||||
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 (tr))) {
|
||||
st.insert (poly);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
const db::Shapes &s = c->shapes (m_merged_polygons.layer ());
|
||||
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
||||
|
||||
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)) {
|
||||
st.insert (poly);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "dbCommon.h"
|
||||
#include "dbEdgesDelegate.h"
|
||||
#include "dbRecursiveShapeIterator.h"
|
||||
#include "dbCellVariants.h"
|
||||
|
||||
#include "gsiObject.h"
|
||||
|
||||
|
|
@ -209,135 +210,7 @@ public:
|
|||
virtual ~EdgeFilterBase () { }
|
||||
|
||||
virtual bool selected (const db::Edge &edge) const = 0;
|
||||
virtual bool isotropic () const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An edge length filter for use with Edges::filter or Edges::filtered
|
||||
*
|
||||
* This filter has two parameters: lmin and lmax.
|
||||
* It will filter all edges for which the length is >= lmin and < lmax.
|
||||
* There is an "invert" flag which allows to select all edges not
|
||||
* matching the criterion.
|
||||
*/
|
||||
|
||||
struct DB_PUBLIC EdgeLengthFilter
|
||||
: public EdgeFilterBase
|
||||
{
|
||||
typedef db::Edge::distance_type length_type;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param lmin The minimum length
|
||||
* @param lmax The maximum length
|
||||
* @param inverse If set to true, only polygons not matching this criterion will be filtered
|
||||
*/
|
||||
EdgeLengthFilter (length_type lmin, length_type lmax, bool inverse)
|
||||
: m_lmin (lmin), m_lmax (lmax), m_inverse (inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the edge length matches the criterion
|
||||
*/
|
||||
bool selected (const db::Edge &edge) const
|
||||
{
|
||||
length_type l = edge.length ();
|
||||
if (! m_inverse) {
|
||||
return l >= m_lmin && l < m_lmax;
|
||||
} else {
|
||||
return ! (l >= m_lmin && l < m_lmax);
|
||||
}
|
||||
}
|
||||
|
||||
bool isotropic () const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
length_type m_lmin, m_lmax;
|
||||
bool m_inverse;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An edge orientation filter for use with Edges::filter or Edges::filtered
|
||||
*
|
||||
* This filter has two parameters: amin and amax.
|
||||
* It will filter all edges for which the orientation angle is >= amin and < amax.
|
||||
* The orientation angle is measured in degree against the x axis in the mathematical sense.
|
||||
* There is an "invert" flag which allows to select all edges not
|
||||
* matching the criterion.
|
||||
*/
|
||||
|
||||
struct DB_PUBLIC EdgeOrientationFilter
|
||||
: public EdgeFilterBase
|
||||
{
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param amin The minimum angle (measured against the x axis)
|
||||
* @param amax The maximum angle (measured against the x axis)
|
||||
* @param inverse If set to true, only edges not matching this criterion will be filtered
|
||||
*
|
||||
* This filter will filter out all edges whose angle against x axis
|
||||
* is larger or equal to amin and less than amax.
|
||||
*/
|
||||
EdgeOrientationFilter (double amin, double amax, bool inverse)
|
||||
: m_inverse (inverse), m_exact (false)
|
||||
{
|
||||
m_emin = db::DVector (cos (amin * M_PI / 180.0), sin (amin * M_PI / 180.0));
|
||||
m_emax = db::DVector (cos (amax * M_PI / 180.0), sin (amax * M_PI / 180.0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param a The angle (measured against the x axis)
|
||||
* @param inverse If set to true, only edges not matching this criterion will be filtered
|
||||
*
|
||||
* This filter will filter out all edges whose angle against x axis
|
||||
* is equal to a.
|
||||
*/
|
||||
EdgeOrientationFilter (double a, bool inverse)
|
||||
: m_inverse (inverse), m_exact (true)
|
||||
{
|
||||
m_emin = db::DVector (cos (a * M_PI / 180.0), sin (a * M_PI / 180.0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the edge orientation matches the criterion
|
||||
*/
|
||||
bool selected (const db::Edge &edge) const
|
||||
{
|
||||
int smin = db::vprod_sign (m_emin, db::DVector (edge.d ()));
|
||||
if (m_exact) {
|
||||
if (! m_inverse) {
|
||||
return smin == 0;
|
||||
} else {
|
||||
return smin != 0;
|
||||
}
|
||||
} else {
|
||||
int smax = db::vprod_sign (m_emax, db::DVector (edge.d ()));
|
||||
if (! m_inverse) {
|
||||
return (smin >= 0 && smax < 0) || (smax > 0 && smin <= 0);
|
||||
} else {
|
||||
return ! ((smin >= 0 && smax < 0) || (smax > 0 && smin <= 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isotropic () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
db::DVector m_emin, m_emax;
|
||||
bool m_inverse;
|
||||
bool m_exact;
|
||||
virtual const TransformationReducer *vars () const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,169 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2019 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_dbEdgesUtils
|
||||
#define HDR_dbEdgesUtils
|
||||
|
||||
#include "dbCommon.h"
|
||||
#include "dbEdges.h"
|
||||
|
||||
namespace db {
|
||||
|
||||
/**
|
||||
* @brief An edge length filter for use with Edges::filter or Edges::filtered
|
||||
*
|
||||
* This filter has two parameters: lmin and lmax.
|
||||
* It will filter all edges for which the length is >= lmin and < lmax.
|
||||
* There is an "invert" flag which allows to select all edges not
|
||||
* matching the criterion.
|
||||
*/
|
||||
|
||||
struct DB_PUBLIC EdgeLengthFilter
|
||||
: public EdgeFilterBase
|
||||
{
|
||||
typedef db::Edge::distance_type length_type;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param lmin The minimum length
|
||||
* @param lmax The maximum length
|
||||
* @param inverse If set to true, only polygons not matching this criterion will be filtered
|
||||
*/
|
||||
EdgeLengthFilter (length_type lmin, length_type lmax, bool inverse)
|
||||
: m_lmin (lmin), m_lmax (lmax), m_inverse (inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the edge length matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Edge &edge) const
|
||||
{
|
||||
length_type l = edge.length ();
|
||||
if (! m_inverse) {
|
||||
return l >= m_lmin && l < m_lmax;
|
||||
} else {
|
||||
return ! (l >= m_lmin && l < m_lmax);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This filter is isotropic
|
||||
*/
|
||||
virtual const TransformationReducer *vars () const
|
||||
{
|
||||
return &m_vars;
|
||||
}
|
||||
|
||||
private:
|
||||
length_type m_lmin, m_lmax;
|
||||
bool m_inverse;
|
||||
db::MagnificationReducer m_vars;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An edge orientation filter for use with Edges::filter or Edges::filtered
|
||||
*
|
||||
* This filter has two parameters: amin and amax.
|
||||
* It will filter all edges for which the orientation angle is >= amin and < amax.
|
||||
* The orientation angle is measured in degree against the x axis in the mathematical sense.
|
||||
* There is an "invert" flag which allows to select all edges not
|
||||
* matching the criterion.
|
||||
*/
|
||||
|
||||
struct DB_PUBLIC EdgeOrientationFilter
|
||||
: public EdgeFilterBase
|
||||
{
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param amin The minimum angle (measured against the x axis)
|
||||
* @param amax The maximum angle (measured against the x axis)
|
||||
* @param inverse If set to true, only edges not matching this criterion will be filtered
|
||||
*
|
||||
* This filter will filter out all edges whose angle against x axis
|
||||
* is larger or equal to amin and less than amax.
|
||||
*/
|
||||
EdgeOrientationFilter (double amin, double amax, bool inverse)
|
||||
: m_inverse (inverse), m_exact (false)
|
||||
{
|
||||
m_emin = db::DVector (cos (amin * M_PI / 180.0), sin (amin * M_PI / 180.0));
|
||||
m_emax = db::DVector (cos (amax * M_PI / 180.0), sin (amax * M_PI / 180.0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param a The angle (measured against the x axis)
|
||||
* @param inverse If set to true, only edges not matching this criterion will be filtered
|
||||
*
|
||||
* This filter will filter out all edges whose angle against x axis
|
||||
* is equal to a.
|
||||
*/
|
||||
EdgeOrientationFilter (double a, bool inverse)
|
||||
: m_inverse (inverse), m_exact (true)
|
||||
{
|
||||
m_emin = db::DVector (cos (a * M_PI / 180.0), sin (a * M_PI / 180.0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the edge orientation matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Edge &edge) const
|
||||
{
|
||||
int smin = db::vprod_sign (m_emin, db::DVector (edge.d ()));
|
||||
if (m_exact) {
|
||||
if (! m_inverse) {
|
||||
return smin == 0;
|
||||
} else {
|
||||
return smin != 0;
|
||||
}
|
||||
} else {
|
||||
int smax = db::vprod_sign (m_emax, db::DVector (edge.d ()));
|
||||
if (! m_inverse) {
|
||||
return (smin >= 0 && smax < 0) || (smax > 0 && smin <= 0);
|
||||
} else {
|
||||
return ! ((smin >= 0 && smax < 0) || (smax > 0 && smin <= 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This filter is not isotropic
|
||||
*/
|
||||
virtual const TransformationReducer *vars () const
|
||||
{
|
||||
return &m_vars;
|
||||
}
|
||||
|
||||
private:
|
||||
db::DVector m_emin, m_emax;
|
||||
bool m_inverse;
|
||||
bool m_exact;
|
||||
db::MagnificationAndOrientationReducer m_vars;
|
||||
};
|
||||
|
||||
} // namespace db
|
||||
|
||||
#endif
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
#include "dbRegionDelegate.h"
|
||||
#include "dbRecursiveShapeIterator.h"
|
||||
#include "dbPolygonGenerators.h"
|
||||
#include "dbCellVariants.h"
|
||||
|
||||
#include "gsiObject.h"
|
||||
|
||||
|
|
@ -39,6 +40,7 @@ class EdgeFilterBase;
|
|||
class FlatRegion;
|
||||
class EmptyRegion;
|
||||
class DeepShapeStore;
|
||||
class TransformationReducer;
|
||||
|
||||
/**
|
||||
* @brief A base class for polygon filters
|
||||
|
|
@ -49,280 +51,8 @@ public:
|
|||
PolygonFilterBase () { }
|
||||
virtual ~PolygonFilterBase () { }
|
||||
|
||||
virtual bool selected (const db::Polygon &polgon) const = 0;
|
||||
virtual bool isotropic () const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A perimeter filter for use with Region::filter or Region::filtered
|
||||
*
|
||||
* This filter has two parameters: pmin and pmax.
|
||||
* It will filter all polygons for which the perimeter is >= pmin and < pmax.
|
||||
* There is an "invert" flag which allows to select all polygons not
|
||||
* matching the criterion.
|
||||
*/
|
||||
|
||||
struct DB_PUBLIC RegionPerimeterFilter
|
||||
: public PolygonFilterBase
|
||||
{
|
||||
typedef db::coord_traits<db::Coord>::perimeter_type perimeter_type;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param amin The min perimeter (only polygons above this value are filtered)
|
||||
* @param amax The maximum perimeter (only polygons with a perimeter below this value are filtered)
|
||||
* @param inverse If set to true, only polygons not matching this criterion will be filtered
|
||||
*/
|
||||
RegionPerimeterFilter (perimeter_type pmin, perimeter_type pmax, bool inverse)
|
||||
: m_pmin (pmin), m_pmax (pmax), m_inverse (inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon's perimeter matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Polygon &poly) const
|
||||
{
|
||||
perimeter_type p = 0;
|
||||
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end () && p < m_pmax; ++e) {
|
||||
p += (*e).length ();
|
||||
}
|
||||
|
||||
if (! m_inverse) {
|
||||
return p >= m_pmin && p < m_pmax;
|
||||
} else {
|
||||
return ! (p >= m_pmin && p < m_pmax);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This filter is isotropic
|
||||
*/
|
||||
virtual bool isotropic () const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
perimeter_type m_pmin, m_pmax;
|
||||
bool m_inverse;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An area filter for use with Region::filter or Region::filtered
|
||||
*
|
||||
* This filter has two parameters: amin and amax.
|
||||
* It will filter all polygons for which the area is >= amin and < amax.
|
||||
* There is an "invert" flag which allows to select all polygons not
|
||||
* matching the criterion.
|
||||
*/
|
||||
|
||||
struct DB_PUBLIC RegionAreaFilter
|
||||
: public PolygonFilterBase
|
||||
{
|
||||
typedef db::Polygon::area_type area_type;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param amin The min area (only polygons above this value are filtered)
|
||||
* @param amax The maximum area (only polygons with an area below this value are filtered)
|
||||
* @param inverse If set to true, only polygons not matching this criterion will be filtered
|
||||
*/
|
||||
RegionAreaFilter (area_type amin, area_type amax, bool inverse)
|
||||
: m_amin (amin), m_amax (amax), m_inverse (inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon's area matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Polygon &poly) const
|
||||
{
|
||||
area_type a = poly.area ();
|
||||
if (! m_inverse) {
|
||||
return a >= m_amin && a < m_amax;
|
||||
} else {
|
||||
return ! (a >= m_amin && a < m_amax);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This filter is isotropic
|
||||
*/
|
||||
virtual bool isotropic () const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
area_type m_amin, m_amax;
|
||||
bool m_inverse;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A filter for rectilinear polygons
|
||||
*
|
||||
* This filter will select all polygons which are rectilinear.
|
||||
*/
|
||||
|
||||
struct DB_PUBLIC RectilinearFilter
|
||||
: public PolygonFilterBase
|
||||
{
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param inverse If set to true, only polygons not matching this criterion will be filtered
|
||||
*/
|
||||
RectilinearFilter (bool inverse)
|
||||
: m_inverse (inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon's area matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Polygon &poly) const
|
||||
{
|
||||
return poly.is_rectilinear () != m_inverse;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This filter is isotropic
|
||||
*/
|
||||
virtual bool isotropic () const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_inverse;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A rectangle filter
|
||||
*
|
||||
* This filter will select all polygons which are rectangles.
|
||||
*/
|
||||
|
||||
struct DB_PUBLIC RectangleFilter
|
||||
: public PolygonFilterBase
|
||||
{
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param inverse If set to true, only polygons not matching this criterion will be filtered
|
||||
*/
|
||||
RectangleFilter (bool inverse)
|
||||
: m_inverse (inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon's area matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Polygon &poly) const
|
||||
{
|
||||
return poly.is_box () != m_inverse;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This filter is isotropic
|
||||
*/
|
||||
virtual bool isotropic () const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_inverse;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A bounding box filter for use with Region::filter or Region::filtered
|
||||
*
|
||||
* This filter has two parameters: vmin and vmax.
|
||||
* It will filter all polygons for which the selected bounding box parameter is >= vmin and < vmax.
|
||||
* There is an "invert" flag which allows to select all polygons not
|
||||
* matching the criterion.
|
||||
*
|
||||
* For bounding box parameters the following choices are available:
|
||||
* - (BoxWidth) width
|
||||
* - (BoxHeight) height
|
||||
* - (BoxMaxDim) maximum of width and height
|
||||
* - (BoxMinDim) minimum of width and height
|
||||
* - (BoxAverageDim) average of width and height
|
||||
*/
|
||||
|
||||
struct DB_PUBLIC RegionBBoxFilter
|
||||
: public PolygonFilterBase
|
||||
{
|
||||
typedef db::Box::distance_type value_type;
|
||||
|
||||
/**
|
||||
* @brief The parameters available
|
||||
*/
|
||||
enum parameter_type {
|
||||
BoxWidth,
|
||||
BoxHeight,
|
||||
BoxMaxDim,
|
||||
BoxMinDim,
|
||||
BoxAverageDim
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param vmin The min value (only polygons with bounding box parameters above this value are filtered)
|
||||
* @param vmax The max value (only polygons with bounding box parameters below this value are filtered)
|
||||
* @param inverse If set to true, only polygons not matching this criterion will be filtered
|
||||
*/
|
||||
RegionBBoxFilter (value_type vmin, value_type vmax, bool inverse, parameter_type parameter)
|
||||
: m_vmin (vmin), m_vmax (vmax), m_inverse (inverse), m_parameter (parameter)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon's area matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Polygon &poly) const
|
||||
{
|
||||
value_type v = 0;
|
||||
db::Box box = poly.box ();
|
||||
if (m_parameter == BoxWidth) {
|
||||
v = box.width ();
|
||||
} else if (m_parameter == BoxHeight) {
|
||||
v = box.height ();
|
||||
} else if (m_parameter == BoxMinDim) {
|
||||
v = std::min (box.width (), box.height ());
|
||||
} else if (m_parameter == BoxMaxDim) {
|
||||
v = std::max (box.width (), box.height ());
|
||||
} else if (m_parameter == BoxAverageDim) {
|
||||
v = (box.width () + box.height ()) / 2;
|
||||
}
|
||||
if (! m_inverse) {
|
||||
return v >= m_vmin && v < m_vmax;
|
||||
} else {
|
||||
return ! (v >= m_vmin && v < m_vmax);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This filter is isotropic unless the parameter is width or height
|
||||
*/
|
||||
virtual bool isotropic () const
|
||||
{
|
||||
return m_parameter != BoxWidth && m_parameter != BoxHeight;
|
||||
}
|
||||
|
||||
private:
|
||||
value_type m_vmin, m_vmax;
|
||||
bool m_inverse;
|
||||
parameter_type m_parameter;
|
||||
virtual bool selected (const db::Polygon &polygon) const = 0;
|
||||
virtual const TransformationReducer *vars () const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2019 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 "dbRegionUtils.h"
|
||||
|
||||
namespace db {
|
||||
|
||||
// .. nothing yet ..
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,316 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2019 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_dbRegionUtils
|
||||
#define HDR_dbRegionUtils
|
||||
|
||||
#include "dbCommon.h"
|
||||
#include "dbRegion.h"
|
||||
#include "dbCellVariants.h"
|
||||
|
||||
namespace db {
|
||||
|
||||
/**
|
||||
* @brief A perimeter filter for use with Region::filter or Region::filtered
|
||||
*
|
||||
* This filter has two parameters: pmin and pmax.
|
||||
* It will filter all polygons for which the perimeter is >= pmin and < pmax.
|
||||
* There is an "invert" flag which allows to select all polygons not
|
||||
* matching the criterion.
|
||||
*/
|
||||
|
||||
struct DB_PUBLIC RegionPerimeterFilter
|
||||
: public PolygonFilterBase
|
||||
{
|
||||
typedef db::coord_traits<db::Coord>::perimeter_type perimeter_type;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param amin The min perimeter (only polygons above this value are filtered)
|
||||
* @param amax The maximum perimeter (only polygons with a perimeter below this value are filtered)
|
||||
* @param inverse If set to true, only polygons not matching this criterion will be filtered
|
||||
*/
|
||||
RegionPerimeterFilter (perimeter_type pmin, perimeter_type pmax, bool inverse)
|
||||
: m_pmin (pmin), m_pmax (pmax), m_inverse (inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon's perimeter matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Polygon &poly) const
|
||||
{
|
||||
perimeter_type p = 0;
|
||||
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end () && p < m_pmax; ++e) {
|
||||
p += (*e).length ();
|
||||
}
|
||||
|
||||
if (! m_inverse) {
|
||||
return p >= m_pmin && p < m_pmax;
|
||||
} else {
|
||||
return ! (p >= m_pmin && p < m_pmax);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This filter is isotropic
|
||||
*/
|
||||
virtual const TransformationReducer *vars () const
|
||||
{
|
||||
return &m_vars;
|
||||
}
|
||||
|
||||
private:
|
||||
perimeter_type m_pmin, m_pmax;
|
||||
bool m_inverse;
|
||||
db::MagnificationReducer m_vars;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An area filter for use with Region::filter or Region::filtered
|
||||
*
|
||||
* This filter has two parameters: amin and amax.
|
||||
* It will filter all polygons for which the area is >= amin and < amax.
|
||||
* There is an "invert" flag which allows to select all polygons not
|
||||
* matching the criterion.
|
||||
*/
|
||||
|
||||
struct DB_PUBLIC RegionAreaFilter
|
||||
: public PolygonFilterBase
|
||||
{
|
||||
typedef db::Polygon::area_type area_type;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param amin The min area (only polygons above this value are filtered)
|
||||
* @param amax The maximum area (only polygons with an area below this value are filtered)
|
||||
* @param inverse If set to true, only polygons not matching this criterion will be filtered
|
||||
*/
|
||||
RegionAreaFilter (area_type amin, area_type amax, bool inverse)
|
||||
: m_amin (amin), m_amax (amax), m_inverse (inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon's area matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Polygon &poly) const
|
||||
{
|
||||
area_type a = poly.area ();
|
||||
if (! m_inverse) {
|
||||
return a >= m_amin && a < m_amax;
|
||||
} else {
|
||||
return ! (a >= m_amin && a < m_amax);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This filter is isotropic
|
||||
*/
|
||||
virtual const TransformationReducer *vars () const
|
||||
{
|
||||
return &m_vars;
|
||||
}
|
||||
|
||||
private:
|
||||
area_type m_amin, m_amax;
|
||||
bool m_inverse;
|
||||
db::MagnificationReducer m_vars;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A filter for rectilinear polygons
|
||||
*
|
||||
* This filter will select all polygons which are rectilinear.
|
||||
*/
|
||||
|
||||
struct DB_PUBLIC RectilinearFilter
|
||||
: public PolygonFilterBase
|
||||
{
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param inverse If set to true, only polygons not matching this criterion will be filtered
|
||||
*/
|
||||
RectilinearFilter (bool inverse)
|
||||
: m_inverse (inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon's area matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Polygon &poly) const
|
||||
{
|
||||
return poly.is_rectilinear () != m_inverse;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This filter does not need variants
|
||||
*/
|
||||
virtual const TransformationReducer *vars () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_inverse;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A rectangle filter
|
||||
*
|
||||
* This filter will select all polygons which are rectangles.
|
||||
*/
|
||||
|
||||
struct DB_PUBLIC RectangleFilter
|
||||
: public PolygonFilterBase
|
||||
{
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param inverse If set to true, only polygons not matching this criterion will be filtered
|
||||
*/
|
||||
RectangleFilter (bool inverse)
|
||||
: m_inverse (inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon's area matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Polygon &poly) const
|
||||
{
|
||||
return poly.is_box () != m_inverse;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This filter does not need variants
|
||||
*/
|
||||
virtual const TransformationReducer *vars () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_inverse;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A bounding box filter for use with Region::filter or Region::filtered
|
||||
*
|
||||
* This filter has two parameters: vmin and vmax.
|
||||
* It will filter all polygons for which the selected bounding box parameter is >= vmin and < vmax.
|
||||
* There is an "invert" flag which allows to select all polygons not
|
||||
* matching the criterion.
|
||||
*
|
||||
* For bounding box parameters the following choices are available:
|
||||
* - (BoxWidth) width
|
||||
* - (BoxHeight) height
|
||||
* - (BoxMaxDim) maximum of width and height
|
||||
* - (BoxMinDim) minimum of width and height
|
||||
* - (BoxAverageDim) average of width and height
|
||||
*/
|
||||
|
||||
struct DB_PUBLIC RegionBBoxFilter
|
||||
: public PolygonFilterBase
|
||||
{
|
||||
typedef db::Box::distance_type value_type;
|
||||
|
||||
/**
|
||||
* @brief The parameters available
|
||||
*/
|
||||
enum parameter_type {
|
||||
BoxWidth,
|
||||
BoxHeight,
|
||||
BoxMaxDim,
|
||||
BoxMinDim,
|
||||
BoxAverageDim
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param vmin The min value (only polygons with bounding box parameters above this value are filtered)
|
||||
* @param vmax The max value (only polygons with bounding box parameters below this value are filtered)
|
||||
* @param inverse If set to true, only polygons not matching this criterion will be filtered
|
||||
*/
|
||||
RegionBBoxFilter (value_type vmin, value_type vmax, bool inverse, parameter_type parameter)
|
||||
: m_vmin (vmin), m_vmax (vmax), m_inverse (inverse), m_parameter (parameter)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the polygon's area matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Polygon &poly) const
|
||||
{
|
||||
value_type v = 0;
|
||||
db::Box box = poly.box ();
|
||||
if (m_parameter == BoxWidth) {
|
||||
v = box.width ();
|
||||
} else if (m_parameter == BoxHeight) {
|
||||
v = box.height ();
|
||||
} else if (m_parameter == BoxMinDim) {
|
||||
v = std::min (box.width (), box.height ());
|
||||
} else if (m_parameter == BoxMaxDim) {
|
||||
v = std::max (box.width (), box.height ());
|
||||
} else if (m_parameter == BoxAverageDim) {
|
||||
v = (box.width () + box.height ()) / 2;
|
||||
}
|
||||
if (! m_inverse) {
|
||||
return v >= m_vmin && v < m_vmax;
|
||||
} else {
|
||||
return ! (v >= m_vmin && v < m_vmax);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This filter is isotropic unless the parameter is width or height
|
||||
*/
|
||||
virtual const TransformationReducer *vars () const
|
||||
{
|
||||
if (m_parameter != BoxWidth && m_parameter != BoxHeight) {
|
||||
return &m_isotropic_vars;
|
||||
} else {
|
||||
return &m_anisotropic_vars;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
value_type m_vmin, m_vmax;
|
||||
bool m_inverse;
|
||||
parameter_type m_parameter;
|
||||
db::MagnificationReducer m_isotropic_vars;
|
||||
db::MagnificationAndOrientationReducer m_anisotropic_vars;
|
||||
};
|
||||
|
||||
} // namespace db
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "dbDeepShapeStore.h"
|
||||
#include "dbEdges.h"
|
||||
#include "dbEdgesUtils.h"
|
||||
#include "dbDeepEdges.h"
|
||||
#include "dbRegion.h"
|
||||
#include "dbLayoutUtils.h"
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "gsiDecl.h"
|
||||
|
||||
#include "dbRegion.h"
|
||||
#include "dbRegionUtils.h"
|
||||
#include "dbDeepRegion.h"
|
||||
#include "dbPolygonTools.h"
|
||||
#include "dbLayoutUtils.h"
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "dbTestSupport.h"
|
||||
#include "dbEdges.h"
|
||||
#include "dbRegion.h"
|
||||
#include "dbEdgesUtils.h"
|
||||
#include "dbDeepShapeStore.h"
|
||||
#include "tlUnitTest.h"
|
||||
#include "tlStream.h"
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
#include "dbTestSupport.h"
|
||||
#include "dbRegion.h"
|
||||
#include "dbEdges.h"
|
||||
#include "dbRegionUtils.h"
|
||||
#include "dbEdgesUtils.h"
|
||||
#include "dbDeepShapeStore.h"
|
||||
#include "tlUnitTest.h"
|
||||
#include "tlStream.h"
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "tlUnitTest.h"
|
||||
|
||||
#include "dbEdges.h"
|
||||
#include "dbEdgesUtils.h"
|
||||
#include "dbPolygonTools.h"
|
||||
#include "dbRegion.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
#include "tlUnitTest.h"
|
||||
|
||||
#include "dbRegion.h"
|
||||
#include "dbRegionUtils.h"
|
||||
#include "dbEdgesUtils.h"
|
||||
#include "dbBoxScanner.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
|
|
|||
Loading…
Reference in New Issue