mirror of https://github.com/KLayout/klayout.git
Fixed 'scale_and_snap' feature
This commit is contained in:
parent
4924d0269c
commit
318efbf7b0
|
|
@ -22,11 +22,124 @@
|
||||||
|
|
||||||
|
|
||||||
#include "dbCellVariants.h"
|
#include "dbCellVariants.h"
|
||||||
|
#include "dbRegionUtils.h"
|
||||||
#include "tlUtils.h"
|
#include "tlUtils.h"
|
||||||
|
|
||||||
namespace db
|
namespace db
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
db::ICplxTrans OrientationReducer::reduce (const db::ICplxTrans &trans) const
|
||||||
|
{
|
||||||
|
db::ICplxTrans res (trans);
|
||||||
|
res.disp (db::Vector ());
|
||||||
|
res.mag (1.0);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
db::Trans OrientationReducer::reduce (const db::Trans &trans) const
|
||||||
|
{
|
||||||
|
return db::Trans (trans.fp_trans ());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
db::ICplxTrans MagnificationReducer::reduce (const db::ICplxTrans &trans) const
|
||||||
|
{
|
||||||
|
return db::ICplxTrans (trans.mag ());
|
||||||
|
}
|
||||||
|
|
||||||
|
db::Trans MagnificationReducer::reduce (const db::Trans &) const
|
||||||
|
{
|
||||||
|
return db::Trans ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
db::ICplxTrans MagnificationAndOrientationReducer::reduce (const db::ICplxTrans &trans) const
|
||||||
|
{
|
||||||
|
db::ICplxTrans res (trans);
|
||||||
|
res.disp (db::Vector ());
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
db::Trans MagnificationAndOrientationReducer::reduce (const db::Trans &trans) const
|
||||||
|
{
|
||||||
|
return db::Trans (trans.fp_trans ());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
GridReducer::GridReducer (db::Coord grid)
|
||||||
|
: m_grid (grid)
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
|
db::ICplxTrans GridReducer::reduce (const db::ICplxTrans &trans) const
|
||||||
|
{
|
||||||
|
// NOTE: we need to keep magnification, angle and mirror so when combining the
|
||||||
|
// reduced transformations, the result will be equivalent to reducing the combined
|
||||||
|
// transformation.
|
||||||
|
db::ICplxTrans res (trans);
|
||||||
|
res.disp (db::Vector (trans.disp ().x () - snap_to_grid (trans.disp ().x (), m_grid), trans.disp ().y () - snap_to_grid (trans.disp ().y (), m_grid)));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
db::Trans GridReducer::reduce (const db::Trans &trans) const
|
||||||
|
{
|
||||||
|
db::Trans res (trans);
|
||||||
|
res.disp (db::Vector (trans.disp ().x () - snap_to_grid (trans.disp ().x (), m_grid), trans.disp ().y () - snap_to_grid (trans.disp ().y (), m_grid)));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ScaleAndGridReducer::ScaleAndGridReducer (db::Coord grid, db::Coord mult, db::Coord div)
|
||||||
|
: m_mult (mult), m_grid (int64_t (grid) * int64_t (div))
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
|
db::ICplxTrans ScaleAndGridReducer::reduce_trans (const db::ICplxTrans &trans) const
|
||||||
|
{
|
||||||
|
db::ICplxTrans res (trans);
|
||||||
|
int64_t dx = int64_t (trans.disp ().x ()) * m_mult;
|
||||||
|
int64_t dy = int64_t (trans.disp ().y ()) * m_mult;
|
||||||
|
res.disp (db::Vector (db::Coord (dx - snap_to_grid (dx, m_grid)), db::Coord (dy - snap_to_grid (dy, m_grid))));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
db::Trans ScaleAndGridReducer::reduce_trans (const db::Trans &trans) const
|
||||||
|
{
|
||||||
|
db::Trans res (trans);
|
||||||
|
int64_t dx = int64_t (trans.disp ().x ()) * m_mult;
|
||||||
|
int64_t dy = int64_t (trans.disp ().y ()) * m_mult;
|
||||||
|
res.disp (db::Vector (db::Coord (dx - snap_to_grid (dx, m_grid)), db::Coord (dy - snap_to_grid (dy, m_grid))));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
db::ICplxTrans ScaleAndGridReducer::reduce (const db::ICplxTrans &trans) const
|
||||||
|
{
|
||||||
|
db::ICplxTrans res (trans);
|
||||||
|
int64_t dx = int64_t (trans.disp ().x ());
|
||||||
|
int64_t dy = int64_t (trans.disp ().y ());
|
||||||
|
res.disp (db::Vector (db::Coord (dx - snap_to_grid (dx, m_grid)), db::Coord (dy - snap_to_grid (dy, m_grid))));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
db::Trans ScaleAndGridReducer::reduce (const db::Trans &trans) const
|
||||||
|
{
|
||||||
|
db::Trans res (trans);
|
||||||
|
int64_t dx = int64_t (trans.disp ().x ());
|
||||||
|
int64_t dy = int64_t (trans.disp ().y ());
|
||||||
|
res.disp (db::Vector (db::Coord (dx - snap_to_grid (dx, m_grid)), db::Coord (dy - snap_to_grid (dy, m_grid))));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
VariantsCollectorBase::VariantsCollectorBase ()
|
VariantsCollectorBase::VariantsCollectorBase ()
|
||||||
: mp_red ()
|
: mp_red ()
|
||||||
{
|
{
|
||||||
|
|
@ -219,7 +332,7 @@ VariantsCollectorBase::commit_shapes (db::Layout &layout, db::Cell &top_cell, un
|
||||||
for (db::CellInstArray::iterator ia = i->begin (); ! ia.at_end (); ++ia) {
|
for (db::CellInstArray::iterator ia = i->begin (); ! ia.at_end (); ++ia) {
|
||||||
|
|
||||||
db::ICplxTrans t = i->complex_trans (*ia);
|
db::ICplxTrans t = i->complex_trans (*ia);
|
||||||
db::ICplxTrans rt = mp_red->reduce (vc->first * t);
|
db::ICplxTrans rt = mp_red->reduce (vc->first * mp_red->reduce_trans (t));
|
||||||
std::map<db::ICplxTrans, db::Shapes>::const_iterator v = vt.find (rt);
|
std::map<db::ICplxTrans, db::Shapes>::const_iterator v = vt.find (rt);
|
||||||
if (v != vt.end ()) {
|
if (v != vt.end ()) {
|
||||||
|
|
||||||
|
|
@ -263,7 +376,7 @@ VariantsCollectorBase::commit_shapes (db::Layout &layout, db::Cell &top_cell, un
|
||||||
for (db::CellInstArray::iterator ia = i->begin (); ! ia.at_end (); ++ia) {
|
for (db::CellInstArray::iterator ia = i->begin (); ! ia.at_end (); ++ia) {
|
||||||
|
|
||||||
db::ICplxTrans t = i->complex_trans (*ia);
|
db::ICplxTrans t = i->complex_trans (*ia);
|
||||||
db::ICplxTrans rt = mp_red->reduce (vvc.begin ()->first * t);
|
db::ICplxTrans rt = mp_red->reduce (vvc.begin ()->first * mp_red->reduce_trans (t));
|
||||||
std::map<db::ICplxTrans, db::Shapes>::const_iterator v = vt.find (rt);
|
std::map<db::ICplxTrans, db::Shapes>::const_iterator v = vt.find (rt);
|
||||||
|
|
||||||
if (v != vt.end ()) {
|
if (v != vt.end ()) {
|
||||||
|
|
@ -325,11 +438,11 @@ VariantsCollectorBase::add_variant_non_tl_invariant (std::map<db::ICplxTrans, si
|
||||||
{
|
{
|
||||||
if (inst.is_complex ()) {
|
if (inst.is_complex ()) {
|
||||||
for (db::CellInstArray::iterator i = inst.begin (); ! i.at_end (); ++i) {
|
for (db::CellInstArray::iterator i = inst.begin (); ! i.at_end (); ++i) {
|
||||||
variants [mp_red->reduce (inst.complex_trans (*i))] += 1;
|
variants [mp_red->reduce_trans (inst.complex_trans (*i))] += 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (db::CellInstArray::iterator i = inst.begin (); ! i.at_end (); ++i) {
|
for (db::CellInstArray::iterator i = inst.begin (); ! i.at_end (); ++i) {
|
||||||
variants [db::ICplxTrans (mp_red->reduce (*i))] += 1;
|
variants [db::ICplxTrans (mp_red->reduce_trans (*i))] += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -338,9 +451,9 @@ void
|
||||||
VariantsCollectorBase::add_variant_tl_invariant (std::map<db::ICplxTrans, size_t> &variants, const db::CellInstArray &inst) const
|
VariantsCollectorBase::add_variant_tl_invariant (std::map<db::ICplxTrans, size_t> &variants, const db::CellInstArray &inst) const
|
||||||
{
|
{
|
||||||
if (inst.is_complex ()) {
|
if (inst.is_complex ()) {
|
||||||
variants [mp_red->reduce (inst.complex_trans ())] += inst.size ();
|
variants [mp_red->reduce_trans (inst.complex_trans ())] += inst.size ();
|
||||||
} else {
|
} else {
|
||||||
variants [db::ICplxTrans (mp_red->reduce (inst.front ()))] += inst.size ();
|
variants [db::ICplxTrans (mp_red->reduce_trans (inst.front ()))] += inst.size ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -390,7 +503,7 @@ VariantsCollectorBase::create_var_instances_non_tl_invariant (db::Cell &in_cell,
|
||||||
|
|
||||||
for (db::CellInstArray::iterator ia = i->begin (); ! ia.at_end (); ++ia) {
|
for (db::CellInstArray::iterator ia = i->begin (); ! ia.at_end (); ++ia) {
|
||||||
|
|
||||||
db::ICplxTrans rt = mp_red->reduce (for_var * i->complex_trans (*ia));
|
db::ICplxTrans rt = mp_red->reduce (for_var * mp_red->reduce_trans (i->complex_trans (*ia)));
|
||||||
std::map<db::ICplxTrans, db::cell_index_type>::const_iterator v = vt.find (rt);
|
std::map<db::ICplxTrans, db::cell_index_type>::const_iterator v = vt.find (rt);
|
||||||
tl_assert (v != vt.end ());
|
tl_assert (v != vt.end ());
|
||||||
|
|
||||||
|
|
@ -419,7 +532,7 @@ VariantsCollectorBase::create_var_instances_tl_invariant (db::Cell &in_cell, std
|
||||||
|
|
||||||
std::map<db::ICplxTrans, db::cell_index_type>::const_iterator v;
|
std::map<db::ICplxTrans, db::cell_index_type>::const_iterator v;
|
||||||
|
|
||||||
db::ICplxTrans rt = mp_red->reduce (for_var * i->complex_trans ());
|
db::ICplxTrans rt = mp_red->reduce (for_var * mp_red->reduce_trans (i->complex_trans ()));
|
||||||
v = vt.find (rt);
|
v = vt.find (rt);
|
||||||
tl_assert (v != vt.end ());
|
tl_assert (v != vt.end ());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,8 @@ public:
|
||||||
TransformationReducer () { }
|
TransformationReducer () { }
|
||||||
virtual ~TransformationReducer () { }
|
virtual ~TransformationReducer () { }
|
||||||
|
|
||||||
|
virtual db::Trans reduce_trans (const db::Trans &trans) const { return reduce (trans); }
|
||||||
|
virtual db::ICplxTrans reduce_trans (const db::ICplxTrans &trans) const { return reduce (trans); }
|
||||||
virtual db::Trans reduce (const db::Trans &trans) const = 0;
|
virtual db::Trans reduce (const db::Trans &trans) const = 0;
|
||||||
virtual db::ICplxTrans reduce (const db::ICplxTrans &trans) const = 0;
|
virtual db::ICplxTrans reduce (const db::ICplxTrans &trans) const = 0;
|
||||||
virtual bool is_translation_invariant () const { return true; }
|
virtual bool is_translation_invariant () const { return true; }
|
||||||
|
|
@ -63,18 +65,8 @@ public:
|
||||||
struct DB_PUBLIC OrientationReducer
|
struct DB_PUBLIC OrientationReducer
|
||||||
: public TransformationReducer
|
: public TransformationReducer
|
||||||
{
|
{
|
||||||
db::ICplxTrans reduce (const db::ICplxTrans &trans) const
|
db::ICplxTrans reduce (const db::ICplxTrans &trans) const;
|
||||||
{
|
db::Trans reduce (const db::Trans &trans) const;
|
||||||
db::ICplxTrans res (trans);
|
|
||||||
res.disp (db::Vector ());
|
|
||||||
res.mag (1.0);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
db::Trans reduce (const db::Trans &trans) const
|
|
||||||
{
|
|
||||||
return db::Trans (trans.fp_trans ());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -85,15 +77,8 @@ struct DB_PUBLIC OrientationReducer
|
||||||
struct DB_PUBLIC MagnificationReducer
|
struct DB_PUBLIC MagnificationReducer
|
||||||
: public TransformationReducer
|
: public TransformationReducer
|
||||||
{
|
{
|
||||||
db::ICplxTrans reduce (const db::ICplxTrans &trans) const
|
db::ICplxTrans reduce (const db::ICplxTrans &trans) const;
|
||||||
{
|
db::Trans reduce (const db::Trans &) const;
|
||||||
return db::ICplxTrans (trans.mag ());
|
|
||||||
}
|
|
||||||
|
|
||||||
db::Trans reduce (const db::Trans &) const
|
|
||||||
{
|
|
||||||
return db::Trans ();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -104,17 +89,8 @@ struct DB_PUBLIC MagnificationReducer
|
||||||
struct DB_PUBLIC MagnificationAndOrientationReducer
|
struct DB_PUBLIC MagnificationAndOrientationReducer
|
||||||
: public TransformationReducer
|
: public TransformationReducer
|
||||||
{
|
{
|
||||||
db::ICplxTrans reduce (const db::ICplxTrans &trans) const
|
db::ICplxTrans reduce (const db::ICplxTrans &trans) const;
|
||||||
{
|
db::Trans reduce (const db::Trans &trans) const;
|
||||||
db::ICplxTrans res (trans);
|
|
||||||
res.disp (db::Vector ());
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
db::Trans reduce (const db::Trans &trans) const
|
|
||||||
{
|
|
||||||
return db::Trans (trans.fp_trans ());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -125,47 +101,15 @@ struct DB_PUBLIC MagnificationAndOrientationReducer
|
||||||
struct DB_PUBLIC GridReducer
|
struct DB_PUBLIC GridReducer
|
||||||
: public TransformationReducer
|
: public TransformationReducer
|
||||||
{
|
{
|
||||||
GridReducer (db::Coord grid)
|
GridReducer (db::Coord grid);
|
||||||
: m_grid (grid)
|
|
||||||
{
|
|
||||||
// .. nothing yet ..
|
|
||||||
}
|
|
||||||
|
|
||||||
db::ICplxTrans reduce (const db::ICplxTrans &trans) const
|
db::ICplxTrans reduce (const db::ICplxTrans &trans) const;
|
||||||
{
|
db::Trans reduce (const db::Trans &trans) const;
|
||||||
// NOTE: we need to keep magnification, angle and mirror so when combining the
|
|
||||||
// reduced transformations, the result will be equivalent to reducing the combined
|
|
||||||
// transformation.
|
|
||||||
db::ICplxTrans res (trans);
|
|
||||||
res.disp (db::Vector (mod (trans.disp ().x ()), mod (trans.disp ().y ())));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
db::Trans reduce (const db::Trans &trans) const
|
|
||||||
{
|
|
||||||
db::Trans res (trans);
|
|
||||||
res.disp (db::Vector (mod (trans.disp ().x ()), mod (trans.disp ().y ())));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_translation_invariant () const { return false; }
|
bool is_translation_invariant () const { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
db::Coord m_grid;
|
db::Coord m_grid;
|
||||||
|
|
||||||
inline db::Coord mod (db::Coord c) const
|
|
||||||
{
|
|
||||||
if (c < 0) {
|
|
||||||
c = m_grid - (-c) % m_grid;
|
|
||||||
if (c == m_grid) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return c % m_grid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -178,49 +122,18 @@ private:
|
||||||
struct DB_PUBLIC ScaleAndGridReducer
|
struct DB_PUBLIC ScaleAndGridReducer
|
||||||
: public TransformationReducer
|
: public TransformationReducer
|
||||||
{
|
{
|
||||||
ScaleAndGridReducer (db::Coord grid, db::Coord mult, db::Coord div)
|
ScaleAndGridReducer (db::Coord grid, db::Coord mult, db::Coord div);
|
||||||
: m_mult (mult), m_grid (int64_t (grid) * int64_t (div))
|
|
||||||
{
|
|
||||||
// .. nothing yet ..
|
|
||||||
}
|
|
||||||
|
|
||||||
db::ICplxTrans reduce (const db::ICplxTrans &trans) const
|
virtual db::ICplxTrans reduce_trans (const db::ICplxTrans &trans) const;
|
||||||
{
|
virtual db::Trans reduce_trans (const db::Trans &trans) const;
|
||||||
// NOTE: we need to keep magnification, angle and mirror so when combining the
|
virtual db::ICplxTrans reduce (const db::ICplxTrans &trans) const;
|
||||||
// reduced transformations, the result will be equivalent to reducing the combined
|
virtual db::Trans reduce (const db::Trans &trans) const;
|
||||||
// transformation.
|
|
||||||
db::ICplxTrans res (trans);
|
|
||||||
res.disp (db::Vector (mod (trans.disp ().x ()), mod (trans.disp ().y ())));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
db::Trans reduce (const db::Trans &trans) const
|
|
||||||
{
|
|
||||||
db::Trans res (trans);
|
|
||||||
res.disp (db::Vector (mod (trans.disp ().x ()), mod (trans.disp ().y ())));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_translation_invariant () const { return false; }
|
bool is_translation_invariant () const { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int64_t m_mult;
|
int64_t m_mult;
|
||||||
int64_t m_grid;
|
int64_t m_grid;
|
||||||
|
|
||||||
inline db::Coord mod (db::Coord c) const
|
|
||||||
{
|
|
||||||
int64_t cc = int64_t (c) * m_mult;
|
|
||||||
if (cc < 0) {
|
|
||||||
cc = m_grid - (-cc) % m_grid;
|
|
||||||
if (cc == m_grid) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return db::Coord (cc);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return db::Coord (cc % m_grid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -493,7 +493,20 @@ scale_and_snap (db::Layout &layout, db::Cell &cell, db::Coord g, db::Coord m, db
|
||||||
db::Polygon poly;
|
db::Polygon poly;
|
||||||
si->polygon (poly);
|
si->polygon (poly);
|
||||||
poly.transform (tr);
|
poly.transform (tr);
|
||||||
out.insert (scaled_and_snapped_polygon (poly, g, m, d, tr_disp.x (), g, m, d, tr_disp.y (), heap).transformed (trinv));
|
poly = scaled_and_snapped_polygon (poly, g, m, d, tr_disp.x (), g, m, d, tr_disp.y (), heap);
|
||||||
|
poly.transform (trinv);
|
||||||
|
out.insert (poly);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Texts); ! si.at_end (); ++si) {
|
||||||
|
|
||||||
|
db::Text text;
|
||||||
|
si->text (text);
|
||||||
|
text.transform (tr);
|
||||||
|
text.trans (db::Trans (text.trans ().rot (), scaled_and_snapped_vector (text.trans ().disp (), g, m, d, tr_disp.x (), g, m, d, tr_disp.y ())));
|
||||||
|
text.transform (trinv);
|
||||||
|
out.insert (text);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -515,7 +528,11 @@ scale_and_snap (db::Layout &layout, db::Cell &cell, db::Coord g, db::Coord m, db
|
||||||
for (db::CellInstArray::iterator i = ia.begin (); ! i.at_end (); ++i) {
|
for (db::CellInstArray::iterator i = ia.begin (); ! i.at_end (); ++i) {
|
||||||
|
|
||||||
db::Trans ti (*i);
|
db::Trans ti (*i);
|
||||||
ti.disp (scaled_and_snapped_vector (ti.disp (), g, m, d, g, m, d));
|
db::Vector ti_disp = ti.disp ();
|
||||||
|
ti_disp.transform (tr);
|
||||||
|
ti_disp = scaled_and_snapped_vector (ti_disp, g, m, d, tr_disp.x (), g, m, d, tr_disp.y ());
|
||||||
|
ti_disp.transform (trinv);
|
||||||
|
ti.disp (ti_disp);
|
||||||
|
|
||||||
if (ia.is_complex ()) {
|
if (ia.is_complex ()) {
|
||||||
new_insts.push_back (db::CellInstArray (ia.object (), ia.complex_trans (ti)));
|
new_insts.push_back (db::CellInstArray (ia.object (), ia.complex_trans (ti)));
|
||||||
|
|
|
||||||
|
|
@ -229,7 +229,7 @@ private:
|
||||||
* This method will scale and snap all layers from the given cell and below to the
|
* This method will scale and snap all layers from the given cell and below to the
|
||||||
* specified grid. Scaling happens by the rational factor m / d.
|
* specified grid. Scaling happens by the rational factor m / d.
|
||||||
*/
|
*/
|
||||||
void scale_and_snap (db::Layout &layout, db::Cell &cell, db::Coord g, db::Coord m, db::Coord d);
|
DB_PUBLIC void scale_and_snap (db::Layout &layout, db::Cell &cell, db::Coord g, db::Coord m, db::Coord d);
|
||||||
|
|
||||||
} // namespace db
|
} // namespace db
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -427,13 +427,13 @@ scaled_and_snapped_polygon (const db::Polygon &poly, db::Coord gx, db::Coord mx,
|
||||||
}
|
}
|
||||||
|
|
||||||
db::Vector
|
db::Vector
|
||||||
scaled_and_snapped_vector (const db::Vector &v, db::Coord gx, db::Coord mx, db::Coord dx, db::Coord gy, db::Coord my, db::Coord dy)
|
scaled_and_snapped_vector (const db::Vector &v, db::Coord gx, db::Coord mx, db::Coord dx, db::Coord ox, db::Coord gy, db::Coord my, db::Coord dy, db::Coord oy)
|
||||||
{
|
{
|
||||||
int64_t dgx = int64_t (gx) * int64_t (dx);
|
int64_t dgx = int64_t (gx) * int64_t (dx);
|
||||||
int64_t dgy = int64_t (gy) * int64_t (dy);
|
int64_t dgy = int64_t (gy) * int64_t (dy);
|
||||||
|
|
||||||
int64_t x = snap_to_grid (int64_t (v.x ()) * mx, dgx) / int64_t (dx);
|
int64_t x = snap_to_grid (int64_t (v.x ()) * mx + int64_t (ox), dgx) / int64_t (dx);
|
||||||
int64_t y = snap_to_grid (int64_t (v.y ()) * my, dgy) / int64_t (dy);
|
int64_t y = snap_to_grid (int64_t (v.y ()) * my + int64_t (oy), dgy) / int64_t (dy);
|
||||||
|
|
||||||
return db::Vector (db::Coord (x), db::Coord (y));
|
return db::Vector (db::Coord (x), db::Coord (y));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -545,15 +545,15 @@ DB_PUBLIC db::Polygon snapped_polygon (const db::Polygon &poly, db::Coord gx, db
|
||||||
/**
|
/**
|
||||||
* @brief Scales and snaps a polygon to the given grid
|
* @brief Scales and snaps a polygon to the given grid
|
||||||
* Heap is a vector of points reused for the point list
|
* Heap is a vector of points reused for the point list
|
||||||
* The coordinate transformation is q = ((p * m + o) % (g * d)) / d.
|
* The coordinate transformation is q = ((p * m + o) snap (g * d)) / d.
|
||||||
*/
|
*/
|
||||||
DB_PUBLIC db::Polygon scaled_and_snapped_polygon (const db::Polygon &poly, db::Coord gx, db::Coord mx, db::Coord dx, db::Coord ox, db::Coord gy, db::Coord my, db::Coord dy, db::Coord oy, std::vector<db::Point> &heap);
|
DB_PUBLIC db::Polygon scaled_and_snapped_polygon (const db::Polygon &poly, db::Coord gx, db::Coord mx, db::Coord dx, db::Coord ox, db::Coord gy, db::Coord my, db::Coord dy, db::Coord oy, std::vector<db::Point> &heap);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Scales and snaps a vector to the given grid
|
* @brief Scales and snaps a vector to the given grid
|
||||||
* The coordinate transformation is q = ((p * m) % (g * d)) / d.
|
* The coordinate transformation is q = ((p * m + o) snap (g * d)) / d.
|
||||||
*/
|
*/
|
||||||
DB_PUBLIC db::Vector scaled_and_snapped_vector (const db::Vector &v, db::Coord gx, db::Coord mx, db::Coord dx, db::Coord gy, db::Coord my, db::Coord dy);
|
DB_PUBLIC db::Vector scaled_and_snapped_vector (const db::Vector &v, db::Coord gx, db::Coord mx, db::Coord dx, db::Coord ox, db::Coord gy, db::Coord my, db::Coord dy, db::Coord oy);
|
||||||
|
|
||||||
} // namespace db
|
} // namespace db
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -615,3 +615,41 @@ TEST(16)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(17_scale_and_snap)
|
||||||
|
{
|
||||||
|
db::Layout l1;
|
||||||
|
{
|
||||||
|
std::string fn (tl::testsrc ());
|
||||||
|
fn += "/testdata/algo/scale_and_snap.gds";
|
||||||
|
tl::InputStream stream (fn);
|
||||||
|
db::Reader reader (stream);
|
||||||
|
reader.read (l1);
|
||||||
|
}
|
||||||
|
|
||||||
|
db::scale_and_snap (l1, l1.cell (*l1.begin_top_down ()), 1, 20, 19);
|
||||||
|
|
||||||
|
CHECKPOINT();
|
||||||
|
db::compare_layouts (_this, l1, tl::testsrc () + "/testdata/algo/layout_utils_au_sns1.gds");
|
||||||
|
|
||||||
|
db::scale_and_snap (l1, l1.cell (*l1.begin_top_down ()), 1, 19, 20);
|
||||||
|
|
||||||
|
CHECKPOINT();
|
||||||
|
db::compare_layouts (_this, l1, tl::testsrc () + "/testdata/algo/layout_utils_au_sns2.gds");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(18_scale_and_snap)
|
||||||
|
{
|
||||||
|
db::Layout l1;
|
||||||
|
{
|
||||||
|
std::string fn (tl::testsrc ());
|
||||||
|
fn += "/testdata/algo/scale_and_snap.gds";
|
||||||
|
tl::InputStream stream (fn);
|
||||||
|
db::Reader reader (stream);
|
||||||
|
reader.read (l1);
|
||||||
|
}
|
||||||
|
|
||||||
|
db::scale_and_snap (l1, l1.cell (*l1.begin_top_down ()), 19, 1, 1);
|
||||||
|
|
||||||
|
CHECKPOINT();
|
||||||
|
db::compare_layouts (_this, l1, tl::testsrc () + "/testdata/algo/layout_utils_au_sns3.gds");
|
||||||
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue