Properly interpret Altium pour index and pad connect style

This commit is contained in:
Jon Evans 2020-05-10 13:30:03 -04:00
parent 0a38ebcc41
commit a073ae5712
4 changed files with 82 additions and 5 deletions

View File

@ -435,7 +435,10 @@ APOLYGON6::APOLYGON6( ALTIUM_PARSER& aReader )
minprimlength = ALTIUM_PARSER::PropertiesReadKicadUnit( properties, "MINPRIMLENGTH", "0mil" );
useoctagons = ALTIUM_PARSER::PropertiesReadBool( properties, "USEOCTAGONS", false );
pourindex = ALTIUM_PARSER::PropertiesReadInt( properties, "POURINDEX", 0 );
wxString hatchstyleraw = ALTIUM_PARSER::PropertiesReadString( properties, "HATCHSTYLE", "" );
if( hatchstyleraw == "Solid" )
{
hatchstyle = ALTIUM_POLYGON_HATCHSTYLE::SOLID;
@ -540,6 +543,17 @@ ARULE6::ARULE6( ALTIUM_PARSER& aReader )
properties, "RELIEFCONDUCTORWIDTH", "10mil" );
polygonconnectReliefentries =
ALTIUM_PARSER::PropertiesReadInt( properties, "RELIEFENTRIES", 4 );
wxString style = ALTIUM_PARSER::PropertiesReadString( properties, "CONNECTSTYLE", "" );
if( style == "Direct" )
polygonconnectStyle = ALTIUM_CONNECT_STYLE::DIRECT;
else if( style == "Relief" )
polygonconnectStyle = ALTIUM_CONNECT_STYLE::RELIEF;
else if( style == "NoConnect" )
polygonconnectStyle = ALTIUM_CONNECT_STYLE::NONE;
else
polygonconnectStyle = ALTIUM_CONNECT_STYLE::UNKNOWN;
}
else
{

View File

@ -106,6 +106,14 @@ enum class ALTIUM_RULE_KIND
POLYGON_CONNECT = 9,
};
enum class ALTIUM_CONNECT_STYLE
{
UNKNOWN = 0,
DIRECT = 1,
RELIEF = 2,
NONE = 3
};
enum class ALTIUM_RECORD
{
ARC = 1,
@ -427,6 +435,9 @@ struct APOLYGON6
int32_t minprimlength;
bool useoctagons;
// Note: Altium pour index is the opposite of KiCad zone priority!
int32_t pourindex;
std::vector<ALTIUM_VERTICE> vertices;
explicit APOLYGON6( ALTIUM_PARSER& aReader );
@ -450,9 +461,10 @@ struct ARULE6
int planeclearanceClearance;
// ALTIUM_RULE_KIND::POLYGON_CONNECT
int32_t polygonconnectAirgapwidth;
int32_t polygonconnectReliefconductorwidth;
int polygonconnectReliefentries;
int32_t polygonconnectAirgapwidth;
int32_t polygonconnectReliefconductorwidth;
int polygonconnectReliefentries;
ALTIUM_CONNECT_STYLE polygonconnectStyle;
// TODO: implement different types of rules we need to parse

View File

@ -330,8 +330,9 @@ PCB_LAYER_ID ALTIUM_PCB::GetKicadLayer( ALTIUM_LAYER aAltiumLayer ) const
ALTIUM_PCB::ALTIUM_PCB( BOARD* aBoard )
{
m_board = aBoard;
m_num_nets = 0;
m_board = aBoard;
m_num_nets = 0;
m_highest_pour_index = 0;
}
ALTIUM_PCB::~ALTIUM_PCB()
@ -453,6 +454,27 @@ void ALTIUM_PCB::Parse( const CFB::CompoundFileReader& aReader,
}
}
// fixup zone priorities since Altium stores them in the opposite order
for( auto& zone : m_polygons )
{
if( !zone )
continue;
// Altium "fills" - not poured in Altium
if( zone->GetPriority() == 1000 )
{
// Unlikely, but you never know
if( m_highest_pour_index >= 1000 )
zone->SetPriority( m_highest_pour_index + 1 );
continue;
}
int priority = m_highest_pour_index - zone->GetPriority();
zone->SetPriority( priority >= 0 ? priority : 0 );
}
// change priority of outer zone to zero
for( auto& zone : m_outer_plane )
{
@ -1249,6 +1271,10 @@ void ALTIUM_PCB::ParsePolygons6Data(
zone->SetLayer( klayer );
zone->SetPosition( elem.vertices.at( 0 ).position );
zone->SetLocked( elem.locked );
zone->SetPriority( elem.pourindex > 0 ? elem.pourindex : 0 );
if( elem.pourindex > m_highest_pour_index )
m_highest_pour_index = elem.pourindex;
for( auto& vertice : elem.vertices )
{
@ -1257,17 +1283,39 @@ void ALTIUM_PCB::ParsePolygons6Data(
// TODO: more flexible rule parsing
const ARULE6* clearanceRule = GetRuleDefault( ALTIUM_RULE_KIND::PLANE_CLEARANCE );
if( clearanceRule != nullptr )
{
zone->SetZoneClearance( clearanceRule->planeclearanceClearance );
}
const ARULE6* polygonConnectRule = GetRuleDefault( ALTIUM_RULE_KIND::POLYGON_CONNECT );
if( polygonConnectRule != nullptr )
{
switch( polygonConnectRule->polygonconnectStyle )
{
case ALTIUM_CONNECT_STYLE::DIRECT:
zone->SetPadConnection( ZONE_CONNECTION::FULL );
break;
case ALTIUM_CONNECT_STYLE::NONE:
zone->SetPadConnection( ZONE_CONNECTION::NONE );
break;
default:
case ALTIUM_CONNECT_STYLE::RELIEF:
zone->SetPadConnection( ZONE_CONNECTION::THERMAL );
break;
}
// TODO: correct variables?
zone->SetThermalReliefCopperBridge(
polygonConnectRule->polygonconnectReliefconductorwidth );
zone->SetThermalReliefGap( polygonConnectRule->polygonconnectAirgapwidth );
if( polygonConnectRule->polygonconnectReliefconductorwidth < zone->GetMinThickness() )
zone->SetMinThickness( polygonConnectRule->polygonconnectReliefconductorwidth );
}
if( IsAltiumLayerAPlane( elem.layer ) )

View File

@ -191,6 +191,9 @@ private:
std::map<ALTIUM_RULE_KIND, std::vector<ARULE6>> m_rules;
std::map<ALTIUM_LAYER, ZONE_CONTAINER*> m_outer_plane;
/// Altium stores pour order across all layers
int m_highest_pour_index;
};