From 70c6314c6719d45ab22af74f978d53e0a8c1d24b Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Tue, 22 Dec 2020 22:28:13 -0500 Subject: [PATCH] Component dragger: be more generous about picking up tracks We now pick up tracks that end anywhere in the pad, not just at the pad anchor. Fixes https://gitlab.com/kicad/code/kicad/-/issues/5945 --- pcbnew/router/pns_component_dragger.cpp | 48 +++++++++++++++++++------ pcbnew/router/pns_component_dragger.h | 1 + pcbnew/router/pns_node.cpp | 17 +++++---- 3 files changed, 48 insertions(+), 18 deletions(-) diff --git a/pcbnew/router/pns_component_dragger.cpp b/pcbnew/router/pns_component_dragger.cpp index e8f8673c60..621d369db8 100644 --- a/pcbnew/router/pns_component_dragger.cpp +++ b/pcbnew/router/pns_component_dragger.cpp @@ -50,6 +50,26 @@ bool COMPONENT_DRAGGER::Start( const VECTOR2I& aP, ITEM_SET& aPrimitives ) m_initialDraggedItems = aPrimitives; m_p0 = aP; + std::unordered_set seenItems; + + auto addLinked = + [&]( SOLID* aSolid, LINKED_ITEM* aItem, VECTOR2I aOffset = {} ) + { + if( seenItems.count( aItem ) ) + return; + + seenItems.insert( aItem ); + + int segIndex; + DRAGGED_CONNECTION cn; + + cn.origLine = m_world->AssembleLine( aItem, &segIndex ); + cn.attachedPad = aSolid; + cn.offset = aOffset; + + m_conns.push_back( cn ); + }; + for( auto item : aPrimitives.Items() ) { if( item.item->Kind() != ITEM::SOLID_T ) @@ -66,17 +86,23 @@ bool COMPONENT_DRAGGER::Start( const VECTOR2I& aP, ITEM_SET& aPrimitives ) for( auto link : jt->LinkList() ) { if( link.item->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T ) ) + addLinked( solid, static_cast( link.item ) ); + } + + std::vector extraJoints; + + if( m_world->QueryJoints( solid->Hull().BBox(), extraJoints, solid->Layer(), + ITEM::SEGMENT_T | ITEM::ARC_T ) ) + { + for( JOINT* extraJoint : extraJoints ) { - LINKED_ITEM* li = static_cast( link.item ); - int segIndex; + if( extraJoint->Net() == jt->Net() && extraJoint->LinkCount() == 1 ) + { + LINKED_ITEM* li = static_cast( extraJoint->LinkList()[0].item ); - auto l0 = m_world->AssembleLine( li, &segIndex ); - - DRAGGED_CONNECTION cn; - - cn.origLine = l0; - cn.attachedPad = solid; - m_conns.push_back( cn ); + if( li->Collide( solid, 0, false, nullptr, nullptr, false ) ) + addLinked( solid, li, extraJoint->Pos() - solid->Pos() ); + } } } } @@ -108,8 +134,8 @@ bool COMPONENT_DRAGGER::Drag( const VECTOR2I& aP ) { if( l.attachedPad == s ) { - l.p_orig = s->Pos(); - l.p_next = p_next; + l.p_orig = s->Pos() + l.offset; + l.p_next = p_next + l.offset; } } } diff --git a/pcbnew/router/pns_component_dragger.h b/pcbnew/router/pns_component_dragger.h index 0be7e3de3f..049938a362 100644 --- a/pcbnew/router/pns_component_dragger.h +++ b/pcbnew/router/pns_component_dragger.h @@ -114,6 +114,7 @@ private: LINE origLine; SOLID* attachedPad; VECTOR2I p_orig, p_next; + VECTOR2I offset; }; std::set m_solids; diff --git a/pcbnew/router/pns_node.cpp b/pcbnew/router/pns_node.cpp index 0bf4066879..bd467a934a 100644 --- a/pcbnew/router/pns_node.cpp +++ b/pcbnew/router/pns_node.cpp @@ -1424,11 +1424,14 @@ int NODE::QueryJoints( const BOX2I& aBox, std::vector& aJoints, int aLay aJoints.clear(); - for( auto j = m_joints.begin(); j != m_joints.end(); ++j ) + for( JOINT_MAP::value_type& j : m_joints ) { - if( aBox.Contains( j->second.Pos() ) && j->second.LinkCount( aKindMask ) ) + if( j.second.Layer() != aLayerMask ) + continue; + + if( aBox.Contains( j.second.Pos() ) && j.second.LinkCount( aKindMask ) ) { - aJoints.push_back( &j->second ); + aJoints.push_back( &j.second ); n++; } } @@ -1436,13 +1439,13 @@ int NODE::QueryJoints( const BOX2I& aBox, std::vector& aJoints, int aLay if( isRoot() ) return n; - for( auto j = m_root->m_joints.begin(); j != m_root->m_joints.end(); ++j ) + for( JOINT_MAP::value_type& j : m_root->m_joints ) { - if( !Overrides( &j->second) ) + if( !Overrides( &j.second ) && j.second.Layer() == aLayerMask ) { - if( aBox.Contains( j->second.Pos() ) && j->second.LinkCount( aKindMask ) ) + if( aBox.Contains( j.second.Pos() ) && j.second.LinkCount( aKindMask ) ) { - aJoints.push_back( &j->second ); + aJoints.push_back( &j.second ); n++; } }