track & via recovery stuff

This commit is contained in:
dickelbeck 2007-10-19 23:02:11 +00:00
parent ce91e15b6d
commit 3d82623c26
7 changed files with 130 additions and 49 deletions

View File

@ -4,6 +4,19 @@ 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-19 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+ pcbnew
* "Clean tracks" changed to "Track operations".
* Housekeeping on clean.cpp completed.
Added static void ConnectDanglingEndToVia( BOARD* pcb ) in clean.cpp which
extends tracks to via centers. Call it from "extend to pads", works nice.
* Added tooltip text to cleaningoptions_dialog.cpp's m_ConnectToPadsOpt
but don't know if DialogBlocks will parse this backwards.
* Made compilable, somebody broke #define VIA_???? s throughout. Would not compile.
* SEGVIA::SetPos() & GetPos() added.
2007-Oct-17 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr> 2007-Oct-17 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================ ================================================================================
+ pcbnew: + pcbnew:
@ -11,8 +24,6 @@ email address.
rastnest computation does not work (errors) with short track segments rastnest computation does not work (errors) with short track segments
(lenght < width) . This is not a bug, but an algorithm problem, so (lenght < width) . This is not a bug, but an algorithm problem, so
I must work on algos. 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>

View File

@ -244,6 +244,9 @@ public:
void SetLayerPair( int top_layer, int bottom_layer ); void SetLayerPair( int top_layer, int bottom_layer );
void ReturnLayerPair( int* top_layer, int* bottom_layer ) const; void ReturnLayerPair( int* top_layer, int* bottom_layer ) const;
const wxPoint& GetPos() const { return m_Start; }
void SetPos( const wxPoint& aPoint ) { m_Start=aPoint; m_End=aPoint; }
/** /**
* Function GetClass * Function GetClass
* returns the class name. * returns the class name.

View File

@ -40,10 +40,11 @@ static bool s_ConnectToPads = false;
#ifdef CONN2PAD_ENBL #ifdef CONN2PAD_ENBL
static void ConnectDanglingEndToPad( WinEDA_PcbFrame* frame, wxDC* DC ); static void ConnectDanglingEndToPad( WinEDA_PcbFrame* frame, wxDC* DC );
static void ConnectDanglingEndToVia( BOARD* pcb );
static void Gen_Raccord_Track( WinEDA_PcbFrame* frame, wxDC* DC ); static void Gen_Raccord_Track( WinEDA_PcbFrame* frame, wxDC* DC );
#endif #endif
/*****************************************/ /*****************************************/
void WinEDA_PcbFrame::Clean_Pcb( wxDC* DC ) void WinEDA_PcbFrame::Clean_Pcb( wxDC* DC )
/*****************************************/ /*****************************************/
@ -124,9 +125,10 @@ void Clean_Pcb_Items( WinEDA_PcbFrame* frame, wxDC* DC )
/* Raccordement des extremites de piste au centre des pastilles : */ /* Raccordement des extremites de piste au centre des pastilles : */
ConnectDanglingEndToPad( frame, DC ); ConnectDanglingEndToPad( frame, DC );
/* Creation de points de raccordements aux intersections de pistes */ // creation of points of connections at the intersection of tracks
// Gen_Raccord_Track(frame, DC); // Gen_Raccord_Track(frame, DC);
ConnectDanglingEndToVia( frame->m_Pcb );
} }
#endif #endif
@ -173,7 +175,7 @@ static void suppression_piste_non_connectee( WinEDA_PcbFrame* frame, wxDC* DC )
// correct via m_End defects and count number of segments // correct via m_End defects and count number of segments
frame->m_Pcb->m_NbSegmTrack = 0; frame->m_Pcb->m_NbSegmTrack = 0;
ii = 0; ii = 0;
for( segment = frame->m_Pcb->m_Track; segment != NULL; segment = next ) for( segment = frame->m_Pcb->m_Track; segment; segment = next )
{ {
frame->m_Pcb->m_NbSegmTrack++; frame->m_Pcb->m_NbSegmTrack++;
next = segment->Next(); next = segment->Next();
@ -341,7 +343,6 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC )
{ {
TRACK* segment; TRACK* segment;
TRACK* other; TRACK* other;
TRACK* next;
int ii, nbpoints_supprimes = 0; int ii, nbpoints_supprimes = 0;
int flag, no_inc, percent, oldpercent; int flag, no_inc, percent, oldpercent;
wxString msg; wxString msg;
@ -362,10 +363,8 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC )
Affiche_1_Parametre( frame, POS_AFF_VAR, wxT( "NullSeg" ), wxT( "0" ), a_color ); Affiche_1_Parametre( frame, POS_AFF_VAR, wxT( "NullSeg" ), wxT( "0" ), a_color );
segment = frame->m_Pcb->m_Track; for( segment = frame->m_Pcb->m_Track; segment; segment = segment->Next() )
for( segment = frame->m_Pcb->m_Track; segment; segment = next )
{ {
next = (TRACK*) segment->Next();
if( !segment->IsNull() ) if( !segment->IsNull() )
continue; continue;
@ -387,8 +386,7 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC )
percent = 0; percent = 0;
oldpercent = -1; oldpercent = -1;
segment = frame->m_Pcb->m_Track; for( segment = frame->m_Pcb->m_Track, ii = 0; segment; segment = segment->Next(), ii++ )
for( ii = 0; segment; segment = (TRACK*) segment->Next(), ii++ )
{ {
/* affichage activite */ /* affichage activite */
percent = (100 * ii) / frame->m_Pcb->m_NbSegmTrack; percent = (100 * ii) / frame->m_Pcb->m_NbSegmTrack;
@ -407,10 +405,9 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC )
return -1; return -1;
} }
for( other = (TRACK*) segment->Next(); other; other = next ) for( other = segment->Next(); other; other = other->Next() )
{ {
int erase = 0; int erase = 0;
next = (TRACK*) other->Next();
if( segment->Type() != other->Type() ) if( segment->Type() != other->Type() )
continue; continue;
@ -459,13 +456,14 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC )
Affiche_1_Parametre( frame, POS_AFF_VAR, _( "Merge" ), _( "0" ), a_color ); Affiche_1_Parametre( frame, POS_AFF_VAR, _( "Merge" ), _( "0" ), a_color );
ii = 0; ii = 0;
TRACK* next;
for( segment = frame->m_Pcb->m_Track; segment; segment = next ) for( segment = frame->m_Pcb->m_Track; segment; segment = next )
{ {
TRACK* segStart; TRACK* segStart;
TRACK* segEnd; TRACK* segEnd;
TRACK* pt_segm_delete; TRACK* segDelete;
next = (TRACK*) segment->Next(); next = segment->Next();
/* affichage activite */ /* affichage activite */
ii++; ii++;
@ -491,7 +489,7 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC )
flag = no_inc = 0; flag = no_inc = 0;
// search for a possible point that connects on START of segment // search for a possible point that connects on START of segment
for( segStart = (TRACK*) segment->Next(); ; ) for( segStart = segment->Next(); ; )
{ {
segStart = Locate_Piste_Connectee( segment, segStart, segStart = Locate_Piste_Connectee( segment, segStart,
NULL, START ); NULL, START );
@ -521,19 +519,18 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC )
if( flag ) /* debut de segment raccorde a un autre segment */ if( flag ) /* debut de segment raccorde a un autre segment */
{ {
pt_segm_delete = AlignSegment( frame->m_Pcb, segment, segStart, START ); segDelete = AlignSegment( frame->m_Pcb, segment, segStart, START );
if( pt_segm_delete ) if( segDelete )
{ {
nbpoints_supprimes++; no_inc = 1; nbpoints_supprimes++; no_inc = 1;
pt_segm_delete->DeleteStructure(); segDelete->DeleteStructure();
} }
} }
/* Recherche d'un point possible raccorde sur FIN de segment: */ /* Recherche d'un point possible raccorde sur FIN de segment: */
for( segEnd = (TRACK*) segment->Next(); ; ) for( segEnd = segment->Next(); ; )
{ {
segEnd = Locate_Piste_Connectee( segment, segEnd, segEnd = Locate_Piste_Connectee( segment, segEnd, NULL, END );
NULL, END );
if( segEnd ) if( segEnd )
{ {
if( segment->m_Width != segEnd->m_Width ) if( segment->m_Width != segEnd->m_Width )
@ -559,12 +556,12 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC )
if( flag & 2 ) /* FIN de segment raccorde a un autre segment */ if( flag & 2 ) /* FIN de segment raccorde a un autre segment */
{ {
pt_segm_delete = AlignSegment( frame->m_Pcb, segment, segEnd, END ); segDelete = AlignSegment( frame->m_Pcb, segment, segEnd, END );
if( pt_segm_delete ) if( segDelete )
{ {
nbpoints_supprimes++; nbpoints_supprimes++;
no_inc = 1; no_inc = 1;
pt_segm_delete->DeleteStructure(); segDelete->DeleteStructure();
} }
} }
@ -573,7 +570,7 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC )
msg.Printf( wxT( "%d " ), nbpoints_supprimes ); msg.Printf( wxT( "%d " ), nbpoints_supprimes );
Affiche_1_Parametre( frame, POS_AFF_VAR, wxEmptyString, msg, a_color ); Affiche_1_Parametre( frame, POS_AFF_VAR, wxEmptyString, msg, a_color );
next = (TRACK*) segment->Next(); next = segment->Next();
} }
} }
@ -822,7 +819,6 @@ static void Gen_Raccord_Track( WinEDA_PcbFrame* frame, wxDC* DC )
{ {
TRACK* segment; TRACK* segment;
TRACK* other; TRACK* other;
TRACK* next;
int nn = 0; int nn = 0;
int masquelayer; int masquelayer;
int ii, percent, oldpercent; int ii, percent, oldpercent;
@ -835,10 +831,8 @@ static void Gen_Raccord_Track( WinEDA_PcbFrame* frame, wxDC* DC )
frame->DrawPanel->m_AbortRequest = FALSE; frame->DrawPanel->m_AbortRequest = FALSE;
oldpercent = -1; ii = 0; oldpercent = -1; ii = 0;
for( segment = frame->m_Pcb->m_Track; segment; segment = next ) for( segment = frame->m_Pcb->m_Track; segment; segment = segment->Next() )
{ {
next = (TRACK*) segment->Next();
// display activity // display activity
ii++; ii++;
percent = (100 * ii) / frame->m_Pcb->m_NbSegmTrack; percent = (100 * ii) / frame->m_Pcb->m_NbSegmTrack;
@ -860,7 +854,7 @@ static void Gen_Raccord_Track( WinEDA_PcbFrame* frame, wxDC* DC )
masquelayer = segment->ReturnMaskLayer(); masquelayer = segment->ReturnMaskLayer();
// look at the "start" of the "segment" // look at the "start" of the "segment"
for( other = frame->m_Pcb->m_Track; other; other = (TRACK*) other->Next() ) for( other = frame->m_Pcb->m_Track; other; other = other->Next() )
{ {
TRACK* newTrack; TRACK* newTrack;
@ -909,7 +903,7 @@ static void Gen_Raccord_Track( WinEDA_PcbFrame* frame, wxDC* DC )
} }
// look at the "end" of the "segment" // look at the "end" of the "segment"
for( other = frame->m_Pcb->m_Track; other; other = (TRACK*) other->Next() ) for( other = frame->m_Pcb->m_Track; other; other = other->Next() )
{ {
TRACK* newTrack; TRACK* newTrack;
@ -959,6 +953,81 @@ static void Gen_Raccord_Track( WinEDA_PcbFrame* frame, wxDC* DC )
} }
/**
* Function ConnectDanglingEndToPad
* looks for vias which have no netcode and which are in electrical contact
* with a track to the degree that the track's end point falls on the via.
* Note that this is not a rigorous electrical check, but is better than
* testing for the track endpoint equaling the via center. When such a via
* is found, then add a small track to bridge from the overlapping track to
* the via and change the via's netcode so that subsequent continuity checks
* can be done with the faster equality algorithm.
*/
static void ConnectDanglingEndToVia( BOARD* pcb )
{
for( TRACK* track = pcb->m_Track; track; track = track->Next() )
{
SEGVIA* via;
if( track->Type()!=TYPEVIA || (via = (SEGVIA*)track)->GetNet()!=0 )
continue;
for( TRACK* other = pcb->m_Track; other; other = other->Next() )
{
if( other == track )
continue;
if( !via->IsOnLayer( other->GetLayer() ) )
continue;
// if the other track's m_End does not match the via position, and the track's m_Start is
// within the bounds of the via, and the other track has no start
if( other->m_End!=via->GetPos() && via->HitTest( other->m_Start ) && !other->start )
{
TRACK* newTrack = other->Copy();
newTrack->Insert( pcb, other );
newTrack->m_End = via->GetPos();
newTrack->start = other;
newTrack->end = via;
other->start = newTrack;
via->SetNet( other->GetNet() );
if( !via->start )
via->start = other;
if( !via->end )
via->end = other;
}
// if the other track's m_Start does not match the via position, and the track's m_End is
// within the bounds of the via, and the other track has no end
else if( other->m_Start!=via->GetPos() && via->HitTest( other->m_End ) && !other->end )
{
TRACK* newTrack = other->Copy();
newTrack->Insert( pcb, other );
newTrack->m_Start = via->GetPos();
newTrack->start = via;
newTrack->end = other;
other->end = newTrack;
via->SetNet( other->GetNet() );
if( !via->start )
via->start = other;
if( !via->end )
via->end = other;
}
}
}
}
/***************************************************************/ /***************************************************************/
void ConnectDanglingEndToPad( WinEDA_PcbFrame* frame, wxDC* DC ) void ConnectDanglingEndToPad( WinEDA_PcbFrame* frame, wxDC* DC )
/**************************************************************/ /**************************************************************/
@ -971,7 +1040,6 @@ void ConnectDanglingEndToPad( WinEDA_PcbFrame* frame, wxDC* DC )
*/ */
{ {
TRACK* segment; TRACK* segment;
TRACK* next;
int nb_new_piste = 0; int nb_new_piste = 0;
wxString msg; wxString msg;
int percent = 0; int percent = 0;
@ -984,12 +1052,10 @@ void ConnectDanglingEndToPad( WinEDA_PcbFrame* frame, wxDC* DC )
Affiche_1_Parametre( frame, POS_AFF_VAR, _( "Centre" ), _( "0 " ), a_color ); Affiche_1_Parametre( frame, POS_AFF_VAR, _( "Centre" ), _( "0 " ), a_color );
int ii = 0; int ii = 0;
for( segment = frame->m_Pcb->m_Track; segment; segment = next ) for( segment = frame->m_Pcb->m_Track; segment; segment = segment->Next() )
{ {
D_PAD* pad; D_PAD* pad;
next = (TRACK*) segment->Next();
ii++; ii++;
percent = (100 * ii) / frame->m_Pcb->m_NbSegmTrack; percent = (100 * ii) / frame->m_Pcb->m_NbSegmTrack;
if( percent != oldpercent ) if( percent != oldpercent )

View File

@ -160,6 +160,7 @@ void WinEDA_CleaningOptionsFrame::CreateControls()
itemStaticBoxSizer4->Add(m_DeleteunconnectedOpt, 0, wxALIGN_LEFT|wxALL, 5); itemStaticBoxSizer4->Add(m_DeleteunconnectedOpt, 0, wxALIGN_LEFT|wxALL, 5);
m_ConnectToPadsOpt = new wxCheckBox( itemDialog1, ID_CHECKBOX, _("Connect to Pads"), wxDefaultPosition, wxDefaultSize, 0 ); m_ConnectToPadsOpt = new wxCheckBox( itemDialog1, ID_CHECKBOX, _("Connect to Pads"), wxDefaultPosition, wxDefaultSize, 0 );
m_ConnectToPadsOpt->SetToolTip( _("Extend dangling tracks which partially cover a pad or via, all the way to pad or via center") );
m_ConnectToPadsOpt->SetValue(false); m_ConnectToPadsOpt->SetValue(false);
itemStaticBoxSizer4->Add(m_ConnectToPadsOpt, 0, wxALIGN_LEFT|wxALL, 5); itemStaticBoxSizer4->Add(m_ConnectToPadsOpt, 0, wxALIGN_LEFT|wxALL, 5);

View File

@ -262,11 +262,10 @@ D_PAD* Locate_Pad_Connecte( BOARD* Pcb, TRACK* ptr_piste, int extr )
*/ */
{ {
D_PAD* ptr_pad = NULL; D_PAD* ptr_pad = NULL;
int masque_layer;
MODULE* module;
wxPoint ref_pos; wxPoint ref_pos;
masque_layer = g_TabOneLayerMask[ptr_piste->GetLayer()]; int masque_layer = g_TabOneLayerMask[ptr_piste->GetLayer()];
if( extr == START ) if( extr == START )
{ {
ref_pos = ptr_piste->m_Start; ref_pos = ptr_piste->m_Start;
@ -275,8 +274,8 @@ D_PAD* Locate_Pad_Connecte( BOARD* Pcb, TRACK* ptr_piste, int extr )
{ {
ref_pos = ptr_piste->m_End; ref_pos = ptr_piste->m_End;
} }
module = Pcb->m_Modules;
for( ; module != NULL; module = (MODULE*) module->Pnext ) for( MODULE* module = Pcb->m_Modules; module; module = module->Next() )
{ {
ptr_pad = Locate_Pads( module, ref_pos, masque_layer ); ptr_pad = Locate_Pads( module, ref_pos, masque_layer );
if( ptr_pad != NULL ) if( ptr_pad != NULL )
@ -421,13 +420,12 @@ D_PAD* Locate_Any_Pad( BOARD* Pcb, int typeloc, bool OnlyCurrentLayer )
D_PAD* Locate_Any_Pad( BOARD* Pcb, const wxPoint& ref_pos, bool OnlyCurrentLayer ) D_PAD* Locate_Any_Pad( BOARD* Pcb, const wxPoint& ref_pos, bool OnlyCurrentLayer )
{ {
D_PAD* pt_pad;
MODULE* module;
int layer_mask = g_TabOneLayerMask[ ( (PCB_SCREEN*) ActiveScreen )->m_Active_Layer]; int layer_mask = g_TabOneLayerMask[ ( (PCB_SCREEN*) ActiveScreen )->m_Active_Layer];
module = Pcb->m_Modules; for( MODULE* module=Pcb->m_Modules; module; module = module->Next() )
for( ; module != NULL; module = (MODULE*) module->Pnext )
{ {
D_PAD* pt_pad;
/* First: Search a pad on the active layer: */ /* First: Search a pad on the active layer: */
if( ( pt_pad = Locate_Pads( module, ref_pos, layer_mask ) ) != NULL ) if( ( pt_pad = Locate_Pads( module, ref_pos, layer_mask ) ) != NULL )
return pt_pad; return pt_pad;
@ -468,8 +466,7 @@ D_PAD* Locate_Pads( MODULE* module, int masque_layer, int typeloc )
D_PAD* Locate_Pads( MODULE* module, const wxPoint& ref_pos, int masque_layer ) D_PAD* Locate_Pads( MODULE* module, const wxPoint& ref_pos, int masque_layer )
{ {
D_PAD* pt_pad = module->m_Pads; for( D_PAD* pt_pad = module->m_Pads; pt_pad; pt_pad = pt_pad->Next() )
for( ; pt_pad != NULL; pt_pad = (D_PAD*) pt_pad->Pnext )
{ {
/* ... et sur la bonne couche */ /* ... et sur la bonne couche */
if( (pt_pad->m_Masque_Layer & masque_layer) == 0 ) if( (pt_pad->m_Masque_Layer & masque_layer) == 0 )

View File

@ -251,8 +251,8 @@ wxMenuBar * menuBar = GetMenuBar();
item->SetBitmap(tools_xpm); item->SetBitmap(tools_xpm);
miscellaneous_menu->Append(item); miscellaneous_menu->Append(item);
item = new wxMenuItem(miscellaneous_menu, ID_MENU_PCB_CLEAN, _("&Clean tracks"), item = new wxMenuItem(miscellaneous_menu, ID_MENU_PCB_CLEAN, _("&Track operations"),
_("Clean stubs, vias, delete break points")); _("Clean stubs, vias, delete break points, or connect dangling tracks to pads and vias"));
item->SetBitmap(delete_body_xpm); item->SetBitmap(delete_body_xpm);
miscellaneous_menu->Append(item); miscellaneous_menu->Append(item);

View File

@ -72,4 +72,7 @@ others (what are they?):
: :
: :
*** Add tooltip text to cleaningoptions_dialog.cpp throughout for all options.
Might need to do this using DialogBlocks.