diff --git a/pcbnew/router/pns_line_placer.cpp b/pcbnew/router/pns_line_placer.cpp index 1b049b479d..5194014771 100644 --- a/pcbnew/router/pns_line_placer.cpp +++ b/pcbnew/router/pns_line_placer.cpp @@ -968,10 +968,28 @@ bool LINE_PLACER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem ) LINE pl = Trace(); - if( m_currentMode == RM_MarkObstacles && - !Settings().CanViolateDRC() && - m_world->CheckColliding( &pl ) ) + if( m_currentMode == RM_MarkObstacles ) + { + // Mark Obstacles is sort of a half-manual, half-automated mode in which the + // user has more responsibility and authority. + + if( aEndItem ) + { + // The user has indicated a connection should be made. If either the + // trace or endItem is netless, then allow the connection by adopting the net of the other. + if( m_currentNet <= 0 ) + { + m_currentNet = aEndItem->Net(); + pl.SetNet( m_currentNet ); + } + else if (aEndItem->Net() <= 0 ) + aEndItem->SetNet( m_currentNet ); + } + + // Collisions still prevent fixing unless "Allow DRC violations" is checked + if( !Settings().CanViolateDRC() && m_world->CheckColliding( &pl ) ) return false; + } const SHAPE_LINE_CHAIN& l = pl.CLine(); diff --git a/pcbnew/router/pns_tool_base.cpp b/pcbnew/router/pns_tool_base.cpp index fef94736c8..aa643957b6 100644 --- a/pcbnew/router/pns_tool_base.cpp +++ b/pcbnew/router/pns_tool_base.cpp @@ -120,9 +120,10 @@ ITEM* TOOL_BASE::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLayer, b if( aLayer > 0 ) tl = aLayer; - ITEM* prioritized[4]; + static const int candidateCount = 5; + ITEM* prioritized[candidateCount]; - for( int i = 0; i < 4; i++ ) + for( int i = 0; i < candidateCount; i++ ) prioritized[i] = 0; ITEM_SET candidates = m_router->QueryHoverItems( aWhere ); @@ -139,7 +140,7 @@ ITEM* TOOL_BASE::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLayer, b //if( item->Parent() && !item->Parent()->ViewIsVisible() ) // continue; - if( aNet < 0 || item->Net() == aNet ) + if( aNet <= 0 || item->Net() == aNet ) { if( item->OfKind( ITEM::VIA_T | ITEM::SOLID_T ) ) { @@ -159,11 +160,20 @@ ITEM* TOOL_BASE::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLayer, b prioritized[1] = item; } } + // Allow unconnected items as last resort in RM_MarkObstacles mode + else if ( item->Net() == 0 && m_router->Settings().Mode() == RM_MarkObstacles ) + { + if( item->OfKind( ITEM::SOLID_T ) && aIgnorePads ) + continue; + + if( item->Layers().Overlaps( tl ) ) + prioritized[4] = item; + } } ITEM* rv = NULL; - for( int i = 0; i < 4; i++ ) + for( int i = 0; i < candidateCount; i++ ) { ITEM* item = prioritized[i]; @@ -274,7 +284,8 @@ void TOOL_BASE::updateEndItem( const TOOL_EVENT& aEvent ) int layer; bool snapEnabled = !aEvent.Modifier( MD_SHIFT ); - if( m_router->GetCurrentNets().empty() || m_router->GetCurrentNets().front() < 0 ) + if( m_router->Settings().Mode() != RM_MarkObstacles && + ( m_router->GetCurrentNets().empty() || m_router->GetCurrentNets().front() < 0 ) ) { m_endSnapPoint = snapToItem( snapEnabled, nullptr, mousePos ); controls()->ForceCursorPosition( true, m_endSnapPoint );