Step exporter fixes and enhancements:
- fix duplicate code and a few bugs (some are due to changes in code over the years) - ADDED: option to export tracks and vias on external layers Exporting tracks is *very* time consuming, and need a bit of optimization.
This commit is contained in:
parent
67ec09c850
commit
f569cffa8e
|
@ -39,7 +39,9 @@ public:
|
|||
m_outputFile(),
|
||||
m_xOrigin( 0.0 ),
|
||||
m_yOrigin( 0.0 ),
|
||||
m_minDistance( 0.01 ) // 0.01 mm is a good value to connect 2 items of the board outlines
|
||||
// max dist to chain 2 items (lines or curves) to build the board outlines
|
||||
m_BoardOutlinesChainingEpsilon( 0.01 ), // 0.01 mm is a good value
|
||||
m_exportTracks( false ) // Extremely time consuming if true
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -53,7 +55,8 @@ public:
|
|||
wxString m_outputFile;
|
||||
double m_xOrigin;
|
||||
double m_yOrigin;
|
||||
double m_minDistance;
|
||||
double m_BoardOutlinesChainingEpsilon;
|
||||
bool m_exportTracks;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -37,6 +37,7 @@
|
|||
#define ARG_MIN_DISTANCE "--min-distance"
|
||||
#define ARG_USER_ORIGIN "--user-origin"
|
||||
#define ARG_BOARD_ONLY "--board-only"
|
||||
#define ARG_EXPORT_TRACKS "--export-tracks"
|
||||
|
||||
#define REGEX_QUANTITY "([\\s]*[+-]?[\\d]*[.]?[\\d]*)"
|
||||
#define REGEX_DELIMITER "(?:[\\s]*x)"
|
||||
|
@ -74,6 +75,11 @@ CLI::EXPORT_PCB_STEP_COMMAND::EXPORT_PCB_STEP_COMMAND() : COMMAND( "step" )
|
|||
.implicit_value( true )
|
||||
.default_value( false );
|
||||
|
||||
m_argParser.add_argument( ARG_EXPORT_TRACKS )
|
||||
.help( UTF8STDSTR( _( "Export tracks (extremely time consuming)" ) ) )
|
||||
.implicit_value( true )
|
||||
.default_value( false );
|
||||
|
||||
m_argParser.add_argument( ARG_MIN_DISTANCE )
|
||||
.default_value( std::string( "0.01mm" ) )
|
||||
.help( UTF8STDSTR( _( "Minimum distance between points to treat them as separate ones" ) ) );
|
||||
|
@ -101,6 +107,7 @@ int CLI::EXPORT_PCB_STEP_COMMAND::doPerform( KIWAY& aKiway )
|
|||
step->m_filename = FROM_UTF8( m_argParser.get<std::string>( ARG_INPUT ).c_str() );
|
||||
step->m_outputFile = FROM_UTF8( m_argParser.get<std::string>( ARG_OUTPUT ).c_str() );
|
||||
step->m_boardOnly = m_argParser.get<bool>( ARG_BOARD_ONLY );
|
||||
step->m_exportTracks = m_argParser.get<bool>( ARG_EXPORT_TRACKS );
|
||||
|
||||
wxString userOrigin = FROM_UTF8( m_argParser.get<std::string>( ARG_USER_ORIGIN ).c_str() );
|
||||
|
||||
|
@ -142,6 +149,7 @@ int CLI::EXPORT_PCB_STEP_COMMAND::doPerform( KIWAY& aKiway )
|
|||
}
|
||||
|
||||
wxString minDistance = FROM_UTF8( m_argParser.get<std::string>( ARG_MIN_DISTANCE ).c_str() );
|
||||
|
||||
if( !minDistance.IsEmpty() )
|
||||
{
|
||||
std::regex re_pattern( REGEX_QUANTITY REGEX_UNIT,
|
||||
|
@ -149,7 +157,7 @@ int CLI::EXPORT_PCB_STEP_COMMAND::doPerform( KIWAY& aKiway )
|
|||
std::smatch sm;
|
||||
std::string str( minDistance.ToUTF8() );
|
||||
std::regex_search( str, sm, re_pattern );
|
||||
step->m_minDistance = atof( sm.str( 1 ).c_str() );
|
||||
step->m_BoardOutlinesChainingEpsilon = atof( sm.str( 1 ).c_str() );
|
||||
|
||||
std::string tunit( sm[2] );
|
||||
|
||||
|
@ -157,7 +165,7 @@ int CLI::EXPORT_PCB_STEP_COMMAND::doPerform( KIWAY& aKiway )
|
|||
{
|
||||
if( !tunit.compare( "in" ) || !tunit.compare( "inch" ) )
|
||||
{
|
||||
step->m_minDistance *= 25.4;
|
||||
step->m_BoardOutlinesChainingEpsilon *= 25.4;
|
||||
}
|
||||
else if( tunit.compare( "mm" ) )
|
||||
{
|
||||
|
|
|
@ -107,13 +107,15 @@ private:
|
|||
double m_userOriginY; // remember last User Origin Y value
|
||||
int m_originUnits; // remember last units for User Origin
|
||||
bool m_noVirtual; // remember last preference for No Virtual Component
|
||||
static bool m_exportTracks; // remember last preference to export tracks
|
||||
// (stored only for the session)
|
||||
wxString m_boardPath; // path to the exported board file
|
||||
static int m_toleranceLastChoice; // Store m_tolerance option during a session
|
||||
};
|
||||
|
||||
|
||||
int DIALOG_EXPORT_STEP::m_toleranceLastChoice = -1; // Use default
|
||||
|
||||
bool DIALOG_EXPORT_STEP::m_exportTracks = false;
|
||||
|
||||
DIALOG_EXPORT_STEP::DIALOG_EXPORT_STEP( PCB_EDIT_FRAME* aParent, const wxString& aBoardPath ) :
|
||||
DIALOG_EXPORT_STEP_BASE( aParent )
|
||||
|
@ -172,6 +174,7 @@ DIALOG_EXPORT_STEP::DIALOG_EXPORT_STEP( PCB_EDIT_FRAME* aParent, const wxString&
|
|||
m_userOriginY = cfg->m_ExportStep.origin_y;
|
||||
m_noVirtual = cfg->m_ExportStep.no_virtual;
|
||||
|
||||
m_cbExportTracks->SetValue( m_exportTracks );
|
||||
m_cbRemoveVirtual->SetValue( m_noVirtual );
|
||||
m_cbSubstModels->SetValue( cfg->m_ExportStep.replace_models );
|
||||
m_cbOverwriteFile->SetValue( cfg->m_ExportStep.overwrite_file );
|
||||
|
@ -224,7 +227,7 @@ DIALOG_EXPORT_STEP::DIALOG_EXPORT_STEP( PCB_EDIT_FRAME* aParent, const wxString&
|
|||
}
|
||||
|
||||
if( m_toleranceLastChoice >= 0 )
|
||||
m_tolerance->SetSelection( m_toleranceLastChoice );
|
||||
m_choiceTolerance->SetSelection( m_toleranceLastChoice );
|
||||
|
||||
// Now all widgets have the size fixed, call FinishDialogSettings
|
||||
finishDialogSettings();
|
||||
|
@ -252,7 +255,8 @@ DIALOG_EXPORT_STEP::~DIALOG_EXPORT_STEP()
|
|||
|
||||
cfg->m_ExportStep.no_virtual = m_cbRemoveVirtual->GetValue();
|
||||
|
||||
m_toleranceLastChoice = m_tolerance->GetSelection();
|
||||
m_toleranceLastChoice = m_choiceTolerance->GetSelection();
|
||||
m_exportTracks = m_cbExportTracks->GetValue();
|
||||
}
|
||||
|
||||
|
||||
|
@ -318,9 +322,10 @@ void DIALOG_EXPORT_STEP::onExportButton( wxCommandEvent& aEvent )
|
|||
m_parent->SetLastPath( LAST_PATH_STEP, m_filePickerSTEP->GetPath() );
|
||||
|
||||
double tolerance; // default value in mm
|
||||
m_toleranceLastChoice = m_tolerance->GetSelection();
|
||||
m_toleranceLastChoice = m_choiceTolerance->GetSelection();
|
||||
m_exportTracks = m_cbExportTracks->GetValue();
|
||||
|
||||
switch( m_tolerance->GetSelection() )
|
||||
switch( m_choiceTolerance->GetSelection() )
|
||||
{
|
||||
case 0: tolerance = 0.001; break;
|
||||
default:
|
||||
|
@ -394,6 +399,9 @@ void DIALOG_EXPORT_STEP::onExportButton( wxCommandEvent& aEvent )
|
|||
if( GetSubstOption() )
|
||||
cmdK2S.Append( wxT( " --subst-models" ) );
|
||||
|
||||
if( m_exportTracks )
|
||||
cmdK2S.Append( wxT( " --export-tracks" ) );
|
||||
|
||||
// Note: for some reason, using \" to insert a quote in a format string, under MacOS
|
||||
// wxString::Format does not work. So use a %c format in string
|
||||
int quote = '\'';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-282-g1fa54006)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -120,17 +120,22 @@ DIALOG_EXPORT_STEP_BASE::DIALOG_EXPORT_STEP_BASE( wxWindow* parent, wxWindowID i
|
|||
m_cbOverwriteFile = new wxCheckBox( sbOtherOptions->GetStaticBox(), wxID_ANY, _("Overwrite old file"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
sbOtherOptions->Add( m_cbOverwriteFile, 0, wxBOTTOM|wxRIGHT, 5 );
|
||||
|
||||
m_cbExportTracks = new wxCheckBox( sbOtherOptions->GetStaticBox(), wxID_ANY, _("Export tracks (time consuming)"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_cbExportTracks->SetToolTip( _("Export tracks and vias on external copper layers.\nWarning: this is *extremely* time consuming.") );
|
||||
|
||||
sbOtherOptions->Add( m_cbExportTracks, 0, wxTOP|wxBOTTOM|wxRIGHT, 5 );
|
||||
|
||||
m_staticTextTolerance = new wxStaticText( sbOtherOptions->GetStaticBox(), wxID_ANY, _("Board outline chaining tolerance:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticTextTolerance->Wrap( -1 );
|
||||
sbOtherOptions->Add( m_staticTextTolerance, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
|
||||
|
||||
wxString m_toleranceChoices[] = { _("Tight (0.001 mm)"), _("Standard (0.01 mm)"), _("Loose (0.1 mm)") };
|
||||
int m_toleranceNChoices = sizeof( m_toleranceChoices ) / sizeof( wxString );
|
||||
m_tolerance = new wxChoice( sbOtherOptions->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_toleranceNChoices, m_toleranceChoices, 0 );
|
||||
m_tolerance->SetSelection( 1 );
|
||||
m_tolerance->SetToolTip( _("Tolerance sets the distance between two points that are considered joined.") );
|
||||
wxString m_choiceToleranceChoices[] = { _("Tight (0.001 mm)"), _("Standard (0.01 mm)"), _("Loose (0.1 mm)") };
|
||||
int m_choiceToleranceNChoices = sizeof( m_choiceToleranceChoices ) / sizeof( wxString );
|
||||
m_choiceTolerance = new wxChoice( sbOtherOptions->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceToleranceNChoices, m_choiceToleranceChoices, 0 );
|
||||
m_choiceTolerance->SetSelection( 1 );
|
||||
m_choiceTolerance->SetToolTip( _("Tolerance sets the distance between two points that are considered joined when building the board outlines.") );
|
||||
|
||||
sbOtherOptions->Add( m_tolerance, 0, wxALL|wxEXPAND, 5 );
|
||||
sbOtherOptions->Add( m_choiceTolerance, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
bSizer2->Add( sbOtherOptions, 1, wxEXPAND|wxRIGHT|wxLEFT, 10 );
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
<property name="center">wxBOTH</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="event_handler">impl_virtual</property>
|
||||
<property name="extra_style"></property>
|
||||
|
@ -95,6 +96,7 @@
|
|||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
@ -156,6 +158,7 @@
|
|||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
@ -244,6 +247,7 @@
|
|||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
@ -308,6 +312,7 @@
|
|||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
@ -372,6 +377,7 @@
|
|||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
@ -436,6 +442,7 @@
|
|||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
@ -530,6 +537,7 @@
|
|||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
@ -592,6 +600,7 @@
|
|||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
@ -656,6 +665,7 @@
|
|||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
@ -717,6 +727,7 @@
|
|||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
@ -782,6 +793,7 @@
|
|||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
@ -843,6 +855,7 @@
|
|||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
@ -925,6 +938,7 @@
|
|||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
@ -989,6 +1003,7 @@
|
|||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
@ -1053,6 +1068,7 @@
|
|||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
@ -1091,6 +1107,71 @@
|
|||
<property name="window_style"></property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxTOP|wxBOTTOM|wxRIGHT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxCheckBox" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="checked">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Export tracks (time consuming)</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_cbExportTracks</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip">Export tracks and vias on external copper layers.
Warning: this is *extremely* time consuming.</property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
|
||||
|
@ -1116,6 +1197,7 @@
|
|||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
@ -1178,6 +1260,7 @@
|
|||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
|
@ -1192,7 +1275,7 @@
|
|||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_tolerance</property>
|
||||
<property name="name">m_choiceTolerance</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
|
@ -1206,7 +1289,7 @@
|
|||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip">Tolerance sets the distance between two points that are considered joined.</property>
|
||||
<property name="tooltip">Tolerance sets the distance between two points that are considered joined when building the board outlines.</property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-282-g1fa54006)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -57,8 +57,9 @@ class DIALOG_EXPORT_STEP_BASE : public DIALOG_SHIM
|
|||
wxCheckBox* m_cbRemoveVirtual;
|
||||
wxCheckBox* m_cbSubstModels;
|
||||
wxCheckBox* m_cbOverwriteFile;
|
||||
wxCheckBox* m_cbExportTracks;
|
||||
wxStaticText* m_staticTextTolerance;
|
||||
wxChoice* m_tolerance;
|
||||
wxChoice* m_choiceTolerance;
|
||||
wxStdDialogButtonSizer* m_sdbSizer;
|
||||
wxButton* m_sdbSizerOK;
|
||||
wxButton* m_sdbSizerCancel;
|
||||
|
|
|
@ -27,7 +27,10 @@
|
|||
#include <board.h>
|
||||
#include <board_design_settings.h>
|
||||
#include <footprint.h>
|
||||
#include <pcb_track.h>
|
||||
#include <pad.h>
|
||||
#include <fp_lib_table.h>
|
||||
#include "step_pcb_model.h"
|
||||
|
||||
#include <pgm_base.h>
|
||||
#include <base_units.h>
|
||||
|
@ -48,7 +51,6 @@
|
|||
#include <Message_Messenger.hxx>
|
||||
#endif
|
||||
|
||||
#define DEFAULT_BOARD_THICKNESS 1.6
|
||||
|
||||
void ReportMessage( const wxString& aMessage )
|
||||
{
|
||||
|
@ -116,8 +118,7 @@ EXPORTER_STEP::EXPORTER_STEP( BOARD* aBoard, const EXPORTER_STEP_PARAMS& aParams
|
|||
m_board( aBoard ),
|
||||
m_pcbModel( nullptr ),
|
||||
m_pcbName(),
|
||||
m_minDistance( STEPEXPORT_MIN_DISTANCE ),
|
||||
m_boardThickness( DEFAULT_BOARD_THICKNESS )
|
||||
m_boardThickness( DEFAULT_BOARD_THICKNESS_MM )
|
||||
{
|
||||
m_solderMaskColor = COLOR4D( 0.08, 0.20, 0.14, 0.83 );
|
||||
|
||||
|
@ -143,6 +144,12 @@ bool EXPORTER_STEP::composePCB( FOOTPRINT* aFootprint, VECTOR2D aOrigin )
|
|||
{
|
||||
if( m_pcbModel->AddPadHole( pad, aOrigin ) )
|
||||
hasdata = true;
|
||||
|
||||
if( ExportTracksAndVias() )
|
||||
{
|
||||
if( m_pcbModel->AddPadShape( pad, aOrigin ) )
|
||||
hasdata = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( ( aFootprint->GetAttributes() & FP_EXCLUDE_FROM_BOM ) && !m_params.m_includeExcludedBom )
|
||||
|
@ -234,6 +241,41 @@ bool EXPORTER_STEP::composePCB( FOOTPRINT* aFootprint, VECTOR2D aOrigin )
|
|||
}
|
||||
|
||||
|
||||
bool EXPORTER_STEP::composePCB( PCB_TRACK* aTrack, VECTOR2D aOrigin )
|
||||
{
|
||||
if( aTrack->Type() == PCB_VIA_T )
|
||||
{
|
||||
PAD dummy( nullptr );
|
||||
int hole = static_cast<PCB_VIA*>( aTrack )->GetDrillValue();
|
||||
dummy.SetDrillSize( VECTOR2I( hole, hole ) );
|
||||
dummy.SetPosition( aTrack->GetStart() );
|
||||
dummy.SetSize( VECTOR2I( aTrack->GetWidth(), aTrack->GetWidth() ) );
|
||||
|
||||
if( m_pcbModel->AddPadHole( &dummy, aOrigin ) )
|
||||
{
|
||||
if( m_pcbModel->AddPadShape( &dummy, aOrigin ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PCB_LAYER_ID pcblayer = aTrack->GetLayer();
|
||||
|
||||
if( pcblayer != F_Cu && pcblayer != B_Cu )
|
||||
return false;
|
||||
|
||||
SHAPE_POLY_SET copper_shapes;
|
||||
int maxError = m_board->GetDesignSettings().m_MaxError;
|
||||
|
||||
aTrack->TransformShapeToPolygon( copper_shapes, pcblayer, 0, maxError, ERROR_INSIDE );
|
||||
|
||||
m_pcbModel->AddCopperPolygonShapes( &copper_shapes, pcblayer == F_Cu, aOrigin );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool EXPORTER_STEP::composePCB()
|
||||
{
|
||||
if( m_pcbModel )
|
||||
|
@ -264,14 +306,27 @@ bool EXPORTER_STEP::composePCB()
|
|||
|
||||
m_pcbModel->SetPCBThickness( m_boardThickness );
|
||||
|
||||
// Set the min distance betewenn 2 points for OCC to see these 2 points as merged
|
||||
double minDistmm = std::max( m_params.m_minDistance, STEPEXPORT_MIN_ACCEPTABLE_DISTANCE );
|
||||
m_pcbModel->SetMinDistance( minDistmm );
|
||||
// Note: m_params.m_BoardOutlinesChainingEpsilon is used only to build the board outlines,
|
||||
// not to set OCC chaining epsilon (much smaller)
|
||||
//
|
||||
// Set the min distance between 2 points for OCC to see these 2 points as merged
|
||||
// OCC_MAX_DISTANCE_TO_MERGE_POINTS is acceptable for OCC, otherwise there are issues
|
||||
// to handle the shapes chaining on copper layers, because the Z dist is 0.035 mm and the
|
||||
// min dist must be much smaller (we use 0.001 mm giving good results)
|
||||
m_pcbModel->OCCSetMergeMaxDistance( OCC_MAX_DISTANCE_TO_MERGE_POINTS );
|
||||
|
||||
m_pcbModel->SetMaxError( m_board->GetDesignSettings().m_MaxError );
|
||||
|
||||
for( FOOTPRINT* i : m_board->Footprints() )
|
||||
composePCB( i, origin );
|
||||
// For copper layers, only pads and tracks are added, because adding everything on copper
|
||||
// generate unreasonable file sizes and take a unreasonable calculation time.
|
||||
for( FOOTPRINT* fp : m_board->Footprints() )
|
||||
composePCB( fp, origin );
|
||||
|
||||
if( ExportTracksAndVias() )
|
||||
{
|
||||
for( PCB_TRACK* track : m_board->Tracks() )
|
||||
composePCB( track, origin );
|
||||
}
|
||||
|
||||
ReportMessage( wxT( "Create PCB solid model\n" ) );
|
||||
|
||||
|
@ -291,7 +346,7 @@ bool EXPORTER_STEP::composePCB()
|
|||
|
||||
void EXPORTER_STEP::determinePcbThickness()
|
||||
{
|
||||
m_boardThickness = DEFAULT_BOARD_THICKNESS;
|
||||
m_boardThickness = DEFAULT_BOARD_THICKNESS_MM;
|
||||
|
||||
const BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
|
||||
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
* Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2016-2023 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
|
||||
|
@ -30,9 +30,14 @@
|
|||
#include <geometry/shape_poly_set.h>
|
||||
#include <gal/color4d.h>
|
||||
|
||||
// Default value to chain 2 shapes when creating the board outlines
|
||||
// from shapes on Edges.Cut layer
|
||||
#define BOARD_DEFAULT_CHAINING_EPSILON 0.01
|
||||
|
||||
class PCBMODEL;
|
||||
class BOARD;
|
||||
class FOOTPRINT;
|
||||
class PCB_TRACK;
|
||||
class FILENAME_RESOLVER;
|
||||
|
||||
class EXPORTER_STEP_PARAMS
|
||||
|
@ -45,8 +50,10 @@ public:
|
|||
m_useDrillOrigin( false ),
|
||||
m_includeExcludedBom( true ),
|
||||
m_substModels( true ),
|
||||
m_minDistance( STEPEXPORT_MIN_DISTANCE ),
|
||||
m_boardOnly( false ) {};
|
||||
m_BoardOutlinesChainingEpsilon( BOARD_DEFAULT_CHAINING_EPSILON ),
|
||||
m_boardOnly( false ),
|
||||
m_exportTracks( false )
|
||||
{};
|
||||
|
||||
wxString m_outputFile;
|
||||
|
||||
|
@ -57,8 +64,9 @@ public:
|
|||
bool m_useDrillOrigin;
|
||||
bool m_includeExcludedBom;
|
||||
bool m_substModels;
|
||||
double m_minDistance;
|
||||
double m_BoardOutlinesChainingEpsilon;
|
||||
bool m_boardOnly;
|
||||
bool m_exportTracks;
|
||||
};
|
||||
|
||||
class EXPORTER_STEP
|
||||
|
@ -75,9 +83,13 @@ public:
|
|||
void SetFail() { m_fail = true; }
|
||||
void SetWarn() { m_warn = true; }
|
||||
|
||||
/// Return rue to export tracks and vias on top and bottom copper layers
|
||||
bool ExportTracksAndVias() { return m_params.m_exportTracks; }
|
||||
|
||||
private:
|
||||
bool composePCB();
|
||||
bool composePCB( FOOTPRINT* aFootprint, VECTOR2D aOrigin );
|
||||
bool composePCB( PCB_TRACK* aTrack, VECTOR2D aOrigin );
|
||||
void determinePcbThickness();
|
||||
|
||||
EXPORTER_STEP_PARAMS m_params;
|
||||
|
@ -93,9 +105,6 @@ private:
|
|||
std::unique_ptr<STEP_PCB_MODEL> m_pcbModel;
|
||||
wxString m_pcbName;
|
||||
|
||||
// minimum distance between points to treat them as separate entities (mm)
|
||||
double m_minDistance;
|
||||
|
||||
double m_boardThickness;
|
||||
|
||||
KIGFX::COLOR4D m_solderMaskColor;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
|
||||
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
* Copyright (C) 2016-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2016-2023 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
|
||||
|
@ -93,21 +93,11 @@
|
|||
static constexpr double USER_PREC = 1e-4;
|
||||
static constexpr double USER_ANGLE_PREC = 1e-6;
|
||||
|
||||
// minimum PCB thickness in mm (2 microns assumes a very thin polyimide film)
|
||||
static constexpr double THICKNESS_MIN = 0.002;
|
||||
|
||||
// default PCB thickness in mm
|
||||
static constexpr double THICKNESS_DEFAULT = 1.6;
|
||||
|
||||
// nominal offset from the board
|
||||
static constexpr double BOARD_OFFSET = 0.05;
|
||||
|
||||
// min. length**2 below which 2 points are considered coincident
|
||||
static constexpr double MIN_LENGTH2 = STEPEXPORT_MIN_DISTANCE * STEPEXPORT_MIN_DISTANCE;
|
||||
|
||||
|
||||
// supported file types
|
||||
enum FormatType
|
||||
// supported file types for 3D models
|
||||
enum MODEL3D_FORMAT_TYPE
|
||||
{
|
||||
FMT_NONE,
|
||||
FMT_STEP,
|
||||
|
@ -120,7 +110,7 @@ enum FormatType
|
|||
};
|
||||
|
||||
|
||||
FormatType fileType( const char* aFileName )
|
||||
MODEL3D_FORMAT_TYPE fileType( const char* aFileName )
|
||||
{
|
||||
wxFileName lfile( wxString::FromUTF8Unchecked( aFileName ) );
|
||||
|
||||
|
@ -194,12 +184,13 @@ STEP_PCB_MODEL::STEP_PCB_MODEL( const wxString& aPcbName )
|
|||
m_components = 0;
|
||||
m_precision = USER_PREC;
|
||||
m_angleprec = USER_ANGLE_PREC;
|
||||
m_thickness = THICKNESS_DEFAULT;
|
||||
m_minDistance2 = MIN_LENGTH2;
|
||||
m_boardThickness = BOARD_THICKNESS_DEFAULT_MM;
|
||||
m_copperThickness = COPPER_THICKNESS_DEFAULT_MM;
|
||||
m_mergeOCCMaxDist = OCC_MAX_DISTANCE_TO_MERGE_POINTS;
|
||||
m_minx = 1.0e10; // absurdly large number; any valid PCB X value will be smaller
|
||||
m_pcbName = aPcbName;
|
||||
BRepBuilderAPI::Precision( STEPEXPORT_MIN_DISTANCE );
|
||||
m_maxError = 5000; // 5 microns
|
||||
BRepBuilderAPI::Precision( m_mergeOCCMaxDist );
|
||||
m_maxError = pcbIUScale.mmToIU( ARC_TO_SEGMENT_MAX_ERROR_MM );
|
||||
}
|
||||
|
||||
|
||||
|
@ -208,22 +199,79 @@ STEP_PCB_MODEL::~STEP_PCB_MODEL()
|
|||
m_doc->Close();
|
||||
}
|
||||
|
||||
bool STEP_PCB_MODEL::AddPadShape( const PAD* aPad, const VECTOR2D& aOrigin )
|
||||
{
|
||||
TopoDS_Shape curr_shape_top;
|
||||
TopoDS_Shape curr_shape_bottom;
|
||||
const std::shared_ptr<SHAPE_POLY_SET>& pad_shape = aPad->GetEffectivePolygon();
|
||||
bool success = true;
|
||||
|
||||
if( aPad->IsOnLayer( F_Cu ) )
|
||||
{
|
||||
// Make a shape on top copper layer
|
||||
success = MakeShape( curr_shape_top, pad_shape.get()->COutline(0), m_copperThickness, m_boardThickness, aOrigin );
|
||||
|
||||
if( success )
|
||||
m_board_outlines.push_back( curr_shape_top );
|
||||
}
|
||||
|
||||
if( success && aPad->IsOnLayer( B_Cu ) )
|
||||
{
|
||||
success = MakeShape( curr_shape_bottom, pad_shape.get()->COutline(0), m_copperThickness, -m_copperThickness, aOrigin );
|
||||
|
||||
if( success )
|
||||
m_board_outlines.push_back( curr_shape_bottom );
|
||||
}
|
||||
|
||||
if( !success ) // Error
|
||||
ReportMessage( wxT( "OCC error adding pad/via polygon.\n" ) );
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
bool STEP_PCB_MODEL::AddCopperPolygonShapes( const SHAPE_POLY_SET* aPolyShapes, bool aOnTop, const VECTOR2D& aOrigin )
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
for( int ii = 0; ii < aPolyShapes->OutlineCount(); ii++ )
|
||||
{
|
||||
TopoDS_Shape copper_shape;
|
||||
double z_pos = aOnTop ? m_boardThickness : -m_copperThickness;
|
||||
|
||||
if( MakeShape( copper_shape, aPolyShapes->COutline( ii ), m_copperThickness, z_pos, aOrigin ) )
|
||||
{
|
||||
m_board_outlines.push_back( copper_shape );
|
||||
}
|
||||
else
|
||||
{
|
||||
ReportMessage( wxString::Format( wxT( "Could not add shape (%d points) to copper layer on %s.\n" ),
|
||||
aPolyShapes->COutline( ii ).PointCount(),
|
||||
aOnTop ? wxT( "top" ) : wxT( "bottom" ) ) );
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
bool STEP_PCB_MODEL::AddPadHole( const PAD* aPad, const VECTOR2D& aOrigin )
|
||||
{
|
||||
if( NULL == aPad || !aPad->GetDrillSize().x )
|
||||
if( aPad == nullptr || !aPad->GetDrillSize().x )
|
||||
return false;
|
||||
|
||||
VECTOR2I pos = aPad->GetPosition();
|
||||
double holeZsize = m_boardThickness + ( m_copperThickness * 2 );
|
||||
|
||||
if( aPad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
|
||||
{
|
||||
TopoDS_Shape s =
|
||||
BRepPrimAPI_MakeCylinder( pcbIUScale.IUTomm( aPad->GetDrillSize().x ) * 0.5, m_thickness * 2.0 ).Shape();
|
||||
BRepPrimAPI_MakeCylinder( pcbIUScale.IUTomm( aPad->GetDrillSize().x ) * 0.5, holeZsize * 2.0 ).Shape();
|
||||
gp_Trsf shift;
|
||||
shift.SetTranslation( gp_Vec( pcbIUScale.IUTomm( pos.x - aOrigin.x ),
|
||||
-pcbIUScale.IUTomm( pos.y - aOrigin.y ),
|
||||
-m_thickness * 0.5 ) );
|
||||
-holeZsize * 0.5 ) );
|
||||
BRepBuilderAPI_Transform hole( s, shift );
|
||||
m_cutouts.push_back( hole.Shape() );
|
||||
return true;
|
||||
|
@ -231,6 +279,7 @@ bool STEP_PCB_MODEL::AddPadHole( const PAD* aPad, const VECTOR2D& aOrigin )
|
|||
|
||||
// slotted hole
|
||||
SHAPE_POLY_SET holeOutlines;
|
||||
|
||||
if( !aPad->TransformHoleToPolygon( holeOutlines, 0, m_maxError, ERROR_INSIDE ) )
|
||||
{
|
||||
return false;
|
||||
|
@ -240,7 +289,7 @@ bool STEP_PCB_MODEL::AddPadHole( const PAD* aPad, const VECTOR2D& aOrigin )
|
|||
|
||||
if( holeOutlines.OutlineCount() > 0 )
|
||||
{
|
||||
if( MakeShape( hole, holeOutlines.COutline( 0 ), m_thickness, aOrigin ) )
|
||||
if( MakeShape( hole, holeOutlines.COutline( 0 ), holeZsize*2, -holeZsize * 0.5, aOrigin ) )
|
||||
{
|
||||
m_cutouts.push_back( hole );
|
||||
}
|
||||
|
@ -312,11 +361,11 @@ bool STEP_PCB_MODEL::AddComponent( const std::string& aFileNameUTF8, const std::
|
|||
void STEP_PCB_MODEL::SetPCBThickness( double aThickness )
|
||||
{
|
||||
if( aThickness < 0.0 )
|
||||
m_thickness = THICKNESS_DEFAULT;
|
||||
else if( aThickness < THICKNESS_MIN )
|
||||
m_thickness = THICKNESS_MIN;
|
||||
m_boardThickness = BOARD_THICKNESS_DEFAULT_MM;
|
||||
else if( aThickness < BOARD_THICKNESS_MIN_MM )
|
||||
m_boardThickness = BOARD_THICKNESS_MIN_MM;
|
||||
else
|
||||
m_thickness = aThickness;
|
||||
m_boardThickness = aThickness;
|
||||
}
|
||||
|
||||
|
||||
|
@ -328,14 +377,11 @@ void STEP_PCB_MODEL::SetBoardColor( double r, double g, double b )
|
|||
}
|
||||
|
||||
|
||||
void STEP_PCB_MODEL::SetMinDistance( double aDistance )
|
||||
void STEP_PCB_MODEL::OCCSetMergeMaxDistance( double aDistance )
|
||||
{
|
||||
// Ensure a minimal value (in mm)
|
||||
aDistance = std::max( aDistance, STEPEXPORT_MIN_ACCEPTABLE_DISTANCE );
|
||||
|
||||
// m_minDistance2 keeps a squared distance value
|
||||
m_minDistance2 = aDistance * aDistance;
|
||||
BRepBuilderAPI::Precision( aDistance );
|
||||
m_mergeOCCMaxDist = aDistance;
|
||||
BRepBuilderAPI::Precision( m_mergeOCCMaxDist );
|
||||
}
|
||||
|
||||
bool STEP_PCB_MODEL::isBoardOutlineValid()
|
||||
|
@ -345,7 +391,7 @@ bool STEP_PCB_MODEL::isBoardOutlineValid()
|
|||
|
||||
|
||||
bool STEP_PCB_MODEL::MakeShape( TopoDS_Shape& aShape, const SHAPE_LINE_CHAIN& aChain,
|
||||
double aThickness, const VECTOR2D& aOrigin )
|
||||
double aThickness, double aZposition, const VECTOR2D& aOrigin )
|
||||
{
|
||||
if( !aShape.IsNull() )
|
||||
return false; // there is already data in the shape object
|
||||
|
@ -354,11 +400,12 @@ bool STEP_PCB_MODEL::MakeShape( TopoDS_Shape& aShape, const SHAPE_LINE_CHAIN& aC
|
|||
return false; // the loop is not closed
|
||||
|
||||
BRepBuilderAPI_MakeWire wire;
|
||||
TopoDS_Edge edge;
|
||||
bool success = true;
|
||||
|
||||
gp_Pnt start = gp_Pnt( pcbIUScale.IUTomm( aChain.CPoint( 0 ).x - aOrigin.x ),
|
||||
-pcbIUScale.IUTomm( aChain.CPoint( 0 ).y - aOrigin.y ), 0.0 );
|
||||
-pcbIUScale.IUTomm( aChain.CPoint( 0 ).y - aOrigin.y ), aZposition );
|
||||
|
||||
int items_count = 0;
|
||||
|
||||
for( int j = 0; j < aChain.PointCount(); j++ )
|
||||
{
|
||||
|
@ -367,38 +414,35 @@ bool STEP_PCB_MODEL::MakeShape( TopoDS_Shape& aShape, const SHAPE_LINE_CHAIN& aC
|
|||
gp_Pnt end;
|
||||
|
||||
if( next >= aChain.PointCount() )
|
||||
{
|
||||
end = gp_Pnt( pcbIUScale.IUTomm( aChain.CPoint( 0 ).x - aOrigin.x ),
|
||||
-pcbIUScale.IUTomm( aChain.CPoint( 0 ).y - aOrigin.y ), 0.0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
next = 0;
|
||||
|
||||
end = gp_Pnt( pcbIUScale.IUTomm( aChain.CPoint( next ).x - aOrigin.x ),
|
||||
-pcbIUScale.IUTomm( aChain.CPoint( next ).y - aOrigin.y ), 0.0 );
|
||||
}
|
||||
-pcbIUScale.IUTomm( aChain.CPoint( next ).y - aOrigin.y ), aZposition );
|
||||
|
||||
// Do not export very small segments: they can create broken outlines
|
||||
double seg_len = std::abs( end.X() - start.X()) + std::abs(start.Y() - end.Y() );
|
||||
double min_len = 0.0001; // In mm, i.e. 0.1 micron
|
||||
// Do not export too short segments: they create broken shape because OCC thinks
|
||||
// start point and end point are at the same place
|
||||
double seg_len = std::hypot( end.X() - start.X(), end.Y() - start.Y() );
|
||||
|
||||
if( seg_len < min_len )
|
||||
if( seg_len <= m_mergeOCCMaxDist )
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
TopoDS_Edge edge;
|
||||
edge = BRepBuilderAPI_MakeEdge( start, end );
|
||||
wire.Add( edge );
|
||||
|
||||
if( BRepBuilderAPI_WireDone != wire.Error() )
|
||||
if( wire.Error() != BRepBuilderAPI_WireDone )
|
||||
{
|
||||
ReportMessage( wxT( "failed to add curve\n" ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
items_count++;
|
||||
}
|
||||
catch( const Standard_Failure& e )
|
||||
{
|
||||
ReportMessage(
|
||||
wxString::Format( wxT( "OCC exception: %s\n" ), e.GetMessageString() ) );
|
||||
ReportMessage( wxString::Format( wxT( "MakeShape1: OCC exception: %s\n" ),
|
||||
e.GetMessageString() ) );
|
||||
success = false;
|
||||
}
|
||||
|
||||
|
@ -420,7 +464,8 @@ bool STEP_PCB_MODEL::MakeShape( TopoDS_Shape& aShape, const SHAPE_LINE_CHAIN& aC
|
|||
catch( const Standard_Failure& e )
|
||||
{
|
||||
ReportMessage(
|
||||
wxString::Format( wxT( "OCC exception: %s\n" ), e.GetMessageString() ) );
|
||||
wxString::Format( wxT( "MakeShape2 (items_count %d): OCC exception: %s\n" ),
|
||||
items_count, e.GetMessageString() ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -448,9 +493,10 @@ bool STEP_PCB_MODEL::CreatePCB( SHAPE_POLY_SET& aOutline, VECTOR2D aOrigin )
|
|||
|
||||
m_hasPCB = true; // whether or not operations fail we note that CreatePCB has been invoked
|
||||
|
||||
// Support for more than one main outline (more than one board)
|
||||
std::vector<TopoDS_Shape> board_outlines;
|
||||
// Number of items having the copper color
|
||||
int copper_item_count = m_board_outlines.size();
|
||||
|
||||
// Support for more than one main outline (more than one board)
|
||||
for( int cnt = 0; cnt < aOutline.OutlineCount(); cnt++ )
|
||||
{
|
||||
const SHAPE_LINE_CHAIN& outline = aOutline.COutline( cnt );
|
||||
|
@ -460,7 +506,7 @@ bool STEP_PCB_MODEL::CreatePCB( SHAPE_POLY_SET& aOutline, VECTOR2D aOrigin )
|
|||
|
||||
TopoDS_Shape curr_brd;
|
||||
|
||||
if( !MakeShape( curr_brd, outline, m_thickness, aOrigin ) )
|
||||
if( !MakeShape( curr_brd, outline, m_boardThickness, 0.0, aOrigin ) )
|
||||
{
|
||||
// Error
|
||||
ReportMessage( wxString::Format(
|
||||
|
@ -468,7 +514,7 @@ bool STEP_PCB_MODEL::CreatePCB( SHAPE_POLY_SET& aOutline, VECTOR2D aOrigin )
|
|||
cnt+1, outline.PointCount() ) );
|
||||
}
|
||||
else
|
||||
board_outlines.push_back( curr_brd );
|
||||
m_board_outlines.push_back( curr_brd );
|
||||
|
||||
// Generate board cutouts in current main outline:
|
||||
if( aOutline.HoleCount( cnt ) > 0 )
|
||||
|
@ -482,7 +528,8 @@ bool STEP_PCB_MODEL::CreatePCB( SHAPE_POLY_SET& aOutline, VECTOR2D aOrigin )
|
|||
const SHAPE_LINE_CHAIN& holeOutline = aOutline.Hole( cnt, ii );
|
||||
TopoDS_Shape hole;
|
||||
|
||||
if( MakeShape( hole, holeOutline, m_thickness, aOrigin ) )
|
||||
if( MakeShape( hole, holeOutline, m_boardThickness + (m_copperThickness*4),
|
||||
-m_copperThickness*2, aOrigin ) )
|
||||
{
|
||||
m_cutouts.push_back( hole );
|
||||
}
|
||||
|
@ -501,8 +548,15 @@ bool STEP_PCB_MODEL::CreatePCB( SHAPE_POLY_SET& aOutline, VECTOR2D aOrigin )
|
|||
holelist.Append( hole );
|
||||
|
||||
// Remove holes for each board (usually there is only one board
|
||||
for( TopoDS_Shape& board: board_outlines )
|
||||
int cnt = 0;
|
||||
for( TopoDS_Shape& board: m_board_outlines )
|
||||
{
|
||||
cnt++;
|
||||
|
||||
if( cnt % 10 == 0 )
|
||||
ReportMessage( wxString::Format( wxT( "added %d/%d shapes\n" ),
|
||||
cnt, (int)m_board_outlines.size() ) );
|
||||
|
||||
BRepAlgoAPI_Cut Cut;
|
||||
TopTools_ListOfShape mainbrd;
|
||||
|
||||
|
@ -521,7 +575,7 @@ bool STEP_PCB_MODEL::CreatePCB( SHAPE_POLY_SET& aOutline, VECTOR2D aOrigin )
|
|||
ReportMessage( wxT( "\nGenerate board full shape.\n" ) );
|
||||
|
||||
// Dont expand the component or else coloring it gets hard
|
||||
for( TopoDS_Shape& board: board_outlines )
|
||||
for( TopoDS_Shape& board: m_board_outlines )
|
||||
{
|
||||
m_pcb_labels.push_back( m_assy->AddComponent( m_assy_label, board, false ) );
|
||||
|
||||
|
@ -538,13 +592,15 @@ bool STEP_PCB_MODEL::CreatePCB( SHAPE_POLY_SET& aOutline, VECTOR2D aOrigin )
|
|||
|
||||
// color the PCB
|
||||
Handle( XCAFDoc_ColorTool ) colorTool = XCAFDoc_DocumentTool::ColorTool( m_doc->Main() );
|
||||
Quantity_Color color( m_boardColor[0], m_boardColor[1], m_boardColor[2], Quantity_TOC_RGB );
|
||||
Quantity_Color board_color( m_boardColor[0], m_boardColor[1], m_boardColor[2], Quantity_TOC_RGB );
|
||||
Quantity_Color copper_color( 0.7, 0.61, 0.0, Quantity_TOC_RGB );
|
||||
|
||||
int pcbIdx = 1;
|
||||
int copper_objects_cnt = 0;
|
||||
|
||||
for( TDF_Label& pcb_label : m_pcb_labels )
|
||||
{
|
||||
colorTool->SetColor( pcb_label, color, XCAFDoc_ColorSurf );
|
||||
colorTool->SetColor( pcb_label, board_color, XCAFDoc_ColorSurf );
|
||||
|
||||
Handle( TDataStd_TreeNode ) node;
|
||||
|
||||
|
@ -568,15 +624,21 @@ bool STEP_PCB_MODEL::CreatePCB( SHAPE_POLY_SET& aOutline, VECTOR2D aOrigin )
|
|||
}
|
||||
}
|
||||
|
||||
TopExp_Explorer topex;
|
||||
// color the PCB
|
||||
TopExp_Explorer topex;
|
||||
topex.Init( m_assy->GetShape( pcb_label ), TopAbs_SOLID );
|
||||
|
||||
while( topex.More() )
|
||||
{
|
||||
colorTool->SetColor( topex.Current(), color, XCAFDoc_ColorSurf );
|
||||
if( copper_objects_cnt < copper_item_count )
|
||||
colorTool->SetColor( topex.Current(), copper_color, XCAFDoc_ColorSurf );
|
||||
else
|
||||
colorTool->SetColor( topex.Current(), board_color, XCAFDoc_ColorSurf );
|
||||
|
||||
topex.Next();
|
||||
}
|
||||
|
||||
copper_objects_cnt++;
|
||||
}
|
||||
|
||||
#if( defined OCC_VERSION_HEX ) && ( OCC_VERSION_HEX > 0x070101 )
|
||||
|
@ -711,7 +773,7 @@ bool STEP_PCB_MODEL::getModelLabel( const std::string& aFileNameUTF8, VECTOR3D a
|
|||
m_app->NewDocument( "MDTV-XCAF", doc );
|
||||
|
||||
wxString fileName( wxString::FromUTF8( aFileNameUTF8.c_str() ) );
|
||||
FormatType modelFmt = fileType( aFileNameUTF8.c_str() );
|
||||
MODEL3D_FORMAT_TYPE modelFmt = fileType( aFileNameUTF8.c_str() );
|
||||
|
||||
switch( modelFmt )
|
||||
{
|
||||
|
@ -944,7 +1006,7 @@ bool STEP_PCB_MODEL::getModelLocation( bool aBottom, VECTOR2D aPosition, double
|
|||
}
|
||||
else
|
||||
{
|
||||
aOffset.z += m_thickness;
|
||||
aOffset.z += m_boardThickness;
|
||||
lRot.SetRotation( gp_Ax1( gp_Pnt( 0.0, 0.0, 0.0 ), gp_Dir( 0.0, 0.0, 1.0 ) ), aRotation );
|
||||
lPos.Multiply( lRot );
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
* Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2023 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
|
||||
|
@ -42,9 +42,27 @@
|
|||
#include <math/vector3.h>
|
||||
#include <geometry/shape_poly_set.h>
|
||||
|
||||
///< Default minimum distance between points to treat them as separate ones (mm)
|
||||
static constexpr double STEPEXPORT_MIN_DISTANCE = 0.01;
|
||||
static constexpr double STEPEXPORT_MIN_ACCEPTABLE_DISTANCE = 0.001;
|
||||
/**
|
||||
* Default distance between points to treat them as separate ones (mm)
|
||||
* 0.001 mm is a reasonable value. A too large value creates issues by
|
||||
* merging points that should be different.
|
||||
* Remember we are a 3D space, so a thin line can be broken if 2 points
|
||||
* are merged (in X, Y, Z coords) when they should not.
|
||||
* round shapes converted to polygon can also be not good with a to large value
|
||||
*/
|
||||
static constexpr double OCC_MAX_DISTANCE_TO_MERGE_POINTS = 0.001;
|
||||
|
||||
// default PCB thickness in mm
|
||||
static constexpr double BOARD_THICKNESS_DEFAULT_MM = 1.6;
|
||||
|
||||
// minimum PCB thickness in mm (10 microns assumes a very thin polyimide film)
|
||||
static constexpr double BOARD_THICKNESS_MIN_MM = 0.01;
|
||||
|
||||
// default copper thickness in mm
|
||||
static constexpr double COPPER_THICKNESS_DEFAULT_MM = 0.035;
|
||||
|
||||
// Max error to approximate an arc by segments (in mm)
|
||||
static constexpr double ARC_TO_SEGMENT_MAX_ERROR_MM = 0.005;
|
||||
|
||||
class PAD;
|
||||
|
||||
|
@ -62,6 +80,12 @@ public:
|
|||
// add a pad hole or slot (must be in final position)
|
||||
bool AddPadHole( const PAD* aPad, const VECTOR2D& aOrigin );
|
||||
|
||||
// add a pad/via shape (must be in final position)
|
||||
bool AddPadShape( const PAD* aPad, const VECTOR2D& aOrigin );
|
||||
|
||||
// add a set of polygons (must be in final position) on top or bottom of the board as copper
|
||||
bool AddCopperPolygonShapes( const SHAPE_POLY_SET* aPolyShapes, bool aOnTop, const VECTOR2D& aOrigin );
|
||||
|
||||
// add a component at the given position and orientation
|
||||
bool AddComponent( const std::string& aFileName, const std::string& aRefDes, bool aBottom,
|
||||
VECTOR2D aPosition, double aRotation, VECTOR3D aOffset,
|
||||
|
@ -75,8 +99,9 @@ public:
|
|||
// aThickness > THICKNESS_MIN == use aThickness
|
||||
void SetPCBThickness( double aThickness );
|
||||
|
||||
// Set the minimum distance (in mm) to consider 2 points have the same coordinates
|
||||
void SetMinDistance( double aDistance );
|
||||
// Set the max distance (in mm) to consider 2 points have the same coordinates
|
||||
// and can be merged
|
||||
void OCCSetMergeMaxDistance( double aDistance = OCC_MAX_DISTANCE_TO_MERGE_POINTS );
|
||||
|
||||
void SetMaxError( int aMaxError ) { m_maxError = aMaxError; }
|
||||
|
||||
|
@ -84,7 +109,7 @@ public:
|
|||
bool CreatePCB( SHAPE_POLY_SET& aOutline, VECTOR2D aOrigin );
|
||||
|
||||
bool MakeShape( TopoDS_Shape& aShape, const SHAPE_LINE_CHAIN& chain, double aThickness,
|
||||
const VECTOR2D& aOrigin );
|
||||
double aZposition, const VECTOR2D& aOrigin );
|
||||
|
||||
#ifdef SUPPORTS_IGES
|
||||
// write the assembly model in IGES format
|
||||
|
@ -141,14 +166,20 @@ private:
|
|||
int m_components; // number of successfully loaded components;
|
||||
double m_precision; // model (length unit) numeric precision
|
||||
double m_angleprec; // angle numeric precision
|
||||
double m_boardColor[3];// RGB values
|
||||
double m_thickness; // PCB thickness, mm
|
||||
double m_boardColor[3]; // RGB values
|
||||
double m_boardThickness; // PCB thickness, mm
|
||||
double m_copperThickness; // copper thickness, mm
|
||||
|
||||
double m_minx; // leftmost curve point
|
||||
double m_minDistance2; // minimum squared distance between items (mm)
|
||||
double m_mergeOCCMaxDist; // minimum distance (mm) below which two
|
||||
// points are considered coincident by OCC
|
||||
|
||||
// Holes in main outlines (more than one board)
|
||||
std::vector<TopoDS_Shape> m_cutouts;
|
||||
|
||||
// Main outlines (more than one board)
|
||||
std::vector<TopoDS_Shape> m_board_outlines;
|
||||
|
||||
/// Name of the PCB, which will most likely be the file name of the path.
|
||||
wxString m_pcbName;
|
||||
|
||||
|
|
|
@ -96,8 +96,9 @@ int PCBNEW_JOBS_HANDLER::JobExportStep( JOB* aJob )
|
|||
}
|
||||
|
||||
EXPORTER_STEP_PARAMS params;
|
||||
params.m_exportTracks = aStepJob->m_exportTracks;
|
||||
params.m_includeExcludedBom = aStepJob->m_includeExcludedBom;
|
||||
params.m_minDistance = aStepJob->m_minDistance;
|
||||
params.m_BoardOutlinesChainingEpsilon = aStepJob->m_BoardOutlinesChainingEpsilon;
|
||||
params.m_overwrite = aStepJob->m_overwrite;
|
||||
params.m_substModels = aStepJob->m_substModels;
|
||||
params.m_origin = VECTOR2D( aStepJob->m_xOrigin, aStepJob->m_yOrigin );
|
||||
|
|
Loading…
Reference in New Issue