more netclass work

This commit is contained in:
dickelbeck 2009-08-17 02:59:38 +00:00
parent f9f671d1b9
commit 85dc98a58a
17 changed files with 710 additions and 406 deletions

View File

@ -4,6 +4,24 @@ KiCad ChangeLog 2009
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2009-Aug-16 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
++pcbnew
* first of my work on NETCLASSes, more to come.
wrote: BOARD* BOARD_ITEM::GetBoard(), int BOARD_CONNECTED_ITEM::GetClearance( BOARD_CONNECTED_ITEM* ),
rewrote: classes NETCLASS, NETCLASSES, BOARD::SynchronizeNetsAndNetClasses(),
added: NETCLASS::m_ViaDrillSize, NETCLASS::m_Description. Removed netname from
EQUIPOTs in *.brd file (were redundant with NETCLASSes in *.brd file). NETCLASSes
now follow EQUIPOTs in *.brd file.
NETs and NETCLASSes are linked by pointer from class NET.
BOARD::SynchronizeNetsAndNetClasses() will validate pointers, NETs and NETCLASSes.
* Pay particular attention to the new:
int BOARD_CONNECTED_ITEM::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const
which considers two netclasses and finds the largest distance from the two
involved.
* I would love to see class NETINFO_ITEM renamed to NET.
2009-Aug-6 UPDATE Dick Hollenbeck <dick@softplc.com> 2009-Aug-6 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================ ================================================================================
++pcbnew ++pcbnew

View File

@ -189,6 +189,7 @@ public:
{ {
wxMessageBox(wxT("virtual BOARD_ITEM::Move used, should not occur"), GetClass()); wxMessageBox(wxT("virtual BOARD_ITEM::Move used, should not occur"), GetClass());
} }
/** /**
* Function Rotate * Function Rotate
* Rotate this object. * Rotate this object.
@ -199,6 +200,7 @@ public:
{ {
wxMessageBox(wxT("virtual BOARD_ITEM::Rotate used, should not occur"), GetClass()); wxMessageBox(wxT("virtual BOARD_ITEM::Rotate used, should not occur"), GetClass());
} }
/** /**
* Function Flip * Function Flip
* Flip this object, i.e. change the board side for this object * Flip this object, i.e. change the board side for this object
@ -208,8 +210,16 @@ public:
{ {
wxMessageBox(wxT("virtual BOARD_ITEM::Flip used, should not occur"), GetClass()); wxMessageBox(wxT("virtual BOARD_ITEM::Flip used, should not occur"), GetClass());
} }
/**
* Function GetBoard
* returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
*/
virtual BOARD* GetBoard() const;
}; };
class NETCLASS;
/** /**
* Class BOARD_CONNECTED_ITEM * Class BOARD_CONNECTED_ITEM
@ -253,6 +263,19 @@ public:
*/ */
int GetZoneSubNet() const; int GetZoneSubNet() const;
void SetZoneSubNet( int aSubNetCode ); void SetZoneSubNet( int aSubNetCode );
/**
* Function GetClearance
* returns the clearance in 1/10000 inches to aItem from this BOARD_CONNECTED_ITEM.
*/
virtual int GetClearance( BOARD_CONNECTED_ITEM* aItem ) const;
/**
* Function GetNetClass
* returns the NETCLASS for this item.
*/
virtual NETCLASS* GetNetClass() const;
}; };

View File

@ -20,7 +20,7 @@ wxPoint BOARD_ITEM::ZeroOffset( 0, 0 );
/* Constructor */ /* Constructor */
BOARD::BOARD( EDA_BaseStruct* parent, WinEDA_BasePcbFrame* frame ) : BOARD::BOARD( EDA_BaseStruct* parent, WinEDA_BasePcbFrame* frame ) :
BOARD_ITEM( (BOARD_ITEM*)parent, TYPE_PCB ), BOARD_ITEM( (BOARD_ITEM*)parent, TYPE_PCB ),
m_NetClassesList(this) m_NetClasses(this)
{ {
m_PcbFrame = frame; m_PcbFrame = frame;
m_Status_Pcb = 0; // Mot d'etat: Bit 1 = Chevelu calcule m_Status_Pcb = 0; // Mot d'etat: Bit 1 = Chevelu calcule
@ -37,10 +37,6 @@ BOARD::BOARD( EDA_BaseStruct* parent, WinEDA_BasePcbFrame* frame ) :
m_Layer[layer].m_Name = ReturnPcbLayerName( layer, true ); m_Layer[layer].m_Name = ReturnPcbLayerName( layer, true );
m_Layer[layer].m_Type = LT_SIGNAL; m_Layer[layer].m_Type = LT_SIGNAL;
} }
// Add the default Netclass to list
NETCLASS * default_netclass = new NETCLASS(this);
m_NetClassesList.AddNetclass( default_netclass );
} }
@ -538,7 +534,7 @@ void BOARD::DisplayInfo( WinEDA_DrawFrame* frame )
txt.Printf( wxT( "%d" ), GetNodesCount() ); txt.Printf( wxT( "%d" ), GetNodesCount() );
Affiche_1_Parametre( frame, POS_AFF_NBNODES, _( "Nodes" ), txt, DARKCYAN ); Affiche_1_Parametre( frame, POS_AFF_NBNODES, _( "Nodes" ), txt, DARKCYAN );
txt.Printf( wxT( "%d" ), m_NetInfo->GetNetsCount() ); txt.Printf( wxT( "%d" ), m_NetInfo->GetCount() );
Affiche_1_Parametre( frame, POS_AFF_NBNETS, _( "Nets" ), txt, RED ); Affiche_1_Parametre( frame, POS_AFF_NBNETS, _( "Nets" ), txt, RED );
/* These parameters are known only if the full ratsnest is available, /* These parameters are known only if the full ratsnest is available,
@ -822,7 +818,7 @@ SEARCH_RESULT BOARD::Visit( INSPECTOR* inspector, const void* testData,
*/ */
NETINFO_ITEM* BOARD::FindNet( int anetcode ) const NETINFO_ITEM* BOARD::FindNet( int anetcode ) const
{ {
// the first valid netcode is 1 and the last is m_NetInfo->GetNetsCount()-1. // the first valid netcode is 1 and the last is m_NetInfo->GetCount()-1.
// zero is reserved for "no connection" and is not used. // zero is reserved for "no connection" and is not used.
// NULL is returned for non valid netcodes // NULL is returned for non valid netcodes
NETINFO_ITEM* item = m_NetInfo->GetNetItem( anetcode ); NETINFO_ITEM* item = m_NetInfo->GetNetItem( anetcode );
@ -850,7 +846,7 @@ NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const
// zero is reserved for "no connection" and is not used. // zero is reserved for "no connection" and is not used.
if( !aNetname.IsEmpty() ) if( !aNetname.IsEmpty() )
{ {
for( unsigned ii = 1; ii < m_NetInfo->GetNetsCount(); ii++ ) for( unsigned ii = 1; ii < m_NetInfo->GetCount(); ii++ )
{ {
NETINFO_ITEM* item = m_NetInfo->GetNetItem( ii ); NETINFO_ITEM* item = m_NetInfo->GetNetItem( ii );
if( item && item->GetNetname() == aNetname ) if( item && item->GetNetname() == aNetname )
@ -909,15 +905,15 @@ static bool s_SortByNodes( const NETINFO_ITEM* a, const NETINFO_ITEM* b )
*/ */
int BOARD::ReturnSortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount ) int BOARD::ReturnSortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount )
{ {
if( m_NetInfo->GetNetsCount() == 0 ) if( m_NetInfo->GetCount() == 0 )
return 0; return 0;
// Build the list // Build the list
std::vector <NETINFO_ITEM*> netBuffer; std::vector <NETINFO_ITEM*> netBuffer;
netBuffer.reserve( m_NetInfo->GetNetsCount() ); netBuffer.reserve( m_NetInfo->GetCount() );
for( unsigned ii = 1; ii < m_NetInfo->GetNetsCount(); ii++ ) for( unsigned ii = 1; ii < m_NetInfo->GetCount(); ii++ )
{ {
if( m_NetInfo->GetNetItem( ii )->GetNet() > 0 ) if( m_NetInfo->GetNetItem( ii )->GetNet() > 0 )
netBuffer.push_back( m_NetInfo->GetNetItem( ii ) ); netBuffer.push_back( m_NetInfo->GetNetItem( ii ) );
@ -941,14 +937,14 @@ bool BOARD::Save( FILE* aFile ) const
bool rc = false; bool rc = false;
BOARD_ITEM* item; BOARD_ITEM* item;
// save the netclasses
m_NetClassesList.Save( aFile );
// save the nets // save the nets
for( unsigned ii = 0; ii < m_NetInfo->GetNetsCount(); ii++ ) for( unsigned ii = 0; ii < m_NetInfo->GetCount(); ii++ )
if( !m_NetInfo->GetNetItem( ii )->Save( aFile ) ) if( !m_NetInfo->GetNetItem( ii )->Save( aFile ) )
goto out; goto out;
// Saved nets do not include netclass names, so save netclasses after nets.
m_NetClasses.Save( aFile );
// save the modules // save the modules
for( item = m_Modules; item; item = item->Next() ) for( item = m_Modules; item; item = item->Next() )
if( !item->Save( aFile ) ) if( !item->Save( aFile ) )

View File

@ -97,7 +97,7 @@ public:
std::vector<RATSNEST_ITEM> m_LocalRatsnest; /* Rastnest list relative to a given footprint std::vector<RATSNEST_ITEM> m_LocalRatsnest; /* Rastnest list relative to a given footprint
* (used while moving a footprint) */ * (used while moving a footprint) */
NETCLASS_LIST m_NetClassesList; // List of current netclasses. There is always the default netclass NETCLASSES m_NetClasses; ///< List of current netclasses. There is always the default netclass
ZONE_CONTAINER* m_CurrentZoneContour; // zone contour currently in progress ZONE_CONTAINER* m_CurrentZoneContour; // zone contour currently in progress
@ -338,15 +338,15 @@ public:
int ReturnSortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount ); int ReturnSortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount );
/** /**
* Function TransfertDesignRulesToNets * Function SynchronizeNetsAndNetClasses
* copies Netclass parameters to each net, corresponding to its net class. * copies NETCLASS info to each NET, based on NET membership in a NETCLASS.
* Must be called after a Design Rules edition, or after reading a netlist (or editing the list of nets) * Must be called after a Design Rules edition, or after reading a netlist (or editing the list of nets)
* Also this function removes the non existing nets in netclasses and add net nets in default netclass * Also this function removes the non existing nets in netclasses and add net nets in default netclass
* (this happens after reading a netlist) * (this happens after reading a netlist)
* @param none * @param none
* @return none * @return none
*/ */
void TransfertDesignRulesToNets(); void SynchronizeNetsAndNetClasses();
/** /**
* Function Save * Function Save

View File

@ -68,3 +68,50 @@ void BOARD_CONNECTED_ITEM::SetZoneSubNet( int aSubNetCode )
{ {
m_ZoneSubnet = aSubNetCode; m_ZoneSubnet = aSubNetCode;
} }
int BOARD_CONNECTED_ITEM::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const
{
NETCLASS* hisclass = aItem->GetNetClass();
NETCLASS* myclass = GetNetClass();
wxASSERT( hisclass );
wxASSERT( myclass );
if( myclass )
{
if( hisclass )
return MAX( hisclass->GetClearance(), myclass->GetClearance() );
else
return myclass->GetClearance();
}
else if( hisclass )
{
return hisclass->GetClearance();
}
return 0;
}
NETCLASS* BOARD_CONNECTED_ITEM::GetNetClass() const
{
// It is important that this be implemented without any sequential searching.
// Simple array lookups should be fine, performance-wise.
BOARD* board = GetBoard();
wxASSERT( board );
if( board )
{
NETINFO_ITEM* net = board->FindNet( GetNet() );
wxASSERT( net );
if( net )
{
NETCLASS* netclass = net->GetNetClass();
wxASSERT( netclass );
return netclass;
}
}
return NULL;
}

View File

@ -315,3 +315,11 @@ void BOARD_ITEM::UnLink()
list->Remove( this ); list->Remove( this );
} }
BOARD* BOARD_ITEM::GetBoard() const
{
// overload this function as needed.
return (BOARD*) GetParent();
}

View File

@ -1,6 +1,28 @@
/*************************************/ /*
/* class to handle Net Classes */ * This program source code file is part of KICAD, a free EDA CAD application.
/**************************************/ *
* Copyright (C) 2009 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2009 Jean-Pierre Charras, jean-pierre.charras@inpg.fr
* Copyright (C) 2009 Kicad Developers, see change_log.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 "fctsys.h" #include "fctsys.h"
@ -9,25 +31,25 @@
#include "pcbnew.h" #include "pcbnew.h"
NET_DESIGN_PARAMS::NET_DESIGN_PARAMS() // "kicad_default" is what we are using in the specctra_export.
const wxString NETCLASS::Default = wxT("kicad_default");
NETCLASS::NETCLASS( BOARD* aParent, const wxString& aName ) :
m_Parent( aParent ),
m_Name( aName )
{ {
m_TracksWidth = 170; // "Default" value for tracks thickness used to route this net m_TrackWidth = 160;
m_TracksMinWidth = 150; // Minimum value for tracks thickness (used in DRC)
m_ViasSize = 550; // "Default" value for vias sizes used to route this net
m_ViasMinSize = 400; // Minimum value for vias sizes (used in DRC)
m_Clearance = 140; // "Default" clearance when routing
m_MinClearance = 110; // Minimum value for clearance (used in DRC)
}
m_TrackMinWidth = 40;
/* A NETCLASS handles a list of nets and the parameters used to route or test (in DRC) these nets m_ViaSize = 350;
* This is mainly used in autotouters like Freeroute, but this can be also used in manual routing
*/
NETCLASS::NETCLASS( BOARD* aParent, const wxString& aName ) m_ViaMinSize = 220;
{
m_Parent = aParent; m_ViaDrillSize = 200;
m_Name = aName; // Name of the net class
m_Clearance = 140;
} }
@ -36,259 +58,321 @@ NETCLASS::~NETCLASS()
} }
NETCLASS_LIST::NETCLASS_LIST( BOARD* aParent ) NETCLASSES::NETCLASSES( BOARD* aParent ) :
m_Parent( aParent ),
m_Default( aParent, NETCLASS::Default )
{ {
m_Parent = aParent;
std::vector <NETCLASS*> m_Netclass_List;
} }
NETCLASS_LIST::~NETCLASS_LIST() NETCLASSES::~NETCLASSES()
{ {
ClearList(); Clear();
} }
void NETCLASS_LIST::ClearList() void NETCLASSES::Clear()
{ {
// the NETCLASS_LIST is owner of its items, so delete them // Although std::map<> will destroy the items that it contains, in this
for( unsigned ii = 0; ii < m_Netclass_List.size(); ii++ ) // case we have NETCLASS* (pointers) and "destroying" a pointer does not
delete m_Netclass_List[ii]; // delete the object that the pointer points to.
m_Netclass_List.clear(); // this NETCLASSES is owner of its NETCLASS pointers,
// so delete NETCLASSes pointed to by them.
for( iterator i = begin(); i!=end(); )
{
// http://www.sgi.com/tech/stl/Map.html says:
// "Erasing an element from a map also does not invalidate any iterators,
// except, of course, for iterators that actually point to the element that
// is being erased."
iterator e = i++; // copy, then advance.
delete e->second; // delete the NETCLASS, which 'second' points to.
m_NetClasses.erase( e );
}
} }
/** Function AddNetclass() bool NETCLASSES::Add( const NETCLASS& aNetClass )
* @param aNetclass = a pointer to the netclass to add
* @return true if Ok, false if cannot be added (mainly because a netclass with the same name exists)
*/
bool NETCLASS_LIST::AddNetclass( NETCLASS* aNetclass )
{ {
const wxString& name = aNetClass.GetName();
if( name == NETCLASS::Default )
{
// invoke operator=(), which is currently generated by compiler.
m_Default = aNetClass;
return true;
}
// Test for an existing netclass: // Test for an existing netclass:
for( unsigned ii = 0; ii < m_Netclass_List.size(); ii++ ) if( !Find( name ) )
{ {
if( m_Netclass_List[ii]->m_Name.CmpNoCase( aNetclass->m_Name ) == 0 ) // insert since name not found, invoke copy constructor.
return false; // this netclass already exists m_NetClasses[name] = new NETCLASS( aNetClass );
return true;
} }
m_Netclass_List.push_back( aNetclass ); return false; // name already exists
return true;
} }
void BOARD::TransfertDesignRulesToNets() NETCLASS* NETCLASSES::Remove( const wxString& aNetName )
{ {
// Clear .m_Flag member of nets (used to detect not in netclass list nets) NETCLASSMAP::iterator found = m_NetClasses.find( aNetName );
for( unsigned ii = 1; ; ii++ )
{
NETINFO_ITEM* net = FindNet( ii );
if( net == NULL )
break;
net->m_Flag = 0; if( found != m_NetClasses.end() )
{
NETCLASS* netclass = found->second;
m_NetClasses.erase( found );
return netclass;
} }
for( unsigned ii = 0; ii < m_NetClassesList.GetNetClassCount(); ii++ ) return NULL;
}
NETCLASS* NETCLASSES::Find( const wxString& aName ) const
{
if( aName == NETCLASS::Default )
return (NETCLASS*) &m_Default;
NETCLASSMAP::const_iterator found = m_NetClasses.find( aName );
if( found == m_NetClasses.end() )
return NULL;
else
return found->second;
}
void BOARD::SynchronizeNetsAndNetClasses()
{
// D(printf("start\n");) // simple performance/timing indicator.
// set all NETs to the default NETCLASS, then later override some
// as we go through the NETCLASSes.
int count = m_NetInfo->GetCount();
for( int i=0; i<count; ++i )
{ {
// Transfert rules and netclass name to nets: NETINFO_ITEM* net = FindNet( i );
NETCLASS* netclass = m_NetClassesList.GetNetClass( ii ); if( net )
net->SetClass( m_NetClasses.GetDefault() );
}
for( unsigned jj = 0; jj < netclass->GetMembersCount(); jj++ ) // Add netclass name and pointer to nets. If a net is in more than one netclass,
// remove it from all but the first netclass in which it resides.
for( NETCLASSES::iterator clazz=m_NetClasses.begin(); clazz!=m_NetClasses.end(); ++clazz )
{
NETCLASS* netclass = clazz->second;
for( NETCLASS::iterator member = netclass->begin(); member!=netclass->end(); )
{ {
wxString netname = netclass->GetMemberName( jj ); const wxString& netname = *member;
NETINFO_ITEM* net = FindNet( netname );
if( net == NULL ) // This net does not exists: remove it // @todo: although this overall function seems to be adequately fast, if you
// wanted to make an improvement it would be in FindNet( wxString ) which I
// think is a sequential search.
NETINFO_ITEM* net = FindNet( netname );
if( !net ) // NET 'netname' does not exist, remove it from 'netclass'
{ {
netclass->m_MembersNetNames.RemoveAt( jj ); NETCLASS::iterator e = member++;
jj--; netclass->Remove( e );
}
else if( net->GetClassName() != NETCLASS::Default )
{
// 'net' is already in a non-default net class. This makes its
// entry in 'netclass' bogus, delete it.
NETCLASS::iterator e = member++;
netclass->Remove( e );
} }
else else
{ {
net->SetClass( *netclass ); net->SetClass( netclass );
net->m_Flag = 1; ++member;
} }
} }
} }
// Now, set nets that do not have yet a netclass to default netclass // Finally, make sure that every NET is in a NETCLASS, even if that
NETCLASS* defaultnetclass = m_NetClassesList.GetNetClass( 0 ); // means the Default NETCLASS. And make sure that all NETCLASSes do not
// contain netnames that do not exist, by deleting all netnames from
// every netclass and re-adding them.
for( unsigned ii = 1; ; ii++ ) for( NETCLASSES::iterator clazz=m_NetClasses.begin(); clazz!=m_NetClasses.end(); ++clazz )
{ {
NETINFO_ITEM* net = FindNet( ii ); NETCLASS* netclass = clazz->second;
if( net == NULL ) netclass->Clear();
break; }
if( net->m_Flag == 0 ) m_NetClasses.GetDefault()->Clear();
for( int i=0; i<count; ++i )
{
NETINFO_ITEM* net = FindNet( i );
if( net )
{ {
net->SetClass( *defaultnetclass ); const wxString& classname = net->GetClassName();
defaultnetclass->AddMember( net->GetNetname() );
// because of the std:map<> this should be fast, and because of
// prior logic, netclass should not be NULL.
NETCLASS* netclass = m_NetClasses.Find( classname );
wxASSERT( netclass );
netclass->Add( net->GetNetname() );
} }
} }
// D(printf("stop\n");)
} }
/** bool NETCLASSES::Save( FILE* aFile ) const
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool NETCLASS_LIST::Save( FILE* aFile ) const
{ {
bool success = true; bool result;
for( unsigned ii = 0; ii < m_Netclass_List.size(); ii++ ) // save the default first.
result = m_Default.Save( aFile );
if( result )
{ {
success = m_Netclass_List[ii]->Save( aFile ); // the rest will be alphabetical in the *.brd file.
if( !success ) for( const_iterator i = begin(); i!=end(); ++i )
break; {
NETCLASS* netclass = i->second;
result = netclass->Save( aFile );
if( !result )
break;
}
} }
return success; return result;
} }
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool NETCLASS::Save( FILE* aFile ) const bool NETCLASS::Save( FILE* aFile ) const
{ {
bool success = true; bool result = true;
fprintf( aFile, "$NETCLASS\n" ); fprintf( aFile, "$NETCLASS\n" );
fprintf( aFile, "Name \"%s\"\n", CONV_TO_UTF8( m_Name ) ); fprintf( aFile, "Name \"%s\"\n", CONV_TO_UTF8( m_Name ) );
fprintf( aFile, "Desc \"%s\"\n", CONV_TO_UTF8( GetDescription() ) );
// Write parameters // Write parameters
success = m_NetParams.Save( aFile ); fprintf( aFile, "TrackWidth %d\n", GetTrackWidth() );
fprintf( aFile, "TrackMinWidth %d\n", GetTrackMinWidth() );
fprintf( aFile, "ViaSize %d\n", GetViaSize() );
fprintf( aFile, "ViaDrillSize %d\n", GetViaDrillSize() );
fprintf( aFile, "ViaMinSize %d\n", GetViaMinSize() );
fprintf( aFile, "Clearance %d\n", GetClearance() );
// Write members list: // Write members:
for( unsigned ii = 0; ii < GetMembersCount(); ii++ ) for( const_iterator i = begin(); i!=end(); ++i )
fprintf( aFile, "AddNet \"%s\"\n", CONV_TO_UTF8( GetMemberName( ii ) ) ); fprintf( aFile, "AddNet \"%s\"\n", CONV_TO_UTF8( *i ) );
fprintf( aFile, "$EndNETCLASS\n" ); fprintf( aFile, "$EndNETCLASS\n" );
return success; return result;
} }
/** #if defined(DEBUG)
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format. void NETCLASS::Show( int nestLevel, std::ostream& os )
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool NET_DESIGN_PARAMS::Save( FILE* aFile ) const
{ {
bool success = true; // for now, make it look like XML:
//NestedSpace( nestLevel, os )
fprintf( aFile, "$PARAMS_START\n" ); os << '<' << GetClass().Lower().mb_str() << ">\n";
fprintf( aFile, "TracksWidth %d\n", m_TracksWidth );
fprintf( aFile, "TracksMinWidth %d\n", m_TracksMinWidth );
fprintf( aFile, "ViasSize %d\n", m_ViasSize );
fprintf( aFile, "ViasMinSize %d\n", m_ViasMinSize );
fprintf( aFile, "Clearance %d\n", m_Clearance );
fprintf( aFile, "MinClearance %d\n", m_MinClearance );
fprintf( aFile, "$PARAMS_END\n" );
return success; for( const_iterator i = begin(); i!=end(); ++i )
}
/**
* Function ReadDescr
* reads the data structures for this object from a FILE in "*.brd" format.
* @param aFile The FILE to read to.
* @return bool - true if success reading else false.
*/
bool NET_DESIGN_PARAMS::ReadDescr( FILE* aFile, int* aLineNum )
{
bool success = true;
char Line[1024];
while( GetLine( aFile, Line, aLineNum, 1024 ) != NULL )
{ {
if( strnicmp( Line, "$PARAMS_END", 11 ) == 0 ) // NestedSpace( nestLevel+1, os ) << *i;
return success; os << *i;
if( strnicmp( Line, "TracksWidth", 11 ) == 0 )
{
m_TracksWidth = atoi( Line + 11 );
continue;
}
if( strnicmp( Line, "TracksMinWidth", 14 ) == 0 )
{
m_TracksMinWidth = atoi( Line + 14 );
continue;
}
if( strnicmp( Line, "ViasSize", 8 ) == 0 )
{
m_ViasSize = atoi( Line + 8 );
continue;
}
if( strnicmp( Line, "ViasMinSize", 11 ) == 0 )
{
m_ViasMinSize = atoi( Line + 11 );
continue;
}
if( strnicmp( Line, "Clearance", 9 ) == 0 )
{
m_Clearance = atoi( Line + 9 );
continue;
}
if( strnicmp( Line, "MinClearance", 12 ) == 0 )
{
m_MinClearance = atoi( Line + 12 );
continue;
}
} }
return success; // NestedSpace( nestLevel, os )
os << "</" << GetClass().Lower().mb_str() << ">\n";
} }
#endif
/**
* Function ReadDescr
* reads the data structures for this object from a FILE in "*.brd" format.
* @param aFile The FILE to read to.
* @return bool - true if success reading else false.
*/
bool NETCLASS::ReadDescr( FILE* aFile, int* aLineNum ) bool NETCLASS::ReadDescr( FILE* aFile, int* aLineNum )
{ {
bool success = true; bool result = false;
char Line[1024]; char Line[1024];
char Buffer[1024]; char Buffer[1024];
wxString netname;
while( GetLine( aFile, Line, aLineNum, 1024 ) != NULL ) while( GetLine( aFile, Line, aLineNum, 1024 ) != NULL )
{ {
if( strnicmp( Line, "$endNETCLASS", 6 ) == 0 ) if( strnicmp( Line, "AddNet", 6 ) == 0 )
return success;
if( strnicmp( Line, "$PARAMS_START", 13 ) == 0 )
{ {
m_NetParams.ReadDescr( aFile, aLineNum ); ReadDelimitedText( Buffer, Line + 6, sizeof(Buffer) );
netname = CONV_FROM_UTF8( Buffer );
Add( netname );
continue; continue;
} }
if( strnicmp( Line, "$endNETCLASS", 6 ) == 0 )
{
result = true;
break;
}
if( strnicmp( Line, "TrackWidth", 10 ) == 0 )
{
SetTrackWidth( atoi( Line + 10 ) );
continue;
}
if( strnicmp( Line, "ViaSize", 7 ) == 0 )
{
SetViaSize( atoi( Line + 7 ) );
continue;
}
if( strnicmp( Line, "ViaDrillSize", 12 ) == 0 )
{
SetViaDrillSize( atoi( Line + 12 ) );
continue;
}
if( strnicmp( Line, "Clearance", 9 ) == 0 )
{
SetClearance( atoi( Line + 9 ) );
continue;
}
if( strnicmp( Line, "TrackMinWidth", 13 ) == 0 )
{
SetTrackMinWidth( atoi( Line + 13 ) );
continue;
}
if( strnicmp( Line, "ViaMinSize", 10 ) == 0 )
{
SetViaMinSize( atoi( Line + 10 ) );
continue;
}
if( strnicmp( Line, "Name", 4 ) == 0 ) if( strnicmp( Line, "Name", 4 ) == 0 )
{ {
ReadDelimitedText( Buffer, Line + 4, sizeof(Buffer) ); ReadDelimitedText( Buffer, Line + 4, sizeof(Buffer) );
m_Name = CONV_FROM_UTF8( Buffer ); m_Name = CONV_FROM_UTF8( Buffer );
continue;
} }
if( strnicmp( Line, "Desc", 4 ) == 0 )
if( strnicmp( Line, "AddNet", 6 ) == 0 )
{ {
ReadDelimitedText( Buffer, Line + 6, sizeof(Buffer) ); ReadDelimitedText( Buffer, Line + 4, sizeof(Buffer) );
wxString netname = CONV_FROM_UTF8( Buffer ); SetDescription( CONV_FROM_UTF8( Buffer ) );
AddMember( netname ); continue;
} }
} }
return success; return result;
} }

View File

@ -1,102 +1,157 @@
/*************************************/
/* class to Net Classes */
/**************************************/
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2009 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2009 Jean-Pierre Charras, jean-pierre.charras@inpg.fr
* Copyright (C) 2009 Kicad Developers, see change_log.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 CLASS_NETCLASS_H #ifndef CLASS_NETCLASS_H
#define CLASS_NETCLASS_H #define CLASS_NETCLASS_H
#include <set>
/** #include <map>
* Class NET_DESIGN_PARAMS
* handles netclass parameters.
*
* This is a separate class because these parameters are also duplicated
* (for calculation time consideration) in each NETINFO_ITEM when making
* tests DRC and routing
*/
class NET_DESIGN_PARAMS
{
public:
int m_TracksWidth; // "Default" value for tracks thickness used to route this net
int m_TracksMinWidth; // Minimum value for tracks thickness (used in DRC)
int m_ViasSize; // "Default" value for vias sizes used to route this net
int m_ViasMinSize; // Minimum value for vias sizes (used in DRC)
int m_Clearance; // "Default" clearance when routing
int m_MinClearance; // Minimum value for clearance (used in DRC)
public:
NET_DESIGN_PARAMS();
// ~NET_DESIGN_PARAMS() {}
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool Save( FILE* aFile ) const;
/**
* Function ReadDescr
* reads the data structures for this object from a FILE in "*.brd" format.
* @param aFile The FILE to read to.
* @return bool - true if success reading else false.
*/
bool ReadDescr( FILE* aFile, int* aLineNum );
};
/** /**
* Class NETCLASS * Class NETCLASS
* handles a list of nets and the parameters used to route or test these nets * handles a collection of nets and the parameters used to route or
* test these nets.
*/ */
class NETCLASS class NETCLASS
{ {
public: protected:
BOARD* m_Parent;
wxString m_Name; // Name of the net class
wxArrayString m_MembersNetNames; // List of nets members of this class
NET_DESIGN_PARAMS m_NetParams; // values of net classes parameters
BOARD* m_Parent;
wxString m_Name; ///< Name of the net class
wxString m_Description; ///< what this NETCLASS is for.
typedef std::set<wxString> STRINGSET;
STRINGSET m_Members; ///< names of NET members of this class
/// The units on these parameters is 1/10000 of an inch.
int m_TrackWidth; ///< value for tracks thickness used to route this net
int m_TrackMinWidth; ///< minimum value for tracks thickness (used in DRC)
int m_ViaSize; ///< default via size used to route this net
int m_ViaDrillSize; ///< default via drill size used to create vias in this net
int m_ViaMinSize; ///< minimum size for vias (used in DRC)
int m_Clearance; ///< clearance when routing
public: public:
NETCLASS( BOARD* aParent, const wxString& aName = wxT( "default" ) );
static const wxString Default; ///< the name of the default NETCLASS
NETCLASS( BOARD* aParent, const wxString& aName );
~NETCLASS(); ~NETCLASS();
wxString GetClass() const
{
return wxT( "NETCLASS" );
}
const wxString& GetName() const
{
return m_Name;
}
/** /**
* Function GetMembersCount * Function GetCount
* returns the number of nets using this rule * returns the number of nets in this NETCLASS, i.e. using these rules.
*/ */
unsigned GetMembersCount() const unsigned GetCount() const
{ {
return m_MembersNetNames.GetCount(); return m_Members.size();
} }
void ClearMembersList() /**
* Function Clear
* empties the collection of members.
*/
void Clear()
{ {
m_MembersNetNames.Clear(); m_Members.clear();
} }
void AddMember( const wxString& aNetname ) /**
* Function AddMember
* adds \a aNetname to this NETCLASS if it is not already in this NETCLASS.
* It is harmless to try and add a second identical name.
*/
void Add( const wxString& aNetname )
{ {
m_MembersNetNames.Add( aNetname ); m_Members.insert( aNetname );
} }
typedef STRINGSET::iterator iterator;
iterator begin() { return m_Members.begin(); }
iterator end() { return m_Members.end(); }
wxString GetMemberName( unsigned aIdx ) const typedef STRINGSET::const_iterator const_iterator;
const_iterator begin() const { return m_Members.begin(); }
const_iterator end() const { return m_Members.end(); }
/**
* Function Remove
* will remove NET name \a aName from the collection of members.
*/
void Remove( iterator aName )
{ {
if( aIdx < GetMembersCount() ) m_Members.erase( aName );
return m_MembersNetNames[aIdx];
else
return wxEmptyString;
} }
/**
* Function Remove
* will remove NET name \a aName from the collection of members.
*/
void Remove( const wxString& aName )
{
m_Members.erase( aName );
}
const wxString& GetDescription() const { return m_Description; }
void SetDescription( const wxString& aDesc ) { m_Description = aDesc; }
int GetTrackWidth() const { return m_TrackWidth; }
void SetTrackWidth( int aWidth ) { m_TrackWidth = aWidth; }
int GetTrackMinWidth() const { return m_TrackMinWidth; }
void SetTrackMinWidth( int aWidth ) { m_TrackMinWidth = aWidth; }
int GetViaSize() const { return m_ViaSize; }
void SetViaSize( int aSize ) { m_ViaSize = aSize; }
int GetViaDrillSize() const { return m_ViaDrillSize; }
void SetViaDrillSize( int aSize ) { m_ViaDrillSize = aSize; }
int GetViaMinSize() const { return m_ViaMinSize; }
void SetViaMinSize( int aSize ) { m_ViaMinSize = aSize; }
int GetClearance() const { return m_Clearance; }
void SetClearance( int aClearance ) { m_Clearance = aClearance; }
/** /**
* Function Save * Function Save
@ -113,55 +168,99 @@ public:
* @return bool - true if success reading else false. * @return bool - true if success reading else false.
*/ */
bool ReadDescr( FILE* aFile, int* aLineNum ); bool ReadDescr( FILE* aFile, int* aLineNum );
#if defined(DEBUG)
/**
* Function Show
* is used to output the object tree, currently for debugging only.
* @param nestLevel An aid to prettier tree indenting, and is the level
* of nesting of this object within the overall tree.
* @param os The ostream& to output to.
*/
void Show( int nestLevel, std::ostream& os );
#endif
}; };
/** /**
* Class NETCLASS_LIST handles the list of NETCLASS for the board * Class NETCLASSES
* Note: the NETCLASS_LIST is owner of all NETCLASS in list * is a containter for NETCLASS instances. It owns all its NETCLASSes
* (=> it will delete them at time of destruction). This container will always have
* a default NETCLASS with the name given by const NETCLASS::Default.
*/ */
class NETCLASS_LIST class NETCLASSES
{ {
protected: private:
BOARD* m_Parent; BOARD* m_Parent;
std::vector <NETCLASS*> m_Netclass_List;
typedef std::map<wxString, NETCLASS*> NETCLASSMAP;
/// all the NETCLASSes except the default one.
NETCLASSMAP m_NetClasses;
/// the default NETCLASS.
NETCLASS m_Default;
public: public:
NETCLASS_LIST( BOARD* aParent = NULL ); NETCLASSES( BOARD* aParent = NULL );
~NETCLASS_LIST(); ~NETCLASSES();
void ClearList();
/** /**
* Function GetNetClassCount() * Function Clear
* @return the number of existing netclasses * destroys any constained NETCLASS instances except the Default one.
*/ */
unsigned GetNetClassCount() void Clear();
typedef NETCLASSMAP::iterator iterator;
iterator begin() { return m_NetClasses.begin(); }
iterator end() { return m_NetClasses.end(); }
typedef NETCLASSMAP::const_iterator const_iterator;
const_iterator begin() const { return m_NetClasses.begin(); }
const_iterator end() const { return m_NetClasses.end(); }
/**
* Function GetCount
* @return the number of netclasses, excluding the default one.
*/
unsigned GetCount() const
{ {
return m_Netclass_List.size(); return m_NetClasses.size();
}
NETCLASS* GetDefault() const
{
return (NETCLASS*) &m_Default;
} }
/** Function GetNetClass() /**
* @param aIdx = the index in netclass list * Function Add
* @return a NETCLASS* pointer on the netclass * @param aNetclass is netclass to add
* @return true if Ok, false if cannot be added (mainly because a
* netclass with the same name exists)
*/ */
NETCLASS* GetNetClass( unsigned aIdx ) bool Add( const NETCLASS& aNetclass );
{
if( GetNetClassCount() && aIdx < GetNetClassCount() )
return m_Netclass_List[aIdx];
else
return NULL;
}
/**
/** Function AddNetclass() * Function Remove
* @param aNetclass = a pointer to the netclass to add * removes a NETCLASS from this container but does not destroy/delete it.
* @return true if Ok, false if cannot be added (mainly because a netclass with the same name exists) * @param aNetName is the name of the net to delete, and it may not be NETCLASS::Default.
* @return NETCLASS* - the NETCLASS associated with aNetName if found and removed, else NULL.
* You have to delete the returned value if you intend to destroy the NETCLASS.
*/ */
bool AddNetclass( NETCLASS* aNetclass ); NETCLASS* Remove( const wxString& aNetName );
/**
* Function Find
* searches this container for a NETCLASS given by \a aName.
* @param aName is the name of the NETCLASS to search for.
* @return NETCLASS* - if found, else NULL.
*/
NETCLASS* Find( const wxString& aName ) const;
/** /**
* Function Save * Function Save
@ -172,5 +271,5 @@ public:
bool Save( FILE* aFile ) const; bool Save( FILE* aFile ) const;
}; };
#endif // CLASS_NETCLASS_H #endif // CLASS_NETCLASS_H

View File

@ -85,11 +85,12 @@ public:
*/ */
NETINFO_ITEM* GetNetItem( int aNetcode ); NETINFO_ITEM* GetNetItem( int aNetcode );
/** Function GetCount() /**
* Function GetCount
* @return the number of nets ( always >= 1 ) * @return the number of nets ( always >= 1 )
* becuse the first net is the "not connected" net and always exists * becuse the first net is the "not connected" net and always exists
*/ */
unsigned GetNetsCount() { return m_NetBuffer.size(); } unsigned GetCount() { return m_NetBuffer.size(); }
/** /**
* Function Append * Function Append
@ -152,12 +153,15 @@ class NETINFO_ITEM
private: private:
int m_NetCode; // this is a number equivalent to the net name int m_NetCode; // this is a number equivalent to the net name
// Used for fast comparisons in rastnest and DRC computations. // Used for fast comparisons in rastnest and DRC computations.
wxString m_Netname; // Full net name like /mysheet/mysubsheet/vout used by eeschema wxString m_Netname; // Full net name like /mysheet/mysubsheet/vout used by eeschema
wxString m_ShortNetname; // short net name, like vout from /mysheet/mysubsheet/vout wxString m_ShortNetname; // short net name, like vout from /mysheet/mysubsheet/vout
wxString m_NetClassName; // Net Class name. if void this is equivalent to "default" (the first wxString m_NetClassName; // Net Class name. if void this is equivalent to "default" (the first
// item of the net classes list // item of the net classes list
NET_DESIGN_PARAMS m_NetParams; // values of net classes parameters NETCLASS* m_NetClass;
public: public:
@ -177,83 +181,97 @@ public:
NETINFO_ITEM( BOARD_ITEM* aParent ); NETINFO_ITEM( BOARD_ITEM* aParent );
~NETINFO_ITEM(); ~NETINFO_ITEM();
/**
/** Functions SetClassParameters * Function SetClass
* copy the class parameters in the locale buffer m_NetParams * sets \a aNetclass into this NET
*/ */
void SetClassParameters(const NET_DESIGN_PARAMS& aParams ) void SetClass( const NETCLASS* aNetClass )
{ {
m_NetParams = aParams; m_NetClass = (NETCLASS*) aNetClass;
if( aNetClass )
m_NetClassName = aNetClass->GetName();
else
m_NetClassName = NETCLASS::Default;
} }
/** Functions SetClass NETCLASS* GetNetClass()
* copy the class Name and class parmeters
*/
void SetClass(const NETCLASS& aNetclass )
{ {
m_NetParams = aNetclass.m_NetParams; return m_NetClass;
m_NetClassName = aNetclass.m_Name;
} }
/** Functions GetClassName /**
* @return the class Name * Function GetClassName
* returns the class name
*/ */
wxString GetClassName( ) const const wxString& GetClassName( ) const
{ {
return m_NetClassName; return m_NetClassName;
} }
/** function GetTracksWidth()
* @return the "default" value for tracks thickness used to route this net /**
* Function GetTrackWidth
* returns the width of tracks used to route this net.
*/ */
int GetTracksWidth() int GetTrackWidth()
{ {
return m_NetParams.m_TracksWidth; wxASSERT( m_NetClass );
return m_NetClass->GetTrackWidth();
} }
/** Function GetTracksMinWidth() /**
* @return the Minimum value for tracks thickness (used in DRC) * Function GetTrackMinWidth
* returns the Minimum value for tracks thickness (used in DRC)
*/ */
int GetTracksMinWidth() int GetTrackMinWidth()
{ {
return m_NetParams.m_TracksMinWidth = 150; wxASSERT( m_NetClass );
return m_NetClass->GetTrackMinWidth();
} }
/** Function /**
* @return the "Default" value for vias sizes used to route this net * Function GetViaSize
* returns the size of vias used to route this net
*/ */
int GetViasSize() int GetViaSize()
{ {
return m_NetParams.m_ViasSize; wxASSERT( m_NetClass );
return m_NetClass->GetViaSize();
} }
/** Function GetViasMinSize() /**
* @return the Minimum value for vias sizes (used in DRC) * Function GetViaDrillSize
* returns the size of via drills used to route this net
*/ */
int GetViasMinSize() int GetViaDrillSize()
{ {
return m_NetParams.m_ViasMinSize; wxASSERT( m_NetClass );
return m_NetClass->GetViaDrillSize();
} }
/** Function GetClearance() /**
* @return the "Default" clearance when routing * Function GetViaMinSize
* returns the Minimum value for via sizes (used in DRC)
*/ */
int GetClearance() int GetViaMinSize()
{ {
return m_NetParams.m_Clearance; wxASSERT( m_NetClass );
return m_NetClass->GetViaMinSize();
} }
/** Function GetMinClearance() /**
* @return the Minimum value for clearance (used in DRC) * Function GetClearance
* returns the clearance when routing near aBoardItem
*/ */
int GetMinClearance() int GetClearance( BOARD_ITEM* aBoardItem )
{ {
return m_NetParams.m_MinClearance; wxASSERT( m_NetClass );
return m_NetClass->GetClearance();
} }

View File

@ -23,13 +23,16 @@ NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent )
m_Flag = 0; m_Flag = 0;
m_RatsnestStartIdx = 0; // Starting point of ratsnests of this net in a general buffer of ratsnest m_RatsnestStartIdx = 0; // Starting point of ratsnests of this net in a general buffer of ratsnest
m_RatsnestEndIdx = 0; // Ending point of ratsnests of this net m_RatsnestEndIdx = 0; // Ending point of ratsnests of this net
m_NetClassName = NETCLASS::Default;
m_NetClass = 0;
} }
/* destructor */
NETINFO_ITEM::~NETINFO_ITEM() NETINFO_ITEM::~NETINFO_ITEM()
{ {
// m_NetClass is not owned by me.
} }
@ -60,12 +63,14 @@ int NETINFO_ITEM:: ReadDescr( FILE* File, int* LineNum )
continue; continue;
} }
/*
if( strncmp( Line, "NetClass", 8 ) == 0 ) if( strncmp( Line, "NetClass", 8 ) == 0 )
{ {
ReadDelimitedText( Ltmp, Line + 8, sizeof(Ltmp) ); ReadDelimitedText( Ltmp, Line + 8, sizeof(Ltmp) );
m_NetClassName = CONV_FROM_UTF8( Ltmp ); m_NetClassName = CONV_FROM_UTF8( Ltmp );
continue; continue;
} }
*/
} }
return 1; return 1;
@ -86,7 +91,7 @@ bool NETINFO_ITEM::Save( FILE* aFile ) const
fprintf( aFile, "Na %d \"%s\"\n", GetNet(), CONV_TO_UTF8( m_Netname ) ); fprintf( aFile, "Na %d \"%s\"\n", GetNet(), CONV_TO_UTF8( m_Netname ) );
fprintf( aFile, "St %s\n", "~" ); fprintf( aFile, "St %s\n", "~" );
fprintf( aFile, "NetClass \"%s\"\n", CONV_TO_UTF8(m_NetClassName) ); // fprintf( aFile, "NetClass \"%s\"\n", CONV_TO_UTF8(m_NetClassName) );
if( fprintf( aFile, "$EndEQUIPOT\n" ) != sizeof("$EndEQUIPOT\n") - 1 ) if( fprintf( aFile, "$EndEQUIPOT\n" ) != sizeof("$EndEQUIPOT\n") - 1 )
goto out; goto out;

View File

@ -29,7 +29,7 @@ NETINFO_LIST::~NETINFO_LIST()
*/ */
NETINFO_ITEM* NETINFO_LIST::GetNetItem( int aNetcode ) NETINFO_ITEM* NETINFO_LIST::GetNetItem( int aNetcode )
{ {
if( aNetcode < 0 || ( aNetcode > (int) ( GetNetsCount() - 1 ) ) ) if( aNetcode < 0 || ( aNetcode > (int) ( GetCount() - 1 ) ) )
return NULL; return NULL;
return m_NetBuffer[aNetcode]; return m_NetBuffer[aNetcode];
} }
@ -40,7 +40,7 @@ NETINFO_ITEM* NETINFO_LIST::GetNetItem( int aNetcode )
*/ */
void NETINFO_LIST::DeleteData() void NETINFO_LIST::DeleteData()
{ {
for( unsigned ii = 0; ii < GetNetsCount(); ii++ ) for( unsigned ii = 0; ii < GetCount(); ii++ )
delete m_NetBuffer[ii]; delete m_NetBuffer[ii];
m_NetBuffer.clear(); m_NetBuffer.clear();
@ -125,7 +125,8 @@ void NETINFO_LIST::BuildListOfNets()
} }
m_Parent->m_NbNodes = nodes_count; m_Parent->m_NbNodes = nodes_count;
m_Parent->TransfertDesignRulesToNets( );
m_Parent->SynchronizeNetsAndNetClasses( );
m_Parent->m_Status_Pcb |= NET_CODES_OK; m_Parent->m_Status_Pcb |= NET_CODES_OK;

View File

@ -202,39 +202,44 @@ void DIALOG_DESIGN_RULES::SetRoutableLayerStatus()
*/ */
void DIALOG_DESIGN_RULES::InitRulesList() void DIALOG_DESIGN_RULES::InitRulesList()
{ {
for( int ii = 0; ; ii++ ) NETCLASSES& netclasses = m_Pcb->m_NetClasses;
int ii = 0;
for( NETCLASSES::iterator i=netclasses.begin(); i!=netclasses.end(); ++i, ++ii )
{ {
const NETCLASS* netclass = m_Pcb->m_NetClassesList.GetNetClass( ii ); NETCLASS* netclass = i->second;
if( netclass == NULL )
break;
// Creates one entry if needed // Creates one entry if needed
if( ii >= m_gridNetClassesProperties->GetNumberRows() ) if( ii >= m_gridNetClassesProperties->GetNumberRows() )
m_gridNetClassesProperties->AppendRows(); m_gridNetClassesProperties->AppendRows();
// Init name // Init name
m_gridNetClassesProperties->SetRowLabelValue( ii, netclass->m_Name ); m_gridNetClassesProperties->SetRowLabelValue( ii, netclass->GetName() );
// Init data // Init data
wxString msg; wxString msg;
msg = ReturnStringFromValue( g_UnitMetric, msg = ReturnStringFromValue( g_UnitMetric,
netclass->m_NetParams.m_TracksWidth, netclass->GetTrackWidth(),
m_Parent->m_InternalUnits, false ); m_Parent->m_InternalUnits, false );
m_gridNetClassesProperties->SetCellValue( ii, RULE_GRID_TRACKSIZE_POSITION, msg ); m_gridNetClassesProperties->SetCellValue( ii, RULE_GRID_TRACKSIZE_POSITION, msg );
msg = ReturnStringFromValue( g_UnitMetric, msg = ReturnStringFromValue( g_UnitMetric,
netclass->m_NetParams.m_ViasSize, netclass->GetViaSize(),
m_Parent->m_InternalUnits, false ); m_Parent->m_InternalUnits, false );
m_gridNetClassesProperties->SetCellValue( ii, RULE_GRID_VIASIZE_POSITION, msg ); m_gridNetClassesProperties->SetCellValue( ii, RULE_GRID_VIASIZE_POSITION, msg );
msg = ReturnStringFromValue( g_UnitMetric, msg = ReturnStringFromValue( g_UnitMetric,
netclass->m_NetParams.m_Clearance, netclass->GetClearance(),
m_Parent->m_InternalUnits, false ); m_Parent->m_InternalUnits, false );
m_gridNetClassesProperties->SetCellValue( ii, RULE_GRID_CLEARANCE_POSITION, msg ); m_gridNetClassesProperties->SetCellValue( ii, RULE_GRID_CLEARANCE_POSITION, msg );
msg = ReturnStringFromValue( g_UnitMetric, msg = ReturnStringFromValue( g_UnitMetric,
netclass->m_NetParams.m_TracksMinWidth, netclass->GetTrackMinWidth(),
m_Parent->m_InternalUnits, false ); m_Parent->m_InternalUnits, false );
m_gridNetClassesProperties->SetCellValue( ii, RULE_GRID_MINTRACKSIZE_POSITION, msg ); m_gridNetClassesProperties->SetCellValue( ii, RULE_GRID_MINTRACKSIZE_POSITION, msg );
msg = ReturnStringFromValue( g_UnitMetric, msg = ReturnStringFromValue( g_UnitMetric,
netclass->m_NetParams.m_ViasMinSize, netclass->GetViaMinSize(),
m_Parent->m_InternalUnits, false ); m_Parent->m_InternalUnits, false );
m_gridNetClassesProperties->SetCellValue( ii, RULE_GRID_MINVIASIZE_POSITION, msg ); m_gridNetClassesProperties->SetCellValue( ii, RULE_GRID_MINVIASIZE_POSITION, msg );
} }
@ -245,53 +250,57 @@ void DIALOG_DESIGN_RULES::InitRulesList()
*/ */
void DIALOG_DESIGN_RULES::CopyRulesListToBoard() void DIALOG_DESIGN_RULES::CopyRulesListToBoard()
{ {
m_Pcb->m_NetClassesList.ClearList(); NETCLASSES& netclasses = m_Pcb->m_NetClasses;
netclasses.Clear();
for( int ii = 0; ii < m_gridNetClassesProperties->GetNumberRows(); ii++ ) for( int ii = 0; ii < m_gridNetClassesProperties->GetNumberRows(); ii++ )
{ {
NETCLASS* netclass = new NETCLASS( m_Pcb, NETCLASS netclass( m_Pcb, m_gridNetClassesProperties->GetRowLabelValue( ii ) );
m_gridNetClassesProperties->GetRowLabelValue( ii ) );
m_Pcb->m_NetClassesList.AddNetclass( netclass );
// Init data // Init data
netclass->m_NetParams.m_TracksWidth = netclass.SetTrackWidth(
ReturnValueFromString( g_UnitMetric, ReturnValueFromString( g_UnitMetric,
m_gridNetClassesProperties->GetCellValue( ii, m_gridNetClassesProperties->GetCellValue( ii,
RULE_GRID_TRACKSIZE_POSITION ), RULE_GRID_TRACKSIZE_POSITION ),
m_Parent->m_InternalUnits ); m_Parent->m_InternalUnits ));
netclass->m_NetParams.m_ViasSize = netclass.SetViaSize(
ReturnValueFromString( g_UnitMetric, ReturnValueFromString( g_UnitMetric,
m_gridNetClassesProperties->GetCellValue( ii, m_gridNetClassesProperties->GetCellValue( ii,
RULE_GRID_VIASIZE_POSITION ), RULE_GRID_VIASIZE_POSITION ),
m_Parent->m_InternalUnits ); m_Parent->m_InternalUnits ));
netclass->m_NetParams.m_Clearance = netclass.SetClearance(
ReturnValueFromString( g_UnitMetric, ReturnValueFromString( g_UnitMetric,
m_gridNetClassesProperties->GetCellValue( ii, m_gridNetClassesProperties->GetCellValue( ii,
RULE_GRID_CLEARANCE_POSITION ), RULE_GRID_CLEARANCE_POSITION ),
m_Parent->m_InternalUnits ); m_Parent->m_InternalUnits ));
netclass->m_NetParams.m_TracksMinWidth = netclass.SetTrackMinWidth(
ReturnValueFromString( g_UnitMetric, ReturnValueFromString( g_UnitMetric,
m_gridNetClassesProperties->GetCellValue( ii, m_gridNetClassesProperties->GetCellValue( ii,
RULE_GRID_MINTRACKSIZE_POSITION ), RULE_GRID_MINTRACKSIZE_POSITION ),
m_Parent->m_InternalUnits ); m_Parent->m_InternalUnits ));
netclass->m_NetParams.m_ViasMinSize = netclass.SetViaMinSize(
ReturnValueFromString( g_UnitMetric, ReturnValueFromString( g_UnitMetric,
m_gridNetClassesProperties->GetCellValue( ii, m_gridNetClassesProperties->GetCellValue( ii,
RULE_GRID_MINVIASIZE_POSITION ), RULE_GRID_MINVIASIZE_POSITION ),
m_Parent->m_InternalUnits ); m_Parent->m_InternalUnits ));
// Copy the list of nets associated to this netclass: // Copy the list of nets associated to this netclass:
for( unsigned idx = 0; idx < m_StockNets.size(); idx++ ) for( unsigned idx = 0; idx < m_StockNets.size(); idx++ )
{ {
if( m_NetsLinkToClasses[idx] == ii ) if( m_NetsLinkToClasses[idx] == ii )
netclass->AddMember( m_StockNets[idx]->GetNetname() ); netclass.Add( m_StockNets[idx]->GetNetname() );
} }
// this calls copy constructor, so all data must be in 'netclass' before Add()ing.
m_Pcb->m_NetClasses.Add( netclass );
} }
m_Pcb->TransfertDesignRulesToNets(); m_Pcb->SynchronizeNetsAndNetClasses();
} }

View File

@ -437,7 +437,7 @@ void CreateSignalsSection( FILE* file, BOARD* pcb )
fputs( "$SIGNALS\n", file ); fputs( "$SIGNALS\n", file );
for( unsigned ii = 0; ii < pcb->m_NetInfo->GetNetsCount() ; ii++ ) for( unsigned ii = 0; ii < pcb->m_NetInfo->GetCount() ; ii++ )
{ {
net = pcb->m_NetInfo->GetNetItem(ii); net = pcb->m_NetInfo->GetNetItem(ii);
if( net->GetNetname() == wxEmptyString ) // dummy equipot (non connexion) if( net->GetNetname() == wxEmptyString ) // dummy equipot (non connexion)

View File

@ -637,7 +637,7 @@ bool WinEDA_PcbFrame::WriteGeneralDescrPcb( FILE* File )
fprintf( File, "LayerThickness %d\n", GetBoard()->m_BoardSettings->m_LayerThickness ); fprintf( File, "LayerThickness %d\n", GetBoard()->m_BoardSettings->m_LayerThickness );
fprintf( File, "Nmodule %d\n", NbModules ); fprintf( File, "Nmodule %d\n", NbModules );
fprintf( File, "Nnets %d\n", GetBoard()->m_NetInfo->GetNetsCount() ); fprintf( File, "Nnets %d\n", GetBoard()->m_NetInfo->GetCount() );
fprintf( File, "$EndGENERAL\n\n" ); fprintf( File, "$EndGENERAL\n\n" );
return TRUE; return TRUE;
@ -787,11 +787,14 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append )
wxBusyCursor dummy; wxBusyCursor dummy;
// Switch the locale to standard C (needed to read floating point numbers like 1.3) // Switch the locale to standard C (needed to read floating point numbers like 1.3)
SetLocaleTo_C_standard( ); SetLocaleTo_C_standard();
BOARD* board = GetBoard();
NbDraw = NbTrack = NbZone = NbMod = NbNets = -1; NbDraw = NbTrack = NbZone = NbMod = NbNets = -1;
GetBoard()->m_Status_Pcb = 0;
GetBoard()->m_NetClassesList.ClearList(); board->m_Status_Pcb = 0;
board->m_NetClasses.Clear();
while( GetLine( File, Line, &LineNum ) != NULL ) while( GetLine( File, Line, &LineNum ) != NULL )
{ {
@ -827,73 +830,72 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append )
if( strnicmp( Line, "$EQUIPOT", 7 ) == 0 ) if( strnicmp( Line, "$EQUIPOT", 7 ) == 0 )
{ {
NETINFO_ITEM* net = new NETINFO_ITEM( GetBoard() ); NETINFO_ITEM* net = new NETINFO_ITEM( board );
GetBoard()->m_NetInfo->AppendNet( net ); board->m_NetInfo->AppendNet( net );
net->ReadDescr( File, &LineNum ); net->ReadDescr( File, &LineNum );
continue; continue;
} }
if( strnicmp( Line, "$NETCLASS", 8 ) == 0 ) if( strnicmp( Line, "$NETCLASS", 8 ) == 0 )
{ {
NETCLASS* netclass = new NETCLASS( GetBoard() ); NETCLASS netclass( board, wxEmptyString );
netclass->ReadDescr( File, &LineNum );
if( ! GetBoard()->m_NetClassesList.AddNetclass( netclass ) ) netclass.ReadDescr( File, &LineNum );
delete netclass;
board->m_NetClasses.Add( netclass );
continue; continue;
} }
if( strnicmp( Line, "$CZONE_OUTLINE", 7 ) == 0 ) if( strnicmp( Line, "$CZONE_OUTLINE", 7 ) == 0 )
{ {
ZONE_CONTAINER * zone_descr = new ZONE_CONTAINER(GetBoard()); ZONE_CONTAINER * zone_descr = new ZONE_CONTAINER(board);
zone_descr->ReadDescr( File, &LineNum ); zone_descr->ReadDescr( File, &LineNum );
if ( zone_descr->GetNumCorners( ) > 2 ) // should always occur if ( zone_descr->GetNumCorners( ) > 2 ) // should always occur
GetBoard()->Add(zone_descr); board->Add(zone_descr);
else delete zone_descr; else delete zone_descr;
continue; continue;
} }
if( strnicmp( Line, "$MODULE", 7 ) == 0 ) if( strnicmp( Line, "$MODULE", 7 ) == 0 )
{ {
MODULE* Module = new MODULE( GetBoard() ); MODULE* Module = new MODULE( board );
if( Module == NULL ) if( Module == NULL )
continue; continue;
GetBoard()->Add( Module, ADD_APPEND ); board->Add( Module, ADD_APPEND );
Module->ReadDescr( File, &LineNum ); Module->ReadDescr( File, &LineNum );
continue; continue;
} }
if( strnicmp( Line, "$TEXTPCB", 8 ) == 0 ) if( strnicmp( Line, "$TEXTPCB", 8 ) == 0 )
{ {
TEXTE_PCB* pcbtxt = new TEXTE_PCB( GetBoard() ); TEXTE_PCB* pcbtxt = new TEXTE_PCB( board );
GetBoard()->Add( pcbtxt, ADD_APPEND ); board->Add( pcbtxt, ADD_APPEND );
pcbtxt->ReadTextePcbDescr( File, &LineNum ); pcbtxt->ReadTextePcbDescr( File, &LineNum );
continue; continue;
} }
if( strnicmp( Line, "$DRAWSEGMENT", 10 ) == 0 ) if( strnicmp( Line, "$DRAWSEGMENT", 10 ) == 0 )
{ {
DRAWSEGMENT* DrawSegm = new DRAWSEGMENT( GetBoard() ); DRAWSEGMENT* DrawSegm = new DRAWSEGMENT( board );
GetBoard()->Add( DrawSegm, ADD_APPEND ); board->Add( DrawSegm, ADD_APPEND );
DrawSegm->ReadDrawSegmentDescr( File, &LineNum ); DrawSegm->ReadDrawSegmentDescr( File, &LineNum );
continue; continue;
} }
if( strnicmp( Line, "$COTATION", 9 ) == 0 ) if( strnicmp( Line, "$COTATION", 9 ) == 0 )
{ {
COTATION* Cotation = new COTATION( GetBoard() ); COTATION* Cotation = new COTATION( board );
GetBoard()->Add( Cotation, ADD_APPEND ); board->Add( Cotation, ADD_APPEND );
Cotation->ReadCotationDescr( File, &LineNum ); Cotation->ReadCotationDescr( File, &LineNum );
continue; continue;
} }
if( strnicmp( Line, "$MIREPCB", 8 ) == 0 ) if( strnicmp( Line, "$MIREPCB", 8 ) == 0 )
{ {
MIREPCB* Mire = new MIREPCB( GetBoard() ); MIREPCB* Mire = new MIREPCB( board );
GetBoard()->Add( Mire, ADD_APPEND ); board->Add( Mire, ADD_APPEND );
Mire->ReadMirePcbDescr( File, &LineNum ); Mire->ReadMirePcbDescr( File, &LineNum );
continue; continue;
} }
@ -901,7 +903,7 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append )
if( strnicmp( Line, "$TRACK", 6 ) == 0 ) if( strnicmp( Line, "$TRACK", 6 ) == 0 )
{ {
#ifdef PCBNEW #ifdef PCBNEW
TRACK* insertBeforeMe = Append ? NULL : GetBoard()->m_Track.GetFirst(); TRACK* insertBeforeMe = Append ? NULL : board->m_Track.GetFirst();
ReadListeSegmentDescr( File, insertBeforeMe, TYPE_TRACK, ReadListeSegmentDescr( File, insertBeforeMe, TYPE_TRACK,
&LineNum, NbTrack ); &LineNum, NbTrack );
#endif #endif
@ -911,7 +913,7 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append )
if( strnicmp( Line, "$ZONE", 5 ) == 0 ) if( strnicmp( Line, "$ZONE", 5 ) == 0 )
{ {
#ifdef PCBNEW #ifdef PCBNEW
SEGZONE* insertBeforeMe = Append ? NULL : GetBoard()->m_Zone.GetFirst(); SEGZONE* insertBeforeMe = Append ? NULL : board->m_Zone.GetFirst();
ReadListeSegmentDescr( File, insertBeforeMe, TYPE_ZONE, ReadListeSegmentDescr( File, insertBeforeMe, TYPE_ZONE,
&LineNum, NbZone ); &LineNum, NbZone );
@ -926,16 +928,8 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append )
BestZoom(); BestZoom();
// One netclass *must* exists (the default netclass) board->SynchronizeNetsAndNetClasses( );
if( GetBoard()->m_NetClassesList.GetNetClassCount() == 0 ) board->m_Status_Pcb = 0;
{
NETCLASS* ncdefault = new NETCLASS(GetBoard());
GetBoard()->m_NetClassesList.AddNetclass( ncdefault );
}
GetBoard()->TransfertDesignRulesToNets( );
GetBoard()->m_Status_Pcb = 0;
return 1; return 1;
} }
@ -970,6 +964,8 @@ int WinEDA_PcbFrame::SavePcbFormatAscii( FILE* aFile )
WriteSheetDescr( GetScreen(), aFile ); WriteSheetDescr( GetScreen(), aFile );
WriteSetup( aFile, this, GetBoard() ); WriteSetup( aFile, this, GetBoard() );
GetBoard()->SynchronizeNetsAndNetClasses();
rc = GetBoard()->Save( aFile ); rc = GetBoard()->Save( aFile );
SetLocaleTo_Default( ); // revert to the current locale SetLocaleTo_Default( ); // revert to the current locale

View File

@ -119,7 +119,7 @@ void WinEDA_BasePcbFrame::Compile_Ratsnest( wxDC* DC, bool display_status_pcb )
if( display_status_pcb ) if( display_status_pcb )
{ {
msg.Printf( wxT( " %d" ), m_Pcb->m_NetInfo->GetNetsCount() ); msg.Printf( wxT( " %d" ), m_Pcb->m_NetInfo->GetCount() );
Affiche_1_Parametre( this, 8, wxT( "Nets" ), msg, CYAN ); Affiche_1_Parametre( this, 8, wxT( "Nets" ), msg, CYAN );
} }
@ -427,7 +427,7 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
unsigned current_net_code = 1; // 1er net_code a analyser (net_code = 0 -> no connect) unsigned current_net_code = 1; // 1er net_code a analyser (net_code = 0 -> no connect)
noconn = 0; noconn = 0;
for( ; current_net_code < m_Pcb->m_NetInfo->GetNetsCount(); current_net_code++ ) for( ; current_net_code < m_Pcb->m_NetInfo->GetCount(); current_net_code++ )
{ {
NETINFO_ITEM* net = m_Pcb->FindNet( current_net_code ); NETINFO_ITEM* net = m_Pcb->FindNet( current_net_code );
if( net == NULL ) //Should not occur if( net == NULL ) //Should not occur
@ -661,7 +661,7 @@ void WinEDA_BasePcbFrame::Tst_Ratsnest( wxDC* DC, int ref_netcode )
if( (m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 ) if( (m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 )
Build_Board_Ratsnest( DC ); Build_Board_Ratsnest( DC );
for( int net_code = 1; net_code < (int) m_Pcb->m_NetInfo->GetNetsCount(); net_code++ ) for( int net_code = 1; net_code < (int) m_Pcb->m_NetInfo->GetCount(); net_code++ )
{ {
net = m_Pcb->FindNet( net_code ); net = m_Pcb->FindNet( net_code );
if( net == NULL ) //Should not occur if( net == NULL ) //Should not occur

View File

@ -1114,7 +1114,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
int highestNetCode = -1; int highestNetCode = -1;
// for( EQUIPOT* equipot = aBoard->m_Equipots; equipot; equipot = equipot->Next() ) // for( EQUIPOT* equipot = aBoard->m_Equipots; equipot; equipot = equipot->Next() )
// highestNetCode = MAX( highestNetCode, equipot->GetNet() ); // highestNetCode = MAX( highestNetCode, equipot->GetNet() );
highestNetCode = aBoard->m_NetInfo->GetNetsCount() - 1; highestNetCode = aBoard->m_NetInfo->GetCount() - 1;
deleteNETs(); deleteNETs();
// expand the net vector to highestNetCode+1, setting empty to NULL // expand the net vector to highestNetCode+1, setting empty to NULL
@ -1124,7 +1124,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
for( unsigned i=1; i<nets.size(); ++i ) for( unsigned i=1; i<nets.size(); ++i )
nets[i] = new NET( pcb->network ); nets[i] = new NET( pcb->network );
for( unsigned ii = 0; ii < aBoard->m_NetInfo->GetNetsCount(); ii++ ) for( unsigned ii = 0; ii < aBoard->m_NetInfo->GetCount(); ii++ )
{ {
NETINFO_ITEM* net = aBoard->m_NetInfo->GetNetItem(ii); NETINFO_ITEM* net = aBoard->m_NetInfo->GetNetItem(ii);
int netcode = net->GetNet(); int netcode = net->GetNet();

View File

@ -37,7 +37,7 @@ void WinEDA_PcbFrame::ListNetsAndSelect( wxCommandEvent& event )
WinEDA_TextFrame List( this, _( "List Nets" ) ); WinEDA_TextFrame List( this, _( "List Nets" ) );
for( unsigned ii = 0; ii < GetBoard()->m_NetInfo->GetNetsCount(); ii++ ) for( unsigned ii = 0; ii < GetBoard()->m_NetInfo->GetCount(); ii++ )
{ {
net = GetBoard()->m_NetInfo->GetNetItem( ii ); net = GetBoard()->m_NetInfo->GetNetItem( ii );
wxString Line; wxString Line;
@ -58,7 +58,7 @@ void WinEDA_PcbFrame::ListNetsAndSelect( wxCommandEvent& event )
unsigned netcode = (unsigned) selection; unsigned netcode = (unsigned) selection;
// Search for the net selected. // Search for the net selected.
for( unsigned ii = 0; ii < GetBoard()->m_NetInfo->GetNetsCount(); ii++ ) for( unsigned ii = 0; ii < GetBoard()->m_NetInfo->GetCount(); ii++ )
{ {
net = GetBoard()->m_NetInfo->GetNetItem( ii ); net = GetBoard()->m_NetInfo->GetNetItem( ii );
if( !WildCompareString( netFilter, net->GetNetname(), false ) ) if( !WildCompareString( netFilter, net->GetNetname(), false ) )