mirror of https://github.com/KLayout/klayout.git
Some more refactoring - generalized polygon processing in region.
This commit is contained in:
parent
2e9fb9fe9a
commit
0f2d0605a9
|
|
@ -926,41 +926,57 @@ DeepRegion::processed (const PolygonProcessorBase &filter) const
|
||||||
|
|
||||||
vars->collect (m_deep_layer.layout (), m_deep_layer.initial_cell ());
|
vars->collect (m_deep_layer.layout (), m_deep_layer.initial_cell ());
|
||||||
|
|
||||||
const_cast<db::DeepLayer &> (m_deep_layer).separate_variants (*vars);
|
if (filter.wants_variants ()) {
|
||||||
|
const_cast<db::DeepLayer &> (m_deep_layer).separate_variants (*vars);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
db::Layout &layout = const_cast<db::Layout &> (m_deep_layer.layout ());
|
db::Layout &layout = const_cast<db::Layout &> (m_deep_layer.layout ());
|
||||||
|
|
||||||
std::vector<db::Polygon> poly_res;
|
std::vector<db::Polygon> poly_res;
|
||||||
|
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > to_commit;
|
||||||
|
|
||||||
std::auto_ptr<db::DeepRegion> res (new db::DeepRegion (m_deep_layer.derived ()));
|
std::auto_ptr<db::DeepRegion> res (new db::DeepRegion (m_deep_layer.derived ()));
|
||||||
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
|
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
|
||||||
|
|
||||||
const db::Shapes &s = c->shapes (filter.requires_raw_input () ? m_deep_layer.layer () : m_merged_polygons.layer ());
|
const db::Shapes &s = c->shapes (filter.requires_raw_input () ? m_deep_layer.layer () : m_merged_polygons.layer ());
|
||||||
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
|
||||||
db::PolygonRefToShapesGenerator pr (&layout, &st);
|
|
||||||
|
|
||||||
if (vars.get ()) {
|
if (vars.get ()) {
|
||||||
|
|
||||||
const std::map<db::ICplxTrans, size_t> &v = vars->variants (c->cell_index ());
|
const std::map<db::ICplxTrans, size_t> &vv = vars->variants (c->cell_index ());
|
||||||
tl_assert (v.size () == size_t (1));
|
for (std::map<db::ICplxTrans, size_t>::const_iterator v = vv.begin (); v != vv.end (); ++v) {
|
||||||
const db::ICplxTrans &tr = v.begin ()->first;
|
|
||||||
db::ICplxTrans trinv = tr.inverted ();
|
|
||||||
|
|
||||||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) {
|
db::Shapes *st;
|
||||||
db::Polygon poly;
|
if (vv.size () == 1) {
|
||||||
si->polygon (poly);
|
st = & c->shapes (res->deep_layer ().layer ());
|
||||||
poly.transform (tr);
|
} else {
|
||||||
poly_res.clear ();
|
st = & to_commit [c->cell_index ()] [v->first];
|
||||||
filter.process (poly, poly_res);
|
|
||||||
for (std::vector<db::Polygon>::const_iterator p = poly_res.begin (); p != poly_res.end (); ++p) {
|
|
||||||
pr.put (p->transformed (trinv));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db::PolygonRefToShapesGenerator pr (&layout, st);
|
||||||
|
|
||||||
|
const db::ICplxTrans &tr = v->first;
|
||||||
|
db::ICplxTrans trinv = tr.inverted ();
|
||||||
|
|
||||||
|
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) {
|
||||||
|
db::Polygon poly;
|
||||||
|
si->polygon (poly);
|
||||||
|
poly.transform (tr);
|
||||||
|
poly_res.clear ();
|
||||||
|
filter.process (poly, poly_res);
|
||||||
|
for (std::vector<db::Polygon>::const_iterator p = poly_res.begin (); p != poly_res.end (); ++p) {
|
||||||
|
pr.put (p->transformed (trinv));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
||||||
|
db::PolygonRefToShapesGenerator pr (&layout, &st);
|
||||||
|
|
||||||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) {
|
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) {
|
||||||
db::Polygon poly;
|
db::Polygon poly;
|
||||||
si->polygon (poly);
|
si->polygon (poly);
|
||||||
|
|
@ -975,6 +991,10 @@ DeepRegion::processed (const PolygonProcessorBase &filter) const
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! to_commit.empty () && vars.get ()) {
|
||||||
|
res->deep_layer ().commit_shapes (*vars, to_commit);
|
||||||
|
}
|
||||||
|
|
||||||
if (filter.result_is_merged ()) {
|
if (filter.result_is_merged ()) {
|
||||||
res->set_is_merged (true);
|
res->set_is_merged (true);
|
||||||
}
|
}
|
||||||
|
|
@ -991,45 +1011,58 @@ DeepRegion::filter_in_place (const PolygonFilterBase &filter)
|
||||||
RegionDelegate *
|
RegionDelegate *
|
||||||
DeepRegion::filtered (const PolygonFilterBase &filter) const
|
DeepRegion::filtered (const PolygonFilterBase &filter) const
|
||||||
{
|
{
|
||||||
ensure_merged_polygons_valid ();
|
if (! filter.requires_raw_input ()) {
|
||||||
|
ensure_merged_polygons_valid ();
|
||||||
|
}
|
||||||
|
|
||||||
std::auto_ptr<VariantsCollectorBase> vars;
|
std::auto_ptr<VariantsCollectorBase> vars;
|
||||||
if (filter.vars ()) {
|
if (filter.vars ()) {
|
||||||
|
|
||||||
vars.reset (new db::VariantsCollectorBase (filter.vars ()));
|
vars.reset (new db::VariantsCollectorBase (filter.vars ()));
|
||||||
|
|
||||||
vars->collect (m_merged_polygons.layout (), m_merged_polygons.initial_cell ());
|
vars->collect (m_deep_layer.layout (), m_deep_layer.initial_cell ());
|
||||||
|
|
||||||
// NOTE: m_merged_polygons is mutable, so why is the const_cast needed?
|
// 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.wants_variants ()) {
|
||||||
|
const_cast<db::DeepLayer &> (m_deep_layer).separate_variants (*vars);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
db::Layout &layout = m_merged_polygons.layout ();
|
db::Layout &layout = const_cast<db::Layout &> (m_deep_layer.layout ());
|
||||||
|
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > to_commit;
|
||||||
|
|
||||||
std::auto_ptr<db::DeepRegion> res (new db::DeepRegion (m_merged_polygons.derived ()));
|
std::auto_ptr<db::DeepRegion> res (new db::DeepRegion (m_deep_layer.derived ()));
|
||||||
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
|
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
|
||||||
|
|
||||||
const db::Shapes &s = c->shapes (m_merged_polygons.layer ());
|
const db::Shapes &s = c->shapes (filter.requires_raw_input () ? m_deep_layer.layer () : m_merged_polygons.layer ());
|
||||||
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
|
||||||
|
|
||||||
if (vars.get ()) {
|
if (vars.get ()) {
|
||||||
|
|
||||||
const std::map<db::ICplxTrans, size_t> &v = vars->variants (c->cell_index ());
|
const std::map<db::ICplxTrans, size_t> &vv = vars->variants (c->cell_index ());
|
||||||
tl_assert (v.size () == size_t (1));
|
for (std::map<db::ICplxTrans, size_t>::const_iterator v = vv.begin (); v != vv.end (); ++v) {
|
||||||
const db::ICplxTrans &tr = v.begin ()->first;
|
|
||||||
|
|
||||||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) {
|
db::Shapes *st;
|
||||||
db::Polygon poly;
|
if (vv.size () == 1) {
|
||||||
si->polygon (poly);
|
st = & c->shapes (res->deep_layer ().layer ());
|
||||||
if (filter.selected (poly.transformed (tr))) {
|
} else {
|
||||||
st.insert (*si);
|
st = & to_commit [c->cell_index ()] [v->first];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const db::ICplxTrans &tr = v->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 (*si);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
const db::Shapes &s = c->shapes (m_merged_polygons.layer ());
|
|
||||||
db::Shapes &st = c->shapes (res->deep_layer ().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) {
|
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) {
|
||||||
|
|
@ -1044,7 +1077,13 @@ DeepRegion::filtered (const PolygonFilterBase &filter) const
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res->set_is_merged (true);
|
if (! to_commit.empty () && vars.get ()) {
|
||||||
|
res->deep_layer ().commit_shapes (*vars, to_commit);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! filter.requires_raw_input ()) {
|
||||||
|
res->set_is_merged (true);
|
||||||
|
}
|
||||||
return res.release ();
|
return res.release ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ public:
|
||||||
virtual const TransformationReducer *vars () const { return 0; }
|
virtual const TransformationReducer *vars () const { return 0; }
|
||||||
virtual bool result_is_merged () const { return false; }
|
virtual bool result_is_merged () const { return false; }
|
||||||
virtual bool requires_raw_input () const { return true; }
|
virtual bool requires_raw_input () const { return true; }
|
||||||
|
virtual bool wants_variants () const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------
|
||||||
|
|
@ -88,6 +89,7 @@ public:
|
||||||
virtual const TransformationReducer *vars () const { return &m_vars; }
|
virtual const TransformationReducer *vars () const { return &m_vars; }
|
||||||
virtual bool result_is_merged () const { return false; }
|
virtual bool result_is_merged () const { return false; }
|
||||||
virtual bool requires_raw_input () const { return false; }
|
virtual bool requires_raw_input () const { return false; }
|
||||||
|
virtual bool wants_variants () const { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
db::Coord m_d;
|
db::Coord m_d;
|
||||||
|
|
@ -113,6 +115,7 @@ public:
|
||||||
virtual const TransformationReducer *vars () const { return &m_vars; }
|
virtual const TransformationReducer *vars () const { return &m_vars; }
|
||||||
virtual bool result_is_merged () const { return true; } // we believe so ...
|
virtual bool result_is_merged () const { return true; } // we believe so ...
|
||||||
virtual bool requires_raw_input () const { return false; }
|
virtual bool requires_raw_input () const { return false; }
|
||||||
|
virtual bool wants_variants () const { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double m_rinner, m_router;
|
double m_rinner, m_router;
|
||||||
|
|
@ -140,6 +143,7 @@ public:
|
||||||
virtual const TransformationReducer *vars () const { return 0; }
|
virtual const TransformationReducer *vars () const { return 0; }
|
||||||
virtual bool result_is_merged () const { return true; } // we believe so ...
|
virtual bool result_is_merged () const { return true; } // we believe so ...
|
||||||
virtual bool requires_raw_input () const { return false; }
|
virtual bool requires_raw_input () const { return false; }
|
||||||
|
virtual bool wants_variants () const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------
|
||||||
|
|
@ -160,6 +164,7 @@ public:
|
||||||
virtual const TransformationReducer *vars () const { return 0; }
|
virtual const TransformationReducer *vars () const { return 0; }
|
||||||
virtual bool result_is_merged () const { return true; } // we believe so ...
|
virtual bool result_is_merged () const { return true; } // we believe so ...
|
||||||
virtual bool requires_raw_input () const { return false; }
|
virtual bool requires_raw_input () const { return false; }
|
||||||
|
virtual bool wants_variants () const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,11 +44,35 @@ class EdgeFilterBase;
|
||||||
class DB_PUBLIC PolygonFilterBase
|
class DB_PUBLIC PolygonFilterBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
*/
|
||||||
PolygonFilterBase () { }
|
PolygonFilterBase () { }
|
||||||
|
|
||||||
virtual ~PolygonFilterBase () { }
|
virtual ~PolygonFilterBase () { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the transformation reducer for building cell variants
|
||||||
|
* This method may return 0. In this case, not cell variants are built.
|
||||||
|
*/
|
||||||
virtual const TransformationReducer *vars () const = 0;
|
virtual const TransformationReducer *vars () const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns true, if the filter wants raw (not merged) input
|
||||||
|
*/
|
||||||
|
virtual bool requires_raw_input () const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns true, if the filter wants to build variants
|
||||||
|
* If not true, the filter accepts shape propagation as variant resolution.
|
||||||
|
*/
|
||||||
|
virtual bool wants_variants () const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -57,13 +81,41 @@ public:
|
||||||
class DB_PUBLIC PolygonProcessorBase
|
class DB_PUBLIC PolygonProcessorBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
*/
|
||||||
PolygonProcessorBase () { }
|
PolygonProcessorBase () { }
|
||||||
|
|
||||||
virtual ~PolygonProcessorBase () { }
|
virtual ~PolygonProcessorBase () { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Performs the actual processing
|
||||||
|
* This method will take the input polygon from "polygon" and puts the results into "res".
|
||||||
|
* "res" can be empty - in this case, the polygon will be skipped.
|
||||||
|
*/
|
||||||
virtual void process (const db::Polygon &polygon, std::vector<db::Polygon> &res) const = 0;
|
virtual void process (const db::Polygon &polygon, std::vector<db::Polygon> &res) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the transformation reducer for building cell variants
|
||||||
|
* This method may return 0. In this case, not cell variants are built.
|
||||||
|
*/
|
||||||
virtual const TransformationReducer *vars () const = 0;
|
virtual const TransformationReducer *vars () const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns true, if the result of this operation can be regarded "merged" always.
|
||||||
|
*/
|
||||||
virtual bool result_is_merged () const = 0;
|
virtual bool result_is_merged () const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns true, if the processor wants raw (not merged) input
|
||||||
|
*/
|
||||||
virtual bool requires_raw_input () const = 0;
|
virtual bool requires_raw_input () const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns true, if the processor wants to build variants
|
||||||
|
* If not true, the processor accepts shape propagation as variant resolution.
|
||||||
|
*/
|
||||||
|
virtual bool wants_variants () const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,16 @@ struct DB_PUBLIC RegionPerimeterFilter
|
||||||
return &m_vars;
|
return &m_vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This filter prefers producing variants
|
||||||
|
*/
|
||||||
|
virtual bool wants_variants () const { return true; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This filter wants merged input
|
||||||
|
*/
|
||||||
|
virtual bool requires_raw_input () const { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
perimeter_type m_pmin, m_pmax;
|
perimeter_type m_pmin, m_pmax;
|
||||||
bool m_inverse;
|
bool m_inverse;
|
||||||
|
|
@ -137,6 +147,16 @@ struct DB_PUBLIC RegionAreaFilter
|
||||||
return &m_vars;
|
return &m_vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This filter prefers producing variants
|
||||||
|
*/
|
||||||
|
virtual bool wants_variants () const { return true; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This filter wants merged input
|
||||||
|
*/
|
||||||
|
virtual bool requires_raw_input () const { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
area_type m_amin, m_amax;
|
area_type m_amin, m_amax;
|
||||||
bool m_inverse;
|
bool m_inverse;
|
||||||
|
|
@ -178,6 +198,16 @@ struct DB_PUBLIC RectilinearFilter
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This filter prefers producing variants
|
||||||
|
*/
|
||||||
|
virtual bool wants_variants () const { return true; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This filter wants merged input
|
||||||
|
*/
|
||||||
|
virtual bool requires_raw_input () const { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_inverse;
|
bool m_inverse;
|
||||||
};
|
};
|
||||||
|
|
@ -217,6 +247,16 @@ struct DB_PUBLIC RectangleFilter
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This filter prefers producing variants
|
||||||
|
*/
|
||||||
|
virtual bool wants_variants () const { return true; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This filter wants merged input
|
||||||
|
*/
|
||||||
|
virtual bool requires_raw_input () const { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_inverse;
|
bool m_inverse;
|
||||||
};
|
};
|
||||||
|
|
@ -303,6 +343,16 @@ struct DB_PUBLIC RegionBBoxFilter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This filter prefers producing variants
|
||||||
|
*/
|
||||||
|
virtual bool wants_variants () const { return true; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This filter wants merged input
|
||||||
|
*/
|
||||||
|
virtual bool requires_raw_input () const { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
value_type m_vmin, m_vmax;
|
value_type m_vmin, m_vmax;
|
||||||
bool m_inverse;
|
bool m_inverse;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue