Watch out for VVIAs.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/16339
This commit is contained in:
Jeff Young 2023-12-12 15:44:58 +00:00
parent d3ab677197
commit de070a1d62
1 changed files with 45 additions and 43 deletions

View File

@ -114,45 +114,34 @@ public:
else if( m_linkedItems.Size() > 2 && m_linkedItems.Count( SEGMENT_T | ARC_T ) == 2 ) else if( m_linkedItems.Size() > 2 && m_linkedItems.Count( SEGMENT_T | ARC_T ) == 2 )
{ {
if( !aAllowLockedSegs ) if( !aAllowLockedSegs )
{
return false; return false;
}
// There will be multiple VVIAs on joints between two locked segments, because we // There will be multiple VVIAs on joints between two locked segments, because we
// naively add a VVIA to each end of a locked segment. // naively add a VVIA to each end of a locked segment.
else if( ( m_linkedItems.Size() - m_linkedItems.Count( SEGMENT_T | ARC_T ) ) const LINKED_ITEM* seg1 = nullptr;
== m_linkedItems.Count( VIA_T ) ) const LINKED_ITEM* seg2 = nullptr;
for( const ITEM* item : m_linkedItems.CItems() )
{ {
const LINKED_ITEM* seg1 = nullptr; if( item->IsVirtual() )
const LINKED_ITEM* seg2 = nullptr; continue;
const VIA* via = nullptr;
bool hasNonVirtualVia = false;
for( const ITEM* item : m_linkedItems.CItems() ) if( item->Kind() == VIA_T )
{ {
if( item->Kind() == VIA_T )
{
via = static_cast<const VIA*>( item );
hasNonVirtualVia |= !via->IsVirtual();
}
else if( item->Kind() == SEGMENT_T || item->Kind() == ARC_T )
{
if( !seg1 )
seg1 = static_cast<const LINKED_ITEM*>( item );
else
seg2 = static_cast<const LINKED_ITEM*>( item );
}
}
if( !via || hasNonVirtualVia )
return false; return false;
}
// This compiles away in release builds so we still need to check it below else if( item->Kind() == SEGMENT_T || item->Kind() == ARC_T )
// to prevent segfaults in release builds. {
assert( seg1 && seg2 ); if( !seg1 )
seg1 = static_cast<const LINKED_ITEM*>( item );
return ( seg1 && seg2 ) ? seg1->Width() == seg2->Width() : false; else
seg2 = static_cast<const LINKED_ITEM*>( item );
}
} }
wxCHECK( seg1 && seg2, false );
return seg1->Width() == seg2->Width();
} }
return false; return false;
@ -166,17 +155,13 @@ public:
for( const ITEM* item : m_linkedItems.CItems() ) for( const ITEM* item : m_linkedItems.CItems() )
{ {
if( item->Kind() == VIA_T ) if( item->IsVirtual() )
{ continue;
if( static_cast<const VIA*>( item )->IsVirtual() )
continue;
if( item->Kind() == VIA_T )
vias++; vias++;
}
else if( item->Kind() == SEGMENT_T || item->Kind() == ARC_T ) else if( item->Kind() == SEGMENT_T || item->Kind() == ARC_T )
{
segs++; segs++;
}
realItems++; realItems++;
} }
@ -191,14 +176,31 @@ public:
bool IsTraceWidthChange() const bool IsTraceWidthChange() const
{ {
if( m_linkedItems.Size() != 2 ) if( m_linkedItems.Count( SEGMENT_T ) != 2 )
return false; return false;
if( m_linkedItems.Count( SEGMENT_T ) != 2) const LINKED_ITEM* seg1 = nullptr;
return false; const LINKED_ITEM* seg2 = nullptr;
SEGMENT* seg1 = static_cast<SEGMENT*>( m_linkedItems[0] ); for( const ITEM* item : m_linkedItems.CItems() )
SEGMENT* seg2 = static_cast<SEGMENT*>( m_linkedItems[1] ); {
if( item->IsVirtual() )
continue;
if( item->Kind() == VIA_T )
{
return false;
}
else if( item->Kind() == SEGMENT_T || item->Kind() == ARC_T )
{
if( !seg1 )
seg1 = static_cast<const LINKED_ITEM*>( item );
else
seg2 = static_cast<const LINKED_ITEM*>( item );
}
}
wxCHECK( seg1 && seg2, false );
return seg1->Width() != seg2->Width(); return seg1->Width() != seg2->Width();
} }