Pcbnew: fix issues and potential issues when reading board files and mainly old board files, and enhance the DRC tests and Delete Single Pad Net option when reading a netlist:
* Delete Single Pad Net option does not delete the net if a zone use this net (i.e. is attached to this pad). * pcb_parser accept now negative netcodes in zones (can happen with old files, which previously could crash Pcbnew) * pcb_parser accept now files with incorrect or missing net count (can happen with old files, which previously could crash Pcbnew) * if a zone has a non-existent net name it now keep this net name, and DRC detect it (previously, the net name was lost, and the DRC did not tected this issue). * Drc test: now detect a "dead" net, i.e. a net with 0 pads, but still used by a zone. It happens easily after a schematic modification, when a net disappears or is renamed.
This commit is contained in:
parent
64dd1f7461
commit
ebb967c46f
|
@ -6,11 +6,11 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
|
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||||
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
|
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
|
||||||
*
|
*
|
||||||
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -2459,14 +2459,14 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We need the pad list, for next tests.
|
||||||
|
// padlist is the list of pads, sorted by netname.
|
||||||
|
BuildListOfNets();
|
||||||
|
std::vector<D_PAD*> padlist = GetPads();
|
||||||
|
|
||||||
// If needed, remove the single pad nets:
|
// If needed, remove the single pad nets:
|
||||||
if( aDeleteSinglePadNets && !aNetlist.IsDryRun() )
|
if( aDeleteSinglePadNets && !aNetlist.IsDryRun() )
|
||||||
{
|
{
|
||||||
BuildListOfNets();
|
|
||||||
|
|
||||||
std::vector<D_PAD*> padlist = GetPads();
|
|
||||||
|
|
||||||
// padlist is the list of pads, sorted by netname.
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
wxString netname;
|
wxString netname;
|
||||||
D_PAD* pad = NULL;
|
D_PAD* pad = NULL;
|
||||||
|
@ -2482,6 +2482,28 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
|
||||||
if( netname != pad->GetNetname() ) // End of net
|
if( netname != pad->GetNetname() ) // End of net
|
||||||
{
|
{
|
||||||
if( previouspad && count == 1 )
|
if( previouspad && count == 1 )
|
||||||
|
{
|
||||||
|
// First, see if we have a copper zone attached to this pad.
|
||||||
|
// If so, this is not really a single pad net
|
||||||
|
|
||||||
|
for( int ii = 0; ii < GetAreaCount(); ii++ )
|
||||||
|
{
|
||||||
|
ZONE_CONTAINER* zone = GetArea( ii );
|
||||||
|
|
||||||
|
if( !zone->IsOnCopperLayer() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( zone->GetIsKeepout() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( zone->GetNet() == previouspad->GetNet() )
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( count == 1 ) // Really one pad, and nothing else
|
||||||
{
|
{
|
||||||
if( aReporter && aReporter->ReportAll() )
|
if( aReporter && aReporter->ReportAll() )
|
||||||
{
|
{
|
||||||
|
@ -2494,6 +2516,8 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
|
||||||
|
|
||||||
previouspad->SetNetCode( NETINFO_LIST::UNCONNECTED );
|
previouspad->SetNetCode( NETINFO_LIST::UNCONNECTED );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
netname = pad->GetNetname();
|
netname = pad->GetNetname();
|
||||||
count = 1;
|
count = 1;
|
||||||
}
|
}
|
||||||
|
@ -2515,6 +2539,10 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
|
||||||
// They should exist in footprints, otherwise the footprint is wrong
|
// They should exist in footprints, otherwise the footprint is wrong
|
||||||
// note also references or time stamps are updated, so we use only
|
// note also references or time stamps are updated, so we use only
|
||||||
// the reference to find a footprint
|
// the reference to find a footprint
|
||||||
|
//
|
||||||
|
// Also verify if zones have acceptable nets, i.e. nets with pads.
|
||||||
|
// Zone with no pad belongs to a "dead" net which happens after changes in schematic
|
||||||
|
// when no more pad use this net name.
|
||||||
if( aReporter && aReporter->ReportErrors() )
|
if( aReporter && aReporter->ReportErrors() )
|
||||||
{
|
{
|
||||||
wxString padname;
|
wxString padname;
|
||||||
|
@ -2543,6 +2571,22 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
|
||||||
aReporter->Report( msg );
|
aReporter->Report( msg );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test copper zones to detect "dead" nets (nets without any pad):
|
||||||
|
for( int ii = 0; ii < GetAreaCount(); ii++ )
|
||||||
|
{
|
||||||
|
ZONE_CONTAINER* zone = GetArea( ii );
|
||||||
|
|
||||||
|
if( !zone->IsOnCopperLayer() || zone->GetIsKeepout() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( zone->GetNet()->GetNodesCount() == 0 )
|
||||||
|
{
|
||||||
|
msg.Printf( _( "* Warning: copper zone (net name '%s'): net has no pad*\n" ),
|
||||||
|
GetChars( zone->GetNet()->GetNetname() ) );
|
||||||
|
aReporter->Report( msg );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
|
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||||
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -50,10 +50,10 @@ BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& aItem )
|
||||||
|
|
||||||
void BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode )
|
void BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode )
|
||||||
{
|
{
|
||||||
assert( aNetCode >= 0 );
|
// assert( aNetCode >= 0 );
|
||||||
BOARD* board = GetBoard();
|
BOARD* board = GetBoard();
|
||||||
|
|
||||||
if( board )
|
if( ( aNetCode >= 0 ) && board )
|
||||||
m_netinfo = board->FindNet( aNetCode );
|
m_netinfo = board->FindNet( aNetCode );
|
||||||
else
|
else
|
||||||
m_netinfo = &NETINFO_LIST::ORPHANED;
|
m_netinfo = &NETINFO_LIST::ORPHANED;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007 Dick Hollenbeck, dick@softplc.com
|
* Copyright (C) 2007 Dick Hollenbeck, dick@softplc.com
|
||||||
* Copyright (C) 2007 KiCad Developers, see change_log.txt for contributors.
|
* Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -75,8 +75,10 @@ wxString DRC_ITEM::GetErrorText() const
|
||||||
return wxString( _( "Copper area inside copper area" ) );
|
return wxString( _( "Copper area inside copper area" ) );
|
||||||
case COPPERAREA_CLOSE_TO_COPPERAREA:
|
case COPPERAREA_CLOSE_TO_COPPERAREA:
|
||||||
return wxString( _( "Copper areas intersect or are too close" ) );
|
return wxString( _( "Copper areas intersect or are too close" ) );
|
||||||
case DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE:
|
|
||||||
return wxString( _( "Copper area has a nonexistent net name" ) );
|
case DRCE_SUSPICIOUS_NET_FOR_ZONE_OUTLINE:
|
||||||
|
return wxString( _( "Copper area belongs a net which has no pads. This is strange" ) );
|
||||||
|
|
||||||
case DRCE_HOLE_NEAR_PAD:
|
case DRCE_HOLE_NEAR_PAD:
|
||||||
return wxString( _( "Hole near pad" ) );
|
return wxString( _( "Hole near pad" ) );
|
||||||
case DRCE_HOLE_NEAR_TRACK:
|
case DRCE_HOLE_NEAR_TRACK:
|
||||||
|
|
|
@ -320,7 +320,7 @@ public:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
///> Constant that holds the unconnected net number
|
///> Constant that holds the unconnected net number (typically 0)
|
||||||
static const int UNCONNECTED;
|
static const int UNCONNECTED;
|
||||||
|
|
||||||
///> NETINFO_ITEM meaning that there was no net assigned for an item, as there was no
|
///> NETINFO_ITEM meaning that there was no net assigned for an item, as there was no
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
|
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||||
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -625,27 +625,21 @@ void ZONE_CONTAINER::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
|
||||||
{
|
{
|
||||||
if( GetNetCode() >= 0 )
|
if( GetNetCode() >= 0 )
|
||||||
{
|
{
|
||||||
NETINFO_ITEM* equipot = GetNet();
|
NETINFO_ITEM* net = GetNet();
|
||||||
|
|
||||||
if( equipot )
|
if( net )
|
||||||
msg = equipot->GetNetname();
|
msg = net->GetNetname();
|
||||||
else
|
else // Should not occur
|
||||||
msg = wxT( "<noname>" );
|
msg = _( "<unknown>" );
|
||||||
}
|
}
|
||||||
else // a netcode < 0 is an error
|
else // a netcode < 0 is an error
|
||||||
{
|
msg = wxT( "<error>" );
|
||||||
msg = wxT( " [" );
|
|
||||||
msg << GetNetname() + wxT( "]" );
|
|
||||||
msg << wxT( " <" ) << _( "Not Found" ) << wxT( ">" );
|
|
||||||
}
|
|
||||||
|
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "NetName" ), msg, RED ) );
|
aList.push_back( MSG_PANEL_ITEM( _( "NetName" ), msg, RED ) );
|
||||||
|
|
||||||
#if 1
|
|
||||||
// Display net code : (useful in test or debug)
|
// Display net code : (useful in test or debug)
|
||||||
msg.Printf( wxT( "%d" ), GetNetCode() );
|
msg.Printf( wxT( "%d" ), GetNetCode() );
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) );
|
aList.push_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) );
|
||||||
#endif
|
|
||||||
|
|
||||||
// Display priority level
|
// Display priority level
|
||||||
msg.Printf( wxT( "%d" ), GetPriority() );
|
msg.Printf( wxT( "%d" ), GetPriority() );
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -578,7 +578,6 @@ public:
|
||||||
void SetDoNotAllowVias( bool aEnable ) { m_doNotAllowVias = aEnable; }
|
void SetDoNotAllowVias( bool aEnable ) { m_doNotAllowVias = aEnable; }
|
||||||
void SetDoNotAllowTracks( bool aEnable ) { m_doNotAllowTracks = aEnable; }
|
void SetDoNotAllowTracks( bool aEnable ) { m_doNotAllowTracks = aEnable; }
|
||||||
|
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
virtual void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
|
virtual void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
|
||||||
#endif
|
#endif
|
||||||
|
@ -632,8 +631,8 @@ private:
|
||||||
/// The index of the corner being moved or -1 if no corner is selected.
|
/// The index of the corner being moved or -1 if no corner is selected.
|
||||||
int m_CornerSelection;
|
int m_CornerSelection;
|
||||||
|
|
||||||
int m_localFlgs; ///< Flags used in polygon calculations.
|
/// Variable used in polygon calculations.
|
||||||
|
int m_localFlgs;
|
||||||
|
|
||||||
/** Segments used to fill the zone (#m_FillMode ==1 ), when fill zone by segment is used.
|
/** Segments used to fill the zone (#m_FillMode ==1 ), when fill zone by segment is used.
|
||||||
* In this case the segments have #m_ZoneMinThickness width.
|
* In this case the segments have #m_ZoneMinThickness width.
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
* Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 2014 Dick Hollenbeck, dick@softplc.com
|
* Copyright (C) 2014 Dick Hollenbeck, dick@softplc.com
|
||||||
* Copyright (C) 2014 KiCad Developers, see change_log.txt for contributors.
|
* Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -564,6 +564,10 @@ void DRC::testZones()
|
||||||
// if a netcode is < 0 the netname was not found when reading a netlist
|
// if a netcode is < 0 the netname was not found when reading a netlist
|
||||||
// if a netcode is == 0 the netname is void, and the zone is not connected.
|
// if a netcode is == 0 the netname is void, and the zone is not connected.
|
||||||
// This is allowed, but i am not sure this is a good idea
|
// This is allowed, but i am not sure this is a good idea
|
||||||
|
//
|
||||||
|
// In recent Pcbnew versions, the netcode is always >= 0, but an internal net name
|
||||||
|
// is stored, and initalized from the file or the zone properpies editor.
|
||||||
|
// if it differs from the net name from net code, there is a DRC issue
|
||||||
for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
|
for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
|
||||||
{
|
{
|
||||||
ZONE_CONTAINER* test_area = m_pcb->GetArea( ii );
|
ZONE_CONTAINER* test_area = m_pcb->GetArea( ii );
|
||||||
|
@ -571,13 +575,21 @@ void DRC::testZones()
|
||||||
if( !test_area->IsOnCopperLayer() )
|
if( !test_area->IsOnCopperLayer() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( test_area->GetNetCode() < 0 )
|
int netcode = test_area->GetNetCode();
|
||||||
|
|
||||||
|
// a netcode < 0 or > 0 and no pad in net is a error or strange
|
||||||
|
// perhaps a "dead" net, which happens when all pads in this net were removed
|
||||||
|
// Remark: a netcode < 0 should not happen (this is more a bug somewhere)
|
||||||
|
int pads_in_net = (test_area->GetNetCode() > 0) ?
|
||||||
|
test_area->GetNet()->GetNodesCount() : 1;
|
||||||
|
|
||||||
|
if( ( netcode < 0 ) || pads_in_net == 0 )
|
||||||
{
|
{
|
||||||
m_currentMarker = fillMarker( test_area,
|
m_currentMarker = fillMarker( test_area,
|
||||||
DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE, m_currentMarker );
|
DRCE_SUSPICIOUS_NET_FOR_ZONE_OUTLINE, m_currentMarker );
|
||||||
m_pcb->Add( m_currentMarker );
|
m_pcb->Add( m_currentMarker );
|
||||||
m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
|
m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
|
||||||
m_currentMarker = 0;
|
m_currentMarker = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007 Dick Hollenbeck, dick@softplc.com
|
* Copyright (C) 2007 Dick Hollenbeck, dick@softplc.com
|
||||||
* Copyright (C) 2007 KiCad Developers, see change_log.txt for contributors.
|
* Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
#define DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR 21 ///< micro via's layer pair incorrect (layers must be adjacent)
|
#define DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR 21 ///< micro via's layer pair incorrect (layers must be adjacent)
|
||||||
#define COPPERAREA_INSIDE_COPPERAREA 22 ///< copper area outlines intersect
|
#define COPPERAREA_INSIDE_COPPERAREA 22 ///< copper area outlines intersect
|
||||||
#define COPPERAREA_CLOSE_TO_COPPERAREA 23 ///< copper area outlines are too close
|
#define COPPERAREA_CLOSE_TO_COPPERAREA 23 ///< copper area outlines are too close
|
||||||
#define DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE 24 ///< copper area outline has an incorrect netcode due to a netname not found
|
#define DRCE_SUSPICIOUS_NET_FOR_ZONE_OUTLINE 24 ///< copper area has a net but no pads in nets, which is suspicious
|
||||||
#define DRCE_HOLE_NEAR_PAD 25 ///< hole too close to pad
|
#define DRCE_HOLE_NEAR_PAD 25 ///< hole too close to pad
|
||||||
#define DRCE_HOLE_NEAR_TRACK 26 ///< hole too close to track
|
#define DRCE_HOLE_NEAR_TRACK 26 ///< hole too close to track
|
||||||
#define DRCE_TOO_SMALL_TRACK_WIDTH 27 ///< Too small track width
|
#define DRCE_TOO_SMALL_TRACK_WIDTH 27 ///< Too small track width
|
||||||
|
|
|
@ -112,6 +112,17 @@ void PCB_PARSER::init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PCB_PARSER::pushValueIntoMap( int aIndex, int aValue )
|
||||||
|
{
|
||||||
|
// Add aValue in netcode mapping (m_netCodes) at index aNetCode
|
||||||
|
// ensure there is room in m_netCodes for that, and add room if needed.
|
||||||
|
|
||||||
|
if( (int)m_netCodes.size() <= aIndex )
|
||||||
|
m_netCodes.resize( aIndex+1 );
|
||||||
|
|
||||||
|
m_netCodes[aIndex] = aValue;
|
||||||
|
}
|
||||||
|
|
||||||
double PCB_PARSER::parseDouble() throw( IO_ERROR )
|
double PCB_PARSER::parseDouble() throw( IO_ERROR )
|
||||||
{
|
{
|
||||||
char* tmp;
|
char* tmp;
|
||||||
|
@ -1194,7 +1205,7 @@ void PCB_PARSER::parseNETINFO_ITEM() throw( IO_ERROR, PARSE_ERROR )
|
||||||
m_board->AppendNet( net );
|
m_board->AppendNet( net );
|
||||||
|
|
||||||
// Store the new code mapping
|
// Store the new code mapping
|
||||||
m_netCodes[netCode] = net->GetNet();
|
pushValueIntoMap( netCode, net->GetNet() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2526,6 +2537,8 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
|
||||||
int hatchPitch = Mils2iu( CPolyLine::GetDefaultHatchPitchMils() );
|
int hatchPitch = Mils2iu( CPolyLine::GetDefaultHatchPitchMils() );
|
||||||
wxPoint pt;
|
wxPoint pt;
|
||||||
T token;
|
T token;
|
||||||
|
int tmp;
|
||||||
|
wxString netnameFromfile; // the zone net name find in file
|
||||||
|
|
||||||
// bigger scope since each filled_polygon is concatenated in here
|
// bigger scope since each filled_polygon is concatenated in here
|
||||||
CPOLYGONS_LIST pts;
|
CPOLYGONS_LIST pts;
|
||||||
|
@ -2545,20 +2558,19 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
|
||||||
// Init the net code only, not the netname, to be sure
|
// Init the net code only, not the netname, to be sure
|
||||||
// the zone net name is the name read in file.
|
// the zone net name is the name read in file.
|
||||||
// (When mismatch, the user will be prompted in DRC, to fix the actual name)
|
// (When mismatch, the user will be prompted in DRC, to fix the actual name)
|
||||||
zone->SetNetCode( getNetCode( parseInt( "net number" ) ) );
|
tmp = getNetCode( parseInt( "net number" ) );
|
||||||
|
|
||||||
|
if( tmp < 0 )
|
||||||
|
tmp = 0;
|
||||||
|
|
||||||
|
zone->SetNetCode( tmp );
|
||||||
|
|
||||||
NeedRIGHT();
|
NeedRIGHT();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_net_name:
|
case T_net_name:
|
||||||
NeedSYMBOLorNUMBER();
|
NeedSYMBOLorNUMBER();
|
||||||
if( zone->GetNet()->GetNetname() != FromUTF8() )
|
netnameFromfile = FromUTF8();
|
||||||
{
|
|
||||||
wxString msg;
|
|
||||||
msg.Printf( _( "There is a zone that belongs to a not existing net"
|
|
||||||
"(%s), you should verify it." ), GetChars( FromUTF8() ) );
|
|
||||||
DisplayError( NULL, msg );
|
|
||||||
zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
|
|
||||||
}
|
|
||||||
NeedRIGHT();
|
NeedRIGHT();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2829,10 +2841,45 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
|
||||||
if( pts.GetCornersCount() )
|
if( pts.GetCornersCount() )
|
||||||
zone->AddFilledPolysList( pts );
|
zone->AddFilledPolysList( pts );
|
||||||
|
|
||||||
// Ensure keepout does not have a net (which have no sense for a keepout zone)
|
// Ensure keepout and non copper zones do not have a net
|
||||||
if( zone->GetIsKeepout() )
|
// (which have no sense for these zones)
|
||||||
|
// the netcode 0 is used for these zones
|
||||||
|
bool zone_has_net = zone->IsOnCopperLayer() && !zone->GetIsKeepout();
|
||||||
|
|
||||||
|
if( !zone_has_net )
|
||||||
zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
|
zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
|
||||||
|
|
||||||
|
// Ensure the zone net name is valid, and matches the net code, for copper zones
|
||||||
|
if( zone_has_net && ( zone->GetNet()->GetNetname() != netnameFromfile ) )
|
||||||
|
{
|
||||||
|
// Can happens which old boards, with nonexistent nets ...
|
||||||
|
// or after being edited by hand
|
||||||
|
// We try to fix the mismatch.
|
||||||
|
NETINFO_ITEM* net = m_board->FindNet( netnameFromfile );
|
||||||
|
|
||||||
|
if( net ) // An existing net has the same net name. use it for the zone
|
||||||
|
zone->SetNetCode( net->GetNet() );
|
||||||
|
else // Not existing net: add a new net to keep trace of the zone netname
|
||||||
|
{
|
||||||
|
int newnetcode = m_board->GetNetCount();
|
||||||
|
net = new NETINFO_ITEM( m_board, netnameFromfile, newnetcode );
|
||||||
|
m_board->AppendNet( net );
|
||||||
|
|
||||||
|
// Store the new code mapping
|
||||||
|
pushValueIntoMap( newnetcode, net->GetNet() );
|
||||||
|
// and update the zone netcode
|
||||||
|
zone->SetNetCode( net->GetNet() );
|
||||||
|
|
||||||
|
// Prompt the user
|
||||||
|
wxString msg;
|
||||||
|
msg.Printf( _( "There is a zone that belongs to a not existing net\n"
|
||||||
|
"\"%s\"\n"
|
||||||
|
"you should verify and edit it (run DRC test)." ),
|
||||||
|
GetChars( netnameFromfile ) );
|
||||||
|
DisplayError( NULL, msg );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return zone.release();
|
return zone.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,15 +69,24 @@ class PCB_PARSER : public PCB_LEXER
|
||||||
std::vector<int> m_netCodes; ///< net codes mapping for boards being loaded
|
std::vector<int> m_netCodes; ///< net codes mapping for boards being loaded
|
||||||
|
|
||||||
///> Converts net code using the mapping table if available,
|
///> Converts net code using the mapping table if available,
|
||||||
///> otherwise returns unchanged net code
|
///> otherwise returns unchanged net code if < 0 or if is is out of range
|
||||||
inline int getNetCode( int aNetCode )
|
inline int getNetCode( int aNetCode )
|
||||||
{
|
{
|
||||||
if( aNetCode < (int) m_netCodes.size() )
|
if( ( aNetCode >= 0 ) && ( aNetCode < (int) m_netCodes.size() ) )
|
||||||
return m_netCodes[aNetCode];
|
return m_netCodes[aNetCode];
|
||||||
|
|
||||||
return aNetCode;
|
return aNetCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function pushValueIntoMap
|
||||||
|
* Add aValue value in netcode mapping (m_netCodes) at index aIndex
|
||||||
|
* ensure there is room in m_netCodes for that, and add room if needed.
|
||||||
|
* @param aIndex = the index ( expected >=0 )of the location to use in m_netCodes
|
||||||
|
* @param aValue = the netcode value to map
|
||||||
|
*/
|
||||||
|
void pushValueIntoMap( int aIndex, int aValue );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function init
|
* Function init
|
||||||
* clears and re-establishes m_layerMap with the default layer names.
|
* clears and re-establishes m_layerMap with the default layer names.
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
|
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||||
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
|
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
|
||||||
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
Loading…
Reference in New Issue