diff --git a/3d-viewer/3d_canvas/create_layer_items.cpp b/3d-viewer/3d_canvas/create_layer_items.cpp
index 6ded7deb2e..a9b5fb184e 100644
--- a/3d-viewer/3d_canvas/create_layer_items.cpp
+++ b/3d-viewer/3d_canvas/create_layer_items.cpp
@@ -166,9 +166,9 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
// /////////////////////////////////////////////////////////////////////////
std::vector< const TRACK *> trackList;
trackList.clear();
- trackList.reserve( m_board->m_Track.GetCount() );
+ trackList.reserve( m_board->Tracks().size() );
- for( const TRACK* track = m_board->m_Track; track; track = track->Next() )
+ for( auto track : m_board->Tracks() )
{
if( !Is3DLayerEnabled( track->GetLayer() ) ) // Skip non enabled layers
continue;
diff --git a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_createscene_ogl_legacy.cpp b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_createscene_ogl_legacy.cpp
index a83c9c51d3..9cc512694e 100644
--- a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_createscene_ogl_legacy.cpp
+++ b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_createscene_ogl_legacy.cpp
@@ -745,9 +745,7 @@ void C3D_RENDER_OGL_LEGACY::generate_3D_Vias_and_Pads()
// /////////////////////////////////////////////////////////////////////////
// Insert vias holes (vertical cylinders)
- for( const TRACK* track = m_settings.GetBoard()->m_Track;
- track;
- track = track->Next() )
+ for( auto track : m_settings.GetBoard()->Tracks() )
{
if( track->Type() == PCB_VIA_T )
{
diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp
index f008aedd9b..f031033755 100644
--- a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp
+++ b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp
@@ -1171,9 +1171,7 @@ void C3D_RENDER_RAYTRACING::add_3D_vias_and_pads_to_container()
// /////////////////////////////////////////////////////////////////////////
// Insert vias holes (vertical cylinders)
- for( const TRACK* track = m_settings.GetBoard()->m_Track;
- track;
- track = track->Next() )
+ for( auto track : m_settings.GetBoard()->Tracks() )
{
if( track->Type() == PCB_VIA_T )
{
diff --git a/common/base_struct.cpp b/common/base_struct.cpp
index 988f086f99..f319665c78 100644
--- a/common/base_struct.cpp
+++ b/common/base_struct.cpp
@@ -131,6 +131,7 @@ EDA_ITEM* EDA_ITEM::Clone() const
// see base_struct.h
// many classes inherit this method, be careful:
+//TODO(snh): Fix this to use std::set instead of C-style vector
SEARCH_RESULT EDA_ITEM::Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] )
{
#if 0 && defined(DEBUG)
diff --git a/pcbnew/board_items_to_polygon_shape_transform.cpp b/pcbnew/board_items_to_polygon_shape_transform.cpp
index e07cfec434..2003a9bdbe 100644
--- a/pcbnew/board_items_to_polygon_shape_transform.cpp
+++ b/pcbnew/board_items_to_polygon_shape_transform.cpp
@@ -74,7 +74,7 @@ static void addTextSegmToPoly( int x0, int y0, int xf, int yf, void* aData )
void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer, SHAPE_POLY_SET& aOutlines )
{
// convert tracks and vias:
- for( TRACK* track = m_Track; track != NULL; track = track->Next() )
+ for( auto track : m_tracks )
{
if( !track->IsOnLayer( aLayer ) )
continue;
diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp
index 27ef2d57c0..bd1fe76a73 100644
--- a/pcbnew/class_board.cpp
+++ b/pcbnew/class_board.cpp
@@ -234,327 +234,6 @@ TRACKS BOARD::TracksInNet( int aNetCode )
}
-/**
- * Function removeTrack
- * removes aOneToRemove from aList, which is a non-owning std::vector
- */
-static void removeTrack( TRACKS* aList, TRACK* aOneToRemove )
-{
- aList->erase( std::remove( aList->begin(), aList->end(), aOneToRemove ), aList->end() );
-}
-
-
-static void otherEnd( const TRACK& aTrack, const wxPoint& aNotThisEnd, wxPoint* aOtherEnd )
-{
- if( aTrack.GetStart() == aNotThisEnd )
- {
- *aOtherEnd = aTrack.GetEnd();
- }
- else
- {
- wxASSERT( aTrack.GetEnd() == aNotThisEnd );
- *aOtherEnd = aTrack.GetStart();
- }
-}
-
-
-/**
- * Function find_vias_and_tracks_at
- * collects TRACKs and VIAs at aPos and returns the @a track_count which excludes vias.
- */
-static int find_vias_and_tracks_at( TRACKS& at_next, TRACKS& in_net, LSET& lset, const wxPoint& next )
-{
- // first find all vias (in this net) at 'next' location, and expand LSET with each
- for( TRACKS::iterator it = in_net.begin(); it != in_net.end(); )
- {
- TRACK* t = *it;
-
- if( t->Type() == PCB_VIA_T && (t->GetLayerSet() & lset).any() &&
- ( t->GetStart() == next || t->GetEnd() == next ) )
- {
- lset |= t->GetLayerSet();
- at_next.push_back( t );
- it = in_net.erase( it );
- }
- else
- ++it;
- }
-
- int track_count = 0;
-
- // with expanded lset, find all tracks with an end on any of the layers in lset
- for( TRACKS::iterator it = in_net.begin(); it != in_net.end(); /* iterates in the loop body */ )
- {
- TRACK* t = *it;
-
- if( ( t->GetLayerSet() & lset ).any() && ( t->GetStart() == next || t->GetEnd() == next ) )
- {
- at_next.push_back( t );
- it = in_net.erase( it );
- ++track_count;
- }
- else
- {
- ++it;
- }
- }
-
- return track_count;
-}
-
-
-/**
- * Function checkConnectedTo
- * returns if aTracksInNet contains a copper pathway to aGoal when starting with
- * aFirstTrack. aFirstTrack should have one end situated on aStart, and the
- * traversal testing begins from the other end of aFirstTrack.
- *
- * The function throws an exception instead of returning bool so that detailed
- * information can be provided about a possible failure in the track layout.
- *
- * @throw IO_ERROR - if points are not connected, with text saying why.
- */
-static void checkConnectedTo( BOARD* aBoard, TRACKS* aList, const TRACKS& aTracksInNet,
- const wxPoint& aGoal, const wxPoint& aStart, TRACK* aFirstTrack )
-{
- TRACKS in_net = aTracksInNet; // copy source list so the copy can be modified
- wxPoint next;
-
- otherEnd( *aFirstTrack, aStart, &next );
-
- aList->push_back( aFirstTrack );
- removeTrack( &in_net, aFirstTrack );
-
- LSET lset( aFirstTrack->GetLayer() );
-
- while( in_net.size() )
- {
- if( next == aGoal )
- return; // success
-
- // Want an exact match on the position of next, i.e. pad at next,
- // not a forgiving HitTest() with tolerance type of match, otherwise the overall
- // algorithm will not work. GetPadFast() is an exact match as I write this.
- if( aBoard->GetPadFast( next, lset ) )
- {
- std::string m = StrPrintf(
- "intervening pad at:(xy %s) between start:(xy %s) and goal:(xy %s)",
- FormatInternalUnits( next ).c_str(),
- FormatInternalUnits( aStart ).c_str(),
- FormatInternalUnits( aGoal ).c_str()
- );
- THROW_IO_ERROR( m );
- }
-
- int track_count = find_vias_and_tracks_at( *aList, in_net, lset, next );
-
- if( track_count != 1 )
- {
- std::string m = StrPrintf(
- "found %d tracks intersecting at (xy %s), exactly 2 would be acceptable.",
- track_count + aList->size() == 1 ? 1 : 0,
- FormatInternalUnits( next ).c_str()
- );
- THROW_IO_ERROR( m );
- }
-
- // reduce lset down to the layer that the last track at 'next' is on.
- lset = aList->back()->GetLayerSet();
-
- otherEnd( *aList->back(), next, &next );
- }
-
- std::string m = StrPrintf(
- "not enough tracks connecting start:(xy %s) and goal:(xy %s).",
- FormatInternalUnits( aStart ).c_str(),
- FormatInternalUnits( aGoal ).c_str()
- );
- THROW_IO_ERROR( m );
-}
-
-
-TRACKS BOARD::TracksInNetBetweenPoints( const wxPoint& aStartPos, const wxPoint& aGoalPos, int aNetCode )
-{
- TRACKS in_between_pts;
- TRACKS on_start_point;
- TRACKS in_net = TracksInNet( aNetCode ); // a small subset of TRACKs and VIAs
-
- for( auto t : in_net )
- {
- if( t->Type() == PCB_TRACE_T && ( t->GetStart() == aStartPos || t->GetEnd() == aStartPos ) )
- on_start_point.push_back( t );
- }
-
- wxString per_path_problem_text;
-
- for( auto t : on_start_point ) // explore each trace (path) leaving aStartPos
- {
- // checkConnectedTo() fills in_between_pts on every attempt. For failures
- // this set needs to be cleared.
- in_between_pts.clear();
-
- try
- {
- checkConnectedTo( this, &in_between_pts, in_net, aGoalPos, aStartPos, t );
- }
- catch( const IO_ERROR& ioe ) // means not connected
- {
- per_path_problem_text += "\n\t";
- per_path_problem_text += ioe.Problem();
- continue; // keep trying, there may be other paths leaving from aStartPos
- }
-
- // success, no exception means a valid connection,
- // return this set of TRACKS without throwing.
- return in_between_pts;
- }
-
- wxString m = wxString::Format(
- "no clean path connecting start:(xy %s) with goal:(xy %s)",
- FormatInternalUnits( aStartPos ).c_str(),
- FormatInternalUnits( aGoalPos ).c_str()
- );
-
- THROW_IO_ERROR( m + per_path_problem_text );
-}
-
-
-void BOARD::chainMarkedSegments( TRACK* aTrackList, wxPoint aPosition,
- const LSET& aLayerSet, TRACKS* aList )
-{
- LSET layer_set = aLayerSet;
-
- if( !aTrackList ) // no tracks at all in board
- return;
-
- D_PAD* pad = NULL;
- double distanceToPadCenter = std::numeric_limits::max();
-
- /* Set the BUSY flag of all connected segments, first search starting at
- * aPosition. The search ends when a pad is found (end of a track), a
- * segment end has more than one other segment end connected, or when no
- * connected item found.
- *
- * Vias are a special case because they can connect segments
- * on other layers and they change the layer mask. They can be a track
- * end or not. They will be analyzed later, and vias on terminal points
- * of the track will be considered as part of this track if they do not
- * connect segments on a other track together and will be considered as
- * part of a other track when removing the via, the segments of that other
- * track are disconnected.
- */
- for( ; ; )
- {
- if( !pad )
- pad = GetPad( aPosition, layer_set );
-
- if( pad )
- distanceToPadCenter = GetLineLength( aPosition, pad->GetCenter() );
-
- /* Test for a via: a via changes the layer mask and can connect a lot
- * of segments at location aPosition. When found, the via is just
- * pushed in list. Vias will be examined later, when all connected
- * segment are found and push in list. This is because when a via
- * is found we do not know at this time the number of connected items
- * and we do not know if this via is on the track or finish the track
- */
- TRACK* via = aTrackList->GetVia( NULL, aPosition, layer_set );
-
- if( via )
- {
- layer_set = via->GetLayerSet();
- aList->push_back( via );
- }
-
- int seg_count = 0;
- TRACK* candidate = NULL;
-
- /* Search all segments connected to point aPosition.
- * if only 1 segment at aPosition: then this segment is "candidate"
- * if > 1 segment:
- * then end of "track" (because more than 2 segments are connected at aPosition)
- */
- TRACK* segment = aTrackList;
-
- while( ( segment = ::GetTrack( segment, NULL, aPosition, layer_set ) ) != NULL )
- {
- if( segment->GetState( BUSY ) ) // already found and selected: skip it
- {
- segment = segment->Next();
- continue;
- }
-
- if( segment == via ) // just previously found: skip it
- {
- segment = segment->Next();
- continue;
- }
-
- if( ++seg_count == 1 ) // if first connected item: then segment is candidate
- {
- candidate = segment;
- segment = segment->Next();
- }
- else // More than 1 segment connected -> location is end of track
- {
- return;
- }
- }
-
- if( candidate ) // A candidate is found: flag it and push it in list
- {
- /* Initialize parameters to search items connected to this
- * candidate:
- * we must analyze connections to its other end
- */
- if( aPosition == candidate->GetStart() )
- {
- aPosition = candidate->GetEnd();
- }
- else
- {
- aPosition = candidate->GetStart();
- }
-
- /* If we are in a pad, only candidates approaching the pad center
- * are accepted.
- */
- if( pad )
- {
- if( GetPad( aPosition, layer_set ) != pad )
- return;
-
- if( GetLineLength( aPosition, pad->GetCenter() ) > distanceToPadCenter )
- return;
- }
-
- layer_set = candidate->GetLayerSet();
-
- // flag this item and push it in list of selected items
- aList->push_back( candidate );
- candidate->SetState( BUSY, true );
- }
- else
- {
- return;
- }
- }
-}
-
-
-void BOARD::PushHighLight()
-{
- m_highLightPrevious = m_highLight;
-}
-
-
-void BOARD::PopHighLight()
-{
- m_highLight = m_highLightPrevious;
- m_highLightPrevious.Clear();
-}
-
-
bool BOARD::SetLayerDescr( PCB_LAYER_ID aIndex, const LAYER& aLayer )
{
if( unsigned( aIndex ) < arrayDim( m_Layer ) )
@@ -566,7 +245,6 @@ bool BOARD::SetLayerDescr( PCB_LAYER_ID aIndex, const LAYER& aLayer )
return false;
}
-#include
const PCB_LAYER_ID BOARD::GetLayerID( const wxString& aLayerName ) const
{
@@ -888,15 +566,9 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode )
case PCB_TRACE_T:
case PCB_VIA_T:
if( aMode == ADD_APPEND )
- {
- m_Track.PushBack( (TRACK*) aBoardItem );
- }
+ m_tracks.push_back( static_cast