mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-14 19:49:36 +00:00
pcbnew: Move tracks to std::deque
This commit is contained in:
parent
d1877d7c1b
commit
888c01d11b
3d-viewer
3d_canvas
3d_rendering
3d_render_ogl_legacy
3d_render_raytracing
common
pcbnew
board_items_to_polygon_shape_transform.cppclass_board.cppclass_board.hclass_track.cppclass_track.h
dialogs
dialog_gendrill.cppdialog_global_deletion.cppdialog_global_edit_tracks_and_vias.cppdialog_pad_properties.cppdialog_swap_layers.cpp
drc.cppdrc.hdrc_clearance_test_functions.cppeagle_plugin.cppexporters
kicad_plugin.cppnetinfo.hnetinfo_item.cppnetinfo_list.cpppcad2kicadpcb_plugin
pcb_draw_panel_gal.cpppcb_edit_frame.hpcb_legacy_draw_utils.cpppcb_parser.cppplot_board_layers.cppplot_brditems_plotter.cppratsnest.cppspecctra_import_export
swig
tools
tracks_cleaner.cpptracks_cleaner.hundo_redo.cppqa/testcases
@ -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;
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
* <p>
|
||||
* 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<double>::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 <stdio.h>
|
||||
|
||||
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<TRACK*>( aBoardItem ) );
|
||||
else
|
||||
{
|
||||
TRACK* insertAid;
|
||||
insertAid = ( (TRACK*) aBoardItem )->GetBestInsertPoint( this );
|
||||
m_Track.Insert( (TRACK*) aBoardItem, insertAid );
|
||||
}
|
||||
m_tracks.push_front( static_cast<TRACK*>( aBoardItem ) );
|
||||
|
||||
break;
|
||||
|
||||
@ -983,7 +655,8 @@ void BOARD::Remove( BOARD_ITEM* aBoardItem )
|
||||
|
||||
case PCB_TRACE_T:
|
||||
case PCB_VIA_T:
|
||||
m_Track.Remove( (TRACK*) aBoardItem );
|
||||
m_tracks.erase( std::remove_if( m_tracks.begin(), m_tracks.end(),
|
||||
[aBoardItem]( BOARD_ITEM* aItem ) { return aItem == aBoardItem; } ) );
|
||||
break;
|
||||
|
||||
case PCB_DIMENSION_T:
|
||||
@ -1070,12 +743,6 @@ BOARD_ITEM* BOARD::GetItem( void* aWeakReference )
|
||||
}
|
||||
|
||||
|
||||
int BOARD::GetNumSegmTrack() const
|
||||
{
|
||||
return m_Track.GetCount();
|
||||
}
|
||||
|
||||
|
||||
unsigned BOARD::GetNodesCount( int aNet )
|
||||
{
|
||||
unsigned retval = 0;
|
||||
@ -1138,7 +805,7 @@ EDA_RECT BOARD::ComputeBoundingBox( bool aBoardEdgesOnly ) const
|
||||
}
|
||||
|
||||
// Check tracks
|
||||
for( TRACK* track = m_Track; track; track = track->Next() )
|
||||
for( auto track : m_tracks )
|
||||
{
|
||||
if( !( track->GetLayerSet() & visible ).any() )
|
||||
continue;
|
||||
@ -1177,7 +844,7 @@ void BOARD::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >&
|
||||
int viasCount = 0;
|
||||
int trackSegmentsCount = 0;
|
||||
|
||||
for( BOARD_ITEM* item = m_Track; item; item = item->Next() )
|
||||
for( auto item : m_tracks )
|
||||
{
|
||||
if( item->Type() == PCB_VIA_T )
|
||||
viasCount++;
|
||||
@ -1331,12 +998,12 @@ SEARCH_RESULT BOARD::Visit( INSPECTOR inspector, void* testData, const KICAD_T s
|
||||
|
||||
#else
|
||||
case PCB_VIA_T:
|
||||
result = IterateForward( m_Track, inspector, testData, p );
|
||||
result = IterateForward<TRACK*>( m_tracks, inspector, testData, p );
|
||||
++p;
|
||||
break;
|
||||
|
||||
case PCB_TRACE_T:
|
||||
result = IterateForward( m_Track, inspector, testData, p );
|
||||
result = IterateForward<TRACK*>( m_tracks, inspector, testData, p );
|
||||
++p;
|
||||
break;
|
||||
#endif
|
||||
@ -1587,20 +1254,6 @@ int BOARD::SetAreasNetCodesFromNetNames()
|
||||
}
|
||||
|
||||
|
||||
VIA* BOARD::GetViaByPosition( const wxPoint& aPosition, PCB_LAYER_ID aLayer) const
|
||||
{
|
||||
for( VIA *via = GetFirstVia( m_Track); via; via = GetFirstVia( via->Next() ) )
|
||||
{
|
||||
if( (via->GetStart() == aPosition) &&
|
||||
(via->GetState( BUSY | IS_DELETED ) == 0) &&
|
||||
((aLayer == UNDEFINED_LAYER) || (via->IsOnLayer( aLayer ))) )
|
||||
return via;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
D_PAD* BOARD::GetPad( const wxPoint& aPosition, LSET aLayerSet )
|
||||
{
|
||||
if( !aLayerSet.any() )
|
||||
@ -1631,23 +1284,6 @@ D_PAD* BOARD::GetPad( TRACK* aTrace, ENDPOINT_T aEndPoint )
|
||||
}
|
||||
|
||||
|
||||
std::list<TRACK*> BOARD::GetTracksByPosition( const wxPoint& aPosition, PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
std::list<TRACK*> tracks;
|
||||
|
||||
for( TRACK* track = GetFirstTrack( m_Track ); track; track = GetFirstTrack( track->Next() ) )
|
||||
{
|
||||
if( ( ( track->GetStart() == aPosition ) || track->GetEnd() == aPosition ) &&
|
||||
( track->GetState( BUSY | IS_DELETED ) == 0 ) &&
|
||||
( ( aLayer == UNDEFINED_LAYER ) || ( track->IsOnLayer( aLayer ) ) ) )
|
||||
|
||||
tracks.push_back( track );
|
||||
}
|
||||
|
||||
return tracks;
|
||||
}
|
||||
|
||||
|
||||
D_PAD* BOARD::GetPadFast( const wxPoint& aPosition, LSET aLayerSet )
|
||||
{
|
||||
for( auto mod : Modules() )
|
||||
@ -1798,340 +1434,44 @@ void BOARD::PadDelete( D_PAD* aPad )
|
||||
}
|
||||
|
||||
|
||||
TRACK* BOARD::GetVisibleTrack( TRACK* aStartingTrace, const wxPoint& aPosition,
|
||||
LSET aLayerSet ) const
|
||||
std::tuple<int, double, double> BOARD::GetTrackLength( const TRACK& aTrack ) const
|
||||
{
|
||||
for( TRACK* track = aStartingTrace; track; track = track->Next() )
|
||||
int count = 0;
|
||||
double length = 0.0;
|
||||
double package_length = 0.0;
|
||||
|
||||
constexpr KICAD_T types[] = { PCB_TRACE_T, PCB_VIA_T, PCB_PAD_T, EOT };
|
||||
auto connectivity = GetBoard()->GetConnectivity();
|
||||
|
||||
for( auto item : connectivity->GetConnectedItems(
|
||||
static_cast<const BOARD_CONNECTED_ITEM*>( &aTrack ), types ) )
|
||||
{
|
||||
PCB_LAYER_ID layer = track->GetLayer();
|
||||
count++;
|
||||
|
||||
if( track->GetState( BUSY | IS_DELETED ) )
|
||||
continue;
|
||||
|
||||
// track's layer is not visible
|
||||
if( m_designSettings.IsLayerVisible( layer ) == false )
|
||||
continue;
|
||||
|
||||
if( track->Type() == PCB_VIA_T ) // VIA encountered.
|
||||
if( auto track = dyn_cast<TRACK*>( item ) )
|
||||
{
|
||||
if( track->HitTest( aPosition ) )
|
||||
return track;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !aLayerSet[layer] )
|
||||
continue; // track's layer is not in aLayerSet
|
||||
bool inPad = false;
|
||||
|
||||
if( track->HitTest( aPosition ) )
|
||||
return track;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
TRACK* BOARD::MarkTrace( TRACK* aTrackList, TRACK* aTrace, int* aCount,
|
||||
double* aTraceLength, double* aPadToDieLength,
|
||||
bool aReorder )
|
||||
{
|
||||
TRACKS trackList;
|
||||
|
||||
if( aCount )
|
||||
*aCount = 0;
|
||||
|
||||
if( aTraceLength )
|
||||
*aTraceLength = 0;
|
||||
|
||||
if( aTrace == NULL )
|
||||
return NULL;
|
||||
|
||||
// Ensure the flag BUSY of all tracks of the board is cleared
|
||||
// because we use it to mark segments of the track
|
||||
for( TRACK* track = aTrackList; track; track = track->Next() )
|
||||
track->SetState( BUSY, false );
|
||||
|
||||
// Set flags of the initial track segment
|
||||
aTrace->SetState( BUSY, true );
|
||||
LSET layer_set = aTrace->GetLayerSet();
|
||||
|
||||
trackList.push_back( aTrace );
|
||||
|
||||
/* Examine the initial track segment : if it is really a segment, this is
|
||||
* easy.
|
||||
* If it is a via, one must search for connected segments.
|
||||
* If <=2, this via connect 2 segments (or is connected to only one
|
||||
* segment) and this via and these 2 segments are a part of a track.
|
||||
* If > 2 only this via is flagged (the track has only this via)
|
||||
*/
|
||||
if( aTrace->Type() == PCB_VIA_T )
|
||||
{
|
||||
TRACK* segm1 = ::GetTrack( aTrackList, NULL, aTrace->GetStart(), layer_set );
|
||||
TRACK* segm2 = NULL;
|
||||
TRACK* segm3 = NULL;
|
||||
|
||||
if( segm1 )
|
||||
{
|
||||
segm2 = ::GetTrack( segm1->Next(), NULL, aTrace->GetStart(), layer_set );
|
||||
}
|
||||
|
||||
if( segm2 )
|
||||
{
|
||||
segm3 = ::GetTrack( segm2->Next(), NULL, aTrace->GetStart(), layer_set );
|
||||
}
|
||||
|
||||
if( segm3 )
|
||||
{
|
||||
// More than 2 segments are connected to this via.
|
||||
// The "track" is only this via.
|
||||
|
||||
if( aCount )
|
||||
*aCount = 1;
|
||||
|
||||
return aTrace;
|
||||
}
|
||||
|
||||
if( segm1 ) // search for other segments connected to the initial segment start point
|
||||
{
|
||||
layer_set = segm1->GetLayerSet();
|
||||
chainMarkedSegments( aTrackList, aTrace->GetStart(), layer_set, &trackList );
|
||||
}
|
||||
|
||||
if( segm2 ) // search for other segments connected to the initial segment end point
|
||||
{
|
||||
layer_set = segm2->GetLayerSet();
|
||||
chainMarkedSegments( aTrackList, aTrace->GetStart(), layer_set, &trackList );
|
||||
}
|
||||
}
|
||||
else // mark the chain using both ends of the initial segment
|
||||
{
|
||||
TRACKS from_start;
|
||||
TRACKS from_end;
|
||||
|
||||
chainMarkedSegments( aTrackList, aTrace->GetStart(), layer_set, &from_start );
|
||||
chainMarkedSegments( aTrackList, aTrace->GetEnd(), layer_set, &from_end );
|
||||
|
||||
// combine into one trackList:
|
||||
trackList.insert( trackList.end(), from_start.begin(), from_start.end() );
|
||||
trackList.insert( trackList.end(), from_end.begin(), from_end.end() );
|
||||
}
|
||||
|
||||
// Now examine selected vias and flag them if they are on the track
|
||||
// If a via is connected to only one or 2 segments, it is flagged (is on the track)
|
||||
// If a via is connected to more than 2 segments, it is a track end, and it
|
||||
// is removed from the list.
|
||||
// Go through the list backwards.
|
||||
for( int i = trackList.size() - 1; i>=0; --i )
|
||||
{
|
||||
::VIA* via = dynamic_cast< ::VIA* >( trackList[i] );
|
||||
|
||||
if( !via )
|
||||
continue;
|
||||
|
||||
if( via == aTrace )
|
||||
continue;
|
||||
|
||||
via->SetState( BUSY, true ); // Try to flag it. the flag will be cleared later if needed
|
||||
|
||||
layer_set = via->GetLayerSet();
|
||||
|
||||
TRACK* track = ::GetTrack( aTrackList, NULL, via->GetStart(), layer_set );
|
||||
|
||||
// GetTrace does not consider tracks flagged BUSY.
|
||||
// So if no connected track found, this via is on the current track
|
||||
// only: keep it
|
||||
if( track == NULL )
|
||||
continue;
|
||||
|
||||
/* If a track is found, this via connects also other segments of
|
||||
* the other track. This case happens when a via ends the selected
|
||||
* track but must we consider this via is on the selected track, or
|
||||
* on a other track.
|
||||
* (this is important when selecting a track for deletion: must this
|
||||
* via be deleted or not?)
|
||||
* We consider this via to be on our track if other segments connected
|
||||
* to this via remain connected when removing this via.
|
||||
* We search for all other segments connected together:
|
||||
* if they are on the same layer, then the via is on the selected track;
|
||||
* if they are on different layers, the via is on a other track.
|
||||
*/
|
||||
LAYER_NUM layer = track->GetLayer();
|
||||
|
||||
while( ( track = ::GetTrack( track->Next(), NULL, via->GetStart(), layer_set ) ) != NULL )
|
||||
{
|
||||
if( layer != track->GetLayer() )
|
||||
for( auto pad_it : connectivity->GetConnectedPads( item ) )
|
||||
{
|
||||
// The via connects segments of a other track: it is removed
|
||||
// from list because it is member of a other track
|
||||
via->SetState( BUSY, false );
|
||||
break;
|
||||
auto pad = static_cast<D_PAD*>( pad_it );
|
||||
|
||||
if( pad->HitTest( track->GetStart(), track->GetWidth() / 2 )
|
||||
&& pad->HitTest( track->GetEnd(), track->GetWidth() / 2 ) )
|
||||
{
|
||||
inPad = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !inPad )
|
||||
length += track->GetLength();
|
||||
}
|
||||
else if( auto pad = dyn_cast<D_PAD*>( item ) )
|
||||
package_length += pad->GetPadToDieLength();
|
||||
}
|
||||
|
||||
/* Rearrange the track list in order to have flagged segments linked
|
||||
* from firstTrack so the NbSegmBusy segments are consecutive segments
|
||||
* in list, the first item in the full track list is firstTrack, and
|
||||
* the NbSegmBusy-1 next items (NbSegmBusy when including firstTrack)
|
||||
* are the flagged segments
|
||||
*/
|
||||
int busy_count = 0;
|
||||
TRACK* firstTrack;
|
||||
|
||||
for( firstTrack = aTrackList; firstTrack; firstTrack = firstTrack->Next() )
|
||||
{
|
||||
// Search for the first flagged BUSY segments
|
||||
if( firstTrack->GetState( BUSY ) )
|
||||
{
|
||||
busy_count = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( firstTrack == NULL )
|
||||
return NULL;
|
||||
|
||||
// First step: calculate the track length and find the pads (when exist)
|
||||
// at each end of the trace.
|
||||
double full_len = 0;
|
||||
double lenPadToDie = 0;
|
||||
// Because we have a track (a set of track segments between 2 nodes),
|
||||
// only 2 pads (maximum) will be taken in account:
|
||||
// that are on each end of the track, if any.
|
||||
// keep trace of them, to know the die length and the track length ibside each pad.
|
||||
D_PAD* s_pad = NULL; // the pad on one end of the trace
|
||||
D_PAD* e_pad = NULL; // the pad on the other end of the trace
|
||||
int dist_fromstart = INT_MAX;
|
||||
int dist_fromend = INT_MAX;
|
||||
|
||||
for( TRACK* track = firstTrack; track; track = track->Next() )
|
||||
{
|
||||
if( !track->GetState( BUSY ) )
|
||||
continue;
|
||||
|
||||
layer_set = track->GetLayerSet();
|
||||
D_PAD * pad_on_start = GetPad( track->GetStart(), layer_set );
|
||||
D_PAD * pad_on_end = GetPad( track->GetEnd(), layer_set );
|
||||
|
||||
// a segment fully inside a pad does not contribute to the track len
|
||||
// (another track end inside this pad will contribute to this lenght)
|
||||
if( pad_on_start && ( pad_on_start == pad_on_end ) )
|
||||
continue;
|
||||
|
||||
full_len += track->GetLength();
|
||||
|
||||
if( pad_on_start == NULL && pad_on_end == NULL )
|
||||
// This most of time the case
|
||||
continue;
|
||||
|
||||
// At this point, we can have one track end on a pad, or the 2 track ends on
|
||||
// 2 different pads.
|
||||
// We don't know what pad (s_pad or e_pad) must be used to store the
|
||||
// start point and the end point of the track, so if a pad is already set,
|
||||
// use the other
|
||||
if( pad_on_start )
|
||||
{
|
||||
SEG segm( track->GetStart(), pad_on_start->GetPosition() );
|
||||
int dist = segm.Length();
|
||||
|
||||
if( s_pad == NULL )
|
||||
{
|
||||
dist_fromstart = dist;
|
||||
s_pad = pad_on_start;
|
||||
}
|
||||
else if( e_pad == NULL )
|
||||
{
|
||||
dist_fromend = dist;
|
||||
e_pad = pad_on_start;
|
||||
}
|
||||
else // Should not occur, at least for basic pads
|
||||
{
|
||||
wxLogWarning( "Unexpected BOARD::MarkTrace: multiple pad_on_start" );
|
||||
}
|
||||
}
|
||||
|
||||
if( pad_on_end )
|
||||
{
|
||||
SEG segm( track->GetEnd(), pad_on_end->GetPosition() );
|
||||
int dist = segm.Length();
|
||||
|
||||
if( s_pad == NULL )
|
||||
{
|
||||
dist_fromstart = dist;
|
||||
s_pad = pad_on_end;
|
||||
}
|
||||
else if( e_pad == NULL )
|
||||
{
|
||||
dist_fromend = dist;
|
||||
e_pad = pad_on_end;
|
||||
}
|
||||
else // Should not occur, at least for basic pads
|
||||
{
|
||||
wxLogWarning( "Unexpected BOARD::MarkTrace: multiple pad_on_end" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( aReorder )
|
||||
{
|
||||
DLIST<TRACK>* list = (DLIST<TRACK>*)firstTrack->GetList();
|
||||
wxASSERT( list );
|
||||
|
||||
/* Rearrange the chain starting at firstTrack
|
||||
* All other BUSY flagged items are moved from their position to the end
|
||||
* of the flagged list
|
||||
*/
|
||||
TRACK* next;
|
||||
|
||||
for( TRACK* track = firstTrack->Next(); track; track = next )
|
||||
{
|
||||
next = track->Next();
|
||||
|
||||
if( track->GetState( BUSY ) ) // move it!
|
||||
{
|
||||
busy_count++;
|
||||
track->UnLink();
|
||||
list->Insert( track, firstTrack->Next() );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( aTraceLength )
|
||||
{
|
||||
busy_count = 0;
|
||||
|
||||
for( TRACK* track = firstTrack; track; track = track->Next() )
|
||||
{
|
||||
if( track->GetState( BUSY ) )
|
||||
{
|
||||
busy_count++;
|
||||
track->SetState( BUSY, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( s_pad )
|
||||
{
|
||||
full_len += dist_fromstart;
|
||||
lenPadToDie += (double) s_pad->GetPadToDieLength();
|
||||
}
|
||||
|
||||
if( e_pad )
|
||||
{
|
||||
full_len += dist_fromend;
|
||||
lenPadToDie += (double) e_pad->GetPadToDieLength();
|
||||
}
|
||||
|
||||
if( aTraceLength )
|
||||
*aTraceLength = full_len;
|
||||
|
||||
if( aPadToDieLength )
|
||||
*aPadToDieLength = lenPadToDie;
|
||||
|
||||
if( aCount )
|
||||
*aCount = busy_count;
|
||||
|
||||
return firstTrack;
|
||||
return std::make_tuple( count, length, package_length );
|
||||
}
|
||||
|
||||
|
||||
@ -2203,104 +1543,6 @@ MODULE* BOARD::GetFootprint( const wxPoint& aPosition, PCB_LAYER_ID aActiveLayer
|
||||
}
|
||||
|
||||
|
||||
BOARD_CONNECTED_ITEM* BOARD::GetLockPoint( const wxPoint& aPosition, LSET aLayerSet )
|
||||
{
|
||||
for( auto module : m_modules )
|
||||
{
|
||||
D_PAD* pad = module->GetPad( aPosition, aLayerSet );
|
||||
|
||||
if( pad )
|
||||
return pad;
|
||||
}
|
||||
|
||||
// No pad has been located so check for a segment of the trace.
|
||||
TRACK* segment = ::GetTrack( m_Track, NULL, aPosition, aLayerSet );
|
||||
|
||||
if( !segment )
|
||||
segment = GetVisibleTrack( m_Track, aPosition, aLayerSet );
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
|
||||
TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS_LIST* aList )
|
||||
{
|
||||
/* creates an intermediate point on aSegment and break it into two segments
|
||||
* at aPosition.
|
||||
* The new segment starts from aPosition and ends at the end point of
|
||||
* aSegment. The original segment now ends at aPosition.
|
||||
*/
|
||||
if( aSegment->GetStart() == aPosition || aSegment->GetEnd() == aPosition )
|
||||
return NULL;
|
||||
|
||||
// A via is a good lock point
|
||||
if( aSegment->Type() == PCB_VIA_T )
|
||||
{
|
||||
aPosition = aSegment->GetStart();
|
||||
return aSegment;
|
||||
}
|
||||
|
||||
// Calculation coordinate of intermediate point relative to the start point of aSegment
|
||||
wxPoint delta = aSegment->GetEnd() - aSegment->GetStart();
|
||||
|
||||
// calculate coordinates of aPosition relative to aSegment->GetStart()
|
||||
wxPoint lockPoint = aPosition - aSegment->GetStart();
|
||||
|
||||
// lockPoint must be on aSegment:
|
||||
// Ensure lockPoint.y/lockPoint.y = delta.y/delta.x
|
||||
if( delta.x == 0 )
|
||||
lockPoint.x = 0; // horizontal segment
|
||||
else
|
||||
lockPoint.y = KiROUND( ( (double)lockPoint.x * delta.y ) / delta.x );
|
||||
|
||||
/* Create the intermediate point (that is to say creation of a new
|
||||
* segment, beginning at the intermediate point.
|
||||
*/
|
||||
lockPoint += aSegment->GetStart();
|
||||
|
||||
TRACK* newTrack = (TRACK*)aSegment->Clone();
|
||||
// The new segment begins at the new point,
|
||||
newTrack->SetStart(lockPoint);
|
||||
newTrack->start = aSegment;
|
||||
newTrack->SetState( BEGIN_ONPAD, false );
|
||||
|
||||
DLIST<TRACK>* list = (DLIST<TRACK>*)aSegment->GetList();
|
||||
wxASSERT( list );
|
||||
list->Insert( newTrack, aSegment->Next() );
|
||||
|
||||
if( aList )
|
||||
{
|
||||
// Prepare the undo command for the now track segment
|
||||
ITEM_PICKER picker( newTrack, UR_NEW );
|
||||
aList->PushItem( picker );
|
||||
// Prepare the undo command for the old track segment
|
||||
// before modifications
|
||||
picker.SetItem( aSegment );
|
||||
picker.SetStatus( UR_CHANGED );
|
||||
picker.SetLink( aSegment->Clone() );
|
||||
aList->PushItem( picker );
|
||||
}
|
||||
|
||||
// Old track segment now ends at new point.
|
||||
aSegment->SetEnd(lockPoint);
|
||||
aSegment->end = newTrack;
|
||||
aSegment->SetState( END_ONPAD, false );
|
||||
|
||||
D_PAD * pad = GetPad( newTrack, ENDPOINT_START );
|
||||
|
||||
if( pad )
|
||||
{
|
||||
newTrack->start = pad;
|
||||
newTrack->SetState( BEGIN_ONPAD, true );
|
||||
aSegment->end = pad;
|
||||
aSegment->SetState( END_ONPAD, true );
|
||||
}
|
||||
|
||||
aPosition = lockPoint;
|
||||
return newTrack;
|
||||
}
|
||||
|
||||
|
||||
ZONE_CONTAINER* BOARD::AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode,
|
||||
PCB_LAYER_ID aLayer, wxPoint aStartPointPosition, int aHatch )
|
||||
{
|
||||
|
@ -30,6 +30,7 @@
|
||||
#ifndef CLASS_BOARD_H_
|
||||
#define CLASS_BOARD_H_
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#include <dlist.h>
|
||||
#include <core/iterators.h>
|
||||
@ -161,7 +162,7 @@ protected:
|
||||
|
||||
DECL_VEC_FOR_SWIG( MARKERS, MARKER_PCB* )
|
||||
DECL_VEC_FOR_SWIG( ZONE_CONTAINERS, ZONE_CONTAINER* )
|
||||
DECL_VEC_FOR_SWIG( TRACKS, TRACK* )
|
||||
DECL_DEQ_FOR_SWIG( TRACKS, TRACK* )
|
||||
DECL_DEQ_FOR_SWIG( DRAWINGS, BOARD_ITEM* )
|
||||
DECL_DEQ_FOR_SWIG( MODULES, MODULE* )
|
||||
|
||||
@ -187,6 +188,9 @@ private:
|
||||
/// MODULES for components on the board, owned by pointer.
|
||||
MODULES m_modules;
|
||||
|
||||
/// TRACKS for traces on the board, owned by pointer.
|
||||
TRACKS m_tracks;
|
||||
|
||||
/// edge zone descriptors, owned by pointer.
|
||||
ZONE_CONTAINERS m_ZoneDescriptorList;
|
||||
|
||||
@ -208,18 +212,6 @@ private:
|
||||
PCB_PLOT_PARAMS m_plotOptions;
|
||||
NETINFO_LIST m_NetInfo; ///< net info list (name, design constraints ..
|
||||
|
||||
/**
|
||||
* Function chainMarkedSegments
|
||||
* is used by MarkTrace() to set the BUSY flag of connected segments of the trace
|
||||
* segment located at \a aPosition on aLayerMask.
|
||||
* Vias are put in list but their flags BUSY is not set
|
||||
* @param aTrackList is the beginning of the track list (usually the board track list).
|
||||
* @param aPosition A wxPoint object containing the position of the starting search.
|
||||
* @param aLayerSet The allowed layers for segments to search.
|
||||
* @param aList The track list to fill with points of flagged segments.
|
||||
*/
|
||||
void chainMarkedSegments( TRACK* aTrackList, wxPoint aPosition,
|
||||
const LSET& aLayerSet, TRACKS* aList );
|
||||
|
||||
// The default copy constructor & operator= are inadequate,
|
||||
// either write one or do not use it at all
|
||||
@ -245,15 +237,16 @@ public:
|
||||
|
||||
const wxString &GetFileName() const { return m_fileName; }
|
||||
|
||||
/// Flags used in ratsnest calculation and update.
|
||||
int m_Status_Pcb;
|
||||
TRACKS& Tracks()
|
||||
{
|
||||
return m_tracks;
|
||||
}
|
||||
const TRACKS& Tracks() const
|
||||
{
|
||||
return m_tracks;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
DLIST<TRACK> m_Track; // linked list of TRACKs and VIAs
|
||||
|
||||
DLIST_ITERATOR_WRAPPER<TRACK> Tracks() { return DLIST_ITERATOR_WRAPPER<TRACK>(m_Track); }
|
||||
MODULES& Modules()
|
||||
MODULES& Modules()
|
||||
{
|
||||
return m_modules;
|
||||
}
|
||||
@ -261,8 +254,17 @@ public:
|
||||
{
|
||||
return m_modules;
|
||||
}
|
||||
DRAWINGS& Drawings() { return m_drawings; }
|
||||
ZONE_CONTAINERS& Zones() { return m_ZoneDescriptorList; }
|
||||
|
||||
DRAWINGS& Drawings()
|
||||
{
|
||||
return m_drawings;
|
||||
}
|
||||
|
||||
ZONE_CONTAINERS& Zones()
|
||||
{
|
||||
return m_ZoneDescriptorList;
|
||||
}
|
||||
|
||||
const std::vector<BOARD_CONNECTED_ITEM*> AllConnectedItems();
|
||||
|
||||
/// zone contour currently in progress
|
||||
@ -276,7 +278,7 @@ public:
|
||||
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return m_drawings.empty() && m_modules.empty() && m_Track.GetCount() == 0;
|
||||
return m_drawings.empty() && m_modules.empty() && m_tracks.empty();
|
||||
}
|
||||
|
||||
void Move( const wxPoint& aMoveVector ) override;
|
||||
@ -423,18 +425,6 @@ public:
|
||||
*/
|
||||
void HighLightON() { m_highLight.m_highLightOn = true; }
|
||||
|
||||
/**
|
||||
* Function PushHighLight
|
||||
* save current high light info for later use
|
||||
*/
|
||||
void PushHighLight();
|
||||
|
||||
/**
|
||||
* Function PopHighLight
|
||||
* retrieve a previously saved high light info
|
||||
*/
|
||||
void PopHighLight();
|
||||
|
||||
/**
|
||||
* Function GetCopperLayerCount
|
||||
* @return int - The number of copper layers in the BOARD.
|
||||
@ -715,9 +705,6 @@ public:
|
||||
*/
|
||||
bool SetLayerType( PCB_LAYER_ID aLayer, LAYER_T aLayerType );
|
||||
|
||||
/** Functions to get some items count */
|
||||
int GetNumSegmTrack() const;
|
||||
|
||||
/**
|
||||
* Function GetNodesCount
|
||||
* @param aNet Only count nodes belonging to this net
|
||||
@ -1091,31 +1078,6 @@ public:
|
||||
ZONE_CONTAINER* area_ref,
|
||||
ZONE_CONTAINER* area_to_combine );
|
||||
|
||||
/**
|
||||
* Function GetViaByPosition
|
||||
* finds the first via at \a aPosition on \a aLayer.
|
||||
* <p>
|
||||
* This function does not use the normal hit test to locate a via which which tests
|
||||
* if a position is within the via's bounding box. It tests for the actual locate
|
||||
* of the via.
|
||||
* </p>
|
||||
* @param aPosition The wxPoint to HitTest() against.
|
||||
* @param aLayer The layer to search. Use -1 (PCB_LAYER_ID::UNDEFINED_LAYER) for a don't care.
|
||||
* @return VIA* A point a to the VIA object if found, else NULL.
|
||||
*/
|
||||
VIA* GetViaByPosition( const wxPoint& aPosition,
|
||||
PCB_LAYER_ID aLayer = PCB_LAYER_ID( -1 ) ) const;
|
||||
|
||||
/**
|
||||
* Function GetTracksByPosition
|
||||
* finds the list of tracks that starts or ends at \a aPosition on \a aLayer.
|
||||
*
|
||||
* @param aPosition The wxPoint to check start agains against.
|
||||
* @param aLayer The layer to search. Use -1 (<PCB_LAYER_ID>::UNDEFINED_LAYER) for a don't care.
|
||||
* @return std::list<TRACK*> A list of TRACK* items that can be zero if no track is found.
|
||||
*/
|
||||
std::list<TRACK*> GetTracksByPosition( const wxPoint& aPosition, PCB_LAYER_ID aLayer = PCB_LAYER_ID( -1 ) ) const;
|
||||
|
||||
/**
|
||||
* Function GetPad
|
||||
* finds a pad \a aPosition on \a aLayer.
|
||||
@ -1192,48 +1154,13 @@ public:
|
||||
void GetSortedPadListByXthenYCoord( std::vector<D_PAD*>& aVector, int aNetCode = -1 );
|
||||
|
||||
/**
|
||||
* Function GetVisibleTrack
|
||||
* finds the neighboring visible segment of \a aTrace at \a aPosition that is
|
||||
* on a layer in \a aLayerSet.
|
||||
* Traces that are flagged as deleted or busy are ignored.
|
||||
* Returns data on the length and number of track segments connected to a given track.
|
||||
* This uses the connectivity data for the board to calculate connections
|
||||
*
|
||||
* @param aStartingTrace is the first TRACK to test, testing continues to end of m_Track list from
|
||||
* this starting point.
|
||||
* @param aPosition A wxPoint object containing the position to test.
|
||||
* @param aLayerSet A set of layers; returned TRACK must be on one of these.
|
||||
* May pass a full set to request any layer.
|
||||
* @return A TRACK object pointer if found otherwise NULL.
|
||||
* @param aTrack Starting track (can also be a via) to check against for connection.
|
||||
* @return a tuple containing <number, length, package length>
|
||||
*/
|
||||
TRACK* GetVisibleTrack( TRACK* aStartingTrace, const wxPoint& aPosition, LSET aLayerSet ) const;
|
||||
|
||||
/**
|
||||
* Function MarkTrace
|
||||
* marks a chain of trace segments, connected to \a aTrace.
|
||||
* <p>
|
||||
* Each segment is marked by setting the BUSY bit into m_Flags. Electrical
|
||||
* continuity is detected by walking each segment, and finally the segments
|
||||
* are rearranged into a contiguous chain within the given list.
|
||||
* </p>
|
||||
*
|
||||
* @param aTrackList The list of available track segments.
|
||||
* usually tracks on board, but can be a list of segments currently created.
|
||||
* @param aTrace The segment within a list of trace segments to test.
|
||||
* @param aCount A pointer to an integer where to return the number of
|
||||
* marked segments (can be NULL).
|
||||
* @param aTraceLength A pointer to an double where to return the length of the
|
||||
* trace (can be NULL).
|
||||
* @param aInPackageLength A pointer to an double where to return the extra lengths inside
|
||||
* integrated circuits from the pads connected to this track to the
|
||||
* die (if any) (can be NULL).
|
||||
* @param aReorder true for reorder the interesting segments (useful for
|
||||
* track editing/deleting) in this case the flag BUSY is
|
||||
* set (the user is responsible of flag clearing). False
|
||||
* for no reorder : useful when we want just calculate the
|
||||
* track length in this case, flags are reset
|
||||
* @return TRACK* - The first in the chain of interesting segments.
|
||||
*/
|
||||
TRACK* MarkTrace( TRACK* aTrackList, TRACK* aTrace, int* aCount, double* aTraceLength,
|
||||
double* aInPackageLength, bool aReorder );
|
||||
std::tuple<int, double, double> GetTrackLength( const TRACK& aTrack ) const;
|
||||
|
||||
/**
|
||||
* Function TrackInNet
|
||||
@ -1244,25 +1171,6 @@ public:
|
||||
*/
|
||||
TRACKS TracksInNet( int aNetCode );
|
||||
|
||||
/**
|
||||
* Function TrackInNetBetweenPoints
|
||||
* collects all the TRACKs and VIAs that are members of a net given by aNetCode and that
|
||||
* make up a path between two end points. The end points must be carefully chosen,
|
||||
* and are typically the locations of two neighboring pads. The function fails if there
|
||||
* is an intervening pad or a 3 way intersection at a track or via. The seeking starts
|
||||
* at @a aStartPos and strives to travel to @a aGoalPos.
|
||||
* Used from python.
|
||||
* @param aStartPos must correspond to a point on the BOARD which has a TRACK end or start,
|
||||
* typically the location of either a via or pad.
|
||||
* @param aGoalPos must correspond to a point on the BOARD which has a TRACK end or start,
|
||||
* typically the location of either a via or pad.
|
||||
* @param aNetCode gives the id of the net.
|
||||
* @return TRACKS - non empty if success, empty if your aStartPos or aEndPos are bad or
|
||||
* the net is interrupted along the way by an intervening D_PAD or a 3 way path.
|
||||
* @throw IO_ERROR in order to convey detailed error reason upon failure.
|
||||
*/
|
||||
TRACKS TracksInNetBetweenPoints( const wxPoint& aStartPos, const wxPoint& aGoalPos, int aNetCode );
|
||||
|
||||
/**
|
||||
* Function GetFootprint
|
||||
* get a footprint by its bounding rectangle at \a aPosition on \a aLayer.
|
||||
@ -1280,40 +1188,6 @@ public:
|
||||
MODULE* GetFootprint( const wxPoint& aPosition, PCB_LAYER_ID aActiveLayer,
|
||||
bool aVisibleOnly, bool aIgnoreLocked = false );
|
||||
|
||||
/**
|
||||
* Function GetLockPoint
|
||||
* returns the item at the "attachment" point at the end of a trace at \a aPosition
|
||||
* on \a aLayerMask.
|
||||
* <p>
|
||||
* This may be a PAD or another trace segment.
|
||||
* </p>
|
||||
*
|
||||
* @param aPosition A wxPoint object containing the position to test.
|
||||
* @param aLayerMask A layer or layers to mask the hit test. Use -1 to ignore
|
||||
* layer mask.
|
||||
* @return A pointer to a BOARD_ITEM object if found otherwise NULL.
|
||||
*/
|
||||
BOARD_CONNECTED_ITEM* GetLockPoint( const wxPoint& aPosition, LSET aLayerMask );
|
||||
|
||||
/**
|
||||
* Function CreateLockPoint
|
||||
* creates an intermediate point on \a aSegment and break it into two segments
|
||||
* at \a aPosition.
|
||||
* <p>
|
||||
* The new segment starts from \a aPosition and ends at the end point of \a
|
||||
* aSegment. The original segment now ends at \a aPosition.
|
||||
* </p>
|
||||
*
|
||||
* @param aPosition A wxPoint object containing the position to test and the new
|
||||
* segment start position if the return value is not NULL.
|
||||
* @param aSegment The trace segment to create the lock point on.
|
||||
* @param aList The pick list to add the created items to.
|
||||
* @return NULL if no new point was created or a pointer to a TRACK object of the
|
||||
* created segment. If \a aSegment points to a via the exact value of \a
|
||||
* aPosition and a pointer to the via are returned.
|
||||
*/
|
||||
TRACK* CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS_LIST* aList );
|
||||
|
||||
/**
|
||||
* Function ClearAllNetCodes()
|
||||
* Resets all items' netcodes to 0 (no net).
|
||||
|
@ -58,40 +58,10 @@ static bool ShowClearance( PCB_DISPLAY_OPTIONS* aDisplOpts, const TRACK* aTrack
|
||||
}
|
||||
|
||||
|
||||
TRACK* GetTrack( TRACK* aStartTrace, const TRACK* aEndTrace,
|
||||
const wxPoint& aPosition, LSET aLayerMask )
|
||||
{
|
||||
for( TRACK* seg = aStartTrace; seg; seg = seg->Next() )
|
||||
{
|
||||
if( seg->GetState( IS_DELETED | BUSY ) == 0 )
|
||||
{
|
||||
if( aPosition == seg->GetStart() )
|
||||
{
|
||||
if( ( aLayerMask & seg->GetLayerSet() ).any() )
|
||||
return seg;
|
||||
}
|
||||
|
||||
if( aPosition == seg->GetEnd() )
|
||||
{
|
||||
if( ( aLayerMask & seg->GetLayerSet() ).any() )
|
||||
return seg;
|
||||
}
|
||||
}
|
||||
|
||||
if( seg == aEndTrace )
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
TRACK::TRACK( BOARD_ITEM* aParent, KICAD_T idtype ) :
|
||||
BOARD_CONNECTED_ITEM( aParent, idtype )
|
||||
{
|
||||
m_Width = Millimeter2iu( 0.2 );
|
||||
start = end = NULL;
|
||||
m_Param = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -188,16 +158,7 @@ int VIA::GetDrillValue() const
|
||||
}
|
||||
|
||||
|
||||
bool TRACK::IsNull()
|
||||
{
|
||||
if( ( Type() != PCB_VIA_T ) && ( m_Start == m_End ) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
STATUS_FLAGS TRACK::IsPointOnEnds( const wxPoint& point, int min_dist )
|
||||
STATUS_FLAGS TRACK::IsPointOnEnds( const wxPoint& point, int min_dist ) const
|
||||
{
|
||||
STATUS_FLAGS result = 0;
|
||||
|
||||
@ -419,21 +380,6 @@ void VIA::SanitizeLayers()
|
||||
}
|
||||
|
||||
|
||||
TRACK* TRACK::GetBestInsertPoint( BOARD* aPcb )
|
||||
{
|
||||
// When reading from a file most of the items will already be in the correct order.
|
||||
// Searching from the back therefore takes us from n^2 to essentially 0.
|
||||
|
||||
for( TRACK* track = aPcb->m_Track.GetLast(); track; track = track->Back() )
|
||||
{
|
||||
if( GetNetCode() >= track->GetNetCode() )
|
||||
return track->Next();
|
||||
}
|
||||
|
||||
return aPcb->m_Track.GetFirst();
|
||||
}
|
||||
|
||||
|
||||
TRACK* TRACK::GetStartNetCode( int NetCode )
|
||||
{
|
||||
TRACK* Track = this;
|
||||
@ -794,17 +740,12 @@ void TRACK::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >&
|
||||
// Display full track length (in Pcbnew)
|
||||
if( board )
|
||||
{
|
||||
double trackLen = 0;
|
||||
double lenPadToDie = 0;
|
||||
int count;
|
||||
double trackLen;
|
||||
double lenPadToDie;
|
||||
|
||||
// Find the beginning of the track buffer containing this, because it is not
|
||||
// always the track list on board, but can be a "private" list
|
||||
TRACK* track_buffer_start = this;
|
||||
std::tie( count, trackLen, lenPadToDie ) = board->GetTrackLength( *this );
|
||||
|
||||
while( track_buffer_start->Back() )
|
||||
track_buffer_start = track_buffer_start->Back();
|
||||
|
||||
board->MarkTrace( track_buffer_start, this, NULL, &trackLen, &lenPadToDie, false );
|
||||
msg = MessageTextFromValue( aUnits, trackLen );
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Length" ), msg, DARKCYAN ) );
|
||||
|
||||
@ -1059,248 +1000,6 @@ bool VIA::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
|
||||
}
|
||||
|
||||
|
||||
VIA* TRACK::GetVia( const wxPoint& aPosition, PCB_LAYER_ID aLayer)
|
||||
{
|
||||
for( VIA* via = GetFirstVia( this ); via; via = GetFirstVia( via->Next() ) )
|
||||
{
|
||||
if( via->HitTest( aPosition ) &&
|
||||
!via->GetState( BUSY | IS_DELETED ) &&
|
||||
((aLayer == UNDEFINED_LAYER) || (via->IsOnLayer( aLayer ))) )
|
||||
return via;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
VIA* TRACK::GetVia( TRACK* aEndTrace, const wxPoint& aPosition, LSET aLayerMask )
|
||||
{
|
||||
for( VIA* via = GetFirstVia( this, aEndTrace ); via; via = GetFirstVia( via->Next() ) )
|
||||
{
|
||||
if( via->HitTest( aPosition ) &&
|
||||
!via->GetState( BUSY | IS_DELETED ) &&
|
||||
( aLayerMask & via->GetLayerSet() ).any()
|
||||
)
|
||||
{
|
||||
return via;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
TRACK* TRACK::GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, ENDPOINT_T aEndPoint,
|
||||
bool aSameNetOnly, bool aSequential )
|
||||
{
|
||||
const wxPoint& position = GetEndPoint( aEndPoint );
|
||||
LSET refLayers = GetLayerSet();
|
||||
TRACK* previousSegment;
|
||||
TRACK* nextSegment;
|
||||
|
||||
if( aSequential )
|
||||
{
|
||||
// Simple sequential search: from aStartTrace forward to aEndTrace
|
||||
previousSegment = NULL;
|
||||
nextSegment = aStartTrace;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Local bidirectional search: from this backward to aStartTrace
|
||||
* AND forward to aEndTrace. The idea is that nearest segments
|
||||
* are found (on average) faster in this way. In fact same-net
|
||||
* segments are almost guaranteed to be found faster, in a global
|
||||
* search, since they are grouped together in the track list */
|
||||
previousSegment = this;
|
||||
nextSegment = this;
|
||||
}
|
||||
|
||||
while( nextSegment || previousSegment )
|
||||
{
|
||||
// Terminate the search in the direction if the netcode mis-matches
|
||||
if( aSameNetOnly )
|
||||
{
|
||||
if( nextSegment && (nextSegment->GetNetCode() != GetNetCode()) )
|
||||
nextSegment = NULL;
|
||||
if( previousSegment && (previousSegment->GetNetCode() != GetNetCode()) )
|
||||
previousSegment = NULL;
|
||||
}
|
||||
|
||||
if( nextSegment )
|
||||
{
|
||||
if ( (nextSegment != this) &&
|
||||
!nextSegment->GetState( BUSY | IS_DELETED ) &&
|
||||
( refLayers & nextSegment->GetLayerSet() ).any() )
|
||||
{
|
||||
if( (position == nextSegment->m_Start) ||
|
||||
(position == nextSegment->m_End) )
|
||||
return nextSegment;
|
||||
}
|
||||
|
||||
// Keep looking forward
|
||||
if( nextSegment == aEndTrace )
|
||||
nextSegment = NULL;
|
||||
else
|
||||
nextSegment = nextSegment->Next();
|
||||
}
|
||||
|
||||
// Same as above, looking back. During sequential search this branch is inactive
|
||||
if( previousSegment )
|
||||
{
|
||||
if( (previousSegment != this) &&
|
||||
!previousSegment->GetState( BUSY | IS_DELETED ) &&
|
||||
( refLayers & previousSegment->GetLayerSet() ).any()
|
||||
)
|
||||
{
|
||||
if( (position == previousSegment->m_Start) ||
|
||||
(position == previousSegment->m_End) )
|
||||
return previousSegment;
|
||||
}
|
||||
|
||||
if( previousSegment == aStartTrace )
|
||||
previousSegment = NULL;
|
||||
else
|
||||
previousSegment = previousSegment->Back();
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int TRACK::GetEndSegments( int aCount, TRACK** aStartTrace, TRACK** aEndTrace )
|
||||
{
|
||||
TRACK* Track, * via, * segm, * TrackListEnd;
|
||||
int NbEnds, ii, ok = 0;
|
||||
LSET layerMask;
|
||||
|
||||
if( aCount <= 1 )
|
||||
{
|
||||
*aStartTrace = *aEndTrace = this;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Calculation of the limit analysis.
|
||||
*aStartTrace = *aEndTrace = NULL;
|
||||
TrackListEnd = Track = this;
|
||||
ii = 0;
|
||||
|
||||
for( ; ( Track != NULL ) && ( ii < aCount ); ii++, Track = Track->Next() )
|
||||
{
|
||||
TrackListEnd = Track;
|
||||
Track->m_Param = 0;
|
||||
}
|
||||
|
||||
// Calculate the extremes.
|
||||
NbEnds = 0;
|
||||
Track = this;
|
||||
ii = 0;
|
||||
|
||||
for( ; ( Track != NULL ) && ( ii < aCount ); ii++, Track = Track->Next() )
|
||||
{
|
||||
if( Track->Type() == PCB_VIA_T )
|
||||
continue;
|
||||
|
||||
layerMask = Track->GetLayerSet();
|
||||
via = GetVia( TrackListEnd, Track->m_Start, layerMask );
|
||||
|
||||
if( via )
|
||||
{
|
||||
layerMask |= via->GetLayerSet();
|
||||
via->SetState( BUSY, true );
|
||||
}
|
||||
|
||||
Track->SetState( BUSY, true );
|
||||
segm = ::GetTrack( this, TrackListEnd, Track->m_Start, layerMask );
|
||||
Track->SetState( BUSY, false );
|
||||
|
||||
if( via )
|
||||
via->SetState( BUSY, false );
|
||||
|
||||
if( segm == NULL )
|
||||
{
|
||||
switch( NbEnds )
|
||||
{
|
||||
case 0:
|
||||
*aStartTrace = Track; NbEnds++;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
int BeginPad, EndPad;
|
||||
*aEndTrace = Track;
|
||||
|
||||
// Swap ox, oy with fx, fy
|
||||
BeginPad = Track->GetState( BEGIN_ONPAD );
|
||||
EndPad = Track->GetState( END_ONPAD );
|
||||
|
||||
Track->SetState( BEGIN_ONPAD | END_ONPAD, false );
|
||||
|
||||
if( BeginPad )
|
||||
Track->SetState( END_ONPAD, true );
|
||||
|
||||
if( EndPad )
|
||||
Track->SetState( BEGIN_ONPAD, true );
|
||||
|
||||
std::swap( Track->m_Start, Track->m_End );
|
||||
std::swap( Track->start, Track->end );
|
||||
ok = 1;
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
|
||||
layerMask = Track->GetLayerSet();
|
||||
via = GetVia( TrackListEnd, Track->m_End, layerMask );
|
||||
|
||||
if( via )
|
||||
{
|
||||
layerMask |= via->GetLayerSet();
|
||||
via->SetState( BUSY, true );
|
||||
}
|
||||
|
||||
Track->SetState( BUSY, true );
|
||||
segm = ::GetTrack( this, TrackListEnd, Track->m_End, layerMask );
|
||||
Track->SetState( BUSY, false );
|
||||
|
||||
if( via )
|
||||
via->SetState( BUSY, false );
|
||||
|
||||
if( segm == NULL )
|
||||
{
|
||||
switch( NbEnds )
|
||||
{
|
||||
case 0:
|
||||
int BeginPad, EndPad;
|
||||
*aStartTrace = Track;
|
||||
NbEnds++;
|
||||
|
||||
// Swap ox, oy with fx, fy
|
||||
BeginPad = Track->GetState( BEGIN_ONPAD );
|
||||
EndPad = Track->GetState( END_ONPAD );
|
||||
|
||||
Track->SetState( BEGIN_ONPAD | END_ONPAD, false );
|
||||
|
||||
if( BeginPad )
|
||||
Track->SetState( END_ONPAD, true );
|
||||
|
||||
if( EndPad )
|
||||
Track->SetState( BEGIN_ONPAD, true );
|
||||
|
||||
std::swap( Track->m_Start, Track->m_End );
|
||||
std::swap( Track->start, Track->end );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
*aEndTrace = Track;
|
||||
ok = 1;
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
wxString TRACK::GetSelectMenuText( EDA_UNITS_T aUnits ) const
|
||||
{
|
||||
return wxString::Format( _("Track %s %s on %s, length: %s" ),
|
||||
|
@ -37,6 +37,8 @@
|
||||
#include <pcb_display_options.h>
|
||||
#include <pcbnew.h>
|
||||
|
||||
#include <geometry/seg.h>
|
||||
|
||||
#include <trigo.h>
|
||||
|
||||
|
||||
@ -72,25 +74,6 @@ enum VIATYPE_T
|
||||
#define GEOMETRY_MIN_SIZE ( int )( 0.001 * IU_PER_MM )
|
||||
|
||||
|
||||
/**
|
||||
* Function GetTrack
|
||||
* is a helper function to locate a trace segment having an end point at \a aPosition
|
||||
* on \a aLayerMask starting at \a aStartTrace and end at \a aEndTrace.
|
||||
* <p>
|
||||
* The segments of track that are flagged as deleted or busy are ignored. Layer
|
||||
* visibility is also ignored.
|
||||
* </p>
|
||||
* @param aStartTrace A pointer to the TRACK object to begin searching.
|
||||
* @param aEndTrace A pointer to the TRACK object to stop the search. A NULL value
|
||||
* searches to the end of the list.
|
||||
* @param aPosition A wxPoint object containing the position to test.
|
||||
* @param aLayerMask A layer or layers to mask the hit test. Use -1 to ignore
|
||||
* layer mask.
|
||||
* @return A TRACK object pointer if found otherwise NULL.
|
||||
*/
|
||||
TRACK* GetTrack( TRACK* aStartTrace, const TRACK* aEndTrace,
|
||||
const wxPoint& aPosition, LSET aLayerMask );
|
||||
|
||||
class TRACK : public BOARD_CONNECTED_ITEM
|
||||
{
|
||||
public:
|
||||
@ -99,18 +82,10 @@ public:
|
||||
return aItem && PCB_TRACE_T == aItem->Type();
|
||||
}
|
||||
|
||||
BOARD_CONNECTED_ITEM* start; // pointers to a connected item (pad or track)
|
||||
BOARD_CONNECTED_ITEM* end;
|
||||
|
||||
double m_Param; // Auxiliary variable ( used in some computations )
|
||||
|
||||
TRACK( BOARD_ITEM* aParent, KICAD_T idtype = PCB_TRACE_T );
|
||||
|
||||
// Do not create a copy constructor. The one generated by the compiler is adequate.
|
||||
|
||||
TRACK* Next() const { return static_cast<TRACK*>( Pnext ); }
|
||||
TRACK* Back() const { return static_cast<TRACK*>( Pback ); }
|
||||
|
||||
virtual void Move( const wxPoint& aMoveVector ) override
|
||||
{
|
||||
m_Start += aMoveVector;
|
||||
@ -156,19 +131,6 @@ public:
|
||||
return SetState( TRACK_LOCKED, aLocked );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetBestInsertPoint
|
||||
* searches the "best" insertion point within the track linked list.
|
||||
* The best point is currently the end of the corresponding net code section.
|
||||
* (The BOARD::m_Track and BOARD::m_Zone lists are sorted by netcode.)
|
||||
* @param aPcb The BOARD to search for the insertion point.
|
||||
* @return TRACK* - the insertion point in the linked list.
|
||||
* this is the next item after the last item having my net code.
|
||||
* therefore the track to insert must be inserted before the insertion point.
|
||||
* if the best insertion point is the end of list, the returned value is NULL
|
||||
*/
|
||||
TRACK* GetBestInsertPoint( BOARD* aPcb );
|
||||
|
||||
/* Search (within the track linked list) the first segment matching the netcode
|
||||
* ( the linked list is always sorted by net codes )
|
||||
*/
|
||||
@ -211,13 +173,16 @@ public:
|
||||
* (dist = min_dist) both ends, or 0 if none of the above.
|
||||
* if min_dist < 0: min_dist = track_width/2
|
||||
*/
|
||||
STATUS_FLAGS IsPointOnEnds( const wxPoint& point, int min_dist = 0 );
|
||||
STATUS_FLAGS IsPointOnEnds( const wxPoint& point, int min_dist = 0 ) const;
|
||||
|
||||
/**
|
||||
* Function IsNull
|
||||
* returns true if segment length is zero.
|
||||
*/
|
||||
bool IsNull();
|
||||
bool IsNull() const
|
||||
{
|
||||
return ( Type() == PCB_VIA_T ) || ( m_Start == m_End );
|
||||
}
|
||||
|
||||
void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override;
|
||||
|
||||
@ -226,57 +191,12 @@ public:
|
||||
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
|
||||
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
|
||||
|
||||
/**
|
||||
* Function GetVia
|
||||
* finds the first VIA object at \a aPosition on \a aLayer starting at the trace.
|
||||
*
|
||||
* @param aPosition The wxPoint to HitTest() against.
|
||||
* @param aLayer The layer to match, pass -1 for a don't care.
|
||||
* @return A pointer to a VIA object if found, else NULL.
|
||||
*/
|
||||
VIA* GetVia( const wxPoint& aPosition, PCB_LAYER_ID aLayer = UNDEFINED_LAYER );
|
||||
|
||||
/**
|
||||
* Function GetVia
|
||||
* finds the first VIA object at \a aPosition on \a aLayer starting at the trace
|
||||
* and ending at \a aEndTrace.
|
||||
*
|
||||
* @param aEndTrace Pointer to the last TRACK object to end search.
|
||||
* @param aPosition The wxPoint to HitTest() against.
|
||||
* @param aLayerMask The layers to match, pass -1 for a don't care.
|
||||
* @return A pointer to a VIA object if found, else NULL.
|
||||
*/
|
||||
VIA* GetVia( TRACK* aEndTrace, const wxPoint& aPosition, LSET aLayerMask );
|
||||
|
||||
/**
|
||||
* Function GetTrack
|
||||
* returns the trace segment connected to the segment at \a aEndPoint from \a
|
||||
* aStartTrace to \a aEndTrace.
|
||||
*
|
||||
* @param aStartTrace A pointer to the TRACK object to begin searching.
|
||||
* @param aEndTrace A pointer to the TRACK object to stop the search. A NULL value
|
||||
* searches to the end of the list.
|
||||
* @param aEndPoint The start or end point of the segment to test against.
|
||||
* @param aSameNetOnly if true stop searching when the netcode changes
|
||||
* @param aSequential If true, forces a forward sequential search,
|
||||
* which is restartable; the default search can be faster but the
|
||||
* position of the returned track in the list is unpredictable
|
||||
* @return A TRACK object pointer if found otherwise NULL.
|
||||
*/
|
||||
TRACK* GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, ENDPOINT_T aEndPoint,
|
||||
bool aSameNetOnly, bool aSequential );
|
||||
|
||||
/**
|
||||
* Function GetEndSegments
|
||||
* get the segments connected to the end point of the track.
|
||||
* return 1 if OK, 0 when a track is a closed loop
|
||||
* and the beginning and the end of the track in *StartTrack and *EndTrack
|
||||
* Modify *StartTrack en *EndTrack :
|
||||
* (*StartTrack)->m_Start coordinate is the beginning of the track
|
||||
* (*EndTrack)->m_End coordinate is the end of the track
|
||||
* Segments connected must be consecutive in list
|
||||
*/
|
||||
int GetEndSegments( int NbSegm, TRACK** StartTrack, TRACK** EndTrack );
|
||||
bool ApproxCollinear( const TRACK& aTrack )
|
||||
{
|
||||
SEG a( m_Start, m_End );
|
||||
SEG b( aTrack.GetStart(), aTrack.GetEnd() );
|
||||
return a.ApproxCollinear( b );
|
||||
}
|
||||
|
||||
wxString GetClass() const override
|
||||
{
|
||||
@ -336,11 +256,6 @@ protected:
|
||||
wxPoint m_Start; ///< Line start point
|
||||
wxPoint m_End; ///< Line end point
|
||||
|
||||
private:
|
||||
// make SetNext() and SetBack() private so that they may not be called from anywhere.
|
||||
// list management is done on TRACKs using DLIST<TRACK> only.
|
||||
void SetNext( EDA_ITEM* aNext ) { Pnext = aNext; }
|
||||
void SetBack( EDA_ITEM* aBack ) { Pback = aBack; }
|
||||
};
|
||||
|
||||
|
||||
@ -472,31 +387,4 @@ private:
|
||||
};
|
||||
|
||||
|
||||
/// 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();
|
||||
|
||||
// It could stop because of the stop point, not on a via
|
||||
if( aTrk && (aTrk->Type() == PCB_VIA_T) )
|
||||
return static_cast<VIA*>( aTrk );
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/// Scan a track list for the first TRACK object. Returns NULL if not found (or NULL passed)
|
||||
inline TRACK* GetFirstTrack( TRACK* aTrk, const TRACK* aStopPoint = NULL )
|
||||
{
|
||||
while( aTrk && ( aTrk != aStopPoint ) && ( aTrk->Type() != PCB_TRACE_T ) )
|
||||
aTrk = aTrk->Next();
|
||||
|
||||
// It could stop because of the stop point, not on a via
|
||||
if( aTrk && ( aTrk->Type() == PCB_TRACE_T ) )
|
||||
return static_cast<TRACK*>( aTrk );
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif // CLASS_TRACK_H
|
||||
|
@ -180,7 +180,7 @@ void DIALOG_GENDRILL::InitDisplayParams()
|
||||
}
|
||||
}
|
||||
|
||||
for( TRACK* track = m_board->m_Track; track != NULL; track = track->Next() )
|
||||
for( auto track : m_board->Tracks() )
|
||||
{
|
||||
const VIA *via = dynamic_cast<const VIA*>( track );
|
||||
if( via )
|
||||
|
@ -196,12 +196,8 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete()
|
||||
if( !m_TrackFilterAR->GetValue() )
|
||||
track_mask_filter |= TRACK_AR;
|
||||
|
||||
TRACK* nexttrack;
|
||||
|
||||
for( TRACK *track = pcb->m_Track; track; track = nexttrack )
|
||||
for( auto track : pcb->Tracks() )
|
||||
{
|
||||
nexttrack = track->Next();
|
||||
|
||||
if( !delAll )
|
||||
{
|
||||
if( ( track->GetState( TRACK_LOCKED | TRACK_AR ) & track_mask_filter ) != 0 )
|
||||
|
@ -329,7 +329,7 @@ bool DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::TransferDataFromWindow()
|
||||
wxBusyCursor dummy;
|
||||
|
||||
// Examine segments
|
||||
for( TRACK* segment = m_brd->m_Track; segment != nullptr; segment = segment->Next() )
|
||||
for( auto segment : m_brd->Tracks() )
|
||||
{
|
||||
if( m_tracks->GetValue() && segment->Type() == PCB_TRACE_T )
|
||||
visitItem( &itemsListPicker, segment );
|
||||
@ -341,7 +341,7 @@ bool DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::TransferDataFromWindow()
|
||||
{
|
||||
m_parent->SaveCopyInUndoList( itemsListPicker, UR_CHANGED );
|
||||
|
||||
for( TRACK* segment = m_brd->m_Track; segment != nullptr; segment = segment->Next() )
|
||||
for( auto segment : m_brd->Tracks() )
|
||||
m_parent->GetGalCanvas()->GetView()->Update( segment );
|
||||
}
|
||||
|
||||
|
@ -1434,7 +1434,6 @@ bool DIALOG_PAD_PROPERTIES::TransferDataFromWindow()
|
||||
if( !padValuesOK() )
|
||||
return false;
|
||||
|
||||
bool rastnestIsChanged = false;
|
||||
int isign = m_isFlipped ? -1 : 1;
|
||||
|
||||
transferDataToPad( m_padMaster );
|
||||
@ -1454,12 +1453,7 @@ bool DIALOG_PAD_PROPERTIES::TransferDataFromWindow()
|
||||
// Update values
|
||||
m_currentPad->SetShape( m_padMaster->GetShape() );
|
||||
m_currentPad->SetAttribute( m_padMaster->GetAttribute() );
|
||||
|
||||
if( m_currentPad->GetPosition() != m_padMaster->GetPosition() )
|
||||
{
|
||||
m_currentPad->SetPosition( m_padMaster->GetPosition() );
|
||||
rastnestIsChanged = true;
|
||||
}
|
||||
m_currentPad->SetPosition( m_padMaster->GetPosition() );
|
||||
|
||||
wxSize size;
|
||||
MODULE* footprint = m_currentPad->GetParent();
|
||||
@ -1505,11 +1499,7 @@ bool DIALOG_PAD_PROPERTIES::TransferDataFromWindow()
|
||||
m_currentPad->FlipPrimitives();
|
||||
}
|
||||
|
||||
if( m_currentPad->GetLayerSet() != m_padMaster->GetLayerSet() )
|
||||
{
|
||||
rastnestIsChanged = true;
|
||||
m_currentPad->SetLayerSet( m_padMaster->GetLayerSet() );
|
||||
}
|
||||
m_currentPad->SetLayerSet( m_padMaster->GetLayerSet() );
|
||||
|
||||
if( m_isFlipped )
|
||||
{
|
||||
@ -1524,12 +1514,7 @@ bool DIALOG_PAD_PROPERTIES::TransferDataFromWindow()
|
||||
if( m_padMaster->GetAttribute() != PAD_ATTRIB_HOLE_NOT_PLATED )
|
||||
padNetcode = m_PadNetSelector->GetSelectedNetcode();
|
||||
|
||||
if( m_currentPad->GetNetCode() != padNetcode )
|
||||
{
|
||||
rastnestIsChanged = true;
|
||||
m_currentPad->SetNetCode( padNetcode );
|
||||
}
|
||||
|
||||
m_currentPad->SetNetCode( padNetcode );
|
||||
m_currentPad->SetLocalClearance( m_padMaster->GetLocalClearance() );
|
||||
m_currentPad->SetLocalSolderMaskMargin( m_padMaster->GetLocalSolderMaskMargin() );
|
||||
m_currentPad->SetLocalSolderPasteMargin( m_padMaster->GetLocalSolderPasteMargin() );
|
||||
|
@ -213,7 +213,7 @@ void PCB_EDIT_FRAME::Swap_Layers( wxCommandEvent& event )
|
||||
bool hasChanges = false;
|
||||
|
||||
// Change tracks.
|
||||
for( TRACK* segm = GetBoard()->m_Track; segm; segm = segm->Next() )
|
||||
for( auto segm : GetBoard()->Tracks() )
|
||||
{
|
||||
if( segm->Type() == PCB_VIA_T )
|
||||
{
|
||||
|
@ -179,7 +179,7 @@ DRC::~DRC()
|
||||
}
|
||||
|
||||
|
||||
int DRC::DrcOnCreatingTrack( TRACK* aRefSegm, TRACK* aList )
|
||||
int DRC::DrcOnCreatingTrack( TRACK* aRefSegm, TRACKS& aList )
|
||||
{
|
||||
updatePointers();
|
||||
|
||||
@ -190,7 +190,7 @@ int DRC::DrcOnCreatingTrack( TRACK* aRefSegm, TRACK* aList )
|
||||
m_reportAllTrackErrors = false;
|
||||
|
||||
// Test new segment against tracks and pads, not against copper zones
|
||||
if( !doTrackDrc( aRefSegm, aList, true, false ) )
|
||||
if( !doTrackDrc( aRefSegm, aList.begin(), aList.end(), true, false ) )
|
||||
{
|
||||
if( m_currentMarker )
|
||||
{
|
||||
@ -833,10 +833,7 @@ void DRC::testTracks( wxWindow *aActiveWindow, bool aShowProgressBar )
|
||||
wxProgressDialog * progressDialog = NULL;
|
||||
const int delta = 500; // This is the number of tests between 2 calls to the
|
||||
// progress bar
|
||||
int count = 0;
|
||||
|
||||
for( TRACK* segm = m_pcb->m_Track; segm && segm->Next(); segm = segm->Next() )
|
||||
count++;
|
||||
int count = m_pcb->Tracks().size();
|
||||
|
||||
int deltamax = count/delta;
|
||||
|
||||
@ -853,7 +850,7 @@ void DRC::testTracks( wxWindow *aActiveWindow, bool aShowProgressBar )
|
||||
int ii = 0;
|
||||
count = 0;
|
||||
|
||||
for( TRACK* segm = m_pcb->m_Track; segm; segm = segm->Next() )
|
||||
for( auto seg_it = m_pcb->Tracks().begin(); seg_it != m_pcb->Tracks().end(); seg_it++ )
|
||||
{
|
||||
if( ii++ > delta )
|
||||
{
|
||||
@ -873,7 +870,7 @@ void DRC::testTracks( wxWindow *aActiveWindow, bool aShowProgressBar )
|
||||
}
|
||||
|
||||
// Test new segment against tracks and pads, optionally against copper zones
|
||||
if( !doTrackDrc( segm, segm->Next(), true, m_doZonesTest ) )
|
||||
if( !doTrackDrc( *seg_it, seg_it + 1, m_pcb->Tracks().end(), true, m_doZonesTest ) )
|
||||
{
|
||||
if( m_currentMarker )
|
||||
{
|
||||
@ -968,7 +965,7 @@ void DRC::testKeepoutAreas()
|
||||
continue;
|
||||
}
|
||||
|
||||
for( TRACK* segm = m_pcb->m_Track; segm != NULL; segm = segm->Next() )
|
||||
for( auto segm : m_pcb->Tracks() )
|
||||
{
|
||||
if( segm->Type() == PCB_TRACE_T )
|
||||
{
|
||||
@ -1104,7 +1101,7 @@ void DRC::testCopperDrawItem( DRAWSEGMENT* aItem )
|
||||
}
|
||||
|
||||
// Test tracks and vias
|
||||
for( TRACK* track = m_pcb->m_Track; track != NULL; track = track->Next() )
|
||||
for( auto track : m_pcb->Tracks() )
|
||||
{
|
||||
if( !track->IsOnLayer( aItem->GetLayer() ) )
|
||||
continue;
|
||||
@ -1172,7 +1169,7 @@ void DRC::testCopperTextItem( BOARD_ITEM* aTextItem )
|
||||
SHAPE_RECT rect_area( bbox.GetX(), bbox.GetY(), bbox.GetWidth(), bbox.GetHeight() );
|
||||
|
||||
// Test tracks and vias
|
||||
for( TRACK* track = m_pcb->m_Track; track != NULL; track = track->Next() )
|
||||
for( auto track : m_pcb->Tracks() )
|
||||
{
|
||||
if( !track->IsOnLayer( aTextItem->GetLayer() ) )
|
||||
continue;
|
||||
|
17
pcbnew/drc.h
17
pcbnew/drc.h
@ -29,10 +29,12 @@
|
||||
#ifndef DRC_H
|
||||
#define DRC_H
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <class_board.h>
|
||||
#include <class_track.h>
|
||||
#include <geometry/seg.h>
|
||||
#include <geometry/shape_poly_set.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <drc/drc_marker_factory.h>
|
||||
|
||||
@ -327,14 +329,15 @@ private:
|
||||
* Test the current segment.
|
||||
*
|
||||
* @param aRefSeg The segment to test
|
||||
* @param aStart the first item of track list to test against (usually BOARD::m_Track)
|
||||
* @param aStartIt the iterator to the first track to test
|
||||
* @param aEndIt the marker for the iterator end
|
||||
* @param aTestPads true if should do pads test
|
||||
* @param aTestZones true if should do copper zones test. This can be very time consumming
|
||||
* @return bool - true if no problems, else false and m_currentMarker is
|
||||
* filled in with the problem information.
|
||||
*/
|
||||
bool doTrackDrc( TRACK* aRefSeg, TRACK* aStart,
|
||||
bool aTestPads, bool aTestZones );
|
||||
bool doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterator aEndIt,
|
||||
bool aTestPads, bool aTestZones );
|
||||
|
||||
/**
|
||||
* Test the current segment or via.
|
||||
@ -428,10 +431,10 @@ public:
|
||||
* No marker created or added to the board. Must be used only during track
|
||||
* creation in legacy canvas
|
||||
* @param aRefSeg The current segment to test.
|
||||
* @param aList The track list to test (usually m_Pcb->m_Track)
|
||||
* @param aList The track list to test (usually m_Pcb->Tracks())
|
||||
* @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK
|
||||
*/
|
||||
int DrcOnCreatingTrack( TRACK* aRefSeg, TRACK* aList );
|
||||
int DrcOnCreatingTrack( TRACK* aRefSeg, TRACKS& aList );
|
||||
|
||||
/**
|
||||
* Function Drc
|
||||
|
@ -135,7 +135,8 @@ bool convex2pointDRC( wxPoint* aTref, int aTrefCount, wxPoint aPcompare, int aDi
|
||||
}
|
||||
|
||||
|
||||
bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool aTestPads, bool aTestZones )
|
||||
bool DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterator aEndIt,
|
||||
bool aTestPads, bool aTestZones )
|
||||
{
|
||||
TRACK* track;
|
||||
wxPoint delta; // length on X and Y axis of segments
|
||||
@ -431,8 +432,9 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool aTestPads, bool aTestZ
|
||||
wxPoint segStartPoint;
|
||||
wxPoint segEndPoint;
|
||||
|
||||
for( track = aStart; track; track = track->Next() )
|
||||
for( auto it = aStartIt; it != aEndIt; it++ )
|
||||
{
|
||||
track = *it;
|
||||
// No problem if segments have the same net code:
|
||||
if( net_code_ref == track->GetNetCode() )
|
||||
continue;
|
||||
|
@ -2107,7 +2107,7 @@ void EAGLE_PLUGIN::loadSignals( wxXmlNode* aSignals )
|
||||
t->SetLayer( layer );
|
||||
t->SetNetCode( netCode );
|
||||
|
||||
m_board->m_Track.PushBack( t );
|
||||
m_board->Add( t );
|
||||
|
||||
start = end;
|
||||
angle -= delta_angle;
|
||||
@ -2122,7 +2122,7 @@ void EAGLE_PLUGIN::loadSignals( wxXmlNode* aSignals )
|
||||
t->SetLayer( layer );
|
||||
t->SetNetCode( netCode );
|
||||
|
||||
m_board->m_Track.PushBack( t );
|
||||
m_board->Add( t );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2146,7 +2146,7 @@ void EAGLE_PLUGIN::loadSignals( wxXmlNode* aSignals )
|
||||
int kidiam;
|
||||
int drillz = v.drill.ToPcbUnits();
|
||||
VIA* via = new VIA( m_board );
|
||||
m_board->m_Track.PushBack( via );
|
||||
m_board->Add( via );
|
||||
|
||||
via->SetLayerPair( layer_front_most, layer_back_most );
|
||||
|
||||
|
@ -189,7 +189,7 @@ static void build_via_testpoints( BOARD *aPcb,
|
||||
wxPoint origin = aPcb->GetAuxOrigin();
|
||||
|
||||
// Enumerate all the track segments and keep the vias
|
||||
for( TRACK *track = aPcb->m_Track; track; track = track->Next() )
|
||||
for( auto track : aPcb->Tracks() )
|
||||
{
|
||||
if( track->Type() == PCB_VIA_T )
|
||||
{
|
||||
|
@ -363,31 +363,25 @@ void PCB_EDIT_FRAME::ExportToGenCAD( wxCommandEvent& aEvent )
|
||||
|
||||
|
||||
// Comparator for sorting pads with qsort
|
||||
static int PadListSortByShape( const void* aRefptr, const void* aObjptr )
|
||||
static int PadListSortByShape( const D_PAD* aRefptr, const D_PAD* aObjptr )
|
||||
{
|
||||
const D_PAD* padref = *(D_PAD**) aRefptr;
|
||||
const D_PAD* padcmp = *(D_PAD**) aObjptr;
|
||||
|
||||
return D_PAD::Compare( padref, padcmp );
|
||||
return D_PAD::Compare( aRefptr, aObjptr ) < 0;
|
||||
}
|
||||
|
||||
|
||||
// Sort vias for uniqueness
|
||||
static int ViaSort( const void* aRefptr, const void* aObjptr )
|
||||
static bool ViaSort( const VIA* aPadref, const VIA* aPadcmp )
|
||||
{
|
||||
VIA* padref = *(VIA**) aRefptr;
|
||||
VIA* padcmp = *(VIA**) aObjptr;
|
||||
if( aPadref->GetWidth() != aPadcmp->GetWidth() )
|
||||
return aPadref->GetWidth() < aPadcmp->GetWidth();
|
||||
|
||||
if( padref->GetWidth() != padcmp->GetWidth() )
|
||||
return padref->GetWidth() - padcmp->GetWidth();
|
||||
if( aPadref->GetDrillValue() != aPadcmp->GetDrillValue() )
|
||||
return aPadref->GetDrillValue() < aPadcmp->GetDrillValue();
|
||||
|
||||
if( padref->GetDrillValue() != padcmp->GetDrillValue() )
|
||||
return padref->GetDrillValue() - padcmp->GetDrillValue();
|
||||
if( aPadref->GetLayerSet() != aPadcmp->GetLayerSet() )
|
||||
return aPadref->GetLayerSet().FmtBin().compare( aPadcmp->GetLayerSet().FmtBin() ) < 0;
|
||||
|
||||
if( padref->GetLayerSet() != padcmp->GetLayerSet() )
|
||||
return padref->GetLayerSet().FmtBin().compare( padcmp->GetLayerSet().FmtBin() );
|
||||
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -418,33 +412,28 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb )
|
||||
fputs( "$PADS\n", aFile );
|
||||
|
||||
// Enumerate and sort the pads
|
||||
if( aPcb->GetPadCount() > 0 )
|
||||
{
|
||||
pads = aPcb->GetPads();
|
||||
qsort( &pads[0], aPcb->GetPadCount(), sizeof( D_PAD* ),
|
||||
PadListSortByShape );
|
||||
}
|
||||
pads = aPcb->GetPads();
|
||||
std::sort( pads.begin(), pads.end(), PadListSortByShape );
|
||||
|
||||
|
||||
// The same for vias
|
||||
for( VIA* via = GetFirstVia( aPcb->m_Track ); via;
|
||||
via = GetFirstVia( via->Next() ) )
|
||||
for( auto track : aPcb->Tracks() )
|
||||
{
|
||||
vias.push_back( via );
|
||||
if( auto via = dyn_cast<VIA*>( track ) )
|
||||
vias.push_back( via );
|
||||
}
|
||||
|
||||
qsort( &vias[0], vias.size(), sizeof(VIA*), ViaSort );
|
||||
std::sort( vias.begin(), vias.end(), ViaSort );
|
||||
vias.erase( std::unique( vias.begin(), vias.end(),
|
||||
[]( const VIA* a, const VIA* b ) { return ViaSort( a, b ) == 0; } ),
|
||||
vias.end() );
|
||||
|
||||
// Emit vias pads
|
||||
TRACK* old_via = 0;
|
||||
|
||||
for( unsigned i = 0; i < vias.size(); i++ )
|
||||
for( auto item : vias )
|
||||
{
|
||||
VIA* via = vias[i];
|
||||
VIA* via = static_cast<VIA*>( item );
|
||||
|
||||
if( old_via && 0 == ViaSort( &old_via, &via ) )
|
||||
continue;
|
||||
|
||||
old_via = via;
|
||||
viastacks.push_back( via );
|
||||
fprintf( aFile, "PAD V%d.%d.%s ROUND %g\nCIRCLE 0 0 %g\n",
|
||||
via->GetWidth(), via->GetDrillValue(),
|
||||
@ -1043,39 +1032,21 @@ static int TrackListSortByNetcode( const void* refptr, const void* objptr )
|
||||
*/
|
||||
static void CreateRoutesSection( FILE* aFile, BOARD* aPcb )
|
||||
{
|
||||
TRACK* track, ** tracklist;
|
||||
int vianum = 1;
|
||||
int old_netcode, old_width, old_layer;
|
||||
int nbitems, ii;
|
||||
LSET master_layermask = aPcb->GetDesignSettings().GetEnabledLayers();
|
||||
|
||||
int cu_count = aPcb->GetCopperLayerCount();
|
||||
|
||||
// Count items
|
||||
nbitems = 0;
|
||||
|
||||
for( track = aPcb->m_Track; track; track = track->Next() )
|
||||
nbitems++;
|
||||
|
||||
tracklist = (TRACK**) operator new( (nbitems + 1)* sizeof( TRACK* ) );
|
||||
|
||||
nbitems = 0;
|
||||
|
||||
for( track = aPcb->m_Track; track; track = track->Next() )
|
||||
tracklist[nbitems++] = track;
|
||||
|
||||
tracklist[nbitems] = NULL;
|
||||
|
||||
qsort( tracklist, nbitems, sizeof(TRACK*), TrackListSortByNetcode );
|
||||
TRACKS tracks = aPcb->Tracks();
|
||||
std::sort( tracks.begin(), tracks.end(), TrackListSortByNetcode );
|
||||
|
||||
fputs( "$ROUTES\n", aFile );
|
||||
|
||||
old_netcode = -1; old_width = -1; old_layer = -1;
|
||||
|
||||
for( ii = 0; ii < nbitems; ii++ )
|
||||
for( auto track : tracks )
|
||||
{
|
||||
track = tracklist[ii];
|
||||
|
||||
if( old_netcode != track->GetNetCode() )
|
||||
{
|
||||
old_netcode = track->GetNetCode();
|
||||
@ -1125,8 +1096,6 @@ static void CreateRoutesSection( FILE* aFile, BOARD* aPcb )
|
||||
}
|
||||
|
||||
fputs( "$ENDROUTES\n\n", aFile );
|
||||
|
||||
delete tracklist;
|
||||
}
|
||||
|
||||
|
||||
@ -1208,41 +1177,18 @@ static void CreateBoardSection( FILE* aFile, BOARD* aPcb )
|
||||
*/
|
||||
static void CreateTracksInfoData( FILE* aFile, BOARD* aPcb )
|
||||
{
|
||||
TRACK* track;
|
||||
int last_width = -1;
|
||||
|
||||
// Find thickness used for traces
|
||||
// XXX could use the same sorting approach used for pads
|
||||
|
||||
std::vector <int> trackinfo;
|
||||
std::set<int> trackinfo;
|
||||
|
||||
unsigned ii;
|
||||
|
||||
for( track = aPcb->m_Track; track; track = track->Next() )
|
||||
{
|
||||
if( last_width != track->GetWidth() ) // Find a thickness already used.
|
||||
{
|
||||
for( ii = 0; ii < trackinfo.size(); ii++ )
|
||||
{
|
||||
if( trackinfo[ii] == track->GetWidth() )
|
||||
break;
|
||||
}
|
||||
|
||||
if( ii == trackinfo.size() ) // not found
|
||||
trackinfo.push_back( track->GetWidth() );
|
||||
|
||||
last_width = track->GetWidth();
|
||||
}
|
||||
}
|
||||
for( auto track : aPcb->Tracks() )
|
||||
trackinfo.insert( track->GetWidth() );
|
||||
|
||||
// Write data
|
||||
fputs( "$TRACKS\n", aFile );
|
||||
|
||||
for( ii = 0; ii < trackinfo.size(); ii++ )
|
||||
{
|
||||
fprintf( aFile, "TRACK TRACK%d %g\n", trackinfo[ii],
|
||||
trackinfo[ii] / SCALE_FACTOR );
|
||||
}
|
||||
for( auto size : trackinfo )
|
||||
fprintf( aFile, "TRACK TRACK%d %g\n", size, size / SCALE_FACTOR );
|
||||
|
||||
fputs( "$ENDTRACKS\n\n", aFile );
|
||||
}
|
||||
|
@ -961,7 +961,7 @@ static void export_vrml_via( MODEL_VRML& aModel, BOARD* aPcb, const VIA* aVia )
|
||||
|
||||
static void export_vrml_tracks( MODEL_VRML& aModel, BOARD* pcb )
|
||||
{
|
||||
for( TRACK* track = pcb->m_Track; track; track = track->Next() )
|
||||
for( auto track : pcb->Tracks() )
|
||||
{
|
||||
if( track->Type() == PCB_VIA_T )
|
||||
{
|
||||
|
@ -82,8 +82,12 @@ void GENDRILL_WRITER_BASE::buildHolesList( DRILL_LAYER_PAIR aLayerPair,
|
||||
// build hole list for vias
|
||||
if( ! aGenerateNPTH_list ) // vias are always plated !
|
||||
{
|
||||
for( VIA* via = GetFirstVia( m_pcb->m_Track ); via; via = GetFirstVia( via->Next() ) )
|
||||
for( auto track : m_pcb->Tracks() )
|
||||
{
|
||||
if( track->Type() != PCB_VIA_T )
|
||||
continue;
|
||||
|
||||
auto via = static_cast<VIA*>( track );
|
||||
int hole_sz = via->GetDrillValue();
|
||||
|
||||
if( hole_sz == 0 ) // Should not occur.
|
||||
|
@ -602,7 +602,7 @@ void PCB_IO::formatGeneral( BOARD* aBoard, int aNestLevel ) const
|
||||
FormatInternalUnits( dsnSettings.GetBoardThickness() ).c_str() );
|
||||
|
||||
m_out->Print( aNestLevel+1, "(drawings %zu)\n", aBoard->Drawings().size() );
|
||||
m_out->Print( aNestLevel+1, "(tracks %d)\n", aBoard->GetNumSegmTrack() );
|
||||
m_out->Print( aNestLevel + 1, "(tracks %zu)\n", aBoard->Tracks().size() );
|
||||
m_out->Print( aNestLevel + 1, "(modules %zu)\n", aBoard->Modules().size() );
|
||||
m_out->Print( aNestLevel+1, "(nets %d)\n", m_mapping->GetSize() );
|
||||
m_out->Print( aNestLevel, ")\n\n" );
|
||||
@ -733,10 +733,10 @@ void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const
|
||||
// Do not save MARKER_PCBs, they can be regenerated easily.
|
||||
|
||||
// Save the tracks and vias.
|
||||
for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
|
||||
for( auto track : aBoard->Tracks() )
|
||||
Format( track, aNestLevel );
|
||||
|
||||
if( aBoard->m_Track.GetCount() )
|
||||
if( aBoard->Tracks().size() )
|
||||
m_out->Print( 0, "\n" );
|
||||
|
||||
/// @todo Add warning here that the old segment filed zones are no longer supported and
|
||||
|
@ -554,15 +554,6 @@ private:
|
||||
*/
|
||||
void buildListOfNets();
|
||||
|
||||
/**
|
||||
* Function buildPadsFullList
|
||||
* creates the pad list, and initializes:
|
||||
* m_Pads (list of pads)
|
||||
* and clear for all pads in list the m_SubRatsnest member;
|
||||
* clear m_Pcb->m_FullRatsnest
|
||||
*/
|
||||
void buildPadsFullList();
|
||||
|
||||
/**
|
||||
* Function getFreeNetCode
|
||||
* returns the first available net code that is not used by any other net.
|
||||
@ -586,6 +577,4 @@ private:
|
||||
#define START_ON_TRACK 0x40
|
||||
#define END_ON_TRACK 0x80
|
||||
|
||||
|
||||
|
||||
#endif // CLASS_NETINFO_
|
||||
|
@ -119,7 +119,7 @@ void NETINFO_ITEM::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_I
|
||||
|
||||
count = 0;
|
||||
|
||||
for( const TRACK *track = board->m_Track; track != NULL; track = track->Next() )
|
||||
for( auto track : board->Tracks() )
|
||||
{
|
||||
if( track->Type() == PCB_VIA_T )
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user