VRML: add options to exclude DNP/unspecified types like STEP exporter

This commit is contained in:
Mike Williams 2024-03-04 10:05:53 -05:00
parent ff8ddae9bd
commit 36331e259a
14 changed files with 215 additions and 18 deletions

View File

@ -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<bool>( ARG_DRILL_ORIGIN );
step->m_useGridOrigin = m_argParser.get<bool>( ARG_GRID_ORIGIN );
step->m_includeUnspecified = !m_argParser.get<bool>( ARG_NO_UNSPECIFIED );
step->m_includeDNP = !m_argParser.get<bool>( ARG_NO_DNP );
step->m_substModels = m_argParser.get<bool>( ARG_SUBST_MODELS );
step->m_exportTracks = m_argParser.get<bool>( ARG_INCLUDE_TRACKS );
step->m_exportZones = m_argParser.get<bool>( ARG_INCLUDE_ZONES );
@ -170,6 +168,8 @@ int CLI::PCB_EXPORT_3D_COMMAND::doPerform( KIWAY& aKiway )
step->m_optimizeStep = !m_argParser.get<bool>( ARG_NO_OPTIMIZE_STEP );
}
step->m_includeUnspecified = !m_argParser.get<bool>( ARG_NO_UNSPECIFIED );
step->m_includeDNP = !m_argParser.get<bool>( ARG_NO_DNP );
step->m_overwrite = m_argParser.get<bool>( ARG_FORCE );
step->m_filename = m_argInput;
step->m_outputFile = m_argOutput;

View File

@ -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 );

View File

@ -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") );

View File

@ -963,6 +963,136 @@
<property name="name">bSizer4</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="true">
<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">Ignore &apos;Do not populate&apos; components</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_cbRemoveDNP</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"></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="true">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="true">
<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">Ignore &apos;Unspecified&apos; components</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_cbRemoveUnspecified</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"></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="false">
<property name="border">5</property>
<property name="flag">wxALL</property>

View File

@ -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;

View File

@ -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 );

View File

@ -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 );

View File

@ -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;

View File

@ -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 );

View File

@ -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 );
}
}

View File

@ -413,6 +413,12 @@ PCBNEW_SETTINGS::PCBNEW_SETTINGS()
m_params.emplace_back( new PARAM<int>( "export_vrml.units",
&m_ExportVrml.units, 1 ) );
m_params.emplace_back( new PARAM<bool>( "export_vrml.no_unspecified",
&m_ExportVrml.no_unspecified, false ) );
m_params.emplace_back( new PARAM<bool>( "export_vrml.no_dnp",
&m_ExportVrml.no_dnp, false ) );
m_params.emplace_back( new PARAM<bool>( "export_vrml.copy_3d_models",
&m_ExportVrml.copy_3d_models, false ) );

View File

@ -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;

View File

@ -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;

View File

@ -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 );
/**