gerbview cleanup, and working towards aperture macro support

This commit is contained in:
dickelbeck 2008-11-09 02:57:42 +00:00
parent eac91489d1
commit 26736baa9b
8 changed files with 392 additions and 295 deletions

View File

@ -5,6 +5,17 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with
email address.
2008-Nov-8 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+gerview
Added support for reading in aperture macros embedded in a RS274X compatible file.
Cannot display them yet.
General cleanup of gerbview. GERBER_Descr replaced with class GERBER.
ReturnToolDescr() replaced with GERBER::GetDCODE().
D_CODEs are created lazily now. pcbnew's gerber plotting needs testing, might
have broke something there, accidentally.
2008-nov-5 UPDATE Andrey Fedorushkov <andrf@mail.ru>
================================================================================
+all:

View File

@ -31,14 +31,14 @@ void Affiche_Infos_PCB_Texte( WinEDA_BasePcbFrame* frame, TEXTE_PCB* pt_texte )
else
Affiche_1_Parametre( frame, 1, _( "PCB Text" ), pt_texte->m_Text, DARKGREEN );
Line = _( "Layer " );
Line = _( "Layer " );
Line << pt_texte->GetLayer() + 1;
Affiche_1_Parametre( frame, 28, _( "Layer:" ), Line,
g_DesignSettings.m_LayerColor[pt_texte->GetLayer()] );
Affiche_1_Parametre( frame, 36, _( "Mirror" ), wxEmptyString, GREEN );
if( (pt_texte->m_Miroir & 1) )
Affiche_1_Parametre( frame, -1, wxEmptyString, _( "No" ), DARKGREEN );
else
@ -58,58 +58,3 @@ void Affiche_Infos_PCB_Texte( WinEDA_BasePcbFrame* frame, TEXTE_PCB* pt_texte )
Affiche_1_Parametre( frame, 70, _( "V Size" ), Line, RED );
}
/*********************************************************************/
void Affiche_Infos_Piste( WinEDA_BasePcbFrame* frame, TRACK* pt_piste )
/*********************************************************************/
/* Affiche les caract principales d'un segment de piste en bas d'ecran */
{
int d_index, ii = -1;
D_CODE* pt_D_code;
int layer = ((PCB_SCREEN*)(frame->GetScreen()))->m_Active_Layer;
wxString msg;
frame->MsgPanel->EraseMsgBox();
d_index = pt_piste->GetNet();
pt_D_code = ReturnToolDescr( layer, d_index, &ii );
switch( pt_piste->Type() )
{
case TYPETRACK:
if( pt_piste->m_Shape < S_SPOT_CIRCLE )
msg = wxT( "LINE" );
else
msg = wxT( "FLASH" );
break;
case TYPEZONE:
msg = wxT( "ZONE" ); break;
default:
msg = wxT( "????" ); break;
}
Affiche_1_Parametre( frame, 1, _( "Type" ), msg, DARKCYAN );
msg.Printf( wxT( "%d" ), ii + 1 );
Affiche_1_Parametre( frame, 10, _( "Tool" ), msg, RED );
if( pt_D_code )
{
msg.Printf( wxT( "D%d" ), d_index );
Affiche_1_Parametre( frame, 20, _( "D-code" ), msg, BLUE );
Affiche_1_Parametre( frame, 30, _( "D-type" ),
pt_D_code ? g_GERBER_Tool_Type[pt_D_code->m_Shape] : _( "????" ),
BLUE );
}
msg.Printf( wxT( "%d" ), pt_piste->GetLayer() + 1 );
Affiche_1_Parametre( frame, 40, _( "Layer" ), msg, BROWN );
/* Affiche Epaisseur */
valeur_param( (unsigned) (pt_piste->m_Width), msg );
Affiche_1_Parametre( frame, 50, _( "Width" ), msg, DARKCYAN );
}

View File

@ -63,37 +63,67 @@
D10 ... = Indentification d'outils ( d'ouvertures )
*/
/*********************************/
/* class GERBER : Methodes */
/*********************************/
GERBER::GERBER( int layer )
GERBER::GERBER( int aLayer )
{
int ii;
m_Layer = aLayer; // Layer Number
m_Layer = layer; // Layer Number
m_Selected_Tool = FIRST_DCODE;
ResetDefaultValues();
for( ii = 0; ii <= MAX_TOOLS; ii++ )
m_Aperture_List[ii] = new D_CODE( ii + FIRST_DCODE );
for( unsigned ii = 0; ii < DIM( m_Aperture_List ); ii++ )
m_Aperture_List[ii] = 0;
}
GERBER::~GERBER()
{
int ii;
if( m_Aperture_List )
for( unsigned ii = 0; ii < DIM(m_Aperture_List); ii++ )
{
for( ii = 0; ii < MAX_TOOLS; ii++ )
{
delete m_Aperture_List[ii];
m_Aperture_List[ii] = NULL;
}
delete m_Aperture_List[ii];
// m_Aperture_List[ii] = NULL;
}
}
D_CODE* GERBER::GetDCODE( int aDCODE, bool create )
{
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( m_Aperture_List[ndx] == NULL )
m_Aperture_List[ndx] = new D_CODE( ndx + FIRST_DCODE );
}
return m_Aperture_List[ndx];
}
return NULL;
}
APERTURE_MACRO* GERBER::FindApertureMacro( const APERTURE_MACRO& aLookup )
{
APERTURE_MACRO_SET::iterator iter = m_aperture_macros.find( aLookup );
if( iter != m_aperture_macros.end() )
{
APERTURE_MACRO* pam = (APERTURE_MACRO*) &(*iter);
return pam;
}
return NULL; // not found
}
/******************************************/
void GERBER::ResetDefaultValues()
/******************************************/
@ -107,8 +137,9 @@ void GERBER::ResetDefaultValues()
m_NoTrailingZeros = FALSE; // True: zeros a droite supprim<69>s
m_MirorA = FALSE; // True: miror / axe A (X)
m_MirorB = FALSE; // True: miror / axe B (Y)
m_As_DCode = FALSE; // TRUE = DCodes in file (FALSE = no DCode->
// separate DCode file
m_Has_DCode = FALSE; // TRUE = DCodes in file (FALSE = no DCode->
// separate DCode file
m_Offset.x = m_Offset.y = 0; // Coord Offset
m_FmtScale.x = m_FmtScale.y = g_Default_GERBER_Format % 10;
@ -136,36 +167,27 @@ void GERBER::ResetDefaultValues()
int GERBER::ReturnUsedDcodeNumber()
/********************************************/
{
int ii, jj;
int count = 0;
jj = 0;
if( m_Aperture_List )
for( unsigned ii = 0; ii < DIM(m_Aperture_List); ii++ )
{
for( ii = 0; ii < MAX_TOOLS; ii++ )
{
if( m_Aperture_List[ii] )
if( m_Aperture_List[ii]->m_InUse || m_Aperture_List[ii]->m_Defined )
jj++;
}
++count;
}
return jj;
return count;
}
/******************************/
void GERBER::InitToolTable()
/******************************/
/* Creation du tableau des MAX_TOOLS DCodes utilisables, si il n'existe pas,
* et Init des DCodes <EFBFBD> une valeur raisonnable
*/
{
int count;
/* Init du buffer des D_CODES a des valeurs raisonnables */
for( count = 0; count < MAX_TOOLS; count++ )
for( int count = 0; count < MAX_TOOLS; count++ )
{
if( m_Aperture_List[count] == NULL )
continue;
m_Aperture_List[count]->m_Num_Dcode = count + FIRST_DCODE;
m_Aperture_List[count]->Clear_D_CODE_Data();
}
@ -184,7 +206,6 @@ void GERBER::InitToolTable()
D_CODE::D_CODE( int num_dcode )
{
m_Num_Dcode = num_dcode;
m_Macro = 0;
Clear_D_CODE_Data();
}
@ -203,6 +224,25 @@ void D_CODE::Clear_D_CODE_Data()
m_DrillShape = 0;
m_InUse = FALSE;
m_Defined = FALSE;
m_Macro = 0;
}
const wxChar* D_CODE::ShowApertureType( APERTURE_T aType )
{
const wxChar* ret;
switch( aType )
{
case APT_CIRCLE: ret = wxT( "Round" ); break;
case APT_LINE: ret = wxT( "Line" ); break;
case APT_RECT: ret = wxT( "Rect" ); break;
case APT_OVAL: ret = wxT( "Oval" ); break;
case APT_POLYGON: ret = wxT( "Poly" ); break;
case APT_MACRO: ret = wxT( "Macro" ); break;
default: ret = wxT( "???" ); break;
}
return ret;
}
@ -217,7 +257,7 @@ int WinEDA_GerberFrame::Read_D_Code_File( const wxString& D_Code_FullFileName )
char c_type_outil[256];
char line[GERBER_BUFZ];
wxString msg;
D_CODE* pt_Dcode;
D_CODE* dcode;
FILE* dest;
int layer = GetScreen()->m_Active_Layer;
int type_outil;
@ -227,6 +267,9 @@ int WinEDA_GerberFrame::Read_D_Code_File( const wxString& D_Code_FullFileName )
g_GERBER_List[layer] = new GERBER( layer );
}
GERBER* gerber = g_GERBER_List[layer];
/* Mise a jour de l'echelle gerber : */
dcode_scale = 10; /* ici unit dcode = mil, unit interne = 0.1 mil
* -> 1 unite dcode = 10 unit PCB */
@ -243,16 +286,18 @@ int WinEDA_GerberFrame::Read_D_Code_File( const wxString& D_Code_FullFileName )
return -1;
}
g_GERBER_List[layer]->InitToolTable();
gerber->InitToolTable();
while( fgets( line, sizeof(line) - 1, dest ) != NULL )
{
if( *line == ';' )
continue; /* Commentaire */
if( strlen( line ) < 10 )
continue; /* Probablemant ligne vide */
pt_Dcode = NULL; current_Dcode = 0;
dcode = NULL;
current_Dcode = 0;
/* Determination du type de fichier D_Code */
ptcar = line;
@ -277,7 +322,9 @@ int WinEDA_GerberFrame::Read_D_Code_File( const wxString& D_Code_FullFileName )
}
else /* valeurs en inches a convertir en mils */
{
fdrill = 0; current_Dcode = 0; fdrill = 0;
fdrill = 0;
current_Dcode = 0;
sscanf( line, "%f,%f,%1s", &fdimV, &fdimH, c_type_outil );
ptcar = line;
while( *ptcar )
@ -311,12 +358,12 @@ int WinEDA_GerberFrame::Read_D_Code_File( const wxString& D_Code_FullFileName )
if( current_Dcode >= MAX_TOOLS )
continue;
pt_Dcode = ReturnToolDescr( layer, current_Dcode );
pt_Dcode->m_Size.x = dimH;
pt_Dcode->m_Size.y = dimV;
pt_Dcode->m_Shape = (APERTURE_T) type_outil;
pt_Dcode->m_Drill.x = pt_Dcode->m_Drill.y = drill;
pt_Dcode->m_Defined = TRUE;
dcode = gerber->GetDCODE( current_Dcode );
dcode->m_Size.x = dimH;
dcode->m_Size.y = dimV;
dcode->m_Shape = (APERTURE_T) type_outil;
dcode->m_Drill.x = dcode->m_Drill.y = drill;
dcode->m_Defined = TRUE;
}
fclose( dest );
@ -332,14 +379,15 @@ void WinEDA_GerberFrame::CopyDCodesSizeToItems()
/* Set Size Items (Lines, Flashes) from DCodes List
*/
{
TRACK* track;
D_CODE* pt_Dcode; /* Pointeur sur le D code*/
track = m_Pcb->m_Track;
for( ; track != NULL; track = (TRACK*) track->Pnext )
for( TRACK* track = m_Pcb->m_Track; track; track = track->Next() )
{
pt_Dcode = ReturnToolDescr( track->GetLayer(), track->GetNet() );
pt_Dcode->m_InUse = TRUE;
GERBER* gerber = g_GERBER_List[track->GetLayer()];
wxASSERT( gerber );
D_CODE* dcode = gerber->GetDCODE( track->GetNet(), false );
wxASSERT( dcode );
dcode->m_InUse = TRUE;
if( // Line Item
(track->m_Shape == S_SEGMENT ) /* segment rectiligne */
@ -349,12 +397,12 @@ void WinEDA_GerberFrame::CopyDCodesSizeToItems()
|| (track->m_Shape == S_ARC_RECT ) /* segment en arc de cercle (bouts droits) (GERBER)*/
)
{
track->m_Width = pt_Dcode->m_Size.x;
track->m_Width = dcode->m_Size.x;
}
else // Spots ( Flashed Items )
{
int width, len;
wxSize size = pt_Dcode->m_Size;
wxSize size = dcode->m_Size;
width = MIN( size.x, size.y );
len = MAX( size.x, size.y ) - width;
@ -365,7 +413,7 @@ void WinEDA_GerberFrame::CopyDCodesSizeToItems()
track->m_Start.y = (track->m_Start.y + track->m_End.y) / 2;
track->m_End = track->m_Start; // m_Start = m_End = Spot center
switch( pt_Dcode->m_Shape )
switch( dcode->m_Shape )
{
case APT_LINE: // ne devrait pas etre utilis<69> ici
case APT_CIRCLE: /* spot round (for GERBER)*/
@ -397,26 +445,6 @@ void WinEDA_GerberFrame::CopyDCodesSizeToItems()
}
/*********************************************************/
D_CODE* ReturnToolDescr( int layer, int Dcode, int* index )
/*********************************************************/
{
GERBER* gerber = g_GERBER_List[layer];
D_CODE* pt_dcode = NULL;
if( index )
*index = 0;
if( gerber && Dcode >= FIRST_DCODE && Dcode < MAX_TOOLS )
{
pt_dcode = gerber->m_Aperture_List[Dcode - FIRST_DCODE];
if( index )
*index = Dcode - FIRST_DCODE + 1;
}
return pt_dcode;
}
/************************************************/
void WinEDA_GerberFrame::Liste_D_Codes( wxDC* DC )
/************************************************/
@ -427,15 +455,13 @@ void WinEDA_GerberFrame::Liste_D_Codes( wxDC* DC )
WinEDA_TextFrame* List;
int scale = 10000;
int curr_layer = GetScreen()->m_Active_Layer;
int layer;
GERBER* gerber;
/* Construction de la liste des messages */
List = new WinEDA_TextFrame( this, _( "List D codes" ) );
for( layer = 0; layer < 32; layer++ )
for( int layer = 0; layer < 32; layer++ )
{
gerber = g_GERBER_List[layer];
GERBER* gerber = g_GERBER_List[layer];
if( gerber == NULL )
continue;
@ -450,7 +476,7 @@ void WinEDA_GerberFrame::Liste_D_Codes( wxDC* DC )
for( ii = 0, jj = 1; ii < MAX_TOOLS; ii++ )
{
pt_D_code = gerber->m_Aperture_List[ii];
pt_D_code = gerber->GetDCODE( ii + FIRST_DCODE, false );
if( pt_D_code == NULL )
continue;
@ -463,7 +489,8 @@ void WinEDA_GerberFrame::Liste_D_Codes( wxDC* DC )
pt_D_code->m_Num_Dcode,
(float) pt_D_code->m_Size.y / scale,
(float) pt_D_code->m_Size.x / scale,
g_GERBER_Tool_Type[pt_D_code->m_Shape] );
D_CODE::ShowApertureType( pt_D_code->m_Shape )
);
if( !pt_D_code->m_Defined )
Line += wxT( " ?" );

View File

@ -58,16 +58,6 @@ enum APERTURE_T
APT_MACRO = 'M'
};
/* replaced by APERTURE_T
enum Gerb_StandardShape {
GERB_CIRCLE = 1,
GERB_RECT,
GERB_LINE,
GERB_OVALE,
GERB_SPECIAL_SHAPE
};
*/
// Interpolation type
enum Gerb_Interpolation {
@ -111,22 +101,50 @@ enum Gerb_Analyse_Cmd {
ENTER_RS274X_CMD
};
class D_CODE;
/**
* Struct DCODE_PARAM
* Class DCODE_PARAM
* holds a parameter for a DCODE or an "aperture macro" as defined within standard RS274X.
* The \a value field can be either a constant or a place holder for a DCODE
* parameter.
*/
struct DCODE_PARAM
class DCODE_PARAM
{
public:
DCODE_PARAM() :
isImmediate(true),
index(-1),
value(0.0)
{}
bool isImmediate; ///< the \a value field is an actual value, not a parameter place holder.
double value; ///< if immediate then the value, else an integer index into D_CODE.m_am_params.
double GetValue( const D_CODE* aDcode );
void SetValue( double aValue )
{
value = aValue;
index = -1;
}
/**
* Function IsImmediate
* tests if this DCODE_PARAM holds an immediate parameter or is a pointer into
* a parameter held by an owning D_CODE.
*/
bool IsImmediate() { return index == -1; }
int GetIndex()
{
return index;
}
void SetIndex( int aIndex )
{
index = aIndex;
}
private:
int index; ///< if -1, then \a value field is an immediate value, else this is an index into a D_CODE parameter.
double value; ///< if immediate then the value, else an integer index into D_CODE.m_am_params.
};
@ -183,7 +201,7 @@ struct APERTURE_MACRO
*/
struct APERTURE_MACRO_less_than
{
// a "less than" test on two wxStrings
// a "less than" test on two APERTURE_MACROs (.name wxStrings)
bool operator()( const APERTURE_MACRO& am1, const APERTURE_MACRO& am2) const
{
return am1.name.Cmp( am2.name ) < 0; // case specific wxString compare
@ -206,6 +224,14 @@ typedef std::pair<APERTURE_MACRO_SET::iterator, bool> APERTURE_MACRO_SET_PAIR;
*/
class D_CODE
{
APERTURE_MACRO* m_Macro; ///< no ownership, points to GERBER.m_aperture_macros element
/**
* parameters used only when this D_CODE holds a reference to an aperture
* macro, and these parameters would customize the macro.
*/
DCODE_PARAMS m_am_params;
public:
wxSize m_Size; /* Dimensions horiz et Vert */
APERTURE_T m_Shape; /* shape ( Line, rect , circulaire , ovale .. ) */
@ -216,27 +242,55 @@ public:
bool m_Defined; /* FALSE si non defini */
wxString m_SpecialDescr;
APERTURE_MACRO* m_Macro; ///< no ownership, points to GERBER.m_aperture_macros element
/**
* parameters used only when this D_CODE holds a reference to an aperture
* macro, and these parameters would customize the macro.
*/
DCODE_PARAMS m_am_params;
public:
D_CODE( int num_dcode );
~D_CODE();
void Clear_D_CODE_Data();
void AppendParam( double aValue )
{
DCODE_PARAM param;
param.SetValue( aValue );
m_am_params.push_back( param );
}
void SetMacro( APERTURE_MACRO* aMacro )
{
m_Macro = aMacro;
}
/**
* Function ShowApertureType
* returns a character string telling what type of aperture type \a aType is.
* @param aType The aperture type to show.
*/
static const wxChar* ShowApertureType( APERTURE_T aType );
};
inline double DCODE_PARAM::GetValue( const D_CODE* aDcode )
{
if( IsImmediate() )
return value;
else
{
// get the parameter from aDcode
return 0.0;
}
}
/**
* Class GERBER
* holds the data for one gerber file or layer
*/
class GERBER
{
D_CODE* m_Aperture_List[MAX_TOOLS]; ///< Dcode (Aperture) List for this layer
public:
wxString m_FileName; // Full File Name for this layer
wxString m_Name; // Layer name
@ -247,7 +301,7 @@ public:
bool m_NoTrailingZeros; // True: zeros a droite supprimés
bool m_MirorA; // True: miror / axe A (X)
bool m_MirorB; // True: miror / axe B (Y)
bool m_As_DCode; // TRUE = DCodes in file (FALSE = no DCode->
bool m_Has_DCode; // TRUE = DCodes in file (FALSE = no DCode->
// separate DCode file
wxPoint m_Offset; // Coord Offset
wxSize m_FmtScale; // Fmt 2.3: m_FmtScale = 3, fmt 3.4: m_FmtScale = 4
@ -262,7 +316,6 @@ public:
wxPoint m_CurrentPos; // current specified coord for plot
wxPoint m_PreviousPos; // old current specified coord for plot
wxPoint m_IJPos; // IJ coord (for arcs & circles )
D_CODE* m_Aperture_List[MAX_TOOLS + FIRST_DCODE + 1]; // Dcode (Aperture) List for this layer
FILE* m_Current_File; // Current file to read
FILE* m_FilesList[12]; // Files list
@ -283,6 +336,11 @@ public:
void Clear_GERBER();
int ReturnUsedDcodeNumber();
void ResetDefaultValues();
/**
* Function InitToolTable
*/
void InitToolTable();
// Routines utilisées en lecture de ficher gerber
@ -324,6 +382,26 @@ public:
* @return bool - true if a macro was read in successfully, else false.
*/
bool ReadApertureMacro( char aBuff[GERBER_BUFZ], char*& text, FILE* gerber_file );
/**
* Function GetDCODE
* 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.
* @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 );
/**
* Function FindApertureMacro
* looks up a previously read in aperture macro.
* @param aLookup A dummy APERTURE_MACRO with [only] the name field set.
* @return APERTURE_MACRO* - the one with a matching name, or NULL if not found.
*/
APERTURE_MACRO* FindApertureMacro( const APERTURE_MACRO& aLookup );
};
@ -334,27 +412,6 @@ public:
bool GetEndOfBlock( char buff[GERBER_BUFZ], char*& text, FILE* gerber_file );
/**
* Function ReturnToolDescr
* returns a D_CODE given a global layer index and Dcode value.
* @param aLayer The index into the global array of GERBER called g_GERBER_List[].
* @param aDcode The dcode value to look up.
* @param aIndex If not null, where to put a one basedindex into the GERBER's m_Aperture_List[] array.
* @return D_CODE* - the looked up D_CODE or NULL if none was encountered in the gerber file for given \a aDcode.
*/
D_CODE * ReturnToolDescr( int layer, int Dcode, int * index = NULL );
eda_global const wxChar* g_GERBER_Tool_Type[6]
#ifdef MAIN
= {
wxT( "????" ), wxT( "Round" ), wxT( "Rect" ), wxT( "Line" ), wxT( "Oval" ), wxT( "Macro" )
}
#endif
;
eda_global GERBER* g_GERBER_List[32];

View File

@ -261,7 +261,7 @@ bool WinEDA_GerberFrame::Read_GERBER_File( wxDC* DC,
/* Init DCodes list and perhaps read a DCODES file,
* if the gerber file is only a RS274D file (without any aperture information)
*/
if( !gerber->m_As_DCode )
if( !gerber->m_Has_DCode )
{
wxString DCodeFileName;
if( D_Code_FullFileName.IsEmpty() )

View File

@ -92,7 +92,7 @@ static int ReadInt( char*& text )
/**
* Function ReadDouble
* reads a double in from a character buffer. If there is a comma after the double,
* reads a double from an ASCII character buffer. If there is a comma after the double,
* then skip over that.
* @param text A reference to a character pointer from which the ASCII double
* is read from and the pointer advanced for each character read.
@ -171,9 +171,7 @@ bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& t
{
int code;
int xy_seq_len, xy_seq_char;
char ctmp;
bool ok = TRUE;
D_CODE* dcode;
char line[GERBER_BUFZ];
wxString msg;
double fcoord;
@ -221,19 +219,21 @@ bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& t
case 'X':
case 'Y': // Valeurs transmises :2 (really xy_seq_len : FIX ME) digits
code = *(text++);
ctmp = *(text++) - '0';
if( code == 'X' )
{
m_FmtScale.x = *text - '0'; // = nb chiffres apres la virgule
m_FmtLen.x = ctmp + m_FmtScale.x; // = nb total de chiffres
code = *(text++);
char ctmp = *(text++) - '0';
if( code == 'X' )
{
m_FmtScale.x = *text - '0'; // = nb chiffres apres la virgule
m_FmtLen.x = ctmp + m_FmtScale.x; // = nb total de chiffres
}
else
{
m_FmtScale.y = *text - '0';
m_FmtLen.y = ctmp + m_FmtScale.y;
}
text++;
}
else
{
m_FmtScale.y = *text - '0';
m_FmtLen.y = ctmp + m_FmtScale.y;
}
text++;
break;
case '*':
@ -321,10 +321,6 @@ bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& t
m_LayerNegative = FALSE;
break;
case AP_MACRO:
ReadApertureMacro( buff, text, m_Current_File );
break;
case INCLUDE_FILE:
if( m_FilesPtr >= 10 )
{
@ -349,29 +345,45 @@ bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& t
m_FilesPtr++;
break;
case AP_MACRO:
ok = ReadApertureMacro( buff, text, m_Current_File );
if( !ok )
break;
break;
case AP_DEFINITION:
if( *text != 'D' )
// input example: %ADD30R,0.081800X0.101500*%
// at this point, text points to 2nd 'D'
if( *text++ != 'D' )
{
ok = FALSE;
break;
}
m_As_DCode = TRUE;
text++;
m_Has_DCode = TRUE;
code = ReadInt( text );
ctmp = *text;
dcode = ReturnToolDescr( m_Layer, code );
D_CODE* dcode;
dcode = GetDCODE( code );
if( dcode == NULL )
break;
if( text[1] == ',' ) // Tool usuel (C,R,O,P)
// at this point, text points to character after the ADD<num>, i.e. R in example above
// if text[0] is one of the usual apertures: (C,R,O,P), there is a comma after it.
if( text[1] == ',' )
{
text += 2; // text pointe size ( 1er modifier)
char stdAperture = *text;
text += 2; // skip "C," for example
dcode->m_Size.x = dcode->m_Size.y =
(int) round( ReadDouble( text ) * conv_scale );
switch( ctmp )
switch( stdAperture )
{
case 'C': // Circle
dcode->m_Shape = APT_CIRCLE;
@ -402,7 +414,7 @@ bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& t
case 'O': // oval
case 'R': // rect
dcode->m_Shape = (ctmp == 'O') ? APT_OVAL : APT_RECT;
dcode->m_Shape = (stdAperture == 'O') ? APT_OVAL : APT_RECT;
while( *text == ' ' )
text++;
@ -444,6 +456,40 @@ bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& t
break;
}
}
else // text[0] starts an aperture macro name
{
APERTURE_MACRO am_lookup;
while( *text && *text!='*' && *text!=',' )
am_lookup.name.Append( *text++ );
if( *text && *text==',' )
{
while( *text && *text!='*' )
{
double param = ReadDouble( text );
if( *text == 'X' )
++text;
dcode->AppendParam( param );
}
}
// lookup the aperture macro here.
APERTURE_MACRO* pam = FindApertureMacro( am_lookup );
if( !pam )
{
// @todo not found, don't know how to report an error
D( printf("aperture macro %s not found\n", CONV_TO_UTF8(am_lookup.name) );)
ok = false;
break;
}
D(printf("pam has %d parameters\n", pam->primitives.size() );)
dcode->SetMacro( (APERTURE_MACRO*) pam );
}
break;
default:
@ -531,7 +577,6 @@ bool GERBER::ReadApertureMacro( char buff[GERBER_BUFZ], char*& text, FILE* gerbe
switch( prim.primitive_id )
{
default:
case AMP_CIRCLE:
paramCount = 4;
break;
@ -558,43 +603,48 @@ bool GERBER::ReadApertureMacro( char buff[GERBER_BUFZ], char*& text, FILE* gerbe
case AMP_THERMAL:
paramCount = 6;
break;
default:
// @todo, there needs to be a way of reporting the line number and character offset.
D(printf("Invalid primitive id code %d\n", prim.primitive_id );)
return false;
}
DCODE_PARAM param;
for( int i=0; i<paramCount && *text && *text!='*'; ++i )
{
DCODE_PARAM param; // construct it on each loop iteration
if( *text == '$' )
{
++text;
param.isImmediate = false;
param.SetIndex( ReadInt( text ) );
}
else
{
param.isImmediate = true;
}
param.SetValue( ReadDouble( text ) );
param.value = ReadDouble( text );
prim.params.push_back( param );
}
// there are more parameters to read if this is an AMP_OUTLINE
if( prim.primitive_id == AMP_OUTLINE )
{
paramCount = (int) prim.params[1].value * 2 + 1;
// params[1] is a count of polygon points, so it must be given
// in advance, i.e. be immediate.
wxASSERT( prim.params[1].IsImmediate() );
paramCount = (int) prim.params[1].GetValue(0) * 2 + 1;
for( int i=0; i<paramCount && *text && *text!='*'; ++i )
{
DCODE_PARAM param; // construct it on each loop
if( *text == '$' )
{
++text;
param.isImmediate = false;
param.SetIndex( ReadInt( text ) );
}
else
{
param.isImmediate = true;
}
param.SetValue( ReadDouble( text ) );
param.value = ReadDouble( text );
prim.params.push_back( param );
}
}

View File

@ -25,6 +25,10 @@
#define ABS( y ) ( (y) >= 0 ? (y) : ( -(y) ) )
#endif
/// # of elements in an arrray
#define DIM(x) (sizeof(x)/sizeof((x)[0]))
#define DEG2RAD( Deg ) ( (Deg) * M_PI / 180.0 )
#define RAD2DEG( Rad ) ( (Rad) * 180.0 / M_PI )

View File

@ -1,6 +1,6 @@
/************/
/* pcbplot.h*/
/************/
/************/
/* pcbplot.h*/
/************/
#ifndef PLOTGERB_H
#define PLOTGERB_H
@ -8,81 +8,84 @@
/* Format Gerber : NOTES :
Fonctions preparatoires:
Gn =
G01 interpolation lineaire ( trace de droites )
G02,G20,G21 Interpolation circulaire , sens trigo < 0
G03,G30,G31 Interpolation circulaire , sens trigo > 0
G04 commentaire
G06 Interpolation parabolique
G07 Interpolation cubique
G10 interpolation lineaire ( echelle 10x )
G11 interpolation lineaire ( echelle 0.1x )
G12 interpolation lineaire ( echelle 0.01x )
G36 Start polygon description
G37 End polygon description
G52 plot symbole reference par Dnn code
G53 plot symbole reference par Dnn ; symbole tourne de -90 degres
G54 Selection d'outil
G55 Mode exposition photo
G56 plot symbole reference par Dnn A code
G57 affiche le symbole reference sur la console
G58 plot et affiche le symbole reference sur la console
G60 interpolation lineaire ( echelle 100x )
G70 Unites = Inches
G71 Unites = Millimetres
G74 supprime interpolation circulaire sur 360 degre, revient a G01
G75 Active interpolation circulaire sur 360 degre
G90 Mode Coordonnees absolues
G91 Mode Coordonnees Relatives
Gn =
G01 interpolation lineaire ( trace de droites )
G02,G20,G21 Interpolation circulaire , sens trigo < 0
G03,G30,G31 Interpolation circulaire , sens trigo > 0
G04 commentaire
G06 Interpolation parabolique
G07 Interpolation cubique
G10 interpolation lineaire ( echelle 10x )
G11 interpolation lineaire ( echelle 0.1x )
G12 interpolation lineaire ( echelle 0.01x )
G36 Start polygon description
G37 End polygon description
G52 plot symbole reference par Dnn code
G53 plot symbole reference par Dnn ; symbole tourne de -90 degres
G54 Selection d'outil
G55 Mode exposition photo
G56 plot symbole reference par Dnn A code
G57 affiche le symbole reference sur la console
G58 plot et affiche le symbole reference sur la console
G60 interpolation lineaire ( echelle 100x )
G70 Unites = Inches
G71 Unites = Millimetres
G74 supprime interpolation circulaire sur 360 degre, revient a G01
G75 Active interpolation circulaire sur 360 degre
G90 Mode Coordonnees absolues
G91 Mode Coordonnees Relatives
Coordonnees X,Y
X,Y sont suivies de + ou - et de m+n chiffres (non separes)
m = partie entiere
n = partie apres la virgule
formats classiques : m = 2, n = 3 (format 2.3)
m = 3, n = 4 (format 3.4)
ex:
G__ X00345Y-06123 D__*
X,Y sont suivies de + ou - et de m+n chiffres (non separes)
m = partie entiere
n = partie apres la virgule
formats classiques : m = 2, n = 3 (format 2.3)
m = 3, n = 4 (format 3.4)
ex:
G__ X00345Y-06123 D__*
Outils et D_CODES
numero d'outil ( identification des formes )
1 a 99 (classique)
1 a 999
D_CODES:
numero d'outil ( identification des formes )
1 a 99 (classique)
1 a 999
D_CODES:
D01 ... D9 = codes d'action:
D01 = activation de lumiere ( baisser de plume)
D02 = extinction de lumiere ( lever de plume)
D03 = Flash
D09 = VAPE Flash
D51 = precede par G54 -> Select VAPE
D01 ... D9 = codes d'action:
D01 = activation de lumiere ( baisser de plume)
D02 = extinction de lumiere ( lever de plume)
D03 = Flash
D09 = VAPE Flash
D51 = precede par G54 -> Select VAPE
D10 ... D255 = Indentification d'outils ( d'ouvertures )
Ne sont pas tj dans l'ordre ( voir tableau ci dessous)
D10 ... D255 = Indentification d'outils ( d'ouvertures )
Ne sont pas tj dans l'ordre ( voir tableau ci dessous)
*/
/*************************************/
/* Constantes utiles en trace GERBER */
/*************************************/
/*************************************/
/* Constantes utiles en trace GERBER */
/*************************************/
/* codes de type de forme d'outils */
/*
#define GERB_CIRCLE 1
#define GERB_RECT 2
#define GERB_LINE 3
#define GERB_OVALE 4
#define GERB_DONUT 5
*/
/* liste des D_CODES en fonction de leur numero d'ordre (numero d'outil)
(l'ordre 0 n'est pas utilise) ;
Tools have D_CODES >= 10
D_CODES <= 9 are used for commands only:
D01 ... D9 = command codes for photo plotting:
D01 = Light on
D02 = Light off
D03 = Flash
D04 .. D08 = ?
D09 = VAPE Flash
(l'ordre 0 n'est pas utilise) ;
Tools have D_CODES >= 10
D_CODES <= 9 are used for commands only:
D01 ... D9 = command codes for photo plotting:
D01 = Light on
D02 = Light off
D03 = Flash
D04 .. D08 = ?
D09 = VAPE Flash
*/
#define FIRST_DCODE_VALUE 10
@ -91,17 +94,17 @@ Outils et D_CODES
class D_CODE
{
public:
D_CODE * m_Pnext, * m_Pback; /* for a linked list */
wxSize m_Size; /* horiz and Vert size*/
int m_Type; /* Type ( Line, rect , circulaire , ovale .. ); -1 = not used (free) descr */
int m_NumDcode; /* code number ( >= 10 ); 0 = not in use */
D_CODE * m_Pnext, * m_Pback; /* for a linked list */
wxSize m_Size; /* horiz and Vert size*/
int m_Type; /* Type ( Line, rect , circulaire , ovale .. ); -1 = not used (free) descr */
int m_NumDcode; /* code number ( >= 10 ); 0 = not in use */
D_CODE()
{
m_Pnext = m_Pback = NULL;
m_Type = -1;
m_NumDcode = 0;
}
D_CODE()
{
m_Pnext = m_Pback = NULL;
m_Type = -1;
m_NumDcode = 0;
}
} ;