GenCAD exporter: settings dialog
This commit is contained in:
parent
a73fa0790c
commit
c3c5205393
|
@ -89,6 +89,7 @@ set( PCBNEW_DIALOGS
|
||||||
dialogs/dialog_fp_plugin_options.cpp
|
dialogs/dialog_fp_plugin_options.cpp
|
||||||
dialogs/dialog_freeroute_exchange.cpp
|
dialogs/dialog_freeroute_exchange.cpp
|
||||||
dialogs/dialog_freeroute_exchange_base.cpp
|
dialogs/dialog_freeroute_exchange_base.cpp
|
||||||
|
dialogs/dialog_gencad_export_options.cpp
|
||||||
dialogs/dialog_gendrill.cpp
|
dialogs/dialog_gendrill.cpp
|
||||||
dialogs/dialog_gendrill_base.cpp
|
dialogs/dialog_gendrill_base.cpp
|
||||||
dialogs/dialog_gen_module_position_file_base.cpp
|
dialogs/dialog_gen_module_position_file_base.cpp
|
||||||
|
|
|
@ -0,0 +1,154 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 CERN
|
||||||
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
*
|
||||||
|
* 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 "dialog_gencad_export_options.h"
|
||||||
|
|
||||||
|
#include <wxPcbStruct.h>
|
||||||
|
#include <class_board.h>
|
||||||
|
#include <project.h>
|
||||||
|
#include <confirm.h>
|
||||||
|
|
||||||
|
#include <wx/statline.h>
|
||||||
|
#include <wx/button.h>
|
||||||
|
|
||||||
|
DIALOG_GENCAD_EXPORT_OPTIONS::DIALOG_GENCAD_EXPORT_OPTIONS( PCB_EDIT_FRAME* aParent )
|
||||||
|
: DIALOG_SHIM( aParent, wxID_ANY, _( "Export to GenCAD settings" ) )
|
||||||
|
{
|
||||||
|
// Obtain a potential filename for the exported file
|
||||||
|
wxFileName fn = aParent->GetBoard()->GetFileName();
|
||||||
|
fn.SetExt( "cad" );
|
||||||
|
|
||||||
|
// Create widgets
|
||||||
|
SetSizeHints( wxSize( 500, 200 ), wxDefaultSize );
|
||||||
|
|
||||||
|
wxBoxSizer* m_mainSizer= new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
|
wxBoxSizer* m_fileSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||||
|
|
||||||
|
m_filePath = new wxTextCtrl( this, wxID_ANY, fn.GetFullPath() );
|
||||||
|
m_fileSizer->Add( m_filePath, 1, wxALL, 5 );
|
||||||
|
|
||||||
|
wxButton* m_browseBtn = new wxButton( this, wxID_ANY, _( "Browse" ) );
|
||||||
|
m_browseBtn->Connect( wxEVT_COMMAND_BUTTON_CLICKED,
|
||||||
|
wxCommandEventHandler( DIALOG_GENCAD_EXPORT_OPTIONS::onBrowse ), NULL, this );
|
||||||
|
m_fileSizer->Add( m_browseBtn, 0, wxALL, 5 );
|
||||||
|
|
||||||
|
m_mainSizer->Add( m_fileSizer, 0, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
m_optsSizer = new wxGridSizer( 0, 1, 0, 0 );
|
||||||
|
createOptCheckboxes();
|
||||||
|
m_mainSizer->Add( m_optsSizer, 1, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
wxSizer* stdButtons = CreateSeparatedButtonSizer( wxOK | wxCANCEL );
|
||||||
|
m_mainSizer->Add( stdButtons, 0, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
SetSizer( m_mainSizer );
|
||||||
|
Layout();
|
||||||
|
m_mainSizer->Fit( this );
|
||||||
|
|
||||||
|
Centre( wxBOTH );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DIALOG_GENCAD_EXPORT_OPTIONS::~DIALOG_GENCAD_EXPORT_OPTIONS()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DIALOG_GENCAD_EXPORT_OPTIONS::GetOption( GENCAD_EXPORT_OPT aOption ) const
|
||||||
|
{
|
||||||
|
auto it = m_options.find( aOption );
|
||||||
|
|
||||||
|
if( it == m_options.end() )
|
||||||
|
{
|
||||||
|
wxASSERT_MSG( false, "Missing checkbox for an option" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return it->second->IsChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::map<GENCAD_EXPORT_OPT, bool> DIALOG_GENCAD_EXPORT_OPTIONS::GetAllOptions() const
|
||||||
|
{
|
||||||
|
std::map<GENCAD_EXPORT_OPT, bool> retVal;
|
||||||
|
|
||||||
|
for( const auto& option : m_options )
|
||||||
|
retVal[option.first] = option.second->IsChecked();
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxString DIALOG_GENCAD_EXPORT_OPTIONS::GetFileName() const
|
||||||
|
{
|
||||||
|
return m_filePath->GetValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DIALOG_GENCAD_EXPORT_OPTIONS::TransferDataFromWindow()
|
||||||
|
{
|
||||||
|
if( !wxDialog::TransferDataFromWindow() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wxString fn = GetFileName();
|
||||||
|
|
||||||
|
if( wxFile::Exists( fn ) )
|
||||||
|
return IsOK( this, wxString::Format( _( "File %s already exists. Overwrite?" ), fn ) );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_GENCAD_EXPORT_OPTIONS::createOptCheckboxes()
|
||||||
|
{
|
||||||
|
std::map<GENCAD_EXPORT_OPT, wxString> opts =
|
||||||
|
{
|
||||||
|
{ FLIP_BOTTOM_LAYERS, _( "Flip layer stack for bottom components" ) }
|
||||||
|
};
|
||||||
|
|
||||||
|
for( const auto& option : opts )
|
||||||
|
{
|
||||||
|
wxCheckBox* chkbox = new wxCheckBox( this, wxID_ANY, option.second );
|
||||||
|
m_options[option.first] = chkbox;
|
||||||
|
m_optsSizer->Add( chkbox, 0, wxALL, 5 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_GENCAD_EXPORT_OPTIONS::onBrowse( wxCommandEvent& aEvent )
|
||||||
|
{
|
||||||
|
wxFileDialog dlg( this, _( "Save GenCAD Board File" ),
|
||||||
|
wxPathOnly( Prj().GetProjectFullName() ),
|
||||||
|
m_filePath->GetValue(),
|
||||||
|
_( "GenCAD 1.4 board files (.cad)|*.cad" ),
|
||||||
|
wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
|
||||||
|
|
||||||
|
if( dlg.ShowModal() == wxID_CANCEL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_filePath->SetValue( dlg.GetPath() );
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 CERN
|
||||||
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DIALOG_GENCAD_EXPORT_OPTIONS_H__
|
||||||
|
#define __DIALOG_GENCAD_EXPORT_OPTIONS_H__
|
||||||
|
|
||||||
|
#include <dialog_shim.h>
|
||||||
|
|
||||||
|
class PCB_EDIT_FRAME;
|
||||||
|
class wxTextCtrl;
|
||||||
|
|
||||||
|
///> Settings for GenCAD exporter
|
||||||
|
enum GENCAD_EXPORT_OPT
|
||||||
|
{
|
||||||
|
FLIP_BOTTOM_LAYERS // invert layer stack for bottom components
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class DIALOG_GENCAD_EXPORT_OPTIONS : public DIALOG_SHIM
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DIALOG_GENCAD_EXPORT_OPTIONS( PCB_EDIT_FRAME* aParent );
|
||||||
|
~DIALOG_GENCAD_EXPORT_OPTIONS();
|
||||||
|
|
||||||
|
///> Checks whether an option has been selected
|
||||||
|
bool GetOption( GENCAD_EXPORT_OPT aOption ) const;
|
||||||
|
|
||||||
|
///> Returns all export settings
|
||||||
|
std::map<GENCAD_EXPORT_OPT, bool> GetAllOptions() const;
|
||||||
|
|
||||||
|
///> Returns the selected file path
|
||||||
|
wxString GetFileName() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool TransferDataFromWindow() override;
|
||||||
|
|
||||||
|
///> Creates checkboxes for GenCAD export options
|
||||||
|
void createOptCheckboxes();
|
||||||
|
|
||||||
|
///> Browse output file event handler
|
||||||
|
void onBrowse( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
|
std::map<GENCAD_EXPORT_OPT, wxCheckBox*> m_options;
|
||||||
|
|
||||||
|
// Widgets
|
||||||
|
wxGridSizer* m_optsSizer;
|
||||||
|
wxTextCtrl* m_filePath;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //__DIALOG_GENCAD_EXPORT_OPTIONS_H__
|
|
@ -40,6 +40,7 @@
|
||||||
#include <macros.h>
|
#include <macros.h>
|
||||||
|
|
||||||
#include <pcbnew.h>
|
#include <pcbnew.h>
|
||||||
|
#include <dialogs/dialog_gencad_export_options.h>
|
||||||
|
|
||||||
#include <class_board.h>
|
#include <class_board.h>
|
||||||
#include <class_module.h>
|
#include <class_module.h>
|
||||||
|
@ -223,6 +224,8 @@ static int GencadOffsetX, GencadOffsetY;
|
||||||
// GerbTool chokes on units different than INCH so this is the conversion factor
|
// GerbTool chokes on units different than INCH so this is the conversion factor
|
||||||
const static double SCALE_FACTOR = 1000.0 * IU_PER_MILS;
|
const static double SCALE_FACTOR = 1000.0 * IU_PER_MILS;
|
||||||
|
|
||||||
|
// Export options
|
||||||
|
bool flipBottomLayers;
|
||||||
|
|
||||||
/* Two helper functions to calculate coordinates of modules in gencad values
|
/* Two helper functions to calculate coordinates of modules in gencad values
|
||||||
* (GenCAD Y axis from bottom to top)
|
* (GenCAD Y axis from bottom to top)
|
||||||
|
@ -242,31 +245,23 @@ static double MapYTo( int aY )
|
||||||
/* Driver function: processing starts here */
|
/* Driver function: processing starts here */
|
||||||
void PCB_EDIT_FRAME::ExportToGenCAD( wxCommandEvent& aEvent )
|
void PCB_EDIT_FRAME::ExportToGenCAD( wxCommandEvent& aEvent )
|
||||||
{
|
{
|
||||||
wxFileName fn = GetBoard()->GetFileName();
|
DIALOG_GENCAD_EXPORT_OPTIONS optionsDialog( this );
|
||||||
FILE* file;
|
|
||||||
|
|
||||||
wxString ext = wxT( "cad" );
|
if( optionsDialog.ShowModal() == wxID_CANCEL )
|
||||||
wxString wildcard = _( "GenCAD 1.4 board files (.cad)|*.cad" );
|
|
||||||
|
|
||||||
fn.SetExt( ext );
|
|
||||||
|
|
||||||
wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() );
|
|
||||||
|
|
||||||
wxFileDialog dlg( this, _( "Save GenCAD Board File" ), pro_dir,
|
|
||||||
fn.GetFullName(), wildcard,
|
|
||||||
wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
|
|
||||||
|
|
||||||
if( dlg.ShowModal() == wxID_CANCEL )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( ( file = wxFopen( dlg.GetPath(), wxT( "wt" ) ) ) == NULL )
|
FILE* file = wxFopen( optionsDialog.GetFileName(), "wt" );
|
||||||
{
|
|
||||||
wxString msg;
|
|
||||||
|
|
||||||
msg.Printf( _( "Unable to create <%s>" ), GetChars( dlg.GetPath() ) );
|
if( !file )
|
||||||
DisplayError( this, msg ); return;
|
{
|
||||||
|
DisplayError( this, wxString::Format( _( "Unable to create <%s>" ),
|
||||||
|
GetChars( optionsDialog.GetFileName() ) ) );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get options
|
||||||
|
flipBottomLayers = optionsDialog.GetOption( FLIP_BOTTOM_LAYERS );
|
||||||
|
|
||||||
// Switch the locale to standard C (needed to print floating point numbers)
|
// Switch the locale to standard C (needed to print floating point numbers)
|
||||||
LOCALE_IO toggle;
|
LOCALE_IO toggle;
|
||||||
|
|
||||||
|
@ -606,14 +601,17 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flipped padstack
|
// Flipped padstack
|
||||||
fprintf( aFile, "PADSTACK PAD%uF %g\n", i, pad->GetDrillSize().x / SCALE_FACTOR );
|
if( flipBottomLayers )
|
||||||
|
|
||||||
// the normal PCB_LAYER_ID sequence is inverted from gc_seq[]
|
|
||||||
for( LSEQ seq = pad_set.Seq(); seq; ++seq )
|
|
||||||
{
|
{
|
||||||
PCB_LAYER_ID layer = *seq;
|
fprintf( aFile, "PADSTACK PAD%uF %g\n", i, pad->GetDrillSize().x / SCALE_FACTOR );
|
||||||
|
|
||||||
fprintf( aFile, "PAD P%u %s 0 0\n", i, GenCADLayerNameFlipped( cu_count, layer ).c_str() );
|
// the normal PCB_LAYER_ID sequence is inverted from gc_seq[]
|
||||||
|
for( LSEQ seq = pad_set.Seq(); seq; ++seq )
|
||||||
|
{
|
||||||
|
PCB_LAYER_ID layer = *seq;
|
||||||
|
|
||||||
|
fprintf( aFile, "PAD P%u %s 0 0\n", i, GenCADLayerNameFlipped( cu_count, layer ).c_str() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,11 +650,11 @@ static void CreateShapesSection( FILE* aFile, BOARD* aPcb )
|
||||||
|
|
||||||
if( ( pad->GetLayerSet() & all_cu ) == LSET( B_Cu ) )
|
if( ( pad->GetLayerSet() & all_cu ) == LSET( B_Cu ) )
|
||||||
{
|
{
|
||||||
layer = module->GetLayer() == B_Cu ? "TOP" : "BOTTOM";
|
layer = flipBottomLayers && module->GetLayer() == B_Cu ? "TOP" : "BOTTOM";
|
||||||
}
|
}
|
||||||
else if( ( pad->GetLayerSet() & all_cu ) == LSET( F_Cu ) )
|
else if( ( pad->GetLayerSet() & all_cu ) == LSET( F_Cu ) )
|
||||||
{
|
{
|
||||||
layer = module->GetLayer() == B_Cu ? "BOTTOM" : "TOP";
|
layer = flipBottomLayers && module->GetLayer() == B_Cu ? "BOTTOM" : "TOP";
|
||||||
}
|
}
|
||||||
|
|
||||||
pinname = pad->GetName();
|
pinname = pad->GetName();
|
||||||
|
@ -668,7 +666,7 @@ static void CreateShapesSection( FILE* aFile, BOARD* aPcb )
|
||||||
NORMALIZE_ANGLE_POS( orient );
|
NORMALIZE_ANGLE_POS( orient );
|
||||||
|
|
||||||
// Bottom side modules use the flipped padstack
|
// Bottom side modules use the flipped padstack
|
||||||
fprintf( aFile, (module->GetLayer() == B_Cu) ?
|
fprintf( aFile, ( flipBottomLayers && module->GetLayer() == B_Cu ) ?
|
||||||
"PIN %s PAD%dF %g %g %s %g %s\n" :
|
"PIN %s PAD%dF %g %g %s %g %s\n" :
|
||||||
"PIN %s PAD%d %g %g %s %g %s\n",
|
"PIN %s PAD%d %g %g %s %g %s\n",
|
||||||
TO_UTF8( pinname ), pad->GetSubRatsnest(),
|
TO_UTF8( pinname ), pad->GetSubRatsnest(),
|
||||||
|
@ -733,7 +731,8 @@ static void CreateComponentsSection( FILE* aFile, BOARD* aPcb )
|
||||||
for( int ii = 0; ii < 2; ii++ )
|
for( int ii = 0; ii < 2; ii++ )
|
||||||
{
|
{
|
||||||
double txt_orient = textmod->GetTextAngle();
|
double txt_orient = textmod->GetTextAngle();
|
||||||
std::string layer = GenCADLayerName( cu_count, module->GetLayer() == B_Cu ? B_SilkS : F_SilkS );
|
std::string layer = GenCADLayerName( cu_count,
|
||||||
|
flipBottomLayers && module->GetLayer() == B_Cu ? B_SilkS : F_SilkS );
|
||||||
|
|
||||||
fprintf( aFile, "TEXT %g %g %g %g %s %s \"%s\"",
|
fprintf( aFile, "TEXT %g %g %g %g %s %s \"%s\"",
|
||||||
textmod->GetPos0().x / SCALE_FACTOR,
|
textmod->GetPos0().x / SCALE_FACTOR,
|
||||||
|
|
Loading…
Reference in New Issue