Be more careful about thermal reliefs for pads on different layers.
Fixes: lp:1605049 * https://bugs.launchpad.net/kicad/+bug/1605049
This commit is contained in:
parent
f30cd67411
commit
6da11de5e0
|
@ -360,9 +360,6 @@ bool hasThermalConnection( D_PAD* pad, const ZONE_CONTAINER* aZone )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !pad->IsOnLayer( aZone->GetLayer() ) )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if( pad->GetNetCode() != aZone->GetNetCode() || pad->GetNetCode() <= 0 )
|
if( pad->GetNetCode() != aZone->GetNetCode() || pad->GetNetCode() <= 0 )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -374,6 +371,21 @@ bool hasThermalConnection( D_PAD* pad, const ZONE_CONTAINER* aZone )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup aDummyPad to have the same size and shape of aPad's hole. This allows us to create
|
||||||
|
* thermal reliefs and clearances for holes using the pad code.
|
||||||
|
*/
|
||||||
|
static void setupDummyPadForHole( const D_PAD* aPad, D_PAD& aDummyPad )
|
||||||
|
{
|
||||||
|
aDummyPad.SetNetCode( aPad->GetNetCode() );
|
||||||
|
aDummyPad.SetSize( aPad->GetDrillSize() );
|
||||||
|
aDummyPad.SetOrientation( aPad->GetOrientation() );
|
||||||
|
aDummyPad.SetShape( aPad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ? PAD_SHAPE_OVAL
|
||||||
|
: PAD_SHAPE_CIRCLE );
|
||||||
|
aDummyPad.SetPosition( aPad->GetPosition() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a knockout for a pad. The knockout is 'aGap' larger than the pad (which might be
|
* Add a knockout for a pad. The knockout is 'aGap' larger than the pad (which might be
|
||||||
* either the thermal clearance or the electrical clearance).
|
* either the thermal clearance or the electrical clearance).
|
||||||
|
@ -467,12 +479,32 @@ void ZONE_FILLER::knockoutThermalReliefs( const ZONE_CONTAINER* aZone, SHAPE_POL
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET holes;
|
SHAPE_POLY_SET holes;
|
||||||
|
|
||||||
|
// Use a dummy pad to calculate relief when a pad has a hole but is not on the zone's
|
||||||
|
// copper layer. The dummy pad has the size and shape of the original pad's hole. We have
|
||||||
|
// to give it a parent because some functions expect a non-null parent to find clearance
|
||||||
|
// data, etc.
|
||||||
|
MODULE dummymodule( m_board );
|
||||||
|
D_PAD dummypad( &dummymodule );
|
||||||
|
|
||||||
for( auto module : m_board->Modules() )
|
for( auto module : m_board->Modules() )
|
||||||
{
|
{
|
||||||
for( auto pad : module->Pads() )
|
for( auto pad : module->Pads() )
|
||||||
{
|
{
|
||||||
if( hasThermalConnection( pad, aZone ) )
|
if( !hasThermalConnection( pad, aZone ) )
|
||||||
addKnockout( pad, aZone->GetThermalReliefGap( pad ), holes );
|
continue;
|
||||||
|
|
||||||
|
// If the pad isn't on the current layer but has a hole, knock out a thermal relief
|
||||||
|
// for the hole.
|
||||||
|
if( !pad->IsOnLayer( aZone->GetLayer() ) )
|
||||||
|
{
|
||||||
|
if( pad->GetDrillSize().x == 0 && pad->GetDrillSize().y == 0 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
setupDummyPadForHole( pad, dummypad );
|
||||||
|
pad = &dummypad;
|
||||||
|
}
|
||||||
|
|
||||||
|
addKnockout( pad, aZone->GetThermalReliefGap( pad ), holes );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,23 +545,10 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE_CONTAINER* aZone, SHAPE_
|
||||||
{
|
{
|
||||||
if( !pad->IsOnLayer( aZone->GetLayer() ) )
|
if( !pad->IsOnLayer( aZone->GetLayer() ) )
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* Test for pads that are on top or bottom only and have a hole.
|
|
||||||
* There are curious pads but they can be used for some components that are
|
|
||||||
* inside the board (in fact inside the hole. Some photo diodes and Leds are
|
|
||||||
* like this)
|
|
||||||
*/
|
|
||||||
if( pad->GetDrillSize().x == 0 && pad->GetDrillSize().y == 0 )
|
if( pad->GetDrillSize().x == 0 && pad->GetDrillSize().y == 0 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Use a dummy pad to calculate a hole shape that have the same dimension as
|
setupDummyPadForHole( pad, dummypad );
|
||||||
// the pad hole
|
|
||||||
dummypad.SetSize( pad->GetDrillSize() );
|
|
||||||
dummypad.SetOrientation( pad->GetOrientation() );
|
|
||||||
dummypad.SetShape( pad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ? PAD_SHAPE_OVAL
|
|
||||||
: PAD_SHAPE_CIRCLE );
|
|
||||||
dummypad.SetPosition( pad->GetPosition() );
|
|
||||||
|
|
||||||
pad = &dummypad;
|
pad = &dummypad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -852,6 +871,10 @@ void ZONE_FILLER::buildThermalSpokes( const ZONE_CONTAINER* aZone,
|
||||||
if( !hasThermalConnection( pad, aZone ) )
|
if( !hasThermalConnection( pad, aZone ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// We currently only connect to pads, not pad holes
|
||||||
|
if( !pad->IsOnLayer( aZone->GetLayer() ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
int thermalReliefGap = aZone->GetThermalReliefGap( pad );
|
int thermalReliefGap = aZone->GetThermalReliefGap( pad );
|
||||||
|
|
||||||
// Calculate thermal bridge half width
|
// Calculate thermal bridge half width
|
||||||
|
|
Loading…
Reference in New Issue