From a52dc5788725822f6e5f45f47d94599187138a48 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Tue, 17 Sep 2019 18:51:27 +0200 Subject: [PATCH] Pcbnew: Fix incorrect footprint angle rotation after flipping around Y axis (left to right) The angle rotation was always negated. But this is incorrect: The angle rotation must be negated when flipping around X axis The angle rotation must be 180 - initial rotation when flipping around Y axis This bug can break position files and footprint updates, especially when mixing flipping around Y axis and flipping around X axis. --- pcbnew/class_module.cpp | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index ebc84270ec..d812a83837 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -997,10 +997,17 @@ void MODULE::Flip( const wxPoint& aCentre, bool aFlipLeftRight ) // Move module to its final position: wxPoint finalPos = m_Pos; - if( aFlipLeftRight ) - MIRROR( finalPos.x, aCentre.x ); /// Mirror the X position - else - MIRROR( finalPos.y, aCentre.y ); /// Mirror the Y position + // Now Flip the footprint. + // Flipping a footprint is a specific transform: + // it is not mirrored like a text. + // We have to change the side, and ensure the footprint rotation is + // modified accordint to the transform, because this parameter is used + // in pick and place files, and when updating the footprint from library. + // When flipped around the X axis (Y coordinates changed) orientation is negated + // When flipped around the Y axis (X coordinates changed) orientation is 180 - old orient. + // Because it is specfic to a footprint, we flip around the X axis, and after rotate 180 deg + + MIRROR( finalPos.y, aCentre.y ); /// Mirror the Y position (around the X axis) SetPosition( finalPos ); @@ -1009,15 +1016,16 @@ void MODULE::Flip( const wxPoint& aCentre, bool aFlipLeftRight ) // Reverse mirror orientation. m_Orient = -m_Orient; + NORMALIZE_ANGLE_POS( m_Orient ); // Mirror pads to other side of board. for( auto pad : m_pads ) - pad->Flip( m_Pos, aFlipLeftRight ); + pad->Flip( m_Pos, false ); // Mirror reference and value. - m_Reference->Flip( m_Pos, aFlipLeftRight ); - m_Value->Flip( m_Pos, aFlipLeftRight ); + m_Reference->Flip( m_Pos, false ); + m_Value->Flip( m_Pos, false ); // Reverse mirror module graphics and texts. for( auto item : m_drawings ) @@ -1025,11 +1033,11 @@ void MODULE::Flip( const wxPoint& aCentre, bool aFlipLeftRight ) switch( item->Type() ) { case PCB_MODULE_EDGE_T: - static_cast( item )->Flip( m_Pos, aFlipLeftRight ); + static_cast( item )->Flip( m_Pos, false ); break; case PCB_MODULE_TEXT_T: - static_cast( item )->Flip( m_Pos, aFlipLeftRight ); + static_cast( item )->Flip( m_Pos, false ); break; default: @@ -1038,6 +1046,10 @@ void MODULE::Flip( const wxPoint& aCentre, bool aFlipLeftRight ) } } + // Now rotate 180 deg if required + if( aFlipLeftRight ) + Rotate( aCentre, 1800.0 ); + CalculateBoundingBox(); }