diff --git a/include/class_board_item.h b/include/class_board_item.h index 607a416e44..4798ea7353 100644 --- a/include/class_board_item.h +++ b/include/class_board_item.h @@ -109,6 +109,14 @@ public: return false; } + /** + * @return true if the object is on any copper layer, false otherwise. + */ + virtual bool IsOnCopperLayer() const + { + return IsCopperLayer( GetLayer() ); + } + /** * A value of wxPoint(0,0) which can be passed to the Draw() functions. */ diff --git a/pcbnew/board_connected_item.cpp b/pcbnew/board_connected_item.cpp index 3bd7fc37a0..63e2588ad0 100644 --- a/pcbnew/board_connected_item.cpp +++ b/pcbnew/board_connected_item.cpp @@ -49,6 +49,9 @@ BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype bool BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode, bool aNoAssert ) { + if( !IsOnCopperLayer() ) + aNetCode = 0; + // if aNetCode < 0 ( typically NETINFO_LIST::FORCE_ORPHANED ) // or no parent board, // set the m_netinfo to the dummy NETINFO_LIST::ORPHANED diff --git a/pcbnew/board_connected_item.h b/pcbnew/board_connected_item.h index 2b35a1d32a..150aa55f03 100644 --- a/pcbnew/board_connected_item.h +++ b/pcbnew/board_connected_item.h @@ -102,12 +102,13 @@ public: } /** - * Function SetNetCode - * sets net using a net code. + * Sets net using a net code. * @param aNetCode is a net code for the new net. It has to exist in NETINFO_LIST held by BOARD. * @param aNoAssert if true, do not assert that the net exists. * Otherwise, item is assigned to the unconnected net. * @return true on success, false if the net did not exist + * Note also items (in fact pads) not on copper layers will have + * their net code always set to 0 (not connected) */ bool SetNetCode( int aNetCode, bool aNoAssert=false ); diff --git a/pcbnew/board_netlist_updater.cpp b/pcbnew/board_netlist_updater.cpp index b1b4ab2c02..0e39e9d2be 100644 --- a/pcbnew/board_netlist_updater.cpp +++ b/pcbnew/board_netlist_updater.cpp @@ -295,7 +295,8 @@ bool BOARD_NETLIST_UPDATER::updateComponentPadConnections( MODULE* aPcbComponent { COMPONENT_NET net = aNewComponent->GetNet( pad->GetName() ); - if( !net.IsValid() ) // New footprint pad has no net. + // Test if new footprint pad has no net (pads not on copper layers have no net). + if( !net.IsValid() || !pad->IsOnCopperLayer() ) { if( !pad->GetNetname().IsEmpty() ) { diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index cd7839a6c9..15ba0b27db 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -261,6 +261,16 @@ public: m_boundingRadius = -1; } + /** + * @return true if the pad is on any copper layer, false otherwise. + * pads can be only on tech layers to build special pads. + * they are therefore not always on a copper layer + */ + bool IsOnCopperLayer() const override + { + return ( GetLayerSet() & LSET::AllCuMask() ) != 0; + } + void SetY( int y ) { m_Pos.y = y; } void SetX( int x ) { m_Pos.x = x; } diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index 5324570221..ac71dc078b 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -228,6 +228,14 @@ public: virtual void SwapData( BOARD_ITEM* aImage ) override; + /** + * @return true because a track or a via is always on a copper layer. + */ + bool IsOnCopperLayer() const override + { + return true; + } + #if defined (DEBUG) virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index 5d0ef1720b..9168e188f0 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -130,7 +130,7 @@ public: * Function IsOnCopperLayer * @return true if this zone is on a copper layer, false if on a technical layer */ - bool IsOnCopperLayer() const; + bool IsOnCopperLayer() const override; /** * Function CommonLayerExist diff --git a/pcbnew/connectivity/connectivity_algo.cpp b/pcbnew/connectivity/connectivity_algo.cpp index e2940cb65b..4b22d0a484 100644 --- a/pcbnew/connectivity/connectivity_algo.cpp +++ b/pcbnew/connectivity/connectivity_algo.cpp @@ -112,7 +112,7 @@ void CN_CONNECTIVITY_ALGO::markItemNetAsDirty( const BOARD_ITEM* aItem ) bool CN_CONNECTIVITY_ALGO::Add( BOARD_ITEM* aItem ) { - if( !IsCopperLayer( aItem->GetLayer() ) ) + if( !aItem->IsOnCopperLayer() ) return false; markItemNetAsDirty ( aItem ); diff --git a/pcbnew/connectivity/connectivity_items.cpp b/pcbnew/connectivity/connectivity_items.cpp index df3d2759a2..d52847d24f 100644 --- a/pcbnew/connectivity/connectivity_items.cpp +++ b/pcbnew/connectivity/connectivity_items.cpp @@ -123,6 +123,9 @@ void CN_ITEM::RemoveInvalidRefs() CN_ITEM* CN_LIST::Add( D_PAD* pad ) { + if( !pad->IsOnCopperLayer() ) + return nullptr; + auto item = new CN_ITEM( pad, false, 1 ); item->AddAnchor( pad->ShapePos() ); item->SetLayers( LAYER_RANGE( F_Cu, B_Cu ) ); @@ -153,7 +156,7 @@ CN_ITEM* CN_LIST::Add( D_PAD* pad ) m_items.push_back( item ); SetDirty(); return item; - } +} CN_ITEM* CN_LIST::Add( TRACK* track ) { diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index 73c68bd805..647a4b6e94 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -2761,14 +2761,19 @@ D_PAD* PCB_PARSER::parseD_PAD( MODULE* aParent ) if( ! pad->SetNetCode( getNetCode( parseInt( "net number" ) ), /* aNoAssert */ true ) ) THROW_IO_ERROR( wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ), - GetChars( CurSource() ), CurLineNumber(), CurOffset() ) + CurSource(), CurLineNumber(), CurOffset() ) ); + NeedSYMBOLorNUMBER(); - if( m_board && FromUTF8() != m_board->FindNet( pad->GetNetCode() )->GetNetname() ) + + // Test validity of the netname in file for netcodes expected having a net name + if( m_board && pad->GetNetCode() > 0 && + FromUTF8() != m_board->FindNet( pad->GetNetCode() )->GetNetname() ) THROW_IO_ERROR( wxString::Format( _( "Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ), - GetChars( CurSource() ), CurLineNumber(), CurOffset() ) + CurSource(), CurLineNumber(), CurOffset() ) ); + NeedRIGHT(); break;