diff --git a/src/ext/ext/extGerberImporter.cc b/src/ext/ext/extGerberImporter.cc index 7443c6f07..b66c5b319 100644 --- a/src/ext/ext/extGerberImporter.cc +++ b/src/ext/ext/extGerberImporter.cc @@ -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 &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 merged_polygons; + m_ep.merge (m_polygons, merged_polygons, 0, false /*don't resolve holes*/); + m_polygons.swap (merged_polygons); + } + + for (std::vector::const_iterator p = m_polygons.begin (); p != m_polygons.end (); ++p) { + region.insert (*p); + } + for (std::vector::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 (); diff --git a/src/ext/ext/extGerberImporter.h b/src/ext/ext/extGerberImporter.h index c72e58295..f5f795105 100644 --- a/src/ext/ext/extGerberImporter.h +++ b/src/ext/ext/extGerberImporter.h @@ -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 lines; + std::vector polygons; + std::vector clear_polygons; + std::vector 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 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 m_lines; std::vector m_polygons; std::vector m_clear_polygons; @@ -374,8 +490,10 @@ private: db::Cell *mp_top_cell; tl::TextInputStream *mp_stream; tl::AbsoluteProgress m_progress; + std::list m_graphics_stack; void process_clear_polygons (); + void swap_graphics_state (GraphicsState &state); }; /** diff --git a/src/ext/ext/extRS274XApertures.cc b/src/ext/ext/extRS274XApertures.cc index d8c5073b3..716fa593a 100644 --- a/src/ext/ext/extRS274XApertures.cc +++ b/src/ext/ext/extRS274XApertures.cc @@ -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 ::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 ::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 ::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::rounded (d.x () / dbu), db::coord_traits::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 diff --git a/src/ext/ext/extRS274XApertures.h b/src/ext/ext/extRS274XApertures.h index d73a0b501..2b4a0d204 100644 --- a/src/ext/ext/extRS274XApertures.h +++ b/src/ext/ext/extRS274XApertures.h @@ -28,6 +28,7 @@ #include "dbPath.h" #include "dbPolygon.h" #include "dbTrans.h" +#include "dbRegion.h" #include "tlStream.h" #include @@ -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: diff --git a/src/ext/ext/extRS274XReader.cc b/src/ext/ext/extRS274XReader.cc index 4b4c67730..2a5b8f0de 100644 --- a/src/ext/ext/extRS274XReader.cc +++ b/src/ext/ext/extRS274XReader.cc @@ -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::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) { diff --git a/src/ext/ext/extRS274XReader.h b/src/ext/ext/extRS274XReader.h index 60ff91a52..e4200dc0c 100644 --- a/src/ext/ext/extRS274XReader.h +++ b/src/ext/ext/extRS274XReader.h @@ -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 (); };