diff --git a/pcbnew/dialogs/dialog_drc.cpp b/pcbnew/dialogs/dialog_drc.cpp
index 7a2748ab62..e40aedd236 100644
--- a/pcbnew/dialogs/dialog_drc.cpp
+++ b/pcbnew/dialogs/dialog_drc.cpp
@@ -543,10 +543,17 @@ void DIALOG_DRC::OnDRCItemRClick( wxDataViewEvent& aEvent )
}
if( rcItem->GetErrorCode() == DRCE_CLEARANCE
- || rcItem->GetErrorCode() == DRCE_EDGE_CLEARANCE )
+ || rcItem->GetErrorCode() == DRCE_EDGE_CLEARANCE
+ || rcItem->GetErrorCode() == DRCE_HOLE_CLEARANCE )
{
menu.Append( 3, _( "Run clearance resolution tool..." ) );
}
+ else if( rcItem->GetErrorCode() == DRCE_TEXT_HEIGHT
+ || rcItem->GetErrorCode() == DRCE_TEXT_THICKNESS
+ || rcItem->GetErrorCode() == DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG )
+ {
+ menu.Append( 3, _( "Run constraints resolution tool..." ) );
+ }
menu.AppendSeparator();
diff --git a/pcbnew/drc/drc_engine.cpp b/pcbnew/drc/drc_engine.cpp
index af709fba2d..3f9d1ce0ec 100644
--- a/pcbnew/drc/drc_engine.cpp
+++ b/pcbnew/drc/drc_engine.cpp
@@ -186,15 +186,18 @@ void DRC_ENGINE::loadImplicitRules()
rule = createImplicitRule( _( "board setup constraints silk" ) );
rule->m_LayerCondition = LSET( 2, F_SilkS, B_SilkS );
-
DRC_CONSTRAINT silkClearanceConstraint( SILK_CLEARANCE_CONSTRAINT );
silkClearanceConstraint.Value().SetMin( bds.m_SilkClearance );
rule->AddConstraint( silkClearanceConstraint );
+ rule = createImplicitRule( _( "board setup constraints silk text height" ) );
+ rule->m_LayerCondition = LSET( 2, F_SilkS, B_SilkS );
DRC_CONSTRAINT silkTextHeightConstraint( TEXT_HEIGHT_CONSTRAINT );
silkTextHeightConstraint.Value().SetMin( bds.m_MinSilkTextHeight );
rule->AddConstraint( silkTextHeightConstraint );
+ rule = createImplicitRule( _( "board setup constraints silk text thickness" ) );
+ rule->m_LayerCondition = LSET( 2, F_SilkS, B_SilkS );
DRC_CONSTRAINT silkTextThicknessConstraint( TEXT_THICKNESS_CONSTRAINT );
silkTextThicknessConstraint.Value().SetMin( bds.m_MinSilkTextThickness );
rule->AddConstraint( silkTextThicknessConstraint );
@@ -920,6 +923,8 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
case SILK_CLEARANCE_CONSTRAINT:
case HOLE_CLEARANCE_CONSTRAINT:
case EDGE_CLEARANCE_CONSTRAINT:
+ case MECHANICAL_CLEARANCE_CONSTRAINT:
+ case MECHANICAL_HOLE_CLEARANCE_CONSTRAINT:
{
int val = c->constraint.m_Value.Min();
REPORT( wxString::Format( _( "Checking %s clearance: %s." ),
@@ -928,11 +933,22 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
break;
}
+ case DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT:
+ {
+ int val = c->constraint.m_Value.Max();
+ REPORT( wxString::Format( _( "Checking %s max uncoupled length: %s." ),
+ EscapeHTML( c->constraint.GetName() ),
+ REPORT_VALUE( val ) ) )
+ break;
+ }
+
+
case TRACK_WIDTH_CONSTRAINT:
case ANNULAR_WIDTH_CONSTRAINT:
case VIA_DIAMETER_CONSTRAINT:
case TEXT_HEIGHT_CONSTRAINT:
case TEXT_THICKNESS_CONSTRAINT:
+ case DIFF_PAIR_GAP_CONSTRAINT:
{
if( aReporter )
{
@@ -950,10 +966,11 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
case TRACK_WIDTH_CONSTRAINT: msg = _( "track width" ); break;
case ANNULAR_WIDTH_CONSTRAINT: msg = _( "annular width" ); break;
case VIA_DIAMETER_CONSTRAINT: msg = _( "via diameter" ); break;
+ case DIFF_PAIR_GAP_CONSTRAINT: msg = _( "diff pair gap" ); break;
default: msg = _( "constraint" ); break;
}
- REPORT( wxString::Format( _( "Checking %s %s: %s." ),
+ REPORT( wxString::Format( _( "Checking %s %s: opt %s." ),
EscapeHTML( c->constraint.GetName() ),
EscapeHTML( msg ),
opt ) )
diff --git a/pcbnew/tools/board_inspection_tool.cpp b/pcbnew/tools/board_inspection_tool.cpp
index 327bc1bcbb..df67fd5c8b 100644
--- a/pcbnew/tools/board_inspection_tool.cpp
+++ b/pcbnew/tools/board_inspection_tool.cpp
@@ -194,19 +194,45 @@ void BOARD_INSPECTION_TOOL::reportHeader( const wxString& aTitle, BOARD_ITEM* a,
}
+wxString reportMin( EDA_UNITS aUnits, DRC_CONSTRAINT& aConstraint )
+{
+ if( aConstraint.m_Value.HasMin() )
+ return StringFromValue( aUnits, aConstraint.m_Value.Min(), true );
+ else
+ return wxT( "" ) + _( "undefined" ) + wxT( "" );
+}
+
+
+wxString reportOpt( EDA_UNITS aUnits, DRC_CONSTRAINT& aConstraint )
+{
+ if( aConstraint.m_Value.HasOpt() )
+ return StringFromValue( aUnits, aConstraint.m_Value.Opt(), true );
+ else
+ return wxT( "" ) + _( "undefined" ) + wxT( "" );
+}
+
+
+wxString reportMax( EDA_UNITS aUnits, DRC_CONSTRAINT& aConstraint )
+{
+ if( aConstraint.m_Value.HasMax() )
+ return StringFromValue( aUnits, aConstraint.m_Value.Max(), true );
+ else
+ return wxT( "" ) + _( "undefined" ) + wxT( "" );
+}
+
+
void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr& aDRCItem )
{
- BOARD_ITEM* a = m_frame->GetBoard()->GetItem( aDRCItem->GetMainItemID() );
- BOARD_ITEM* b = m_frame->GetBoard()->GetItem( aDRCItem->GetAuxItemID() );
- PCB_LAYER_ID layer = m_frame->GetActiveLayer();
-
- if( !a || !b )
- return;
+ BOARD_ITEM* a = m_frame->GetBoard()->GetItem( aDRCItem->GetMainItemID() );
+ BOARD_ITEM* b = m_frame->GetBoard()->GetItem( aDRCItem->GetAuxItemID() );
+ BOARD_CONNECTED_ITEM* ac = dynamic_cast( a );
+ BOARD_CONNECTED_ITEM* bc = dynamic_cast( b );
+ PCB_LAYER_ID layer = m_frame->GetActiveLayer();
if( m_inspectClearanceDialog == nullptr )
{
m_inspectClearanceDialog = std::make_unique( m_frame );
- m_inspectClearanceDialog->SetTitle( _( "Clearance Report" ) );
+ m_inspectClearanceDialog->SetTitle( _( "Violation Report" ) );
m_inspectClearanceDialog->Connect( wxEVT_CLOSE_WINDOW,
wxCommandEventHandler( BOARD_INSPECTION_TOOL::onInspectClearanceDialogClosed ),
@@ -222,8 +248,108 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr& aDR
switch( aDRCItem->GetErrorCode() )
{
+ case DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG:
+ {
+ for( KIID id : aDRCItem->GetIDs() )
+ {
+ bc = dynamic_cast( m_frame->GetBoard()->GetItem( id ) );
+
+ if( ac && bc && ac->GetNetCode() != bc->GetNetCode() )
+ break;
+ }
+
+ r = m_inspectClearanceDialog->AddPage( _( "Uncoupled Length" ) );
+ reportHeader( _( "Diff pair uncoupled length resolution for:" ), ac, bc, r );
+
+ if( compileError )
+ reportCompileError( r );
+
+ constraint = drcEngine.EvalRules( DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT, a, b, layer, r );
+
+ r->Report( "" );
+ r->Report( wxString::Format( _( "Resolved max uncoupled length: %s." ),
+ reportMax( r->GetUnits(), constraint ) ) );
+ break;
+ }
+
+ case DRCE_TEXT_HEIGHT:
+ r = m_inspectClearanceDialog->AddPage( _( "Text Height" ) );
+ reportHeader( _( "Text height resolution for:" ), a, r );
+
+ if( compileError )
+ reportCompileError( r );
+
+ constraint = drcEngine.EvalRules( TEXT_HEIGHT_CONSTRAINT, a, b, layer, r );
+
+ r->Report( "" );
+ r->Report( wxString::Format( _( "Resolved text height constraints: min %s; opt %s; max %s." ),
+ reportMin( r->GetUnits(), constraint ),
+ reportOpt( r->GetUnits(), constraint ),
+ reportMax( r->GetUnits(), constraint ) ) );
+ break;
+
+ case DRCE_TEXT_THICKNESS:
+ r = m_inspectClearanceDialog->AddPage( _( "Text Thickness" ) );
+ reportHeader( _( "Text thickness resolution for:" ), a, r );
+
+ if( compileError )
+ reportCompileError( r );
+
+ constraint = drcEngine.EvalRules( TEXT_THICKNESS_CONSTRAINT, a, b, layer, r );
+
+ r->Report( "" );
+ r->Report( wxString::Format( _( "Resolved text thickness constraints: min %s; opt %s; max %s." ),
+ reportMin( r->GetUnits(), constraint ),
+ reportOpt( r->GetUnits(), constraint ),
+ reportMax( r->GetUnits(), constraint ) ) );
+ break;
+
+ case DRCE_HOLE_CLEARANCE:
+ r = m_inspectClearanceDialog->AddPage( _( "Hole Clearance" ) );
+ reportHeader( _( "Hole clearance resolution for:" ), a, b, r );
+
+ if( compileError )
+ reportCompileError( r );
+
+ if( ac && bc && ac->GetNetCode() == bc->GetNetCode() )
+ {
+ r->Report( "" );
+ r->Report( _( "Items belong to the same net. Clearance is 0." ) );
+ }
+ else
+ {
+ constraint = drcEngine.EvalRules( HOLE_CLEARANCE_CONSTRAINT, a, b, layer, r );
+ clearance = constraint.m_Value.Min();
+ clearanceStr = StringFromValue( r->GetUnits(), clearance, true );
+
+ r->Report( "" );
+ r->Report( wxString::Format( _( "Resolved clearance: %s." ), clearanceStr ) );
+ }
+
+ r->Report( "" );
+ r->Report( "" );
+ r->Report( "" );
+ reportHeader( _( "Mechanical hole clearance resolution for:" ), a, b, layer, r );
+
+ constraint = drcEngine.EvalRules( MECHANICAL_HOLE_CLEARANCE_CONSTRAINT, a, b, layer, r );
+ clearance = constraint.m_Value.Min();
+ clearanceStr = StringFromValue( r->GetUnits(), clearance, true );
+
+ if( !drcEngine.HasRulesForConstraintType( MECHANICAL_HOLE_CLEARANCE_CONSTRAINT ) )
+ {
+ r->Report( "" );
+ r->Report( _( "No 'mechanical_hole_clearance' constraints defined." ) );
+ }
+ else
+ {
+ r->Report( "" );
+ r->Report( wxString::Format( _( "Resolved clearance: %s." ), clearanceStr ) );
+ }
+
+ break;
+
case DRCE_EDGE_CLEARANCE:
- r = m_inspectClearanceDialog->AddPage( _( "Clearance" ) );
+ r = m_inspectClearanceDialog->AddPage( _( "Edge Clearance" ) );
reportHeader( _( "Edge clearance resolution for:" ), a, b, r );
if( compileError )
@@ -271,12 +397,41 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr& aDR
if( compileError )
reportCompileError( r );
- constraint = drcEngine.EvalRules( CLEARANCE_CONSTRAINT, a, a, layer, r );
+ if( ac && bc && ac->GetNetCode() == bc->GetNetCode() )
+ {
+ r->Report( "" );
+ r->Report( _( "Items belong to the same net. Clearance is 0." ) );
+ }
+ else
+ {
+ constraint = drcEngine.EvalRules( CLEARANCE_CONSTRAINT, a, a, layer, r );
+ clearance = constraint.m_Value.Min();
+ clearanceStr = StringFromValue( r->GetUnits(), clearance, true );
+
+ r->Report( "" );
+ r->Report( wxString::Format( _( "Resolved clearance: %s." ), clearanceStr ) );
+ }
+
+ r->Report( "" );
+ r->Report( "" );
+ r->Report( "" );
+ reportHeader( _( "Mechanical clearance resolution for:" ), a, b, layer, r );
+
+ constraint = drcEngine.EvalRules( MECHANICAL_CLEARANCE_CONSTRAINT, a, b, layer, r );
clearance = constraint.m_Value.Min();
clearanceStr = StringFromValue( r->GetUnits(), clearance, true );
- r->Report( "" );
- r->Report( wxString::Format( _( "Resolved clearance: %s." ), clearanceStr ) );
+ if( !drcEngine.HasRulesForConstraintType( MECHANICAL_CLEARANCE_CONSTRAINT ) )
+ {
+ r->Report( "" );
+ r->Report( _( "No 'mechanical_clearance' constraints defined." ) );
+ }
+ else
+ {
+ r->Report( "" );
+ r->Report( wxString::Format( _( "Resolved clearance: %s." ), clearanceStr ) );
+ }
+
break;
default:
@@ -499,6 +654,49 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
r->Flush();
}
+ if( ac && bc )
+ {
+ NETINFO_ITEM* refNet = ac->GetNet();
+ wxString coupledNet;
+ wxString dummy;
+
+ if( DRC_ENGINE::MatchDpSuffix( refNet->GetNetname(), coupledNet, dummy )
+ && bc->GetNetname() == coupledNet )
+ {
+ r = m_inspectClearanceDialog->AddPage( _( "Diff Pair" ) );
+ reportHeader( _( "Diff pair gap resolution for:" ), ac, bc, active, r );
+
+ constraint = drcEngine.EvalRules( DIFF_PAIR_GAP_CONSTRAINT, ac, bc, active, r );
+
+ r->Report( "" );
+ r->Report( wxString::Format( _( "Resolved gap constraints: min %s; opt %s; max %s." ),
+ reportMin( r->GetUnits(), constraint ),
+ reportOpt( r->GetUnits(), constraint ),
+ reportMax( r->GetUnits(), constraint ) ) );
+
+ r->Report( "" );
+ r->Report( "" );
+ r->Report( "" );
+ reportHeader( _( "Diff pair max uncoupled length resolution for:" ), ac, bc, active, r );
+
+ if( !drcEngine.HasRulesForConstraintType( DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT ) )
+ {
+ r->Report( "" );
+ r->Report( _( "No 'diff_pair_uncoupled' constraints defined." ) );
+ }
+ else
+ {
+ constraint = drcEngine.EvalRules( DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT, ac, bc,
+ active, r );
+
+ r->Report( "" );
+ r->Report( wxString::Format( _( "Resolved max uncoupled length: %s." ),
+ reportMax( r->GetUnits(), constraint ) ) );
+ }
+ r->Flush();
+ }
+ }
+
for( PCB_LAYER_ID layer : { F_SilkS, B_SilkS } )
{
PCB_LAYER_ID correspondingMask = IsFrontLayer( layer ) ? F_Mask : B_Mask;
@@ -691,33 +889,6 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
}
-wxString reportMin( EDA_UNITS aUnits, DRC_CONSTRAINT& aConstraint )
-{
- if( aConstraint.m_Value.HasMin() )
- return StringFromValue( aUnits, aConstraint.m_Value.Min(), true );
- else
- return wxT( "" ) + _( "undefined" ) + wxT( "" );
-}
-
-
-wxString reportOpt( EDA_UNITS aUnits, DRC_CONSTRAINT& aConstraint )
-{
- if( aConstraint.m_Value.HasOpt() )
- return StringFromValue( aUnits, aConstraint.m_Value.Opt(), true );
- else
- return wxT( "" ) + _( "undefined" ) + wxT( "" );
-}
-
-
-wxString reportMax( EDA_UNITS aUnits, DRC_CONSTRAINT& aConstraint )
-{
- if( aConstraint.m_Value.HasMax() )
- return StringFromValue( aUnits, aConstraint.m_Value.Max(), true );
- else
- return wxT( "" ) + _( "undefined" ) + wxT( "" );
-}
-
-
int BOARD_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent )
{
#define EVAL_RULES( constraint, a, b, layer, r ) drcEngine.EvalRules( constraint, a, b, layer, r )
@@ -830,6 +1001,43 @@ int BOARD_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent )
r->Flush();
}
+ if( item->Type() == PCB_TEXT_T
+ || item->Type() == PCB_TEXTBOX_T
+ || item->Type() == PCB_FP_TEXT_T )
+ {
+ r = m_inspectConstraintsDialog->AddPage( _( "Text Size" ) );
+ reportHeader( _( "Text height resolution for:" ), item, r );
+
+ constraint = EVAL_RULES( TEXT_HEIGHT_CONSTRAINT, item, nullptr, UNDEFINED_LAYER, r );
+
+ if( compileError )
+ reportCompileError( r );
+
+ r->Report( "" );
+ r->Report( wxString::Format( _( "Text height constraints: min %s; opt %s; max %s." ),
+ reportMin( r->GetUnits(), constraint ),
+ reportOpt( r->GetUnits(), constraint ),
+ reportMax( r->GetUnits(), constraint ) ) );
+
+ r->Report( "" );
+ r->Report( "" );
+ r->Report( "" );
+ reportHeader( _( "Text thickness resolution for:" ), item, r );
+
+ constraint = EVAL_RULES( TEXT_THICKNESS_CONSTRAINT, item, nullptr, UNDEFINED_LAYER, r );
+
+ if( compileError )
+ reportCompileError( r );
+
+ r->Report( "" );
+ r->Report( wxString::Format( _( "Text thickness constraints: min %s; opt %s; max %s." ),
+ reportMin( r->GetUnits(), constraint ),
+ reportOpt( r->GetUnits(), constraint ),
+ reportMax( r->GetUnits(), constraint ) ) );
+
+ r->Flush();
+ }
+
r = m_inspectConstraintsDialog->AddPage( _( "Keepouts" ) );
reportHeader( _( "Keepout resolution for:" ), item, r );