diff --git a/pcbnew/pad.cpp b/pcbnew/pad.cpp index d50eb76070..46779bd60b 100644 --- a/pcbnew/pad.cpp +++ b/pcbnew/pad.cpp @@ -1422,11 +1422,11 @@ void PAD::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection ) MIRROR( m_pos, aCentre, aFlipDirection ); m_padStack.ForEachUniqueLayer( - [&]( PCB_LAYER_ID aLayer ) - { - MIRROR( m_padStack.Offset( aLayer ), VECTOR2I{ 0, 0 }, aFlipDirection ); - MIRROR( m_padStack.TrapezoidDeltaSize( aLayer ), VECTOR2I{ 0, 0 }, aFlipDirection ); - } ); + [&]( PCB_LAYER_ID aLayer ) + { + MIRROR( m_padStack.Offset( aLayer ), VECTOR2I{ 0, 0 }, aFlipDirection ); + MIRROR( m_padStack.TrapezoidDeltaSize( aLayer ), VECTOR2I{ 0, 0 }, aFlipDirection ); + } ); SetFPRelativeOrientation( -GetFPRelativeOrientation() ); @@ -1446,28 +1446,25 @@ void PAD::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection ) }; Padstack().ForEachUniqueLayer( - [&]( PCB_LAYER_ID aLayer ) - { - if( aFlipDirection == FLIP_DIRECTION::LEFT_RIGHT ) + [&]( PCB_LAYER_ID aLayer ) { - mirrorBitFlags( m_padStack.ChamferPositions( aLayer ), RECT_CHAMFER_TOP_LEFT, - RECT_CHAMFER_TOP_RIGHT ); - mirrorBitFlags( m_padStack.ChamferPositions( aLayer ), RECT_CHAMFER_BOTTOM_LEFT, - RECT_CHAMFER_BOTTOM_RIGHT ); - } - else - { - mirrorBitFlags( m_padStack.ChamferPositions( aLayer ), RECT_CHAMFER_TOP_LEFT, - RECT_CHAMFER_BOTTOM_LEFT ); - mirrorBitFlags( m_padStack.ChamferPositions( aLayer ), RECT_CHAMFER_TOP_RIGHT, - RECT_CHAMFER_BOTTOM_RIGHT ); - } - } ); + if( aFlipDirection == FLIP_DIRECTION::LEFT_RIGHT ) + { + mirrorBitFlags( m_padStack.ChamferPositions( aLayer ), RECT_CHAMFER_TOP_LEFT, + RECT_CHAMFER_TOP_RIGHT ); + mirrorBitFlags( m_padStack.ChamferPositions( aLayer ), RECT_CHAMFER_BOTTOM_LEFT, + RECT_CHAMFER_BOTTOM_RIGHT ); + } + else + { + mirrorBitFlags( m_padStack.ChamferPositions( aLayer ), RECT_CHAMFER_TOP_LEFT, + RECT_CHAMFER_BOTTOM_LEFT ); + mirrorBitFlags( m_padStack.ChamferPositions( aLayer ), RECT_CHAMFER_TOP_RIGHT, + RECT_CHAMFER_BOTTOM_RIGHT ); + } + } ); - // Flip padstack geometry - int copperLayerCount = BoardCopperLayerCount(); - - m_padStack.FlipLayers( copperLayerCount ); + m_padStack.FlipLayers( GetBoard() ); // Flip pads layers after padstack geometry LSET flipped; diff --git a/pcbnew/padstack.cpp b/pcbnew/padstack.cpp index 150197040c..cb12f5b31d 100644 --- a/pcbnew/padstack.cpp +++ b/pcbnew/padstack.cpp @@ -1415,14 +1415,77 @@ bool PADSTACK::HasExplicitDefinitionForLayer( PCB_LAYER_ID aLayer ) const double PADSTACK::Similarity( const PADSTACK& aOther ) const { - // TODO: Implement similarity - return 0.0; + double similarity = 1.0; + + if( m_mode != aOther.m_mode ) + similarity *= 0.9; + + if( m_layerSet != aOther.m_layerSet ) + similarity *= 0.9; + + if( m_customName != aOther.m_customName ) + similarity *= 0.9; + + if( m_orientation != aOther.m_orientation ) + similarity *= 0.9; + + if( m_frontMaskProps != aOther.m_frontMaskProps ) + similarity *= 0.9; + + if( m_backMaskProps != aOther.m_backMaskProps ) + similarity *= 0.9; + + if( m_unconnectedLayerMode != aOther.m_unconnectedLayerMode ) + similarity *= 0.9; + + if( m_customShapeInZoneMode != aOther.m_customShapeInZoneMode ) + similarity *= 0.9; + + if( m_drill != aOther.m_drill ) + similarity *= 0.9; + + if( m_secondaryDrill != aOther.m_secondaryDrill ) + similarity *= 0.9; + + if( m_tertiaryDrill != aOther.m_tertiaryDrill ) + similarity *= 0.9; + + if( m_frontPostMachining != aOther.m_frontPostMachining ) + similarity *= 0.9; + + if( m_backPostMachining != aOther.m_backPostMachining ) + similarity *= 0.9; + + ForEachUniqueLayer( + [&]( PCB_LAYER_ID aLayer ) + { + similarity *= CopperLayer( aLayer ).Similarity( aOther.CopperLayer( aLayer ) ); + } ); + + return similarity; } -void PADSTACK::FlipLayers( int aLayerCount ) +void PADSTACK::FlipLayers( BOARD* aBoard ) { - // TODO: Implement FlipLayers + std::unordered_map oldCopperProps = m_copperProps; + m_copperProps.clear(); + + for( const auto& [layer, props] : oldCopperProps ) + m_copperProps[aBoard->FlipLayer( layer )] = props; + + std::swap( m_frontMaskProps, m_backMaskProps ); + + m_drill.start = aBoard->FlipLayer( m_drill.start ); + m_drill.end = aBoard->FlipLayer( m_drill.end ); + + m_secondaryDrill.start = aBoard->FlipLayer( m_secondaryDrill.start ); + m_secondaryDrill.end = aBoard->FlipLayer( m_secondaryDrill.end ); + + m_tertiaryDrill.start = aBoard->FlipLayer( m_tertiaryDrill.start ); + m_tertiaryDrill.end = aBoard->FlipLayer( m_tertiaryDrill.end ); + + std::swap( m_frontPostMachining, m_backPostMachining ); } @@ -1511,6 +1574,35 @@ bool PADSTACK::COPPER_LAYER_PROPS::operator==( const COPPER_LAYER_PROPS& aOther } +double PADSTACK::COPPER_LAYER_PROPS::Similarity( const PADSTACK::COPPER_LAYER_PROPS& aOther ) const +{ + double similarity = 1.0; + + if( shape != aOther.shape ) + similarity *= 0.5; + + if( zone_connection != aOther.zone_connection ) + similarity *= 0.9; + + if( thermal_spoke_width != aOther.thermal_spoke_width ) + similarity *= 0.9; + + if( thermal_spoke_angle != aOther.thermal_spoke_angle ) + similarity *= 0.9; + + if( thermal_gap != aOther.thermal_gap ) + similarity *= 0.9; + + if( clearance != aOther.clearance ) + similarity *= 0.9; + + if( custom_shapes != aOther.custom_shapes ) + similarity *= 0.5; + + return similarity; +} + + #define TEST_OPT( a, b, v ) \ { \ if( a.has_value() != b.has_value() ) \ diff --git a/pcbnew/padstack.h b/pcbnew/padstack.h index f1374fab4a..8b19c1d6d8 100644 --- a/pcbnew/padstack.h +++ b/pcbnew/padstack.h @@ -240,6 +240,8 @@ public: bool operator==( const COPPER_LAYER_PROPS& aOther ) const; int Compare( const COPPER_LAYER_PROPS& aOther ) const; + + double Similarity( const COPPER_LAYER_PROPS& aOther ) const; }; ///! The features of a padstack that can vary on outer layers. @@ -325,7 +327,7 @@ public: * 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 ); + void FlipLayers( BOARD* aBoard ); PCB_LAYER_ID StartLayer() const; PCB_LAYER_ID EndLayer() const;