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.
*
* Copyright (C) 1992-2013 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 1992-2013 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 1992-2016 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 1992-2016 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
@ -122,14 +122,14 @@ GERBER_DRAW_ITEM * GERBER_IMAGE::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;
if( ndx < (unsigned) DIM( m_Aperture_List ) )
{
// lazily create the D_CODE if it does not exist.
if( create )
if( aCreateIfNoExist )
{
if( m_Aperture_List[ndx] == NULL )
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 NULL;
}
@ -497,10 +498,10 @@ const wxString GERBER_IMAGE_LIST::GetDisplayName( int aIdx )
}
}
else
name.Printf( _( "Layer %d *" ), aIdx + 1 );
name.Printf( _( "%d %s" ), aIdx + 1, filename.GetData() );
}
else
name.Printf( _( "Layer %d" ), aIdx + 1 );
name.Printf( _( "Graphic layer %d" ), aIdx + 1 );
return name;
}

View File

@ -277,12 +277,12 @@ public:
* returns a pointer to the D_CODE within this GERBER for the given
* \a aDCODE.
* @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
* exist.
* @param aCreateIfNoExist If true, then create the D_CODE if it does not
* exist in list.
* @return D_CODE* - the one implied by the given \a aDCODE, or NULL
* 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

View File

@ -1,8 +1,8 @@
/*
* 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) 1992-2014 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2011-2016 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 1992-2016 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
@ -94,7 +94,7 @@ private:
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 oval driil definition
bool m_SlotOn; // true during an oblong drill definition
public: EXCELLON_IMAGE( GERBVIEW_FRAME* aParent, int layer ) :
GERBER_IMAGE( aParent, layer )
@ -121,9 +121,14 @@ private:
bool Execute_EXCELLON_G_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.
*
* Copyright (C) 1992-2014 Jean-Pierre Charras <jp.charras at wanadoo.fr>
* Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 1992-2016 Jean-Pierre Charras <jp.charras at wanadoo.fr>
* Copyright (C) 1992-2016 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
@ -81,13 +81,13 @@
#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:
static int fmtMantissaMM = 3;
static int fmtMantissaInch = 4;
static const int fmtMantissaMM = 3;
static const int fmtMantissaInch = 4;
// number of digits, integer part:
static int fmtIntegerMM = 3;
static int fmtIntegerInch = 2;
static const int fmtIntegerMM = 3;
static const int fmtIntegerInch = 2;
extern int ReadInt( 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();
/* Read the gerber file */
// Read the Excellon drill file:
FILE * file = wxFopen( aFullFileName, wxT( "rt" ) );
if( file == NULL )
{
msg.Printf( _( "File %s not found" ), GetChars( aFullFileName ) );
@ -211,7 +212,7 @@ bool GERBVIEW_FRAME::Read_EXCELLON_File( const wxString& aFullFileName )
// Display errors list
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.ShowModal();
}
@ -221,7 +222,9 @@ bool GERBVIEW_FRAME::Read_EXCELLON_File( const wxString& aFullFileName )
bool EXCELLON_IMAGE::Read_EXCELLON_File( FILE * aFile,
const wxString & aFullFileName )
{
/* Set the gerber scale: */
wxASSERT( aFile );
// Set the default parmeter values:
ResetDefaultValues();
m_FileName = aFullFileName;
@ -230,13 +233,8 @@ bool EXCELLON_IMAGE::Read_EXCELLON_File( FILE * aFile,
LOCALE_IO toggleIo;
// 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 );
while( true )
{
if( excellonReader.ReadLine() == 0 )
@ -313,20 +311,17 @@ bool EXCELLON_IMAGE::Read_EXCELLON_File( FILE * aFile,
bool EXCELLON_IMAGE::Execute_HEADER_Command( char*& text )
{
EXCELLON_CMD* cmd = NULL;
int iprm;
double dprm;
D_CODE* dcode;
wxString msg;
// Search command in list
EXCELLON_CMD* candidate;
for( unsigned ii = 0; ; ii++ )
{
candidate = &excellonHeaderCmdList[ii];
EXCELLON_CMD* candidate = &excellonHeaderCmdList[ii];
int len = candidate->m_Name.size();
if( len == 0 ) // End of list reached
break;
if( candidate->m_Name.compare( 0, len, text, len ) == 0 ) // found.
{
cmd = candidate;
@ -463,41 +458,7 @@ bool EXCELLON_IMAGE::Execute_HEADER_Command( char*& text )
break;
case DRILL_TOOL_INFORMATION:
// 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;
readToolInformation( text );
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 )
{
D_CODE* tool;
GERBER_DRAW_ITEM * gbritem;
while( true )
{
switch( *text )
@ -528,15 +542,18 @@ bool EXCELLON_IMAGE::Execute_Drill_Command( char*& text )
break;
case 0: // E.O.L: execute command
tool = GetDCODE( m_Current_Tool, false );
if( !tool )
{
wxString msg;
msg.Printf( _( "Tool <%d> not defined" ), m_Current_Tool );
msg.Printf( _( "Tool %d not defined" ), m_Current_Tool );
ReportMessage( msg );
return false;
}
gbritem = new GERBER_DRAW_ITEM( GetParent()->GetGerberLayout(), this );
GetParent()->GetGerberLayout()->m_Drawings.Append( gbritem );
if( m_SlotOn ) // Oval hole
{
fillLineGBRITEM( gbritem,
@ -551,6 +568,7 @@ bool EXCELLON_IMAGE::Execute_Drill_Command( char*& text )
m_CurrentPos,
tool->m_Size, false );
}
StepAndRepeatItem( *gbritem );
m_PreviousPos = m_CurrentPos;
return true;
@ -568,18 +586,35 @@ bool EXCELLON_IMAGE::Execute_Drill_Command( 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 );
// T0 is legal, but is not a selection tool. it is a special command
if( tool_id >= 0 )
{
tool_id += FIRST_DCODE; // Remember: dcodes are >= FIRST_DCODE
if( tool_id > (TOOLS_MAX_COUNT - 1) )
tool_id = TOOLS_MAX_COUNT - 1;
m_Current_Tool = tool_id;
D_CODE* pt_Dcode = GetDCODE( tool_id , false );
if( pt_Dcode )
pt_Dcode->m_InUse = true;
int dcode_id = tool_id + FIRST_DCODE; // Remember: dcodes are >= FIRST_DCODE
if( dcode_id > (TOOLS_MAX_COUNT - 1) )
dcode_id = TOOLS_MAX_COUNT - 1;
m_Current_Tool = dcode_id;
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 )
text++;
@ -678,8 +713,8 @@ void EXCELLON_IMAGE::SelectUnits( bool aMetric )
* Five digit 10 micron resolution (000.00)
* Six digit 10 micron resolution (0000.00)
* 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
*/
if( aMetric )

View File

@ -456,9 +456,9 @@ void GERBVIEW_FRAME::Liste_D_Codes()
);
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)" );
list.Add( Line );
@ -485,7 +485,7 @@ void GERBVIEW_FRAME::UpdateTitleAndInfo()
text.Printf( wxT( "GerbView %s" ), GetChars( GetBuildVersion() ) );
SetTitle( text );
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 );
ClearMsgPanel();
return;