mirror of https://github.com/KLayout/klayout.git
Gerber X2 support basically implemented. Needs testing.
This commit is contained in:
parent
468c3f4952
commit
17327ce19c
|
|
@ -108,7 +108,12 @@ static std::string format_to_string (int l, int t, bool tz)
|
|||
|
||||
GerberFileReader::GerberFileReader ()
|
||||
: m_circle_points (64), m_digits_before (-1), m_digits_after (-1), m_omit_leading_zeroes (true),
|
||||
m_merge (false), m_inverse (false), m_dbu (0.001), m_unit (1000.0), m_ep (true /*report progress*/),
|
||||
m_merge (false), m_inverse (false),
|
||||
m_dbu (0.001), m_unit (1000.0),
|
||||
m_rot (0.0), m_s (1.0), m_ox (0.0), m_oy (0.0),
|
||||
m_mx (false), m_my (false),
|
||||
m_orot (0.0), m_os (1.0), m_omx (false), m_omy (false),
|
||||
m_ep (true /*report progress*/),
|
||||
mp_layout (0), mp_top_cell (0), mp_stream (0),
|
||||
m_progress (tl::to_string (QObject::tr ("Reading Gerber file")), 10000)
|
||||
{
|
||||
|
|
@ -128,19 +133,14 @@ GerberFileReader::accepts (tl::TextInputStream &stream)
|
|||
void
|
||||
GerberFileReader::read (tl::TextInputStream &stream, db::Layout &layout, db::Cell &cell, const std::vector <unsigned int> &targets)
|
||||
{
|
||||
reset_step_and_repeat ();
|
||||
GraphicsState state;
|
||||
swap_graphics_state (state);
|
||||
|
||||
m_inverse = false;
|
||||
mp_stream = &stream;
|
||||
mp_layout = &layout;
|
||||
mp_top_cell = &cell;
|
||||
m_target_layers = targets;
|
||||
|
||||
m_polygons.clear ();
|
||||
m_lines.clear ();
|
||||
m_clear_polygons.clear ();
|
||||
m_local_trans = db::DCplxTrans ();
|
||||
|
||||
try {
|
||||
do_read ();
|
||||
} catch (tl::Exception &ex) {
|
||||
|
|
@ -236,10 +236,89 @@ GerberFileReader::read_coord (tl::Extractor &ex)
|
|||
return number * m_unit * sign;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
GerberFileReader::swap_graphics_state (GraphicsState &state)
|
||||
{
|
||||
std::swap (m_merge, state.merge);
|
||||
std::swap (m_inverse, state.inverse);
|
||||
std::swap (m_global_trans, state.global_trans);
|
||||
std::swap (m_s, state.m_s);
|
||||
std::swap (m_mx, state.m_mx);
|
||||
std::swap (m_my, state.m_my);
|
||||
std::swap (m_ox, state.m_ox);
|
||||
std::swap (m_oy, state.m_oy);
|
||||
std::swap (m_rot, state.m_rot);
|
||||
std::swap (m_os, state.m_os);
|
||||
std::swap (m_omx, state.m_omx);
|
||||
std::swap (m_omy, state.m_omy);
|
||||
std::swap (m_orot, state.m_orot);
|
||||
std::swap (m_lines, state.lines);
|
||||
std::swap (m_polygons, state.polygons);
|
||||
std::swap (m_clear_polygons, state.clear_polygons);
|
||||
std::swap (m_displacements, state.displacements);
|
||||
}
|
||||
|
||||
void
|
||||
GerberFileReader::push_state (const std::string &token)
|
||||
{
|
||||
m_graphics_stack.push_back (GraphicsState ());
|
||||
swap_graphics_state (m_graphics_stack.back ());
|
||||
m_graphics_stack.back ().token = token;
|
||||
}
|
||||
|
||||
std::string
|
||||
GerberFileReader::pop_state ()
|
||||
{
|
||||
std::string token;
|
||||
|
||||
if (! m_graphics_stack.empty ()) {
|
||||
swap_graphics_state (m_graphics_stack.back ());
|
||||
token = m_graphics_stack.back ().token;
|
||||
}
|
||||
|
||||
m_graphics_stack.pop_back ();
|
||||
return token;
|
||||
}
|
||||
|
||||
bool
|
||||
GerberFileReader::graphics_stack_empty () const
|
||||
{
|
||||
return m_graphics_stack.empty ();
|
||||
}
|
||||
|
||||
db::DCplxTrans
|
||||
GerberFileReader::local_trans () const
|
||||
{
|
||||
// TODO: is this order correct?
|
||||
db::DCplxTrans lt = db::DCplxTrans (m_s, m_rot, false, db::DVector (m_ox, m_oy));
|
||||
if (m_mx) {
|
||||
lt *= db::DCplxTrans (db::DTrans (db::FTrans::m0));
|
||||
}
|
||||
if (m_my) {
|
||||
lt *= db::DCplxTrans (db::DTrans (db::FTrans::m90));
|
||||
}
|
||||
|
||||
return lt;
|
||||
}
|
||||
|
||||
db::DCplxTrans
|
||||
GerberFileReader::object_trans () const
|
||||
{
|
||||
db::DCplxTrans ot = db::DCplxTrans (m_os, m_orot, false, db::DVector ());
|
||||
if (m_omx) {
|
||||
ot *= db::DCplxTrans (db::DTrans (db::FTrans::m0));
|
||||
}
|
||||
if (m_omy) {
|
||||
ot *= db::DCplxTrans (db::DTrans (db::FTrans::m90));
|
||||
}
|
||||
|
||||
return ot;
|
||||
}
|
||||
|
||||
void
|
||||
GerberFileReader::produce_line (const db::DPath &p, bool clear)
|
||||
{
|
||||
db::DCplxTrans t = m_global_trans * db::DCplxTrans (1.0 / dbu ()) * m_local_trans;
|
||||
db::DCplxTrans t = global_trans () * db::DCplxTrans (1.0 / dbu ()) * local_trans ();
|
||||
|
||||
// Ignore clear paths for now - they cannot be subtracted from anything.
|
||||
// Clear is just provided for completeness.
|
||||
|
|
@ -258,7 +337,7 @@ GerberFileReader::produce_line (const db::DPath &p, bool clear)
|
|||
void
|
||||
GerberFileReader::produce_polygon (const db::DPolygon &p, bool clear)
|
||||
{
|
||||
db::DCplxTrans t = m_global_trans * db::DCplxTrans (1.0 / dbu ()) * m_local_trans;
|
||||
db::DCplxTrans t = global_trans () * db::DCplxTrans (1.0 / dbu ()) * local_trans ();
|
||||
|
||||
if (! clear) {
|
||||
process_clear_polygons ();
|
||||
|
|
@ -288,7 +367,29 @@ GerberFileReader::process_clear_polygons ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
GerberFileReader::collect (db::Region ®ion)
|
||||
{
|
||||
process_clear_polygons ();
|
||||
|
||||
if (m_merge) {
|
||||
std::vector<db::Polygon> merged_polygons;
|
||||
m_ep.merge (m_polygons, merged_polygons, 0, false /*don't resolve holes*/);
|
||||
m_polygons.swap (merged_polygons);
|
||||
}
|
||||
|
||||
for (std::vector<db::Polygon>::const_iterator p = m_polygons.begin (); p != m_polygons.end (); ++p) {
|
||||
region.insert (*p);
|
||||
}
|
||||
for (std::vector<db::Path>::const_iterator p = m_lines.begin (); p != m_lines.end (); ++p) {
|
||||
region.insert (*p);
|
||||
}
|
||||
|
||||
m_polygons.clear ();
|
||||
m_lines.clear ();
|
||||
}
|
||||
|
||||
void
|
||||
GerberFileReader::flush ()
|
||||
{
|
||||
process_clear_polygons ();
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "dbLayout.h"
|
||||
#include "dbTrans.h"
|
||||
#include "dbEdgeProcessor.h"
|
||||
#include "dbRegion.h"
|
||||
#include "tlStream.h"
|
||||
#include "tlProgress.h"
|
||||
|
||||
|
|
@ -48,6 +49,36 @@ namespace lay
|
|||
namespace ext
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief A class holding the graphics state of the reader
|
||||
*/
|
||||
struct GraphicsState
|
||||
{
|
||||
GraphicsState ()
|
||||
: merge (false), inverse (false),
|
||||
m_rot (0.0), m_s (1.0), m_ox (false), m_oy (false), m_mx (false), m_my (false),
|
||||
m_orot (0.0), m_os (1.0), m_omx (false), m_omy (false)
|
||||
{
|
||||
displacements.push_back (db::DVector ());
|
||||
}
|
||||
|
||||
bool merge;
|
||||
bool inverse;
|
||||
db::DCplxTrans global_trans;
|
||||
double m_rot;
|
||||
double m_s;
|
||||
double m_ox, m_oy;
|
||||
bool m_mx, m_my;
|
||||
double m_orot;
|
||||
double m_os;
|
||||
bool m_omx, m_omy;
|
||||
std::vector<db::Path> lines;
|
||||
std::vector<db::Polygon> polygons;
|
||||
std::vector<db::Polygon> clear_polygons;
|
||||
std::vector<db::DVector> displacements;
|
||||
std::string token;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The base class for all readers
|
||||
*/
|
||||
|
|
@ -283,14 +314,14 @@ protected:
|
|||
void fatal (const std::string &error);
|
||||
|
||||
/**
|
||||
* @brief Set the local transformation
|
||||
*
|
||||
* The global transformation is applied before the global transformation
|
||||
* @brief Gets the local transformation
|
||||
*/
|
||||
void set_local_trans (const db::DCplxTrans &trans)
|
||||
{
|
||||
m_local_trans = trans;
|
||||
}
|
||||
db::DCplxTrans local_trans () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the local transformation
|
||||
*/
|
||||
db::DCplxTrans object_trans () const;
|
||||
|
||||
/**
|
||||
* @brief Read a coordinate from the extractor using the format and unit
|
||||
|
|
@ -306,9 +337,32 @@ protected:
|
|||
|
||||
/**
|
||||
* @brief Flush the stored data to the output
|
||||
* This method is similar to collect(), but writes the data to the layout.
|
||||
*/
|
||||
void flush ();
|
||||
|
||||
/**
|
||||
* @brief Collects the data taken so far into the given region
|
||||
* This method is similar to flush(), but will return a Region object.
|
||||
*/
|
||||
void collect (db::Region ®ion);
|
||||
|
||||
/**
|
||||
* @brief Pushes the graphics state
|
||||
*/
|
||||
void push_state (const std::string &token);
|
||||
|
||||
/**
|
||||
* @brief Pops the graphics state
|
||||
* Returns the token given in "push_state"
|
||||
*/
|
||||
std::string pop_state ();
|
||||
|
||||
/**
|
||||
* @brief Returns true if the graphics stack is empty
|
||||
*/
|
||||
bool graphics_stack_empty () const;
|
||||
|
||||
/**
|
||||
* @brief Access to the edge processor
|
||||
*/
|
||||
|
|
@ -353,6 +407,62 @@ protected:
|
|||
return *mp_stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the local mirror flags
|
||||
*/
|
||||
void update_local_mirror (bool mx, bool my)
|
||||
{
|
||||
m_mx = mx; m_my = my;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the local orientation
|
||||
*/
|
||||
void update_local_angle (double rot)
|
||||
{
|
||||
m_rot = rot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the local scale factor
|
||||
*/
|
||||
void update_local_scale (double s)
|
||||
{
|
||||
m_s = s;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the local offset
|
||||
*/
|
||||
void update_local_offset (double x, double y)
|
||||
{
|
||||
m_ox = x; m_oy = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the object mirror flags
|
||||
*/
|
||||
void update_object_mirror (bool mx, bool my)
|
||||
{
|
||||
m_omx = mx; m_omy = my;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the object orientation
|
||||
*/
|
||||
void update_object_angle (double rot)
|
||||
{
|
||||
m_orot = rot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the object scale factor
|
||||
*/
|
||||
void update_object_scale (double s)
|
||||
{
|
||||
m_os = s;
|
||||
}
|
||||
|
||||
private:
|
||||
int m_circle_points;
|
||||
int m_digits_before;
|
||||
|
|
@ -362,8 +472,14 @@ private:
|
|||
bool m_inverse;
|
||||
double m_dbu;
|
||||
double m_unit;
|
||||
db::DCplxTrans m_global_trans, m_local_trans;
|
||||
std::vector<db::DPoint> m_polygon_points;
|
||||
db::DCplxTrans m_global_trans;
|
||||
double m_rot;
|
||||
double m_s;
|
||||
double m_ox, m_oy;
|
||||
bool m_mx, m_my;
|
||||
double m_orot;
|
||||
double m_os;
|
||||
bool m_omx, m_omy;
|
||||
std::vector<db::Path> m_lines;
|
||||
std::vector<db::Polygon> m_polygons;
|
||||
std::vector<db::Polygon> m_clear_polygons;
|
||||
|
|
@ -374,8 +490,10 @@ private:
|
|||
db::Cell *mp_top_cell;
|
||||
tl::TextInputStream *mp_stream;
|
||||
tl::AbsoluteProgress m_progress;
|
||||
std::list<GraphicsState> m_graphics_stack;
|
||||
|
||||
void process_clear_polygons ();
|
||||
void swap_graphics_state (GraphicsState &state);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ RS274XApertureBase::RS274XApertureBase ()
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void
|
||||
RS274XApertureBase::produce_flash (const db::DVector &d, RS274XReader &reader, db::EdgeProcessor &ep, bool clear)
|
||||
void
|
||||
RS274XApertureBase::produce_flash (const db::DCplxTrans &d, RS274XReader &reader, db::EdgeProcessor &ep, bool clear)
|
||||
{
|
||||
if (m_needs_update) {
|
||||
|
||||
|
|
@ -65,18 +65,18 @@ RS274XApertureBase::produce_flash (const db::DVector &d, RS274XReader &reader, d
|
|||
|
||||
}
|
||||
|
||||
db::CplxTrans trans = db::CplxTrans (reader.dbu ());
|
||||
db::CplxTrans trans = d * db::CplxTrans (reader.dbu ());
|
||||
|
||||
for (std::vector <db::Polygon>::const_iterator p = m_polygons.begin (); p != m_polygons.end (); ++p) {
|
||||
reader.produce_polygon (p->transformed (trans).moved (d), clear);
|
||||
reader.produce_polygon (p->transformed (trans), clear);
|
||||
}
|
||||
for (std::vector <db::Path>::const_iterator p = m_lines.begin (); p != m_lines.end (); ++p) {
|
||||
reader.produce_line (p->transformed (trans).moved (d), clear);
|
||||
reader.produce_line (p->transformed (trans), clear);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RS274XApertureBase::produce_linear (const db::DPoint &from, const db::DPoint &to, RS274XReader &reader, db::EdgeProcessor &ep, bool clear)
|
||||
RS274XApertureBase::produce_linear (const db::DCplxTrans &d, const db::DVector &dist, RS274XReader &reader, db::EdgeProcessor &ep, bool clear)
|
||||
{
|
||||
mp_reader = &reader;
|
||||
mp_ep = &ep;
|
||||
|
|
@ -88,6 +88,9 @@ RS274XApertureBase::produce_linear (const db::DPoint &from, const db::DPoint &to
|
|||
p.swap (m_polygons);
|
||||
cp.swap (m_clear_polygons);
|
||||
|
||||
db::DPoint from;
|
||||
db::DPoint to = from + d.inverted () * dist;
|
||||
|
||||
if (! do_produce_linear (from, to)) {
|
||||
|
||||
// fallback: produce flash and employ a Minkowsky sum to generate the resulting structure
|
||||
|
|
@ -120,7 +123,7 @@ RS274XApertureBase::produce_linear (const db::DPoint &from, const db::DPoint &to
|
|||
m_clear_polygons.clear ();
|
||||
}
|
||||
|
||||
db::CplxTrans trans = db::CplxTrans (mp_reader->dbu ());
|
||||
db::CplxTrans trans = d * db::CplxTrans (mp_reader->dbu ());
|
||||
|
||||
for (std::vector <db::Polygon>::const_iterator p = m_polygons.begin (); p != m_polygons.end (); ++p) {
|
||||
mp_reader->produce_polygon (p->transformed (trans), clear);
|
||||
|
|
@ -157,7 +160,13 @@ RS274XApertureBase::add_point (const db::DPoint &d)
|
|||
m_points.push_back (db::Point (db::coord_traits<db::Coord>::rounded (d.x () / dbu), db::coord_traits<db::Coord>::rounded (d.y () / dbu)));
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
RS274XApertureBase::add_point (const db::Point &p)
|
||||
{
|
||||
m_points.push_back (p);
|
||||
}
|
||||
|
||||
void
|
||||
RS274XApertureBase::produce_circle (double cx, double cy, double r, bool clear)
|
||||
{
|
||||
clear_points ();
|
||||
|
|
@ -531,6 +540,44 @@ RS274XRegularAperture::do_produce_linear (const db::DPoint & /*from*/, const db:
|
|||
return false;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// RS274XRegionAperture implementation
|
||||
|
||||
RS274XRegionAperture::RS274XRegionAperture (const db::Region ®ion)
|
||||
: m_region (region)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void RS274XRegionAperture::do_produce_flash ()
|
||||
{
|
||||
for (db::Region::const_iterator p = m_region.begin (); ! p.at_end (); ++p) {
|
||||
|
||||
db::Polygon poly = *p;
|
||||
|
||||
clear_points ();
|
||||
for (db::Polygon::polygon_contour_iterator pt = poly.begin_hull (); pt != poly.end_hull (); ++pt) {
|
||||
add_point (*pt);
|
||||
}
|
||||
produce_polygon (false);
|
||||
|
||||
for (size_t h = 0; h < poly.holes (); ++h) {
|
||||
clear_points ();
|
||||
for (db::Polygon::polygon_contour_iterator pt = poly.begin_hole (h); pt != poly.end_hole (h); ++pt) {
|
||||
add_point (*pt);
|
||||
}
|
||||
produce_polygon (true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
RS274XRegionAperture::do_produce_linear (const db::DPoint & /*from*/, const db::DPoint & /*to*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// RS274XMacroAperture implementation
|
||||
|
||||
|
|
@ -592,9 +639,8 @@ RS274XMacroAperture::do_produce_flash_internal ()
|
|||
|
||||
if (code == 1) {
|
||||
|
||||
int pol = 0;
|
||||
ex.expect (",");
|
||||
ex.read (pol);
|
||||
int pol = (read_expr (ex) > 0.5);
|
||||
|
||||
if (pol == 0) {
|
||||
clear = true;
|
||||
|
|
@ -613,13 +659,18 @@ RS274XMacroAperture::do_produce_flash_internal ()
|
|||
ex.expect (",");
|
||||
double cy = read_expr (ex, true);
|
||||
|
||||
produce_circle (cx, cy, d * 0.5, clear);
|
||||
double a = 0.0;
|
||||
if (ex.test (",")) {
|
||||
a = read_expr (ex);
|
||||
}
|
||||
|
||||
db::DVector c = db::DCplxTrans (1.0, a, false, db::DVector ()) * db::DVector (cx, cy);
|
||||
produce_circle (c.x (), c.y (), d * 0.5, clear);
|
||||
|
||||
} else if (code == 2 || code == 20) {
|
||||
|
||||
int pol = 0;
|
||||
ex.expect (",");
|
||||
ex.read (pol);
|
||||
int pol = (read_expr (ex) > 0.5);
|
||||
|
||||
if (pol == 0) {
|
||||
clear = true;
|
||||
|
|
@ -671,9 +722,8 @@ RS274XMacroAperture::do_produce_flash_internal ()
|
|||
|
||||
} else if (code == 21 || code == 22) {
|
||||
|
||||
int pol = 0;
|
||||
ex.expect (",");
|
||||
ex.read (pol);
|
||||
int pol = (read_expr (ex) > 0.5);
|
||||
|
||||
if (pol == 0) {
|
||||
clear = true;
|
||||
|
|
@ -715,9 +765,8 @@ RS274XMacroAperture::do_produce_flash_internal ()
|
|||
|
||||
} else if (code == 4) {
|
||||
|
||||
int pol = 0;
|
||||
ex.expect (",");
|
||||
ex.read (pol);
|
||||
int pol = (read_expr (ex) > 0.5);
|
||||
|
||||
if (pol == 0) {
|
||||
clear = true;
|
||||
|
|
@ -804,9 +853,8 @@ RS274XMacroAperture::do_produce_flash_internal ()
|
|||
|
||||
} else if (code == 5) {
|
||||
|
||||
int pol = 0;
|
||||
ex.expect (",");
|
||||
ex.read (pol);
|
||||
int pol = (read_expr (ex) > 0.5);
|
||||
|
||||
if (pol == 0) {
|
||||
clear = true;
|
||||
|
|
@ -945,24 +993,28 @@ RS274XMacroAperture::do_produce_linear (const db::DPoint & /*from*/, const db::D
|
|||
double
|
||||
RS274XMacroAperture::read_atom (tl::Extractor &ex)
|
||||
{
|
||||
double fac = 1.0;
|
||||
if (ex.test ("-")) {
|
||||
fac = -1.0;
|
||||
}
|
||||
|
||||
double d = 0.0;
|
||||
|
||||
if (ex.test ("$")) {
|
||||
int nvar = 0;
|
||||
ex.read (nvar);
|
||||
nvar -= 1;
|
||||
if (nvar >= 0 && nvar < int (m_parameters.size ())) {
|
||||
return m_parameters[nvar];
|
||||
} else {
|
||||
return 0.0;
|
||||
d = m_parameters[nvar];
|
||||
}
|
||||
} else if (ex.test ("(")) {
|
||||
double d = read_expr (ex);
|
||||
d = read_expr (ex);
|
||||
ex.expect (")");
|
||||
return d;
|
||||
} else {
|
||||
double d = 0.0;
|
||||
ex.read (d);
|
||||
return d;
|
||||
}
|
||||
|
||||
return fac * d;
|
||||
}
|
||||
|
||||
double
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "dbPath.h"
|
||||
#include "dbPolygon.h"
|
||||
#include "dbTrans.h"
|
||||
#include "dbRegion.h"
|
||||
#include "tlStream.h"
|
||||
|
||||
#include <vector>
|
||||
|
|
@ -48,13 +49,14 @@ public:
|
|||
RS274XApertureBase ();
|
||||
virtual ~RS274XApertureBase () { }
|
||||
|
||||
void produce_flash (const db::DVector &d, RS274XReader &reader, db::EdgeProcessor &ep, bool clear);
|
||||
void produce_linear (const db::DPoint &from, const db::DPoint &to, RS274XReader &reader, db::EdgeProcessor &ep, bool clear);
|
||||
void produce_flash (const db::DCplxTrans &d, RS274XReader &reader, db::EdgeProcessor &ep, bool clear);
|
||||
void produce_linear (const db::DCplxTrans &d, const db::DVector &dist, RS274XReader &reader, db::EdgeProcessor &ep, bool clear);
|
||||
|
||||
protected:
|
||||
void clear_points ();
|
||||
void add_point (double x, double y);
|
||||
void add_point (const db::DPoint &d);
|
||||
void add_point (const db::Point &d);
|
||||
void produce_circle (double cx, double cy, double r, bool clear);
|
||||
void produce_polygon (bool clear);
|
||||
void produce_line ();
|
||||
|
|
@ -135,7 +137,20 @@ private:
|
|||
double m_hx, m_hy;
|
||||
};
|
||||
|
||||
class RS274XMacroAperture
|
||||
class RS274XRegionAperture
|
||||
: public RS274XApertureBase
|
||||
{
|
||||
public:
|
||||
RS274XRegionAperture (const db::Region ®ion);
|
||||
|
||||
virtual void do_produce_flash ();
|
||||
virtual bool do_produce_linear (const db::DPoint &from, const db::DPoint &to);
|
||||
|
||||
private:
|
||||
db::Region m_region;
|
||||
};
|
||||
|
||||
class RS274XMacroAperture
|
||||
: public RS274XApertureBase
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -79,12 +79,6 @@ RS274XReader::init ()
|
|||
m_buffer.clear ();
|
||||
m_polygon_points.clear ();
|
||||
|
||||
m_ox = m_oy = 0.0;
|
||||
m_sx = m_sy = 1.0;
|
||||
m_mx = m_my = false;
|
||||
m_rot = 0.0;
|
||||
update_trans ();
|
||||
|
||||
for (std::vector<RS274XApertureBase *>::const_iterator a = m_apertures.begin (); a != m_apertures.end (); ++a) {
|
||||
if (*a) {
|
||||
delete *a;
|
||||
|
|
@ -146,6 +140,26 @@ RS274XReader::do_read ()
|
|||
read_pf_parameter (get_block ());
|
||||
} else if (param == "AD") {
|
||||
read_ad_parameter (get_block ());
|
||||
} else if (param == "AB") {
|
||||
|
||||
std::string dcode = get_block ();
|
||||
if (dcode.empty ()) {
|
||||
|
||||
if (graphics_stack_empty ()) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("AB closed without initial opening AB command")));
|
||||
} else {
|
||||
db::Region region;
|
||||
collect (region);
|
||||
std::string ap = pop_state ();
|
||||
install_block_aperture (ap, region);
|
||||
}
|
||||
|
||||
} else if (m_polygon_mode) {
|
||||
warn (tl::to_string (QObject::tr ("AB command inside polygon sequence (G36/G37) - polygon ignored")));
|
||||
} else {
|
||||
push_state (dcode);
|
||||
}
|
||||
|
||||
} else if (param == "AM") {
|
||||
|
||||
// AM parameters can span multiple data blocks, so collect them
|
||||
|
|
@ -164,6 +178,12 @@ RS274XReader::do_read ()
|
|||
read_ln_parameter (get_block ());
|
||||
} else if (param == "LP") {
|
||||
read_lp_parameter (get_block ());
|
||||
} else if (param == "LM") {
|
||||
read_lm_parameter (get_block ());
|
||||
} else if (param == "LR") {
|
||||
read_lr_parameter (get_block ());
|
||||
} else if (param == "LS") {
|
||||
read_ls_parameter (get_block ());
|
||||
} else if (param == "SR") {
|
||||
read_sr_parameter (get_block ());
|
||||
} else if (param == "IF") {
|
||||
|
|
@ -385,7 +405,7 @@ RS274XReader::do_read ()
|
|||
if (m_polygon_mode) {
|
||||
warn (tl::to_string (QObject::tr ("D03 blocks are ignored in polygon mode")));
|
||||
} else {
|
||||
m_current_aperture->produce_flash (db::DVector (x, y), *this, ep (), is_clear_polarity ());
|
||||
m_current_aperture->produce_flash (db::DCplxTrans (db::DVector (x, y)) * object_trans (), *this, ep (), is_clear_polarity ());
|
||||
}
|
||||
|
||||
} else { // only if m_current_dcode == 1?
|
||||
|
|
@ -479,7 +499,7 @@ RS274XReader::do_read ()
|
|||
throw tl::Exception (tl::to_string (QObject::tr ("No aperture defined (missing G54 block)")));
|
||||
}
|
||||
|
||||
m_current_aperture->produce_linear (db::DPoint (m_x, m_y), pe, *this, ep (), is_clear_polarity ());
|
||||
m_current_aperture->produce_linear (db::DCplxTrans (db::DVector (m_x, m_y)) * object_trans (), pe - db::DPoint (m_x, m_y), *this, ep (), is_clear_polarity ());
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -508,7 +528,7 @@ RS274XReader::do_read ()
|
|||
throw tl::Exception (tl::to_string (QObject::tr ("No aperture defined (missing G54 block)")));
|
||||
}
|
||||
|
||||
m_current_aperture->produce_linear (db::DPoint (m_x, m_y), db::DPoint (x, y), *this, ep (), is_clear_polarity ());
|
||||
m_current_aperture->produce_linear (db::DCplxTrans (db::DVector (m_x, m_y)) * object_trans (), db::DPoint (x, y) - db::DPoint (m_x, m_y), *this, ep (), is_clear_polarity ());
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -527,6 +547,9 @@ RS274XReader::do_read ()
|
|||
|
||||
}
|
||||
|
||||
if (! graphics_stack_empty ()) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("AB block not closed")));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -550,25 +573,6 @@ RS274XReader::get_block ()
|
|||
return m_buffer;
|
||||
}
|
||||
|
||||
void
|
||||
RS274XReader::update_trans ()
|
||||
{
|
||||
if (fabs (m_sx - m_sy) > 1e-6) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Different scalings for x and y axis is not supported currently.")));
|
||||
}
|
||||
|
||||
// TODO: is this order correct?
|
||||
db::DCplxTrans lt = db::DCplxTrans (m_sx, m_rot, false, db::DVector (m_ox, m_oy));
|
||||
if (m_mx) {
|
||||
lt *= db::DCplxTrans (db::DTrans (db::FTrans::m0));
|
||||
}
|
||||
if (m_my) {
|
||||
lt *= db::DCplxTrans (db::DTrans (db::FTrans::m90));
|
||||
}
|
||||
|
||||
set_local_trans (lt);
|
||||
}
|
||||
|
||||
void
|
||||
RS274XReader::read_as_parameter (const std::string &block)
|
||||
{
|
||||
|
|
@ -648,14 +652,14 @@ RS274XReader::read_mi_parameter (const std::string &block)
|
|||
ex.read (mb);
|
||||
ex.expect_end ();
|
||||
|
||||
m_mx = (ma != 0);
|
||||
m_my = (mb != 0);
|
||||
bool mx = (ma != 0);
|
||||
bool my = (mb != 0);
|
||||
|
||||
if (m_axis_mapping != ab_xy) {
|
||||
std::swap (m_mx, m_my);
|
||||
std::swap (mx, my);
|
||||
}
|
||||
|
||||
update_trans ();
|
||||
update_local_mirror (mx, my);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -686,14 +690,14 @@ RS274XReader::read_of_parameter (const std::string &block)
|
|||
bo *= unit ();
|
||||
ex.expect_end ();
|
||||
|
||||
m_ox = ao;
|
||||
m_oy = bo;
|
||||
double ox = ao;
|
||||
double oy = bo;
|
||||
|
||||
if (m_axis_mapping != ab_xy) {
|
||||
std::swap (m_ox, m_oy);
|
||||
std::swap (ox, oy);
|
||||
}
|
||||
|
||||
update_trans ();
|
||||
update_local_offset (ox, oy);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -702,18 +706,63 @@ RS274XReader::read_sf_parameter (const std::string &block)
|
|||
tl::Extractor ex (block.c_str ());
|
||||
|
||||
ex.expect ("A");
|
||||
m_sx = 1.0;
|
||||
ex.read (m_sx);
|
||||
double sx = 1.0;
|
||||
ex.read (sx);
|
||||
ex.expect ("B");
|
||||
m_sy = 1.0;
|
||||
ex.read (m_sy);
|
||||
double sy = 1.0;
|
||||
ex.read (sy);
|
||||
ex.expect_end ();
|
||||
|
||||
if (m_axis_mapping != ab_xy) {
|
||||
std::swap (m_sx, m_sy);
|
||||
std::swap (sx, sy);
|
||||
}
|
||||
|
||||
update_trans ();
|
||||
if (fabs (sx - sy) > 1e-6) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Different scalings for x and y axis is not supported currently.")));
|
||||
}
|
||||
|
||||
update_local_scale (sx);
|
||||
}
|
||||
|
||||
void
|
||||
RS274XReader::read_ls_parameter (const std::string &block)
|
||||
{
|
||||
tl::Extractor ex (block.c_str ());
|
||||
|
||||
double s = 1.0;
|
||||
ex.read (s);
|
||||
|
||||
update_object_scale (s);
|
||||
}
|
||||
|
||||
void
|
||||
RS274XReader::read_lr_parameter (const std::string &block)
|
||||
{
|
||||
tl::Extractor ex (block.c_str ());
|
||||
|
||||
double a = 0.0;
|
||||
ex.read (a);
|
||||
|
||||
update_object_angle (a);
|
||||
}
|
||||
|
||||
void
|
||||
RS274XReader::read_lm_parameter (const std::string &block)
|
||||
{
|
||||
tl::Extractor ex (block.c_str ());
|
||||
|
||||
bool omx = false, omy = false;
|
||||
while (! ex.at_end ()) {
|
||||
if (ex.test ("X")) {
|
||||
omy = true; // "my == mirror at y axis" is "X == mirror along x axis"
|
||||
} else if (ex.test ("Y")) {
|
||||
omx = true; // "mx == mirror at x axis" is "Y == mirror along y axis"
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
update_object_mirror (omx, omy);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -744,14 +793,14 @@ RS274XReader::read_io_parameter (const std::string &block)
|
|||
bo *= unit ();
|
||||
ex.expect_end ();
|
||||
|
||||
m_ox = ao;
|
||||
m_oy = bo;
|
||||
double ox = ao;
|
||||
double oy = bo;
|
||||
|
||||
if (m_axis_mapping != ab_xy) {
|
||||
std::swap (m_ox, m_oy);
|
||||
std::swap (ox, oy);
|
||||
}
|
||||
|
||||
update_trans ();
|
||||
update_local_offset (ox, oy);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -773,9 +822,9 @@ RS274XReader::read_ir_parameter (const std::string &block)
|
|||
{
|
||||
tl::Extractor ex (block.c_str ());
|
||||
|
||||
m_rot = 0.0;
|
||||
ex.read (m_rot);
|
||||
ex.expect_end ();
|
||||
double rot = 0.0;
|
||||
ex.read (rot);
|
||||
update_local_angle (rot);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -827,6 +876,31 @@ RS274XReader::read_ad_parameter (const std::string &block)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
RS274XReader::install_block_aperture (const std::string &d, const db::Region ®ion)
|
||||
{
|
||||
int dcode = 0;
|
||||
|
||||
try {
|
||||
tl::Extractor ex (d.c_str ());
|
||||
ex.expect ("D");
|
||||
ex.read (dcode);
|
||||
ex.expect_end ();
|
||||
} catch (...) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Invalid aperture code string for AB command")));
|
||||
}
|
||||
|
||||
if (dcode < 0) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Invalid D code for AB command")));
|
||||
}
|
||||
|
||||
while (int (m_apertures.size ()) <= dcode) {
|
||||
m_apertures.push_back (0);
|
||||
}
|
||||
|
||||
m_apertures[dcode] = new RS274XRegionAperture (region);
|
||||
}
|
||||
|
||||
void
|
||||
RS274XReader::read_am_parameter (const std::string &block)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -66,10 +66,6 @@ private:
|
|||
bool m_guess_polarity;
|
||||
bool m_neg_polarity;
|
||||
bool m_360deg_circular;
|
||||
double m_sx, m_sy;
|
||||
double m_rot;
|
||||
bool m_mx, m_my;
|
||||
double m_ox, m_oy;
|
||||
double m_x, m_y;
|
||||
bool m_relative;
|
||||
std::string m_buffer;
|
||||
|
|
@ -99,13 +95,16 @@ private:
|
|||
void read_ad_parameter (const std::string &block);
|
||||
void read_am_parameter (const std::string &block);
|
||||
void read_ko_parameter (const std::string &block);
|
||||
void read_lm_parameter (const std::string &block);
|
||||
void read_lr_parameter (const std::string &block);
|
||||
void read_ls_parameter (const std::string &block);
|
||||
void read_ln_parameter (const std::string &block);
|
||||
void read_lp_parameter (const std::string &block);
|
||||
void read_sr_parameter (const std::string &block);
|
||||
void read_if_parameter (const std::string &block);
|
||||
void install_block_aperture (const std::string &dcode, const db::Region ®ion);
|
||||
void process_mcode (int mcode);
|
||||
const std::string &get_block ();
|
||||
void update_trans ();
|
||||
bool is_clear_polarity ();
|
||||
void init ();
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue