Loading change_log.txt +11 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,17 @@ Started 2007-June-11 Please add newer entries at the top, list the date and your name with email address. 2007-Oct-17 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr> ================================================================================ + pcbnew: Removed enhancements in connectivity computation because rastnest computation does not work (errors) with short track segments (lenght < width) . This is not a bug, but an algorithm problem, so I must work on algos. 2007-Oct-17 UPDATE Geoff Harland <gharlandau@yahoo.com.au> ================================================================================ + pcbnew Loading include/wxstruct.h +0 −1 Original line number Diff line number Diff line Loading @@ -502,7 +502,6 @@ public: int* build_ratsnest_pad( EDA_BaseStruct* ref, const wxPoint& refpos, bool init ); void Tst_Ratsnest( wxDC* DC, int ref_netcode ); void Recalcule_all_net_connexion( wxDC* DC ); void test_connexions( wxDC* DC ); void test_1_net_connexion( wxDC* DC, int net_code ); void reattribution_reference_piste( int affiche ); Loading pcbnew/class_track.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,28 @@ #include "protos.h" // #define RATSNET_DEBUG #ifdef RATSNET_DEBUG /**************************************/ void DbgDisplayTrackInfos(TRACK * track) /**************************************/ /* Only for ratsnest debug */ { wxString msg; msg << wxT("Netcode ") << track->GetNet(); msg << wxT(" - ") << track->GetSubNet(); msg << wxT("\nptrS ") << (unsigned) track->start; msg << wxT(" ptrE ") << (unsigned) track->end; msg << wxT(" this ") << (unsigned) track; wxMessageBox(msg); } #endif /**************************************/ /* Classes pour Pistes, Vias et Zones */ /**************************************/ Loading Loading @@ -715,6 +737,9 @@ void TRACK::Display_Infos( WinEDA_DrawFrame* frame ) { wxString msg; int text_pos; #ifdef RATSNET_DEBUG DbgDisplayTrackInfos(this); #endif frame->MsgPanel->EraseMsgBox(); Loading Loading @@ -865,6 +890,7 @@ bool TRACK::HitTest( const wxPoint& ref_pos ) } #if defined(DEBUG) /** Loading pcbnew/connect.cpp +127 −154 Original line number Diff line number Diff line Loading @@ -15,14 +15,11 @@ /* variables locales */ /* routines exportees */ void Recalcule_all_net_connexion( wxDC* DC ); /* Routines locales */ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn ); static void calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn ); static void RebuildTrackChain( BOARD* pcb ); static int tri_par_netcode( TRACK** pt_ref, TRACK** pt_compare ); static int Sort_By_NetCode( TRACK** pt_ref, TRACK** pt_compare ); /*..*/ Loading Loading @@ -101,7 +98,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn ) TRACK* pt_autre_piste; BOARD_ITEM* PtStruct; /* Initialisations prealables */ /* Clear variables used in computations */ pt_conn = pt_start_conn; for( ; pt_conn != NULL; pt_conn = (TRACK*) pt_conn->Pnext ) { Loading Loading @@ -304,38 +301,6 @@ void WinEDA_BasePcbFrame::test_connexions( wxDC* DC ) } /**************************************************************/ void WinEDA_BasePcbFrame::Recalcule_all_net_connexion( wxDC* DC ) /**************************************************************/ /* * Routine Recalculant les pointeurs sur connexions types piste a piste * relatives a tous les nets. * Cette routine est utilisee apres reclassement des segments de piste par * ordre de net_code, puisque des pointeurs sur connexions deviennent faux * ( les pointeurs type pad restent bons ) */ { TRACK* EndConn; int net_code, net_code_max; if( m_Pcb->m_Track == NULL ) return; /* calcul du net_code max */ EndConn = m_Pcb->m_Track; while( EndConn->Pnext ) EndConn = (TRACK*) EndConn->Pnext; net_code_max = EndConn->GetNet(); for( net_code = 0; net_code <= net_code_max; net_code++ ) { test_1_net_connexion( DC, net_code ); } } /*************************************************************************/ void WinEDA_BasePcbFrame::test_1_net_connexion( wxDC* DC, int net_code ) /*************************************************************************/ Loading Loading @@ -396,26 +361,25 @@ void WinEDA_BasePcbFrame::test_1_net_connexion( wxDC* DC, int net_code ) } bool zflg; // DEBUG, must be removed /***************************************************************************/ static void calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn ) /***************************************************************************/ /* calcule la connexite d'un net constitue de segments de piste consecutifs. * Entree: * pt_start_conn = adresse du 1er segment ( debut du net ) * pt_end_conn = adr de fin (dernier segment) * Les connexions relatives aux pads doivent etre deja calculees, car elles * ne sont pas ici recalculees ( pour des raisons de temps de calcul, et * du fait que lors des modif de pistes, les pads ne sont pas touches /** Used after a track change (delete a track ou add a track) * Compute connections (initialize the .start and .end members) for a single net. * tracks must be sorted by net, as usual * @param pt_start_conn = first segment of the net * @param pt_end_conn = last segment of the net * Connections to pads are assumed to be already initialized. * If a track is deleted, the other pointers to pads do not change. * When a track is added, its pointers to pads are already initialized */ { TRACK* Track; /* Les pointeurs .start et .end sont mis a jour, si la * connexion est du type segment a segment. * la connexion sur pads est supposee etre deja calculee */ /* Raz des pointeurs sur pistes */ /* Reset the old connections type track to track */ for( Track = pt_start_conn; Track != NULL; Track = (TRACK*) Track->Pnext ) { Track->SetSubNet( 0 ); Loading @@ -430,10 +394,10 @@ static void calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn ) break; } /* calcul des connexions */ /* Update connections type track to track */ for( Track = pt_start_conn; Track != NULL; Track = (TRACK*) Track->Pnext ) { if( Track->Type() == TYPEVIA ) if( Track->Type() == TYPEVIA ) // A via can connect many tracks, we must search for all track segments in this net { TRACK* pt_segm; int layermask = Track->ReturnMaskLayer(); Loading @@ -457,42 +421,33 @@ static void calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn ) } } if( Track->start == NULL ) zflg = false; if( Track->start == NULL ) // end track not already connected, search a connection { Track->start = Locate_Piste_Connectee( Track, Track, pt_end_conn, START ); Track->start = Locate_Piste_Connectee( Track, pt_start_conn /*Track*/, pt_end_conn, START ); } if( Track->end == NULL ) if( Track->end == NULL ) // end track not already connected, search a connection { Track->end = Locate_Piste_Connectee( Track, Track, pt_end_conn, END ); Track->end = Locate_Piste_Connectee( Track, pt_start_conn/*Track*/, pt_end_conn, END ); } if( Track == pt_end_conn ) break; } zflg = false; /* Generation des sous equipots du net */ propage_equipot( pt_start_conn, pt_end_conn ); } /********************************************/ /* Reattribution des net_codes de reference */ /********************************************/ /* * reattribution des net_codes aux segments de pistes. * Routine utilisee apres modification generale des noms de nets (apres * lecrure netliste ou edition de nets sur pads, effacement /ajout de * modules...) * * Elle se fait en 2 passes: * 1 - reattribution des segments commencant ( et/ou finissant ) sur 1 pad * les autres segments sont mis a reference NULLE * 2 - reattribution des segments restantes a ref NULLE */ #define POS_AFF_CHREF 62 /******************************************************************************/ static D_PAD* SuperFast_Locate_Pad_Connecte( BOARD* pcb, LISTE_PAD* pt_liste, int px, int py, int masque_layer ) /******************************************************************************/ /* recherche le pad connecte a l'extremite de la piste de coord px, py * parametres d'appel: * px, py = coord du point tst Loading @@ -507,9 +462,6 @@ static void calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn ) * * (la liste placee en m_Pcb->m_Pads et elle triee par netcodes croissants) */ static D_PAD* SuperFast_Locate_Pad_Connecte( BOARD* pcb, LISTE_PAD* pt_liste, int px, int py, int masque_layer ) { D_PAD* pad; LISTE_PAD* ptr_pad, * lim; Loading Loading @@ -608,9 +560,16 @@ LISTE_PAD* CreateSortedPadListByXCoord( BOARD* pcb ) } /******************************************************************/ /********************************************************************/ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) /******************************************************************/ /********************************************************************/ /* search connections between tracks and pads, and propagate pad net codes to the track segments * This is a 2 pass computation. * The pad netcodes are assumed to be initialized. * First: * We search a connection between a track segment and a pad: if found : this segment netcode is set to the pad netcode */ { TRACK* pt_piste, * pt_next; Loading @@ -634,29 +593,32 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) if( affiche ) Affiche_1_Parametre( this, -1, wxEmptyString, wxT( "Gen Pads " ), a_color ); ////////////////////////////////////////////////////// // Connexion des pistes accrochees a 1 pad au moins // ////////////////////////////////////////////////////// /**************************************************************/ /* Pass 1: search the connections between track ends and pads */ /**************************************************************/ pt_mem = CreateSortedPadListByXCoord( m_Pcb ); if( affiche ) Affiche_1_Parametre( this, -1, wxEmptyString, wxT( "Conn Pads" ), a_color ); /* Raz des flags particuliers des segments de piste */ /* Reset variables and flags used in computation */ 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->SetNet( 0 ); pt_piste->SetNet( 0 ); // net code = 0 means not connected } /* First pass: search connection between a track segment and a pad. * if found, set the track net code to the pad netcode */ pt_piste = m_Pcb->m_Track; for( ; pt_piste != NULL; pt_piste = (TRACK*) pt_piste->Pnext ) { flag = 0; masque_layer = g_TabOneLayerMask[pt_piste->GetLayer()]; /* y a t-il une pastille sur une extremite */ /* Search for a pad on the segment starting point */ pt_piste->start = SuperFast_Locate_Pad_Connecte( m_Pcb, pt_mem, pt_piste->m_Start.x, Loading @@ -668,6 +630,7 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) pt_piste->SetNet( ( (D_PAD*) (pt_piste->start) )->GetNet() ); } /* Search for a pad on the segment ending point */ pt_piste->end = SuperFast_Locate_Pad_Connecte( m_Pcb, pt_mem, pt_piste->m_End.x, Loading @@ -683,12 +646,14 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) MyFree( pt_mem ); //////////////////////////////////////////////////// // Calcul de la connexite entre segments de piste // //////////////////////////////////////////////////// /*****************************************************/ /* Pass 2: search the connections between track ends */ /*****************************************************/ /* Les pointeurs .start et .end sont mis a jour, s'ils etaient NULLs. * La connexion est alors du type segment a segment /* the .start et .end member pointers are updated, only if NULLs * (if not nuls, the end is already connected to a pad). * the connection (if found) is between segments * when a track has a net code and the other has a null net code, the null net code is changed */ if( affiche ) Affiche_1_Parametre( this, POS_AFF_CHREF, wxEmptyString, wxT( "Conn Segm" ), a_color ); Loading @@ -706,9 +671,9 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) } } //////////////////////////////// // Reattribution des net_code // //////////////////////////////// /**********************************************************/ /* Propagate net codes from a segment to an other segment */ /**********************************************************/ a_color = YELLOW; Loading Loading @@ -751,9 +716,16 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) pt_piste->SetState( BUSY, OFF ); } /* set the netcode of connected tracks: if at track is connected to a pad, its net code is already set. * if the current track is connected to an other track: * if a track has a net code, it is used for the other track. * Thus there is a propagation of the netcode from a track to an other. * if none of the 2 track has a net code we do nothing * the iteration is stopped when no new change occurs */ for( pt_piste = m_Pcb->m_Track; pt_piste != NULL; pt_piste = pt_piste->Next() ) { /* Traitement du point de debut */ /* look for the connection to the current segment starting point */ PtStruct = (BOARD_ITEM*) pt_piste->start; if( PtStruct && (PtStruct->Type() != TYPEPAD) ) { Loading @@ -761,15 +733,15 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) pt_next = (TRACK*) PtStruct; if( pt_piste->GetNet() ) { if( pt_next->GetNet() == 0 ) if( pt_next->GetNet() == 0 ) // the current track has a netcode, we use it for the other track { new_passe_request = 1; new_passe_request = 1; // A change is made: a new iteration is requested. pt_next->SetNet( pt_piste->GetNet() ); } } else { if( pt_next->GetNet() != 0 ) if( pt_next->GetNet() != 0 ) // the other track has a netcode, we use it for the current track { pt_piste->SetNet( pt_next->GetNet() ); new_passe_request = 1; Loading @@ -777,12 +749,13 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) } } /* Localisation du point de fin */ /* look for the connection to the current segment ending point */ PtStruct = pt_piste->end; if( PtStruct &&(PtStruct->Type() != TYPEPAD) ) { // End sur piste pt_next = (TRACK*) PtStruct; // End on an other track: propagate netcode if possible if( pt_piste->GetNet() ) { if( pt_next->GetNet() == 0 ) Loading @@ -803,7 +776,7 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) } } /* Reclassemment des pistes par numero de net: */ /* Sort the track list by net codes: */ if( affiche ) Affiche_1_Parametre( this, -1, wxEmptyString, wxT( "Reorder " ), a_color ); RebuildTrackChain( m_Pcb ); Loading @@ -817,7 +790,7 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) * routine de tri de connexion utilisee par la fonction QSORT * le tri est fait par numero de net */ int tri_par_netcode( TRACK** pt_ref, TRACK** pt_compare ) int Sort_By_NetCode( TRACK** pt_ref, TRACK** pt_compare ) { int ii; Loading Loading @@ -851,7 +824,7 @@ static void RebuildTrackChain( BOARD* pcb ) } qsort( Liste, nbsegm, sizeof(TRACK*), ( int( * ) ( const void*, const void* ) )tri_par_netcode ); ( int( * ) ( const void*, const void* ) )Sort_By_NetCode ); /* Update the linked list pointers */ Loading pcbnew/locate.cpp +42 −27 Original line number Diff line number Diff line Loading @@ -664,18 +664,27 @@ TEXTE_MODULE* LocateTexteModule( BOARD* Pcb, MODULE** PtModule, int typeloc ) /******************************************/ inline int Dist(wxPoint & p1, wxPoint & p2) /******************************************/ /******************************************************************/ inline bool IsPointsAreNear(wxPoint & p1, wxPoint & p2, int max_dist) /******************************************************************/ /* return the dist min between p1 and p2 return true if the dist between p1 and p2 < max_dist Currently in test (currently rasnest algos work only if p1 == p2 */ { extern bool zflg; if (zflg == true) { int dist; dist = abs(p1.x - p2.x) + abs (p1.y - p2.y); dist *= 7; dist /= 10; return dist; if ( dist < max_dist ) return true; } else if ( p1 == p2 ) return true; //#endif return false; } /**************************************************************/ Loading @@ -683,25 +692,30 @@ TRACK* Locate_Piste_Connectee( TRACK* PtRefSegm, TRACK* pt_base, TRACK* pt_lim, int extr ) /**************************************************************/ /* recherche le segment connecte au segment pointe par * PtRefSegm: * si int extr = START, le point de debut du segment est utilise * si int extr = END, le point de fin du segment est utilise * La recherche ne se fait que sur les EXTREMITES des segments /** Search for the track (or via) segment which is connected to the track segment PtRefSegm * if extr == START, the starting track segment PtRefSegm is used to locate a connected segment * if extr == END, the ending track segment PtRefSegm is used * The test connection consider only end track segments * * Search is made from pt_base to pt_lim (in the track linked list) * if pt_lim == NULL, the search is made from pt_base to the end of list * * In order to have a fast computation time: * a first search is made considering only the +/- 50 next door neightbour of PtRefSegm. * if no track is found : the entire list is tested * * La recherche se fait de l'adresse : * pt_base a pt_lim (borne finale comprise) * si pt_lim = NULL, la recherche se fait jusqu'a la fin de la liste * Afin d'accelerer la recherche, une 1ere passe est faite, avec une recherche * realisee sur un ensemble de +/- 100 points autour du point courant. * Si echec: recherche generale * @param PtRefSegm = reference segment * @param pt_base = lower limit for search * @param pt_lim = upper limit for search (can be NULL) * @param extr = START or END = end of ref track segment to use in tests */ { #define NEIGHTBOUR_COUNT_MAX 50 TRACK* PtSegmB, * PtSegmN; int Reflayer; wxPoint pos_ref; int ii; int min_dist; int max_dist; if( extr == START ) pos_ref = PtRefSegm->m_Start; Loading @@ -713,7 +727,7 @@ TRACK* Locate_Piste_Connectee( TRACK* PtRefSegm, TRACK* pt_base, /* 1ere passe */ PtSegmB = PtSegmN = PtRefSegm; for( ii = 0; ii < 50; ii++ ) for( ii = 0; ii < NEIGHTBOUR_COUNT_MAX; ii++ ) { if( (PtSegmN == NULL) && (PtSegmB == NULL) ) break; Loading @@ -725,15 +739,16 @@ TRACK* Locate_Piste_Connectee( TRACK* PtRefSegm, TRACK* pt_base, if( PtSegmN == PtRefSegm ) goto suite; min_dist = (PtSegmN->m_Width + PtRefSegm->m_Width)/2; /* max_dist is the max distance between 2 tack ends which ensure a copper continuty */ max_dist = (PtSegmN->m_Width + PtRefSegm->m_Width)/2; if( Dist(pos_ref, PtSegmN->m_Start) < min_dist ) if( IsPointsAreNear(pos_ref, PtSegmN->m_Start, max_dist) ) { /* Test des couches */ if( Reflayer & PtSegmN->ReturnMaskLayer() ) return PtSegmN; } if( Dist(pos_ref, PtSegmN->m_End) < min_dist ) if( IsPointsAreNear(pos_ref, PtSegmN->m_End, max_dist) ) { /* Test des couches */ if( Reflayer & PtSegmN->ReturnMaskLayer() ) return PtSegmN; Loading @@ -752,15 +767,15 @@ suite: if( PtSegmB == PtRefSegm ) goto suite1; min_dist = (PtSegmB->m_Width + PtRefSegm->m_Width)/2; max_dist = (PtSegmB->m_Width + PtRefSegm->m_Width)/2; if( Dist(pos_ref, PtSegmB->m_Start) < min_dist ) if( IsPointsAreNear(pos_ref, PtSegmB->m_Start, max_dist) ) { /* Test des couches */ if( Reflayer & PtSegmB->ReturnMaskLayer() ) return PtSegmB; } if( Dist(pos_ref, PtSegmB->m_End) < min_dist ) if( IsPointsAreNear(pos_ref, PtSegmB->m_End, max_dist) ) { /* Test des couches */ if( Reflayer & PtSegmB->ReturnMaskLayer() ) return PtSegmB; Loading Loading @@ -792,15 +807,15 @@ suite1: } min_dist = (PtSegmN->m_Width + PtRefSegm->m_Width)/2; max_dist = (PtSegmN->m_Width + PtRefSegm->m_Width)/2; if( Dist(pos_ref,PtSegmN->m_Start) < min_dist ) if( IsPointsAreNear(pos_ref,PtSegmN->m_Start, max_dist) ) { /* Test des couches */ if( Reflayer & PtSegmN->ReturnMaskLayer() ) return PtSegmN; } if( Dist(pos_ref, PtSegmN->m_End) < min_dist ) if( IsPointsAreNear(pos_ref, PtSegmN->m_End, max_dist) ) { /* Test des couches */ if( Reflayer & PtSegmN->ReturnMaskLayer() ) return PtSegmN; Loading Loading
change_log.txt +11 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,17 @@ Started 2007-June-11 Please add newer entries at the top, list the date and your name with email address. 2007-Oct-17 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr> ================================================================================ + pcbnew: Removed enhancements in connectivity computation because rastnest computation does not work (errors) with short track segments (lenght < width) . This is not a bug, but an algorithm problem, so I must work on algos. 2007-Oct-17 UPDATE Geoff Harland <gharlandau@yahoo.com.au> ================================================================================ + pcbnew Loading
include/wxstruct.h +0 −1 Original line number Diff line number Diff line Loading @@ -502,7 +502,6 @@ public: int* build_ratsnest_pad( EDA_BaseStruct* ref, const wxPoint& refpos, bool init ); void Tst_Ratsnest( wxDC* DC, int ref_netcode ); void Recalcule_all_net_connexion( wxDC* DC ); void test_connexions( wxDC* DC ); void test_1_net_connexion( wxDC* DC, int net_code ); void reattribution_reference_piste( int affiche ); Loading
pcbnew/class_track.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,28 @@ #include "protos.h" // #define RATSNET_DEBUG #ifdef RATSNET_DEBUG /**************************************/ void DbgDisplayTrackInfos(TRACK * track) /**************************************/ /* Only for ratsnest debug */ { wxString msg; msg << wxT("Netcode ") << track->GetNet(); msg << wxT(" - ") << track->GetSubNet(); msg << wxT("\nptrS ") << (unsigned) track->start; msg << wxT(" ptrE ") << (unsigned) track->end; msg << wxT(" this ") << (unsigned) track; wxMessageBox(msg); } #endif /**************************************/ /* Classes pour Pistes, Vias et Zones */ /**************************************/ Loading Loading @@ -715,6 +737,9 @@ void TRACK::Display_Infos( WinEDA_DrawFrame* frame ) { wxString msg; int text_pos; #ifdef RATSNET_DEBUG DbgDisplayTrackInfos(this); #endif frame->MsgPanel->EraseMsgBox(); Loading Loading @@ -865,6 +890,7 @@ bool TRACK::HitTest( const wxPoint& ref_pos ) } #if defined(DEBUG) /** Loading
pcbnew/connect.cpp +127 −154 Original line number Diff line number Diff line Loading @@ -15,14 +15,11 @@ /* variables locales */ /* routines exportees */ void Recalcule_all_net_connexion( wxDC* DC ); /* Routines locales */ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn ); static void calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn ); static void RebuildTrackChain( BOARD* pcb ); static int tri_par_netcode( TRACK** pt_ref, TRACK** pt_compare ); static int Sort_By_NetCode( TRACK** pt_ref, TRACK** pt_compare ); /*..*/ Loading Loading @@ -101,7 +98,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn ) TRACK* pt_autre_piste; BOARD_ITEM* PtStruct; /* Initialisations prealables */ /* Clear variables used in computations */ pt_conn = pt_start_conn; for( ; pt_conn != NULL; pt_conn = (TRACK*) pt_conn->Pnext ) { Loading Loading @@ -304,38 +301,6 @@ void WinEDA_BasePcbFrame::test_connexions( wxDC* DC ) } /**************************************************************/ void WinEDA_BasePcbFrame::Recalcule_all_net_connexion( wxDC* DC ) /**************************************************************/ /* * Routine Recalculant les pointeurs sur connexions types piste a piste * relatives a tous les nets. * Cette routine est utilisee apres reclassement des segments de piste par * ordre de net_code, puisque des pointeurs sur connexions deviennent faux * ( les pointeurs type pad restent bons ) */ { TRACK* EndConn; int net_code, net_code_max; if( m_Pcb->m_Track == NULL ) return; /* calcul du net_code max */ EndConn = m_Pcb->m_Track; while( EndConn->Pnext ) EndConn = (TRACK*) EndConn->Pnext; net_code_max = EndConn->GetNet(); for( net_code = 0; net_code <= net_code_max; net_code++ ) { test_1_net_connexion( DC, net_code ); } } /*************************************************************************/ void WinEDA_BasePcbFrame::test_1_net_connexion( wxDC* DC, int net_code ) /*************************************************************************/ Loading Loading @@ -396,26 +361,25 @@ void WinEDA_BasePcbFrame::test_1_net_connexion( wxDC* DC, int net_code ) } bool zflg; // DEBUG, must be removed /***************************************************************************/ static void calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn ) /***************************************************************************/ /* calcule la connexite d'un net constitue de segments de piste consecutifs. * Entree: * pt_start_conn = adresse du 1er segment ( debut du net ) * pt_end_conn = adr de fin (dernier segment) * Les connexions relatives aux pads doivent etre deja calculees, car elles * ne sont pas ici recalculees ( pour des raisons de temps de calcul, et * du fait que lors des modif de pistes, les pads ne sont pas touches /** Used after a track change (delete a track ou add a track) * Compute connections (initialize the .start and .end members) for a single net. * tracks must be sorted by net, as usual * @param pt_start_conn = first segment of the net * @param pt_end_conn = last segment of the net * Connections to pads are assumed to be already initialized. * If a track is deleted, the other pointers to pads do not change. * When a track is added, its pointers to pads are already initialized */ { TRACK* Track; /* Les pointeurs .start et .end sont mis a jour, si la * connexion est du type segment a segment. * la connexion sur pads est supposee etre deja calculee */ /* Raz des pointeurs sur pistes */ /* Reset the old connections type track to track */ for( Track = pt_start_conn; Track != NULL; Track = (TRACK*) Track->Pnext ) { Track->SetSubNet( 0 ); Loading @@ -430,10 +394,10 @@ static void calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn ) break; } /* calcul des connexions */ /* Update connections type track to track */ for( Track = pt_start_conn; Track != NULL; Track = (TRACK*) Track->Pnext ) { if( Track->Type() == TYPEVIA ) if( Track->Type() == TYPEVIA ) // A via can connect many tracks, we must search for all track segments in this net { TRACK* pt_segm; int layermask = Track->ReturnMaskLayer(); Loading @@ -457,42 +421,33 @@ static void calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn ) } } if( Track->start == NULL ) zflg = false; if( Track->start == NULL ) // end track not already connected, search a connection { Track->start = Locate_Piste_Connectee( Track, Track, pt_end_conn, START ); Track->start = Locate_Piste_Connectee( Track, pt_start_conn /*Track*/, pt_end_conn, START ); } if( Track->end == NULL ) if( Track->end == NULL ) // end track not already connected, search a connection { Track->end = Locate_Piste_Connectee( Track, Track, pt_end_conn, END ); Track->end = Locate_Piste_Connectee( Track, pt_start_conn/*Track*/, pt_end_conn, END ); } if( Track == pt_end_conn ) break; } zflg = false; /* Generation des sous equipots du net */ propage_equipot( pt_start_conn, pt_end_conn ); } /********************************************/ /* Reattribution des net_codes de reference */ /********************************************/ /* * reattribution des net_codes aux segments de pistes. * Routine utilisee apres modification generale des noms de nets (apres * lecrure netliste ou edition de nets sur pads, effacement /ajout de * modules...) * * Elle se fait en 2 passes: * 1 - reattribution des segments commencant ( et/ou finissant ) sur 1 pad * les autres segments sont mis a reference NULLE * 2 - reattribution des segments restantes a ref NULLE */ #define POS_AFF_CHREF 62 /******************************************************************************/ static D_PAD* SuperFast_Locate_Pad_Connecte( BOARD* pcb, LISTE_PAD* pt_liste, int px, int py, int masque_layer ) /******************************************************************************/ /* recherche le pad connecte a l'extremite de la piste de coord px, py * parametres d'appel: * px, py = coord du point tst Loading @@ -507,9 +462,6 @@ static void calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn ) * * (la liste placee en m_Pcb->m_Pads et elle triee par netcodes croissants) */ static D_PAD* SuperFast_Locate_Pad_Connecte( BOARD* pcb, LISTE_PAD* pt_liste, int px, int py, int masque_layer ) { D_PAD* pad; LISTE_PAD* ptr_pad, * lim; Loading Loading @@ -608,9 +560,16 @@ LISTE_PAD* CreateSortedPadListByXCoord( BOARD* pcb ) } /******************************************************************/ /********************************************************************/ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) /******************************************************************/ /********************************************************************/ /* search connections between tracks and pads, and propagate pad net codes to the track segments * This is a 2 pass computation. * The pad netcodes are assumed to be initialized. * First: * We search a connection between a track segment and a pad: if found : this segment netcode is set to the pad netcode */ { TRACK* pt_piste, * pt_next; Loading @@ -634,29 +593,32 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) if( affiche ) Affiche_1_Parametre( this, -1, wxEmptyString, wxT( "Gen Pads " ), a_color ); ////////////////////////////////////////////////////// // Connexion des pistes accrochees a 1 pad au moins // ////////////////////////////////////////////////////// /**************************************************************/ /* Pass 1: search the connections between track ends and pads */ /**************************************************************/ pt_mem = CreateSortedPadListByXCoord( m_Pcb ); if( affiche ) Affiche_1_Parametre( this, -1, wxEmptyString, wxT( "Conn Pads" ), a_color ); /* Raz des flags particuliers des segments de piste */ /* Reset variables and flags used in computation */ 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->SetNet( 0 ); pt_piste->SetNet( 0 ); // net code = 0 means not connected } /* First pass: search connection between a track segment and a pad. * if found, set the track net code to the pad netcode */ pt_piste = m_Pcb->m_Track; for( ; pt_piste != NULL; pt_piste = (TRACK*) pt_piste->Pnext ) { flag = 0; masque_layer = g_TabOneLayerMask[pt_piste->GetLayer()]; /* y a t-il une pastille sur une extremite */ /* Search for a pad on the segment starting point */ pt_piste->start = SuperFast_Locate_Pad_Connecte( m_Pcb, pt_mem, pt_piste->m_Start.x, Loading @@ -668,6 +630,7 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) pt_piste->SetNet( ( (D_PAD*) (pt_piste->start) )->GetNet() ); } /* Search for a pad on the segment ending point */ pt_piste->end = SuperFast_Locate_Pad_Connecte( m_Pcb, pt_mem, pt_piste->m_End.x, Loading @@ -683,12 +646,14 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) MyFree( pt_mem ); //////////////////////////////////////////////////// // Calcul de la connexite entre segments de piste // //////////////////////////////////////////////////// /*****************************************************/ /* Pass 2: search the connections between track ends */ /*****************************************************/ /* Les pointeurs .start et .end sont mis a jour, s'ils etaient NULLs. * La connexion est alors du type segment a segment /* the .start et .end member pointers are updated, only if NULLs * (if not nuls, the end is already connected to a pad). * the connection (if found) is between segments * when a track has a net code and the other has a null net code, the null net code is changed */ if( affiche ) Affiche_1_Parametre( this, POS_AFF_CHREF, wxEmptyString, wxT( "Conn Segm" ), a_color ); Loading @@ -706,9 +671,9 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) } } //////////////////////////////// // Reattribution des net_code // //////////////////////////////// /**********************************************************/ /* Propagate net codes from a segment to an other segment */ /**********************************************************/ a_color = YELLOW; Loading Loading @@ -751,9 +716,16 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) pt_piste->SetState( BUSY, OFF ); } /* set the netcode of connected tracks: if at track is connected to a pad, its net code is already set. * if the current track is connected to an other track: * if a track has a net code, it is used for the other track. * Thus there is a propagation of the netcode from a track to an other. * if none of the 2 track has a net code we do nothing * the iteration is stopped when no new change occurs */ for( pt_piste = m_Pcb->m_Track; pt_piste != NULL; pt_piste = pt_piste->Next() ) { /* Traitement du point de debut */ /* look for the connection to the current segment starting point */ PtStruct = (BOARD_ITEM*) pt_piste->start; if( PtStruct && (PtStruct->Type() != TYPEPAD) ) { Loading @@ -761,15 +733,15 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) pt_next = (TRACK*) PtStruct; if( pt_piste->GetNet() ) { if( pt_next->GetNet() == 0 ) if( pt_next->GetNet() == 0 ) // the current track has a netcode, we use it for the other track { new_passe_request = 1; new_passe_request = 1; // A change is made: a new iteration is requested. pt_next->SetNet( pt_piste->GetNet() ); } } else { if( pt_next->GetNet() != 0 ) if( pt_next->GetNet() != 0 ) // the other track has a netcode, we use it for the current track { pt_piste->SetNet( pt_next->GetNet() ); new_passe_request = 1; Loading @@ -777,12 +749,13 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) } } /* Localisation du point de fin */ /* look for the connection to the current segment ending point */ PtStruct = pt_piste->end; if( PtStruct &&(PtStruct->Type() != TYPEPAD) ) { // End sur piste pt_next = (TRACK*) PtStruct; // End on an other track: propagate netcode if possible if( pt_piste->GetNet() ) { if( pt_next->GetNet() == 0 ) Loading @@ -803,7 +776,7 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) } } /* Reclassemment des pistes par numero de net: */ /* Sort the track list by net codes: */ if( affiche ) Affiche_1_Parametre( this, -1, wxEmptyString, wxT( "Reorder " ), a_color ); RebuildTrackChain( m_Pcb ); Loading @@ -817,7 +790,7 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) * routine de tri de connexion utilisee par la fonction QSORT * le tri est fait par numero de net */ int tri_par_netcode( TRACK** pt_ref, TRACK** pt_compare ) int Sort_By_NetCode( TRACK** pt_ref, TRACK** pt_compare ) { int ii; Loading Loading @@ -851,7 +824,7 @@ static void RebuildTrackChain( BOARD* pcb ) } qsort( Liste, nbsegm, sizeof(TRACK*), ( int( * ) ( const void*, const void* ) )tri_par_netcode ); ( int( * ) ( const void*, const void* ) )Sort_By_NetCode ); /* Update the linked list pointers */ Loading
pcbnew/locate.cpp +42 −27 Original line number Diff line number Diff line Loading @@ -664,18 +664,27 @@ TEXTE_MODULE* LocateTexteModule( BOARD* Pcb, MODULE** PtModule, int typeloc ) /******************************************/ inline int Dist(wxPoint & p1, wxPoint & p2) /******************************************/ /******************************************************************/ inline bool IsPointsAreNear(wxPoint & p1, wxPoint & p2, int max_dist) /******************************************************************/ /* return the dist min between p1 and p2 return true if the dist between p1 and p2 < max_dist Currently in test (currently rasnest algos work only if p1 == p2 */ { extern bool zflg; if (zflg == true) { int dist; dist = abs(p1.x - p2.x) + abs (p1.y - p2.y); dist *= 7; dist /= 10; return dist; if ( dist < max_dist ) return true; } else if ( p1 == p2 ) return true; //#endif return false; } /**************************************************************/ Loading @@ -683,25 +692,30 @@ TRACK* Locate_Piste_Connectee( TRACK* PtRefSegm, TRACK* pt_base, TRACK* pt_lim, int extr ) /**************************************************************/ /* recherche le segment connecte au segment pointe par * PtRefSegm: * si int extr = START, le point de debut du segment est utilise * si int extr = END, le point de fin du segment est utilise * La recherche ne se fait que sur les EXTREMITES des segments /** Search for the track (or via) segment which is connected to the track segment PtRefSegm * if extr == START, the starting track segment PtRefSegm is used to locate a connected segment * if extr == END, the ending track segment PtRefSegm is used * The test connection consider only end track segments * * Search is made from pt_base to pt_lim (in the track linked list) * if pt_lim == NULL, the search is made from pt_base to the end of list * * In order to have a fast computation time: * a first search is made considering only the +/- 50 next door neightbour of PtRefSegm. * if no track is found : the entire list is tested * * La recherche se fait de l'adresse : * pt_base a pt_lim (borne finale comprise) * si pt_lim = NULL, la recherche se fait jusqu'a la fin de la liste * Afin d'accelerer la recherche, une 1ere passe est faite, avec une recherche * realisee sur un ensemble de +/- 100 points autour du point courant. * Si echec: recherche generale * @param PtRefSegm = reference segment * @param pt_base = lower limit for search * @param pt_lim = upper limit for search (can be NULL) * @param extr = START or END = end of ref track segment to use in tests */ { #define NEIGHTBOUR_COUNT_MAX 50 TRACK* PtSegmB, * PtSegmN; int Reflayer; wxPoint pos_ref; int ii; int min_dist; int max_dist; if( extr == START ) pos_ref = PtRefSegm->m_Start; Loading @@ -713,7 +727,7 @@ TRACK* Locate_Piste_Connectee( TRACK* PtRefSegm, TRACK* pt_base, /* 1ere passe */ PtSegmB = PtSegmN = PtRefSegm; for( ii = 0; ii < 50; ii++ ) for( ii = 0; ii < NEIGHTBOUR_COUNT_MAX; ii++ ) { if( (PtSegmN == NULL) && (PtSegmB == NULL) ) break; Loading @@ -725,15 +739,16 @@ TRACK* Locate_Piste_Connectee( TRACK* PtRefSegm, TRACK* pt_base, if( PtSegmN == PtRefSegm ) goto suite; min_dist = (PtSegmN->m_Width + PtRefSegm->m_Width)/2; /* max_dist is the max distance between 2 tack ends which ensure a copper continuty */ max_dist = (PtSegmN->m_Width + PtRefSegm->m_Width)/2; if( Dist(pos_ref, PtSegmN->m_Start) < min_dist ) if( IsPointsAreNear(pos_ref, PtSegmN->m_Start, max_dist) ) { /* Test des couches */ if( Reflayer & PtSegmN->ReturnMaskLayer() ) return PtSegmN; } if( Dist(pos_ref, PtSegmN->m_End) < min_dist ) if( IsPointsAreNear(pos_ref, PtSegmN->m_End, max_dist) ) { /* Test des couches */ if( Reflayer & PtSegmN->ReturnMaskLayer() ) return PtSegmN; Loading @@ -752,15 +767,15 @@ suite: if( PtSegmB == PtRefSegm ) goto suite1; min_dist = (PtSegmB->m_Width + PtRefSegm->m_Width)/2; max_dist = (PtSegmB->m_Width + PtRefSegm->m_Width)/2; if( Dist(pos_ref, PtSegmB->m_Start) < min_dist ) if( IsPointsAreNear(pos_ref, PtSegmB->m_Start, max_dist) ) { /* Test des couches */ if( Reflayer & PtSegmB->ReturnMaskLayer() ) return PtSegmB; } if( Dist(pos_ref, PtSegmB->m_End) < min_dist ) if( IsPointsAreNear(pos_ref, PtSegmB->m_End, max_dist) ) { /* Test des couches */ if( Reflayer & PtSegmB->ReturnMaskLayer() ) return PtSegmB; Loading Loading @@ -792,15 +807,15 @@ suite1: } min_dist = (PtSegmN->m_Width + PtRefSegm->m_Width)/2; max_dist = (PtSegmN->m_Width + PtRefSegm->m_Width)/2; if( Dist(pos_ref,PtSegmN->m_Start) < min_dist ) if( IsPointsAreNear(pos_ref,PtSegmN->m_Start, max_dist) ) { /* Test des couches */ if( Reflayer & PtSegmN->ReturnMaskLayer() ) return PtSegmN; } if( Dist(pos_ref, PtSegmN->m_End) < min_dist ) if( IsPointsAreNear(pos_ref, PtSegmN->m_End, max_dist) ) { /* Test des couches */ if( Reflayer & PtSegmN->ReturnMaskLayer() ) return PtSegmN; Loading