Loading pcbnew/router/CMakeLists.txt +47 −46 Original line number Diff line number Diff line Loading @@ -48,3 +48,4 @@ set(PCBNEW_PNS_SRCS ) add_library( pnsrouter STATIC ${PCBNEW_PNS_SRCS} ) pcbnew/router/direction.h +298 −261 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ class DIRECTION_45 { public: /** Loading @@ -39,7 +38,8 @@ public: * 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. */ enum Directions { enum Directions { N = 0, NE = 1, E = 2, Loading @@ -55,11 +55,12 @@ public: * Enum AngleType * Represents kind of angle formed by vectors heading in two DIRECTION_45s. */ enum AngleType { ANG_OBTUSE = 0x1, ANG_RIGHT = 0x2, ANG_ACUTE = 0x4, ANG_STRAIGHT = 0x8, enum AngleType { ANG_OBTUSE = 0x01, ANG_RIGHT = 0x02, ANG_ACUTE = 0x04, ANG_STRAIGHT = 0x08, ANG_HALF_FULL = 0x10, ANG_UNDEFINED = 0x20 }; Loading Loading @@ -93,16 +94,35 @@ public: { switch( m_dir ) { case N : return "north"; case NE : return "north-east"; case E : return "east"; 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>"; case N: return "north"; case NE: return "north-east"; case E: return "east"; 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 ) return UNDEFINED; const Directions OppositeMap[] = { S, SW, W, NW, N, NE, E, SE }; return OppositeMap[m_dir]; } Loading Loading @@ -172,7 +193,9 @@ public: * @param aStartDiagonal whether the first segment has to be diagonal * @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 h = abs( aP1.y - aP0.y ); Loading @@ -186,7 +209,9 @@ public: { mp0 = VECTOR2I( (w - h) * sw, 0 ); // direction: E mp1 = VECTOR2I( h * sw, h * sh ); // direction: NE } else { } else { mp0 = VECTOR2I( 0, sh * (h - w) ); // direction: N mp1 = VECTOR2I( sw * w, sh * w ); // direction: NE } Loading @@ -201,6 +226,7 @@ public: SHAPE_LINE_CHAIN pl; pl.Append( aP0 ); if( start_diagonal ) pl.Append( aP0 + mp1 ); else Loading @@ -224,15 +250,20 @@ public: const DIRECTION_45 Right() const { DIRECTION_45 r; r.m_dir = (Directions) (m_dir + 1); if( r.m_dir == NW ) r.m_dir = N; return r; } private: template <typename T> int sign(T val) const { template <typename T> int sign( T val ) const { return (T( 0 ) < val) - ( val < T( 0 ) ); } Loading @@ -245,12 +276,15 @@ private: void construct( const VECTOR2I& aVec ) { m_dir = UNDEFINED; if( aVec.x == 0 && aVec.y == 0 ) return; double mag = 360.0 - ( 180.0 / M_PI * atan2( (double) aVec.y, (double) aVec.x ) ) + 90.0; if( mag >= 360.0 ) mag -= 360.0; if( mag < 0.0 ) mag += 360.0; Loading @@ -258,10 +292,12 @@ private: if( m_dir >= 8 ) m_dir = (Directions)( m_dir - 8 ); if( m_dir < 0 ) m_dir = (Directions)( m_dir + 8 ); return; if( aVec.y < 0 ) { if( aVec.x > 0 ) Loading Loading @@ -293,3 +329,4 @@ private: }; #endif // __DIRECTION_H pcbnew/router/pns_index.h +181 −159 Original line number Diff line number Diff line Loading @@ -37,10 +37,9 @@ * overlap and improving search time. **/ class PNS_INDEX { class PNS_INDEX { public: typedef std::list<PNS_ITEM*> NetItemsList; typedef SHAPE_INDEX<PNS_ITEM*> ItemShapeIndex; typedef boost::unordered_set<PNS_ITEM*> ItemSet; Loading @@ -54,6 +53,7 @@ public: template<class Visitor> int Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& v ); template<class Visitor> int Query( const SHAPE* aShape, int aMinDistance, Visitor& v ); Loading @@ -64,15 +64,14 @@ public: ItemSet::iterator begin() { return m_allItems.begin(); } 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(); } int Size() const { return m_allItems.size(); } private: static const int MaxSubIndices = 64; static const int SI_Multilayer = 2; static const int SI_SegDiagonal = 0; Loading @@ -91,11 +90,13 @@ private: ItemSet m_allItems; }; PNS_INDEX::PNS_INDEX() { memset( m_subIndices, 0, sizeof( m_subIndices ) ); } PNS_INDEX::ItemShapeIndex* PNS_INDEX::getSubindex( const PNS_ITEM* aItem ) { int idx_n = -1; Loading @@ -107,6 +108,7 @@ PNS_INDEX::ItemShapeIndex *PNS_INDEX::getSubindex(const PNS_ITEM *aItem ) case PNS_ITEM::VIA: idx_n = SI_Multilayer; break; case PNS_ITEM::SOLID: { if( l.IsMultilayer() ) Loading @@ -115,15 +117,19 @@ PNS_INDEX::ItemShapeIndex *PNS_INDEX::getSubindex(const PNS_ITEM *aItem ) idx_n = SI_PadsTop; else if( l.Start() == 15 ) idx_n = SI_PadsBottom; break; } case PNS_ITEM::SEGMENT: case PNS_ITEM::LINE: idx_n = SI_Traces + 2 * l.Start() + SI_SegStraight; break; default: break; } assert( idx_n >= 0 && idx_n < MaxSubIndices ); 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]; } void PNS_INDEX::Add( PNS_ITEM* aItem ) { ItemShapeIndex* idx = getSubindex( aItem ); idx->Add( aItem ); m_allItems.insert( aItem ); int net = aItem->GetNet(); if( net >= 0 ) { m_netMap[net].push_back( aItem ); } } void PNS_INDEX::Remove( PNS_ITEM* aItem ) { ItemShapeIndex* idx = getSubindex( aItem ); idx->Remove( aItem ); m_allItems.erase( aItem ); Loading @@ -158,27 +167,30 @@ void PNS_INDEX::Remove( PNS_ITEM *aItem ) m_netMap[net].remove( aItem ); } void PNS_INDEX::Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem ) { Remove( aOldItem ); Add( aNewItem ); } template<class Visitor> int PNS_INDEX::querySingle( int index, const SHAPE* aShape, int aMinDistance, Visitor& v ) { if( !m_subIndices[index] ) return 0; return m_subIndices[index]->Query( aShape, aMinDistance, v, false ); } template<class Visitor> int PNS_INDEX::Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& v ) { const SHAPE* shape = aItem->GetShape(); int total = 0; total += querySingle( SI_Multilayer, shape, aMinDistance, v ); const PNS_LAYERSET layers = aItem->GetLayers(); Loading @@ -188,29 +200,33 @@ template<class Visitor> total += querySingle( SI_PadsTop, shape, aMinDistance, v ); total += querySingle( SI_PadsBottom, shape, aMinDistance, v ); for( int i = layers.Start(); i <= layers.End(); ++i ) total += querySingle( SI_Traces + 2 * i + SI_SegStraight, shape, aMinDistance, v ); } else { } else { int l = layers.Start(); if( l == 0 ) total += querySingle( SI_PadsTop, shape, aMinDistance, v ); else if( l == 15 ) total += querySingle( SI_PadsBottom, shape, aMinDistance, v ); total += querySingle( SI_Traces + 2 * l + SI_SegStraight, shape, aMinDistance, v ); } return total; } template<class Visitor> int PNS_INDEX::Query( const SHAPE* aShape, int aMinDistance, Visitor& v ) { int total = 0; for( int i = 0; i < MaxSubIndices; i++ ) total += querySingle( i, aShape, aMinDistance, v ); return total; } Loading @@ -220,22 +236,28 @@ void PNS_INDEX::Clear() for( int i = 0; i < MaxSubIndices; ++i ) { ItemShapeIndex* idx = m_subIndices[i]; if( idx ) delete idx; m_subIndices[i] = NULL; } } PNS_INDEX::~PNS_INDEX() { Clear(); } PNS_INDEX::NetItemsList* PNS_INDEX::GetItemsForNet( int aNet ) { if( m_netMap.find( aNet ) == m_netMap.end() ) return NULL; return &m_netMap[aNet]; } #endif pcbnew/router/pns_item.cpp +53 −36 Original line number Diff line number Diff line Loading @@ -21,7 +21,8 @@ #include "pns_item.h" #include "pns_line.h" bool PNS_ITEM::collideSimple ( const PNS_ITEM *aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const bool PNS_ITEM::collideSimple( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const { // same nets? no collision! if( m_net == aOther->m_net ) Loading @@ -36,7 +37,9 @@ bool PNS_ITEM::collideSimple ( const PNS_ITEM *aOther, int aClearance, bool aNee // fixme: MTV } bool PNS_ITEM::Collide( const PNS_ITEM *aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const bool PNS_ITEM::Collide( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const { if( collideSimple( aOther, aClearance, aNeedMTV, aMTV ) ) return true; Loading @@ -45,28 +48,42 @@ bool PNS_ITEM::Collide( const PNS_ITEM *aOther, int aClearance, bool aNeedMTV, V if( aOther->m_kind == LINE ) { const PNS_LINE* line = static_cast<const PNS_LINE*>( aOther ); if( line->EndsWithVia() ) return collideSimple( &line->GetVia(), aClearance - line->GetWidth() / 2, aNeedMTV, aMTV ); return collideSimple( &line->GetVia(), aClearance - line->GetWidth() / 2, aNeedMTV, aMTV ); } return false; } const std::string PNS_ITEM::GetKindStr() const { switch( m_kind ) { case LINE: return "line"; case SEGMENT: return "segment"; case VIA: return "via"; case JOINT: return "joint"; case SOLID: return "solid"; default: return "unknown"; case LINE: return "line"; case SEGMENT: return "segment"; case VIA: return "via"; case JOINT: return "joint"; case SOLID: return "solid"; default: return "unknown"; } } PNS_ITEM::~PNS_ITEM() { } pcbnew/router/pns_item.h +111 −108 Original line number Diff line number Diff line Loading @@ -41,11 +41,11 @@ class PNS_NODE; class PNS_ITEM { public: static const int UnusedNet = INT_MAX; ///> Supported item types enum PnsKind { enum PnsKind { SOLID = 1, LINE = 2, JOINT = 4, Loading Loading @@ -88,8 +88,6 @@ public: return SHAPE_LINE_CHAIN(); }; PnsKind GetKind() const { return m_kind; } bool OfKind( int aKind ) const { return (aKind & m_kind) != 0; } Loading @@ -106,7 +104,10 @@ public: ///> Layers accessors const PNS_LAYERSET& GetLayers() const { return m_layers; } void SetLayers( const PNS_LAYERSET& aLayers ) { m_layers = aLayers; } void SetLayer ( int aLayer ) { m_layers = PNS_LAYERSET (aLayer, aLayer); } void SetLayer( int aLayer ) { m_layers = PNS_LAYERSET( aLayer, aLayer ); } ///> Ownership management. An item can belong to a single PNS_NODE or stay unowned. void SetOwner( PNS_NODE* aOwner ) { m_owner = aOwner; } Loading @@ -117,29 +118,31 @@ public: void SetWorld( PNS_NODE* aWorld ) { m_world = aWorld; } PNS_NODE* GetWorld() const { return m_world; } ///> Collision function. Checks if the item aOther is closer to us than /// aClearance and returns true if so. It can also calculate a minimum translation vector that resolves the /// collision if needed. virtual bool Collide( const PNS_ITEM *aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const; /// aClearance and returns true if so. It can also calculate a minimum translation vector that /// resolves the collision if needed. virtual bool Collide( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const; ///> A shortcut without MTV calculation bool Collide( const PNS_ITEM* aOther, int aClearance ) const { VECTOR2I dummy; return Collide( aOther, aClearance, false, dummy ); } ///> Returns the geometric shape of the item virtual const SHAPE* GetShape() const { virtual const SHAPE* GetShape() const { return NULL; } private: bool collideSimple ( const PNS_ITEM *aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const; bool collideSimple( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const; protected: PnsKind m_kind; BOARD_ITEM* m_parent; Loading @@ -151,5 +154,5 @@ protected: int m_net; }; #endif // __PNS_ITEM_H #endif // __PNS_ITEM_Ha Loading
pcbnew/router/CMakeLists.txt +47 −46 Original line number Diff line number Diff line Loading @@ -48,3 +48,4 @@ set(PCBNEW_PNS_SRCS ) add_library( pnsrouter STATIC ${PCBNEW_PNS_SRCS} )
pcbnew/router/direction.h +298 −261 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ class DIRECTION_45 { public: /** Loading @@ -39,7 +38,8 @@ public: * 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. */ enum Directions { enum Directions { N = 0, NE = 1, E = 2, Loading @@ -55,11 +55,12 @@ public: * Enum AngleType * Represents kind of angle formed by vectors heading in two DIRECTION_45s. */ enum AngleType { ANG_OBTUSE = 0x1, ANG_RIGHT = 0x2, ANG_ACUTE = 0x4, ANG_STRAIGHT = 0x8, enum AngleType { ANG_OBTUSE = 0x01, ANG_RIGHT = 0x02, ANG_ACUTE = 0x04, ANG_STRAIGHT = 0x08, ANG_HALF_FULL = 0x10, ANG_UNDEFINED = 0x20 }; Loading Loading @@ -93,16 +94,35 @@ public: { switch( m_dir ) { case N : return "north"; case NE : return "north-east"; case E : return "east"; 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>"; case N: return "north"; case NE: return "north-east"; case E: return "east"; 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 ) return UNDEFINED; const Directions OppositeMap[] = { S, SW, W, NW, N, NE, E, SE }; return OppositeMap[m_dir]; } Loading Loading @@ -172,7 +193,9 @@ public: * @param aStartDiagonal whether the first segment has to be diagonal * @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 h = abs( aP1.y - aP0.y ); Loading @@ -186,7 +209,9 @@ public: { mp0 = VECTOR2I( (w - h) * sw, 0 ); // direction: E mp1 = VECTOR2I( h * sw, h * sh ); // direction: NE } else { } else { mp0 = VECTOR2I( 0, sh * (h - w) ); // direction: N mp1 = VECTOR2I( sw * w, sh * w ); // direction: NE } Loading @@ -201,6 +226,7 @@ public: SHAPE_LINE_CHAIN pl; pl.Append( aP0 ); if( start_diagonal ) pl.Append( aP0 + mp1 ); else Loading @@ -224,15 +250,20 @@ public: const DIRECTION_45 Right() const { DIRECTION_45 r; r.m_dir = (Directions) (m_dir + 1); if( r.m_dir == NW ) r.m_dir = N; return r; } private: template <typename T> int sign(T val) const { template <typename T> int sign( T val ) const { return (T( 0 ) < val) - ( val < T( 0 ) ); } Loading @@ -245,12 +276,15 @@ private: void construct( const VECTOR2I& aVec ) { m_dir = UNDEFINED; if( aVec.x == 0 && aVec.y == 0 ) return; double mag = 360.0 - ( 180.0 / M_PI * atan2( (double) aVec.y, (double) aVec.x ) ) + 90.0; if( mag >= 360.0 ) mag -= 360.0; if( mag < 0.0 ) mag += 360.0; Loading @@ -258,10 +292,12 @@ private: if( m_dir >= 8 ) m_dir = (Directions)( m_dir - 8 ); if( m_dir < 0 ) m_dir = (Directions)( m_dir + 8 ); return; if( aVec.y < 0 ) { if( aVec.x > 0 ) Loading Loading @@ -293,3 +329,4 @@ private: }; #endif // __DIRECTION_H
pcbnew/router/pns_index.h +181 −159 Original line number Diff line number Diff line Loading @@ -37,10 +37,9 @@ * overlap and improving search time. **/ class PNS_INDEX { class PNS_INDEX { public: typedef std::list<PNS_ITEM*> NetItemsList; typedef SHAPE_INDEX<PNS_ITEM*> ItemShapeIndex; typedef boost::unordered_set<PNS_ITEM*> ItemSet; Loading @@ -54,6 +53,7 @@ public: template<class Visitor> int Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& v ); template<class Visitor> int Query( const SHAPE* aShape, int aMinDistance, Visitor& v ); Loading @@ -64,15 +64,14 @@ public: ItemSet::iterator begin() { return m_allItems.begin(); } 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(); } int Size() const { return m_allItems.size(); } private: static const int MaxSubIndices = 64; static const int SI_Multilayer = 2; static const int SI_SegDiagonal = 0; Loading @@ -91,11 +90,13 @@ private: ItemSet m_allItems; }; PNS_INDEX::PNS_INDEX() { memset( m_subIndices, 0, sizeof( m_subIndices ) ); } PNS_INDEX::ItemShapeIndex* PNS_INDEX::getSubindex( const PNS_ITEM* aItem ) { int idx_n = -1; Loading @@ -107,6 +108,7 @@ PNS_INDEX::ItemShapeIndex *PNS_INDEX::getSubindex(const PNS_ITEM *aItem ) case PNS_ITEM::VIA: idx_n = SI_Multilayer; break; case PNS_ITEM::SOLID: { if( l.IsMultilayer() ) Loading @@ -115,15 +117,19 @@ PNS_INDEX::ItemShapeIndex *PNS_INDEX::getSubindex(const PNS_ITEM *aItem ) idx_n = SI_PadsTop; else if( l.Start() == 15 ) idx_n = SI_PadsBottom; break; } case PNS_ITEM::SEGMENT: case PNS_ITEM::LINE: idx_n = SI_Traces + 2 * l.Start() + SI_SegStraight; break; default: break; } assert( idx_n >= 0 && idx_n < MaxSubIndices ); 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]; } void PNS_INDEX::Add( PNS_ITEM* aItem ) { ItemShapeIndex* idx = getSubindex( aItem ); idx->Add( aItem ); m_allItems.insert( aItem ); int net = aItem->GetNet(); if( net >= 0 ) { m_netMap[net].push_back( aItem ); } } void PNS_INDEX::Remove( PNS_ITEM* aItem ) { ItemShapeIndex* idx = getSubindex( aItem ); idx->Remove( aItem ); m_allItems.erase( aItem ); Loading @@ -158,27 +167,30 @@ void PNS_INDEX::Remove( PNS_ITEM *aItem ) m_netMap[net].remove( aItem ); } void PNS_INDEX::Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem ) { Remove( aOldItem ); Add( aNewItem ); } template<class Visitor> int PNS_INDEX::querySingle( int index, const SHAPE* aShape, int aMinDistance, Visitor& v ) { if( !m_subIndices[index] ) return 0; return m_subIndices[index]->Query( aShape, aMinDistance, v, false ); } template<class Visitor> int PNS_INDEX::Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& v ) { const SHAPE* shape = aItem->GetShape(); int total = 0; total += querySingle( SI_Multilayer, shape, aMinDistance, v ); const PNS_LAYERSET layers = aItem->GetLayers(); Loading @@ -188,29 +200,33 @@ template<class Visitor> total += querySingle( SI_PadsTop, shape, aMinDistance, v ); total += querySingle( SI_PadsBottom, shape, aMinDistance, v ); for( int i = layers.Start(); i <= layers.End(); ++i ) total += querySingle( SI_Traces + 2 * i + SI_SegStraight, shape, aMinDistance, v ); } else { } else { int l = layers.Start(); if( l == 0 ) total += querySingle( SI_PadsTop, shape, aMinDistance, v ); else if( l == 15 ) total += querySingle( SI_PadsBottom, shape, aMinDistance, v ); total += querySingle( SI_Traces + 2 * l + SI_SegStraight, shape, aMinDistance, v ); } return total; } template<class Visitor> int PNS_INDEX::Query( const SHAPE* aShape, int aMinDistance, Visitor& v ) { int total = 0; for( int i = 0; i < MaxSubIndices; i++ ) total += querySingle( i, aShape, aMinDistance, v ); return total; } Loading @@ -220,22 +236,28 @@ void PNS_INDEX::Clear() for( int i = 0; i < MaxSubIndices; ++i ) { ItemShapeIndex* idx = m_subIndices[i]; if( idx ) delete idx; m_subIndices[i] = NULL; } } PNS_INDEX::~PNS_INDEX() { Clear(); } PNS_INDEX::NetItemsList* PNS_INDEX::GetItemsForNet( int aNet ) { if( m_netMap.find( aNet ) == m_netMap.end() ) return NULL; return &m_netMap[aNet]; } #endif
pcbnew/router/pns_item.cpp +53 −36 Original line number Diff line number Diff line Loading @@ -21,7 +21,8 @@ #include "pns_item.h" #include "pns_line.h" bool PNS_ITEM::collideSimple ( const PNS_ITEM *aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const bool PNS_ITEM::collideSimple( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const { // same nets? no collision! if( m_net == aOther->m_net ) Loading @@ -36,7 +37,9 @@ bool PNS_ITEM::collideSimple ( const PNS_ITEM *aOther, int aClearance, bool aNee // fixme: MTV } bool PNS_ITEM::Collide( const PNS_ITEM *aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const bool PNS_ITEM::Collide( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const { if( collideSimple( aOther, aClearance, aNeedMTV, aMTV ) ) return true; Loading @@ -45,28 +48,42 @@ bool PNS_ITEM::Collide( const PNS_ITEM *aOther, int aClearance, bool aNeedMTV, V if( aOther->m_kind == LINE ) { const PNS_LINE* line = static_cast<const PNS_LINE*>( aOther ); if( line->EndsWithVia() ) return collideSimple( &line->GetVia(), aClearance - line->GetWidth() / 2, aNeedMTV, aMTV ); return collideSimple( &line->GetVia(), aClearance - line->GetWidth() / 2, aNeedMTV, aMTV ); } return false; } const std::string PNS_ITEM::GetKindStr() const { switch( m_kind ) { case LINE: return "line"; case SEGMENT: return "segment"; case VIA: return "via"; case JOINT: return "joint"; case SOLID: return "solid"; default: return "unknown"; case LINE: return "line"; case SEGMENT: return "segment"; case VIA: return "via"; case JOINT: return "joint"; case SOLID: return "solid"; default: return "unknown"; } } PNS_ITEM::~PNS_ITEM() { }
pcbnew/router/pns_item.h +111 −108 Original line number Diff line number Diff line Loading @@ -41,11 +41,11 @@ class PNS_NODE; class PNS_ITEM { public: static const int UnusedNet = INT_MAX; ///> Supported item types enum PnsKind { enum PnsKind { SOLID = 1, LINE = 2, JOINT = 4, Loading Loading @@ -88,8 +88,6 @@ public: return SHAPE_LINE_CHAIN(); }; PnsKind GetKind() const { return m_kind; } bool OfKind( int aKind ) const { return (aKind & m_kind) != 0; } Loading @@ -106,7 +104,10 @@ public: ///> Layers accessors const PNS_LAYERSET& GetLayers() const { return m_layers; } void SetLayers( const PNS_LAYERSET& aLayers ) { m_layers = aLayers; } void SetLayer ( int aLayer ) { m_layers = PNS_LAYERSET (aLayer, aLayer); } void SetLayer( int aLayer ) { m_layers = PNS_LAYERSET( aLayer, aLayer ); } ///> Ownership management. An item can belong to a single PNS_NODE or stay unowned. void SetOwner( PNS_NODE* aOwner ) { m_owner = aOwner; } Loading @@ -117,29 +118,31 @@ public: void SetWorld( PNS_NODE* aWorld ) { m_world = aWorld; } PNS_NODE* GetWorld() const { return m_world; } ///> Collision function. Checks if the item aOther is closer to us than /// aClearance and returns true if so. It can also calculate a minimum translation vector that resolves the /// collision if needed. virtual bool Collide( const PNS_ITEM *aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const; /// aClearance and returns true if so. It can also calculate a minimum translation vector that /// resolves the collision if needed. virtual bool Collide( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const; ///> A shortcut without MTV calculation bool Collide( const PNS_ITEM* aOther, int aClearance ) const { VECTOR2I dummy; return Collide( aOther, aClearance, false, dummy ); } ///> Returns the geometric shape of the item virtual const SHAPE* GetShape() const { virtual const SHAPE* GetShape() const { return NULL; } private: bool collideSimple ( const PNS_ITEM *aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const; bool collideSimple( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) const; protected: PnsKind m_kind; BOARD_ITEM* m_parent; Loading @@ -151,5 +154,5 @@ protected: int m_net; }; #endif // __PNS_ITEM_H #endif // __PNS_ITEM_Ha