From 5d0d2201f360cc1adc3b6e14e48617bcbc3e7afb Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Tue, 3 May 2022 00:47:36 +0100 Subject: [PATCH] Improve clearance report messages. Removes some duplicated terms; puts in some more headers to make visual parsing easier, and makes non-connected-pads report the correct data. Also fixes a bug where zone-connection overrides of none weren't getting handled correctly. Fixes https://gitlab.com/kicad/code/kicad/issues/11544 --- pcbnew/drc/drc_engine.cpp | 19 +++++--- pcbnew/tools/board_inspection_tool.cpp | 64 ++++++++++++++++++++++---- pcbnew/zone_filler.cpp | 36 +++++++++++---- 3 files changed, 94 insertions(+), 25 deletions(-) diff --git a/pcbnew/drc/drc_engine.cpp b/pcbnew/drc/drc_engine.cpp index 4050513afd..acacc7720f 100644 --- a/pcbnew/drc/drc_engine.cpp +++ b/pcbnew/drc/drc_engine.cpp @@ -170,8 +170,7 @@ void DRC_ENGINE::loadImplicitRules() holeToHoleConstraint.Value().SetMin( bds.m_HoleToHoleMin ); rule->AddConstraint( holeToHoleConstraint ); - rule = createImplicitRule( _( "default" ) ); - + rule = createImplicitRule( _( "board setup constraints zone fill strategy" ) ); DRC_CONSTRAINT thermalSpokeCountConstraint( MIN_RESOLVED_SPOKES_CONSTRAINT ); thermalSpokeCountConstraint.Value().SetMin( bds.m_MinResolvedSpokes ); rule->AddConstraint( thermalSpokeCountConstraint ); @@ -870,7 +869,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO spoke_override = zone->GetMinThickness(); REPORT( "" ) - REPORT( wxString::Format( _( "Zone %s min thickness: %s." ), + REPORT( wxString::Format( _( "%s min thickness: %s." ), EscapeHTML( zone->GetSelectMenuText( UNITS ) ), EscapeHTML( REPORT_VALUE( spoke_override ) ) ) ) } @@ -943,6 +942,12 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO REPORT_VALUE( c->constraint.m_Value.Opt() ) ) ) break; + case MIN_RESOLVED_SPOKES_CONSTRAINT: + REPORT( wxString::Format( _( "Checking %s min spoke count: %s." ), + EscapeHTML( c->constraint.GetName() ), + MessageTextFromValue( EDA_UNITS::UNSCALED, c->constraint.m_Value.Min() ) ) ) + break; + case ZONE_CONNECTION_CONSTRAINT: REPORT( wxString::Format( _( "Checking %s zone connection: %s." ), EscapeHTML( c->constraint.GetName() ), @@ -1371,7 +1376,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO if( local != ZONE_CONNECTION::INHERITED ) { REPORT( "" ) - REPORT( wxString::Format( _( "Footprint %s zone connection: %s." ), + REPORT( wxString::Format( _( "%s zone connection: %s." ), EscapeHTML( footprint->GetSelectMenuText( UNITS ) ), EscapeHTML( PrintZoneConnection( local ) ) ) ) @@ -1387,7 +1392,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO ZONE_CONNECTION local = zone->GetPadConnection(); REPORT( "" ) - REPORT( wxString::Format( _( "Zone %s pad connection: %s." ), + REPORT( wxString::Format( _( "%s pad connection: %s." ), EscapeHTML( zone->GetSelectMenuText( UNITS ) ), EscapeHTML( PrintZoneConnection( local ) ) ) ) @@ -1404,7 +1409,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO int local = zone->GetThermalReliefGap(); REPORT( "" ) - REPORT( wxString::Format( _( "Zone %s thermal relief gap: %s." ), + REPORT( wxString::Format( _( "%s thermal relief gap: %s." ), EscapeHTML( zone->GetSelectMenuText( UNITS ) ), EscapeHTML( REPORT_VALUE( local ) ) ) ) @@ -1421,7 +1426,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO int local = zone->GetThermalReliefSpokeWidth(); REPORT( "" ) - REPORT( wxString::Format( _( "Zone %s thermal spoke width: %s." ), + REPORT( wxString::Format( _( "%s thermal spoke width: %s." ), EscapeHTML( zone->GetSelectMenuText( UNITS ) ), EscapeHTML( REPORT_VALUE( local ) ) ) ) diff --git a/pcbnew/tools/board_inspection_tool.cpp b/pcbnew/tools/board_inspection_tool.cpp index a2748155c5..91a044a020 100644 --- a/pcbnew/tools/board_inspection_tool.cpp +++ b/pcbnew/tools/board_inspection_tool.cpp @@ -616,19 +616,38 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent ) if( constraint.m_ZoneConnection == ZONE_CONNECTION::THERMAL ) { + r->Report( "" ); + r->Report( "" ); + reportHeader( _( "Thermal relief gap resolution for:" ), a, b, layer, r ); + constraint = drcEngine.EvalRules( THERMAL_RELIEF_GAP_CONSTRAINT, pad, zone, layer, r ); int gap = constraint.m_Value.Min(); + if( compileError ) + reportCompileError( r ); + + r->Report( "" ); r->Report( wxString::Format( _( "Resolved thermal relief gap: %s." ), StringFromValue( units, gap, true ) ) ); + r->Report( "" ); + r->Report( "" ); + reportHeader( _( "Spoke width resolution for:" ), a, b, layer, r ); + constraint = drcEngine.EvalRules( THERMAL_SPOKE_WIDTH_CONSTRAINT, pad, zone, layer, r ); int width = constraint.m_Value.Opt(); + if( compileError ) + reportCompileError( r ); + r->Report( "" ); - r->Report( wxString::Format( _( "Resolved thermal spoke width: %s." ), + r->Report( wxString::Format( _( "Resolved thermal relief spoke width: %s." ), StringFromValue( units, width, true ) ) ); + r->Report( "" ); + r->Report( "" ); + reportHeader( _( "Spoke count resolution for:" ), a, b, layer, r ); + constraint = drcEngine.EvalRules( MIN_RESOLVED_SPOKES_CONSTRAINT, pad, zone, layer, r ); int minSpokes = constraint.m_Value.Min(); @@ -636,46 +655,71 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent ) reportCompileError( r ); r->Report( "" ); - r->Report( wxString::Format( _( "Minimum thermal spoke count: %d." ), + r->Report( wxString::Format( _( "Resolved min thermal relief spoke count: %d." ), minSpokes ) ); std::shared_ptr connectivity = pad->GetBoard()->GetConnectivity(); - - if( !alg::contains( connectivity->GetConnectedItems( pad, { PCB_ZONE_T } ), zone ) ) - r->Report( _( "Items are not connected. No thermal spokes will be generated." ) ); } else if( constraint.m_ZoneConnection == ZONE_CONNECTION::NONE ) { + r->Report( "" ); + r->Report( "" ); + reportHeader( _( "Zone clearance resolution for:" ), a, b, layer, r ); + clearance = zone->GetLocalClearance(); + r->Report( "" ); r->Report( wxString::Format( _( "Zone clearance: %s." ), StringFromValue( units, clearance, true ) ) ); - constraint = drcEngine.EvalRules( THERMAL_RELIEF_GAP_CONSTRAINT, pad, zone, layer, r ); + constraint = drcEngine.EvalRules( MECHANICAL_CLEARANCE_CONSTRAINT, pad, zone, layer, r ); if( constraint.m_Value.Min() > clearance ) { clearance = constraint.m_Value.Min(); - r->Report( wxString::Format( _( "Overridden by larger thermal relief from %s;" + + r->Report( "" ); + r->Report( wxString::Format( _( "Overridden by larger mechanical clearance from %s;" "clearance: %s." ), EscapeHTML( constraint.GetName() ), StringFromValue( units, clearance, true ) ) ); } + if( !pad->FlashLayer( layer ) ) + { + constraint = drcEngine.EvalRules( MECHANICAL_HOLE_CLEARANCE_CONSTRAINT, pad, zone, + layer, r ); + + if( constraint.m_Value.Min() > clearance ) + { + clearance = constraint.m_Value.Min(); + + r->Report( "" ); + r->Report( wxString::Format( _( "Overridden by larger mechanical hole clearance from %s;" + "clearance: %s." ), + EscapeHTML( constraint.GetName() ), + StringFromValue( units, clearance, true ) ) ); + } + } + if( compileError ) reportCompileError( r ); r->Report( "" ); - r->Report( wxString::Format( _( "Clearance: %s." ), - StringFromValue( units, 0, true ) ) ); + r->Report( wxString::Format( _( "Resolved clearance: %s." ), + StringFromValue( units, clearance, true ) ) ); } else { + r->Report( "" ); + r->Report( "" ); + reportHeader( _( "Zone clearance resolution for:" ), a, b, layer, r ); + if( compileError ) reportCompileError( r ); // Report a 0 clearance for solid connections r->Report( "" ); - r->Report( wxString::Format( _( "Clearance: %s." ), + r->Report( wxString::Format( _( "Resolved clearance: %s." ), StringFromValue( units, 0, true ) ) ); } diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp index fd5d66bfc7..e74e7e641b 100644 --- a/pcbnew/zone_filler.cpp +++ b/pcbnew/zone_filler.cpp @@ -560,7 +560,8 @@ void ZONE_FILLER::knockoutThermalReliefs( const ZONE* aZone, PCB_LAYER_ID aLayer BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); ZONE_CONNECTION connection; DRC_CONSTRAINT constraint; - int gap; + int padClearance; + int holeClearance; SHAPE_POLY_SET holes; for( FOOTPRINT* footprint : m_board->Footprints() ) @@ -595,11 +596,31 @@ void ZONE_FILLER::knockoutThermalReliefs( const ZONE* aZone, PCB_LAYER_ID aLayer case ZONE_CONNECTION::THERMAL: constraint = bds.m_DRCEngine->EvalRules( THERMAL_RELIEF_GAP_CONSTRAINT, pad, aZone, aLayer ); - gap = constraint.GetValue().Min(); + padClearance = constraint.GetValue().Min(); + holeClearance = padClearance; + + if( pad->FlashLayer( aLayer ) ) + aThermalConnectionPads.push_back( pad ); + break; case ZONE_CONNECTION::NONE: - gap = aZone->GetLocalClearance(); + constraint = bds.m_DRCEngine->EvalRules( MECHANICAL_CLEARANCE_CONSTRAINT, pad, + aZone, aLayer ); + + if( constraint.GetValue().Min() > aZone->GetLocalClearance() ) + padClearance = constraint.GetValue().Min(); + else + padClearance = aZone->GetLocalClearance(); + + constraint = bds.m_DRCEngine->EvalRules( MECHANICAL_HOLE_CLEARANCE_CONSTRAINT, pad, + aZone, aLayer ); + + if( constraint.GetValue().Min() > padClearance ) + holeClearance = constraint.GetValue().Min(); + else + holeClearance = padClearance; + break; default: @@ -609,17 +630,16 @@ void ZONE_FILLER::knockoutThermalReliefs( const ZONE* aZone, PCB_LAYER_ID aLayer if( pad->FlashLayer( aLayer ) ) { - aThermalConnectionPads.push_back( pad ); - addKnockout( pad, aLayer, gap, holes ); + addKnockout( pad, aLayer, padClearance, holes ); } else if( pad->GetDrillSize().x > 0 ) { // Note: drill size represents finish size, which means the actual holes size // is the plating thickness larger. - if( pad->GetAttribute() == PAD_ATTRIB::PTH ) - gap += pad->GetBoard()->GetDesignSettings().GetHolePlatingThickness(); + holeClearance += pad->GetBoard()->GetDesignSettings().GetHolePlatingThickness(); - pad->TransformHoleWithClearanceToPolygon( holes, gap, m_maxError, ERROR_OUTSIDE ); + pad->TransformHoleWithClearanceToPolygon( holes, holeClearance, m_maxError, + ERROR_OUTSIDE ); } } }