From 85dc98a58aec05dff87f5f0fbc4a159833516c28 Mon Sep 17 00:00:00 2001 From: dickelbeck Date: Mon, 17 Aug 2009 02:59:38 +0000 Subject: [PATCH] more netclass work --- CHANGELOG.txt | 18 ++ include/board_item_struct.h | 23 ++ pcbnew/class_board.cpp | 26 +- pcbnew/class_board.h | 8 +- pcbnew/class_board_connected_item.cpp | 47 +++ pcbnew/class_board_item.cpp | 8 + pcbnew/class_netclass.cpp | 438 +++++++++++++++----------- pcbnew/class_netclass.h | 289 +++++++++++------ pcbnew/class_netinfo.h | 100 +++--- pcbnew/class_netinfo_item.cpp | 11 +- pcbnew/class_netinfolist.cpp | 7 +- pcbnew/dialog_design_rules.cpp | 61 ++-- pcbnew/export_gencad.cpp | 2 +- pcbnew/ioascii.cpp | 64 ++-- pcbnew/ratsnest.cpp | 6 +- pcbnew/specctra_export.cpp | 4 +- pcbnew/surbrill.cpp | 4 +- 17 files changed, 710 insertions(+), 406 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index cf215a3f59..8ceb89c62d 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -4,6 +4,24 @@ KiCad ChangeLog 2009 Please add newer entries at the top, list the date and your name with email address. +2009-Aug-16 UPDATE Dick Hollenbeck +================================================================================ +++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 ================================================================================ ++pcbnew diff --git a/include/board_item_struct.h b/include/board_item_struct.h index 5e496846d7..474429bf4f 100644 --- a/include/board_item_struct.h +++ b/include/board_item_struct.h @@ -189,6 +189,7 @@ public: { wxMessageBox(wxT("virtual BOARD_ITEM::Move used, should not occur"), GetClass()); } + /** * Function Rotate * Rotate this object. @@ -199,6 +200,7 @@ public: { wxMessageBox(wxT("virtual BOARD_ITEM::Rotate used, should not occur"), GetClass()); } + /** * Function Flip * 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()); } + + + /** + * 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 @@ -253,6 +263,19 @@ public: */ int GetZoneSubNet() const; 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; }; diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index c91361a676..1586813a45 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -20,7 +20,7 @@ wxPoint BOARD_ITEM::ZeroOffset( 0, 0 ); /* Constructor */ BOARD::BOARD( EDA_BaseStruct* parent, WinEDA_BasePcbFrame* frame ) : BOARD_ITEM( (BOARD_ITEM*)parent, TYPE_PCB ), - m_NetClassesList(this) + m_NetClasses(this) { m_PcbFrame = frame; 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_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() ); 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 ); /* 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 { - // 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. // NULL is returned for non valid netcodes 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. 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 ); 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 ) { - if( m_NetInfo->GetNetsCount() == 0 ) + if( m_NetInfo->GetCount() == 0 ) return 0; // Build the list std::vector 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 ) netBuffer.push_back( m_NetInfo->GetNetItem( ii ) ); @@ -941,14 +937,14 @@ bool BOARD::Save( FILE* aFile ) const bool rc = false; BOARD_ITEM* item; - // save the netclasses - m_NetClassesList.Save( aFile ); - // 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 ) ) goto out; + // Saved nets do not include netclass names, so save netclasses after nets. + m_NetClasses.Save( aFile ); + // save the modules for( item = m_Modules; item; item = item->Next() ) if( !item->Save( aFile ) ) diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index f976b8fe3d..e8858ae9db 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -97,7 +97,7 @@ public: std::vector m_LocalRatsnest; /* Rastnest list relative to a given 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 @@ -338,15 +338,15 @@ public: int ReturnSortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount ); /** - * Function TransfertDesignRulesToNets - * copies Netclass parameters to each net, corresponding to its net class. + * Function SynchronizeNetsAndNetClasses + * 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) * Also this function removes the non existing nets in netclasses and add net nets in default netclass * (this happens after reading a netlist) * @param none * @return none */ - void TransfertDesignRulesToNets(); + void SynchronizeNetsAndNetClasses(); /** * Function Save diff --git a/pcbnew/class_board_connected_item.cpp b/pcbnew/class_board_connected_item.cpp index 7356a89182..e5e5b418a6 100644 --- a/pcbnew/class_board_connected_item.cpp +++ b/pcbnew/class_board_connected_item.cpp @@ -68,3 +68,50 @@ void BOARD_CONNECTED_ITEM::SetZoneSubNet( int 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; +} diff --git a/pcbnew/class_board_item.cpp b/pcbnew/class_board_item.cpp index 35c6461f2d..710e5c8bb7 100644 --- a/pcbnew/class_board_item.cpp +++ b/pcbnew/class_board_item.cpp @@ -315,3 +315,11 @@ void BOARD_ITEM::UnLink() list->Remove( this ); } + +BOARD* BOARD_ITEM::GetBoard() const +{ + // overload this function as needed. + + return (BOARD*) GetParent(); +} + diff --git a/pcbnew/class_netclass.cpp b/pcbnew/class_netclass.cpp index eb683606a6..0d09bf74df 100644 --- a/pcbnew/class_netclass.cpp +++ b/pcbnew/class_netclass.cpp @@ -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 + * 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" @@ -9,25 +31,25 @@ #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_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_TrackWidth = 160; + m_TrackMinWidth = 40; -/* A NETCLASS handles a list of nets and the parameters used to route or test (in DRC) these nets - * This is mainly used in autotouters like Freeroute, but this can be also used in manual routing - */ + m_ViaSize = 350; -NETCLASS::NETCLASS( BOARD* aParent, const wxString& aName ) -{ - m_Parent = aParent; - m_Name = aName; // Name of the net class + m_ViaMinSize = 220; + + m_ViaDrillSize = 200; + + 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 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 - for( unsigned ii = 0; ii < m_Netclass_List.size(); ii++ ) - delete m_Netclass_List[ii]; + // Although std::map<> will destroy the items that it contains, in this + // case we have NETCLASS* (pointers) and "destroying" a pointer does not + // 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() - * @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 ) +bool NETCLASSES::Add( const 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: - 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 ) - return false; // this netclass already exists + // insert since name not found, invoke copy constructor. + m_NetClasses[name] = new NETCLASS( aNetClass ); + return true; } - m_Netclass_List.push_back( aNetclass ); - return true; + return false; // name already exists } -void BOARD::TransfertDesignRulesToNets() +NETCLASS* NETCLASSES::Remove( const wxString& aNetName ) { - // Clear .m_Flag member of nets (used to detect not in netclass list nets) - for( unsigned ii = 1; ; ii++ ) - { - NETINFO_ITEM* net = FindNet( ii ); - if( net == NULL ) - break; + NETCLASSMAP::iterator found = m_NetClasses.find( aNetName ); - 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; iSetClass( 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 ); - NETINFO_ITEM* net = FindNet( netname ); + const wxString& netname = *member; - 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 ); - jj--; + NETCLASS::iterator e = member++; + 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 { - net->SetClass( *netclass ); - net->m_Flag = 1; + net->SetClass( netclass ); + ++member; } } } - // Now, set nets that do not have yet a netclass to default netclass - NETCLASS* defaultnetclass = m_NetClassesList.GetNetClass( 0 ); + // Finally, make sure that every NET is in a NETCLASS, even if that + // 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 ) - break; + netclass->Clear(); + } - if( net->m_Flag == 0 ) + m_NetClasses.GetDefault()->Clear(); + + for( int i=0; iSetClass( *defaultnetclass ); - defaultnetclass->AddMember( net->GetNetname() ); + const wxString& classname = net->GetClassName(); + + // 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");) } -/** - * 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 NETCLASSES::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 ); - if( !success ) - break; + // the rest will be alphabetical in the *.brd file. + for( const_iterator i = begin(); i!=end(); ++i ) + { + 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 success = true; + bool result = true; fprintf( aFile, "$NETCLASS\n" ); fprintf( aFile, "Name \"%s\"\n", CONV_TO_UTF8( m_Name ) ); + fprintf( aFile, "Desc \"%s\"\n", CONV_TO_UTF8( GetDescription() ) ); + // 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: - for( unsigned ii = 0; ii < GetMembersCount(); ii++ ) - fprintf( aFile, "AddNet \"%s\"\n", CONV_TO_UTF8( GetMemberName( ii ) ) ); + // Write members: + for( const_iterator i = begin(); i!=end(); ++i ) + fprintf( aFile, "AddNet \"%s\"\n", CONV_TO_UTF8( *i ) ); fprintf( aFile, "$EndNETCLASS\n" ); - 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 NET_DESIGN_PARAMS::Save( FILE* aFile ) const +#if defined(DEBUG) + +void NETCLASS::Show( int nestLevel, std::ostream& os ) { - bool success = true; + // for now, make it look like XML: + //NestedSpace( nestLevel, os ) - fprintf( aFile, "$PARAMS_START\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" ); + os << '<' << GetClass().Lower().mb_str() << ">\n"; - return success; -} - - -/** - * 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 ) + for( const_iterator i = begin(); i!=end(); ++i ) { - if( strnicmp( Line, "$PARAMS_END", 11 ) == 0 ) - return success; - - 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; - } + // NestedSpace( nestLevel+1, os ) << *i; + os << *i; } - return success; + // NestedSpace( nestLevel, os ) + os << "\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 success = true; - char Line[1024]; - char Buffer[1024]; + bool result = false; + char Line[1024]; + char Buffer[1024]; + wxString netname; while( GetLine( aFile, Line, aLineNum, 1024 ) != NULL ) { - if( strnicmp( Line, "$endNETCLASS", 6 ) == 0 ) - return success; - - if( strnicmp( Line, "$PARAMS_START", 13 ) == 0 ) + if( strnicmp( Line, "AddNet", 6 ) == 0 ) { - m_NetParams.ReadDescr( aFile, aLineNum ); + ReadDelimitedText( Buffer, Line + 6, sizeof(Buffer) ); + netname = CONV_FROM_UTF8( Buffer ); + Add( netname ); 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 ) { ReadDelimitedText( Buffer, Line + 4, sizeof(Buffer) ); m_Name = CONV_FROM_UTF8( Buffer ); + continue; } - - if( strnicmp( Line, "AddNet", 6 ) == 0 ) + if( strnicmp( Line, "Desc", 4 ) == 0 ) { - ReadDelimitedText( Buffer, Line + 6, sizeof(Buffer) ); - wxString netname = CONV_FROM_UTF8( Buffer ); - AddMember( netname ); + ReadDelimitedText( Buffer, Line + 4, sizeof(Buffer) ); + SetDescription( CONV_FROM_UTF8( Buffer ) ); + continue; } } - return success; + return result; } diff --git a/pcbnew/class_netclass.h b/pcbnew/class_netclass.h index 54fb421a74..f2ffa5fb82 100644 --- a/pcbnew/class_netclass.h +++ b/pcbnew/class_netclass.h @@ -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 + * 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 #define CLASS_NETCLASS_H - -/** - * 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 ); -}; +#include +#include /** * 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 { -public: - 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 +protected: + BOARD* m_Parent; + wxString m_Name; ///< Name of the net class + wxString m_Description; ///< what this NETCLASS is for. + + typedef std::set 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: - 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(); + wxString GetClass() const + { + return wxT( "NETCLASS" ); + } + + const wxString& GetName() const + { + return m_Name; + } + /** - * Function GetMembersCount - * returns the number of nets using this rule + * Function GetCount + * 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() ) - return m_MembersNetNames[aIdx]; - else - return wxEmptyString; + m_Members.erase( aName ); } + /** + * 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 @@ -113,55 +168,99 @@ public: * @return bool - true if success reading else false. */ 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 - * Note: the NETCLASS_LIST is owner of all NETCLASS in list + * Class NETCLASSES + * 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: - BOARD* m_Parent; - std::vector m_Netclass_List; +private: + BOARD* m_Parent; + typedef std::map NETCLASSMAP; + + /// all the NETCLASSes except the default one. + NETCLASSMAP m_NetClasses; + + /// the default NETCLASS. + NETCLASS m_Default; public: - NETCLASS_LIST( BOARD* aParent = NULL ); - ~NETCLASS_LIST(); - - - void ClearList(); + NETCLASSES( BOARD* aParent = NULL ); + ~NETCLASSES(); /** - * Function GetNetClassCount() - * @return the number of existing netclasses + * Function Clear + * 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 - * @return a NETCLASS* pointer on the netclass + /** + * Function Add + * @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 ) - { - if( GetNetClassCount() && aIdx < GetNetClassCount() ) - return m_Netclass_List[aIdx]; - else - return NULL; - } + bool Add( const NETCLASS& aNetclass ); - - /** Function AddNetclass() - * @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) + /** + * Function Remove + * removes a NETCLASS from this container but does not destroy/delete it. + * @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 @@ -172,5 +271,5 @@ public: bool Save( FILE* aFile ) const; }; - #endif // CLASS_NETCLASS_H + diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h index 9cbc8ac795..df53c9a936 100644 --- a/pcbnew/class_netinfo.h +++ b/pcbnew/class_netinfo.h @@ -85,11 +85,12 @@ public: */ NETINFO_ITEM* GetNetItem( int aNetcode ); - /** Function GetCount() + /** + * Function GetCount * @return the number of nets ( always >= 1 ) * 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 @@ -152,12 +153,15 @@ class NETINFO_ITEM private: int m_NetCode; // this is a number equivalent to the net name // Used for fast comparisons in rastnest and DRC computations. + 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_NetClassName; // Net Class name. if void this is equivalent to "default" (the first // item of the net classes list - NET_DESIGN_PARAMS m_NetParams; // values of net classes parameters + NETCLASS* m_NetClass; public: @@ -177,83 +181,97 @@ public: NETINFO_ITEM( BOARD_ITEM* aParent ); ~NETINFO_ITEM(); - - /** Functions SetClassParameters - * copy the class parameters in the locale buffer m_NetParams + /** + * Function SetClass + * 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 - * copy the class Name and class parmeters - */ - void SetClass(const NETCLASS& aNetclass ) + NETCLASS* GetNetClass() { - m_NetParams = aNetclass.m_NetParams; - m_NetClassName = aNetclass.m_Name; + return m_NetClass; } - /** Functions GetClassName - * @return the class Name + /** + * Function GetClassName + * returns the class name */ - wxString GetClassName( ) const + const wxString& GetClassName( ) const { 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(); } diff --git a/pcbnew/class_netinfo_item.cpp b/pcbnew/class_netinfo_item.cpp index 6a00db8396..b7d9cba66a 100644 --- a/pcbnew/class_netinfo_item.cpp +++ b/pcbnew/class_netinfo_item.cpp @@ -23,13 +23,16 @@ NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent ) m_Flag = 0; 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_NetClassName = NETCLASS::Default; + + m_NetClass = 0; } -/* destructor */ - NETINFO_ITEM::~NETINFO_ITEM() { + // m_NetClass is not owned by me. } @@ -60,12 +63,14 @@ int NETINFO_ITEM:: ReadDescr( FILE* File, int* LineNum ) continue; } + /* if( strncmp( Line, "NetClass", 8 ) == 0 ) { ReadDelimitedText( Ltmp, Line + 8, sizeof(Ltmp) ); m_NetClassName = CONV_FROM_UTF8( Ltmp ); continue; } + */ } 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, "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 ) goto out; diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp index b3e9fb8bda..526cfde420 100644 --- a/pcbnew/class_netinfolist.cpp +++ b/pcbnew/class_netinfolist.cpp @@ -29,7 +29,7 @@ NETINFO_LIST::~NETINFO_LIST() */ NETINFO_ITEM* NETINFO_LIST::GetNetItem( int aNetcode ) { - if( aNetcode < 0 || ( aNetcode > (int) ( GetNetsCount() - 1 ) ) ) + if( aNetcode < 0 || ( aNetcode > (int) ( GetCount() - 1 ) ) ) return NULL; return m_NetBuffer[aNetcode]; } @@ -40,7 +40,7 @@ NETINFO_ITEM* NETINFO_LIST::GetNetItem( int aNetcode ) */ void NETINFO_LIST::DeleteData() { - for( unsigned ii = 0; ii < GetNetsCount(); ii++ ) + for( unsigned ii = 0; ii < GetCount(); ii++ ) delete m_NetBuffer[ii]; m_NetBuffer.clear(); @@ -125,7 +125,8 @@ void NETINFO_LIST::BuildListOfNets() } m_Parent->m_NbNodes = nodes_count; - m_Parent->TransfertDesignRulesToNets( ); + + m_Parent->SynchronizeNetsAndNetClasses( ); m_Parent->m_Status_Pcb |= NET_CODES_OK; diff --git a/pcbnew/dialog_design_rules.cpp b/pcbnew/dialog_design_rules.cpp index e7d893e804..238a59d112 100644 --- a/pcbnew/dialog_design_rules.cpp +++ b/pcbnew/dialog_design_rules.cpp @@ -202,39 +202,44 @@ void DIALOG_DESIGN_RULES::SetRoutableLayerStatus() */ 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 ); - if( netclass == NULL ) - break; + NETCLASS* netclass = i->second; // Creates one entry if needed if( ii >= m_gridNetClassesProperties->GetNumberRows() ) m_gridNetClassesProperties->AppendRows(); // Init name - m_gridNetClassesProperties->SetRowLabelValue( ii, netclass->m_Name ); + m_gridNetClassesProperties->SetRowLabelValue( ii, netclass->GetName() ); // Init data wxString msg; msg = ReturnStringFromValue( g_UnitMetric, - netclass->m_NetParams.m_TracksWidth, + netclass->GetTrackWidth(), m_Parent->m_InternalUnits, false ); m_gridNetClassesProperties->SetCellValue( ii, RULE_GRID_TRACKSIZE_POSITION, msg ); + msg = ReturnStringFromValue( g_UnitMetric, - netclass->m_NetParams.m_ViasSize, + netclass->GetViaSize(), m_Parent->m_InternalUnits, false ); m_gridNetClassesProperties->SetCellValue( ii, RULE_GRID_VIASIZE_POSITION, msg ); + msg = ReturnStringFromValue( g_UnitMetric, - netclass->m_NetParams.m_Clearance, + netclass->GetClearance(), m_Parent->m_InternalUnits, false ); m_gridNetClassesProperties->SetCellValue( ii, RULE_GRID_CLEARANCE_POSITION, msg ); + msg = ReturnStringFromValue( g_UnitMetric, - netclass->m_NetParams.m_TracksMinWidth, + netclass->GetTrackMinWidth(), m_Parent->m_InternalUnits, false ); m_gridNetClassesProperties->SetCellValue( ii, RULE_GRID_MINTRACKSIZE_POSITION, msg ); + msg = ReturnStringFromValue( g_UnitMetric, - netclass->m_NetParams.m_ViasMinSize, + netclass->GetViaMinSize(), m_Parent->m_InternalUnits, false ); m_gridNetClassesProperties->SetCellValue( ii, RULE_GRID_MINVIASIZE_POSITION, msg ); } @@ -245,53 +250,57 @@ void DIALOG_DESIGN_RULES::InitRulesList() */ 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++ ) { - NETCLASS* netclass = new NETCLASS( m_Pcb, - m_gridNetClassesProperties->GetRowLabelValue( ii ) ); - m_Pcb->m_NetClassesList.AddNetclass( netclass ); + NETCLASS netclass( m_Pcb, m_gridNetClassesProperties->GetRowLabelValue( ii ) ); // Init data - netclass->m_NetParams.m_TracksWidth = + netclass.SetTrackWidth( ReturnValueFromString( g_UnitMetric, m_gridNetClassesProperties->GetCellValue( ii, RULE_GRID_TRACKSIZE_POSITION ), - m_Parent->m_InternalUnits ); + m_Parent->m_InternalUnits )); - netclass->m_NetParams.m_ViasSize = + netclass.SetViaSize( ReturnValueFromString( g_UnitMetric, m_gridNetClassesProperties->GetCellValue( ii, RULE_GRID_VIASIZE_POSITION ), - m_Parent->m_InternalUnits ); + m_Parent->m_InternalUnits )); - netclass->m_NetParams.m_Clearance = + netclass.SetClearance( ReturnValueFromString( g_UnitMetric, m_gridNetClassesProperties->GetCellValue( ii, RULE_GRID_CLEARANCE_POSITION ), - m_Parent->m_InternalUnits ); + m_Parent->m_InternalUnits )); - netclass->m_NetParams.m_TracksMinWidth = + netclass.SetTrackMinWidth( ReturnValueFromString( g_UnitMetric, m_gridNetClassesProperties->GetCellValue( ii, RULE_GRID_MINTRACKSIZE_POSITION ), - m_Parent->m_InternalUnits ); + m_Parent->m_InternalUnits )); - netclass->m_NetParams.m_ViasMinSize = + netclass.SetViaMinSize( ReturnValueFromString( g_UnitMetric, m_gridNetClassesProperties->GetCellValue( ii, RULE_GRID_MINVIASIZE_POSITION ), - m_Parent->m_InternalUnits ); + m_Parent->m_InternalUnits )); // Copy the list of nets associated to this netclass: for( unsigned idx = 0; idx < m_StockNets.size(); idx++ ) { 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(); } diff --git a/pcbnew/export_gencad.cpp b/pcbnew/export_gencad.cpp index 008a929ebc..6c8727177a 100644 --- a/pcbnew/export_gencad.cpp +++ b/pcbnew/export_gencad.cpp @@ -437,7 +437,7 @@ void CreateSignalsSection( FILE* file, BOARD* pcb ) 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); if( net->GetNetname() == wxEmptyString ) // dummy equipot (non connexion) diff --git a/pcbnew/ioascii.cpp b/pcbnew/ioascii.cpp index 133024bb01..fa5c0335f7 100644 --- a/pcbnew/ioascii.cpp +++ b/pcbnew/ioascii.cpp @@ -637,7 +637,7 @@ bool WinEDA_PcbFrame::WriteGeneralDescrPcb( FILE* File ) fprintf( File, "LayerThickness %d\n", GetBoard()->m_BoardSettings->m_LayerThickness ); 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" ); return TRUE; @@ -787,11 +787,14 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append ) wxBusyCursor dummy; // 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; - GetBoard()->m_Status_Pcb = 0; - GetBoard()->m_NetClassesList.ClearList(); + + board->m_Status_Pcb = 0; + board->m_NetClasses.Clear(); while( GetLine( File, Line, &LineNum ) != NULL ) { @@ -827,73 +830,72 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append ) if( strnicmp( Line, "$EQUIPOT", 7 ) == 0 ) { - NETINFO_ITEM* net = new NETINFO_ITEM( GetBoard() ); - GetBoard()->m_NetInfo->AppendNet( net ); + NETINFO_ITEM* net = new NETINFO_ITEM( board ); + board->m_NetInfo->AppendNet( net ); net->ReadDescr( File, &LineNum ); continue; } if( strnicmp( Line, "$NETCLASS", 8 ) == 0 ) { - NETCLASS* netclass = new NETCLASS( GetBoard() ); - netclass->ReadDescr( File, &LineNum ); + NETCLASS netclass( board, wxEmptyString ); - if( ! GetBoard()->m_NetClassesList.AddNetclass( netclass ) ) - delete netclass; + netclass.ReadDescr( File, &LineNum ); + board->m_NetClasses.Add( netclass ); continue; } 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 ); if ( zone_descr->GetNumCorners( ) > 2 ) // should always occur - GetBoard()->Add(zone_descr); + board->Add(zone_descr); else delete zone_descr; continue; } if( strnicmp( Line, "$MODULE", 7 ) == 0 ) { - MODULE* Module = new MODULE( GetBoard() ); + MODULE* Module = new MODULE( board ); if( Module == NULL ) continue; - GetBoard()->Add( Module, ADD_APPEND ); + board->Add( Module, ADD_APPEND ); Module->ReadDescr( File, &LineNum ); continue; } if( strnicmp( Line, "$TEXTPCB", 8 ) == 0 ) { - TEXTE_PCB* pcbtxt = new TEXTE_PCB( GetBoard() ); - GetBoard()->Add( pcbtxt, ADD_APPEND ); + TEXTE_PCB* pcbtxt = new TEXTE_PCB( board ); + board->Add( pcbtxt, ADD_APPEND ); pcbtxt->ReadTextePcbDescr( File, &LineNum ); continue; } if( strnicmp( Line, "$DRAWSEGMENT", 10 ) == 0 ) { - DRAWSEGMENT* DrawSegm = new DRAWSEGMENT( GetBoard() ); - GetBoard()->Add( DrawSegm, ADD_APPEND ); + DRAWSEGMENT* DrawSegm = new DRAWSEGMENT( board ); + board->Add( DrawSegm, ADD_APPEND ); DrawSegm->ReadDrawSegmentDescr( File, &LineNum ); continue; } if( strnicmp( Line, "$COTATION", 9 ) == 0 ) { - COTATION* Cotation = new COTATION( GetBoard() ); - GetBoard()->Add( Cotation, ADD_APPEND ); + COTATION* Cotation = new COTATION( board ); + board->Add( Cotation, ADD_APPEND ); Cotation->ReadCotationDescr( File, &LineNum ); continue; } if( strnicmp( Line, "$MIREPCB", 8 ) == 0 ) { - MIREPCB* Mire = new MIREPCB( GetBoard() ); - GetBoard()->Add( Mire, ADD_APPEND ); + MIREPCB* Mire = new MIREPCB( board ); + board->Add( Mire, ADD_APPEND ); Mire->ReadMirePcbDescr( File, &LineNum ); continue; } @@ -901,7 +903,7 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append ) if( strnicmp( Line, "$TRACK", 6 ) == 0 ) { #ifdef PCBNEW - TRACK* insertBeforeMe = Append ? NULL : GetBoard()->m_Track.GetFirst(); + TRACK* insertBeforeMe = Append ? NULL : board->m_Track.GetFirst(); ReadListeSegmentDescr( File, insertBeforeMe, TYPE_TRACK, &LineNum, NbTrack ); #endif @@ -911,7 +913,7 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append ) if( strnicmp( Line, "$ZONE", 5 ) == 0 ) { #ifdef PCBNEW - SEGZONE* insertBeforeMe = Append ? NULL : GetBoard()->m_Zone.GetFirst(); + SEGZONE* insertBeforeMe = Append ? NULL : board->m_Zone.GetFirst(); ReadListeSegmentDescr( File, insertBeforeMe, TYPE_ZONE, &LineNum, NbZone ); @@ -926,16 +928,8 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append ) BestZoom(); - // One netclass *must* exists (the default netclass) - if( GetBoard()->m_NetClassesList.GetNetClassCount() == 0 ) - { - NETCLASS* ncdefault = new NETCLASS(GetBoard()); - GetBoard()->m_NetClassesList.AddNetclass( ncdefault ); - } - - - GetBoard()->TransfertDesignRulesToNets( ); - GetBoard()->m_Status_Pcb = 0; + board->SynchronizeNetsAndNetClasses( ); + board->m_Status_Pcb = 0; return 1; } @@ -970,6 +964,8 @@ int WinEDA_PcbFrame::SavePcbFormatAscii( FILE* aFile ) WriteSheetDescr( GetScreen(), aFile ); WriteSetup( aFile, this, GetBoard() ); + GetBoard()->SynchronizeNetsAndNetClasses(); + rc = GetBoard()->Save( aFile ); SetLocaleTo_Default( ); // revert to the current locale diff --git a/pcbnew/ratsnest.cpp b/pcbnew/ratsnest.cpp index 3bb13d4a80..4430a67009 100644 --- a/pcbnew/ratsnest.cpp +++ b/pcbnew/ratsnest.cpp @@ -119,7 +119,7 @@ void WinEDA_BasePcbFrame::Compile_Ratsnest( wxDC* DC, bool 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 ); } @@ -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) 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 ); 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 ) 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 ); if( net == NULL ) //Should not occur diff --git a/pcbnew/specctra_export.cpp b/pcbnew/specctra_export.cpp index c55badb224..10a07b1fce 100644 --- a/pcbnew/specctra_export.cpp +++ b/pcbnew/specctra_export.cpp @@ -1114,7 +1114,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) int highestNetCode = -1; // for( EQUIPOT* equipot = aBoard->m_Equipots; equipot; equipot = equipot->Next() ) // highestNetCode = MAX( highestNetCode, equipot->GetNet() ); - highestNetCode = aBoard->m_NetInfo->GetNetsCount() - 1; + highestNetCode = aBoard->m_NetInfo->GetCount() - 1; deleteNETs(); // 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; inetwork ); - 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); int netcode = net->GetNet(); diff --git a/pcbnew/surbrill.cpp b/pcbnew/surbrill.cpp index de68160fda..603c835e20 100644 --- a/pcbnew/surbrill.cpp +++ b/pcbnew/surbrill.cpp @@ -37,7 +37,7 @@ void WinEDA_PcbFrame::ListNetsAndSelect( wxCommandEvent& event ) 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 ); wxString Line; @@ -58,7 +58,7 @@ void WinEDA_PcbFrame::ListNetsAndSelect( wxCommandEvent& event ) unsigned netcode = (unsigned) selection; // 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 ); if( !WildCompareString( netFilter, net->GetNetname(), false ) )