/* Emit the netlist (which is actually the thing for which GenCAD is used these * days!); tracks are handled later */ static void CreateSignalsSection( FILE* aFile, BOARD* aPcb ) { wxString msg; NETINFO_ITEM* net; D_PAD* pad; MODULE* module; int NbNoConn = 1; fputs( "$SIGNALS\n", aFile ); for( unsigned ii = 0; ii < aPcb->GetNetCount(); ii++ ) { net = aPcb->FindNet( ii ); if( net->GetNetname() == wxEmptyString ) // dummy netlist (no connection) { wxString msg; msg << wxT( "NoConnection" ) << NbNoConn++; } if( net->GetNet() <= 0 ) // dummy netlist (no connection) continue; msg = wxT( "SIGNAL " ) + net->GetNetname(); fputs( TO_UTF8( msg ), aFile ); fputs( "\n", aFile ); for( module = aPcb->m_Modules; module; module = module->Next() ) { for( pad = module->Pads(); pad; pad = pad->Next() ) { wxString padname; if( pad->GetNetCode() != net->GetNet() ) continue; pad->StringPadName( padname ); msg.Printf( wxT( "NODE %s %s" ), GetChars( module->GetReference() ), GetChars( padname ) ); fputs( TO_UTF8( msg ), aFile ); fputs( "\n", aFile ); } } } fputs( "$ENDSIGNALS\n\n", aFile ); }
void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement ) { // if there is a net with such name then just assign the correct number NETINFO_ITEM* sameName = GetNetItem( aNewElement->GetNetname() ); if( sameName != NULL ) { aNewElement->m_NetCode = sameName->GetNet(); return; } // be sure that net codes are consecutive // negative net code means that it has to be auto assigned else if( ( aNewElement->m_NetCode != (int) m_netCodes.size() ) || ( aNewElement->m_NetCode < 0 ) ) { aNewElement->m_NetCode = getFreeNetCode(); } // net names & codes are supposed to be unique assert( GetNetItem( aNewElement->GetNetname() ) == NULL ); assert( GetNetItem( aNewElement->GetNet() ) == NULL ); // add an entry for fast look up by a net name using a map m_netNames.insert( std::make_pair( aNewElement->GetNetname(), aNewElement ) ); m_netCodes.insert( std::make_pair( aNewElement->GetNet(), aNewElement ) ); }
bool PNS_PCBNEW_RULE_RESOLVER::DpNetPair( PNS::ITEM* aItem, int& aNetP, int& aNetN ) { if( !aItem || !aItem->Parent() || !aItem->Parent()->GetNet() ) return false; wxString netNameP = aItem->Parent()->GetNet()->GetNetname(); wxString netNameN, netNameCoupled, netNameBase; int r = matchDpSuffix( netNameP, netNameCoupled, netNameBase ); if( r == 0 ) return false; else if( r == 1 ) { netNameN = netNameCoupled; } else { netNameN = netNameP; netNameP = netNameCoupled; } // wxLogTrace( "PNS","p %s n %s base %s\n", (const char *)netNameP.c_str(), (const char *)netNameN.c_str(), (const char *)netNameBase.c_str() ); NETINFO_ITEM* netInfoP = m_board->FindNet( netNameP ); NETINFO_ITEM* netInfoN = m_board->FindNet( netNameN ); //wxLogTrace( "PNS","ip %p in %p\n", netInfoP, netInfoN); if( !netInfoP || !netInfoN ) return false; aNetP = netInfoP->GetNet(); aNetN = netInfoN->GetNet(); return true; }
int PNS_PCBNEW_RULE_RESOLVER::DpCoupledNet( int aNet ) { wxString refName = m_board->FindNet( aNet )->GetNetname(); wxString dummy, coupledNetName; if( matchDpSuffix( refName, coupledNetName, dummy ) ) { NETINFO_ITEM* net = m_board->FindNet( coupledNetName ); if( !net ) return -1; return net->GetNet(); } return -1; }
int PCBNEW_PAIRING_RESOLVER::PairedNet(int aNet) const { wxString refName = m_board->FindNet( aNet )->GetNetname(); wxString dummy, coupledNetName; if( MatchDpSuffix( refName, coupledNetName, dummy ) ) { NETINFO_ITEM* net = m_board->FindNet( coupledNetName ); if( !net ) return -1; return net->GetNet(); } return -1; }
int PNS_TOPOLOGY::DpCoupledNet( int aNet ) { BOARD* brd = PNS_ROUTER::GetInstance()->GetBoard(); wxString refName = brd->FindNet( aNet )->GetNetname(); wxString dummy, coupledNetName; if( MatchDpSuffix( refName, coupledNetName, dummy ) ) { NETINFO_ITEM* net = brd->FindNet( coupledNetName ); if( !net ) return -1; return net->GetNet(); } return -1; }
bool DIALOG_COPPER_ZONE::AcceptOptions( bool aPromptForErrors, bool aUseExportableSetupOnly ) { switch( m_PadInZoneOpt->GetSelection() ) { case 3: // Pads are not covered m_settings.SetPadConnection( PAD_NOT_IN_ZONE ); break; case 2: // Use thermal relief for THT pads m_settings.SetPadConnection( THT_THERMAL ); break; case 1: // Use thermal relief for pads m_settings.SetPadConnection( THERMAL_PAD ); break; case 0: // pads are covered by copper m_settings.SetPadConnection( PAD_IN_ZONE ); break; } switch( m_OutlineAppearanceCtrl->GetSelection() ) { case 0: m_settings.m_Zone_HatchingStyle = CPolyLine::NO_HATCH; break; case 1: m_settings.m_Zone_HatchingStyle = CPolyLine::DIAGONAL_EDGE; break; case 2: m_settings.m_Zone_HatchingStyle = CPolyLine::DIAGONAL_FULL; break; } m_settings.m_ArcToSegmentsCount = m_ArcApproximationOpt->GetSelection() == 1 ? ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF : ARC_APPROX_SEGMENTS_COUNT_LOW_DEF; if( m_Config ) { m_Config->Write( ZONE_NET_OUTLINES_HATCH_OPTION_KEY, (long) m_settings.m_Zone_HatchingStyle ); wxString filter = m_DoNotShowNetNameFilter->GetValue(); m_Config->Write( ZONE_NET_FILTER_STRING_KEY, filter ); } m_netNameShowFilter = m_ShowNetNameFilter->GetValue(); m_settings.m_FillMode = (m_FillModeCtrl->GetSelection() == 0) ? 0 : 1; wxString txtvalue = m_ZoneClearanceCtrl->GetValue(); m_settings.m_ZoneClearance = ReturnValueFromString( g_UserUnit, txtvalue ); // Test if this is a reasonable value for this parameter // A too large value can hang Pcbnew #define CLEARANCE_MAX_VALUE ZONE_CLEARANCE_MAX_VALUE_MIL*IU_PER_MILS if( m_settings.m_ZoneClearance > CLEARANCE_MAX_VALUE ) { wxString msg; msg.Printf( _( "Clearance must be smaller than %f\" / %f mm." ), ZONE_CLEARANCE_MAX_VALUE_MIL / 1000.0, ZONE_CLEARANCE_MAX_VALUE_MIL * 0.0254 ); DisplayError( this, msg ); return false; } txtvalue = m_ZoneMinThicknessCtrl->GetValue(); m_settings.m_ZoneMinThickness = ReturnValueFromString( g_UserUnit, txtvalue ); if( m_settings.m_ZoneMinThickness < (ZONE_THICKNESS_MIN_VALUE_MIL*IU_PER_MILS) ) { wxString msg; msg.Printf( _( "Minimum width must be larger than %f\" / %f mm." ), ZONE_THICKNESS_MIN_VALUE_MIL / 1000.0, ZONE_THICKNESS_MIN_VALUE_MIL * 0.0254 ); DisplayError( this, msg ); return false; } m_settings.SetCornerSmoothingType( m_cornerSmoothingChoice->GetSelection() ); txtvalue = m_cornerSmoothingCtrl->GetValue(); m_settings.SetCornerRadius( ReturnValueFromString( g_UserUnit, txtvalue ) ); m_settings.m_ZonePriority = m_PriorityLevelCtrl->GetValue(); if( m_OrientEdgesOpt->GetSelection() == 0 ) m_settings.m_Zone_45_Only = false; else m_settings.m_Zone_45_Only = true; m_settings.m_ThermalReliefGap = ReturnValueFromTextCtrl( *m_AntipadSizeValue ); m_settings.m_ThermalReliefCopperBridge = ReturnValueFromTextCtrl( *m_CopperWidthValue ); if( m_Config ) { ConfigBaseWriteDouble( m_Config, ZONE_CLEARANCE_WIDTH_STRING_KEY, (double) m_settings.m_ZoneClearance / IU_PER_MILS ); ConfigBaseWriteDouble( m_Config, ZONE_MIN_THICKNESS_WIDTH_STRING_KEY, (double) m_settings.m_ZoneMinThickness / IU_PER_MILS ); ConfigBaseWriteDouble( m_Config, ZONE_THERMAL_RELIEF_GAP_STRING_KEY, (double) m_settings.m_ThermalReliefGap / IU_PER_MILS ); ConfigBaseWriteDouble( m_Config, ZONE_THERMAL_RELIEF_COPPER_WIDTH_STRING_KEY, (double) m_settings.m_ThermalReliefCopperBridge / IU_PER_MILS ); } if( m_settings.m_ThermalReliefCopperBridge <= m_settings.m_ZoneMinThickness ) { DisplayError( this, _( "Thermal relief spoke width is smaller than the minimum width." ) ); return false; } // If we use only exportable to others zones parameters, exit here: if( aUseExportableSetupOnly ) return true; // Get the layer selection for this zone int ii = m_LayerSelectionCtrl->GetFirstSelected(); if( ii < 0 && aPromptForErrors ) { DisplayError( this, _( "No layer selected." ) ); return false; } m_settings.m_CurrentZone_Layer = m_LayerId[ii]; // Get the net name selection for this zone ii = m_ListNetNameSelection->GetSelection(); if( ii < 0 && aPromptForErrors ) { DisplayError( this, _( "No net selected." ) ); return false; } if( ii == 0 ) // the not connected option was selected: this is not a good practice: warn: { if( !IsOK( this, _( "You have chosen the \"not connected\" option. This will create insulated copper islands. Are you sure ?" ) ) ) return false; } wxString net_name = m_ListNetNameSelection->GetString( ii ); m_settings.m_NetcodeSelection = 0; // Search net_code for this net, if a net was selected if( m_ListNetNameSelection->GetSelection() > 0 ) { NETINFO_ITEM* net = m_Parent->GetBoard()->FindNet( net_name ); if( net ) m_settings.m_NetcodeSelection = net->GetNet(); } return true; }
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 ); } } } }
bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType ) { switch( (IO_MGR::PCB_FILE_T) aFileType ) { case IO_MGR::EAGLE: if( OpenProjectFiles( std::vector<wxString>( 1, aFileName ), KICTL_EAGLE_BRD ) ) { wxString projectpath = Kiway().Prj().GetProjectPath(); wxFileName newfilename; newfilename.SetPath( Prj().GetProjectPath() ); newfilename.SetName( Prj().GetProjectName() ); newfilename.SetExt( KiCadPcbFileExtension ); GetBoard()->SetFileName( newfilename.GetFullPath() ); UpdateTitle(); OnModify(); // Extract a footprint library from the design and add it to the fp-lib-table wxString newLibPath; ArchiveModulesOnBoard( true, newfilename.GetName(), &newLibPath ); if( newLibPath.Length() > 0 ) { FP_LIB_TABLE* prjlibtable = Prj().PcbFootprintLibs(); const wxString& project_env = PROJECT_VAR_NAME; wxString rel_path, env_path; wxGetEnv( project_env, &env_path ); wxString result( newLibPath ); rel_path = result.Replace( env_path, wxString( "$(" + project_env + ")" ) ) ? result : "" ; if( !rel_path.IsEmpty() ) newLibPath = rel_path; FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( newfilename.GetName(), newLibPath, wxT( "KiCad" ), wxEmptyString ); prjlibtable->InsertRow( row ); } if( !GetBoard()->GetFileName().IsEmpty() ) { wxString tblName = Prj().FootprintLibTblName(); try { Prj().PcbFootprintLibs()->Save( tblName ); } catch( const IO_ERROR& ioe ) { wxString msg = wxString::Format( _( "Error occurred saving project specific footprint library " "table:\n\n%s" ), GetChars( ioe.What() ) ); wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR ); } } // Update module LIB_IDs to point to the just imported Eagle library for( MODULE* module : GetBoard()->Modules() ) { LIB_ID libId = module->GetFPID(); if( libId.GetLibItemName().empty() ) continue; libId.SetLibNickname( newfilename.GetName() ); module->SetFPID( libId ); } // Store net names for all pads, to create net remap information std::unordered_map<D_PAD*, wxString> netMap; for( const auto& pad : GetBoard()->GetPads() ) { NETINFO_ITEM* netinfo = pad->GetNet(); if( netinfo->GetNet() > 0 && !netinfo->GetNetname().IsEmpty() ) netMap[pad] = netinfo->GetNetname(); } // Two stage netlist update: // - first, assign valid timestamps to footprints (no reannotation) // - second, perform schematic annotation and update footprint references // based on timestamps NETLIST netlist; FetchNetlistFromSchematic( netlist, NO_ANNOTATION ); DoUpdatePCBFromNetlist( netlist, false ); FetchNetlistFromSchematic( netlist, QUIET_ANNOTATION ); DoUpdatePCBFromNetlist( netlist, true ); std::unordered_map<wxString, wxString> netRemap; // Compare the old net names with the new net names and create a net map for( const auto& pad : GetBoard()->GetPads() ) { auto it = netMap.find( pad ); if( it == netMap.end() ) continue; NETINFO_ITEM* netinfo = pad->GetNet(); // Net name has changed, create a remap entry if( netinfo->GetNet() > 0 && netMap[pad] != netinfo->GetNetname() ) netRemap[netMap[pad]] = netinfo->GetNetname(); } if( !netRemap.empty() ) fixEagleNets( netRemap ); return true; } return false; default: return false; } return false; }
void PCB_PAD::AddToModule( MODULE* aModule, int aRotation, bool aEncapsulatedPad ) { PCB_PAD_SHAPE* padShape; wxString padShapeName = wxT( "Ellipse" ); PAD_ATTR_T padType; int i; int width = 0; int height = 0; D_PAD* pad = new D_PAD( aModule ); aModule->Pads().PushBack( pad ); if( !m_isHolePlated && m_hole ) { // mechanical hole pad->SetShape( PAD_CIRCLE ); pad->SetAttribute( PAD_HOLE_NOT_PLATED ); pad->SetDrillShape( PAD_DRILL_CIRCLE ); pad->SetDrillSize( wxSize( m_hole, m_hole ) ); pad->SetSize( wxSize( m_hole, m_hole ) ); pad->SetLayerSet( LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask ) ); } else { ( m_hole ) ? padType = PAD_STANDARD : padType = PAD_SMD; // form layer mask for( i = 0; i < (int) m_shapes.GetCount(); i++ ) { padShape = m_shapes[i]; if( padShape->m_width > 0 && padShape->m_height > 0 ) { if( padShape->m_KiCadLayer == F_Cu || padShape->m_KiCadLayer == B_Cu ) { padShapeName = padShape->m_shape; width = padShape->m_width; height = padShape->m_height; // assume this is SMD pad if( padShape->m_KiCadLayer == F_Cu ) pad->SetLayerSet( LSET( 3, F_Cu, F_Paste, F_Mask ) ); else pad->SetLayerSet( LSET( 3, B_Cu, B_Paste, B_Mask ) ); break; } } } if( padType == PAD_STANDARD ) // actually this is a thru-hole pad pad->SetLayerSet( LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask ) ); if( width == 0 || height == 0 ) THROW_IO_ERROR( wxT( "pad with zero size" ) ); pad->SetPadName( m_name.text ); if( padShapeName == wxT( "Oval" ) || padShapeName == wxT( "Ellipse" ) || padShapeName == wxT( "MtHole" ) ) { if( width != height ) pad->SetShape( PAD_OVAL ); else pad->SetShape( PAD_CIRCLE ); } else if( padShapeName == wxT( "Rect" ) || padShapeName == wxT( "RndRect" ) ) pad->SetShape( PAD_RECT ); else if( padShapeName == wxT( "Polygon" ) ) pad->SetShape( PAD_RECT ); // approximation pad->SetSize( wxSize( width, height ) ); pad->SetDelta( wxSize( 0, 0 ) ); pad->SetOrientation( m_rotation + aRotation ); pad->SetDrillShape( PAD_DRILL_CIRCLE ); pad->SetOffset( wxPoint( 0, 0 ) ); pad->SetDrillSize( wxSize( m_hole, m_hole ) ); pad->SetAttribute( padType ); // Set the proper net code NETINFO_ITEM* netinfo = m_board->FindNet( m_net ); if( netinfo == NULL ) // I believe this should not happen, but just in case { // It is a new net netinfo = new NETINFO_ITEM( m_board, m_net ); m_board->AppendNet( netinfo ); } pad->SetNetCode( netinfo->GetNet() ); } if( !aEncapsulatedPad ) { // pad's "Position" is not relative to the module's, // whereas Pos0 is relative to the module's but is the unrotated coordinate. wxPoint padpos( m_positionX, m_positionY ); pad->SetPos0( padpos ); RotatePoint( &padpos, aModule->GetOrientation() ); pad->SetPosition( padpos + aModule->GetPosition() ); } }
void PCB_EDIT_FRAME::ListNetsAndSelect( wxCommandEvent& event ) { NETINFO_ITEM* net; wxString netFilter; wxArrayString list; netFilter = wxT( "*" ); wxTextEntryDialog dlg( this, _( "Filter Net Names" ), _( "Net Filter" ), netFilter ); if( dlg.ShowModal() != wxID_OK ) return; // cancelled by user netFilter = dlg.GetValue( ); if( netFilter.IsEmpty() ) return; wxString Line; for( unsigned ii = 0; ii < GetBoard()->GetNetCount(); ii++ ) { net = GetBoard()->m_NetInfo.GetNetItem( ii ); if( !WildCompareString( netFilter, net->GetNetname(), false ) ) continue; Line.Printf( wxT( "net %3.3d: %s" ), net->GetNet(), GetChars( net->GetNetname() ) ); list.Add( Line ); } wxSingleChoiceDialog choiceDlg( this, wxEmptyString, _( "Select Net" ), list ); if( (choiceDlg.ShowModal() == wxID_CANCEL) || (choiceDlg.GetSelection() == wxNOT_FOUND) ) return; bool found = false; unsigned netcode = (unsigned) choiceDlg.GetSelection(); // Search for the net selected. for( unsigned ii = 0; ii < GetBoard()->GetNetCount(); ii++ ) { net = GetBoard()->FindNet( ii ); if( !WildCompareString( netFilter, net->GetNetname(), false ) ) continue; if( ii == netcode ) { netcode = net->GetNet(); found = true; break; } } if( found ) { INSTALL_UNBUFFERED_DC( dc, m_canvas ); if( GetBoard()->IsHighLightNetON() ) HighLight( &dc ); GetBoard()->SetHighLightNet( netcode ); HighLight( &dc ); } }
bool PNS_DIFF_PAIR_PLACER::findDpPrimitivePair( const VECTOR2I& aP, PNS_ITEM* aItem, PNS_DP_PRIMITIVE_PAIR& aPair ) { if( !aItem || !aItem->Parent() || !aItem->Parent()->GetNet() ) return false; wxString netNameP = aItem->Parent()->GetNet()->GetNetname(); wxString netNameN, netNameBase; BOARD* brd = Router()->GetBoard(); PNS_ITEM *primRef = NULL, *primP = NULL, *primN = NULL; int refNet; wxString suffix; int r = matchDpSuffix ( netNameP, suffix, netNameBase ); if( r == 0 ) return false; else if( r == 1 ) { primRef = primP = static_cast<PNS_SOLID*>( aItem ); netNameN = netNameBase + suffix; } else { primRef = primN = static_cast<PNS_SOLID*>( aItem ); netNameN = netNameP; netNameP = netNameBase + suffix; } NETINFO_ITEM* netInfoP = brd->FindNet( netNameP ); NETINFO_ITEM* netInfoN = brd->FindNet( netNameN ); if( !netInfoP || !netInfoN ) return false; int netP = netInfoP->GetNet(); int netN = netInfoN->GetNet(); if( primP ) refNet = netN; else refNet = netP; std::set<PNS_ITEM*> items; OPT_VECTOR2I refAnchor = getDanglingAnchor( m_currentNode, primRef ); if( !refAnchor ) return false; m_currentNode->AllItemsInNet( refNet, items ); double bestDist = std::numeric_limits<double>::max(); bool found = false; BOOST_FOREACH(PNS_ITEM* item, items ) { if( item->Kind() == aItem->Kind() ) { OPT_VECTOR2I anchor = getDanglingAnchor( m_currentNode, item ); if( !anchor ) continue; double dist = ( *anchor - *refAnchor ).EuclideanNorm(); if( dist < bestDist ) { found = true; bestDist = dist; if( refNet == netP ) { aPair = PNS_DP_PRIMITIVE_PAIR ( item, primRef ); aPair.SetAnchors( *anchor, *refAnchor ); } else { aPair = PNS_DP_PRIMITIVE_PAIR( primRef, item ); aPair.SetAnchors( *refAnchor, *anchor ); } } } } return found; }
void PCB_EDIT_FRAME::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* aZone ) { ZONE_EDIT_T edited; ZONE_SETTINGS zoneInfo = GetZoneSettings(); BOARD_COMMIT commit( this ); m_canvas->SetIgnoreMouseEvents( true ); // Save initial zones configuration, for undo/redo, before adding new zone // note the net name and the layer can be changed, so we must save all zones s_AuxiliaryList.ClearListAndDeleteItems(); s_PickedList.ClearListAndDeleteItems(); SaveCopyOfZones( s_PickedList, GetBoard(), -1, UNDEFINED_LAYER ); if( aZone->GetIsKeepout() ) { // edit a keepout area on a copper layer zoneInfo << *aZone; edited = InvokeKeepoutAreaEditor( this, &zoneInfo ); } else if( IsCopperLayer( aZone->GetLayer() ) ) { // edit a zone on a copper layer zoneInfo << *aZone; edited = InvokeCopperZonesEditor( this, &zoneInfo ); } else { edited = InvokeNonCopperZonesEditor( this, aZone, &zoneInfo ); } m_canvas->MoveCursorToCrossHair(); m_canvas->SetIgnoreMouseEvents( false ); if( edited == ZONE_ABORT ) { s_AuxiliaryList.ClearListAndDeleteItems(); s_PickedList.ClearListAndDeleteItems(); return; } SetZoneSettings( zoneInfo ); if( edited == ZONE_EXPORT_VALUES ) { UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() ); commit.Stage( s_PickedList ); commit.Push( _( "Modify zone properties" ) ); s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items return; } // Undraw old zone outlines for( int ii = 0; ii < GetBoard()->GetAreaCount(); ii++ ) { ZONE_CONTAINER* edge_zone = GetBoard()->GetArea( ii ); edge_zone->Draw( m_canvas, DC, GR_XOR ); if( IsGalCanvasActive() ) { GetGalCanvas()->GetView()->Update( edge_zone ); } } zoneInfo.ExportSetting( *aZone ); NETINFO_ITEM* net = GetBoard()->FindNet( zoneInfo.m_NetcodeSelection ); if( net ) // net == NULL should not occur aZone->SetNetCode( net->GetNet() ); // Combine zones if possible GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, aZone ); // Redraw the real new zone outlines GetBoard()->RedrawAreasOutlines( m_canvas, DC, GR_OR, UNDEFINED_LAYER ); UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() ); commit.Stage( s_PickedList ); commit.Push( _( "Modify zone properties" ) ); s_PickedList.ClearItemsList(); // s_ItemsListPicker is no longer owner of picked items }