7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-03-30 05:06:55 +00:00

An arbitrary layer flip can not be done without the board.

(User-defined layers can be sided or not.)

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20169
This commit is contained in:
Jeff Young 2025-03-05 17:58:51 +00:00
parent 305bb6302b
commit 9856cb2210
10 changed files with 30 additions and 13 deletions

View File

@ -466,7 +466,7 @@ LSEQ LSET::SeqStackupForPlotting() const
}
LSET& LSET::Flip( int aCopperLayersCount )
LSET& LSET::FlipStandardLayers( int aCopperLayersCount )
{
LSET oldMask = *this;
@ -495,6 +495,8 @@ LSET& LSET::Flip( int aCopperLayersCount )
{
if( oldMask.test( pair.first ) )
set( pair.second );
oldMask.set( pair.first, false );
}
if( aCopperLayersCount >= 4 )
@ -511,6 +513,12 @@ LSET& LSET::Flip( int aCopperLayersCount )
}
}
oldMask.ClearCopperLayers();
// Copy across any remaining, non-side-specific layers
for( PCB_LAYER_ID layer : oldMask )
set( layer );
return *this;
}

View File

@ -279,7 +279,7 @@ public:
* @param aCopperLayersCount = the number of copper layers. if 0 (in fact if < 4 )
* internal layers will be not flipped because the layer count is not known
*/
LSET& Flip( int aCopperLayersCount = 0 );
LSET& FlipStandardLayers( int aCopperLayersCount = 0 );
/**
* Return the number of layers between aStart and aEnd, inclusive.

View File

@ -998,8 +998,12 @@ void PAD::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
m_padStack.FlipLayers( copperLayerCount );
// Flip pads layers after padstack geometry
LSET layerSet = m_padStack.LayerSet();
SetLayerSet( layerSet.Flip( copperLayerCount ) );
LSET flipped;
for( PCB_LAYER_ID layer : m_padStack.LayerSet() )
flipped.set( GetBoard()->FlipLayer( layer ) );
SetLayerSet( flipped );
// Flip the basic shapes, in custom pads
FlipPrimitives( aFlipDirection );

View File

@ -3538,7 +3538,7 @@ void ALTIUM_PCB::ConvertPads6ToFootprintItemOnCopper( FOOTPRINT* aFootprint, con
case ALTIUM_LAYER::BOTTOM_LAYER:
pad->SetLayer( B_Cu );
pad->SetLayerSet( PAD::SMDMask().Flip() );
pad->SetLayerSet( PAD::SMDMask().FlipStandardLayers() );
break;
case ALTIUM_LAYER::MULTI_LAYER:

View File

@ -974,7 +974,7 @@ void PCB_IO_EASYEDA_PARSER::ParseToBoardItemContainer(
else if( klayer == B_Cu )
{
pad->SetLayer( B_Cu );
pad->SetLayerSet( PAD::SMDMask().Flip() );
pad->SetLayerSet( PAD::SMDMask().FlipStandardLayers() );
pad->SetAttribute( PAD_ATTRIB::SMD );
}
else if( elayer == wxS( "11" ) )

View File

@ -656,7 +656,7 @@ std::unique_ptr<PAD> PCB_IO_EASYEDAPRO_PARSER::createPAD( FOOTPRINT*
}
else if( klayer == B_Cu )
{
pad->SetLayerSet( PAD::SMDMask().Flip() );
pad->SetLayerSet( PAD::SMDMask().FlipStandardLayers() );
}
pad->SetAttribute( PAD_ATTRIB::SMD );

View File

@ -2797,7 +2797,7 @@ bool FABMASTER::loadFootprints( BOARD* aBoard )
if( pad.top )
newpad->SetLayerSet( PAD::SMDMask() );
else if( pad.bottom )
newpad->SetLayerSet( PAD::SMDMask().Flip() );
newpad->SetLayerSet( PAD::SMDMask().FlipStandardLayers() );
}
}

View File

@ -1040,7 +1040,12 @@ void ZONE::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
std::ranges::copy( m_layerProperties,
std::inserter( layerPropertiesCopy, std::end( layerPropertiesCopy ) ) );
SetLayerSet( GetLayerSet().Flip( GetBoard()->GetCopperLayerCount() ) );
LSET flipped;
for( PCB_LAYER_ID layer : GetLayerSet() )
flipped.set( GetBoard()->FlipLayer( layer ) );
SetLayerSet( flipped );
for( auto& [oldLayer, properties] : layerPropertiesCopy )
{

View File

@ -59,8 +59,8 @@ BOOST_AUTO_TEST_CASE( FlipLset )
LSET front( { F_Cu, In1_Cu, In2_Cu } );
LSET back( { B_Cu, In3_Cu, In4_Cu } );
front.Flip( 6 );
back.Flip( 6 );
front.FlipStandardLayers( 6 );
back.FlipStandardLayers( 6 );
BOOST_TEST( front.compare( LSET { B_Cu, In3_Cu, In4_Cu } ) == 0 );
BOOST_TEST( back.compare( LSET { F_Cu, In1_Cu, In2_Cu } ) == 0 );

View File

@ -124,7 +124,7 @@ BOOST_AUTO_TEST_CASE(LSETManipulations)
BOOST_CHECK_EQUAL(extractedLayer, UNDEFINED_LAYER);
// Test Flip: should swap front and back layers
set.Flip( 4 );
set.FlipStandardLayers( 4 );
BOOST_CHECK(set.Contains(B_Cu));
BOOST_CHECK(set.Contains(In1_Cu)); // Internal layers remain unchanged
@ -132,7 +132,7 @@ BOOST_AUTO_TEST_CASE(LSETManipulations)
set = {F_Cu};
extractedLayer = set.ExtractLayer();
BOOST_CHECK_EQUAL(extractedLayer, F_Cu);
set.Flip();
set.FlipStandardLayers();
extractedLayer = set.ExtractLayer();
BOOST_CHECK_EQUAL(extractedLayer, B_Cu);
}