diff --git a/pcbnew/board_design_settings.cpp b/pcbnew/board_design_settings.cpp index a3ef779f07..cc807ee189 100644 --- a/pcbnew/board_design_settings.cpp +++ b/pcbnew/board_design_settings.cpp @@ -177,6 +177,7 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std: m_DRCSeverities[ DRCE_OVERLAPPING_SILK ] = RPT_SEVERITY_WARNING; m_DRCSeverities[ DRCE_SILK_CLEARANCE ] = RPT_SEVERITY_WARNING; + m_DRCSeverities[ DRCE_SILK_EDGE_CLEARANCE ] = RPT_SEVERITY_WARNING; m_DRCSeverities[ DRCE_TEXT_HEIGHT ] = RPT_SEVERITY_WARNING; m_DRCSeverities[ DRCE_TEXT_THICKNESS ] = RPT_SEVERITY_WARNING; diff --git a/pcbnew/drc/drc_item.cpp b/pcbnew/drc/drc_item.cpp index a585d01a6d..d3455b97ab 100644 --- a/pcbnew/drc/drc_item.cpp +++ b/pcbnew/drc/drc_item.cpp @@ -204,6 +204,10 @@ DRC_ITEM DRC_ITEM::silkClearance( DRCE_SILK_CLEARANCE, _( "Silkscreen clipped by solder mask" ), wxT( "silk_over_copper" ) ); +DRC_ITEM DRC_ITEM::silkEdgeClearance( DRCE_SILK_EDGE_CLEARANCE, + _( "Silkscreen clipped by board edge" ), + wxT( "silk_edge_clearance" ) ); + DRC_ITEM DRC_ITEM::silkOverlaps( DRCE_OVERLAPPING_SILK, _( "Silkscreen overlap" ), wxT( "silk_overlap" ) ); @@ -286,6 +290,7 @@ std::vector> DRC_ITEM::allItemTypes( { DRC_ITEM::heading_readability, DRC_ITEM::silkOverlaps, DRC_ITEM::silkClearance, + DRC_ITEM::silkEdgeClearance, DRC_ITEM::textHeightOutOfRange, DRC_ITEM::textThicknessOutOfRange, @@ -349,6 +354,7 @@ std::shared_ptr DRC_ITEM::Create( int aErrorCode ) case DRCE_COPPER_SLIVER: return std::make_shared( copperSliver ); case DRCE_OVERLAPPING_SILK: return std::make_shared( silkOverlaps ); case DRCE_SILK_CLEARANCE: return std::make_shared( silkClearance ); + case DRCE_SILK_EDGE_CLEARANCE: return std::make_shared( silkEdgeClearance ); case DRCE_SOLDERMASK_BRIDGE: return std::make_shared( solderMaskBridge ); case DRCE_TEXT_HEIGHT: return std::make_shared( textHeightOutOfRange ); case DRCE_TEXT_THICKNESS: return std::make_shared( textThicknessOutOfRange ); diff --git a/pcbnew/drc/drc_item.h b/pcbnew/drc/drc_item.h index ce582b2f91..ca6ab2e037 100644 --- a/pcbnew/drc/drc_item.h +++ b/pcbnew/drc/drc_item.h @@ -85,6 +85,7 @@ enum PCB_DRC_CODE { DRCE_SILK_CLEARANCE, // silkscreen clipped by mask (potentially leaving it // over pads, exposed copper, etc.) + DRCE_SILK_EDGE_CLEARANCE, DRCE_TEXT_HEIGHT, DRCE_TEXT_THICKNESS, DRCE_OVERLAPPING_SILK, // silk to silk clearance error @@ -186,6 +187,7 @@ private: static DRC_ITEM assertionFailure; static DRC_ITEM copperSliver; static DRC_ITEM silkClearance; + static DRC_ITEM silkEdgeClearance; static DRC_ITEM solderMaskBridge; static DRC_ITEM silkOverlaps; static DRC_ITEM textHeightOutOfRange; diff --git a/pcbnew/drc/drc_rtree.h b/pcbnew/drc/drc_rtree.h index 98f10ecec1..25737c9fb1 100644 --- a/pcbnew/drc/drc_rtree.h +++ b/pcbnew/drc/drc_rtree.h @@ -38,6 +38,7 @@ #include #include #include +#include "geometry/shape_null.h" /** * Implement an R-tree for fast spatial and layer indexing of connectable items. @@ -129,6 +130,9 @@ public: for( SHAPE* subshape : subshapes ) { + if( dynamic_cast( subshape ) ) + continue; + BOX2I bbox = subshape->BBox(); bbox.Inflate( aWorstClearance ); diff --git a/pcbnew/drc/drc_test_provider_edge_clearance.cpp b/pcbnew/drc/drc_test_provider_edge_clearance.cpp index e318f1c7fe..429924d3dd 100644 --- a/pcbnew/drc/drc_test_provider_edge_clearance.cpp +++ b/pcbnew/drc/drc_test_provider_edge_clearance.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -36,6 +37,7 @@ edge. Errors generated: - DRCE_EDGE_CLEARANCE + - DRCE_SILK_EDGE_CLEARANCE TODO: - separate holes to edge check @@ -79,7 +81,10 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::testAgainstEdge( BOARD_ITEM* item, SHAPE* DRC_CONSTRAINT_T aConstraintType, PCB_DRC_CODE aErrorCode ) { - const std::shared_ptr& edgeShape = edge->GetEffectiveShape( Edge_Cuts ); + const SHAPE* edgeShape = edge->GetEffectiveShape( Edge_Cuts ).get(); + + if( edge->Type() == PCB_PAD_T ) + edgeShape = static_cast( edge )->GetEffectiveHoleShape(); auto constraint = m_drcEngine->EvalRules( aConstraintType, edge, item, UNDEFINED_LAYER ); int minClearance = constraint.GetValue().Min(); @@ -88,7 +93,7 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::testAgainstEdge( BOARD_ITEM* item, SHAPE* if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && minClearance >= 0 ) { - if( itemShape->Collide( edgeShape.get(), minClearance, &actual, &pos ) ) + if( itemShape->Collide( edgeShape, minClearance, &actual, &pos ) ) { std::shared_ptr drce = DRC_ITEM::Create( aErrorCode ); @@ -122,7 +127,7 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run() if( !reportPhase( _( "Checking copper to board edge clearances..." ) ) ) return false; // DRC cancelled } - else if( m_drcEngine->IsErrorLimitExceeded( DRCE_SILK_CLEARANCE ) ) + else if( m_drcEngine->IsErrorLimitExceeded( DRCE_SILK_EDGE_CLEARANCE ) ) { if( !reportPhase( _( "Checking silk to board edge clearances..." ) ) ) return false; // DRC cancelled @@ -204,6 +209,15 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run() } } + for( FOOTPRINT* footprint : m_board->Footprints() ) + { + for( PAD* pad : footprint->Pads() ) + { + if( pad->GetAttribute() == PAD_ATTRIB::NPTH ) + edgesTree.Insert( pad, Edge_Cuts, m_largestClearance ); + } + } + // This is the number of tests between 2 calls to the progress bar const int delta = 100; int count = 0; @@ -220,7 +234,7 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run() [&]( BOARD_ITEM *item ) -> bool { bool testCopper = !m_drcEngine->IsErrorLimitExceeded( DRCE_EDGE_CLEARANCE ); - bool testSilk = !m_drcEngine->IsErrorLimitExceeded( DRCE_SILK_CLEARANCE ); + bool testSilk = !m_drcEngine->IsErrorLimitExceeded( DRCE_SILK_EDGE_CLEARANCE ); if( !testCopper && !testSilk ) return false; // We're done @@ -260,7 +274,7 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run() { return testAgainstEdge( item, itemShape.get(), edge, SILK_CLEARANCE_CONSTRAINT, - DRCE_SILK_CLEARANCE ); + DRCE_SILK_EDGE_CLEARANCE ); }, m_largestClearance ) ) {