/* search connections between tracks and pads and propagate pad net codes to the track * segments. * Pads netcodes are assumed to be up to date. */ void PCB_BASE_FRAME::RecalculateAllTracksNetcode() { // Build the net info list GetBoard()->BuildListOfNets(); // Reset variables and flags used in computation for( TRACK* t = m_Pcb->m_Track; t; t = t->Next() ) { t->m_TracksConnected.clear(); t->m_PadsConnected.clear(); t->start = NULL; t->end = NULL; t->SetState( BUSY | IN_EDIT | BEGIN_ONPAD | END_ONPAD, false ); t->SetZoneSubNet( 0 ); t->SetNetCode( NETINFO_LIST::UNCONNECTED ); } // If no pad, reset pointers and netcode, and do nothing else if( m_Pcb->GetPadCount() == 0 ) return; CONNECTIONS connections( m_Pcb ); connections.BuildPadsList(); connections.BuildTracksCandidatesList(m_Pcb->m_Track); // First pass: build connections between track segments and pads. connections.SearchTracksConnectedToPads(); // For tracks connected to at least one pad, // set the track net code to the pad netcode for( TRACK* t = m_Pcb->m_Track; t; t = t->Next() ) { if( t->m_PadsConnected.size() ) t->SetNetCode( t->m_PadsConnected[0]->GetNetCode() ); } // Pass 2: build connections between track ends for( TRACK* t = m_Pcb->m_Track; t; t = t->Next() ) { connections.SearchConnectedTracks( t ); connections.GetConnectedTracks( t ); } // Propagate net codes from a segment to other connected segments bool new_pass_request = true; // set to true if a track has its netcode changed from 0 // to a known netcode to re-evaluate netcodes // of connected items while( new_pass_request ) { new_pass_request = false; for( TRACK* t = m_Pcb->m_Track; t; t = t->Next() ) { int netcode = t->GetNetCode(); if( netcode == 0 ) { // try to find a connected item having a netcode for( unsigned kk = 0; kk < t->m_TracksConnected.size(); kk++ ) { int altnetcode = t->m_TracksConnected[kk]->GetNetCode(); if( altnetcode ) { new_pass_request = true; netcode = altnetcode; t->SetNetCode(netcode); break; } } } if( netcode ) // this track has a netcode { // propagate this netcode to connected tracks having no netcode for( unsigned kk = 0; kk < t->m_TracksConnected.size(); kk++ ) { int altnetcode = t->m_TracksConnected[kk]->GetNetCode(); if( altnetcode == 0 ) { t->m_TracksConnected[kk]->SetNetCode(netcode); new_pass_request = true; } } } } } if( IsGalCanvasActive() ) { /// @todo LEGACY tracks might have changed their nets, so we need to refresh labels in GAL for( TRACK* track = m_Pcb->m_Track; track; track = track->Next() ) GetGalCanvas()->GetView()->Update( track ); } // Sort the track list by net codes: RebuildTrackChain( m_Pcb ); }
void WinEDA_BasePcbFrame::reattribution_reference_piste(int affiche) { TRACK * pt_piste, * pt_next; int a_color; char new_passe_request = 1, flag; LISTE_PAD * pt_mem; EDA_BaseStruct * PtStruct; int masque_layer; if( m_Pcb->m_NbPads == 0 ) return; a_color = CYAN; if(affiche) Affiche_1_Parametre(this, POS_AFF_CHREF, wxT("DataBase"), wxT("Netcodes"),a_color); recalcule_pad_net_code(); if(affiche) Affiche_1_Parametre(this, -1,wxEmptyString, wxT("Gen Pads "),a_color); ////////////////////////////////////////////////////// // Connexion des pistes accrochees a 1 pad au moins // ////////////////////////////////////////////////////// pt_mem = (LISTE_PAD*) MyMalloc( m_Pcb->m_NbPads * sizeof( D_PAD *) ); memcpy(pt_mem, m_Pcb->m_Pads, m_Pcb->m_NbPads* sizeof( D_PAD *) ); qsort(pt_mem, m_Pcb->m_NbPads, sizeof( D_PAD *), (int(*)(const void *, const void *)) tri_par_X); if(affiche) Affiche_1_Parametre(this, -1,wxEmptyString, wxT("Conn Pads"),a_color); /* Raz des flags particuliers des segments de piste */ pt_piste = m_Pcb->m_Track; for ( ; pt_piste != NULL; pt_piste = (TRACK*) pt_piste->Pnext) { pt_piste->SetState(BUSY|EDIT|BEGIN_ONPAD|END_ONPAD, OFF); pt_piste->m_NetCode = 0; } pt_piste = m_Pcb->m_Track; for ( ; pt_piste != NULL; pt_piste = (TRACK*) pt_piste->Pnext) { flag = 0; masque_layer = g_TabOneLayerMask[pt_piste->m_Layer]; /* y a t-il une pastille sur une extremite */ pt_piste->start = SuperFast_Locate_Pad_Connecte(m_Pcb, pt_mem, pt_piste->m_Start.x, pt_piste->m_Start.y, masque_layer); if( pt_piste->start != NULL) { pt_piste->SetState( BEGIN_ONPAD, ON); pt_piste->m_NetCode = ((D_PAD*)(pt_piste->start))->m_NetCode; } pt_piste->end = SuperFast_Locate_Pad_Connecte(m_Pcb, pt_mem, pt_piste->m_End.x, pt_piste->m_End.y, masque_layer); if( pt_piste->end != NULL) { pt_piste->SetState(END_ONPAD, ON); pt_piste->m_NetCode = ((D_PAD*)(pt_piste->end))->m_NetCode; } } MyFree(pt_mem); //////////////////////////////////////////////////// // Calcul de la connexite entre segments de piste // //////////////////////////////////////////////////// /* Les pointeurs .start et .end sont mis a jour, s'ils etaient NULLs. La connexion est alors du type segment a segment */ if(affiche) Affiche_1_Parametre(this, POS_AFF_CHREF,wxEmptyString, wxT("Conn Segm"), a_color); for ( pt_piste = m_Pcb->m_Track; pt_piste != NULL; pt_piste = (TRACK*) pt_piste->Pnext) { if ( pt_piste->start == NULL ) { pt_piste->start = Locate_Piste_Connectee(pt_piste, m_Pcb->m_Track,NULL,START); } if ( pt_piste->end == NULL ) { pt_piste->end = Locate_Piste_Connectee(pt_piste, m_Pcb->m_Track,NULL,END); } } //////////////////////////////// // Reattribution des net_code // //////////////////////////////// a_color = YELLOW; if(affiche) Affiche_1_Parametre(this, POS_AFF_CHREF,wxEmptyString, wxT("Net->Segm"),a_color); while(new_passe_request) { new_passe_request = 0; for ( pt_piste = m_Pcb->m_Track; pt_piste != NULL; pt_piste = (TRACK*) pt_piste->Pnext) { /* Traitement du point de debut */ PtStruct = (EDA_BaseStruct*)pt_piste->start; if( PtStruct && (PtStruct->m_StructType != TYPEPAD) ) { // start sur piste pt_next = (TRACK*)PtStruct; if(pt_piste->m_NetCode) { if(pt_next->m_NetCode == 0) { new_passe_request = 1; pt_next->m_NetCode = pt_piste->m_NetCode; } } else { if(pt_next->m_NetCode != 0) { pt_piste->m_NetCode = pt_next->m_NetCode; new_passe_request = 1; } } } /* Localisation du point de fin */ PtStruct = pt_piste->end; if( PtStruct &&(PtStruct->m_StructType != TYPEPAD) ) { // End sur piste pt_next = (TRACK*)PtStruct; if(pt_piste->m_NetCode) { if(pt_next->m_NetCode == 0) { new_passe_request = 1; pt_next->m_NetCode = pt_piste->m_NetCode; } } else { if(pt_next->m_NetCode != 0) { pt_piste->m_NetCode = pt_next->m_NetCode; new_passe_request = 1; } } } } } if( affiche ) Affiche_1_Parametre(this, -1,wxEmptyString, wxT("Reorder "),a_color); /* Reclassemment des pistes par numero de net: */ RebuildTrackChain(m_Pcb); if( affiche ) Affiche_1_Parametre(this, -1,wxEmptyString, wxT(" "),a_color); }