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 The 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 )
107 {
108 m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
109 SetupStandardButtons( { { wxID_OK, _( "Export" ) },
110 { wxID_CANCEL, _( "Close" ) } } );
111
112
113 // Build default output file name
114 // (last saved filename in project or built from board filename)
116
117 if( path.IsEmpty() )
118 {
119 wxFileName brdFile( m_editFrame->GetBoard()->GetFileName() );
120 brdFile.SetExt( wxT( "step" ) );
121 path = brdFile.GetFullPath();
122 }
123
124 m_outputFileName->SetValue( path );
125 }
126 else
127 {
128 SetTitle( m_job->GetSettingsDialogTitle() );
129
130 m_browseButton->Hide();
132 }
133
134 // DIALOG_SHIM needs a unique hash_key because classname will be the same for both job and
135 // non-job versions (which have different sizes).
136 m_hash_key = TO_UTF8( GetTitle() );
137
138 Layout();
139 bSizerSTEPFile->Fit( this );
140
141 SetFocus();
142
143 if( !m_job )
144 {
146
148
149 switch( m_origin )
150 {
151 default:
152 case STEP_ORIGIN_PLOT_AXIS: m_rbDrillAndPlotOrigin->SetValue( true ); break;
153 case STEP_ORIGIN_GRID_AXIS: m_rbGridOrigin->SetValue( true ); break;
154 case STEP_ORIGIN_USER: m_rbUserDefinedOrigin->SetValue( true ); break;
155 case STEP_ORIGIN_BOARD_CENTER: m_rbBoardCenterOrigin->SetValue( true ); break;
156 }
157
163
164 m_txtNetFilter->SetValue( m_netFilter );
165 m_cbOptimizeStep->SetValue( m_optimizeStep );
168 m_cbExportTracks->SetValue( m_exportTracks );
169 m_cbExportPads->SetValue( m_exportPads );
170 m_cbExportZones->SetValue( m_exportZones );
174 m_cbFuseShapes->SetValue( m_fuseShapes );
176 m_cbFillAllVias->SetValue( m_fillAllVias );
178 m_cbRemoveDNP->SetValue( m_noDNP );
181
183
184 switch( m_componentMode )
185 {
186 case COMPONENT_MODE::EXPORT_ALL: m_rbAllComponents->SetValue( true ); break;
187 case COMPONENT_MODE::EXPORT_SELECTED: m_rbOnlySelected->SetValue( true ); break;
188 case COMPONENT_MODE::CUSTOM_FILTER: m_rbFilteredComponents->SetValue( true ); break;
189 }
190
191 // Sync the enabled states
192 wxCommandEvent dummy;
194
195 m_STEP_OrgUnitChoice->SetSelection( m_originUnits );
196 wxString tmpStr;
197 tmpStr << m_userOriginX;
198 m_STEP_Xorg->SetValue( tmpStr );
199 tmpStr = wxEmptyString;
200 tmpStr << m_userOriginY;
201 m_STEP_Yorg->SetValue( tmpStr );
202 }
203 else
204 {
206 m_rbDrillAndPlotOrigin->SetValue( true );
208 m_rbGridOrigin->SetValue( true );
209 else if( m_job->m_3dparams.m_Origin.x == 0.0 && m_job->m_3dparams.m_Origin.y == 0.0 )
210 m_rbBoardCenterOrigin->SetValue( true );
211 else
212 m_rbUserDefinedOrigin->SetValue( true );
213
216
219
237
240
241 wxCommandEvent dummy;
243
244 m_STEP_OrgUnitChoice->SetSelection( m_originUnits );
245
246 wxString tmpStr;
247 tmpStr << m_userOriginX;
248 m_STEP_Xorg->SetValue( tmpStr );
249 tmpStr = wxEmptyString;
250 tmpStr << m_userOriginY;
251 m_STEP_Yorg->SetValue( tmpStr );
252 }
253
254 wxString bad_scales;
255 size_t bad_count = 0;
256
257 for( FOOTPRINT* fp : m_editFrame->GetBoard()->Footprints() )
258 {
259 for( const FP_3DMODEL& model : fp->Models() )
260 {
261 if( model.m_Scale.x != 1.0 || model.m_Scale.y != 1.0 || model.m_Scale.z != 1.0 )
262 {
263 bad_scales.Append( wxS("\n") );
264 bad_scales.Append( model.m_Filename );
265 bad_count++;
266 }
267 }
268
269 if( bad_count >= 5 )
270 break;
271 }
272
273 if( !bad_scales.empty()
274 && !Pgm().GetCommonSettings()->m_DoNotShowAgain.scaled_3d_models_warning )
275 {
276 wxString extendedMsg = _( "Non-unity scaled models:" ) + wxT( "\n" ) + bad_scales;
277
278 KIDIALOG msgDlg( m_editFrame, _( "Scaled models detected. "
279 "Model scaling is not reliable for mechanical export." ),
280 _( "Model Scale Warning" ), wxOK | wxICON_WARNING );
281 msgDlg.SetExtendedMessage( extendedMsg );
282 msgDlg.DoNotShowCheckbox( __FILE__, __LINE__ );
283
284 msgDlg.ShowModal();
285
286 if( msgDlg.DoNotShowAgain() )
288 }
289
290 if( m_toleranceLastChoice >= 0 )
292
293 if( m_formatLastChoice >= 0 )
294 m_choiceFormat->SetSelection( m_formatLastChoice );
295 else
296 // ensure the selected fmt and the output file ext are synchronized the first time
297 // the dialog is opened
299
300 // Now all widgets have the size fixed, call FinishDialogSettings
302}
303
304
306{
307 GetOriginOption(); // Update m_origin member.
308
309 PCBNEW_SETTINGS* cfg = nullptr;
310
311 try
312 {
314 }
315 catch( const std::runtime_error& e )
316 {
317 wxFAIL_MSG( e.what() );
318 }
319
320 if( !m_job ) // dont save mru if its a job dialog
321 {
322 if( cfg )
323 {
324 cfg->m_ExportStep.origin_mode = static_cast<int>( m_origin );
325 cfg->m_ExportStep.origin_units = m_STEP_OrgUnitChoice->GetSelection();
328
329 double val = 0.0;
330
331 m_STEP_Xorg->GetValue().ToDouble( &val );
332 cfg->m_ExportStep.origin_x = val;
333
334 m_STEP_Yorg->GetValue().ToDouble( &val );
335 cfg->m_ExportStep.origin_y = val;
336
338 cfg->m_ExportStep.no_dnp = m_cbRemoveDNP->GetValue();
339 }
340
341 m_netFilter = m_txtNetFilter->GetValue();
343 m_formatLastChoice = m_choiceFormat->GetSelection();
344 m_optimizeStep = m_cbOptimizeStep->GetValue();
345 m_exportBoardBody = m_cbExportBody->GetValue();
347 m_exportTracks = m_cbExportTracks->GetValue();
348 m_exportPads = m_cbExportPads->GetValue();
349 m_exportZones = m_cbExportZones->GetValue();
353 m_fuseShapes = m_cbFuseShapes->GetValue();
355 m_fillAllVias = m_cbFillAllVias->GetValue();
357
358 if( m_rbAllComponents->GetValue() )
360 else if( m_rbOnlySelected->GetValue() )
362 else
364 }
365}
366
367
369{
371
372 if( m_rbDrillAndPlotOrigin->GetValue() )
374 else if( m_rbGridOrigin->GetValue() )
376 else if( m_rbUserDefinedOrigin->GetValue() )
378 else if( m_rbBoardCenterOrigin->GetValue() )
380
381 return m_origin;
382}
383
384
385void PCB_EDIT_FRAME::OnExportSTEP( wxCommandEvent& event )
386{
387 wxFileName brdFile = GetBoard()->GetFileName();
388
389 // The project filename (.kicad_pro) of the auto saved board filename, if it is created
390 wxFileName autosaveProjFile;
391
392 if( GetScreen()->IsContentModified() || brdFile.GetFullPath().empty() )
393 {
394 if( !doAutoSave() )
395 {
396 DisplayErrorMessage( this, _( "STEP export failed! "
397 "Please save the PCB and try again" ) );
398 return;
399 }
400
401 wxString autosaveFileName = FILEEXT::AutoSaveFilePrefix + brdFile.GetName();
402
403 // Create a dummy .kicad_pro file for this auto saved board file.
404 // this is useful to use some settings (like project path and name)
405 // Because doAutoSave() works, the target directory exists and is writable
406 autosaveProjFile = brdFile;
407 autosaveProjFile.SetName( autosaveFileName );
408 autosaveProjFile.SetExt( "kicad_pro" );
409
410 // Use auto-saved board for export
411 GetSettingsManager()->SaveProjectCopy( autosaveProjFile.GetFullPath(), GetBoard()->GetProject() );
412 brdFile.SetName( autosaveFileName );
413 }
414
415 DIALOG_EXPORT_STEP dlg( this, brdFile.GetFullPath() );
416 dlg.ShowModal();
417
418 // If a dummy .kicad_pro file is created, delete it now it is useless.
419 if( !autosaveProjFile.GetFullPath().IsEmpty() )
420 wxRemoveFile( autosaveProjFile.GetFullPath() );
421}
422
423
424void DIALOG_EXPORT_STEP::onUpdateUnits( wxUpdateUIEvent& aEvent )
425{
426 aEvent.Enable( m_rbUserDefinedOrigin->GetValue() );
427}
428
429
430void DIALOG_EXPORT_STEP::onUpdateXPos( wxUpdateUIEvent& aEvent )
431{
432 aEvent.Enable( m_rbUserDefinedOrigin->GetValue() );
433}
434
435
436void DIALOG_EXPORT_STEP::onUpdateYPos( wxUpdateUIEvent& aEvent )
437{
438 aEvent.Enable( m_rbUserDefinedOrigin->GetValue() );
439}
440
441
442void DIALOG_EXPORT_STEP::onBrowseClicked( wxCommandEvent& aEvent )
443{
444 // clang-format off
445 wxString filter = _( "STEP files" )
447 + _( "Binary glTF files" )
449 + _( "XAO files" )
451 + _( "BREP (OCCT) files" )
453 + _( "PLY files" )
455 + _( "STL files" )
457 // clang-format on
458
459 // Build the absolute path of current output directory to preselect it in the file browser.
460 wxString path = ExpandEnvVarSubstitutions( m_outputFileName->GetValue(), &Prj() );
461 wxFileName fn( Prj().AbsolutePath( path ) );
462
463 wxFileDialog dlg( this, _( "3D Model Output File" ), fn.GetPath(), fn.GetFullName(), filter,
464 wxFD_SAVE );
465
466 if( dlg.ShowModal() == wxID_CANCEL )
467 return;
468
469 path = dlg.GetPath();
470 m_outputFileName->SetValue( path );
471
472 fn = wxFileName( path );
473
474 if( auto formatChoice = get_opt( c_formatExtToChoice, fn.GetExt().Lower() ) )
475 m_choiceFormat->SetSelection( *formatChoice );
476}
477
478
479void DIALOG_EXPORT_STEP::onFormatChoice( wxCommandEvent& event )
480{
482}
483
484
486{
487 wxString newExt = c_formatCommand[m_choiceFormat->GetSelection()];
488 wxString path = m_outputFileName->GetValue();
489
490 int sepIdx = std::max( path.Find( '/', true ), path.Find( '\\', true ) );
491 int dotIdx = path.Find( '.', true );
492
493 if( dotIdx == -1 || dotIdx < sepIdx )
494 path << '.' << newExt;
495 else
496 path = path.Mid( 0, dotIdx ) << '.' << newExt;
497
498 m_outputFileName->SetValue( path );
500}
501
502
503void DIALOG_EXPORT_STEP::onCbExportComponents( wxCommandEvent& event )
504{
505 bool enable = m_cbExportComponents->GetValue();
506
507 m_rbAllComponents->Enable( enable );
508 m_rbOnlySelected->Enable( enable );
509 m_rbFilteredComponents->Enable( enable );
510 m_txtComponentFilter->Enable( enable && m_rbFilteredComponents->GetValue() );
511}
512
513
514void DIALOG_EXPORT_STEP::OnComponentModeChange( wxCommandEvent& event )
515{
516 m_txtComponentFilter->Enable( m_rbFilteredComponents->GetValue() );
517}
518
519
520void DIALOG_EXPORT_STEP::onExportButton( wxCommandEvent& aEvent )
521{
522 if( !m_job )
523 {
524 wxString path = m_outputFileName->GetValue();
526
527 // Build the absolute path of current output directory to preselect it in the file browser.
528 std::function<bool( wxString* )> textResolver =
529 [&]( wxString* token ) -> bool
530 {
531 return m_editFrame->GetBoard()->ResolveTextVar( token, 0 );
532 };
533
534 path = ExpandTextVars( path, &textResolver );
536 path = Prj().AbsolutePath( path );
537
538 if( path.IsEmpty() )
539 {
540 DisplayErrorMessage( this, _( "No filename for output file" ) );
541 return;
542 }
543
544 m_netFilter = m_txtNetFilter->GetValue();
546
547 if( m_rbAllComponents->GetValue() )
549 else if( m_rbOnlySelected->GetValue() )
551 else
553
554 double tolerance; // default value in mm
556 m_formatLastChoice = m_choiceFormat->GetSelection();
557 m_optimizeStep = m_cbOptimizeStep->GetValue();
558 m_exportBoardBody = m_cbExportBody->GetValue();
560 m_exportTracks = m_cbExportTracks->GetValue();
561 m_exportPads = m_cbExportPads->GetValue();
562 m_exportZones = m_cbExportZones->GetValue();
566 m_fuseShapes = m_cbFuseShapes->GetValue();
568 m_fillAllVias = m_cbFillAllVias->GetValue();
569
570 switch( m_choiceTolerance->GetSelection() )
571 {
572 case 0: tolerance = 0.001; break;
573 default:
574 case 1: tolerance = 0.01; break;
575 case 2: tolerance = 0.1; break;
576 }
577
578 SHAPE_POLY_SET outline;
579 wxString msg;
580
581 // Check if the board outline is continuous
582 // max dist from one endPt to next startPt to build a closed shape:
583 int chainingEpsilon = pcbIUScale.mmToIU( tolerance );
584
585 // Arc to segment approx error (not critical here: we do not use the outline shape):
586 int maxError = pcbIUScale.mmToIU( 0.005 );
587 bool success = BuildBoardPolygonOutlines( m_editFrame->GetBoard(), outline, maxError,
588 chainingEpsilon, nullptr );
589 if( !success )
590 {
591 DisplayErrorMessage( this, wxString::Format(
592 _( "Board outline is missing or not closed using %.3f mm tolerance.\n"
593 "Run DRC for a full analysis." ), tolerance ) );
594 return;
595 }
596
597 wxFileName fn( Prj().AbsolutePath( path ) );
598
599 if( fn.FileExists() && !GetOverwriteFile() )
600 {
601 msg.Printf( _( "File '%s' already exists. Do you want overwrite this file?" ),
602 fn.GetFullPath() );
603
604 if( wxMessageBox( msg, _( "STEP/GLTF Export" ), wxYES_NO | wxICON_QUESTION, this ) == wxNO )
605 return;
606 }
607
608 wxFileName appK2S( wxStandardPaths::Get().GetExecutablePath() );
609 #ifdef __WXMAC__
610 // On macOS, we have standalone applications inside the main bundle, so we handle that here:
611 if( appK2S.GetPath().Find( "/Contents/Applications/pcbnew.app/Contents/MacOS" ) != wxNOT_FOUND )
612 {
613 appK2S.AppendDir( wxT( ".." ) );
614 appK2S.AppendDir( wxT( ".." ) );
615 appK2S.AppendDir( wxT( ".." ) );
616 appK2S.AppendDir( wxT( ".." ) );
617 appK2S.AppendDir( wxT( "MacOS" ) );
618 }
619 #else
620 if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
621 {
622 appK2S.RemoveLastDir();
623 appK2S.AppendDir( "kicad" );
624 }
625 #endif
626
627 appK2S.SetName( wxT( "kicad-cli" ) );
628 appK2S.Normalize( FN_NORMALIZE_FLAGS );
629
630 wxString cmdK2S = wxT( "\"" );
631 cmdK2S.Append( appK2S.GetFullPath() );
632 cmdK2S.Append( wxT( "\"" ) );
633
634 cmdK2S.Append( wxT( " pcb" ) );
635 cmdK2S.Append( wxT( " export" ) );
636
637 cmdK2S.Append( wxT( " " ) );
638 cmdK2S.Append( c_formatCommand[m_choiceFormat->GetSelection()] );
639
641 cmdK2S.Append( wxT( " --no-unspecified" ) );
642
643 if( GetNoDNPOption() )
644 cmdK2S.Append( wxT( " --no-dnp" ) );
645
646 if( GetSubstOption() )
647 cmdK2S.Append( wxT( " --subst-models" ) );
648
649 if( !m_optimizeStep )
650 cmdK2S.Append( wxT( " --no-optimize-step" ) );
651
652 if( !m_exportBoardBody )
653 cmdK2S.Append( wxT( " --no-board-body" ) );
654
655 if( !m_exportComponents )
656 cmdK2S.Append( wxT( " --no-components" ) );
657
658 if( m_exportTracks )
659 cmdK2S.Append( wxT( " --include-tracks" ) );
660
661 if( m_exportPads )
662 cmdK2S.Append( wxT( " --include-pads" ) );
663
664 if( m_exportZones )
665 cmdK2S.Append( wxT( " --include-zones" ) );
666
668 cmdK2S.Append( wxT( " --include-inner-copper" ) );
669
671 cmdK2S.Append( wxT( " --include-silkscreen" ) );
672
674 cmdK2S.Append( wxT( " --include-soldermask" ) );
675
676 if( m_fuseShapes )
677 cmdK2S.Append( wxT( " --fuse-shapes" ) );
678
679 if( m_cutViasInBody )
680 cmdK2S.Append( wxT( " --cut-vias-in-body" ) );
681
682 if( m_fillAllVias )
683 cmdK2S.Append( wxT( " --fill-all-vias" ) );
684
685 // Note: for some reason, using \" to insert a quote in a format string, under MacOS
686 // wxString::Format does not work. So use a %c format in string
687 int quote = '\'';
688 int dblquote = '"';
689
690 if( !m_netFilter.empty() )
691 {
692 cmdK2S.Append( wxString::Format( wxT( " --net-filter %c%s%c" ), dblquote, m_netFilter,
693 dblquote ) );
694 }
695
696 switch( m_componentMode )
697 {
699 {
700 wxArrayString components;
702
703 std::for_each( selection.begin(), selection.end(),
704 [&components]( EDA_ITEM* item )
705 {
706 if( item->Type() == PCB_FOOTPRINT_T )
707 components.push_back( static_cast<FOOTPRINT*>( item )->GetReference() );
708 } );
709
710 cmdK2S.Append( wxString::Format( wxT( " --component-filter %c%s%c" ), dblquote,
711 wxJoin( components, ',' ), dblquote ) );
712 break;
713 }
714
716 cmdK2S.Append( wxString::Format( wxT( " --component-filter %c%s%c" ), dblquote,
717 m_componentFilter, dblquote ) );
718 break;
719
720 default:
721 break;
722 }
723
724 switch( GetOriginOption() )
725 {
726 case STEP_ORIGIN_0:
727 wxFAIL_MSG( wxT( "Unsupported origin option: how did we get here?" ) );
728 break;
729
731 cmdK2S.Append( wxT( " --drill-origin" ) );
732 break;
733
735 cmdK2S.Append( wxT( " --grid-origin" ) );
736 break;
737
738 case STEP_ORIGIN_USER:
739 {
740 double xOrg = GetXOrg();
741 double yOrg = GetYOrg();
742
743 if( GetOrgUnitsChoice() == 1 )
744 {
745 // selected reference unit is in inches, and STEP units are mm
746 xOrg *= 25.4;
747 yOrg *= 25.4;
748 }
749
751 cmdK2S.Append( wxString::Format( wxT( " --user-origin=%c%.6fx%.6fmm%c" ),
752 quote, xOrg, yOrg, quote ) );
753 break;
754 }
755
757 {
758 BOX2I bbox = m_editFrame->GetBoard()->ComputeBoundingBox( true );
759 double xOrg = pcbIUScale.IUTomm( bbox.GetCenter().x );
760 double yOrg = pcbIUScale.IUTomm( bbox.GetCenter().y );
762
763 cmdK2S.Append( wxString::Format( wxT( " --user-origin=%c%.6fx%.6fmm%c" ),
764 quote, xOrg, yOrg, quote ) );
765 break;
766 }
767 }
768
769 {
771 cmdK2S.Append( wxString::Format( wxT( " --min-distance=%c%.3fmm%c" ),
772 quote, tolerance, quote ) );
773 }
774
775 // Output file path.
776 cmdK2S.Append( wxString::Format( wxT( " -f -o %c%s%c" ),
777 dblquote, fn.GetFullPath(), dblquote ) );
778
779
780 // Input file path.
781 cmdK2S.Append( wxString::Format( wxT( " %c%s%c" ), dblquote, m_boardPath, dblquote ) );
782
783 wxLogTrace( traceKiCad2Step, wxT( "export step command: %s" ), cmdK2S );
784
785 DIALOG_EXPORT_STEP_LOG* log = new DIALOG_EXPORT_STEP_LOG( this, cmdK2S );
786 log->ShowModal();
787 }
788 else
789 {
809
811 static_cast<EXPORTER_STEP_PARAMS::FORMAT>( m_choiceFormat->GetSelection() ) );
812
813 // ensure the main format on the job is populated
814 switch( m_job->m_3dparams.m_Format )
815 {
818 break;
821 break;
824 break;
827 break;
830 break;
833 break;
834 }
835
836 switch( GetOriginOption() )
837 {
838 case STEP_ORIGIN_0:
839 break;
842 break;
845 break;
846 case STEP_ORIGIN_USER:
847 {
848 double xOrg = GetXOrg();
849 double yOrg = GetYOrg();
850
851 if( GetOrgUnitsChoice() == 1 )
852 {
853 // selected reference unit is in inches, and STEP units are mm
854 xOrg *= 25.4;
855 yOrg *= 25.4;
856 }
857
858 m_job->m_3dparams.m_Origin = VECTOR2D( xOrg, yOrg );
859 break;
860 }
861
863 {
864 BOX2I bbox = m_editFrame->GetBoard()->ComputeBoundingBox( true );
865 double xOrg = pcbIUScale.IUTomm( bbox.GetCenter().x );
866 double yOrg = pcbIUScale.IUTomm( bbox.GetCenter().y );
868
869 m_job->m_3dparams.m_Origin = VECTOR2D( xOrg, yOrg );
870 break;
871 }
872 }
873
874 EndModal( wxID_OK );
875 }
876}
877
878
880{
882}
883
884
886{
888}
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:1713
const FOOTPRINTS & Footprints() const
Definition: board.h:336
const wxString & GetFileName() const
Definition: board.h:332
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={})
std::string m_hash_key
Definition: dialog_shim.h:230
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
JOB_EXPORT_PCB_3D::FORMAT m_format
wxString GetSettingsDialogTitle() const override
void SetStepFormat(EXPORTER_STEP_PARAMS::FORMAT aFormat)
EXPORTER_STEP_PARAMS m_3dparams
Despite the name; also used for other formats.
void SetConfiguredOutputPath(const wxString &aPath)
Sets the configured output path for the job, this path is always saved to file.
Definition: job.cpp:153
wxString GetConfiguredOutputPath() const
Returns the configured output path for the job.
Definition: job.h:226
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: kidialog.h:43
bool DoNotShowAgain() const
Checks the 'do not show again' setting for the dialog.
Definition: kidialog.cpp:59
void DoNotShowCheckbox(wxString file, int line)
Shows the 'do not show again' checkbox.
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:689
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:370
ITER end()
Definition: selection.h:75
ITER begin()
Definition: selection.h:74
void SaveProjectCopy(const wxString &aFullPath, PROJECT *aProject=nullptr)
Save 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:351
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)
Convert aTextValue to a double.
Definition: eda_units.cpp:553
SETTINGS_MANAGER * GetSettingsManager()
PGM_BASE & Pgm()
The global program "get" accessor.
Definition: pgm_base.cpp:1073
see class PGM_BASE
@ LAST_PATH_STEP
Definition: project_file.h:51
std::vector< FAB_LAYER_COLOR > dummy
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: string_utils.h:398
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:694
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