Don't conclude we're unconnected if only connected to isolated island.
Also adds the layer name to the "thermal connection incomplete" DRC error message. Also improves zone layer description to not say "X and 1 more" (which takes as much room as saying "X and Y"). Fixes https://gitlab.com/kicad/code/kicad/-/issues/15279
This commit is contained in:
parent
457e58d0d5
commit
9e019a1ad1
|
@ -79,6 +79,7 @@ void DRC_TEST_PROVIDER_ZONE_CONNECTIONS::testZoneLayer( ZONE* aZone, PCB_LAYER_I
|
|||
BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
|
||||
std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
|
||||
DRC_CONSTRAINT constraint;
|
||||
wxString msg;
|
||||
|
||||
const std::shared_ptr<SHAPE_POLY_SET>& zoneFill = aZone->GetFilledPolysList( aLayer );
|
||||
ISOLATED_ISLANDS isolatedIslands;
|
||||
|
@ -140,25 +141,28 @@ void DRC_TEST_PROVIDER_ZONE_CONNECTIONS::testZoneLayer( ZONE* aZone, PCB_LAYER_I
|
|||
|
||||
SHAPE_LINE_CHAIN& padOutline = padPoly.Outline( 0 );
|
||||
BOX2I padBBox( item_bbox );
|
||||
std::vector<SHAPE_LINE_CHAIN::INTERSECTION> intersections;
|
||||
int spokes = 0;
|
||||
int ignoredSpokes = 0;
|
||||
|
||||
for( int jj = 0; jj < zoneFill->OutlineCount(); ++jj )
|
||||
{
|
||||
std::vector<SHAPE_LINE_CHAIN::INTERSECTION> intersections;
|
||||
|
||||
zoneFill->Outline( jj ).Intersect( padOutline, intersections, true, &padBBox );
|
||||
|
||||
// If we connect to an island that only connects to a single item then we *are*
|
||||
// that item. Thermal spokes to this (otherwise isolated) island don't provide
|
||||
// electrical connectivity to anything, so we don't count them.
|
||||
if( alg::contains( isolatedIslands.m_SingleConnectionOutlines, jj ) )
|
||||
continue;
|
||||
|
||||
zoneFill->Outline( jj ).Intersect( padOutline, intersections, true, &padBBox );
|
||||
ignoredSpokes += (int) intersections.size() / 2;
|
||||
else
|
||||
spokes += (int) intersections.size() / 2;
|
||||
}
|
||||
|
||||
int spokes = intersections.size() / 2;
|
||||
|
||||
if( spokes <= 0 ) // Not connected at all
|
||||
if( spokes == 0 && ignoredSpokes == 0 ) // Not connected at all
|
||||
continue;
|
||||
|
||||
if( spokes >= minCount ) // We already have enough
|
||||
if( spokes >= minCount ) // We already have enough
|
||||
continue;
|
||||
|
||||
//
|
||||
|
@ -186,7 +190,8 @@ void DRC_TEST_PROVIDER_ZONE_CONNECTIONS::testZoneLayer( ZONE* aZone, PCB_LAYER_I
|
|||
if( spokes < minCount )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_STARVED_THERMAL );
|
||||
wxString msg = wxString::Format( _( "(%s min spoke count %d; actual %d)" ),
|
||||
wxString msg = wxString::Format( _( "(layer %s; %s min spoke count %d; actual %d)" ),
|
||||
board->GetLayerName( aLayer ),
|
||||
constraint.GetName(),
|
||||
minCount,
|
||||
spokes );
|
||||
|
|
|
@ -600,19 +600,33 @@ void ZONE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>&
|
|||
aList.emplace_back( _( "Status" ), _( "Locked" ) );
|
||||
}
|
||||
|
||||
LSEQ layers = m_layerSet.Seq();
|
||||
wxString layerDesc;
|
||||
int count = 0;
|
||||
|
||||
for( PCB_LAYER_ID layer : m_layerSet.Seq() )
|
||||
if( layers.size() == 1 )
|
||||
{
|
||||
if( count == 0 )
|
||||
layerDesc = GetBoard()->GetLayerName( layer );
|
||||
|
||||
count++;
|
||||
layerDesc.Printf( _( "%s" ), GetBoard()->GetLayerName( layers[0] ) );
|
||||
}
|
||||
else if (layers.size() == 2 )
|
||||
{
|
||||
layerDesc.Printf( _( "%s and %s" ),
|
||||
GetBoard()->GetLayerName( layers[0] ),
|
||||
GetBoard()->GetLayerName( layers[1] ) );
|
||||
}
|
||||
else if (layers.size() == 3 )
|
||||
{
|
||||
layerDesc.Printf( _( "%s, %s and %s" ),
|
||||
GetBoard()->GetLayerName( layers[0] ),
|
||||
GetBoard()->GetLayerName( layers[1] ),
|
||||
GetBoard()->GetLayerName( layers[2] ) );
|
||||
}
|
||||
else if( layers.size() > 3 )
|
||||
{
|
||||
layerDesc.Printf( _( "%s, %s and %d more" ),
|
||||
GetBoard()->GetLayerName( layers[0] ),
|
||||
GetBoard()->GetLayerName( layers[1] ),
|
||||
layers.size() - 2 );
|
||||
}
|
||||
|
||||
if( count > 1 )
|
||||
layerDesc.Printf( _( "%s and %d more" ), layerDesc, count - 1 );
|
||||
|
||||
aList.emplace_back( _( "Layer" ), layerDesc );
|
||||
|
||||
|
@ -644,7 +658,7 @@ void ZONE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>&
|
|||
|
||||
if( !m_FilledPolysList.empty() )
|
||||
{
|
||||
count = 0;
|
||||
int count = 0;
|
||||
|
||||
for( std::pair<const PCB_LAYER_ID, std::shared_ptr<SHAPE_POLY_SET>>& ii: m_FilledPolysList )
|
||||
count += ii.second->TotalVertices();
|
||||
|
@ -807,34 +821,48 @@ bool ZONE::AppendCorner( VECTOR2I aPosition, int aHoleIdx, bool aAllowDuplicatio
|
|||
|
||||
wxString ZONE::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
|
||||
{
|
||||
LSEQ layers = m_layerSet.Seq();
|
||||
wxString layerDesc;
|
||||
int count = 0;
|
||||
|
||||
for( PCB_LAYER_ID layer : m_layerSet.Seq() )
|
||||
if( layers.size() == 1 )
|
||||
{
|
||||
if( count == 0 )
|
||||
layerDesc = GetBoard()->GetLayerName( layer );
|
||||
|
||||
count++;
|
||||
layerDesc.Printf( _( "on %s" ), GetBoard()->GetLayerName( layers[0] ) );
|
||||
}
|
||||
else if (layers.size() == 2 )
|
||||
{
|
||||
layerDesc.Printf( _( "on %s and %s" ),
|
||||
GetBoard()->GetLayerName( layers[0] ),
|
||||
GetBoard()->GetLayerName( layers[1] ) );
|
||||
}
|
||||
else if (layers.size() == 3 )
|
||||
{
|
||||
layerDesc.Printf( _( "on %s, %s and %s" ),
|
||||
GetBoard()->GetLayerName( layers[0] ),
|
||||
GetBoard()->GetLayerName( layers[1] ),
|
||||
GetBoard()->GetLayerName( layers[2] ) );
|
||||
}
|
||||
else if( layers.size() > 3 )
|
||||
{
|
||||
layerDesc.Printf( _( "on %s, %s and %d more" ),
|
||||
GetBoard()->GetLayerName( layers[0] ),
|
||||
GetBoard()->GetLayerName( layers[1] ),
|
||||
layers.size() - 2 );
|
||||
}
|
||||
|
||||
if( count > 1 )
|
||||
layerDesc.Printf( _( "%s and %d more" ), layerDesc, count - 1 );
|
||||
|
||||
// Check whether the selected contour is a hole (contour index > 0)
|
||||
if( m_CornerSelection != nullptr && m_CornerSelection->m_contour > 0 )
|
||||
{
|
||||
if( GetIsRuleArea() )
|
||||
return wxString::Format( _( "Rule Area Cutout on %s" ), layerDesc );
|
||||
return wxString::Format( _( "Rule Area Cutout %s" ), layerDesc );
|
||||
else
|
||||
return wxString::Format( _( "Zone Cutout on %s" ), layerDesc );
|
||||
return wxString::Format( _( "Zone Cutout %s" ), layerDesc );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( GetIsRuleArea() )
|
||||
return wxString::Format( _( "Rule Area on %s" ), layerDesc );
|
||||
return wxString::Format( _( "Rule Area %s" ), layerDesc );
|
||||
else
|
||||
return wxString::Format( _( "Zone %s on %s" ), GetNetnameMsg(), layerDesc );
|
||||
return wxString::Format( _( "Zone %s %s" ), GetNetnameMsg(), layerDesc );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue