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
|| 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..." ) );
}

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,
const BOARD_ITEM* b, PCB_LAYER_ID aLayer,
REPORTER* aReporter )
@ -901,6 +928,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
case DIFF_PAIR_GAP_CONSTRAINT:
case LENGTH_CONSTRAINT:
case CONNECTION_WIDTH_CONSTRAINT:
case HOLE_TO_HOLE_CONSTRAINT:
{
if( aReporter )
{
@ -993,6 +1021,12 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
break;
case HOLE_TO_HOLE_CONSTRAINT:
REPORT( wxString::Format( _( "Checking board setup constraints "
"hole to hole: min %s." ),
min ) )
break;
default:
REPORT( wxString::Format( _( "Checking %s." ),
EscapeHTML( c->constraint.GetName() ) ) )
@ -1136,7 +1170,21 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
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 )
{

View File

@ -1217,15 +1217,13 @@ wxString PAD::GetSelectMenuText( EDA_UNITS aUnits ) const
GetParent()->GetReference(),
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" ),
wxT( "(" ) + _( "NPTH, Mechanical" ) + wxT( ")" ),
GetParent()->GetReference() );
return wxString::Format( _( "NPTH pad of %s" ), GetParent()->GetReference() );
}
else
{
return wxString::Format( _( "Through hole pad %s of %s" ),
return wxString::Format( _( "PTH pad %s of %s" ),
GetNetnameMsg(),
GetParent()->GetReference() );
}
@ -1240,15 +1238,13 @@ wxString PAD::GetSelectMenuText( EDA_UNITS aUnits ) const
GetParent()->GetReference(),
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" ),
wxT( "(" ) + _( "NPTH, Mechanical" ) + wxT( ")" ),
GetParent()->GetReference() );
return wxString::Format( _( "NPTH of %s" ), GetParent()->GetReference() );
}
else
{
return wxString::Format( _( "Through hole pad %s %s of %s" ),
return wxString::Format( _( "PTH pad %s %s of %s" ),
GetNumber(),
GetNetnameMsg(),
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 )
{
// Null items have no description
@ -149,9 +156,10 @@ wxString BOARD_INSPECTION_TOOL::getItemDescription( BOARD_ITEM* aItem )
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 );
s += wxS( " " ) + wxString::Format( _( "[netclass %s]" ),
cItem->GetEffectiveNetClass()->GetName() );
}
@ -423,6 +431,21 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
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:
r = m_inspectClearanceDialog->AddPage( _( "Edge Clearance" ) );
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() )
{
PCB_LAYER_ID layer = UNDEFINED_LAYER;
bool pageAdded = false;
if( a->HasHole() && b->IsOnLayer( active ) && IsCopperLayer( active ) )
layer = active;
@ -893,7 +917,18 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
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 );
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();
}
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 } )