From 2013a801d12a739a1eb0e47343dc26ba225b88c1 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Mon, 22 Feb 2021 15:43:31 -0800 Subject: [PATCH] Fix zone merge undo Also remove an implicit zone merge that was happening when the user edited the zone parameters. This appears to have been a feature but it happened without a) telling the user and b) having the option to prevent it. Fixes https://gitlab.com/kicad/code/kicad/issues/7661 --- pcbnew/board.h | 26 ---- pcbnew/edit_zone_helpers.cpp | 194 -------------------------- pcbnew/tools/board_editor_control.cpp | 3 +- 3 files changed, 2 insertions(+), 221 deletions(-) diff --git a/pcbnew/board.h b/pcbnew/board.h index 60947685a1..94fbd87a30 100644 --- a/pcbnew/board.h +++ b/pcbnew/board.h @@ -949,22 +949,6 @@ public: */ bool OnAreaPolygonModified( PICKED_ITEMS_LIST* aModifiedZonesList, ZONE* modified_area ); - /** - * Check all copper areas in net for intersections, combining them if found. - * - * @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful - * in undo commands can be NULL - * @param aNetCode = net to consider - * @return true if some areas modified - */ - bool CombineAllZonesInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode ); - - /** - * Check for intersection of a given copper area with other areas in same net - * @param aZone = area to compare to all other areas in the same net - */ - bool TestZoneIntersections( ZONE* aZone ); - /** * Test for intersection of 2 copper areas * @param aZone1 = area reference @@ -973,16 +957,6 @@ public: */ bool TestZoneIntersection( ZONE* aZone1, ZONE* aZone2 ); - /** - * If possible, combine 2 copper areas - * @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (for undo). - * @param aRefZone = the main area (zone) - * @param aZoneToCombine = the zone that can be merged with aRefZone; will be deleted if the - * combine is successful - * @return : true if aZoneToCombine is combined with aRefZone (and therefore be deleted) - */ - bool CombineZones( PICKED_ITEMS_LIST* aDeletedList, ZONE* aRefZone, ZONE* aZoneToCombine ); - /** * Find a pad \a aPosition on \a aLayer. * diff --git a/pcbnew/edit_zone_helpers.cpp b/pcbnew/edit_zone_helpers.cpp index 482b34fe9b..04a71ae7a1 100644 --- a/pcbnew/edit_zone_helpers.cpp +++ b/pcbnew/edit_zone_helpers.cpp @@ -152,13 +152,6 @@ bool BOARD::OnAreaPolygonModified( PICKED_ITEMS_LIST* aModifiedZonesList, ZONE* // clip polygon against itself bool modified = NormalizeAreaPolygon( aModifiedZonesList, modified_area ); - // now see if we need to clip against other areas - if( TestZoneIntersections( modified_area ) ) - { - modified = true; - CombineAllZonesInNet( aModifiedZonesList, modified_area->GetNetCode() ); - } - // Test for bad areas: all zones must have more than 2 corners: // Note: should not happen, but just in case. for( ZONE* zone : m_zones ) @@ -175,152 +168,6 @@ bool BOARD::OnAreaPolygonModified( PICKED_ITEMS_LIST* aModifiedZonesList, ZONE* } -bool BOARD::CombineAllZonesInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode ) -{ - if( m_zones.size() <= 1 ) - return false; - - bool modified = false; - - for( ZONE* zone : m_zones ) - zone->ClearFlags( STRUCT_DELETED ); - - // Loop through all combinations - for( unsigned ia1 = 0; ia1 < m_zones.size() - 1; ia1++ ) - { - ZONE* refZone = m_zones[ia1]; - - if( refZone->GetNetCode() != aNetCode ) - continue; - - // legal polygon - BOX2I b1 = refZone->Outline()->BBox(); - bool mod_ia1 = false; - - for( unsigned ia2 = m_zones.size() - 1; ia2 > ia1; ia2-- ) - { - ZONE* otherZone = m_zones[ia2]; - - if( otherZone->HasFlag( STRUCT_DELETED ) ) - continue; - - if( otherZone->GetNetCode() != aNetCode ) - continue; - - if( refZone->GetPriority() != otherZone->GetPriority() ) - continue; - - if( refZone->GetIsRuleArea() != otherZone->GetIsRuleArea() ) - continue; - - if( refZone->GetLayerSet() != otherZone->GetLayerSet() ) - continue; - - BOX2I b2 = otherZone->Outline()->BBox(); - - if( b1.Intersects( b2 ) ) - { - // check otherZone against refZone - if( refZone->GetLocalFlags() || otherZone->GetLocalFlags() ) - { - bool ret = TestZoneIntersection( refZone, otherZone ); - - if( ret ) - ret = CombineZones( aDeletedList, refZone, otherZone ); - - if( ret ) - { - mod_ia1 = true; - modified = true; - } - } - } - } - - if( mod_ia1 ) - ia1--; // if modified, we need to check it again - } - - return modified; -} - - -bool BOARD::TestZoneIntersections( ZONE* aZone ) -{ - for( ZONE* otherZone : m_zones ) - { - if( aZone->GetNetCode() != otherZone->GetNetCode() ) - continue; - - if( aZone == otherZone ) - continue; - - // see if areas are on same layers - if( aZone->GetLayerSet() != otherZone->GetLayerSet() ) - continue; - - // test for different priorities - if( aZone->GetPriority() != otherZone->GetPriority() ) - continue; - - // test for different types - if( aZone->GetIsRuleArea() != otherZone->GetIsRuleArea() ) - continue; - - // Keepout area-specific tests - if( aZone->GetIsRuleArea() ) - { - if( aZone->GetDoNotAllowCopperPour() != otherZone->GetDoNotAllowCopperPour() ) - continue; - - if( aZone->GetDoNotAllowTracks() != otherZone->GetDoNotAllowTracks() ) - continue; - - if( aZone->GetDoNotAllowVias() != otherZone->GetDoNotAllowVias() ) - continue; - - if( aZone->GetDoNotAllowPads() != otherZone->GetDoNotAllowPads() ) - continue; - - if( aZone->GetDoNotAllowFootprints() != otherZone->GetDoNotAllowFootprints() ) - continue; - } - // Filled zone specific tests - else - { - if( aZone->GetLocalClearance() != otherZone->GetLocalClearance() ) - continue; - - if( aZone->GetThermalReliefGap() != otherZone->GetThermalReliefGap() ) - continue; - - if( aZone->GetThermalReliefSpokeWidth() != otherZone->GetThermalReliefSpokeWidth() ) - continue; - - if( aZone->GetLocalClearance() != otherZone->GetLocalClearance() ) - continue; - - if( aZone->GetPadConnection() != otherZone->GetPadConnection() ) - continue; - - if( aZone->GetMinThickness() != otherZone->GetMinThickness() ) - continue; - - if( aZone->GetCornerSmoothingType() != otherZone->GetCornerSmoothingType() ) - continue; - - if( aZone->GetCornerRadius() != otherZone->GetCornerRadius() ) - continue; - } - - if( TestZoneIntersection( aZone, otherZone ) ) - return true; - } - - return false; -} - - bool BOARD::TestZoneIntersection( ZONE* aZone1, ZONE* aZone2 ) { // see if areas are on same layer @@ -372,45 +219,4 @@ bool BOARD::TestZoneIntersection( ZONE* aZone1, ZONE* aZone2 ) } -bool BOARD::CombineZones( PICKED_ITEMS_LIST* aDeletedList, ZONE* aRefZone, ZONE* aZoneToCombine ) -{ - if( aRefZone == aZoneToCombine ) - { - wxASSERT( 0 ); - return false; - } - - SHAPE_POLY_SET mergedOutlines = *aRefZone->Outline(); - SHAPE_POLY_SET areaToMergePoly = *aZoneToCombine->Outline(); - - mergedOutlines.BooleanAdd( areaToMergePoly, SHAPE_POLY_SET::PM_FAST ); - mergedOutlines.Simplify( SHAPE_POLY_SET::PM_FAST ); - - // We should have one polygon with hole - // We can have 2 polygons with hole, if the 2 initial polygons have only one common corner - // and therefore cannot be merged (they are dectected as intersecting) - // but we should never have more than 2 polys - if( mergedOutlines.OutlineCount() > 2 ) - { - wxLogMessage( "BOARD::CombineZones error: more than 2 polys after merging" ); - return false; - } - - if( mergedOutlines.OutlineCount() > 1 ) - return false; - - // Update the area with the new merged outline - delete aRefZone->Outline(); - aRefZone->SetOutline( new SHAPE_POLY_SET( mergedOutlines ) ); - - ITEM_PICKER picker( nullptr, aZoneToCombine, UNDO_REDO::DELETED ); - aDeletedList->PushItem( picker ); - aZoneToCombine->SetFlags( STRUCT_DELETED ); - - aRefZone->SetLocalFlags( 1 ); - aRefZone->HatchBorder(); - - return true; -} - diff --git a/pcbnew/tools/board_editor_control.cpp b/pcbnew/tools/board_editor_control.cpp index 9147526e1b..136110119d 100644 --- a/pcbnew/tools/board_editor_control.cpp +++ b/pcbnew/tools/board_editor_control.cpp @@ -1152,6 +1152,8 @@ int BOARD_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent ) static bool mergeZones( BOARD_COMMIT& aCommit, std::vector& aOriginZones, std::vector& aMergedZones ) { + aCommit.Modify( aOriginZones[0] ); + for( unsigned int i = 1; i < aOriginZones.size(); i++ ) { aOriginZones[0]->Outline()->BooleanAdd( *aOriginZones[i]->Outline(), @@ -1175,7 +1177,6 @@ static bool mergeZones( BOARD_COMMIT& aCommit, std::vector& aOriginZones, aCommit.Remove( aOriginZones[i] ); } - aCommit.Modify( aOriginZones[0] ); aMergedZones.push_back( aOriginZones[0] ); aOriginZones[0]->SetLocalFlags( 1 );