- Better way to iterate on vias in the track list (GetFirstVia)

- Converted the Next/Prev C casts to static casts and removed the type
  unsafe ones
- Splitted as virtual the VIA::Flip member instead of using RTTI
- Heavily refactored the 'unconnected track' cleanup routine
- Misc constification
This commit is contained in:
Lorenzo Marcantonio 2014-04-30 21:16:22 +02:00
parent 7b843ecac8
commit 7b4b3297db
27 changed files with 217 additions and 310 deletions

View File

@ -274,7 +274,7 @@ void EDA_3D_CANVAS::BuildBoard3DView()
bool hightQualityMode = false;
for( LAYER_NUM layer = FIRST_COPPER_LAYER; layer <= LAST_COPPER_LAYER;
layer++ )
++layer )
{
if( layer != LAST_COPPER_LAYER
&& layer >= g_Parm_3D_Visu.m_CopperLayersCount )
@ -528,21 +528,19 @@ void EDA_3D_CANVAS::BuildTechLayers3DView()
}
int thickness = g_Parm_3D_Visu.GetCopperThicknessBIU();
for( TRACK* track = pcb->m_Track; track != NULL; track = track->Next() )
{
// Add via hole
if( track->Type() == PCB_VIA_T )
{
const VIA *via = static_cast<const VIA*>( track );
VIATYPE_T viatype = via->GetViaType();
int holediameter = via->GetDrillValue();
int hole_outer_radius = (holediameter + thickness) / 2;
if( viatype == VIA_THROUGH )
TransformCircleToPolygon( allLayerHoles,
via->GetStart(), hole_outer_radius,
segcountLowQuality );
}
// Add via holes
for( VIA* via = GetFirstVia( pcb->m_Track ); via != NULL;
via = GetFirstVia( via->Next() ) )
{
VIATYPE_T viatype = via->GetViaType();
int holediameter = via->GetDrillValue();
int hole_outer_radius = (holediameter + thickness) / 2;
if( viatype == VIA_THROUGH )
TransformCircleToPolygon( allLayerHoles,
via->GetStart(), hole_outer_radius,
segcountLowQuality );
}
// draw pads holes
@ -562,7 +560,7 @@ void EDA_3D_CANVAS::BuildTechLayers3DView()
allLayerHoles.ExportTo( brdpolysetHoles );
for( LAYER_NUM layer = FIRST_NON_COPPER_LAYER; layer <= LAST_NON_COPPER_LAYER;
layer++ )
++layer )
{
// Skip user layers, which are not drawn here
if( IsUserLayer( layer) )
@ -713,7 +711,7 @@ void EDA_3D_CANVAS::BuildBoard3DAuxLayers()
bufferPolys.reserve( 5000 ); // Reserve for items not on board
for( LAYER_NUM layer = FIRST_USER_LAYER; layer <= LAST_USER_LAYER;
layer++ )
++layer )
{
if( !Is3DLayerEnabled( layer ) )
continue;

View File

@ -1345,7 +1345,7 @@ SCH_SCREEN* SCH_SCREENS::GetNext()
}
SCH_SCREEN* SCH_SCREENS::GetScreen( unsigned int aIndex )
SCH_SCREEN* SCH_SCREENS::GetScreen( unsigned int aIndex ) const
{
if( aIndex < m_screens.size() )
return m_screens[ aIndex ];

View File

@ -112,7 +112,7 @@ int SCH_SHEET_PATH::Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const
}
SCH_SHEET* SCH_SHEET_PATH::Last()
SCH_SHEET* SCH_SHEET_PATH::Last() const
{
if( m_numSheets )
return m_sheets[m_numSheets - 1];
@ -121,7 +121,7 @@ SCH_SHEET* SCH_SHEET_PATH::Last()
}
SCH_SCREEN* SCH_SHEET_PATH::LastScreen()
SCH_SCREEN* SCH_SHEET_PATH::LastScreen() const
{
SCH_SHEET* lastSheet = Last();
@ -132,7 +132,7 @@ SCH_SCREEN* SCH_SHEET_PATH::LastScreen()
}
SCH_ITEM* SCH_SHEET_PATH::LastDrawList()
SCH_ITEM* SCH_SHEET_PATH::LastDrawList() const
{
SCH_SHEET* lastSheet = Last();
@ -143,7 +143,7 @@ SCH_ITEM* SCH_SHEET_PATH::LastDrawList()
}
SCH_ITEM* SCH_SHEET_PATH::FirstDrawList()
SCH_ITEM* SCH_SHEET_PATH::FirstDrawList() const
{
SCH_ITEM* item = NULL;
@ -316,7 +316,7 @@ void SCH_SHEET_PATH::GetComponents( SCH_REFERENCE_LIST& aReferences, bool aInclu
}
SCH_ITEM* SCH_SHEET_PATH::FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap )
SCH_ITEM* SCH_SHEET_PATH::FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap ) const
{
bool hasWrapped = false;
bool firstItemFound = false;
@ -349,7 +349,7 @@ SCH_ITEM* SCH_SHEET_PATH::FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem, bool
}
SCH_ITEM* SCH_SHEET_PATH::FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap )
SCH_ITEM* SCH_SHEET_PATH::FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap ) const
{
bool hasWrapped = false;
bool firstItemFound = false;

View File

@ -129,20 +129,20 @@ public:
* returns a pointer to the last sheet of the list
* One can see the others sheet as the "path" to reach this last sheet
*/
SCH_SHEET* Last();
SCH_SHEET* Last() const;
/**
* Function LastScreen
* @return the SCH_SCREEN relative to the last sheet in list
*/
SCH_SCREEN* LastScreen();
SCH_SCREEN* LastScreen() const;
/**
* Function LastDrawList
* @return a pointer to the first schematic item handled by the
* SCH_SCREEN relative to the last sheet in list
*/
SCH_ITEM* LastDrawList();
SCH_ITEM* LastDrawList() const;
/**
* Get the last schematic item relative to the first sheet in the list.
@ -150,7 +150,7 @@ public:
* @return Last schematic item relative to the first sheet in the list if list
* is not empty. Otherwise NULL.
*/
SCH_ITEM* FirstDrawList();
SCH_ITEM* FirstDrawList() const;
/**
* Function Push
@ -248,7 +248,7 @@ public:
* is defined.
* @return - The next schematic item if found. Otherwise, NULL is returned.
*/
SCH_ITEM* FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false );
SCH_ITEM* FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ) const;
/**
* Find the previous schematic item in this sheet path object.
@ -260,7 +260,7 @@ public:
* is defined.
* @return - The previous schematic item if found. Otherwise, NULL is returned.
*/
SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false );
SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ) const;
SCH_SHEET_PATH& operator=( const SCH_SHEET_PATH& d1 );
@ -318,7 +318,7 @@ public:
* @return the number of sheets in list:
* usually the number of sheets found in the whole hierarchy
*/
int GetCount() { return m_count; }
int GetCount() const { return m_count; }
/**
* Function GetFirst

View File

@ -26,7 +26,7 @@ public:
~GBR_SCREEN();
GBR_SCREEN* Next() { return (GBR_SCREEN*) Pnext; }
GBR_SCREEN* Next() const { return static_cast<GBR_SCREEN*>( Pnext ); }
// void SetNextZoom();
// void SetPreviousZoom();

View File

@ -116,8 +116,8 @@ public:
*/
GERBER_DRAW_ITEM* Copy() const;
GERBER_DRAW_ITEM* Next() const { return (GERBER_DRAW_ITEM*) Pnext; }
GERBER_DRAW_ITEM* Back() const { return (GERBER_DRAW_ITEM*) Pback; }
GERBER_DRAW_ITEM* Next() const { return static_cast<GERBER_DRAW_ITEM*>( Pnext ); }
GERBER_DRAW_ITEM* Back() const { return static_cast<GERBER_DRAW_ITEM*>( Pback ); }
/**
* Function GetLayer

View File

@ -375,8 +375,8 @@ public:
void SetTimeStamp( time_t aNewTimeStamp ) { m_TimeStamp = aNewTimeStamp; }
time_t GetTimeStamp() const { return m_TimeStamp; }
EDA_ITEM* Next() const { return (EDA_ITEM*) Pnext; }
EDA_ITEM* Back() const { return (EDA_ITEM*) Pback; }
EDA_ITEM* Next() const { return Pnext; }
EDA_ITEM* Back() const { return Pback; }
EDA_ITEM* GetParent() const { return m_Parent; }
DHEAD* GetList() const { return m_List; }

View File

@ -108,8 +108,8 @@ public:
*/
static wxPoint ZeroOffset;
BOARD_ITEM* Next() const { return (BOARD_ITEM*) Pnext; }
BOARD_ITEM* Back() const { return (BOARD_ITEM*) Pback; }
BOARD_ITEM* Next() const { return static_cast<BOARD_ITEM*>( Pnext ); }
BOARD_ITEM* Back() const { return static_cast<BOARD_ITEM*>( Pback ); }
BOARD_ITEM* GetParent() const { return (BOARD_ITEM*) m_Parent; }
/**

View File

@ -31,7 +31,7 @@ public:
~PCB_SCREEN();
PCB_SCREEN* Next() { return (PCB_SCREEN*) Pnext; }
PCB_SCREEN* Next() const { return static_cast<PCB_SCREEN*>( Pnext ); }
void SetNextZoom();
void SetPreviousZoom();

View File

@ -523,7 +523,7 @@ public:
int GetCount() const { return m_screens.size(); }
SCH_SCREEN* GetFirst();
SCH_SCREEN* GetNext();
SCH_SCREEN* GetScreen( unsigned int aIndex );
SCH_SCREEN* GetScreen( unsigned int aIndex ) const;
/**
* Function ClearAnnotation

View File

@ -136,8 +136,8 @@ public:
*/
virtual void SwapData( SCH_ITEM* aItem );
SCH_ITEM* Next() { return (SCH_ITEM*) Pnext; }
SCH_ITEM* Back() { return (SCH_ITEM*) Pback; }
SCH_ITEM* Next() const { return static_cast<SCH_ITEM*>( Pnext ); }
SCH_ITEM* Back() const { return static_cast<SCH_ITEM*>( Pback ); }
/**
* Function GetLayer

View File

@ -1563,19 +1563,12 @@ int BOARD::SetAreasNetCodesFromNetNames( void )
VIA* BOARD::GetViaByPosition( const wxPoint& aPosition, LAYER_NUM aLayer) const
{
for( TRACK *track = m_Track; track; track = track->Next() )
for( VIA *via = GetFirstVia( m_Track); via; via = GetFirstVia( via->Next() ) )
{
if( track->Type() != PCB_VIA_T )
continue;
if( track->GetStart() != aPosition )
continue;
if( track->GetState( BUSY | IS_DELETED ) )
continue;
if( (aLayer == UNDEFINED_LAYER) || (track->IsOnLayer( aLayer )) )
return static_cast<VIA *>( track );
if( (via->GetStart() == aPosition) &&
(via->GetState( BUSY | IS_DELETED ) == 0) &&
((aLayer == UNDEFINED_LAYER) || (via->IsOnLayer( aLayer ))) )
return via;
}
return NULL;

View File

@ -68,9 +68,6 @@ public:
/// skip the linked list stuff, and parent
const DRAWSEGMENT& operator = ( const DRAWSEGMENT& rhs );
DRAWSEGMENT* Next() const { return (DRAWSEGMENT*) Pnext; }
DRAWSEGMENT* Back() const { return (DRAWSEGMENT*) Pback; }
void SetWidth( int aWidth ) { m_Width = aWidth; }
int GetWidth() const { return m_Width; }

View File

@ -51,9 +51,6 @@ public:
~EDGE_MODULE();
EDGE_MODULE* Next() const { return (EDGE_MODULE*) Pnext; }
EDGE_MODULE* Back() const { return (EDGE_MODULE*) Pback; }
/// skip the linked list stuff, and parent
const EDGE_MODULE& operator = ( const EDGE_MODULE& rhs );

View File

@ -56,9 +56,6 @@ public:
~PCB_TARGET();
PCB_TARGET* Next() const { return (PCB_TARGET*) Pnext; }
PCB_TARGET* Back() const { return (PCB_TARGET*) Pnext; }
void SetPosition( const wxPoint& aPos ) { m_Pos = aPos; } // override
const wxPoint& GetPosition() const { return m_Pos; } // override

View File

@ -422,9 +422,12 @@ EDA_RECT MODULE::GetFootprintRect() const
area.SetEnd( m_Pos );
area.Inflate( Millimeter2iu( 0.25 ) ); // Give a min size to the area
for( EDGE_MODULE* edge = (EDGE_MODULE*) m_Drawings.GetFirst(); edge; edge = edge->Next() )
if( edge->Type() == PCB_MODULE_EDGE_T )
for( const BOARD_ITEM* item = m_Drawings.GetFirst(); item; item = item->Next() )
{
const EDGE_MODULE *edge = dynamic_cast<const EDGE_MODULE*>( item );
if( edge )
area.Merge( edge->GetBoundingBox() );
}
for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
area.Merge( pad->GetBoundingBox() );

View File

@ -77,8 +77,8 @@ public:
~MODULE();
MODULE* Next() const { return (MODULE*) Pnext; }
MODULE* Back() const { return (MODULE*) Pback; }
MODULE* Next() const { return static_cast<MODULE*>( Pnext ); }
MODULE* Back() const { return static_cast<MODULE*>( Pback ); }
void Copy( MODULE* Module ); // Copy structure

View File

@ -106,7 +106,7 @@ public:
void Copy( D_PAD* source );
D_PAD* Next() const { return (D_PAD*) Pnext; }
D_PAD* Next() const { return static_cast<D_PAD*>( Pnext ); }
MODULE* GetParent() const { return (MODULE*) m_Parent; }

View File

@ -98,10 +98,6 @@ public:
void Flip( const wxPoint& aCentre );
TEXTE_MODULE* Next() const { return (TEXTE_MODULE*) Pnext; }
TEXTE_MODULE* Back() const { return (TEXTE_MODULE*) Pback; }
/// @deprecated it seems (but the type is used to 'protect'
//reference and value from deletion, and for identification)
void SetType( TEXT_TYPE aType ) { m_Type = aType; }

View File

@ -88,12 +88,9 @@ inline bool IsNear( const wxPoint& p1, const wxPoint& p2, int max_dist )
}
TRACK* GetTrack( TRACK* aStartTrace, TRACK* aEndTrace,
TRACK* GetTrack( TRACK* aStartTrace, const TRACK* aEndTrace,
const wxPoint& aPosition, LAYER_MSK aLayerMask )
{
if( aStartTrace == NULL )
return NULL;
for( TRACK *PtSegm = aStartTrace; PtSegm != NULL; PtSegm = PtSegm->Next() )
{
if( PtSegm->GetState( IS_DELETED | BUSY ) == 0 )
@ -180,7 +177,6 @@ VIA::VIA( BOARD_ITEM* aParent ) :
{
SetViaType( VIA_THROUGH );
m_BottomLayer = LAYER_N_BACK;
m_Width = Millimeter2iu( 0.5 );
SetDrillDefault();
}
@ -369,9 +365,14 @@ void TRACK::Flip( const wxPoint& aCentre )
{
m_Start.y = aCentre.y - (m_Start.y - aCentre.y);
m_End.y = aCentre.y - (m_End.y - aCentre.y);
SetLayer( FlipLayer( GetLayer() ) );
}
if( Type() != PCB_VIA_T )
SetLayer( FlipLayer( GetLayer() ) );
void VIA::Flip( const wxPoint& aCentre )
{
m_Start.y = aCentre.y - (m_Start.y - aCentre.y);
m_End.y = aCentre.y - (m_End.y - aCentre.y);
}

View File

@ -74,7 +74,7 @@ enum VIATYPE_T
* layer mask.
* @return A TRACK object pointer if found otherwise NULL.
*/
extern TRACK* GetTrack( TRACK* aStartTrace, TRACK* aEndTrace,
extern TRACK* GetTrack( TRACK* aStartTrace, const TRACK* aEndTrace,
const wxPoint& aPosition, LAYER_MSK aLayerMask );
class TRACK : public BOARD_CONNECTED_ITEM
@ -100,8 +100,8 @@ public:
// Do not create a copy constructor. The one generated by the compiler is adequate.
TRACK* Next() const { return (TRACK*) Pnext; }
TRACK* Back() const { return (TRACK*) Pback; }
TRACK* Next() const { return static_cast<TRACK*>( Pnext ); }
TRACK* Back() const { return static_cast<TRACK*>( Pback ); }
virtual void Move( const wxPoint& aMoveVector )
{
@ -350,7 +350,7 @@ public:
}
SEGZONE* Next() const { return (SEGZONE*) Pnext; }
SEGZONE* Next() const { return static_cast<SEGZONE*>( Pnext ); }
wxString GetSelectMenuText() const;
@ -415,6 +415,8 @@ public:
/// @copydoc VIEW_ITEM::ViewGetLayers()
virtual void ViewGetLayers( int aLayers[], int& aCount ) const;
virtual void Flip( const wxPoint& aCentre );
#if defined (DEBUG)
virtual void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
#endif
@ -469,5 +471,13 @@ private:
int m_Drill; // for vias: via drill (- 1 for default value)
};
/// Scan a track list for the first VIA o NULL if not found (or NULL passed)
inline VIA *GetFirstVia( TRACK *aTrk, const TRACK *aStopPoint = NULL )
{
while( aTrk && (aTrk != aStopPoint) && (aTrk->Type() != PCB_VIA_T) )
aTrk = aTrk->Next();
return static_cast<VIA*>( aTrk );
}
#endif /* CLASS_TRACK_H */

View File

@ -87,6 +87,11 @@ private:
*/
TRACK* mergeCollinearSegmentIfPossible( TRACK* aTrackRef,
TRACK* aCandidate, ENDPOINT_T aEndType );
const ZONE_CONTAINER* zoneForTrackEndpoint( const TRACK *aTrack,
ENDPOINT_T aEndPoint );
bool testTrackEndpointDangling( TRACK *aTrack, ENDPOINT_T aEndPoint );
};
/* Install the cleanup dialog frame to know what should be cleaned
@ -101,7 +106,7 @@ void PCB_EDIT_FRAME::Clean_Pcb()
wxBusyCursor( dummy );
TRACKS_CLEANER cleaner( GetBoard() );
cleaner.CleanupBoard( this, dlg.m_cleanVias, dlg.m_mergeSegments,
cleaner.CleanupBoard( this, dlg.m_cleanVias, dlg.m_mergeSegments,
dlg.m_deleteUnconnectedSegm );
m_canvas->Refresh( true );
}
@ -134,8 +139,6 @@ bool TRACKS_CLEANER::CleanupBoard( PCB_EDIT_FRAME *aFrame,
if( modified )
{
// Clear undo and redo lists to avoid inconsistencies between lists
// XXX This is very involved... maybe a member in PCB_EDIT_FRAME
// would be better?
aFrame->GetScreen()->ClearUndoRedoList();
aFrame->SetCurItem( NULL );
aFrame->Compile_Ratsnest( NULL, true );
@ -158,7 +161,7 @@ void TRACKS_CLEANER::buildTrackConnectionInfo()
BuildTracksCandidatesList( m_Brd->m_Track, NULL);
// clear flags and variables used in cleanup
for( TRACK * track = m_Brd->m_Track; track; track = track->Next() )
for( TRACK *track = m_Brd->m_Track; track != NULL; track = track->Next() )
{
track->start = NULL;
track->end = NULL;
@ -168,7 +171,7 @@ void TRACKS_CLEANER::buildTrackConnectionInfo()
// Build connections info tracks to pads
SearchTracksConnectedToPads();
for( TRACK * track = m_Brd->m_Track; track; track = track->Next() )
for( TRACK *track = m_Brd->m_Track; track != NULL; track = track->Next() )
{
// Mark track if connected to pads
for( unsigned jj = 0; jj < track->m_PadsConnected.size(); jj++ )
@ -194,70 +197,50 @@ bool TRACKS_CLEANER::clean_vias()
{
bool modified = false;
for( TRACK* track = m_Brd->m_Track; track; track = track->Next() )
for( VIA* via = GetFirstVia( m_Brd->m_Track ); via != NULL;
via = GetFirstVia( via->Next() ) )
{
// Correct via m_End defects (if any)
if( track->Type() == PCB_VIA_T )
// Correct via m_End defects (if any), should never happen
if( via->GetStart() != via->GetEnd() )
{
if( track->GetStart() != track->GetEnd() )
track->SetEnd( track->GetStart() );
VIA *via = static_cast<VIA*>( track );
/* Important: this cleanup only does thru hole vias, it doesn't
* (yet) handle high density interconnects */
if( via->GetViaType() != VIA_THROUGH )
continue;
wxFAIL_MSG( "Via with mismatching ends" );
via->SetEnd( via->GetStart() );
}
else
continue;
// Search and delete others vias at same location
TRACK* alt_track = track->Next();
TRACK* next_track;
for( ; alt_track != NULL; alt_track = next_track )
/* Important: these cleanups only do thru hole vias, they don't
* (yet) handle high density interconnects */
if( via->GetViaType() != VIA_THROUGH )
{
next_track = alt_track->Next();
VIA *alt_via = dynamic_cast<VIA*>( alt_track );
if( alt_via )
// Search and delete others vias at same location
VIA* next_via;
for( VIA* alt_via = GetFirstVia( via->Next() ); alt_via != NULL;
alt_via = next_via )
{
if( alt_via->GetViaType() != VIA_THROUGH )
continue;
next_via = GetFirstVia( alt_via->Next() );
if( alt_via->GetStart() != track->GetStart() )
continue;
// delete via
alt_track->UnLink();
delete alt_track;
modified = true;
if( (alt_via->GetViaType() == VIA_THROUGH) &&
(alt_via->GetStart() == via->GetStart()) )
{
// delete via
alt_via->DeleteStructure();
modified = true;
}
}
}
}
// Delete Via on pads at same location
TRACK* next_track;
for( TRACK* track = m_Brd->m_Track; track != NULL; track = next_track )
{
next_track = track->Next();
VIA *via = dynamic_cast<VIA*>( track );
if( !via || (via->GetViaType() != VIA_THROUGH ))
continue;
// Examine the list of connected pads:
// if one pad through is found, the via can be removed
for( unsigned ii = 0; ii < track->m_PadsConnected.size(); ii++ )
{
D_PAD * pad = track->m_PadsConnected[ii];
if( (pad->GetLayerMask() & ALL_CU_LAYERS) == ALL_CU_LAYERS )
/* To delete through Via on THT pads at same location
* Examine the list of connected pads:
* if one through pad is found, the via can be removed */
for( unsigned ii = 0; ii < via->m_PadsConnected.size(); ++ii )
{
// redundant: via delete it
track->UnLink();
delete track;
modified = true;
break;
const D_PAD *pad = via->m_PadsConnected[ii];
if( (pad->GetLayerMask() & ALL_CU_LAYERS) == ALL_CU_LAYERS )
{
// redundant: delete the via
via->DeleteStructure();
modified = true;
break;
}
}
}
}
@ -265,6 +248,64 @@ bool TRACKS_CLEANER::clean_vias()
return modified;
}
/// Utility for checking if a track/via ends on a zone
const ZONE_CONTAINER* TRACKS_CLEANER::zoneForTrackEndpoint( const TRACK *aTrack,
ENDPOINT_T aEndPoint )
{
// Vias are special cased, since they get a layer range, not a single one
LAYER_NUM top_layer, bottom_layer;
const VIA *via = dynamic_cast<const VIA*>( aTrack );
if( via )
via->LayerPair( &top_layer, &bottom_layer );
else
{
top_layer = aTrack->GetLayer();
bottom_layer = top_layer;
}
return m_Brd->HitTestForAnyFilledArea( aTrack->GetEndPoint( aEndPoint ),
top_layer, bottom_layer, aTrack->GetNetCode() );
}
/** Utility: does the endpoint unconnected processed for one endpoint of one track
* Returns true if the track must be deleted, false if not necessarily */
bool TRACKS_CLEANER::testTrackEndpointDangling( TRACK *aTrack, ENDPOINT_T aEndPoint )
{
bool flag_erase = false;
TRACK* other = aTrack->GetTrack( m_Brd->m_Track, NULL, aEndPoint );
if( (other == NULL) &&
(zoneForTrackEndpoint( aTrack, aEndPoint ) == NULL) )
flag_erase = true; // Start endpoint is neither on pad, zone or other track
else // segment, via or zone connected to this end
{
// Fill connectivity informations
if( aEndPoint == ENDPOINT_START )
aTrack->start = other;
else
aTrack->end = other;
/* If a via is connected to this end, test if this via has a second item connected.
* If not, remove the current segment (the via would then become
* unconnected and remove on the following pass) */
VIA* via = dynamic_cast<VIA*>( other );
if( via )
{
// search for another segment following the via
aTrack->SetState( BUSY, true );
other = via->GetTrack( m_Brd->m_Track, NULL, aEndPoint );
// There is a via on the start but it goes nowhere
if( (other == NULL) &&
(zoneForTrackEndpoint( via, aEndPoint ) == NULL) )
flag_erase = true;
aTrack->SetState( BUSY, false );
}
}
return flag_erase;
}
/*
* Delete dangling tracks
@ -277,161 +318,44 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks()
return false;
bool modified = false;
bool item_erased = true;
while( item_erased ) // Iterate when at least one track is deleted
bool item_erased;
do // Iterate when at least one track is deleted
{
item_erased = false;
TRACK* next_track;
for( TRACK * track = m_Brd->m_Track; track ; track = next_track )
for( TRACK *track = m_Brd->m_Track; track != NULL; track = next_track )
{
next_track = track->Next();
int flag_erase = 0; //Not connected indicator
int type_end = 0;
bool flag_erase = false; // Start without a good reason to erase it
if( track->GetState( START_ON_PAD ) )
type_end |= START_ON_PAD;
/* if a track endpoint is not connected to a pad, test if
* the endpoint is connected to another track or to a zone.
* For via test, an enhancement could be to test if
* connected to 2 items on different layers. Currently
* a via must be connected to 2 items, that can be on the
* same layer */
if( track->GetState( END_ON_PAD ) )
type_end |= END_ON_PAD;
// Check if there is nothing attached on the start
if( !(track->GetState( START_ON_PAD )) )
flag_erase |= testTrackEndpointDangling( track, ENDPOINT_START );
// if the track start point is not connected to a pad,
// test if this track start point is connected to another track
// For via test, an enhancement could be to test if connected
// to 2 items on different layers.
// Currently a via must be connected to 2 items, that can be on the same layer
LAYER_NUM top_layer, bottom_layer;
ZONE_CONTAINER* zone;
if( (type_end & START_ON_PAD ) == 0 )
{
TRACK* other = track->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_START );
if( other == NULL ) // Test a connection to zones
{
if( track->Type() != PCB_VIA_T )
{
zone = m_Brd->HitTestForAnyFilledArea( track->GetStart(),
track->GetLayer(),
track->GetLayer(),
track->GetNetCode() );
}
else
{
((VIA*)track)->LayerPair( &top_layer, &bottom_layer );
zone = m_Brd->HitTestForAnyFilledArea( track->GetStart(),
top_layer, bottom_layer,
track->GetNetCode() );
}
}
if( (other == NULL) && (zone == NULL) )
{
flag_erase |= 1;
}
else // segment, via or zone connected to this end
{
track->start = other;
// If a via is connected to this end,
// test if this via has a second item connected.
// If no, remove it with the current segment
if( other && other->Type() == PCB_VIA_T )
{
// search for another segment following the via
track->SetState( BUSY, true );
VIA* via = (VIA*) other;
other = via->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_START );
if( other == NULL )
{
via->LayerPair( &top_layer, &bottom_layer );
zone = m_Brd->HitTestForAnyFilledArea( via->GetStart(),
bottom_layer,
top_layer,
via->GetNetCode() );
}
if( (other == NULL) && (zone == NULL) )
flag_erase |= 2;
track->SetState( BUSY, false );
}
}
}
// if track end point is not connected to a pad,
// test if this track end point is connected to an other track
if( (type_end & END_ON_PAD ) == 0 )
{
TRACK* other = track->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_END );
if( other == NULL ) // Test a connection to zones
{
if( track->Type() != PCB_VIA_T )
{
zone = m_Brd->HitTestForAnyFilledArea( track->GetEnd(),
track->GetLayer(),
track->GetLayer(),
track->GetNetCode() );
}
else
{
((VIA*)track)->LayerPair( &top_layer, &bottom_layer );
zone = m_Brd->HitTestForAnyFilledArea( track->GetEnd(),
top_layer, bottom_layer,
track->GetNetCode() );
}
}
if ( (other == NULL) && (zone == NULL) )
{
flag_erase |= 0x10;
}
else // segment, via or zone connected to this end
{
track->end = other;
// If a via is connected to this end, test if this via has a second item connected
// if no, remove it with the current segment
if( other && other->Type() == PCB_VIA_T )
{
// search for another segment following the via
track->SetState( BUSY, true );
VIA* via = (VIA*) other;
other = via->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_END );
if( other == NULL )
{
via->LayerPair( &top_layer, &bottom_layer );
zone = m_Brd->HitTestForAnyFilledArea( via->GetEnd(),
bottom_layer, top_layer,
via->GetNetCode() );
}
if( (other == NULL) && (zone == NULL) )
flag_erase |= 0x20;
track->SetState( BUSY, false );
}
}
}
// Check if there is nothing attached on the end
if( !(track->GetState( END_ON_PAD )) )
flag_erase |= testTrackEndpointDangling( track, ENDPOINT_END );
if( flag_erase )
{
// remove segment from board
track->DeleteStructure();
// iterate, because a track connected to the deleted track
// is now perhaps now not connected and should be deleted
/* keep iterating, because a track connected to the deleted track
* now perhaps is not connected and should be deleted */
item_erased = true;
modified = true;
}
}
}
} while( item_erased );
return modified;
}

View File

@ -169,12 +169,11 @@ void FOOTPRINT_EDIT_FRAME::Edit_Edge_Width( EDGE_MODULE* aEdge )
{
aEdge = (EDGE_MODULE*) (BOARD_ITEM*) module->GraphicalItems();
for( ; aEdge != NULL; aEdge = aEdge->Next() )
for( BOARD_ITEM *item = module->GraphicalItems(); item; item = item->Next() )
{
if( aEdge->Type() != PCB_MODULE_EDGE_T )
continue;
aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth );
aEdge = dynamic_cast<EDGE_MODULE*>( item );
if( aEdge )
aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth );
}
}
else
@ -216,14 +215,12 @@ void FOOTPRINT_EDIT_FRAME::Edit_Edge_Layer( EDGE_MODULE* aEdge )
if( aEdge == NULL )
{
aEdge = (EDGE_MODULE*) (BOARD_ITEM*) module->GraphicalItems();
for( ; aEdge != NULL; aEdge = aEdge->Next() )
for( BOARD_ITEM *item = module->GraphicalItems() ; item != NULL;
item = item->Next() )
{
if( aEdge->Type() != PCB_MODULE_EDGE_T )
continue;
aEdge = dynamic_cast<EDGE_MODULE*>( item );
if( aEdge->GetLayer() != new_layer )
if( aEdge && (aEdge->GetLayer() != new_layer) )
{
if( ! modified ) // save only once
SaveCopyInUndoList( module, UR_MODEDIT );

View File

@ -62,9 +62,9 @@ static void Abort_Create_Track( EDA_DRAW_PANEL* Panel, wxDC* DC )
{
PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Panel->GetParent();
BOARD* pcb = frame->GetBoard();
TRACK* track = (TRACK*) frame->GetCurItem();
TRACK* track = dynamic_cast<TRACK*>( frame->GetCurItem() );
if( track && ( track->Type()==PCB_VIA_T || track->Type()==PCB_TRACE_T ) )
if( track )
{
// Erase the current drawing
ShowNewTrackWhenMovingCursor( Panel, DC, wxDefaultPosition, false );

View File

@ -271,12 +271,10 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb )
}
// The same for vias
for( TRACK* track = aPcb->m_Track; track != NULL; track = track->Next() )
for( VIA* via = GetFirstVia( aPcb->m_Track ); via != NULL;
via = GetFirstVia( via->Next() ) )
{
if( track->Type() == PCB_VIA_T )
{
vias.push_back( static_cast<VIA*>(track) );
}
vias.push_back( via );
}
qsort( &vias[0], vias.size(), sizeof(VIA*), ViaSort );

View File

@ -453,12 +453,9 @@ void EXCELLON_WRITER::BuildHolesList( int aFirstLayer,
// build hole list for vias
if( ! aGenerateNPTH_list ) // vias are always plated !
{
for( TRACK* track = m_pcb->m_Track; track; track = track->Next() )
for( VIA* via = GetFirstVia( m_pcb->m_Track ); via;
via = GetFirstVia( via->Next() ) )
{
if( track->Type() != PCB_VIA_T )
continue;
const VIA* via = (const VIA*) track;
hole_value = via->GetDrillValue();
if( hole_value == 0 )

View File

@ -148,10 +148,11 @@ bool BRDITEMS_PLOTTER::PlotAllTextsModule( MODULE* aModule )
PlotTextModule( &aModule->Value(), GetValueColor() );
}
for( textModule = (TEXTE_MODULE*) aModule->GraphicalItems().GetFirst();
textModule != NULL; textModule = textModule->Next() )
for( BOARD_ITEM *item = aModule->GraphicalItems().GetFirst();
item != NULL; item = item->Next() )
{
if( textModule->Type() != PCB_MODULE_TEXT_T )
textModule = dynamic_cast<TEXTE_MODULE*>( item );
if( !textModule )
continue;
if( !GetPlotOtherText() )
@ -350,13 +351,11 @@ void BRDITEMS_PLOTTER::Plot_Edges_Modules()
{
for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
{
for( EDGE_MODULE* edge = (EDGE_MODULE*) module->GraphicalItems().GetFirst();
edge; edge = edge->Next() )
for( BOARD_ITEM* item = module->GraphicalItems().GetFirst(); item; item = item->Next() )
{
if( edge->Type() != PCB_MODULE_EDGE_T )
continue;
EDGE_MODULE *edge = dynamic_cast<EDGE_MODULE*>( item );
if( ( GetLayerMask( edge->GetLayer() ) & m_layerMask ) == 0 )
if( !edge || (( GetLayerMask( edge->GetLayer() ) & m_layerMask ) == 0) )
continue;
Plot_1_EdgeModule( edge );