Commit 387a8763 authored by CHARRAS's avatar CHARRAS

Removed enhancements in connectivity computation (in certain cases, does not work)

parent 0d403649
...@@ -4,6 +4,17 @@ Started 2007-June-11 ...@@ -4,6 +4,17 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. 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> 2007-Oct-17 UPDATE Geoff Harland <gharlandau@yahoo.com.au>
================================================================================ ================================================================================
+ pcbnew + pcbnew
......
...@@ -502,7 +502,6 @@ public: ...@@ -502,7 +502,6 @@ public:
int* build_ratsnest_pad( EDA_BaseStruct* ref, const wxPoint& refpos, bool init ); int* build_ratsnest_pad( EDA_BaseStruct* ref, const wxPoint& refpos, bool init );
void Tst_Ratsnest( wxDC* DC, int ref_netcode ); void Tst_Ratsnest( wxDC* DC, int ref_netcode );
void Recalcule_all_net_connexion( wxDC* DC );
void test_connexions( wxDC* DC ); void test_connexions( wxDC* DC );
void test_1_net_connexion( wxDC* DC, int net_code ); void test_1_net_connexion( wxDC* DC, int net_code );
void reattribution_reference_piste( int affiche ); void reattribution_reference_piste( int affiche );
......
...@@ -16,6 +16,28 @@ ...@@ -16,6 +16,28 @@
#include "protos.h" #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 */ /* Classes pour Pistes, Vias et Zones */
/**************************************/ /**************************************/
...@@ -715,6 +737,9 @@ void TRACK::Display_Infos( WinEDA_DrawFrame* frame ) ...@@ -715,6 +737,9 @@ void TRACK::Display_Infos( WinEDA_DrawFrame* frame )
{ {
wxString msg; wxString msg;
int text_pos; int text_pos;
#ifdef RATSNET_DEBUG
DbgDisplayTrackInfos(this);
#endif
frame->MsgPanel->EraseMsgBox(); frame->MsgPanel->EraseMsgBox();
...@@ -865,6 +890,7 @@ bool TRACK::HitTest( const wxPoint& ref_pos ) ...@@ -865,6 +890,7 @@ bool TRACK::HitTest( const wxPoint& ref_pos )
} }
#if defined(DEBUG) #if defined(DEBUG)
/** /**
......
...@@ -15,14 +15,11 @@ ...@@ -15,14 +15,11 @@
/* variables locales */ /* variables locales */
/* routines exportees */
void Recalcule_all_net_connexion( wxDC* DC );
/* Routines locales */ /* Routines locales */
static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn ); 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 calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn );
static void RebuildTrackChain( BOARD* pcb ); 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 );
/*..*/ /*..*/
...@@ -95,13 +92,13 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn ) ...@@ -95,13 +92,13 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn )
* les segments de pistes sont tries par net_code * les segments de pistes sont tries par net_code
*/ */
{ {
TRACK* pt_conn; TRACK* pt_conn;
int sous_net_code; int sous_net_code;
D_PAD* pt_pad; D_PAD* pt_pad;
TRACK* pt_autre_piste; TRACK* pt_autre_piste;
BOARD_ITEM* PtStruct; BOARD_ITEM* PtStruct;
/* Initialisations prealables */ /* Clear variables used in computations */
pt_conn = pt_start_conn; pt_conn = pt_start_conn;
for( ; pt_conn != NULL; pt_conn = (TRACK*) pt_conn->Pnext ) for( ; pt_conn != NULL; pt_conn = (TRACK*) pt_conn->Pnext )
{ {
...@@ -118,7 +115,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn ) ...@@ -118,7 +115,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn )
break; break;
} }
sous_net_code = 1; sous_net_code = 1;
pt_start_conn->SetSubNet( sous_net_code ); pt_start_conn->SetSubNet( sous_net_code );
/* debut du calcul de propagation */ /* debut du calcul de propagation */
...@@ -127,17 +124,17 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn ) ...@@ -127,17 +124,17 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn )
{ {
/* Traitement des connexions a pads */ /* Traitement des connexions a pads */
PtStruct = pt_conn->start; PtStruct = pt_conn->start;
/* la connexion debute sur 1 pad */ /* la connexion debute sur 1 pad */
if( PtStruct && (PtStruct->Type() == TYPEPAD) ) if( PtStruct && (PtStruct->Type() == TYPEPAD) )
{ {
pt_pad = (D_PAD*) PtStruct; pt_pad = (D_PAD*) PtStruct;
if( pt_conn->GetSubNet() ) /* la connexion fait deja partie d'une chaine */ if( pt_conn->GetSubNet() ) /* la connexion fait deja partie d'une chaine */
{ {
if( pt_pad->m_physical_connexion > 0 ) /* le pad fait aussi partie d'une chaine */ if( pt_pad->m_physical_connexion > 0 ) /* le pad fait aussi partie d'une chaine */
{ {
change_equipot( pt_start_conn, pt_end_conn, change_equipot( pt_start_conn, pt_end_conn,
pt_pad->m_physical_connexion, pt_conn->GetSubNet() ); pt_pad->m_physical_connexion, pt_conn->GetSubNet() );
} }
else else
pt_pad->m_physical_connexion = pt_conn->GetSubNet(); pt_pad->m_physical_connexion = pt_conn->GetSubNet();
...@@ -150,7 +147,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn ) ...@@ -150,7 +147,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn )
} }
else else
{ {
sous_net_code++; sous_net_code++;
pt_conn->SetSubNet( sous_net_code ); pt_conn->SetSubNet( sous_net_code );
pt_pad->m_physical_connexion = pt_conn->GetSubNet(); pt_pad->m_physical_connexion = pt_conn->GetSubNet();
} }
...@@ -167,7 +164,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn ) ...@@ -167,7 +164,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn )
if( pt_pad->m_physical_connexion > 0 ) if( pt_pad->m_physical_connexion > 0 )
{ {
change_equipot( pt_start_conn, pt_end_conn, change_equipot( pt_start_conn, pt_end_conn,
pt_pad->m_physical_connexion, pt_conn->GetSubNet() ); pt_pad->m_physical_connexion, pt_conn->GetSubNet() );
} }
else else
pt_pad->m_physical_connexion = pt_conn->GetSubNet(); pt_pad->m_physical_connexion = pt_conn->GetSubNet();
...@@ -180,7 +177,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn ) ...@@ -180,7 +177,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn )
} }
else else
{ {
sous_net_code++; sous_net_code++;
pt_conn->SetSubNet( sous_net_code ); pt_conn->SetSubNet( sous_net_code );
pt_pad->m_physical_connexion = pt_conn->GetSubNet(); pt_pad->m_physical_connexion = pt_conn->GetSubNet();
} }
...@@ -191,7 +188,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn ) ...@@ -191,7 +188,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn )
/* traitement des connexions entre segments */ /* traitement des connexions entre segments */
PtStruct = pt_conn->start; PtStruct = pt_conn->start;
if( PtStruct && (PtStruct->Type() != TYPEPAD) ) if( PtStruct && (PtStruct->Type() != TYPEPAD) )
{ {
/* debut sur une autre piste */ /* debut sur une autre piste */
pt_autre_piste = (TRACK*) PtStruct; pt_autre_piste = (TRACK*) PtStruct;
...@@ -200,7 +197,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn ) ...@@ -200,7 +197,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn )
if( pt_autre_piste->GetSubNet() ) if( pt_autre_piste->GetSubNet() )
{ {
change_equipot( pt_start_conn, pt_end_conn, change_equipot( pt_start_conn, pt_end_conn,
pt_autre_piste->GetSubNet(), pt_conn->GetSubNet() ); pt_autre_piste->GetSubNet(), pt_conn->GetSubNet() );
} }
else else
{ {
...@@ -215,7 +212,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn ) ...@@ -215,7 +212,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn )
} }
else else
{ {
sous_net_code++; sous_net_code++;
pt_conn->SetSubNet( sous_net_code ); pt_conn->SetSubNet( sous_net_code );
pt_autre_piste->SetSubNet( pt_conn->GetSubNet() ); pt_autre_piste->SetSubNet( pt_conn->GetSubNet() );
} }
...@@ -224,16 +221,16 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn ) ...@@ -224,16 +221,16 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn )
PtStruct = pt_conn->end; PtStruct = pt_conn->end;
if( PtStruct && (PtStruct->Type() != TYPEPAD) ) if( PtStruct && (PtStruct->Type() != TYPEPAD) )
{ {
/* fin connectee a une autre piste */ /* fin connectee a une autre piste */
pt_autre_piste = (TRACK*) PtStruct; pt_autre_piste = (TRACK*) PtStruct;
if( pt_conn->GetSubNet() ) /* La connexion fait deja partie d'un block */ if( pt_conn->GetSubNet() ) /* La connexion fait deja partie d'un block */
{ {
if( pt_autre_piste->GetSubNet() ) if( pt_autre_piste->GetSubNet() )
{ {
change_equipot( pt_start_conn, pt_end_conn, change_equipot( pt_start_conn, pt_end_conn,
pt_autre_piste->GetSubNet(), pt_conn->GetSubNet() ); pt_autre_piste->GetSubNet(), pt_conn->GetSubNet() );
} }
else else
pt_autre_piste->SetSubNet( pt_conn->GetSubNet() ); pt_autre_piste->SetSubNet( pt_conn->GetSubNet() );
...@@ -246,7 +243,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn ) ...@@ -246,7 +243,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn )
} }
else else
{ {
sous_net_code++; sous_net_code++;
pt_conn->SetSubNet( sous_net_code ); pt_conn->SetSubNet( sous_net_code );
pt_autre_piste->SetSubNet( pt_conn->GetSubNet() ); pt_autre_piste->SetSubNet( pt_conn->GetSubNet() );
} }
...@@ -304,38 +301,6 @@ void WinEDA_BasePcbFrame::test_connexions( wxDC* DC ) ...@@ -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 ) void WinEDA_BasePcbFrame::test_1_net_connexion( wxDC* DC, int net_code )
/*************************************************************************/ /*************************************************************************/
...@@ -361,10 +326,10 @@ void WinEDA_BasePcbFrame::test_1_net_connexion( wxDC* DC, int net_code ) ...@@ -361,10 +326,10 @@ void WinEDA_BasePcbFrame::test_1_net_connexion( wxDC* DC, int net_code )
int pad_net_code = (*pt_pad)->GetNet(); int pad_net_code = (*pt_pad)->GetNet();
if( pad_net_code < net_code ) if( pad_net_code < net_code )
continue; continue;
if( pad_net_code > net_code ) if( pad_net_code > net_code )
break; break;
(*pt_pad)->m_physical_connexion = 0; (*pt_pad)->m_physical_connexion = 0;
} }
...@@ -396,33 +361,32 @@ void WinEDA_BasePcbFrame::test_1_net_connexion( wxDC* DC, int net_code ) ...@@ -396,33 +361,32 @@ 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 ) 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. /** Used after a track change (delete a track ou add a track)
* Entree: * Compute connections (initialize the .start and .end members) for a single net.
* pt_start_conn = adresse du 1er segment ( debut du net ) * tracks must be sorted by net, as usual
* pt_end_conn = adr de fin (dernier segment) * @param pt_start_conn = first segment of the net
* Les connexions relatives aux pads doivent etre deja calculees, car elles * @param pt_end_conn = last segment of the net
* ne sont pas ici recalculees ( pour des raisons de temps de calcul, et * Connections to pads are assumed to be already initialized.
* du fait que lors des modif de pistes, les pads ne sont pas touches * 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; TRACK* Track;
/* Les pointeurs .start et .end sont mis a jour, si la /* Reset the old connections type track to track */
* connexion est du type segment a segment.
* la connexion sur pads est supposee etre deja calculee */
/* Raz des pointeurs sur pistes */
for( Track = pt_start_conn; Track != NULL; Track = (TRACK*) Track->Pnext ) for( Track = pt_start_conn; Track != NULL; Track = (TRACK*) Track->Pnext )
{ {
Track->SetSubNet( 0 ); Track->SetSubNet( 0 );
if( Track->GetState( BEGIN_ONPAD ) == 0 ) if( Track->GetState( BEGIN_ONPAD ) == 0 )
Track->start = NULL; Track->start = NULL;
if( Track->GetState( END_ONPAD ) == 0 ) if( Track->GetState( END_ONPAD ) == 0 )
Track->end = NULL; Track->end = NULL;
...@@ -430,23 +394,23 @@ static void calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn ) ...@@ -430,23 +394,23 @@ static void calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn )
break; break;
} }
/* calcul des connexions */ /* Update connections type track to track */
for( Track = pt_start_conn; Track != NULL; Track = (TRACK*) Track->Pnext ) 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; TRACK* pt_segm;
int layermask = Track->ReturnMaskLayer(); int layermask = Track->ReturnMaskLayer();
for( pt_segm = pt_start_conn; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext ) for( pt_segm = pt_start_conn; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext )
{ {
int curlayermask = pt_segm->ReturnMaskLayer(); int curlayermask = pt_segm->ReturnMaskLayer();
if( !pt_segm->start && (pt_segm->m_Start == Track->m_Start) if( !pt_segm->start && (pt_segm->m_Start == Track->m_Start)
&& ( layermask & curlayermask ) ) && ( layermask & curlayermask ) )
{ {
pt_segm->start = Track; pt_segm->start = Track;
} }
if( !pt_segm->end && (pt_segm->m_End == Track->m_Start) if( !pt_segm->end && (pt_segm->m_End == Track->m_Start)
&& (layermask & curlayermask) ) && (layermask & curlayermask) )
{ {
...@@ -457,42 +421,33 @@ static void calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn ) ...@@ -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 ) if( Track == pt_end_conn )
break; break;
} }
zflg = false;
/* Generation des sous equipots du net */ /* Generation des sous equipots du net */
propage_equipot( pt_start_conn, pt_end_conn ); 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 #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 /* recherche le pad connecte a l'extremite de la piste de coord px, py
* parametres d'appel: * parametres d'appel:
* px, py = coord du point tst * px, py = coord du point tst
...@@ -504,12 +459,9 @@ static void calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn ) ...@@ -504,12 +459,9 @@ static void calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn )
* la routine travaille par dichotomie sur la liste des pads tries par pos X * la routine travaille par dichotomie sur la liste des pads tries par pos X
* croissante, elle est donc beaucoup plus rapide que Fast_Locate_Pad_connecte, * croissante, elle est donc beaucoup plus rapide que Fast_Locate_Pad_connecte,
* mais implique le calcul de cette liste. * mais implique le calcul de cette liste.
* *
* (la liste placee en m_Pcb->m_Pads et elle triee par netcodes croissants) * (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; D_PAD* pad;
LISTE_PAD* ptr_pad, * lim; LISTE_PAD* ptr_pad, * lim;
...@@ -523,13 +475,13 @@ static D_PAD* SuperFast_Locate_Pad_Connecte( BOARD* pcb, LISTE_PAD* pt_liste, ...@@ -523,13 +475,13 @@ static D_PAD* SuperFast_Locate_Pad_Connecte( BOARD* pcb, LISTE_PAD* pt_liste,
pad = *ptr_pad; pad = *ptr_pad;
ii = nb_pad; ii = nb_pad;
nb_pad >>= 1; nb_pad >>= 1;
if( (ii & 1) && ( ii > 1 ) ) if( (ii & 1) && ( ii > 1 ) )
nb_pad++; nb_pad++;
if( pad->m_Pos.x < px ) /* on doit chercher plus loin */ if( pad->m_Pos.x < px ) /* on doit chercher plus loin */
{ {
ptr_pad += nb_pad; ptr_pad += nb_pad;
if( ptr_pad > lim ) if( ptr_pad > lim )
ptr_pad = lim; ptr_pad = lim;
continue; continue;
...@@ -559,15 +511,15 @@ static D_PAD* SuperFast_Locate_Pad_Connecte( BOARD* pcb, LISTE_PAD* pt_liste, ...@@ -559,15 +511,15 @@ static D_PAD* SuperFast_Locate_Pad_Connecte( BOARD* pcb, LISTE_PAD* pt_liste,
for( ; ; ptr_pad++ ) for( ; ; ptr_pad++ )
{ {
if( ptr_pad > lim ) if( ptr_pad > lim )
return NULL; /* hors zone */ return NULL; /* hors zone */
pad = *ptr_pad; pad = *ptr_pad;
if( pad->m_Pos.x != px ) if( pad->m_Pos.x != px )
return NULL; /* hors zone */ return NULL; /* hors zone */
if( pad->m_Pos.y != py ) if( pad->m_Pos.y != py )
continue; continue;
/* Pad peut-etre trouve ici: il doit etre sur la bonne couche */ /* Pad peut-etre trouve ici: il doit etre sur la bonne couche */
if( pad->m_Masque_Layer & masque_layer ) if( pad->m_Masque_Layer & masque_layer )
return pad; return pad;
...@@ -600,32 +552,39 @@ LISTE_PAD* CreateSortedPadListByXCoord( BOARD* pcb ) ...@@ -600,32 +552,39 @@ LISTE_PAD* CreateSortedPadListByXCoord( BOARD* pcb )
* The list must be freed by user * The list must be freed by user
*/ */
{ {
LISTE_PAD* pad_list = (LISTE_PAD*) MyMalloc( pcb->m_NbPads * sizeof(D_PAD *) ); LISTE_PAD* pad_list = (LISTE_PAD*) MyMalloc( pcb->m_NbPads * sizeof(D_PAD*) );
memcpy( pad_list, pcb->m_Pads, pcb->m_NbPads * sizeof( D_PAD *) ); memcpy( pad_list, pcb->m_Pads, pcb->m_NbPads * sizeof( D_PAD*) );
qsort( pad_list, pcb->m_NbPads, sizeof( D_PAD *), SortPadsByXCoord ); qsort( pad_list, pcb->m_NbPads, sizeof( D_PAD*), SortPadsByXCoord );
return pad_list; return pad_list;
} }
/******************************************************************/ /********************************************************************/
void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) 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, TRACK* pt_piste,
* pt_next; * pt_next;
int a_color; int a_color;
char new_passe_request = 1, flag; char new_passe_request = 1, flag;
LISTE_PAD* pt_mem; LISTE_PAD* pt_mem;
BOARD_ITEM* PtStruct; BOARD_ITEM* PtStruct;
int masque_layer; int masque_layer;
wxString msg; wxString msg;
if( m_Pcb->m_NbPads == 0 ) if( m_Pcb->m_NbPads == 0 )
return; return;
a_color = CYAN; a_color = CYAN;
if( affiche ) if( affiche )
Affiche_1_Parametre( this, POS_AFF_CHREF, wxT( "DataBase" ), wxT( "Netcodes" ), a_color ); Affiche_1_Parametre( this, POS_AFF_CHREF, wxT( "DataBase" ), wxT( "Netcodes" ), a_color );
...@@ -634,29 +593,32 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) ...@@ -634,29 +593,32 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche )
if( affiche ) if( affiche )
Affiche_1_Parametre( this, -1, wxEmptyString, wxT( "Gen Pads " ), a_color ); 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 ); pt_mem = CreateSortedPadListByXCoord( m_Pcb );
if( affiche ) if( affiche )
Affiche_1_Parametre( this, -1, wxEmptyString, wxT( "Conn Pads" ), a_color ); 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; pt_piste = m_Pcb->m_Track;
for( ; pt_piste != NULL; pt_piste = (TRACK*) pt_piste->Pnext ) for( ; pt_piste != NULL; pt_piste = (TRACK*) pt_piste->Pnext )
{ {
pt_piste->SetState( BUSY | EDIT | BEGIN_ONPAD | END_ONPAD, OFF ); 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; pt_piste = m_Pcb->m_Track;
for( ; pt_piste != NULL; pt_piste = (TRACK*) pt_piste->Pnext ) for( ; pt_piste != NULL; pt_piste = (TRACK*) pt_piste->Pnext )
{ {
flag = 0; flag = 0;
masque_layer = g_TabOneLayerMask[pt_piste->GetLayer()]; 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_piste->start = SuperFast_Locate_Pad_Connecte( m_Pcb,
pt_mem, pt_mem,
pt_piste->m_Start.x, pt_piste->m_Start.x,
...@@ -668,6 +630,7 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) ...@@ -668,6 +630,7 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche )
pt_piste->SetNet( ( (D_PAD*) (pt_piste->start) )->GetNet() ); 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_piste->end = SuperFast_Locate_Pad_Connecte( m_Pcb,
pt_mem, pt_mem,
pt_piste->m_End.x, pt_piste->m_End.x,
...@@ -683,12 +646,14 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) ...@@ -683,12 +646,14 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche )
MyFree( pt_mem ); 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. /* the .start et .end member pointers are updated, only if NULLs
* La connexion est alors du type segment a segment * (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 ) if( affiche )
Affiche_1_Parametre( this, POS_AFF_CHREF, wxEmptyString, wxT( "Conn Segm" ), a_color ); Affiche_1_Parametre( this, POS_AFF_CHREF, wxEmptyString, wxT( "Conn Segm" ), a_color );
...@@ -706,9 +671,9 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) ...@@ -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; a_color = YELLOW;
...@@ -727,10 +692,10 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) ...@@ -727,10 +692,10 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche )
{ {
if( via->Type() != TYPEVIA ) if( via->Type() != TYPEVIA )
continue; continue;
if( via->GetNet() > 0 ) if( via->GetNet() > 0 )
continue; // Netcode already known continue; // Netcode already known
// Lock for a connection to a track with a known netcode // Lock for a connection to a track with a known netcode
pt_next = m_Pcb->m_Track; pt_next = m_Pcb->m_Track;
while( ( pt_next = Locate_Piste_Connectee( via, pt_next, NULL, START ) ) != NULL ) while( ( pt_next = Locate_Piste_Connectee( via, pt_next, NULL, START ) ) != NULL )
...@@ -751,43 +716,51 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) ...@@ -751,43 +716,51 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche )
pt_piste->SetState( BUSY, OFF ); 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() ) 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; PtStruct = (BOARD_ITEM*) pt_piste->start;
if( PtStruct && (PtStruct->Type() != TYPEPAD) ) if( PtStruct && (PtStruct->Type() != TYPEPAD) )
{ {
// Begin on an other track segment // Begin on an other track segment
pt_next = (TRACK*) PtStruct; pt_next = (TRACK*) PtStruct;
if( pt_piste->GetNet() ) 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() ); pt_next->SetNet( pt_piste->GetNet() );
} }
} }
else 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() ); pt_piste->SetNet( pt_next->GetNet() );
new_passe_request = 1; new_passe_request = 1;
} }
} }
} }
/* Localisation du point de fin */ /* look for the connection to the current segment ending point */
PtStruct = pt_piste->end; PtStruct = pt_piste->end;
if( PtStruct &&(PtStruct->Type() != TYPEPAD) ) if( PtStruct &&(PtStruct->Type() != TYPEPAD) )
{ {
// End sur piste
pt_next = (TRACK*) PtStruct; pt_next = (TRACK*) PtStruct;
// End on an other track: propagate netcode if possible
if( pt_piste->GetNet() ) if( pt_piste->GetNet() )
{ {
if( pt_next->GetNet() == 0 ) if( pt_next->GetNet() == 0 )
{ {
new_passe_request = 1; new_passe_request = 1;
pt_next->SetNet( pt_piste->GetNet() ); pt_next->SetNet( pt_piste->GetNet() );
} }
} }
...@@ -796,14 +769,14 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) ...@@ -796,14 +769,14 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche )
if( pt_next->GetNet() != 0 ) if( pt_next->GetNet() != 0 )
{ {
pt_piste->SetNet( pt_next->GetNet() ); pt_piste->SetNet( pt_next->GetNet() );
new_passe_request = 1; new_passe_request = 1;
} }
} }
} }
} }
} }
/* Reclassemment des pistes par numero de net: */ /* Sort the track list by net codes: */
if( affiche ) if( affiche )
Affiche_1_Parametre( this, -1, wxEmptyString, wxT( "Reorder " ), a_color ); Affiche_1_Parametre( this, -1, wxEmptyString, wxT( "Reorder " ), a_color );
RebuildTrackChain( m_Pcb ); RebuildTrackChain( m_Pcb );
...@@ -817,7 +790,7 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche ) ...@@ -817,7 +790,7 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche )
* routine de tri de connexion utilisee par la fonction QSORT * routine de tri de connexion utilisee par la fonction QSORT
* le tri est fait par numero de net * 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; int ii;
...@@ -842,7 +815,7 @@ static void RebuildTrackChain( BOARD* pcb ) ...@@ -842,7 +815,7 @@ static void RebuildTrackChain( BOARD* pcb )
if( pcb->m_Track == NULL ) if( pcb->m_Track == NULL )
return; return;
Liste = (TRACK**) MyZMalloc( (nbsegm + 1) * sizeof(TRACK *) ); Liste = (TRACK**) MyZMalloc( (nbsegm + 1) * sizeof(TRACK*) );
ii = 0; Track = pcb->m_Track; ii = 0; Track = pcb->m_Track;
for( ; Track != NULL; ii++, Track = (TRACK*) Track->Pnext ) for( ; Track != NULL; ii++, Track = (TRACK*) Track->Pnext )
...@@ -850,8 +823,8 @@ static void RebuildTrackChain( BOARD* pcb ) ...@@ -850,8 +823,8 @@ static void RebuildTrackChain( BOARD* pcb )
Liste[ii] = Track; Liste[ii] = Track;
} }
qsort( Liste, nbsegm, sizeof(TRACK *), 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 */ /* Update the linked list pointers */
......
...@@ -664,18 +664,27 @@ TEXTE_MODULE* LocateTexteModule( BOARD* Pcb, MODULE** PtModule, int typeloc ) ...@@ -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; int dist;
dist = abs(p1.x - p2.x) + abs (p1.y - p2.y); dist = abs(p1.x - p2.x) + abs (p1.y - p2.y);
dist *= 7; dist *= 7;
dist /= 10; dist /= 10;
return dist; if ( dist < max_dist ) return true;
}
else
if ( p1 == p2 ) return true;
//#endif
return false;
} }
/**************************************************************/ /**************************************************************/
...@@ -683,25 +692,30 @@ TRACK* Locate_Piste_Connectee( TRACK* PtRefSegm, TRACK* pt_base, ...@@ -683,25 +692,30 @@ TRACK* Locate_Piste_Connectee( TRACK* PtRefSegm, TRACK* pt_base,
TRACK* pt_lim, int extr ) TRACK* pt_lim, int extr )
/**************************************************************/ /**************************************************************/
/* recherche le segment connecte au segment pointe par /** Search for the track (or via) segment which is connected to the track segment PtRefSegm
* PtRefSegm: * if extr == START, the starting track segment PtRefSegm is used to locate a connected segment
* si int extr = START, le point de debut du segment est utilise * if extr == END, the ending track segment PtRefSegm is used
* si int extr = END, le point de fin du segment est utilise * The test connection consider only end track segments
* La recherche ne se fait que sur les EXTREMITES des segments
* *
* La recherche se fait de l'adresse : * Search is made from pt_base to pt_lim (in the track linked list)
* pt_base a pt_lim (borne finale comprise) * if pt_lim == NULL, the search is made from pt_base to the end of list
* 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 * In order to have a fast computation time:
* realisee sur un ensemble de +/- 100 points autour du point courant. * a first search is made considering only the +/- 50 next door neightbour of PtRefSegm.
* Si echec: recherche generale * if no track is found : the entire list is tested
*
* @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; TRACK* PtSegmB, * PtSegmN;
int Reflayer; int Reflayer;
wxPoint pos_ref; wxPoint pos_ref;
int ii; int ii;
int min_dist; int max_dist;
if( extr == START ) if( extr == START )
pos_ref = PtRefSegm->m_Start; pos_ref = PtRefSegm->m_Start;
...@@ -713,7 +727,7 @@ TRACK* Locate_Piste_Connectee( TRACK* PtRefSegm, TRACK* pt_base, ...@@ -713,7 +727,7 @@ TRACK* Locate_Piste_Connectee( TRACK* PtRefSegm, TRACK* pt_base,
/* 1ere passe */ /* 1ere passe */
PtSegmB = PtSegmN = PtRefSegm; PtSegmB = PtSegmN = PtRefSegm;
for( ii = 0; ii < 50; ii++ ) for( ii = 0; ii < NEIGHTBOUR_COUNT_MAX; ii++ )
{ {
if( (PtSegmN == NULL) && (PtSegmB == NULL) ) if( (PtSegmN == NULL) && (PtSegmB == NULL) )
break; break;
...@@ -725,15 +739,16 @@ TRACK* Locate_Piste_Connectee( TRACK* PtRefSegm, TRACK* pt_base, ...@@ -725,15 +739,16 @@ TRACK* Locate_Piste_Connectee( TRACK* PtRefSegm, TRACK* pt_base,
if( PtSegmN == PtRefSegm ) if( PtSegmN == PtRefSegm )
goto suite; 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 */ { /* Test des couches */
if( Reflayer & PtSegmN->ReturnMaskLayer() ) if( Reflayer & PtSegmN->ReturnMaskLayer() )
return PtSegmN; return PtSegmN;
} }
if( Dist(pos_ref, PtSegmN->m_End) < min_dist ) if( IsPointsAreNear(pos_ref, PtSegmN->m_End, max_dist) )
{ /* Test des couches */ { /* Test des couches */
if( Reflayer & PtSegmN->ReturnMaskLayer() ) if( Reflayer & PtSegmN->ReturnMaskLayer() )
return PtSegmN; return PtSegmN;
...@@ -752,15 +767,15 @@ suite: ...@@ -752,15 +767,15 @@ suite:
if( PtSegmB == PtRefSegm ) if( PtSegmB == PtRefSegm )
goto suite1; 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 */ { /* Test des couches */
if( Reflayer & PtSegmB->ReturnMaskLayer() ) if( Reflayer & PtSegmB->ReturnMaskLayer() )
return PtSegmB; return PtSegmB;
} }
if( Dist(pos_ref, PtSegmB->m_End) < min_dist ) if( IsPointsAreNear(pos_ref, PtSegmB->m_End, max_dist) )
{ /* Test des couches */ { /* Test des couches */
if( Reflayer & PtSegmB->ReturnMaskLayer() ) if( Reflayer & PtSegmB->ReturnMaskLayer() )
return PtSegmB; return PtSegmB;
...@@ -792,15 +807,15 @@ suite1: ...@@ -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 */ { /* Test des couches */
if( Reflayer & PtSegmN->ReturnMaskLayer() ) if( Reflayer & PtSegmN->ReturnMaskLayer() )
return PtSegmN; return PtSegmN;
} }
if( Dist(pos_ref, PtSegmN->m_End) < min_dist ) if( IsPointsAreNear(pos_ref, PtSegmN->m_End, max_dist) )
{ /* Test des couches */ { /* Test des couches */
if( Reflayer & PtSegmN->ReturnMaskLayer() ) if( Reflayer & PtSegmN->ReturnMaskLayer() )
return PtSegmN; return PtSegmN;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment