Formatting.

This commit is contained in:
Jeff Young 2021-01-01 01:02:06 +00:00
parent ecc0e861d3
commit 3ba17e0a16
3 changed files with 172 additions and 240 deletions

View File

@ -2,7 +2,7 @@
* KiRouter - a push-and-(sometimes-)shove PCB router * KiRouter - a push-and-(sometimes-)shove PCB router
* *
* Copyright (C) 2013-2017 CERN * Copyright (C) 2013-2017 CERN
* Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
@ -42,31 +42,33 @@ class VIA;
class SIZES_SETTINGS; class SIZES_SETTINGS;
class NODE; class NODE;
class FIXED_TAIL { class FIXED_TAIL
{
public: public:
FIXED_TAIL ( int aLineCount = 1); FIXED_TAIL( int aLineCount = 1);
~FIXED_TAIL(); ~FIXED_TAIL();
struct FIX_POINT struct FIX_POINT
{ {
int layer; int layer;
bool placingVias; bool placingVias;
VECTOR2I p; VECTOR2I p;
DIRECTION_45 direction; DIRECTION_45 direction;
}; };
struct STAGE { struct STAGE
NODE *commit; {
NODE* commit;
std::vector<FIX_POINT> pts; std::vector<FIX_POINT> pts;
}; };
void Clear(); void Clear();
void AddStage( VECTOR2I aStart, int aLayer, bool placingVias, DIRECTION_45 direction, NODE *aNode ); void AddStage( VECTOR2I aStart, int aLayer, bool placingVias, DIRECTION_45 direction,
NODE *aNode );
bool PopStage( STAGE& aStage ); bool PopStage( STAGE& aStage );
int StageCount() const; int StageCount() const;
private: private:
std::vector<STAGE> m_stages; std::vector<STAGE> m_stages;
}; };
@ -140,11 +142,10 @@ public:
/** /**
* Function FixRoute() * Function FixRoute()
* *
* Commits the currently routed track to the parent node, taking * Commits the currently routed track to the parent node, taking aP as the final end point
* aP as the final end point and aEndItem as the final anchor (if provided). * and aEndItem as the final anchor (if provided).
* @return true, if route has been commited. May return false if the routing * @return true, if route has been commited. May return false if the routing result is
* result is violating design rules - in such case, the track is only committed * violating design rules - in such case, the track is only committed if CanViolateDRC() is on.
* if Settings.CanViolateDRC() is on.
*/ */
bool FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinish ) override; bool FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinish ) override;
@ -173,8 +174,8 @@ public:
/** /**
* Function Head() * Function Head()
* *
* Returns the "head" of the line being placed, that is the volatile part * Returns the "head" of the line being placed, that is the volatile part that has not been
* that has not "settled" yet. * "fixed" yet.
*/ */
const LINE& Head() const { return m_head; } const LINE& Head() const { return m_head; }
@ -248,9 +249,8 @@ public:
/** /**
* Function UpdateSizes() * Function UpdateSizes()
* *
* Performs on-the-fly update of the width, via diameter & drill size from * Performs on-the-fly update of the width, via diameter & drill size from a settings class.
* a settings class. Used to dynamically change these parameters as * Used to dynamically change these parameters as the track is routed.
* the track is routed.
*/ */
void UpdateSizes( const SIZES_SETTINGS& aSizes ) override; void UpdateSizes( const SIZES_SETTINGS& aSizes ) override;
@ -263,8 +263,8 @@ public:
/** /**
* Function SplitAdjacentSegments() * Function SplitAdjacentSegments()
* *
* Checks if point aP lies on segment aSeg. If so, splits the segment in two, * Checks if point aP lies on segment aSeg. If so, splits the segment in two, forming a
* forming a joint at aP and stores updated topology in node aNode. * joint at aP and stores updated topology in node aNode.
*/ */
bool SplitAdjacentSegments( NODE* aNode, ITEM* aSeg, const VECTOR2I& aP ); bool SplitAdjacentSegments( NODE* aNode, ITEM* aSeg, const VECTOR2I& aP );
@ -273,10 +273,9 @@ private:
/** /**
* Function route() * Function route()
* *
* Re-routes the current track to point aP. Returns true, when routing has * Re-routes the current track to point aP. Returns true, when routing has completed
* completed successfully (i.e. the trace end has reached point aP), and false * successfully (i.e. the trace end has reached point aP), and false if the trace was
* if the trace was stuck somewhere on the way. May call routeStep() * stuck somewhere on the way. May call routeStep() repetitively due to mouse smoothing.
* repetitively due to mouse smoothing.
* @param aP ending point of current route. * @param aP ending point of current route.
* @return true, if the routing is complete. * @return true, if the routing is complete.
*/ */
@ -285,9 +284,8 @@ private:
/** /**
* Function updateLeadingRatLine() * Function updateLeadingRatLine()
* *
* Draws the "leading" ratsnest line, which connects the end of currently * Draws the "leading" ratsnest line, which connects the end of currently routed track and
* routed track and the nearest yet unrouted item. If the routing for * the nearest yet unrouted item. If the routing for current net is complete, draws nothing.
* current net is complete, draws nothing.
*/ */
void updateLeadingRatLine(); void updateLeadingRatLine();
@ -424,54 +422,45 @@ private:
bool buildInitialLine( const VECTOR2I& aP, LINE& aHead ); bool buildInitialLine( const VECTOR2I& aP, LINE& aHead );
///> current routing direction
DIRECTION_45 m_direction;
///> routing direction for new traces DIRECTION_45 m_direction; ///> current routing direction
DIRECTION_45 m_initial_direction; DIRECTION_45 m_initial_direction; ///> routing direction for new traces
///> routing "head": volatile part of the track from the previously LINE m_head; ///> the volatile part of the track from the previously
/// analyzed point to the current routing destination ///> analyzed point to the current routing destination
LINE m_head;
///> routing "tail": part of the track that has been already fixed due to collisions with obstacles LINE m_tail; ///> routing "tail": part of the track that has been already
LINE m_tail; ///> fixed due to collisions with obstacles
///> pointer to world to search colliding items NODE* m_world; ///> pointer to world to search colliding items
NODE* m_world; VECTOR2I m_p_start; ///> current routing start (end of tail, beginning of head)
///> current routing start point (end of tail, beginning of head) std::unique_ptr<SHOVE> m_shove; ///> The shove engine
VECTOR2I m_p_start;
///> The shove engine NODE* m_currentNode; ///> Current world state
std::unique_ptr< SHOVE > m_shove; NODE* m_lastNode; ///> Postprocessed world state (including marked collisions &
///> removed loops)
///> Current world state
NODE* m_currentNode;
///> Postprocessed world state (including marked collisions & removed loops)
NODE* m_lastNode;
SIZES_SETTINGS m_sizes; SIZES_SETTINGS m_sizes;
///> Are we placing a via? bool m_placingVia;
bool m_placingVia;
int m_currentNet; int m_currentNet;
int m_currentLayer; int m_currentLayer;
VECTOR2I m_currentEnd, m_currentStart; VECTOR2I m_currentEnd;
LINE m_currentTrace; VECTOR2I m_currentStart;
LINE m_currentTrace;
PNS_MODE m_currentMode; PNS_MODE m_currentMode;
ITEM* m_startItem; ITEM* m_startItem;
bool m_idle; bool m_idle;
bool m_chainedPlacement; bool m_chainedPlacement;
bool m_orthoMode; bool m_orthoMode;
bool m_placementCorrect; bool m_placementCorrect;
FIXED_TAIL m_fixedTail; FIXED_TAIL m_fixedTail;
POSTURE_SOLVER m_postureSolver; POSTURE_SOLVER m_postureSolver;
}; };

View File

@ -2,7 +2,7 @@
* KiRouter - a push-and-(sometimes-)shove PCB router * KiRouter - a push-and-(sometimes-)shove PCB router
* *
* Copyright (C) 2013-2019 CERN * Copyright (C) 2013-2019 CERN
* Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
@ -151,7 +151,9 @@ NODE* NODE::Branch()
} }
wxLogTrace( "PNS", "%d items, %d joints, %d overrides", wxLogTrace( "PNS", "%d items, %d joints, %d overrides",
child->m_index->Size(), (int) child->m_joints.size(), (int) child->m_override.size() ); child->m_index->Size(),
(int) child->m_joints.size(),
(int) child->m_override.size() );
return child; return child;
} }
@ -184,8 +186,8 @@ void OBSTACLE_VISITOR::SetWorld( const NODE* aNode, const NODE* aOverride )
bool OBSTACLE_VISITOR::visit( ITEM* aCandidate ) bool OBSTACLE_VISITOR::visit( ITEM* aCandidate )
{ {
// check if there is a more recent branch with a newer // check if there is a more recent branch with a newer (possibily modified) version of this
// (possibily modified) version of this item. // item.
if( m_override && m_override->Overrides( aCandidate ) ) if( m_override && m_override->Overrides( aCandidate ) )
return true; return true;
@ -193,28 +195,19 @@ bool OBSTACLE_VISITOR::visit( ITEM* aCandidate )
} }
// function object that visits potential obstacles and performs // function object that visits potential obstacles and performs the actual collision refining
// the actual collision refining
struct NODE::DEFAULT_OBSTACLE_VISITOR : public OBSTACLE_VISITOR struct NODE::DEFAULT_OBSTACLE_VISITOR : public OBSTACLE_VISITOR
{ {
///> list of encountered obstacles
OBSTACLES& m_tab; OBSTACLES& m_tab;
///> acccepted kinds of colliding items (solids, vias, segments, etc...) int m_kindMask; ///> (solids, vias, segments, etc...)
int m_kindMask; int m_limitCount;
int m_matchCount;
int m_extraClearance;
bool m_differentNetsOnly;
///> max number of hits DEFAULT_OBSTACLE_VISITOR( NODE::OBSTACLES& aTab, const ITEM* aItem, int aKindMask,
int m_limitCount; bool aDifferentNetsOnly ) :
///> number of items found so far
int m_matchCount;
///> additional clearance
int m_extraClearance;
bool m_differentNetsOnly;
DEFAULT_OBSTACLE_VISITOR( NODE::OBSTACLES& aTab, const ITEM* aItem, int aKindMask, bool aDifferentNetsOnly ) :
OBSTACLE_VISITOR( aItem ), OBSTACLE_VISITOR( aItem ),
m_tab( aTab ), m_tab( aTab ),
m_kindMask( aKindMask ), m_kindMask( aKindMask ),
@ -468,7 +461,9 @@ NODE::OPT_OBSTACLE NODE::CheckColliding( const ITEM* aItemA, int aKindMask )
} }
} }
else if( QueryColliding( aItemA, obs, aKindMask, 1 ) > 0 ) else if( QueryColliding( aItemA, obs, aKindMask, 1 ) > 0 )
{
return OPT_OBSTACLE( obs[0] ); return OPT_OBSTACLE( obs[0] );
}
return OPT_OBSTACLE(); return OPT_OBSTACLE();
} }
@ -481,7 +476,8 @@ struct HIT_VISITOR : public OBSTACLE_VISITOR
HIT_VISITOR( ITEM_SET& aTab, const VECTOR2I& aPoint ) : HIT_VISITOR( ITEM_SET& aTab, const VECTOR2I& aPoint ) :
OBSTACLE_VISITOR( NULL ), OBSTACLE_VISITOR( NULL ),
m_items( aTab ), m_point( aPoint ) m_items( aTab ),
m_point( aPoint )
{} {}
virtual ~HIT_VISITOR() virtual ~HIT_VISITOR()
@ -539,12 +535,14 @@ void NODE::addSolid( SOLID* aSolid )
m_index->Add( aSolid ); m_index->Add( aSolid );
} }
void NODE::Add( std::unique_ptr< SOLID > aSolid ) void NODE::Add( std::unique_ptr< SOLID > aSolid )
{ {
aSolid->SetOwner( this ); aSolid->SetOwner( this );
addSolid( aSolid.release() ); addSolid( aSolid.release() );
} }
void NODE::addVia( VIA* aVia ) void NODE::addVia( VIA* aVia )
{ {
linkJoint( aVia->Pos(), aVia->Layers(), aVia->Net(), aVia ); linkJoint( aVia->Pos(), aVia->Layers(), aVia->Net(), aVia );
@ -552,12 +550,14 @@ void NODE::addVia( VIA* aVia )
m_index->Add( aVia ); m_index->Add( aVia );
} }
void NODE::Add( std::unique_ptr< VIA > aVia ) void NODE::Add( std::unique_ptr< VIA > aVia )
{ {
aVia->SetOwner( this ); aVia->SetOwner( this );
addVia( aVia.release() ); addVia( aVia.release() );
} }
void NODE::Add( LINE& aLine, bool aAllowRedundant ) void NODE::Add( LINE& aLine, bool aAllowRedundant )
{ {
assert( !aLine.IsLinked() ); assert( !aLine.IsLinked() );
@ -569,8 +569,8 @@ void NODE::Add( LINE& aLine, bool aAllowRedundant )
auto s = l.Arc( i ); auto s = l.Arc( i );
ARC* rarc; ARC* rarc;
if( !aAllowRedundant if( !aAllowRedundant && ( rarc = findRedundantArc( s.GetP0(), s.GetP1(), aLine.Layers(),
&& ( rarc = findRedundantArc( s.GetP0(), s.GetP1(), aLine.Layers(), aLine.Net() ) ) ) aLine.Net() ) ) )
{ {
aLine.Link( rarc ); aLine.Link( rarc );
} }
@ -593,8 +593,8 @@ void NODE::Add( LINE& aLine, bool aAllowRedundant )
{ {
SEGMENT* rseg; SEGMENT* rseg;
if( !aAllowRedundant if( !aAllowRedundant && ( rseg = findRedundantSegment( s.A, s.B, aLine.Layers(),
&& ( rseg = findRedundantSegment( s.A, s.B, aLine.Layers(), aLine.Net() ) ) ) aLine.Net() ) ) )
{ {
// another line could be referencing this segment too :( // another line could be referencing this segment too :(
aLine.Link( rseg ); aLine.Link( rseg );
@ -609,6 +609,7 @@ void NODE::Add( LINE& aLine, bool aAllowRedundant )
} }
} }
void NODE::addSegment( SEGMENT* aSeg ) void NODE::addSegment( SEGMENT* aSeg )
{ {
linkJoint( aSeg->Seg().A, aSeg->Layers(), aSeg->Net(), aSeg ); linkJoint( aSeg->Seg().A, aSeg->Layers(), aSeg->Net(), aSeg );
@ -617,6 +618,7 @@ void NODE::addSegment( SEGMENT* aSeg )
m_index->Add( aSeg ); m_index->Add( aSeg );
} }
bool NODE::Add( std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant ) bool NODE::Add( std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant )
{ {
if( aSegment->Seg().A == aSegment->Seg().B ) if( aSegment->Seg().A == aSegment->Seg().B )
@ -634,6 +636,7 @@ bool NODE::Add( std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant )
return true; return true;
} }
void NODE::addArc( ARC* aArc ) void NODE::addArc( ARC* aArc )
{ {
linkJoint( aArc->Anchor( 0 ), aArc->Layers(), aArc->Net(), aArc ); linkJoint( aArc->Anchor( 0 ), aArc->Layers(), aArc->Net(), aArc );
@ -642,12 +645,14 @@ void NODE::addArc( ARC* aArc )
m_index->Add( aArc ); m_index->Add( aArc );
} }
void NODE::Add( std::unique_ptr< ARC > aArc ) void NODE::Add( std::unique_ptr< ARC > aArc )
{ {
aArc->SetOwner( this ); aArc->SetOwner( this );
addArc( aArc.release() ); addArc( aArc.release() );
} }
void NODE::Add( std::unique_ptr< ITEM > aItem, bool aAllowRedundant ) void NODE::Add( std::unique_ptr< ITEM > aItem, bool aAllowRedundant )
{ {
switch( aItem->Kind() ) switch( aItem->Kind() )
@ -705,8 +710,9 @@ void NODE::removeArcIndex( ARC* aArc )
void NODE::rebuildJoint( JOINT* aJoint, ITEM* aItem ) void NODE::rebuildJoint( JOINT* aJoint, ITEM* aItem )
{ {
// We have to split a single joint (associated with a via or a pad, binding together multiple layers) // We have to split a single joint (associated with a via or a pad, binding together multiple
// into multiple independent joints. As I'm a lazy bastard, I simply delete the via/solid and all its links and re-insert them. // layers) into multiple independent joints. As I'm a lazy bastard, I simply delete the
// via/solid and all its links and re-insert them.
JOINT::LINKED_ITEMS links( aJoint->LinkList() ); JOINT::LINKED_ITEMS links( aJoint->LinkList() );
JOINT::HASH_TAG tag; JOINT::HASH_TAG tag;
@ -772,36 +778,42 @@ void NODE::Replace( ITEM* aOldItem, std::unique_ptr< ITEM > aNewItem )
Add( std::move( aNewItem ) ); Add( std::move( aNewItem ) );
} }
void NODE::Replace( LINE& aOldLine, LINE& aNewLine ) void NODE::Replace( LINE& aOldLine, LINE& aNewLine )
{ {
Remove( aOldLine ); Remove( aOldLine );
Add( aNewLine ); Add( aNewLine );
} }
void NODE::Remove( SOLID* aSolid ) void NODE::Remove( SOLID* aSolid )
{ {
removeSolidIndex( aSolid ); removeSolidIndex( aSolid );
doRemove( aSolid ); doRemove( aSolid );
} }
void NODE::Remove( VIA* aVia ) void NODE::Remove( VIA* aVia )
{ {
removeViaIndex( aVia ); removeViaIndex( aVia );
doRemove( aVia ); doRemove( aVia );
} }
void NODE::Remove( SEGMENT* aSegment ) void NODE::Remove( SEGMENT* aSegment )
{ {
removeSegmentIndex( aSegment ); removeSegmentIndex( aSegment );
doRemove( aSegment ); doRemove( aSegment );
} }
void NODE::Remove( ARC* aArc ) void NODE::Remove( ARC* aArc )
{ {
removeArcIndex( aArc ); removeArcIndex( aArc );
doRemove( aArc ); doRemove( aArc );
} }
void NODE::Remove( ITEM* aItem ) void NODE::Remove( ITEM* aItem )
{ {
switch( aItem->Kind() ) switch( aItem->Kind() )
@ -820,9 +832,9 @@ void NODE::Remove( ITEM* aItem )
case ITEM::LINE_T: case ITEM::LINE_T:
{ {
auto l = static_cast<LINE *> ( aItem ); LINE* l = static_cast<LINE*>( aItem );
for ( auto s : l->Links() ) for ( LINKED_ITEM* s : l->Links() )
Remove( s ); Remove( s );
break; break;
@ -843,7 +855,7 @@ void NODE::Remove( LINE& aLine )
// LINE does not have a seperate remover, as LINEs are never truly a member of the tree // LINE does not have a seperate remover, as LINEs are never truly a member of the tree
std::vector<LINKED_ITEM*>& segRefs = aLine.Links(); std::vector<LINKED_ITEM*>& segRefs = aLine.Links();
for( auto li : segRefs ) for( LINKED_ITEM* li : segRefs )
{ {
if( li->OfKind( ITEM::SEGMENT_T ) ) if( li->OfKind( ITEM::SEGMENT_T ) )
Remove( static_cast<SEGMENT*>( li ) ); Remove( static_cast<SEGMENT*>( li ) );
@ -856,8 +868,9 @@ void NODE::Remove( LINE& aLine )
} }
void NODE::followLine( LINKED_ITEM* aCurrent, int aScanDirection, int& aPos, int aLimit, VECTOR2I* aCorners, void NODE::followLine( LINKED_ITEM* aCurrent, int aScanDirection, int& aPos, int aLimit,
LINKED_ITEM** aSegments, bool& aGuardHit, bool aStopAtLockedJoints ) VECTOR2I* aCorners, LINKED_ITEM** aSegments, bool& aGuardHit,
bool aStopAtLockedJoints )
{ {
bool prevReversed = false; bool prevReversed = false;
@ -893,7 +906,8 @@ void NODE::followLine( LINKED_ITEM* aCurrent, int aScanDirection, int& aPos, int
} }
const LINE NODE::AssembleLine( LINKED_ITEM* aSeg, int* aOriginSegmentIndex, bool aStopAtLockedJoints ) const LINE NODE::AssembleLine( LINKED_ITEM* aSeg, int* aOriginSegmentIndex,
bool aStopAtLockedJoints )
{ {
const int MaxVerts = 1024 * 16; const int MaxVerts = 1024 * 16;
@ -955,44 +969,6 @@ void NODE::FindLineEnds( const LINE& aLine, JOINT& aA, JOINT& aB )
} }
#if 0
void NODE::MapConnectivity( JOINT* aStart, std::vector<JOINT*>& aFoundJoints )
{
std::deque<JOINT*> searchQueue;
std::set<JOINT*> processed;
searchQueue.push_back( aStart );
processed.insert( aStart );
while( !searchQueue.empty() )
{
JOINT* current = searchQueue.front();
searchQueue.pop_front();
for( ITEM* item : current->LinkList() )
{
if( item->OfKind( ITEM::SEGMENT_T ) )
{
SEGMENT* seg = static_cast<SEGMENT *>( item );
JOINT* a = FindJoint( seg->Seg().A, seg );
JOINT* b = FindJoint( seg->Seg().B, seg );
JOINT* next = ( *a == *current ) ? b : a;
if( processed.find( next ) == processed.end() )
{
processed.insert( next );
searchQueue.push_back( next );
}
}
}
}
for(JOINT* jt : processed)
aFoundJoints.push_back( jt );
}
#endif
int NODE::FindLinesBetweenJoints( const JOINT& aA, const JOINT& aB, std::vector<LINE>& aLines ) int NODE::FindLinesBetweenJoints( const JOINT& aA, const JOINT& aB, std::vector<LINE>& aLines )
{ {
for( ITEM* item : aA.LinkList() ) for( ITEM* item : aA.LinkList() )
@ -1117,13 +1093,16 @@ JOINT& NODE::touchJoint( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, int a
void JOINT::Dump() const void JOINT::Dump() const
{ {
wxLogTrace( "PNS", "joint layers %d-%d, net %d, pos %s, links: %d", m_layers.Start(), wxLogTrace( "PNS", "joint layers %d-%d, net %d, pos %s, links: %d",
m_layers.End(), m_tag.net, m_tag.pos.Format().c_str(), LinkCount() ); m_layers.Start(),
m_layers.End(),
m_tag.net,
m_tag.pos.Format().c_str(),
LinkCount() );
} }
void NODE::linkJoint( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, void NODE::linkJoint( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, int aNet, ITEM* aWhere )
int aNet, ITEM* aWhere )
{ {
JOINT& jt = touchJoint( aPos, aLayers, aNet ); JOINT& jt = touchJoint( aPos, aLayers, aNet );
@ -1131,8 +1110,7 @@ void NODE::linkJoint( const VECTOR2I& aPos, const LAYER_RANGE& aLayers,
} }
void NODE::unlinkJoint( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, void NODE::unlinkJoint( const VECTOR2I& aPos, const LAYER_RANGE& aLayers, int aNet, ITEM* aWhere )
int aNet, ITEM* aWhere )
{ {
// fixme: remove dangling joints // fixme: remove dangling joints
JOINT& jt = touchJoint( aPos, aLayers, aNet ); JOINT& jt = touchJoint( aPos, aLayers, aNet );
@ -1240,6 +1218,7 @@ void NODE::GetUpdatedItems( ITEM_VECTOR& aRemoved, ITEM_VECTOR& aAdded )
aAdded.push_back( *i ); aAdded.push_back( *i );
} }
void NODE::releaseChildren() void NODE::releaseChildren()
{ {
// copy the kids as the NODE destructor erases the item from the parent node. // copy the kids as the NODE destructor erases the item from the parent node.

View File

@ -2,7 +2,7 @@
* KiRouter - a push-and-(sometimes-)shove PCB router * KiRouter - a push-and-(sometimes-)shove PCB router
* *
* Copyright (C) 2013-2014 CERN * Copyright (C) 2013-2014 CERN
* Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
@ -52,7 +52,8 @@ class NODE;
/** /**
* RULE_RESOLVER * RULE_RESOLVER
* *
* An abstract function object, returning a design rule (clearance, diff pair gap, etc) required between two items. * An abstract function object, returning a design rule (clearance, diff pair gap, etc) required
* between two items.
**/ **/
enum class CONSTRAINT_TYPE enum class CONSTRAINT_TYPE
@ -71,11 +72,11 @@ enum class CONSTRAINT_TYPE
struct CONSTRAINT struct CONSTRAINT
{ {
CONSTRAINT_TYPE m_Type; CONSTRAINT_TYPE m_Type;
MINOPTMAX<int> m_Value; MINOPTMAX<int> m_Value;
bool m_Allowed; bool m_Allowed;
wxString m_RuleName; wxString m_RuleName;
wxString m_FromName; wxString m_FromName;
wxString m_ToName; wxString m_ToName;
}; };
class RULE_RESOLVER class RULE_RESOLVER
@ -93,7 +94,9 @@ public:
virtual bool IsDiffPair( const ITEM* aA, const ITEM* aB ) = 0; virtual bool IsDiffPair( const ITEM* aA, const ITEM* aB ) = 0;
virtual bool QueryConstraint( CONSTRAINT_TYPE aType, const PNS::ITEM* aItemA, const PNS::ITEM* aItemB, int aLayer, PNS::CONSTRAINT* aConstraint ) = 0; virtual bool QueryConstraint( CONSTRAINT_TYPE aType, const PNS::ITEM* aItemA,
const PNS::ITEM* aItemB, int aLayer,
PNS::CONSTRAINT* aConstraint ) = 0;
virtual wxString NetName( int aNet ) = 0; virtual wxString NetName( int aNet ) = 0;
}; };
@ -101,34 +104,24 @@ public:
/** /**
* Struct OBSTACLE * Struct OBSTACLE
* *
* Holds an object colliding with another object, along with * Holds an object colliding with another object, along with some useful data about the collision.
* some useful data about the collision.
**/ **/
struct OBSTACLE struct OBSTACLE
{ {
///> Item we search collisions with const ITEM* m_head; ///> Item we search collisions with
const ITEM* m_head;
///> Item found to be colliding with m_head ITEM* m_item; ///> Item found to be colliding with m_head
ITEM* m_item; SHAPE_LINE_CHAIN m_hull; ///> Hull of the colliding m_item
VECTOR2I m_ipFirst; ///> First intersection between m_head and m_hull
///> Hull of the colliding m_item int m_distFirst; ///> ... and the distance thereof
SHAPE_LINE_CHAIN m_hull;
///> First intersection point between the head item and the hull of the colliding m_item
VECTOR2I m_ipFirst;
///> ... and the distance thereof
int m_distFirst;
}; };
/** /**
* Struct OBSTACLE_VISITOR * Struct OBSTACLE_VISITOR
**/ **/
class OBSTACLE_VISITOR { class OBSTACLE_VISITOR
{
public: public:
OBSTACLE_VISITOR( const ITEM* aItem ); OBSTACLE_VISITOR( const ITEM* aItem );
virtual ~OBSTACLE_VISITOR() virtual ~OBSTACLE_VISITOR()
@ -140,27 +133,20 @@ public:
virtual bool operator()( ITEM* aCandidate ) = 0; virtual bool operator()( ITEM* aCandidate ) = 0;
protected: protected:
bool visit( ITEM* aCandidate ); bool visit( ITEM* aCandidate );
///> the item we are looking for collisions with protected:
const ITEM* m_item; const ITEM* m_item; ///> the item we are looking for collisions with
///> node we are searching in (either root or a branch) const NODE* m_node; ///> node we are searching in (either root or a branch)
const NODE* m_node; const NODE* m_override; ///> node that overrides root entries
int m_extraClearance; ///> additional clearance
///> node that overrides root entries
const NODE* m_override;
///> additional clearance
int m_extraClearance;
}; };
/** /**
* NODE * NODE
* *
* Keeps the router "world" - i.e. all the tracks, vias, solids in a * Keeps the router "world" - i.e. all the tracks, vias, solids in a hierarchical and indexed way.
* hierarchical and indexed way.
* Features: * Features:
* - spatial-indexed container for PCB item shapes * - spatial-indexed container for PCB item shapes
* - collision search & clearance checking * - collision search & clearance checking
@ -171,9 +157,9 @@ protected:
class NODE class NODE
{ {
public: public:
typedef OPT<OBSTACLE> OPT_OBSTACLE; typedef OPT<OBSTACLE> OPT_OBSTACLE;
typedef std::vector<ITEM*> ITEM_VECTOR; typedef std::vector<ITEM*> ITEM_VECTOR;
typedef std::vector<OBSTACLE> OBSTACLES; typedef std::vector<OBSTACLE> OBSTACLES;
NODE(); NODE();
~NODE(); ~NODE();
@ -242,8 +228,8 @@ public:
/** /**
* Function NearestObstacle() * Function NearestObstacle()
* *
* Follows the line in search of an obstacle that is nearest to the starting to the line's starting * Follows the line in search of an obstacle that is nearest to the starting to the line's
* point. * starting point.
* @param aLine the item to find collisions with * @param aLine the item to find collisions with
* @param aKindMask mask of obstacle types to take into account * @param aKindMask mask of obstacle types to take into account
* @return the obstacle, if found, otherwise empty. * @return the obstacle, if found, otherwise empty.
@ -255,8 +241,8 @@ public:
/** /**
* Function CheckColliding() * Function CheckColliding()
* *
* Checks if the item collides with anything else in the world, * Checks if the item collides with anything else in the world, and if found, returns the
* and if found, returns the obstacle. * obstacle.
* @param aItem the item to find collisions with * @param aItem the item to find collisions with
* @param aKindMask mask of obstacle types to take into account * @param aKindMask mask of obstacle types to take into account
* @return the obstacle, if found, otherwise empty. * @return the obstacle, if found, otherwise empty.
@ -268,8 +254,8 @@ public:
/** /**
* Function CheckColliding() * Function CheckColliding()
* *
* Checks if any item in the set collides with anything else in the world, * Checks if any item in the set collides with anything else in the world, and if found,
* and if found, returns the obstacle. * returns the obstacle.
* @param aSet set of items to find collisions with * @param aSet set of items to find collisions with
* @param aKindMask mask of obstacle types to take into account * @param aKindMask mask of obstacle types to take into account
* @return the obstacle, if found, otherwise empty. * @return the obstacle, if found, otherwise empty.
@ -292,8 +278,8 @@ public:
* Adds an item to the current node. * Adds an item to the current node.
* @param aSegment item to add * @param aSegment item to add
* @param aAllowRedundant if true, duplicate items are allowed (e.g. a segment or via * @param aAllowRedundant if true, duplicate items are allowed (e.g. a segment or via
* at the same coordinates as an existing one)
* @return true if added * @return true if added
* at the same coordinates as an existing one)
*/ */
bool Add( std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant = false ); bool Add( std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant = false );
void Add( std::unique_ptr< SOLID > aSolid ); void Add( std::unique_ptr< SOLID > aSolid );
@ -339,9 +325,9 @@ public:
/** /**
* Function Branch() * Function Branch()
* *
* Creates a lightweight copy (called branch) of self that tracks * Creates a lightweight copy (called branch) of self that tracks the changes (added/removed
* the changes (added/removed items) wrs to the root. Note that if there are * items) wrs to the root. Note that if there are any branches in use, their parents must NOT
* any branches in use, their parents must NOT be deleted. * be deleted.
* @return the new branch * @return the new branch
*/ */
NODE* Branch(); NODE* Branch();
@ -349,8 +335,8 @@ public:
/** /**
* Function AssembleLine() * Function AssembleLine()
* *
* Follows the joint map to assemble a line connecting two non-trivial * Follows the joint map to assemble a line connecting two non-trivial joints starting from
* joints starting from segment aSeg. * segment aSeg.
* @param aSeg the initial segment * @param aSeg the initial segment
* @param aOriginSegmentIndex index of aSeg in the resulting line * @param aOriginSegmentIndex index of aSeg in the resulting line
* @return the line * @return the line
@ -364,8 +350,7 @@ public:
/** /**
* Function GetUpdatedItems() * Function GetUpdatedItems()
* *
* Returns the lists of items removed and added in this branch, with * Returns the list of items removed and added in this branch with respect to the root branch.
* respect to the root branch.
* @param aRemoved removed items * @param aRemoved removed items
* @param aAdded added items * @param aAdded added items
*/ */
@ -374,8 +359,8 @@ public:
/** /**
* Function Commit() * Function Commit()
* *
* Applies the changes from a given branch (aNode) to the root branch. Called on * Applies the changes from a given branch (aNode) to the root branch. Calling on a non-root
* a non-root branch will fail. Calling commit also kills all children nodes of the root branch. * branch will fail. Calling commit also kills all children nodes of the root branch.
* @param aNode node to commit changes from * @param aNode node to commit changes from
*/ */
void Commit( NODE* aNode ); void Commit( NODE* aNode );
@ -401,14 +386,6 @@ public:
return FindJoint( aPos, aItem->Layers().Start(), aItem->Net() ); return FindJoint( aPos, aItem->Layers().Start(), aItem->Net() );
} }
#if 0
void MapConnectivity( JOINT* aStart, std::vector<JOINT*> & aFoundJoints );
ITEM* NearestUnconnectedItem( JOINT* aStart, int* aAnchor = NULL,
int aKindMask = ITEM::ANY_T);
#endif
///> finds all lines between a pair of joints. Used by the loop removal procedure. ///> finds all lines between a pair of joints. Used by the loop removal procedure.
int FindLinesBetweenJoints( const JOINT& aA, int FindLinesBetweenJoints( const JOINT& aA,
const JOINT& aB, const JOINT& aB,
@ -438,8 +415,7 @@ public:
return m_parent; return m_parent;
} }
///> checks if this branch contains an updated version of the m_item ///> checks if this branch contains an updated version of the m_item from the root branch.
///> from the root branch.
bool Overrides( ITEM* aItem ) const bool Overrides( ITEM* aItem ) const
{ {
return m_override.find( aItem ) != m_override.end(); return m_override.find( aItem ) != m_override.end();
@ -471,7 +447,6 @@ private:
void addVia( VIA* aVia ); void addVia( VIA* aVia );
void addArc( ARC* aVia ); void addArc( ARC* aVia );
void removeLine( LINE& aLine );
void removeSolidIndex( SOLID* aSeg ); void removeSolidIndex( SOLID* aSeg );
void removeSegmentIndex( SEGMENT* aSeg ); void removeSegmentIndex( SEGMENT* aSeg );
void removeViaIndex( VIA* aVia ); void removeViaIndex( VIA* aVia );
@ -488,45 +463,34 @@ private:
return m_parent == NULL; return m_parent == NULL;
} }
SEGMENT* findRedundantSegment( const VECTOR2I& A, const VECTOR2I& B, SEGMENT* findRedundantSegment( const VECTOR2I& A, const VECTOR2I& B, const LAYER_RANGE& lr,
const LAYER_RANGE & lr, int aNet ); int aNet );
SEGMENT* findRedundantSegment( SEGMENT* aSeg ); SEGMENT* findRedundantSegment( SEGMENT* aSeg );
ARC* findRedundantArc( const VECTOR2I& A, const VECTOR2I& B, ARC* findRedundantArc( const VECTOR2I& A, const VECTOR2I& B, const LAYER_RANGE& lr, int aNet );
const LAYER_RANGE & lr, int aNet );
ARC* findRedundantArc( ARC* aSeg ); ARC* findRedundantArc( ARC* aSeg );
///> scans the joint map, forming a line starting from segment (current). ///> scans the joint map, forming a line starting from segment (current).
void followLine( LINKED_ITEM* aCurrent, int aScanDirection, int& aPos, int aLimit, VECTOR2I* aCorners, void followLine( LINKED_ITEM* aCurrent, int aScanDirection, int& aPos, int aLimit,
LINKED_ITEM** aSegments, bool& aGuardHit, bool aStopAtLockedJoints ); VECTOR2I* aCorners, LINKED_ITEM** aSegments, bool& aGuardHit,
bool aStopAtLockedJoints );
///> hash table with the joints, linking the items. Joints are hashed by private:
///> their position, layer set and net. JOINT_MAP m_joints; ///> hash table with the joints, linking the items. Joints
JOINT_MAP m_joints; ///> are hashed by their position, layer set and net.
///> node this node was branched from NODE* m_parent; ///> node this node was branched from
NODE* m_parent; NODE* m_root; ///> root node of the whole hierarchy
std::set<NODE*> m_children; ///> list of nodes branched from this one
///> root node of the whole hierarchy std::unordered_set<ITEM*> m_override; ///> hash of root's items that have been changed
NODE* m_root; ///> in this node
///> list of nodes branched from this one int m_maxClearance; ///> worst case item-item clearance
std::set<NODE*> m_children; RULE_RESOLVER* m_ruleResolver; ///> Design rules resolver
INDEX* m_index; ///> Geometric/Net index of the items
///> hash of root's items that have been changed in this node int m_depth; ///> depth of the node (number of parent nodes in the
std::unordered_set<ITEM*> m_override; ///> inheritance chain)
///> worst case item-item clearance
int m_maxClearance;
///> Design rules resolver
RULE_RESOLVER* m_ruleResolver;
///> Geometric/Net index of the items
INDEX* m_index;
///> depth of the node (number of parent nodes in the inheritance chain)
int m_depth;
std::unordered_set<ITEM*> m_garbageItems; std::unordered_set<ITEM*> m_garbageItems;
}; };