Example #1
0
/* 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 );
}
Example #2
0
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);
}