From f0efa9af9d7a84533237fc7084b0a07dda6050d6 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Tue, 2 Aug 2022 11:22:12 +0200 Subject: [PATCH] gen_footprints_placefile: re-add option to negate or not the X coordinate. This option is for footprints on bottom side, and not for Gerber format. This option was existing in 5.x version, but lost in 6.x version. Fixes #4638 https://gitlab.com/kicad/code/kicad/issues/4638 --- ...ialog_gen_footprint_position_file_base.cpp | 7 +- ...ialog_gen_footprint_position_file_base.fbp | 71 ++++++++++++++++++- .../dialog_gen_footprint_position_file_base.h | 7 +- .../exporters/export_footprints_placefile.cpp | 17 ++--- .../exporters/export_footprints_placefile.h | 21 +++--- pcbnew/exporters/gen_footprints_placefile.cpp | 38 ++++++++-- pcbnew/pcb_edit_frame.h | 3 +- pcbnew/pcbnew_settings.cpp | 3 + pcbnew/pcbnew_settings.h | 1 + 9 files changed, 139 insertions(+), 29 deletions(-) diff --git a/pcbnew/dialogs/dialog_gen_footprint_position_file_base.cpp b/pcbnew/dialogs/dialog_gen_footprint_position_file_base.cpp index f2011429a9..24af25ae58 100644 --- a/pcbnew/dialogs/dialog_gen_footprint_position_file_base.cpp +++ b/pcbnew/dialogs/dialog_gen_footprint_position_file_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 26 2018) +// C++ code generated with wxFormBuilder (version 3.10.0-39-g3487c3cb) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -83,6 +83,9 @@ DIALOG_GEN_FOOTPRINT_POSITION_BASE::DIALOG_GEN_FOOTPRINT_POSITION_BASE( wxWindow m_useDrillPlaceOrigin = new wxCheckBox( this, wxID_ANY, _("Use drill/place file origin"), wxDefaultPosition, wxDefaultSize, 0 ); bSizerLower->Add( m_useDrillPlaceOrigin, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + m_negateXcb = new wxCheckBox( this, wxID_ANY, _("Use negative X coordinates for footprints on bottom layer"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerLower->Add( m_negateXcb, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + m_messagesPanel = new WX_HTML_REPORT_PANEL( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); m_messagesPanel->SetMinSize( wxSize( 350,300 ) ); @@ -118,6 +121,7 @@ DIALOG_GEN_FOOTPRINT_POSITION_BASE::DIALOG_GEN_FOOTPRINT_POSITION_BASE( wxWindow m_onlySMD->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GEN_FOOTPRINT_POSITION_BASE::onUpdateUIOnlySMD ), NULL, this ); m_excludeTH->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GEN_FOOTPRINT_POSITION_BASE::onUpdateUIExcludeTH ), NULL, this ); m_cbIncludeBoardEdge->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GEN_FOOTPRINT_POSITION_BASE::onUpdateUIincludeBoardEdge ), NULL, this ); + m_negateXcb->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GEN_FOOTPRINT_POSITION_BASE::onUpdateUInegXcoord ), NULL, this ); m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GEN_FOOTPRINT_POSITION_BASE::OnGenerate ), NULL, this ); } @@ -131,6 +135,7 @@ DIALOG_GEN_FOOTPRINT_POSITION_BASE::~DIALOG_GEN_FOOTPRINT_POSITION_BASE() m_onlySMD->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GEN_FOOTPRINT_POSITION_BASE::onUpdateUIOnlySMD ), NULL, this ); m_excludeTH->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GEN_FOOTPRINT_POSITION_BASE::onUpdateUIExcludeTH ), NULL, this ); m_cbIncludeBoardEdge->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GEN_FOOTPRINT_POSITION_BASE::onUpdateUIincludeBoardEdge ), NULL, this ); + m_negateXcb->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GEN_FOOTPRINT_POSITION_BASE::onUpdateUInegXcoord ), NULL, this ); m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GEN_FOOTPRINT_POSITION_BASE::OnGenerate ), NULL, this ); } diff --git a/pcbnew/dialogs/dialog_gen_footprint_position_file_base.fbp b/pcbnew/dialogs/dialog_gen_footprint_position_file_base.fbp index 93b2b8c8b5..e6844f1ff1 100644 --- a/pcbnew/dialogs/dialog_gen_footprint_position_file_base.fbp +++ b/pcbnew/dialogs/dialog_gen_footprint_position_file_base.fbp @@ -1,6 +1,6 @@ - + C++ @@ -14,6 +14,7 @@ dialog_gen_footprint_position_file_base 1000 none + 1 dialog_gen_footprint_positions_base @@ -25,6 +26,7 @@ 1 1 UI + 0 1 0 @@ -50,6 +52,7 @@ DIALOG_SHIM; dialog_shim.h Generate Placement Files + 0 @@ -214,6 +217,7 @@ + 0 @@ -758,6 +762,71 @@ + + 5 + wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Use negative X coordinates for footprints on bottom layer + + 0 + + + 0 + + 1 + m_negateXcb + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + onUpdateUInegXcoord + + 5 wxEXPAND | wxALL diff --git a/pcbnew/dialogs/dialog_gen_footprint_position_file_base.h b/pcbnew/dialogs/dialog_gen_footprint_position_file_base.h index c8cda4d463..de5607a847 100644 --- a/pcbnew/dialogs/dialog_gen_footprint_position_file_base.h +++ b/pcbnew/dialogs/dialog_gen_footprint_position_file_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 26 2018) +// C++ code generated with wxFormBuilder (version 3.10.0-39-g3487c3cb) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -53,13 +53,14 @@ class DIALOG_GEN_FOOTPRINT_POSITION_BASE : public DIALOG_SHIM wxCheckBox* m_excludeTH; wxCheckBox* m_cbIncludeBoardEdge; wxCheckBox* m_useDrillPlaceOrigin; + wxCheckBox* m_negateXcb; WX_HTML_REPORT_PANEL* m_messagesPanel; wxStaticLine* m_staticline; wxStdDialogButtonSizer* m_sdbSizer; wxButton* m_sdbSizerOK; wxButton* m_sdbSizerCancel; - // Virtual event handlers, overide them in your derived class + // Virtual event handlers, override them in your derived class virtual void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) { event.Skip(); } virtual void onSelectFormat( wxCommandEvent& event ) { event.Skip(); } virtual void onUpdateUIUnits( wxUpdateUIEvent& event ) { event.Skip(); } @@ -67,12 +68,14 @@ class DIALOG_GEN_FOOTPRINT_POSITION_BASE : public DIALOG_SHIM virtual void onUpdateUIOnlySMD( wxUpdateUIEvent& event ) { event.Skip(); } virtual void onUpdateUIExcludeTH( wxUpdateUIEvent& event ) { event.Skip(); } virtual void onUpdateUIincludeBoardEdge( wxUpdateUIEvent& event ) { event.Skip(); } + virtual void onUpdateUInegXcoord( wxUpdateUIEvent& event ) { event.Skip(); } virtual void OnGenerate( wxCommandEvent& event ) { event.Skip(); } public: DIALOG_GEN_FOOTPRINT_POSITION_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Generate Placement Files"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~DIALOG_GEN_FOOTPRINT_POSITION_BASE(); }; diff --git a/pcbnew/exporters/export_footprints_placefile.cpp b/pcbnew/exporters/export_footprints_placefile.cpp index 34e4c0fd24..e3fc82fde1 100644 --- a/pcbnew/exporters/export_footprints_placefile.cpp +++ b/pcbnew/exporters/export_footprints_placefile.cpp @@ -75,13 +75,14 @@ enum SELECT_SIDE PLACE_FILE_EXPORTER::PLACE_FILE_EXPORTER( BOARD* aBoard, bool aUnitsMM, bool aOnlySMD, bool aExcludeAllTH, bool aTopSide, bool aBottomSide, - bool aFormatCSV, bool aUseAuxOrigin ) + bool aFormatCSV, bool aUseAuxOrigin, bool aNegateBottomX ) { - m_board = aBoard; - m_unitsMM = aUnitsMM; - m_onlySMD = aOnlySMD; - m_excludeAllTH = aExcludeAllTH; - m_fpCount = 0; + m_board = aBoard; + m_unitsMM = aUnitsMM; + m_onlySMD = aOnlySMD; + m_excludeAllTH = aExcludeAllTH; + m_fpCount = 0; + m_negateBottomX = aNegateBottomX; if( aTopSide && aBottomSide ) m_side = PCB_BOTH_SIDES; @@ -180,7 +181,7 @@ std::string PLACE_FILE_EXPORTER::GenPositionData() int layer = list[ii].m_Footprint->GetLayer(); wxASSERT( layer == F_Cu || layer == B_Cu ); - if( layer == B_Cu ) + if( layer == B_Cu && m_negateBottomX ) footprint_pos.x = - footprint_pos.x; wxString tmp = wxT( "\"" ) + list[ii].m_Reference; @@ -248,7 +249,7 @@ std::string PLACE_FILE_EXPORTER::GenPositionData() int layer = list[ii].m_Footprint->GetLayer(); wxASSERT( layer == F_Cu || layer == B_Cu ); - if( layer == B_Cu ) + if( layer == B_Cu && m_negateBottomX ) footprint_pos.x = - footprint_pos.x; wxString ref = list[ii].m_Reference; diff --git a/pcbnew/exporters/export_footprints_placefile.h b/pcbnew/exporters/export_footprints_placefile.h index 4bcd3b7595..41b9e29761 100644 --- a/pcbnew/exporters/export_footprints_placefile.h +++ b/pcbnew/exporters/export_footprints_placefile.h @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2015-2019 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2022 KiCad Developers, see AUTHORS.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 @@ -61,10 +61,12 @@ public: * @param aTopSide true to generate top side info * @param aBottomSide true to generate bottom side info * @param aFormatCSV true to generate a csv format info, false to generate a ascii info + * @param aNegateBottomX true to negate X coordinates for bottom side of the placement file * @param aUseAuxOrigin true to use auxiliary axis as an origin for the position data */ PLACE_FILE_EXPORTER( BOARD* aBoard, bool aUnitsMM, bool aOnlySMD, bool aExcludeAllTH, - bool aTopSide, bool aBottomSide, bool aFormatCSV, bool aUseAuxOrigin ); + bool aTopSide, bool aBottomSide, bool aFormatCSV, bool aUseAuxOrigin, + bool aNegateBottomX ); /** * build a string filled with the position data @@ -91,13 +93,14 @@ public: private: BOARD* m_board; - bool m_unitsMM; // true for mm, false for inches - bool m_onlySMD; // Include only SMD components - bool m_excludeAllTH; // Exclude any footprints with through-hole pads - int m_side; // PCB_BACK_SIDE, PCB_FRONT_SIDE, PCB_BOTH_SIDES - bool m_formatCSV; // true for csv format, false for ascii (utf8) format - int m_fpCount; // Number of footprints in list, for info - VECTOR2I m_place_Offset; // Offset for coordinates in generated data. + bool m_unitsMM; // true for mm, false for inches + bool m_onlySMD; // Include only SMD components + bool m_excludeAllTH; // Exclude any footprints with through-hole pads + int m_side; // PCB_BACK_SIDE, PCB_FRONT_SIDE, PCB_BOTH_SIDES + bool m_formatCSV; // true for csv format, false for ascii (utf8) format + bool m_negateBottomX; // true to negate X coordinate on bottom side + int m_fpCount; // Number of footprints in list, for info + VECTOR2I m_place_Offset; // Offset for coordinates in generated data. }; #endif // #ifndef EXPORT_FOOTPRINTS_PLACEFILE_H diff --git a/pcbnew/exporters/gen_footprints_placefile.cpp b/pcbnew/exporters/gen_footprints_placefile.cpp index 41818b9021..5f4dba541c 100644 --- a/pcbnew/exporters/gen_footprints_placefile.cpp +++ b/pcbnew/exporters/gen_footprints_placefile.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2015-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2022 KiCad Developers, see AUTHORS.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 @@ -97,6 +97,19 @@ private: } } + void onUpdateUInegXcoord( wxUpdateUIEvent& event ) override + { + if( m_rbFormat->GetSelection() == 2 ) + { + m_negateXcb->SetValue( false ); + m_negateXcb->Enable( false ); + } + else + { + m_negateXcb->Enable( true ); + } + } + void onUpdateUIExcludeTH( wxUpdateUIEvent& event ) override { if( m_rbFormat->GetSelection() == 2 ) @@ -156,6 +169,7 @@ private: static bool m_includeBoardEdge; static bool m_excludeTHOpt; static bool m_onlySMDOpt; + static bool m_negateBottomX; }; @@ -165,6 +179,7 @@ int DIALOG_GEN_FOOTPRINT_POSITION::m_fileFormat = 0; bool DIALOG_GEN_FOOTPRINT_POSITION::m_includeBoardEdge = false; bool DIALOG_GEN_FOOTPRINT_POSITION::m_excludeTHOpt = false; bool DIALOG_GEN_FOOTPRINT_POSITION::m_onlySMDOpt = false; +bool DIALOG_GEN_FOOTPRINT_POSITION::m_negateBottomX = false; void DIALOG_GEN_FOOTPRINT_POSITION::initDialog() @@ -177,6 +192,7 @@ void DIALOG_GEN_FOOTPRINT_POSITION::initDialog() m_fileOpt = cfg->m_PlaceFile.file_options; m_fileFormat = cfg->m_PlaceFile.file_format; m_includeBoardEdge = cfg->m_PlaceFile.include_board_edge; + m_negateBottomX = cfg->m_PlaceFile.negate_xcoord; // Output directory m_outputDirectoryName->SetValue( m_plotOpts.GetOutputDirectory() ); @@ -188,6 +204,7 @@ void DIALOG_GEN_FOOTPRINT_POSITION::initDialog() m_cbIncludeBoardEdge->SetValue( m_includeBoardEdge ); m_useDrillPlaceOrigin->SetValue( cfg->m_PlaceFile.use_aux_origin ); m_onlySMD->SetValue( m_onlySMDOpt ); + m_negateXcb->SetValue( m_negateBottomX ); m_excludeTH->SetValue( m_excludeTHOpt ); // Update sizes and sizers: @@ -232,6 +249,7 @@ void DIALOG_GEN_FOOTPRINT_POSITION::OnGenerate( wxCommandEvent& event ) m_fileFormat = m_rbFormat->GetSelection(); m_includeBoardEdge = m_cbIncludeBoardEdge->GetValue(); m_onlySMDOpt = m_onlySMD->GetValue(); + m_negateBottomX = m_negateXcb->GetValue(); m_excludeTHOpt = m_excludeTH->GetValue(); auto cfg = m_parent->GetPcbNewSettings(); @@ -242,6 +260,7 @@ void DIALOG_GEN_FOOTPRINT_POSITION::OnGenerate( wxCommandEvent& event ) cfg->m_PlaceFile.file_format = m_fileFormat; cfg->m_PlaceFile.include_board_edge = m_includeBoardEdge; cfg->m_PlaceFile.use_aux_origin = m_useDrillPlaceOrigin->GetValue(); + cfg->m_PlaceFile.negate_xcoord = m_negateBottomX; // Set output directory and replace backslashes with forward ones // (Keep unix convention in cfg files) @@ -360,11 +379,12 @@ bool DIALOG_GEN_FOOTPRINT_POSITION::CreateAsciiFiles() int fullcount = 0; int topSide = true; int bottomSide = true; + bool negateBottomX = m_negateXcb->GetValue(); // Test for any footprint candidate in list. { PLACE_FILE_EXPORTER exporter( brd, UnitsMM(), OnlySMD(), ExcludeAllTH(), topSide, - bottomSide, useCSVfmt, useAuxOrigin ); + bottomSide, useCSVfmt, useAuxOrigin, negateBottomX ); exporter.GenPositionData(); if( exporter.GetFootprintCount() == 0 ) @@ -430,7 +450,7 @@ bool DIALOG_GEN_FOOTPRINT_POSITION::CreateAsciiFiles() int fpcount = m_parent->DoGenFootprintsPositionFile( fn.GetFullPath(), UnitsMM(), OnlySMD(), ExcludeAllTH(), topSide, bottomSide, - useCSVfmt, useAuxOrigin ); + useCSVfmt, useAuxOrigin, negateBottomX ); if( fpcount < 0 ) { msg.Printf( _( "Failed to create file '%s'." ), fn.GetFullPath() ); @@ -475,7 +495,7 @@ bool DIALOG_GEN_FOOTPRINT_POSITION::CreateAsciiFiles() fpcount = m_parent->DoGenFootprintsPositionFile( fn.GetFullPath(), UnitsMM(), OnlySMD(), ExcludeAllTH(), topSide, bottomSide, useCSVfmt, - useAuxOrigin ); + useAuxOrigin, negateBottomX ); if( fpcount < 0 ) { @@ -521,7 +541,7 @@ int BOARD_EDITOR_CONTROL::GeneratePosFile( const TOOL_EVENT& aEvent ) int PCB_EDIT_FRAME::DoGenFootprintsPositionFile( const wxString& aFullFileName, bool aUnitsMM, bool aOnlySMD, bool aNoTHItems, bool aTopSide, bool aBottomSide, bool aFormatCSV, - bool aUseAuxOrigin ) + bool aUseAuxOrigin, bool aNegateBottomX ) { FILE * file = nullptr; @@ -535,7 +555,7 @@ int PCB_EDIT_FRAME::DoGenFootprintsPositionFile( const wxString& aFullFileName, std::string data; PLACE_FILE_EXPORTER exporter( GetBoard(), aUnitsMM, aOnlySMD, aNoTHItems, aTopSide, aBottomSide, - aFormatCSV, aUseAuxOrigin ); + aFormatCSV, aUseAuxOrigin, aNegateBottomX ); data = exporter.GenPositionData(); // if aFullFileName is empty, the file is not created, only the @@ -595,7 +615,11 @@ bool PCB_EDIT_FRAME::DoGenFootprintsReport( const wxString& aFullFilename, bool return false; std::string data; - PLACE_FILE_EXPORTER exporter( GetBoard(), aUnitsMM, false, false, true, true, false, true ); + PLACE_FILE_EXPORTER exporter( GetBoard(), aUnitsMM, + false, false, // SMD aOnlySMD, aNoTHItems + true, true, // aTopSide, aBottomSide + false, true, false // aFormatCSV, aUseAuxOrigin, aNegateBottomX + ); data = exporter.GenReportData(); fputs( data.c_str(), rptfile ); diff --git a/pcbnew/pcb_edit_frame.h b/pcbnew/pcb_edit_frame.h index 8ff244c771..caaf7dd098 100644 --- a/pcbnew/pcb_edit_frame.h +++ b/pcbnew/pcb_edit_frame.h @@ -308,11 +308,12 @@ public: * \a aTopSide are true, list footprints on both sides. * @param aFormatCSV true to use a comma separated file (CSV) format; default = false * @param aUseAuxOrigin true to use auxiliary axis as an origin for the position data + * @param aNegateBottomX true to negate X coordinates for bottom side of the placement file * @return the number of footprints found on aSide side or -1 if the file could not be created. */ int DoGenFootprintsPositionFile( const wxString& aFullFileName, bool aUnitsMM, bool aOnlySMD, bool aNoTHItems, bool aTopSide, bool aBottomSide, - bool aFormatCSV, bool aUseAuxOrigin ); + bool aFormatCSV, bool aUseAuxOrigin, bool aNegateBottomX ); /** * Call #DoGenFootprintsReport to create a footprint report file diff --git a/pcbnew/pcbnew_settings.cpp b/pcbnew/pcbnew_settings.cpp index b11cbb75e8..f983622010 100644 --- a/pcbnew/pcbnew_settings.cpp +++ b/pcbnew/pcbnew_settings.cpp @@ -426,6 +426,9 @@ PCBNEW_SETTINGS::PCBNEW_SETTINGS() m_params.emplace_back( new PARAM( "place_file.use_place_file_origin", &m_PlaceFile.use_aux_origin, true ) ); + m_params.emplace_back( new PARAM( "place_file.negate_xcoord", + &m_PlaceFile.negate_xcoord, false ) ); + m_params.emplace_back( new PARAM( "plot.all_layers_on_one_page", &m_Plot.all_layers_on_one_page, 1 ) ); diff --git a/pcbnew/pcbnew_settings.h b/pcbnew/pcbnew_settings.h index 68c855ceb3..d580881f31 100644 --- a/pcbnew/pcbnew_settings.h +++ b/pcbnew/pcbnew_settings.h @@ -235,6 +235,7 @@ public: int file_format; bool include_board_edge; bool use_aux_origin; + bool negate_xcoord; }; struct DIALOG_PLOT