ADDED: Support 3D shape export in BREP format.

BREP doesn't support colors or label names,
but is much faster to write/read compared to STEP.
This commit is contained in:
Alex Shvartzkop 2024-04-17 17:31:07 +03:00
parent bf16f757ed
commit d98d7f9017
14 changed files with 2119 additions and 2022 deletions

View File

@ -34,6 +34,7 @@ public:
{
UNKNOWN, // defefer to arg
STEP,
BREP,
GLB,
VRML
};

View File

@ -196,6 +196,7 @@ const std::string FILEEXT::JsonFileExtension( "json" );
const std::string FILEEXT::StepFileExtension( "step" );
const std::string FILEEXT::StepFileAbrvExtension( "stp" );
const std::string FILEEXT::GltfBinaryFileExtension( "glb" );
const std::string FILEEXT::BrepFileExtension( "brep" );
const wxString FILEEXT::GerberFileExtensionsRegex( "(gbr|gko|pho|(g[tb][alops])|(gm?\\d\\d*)|(gp[tb]))" );

View File

@ -186,6 +186,7 @@ public:
static const std::string StepFileExtension;
static const std::string StepFileAbrvExtension;
static const std::string GltfBinaryFileExtension;
static const std::string BrepFileExtension;
static const wxString GerberFileExtensionsRegex;

View File

@ -63,7 +63,8 @@ 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, glb (binary glTF)" ) ) );
.help( UTF8STDSTR(
_( "Output file format, options: step, brep, glb (binary glTF)" ) ) );
}
m_argParser.add_argument( ARG_FORCE, "-f" )
@ -81,7 +82,8 @@ CLI::PCB_EXPORT_3D_COMMAND::PCB_EXPORT_3D_COMMAND( const std::string& aNa
_( "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 )
if( m_format == JOB_EXPORT_PCB_3D::FORMAT::STEP || m_format == JOB_EXPORT_PCB_3D::FORMAT::BREP
|| m_format == JOB_EXPORT_PCB_3D::FORMAT::GLB )
{
m_argParser.add_argument( ARG_GRID_ORIGIN )
.help( UTF8STDSTR( _( "Use Grid Origin for output origin" ) ) )
@ -153,7 +155,8 @@ int CLI::PCB_EXPORT_3D_COMMAND::doPerform( KIWAY& aKiway )
{
std::unique_ptr<JOB_EXPORT_PCB_3D> step( new JOB_EXPORT_PCB_3D( true ) );
if( m_format == JOB_EXPORT_PCB_3D::FORMAT::STEP || m_format == JOB_EXPORT_PCB_3D::FORMAT::GLB )
if( m_format == JOB_EXPORT_PCB_3D::FORMAT::STEP || m_format == JOB_EXPORT_PCB_3D::FORMAT::BREP
|| m_format == JOB_EXPORT_PCB_3D::FORMAT::GLB )
{
step->m_useDrillOrigin = m_argParser.get<bool>( ARG_DRILL_ORIGIN );
step->m_useGridOrigin = m_argParser.get<bool>( ARG_GRID_ORIGIN );
@ -182,6 +185,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( "brep" ) )
step->m_format = JOB_EXPORT_PCB_3D::FORMAT::BREP;
else if( format == wxS( "glb" ) )
step->m_format = JOB_EXPORT_PCB_3D::FORMAT::GLB;
else
@ -260,7 +265,8 @@ int CLI::PCB_EXPORT_3D_COMMAND::doPerform( KIWAY& aKiway )
step->m_hasUserOrigin = true;
}
if( m_format == JOB_EXPORT_PCB_3D::FORMAT::STEP || m_format == JOB_EXPORT_PCB_3D::FORMAT::GLB )
if( m_format == JOB_EXPORT_PCB_3D::FORMAT::STEP || m_format == JOB_EXPORT_PCB_3D::FORMAT::BREP
|| m_format == JOB_EXPORT_PCB_3D::FORMAT::GLB )
{
wxString minDistance =
From_UTF8( m_argParser.get<std::string>( ARG_MIN_DISTANCE ).c_str() );

View File

@ -112,6 +112,7 @@ static CLI::PCB_EXPORT_DRILL_COMMAND exportPcbDrillCmd{};
static CLI::PCB_EXPORT_DXF_COMMAND exportPcbDxfCmd{};
static CLI::PCB_EXPORT_3D_COMMAND exportPcbGlbCmd{ "glb", UTF8STDSTR( _( "Export GLB (binary GLTF)" ) ), JOB_EXPORT_PCB_3D::FORMAT::GLB };
static CLI::PCB_EXPORT_3D_COMMAND exportPcbStepCmd{ "step", UTF8STDSTR( _( "Export STEP" ) ), JOB_EXPORT_PCB_3D::FORMAT::STEP };
static CLI::PCB_EXPORT_3D_COMMAND exportPcbBrepCmd{ "brep", UTF8STDSTR( _( "Export BREP" ) ), JOB_EXPORT_PCB_3D::FORMAT::BREP };
static CLI::PCB_EXPORT_3D_COMMAND exportPcbVrmlCmd{ "vrml", UTF8STDSTR( _( "Export VRML" ) ), JOB_EXPORT_PCB_3D::FORMAT::VRML };
static CLI::PCB_EXPORT_SVG_COMMAND exportPcbSvgCmd{};
static CLI::PCB_EXPORT_PDF_COMMAND exportPcbPdfCmd{};
@ -169,6 +170,7 @@ static std::vector<COMMAND_ENTRY> commandStack = {
{
&exportPcbCmd,
{
&exportPcbBrepCmd,
&exportPcbDrillCmd,
&exportPcbDxfCmd,
&exportPcbGerberCmd,

View File

@ -444,6 +444,8 @@ void DIALOG_EXPORT_STEP::onExportButton( wxCommandEvent& aEvent )
if( fn.GetExt() == FILEEXT::GltfBinaryFileExtension )
cmdK2S.Append( wxT( " glb" ) );
else if( fn.GetExt() == FILEEXT::BrepFileExtension )
cmdK2S.Append( wxT( " brep" ) );
else
cmdK2S.Append( wxT( " step" ) );

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -90,7 +90,7 @@ class DIALOG_EXPORT_STEP_BASE : public DIALOG_SHIM
public:
DIALOG_EXPORT_STEP_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Export STEP / GLTF"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
DIALOG_EXPORT_STEP_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Export STEP / BREP / GLTF"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_EXPORT_STEP_BASE();

View File

@ -118,6 +118,7 @@ wxString EXPORTER_STEP_PARAMS::GetDefaultExportExtension()
switch( m_format )
{
case EXPORTER_STEP_PARAMS::FORMAT::STEP: return wxS( "step" );
case EXPORTER_STEP_PARAMS::FORMAT::BREP: return wxS( "brep" );
case EXPORTER_STEP_PARAMS::FORMAT::GLB: return wxS( "glb" );
default: return wxEmptyString; // shouldn't happen
}
@ -129,7 +130,8 @@ wxString EXPORTER_STEP_PARAMS::GetFormatName()
{
// 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::GLB: return wxS("Binary GLTF" );
case EXPORTER_STEP_PARAMS::FORMAT::BREP: return wxS( "BREP" );
case EXPORTER_STEP_PARAMS::FORMAT::GLB: return wxS( "Binary GLTF" );
default: return wxEmptyString; // shouldn't happen
}
}
@ -529,6 +531,8 @@ 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 );
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::GLB )
success = m_pcbModel->WriteGLTF( m_outputFile );

View File

@ -63,6 +63,7 @@ public:
enum class FORMAT
{
STEP,
BREP,
GLB
};

View File

@ -33,6 +33,7 @@
#include <wx/stdpaths.h>
#include <wx/wfstream.h>
#include <wx/zipstrm.h>
#include <wx/stdstream.h>
#include <decompress.hpp>
@ -77,6 +78,7 @@
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <BRepTools.hxx>
#include <BRepAlgoAPI_Cut.hxx>
#include <BRepBndLib.hxx>
@ -1230,6 +1232,45 @@ bool STEP_PCB_MODEL::WriteSTEP( const wxString& aFileName, bool aOptimize )
}
bool STEP_PCB_MODEL::WriteBREP( const wxString& aFileName )
{
if( !isBoardOutlineValid() )
{
ReportMessage( wxString::Format( wxT( "No valid PCB assembly; cannot create output file "
"'%s'.\n" ),
aFileName ) );
return false;
}
wxFileName fn( aFileName );
// s_assy = shape tool for the source
Handle( XCAFDoc_ShapeTool ) s_assy = XCAFDoc_DocumentTool::ShapeTool( m_doc->Main() );
// retrieve all free shapes within the assembly
TDF_LabelSequence freeShapes;
s_assy->GetFreeShapes( freeShapes );
for( Standard_Integer i = 1; i <= freeShapes.Length(); ++i )
{
TDF_Label label = freeShapes.Value( i );
TopoDS_Shape shape;
m_assy->GetShape( label, shape );
wxFileName fn( aFileName );
if( freeShapes.Length() > 1 )
fn.SetName( wxString::Format( "%s_%s", fn.GetName(), i ) );
wxFFileOutputStream ffStream( fn.GetFullPath() );
wxStdOutputStream stdStream( ffStream );
BRepTools::Write( shape, stdStream, false, false, TopTools_FormatVersion_VERSION_1 );
}
return true;
}
bool STEP_PCB_MODEL::getModelLabel( const std::string& aFileNameUTF8, VECTOR3D aScale, TDF_Label& aLabel,
bool aSubstituteModels, wxString* aErrorMessage )
{

View File

@ -168,6 +168,9 @@ public:
// write the assembly model in STEP format
bool WriteSTEP( const wxString& aFileName, bool aOptimize );
// write the assembly in BREP format
bool WriteBREP( const wxString& aFileName );
/**
* Write the assembly in binary GLTF Format
*

View File

@ -133,6 +133,8 @@ int PCBNEW_JOBS_HANDLER::JobExportStep( JOB* aJob )
break;
case JOB_EXPORT_PCB_3D::FORMAT::STEP: fn.SetExt( FILEEXT::StepFileExtension );
break;
case JOB_EXPORT_PCB_3D::FORMAT::BREP: fn.SetExt( FILEEXT::BrepFileExtension );
break;
case JOB_EXPORT_PCB_3D::FORMAT::GLB: fn.SetExt( FILEEXT::GltfBinaryFileExtension );
break;
default:
@ -206,6 +208,9 @@ int PCBNEW_JOBS_HANDLER::JobExportStep( JOB* aJob )
case JOB_EXPORT_PCB_3D::FORMAT::STEP:
params.m_format = EXPORTER_STEP_PARAMS::FORMAT::STEP;
break;
case JOB_EXPORT_PCB_3D::FORMAT::BREP:
params.m_format = EXPORTER_STEP_PARAMS::FORMAT::BREP;
break;
case JOB_EXPORT_PCB_3D::FORMAT::GLB:
params.m_format = EXPORTER_STEP_PARAMS::FORMAT::GLB;
break;