Apply a more sophisticated test for ignoring isInCoupledDiffPair.
The basic problem is that the DRC engine does length testing and skew
testing by collecting all the diff pair constituent parts and pairing them
itself. Since each part is collected on its own, we need to ignore the
'B' unit when evaluating any conditional expressions. However, doing this
in general means that when evaluating "OwnClearance()" we also ignore the
'B' unit and return the diff pair CLEARANCE_CONSTRAINT when we shouldn't.
This implements a more discerning test which know what the current requested
constraint is when evaluating expressions.
See also https://forum.kicad.info/t/solved-custom-differencing-rule-not-working-drc/34034/6
Fixes https://gitlab.com/kicad/code/kicad/issues/11314
(cherry picked from commit f7cdc7af75
)
This commit is contained in:
parent
80bf1048d0
commit
8054f1a948
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004-2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
* Copyright (C) 2004-2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 2014 Dick Hollenbeck, dick@softplc.com
|
* Copyright (C) 2014 Dick Hollenbeck, dick@softplc.com
|
||||||
* Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -1055,7 +1055,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
|
||||||
EscapeHTML( c->condition->GetExpression() ) ) )
|
EscapeHTML( c->condition->GetExpression() ) ) )
|
||||||
}
|
}
|
||||||
|
|
||||||
if( c->condition->EvaluateFor( a, b, aLayer, aReporter ) )
|
if( c->condition->EvaluateFor( a, b, c->constraint.m_Type, aLayer, aReporter ) )
|
||||||
{
|
{
|
||||||
REPORT( implicit ? _( "Constraint applied." )
|
REPORT( implicit ? _( "Constraint applied." )
|
||||||
: _( "Rule applied; overrides previous constraints." ) )
|
: _( "Rule applied; overrides previous constraints." ) )
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
|
* Copyright (C) 2020-2022 KiCad Developers, see change_log.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -41,7 +41,7 @@ DRC_RULE_CONDITION::~DRC_RULE_CONDITION()
|
||||||
|
|
||||||
|
|
||||||
bool DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB,
|
bool DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB,
|
||||||
PCB_LAYER_ID aLayer, REPORTER* aReporter )
|
int aConstraint, PCB_LAYER_ID aLayer, REPORTER* aReporter )
|
||||||
{
|
{
|
||||||
if( GetExpression().IsEmpty() )
|
if( GetExpression().IsEmpty() )
|
||||||
return true;
|
return true;
|
||||||
|
@ -54,7 +54,7 @@ bool DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PCB_EXPR_CONTEXT ctx( aLayer );
|
PCB_EXPR_CONTEXT ctx( aConstraint, aLayer );
|
||||||
|
|
||||||
if( aReporter )
|
if( aReporter )
|
||||||
{
|
{
|
||||||
|
@ -109,7 +109,7 @@ bool DRC_RULE_CONDITION::Compile( REPORTER* aReporter, int aSourceLine, int aSou
|
||||||
|
|
||||||
m_ucode = std::make_unique<PCB_EXPR_UCODE>();
|
m_ucode = std::make_unique<PCB_EXPR_UCODE>();
|
||||||
|
|
||||||
PCB_EXPR_CONTEXT preflightContext( F_Cu );
|
PCB_EXPR_CONTEXT preflightContext( 0, F_Cu );
|
||||||
|
|
||||||
bool ok = compiler.Compile( GetExpression().ToUTF8().data(), m_ucode.get(), &preflightContext );
|
bool ok = compiler.Compile( GetExpression().ToUTF8().data(), m_ucode.get(), &preflightContext );
|
||||||
return ok;
|
return ok;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
|
* Copyright (C) 2020-2022 KiCad Developers, see change_log.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -38,8 +38,8 @@ public:
|
||||||
DRC_RULE_CONDITION( const wxString& aExpression = "" );
|
DRC_RULE_CONDITION( const wxString& aExpression = "" );
|
||||||
~DRC_RULE_CONDITION();
|
~DRC_RULE_CONDITION();
|
||||||
|
|
||||||
bool EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB, PCB_LAYER_ID aLayer,
|
bool EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB, int aConstraint,
|
||||||
REPORTER* aReporter = nullptr );
|
PCB_LAYER_ID aLayer, REPORTER* aReporter = nullptr );
|
||||||
|
|
||||||
bool Compile( REPORTER* aReporter, int aSourceLine = 0, int aSourceOffset = 0 );
|
bool Compile( REPORTER* aReporter, int aSourceLine = 0, int aSourceOffset = 0 );
|
||||||
|
|
||||||
|
|
|
@ -782,20 +782,27 @@ static void isCoupledDiffPair( LIBEVAL::CONTEXT* aCtx, void* self )
|
||||||
aCtx->Push( result );
|
aCtx->Push( result );
|
||||||
|
|
||||||
result->SetDeferredEval(
|
result->SetDeferredEval(
|
||||||
[a, b]() -> double
|
[a, b, context]() -> double
|
||||||
{
|
{
|
||||||
NETINFO_ITEM* netinfo = a ? a->GetNet() : nullptr;
|
NETINFO_ITEM* netinfo = a ? a->GetNet() : nullptr;
|
||||||
|
|
||||||
|
if( !netinfo )
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
wxString coupledNet;
|
wxString coupledNet;
|
||||||
wxString dummy;
|
wxString dummy;
|
||||||
|
|
||||||
if( netinfo
|
if( !DRC_ENGINE::MatchDpSuffix( netinfo->GetNetname(), coupledNet, dummy ) )
|
||||||
&& DRC_ENGINE::MatchDpSuffix( netinfo->GetNetname(), coupledNet, dummy )
|
return 0.0;
|
||||||
&& ( !b || b->GetNetname() == coupledNet ) )
|
|
||||||
|
if( context->GetConstraint() == DRC_CONSTRAINT_T::LENGTH_CONSTRAINT
|
||||||
|
|| context->GetConstraint() == DRC_CONSTRAINT_T::SKEW_CONSTRAINT )
|
||||||
{
|
{
|
||||||
|
// DRC engine evaluates these singly, so we won't have a B item
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0.0;
|
return b && b->GetNetname() == coupledNet;
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1184,12 +1191,12 @@ PCB_EXPR_EVALUATOR::~PCB_EXPR_EVALUATOR()
|
||||||
bool PCB_EXPR_EVALUATOR::Evaluate( const wxString& aExpr )
|
bool PCB_EXPR_EVALUATOR::Evaluate( const wxString& aExpr )
|
||||||
{
|
{
|
||||||
PCB_EXPR_UCODE ucode;
|
PCB_EXPR_UCODE ucode;
|
||||||
PCB_EXPR_CONTEXT preflightContext( F_Cu );
|
PCB_EXPR_CONTEXT preflightContext( NULL_CONSTRAINT, F_Cu );
|
||||||
|
|
||||||
if( !m_compiler.Compile( aExpr.ToUTF8().data(), &ucode, &preflightContext ) )
|
if( !m_compiler.Compile( aExpr.ToUTF8().data(), &ucode, &preflightContext ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
PCB_EXPR_CONTEXT evaluationContext( F_Cu );
|
PCB_EXPR_CONTEXT evaluationContext( NULL_CONSTRAINT, F_Cu );
|
||||||
LIBEVAL::VALUE* result = ucode.Run( &evaluationContext );
|
LIBEVAL::VALUE* result = ucode.Run( &evaluationContext );
|
||||||
|
|
||||||
if( result->GetType() == LIBEVAL::VT_NUMERIC )
|
if( result->GetType() == LIBEVAL::VT_NUMERIC )
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -52,7 +52,8 @@ public:
|
||||||
class PCB_EXPR_CONTEXT : public LIBEVAL::CONTEXT
|
class PCB_EXPR_CONTEXT : public LIBEVAL::CONTEXT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PCB_EXPR_CONTEXT( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) :
|
PCB_EXPR_CONTEXT( int aConstraint, PCB_LAYER_ID aLayer ) :
|
||||||
|
m_constraint( aConstraint ),
|
||||||
m_layer( aLayer )
|
m_layer( aLayer )
|
||||||
{
|
{
|
||||||
m_items[0] = nullptr;
|
m_items[0] = nullptr;
|
||||||
|
@ -67,17 +68,12 @@ public:
|
||||||
|
|
||||||
BOARD* GetBoard() const;
|
BOARD* GetBoard() const;
|
||||||
|
|
||||||
BOARD_ITEM* GetItem( int index ) const
|
int GetConstraint() const { return m_constraint; }
|
||||||
{
|
BOARD_ITEM* GetItem( int index ) const { return m_items[index]; }
|
||||||
return m_items[index];
|
PCB_LAYER_ID GetLayer() const { return m_layer; }
|
||||||
}
|
|
||||||
|
|
||||||
PCB_LAYER_ID GetLayer() const
|
|
||||||
{
|
|
||||||
return m_layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int m_constraint;
|
||||||
BOARD_ITEM* m_items[2];
|
BOARD_ITEM* m_items[2];
|
||||||
PCB_LAYER_ID m_layer;
|
PCB_LAYER_ID m_layer;
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
#include <layer_ids.h>
|
#include <layer_ids.h>
|
||||||
#include <pcbnew/pcb_expr_evaluator.h>
|
#include <pcbnew/pcb_expr_evaluator.h>
|
||||||
|
#include <drc/drc_rule.h>
|
||||||
#include <pcbnew/board.h>
|
#include <pcbnew/board.h>
|
||||||
#include <pcbnew/pcb_track.h>
|
#include <pcbnew/pcb_track.h>
|
||||||
|
|
||||||
|
@ -91,7 +91,8 @@ static bool testEvalExpr( const wxString& expr, LIBEVAL::VALUE expectedResult,
|
||||||
{
|
{
|
||||||
PCB_EXPR_COMPILER compiler;
|
PCB_EXPR_COMPILER compiler;
|
||||||
PCB_EXPR_UCODE ucode;
|
PCB_EXPR_UCODE ucode;
|
||||||
PCB_EXPR_CONTEXT context, preflightContext;
|
PCB_EXPR_CONTEXT context( NULL_CONSTRAINT, UNDEFINED_LAYER );
|
||||||
|
PCB_EXPR_CONTEXT preflightContext( NULL_CONSTRAINT, UNDEFINED_LAYER );
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
context.SetItems( itemA, itemB );
|
context.SetItems( itemA, itemB );
|
||||||
|
|
Loading…
Reference in New Issue