From 36331e259a484c6afeb08474cf22acc8d0bec5c9 Mon Sep 17 00:00:00 2001 From: Mike Williams Date: Mon, 4 Mar 2024 10:05:53 -0500 Subject: [PATCH] VRML: add options to exclude DNP/unspecified types like STEP exporter --- kicad/cli/command_pcb_export_3d.cpp | 26 ++-- pcbnew/dialogs/dialog_export_vrml.cpp | 26 +++- pcbnew/dialogs/dialog_export_vrml_base.cpp | 6 + pcbnew/dialogs/dialog_export_vrml_base.fbp | 130 ++++++++++++++++++ pcbnew/dialogs/dialog_export_vrml_base.h | 2 + pcbnew/exporters/export_vrml.h | 1 + pcbnew/exporters/exporter_vrml.cpp | 16 +++ pcbnew/exporters/exporter_vrml.h | 7 + pcbnew/pcb_edit_frame.h | 1 + pcbnew/pcbnew_jobs_handler.cpp | 3 +- pcbnew/pcbnew_settings.cpp | 6 + pcbnew/pcbnew_settings.h | 2 + .../scripting/pcbnew_scripting_helpers.cpp | 4 +- .../scripting/pcbnew_scripting_helpers.h | 3 +- 14 files changed, 215 insertions(+), 18 deletions(-) diff --git a/kicad/cli/command_pcb_export_3d.cpp b/kicad/cli/command_pcb_export_3d.cpp index 87c42a8f36..f509c54f65 100644 --- a/kicad/cli/command_pcb_export_3d.cpp +++ b/kicad/cli/command_pcb_export_3d.cpp @@ -70,6 +70,17 @@ CLI::PCB_EXPORT_3D_COMMAND::PCB_EXPORT_3D_COMMAND( const std::string& aNa .help( UTF8STDSTR( _( "Overwrite output file" ) ) ) .flag(); + m_argParser.add_argument( ARG_NO_UNSPECIFIED ) + .help( UTF8STDSTR( + _( "Exclude 3D models for components with 'Unspecified' footprint type" ) ) ) + .implicit_value( true ) + .default_value( false ); + + m_argParser.add_argument( ARG_NO_DNP ) + .help( UTF8STDSTR( + _( "Exclude 3D models for components with 'Do not populate' attribute" ) ) ) + .flag(); + if( m_format == JOB_EXPORT_PCB_3D::FORMAT::STEP || m_format == JOB_EXPORT_PCB_3D::FORMAT::GLB ) { m_argParser.add_argument( ARG_GRID_ORIGIN ) @@ -80,17 +91,6 @@ CLI::PCB_EXPORT_3D_COMMAND::PCB_EXPORT_3D_COMMAND( const std::string& aNa .help( UTF8STDSTR( _( "Use Drill Origin for output origin" ) ) ) .flag(); - m_argParser.add_argument( ARG_NO_UNSPECIFIED ) - .help( UTF8STDSTR( _( - "Exclude 3D models for components with 'Unspecified' footprint type" ) ) ) - .implicit_value( true ) - .default_value( false ); - - m_argParser.add_argument( ARG_NO_DNP ) - .help( UTF8STDSTR( - _( "Exclude 3D models for components with 'Do not populate' attribute" ) ) ) - .flag(); - m_argParser.add_argument( "--subst-models" ) .help( UTF8STDSTR( _( "Substitute STEP or IGS models with the same name in place " "of VRML models" ) ) ) @@ -157,8 +157,6 @@ int CLI::PCB_EXPORT_3D_COMMAND::doPerform( KIWAY& aKiway ) { step->m_useDrillOrigin = m_argParser.get( ARG_DRILL_ORIGIN ); step->m_useGridOrigin = m_argParser.get( ARG_GRID_ORIGIN ); - step->m_includeUnspecified = !m_argParser.get( ARG_NO_UNSPECIFIED ); - step->m_includeDNP = !m_argParser.get( ARG_NO_DNP ); step->m_substModels = m_argParser.get( ARG_SUBST_MODELS ); step->m_exportTracks = m_argParser.get( ARG_INCLUDE_TRACKS ); step->m_exportZones = m_argParser.get( ARG_INCLUDE_ZONES ); @@ -170,6 +168,8 @@ int CLI::PCB_EXPORT_3D_COMMAND::doPerform( KIWAY& aKiway ) step->m_optimizeStep = !m_argParser.get( ARG_NO_OPTIMIZE_STEP ); } + step->m_includeUnspecified = !m_argParser.get( ARG_NO_UNSPECIFIED ); + step->m_includeDNP = !m_argParser.get( ARG_NO_DNP ); step->m_overwrite = m_argParser.get( ARG_FORCE ); step->m_filename = m_argInput; step->m_outputFile = m_argOutput; diff --git a/pcbnew/dialogs/dialog_export_vrml.cpp b/pcbnew/dialogs/dialog_export_vrml.cpp index d20f1568bd..619a2d63d8 100644 --- a/pcbnew/dialogs/dialog_export_vrml.cpp +++ b/pcbnew/dialogs/dialog_export_vrml.cpp @@ -54,6 +54,8 @@ public: PCBNEW_SETTINGS* cfg = m_parent->GetPcbNewSettings(); m_unitsOpt = cfg->m_ExportVrml.units; + m_noUnspecified = cfg->m_ExportVrml.no_unspecified; + m_noDNP = cfg->m_ExportVrml.no_dnp; m_copy3DFilesOpt = cfg->m_ExportVrml.copy_3d_models; m_useRelativePathsOpt = cfg->m_ExportVrml.use_relative_paths; m_RefUnits = cfg->m_ExportVrml.ref_units; @@ -64,6 +66,8 @@ public: m_rbCoordOrigin->SetSelection( m_originMode ); m_rbSelectUnits->SetSelection( m_unitsOpt ); + m_cbRemoveUnspecified->SetValue( m_noUnspecified ); + m_cbRemoveDNP->SetValue( m_noDNP ); m_cbCopyFiles->SetValue( m_copy3DFilesOpt ); m_cbUseRelativePaths->SetValue( m_useRelativePathsOpt ); m_VRML_RefUnitChoice->SetSelection( m_RefUnits ); @@ -83,6 +87,8 @@ public: ~DIALOG_EXPORT_3DFILE() { m_unitsOpt = GetUnits(); + m_noUnspecified = GetNoUnspecifiedOption(); + m_noDNP = GetNoDNPOption(); m_copy3DFilesOpt = GetCopyFilesOption(); PCBNEW_SETTINGS* cfg = nullptr; @@ -99,6 +105,8 @@ public: if( cfg ) { cfg->m_ExportVrml.units = m_unitsOpt; + cfg->m_ExportVrml.no_unspecified = m_noUnspecified; + cfg->m_ExportVrml.no_dnp = m_noDNP; cfg->m_ExportVrml.copy_3d_models = m_copy3DFilesOpt; cfg->m_ExportVrml.use_relative_paths = m_useRelativePathsOpt; cfg->m_ExportVrml.ref_units = m_VRML_RefUnitChoice->GetSelection(); @@ -153,6 +161,16 @@ public: return m_unitsOpt = m_rbSelectUnits->GetSelection(); } + bool GetNoUnspecifiedOption() + { + return m_cbRemoveUnspecified->GetValue(); + } + + bool GetNoDNPOption() + { + return m_cbRemoveDNP->GetValue(); + } + bool GetCopyFilesOption() { return m_copy3DFilesOpt = m_cbCopyFiles->GetValue(); @@ -174,6 +192,8 @@ public: private: PCB_EDIT_FRAME* m_parent; int m_unitsOpt; // Remember last units option + bool m_noUnspecified; // Remember last No Unspecified Component option + bool m_noDNP; // Remember last No DNP Component option bool m_copy3DFilesOpt; // Remember last copy model files option bool m_useRelativePathsOpt; // Remember last use absolute paths option int m_RefUnits; // Remember last units for Reference Point @@ -249,6 +269,8 @@ void PCB_EDIT_FRAME::OnExportVRML( wxCommandEvent& event ) } double scale = scaleList[dlg.GetUnits()]; // final scale export + bool includeUnspecified = !dlg.GetNoUnspecifiedOption(); + bool includeDNP = !dlg.GetNoDNPOption(); bool export3DFiles = dlg.GetCopyFilesOption(); bool useRelativePaths = dlg.GetUseRelativePathsOption(); @@ -272,8 +294,8 @@ void PCB_EDIT_FRAME::OnExportVRML( wxCommandEvent& event ) } } - if( !ExportVRML_File( path, scale, export3DFiles, useRelativePaths, - modelPath.GetPath(), aXRef, aYRef ) ) + if( !ExportVRML_File( path, scale, includeUnspecified, includeDNP, export3DFiles, + useRelativePaths, modelPath.GetPath(), aXRef, aYRef ) ) { wxString msg = wxString::Format( _( "Failed to create file '%s'." ), path ); DisplayErrorMessage( this, msg ); diff --git a/pcbnew/dialogs/dialog_export_vrml_base.cpp b/pcbnew/dialogs/dialog_export_vrml_base.cpp index cc2fe12c84..1cc4695a6c 100644 --- a/pcbnew/dialogs/dialog_export_vrml_base.cpp +++ b/pcbnew/dialogs/dialog_export_vrml_base.cpp @@ -121,6 +121,12 @@ DIALOG_EXPORT_3DFILE_BASE::DIALOG_EXPORT_3DFILE_BASE( wxWindow* parent, wxWindow wxBoxSizer* bSizer4; bSizer4 = new wxBoxSizer( wxVERTICAL ); + m_cbRemoveDNP = new wxCheckBox( this, wxID_ANY, _("Ignore 'Do not populate' components"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer4->Add( m_cbRemoveDNP, 0, wxALL, 5 ); + + m_cbRemoveUnspecified = new wxCheckBox( this, wxID_ANY, _("Ignore 'Unspecified' components"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer4->Add( m_cbRemoveUnspecified, 0, wxALL, 5 ); + m_cbCopyFiles = new wxCheckBox( this, wxID_ANY, _("Copy 3D model files to 3D model path"), wxDefaultPosition, wxDefaultSize, 0 ); m_cbCopyFiles->SetToolTip( _("If checked: copy 3D models to the destination folder\nIf not checked: Embed 3D models in the VRML board file") ); diff --git a/pcbnew/dialogs/dialog_export_vrml_base.fbp b/pcbnew/dialogs/dialog_export_vrml_base.fbp index 596de1db23..4899a16bee 100644 --- a/pcbnew/dialogs/dialog_export_vrml_base.fbp +++ b/pcbnew/dialogs/dialog_export_vrml_base.fbp @@ -963,6 +963,136 @@ bSizer4 wxVERTICAL none + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Ignore 'Do not populate' components + + 0 + + + 0 + + 1 + m_cbRemoveDNP + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Ignore 'Unspecified' components + + 0 + + + 0 + + 1 + m_cbRemoveUnspecified + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + 5 wxALL diff --git a/pcbnew/dialogs/dialog_export_vrml_base.h b/pcbnew/dialogs/dialog_export_vrml_base.h index c81e02e423..df864e53f5 100644 --- a/pcbnew/dialogs/dialog_export_vrml_base.h +++ b/pcbnew/dialogs/dialog_export_vrml_base.h @@ -50,6 +50,8 @@ class DIALOG_EXPORT_3DFILE_BASE : public DIALOG_SHIM wxStaticText* m_staticText5; wxTextCtrl* m_VRML_Yref; wxRadioBox* m_rbSelectUnits; + wxCheckBox* m_cbRemoveDNP; + wxCheckBox* m_cbRemoveUnspecified; wxCheckBox* m_cbCopyFiles; wxCheckBox* m_cbUseRelativePaths; wxStdDialogButtonSizer* m_sdbSizer; diff --git a/pcbnew/exporters/export_vrml.h b/pcbnew/exporters/export_vrml.h index 8b45110983..7cb3b721ed 100644 --- a/pcbnew/exporters/export_vrml.h +++ b/pcbnew/exporters/export_vrml.h @@ -51,6 +51,7 @@ public: */ bool ExportVRML_File( PROJECT* aProject, wxString *aMessages, const wxString& aFullFileName, double aMMtoWRMLunit, + bool aIncludeUnspecified, bool aIncludeDNP, bool aExport3DFiles, bool aUseRelativePaths, const wxString& a3D_Subdir, double aXRef, double aYRef ); diff --git a/pcbnew/exporters/exporter_vrml.cpp b/pcbnew/exporters/exporter_vrml.cpp index ced39ab04c..f82655debc 100644 --- a/pcbnew/exporters/exporter_vrml.cpp +++ b/pcbnew/exporters/exporter_vrml.cpp @@ -60,12 +60,14 @@ EXPORTER_VRML::EXPORTER_VRML( BOARD* aBoard ) bool EXPORTER_VRML::ExportVRML_File( PROJECT* aProject, wxString *aMessages, const wxString& aFullFileName, double aMMtoWRMLunit, + bool aIncludeUnspecified, bool aIncludeDNP, bool aExport3DFiles, bool aUseRelativePaths, const wxString& a3D_Subdir, double aXRef, double aYRef ) { return pcb_exporter->ExportVRML_File( aProject, aMessages, aFullFileName, aMMtoWRMLunit, + aIncludeUnspecified, aIncludeDNP, aExport3DFiles, aUseRelativePaths, a3D_Subdir, aXRef, aYRef ); } @@ -1020,6 +1022,15 @@ void EXPORTER_PCB_VRML::ExportVrmlFootprint( FOOTPRINT* aFootprint, std::ostream for( PAD* pad : aFootprint->Pads() ) ExportVrmlPadHole( pad ); + if( !m_includeUnspecified + && ( !( aFootprint->GetAttributes() & ( FP_THROUGH_HOLE | FP_SMD ) ) ) ) + { + return; + } + + if( !m_includeDNP && aFootprint->IsDNP() ) + return; + bool isFlipped = aFootprint->GetLayer() == B_Cu; // Export the object VRML model(s) @@ -1231,6 +1242,7 @@ void EXPORTER_PCB_VRML::ExportVrmlFootprint( FOOTPRINT* aFootprint, std::ostream bool EXPORTER_PCB_VRML::ExportVRML_File( PROJECT* aProject, wxString *aMessages, const wxString& aFullFileName, double aMMtoWRMLunit, + bool aIncludeUnspecified, bool aIncludeDNP, bool aExport3DFiles, bool aUseRelativePaths, const wxString& a3D_Subdir, double aXRef, double aYRef ) @@ -1251,6 +1263,8 @@ bool EXPORTER_PCB_VRML::ExportVRML_File( PROJECT* aProject, wxString *aMessages, m_Subdir3DFpModels = subdir.GetAbsolutePath( wxFileName( aFullFileName ).GetPath() ); m_UseRelPathIn3DModelFilename = aUseRelativePaths; + m_includeUnspecified = aIncludeUnspecified; + m_includeDNP = aIncludeDNP; m_Cache3Dmodels = PROJECT_PCB::Get3DCacheManager( aProject ); // When 3D models are separate files, for historical reasons the VRML unit @@ -1311,6 +1325,7 @@ bool EXPORTER_PCB_VRML::ExportVRML_File( PROJECT* aProject, wxString *aMessages, } bool PCB_EDIT_FRAME::ExportVRML_File( const wxString& aFullFileName, double aMMtoWRMLunit, + bool aIncludeUnspecified, bool aIncludeDNP, bool aExport3DFiles, bool aUseRelativePaths, const wxString& a3D_Subdir, double aXRef, double aYRef ) @@ -1320,6 +1335,7 @@ bool PCB_EDIT_FRAME::ExportVRML_File( const wxString& aFullFileName, double aMMt EXPORTER_VRML model3d( GetBoard() ); success = model3d.ExportVRML_File( &Prj(), &msgs, aFullFileName, aMMtoWRMLunit, + aIncludeUnspecified, aIncludeDNP, aExport3DFiles, aUseRelativePaths, a3D_Subdir, aXRef, aYRef ); diff --git a/pcbnew/exporters/exporter_vrml.h b/pcbnew/exporters/exporter_vrml.h index 310b61213d..f2fff05129 100644 --- a/pcbnew/exporters/exporter_vrml.h +++ b/pcbnew/exporters/exporter_vrml.h @@ -124,6 +124,7 @@ public: */ bool ExportVRML_File( PROJECT* aProject, wxString *aMessages, const wxString& aFullFileName, double aMMtoWRMLunit, + bool aIncludeUnspecified, bool aIncludeDNP, bool aExport3DFiles, bool aUseRelativePaths, const wxString& a3D_Subdir, double aXRef, double aYRef ); @@ -244,6 +245,12 @@ private: // true to reuse component definitions bool m_ReuseDef; + // true if unspecified components should be included + bool m_includeUnspecified; + + // true if DNP components should be included + bool m_includeDNP; + // scaling from 0.1 inch to desired VRML unit double m_WorldScale = 1.0; diff --git a/pcbnew/pcb_edit_frame.h b/pcbnew/pcb_edit_frame.h index e3cbc6afe9..e58bb2e50a 100644 --- a/pcbnew/pcb_edit_frame.h +++ b/pcbnew/pcb_edit_frame.h @@ -494,6 +494,7 @@ public: * @return true if Ok. */ bool ExportVRML_File( const wxString& aFullFileName, double aMMtoWRMLunit, + bool aIncludeUnspecified, bool aIncludeDNP, bool aExport3DFiles, bool aUseRelativePaths, const wxString& a3D_Subdir, double aXRef, double aYRef ); diff --git a/pcbnew/pcbnew_jobs_handler.cpp b/pcbnew/pcbnew_jobs_handler.cpp index ba3992939e..0ad66cf616 100644 --- a/pcbnew/pcbnew_jobs_handler.cpp +++ b/pcbnew/pcbnew_jobs_handler.cpp @@ -157,6 +157,7 @@ int PCBNEW_JOBS_HANDLER::JobExportStep( JOB* aJob ) bool success = vrmlExporter.ExportVRML_File( brd->GetProject(), &messages, aStepJob->m_outputFile, scale, + aStepJob->m_includeUnspecified, aStepJob->m_includeDNP, !aStepJob->m_vrmlModelDir.IsEmpty(), aStepJob->m_vrmlRelativePaths, aStepJob->m_vrmlModelDir, originX, originY ); @@ -1269,4 +1270,4 @@ void PCBNEW_JOBS_HANDLER::loadOverrideDrawingSheet( BOARD* aBrd, const wxString& // failed loading custom path, revert back to default loadSheet( aBrd->GetProject()->GetProjectFile().m_BoardDrawingSheetFile ); -} \ No newline at end of file +} diff --git a/pcbnew/pcbnew_settings.cpp b/pcbnew/pcbnew_settings.cpp index 6bf4aeb375..da06a4077c 100644 --- a/pcbnew/pcbnew_settings.cpp +++ b/pcbnew/pcbnew_settings.cpp @@ -413,6 +413,12 @@ PCBNEW_SETTINGS::PCBNEW_SETTINGS() m_params.emplace_back( new PARAM( "export_vrml.units", &m_ExportVrml.units, 1 ) ); + m_params.emplace_back( new PARAM( "export_vrml.no_unspecified", + &m_ExportVrml.no_unspecified, false ) ); + + m_params.emplace_back( new PARAM( "export_vrml.no_dnp", + &m_ExportVrml.no_dnp, false ) ); + m_params.emplace_back( new PARAM( "export_vrml.copy_3d_models", &m_ExportVrml.copy_3d_models, false ) ); diff --git a/pcbnew/pcbnew_settings.h b/pcbnew/pcbnew_settings.h index 5a263b6858..36df7cca29 100644 --- a/pcbnew/pcbnew_settings.h +++ b/pcbnew/pcbnew_settings.h @@ -213,6 +213,8 @@ public: struct DIALOG_EXPORT_VRML { int units; + bool no_unspecified; + bool no_dnp; bool copy_3d_models; bool use_relative_paths; int ref_units; diff --git a/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp b/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp index 2f93274791..918ea0eb31 100644 --- a/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp +++ b/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp @@ -397,12 +397,14 @@ bool ExportSpecctraDSN( BOARD* aBoard, wxString& aFullFilename ) } -bool ExportVRML( const wxString& aFullFileName, double aMMtoWRMLunit, bool aExport3DFiles, +bool ExportVRML( const wxString& aFullFileName, double aMMtoWRMLunit, bool aIncludeUnspecified, + bool aIncludeDNP, bool aExport3DFiles, bool aUseRelativePaths, const wxString& a3D_Subdir, double aXRef, double aYRef ) { if( s_PcbEditFrame ) { bool ok = s_PcbEditFrame->ExportVRML_File( aFullFileName, aMMtoWRMLunit, + aIncludeUnspecified, aIncludeDNP, aExport3DFiles, aUseRelativePaths, a3D_Subdir, aXRef, aYRef ); return ok; diff --git a/pcbnew/python/scripting/pcbnew_scripting_helpers.h b/pcbnew/python/scripting/pcbnew_scripting_helpers.h index db2b4c11d3..76f47d1267 100644 --- a/pcbnew/python/scripting/pcbnew_scripting_helpers.h +++ b/pcbnew/python/scripting/pcbnew_scripting_helpers.h @@ -157,7 +157,8 @@ bool ExportSpecctraDSN( BOARD* aBoard, wxString& aFullFilename ); * See ExportVRML_File in pcb_edit_frame.h for detailed documentation. * @return true if OK. */ -bool ExportVRML( const wxString& aFullFileName, double aMMtoWRMLunit, bool aExport3DFiles, +bool ExportVRML( const wxString& aFullFileName, double aMMtoWRMLunit, bool aIncludeUnspecified, + bool aIncludeDNP, bool aExport3DFiles, bool aUseRelativePaths, const wxString& a3D_Subdir, double aXRef, double aYRef ); /**