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:
Jeff Young 2020-10-04 12:44:22 +01:00
parent 36ceb8075e
commit 85c6cebd77
13 changed files with 127 additions and 83 deletions

View File

@ -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

View File

@ -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

View File

@ -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" )

View File

@ -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 );

View File

@ -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 );

View File

@ -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;

View File

@ -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++;
} }

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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;
} }

View File

@ -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() );

View File

@ -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