From 26b9d2f5aca3496fc06a003c6cd35cb06b2cbbdd Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Wed, 1 Feb 2023 23:11:39 -0500 Subject: [PATCH] DRC: Allow disabling DP constraints in specific areas Fixes https://gitlab.com/kicad/code/kicad/-/issues/13743 --- .../drc_test_provider_diff_pair_coupling.cpp | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/pcbnew/drc/drc_test_provider_diff_pair_coupling.cpp b/pcbnew/drc/drc_test_provider_diff_pair_coupling.cpp index b23258e696..d8f70dde53 100644 --- a/pcbnew/drc/drc_test_provider_diff_pair_coupling.cpp +++ b/pcbnew/drc/drc_test_provider_diff_pair_coupling.cpp @@ -417,11 +417,19 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run() if( key.gapConstraint ) { - if( key.gapConstraint->HasMin() && gap < key.gapConstraint->Min() - epsilon ) + if( key.gapConstraint->HasMin() + && key.gapConstraint->Min() >= 0 + && ( gap < key.gapConstraint->Min() - epsilon ) ) + { dp.couplingFailMin = true; + } - if( key.gapConstraint->HasMax() && gap > key.gapConstraint->Max() + epsilon ) + if( key.gapConstraint->HasMax() + && key.gapConstraint->Max() >= 0 + && ( gap > key.gapConstraint->Max() + epsilon ) ) + { dp.couplingFailMax = true; + } } if( !dp.couplingFailMin && !dp.couplingFailMax ) @@ -441,7 +449,7 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run() { const MINOPTMAX& val = *key.uncoupledConstraint; - if ( val.HasMax() && totalUncoupled > val.Max() ) + if( val.HasMax() && val.Max() >= 0 && totalUncoupled > val.Max() ) { auto drce = DRC_ITEM::Create( DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG ); wxString msg = formatMsg( _( "(%s maximum uncoupled length %s; actual %s)" ), @@ -489,9 +497,24 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run() { if( ( dp.couplingFailMin || dp.couplingFailMax ) && ( dp.parentP || dp.parentN ) ) { - MINOPTMAX val = *key.gapConstraint; - auto drcItem = DRC_ITEM::Create( DRCE_DIFF_PAIR_GAP_OUT_OF_RANGE ); - wxString msg; + // We have a candidate violation, now we need to re-query for a constraint + // given the actual items, because there may be a location-based rule in play. + DRC_CONSTRAINT constraint = m_drcEngine->EvalRules( DIFF_PAIR_GAP_CONSTRAINT, + dp.parentP, dp.parentN, + dp.parentP->GetLayer() ); + MINOPTMAX val = constraint.GetValue(); + + if( !val.HasMin() || val.Min() < 0 || dp.computedGap >= val.Min() ) + dp.couplingFailMin = false; + + if( !val.HasMax() || val.Max() < 0 || dp.computedGap <= val.Max() ) + dp.couplingFailMax = false; + + if( !dp.couplingFailMin && !dp.couplingFailMax ) + continue; + + auto drcItem = DRC_ITEM::Create( DRCE_DIFF_PAIR_GAP_OUT_OF_RANGE ); + wxString msg; if( dp.couplingFailMin ) {