Loading common/gal/opengl/cached_container.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -362,7 +362,7 @@ void CACHED_CONTAINER::mergeFreeChunks() if( m_freeChunks.size() <= 1 ) // There are no chunks that can be merged if( m_freeChunks.size() <= 1 ) // There are no chunks that can be merged return; return; #ifdef CACHED_CONTAINER_TEST > 0 #if CACHED_CONTAINER_TEST > 0 prof_counter totalTime; prof_counter totalTime; prof_start( &totalTime, false ); prof_start( &totalTime, false ); #endif #endif Loading Loading @@ -406,7 +406,7 @@ void CACHED_CONTAINER::mergeFreeChunks() // Add the last one // Add the last one m_freeChunks.insert( std::make_pair( size, offset ) ); m_freeChunks.insert( std::make_pair( size, offset ) ); #ifdef CACHED_CONTAINER_TEST > 0 #if CACHED_CONTAINER_TEST > 0 prof_end( &totalTime ); prof_end( &totalTime ); wxLogDebug( wxT( "Merged free chunks / %.1f ms" ), (double) totalTime.value / 1000.0 ); wxLogDebug( wxT( "Merged free chunks / %.1f ms" ), (double) totalTime.value / 1000.0 ); Loading common/view/view_item.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -69,7 +69,7 @@ void VIEW_ITEM::ViewRelease() void VIEW_ITEM::getLayers( int* aLayers, int& aCount ) const void VIEW_ITEM::getLayers( int* aLayers, int& aCount ) const { { int* layersPtr = aLayers; int* layersPtr = aLayers; for( int i = 0; i < m_layers.size(); ++i ) for( unsigned int i = 0; i < m_layers.size(); ++i ) { { if( m_layers[i] ) if( m_layers[i] ) *layersPtr++ = i; *layersPtr++ = i; Loading pcbnew/router/CMakeLists.txt +43 −42 Original line number Original line Diff line number Diff line Loading @@ -48,3 +48,4 @@ set(PCBNEW_PNS_SRCS ) ) add_library( pnsrouter STATIC ${PCBNEW_PNS_SRCS} ) add_library( pnsrouter STATIC ${PCBNEW_PNS_SRCS} ) pcbnew/router/direction.h +298 −261 Original line number Original line Diff line number Diff line Loading @@ -31,7 +31,6 @@ class DIRECTION_45 class DIRECTION_45 { { public: public: /** /** Loading @@ -39,7 +38,8 @@ public: * Represents available directions - there are 8 of them, as on a rectilinear map (north = up) + * Represents available directions - there are 8 of them, as on a rectilinear map (north = up) + * an extra undefined direction, reserved for traces that don't respect 45-degree routing regime. * an extra undefined direction, reserved for traces that don't respect 45-degree routing regime. */ */ enum Directions { enum Directions { N = 0, N = 0, NE = 1, NE = 1, E = 2, E = 2, Loading @@ -55,11 +55,12 @@ public: * Enum AngleType * Enum AngleType * Represents kind of angle formed by vectors heading in two DIRECTION_45s. * Represents kind of angle formed by vectors heading in two DIRECTION_45s. */ */ enum AngleType { enum AngleType ANG_OBTUSE = 0x1, { ANG_RIGHT = 0x2, ANG_OBTUSE = 0x01, ANG_ACUTE = 0x4, ANG_RIGHT = 0x02, ANG_STRAIGHT = 0x8, ANG_ACUTE = 0x04, ANG_STRAIGHT = 0x08, ANG_HALF_FULL = 0x10, ANG_HALF_FULL = 0x10, ANG_UNDEFINED = 0x20 ANG_UNDEFINED = 0x20 }; }; Loading Loading @@ -93,16 +94,35 @@ public: { { switch( m_dir ) switch( m_dir ) { { case N : return "north"; case N: case NE : return "north-east"; return "north"; case E : return "east"; case SE : return "south-east"; case NE: case S : return "south"; return "north-east"; case SW : return "south-west"; case W : return "west"; case E: case NW : return "north-west"; return "east"; case UNDEFINED : return "undefined"; default: return "<Error>"; case SE: return "south-east"; case S: return "south"; case SW: return "south-west"; case W: return "west"; case NW: return "north-west"; case UNDEFINED: return "undefined"; default: return "<Error>"; } } } } Loading @@ -115,6 +135,7 @@ public: { { if( m_dir == UNDEFINED ) if( m_dir == UNDEFINED ) return UNDEFINED; return UNDEFINED; const Directions OppositeMap[] = { S, SW, W, NW, N, NE, E, SE }; const Directions OppositeMap[] = { S, SW, W, NW, N, NE, E, SE }; return OppositeMap[m_dir]; return OppositeMap[m_dir]; } } Loading Loading @@ -172,7 +193,9 @@ public: * @param aStartDiagonal whether the first segment has to be diagonal * @param aStartDiagonal whether the first segment has to be diagonal * @return the trace * @return the trace */ */ const SHAPE_LINE_CHAIN BuildInitialTrace(const VECTOR2I& aP0, const VECTOR2I &aP1, bool aStartDiagonal = false) const const SHAPE_LINE_CHAIN BuildInitialTrace( const VECTOR2I& aP0, const VECTOR2I& aP1, bool aStartDiagonal = false ) const { { int w = abs( aP1.x - aP0.x ); int w = abs( aP1.x - aP0.x ); int h = abs( aP1.y - aP0.y ); int h = abs( aP1.y - aP0.y ); Loading @@ -186,7 +209,9 @@ public: { { mp0 = VECTOR2I( (w - h) * sw, 0 ); // direction: E mp0 = VECTOR2I( (w - h) * sw, 0 ); // direction: E mp1 = VECTOR2I( h * sw, h * sh ); // direction: NE mp1 = VECTOR2I( h * sw, h * sh ); // direction: NE } else { } else { mp0 = VECTOR2I( 0, sh * (h - w) ); // direction: N mp0 = VECTOR2I( 0, sh * (h - w) ); // direction: N mp1 = VECTOR2I( sw * w, sh * w ); // direction: NE mp1 = VECTOR2I( sw * w, sh * w ); // direction: NE } } Loading @@ -201,6 +226,7 @@ public: SHAPE_LINE_CHAIN pl; SHAPE_LINE_CHAIN pl; pl.Append( aP0 ); pl.Append( aP0 ); if( start_diagonal ) if( start_diagonal ) pl.Append( aP0 + mp1 ); pl.Append( aP0 + mp1 ); else else Loading @@ -224,15 +250,20 @@ public: const DIRECTION_45 Right() const const DIRECTION_45 Right() const { { DIRECTION_45 r; DIRECTION_45 r; r.m_dir = (Directions) (m_dir + 1); r.m_dir = (Directions) (m_dir + 1); if( r.m_dir == NW ) if( r.m_dir == NW ) r.m_dir = N; r.m_dir = N; return r; return r; } } private: private: template <typename T> int sign(T val) const { template <typename T> int sign( T val ) const { return (T( 0 ) < val) - ( val < T( 0 ) ); return (T( 0 ) < val) - ( val < T( 0 ) ); } } Loading @@ -245,12 +276,15 @@ private: void construct( const VECTOR2I& aVec ) void construct( const VECTOR2I& aVec ) { { m_dir = UNDEFINED; m_dir = UNDEFINED; if( aVec.x == 0 && aVec.y == 0 ) if( aVec.x == 0 && aVec.y == 0 ) return; return; double mag = 360.0 - ( 180.0 / M_PI * atan2( (double) aVec.y, (double) aVec.x ) ) + 90.0; double mag = 360.0 - ( 180.0 / M_PI * atan2( (double) aVec.y, (double) aVec.x ) ) + 90.0; if( mag >= 360.0 ) if( mag >= 360.0 ) mag -= 360.0; mag -= 360.0; if( mag < 0.0 ) if( mag < 0.0 ) mag += 360.0; mag += 360.0; Loading @@ -258,10 +292,12 @@ private: if( m_dir >= 8 ) if( m_dir >= 8 ) m_dir = (Directions)( m_dir - 8 ); m_dir = (Directions)( m_dir - 8 ); if( m_dir < 0 ) if( m_dir < 0 ) m_dir = (Directions)( m_dir + 8 ); m_dir = (Directions)( m_dir + 8 ); return; return; if( aVec.y < 0 ) if( aVec.y < 0 ) { { if( aVec.x > 0 ) if( aVec.x > 0 ) Loading Loading @@ -293,3 +329,4 @@ private: }; }; #endif // __DIRECTION_H #endif // __DIRECTION_H pcbnew/router/pns_index.h +181 −159 Original line number Original line Diff line number Diff line Loading @@ -37,10 +37,9 @@ * overlap and improving search time. * overlap and improving search time. **/ **/ class PNS_INDEX { class PNS_INDEX { public: public: typedef std::list<PNS_ITEM*> NetItemsList; typedef std::list<PNS_ITEM*> NetItemsList; typedef SHAPE_INDEX<PNS_ITEM*> ItemShapeIndex; typedef SHAPE_INDEX<PNS_ITEM*> ItemShapeIndex; typedef boost::unordered_set<PNS_ITEM*> ItemSet; typedef boost::unordered_set<PNS_ITEM*> ItemSet; Loading @@ -54,6 +53,7 @@ public: template<class Visitor> template<class Visitor> int Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& v ); int Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& v ); template<class Visitor> template<class Visitor> int Query( const SHAPE* aShape, int aMinDistance, Visitor& v ); int Query( const SHAPE* aShape, int aMinDistance, Visitor& v ); Loading @@ -64,15 +64,14 @@ public: ItemSet::iterator begin() { return m_allItems.begin(); } ItemSet::iterator begin() { return m_allItems.begin(); } ItemSet::iterator end() { return m_allItems.end(); } ItemSet::iterator end() { return m_allItems.end(); } bool Contains ( PNS_ITEM *aItem ) const { bool Contains( PNS_ITEM* aItem ) const { return m_allItems.find( aItem ) != m_allItems.end(); return m_allItems.find( aItem ) != m_allItems.end(); } } int Size() const { return m_allItems.size(); } int Size() const { return m_allItems.size(); } private: private: static const int MaxSubIndices = 64; static const int MaxSubIndices = 64; static const int SI_Multilayer = 2; static const int SI_Multilayer = 2; static const int SI_SegDiagonal = 0; static const int SI_SegDiagonal = 0; Loading @@ -91,11 +90,13 @@ private: ItemSet m_allItems; ItemSet m_allItems; }; }; PNS_INDEX::PNS_INDEX() PNS_INDEX::PNS_INDEX() { { memset( m_subIndices, 0, sizeof( m_subIndices ) ); memset( m_subIndices, 0, sizeof( m_subIndices ) ); } } PNS_INDEX::ItemShapeIndex* PNS_INDEX::getSubindex( const PNS_ITEM* aItem ) PNS_INDEX::ItemShapeIndex* PNS_INDEX::getSubindex( const PNS_ITEM* aItem ) { { int idx_n = -1; int idx_n = -1; Loading @@ -107,6 +108,7 @@ PNS_INDEX::ItemShapeIndex *PNS_INDEX::getSubindex(const PNS_ITEM *aItem ) case PNS_ITEM::VIA: case PNS_ITEM::VIA: idx_n = SI_Multilayer; idx_n = SI_Multilayer; break; break; case PNS_ITEM::SOLID: case PNS_ITEM::SOLID: { { if( l.IsMultilayer() ) if( l.IsMultilayer() ) Loading @@ -115,15 +117,19 @@ PNS_INDEX::ItemShapeIndex *PNS_INDEX::getSubindex(const PNS_ITEM *aItem ) idx_n = SI_PadsTop; idx_n = SI_PadsTop; else if( l.Start() == 15 ) else if( l.Start() == 15 ) idx_n = SI_PadsBottom; idx_n = SI_PadsBottom; break; break; } } case PNS_ITEM::SEGMENT: case PNS_ITEM::SEGMENT: case PNS_ITEM::LINE: case PNS_ITEM::LINE: idx_n = SI_Traces + 2 * l.Start() + SI_SegStraight; idx_n = SI_Traces + 2 * l.Start() + SI_SegStraight; break; break; default: default: break; break; } } assert( idx_n >= 0 && idx_n < MaxSubIndices ); assert( idx_n >= 0 && idx_n < MaxSubIndices ); if( !m_subIndices[idx_n] ) if( !m_subIndices[idx_n] ) Loading @@ -132,23 +138,26 @@ PNS_INDEX::ItemShapeIndex *PNS_INDEX::getSubindex(const PNS_ITEM *aItem ) return m_subIndices[idx_n]; return m_subIndices[idx_n]; } } void PNS_INDEX::Add( PNS_ITEM* aItem ) void PNS_INDEX::Add( PNS_ITEM* aItem ) { { ItemShapeIndex* idx = getSubindex( aItem ); ItemShapeIndex* idx = getSubindex( aItem ); idx->Add( aItem ); idx->Add( aItem ); m_allItems.insert( aItem ); m_allItems.insert( aItem ); int net = aItem->GetNet(); int net = aItem->GetNet(); if( net >= 0 ) if( net >= 0 ) { { m_netMap[net].push_back( aItem ); m_netMap[net].push_back( aItem ); } } } } void PNS_INDEX::Remove( PNS_ITEM* aItem ) void PNS_INDEX::Remove( PNS_ITEM* aItem ) { { ItemShapeIndex* idx = getSubindex( aItem ); ItemShapeIndex* idx = getSubindex( aItem ); idx->Remove( aItem ); idx->Remove( aItem ); m_allItems.erase( aItem ); m_allItems.erase( aItem ); Loading @@ -158,27 +167,30 @@ void PNS_INDEX::Remove( PNS_ITEM *aItem ) m_netMap[net].remove( aItem ); m_netMap[net].remove( aItem ); } } void PNS_INDEX::Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem ) void PNS_INDEX::Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem ) { { Remove( aOldItem ); Remove( aOldItem ); Add( aNewItem ); Add( aNewItem ); } } template<class Visitor> template<class Visitor> int PNS_INDEX::querySingle( int index, const SHAPE* aShape, int aMinDistance, Visitor& v ) int PNS_INDEX::querySingle( int index, const SHAPE* aShape, int aMinDistance, Visitor& v ) { { if( !m_subIndices[index] ) if( !m_subIndices[index] ) return 0; return 0; return m_subIndices[index]->Query( aShape, aMinDistance, v, false ); return m_subIndices[index]->Query( aShape, aMinDistance, v, false ); } } template<class Visitor> template<class Visitor> int PNS_INDEX::Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& v ) int PNS_INDEX::Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& v ) { { const SHAPE* shape = aItem->GetShape(); const SHAPE* shape = aItem->GetShape(); int total = 0; int total = 0; total += querySingle( SI_Multilayer, shape, aMinDistance, v ); total += querySingle( SI_Multilayer, shape, aMinDistance, v ); const PNS_LAYERSET layers = aItem->GetLayers(); const PNS_LAYERSET layers = aItem->GetLayers(); Loading @@ -188,29 +200,33 @@ template<class Visitor> total += querySingle( SI_PadsTop, shape, aMinDistance, v ); total += querySingle( SI_PadsTop, shape, aMinDistance, v ); total += querySingle( SI_PadsBottom, shape, aMinDistance, v ); total += querySingle( SI_PadsBottom, shape, aMinDistance, v ); for( int i = layers.Start(); i <= layers.End(); ++i ) for( int i = layers.Start(); i <= layers.End(); ++i ) total += querySingle( SI_Traces + 2 * i + SI_SegStraight, shape, aMinDistance, v ); total += querySingle( SI_Traces + 2 * i + SI_SegStraight, shape, aMinDistance, v ); } } else { else { int l = layers.Start(); int l = layers.Start(); if( l == 0 ) if( l == 0 ) total += querySingle( SI_PadsTop, shape, aMinDistance, v ); total += querySingle( SI_PadsTop, shape, aMinDistance, v ); else if( l == 15 ) else if( l == 15 ) total += querySingle( SI_PadsBottom, shape, aMinDistance, v ); total += querySingle( SI_PadsBottom, shape, aMinDistance, v ); total += querySingle( SI_Traces + 2 * l + SI_SegStraight, shape, aMinDistance, v ); total += querySingle( SI_Traces + 2 * l + SI_SegStraight, shape, aMinDistance, v ); } } return total; return total; } } template<class Visitor> template<class Visitor> int PNS_INDEX::Query( const SHAPE* aShape, int aMinDistance, Visitor& v ) int PNS_INDEX::Query( const SHAPE* aShape, int aMinDistance, Visitor& v ) { { int total = 0; int total = 0; for( int i = 0; i < MaxSubIndices; i++ ) for( int i = 0; i < MaxSubIndices; i++ ) total += querySingle( i, aShape, aMinDistance, v ); total += querySingle( i, aShape, aMinDistance, v ); return total; return total; } } Loading @@ -220,22 +236,28 @@ void PNS_INDEX::Clear() for( int i = 0; i < MaxSubIndices; ++i ) for( int i = 0; i < MaxSubIndices; ++i ) { { ItemShapeIndex* idx = m_subIndices[i]; ItemShapeIndex* idx = m_subIndices[i]; if( idx ) if( idx ) delete idx; delete idx; m_subIndices[i] = NULL; m_subIndices[i] = NULL; } } } } PNS_INDEX::~PNS_INDEX() PNS_INDEX::~PNS_INDEX() { { Clear(); Clear(); } } PNS_INDEX::NetItemsList* PNS_INDEX::GetItemsForNet( int aNet ) PNS_INDEX::NetItemsList* PNS_INDEX::GetItemsForNet( int aNet ) { { if( m_netMap.find( aNet ) == m_netMap.end() ) if( m_netMap.find( aNet ) == m_netMap.end() ) return NULL; return NULL; return &m_netMap[aNet]; return &m_netMap[aNet]; } } #endif #endif Loading
common/gal/opengl/cached_container.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -362,7 +362,7 @@ void CACHED_CONTAINER::mergeFreeChunks() if( m_freeChunks.size() <= 1 ) // There are no chunks that can be merged if( m_freeChunks.size() <= 1 ) // There are no chunks that can be merged return; return; #ifdef CACHED_CONTAINER_TEST > 0 #if CACHED_CONTAINER_TEST > 0 prof_counter totalTime; prof_counter totalTime; prof_start( &totalTime, false ); prof_start( &totalTime, false ); #endif #endif Loading Loading @@ -406,7 +406,7 @@ void CACHED_CONTAINER::mergeFreeChunks() // Add the last one // Add the last one m_freeChunks.insert( std::make_pair( size, offset ) ); m_freeChunks.insert( std::make_pair( size, offset ) ); #ifdef CACHED_CONTAINER_TEST > 0 #if CACHED_CONTAINER_TEST > 0 prof_end( &totalTime ); prof_end( &totalTime ); wxLogDebug( wxT( "Merged free chunks / %.1f ms" ), (double) totalTime.value / 1000.0 ); wxLogDebug( wxT( "Merged free chunks / %.1f ms" ), (double) totalTime.value / 1000.0 ); Loading
common/view/view_item.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -69,7 +69,7 @@ void VIEW_ITEM::ViewRelease() void VIEW_ITEM::getLayers( int* aLayers, int& aCount ) const void VIEW_ITEM::getLayers( int* aLayers, int& aCount ) const { { int* layersPtr = aLayers; int* layersPtr = aLayers; for( int i = 0; i < m_layers.size(); ++i ) for( unsigned int i = 0; i < m_layers.size(); ++i ) { { if( m_layers[i] ) if( m_layers[i] ) *layersPtr++ = i; *layersPtr++ = i; Loading
pcbnew/router/CMakeLists.txt +43 −42 Original line number Original line Diff line number Diff line Loading @@ -48,3 +48,4 @@ set(PCBNEW_PNS_SRCS ) ) add_library( pnsrouter STATIC ${PCBNEW_PNS_SRCS} ) add_library( pnsrouter STATIC ${PCBNEW_PNS_SRCS} )
pcbnew/router/direction.h +298 −261 Original line number Original line Diff line number Diff line Loading @@ -31,7 +31,6 @@ class DIRECTION_45 class DIRECTION_45 { { public: public: /** /** Loading @@ -39,7 +38,8 @@ public: * Represents available directions - there are 8 of them, as on a rectilinear map (north = up) + * Represents available directions - there are 8 of them, as on a rectilinear map (north = up) + * an extra undefined direction, reserved for traces that don't respect 45-degree routing regime. * an extra undefined direction, reserved for traces that don't respect 45-degree routing regime. */ */ enum Directions { enum Directions { N = 0, N = 0, NE = 1, NE = 1, E = 2, E = 2, Loading @@ -55,11 +55,12 @@ public: * Enum AngleType * Enum AngleType * Represents kind of angle formed by vectors heading in two DIRECTION_45s. * Represents kind of angle formed by vectors heading in two DIRECTION_45s. */ */ enum AngleType { enum AngleType ANG_OBTUSE = 0x1, { ANG_RIGHT = 0x2, ANG_OBTUSE = 0x01, ANG_ACUTE = 0x4, ANG_RIGHT = 0x02, ANG_STRAIGHT = 0x8, ANG_ACUTE = 0x04, ANG_STRAIGHT = 0x08, ANG_HALF_FULL = 0x10, ANG_HALF_FULL = 0x10, ANG_UNDEFINED = 0x20 ANG_UNDEFINED = 0x20 }; }; Loading Loading @@ -93,16 +94,35 @@ public: { { switch( m_dir ) switch( m_dir ) { { case N : return "north"; case N: case NE : return "north-east"; return "north"; case E : return "east"; case SE : return "south-east"; case NE: case S : return "south"; return "north-east"; case SW : return "south-west"; case W : return "west"; case E: case NW : return "north-west"; return "east"; case UNDEFINED : return "undefined"; default: return "<Error>"; case SE: return "south-east"; case S: return "south"; case SW: return "south-west"; case W: return "west"; case NW: return "north-west"; case UNDEFINED: return "undefined"; default: return "<Error>"; } } } } Loading @@ -115,6 +135,7 @@ public: { { if( m_dir == UNDEFINED ) if( m_dir == UNDEFINED ) return UNDEFINED; return UNDEFINED; const Directions OppositeMap[] = { S, SW, W, NW, N, NE, E, SE }; const Directions OppositeMap[] = { S, SW, W, NW, N, NE, E, SE }; return OppositeMap[m_dir]; return OppositeMap[m_dir]; } } Loading Loading @@ -172,7 +193,9 @@ public: * @param aStartDiagonal whether the first segment has to be diagonal * @param aStartDiagonal whether the first segment has to be diagonal * @return the trace * @return the trace */ */ const SHAPE_LINE_CHAIN BuildInitialTrace(const VECTOR2I& aP0, const VECTOR2I &aP1, bool aStartDiagonal = false) const const SHAPE_LINE_CHAIN BuildInitialTrace( const VECTOR2I& aP0, const VECTOR2I& aP1, bool aStartDiagonal = false ) const { { int w = abs( aP1.x - aP0.x ); int w = abs( aP1.x - aP0.x ); int h = abs( aP1.y - aP0.y ); int h = abs( aP1.y - aP0.y ); Loading @@ -186,7 +209,9 @@ public: { { mp0 = VECTOR2I( (w - h) * sw, 0 ); // direction: E mp0 = VECTOR2I( (w - h) * sw, 0 ); // direction: E mp1 = VECTOR2I( h * sw, h * sh ); // direction: NE mp1 = VECTOR2I( h * sw, h * sh ); // direction: NE } else { } else { mp0 = VECTOR2I( 0, sh * (h - w) ); // direction: N mp0 = VECTOR2I( 0, sh * (h - w) ); // direction: N mp1 = VECTOR2I( sw * w, sh * w ); // direction: NE mp1 = VECTOR2I( sw * w, sh * w ); // direction: NE } } Loading @@ -201,6 +226,7 @@ public: SHAPE_LINE_CHAIN pl; SHAPE_LINE_CHAIN pl; pl.Append( aP0 ); pl.Append( aP0 ); if( start_diagonal ) if( start_diagonal ) pl.Append( aP0 + mp1 ); pl.Append( aP0 + mp1 ); else else Loading @@ -224,15 +250,20 @@ public: const DIRECTION_45 Right() const const DIRECTION_45 Right() const { { DIRECTION_45 r; DIRECTION_45 r; r.m_dir = (Directions) (m_dir + 1); r.m_dir = (Directions) (m_dir + 1); if( r.m_dir == NW ) if( r.m_dir == NW ) r.m_dir = N; r.m_dir = N; return r; return r; } } private: private: template <typename T> int sign(T val) const { template <typename T> int sign( T val ) const { return (T( 0 ) < val) - ( val < T( 0 ) ); return (T( 0 ) < val) - ( val < T( 0 ) ); } } Loading @@ -245,12 +276,15 @@ private: void construct( const VECTOR2I& aVec ) void construct( const VECTOR2I& aVec ) { { m_dir = UNDEFINED; m_dir = UNDEFINED; if( aVec.x == 0 && aVec.y == 0 ) if( aVec.x == 0 && aVec.y == 0 ) return; return; double mag = 360.0 - ( 180.0 / M_PI * atan2( (double) aVec.y, (double) aVec.x ) ) + 90.0; double mag = 360.0 - ( 180.0 / M_PI * atan2( (double) aVec.y, (double) aVec.x ) ) + 90.0; if( mag >= 360.0 ) if( mag >= 360.0 ) mag -= 360.0; mag -= 360.0; if( mag < 0.0 ) if( mag < 0.0 ) mag += 360.0; mag += 360.0; Loading @@ -258,10 +292,12 @@ private: if( m_dir >= 8 ) if( m_dir >= 8 ) m_dir = (Directions)( m_dir - 8 ); m_dir = (Directions)( m_dir - 8 ); if( m_dir < 0 ) if( m_dir < 0 ) m_dir = (Directions)( m_dir + 8 ); m_dir = (Directions)( m_dir + 8 ); return; return; if( aVec.y < 0 ) if( aVec.y < 0 ) { { if( aVec.x > 0 ) if( aVec.x > 0 ) Loading Loading @@ -293,3 +329,4 @@ private: }; }; #endif // __DIRECTION_H #endif // __DIRECTION_H
pcbnew/router/pns_index.h +181 −159 Original line number Original line Diff line number Diff line Loading @@ -37,10 +37,9 @@ * overlap and improving search time. * overlap and improving search time. **/ **/ class PNS_INDEX { class PNS_INDEX { public: public: typedef std::list<PNS_ITEM*> NetItemsList; typedef std::list<PNS_ITEM*> NetItemsList; typedef SHAPE_INDEX<PNS_ITEM*> ItemShapeIndex; typedef SHAPE_INDEX<PNS_ITEM*> ItemShapeIndex; typedef boost::unordered_set<PNS_ITEM*> ItemSet; typedef boost::unordered_set<PNS_ITEM*> ItemSet; Loading @@ -54,6 +53,7 @@ public: template<class Visitor> template<class Visitor> int Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& v ); int Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& v ); template<class Visitor> template<class Visitor> int Query( const SHAPE* aShape, int aMinDistance, Visitor& v ); int Query( const SHAPE* aShape, int aMinDistance, Visitor& v ); Loading @@ -64,15 +64,14 @@ public: ItemSet::iterator begin() { return m_allItems.begin(); } ItemSet::iterator begin() { return m_allItems.begin(); } ItemSet::iterator end() { return m_allItems.end(); } ItemSet::iterator end() { return m_allItems.end(); } bool Contains ( PNS_ITEM *aItem ) const { bool Contains( PNS_ITEM* aItem ) const { return m_allItems.find( aItem ) != m_allItems.end(); return m_allItems.find( aItem ) != m_allItems.end(); } } int Size() const { return m_allItems.size(); } int Size() const { return m_allItems.size(); } private: private: static const int MaxSubIndices = 64; static const int MaxSubIndices = 64; static const int SI_Multilayer = 2; static const int SI_Multilayer = 2; static const int SI_SegDiagonal = 0; static const int SI_SegDiagonal = 0; Loading @@ -91,11 +90,13 @@ private: ItemSet m_allItems; ItemSet m_allItems; }; }; PNS_INDEX::PNS_INDEX() PNS_INDEX::PNS_INDEX() { { memset( m_subIndices, 0, sizeof( m_subIndices ) ); memset( m_subIndices, 0, sizeof( m_subIndices ) ); } } PNS_INDEX::ItemShapeIndex* PNS_INDEX::getSubindex( const PNS_ITEM* aItem ) PNS_INDEX::ItemShapeIndex* PNS_INDEX::getSubindex( const PNS_ITEM* aItem ) { { int idx_n = -1; int idx_n = -1; Loading @@ -107,6 +108,7 @@ PNS_INDEX::ItemShapeIndex *PNS_INDEX::getSubindex(const PNS_ITEM *aItem ) case PNS_ITEM::VIA: case PNS_ITEM::VIA: idx_n = SI_Multilayer; idx_n = SI_Multilayer; break; break; case PNS_ITEM::SOLID: case PNS_ITEM::SOLID: { { if( l.IsMultilayer() ) if( l.IsMultilayer() ) Loading @@ -115,15 +117,19 @@ PNS_INDEX::ItemShapeIndex *PNS_INDEX::getSubindex(const PNS_ITEM *aItem ) idx_n = SI_PadsTop; idx_n = SI_PadsTop; else if( l.Start() == 15 ) else if( l.Start() == 15 ) idx_n = SI_PadsBottom; idx_n = SI_PadsBottom; break; break; } } case PNS_ITEM::SEGMENT: case PNS_ITEM::SEGMENT: case PNS_ITEM::LINE: case PNS_ITEM::LINE: idx_n = SI_Traces + 2 * l.Start() + SI_SegStraight; idx_n = SI_Traces + 2 * l.Start() + SI_SegStraight; break; break; default: default: break; break; } } assert( idx_n >= 0 && idx_n < MaxSubIndices ); assert( idx_n >= 0 && idx_n < MaxSubIndices ); if( !m_subIndices[idx_n] ) if( !m_subIndices[idx_n] ) Loading @@ -132,23 +138,26 @@ PNS_INDEX::ItemShapeIndex *PNS_INDEX::getSubindex(const PNS_ITEM *aItem ) return m_subIndices[idx_n]; return m_subIndices[idx_n]; } } void PNS_INDEX::Add( PNS_ITEM* aItem ) void PNS_INDEX::Add( PNS_ITEM* aItem ) { { ItemShapeIndex* idx = getSubindex( aItem ); ItemShapeIndex* idx = getSubindex( aItem ); idx->Add( aItem ); idx->Add( aItem ); m_allItems.insert( aItem ); m_allItems.insert( aItem ); int net = aItem->GetNet(); int net = aItem->GetNet(); if( net >= 0 ) if( net >= 0 ) { { m_netMap[net].push_back( aItem ); m_netMap[net].push_back( aItem ); } } } } void PNS_INDEX::Remove( PNS_ITEM* aItem ) void PNS_INDEX::Remove( PNS_ITEM* aItem ) { { ItemShapeIndex* idx = getSubindex( aItem ); ItemShapeIndex* idx = getSubindex( aItem ); idx->Remove( aItem ); idx->Remove( aItem ); m_allItems.erase( aItem ); m_allItems.erase( aItem ); Loading @@ -158,27 +167,30 @@ void PNS_INDEX::Remove( PNS_ITEM *aItem ) m_netMap[net].remove( aItem ); m_netMap[net].remove( aItem ); } } void PNS_INDEX::Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem ) void PNS_INDEX::Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem ) { { Remove( aOldItem ); Remove( aOldItem ); Add( aNewItem ); Add( aNewItem ); } } template<class Visitor> template<class Visitor> int PNS_INDEX::querySingle( int index, const SHAPE* aShape, int aMinDistance, Visitor& v ) int PNS_INDEX::querySingle( int index, const SHAPE* aShape, int aMinDistance, Visitor& v ) { { if( !m_subIndices[index] ) if( !m_subIndices[index] ) return 0; return 0; return m_subIndices[index]->Query( aShape, aMinDistance, v, false ); return m_subIndices[index]->Query( aShape, aMinDistance, v, false ); } } template<class Visitor> template<class Visitor> int PNS_INDEX::Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& v ) int PNS_INDEX::Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& v ) { { const SHAPE* shape = aItem->GetShape(); const SHAPE* shape = aItem->GetShape(); int total = 0; int total = 0; total += querySingle( SI_Multilayer, shape, aMinDistance, v ); total += querySingle( SI_Multilayer, shape, aMinDistance, v ); const PNS_LAYERSET layers = aItem->GetLayers(); const PNS_LAYERSET layers = aItem->GetLayers(); Loading @@ -188,29 +200,33 @@ template<class Visitor> total += querySingle( SI_PadsTop, shape, aMinDistance, v ); total += querySingle( SI_PadsTop, shape, aMinDistance, v ); total += querySingle( SI_PadsBottom, shape, aMinDistance, v ); total += querySingle( SI_PadsBottom, shape, aMinDistance, v ); for( int i = layers.Start(); i <= layers.End(); ++i ) for( int i = layers.Start(); i <= layers.End(); ++i ) total += querySingle( SI_Traces + 2 * i + SI_SegStraight, shape, aMinDistance, v ); total += querySingle( SI_Traces + 2 * i + SI_SegStraight, shape, aMinDistance, v ); } } else { else { int l = layers.Start(); int l = layers.Start(); if( l == 0 ) if( l == 0 ) total += querySingle( SI_PadsTop, shape, aMinDistance, v ); total += querySingle( SI_PadsTop, shape, aMinDistance, v ); else if( l == 15 ) else if( l == 15 ) total += querySingle( SI_PadsBottom, shape, aMinDistance, v ); total += querySingle( SI_PadsBottom, shape, aMinDistance, v ); total += querySingle( SI_Traces + 2 * l + SI_SegStraight, shape, aMinDistance, v ); total += querySingle( SI_Traces + 2 * l + SI_SegStraight, shape, aMinDistance, v ); } } return total; return total; } } template<class Visitor> template<class Visitor> int PNS_INDEX::Query( const SHAPE* aShape, int aMinDistance, Visitor& v ) int PNS_INDEX::Query( const SHAPE* aShape, int aMinDistance, Visitor& v ) { { int total = 0; int total = 0; for( int i = 0; i < MaxSubIndices; i++ ) for( int i = 0; i < MaxSubIndices; i++ ) total += querySingle( i, aShape, aMinDistance, v ); total += querySingle( i, aShape, aMinDistance, v ); return total; return total; } } Loading @@ -220,22 +236,28 @@ void PNS_INDEX::Clear() for( int i = 0; i < MaxSubIndices; ++i ) for( int i = 0; i < MaxSubIndices; ++i ) { { ItemShapeIndex* idx = m_subIndices[i]; ItemShapeIndex* idx = m_subIndices[i]; if( idx ) if( idx ) delete idx; delete idx; m_subIndices[i] = NULL; m_subIndices[i] = NULL; } } } } PNS_INDEX::~PNS_INDEX() PNS_INDEX::~PNS_INDEX() { { Clear(); Clear(); } } PNS_INDEX::NetItemsList* PNS_INDEX::GetItemsForNet( int aNet ) PNS_INDEX::NetItemsList* PNS_INDEX::GetItemsForNet( int aNet ) { { if( m_netMap.find( aNet ) == m_netMap.end() ) if( m_netMap.find( aNet ) == m_netMap.end() ) return NULL; return NULL; return &m_netMap[aNet]; return &m_netMap[aNet]; } } #endif #endif