Trim wires based on how many pins they intersect
If a wire intersects more than 2 pins from the same symbol, we don't trim connections. If the wire intersects exactly two pins from a single symbol, we remove the wire between the pins. We avoided doing this before because we didn't have a good metric for trimming vs. not. But the per-symbol calculation feels like the least surprising option. Fixes https://gitlab.com/kicad/code/kicad/issues/10909 Fixes https://gitlab.com/kicad/code/kicad/issues/1857
This commit is contained in:
parent
f0d7a09af9
commit
75a4036e45
|
@ -692,6 +692,11 @@ TOOL_ACTION EE_ACTIONS::addNeededJunctions( "eeschema.InteractiveDrawingLineWire
|
|||
_( "Add Junctions to Selection where needed" ), "",
|
||||
BITMAPS::INVALID_BITMAP, AF_ACTIVATE );
|
||||
|
||||
TOOL_ACTION EE_ACTIONS::trimOverlappingWires( "eeschema.InteractiveDrawingLineWireBus.trimOverlappingWires",
|
||||
AS_ACTIVE, 0, "",
|
||||
"", "",
|
||||
BITMAPS::INVALID_BITMAP, AF_ACTIVATE );
|
||||
|
||||
|
||||
const DRAW_SEGMENT_EVENT_PARAMS drawWireActionParam = { LAYER_WIRE, false };
|
||||
TOOL_ACTION EE_ACTIONS::drawWire( "eeschema.InteractiveDrawingLineWireBus.drawWires",
|
||||
|
|
|
@ -73,6 +73,7 @@ public:
|
|||
|
||||
// Schematic Tools
|
||||
static TOOL_ACTION addNeededJunctions;
|
||||
static TOOL_ACTION trimOverlappingWires;
|
||||
static TOOL_ACTION pickerTool;
|
||||
static TOOL_ACTION placeSymbol;
|
||||
static TOOL_ACTION placePower;
|
||||
|
|
|
@ -278,12 +278,14 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
|
|||
symbol->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
|
||||
|
||||
symbol->ClearEditFlags();
|
||||
m_view->Update( symbol );
|
||||
m_frame->GetScreen()->Update( symbol );
|
||||
|
||||
m_toolMgr->RunAction( EE_ACTIONS::trimOverlappingWires, true,
|
||||
&m_selectionTool->GetSelection() );
|
||||
m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true,
|
||||
&m_selectionTool->GetSelection() );
|
||||
|
||||
m_view->Update( symbol );
|
||||
m_frame->GetScreen()->Update( symbol );
|
||||
m_frame->OnModify();
|
||||
|
||||
SCH_SYMBOL* nextSymbol = nullptr;
|
||||
|
|
|
@ -893,6 +893,7 @@ int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent )
|
|||
EE_SELECTION new_sel;
|
||||
new_sel.Add( newItem );
|
||||
|
||||
m_toolMgr->RunAction( EE_ACTIONS::trimOverlappingWires, true, &new_sel );
|
||||
m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true, &new_sel );
|
||||
|
||||
m_frame->RecalculateConnections( LOCAL_CLEANUP );
|
||||
|
|
|
@ -973,6 +973,50 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments()
|
|||
}
|
||||
|
||||
|
||||
int SCH_LINE_WIRE_BUS_TOOL::TrimOverLappingWires( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
EE_SELECTION* aSelection = aEvent.Parameter<EE_SELECTION*>();
|
||||
SCHEMATIC* sch = getModel<SCHEMATIC>();
|
||||
SCH_SCREEN* screen = sch->CurrentSheet().LastScreen();
|
||||
|
||||
std::set<SCH_LINE*> lines;
|
||||
EDA_RECT bb = aSelection->GetBoundingBox();
|
||||
|
||||
for( EDA_ITEM* item : screen->Items().Overlapping( SCH_LINE_T, bb ) )
|
||||
lines.insert( static_cast<SCH_LINE*>( item ) );
|
||||
|
||||
for( unsigned ii = 0; ii < aSelection->GetSize(); ii++ )
|
||||
{
|
||||
SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( aSelection->GetItem( ii ) );
|
||||
std::vector<wxPoint> pts = item->GetConnectionPoints();
|
||||
|
||||
if( !item || !item->IsConnectable() || ( item->Type() == SCH_LINE_T ) )
|
||||
continue;
|
||||
|
||||
/// If the line intersects with an item in the selection at only two points,
|
||||
/// then we can remove the line between the two points.
|
||||
for( SCH_LINE* line : lines )
|
||||
{
|
||||
std::vector<wxPoint> conn_pts;
|
||||
|
||||
for( wxPoint pt : pts )
|
||||
{
|
||||
if( IsPointOnSegment( line->GetStartPoint(), line->GetEndPoint(), pt ) )
|
||||
conn_pts.push_back( pt );
|
||||
|
||||
if( conn_pts.size() > 2 )
|
||||
break;
|
||||
}
|
||||
|
||||
if( conn_pts.size() == 2 )
|
||||
m_frame->TrimWire( conn_pts[0], conn_pts[1] );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SCH_LINE_WIRE_BUS_TOOL::AddJunctionsIfNeeded( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
EE_SELECTION* aSelection = aEvent.Parameter<EE_SELECTION*>();
|
||||
|
@ -980,6 +1024,12 @@ int SCH_LINE_WIRE_BUS_TOOL::AddJunctionsIfNeeded( const TOOL_EVENT& aEvent )
|
|||
std::vector<wxPoint> pts;
|
||||
std::vector<wxPoint> connections = m_frame->GetSchematicConnections();
|
||||
|
||||
std::set<SCH_LINE*> lines;
|
||||
EDA_RECT bb = aSelection->GetBoundingBox();
|
||||
|
||||
for( EDA_ITEM* item : m_frame->GetScreen()->Items().Overlapping( SCH_LINE_T, bb ) )
|
||||
lines.insert( static_cast<SCH_LINE*>( item ) );
|
||||
|
||||
for( unsigned ii = 0; ii < aSelection->GetSize(); ii++ )
|
||||
{
|
||||
SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( aSelection->GetItem( ii ) );
|
||||
|
@ -1002,15 +1052,6 @@ int SCH_LINE_WIRE_BUS_TOOL::AddJunctionsIfNeeded( const TOOL_EVENT& aEvent )
|
|||
pts.push_back( pt );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clean up any wires that short non-wire connections in the list
|
||||
for( auto pt = new_pts.begin(); pt != new_pts.end(); pt++ )
|
||||
{
|
||||
for( auto secondPt = pt + 1; secondPt != new_pts.end(); secondPt++ )
|
||||
m_frame->TrimWire( *pt, *secondPt );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We always have some overlapping connection points. Drop duplicates here
|
||||
|
@ -1035,6 +1076,7 @@ int SCH_LINE_WIRE_BUS_TOOL::AddJunctionsIfNeeded( const TOOL_EVENT& aEvent )
|
|||
void SCH_LINE_WIRE_BUS_TOOL::setTransitions()
|
||||
{
|
||||
Go( &SCH_LINE_WIRE_BUS_TOOL::AddJunctionsIfNeeded, EE_ACTIONS::addNeededJunctions.MakeEvent() );
|
||||
Go( &SCH_LINE_WIRE_BUS_TOOL::TrimOverLappingWires, EE_ACTIONS::trimOverlappingWires.MakeEvent() );
|
||||
Go( &SCH_LINE_WIRE_BUS_TOOL::DrawSegments, EE_ACTIONS::drawWire.MakeEvent() );
|
||||
Go( &SCH_LINE_WIRE_BUS_TOOL::DrawSegments, EE_ACTIONS::drawBus.MakeEvent() );
|
||||
Go( &SCH_LINE_WIRE_BUS_TOOL::DrawSegments, EE_ACTIONS::drawLines.MakeEvent() );
|
||||
|
|
|
@ -93,6 +93,11 @@ public:
|
|||
*/
|
||||
int AddJunctionsIfNeeded( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Logic to remove wires when overlapping correct items
|
||||
*/
|
||||
int TrimOverLappingWires( const TOOL_EVENT& aEvent );
|
||||
|
||||
private:
|
||||
int doDrawSegments( const std::string& aTool, int aType, bool aQuitOnDraw );
|
||||
SCH_LINE* startSegments( int aType, const VECTOR2D& aPos );
|
||||
|
|
|
@ -505,6 +505,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
m_frame->AddJunction( m_frame->GetScreen(), it.GetPosition(), true, false );
|
||||
}
|
||||
|
||||
m_toolMgr->RunAction( EE_ACTIONS::trimOverlappingWires, true, &selectionCopy );
|
||||
m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true, &selectionCopy );
|
||||
|
||||
m_frame->RecalculateConnections( LOCAL_CLEANUP );
|
||||
|
@ -917,6 +918,7 @@ int SCH_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
m_toolMgr->PostEvent( EVENTS::SelectedItemsMoved );
|
||||
m_toolMgr->RunAction( EE_ACTIONS::trimOverlappingWires, true, &selection );
|
||||
m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true, &selection );
|
||||
|
||||
m_frame->RecalculateConnections( LOCAL_CLEANUP );
|
||||
|
|
Loading…
Reference in New Issue