bool BOARD_DESIGN_SETTINGS::SetCurrentNetClass( const wxString& aNetClassName ) { NETCLASSPTR netClass = m_NetClasses.Find( aNetClassName ); bool lists_sizes_modified = false; // if not found (should not happen) use the default if( netClass == NULL ) netClass = m_NetClasses.GetDefault(); m_currentNetClassName = netClass->GetName(); // Initialize others values: if( m_ViasDimensionsList.size() == 0 ) { VIA_DIMENSION viadim; lists_sizes_modified = true; m_ViasDimensionsList.push_back( viadim ); } if( m_TrackWidthList.size() == 0 ) { lists_sizes_modified = true; m_TrackWidthList.push_back( 0 ); } /* note the m_ViasDimensionsList[0] and m_TrackWidthList[0] values * are always the Netclass values */ if( m_ViasDimensionsList[0].m_Diameter != netClass->GetViaDiameter() ) { lists_sizes_modified = true; m_ViasDimensionsList[0].m_Diameter = netClass->GetViaDiameter(); } if( m_ViasDimensionsList[0].m_Drill != netClass->GetViaDrill() ) { lists_sizes_modified = true; m_ViasDimensionsList[0].m_Drill = netClass->GetViaDrill(); } if( m_TrackWidthList[0] != netClass->GetTrackWidth() ) { lists_sizes_modified = true; m_TrackWidthList[0] = netClass->GetTrackWidth(); } if( GetViaSizeIndex() >= m_ViasDimensionsList.size() ) SetViaSizeIndex( m_ViasDimensionsList.size() ); if( GetTrackWidthIndex() >= m_TrackWidthList.size() ) SetTrackWidthIndex( m_TrackWidthList.size() ); return lists_sizes_modified; }
static void class2gridRow( wxGrid* grid, int row, NETCLASSPTR nc ) { wxString msg; // label is netclass name grid->SetRowLabelValue( row, nc->GetName() ); msg = StringFromValue( g_UserUnit, nc->GetClearance() ); grid->SetCellValue( row, GRID_CLEARANCE, msg ); msg = StringFromValue( g_UserUnit, nc->GetTrackWidth() ); grid->SetCellValue( row, GRID_TRACKSIZE, msg ); msg = StringFromValue( g_UserUnit, nc->GetViaDiameter() ); grid->SetCellValue( row, GRID_VIASIZE, msg ); msg = StringFromValue( g_UserUnit, nc->GetViaDrill() ); grid->SetCellValue( row, GRID_VIADRILL, msg ); msg = StringFromValue( g_UserUnit, nc->GetuViaDiameter() ); grid->SetCellValue( row, GRID_uVIASIZE, msg ); msg = StringFromValue( g_UserUnit, nc->GetuViaDrill() ); grid->SetCellValue( row, GRID_uVIADRILL, msg ); }
int VIA::GetDrillValue() const { if( m_Drill > 0 ) // Use the specific value. return m_Drill; // Use the default value from the Netclass NETCLASSPTR netclass = GetNetClass(); if( GetViaType() == VIA_MICROVIA ) return netclass->GetuViaDrill(); return netclass->GetViaDrill(); }
void ReadParam( wxConfigBase* aConfig ) const override { if( !m_Pt_param || !aConfig ) return; wxString oldPath = aConfig->GetPath(); m_Pt_param->Clear(); for( int index = 0; ; ++index ) { wxString path = ""; NETCLASSPTR netclass; wxString netclassName; if( index == 0 ) path = "Default"; else path << index; aConfig->SetPath( oldPath ); aConfig->SetPath( m_Ident ); aConfig->SetPath( path ); if( !aConfig->Read( NetclassNameKey, &netclassName ) ) break; if( index == 0 ) netclass = m_Pt_param->GetDefault(); else netclass = std::make_shared<NETCLASS>( netclassName ); #define READ_MM( aKey, aDefault ) Millimeter2iu( aConfig->ReadDouble( aKey, aDefault ) ) netclass->SetClearance( READ_MM( ClearanceKey, netclass->GetClearance() ) ); netclass->SetTrackWidth( READ_MM( TrackWidthKey, netclass->GetTrackWidth() ) ); netclass->SetViaDiameter( READ_MM( ViaDiameterKey, netclass->GetViaDiameter() ) ); netclass->SetViaDrill( READ_MM( ViaDrillKey, netclass->GetViaDrill() ) ); netclass->SetuViaDiameter( READ_MM( uViaDiameterKey, netclass->GetuViaDiameter() ) ); netclass->SetuViaDrill( READ_MM( uViaDrillKey, netclass->GetuViaDrill() ) ); netclass->SetDiffPairWidth( READ_MM( dPairWidthKey, netclass->GetDiffPairWidth() ) ); netclass->SetDiffPairGap( READ_MM( dPairGapKey, netclass->GetDiffPairGap() ) ); netclass->SetDiffPairViaGap( READ_MM( dPairViaGapKey, netclass->GetDiffPairViaGap() ) ); if( index > 0 ) m_Pt_param->Add( netclass ); } aConfig->SetPath( oldPath ); }
void SaveParam( wxConfigBase* aConfig ) const override { if( !m_Pt_param || !aConfig ) return; wxString oldPath = aConfig->GetPath(); NETCLASSES::const_iterator nc = m_Pt_param->begin(); for( unsigned index = 0; index <= m_Pt_param->GetCount(); ++index ) { wxString path = ""; NETCLASSPTR netclass; if( index == 0 ) path = "Default"; else path << index; aConfig->SetPath( oldPath ); aConfig->SetPath( m_Ident ); aConfig->SetPath( path ); if( index == 0 ) { netclass = m_Pt_param->GetDefault(); } else { netclass = nc->second; ++nc; } aConfig->Write( NetclassNameKey, netclass->GetName() ); #define WRITE_MM( aKey, aValue ) aConfig->Write( aKey, Iu2Millimeter( aValue ) ) WRITE_MM( ClearanceKey, netclass->GetClearance() ); WRITE_MM( TrackWidthKey, netclass->GetTrackWidth() ); WRITE_MM( ViaDiameterKey, netclass->GetViaDiameter() ); WRITE_MM( ViaDrillKey, netclass->GetViaDrill() ); WRITE_MM( uViaDiameterKey, netclass->GetuViaDiameter() ); WRITE_MM( uViaDrillKey, netclass->GetuViaDrill() ); WRITE_MM( dPairWidthKey, netclass->GetDiffPairWidth() ); WRITE_MM( dPairGapKey, netclass->GetDiffPairGap() ); WRITE_MM( dPairViaGapKey, netclass->GetDiffPairViaGap() ); } aConfig->SetPath( oldPath ); }
// see class_track.h void TRACK::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) { wxString msg; BOARD* board = GetBoard(); // Display basic infos GetMsgPanelInfoBase( aList ); // Display full track length (in Pcbnew) if( board ) { double trackLen = 0; double lenPadToDie = 0; board->MarkTrace( this, NULL, &trackLen, &lenPadToDie, false ); msg = ::CoordinateToString( trackLen ); aList.push_back( MSG_PANEL_ITEM( _( "Track Len" ), msg, DARKCYAN ) ); if( lenPadToDie != 0 ) { msg = ::LengthDoubleToString( trackLen + lenPadToDie ); aList.push_back( MSG_PANEL_ITEM( _( "Full Len" ), msg, DARKCYAN ) ); msg = ::LengthDoubleToString( lenPadToDie ); aList.push_back( MSG_PANEL_ITEM( _( "In Package" ), msg, DARKCYAN ) ); } } NETCLASSPTR netclass = GetNetClass(); if( netclass ) { aList.push_back( MSG_PANEL_ITEM( _( "NC Name" ), netclass->GetName(), DARKMAGENTA ) ); aList.push_back( MSG_PANEL_ITEM( _( "NC Clearance" ), ::CoordinateToString( netclass->GetClearance(), true ), DARKMAGENTA ) ); aList.push_back( MSG_PANEL_ITEM( _( "NC Width" ), ::CoordinateToString( netclass->GetTrackWidth(), true ), DARKMAGENTA ) ); aList.push_back( MSG_PANEL_ITEM( _( "NC Via Size" ), ::CoordinateToString( netclass->GetViaDiameter(), true ), DARKMAGENTA ) ); aList.push_back( MSG_PANEL_ITEM( _( "NC Via Drill"), ::CoordinateToString( netclass->GetViaDrill(), true ), DARKMAGENTA ) ); } }
void ROUTER_TOOL::getNetclassDimensions( int aNetCode, int& aWidth, int& aViaDiameter, int& aViaDrill ) { BOARD_DESIGN_SETTINGS &bds = m_board->GetDesignSettings(); NETCLASSPTR netClass; NETINFO_ITEM* ni = m_board->FindNet( aNetCode ); if( ni ) { wxString netClassName = ni->GetClassName(); netClass = bds.m_NetClasses.Find( netClassName ); } if( !netClass ) netClass = bds.GetDefault(); aWidth = netClass->GetTrackWidth(); aViaDiameter = netClass->GetViaDiameter(); aViaDrill = netClass->GetViaDrill(); }
bool DRC::doNetClass( NETCLASSPTR nc, wxString& msg ) { bool ret = true; const BOARD_DESIGN_SETTINGS& g = m_pcb->GetDesignSettings(); #define FmtVal( x ) GetChars( StringFromValue( g_UserUnit, x ) ) #if 0 // set to 1 when (if...) BOARD_DESIGN_SETTINGS has a m_MinClearance value if( nc->GetClearance() < g.m_MinClearance ) { msg.Printf( _( "NETCLASS: '%s' has Clearance:%s which is less than global:%s" ), GetChars( nc->GetName() ), FmtVal( nc->GetClearance() ), FmtVal( g.m_TrackClearance ) ); addMarkerToPcb( fillMarker( DRCE_NETCLASS_CLEARANCE, msg, m_currentMarker ) ); m_currentMarker = nullptr; ret = false; } #endif if( nc->GetTrackWidth() < g.m_TrackMinWidth ) { msg.Printf( _( "NETCLASS: '%s' has TrackWidth:%s which is less than global:%s" ), GetChars( nc->GetName() ), FmtVal( nc->GetTrackWidth() ), FmtVal( g.m_TrackMinWidth ) ); addMarkerToPcb( fillMarker( DRCE_NETCLASS_TRACKWIDTH, msg, m_currentMarker ) ); m_currentMarker = nullptr; ret = false; } if( nc->GetViaDiameter() < g.m_ViasMinSize ) { msg.Printf( _( "NETCLASS: '%s' has Via Dia:%s which is less than global:%s" ), GetChars( nc->GetName() ), FmtVal( nc->GetViaDiameter() ), FmtVal( g.m_ViasMinSize ) ); addMarkerToPcb( fillMarker( DRCE_NETCLASS_VIASIZE, msg, m_currentMarker ) ); m_currentMarker = nullptr; ret = false; } if( nc->GetViaDrill() < g.m_ViasMinDrill ) { msg.Printf( _( "NETCLASS: '%s' has Via Drill:%s which is less than global:%s" ), GetChars( nc->GetName() ), FmtVal( nc->GetViaDrill() ), FmtVal( g.m_ViasMinDrill ) ); addMarkerToPcb( fillMarker( DRCE_NETCLASS_VIADRILLSIZE, msg, m_currentMarker ) ); m_currentMarker = nullptr; ret = false; } if( nc->GetuViaDiameter() < g.m_MicroViasMinSize ) { msg.Printf( _( "NETCLASS: '%s' has uVia Dia:%s which is less than global:%s" ), GetChars( nc->GetName() ), FmtVal( nc->GetuViaDiameter() ), FmtVal( g.m_MicroViasMinSize ) ); addMarkerToPcb( fillMarker( DRCE_NETCLASS_uVIASIZE, msg, m_currentMarker ) ); m_currentMarker = nullptr; ret = false; } if( nc->GetuViaDrill() < g.m_MicroViasMinDrill ) { msg.Printf( _( "NETCLASS: '%s' has uVia Drill:%s which is less than global:%s" ), GetChars( nc->GetName() ), FmtVal( nc->GetuViaDrill() ), FmtVal( g.m_MicroViasMinDrill ) ); addMarkerToPcb( fillMarker( DRCE_NETCLASS_uVIADRILLSIZE, msg, m_currentMarker ) ); m_currentMarker = nullptr; ret = false; } return ret; }
void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IO_ERROR ) { sessionBoard = aBoard; // not owned here if( !session ) THROW_IO_ERROR( _("Session file is missing the \"session\" section") ); /* Dick 16-Jan-2012: session need not have a placement section. if( !session->placement ) THROW_IO_ERROR( _("Session file is missing the \"placement\" section") ); */ if( !session->route ) THROW_IO_ERROR( _("Session file is missing the \"routes\" section") ); if( !session->route->library ) THROW_IO_ERROR( _("Session file is missing the \"library_out\" section") ); // delete all the old tracks and vias aBoard->m_Track.DeleteAll(); aBoard->DeleteMARKERs(); buildLayerMaps( aBoard ); if( session->placement ) { // Walk the PLACEMENT object's COMPONENTs list, and for each PLACE within // each COMPONENT, reposition and re-orient each component and put on // correct side of the board. COMPONENTS& components = session->placement->components; for( COMPONENTS::iterator comp=components.begin(); comp!=components.end(); ++comp ) { PLACES& places = comp->places; for( unsigned i=0; i<places.size(); ++i ) { PLACE* place = &places[i]; // '&' even though places[] holds a pointer! wxString reference = FROM_UTF8( place->component_id.c_str() ); MODULE* module = aBoard->FindModuleByReference( reference ); if( !module ) { THROW_IO_ERROR( wxString::Format( _("Session file has 'reference' to non-existent component \"%s\""), GetChars( reference ) ) ); } if( !place->hasVertex ) continue; UNIT_RES* resolution = place->GetUnits(); wxASSERT( resolution ); wxPoint newPos = mapPt( place->vertex, resolution ); module->SetPosition( newPos ); if( place->side == T_front ) { // convert from degrees to tenths of degrees used in KiCad. int orientation = KiROUND( place->rotation * 10.0 ); if( module->GetLayer() != F_Cu ) { // module is on copper layer (back) module->Flip( module->GetPosition() ); } module->SetOrientation( orientation ); } else if( place->side == T_back ) { int orientation = KiROUND( (place->rotation + 180.0) * 10.0 ); if( module->GetLayer() != B_Cu ) { // module is on component layer (front) module->Flip( module->GetPosition() ); } module->SetOrientation( orientation ); } else { // as I write this, the PARSER *is* catching this, so we should never see below: wxFAIL_MSG( wxT("DSN::PARSER did not catch an illegal side := 'back|front'") ); } } } } routeResolution = session->route->GetUnits(); // Walk the NET_OUTs and create tracks and vias anew. NET_OUTS& net_outs = session->route->net_outs; for( NET_OUTS::iterator net = net_outs.begin(); net!=net_outs.end(); ++net ) { int netCode = 0; // page 143 of spec says wire's net_id is optional if( net->net_id.size() ) { wxString netName = FROM_UTF8( net->net_id.c_str() ); NETINFO_ITEM* netinfo = aBoard->FindNet( netName ); if( netinfo ) netCode = netinfo->GetNet(); else // else netCode remains 0 { // int breakhere = 1; } } WIRES& wires = net->wires; for( unsigned i = 0; i<wires.size(); ++i ) { WIRE* wire = &wires[i]; DSN_T shape = wire->shape->Type(); if( shape != T_path ) { /* shape == T_polygon is expected from freerouter if you have a zone on a non "power" type layer, i.e. a T_signal layer and the design does a round trip back in as session here. We kept our own zones in the BOARD, so ignore this so called 'wire'. wxString netId = FROM_UTF8( wire->net_id.c_str() ); THROW_IO_ERROR( wxString::Format( _("Unsupported wire shape: \"%s\" for net: \"%s\""), DLEX::GetTokenString(shape).GetData(), netId.GetData() ) ); */ } else { PATH* path = (PATH*) wire->shape; for( unsigned pt=0; pt<path->points.size()-1; ++pt ) { /* a debugging aid, may come in handy if( path->points[pt].x == 547800 && path->points[pt].y == -380250 ) { int breakhere = 1; } */ TRACK* track = makeTRACK( path, pt, netCode ); aBoard->Add( track ); } } } WIRE_VIAS& wire_vias = net->wire_vias; LIBRARY& library = *session->route->library; for( unsigned i=0; i<wire_vias.size(); ++i ) { int netCode = 0; // page 144 of spec says wire_via's net_id is optional if( net->net_id.size() ) { wxString netName = FROM_UTF8( net->net_id.c_str() ); NETINFO_ITEM* net = aBoard->FindNet( netName ); if( net ) netCode = net->GetNet(); // else netCode remains 0 } WIRE_VIA* wire_via = &wire_vias[i]; // example: (via Via_15:8_mil 149000 -71000 ) PADSTACK* padstack = library.FindPADSTACK( wire_via->GetPadstackId() ); if( !padstack ) { // Dick Feb 29, 2008: // Freerouter has a bug where it will not round trip all vias. // Vias which have a (use_via) element will be round tripped. // Vias which do not, don't come back in in the session library, // even though they may be actually used in the pre-routed, // protected wire_vias. So until that is fixed, create the // padstack from its name as a work around. // Could use a STRING_FORMATTER here and convert the entire // wire_via to text and put that text into the exception. wxString psid( FROM_UTF8( wire_via->GetPadstackId().c_str() ) ); THROW_IO_ERROR( wxString::Format( _("A wire_via references a missing padstack \"%s\""), GetChars( psid ) ) ); } NETCLASSPTR netclass = aBoard->GetDesignSettings().m_NetClasses.GetDefault(); int via_drill_default = netclass->GetViaDrill(); for( unsigned v=0; v<wire_via->vertexes.size(); ++v ) { ::VIA* via = makeVIA( padstack, wire_via->vertexes[v], netCode, via_drill_default ); aBoard->Add( via ); } } } }
void BOARD::SynchronizeNetsAndNetClasses() { NETCLASSES& netClasses = m_designSettings.m_NetClasses; NETCLASSPTR defaultNetClass = netClasses.GetDefault(); // set all NETs to the default NETCLASS, then later override some // as we go through the NETCLASSes. for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() ); net != netEnd; ++net ) { net->SetClass( defaultNetClass ); } // Add netclass name and pointer to nets. If a net is in more than one netclass, // set the net's name and pointer to only the first netclass. Subsequent // and therefore bogus netclass memberships will be deleted in logic below this loop. for( NETCLASSES::iterator clazz = netClasses.begin(); clazz != netClasses.end(); ++clazz ) { NETCLASSPTR netclass = clazz->second; for( NETCLASS::const_iterator member = netclass->begin(); member != netclass->end(); ++member ) { const wxString& netname = *member; // although this overall function seems to be adequately fast, // FindNet( wxString ) uses now a fast binary search and is fast // event for large net lists NETINFO_ITEM* net = FindNet( netname ); if( net && net->GetClassName() == NETCLASS::Default ) { net->SetClass( netclass ); } } } // 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( NETCLASSES::iterator clazz = netClasses.begin(); clazz != netClasses.end(); ++clazz ) { NETCLASSPTR netclass = clazz->second; netclass->Clear(); } defaultNetClass->Clear(); for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() ); net != netEnd; ++net ) { const wxString& classname = net->GetClassName(); // because of the std:map<> this should be fast, and because of // prior logic, netclass should not be NULL. NETCLASSPTR netclass = netClasses.Find( classname ); wxASSERT( netclass ); netclass->Add( net->GetNetname() ); } // Set initial values for custom track width & via size to match the default netclass settings m_designSettings.UseCustomTrackViaSize( false ); m_designSettings.SetCustomTrackWidth( defaultNetClass->GetTrackWidth() ); m_designSettings.SetCustomViaSize( defaultNetClass->GetViaDiameter() ); m_designSettings.SetCustomViaDrill( defaultNetClass->GetViaDrill() ); }