From 20bebeb543d8e30d31148644921099afd3ba399c Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Thu, 23 Jun 2022 11:56:27 +0200 Subject: [PATCH] Gen Drill map: Re-add Gerber option but only using X2 format. Only the X2 format allows the TF.FileFunction option, mandatory to avoid mistakes about this file that is not a standard Gerber file. --- pcbnew/dialogs/dialog_gendrill.cpp | 7 +- pcbnew/dialogs/dialog_gendrill_base.cpp | 19 ++- pcbnew/dialogs/dialog_gendrill_base.fbp | 134 +++++++++++++++++++- pcbnew/dialogs/dialog_gendrill_base.h | 4 +- pcbnew/exporters/gen_drill_report_files.cpp | 68 +++++++--- 5 files changed, 196 insertions(+), 36 deletions(-) diff --git a/pcbnew/dialogs/dialog_gendrill.cpp b/pcbnew/dialogs/dialog_gendrill.cpp index e0fcf22cb1..97022654b4 100644 --- a/pcbnew/dialogs/dialog_gendrill.cpp +++ b/pcbnew/dialogs/dialog_gendrill.cpp @@ -92,7 +92,7 @@ int DIALOG_GENDRILL::m_ZerosFormat = EXCELLON_WRITER::DECIMAL_FORMAT; bool DIALOG_GENDRILL::m_MinimalHeader = false; // Only for Excellon format bool DIALOG_GENDRILL::m_Mirror = false; // Only for Excellon format bool DIALOG_GENDRILL::m_Merge_PTH_NPTH = false; // Only for Excellon format -int DIALOG_GENDRILL::m_mapFileType = 3; +int DIALOG_GENDRILL::m_mapFileType = 4; // The last choice in m_Choice_Drill_Map int DIALOG_GENDRILL::m_drillFileType = 0; bool DIALOG_GENDRILL::m_UseRouteModeForOvalHoles = true; // Use G00 route mode to "drill" oval holes @@ -117,8 +117,8 @@ void DIALOG_GENDRILL::initDialog() m_drillOriginIsAuxAxis = m_plotOpts.GetUseAuxOrigin(); // Ensure validity of m_mapFileType - if( m_mapFileType < 0 || m_mapFileType > 3 ) - m_mapFileType = 3; // default = PDF + if( m_mapFileType < 0 || m_mapFileType >= (int)m_Choice_Drill_Map->GetCount() ) + m_mapFileType = m_Choice_Drill_Map->GetCount() - 1; // last item in list = default = PDF InitDisplayParams(); } @@ -375,6 +375,7 @@ void DIALOG_GENDRILL::GenDrillAndMapFiles( bool aGenDrill, bool aGenMap ) const PLOT_FORMAT filefmt[] = { // Keep these format ids in the same order than m_Choice_Drill_Map choices PLOT_FORMAT::POST, + PLOT_FORMAT::GERBER, // Only X2 format because we need the .FileFunction attribute PLOT_FORMAT::DXF, PLOT_FORMAT::SVG, PLOT_FORMAT::PDF diff --git a/pcbnew/dialogs/dialog_gendrill_base.cpp b/pcbnew/dialogs/dialog_gendrill_base.cpp index 0e03044239..91680d69ab 100644 --- a/pcbnew/dialogs/dialog_gendrill_base.cpp +++ b/pcbnew/dialogs/dialog_gendrill_base.cpp @@ -79,11 +79,19 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con bMiddleSizer->Add( sbSizer6, 1, wxEXPAND|wxALL, 5 ); - wxString m_Choice_Drill_MapChoices[] = { _("PostScript"), _("DXF"), _("SVG"), _("PDF") }; + m_staticTextInfo1 = new wxStaticText( this, wxID_ANY, _("Note:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextInfo1->Wrap( -1 ); + bMiddleSizer->Add( m_staticTextInfo1, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_staticTextInfo = new wxStaticText( this, wxID_ANY, _("A drill map is a doc. file, not a fab. file"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextInfo->Wrap( -1 ); + bMiddleSizer->Add( m_staticTextInfo, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + wxString m_Choice_Drill_MapChoices[] = { _("PostScript"), _("Gerber X2"), _("DXF"), _("SVG"), _("PDF") }; int m_Choice_Drill_MapNChoices = sizeof( m_Choice_Drill_MapChoices ) / sizeof( wxString ); m_Choice_Drill_Map = new wxRadioBox( this, wxID_ANY, _("Map File Format"), wxDefaultPosition, wxDefaultSize, m_Choice_Drill_MapNChoices, m_Choice_Drill_MapChoices, 1, wxRA_SPECIFY_COLS ); - m_Choice_Drill_Map->SetSelection( 5 ); - m_Choice_Drill_Map->SetToolTip( _("Creates a drill map in PS, HPGL or other formats") ); + m_Choice_Drill_Map->SetSelection( 4 ); + m_Choice_Drill_Map->SetToolTip( _("Creates a drill map in PDF or other formats") ); bMiddleSizer->Add( m_Choice_Drill_Map, 0, wxALL|wxEXPAND, 5 ); @@ -133,7 +141,7 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con bLeftSizer->Add( fgSizer1, 0, wxEXPAND, 5 ); - bmiddlerSizer->Add( bLeftSizer, 1, wxEXPAND, 5 ); + bmiddlerSizer->Add( bLeftSizer, 0, wxEXPAND, 5 ); wxBoxSizer* bRightBoxSizer; bRightBoxSizer = new wxBoxSizer( wxVERTICAL ); @@ -193,7 +201,7 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con bRightBoxSizer->Add( sbSizerHoles, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 ); - bmiddlerSizer->Add( bRightBoxSizer, 1, wxEXPAND|wxTOP, 5 ); + bmiddlerSizer->Add( bRightBoxSizer, 0, wxEXPAND|wxTOP, 5 ); bMainSizer->Add( bmiddlerSizer, 0, wxEXPAND|wxTOP, 2 ); @@ -231,7 +239,6 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con this->SetSizer( bMainSizer ); this->Layout(); - bMainSizer->Fit( this ); this->Centre( wxBOTH ); diff --git a/pcbnew/dialogs/dialog_gendrill_base.fbp b/pcbnew/dialogs/dialog_gendrill_base.fbp index 867d3c1ae8..f4c278be10 100644 --- a/pcbnew/dialogs/dialog_gendrill_base.fbp +++ b/pcbnew/dialogs/dialog_gendrill_base.fbp @@ -47,7 +47,7 @@ DIALOG_GENDRILL_BASE - -1,-1 + 643,558 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER DIALOG_SHIM; dialog_shim.h Generate Drill Files @@ -703,6 +703,128 @@ + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Note: + 0 + + 0 + + + 0 + + 1 + m_staticTextInfo1 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + A drill map is a doc. file, not a fab. file + 0 + + 0 + + + 0 + + 1 + m_staticTextInfo + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + 5 wxALL|wxEXPAND @@ -721,7 +843,7 @@ 1 0 - "PostScript" "DXF" "SVG" "PDF" + "PostScript" "Gerber X2" "DXF" "SVG" "PDF" 1 1 @@ -753,13 +875,13 @@ 1 Resizable - 5 + 4 1 wxRA_SPECIFY_COLS 0 - Creates a drill map in PS, HPGL or other formats + Creates a drill map in PDF or other formats wxFILTER_NONE wxDefaultValidator @@ -774,7 +896,7 @@ 5 wxEXPAND - 1 + 0 bLeftSizer @@ -1125,7 +1247,7 @@ 5 wxEXPAND|wxTOP - 1 + 0 bRightBoxSizer diff --git a/pcbnew/dialogs/dialog_gendrill_base.h b/pcbnew/dialogs/dialog_gendrill_base.h index fdb735d56f..0a9f8e9bfb 100644 --- a/pcbnew/dialogs/dialog_gendrill_base.h +++ b/pcbnew/dialogs/dialog_gendrill_base.h @@ -50,6 +50,8 @@ class DIALOG_GENDRILL_BASE : public DIALOG_SHIM wxCheckBox* m_Check_Merge_PTH_NPTH; wxRadioBox* m_radioBoxOvalHoleMode; wxRadioButton* m_rbGerberX2; + wxStaticText* m_staticTextInfo1; + wxStaticText* m_staticTextInfo; wxRadioBox* m_Choice_Drill_Map; wxRadioBox* m_Choice_Drill_Offset; wxRadioBox* m_Choice_Unit; @@ -88,7 +90,7 @@ class DIALOG_GENDRILL_BASE : public DIALOG_SHIM public: - DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Generate Drill Files"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Generate Drill Files"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 643,558 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~DIALOG_GENDRILL_BASE(); diff --git a/pcbnew/exporters/gen_drill_report_files.cpp b/pcbnew/exporters/gen_drill_report_files.cpp index bf769914a5..a7d230e317 100644 --- a/pcbnew/exporters/gen_drill_report_files.cpp +++ b/pcbnew/exporters/gen_drill_report_files.cpp @@ -44,6 +44,7 @@ #include #include #include +#include /* Conversion utilities - these will be used often in there... */ @@ -92,11 +93,9 @@ bool GENDRILL_WRITER_BASE::genDrillMapFile( const wxString& aFullFileName, PLOT_ m_pcb->SetVisibleLayers( visibleLayers ); // Some formats cannot be used to generate a document like the map files - // - HPGL (old format not very used) - // - GERBER because a map file is not a fabrication file usable by board house - // (in fact such a file usually create problems when sent to a board house) + // Currently HPGL (old format not very used) - if( aFormat == PLOT_FORMAT::HPGL || aFormat == PLOT_FORMAT::GERBER ) + if( aFormat == PLOT_FORMAT::HPGL ) aFormat = PLOT_FORMAT::PDF; // Calculate the scale for the format type, scale 1 in HPGL, drawing on @@ -104,7 +103,11 @@ bool GENDRILL_WRITER_BASE::genDrillMapFile( const wxString& aFullFileName, PLOT_ switch( aFormat ) { case PLOT_FORMAT::GERBER: - case PLOT_FORMAT::HPGL: // Scale for HPGL format. + plotter = new GERBER_PLOTTER(); + plotter->SetViewport( offset, IU_PER_MILS / 10, scale, false ); + plotter->SetGerberCoordinatesFormat( 5 ); // format x.5 unit = mm + break; + default: wxASSERT( false ); KI_FALLTHROUGH; @@ -184,30 +187,55 @@ bool GENDRILL_WRITER_BASE::genDrillMapFile( const wxString& aFullFileName, PLOT_ return false; } + plotter->ClearHeaderLinesList(); + + // For the Gerber X2 format we need to set the "FileFunction" to Drillmap + // and set a few other options. + if( plotter->GetPlotterType() == PLOT_FORMAT::GERBER ) + { + GERBER_PLOTTER* gbrplotter = static_cast ( plotter ); + gbrplotter->DisableApertMacros( false ); + gbrplotter->UseX2format( true ); // Mandatory + gbrplotter->UseX2NetAttributes( false ); // net attributes hace no meaning here + + // Attributes are added using X2 format + AddGerberX2Header( gbrplotter, m_pcb, false ); + + wxString text; + + // Add the TF.FileFunction + text = "%TF.FileFunction,Drillmap*%"; + gbrplotter->AddLineToHeader( text ); + + // Add the TF.FilePolarity + text = wxT( "%TF.FilePolarity,Positive*%" ); + gbrplotter->AddLineToHeader( text ); + } + plotter->StartPlot(); - // Draw items on edge layer (not all, only items useful for drill map + // Draw items on edge layer. + // Not all, only items useful for drill map, i.e. board outlines. BRDITEMS_PLOTTER itemplotter( plotter, m_pcb, plot_opts ); - itemplotter.SetLayerSet( Edge_Cuts ); - for( auto PtStruct : m_pcb->Drawings() ) + // Use attributes of a drawing layer (we are not really draw the Edge.Cuts layer) + itemplotter.SetLayerSet( Dwgs_User ); + + for( BOARD_ITEM* item : m_pcb->Drawings() ) { - switch( PtStruct->Type() ) + if( item->GetLayer() != Edge_Cuts ) + continue; + + switch( item->Type() ) { case PCB_SHAPE_T: - itemplotter.PlotPcbShape( (PCB_SHAPE*) PtStruct ); + { + PCB_SHAPE dummy_shape( *static_cast( item ) ); + dummy_shape.SetLayer( Dwgs_User ); + itemplotter.PlotPcbShape( &dummy_shape ); + } break; - case PCB_TEXT_T: - itemplotter.PlotPcbText( (PCB_TEXT*) PtStruct ); - break; - - case PCB_DIM_ALIGNED_T: - case PCB_DIM_CENTER_T: - case PCB_DIM_ORTHOGONAL_T: - case PCB_DIM_LEADER_T: - case PCB_TARGET_T: - case PCB_MARKER_T: // do not draw default: break; }