Better reporting of hole-to-hole clearances and clearance resolutions.

This commit is contained in:
Jeff Young 2022-08-29 16:30:06 +01:00
parent e0f6a6e475
commit 2d68cdff94
4 changed files with 123 additions and 14 deletions

View File

@ -593,7 +593,8 @@ void DIALOG_DRC::OnDRCItemRClick( wxDataViewEvent& aEvent )
if( rcItem->GetErrorCode() == DRCE_CLEARANCE if( rcItem->GetErrorCode() == DRCE_CLEARANCE
|| rcItem->GetErrorCode() == DRCE_EDGE_CLEARANCE || rcItem->GetErrorCode() == DRCE_EDGE_CLEARANCE
|| rcItem->GetErrorCode() == DRCE_HOLE_CLEARANCE ) || rcItem->GetErrorCode() == DRCE_HOLE_CLEARANCE
|| rcItem->GetErrorCode() == DRCE_DRILLED_HOLES_TOO_CLOSE )
{ {
menu.Append( 3, _( "Run clearance resolution tool..." ) ); menu.Append( 3, _( "Run clearance resolution tool..." ) );
} }

View File

@ -643,6 +643,33 @@ DRC_CONSTRAINT DRC_ENGINE::EvalZoneConnection( const BOARD_ITEM* a, const BOARD_
} }
bool hasDrilledHole( const BOARD_ITEM* aItem )
{
if( !aItem->HasHole() )
return false;
switch( aItem->Type() )
{
case PCB_VIA_T:
{
const PCB_VIA* via = static_cast<const PCB_VIA*>( aItem );
return via->GetViaType() == VIATYPE::THROUGH;
}
case PCB_PAD_T:
{
const PAD* pad = static_cast<const PAD*>( aItem );
return pad->GetDrillSizeX() == pad->GetDrillSizeY();
}
default:
return false;
}
}
DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BOARD_ITEM* a, DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BOARD_ITEM* a,
const BOARD_ITEM* b, PCB_LAYER_ID aLayer, const BOARD_ITEM* b, PCB_LAYER_ID aLayer,
REPORTER* aReporter ) REPORTER* aReporter )
@ -901,6 +928,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
case DIFF_PAIR_GAP_CONSTRAINT: case DIFF_PAIR_GAP_CONSTRAINT:
case LENGTH_CONSTRAINT: case LENGTH_CONSTRAINT:
case CONNECTION_WIDTH_CONSTRAINT: case CONNECTION_WIDTH_CONSTRAINT:
case HOLE_TO_HOLE_CONSTRAINT:
{ {
if( aReporter ) if( aReporter )
{ {
@ -993,6 +1021,12 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
break; break;
case HOLE_TO_HOLE_CONSTRAINT:
REPORT( wxString::Format( _( "Checking board setup constraints "
"hole to hole: min %s." ),
min ) )
break;
default: default:
REPORT( wxString::Format( _( "Checking %s." ), REPORT( wxString::Format( _( "Checking %s." ),
EscapeHTML( c->constraint.GetName() ) ) ) EscapeHTML( c->constraint.GetName() ) ) )
@ -1136,7 +1170,21 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
return false; return false;
} }
if( !c->condition || c->condition->GetExpression().IsEmpty() ) if( c->constraint.m_Type == HOLE_TO_HOLE_CONSTRAINT
&& ( !hasDrilledHole( a ) || !hasDrilledHole( b ) ) )
{
// Report non-drilled-holes as an implicit condition
if( aReporter )
{
const BOARD_ITEM* x = !hasDrilledHole( a ) ? a : b;
REPORT( wxString::Format( _( "%s is not a drilled hole; rule ignored." ),
x->GetSelectMenuText( UNITS ) ) )
}
return false;
}
else if( !c->condition || c->condition->GetExpression().IsEmpty() )
{ {
if( aReporter ) if( aReporter )
{ {

View File

@ -1217,15 +1217,13 @@ wxString PAD::GetSelectMenuText( EDA_UNITS aUnits ) const
GetParent()->GetReference(), GetParent()->GetReference(),
layerMaskDescribe() ); layerMaskDescribe() );
} }
else if( GetAttribute() == PAD_ATTRIB::NPTH && !FlashLayer( F_Cu ) ) else if( GetAttribute() == PAD_ATTRIB::NPTH )
{ {
return wxString::Format( _( "Through hole pad %s of %s" ), return wxString::Format( _( "NPTH pad of %s" ), GetParent()->GetReference() );
wxT( "(" ) + _( "NPTH, Mechanical" ) + wxT( ")" ),
GetParent()->GetReference() );
} }
else else
{ {
return wxString::Format( _( "Through hole pad %s of %s" ), return wxString::Format( _( "PTH pad %s of %s" ),
GetNetnameMsg(), GetNetnameMsg(),
GetParent()->GetReference() ); GetParent()->GetReference() );
} }
@ -1240,15 +1238,13 @@ wxString PAD::GetSelectMenuText( EDA_UNITS aUnits ) const
GetParent()->GetReference(), GetParent()->GetReference(),
layerMaskDescribe() ); layerMaskDescribe() );
} }
else if( GetAttribute() == PAD_ATTRIB::NPTH && !FlashLayer( F_Cu ) ) else if( GetAttribute() == PAD_ATTRIB::NPTH )
{ {
return wxString::Format( _( "Through hole pad %s of %s" ), return wxString::Format( _( "NPTH of %s" ), GetParent()->GetReference() );
wxT( "(" ) + _( "NPTH, Mechanical" ) + wxT( ")" ),
GetParent()->GetReference() );
} }
else else
{ {
return wxString::Format( _( "Through hole pad %s %s of %s" ), return wxString::Format( _( "PTH pad %s %s of %s" ),
GetNumber(), GetNumber(),
GetNetnameMsg(), GetNetnameMsg(),
GetParent()->GetReference() ); GetParent()->GetReference() );

View File

@ -141,6 +141,13 @@ DRC_ENGINE BOARD_INSPECTION_TOOL::makeDRCEngine( bool* aCompileError, bool* aCou
} }
bool isNPTHPad( BOARD_ITEM* aItem )
{
return aItem->Type() == PCB_PAD_T
&& static_cast<PAD*>( aItem )->GetAttribute() == PAD_ATTRIB::NPTH;
}
wxString BOARD_INSPECTION_TOOL::getItemDescription( BOARD_ITEM* aItem ) wxString BOARD_INSPECTION_TOOL::getItemDescription( BOARD_ITEM* aItem )
{ {
// Null items have no description // Null items have no description
@ -149,9 +156,10 @@ wxString BOARD_INSPECTION_TOOL::getItemDescription( BOARD_ITEM* aItem )
wxString s = aItem->GetSelectMenuText( m_frame->GetUserUnits() ); wxString s = aItem->GetSelectMenuText( m_frame->GetUserUnits() );
if( aItem->IsConnected() ) if( aItem->IsConnected() && !isNPTHPad( aItem ) )
{ {
BOARD_CONNECTED_ITEM* cItem = static_cast<BOARD_CONNECTED_ITEM*>( aItem ); BOARD_CONNECTED_ITEM* cItem = static_cast<BOARD_CONNECTED_ITEM*>( aItem );
s += wxS( " " ) + wxString::Format( _( "[netclass %s]" ), s += wxS( " " ) + wxString::Format( _( "[netclass %s]" ),
cItem->GetEffectiveNetClass()->GetName() ); cItem->GetEffectiveNetClass()->GetName() );
} }
@ -423,6 +431,21 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
break; break;
case DRCE_DRILLED_HOLES_TOO_CLOSE:
r = m_inspectClearanceDialog->AddPage( _( "Hole to Hole" ) );
reportHeader( _( "Hole to hole clearance resolution for:" ), a, b, r );
if( compileError )
reportCompileError( r );
constraint = drcEngine.EvalRules( HOLE_TO_HOLE_CONSTRAINT, a, b, UNDEFINED_LAYER, r );
clearance = constraint.m_Value.Min();
clearanceStr = StringFromValue( r->GetUnits(), clearance, true );
r->Report( "" );
r->Report( wxString::Format( _( "Resolved clearance: %s." ), clearanceStr ) );
break;
case DRCE_EDGE_CLEARANCE: case DRCE_EDGE_CLEARANCE:
r = m_inspectClearanceDialog->AddPage( _( "Edge Clearance" ) ); r = m_inspectClearanceDialog->AddPage( _( "Edge Clearance" ) );
reportHeader( _( "Edge clearance resolution for:" ), a, b, r ); reportHeader( _( "Edge clearance resolution for:" ), a, b, r );
@ -881,6 +904,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
if( a->HasHole() || b->HasHole() ) if( a->HasHole() || b->HasHole() )
{ {
PCB_LAYER_ID layer = UNDEFINED_LAYER; PCB_LAYER_ID layer = UNDEFINED_LAYER;
bool pageAdded = false;
if( a->HasHole() && b->IsOnLayer( active ) && IsCopperLayer( active ) ) if( a->HasHole() && b->IsOnLayer( active ) && IsCopperLayer( active ) )
layer = active; layer = active;
@ -893,7 +917,18 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
if( layer >= 0 ) if( layer >= 0 )
{ {
r = m_inspectClearanceDialog->AddPage( _( "Hole" ) ); if( !pageAdded )
{
r = m_inspectClearanceDialog->AddPage( _( "Hole" ) );
pageAdded = true;
}
else
{
r->Report( "" );
r->Report( "" );
r->Report( "" );
}
reportHeader( _( "Hole clearance resolution for:" ), a, b, layer, r ); reportHeader( _( "Hole clearance resolution for:" ), a, b, layer, r );
constraint = drcEngine.EvalRules( HOLE_CLEARANCE_CONSTRAINT, a, b, layer, r ); constraint = drcEngine.EvalRules( HOLE_CLEARANCE_CONSTRAINT, a, b, layer, r );
@ -908,6 +943,35 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
r->Flush(); r->Flush();
} }
if( a->HasHole() && b->HasHole() )
{
if( !pageAdded )
{
r = m_inspectClearanceDialog->AddPage( _( "Hole" ) );
pageAdded = true;
}
else
{
r->Report( "" );
r->Report( "" );
r->Report( "" );
}
reportHeader( _( "Hole to hole clearance resolution for:" ), a, b, r );
constraint = drcEngine.EvalRules( HOLE_TO_HOLE_CONSTRAINT, a, b, UNDEFINED_LAYER, r );
clearance = constraint.m_Value.Min();
if( compileError )
reportCompileError( r );
r->Report( "" );
r->Report( wxString::Format( _( "Resolved clearance: %s." ),
StringFromValue( units, clearance, true ) ) );
r->Flush();
}
} }
for( PCB_LAYER_ID edgeLayer : { Edge_Cuts, Margin } ) for( PCB_LAYER_ID edgeLayer : { Edge_Cuts, Margin } )