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

View File

@ -35,6 +35,8 @@
#include <geometry/shape_rect.h> #include <geometry/shape_rect.h>
#include <geometry/shape_circle.h> #include <geometry/shape_circle.h>
#include <tools/grid_helper.h>
#include "trace.h" #include "trace.h"
#include "pns_node.h" #include "pns_node.h"
#include "pns_line_placer.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; anchor = s.B;
else else
{ {
anchor = s.NearestPoint( aP ); anchor = m_gridHelper->AlignToSegment ( aP, s );
aSplitsSegment = true; aSplitsSegment = (anchor != s.A && anchor != s.B );
} }
break; break;

View File

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

View File

@ -803,7 +803,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onReverseCollidingVia( PNS_LINE& aCurrent, PN
int currentRank = aCurrent.Rank(); int currentRank = aCurrent.Rank();
replaceItems( &aCurrent, &shoved ); replaceItems( &aCurrent, &shoved );
if ( !pushLine( shoved ) ) if( !pushLine( shoved ) )
return SH_INCOMPLETE; return SH_INCOMPLETE;
shoved.SetRank( currentRank ); shoved.SetRank( currentRank );
@ -952,7 +952,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::shoveIteration( int aIter )
popLine(); popLine();
st = onCollidingLine( revLine, currentLine ); st = onCollidingLine( revLine, currentLine );
if ( !pushLine( revLine ) ) if( !pushLine( revLine ) )
return SH_INCOMPLETE; return SH_INCOMPLETE;
break; break;
@ -1036,7 +1036,7 @@ OPT_BOX2I PNS_SHOVE::totalAffectedArea() const
if( area ) if( area )
{ {
if ( m_affectedAreaSum ) if( m_affectedAreaSum )
area->Merge ( *m_affectedAreaSum ); area->Merge ( *m_affectedAreaSum );
} else } else
area = m_affectedAreaSum; 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 ) 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 else
{ {
@ -1134,6 +1134,13 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
m_newHead = OPT_LINE(); 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; return st;
} }

View File

@ -55,7 +55,9 @@ int PNS_SIZES_SETTINGS::inheritTrackWidth( PNS_ITEM* aItem )
int mval = INT_MAX; 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() ) BOOST_FOREACH( PNS_ITEM* item, linkedSegs.Items() )
{ {

View File

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

View File

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

View File

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

View File

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