Gerber X2 support basically implemented. Needs testing.

This commit is contained in:
Matthias Koefferlein 2017-09-09 02:07:09 +02:00
parent 468c3f4952
commit 17327ce19c
6 changed files with 463 additions and 104 deletions

View File

@ -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 &region)
{
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 ();

View File

@ -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 &region);
/**
* @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);
};
/**

View File

@ -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 &region)
: 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

View File

@ -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 &region);
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:

View File

@ -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 &region)
{
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)
{

View File

@ -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 &region);
void process_mcode (int mcode);
const std::string &get_block ();
void update_trans ();
bool is_clear_polarity ();
void init ();
};