From df29e89c4a5ca3cc4521bc359a2a52b78b9dd49e Mon Sep 17 00:00:00 2001 From: dickelbeck Date: Sat, 8 Nov 2008 06:44:07 +0000 Subject: [PATCH] beginnings of aperture macro support --- gerbview/dcode.cpp | 147 +++++++++----------- gerbview/edit.cpp | 2 +- gerbview/export_to_pcbnew.cpp | 20 +-- gerbview/gerberframe.cpp | 8 +- gerbview/gerbview.h | 217 ++++++++++++++++++++++++------ gerbview/initpcb.cpp | 4 +- gerbview/readgerb.cpp | 64 ++++----- gerbview/rs274d.cpp | 44 +++--- gerbview/rs274x.cpp | 185 ++++++++++++++++++++----- gerbview/select_layers_to_pcb.cpp | 4 +- gerbview/tool_gerber.cpp | 6 +- gerbview/trpiste.cpp | 6 +- 12 files changed, 467 insertions(+), 240 deletions(-) diff --git a/gerbview/dcode.cpp b/gerbview/dcode.cpp index 0a3660bbca..bbacdaf018 100644 --- a/gerbview/dcode.cpp +++ b/gerbview/dcode.cpp @@ -64,10 +64,10 @@ */ /*********************************/ -/* class GERBER_Descr : Methodes */ +/* class GERBER : Methodes */ /*********************************/ -GERBER_Descr::GERBER_Descr( int layer ) +GERBER::GERBER( int layer ) { int ii; @@ -79,7 +79,7 @@ GERBER_Descr::GERBER_Descr( int layer ) } -GERBER_Descr::~GERBER_Descr() +GERBER::~GERBER() { int ii; @@ -95,12 +95,9 @@ GERBER_Descr::~GERBER_Descr() /******************************************/ -void GERBER_Descr::ResetDefaultValues() +void GERBER::ResetDefaultValues() /******************************************/ { - m_Parent = NULL; - m_Pback = NULL; - m_Pnext = NULL; m_FileName.Empty(); m_Name = wxT( "no name" ); // Layer name m_LayerNegative = FALSE; // TRUE = Negative Layer @@ -136,7 +133,7 @@ void GERBER_Descr::ResetDefaultValues() /********************************************/ -int GERBER_Descr::ReturnUsedDcodeNumber() +int GERBER::ReturnUsedDcodeNumber() /********************************************/ { int ii, jj; @@ -155,7 +152,7 @@ int GERBER_Descr::ReturnUsedDcodeNumber() /******************************/ -void GERBER_Descr::InitToolTable() +void GERBER::InitToolTable() /******************************/ /* Creation du tableau des MAX_TOOLS DCodes utilisables, si il n'existe pas, @@ -187,6 +184,7 @@ void GERBER_Descr::InitToolTable() D_CODE::D_CODE( int num_dcode ) { m_Num_Dcode = num_dcode; + m_Macro = 0; Clear_D_CODE_Data(); } @@ -200,7 +198,7 @@ void D_CODE::Clear_D_CODE_Data() { m_Size.x = DEFAULT_SIZE; m_Size.y = DEFAULT_SIZE; - m_Shape = GERB_CIRCLE; + m_Shape = APT_CIRCLE; m_Drill.x = m_Drill.y = 0; m_DrillShape = 0; m_InUse = FALSE; @@ -211,44 +209,22 @@ void D_CODE::Clear_D_CODE_Data() /******************************************************************************/ int WinEDA_GerberFrame::Read_D_Code_File( const wxString& D_Code_FullFileName ) /******************************************************************************/ - -/* Routine de Lecture d'un fichier de D Codes. - * Accepte format standard ou ALSPCB - * un ';' demarre un commentaire. - * - * Format Standard: - * tool, Horiz, Vert, drill, vitesse, acc. ,Type ; [DCODE (commentaire)] - * ex: 1, 12, 12, 0, 0, 0, 3 ; D10 - * - * Format: - * Ver , Hor , Type , Tool [,Drill] - * ex: 0.012, 0.012, L , D10 - * - * Classe les caract en buf_tmp sous forme de tableau de structures D_CODE. - * Retourne: - * < 0 si erreur: - * -1 = Fichier non trouve - * -2 = Erreur lecture fichier - * 0 si pas de nom de fichier (inits seules) - * 1 si OK - */ { int current_Dcode, ii, dcode_scale; char* ptcar; - int dimH, dimV, drill, type_outil, dummy; + int dimH, dimV, drill, dummy; float fdimH, fdimV, fdrill; char c_type_outil[256]; - char Line[2000]; + char line[GERBER_BUFZ]; wxString msg; D_CODE* pt_Dcode; FILE* dest; int layer = GetScreen()->m_Active_Layer; - D_CODE** ListeDCode; + int type_outil; - - if( g_GERBER_Descr_List[layer] == NULL ) + if( g_GERBER_List[layer] == NULL ) { - g_GERBER_Descr_List[layer] = new GERBER_Descr( layer ); + g_GERBER_List[layer] = new GERBER( layer ); } /* Mise a jour de l'echelle gerber : */ @@ -260,7 +236,6 @@ int WinEDA_GerberFrame::Read_D_Code_File( const wxString& D_Code_FullFileName ) return 0; dest = wxFopen( D_Code_FullFileName, wxT( "rt" ) ); - if( dest == 0 ) { msg = _( "File " ) + D_Code_FullFileName + _( " not found" ); @@ -268,30 +243,31 @@ int WinEDA_GerberFrame::Read_D_Code_File( const wxString& D_Code_FullFileName ) return -1; } - g_GERBER_Descr_List[layer]->InitToolTable(); + g_GERBER_List[layer]->InitToolTable(); - ListeDCode = g_GERBER_Descr_List[layer]->m_Aperture_List; - - while( fgets( Line, sizeof(Line) - 1, dest ) != NULL ) + while( fgets( line, sizeof(line) - 1, dest ) != NULL ) { - if( *Line == ';' ) + if( *line == ';' ) continue; /* Commentaire */ - if( strlen( Line ) < 10 ) + if( strlen( line ) < 10 ) continue; /* Probablemant ligne vide */ pt_Dcode = NULL; current_Dcode = 0; + /* Determination du type de fichier D_Code */ - ptcar = Line; ii = 0; + ptcar = line; + ii = 0; while( *ptcar ) if( *(ptcar++) == ',' ) ii++; if( ii >= 6 ) /* valeurs en mils */ { - sscanf( Line, "%d,%d,%d,%d,%d,%d,%d", &ii, + sscanf( line, "%d,%d,%d,%d,%d,%d,%d", &ii, &dimH, &dimV, &drill, &dummy, &dummy, &type_outil ); + dimH = (int) ( (dimH * dcode_scale) + 0.5 ); dimV = (int) ( (dimV * dcode_scale) + 0.5 ); drill = (int) ( (drill * dcode_scale) + 0.5 ); @@ -302,13 +278,14 @@ 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; - sscanf( Line, "%f,%f,%1s", &fdimV, &fdimH, c_type_outil ); - ptcar = Line; + sscanf( line, "%f,%f,%1s", &fdimV, &fdimH, c_type_outil ); + ptcar = line; while( *ptcar ) { if( *ptcar == 'D' ) { - sscanf( ptcar + 1, "%d,%f", ¤t_Dcode, &fdrill ); break; + sscanf( ptcar + 1, "%d,%f", ¤t_Dcode, &fdrill ); + break; } else ptcar++; @@ -317,29 +294,27 @@ int WinEDA_GerberFrame::Read_D_Code_File( const wxString& D_Code_FullFileName ) dimH = (int) ( (fdimH * dcode_scale * 1000) + 0.5 ); dimV = (int) ( (fdimV * dcode_scale * 1000) + 0.5 ); drill = (int) ( (fdrill * dcode_scale * 1000) + 0.5 ); - type_outil = -1; - if( c_type_outil[0] == 'L' ) - type_outil = GERB_LINE; - if( c_type_outil[0] == 'R' ) - type_outil = GERB_RECT; - if( c_type_outil[0] == 'C' ) - type_outil = GERB_CIRCLE; - if( c_type_outil[0] == 'O' ) - type_outil = GERB_OVALE; - if( type_outil == -1 ) + + if( strchr( "CLROP", c_type_outil[0] ) ) + type_outil = (APERTURE_T) c_type_outil[0]; + else { - fclose( dest ); return -2; + fclose( dest ); + return -2; } } + /* Mise a jour de la liste des d_codes si valeurs lues coherentes*/ if( current_Dcode < FIRST_DCODE ) continue; + 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 = type_outil; + pt_Dcode->m_Shape = (APERTURE_T) type_outil; pt_Dcode->m_Drill.x = pt_Dcode->m_Drill.y = drill; pt_Dcode->m_Defined = TRUE; } @@ -392,12 +367,12 @@ void WinEDA_GerberFrame::CopyDCodesSizeToItems() switch( pt_Dcode->m_Shape ) { - case GERB_LINE: // ne devrait pas etre utilis� ici - case GERB_CIRCLE: /* spot rond (for GERBER)*/ + case APT_LINE: // ne devrait pas etre utilis� ici + case APT_CIRCLE: /* spot round (for GERBER)*/ track->m_Shape = S_SPOT_CIRCLE; break; - case GERB_OVALE: /* spot ovale (for GERBER)*/ + case APT_OVAL: /* spot oval (for GERBER)*/ track->m_Shape = S_SPOT_OVALE; break; @@ -425,19 +400,16 @@ void WinEDA_GerberFrame::CopyDCodesSizeToItems() /*********************************************************/ D_CODE* ReturnToolDescr( int layer, int Dcode, int* index ) /*********************************************************/ - -/* Retourne un pointeur sur la description de l'outil DCode de reference Dcode - * (rappel : Dcode >= 10) - */ { - GERBER_Descr* DcodeList = g_GERBER_Descr_List[layer]; - D_CODE* pt_dcode = NULL; + GERBER* gerber = g_GERBER_List[layer]; + D_CODE* pt_dcode = NULL; if( index ) *index = 0; - if( DcodeList && Dcode >= FIRST_DCODE && Dcode < MAX_TOOLS ) + + if( gerber && Dcode >= FIRST_DCODE && Dcode < MAX_TOOLS ) { - pt_dcode = DcodeList->m_Aperture_List[Dcode - FIRST_DCODE]; + pt_dcode = gerber->m_Aperture_List[Dcode - FIRST_DCODE]; if( index ) *index = Dcode - FIRST_DCODE + 1; } @@ -449,25 +421,27 @@ D_CODE* ReturnToolDescr( int layer, int Dcode, int* index ) void WinEDA_GerberFrame::Liste_D_Codes( wxDC* DC ) /************************************************/ { - int ii, jj; - D_CODE* pt_D_code; - wxString Line; - WinEDA_TextFrame* List; - int scale = 10000; - int curr_layer = GetScreen()->m_Active_Layer; - int layer; - GERBER_Descr* DcodeList; + int ii, jj; + D_CODE* pt_D_code; + wxString Line; + 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++ ) { - DcodeList = g_GERBER_Descr_List[layer]; - if( DcodeList == NULL ) + gerber = g_GERBER_List[layer]; + if( gerber == NULL ) continue; - if( DcodeList->ReturnUsedDcodeNumber() == 0 ) + + if( gerber->ReturnUsedDcodeNumber() == 0 ) continue; + if( layer == curr_layer ) Line.Printf( wxT( "*** Active layer (%2.2d) ***" ), layer + 1 ); else @@ -476,11 +450,13 @@ void WinEDA_GerberFrame::Liste_D_Codes( wxDC* DC ) for( ii = 0, jj = 1; ii < MAX_TOOLS; ii++ ) { - pt_D_code = DcodeList->m_Aperture_List[ii]; + pt_D_code = gerber->m_Aperture_List[ii]; if( pt_D_code == NULL ) continue; + if( !pt_D_code->m_InUse && !pt_D_code->m_Defined ) continue; + Line.Printf( wxT( "tool %2.2d: D%2.2d V %2.4f H %2.4f %s" ), jj, @@ -500,7 +476,8 @@ void WinEDA_GerberFrame::Liste_D_Codes( wxDC* DC ) } } - ii = List->ShowModal(); List->Destroy(); + ii = List->ShowModal(); + List->Destroy(); if( ii < 0 ) return; diff --git a/gerbview/edit.cpp b/gerbview/edit.cpp index cd3a8bb98e..a295cab2f5 100644 --- a/gerbview/edit.cpp +++ b/gerbview/edit.cpp @@ -85,7 +85,7 @@ void WinEDA_GerberFrame::Process_Special_Functions( wxCommandEvent& event ) { int id = event.GetId(); int layer = GetScreen()->m_Active_Layer; - GERBER_Descr* gerber_layer = g_GERBER_Descr_List[layer]; + GERBER* gerber_layer = g_GERBER_List[layer]; wxPoint pos; wxClientDC dc( DrawPanel ); diff --git a/gerbview/export_to_pcbnew.cpp b/gerbview/export_to_pcbnew.cpp index c0d6937ad7..ce3a9d35da 100644 --- a/gerbview/export_to_pcbnew.cpp +++ b/gerbview/export_to_pcbnew.cpp @@ -31,7 +31,7 @@ void WinEDA_GerberFrame::ExportDataInPcbnewFormat( wxCommandEvent& event ) // Check whether any of the Gerber layers are actually currently used while( no_used_layers && ii < 32 ) { - if( g_GERBER_Descr_List[ii] != NULL ) + if( g_GERBER_List[ii] != NULL ) no_used_layers = false; ii++; } @@ -152,7 +152,7 @@ static int SavePcbFormatAscii( WinEDA_GerberFrame* frame, FILE* aFile, int pcb_layer_number = LayerLookUpTable[layer]; if( pcb_layer_number < 0 || pcb_layer_number > LAST_NO_COPPER_LAYER ) continue; - + if( pcb_layer_number > LAST_COPPER_LAYER ) { DRAWSEGMENT* drawitem = new DRAWSEGMENT( pcb, TYPEDRAWSEGMENT ); @@ -167,7 +167,7 @@ static int SavePcbFormatAscii( WinEDA_GerberFrame* frame, FILE* aFile, else { TRACK* newtrack; - + // replace spots with vias when possible if( track->m_Shape == S_SPOT_CIRCLE || track->m_Shape == S_SPOT_RECT @@ -178,13 +178,13 @@ static int SavePcbFormatAscii( WinEDA_GerberFrame* frame, FILE* aFile, // A spot is found, and can be a via: change it to via, and delete other // spots at same location newtrack->m_Shape = VIA_THROUGH; - + newtrack->SetLayer( 0x0F ); // Layers are 0 to 15 (Cu/Cmp) - + newtrack->SetDrillDefault(); - // Compute the via position from track position ( Via position is the - // position of the middle of the track segment ) + // Compute the via position from track position ( Via position is the + // position of the middle of the track segment ) newtrack->m_Start.x = (newtrack->m_Start.x + newtrack->m_End.x) / 2; newtrack->m_Start.y = (newtrack->m_Start.y + newtrack->m_End.y) / 2; newtrack->m_End = newtrack->m_Start; @@ -194,7 +194,7 @@ static int SavePcbFormatAscii( WinEDA_GerberFrame* frame, FILE* aFile, newtrack = track->Copy(); newtrack->SetLayer( pcb_layer_number ); } - + newtrack->Insert( pcb, NULL ); } } @@ -204,7 +204,7 @@ static int SavePcbFormatAscii( WinEDA_GerberFrame* frame, FILE* aFile, { if( track->m_Shape != VIA_THROUGH ) continue; - + // Search and delete others vias TRACK* next_track; TRACK* alt_track = track->Next(); @@ -225,7 +225,7 @@ static int SavePcbFormatAscii( WinEDA_GerberFrame* frame, FILE* aFile, // Switch the locale to standard C (needed to print floating point numbers like 1.3) SetLocaleTo_C_standard( ); - + // write the PCB heading fprintf( aFile, "PCBNEW-BOARD Version %d date %s\n\n", g_CurrentVersionPCB, DateAndTime( line ) ); diff --git a/gerbview/gerberframe.cpp b/gerbview/gerberframe.cpp index 4be8217c0b..c08a47febb 100644 --- a/gerbview/gerberframe.cpp +++ b/gerbview/gerberframe.cpp @@ -209,7 +209,7 @@ void WinEDA_GerberFrame::SetToolbars() */ { int layer = ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer; - GERBER_Descr* Gerber_layer_descr = g_GERBER_Descr_List[layer]; + GERBER* gerber = g_GERBER_List[layer]; if( m_HToolBar == NULL ) return; @@ -242,14 +242,14 @@ void WinEDA_GerberFrame::SetToolbars() m_SelLayerBox->SetSelection( ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer ); } - if( Gerber_layer_descr ) + if( gerber ) { int sel_index; m_SelLayerTool->Enable( TRUE ); - if( Gerber_layer_descr->m_Selected_Tool < FIRST_DCODE ) // No tool selected + if( gerber->m_Selected_Tool < FIRST_DCODE ) // No tool selected sel_index = 0; else - sel_index = Gerber_layer_descr->m_Selected_Tool - FIRST_DCODE + 1; + sel_index = gerber->m_Selected_Tool - FIRST_DCODE + 1; if( sel_index != m_SelLayerTool->GetSelection() ) { diff --git a/gerbview/gerbview.h b/gerbview/gerbview.h index 6a9bf6777c..554c6aeb51 100644 --- a/gerbview/gerbview.h +++ b/gerbview/gerbview.h @@ -5,6 +5,10 @@ #ifndef GERBVIEW_H #define GERBVIEW_H +#include +#include + + #ifndef eda_global #define eda_global extern #endif @@ -21,6 +25,7 @@ typedef enum { FORMAT_POST } PlotFormat; + //eda_global wxString g_Plot_FileName; eda_global wxString g_PhotoFilenameExt; eda_global wxString g_DrillFilenameExt; @@ -38,7 +43,22 @@ eda_global int g_Plot_Spot_Mini; /* Diametre mini de l'ouverture pour /* Constantes utiles en trace GERBER */ /*************************************/ -/* codes de type de forme d'outils */ +/** + * Enum APERTURE_T + * is the set of all gerber aperture types allowed, according to page 16 of + * http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf + */ +enum APERTURE_T +{ + APT_CIRCLE = 'C', + APT_LINE = 'L', + APT_RECT = 'R', + APT_OVAL = '0', + APT_POLYGON = 'P', + APT_MACRO = 'M' +}; + +/* replaced by APERTURE_T enum Gerb_StandardShape { GERB_CIRCLE = 1, GERB_RECT, @@ -46,6 +66,8 @@ enum Gerb_StandardShape { GERB_OVALE, GERB_SPECIAL_SHAPE }; +*/ + // Interpolation type enum Gerb_Interpolation { @@ -90,18 +112,132 @@ enum Gerb_Analyse_Cmd { }; -class D_CODE; +/** + * Struct 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 +{ + DCODE_PARAM() : + isImmediate(true), + 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. +}; + /** - * Class GERBER_Descr - * holds the data for one gerber file or layer + * Enum AM_PRIMITIVE_ID + * is the set of all "aperture macro primitives" (primitive numbers). See + * Table 3 in http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf */ -class GERBER_Descr +enum AM_PRIMITIVE_ID +{ + AMP_CIRCLE = 1, + AMP_LINE2 = 2, + AMP_LINE20 = 20, + AMP_LINE_CENTER = 21, + AMP_LINE_LOWER_LEFT = 22, + AMP_EOF = 3, + AMP_OUTLINE = 4, + AMP_POLYGON = 5, + AMP_MOIRE = 6, + AMP_THERMAL = 7, +}; + + +typedef std::vector DCODE_PARAMS; + +/** + * Struct AM_PRIMITIVE + * holds an aperture macro primitive as given in Table 3 of + * http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf + */ +struct AM_PRIMITIVE +{ + AM_PRIMITIVE_ID primitive_id; + DCODE_PARAMS params; +}; + + +typedef std::vector AM_PRIMITIVES; + +/** + * Struct APERTURE_MACRO + * helps support the "aperture macro" defined within standard RS274X. + */ +struct APERTURE_MACRO +{ + wxString name; + AM_PRIMITIVES primitives; +}; + + +/** + * Struct APERTURE_MACRO_less_than + * is used by std:set instantiation which uses APERTURE_MACRO.name as its key. + */ +struct APERTURE_MACRO_less_than +{ + // a "less than" test on two wxStrings + bool operator()( const APERTURE_MACRO& am1, const APERTURE_MACRO& am2) const + { + return am1.name.Cmp( am2.name ) < 0; // case specific wxString compare + } +}; + + +/** + * Type APERTURE_MACRO_SET + * is a sorted collection of APERTURE_MACROS whose key is the name field in + * the APERTURE_MACRO. + */ +typedef std::set APERTURE_MACRO_SET; +typedef std::pair APERTURE_MACRO_SET_PAIR; + + +/** + * Class D_CODE + * holds a gerber DCODE definition. + */ +class D_CODE +{ +public: + wxSize m_Size; /* Dimensions horiz et Vert */ + APERTURE_T m_Shape; /* shape ( Line, rect , circulaire , ovale .. ) */ + int m_Num_Dcode; /* numero de code ( >= 10 ) */ + wxSize m_Drill; /* dimension du trou central (s'il existe) */ + int m_DrillShape; /* forme du trou central ( rond = 1, rect = 2 ) */ + bool m_InUse; /* FALSE si non utilisé */ + 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(); +}; + + +/** + * Class GERBER + * holds the data for one gerber file or layer + */ +class GERBER { public: - GERBER_Descr* m_Parent; // Pointeur sur la racine pour layers imbriquées - GERBER_Descr* m_Pback; // Pointeur de chainage arriere pour layers imbriquées - GERBER_Descr* m_Pnext; // Pointeur de chainage avant pour layers imbriquées wxString m_FileName; // Full File Name for this layer wxString m_Name; // Layer name int m_Layer; // Layer Number @@ -139,10 +275,12 @@ public: bool m_PolygonFillMode; // Enbl polygon mode (read coord as a polygone descr) int m_PolygonFillModeState; // In polygon mode: 0 = first segm, 1 = next segm + APERTURE_MACRO_SET m_aperture_macros; + public: - GERBER_Descr( int layer ); - ~GERBER_Descr(); - void Clear_GERBER_Descr(); + GERBER( int layer ); + ~GERBER(); + void Clear_GERBER(); int ReturnUsedDcodeNumber(); void ResetDefaultValues(); void InitToolTable(); @@ -174,29 +312,18 @@ public: * executes 1 commande */ bool ExecuteRS274XCommand( int command, char aBuff[GERBER_BUFZ], char*& text ); -}; -/** - * Class D_CODE - * holds a gerber DCODE definition. - */ -class D_CODE -{ -public: - wxSize m_Size; /* Dimensions horiz et Vert */ - int m_Shape; /* shape ( Line, rect , circulaire , ovale .. ) */ - int m_Num_Dcode; /* numero de code ( >= 10 ) */ - wxSize m_Drill; /* dimension du trou central (s'il existe) */ - int m_DrillShape; /* forme du trou central ( rond = 1, rect = 2 ) */ - bool m_InUse; /* FALSE si non utilisé */ - bool m_Defined; /* FALSE si non defini */ - wxString m_SpecialDescr; - -public: - D_CODE( int num_dcode ); - ~D_CODE(); - void Clear_D_CODE_Data(); + /** + * Function ReadApertureMacro + * reads in an aperture macro and saves it in m_aperture_macros. + * @param aBuff a character buffer at least GERBER_BUFZ long that can be + * used to read successive lines from the gerber file. + * @param text A reference to a character pointer which gives the initial text to read from. + * @param gerber_file Which file to read from for continuation. + * @return bool - true if a macro was read in successfully, else false. + */ + bool ReadApertureMacro( char aBuff[GERBER_BUFZ], char*& text, FILE* gerber_file ); }; @@ -206,9 +333,15 @@ public: /**************/ bool GetEndOfBlock( char buff[GERBER_BUFZ], char*& text, FILE* gerber_file ); -/*************/ -/* dcode.cpp */ -/*************/ + +/** + * 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 ); @@ -222,11 +355,15 @@ eda_global const wxChar* g_GERBER_Tool_Type[6] #endif ; -eda_global GERBER_Descr* g_GERBER_Descr_List[32]; -eda_global int g_DisplayPolygonsModeSketch; /* How to show filled polygons : - * 0 = filled - * 1 = Sketch mode - */ +eda_global GERBER* g_GERBER_List[32]; + + +/** + * How to show filled polygons : + * 0 = filled + * 1 = Sketch mode + */ +eda_global int g_DisplayPolygonsModeSketch; #include "pcbnew.h" diff --git a/gerbview/initpcb.cpp b/gerbview/initpcb.cpp index 2b38d93a77..5fcc2f922c 100644 --- a/gerbview/initpcb.cpp +++ b/gerbview/initpcb.cpp @@ -56,8 +56,8 @@ bool WinEDA_GerberFrame::Clear_Pcb( bool query ) /* init pointeurs et variables */ for( layer = 0; layer < 32; layer++ ) { - if( g_GERBER_Descr_List[layer] ) - g_GERBER_Descr_List[layer]->InitToolTable(); + if( g_GERBER_List[layer] ) + g_GERBER_List[layer]->InitToolTable(); } /* remise a 0 ou a une valeur initiale des variables de la structure */ diff --git a/gerbview/readgerb.cpp b/gerbview/readgerb.cpp index b12e20280c..5878160645 100644 --- a/gerbview/readgerb.cpp +++ b/gerbview/readgerb.cpp @@ -117,37 +117,37 @@ bool WinEDA_GerberFrame::Read_GERBER_File( wxDC* DC, int G_commande = 0, D_commande = 0; /* command number for G et D commands (like G04 or D02) */ - char Line[GERBER_BUFZ]; + char line[GERBER_BUFZ]; wxString msg; char* text; int layer; /* current layer used in gerbview */ - GERBER_Descr* gerber_layer; + GERBER* gerber; wxPoint pos; int error = 0; layer = GetScreen()->m_Active_Layer; - if( g_GERBER_Descr_List[layer] == NULL ) + if( g_GERBER_List[layer] == NULL ) { - g_GERBER_Descr_List[layer] = new GERBER_Descr( layer ); + g_GERBER_List[layer] = new GERBER( layer ); } - gerber_layer = g_GERBER_Descr_List[layer]; + gerber = g_GERBER_List[layer]; /* Set the gerber scale: */ - gerber_layer->ResetDefaultValues(); + gerber->ResetDefaultValues(); /* Read the gerber file */ - gerber_layer->m_Current_File = wxFopen( GERBER_FullFileName, wxT( "rt" ) ); - if( gerber_layer->m_Current_File == 0 ) + gerber->m_Current_File = wxFopen( GERBER_FullFileName, wxT( "rt" ) ); + if( gerber->m_Current_File == 0 ) { msg = _( "File " ) + GERBER_FullFileName + _( " not found" ); DisplayError( this, msg, 10 ); return FALSE; } - gerber_layer->m_FileName = GERBER_FullFileName; + gerber->m_FileName = GERBER_FullFileName; wxString path = wxPathOnly( GERBER_FullFileName ); if( path != wxEmptyString ) @@ -158,21 +158,21 @@ bool WinEDA_GerberFrame::Read_GERBER_File( wxDC* DC, while( TRUE ) { - if( fgets( Line, sizeof(Line), gerber_layer->m_Current_File ) == NULL ) // E.O.F + if( fgets( line, sizeof(line), gerber->m_Current_File ) == NULL ) // E.O.F { - if( gerber_layer->m_FilesPtr == 0 ) + if( gerber->m_FilesPtr == 0 ) break; - fclose( gerber_layer->m_Current_File ); + fclose( gerber->m_Current_File ); - gerber_layer->m_FilesPtr--; - gerber_layer->m_Current_File = - gerber_layer->m_FilesList[gerber_layer->m_FilesPtr]; + gerber->m_FilesPtr--; + gerber->m_Current_File = + gerber->m_FilesList[gerber->m_FilesPtr]; continue; } - text = StrPurge( Line ); + text = StrPurge( line ); while( text && *text ) { @@ -185,49 +185,49 @@ bool WinEDA_GerberFrame::Read_GERBER_File( wxDC* DC, break; case '*': // End commande - gerber_layer->m_CommandState = END_BLOCK; + gerber->m_CommandState = END_BLOCK; text++; break; case 'M': // End file - gerber_layer->m_CommandState = CMD_IDLE; + gerber->m_CommandState = CMD_IDLE; while( *text ) text++; break; case 'G': /* Line type Gxx : command */ - G_commande = gerber_layer->ReturnGCodeNumber( text ); - gerber_layer->Execute_G_Command( text, G_commande ); + G_commande = gerber->ReturnGCodeNumber( text ); + gerber->Execute_G_Command( text, G_commande ); break; case 'D': /* Line type Dxx : Tool selection (xx > 0) or command if xx = 0..9*/ - D_commande = gerber_layer->ReturnDCodeNumber( text ); - gerber_layer->Execute_DCODE_Command( this, DC, + D_commande = gerber->ReturnDCodeNumber( text ); + gerber->Execute_DCODE_Command( this, DC, text, D_commande ); break; case 'X': case 'Y': /* Move or draw command */ - pos = gerber_layer->ReadXYCoord( text ); + pos = gerber->ReadXYCoord( text ); if( *text == '*' ) // command like X12550Y19250* { - gerber_layer->Execute_DCODE_Command( this, DC, text, - gerber_layer->m_Last_Pen_Command ); + gerber->Execute_DCODE_Command( this, DC, text, + gerber->m_Last_Pen_Command ); } break; case 'I': case 'J': /* Auxiliary Move command */ - pos = gerber_layer->ReadIJCoord( text ); + pos = gerber->ReadIJCoord( text ); break; case '%': - if( gerber_layer->m_CommandState != ENTER_RS274X_CMD ) + if( gerber->m_CommandState != ENTER_RS274X_CMD ) { - gerber_layer->m_CommandState = ENTER_RS274X_CMD; + gerber->m_CommandState = ENTER_RS274X_CMD; - if( !gerber_layer->ReadRS274XCommand( this, DC, Line, text ) ) + if( !gerber->ReadRS274XCommand( this, DC, line, text ) ) { error++; } @@ -235,7 +235,7 @@ bool WinEDA_GerberFrame::Read_GERBER_File( wxDC* DC, else //Error { error++; - gerber_layer->m_CommandState = CMD_IDLE; + gerber->m_CommandState = CMD_IDLE; text++; } break; @@ -254,14 +254,14 @@ bool WinEDA_GerberFrame::Read_GERBER_File( wxDC* DC, error, GERBER_FullFileName.GetData() ); DisplayError( this, msg ); } - fclose( gerber_layer->m_Current_File ); + fclose( gerber->m_Current_File ); SetLocaleTo_Default( ); /* Init DCodes list and perhaps read a DCODES file, * if the gerber file is only a RS274D file (without any aperture information) */ - if( !gerber_layer->m_As_DCode ) + if( !gerber->m_As_DCode ) { wxString DCodeFileName; if( D_Code_FullFileName.IsEmpty() ) diff --git a/gerbview/rs274d.cpp b/gerbview/rs274d.cpp index 574afac083..e77eedf9c2 100644 --- a/gerbview/rs274d.cpp +++ b/gerbview/rs274d.cpp @@ -302,7 +302,7 @@ static void Append_1_SEG_ARC_GERBER( int Dcode_index, */ /***********************************************/ -wxPoint GERBER_Descr::ReadXYCoord( char*& Text ) +wxPoint GERBER::ReadXYCoord( char*& Text ) /***********************************************/ /* Retourne la coord courante pointee par Text (XnnnnYmmmm) @@ -432,7 +432,7 @@ wxPoint GERBER_Descr::ReadXYCoord( char*& Text ) /************************************************/ -wxPoint GERBER_Descr::ReadIJCoord( char*& Text ) +wxPoint GERBER::ReadIJCoord( char*& Text ) /************************************************/ /* Retourne la coord type InnJnn courante pointee par Text (InnnnJmmmm) @@ -553,7 +553,7 @@ wxPoint GERBER_Descr::ReadIJCoord( char*& Text ) /*****************************************************/ -int GERBER_Descr::ReturnGCodeNumber( char*& Text ) +int GERBER::ReturnGCodeNumber( char*& Text ) /*****************************************************/ /* Lit la sequence Gnn et retourne la valeur nn @@ -579,7 +579,7 @@ int GERBER_Descr::ReturnGCodeNumber( char*& Text ) /**************************************************/ -int GERBER_Descr::ReturnDCodeNumber( char*& Text ) +int GERBER::ReturnDCodeNumber( char*& Text ) /**************************************************/ /* Lit la sequence Dnn et retourne la valeur nn @@ -603,7 +603,7 @@ int GERBER_Descr::ReturnDCodeNumber( char*& Text ) /******************************************************************/ -bool GERBER_Descr::Execute_G_Command( char*& text, int G_commande ) +bool GERBER::Execute_G_Command( char*& text, int G_commande ) /******************************************************************/ { @@ -699,15 +699,17 @@ bool GERBER_Descr::Execute_G_Command( char*& text, int G_commande ) /*****************************************************************************/ -bool GERBER_Descr::Execute_DCODE_Command( WinEDA_GerberFrame* frame, wxDC* DC, +bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, wxDC* DC, char*& text, int D_commande ) /*****************************************************************************/ { - wxSize size( 15, 15 ); + wxSize size( 15, 15 ); - int shape = 1, dcode = 0; - D_CODE* pt_Tool = NULL; - wxString msg; + APERTURE_T aperture = APT_CIRCLE; + + int dcode = 0; + D_CODE* pt_Tool = NULL; + wxString msg; if( D_commande >= FIRST_DCODE ) // This is a "Set tool" command { @@ -769,9 +771,9 @@ bool GERBER_Descr::Execute_DCODE_Command( WinEDA_GerberFrame* frame, wxDC* DC, pt_Tool = ReturnToolDescr( m_Layer, m_Current_Tool ); if( pt_Tool ) { - size = pt_Tool->m_Size; - dcode = pt_Tool->m_Num_Dcode; - shape = pt_Tool->m_Shape; + size = pt_Tool->m_Size; + dcode = pt_Tool->m_Num_Dcode; + aperture = pt_Tool->m_Shape; } switch( m_Iterpolation ) @@ -821,29 +823,29 @@ bool GERBER_Descr::Execute_DCODE_Command( WinEDA_GerberFrame* frame, wxDC* DC, pt_Tool = ReturnToolDescr( m_Layer, m_Current_Tool ); if( pt_Tool ) { - size = pt_Tool->m_Size; - dcode = pt_Tool->m_Num_Dcode; - shape = pt_Tool->m_Shape; + size = pt_Tool->m_Size; + dcode = pt_Tool->m_Num_Dcode; + aperture = pt_Tool->m_Shape; } - switch( shape ) + switch( aperture ) { - case GERB_LINE: - case GERB_CIRCLE: + case APT_LINE: + case APT_CIRCLE: Append_1_Flash_ROND_GERBER( dcode, frame, DC, m_CurrentPos, size.x ); break; - case GERB_OVALE: + case APT_OVAL: Append_1_Flash_GERBER( dcode, frame, DC, m_CurrentPos, size, PAD_OVAL ); break; - case GERB_RECT: + case APT_RECT: Append_1_Flash_GERBER( dcode, frame, DC, m_CurrentPos, size, diff --git a/gerbview/rs274x.cpp b/gerbview/rs274x.cpp index 7e520bbe1f..4b1510469f 100644 --- a/gerbview/rs274x.cpp +++ b/gerbview/rs274x.cpp @@ -12,7 +12,8 @@ #define CODE( x, y ) ( ((x) << 8) + (y) ) -enum rs274x_parameters { +enum RS274X_PARAMETERS +{ FORMAT_STATEMENT = CODE( 'F', 'S' ), AXIS_SELECT = CODE( 'A', 'S' ), MIRROR_IMAGE = CODE( 'M', 'I' ), @@ -30,8 +31,9 @@ enum rs274x_parameters { PLOTTER_FILM = CODE( 'P', 'M' ), INCLUDE_FILE = CODE( 'I', 'F' ), - APERTURE_DESCR = CODE( 'A', 'D' ), - APERTURE_MACRO = CODE( 'A', 'M' ), + AP_DEFINITION = CODE( 'A', 'D' ), + + AP_MACRO = CODE( 'A', 'M' ), LAYER_NAME = CODE( 'L', 'N' ), LAYER_POLARITY = CODE( 'L', 'P' ), KNOCKOUT = CODE( 'K', 'O' ), @@ -41,7 +43,6 @@ enum rs274x_parameters { /* Local Functions */ -static bool ReadApertureMacro( char aBuff[GERBER_BUFZ], char*& text, FILE* gerber_file ); /** @@ -79,7 +80,19 @@ static int ReadXCommand( char*& text ) */ static int ReadInt( char*& text ) { - return (int) strtol( text, &text, 10 ); + char* start = text; + + int ret = (int) strtol( text, &text, 10 ); + +/* + if( text == start ) // no conversion was performed, skip one character forward + ++text; +*/ + + if( *text == ',' ) + ++text; + + return ret; } @@ -92,12 +105,24 @@ static int ReadInt( char*& text ) */ static double ReadDouble( char*& text ) { - return strtod( text, &text ); + char* start = text; + + double ret = strtod( text, &text ); + +/* + if( text == start ) // no conversion was performed, skip one character forward + ++text; +*/ + + if( *text == ',' ) + ++text; + + return ret; } /****************************************************************************/ -bool GERBER_Descr::ReadRS274XCommand( WinEDA_GerberFrame* frame, wxDC* DC, +bool GERBER::ReadRS274XCommand( WinEDA_GerberFrame* frame, wxDC* DC, char buff[GERBER_BUFZ], char*& text ) /****************************************************************************/ { @@ -112,7 +137,7 @@ bool GERBER_Descr::ReadRS274XCommand( WinEDA_GerberFrame* frame, wxDC* DC, { switch( *text ) { - case '%': // End commande + case '%': // end of command text++; m_CommandState = CMD_IDLE; goto exit; // success completion @@ -136,9 +161,10 @@ bool GERBER_Descr::ReadRS274XCommand( WinEDA_GerberFrame* frame, wxDC* DC, } } - // End of current line + // end of current line, read another one. if( fgets( buff, GERBER_BUFZ, m_Current_File ) == NULL ) { + // end of file ok = false; break; } @@ -152,7 +178,7 @@ exit: /*******************************************************************************/ -bool GERBER_Descr::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& text ) +bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& text ) /*******************************************************************************/ { int code; @@ -307,7 +333,7 @@ bool GERBER_Descr::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], ch m_LayerNegative = FALSE; break; - case APERTURE_MACRO: + case AP_MACRO: ReadApertureMacro( buff, text, m_Current_File ); break; @@ -335,7 +361,7 @@ bool GERBER_Descr::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], ch m_FilesPtr++; break; - case APERTURE_DESCR: + case AP_DEFINITION: if( *text != 'D' ) { ok = FALSE; @@ -360,7 +386,7 @@ bool GERBER_Descr::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], ch switch( ctmp ) { case 'C': // Circle - dcode->m_Shape = GERB_CIRCLE; + dcode->m_Shape = APT_CIRCLE; while( *text == ' ' ) text++; @@ -386,9 +412,9 @@ bool GERBER_Descr::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], ch dcode->m_Defined = TRUE; break; - case 'O': // ovale + case 'O': // oval case 'R': // rect - dcode->m_Shape = (ctmp == 'O') ? GERB_OVALE : GERB_RECT; + dcode->m_Shape = (ctmp == 'O') ? APT_OVAL : APT_RECT; while( *text == ' ' ) text++; @@ -424,9 +450,8 @@ bool GERBER_Descr::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], ch dcode->m_Defined = TRUE; break; - case 'P': // Polygone - // A modifier: temporairement la forme ronde est utilisée - dcode->m_Shape = GERB_CIRCLE; + case 'P': // Polygon + dcode->m_Shape = APT_POLYGON; dcode->m_Defined = TRUE; break; } @@ -472,39 +497,125 @@ bool GetEndOfBlock( char buff[GERBER_BUFZ], char*& text, FILE* gerber_file ) /*******************************************************************/ -bool ReadApertureMacro( char buff[GERBER_BUFZ], char*& text, FILE* gerber_file ) +bool GERBER::ReadApertureMacro( char buff[GERBER_BUFZ], char*& text, FILE* gerber_file ) /*******************************************************************/ { - wxString macro_name; - int macro_type = 0; + APERTURE_MACRO am; - // Read macro name - while( (text < buff + GERBER_BUFZ) && *text ) + // read macro name + while( *text ) { if( *text == '*' ) + { + ++text; break; + } - macro_name.Append( *text ); - text++; + am.name.Append( *text++ ); } if( g_DebugLevel > 0 ) - wxMessageBox( macro_name, wxT( "macro name" ) ); + wxMessageBox( am.name, wxT( "macro name" ) ); - text = buff; - fgets( buff, GERBER_BUFZ, gerber_file ); - - // Read parameters - macro_type = ReadInt( text ); - - while( (text < buff + GERBER_BUFZ) && *text ) + for(;;) { - if( *text == '*' ) - return TRUE; + AM_PRIMITIVE prim; - text++; + if( *text == '*' ) + ++text; + + if( *text == '\n' ) + ++text; + + if( !*text ) + { + text = buff; + if( fgets( buff, GERBER_BUFZ, gerber_file ) == NULL ) + return false; + } + + if( *text == '%' ) + break; // exit with text still pointing at % + + prim.primitive_id = (AM_PRIMITIVE_ID) ReadInt( text ); + + int paramCount; + + switch( prim.primitive_id ) + { + default: + case AMP_CIRCLE: + paramCount = 4; + break; + case AMP_LINE2: + case AMP_LINE20: + paramCount = 7; + break; + case AMP_LINE_CENTER: + case AMP_LINE_LOWER_LEFT: + paramCount = 6; + break; + case AMP_EOF: + paramCount = 0; + break; + case AMP_OUTLINE: + paramCount = 4; + break; + case AMP_POLYGON: + paramCount = 4; + break; + case AMP_MOIRE: + paramCount = 9; + break; + case AMP_THERMAL: + paramCount = 6; + break; + } + + DCODE_PARAM param; + + for( int i=0; iAppend( m_FilesMenu, _( "&File" ) ); @@ -192,7 +192,7 @@ void WinEDA_GerberFrame::ReCreateHToolbar( void ) /***********************************************/ { int layer = 0; - GERBER_Descr* gerber_layer = NULL; + GERBER* gerber = NULL; int ii; wxString msg; @@ -203,7 +203,7 @@ void WinEDA_GerberFrame::ReCreateHToolbar( void ) if( GetScreen() ) { layer = GetScreen()->m_Active_Layer; - gerber_layer = g_GERBER_Descr_List[layer]; + gerber = g_GERBER_List[layer]; } m_HToolBar = new WinEDA_Toolbar( TOOLBAR_MAIN, this, ID_H_TOOLBAR, TRUE ); diff --git a/gerbview/trpiste.cpp b/gerbview/trpiste.cpp index 0041f654d5..1ff7f05ab5 100644 --- a/gerbview/trpiste.cpp +++ b/gerbview/trpiste.cpp @@ -31,11 +31,11 @@ void Draw_Track_Buffer( WinEDA_DrawPanel* panel, wxDC* DC, BOARD* Pcb, int draw_ { TRACK* Track; int layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; - GERBER_Descr* gerber_layer = g_GERBER_Descr_List[layer]; + GERBER* gerber = g_GERBER_List[layer]; int dcode_hightlight = 0; - if( gerber_layer ) - dcode_hightlight = gerber_layer->m_Selected_Tool; + if( gerber ) + dcode_hightlight = gerber->m_Selected_Tool; Track = Pcb->m_Track; for( ; Track != NULL; Track = (TRACK*) Track->Pnext )