diff --git a/pcbnew/connect.cpp b/pcbnew/connect.cpp index ff9242c619..5b5b06497e 100644 --- a/pcbnew/connect.cpp +++ b/pcbnew/connect.cpp @@ -245,12 +245,13 @@ static bool sortConnectedPointByXthenYCoordinates( const CONNECTED_POINT & aRef, return aRef.GetPoint().x < aTst.GetPoint().x; } -void CONNECTIONS::BuildTracksCandidatesList( TRACK * aBegin, TRACK * aEnd) +void CONNECTIONS::BuildTracksCandidatesList( TRACK* aBegin, TRACK* aEnd) { m_candidates.clear(); m_firstTrack = m_lastTrack = aBegin; unsigned ii = 0; + // Count candidates ( i.e. end points ) for( const TRACK* track = aBegin; track; track = track->Next() ) { @@ -260,14 +261,17 @@ void CONNECTIONS::BuildTracksCandidatesList( TRACK * aBegin, TRACK * aEnd) ii += 2; m_lastTrack = track; + if( track == aEnd ) break; } + // Build candidate list m_candidates.reserve( ii ); for( TRACK* track = aBegin; track; track = track->Next() ) { - CONNECTED_POINT candidate( track, track->GetStart()); + CONNECTED_POINT candidate( track, track->GetStart() ); + m_candidates.push_back( candidate ); if( track->Type() != PCB_VIA_T ) { @@ -285,6 +289,7 @@ void CONNECTIONS::BuildTracksCandidatesList( TRACK * aBegin, TRACK * aEnd) sort( m_candidates.begin(), m_candidates.end(), sortConnectedPointByXthenYCoordinates ); } + /* Populates .m_connected with tracks/vias connected to aTrack * param aTrack = track or via to use as reference * For calculation time reason, an exhaustive search cannot be made @@ -294,7 +299,7 @@ void CONNECTIONS::BuildTracksCandidatesList( TRACK * aBegin, TRACK * aEnd) * because with this constraint we can make a fast search in track list * m_candidates is expected to be populated by the track candidates ends list */ -int CONNECTIONS::SearchConnectedTracks( const TRACK * aTrack ) +int CONNECTIONS::SearchConnectedTracks( const TRACK* aTrack ) { int count = 0; m_connected.clear(); @@ -308,7 +313,9 @@ int CONNECTIONS::SearchConnectedTracks( const TRACK * aTrack ) int dist_max = aTrack->GetWidth() / 2; static std::vector tracks_candidates; #endif + wxPoint position = aTrack->GetStart(); + for( int kk = 0; kk < 2; kk++ ) { #ifndef USE_EXTENDED_SEARCH @@ -321,8 +328,10 @@ int CONNECTIONS::SearchConnectedTracks( const TRACK * aTrack ) { if( m_candidates[ii].GetTrack() == aTrack ) continue; + if( m_candidates[ii].GetPoint() != position ) break; + if( ( m_candidates[ii].GetTrack()->GetLayerSet() & layerMask ).any() ) m_connected.push_back( m_candidates[ii].GetTrack() ); } @@ -332,18 +341,23 @@ int CONNECTIONS::SearchConnectedTracks( const TRACK * aTrack ) { if( m_candidates[ii].GetTrack() == aTrack ) continue; + if( m_candidates[ii].GetPoint() != position ) break; + if( ( m_candidates[ii].GetTrack()->GetLayerSet() & layerMask ).any() ) m_connected.push_back( m_candidates[ii].GetTrack() ); } } #else + tracks_candidates.clear(); + CollectItemsNearTo( tracks_candidates, position, dist_max ); - for ( unsigned ii = 0; ii < tracks_candidates.size(); ii ++ ) + + for( unsigned ii = 0; ii < tracks_candidates.size(); ii++ ) { - TRACK * ctrack = tracks_candidates[ii]->GetTrack(); + TRACK* ctrack = tracks_candidates[ii]->GetTrack(); if( !( ctrack->GetLayerSet() & layerMask ).any() ) continue; @@ -354,6 +368,7 @@ int CONNECTIONS::SearchConnectedTracks( const TRACK * aTrack ) // We have a good candidate: calculate the actual distance // between ends, which should be <= dist max. wxPoint delta = tracks_candidates[ii]->GetPoint() - position; + int dist = KiROUND( EuclideanNorm( delta ) ); if( dist > dist_max ) diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index c5d9a36492..db912bfb7b 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -734,6 +734,7 @@ void PCB_PARSER::parseLayer( LAYER* aLayer ) throw( IO_ERROR, PARSE_ERROR ) } + void PCB_PARSER::parseLayers() throw( IO_ERROR, PARSE_ERROR ) { wxCHECK_RET( CurTok() == T_layers, @@ -752,50 +753,55 @@ void PCB_PARSER::parseLayers() throw( IO_ERROR, PARSE_ERROR ) parseLayer( &layer ); - if( layer.m_type != LT_UNDEFINED ) // it's a copper layer - { - cu.push_back( layer ); + if( layer.m_type == LT_UNDEFINED ) // it's a non-copper layer + break; - //DBG( printf( "cop m_visible:%s\n", cu.back().m_visible ? "true" : "false" );) + cu.push_back( layer ); // it's copper + } + + // All Cu layers are parsed, but not the non-cu layers here. + + // The original *.kicad_pcb file format and the inverted + // Cu stack format both have all the Cu layers first, so use this + // trick to handle either. The layer number in the (layers ..) + // s-expression element are ignored. + if( cu.size() ) + { + // Rework the layer numbers, which changed when the Cu stack + // was flipped. So we instead use position in the list. + cu[cu.size()-1].m_number = B_Cu; + + for( unsigned i=0; i < cu.size()-1; ++i ) + { + cu[i].m_number = i; } - else // all non-copper are fixed names, simply look up LAYER_ID. + + for( std::vector::const_iterator it = cu.begin(); itm_number ); - for( unsigned i=0; i < cu.size()-1; ++i ) - { - cu[i].m_number = i; - } + if( it->m_visible ) + visibleLayers.set( it->m_number ); - for( std::vector::const_iterator it = cu.begin(); itm_number ); + m_board->SetLayer( LAYER_ID( it->m_number ), *it ); - if( it->m_visible ) - visibleLayers.set( it->m_number ); + UTF8 name = it->m_name; - m_board->SetLayer( LAYER_ID( it->m_number ), *it ); + m_layerIndices[ name ] = LAYER_ID( it->m_number ); + m_layerMasks[ name ] = LSET( LAYER_ID( it->m_number ) ); + } - UTF8 name = it->m_name; + copperLayerCount = cu.size(); + } - m_layerIndices[ name ] = LAYER_ID( it->m_number ); - m_layerMasks[ name ] = LSET( LAYER_ID( it->m_number ) ); - } + if( token != T_RIGHT ) + { + // read any non-copper layers + for( token = NextTok(); token != T_RIGHT; token = NextTok() ) + { + LAYER layer; - copperLayerCount = cu.size(); - - cu.clear(); // this marks the list as "one time processed". - } + parseLayer( &layer ); LAYER_ID_MAP::const_iterator it = m_layerIndices.find( UTF8( layer.m_name ) );