Pcbnew: fix push and shove router segfault bug.
This commit is contained in:
parent
6d8fb6015b
commit
6e470ece1d
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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() )
|
||||
{
|
||||
|
|
|
@ -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() )
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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() )
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
Loading…
Reference in New Issue