bool EXCELLON_IMAGE::Execute_Drill_Command( char*& text ) { D_CODE* tool; GERBER_DRAW_ITEM * gbritem; while( true ) { switch( *text ) { case 'X': ReadXYCoord( text ); break; case 'Y': ReadXYCoord( text ); break; case 'G': // G85 is found here for oval holes m_PreviousPos = m_CurrentPos; Execute_EXCELLON_G_Command( 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 ); ReportMessage( msg ); return false; } gbritem = new GERBER_DRAW_ITEM( GetParent()->GetBoard(), this ); GetParent()->GetBoard()->m_Drawings.Append( gbritem ); if( m_SlotOn ) // Oval hole { fillLineGBRITEM( gbritem, tool->m_Num_Dcode, GetParent()->getActiveLayer(), m_PreviousPos, m_CurrentPos, tool->m_Size, false ); } else { fillFlashedGBRITEM( gbritem, tool->m_Shape, tool->m_Num_Dcode, GetParent()->getActiveLayer(), m_CurrentPos, tool->m_Size, false ); } StepAndRepeatItem( *gbritem ); m_PreviousPos = m_CurrentPos; return true; break; default: text++; break; } } return true; }
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 ) AddMessageToList( wxString:: Format( _( "Tool definition shape not found" ) ) ); else if( *aText != 'C' ) AddMessageToList( 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::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 ) { 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++; return tool_id >= 0; }
bool EXCELLON_IMAGE::Select_Tool( char*& text ) { int tool_id = ReturnTCodeNumber( text ); 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; } while( *text ) text++; return tool_id >= 0; }
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]; 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; text += len; break; } } if( !cmd ) { msg.Printf( wxT( "Unknown Excellon command <%s>" ), text ); ReportMessage( msg ); while( *text ) text++; return false; } // Execute command // some do nothing switch( cmd->m_Code ) { case DRILL_SKIP: case DRILL_M_UNKNOWN: break; case DRILL_M_END: break; case DRILL_M_ENDREWIND: break; case DRILL_M_MESSAGE: break; case DRILL_M_LONGMESSAGE: break; case DRILL_M_HEADER: m_State = READ_HEADER_STATE; break; case DRILL_M_ENDHEADER: m_State = READ_PROGRAM_STATE; break; case DRILL_REWIND_STOP: // TODO: what this command really is ? m_State = READ_PROGRAM_STATE; break; case DRILL_M_METRIC: SelectUnits( true ); break; case DRILL_METRICHEADER: // command like METRIC,TZ or METRIC,LZ SelectUnits( true ); if( *text != ',' ) { ReportMessage( _( "METRIC command has no parameter" ) ); break; } text++; // skip separator if( *text == 'T' ) m_NoTrailingZeros = false; else m_NoTrailingZeros = true; break; case DRILL_M_IMPERIAL: SelectUnits( false ); break; case DRILL_IMPERIALHEADER: // command like INCH,TZ or INCH,LZ SelectUnits( false ); if( *text != ',' ) { ReportMessage( _( "INCH command has no parameter" ) ); break; } text++; // skip separator if( *text == 'T' ) m_NoTrailingZeros = false; else m_NoTrailingZeros = true; break; case DRILL_M_BEGINPATTERN: break; case DRILL_M_ENDPATTERN: break; case DRILL_M_CANNEDTEXT: break; case DRILL_M_TIPCHECK: break; case DRILL_DETECT_BROKEN: break; case DRILL_INCREMENTALHEADER: m_Relative = true; break; case DRILL_TOOL_CHANGE_STOP: break; case DRILL_AUTOMATIC_SPEED: break; case DRILL_AXIS_VERSION: break; case DRILL_RESET_CMD: break; case DRILL_AUTOMATIC_TOOL_CHANGE: break; case DRILL_FMT: break; case DRILL_TOOL_INFORMATION: // Read a tool definition like T1C0.02: // Read tool number: iprm = ReadInt( text, false ); // Read tool shape if( *text != 'C' ) ReportMessage( _( "Tool definition <%c> not supported" ) ); 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; double conv_scale = m_GerbMetric ? PCB_INTERNAL_UNIT / 25.4 : PCB_INTERNAL_UNIT; dcode->m_Size.x = dcode->m_Size.y = wxRound( dprm * conv_scale ); dcode->m_Shape = APT_CIRCLE; break; } while( *text ) text++; return true; }
bool EXCELLON_IMAGE::Execute_Drill_Command( char*& text ) { D_CODE* tool; GERBER_DRAW_ITEM * gbritem; while( true ) { switch( *text ) { case 'X': ReadXYCoord( text ); break; case 'Y': ReadXYCoord( text ); break; case 'G': // G85 is found here for oval holes m_PreviousPos = m_CurrentPos; Execute_EXCELLON_G_Command( 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 ); AddMessageToList( msg ); return false; } gbritem = new GERBER_DRAW_ITEM( this ); m_Drawings.Append( gbritem ); if( m_SlotOn ) // Oblong hole { fillLineGBRITEM( gbritem, tool->m_Num_Dcode, m_PreviousPos, m_CurrentPos, tool->m_Size, false ); // the hole is made: reset the slot on command (G85) // (it is needed for each oblong hole) m_SlotOn = false; } else { fillFlashedGBRITEM( gbritem, tool->m_Shape, tool->m_Num_Dcode, m_CurrentPos, tool->m_Size, false ); } StepAndRepeatItem( *gbritem ); m_PreviousPos = m_CurrentPos; return true; break; default: text++; break; } } return true; }
bool EXCELLON_IMAGE::Execute_Drill_Command( char*& text ) { D_CODE* tool; GERBER_DRAW_ITEM * gbritem; while( true ) { switch( *text ) { case 'X': case 'Y': // Decode the coordinate format if( !m_format_known ) { int nbdigits = 0; int integer = m_GerbMetric ? fmtIntegerMM : fmtIntegerInch; int mantissa; char* read = text + 1; while( IsNumber( *read ) ) { if( *read == '.' ) { integer = nbdigits; read++; continue; } if( ( *read >= '0' ) && ( *read <='9' ) ) nbdigits++; read++; } mantissa = nbdigits - integer; // Enforce minimum mantissa of 3 for metric if( m_GerbMetric && mantissa < 3 ) mantissa = 3; m_FmtScale.x = m_FmtScale.y = mantissa; m_FmtLen.x = m_FmtLen.y = integer + mantissa; m_format_known = true; } ReadXYCoord( text ); break; case 'G': // G85 is found here for oval holes m_PreviousPos = m_CurrentPos; Execute_EXCELLON_G_Command( text ); break; case 0: // E.O.L: execute command tool = GetDCODE( m_Current_Tool ); if( !tool ) { wxString msg; msg.Printf( _( "Tool %d not defined" ), m_Current_Tool ); AddMessageToList( msg ); return false; } gbritem = new GERBER_DRAW_ITEM( this ); m_Drawings.Append( gbritem ); if( m_SlotOn ) // Oblong hole { fillLineGBRITEM( gbritem, tool->m_Num_Dcode, m_PreviousPos, m_CurrentPos, tool->m_Size, false ); // the hole is made: reset the slot on command (G85) // (it is needed for each oblong hole) m_SlotOn = false; } else { fillFlashedGBRITEM( gbritem, tool->m_Shape, tool->m_Num_Dcode, m_CurrentPos, tool->m_Size, false ); } StepAndRepeatItem( *gbritem ); m_PreviousPos = m_CurrentPos; return true; break; default: text++; break; } } return true; }
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]; 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; text += len; break; } } if( !cmd ) { msg.Printf( wxT( "Unknown Excellon command <%s>" ), text ); ReportMessage( msg ); while( *text ) text++; return false; } // Execute command // some do nothing switch( cmd->m_Code ) { case DRILL_SKIP: case DRILL_M_UNKNOWN: break; case DRILL_M_END: break; case DRILL_M_ENDREWIND: break; case DRILL_M_MESSAGE: break; case DRILL_M_LONGMESSAGE: break; case DRILL_M_HEADER: m_State = READ_HEADER_STATE; break; case DRILL_M_ENDHEADER: m_State = READ_PROGRAM_STATE; break; case DRILL_REWIND_STOP: // End of header. No action in a viewer m_State = READ_PROGRAM_STATE; break; case DRILL_M_METRIC: SelectUnits( true ); break; case DRILL_METRICHEADER: // command like METRIC,TZ or METRIC,LZ SelectUnits( true ); if( *text != ',' ) { ReportMessage( _( "METRIC command has no parameter" ) ); break; } text++; // skip separator if( *text == 'T' ) m_NoTrailingZeros = false; else m_NoTrailingZeros = true; break; case DRILL_M_IMPERIAL: SelectUnits( false ); break; case DRILL_IMPERIALHEADER: // command like INCH,TZ or INCH,LZ SelectUnits( false ); if( *text != ',' ) { ReportMessage( _( "INCH command has no parameter" ) ); break; } text++; // skip separator if( *text == 'T' ) m_NoTrailingZeros = false; else m_NoTrailingZeros = true; break; case DRILL_M_BEGINPATTERN: break; case DRILL_M_ENDPATTERN: break; case DRILL_M_CANNEDTEXT: break; case DRILL_M_TIPCHECK: break; case DRILL_DETECT_BROKEN: break; case DRILL_INCREMENTALHEADER: if( *text != ',' ) { ReportMessage( _( "ICI command has no parameter" ) ); break; } text++; // skip separator // Parameter should be ON or OFF if( strnicmp( text, "OFF", 3 ) == 0 ) m_Relative = false; else if( strnicmp( text, "ON", 2 ) == 0 ) m_Relative = true; else ReportMessage( _( "ICI command has incorrect parameter" ) ); break; case DRILL_TOOL_CHANGE_STOP: break; case DRILL_AUTOMATIC_SPEED: break; case DRILL_AXIS_VERSION: break; case DRILL_RESET_CMD: break; case DRILL_AUTOMATIC_TOOL_CHANGE: break; case DRILL_FMT: 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; break; } while( *text ) text++; return true; }