router: drag in walkaround mode now works
This commit is contained in:
parent
f84836f51e
commit
a4bd2ad8c6
|
@ -47,6 +47,24 @@ DRAGGER::~DRAGGER()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DRAGGER::propagateViaForces( NODE* node, std::set<VIA*>& vias )
|
||||||
|
{
|
||||||
|
VIA* via = *vias.begin();
|
||||||
|
|
||||||
|
VECTOR2I force;
|
||||||
|
VECTOR2I lead = m_mouseTrailTracer.GetTrailLeadVector();
|
||||||
|
|
||||||
|
bool solidsOnly = false;// ( m_currentMode != RM_Walkaround );
|
||||||
|
|
||||||
|
if( via->PushoutForce( node, lead, force, solidsOnly, 40 ) )
|
||||||
|
{
|
||||||
|
via->SetPos( via->Pos() + force );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool DRAGGER::startDragSegment( const VECTOR2D& aP, SEGMENT* aSeg )
|
bool DRAGGER::startDragSegment( const VECTOR2D& aP, SEGMENT* aSeg )
|
||||||
{
|
{
|
||||||
int w2 = aSeg->Width() / 2;
|
int w2 = aSeg->Width() / 2;
|
||||||
|
@ -153,6 +171,9 @@ bool DRAGGER::Start( const VECTOR2I& aP, ITEM_SET& aPrimitives )
|
||||||
m_freeAngleMode = (m_mode & DM_FREE_ANGLE);
|
m_freeAngleMode = (m_mode & DM_FREE_ANGLE);
|
||||||
m_lastValidPoint = aP;
|
m_lastValidPoint = aP;
|
||||||
|
|
||||||
|
m_mouseTrailTracer.Clear();
|
||||||
|
m_mouseTrailTracer.AddTrailPoint( aP );
|
||||||
|
|
||||||
if( m_currentMode == RM_Shove && !m_freeAngleMode )
|
if( m_currentMode == RM_Shove && !m_freeAngleMode )
|
||||||
{
|
{
|
||||||
m_shove = std::make_unique<SHOVE>( m_world, Router() );
|
m_shove = std::make_unique<SHOVE>( m_world, Router() );
|
||||||
|
@ -241,7 +262,7 @@ bool DRAGGER::dragMarkObstacles( const VECTOR2I& aP )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DRAGGER::dragViaMarkObstacles( const VIA_HANDLE& aHandle, NODE* aNode, const VECTOR2I& aP )
|
bool DRAGGER::dragViaMarkObstacles( const VIA_HANDLE& aHandle, NODE* aNode, const VECTOR2I& aP )
|
||||||
{
|
{
|
||||||
m_draggedItems.Clear();
|
m_draggedItems.Clear();
|
||||||
|
|
||||||
|
@ -249,7 +270,7 @@ void DRAGGER::dragViaMarkObstacles( const VIA_HANDLE& aHandle, NODE* aNode, cons
|
||||||
|
|
||||||
if( fanout.Empty() )
|
if( fanout.Empty() )
|
||||||
{
|
{
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( ITEM* item : fanout.Items() )
|
for( ITEM* item : fanout.Items() )
|
||||||
|
@ -278,10 +299,12 @@ void DRAGGER::dragViaMarkObstacles( const VIA_HANDLE& aHandle, NODE* aNode, cons
|
||||||
m_lastNode->Add( std::move( nvia ) );
|
m_lastNode->Add( std::move( nvia ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DRAGGER::dragViaWalkaround( const VIA_HANDLE& aHandle, NODE* aNode, const VECTOR2I& aP )
|
bool DRAGGER::dragViaWalkaround( const VIA_HANDLE& aHandle, NODE* aNode, const VECTOR2I& aP )
|
||||||
{
|
{
|
||||||
m_draggedItems.Clear();
|
m_draggedItems.Clear();
|
||||||
|
|
||||||
|
@ -289,10 +312,12 @@ void DRAGGER::dragViaWalkaround( const VIA_HANDLE& aHandle, NODE* aNode, const V
|
||||||
|
|
||||||
if( fanout.Empty() )
|
if( fanout.Empty() )
|
||||||
{
|
{
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool viaPropOk = false;
|
||||||
|
VECTOR2I viaTargetPos;
|
||||||
|
|
||||||
for( ITEM* item : fanout.Items() )
|
for( ITEM* item : fanout.Items() )
|
||||||
{
|
{
|
||||||
if ( VIA *via = dyn_cast<VIA*>( item ) )
|
if ( VIA *via = dyn_cast<VIA*>( item ) )
|
||||||
|
@ -302,28 +327,61 @@ void DRAGGER::dragViaWalkaround( const VIA_HANDLE& aHandle, NODE* aNode, const V
|
||||||
draggedVia->SetPos( aP );
|
draggedVia->SetPos( aP );
|
||||||
m_draggedItems.Add( draggedVia.get() );
|
m_draggedItems.Add( draggedVia.get() );
|
||||||
|
|
||||||
}
|
std::set<VIA*> vias;
|
||||||
|
|
||||||
/*
|
vias.insert( draggedVia.get() );
|
||||||
|
|
||||||
|
bool ok = propagateViaForces( m_lastNode, vias );
|
||||||
|
|
||||||
|
if( ok )
|
||||||
|
{
|
||||||
|
viaTargetPos = draggedVia->Pos();
|
||||||
|
viaPropOk = true;
|
||||||
|
m_lastNode->Remove( via );
|
||||||
|
m_lastNode->Add( std::move(draggedVia) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !viaPropOk ) // can't force-propagate the via? bummer...
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for( ITEM* item : fanout.Items() )
|
||||||
|
{
|
||||||
if( const LINE* l = dyn_cast<const LINE*>( item ) )
|
if( const LINE* l = dyn_cast<const LINE*>( item ) )
|
||||||
{
|
{
|
||||||
LINE origLine( *l );
|
LINE origLine( *l );
|
||||||
LINE draggedLine( *l );
|
LINE draggedLine( *l );
|
||||||
|
LINE walkLine( *l );
|
||||||
|
|
||||||
draggedLine.DragCorner( aP, origLine.CLine().Find( aHandle.pos ), m_freeAngleMode );
|
draggedLine.DragCorner( viaTargetPos, origLine.CLine().Find( aHandle.pos ), m_freeAngleMode );
|
||||||
draggedLine.ClearLinks();
|
draggedLine.ClearLinks();
|
||||||
|
|
||||||
m_draggedItems.Add( draggedLine );
|
if ( m_world->CheckColliding( &draggedLine ) )
|
||||||
|
{
|
||||||
|
bool ok = tryWalkaround( m_lastNode, draggedLine, walkLine );
|
||||||
|
|
||||||
|
if( !ok )
|
||||||
|
return false;
|
||||||
|
|
||||||
m_lastNode->Remove( origLine );
|
m_lastNode->Remove( origLine );
|
||||||
m_lastNode->Add( draggedLine );
|
optimizeAndUpdateDraggedLine( walkLine, origLine, aP );
|
||||||
}
|
}
|
||||||
else */
|
else
|
||||||
|
{
|
||||||
|
m_draggedItems.Add( draggedLine );
|
||||||
|
|
||||||
|
m_lastNode->Remove( origLine );
|
||||||
|
m_lastNode->Add( draggedLine );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void DRAGGER::optimizeAndUpdateDraggedLine( LINE& aDragged, const LINE& aOrig, SEG& aDraggedSeg, const VECTOR2I& aP )
|
|
||||||
|
void DRAGGER::optimizeAndUpdateDraggedLine( LINE& aDragged, const LINE& aOrig, const VECTOR2I& aP )
|
||||||
{
|
{
|
||||||
VECTOR2D lockV;
|
VECTOR2D lockV;
|
||||||
aDragged.ClearLinks();
|
aDragged.ClearLinks();
|
||||||
|
@ -337,6 +395,12 @@ void DRAGGER::optimizeAndUpdateDraggedLine( LINE& aDragged, const LINE& aOrig, S
|
||||||
|
|
||||||
optimizer.SetEffortLevel( OPTIMIZER::MERGE_SEGMENTS | OPTIMIZER::KEEP_TOPOLOGY );
|
optimizer.SetEffortLevel( OPTIMIZER::MERGE_SEGMENTS | OPTIMIZER::KEEP_TOPOLOGY );
|
||||||
|
|
||||||
|
//printf("sa %d %d\n", aDraggedSeg.A.x, aDraggedSeg.A.y );
|
||||||
|
//Dbg()->AddPoint( aDraggedSeg.A, 4 );
|
||||||
|
//Dbg()->AddPoint( aDraggedSeg.B, 5 );
|
||||||
|
|
||||||
|
// Dbg()->AddLine( aDragged.CLine(), 3, 1000 );
|
||||||
|
|
||||||
OPT_BOX2I affectedArea = *aDragged.ChangedArea( &aOrig );
|
OPT_BOX2I affectedArea = *aDragged.ChangedArea( &aOrig );
|
||||||
|
|
||||||
optimizer.SetPreserveVertex( aP );
|
optimizer.SetPreserveVertex( aP );
|
||||||
|
@ -363,6 +427,40 @@ void DRAGGER::optimizeAndUpdateDraggedLine( LINE& aDragged, const LINE& aOrig, S
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DRAGGER::tryWalkaround( NODE* aNode, LINE& aOrig, LINE& aWalk )
|
||||||
|
{
|
||||||
|
WALKAROUND walkaround( aNode, Router() );
|
||||||
|
bool ok = false;
|
||||||
|
walkaround.SetSolidsOnly( false );
|
||||||
|
walkaround.SetDebugDecorator( Dbg() );
|
||||||
|
walkaround.SetLogger( Logger() );
|
||||||
|
walkaround.SetIterationLimit( Settings().WalkaroundIterationLimit() );
|
||||||
|
|
||||||
|
aWalk = aOrig;
|
||||||
|
|
||||||
|
WALKAROUND::RESULT wr = walkaround.Route( aWalk );
|
||||||
|
|
||||||
|
|
||||||
|
if( wr.statusCcw == WALKAROUND::DONE && wr.statusCw == WALKAROUND::DONE )
|
||||||
|
{
|
||||||
|
aWalk = ( wr.lineCw.CLine().Length() < wr.lineCcw.CLine().Length() ? wr.lineCw :
|
||||||
|
wr.lineCcw );
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
else if( wr.statusCw == WALKAROUND::DONE )
|
||||||
|
{
|
||||||
|
aWalk = wr.lineCw;
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
else if( wr.statusCcw == WALKAROUND::DONE )
|
||||||
|
{
|
||||||
|
aWalk = wr.lineCcw;
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool DRAGGER::dragWalkaround( const VECTOR2I& aP )
|
bool DRAGGER::dragWalkaround( const VECTOR2I& aP )
|
||||||
{
|
{
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
|
@ -382,8 +480,11 @@ bool DRAGGER::dragWalkaround( const VECTOR2I& aP )
|
||||||
{
|
{
|
||||||
int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine.Width() / 4 : 0;
|
int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine.Width() / 4 : 0;
|
||||||
LINE dragged( m_draggedLine );
|
LINE dragged( m_draggedLine );
|
||||||
|
LINE draggedWalk( m_draggedLine );
|
||||||
LINE origLine( m_draggedLine );
|
LINE origLine( m_draggedLine );
|
||||||
|
|
||||||
|
dragged.SetSnapThreshhold( thresh );
|
||||||
|
|
||||||
if( m_mode == DM_SEGMENT )
|
if( m_mode == DM_SEGMENT )
|
||||||
dragged.DragSegment( aP, m_draggedSegmentIndex );
|
dragged.DragSegment( aP, m_draggedSegmentIndex );
|
||||||
else
|
else
|
||||||
|
@ -391,55 +492,28 @@ bool DRAGGER::dragWalkaround( const VECTOR2I& aP )
|
||||||
|
|
||||||
if ( m_world->CheckColliding( &dragged ) )
|
if ( m_world->CheckColliding( &dragged ) )
|
||||||
{
|
{
|
||||||
WALKAROUND walkaround( m_lastNode, Router() );
|
ok = tryWalkaround( m_lastNode, dragged, draggedWalk );
|
||||||
|
|
||||||
walkaround.SetSolidsOnly( false );
|
|
||||||
walkaround.SetDebugDecorator( Dbg() );
|
|
||||||
walkaround.SetLogger( Logger() );
|
|
||||||
walkaround.SetIterationLimit( Settings().WalkaroundIterationLimit() );
|
|
||||||
|
|
||||||
WALKAROUND::RESULT wr = walkaround.Route( dragged );
|
|
||||||
|
|
||||||
//Dbg()->AddLine( wr.lineCw.CLine(), 3, 200000 );
|
|
||||||
//Dbg()->AddLine( wr.lineCcw.CLine(), 2, 200000 );
|
|
||||||
|
|
||||||
if( wr.statusCcw == WALKAROUND::DONE && wr.statusCw == WALKAROUND::DONE )
|
|
||||||
{
|
|
||||||
dragged = ( wr.lineCw.CLine().Length() < wr.lineCcw.CLine().Length() ? wr.lineCw : wr.lineCcw );
|
|
||||||
ok = true;
|
|
||||||
}
|
|
||||||
else if ( wr.statusCw == WALKAROUND::DONE )
|
|
||||||
{
|
|
||||||
dragged = wr.lineCw;
|
|
||||||
ok = true;
|
|
||||||
}
|
|
||||||
else if ( wr.statusCcw == WALKAROUND::DONE )
|
|
||||||
{
|
|
||||||
dragged = wr.lineCcw;
|
|
||||||
ok = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
draggedWalk = dragged;
|
||||||
ok = true;
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ok)
|
if(ok)
|
||||||
{
|
{
|
||||||
|
//Dbg()->AddLine( origLine.CLine(), 4, 100000 );
|
||||||
m_lastNode->Remove( origLine );
|
m_lastNode->Remove( origLine );
|
||||||
SEG dummy;
|
optimizeAndUpdateDraggedLine( draggedWalk, origLine, aP );
|
||||||
optimizeAndUpdateDraggedLine( dragged, origLine, dummy, aP );
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DM_VIA: // fixme...
|
case DM_VIA: // fixme...
|
||||||
{
|
{
|
||||||
dragViaWalkaround( m_initialVia, m_lastNode, aP );
|
ok = dragViaWalkaround( m_initialVia, m_lastNode, aP );
|
||||||
ok = !m_world->CheckColliding( m_draggedItems );
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_dragStatus = ok;
|
m_dragStatus = ok;
|
||||||
|
|
||||||
|
@ -489,18 +563,7 @@ bool DRAGGER::dragShove( const VECTOR2I& aP )
|
||||||
dragged.ClearLinks();
|
dragged.ClearLinks();
|
||||||
dragged.Unmark();
|
dragged.Unmark();
|
||||||
|
|
||||||
lockV = dragged.CLine().NearestPoint( aP );
|
optimizeAndUpdateDraggedLine( dragged, m_draggedLine, aP );
|
||||||
|
|
||||||
if( Settings().GetOptimizeDraggedTrack() )
|
|
||||||
{
|
|
||||||
OPTIMIZER::Optimize( &dragged, OPTIMIZER::MERGE_SEGMENTS
|
|
||||||
| OPTIMIZER::KEEP_TOPOLOGY
|
|
||||||
| OPTIMIZER::PRESERVE_VERTEX, m_lastNode, lockV );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_lastNode->Add( dragged );
|
|
||||||
m_draggedItems.Clear();
|
|
||||||
m_draggedItems.Add( dragged );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -562,6 +625,8 @@ bool DRAGGER::FixRoute()
|
||||||
|
|
||||||
bool DRAGGER::Drag( const VECTOR2I& aP )
|
bool DRAGGER::Drag( const VECTOR2I& aP )
|
||||||
{
|
{
|
||||||
|
m_mouseTrailTracer.AddTrailPoint( aP );
|
||||||
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if( m_freeAngleMode )
|
if( m_freeAngleMode )
|
||||||
|
@ -570,24 +635,24 @@ bool DRAGGER::Drag( const VECTOR2I& aP )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch( m_currentMode )
|
switch( m_currentMode )
|
||||||
{
|
{
|
||||||
case RM_MarkObstacles:
|
case RM_MarkObstacles:
|
||||||
ret = dragMarkObstacles( aP );
|
ret = dragMarkObstacles( aP );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RM_Shove:
|
case RM_Shove:
|
||||||
case RM_Smart:
|
case RM_Smart:
|
||||||
ret = dragShove( aP );
|
ret = dragShove( aP );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RM_Walkaround:
|
case RM_Walkaround:
|
||||||
ret = dragWalkaround( aP );
|
ret = dragWalkaround( aP );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ret )
|
if( ret )
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#include "pns_drag_algo.h"
|
#include "pns_drag_algo.h"
|
||||||
#include "pns_itemset.h"
|
#include "pns_itemset.h"
|
||||||
#include "pns_layerset.h"
|
#include "pns_layerset.h"
|
||||||
|
#include "pns_mouse_trail_tracer.h"
|
||||||
|
|
||||||
namespace PNS {
|
namespace PNS {
|
||||||
|
|
||||||
|
@ -121,11 +121,13 @@ private:
|
||||||
bool startDragSegment( const VECTOR2D& aP, SEGMENT* aSeg );
|
bool startDragSegment( const VECTOR2D& aP, SEGMENT* aSeg );
|
||||||
bool startDragArc( const VECTOR2D& aP, ARC* aArc );
|
bool startDragArc( const VECTOR2D& aP, ARC* aArc );
|
||||||
bool startDragVia( VIA* aVia );
|
bool startDragVia( VIA* aVia );
|
||||||
void dragViaMarkObstacles( const VIA_HANDLE& aHandle, NODE* aNode, const VECTOR2I& aP );
|
bool dragViaMarkObstacles( const VIA_HANDLE& aHandle, NODE* aNode, const VECTOR2I& aP );
|
||||||
void dragViaWalkaround( const VIA_HANDLE& aHandle, NODE* aNode, const VECTOR2I& aP );
|
bool dragViaWalkaround( const VIA_HANDLE& aHandle, NODE* aNode, const VECTOR2I& aP );
|
||||||
void optimizeAndUpdateDraggedLine( LINE& aDragged, const LINE& aOrig, SEG& aDraggedSeg, const VECTOR2I& aP );
|
void optimizeAndUpdateDraggedLine( LINE& aDragged, const LINE& aOrig, const VECTOR2I& aP );
|
||||||
|
bool propagateViaForces( NODE* node, std::set<VIA*>& vias );
|
||||||
|
bool tryWalkaround( NODE* aNode, LINE& aOrig, LINE& aWalk );
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
VIA_HANDLE m_initialVia;
|
VIA_HANDLE m_initialVia;
|
||||||
VIA_HANDLE m_draggedVia;
|
VIA_HANDLE m_draggedVia;
|
||||||
|
|
||||||
|
@ -136,6 +138,7 @@ private:
|
||||||
int m_draggedSegmentIndex;
|
int m_draggedSegmentIndex;
|
||||||
bool m_dragStatus;
|
bool m_dragStatus;
|
||||||
PNS_MODE m_currentMode;
|
PNS_MODE m_currentMode;
|
||||||
|
ITEM_SET m_origViaConnections;
|
||||||
VECTOR2D m_lastValidPoint;
|
VECTOR2D m_lastValidPoint;
|
||||||
|
|
||||||
///< Contains the list of items that are currently modified by the dragger
|
///< Contains the list of items that are currently modified by the dragger
|
||||||
|
@ -143,6 +146,7 @@ private:
|
||||||
|
|
||||||
///< If true, moves the connection lines without maintaining 45 degrees corners
|
///< If true, moves the connection lines without maintaining 45 degrees corners
|
||||||
bool m_freeAngleMode;
|
bool m_freeAngleMode;
|
||||||
|
MOUSE_TRAIL_TRACER m_mouseTrailTracer;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue