Error messages for zone merging.

Also fixes a bug where zones meeting at a point would get merged
resulting in a self-intersecting zone.

Also fixes a bug where undo would not be handled correctly when zones
could not be merged.

Fixes https://gitlab.com/kicad/code/kicad/issues/10466

(cherry picked from commit d5a2059c21)
This commit is contained in:
Jeff Young 2022-01-21 19:54:54 +00:00
parent b8b9f646c6
commit fd4ac7c5df
3 changed files with 30 additions and 15 deletions

View File

@ -83,7 +83,7 @@ void POLYGON_GEOM_MANAGER::SetLeaderMode( LEADER_MODE aMode )
bool POLYGON_GEOM_MANAGER::IsSelfIntersecting( bool aIncludeLeaderPts ) const bool POLYGON_GEOM_MANAGER::IsSelfIntersecting( bool aIncludeLeaderPts ) const
{ {
auto pts( m_lockedPoints ); SHAPE_LINE_CHAIN pts( m_lockedPoints );
if( aIncludeLeaderPts ) if( aIncludeLeaderPts )
{ {

View File

@ -726,12 +726,11 @@ void PCB_EDIT_FRAME::setupUIConditions()
ENABLE( SELECTION_CONDITIONS::OnlyType( PCB_FOOTPRINT_T ) ) ); ENABLE( SELECTION_CONDITIONS::OnlyType( PCB_FOOTPRINT_T ) ) );
SELECTION_CONDITION singleZoneCond = SELECTION_CONDITIONS::Count( 1 ) && SELECTION_CONDITION singleZoneCond = SELECTION_CONDITIONS::Count( 1 )
SELECTION_CONDITIONS::OnlyTypes( GENERAL_COLLECTOR::Zones ); && SELECTION_CONDITIONS::OnlyTypes( GENERAL_COLLECTOR::Zones );
SELECTION_CONDITION zoneMergeCond = SELECTION_CONDITIONS::MoreThan( 1 ) && SELECTION_CONDITION zoneMergeCond = SELECTION_CONDITIONS::MoreThan( 1 )
PCB_SELECTION_CONDITIONS::SameNet( true ) && && SELECTION_CONDITIONS::OnlyTypes( GENERAL_COLLECTOR::Zones );
PCB_SELECTION_CONDITIONS::SameLayer();
mgr->SetConditions( PCB_ACTIONS::zoneDuplicate, ENABLE( singleZoneCond ) ); mgr->SetConditions( PCB_ACTIONS::zoneDuplicate, ENABLE( singleZoneCond ) );
mgr->SetConditions( PCB_ACTIONS::drawZoneCutout, ENABLE( singleZoneCond ) ); mgr->SetConditions( PCB_ACTIONS::drawZoneCutout, ENABLE( singleZoneCond ) );

View File

@ -1371,8 +1371,8 @@ int BOARD_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent )
} }
static bool mergeZones( BOARD_COMMIT& aCommit, std::vector<ZONE*>& aOriginZones, static bool mergeZones( EDA_DRAW_FRAME* aFrame, BOARD_COMMIT& aCommit,
std::vector<ZONE*>& aMergedZones ) std::vector<ZONE*>& aOriginZones, std::vector<ZONE*>& aMergedZones )
{ {
aCommit.Modify( aOriginZones[0] ); aCommit.Modify( aOriginZones[0] );
@ -1384,13 +1384,14 @@ static bool mergeZones( BOARD_COMMIT& aCommit, std::vector<ZONE*>& aOriginZones,
aOriginZones[0]->Outline()->Simplify( SHAPE_POLY_SET::PM_FAST ); aOriginZones[0]->Outline()->Simplify( SHAPE_POLY_SET::PM_FAST );
// We should have one polygon with hole // We should have one polygon, possibly with holes. If we end up with two polygons (either
// We can have 2 polygons with hole, if the 2 initial polygons have only one common corner // because the intersection was a single point or because the intersection was within one of
// and therefore cannot be merged (they are detected as intersecting) // the zone's holes) then we can't merge.
// but we should never have more than 2 polys if( aOriginZones[0]->Outline()->IsSelfIntersecting()
if( aOriginZones[0]->Outline()->OutlineCount() > 1 ) || aOriginZones[0]->Outline()->OutlineCount() > 1 )
{ {
wxLogMessage( "BOARD::mergeZones error: more than 2 polys after merging" ); DisplayErrorMessage( aFrame, _( "Zones have insufficient overlap for merging." ) );
aCommit.Revert();
return false; return false;
} }
@ -1434,26 +1435,41 @@ int BOARD_EDITOR_CONTROL::ZoneMerge( const TOOL_EVENT& aEvent )
netcode = curr_area->GetNetCode(); netcode = curr_area->GetNetCode();
if( firstZone->GetNetCode() != netcode ) if( firstZone->GetNetCode() != netcode )
{
wxLogMessage( _( "Some zone netcodes did not match and were not merged." ) );
continue; continue;
}
if( curr_area->GetPriority() != firstZone->GetPriority() ) if( curr_area->GetPriority() != firstZone->GetPriority() )
{
wxLogMessage( _( "Some zone priorities did not match and were not merged." ) );
continue; continue;
}
if( curr_area->GetIsRuleArea() != firstZone->GetIsRuleArea() ) if( curr_area->GetIsRuleArea() != firstZone->GetIsRuleArea() )
{
wxLogMessage( _( "Some zones were rule areas and were not merged." ) );
continue; continue;
}
if( curr_area->GetLayer() != firstZone->GetLayer() ) if( curr_area->GetLayer() != firstZone->GetLayer() )
{
wxLogMessage( _( "Some zone layer sets did not match and were not merged." ) );
continue; continue;
}
if( !board->TestZoneIntersection( curr_area, firstZone ) ) if( !board->TestZoneIntersection( curr_area, firstZone ) )
{
wxLogMessage( _( "Some zones did not intersect and were not merged." ) );
continue; continue;
}
toMerge.push_back( curr_area ); toMerge.push_back( curr_area );
} }
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
if( mergeZones( commit, toMerge, merged ) ) if( mergeZones( m_frame, commit, toMerge, merged ) )
{ {
commit.Push( wxT( "Merge zones" ) ); commit.Push( wxT( "Merge zones" ) );