STEP/BREP export: ensure pad surface is a separate face.

Useful for FEM simulation.
This commit is contained in:
Alex Shvartzkop 2024-04-25 15:34:49 +03:00
parent d058e12cb5
commit da1926d723
3 changed files with 19 additions and 9 deletions

View File

@ -187,7 +187,7 @@ bool EXPORTER_STEP::buildFootprint3DShapes( FOOTPRINT* aFootprint, VECTOR2D aOri
if( m_params.m_exportTracksVias ) if( m_params.m_exportTracksVias )
{ {
if( m_pcbModel->AddPadShape( pad, aOrigin ) ) if( m_pcbModel->AddPadShape( pad, aOrigin, false ) )
hasdata = true; hasdata = true;
} }
@ -217,8 +217,6 @@ bool EXPORTER_STEP::buildFootprint3DShapes( FOOTPRINT* aFootprint, VECTOR2D aOri
// Only add shapes colliding with any matching pads // Only add shapes colliding with any matching pads
for( const SHAPE_POLY_SET::POLYGON& poly : buffer.CPolygons() ) for( const SHAPE_POLY_SET::POLYGON& poly : buffer.CPolygons() )
{ {
bool connectsToPad = false;
for( PAD* pad : padsMatchingNetFilter ) for( PAD* pad : padsMatchingNetFilter )
{ {
if( !pad->IsOnLayer( pcblayer ) ) if( !pad->IsOnLayer( pcblayer ) )

View File

@ -399,6 +399,9 @@ STEP_PCB_MODEL::STEP_PCB_MODEL( const wxString& aPcbName )
m_pcbName = aPcbName; m_pcbName = aPcbName;
m_maxError = pcbIUScale.mmToIU( ARC_TO_SEGMENT_MAX_ERROR_MM ); m_maxError = pcbIUScale.mmToIU( ARC_TO_SEGMENT_MAX_ERROR_MM );
m_fuseShapes = false; m_fuseShapes = false;
// TODO: make configurable
m_platingThickness = pcbIUScale.mmToIU( 0.025 );
} }
@ -409,7 +412,7 @@ STEP_PCB_MODEL::~STEP_PCB_MODEL()
} }
bool STEP_PCB_MODEL::AddPadShape( const PAD* aPad, const VECTOR2D& aOrigin ) bool STEP_PCB_MODEL::AddPadShape( const PAD* aPad, const VECTOR2D& aOrigin, bool aVia )
{ {
bool success = true; bool success = true;
@ -426,6 +429,15 @@ bool STEP_PCB_MODEL::AddPadShape( const PAD* aPad, const VECTOR2D& aOrigin )
double Zpos, thickness; double Zpos, thickness;
getLayerZPlacement( pcb_layer, Zpos, thickness ); getLayerZPlacement( pcb_layer, Zpos, thickness );
if( !aVia )
{
// Pad surface as a separate face for FEM simulations.
if( pcb_layer == F_Cu )
thickness += 0.01;
else if( pcb_layer == B_Cu )
thickness -= 0.01;
}
// Make a shape on copper layers // Make a shape on copper layers
std::shared_ptr<SHAPE> effShapePtr = aPad->GetEffectiveShape( pcb_layer ); std::shared_ptr<SHAPE> effShapePtr = aPad->GetEffectiveShape( pcb_layer );
@ -579,7 +591,7 @@ bool STEP_PCB_MODEL::AddViaShape( const PCB_VIA* aVia, const VECTOR2D& aOrigin )
if( AddPadHole( &dummy, aOrigin ) ) if( AddPadHole( &dummy, aOrigin ) )
{ {
if( !AddPadShape( &dummy, aOrigin ) ) if( !AddPadShape( &dummy, aOrigin, true ) )
return false; return false;
} }
@ -700,9 +712,6 @@ bool STEP_PCB_MODEL::AddPadHole( const PAD* aPad, const VECTOR2D& aOrigin )
if( aPad == nullptr || !aPad->GetDrillSize().x ) if( aPad == nullptr || !aPad->GetDrillSize().x )
return false; return false;
// TODO: make configurable
int platingThickness = aPad->GetAttribute() == PAD_ATTRIB::PTH ? pcbIUScale.mmToIU( 0.025 ) : 0;
const double margin = 0.01; // a small margin on the Z axix to be sure the hole const double margin = 0.01; // a small margin on the Z axix to be sure the hole
// is bigger than the board with copper // is bigger than the board with copper
// must be > OCC_MAX_DISTANCE_TO_MERGE_POINTS // must be > OCC_MAX_DISTANCE_TO_MERGE_POINTS
@ -719,6 +728,8 @@ bool STEP_PCB_MODEL::AddPadHole( const PAD* aPad, const VECTOR2D& aOrigin )
std::shared_ptr<SHAPE_SEGMENT> seg_hole = aPad->GetEffectiveHoleShape(); std::shared_ptr<SHAPE_SEGMENT> seg_hole = aPad->GetEffectiveHoleShape();
double boardDrill = std::min( aPad->GetDrillSize().x, aPad->GetDrillSize().y ); double boardDrill = std::min( aPad->GetDrillSize().x, aPad->GetDrillSize().y );
int platingThickness = aPad->GetAttribute() == PAD_ATTRIB::PTH ? m_platingThickness : 0;
double copperDrill = boardDrill - platingThickness * 2; double copperDrill = boardDrill - platingThickness * 2;
TopoDS_Shape copperHole, boardHole; TopoDS_Shape copperHole, boardHole;

View File

@ -85,7 +85,7 @@ public:
bool AddPadHole( const PAD* aPad, const VECTOR2D& aOrigin ); bool AddPadHole( const PAD* aPad, const VECTOR2D& aOrigin );
// add a pad shape (must be in final position) // add a pad shape (must be in final position)
bool AddPadShape( const PAD* aPad, const VECTOR2D& aOrigin ); bool AddPadShape( const PAD* aPad, const VECTOR2D& aOrigin, bool aVia );
// add a via shape // add a via shape
bool AddViaShape( const PCB_VIA* aVia, const VECTOR2D& aOrigin ); bool AddViaShape( const PCB_VIA* aVia, const VECTOR2D& aOrigin );
@ -232,6 +232,7 @@ private:
TDF_Label m_assy_label; TDF_Label m_assy_label;
bool m_hasPCB; // set true if CreatePCB() has been invoked bool m_hasPCB; // set true if CreatePCB() has been invoked
bool m_fuseShapes; // fuse geometry together bool m_fuseShapes; // fuse geometry together
int m_platingThickness; // plating thickness for TH pads/vias
std::vector<TDF_Label> m_pcb_labels; // labels for the PCB model (one by main outline) std::vector<TDF_Label> m_pcb_labels; // labels for the PCB model (one by main outline)
MODEL_MAP m_models; // map of file names to model labels MODEL_MAP m_models; // map of file names to model labels
int m_components; // number of successfully loaded components; int m_components; // number of successfully loaded components;