Fix SolderBridge check to only check across multiple

We should not generate an error when overlapping a single copper element
with a soldermask that is not associated with copper.

Fixes https://gitlab.com/kicad/code/kicad/issues/10906
This commit is contained in:
Seth Hillbrand 2022-02-18 11:46:16 -08:00
parent f0e4448a9d
commit a19d9105f0
6 changed files with 1029 additions and 890 deletions

View File

@ -333,11 +333,17 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testItemAgainstItems( BOARD_ITEM* aItem,
if( otherNet > 0 && otherNet == itemNet )
return false;
if( aItem->GetParentFootprint() && other->GetParentFootprint() )
{
int attr = static_cast<FOOTPRINT*>( aItem->GetParentFootprint() )->GetAttributes();
if( attr & FP_ALLOW_SOLDERMASK_BRIDGES )
return false;
}
if( pad && otherPad && pad->GetParent() == otherPad->GetParent() )
{
if( pad->GetParent()->GetAttributes() & FP_ALLOW_SOLDERMASK_BRIDGES )
return false;
else if( pad->SameLogicalPadAs( otherPad ) )
if( pad->SameLogicalPadAs( otherPad ) )
return false;
}
@ -401,8 +407,13 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testItemAgainstItems( BOARD_ITEM* aItem,
{
std::pair<BOARD_ITEM*, PCB_LAYER_ID> key = { aItem, aRefLayer };
// If the mask collides with the first object, add the object
// net to our map and stop. This cannot be an error yet.
if( m_maskApertureNetMap.count( key ) == 0 )
{
m_maskApertureNetMap[ key ] = otherNet;
return true;
}
if( m_maskApertureNetMap.at( key ) == otherNet && otherNet > 0 )
return true;
@ -413,7 +424,10 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testItemAgainstItems( BOARD_ITEM* aItem,
std::pair<BOARD_ITEM*, PCB_LAYER_ID> key = { other, aRefLayer };
if( m_maskApertureNetMap.count( key ) == 0 )
{
m_maskApertureNetMap[ key ] = itemNet;
return true;
}
if( m_maskApertureNetMap.at( key ) == itemNet && itemNet > 0 )
return true;

View File

@ -0,0 +1,103 @@
(kicad_pcb (version 20220211) (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 "")
(footprint "Connector_Wire:SolderWirePad_1x01_SMD_1x2mm" (layer "F.Cu")
(tedit 620FF1C8) (tstamp 2e642b3e-a476-4c54-9a52-dcea955640cd)
(at 136.84 58.35)
(descr "Wire Pad, Square, SMD Pad, 5mm x 10mm,")
(tags "MesurementPoint Square SMDPad 5mmx10mm ")
(attr exclude_from_pos_files exclude_from_bom)
(fp_text reference "REF**" (at 0 -2.54) (layer "F.SilkS") hide
(effects (font (size 1 1) (thickness 0.15)))
(tstamp b1086f75-01ba-4188-8d36-75a9e2828ca9)
)
(fp_text value "" (at 0 2.54) (layer "F.Fab") hide
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 716e31c5-485f-40b5-88e3-a75900da9811)
)
(fp_rect (start -0.762 -0.508) (end 1.016 0.762)
(stroke (width 0) (type solid)) (fill solid) (layer "F.Cu") (tstamp e87a6f80-914f-4f62-9c9f-9ba62a88ee3d))
(fp_rect (start -0.762 -0.508) (end 1.016 0.762)
(stroke (width 0) (type solid)) (fill solid) (layer "F.Mask") (tstamp df3dc9a2-ba40-4c3a-87fe-61cc8e23d71b))
)
(gr_rect (start 135.25 57.21) (end 138.55 60.51)
(stroke (width 0.05) (type default)) (fill none) (layer "Edge.Cuts") (tstamp 2f0570b6-86da-47a8-9e56-ce60c431c534))
)

File diff suppressed because it is too large Load Diff

View File

@ -56,7 +56,8 @@
}
],
"drc_exclusions": [
"lib_footprint_issues|154305000|81417500|3bd3a1e0-b35d-4974-99fa-33d3eee5d601|00000000-0000-0000-0000-000000000000"
"lib_footprint_issues|154305000|81417500|3bd3a1e0-b35d-4974-99fa-33d3eee5d601|00000000-0000-0000-0000-000000000000",
"lib_footprint_mismatch|194730000|83947750|970e0f64-111f-41e3-9f5a-fb0d0f6fa101|00000000-0000-0000-0000-000000000000"
],
"meta": {
"version": 2
@ -80,6 +81,7 @@
"items_not_allowed": "error",
"length_out_of_range": "error",
"lib_footprint_issues": "ignore",
"lib_footprint_mismatch": "error",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
@ -129,6 +131,46 @@
"solder_mask_to_copper_clearance": 0.0,
"use_height_for_length_calcs": true
},
"teardrop_options": [
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 5,
"td_on_pad_in_zone": false,
"td_onpadsmd": true,
"td_onroundshapesonly": false,
"td_ontrackend": false,
"td_onviapad": true
}
],
"teardrop_parameters": [
{
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_target_name": "td_round_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_target_name": "td_rect_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_target_name": "td_track_end",
"td_width_to_size_filter_ratio": 0.9
}
],
"track_widths": [
0.0,
0.2,

View File

@ -57,7 +57,8 @@ BOOST_FIXTURE_TEST_CASE( DRCFalsePositiveRegressions, DRC_REGRESSION_TEST_FIXTUR
// selective inner copper layers
"issue7567", // DRC constraint to disallow holes gets SMD pads also
"issue7975", // Differential pair gap out of range fault by DRC
"issue8407" // PCBNEW: Arc for diff pair has clearance DRC error
"issue8407", // PCBNEW: Arc for diff pair has clearance DRC error
"issue10906" // Soldermask bridge for only one object
};
for( const wxString& relPath : tests )

View File

@ -66,14 +66,14 @@ BOOST_FIXTURE_TEST_CASE( DRCSolderMaskBridgingTest, DRC_REGRESSION_TEST_FIXTURE
bds.m_DRCEngine->RunTests( EDA_UNITS::MILLIMETRES, true, false );
if( violations.size() == 4 )
if( violations.size() == 5 )
{
BOOST_CHECK_EQUAL( 1, 1 ); // quiet "did not check any assertions" warning
BOOST_TEST_MESSAGE( "DRC solder mask bridge test passed" );
}
else
{
BOOST_CHECK_EQUAL( violations.size(), 4 );
BOOST_CHECK_EQUAL( violations.size(), 5 );
std::map<KIID, EDA_ITEM*> itemMap;
m_board->FillItemMap( itemMap );