From 459cf030b8098bb5d1f780e0cb0fcfd058a738ac Mon Sep 17 00:00:00 2001
From: Jeff Young <jeff@rokeby.ie>
Date: Tue, 11 Mar 2025 18:40:47 +0000
Subject: [PATCH] Don't disable first internal layer in footprint editor.

It's used as a proxy for all internal layers.

Also fixes LAYER_RANGE_ITERATOR so that it works with an odd
number of copper layers.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20246
---
 common/lset.cpp                 | 3 ++-
 include/layer_range.h           | 2 +-
 pcbnew/footprint_edit_frame.cpp | 7 ++++++-
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/common/lset.cpp b/common/lset.cpp
index 923f290551..0c3ebd6b0d 100644
--- a/common/lset.cpp
+++ b/common/lset.cpp
@@ -703,7 +703,8 @@ LSET LSET::SideSpecificMask()
 
 LSET LSET::ForbiddenFootprintLayers()
 {
-    static const LSET saved = InternalCuMask();
+    static LSET saved = InternalCuMask();
+    saved.set( In1_Cu, false );
     return saved;
 }
 
diff --git a/include/layer_range.h b/include/layer_range.h
index f715db7ff6..271b1cc6ac 100644
--- a/include/layer_range.h
+++ b/include/layer_range.h
@@ -82,7 +82,7 @@ private:
             if( start & 1 || stop & 1 )
                 throw std::invalid_argument( "Only works for copper layers" );
 
-            m_layer_count = m_layer_count & ~1;
+            m_layer_count = m_layer_count;
 
             if( stop == B_Cu || m_stop >= m_current )
                 m_reverse = false;
diff --git a/pcbnew/footprint_edit_frame.cpp b/pcbnew/footprint_edit_frame.cpp
index 3f58bd2367..f33d0b87c8 100644
--- a/pcbnew/footprint_edit_frame.cpp
+++ b/pcbnew/footprint_edit_frame.cpp
@@ -181,6 +181,12 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
     // NOTE: KifaceSettings() will return PCBNEW_SETTINGS if we started from pcbnew
     LoadSettings( GetSettings() );
 
+    // Enable one internal layer, because footprints support keepout areas that can be on
+    // internal layers only (therefore on the first internal layer).  This is needed to handle
+    // these keepout in internal layers only.
+    GetBoard()->SetCopperLayerCount( 3 );
+    GetBoard()->SetLayerName( In1_Cu, _( "Inner layers" ) );
+
     float proportion = GetFootprintEditorSettings()->m_AuiPanels.properties_splitter;
     m_propertiesPanel->SetSplitterProportion( proportion );
 
@@ -544,7 +550,6 @@ void FOOTPRINT_EDIT_FRAME::ReloadFootprint( FOOTPRINT* aFootprint )
 
     // Don't drop pre-existing user layers
     LSET enabledLayers = GetBoard()->GetEnabledLayers();
-    enabledLayers.set( In1_Cu );    // we've already done this, but it needs doing again :shrug:
 
     aFootprint->RunOnDescendants(
             [&]( BOARD_ITEM* child )