Add board stackup parsing to Kicad2Step.
Fixes https://gitlab.com/kicad/code/kicad/issues/11565
(cherry picked from commit e85105a907
)
This commit is contained in:
parent
aac4f30b7d
commit
68d9b3cbf7
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
* Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -43,6 +43,13 @@
|
|||
KICADPCB::KICADPCB( const wxString& aPcbName )
|
||||
{
|
||||
m_resolver.Set3DConfigDir( wxEmptyString );
|
||||
|
||||
m_topSolderMask = wxColour( 15, 102, 15 );
|
||||
m_bottomSolderMask = wxColour( 15, 102, 15 );
|
||||
m_topSilk = wxColour( 240, 240, 240 );
|
||||
m_bottomSilk = wxColour( 240, 240, 240 );
|
||||
m_copperFinish = wxColour( 191, 155, 58 );
|
||||
|
||||
m_thickness = 1.6;
|
||||
m_pcb_model = nullptr;
|
||||
m_minDistance = MIN_DISTANCE;
|
||||
|
@ -124,9 +131,7 @@ bool KICADPCB::ReadFile( const wxString& aFileName )
|
|||
bool KICADPCB::WriteSTEP( const wxString& aFileName )
|
||||
{
|
||||
if( m_pcb_model )
|
||||
{
|
||||
return m_pcb_model->WriteSTEP( aFileName );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -136,9 +141,7 @@ bool KICADPCB::WriteSTEP( const wxString& aFileName )
|
|||
bool KICADPCB::WriteIGES( const wxString& aFileName )
|
||||
{
|
||||
if( m_pcb_model )
|
||||
{
|
||||
return m_pcb_model->WriteIGES( aFileName );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -250,6 +253,7 @@ bool KICADPCB::parseLayers( SEXPR::SEXPR* data )
|
|||
child->GetLineNumber() ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string ref;
|
||||
|
||||
if( child->GetChild( 1 )->IsSymbol() )
|
||||
|
@ -264,6 +268,146 @@ bool KICADPCB::parseLayers( SEXPR::SEXPR* data )
|
|||
}
|
||||
|
||||
|
||||
bool KICADPCB::parseStackupLayer( SEXPR::SEXPR* data )
|
||||
{
|
||||
if( data->IsList() && data->GetNumberOfChildren() >= 3 )
|
||||
{
|
||||
size_t nc = data->GetNumberOfChildren();
|
||||
SEXPR::SEXPR* child = NULL;
|
||||
std::string ref;
|
||||
std::string value;
|
||||
|
||||
for( size_t i = 1; i < nc; ++i )
|
||||
{
|
||||
child = data->GetChild( i );
|
||||
|
||||
if( child->IsList() && child->GetChild( 0 )->GetSymbol() == "type" )
|
||||
{
|
||||
if( child->GetChild( 1 )->IsSymbol() )
|
||||
ref = child->GetChild( 1 )->GetSymbol();
|
||||
else
|
||||
ref = child->GetChild( 1 )->GetString();
|
||||
}
|
||||
else if( child->IsList() && child->GetChild( 0 )->GetSymbol() == "color" )
|
||||
{
|
||||
if( child->GetChild( 1 )->IsSymbol() )
|
||||
value = child->GetChild( 1 )->GetSymbol();
|
||||
else
|
||||
value = child->GetChild( 1 )->GetString();
|
||||
}
|
||||
}
|
||||
|
||||
if( !value.empty() )
|
||||
{
|
||||
wxString colorName( value );
|
||||
wxColour color;
|
||||
|
||||
if( colorName.StartsWith( wxT( "#" ) ) )
|
||||
color = wxColour( colorName.Left( 7 ) /* drop alpha component */ );
|
||||
else if( colorName == wxT( "Green" ) )
|
||||
color = wxColour( 20, 51, 36 );
|
||||
else if( colorName == wxT( "Light Green" ) )
|
||||
color = wxColour( 91, 168, 12);
|
||||
else if( colorName == wxT( "Saturated Green" ) )
|
||||
color = wxColour( 13, 104, 11 );
|
||||
else if( colorName == wxT( "Red" ) )
|
||||
color = wxColour( 181, 19, 21 );
|
||||
else if( colorName == wxT( "Light Red" ) )
|
||||
color = wxColour( 210, 40, 14 );
|
||||
else if( colorName == wxT( "Red/Orange" ) )
|
||||
color = wxColour( 239, 53, 41 );
|
||||
else if( colorName == wxT( "Blue" ) )
|
||||
color = wxColour( 2, 59, 162 );
|
||||
else if( colorName == wxT( "Light Blue 1" ) )
|
||||
color = wxColour( 54, 79, 116 );
|
||||
else if( colorName == wxT( "Light Blue 2" ) )
|
||||
color = wxColour( 61, 85, 130 );
|
||||
else if( colorName == wxT( "Green/Blue" ) )
|
||||
color = wxColour( 21, 70, 80 );
|
||||
else if( colorName == wxT( "Black" ) )
|
||||
color = wxColour( 11, 11, 11 );
|
||||
else if( colorName == wxT( "White" ) )
|
||||
color = wxColour( 245, 245, 245 );
|
||||
else if( colorName == wxT( "Purple" ) )
|
||||
color = wxColour( 32, 2, 53 );
|
||||
else if( colorName == wxT( "Light Purple" ) )
|
||||
color = wxColour( 119, 31, 91 );
|
||||
else if( colorName == wxT( "Yellow" ) )
|
||||
color = wxColour( 194, 195, 0 );
|
||||
|
||||
if( ref == "Top Silk Screen" )
|
||||
m_topSilk = color;
|
||||
else if( ref == "Top Solder Mask" )
|
||||
m_topSolderMask = color;
|
||||
else if( ref == "Bottom Silk Screen" )
|
||||
m_bottomSilk = color;
|
||||
else if( ref == "Bottom Solder Mask" )
|
||||
m_bottomSolderMask = color;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool KICADPCB::parseStackup( SEXPR::SEXPR* data )
|
||||
{
|
||||
size_t nc = data->GetNumberOfChildren();
|
||||
SEXPR::SEXPR* child = NULL;
|
||||
|
||||
for( size_t i = 1; i < nc; ++i )
|
||||
{
|
||||
child = data->GetChild( i );
|
||||
|
||||
if( !child->IsList() )
|
||||
{
|
||||
ReportMessage( wxString::Format( wxT( "corrupt PCB file (line %d)\n" ),
|
||||
child->GetLineNumber() ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string ref;
|
||||
|
||||
if( child->GetChild( 0 )->GetSymbol() == "layer" )
|
||||
{
|
||||
parseStackupLayer( child );
|
||||
}
|
||||
else if( child->GetChild( 0 )->GetSymbol() == "copper_finish" )
|
||||
{
|
||||
if( child->GetChild( 1 )->IsSymbol() )
|
||||
ref = child->GetChild( 1 )->GetSymbol();
|
||||
else
|
||||
ref = child->GetChild( 1 )->GetString();
|
||||
|
||||
wxString finishName( ref );
|
||||
|
||||
if( finishName.EndsWith( wxT( "OSP" ) ) )
|
||||
{
|
||||
m_copperFinish = wxColour( 184, 115, 50 );
|
||||
}
|
||||
else if( finishName.EndsWith( wxT( "IG" ) )
|
||||
|| finishName.EndsWith( wxT( "gold" ) ) )
|
||||
{
|
||||
m_copperFinish = wxColour( 178, 156, 0 );
|
||||
}
|
||||
else if( finishName.StartsWith( wxT( "HAL" ) )
|
||||
|| finishName.StartsWith( wxT( "HASL" ) )
|
||||
|| finishName.EndsWith( wxT( "tin" ) )
|
||||
|| finishName.EndsWith( wxT( "nickel" ) ) )
|
||||
{
|
||||
m_copperFinish = wxColour( 160, 160, 160 );
|
||||
}
|
||||
else if( finishName.EndsWith( wxT( "silver" ) ) )
|
||||
{
|
||||
m_copperFinish = wxColour( 213, 213, 213 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int KICADPCB::GetLayerId( std::string& aLayerName )
|
||||
{
|
||||
int lid = -1;
|
||||
|
@ -323,7 +467,10 @@ bool KICADPCB::parseSetup( SEXPR::SEXPR* data )
|
|||
m_drillOrigin.y = child->GetChild( 2 )->GetDouble();
|
||||
m_hasDrillOrigin = true;
|
||||
}
|
||||
|
||||
else if( child->GetChild( 0 )->GetSymbol() == "stackup" )
|
||||
{
|
||||
parseStackup( child );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -389,15 +536,11 @@ bool KICADPCB::parsePolygon( SEXPR::SEXPR* data )
|
|||
std::unique_ptr<KICADCURVE> poly = std::make_unique<KICADCURVE>();
|
||||
|
||||
if( !poly->Read( data, CURVE_POLYGON ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// reject any curves not on the Edge.Cuts layer
|
||||
if( poly->GetLayer() != LAYER_EDGE )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
auto pts = poly->m_poly;
|
||||
|
||||
|
@ -460,23 +603,23 @@ bool KICADPCB::ComposePCB( bool aComposeVirtual, bool aSubstituteModels )
|
|||
// Determine the coordinate system reference:
|
||||
// Precedence of reference point is Drill Origin > Grid Origin > User Offset
|
||||
if( m_useDrillOrigin && m_hasDrillOrigin )
|
||||
{
|
||||
origin = m_drillOrigin;
|
||||
}
|
||||
else if( m_useGridOrigin && m_hasDrillOrigin )
|
||||
{
|
||||
origin = m_gridOrigin;
|
||||
}
|
||||
else
|
||||
{
|
||||
origin = m_origin;
|
||||
}
|
||||
|
||||
m_pcb_model = new PCBMODEL( m_pcbName );
|
||||
|
||||
// TODO: Handle when top & bottom soldermask colours are different...
|
||||
m_pcb_model->SetBoardColor( m_topSolderMask.Red() / 255.0,
|
||||
m_topSolderMask.Green() / 255.0,
|
||||
m_topSolderMask.Blue() / 255.0 );
|
||||
|
||||
m_pcb_model->SetPCBThickness( m_thickness );
|
||||
m_pcb_model->SetMinDistance( m_minDistance );
|
||||
|
||||
for( auto i : m_curves )
|
||||
for( KICADCURVE* i : m_curves )
|
||||
{
|
||||
if( CURVE_NONE == i->m_form || LAYER_EDGE != i->m_layer )
|
||||
continue;
|
||||
|
@ -501,7 +644,7 @@ bool KICADPCB::ComposePCB( bool aComposeVirtual, bool aSubstituteModels )
|
|||
m_pcb_model->AddOutlineSegment( &lcurve );
|
||||
}
|
||||
|
||||
for( auto i : m_footprints )
|
||||
for( KICADFOOTPRINT* i : m_footprints )
|
||||
i->ComposePCB( m_pcb_model, &m_resolver, origin, aComposeVirtual, aSubstituteModels );
|
||||
|
||||
ReportMessage( wxT( "Create PCB solid model\n" ) );
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -31,6 +31,7 @@
|
|||
#define KICADPCB_H
|
||||
|
||||
#include <wx/string.h>
|
||||
#include <wx/colour.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "3d_resolver.h"
|
||||
|
@ -92,6 +93,8 @@ private:
|
|||
bool parsePCB( SEXPR::SEXPR* data );
|
||||
bool parseGeneral( SEXPR::SEXPR* data );
|
||||
bool parseSetup( SEXPR::SEXPR* data );
|
||||
bool parseStackup( SEXPR::SEXPR* data );
|
||||
bool parseStackupLayer( SEXPR::SEXPR* data );
|
||||
bool parseLayers( SEXPR::SEXPR* data );
|
||||
bool parseModule( SEXPR::SEXPR* data );
|
||||
bool parseCurve( SEXPR::SEXPR* data, CURVE_TYPE aCurveType );
|
||||
|
@ -118,6 +121,11 @@ private:
|
|||
|
||||
// PCB parameters/entities
|
||||
double m_thickness;
|
||||
wxColour m_topSolderMask;
|
||||
wxColour m_bottomSolderMask; // Not currently used.
|
||||
wxColour m_topSilk; // Not currently used.
|
||||
wxColour m_bottomSilk; // Not currently used.
|
||||
wxColour m_copperFinish; // Not currently used.
|
||||
std::vector<KICADFOOTPRINT*> m_footprints;
|
||||
std::vector<KICADCURVE*> m_curves;
|
||||
wxString m_pcbName;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -673,6 +673,14 @@ void PCBMODEL::SetPCBThickness( double aThickness )
|
|||
}
|
||||
|
||||
|
||||
void PCBMODEL::SetBoardColor( double r, double g, double b )
|
||||
{
|
||||
m_boardColor[0] = r;
|
||||
m_boardColor[1] = g;
|
||||
m_boardColor[2] = b;
|
||||
}
|
||||
|
||||
|
||||
void PCBMODEL::SetMinDistance( double aDistance )
|
||||
{
|
||||
// m_minDistance2 keeps a squared distance value
|
||||
|
@ -889,16 +897,17 @@ bool PCBMODEL::CreatePCB()
|
|||
|
||||
|
||||
// color the PCB
|
||||
Handle( XCAFDoc_ColorTool ) color = XCAFDoc_DocumentTool::ColorTool( m_doc->Main () );
|
||||
Quantity_Color pcb_green( 0.06, 0.4, 0.06, Quantity_TOC_RGB );
|
||||
color->SetColor( m_pcb_label, pcb_green, XCAFDoc_ColorSurf );
|
||||
Handle( XCAFDoc_ColorTool ) colorTool = XCAFDoc_DocumentTool::ColorTool( m_doc->Main () );
|
||||
Quantity_Color color( m_boardColor[0], m_boardColor[1], m_boardColor[2], Quantity_TOC_RGB );
|
||||
|
||||
colorTool->SetColor( m_pcb_label, color, XCAFDoc_ColorSurf );
|
||||
|
||||
TopExp_Explorer topex;
|
||||
topex.Init( m_assy->GetShape( m_pcb_label ), TopAbs_SOLID );
|
||||
|
||||
while( topex.More() )
|
||||
{
|
||||
color->SetColor( topex.Current(), pcb_green, XCAFDoc_ColorSurf );
|
||||
colorTool->SetColor( topex.Current(), color, XCAFDoc_ColorSurf );
|
||||
topex.Next();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -101,6 +101,8 @@ public:
|
|||
TRIPLET aOffset, TRIPLET aOrientation, TRIPLET aScale,
|
||||
bool aSubstituteModels = true );
|
||||
|
||||
void SetBoardColor( double r, double g, double b );
|
||||
|
||||
// set the thickness of the PCB (mm); the top of the PCB shall be at Z = aThickness
|
||||
// aThickness < 0.0 == use default thickness
|
||||
// aThickness <= THICKNESS_MIN == use THICKNESS_MIN
|
||||
|
@ -156,10 +158,10 @@ private:
|
|||
int m_components; // number of successfully loaded components;
|
||||
double m_precision; // model (length unit) numeric precision
|
||||
double m_angleprec; // angle numeric precision
|
||||
double m_boardColor[3];// RGB values
|
||||
double m_thickness; // PCB thickness, mm
|
||||
|
||||
// minimum X value in curves (leftmost curve feature).
|
||||
double m_minx;
|
||||
double m_minx; // leftmost curve point
|
||||
double m_minDistance2; // minimum squared distance between items (mm)
|
||||
std::list<KICADCURVE>::iterator m_mincurve; // iterator to the leftmost curve
|
||||
|
||||
|
|
Loading…
Reference in New Issue