PCB: Add option to cli and graphics to export stpz

This commit is contained in:
Andrea Greco 2025-06-09 23:01:24 +02:00 committed by Ian McInerney
parent 4a4aad7373
commit 8eff58a6dc
13 changed files with 108 additions and 31 deletions

View File

@ -25,6 +25,7 @@
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_3D::FORMAT,
{
{ JOB_EXPORT_PCB_3D::FORMAT::UNKNOWN, nullptr },
{ JOB_EXPORT_PCB_3D::FORMAT::STEPZ, "stpz" },
{ JOB_EXPORT_PCB_3D::FORMAT::STEP, "step" },
{ JOB_EXPORT_PCB_3D::FORMAT::BREP, "brep" },
{ JOB_EXPORT_PCB_3D::FORMAT::GLB, "step" },
@ -47,6 +48,7 @@ wxString EXPORTER_STEP_PARAMS::GetDefaultExportExtension() const
switch( m_Format )
{
case EXPORTER_STEP_PARAMS::FORMAT::STEP: return wxS( "step" );
case EXPORTER_STEP_PARAMS::FORMAT::STEPZ: return wxS( "stpz" );
case EXPORTER_STEP_PARAMS::FORMAT::BREP: return wxS( "brep" );
case EXPORTER_STEP_PARAMS::FORMAT::XAO: return wxS( "xao" );
case EXPORTER_STEP_PARAMS::FORMAT::GLB: return wxS( "glb" );
@ -63,6 +65,7 @@ wxString EXPORTER_STEP_PARAMS::GetFormatName() const
{
// honestly these names shouldn't be translated since they are mostly industry standard acronyms
case EXPORTER_STEP_PARAMS::FORMAT::STEP: return wxS( "STEP" );
case EXPORTER_STEP_PARAMS::FORMAT::STEPZ: return wxS( "STPZ" );
case EXPORTER_STEP_PARAMS::FORMAT::BREP: return wxS( "BREP" );
case EXPORTER_STEP_PARAMS::FORMAT::XAO: return wxS( "XAO" );
case EXPORTER_STEP_PARAMS::FORMAT::GLB: return wxS( "Binary GLTF" );
@ -159,6 +162,7 @@ void JOB_EXPORT_PCB_3D::SetStepFormat( EXPORTER_STEP_PARAMS::FORMAT aFormat )
switch( m_3dparams.m_Format )
{
case EXPORTER_STEP_PARAMS::FORMAT::STEP: m_format = JOB_EXPORT_PCB_3D::FORMAT::STEP; break;
case EXPORTER_STEP_PARAMS::FORMAT::STEPZ: m_format = JOB_EXPORT_PCB_3D::FORMAT::STEPZ; break;
case EXPORTER_STEP_PARAMS::FORMAT::GLB: m_format = JOB_EXPORT_PCB_3D::FORMAT::GLB; break;
case EXPORTER_STEP_PARAMS::FORMAT::XAO: m_format = JOB_EXPORT_PCB_3D::FORMAT::XAO; break;
case EXPORTER_STEP_PARAMS::FORMAT::BREP: m_format = JOB_EXPORT_PCB_3D::FORMAT::BREP; break;

View File

@ -63,6 +63,7 @@ public:
enum class FORMAT
{
STEP,
STEPZ,
BREP,
XAO,
GLB,
@ -118,6 +119,7 @@ public:
{
UNKNOWN, // defefer to arg
STEP,
STEPZ,
BREP,
XAO,
GLB,

View File

@ -204,6 +204,7 @@ const std::string FILEEXT::JsonFileExtension( "json" );
const std::string FILEEXT::PythonFileExtension( "py" );
const std::string FILEEXT::StepFileExtension( "step" );
const std::string FILEEXT::StepZFileAbrvExtension( "stpz" );
const std::string FILEEXT::StepFileAbrvExtension( "stp" );
const std::string FILEEXT::GltfBinaryFileExtension( "glb" );
const std::string FILEEXT::BrepFileExtension( "brep" );

View File

@ -193,6 +193,7 @@ public:
static const std::string PythonFileExtension;
static const std::string StepFileExtension;
static const std::string StepZFileAbrvExtension;
static const std::string StepFileAbrvExtension;
static const std::string GltfBinaryFileExtension;
static const std::string BrepFileExtension;

View File

@ -75,7 +75,7 @@ CLI::PCB_EXPORT_3D_COMMAND::PCB_EXPORT_3D_COMMAND( const std::string& aNa
{
m_argParser.add_argument( ARG_FORMAT )
.default_value( std::string( "step" ) )
.help( UTF8STDSTR( _( "Output file format, options: step, brep, xao, glb "
.help( UTF8STDSTR( _( "Output file format, options: step, stepz, brep, xao, glb "
"(binary glTF), ply, stl" ) ) );
}
@ -258,6 +258,8 @@ int CLI::PCB_EXPORT_3D_COMMAND::doPerform( KIWAY& aKiway )
if( format == wxS( "step" ) )
step->m_format = JOB_EXPORT_PCB_3D::FORMAT::STEP;
else if( format == wxS( "stpz" ) )
step->m_format = JOB_EXPORT_PCB_3D::FORMAT::STEPZ;
else if( format == wxS( "brep" ) )
step->m_format = JOB_EXPORT_PCB_3D::FORMAT::BREP;
else if( format == wxS( "xao" ) )

View File

@ -126,6 +126,7 @@ static CLI::PCB_EXPORT_3D_COMMAND exportPcbXaoCmd{ "xao", UTF8STDSTR( _(
static CLI::PCB_EXPORT_3D_COMMAND exportPcbVrmlCmd{ "vrml", UTF8STDSTR( _( "Export VRML" ) ), JOB_EXPORT_PCB_3D::FORMAT::VRML };
static CLI::PCB_EXPORT_3D_COMMAND exportPcbPlyCmd{ "ply", UTF8STDSTR( _( "Export PLY" ) ), JOB_EXPORT_PCB_3D::FORMAT::PLY };
static CLI::PCB_EXPORT_3D_COMMAND exportPcbStlCmd{ "stl", UTF8STDSTR( _( "Export STL" ) ), JOB_EXPORT_PCB_3D::FORMAT::STL };
static CLI::PCB_EXPORT_3D_COMMAND exportPcbStepzCmd{ "stpz", UTF8STDSTR( _( "Export STEPZ" ) ), JOB_EXPORT_PCB_3D::FORMAT::STEPZ };
static CLI::PCB_EXPORT_SVG_COMMAND exportPcbSvgCmd{};
static CLI::PCB_EXPORT_PDF_COMMAND exportPcbPdfCmd{};
static CLI::PCB_EXPORT_POS_COMMAND exportPcbPosCmd{};
@ -215,7 +216,8 @@ static std::vector<COMMAND_ENTRY> commandStack = {
&exportPcbVrmlCmd,
&exportPcbXaoCmd,
&exportPcbPlyCmd,
&exportPcbStlCmd
&exportPcbStlCmd,
&exportPcbStepzCmd
}
}
}

View File

@ -59,7 +59,8 @@ static const std::vector<wxString> c_formatCommand = { FILEEXT::StepFileExtensio
FILEEXT::XaoFileExtension,
FILEEXT::BrepFileExtension,
FILEEXT::PlyFileExtension,
FILEEXT::StlFileExtension};
FILEEXT::StlFileExtension,
FILEEXT::StepZFileAbrvExtension };
// Maps file extensions to m_choiceFormat selection
static const std::map<wxString, int> c_formatExtToChoice = { { FILEEXT::StepFileExtension, 0 },
@ -68,8 +69,8 @@ static const std::map<wxString, int> c_formatExtToChoice = { { FILEEXT::StepFile
{ FILEEXT::XaoFileExtension, 2 },
{ FILEEXT::BrepFileExtension, 3 },
{ FILEEXT::PlyFileExtension, 4 },
{ FILEEXT::StlFileExtension, 5 }};
{ FILEEXT::StlFileExtension, 5 },
{ FILEEXT::StepZFileAbrvExtension, 6 }};
int DIALOG_EXPORT_STEP::m_toleranceLastChoice = -1; // Use default
@ -820,6 +821,7 @@ void DIALOG_EXPORT_STEP::onExportButton( wxCommandEvent& aEvent )
switch( m_job->m_3dparams.m_Format )
{
case EXPORTER_STEP_PARAMS::FORMAT::STEP: m_job->m_format = JOB_EXPORT_PCB_3D::FORMAT::STEP; break;
case EXPORTER_STEP_PARAMS::FORMAT::STEPZ: m_job->m_format = JOB_EXPORT_PCB_3D::FORMAT::STEPZ; break;
case EXPORTER_STEP_PARAMS::FORMAT::GLB: m_job->m_format = JOB_EXPORT_PCB_3D::FORMAT::GLB; break;
case EXPORTER_STEP_PARAMS::FORMAT::XAO: m_job->m_format = JOB_EXPORT_PCB_3D::FORMAT::XAO; break;
case EXPORTER_STEP_PARAMS::FORMAT::BREP: m_job->m_format = JOB_EXPORT_PCB_3D::FORMAT::BREP; break;

View File

@ -24,7 +24,7 @@ DIALOG_EXPORT_STEP_BASE::DIALOG_EXPORT_STEP_BASE( wxWindow* parent, wxWindowID i
m_txtFormat->Wrap( -1 );
bSizerTop->Add( m_txtFormat, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
wxString m_choiceFormatChoices[] = { _("STEP"), _("GLB (Binary glTF)"), _("XAO"), _("BREP (OCCT)"), _("PLY (ASCII)"), _("STL") };
wxString m_choiceFormatChoices[] = { _("STEP"), _("GLB (Binary glTF)"), _("XAO"), _("BREP (OCCT)"), _("PLY (ASCII)"), _("STL"), _("STPZ") };
int m_choiceFormatNChoices = sizeof( m_choiceFormatChoices ) / sizeof( wxString );
m_choiceFormat = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceFormatNChoices, m_choiceFormatChoices, 0 );
m_choiceFormat->SetSelection( 0 );

View File

@ -64,11 +64,11 @@
<property name="name">bSizerSTEPFile</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">protected</property>
<object class="sizeritem" expanded="false">
<object class="sizeritem" expanded="true">
<property name="border">6</property>
<property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="false">
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bSizerTop</property>
<property name="orient">wxHORIZONTAL</property>
@ -153,7 +153,7 @@
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="choices">&quot;STEP&quot; &quot;GLB (Binary glTF)&quot; &quot;XAO&quot; &quot;BREP (OCCT)&quot; &quot;PLY (ASCII)&quot; &quot;STL&quot;</property>
<property name="choices">&quot;STEP&quot; &quot;GLB (Binary glTF)&quot; &quot;XAO&quot; &quot;BREP (OCCT)&quot; &quot;PLY (ASCII)&quot; &quot;STL&quot; &quot;STPZ&quot;</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
@ -409,25 +409,25 @@
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="true">
<object class="wxBoxSizer" expanded="false">
<property name="minimum_size"></property>
<property name="name">bSizerMain</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="true">
<object class="wxBoxSizer" expanded="false">
<property name="minimum_size"></property>
<property name="name">bSizer8</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="proportion">0</property>
<object class="wxStaticBoxSizer" expanded="true">
<object class="wxStaticBoxSizer" expanded="false">
<property name="id">wxID_ANY</property>
<property name="label">Board Options</property>
<property name="minimum_size"></property>
@ -565,11 +565,11 @@
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="true">
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="true">
<object class="wxCheckBox" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -1167,11 +1167,11 @@
</object>
</object>
</object>
<object class="sizeritem" expanded="true">
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="proportion">0</property>
<object class="wxStaticBoxSizer" expanded="true">
<object class="wxStaticBoxSizer" expanded="false">
<property name="id">wxID_ANY</property>
<property name="label">Conductor Options</property>
<property name="minimum_size"></property>
@ -1504,11 +1504,11 @@
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="true">
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="true">
<object class="wxCheckBox" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -1700,11 +1700,11 @@
</object>
</object>
</object>
<object class="sizeritem" expanded="true">
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="true">
<object class="wxBoxSizer" expanded="false">
<property name="minimum_size"></property>
<property name="name">bSizer5</property>
<property name="orient">wxVERTICAL</property>
@ -2399,11 +2399,11 @@
</object>
</object>
</object>
<object class="sizeritem" expanded="true">
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="proportion">1</property>
<object class="wxStaticBoxSizer" expanded="true">
<object class="wxStaticBoxSizer" expanded="false">
<property name="id">wxID_ANY</property>
<property name="label">Other Options</property>
<property name="minimum_size"></property>

View File

@ -661,6 +661,10 @@ void EXPORTER_STEP::initOutputVariant()
m_pcbModel->SpecializeVariant( OUTPUT_FORMAT::FMT_OUT_STEP );
break;
case EXPORTER_STEP_PARAMS::FORMAT::STEPZ:
m_pcbModel->SpecializeVariant( OUTPUT_FORMAT::FMT_OUT_STEPZ );
break;
case EXPORTER_STEP_PARAMS::FORMAT::BREP:
m_pcbModel->SpecializeVariant( OUTPUT_FORMAT::FMT_OUT_BREP );
break;
@ -872,7 +876,9 @@ bool EXPORTER_STEP::Export()
bool success = true;
if( m_params.m_Format == EXPORTER_STEP_PARAMS::FORMAT::STEP )
success = m_pcbModel->WriteSTEP( m_outputFile, m_params.m_OptimizeStep );
success = m_pcbModel->WriteSTEP( m_outputFile, m_params.m_OptimizeStep, false );
else if( m_params.m_Format == EXPORTER_STEP_PARAMS::FORMAT::STEPZ )
success = m_pcbModel->WriteSTEP( m_outputFile, m_params.m_OptimizeStep, true );
else if( m_params.m_Format == EXPORTER_STEP_PARAMS::FORMAT::BREP )
success = m_pcbModel->WriteBREP( m_outputFile );
else if( m_params.m_Format == EXPORTER_STEP_PARAMS::FORMAT::XAO )

View File

@ -28,10 +28,14 @@
#include <sstream>
#include <string>
#include <utility>
#include <wx/file.h>
#include <wx/filename.h>
#include <wx/filefn.h>
#include <wx/sstream.h>
#include <wx/stdpaths.h>
#include <wx/stream.h>
#include <wx/string.h>
#include <wx/zstream.h>
#include <wx/wfstream.h>
#include <wx/zipstrm.h>
#include <wx/stdstream.h>
@ -2360,8 +2364,46 @@ bool STEP_PCB_MODEL::WriteIGES( const wxString& aFileName )
}
#endif
bool STEP_PCB_MODEL::CompressSTEP( wxString& inputFile, wxString& outputFile )
{
wxFileInputStream input( inputFile );
wxFileOutputStream output( outputFile );
bool STEP_PCB_MODEL::WriteSTEP( const wxString& aFileName, bool aOptimize )
if( !input.IsOk() )
{
m_reporter->Report( wxString::Format( _( "Cannot create input stream '%s'.\n" ), inputFile ) );
return false;
}
if( !output.IsOk() )
{
m_reporter->Report( wxString::Format( _( "Cannot create output stream '%s'.\n" ), outputFile ) );
return false;
}
wxZlibOutputStream zlibStream( output, -1, wxZLIB_GZIP );
if( !zlibStream.IsOk() )
{
m_reporter->Report( _( "Impossible create compress stream" ) );
return false;
}
input.Read( zlibStream );
if( input.LastRead() == 0 || zlibStream.LastWrite() == 0 )
{
m_reporter->Report( _( "Compress read or write error" ) );
return false;
}
zlibStream.Close();
output.Close();
return true;
}
bool STEP_PCB_MODEL::WriteSTEP( const wxString& aFileName, bool aOptimize, bool compress )
{
if( !isBoardOutlineValid() )
{
@ -2422,16 +2464,27 @@ bool STEP_PCB_MODEL::WriteSTEP( const wxString& aFileName, bool aOptimize )
if( !workCWD.IsEmpty() )
wxSetWorkingDirectory( workCWD );
char tmpfname[] = "$tempfile$.step";
wxString tmpfname( "$tempfile$.step" );
if( Standard_False == writer.Write( tmpfname ) )
if( Standard_False == writer.Write( tmpfname.c_str() ) )
success = false;
if( compress && success )
{
wxString srcTmp( tmpfname );
wxString dstTmp( "$tempfile$.stpz" );
success = STEP_PCB_MODEL::CompressSTEP( srcTmp, dstTmp );
wxRemoveFile( srcTmp );
tmpfname = dstTmp;
}
if( success )
{
// Preserve the permissions of the current file
KIPLATFORM::IO::DuplicatePermissions( fn.GetFullPath(), tmpfname );
KIPLATFORM::IO::DuplicatePermissions( fn.GetFullPath(), tmpfname.c_str() );
if( !wxRenameFile( tmpfname, fn.GetFullName(), true ) )
{
@ -3347,4 +3400,4 @@ bool STEP_PCB_MODEL::WriteSTL( const wxString& aFileName )
wxSetWorkingDirectory( currCWD );
return success;
}
}

View File

@ -78,6 +78,7 @@ enum class OUTPUT_FORMAT
{
FMT_OUT_UNKNOWN = 0,
FMT_OUT_STEP,
FMT_OUT_STEPZ,
FMT_OUT_IGES,
FMT_OUT_BREP,
FMT_OUT_XAO,
@ -187,7 +188,7 @@ public:
#endif
// write the assembly model in STEP format
bool WriteSTEP( const wxString& aFileName, bool aOptimize );
bool WriteSTEP( const wxString& aFileName, bool aOptimize, bool compress );
// write the assembly in BREP format
bool WriteBREP( const wxString& aFileName );
@ -256,6 +257,8 @@ private:
TDF_Label transferModel( Handle( TDocStd_Document )& source, Handle( TDocStd_Document ) & dest,
VECTOR3D aScale );
bool CompressSTEP( wxString& inputFile, wxString& outputFile );
Handle( XCAFApp_Application ) m_app;
Handle( TDocStd_Document ) m_doc;
Handle( XCAFDoc_ShapeTool ) m_assy;

View File

@ -542,6 +542,7 @@ int PCBNEW_JOBS_HANDLER::JobExportStep( JOB* aJob )
switch( aStepJob->m_format )
{
case JOB_EXPORT_PCB_3D::FORMAT::STEP: params.m_Format = EXPORTER_STEP_PARAMS::FORMAT::STEP; break;
case JOB_EXPORT_PCB_3D::FORMAT::STEPZ: params.m_Format = EXPORTER_STEP_PARAMS::FORMAT::STEPZ; break;
case JOB_EXPORT_PCB_3D::FORMAT::BREP: params.m_Format = EXPORTER_STEP_PARAMS::FORMAT::BREP; break;
case JOB_EXPORT_PCB_3D::FORMAT::XAO: params.m_Format = EXPORTER_STEP_PARAMS::FORMAT::XAO; break;
case JOB_EXPORT_PCB_3D::FORMAT::GLB: params.m_Format = EXPORTER_STEP_PARAMS::FORMAT::GLB; break;