Check for additional connections between tracks

Prevents removal when a track is connected not just to other tracks but
also other connected items

Fixes https://gitlab.com/kicad/code/kicad/issues/10916
This commit is contained in:
Seth Hillbrand 2022-03-03 12:06:36 -08:00
parent 4d9c156b0a
commit 9d927f3135
3 changed files with 219 additions and 14 deletions

View File

@ -461,40 +461,63 @@ void TRACKS_CLEANER::cleanup( bool aDeleteDuplicateVias, bool aDeleteNullSegment
bool TRACKS_CLEANER::mergeCollinearSegments( PCB_TRACK* aSeg1, PCB_TRACK* aSeg2 )
{
KICAD_T items[] = { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, PCB_PAD_T, PCB_ZONE_T };
if( aSeg1->IsLocked() || aSeg2->IsLocked() )
return false;
std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_brd->GetConnectivity();
std::vector<PCB_TRACK*> tracks = connectivity->GetConnectedTracks( aSeg1 );
std::vector<PCB_TRACK*> tracks2 = connectivity->GetConnectedTracks( aSeg2 );
std::vector<BOARD_CONNECTED_ITEM*> tracks = connectivity->GetConnectedItems( aSeg1, items );
std::vector<BOARD_CONNECTED_ITEM*> tracks2 = connectivity->GetConnectedItems( aSeg2, items );
std::move( tracks2.begin(), tracks2.end(), std::back_inserter( tracks ) );
std::sort( tracks.begin(), tracks.end() );
tracks.erase( std::unique( tracks.begin(), tracks.end() ), tracks.end() );
tracks.erase(
std::remove_if( tracks.begin(), tracks.end(), [ aSeg1, aSeg2 ]( PCB_TRACK* aTest )
std::remove_if( tracks.begin(), tracks.end(), [ aSeg1, aSeg2 ]( BOARD_CONNECTED_ITEM* aTest )
{
return ( aTest == aSeg1 ) || ( aTest == aSeg2 );
} ), tracks.end() );
std::set<VECTOR2I> pts;
// Collect the unique points where the two tracks are connected to others
for( PCB_TRACK* track : tracks )
// Collect the unique points where the two tracks are connected to other items
for( BOARD_CONNECTED_ITEM* citem : tracks )
{
if( track->IsPointOnEnds( aSeg1->GetStart() ) )
pts.emplace( aSeg1->GetStart() );
if( track->IsPointOnEnds( aSeg1->GetEnd() ) )
pts.emplace( aSeg1->GetEnd() );
if( PCB_TRACK* track = dyn_cast<PCB_TRACK*>( citem ) )
{
if( track->IsPointOnEnds( aSeg1->GetStart() ) )
pts.emplace( aSeg1->GetStart() );
if( track->IsPointOnEnds( aSeg2->GetStart() ) )
pts.emplace( aSeg2->GetStart() );
if( track->IsPointOnEnds( aSeg1->GetEnd() ) )
pts.emplace( aSeg1->GetEnd() );
if( track->IsPointOnEnds( aSeg2->GetEnd() ) )
pts.emplace( aSeg2->GetEnd() );
if( track->IsPointOnEnds( aSeg2->GetStart() ) )
pts.emplace( aSeg2->GetStart() );
if( track->IsPointOnEnds( aSeg2->GetEnd() ) )
pts.emplace( aSeg2->GetEnd() );
}
else
{
if( citem->HitTest( aSeg1->GetStart(), ( aSeg1->GetWidth() + 1 ) / 2 ) )
pts.emplace( aSeg1->GetStart() );
if( citem->HitTest( aSeg1->GetEnd(), ( aSeg1->GetWidth() + 1 ) / 2 ) )
pts.emplace( aSeg1->GetEnd() );
if( citem->HitTest( aSeg2->GetStart(), ( aSeg2->GetWidth() + 1 ) / 2 ) )
pts.emplace( aSeg2->GetStart() );
if( citem->HitTest( aSeg2->GetEnd(), ( aSeg2->GetWidth() + 1 ) / 2 ) )
pts.emplace( aSeg2->GetEnd() );
}
}
// This means there is a node in the center
if( pts.size() > 2 )
return false;

View File

@ -0,0 +1,181 @@
(kicad_pcb (version 20220225) (generator pcbnew)
(general
(thickness 1.6)
)
(paper "A4")
(layers
(0 "F.Cu" signal)
(31 "B.Cu" signal)
(32 "B.Adhes" user "B.Adhesive")
(33 "F.Adhes" user "F.Adhesive")
(34 "B.Paste" user)
(35 "F.Paste" user)
(36 "B.SilkS" user "B.Silkscreen")
(37 "F.SilkS" user "F.Silkscreen")
(38 "B.Mask" user)
(39 "F.Mask" user)
(40 "Dwgs.User" user "User.Drawings")
(41 "Cmts.User" user "User.Comments")
(42 "Eco1.User" user "User.Eco1")
(43 "Eco2.User" user "User.Eco2")
(44 "Edge.Cuts" user)
(45 "Margin" user)
(46 "B.CrtYd" user "B.Courtyard")
(47 "F.CrtYd" user "F.Courtyard")
(48 "B.Fab" user)
(49 "F.Fab" user)
(50 "User.1" user)
(51 "User.2" user)
(52 "User.3" user)
(53 "User.4" user)
(54 "User.5" user)
(55 "User.6" user)
(56 "User.7" user)
(57 "User.8" user)
(58 "User.9" user)
)
(setup
(pad_to_mask_clearance 0)
(pcbplotparams
(layerselection 0x00010fc_ffffffff)
(disableapertmacros false)
(usegerberextensions false)
(usegerberattributes true)
(usegerberadvancedattributes true)
(creategerberjobfile true)
(dashed_line_dash_ratio 12.000000)
(dashed_line_gap_ratio 3.000000)
(svgprecision 4)
(excludeedgelayer true)
(plotframeref false)
(viasonmask false)
(mode 1)
(useauxorigin false)
(hpglpennumber 1)
(hpglpenspeed 20)
(hpglpendiameter 15.000000)
(dxfpolygonmode true)
(dxfimperialunits true)
(dxfusepcbnewfont true)
(psnegative false)
(psa4output false)
(plotreference true)
(plotvalue true)
(plotinvisibletext false)
(sketchpadsonfab false)
(subtractmaskfromsilk false)
(outputformat 1)
(mirror false)
(drillshape 1)
(scaleselection 1)
(outputdirectory "")
)
)
(net 0 "")
(net 1 "a")
(footprint "Capacitor_SMD:C_0805_2012Metric" (layer "F.Cu")
(tstamp 0b9f21ed-3d41-4f23-ae45-74117a5f3153)
(at 141 54)
(descr "Capacitor SMD 0805 (2012 Metric), square (rectangular) end terminal, IPC_7351 nominal, (Body size source: IPC-SM-782 page 76, https://www.pcb-3d.com/wordpress/wp-content/uploads/ipc-sm-782a_amendment_1_and_2.pdf, https://docs.google.com/spreadsheets/d/1BsfQQcO9C6DZCsRaXUlFlo91Tg2WpOkGARC1WS5S8t0/edit?usp=sharing), generated with kicad-footprint-generator")
(tags "capacitor")
(attr smd)
(fp_text reference "REF**" (at 0 -1.68) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 3e3d55c8-e0ea-48fb-8421-a84b7cb7055b)
)
(fp_text value "C_0805_2012Metric" (at 0 1.68) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 725cdf26-4b92-46db-bca9-10d930002dda)
)
(fp_text user "${REFERENCE}" (at 0 0) (layer "F.Fab")
(effects (font (size 0.5 0.5) (thickness 0.08)))
(tstamp aee7520e-3bfc-435f-a66b-1dd1f5aa6a87)
)
(fp_line (start -0.261252 -0.735) (end 0.261252 -0.735)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp df2a6036-7274-4398-9365-148b6ddab90d))
(fp_line (start -0.261252 0.735) (end 0.261252 0.735)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 7b766787-7689-40b8-9ef5-c0b1af45a9ae))
(fp_line (start -1.7 -0.98) (end 1.7 -0.98)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 2b64d2cb-d62a-4762-97ea-f1b0d4293c4f))
(fp_line (start -1.7 0.98) (end -1.7 -0.98)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp fc83cd71-1198-4019-87a1-dc154bceead3))
(fp_line (start 1.7 -0.98) (end 1.7 0.98)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 10d8ad0e-6a08-4053-92aa-23a15910fd21))
(fp_line (start 1.7 0.98) (end -1.7 0.98)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 475ed8b3-90bf-48cd-bce5-d8f48b689541))
(fp_line (start -1 -0.625) (end 1 -0.625)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 99186658-0361-40ba-ae93-62f23c5622e6))
(fp_line (start -1 0.625) (end -1 -0.625)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 5f312b85-6822-40a3-b417-2df49696ca2d))
(fp_line (start 1 -0.625) (end 1 0.625)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 123968c6-74e7-4754-8c36-08ea08e42555))
(fp_line (start 1 0.625) (end -1 0.625)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ee29d712-3378-4507-a00b-003526b29bb1))
(pad "1" smd roundrect (at -0.95 0) (size 1 1.45) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25)
(net 1 "a") (tstamp 8486c294-aa7e-43c3-b257-1ca3356dd17a))
(pad "2" smd roundrect (at 0.95 0) (size 1 1.45) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 2c95b9a6-9c71-4108-9cde-57ddfdd2dd19))
(model "${KICAD6_3DMODEL_DIR}/Capacitor_SMD.3dshapes/C_0805_2012Metric.wrl"
(offset (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)
(footprint "Capacitor_SMD:C_0805_2012Metric" (layer "F.Cu")
(tstamp 47993d80-a37e-426e-90c9-fd54b49ed166)
(at 141 59)
(descr "Capacitor SMD 0805 (2012 Metric), square (rectangular) end terminal, IPC_7351 nominal, (Body size source: IPC-SM-782 page 76, https://www.pcb-3d.com/wordpress/wp-content/uploads/ipc-sm-782a_amendment_1_and_2.pdf, https://docs.google.com/spreadsheets/d/1BsfQQcO9C6DZCsRaXUlFlo91Tg2WpOkGARC1WS5S8t0/edit?usp=sharing), generated with kicad-footprint-generator")
(tags "capacitor")
(attr smd)
(fp_text reference "REF**" (at 0 -1.68) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 49d97c73-e37a-4154-9d0a-88037e40cc11)
)
(fp_text value "C_0805_2012Metric" (at 0 1.68) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 961b4579-9ee8-407a-89a7-81f36f1ad865)
)
(fp_text user "${REFERENCE}" (at 0 0) (layer "F.Fab")
(effects (font (size 0.5 0.5) (thickness 0.08)))
(tstamp 01024d27-e392-4482-9e67-565b0c294fe8)
)
(fp_line (start -0.261252 -0.735) (end 0.261252 -0.735)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 88a17e56-466a-45e7-9047-7346a507f505))
(fp_line (start -0.261252 0.735) (end 0.261252 0.735)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp acf5d924-0760-425a-996c-c1d965700be8))
(fp_line (start -1.7 -0.98) (end 1.7 -0.98)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp fead07ab-5a70-40db-ada8-c72dcc827bfc))
(fp_line (start -1.7 0.98) (end -1.7 -0.98)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 2026567f-be64-41dd-8011-b0897ba0ff2e))
(fp_line (start 1.7 -0.98) (end 1.7 0.98)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 981ff4de-0330-4757-b746-0cb983df5e7c))
(fp_line (start 1.7 0.98) (end -1.7 0.98)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 77ef8901-6325-4427-901a-4acd9074dd7b))
(fp_line (start -1 -0.625) (end 1 -0.625)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 7943ed8c-e760-4ace-9c5f-baf5589fae39))
(fp_line (start -1 0.625) (end -1 -0.625)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 59e09498-d26e-4ba7-b47d-fece2ea7c274))
(fp_line (start 1 -0.625) (end 1 0.625)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 9505be36-b21c-4db8-9484-dd0861395d26))
(fp_line (start 1 0.625) (end -1 0.625)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp ea4f0afc-785b-40cf-8ef1-cbe20404c18b))
(pad "1" smd roundrect (at -0.95 0) (size 1 1.45) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25)
(net 1 "a") (tstamp fb9a832c-737d-49fb-bbb4-29a0ba3e8178))
(pad "2" smd roundrect (at 0.95 0) (size 1 1.45) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 54093c93-5e7e-4c8d-8d94-40c077747c12))
(model "${KICAD6_3DMODEL_DIR}/Capacitor_SMD.3dshapes/C_0805_2012Metric.wrl"
(offset (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)
(segment (start 140.05 56.95) (end 140.05 54) (width 0.25) (layer "F.Cu") (net 1) (tstamp 01caafb3-af8a-4642-870c-c290b286d040))
(segment (start 140.05 59) (end 140.05 56.95) (width 0.25) (layer "F.Cu") (net 1) (tstamp a29e1299-22c5-4fd2-9a37-e405785962a9))
(via (at 140.05 56.95) (size 0.8) (drill 0.4) (layers "F.Cu" "B.Cu") (net 1) (tstamp 74d2d2c1-d0d5-412f-ab06-bb67df0a3900))
)

View File

@ -69,7 +69,8 @@ BOOST_FIXTURE_TEST_CASE( FailedToCleanRegressionTests, TRACK_CLEANER_TEST_FIXTUR
{ "issue2904", false, false, false, true, false, false, 9 },
{ "issue5093", false, false, false, false, true, false, 118 },
{ "issue7004", false, true, false, false, false, true, 25 },
{ "issue8883", true, true, true, true, false, true, 80 }
{ "issue8883", true, true, true, true, false, true, 80 },
{ "issue10916", false, false, true, false, false, false, 0 }
};
for( const TEST_DESCRIPTION& entry : tests )