Don't do a sided-test on a footprint which has no side.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15284
This commit is contained in:
parent
d9abaa23a4
commit
cab351d249
|
@ -271,10 +271,10 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* aTestItem, void* aTestData
|
||||||
|
|
||||||
if( footprint )
|
if( footprint )
|
||||||
{
|
{
|
||||||
if( m_Guide->IgnoreFootprintsOnBack() && ( footprint->GetLayer() == B_Cu ) )
|
if( m_Guide->IgnoreFootprintsOnBack() && footprint->GetSide() == B_Cu )
|
||||||
return INSPECT_RESULT::CONTINUE;
|
return INSPECT_RESULT::CONTINUE;
|
||||||
|
|
||||||
if( m_Guide->IgnoreFootprintsOnFront() && ( footprint->GetLayer() == F_Cu ) )
|
if( m_Guide->IgnoreFootprintsOnFront() && footprint->GetSide() == F_Cu )
|
||||||
return INSPECT_RESULT::CONTINUE;
|
return INSPECT_RESULT::CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -217,10 +217,13 @@ void DIALOG_BOARD_STATISTICS::getDataFromPCB()
|
||||||
{
|
{
|
||||||
if( ( footprint->GetAttributes() & line.attribute_mask ) == line.attribute_value )
|
if( ( footprint->GetAttributes() & line.attribute_mask ) == line.attribute_value )
|
||||||
{
|
{
|
||||||
if( footprint->IsFlipped() )
|
switch( footprint->GetSide() )
|
||||||
line.backSideQty++;
|
{
|
||||||
else
|
case F_Cu: line.frontSideQty++; break;
|
||||||
line.frontSideQty++;
|
case B_Cu: line.backSideQty++; break;
|
||||||
|
default: /* unsided: user-layers only, etc. */ break;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -989,6 +989,7 @@ const BOX2I FOOTPRINT::GetBoundingBox( bool aIncludeText, bool aIncludeInvisible
|
||||||
std::vector<PCB_TEXT*> texts;
|
std::vector<PCB_TEXT*> texts;
|
||||||
const BOARD* board = GetBoard();
|
const BOARD* board = GetBoard();
|
||||||
bool isFPEdit = board && board->IsFootprintHolder();
|
bool isFPEdit = board && board->IsFootprintHolder();
|
||||||
|
PCB_LAYER_ID footprintSide = GetSide();
|
||||||
|
|
||||||
if( board )
|
if( board )
|
||||||
{
|
{
|
||||||
|
@ -1029,8 +1030,9 @@ const BOX2I FOOTPRINT::GetBoundingBox( bool aIncludeText, bool aIncludeInvisible
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're not including text then drop annotations as well
|
// If we're not including text then drop annotations as well -- unless, of course, it's
|
||||||
if( !aIncludeText )
|
// an unsided footprint -- in which case it's likely to be nothing *but* annotations.
|
||||||
|
if( !aIncludeText && footprintSide != UNDEFINED_LAYER )
|
||||||
{
|
{
|
||||||
if( BaseType( item->Type() ) == PCB_DIMENSION_T )
|
if( BaseType( item->Type() ) == PCB_DIMENSION_T )
|
||||||
continue;
|
continue;
|
||||||
|
@ -1287,7 +1289,13 @@ void FOOTPRINT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_I
|
||||||
}
|
}
|
||||||
|
|
||||||
// aFrame is the board editor:
|
// aFrame is the board editor:
|
||||||
aList.emplace_back( _( "Board Side" ), IsFlipped() ? _( "Back (Flipped)" ) : _( "Front" ) );
|
|
||||||
|
switch( GetSide() )
|
||||||
|
{
|
||||||
|
case F_Cu: aList.emplace_back( _( "Board Side" ), _( "Front" ) ); break;
|
||||||
|
case B_Cu: aList.emplace_back( _( "Board Side" ), _( "Back (Flipped)" ) ); break;
|
||||||
|
default: /* unsided: user-layers only, etc. */ break;
|
||||||
|
}
|
||||||
|
|
||||||
auto addToken = []( wxString* aStr, const wxString& aAttr )
|
auto addToken = []( wxString* aStr, const wxString& aAttr )
|
||||||
{
|
{
|
||||||
|
@ -1334,6 +1342,37 @@ void FOOTPRINT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_I
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PCB_LAYER_ID FOOTPRINT::GetSide() const
|
||||||
|
{
|
||||||
|
if( const BOARD* board = GetBoard() )
|
||||||
|
{
|
||||||
|
if( board->IsFootprintHolder() )
|
||||||
|
return UNDEFINED_LAYER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test pads first; they're the most likely to return a quick answer.
|
||||||
|
for( PAD* pad : m_pads )
|
||||||
|
{
|
||||||
|
if( ( LSET::SideSpecificMask() & pad->GetLayerSet() ).any() )
|
||||||
|
return GetLayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
for( BOARD_ITEM* item : m_drawings )
|
||||||
|
{
|
||||||
|
if( LSET::SideSpecificMask().test( item->GetLayer() ) )
|
||||||
|
return GetLayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
for( ZONE* zone : m_zones )
|
||||||
|
{
|
||||||
|
if( ( LSET::SideSpecificMask() & zone->GetLayerSet() ).any() )
|
||||||
|
return GetLayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
return UNDEFINED_LAYER;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool FOOTPRINT::IsOnLayer( PCB_LAYER_ID aLayer ) const
|
bool FOOTPRINT::IsOnLayer( PCB_LAYER_ID aLayer ) const
|
||||||
{
|
{
|
||||||
// If we have any pads, fall back on normal checking
|
// If we have any pads, fall back on normal checking
|
||||||
|
|
|
@ -350,6 +350,12 @@ public:
|
||||||
*/
|
*/
|
||||||
bool IsFlipped() const { return GetLayer() == B_Cu; }
|
bool IsFlipped() const { return GetLayer() == B_Cu; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use instead of IsFlipped() when you also need to account for unsided footprints (those
|
||||||
|
* purely on user-layers, etc.).
|
||||||
|
*/
|
||||||
|
PCB_LAYER_ID GetSide() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copydoc BOARD_ITEM::IsOnLayer
|
* @copydoc BOARD_ITEM::IsOnLayer
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2605,16 +2605,20 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili
|
||||||
|
|
||||||
if( aItem->Type() == PCB_FOOTPRINT_T )
|
if( aItem->Type() == PCB_FOOTPRINT_T )
|
||||||
{
|
{
|
||||||
|
const FOOTPRINT* footprint = static_cast<const FOOTPRINT*>( aItem );
|
||||||
|
|
||||||
// In footprint editor, we do not want to select the footprint itself.
|
// In footprint editor, we do not want to select the footprint itself.
|
||||||
if( m_isFootprintEditor )
|
if( m_isFootprintEditor )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Allow selection of footprints if some part of the footprint is visible.
|
// Allow selection of footprints if some part of the footprint is visible.
|
||||||
const FOOTPRINT* footprint = static_cast<const FOOTPRINT*>( aItem );
|
if( footprint->GetSide() != UNDEFINED_LAYER && !m_skip_heuristics )
|
||||||
|
{
|
||||||
LSET boardSide = footprint->IsFlipped() ? LSET::BackMask() : LSET::FrontMask();
|
LSET boardSide = footprint->IsFlipped() ? LSET::BackMask() : LSET::FrontMask();
|
||||||
|
|
||||||
if( !( visibleLayers() & boardSide ).any() && !m_skip_heuristics )
|
if( !( visibleLayers() & boardSide ).any() )
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// If the footprint has no items except the reference and value fields, include the
|
// If the footprint has no items except the reference and value fields, include the
|
||||||
// footprint in the selections.
|
// footprint in the selections.
|
||||||
|
|
Loading…
Reference in New Issue