Fix assert in DRC.

This commit is contained in:
Jeff Young 2020-11-17 17:41:57 +00:00
parent b2d86ec7c9
commit 795e45836d
4 changed files with 40 additions and 39 deletions

View File

@ -28,9 +28,9 @@ template<class T=int>
class MINOPTMAX
{
public:
T Min() const { assert( m_hasMin ); return m_min; };
T Max() const { assert( m_hasMax ); return m_max; };
T Opt() const { assert( m_hasOpt ); return m_opt; };
T Min() const { return m_hasMin ? m_min : 0; };
T Max() const { return m_hasMax ? m_max : std::numeric_limits<T>::max(); };
T Opt() const { return m_hasOpt ? m_opt : Min(); };
bool HasMin() const { return m_hasMin; }
bool HasMax() const { return m_hasMax; }
@ -42,17 +42,6 @@ public:
bool IsNull() const { return m_isNull; }
T OptThenMin() const
{
if( m_hasOpt )
return m_opt;
else if( m_hasMin )
return m_min;
assert( m_hasMin );
return 0;
}
private:
bool m_isNull;
T m_min;

View File

@ -83,20 +83,32 @@ DRC_ENGINE::~DRC_ENGINE()
}
static bool isKeepoutZone( const BOARD_ITEM* aItem )
{
if( aItem && ( aItem->Type() == PCB_ZONE_T || aItem->Type() == PCB_FP_ZONE_T ) )
static bool isKeepoutZone( const BOARD_ITEM* aItem, bool aCheckFlags )
{
if( !aItem )
return false;
if( aItem->Type() != PCB_ZONE_T && aItem->Type() != PCB_FP_ZONE_T )
return false;
const ZONE* zone = static_cast<const ZONE*>( aItem );
return zone->GetIsRuleArea() && ( zone->GetDoNotAllowTracks()
|| zone->GetDoNotAllowVias()
|| zone->GetDoNotAllowPads()
|| zone->GetDoNotAllowCopperPour()
|| zone->GetDoNotAllowFootprints() );
if( !zone->GetIsRuleArea() )
return false;
if( aCheckFlags )
{
if( !zone->GetDoNotAllowTracks()
&& !zone->GetDoNotAllowVias()
&& !zone->GetDoNotAllowPads()
&& !zone->GetDoNotAllowCopperPour()
&& !zone->GetDoNotAllowFootprints() )
{
return false;
}
}
return false;
return true;
}
@ -361,7 +373,7 @@ void DRC_ENGINE::loadImplicitRules()
for( ZONE* zone : m_board->Zones() )
{
if( isKeepoutZone( zone ) )
if( isKeepoutZone( zone, true ) )
keepoutZones.push_back( zone );
}
@ -369,7 +381,7 @@ void DRC_ENGINE::loadImplicitRules()
{
for( ZONE* zone : footprint->Zones() )
{
if( isKeepoutZone( zone ) )
if( isKeepoutZone( zone, true ) )
keepoutZones.push_back( zone );
}
}
@ -711,8 +723,8 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
const BOARD_CONNECTED_ITEM* bc = b && b->IsConnected() ?
static_cast<const BOARD_CONNECTED_ITEM*>( b ) : nullptr;
bool a_is_unconnected = a && !ac;
bool b_is_unconnected = b && !bc;
bool a_is_non_copper = a && ( !a->IsOnCopperLayer() || isKeepoutZone( a, false ) );
bool b_is_non_copper = b && ( !b->IsOnCopperLayer() || isKeepoutZone( b, false ) );
const DRC_CONSTRAINT* constraintRef = nullptr;
bool implicit = false;
@ -723,7 +735,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
int overrideA = 0;
int overrideB = 0;
if( ac && !b_is_unconnected && ac->GetLocalClearanceOverrides( nullptr ) > 0 )
if( ac && !b_is_non_copper && ac->GetLocalClearanceOverrides( nullptr ) > 0 )
{
overrideA = ac->GetLocalClearanceOverrides( &m_msg );
@ -733,7 +745,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
MessageTextFromValue( UNITS, overrideA ) ) )
}
if( bc && !a_is_unconnected && bc->GetLocalClearanceOverrides( nullptr ) > 0 )
if( bc && !a_is_non_copper && bc->GetLocalClearanceOverrides( nullptr ) > 0 )
{
overrideB = bc->GetLocalClearanceOverrides( &m_msg );
@ -800,7 +812,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
if( aConstraintId == CLEARANCE_CONSTRAINT )
{
if( implicit && ( a_is_unconnected || b_is_unconnected ) )
if( implicit && ( a_is_non_copper || b_is_non_copper ) )
{
REPORT( _( "Board and netclass clearances apply only to connected items." ) );
return true;

View File

@ -390,7 +390,7 @@ bool PNS_KICAD_IFACE_BASE::ImportSizes( PNS::SIZES_SETTINGS& aSizes, PNS::ITEM*
if( m_ruleResolver->QueryConstraint( PNS::CONSTRAINT_TYPE::CT_WIDTH, aStartItem, nullptr,
aStartItem->Layer(), &constraint ) )
{
trackWidth = constraint.m_Value.OptThenMin();
trackWidth = constraint.m_Value.Opt();
found = true; // Note: allowed to override anything, including bds.m_TrackMinWidth
}
}
@ -410,13 +410,13 @@ bool PNS_KICAD_IFACE_BASE::ImportSizes( PNS::SIZES_SETTINGS& aSizes, PNS::ITEM*
if( m_ruleResolver->QueryConstraint( PNS::CONSTRAINT_TYPE::CT_VIA_DIAMETER, aStartItem,
nullptr, aStartItem->Layer(), &constraint ) )
{
viaDiameter = constraint.m_Value.OptThenMin();
viaDiameter = constraint.m_Value.Opt();
}
if( m_ruleResolver->QueryConstraint( PNS::CONSTRAINT_TYPE::CT_VIA_HOLE, aStartItem,
nullptr, aStartItem->Layer(), &constraint ) )
{
viaDrill = constraint.m_Value.OptThenMin();
viaDrill = constraint.m_Value.Opt();
}
}
else
@ -437,14 +437,14 @@ bool PNS_KICAD_IFACE_BASE::ImportSizes( PNS::SIZES_SETTINGS& aSizes, PNS::ITEM*
if( m_ruleResolver->QueryConstraint( PNS::CONSTRAINT_TYPE::CT_WIDTH, aStartItem,
nullptr, aStartItem->Layer(), &constraint ) )
{
diffPairWidth = constraint.m_Value.OptThenMin();
diffPairWidth = constraint.m_Value.Opt();
}
if( m_ruleResolver->QueryConstraint( PNS::CONSTRAINT_TYPE::CT_DIFF_PAIR_GAP, aStartItem,
nullptr, aStartItem->Layer(), &constraint ) )
{
diffPairGap = constraint.m_Value.OptThenMin();
diffPairViaGap = constraint.m_Value.OptThenMin();
diffPairGap = constraint.m_Value.Opt();
diffPairViaGap = constraint.m_Value.Opt();
}
}
else if( bds.UseCustomDiffPairDimensions() )

View File

@ -884,13 +884,13 @@ int ROUTER_TOOL::onViaCommand( const TOOL_EVENT& aEvent )
nullptr, currentLayer );
if( !constraint.IsNull() )
sizes.SetViaDiameter( constraint.m_Value.OptThenMin() );
sizes.SetViaDiameter( constraint.m_Value.Opt() );
constraint = bds.m_DRCEngine->EvalRulesForItems( HOLE_SIZE_CONSTRAINT, &dummyVia, nullptr,
currentLayer );
if( !constraint.IsNull() )
sizes.SetViaDrill( constraint.m_Value.OptThenMin() );
sizes.SetViaDrill( constraint.m_Value.Opt() );
}
else
{