eagle: Handle DRC rule-based pad shapes

Circles and Squares are handled correctly.  Octagons are converted to
circles.  Pad 1 is identified by the "1" string in the Eagle name.

Fixes: lp:1784126
* https://bugs.launchpad.net/kicad/+bug/1784126
This commit is contained in:
Seth Hillbrand 2019-02-04 02:46:10 +01:00
parent 1d09f84303
commit d7272b7f5e
3 changed files with 57 additions and 2 deletions

View File

@ -698,6 +698,7 @@ struct EPAD : public EPAD_COMMON
// for shape: (square | round | octagon | long | offset)
enum {
UNDEF = -1,
SQUARE,
ROUND,
OCTAGON,

View File

@ -150,6 +150,13 @@ void ERULES::parse( wxXmlNode* aRules )
else if( name == "srMaxRoundness" )
srMaxRoundness = parseEagle( value );
else if( name == "psTop" )
psTop = wxAtoi( value );
else if( name == "psBottom" )
psBottom = wxAtoi( value );
else if( name == "psFirst" )
psFirst = wxAtoi( value );
else if( name == "rvPadTop" )
value.ToDouble( &rvPadTop );
else if( name == "rlMinPadTop" )
@ -1431,14 +1438,28 @@ void EAGLE_PLUGIN::packagePad( MODULE* aModule, wxXmlNode* aTree ) const
{
// this is thru hole technology here, no SMDs
EPAD e( aTree );
int shape = EPAD::UNDEF;
D_PAD* pad = new D_PAD( aModule );
aModule->PadsList().PushBack( pad );
transferPad( e, pad );
if( pad->GetName() == wxT( "1" ) && m_rules->psFirst != EPAD::UNDEF )
shape = m_rules->psFirst;
else if( aModule->GetLayer() == F_Cu && m_rules->psTop != EPAD::UNDEF )
shape = m_rules->psTop;
else if( aModule->GetLayer() == B_Cu && m_rules->psBottom != EPAD::UNDEF )
shape = m_rules->psBottom;
pad->SetDrillSize( wxSize( e.drill.ToPcbUnits(), e.drill.ToPcbUnits() ) );
pad->SetLayerSet( LSET::AllCuMask().set( B_Mask ).set( F_Mask ) );
if( shape == EPAD::ROUND || shape == EPAD::SQUARE )
e.shape = shape;
if( shape == EPAD::OCTAGON )
e.shape = EPAD::ROUND;
if( e.shape )
{
switch( *e.shape )
@ -1799,11 +1820,36 @@ void EAGLE_PLUGIN::packageSMD( MODULE* aModule, wxXmlNode* aTree ) const
if( !IsCopperLayer( layer ) )
return;
bool shape_set = false;
int shape = EPAD::UNDEF;
D_PAD* pad = new D_PAD( aModule );
aModule->PadsList().PushBack( pad );
transferPad( e, pad );
pad->SetShape( PAD_SHAPE_RECT );
if( pad->GetName() == wxT( "1" ) && m_rules->psFirst != EPAD::UNDEF )
shape = m_rules->psFirst;
else if( layer == F_Cu && m_rules->psTop != EPAD::UNDEF )
shape = m_rules->psTop;
else if( layer == B_Cu && m_rules->psBottom != EPAD::UNDEF )
shape = m_rules->psBottom;
switch( shape )
{
case EPAD::ROUND:
case EPAD::OCTAGON:
shape_set = true;
pad->SetShape( PAD_SHAPE_CIRCLE );
break;
case EPAD::SQUARE:
shape_set = true;
pad->SetShape( PAD_SHAPE_RECT );
break;
default:
pad->SetShape( PAD_SHAPE_RECT );
}
pad->SetAttribute( PAD_ATTRIB_SMD );
wxSize padSize( e.dx.ToPcbUnits(), e.dy.ToPcbUnits() );
@ -1824,7 +1870,7 @@ void EAGLE_PLUGIN::packageSMD( MODULE* aModule, wxXmlNode* aTree ) const
int roundRadius = eagleClamp( m_rules->srMinRoundness * 2,
(int)( minPadSize * m_rules->srRoundness ), m_rules->srMaxRoundness * 2 );
if( e.roundness || roundRadius > 0 )
if( !shape_set && ( e.roundness || roundRadius > 0 ) )
{
double roundRatio = (double) roundRadius / minPadSize / 2.0;

View File

@ -56,6 +56,10 @@ struct ERULES
int mlMinCreamFrame; ///< solder paste mask, minimum size (Eagle mils, here nanometers)
int mlMaxCreamFrame; ///< solder paste mask, maximum size (Eagle mils, here nanometers)
int psTop; ///< Shape of the top pads
int psBottom; ///< Shape of the bottom pads
int psFirst; ///< Shape of the first pads
double srRoundness; ///< corner rounding ratio for SMD pads (percentage)
int srMinRoundness; ///< corner rounding radius, minimum size (Eagle mils, here nanometers)
int srMaxRoundness; ///< corner rounding radius, maximum size (Eagle mils, here nanometers)
@ -83,6 +87,10 @@ struct ERULES
mlMinCreamFrame ( Mils2iu( 0.0 ) ),
mlMaxCreamFrame ( Mils2iu( 0.0 ) ),
psTop ( EPAD::UNDEF ),
psBottom ( EPAD::UNDEF ),
psFirst ( EPAD::UNDEF ),
srRoundness ( 0.0 ),
srMinRoundness ( Mils2iu( 0.0 ) ),
srMaxRoundness ( Mils2iu( 0.0 ) ),