From c5e7d800a4b68c478103edc7420c38e7c1b83ef6 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Mon, 5 Jun 2023 21:26:11 +0100 Subject: [PATCH] Back out earlier diamond-to-rectangle fix for one that's more targeted. (And doesn't fail qa_pcbnew.) Fixes https://gitlab.com/kicad/code/kicad/-/issues/14828 --- common/eda_shape.cpp | 42 ------------------ .../drc/drc_test_provider_library_parity.cpp | 6 +++ pcbnew/pcb_shape.cpp | 43 +++++++++++++++++++ 3 files changed, 49 insertions(+), 42 deletions(-) diff --git a/common/eda_shape.cpp b/common/eda_shape.cpp index cb9a486194..7a357603df 100644 --- a/common/eda_shape.cpp +++ b/common/eda_shape.cpp @@ -262,18 +262,6 @@ void EDA_SHAPE::scale( double aScale ) void EDA_SHAPE::rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle ) { - auto horizontal = - []( const SEG& seg ) - { - return seg.A.y == seg.B.y; - }; - - auto vertical = - []( const SEG& seg ) - { - return seg.A.x == seg.B.x; - }; - switch( m_shape ) { case SHAPE_T::SEGMENT: @@ -309,36 +297,6 @@ void EDA_SHAPE::rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle ) case SHAPE_T::POLY: m_poly.Rotate( aAngle, aRotCentre ); - - // Convert back to rectangle if appropriate - if( m_poly.OutlineCount() == 1 && m_poly.Outline( 0 ).SegmentCount() == 4 ) - { - SHAPE_LINE_CHAIN& outline = m_poly.Outline( 0 ); - - if( horizontal( outline.Segment( 0 ) ) - && vertical( outline.Segment( 1 ) ) - && horizontal( outline.Segment( 2 ) ) - && vertical( outline.Segment( 3 ) ) ) - { - m_shape = SHAPE_T::RECT; - m_start.x = std::min( outline.Segment( 0 ).A.x, outline.Segment( 0 ).B.x ); - m_start.y = std::min( outline.Segment( 1 ).A.y, outline.Segment( 1 ).B.y ); - m_end.x = std::max( outline.Segment( 0 ).A.x, outline.Segment( 0 ).B.x ); - m_end.y = std::max( outline.Segment( 1 ).A.y, outline.Segment( 1 ).B.y ); - } - else if( vertical( outline.Segment( 0 ) ) - && horizontal( outline.Segment( 1 ) ) - && vertical( outline.Segment( 2 ) ) - && horizontal( outline.Segment( 3 ) ) ) - { - m_shape = SHAPE_T::RECT; - m_start.x = std::min( outline.Segment( 1 ).A.x, outline.Segment( 1 ).B.x ); - m_start.y = std::min( outline.Segment( 0 ).A.y, outline.Segment( 0 ).B.y ); - m_end.x = std::max( outline.Segment( 1 ).A.x, outline.Segment( 1 ).B.x ); - m_end.y = std::max( outline.Segment( 0 ).A.y, outline.Segment( 0 ).B.y ); - } - } - break; case SHAPE_T::BEZIER: diff --git a/pcbnew/drc/drc_test_provider_library_parity.cpp b/pcbnew/drc/drc_test_provider_library_parity.cpp index 5ff73d3b93..bffffab21c 100644 --- a/pcbnew/drc/drc_test_provider_library_parity.cpp +++ b/pcbnew/drc/drc_test_provider_library_parity.cpp @@ -472,6 +472,12 @@ bool FOOTPRINT::FootprintNeedsUpdate( const FOOTPRINT* aLibFootprint, REPORTER* if( GetOrientation() != ANGLE_0 ) temp->SetOrientation( ANGLE_0 ); + for( BOARD_ITEM* item : temp->GraphicalItems() ) + { + if( item->Type() == PCB_SHAPE_T ) + static_cast( item )->NormalizeRect(); + } + diff = temp->FootprintNeedsUpdate( aLibFootprint, aReporter ); // This temporary footprint must not have a parent when it goes out of scope because it must diff --git a/pcbnew/pcb_shape.cpp b/pcbnew/pcb_shape.cpp index 3b7026b8f8..2f9bf15420 100644 --- a/pcbnew/pcb_shape.cpp +++ b/pcbnew/pcb_shape.cpp @@ -181,6 +181,49 @@ void PCB_SHAPE::NormalizeRect() SetStart( rect.GetPosition() ); SetEnd( rect.GetEnd() ); } + else if( m_shape == SHAPE_T::POLY ) + { + auto horizontal = + []( const SEG& seg ) + { + return seg.A.y == seg.B.y; + }; + + auto vertical = + []( const SEG& seg ) + { + return seg.A.x == seg.B.x; + }; + + // Convert a poly back to a rectangle if appropriate + if( m_poly.OutlineCount() == 1 && m_poly.Outline( 0 ).SegmentCount() == 4 ) + { + SHAPE_LINE_CHAIN& outline = m_poly.Outline( 0 ); + + if( horizontal( outline.Segment( 0 ) ) + && vertical( outline.Segment( 1 ) ) + && horizontal( outline.Segment( 2 ) ) + && vertical( outline.Segment( 3 ) ) ) + { + m_shape = SHAPE_T::RECT; + m_start.x = std::min( outline.Segment( 0 ).A.x, outline.Segment( 0 ).B.x ); + m_start.y = std::min( outline.Segment( 1 ).A.y, outline.Segment( 1 ).B.y ); + m_end.x = std::max( outline.Segment( 0 ).A.x, outline.Segment( 0 ).B.x ); + m_end.y = std::max( outline.Segment( 1 ).A.y, outline.Segment( 1 ).B.y ); + } + else if( vertical( outline.Segment( 0 ) ) + && horizontal( outline.Segment( 1 ) ) + && vertical( outline.Segment( 2 ) ) + && horizontal( outline.Segment( 3 ) ) ) + { + m_shape = SHAPE_T::RECT; + m_start.x = std::min( outline.Segment( 1 ).A.x, outline.Segment( 1 ).B.x ); + m_start.y = std::min( outline.Segment( 0 ).A.y, outline.Segment( 0 ).B.y ); + m_end.x = std::max( outline.Segment( 1 ).A.x, outline.Segment( 1 ).B.x ); + m_end.y = std::max( outline.Segment( 0 ).A.y, outline.Segment( 0 ).B.y ); + } + } + } }