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

(cherry picked from commit 9d927f3135)
This commit is contained in:
Seth Hillbrand 2022-03-03 12:06:36 -08:00
parent c3f8d8b5a1
commit 8f75841c85
3 changed files with 198 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,160 @@
(kicad_pcb (version 20211014) (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)
(svguseinch false)
(svgprecision 6)
(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")
(tedit 5F68FEEE) (tstamp 8ac400bf-c9b3-4af4-b0a7-9aa9ab4ad17e)
(at 136 63)
(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 212bf70c-2324-47d9-8700-59771063baeb)
)
(fp_text value "C_0805_2012Metric" (at 0 1.68) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 44035e53-ff94-45ad-801f-55a1ce042a0d)
)
(fp_text user "${REFERENCE}" (at 0 0) (layer "F.Fab")
(effects (font (size 0.5 0.5) (thickness 0.08)))
(tstamp 0cc9bf07-55b9-458f-b8aa-41b2f51fa940)
)
(fp_line (start -0.261252 0.735) (end 0.261252 0.735) (layer "F.SilkS") (width 0.12) (tstamp 241e0c85-4796-48eb-a5a0-1c0f2d6e5910))
(fp_line (start -0.261252 -0.735) (end 0.261252 -0.735) (layer "F.SilkS") (width 0.12) (tstamp 386ad9e3-71fa-420f-8722-88548b024fc5))
(fp_line (start 1.7 -0.98) (end 1.7 0.98) (layer "F.CrtYd") (width 0.05) (tstamp 5d49e9a6-41dd-4072-adde-ef1036c1979b))
(fp_line (start -1.7 0.98) (end -1.7 -0.98) (layer "F.CrtYd") (width 0.05) (tstamp 87a1984f-543d-4f2e-ad8a-7a3a24ee6047))
(fp_line (start 1.7 0.98) (end -1.7 0.98) (layer "F.CrtYd") (width 0.05) (tstamp 8cb2cd3a-4ef9-4ae5-b6bc-2b1d16f657d6))
(fp_line (start -1.7 -0.98) (end 1.7 -0.98) (layer "F.CrtYd") (width 0.05) (tstamp c8ab8246-b2bb-4b06-b45e-2548482466fd))
(fp_line (start -1 0.625) (end -1 -0.625) (layer "F.Fab") (width 0.1) (tstamp 7f9683c1-2203-43df-8fa1-719a0dc360df))
(fp_line (start -1 -0.625) (end 1 -0.625) (layer "F.Fab") (width 0.1) (tstamp b0054ce1-b60e-41de-a6a2-bf712784dd39))
(fp_line (start 1 -0.625) (end 1 0.625) (layer "F.Fab") (width 0.1) (tstamp be2983fa-f06e-485e-bea1-3dd96b916ec5))
(fp_line (start 1 0.625) (end -1 0.625) (layer "F.Fab") (width 0.1) (tstamp dc1d84c8-33da-4489-be8e-2a1de3001779))
(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 97dcf785-3264-40a1-a36e-8842acab24fb))
(pad "2" smd roundrect (at 0.95 0) (size 1 1.45) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 363945f6-fbef-42be-99cf-4a8a48434d92))
(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")
(tedit 5F68FEEE) (tstamp eb667eea-300e-4ca7-8a6f-4b00de80cd45)
(at 136 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 a690fc6c-55d9-47e6-b533-faa4b67e20f3)
)
(fp_text value "C_0805_2012Metric" (at 0 1.68) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp c144caa5-b0d4-4cef-840a-d4ad178a2102)
)
(fp_text user "${REFERENCE}" (at 0 0) (layer "F.Fab")
(effects (font (size 0.5 0.5) (thickness 0.08)))
(tstamp 3b838d52-596d-4e4d-a6ac-e4c8e7621137)
)
(fp_line (start -0.261252 -0.735) (end 0.261252 -0.735) (layer "F.SilkS") (width 0.12) (tstamp 1e1b062d-fad0-427c-a622-c5b8a80b5268))
(fp_line (start -0.261252 0.735) (end 0.261252 0.735) (layer "F.SilkS") (width 0.12) (tstamp cbdcaa78-3bbc-413f-91bf-2709119373ce))
(fp_line (start -1.7 -0.98) (end 1.7 -0.98) (layer "F.CrtYd") (width 0.05) (tstamp 2e642b3e-a476-4c54-9a52-dcea955640cd))
(fp_line (start -1.7 0.98) (end -1.7 -0.98) (layer "F.CrtYd") (width 0.05) (tstamp 30f15357-ce1d-48b9-93dc-7d9b1b2aa048))
(fp_line (start 1.7 -0.98) (end 1.7 0.98) (layer "F.CrtYd") (width 0.05) (tstamp 87371631-aa02-498a-998a-09bdb74784c1))
(fp_line (start 1.7 0.98) (end -1.7 0.98) (layer "F.CrtYd") (width 0.05) (tstamp d8603679-3e7b-4337-8dbc-1827f5f54d8a))
(fp_line (start -1 -0.625) (end 1 -0.625) (layer "F.Fab") (width 0.1) (tstamp 5038e144-5119-49db-b6cf-f7c345f1cf03))
(fp_line (start 1 0.625) (end -1 0.625) (layer "F.Fab") (width 0.1) (tstamp 54365317-1355-4216-bb75-829375abc4ec))
(fp_line (start 1 -0.625) (end 1 0.625) (layer "F.Fab") (width 0.1) (tstamp a3e4f0ae-9f86-49e9-b386-ed8b42e012fb))
(fp_line (start -1 0.625) (end -1 -0.625) (layer "F.Fab") (width 0.1) (tstamp ac264c30-3e9a-4be2-b97a-9949b68bd497))
(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 66116376-6967-4178-9f23-a26cdeafc400))
(pad "2" smd roundrect (at 0.95 0) (size 1 1.45) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 749dfe75-c0d6-4872-9330-29c5bbcb8ff8))
(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 135.05 63) (end 135.05 60.95) (width 0.25) (layer "F.Cu") (net 1) (tstamp 8cb5a828-8cef-4784-b78d-175b49646952))
(segment (start 135.05 60.95) (end 135.05 59) (width 0.25) (layer "F.Cu") (net 1) (tstamp c0c62e93-8e84-4f2b-96ae-e90b55e0550a))
(via (at 135.05 60.95) (size 0.8) (drill 0.4) (layers "F.Cu" "B.Cu") (net 1) (tstamp 53ae21b8-f187-4817-8c27-1f06278d249b))
)

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 )