Implement two-staged zone priority: assigned priority followed by UUID.

This commit is contained in:
Jeff Young 2022-03-01 14:53:35 +00:00
parent 914e706023
commit 843a56c4e4
19 changed files with 86 additions and 65 deletions

View File

@ -882,7 +882,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
continue;
// test for different priorities
if( zoneA->GetPriority() != zoneB->GetPriority() )
if( zoneA->GetAssignedPriority() != zoneB->GetAssignedPriority() )
continue;
// rule areas may overlap at will

View File

@ -260,7 +260,7 @@ bool zonesNeedUpdate( const FP_ZONE* a, const FP_ZONE* b )
TEST( a->GetCornerSmoothingType(), b->GetCornerSmoothingType() );
TEST( a->GetCornerRadius(), b->GetCornerRadius() );
TEST( a->GetZoneName(), b->GetZoneName() );
TEST( a->GetPriority(), b->GetPriority() );
TEST( a->GetAssignedPriority(), b->GetAssignedPriority() );
TEST( a->GetIsRuleArea(), b->GetIsRuleArea() );
TEST( a->GetDoNotAllowCopperPour(), b->GetDoNotAllowCopperPour() );

View File

@ -2310,7 +2310,7 @@ bool FOOTPRINT::cmp_pads::operator()( const PAD* aFirst, const PAD* aSecond ) co
bool FOOTPRINT::cmp_zones::operator()( const FP_ZONE* aFirst, const FP_ZONE* aSecond ) const
{
TEST( aFirst->GetPriority(), aSecond->GetPriority() );
TEST( aFirst->GetAssignedPriority(), aSecond->GetAssignedPriority() );
TEST( aFirst->GetLayerSet().Seq(), aSecond->GetLayerSet().Seq() );
TEST( aFirst->Outline()->TotalVertices(), aSecond->Outline()->TotalVertices() );

View File

@ -562,23 +562,23 @@ void ALTIUM_PCB::Parse( const ALTIUM_COMPOUND_FILE& altiumPcbFi
continue;
// Altium "fills" - not poured in Altium
if( zone->GetPriority() == 1000 )
if( zone->GetAssignedPriority() == 1000 )
{
// Unlikely, but you never know
if( m_highest_pour_index >= 1000 )
zone->SetPriority( m_highest_pour_index + 1 );
zone->SetAssignedPriority( m_highest_pour_index + 1 );
continue;
}
int priority = m_highest_pour_index - zone->GetPriority();
int priority = m_highest_pour_index - zone->GetAssignedPriority();
zone->SetPriority( priority >= 0 ? priority : 0 );
zone->SetAssignedPriority( priority >= 0 ? priority : 0 );
}
// change priority of outer zone to zero
for( std::pair<const ALTIUM_LAYER, ZONE*>& zone : m_outer_plane )
zone.second->SetPriority( 0 );
zone.second->SetAssignedPriority( 0 );
// Altium doesn't appear to store either the dimension value nor the dimensioned object in
// the dimension record. (Yes, there is a REFERENCE0OBJECTID, but it doesn't point to the
@ -1733,7 +1733,7 @@ void ALTIUM_PCB::ParsePolygons6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbF
zone->SetNetCode( GetNetCode( elem.net ) );
zone->SetPosition( elem.vertices.at( 0 ).position );
zone->SetLocked( elem.locked );
zone->SetPriority( elem.pourindex > 0 ? elem.pourindex : 0 );
zone->SetAssignedPriority( elem.pourindex > 0 ? elem.pourindex : 0 );
zone->Outline()->AddOutline( linechain );
HelperSetZoneLayers( zone, elem.layer );
@ -1779,7 +1779,7 @@ void ALTIUM_PCB::ParsePolygons6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbF
if( IsAltiumLayerAPlane( elem.layer ) )
{
// outer zone will be set to priority 0 later.
zone->SetPriority( 1 );
zone->SetAssignedPriority( 1 );
// check if this is the outer zone by simply comparing the BBOX
const auto& outer_plane = m_outer_plane.find( elem.layer );
@ -3340,7 +3340,7 @@ void ALTIUM_PCB::ConvertFills6ToBoardItemWithNet( const AFILL6& aElem )
zone->SetNetCode( GetNetCode( aElem.net ) );
zone->SetPosition( aElem.pos1 );
zone->SetPriority( 1000 );
zone->SetAssignedPriority( 1000 );
HelperSetZoneLayers( zone, aElem.layer );

View File

@ -1827,7 +1827,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadTemplates()
zone->SetZoneName( csTemplate.Name );
zone->SetLayer( getKiCadLayer( csTemplate.LayerID ) );
zone->SetPriority( 1 ); // initially 1, we will increase in calculateZonePriorities
zone->SetAssignedPriority( 1 ); // initially 1, we will increase in calculateZonePriorities
if( !( csTemplate.NetID.IsEmpty() || csTemplate.NetID == wxT( "NONE" ) ) )
zone->SetNet( getKiCadNet( csTemplate.NetID ) );
@ -2009,7 +2009,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadTemplates()
zone->SetFillMode( ZONE_FILL_MODE::POLYGONS );
zone->SetPadConnection( ZONE_CONNECTION::FULL );
zone->SetMinIslandArea( -1 );
zone->SetPriority( 0 ); // Priority always 0 (lowest priority) for implied power planes.
zone->SetAssignedPriority( 0 ); // Priority always 0 (lowest priority) for implied power planes.
zone->SetNet( getKiCadNet( netid ) );
}
}
@ -2152,7 +2152,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadCoppers()
zone->SetIslandRemovalMode( ISLAND_REMOVAL_MODE::NEVER );
zone->SetPadConnection( ZONE_CONNECTION::FULL );
zone->SetNet( getKiCadNet( csCopper.NetRef.NetID ) );
zone->SetPriority( m_zonesMap.size() + 1 ); // Highest priority (always fill first)
zone->SetAssignedPriority( m_zonesMap.size() + 1 ); // Highest priority (always fill first)
SHAPE_POLY_SET fill( *zone->Outline() );
fill.Fracture( SHAPE_POLY_SET::POLYGON_MODE::PM_STRICTLY_SIMPLE );
@ -3832,13 +3832,13 @@ bool CADSTAR_PCB_ARCHIVE_LOADER::calculateZonePriorities( PCB_LAYER_ID& aLayer )
wxASSERT( !isLowerPriority( id, prevID ) );
int newPriority = m_zonesMap.at( prevID )->GetPriority();
int newPriority = m_zonesMap.at( prevID )->GetAssignedPriority();
// Only increase priority of the current zone
if( isLowerPriority( prevID, id ) )
newPriority++;
m_zonesMap.at( id )->SetPriority( newPriority );
m_zonesMap.at( id )->SetAssignedPriority( newPriority );
prevID = id;
}
@ -3849,8 +3849,8 @@ bool CADSTAR_PCB_ARCHIVE_LOADER::calculateZonePriorities( PCB_LAYER_ID& aLayer )
for( const TEMPLATE_ID& losingID : idPair.second )
{
if( m_zonesMap.at( losingID )->GetPriority()
> m_zonesMap.at( winningID )->GetPriority() )
if( m_zonesMap.at( losingID )->GetAssignedPriority()
> m_zonesMap.at( winningID )->GetAssignedPriority() )
{
return false;
}

View File

@ -1530,7 +1530,7 @@ ZONE* EAGLE_PLUGIN::loadPolygon( wxXmlNode* aPolyNode )
}
int rank = p.rank ? (p.max_priority - *p.rank) : p.max_priority;
zone->SetPriority( rank );
zone->SetAssignedPriority( rank );
return zone;
}

View File

@ -2706,7 +2706,7 @@ bool FABMASTER::loadZone( BOARD* aBoard, const std::unique_ptr<FABMASTER::TRACE>
}
else
{
zone->SetPriority( 50 );
zone->SetAssignedPriority( 50 );
}
zone->SetLocalClearance( 0 );
@ -3021,7 +3021,7 @@ bool FABMASTER::orderZones( BOARD* aBoard )
priority = 0;
}
zone->SetPriority( priority );
zone->SetAssignedPriority( priority );
priority += 10;
}

View File

@ -5324,7 +5324,7 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent )
else
zone = std::make_unique<ZONE>( aParent );
zone->SetPriority( 0 );
zone->SetAssignedPriority( 0 );
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
@ -5397,7 +5397,7 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent )
break;
case T_priority:
zone->SetPriority( parseInt( "zone priority" ) );
zone->SetAssignedPriority( parseInt( "zone priority" ) );
NeedRIGHT();
break;

View File

@ -2078,8 +2078,8 @@ void PCB_PLUGIN::format( const ZONE* aZone, int aNestLevel ) const
m_out->Print( 0, " (hatch %s %s)\n", hatch.c_str(),
FormatInternalUnits( aZone->GetBorderHatchPitch() ).c_str() );
if( aZone->GetPriority() > 0 )
m_out->Print( aNestLevel+1, "(priority %d)\n", aZone->GetPriority() );
if( aZone->GetAssignedPriority() > 0 )
m_out->Print( aNestLevel+1, "(priority %d)\n", aZone->GetAssignedPriority() );
m_out->Print( aNestLevel+1, "(connect_pads" );

View File

@ -2520,7 +2520,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
else if( TESTLINE( "ZPriority" ) )
{
int priority = intParse( line + SZ( "ZPriority" ) );
zc->SetPriority( priority );
zc->SetAssignedPriority( priority );
}
else if( TESTLINE( "$POLYSCORNERS" ) )
{

View File

@ -203,7 +203,7 @@ void PCB_POLYGON::AddToBoard()
zone->SetLocalClearance( m_width );
zone->SetPriority( m_priority );
zone->SetAssignedPriority( m_priority );
zone->SetBorderDisplayStyle( ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE,
zone->GetDefaultHatchPitch(), true );

View File

@ -238,7 +238,7 @@ void TEARDROP_MANAGER::setTeardropPriorities()
priority_base = MAGIC_TEARDROP_ZONE_ID;
}
td->SetPriority( priority_base++ );
td->SetAssignedPriority( priority_base++ );
}
}

View File

@ -1440,7 +1440,7 @@ int BOARD_EDITOR_CONTROL::ZoneMerge( const TOOL_EVENT& aEvent )
continue;
}
if( curr_area->GetPriority() != firstZone->GetPriority() )
if( curr_area->GetAssignedPriority() != firstZone->GetAssignedPriority() )
{
wxLogMessage( _( "Some zone priorities did not match and were not merged." ) );
continue;

View File

@ -179,6 +179,21 @@ EDA_ITEM* ZONE::Clone() const
}
bool ZONE::HigherPriority( const ZONE* aOther ) const
{
if( m_priority != aOther->m_priority )
return m_priority > aOther->m_priority;
return m_Uuid > aOther->m_Uuid;
}
bool ZONE::SameNet( const ZONE* aOther ) const
{
return GetNetCode() == aOther->GetNetCode();
}
bool ZONE::UnFill()
{
bool change = false;
@ -549,7 +564,8 @@ void ZONE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>&
}
// Display priority level
aList.emplace_back( _( "Priority" ), wxString::Format( wxT( "%d" ), GetPriority() ) );
aList.emplace_back( _( "Priority" ),
wxString::Format( wxT( "%d" ), GetAssignedPriority() ) );
}
if( aFrame->GetName() == PCB_EDIT_FRAME_NAME )
@ -1337,7 +1353,7 @@ static struct ZONE_DESC
REGISTER_TYPE( ZONE );
propMgr.InheritsAfter( TYPE_HASH( ZONE ), TYPE_HASH( BOARD_CONNECTED_ITEM ) );
propMgr.AddProperty( new PROPERTY<ZONE, unsigned>( _HKI( "Priority" ),
&ZONE::SetPriority, &ZONE::GetPriority ) );
&ZONE::SetAssignedPriority, &ZONE::GetAssignedPriority ) );
//propMgr.AddProperty( new PROPERTY<ZONE, bool>( "Filled",
//&ZONE::SetIsFilled, &ZONE::IsFilled ) );
propMgr.AddProperty( new PROPERTY<ZONE, wxString>( _HKI( "Name" ),

View File

@ -126,12 +126,16 @@ public:
/**
* @param aPriority is the priority level.
*/
void SetPriority( unsigned aPriority ) { m_priority = aPriority; }
void SetAssignedPriority( unsigned aPriority ) { m_priority = aPriority; }
/**
* @return the priority level of this zone.
*/
unsigned GetPriority() const { return m_priority; }
unsigned GetAssignedPriority() const { return m_priority; }
bool HigherPriority( const ZONE* aOther ) const;
bool SameNet( const ZONE* aOther ) const;
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;

View File

@ -106,6 +106,7 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
// Update and cache zone bounding boxes and pad effective shapes so that we don't have to
// make them thread-safe.
//
for( ZONE* zone : m_board->Zones() )
{
zone->CacheBoundingBox();
@ -136,10 +137,11 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
}
// Sort by priority to reduce deferrals waiting on higher priority zones.
//
std::sort( aZones.begin(), aZones.end(),
[]( const ZONE* lhs, const ZONE* rhs )
{
return lhs->GetPriority() > rhs->GetPriority();
return lhs->HigherPriority( rhs );
} );
for( ZONE* zone : aZones )
@ -151,8 +153,8 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
if( m_commit )
m_commit->Modify( zone );
// calculate the hash value for filled areas. it will be used later
// to know if the current filled areas are up to date
// calculate the hash value for filled areas. it will be used later to know if the
// current filled areas are up to date
for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
{
zone->BuildHashValue( layer );
@ -164,8 +166,7 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
islandsList.emplace_back( CN_ZONE_ISOLATED_ISLAND_LIST( zone ) );
// Remove existing fill first to prevent drawing invalid polygons
// on some platforms
// Remove existing fill first to prevent drawing invalid polygons on some platforms
zone->UnFill();
}
@ -191,11 +192,11 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
if( !aOtherZone->GetLayerSet().test( aLayer ) )
return false;
if( aOtherZone->GetPriority() <= aZone->GetPriority() )
if( aZone->HigherPriority( aOtherZone ) )
return false;
// Same-net zones always use outline to produce predictable results
if( aOtherZone->GetNetCode() == aZone->GetNetCode() )
if( aOtherZone->SameNet( aZone ) )
return false;
// A higher priority zone is found: if we intersect and it's not filled yet
@ -255,6 +256,8 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
return num;
};
// Calculate the copper fills (NB: this is multi-threaded)
//
while( !toFill.empty() )
{
size_t parallelThreadCount = std::min( cores, toFill.size() );
@ -263,7 +266,9 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
nextItem = 0;
if( parallelThreadCount <= 1 )
{
fill_lambda( m_progressReporter );
}
else
{
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
@ -292,9 +297,13 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
break;
}
// Triangulate the copper fills (NB: this is multi-threaded)
//
m_board->CacheTriangulation( m_progressReporter, aZones );
// Now update the connectivity to check for copper islands
// Now update the connectivity to check for isolated copper islands
// (NB: FindIsolatedCopperIslands() is multi-threaded)
//
if( m_progressReporter )
{
if( m_progressReporter->IsCancelled() )
@ -321,7 +330,9 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
zone->SetIsFilled( true );
}
// Now remove insulated copper islands
// Now remove isolated copper islands according to the isolated islands strategy assigned
// by the user (always, never, below-certain-size).
//
for( CN_ZONE_ISOLATED_ISLAND_LIST& zone : islandsList )
{
for( PCB_LAYER_ID layer : zone.m_zone->GetLayerSet().Seq() )
@ -363,6 +374,7 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
}
// Now remove islands outside the board edge
//
for( ZONE* zone : aZones )
{
LSET zoneCopperLayers = zone->GetLayerSet() & LSET::AllCuMask( MAX_CU_LAYERS );
@ -751,7 +763,7 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLa
if( !track->IsOnLayer( aLayer ) )
continue;
if( track->GetNetCode() == aZone->GetNetCode() && ( aZone->GetNetCode() != 0) )
if( track->GetNetCode() == aZone->GetNetCode() && ( aZone->GetNetCode() != 0) )
continue;
if( checkForCancel( m_progressReporter ) )
@ -803,8 +815,7 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLa
knockoutGraphicClearance( &footprint->Reference() );
knockoutGraphicClearance( &footprint->Value() );
// Don't knock out holes in zones that share a net
// with a nettie footprint
// Don't knock out holes in zones that share a net with a nettie footprint
if( footprint->IsNetTie() )
{
for( PAD* pad : footprint->Pads() )
@ -879,13 +890,10 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLa
if( otherZone->GetDoNotAllowCopperPour() && !aZone->IsTeardropArea() )
knockoutZoneClearance( otherZone );
}
else
else if( otherZone->HigherPriority( aZone ) )
{
if( otherZone->GetNetCode() != aZone->GetNetCode()
&& otherZone->GetPriority() > aZone->GetPriority() )
{
if( !otherZone->SameNet( aZone ) )
knockoutZoneClearance( otherZone );
}
}
}
@ -901,13 +909,10 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLa
if( otherZone->GetDoNotAllowCopperPour() && !aZone->IsTeardropArea() )
knockoutZoneClearance( otherZone );
}
else
else if( otherZone->HigherPriority( aZone ) )
{
if( otherZone->GetNetCode() != aZone->GetNetCode()
&& otherZone->GetPriority() > aZone->GetPriority() )
{
if( !otherZone->SameNet( aZone ) )
knockoutZoneClearance( otherZone );
}
}
}
}
@ -931,15 +936,12 @@ void ZONE_FILLER::subtractHigherPriorityZones( const ZONE* aZone, PCB_LAYER_ID a
return;
if( aKnockout->GetCachedBoundingBox().Intersects( aZone->GetCachedBoundingBox() ) )
{
aRawFill.BooleanSubtract( *aKnockout->Outline(), SHAPE_POLY_SET::PM_FAST );
}
};
for( ZONE* otherZone : m_board->Zones() )
{
if( otherZone->GetNetCode() == aZone->GetNetCode()
&& otherZone->GetPriority() > aZone->GetPriority() )
if( otherZone->SameNet( aZone ) && otherZone->HigherPriority( aZone ) )
{
// Do not remove teardrop area: it is not useful and not good
if( !otherZone->IsTeardropArea() )
@ -951,8 +953,7 @@ void ZONE_FILLER::subtractHigherPriorityZones( const ZONE* aZone, PCB_LAYER_ID a
{
for( ZONE* otherZone : footprint->Zones() )
{
if( otherZone->GetNetCode() == aZone->GetNetCode()
&& otherZone->GetPriority() > aZone->GetPriority() )
if( otherZone->SameNet( aZone ) && otherZone->HigherPriority( aZone ) )
{
// Do not remove teardrop area: it is not useful and not good
if( !otherZone->IsTeardropArea() )

View File

@ -91,7 +91,7 @@ ZONE_SETTINGS::ZONE_SETTINGS()
ZONE_SETTINGS& ZONE_SETTINGS::operator << ( const ZONE& aSource )
{
m_ZonePriority = aSource.GetPriority();
m_ZonePriority = aSource.GetAssignedPriority();
m_FillMode = aSource.GetFillMode();
m_ZoneClearance = aSource.GetLocalClearance();
m_ZoneMinThickness = aSource.GetMinThickness();
@ -158,7 +158,7 @@ void ZONE_SETTINGS::ExportSetting( ZONE& aTarget, bool aFullExport ) const
if( aFullExport )
{
aTarget.SetPriority( m_ZonePriority );
aTarget.SetAssignedPriority( m_ZonePriority );
aTarget.SetLayerSet( m_Layers );
aTarget.SetZoneName( m_Name );

View File

@ -66,7 +66,7 @@ bool ZONE::IsSame( const ZONE& aZoneToCompare )
if( GetNetCode() != aZoneToCompare.GetNetCode() )
return false;
if( GetPriority() != aZoneToCompare.GetPriority() )
if( GetAssignedPriority() != aZoneToCompare.GetAssignedPriority() )
return false;
// Compare zone specific parameters

View File

@ -353,7 +353,7 @@ void CheckFpZone( const FP_ZONE* expected, const FP_ZONE* zone )
BOOST_CHECK_EQUAL( expected->IsLocked(), zone->IsLocked() );
BOOST_CHECK_EQUAL( expected->GetNetCode(), zone->GetNetCode() );
BOOST_CHECK_EQUAL( expected->GetPriority(), zone->GetPriority() );
BOOST_CHECK_EQUAL( expected->GetAssignedPriority(), zone->GetAssignedPriority() );
CHECK_ENUM_CLASS_EQUAL( expected->GetPadConnection(), zone->GetPadConnection() );
BOOST_CHECK_EQUAL( expected->GetLocalClearance(), zone->GetLocalClearance() );
BOOST_CHECK_EQUAL( expected->GetMinThickness(), zone->GetMinThickness() );