KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_export_step.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2016 Cirilo Bernardo
5 * Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <wx/log.h>
26#include <wx/stdpaths.h>
27#include <wx/process.h>
28#include <wx/string.h>
29#include <wx/filedlg.h>
30
31#include <pgm_base.h>
32#include <board.h>
33#include <confirm.h>
34#include <kidialog.h>
36#include "dialog_export_step.h"
38#include <footprint.h>
39#include <kiface_base.h>
40#include <locale_io.h>
41#include <math/vector3.h>
42#include <pcb_edit_frame.h>
43#include <pcbnew_settings.h>
44#include <project/project_file.h> // LAST_PATH_TYPE
45#include <reporter.h>
46#include <trace_helpers.h>
49#include <filename_resolver.h>
50#include <core/map_helpers.h>
53
54
55// Maps m_choiceFormat selection to extension (and kicad-cli command)
56static const std::vector<wxString> c_formatCommand = { FILEEXT::StepFileExtension,
62
63// Maps file extensions to m_choiceFormat selection
64static const std::map<wxString, int> c_formatExtToChoice = { { FILEEXT::StepFileExtension, 0 },
71
72
73
74int DIALOG_EXPORT_STEP::m_toleranceLastChoice = -1; // Use default
75int DIALOG_EXPORT_STEP::m_formatLastChoice = -1; // Use default
90
91
92DIALOG_EXPORT_STEP::DIALOG_EXPORT_STEP( PCB_EDIT_FRAME* aEditFrame, const wxString& aBoardPath ) :
93 DIALOG_EXPORT_STEP( aEditFrame, aEditFrame, aBoardPath )
94{
95}
96
97
99 const wxString& aBoardPath,
100 JOB_EXPORT_PCB_3D* aJob ) :
101 DIALOG_EXPORT_STEP_BASE( aEditFrame ),
102 m_editFrame( aEditFrame ),
103 m_job( aJob ),
104 m_boardPath( aBoardPath )
105{
106 if( m_job == nullptr )
107 {
108 m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
109 SetupStandardButtons( { { wxID_OK, _( "Export" ) },
110 { wxID_CANCEL, _( "Close" ) } } );
111 }
112 else
113 {
114 m_browseButton->Hide();
115 SetupStandardButtons( { { wxID_OK, _( "Save" ) },
116 { wxID_CANCEL, _( "Close" ) } } );
117 }
118
119 // Build default output file name
120 // (last saved filename in project or built from board filename)
122
123 if( path.IsEmpty() )
124 {
125 wxFileName brdFile( m_editFrame->GetBoard()->GetFileName() );
126 brdFile.SetExt( wxT( "step" ) );
127 path = brdFile.GetFullPath();
128 }
129
130 m_outputFileName->SetValue( path );
131
132 Layout();
133 bSizerSTEPFile->Fit( this );
134
135 SetFocus();
136
137 if( !m_job )
138 {
140
142
143 switch( m_origin )
144 {
145 default:
146 case STEP_ORIGIN_PLOT_AXIS: m_rbDrillAndPlotOrigin->SetValue( true ); break;
147 case STEP_ORIGIN_GRID_AXIS: m_rbGridOrigin->SetValue( true ); break;
148 case STEP_ORIGIN_USER: m_rbUserDefinedOrigin->SetValue( true ); break;
149 case STEP_ORIGIN_BOARD_CENTER: m_rbBoardCenterOrigin->SetValue( true ); break;
150 }
151
157
158 m_txtNetFilter->SetValue( m_netFilter );
159 m_cbOptimizeStep->SetValue( m_optimizeStep );
162 m_cbExportTracks->SetValue( m_exportTracks );
163 m_cbExportPads->SetValue( m_exportPads );
164 m_cbExportZones->SetValue( m_exportZones );
168 m_cbFuseShapes->SetValue( m_fuseShapes );
170 m_cbFillAllVias->SetValue( m_fillAllVias );
172 m_cbRemoveDNP->SetValue( m_noDNP );
175
177
178 switch( m_componentMode )
179 {
180 case COMPONENT_MODE::EXPORT_ALL: m_rbAllComponents->SetValue( true ); break;
181 case COMPONENT_MODE::EXPORT_SELECTED: m_rbOnlySelected->SetValue( true ); break;
182 case COMPONENT_MODE::CUSTOM_FILTER: m_rbFilteredComponents->SetValue( true ); break;
183 }
184
185 // Sync the enabled states
186 wxCommandEvent dummy;
188
189 m_STEP_OrgUnitChoice->SetSelection( m_originUnits );
190 wxString tmpStr;
191 tmpStr << m_userOriginX;
192 m_STEP_Xorg->SetValue( tmpStr );
193 tmpStr = wxEmptyString;
194 tmpStr << m_userOriginY;
195 m_STEP_Yorg->SetValue( tmpStr );
196 }
197 else
198 {
200 m_rbDrillAndPlotOrigin->SetValue( true );
202 m_rbGridOrigin->SetValue( true );
203 else if( m_job->m_3dparams.m_Origin.x == 0.0 && m_job->m_3dparams.m_Origin.y == 0.0 )
204 m_rbBoardCenterOrigin->SetValue( true );
205 else
206 m_rbUserDefinedOrigin->SetValue( true );
207
210
213
231
233
234 wxCommandEvent dummy;
236
237 m_STEP_OrgUnitChoice->SetSelection( m_originUnits );
238
239 wxString tmpStr;
240 tmpStr << m_userOriginX;
241 m_STEP_Xorg->SetValue( tmpStr );
242 tmpStr = wxEmptyString;
243 tmpStr << m_userOriginY;
244 m_STEP_Yorg->SetValue( tmpStr );
245 }
246
247 wxString bad_scales;
248 size_t bad_count = 0;
249
250 for( FOOTPRINT* fp : m_editFrame->GetBoard()->Footprints() )
251 {
252 for( const FP_3DMODEL& model : fp->Models() )
253 {
254 if( model.m_Scale.x != 1.0 || model.m_Scale.y != 1.0 || model.m_Scale.z != 1.0 )
255 {
256 bad_scales.Append( wxS("\n") );
257 bad_scales.Append( model.m_Filename );
258 bad_count++;
259 }
260 }
261
262 if( bad_count >= 5 )
263 break;
264 }
265
266 if( !bad_scales.empty()
267 && !Pgm().GetCommonSettings()->m_DoNotShowAgain.scaled_3d_models_warning )
268 {
269 wxString extendedMsg = _( "Non-unity scaled models:" ) + wxT( "\n" ) + bad_scales;
270
271 KIDIALOG msgDlg( m_editFrame, _( "Scaled models detected. "
272 "Model scaling is not reliable for mechanical export." ),
273 _( "Model Scale Warning" ), wxOK | wxICON_WARNING );
274 msgDlg.SetExtendedMessage( extendedMsg );
275 msgDlg.DoNotShowCheckbox( __FILE__, __LINE__ );
276
277 msgDlg.ShowModal();
278
279 if( msgDlg.DoNotShowAgain() )
281 }
282
283 if( m_toleranceLastChoice >= 0 )
285
286 if( m_formatLastChoice >= 0 )
287 m_choiceFormat->SetSelection( m_formatLastChoice );
288 else
289 // ensure the selected fmt and the output file ext are synchronized the first time
290 // the dialog is opened
292
293 // Now all widgets have the size fixed, call FinishDialogSettings
295}
296
297
299{
300 GetOriginOption(); // Update m_origin member.
301
302 PCBNEW_SETTINGS* cfg = nullptr;
303
304 try
305 {
307 }
308 catch( const std::runtime_error& e )
309 {
310 wxFAIL_MSG( e.what() );
311 }
312
313 if( cfg )
314 {
315 cfg->m_ExportStep.origin_mode = static_cast<int>( m_origin );
316 cfg->m_ExportStep.origin_units = m_STEP_OrgUnitChoice->GetSelection();
319
320 double val = 0.0;
321
322 m_STEP_Xorg->GetValue().ToDouble( &val );
323 cfg->m_ExportStep.origin_x = val;
324
325 m_STEP_Yorg->GetValue().ToDouble( &val );
326 cfg->m_ExportStep.origin_y = val;
327
329 cfg->m_ExportStep.no_dnp = m_cbRemoveDNP->GetValue();
330 }
331
332 m_netFilter = m_txtNetFilter->GetValue();
334 m_formatLastChoice = m_choiceFormat->GetSelection();
335 m_optimizeStep = m_cbOptimizeStep->GetValue();
336 m_exportBoardBody = m_cbExportBody->GetValue();
338 m_exportTracks = m_cbExportTracks->GetValue();
339 m_exportPads = m_cbExportPads->GetValue();
340 m_exportZones = m_cbExportZones->GetValue();
344 m_fuseShapes = m_cbFuseShapes->GetValue();
346 m_fillAllVias = m_cbFillAllVias->GetValue();
348
349 if( m_rbAllComponents->GetValue() )
351 else if( m_rbOnlySelected->GetValue() )
353 else
355}
356
357
359{
361
362 if( m_rbDrillAndPlotOrigin->GetValue() )
364 else if( m_rbGridOrigin->GetValue() )
366 else if( m_rbUserDefinedOrigin->GetValue() )
368 else if( m_rbBoardCenterOrigin->GetValue() )
370
371 return m_origin;
372}
373
374
375void PCB_EDIT_FRAME::OnExportSTEP( wxCommandEvent& event )
376{
377 wxFileName brdFile = GetBoard()->GetFileName();
378
379 // The project filename (.kicad_pro) of the auto saved board filename, if it is created
380 wxFileName autosaveProjFile;
381
382 if( GetScreen()->IsContentModified() || brdFile.GetFullPath().empty() )
383 {
384 if( !doAutoSave() )
385 {
386 DisplayErrorMessage( this, _( "STEP export failed! "
387 "Please save the PCB and try again" ) );
388 return;
389 }
390
391 wxString autosaveFileName = FILEEXT::AutoSaveFilePrefix + brdFile.GetName();
392
393 // Create a dummy .kicad_pro file for this auto saved board file.
394 // this is useful to use some settings (like project path and name)
395 // Because doAutoSave() works, the target directory exists and is writable
396 autosaveProjFile = brdFile;
397 autosaveProjFile.SetName( autosaveFileName );
398 autosaveProjFile.SetExt( "kicad_pro" );
399
400 // Use auto-saved board for export
401 GetSettingsManager()->SaveProjectCopy( autosaveProjFile.GetFullPath(), GetBoard()->GetProject() );
402 brdFile.SetName( autosaveFileName );
403 }
404
405 DIALOG_EXPORT_STEP dlg( this, brdFile.GetFullPath() );
406 dlg.ShowModal();
407
408 // If a dummy .kicad_pro file is created, delete it now it is useless.
409 if( !autosaveProjFile.GetFullPath().IsEmpty() )
410 wxRemoveFile( autosaveProjFile.GetFullPath() );
411}
412
413
414void DIALOG_EXPORT_STEP::onUpdateUnits( wxUpdateUIEvent& aEvent )
415{
416 aEvent.Enable( m_rbUserDefinedOrigin->GetValue() );
417}
418
419
420void DIALOG_EXPORT_STEP::onUpdateXPos( wxUpdateUIEvent& aEvent )
421{
422 aEvent.Enable( m_rbUserDefinedOrigin->GetValue() );
423}
424
425
426void DIALOG_EXPORT_STEP::onUpdateYPos( wxUpdateUIEvent& aEvent )
427{
428 aEvent.Enable( m_rbUserDefinedOrigin->GetValue() );
429}
430
431
432void DIALOG_EXPORT_STEP::onBrowseClicked( wxCommandEvent& aEvent )
433{
434 // clang-format off
435 wxString filter = _( "STEP files" )
437 + _( "Binary glTF files" )
439 + _( "XAO files" )
441 + _( "BREP (OCCT) files" )
443 + _( "PLY files" )
445 + _( "STL files" )
447 // clang-format on
448
449 // Build the absolute path of current output directory to preselect it in the file browser.
450 wxString path = ExpandEnvVarSubstitutions( m_outputFileName->GetValue(), &Prj() );
451 wxFileName fn( Prj().AbsolutePath( path ) );
452
453 wxFileDialog dlg( this, _( "3D Model Output File" ), fn.GetPath(), fn.GetFullName(), filter,
454 wxFD_SAVE );
455
456 if( dlg.ShowModal() == wxID_CANCEL )
457 return;
458
459 path = dlg.GetPath();
460 m_outputFileName->SetValue( path );
461
462 fn = wxFileName( path );
463
464 if( auto formatChoice = get_opt( c_formatExtToChoice, fn.GetExt().Lower() ) )
465 m_choiceFormat->SetSelection( *formatChoice );
466}
467
468
469void DIALOG_EXPORT_STEP::onFormatChoice( wxCommandEvent& event )
470{
472}
473
474
476{
477 wxString newExt = c_formatCommand[m_choiceFormat->GetSelection()];
478 wxString path = m_outputFileName->GetValue();
479
480 int sepIdx = std::max( path.Find( '/', true ), path.Find( '\\', true ) );
481 int dotIdx = path.Find( '.', true );
482
483 if( dotIdx == -1 || dotIdx < sepIdx )
484 path << '.' << newExt;
485 else
486 path = path.Mid( 0, dotIdx ) << '.' << newExt;
487
488 m_outputFileName->SetValue( path );
490}
491
492
493void DIALOG_EXPORT_STEP::onCbExportComponents( wxCommandEvent& event )
494{
495 bool enable = m_cbExportComponents->GetValue();
496
497 m_rbAllComponents->Enable( enable );
498 m_rbOnlySelected->Enable( enable );
499 m_rbFilteredComponents->Enable( enable );
500 m_txtComponentFilter->Enable( enable && m_rbFilteredComponents->GetValue() );
501}
502
503
504void DIALOG_EXPORT_STEP::OnComponentModeChange( wxCommandEvent& event )
505{
506 m_txtComponentFilter->Enable( m_rbFilteredComponents->GetValue() );
507}
508
509
510void DIALOG_EXPORT_STEP::onExportButton( wxCommandEvent& aEvent )
511{
512 if( !m_job )
513 {
514 wxString path = m_outputFileName->GetValue();
516
517 // Build the absolute path of current output directory to preselect it in the file browser.
518 std::function<bool( wxString* )> textResolver =
519 [&]( wxString* token ) -> bool
520 {
521 return m_editFrame->GetBoard()->ResolveTextVar( token, 0 );
522 };
523
524 path = ExpandTextVars( path, &textResolver );
526 path = Prj().AbsolutePath( path );
527
528 if( path.IsEmpty() )
529 {
530 DisplayErrorMessage( this, _( "No filename for output file" ) );
531 return;
532 }
533
534 m_netFilter = m_txtNetFilter->GetValue();
536
537 if( m_rbAllComponents->GetValue() )
539 else if( m_rbOnlySelected->GetValue() )
541 else
543
544 double tolerance; // default value in mm
546 m_formatLastChoice = m_choiceFormat->GetSelection();
547 m_optimizeStep = m_cbOptimizeStep->GetValue();
548 m_exportBoardBody = m_cbExportBody->GetValue();
550 m_exportTracks = m_cbExportTracks->GetValue();
551 m_exportPads = m_cbExportPads->GetValue();
552 m_exportZones = m_cbExportZones->GetValue();
556 m_fuseShapes = m_cbFuseShapes->GetValue();
558 m_fillAllVias = m_cbFillAllVias->GetValue();
559
560 switch( m_choiceTolerance->GetSelection() )
561 {
562 case 0: tolerance = 0.001; break;
563 default:
564 case 1: tolerance = 0.01; break;
565 case 2: tolerance = 0.1; break;
566 }
567
568 SHAPE_POLY_SET outline;
569 wxString msg;
570
571 // Check if the board outline is continuous
572 // max dist from one endPt to next startPt to build a closed shape:
573 int chainingEpsilon = pcbIUScale.mmToIU( tolerance );
574
575 // Arc to segment approx error (not critical here: we do not use the outline shape):
576 int maxError = pcbIUScale.mmToIU( 0.005 );
577 bool success = BuildBoardPolygonOutlines( m_editFrame->GetBoard(), outline, maxError,
578 chainingEpsilon, nullptr );
579 if( !success )
580 {
581 DisplayErrorMessage( this, wxString::Format(
582 _( "Board outline is missing or not closed using %.3f mm tolerance.\n"
583 "Run DRC for a full analysis." ), tolerance ) );
584 return;
585 }
586
587 wxFileName fn( Prj().AbsolutePath( path ) );
588
589 if( fn.FileExists() && !GetOverwriteFile() )
590 {
591 msg.Printf( _( "File '%s' already exists. Do you want overwrite this file?" ),
592 fn.GetFullPath() );
593
594 if( wxMessageBox( msg, _( "STEP/GLTF Export" ), wxYES_NO | wxICON_QUESTION, this ) == wxNO )
595 return;
596 }
597
598 wxFileName appK2S( wxStandardPaths::Get().GetExecutablePath() );
599 #ifdef __WXMAC__
600 // On macOS, we have standalone applications inside the main bundle, so we handle that here:
601 if( appK2S.GetPath().Find( "/Contents/Applications/pcbnew.app/Contents/MacOS" ) != wxNOT_FOUND )
602 {
603 appK2S.AppendDir( wxT( ".." ) );
604 appK2S.AppendDir( wxT( ".." ) );
605 appK2S.AppendDir( wxT( ".." ) );
606 appK2S.AppendDir( wxT( ".." ) );
607 appK2S.AppendDir( wxT( "MacOS" ) );
608 }
609 #else
610 if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
611 {
612 appK2S.RemoveLastDir();
613 appK2S.AppendDir( "kicad" );
614 }
615 #endif
616
617 appK2S.SetName( wxT( "kicad-cli" ) );
618 appK2S.Normalize( FN_NORMALIZE_FLAGS );
619
620 wxString cmdK2S = wxT( "\"" );
621 cmdK2S.Append( appK2S.GetFullPath() );
622 cmdK2S.Append( wxT( "\"" ) );
623
624 cmdK2S.Append( wxT( " pcb" ) );
625 cmdK2S.Append( wxT( " export" ) );
626
627 cmdK2S.Append( wxT( " " ) );
628 cmdK2S.Append( c_formatCommand[m_choiceFormat->GetSelection()] );
629
631 cmdK2S.Append( wxT( " --no-unspecified" ) );
632
633 if( GetNoDNPOption() )
634 cmdK2S.Append( wxT( " --no-dnp" ) );
635
636 if( GetSubstOption() )
637 cmdK2S.Append( wxT( " --subst-models" ) );
638
639 if( !m_optimizeStep )
640 cmdK2S.Append( wxT( " --no-optimize-step" ) );
641
642 if( !m_exportBoardBody )
643 cmdK2S.Append( wxT( " --no-board-body" ) );
644
645 if( !m_exportComponents )
646 cmdK2S.Append( wxT( " --no-components" ) );
647
648 if( m_exportTracks )
649 cmdK2S.Append( wxT( " --include-tracks" ) );
650
651 if( m_exportPads )
652 cmdK2S.Append( wxT( " --include-pads" ) );
653
654 if( m_exportZones )
655 cmdK2S.Append( wxT( " --include-zones" ) );
656
658 cmdK2S.Append( wxT( " --include-inner-copper" ) );
659
661 cmdK2S.Append( wxT( " --include-silkscreen" ) );
662
664 cmdK2S.Append( wxT( " --include-soldermask" ) );
665
666 if( m_fuseShapes )
667 cmdK2S.Append( wxT( " --fuse-shapes" ) );
668
669 if( m_cutViasInBody )
670 cmdK2S.Append( wxT( " --cut-vias-in-body" ) );
671
672 if( m_fillAllVias )
673 cmdK2S.Append( wxT( " --fill-all-vias" ) );
674
675 // Note: for some reason, using \" to insert a quote in a format string, under MacOS
676 // wxString::Format does not work. So use a %c format in string
677 int quote = '\'';
678 int dblquote = '"';
679
680 if( !m_netFilter.empty() )
681 {
682 cmdK2S.Append( wxString::Format( wxT( " --net-filter %c%s%c" ), dblquote, m_netFilter,
683 dblquote ) );
684 }
685
686 switch( m_componentMode )
687 {
689 {
690 wxArrayString components;
692
693 std::for_each( selection.begin(), selection.end(),
694 [&components]( EDA_ITEM* item )
695 {
696 if( item->Type() == PCB_FOOTPRINT_T )
697 components.push_back( static_cast<FOOTPRINT*>( item )->GetReference() );
698 } );
699
700 cmdK2S.Append( wxString::Format( wxT( " --component-filter %c%s%c" ), dblquote,
701 wxJoin( components, ',' ), dblquote ) );
702 break;
703 }
704
706 cmdK2S.Append( wxString::Format( wxT( " --component-filter %c%s%c" ), dblquote,
707 m_componentFilter, dblquote ) );
708 break;
709
710 default:
711 break;
712 }
713
714 switch( GetOriginOption() )
715 {
716 case STEP_ORIGIN_0:
717 wxFAIL_MSG( wxT( "Unsupported origin option: how did we get here?" ) );
718 break;
719
721 cmdK2S.Append( wxT( " --drill-origin" ) );
722 break;
723
725 cmdK2S.Append( wxT( " --grid-origin" ) );
726 break;
727
728 case STEP_ORIGIN_USER:
729 {
730 double xOrg = GetXOrg();
731 double yOrg = GetYOrg();
732
733 if( GetOrgUnitsChoice() == 1 )
734 {
735 // selected reference unit is in inches, and STEP units are mm
736 xOrg *= 25.4;
737 yOrg *= 25.4;
738 }
739
741 cmdK2S.Append( wxString::Format( wxT( " --user-origin=%c%.6fx%.6fmm%c" ),
742 quote, xOrg, yOrg, quote ) );
743 break;
744 }
745
747 {
748 BOX2I bbox = m_editFrame->GetBoard()->ComputeBoundingBox( true );
749 double xOrg = pcbIUScale.IUTomm( bbox.GetCenter().x );
750 double yOrg = pcbIUScale.IUTomm( bbox.GetCenter().y );
752
753 cmdK2S.Append( wxString::Format( wxT( " --user-origin=%c%.6fx%.6fmm%c" ),
754 quote, xOrg, yOrg, quote ) );
755 break;
756 }
757 }
758
759 {
761 cmdK2S.Append( wxString::Format( wxT( " --min-distance=%c%.3fmm%c" ),
762 quote, tolerance, quote ) );
763 }
764
765 // Output file path.
766 cmdK2S.Append( wxString::Format( wxT( " -f -o %c%s%c" ),
767 dblquote, fn.GetFullPath(), dblquote ) );
768
769
770 // Input file path.
771 cmdK2S.Append( wxString::Format( wxT( " %c%s%c" ), dblquote, m_boardPath, dblquote ) );
772
773 wxLogTrace( traceKiCad2Step, wxT( "export step command: %s" ), cmdK2S );
774
775 DIALOG_EXPORT_STEP_LOG* log = new DIALOG_EXPORT_STEP_LOG( this, cmdK2S );
776 log->ShowModal();
777 }
778 else
779 {
780 m_job->SetOutputPath( m_outputFileName->GetValue() );
795 m_job->m_3dparams.m_Format = static_cast<EXPORTER_STEP_PARAMS::FORMAT>( m_choiceFormat->GetSelection() );
800
801 switch( GetOriginOption() )
802 {
803 case STEP_ORIGIN_0:
804 break;
807 break;
810 break;
811 case STEP_ORIGIN_USER:
812 {
813 double xOrg = GetXOrg();
814 double yOrg = GetYOrg();
815
816 if( GetOrgUnitsChoice() == 1 )
817 {
818 // selected reference unit is in inches, and STEP units are mm
819 xOrg *= 25.4;
820 yOrg *= 25.4;
821 }
822
823 m_job->m_3dparams.m_Origin = VECTOR2D( xOrg, yOrg );
824 break;
825 }
826
828 {
829 BOX2I bbox = m_editFrame->GetBoard()->ComputeBoundingBox( true );
830 double xOrg = pcbIUScale.IUTomm( bbox.GetCenter().x );
831 double yOrg = pcbIUScale.IUTomm( bbox.GetCenter().y );
833
834 m_job->m_3dparams.m_Origin = VECTOR2D( xOrg, yOrg );
835 break;
836 }
837 }
838
839 Close();
840 }
841}
842
843
845{
847}
848
849
851{
853}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
bool ResolveTextVar(wxString *token, int aDepth) const
Definition: board.cpp:433
BOX2I ComputeBoundingBox(bool aBoardEdgesOnly=false) const
Calculate the bounding box containing all board items (or board edge segments).
Definition: board.cpp:1674
const FOOTPRINTS & Footprints() const
Definition: board.h:331
const wxString & GetFileName() const
Definition: board.h:327
constexpr const Vec GetCenter() const
Definition: box2.h:230
DO_NOT_SHOW_AGAIN m_DoNotShowAgain
Class DIALOG_EXPORT_STEP_BASE.
wxRadioButton * m_rbFilteredComponents
wxRadioButton * m_rbDrillAndPlotOrigin
STD_BITMAP_BUTTON * m_browseButton
void onFormatChoice(wxCommandEvent &event) override
STEP_ORIGIN_OPTION GetOriginOption()
static bool m_exportSoldermask
int GetOrgUnitsChoice() const
void onCbExportComponents(wxCommandEvent &event) override
PCB_EDIT_FRAME * m_editFrame
void OnComponentModeChange(wxCommandEvent &event) override
DIALOG_EXPORT_STEP(PCB_EDIT_FRAME *aEditFrame, const wxString &aBoardPath)
static COMPONENT_MODE m_componentMode
void onUpdateXPos(wxUpdateUIEvent &aEvent) override
static bool m_exportComponents
STEP_ORIGIN_OPTION m_origin
JOB_EXPORT_PCB_3D * m_job
void onExportButton(wxCommandEvent &aEvent) override
static bool m_exportBoardBody
static bool m_exportSilkscreen
static wxString m_componentFilter
static int m_toleranceLastChoice
void onUpdateUnits(wxUpdateUIEvent &aEvent) override
static bool m_exportInnerCopper
void onUpdateYPos(wxUpdateUIEvent &aEvent) override
void onBrowseClicked(wxCommandEvent &aEvent) override
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
int ShowModal() override
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:89
EXPORTER_STEP_PARAMS m_3dparams
Despite the name; also used for other formats.
void SetOutputPath(const wxString &aPath)
Definition: job.cpp:129
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: kidialog.h:43
bool DoNotShowAgain() const
Definition: kidialog.cpp:59
void DoNotShowCheckbox(wxString file, int line)
Checks the 'do not show again' setting for the dialog.
Definition: kidialog.cpp:51
int ShowModal() override
Definition: kidialog.cpp:95
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:49
DIALOG_EXPORT_STEP m_ExportStep
PCBNEW_SETTINGS * GetPcbNewSettings() const
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
BOARD * GetBoard() const
The main frame for Pcbnew.
void SetLastPath(LAST_PATH_TYPE aType, const wxString &aLastPath)
Set the path of the last file successfully read.
bool doAutoSave() override
Perform auto save when the board has been modified and not saved within the auto save interval.
void OnExportSTEP(wxCommandEvent &event)
Export the current BOARD to a STEP assembly.
wxString GetLastPath(LAST_PATH_TYPE aType)
Get the last path for a particular type.
bool IsContentModified() const override
Get if the current board has been modified but not saved.
SELECTION & GetCurrentSelection() override
Get the current selection from the canvas area.
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition: pgm_base.cpp:679
virtual const wxString AbsolutePath(const wxString &aFileName) const
Fix up aFileName if it is relative to the project's directory to be an absolute path and filename.
Definition: project.cpp:359
ITER end()
Definition: selection.h:75
ITER begin()
Definition: selection.h:74
void SaveProjectCopy(const wxString &aFullPath, PROJECT *aProject=nullptr)
Saves a copy of the current project under the given path.
Represent a set of closed polygons.
void SetBitmap(const wxBitmapBundle &aBmp)
void SetValue(const wxString &aValue) override
Set a new value in evaluator buffer, and display it in the wxTextCtrl.
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition: common.cpp:348
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject, int aFlags)
Definition: common.cpp:59
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:195
This file is part of the common library.
bool BuildBoardPolygonOutlines(BOARD *aBoard, SHAPE_POLY_SET &aOutlines, int aErrorMax, int aChainingEpsilon, OUTLINE_ERROR_HANDLER *aErrorHandler, bool aAllowUseArcsInPolygons)
Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut l...
static const std::map< wxString, int > c_formatExtToChoice
static const std::vector< wxString > c_formatCommand
#define _(s)
static const std::string BrepFileExtension
static const std::string StepFileAbrvExtension
static const std::string XaoFileExtension
static const std::string GltfBinaryFileExtension
static const std::string StlFileExtension
static const std::string AutoSaveFilePrefix
static const std::string PlyFileExtension
static const std::string StepFileExtension
const wxChar *const traceKiCad2Step
Flag to enable KiCad2Step debug tracing.
This file is part of the common library.
std::optional< V > get_opt(const std::map< wxString, V > &aMap, const wxString &aKey)
Definition: map_helpers.h:34
KICOMMON_API double DoubleValueFromString(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Function DoubleValueFromString converts aTextValue to a double.
Definition: eda_units.cpp:576
SETTINGS_MANAGER * GetSettingsManager()
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1060
see class PGM_BASE
@ LAST_PATH_STEP
Definition: project_file.h:51
std::vector< FAB_LAYER_COLOR > dummy
constexpr double IUTomm(int iu) const
Definition: base_units.h:86
constexpr int mmToIU(double mm) const
Definition: base_units.h:88
wxLogTrace helper definitions.
VECTOR2< double > VECTOR2D
Definition: vector2d.h:690
wxString AddFileExtListToFilter(const std::vector< std::string > &aExts)
Build the wildcard extension file dialog wildcard filter to add to the base message dialog.
Definition of file extensions used in Kicad.
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().
Definition: wx_filename.h:39