router: initial attempt at walkaround mode for dragger

This commit is contained in:
Tomasz Wlostowski 2020-02-05 16:33:14 +01:00
parent c0314dbb29
commit 53c3f95ac4
4 changed files with 133 additions and 15 deletions

View File

@ -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,6 +278,102 @@ 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 )
{
@ -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;
}

View File

@ -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;

View File

@ -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 );
}

View File

@ -30,6 +30,7 @@
#include "range.h"
namespace PNS {
class NODE;