Implement Flip action for PADSTACK

Fixes https://gitlab.com/kicad/code/kicad/-/issues/19002
This commit is contained in:
Jon Evans 2024-10-27 11:27:16 -04:00
parent 6cd670de6d
commit 42b5b604e2
3 changed files with 48 additions and 5 deletions

View File

@ -932,11 +932,7 @@ void PAD::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
} ); } );
// flip pads layers // flip pads layers
// PADS items are currently on all copper layers, or m_padStack.FlipLayers( BoardCopperLayerCount() );
// currently, only on Front or Back layers.
// So the copper layers count is not taken in account
LSET layerSet = m_padStack.LayerSet();
SetLayerSet( layerSet.Flip() );
// Flip the basic shapes, in custom pads // Flip the basic shapes, in custom pads
FlipPrimitives( aFlipDirection ); FlipPrimitives( aFlipDirection );

View File

@ -25,6 +25,7 @@
#include <api/api_pcb_utils.h> #include <api/api_pcb_utils.h>
#include <api/board/board_types.pb.h> #include <api/board/board_types.pb.h>
#include <layer_range.h> #include <layer_range.h>
#include <macros.h>
#include <magic_enum.hpp> #include <magic_enum.hpp>
#include <pad.h> #include <pad.h>
#include <pcb_shape.h> #include <pcb_shape.h>
@ -653,6 +654,46 @@ PCB_LAYER_ID PADSTACK::EndLayer() const
} }
void PADSTACK::FlipLayers( int aCopperLayerCount )
{
switch( m_mode )
{
case MODE::NORMAL:
// Same shape on all layers; nothing to do
break;
case MODE::CUSTOM:
{
if( aCopperLayerCount > 2 )
{
int innerCount = ( aCopperLayerCount - 2 );
int halfInnerLayerCount = innerCount / 2;
PCB_LAYER_ID lastInner
= static_cast<PCB_LAYER_ID>( In1_Cu + ( innerCount - 1 ) * 2 );
PCB_LAYER_ID midpointInner
= static_cast<PCB_LAYER_ID>( In1_Cu + ( halfInnerLayerCount - 1 ) * 2 );
for( PCB_LAYER_ID layer : LAYER_RANGE( In1_Cu, midpointInner, MAX_CU_LAYERS ) )
{
auto conjugate =
magic_enum::enum_cast<PCB_LAYER_ID>( lastInner - ( layer - In1_Cu ) );
wxCHECK2_MSG( conjugate.has_value() && m_copperProps.contains( conjugate.value() ),
continue, "Invalid inner layer conjugate!" );
std::swap( m_copperProps[layer], m_copperProps[conjugate.value()] );
}
}
KI_FALLTHROUGH;
}
case MODE::FRONT_INNER_BACK:
std::swap( m_copperProps[F_Cu], m_copperProps[B_Cu] );
std::swap( m_frontMaskProps, m_backMaskProps );
break;
}
}
PADSTACK::SHAPE_PROPS::SHAPE_PROPS() : PADSTACK::SHAPE_PROPS::SHAPE_PROPS() :
shape( PAD_SHAPE::CIRCLE ), shape( PAD_SHAPE::CIRCLE ),
anchor_shape( PAD_SHAPE::CIRCLE ), anchor_shape( PAD_SHAPE::CIRCLE ),

View File

@ -269,6 +269,12 @@ public:
LSET& LayerSet() { return m_layerSet; } LSET& LayerSet() { return m_layerSet; }
void SetLayerSet( const LSET& aSet ) { m_layerSet = aSet; } void SetLayerSet( const LSET& aSet ) { m_layerSet = aSet; }
/**
* Flips the padstack layers in the case that the pad's parent footprint is flipped to the
* other side of the board.
*/
void FlipLayers( int aCopperLayerCount );
PCB_LAYER_ID StartLayer() const; PCB_LAYER_ID StartLayer() const;
PCB_LAYER_ID EndLayer() const; PCB_LAYER_ID EndLayer() const;