Add mechanical copper clearance testing for shapes.

Also includes going from distance-based neighbor exclusion to angle-
based.  (Distance doesn't work when very short segments are followed
by very long ones.)

Fixes https://gitlab.com/kicad/code/kicad/issues/2512
This commit is contained in:
Jeff Young 2021-08-19 22:28:54 +01:00
parent 1305c2177f
commit 4b6f2f0658
10 changed files with 1190 additions and 124 deletions

View File

@ -222,8 +222,6 @@ public:
void SetPolyShape( const SHAPE_POLY_SET& aShape ) { m_poly = aShape; }
void SetBezierPoints( const std::vector<wxPoint>& aPoints ) { m_bezierPoints = aPoints; }
/**
* Rebuild the m_BezierPoints vertex list that approximate the Bezier curve
* by a list of segments.

View File

@ -629,7 +629,7 @@ void DRC_ENGINE::RunTests( EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aT
zone->CacheBoundingBox();
zone->CacheTriangulation();
if( !zone->GetIsRuleArea() )
if( ( zone->GetLayerSet() & LSET::AllCuMask() ).any() && !zone->GetIsRuleArea() )
copperZones.push_back( zone );
}
@ -640,7 +640,7 @@ void DRC_ENGINE::RunTests( EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aT
zone->CacheBoundingBox();
zone->CacheTriangulation();
if( !zone->GetIsRuleArea() )
if( ( zone->GetLayerSet() & LSET::AllCuMask() ).any() && !zone->GetIsRuleArea() )
copperZones.push_back( zone );
}

View File

@ -98,7 +98,7 @@ private:
DRC_RTREE m_copperTree;
int m_drcEpsilon;
std::vector<ZONE*> m_zones;
std::vector<ZONE*> m_copperZones;
};
@ -121,13 +121,13 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::Run()
m_drcEpsilon = m_board->GetDesignSettings().GetDRCEpsilon();
m_zones.clear();
m_copperZones.clear();
for( ZONE* zone : m_board->Zones() )
{
if( !zone->GetIsRuleArea() )
if( ( zone->GetLayerSet() & LSET::AllCuMask() ).any() && !zone->GetIsRuleArea() )
{
m_zones.push_back( zone );
m_copperZones.push_back( zone );
m_largestClearance = std::max( m_largestClearance, zone->GetLocalClearance() );
}
}
@ -139,9 +139,9 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::Run()
for( ZONE* zone : footprint->Zones() )
{
if( !zone->GetIsRuleArea() )
if( ( zone->GetLayerSet() & LSET::AllCuMask() ).any() && !zone->GetIsRuleArea() )
{
m_zones.push_back( zone );
m_copperZones.push_back( zone );
m_largestClearance = std::max( m_largestClearance, zone->GetLocalClearance() );
}
}
@ -201,7 +201,7 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::Run()
forEachGeometryItem( itemTypes, LSET::AllCuMask(), countItems );
forEachGeometryItem( itemTypes, LSET::AllCuMask(), addToCopperTree );
reportAux( "Testing %d copper items and %d zones...", count, m_zones.size() );
reportAux( "Testing %d copper items and %d zones...", count, m_copperZones.size() );
if( !m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE ) )
{
@ -377,7 +377,7 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testItemAgainstZones( BOARD_ITEM* aItem,
PCB_LAYER_ID aLayer )
{
for( ZONE* zone : m_zones )
for( ZONE* zone : m_copperZones )
{
if( !zone->GetLayerSet().test( aLayer ) )
continue;
@ -840,34 +840,34 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
{
PCB_LAYER_ID layer = static_cast<PCB_LAYER_ID>( layer_id );
std::vector<SHAPE_POLY_SET> smoothed_polys;
smoothed_polys.resize( m_zones.size() );
smoothed_polys.resize( m_copperZones.size() );
// Skip over layers not used on the current board
if( !m_board->IsLayerEnabled( layer ) )
continue;
for( size_t ii = 0; ii < m_zones.size(); ii++ )
for( size_t ii = 0; ii < m_copperZones.size(); ii++ )
{
if( m_zones[ii]->IsOnLayer( layer ) )
m_zones[ii]->BuildSmoothedPoly( smoothed_polys[ii], layer, boardOutline );
if( m_copperZones[ii]->IsOnLayer( layer ) )
m_copperZones[ii]->BuildSmoothedPoly( smoothed_polys[ii], layer, boardOutline );
}
// iterate through all areas
for( size_t ia = 0; ia < m_zones.size(); ia++ )
for( size_t ia = 0; ia < m_copperZones.size(); ia++ )
{
if( !reportProgress( layer_id * m_zones.size() + ia, B_Cu * m_zones.size(), delta ) )
if( !reportProgress( layer_id * m_copperZones.size() + ia, B_Cu * m_copperZones.size(), delta ) )
break;
ZONE* zoneRef = m_zones[ia];
ZONE* zoneRef = m_copperZones[ia];
if( !zoneRef->IsOnLayer( layer ) )
continue;
// If we are testing a single zone, then iterate through all other zones
// Otherwise, we have already tested the zone combination
for( size_t ia2 = ia + 1; ia2 < m_zones.size(); ia2++ )
for( size_t ia2 = ia + 1; ia2 < m_copperZones.size(); ia2++ )
{
ZONE* zoneToTest = m_zones[ia2];
ZONE* zoneToTest = m_copperZones[ia2];
if( zoneRef == zoneToTest )
continue;

View File

@ -22,15 +22,16 @@
*/
#include <common.h>
#include <macros.h>
#include <board_design_settings.h>
#include <footprint.h>
#include <pad.h>
#include <pcb_track.h>
#include <pcb_shape.h>
#include <zone.h>
#include <advanced_config.h>
#include <geometry/seg.h>
#include <geometry/shape_segment.h>
#include <drc/drc_engine.h>
#include <drc/drc_rtree.h>
#include <drc/drc_item.h>
@ -77,7 +78,10 @@ private:
void testItemAgainstZones( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer );
void testZoneLayer( ZONE* aZone, PCB_LAYER_ID aLayer );
void testShapeLineChain( const SHAPE_LINE_CHAIN& aOutline, int aLineWidth,
BOARD_ITEM* aParentItem, DRC_CONSTRAINT& aConstraint );
void testZoneLayer( ZONE* aZone, PCB_LAYER_ID aLayer, DRC_CONSTRAINT& aConstraint );
private:
DRC_RTREE m_itemTree;
@ -93,6 +97,7 @@ bool DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::Run()
m_zones.clear();
m_items.clear();
int errorMax = m_board->GetDesignSettings().m_MaxError;
DRC_CONSTRAINT worstConstraint;
if( m_drcEngine->QueryWorstConstraint( MECHANICAL_CLEARANCE_CONSTRAINT, worstConstraint ) )
@ -231,7 +236,7 @@ bool DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::Run()
for( BOARD_ITEM* item : m_items )
{
if( !reportProgress( ii++, m_board->Tracks().size(), delta ) )
if( !reportProgress( ii++, m_items.size(), delta ) )
break;
for( PCB_LAYER_ID layer : item->GetLayerSet().Seq() )
@ -240,20 +245,41 @@ bool DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::Run()
}
count = 0;
forEachGeometryItem( { PCB_ZONE_T, PCB_FP_ZONE_T }, LSET::AllCuMask(),
forEachGeometryItem( { PCB_ZONE_T, PCB_FP_ZONE_T, PCB_SHAPE_T, PCB_FP_SHAPE_T },
LSET::AllCuMask(),
[&]( BOARD_ITEM* item ) -> bool
{
for( PCB_LAYER_ID layer : item->GetLayerSet().Seq() )
PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( item );
ZONE* zone = dynamic_cast<ZONE*>( item );
if( shape )
{
if( IsCopperLayer( layer ) )
switch( shape->GetShape() )
{
case SHAPE_T::POLY:
case SHAPE_T::BEZIER:
case SHAPE_T::ARC:
if( IsCopperLayer( shape->GetLayer() ) )
count++;
break;
default:
break;
}
}
if( zone )
{
count += ( item->GetLayerSet() & LSET::AllCuMask() ).count();
}
return true;
} );
ii = 0;
forEachGeometryItem( { PCB_ZONE_T, PCB_FP_ZONE_T }, LSET::AllCuMask(),
forEachGeometryItem( { PCB_ZONE_T, PCB_FP_ZONE_T, PCB_SHAPE_T, PCB_FP_SHAPE_T },
LSET::AllCuMask(),
[&]( BOARD_ITEM* item ) -> bool
{
for( PCB_LAYER_ID layer : item->GetLayerSet().Seq() )
@ -263,7 +289,66 @@ bool DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::Run()
if( !reportProgress( ii++, count, delta ) )
return false;
testZoneLayer( static_cast<ZONE*>( item ), layer );
PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( item );
ZONE* zone = dynamic_cast<ZONE*>( item );
DRC_CONSTRAINT c = m_drcEngine->EvalRules( MECHANICAL_CLEARANCE_CONSTRAINT,
item, nullptr, layer );
if( shape )
{
switch( shape->GetShape() )
{
case SHAPE_T::POLY:
testShapeLineChain( shape->GetPolyShape().Outline( 0 ),
shape->GetWidth(), item, c );
break;
case SHAPE_T::BEZIER:
{
SHAPE_LINE_CHAIN asPoly;
shape->RebuildBezierToSegmentsPointsList( shape->GetWidth() );
for( const wxPoint& pt : shape->GetBezierPoints() )
asPoly.Append( pt );
testShapeLineChain( asPoly, shape->GetWidth(), item, c );
break;
}
case SHAPE_T::ARC:
{
SHAPE_LINE_CHAIN asPoly;
wxPoint center = shape->GetCenter();
double angle = -shape->GetArcAngle();
double r = shape->GetRadius();
int steps = GetArcToSegmentCount( r, errorMax, angle / 10.0 );
asPoly.Append( shape->GetStart() );
for( int step = 1; step <= steps; ++step )
{
double rotation = ( angle * step ) / steps;
wxPoint pt = shape->GetStart();
RotatePoint( &pt, center, rotation );
asPoly.Append( pt );
}
testShapeLineChain( asPoly, shape->GetWidth(), item, c );
break;
}
default:
UNIMPLEMENTED_FOR( shape->SHAPE_T_asString() );
}
}
if( zone )
{
testZoneLayer( static_cast<ZONE*>( item ), layer, c );
}
}
}
@ -276,15 +361,154 @@ bool DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::Run()
}
void DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::testZoneLayer( ZONE* aZone, PCB_LAYER_ID aLayer )
void DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::testShapeLineChain( const SHAPE_LINE_CHAIN& aOutline,
int aLineWidth,
BOARD_ITEM* aParentItem,
DRC_CONSTRAINT& aConstraint )
{
// We don't want to collide with neighboring segments forming a curve until the concavity
// approaches 180 degrees.
double angleTolerance = DEG2RAD( 180.0 - ADVANCED_CFG::GetCfg().m_SliverAngleTolerance );
int epsilon = m_board->GetDesignSettings().GetDRCEpsilon();
int count = aOutline.SegmentCount();
int clearance = aConstraint.GetValue().Min();
// Trigonometry is not cheap; cache seg angles
std::vector<double> angles;
angles.reserve( count );
auto angleDiff =
[]( double a, double b ) -> double
{
if( a > b )
std::swap( a, b );
double diff = b - a;
if( diff > M_PI )
return 2 * M_PI - diff;
else
return diff;
};
for( int ii = 0; ii < count; ++ii )
{
const SEG& seg = aOutline.CSegment( ii );
// NB: don't store angles of really short segments (which could point anywhere)
if( seg.SquaredLength() > SEG::Square( epsilon * 2 ) )
{
angles.push_back( ( seg.B - seg.A ).Angle() );
}
else if( ii > 0 )
{
angles.push_back( angles.back() );
}
else
{
for( int jj = 1; jj < count; ++jj )
{
const SEG& following = aOutline.CSegment( jj );
if( following.SquaredLength() > SEG::Square( epsilon * 2 ) || jj == count - 1 )
{
angles.push_back( ( following.B - following.A ).Angle() );
break;
}
}
}
}
// Find collisions before reporting so that we can condense them into fewer reports.
std::vector< std::pair<VECTOR2I, int> > collisions;
for( int ii = 0; ii < count; ++ii )
{
const SEG seg = aOutline.CSegment( ii );
double segAngle = angles[ ii ];
// Exclude segments on either side of us until we reach the angle tolerance
int firstCandidate = ii + 1;
int lastCandidate = count - 1;
while( firstCandidate < count )
{
if( angleDiff( segAngle, angles[ firstCandidate ] ) < angleTolerance )
firstCandidate++;
else
break;
}
if( aOutline.IsClosed() )
{
if( ii > 0 )
lastCandidate = ii - 1;
while( lastCandidate != std::min( firstCandidate, count - 1 ) )
{
if( angleDiff( segAngle, angles[ lastCandidate ] ) < angleTolerance )
lastCandidate = ( lastCandidate == 0 ) ? count - 1 : lastCandidate - 1;
else
break;
}
}
// Now run the collision between seg and each candidate seg in the candidate range.
if( lastCandidate < ii )
lastCandidate = count - 1;
for( int jj = firstCandidate; jj <= lastCandidate; ++jj )
{
const SEG candidate = aOutline.CSegment( jj );
int actual;
if( seg.Collide( candidate, clearance + aLineWidth - epsilon, &actual ) )
{
VECTOR2I firstPoint = seg.NearestPoint( candidate );
VECTOR2I secondPoint = candidate.NearestPoint( seg );
VECTOR2I pos = ( firstPoint + secondPoint ) / 2;
if( !collisions.empty() &&
( pos - collisions.back().first ).EuclideanNorm() < clearance * 2 )
{
if( actual < collisions.back().second )
{
collisions.back().first = pos;
collisions.back().second = actual;
}
continue;
}
collisions.push_back( { pos, actual } );
}
}
}
for( std::pair<VECTOR2I, int> collision : collisions )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
aConstraint.GetName(),
MessageTextFromValue( userUnits(), clearance ),
MessageTextFromValue( userUnits(), collision.second ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetItems( aParentItem );
drce->SetViolatingRule( aConstraint.GetParentRule() );
reportViolation( drce, (wxPoint) collision.first );
}
}
void DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::testZoneLayer( ZONE* aZone, PCB_LAYER_ID aLayer,
DRC_CONSTRAINT& aConstraint )
{
int epsilon = m_board->GetDesignSettings().GetDRCEpsilon();
int clearance = aConstraint.GetValue().Min();
SHAPE_POLY_SET fill = aZone->GetFilledPolysList( aLayer );
DRC_CONSTRAINT constraint;
int clearance;
constraint = m_drcEngine->EvalRules( MECHANICAL_CLEARANCE_CONSTRAINT, aZone, nullptr, aLayer );
clearance = constraint.GetValue().Min();
if( clearance - epsilon <= 0 )
return;
@ -313,13 +537,13 @@ void DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::testZoneLayer( ZONE* aZone, PCB_LAY
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
aConstraint.GetName(),
MessageTextFromValue( userUnits(), clearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetItems( aZone );
drce->SetViolatingRule( constraint.GetParentRule() );
drce->SetViolatingRule( aConstraint.GetParentRule() );
reportViolation( drce, (wxPoint) pos );
}
@ -330,76 +554,7 @@ void DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::testZoneLayer( ZONE* aZone, PCB_LAY
for( int holeIdx = 0; holeIdx < fill.HoleCount( outlineIdx ); ++holeIdx )
{
SHAPE_LINE_CHAIN hole = fill.Hole( outlineIdx, holeIdx );
int count = hole.SegmentCount();
int distanceBackToStart = 0;
std::vector< std::pair<VECTOR2I, int> > collisions;
for( int ii = 0; ii < count; ++ii )
{
SEG seg = hole.Segment( ii );
// We don't want to collide with neighboring segments within clearance distance,
// so we first need to set the firstCandidate and lastCandidate bounds of our
// search.
int firstCandidate = ii + 1;
int lastCandidate = count - 1;
int dist = 0;
while( firstCandidate < count && dist < clearance * 2 )
dist += hole.Segment( firstCandidate++ ).Length();
dist = distanceBackToStart;
while( lastCandidate >= firstCandidate && dist < clearance * 2 )
dist += hole.Segment( lastCandidate-- ).Length();
// Now run the collision between seg and each seg in the candidate range.
for( int jj = firstCandidate; jj <= lastCandidate; ++jj )
{
SEG candidate = hole.Segment( jj );
int actual;
if( seg.Collide( candidate, clearance - epsilon, &actual ) )
{
VECTOR2I firstPoint = seg.NearestPoint( candidate );
VECTOR2I secondPoint = candidate.NearestPoint( seg );
VECTOR2I pos = ( firstPoint + secondPoint ) / 2;
if( !collisions.empty() &&
( pos - collisions.back().first ).EuclideanNorm() < clearance * 2 )
{
if( actual < collisions.back().second )
{
collisions.back().first = pos;
collisions.back().second = actual;
}
continue;
}
collisions.push_back( { pos, actual } );
}
}
distanceBackToStart += seg.Length();
}
for( std::pair<VECTOR2I, int> collision : collisions )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), clearance ),
MessageTextFromValue( userUnits(), collision.second ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetItems( aZone );
drce->SetViolatingRule( constraint.GetParentRule() );
reportViolation( drce, (wxPoint) collision.first );
}
testShapeLineChain( fill.Hole( outlineIdx, holeIdx ), 0, aZone, aConstraint );
}
}
}
@ -547,6 +702,7 @@ void DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::testItemAgainstZones( BOARD_ITEM* a
DRC_RTREE* zoneTree = m_board->m_CopperZoneRTrees[ zone ].get();
EDA_RECT itemBBox = aItem->GetBoundingBox();
DRC_CONSTRAINT constraint;
bool colliding;
int clearance = -1;
int actual;
VECTOR2I pos;
@ -583,8 +739,18 @@ void DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::testItemAgainstZones( BOARD_ITEM* a
}
}
if( zoneTree->QueryColliding( itemBBox, itemShape.get(), aLayer, clearance,
&actual, &pos ) )
if( zoneTree )
{
colliding = zoneTree->QueryColliding( itemBBox, itemShape.get(), aLayer,
clearance, &actual, &pos );
}
else
{
colliding = zone->Outline()->Collide( itemShape.get(), clearance, &actual,
&pos );
}
if( colliding )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );

View File

@ -0,0 +1,11 @@
(version 1)
#(rule mine
# (condition "A.NetName == 'GND'")
# (constraint clearance (min 2mm)))
(rule "SilkZoneOverPads"
(condition "A.Type == 'zone' && A.existsOnLayer('*.Silkscreen') && B.existsOnLayer('*.Mask')")
(constraint silk_clearance (min -0.1mm)))
(rule mech
(constraint mechanical_clearance (min 0.1mm)))

428
qa/data/issue2512.kicad_pcb Normal file
View File

@ -0,0 +1,428 @@
(kicad_pcb (version 20210812) (generator pcbnew)
(general
(thickness 4.48)
)
(paper "A4")
(title_block
(title "Demo Project showing SameNetSpacing problem caused by KiCads filling algorithm")
(date "2019-10-07")
(rev "0.1")
)
(layers
(0 "F.Cu" signal)
(1 "In1.Cu" power)
(2 "In2.Cu" power)
(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)
)
(setup
(stackup
(layer "F.SilkS" (type "Top Silk Screen"))
(layer "F.Paste" (type "Top Solder Paste"))
(layer "F.Mask" (type "Top Solder Mask") (color "Green") (thickness 0.01))
(layer "F.Cu" (type "copper") (thickness 0.035))
(layer "dielectric 1" (type "core") (thickness 1.44) (material "FR4") (epsilon_r 4.5) (loss_tangent 0.02))
(layer "In1.Cu" (type "copper") (thickness 0.035))
(layer "dielectric 2" (type "prepreg") (thickness 1.44) (material "FR4") (epsilon_r 4.5) (loss_tangent 0.02))
(layer "In2.Cu" (type "copper") (thickness 0.035))
(layer "dielectric 3" (type "core") (thickness 1.44) (material "FR4") (epsilon_r 4.5) (loss_tangent 0.02))
(layer "B.Cu" (type "copper") (thickness 0.035))
(layer "B.Mask" (type "Bottom Solder Mask") (color "Green") (thickness 0.01))
(layer "B.Paste" (type "Bottom Solder Paste"))
(layer "B.SilkS" (type "Bottom Silk Screen"))
(copper_finish "None")
(dielectric_constraints no)
)
(pad_to_mask_clearance 0.05)
(solder_mask_min_width 0.15)
(aux_axis_origin 148.5 105)
(pcbplotparams
(layerselection 0x00010fc_ffffffff)
(disableapertmacros false)
(usegerberextensions false)
(usegerberattributes false)
(usegerberadvancedattributes false)
(creategerberjobfile false)
(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 0)
(scaleselection 1)
(outputdirectory "gerber/")
)
)
(net 0 "")
(net 1 "GND")
(net 2 "VDD3V3")
(gr_arc (start 143.1036 129.9464) (end 142.240001 129.3876) (angle 350.9270568) (layer "In2.Cu") (width 0.1) (tstamp 6ba5cc1c-0aa9-403c-8c78-baeb88b53289))
(gr_poly
(pts
(xy 144.3736 127.3048)
(xy 142.5956 127.3048)
(xy 144.3736 128.27)
(xy 144.3736 128.5748)
(xy 142.0876 128.5748)
(xy 142.0876 126.2888)
(xy 144.3736 126.2888)
) (layer "In2.Cu") (width 0.1) (fill solid) (tstamp abd486ea-b329-4192-afc3-c44eb6e87cea))
(gr_poly
(pts
(xy 147.4216 129.8956)
(xy 145.3896 129.9464)
(xy 145.3896 130.0988)
(xy 147.4216 130.2512)
(xy 147.4216 131.1656)
(xy 144.8816 131.1656)
(xy 144.8816 128.8796)
(xy 147.4216 128.8796)
) (layer "In2.Cu") (width 0.1) (fill solid) (tstamp b158edbd-63ca-41e4-8234-a443de3cf560))
(gr_poly
(pts
(xy 147.4216 127.3048)
(xy 145.3896 127.3556)
(xy 145.3896 127.4064)
(xy 147.4216 127.6604)
(xy 147.4216 128.5748)
(xy 144.8816 128.5748)
(xy 144.8816 126.2888)
(xy 147.4216 126.2888)
) (layer "In2.Cu") (width 0) (fill solid) (tstamp dda81f80-2a0f-4292-9d5e-54a02cef836f))
(gr_rect (start 136.2456 125.5776) (end 147.864 131.7576) (layer "Edge.Cuts") (width 0.01) (fill none) (tstamp 2ff03438-48dd-4ff9-86ab-4aae55d6a1a4))
(via (at 138.2268 129.4445) (size 0.6096) (drill 0.3048) (layers "F.Cu" "B.Cu") (net 1) (tstamp 0a0bd538-0f11-4f77-8877-7ded1f64a1f5))
(via (at 140.681801 128.8692) (size 0.6096) (drill 0.3048) (layers "F.Cu" "B.Cu") (net 1) (tstamp 278fe112-f2ff-479a-a63f-0a6506627139))
(via (at 140.046801 129.4788) (size 0.6096) (drill 0.3048) (layers "F.Cu" "B.Cu") (net 1) (tstamp 6991baf3-a77e-489b-a4f3-31121be3dfdc))
(via (at 137.5233 128.666) (size 0.6096) (drill 0.3048) (layers "F.Cu" "B.Cu") (net 1) (tstamp e48c293e-c06c-440a-8604-01ac35e3346f))
(zone (net 2) (net_name "VDD3V3") (layer "In2.Cu") (tstamp 00000000-0000-0000-0000-00005d9bbec6) (hatch none 0.508)
(connect_pads (clearance 0.1524))
(min_thickness 0.1524) (filled_areas_thickness no)
(fill yes (thermal_gap 0.1524) (thermal_bridge_width 1.27) (island_removal_mode 1) (island_area_min 0))
(polygon
(pts
(xy 136.7048 126.6)
(xy 136.7048 130.8)
(xy 141.5 130.8)
(xy 141.5 126.6)
)
)
(filled_polygon
(layer "In2.Cu")
(island)
(pts
(xy 141.473138 126.617593)
(xy 141.498858 126.662142)
(xy 141.5 126.6752)
(xy 141.5 130.7248)
(xy 141.482407 130.773138)
(xy 141.437858 130.798858)
(xy 141.4248 130.8)
(xy 136.78 130.8)
(xy 136.731662 130.782407)
(xy 136.705942 130.737858)
(xy 136.7048 130.7248)
(xy 136.7048 128.660332)
(xy 137.059413 128.660332)
(xy 137.060107 128.66564)
(xy 137.060107 128.665642)
(xy 137.061636 128.677335)
(xy 137.076468 128.790758)
(xy 137.078626 128.795662)
(xy 137.078626 128.795663)
(xy 137.085758 128.811871)
(xy 137.129443 128.911154)
(xy 137.214081 129.011843)
(xy 137.21854 129.014811)
(xy 137.218541 129.014812)
(xy 137.290203 129.062514)
(xy 137.323576 129.084729)
(xy 137.328688 129.086326)
(xy 137.32869 129.086327)
(xy 137.36913 129.098961)
(xy 137.449128 129.123954)
(xy 137.50373 129.124955)
(xy 137.575279 129.126267)
(xy 137.575281 129.126267)
(xy 137.580641 129.126365)
(xy 137.585812 129.124955)
(xy 137.585814 129.124955)
(xy 137.65404 129.106354)
(xy 137.707546 129.091767)
(xy 137.732892 129.076204)
(xy 137.755189 129.062514)
(xy 137.805587 129.052214)
(xy 137.850815 129.07672)
(xy 137.869709 129.124564)
(xy 137.850901 129.176378)
(xy 137.839051 129.189796)
(xy 137.783149 129.308862)
(xy 137.782325 129.314152)
(xy 137.782325 129.314153)
(xy 137.778563 129.338316)
(xy 137.762913 129.438832)
(xy 137.763607 129.44414)
(xy 137.763607 129.444142)
(xy 137.774841 129.530047)
(xy 137.779968 129.569258)
(xy 137.782126 129.574162)
(xy 137.782126 129.574163)
(xy 137.789258 129.590371)
(xy 137.832943 129.689654)
(xy 137.917581 129.790343)
(xy 137.92204 129.793311)
(xy 137.922041 129.793312)
(xy 137.962947 129.820541)
(xy 138.027076 129.863229)
(xy 138.032188 129.864826)
(xy 138.03219 129.864827)
(xy 138.049603 129.870267)
(xy 138.152628 129.902454)
(xy 138.20723 129.903455)
(xy 138.278779 129.904767)
(xy 138.278781 129.904767)
(xy 138.284141 129.904865)
(xy 138.289312 129.903455)
(xy 138.289314 129.903455)
(xy 138.35754 129.884854)
(xy 138.411046 129.870267)
(xy 138.523138 129.801441)
(xy 138.611409 129.703922)
(xy 138.668761 129.585548)
(xy 138.684331 129.493003)
(xy 138.687674 129.473132)
(xy 139.582914 129.473132)
(xy 139.583608 129.47844)
(xy 139.583608 129.478442)
(xy 139.585137 129.490135)
(xy 139.599969 129.603558)
(xy 139.602127 129.608462)
(xy 139.602127 129.608463)
(xy 139.64413 129.703922)
(xy 139.652944 129.723954)
(xy 139.737582 129.824643)
(xy 139.742041 129.827611)
(xy 139.742042 129.827612)
(xy 139.842615 129.894559)
(xy 139.847077 129.897529)
(xy 139.852189 129.899126)
(xy 139.852191 129.899127)
(xy 139.870558 129.904865)
(xy 139.972629 129.936754)
(xy 140.027231 129.937755)
(xy 140.09878 129.939067)
(xy 140.098782 129.939067)
(xy 140.104142 129.939165)
(xy 140.109313 129.937755)
(xy 140.109315 129.937755)
(xy 140.177541 129.919154)
(xy 140.231047 129.904567)
(xy 140.343139 129.835741)
(xy 140.43141 129.738222)
(xy 140.488762 129.619848)
(xy 140.498168 129.563942)
(xy 140.510103 129.493003)
(xy 140.510104 129.492996)
(xy 140.510585 129.490135)
(xy 140.510723 129.4788)
(xy 140.500346 129.406338)
(xy 140.51091 129.355995)
(xy 140.551362 129.32422)
(xy 140.597214 129.3239)
(xy 140.607629 129.327154)
(xy 140.662231 129.328155)
(xy 140.73378 129.329467)
(xy 140.733782 129.329467)
(xy 140.739142 129.329565)
(xy 140.744313 129.328155)
(xy 140.744315 129.328155)
(xy 140.832855 129.304016)
(xy 140.866047 129.294967)
(xy 140.978139 129.226141)
(xy 141.06641 129.128622)
(xy 141.069446 129.122357)
(xy 141.102639 129.053845)
(xy 141.123762 129.010248)
(xy 141.136223 128.936181)
(xy 141.145103 128.883403)
(xy 141.145104 128.883396)
(xy 141.145585 128.880535)
(xy 141.145723 128.8692)
(xy 141.144912 128.863532)
(xy 141.127835 128.74429)
(xy 141.127834 128.744287)
(xy 141.127076 128.738993)
(xy 141.072633 128.619252)
(xy 141.065076 128.610481)
(xy 140.990267 128.523661)
(xy 140.990266 128.523661)
(xy 140.986772 128.519605)
(xy 140.876394 128.448062)
(xy 140.833494 128.435232)
(xy 140.755507 128.411909)
(xy 140.755504 128.411909)
(xy 140.750373 128.410374)
(xy 140.745018 128.410341)
(xy 140.745016 128.410341)
(xy 140.686019 128.409981)
(xy 140.61884 128.40957)
(xy 140.492368 128.445716)
(xy 140.381124 128.515906)
(xy 140.294052 128.614496)
(xy 140.23815 128.733562)
(xy 140.237326 128.738852)
(xy 140.237326 128.738853)
(xy 140.230593 128.7821)
(xy 140.217914 128.863532)
(xy 140.218608 128.868839)
(xy 140.218608 128.868841)
(xy 140.228334 128.943215)
(xy 140.217157 128.993426)
(xy 140.17632 129.024705)
(xy 140.132222 129.025013)
(xy 140.131193 129.024705)
(xy 140.126702 129.023362)
(xy 140.120507 129.021509)
(xy 140.120504 129.021509)
(xy 140.115373 129.019974)
(xy 140.110018 129.019941)
(xy 140.110016 129.019941)
(xy 140.051019 129.019581)
(xy 139.98384 129.01917)
(xy 139.857368 129.055316)
(xy 139.746124 129.125506)
(xy 139.659052 129.224096)
(xy 139.636962 129.271145)
(xy 139.611416 129.325557)
(xy 139.60315 129.343162)
(xy 139.582914 129.473132)
(xy 138.687674 129.473132)
(xy 138.690102 129.458703)
(xy 138.690103 129.458696)
(xy 138.690584 129.455835)
(xy 138.690722 129.4445)
(xy 138.689911 129.438832)
(xy 138.672834 129.31959)
(xy 138.672833 129.319587)
(xy 138.672075 129.314293)
(xy 138.652457 129.271145)
(xy 138.619851 129.199432)
(xy 138.61985 129.199431)
(xy 138.617632 129.194552)
(xy 138.610075 129.185781)
(xy 138.535266 129.098961)
(xy 138.535265 129.098961)
(xy 138.531771 129.094905)
(xy 138.474312 129.057662)
(xy 138.425886 129.026274)
(xy 138.425885 129.026274)
(xy 138.421393 129.023362)
(xy 138.359874 129.004964)
(xy 138.300506 128.987209)
(xy 138.300503 128.987209)
(xy 138.295372 128.985674)
(xy 138.290017 128.985641)
(xy 138.290015 128.985641)
(xy 138.231018 128.985281)
(xy 138.163839 128.98487)
(xy 138.037367 129.021016)
(xy 138.032841 129.023872)
(xy 138.032836 129.023874)
(xy 137.998055 129.045819)
(xy 137.947787 129.056733)
(xy 137.902263 129.032782)
(xy 137.882786 128.985172)
(xy 137.898468 128.936181)
(xy 137.902162 128.931771)
(xy 137.907909 128.925422)
(xy 137.965261 128.807048)
(xy 137.968896 128.785442)
(xy 137.986602 128.680203)
(xy 137.986603 128.680196)
(xy 137.987084 128.677335)
(xy 137.987222 128.666)
(xy 137.986411 128.660332)
(xy 137.969334 128.54109)
(xy 137.969333 128.541087)
(xy 137.968575 128.535793)
(xy 137.93001 128.450974)
(xy 137.916351 128.420932)
(xy 137.91635 128.420931)
(xy 137.914132 128.416052)
(xy 137.906575 128.407281)
(xy 137.831766 128.320461)
(xy 137.831765 128.320461)
(xy 137.828271 128.316405)
(xy 137.717893 128.244862)
(xy 137.674993 128.232032)
(xy 137.597006 128.208709)
(xy 137.597003 128.208709)
(xy 137.591872 128.207174)
(xy 137.586517 128.207141)
(xy 137.586515 128.207141)
(xy 137.527518 128.206781)
(xy 137.460339 128.20637)
(xy 137.333867 128.242516)
(xy 137.222623 128.312706)
(xy 137.135551 128.411296)
(xy 137.133275 128.416144)
(xy 137.087778 128.513049)
(xy 137.079649 128.530362)
(xy 137.078825 128.535652)
(xy 137.078825 128.535653)
(xy 137.072092 128.5789)
(xy 137.059413 128.660332)
(xy 136.7048 128.660332)
(xy 136.7048 126.6752)
(xy 136.722393 126.626862)
(xy 136.766942 126.601142)
(xy 136.78 126.6)
(xy 141.4248 126.6)
)
)
)
)

459
qa/data/issue2512.kicad_pro Normal file
View File

@ -0,0 +1,459 @@
{
"board": {
"design_settings": {
"defaults": {
"board_outline_line_width": 0.09999999999999999,
"copper_line_width": 0.09999999999999999,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.049999999999999996,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.09999999999999999,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.09999999999999999,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 0.0,
"height": 0.95,
"width": 0.875
},
"silk_line_width": 0.15,
"silk_text_italic": false,
"silk_text_size_h": 0.7,
"silk_text_size_v": 0.7,
"silk_text_thickness": 0.15,
"silk_text_upright": false,
"zones": {
"45_degree_only": false,
"min_clearance": 0.15239999999999998
}
},
"diff_pair_dimensions": [
{
"gap": 0.0,
"via_gap": 0.0,
"width": 0.0
}
],
"drc_exclusions": [],
"meta": {
"filename": "board_design_settings.json",
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"copper_edge_clearance": "error",
"copper_sliver": "warning",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"hole_clearance": "error",
"hole_near_hole": "error",
"invalid_outline": "error",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"lib_footprint_issues": "error",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "error",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"solder_mask_bridge": "error",
"starved_thermal": "error",
"text_height": "warning",
"text_thickness": "warning",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "ignore",
"unresolved_variable": "error",
"via_dangling": "ignore",
"zone_has_empty_net": "ignore",
"zones_intersect": "error"
},
"rules": {
"allow_blind_buried_vias": false,
"allow_microvias": false,
"max_error": 0.005,
"min_clearance": 0.0,
"min_copper_edge_clearance": 0.0,
"min_hole_clearance": 0.0,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.19999999999999998,
"min_microvia_drill": 0.09999999999999999,
"min_resolved_spokes": 2,
"min_silk_clearance": 0.0,
"min_text_height": 0.7999999999999999,
"min_text_thickness": 0.12,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.19999999999999998,
"min_via_annular_width": 0.049999999999999996,
"min_via_diameter": 0.39999999999999997,
"use_height_for_length_calcs": true
},
"track_widths": [
0.0,
0.1524,
0.2032,
0.254,
0.3048,
0.4064,
0.508,
0.6096,
0.762,
1.016,
6.000001
],
"via_dimensions": [
{
"diameter": 0.0,
"drill": 0.0
},
{
"diameter": 0.6096,
"drill": 0.3048
}
],
"zones_allow_external_fillets": false,
"zones_use_no_outline": true
},
"layer_presets": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_label_syntax": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "error",
"no_connect_dangling": "error",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "error",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "issue2512.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12.0,
"clearance": 0.1524,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.25,
"via_diameter": 0.6,
"via_drill": 0.4,
"wire_width": 6.0
}
],
"meta": {
"version": 1
},
"net_colors": null
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"specctra_dsn": "",
"step": "",
"vmrl": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"drawing": {
"dashed_lines_dash_length_ratio": 5.0,
"dashed_lines_gap_length_ratio": 3.0,
"default_bus_thickness": 12.0,
"default_junction_size": 36.0,
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"default_wire_thickness": 6.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.3,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.3
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "",
"ngspice": {
"fix_include_paths": true,
"fix_passive_vals": false,
"meta": {
"version": 0
},
"model_mode": 0,
"workbook_filename": ""
},
"page_layout_descr_file": "",
"plot_directory": "",
"spice_adjust_passive_values": false,
"spice_external_command": "spice \"%I\"",
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"7ab16063-d1b0-49de-9b3e-10ea1f7e76a7",
""
]
],
"text_variables": {}
}

View File

@ -316,7 +316,7 @@
"pinned_symbol_libs": []
},
"meta": {
"filename": "hole_pad_clearance.kicad_pro",
"filename": "issue5978.kicad_pro",
"version": 1
},
"net_settings": {
@ -376,7 +376,7 @@
}
],
"meta": {
"version": 0
"version": 1
},
"net_colors": null
},

View File

@ -57,16 +57,17 @@
],
"drc_exclusions": [],
"meta": {
"version": 1
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"copper_edge_clearance": "error",
"copper_sliver": "warning",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_too_small": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"hole_clearance": "error",
@ -74,11 +75,10 @@
"invalid_outline": "error",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"keepout": "error",
"length_out_of_range": "error",
"lib_footprint_issues": "ignore",
"malformed_courtyard": "error",
"microvia_drill_too_small": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
@ -90,6 +90,9 @@
"silk_overlap": "error",
"skew_out_of_range": "error",
"solder_mask_bridge": "ignore",
"starved_thermal": "error",
"text_height": "warning",
"text_thickness": "warning",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
@ -97,7 +100,6 @@
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"via_hole_larger_than_pad": "error",
"zone_has_empty_net": "error",
"zones_intersect": "error"
},
@ -107,19 +109,20 @@
"max_error": 0.005,
"min_clearance": 0.2032,
"min_copper_edge_clearance": 0.3,
"min_hole_clearance": 0.0,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.39877999999999997,
"min_microvia_drill": 0.29972,
"min_resolved_spokes": 2,
"min_silk_clearance": 0.0,
"min_text_height": 0.7999999999999999,
"min_text_thickness": 0.12,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.2032,
"min_via_annular_width": 0.049999999999999996,
"min_via_annulus": 0.15,
"min_via_diameter": 0.6,
"solder_mask_clearance": 0.15239999999999998,
"solder_mask_min_width": 0.15239999999999998,
"solder_paste_clearance": 0.0,
"solder_paste_margin_ratio": -0.0
"use_height_for_length_calcs": true
},
"track_widths": [
0.0,
@ -411,7 +414,7 @@
],
"hidden_nets": [],
"meta": {
"version": 0
"version": 1
},
"net_colors": null
},

View File

@ -104,6 +104,7 @@ BOOST_FIXTURE_TEST_CASE( DRCFalseNegativeRegressions, DRC_REGRESSION_TEST_FIXTUR
// These documents at one time failed to catch DRC errors that they should have.
std::vector< std::pair<wxString, int> > tests = { { "issue1358", 2 },
{ "issue2512", 4 },
{ "issue2528", 1 },
{ "issue5750", 4 },
{ "issue5854", 3 },