From a5b53a623d46da85c054815a48a46772cccb95b5 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Thu, 21 May 2020 18:42:42 +0100 Subject: [PATCH] Update status bar with clearance & rule sources. --- include/class_board_item.h | 8 + pcbnew/board_connected_item.cpp | 6 +- pcbnew/class_board_item.cpp | 33 +++ pcbnew/class_pad.cpp | 198 ++++--------- pcbnew/class_track.cpp | 306 +++++++++++--------- pcbnew/class_track.h | 17 +- pcbnew/class_zone.cpp | 88 +++--- pcbnew/drc/drc.cpp | 14 +- pcbnew/drc/drc_clearance_test_functions.cpp | 35 +-- 9 files changed, 335 insertions(+), 370 deletions(-) diff --git a/include/class_board_item.h b/include/class_board_item.h index 0a3c5979c1..48e814e91d 100644 --- a/include/class_board_item.h +++ b/include/class_board_item.h @@ -300,6 +300,14 @@ public: */ virtual void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, int aClearanceValue, int aError = ARC_LOW_DEF, bool ignoreLineWidth = false ) const; + +protected: + /** + * Helper function + * Return a string (to be shown to the user) describing a layer mask. + * The BOARD is needed because layer names are (somewhat) customizable + */ + static wxString LayerMaskDescribe( const BOARD* aBoard, LSET aMask ); }; #endif /* BOARD_ITEM_STRUCT_H */ diff --git a/pcbnew/board_connected_item.cpp b/pcbnew/board_connected_item.cpp index 635fa00f68..9975f3b4ad 100644 --- a/pcbnew/board_connected_item.cpp +++ b/pcbnew/board_connected_item.cpp @@ -117,7 +117,7 @@ int BOARD_CONNECTED_ITEM::GetClearance( BOARD_ITEM* aItem, wxString* aSource ) c clearance = myClearance; if( aSource ) - *aSource = wxString::Format( _( "'%s' netclass clearance" ), myNetclass->GetName() ); + *aSource = wxString::Format( _( "'%s' netclass" ), myNetclass->GetName() ); } } @@ -130,7 +130,7 @@ int BOARD_CONNECTED_ITEM::GetClearance( BOARD_ITEM* aItem, wxString* aSource ) c clearance = itemClearance; if( aSource ) - *aSource = wxString::Format( _( "'%s' netclass clearance" ), itemNetclass->GetName() ); + *aSource = wxString::Format( _( "'%s' netclass" ), itemNetclass->GetName() ); } } @@ -143,7 +143,7 @@ int BOARD_CONNECTED_ITEM::GetClearance( BOARD_ITEM* aItem, wxString* aSource ) c clearance = edgeClearance; if( aSource ) - *aSource = _( "board edge clearance" ); + *aSource = _( "board edge" ); } } diff --git a/pcbnew/class_board_item.cpp b/pcbnew/class_board_item.cpp index 316d64cc66..fb9a9ae951 100644 --- a/pcbnew/class_board_item.cpp +++ b/pcbnew/class_board_item.cpp @@ -77,6 +77,39 @@ wxString BOARD_ITEM::GetLayerName() const } +wxString BOARD_ITEM::LayerMaskDescribe( const BOARD* aBoard, LSET aMask ) +{ + // Try to be smart and useful. Check all copper first. + if( aMask[F_Cu] && aMask[B_Cu] ) + return _( "All copper layers" ); + + // Check for copper. + auto layer = aBoard->GetEnabledLayers().AllCuMask() & aMask; + + for( int i = 0; i < 2; i++ ) + { + for( int bit = PCBNEW_LAYER_ID_START; bit < PCB_LAYER_ID_COUNT; ++bit ) + { + if( layer[ bit ] ) + { + wxString layerInfo = aBoard->GetLayerName( static_cast( bit ) ); + + if( aMask.count() > 1 ) + layerInfo << _( " and others" ); + + return layerInfo; + } + } + + // No copper; check for technicals. + layer = aBoard->GetEnabledLayers().AllTechMask() & aMask; + } + + // No copper, no technicals: no layer + return _( "no layers" ); +} + + void BOARD_ITEM::ViewGetLayers( int aLayers[], int& aCount ) const { // Basic fallback diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index c29a01434a..aaa8b58501 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -47,16 +47,6 @@ #include -/** - * Helper function - * Return a string (to be shown to the user) describing a layer mask. - * Useful for showing where is a pad. - * The BOARD is needed because layer names are (somewhat) customizable - */ -static wxString LayerMaskDescribe( const BOARD* aBoard, LSET aMask ); - -int D_PAD::m_PadSketchModePenSize = 0; // Pen size used to draw pads in sketch mode - D_PAD::D_PAD( MODULE* parent ) : BOARD_CONNECTED_ITEM( parent, PCB_PAD_T ) { @@ -633,7 +623,7 @@ int D_PAD::GetClearance( BOARD_ITEM* aItem, wxString* aSource ) const clearance = m_LocalClearance; if( aSource ) - *aSource = wxString::Format( _( "pad %s clearance" ), GetName() ); + *aSource = wxString::Format( _( "pad %s" ), GetName() ); } // A footprint can have a specific clearance value @@ -642,7 +632,7 @@ int D_PAD::GetClearance( BOARD_ITEM* aItem, wxString* aSource ) const clearance = GetParent()->GetLocalClearance(); if( aSource ) - *aSource = wxString::Format( _( "%s footprint clearance" ), GetParent()->GetReference() ); + *aSource = wxString::Format( _( "%s footprint" ), GetParent()->GetReference() ); } // Otherwise use the baseclass method to fetch the netclass and/or rule setting @@ -933,28 +923,32 @@ void D_PAD::BuildPadPolygon( wxPoint aCoord[4], wxSize aInflateValue, void D_PAD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) { - MODULE* module; - wxString msg; - BOARD* board; - - module = (MODULE*) m_Parent; + EDA_UNITS units = aFrame->GetUserUnits(); + wxString msg, msg2; + BOARD* board = GetBoard(); + BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings(); + MODULE* module = (MODULE*) m_Parent; if( module ) - { aList.emplace_back( _( "Footprint" ), module->GetReference(), DARKCYAN ); - } aList.emplace_back( _( "Pad" ), m_name, BROWN ); if( !GetPinFunction().IsEmpty() ) - aList.emplace_back( _( "Pin fct" ), GetPinFunction(), BROWN ); + aList.emplace_back( _( "Pin Name" ), GetPinFunction(), BROWN ); aList.emplace_back( _( "Net" ), UnescapeString( GetNetname() ), DARKCYAN ); - board = GetBoard(); + // Display the netclass name (a pad having a netcode = 0 (no net) use the + // default netclass for clearance): + if( m_netinfo->GetNet() <= 0 ) + msg = bds.GetDefault()->GetName(); + else + msg = GetNetClassName(); - aList.emplace_back( _( "Layer" ), - LayerMaskDescribe( board, m_layerMask ), DARKGREEN ); + aList.emplace_back( _( "NetClass" ), msg, CYAN ); + + aList.emplace_back( _( "Layer" ), LayerMaskDescribe( board, m_layerMask ), DARKGREEN ); // Show the pad shape, attribute and property wxString props = ShowPadAttr(); @@ -975,13 +969,28 @@ void D_PAD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector aList.emplace_back( ShowPadShape(), props, DARKGREEN ); - msg = MessageTextFromValue( aFrame->GetUserUnits(), m_Size.x, true ); - aList.emplace_back( _( "Width" ), msg, RED ); + if( (GetShape() == PAD_SHAPE_CIRCLE || GetShape() == PAD_SHAPE_OVAL ) + && m_Size.x == m_Size.y ) + { + msg = MessageTextFromValue( units, m_Size.x, true ); + aList.emplace_back( _( "Diameter" ), msg, RED ); + } + else + { + msg = MessageTextFromValue( units, m_Size.x, true ); + aList.emplace_back( _( "Width" ), msg, RED ); - msg = MessageTextFromValue( aFrame->GetUserUnits(), m_Size.y, true ); - aList.emplace_back( _( "Height" ), msg, RED ); + msg = MessageTextFromValue( units, m_Size.y, true ); + aList.emplace_back( _( "Height" ), msg, RED ); + } - msg = MessageTextFromValue( aFrame->GetUserUnits(), m_Drill.x, true ); + if( GetPadToDieLength() ) + { + msg = MessageTextFromValue(units, GetPadToDieLength(), true ); + aList.emplace_back( _( "Length in Package" ), msg, CYAN ); + } + + msg = MessageTextFromValue( units, m_Drill.x, true ); if( GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE ) { @@ -989,46 +998,18 @@ void D_PAD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector } else { - msg = MessageTextFromValue( aFrame->GetUserUnits(), m_Drill.x, true ) + msg = MessageTextFromValue( units, m_Drill.x, true ) + wxT( "/" ) - + MessageTextFromValue( aFrame->GetUserUnits(), m_Drill.y, true ); + + MessageTextFromValue( units, m_Drill.y, true ); aList.emplace_back( _( "Drill X / Y" ), msg, RED ); } - double module_orient_degrees = module ? module->GetOrientationDegrees() : 0; + wxString source; + int clearance = GetClearance( nullptr, &source ); - if( module_orient_degrees != 0.0 ) - msg.Printf( wxT( "%3.1f(+%3.1f)" ), - GetOrientationDegrees() - module_orient_degrees, - module_orient_degrees ); - else - msg.Printf( wxT( "%3.1f" ), GetOrientationDegrees() ); - - aList.emplace_back( _( "Angle" ), msg, LIGHTBLUE ); - - msg = MessageTextFromValue( aFrame->GetUserUnits(), m_Pos.x ) - + wxT( ", " ) - + MessageTextFromValue( aFrame->GetUserUnits(), m_Pos.y ); - aList.emplace_back( _( "Position" ), msg, LIGHTBLUE ); - - if( GetPadToDieLength() ) - { - msg = MessageTextFromValue( aFrame->GetUserUnits(), GetPadToDieLength(), true ); - aList.emplace_back( _( "Length in package" ), msg, CYAN ); - } - - // Display the actual pad clearance: - msg = MessageTextFromValue( aFrame->GetUserUnits(), GetClearance(), true ); - aList.emplace_back( _( "Pad clearance" ), msg, CYAN ); - - // Display the netclass name (a pad having a netcode = 0 (no net) use the - // default netclass for clearance): - if( m_netinfo->GetNet() <= 0 ) - msg = GetBoard()->GetDesignSettings().GetDefault()->GetName(); - else - msg = GetNetClassName(); - - aList.emplace_back( _( "Net class" ), msg, CYAN ); + msg.Printf( _( "Min Clearance: %s" ), MessageTextFromValue( units, clearance, true ) ); + msg2.Printf( _( "Source: %s" ), source ); + aList.emplace_back( msg, msg2, BLACK ); } @@ -1245,9 +1226,7 @@ bool D_PAD::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) con // Test rectangular portion between rounded ends if( arect.Intersects( shapeRect, m_Orient ) ) - { return true; - } break; @@ -1278,19 +1257,13 @@ bool D_PAD::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) con for( int ii=0; ii<4; ii++ ) { if( TestPointInsidePolygon( poly, 4, corners[ii] ) ) - { return true; - } if( arect.Contains( poly[ii] ) ) - { return true; - } if( arect.Intersects( poly[ii], poly[(ii+1) % 4] ) ) - { return true; - } } return false; @@ -1427,29 +1400,14 @@ wxString D_PAD::ShowPadShape() const { switch( GetShape() ) { - case PAD_SHAPE_CIRCLE: - return _( "Circle" ); - - case PAD_SHAPE_OVAL: - return _( "Oval" ); - - case PAD_SHAPE_RECT: - return _( "Rect" ); - - case PAD_SHAPE_TRAPEZOID: - return _( "Trap" ); - - case PAD_SHAPE_ROUNDRECT: - return _( "Roundrect" ); - - case PAD_SHAPE_CHAMFERED_RECT: - return _( "Chamferedrect" ); - - case PAD_SHAPE_CUSTOM: - return _( "CustomShape" ); - - default: - return wxT( "???" ); + case PAD_SHAPE_CIRCLE: return _( "Circle" ); + case PAD_SHAPE_OVAL: return _( "Oval" ); + case PAD_SHAPE_RECT: return _( "Rect" ); + case PAD_SHAPE_TRAPEZOID: return _( "Trap" ); + case PAD_SHAPE_ROUNDRECT: return _( "Roundrect" ); + case PAD_SHAPE_CHAMFERED_RECT: return _( "Chamferedrect" ); + case PAD_SHAPE_CUSTOM: return _( "CustomShape" ); + default: return wxT( "???" ); } } @@ -1458,20 +1416,11 @@ wxString D_PAD::ShowPadAttr() const { switch( GetAttribute() ) { - case PAD_ATTRIB_STANDARD: - return _( "Std" ); - - case PAD_ATTRIB_SMD: - return _( "SMD" ); - - case PAD_ATTRIB_CONN: - return _( "Conn" ); - - case PAD_ATTRIB_HOLE_NOT_PLATED: - return _( "Not Plated" ); - - default: - return wxT( "???" ); + case PAD_ATTRIB_STANDARD: return _( "Std" ); + case PAD_ATTRIB_SMD: return _( "SMD" ); + case PAD_ATTRIB_CONN: return _( "Conn" ); + case PAD_ATTRIB_HOLE_NOT_PLATED: return _( "Not Plated" ); + default: return wxT( "???" ); } } @@ -1650,39 +1599,6 @@ const BOX2I D_PAD::ViewBBox() const } -wxString LayerMaskDescribe( const BOARD *aBoard, LSET aMask ) -{ - // Try to be smart and useful. Check all copper first. - if( aMask[F_Cu] && aMask[B_Cu] ) - return _( "All copper layers" ); - - // Check for copper. - auto layer = aBoard->GetEnabledLayers().AllCuMask() & aMask; - - for( int i = 0; i < 2; i++ ) - { - for( int bit = PCBNEW_LAYER_ID_START; bit < PCB_LAYER_ID_COUNT; ++bit ) - { - if( layer[ bit ] ) - { - wxString layerInfo = aBoard->GetLayerName( static_cast( bit ) ); - - if( aMask.count() > 1 ) - layerInfo << _( " and others" ); - - return layerInfo; - } - } - - // No copper; check for technicals. - layer = aBoard->GetEnabledLayers().AllTechMask() & aMask; - } - - // No copper, no technicals: no layer - return _( "no layers" ); -} - - void D_PAD::ImportSettingsFrom( const D_PAD& aMasterPad ) { SetShape( aMasterPad.GetShape() ); diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 18f7fda9eb..8ee2e6498a 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -125,6 +125,78 @@ int TRACK::GetClearance( BOARD_ITEM* aItem, wxString* aSource ) const } +int TRACK::GetMinWidth( wxString* aSource ) const +{ + BOARD_DESIGN_SETTINGS& bds = GetBoard()->GetDesignSettings(); + NETCLASS* netclass = nullptr; + std::vector matched; + + // NB: we must check the net first, as when it is 0 GetNetClass() will return the + // orphaned net netclass, not the default netclass. + if( m_netinfo->GetNet() == 0 ) + netclass = bds.GetDefault(); + else + netclass = GetNetClass(); + + MatchSelectors( bds.m_DRCRuleSelectors, this, netclass, nullptr, nullptr, &matched ); + + int minWidth = bds.m_TrackMinWidth; + + if( aSource ) + *aSource = _( "board" ); + + for( DRC_SELECTOR* selector : matched ) + { + if( selector->m_Rule->m_TrackWidth > minWidth ) + { + minWidth = selector->m_Rule->m_TrackWidth; + + if( aSource ) + *aSource = wxString::Format( _( "'%s' rule" ), selector->m_Rule->m_Name ); + } + } + + return minWidth; +} + + +int VIA::GetMinAnnulus( wxString* aSource ) const +{ + BOARD_DESIGN_SETTINGS& bds = GetBoard()->GetDesignSettings(); + NETCLASS* netclass = nullptr; + std::vector matched; + + // NB: we must check the net first, as when it is 0 GetNetClass() will return the + // orphaned net netclass, not the default netclass. + if( m_netinfo->GetNet() == 0 ) + netclass = bds.GetDefault(); + else + netclass = GetNetClass(); + + MatchSelectors( bds.m_DRCRuleSelectors, this, netclass, nullptr, nullptr, &matched ); + + int minAnnulus = bds.m_ViasMinAnnulus; + + if( aSource ) + *aSource = _( "board" ); + + MatchSelectors( bds.m_DRCRuleSelectors, this, netclass, nullptr, nullptr, &matched ); + + for( DRC_SELECTOR* selector : matched ) + { + if( selector->m_Rule->m_AnnulusWidth > minAnnulus ) + { + minAnnulus = selector->m_Rule->m_AnnulusWidth; + + if( aSource ) + *aSource = wxString::Format( _( "'%s' rule" ), selector->m_Rule->m_Name ); + } + } + + return minAnnulus; +} + + int VIA::GetDrillValue() const { if( m_Drill > 0 ) // Use the specific value. @@ -512,11 +584,27 @@ unsigned int VIA::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const // see class_track.h void TRACK::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) { - wxString msg; - BOARD* board = GetBoard(); + EDA_UNITS units = aFrame->GetUserUnits(); + wxString msg; + wxString msg2; + wxString source; + BOARD* board = GetBoard(); // Display basic infos - GetMsgPanelInfoBase( aFrame, aList ); + aList.emplace_back( _( "Type" ), _( "Track" ), DARKCYAN ); + + GetMsgPanelInfoBase_Common( aFrame, aList ); + + // Display layer + if( board ) + msg = board->GetLayerName( m_Layer ); + else + msg.Printf(wxT("%d"), m_Layer ); + + // Display width + msg = MessageTextFromValue( aFrame->GetUserUnits(), m_Width, true ); + + aList.emplace_back( _( "Width" ), msg, DARKCYAN ); // Display full track length (in Pcbnew) if( board ) @@ -532,135 +620,40 @@ void TRACK::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector if( lenPadToDie != 0 ) { - msg = MessageTextFromValue( aFrame->GetUserUnits(), trackLen + lenPadToDie ); - aList.emplace_back( _( "Full Length" ), msg, DARKCYAN ); - msg = MessageTextFromValue( aFrame->GetUserUnits(), lenPadToDie, true ); aList.emplace_back( _( "Pad To Die Length" ), msg, DARKCYAN ); + + msg = MessageTextFromValue( aFrame->GetUserUnits(), trackLen + lenPadToDie ); + aList.emplace_back( _( "Full Length" ), msg, DARKCYAN ); } } - NETCLASS* netclass = GetNetClass(); + int clearance = GetClearance( nullptr, &source ); - if( netclass ) - { - aList.emplace_back( _( "NC Name" ), netclass->GetName(), DARKMAGENTA ); + msg.Printf( _( "Min Clearance: %s" ), MessageTextFromValue( units, clearance, true ) ); + msg2.Printf( _( "Source: %s" ), source ); + aList.emplace_back( msg, msg2, BLACK ); - msg = MessageTextFromValue( aFrame->GetUserUnits(), netclass->GetClearance(), true ); - aList.emplace_back( _( "NC Clearance" ), msg, DARKMAGENTA ); + int minWidth = GetMinWidth( &source ); - msg = MessageTextFromValue( aFrame->GetUserUnits(), netclass->GetTrackWidth(), true ); - aList.emplace_back( _( "NC Width" ), msg, DARKMAGENTA ); - - msg = MessageTextFromValue( aFrame->GetUserUnits(), netclass->GetViaDiameter(), true ); - aList.emplace_back( _( "NC Via Size" ), msg, DARKMAGENTA ); - - msg = MessageTextFromValue( aFrame->GetUserUnits(), netclass->GetViaDrill(), true ); - aList.emplace_back( _( "NC Via Drill"), msg, DARKMAGENTA ); - } -} - -void TRACK::GetMsgPanelInfoBase_Common( EDA_DRAW_FRAME* aFrame, std::vector& aList ) -{ - wxString msg; - - // Display Net Name - if( GetBoard() ) - { - NETINFO_ITEM* net = GetNet(); - - if( net ) - msg = UnescapeString( net->GetNetname() ); - else - msg = wxT( "" ); - - aList.emplace_back( _( "NetName" ), msg, RED ); - - // Display net code : (useful in test or debug) - msg.Printf( wxT( "%d" ), GetNetCode() ); - aList.emplace_back( _( "NetCode" ), msg, RED ); - } - -#if defined(DEBUG) - - // Display the flags - msg.Printf( wxT( "0x%08X" ), m_Flags ); - aList.emplace_back( wxT( "Flags" ), msg, BLUE ); - -#if 0 - // Display start and end pointers: - msg.Printf( wxT( "%p" ), start ); - aList.push_back( MSG_PANEL_ITEM( wxT( "start ptr" ), msg, BLUE ) ); - msg.Printf( wxT( "%p" ), end ); - aList.push_back( MSG_PANEL_ITEM( wxT( "end ptr" ), msg, BLUE ) ); - // Display this ptr - msg.Printf( wxT( "%p" ), this ); - aList.push_back( MSG_PANEL_ITEM( wxT( "this" ), msg, BLUE ) ); -#endif - -#if 0 - // Display start and end positions: - msg.Printf( wxT( "%d %d" ), m_Start.x, m_Start.y ); - aList.push_back( MSG_PANEL_ITEM( wxT( "Start pos" ), msg, BLUE ) ); - msg.Printf( wxT( "%d %d" ), m_End.x, m_End.y ); - aList.push_back( MSG_PANEL_ITEM( wxT( "End pos" ), msg, BLUE ) ); -#endif - -#endif // defined(DEBUG) - - // Display the State member - msg = wxT( ". . " ); - - if( GetState( TRACK_LOCKED ) ) - msg[0] = 'L'; - - if( GetState( TRACK_AR ) ) - msg[2] = 'A'; - - aList.emplace_back( _( "Status" ), msg, MAGENTA ); + msg.Printf( _( "Min Width: %s" ), MessageTextFromValue( units, minWidth, true ) ); + msg2.Printf( _( "Source: %s" ), source ); + aList.emplace_back( msg, msg2, BLACK ); } -void TRACK::GetMsgPanelInfoBase( EDA_DRAW_FRAME* aFrame, std::vector& aList ) +void VIA::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) { - wxString msg; - BOARD* board = GetBoard(); - - aList.emplace_back( _( "Type" ), _( "Track" ), DARKCYAN ); - - GetMsgPanelInfoBase_Common( aFrame, aList ); - - // Display layer - if( board ) - msg = board->GetLayerName( m_Layer ); - else - msg.Printf(wxT("%d"), m_Layer ); - - aList.emplace_back( _( "Layer" ), msg, BROWN ); - - // Display width - msg = MessageTextFromValue( aFrame->GetUserUnits(), m_Width, true ); - - aList.emplace_back( _( "Width" ), msg, DARKCYAN ); - - // Display segment length - msg = ::MessageTextFromValue( aFrame->GetUserUnits(), GetLength() ); - aList.emplace_back( _( "Segment Length" ), msg, DARKCYAN ); -} - - -void VIA::GetMsgPanelInfoBase( EDA_DRAW_FRAME* aFrame, std::vector& aList ) -{ - wxString msg; - BOARD* board = GetBoard(); + EDA_UNITS units = aFrame->GetUserUnits(); + wxString msg; + wxString msg2; + wxString source; + BOARD* board = GetBoard(); + // Display basic infos switch( GetViaType() ) { default: - case VIATYPE::NOT_DEFINED: - msg = wxT( "???" ); // Not used yet, does not exist currently - break; - case VIATYPE::MICROVIA: msg = _( "Micro Via" ); // from external layer (TOP or BOTTOM) from // the near neighbor inner layer only @@ -674,21 +667,23 @@ void VIA::GetMsgPanelInfoBase( EDA_DRAW_FRAME* aFrame, std::vectorGetLayerName( top_layer ) + wxT( "/" ) - + board->GetLayerName( bottom_layer ); + msg = board->GetLayerName( top_layer ) + wxT( "/" ) + board->GetLayerName( bottom_layer ); else msg.Printf( wxT( "%d/%d" ), top_layer, bottom_layer ); @@ -703,34 +698,81 @@ void VIA::GetMsgPanelInfoBase( EDA_DRAW_FRAME* aFrame, std::vectorGetUserUnits(), GetDrillValue() ); - wxString title = _( "Drill" ); - title += wxT( " " ); + aList.emplace_back( _( "Drill" ), msg, RED ); - bool drl_specific = true; + int clearance = GetClearance( nullptr, &source ); + msg.Printf( _( "Min Clearance: %s" ), MessageTextFromValue( units, clearance, true ) ); + msg2.Printf( _( "Source: %s" ), source ); + aList.emplace_back( msg, msg2, BLACK ); + + int minAnnulus = GetMinAnnulus( &source ); + + msg.Printf( _( "Min Annulus: %s" ), MessageTextFromValue( units, minAnnulus, true ) ); + msg2.Printf( _( "Source: %s" ), source ); + aList.emplace_back( msg, msg2, BLACK ); +} + + +void TRACK::GetMsgPanelInfoBase_Common( EDA_DRAW_FRAME* aFrame, std::vector& aList ) +{ + wxString msg; + + // Display Net Name if( GetBoard() ) { NETINFO_ITEM* net = GetNet(); - int drill_class_value = 0; + NETCLASS* netclass = nullptr; if( net ) { - if( GetViaType() == VIATYPE::MICROVIA ) - drill_class_value = net->GetMicroViaDrillSize(); + if( net->GetNet() ) + netclass = GetNetClass(); else - drill_class_value = net->GetViaDrillSize(); + netclass = GetBoard()->GetDesignSettings().GetDefault(); + + msg = UnescapeString( net->GetNetname() ); + } + else + { + msg = wxT( "" ); } - drl_specific = GetDrillValue() != drill_class_value; + aList.emplace_back( _( "Net" ), msg, RED ); + + if( netclass ) + aList.emplace_back( _( "NetClass" ), netclass->GetName(), DARKMAGENTA ); } +#if 0 // Enable for debugging + if( GetBoard() ) + { + // Display net code: + msg.Printf( wxT( "%d" ), GetNetCode() ); + aList.emplace_back( _( "NetCode" ), msg, RED ); + } - if( drl_specific ) - title += _( "(Specific)" ); - else - title += _( "(NetClass)" ); + // Display the flags: + msg.Printf( wxT( "0x%08X" ), m_Flags ); + aList.emplace_back( wxT( "Flags" ), msg, BLUE ); - aList.emplace_back( title, msg, RED ); + // Display start and end positions: + msg.Printf( wxT( "%d %d" ), m_Start.x, m_Start.y ); + aList.push_back( MSG_PANEL_ITEM( wxT( "Start pos" ), msg, BLUE ) ); + msg.Printf( wxT( "%d %d" ), m_End.x, m_End.y ); + aList.push_back( MSG_PANEL_ITEM( wxT( "End pos" ), msg, BLUE ) ); +#endif + + // Display the State member + msg = wxT( ". . " ); + + if( GetState( TRACK_LOCKED ) ) + msg[0] = 'L'; + + if( GetState( TRACK_AR ) ) + msg[2] = 'A'; + + aList.emplace_back( _( "Status" ), msg, MAGENTA ); } diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index 5eb93ba625..596d9ac191 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -212,6 +212,8 @@ public: */ int GetClearance( BOARD_ITEM* aItem = nullptr, wxString* aSource = nullptr ) const override; + int GetMinWidth( wxString* aSource ) const; + wxString GetSelectMenuText( EDA_UNITS aUnits ) const override; BITMAP_DEF GetMenuImage() const override; @@ -247,14 +249,6 @@ public: #endif protected: - /** - * Function GetMsgPanelInfoBase - * Display info about the track segment only, and does not calculate the full track length - * @param aList A list of #MSG_PANEL_ITEM objects to add status information. - */ - virtual void GetMsgPanelInfoBase( EDA_DRAW_FRAME* aFrame, std::vector& aList ); - - void GetMsgPanelInfoBase_Common( EDA_DRAW_FRAME* aFrame, std::vector& aList ); @@ -414,6 +408,8 @@ public: const wxPoint GetPosition() const override { return m_Start; } void SetPosition( const wxPoint& aPoint ) override { m_Start = aPoint; m_End = aPoint; } + void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) override; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; @@ -438,6 +434,8 @@ public: void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } #endif + int GetMinAnnulus( wxString* aSource ) const; + /** * Function SetDrill * sets the drill value for vias. @@ -474,9 +472,6 @@ public: virtual void SwapData( BOARD_ITEM* aImage ) override; -protected: - void GetMsgPanelInfoBase( EDA_DRAW_FRAME* aFrame, std::vector& aList ) override; - private: /// The bottom layer of the via (the top layer is in m_Layer) PCB_LAYER_ID m_BottomLayer; diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index c915c15199..4caaf063ed 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -470,7 +470,7 @@ int ZONE_CONTAINER::GetClearance( BOARD_ITEM* aItem, wxString* aSource ) const clearance = m_ZoneClearance; if( aSource ) - *aSource = _( "zone clearance" ); + *aSource = _( "zone" ); } return clearance; @@ -510,15 +510,21 @@ bool ZONE_CONTAINER::HitTestCutout( const VECTOR2I& aRefPos, int* aOutlineIdx, i void ZONE_CONTAINER::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector& aList ) { - wxString msg; + EDA_UNITS units = aFrame->GetUserUnits(); + wxString msg, msg2; - msg = _( "Zone Outline" ); + if( GetIsKeepout() ) + msg = _( "Keepout Area" ); + else if( IsOnCopperLayer() ) + msg = _( "Copper Zone" ); + else + msg = _( "Non-copper Zone" ); // Display Cutout instead of Outline for holes inside a zone // i.e. when num contour !=0 // Check whether the selected corner is in a hole; i.e., in any contour but the first one. if( m_CornerSelection != nullptr && m_CornerSelection->m_contour > 0 ) - msg << wxT( " " ) << _( "(Cutout)" ); + msg << wxT( " " ) << _( "Cutout" ); aList.emplace_back( MSG_PANEL_ITEM( _( "Type" ), msg, DARKCYAN ) ); @@ -548,59 +554,53 @@ void ZONE_CONTAINER::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector= 0 ) { NETINFO_ITEM* net = GetNet(); + NETCLASS* netclass = nullptr; if( net ) + { + if( net->GetNet() ) + netclass = GetNetClass(); + else + netclass = GetBoard()->GetDesignSettings().GetDefault(); + msg = UnescapeString( net->GetNetname() ); - else // Should not occur - msg = _( "" ); + } + else + { + msg = wxT( "" ); + } + + aList.emplace_back( _( "Net" ), msg, RED ); + + if( netclass ) + aList.emplace_back( _( "NetClass" ), netclass->GetName(), DARKMAGENTA ); } - else // a netcode < 0 is an error - msg = wxT( "" ); - - aList.emplace_back( MSG_PANEL_ITEM( _( "NetName" ), msg, RED ) ); - - // Display net code : (useful in test or debug) - msg.Printf( wxT( "%d" ), GetNetCode() ); - aList.emplace_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) ); // Display priority level msg.Printf( wxT( "%d" ), GetPriority() ); aList.emplace_back( MSG_PANEL_ITEM( _( "Priority" ), msg, BLUE ) ); } - else - { - aList.emplace_back( MSG_PANEL_ITEM( _( "Non Copper Zone" ), wxEmptyString, RED ) ); - } - aList.emplace_back( MSG_PANEL_ITEM( _( "Layer" ), GetLayerName(), BROWN ) ); - - msg.Printf( wxT( "%d" ), (int) m_Poly->TotalVertices() ); - aList.emplace_back( MSG_PANEL_ITEM( _( "Vertices" ), msg, BLUE ) ); + aList.emplace_back( _( "Layer" ), LayerMaskDescribe( GetBoard(), m_layerSet ), DARKGREEN ); switch( m_FillMode ) { - case ZONE_FILL_MODE::POLYGONS: - msg = _( "Solid" ); break; - case ZONE_FILL_MODE::HATCH_PATTERN: - msg = _( "Hatched" ); break; - default: - msg = _( "Unknown" ); break; + case ZONE_FILL_MODE::POLYGONS: msg = _( "Solid" ); break; + case ZONE_FILL_MODE::HATCH_PATTERN: msg = _( "Hatched" ); break; + default: msg = _( "Unknown" ); break; } - aList.emplace_back( MSG_PANEL_ITEM( _( "Fill Mode" ), msg, BROWN ) ); + aList.emplace_back( _( "Fill Mode" ), msg, BROWN ); - msg = MessageTextFromValue( aFrame->GetUserUnits(), m_area, false, EDA_DATA_TYPE::AREA ); - aList.emplace_back( MSG_PANEL_ITEM( _( "Filled Area" ), msg, BLUE ) ); + msg = MessageTextFromValue( units, m_area, false, EDA_DATA_TYPE::AREA ); + aList.emplace_back( _( "Filled Area" ), msg, BLUE ); - // Useful for statistics : - msg.Printf( wxT( "%d" ), (int) m_HatchLines.size() ); - aList.emplace_back( MSG_PANEL_ITEM( _( "Hatch Lines" ), msg, BLUE ) ); + wxString source; + int clearance = GetClearance( nullptr, &source ); - if( !m_FilledPolysList.IsEmpty() ) - { - msg.Printf( wxT( "%d" ), m_FilledPolysList.TotalVertices() ); - aList.emplace_back( MSG_PANEL_ITEM( _( "Corner Count" ), msg, BLUE ) ); - } + msg.Printf( _( "Min Clearance: %s" ), MessageTextFromValue( units, clearance, true ) ); + msg2.Printf( _( "Source: %s" ), source ); + aList.emplace_back( msg, msg2, BLACK ); } @@ -668,13 +668,9 @@ void ZONE_CONTAINER::Flip( const wxPoint& aCentre, bool aFlipLeftRight ) int copperLayerCount = GetBoard()->GetCopperLayerCount(); if( GetIsKeepout() ) - { SetLayerSet( FlipLayerMask( GetLayerSet(), copperLayerCount ) ); - } else - { SetLayer( FlipLayer( GetLayer(), copperLayerCount ) ); - } } @@ -749,10 +745,8 @@ void ZONE_CONTAINER::AddPolygon( std::vector< wxPoint >& aPolygon ) SHAPE_LINE_CHAIN outline; // Create an outline and populate it with the points of aPolygon - for( unsigned i = 0; i < aPolygon.size(); i++ ) - { - outline.Append( VECTOR2I( aPolygon[i] ) ); - } + for( const wxPoint& pt : aPolygon) + outline.Append( pt ); outline.SetClosed( true ); diff --git a/pcbnew/drc/drc.cpp b/pcbnew/drc/drc.cpp index 03163d2d6d..d09dcb214f 100644 --- a/pcbnew/drc/drc.cpp +++ b/pcbnew/drc/drc.cpp @@ -332,7 +332,7 @@ int DRC::testZoneToZoneOutlines( BOARD_COMMIT& aCommit ) { drcItem = new DRC_ITEM( DRCE_ZONES_TOO_CLOSE ); - m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ), + m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, MessageTextFromValue( userUnits(), zone2zoneClearance, true ), MessageTextFromValue( userUnits(), conflict.second, true ) ); @@ -716,7 +716,7 @@ void DRC::testPadClearances( BOARD_COMMIT& aCommit ) actual = std::max( 0, actual ); DRC_ITEM* drcItem = new DRC_ITEM( DRCE_PAD_NEAR_EDGE ); - m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ), + m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, MessageTextFromValue( userUnits(), minClearance, true ), MessageTextFromValue( userUnits(), actual, true ) ); @@ -1039,7 +1039,7 @@ void DRC::testCopperDrawItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aItem ) : DRCE_TRACK_NEAR_COPPER; DRC_ITEM* drcItem = new DRC_ITEM( errorCode ); - m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ), + m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, MessageTextFromValue( userUnits(), minClearance, true ), MessageTextFromValue( userUnits(), actual, true ) ); @@ -1097,7 +1097,7 @@ void DRC::testCopperDrawItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aItem ) int actual = std::max( 0.0, sqrt( center2center_squared ) - widths ); DRC_ITEM* drcItem = new DRC_ITEM( DRCE_PAD_NEAR_COPPER ); - m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ), + m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, MessageTextFromValue( userUnits(), minClearance, true ), MessageTextFromValue( userUnits(), actual, true ) ); @@ -1277,7 +1277,7 @@ bool DRC::doPadToPadsDrc( BOARD_COMMIT& aCommit, D_PAD* aRefPad, D_PAD** aStart, { DRC_ITEM* drcItem = new DRC_ITEM( DRCE_HOLE_NEAR_PAD ); - m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ), + m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, MessageTextFromValue( userUnits(), minClearance, true ), MessageTextFromValue( userUnits(), actual, true ) ); @@ -1306,7 +1306,7 @@ bool DRC::doPadToPadsDrc( BOARD_COMMIT& aCommit, D_PAD* aRefPad, D_PAD** aStart, { DRC_ITEM* drcItem = new DRC_ITEM( DRCE_HOLE_NEAR_PAD ); - m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ), + m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, MessageTextFromValue( userUnits(), minClearance, true ), MessageTextFromValue( userUnits(), actual, true ) ); @@ -1354,7 +1354,7 @@ bool DRC::doPadToPadsDrc( BOARD_COMMIT& aCommit, D_PAD* aRefPad, D_PAD** aStart, { DRC_ITEM* drcItem = new DRC_ITEM( DRCE_PAD_NEAR_PAD ); - m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ), + m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, MessageTextFromValue( userUnits(), minClearance, true ), MessageTextFromValue( userUnits(), actual, true ) ); diff --git a/pcbnew/drc/drc_clearance_test_functions.cpp b/pcbnew/drc/drc_clearance_test_functions.cpp index fc29b4254e..b4f5554c56 100644 --- a/pcbnew/drc/drc_clearance_test_functions.cpp +++ b/pcbnew/drc/drc_clearance_test_functions.cpp @@ -140,18 +140,14 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS TRACKS::iterator aEndIt, bool aTestZones ) { BOARD_DESIGN_SETTINGS& bds = m_pcb->GetDesignSettings(); - std::vector matched; SEG refSeg( aRefSeg->GetStart(), aRefSeg->GetEnd() ); PCB_LAYER_ID refLayer = aRefSeg->GetLayer(); LSET refLayerSet = aRefSeg->GetLayerSet(); - NETCLASS* netclass = aRefSeg->GetNet()->GetNet() == 0 ? bds.GetDefault() - : aRefSeg->GetNetClass(); EDA_RECT refSegBB = aRefSeg->GetBoundingBox(); int refSegWidth = aRefSeg->GetWidth(); - MatchSelectors( bds.m_DRCRuleSelectors, aRefSeg, netclass, nullptr, nullptr, &matched ); /******************************************/ @@ -162,16 +158,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS { VIA *refvia = static_cast( aRefSeg ); int viaAnnulus = ( refvia->GetWidth() - refvia->GetDrill() ) / 2; - int minAnnulus = 0; - - for( DRC_SELECTOR* selector : matched ) - { - if( selector->m_Rule->m_AnnulusWidth > minAnnulus ) - { - minAnnulus = selector->m_Rule->m_AnnulusWidth; - m_clearanceSource = wxString::Format( _( "'%s' rule" ), selector->m_Rule->m_Name ); - } - } + int minAnnulus = refvia->GetMinAnnulus( &m_clearanceSource ); // test if the via size is smaller than minimum if( refvia->GetViaType() == VIATYPE::MICROVIA ) @@ -328,17 +315,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS } else // This is a track segment { - int minWidth = bds.m_TrackMinWidth; - m_clearanceSource = _( "board" ); - - for( DRC_SELECTOR* selector : matched ) - { - if( selector->m_Rule->m_TrackWidth > minWidth ) - { - minWidth = selector->m_Rule->m_TrackWidth; - m_clearanceSource = wxString::Format( _( "'%s' rule" ), selector->m_Rule->m_Name ); - } - } + int minWidth = aRefSeg->GetMinWidth( &m_clearanceSource ); if( refSegWidth < minWidth ) { @@ -414,7 +391,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS int actual = std::max( 0.0, sqrt( center2center_squared ) - widths ); DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_NEAR_HOLE ); - m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ), + m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, MessageTextFromValue( userUnits(), minClearance, true ), MessageTextFromValue( userUnits(), actual, true ) ); @@ -439,7 +416,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS SEG padSeg( pad->GetPosition(), pad->GetPosition() ); DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_NEAR_PAD ); - m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ), + m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, MessageTextFromValue( userUnits(), minClearance, true ), MessageTextFromValue( userUnits(), actual, true ) ); @@ -535,7 +512,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS int actual = std::max( 0.0, sqrt( center2center_squared ) - widths ); DRC_ITEM* drcItem = new DRC_ITEM( errorCode ); - m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ), + m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, MessageTextFromValue( userUnits(), minClearance, true ), MessageTextFromValue( userUnits(), actual, true ) ); @@ -587,7 +564,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS int actual = std::max( 0.0, sqrt( center2center_squared ) - widths ); DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_NEAR_ZONE ); - m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ), + m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, MessageTextFromValue( userUnits(), minClearance, true ), MessageTextFromValue( userUnits(), actual, true ) );