diff --git a/common/wildcards_and_files_ext.cpp b/common/wildcards_and_files_ext.cpp index 1076d9de55..c3a74a8ec3 100644 --- a/common/wildcards_and_files_ext.cpp +++ b/common/wildcards_and_files_ext.cpp @@ -72,6 +72,7 @@ const wxString AllFilesWildcard( _( "All files (*)|*" ) ); // Wildcard for cvpcb component to footprint link file const wxString ComponentFileWildcard( _( "KiCad cmp/footprint link files (*.cmp)|*.cmp" ) ); +// Wildcard for reports and fabrication documents const wxString DrillFileWildcard( _( "Drill files (*.drl)|*.drl;*.DRL" ) ); const wxString SVGFileWildcard( _( "SVG files (*.svg)|*.svg;*.SVG" ) ); const wxString ReportFileWildcard = _( "Report files (*.rpt)|*.rpt" ); diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 478e3e820e..ffc56cdfde 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -151,9 +151,8 @@ set(PCBNEW_CLASS_SRCS export_vrml.cpp files.cpp gen_drill_report_files.cpp - gen_holes_and_tools_lists_for_drill.cpp gen_modules_placefile.cpp - gendrill.cpp + gendrill_Excellon_writer.cpp globaleditpad.cpp gpcb_exchange.cpp highlight.cpp diff --git a/pcbnew/dialogs/dialog_SVG_print_base.cpp b/pcbnew/dialogs/dialog_SVG_print_base.cpp index 34605e00a3..ea8185194d 100644 --- a/pcbnew/dialogs/dialog_SVG_print_base.cpp +++ b/pcbnew/dialogs/dialog_SVG_print_base.cpp @@ -40,11 +40,11 @@ DIALOG_SVG_PRINT_base::DIALOG_SVG_PRINT_base( wxWindow* parent, wxWindowID id, c m_TextPenWidth = new wxStaticText( this, wxID_ANY, _("Default pen size"), wxDefaultPosition, wxDefaultSize, 0 ); m_TextPenWidth->Wrap( -1 ); + m_TextPenWidth->SetToolTip( _("Selection of the pen size used to draw items which have no pen size specified.") ); + sbOptionsSizer->Add( m_TextPenWidth, 0, wxRIGHT|wxLEFT, 5 ); m_DialogDefaultPenSize = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_DialogDefaultPenSize->SetToolTip( _("Selection of the pen size used to draw items which have no pen size speicfied.") ); - sbOptionsSizer->Add( m_DialogDefaultPenSize, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 ); wxString m_ModeColorOptionChoices[] = { _("Color"), _("Black and white") }; @@ -67,7 +67,7 @@ DIALOG_SVG_PRINT_base::DIALOG_SVG_PRINT_base( wxWindow* parent, wxWindowID id, c sbOptionsSizer->Add( m_PrintBoardEdgesCtrl, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - m_printMirrorOpt = new wxCheckBox( this, wxID_ANY, _("Print mirror"), wxDefaultPosition, wxDefaultSize, 0 ); + m_printMirrorOpt = new wxCheckBox( this, wxID_ANY, _("Print mirrored"), wxDefaultPosition, wxDefaultSize, 0 ); sbOptionsSizer->Add( m_printMirrorOpt, 0, wxRIGHT|wxLEFT, 5 ); diff --git a/pcbnew/dialogs/dialog_SVG_print_base.fbp b/pcbnew/dialogs/dialog_SVG_print_base.fbp index a267ca1193..adf328e778 100644 --- a/pcbnew/dialogs/dialog_SVG_print_base.fbp +++ b/pcbnew/dialogs/dialog_SVG_print_base.fbp @@ -207,7 +207,7 @@ 0 - + Selection of the pen size used to draw items which have no pen size specified. @@ -290,7 +290,7 @@ 0 - Selection of the pen size used to draw items which have no pen size speicfied. + wxFILTER_NONE wxDefaultValidator @@ -629,7 +629,7 @@ 0 0 wxID_ANY - Print mirror + Print mirrored 0 diff --git a/pcbnew/dialogs/dialog_gendrill.cpp b/pcbnew/dialogs/dialog_gendrill.cpp index f07f41ae64..3b84202876 100644 --- a/pcbnew/dialogs/dialog_gendrill.cpp +++ b/pcbnew/dialogs/dialog_gendrill.cpp @@ -5,8 +5,8 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 1992-2010 Jean_Pierre Charras - * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 1992-2012 Jean_Pierre Charras + * Copyright (C) 1992-2012 KiCad Developers, see change_log.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 @@ -31,13 +31,14 @@ #include #include #include -#include +#include #include #include #include #include +#include // Keywords for read and write config @@ -62,11 +63,26 @@ static DRILL_PRECISION precisionListForMetric[] = }; + + +/* This function displays the dialog frame for drill tools + */ +void PCB_EDIT_FRAME::InstallDrillFrame( wxCommandEvent& event ) +{ + DIALOG_GENDRILL dlg( this ); + + dlg.ShowModal(); +} + + + DIALOG_GENDRILL::DIALOG_GENDRILL( PCB_EDIT_FRAME* parent ) : DIALOG_GENDRILL_BASE( parent ) { m_parent = parent; m_board = parent->GetBoard(); + m_config = wxGetApp().GetSettings(); + m_plotOpts = m_parent->GetPlotSettings(); SetReturnCode( 1 ); initDialog(); @@ -75,14 +91,13 @@ DIALOG_GENDRILL::DIALOG_GENDRILL( PCB_EDIT_FRAME* parent ) : // Static members of DIALOG_GENDRILL -int DIALOG_GENDRILL:: m_UnitDrillIsInch = true; -int DIALOG_GENDRILL:: m_ZerosFormat = EXCELLON_WRITER::DECIMAL_FORMAT; +int DIALOG_GENDRILL::m_UnitDrillIsInch = true; +int DIALOG_GENDRILL::m_ZerosFormat = EXCELLON_WRITER::DECIMAL_FORMAT; bool DIALOG_GENDRILL::m_MinimalHeader = false; bool DIALOG_GENDRILL::m_Mirror = false; bool DIALOG_GENDRILL::m_DrillOriginIsAuxAxis = false; -int DIALOG_GENDRILL:: m_PrecisionFormat = 1; -bool DIALOG_GENDRILL::m_createRpt = false; -int DIALOG_GENDRILL::m_createMap = 0; +int DIALOG_GENDRILL::m_PrecisionFormat = 1; +int DIALOG_GENDRILL::m_mapFileType = 1; DIALOG_GENDRILL::~DIALOG_GENDRILL() @@ -93,17 +108,12 @@ DIALOG_GENDRILL::~DIALOG_GENDRILL() void DIALOG_GENDRILL::initDialog() { - wxConfig* Config = wxGetApp().GetSettings(); - - if( Config ) - { - Config->Read( ZerosFormatKey, &DIALOG_GENDRILL::m_ZerosFormat ); - Config->Read( PrecisionKey, &DIALOG_GENDRILL::m_PrecisionFormat ); - Config->Read( MirrorKey, &DIALOG_GENDRILL::m_Mirror ); - Config->Read( MinimalHeaderKey, &DIALOG_GENDRILL::m_MinimalHeader ); - Config->Read( UnitDrillInchKey, &DIALOG_GENDRILL::m_UnitDrillIsInch ); - Config->Read( DrillOriginIsAuxAxisKey, &DIALOG_GENDRILL::m_DrillOriginIsAuxAxis ); - } + m_config->Read( ZerosFormatKey, &DIALOG_GENDRILL::m_ZerosFormat ); + m_config->Read( PrecisionKey, &DIALOG_GENDRILL::m_PrecisionFormat ); + m_config->Read( MirrorKey, &DIALOG_GENDRILL::m_Mirror ); + m_config->Read( MinimalHeaderKey, &DIALOG_GENDRILL::m_MinimalHeader ); + m_config->Read( UnitDrillInchKey, &DIALOG_GENDRILL::m_UnitDrillIsInch ); + m_config->Read( DrillOriginIsAuxAxisKey, &DIALOG_GENDRILL::m_DrillOriginIsAuxAxis ); InitDisplayParams(); } @@ -129,8 +139,7 @@ void DIALOG_GENDRILL::InitDisplayParams() m_Check_Mirror->SetValue( m_Mirror ); - m_Choice_Drill_Map->SetSelection( m_createMap ); - m_Choice_Drill_Report->SetSelection( m_createRpt ); + m_Choice_Drill_Map->SetSelection( m_mapFileType ); m_ViaDrillValue->SetLabel( _( "Use Netclasses values" ) ); @@ -208,6 +217,9 @@ void DIALOG_GENDRILL::InitDisplayParams() msg = m_BuriedViasInfoMsg->GetLabel(); msg << wxT( " " ) << m_blindOrBuriedViasCount; m_BuriedViasInfoMsg->SetLabel( msg ); + + // Output directory + m_outputDirectoryName->SetValue( m_plotOpts.GetOutputDirectory() ); } @@ -215,17 +227,12 @@ void DIALOG_GENDRILL::UpdateConfig() { SetParams(); - wxConfig* config = wxGetApp().GetSettings(); - - if( config ) - { - config->Write( ZerosFormatKey, m_ZerosFormat ); - config->Write( PrecisionKey, m_PrecisionFormat ); - config->Write( MirrorKey, m_Mirror ); - config->Write( MinimalHeaderKey, m_MinimalHeader ); - config->Write( UnitDrillInchKey, m_UnitDrillIsInch ); - config->Write( DrillOriginIsAuxAxisKey, m_DrillOriginIsAuxAxis ); - } + m_config->Write( ZerosFormatKey, m_ZerosFormat ); + m_config->Write( PrecisionKey, m_PrecisionFormat ); + m_config->Write( MirrorKey, m_Mirror ); + m_config->Write( MinimalHeaderKey, m_MinimalHeader ); + m_config->Write( UnitDrillInchKey, m_UnitDrillIsInch ); + m_config->Write( DrillOriginIsAuxAxisKey, m_DrillOriginIsAuxAxis ); } @@ -234,11 +241,14 @@ void DIALOG_GENDRILL::OnSelDrillUnitsSelected( wxCommandEvent& event ) UpdatePrecisionOptions(); } - -void DIALOG_GENDRILL::OnOkClick( wxCommandEvent& event ) +void DIALOG_GENDRILL::OnGenMapFile( wxCommandEvent& event ) { - GenDrillAndReportFiles(); - EndModal( wxID_OK ); + GenDrillAndMapFiles( false, true); +} + +void DIALOG_GENDRILL::OnGenDrillFile( wxCommandEvent& event ) +{ + GenDrillAndMapFiles(true, false); } @@ -276,17 +286,53 @@ void DIALOG_GENDRILL::UpdatePrecisionOptions() m_Choice_Precision->Enable( true ); } +void DIALOG_GENDRILL::OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) +{ + // Build the absolute path of current output plot directory + // to preselect it when opening the dialog. + wxFileName fn( m_outputDirectoryName->GetValue() ); + wxString path; + + if( fn.IsRelative() ) + path = wxGetCwd() + fn.GetPathSeparator() + m_outputDirectoryName->GetValue(); + else + path = m_outputDirectoryName->GetValue(); + + wxDirDialog dirDialog( this, _( "Select Output Directory" ), path ); + + if( dirDialog.ShowModal() == wxID_CANCEL ) + return; + + wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() ); + + wxMessageDialog dialog( this, _( "Use a relative path? " ), + _( "Plot Output Directory" ), + wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT ); + + if( dialog.ShowModal() == wxID_YES ) + { + wxString boardFilePath = ( (wxFileName) m_parent->GetBoard()->GetFileName() ).GetPath(); + + if( !dirName.MakeRelativeTo( boardFilePath ) ) + wxMessageBox( _( + "Cannot make path relative (target volume different from board file volume)!" ), + _( "Plot Output Directory" ), wxOK | wxICON_ERROR ); + } + + m_outputDirectoryName->SetValue( dirName.GetFullPath() ); +} void DIALOG_GENDRILL::SetParams() { wxString msg; - PCB_PLOT_PARAMS plot_opts = m_board->GetPlotOptions(); + // Set output directory and replace backslashes with forward ones + wxString dirStr; + dirStr = m_outputDirectoryName->GetValue(); + dirStr.Replace( wxT( "\\" ), wxT( "/" ) ); + m_plotOpts.SetOutputDirectory( dirStr ); - m_plotDefaultpath = plot_opts.GetOutputDirectory(); - - m_createMap = m_Choice_Drill_Map->GetSelection(); - m_createRpt = m_Choice_Drill_Report->GetSelection(); + m_mapFileType = m_Choice_Drill_Map->GetSelection(); m_UnitDrillIsInch = (m_Choice_Unit->GetSelection() == 0) ? false : true; m_MinimalHeader = m_Check_Minimal->IsChecked(); @@ -295,8 +341,6 @@ void DIALOG_GENDRILL::SetParams() m_DrillOriginIsAuxAxis = m_Choice_Drill_Offset->GetSelection(); m_PrecisionFormat = m_Choice_Precision->GetSelection(); - plot_opts.SetHPGLPenNum( 1 ); - if( m_Choice_Drill_Offset->GetSelection() == 0 ) m_FileDrillOffset = wxPoint( 0, 0 ); else @@ -310,5 +354,271 @@ void DIALOG_GENDRILL::SetParams() else m_Precision = precisionListForMetric[idx]; - m_board->SetPlotOptions( plot_opts ); + m_board->SetPlotOptions( m_plotOpts ); +} + +/** + * Function GenDrillAndMapFiles + * Calls the functions to create EXCELLON drill files and/or drill map files + * >When all holes are through, only one excellon file is created. + * >When there are some partial holes (some blind or buried vias), + * one excellon file is created, for all plated through holes, + * and one file per layer pair, which have one or more holes, excluding + * through holes, already in the first file. + * one file for all Not Plated through holes + */ +void DIALOG_GENDRILL::GenDrillAndMapFiles(bool aGenDrill, bool aGenMap) +{ + wxString layer_extend; /* added to the Board FileName to + * create FullFileName (= Board + * FileName + layer pair names) */ + wxString msg; + bool hasBuriedVias = false; /* If true, drill files are created + * layer pair by layer pair for + * buried vias */ + int layer1 = LAYER_N_BACK; + int layer2 = LAYER_N_FRONT; + bool gen_through_holes = true; + bool gen_NPTH_holes = false; + + wxString currentWD = ::wxGetCwd(); + + UpdateConfig(); // set params and Save drill options + + m_parent->ClearMsgPanel(); + + if( m_microViasCount || m_blindOrBuriedViasCount ) + hasBuriedVias = true; + + EXCELLON_WRITER excellonWriter( m_parent->GetBoard(), + m_FileDrillOffset ); + excellonWriter.SetFormat( !m_UnitDrillIsInch, + (EXCELLON_WRITER::zeros_fmt) m_ZerosFormat, + m_Precision.m_lhs, m_Precision.m_rhs ); + excellonWriter.SetOptions( m_Mirror, m_MinimalHeader, m_FileDrillOffset ); + + wxFileName fn; + + for( ; ; ) + { + excellonWriter.BuildHolesList( layer1, layer2, + gen_through_holes ? false : true, gen_NPTH_holes ); + + if( excellonWriter.GetHolesCount() > 0 ) // has holes? + { + fn = m_parent->GetBoard()->GetFileName(); + layer_extend.Empty(); + + if( gen_NPTH_holes ) + { + layer_extend << wxT( "-NPTH" ); + } + else if( !gen_through_holes ) + { + if( layer1 == LAYER_N_BACK ) + layer_extend << wxT( "-back" ); + else + layer_extend << wxT( "-inner" ) << layer1; + if( layer2 == LAYER_N_FRONT ) + layer_extend << wxT( "-front" ); + else + layer_extend << wxT( "-inner" ) << layer2; + } + + fn.SetName( fn.GetName() + layer_extend ); + wxString defaultPath = m_plotOpts.GetOutputDirectory(); + if( defaultPath.IsEmpty() ) + defaultPath = ::wxGetCwd(); + + fn.SetPath( defaultPath ); + + if( aGenDrill ) + { + fn.SetExt( DrillFileExtension ); + wxString fullFilename = fn.GetFullPath(); + + FILE* file = wxFopen( fullFilename, wxT( "w" ) ); + + if( file == 0 ) + { + msg.Printf( _( "** Unable to create %s **\n" ), + GetChars( fullFilename ) ); + m_messagesBox->AppendText( msg ); + break; + } + else + { + msg.Printf( _( "Plot: %s OK\n" ), GetChars( fullFilename ) ); + m_messagesBox->AppendText( msg ); + } + + excellonWriter.CreateDrillFile( file ); + } + + if( aGenMap ) + { + const PlotFormat filefmt[5] = + { // Keep these format ids in the same order than m_Choice_Drill_Map choices + PLOT_FORMAT_HPGL, PLOT_FORMAT_POST, PLOT_FORMAT_GERBER, + PLOT_FORMAT_DXF, PLOT_FORMAT_SVG + }; + unsigned choice = (unsigned) m_Choice_Drill_Map->GetSelection(); + + if( choice > 4 ) + choice = 1; + + fn.SetExt( wxEmptyString ); // Will be modified by GenDrillMap + + GenDrillMap( fn.GetFullPath(), excellonWriter, filefmt[choice] ); + } + } + + if( gen_NPTH_holes ) // The last drill file was created + break; + + if( !hasBuriedVias ) + gen_NPTH_holes = true; + else + { + if( gen_through_holes ) + layer2 = layer1 + 1; // prepare generation of first layer pair + else + { + if( layer2 >= LAYER_N_FRONT ) // no more layer pair to consider + { + layer1 = LAYER_N_BACK; + layer2 = LAYER_N_FRONT; + gen_NPTH_holes = true; + continue; + } + layer1++; + layer2++; // use next layer pair + + if( layer2 == m_parent->GetBoard()->GetCopperLayerCount() - 1 ) + layer2 = LAYER_N_FRONT; // the last layer is always the + // Front layer + } + + gen_through_holes = false; + } + } + + ::wxSetWorkingDirectory( currentWD ); +} + + +/* + * Create a plain text report file giving a list of drill values and drill count + * for through holes, oblong holes, and for buried vias, + * drill values and drill count per layer pair + */ +void DIALOG_GENDRILL::OnGenReportFile( wxCommandEvent& event ) +{ + UpdateConfig(); // set params and Save drill options + + wxFileName fn = m_parent->GetBoard()->GetFileName(); + + fn.SetName( fn.GetName() + wxT( "-drl" ) ); + fn.SetExt( ReportFileExtension ); + + wxString defaultPath = m_plotOpts.GetOutputDirectory(); + if( defaultPath.IsEmpty() ) + defaultPath = ::wxGetCwd(); + + wxFileDialog dlg( this, _( "Save Drill Report File" ), defaultPath, + fn.GetFullName(), wxGetTranslation( ReportFileWildcard ), + wxFD_SAVE ); + + if( dlg.ShowModal() == wxID_CANCEL ) + return; + + EXCELLON_WRITER excellonWriter( m_parent->GetBoard(), + m_FileDrillOffset ); + excellonWriter.SetFormat( !m_UnitDrillIsInch, + (EXCELLON_WRITER::zeros_fmt) m_ZerosFormat, + m_Precision.m_lhs, m_Precision.m_rhs ); + excellonWriter.SetOptions( m_Mirror, m_MinimalHeader, m_FileDrillOffset ); + + bool success = excellonWriter.GenDrillReportFile( dlg.GetPath() ); + + wxString msg; + + if( ! success ) + { + msg.Printf( _( "** Unable to create %s **\n" ), GetChars( dlg.GetPath() ) ); + m_messagesBox->AppendText( msg ); + } + else + { + msg.Printf( _( "Create report file %s\n" ), GetChars( dlg.GetPath() ) ); + m_messagesBox->AppendText( msg ); + } +} + + +// Generate the drill map of the board +void DIALOG_GENDRILL::GenDrillMap( const wxString aFileName, + EXCELLON_WRITER& aExcellonWriter, + PlotFormat format ) +{ + wxString ext, wildcard; + + /* Init extension */ + switch( format ) + { + case PLOT_FORMAT_HPGL: + ext = HPGL_PLOTTER::GetDefaultFileExtension(); + wildcard = _( "HPGL plot files (.plt)|*.plt" ); + break; + + case PLOT_FORMAT_POST: + ext = PS_PLOTTER::GetDefaultFileExtension(); + wildcard = _( "PostScript files (.ps)|*.ps" ); + break; + + case PLOT_FORMAT_GERBER: + ext = GERBER_PLOTTER::GetDefaultFileExtension(); + wildcard = _( "Gerber files (.pho)|*.pho" ); + break; + + case PLOT_FORMAT_DXF: + ext = DXF_PLOTTER::GetDefaultFileExtension(); + wildcard = _( "DXF files (.dxf)|*.dxf" ); + break; + + case PLOT_FORMAT_SVG: + ext = SVG_PLOTTER::GetDefaultFileExtension(); + wildcard = SVGFileWildcard; + break; + + default: + wxMessageBox( wxT( "DIALOG_GENDRILL::GenDrillMap() error" ) ); + return; + } + + /* Init file name */ + wxFileName fn = aFileName; + fn.SetName( fn.GetName() + wxT( "-drl_map" ) ); + fn.SetExt( ext ); + wxString fullFilename = fn.GetFullPath(); + + bool success = aExcellonWriter.GenDrillMapFile( fullFilename, + m_parent->GetPageSettings(), + format ); + + wxString msg; + + if( ! success ) + { + msg.Printf( _( "** Unable to create %s **\n" ), + GetChars( fullFilename ) ); + m_messagesBox->AppendText( msg ); + return; + } + else + { + msg.Printf( _( "Plot: %s OK\n" ), GetChars( fullFilename ) ); + m_messagesBox->AppendText( msg ); + } + } diff --git a/pcbnew/dialogs/dialog_gendrill.h b/pcbnew/dialogs/dialog_gendrill.h index 5771138625..58b3307d20 100644 --- a/pcbnew/dialogs/dialog_gendrill.h +++ b/pcbnew/dialogs/dialog_gendrill.h @@ -51,8 +51,9 @@ public: private: PCB_EDIT_FRAME* m_parent; + wxConfig* m_config; BOARD* m_board; - wxString m_plotDefaultpath; // Current default plot dircetory. + PCB_PLOT_PARAMS m_plotOpts; int m_platedPadsHoleCount; int m_notplatedPadsHoleCount; @@ -60,8 +61,7 @@ private: int m_microViasCount; int m_blindOrBuriedViasCount; - static bool m_createRpt; // true to create a drill file report - static int m_createMap; // > 0 to create a map file report + static int m_mapFileType; // HPGL, PS ... void initDialog(); @@ -70,24 +70,25 @@ private: // event functions void OnSelDrillUnitsSelected( wxCommandEvent& event ); void OnSelZerosFmtSelected( wxCommandEvent& event ); - void OnOkClick( wxCommandEvent& event ); + void OnGenDrillFile( wxCommandEvent& event ); + void OnGenMapFile( wxCommandEvent& event ); + void OnGenReportFile( wxCommandEvent& event ); void OnCancelClick( wxCommandEvent& event ); + void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ); // Specific functions: void SetParams( void ); - void GenDrillAndReportFiles(); - void GenDrillMap( const wxString aFileName, - std::vector& aHoleListBuffer, - std::vector& aToolListBuffer, - int format ); + void GenDrillAndMapFiles(bool aGenDrill, bool aGenMap); + void GenDrillMap( const wxString aFileName, + EXCELLON_WRITER& aExcellonWriter, + PlotFormat format ); + void UpdatePrecisionOptions(); void UpdateConfig(); - void GenDrillReport( const wxString aFileName ); - int Create_Drill_File_EXCELLON( FILE* aFile, - wxPoint aOffset, - std::vector& aHoleListBuffer, - std::vector& aToolListBuffer ); - int Gen_Liste_Tools( std::vector& buffer, bool print_header ); + int Create_Drill_File_EXCELLON( FILE* aFile, + wxPoint aOffset ); + int Gen_Liste_Tools( std::vector& buffer, + bool print_header ); /** * Return the selected format for coordinates, if not decimal diff --git a/pcbnew/dialogs/dialog_gendrill_base.cpp b/pcbnew/dialogs/dialog_gendrill_base.cpp index d3a326a80b..cdbd6f7520 100644 --- a/pcbnew/dialogs/dialog_gendrill_base.cpp +++ b/pcbnew/dialogs/dialog_gendrill_base.cpp @@ -14,7 +14,28 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con this->SetSizeHints( wxDefaultSize, wxDefaultSize ); wxBoxSizer* bMainSizer; - bMainSizer = new wxBoxSizer( wxHORIZONTAL ); + bMainSizer = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bupperSizer; + bupperSizer = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* bdirnameSizer; + bdirnameSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Output directory:") ), wxHORIZONTAL ); + + m_outputDirectoryName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + bdirnameSizer->Add( m_outputDirectoryName, 1, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + m_buttonBrowse = new wxButton( this, wxID_ANY, _("Browse"), wxDefaultPosition, wxDefaultSize, 0 ); + bdirnameSizer->Add( m_buttonBrowse, 0, wxBOTTOM|wxLEFT, 5 ); + + + bupperSizer->Add( bdirnameSizer, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + + bMainSizer->Add( bupperSizer, 0, wxEXPAND, 5 ); + + wxBoxSizer* bmiddlerSizer; + bmiddlerSizer = new wxBoxSizer( wxHORIZONTAL ); wxBoxSizer* m_LeftBoxSizer; m_LeftBoxSizer = new wxBoxSizer( wxVERTICAL ); @@ -41,36 +62,20 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con m_LeftBoxSizer->Add( m_Choice_Precision, 0, wxALL|wxEXPAND, 5 ); - wxString m_Choice_Drill_OffsetChoices[] = { _("Absolute"), _("Auxiliary axis") }; - int m_Choice_Drill_OffsetNChoices = sizeof( m_Choice_Drill_OffsetChoices ) / sizeof( wxString ); - m_Choice_Drill_Offset = new wxRadioBox( this, wxID_ANY, _("Drill Origin:"), wxDefaultPosition, wxDefaultSize, m_Choice_Drill_OffsetNChoices, m_Choice_Drill_OffsetChoices, 1, wxRA_SPECIFY_COLS ); - m_Choice_Drill_Offset->SetSelection( 0 ); - m_Choice_Drill_Offset->SetToolTip( _("Choose the coordinate origin: absolute or relative to the auxiliray axis") ); - m_LeftBoxSizer->Add( m_Choice_Drill_Offset, 0, wxALL|wxEXPAND, 5 ); - - - bMainSizer->Add( m_LeftBoxSizer, 1, wxEXPAND, 5 ); + bmiddlerSizer->Add( m_LeftBoxSizer, 0, wxEXPAND, 5 ); wxBoxSizer* bMiddleBoxSizer; bMiddleBoxSizer = new wxBoxSizer( wxVERTICAL ); - wxString m_Choice_Drill_MapChoices[] = { _("None"), _("Drill map (HPGL)"), _("Drill map (PostScript)"), _("Drill map (Gerber)"), _("Drill map (DXF)"), _("Drill map (SVG)") }; + wxString m_Choice_Drill_MapChoices[] = { _("Drill map (HPGL)"), _("Drill map (PostScript)"), _("Drill map (Gerber)"), _("Drill map (DXF)"), _("Drill map (SVG)") }; int m_Choice_Drill_MapNChoices = sizeof( m_Choice_Drill_MapChoices ) / sizeof( wxString ); m_Choice_Drill_Map = new wxRadioBox( this, wxID_ANY, _("Drill Map:"), wxDefaultPosition, wxDefaultSize, m_Choice_Drill_MapNChoices, m_Choice_Drill_MapChoices, 1, wxRA_SPECIFY_COLS ); - m_Choice_Drill_Map->SetSelection( 0 ); + m_Choice_Drill_Map->SetSelection( 1 ); m_Choice_Drill_Map->SetToolTip( _("Creates a drill map in PS, HPGL or other formats") ); bMiddleBoxSizer->Add( m_Choice_Drill_Map, 0, wxALL|wxEXPAND, 5 ); - wxString m_Choice_Drill_ReportChoices[] = { _("None"), _("Drill report") }; - int m_Choice_Drill_ReportNChoices = sizeof( m_Choice_Drill_ReportChoices ) / sizeof( wxString ); - m_Choice_Drill_Report = new wxRadioBox( this, wxID_ANY, _("Drill Report:"), wxDefaultPosition, wxDefaultSize, m_Choice_Drill_ReportNChoices, m_Choice_Drill_ReportChoices, 1, wxRA_SPECIFY_COLS ); - m_Choice_Drill_Report->SetSelection( 0 ); - m_Choice_Drill_Report->SetToolTip( _("Creates a plain text report") ); - - bMiddleBoxSizer->Add( m_Choice_Drill_Report, 0, wxALL|wxEXPAND, 5 ); - wxStaticBoxSizer* sbOptSizer; sbOptSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Options:") ), wxVERTICAL ); @@ -81,10 +86,18 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con sbOptSizer->Add( m_Check_Minimal, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - bMiddleBoxSizer->Add( sbOptSizer, 0, wxEXPAND, 5 ); + bMiddleBoxSizer->Add( sbOptSizer, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + wxString m_Choice_Drill_OffsetChoices[] = { _("Absolute"), _("Auxiliary axis") }; + int m_Choice_Drill_OffsetNChoices = sizeof( m_Choice_Drill_OffsetChoices ) / sizeof( wxString ); + m_Choice_Drill_Offset = new wxRadioBox( this, wxID_ANY, _("Drill Origin:"), wxDefaultPosition, wxDefaultSize, m_Choice_Drill_OffsetNChoices, m_Choice_Drill_OffsetChoices, 1, wxRA_SPECIFY_COLS ); + m_Choice_Drill_Offset->SetSelection( 0 ); + m_Choice_Drill_Offset->SetToolTip( _("Choose the coordinate origin: absolute or relative to the auxiliray axis") ); + + bMiddleBoxSizer->Add( m_Choice_Drill_Offset, 0, wxALL|wxEXPAND, 5 ); - bMainSizer->Add( bMiddleBoxSizer, 1, wxEXPAND, 5 ); + bmiddlerSizer->Add( bMiddleBoxSizer, 0, wxEXPAND, 5 ); wxBoxSizer* bRightBoxSizer; bRightBoxSizer = new wxBoxSizer( wxVERTICAL ); @@ -108,7 +121,7 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con m_MicroViasDrillSizer->Add( m_MicroViaDrillValue, 0, wxALL, 5 ); - sbSizerInfo->Add( m_MicroViasDrillSizer, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 ); + sbSizerInfo->Add( m_MicroViasDrillSizer, 0, wxEXPAND|wxBOTTOM, 5 ); wxStaticBoxSizer* sbSizerHoles; sbSizerHoles = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Holes Count:") ), wxVERTICAL ); @@ -134,23 +147,49 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con sbSizerHoles->Add( m_BuriedViasInfoMsg, 0, wxALL, 5 ); - sbSizerInfo->Add( sbSizerHoles, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 ); + sbSizerInfo->Add( sbSizerHoles, 1, wxEXPAND|wxBOTTOM, 5 ); bRightBoxSizer->Add( sbSizerInfo, 0, wxEXPAND|wxTOP, 5 ); - bRightBoxSizer->Add( 10, 10, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 ); + bmiddlerSizer->Add( bRightBoxSizer, 0, wxEXPAND, 5 ); - m_OkButton = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 ); - m_OkButton->SetDefault(); - bRightBoxSizer->Add( m_OkButton, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); - - m_CancelButton = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bRightBoxSizer->Add( m_CancelButton, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + wxBoxSizer* bSizerButtons; + bSizerButtons = new wxBoxSizer( wxVERTICAL ); - bMainSizer->Add( bRightBoxSizer, 1, wxEXPAND, 5 ); + bSizerButtons->Add( 10, 20, 0, 0, 5 ); + + m_buttonDrill = new wxButton( this, ID_GEN_DRILL_FILE, _("Drill Fille"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonDrill->SetDefault(); + bSizerButtons->Add( m_buttonDrill, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + + m_buttonMap = new wxButton( this, wxID_ANY, _("Map File"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerButtons->Add( m_buttonMap, 0, wxALL, 5 ); + + m_buttonReport = new wxButton( this, wxID_ANY, _("Report File"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerButtons->Add( m_buttonReport, 0, wxALL, 5 ); + + m_CancelButton = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerButtons->Add( m_CancelButton, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + + + bmiddlerSizer->Add( bSizerButtons, 1, wxEXPAND, 5 ); + + + bMainSizer->Add( bmiddlerSizer, 0, wxEXPAND, 5 ); + + wxStaticBoxSizer* bmsgSizer; + bmsgSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Messages:") ), wxVERTICAL ); + + m_messagesBox = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY ); + m_messagesBox->SetMinSize( wxSize( -1,90 ) ); + + bmsgSizer->Add( m_messagesBox, 1, wxALL|wxEXPAND, 5 ); + + + bMainSizer->Add( bmsgSizer, 1, wxEXPAND, 5 ); this->SetSizer( bMainSizer ); @@ -159,18 +198,24 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con this->Centre( wxBOTH ); // Connect Events + m_buttonBrowse->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnOutputDirectoryBrowseClicked ), NULL, this ); m_Choice_Unit->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnSelDrillUnitsSelected ), NULL, this ); m_Choice_Zeros_Format->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnSelZerosFmtSelected ), NULL, this ); - m_OkButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnOkClick ), NULL, this ); + m_buttonDrill->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnGenDrillFile ), NULL, this ); + m_buttonMap->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnGenMapFile ), NULL, this ); + m_buttonReport->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnGenReportFile ), NULL, this ); m_CancelButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnCancelClick ), NULL, this ); } DIALOG_GENDRILL_BASE::~DIALOG_GENDRILL_BASE() { // Disconnect Events + m_buttonBrowse->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnOutputDirectoryBrowseClicked ), NULL, this ); m_Choice_Unit->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnSelDrillUnitsSelected ), NULL, this ); m_Choice_Zeros_Format->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnSelZerosFmtSelected ), NULL, this ); - m_OkButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnOkClick ), NULL, this ); + m_buttonDrill->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnGenDrillFile ), NULL, this ); + m_buttonMap->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnGenMapFile ), NULL, this ); + m_buttonReport->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnGenReportFile ), NULL, this ); m_CancelButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnCancelClick ), NULL, this ); } diff --git a/pcbnew/dialogs/dialog_gendrill_base.fbp b/pcbnew/dialogs/dialog_gendrill_base.fbp index 4895e56de9..3c0424596d 100644 --- a/pcbnew/dialogs/dialog_gendrill_base.fbp +++ b/pcbnew/dialogs/dialog_gendrill_base.fbp @@ -42,7 +42,7 @@ DIALOG_GENDRILL_BASE - 455,358 + 506,471 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER DIALOG_SHIM; dialog_shim.h Drill Files Generation @@ -89,375 +89,208 @@ bMainSizer - wxHORIZONTAL + wxVERTICAL none 5 wxEXPAND - 1 + 0 - m_LeftBoxSizer + bupperSizer wxVERTICAL none 5 - wxALL|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - "Millimeters" "Inches" - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 + wxEXPAND|wxRIGHT|wxLEFT + 1 + wxID_ANY - Drill Units: - 1 - - 0 - - - 0 + Output directory: - 1 - m_Choice_Unit - 1 - - - protected - 1 - - Resizable - 1 - 1 - - wxRA_SPECIFY_COLS - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - OnSelDrillUnitsSelected - - - - - - - - - - 5 - wxALL|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - "Decimal format" "Suppress leading zeros" "Suppress trailing zeros" "Keep zeros" - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Zeros Format - 1 - - 0 - - - 0 - - 1 - m_Choice_Zeros_Format - 1 - - - protected - 1 - - Resizable - 0 - 1 - - wxRA_SPECIFY_COLS - - 0 - Choose EXCELLON numbers notation - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - OnSelZerosFmtSelected - - - - - - - - - - 5 - wxALL|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - "2:3" "2:4" - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Precision - 1 - - 0 - - - 0 - - 1 - m_Choice_Precision - 1 - - - protected - 1 - - Resizable - 1 - 1 - - wxRA_SPECIFY_COLS - - 0 - Choose EXCELLON numbers precision - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - "Absolute" "Auxiliary axis" - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Drill Origin: - 1 - - 0 - - - 0 - - 1 - m_Choice_Drill_Offset - 1 - - - protected - 1 - - Resizable - 0 - 1 - - wxRA_SPECIFY_COLS - - 0 - Choose the coordinate origin: absolute or relative to the auxiliray axis - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - + bdirnameSizer + wxHORIZONTAL + none + + 5 + wxBOTTOM|wxRIGHT|wxLEFT + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 0 + + 0 + + 1 + m_outputDirectoryName + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxBOTTOM|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Browse + + 0 + + + 0 + + 1 + m_buttonBrowse + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnOutputDirectoryBrowseClicked + + + + + + + + + + + + + + + + + + + + + + + + + @@ -465,209 +298,307 @@ 5 wxEXPAND - 1 + 0 - bMiddleBoxSizer - wxVERTICAL + bmiddlerSizer + wxHORIZONTAL none 5 - wxALL|wxEXPAND + wxEXPAND 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - "None" "Drill map (HPGL)" "Drill map (PostScript)" "Drill map (Gerber)" "Drill map (DXF)" "Drill map (SVG)" - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Drill Map: - 1 - - 0 - - - 0 + - 1 - m_Choice_Drill_Map - 1 - - - protected - 1 - - Resizable - 0 - 1 - - wxRA_SPECIFY_COLS - - 0 - Creates a drill map in PS, HPGL or other formats - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - "None" "Drill report" - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Drill Report: - 1 - - 0 - - - 0 - - 1 - m_Choice_Drill_Report - 1 - - - protected - 1 - - Resizable - 0 - 1 - - wxRA_SPECIFY_COLS - - 0 - Creates a plain text report - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - + m_LeftBoxSizer + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "Millimeters" "Inches" + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Drill Units: + 1 + + 0 + + + 0 + + 1 + m_Choice_Unit + 1 + + + protected + 1 + + Resizable + 1 + 1 + + wxRA_SPECIFY_COLS + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + OnSelDrillUnitsSelected + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "Decimal format" "Suppress leading zeros" "Suppress trailing zeros" "Keep zeros" + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Zeros Format + 1 + + 0 + + + 0 + + 1 + m_Choice_Zeros_Format + 1 + + + protected + 1 + + Resizable + 0 + 1 + + wxRA_SPECIFY_COLS + + 0 + Choose EXCELLON numbers notation + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + OnSelZerosFmtSelected + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "2:3" "2:4" + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Precision + 1 + + 0 + + + 0 + + 1 + m_Choice_Precision + 1 + + + protected + 1 + + Resizable + 1 + 1 + + wxRA_SPECIFY_COLS + + 0 + Choose EXCELLON numbers precision + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 wxEXPAND 0 - - wxID_ANY - Options: + - sbOptSizer + bMiddleBoxSizer wxVERTICAL none - 5 - wxRIGHT|wxLEFT + wxALL|wxEXPAND 0 - + 1 1 1 @@ -681,7 +612,7 @@ 1 0 - 0 + "Drill map (HPGL)" "Drill map (PostScript)" "Drill map (Gerber)" "Drill map (DXF)" "Drill map (SVG)" 1 1 @@ -696,7 +627,8 @@ 0 0 wxID_ANY - Mirror y axis + Drill Map: + 1 0 @@ -704,7 +636,1045 @@ 0 1 - m_Check_Mirror + m_Choice_Drill_Map + 1 + + + protected + 1 + + Resizable + 1 + 1 + + wxRA_SPECIFY_COLS + + 0 + Creates a drill map in PS, HPGL or other formats + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxRIGHT|wxLEFT + 0 + + wxID_ANY + Options: + + sbOptSizer + wxVERTICAL + none + + + 5 + wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Mirror y axis + + 0 + + + 0 + + 1 + m_Check_Mirror + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Minimal header + + 0 + + + 0 + + 1 + m_Check_Minimal + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "Absolute" "Auxiliary axis" + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Drill Origin: + 1 + + 0 + + + 0 + + 1 + m_Choice_Drill_Offset + 1 + + + protected + 1 + + Resizable + 0 + 1 + + wxRA_SPECIFY_COLS + + 0 + Choose the coordinate origin: absolute or relative to the auxiliray axis + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bRightBoxSizer + wxVERTICAL + none + + 5 + wxEXPAND|wxTOP + 0 + + wxID_ANY + Info: + + sbSizerInfo + wxVERTICAL + none + + + 5 + wxEXPAND|wxTOP|wxBOTTOM + 0 + + wxID_ANY + Default Vias Drill: + + m_DefaultViasDrillSizer + wxVERTICAL + protected + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Via Drill Value + + 0 + + + 0 + + 1 + m_ViaDrillValue + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxBOTTOM + 0 + + wxID_ANY + Micro Vias Drill: + + m_MicroViasDrillSizer + wxVERTICAL + protected + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Micro Via Drill Value + + 0 + + + 0 + + 1 + m_MicroViaDrillValue + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxBOTTOM + 1 + + wxID_ANY + Holes Count: + + sbSizerHoles + wxVERTICAL + none + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Plated Pads: + + 0 + + + 0 + + 1 + m_PlatedPadsCountInfoMsg + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Not Plated Pads: + + 0 + + + 0 + + 1 + m_NotPlatedPadsCountInfoMsg + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Through Vias: + + 0 + + + 0 + + 1 + m_ThroughViasInfoMsg + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Micro Vias: + + 0 + + + 0 + + 1 + m_MicroViasInfoMsg + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Buried Vias: + + 0 + + + 0 + + 1 + m_BuriedViasInfoMsg + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + bSizerButtons + wxVERTICAL + none + + 5 + + 0 + + 20 + protected + 10 + + + + 5 + wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + ID_GEN_DRILL_FILE + Drill Fille + + 0 + + + 0 + + 1 + m_buttonDrill 1 @@ -725,8 +1695,8 @@ + OnGenDrillFile - @@ -753,9 +1723,9 @@ 5 - wxTOP|wxRIGHT|wxLEFT + wxALL 0 - + 1 1 1 @@ -769,10 +1739,10 @@ 1 0 - 0 1 1 + 0 0 Dock 0 @@ -784,7 +1754,7 @@ 0 0 wxID_ANY - Minimal header + Map File 0 @@ -792,7 +1762,7 @@ 0 1 - m_Check_Minimal + m_buttonMap 1 @@ -813,8 +1783,184 @@ + OnGenMapFile + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Report File + + 0 + + + 0 + + 1 + m_buttonReport + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnGenReportFile + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_CANCEL + Close + + 0 + + + 0 + + 1 + m_CancelButton + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnCancelClick - @@ -847,663 +1993,19 @@ 5 wxEXPAND 1 - + + wxID_ANY + Messages: - bRightBoxSizer + bmsgSizer wxVERTICAL none + 5 - wxEXPAND|wxTOP - 0 - - wxID_ANY - Info: - - sbSizerInfo - wxVERTICAL - none - - - 5 - wxEXPAND|wxTOP|wxBOTTOM - 0 - - wxID_ANY - Default Vias Drill: - - m_DefaultViasDrillSizer - wxVERTICAL - protected - - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Via Drill Value - - 0 - - - 0 - - 1 - m_ViaDrillValue - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxTOP|wxBOTTOM - 0 - - wxID_ANY - Micro Vias Drill: - - m_MicroViasDrillSizer - wxVERTICAL - protected - - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Micro Via Drill Value - - 0 - - - 0 - - 1 - m_MicroViaDrillValue - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxTOP|wxBOTTOM - 1 - - wxID_ANY - Holes Count: - - sbSizerHoles - wxVERTICAL - none - - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Plated Pads: - - 0 - - - 0 - - 1 - m_PlatedPadsCountInfoMsg - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Not Plated Pads: - - 0 - - - 0 - - 1 - m_NotPlatedPadsCountInfoMsg - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Through Vias: - - 0 - - - 0 - - 1 - m_ThroughViasInfoMsg - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Micro Vias: - - 0 - - - 0 - - 1 - m_MicroViasInfoMsg - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Buried Vias: - - 0 - - - 0 - - 1 - m_BuriedViasInfoMsg - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxALIGN_CENTER_HORIZONTAL + wxALL|wxEXPAND 1 - - 10 - protected - 10 - - - - 5 - wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND - 0 - + 1 1 1 @@ -1520,7 +2022,6 @@ 1 1 - 1 0 Dock 0 @@ -1531,16 +2032,16 @@ 0 0 - wxID_OK - OK + wxID_ANY 0 + 0 0 - + -1,90 1 - m_OkButton + m_messagesBox 1 @@ -1550,7 +2051,7 @@ Resizable 1 - + wxTE_MULTILINE|wxTE_READONLY 0 @@ -1558,98 +2059,10 @@ wxFILTER_NONE wxDefaultValidator + - OnOkClick - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_CANCEL - Cancel - - 0 - - - 0 - - 1 - m_CancelButton - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - OnCancelClick @@ -1672,6 +2085,10 @@ + + + + diff --git a/pcbnew/dialogs/dialog_gendrill_base.h b/pcbnew/dialogs/dialog_gendrill_base.h index a6fbab704d..e4f5ac6e4b 100644 --- a/pcbnew/dialogs/dialog_gendrill_base.h +++ b/pcbnew/dialogs/dialog_gendrill_base.h @@ -13,20 +13,22 @@ #include #include "dialog_shim.h" #include -#include +#include #include #include #include #include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include #include /////////////////////////////////////////////////////////////////////////// +#define ID_GEN_DRILL_FILE 1000 /////////////////////////////////////////////////////////////////////////////// /// Class DIALOG_GENDRILL_BASE @@ -36,14 +38,15 @@ class DIALOG_GENDRILL_BASE : public DIALOG_SHIM private: protected: + wxTextCtrl* m_outputDirectoryName; + wxButton* m_buttonBrowse; wxRadioBox* m_Choice_Unit; wxRadioBox* m_Choice_Zeros_Format; wxRadioBox* m_Choice_Precision; - wxRadioBox* m_Choice_Drill_Offset; wxRadioBox* m_Choice_Drill_Map; - wxRadioBox* m_Choice_Drill_Report; wxCheckBox* m_Check_Mirror; wxCheckBox* m_Check_Minimal; + wxRadioBox* m_Choice_Drill_Offset; wxStaticBoxSizer* m_DefaultViasDrillSizer; wxStaticText* m_ViaDrillValue; wxStaticBoxSizer* m_MicroViasDrillSizer; @@ -53,19 +56,25 @@ class DIALOG_GENDRILL_BASE : public DIALOG_SHIM wxStaticText* m_ThroughViasInfoMsg; wxStaticText* m_MicroViasInfoMsg; wxStaticText* m_BuriedViasInfoMsg; - wxButton* m_OkButton; + wxButton* m_buttonDrill; + wxButton* m_buttonMap; + wxButton* m_buttonReport; wxButton* m_CancelButton; + wxTextCtrl* m_messagesBox; // Virtual event handlers, overide them in your derived class + virtual void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) { event.Skip(); } virtual void OnSelDrillUnitsSelected( wxCommandEvent& event ) { event.Skip(); } virtual void OnSelZerosFmtSelected( wxCommandEvent& event ) { event.Skip(); } - virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); } + virtual void OnGenDrillFile( wxCommandEvent& event ) { event.Skip(); } + virtual void OnGenMapFile( wxCommandEvent& event ) { event.Skip(); } + virtual void OnGenReportFile( wxCommandEvent& event ) { event.Skip(); } virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); } public: - DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Drill Files Generation"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 455,358 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Drill Files Generation"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 506,471 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~DIALOG_GENDRILL_BASE(); }; diff --git a/pcbnew/gen_drill_report_files.cpp b/pcbnew/gen_drill_report_files.cpp index 9afedb531e..953b51a246 100644 --- a/pcbnew/gen_drill_report_files.cpp +++ b/pcbnew/gen_drill_report_files.cpp @@ -1,64 +1,91 @@ -/************************************************************************/ -/* Functions to create drill data used to create files and report files */ -/************************************************************************/ +/** + * @file gen_drill_report_files.cpp + * @brief Functions to create report and map files for EXCELLON drill files. + */ + +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 1992-2012 Jean_Pierre Charras + * Copyright (C) 1992-2012 KiCad Developers, see change_log.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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include #include #include -#include #include #include #include -#include #include #include #include -#include +#include /* Conversion utilities - these will be used often in there... */ -static double diameter_in_inches(double ius) +inline double diameter_in_inches( double ius ) { return ius * 0.001 / IU_PER_MILS; } -static double diameter_in_mm(double ius) + +inline double diameter_in_mm( double ius ) { return ius / IU_PER_MM; } -void GenDrillMapFile( BOARD* aPcb, FILE* aFile, const wxString& aFullFileName, - const PAGE_INFO& aSheet, - std::vector aHoleListBuffer, - std::vector aToolListBuffer, - bool aUnit_Drill_is_Inch, int format, - const wxPoint& auxoffset ) +/* Creates a hole map of the board in HPGL, POSTSCRIPT or other supported formats + * Each hole size has a the drill mark symbol (circle, cross X, cross + ...) up to + * PLOTTER::MARKER_COUNT different values. + * If more than PLOTTER::MARKER_COUNT different values, + * these other vaules share the same mark + */ +bool EXCELLON_WRITER::GenDrillMapFile( const wxString& aFullFileName, + const PAGE_INFO& aSheet, + PlotFormat aFormat ) { - double scale = 1.0; - wxPoint offset; - PLOTTER* plotter = NULL; + double scale = 1.0; + wxPoint offset; + PLOTTER* plotter = NULL; - PCB_PLOT_PARAMS plot_opts; // starts plotting with default options + PCB_PLOT_PARAMS plot_opts; // starts plotting with default options - LOCALE_IO toggle; // use standard C notation for float numbers + LOCALE_IO toggle; // use standard C notation for float numbers // Calculate dimensions and center of PCB - EDA_RECT bbbox = aPcb->ComputeBoundingBox(true); + EDA_RECT bbbox = m_pcb->ComputeBoundingBox( true ); // Calculate the scale for the format type, scale 1 in HPGL, drawing on // an A4 sheet in PS, + text description of symbols - switch( format ) + switch( aFormat ) { case PLOT_FORMAT_GERBER: - offset = auxoffset; + offset = GetOffset(); plotter = new GERBER_PLOTTER(); plotter->SetViewport( offset, IU_PER_DECIMILS, scale, false ); break; - case PLOT_FORMAT_HPGL: // Scale for HPGL format. + case PLOT_FORMAT_HPGL: // Scale for HPGL format. { HPGL_PLOTTER* hpgl_plotter = new HPGL_PLOTTER; plotter = hpgl_plotter; @@ -76,15 +103,15 @@ void GenDrillMapFile( BOARD* aPcb, FILE* aFile, const wxString& aFullFileName, wxSize pageSizeIU = pageA4.GetSizeIU(); // Reserve a margin around the page. - int margin = (int)(20 * IU_PER_MM ); + int margin = (int) (20 * IU_PER_MM ); // Calculate a scaling factor to print the board on the sheet - double Xscale = (double)( pageSizeIU.x - ( 2 * margin ) ) / bbbox.GetWidth(); + double Xscale = (double) ( pageSizeIU.x - ( 2 * margin ) ) / bbbox.GetWidth(); // We should print the list of drill sizes, so reserve room for it // 60% height for board 40% height for list - int ypagesize_for_board = (int) (pageSizeIU.y * 0.6); - double Yscale = (double)( ypagesize_for_board - margin ) / bbbox.GetHeight(); + int ypagesize_for_board = (int) (pageSizeIU.y * 0.6); + double Yscale = (double) ( ypagesize_for_board - margin ) / bbbox.GetHeight(); scale = std::min( Xscale, Yscale ); @@ -93,9 +120,9 @@ void GenDrillMapFile( BOARD* aPcb, FILE* aFile, const wxString& aFullFileName, // So the scale is clipped at 3.0; scale = std::min( scale, 3.0 ); - offset.x = (int) ( (double) bbbox.Centre().x - ( pageSizeIU.x / 2.0 ) / scale ); - offset.y = (int) ( (double) bbbox.Centre().y - - ( ypagesize_for_board / 2.0 ) / scale ); + offset.x = (int) ( (double) bbbox.Centre().x - ( pageSizeIU.x / 2.0 ) / scale ); + offset.y = (int) ( (double) bbbox.Centre().y - + ( ypagesize_for_board / 2.0 ) / scale ); PS_PLOTTER* ps_plotter = new PS_PLOTTER; plotter = ps_plotter; @@ -126,16 +153,24 @@ void GenDrillMapFile( BOARD* aPcb, FILE* aFile, const wxString& aFullFileName, wxASSERT( false ); } + FILE* plotfile = wxFopen( aFullFileName, wxT( "wt" ) ); + + if( plotfile == NULL ) + { + delete plotter; + return false; + } + plotter->SetCreator( wxT( "PCBNEW" ) ); plotter->SetFilename( aFullFileName ); plotter->SetDefaultLineWidth( 10 * IU_PER_DECIMILS ); - plotter->StartPlot( aFile ); + plotter->StartPlot( plotfile ); // Draw items on edge layer (not all, only items useful for drill map - BRDITEMS_PLOTTER itemplotter( plotter, aPcb, plot_opts ); + BRDITEMS_PLOTTER itemplotter( plotter, m_pcb, plot_opts ); itemplotter.SetLayerMask( EDGE_LAYER ); - for( EDA_ITEM* PtStruct = aPcb->m_Drawings; PtStruct != NULL; PtStruct = PtStruct->Next() ) + for( EDA_ITEM* PtStruct = m_pcb->m_Drawings; PtStruct != NULL; PtStruct = PtStruct->Next() ) { switch( PtStruct->Type() ) { @@ -160,25 +195,25 @@ void GenDrillMapFile( BOARD* aPcb, FILE* aFile, const wxString& aFullFileName, int intervalle = 0; char line[1024]; wxString msg; - int textmarginaftersymbol = (int) (2 * IU_PER_MM); + int textmarginaftersymbol = (int) (2 * IU_PER_MM); // Set Drill Symbols width plotter->SetDefaultLineWidth( 0.2 * IU_PER_MM / scale ); plotter->SetCurrentLineWidth( -1 ); // Plot board outlines and drill map - Gen_Drill_PcbMap( aPcb, plotter, aHoleListBuffer, aToolListBuffer ); + PlotDrillMarks( plotter ); // Print a list of symbols used. - int charSize = 3 * IU_PER_MM; // text size in IUs - double charScale = 1.0/scale; // real scale will be 1/scale, - //because the global plot scale is scale - TextWidth = (int) ( (charSize * charScale) / 10 ); // Set text width (thickness) - intervalle = (int) ( charSize * charScale ) + TextWidth; + int charSize = 3 * IU_PER_MM; // text size in IUs + double charScale = 1.0 / scale; // real scale will be 1/scale, + // because the global plot scale is scale + TextWidth = (int) ( (charSize * charScale) / 10 ); // Set text width (thickness) + intervalle = (int) ( charSize * charScale ) + TextWidth; // Trace information. - plotX = (int) ( (double) bbbox.GetX() + textmarginaftersymbol * charScale ); - plotY = bbbox.GetBottom() + intervalle; + plotX = (int) ( (double) bbbox.GetX() + textmarginaftersymbol * charScale ); + plotY = bbbox.GetBottom() + intervalle; // Plot title "Info" wxString Text = wxT( "Drill Map:" ); @@ -188,139 +223,128 @@ void GenDrillMapFile( BOARD* aPcb, FILE* aFile, const wxString& aFullFileName, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, TextWidth, false, false ); - for( unsigned ii = 0; ii < aToolListBuffer.size(); ii++ ) + for( unsigned ii = 0; ii < m_toolListBuffer.size(); ii++ ) { int plot_diam; - if( aToolListBuffer[ii].m_TotalCount == 0 ) + if( m_toolListBuffer[ii].m_TotalCount == 0 ) continue; plotY += intervalle; - plot_diam = (int) aToolListBuffer[ii].m_Diameter; + plot_diam = (int) m_toolListBuffer[ii].m_Diameter; x = (int) ( (double) plotX - textmarginaftersymbol * charScale - - (double)plot_diam / 2.0 ); + - (double) plot_diam / 2.0 ); y = (int) ( (double) plotY + (double) charSize * charScale ); plotter->Marker( wxPoint( x, y ), plot_diam, ii ); - // Trace the legends. - - // List the diameter of each drill in the selected Drill Unit, - // and then its diameter in the other Drill Unit. - if( aUnit_Drill_is_Inch ) - sprintf( line, "%2.3f\" / %2.2fmm ", - diameter_in_inches( aToolListBuffer[ii].m_Diameter ), - diameter_in_mm( aToolListBuffer[ii].m_Diameter ) ); - else - sprintf( line, "%2.2fmm / %2.3f\" ", - diameter_in_mm( aToolListBuffer[ii].m_Diameter ), - diameter_in_inches( aToolListBuffer[ii].m_Diameter ) ); + // List the diameter of each drill in mm and inches. + sprintf( line, "%2.2fmm / %2.3f\" ", + diameter_in_mm( m_toolListBuffer[ii].m_Diameter ), + diameter_in_inches( m_toolListBuffer[ii].m_Diameter ) ); msg = FROM_UTF8( line ); // Now list how many holes and ovals are associated with each drill. - if( ( aToolListBuffer[ii].m_TotalCount == 1 ) - && ( aToolListBuffer[ii].m_OvalCount == 0 ) ) + if( ( m_toolListBuffer[ii].m_TotalCount == 1 ) + && ( m_toolListBuffer[ii].m_OvalCount == 0 ) ) sprintf( line, "(1 hole)" ); - else if( aToolListBuffer[ii].m_TotalCount == 1 ) // && ( aToolListBuffer[ii]m_OvalCount == 1 ) + else if( m_toolListBuffer[ii].m_TotalCount == 1 ) // && ( m_toolListBuffer[ii]m_OvalCount == 1 ) sprintf( line, "(1 slot)" ); - else if( aToolListBuffer[ii].m_OvalCount == 0 ) - sprintf( line, "(%d holes)", aToolListBuffer[ii].m_TotalCount ); - else if( aToolListBuffer[ii].m_OvalCount == 1 ) - sprintf( line, "(%d holes + 1 slot)", aToolListBuffer[ii].m_TotalCount - 1 ); - else // if ( aToolListBuffer[ii]m_OvalCount > 1 ) + else if( m_toolListBuffer[ii].m_OvalCount == 0 ) + sprintf( line, "(%d holes)", m_toolListBuffer[ii].m_TotalCount ); + else if( m_toolListBuffer[ii].m_OvalCount == 1 ) + sprintf( line, "(%d holes + 1 slot)", m_toolListBuffer[ii].m_TotalCount - 1 ); + else // if ( m_toolListBuffer[ii]m_OvalCount > 1 ) sprintf( line, "(%d holes + %d slots)", - aToolListBuffer[ii].m_TotalCount - aToolListBuffer[ii].m_OvalCount, - aToolListBuffer[ii].m_OvalCount ); + m_toolListBuffer[ii].m_TotalCount - m_toolListBuffer[ii].m_OvalCount, + m_toolListBuffer[ii].m_OvalCount ); msg += FROM_UTF8( line ); plotter->Text( wxPoint( plotX, y ), UNSPECIFIED_COLOR, msg, 0, wxSize( (int) ( charSize * charScale ), - (int) ( charSize * charScale ) ), + (int) ( charSize * charScale ) ), GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, TextWidth, false, false ); - intervalle = (int) ( charSize * charScale ) + TextWidth; - intervalle = (int) ( intervalle * 1.2 ); + intervalle = (int) ( charSize * charScale ) + TextWidth; + intervalle = (int) ( intervalle * 1.2 ); - if( intervalle < (plot_diam + (1*IU_PER_MM/scale) + TextWidth) ) - intervalle = plot_diam + (1*IU_PER_MM/scale) + TextWidth; + if( intervalle < (plot_diam + (1 * IU_PER_MM / scale) + TextWidth) ) + intervalle = plot_diam + (1 * IU_PER_MM / scale) + TextWidth; } plotter->EndPlot(); delete plotter; -} - -/** Creates the drill map aFile in HPGL or POSTSCRIPT format - * @param aPcb = the BOARD - * @param aPlotter = a PLOTTER instance (HPGL or POSTSCRIPT plotter). - * @param aHoleListBuffer = std::vector list of holes descriptors - * @param aToolListBuffer = std::vector drill list buffer - */ -void Gen_Drill_PcbMap( BOARD* aPcb, PLOTTER* aPlotter, - std::vector& aHoleListBuffer, - std::vector& aToolListBuffer ) -{ - wxPoint pos; - - // create the drill list - if( aToolListBuffer.size() > PLOTTER::MARKER_COUNT ) - { - DisplayInfoMessage( NULL, - _( " Drill map: Too many diameter values to draw one symbol per drill value\n" -"Plot will use circle shape for some drill values" ), - 10 ); - } - - // Plot the drill map: - for( unsigned ii = 0; ii < aHoleListBuffer.size(); ii++ ) - { - pos = aHoleListBuffer[ii].m_Hole_Pos; - - /* Always plot the drill symbol (for slots identifies the needed - * cutter!) */ - aPlotter->Marker( pos, aHoleListBuffer[ii].m_Hole_Diameter, - aHoleListBuffer[ii].m_Tool_Reference - 1 ); - - if( aHoleListBuffer[ii].m_Hole_Shape != 0 ) - { - wxSize oblong_size; - oblong_size = aHoleListBuffer[ii].m_Hole_Size; - aPlotter->FlashPadOval( pos, oblong_size, - aHoleListBuffer[ii].m_Hole_Orient, LINE ); - } - } + return true; } /* - * Create a list of drill values and drill count + * Create a plain text report file giving a list of drill values and drill count + * for through holes, oblong holes, and for buried vias, + * drill values and drill count per layer pair */ -void GenDrillReportFile( FILE* aFile, BOARD* aPcb, - const wxString& aBoardFilename, - bool aUnit_Drill_is_Inch, - std::vector& aHoleListBuffer, - std::vector& aToolListBuffer ) +/* Here is a sample created by this function: + * Drill report for F:/tmp/interf_u/interf_u.brd + * Created on 04/10/2012 20:48:38 + * Selected Drill Unit: Imperial (inches) + * + * Drill report for plated through holes : + * T1 0,025" 0,64mm (88 holes) + * T2 0,031" 0,79mm (120 holes) + * T3 0,032" 0,81mm (151 holes) (with 1 slot) + * T4 0,040" 1,02mm (43 holes) + * T5 0,079" 2,00mm (1 hole) (with 1 slot) + * T6 0,120" 3,05mm (1 hole) (with 1 slot) + * + * Total plated holes count 404 + * + * + * Drill report for buried and blind vias : + * + * Drill report for holes from layer Soudure to layer Interne1 : + * + * Total plated holes count 0 + * + * + * Drill report for holes from layer Interne1 to layer Interne2 : + * T1 0,025" 0,64mm (3 holes) + * + * Total plated holes count 3 + * + * + * Drill report for holes from layer Interne2 to layer Composant : + * T1 0,025" 0,64mm (1 hole) + * + * Total plated holes count 1 + * + * + * Drill report for unplated through holes : + * T1 0,120" 3,05mm (1 hole) (with 1 slot) + * + * Total unplated holes count 1 + * + */ +bool EXCELLON_WRITER::GenDrillReportFile( const wxString& aFullFileName ) { - unsigned TotalHoleCount; - char line[1024]; - int layer1 = LAYER_N_BACK; - int layer2 = LAYER_N_FRONT; - bool gen_through_holes = true; - bool gen_NPTH_holes = false; + unsigned totalHoleCount; + char line[1024]; + int layer1 = LAYER_N_BACK; + int layer2 = LAYER_N_FRONT; + bool gen_through_holes = true; + bool gen_NPTH_holes = false; + m_file = wxFopen( aFullFileName, wxT( "w" ) ); - fprintf( aFile, "Drill report for %s\n", TO_UTF8( aBoardFilename ) ); - fprintf( aFile, "Created on %s\n", TO_UTF8( DateAndTime() ) ); + if( m_file == NULL ) + return false; - // List which Drill Unit option had been selected for the associated - // drill aFile. - if( aUnit_Drill_is_Inch ) - fputs( "Selected Drill Unit: Imperial (inches)\n\n", aFile ); - else - fputs( "Selected Drill Unit: Metric (mm)\n\n", aFile ); + wxString brdFilename = m_pcb->GetFileName(); + fprintf( m_file, "Drill report for %s\n", TO_UTF8( brdFilename ) ); + fprintf( m_file, "Created on %s\n", TO_UTF8( DateAndTime() ) ); /* build hole lists: * 1 - through holes @@ -330,87 +354,66 @@ void GenDrillReportFile( FILE* aFile, BOARD* aPcb, for( ; ; ) { - Build_Holes_List( aPcb, - aHoleListBuffer, - aToolListBuffer, - layer1, - layer2, + BuildHolesList( layer1, layer2, gen_through_holes ? false : true, gen_NPTH_holes ); - TotalHoleCount = 0; + totalHoleCount = 0; if( gen_NPTH_holes ) - { sprintf( line, "Drill report for unplated through holes :\n" ); - } - else if( gen_through_holes ) - { sprintf( line, "Drill report for plated through holes :\n" ); - } else { - if( layer1 == LAYER_N_BACK ) // First partial hole list - { - sprintf( line, "Drill report for buried and blind vias :\n\n" ); - fputs( line, aFile ); - } + // If this is the first partial hole list: print a title + if( layer1 == LAYER_N_BACK ) + fputs( "Drill report for buried and blind vias :\n\n", m_file ); sprintf( line, "Drill report for holes from layer %s to layer %s :\n", - TO_UTF8( aPcb->GetLayerName( layer1 ) ), - TO_UTF8( aPcb->GetLayerName( layer2 ) ) ); + TO_UTF8( m_pcb->GetLayerName( layer1 ) ), + TO_UTF8( m_pcb->GetLayerName( layer2 ) ) ); } - fputs( line, aFile ); + fputs( line, m_file ); - for( unsigned ii = 0; ii < aToolListBuffer.size(); ii++ ) + for( unsigned ii = 0; ii < m_toolListBuffer.size(); ii++ ) { // List the tool number assigned to each drill, - // then its diameter in the selected Drill Unit, - // and then its diameter in the other Drill Unit. - if( aUnit_Drill_is_Inch ) - { - sprintf( line, "T%d %2.3f\" %2.2fmm ", - ii + 1, - diameter_in_inches( aToolListBuffer[ii].m_Diameter ), - diameter_in_mm( aToolListBuffer[ii].m_Diameter ) ); - } - else - { - sprintf( line, "T%d %2.2fmm %2.3f\" ", - ii + 1, - diameter_in_mm( aToolListBuffer[ii].m_Diameter ), - diameter_in_inches( aToolListBuffer[ii].m_Diameter ) ); - } + // in mm then in inches. + sprintf( line, "T%d %2.2fmm %2.3f\" ", + ii + 1, + diameter_in_mm( m_toolListBuffer[ii].m_Diameter ), + diameter_in_inches( m_toolListBuffer[ii].m_Diameter ) ); - fputs( line, aFile ); + fputs( line, m_file ); // Now list how many holes and ovals are associated with each drill. - if( ( aToolListBuffer[ii].m_TotalCount == 1 ) - && ( aToolListBuffer[ii].m_OvalCount == 0 ) ) + if( ( m_toolListBuffer[ii].m_TotalCount == 1 ) + && ( m_toolListBuffer[ii].m_OvalCount == 0 ) ) sprintf( line, "(1 hole)\n" ); - else if( aToolListBuffer[ii].m_TotalCount == 1 ) + else if( m_toolListBuffer[ii].m_TotalCount == 1 ) sprintf( line, "(1 hole) (with 1 slot)\n" ); - else if( aToolListBuffer[ii].m_OvalCount == 0 ) - sprintf( line, "(%d holes)\n", aToolListBuffer[ii].m_TotalCount ); - else if( aToolListBuffer[ii].m_OvalCount == 1 ) - sprintf( line, "(%d holes) (with 1 slot)\n", aToolListBuffer[ii].m_TotalCount ); - else // if ( buffer[ii]m_OvalCount > 1 ) + else if( m_toolListBuffer[ii].m_OvalCount == 0 ) + sprintf( line, "(%d holes)\n", m_toolListBuffer[ii].m_TotalCount ); + else if( m_toolListBuffer[ii].m_OvalCount == 1 ) + sprintf( line, "(%d holes) (with 1 slot)\n", + m_toolListBuffer[ii].m_TotalCount ); + else // if ( buffer[ii]m_OvalCount > 1 ) sprintf( line, "(%d holes) (with %d slots)\n", - aToolListBuffer[ii].m_TotalCount, - aToolListBuffer[ii].m_OvalCount ); + m_toolListBuffer[ii].m_TotalCount, + m_toolListBuffer[ii].m_OvalCount ); - fputs( line, aFile ); + fputs( line, m_file ); - TotalHoleCount += aToolListBuffer[ii].m_TotalCount; + totalHoleCount += m_toolListBuffer[ii].m_TotalCount; } if( gen_NPTH_holes ) - sprintf( line, "\nTotal unplated holes count %d\n\n\n", TotalHoleCount ); + sprintf( line, "\nTotal unplated holes count %d\n\n\n", totalHoleCount ); else - sprintf( line, "\nTotal plated holes count %d\n\n\n", TotalHoleCount ); + sprintf( line, "\nTotal plated holes count %d\n\n\n", totalHoleCount ); - fputs( line, aFile ); + fputs( line, m_file ); if( gen_NPTH_holes ) { @@ -418,7 +421,7 @@ void GenDrillReportFile( FILE* aFile, BOARD* aPcb, } else { - if( aPcb->GetCopperLayerCount() <= 2 ) + if( m_pcb->GetCopperLayerCount() <= 2 ) { gen_NPTH_holes = true; continue; @@ -438,13 +441,43 @@ void GenDrillReportFile( FILE* aFile, BOARD* aPcb, layer1++; layer2++; // use next layer pair - if( layer2 == aPcb->GetCopperLayerCount() - 1 ) - layer2 = LAYER_N_FRONT; // the last layer is always the - // component layer + if( layer2 == m_pcb->GetCopperLayerCount() - 1 ) + layer2 = LAYER_N_FRONT; // the last layer is always the + + // component layer } + gen_through_holes = false; } } - fclose( aFile ); + fclose( m_file ); + + return true; +} + +// Helper function to plot drill marks: +bool EXCELLON_WRITER::PlotDrillMarks( PLOTTER* aPlotter ) +{ + // Plot the drill map: + wxPoint pos; + for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ ) + { + pos = m_holeListBuffer[ii].m_Hole_Pos; + + /* Always plot the drill symbol (for slots identifies the needed + * cutter!) */ + aPlotter->Marker( pos, m_holeListBuffer[ii].m_Hole_Diameter, + m_holeListBuffer[ii].m_Tool_Reference - 1 ); + + if( m_holeListBuffer[ii].m_Hole_Shape != 0 ) + { + wxSize oblong_size; + oblong_size = m_holeListBuffer[ii].m_Hole_Size; + aPlotter->FlashPadOval( pos, oblong_size, + m_holeListBuffer[ii].m_Hole_Orient, LINE ); + } + } + + return true; } diff --git a/pcbnew/gendrill.cpp b/pcbnew/gendrill_Excellon_writer.cpp similarity index 53% rename from pcbnew/gendrill.cpp rename to pcbnew/gendrill_Excellon_writer.cpp index 121e13c04e..1dd50293e4 100644 --- a/pcbnew/gendrill.cpp +++ b/pcbnew/gendrill_Excellon_writer.cpp @@ -1,13 +1,13 @@ /** - * @file gendrill.cpp + * @file gendrill_Excellon_writer.cpp * @brief Functions to create EXCELLON drill files and report files. */ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 1992-2010 Jean_Pierre Charras - * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 1992-2012 Jean_Pierre Charras + * Copyright (C) 1992-2012 KiCad Developers, see change_log.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 @@ -39,19 +39,18 @@ #include #include -#include #include -#include #include -#include #include #include #include +#include +#include #include #include -#include +#include #include #include // Dialog box for drill file generation @@ -66,199 +65,17 @@ * Units * - Decimal * - Metric - * - * The drill maps can be created in HPGL or PS format - * - * dialog_gendrill.cpp is the file which handles - * the Dialog box for drill file generation */ -static std::vector s_ToolListBuffer; -static std::vector s_HoleListBuffer; - -/* This function displays the dialog frame for drill tools - */ -void PCB_EDIT_FRAME::InstallDrillFrame( wxCommandEvent& event ) -{ - DIALOG_GENDRILL dlg( this ); - - dlg.ShowModal(); -} - - -/** - * Function GenDrillAndReportFiles - * Calls the functions to create EXCELLON drill files and/or drill map files - * >When all holes are through, only one excellon file is created. - * >When there are some partial holes (some blind or buried vias), - * one excellon file is created, for all plated through holes, - * and one file per layer pair, which have one or more holes, excluding - * through holes, already in the first file. - * one file for all Not Plated through holes - */ -void DIALOG_GENDRILL::GenDrillAndReportFiles() -{ - wxFileName fn; - wxString layer_extend; /* added to the Board FileName to - * create FullFileName (= Board - * FileName + layer pair names) */ - wxString msg; - bool hasBuriedVias = false; /* If true, drill files are created - * layer pair by layer pair for - * buried vias */ - int layer1 = LAYER_N_BACK; - int layer2 = LAYER_N_FRONT; - bool gen_through_holes = true; - bool gen_NPTH_holes = false; - - wxString currentWD = ::wxGetCwd(); - - UpdateConfig(); // set params and Save drill options - - m_parent->ClearMsgPanel(); - - if( m_microViasCount || m_blindOrBuriedViasCount ) - hasBuriedVias = true; - - for( ; ; ) - { - Build_Holes_List( m_parent->GetBoard(), s_HoleListBuffer, - s_ToolListBuffer, layer1, layer2, - gen_through_holes ? false : true, gen_NPTH_holes ); - - if( s_ToolListBuffer.size() > 0 ) // holes? - { - fn = m_parent->GetBoard()->GetFileName(); - layer_extend.Empty(); - - if( gen_NPTH_holes ) - { - layer_extend << wxT( "-NPTH" ); - } - else if( !gen_through_holes ) - { - if( layer1 == LAYER_N_BACK ) - layer_extend << wxT( "-copper" ); - else - layer_extend << wxT( "-inner" ) << layer1; - if( layer2 == LAYER_N_FRONT ) - layer_extend << wxT( "-cmp" ); - else - layer_extend << wxT( "-inner" ) << layer2; - } - - fn.SetName( fn.GetName() + layer_extend ); - fn.SetExt( DrillFileExtension ); - wxString defaultPath = m_plotDefaultpath; - if( defaultPath.IsEmpty() ) - defaultPath = ::wxGetCwd(); - - wxFileDialog dlg( this, _( "Save Drill File" ), defaultPath, - fn.GetFullName(), wxGetTranslation( DrillFileWildcard ), - wxFD_SAVE | wxFD_CHANGE_DIR ); - - if( dlg.ShowModal() == wxID_CANCEL ) - break; - - FILE* aFile = wxFopen( dlg.GetPath(), wxT( "w" ) ); - - if( aFile == 0 ) - { - msg.Printf( _( "Unable to create drill file %s" ), GetChars( dlg.GetPath() ) ); - wxMessageBox( msg ); - ::wxSetWorkingDirectory( currentWD ); - EndModal( 0 ); - return; - } - - EXCELLON_WRITER excellonWriter( m_parent->GetBoard(), - aFile, m_FileDrillOffset, - &s_HoleListBuffer, &s_ToolListBuffer ); - excellonWriter.SetFormat( !m_UnitDrillIsInch, - (EXCELLON_WRITER::zeros_fmt) m_ZerosFormat, - m_Precision.m_lhs, m_Precision.m_rhs ); - excellonWriter.SetOptions( m_Mirror, m_MinimalHeader, m_FileDrillOffset ); - excellonWriter.CreateDrillFile(); - - switch( m_Choice_Drill_Map->GetSelection() ) - { - case 0: - break; - - case 1: - GenDrillMap( dlg.GetPath(), s_HoleListBuffer, s_ToolListBuffer, - PLOT_FORMAT_HPGL ); - break; - - case 2: - GenDrillMap( dlg.GetPath(), s_HoleListBuffer, s_ToolListBuffer, - PLOT_FORMAT_POST ); - break; - - case 3: - GenDrillMap( dlg.GetPath(), s_HoleListBuffer, s_ToolListBuffer, - PLOT_FORMAT_GERBER ); - break; - - case 4: - GenDrillMap( dlg.GetPath(), s_HoleListBuffer, s_ToolListBuffer, - PLOT_FORMAT_DXF ); - break; - - case 5: - GenDrillMap( dlg.GetPath(), s_HoleListBuffer, s_ToolListBuffer, - PLOT_FORMAT_SVG ); - break; - } - } - - if( gen_NPTH_holes ) // The last drill file was created - break; - - if( !hasBuriedVias ) - gen_NPTH_holes = true; - else - { - if( gen_through_holes ) - layer2 = layer1 + 1; // prepare generation of first layer pair - else - { - if( layer2 >= LAYER_N_FRONT ) // no more layer pair to consider - { - layer1 = LAYER_N_BACK; - layer2 = LAYER_N_FRONT; - gen_NPTH_holes = true; - continue; - } - layer1++; - layer2++; // use next layer pair - - if( layer2 == m_parent->GetBoard()->GetCopperLayerCount() - 1 ) - layer2 = LAYER_N_FRONT; // the last layer is always the - // component layer - } - - gen_through_holes = false; - } - } - - if( m_Choice_Drill_Report->GetSelection() > 0 ) - { - fn = m_parent->GetBoard()->GetFileName(); - GenDrillReport( fn.GetFullName() ); - } - - ::wxSetWorkingDirectory( currentWD ); -} - - -/** +/* * Create the drill file in EXCELLON format - * @return hole count + * return hole count */ -int EXCELLON_WRITER::CreateDrillFile() +int EXCELLON_WRITER::CreateDrillFile( FILE * aFile ) { + m_file = aFile; + int diam, holes_count; int x0, y0, xf, yf, xc, yc; double xt, yt; @@ -266,14 +83,14 @@ int EXCELLON_WRITER::CreateDrillFile() SetLocaleTo_C_standard(); // Use the standard notation for double numbers - WriteHeader(); + WriteEXCELLONHeader(); holes_count = 0; /* Write the tool list */ - for( unsigned ii = 0; ii < m_toolListBuffer->size(); ii++ ) + for( unsigned ii = 0; ii < m_toolListBuffer.size(); ii++ ) { - DRILL_TOOL& tool_descr = (*m_toolListBuffer)[ii]; + DRILL_TOOL& tool_descr = m_toolListBuffer[ii]; fprintf( m_file, "T%dC%.3f\n", ii + 1, tool_descr.m_Diameter * m_conversionUnits ); } @@ -294,9 +111,9 @@ int EXCELLON_WRITER::CreateDrillFile() /* Read the hole file and generate lines for normal holes (oblong * holes will be created later) */ int tool_reference = -2; - for( unsigned ii = 0; ii < m_holeListBuffer->size(); ii++ ) + for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ ) { - HOLE_INFO& hole_descr = (*m_holeListBuffer)[ii]; + HOLE_INFO& hole_descr = m_holeListBuffer[ii]; if( hole_descr.m_Hole_Shape ) continue; // oblong holes will be created later @@ -323,10 +140,10 @@ int EXCELLON_WRITER::CreateDrillFile() /* Read the hole file and generate lines for normal holes (oblong holes * will be created later) */ tool_reference = -2; // set to a value not used for - // aHoleListBuffer[ii].m_Tool_Reference - for( unsigned ii = 0; ii < m_holeListBuffer->size(); ii++ ) + // m_holeListBuffer[ii].m_Tool_Reference + for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ ) { - HOLE_INFO& hole_descr = (*m_holeListBuffer)[ii]; + HOLE_INFO& hole_descr = m_holeListBuffer[ii]; if( hole_descr.m_Hole_Shape == 0 ) continue; // wait for oblong holes if( tool_reference != hole_descr.m_Tool_Reference ) @@ -387,7 +204,7 @@ int EXCELLON_WRITER::CreateDrillFile() holes_count++; } - WriteEndOfFile(); + WriteEXCELLONEndOfFile(); SetLocaleTo_Default(); // Revert to locale double notation @@ -432,7 +249,7 @@ void EXCELLON_WRITER::WriteCoordinates( char* aLine, double aCoordX, double aCoo int xpad = m_precision.m_lhs + m_precision.m_rhs; int ypad = xpad; - switch( DIALOG_GENDRILL::m_ZerosFormat ) + switch( m_zeroFormat ) { default: case DECIMAL_FORMAT: @@ -526,7 +343,7 @@ void EXCELLON_WRITER::WriteCoordinates( char* aLine, double aCoordX, double aCoo * FMAT,2 * INCH,TZ */ -void EXCELLON_WRITER::WriteHeader() +void EXCELLON_WRITER::WriteEXCELLONHeader() { fputs( "M48\n", m_file ); // The beginning of a header @@ -589,7 +406,7 @@ void EXCELLON_WRITER::WriteHeader() } -void EXCELLON_WRITER::WriteEndOfFile() +void EXCELLON_WRITER::WriteEXCELLONEndOfFile() { //add if minimal here fputs( "T0\nM30\n", m_file ); @@ -597,114 +414,154 @@ void EXCELLON_WRITER::WriteEndOfFile() } -/* Generate the drill plan (Drill map) format HPGL or POSTSCRIPT + +/* Helper function for sorting hole list. + * Compare function used for sorting holes by increasing diameter value + * and X value */ -void DIALOG_GENDRILL::GenDrillMap( const wxString aFileName, - std::vector& aHoleListBuffer, - std::vector& buffer, - int format ) +static bool CmpHoleDiameterValue( const HOLE_INFO& a, const HOLE_INFO& b ) { - wxFileName fn; - wxString ext, wildcard; - wxString msg; + if( a.m_Hole_Diameter != b.m_Hole_Diameter ) + return a.m_Hole_Diameter < b.m_Hole_Diameter; - /* Init extension */ - switch( format ) - { - case PLOT_FORMAT_HPGL: - ext = HPGL_PLOTTER::GetDefaultFileExtension(); - wildcard = _( "HPGL plot files (.plt)|*.plt" ); - break; + if( a.m_Hole_Pos.x != b.m_Hole_Pos.x ) + return a.m_Hole_Pos.x < b.m_Hole_Pos.x; - case PLOT_FORMAT_POST: - ext = PS_PLOTTER::GetDefaultFileExtension(); - wildcard = _( "PostScript files (.ps)|*.ps" ); - break; - - case PLOT_FORMAT_GERBER: - ext = GERBER_PLOTTER::GetDefaultFileExtension(); - wildcard = _( "Gerber files (.pho)|*.pho" ); - break; - - case PLOT_FORMAT_DXF: - ext = DXF_PLOTTER::GetDefaultFileExtension(); - wildcard = _( "DXF files (.dxf)|*.dxf" ); - break; - - case PLOT_FORMAT_SVG: - ext = SVG_PLOTTER::GetDefaultFileExtension(); - wildcard = SVGFileWildcard; - break; - - default: - DisplayError( this, wxT( "DIALOG_GENDRILL::GenDrillMap() error" ) ); - return; - } - - /* Init file name */ - fn = aFileName; - fn.SetName( fn.GetName() + wxT( "-drl" ) ); - fn.SetExt( ext ); - - wxFileDialog dlg( this, _( "Save Drill Plot File" ), fn.GetPath(), - fn.GetFullName(), wildcard, - wxFD_SAVE ); - - if( dlg.ShowModal() == wxID_CANCEL ) - return; - - FILE* plotfile = wxFopen( dlg.GetPath(), wxT( "wt" ) ); - - if( plotfile == 0 ) - { - msg = _( "Unable to create file" ); - msg << wxT( " <" ) << dlg.GetPath() << wxT( ">" ); - wxMessageBox( msg ); - return; - } - - GenDrillMapFile( m_parent->GetBoard(), - plotfile, - dlg.GetPath(), - m_parent->GetPageSettings(), - s_HoleListBuffer, - s_ToolListBuffer, - m_UnitDrillIsInch, - format, m_FileDrillOffset ); + return a.m_Hole_Pos.y < b.m_Hole_Pos.y; } /* - * Create a list of drill values and drill count + * Create the list of holes and tools for a given board + * The list is sorted by increasing drill values + * Only holes from aFirstLayer to aLastLayer copper layers are listed (for vias, because pad holes are always through holes) + * param aFirstLayer = first layer to consider. if < 0 aFirstLayer is ignored (used to creates report file) + * param aLastLayer = last layer to consider. if < 0 aLastLayer is ignored + * param aExcludeThroughHoles : if true, exclude through holes ( pads and vias through ) + * param aGenerateNPTH_list : + * true to create NPTH only list (with no plated holes) + * false to created plated holes list (with no NPTH ) */ -void DIALOG_GENDRILL::GenDrillReport( const wxString aFileName ) +void EXCELLON_WRITER::BuildHolesList( int aFirstLayer, + int aLastLayer, + bool aExcludeThroughHoles, + bool aGenerateNPTH_list ) { - wxFileName fn; - wxString msg; + HOLE_INFO new_hole; + int hole_value; - fn = aFileName; - fn.SetName( fn.GetName() + wxT( "-drl" ) ); - fn.SetExt( ReportFileExtension ); + m_holeListBuffer.clear(); + m_toolListBuffer.clear(); - wxFileDialog dlg( this, _( "Save Drill Report File" ), fn.GetPath(), - fn.GetFullName(), wxGetTranslation( ReportFileWildcard ), - wxFD_SAVE ); - - if( dlg.ShowModal() == wxID_CANCEL ) - return; - - FILE* report_dest = wxFopen( dlg.GetPath(), wxT( "w" ) ); - - if( report_dest == 0 ) + if( (aFirstLayer >= 0) && (aLastLayer >= 0) ) { - msg = _( "Unable to create file " ) + dlg.GetPath(); - wxMessageBox( msg ); - return; + if( aFirstLayer > aLastLayer ) + EXCHG( aFirstLayer, aLastLayer ); } - GenDrillReportFile( report_dest, m_parent->GetBoard(), - m_parent->GetBoard()->GetFileName(), - m_UnitDrillIsInch, - s_HoleListBuffer, - s_ToolListBuffer ); + /* build hole list for vias + */ + if( ! aGenerateNPTH_list ) // vias are always plated ! + { + for( TRACK* track = m_pcb->m_Track; track; track = track->Next() ) + { + if( track->Type() != PCB_VIA_T ) + continue; + + SEGVIA* via = (SEGVIA*) track; + hole_value = via->GetDrillValue(); + + if( hole_value == 0 ) + continue; + + new_hole.m_Tool_Reference = -1; // Flag value for Not initialized + new_hole.m_Hole_Orient = 0; + new_hole.m_Hole_Diameter = hole_value; + new_hole.m_Hole_Size.x = new_hole.m_Hole_Size.y = new_hole.m_Hole_Diameter; + + new_hole.m_Hole_Shape = 0; // hole shape: round + new_hole.m_Hole_Pos = via->m_Start; + via->ReturnLayerPair( &new_hole.m_Hole_Top_Layer, &new_hole.m_Hole_Bottom_Layer ); + + // ReturnLayerPair return params with m_Hole_Bottom_Layer < m_Hole_Top_Layer + if( (new_hole.m_Hole_Bottom_Layer > aFirstLayer) && (aFirstLayer >= 0) ) + continue; + + if( (new_hole.m_Hole_Top_Layer < aLastLayer) && (aLastLayer >= 0) ) + continue; + + if( aExcludeThroughHoles && (new_hole.m_Hole_Bottom_Layer == LAYER_N_BACK) + && (new_hole.m_Hole_Top_Layer == LAYER_N_FRONT) ) + continue; + + m_holeListBuffer.push_back( new_hole ); + } + } + + // build hole list for pads (assumed always through holes) + if( !aExcludeThroughHoles || aGenerateNPTH_list ) + { + for( MODULE* module = m_pcb->m_Modules; module; module = module->Next() ) + { + // Read and analyse pads + for( D_PAD* pad = module->m_Pads; pad; pad = pad->Next() ) + { + if( ! aGenerateNPTH_list && pad->GetAttribute() == PAD_HOLE_NOT_PLATED ) + continue; + + if( aGenerateNPTH_list && pad->GetAttribute() != PAD_HOLE_NOT_PLATED ) + continue; + + if( pad->GetDrillSize().x == 0 ) + continue; + + new_hole.m_Hole_NotPlated = (pad->GetAttribute() == PAD_HOLE_NOT_PLATED); + new_hole.m_Tool_Reference = -1; // Flag is: Not initialized + new_hole.m_Hole_Orient = pad->GetOrientation(); + new_hole.m_Hole_Shape = 0; // hole shape: round + new_hole.m_Hole_Diameter = std::min( pad->GetDrillSize().x, pad->GetDrillSize().y ); + new_hole.m_Hole_Size.x = new_hole.m_Hole_Size.y = new_hole.m_Hole_Diameter; + + if( pad->GetDrillShape() != PAD_CIRCLE ) + new_hole.m_Hole_Shape = 1; // oval flag set + + new_hole.m_Hole_Size = pad->GetDrillSize(); + new_hole.m_Hole_Pos = pad->GetPosition(); // hole position + new_hole.m_Hole_Bottom_Layer = LAYER_N_BACK; + new_hole.m_Hole_Top_Layer = LAYER_N_FRONT;// pad holes are through holes + m_holeListBuffer.push_back( new_hole ); + } + } + } + + // Sort holes per increasing diameter value + sort( m_holeListBuffer.begin(), m_holeListBuffer.end(), CmpHoleDiameterValue ); + + // build the tool list + int LastHole = -1; /* Set to not initialised (this is a value not used + * for m_holeListBuffer[ii].m_Hole_Diameter) */ + DRILL_TOOL new_tool( 0 ); + unsigned jj; + + for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ ) + { + if( m_holeListBuffer[ii].m_Hole_Diameter != LastHole ) + { + new_tool.m_Diameter = ( m_holeListBuffer[ii].m_Hole_Diameter ); + m_toolListBuffer.push_back( new_tool ); + LastHole = new_tool.m_Diameter; + } + + jj = m_toolListBuffer.size(); + + if( jj == 0 ) + continue; // Should not occurs + + m_holeListBuffer[ii].m_Tool_Reference = jj; // Tool value Initialized (value >= 1) + + m_toolListBuffer.back().m_TotalCount++; + + if( m_holeListBuffer[ii].m_Hole_Shape ) + m_toolListBuffer.back().m_OvalCount++; + } } diff --git a/pcbnew/gendrill.h b/pcbnew/gendrill_Excellon_writer.h similarity index 64% rename from pcbnew/gendrill.h rename to pcbnew/gendrill_Excellon_writer.h index 8bb0a53ed4..f065f20991 100644 --- a/pcbnew/gendrill.h +++ b/pcbnew/gendrill_Excellon_writer.h @@ -1,13 +1,13 @@ /** - * @file gendrill.h - * @brief Classes and functions declaration used in drill file and report generation. + * @file gendrill_Excellon_writer.h + * @brief Classes used in drill files, map files and report files generation. */ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 1992-2010 Jean_Pierre Charras - * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 1992-2012 Jean_Pierre Charras + * Copyright (C) 1992-2012 KiCad Developers, see change_log.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 @@ -27,8 +27,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef _GENDRILL_H_ -#define _GENDRILL_H_ +#ifndef _GENDRILL_EXCELLON_WRITER_ +#define _GENDRILL_EXCELLON_WRITER_ #include @@ -44,7 +44,9 @@ public: int m_Diameter; // the diameter of the used tool (for oblong, the smaller size) int m_TotalCount; // how many times it is used (round and oblong) int m_OvalCount; // oblong count -public: DRILL_TOOL( int diametre ) + +public: + DRILL_TOOL( int diametre ) { m_TotalCount = 0; m_OvalCount = 0; @@ -104,7 +106,10 @@ public: DRILL_PRECISION( int l = 2, int r = 4 ) }; -// A helper class to create Excellon drill files +/** + * EXCELLON_WRITER is a class mainly used to create Excellon drill files + * However, this class is also used to create drill maps and drill report + */ class EXCELLON_WRITER { public: @@ -130,19 +135,14 @@ private: // (i.e inches or mm) bool m_mirror; wxPoint m_offset; // Drill offset ooordinates - std::vector* m_holeListBuffer; // Buffer containing holes - std::vector* m_toolListBuffer; // Buffer containing tools + std::vector m_holeListBuffer; // Buffer containing holes + std::vector m_toolListBuffer; // Buffer containing tools -public: EXCELLON_WRITER( BOARD* aPcb, FILE* aFile, - wxPoint aOffset, - std::vector* aHoleListBuffer, - std::vector* aToolListBuffer ) +public: EXCELLON_WRITER( BOARD* aPcb, wxPoint aOffset ) { - m_file = aFile; + m_file = NULL; m_pcb = aPcb; m_zeroFormat = DECIMAL_FORMAT; - m_holeListBuffer = aHoleListBuffer; - m_toolListBuffer = aToolListBuffer; m_conversionUnits = 0.0001; m_unitsDecimal = false; m_mirror = false; @@ -154,6 +154,11 @@ public: EXCELLON_WRITER( BOARD* aPcb, FILE* aFile, { } + /** + * Return the plot offset (usually the position + * of the auxiliaty axis + */ + const wxPoint GetOffset() { return m_offset; } /** * Function SetFormat @@ -179,62 +184,74 @@ public: EXCELLON_WRITER( BOARD* aPcb, FILE* aFile, m_minimalHeader = aMinimalHeader; } + /** + * Function BuildHolesList + * Create the list of holes and tools for a given board + * The list is sorted by increasing drill values + * Only holes from aFirstLayer to aLastLayer copper layers are listed (for vias, because + * pad holes are always through holes) + * @param aFirstLayer = first layer to consider. if < 0 aFirstLayer is ignored + * @param aLastLayer = last layer to consider. if < 0 aLastLayer is ignored + * @param aExcludeThroughHoles Exclude through holes if true. + * @param aGenerateNPTH_list : + * true to create NPTH only list (with no plated holes) + * false to created plated holes list (with no NPTH ) + */ + void BuildHolesList( int aFirstLayer, int aLastLayer, + bool aExcludeThroughHoles, + bool aGenerateNPTH_list ); + + int GetHolesCount() const { return m_holeListBuffer.size(); } /** * Function CreateDrillFile * Creates an Excellon drill file + * @param aFile = an opened file to write to + * will be closed by CreateDrillFile * @return hole count */ - int CreateDrillFile(); + int CreateDrillFile( FILE * aFile ); + /** + * Function GenDrillReportFile + * Create a plain text report file giving a list of drill values and drill count + * for through holes, oblong holes, and for buried vias, + * drill values and drill count per layer pair + * there is only one report for all drill files even when buried or blinds vias exist + * @param aFullFileName : the name of the file to create + * m_unitsDecimal = false tu use inches, true to use mm in report file + * + * @return success if the file is created + */ + bool GenDrillReportFile( const wxString& aFullFileName ); + + /** + * Function GenDrillMapFile + * Plot a map of drill marks for holes. + * @param aFullFileName : the name of this file (to plot it) + * @param aSheet : the paper sheet touse for plot + * @param aFormat : one of the supported plot formats (see enum PlotFormat ) + */ + bool GenDrillMapFile( const wxString& aFullFileName, + const PAGE_INFO& aSheet, + PlotFormat aFormat ); private: - void WriteHeader(); - void WriteEndOfFile(); + void WriteEXCELLONHeader(); + void WriteEXCELLONEndOfFile(); void WriteCoordinates( char* aLine, double aCoordX, double aCoordY ); + + /** Helper function. + * Writes the drill marks in HPGL, POSTSCRIPT or other supported formats + * Each hole size has a symbol (circle, cross X, cross + ...) up to + * PLOTTER::MARKER_COUNT different values. + * If more than PLOTTER::MARKER_COUNT different values, + * these other values share the same mark shape + * @param aPlotter = a PLOTTER instance (HPGL, POSTSCRIPT ... plotter). + */ + bool PlotDrillMarks( PLOTTER* plotter ); }; -/** - * Function BuildHolesList - * Create the list of holes and tools for a given board - * The list is sorted by increasing drill values - * Only holes from aFirstLayer to aLastLayer copper layers are listed (for vias, because - * pad holes are always through holes) - * @param aPcb : the given board - * @param aHoleListBuffer : the std::vector to fill with pcb holes info - * @param aToolListBuffer : the std::vector to fill with tools to use - * @param aFirstLayer = first layer to consider. if < 0 aFirstLayer is ignored - * @param aLastLayer = last layer to consider. if < 0 aLastLayer is ignored - * @param aExcludeThroughHoles Exclude through holes if true. - * @param aGenerateNPTH_list : - * true to create NPTH only list (with no plated holes) - * false to created plated holes list (with no NPTH ) - */ -void Build_Holes_List( BOARD* aPcb, std::vector& aHoleListBuffer, - std::vector& aToolListBuffer, - int aFirstLayer, int aLastLayer, bool aExcludeThroughHoles, - bool aGenerateNPTH_list ); -void GenDrillMapFile( BOARD* aPcb, - FILE* aFile, - const wxString& aFullFileName, - const PAGE_INFO& aSheet, - std::vector aHoleListBuffer, - std::vector aToolListBuffer, - bool aUnit_Drill_is_Inch, - int format, const wxPoint& auxoffset ); -void Gen_Drill_PcbMap( BOARD* aPcb, PLOTTER* plotter, - std::vector& aHoleListBuffer, - std::vector& aToolListBuffer ); -/* - * Create a list of drill values and drill count - * there is only one report for all drill files even when buried or blinds vias exist - */ -void GenDrillReportFile( FILE* aFile, BOARD* aPcb, const wxString& aBoardFilename, - bool aUnit_Drill_is_Inch, - std::vector& aHoleListBuffer, - std::vector& aToolListBuffer - ); - -#endif // #ifndef _GENDRILL_H_ +#endif // #ifndef _GENDRILL_EXCELLON_WRITER_