From ea12df80be9fb1055e266c68b8c9340af6408e6c Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Wed, 28 Aug 2024 10:56:14 +0200 Subject: [PATCH] make board area colored (from Ethan Chien) --- common/CMakeLists.txt | 1 + common/layer_id.cpp | 1 + common/settings/builtin_color_themes.h | 2 + common/settings/color_settings.cpp | 1 + include/core/typeinfo.h | 2 + include/layer_ids.h | 1 + pcbnew/board.cpp | 20 +++- pcbnew/board.h | 8 ++ pcbnew/board_bounding_box.cpp | 89 +++++++++++++++++ pcbnew/board_bounding_box.h | 66 +++++++++++++ pcbnew/board_commit.cpp | 18 +++- pcbnew/pcb_board_outline.cpp | 129 +++++++++++++++++++++++++ pcbnew/pcb_board_outline.h | 81 ++++++++++++++++ pcbnew/pcb_draw_panel_gal.cpp | 5 + pcbnew/pcb_painter.cpp | 24 +++++ pcbnew/pcb_painter.h | 2 + pcbnew/undo_redo.cpp | 7 ++ qa/tests/pcbnew/test_board_item.cpp | 2 + 18 files changed, 455 insertions(+), 4 deletions(-) create mode 100644 pcbnew/board_bounding_box.cpp create mode 100644 pcbnew/board_bounding_box.h create mode 100644 pcbnew/pcb_board_outline.cpp create mode 100644 pcbnew/pcb_board_outline.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index e6a8053646..0e7ebdd623 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -865,6 +865,7 @@ set( PCB_COMMON_SRCS ${CMAKE_SOURCE_DIR}/pcbnew/teardrop/teardrop_parameters.cpp ${CMAKE_SOURCE_DIR}/pcbnew/teardrop/teardrop_utils.cpp ${CMAKE_SOURCE_DIR}/pcbnew/zone_settings.cpp + ${CMAKE_SOURCE_DIR}/pcbnew/pcb_board_outline.cpp # IO files ${CMAKE_SOURCE_DIR}/pcbnew/pcb_io/pcb_io.cpp diff --git a/common/layer_id.cpp b/common/layer_id.cpp index 87112c173d..45e47313be 100644 --- a/common/layer_id.cpp +++ b/common/layer_id.cpp @@ -152,6 +152,7 @@ wxString LayerName( int aLayer ) case LAYER_SELECT_OVERLAY: return _( "Selection highlight" ); case LAYER_LOCKED_ITEM_SHADOW: return _( "Locked item shadow" ); case LAYER_CONFLICTS_SHADOW: return _( "Courtyard collision shadow" ); + case LAYER_BOARD_OUTLINE: return _( "Board outline" ); case NETNAMES_LAYER_ID_START: return _( "Track net names" ); case LAYER_PAD_NETNAMES: return _( "Pad net names" ); case LAYER_VIA_NETNAMES: return _( "Via net names" ); diff --git a/common/settings/builtin_color_themes.h b/common/settings/builtin_color_themes.h index c5d0e2c179..1b35214331 100644 --- a/common/settings/builtin_color_themes.h +++ b/common/settings/builtin_color_themes.h @@ -171,6 +171,7 @@ static const std::map s_defaultTheme = { LAYER_VIA_HOLEWALLS, CSS_COLOR( 236, 236, 236, 1 ) }, { LAYER_DRAWINGSHEET, CSS_COLOR( 200, 114, 171, 1 ) }, { LAYER_PAGE_LIMITS, CSS_COLOR( 132, 132, 132, 1 ) }, + { LAYER_BOARD_OUTLINE, CSS_COLOR( 109, 106, 105,1 ) }, { NETNAMES_LAYER_ID_START, CSS_COLOR( 255, 255, 255, 0.7 ) }, { LAYER_PAD_NETNAMES, CSS_COLOR( 255, 255, 255, 0.9 ) }, { LAYER_VIA_NETNAMES, CSS_COLOR( 50, 50, 50, 0.9 ) }, @@ -445,6 +446,7 @@ static const std::map s_classicTheme = { LAYER_VIA_HOLEWALLS, COLOR4D( WHITE ) }, { LAYER_DRAWINGSHEET, COLOR4D( DARKRED ) }, { LAYER_PAGE_LIMITS, COLOR4D( DARKGRAY) }, + { LAYER_BOARD_OUTLINE, CSS_COLOR( 109, 106, 105,1 ) }, { NETNAMES_LAYER_ID_START, CSS_COLOR( 255, 255, 255, 0.7 ) }, { LAYER_PAD_NETNAMES, CSS_COLOR( 255, 255, 255, 0.9 ) }, { LAYER_VIA_NETNAMES, CSS_COLOR( 50, 50, 50, 0.9 ) }, diff --git a/common/settings/color_settings.cpp b/common/settings/color_settings.cpp index b0bc8bfb72..6c5f364520 100644 --- a/common/settings/color_settings.cpp +++ b/common/settings/color_settings.cpp @@ -138,6 +138,7 @@ COLOR_SETTINGS::COLOR_SETTINGS( const wxString& aFilename, bool aAbsolutePath ) CLR( "board.via_hole_walls", LAYER_VIA_HOLEWALLS ); CLR( "board.worksheet", LAYER_DRAWINGSHEET ); CLR( "board.page_limits", LAYER_PAGE_LIMITS ); + CLR( "board.outline", LAYER_BOARD_OUTLINE ); CLR( "board.track_net_names", NETNAMES_LAYER_ID_START ); CLR( "board.pad_net_names", LAYER_PAD_NETNAMES ); CLR( "board.via_net_names", LAYER_VIA_NETNAMES ); diff --git a/include/core/typeinfo.h b/include/core/typeinfo.h index c12c1f1dec..84c5f67ade 100644 --- a/include/core/typeinfo.h +++ b/include/core/typeinfo.h @@ -108,6 +108,7 @@ enum KICAD_T PCB_ITEM_LIST_T, ///< class BOARD_ITEM_LIST, a list of board items PCB_NETINFO_T, ///< class NETINFO_ITEM, a description of a net PCB_GROUP_T, ///< class PCB_GROUP, a set of BOARD_ITEMs + PCB_BOARD_OUTLINE_T, ///< class PCB_BOARD_OUTLINE_T, a pcb board outline item // Be prudent with these types: // they should be used only to locate a specific field type among PCB_FIELD_Ts @@ -470,6 +471,7 @@ constexpr bool IsPcbnewType( const KICAD_T aType ) case PCB_SHAPE_LOCATE_ARC_T: case PCB_SHAPE_LOCATE_POLY_T: case PCB_SHAPE_LOCATE_BEZIER_T: + case PCB_BOARD_OUTLINE_T: return true; default: diff --git a/include/layer_ids.h b/include/layer_ids.h index ae331ecd0f..8d0ec0eba6 100644 --- a/include/layer_ids.h +++ b/include/layer_ids.h @@ -314,6 +314,7 @@ enum GAL_LAYER_ID: int LAYER_DRC_SHAPE1 = GAL_LAYER_ID_START + 42, ///< Custom shape for DRC marker. LAYER_DRC_SHAPE2 = GAL_LAYER_ID_START + 43, ///< Custom shape for DRC marker. + LAYER_BOARD_OUTLINE = GAL_LAYER_ID_START + 44, ///< PCB board outline // Add layers below this point that do not have visibility controls, so don't need explicit // enum values diff --git a/pcbnew/board.cpp b/pcbnew/board.cpp index d11442fe04..3a01725511 100644 --- a/pcbnew/board.cpp +++ b/pcbnew/board.cpp @@ -68,6 +68,7 @@ #include #include #include +#include // This is an odd place for this, but CvPcb won't link if it's in board_item.cpp like I first // tried it. @@ -97,6 +98,7 @@ BOARD::BOARD() : m_DRCMaxClearance = 0; m_DRCMaxPhysicalClearance = 0; + m_boardOutline = new PCB_BOARD_OUTLINE( this ); // we have not loaded a board yet, assume latest until then. m_fileFormatVersionAtLoad = LEGACY_BOARD_FILE_VERSION; @@ -167,6 +169,7 @@ BOARD::~BOARD() for( PCB_GENERATOR* g : m_generators ) ownedItems.insert( g ); + delete m_boardOutline; m_generators.clear(); // Delete the owned items after clearing the containers, because some item dtors @@ -432,8 +435,8 @@ bool BOARD::ResolveTextVar( wxString* token, int aDepth ) const { if( token->Contains( ':' ) ) { - wxString remainder; - wxString ref = token->BeforeFirst( ':', &remainder ); + wxString remainder; + wxString ref = token->BeforeFirst( ':', &remainder ); BOARD_ITEM* refItem = ResolveItem( KIID( ref ), true ); if( refItem && refItem->Type() == PCB_FOOTPRINT_T ) @@ -1598,7 +1601,7 @@ BOARD_ITEM* BOARD::ResolveItem( const KIID& aID, bool aAllowNullptrReturn ) cons if( aAllowNullptrReturn ) return nullptr; else - return DELETED_BOARD_ITEM::GetInstance(); + return DELETED_BOARD_ITEM::GetInstance(); } @@ -3108,3 +3111,14 @@ bool BOARD::operator==( const BOARD_ITEM& aItem ) const return true; } + +void BOARD::UpdateBoardOutline() +{ + SHAPE_POLY_SET outline; + bool has_outline = GetBoardPolygonOutlines( m_boardOutline->GetOutline() ); + + if( !has_outline ) + m_boardOutline->GetOutline().RemoveAllContours(); +} + + diff --git a/pcbnew/board.h b/pcbnew/board.h index 406a2db667..fc2845eed3 100644 --- a/pcbnew/board.h +++ b/pcbnew/board.h @@ -67,6 +67,9 @@ class CONNECTIVITY_DATA; class COMPONENT; class PROJECT; class PROGRESS_REPORTER; +class PCB_BOARD_OUTLINE; + + namespace KIFONT { class OUTLINE_FONT; @@ -360,6 +363,10 @@ public: const GENERATORS& Generators() const { return m_generators; } + PCB_BOARD_OUTLINE* BoardOutline() { return m_boardOutline; } + const PCB_BOARD_OUTLINE* BoardOutline() const { return m_boardOutline; } + void UpdateBoardOutline(); + const MARKERS& Markers() const { return m_markers; } // SWIG requires non-const accessors for some reason to make the custom iterators in board.i @@ -1388,6 +1395,7 @@ private: GROUPS m_groups; ZONES m_zones; GENERATORS m_generators; + PCB_BOARD_OUTLINE* m_boardOutline; // Cache for fast access to items in the containers above by KIID, including children std::unordered_map m_itemByIdCache; diff --git a/pcbnew/board_bounding_box.cpp b/pcbnew/board_bounding_box.cpp new file mode 100644 index 0000000000..ecef0d05b3 --- /dev/null +++ b/pcbnew/board_bounding_box.cpp @@ -0,0 +1,89 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "board_bounding_box.h" + +#include +#include + +BOARD_BOUNDING_BOX::BOARD_BOUNDING_BOX( BOX2I const& aBoundingBox ) : + EDA_ITEM( KICAD_T::PCB_BOUNDING_BOX_T ), + m_boundingBox( std::make_shared( aBoundingBox ) ) +{ + SetFlags( SKIP_STRUCT ); +} + +BOARD_BOUNDING_BOX::BOARD_BOUNDING_BOX( const BOARD_BOUNDING_BOX& aOther ) : + EDA_ITEM( KICAD_T::PCB_BOUNDING_BOX_T ), m_boundingBox( aOther.m_boundingBox ) +{ + SetFlags( SKIP_STRUCT ); +} + +BOARD_BOUNDING_BOX& BOARD_BOUNDING_BOX::operator=( const BOARD_BOUNDING_BOX& aOther ) +{ + m_parent = aOther.m_parent; + m_boundingBox = aOther.m_boundingBox; + return *this; +} + +EDA_ITEM* BOARD_BOUNDING_BOX::Clone() const +{ + return new BOARD_BOUNDING_BOX( *this ); +} + +BOARD_BOUNDING_BOX::~BOARD_BOUNDING_BOX() +{ +} + +const BOX2I BOARD_BOUNDING_BOX::GetBoundingBox() const +{ + return *m_boundingBox; +} + +void BOARD_BOUNDING_BOX::SetBoundingBox( BOX2I const& aBoundingBox ) +{ + m_boundingBox = std::make_shared( aBoundingBox ); +} + +wxString BOARD_BOUNDING_BOX::GetClass() const +{ + return "BOARD_BOUNDING_BOX"; +} + +void BOARD_BOUNDING_BOX::ViewGetLayers( int aLayers[], int& aCount ) const +{ + aCount = 1; + aLayers[0] = LAYER_BOARD_BOUNDING_BOX; +} + +#if defined( DEBUG ) + + +void BOARD_BOUNDING_BOX::Show( int nestLevel, std::ostream& os ) const +{ + NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << m_boundingBox->Format() + << "/>\n"; +} + +#endif diff --git a/pcbnew/board_bounding_box.h b/pcbnew/board_bounding_box.h new file mode 100644 index 0000000000..a89421bf14 --- /dev/null +++ b/pcbnew/board_bounding_box.h @@ -0,0 +1,66 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +#ifndef BOARD_BOUNDING_BOX_H +#define BOARD_BOUNDING_BOX_H + +#include +#include + + +class BOARD_BOUNDING_BOX : public EDA_ITEM +{ +public: + BOARD_BOUNDING_BOX( BOX2I const& aBoundingBox ); + + BOARD_BOUNDING_BOX( const BOARD_BOUNDING_BOX& aOther ); + + BOARD_BOUNDING_BOX& operator=( const BOARD_BOUNDING_BOX& aOther ); + + EDA_ITEM* Clone() const override; + + ~BOARD_BOUNDING_BOX() override; + + const BOX2I GetBoundingBox() const override; + + void SetBoundingBox( BOX2I const& aBoundingBox ); + + wxString GetClass() const override; + + void ViewGetLayers( int aLayers[], int& aCount ) const override; + + +#if defined( DEBUG ) + + void Show( int nestLevel, std::ostream& os ) const override; + +#endif + + +private: + std::shared_ptr m_boundingBox; +}; + +#endif \ No newline at end of file diff --git a/pcbnew/board_commit.cpp b/pcbnew/board_commit.cpp index 60fa412190..c48efdea56 100644 --- a/pcbnew/board_commit.cpp +++ b/pcbnew/board_commit.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -135,7 +136,7 @@ void BOARD_COMMIT::propagateDamage( BOARD_ITEM* aChangedItem, std::vector aStaleZones->push_back( static_cast( aChangedItem ) ); aChangedItem->RunOnChildren( std::bind( &BOARD_COMMIT::propagateDamage, this, _1, aStaleZones, aStaleRuleAreas ), - RECURSE_MODE::NO_RECURSE ); + RECURSE_MODE::NO_RECURSE ); BOARD* board = static_cast( m_toolMgr->GetModel() ); BOX2I damageBBox = aChangedItem->GetBoundingBox(); @@ -189,6 +190,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags ) // Dirty flags and lists bool solderMaskDirty = false; bool autofillZones = false; + bool updateBoardBoundingBox = false; std::vector staleTeardropPadsAndVias; std::set staleTeardropTracks; std::vector staleZonesStorage; @@ -235,6 +237,11 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags ) solderMaskDirty = true; } + if( boardItem->GetLayer() == Edge_Cuts ) + { + updateBoardBoundingBox = true; + } + if( !( aCommitFlags & SKIP_TEARDROPS ) ) { if( boardItem->Type() == PCB_FOOTPRINT_T ) @@ -509,6 +516,15 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags ) frame->HideSolderMask(); } + if( updateBoardBoundingBox && view ) + { + if( PCB_BOARD_OUTLINE* outline = board->BoardOutline() ) + { + board->UpdateBoardOutline(); + view->Update( outline ); + } + } + if( PCBNEW_SETTINGS* cfg = GetAppSettings( "pcbnew" ) ) { if( !staleRuleAreas.empty() && ( cfg->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS diff --git a/pcbnew/pcb_board_outline.cpp b/pcbnew/pcb_board_outline.cpp new file mode 100644 index 0000000000..95b0ac97f3 --- /dev/null +++ b/pcbnew/pcb_board_outline.cpp @@ -0,0 +1,129 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "pcb_board_outline.h" +#include +#include +#include +#include +#include + +void PCB_BOARD_OUTLINE::CopyPros( const PCB_BOARD_OUTLINE& aCopyFrom, PCB_BOARD_OUTLINE& aCopyTo ) +{ + aCopyTo.m_outlines = aCopyFrom.m_outlines; + aCopyTo.m_parent = aCopyFrom.m_parent; +} + + +PCB_BOARD_OUTLINE::PCB_BOARD_OUTLINE( BOARD_ITEM* aParent ) : + BOARD_ITEM( aParent, KICAD_T::PCB_BOARD_OUTLINE_T, Edge_Cuts ) +{ + SetFlags( SKIP_STRUCT ); +} + +PCB_BOARD_OUTLINE::PCB_BOARD_OUTLINE( const PCB_BOARD_OUTLINE& aOther ) : + PCB_BOARD_OUTLINE( aOther.GetParent() ) +{ + CopyPros( aOther, *this ); +} + +PCB_BOARD_OUTLINE& PCB_BOARD_OUTLINE::operator=( const PCB_BOARD_OUTLINE& aOther ) +{ + CopyPros( aOther, *this ); + return *this; +} + +PCB_BOARD_OUTLINE::~PCB_BOARD_OUTLINE() +{ +} + +void PCB_BOARD_OUTLINE::ViewGetLayers( int aLayers[], int& aCount ) const +{ + aCount = 1; + aLayers[0] = LAYER_BOARD_OUTLINE; +} + +const BOX2I PCB_BOARD_OUTLINE::GetBoundingBox() const +{ + return m_outlines.BBox(); +} + +PCB_LAYER_ID PCB_BOARD_OUTLINE::GetLayer() const +{ + return UNDEFINED_LAYER; +} + +LSET PCB_BOARD_OUTLINE::GetLayerSet() const +{ + return {}; +} + +bool PCB_BOARD_OUTLINE::IsOnLayer( PCB_LAYER_ID aLayer ) const +{ + WXUNUSED( aLayer ) + return {}; +} + +double PCB_BOARD_OUTLINE::Similarity( const BOARD_ITEM& aItem ) const +{ + if( const PCB_BOARD_OUTLINE* outline = dynamic_cast( &aItem ) ) + { + if( m_parent == aItem.GetParent() ) + return 1; + + return 0.5; + } + + return {}; +} + +bool PCB_BOARD_OUTLINE::operator==( const BOARD_ITEM& aItem ) const +{ + if( const PCB_BOARD_OUTLINE* outline = dynamic_cast( &aItem ) ) + { + return outline->m_parent == m_parent; + } + + return {}; +} + +EDA_ITEM* PCB_BOARD_OUTLINE::Clone() const +{ + return new PCB_BOARD_OUTLINE( *this ); +} + +wxString PCB_BOARD_OUTLINE::GetClass() const +{ + return "PCB_BOARD_OUTLINE"; +} + + +#if defined( DEBUG ) + +void PCB_BOARD_OUTLINE::Show( int nestLevel, std::ostream& os ) const +{ + NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << wxS( ">\n" ); +} + +#endif diff --git a/pcbnew/pcb_board_outline.h b/pcbnew/pcb_board_outline.h new file mode 100644 index 0000000000..6a3df7acd8 --- /dev/null +++ b/pcbnew/pcb_board_outline.h @@ -0,0 +1,81 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef PCB_BOARD_OUTLINE_H +#define PCB_BOARD_OUTLINE_H + +#include +#include +#include +#include + + +class PCB_BOARD_OUTLINE : public BOARD_ITEM +{ +public: + PCB_BOARD_OUTLINE( BOARD_ITEM* aParent ); + + PCB_BOARD_OUTLINE( const PCB_BOARD_OUTLINE& aOther ); + + PCB_BOARD_OUTLINE& operator=( const PCB_BOARD_OUTLINE& aOther ); + + ~PCB_BOARD_OUTLINE() override; + + const SHAPE_POLY_SET& GetOutline() const { return m_outlines; } + + SHAPE_POLY_SET& GetOutline() { return m_outlines; } + + void ViewGetLayers( int aLayers[], int& aCount ) const override; + + const BOX2I GetBoundingBox() const override; + + PCB_LAYER_ID GetLayer() const override; + + LSET GetLayerSet() const override; + + bool IsOnLayer( PCB_LAYER_ID aLayer ) const override; + + double Similarity( const BOARD_ITEM& aItem ) const override; + + bool operator==( const BOARD_ITEM& aItem ) const override; + + EDA_ITEM* Clone() const override; + + bool HasOutline() const { return !m_outlines.IsEmpty(); } + + static void CopyPros( const PCB_BOARD_OUTLINE& aCopyFrom, PCB_BOARD_OUTLINE& aCopyTo ); + +#if defined( DEBUG ) + + void Show( int nestLevel, std::ostream& os ) const override; + +#endif + + wxString GetClass() const override; + +private: + SHAPE_POLY_SET m_outlines; +}; + +#endif diff --git a/pcbnew/pcb_draw_panel_gal.cpp b/pcbnew/pcb_draw_panel_gal.cpp index 6b2234607c..02401a460d 100644 --- a/pcbnew/pcb_draw_panel_gal.cpp +++ b/pcbnew/pcb_draw_panel_gal.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -436,6 +437,9 @@ void PCB_DRAW_PANEL_GAL::DisplayBoard( BOARD* aBoard, PROGRESS_REPORTER* aReport for( PCB_GENERATOR* generator : aBoard->Generators() ) m_view->Add( generator ); + aBoard->UpdateBoardOutline(); + m_view->Add( aBoard->BoardOutline() ); + // Ratsnest if( !aBoard->IsFootprintHolder() ) { @@ -666,6 +670,7 @@ void PCB_DRAW_PANEL_GAL::SyncLayersVisibility( const BOARD* aBoard ) m_view->SetLayerVisible( LAYER_SELECT_OVERLAY, true ); m_view->SetLayerVisible( LAYER_RATSNEST, true ); m_view->SetLayerVisible( LAYER_MARKER_SHADOWS, true ); + m_view->SetLayerVisible( LAYER_BOARD_OUTLINE, true ); m_view->SetLayerVisible( LAYER_DRC_SHAPE1, true ); m_view->SetLayerVisible( LAYER_DRC_SHAPE2, true ); } diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index e49764b1e3..e73d99fa3f 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -709,6 +710,10 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer ) draw( static_cast( item ), aLayer ); break; + case PCB_BOARD_OUTLINE_T: + draw( static_cast( item ), aLayer ); + break; + default: // Painter does not know how to draw the object return false; @@ -3004,5 +3009,24 @@ void PCB_PAINTER::draw( const PCB_MARKER* aMarker, int aLayer ) } } +void PCB_PAINTER::draw( const PCB_BOARD_OUTLINE* aBoardOutline, int aLayer ) +{ + if( !aBoardOutline->HasOutline() ) + return; + + m_gal->Save(); + m_gal->PushDepth(); + const COLOR4D& outlineColor = m_pcbSettings.GetColor( aBoardOutline, aLayer ); + m_gal->SetFillColor( outlineColor ); + m_gal->AdvanceDepth(); + m_gal->SetLineWidth( 0 ); + m_gal->SetIsFill( true ); + m_gal->SetIsStroke( false ); + m_gal->DrawPolygon( aBoardOutline->GetOutline() ); + m_gal->PopDepth(); + m_gal->Restore(); +} + + const double PCB_RENDER_SETTINGS::MAX_FONT_SIZE = pcbIUScale.mmToIU( 10.0 ); diff --git a/pcbnew/pcb_painter.h b/pcbnew/pcb_painter.h index a6f8bd4f4a..664a2f9129 100644 --- a/pcbnew/pcb_painter.h +++ b/pcbnew/pcb_painter.h @@ -61,6 +61,7 @@ class PCB_MARKER; class NET_SETTINGS; class NETINFO_LIST; class TEXT_ATTRIBUTES; +class PCB_BOARD_OUTLINE; namespace KIFONT { @@ -211,6 +212,7 @@ protected: void draw( const PCB_DIMENSION_BASE* aDimension, int aLayer ); void draw( const PCB_TARGET* aTarget ); void draw( const PCB_MARKER* aMarker, int aLayer ); + void draw( const PCB_BOARD_OUTLINE* aBoardOutline, int aLayer ); /** * Get the thickness to draw for a line (e.g. 0 thickness lines get a minimum value). diff --git a/pcbnew/undo_redo.cpp b/pcbnew/undo_redo.cpp index 4901445e55..e1ddd8b393 100644 --- a/pcbnew/undo_redo.cpp +++ b/pcbnew/undo_redo.cpp @@ -48,6 +48,7 @@ using namespace std::placeholders; #include #include #include +#include /* Functions to undo and redo edit commands. * commands to undo are stored in CurrentScreen->m_UndoList @@ -221,6 +222,8 @@ void PCB_BASE_EDIT_FRAME::RestoreCopyFromUndoList( wxCommandEvent& aEvent ) m_toolManager->ProcessEvent( { TC_MESSAGE, TA_UNDO_REDO_POST, AS_GLOBAL } ); m_toolManager->PostEvent( EVENTS::SelectedItemsModified ); + m_pcb->UpdateBoardOutline(); + GetCanvas()->GetView()->Update( m_pcb->BoardOutline() ); GetCanvas()->Refresh(); } @@ -251,6 +254,8 @@ void PCB_BASE_EDIT_FRAME::RestoreCopyFromRedoList( wxCommandEvent& aEvent ) m_toolManager->ProcessEvent( EVENTS::UndoRedoPostEvent ); m_toolManager->PostEvent( EVENTS::SelectedItemsModified ); + m_pcb->UpdateBoardOutline(); + GetCanvas()->GetView()->Update( m_pcb->BoardOutline() ); GetCanvas()->Refresh(); } @@ -670,5 +675,7 @@ void PCB_BASE_EDIT_FRAME::RollbackFromUndo() ClearListAndDeleteItems( undo ); delete undo; + m_pcb->UpdateBoardOutline(); + GetCanvas()->GetView()->Update( m_pcb->BoardOutline() ); GetCanvas()->Refresh(); } diff --git a/qa/tests/pcbnew/test_board_item.cpp b/qa/tests/pcbnew/test_board_item.cpp index 4d993b12b7..ffc3f32829 100644 --- a/qa/tests/pcbnew/test_board_item.cpp +++ b/qa/tests/pcbnew/test_board_item.cpp @@ -43,6 +43,7 @@ #include #include #include +#include class TEST_BOARD_ITEM_FIXTURE { @@ -137,6 +138,7 @@ public: case PCB_ITEM_LIST_T: case PCB_NETINFO_T: case PCB_GENERATOR_T: + case PCB_BOARD_OUTLINE_T: return nullptr; default: