From b33fa0cc13a6d9335ff93c0114d7680726270e1b Mon Sep 17 00:00:00 2001 From: Martin Janitschke Date: Mon, 3 Mar 2014 09:28:05 -0500 Subject: [PATCH] Pcbnew: add option to merge non-plated through holes to drill file. (fixes lp:1133330) --- pcbnew/dialogs/dialog_gendrill.cpp | 51 +++++----- pcbnew/dialogs/dialog_gendrill.h | 28 +++++- pcbnew/dialogs/dialog_gendrill_base.cpp | 5 +- pcbnew/dialogs/dialog_gendrill_base.fbp | 92 ++++++++++++++++++- pcbnew/dialogs/dialog_gendrill_base.h | 3 +- pcbnew/exporters/gen_drill_report_files.cpp | 2 +- pcbnew/exporters/gendrill_Excellon_writer.cpp | 11 ++- pcbnew/exporters/gendrill_Excellon_writer.h | 8 +- 8 files changed, 160 insertions(+), 40 deletions(-) diff --git a/pcbnew/dialogs/dialog_gendrill.cpp b/pcbnew/dialogs/dialog_gendrill.cpp index c46e1f8e37..ee54fd6e82 100644 --- a/pcbnew/dialogs/dialog_gendrill.cpp +++ b/pcbnew/dialogs/dialog_gendrill.cpp @@ -47,6 +47,7 @@ #define PrecisionKey wxT( "DrilltPrecisionOpt" ) #define MirrorKey wxT( "DrillMirrorYOpt" ) #define MinimalHeaderKey wxT( "DrillMinHeader" ) +#define MergePTHNPTHKey wxT( "DrillMergePTHNPTH" ) #define UnitDrillInchKey wxT( "DrillUnit" ) #define DrillOriginIsAuxAxisKey wxT( "DrillAuxAxis" ) #define DrillMapFileTypeKey wxT( "DrillMapFileType" ) @@ -68,7 +69,6 @@ void PCB_EDIT_FRAME::InstallDrillFrame( wxCommandEvent& event ) } - DIALOG_GENDRILL::DIALOG_GENDRILL( PCB_EDIT_FRAME* parent ) : DIALOG_GENDRILL_BASE( parent ) { @@ -88,6 +88,7 @@ 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_Merge_PTH_NPTH = false; bool DIALOG_GENDRILL::m_DrillOriginIsAuxAxis = false; int DIALOG_GENDRILL::m_mapFileType = 1; @@ -102,6 +103,7 @@ void DIALOG_GENDRILL::initDialog() { m_config->Read( ZerosFormatKey, &m_ZerosFormat ); m_config->Read( MirrorKey, &m_Mirror ); + m_config->Read( MergePTHNPTHKey, &m_Merge_PTH_NPTH ); m_config->Read( MinimalHeaderKey, &m_MinimalHeader ); m_config->Read( UnitDrillInchKey, &m_UnitDrillIsInch ); m_config->Read( DrillOriginIsAuxAxisKey, &m_DrillOriginIsAuxAxis ); @@ -124,6 +126,7 @@ void DIALOG_GENDRILL::InitDisplayParams() m_Choice_Drill_Offset->SetSelection( 1 ); m_Check_Mirror->SetValue( m_Mirror ); + m_Check_Merge_PTH_NPTH->SetValue( m_Merge_PTH_NPTH ); m_Choice_Drill_Map->SetSelection( m_mapFileType ); m_ViaDrillValue->SetLabel( _( "Use Netclasses values" ) ); m_MicroViaDrillValue->SetLabel( _( "Use Netclasses values" ) ); @@ -213,6 +216,7 @@ void DIALOG_GENDRILL::UpdateConfig() m_config->Write( ZerosFormatKey, m_ZerosFormat ); m_config->Write( MirrorKey, m_Mirror ); m_config->Write( MinimalHeaderKey, m_MinimalHeader ); + m_config->Write( MergePTHNPTHKey, m_Merge_PTH_NPTH ); m_config->Write( UnitDrillInchKey, m_UnitDrillIsInch ); m_config->Write( DrillOriginIsAuxAxisKey, m_DrillOriginIsAuxAxis ); m_config->Write( DrillMapFileTypeKey, m_mapFileType ); @@ -229,6 +233,7 @@ void DIALOG_GENDRILL::OnGenMapFile( wxCommandEvent& event ) GenDrillAndMapFiles( false, true); } + void DIALOG_GENDRILL::OnGenDrillFile( wxCommandEvent& event ) { GenDrillAndMapFiles(true, false); @@ -264,6 +269,7 @@ void DIALOG_GENDRILL::UpdatePrecisionOptions() m_staticTextPrecision->Enable( true ); } + void DIALOG_GENDRILL::OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) { // Build the absolute path of current output plot directory @@ -292,14 +298,14 @@ void DIALOG_GENDRILL::OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) wxString boardFilePath = ( (wxFileName) m_parent->GetBoard()->GetFileName() ).GetPath(); if( !dirName.MakeRelativeTo( boardFilePath ) ) - wxMessageBox( _( - "Cannot make path relative (target volume different from board file volume)!" ), + wxMessageBox( _( "Cannot make path relative. The target volume is different from board file volume!" ), _( "Plot Output Directory" ), wxOK | wxICON_ERROR ); } m_outputDirectoryName->SetValue( dirName.GetFullPath() ); } + void DIALOG_GENDRILL::SetParams() { wxString msg; @@ -315,6 +321,7 @@ void DIALOG_GENDRILL::SetParams() m_UnitDrillIsInch = (m_Choice_Unit->GetSelection() == 0) ? false : true; m_MinimalHeader = m_Check_Minimal->IsChecked(); m_Mirror = m_Check_Mirror->IsChecked(); + m_Merge_PTH_NPTH = m_Check_Merge_PTH_NPTH->IsChecked(); m_ZerosFormat = m_Choice_Zeros_Format->GetSelection(); m_DrillOriginIsAuxAxis = m_Choice_Drill_Offset->GetSelection(); @@ -331,16 +338,7 @@ void DIALOG_GENDRILL::SetParams() 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 holes, 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 @@ -369,14 +367,14 @@ void DIALOG_GENDRILL::GenDrillAndMapFiles(bool aGenDrill, bool aGenMap) 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.SetOptions( m_Mirror, m_MinimalHeader, m_FileDrillOffset, m_Merge_PTH_NPTH ); wxFileName fn; for( ; ; ) { - excellonWriter.BuildHolesList( layer1, layer2, - gen_through_holes ? false : true, gen_NPTH_holes ); + excellonWriter.BuildHolesList( layer1, layer2, gen_through_holes ? false : true, + gen_NPTH_holes, m_Merge_PTH_NPTH ); if( excellonWriter.GetHolesCount() > 0 ) // has holes? { @@ -393,6 +391,7 @@ void DIALOG_GENDRILL::GenDrillAndMapFiles(bool aGenDrill, bool aGenMap) layer_extend << wxT( "-back" ); else layer_extend << wxT( "-inner" ) << layer1; + if( layer2 == LAYER_N_FRONT ) layer_extend << wxT( "-front" ); else @@ -401,6 +400,7 @@ void DIALOG_GENDRILL::GenDrillAndMapFiles(bool aGenDrill, bool aGenMap) fn.SetName( fn.GetName() + layer_extend ); wxString defaultPath = m_plotOpts.GetOutputDirectory(); + if( defaultPath.IsEmpty() ) defaultPath = ::wxGetCwd(); @@ -466,6 +466,7 @@ void DIALOG_GENDRILL::GenDrillAndMapFiles(bool aGenDrill, bool aGenMap) gen_NPTH_holes = true; continue; } + layer1++; layer2++; // use next layer pair @@ -482,11 +483,6 @@ void DIALOG_GENDRILL::GenDrillAndMapFiles(bool aGenDrill, bool aGenMap) } -/* - * 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 @@ -497,6 +493,7 @@ void DIALOG_GENDRILL::OnGenReportFile( wxCommandEvent& event ) fn.SetExt( ReportFileExtension ); wxString defaultPath = m_plotOpts.GetOutputDirectory(); + if( defaultPath.IsEmpty() ) defaultPath = ::wxGetCwd(); @@ -512,7 +509,7 @@ void DIALOG_GENDRILL::OnGenReportFile( wxCommandEvent& event ) 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.SetOptions( m_Mirror, m_MinimalHeader, m_FileDrillOffset, m_Merge_PTH_NPTH ); bool success = excellonWriter.GenDrillReportFile( dlg.GetPath() ); @@ -572,7 +569,7 @@ void DIALOG_GENDRILL::GenDrillMap( const wxString aFullFileNameWithoutExt, break; default: - wxLogMessage( wxT( "DIALOG_GENDRILL::GenDrillMap() error, fmt % unkown" ), format ); + wxLogMessage( wxT( "DIALOG_GENDRILL::GenDrillMap() error, fmt % unknown" ), format ); return; } @@ -581,15 +578,14 @@ void DIALOG_GENDRILL::GenDrillMap( const wxString aFullFileNameWithoutExt, fullFilename << wxT(".") << ext; bool success = aExcellonWriter.GenDrillMapFile( fullFilename, - m_parent->GetPageSettings(), - format ); + m_parent->GetPageSettings(), + format ); wxString msg; if( ! success ) { - msg.Printf( _( "** Unable to create %s **\n" ), - GetChars( fullFilename ) ); + msg.Printf( _( "** Unable to create %s **\n" ), GetChars( fullFilename ) ); m_messagesBox->AppendText( msg ); return; } @@ -598,5 +594,4 @@ void DIALOG_GENDRILL::GenDrillMap( const wxString aFullFileNameWithoutExt, 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 b7c2717886..c9b32cfed0 100644 --- a/pcbnew/dialogs/dialog_gendrill.h +++ b/pcbnew/dialogs/dialog_gendrill.h @@ -41,6 +41,7 @@ public: static int m_ZerosFormat; static bool m_MinimalHeader; static bool m_Mirror; + static bool m_Merge_PTH_NPTH; static bool m_DrillOriginIsAuxAxis; /* Axis selection (main / auxiliary) * for drill origin coordinates */ DRILL_PRECISION m_Precision; // Selected precision for drill files @@ -69,15 +70,34 @@ private: // event functions void OnSelDrillUnitsSelected( wxCommandEvent& event ); void OnSelZerosFmtSelected( wxCommandEvent& event ); - void OnGenDrillFile( wxCommandEvent& event ); - void OnGenMapFile( wxCommandEvent& event ); - void OnGenReportFile( wxCommandEvent& event ); + void OnGenDrillFile( wxCommandEvent& event ); + void OnGenMapFile( wxCommandEvent& event ); + + /* + * 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 OnGenReportFile( wxCommandEvent& event ); + void OnCancelClick( wxCommandEvent& event ); void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ); // Specific functions: void SetParams( void ); - void GenDrillAndMapFiles(bool aGenDrill, bool aGenMap); + + /** + * Function GenDrillAndMapFiles + * Calls the functions to create EXCELLON drill files and/or drill map files + * >When all holes are through holes, 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 GenDrillAndMapFiles( bool aGenDrill, bool aGenMap ); + void GenDrillMap( const wxString aFileName, EXCELLON_WRITER& aExcellonWriter, PlotFormat format ); diff --git a/pcbnew/dialogs/dialog_gendrill_base.cpp b/pcbnew/dialogs/dialog_gendrill_base.cpp index 0210d9fb84..126fce0196 100644 --- a/pcbnew/dialogs/dialog_gendrill_base.cpp +++ b/pcbnew/dialogs/dialog_gendrill_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 8 2012) +// C++ code generated with wxFormBuilder (version Feb 26 2014) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -88,6 +88,9 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con m_Check_Minimal = new wxCheckBox( this, wxID_ANY, _("Minimal header"), wxDefaultPosition, wxDefaultSize, 0 ); sbOptSizer->Add( m_Check_Minimal, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + m_Check_Merge_PTH_NPTH = new wxCheckBox( this, wxID_ANY, _("Merge PTH and NPTH holes into one file"), wxDefaultPosition, wxDefaultSize, 0 ); + sbOptSizer->Add( m_Check_Merge_PTH_NPTH, 0, wxALL, 5 ); + bMiddleBoxSizer->Add( sbOptSizer, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); diff --git a/pcbnew/dialogs/dialog_gendrill_base.fbp b/pcbnew/dialogs/dialog_gendrill_base.fbp index 940053bf24..06fce1aa16 100644 --- a/pcbnew/dialogs/dialog_gendrill_base.fbp +++ b/pcbnew/dialogs/dialog_gendrill_base.fbp @@ -1,6 +1,6 @@ - + C++ @@ -20,8 +20,10 @@ . 1 + 1 1 1 + UI 0 0 @@ -879,6 +881,94 @@ + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Merge PTH and NPTH holes into one file + + 0 + + + 0 + + 1 + m_Check_Merge_PTH_NPTH + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pcbnew/dialogs/dialog_gendrill_base.h b/pcbnew/dialogs/dialog_gendrill_base.h index 63aa22dfbb..fc61ef59de 100644 --- a/pcbnew/dialogs/dialog_gendrill_base.h +++ b/pcbnew/dialogs/dialog_gendrill_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 8 2012) +// C++ code generated with wxFormBuilder (version Feb 26 2014) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -48,6 +48,7 @@ class DIALOG_GENDRILL_BASE : public DIALOG_SHIM wxRadioBox* m_Choice_Drill_Map; wxCheckBox* m_Check_Mirror; wxCheckBox* m_Check_Minimal; + wxCheckBox* m_Check_Merge_PTH_NPTH; wxRadioBox* m_Choice_Drill_Offset; wxStaticBoxSizer* m_DefaultViasDrillSizer; wxStaticText* m_ViaDrillValue; diff --git a/pcbnew/exporters/gen_drill_report_files.cpp b/pcbnew/exporters/gen_drill_report_files.cpp index c73e4e19d1..2c4f9b8c7c 100644 --- a/pcbnew/exporters/gen_drill_report_files.cpp +++ b/pcbnew/exporters/gen_drill_report_files.cpp @@ -360,7 +360,7 @@ bool EXCELLON_WRITER::GenDrillReportFile( const wxString& aFullFileName ) for( ; ; ) { BuildHolesList( layer1, layer2, - gen_through_holes ? false : true, gen_NPTH_holes ); + gen_through_holes ? false : true, gen_NPTH_holes, false); totalHoleCount = 0; diff --git a/pcbnew/exporters/gendrill_Excellon_writer.cpp b/pcbnew/exporters/gendrill_Excellon_writer.cpp index 7ad2293b95..91b486c4ad 100644 --- a/pcbnew/exporters/gendrill_Excellon_writer.cpp +++ b/pcbnew/exporters/gendrill_Excellon_writer.cpp @@ -442,11 +442,13 @@ static bool CmpHoleDiameterValue( const HOLE_INFO& a, const HOLE_INFO& b ) * param aGenerateNPTH_list : * true to create NPTH only list (with no plated holes) * false to created plated holes list (with no NPTH ) + * param aMergePTHNPTH : if true, merge PTH and NPTH holes into one file by treating all holes as PTH */ void EXCELLON_WRITER::BuildHolesList( int aFirstLayer, int aLastLayer, bool aExcludeThroughHoles, - bool aGenerateNPTH_list ) + bool aGenerateNPTH_list, + bool aMergePTHNPTH ) { HOLE_INFO new_hole; int hole_value; @@ -460,6 +462,11 @@ void EXCELLON_WRITER::BuildHolesList( int aFirstLayer, EXCHG( aFirstLayer, aLastLayer ); } + if ( aGenerateNPTH_list && aMergePTHNPTH ) + { + return; + } + /* build hole list for vias */ if( ! aGenerateNPTH_list ) // vias are always plated ! @@ -507,7 +514,7 @@ void EXCELLON_WRITER::BuildHolesList( int aFirstLayer, // Read and analyse pads for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) { - if( ! aGenerateNPTH_list && pad->GetAttribute() == PAD_HOLE_NOT_PLATED ) + if( ! aGenerateNPTH_list && pad->GetAttribute() == PAD_HOLE_NOT_PLATED && ! aMergePTHNPTH ) continue; if( aGenerateNPTH_list && pad->GetAttribute() != PAD_HOLE_NOT_PLATED ) diff --git a/pcbnew/exporters/gendrill_Excellon_writer.h b/pcbnew/exporters/gendrill_Excellon_writer.h index 2a059fade4..e62501e80a 100644 --- a/pcbnew/exporters/gendrill_Excellon_writer.h +++ b/pcbnew/exporters/gendrill_Excellon_writer.h @@ -135,6 +135,7 @@ private: // (i.e inches or mm) bool m_mirror; wxPoint m_offset; // Drill offset ooordinates + bool m_mergePTHNPTH; std::vector m_holeListBuffer; // Buffer containing holes std::vector m_toolListBuffer; // Buffer containing tools @@ -146,6 +147,7 @@ public: EXCELLON_WRITER( BOARD* aPcb, wxPoint aOffset ) m_conversionUnits = 0.0001; m_unitsDecimal = false; m_mirror = false; + m_mergePTHNPTH = false; m_minimalHeader = false; } @@ -177,11 +179,12 @@ public: EXCELLON_WRITER( BOARD* aPcb, wxPoint aOffset ) * @param aMinimalHeader = true to use a minimal header (no comments, no info) * @param aOffset = drill coordinates offset */ - void SetOptions( bool aMirror, bool aMinimalHeader, wxPoint aOffset ) + void SetOptions( bool aMirror, bool aMinimalHeader, wxPoint aOffset, bool aMergePTHNPTH ) { m_mirror = aMirror; m_offset = aOffset; m_minimalHeader = aMinimalHeader; + m_mergePTHNPTH = aMergePTHNPTH; } /** @@ -199,7 +202,8 @@ public: EXCELLON_WRITER( BOARD* aPcb, wxPoint aOffset ) */ void BuildHolesList( int aFirstLayer, int aLastLayer, bool aExcludeThroughHoles, - bool aGenerateNPTH_list ); + bool aGenerateNPTH_list, + bool aMergePTHNPTH ); int GetHolesCount() const { return m_holeListBuffer.size(); }