router: initial attempt at walkaround mode for dragger
This commit is contained in:
parent
c0314dbb29
commit
53c3f95ac4
|
@ -25,6 +25,7 @@
|
|||
#include "pns_shove.h"
|
||||
#include "pns_router.h"
|
||||
#include "pns_debug_decorator.h"
|
||||
#include "pns_walkaround.h"
|
||||
|
||||
namespace PNS {
|
||||
|
||||
|
@ -151,8 +152,12 @@ bool DRAGGER::Start( const VECTOR2I& aP, ITEM* aStartItem )
|
|||
m_currentMode = Settings().Mode();
|
||||
m_freeAngleMode = (m_mode & DM_FREE_ANGLE);
|
||||
|
||||
if( m_currentMode != RM_MarkObstacles && !m_freeAngleMode )
|
||||
if( m_currentMode == RM_Shove && !m_freeAngleMode )
|
||||
{
|
||||
m_shove = std::make_unique<SHOVE>( m_world, Router() );
|
||||
m_shove->SetLogger( Logger() );
|
||||
m_shove->SetDebugDecorator( Dbg() );
|
||||
}
|
||||
|
||||
aStartItem->Unmark( MK_LOCKED );
|
||||
|
||||
|
@ -273,11 +278,107 @@ void DRAGGER::dumbDragVia( const VIA_HANDLE& aHandle, NODE* aNode, const VECTOR2
|
|||
}
|
||||
}
|
||||
|
||||
void DRAGGER::optimizeAndUpdateDraggedLine( LINE& dragged, const VECTOR2I& aP )
|
||||
{
|
||||
VECTOR2D lockV;
|
||||
dragged.ClearSegmentLinks();
|
||||
dragged.Unmark();
|
||||
|
||||
Dbg()->AddLine( dragged.CLine(), 5, 100000 );
|
||||
|
||||
lockV = dragged.CLine().NearestPoint( aP );
|
||||
Dbg()->AddPoint( lockV, 4 );
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
bool DRAGGER::dragWalkaround( const VECTOR2I& aP )
|
||||
{
|
||||
bool ok = false;
|
||||
// fixme: rewrite using shared_ptr...
|
||||
if( m_lastNode )
|
||||
{
|
||||
delete m_lastNode;
|
||||
m_lastNode = nullptr;
|
||||
}
|
||||
|
||||
m_lastNode = m_world->Branch();
|
||||
|
||||
switch( m_mode )
|
||||
{
|
||||
case DM_SEGMENT:
|
||||
case DM_CORNER:
|
||||
{
|
||||
int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine.Width() / 4 : 0;
|
||||
LINE dragged( m_draggedLine );
|
||||
LINE origLine( m_draggedLine );
|
||||
|
||||
if( m_mode == DM_SEGMENT )
|
||||
dragged.DragSegment( aP, m_draggedSegmentIndex, thresh );
|
||||
else
|
||||
dragged.DragCorner( aP, m_draggedSegmentIndex, thresh );
|
||||
|
||||
if ( m_world->CheckColliding( &dragged ) )
|
||||
{
|
||||
WALKAROUND walkaround( m_lastNode, Router() );
|
||||
|
||||
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
|
||||
{
|
||||
ok = true;
|
||||
}
|
||||
|
||||
if(ok)
|
||||
{
|
||||
m_lastNode->Remove( origLine );
|
||||
optimizeAndUpdateDraggedLine( dragged, aP );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_dragStatus = ok;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DRAGGER::dragShove( const VECTOR2I& aP )
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
|
||||
if( m_lastNode )
|
||||
{
|
||||
delete m_lastNode;
|
||||
|
@ -317,7 +418,10 @@ bool DRAGGER::dragShove( const VECTOR2I& aP )
|
|||
dragged.ClearSegmentLinks();
|
||||
dragged.Unmark();
|
||||
|
||||
Dbg()->AddLine(dragged.CLine(), 5, 100000 );
|
||||
|
||||
lockV = dragged.CLine().NearestPoint( aP );
|
||||
Dbg()->AddPoint(lockV, 4 );
|
||||
|
||||
OPTIMIZER::Optimize( &dragged, OPTIMIZER::MERGE_SEGMENTS
|
||||
| OPTIMIZER::KEEP_TOPOLOGY
|
||||
|
@ -385,10 +489,12 @@ bool DRAGGER::Drag( const VECTOR2I& aP )
|
|||
return dragMarkObstacles( aP );
|
||||
|
||||
case RM_Shove:
|
||||
case RM_Walkaround:
|
||||
case RM_Smart:
|
||||
return dragShove( aP );
|
||||
|
||||
case RM_Walkaround:
|
||||
return dragWalkaround( aP );
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -105,10 +105,12 @@ private:
|
|||
|
||||
bool dragMarkObstacles( const VECTOR2I& aP );
|
||||
bool dragShove(const VECTOR2I& aP );
|
||||
bool dragWalkaround(const VECTOR2I& aP );
|
||||
bool startDragSegment( const VECTOR2D& aP, SEGMENT* aSeg );
|
||||
bool startDragArc( const VECTOR2D& aP, ARC* aArc );
|
||||
bool startDragVia( VIA* aVia );
|
||||
void dumbDragVia( const VIA_HANDLE& aHandle, NODE* aNode, const VECTOR2I& aP );
|
||||
void optimizeAndUpdateDraggedLine( LINE& dragged, const VECTOR2I& aP );
|
||||
|
||||
VIA_HANDLE m_initialVia;
|
||||
VIA_HANDLE m_draggedVia;
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
namespace PNS {
|
||||
|
||||
|
||||
static DEBUG_DECORATOR *dbg;
|
||||
static DEBUG_DECORATOR *g_dbg;
|
||||
/**
|
||||
* Cost Estimator Methods
|
||||
*/
|
||||
|
@ -292,12 +292,18 @@ class JOINT_CACHE
|
|||
bool PRESERVE_VERTEX_CONSTRAINT::Check ( int aVertex1, int aVertex2, LINE* aOriginLine, const SHAPE_LINE_CHAIN& aReplacement )
|
||||
{
|
||||
const auto& l = aOriginLine->CLine();
|
||||
bool cv;
|
||||
bool cv = false;
|
||||
|
||||
printf("-------> avtx chk %d %d v %d %d\n", aVertex1, aVertex2, m_v.x, m_v.y );
|
||||
|
||||
for( int i = aVertex1; i < aVertex2; i++ )
|
||||
{
|
||||
if ( l.CSegment(i).Contains( m_v ) )
|
||||
int dist = l.CSegment(i).Distance( m_v );
|
||||
printf("i %d dist %d\n", i, dist );
|
||||
if ( dist <= 1 )
|
||||
{
|
||||
g_dbg->AddSegment( l.CSegment(i), 1 );
|
||||
|
||||
cv = true;
|
||||
break;
|
||||
}
|
||||
|
@ -308,7 +314,7 @@ bool PRESERVE_VERTEX_CONSTRAINT::Check ( int aVertex1, int aVertex2, LINE* aOrig
|
|||
|
||||
for( int i = 0; i < aReplacement.SegmentCount(); i++ )
|
||||
{
|
||||
if ( aReplacement.CSegment(i).Contains( m_v ) )
|
||||
if ( aReplacement.CSegment(i).Distance( m_v ) < 1 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -444,9 +450,9 @@ void OPTIMIZER::AddConstraint ( OPT_CONSTRAINT *aConstraint )
|
|||
}
|
||||
|
||||
bool OPTIMIZER::checkConstraints( int aVertex1, int aVertex2, LINE* aOriginLine, const SHAPE_LINE_CHAIN& aReplacement )
|
||||
{
|
||||
{
|
||||
for( auto c: m_constraints)
|
||||
if ( !c->Check( aVertex1, aVertex2, aOriginLine, aReplacement ))
|
||||
if ( !c->Check( aVertex1, aVertex2, aOriginLine, aReplacement ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -1008,21 +1014,24 @@ bool OPTIMIZER::Optimize( LINE* aLine, int aEffortLevel, NODE* aWorld, const VEC
|
|||
{
|
||||
OPTIMIZER opt( aWorld );
|
||||
|
||||
g_dbg = ROUTER::GetInstance()->GetInterface()->GetDebugDecorator();
|
||||
|
||||
opt.SetEffortLevel( aEffortLevel );
|
||||
opt.SetCollisionMask( -1 );
|
||||
|
||||
if ( aEffortLevel & KEEP_TOPOLOGY )
|
||||
{
|
||||
auto c = new KEEP_TOPOLOGY_CONSTRAINT( aWorld );
|
||||
opt.AddConstraint( c );
|
||||
}
|
||||
|
||||
if ( aEffortLevel & PRESERVE_VERTEX )
|
||||
{
|
||||
auto c = new PRESERVE_VERTEX_CONSTRAINT( aWorld, aV );
|
||||
opt.AddConstraint( c );
|
||||
//printf("pres-v %d %d\n", aV.x, aV.y );
|
||||
}
|
||||
|
||||
if ( aEffortLevel & KEEP_TOPOLOGY )
|
||||
{
|
||||
auto c = new KEEP_TOPOLOGY_CONSTRAINT( aWorld );
|
||||
opt.AddConstraint( c );
|
||||
}
|
||||
|
||||
return opt.Optimize( aLine );
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "range.h"
|
||||
|
||||
|
||||
namespace PNS {
|
||||
|
||||
class NODE;
|
||||
|
|
Loading…
Reference in New Issue