Support arcs in Break Track.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/16712
This commit is contained in:
parent
a46d409ec6
commit
ed00cb3304
|
@ -2,7 +2,7 @@
|
|||
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||
*
|
||||
* Copyright (C) 2013-2017 CERN
|
||||
* Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
|
@ -1292,6 +1292,38 @@ bool LINE_PLACER::SplitAdjacentSegments( NODE* aNode, ITEM* aSeg, const VECTOR2I
|
|||
}
|
||||
|
||||
|
||||
bool LINE_PLACER::SplitAdjacentArcs( NODE* aNode, ITEM* aArc, const VECTOR2I& aP )
|
||||
{
|
||||
if( !aArc )
|
||||
return false;
|
||||
|
||||
if( !aArc->OfKind( ITEM::ARC_T ) )
|
||||
return false;
|
||||
|
||||
const JOINT* jt = aNode->FindJoint( aP, aArc );
|
||||
|
||||
if( jt && jt->LinkCount() >= 1 )
|
||||
return false;
|
||||
|
||||
ARC* a_old = static_cast<ARC*>( aArc );
|
||||
const SHAPE_ARC& o_arc = a_old->Arc();
|
||||
|
||||
std::unique_ptr<ARC> a_new[2] = { Clone( *a_old ), Clone( *a_old ) };
|
||||
|
||||
a_new[0]->Arc().ConstructFromStartEndCenter( o_arc.GetP0(), aP, o_arc.GetCenter(),
|
||||
o_arc.IsClockwise(), o_arc.GetWidth() );
|
||||
|
||||
a_new[1]->Arc().ConstructFromStartEndCenter( aP, o_arc.GetP1(), o_arc.GetCenter(),
|
||||
o_arc.IsClockwise(), o_arc.GetWidth() );
|
||||
|
||||
aNode->Remove( a_old );
|
||||
aNode->Add( std::move( a_new[0] ), true );
|
||||
aNode->Add( std::move( a_new[1] ), true );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool LINE_PLACER::SetLayer( int aLayer )
|
||||
{
|
||||
if( m_idle )
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||
*
|
||||
* Copyright (C) 2013-2017 CERN
|
||||
* Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
|
@ -206,11 +206,17 @@ public:
|
|||
void GetModifiedNets( std::vector<NET_HANDLE>& aNets ) const override;
|
||||
|
||||
/**
|
||||
* Check if point \a aP lies on segment \a aSeg. If so, splits the segment in two, forming a
|
||||
* Snaps the point \a aP to segment \a aSeg. Splits the segment in two, forming a
|
||||
* joint at \a aP and stores updated topology in node \a aNode.
|
||||
*/
|
||||
bool SplitAdjacentSegments( NODE* aNode, ITEM* aSeg, const VECTOR2I& aP );
|
||||
|
||||
/**
|
||||
* Snaps the point \a aP to arc \a aArc. Splits the arc in two, forming a
|
||||
* joint at \a aP and stores updated topology in node \a aNode.
|
||||
*/
|
||||
bool SplitAdjacentArcs( NODE* aNode, ITEM* aArc, const VECTOR2I& aP );
|
||||
|
||||
private:
|
||||
/**
|
||||
* Re-route the current track to point aP. Returns true, when routing has completed
|
||||
|
|
|
@ -1039,13 +1039,20 @@ void ROUTER::SetInterface( ROUTER_IFACE *aIface )
|
|||
}
|
||||
|
||||
|
||||
void ROUTER::BreakSegment( ITEM *aItem, const VECTOR2I& aP )
|
||||
void ROUTER::BreakSegmentOrArc( ITEM *aItem, const VECTOR2I& aP )
|
||||
{
|
||||
NODE *node = m_world->Branch();
|
||||
|
||||
LINE_PLACER placer( this );
|
||||
|
||||
if( placer.SplitAdjacentSegments( node, aItem, aP ) )
|
||||
bool ret = false;
|
||||
|
||||
if( aItem->OfKind( ITEM::SEGMENT_T ) )
|
||||
ret = placer.SplitAdjacentSegments( node, aItem, aP );
|
||||
else if( aItem->OfKind( ITEM::ARC_T ) )
|
||||
ret = placer.SplitAdjacentArcs( node, aItem, aP );
|
||||
|
||||
if( ret )
|
||||
{
|
||||
CommitRouting( node );
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ public:
|
|||
bool Finish();
|
||||
bool ContinueFromEnd( ITEM** aNewStartItem );
|
||||
bool FixRoute( const VECTOR2I& aP, ITEM* aItem, bool aForceFinish, bool aForceCommit );
|
||||
void BreakSegment( ITEM *aItem, const VECTOR2I& aP );
|
||||
void BreakSegmentOrArc( ITEM *aItem, const VECTOR2I& aP );
|
||||
|
||||
std::optional<VECTOR2I> UndoLastSegment();
|
||||
void CommitRouting();
|
||||
|
|
|
@ -1563,8 +1563,11 @@ bool ROUTER_TOOL::RoutingInProgress()
|
|||
|
||||
void ROUTER_TOOL::breakTrack()
|
||||
{
|
||||
if( m_startItem && m_startItem->OfKind( PNS::ITEM::SEGMENT_T ) )
|
||||
m_router->BreakSegment( m_startItem, m_startSnapPoint );
|
||||
if( !m_startItem )
|
||||
return;
|
||||
|
||||
if( m_startItem->OfKind( PNS::ITEM::SEGMENT_T | PNS::ITEM::ARC_T ) )
|
||||
m_router->BreakSegmentOrArc( m_startItem, m_startSnapPoint );
|
||||
}
|
||||
|
||||
|
||||
|
@ -2501,7 +2504,7 @@ int ROUTER_TOOL::InlineBreakTrack( const TOOL_EVENT& aEvent )
|
|||
const BOARD_CONNECTED_ITEM* item =
|
||||
static_cast<const BOARD_CONNECTED_ITEM*>( selection.Front() );
|
||||
|
||||
if( item->Type() != PCB_TRACE_T )
|
||||
if( item->Type() != PCB_TRACE_T && item->Type() != PCB_ARC_T )
|
||||
return 0;
|
||||
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear );
|
||||
|
@ -2516,6 +2519,8 @@ int ROUTER_TOOL::InlineBreakTrack( const TOOL_EVENT& aEvent )
|
|||
m_gridHelper->SetUseGrid( gal->GetGridSnapping() && !aEvent.DisableGridSnapping() );
|
||||
m_gridHelper->SetSnap( !aEvent.Modifier( MD_SHIFT ) );
|
||||
|
||||
controls()->ForceCursorPosition( false );
|
||||
|
||||
if( toolManager->IsContextMenuActive() )
|
||||
{
|
||||
// If we're here from a context menu then we need to get the position of the
|
||||
|
|
Loading…
Reference in New Issue