router: clearer distinction between LOGGER and DEBUG_DECORATOR classes.
The first one keeps a log of events (start routing, mouse motion, etc). The second allows for adding temporary debug drawings and messages which are stored synchronously with the events in LOGGER. The event stream together with the PCB design (now with UUIDs) can be used to deterministically replay routing bugs as the user sees them.
This commit is contained in:
parent
2a2e389a94
commit
379aa8f3b5
|
@ -38,6 +38,11 @@ public:
|
||||||
virtual ~DEBUG_DECORATOR()
|
virtual ~DEBUG_DECORATOR()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
virtual void SetIteration( int iter ) {};
|
||||||
|
virtual void Message( const wxString msg ) {};
|
||||||
|
virtual void NewStage( const std::string& name, int iter ) {};
|
||||||
|
virtual void BeginGroup( const std::string name ) {};
|
||||||
|
virtual void EndGroup( ) {};
|
||||||
virtual void AddPoint( VECTOR2I aP, int aColor, const std::string aName = "" ) {};
|
virtual void AddPoint( VECTOR2I aP, int aColor, const std::string aName = "" ) {};
|
||||||
virtual void AddLine( const SHAPE_LINE_CHAIN& aLine, int aType = 0, int aWidth = 0, const std::string aName = "" ) {};
|
virtual void AddLine( const SHAPE_LINE_CHAIN& aLine, int aType = 0, int aWidth = 0, const std::string aName = "" ) {};
|
||||||
virtual void AddSegment( SEG aS, int aColor, const std::string aName = "" ) {};
|
virtual void AddSegment( SEG aS, int aColor, const std::string aName = "" ) {};
|
||||||
|
|
|
@ -72,7 +72,7 @@ typedef VECTOR2I::extended_type ecoord;
|
||||||
class PNS_PCBNEW_RULE_RESOLVER : public PNS::RULE_RESOLVER
|
class PNS_PCBNEW_RULE_RESOLVER : public PNS::RULE_RESOLVER
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PNS_PCBNEW_RULE_RESOLVER( BOARD* aBoard, PNS::ROUTER* aRouter );
|
PNS_PCBNEW_RULE_RESOLVER( BOARD* aBoard, PNS::ROUTER_IFACE* aRouterIface );
|
||||||
virtual ~PNS_PCBNEW_RULE_RESOLVER();
|
virtual ~PNS_PCBNEW_RULE_RESOLVER();
|
||||||
|
|
||||||
virtual bool CollideHoles( const PNS::ITEM* aA, const PNS::ITEM* aB,
|
virtual bool CollideHoles( const PNS::ITEM* aA, const PNS::ITEM* aB,
|
||||||
|
@ -98,7 +98,7 @@ private:
|
||||||
int localPadClearance( const PNS::ITEM* aItem ) const;
|
int localPadClearance( const PNS::ITEM* aItem ) const;
|
||||||
int matchDpSuffix( const wxString& aNetName, wxString& aComplementNet, wxString& aBaseDpName );
|
int matchDpSuffix( const wxString& aNetName, wxString& aComplementNet, wxString& aBaseDpName );
|
||||||
|
|
||||||
PNS::ROUTER* m_router;
|
PNS::ROUTER_IFACE* m_routerIface;
|
||||||
BOARD* m_board;
|
BOARD* m_board;
|
||||||
|
|
||||||
std::vector<CLEARANCE_ENT> m_netClearanceCache;
|
std::vector<CLEARANCE_ENT> m_netClearanceCache;
|
||||||
|
@ -107,13 +107,10 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
PNS_PCBNEW_RULE_RESOLVER::PNS_PCBNEW_RULE_RESOLVER( BOARD* aBoard, PNS::ROUTER* aRouter ) :
|
PNS_PCBNEW_RULE_RESOLVER::PNS_PCBNEW_RULE_RESOLVER( BOARD* aBoard, PNS::ROUTER_IFACE* aRouterIface ) :
|
||||||
m_router( aRouter ),
|
m_routerIface( aRouterIface ),
|
||||||
m_board( aBoard )
|
m_board( aBoard )
|
||||||
{
|
{
|
||||||
PNS::NODE* world = m_router->GetWorld();
|
|
||||||
|
|
||||||
PNS::TOPOLOGY topo( world );
|
|
||||||
m_netClearanceCache.resize( m_board->GetNetCount() );
|
m_netClearanceCache.resize( m_board->GetNetCount() );
|
||||||
|
|
||||||
// Build clearance cache for net classes
|
// Build clearance cache for net classes
|
||||||
|
@ -535,9 +532,8 @@ PNS_KICAD_IFACE_BASE::PNS_KICAD_IFACE_BASE()
|
||||||
{
|
{
|
||||||
m_ruleResolver = nullptr;
|
m_ruleResolver = nullptr;
|
||||||
m_board = nullptr;
|
m_board = nullptr;
|
||||||
m_router = nullptr;
|
m_world = nullptr;
|
||||||
m_debugDecorator = nullptr;
|
m_debugDecorator = nullptr;
|
||||||
m_router = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -552,13 +548,14 @@ PNS_KICAD_IFACE::PNS_KICAD_IFACE()
|
||||||
|
|
||||||
PNS_KICAD_IFACE_BASE::~PNS_KICAD_IFACE_BASE()
|
PNS_KICAD_IFACE_BASE::~PNS_KICAD_IFACE_BASE()
|
||||||
{
|
{
|
||||||
delete m_ruleResolver;
|
|
||||||
delete m_debugDecorator;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PNS_KICAD_IFACE::~PNS_KICAD_IFACE()
|
PNS_KICAD_IFACE::~PNS_KICAD_IFACE()
|
||||||
{
|
{
|
||||||
|
delete m_ruleResolver;
|
||||||
|
delete m_debugDecorator;
|
||||||
|
|
||||||
if( m_previewItems )
|
if( m_previewItems )
|
||||||
{
|
{
|
||||||
m_previewItems->FreeItems();
|
m_previewItems->FreeItems();
|
||||||
|
@ -925,6 +922,8 @@ void PNS_KICAD_IFACE_BASE::SyncWorld( PNS::NODE *aWorld )
|
||||||
{
|
{
|
||||||
int worstPadClearance = 0;
|
int worstPadClearance = 0;
|
||||||
|
|
||||||
|
m_world = aWorld;
|
||||||
|
|
||||||
if( !m_board )
|
if( !m_board )
|
||||||
{
|
{
|
||||||
wxLogTrace( "PNS", "No board attached, aborting sync." );
|
wxLogTrace( "PNS", "No board attached, aborting sync." );
|
||||||
|
@ -1004,7 +1003,7 @@ void PNS_KICAD_IFACE_BASE::SyncWorld( PNS::NODE *aWorld )
|
||||||
int worstRuleClearance = m_board->GetDesignSettings().GetBiggestClearanceValue();
|
int worstRuleClearance = m_board->GetDesignSettings().GetBiggestClearanceValue();
|
||||||
|
|
||||||
delete m_ruleResolver;
|
delete m_ruleResolver;
|
||||||
m_ruleResolver = new PNS_PCBNEW_RULE_RESOLVER( m_board, m_router );
|
m_ruleResolver = new PNS_PCBNEW_RULE_RESOLVER( m_board, this );
|
||||||
|
|
||||||
aWorld->SetRuleResolver( m_ruleResolver );
|
aWorld->SetRuleResolver( m_ruleResolver );
|
||||||
aWorld->SetMaxClearance( 4 * std::max(worstPadClearance, worstRuleClearance ) );
|
aWorld->SetMaxClearance( 4 * std::max(worstPadClearance, worstRuleClearance ) );
|
||||||
|
@ -1261,12 +1260,6 @@ PNS::RULE_RESOLVER* PNS_KICAD_IFACE_BASE::GetRuleResolver()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PNS_KICAD_IFACE_BASE::SetRouter( PNS::ROUTER* aRouter )
|
|
||||||
{
|
|
||||||
m_router = aRouter;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PNS_KICAD_IFACE::SetHostTool( PCB_TOOL_BASE* aTool )
|
void PNS_KICAD_IFACE::SetHostTool( PCB_TOOL_BASE* aTool )
|
||||||
{
|
{
|
||||||
m_tool = aTool;
|
m_tool = aTool;
|
||||||
|
|
|
@ -46,7 +46,6 @@ public:
|
||||||
PNS_KICAD_IFACE_BASE();
|
PNS_KICAD_IFACE_BASE();
|
||||||
~PNS_KICAD_IFACE_BASE();
|
~PNS_KICAD_IFACE_BASE();
|
||||||
|
|
||||||
void SetRouter( PNS::ROUTER* aRouter ) override;
|
|
||||||
void SetHostTool( PCB_TOOL_BASE* aTool );
|
void SetHostTool( PCB_TOOL_BASE* aTool );
|
||||||
void SetDisplayOptions( const PCB_DISPLAY_OPTIONS* aDispOptions );
|
void SetDisplayOptions( const PCB_DISPLAY_OPTIONS* aDispOptions );
|
||||||
|
|
||||||
|
@ -65,6 +64,16 @@ public:
|
||||||
|
|
||||||
void SetDebugDecorator( PNS::DEBUG_DECORATOR *aDec );
|
void SetDebugDecorator( PNS::DEBUG_DECORATOR *aDec );
|
||||||
|
|
||||||
|
virtual PNS::NODE* GetWorld() const override
|
||||||
|
{
|
||||||
|
return m_world;
|
||||||
|
};
|
||||||
|
|
||||||
|
BOARD* GetBoard() const
|
||||||
|
{
|
||||||
|
return m_board;
|
||||||
|
}
|
||||||
|
|
||||||
PNS::RULE_RESOLVER* GetRuleResolver() override;
|
PNS::RULE_RESOLVER* GetRuleResolver() override;
|
||||||
PNS::DEBUG_DECORATOR* GetDebugDecorator() override;
|
PNS::DEBUG_DECORATOR* GetDebugDecorator() override;
|
||||||
|
|
||||||
|
@ -80,7 +89,7 @@ protected:
|
||||||
bool syncGraphicalItem( PNS::NODE* aWorld, DRAWSEGMENT* aItem );
|
bool syncGraphicalItem( PNS::NODE* aWorld, DRAWSEGMENT* aItem );
|
||||||
bool syncZone( PNS::NODE* aWorld, ZONE_CONTAINER* aZone );
|
bool syncZone( PNS::NODE* aWorld, ZONE_CONTAINER* aZone );
|
||||||
|
|
||||||
PNS::ROUTER* m_router;
|
PNS::NODE* m_world;
|
||||||
BOARD* m_board;
|
BOARD* m_board;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ namespace PNS {
|
||||||
|
|
||||||
LOGGER::LOGGER( )
|
LOGGER::LOGGER( )
|
||||||
{
|
{
|
||||||
m_groupOpened = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,162 +46,40 @@ LOGGER::~LOGGER()
|
||||||
|
|
||||||
void LOGGER::Clear()
|
void LOGGER::Clear()
|
||||||
{
|
{
|
||||||
m_theLog.str( std::string() );
|
m_events.clear();
|
||||||
m_groupOpened = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LOGGER::NewGroup( const std::string& aName, int aIter )
|
|
||||||
{
|
|
||||||
if( m_groupOpened )
|
|
||||||
m_theLog << "endgroup" << std::endl;
|
|
||||||
|
|
||||||
m_theLog << "group " << aName << " " << aIter << std::endl;
|
|
||||||
m_groupOpened = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LOGGER::EndGroup()
|
|
||||||
{
|
|
||||||
if( !m_groupOpened )
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_groupOpened = false;
|
|
||||||
m_theLog << "endgroup" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LOGGER::Log ( const ITEM* aItem, int aKind, const std::string& aName )
|
|
||||||
{
|
|
||||||
m_theLog << "item " << aKind << " " << aName << " ";
|
|
||||||
m_theLog << aItem->Net() << " " << aItem->Layers().Start() << " " <<
|
|
||||||
aItem->Layers().End() << " " << aItem->Marker() << " " << aItem->Rank();
|
|
||||||
|
|
||||||
switch( aItem->Kind() )
|
|
||||||
{
|
|
||||||
case ITEM::LINE_T:
|
|
||||||
{
|
|
||||||
LINE* l = (LINE*) aItem;
|
|
||||||
m_theLog << " line ";
|
|
||||||
m_theLog << l->Width() << " " << ( l->EndsWithVia() ? 1 : 0 ) << " ";
|
|
||||||
dumpShape ( l->Shape() );
|
|
||||||
m_theLog << std::endl;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ITEM::VIA_T:
|
|
||||||
{
|
|
||||||
m_theLog << " via 0 0 ";
|
|
||||||
dumpShape ( aItem->Shape() );
|
|
||||||
m_theLog << std::endl;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ITEM::SEGMENT_T:
|
|
||||||
{
|
|
||||||
SEGMENT* s =(SEGMENT*) aItem;
|
|
||||||
m_theLog << " line ";
|
|
||||||
m_theLog << s->Width() << " 0 linechain 2 0 " << s->Seg().A.x << " " <<
|
|
||||||
s->Seg().A.y << " " << s->Seg().B.x << " " <<s->Seg().B.y << std::endl;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ITEM::SOLID_T:
|
|
||||||
{
|
|
||||||
SOLID* s = (SOLID*) aItem;
|
|
||||||
m_theLog << " solid 0 0 ";
|
|
||||||
dumpShape( s->Shape() );
|
|
||||||
m_theLog << std::endl;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LOGGER::Log( const SHAPE_LINE_CHAIN *aL, int aKind, const std::string& aName )
|
|
||||||
{
|
|
||||||
m_theLog << "item " << aKind << " " << aName << " ";
|
|
||||||
m_theLog << 0 << " " << 0 << " " << 0 << " " << 0 << " " << 0;
|
|
||||||
m_theLog << " line ";
|
|
||||||
m_theLog << 0 << " " << 0 << " ";
|
|
||||||
dumpShape( aL );
|
|
||||||
m_theLog << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LOGGER::Log( const VECTOR2I& aStart, const VECTOR2I& aEnd,
|
|
||||||
int aKind, const std::string& aName)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LOGGER::dumpShape( const SHAPE* aSh )
|
|
||||||
{
|
|
||||||
switch( aSh->Type() )
|
|
||||||
{
|
|
||||||
case SH_LINE_CHAIN:
|
|
||||||
{
|
|
||||||
const SHAPE_LINE_CHAIN* lc = (const SHAPE_LINE_CHAIN*) aSh;
|
|
||||||
m_theLog << "linechain " << lc->PointCount() << " " << ( lc->IsClosed() ? 1 : 0 ) << " ";
|
|
||||||
|
|
||||||
for( int i = 0; i < lc->PointCount(); i++ )
|
|
||||||
m_theLog << lc->CPoint( i ).x << " " << lc->CPoint( i ).y << " ";
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SH_CIRCLE:
|
|
||||||
{
|
|
||||||
const SHAPE_CIRCLE *c = (const SHAPE_CIRCLE*) aSh;
|
|
||||||
m_theLog << "circle " << c->GetCenter().x << " " << c->GetCenter().y << " " << c->GetRadius();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SH_RECT:
|
|
||||||
{
|
|
||||||
const SHAPE_RECT* r = (const SHAPE_RECT*) aSh;
|
|
||||||
m_theLog << "rect " << r->GetPosition().x << " " << r->GetPosition().y << " " <<
|
|
||||||
r->GetSize().x << " " <<r->GetSize().y;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SH_SEGMENT:
|
|
||||||
{
|
|
||||||
const SHAPE_SEGMENT* s = (const SHAPE_SEGMENT*) aSh;
|
|
||||||
m_theLog << "linechain 2 0 " << s->GetSeg().A.x << " " << s->GetSeg().A.y << " " <<
|
|
||||||
s->GetSeg().B.x << " " << s->GetSeg().B.y;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SH_SIMPLE:
|
|
||||||
{
|
|
||||||
const SHAPE_SIMPLE* c = (const SHAPE_SIMPLE*) aSh;
|
|
||||||
m_theLog << "convex " << c->PointCount() << " ";
|
|
||||||
|
|
||||||
for( int i = 0; i < c->PointCount(); i++ )
|
|
||||||
m_theLog << c->CPoint( i ).x << " " << c->CPoint( i ).y << " ";
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LOGGER::Save( const std::string& aFilename )
|
void LOGGER::Save( const std::string& aFilename )
|
||||||
{
|
{
|
||||||
EndGroup();
|
|
||||||
|
|
||||||
FILE* f = fopen( aFilename.c_str(), "wb" );
|
FILE* f = fopen( aFilename.c_str(), "wb" );
|
||||||
|
|
||||||
wxLogTrace( "PNS", "Saving to '%s' [%p]", aFilename.c_str(), f );
|
wxLogTrace( "PNS", "Saving to '%s' [%p]", aFilename.c_str(), f );
|
||||||
const std::string s = m_theLog.str();
|
|
||||||
fwrite( s.c_str(), 1, s.length(), f );
|
for( const auto evt : m_events )
|
||||||
|
{
|
||||||
|
uint64_t id = 0;
|
||||||
|
if( evt.item && evt.item->Parent() )
|
||||||
|
{
|
||||||
|
const char* idString = evt.item->Parent()->m_Uuid.AsString().c_str();
|
||||||
|
fprintf( f, "event %d %d %d %s\n", evt.type, evt.p.x, evt.p.y, idString );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fclose( f );
|
fclose( f );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LOGGER::Log( LOGGER::EVENT_TYPE evt, VECTOR2I pos, const ITEM* item )
|
||||||
|
{
|
||||||
|
LOGGER::EVENT_ENTRY ent;
|
||||||
|
|
||||||
|
ent.type = evt;
|
||||||
|
ent.p = pos;
|
||||||
|
ent.item = item;
|
||||||
|
|
||||||
|
m_events.push_back( ent );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,25 +39,35 @@ class ITEM;
|
||||||
class LOGGER
|
class LOGGER
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum EVENT_TYPE {
|
||||||
|
EVT_START_ROUTE = 0,
|
||||||
|
EVT_START_DRAG,
|
||||||
|
EVT_FIX,
|
||||||
|
EVT_MOVE,
|
||||||
|
EVT_ABORT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EVENT_ENTRY {
|
||||||
|
VECTOR2I p;
|
||||||
|
EVENT_TYPE type;
|
||||||
|
const ITEM* item;
|
||||||
|
};
|
||||||
|
|
||||||
LOGGER();
|
LOGGER();
|
||||||
~LOGGER();
|
~LOGGER();
|
||||||
|
|
||||||
void Save( const std::string& aFilename );
|
void Save( const std::string& aFilename );
|
||||||
void Clear();
|
void Clear();
|
||||||
|
void Log( EVENT_TYPE evt, VECTOR2I pos, const ITEM* item = nullptr );
|
||||||
|
|
||||||
void NewGroup( const std::string& aName, int aIter = 0 );
|
const std::vector<EVENT_ENTRY>& GetEvents()
|
||||||
void EndGroup();
|
{
|
||||||
|
return m_events;
|
||||||
void Log( const ITEM* aItem, int aKind = 0, const std::string& aName = std::string() );
|
}
|
||||||
void Log( const SHAPE_LINE_CHAIN *aL, int aKind = 0, const std::string& aName = std::string() );
|
|
||||||
void Log( const VECTOR2I& aStart, const VECTOR2I& aEnd, int aKind = 0,
|
|
||||||
const std::string& aName = std::string() );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void dumpShape( const SHAPE* aSh );
|
std::vector<EVENT_ENTRY> m_events;
|
||||||
|
|
||||||
bool m_groupOpened;
|
|
||||||
std::stringstream m_theLog;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,8 @@ ROUTER::ROUTER()
|
||||||
m_state = IDLE;
|
m_state = IDLE;
|
||||||
m_mode = PNS_MODE_ROUTE_SINGLE;
|
m_mode = PNS_MODE_ROUTE_SINGLE;
|
||||||
|
|
||||||
|
m_logger = new LOGGER;
|
||||||
|
|
||||||
// Initialize all other variables:
|
// Initialize all other variables:
|
||||||
m_lastNode = nullptr;
|
m_lastNode = nullptr;
|
||||||
m_iterLimit = 0;
|
m_iterLimit = 0;
|
||||||
|
@ -90,6 +92,7 @@ ROUTER::~ROUTER()
|
||||||
{
|
{
|
||||||
ClearWorld();
|
ClearWorld();
|
||||||
theRouter = nullptr;
|
theRouter = nullptr;
|
||||||
|
delete m_logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,6 +159,7 @@ bool ROUTER::StartDragging( const VECTOR2I& aP, ITEM_SET aStartItems, int aDragM
|
||||||
|
|
||||||
m_dragger->SetMode( aDragMode );
|
m_dragger->SetMode( aDragMode );
|
||||||
m_dragger->SetWorld( m_world.get() );
|
m_dragger->SetWorld( m_world.get() );
|
||||||
|
m_dragger->SetLogger( m_logger );
|
||||||
m_dragger->SetDebugDecorator ( m_iface->GetDebugDecorator () );
|
m_dragger->SetDebugDecorator ( m_iface->GetDebugDecorator () );
|
||||||
|
|
||||||
if( m_dragger->Start ( aP, aStartItems ) )
|
if( m_dragger->Start ( aP, aStartItems ) )
|
||||||
|
@ -224,6 +228,13 @@ bool ROUTER::StartRouting( const VECTOR2I& aP, ITEM* aStartItem, int aLayer )
|
||||||
m_placer->UpdateSizes ( m_sizes );
|
m_placer->UpdateSizes ( m_sizes );
|
||||||
m_placer->SetLayer( aLayer );
|
m_placer->SetLayer( aLayer );
|
||||||
m_placer->SetDebugDecorator ( m_iface->GetDebugDecorator () );
|
m_placer->SetDebugDecorator ( m_iface->GetDebugDecorator () );
|
||||||
|
m_placer->SetLogger( m_logger );
|
||||||
|
|
||||||
|
if( m_logger )
|
||||||
|
{
|
||||||
|
m_logger->Log( LOGGER::EVT_START_ROUTE, aP, aStartItem );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool rv = m_placer->Start( aP, aStartItem );
|
bool rv = m_placer->Start( aP, aStartItem );
|
||||||
|
|
||||||
|
@ -247,6 +258,11 @@ void ROUTER::Move( const VECTOR2I& aP, ITEM* endItem )
|
||||||
{
|
{
|
||||||
m_currentEnd = aP;
|
m_currentEnd = aP;
|
||||||
|
|
||||||
|
if( m_logger )
|
||||||
|
{
|
||||||
|
m_logger->Log( LOGGER::EVT_MOVE, aP, endItem );
|
||||||
|
}
|
||||||
|
|
||||||
switch( m_state )
|
switch( m_state )
|
||||||
{
|
{
|
||||||
case ROUTE_TRACK:
|
case ROUTE_TRACK:
|
||||||
|
@ -392,6 +408,11 @@ bool ROUTER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinish )
|
||||||
{
|
{
|
||||||
bool rv = false;
|
bool rv = false;
|
||||||
|
|
||||||
|
if( m_logger )
|
||||||
|
{
|
||||||
|
m_logger->Log( LOGGER::EVT_FIX, aP, aEndItem );
|
||||||
|
}
|
||||||
|
|
||||||
switch( m_state )
|
switch( m_state )
|
||||||
{
|
{
|
||||||
case ROUTE_TRACK:
|
case ROUTE_TRACK:
|
||||||
|
@ -505,26 +526,9 @@ int ROUTER::GetCurrentLayer() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ROUTER::DumpLog()
|
LOGGER* ROUTER::Logger()
|
||||||
{
|
{
|
||||||
LOGGER* logger = nullptr;
|
return m_logger;
|
||||||
|
|
||||||
switch( m_state )
|
|
||||||
{
|
|
||||||
case DRAG_SEGMENT:
|
|
||||||
logger = m_dragger->Logger();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ROUTE_TRACK:
|
|
||||||
logger = m_placer->Logger();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( logger )
|
|
||||||
logger->Save( "/tmp/shove.log" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -561,7 +565,6 @@ void ROUTER::SetMode( ROUTER_MODE aMode )
|
||||||
void ROUTER::SetInterface( ROUTER_IFACE *aIface )
|
void ROUTER::SetInterface( ROUTER_IFACE *aIface )
|
||||||
{
|
{
|
||||||
m_iface = aIface;
|
m_iface = aIface;
|
||||||
m_iface->SetRouter( this );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ROUTER::BreakSegment( ITEM *aItem, const VECTOR2I& aP )
|
void ROUTER::BreakSegment( ITEM *aItem, const VECTOR2I& aP )
|
||||||
|
|
|
@ -63,6 +63,7 @@ class RULE_RESOLVER;
|
||||||
class SHOVE;
|
class SHOVE;
|
||||||
class DRAGGER;
|
class DRAGGER;
|
||||||
class DRAG_ALGO;
|
class DRAG_ALGO;
|
||||||
|
class LOGGER;
|
||||||
|
|
||||||
enum ROUTER_MODE {
|
enum ROUTER_MODE {
|
||||||
PNS_MODE_ROUTE_SINGLE = 1,
|
PNS_MODE_ROUTE_SINGLE = 1,
|
||||||
|
@ -94,7 +95,6 @@ enum DRAG_MODE
|
||||||
ROUTER_IFACE() {};
|
ROUTER_IFACE() {};
|
||||||
virtual ~ROUTER_IFACE() {};
|
virtual ~ROUTER_IFACE() {};
|
||||||
|
|
||||||
virtual void SetRouter( ROUTER* aRouter ) = 0;
|
|
||||||
virtual void SyncWorld( NODE* aNode ) = 0;
|
virtual void SyncWorld( NODE* aNode ) = 0;
|
||||||
virtual void AddItem( ITEM* aItem ) = 0;
|
virtual void AddItem( ITEM* aItem ) = 0;
|
||||||
virtual void RemoveItem( ITEM* aItem ) = 0;
|
virtual void RemoveItem( ITEM* aItem ) = 0;
|
||||||
|
@ -108,6 +108,8 @@ enum DRAG_MODE
|
||||||
virtual void EraseView() = 0;
|
virtual void EraseView() = 0;
|
||||||
virtual void UpdateNet( int aNetCode ) = 0;
|
virtual void UpdateNet( int aNetCode ) = 0;
|
||||||
|
|
||||||
|
virtual PNS::NODE* GetWorld() const = 0;
|
||||||
|
|
||||||
virtual RULE_RESOLVER* GetRuleResolver() = 0;
|
virtual RULE_RESOLVER* GetRuleResolver() = 0;
|
||||||
virtual DEBUG_DECORATOR* GetDebugDecorator() = 0;
|
virtual DEBUG_DECORATOR* GetDebugDecorator() = 0;
|
||||||
};
|
};
|
||||||
|
@ -170,6 +172,7 @@ public:
|
||||||
const std::vector<int> GetCurrentNets() const;
|
const std::vector<int> GetCurrentNets() const;
|
||||||
|
|
||||||
void DumpLog();
|
void DumpLog();
|
||||||
|
LOGGER* Logger();
|
||||||
|
|
||||||
RULE_RESOLVER* GetRuleResolver() const
|
RULE_RESOLVER* GetRuleResolver() const
|
||||||
{
|
{
|
||||||
|
@ -280,6 +283,7 @@ private:
|
||||||
ROUTING_SETTINGS* m_settings;
|
ROUTING_SETTINGS* m_settings;
|
||||||
SIZES_SETTINGS m_sizes;
|
SIZES_SETTINGS m_sizes;
|
||||||
ROUTER_MODE m_mode;
|
ROUTER_MODE m_mode;
|
||||||
|
LOGGER* m_logger;
|
||||||
|
|
||||||
wxString m_toolStatusbarName;
|
wxString m_toolStatusbarName;
|
||||||
wxString m_failureReason;
|
wxString m_failureReason;
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
#include "time_limit.h"
|
#include "time_limit.h"
|
||||||
|
|
||||||
|
// fixme - move all logger calls to debug decorator
|
||||||
|
|
||||||
typedef VECTOR2I::extended_type ecoord;
|
typedef VECTOR2I::extended_type ecoord;
|
||||||
|
|
||||||
|
@ -235,6 +236,12 @@ SHOVE::SHOVE_STATUS SHOVE::processHullSet( LINE& aCurrent, LINE& aObstacle,
|
||||||
|
|
||||||
bool colliding = m_currentNode->CheckColliding( &l, &aCurrent, ITEM::ANY_T, m_forceClearance );
|
bool colliding = m_currentNode->CheckColliding( &l, &aCurrent, ITEM::ANY_T, m_forceClearance );
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
char str[128];
|
||||||
|
sprintf(str,"att-%d-shoved", attempt);
|
||||||
|
Dbg()->AddLine( l.CLine(), 3, 20000, str );
|
||||||
|
#endif
|
||||||
|
|
||||||
if( ( aCurrent.Marker() & MK_HEAD ) && !colliding )
|
if( ( aCurrent.Marker() & MK_HEAD ) && !colliding )
|
||||||
{
|
{
|
||||||
JOINT* jtStart = m_currentNode->FindJoint( aCurrent.CPoint( 0 ), &aCurrent );
|
JOINT* jtStart = m_currentNode->FindJoint( aCurrent.CPoint( 0 ), &aCurrent );
|
||||||
|
@ -294,6 +301,10 @@ SHOVE::SHOVE_STATUS SHOVE::ProcessSingleLine( LINE& aCurrent, LINE& aObstacle, L
|
||||||
|
|
||||||
int clearance = getClearance( &aCurrent, &aObstacle ) + 1;
|
int clearance = getClearance( &aCurrent, &aObstacle ) + 1;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
Dbg()->Message( wxString::Format( "shove process-single: cur net %d obs %d cl %d", aCurrent.Net(), aObstacle.Net(), clearance ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
HULL_SET hulls;
|
HULL_SET hulls;
|
||||||
|
|
||||||
hulls.reserve( n_segs + 1 );
|
hulls.reserve( n_segs + 1 );
|
||||||
|
@ -309,6 +320,12 @@ SHOVE::SHOVE_STATUS SHOVE::ProcessSingleLine( LINE& aCurrent, LINE& aObstacle, L
|
||||||
if( viaOnEnd )
|
if( viaOnEnd )
|
||||||
hulls.push_back( aCurrent.Via().Hull( clearance, w ) );
|
hulls.push_back( aCurrent.Via().Hull( clearance, w ) );
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
char str[128];
|
||||||
|
sprintf(str,"current-cl-%d", clearance );
|
||||||
|
Dbg()->AddLine( aCurrent.CLine(), 5, 20000, str );
|
||||||
|
#endif
|
||||||
|
|
||||||
rv = processHullSet( aCurrent, aObstacle, aShoved, hulls );
|
rv = processHullSet( aCurrent, aObstacle, aShoved, hulls );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,7 +365,7 @@ SHOVE::SHOVE_STATUS SHOVE::onCollidingSegment( LINE& aCurrent, SEGMENT* aObstacl
|
||||||
|
|
||||||
assert( obstacleLine.LayersOverlap( &shovedLine ) );
|
assert( obstacleLine.LayersOverlap( &shovedLine ) );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if 0
|
||||||
m_logger.NewGroup( "on-colliding-segment", m_iter );
|
m_logger.NewGroup( "on-colliding-segment", m_iter );
|
||||||
m_logger.Log( &tmp, 0, "obstacle-segment" );
|
m_logger.Log( &tmp, 0, "obstacle-segment" );
|
||||||
m_logger.Log( &aCurrent, 1, "current-line" );
|
m_logger.Log( &aCurrent, 1, "current-line" );
|
||||||
|
@ -409,7 +426,7 @@ SHOVE::SHOVE_STATUS SHOVE::onCollidingArc( LINE& aCurrent, ARC* aObstacleArc )
|
||||||
|
|
||||||
assert( obstacleLine.LayersOverlap( &shovedLine ) );
|
assert( obstacleLine.LayersOverlap( &shovedLine ) );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if 0
|
||||||
m_logger.NewGroup( "on-colliding-segment", m_iter );
|
m_logger.NewGroup( "on-colliding-segment", m_iter );
|
||||||
m_logger.Log( &tmp, 0, "obstacle-segment" );
|
m_logger.Log( &tmp, 0, "obstacle-segment" );
|
||||||
m_logger.Log( &aCurrent, 1, "current-line" );
|
m_logger.Log( &aCurrent, 1, "current-line" );
|
||||||
|
@ -450,7 +467,7 @@ SHOVE::SHOVE_STATUS SHOVE::onCollidingLine( LINE& aCurrent, LINE& aObstacle )
|
||||||
|
|
||||||
SHOVE_STATUS rv = ProcessSingleLine( aCurrent, aObstacle, shovedLine );
|
SHOVE_STATUS rv = ProcessSingleLine( aCurrent, aObstacle, shovedLine );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if 0
|
||||||
m_logger.NewGroup( "on-colliding-line", m_iter );
|
m_logger.NewGroup( "on-colliding-line", m_iter );
|
||||||
m_logger.Log( &aObstacle, 0, "obstacle-line" );
|
m_logger.Log( &aObstacle, 0, "obstacle-line" );
|
||||||
m_logger.Log( &aCurrent, 1, "current-line" );
|
m_logger.Log( &aCurrent, 1, "current-line" );
|
||||||
|
@ -518,7 +535,7 @@ SHOVE::SHOVE_STATUS SHOVE::onCollidingSolid( LINE& aCurrent, ITEM* aObstacle )
|
||||||
|
|
||||||
std::set<ITEM*> cluster = topo.AssembleCluster( aObstacle, aCurrent.Layers().Start() );
|
std::set<ITEM*> cluster = topo.AssembleCluster( aObstacle, aCurrent.Layers().Start() );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if 0
|
||||||
m_logger.NewGroup( "on-colliding-solid-cluster", m_iter );
|
m_logger.NewGroup( "on-colliding-solid-cluster", m_iter );
|
||||||
for( ITEM* item : cluster )
|
for( ITEM* item : cluster )
|
||||||
{
|
{
|
||||||
|
@ -600,7 +617,7 @@ SHOVE::SHOVE_STATUS SHOVE::onCollidingSolid( LINE& aCurrent, ITEM* aObstacle )
|
||||||
replaceLine( aCurrent, walkaroundLine );
|
replaceLine( aCurrent, walkaroundLine );
|
||||||
walkaroundLine.SetRank( nextRank );
|
walkaroundLine.SetRank( nextRank );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if 0
|
||||||
m_logger.NewGroup( "on-colliding-solid", m_iter );
|
m_logger.NewGroup( "on-colliding-solid", m_iter );
|
||||||
m_logger.Log( aObstacle, 0, "obstacle-solid" );
|
m_logger.Log( aObstacle, 0, "obstacle-solid" );
|
||||||
m_logger.Log( &aCurrent, 1, "current-line" );
|
m_logger.Log( &aCurrent, 1, "current-line" );
|
||||||
|
@ -749,13 +766,13 @@ SHOVE::SHOVE_STATUS SHOVE::pushOrShoveVia( VIA* aVia, const VECTOR2I& aForce, in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if 0
|
||||||
m_logger.Log( aVia, 0, "obstacle-via" );
|
m_logger.Log( aVia, 0, "obstacle-via" );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pushedVia->SetRank( aCurrentRank - 1 );
|
pushedVia->SetRank( aCurrentRank - 1 );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if 0
|
||||||
m_logger.Log( pushedVia.get(), 1, "pushed-via" );
|
m_logger.Log( pushedVia.get(), 1, "pushed-via" );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -798,7 +815,7 @@ SHOVE::SHOVE_STATUS SHOVE::pushOrShoveVia( VIA* aVia, const VECTOR2I& aForce, in
|
||||||
m_currentNode->Remove( lp.first );
|
m_currentNode->Remove( lp.first );
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if 0
|
||||||
m_logger.Log( &lp.first, 2, "fan-pre" );
|
m_logger.Log( &lp.first, 2, "fan-pre" );
|
||||||
m_logger.Log( &lp.second, 3, "fan-post" );
|
m_logger.Log( &lp.second, 3, "fan-post" );
|
||||||
#endif
|
#endif
|
||||||
|
@ -829,7 +846,7 @@ SHOVE::SHOVE_STATUS SHOVE::onCollidingVia( ITEM* aCurrent, VIA* aObstacleVia )
|
||||||
|
|
||||||
if( aCurrent->OfKind( ITEM::LINE_T ) )
|
if( aCurrent->OfKind( ITEM::LINE_T ) )
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#if 0
|
||||||
m_logger.NewGroup( "push-via-by-line", m_iter );
|
m_logger.NewGroup( "push-via-by-line", m_iter );
|
||||||
m_logger.Log( aCurrent, 4, "current" );
|
m_logger.Log( aCurrent, 4, "current" );
|
||||||
#endif
|
#endif
|
||||||
|
@ -913,7 +930,7 @@ SHOVE::SHOVE_STATUS SHOVE::onReverseCollidingVia( LINE& aCurrent, VIA* aObstacle
|
||||||
|
|
||||||
if( st != SH_OK )
|
if( st != SH_OK )
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#if 0
|
||||||
m_logger.NewGroup( "on-reverse-via-fail-shove", m_iter );
|
m_logger.NewGroup( "on-reverse-via-fail-shove", m_iter );
|
||||||
m_logger.Log( aObstacleVia, 0, "the-via" );
|
m_logger.Log( aObstacleVia, 0, "the-via" );
|
||||||
m_logger.Log( &aCurrent, 1, "current-line" );
|
m_logger.Log( &aCurrent, 1, "current-line" );
|
||||||
|
@ -930,7 +947,7 @@ SHOVE::SHOVE_STATUS SHOVE::onReverseCollidingVia( LINE& aCurrent, VIA* aObstacle
|
||||||
|
|
||||||
if( !n )
|
if( !n )
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#if 0
|
||||||
m_logger.NewGroup( "on-reverse-via-fail-lonevia", m_iter );
|
m_logger.NewGroup( "on-reverse-via-fail-lonevia", m_iter );
|
||||||
m_logger.Log( aObstacleVia, 0, "the-via" );
|
m_logger.Log( aObstacleVia, 0, "the-via" );
|
||||||
m_logger.Log( &aCurrent, 1, "current-line" );
|
m_logger.Log( &aCurrent, 1, "current-line" );
|
||||||
|
@ -952,7 +969,7 @@ SHOVE::SHOVE_STATUS SHOVE::onReverseCollidingVia( LINE& aCurrent, VIA* aObstacle
|
||||||
if( aCurrent.EndsWithVia() )
|
if( aCurrent.EndsWithVia() )
|
||||||
shoved.AppendVia( aCurrent.Via() );
|
shoved.AppendVia( aCurrent.Via() );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if 0
|
||||||
m_logger.NewGroup( "on-reverse-via", m_iter );
|
m_logger.NewGroup( "on-reverse-via", m_iter );
|
||||||
m_logger.Log( aObstacleVia, 0, "the-via" );
|
m_logger.Log( aObstacleVia, 0, "the-via" );
|
||||||
m_logger.Log( &aCurrent, 1, "current-line" );
|
m_logger.Log( &aCurrent, 1, "current-line" );
|
||||||
|
@ -1058,6 +1075,10 @@ SHOVE::SHOVE_STATUS SHOVE::shoveIteration( int aIter )
|
||||||
NODE::OPT_OBSTACLE nearest;
|
NODE::OPT_OBSTACLE nearest;
|
||||||
SHOVE_STATUS st = SH_NULL;
|
SHOVE_STATUS st = SH_NULL;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
Dbg()->SetIteration( aIter );
|
||||||
|
#endif
|
||||||
|
|
||||||
for( ITEM::PnsKind search_order : { ITEM::SOLID_T, ITEM::VIA_T, ITEM::SEGMENT_T } )
|
for( ITEM::PnsKind search_order : { ITEM::SOLID_T, ITEM::VIA_T, ITEM::SEGMENT_T } )
|
||||||
{
|
{
|
||||||
nearest = m_currentNode->NearestObstacle( ¤tLine, search_order );
|
nearest = m_currentNode->NearestObstacle( ¤tLine, search_order );
|
||||||
|
@ -1259,7 +1280,9 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveLines( const LINE& aCurrentHead )
|
||||||
m_lineStack.clear();
|
m_lineStack.clear();
|
||||||
m_optimizerQueue.clear();
|
m_optimizerQueue.clear();
|
||||||
m_newHead = OPT_LINE();
|
m_newHead = OPT_LINE();
|
||||||
|
#if 0
|
||||||
m_logger.Clear();
|
m_logger.Clear();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Pop NODEs containing previous shoves which are no longer necessary
|
// Pop NODEs containing previous shoves which are no longer necessary
|
||||||
//
|
//
|
||||||
|
@ -1284,15 +1307,16 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveLines( const LINE& aCurrentHead )
|
||||||
head.Mark( MK_HEAD );
|
head.Mark( MK_HEAD );
|
||||||
head.SetRank( 100000 );
|
head.SetRank( 100000 );
|
||||||
|
|
||||||
|
#if 0
|
||||||
m_logger.NewGroup( "initial", 0 );
|
m_logger.NewGroup( "initial", 0 );
|
||||||
m_logger.Log( &head, 0, "head" );
|
m_logger.Log( &head, 0, "head" );
|
||||||
|
#endif
|
||||||
|
|
||||||
if( head.EndsWithVia() )
|
if( head.EndsWithVia() )
|
||||||
{
|
{
|
||||||
std::unique_ptr< VIA >headVia = Clone( head.Via() );
|
std::unique_ptr< VIA >headVia = Clone( head.Via() );
|
||||||
headVia->Mark( MK_HEAD );
|
headVia->Mark( MK_HEAD );
|
||||||
headVia->SetRank( 100000 );
|
headVia->SetRank( 100000 );
|
||||||
m_logger.Log( headVia.get(), 0, "head-via" );
|
|
||||||
m_currentNode->Add( std::move( headVia ) );
|
m_currentNode->Add( std::move( headVia ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1368,7 +1392,9 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveMultiLines( const ITEM_SET& aHeadSet )
|
||||||
|
|
||||||
m_lineStack.clear();
|
m_lineStack.clear();
|
||||||
m_optimizerQueue.clear();
|
m_optimizerQueue.clear();
|
||||||
|
#if 0
|
||||||
m_logger.Clear();
|
m_logger.Clear();
|
||||||
|
#endif
|
||||||
|
|
||||||
VIA_HANDLE dummyVia;
|
VIA_HANDLE dummyVia;
|
||||||
|
|
||||||
|
@ -1398,14 +1424,10 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveMultiLines( const ITEM_SET& aHeadSet )
|
||||||
std::unique_ptr< VIA > headVia = Clone( head.Via() );
|
std::unique_ptr< VIA > headVia = Clone( head.Via() );
|
||||||
headVia->Mark( MK_HEAD );
|
headVia->Mark( MK_HEAD );
|
||||||
headVia->SetRank( 100000 );
|
headVia->SetRank( 100000 );
|
||||||
m_logger.Log( headVia.get(), 0, "head-via" );
|
|
||||||
m_currentNode->Add( std::move( headVia ) );
|
m_currentNode->Add( std::move( headVia ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_logger.NewGroup( "initial", 0 );
|
|
||||||
//m_logger.Log( head, 0, "head" );
|
|
||||||
|
|
||||||
st = shoveMainLoop();
|
st = shoveMainLoop();
|
||||||
|
|
||||||
if( st == SH_OK )
|
if( st == SH_OK )
|
||||||
|
|
|
@ -87,7 +87,8 @@ WALKAROUND::WALKAROUND_STATUS WALKAROUND::singleStep( LINE& aPath,
|
||||||
path_post[1], !aWindingDirection ) )
|
path_post[1], !aWindingDirection ) )
|
||||||
return STUCK;
|
return STUCK;
|
||||||
auto l =aPath.CLine();
|
auto l =aPath.CLine();
|
||||||
#ifdef DEBUG
|
|
||||||
|
#if 0
|
||||||
if( m_logger )
|
if( m_logger )
|
||||||
{
|
{
|
||||||
m_logger->NewGroup( aWindingDirection ? "walk-cw" : "walk-ccw", m_iteration );
|
m_logger->NewGroup( aWindingDirection ? "walk-cw" : "walk-ccw", m_iteration );
|
||||||
|
|
|
@ -53,6 +53,9 @@ using namespace std::placeholders;
|
||||||
#include "pns_segment.h"
|
#include "pns_segment.h"
|
||||||
#include "pns_router.h"
|
#include "pns_router.h"
|
||||||
#include "pns_itemset.h"
|
#include "pns_itemset.h"
|
||||||
|
#include "pns_logger.h"
|
||||||
|
|
||||||
|
#include "pns_kicad_iface.h"
|
||||||
|
|
||||||
using namespace KIGFX;
|
using namespace KIGFX;
|
||||||
|
|
||||||
|
@ -471,8 +474,7 @@ void ROUTER_TOOL::handleCommonEvents( const TOOL_EVENT& aEvent )
|
||||||
switch( aEvent.KeyCode() )
|
switch( aEvent.KeyCode() )
|
||||||
{
|
{
|
||||||
case '0':
|
case '0':
|
||||||
wxLogTrace( "PNS", "saving drag/route log...\n" );
|
// fixme: move to new logging infrastructure
|
||||||
m_router->DumpLog();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue