kicad/gerbview/excellon_image.h

399 lines
14 KiB
C++

/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2011-2016 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef EXCELLON_IMAGE_H
#define EXCELLON_IMAGE_H
struct EXCELLON_DEFAULTS;
enum drill_M_code_t {
DRILL_M_UNKNOWN,
DRILL_M_END,
DRILL_M_TOOL_DOWN, // tool down (starting a routed hole)
DRILL_M_TOOL_UP, // tool up (ending a routed hole)
DRILL_M_ENDFILE,
DRILL_M_MESSAGE,
DRILL_M_LONGMESSAGE,
DRILL_M_HEADER,
DRILL_M_ENDHEADER,
DRILL_M_BEGINPATTERN,
DRILL_M_ENDPATTERN,
DRILL_M_CANNEDTEXT,
DRILL_M_TIPCHECK,
DRILL_M_METRIC,
DRILL_M_IMPERIAL,
DRILL_METRIC_HEADER,
DRILL_IMPERIAL_HEADER,
DRILL_DETECT_BROKEN,
DRILL_INCREMENTALHEADER,
DRILL_REWIND_STOP,
DRILL_TOOL_CHANGE_STOP,
DRILL_AUTOMATIC_SPEED,
DRILL_AXIS_VERSION,
DRILL_RESET_CMD,
DRILL_AUTOMATIC_TOOL_CHANGE,
DRILL_FMT,
DRILL_FORMAT_ALTIUM,
DRILL_HEADER_SKIP,
DRILL_SKIP,
DRILL_TOOL_INFORMATION,
DRILL_M_END_LIST // not used: sentinel
};
enum drill_G_code_t {
DRILL_G_UNKNOWN = DRILL_M_END_LIST+1, // Use next available value
DRILL_G_ABSOLUTE,
DRILL_G_INCREMENTAL,
DRILL_G_ZEROSET,
DRILL_G_ROUT,
DRILL_G_DRILL,
DRILL_G_SLOT,
DRILL_G_ZERO_SET,
DRILL_G_LINEARMOVE,
DRILL_G_CWMOVE,
DRILL_G_CCWMOVE
};
// Helper struct to analyze Excellon commands
struct EXCELLON_CMD
{
std::string m_Name; // key string
int m_Code; // internal code, used as id in functions
int m_asParams; // 0 = no param, -1 = skip params, 1 = read params
};
// Helper struct to store Excellon points in routing mode
#define ROUTE_CCW 1
#define ROUTE_CW -1
struct EXCELLON_ROUTE_COORD
{
int m_x; // X coordinate
int m_y; // y coordinate
int m_cx; // center X coordinate in circular routing mode
// (when the IJ command is used)
int m_cy; // center y coordinate in circular routing mode
// (when the IJ command is used)
int m_radius; // radius in circular routing mode (when the A## command is used)
int m_rmode; // routing mode: 0 = circular, ROUTE_CCW (1) = ccw, ROUTE_CW (-1) = cw
int m_arc_type_info; // arc using radius or center coordinates
EXCELLON_ROUTE_COORD():
m_x( 0 ), m_y( 0 ), m_cx( 0 ), m_cy( 0 ), m_radius( 0 ),
m_rmode( 0 ), m_arc_type_info( 0 )
{}
EXCELLON_ROUTE_COORD( const VECTOR2I& aPos ) :
m_x( aPos.x ), m_y( aPos.y ),
m_cx( 0 ), m_cy( 0 ), m_radius( 0 ), m_rmode( 0 ),
m_arc_type_info( ARC_INFO_TYPE_NONE )
{}
EXCELLON_ROUTE_COORD( const VECTOR2I& aPos, const VECTOR2I& aCenter, int aMode ) :
m_x( aPos.x ), m_y( aPos.y ),
m_cx( aCenter.x ), m_cy( aCenter.y ), m_radius( 0 ), m_rmode( aMode ),
m_arc_type_info( ARC_INFO_TYPE_CENTER )
{}
EXCELLON_ROUTE_COORD( const VECTOR2I& aPos, int aRadius, int aMode ) :
m_x( aPos.x ), m_y( aPos.y ),
m_cx( 0 ), m_cy( 0 ), m_radius( aRadius ), m_rmode( aMode ),
m_arc_type_info( ARC_INFO_TYPE_RADIUS )
{}
VECTOR2I GetPos() { return VECTOR2I( m_x, m_y ); }
};
/**
* Handle a drill image.
*
* It is derived from #GERBER_FILE_IMAGE because there is a lot of likeness between EXCELLON
* files and GERBER files.
* DCode apertures are also similar to T Codes.
*/
class EXCELLON_IMAGE : public GERBER_FILE_IMAGE
{
public: EXCELLON_IMAGE( int layer ) :
GERBER_FILE_IMAGE( layer )
{
m_State = READ_HEADER_STATE;
m_SlotOn = false;
m_RouteModeOn = false;
m_hasFormat = false;
}
~EXCELLON_IMAGE() {};
/**
* Set all parameters to a default value, before reading a file
*/
virtual void ResetDefaultValues() override;
/**
* Read and load a drill (EXCELLON format) file.
*
* When the file cannot be loaded, warning and info messages are stored in m_Messages.
*
* @param aFullFileName is the full filename of the Excellon file.
* @param aDefaults is the default values when not found in file.
* @return true if OK, false if the gerber file was not loaded.
*/
bool LoadFile( const wxString& aFullFileName, EXCELLON_DEFAULTS* aDefaults );
private:
bool Execute_HEADER_And_M_Command( char*& text );
bool Select_Tool( char*& text );
bool Execute_EXCELLON_G_Command( char*& text );
bool Execute_Drill_Command( char*& text );
/**
* Read an Altium-specific FILE_FORMAT=X:X attribute that specifies the length
* and mantissa of the numbers in the gerber file
*
* @param aText Text containing format and mantissa
*/
void readFileFormat( char*& aText );
/**
* Read a tool definition like T1C0.02 or T1F00S00C0.02 or T1C0.02F00S00
* and enter params in TCODE list.
*/
bool readToolInformation( char*& aText );
int TCodeNumber( char*& aText )
{
return DCodeNumber( aText );
}
/**
* End a route command started by M15 ot G01, G02 or G03 command.
*/
void FinishRouteCommand();
/**
* Switch unit selection, and the coordinate format (nn:mm) if not yet set
*/
void SelectUnits( bool aMetric, EXCELLON_DEFAULTS* aDefaults );
private:
enum EXCELLON_STATE {
READ_HEADER_STATE, // When we are in this state, we are reading header
READ_PROGRAM_STATE // When we are in this state, we are reading drill data
};
EXCELLON_STATE m_State; // state of excellon file analysis
bool m_SlotOn; // true during an oblong drill definition
// by G85 (canned slot) command
bool m_RouteModeOn; // true during a route mode (for instance a oval hole) or
// a cutout.
std::vector<EXCELLON_ROUTE_COORD> m_RoutePositions; // The list of points in a route mode
/// Excellon file do not have a format statement to specify the coordinate format
/// like nn:mm.
/// However Altium files have a comment to specify it (";FILE_FORMET_"
/// m_hasFormat is set to true if this comment is found, and coordinate format is known.
bool m_hasFormat;
};
/*
* EXCELLON commands are given here.
* Pcbnew uses only few excellon commands
*/
/*
* see http://www.excellon.com/manuals/program.htm
*/
/* coordinates units:
* Coordinates are measured either in inch or metric (millimeters).
* Inch coordinates are in six digits (00.0000) with increments as small as 0.0001 (1/10,000).
* Metric coordinates can be measured in microns (thousandths of a millimeter)
* in one of the following three ways:
* Five digit 10 micron resolution (000.00)
* Six digit 10 micron resolution (0000.00)
* Six digit micron resolution (000.000)
*
* Leading and trailing zeros:
* Excellon (CNC-7) uses inches in six digits and metric in five or six digits.
* The zeros to the left of the coordinate are called leading zeros (LZ).
* The zeros to right of the coordinate are called trailing zeros (TZ).
* The CNC-7 uses leading zeros unless you specify otherwise through a part program.
* You can do so with the INCH/METRIC command.
* With leading zeros, the leading zeros must always be included.
* Trailing zeros are unneeded and may be left off.
* For trailing zeros, the reverse of the above is true.
*/
/*
* EXCELLON Commands Used in a Header
* The following table provides you with a list of commands which
* are the most used in a part program header.
* COMMAND DESCRIPTION
* AFS Automatic Feeds and Speeds
* ATC Automatic Tool Change
* BLKD Delete all Blocks starting with a slash (/)
* CCW Clockwise or Counter-clockwise Routing
* CP Cutter Compensation
* DETECT Broken Tool Detection
* DN Down Limit Set
* DTMDIST Maximum Rout Distance Before Toolchange
* EXDA Extended Drill Area
* FMAT Format 1 or 2
* FSB Turns the Feed/Speed Buttons off
* HPCK Home Pulse Check
* ICI Incremental Input of Part Program Coordinates
* INCH Measure Everything in Inches
* METRIC Measure Everything in Metric
* M48 Beginning of Part Program Header
* M95 End of Header
* NCSL NC Slope Enable/Disable
* OM48 Override Part Program Header
* OSTOP Optional Stop Switch
* OTCLMP Override Table Clamp
* PCKPARAM Set up pecking tool,depth,infeed and retract parameters
* PF Floating Pressure Foot Switch
* PPR Programmable Plunge Rate Enable
* PVS Pre-vacuum Shut-off Switch
* R,C Reset Clocks
* R,CP Reset Program Clocks
* R,CR Reset Run Clocks
* R,D Reset All Cutter Distances
* R,H Reset All Hit Counters
* R,T Reset Tool Data
* SBK Single Block Mode Switch
* SG Spindle Group Mode
* SIXM Input From External Source
* T Tool Information
* TCST Tool Change Stop
* UP Upper Limit Set
* VER Selection of X and Y Axis Version
* Z Zero Set
* ZA Auxiliary Zero
* ZC Zero Correction
* ZS Zero Preset
* Z+# or Z-# Set Depth Offset
* % Rewind Stop
* #/#/# Link Tool for Automatic Tool Change
* / Clear Tool Linking
*/
/*
* Beyond The Header: The Part Program Body
* COMMAND DESCRIPTION
* A# Arc Radius
* B# Retract Rate
* C# Tool Diameter
* F# Table Feed Rate;Z Axis Infeed Rate
* G00X#Y# Route Mode; XY is the starting point
* G01X#Y# Linear (Straight Line) Route Mode YX is the ending point
* G02X#Y#... Circular CW Mode. Radius value (A#) or Center position (I#J#) follows
* G03X#Y#... Circular CCW Mode. Radius value (A#) or Center position (I#J#) follows
* G04X# Variable Dwell
* G05 Drill Mode
* G07 Override current tool feed or speed
* G32X#Y#A# Routed Circle Canned Cycle
* CW G33X#Y#A# Routed Circle Canned Cycle
* CCW G34,#(,#) Select Vision Tool
* G35(X#Y#) Single Point Vision Offset (Relative to Work Zero)
* G36(X#Y#) Multipoint Vision Translation (Relative to Work Zero)
* G37 Cancel Vision Translation or Offset (From G35 or G36)
* G38(X#Y#) Vision Corrected Single Hole Drilling (Relative to Work Zero)
* G39(X#Y#) Vision System Autocalibration
* G40 Cutter Compensation Off
* G41 Cutter Compensation Left
* G42 Cutter Compensation Right
* G45(X#Y#) Single Point Vision Offset (Relative to G35 or G36)
* G46(X#Y#) Multipoint Vision Translation (Relative to G35 or G36)
* G47 Cancel Vision Translation or Offset (From G45 or G46)
* G48(X#Y#) Vision Corrected Single Hole Drilling (Relative to G35 or G36)
* G82(G81) Dual In Line Package
* G83 Eight Pin L Pack
* G84 Circle
* G85 Slot
* G87 Routed Step Slot Canned Cycle
* G90 Absolute Mode
* G91 Incremental Input Mode
* G93X#Y# Zero Set
* H# Maximum hit count
* I#J# Arc Center Offset
* M00(X#Y#) End of Program - No Rewind
* M01 End of Pattern
* M02X#Y# Repeat Pattern Offset
* M06(X#Y#) Optional Stop
* M08 End of Step and Repeat
* M09(X#Y#) Stop for Inspection
* M14 Z Axis Route Position With Depth Controlled Contouring
* M15 Z Axis Route Position
* M16 Retract With Clamping
* M17 Retract Without Clamping
* M18 Command tool tip check
* M25 Beginning of Pattern
* M30(X#Y#) End of Program Rewind
* M45,long message\ Long Operator message on multiple\ part program lines
* M47,text Operator Message
* M50,# Vision Step and Repeat Pattern Start
* M51,# Vision Step and Repeat Rewind
* M52(#) Vision Step and Repeat Offset Counter Control
* M02XYM70 Swap Axes
* M60 Reference Scaling enable
* M61 Reference Scaling disable
* M62 Turn on peck drilling
* M63 Turn off peck drilling
* M71 Metric Measuring Mode
* M72 Inch Measuring Mode
* M02XYM80 Mirror Image X Axis
* M02XYM90 Mirror Image Y Axis
* M97,text Canned Text
* M98,text Canned Text
* M99,subprogram User Defined Stored Pattern
* P#X#(Y#) Repeat Stored Pattern
* R#M02X#Y# Repeat Pattern (S&R)
* R#(X#Y#) Repeat Hole
* S# Spindle RPM
* T# Tool Selection; Cutter Index
* Z+# or Z-# Depth Offset
* % Beginning of Pattern (see M25 command)
* / Block Delete
*/
/*
* Example of a Header
* COMMAND PURPOSE
* M48 The beginning of a header
* INCH,LZ Use the inch measuring system with leading zeros
* VER,1 Use Version 1 X and Y axis layout
* FMAT,2 Use Format 2 commands
* 1/2/3 Link tools 1, 2, and 3
* T1C.04F200S65 Set Tool 1 for 0.040" with infeed rate of 200 inch/min Speed of 65,000 RPM
* DETECT,ON Detect broken tools
* M95 End of the header
*/
#endif // EXCELLON_IMAGE_H