fix VIA::IsOnLayer()

This commit is contained in:
Dick Hollenbeck 2014-06-29 23:40:16 -05:00
parent 3aa880dedb
commit 575f13d887
6 changed files with 121 additions and 109 deletions

View File

@ -1401,26 +1401,28 @@ int BOARD::SetAreasNetCodesFromNetNames()
for( int ii = 0; ii < GetAreaCount(); ii++ )
{
if( !GetArea( ii )->IsOnCopperLayer() )
ZONE_CONTAINER* it = GetArea( ii );
if( !it->IsOnCopperLayer() )
{
GetArea( ii )->SetNetCode( NETINFO_LIST::UNCONNECTED );
it->SetNetCode( NETINFO_LIST::UNCONNECTED );
continue;
}
if( GetArea( ii )->GetNetCode() != 0 ) // i.e. if this zone is connected to a net
if( it->GetNetCode() != 0 ) // i.e. if this zone is connected to a net
{
const NETINFO_ITEM* net = GetArea( ii )->GetNet();
const NETINFO_ITEM* net = it->GetNet();
if( net )
{
GetArea( ii )->SetNetCode( net->GetNet() );
it->SetNetCode( net->GetNet() );
}
else
{
error_count++;
// keep Net Name and set m_NetCode to -1 : error flag.
GetArea( ii )->SetNetCode( -1 );
it->SetNetCode( -1 );
}
}
}

View File

@ -377,7 +377,9 @@ bool VIA::IsOnLayer( LAYER_ID layer_number ) const
LayerPair( &top_layer, &bottom_layer );
if( bottom_layer <= layer_number && layer_number <= top_layer )
wxASSERT( top_layer <= bottom_layer );
if( top_layer <= layer_number && layer_number <= bottom_layer )
return true;
else
return false;

View File

@ -861,22 +861,19 @@ void PCB_BASE_FRAME::TestNetConnection( wxDC* aDC, int aNetCode )
*/
void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
{
TRACK* curr_track;
// Build the net info list
GetBoard()->BuildListOfNets();
// Reset variables and flags used in computation
curr_track = m_Pcb->m_Track;
for( ; curr_track != NULL; curr_track = curr_track->Next() )
for( TRACK* t = m_Pcb->m_Track; t; t = t->Next() )
{
curr_track->m_TracksConnected.clear();
curr_track->m_PadsConnected.clear();
curr_track->start = NULL;
curr_track->end = NULL;
curr_track->SetState( BUSY | IN_EDIT | BEGIN_ONPAD | END_ONPAD, false );
curr_track->SetZoneSubNet( 0 );
curr_track->SetNetCode( NETINFO_LIST::UNCONNECTED );
t->m_TracksConnected.clear();
t->m_PadsConnected.clear();
t->start = NULL;
t->end = NULL;
t->SetState( BUSY | IN_EDIT | BEGIN_ONPAD | END_ONPAD, false );
t->SetZoneSubNet( 0 );
t->SetNetCode( NETINFO_LIST::UNCONNECTED );
}
// If no pad, reset pointers and netcode, and do nothing else
@ -890,21 +887,19 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
// First pass: build connections between track segments and pads.
connections.SearchTracksConnectedToPads();
/* For tracks connected to at least one pad,
* set the track net code to the pad netcode
*/
curr_track = m_Pcb->m_Track;
for( ; curr_track != NULL; curr_track = curr_track->Next() )
// For tracks connected to at least one pad,
// set the track net code to the pad netcode
for( TRACK* t = m_Pcb->m_Track; t; t = t->Next() )
{
if( curr_track->m_PadsConnected.size() )
curr_track->SetNetCode( curr_track->m_PadsConnected[0]->GetNetCode() );
if( t->m_PadsConnected.size() )
t->SetNetCode( t->m_PadsConnected[0]->GetNetCode() );
}
// Pass 2: build connections between track ends
for( curr_track = m_Pcb->m_Track; curr_track != NULL; curr_track = curr_track->Next() )
for( TRACK* t = m_Pcb->m_Track; t; t = t->Next() )
{
connections.SearchConnectedTracks( curr_track );
connections.GetConnectedTracks( curr_track );
connections.SearchConnectedTracks( t );
connections.GetConnectedTracks( t );
}
// Propagate net codes from a segment to other connected segments
@ -915,21 +910,21 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
{
new_pass_request = false;
for( curr_track = m_Pcb->m_Track; curr_track; curr_track = curr_track->Next() )
for( TRACK* t = m_Pcb->m_Track; t; t = t->Next() )
{
int netcode = curr_track->GetNetCode();
int netcode = t->GetNetCode();
if( netcode == 0 )
{
// try to find a connected item having a netcode
for( unsigned kk = 0; kk < curr_track->m_TracksConnected.size(); kk++ )
for( unsigned kk = 0; kk < t->m_TracksConnected.size(); kk++ )
{
int altnetcode = curr_track->m_TracksConnected[kk]->GetNetCode();
int altnetcode = t->m_TracksConnected[kk]->GetNetCode();
if( altnetcode )
{
new_pass_request = true;
netcode = altnetcode;
curr_track->SetNetCode(netcode);
t->SetNetCode(netcode);
break;
}
}
@ -938,12 +933,12 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
if( netcode ) // this track has a netcode
{
// propagate this netcode to connected tracks having no netcode
for( unsigned kk = 0; kk < curr_track->m_TracksConnected.size(); kk++ )
for( unsigned kk = 0; kk < t->m_TracksConnected.size(); kk++ )
{
int altnetcode = curr_track->m_TracksConnected[kk]->GetNetCode();
int altnetcode = t->m_TracksConnected[kk]->GetNetCode();
if( altnetcode == 0 )
{
curr_track->m_TracksConnected[kk]->SetNetCode(netcode);
t->m_TracksConnected[kk]->SetNetCode(netcode);
new_pass_request = true;
}
}

View File

@ -2734,68 +2734,65 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
break;
case T_polygon:
{
std::vector< wxPoint > corners;
NeedLEFT();
token = NextTok();
if( token != T_pts )
Expecting( T_pts );
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
corners.push_back( parseXY() );
}
NeedRIGHT();
zone->AddPolygon( corners );
}
break;
case T_filled_polygon:
{
// "(filled_polygon (pts"
NeedLEFT();
token = NextTok();
if( token != T_pts )
Expecting( T_pts );
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
pts.Append( CPolyPt( parseXY() ) );
}
NeedRIGHT();
pts.CloseLastContour();
}
break;
case T_fill_segments:
{
std::vector< SEGMENT > segs;
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
Expecting( T_LEFT );
std::vector< wxPoint > corners;
NeedLEFT();
token = NextTok();
if( token != T_pts )
Expecting( T_pts );
SEGMENT segment( parseXY(), parseXY() );
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
corners.push_back( parseXY() );
}
NeedRIGHT();
segs.push_back( segment );
zone->AddPolygon( corners );
}
break;
zone->AddFillSegments( segs );
}
case T_filled_polygon:
{
// "(filled_polygon (pts"
NeedLEFT();
token = NextTok();
if( token != T_pts )
Expecting( T_pts );
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
pts.Append( CPolyPt( parseXY() ) );
}
NeedRIGHT();
pts.CloseLastContour();
}
break;
case T_fill_segments:
{
std::vector< SEGMENT > segs;
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
Expecting( T_LEFT );
token = NextTok();
if( token != T_pts )
Expecting( T_pts );
SEGMENT segment( parseXY(), parseXY() );
NeedRIGHT();
segs.push_back( segment );
}
zone->AddFillSegments( segs );
}
break;
default:

View File

@ -790,6 +790,7 @@ static bool sort_by_distance( const wxPoint& ref, const wxPoint& compare )
return lengthref < lengthcmp;
}
static bool sort_by_point( const wxPoint& ref, const wxPoint& compare )
{
if( ref.x == compare.x )

View File

@ -71,15 +71,15 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode )
// clear .m_ZoneSubnet parameter for pads
for( MODULE* module = m_Modules; module; module = module->Next() )
{
for( D_PAD* pad = module->Pads(); pad != NULL; pad = pad->Next() )
if( (aNetcode < 0) || ( aNetcode == pad->GetNetCode() ) )
for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
if( aNetcode < 0 || aNetcode == pad->GetNetCode() )
pad->SetZoneSubNet( 0 );
}
// clear .m_ZoneSubnet parameter for tracks and vias
for( TRACK* track = m_Track; track; track = track->Next() )
{
if( (aNetcode < 0) || ( aNetcode == track->GetNetCode() ) )
if( aNetcode < 0 || aNetcode == track->GetNetCode() )
track->SetZoneSubNet( 0 );
}
@ -88,40 +88,50 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode )
// Build zones candidates list
std::vector<ZONE_CONTAINER*> zones_candidates;
zones_candidates.reserve( GetAreaCount() );
for( int index = 0; index < GetAreaCount(); index++ )
{
ZONE_CONTAINER* curr_zone = GetArea( index );
if( !curr_zone->IsOnCopperLayer() )
ZONE_CONTAINER* zone = GetArea( index );
if( !zone->IsOnCopperLayer() )
continue;
if( (aNetcode >= 0) && ( aNetcode != curr_zone->GetNetCode() ) )
if( aNetcode >= 0 && aNetcode != zone->GetNetCode() )
continue;
if( curr_zone->GetFilledPolysList().GetCornersCount() == 0 )
if( zone->GetFilledPolysList().GetCornersCount() == 0 )
continue;
zones_candidates.push_back(curr_zone);
zones_candidates.push_back( zone );
}
// sort them by netcode then vertices count.
// For a given net, examine the smaller zones first slightly speed up calculation
// (25% faster)
// this is only noticeable with very large boards and depends on board zones topology
// This is due to the fact some items are connected by small zones ares,
// before examining large zones areas and these items are not tested after a connection is found
sort(zones_candidates.begin(), zones_candidates.end(), sort_areas );
sort( zones_candidates.begin(), zones_candidates.end(), sort_areas );
int oldnetcode = -1;
for( unsigned idx = 0; idx < zones_candidates.size(); idx++ )
{
ZONE_CONTAINER* curr_zone = zones_candidates[idx];
ZONE_CONTAINER* zone = zones_candidates[idx];
int netcode = curr_zone->GetNetCode();
int netcode = zone->GetNetCode();
// Build a list of candidates connected to the net:
// At this point, layers are not considered, because areas on different layers can
// be connected by a via or a pad.
// (because zones are sorted by netcode, there is made only once per net)
NETINFO_ITEM* net = FindNet( netcode );
wxASSERT( net );
if( net == NULL )
continue;
if( oldnetcode != netcode )
{
oldnetcode = netcode;
@ -129,38 +139,43 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode )
// Build the list of pads candidates connected to the net:
candidates.reserve( net->m_PadInNetList.size() );
for( unsigned ii = 0; ii < net->m_PadInNetList.size(); ii++ )
candidates.push_back( net->m_PadInNetList[ii] );
// Build the list of track candidates connected to the net:
TRACK* track = m_Track.GetFirst()->GetStartNetCode( netcode );
for( ; track; track = track->Next() )
{
if( track->GetNetCode() != netcode )
break;
candidates.push_back( track );
}
}
// test if a candidate is inside a filled area of this zone
unsigned indexstart = 0, indexend;
const CPOLYGONS_LIST& polysList = curr_zone->GetFilledPolysList();
const CPOLYGONS_LIST& polysList = zone->GetFilledPolysList();
for( indexend = 0; indexend < polysList.GetCornersCount(); indexend++ )
{
// end of a filled sub-area found
if( polysList.IsEndContour( indexend ) )
{
subnet++;
EDA_RECT bbox = curr_zone->CalculateSubAreaBoundaryBox( indexstart, indexend );
EDA_RECT bbox = zone->CalculateSubAreaBoundaryBox( indexstart, indexend );
for( unsigned ic = 0; ic < candidates.size(); ic++ )
{ // test if this area is connected to a board item:
{
// test if this area is connected to a board item:
BOARD_CONNECTED_ITEM* item = candidates[ic];
if( item->GetZoneSubNet() == subnet ) // Already merged
continue;
if( !item->IsOnLayer( curr_zone->GetLayer() ) )
if( !item->IsOnLayer( zone->GetLayer() ) )
continue;
wxPoint pos1, pos2;
@ -236,7 +251,7 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode )
// End test candidates for the current filled area
indexstart = indexend + 1; // prepare test next area, starting at indexend+1
// (if exists). End read one area in
// curr_zone->m_FilledPolysList
// zone->m_FilledPolysList
}
} // End read all segments in zone
} // End read all zones candidates
@ -253,15 +268,15 @@ void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb )
{
for( int index = 0; index < aPcb->GetAreaCount(); index++ )
{
ZONE_CONTAINER* curr_zone = aPcb->GetArea( index );
ZONE_CONTAINER* zone = aPcb->GetArea( index );
if ( ! curr_zone->IsOnCopperLayer() )
if ( ! zone->IsOnCopperLayer() )
continue;
if ( curr_zone->GetNetCode() <= 0 )
if ( zone->GetNetCode() <= 0 )
continue;
Merge_SubNets_Connected_By_CopperAreas( aPcb, curr_zone->GetNetCode() );
Merge_SubNets_Connected_By_CopperAreas( aPcb, zone->GetNetCode() );
}
}
@ -285,9 +300,9 @@ void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode )
for( int index = 0; index < aPcb->GetAreaCount(); index++ )
{
ZONE_CONTAINER* curr_zone = aPcb->GetArea( index );
ZONE_CONTAINER* zone = aPcb->GetArea( index );
if( aNetcode == curr_zone->GetNetCode() )
if( aNetcode == zone->GetNetCode() )
{
found = true;
break;