Gerbview: accept embedded tool definition (i.e. select tool and define it in the same line, outside the header). A few minor other fixes.

This commit is contained in:
jean-pierre charras 2016-05-24 17:56:52 +02:00
parent ac734ab54b
commit 75c551f305
5 changed files with 128 additions and 87 deletions

View File

@ -6,8 +6,8 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 1992-2013 Jean-Pierre Charras jp.charras at wanadoo.fr * Copyright (C) 1992-2016 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 1992-2013 KiCad Developers, see change_log.txt for contributors. * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -122,14 +122,14 @@ GERBER_DRAW_ITEM * GERBER_IMAGE::GetItemsList()
return m_Parent->GetItemsList(); return m_Parent->GetItemsList();
} }
D_CODE* GERBER_IMAGE::GetDCODE( int aDCODE, bool create ) D_CODE* GERBER_IMAGE::GetDCODE( int aDCODE, bool aCreateIfNoExist )
{ {
unsigned ndx = aDCODE - FIRST_DCODE; unsigned ndx = aDCODE - FIRST_DCODE;
if( ndx < (unsigned) DIM( m_Aperture_List ) ) if( ndx < (unsigned) DIM( m_Aperture_List ) )
{ {
// lazily create the D_CODE if it does not exist. // lazily create the D_CODE if it does not exist.
if( create ) if( aCreateIfNoExist )
{ {
if( m_Aperture_List[ndx] == NULL ) if( m_Aperture_List[ndx] == NULL )
m_Aperture_List[ndx] = new D_CODE( ndx + FIRST_DCODE ); m_Aperture_List[ndx] = new D_CODE( ndx + FIRST_DCODE );
@ -137,6 +137,7 @@ D_CODE* GERBER_IMAGE::GetDCODE( int aDCODE, bool create )
return m_Aperture_List[ndx]; return m_Aperture_List[ndx];
} }
return NULL; return NULL;
} }
@ -497,10 +498,10 @@ const wxString GERBER_IMAGE_LIST::GetDisplayName( int aIdx )
} }
} }
else else
name.Printf( _( "Layer %d *" ), aIdx + 1 ); name.Printf( _( "%d %s" ), aIdx + 1, filename.GetData() );
} }
else else
name.Printf( _( "Layer %d" ), aIdx + 1 ); name.Printf( _( "Graphic layer %d" ), aIdx + 1 );
return name; return name;
} }

View File

@ -277,12 +277,12 @@ public:
* returns a pointer to the D_CODE within this GERBER for the given * returns a pointer to the D_CODE within this GERBER for the given
* \a aDCODE. * \a aDCODE.
* @param aDCODE The numeric value of the D_CODE to look up. * @param aDCODE The numeric value of the D_CODE to look up.
* @param createIfNoExist If true, then create the D_CODE if it does not * @param aCreateIfNoExist If true, then create the D_CODE if it does not
* exist. * exist in list.
* @return D_CODE* - the one implied by the given \a aDCODE, or NULL * @return D_CODE* - the one implied by the given \a aDCODE, or NULL
* if the requested \a aDCODE is out of range. * if the requested \a aDCODE is out of range.
*/ */
D_CODE* GetDCODE( int aDCODE, bool createIfNoExist = true ); D_CODE* GetDCODE( int aDCODE, bool aCreateIfNoExist = true );
/** /**
* Function FindApertureMacro * Function FindApertureMacro

View File

@ -1,8 +1,8 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2011-2014 Jean-Pierre Charras jp.charras at wanadoo.fr * Copyright (C) 2011-2016 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors. * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -73,9 +73,9 @@ enum drill_G_code_t {
// Helper struct to analyse Excellon commands // Helper struct to analyse Excellon commands
struct EXCELLON_CMD struct EXCELLON_CMD
{ {
std::string m_Name; // key string std::string m_Name; // key string
int m_Code; // internal code, used as id in functions int m_Code; // internal code, used as id in functions
int m_asParams; // 0 = no param, -1 = skip params, 1 = read params int m_asParams; // 0 = no param, -1 = skip params, 1 = read params
}; };
@ -94,7 +94,7 @@ private:
READ_PROGRAM_STATE // When we are in this state, we are reading drill data READ_PROGRAM_STATE // When we are in this state, we are reading drill data
}; };
excellon_state m_State; // state of excellon file analysis excellon_state m_State; // state of excellon file analysis
bool m_SlotOn; // true during an oval driil definition bool m_SlotOn; // true during an oblong drill definition
public: EXCELLON_IMAGE( GERBVIEW_FRAME* aParent, int layer ) : public: EXCELLON_IMAGE( GERBVIEW_FRAME* aParent, int layer ) :
GERBER_IMAGE( aParent, layer ) GERBER_IMAGE( aParent, layer )
@ -121,9 +121,14 @@ private:
bool Execute_EXCELLON_G_Command( char*& text ); bool Execute_EXCELLON_G_Command( char*& text );
bool Execute_Drill_Command( char*& text ); bool Execute_Drill_Command( char*& text );
int TCodeNumber( char*& Text ) /** 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( Text ); return DCodeNumber( aText );
} }

View File

@ -8,8 +8,8 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 1992-2014 Jean-Pierre Charras <jp.charras at wanadoo.fr> * Copyright (C) 1992-2016 Jean-Pierre Charras <jp.charras at wanadoo.fr>
* Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors. * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -81,13 +81,13 @@
#include <html_messagebox.h> #include <html_messagebox.h>
// Default format for dimensions // Default format for dimensions: they are the default values, not the actual values
// number of digits in mantissa: // number of digits in mantissa:
static int fmtMantissaMM = 3; static const int fmtMantissaMM = 3;
static int fmtMantissaInch = 4; static const int fmtMantissaInch = 4;
// number of digits, integer part: // number of digits, integer part:
static int fmtIntegerMM = 3; static const int fmtIntegerMM = 3;
static int fmtIntegerInch = 2; static const int fmtIntegerInch = 2;
extern int ReadInt( char*& text, bool aSkipSeparator = true ); extern int ReadInt( char*& text, bool aSkipSeparator = true );
extern double ReadDouble( char*& text, bool aSkipSeparator = true ); extern double ReadDouble( char*& text, bool aSkipSeparator = true );
@ -192,8 +192,9 @@ bool GERBVIEW_FRAME::Read_EXCELLON_File( const wxString& aFullFileName )
ClearMessageList(); ClearMessageList();
/* Read the gerber file */ // Read the Excellon drill file:
FILE * file = wxFopen( aFullFileName, wxT( "rt" ) ); FILE * file = wxFopen( aFullFileName, wxT( "rt" ) );
if( file == NULL ) if( file == NULL )
{ {
msg.Printf( _( "File %s not found" ), GetChars( aFullFileName ) ); msg.Printf( _( "File %s not found" ), GetChars( aFullFileName ) );
@ -211,7 +212,7 @@ bool GERBVIEW_FRAME::Read_EXCELLON_File( const wxString& aFullFileName )
// Display errors list // Display errors list
if( m_Messages.size() > 0 ) if( m_Messages.size() > 0 )
{ {
HTML_MESSAGE_BOX dlg( this, _( "Files not found" ) ); HTML_MESSAGE_BOX dlg( this, _( "Error reading EXCELLON drill file" ) );
dlg.ListSet( m_Messages ); dlg.ListSet( m_Messages );
dlg.ShowModal(); dlg.ShowModal();
} }
@ -221,7 +222,9 @@ bool GERBVIEW_FRAME::Read_EXCELLON_File( const wxString& aFullFileName )
bool EXCELLON_IMAGE::Read_EXCELLON_File( FILE * aFile, bool EXCELLON_IMAGE::Read_EXCELLON_File( FILE * aFile,
const wxString & aFullFileName ) const wxString & aFullFileName )
{ {
/* Set the gerber scale: */ wxASSERT( aFile );
// Set the default parmeter values:
ResetDefaultValues(); ResetDefaultValues();
m_FileName = aFullFileName; m_FileName = aFullFileName;
@ -230,13 +233,8 @@ bool EXCELLON_IMAGE::Read_EXCELLON_File( FILE * aFile,
LOCALE_IO toggleIo; LOCALE_IO toggleIo;
// FILE_LINE_READER will close the file. // FILE_LINE_READER will close the file.
if( m_Current_File == NULL )
{
wxMessageBox( wxT("NULL!"), m_FileName );
return false;
}
FILE_LINE_READER excellonReader( m_Current_File, m_FileName ); FILE_LINE_READER excellonReader( m_Current_File, m_FileName );
while( true ) while( true )
{ {
if( excellonReader.ReadLine() == 0 ) if( excellonReader.ReadLine() == 0 )
@ -313,20 +311,17 @@ bool EXCELLON_IMAGE::Read_EXCELLON_File( FILE * aFile,
bool EXCELLON_IMAGE::Execute_HEADER_Command( char*& text ) bool EXCELLON_IMAGE::Execute_HEADER_Command( char*& text )
{ {
EXCELLON_CMD* cmd = NULL; EXCELLON_CMD* cmd = NULL;
int iprm;
double dprm;
D_CODE* dcode;
wxString msg; wxString msg;
// Search command in list // Search command in list
EXCELLON_CMD* candidate;
for( unsigned ii = 0; ; ii++ ) for( unsigned ii = 0; ; ii++ )
{ {
candidate = &excellonHeaderCmdList[ii]; EXCELLON_CMD* candidate = &excellonHeaderCmdList[ii];
int len = candidate->m_Name.size(); int len = candidate->m_Name.size();
if( len == 0 ) // End of list reached if( len == 0 ) // End of list reached
break; break;
if( candidate->m_Name.compare( 0, len, text, len ) == 0 ) // found. if( candidate->m_Name.compare( 0, len, text, len ) == 0 ) // found.
{ {
cmd = candidate; cmd = candidate;
@ -463,41 +458,7 @@ bool EXCELLON_IMAGE::Execute_HEADER_Command( char*& text )
break; break;
case DRILL_TOOL_INFORMATION: case DRILL_TOOL_INFORMATION:
readToolInformation( text );
// Read a tool definition like T1C0.02:
// or T1F00S00C0.02 or T1C0.02F00S00
// Read tool number:
iprm = ReadInt( text, false );
// Skip Feed rate and Spindle speed, if any here
while( *text && ( *text == 'F' || *text == 'S' ) )
{
text++;
ReadInt( text, false );
}
// Read tool shape
if( *text != 'C' )
ReportMessage( wxString:: Format(
_( "Tool definition <%c> not supported" ), *text ) );
if( *text )
text++;
//read tool diameter:
dprm = ReadDouble( text, false );
m_Has_DCode = true;
// Initialize Dcode to handle this Tool
dcode = GetDCODE( iprm + FIRST_DCODE ); // Remember: dcodes are >= FIRST_DCODE
if( dcode == NULL )
break;
// conv_scale = scaling factor from inch to Internal Unit
double conv_scale = IU_PER_MILS * 1000;
if( m_GerbMetric )
conv_scale /= 25.4;
dcode->m_Size.x = dcode->m_Size.y = KiROUND( dprm * conv_scale );
dcode->m_Shape = APT_CIRCLE;
break; break;
} }
@ -508,10 +469,63 @@ bool EXCELLON_IMAGE::Execute_HEADER_Command( char*& text )
} }
bool EXCELLON_IMAGE::readToolInformation( char*& aText )
{
// Read a tool definition like T1C0.02 or T1F00S00C0.02 or T1C0.02F00S00
// and enter the TCODE param in list (using the D_CODE param management, which
// is similar to TCODE params.
if( *aText == 'T' ) // This is the beginning of the definition
aText++;
// Read tool number:
int iprm = ReadInt( aText, false );
// Skip Feed rate and Spindle speed, if any here
while( *aText && ( *aText == 'F' || *aText == 'S' ) )
{
aText++;
ReadInt( aText, false );
}
// Read tool shape
if( ! *aText )
ReportMessage( wxString:: Format(
_( "Tool definition shape not found" ) ) );
else if( *aText != 'C' )
ReportMessage( wxString:: Format(
_( "Tool definition '%c' not supported" ), *aText ) );
if( *aText )
aText++;
//read tool diameter:
double dprm = ReadDouble( aText, false );
m_Has_DCode = true;
// Initialize Dcode to handle this Tool
// Remember: dcodes are >= FIRST_DCODE
D_CODE* dcode = GetDCODE( iprm + FIRST_DCODE );
if( dcode == NULL )
return false;
// conv_scale = scaling factor from inch to Internal Unit
double conv_scale = IU_PER_MILS * 1000;
if( m_GerbMetric )
conv_scale /= 25.4;
dcode->m_Size.x = dcode->m_Size.y = KiROUND( dprm * conv_scale );
dcode->m_Shape = APT_CIRCLE;
dcode->m_Defined = true;
return true;
}
bool EXCELLON_IMAGE::Execute_Drill_Command( char*& text ) bool EXCELLON_IMAGE::Execute_Drill_Command( char*& text )
{ {
D_CODE* tool; D_CODE* tool;
GERBER_DRAW_ITEM * gbritem; GERBER_DRAW_ITEM * gbritem;
while( true ) while( true )
{ {
switch( *text ) switch( *text )
@ -528,15 +542,18 @@ bool EXCELLON_IMAGE::Execute_Drill_Command( char*& text )
break; break;
case 0: // E.O.L: execute command case 0: // E.O.L: execute command
tool = GetDCODE( m_Current_Tool, false ); tool = GetDCODE( m_Current_Tool, false );
if( !tool ) if( !tool )
{ {
wxString msg; wxString msg;
msg.Printf( _( "Tool <%d> not defined" ), m_Current_Tool ); msg.Printf( _( "Tool %d not defined" ), m_Current_Tool );
ReportMessage( msg ); ReportMessage( msg );
return false; return false;
} }
gbritem = new GERBER_DRAW_ITEM( GetParent()->GetGerberLayout(), this ); gbritem = new GERBER_DRAW_ITEM( GetParent()->GetGerberLayout(), this );
GetParent()->GetGerberLayout()->m_Drawings.Append( gbritem ); GetParent()->GetGerberLayout()->m_Drawings.Append( gbritem );
if( m_SlotOn ) // Oval hole if( m_SlotOn ) // Oval hole
{ {
fillLineGBRITEM( gbritem, fillLineGBRITEM( gbritem,
@ -551,6 +568,7 @@ bool EXCELLON_IMAGE::Execute_Drill_Command( char*& text )
m_CurrentPos, m_CurrentPos,
tool->m_Size, false ); tool->m_Size, false );
} }
StepAndRepeatItem( *gbritem ); StepAndRepeatItem( *gbritem );
m_PreviousPos = m_CurrentPos; m_PreviousPos = m_CurrentPos;
return true; return true;
@ -568,18 +586,35 @@ bool EXCELLON_IMAGE::Execute_Drill_Command( char*& text )
bool EXCELLON_IMAGE::Select_Tool( char*& text ) bool EXCELLON_IMAGE::Select_Tool( char*& text )
{ {
// Select the tool from the command line Tn, with n = 1 ... TOOLS_MAX_COUNT - 1
// Because some drill file have an embedded TCODE definition (like T1C.008F0S0)
// in tool selection command, if the tool is not defined in list,
// and the definition is embedded, it will be entered in list
char * startline = text; // the tool id starts here.
int tool_id = TCodeNumber( text ); int tool_id = TCodeNumber( text );
// T0 is legal, but is not a selection tool. it is a special command
if( tool_id >= 0 ) if( tool_id >= 0 )
{ {
tool_id += FIRST_DCODE; // Remember: dcodes are >= FIRST_DCODE int dcode_id = tool_id + FIRST_DCODE; // Remember: dcodes are >= FIRST_DCODE
if( tool_id > (TOOLS_MAX_COUNT - 1) )
tool_id = TOOLS_MAX_COUNT - 1; if( dcode_id > (TOOLS_MAX_COUNT - 1) )
m_Current_Tool = tool_id; dcode_id = TOOLS_MAX_COUNT - 1;
D_CODE* pt_Dcode = GetDCODE( tool_id , false );
if( pt_Dcode ) m_Current_Tool = dcode_id;
pt_Dcode->m_InUse = true; D_CODE* currDcode = GetDCODE( dcode_id , false );
if( currDcode == NULL && tool_id > 0 ) // if the definition is embedded, enter it
{
text = startline; // text starts at the beginning of the command
readToolInformation( text );
currDcode = GetDCODE( dcode_id , false );
}
if( currDcode )
currDcode->m_InUse = true;
} }
while( *text ) while( *text )
text++; text++;
@ -678,8 +713,8 @@ void EXCELLON_IMAGE::SelectUnits( bool aMetric )
* Five digit 10 micron resolution (000.00) * Five digit 10 micron resolution (000.00)
* Six digit 10 micron resolution (0000.00) * Six digit 10 micron resolution (0000.00)
* Six digit micron resolution (000.000) * Six digit micron resolution (000.000)
*/ *
/* Inches: Default fmt = 2.4 for X and Y axis: 6 digits with 0.0001 resolution * Inches: Default fmt = 2.4 for X and Y axis: 6 digits with 0.0001 resolution
* metric: Default fmt = 3.3 for X and Y axis: 6 digits, 1 micron resolution * metric: Default fmt = 3.3 for X and Y axis: 6 digits, 1 micron resolution
*/ */
if( aMetric ) if( aMetric )

View File

@ -456,9 +456,9 @@ void GERBVIEW_FRAME::Liste_D_Codes()
); );
if( !pt_D_code->m_Defined ) if( !pt_D_code->m_Defined )
Line += wxT( "(not used)" ); Line += wxT( "(not defined) " );
if( !pt_D_code->m_InUse ) if( pt_D_code->m_InUse )
Line += wxT( "(in use)" ); Line += wxT( "(in use)" );
list.Add( Line ); list.Add( Line );
@ -485,7 +485,7 @@ void GERBVIEW_FRAME::UpdateTitleAndInfo()
text.Printf( wxT( "GerbView %s" ), GetChars( GetBuildVersion() ) ); text.Printf( wxT( "GerbView %s" ), GetChars( GetBuildVersion() ) );
SetTitle( text ); SetTitle( text );
SetStatusText( wxEmptyString, 0 ); SetStatusText( wxEmptyString, 0 );
text.Printf( _( "Layer %d not in use" ), getActiveLayer() + 1 ); text.Printf( _( "Drawing layer %d not in use" ), getActiveLayer() + 1 );
m_TextInfo->SetValue( text ); m_TextInfo->SetValue( text );
ClearMsgPanel(); ClearMsgPanel();
return; return;