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 class MINOPTMAX
{ {
public: public:
T Min() const { assert( m_hasMin ); return m_min; }; T Min() const { return m_hasMin ? m_min : 0; };
T Max() const { assert( m_hasMax ); return m_max; }; T Max() const { return m_hasMax ? m_max : std::numeric_limits<T>::max(); };
T Opt() const { assert( m_hasOpt ); return m_opt; }; T Opt() const { return m_hasOpt ? m_opt : Min(); };
bool HasMin() const { return m_hasMin; } bool HasMin() const { return m_hasMin; }
bool HasMax() const { return m_hasMax; } bool HasMax() const { return m_hasMax; }
@ -42,17 +42,6 @@ public:
bool IsNull() const { return m_isNull; } 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: private:
bool m_isNull; bool m_isNull;
T m_min; T m_min;

View File

@ -83,20 +83,32 @@ DRC_ENGINE::~DRC_ENGINE()
} }
static bool isKeepoutZone( const BOARD_ITEM* aItem ) static bool isKeepoutZone( const BOARD_ITEM* aItem, bool aCheckFlags )
{
if( aItem && ( aItem->Type() == PCB_ZONE_T || aItem->Type() == PCB_FP_ZONE_T ) )
{ {
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 ); const ZONE* zone = static_cast<const ZONE*>( aItem );
return zone->GetIsRuleArea() && ( zone->GetDoNotAllowTracks() if( !zone->GetIsRuleArea() )
|| zone->GetDoNotAllowVias() return false;
|| zone->GetDoNotAllowPads()
|| zone->GetDoNotAllowCopperPour() if( aCheckFlags )
|| zone->GetDoNotAllowFootprints() ); {
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() ) for( ZONE* zone : m_board->Zones() )
{ {
if( isKeepoutZone( zone ) ) if( isKeepoutZone( zone, true ) )
keepoutZones.push_back( zone ); keepoutZones.push_back( zone );
} }
@ -369,7 +381,7 @@ void DRC_ENGINE::loadImplicitRules()
{ {
for( ZONE* zone : footprint->Zones() ) for( ZONE* zone : footprint->Zones() )
{ {
if( isKeepoutZone( zone ) ) if( isKeepoutZone( zone, true ) )
keepoutZones.push_back( zone ); 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() ? const BOARD_CONNECTED_ITEM* bc = b && b->IsConnected() ?
static_cast<const BOARD_CONNECTED_ITEM*>( b ) : nullptr; static_cast<const BOARD_CONNECTED_ITEM*>( b ) : nullptr;
bool a_is_unconnected = a && !ac; bool a_is_non_copper = a && ( !a->IsOnCopperLayer() || isKeepoutZone( a, false ) );
bool b_is_unconnected = b && !bc; bool b_is_non_copper = b && ( !b->IsOnCopperLayer() || isKeepoutZone( b, false ) );
const DRC_CONSTRAINT* constraintRef = nullptr; const DRC_CONSTRAINT* constraintRef = nullptr;
bool implicit = false; bool implicit = false;
@ -723,7 +735,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
int overrideA = 0; int overrideA = 0;
int overrideB = 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 ); overrideA = ac->GetLocalClearanceOverrides( &m_msg );
@ -733,7 +745,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
MessageTextFromValue( UNITS, overrideA ) ) ) 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 ); overrideB = bc->GetLocalClearanceOverrides( &m_msg );
@ -800,7 +812,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
if( aConstraintId == CLEARANCE_CONSTRAINT ) 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." ) ); REPORT( _( "Board and netclass clearances apply only to connected items." ) );
return true; 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, if( m_ruleResolver->QueryConstraint( PNS::CONSTRAINT_TYPE::CT_WIDTH, aStartItem, nullptr,
aStartItem->Layer(), &constraint ) ) aStartItem->Layer(), &constraint ) )
{ {
trackWidth = constraint.m_Value.OptThenMin(); trackWidth = constraint.m_Value.Opt();
found = true; // Note: allowed to override anything, including bds.m_TrackMinWidth 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, if( m_ruleResolver->QueryConstraint( PNS::CONSTRAINT_TYPE::CT_VIA_DIAMETER, aStartItem,
nullptr, aStartItem->Layer(), &constraint ) ) 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, if( m_ruleResolver->QueryConstraint( PNS::CONSTRAINT_TYPE::CT_VIA_HOLE, aStartItem,
nullptr, aStartItem->Layer(), &constraint ) ) nullptr, aStartItem->Layer(), &constraint ) )
{ {
viaDrill = constraint.m_Value.OptThenMin(); viaDrill = constraint.m_Value.Opt();
} }
} }
else 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, if( m_ruleResolver->QueryConstraint( PNS::CONSTRAINT_TYPE::CT_WIDTH, aStartItem,
nullptr, aStartItem->Layer(), &constraint ) ) 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, if( m_ruleResolver->QueryConstraint( PNS::CONSTRAINT_TYPE::CT_DIFF_PAIR_GAP, aStartItem,
nullptr, aStartItem->Layer(), &constraint ) ) nullptr, aStartItem->Layer(), &constraint ) )
{ {
diffPairGap = constraint.m_Value.OptThenMin(); diffPairGap = constraint.m_Value.Opt();
diffPairViaGap = constraint.m_Value.OptThenMin(); diffPairViaGap = constraint.m_Value.Opt();
} }
} }
else if( bds.UseCustomDiffPairDimensions() ) else if( bds.UseCustomDiffPairDimensions() )

View File

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