Pcbnew: fix push and shove router segfault bug.

This commit is contained in:
Thomasz Wlostowski 2015-11-03 11:19:42 -05:00 committed by Wayne Stambaugh
parent 6d8fb6015b
commit 6e470ece1d
10 changed files with 98 additions and 24 deletions

View File

@ -949,9 +949,10 @@ void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE& aLatest )
if( !aLatest.SegmentCount() )
return;
if ( aLatest.CLine().CPoint( 0 ) == aLatest.CLine().CPoint( -1 ) )
if( aLatest.CLine().CPoint( 0 ) == aLatest.CLine().CPoint( -1 ) )
return;
std::set<PNS_SEGMENT *> toErase;
aNode->Add( &aLatest, true );
for( int s = 0; s < aLatest.LinkCount(); s++ )
@ -979,7 +980,9 @@ void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE& aLatest )
if( !( line.ContainsSegment( seg ) ) && line.SegmentCount() )
{
aNode->Remove( &line );
BOOST_FOREACH( PNS_SEGMENT *ss, *line.LinkedSegments() )
toErase.insert( ss );
removedCount++;
}
}
@ -987,6 +990,9 @@ void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE& aLatest )
TRACE( 0, "total segs removed: %d/%d\n", removedCount % total );
}
BOOST_FOREACH( PNS_SEGMENT *s, toErase )
aNode->Remove( s );
aNode->Remove( &aLatest );
}
@ -1034,17 +1040,12 @@ void PNS_LINE_PLACER::updateLeadingRatLine()
void PNS_LINE_PLACER::SetOrthoMode( bool aOrthoMode )
{
m_orthoMode = aOrthoMode;
if( !m_idle )
Move( m_currentEnd, NULL );
}
bool PNS_LINE_PLACER::buildInitialLine( const VECTOR2I& aP, PNS_LINE& aHead )
{
SHAPE_LINE_CHAIN l;
printf("H-net %d\n", aHead.Net());
if( m_p_start == aP )
{
l.Clear();

View File

@ -35,6 +35,8 @@
#include <geometry/shape_rect.h>
#include <geometry/shape_circle.h>
#include <tools/grid_helper.h>
#include "trace.h"
#include "pns_node.h"
#include "pns_line_placer.h"
@ -572,8 +574,8 @@ const VECTOR2I PNS_ROUTER::SnapToItem( PNS_ITEM* aItem, VECTOR2I aP, bool& aSpli
anchor = s.B;
else
{
anchor = s.NearestPoint( aP );
aSplitsSegment = true;
anchor = m_gridHelper->AlignToSegment ( aP, s );
aSplitsSegment = (anchor != s.A && anchor != s.B );
}
break;

View File

@ -40,6 +40,7 @@ class BOARD_ITEM;
class D_PAD;
class TRACK;
class VIA;
class GRID_HELPER;
class PNS_NODE;
class PNS_DIFF_PAIR_PLACER;
class PNS_PLACEMENT_ALGO;
@ -106,7 +107,6 @@ public:
void StopRouting();
int GetClearance( const PNS_ITEM* aA, const PNS_ITEM* aB ) const;
PNS_NODE* GetWorld() const
@ -216,10 +216,9 @@ public:
PNS_PLACEMENT_ALGO *Placer() { return m_placer; }
void SetGrid( const VECTOR2I& aOrigin, const VECTOR2I& aSize )
void SetGrid( GRID_HELPER *aGridHelper )
{
m_gridOrigin = aOrigin;
m_gridSize = aSize;
m_gridHelper = aGridHelper;
}
private:
@ -284,8 +283,7 @@ private:
wxString m_toolStatusbarName;
wxString m_failureReason;
VECTOR2I m_gridOrigin;
VECTOR2I m_gridSize;
GRID_HELPER *m_gridHelper;
};
#endif

View File

@ -803,7 +803,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onReverseCollidingVia( PNS_LINE& aCurrent, PN
int currentRank = aCurrent.Rank();
replaceItems( &aCurrent, &shoved );
if ( !pushLine( shoved ) )
if( !pushLine( shoved ) )
return SH_INCOMPLETE;
shoved.SetRank( currentRank );
@ -952,7 +952,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::shoveIteration( int aIter )
popLine();
st = onCollidingLine( revLine, currentLine );
if ( !pushLine( revLine ) )
if( !pushLine( revLine ) )
return SH_INCOMPLETE;
break;
@ -1036,7 +1036,7 @@ OPT_BOX2I PNS_SHOVE::totalAffectedArea() const
if( area )
{
if ( m_affectedAreaSum )
if( m_affectedAreaSum )
area->Merge ( *m_affectedAreaSum );
} else
area = m_affectedAreaSum;
@ -1124,7 +1124,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
if( st == SH_OK || st == SH_HEAD_MODIFIED )
{
pushSpringback( m_currentNode, headSet, PNS_COST_ESTIMATOR(), m_affectedAreaSum);
pushSpringback( m_currentNode, headSet, PNS_COST_ESTIMATOR(), m_affectedAreaSum );
}
else
{
@ -1134,6 +1134,13 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
m_newHead = OPT_LINE();
}
if( m_newHead && head.EndsWithVia() )
{
PNS_VIA v = head.Via();
v.SetPos( m_newHead->CPoint( -1 ) );
m_newHead->AppendVia(v);
}
return st;
}

View File

@ -55,7 +55,9 @@ int PNS_SIZES_SETTINGS::inheritTrackWidth( PNS_ITEM* aItem )
int mval = INT_MAX;
PNS_ITEMSET linkedSegs = jt->Links().ExcludeItem( aItem ).FilterKinds( PNS_ITEM::SEGMENT );
PNS_ITEMSET linkedSegs = jt->Links();
linkedSegs.ExcludeItem( aItem ).FilterKinds( PNS_ITEM::SEGMENT );
BOOST_FOREACH( PNS_ITEM* item, linkedSegs.Items() )
{

View File

@ -42,6 +42,7 @@
#include <tool/context_menu.h>
#include <tools/common_actions.h>
#include <tools/grid_helper.h>
#include <ratsnest_data.h>
@ -75,20 +76,26 @@ PNS_TOOL_BASE::PNS_TOOL_BASE( const std::string& aToolName ) :
m_frame = NULL;
m_ctls = NULL;
m_board = NULL;
m_gridHelper = NULL;
}
PNS_TOOL_BASE::~PNS_TOOL_BASE()
{
delete m_router;
delete m_gridHelper;
}
void PNS_TOOL_BASE::Reset( RESET_REASON aReason )
{
if( m_router )
delete m_router;
if( m_gridHelper)
delete m_gridHelper;
m_frame = getEditFrame<PCB_EDIT_FRAME>();
m_ctls = getViewControls();
m_board = getModel<BOARD>();
@ -100,6 +107,10 @@ void PNS_TOOL_BASE::Reset( RESET_REASON aReason )
m_router->SyncWorld();
m_router->LoadSettings( m_savedSettings );
m_router->UpdateSizes( m_savedSizes );
m_gridHelper = new GRID_HELPER( m_frame );
m_router->SetGrid( m_gridHelper );
m_needsSync = false;
if( getView() )

View File

@ -32,6 +32,7 @@
#include "pns_router.h"
class PNS_TUNE_STATUS_POPUP;
class GRID_HELPER;
class APIEXPORT PNS_TOOL_BASE : public TOOL_INTERACTIVE
{
@ -73,6 +74,8 @@ protected:
PCB_EDIT_FRAME* m_frame;
KIGFX::VIEW_CONTROLS* m_ctls;
BOARD* m_board;
GRID_HELPER* m_gridHelper;
};

View File

@ -46,6 +46,8 @@
#include <tool/tool_settings.h>
#include <tools/common_actions.h>
#include <tools/size_menu.h>
#include <tools/selection_tool.h>
#include <tools/edit_tool.h>
#include <ratsnest_data.h>
@ -551,8 +553,8 @@ void ROUTER_TOOL::performRouting()
break;
else if( evt->IsMotion() )
{
updateEndItem( *evt );
m_router->SetOrthoMode( evt->Modifier( MD_CTRL ) );
updateEndItem( *evt );
m_router->Move( m_endSnapPoint, m_endItem );
}
else if( evt->IsClick( BUT_LEFT ) )
@ -568,6 +570,7 @@ void ROUTER_TOOL::performRouting()
// Synchronize the indicated layer
m_frame->SetActiveLayer( ToLAYER_ID( m_router->GetCurrentLayer() ) );
updateEndItem( *evt );
m_router->Move( m_endSnapPoint, m_endItem );
m_startItem = NULL;
}
@ -586,12 +589,13 @@ void ROUTER_TOOL::performRouting()
else if( evt->IsAction( &ACT_SwitchPosture ) )
{
m_router->FlipPosture();
updateEndItem( *evt );
m_router->Move( m_endSnapPoint, m_endItem ); // refresh
}
else if( evt->IsAction( &COMMON_ACTIONS::layerChanged ) )
{
updateEndItem( *evt );
m_router->SwitchLayer( m_frame->GetActiveLayer() );
updateEndItem( *evt );
m_router->Move( m_endSnapPoint, m_endItem ); // refresh
}
else if( evt->IsAction( &ACT_EndTrack ) )
@ -733,12 +737,15 @@ void ROUTER_TOOL::performDragging()
if( m_startItem && m_startItem->Net() >= 0 )
highlightNet( true, m_startItem->Net() );
ctls->ForceCursorPosition( false );
ctls->SetAutoPan( true );
while( OPT_TOOL_EVENT evt = Wait() )
{
if( evt->IsCancel() || evt->IsActivate() )
ctls->ForceCursorPosition( false );
VECTOR2I p0 = ctls->GetCursorPosition();
if( evt->IsCancel() || evt->IsActivate() )
break;
else if( evt->IsMotion() )
{

View File

@ -112,6 +112,43 @@ VECTOR2I GRID_HELPER::Align( const VECTOR2I& aPoint ) const
}
VECTOR2I GRID_HELPER::AlignToSegment ( const VECTOR2I& aPoint, const SEG& aSeg )
{
OPT_VECTOR2I pts[6];
VECTOR2I origin( GetOrigin() );
VECTOR2I grid( GetGrid() );
const VECTOR2D gridOffset( GetOrigin() );
const VECTOR2D gridSize( GetGrid() );
VECTOR2I nearest( KiROUND( ( aPoint.x - gridOffset.x ) / gridSize.x ) * gridSize.x + gridOffset.x,
KiROUND( ( aPoint.y - gridOffset.y ) / gridSize.y ) * gridSize.y + gridOffset.y );
pts[0] = aSeg.A;
pts[1] = aSeg.B;
pts[2] = aSeg.IntersectLines( SEG( nearest, nearest + VECTOR2I( 1, 0 ) ) );
pts[3] = aSeg.IntersectLines( SEG( nearest, nearest + VECTOR2I( 0, 1 ) ) );
int min_d = std::numeric_limits<int>::max();
for( int i = 0; i < 4; i++ )
{
if( pts[i] && aSeg.Contains( *pts[i] ) )
{
int d = (*pts[i] - aPoint).EuclideanNorm();
if( d < min_d )
{
min_d = d;
nearest = *pts[i];
}
}
}
return nearest;
}
VECTOR2I GRID_HELPER::BestDragOrigin( const VECTOR2I &aMousePos, BOARD_ITEM* aItem )
{
clearAnchors();
@ -135,6 +172,7 @@ VECTOR2I GRID_HELPER::BestDragOrigin( const VECTOR2I &aMousePos, BOARD_ITEM* aIt
if( nearestCorner )
{
double dist = nearestCorner->Distance( aMousePos );
if( dist < minDist )
{
minDist = dist;
@ -145,6 +183,7 @@ VECTOR2I GRID_HELPER::BestDragOrigin( const VECTOR2I &aMousePos, BOARD_ITEM* aIt
if( nearestOutline )
{
double dist = nearestOutline->Distance( aMousePos );
if( minDist > lineSnapMinCornerDistance && dist < minDist )
best = nearestOutline;
}

View File

@ -32,6 +32,8 @@
#include <layers_id_colors_and_visibility.h>
#include <geometry/seg.h>
class PCB_BASE_FRAME;
class GRID_HELPER {
@ -50,6 +52,8 @@ public:
VECTOR2I Align( const VECTOR2I& aPoint ) const;
VECTOR2I AlignToSegment ( const VECTOR2I& aPoint, const SEG& aSeg );
VECTOR2I BestDragOrigin( const VECTOR2I& aMousePos, BOARD_ITEM* aItem );
VECTOR2I BestSnapAnchor( const VECTOR2I& aOrigin, BOARD_ITEM* aDraggedItem );