PCB Actions: Grab Unconnected

Grabs the nearest unconnected item for each selected footprint/pad.

Fixes: https://gitlab.com/kicad/code/kicad/-/issues/1986
This commit is contained in:
Mike Williams 2022-09-22 14:25:44 -04:00
parent f4a3062684
commit 700edb95e3
5 changed files with 89 additions and 2 deletions

View File

@ -101,6 +101,10 @@ public:
const VECTOR2I GetSourcePos() const { return m_source->Pos(); }
const VECTOR2I GetTargetPos() const { return m_target->Pos(); }
const unsigned GetLength() const
{
return ( m_target->Pos() - m_source->Pos() ).EuclideanNorm();
}
private:
std::shared_ptr<CN_ANCHOR> m_source;

View File

@ -1320,6 +1320,12 @@ TOOL_ACTION PCB_ACTIONS::selectUnconnected( "pcbnew.InteractiveSelection.SelectU
_( "Select All Unconnected Footprints" ),
_( "Selects all unconnected footprints belonging to each selected net." ) );
TOOL_ACTION PCB_ACTIONS::grabUnconnected( "pcbnew.InteractiveSelection.GrabUnconnected",
AS_GLOBAL,
MD_SHIFT + 'O', "",
_( "Grab Nearest Unconnected Footprints" ),
_( "Selects and initiates moving the nearest unconnected footprint on each selected net." ) );
TOOL_ACTION PCB_ACTIONS::selectOnSheetFromEeschema( "pcbnew.InteractiveSelection.SelectOnSheet",
AS_GLOBAL, 0, "",
_( "Sheet" ),
@ -1533,5 +1539,4 @@ TOOL_ACTION PCB_ACTIONS::ddAppendBoard( "pcbnew.Control.DdAppendBoard",
AS_GLOBAL );
TOOL_ACTION PCB_ACTIONS::ddImportFootprint( "pcbnew.Control.ddImportFootprint",
AS_GLOBAL );
TOOL_ACTION PCB_ACTIONS::ddImportFootprint( "pcbnew.Control.ddImportFootprint", AS_GLOBAL );

View File

@ -91,6 +91,9 @@ public:
/// Select unconnected footprints from ratsnest of selection
static TOOL_ACTION selectUnconnected;
/// Select and move nearest unconnected footprint from ratsnest of selection
static TOOL_ACTION grabUnconnected;
/// Select all components on sheet from Eeschema crossprobing.
static TOOL_ACTION selectOnSheetFromEeschema;

View File

@ -90,6 +90,7 @@ public:
Add( PCB_ACTIONS::selectOnSchematic );
Add( PCB_ACTIONS::selectUnconnected );
Add( PCB_ACTIONS::grabUnconnected );
}
private:
@ -1445,6 +1446,74 @@ int PCB_SELECTION_TOOL::selectUnconnected( const TOOL_EVENT& aEvent )
}
int PCB_SELECTION_TOOL::grabUnconnected( const TOOL_EVENT& aEvent )
{
PCB_SELECTION originalSelection = m_selection;
// Get all pads
std::vector<PAD*> pads;
for( EDA_ITEM* item : m_selection.GetItems() )
{
if( item->Type() == PCB_FOOTPRINT_T )
{
for( PAD* pad : static_cast<FOOTPRINT*>( item )->Pads() )
pads.push_back( pad );
}
else if( item->Type() == PCB_PAD_T )
{
pads.push_back( static_cast<PAD*>( item ) );
}
}
ClearSelection();
// Select every footprint on the end of the ratsnest for each pad in our selection
std::shared_ptr<CONNECTIVITY_DATA> conn = board()->GetConnectivity();
for( PAD* pad : pads )
{
const std::vector<CN_EDGE> edges = conn->GetRatsnestForPad( pad );
// Need to have something unconnected to grab
if( edges.size() == 0 )
continue;
double currentDistance = DBL_MAX;
FOOTPRINT* nearest = nullptr;
// Check every ratsnest line for the nearest one
for( const CN_EDGE& edge : edges )
{
// Figure out if we are the source or the target node on the ratnest
std::shared_ptr<CN_ANCHOR> ourNode = edge.GetSourceNode()->Parent() == pad
? edge.GetSourceNode()
: edge.GetTargetNode();
std::shared_ptr<CN_ANCHOR> otherNode = edge.GetSourceNode()->Parent() != pad
? edge.GetSourceNode()
: edge.GetTargetNode();
// We only want to grab footprints, so the ratnest has to point to a pad
if( otherNode->Parent()->Type() != PCB_PAD_T )
continue;
if( edge.GetLength() < currentDistance )
{
currentDistance = edge.GetLength();
nearest = static_cast<PAD*>( otherNode->Parent() )->GetParent();
}
}
if( nearest != nullptr )
select( nearest );
}
m_toolMgr->RunAction( PCB_ACTIONS::moveIndividually, true );
return 0;
}
void PCB_SELECTION_TOOL::SelectAllItemsOnNet( int aNetCode, bool aSelect )
{
std::shared_ptr<CONNECTIVITY_DATA> conn = board()->GetConnectivity();
@ -3037,6 +3106,7 @@ void PCB_SELECTION_TOOL::setTransitions()
Go( &PCB_SELECTION_TOOL::selectNet, PCB_ACTIONS::selectNet.MakeEvent() );
Go( &PCB_SELECTION_TOOL::selectNet, PCB_ACTIONS::deselectNet.MakeEvent() );
Go( &PCB_SELECTION_TOOL::selectUnconnected, PCB_ACTIONS::selectUnconnected.MakeEvent() );
Go( &PCB_SELECTION_TOOL::grabUnconnected, PCB_ACTIONS::grabUnconnected.MakeEvent() );
Go( &PCB_SELECTION_TOOL::syncSelection, PCB_ACTIONS::syncSelection.MakeEvent() );
Go( &PCB_SELECTION_TOOL::syncSelectionWithNets,
PCB_ACTIONS::syncSelectionWithNets.MakeEvent() );

View File

@ -303,6 +303,11 @@ private:
*/
int selectUnconnected( const TOOL_EVENT& aEvent );
/**
* Select and move other nearest footprint unconnected on same net as selected items.
*/
int grabUnconnected( const TOOL_EVENT& aEvent );
enum STOP_CONDITION
{
/**