Fix crash when attempting to tune discontinuous lines

Also correctly find the tuning path through arcs

https://gitlab.com/kicad/code/kicad/-/issues/8131
This commit is contained in:
Jon Evans 2021-04-06 09:07:00 -04:00
parent 235688e459
commit 9f957d3e08
1 changed files with 39 additions and 37 deletions

View File

@ -248,23 +248,30 @@ bool TOPOLOGY::followTrivialPath( LINE* aLine, bool aLeft, ITEM_SET& aSet,
const ITEM_SET TOPOLOGY::AssembleTrivialPath( ITEM* aStart, const ITEM_SET TOPOLOGY::AssembleTrivialPath( ITEM* aStart,
std::pair<JOINT*, JOINT*>* aTerminalJoints ) std::pair<JOINT*, JOINT*>* aTerminalJoints )
{ {
ITEM_SET path; ITEM_SET path;
std::set<ITEM*> visited; std::set<ITEM*> visited;
SEGMENT* seg; LINKED_ITEM* seg = nullptr;
VIA* via;
seg = dyn_cast<SEGMENT*>( aStart ); if( aStart->Kind() == ITEM::VIA_T )
if(!seg && (via = dyn_cast<VIA*>( aStart ) ) )
{ {
JOINT *jt = m_world->FindJoint( via->Pos(), via ); VIA* via = static_cast<VIA*>( aStart );
JOINT* jt = m_world->FindJoint( via->Pos(), via );
if( !jt->IsNonFanoutVia() ) if( !jt->IsNonFanoutVia() )
return ITEM_SET(); return ITEM_SET();
for( const auto& entry : jt->Links().Items() ) for( const ITEM_SET::ENTRY& entry : jt->Links().Items() )
if( ( seg = dyn_cast<SEGMENT*>( entry.item ) ) ) {
if( entry.item->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T ) )
{
seg = static_cast<LINKED_ITEM*>( entry.item );
break; break;
}
}
}
else if( aStart->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T ) )
{
seg = static_cast<LINKED_ITEM*>( aStart );
} }
if( !seg ) if( !seg )
@ -298,41 +305,36 @@ const ITEM_SET TOPOLOGY::AssembleTuningPath( ITEM* aStart, SOLID** aStartPad, SO
PAD* padA = nullptr; PAD* padA = nullptr;
PAD* padB = nullptr; PAD* padB = nullptr;
for( ITEM* item : joints.first->LinkList() ) auto getPadFromJoint =
{ []( JOINT* aJoint, PAD** aTargetPad, SOLID** aTargetSolid )
if( item->OfKind( ITEM::SOLID_T ) )
{
BOARD_ITEM* bi = static_cast<SOLID*>( item )->Parent();
if( bi->Type() == PCB_PAD_T )
{ {
padA = static_cast<PAD*>( bi ); for( ITEM* item : aJoint->LinkList() )
{
if( item->OfKind( ITEM::SOLID_T ) )
{
BOARD_ITEM* bi = static_cast<SOLID*>( item )->Parent();
if( aStartPad ) if( bi->Type() == PCB_PAD_T )
*aStartPad = static_cast<SOLID*>( item ); {
} *aTargetPad = static_cast<PAD*>( bi );
break; if( aTargetSolid )
} *aTargetSolid = static_cast<SOLID*>( item );
} }
for( ITEM* item : joints.second->LinkList() ) break;
{ }
if( item->OfKind( ITEM::SOLID_T ) ) }
{ };
BOARD_ITEM* bi = static_cast<SOLID*>( item )->Parent();
if( bi->Type() == PCB_PAD_T ) if( joints.first )
{ getPadFromJoint( joints.first, &padA, aStartPad );
padB = static_cast<PAD*>( bi );
if( aEndPad ) if( joints.second )
*aEndPad = static_cast<SOLID*>( item ); getPadFromJoint( joints.second, &padB, aEndPad );
}
break; if( !padA && !padB )
} return initialPath;
}
auto clipLineToPad = auto clipLineToPad =
[]( SHAPE_LINE_CHAIN& aLine, PAD* aPad, bool aForward = true ) []( SHAPE_LINE_CHAIN& aLine, PAD* aPad, bool aForward = true )