Rework silk-to-pad checker to handle all solder mask clipping of silk.
Fixes https://gitlab.com/kicad/code/kicad/issues/5851
This commit is contained in:
parent
36ceb8075e
commit
85c6cebd77
|
@ -29,7 +29,7 @@ zone
|
||||||
edge_clearance
|
edge_clearance
|
||||||
hole_clearance
|
hole_clearance
|
||||||
courtyard_clearance
|
courtyard_clearance
|
||||||
silk_to_pad
|
silk_to_mask
|
||||||
silk_to_silk
|
silk_to_silk
|
||||||
skew
|
skew
|
||||||
diff_pair_gap
|
diff_pair_gap
|
||||||
|
|
|
@ -250,7 +250,7 @@ set( PCBNEW_DRC_SRCS
|
||||||
drc/drc_test_provider_misc.cpp
|
drc/drc_test_provider_misc.cpp
|
||||||
drc/drc_test_provider_track_width.cpp
|
drc/drc_test_provider_track_width.cpp
|
||||||
drc/drc_test_provider_via_diameter.cpp
|
drc/drc_test_provider_via_diameter.cpp
|
||||||
drc/drc_test_provider_silk_to_pad.cpp
|
drc/drc_test_provider_silk_to_mask.cpp
|
||||||
drc/drc_test_provider_silk_to_silk.cpp
|
drc/drc_test_provider_silk_to_silk.cpp
|
||||||
drc/drc_test_provider_matched_length.cpp
|
drc/drc_test_provider_matched_length.cpp
|
||||||
drc/drc_test_provider_diff_pair_coupling.cpp
|
drc/drc_test_provider_diff_pair_coupling.cpp
|
||||||
|
|
|
@ -200,11 +200,22 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
|
||||||
if( context == SEXPR_OPEN )
|
if( context == SEXPR_OPEN )
|
||||||
{
|
{
|
||||||
if( sexprs.empty() )
|
if( sexprs.empty() )
|
||||||
tokens = "rule version";
|
{
|
||||||
|
tokens = "rule "
|
||||||
|
"version";
|
||||||
|
}
|
||||||
else if( sexprs.top() == "rule" )
|
else if( sexprs.top() == "rule" )
|
||||||
tokens = "condition constraint layer";
|
{
|
||||||
|
tokens = "condition "
|
||||||
|
"constraint "
|
||||||
|
"layer";
|
||||||
|
}
|
||||||
else if( sexprs.top() == "constraint" )
|
else if( sexprs.top() == "constraint" )
|
||||||
tokens = "max min opt";
|
{
|
||||||
|
tokens = "max "
|
||||||
|
"min "
|
||||||
|
"opt";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( context == SEXPR_TOKEN )
|
else if( context == SEXPR_TOKEN )
|
||||||
{
|
{
|
||||||
|
@ -214,7 +225,20 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
|
||||||
}
|
}
|
||||||
else if( sexprs.top() == "constraint" )
|
else if( sexprs.top() == "constraint" )
|
||||||
{
|
{
|
||||||
tokens = "annulus_width clearance disallow hole track_width";
|
tokens = "annulus_width "
|
||||||
|
"clearance "
|
||||||
|
"courtyard_clearance "
|
||||||
|
"diff_pair_gap "
|
||||||
|
"diff_pair_uncoupled "
|
||||||
|
"disallow "
|
||||||
|
"edge_clearance "
|
||||||
|
"length "
|
||||||
|
"hole "
|
||||||
|
"hole_clearance "
|
||||||
|
"silk_to_mask "
|
||||||
|
"silk_to_silk skew "
|
||||||
|
"track_width "
|
||||||
|
"via_count ";
|
||||||
}
|
}
|
||||||
else if( sexprs.top() == "disallow"
|
else if( sexprs.top() == "disallow"
|
||||||
|| sexprs.top() == "buried_via"
|
|| sexprs.top() == "buried_via"
|
||||||
|
@ -227,11 +251,21 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
|
||||||
|| sexprs.top() == "via"
|
|| sexprs.top() == "via"
|
||||||
|| sexprs.top() == "zone" )
|
|| sexprs.top() == "zone" )
|
||||||
{
|
{
|
||||||
tokens = "buried_via graphic hole micro_via pad text track via zone";
|
tokens = "buried_via "
|
||||||
|
"graphic "
|
||||||
|
"hole "
|
||||||
|
"micro_via "
|
||||||
|
"pad "
|
||||||
|
"text "
|
||||||
|
"track "
|
||||||
|
"via "
|
||||||
|
"zone";
|
||||||
}
|
}
|
||||||
else if( sexprs.top() == "layer" )
|
else if( sexprs.top() == "layer" )
|
||||||
{
|
{
|
||||||
tokens = "inner outer \"x\"";
|
tokens = "inner "
|
||||||
|
"outer "
|
||||||
|
"\"x\"";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( context == STRING && !sexprs.empty() && sexprs.top() == "condition" )
|
else if( context == STRING && !sexprs.empty() && sexprs.top() == "condition" )
|
||||||
|
|
|
@ -126,7 +126,7 @@ void DRC_ENGINE::loadImplicitRules()
|
||||||
holeClearanceConstraint.Value().SetMin( 0 );
|
holeClearanceConstraint.Value().SetMin( 0 );
|
||||||
rule->AddConstraint( courtyardClearanceConstraint );
|
rule->AddConstraint( courtyardClearanceConstraint );
|
||||||
|
|
||||||
DRC_CONSTRAINT silkToPadClearanceConstraint( DRC_CONSTRAINT_TYPE_SILK_TO_PAD );
|
DRC_CONSTRAINT silkToPadClearanceConstraint( DRC_CONSTRAINT_TYPE_SILK_TO_MASK );
|
||||||
silkToPadClearanceConstraint.Value().SetMin( 0 );
|
silkToPadClearanceConstraint.Value().SetMin( 0 );
|
||||||
rule->AddConstraint( silkToPadClearanceConstraint );
|
rule->AddConstraint( silkToPadClearanceConstraint );
|
||||||
|
|
||||||
|
@ -237,21 +237,21 @@ static wxString formatConstraint( const DRC_CONSTRAINT& constraint )
|
||||||
|
|
||||||
std::vector<Formatter> formats =
|
std::vector<Formatter> formats =
|
||||||
{
|
{
|
||||||
{ DRC_CONSTRAINT_TYPE_UNKNOWN, "unknown", nullptr },
|
{ DRC_CONSTRAINT_TYPE_UNKNOWN, "unknown", nullptr },
|
||||||
{ DRC_CONSTRAINT_TYPE_CLEARANCE, "clearance", formatMinMax },
|
{ DRC_CONSTRAINT_TYPE_CLEARANCE, "clearance", formatMinMax },
|
||||||
{ DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE, "hole_clearance", formatMinMax },
|
{ DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE, "hole_clearance", formatMinMax },
|
||||||
{ DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE, "edge_clearance", formatMinMax },
|
{ DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE, "edge_clearance", formatMinMax },
|
||||||
{ DRC_CONSTRAINT_TYPE_HOLE_SIZE, "hole_size", formatMinMax },
|
{ DRC_CONSTRAINT_TYPE_HOLE_SIZE, "hole_size", formatMinMax },
|
||||||
{ DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE, "courtyard_clearance", formatMinMax },
|
{ DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE, "courtyard_clearance", formatMinMax },
|
||||||
{ DRC_CONSTRAINT_TYPE_SILK_TO_PAD, "silk_to_pad", formatMinMax },
|
{ DRC_CONSTRAINT_TYPE_SILK_TO_MASK, "silk_to_mask", formatMinMax },
|
||||||
{ DRC_CONSTRAINT_TYPE_SILK_TO_SILK, "silk_to_silk", formatMinMax },
|
{ DRC_CONSTRAINT_TYPE_SILK_TO_SILK, "silk_to_silk", formatMinMax },
|
||||||
{ DRC_CONSTRAINT_TYPE_TRACK_WIDTH, "track_width", formatMinMax },
|
{ DRC_CONSTRAINT_TYPE_TRACK_WIDTH, "track_width", formatMinMax },
|
||||||
{ DRC_CONSTRAINT_TYPE_ANNULAR_WIDTH, "annular_width", formatMinMax },
|
{ DRC_CONSTRAINT_TYPE_ANNULAR_WIDTH, "annular_width", formatMinMax },
|
||||||
{ DRC_CONSTRAINT_TYPE_DISALLOW, "disallow", nullptr },
|
{ DRC_CONSTRAINT_TYPE_DISALLOW, "disallow", nullptr },
|
||||||
{ DRC_CONSTRAINT_TYPE_VIA_DIAMETER, "via_diameter", formatMinMax },
|
{ DRC_CONSTRAINT_TYPE_VIA_DIAMETER, "via_diameter", formatMinMax },
|
||||||
{ DRC_CONSTRAINT_TYPE_LENGTH, "length", formatMinMax },
|
{ DRC_CONSTRAINT_TYPE_LENGTH, "length", formatMinMax },
|
||||||
{ DRC_CONSTRAINT_TYPE_SKEW, "skew", formatMinMax },
|
{ DRC_CONSTRAINT_TYPE_SKEW, "skew", formatMinMax },
|
||||||
{ DRC_CONSTRAINT_TYPE_VIA_COUNT, "via_count", formatMinMax }
|
{ DRC_CONSTRAINT_TYPE_VIA_COUNT, "via_count", formatMinMax }
|
||||||
};
|
};
|
||||||
|
|
||||||
for( auto& fmt : formats )
|
for( auto& fmt : formats )
|
||||||
|
@ -284,14 +284,14 @@ void DRC_ENGINE::loadRules( const wxFileName& aPath )
|
||||||
{
|
{
|
||||||
DRC_RULES_PARSER parser( fp, aPath.GetFullPath() );
|
DRC_RULES_PARSER parser( fp, aPath.GetFullPath() );
|
||||||
parser.Parse( rules, m_reporter );
|
parser.Parse( rules, m_reporter );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the rules into the member variable afterwards so that if Parse() throws then
|
// Copy the rules into the member variable afterwards so that if Parse() throws then
|
||||||
// the possibly malformed rules won't contaminate the current ruleset.
|
// the possibly malformed rules won't contaminate the current ruleset.
|
||||||
|
|
||||||
for( DRC_RULE* rule : rules )
|
for( DRC_RULE* rule : rules )
|
||||||
m_rules.push_back( rule );
|
m_rules.push_back( rule );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -414,9 +414,7 @@ void DRC_ENGINE::RunTests( EDA_UNITS aUnits, bool aTestTracksAgainstZones,
|
||||||
for( DRC_TEST_PROVIDER* provider : m_testProviders )
|
for( DRC_TEST_PROVIDER* provider : m_testProviders )
|
||||||
{
|
{
|
||||||
if( provider->IsEnabled() )
|
if( provider->IsEnabled() )
|
||||||
{
|
phases += provider->GetNumPhases();
|
||||||
phases += provider->GetNumPhases();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_progressReporter->AddPhases( phases );
|
m_progressReporter->AddPhases( phases );
|
||||||
|
|
|
@ -164,13 +164,13 @@ DRC_ITEM DRC_ITEM::unresolvedVariable( DRCE_UNRESOLVED_VARIABLE,
|
||||||
_( "Unresolved text variable" ),
|
_( "Unresolved text variable" ),
|
||||||
wxT( "unresolved_variable" ) );
|
wxT( "unresolved_variable" ) );
|
||||||
|
|
||||||
DRC_ITEM DRC_ITEM::silkOverPad( DRCE_SILK_OVER_PAD,
|
DRC_ITEM DRC_ITEM::silkMaskClearance( DRCE_SILK_MASK_CLEARANCE,
|
||||||
_( "Silkscreen overlapping pad" ),
|
_( "Silkscreen clipped by solder mask" ),
|
||||||
wxT( "silk_over_pad" ) );
|
wxT( "silk_over_copper" ) );
|
||||||
|
|
||||||
DRC_ITEM DRC_ITEM::silkClearance( DRCE_SILK_CLEARANCE,
|
DRC_ITEM DRC_ITEM::silkSilkClearance( DRCE_SILK_SILK_CLEARANCE,
|
||||||
_( "Silkscreen clearance" ),
|
_( "Silkscreen overlap" ),
|
||||||
wxT( "silk_clearance" ) );
|
wxT( "silk_overlap" ) );
|
||||||
|
|
||||||
DRC_ITEM DRC_ITEM::lengthOutOfRange( DRCE_LENGTH_OUT_OF_RANGE,
|
DRC_ITEM DRC_ITEM::lengthOutOfRange( DRCE_LENGTH_OUT_OF_RANGE,
|
||||||
_( "Trace length out of range" ),
|
_( "Trace length out of range" ),
|
||||||
|
@ -224,8 +224,8 @@ std::vector<std::reference_wrapper<RC_ITEM>> DRC_ITEM::allItemTypes( {
|
||||||
DRC_ITEM::extraFootprint,
|
DRC_ITEM::extraFootprint,
|
||||||
DRC_ITEM::netConflict,
|
DRC_ITEM::netConflict,
|
||||||
DRC_ITEM::unresolvedVariable,
|
DRC_ITEM::unresolvedVariable,
|
||||||
DRC_ITEM::silkClearance,
|
DRC_ITEM::silkSilkClearance,
|
||||||
DRC_ITEM::silkOverPad,
|
DRC_ITEM::silkMaskClearance,
|
||||||
DRC_ITEM::lengthOutOfRange,
|
DRC_ITEM::lengthOutOfRange,
|
||||||
DRC_ITEM::skewOutOfRange,
|
DRC_ITEM::skewOutOfRange,
|
||||||
DRC_ITEM::tooManyVias,
|
DRC_ITEM::tooManyVias,
|
||||||
|
@ -270,8 +270,8 @@ std::shared_ptr<DRC_ITEM> DRC_ITEM::Create( int aErrorCode )
|
||||||
case DRCE_NET_CONFLICT: return std::make_shared<DRC_ITEM>( netConflict );
|
case DRCE_NET_CONFLICT: return std::make_shared<DRC_ITEM>( netConflict );
|
||||||
case DRCE_EXTRA_FOOTPRINT: return std::make_shared<DRC_ITEM>( extraFootprint );
|
case DRCE_EXTRA_FOOTPRINT: return std::make_shared<DRC_ITEM>( extraFootprint );
|
||||||
case DRCE_UNRESOLVED_VARIABLE: return std::make_shared<DRC_ITEM>( unresolvedVariable );
|
case DRCE_UNRESOLVED_VARIABLE: return std::make_shared<DRC_ITEM>( unresolvedVariable );
|
||||||
case DRCE_SILK_OVER_PAD: return std::make_shared<DRC_ITEM>( silkOverPad );
|
case DRCE_SILK_SILK_CLEARANCE: return std::make_shared<DRC_ITEM>( silkSilkClearance );
|
||||||
case DRCE_SILK_CLEARANCE: return std::make_shared<DRC_ITEM>( silkClearance );
|
case DRCE_SILK_MASK_CLEARANCE: return std::make_shared<DRC_ITEM>( silkMaskClearance );
|
||||||
case DRCE_LENGTH_OUT_OF_RANGE: return std::make_shared<DRC_ITEM>( lengthOutOfRange );
|
case DRCE_LENGTH_OUT_OF_RANGE: return std::make_shared<DRC_ITEM>( lengthOutOfRange );
|
||||||
case DRCE_SKEW_OUT_OF_RANGE: return std::make_shared<DRC_ITEM>( skewOutOfRange );
|
case DRCE_SKEW_OUT_OF_RANGE: return std::make_shared<DRC_ITEM>( skewOutOfRange );
|
||||||
case DRCE_TOO_MANY_VIAS: return std::make_shared<DRC_ITEM>( tooManyVias );
|
case DRCE_TOO_MANY_VIAS: return std::make_shared<DRC_ITEM>( tooManyVias );
|
||||||
|
|
|
@ -68,8 +68,9 @@ enum PCB_DRC_CODE {
|
||||||
DRCE_NET_CONFLICT, // pad net doesn't match netlist
|
DRCE_NET_CONFLICT, // pad net doesn't match netlist
|
||||||
|
|
||||||
DRCE_UNRESOLVED_VARIABLE,
|
DRCE_UNRESOLVED_VARIABLE,
|
||||||
DRCE_SILK_OVER_PAD, // silkscreen over component pad(s)
|
DRCE_SILK_MASK_CLEARANCE, // silkscreen clipped by mask (potentially leaving it
|
||||||
DRCE_SILK_CLEARANCE, // silk to silk clearance error
|
// over pads, exposed copper, etc.)
|
||||||
|
DRCE_SILK_SILK_CLEARANCE, // silk to silk clearance error
|
||||||
DRCE_LENGTH_OUT_OF_RANGE,
|
DRCE_LENGTH_OUT_OF_RANGE,
|
||||||
DRCE_SKEW_OUT_OF_RANGE,
|
DRCE_SKEW_OUT_OF_RANGE,
|
||||||
DRCE_TOO_MANY_VIAS,
|
DRCE_TOO_MANY_VIAS,
|
||||||
|
@ -152,8 +153,8 @@ private:
|
||||||
static DRC_ITEM extraFootprint;
|
static DRC_ITEM extraFootprint;
|
||||||
static DRC_ITEM netConflict;
|
static DRC_ITEM netConflict;
|
||||||
static DRC_ITEM unresolvedVariable;
|
static DRC_ITEM unresolvedVariable;
|
||||||
static DRC_ITEM silkOverPad;
|
static DRC_ITEM silkMaskClearance;
|
||||||
static DRC_ITEM silkClearance;
|
static DRC_ITEM silkSilkClearance;
|
||||||
static DRC_ITEM lengthOutOfRange;
|
static DRC_ITEM lengthOutOfRange;
|
||||||
static DRC_ITEM skewOutOfRange;
|
static DRC_ITEM skewOutOfRange;
|
||||||
static DRC_ITEM tooManyVias;
|
static DRC_ITEM tooManyVias;
|
||||||
|
|
|
@ -100,9 +100,11 @@ public:
|
||||||
|
|
||||||
for( auto subshape : subshapes )
|
for( auto subshape : subshapes )
|
||||||
{
|
{
|
||||||
const BOX2I& bbox = subshape->BBox();
|
BOX2I bbox = subshape->BBox();
|
||||||
const int mmin[2] = { bbox.GetX(), bbox.GetY() };
|
bbox.Inflate( Millimeter2iu( 20 ) );
|
||||||
const int mmax[2] = { bbox.GetRight(), bbox.GetBottom() };
|
const int mmin[2] = { bbox.GetX(), bbox.GetY() };
|
||||||
|
const int mmax[2] = { bbox.GetRight(), bbox.GetBottom() };
|
||||||
|
|
||||||
m_tree[layer]->Insert( mmin, mmax, new ITEM_WITH_SHAPE( aItem, subshape, itemShape ) );
|
m_tree[layer]->Insert( mmin, mmax, new ITEM_WITH_SHAPE( aItem, subshape, itemShape ) );
|
||||||
m_count++;
|
m_count++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ enum DRC_CONSTRAINT_TYPE_T
|
||||||
DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE,
|
DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE,
|
||||||
DRC_CONSTRAINT_TYPE_HOLE_SIZE,
|
DRC_CONSTRAINT_TYPE_HOLE_SIZE,
|
||||||
DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE,
|
DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE,
|
||||||
DRC_CONSTRAINT_TYPE_SILK_TO_PAD,
|
DRC_CONSTRAINT_TYPE_SILK_TO_MASK,
|
||||||
DRC_CONSTRAINT_TYPE_SILK_TO_SILK,
|
DRC_CONSTRAINT_TYPE_SILK_TO_SILK,
|
||||||
DRC_CONSTRAINT_TYPE_TRACK_WIDTH,
|
DRC_CONSTRAINT_TYPE_TRACK_WIDTH,
|
||||||
DRC_CONSTRAINT_TYPE_ANNULAR_WIDTH,
|
DRC_CONSTRAINT_TYPE_ANNULAR_WIDTH,
|
||||||
|
|
|
@ -276,7 +276,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
|
||||||
case T_edge_clearance: constraint.m_Type = DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE; break;
|
case T_edge_clearance: constraint.m_Type = DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE; break;
|
||||||
case T_hole: constraint.m_Type = DRC_CONSTRAINT_TYPE_HOLE_SIZE; break;
|
case T_hole: constraint.m_Type = DRC_CONSTRAINT_TYPE_HOLE_SIZE; break;
|
||||||
case T_courtyard_clearance: constraint.m_Type = DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE; break;
|
case T_courtyard_clearance: constraint.m_Type = DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE; break;
|
||||||
case T_silk_to_pad: constraint.m_Type = DRC_CONSTRAINT_TYPE_SILK_TO_PAD; break;
|
case T_silk_to_mask: constraint.m_Type = DRC_CONSTRAINT_TYPE_SILK_TO_MASK; break;
|
||||||
case T_silk_to_silk: constraint.m_Type = DRC_CONSTRAINT_TYPE_SILK_TO_SILK; break;
|
case T_silk_to_silk: constraint.m_Type = DRC_CONSTRAINT_TYPE_SILK_TO_SILK; break;
|
||||||
case T_track_width: constraint.m_Type = DRC_CONSTRAINT_TYPE_TRACK_WIDTH; break;
|
case T_track_width: constraint.m_Type = DRC_CONSTRAINT_TYPE_TRACK_WIDTH; break;
|
||||||
case T_annular_width: constraint.m_Type = DRC_CONSTRAINT_TYPE_ANNULAR_WIDTH; break;
|
case T_annular_width: constraint.m_Type = DRC_CONSTRAINT_TYPE_ANNULAR_WIDTH; break;
|
||||||
|
|
|
@ -127,7 +127,7 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testOverlappingComponentCourtyards()
|
||||||
{
|
{
|
||||||
const int delta = 100; // This is the number of tests between 2 calls to the progress bar
|
const int delta = 100; // This is the number of tests between 2 calls to the progress bar
|
||||||
|
|
||||||
if( !reportPhase( _( "Checking footprint courtyard overlap..." ) ) )
|
if( !reportPhase( _( "Checking footprints for overlapping courtyards..." ) ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int ii = 0;
|
int ii = 0;
|
||||||
|
|
|
@ -24,13 +24,9 @@
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <class_board.h>
|
#include <class_board.h>
|
||||||
#include <class_drawsegment.h>
|
#include <class_drawsegment.h>
|
||||||
#include <class_pad.h>
|
|
||||||
|
|
||||||
#include <convert_basic_shapes_to_polygon.h>
|
|
||||||
#include <geometry/polygon_test_point_inside.h>
|
#include <geometry/polygon_test_point_inside.h>
|
||||||
#include <geometry/seg.h>
|
#include <geometry/seg.h>
|
||||||
#include <geometry/shape_poly_set.h>
|
|
||||||
#include <geometry/shape_rect.h>
|
|
||||||
#include <geometry/shape_segment.h>
|
#include <geometry/shape_segment.h>
|
||||||
|
|
||||||
#include <drc/drc_engine.h>
|
#include <drc/drc_engine.h>
|
||||||
|
@ -43,21 +39,21 @@
|
||||||
/*
|
/*
|
||||||
Silk to pads clearance test. Check all pads against silkscreen (mask opening in the pad vs silkscreen)
|
Silk to pads clearance test. Check all pads against silkscreen (mask opening in the pad vs silkscreen)
|
||||||
Errors generated:
|
Errors generated:
|
||||||
- DRCE_SILK_ON_PADS
|
- DRCE_SILK_MASK_CLEARANCE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace test {
|
namespace test {
|
||||||
|
|
||||||
class DRC_TEST_PROVIDER_SILK_TO_PAD : public ::DRC_TEST_PROVIDER
|
class DRC_TEST_PROVIDER_SILK_TO_MASK : public ::DRC_TEST_PROVIDER
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DRC_TEST_PROVIDER_SILK_TO_PAD ():
|
DRC_TEST_PROVIDER_SILK_TO_MASK ():
|
||||||
m_board( nullptr ),
|
m_board( nullptr ),
|
||||||
m_largestClearance( 0 )
|
m_largestClearance( 0 )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~DRC_TEST_PROVIDER_SILK_TO_PAD()
|
virtual ~DRC_TEST_PROVIDER_SILK_TO_MASK()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,12 +61,12 @@ public:
|
||||||
|
|
||||||
virtual const wxString GetName() const override
|
virtual const wxString GetName() const override
|
||||||
{
|
{
|
||||||
return "silk_to_pad";
|
return "silk_to_mask";
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual const wxString GetDescription() const override
|
virtual const wxString GetDescription() const override
|
||||||
{
|
{
|
||||||
return "Tests for silkscreen covering components pads";
|
return "Tests for silkscreen being clipped by solder mask";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int GetNumPhases() const override
|
virtual int GetNumPhases() const override
|
||||||
|
@ -89,28 +85,28 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
bool test::DRC_TEST_PROVIDER_SILK_TO_PAD::Run()
|
bool test::DRC_TEST_PROVIDER_SILK_TO_MASK::Run()
|
||||||
{
|
{
|
||||||
m_board = m_drcEngine->GetBoard();
|
m_board = m_drcEngine->GetBoard();
|
||||||
|
|
||||||
DRC_CONSTRAINT worstClearanceConstraint;
|
DRC_CONSTRAINT worstClearanceConstraint;
|
||||||
m_largestClearance = 0;
|
m_largestClearance = 0;
|
||||||
|
|
||||||
if( m_drcEngine->QueryWorstConstraint( DRC_CONSTRAINT_TYPE_SILK_TO_PAD,
|
if( m_drcEngine->QueryWorstConstraint( DRC_CONSTRAINT_TYPE_SILK_TO_MASK,
|
||||||
worstClearanceConstraint, DRCCQ_LARGEST_MINIMUM ) )
|
worstClearanceConstraint, DRCCQ_LARGEST_MINIMUM ) )
|
||||||
{
|
{
|
||||||
m_largestClearance = worstClearanceConstraint.m_Value.Min();
|
m_largestClearance = worstClearanceConstraint.m_Value.Min();
|
||||||
}
|
}
|
||||||
|
|
||||||
reportAux( "Worst clearance : %d nm", m_largestClearance );
|
reportAux( "Worst clearance : %d nm", m_largestClearance );
|
||||||
reportPhase(( "Pad to silkscreen clearances..." ));
|
reportPhase( _( "Checking silkscreen for potential soldermask clipping..." ) );
|
||||||
|
|
||||||
DRC_RTREE padTree, silkTree;
|
DRC_RTREE maskTree, silkTree;
|
||||||
|
|
||||||
auto addPadToTree =
|
auto addMaskToTree =
|
||||||
[&padTree]( BOARD_ITEM *item ) -> bool
|
[&maskTree]( BOARD_ITEM *item ) -> bool
|
||||||
{
|
{
|
||||||
padTree.insert( item );
|
maskTree.insert( item );
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -125,10 +121,10 @@ bool test::DRC_TEST_PROVIDER_SILK_TO_PAD::Run()
|
||||||
[&]( const DRC_RTREE::LAYER_PAIR& aLayers, DRC_RTREE::ITEM_WITH_SHAPE* aRefItem,
|
[&]( const DRC_RTREE::LAYER_PAIR& aLayers, DRC_RTREE::ITEM_WITH_SHAPE* aRefItem,
|
||||||
DRC_RTREE::ITEM_WITH_SHAPE* aTestItem, bool* aCollisionDetected ) -> bool
|
DRC_RTREE::ITEM_WITH_SHAPE* aTestItem, bool* aCollisionDetected ) -> bool
|
||||||
{
|
{
|
||||||
if( m_drcEngine->IsErrorLimitExceeded( DRCE_SILK_OVER_PAD ) )
|
if( m_drcEngine->IsErrorLimitExceeded( DRCE_SILK_MASK_CLEARANCE ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_SILK_TO_PAD,
|
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_SILK_TO_MASK,
|
||||||
aRefItem->parent,
|
aRefItem->parent,
|
||||||
aTestItem->parent );
|
aTestItem->parent );
|
||||||
|
|
||||||
|
@ -147,7 +143,7 @@ bool test::DRC_TEST_PROVIDER_SILK_TO_PAD::Run()
|
||||||
if( !aRefItem->shape->Collide( aTestItem->shape, minClearance, &actual, &pos ) )
|
if( !aRefItem->shape->Collide( aTestItem->shape, minClearance, &actual, &pos ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_SILK_OVER_PAD );
|
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_SILK_MASK_CLEARANCE );
|
||||||
wxString msg;
|
wxString msg;
|
||||||
|
|
||||||
drcItem->SetItems( aRefItem->parent, aTestItem->parent );
|
drcItem->SetItems( aRefItem->parent, aTestItem->parent );
|
||||||
|
@ -159,21 +155,28 @@ bool test::DRC_TEST_PROVIDER_SILK_TO_PAD::Run()
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
int numPads = forEachGeometryItem( { PCB_PAD_T }, LSET::AllTechMask() | LSET::AllCuMask(),
|
int numPads = forEachGeometryItem( { PCB_PAD_T,
|
||||||
addPadToTree );
|
PCB_LINE_T,
|
||||||
|
PCB_MODULE_EDGE_T,
|
||||||
|
PCB_TEXT_T,
|
||||||
|
PCB_MODULE_TEXT_T },
|
||||||
|
LSET( 2, F_Mask, B_Mask ), addMaskToTree );
|
||||||
|
|
||||||
int numSilk = forEachGeometryItem( { PCB_LINE_T, PCB_MODULE_EDGE_T, PCB_TEXT_T, PCB_MODULE_TEXT_T },
|
int numSilk = forEachGeometryItem( { PCB_LINE_T,
|
||||||
|
PCB_MODULE_EDGE_T,
|
||||||
|
PCB_TEXT_T,
|
||||||
|
PCB_MODULE_TEXT_T },
|
||||||
LSET( 2, F_SilkS, B_SilkS ), addSilkToTree );
|
LSET( 2, F_SilkS, B_SilkS ), addSilkToTree );
|
||||||
|
|
||||||
reportAux( _("Testing %d pads against %d silkscreen features."), numPads, numSilk );
|
reportAux( _("Testing %d exposed copper against %d silkscreen features."), numPads, numSilk );
|
||||||
|
|
||||||
const std::vector<DRC_RTREE::LAYER_PAIR> layerPairs =
|
const std::vector<DRC_RTREE::LAYER_PAIR> layerPairs =
|
||||||
{
|
{
|
||||||
DRC_RTREE::LAYER_PAIR( F_SilkS, F_Cu ),
|
DRC_RTREE::LAYER_PAIR( F_SilkS, F_Mask ),
|
||||||
DRC_RTREE::LAYER_PAIR( B_SilkS, B_Cu )
|
DRC_RTREE::LAYER_PAIR( B_SilkS, B_Mask )
|
||||||
};
|
};
|
||||||
|
|
||||||
padTree.QueryCollidingPairs( &silkTree, layerPairs, checkClearance, m_largestClearance );
|
maskTree.QueryCollidingPairs( &silkTree, layerPairs, checkClearance, m_largestClearance );
|
||||||
|
|
||||||
reportRuleStatistics();
|
reportRuleStatistics();
|
||||||
|
|
||||||
|
@ -181,13 +184,13 @@ bool test::DRC_TEST_PROVIDER_SILK_TO_PAD::Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_SILK_TO_PAD::GetConstraintTypes() const
|
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_SILK_TO_MASK::GetConstraintTypes() const
|
||||||
{
|
{
|
||||||
return { DRC_CONSTRAINT_TYPE_SILK_TO_PAD };
|
return { DRC_CONSTRAINT_TYPE_SILK_TO_MASK };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_SILK_TO_PAD> dummy;
|
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_SILK_TO_MASK> dummy;
|
||||||
}
|
}
|
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
#include <geometry/polygon_test_point_inside.h>
|
#include <geometry/polygon_test_point_inside.h>
|
||||||
#include <geometry/seg.h>
|
#include <geometry/seg.h>
|
||||||
#include <geometry/shape_rect.h>
|
|
||||||
#include <geometry/shape_segment.h>
|
#include <geometry/shape_segment.h>
|
||||||
|
|
||||||
#include <drc/drc_engine.h>
|
#include <drc/drc_engine.h>
|
||||||
|
@ -40,7 +39,7 @@
|
||||||
/*
|
/*
|
||||||
Silk to silk clearance test. Check all silkscreen features against each other.
|
Silk to silk clearance test. Check all silkscreen features against each other.
|
||||||
Errors generated:
|
Errors generated:
|
||||||
- DRCE_SILK_CLEARANCE
|
- DRCE_SILK_SILK_CLEARANCE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -95,7 +94,7 @@ bool DRC_TEST_PROVIDER_SILK_TO_SILK::Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
reportAux( "Worst clearance : %d nm", m_largestClearance );
|
reportAux( "Worst clearance : %d nm", m_largestClearance );
|
||||||
reportPhase(( "Silkscreen clearances..." ));
|
reportPhase( _( "Checking silkscreen for overlapping items..." ) );
|
||||||
|
|
||||||
DRC_RTREE silkTree;
|
DRC_RTREE silkTree;
|
||||||
|
|
||||||
|
@ -110,7 +109,7 @@ bool DRC_TEST_PROVIDER_SILK_TO_SILK::Run()
|
||||||
[&]( const DRC_RTREE::LAYER_PAIR& aLayers, DRC_RTREE::ITEM_WITH_SHAPE* aRefItem,
|
[&]( const DRC_RTREE::LAYER_PAIR& aLayers, DRC_RTREE::ITEM_WITH_SHAPE* aRefItem,
|
||||||
DRC_RTREE::ITEM_WITH_SHAPE* aTestItem, bool* aCollisionDetected ) -> bool
|
DRC_RTREE::ITEM_WITH_SHAPE* aTestItem, bool* aCollisionDetected ) -> bool
|
||||||
{
|
{
|
||||||
if( m_drcEngine->IsErrorLimitExceeded( DRCE_SILK_CLEARANCE ) )
|
if( m_drcEngine->IsErrorLimitExceeded( DRCE_SILK_SILK_CLEARANCE ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_SILK_TO_SILK,
|
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_SILK_TO_SILK,
|
||||||
|
@ -162,18 +161,23 @@ bool DRC_TEST_PROVIDER_SILK_TO_SILK::Run()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ! aRefItem->shape->Collide( aTestItem->shape, minClearance, &actual, &pos ) )
|
if( !aRefItem->shape->Collide( aTestItem->shape, minClearance, &actual, &pos ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_SILK_CLEARANCE );
|
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_SILK_SILK_CLEARANCE );
|
||||||
wxString msg;
|
wxString msg;
|
||||||
|
|
||||||
|
/* For now we're just reporting silkscreen collisions without any dimensional
|
||||||
|
* data. I suspect it's usually noise, and they can always use the clearance
|
||||||
|
* resolution report if they want.
|
||||||
|
*
|
||||||
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
|
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
|
||||||
constraint.GetParentRule()->m_Name,
|
constraint.GetParentRule()->m_Name,
|
||||||
MessageTextFromValue( userUnits(), minClearance ),
|
MessageTextFromValue( userUnits(), minClearance ),
|
||||||
MessageTextFromValue( userUnits(), actual ) );
|
MessageTextFromValue( userUnits(), actual ) );
|
||||||
|
|
||||||
drcItem->SetErrorMessage( msg );
|
drcItem->SetErrorMessage( msg );
|
||||||
|
*/
|
||||||
drcItem->SetItems( aRefItem->parent, aTestItem->parent );
|
drcItem->SetItems( aRefItem->parent, aTestItem->parent );
|
||||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,8 @@ add_executable( drc_proto
|
||||||
../../pcbnew/drc/drc_test_provider_via_diameter.cpp
|
../../pcbnew/drc/drc_test_provider_via_diameter.cpp
|
||||||
../../pcbnew/drc/drc_test_provider_lvs.cpp
|
../../pcbnew/drc/drc_test_provider_lvs.cpp
|
||||||
../../pcbnew/drc/drc_test_provider_misc.cpp
|
../../pcbnew/drc/drc_test_provider_misc.cpp
|
||||||
|
../../pcbnew/drc/drc_test_provider_silk_to_mask.cpp
|
||||||
|
../../pcbnew/drc/drc_test_provider_silk_to_silk.cpp
|
||||||
../../pcbnew/drc/drc_engine.cpp
|
../../pcbnew/drc/drc_engine.cpp
|
||||||
../../pcbnew/drc/drc_item.cpp
|
../../pcbnew/drc/drc_item.cpp
|
||||||
../qa_utils/mocks.cpp
|
../qa_utils/mocks.cpp
|
||||||
|
|
Loading…
Reference in New Issue