Improve clearance and constraint resolution reporting.
1) Report on all applicable clearance types 2) Don't double-book constraints if they're used by more than one test provider Fixes https://gitlab.com/kicad/code/kicad/issues/8961
This commit is contained in:
parent
3f64b69917
commit
56c85bd354
|
@ -40,7 +40,7 @@
|
|||
#include <geometry/shape.h>
|
||||
#include <geometry/shape_segment.h>
|
||||
#include <geometry/shape_null.h>
|
||||
#include <convert_basic_shapes_to_polygon.h>
|
||||
|
||||
|
||||
void drcPrintDebugMessage( int level, const wxString& msg, const char *function, int line )
|
||||
{
|
||||
|
@ -580,70 +580,43 @@ void DRC_ENGINE::loadRules( const wxFileName& aPath )
|
|||
|
||||
void DRC_ENGINE::compileRules()
|
||||
{
|
||||
ReportAux( wxString::Format( "Compiling Rules (%d rules): ",
|
||||
(int) m_rules.size() ) );
|
||||
ReportAux( wxString::Format( "Compiling Rules (%d rules): ", (int) m_rules.size() ) );
|
||||
|
||||
std::set<DRC_CONSTRAINT_T> constraintTypes;
|
||||
|
||||
for( DRC_TEST_PROVIDER* provider : m_testProviders )
|
||||
{
|
||||
ReportAux( wxString::Format( "- Provider: '%s': ", provider->GetName() ) );
|
||||
drc_dbg( 7, "do prov %s", provider->GetName() );
|
||||
for( DRC_CONSTRAINT_T constraintType : provider->GetConstraintTypes() )
|
||||
constraintTypes.insert( constraintType );
|
||||
}
|
||||
|
||||
for( DRC_CONSTRAINT_T id : provider->GetConstraintTypes() )
|
||||
for( DRC_CONSTRAINT_T constraintType : constraintTypes )
|
||||
{
|
||||
if( m_constraintMap.find( constraintType ) == m_constraintMap.end() )
|
||||
m_constraintMap[ constraintType ] = new std::vector<DRC_ENGINE_CONSTRAINT*>();
|
||||
|
||||
for( DRC_RULE* rule : m_rules )
|
||||
{
|
||||
drc_dbg( 7, "do id %d", id );
|
||||
DRC_RULE_CONDITION* condition = nullptr;
|
||||
|
||||
if( m_constraintMap.find( id ) == m_constraintMap.end() )
|
||||
m_constraintMap[ id ] = new std::vector<DRC_ENGINE_CONSTRAINT*>();
|
||||
|
||||
for( DRC_RULE* rule : m_rules )
|
||||
if( rule->m_Condition && !rule->m_Condition->GetExpression().IsEmpty() )
|
||||
{
|
||||
DRC_RULE_CONDITION* condition = nullptr;
|
||||
bool compileOk = false;
|
||||
std::vector<DRC_CONSTRAINT> matchingConstraints;
|
||||
drc_dbg( 7, "Scan provider %s, rule %s", provider->GetName(), rule->m_Name );
|
||||
condition = rule->m_Condition;
|
||||
condition->Compile( nullptr, 0, 0 ); // fixme
|
||||
}
|
||||
|
||||
if( rule->m_Condition && !rule->m_Condition->GetExpression().IsEmpty() )
|
||||
for( const DRC_CONSTRAINT& constraint : rule->m_Constraints )
|
||||
{
|
||||
if( constraint.m_Type == constraintType )
|
||||
{
|
||||
condition = rule->m_Condition;
|
||||
compileOk = condition->Compile( nullptr, 0, 0 ); // fixme
|
||||
}
|
||||
DRC_ENGINE_CONSTRAINT* engineConstraint = new DRC_ENGINE_CONSTRAINT;
|
||||
|
||||
for( const DRC_CONSTRAINT& constraint : rule->m_Constraints )
|
||||
{
|
||||
drc_dbg(7, "scan constraint id %d\n", constraint.m_Type );
|
||||
engineConstraint->layerTest = rule->m_LayerCondition;
|
||||
engineConstraint->condition = condition;
|
||||
|
||||
if( constraint.m_Type != id )
|
||||
continue;
|
||||
|
||||
DRC_ENGINE_CONSTRAINT* rcons = new DRC_ENGINE_CONSTRAINT;
|
||||
|
||||
rcons->layerTest = rule->m_LayerCondition;
|
||||
rcons->condition = condition;
|
||||
|
||||
matchingConstraints.push_back( constraint );
|
||||
|
||||
rcons->constraint = constraint;
|
||||
rcons->parentRule = rule;
|
||||
m_constraintMap[ id ]->push_back( rcons );
|
||||
}
|
||||
|
||||
if( !matchingConstraints.empty() )
|
||||
{
|
||||
ReportAux( wxString::Format( " |- Rule: '%s' ",
|
||||
rule->m_Name ) );
|
||||
|
||||
if( condition )
|
||||
{
|
||||
ReportAux( wxString::Format( " |- condition: '%s' compile: %s",
|
||||
condition->GetExpression(),
|
||||
compileOk ? "OK" : "ERROR" ) );
|
||||
}
|
||||
|
||||
for (const DRC_CONSTRAINT& constraint : matchingConstraints )
|
||||
{
|
||||
ReportAux( wxString::Format( " |- constraint: %s",
|
||||
formatConstraint( constraint ) ) );
|
||||
}
|
||||
engineConstraint->constraint = constraint;
|
||||
engineConstraint->parentRule = rule;
|
||||
m_constraintMap[ constraintType ]->push_back( engineConstraint );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1018,6 +991,8 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
|
|||
case TRACK_WIDTH_CONSTRAINT:
|
||||
case ANNULAR_WIDTH_CONSTRAINT:
|
||||
case VIA_DIAMETER_CONSTRAINT:
|
||||
case TEXT_HEIGHT_CONSTRAINT:
|
||||
case TEXT_THICKNESS_CONSTRAINT:
|
||||
{
|
||||
if( aReporter )
|
||||
{
|
||||
|
|
|
@ -107,6 +107,38 @@ int BOARD_INSPECTION_TOOL::ShowStatisticsDialog( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
DRC_ENGINE BOARD_INSPECTION_TOOL::makeDRCEngine( bool* aCompileError, bool* aCourtyardError )
|
||||
{
|
||||
DRC_ENGINE engine( m_frame->GetBoard(), &m_frame->GetBoard()->GetDesignSettings() );
|
||||
|
||||
try
|
||||
{
|
||||
engine.InitEngine( m_frame->GetDesignRulesPath() );
|
||||
}
|
||||
catch( PARSE_ERROR& )
|
||||
{
|
||||
if( aCompileError )
|
||||
*aCompileError = true;
|
||||
}
|
||||
|
||||
for( ZONE* zone : m_frame->GetBoard()->Zones() )
|
||||
zone->CacheBoundingBox();
|
||||
|
||||
for( FOOTPRINT* footprint : m_frame->GetBoard()->Footprints() )
|
||||
{
|
||||
for( ZONE* zone : footprint->Zones() )
|
||||
zone->CacheBoundingBox();
|
||||
|
||||
footprint->BuildPolyCourtyards();
|
||||
|
||||
if( aCourtyardError && ( footprint->GetFlags() & MALFORMED_COURTYARDS ) != 0 )
|
||||
*aCourtyardError = true;
|
||||
}
|
||||
|
||||
return engine;
|
||||
}
|
||||
|
||||
|
||||
wxString BOARD_INSPECTION_TOOL::getItemDescription( BOARD_ITEM* aItem )
|
||||
{
|
||||
// Null items have no description
|
||||
|
@ -126,7 +158,7 @@ wxString BOARD_INSPECTION_TOOL::getItemDescription( BOARD_ITEM* aItem )
|
|||
};
|
||||
|
||||
|
||||
void reportCompileError( REPORTER* r )
|
||||
void BOARD_INSPECTION_TOOL::reportCompileError( REPORTER* r )
|
||||
{
|
||||
r->Report( "" );
|
||||
r->Report( _( "Report incomplete: could not compile custom design rules. " )
|
||||
|
@ -134,40 +166,31 @@ void reportCompileError( REPORTER* r )
|
|||
}
|
||||
|
||||
|
||||
void BOARD_INSPECTION_TOOL::reportClearance( DRC_CONSTRAINT_T aClearanceType, PCB_LAYER_ID aLayer,
|
||||
BOARD_ITEM* aA, BOARD_ITEM* aB, REPORTER* r )
|
||||
void BOARD_INSPECTION_TOOL::reportHeader( const wxString& aTitle, BOARD_ITEM* a, REPORTER* r )
|
||||
{
|
||||
r->Report( "" );
|
||||
r->Report( "<h7>" + EscapeHTML( aTitle ) + "</h7>" );
|
||||
r->Report( "<ul><li>" + EscapeHTML( getItemDescription( a ) ) + "</li></ul>" );
|
||||
}
|
||||
|
||||
DRC_ENGINE drcEngine( m_frame->GetBoard(), &m_frame->GetBoard()->GetDesignSettings() );
|
||||
|
||||
try
|
||||
{
|
||||
drcEngine.InitEngine( m_frame->GetDesignRulesPath() );
|
||||
}
|
||||
catch( PARSE_ERROR& )
|
||||
{
|
||||
reportCompileError( r );
|
||||
return;
|
||||
}
|
||||
void BOARD_INSPECTION_TOOL::reportHeader( const wxString& aTitle, BOARD_ITEM* a, BOARD_ITEM* b,
|
||||
REPORTER* r )
|
||||
{
|
||||
r->Report( "<h7>" + EscapeHTML( aTitle ) + "</h7>" );
|
||||
r->Report( "<ul><li>" + EscapeHTML( getItemDescription( a ) ) + "</li>"
|
||||
+ "<li>" + EscapeHTML( getItemDescription( b ) ) + "</li></ul>" );
|
||||
}
|
||||
|
||||
for( ZONE* zone : m_frame->GetBoard()->Zones() )
|
||||
zone->CacheBoundingBox();
|
||||
|
||||
for( FOOTPRINT* footprint : m_frame->GetBoard()->Footprints() )
|
||||
{
|
||||
for( ZONE* zone : footprint->Zones() )
|
||||
zone->CacheBoundingBox();
|
||||
void BOARD_INSPECTION_TOOL::reportHeader( const wxString& aTitle, BOARD_ITEM* a, BOARD_ITEM* b,
|
||||
PCB_LAYER_ID aLayer, REPORTER* r )
|
||||
{
|
||||
wxString layerStr = _( "Layer" ) + wxS( " " ) + m_frame->GetBoard()->GetLayerName( aLayer );
|
||||
|
||||
footprint->BuildPolyCourtyards();
|
||||
}
|
||||
|
||||
DRC_CONSTRAINT constraint = drcEngine.EvalRules( aClearanceType, aA, aB, aLayer, r );
|
||||
int clearance = constraint.m_Value.Min();
|
||||
wxString clearanceStr = StringFromValue( r->GetUnits(), clearance, true );
|
||||
|
||||
r->Report( "" );
|
||||
r->Report( wxString::Format( _( "Resolved clearance: %s." ), clearanceStr ) );
|
||||
r->Report( "<h7>" + EscapeHTML( aTitle ) + "</h7>" );
|
||||
r->Report( "<ul><li>" + EscapeHTML( layerStr ) + "</li>"
|
||||
+ "<li>" + EscapeHTML( getItemDescription( a ) ) + "</li>"
|
||||
+ "<li>" + EscapeHTML( getItemDescription( b ) ) + "</li></ul>" );
|
||||
}
|
||||
|
||||
|
||||
|
@ -190,18 +213,28 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
|
|||
nullptr, this );
|
||||
}
|
||||
|
||||
WX_HTML_REPORT_BOX* r = m_inspectClearanceDialog->AddPage( _( "Clearance" ) );
|
||||
WX_HTML_REPORT_BOX* r = nullptr;
|
||||
bool compileError = false;
|
||||
DRC_ENGINE drcEngine = makeDRCEngine( &compileError );
|
||||
DRC_CONSTRAINT constraint;
|
||||
int clearance = 0;
|
||||
wxString clearanceStr;
|
||||
|
||||
switch( aDRCItem->GetErrorCode() )
|
||||
{
|
||||
case DRCE_EDGE_CLEARANCE:
|
||||
r->Report( "<h7>" + _( "Edge clearance resolution for:" ) + "</h7>" );
|
||||
r = m_inspectClearanceDialog->AddPage( _( "Clearance" ) );
|
||||
reportHeader( _( "Edge clearance resolution for:" ), a, b, r );
|
||||
|
||||
r->Report( wxString::Format( "<ul><li>%s</li><li>%s</li></ul>",
|
||||
EscapeHTML( getItemDescription( a ) ),
|
||||
EscapeHTML( getItemDescription( b ) ) ) );
|
||||
if( compileError )
|
||||
reportCompileError( r );
|
||||
|
||||
reportClearance( EDGE_CLEARANCE_CONSTRAINT, layer, a, b, r );
|
||||
constraint = drcEngine.EvalRules( EDGE_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 ) );
|
||||
break;
|
||||
|
||||
case DRCE_CLEARANCE:
|
||||
|
@ -232,15 +265,18 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
|
|||
layer = B_Cu;
|
||||
}
|
||||
|
||||
r->Report( "<h7>" + _( "Clearance resolution for:" ) + "</h7>" );
|
||||
r = m_inspectClearanceDialog->AddPage( _( "Clearance" ) );
|
||||
reportHeader( _( "Clearance resolution for:" ), a, b, layer, r );
|
||||
|
||||
r->Report( wxString::Format( "<ul><li>%s %s</li><li>%s</li><li>%s</li></ul>",
|
||||
_( "Layer" ),
|
||||
EscapeHTML( m_frame->GetBoard()->GetLayerName( layer ) ),
|
||||
EscapeHTML( getItemDescription( a ) ),
|
||||
EscapeHTML( getItemDescription( b ) ) ) );
|
||||
if( compileError )
|
||||
reportCompileError( r );
|
||||
|
||||
reportClearance( CLEARANCE_CONSTRAINT, layer, a, b, r );
|
||||
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 ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -254,6 +290,22 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
|
|||
}
|
||||
|
||||
|
||||
bool hasHole( BOARD_ITEM* aItem )
|
||||
{
|
||||
PAD* pad = dynamic_cast<PAD*>( aItem );
|
||||
|
||||
if( pad && pad->GetDrillSizeX() > 0 && pad->GetDrillSizeY() > 0 )
|
||||
return true;
|
||||
|
||||
PCB_VIA* via = dynamic_cast<PCB_VIA*>( aItem );
|
||||
|
||||
if( via )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
|
||||
|
@ -309,9 +361,6 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
|
|||
nullptr, this );
|
||||
}
|
||||
|
||||
WX_HTML_REPORT_BOX* r = nullptr;
|
||||
EDA_UNITS units = m_frame->GetUserUnits();
|
||||
|
||||
m_inspectClearanceDialog->DeleteAllPages();
|
||||
|
||||
if( a->Type() != PCB_ZONE_T && b->Type() == PCB_ZONE_T )
|
||||
|
@ -319,6 +368,9 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
|
|||
else if( !a->IsConnected() && b->IsConnected() )
|
||||
std::swap( a, b );
|
||||
|
||||
WX_HTML_REPORT_BOX* r = nullptr;
|
||||
EDA_UNITS units = m_frame->GetUserUnits();
|
||||
|
||||
PCB_LAYER_ID active = m_frame->GetActiveLayer();
|
||||
LSET layerIntersection = a->GetLayerSet() & b->GetLayerSet();
|
||||
LSET copperIntersection = layerIntersection & LSET::AllCuMask();
|
||||
|
@ -329,46 +381,10 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
|
|||
FOOTPRINT* aFP = dynamic_cast<FOOTPRINT*>( a );
|
||||
FOOTPRINT* bFP = dynamic_cast<FOOTPRINT*>( b );
|
||||
|
||||
DRC_ENGINE drcEngine( m_frame->GetBoard(), &m_frame->GetBoard()->GetDesignSettings() );
|
||||
bool compileError = false;
|
||||
DRC_CONSTRAINT constraint;
|
||||
int clearance = 0;
|
||||
|
||||
try
|
||||
{
|
||||
drcEngine.InitEngine( m_frame->GetDesignRulesPath() );
|
||||
}
|
||||
catch( PARSE_ERROR& )
|
||||
{
|
||||
compileError = true;
|
||||
}
|
||||
|
||||
for( ZONE* z : m_frame->GetBoard()->Zones() )
|
||||
z->CacheBoundingBox();
|
||||
|
||||
for( FOOTPRINT* f : m_frame->GetBoard()->Footprints() )
|
||||
{
|
||||
for( ZONE* z : f->Zones() )
|
||||
z->CacheBoundingBox();
|
||||
|
||||
f->BuildPolyCourtyards();
|
||||
}
|
||||
|
||||
auto hasHole =
|
||||
[]( BOARD_ITEM* aItem )
|
||||
{
|
||||
PAD* tmpPad = dynamic_cast<PAD*>( aItem );
|
||||
|
||||
if( tmpPad && tmpPad->GetDrillSizeX() > 0 && tmpPad->GetDrillSizeY() > 0 )
|
||||
return true;
|
||||
|
||||
PCB_VIA* via = dynamic_cast<PCB_VIA*>( aItem );
|
||||
|
||||
if( via )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
};
|
||||
bool compileError = false;
|
||||
DRC_ENGINE drcEngine = makeDRCEngine( &compileError );
|
||||
DRC_CONSTRAINT constraint;
|
||||
int clearance = 0;
|
||||
|
||||
if( copperIntersection.any() && zone && pad && zone->GetNetCode() == pad->GetNetCode() )
|
||||
{
|
||||
|
@ -378,13 +394,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
|
|||
layer = zone->GetLayerSet().Seq().front();
|
||||
|
||||
r = m_inspectClearanceDialog->AddPage( _( "Zone" ) );
|
||||
|
||||
r->Report( "<h7>" + _( "Zone connection resolution for:" ) + "</h7>" );
|
||||
r->Report( wxString::Format( "<ul><li>%s %s</li><li>%s</li><li>%s</li></ul>",
|
||||
_( "Layer" ),
|
||||
EscapeHTML( m_frame->GetBoard()->GetLayerName( layer ) ),
|
||||
EscapeHTML( getItemDescription( a ) ),
|
||||
EscapeHTML( getItemDescription( b ) ) ) );
|
||||
reportHeader( _( "Zone connection resolution for:" ), a, b, layer, r );
|
||||
|
||||
constraint = drcEngine.EvalZoneConnection( pad, zone, layer, r );
|
||||
|
||||
|
@ -451,13 +461,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
|
|||
layer = copperIntersection.Seq().front();
|
||||
|
||||
r = m_inspectClearanceDialog->AddPage( m_frame->GetBoard()->GetLayerName( layer ) );
|
||||
|
||||
r->Report( "<h7>" + _( "Clearance resolution for:" ) + "</h7>" );
|
||||
r->Report( wxString::Format( "<ul><li>%s %s</li><li>%s</li><li>%s</li></ul>",
|
||||
_( "Layer" ),
|
||||
EscapeHTML( m_frame->GetBoard()->GetLayerName( layer ) ),
|
||||
EscapeHTML( getItemDescription( a ) ),
|
||||
EscapeHTML( getItemDescription( b ) ) ) );
|
||||
reportHeader( _( "Clearance resolution for:" ), a, b, layer, r );
|
||||
|
||||
if( ac && bc && ac->GetNetCode() > 0 && ac->GetNetCode() == bc->GetNetCode() )
|
||||
{
|
||||
|
@ -490,13 +494,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
|
|||
|| ( b->IsOnLayer( layer ) && a->IsOnLayer( correspondingMask ) ) )
|
||||
{
|
||||
r = m_inspectClearanceDialog->AddPage( m_frame->GetBoard()->GetLayerName( layer ) );
|
||||
|
||||
r->Report( "<h7>" + _( "Silkscreen clearance resolution for:" ) + "</h7>" );
|
||||
r->Report( wxString::Format( "<ul><li>%s %s</li><li>%s</li><li>%s</li></ul>",
|
||||
_( "Layer" ),
|
||||
EscapeHTML( m_frame->GetBoard()->GetLayerName( layer ) ),
|
||||
EscapeHTML( getItemDescription( a ) ),
|
||||
EscapeHTML( getItemDescription( b ) ) ) );
|
||||
reportHeader( _( "Silkscreen clearance resolution for:" ), a, b, layer, r );
|
||||
|
||||
constraint = drcEngine.EvalRules( SILK_CLEARANCE_CONSTRAINT, a, b, layer, r );
|
||||
clearance = constraint.m_Value.Min();
|
||||
|
@ -520,13 +518,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
|
|||
if( aCourtyard && bCourtyard )
|
||||
{
|
||||
r = m_inspectClearanceDialog->AddPage( m_frame->GetBoard()->GetLayerName( layer ) );
|
||||
|
||||
r->Report( "<h7>" + _( "Courtyard clearance resolution for:" ) + "</h7>" );
|
||||
r->Report( wxString::Format( "<ul><li>%s %s</li><li>%s</li><li>%s</li></ul>",
|
||||
_( "Layer" ),
|
||||
EscapeHTML( m_frame->GetBoard()->GetLayerName( layer ) ),
|
||||
EscapeHTML( getItemDescription( a ) ),
|
||||
EscapeHTML( getItemDescription( b ) ) ) );
|
||||
reportHeader( _( "Courtyard clearance resolution for:" ), a, b, layer, r );
|
||||
|
||||
constraint = drcEngine.EvalRules( COURTYARD_CLEARANCE_CONSTRAINT, a, b, layer, r );
|
||||
clearance = constraint.m_Value.Min();
|
||||
|
@ -558,13 +550,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
|
|||
if( layer >= 0 )
|
||||
{
|
||||
r = m_inspectClearanceDialog->AddPage( _( "Hole" ) );
|
||||
|
||||
r->Report( "<h7>" + _( "Hole clearance resolution for:" ) + "</h7>" );
|
||||
r->Report( wxString::Format( "<ul><li>%s %s</li><li>%s</li><li>%s</li></ul>",
|
||||
_( "Layer" ),
|
||||
EscapeHTML( m_frame->GetBoard()->GetLayerName( layer ) ),
|
||||
EscapeHTML( getItemDescription( a ) ),
|
||||
EscapeHTML( getItemDescription( b ) ) ) );
|
||||
reportHeader( _( "Hole clearance resolution for:" ), a, b, layer, r );
|
||||
|
||||
constraint = drcEngine.EvalRules( HOLE_CLEARANCE_CONSTRAINT, a, b, layer, r );
|
||||
clearance = constraint.m_Value.Min();
|
||||
|
@ -597,13 +583,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
wxString layerName = m_frame->GetBoard()->GetLayerName( edgeLayer );
|
||||
r = m_inspectClearanceDialog->AddPage( layerName + wxS( " " ) + _( "Clearance" ) );
|
||||
|
||||
r->Report( "<h7>" + _( "Edge clearance resolution for:" ) + "</h7>" );
|
||||
r->Report( wxString::Format( "<ul><li>%s %s</li><li>%s</li><li>%s</li></ul>",
|
||||
_( "Layer" ),
|
||||
EscapeHTML( m_frame->GetBoard()->GetLayerName( layer ) ),
|
||||
EscapeHTML( getItemDescription( a ) ),
|
||||
EscapeHTML( getItemDescription( b ) ) ) );
|
||||
reportHeader( _( "Edge clearance resolution for:" ), a, b, layer, r );
|
||||
|
||||
constraint = drcEngine.EvalRules( EDGE_CLEARANCE_CONSTRAINT, a, b, layer, r );
|
||||
clearance = constraint.m_Value.Min();
|
||||
|
@ -619,16 +599,78 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
}
|
||||
|
||||
if( m_inspectClearanceDialog->GetPageCount() == 0 )
|
||||
r = m_inspectClearanceDialog->AddPage( _( "Mechanical" ) );
|
||||
|
||||
if( layerIntersection.any() )
|
||||
{
|
||||
r = m_inspectClearanceDialog->AddPage( _( "Clearance" ) );
|
||||
r->Report( "<h7>" + _( "Items share no relevant layers:" ) + "</h7>" );
|
||||
r->Report( wxString::Format( "<ul><li>%s</li><li>%s</li></ul>",
|
||||
EscapeHTML( getItemDescription( a ) ),
|
||||
EscapeHTML( getItemDescription( b ) ) ) );
|
||||
r->Flush();
|
||||
PCB_LAYER_ID layer = active;
|
||||
|
||||
if( !layerIntersection.test( layer ) )
|
||||
layer = layerIntersection.Seq().front();
|
||||
|
||||
reportHeader( _( "Mechanical clearance resolution for:" ), a, b, layer, r );
|
||||
|
||||
constraint = drcEngine.EvalRules( MECHANICAL_CLEARANCE_CONSTRAINT, a, b, layer, r );
|
||||
clearance = constraint.m_Value.Min();
|
||||
|
||||
if( compileError )
|
||||
{
|
||||
reportCompileError( r );
|
||||
}
|
||||
else 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." ),
|
||||
StringFromValue( units, clearance, true ) ) );
|
||||
}
|
||||
|
||||
r->Report( "" );
|
||||
r->Report( "" );
|
||||
r->Report( "" );
|
||||
}
|
||||
|
||||
if( hasHole( a ) || hasHole( b ) )
|
||||
{
|
||||
PCB_LAYER_ID layer;
|
||||
|
||||
if( hasHole( a ) && b->IsOnLayer( active ) )
|
||||
layer = active;
|
||||
else if( hasHole( b ) && a->IsOnLayer( active ) )
|
||||
layer = active;
|
||||
else if( hasHole( a ) )
|
||||
layer = b->GetLayer();
|
||||
else
|
||||
layer = a->GetLayer();
|
||||
|
||||
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();
|
||||
|
||||
if( compileError )
|
||||
{
|
||||
reportCompileError( r );
|
||||
}
|
||||
else 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." ),
|
||||
StringFromValue( units, clearance, true ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
r->Flush();
|
||||
|
||||
m_inspectClearanceDialog->Raise();
|
||||
m_inspectClearanceDialog->Show( true );
|
||||
return 0;
|
||||
|
@ -688,43 +730,17 @@ int BOARD_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent )
|
|||
m_inspectConstraintsDialog->DeleteAllPages();
|
||||
|
||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.GetItem( 0 ) );
|
||||
DRC_ENGINE drcEngine( m_frame->GetBoard(), &m_frame->GetBoard()->GetDesignSettings() );
|
||||
DRC_CONSTRAINT constraint;
|
||||
bool courtyardError = false;
|
||||
bool compileError = false;
|
||||
|
||||
try
|
||||
{
|
||||
drcEngine.InitEngine( m_frame->GetDesignRulesPath() );
|
||||
}
|
||||
catch( PARSE_ERROR& )
|
||||
{
|
||||
compileError = true;
|
||||
}
|
||||
|
||||
for( ZONE* zone : m_frame->GetBoard()->Zones() )
|
||||
zone->CacheBoundingBox();
|
||||
|
||||
for( FOOTPRINT* footprint : m_frame->GetBoard()->Footprints() )
|
||||
{
|
||||
for( ZONE* zone : footprint->Zones() )
|
||||
zone->CacheBoundingBox();
|
||||
|
||||
footprint->BuildPolyCourtyards();
|
||||
|
||||
if( ( footprint->GetFlags() & MALFORMED_COURTYARDS ) != 0 )
|
||||
courtyardError = true;
|
||||
}
|
||||
bool courtyardError = false;
|
||||
DRC_ENGINE drcEngine = makeDRCEngine( &compileError, &courtyardError );
|
||||
DRC_CONSTRAINT constraint;
|
||||
|
||||
WX_HTML_REPORT_BOX* r = nullptr;
|
||||
|
||||
if( item->Type() == PCB_TRACE_T )
|
||||
{
|
||||
r = m_inspectConstraintsDialog->AddPage( _( "Track Width" ) );
|
||||
|
||||
r->Report( "<h7>" + _( "Track width resolution for:" ) + "</h7>" );
|
||||
r->Report( "<ul><li>" + EscapeHTML( getItemDescription( item ) ) + "</li></ul>" );
|
||||
r->Report( "" );
|
||||
reportHeader( _( "Track width resolution for:" ), item, r );
|
||||
|
||||
constraint = EVAL_RULES( TRACK_WIDTH_CONSTRAINT, item, nullptr, item->GetLayer(), r );
|
||||
|
||||
|
@ -743,10 +759,7 @@ int BOARD_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent )
|
|||
if( item->Type() == PCB_VIA_T )
|
||||
{
|
||||
r = m_inspectConstraintsDialog->AddPage( _( "Via Diameter" ) );
|
||||
|
||||
r->Report( "<h7>" + _( "Via diameter resolution for:" ) + "</h7>" );
|
||||
r->Report( "<ul><li>" + EscapeHTML( getItemDescription( item ) ) + "</li></ul>" );
|
||||
r->Report( "" );
|
||||
reportHeader( _( "Via diameter resolution for:" ), item, r );
|
||||
|
||||
// PADSTACKS TODO: once we have padstacks we'll need to run this per-layer....
|
||||
constraint = EVAL_RULES( VIA_DIAMETER_CONSTRAINT, item, nullptr, UNDEFINED_LAYER, r );
|
||||
|
@ -763,10 +776,7 @@ int BOARD_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent )
|
|||
r->Flush();
|
||||
|
||||
r = m_inspectConstraintsDialog->AddPage( _( "Via Annular Width" ) );
|
||||
|
||||
r->Report( "<h7>" + _( "Via annular width resolution for:" ) + "</h7>" );
|
||||
r->Report( "<ul><li>" + EscapeHTML( getItemDescription( item ) ) + "</li></ul>" );
|
||||
r->Report( "" );
|
||||
reportHeader( _( "Via annular width resolution for:" ), item, r );
|
||||
|
||||
// PADSTACKS TODO: once we have padstacks we'll need to run this per-layer....
|
||||
constraint = EVAL_RULES( ANNULAR_WIDTH_CONSTRAINT, item, nullptr, UNDEFINED_LAYER, r );
|
||||
|
@ -787,10 +797,7 @@ int BOARD_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent )
|
|||
|| item->Type() == PCB_VIA_T )
|
||||
{
|
||||
r = m_inspectConstraintsDialog->AddPage( _( "Hole Size" ) );
|
||||
|
||||
r->Report( "<h7>" + _( "Hole diameter resolution for:" ) + "</h7>" );
|
||||
r->Report( "<ul><li>" + EscapeHTML( getItemDescription( item ) ) + "</li></ul>" );
|
||||
r->Report( "" );
|
||||
reportHeader( _( "Hole diameter resolution for:" ), item, r );
|
||||
|
||||
// PADSTACKS TODO: once we have padstacks we'll need to run this per-layer....
|
||||
constraint = EVAL_RULES( HOLE_SIZE_CONSTRAINT, item, nullptr, UNDEFINED_LAYER, r );
|
||||
|
@ -810,10 +817,7 @@ int BOARD_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
r = m_inspectConstraintsDialog->AddPage( _( "Keepouts" ) );
|
||||
|
||||
r->Report( "<h7>" + _( "Keepout resolution for:" ) + "</h7>" );
|
||||
r->Report( "<ul><li>" + EscapeHTML( getItemDescription( item ) ) + "</li></ul>" );
|
||||
r->Report( "" );
|
||||
reportHeader( _( "Keepout resolution for:" ), item, r );
|
||||
|
||||
constraint = EVAL_RULES( DISALLOW_CONSTRAINT, item, nullptr, item->GetLayer(), r );
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <dialogs/dialog_HTML_reporter_base.h>
|
||||
#include <dialogs/dialog_constraints_reporter.h>
|
||||
#include <drc/drc_rule.h>
|
||||
#include <drc/drc_engine.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <rc_item.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
|
@ -106,7 +107,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
///< Recalculate dynamic ratsnest for the current selection.
|
||||
void calculateSelectionRatsnest( const VECTOR2I& aDelta );
|
||||
|
||||
|
@ -128,24 +128,27 @@ private:
|
|||
void onInspectClearanceDialogClosed( wxCommandEvent& aEvent );
|
||||
void onInspectConstraintsDialogClosed( wxCommandEvent& aEvent );
|
||||
|
||||
void reportZoneConnection( ZONE* aZone, PAD* aPad, REPORTER* r );
|
||||
|
||||
void reportClearance( DRC_CONSTRAINT_T aClearanceType, PCB_LAYER_ID aLayer, BOARD_ITEM* aA,
|
||||
BOARD_ITEM* aB, REPORTER* r );
|
||||
DRC_ENGINE makeDRCEngine( bool* aCompileError, bool* aCourtyardError = nullptr );
|
||||
|
||||
wxString getItemDescription( BOARD_ITEM* aItem );
|
||||
|
||||
void reportCompileError( REPORTER* r );
|
||||
void reportHeader( const wxString& aTitle, BOARD_ITEM* a, REPORTER* r );
|
||||
void reportHeader( const wxString& aTitle, BOARD_ITEM* a, BOARD_ITEM* b, REPORTER* r );
|
||||
void reportHeader( const wxString& aTitle, BOARD_ITEM* a, BOARD_ITEM* b, PCB_LAYER_ID aLayer,
|
||||
REPORTER* r );
|
||||
|
||||
private:
|
||||
PCB_EDIT_FRAME* m_frame; // Pointer to the currently used edit frame.
|
||||
PCB_EDIT_FRAME* m_frame; // Pointer to the currently used edit frame.
|
||||
|
||||
bool m_probingSchToPcb; // Recursion guard when cross-probing to Eeschema
|
||||
std::set<int> m_currentlyHighlighted; // Active net being highlighted, or -1 when off
|
||||
std::set<int> m_lastHighlighted; // Used for toggling between last two highlighted nets
|
||||
bool m_probingSchToPcb; // Recursion guard when cross-probing to Eeschema
|
||||
std::set<int> m_currentlyHighlighted; // Active net being highlighted, or -1 when off
|
||||
std::set<int> m_lastHighlighted; // For toggling between last two highlighted nets
|
||||
|
||||
CONNECTIVITY_DATA* m_dynamicData; // Cached connectivity data from the selection
|
||||
CONNECTIVITY_DATA* m_dynamicData; // Cached connectivity data from the selection
|
||||
|
||||
std::unique_ptr<DIALOG_NET_INSPECTOR> m_listNetsDialog;
|
||||
DIALOG_NET_INSPECTOR::SETTINGS m_listNetsDialogSettings;
|
||||
std::unique_ptr<DIALOG_NET_INSPECTOR> m_listNetsDialog;
|
||||
DIALOG_NET_INSPECTOR::SETTINGS m_listNetsDialogSettings;
|
||||
|
||||
std::unique_ptr<DIALOG_CONSTRAINTS_REPORTER> m_inspectClearanceDialog;
|
||||
std::unique_ptr<DIALOG_CONSTRAINTS_REPORTER> m_inspectConstraintsDialog;
|
||||
|
|
Loading…
Reference in New Issue