Coverity fixes for issues 314755, 316287, 324536, 324539, and 324539.

This commit is contained in:
Wayne Stambaugh 2021-03-02 08:10:37 -05:00
parent d06e8ef01c
commit 79a9d69ff5
5 changed files with 117 additions and 84 deletions

View File

@ -2,7 +2,7 @@
* KiRouter - a push-and-(sometimes-)shove PCB router * KiRouter - a push-and-(sometimes-)shove PCB router
* *
* Copyright (C) 2013-2017 CERN * Copyright (C) 2013-2017 CERN
* Copyright (C) 2016-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
@ -39,18 +39,18 @@ LINE_PLACER::LINE_PLACER( ROUTER* aRouter ) :
PLACEMENT_ALGO( aRouter ) PLACEMENT_ALGO( aRouter )
{ {
m_initial_direction = DIRECTION_45::N; m_initial_direction = DIRECTION_45::N;
m_world = NULL; m_world = nullptr;
m_shove = NULL; m_shove = nullptr;
m_currentNode = NULL; m_currentNode = nullptr;
m_idle = true; m_idle = true;
// Init temporary variables (do not leave uninitialized members) // Init temporary variables (do not leave uninitialized members)
m_lastNode = NULL; m_lastNode = nullptr;
m_placingVia = false; m_placingVia = false;
m_currentNet = 0; m_currentNet = 0;
m_currentLayer = 0; m_currentLayer = 0;
m_currentMode = RM_MarkObstacles; m_currentMode = RM_MarkObstacles;
m_startItem = NULL; m_startItem = nullptr;
m_chainedPlacement = false; m_chainedPlacement = false;
m_orthoMode = false; m_orthoMode = false;
m_placementCorrect = false; m_placementCorrect = false;
@ -195,6 +195,7 @@ bool LINE_PLACER::handlePullback()
const std::vector<ssize_t>& tailShapes = tail.CShapes(); const std::vector<ssize_t>& tailShapes = tail.CShapes();
wxASSERT( tail.PointCount() >= 2 ); wxASSERT( tail.PointCount() >= 2 );
if( headShapes[0] == -1 ) if( headShapes[0] == -1 )
first_head = DIRECTION_45( head.CSegment( 0 ) ); first_head = DIRECTION_45( head.CSegment( 0 ) );
else else
@ -236,7 +237,7 @@ bool LINE_PLACER::handlePullback()
} }
wxLogTrace( "PNS", "Placer: pullback triggered [%d] [%s %s]", wxLogTrace( "PNS", "Placer: pullback triggered [%d] [%s %s]",
n, last_tail.Format().c_str(), first_head.Format().c_str() ); n, last_tail.Format().c_str(), first_head.Format().c_str() );
// erase the last point in the tail, hoping that the next iteration will // erase the last point in the tail, hoping that the next iteration will
// result with a head trace that starts with a segment following our // result with a head trace that starts with a segment following our
@ -391,7 +392,8 @@ bool LINE_PLACER::mergeHead()
head.Remove( 0, -1 ); head.Remove( 0, -1 );
wxLogTrace( "PNS", "Placer: merge %d, new direction: %s", n_head, m_direction.Format().c_str() ); wxLogTrace( "PNS", "Placer: merge %d, new direction: %s", n_head,
m_direction.Format().c_str() );
head.Simplify(); head.Simplify();
tail.Simplify(); tail.Simplify();
@ -408,7 +410,7 @@ VECTOR2I closestProjectedPoint( const SHAPE_LINE_CHAIN& line, const VECTOR2I& p
for( int i = 0; i < line.SegmentCount(); i++ ) for( int i = 0; i < line.SegmentCount(); i++ )
{ {
const SEG& s = line.CSegment(i); const SEG& s = line.CSegment( i );
VECTOR2I a = s.NearestPoint( p ); VECTOR2I a = s.NearestPoint( p );
int d_sq = (a - p).SquaredEuclideanNorm(); int d_sq = (a - p).SquaredEuclideanNorm();
@ -586,8 +588,8 @@ bool LINE_PLACER::rhShoveOnly( const VECTOR2I& aP, LINE& aNewHead )
l.Line().Simplify(); l.Line().Simplify();
// in certain, uncommon cases there may be loops in the head+tail, In such case, we don't shove to avoid // in certain, uncommon cases there may be loops in the head+tail, In such case, we don't
// screwing up the database. // shove to avoid screwing up the database.
if( l.HasLoops() ) if( l.HasLoops() )
{ {
aNewHead = m_head; aNewHead = m_head;
@ -759,13 +761,12 @@ void LINE_PLACER::routeStep( const VECTOR2I& aP )
n_iter++; n_iter++;
go_back = true; go_back = true;
} }
} }
if( !fail ) if( !fail )
{ {
if( optimizeTailHeadTransition() ) if( optimizeTailHeadTransition() )
return; return;
mergeHead(); mergeHead();
} }
@ -864,7 +865,7 @@ bool LINE_PLACER::SetLayer( int aLayer )
m_tail.Line().Clear(); m_tail.Line().Clear();
m_head.SetLayer( m_currentLayer ); m_head.SetLayer( m_currentLayer );
m_tail.SetLayer( m_currentLayer ); m_tail.SetLayer( m_currentLayer );
Move( m_currentEnd, NULL ); Move( m_currentEnd, nullptr );
return true; return true;
} }
@ -963,7 +964,7 @@ void LINE_PLACER::initPlacement()
m_direction.Format().c_str(), m_direction.Format().c_str(),
m_currentLayer ); m_currentLayer );
m_lastNode = NULL; m_lastNode = nullptr;
m_currentNode = m_world; m_currentNode = m_world;
m_currentMode = Settings().Mode(); m_currentMode = Settings().Mode();
@ -986,7 +987,7 @@ bool LINE_PLACER::Move( const VECTOR2I& aP, ITEM* aEndItem )
if( m_lastNode ) if( m_lastNode )
{ {
delete m_lastNode; delete m_lastNode;
m_lastNode = NULL; m_lastNode = nullptr;
} }
bool reachesEnd = route( p ); bool reachesEnd = route( p );
@ -1068,8 +1069,12 @@ bool LINE_PLACER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinis
if( !pl.EndsWithVia() ) if( !pl.EndsWithVia() )
return false; return false;
m_lastNode->Add( Clone( pl.Via() ) ); ///< @todo Determine what to do if m_lastNode is a null pointer. I'm guessing return
m_currentNode = NULL; ///< false but someone with more knowledge of the code will need to determine that..
if( m_lastNode )
m_lastNode->Add( Clone( pl.Via() ) );
m_currentNode = nullptr;
m_idle = true; m_idle = true;
m_placementCorrect = true; m_placementCorrect = true;
@ -1150,7 +1155,7 @@ bool LINE_PLACER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinis
m_fixedTail.AddStage( m_p_start, m_currentLayer, m_placingVia, m_direction, m_currentNode ); m_fixedTail.AddStage( m_p_start, m_currentLayer, m_placingVia, m_direction, m_currentNode );
m_startItem = NULL; m_startItem = nullptr;
m_placingVia = false; m_placingVia = false;
m_chainedPlacement = !pl.EndsWithVia(); m_chainedPlacement = !pl.EndsWithVia();
@ -1195,7 +1200,7 @@ bool LINE_PLACER::UnfixRoute()
m_head.Line().Clear(); m_head.Line().Clear();
m_tail.Line().Clear(); m_tail.Line().Clear();
m_startItem = NULL; m_startItem = nullptr;
m_p_start = st.pts[0].p; m_p_start = st.pts[0].p;
m_direction = st.pts[0].direction; m_direction = st.pts[0].direction;
m_placingVia = st.pts[0].placingVias; m_placingVia = st.pts[0].placingVias;
@ -1235,8 +1240,8 @@ bool LINE_PLACER::CommitPlacement()
if( m_lastNode ) if( m_lastNode )
Router()->CommitRouting( m_lastNode ); Router()->CommitRouting( m_lastNode );
m_lastNode = NULL; m_lastNode = nullptr;
m_currentNode = NULL; m_currentNode = nullptr;
return true; return true;
} }
@ -1438,21 +1443,25 @@ bool LINE_PLACER::AbortPlacement()
return true; return true;
} }
FIXED_TAIL::FIXED_TAIL( int aLineCount ) FIXED_TAIL::FIXED_TAIL( int aLineCount )
{ {
} }
FIXED_TAIL::~FIXED_TAIL() FIXED_TAIL::~FIXED_TAIL()
{ {
} }
void FIXED_TAIL::Clear() void FIXED_TAIL::Clear()
{ {
m_stages.clear(); m_stages.clear();
} }
void FIXED_TAIL::AddStage( VECTOR2I aStart, int aLayer, bool placingVias, DIRECTION_45 direction, void FIXED_TAIL::AddStage( VECTOR2I aStart, int aLayer, bool placingVias, DIRECTION_45 direction,
NODE *aNode ) NODE *aNode )
{ {
@ -1470,6 +1479,7 @@ void FIXED_TAIL::AddStage( VECTOR2I aStart, int aLayer, bool placingVias, DIRECT
m_stages.push_back( st ); m_stages.push_back( st );
} }
bool FIXED_TAIL::PopStage( FIXED_TAIL::STAGE& aStage ) bool FIXED_TAIL::PopStage( FIXED_TAIL::STAGE& aStage )
{ {
if( !m_stages.size() ) if( !m_stages.size() )

View File

@ -2,7 +2,7 @@
* KiRouter - a push-and-(sometimes-)shove PCB router * KiRouter - a push-and-(sometimes-)shove PCB router
* *
* Copyright (C) 2013-2014 CERN * Copyright (C) 2013-2014 CERN
* Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
@ -121,7 +121,8 @@ bool COST_ESTIMATOR::IsBetter( const COST_ESTIMATOR& aOther, double aLengthToler
OPTIMIZER::OPTIMIZER( NODE* aWorld ) : OPTIMIZER::OPTIMIZER( NODE* aWorld ) :
m_world( aWorld ), m_world( aWorld ),
m_collisionKindMask( ITEM::ANY_T ), m_collisionKindMask( ITEM::ANY_T ),
m_effortLevel( MERGE_SEGMENTS ) m_effortLevel( MERGE_SEGMENTS ),
m_restrictAreaIsStrict( false )
{ {
} }
@ -172,7 +173,8 @@ void OPTIMIZER::cacheAdd( ITEM* aItem, bool aIsStatic = false )
void OPTIMIZER::removeCachedSegments( LINE* aLine, int aStartVertex, int aEndVertex ) void OPTIMIZER::removeCachedSegments( LINE* aLine, int aStartVertex, int aEndVertex )
{ {
if( !aLine->IsLinked() ) return; if( !aLine->IsLinked() )
return;
auto links = aLine->Links(); auto links = aLine->Links();
@ -224,7 +226,7 @@ bool AREA_CONSTRAINT::Check( int aVertex1, int aVertex2, const LINE* aOriginLine
bool p1_in = m_allowedArea.Contains( p1 ); bool p1_in = m_allowedArea.Contains( p1 );
bool p2_in = m_allowedArea.Contains( p2 ); bool p2_in = m_allowedArea.Contains( p2 );
if( m_allowedAreaStrict ) // strict restriction? both points must be inside the restricted area if( m_allowedAreaStrict ) // strict restriction? both points must be inside the restricted area
return p1_in && p2_in; return p1_in && p2_in;
else // loose restriction else // loose restriction
@ -274,7 +276,8 @@ bool RESTRICT_VERTEX_RANGE_CONSTRAINT::Check( int aVertex1, int aVertex2, const
/** /**
* Determine if a point is located within a given polygon * Determine if a point is located within a given polygon
* *
* @todo fixme: integrate into SHAPE_LINE_CHAIN, check corner cases against current PointInside implementation * @todo fixme: integrate into SHAPE_LINE_CHAIN, check corner cases against current PointInside
* implementation
* *
* @param aL Polygon * @param aL Polygon
* @param aP Point to check for location within the polygon * @param aP Point to check for location within the polygon
@ -370,6 +373,7 @@ bool KEEP_TOPOLOGY_CONSTRAINT::Check( int aVertex1, int aVertex2, const LINE* aO
if( pointInside2( encPoly, j->Pos() ) ) if( pointInside2( encPoly, j->Pos() ) )
{ {
bool falsePositive = false; bool falsePositive = false;
for( int k = 0; k < encPoly.PointCount(); k++ ) for( int k = 0; k < encPoly.PointCount(); k++ )
{ {
if( encPoly.CPoint(k) == j->Pos() ) if( encPoly.CPoint(k) == j->Pos() )
@ -609,7 +613,6 @@ bool OPTIMIZER::Optimize( LINE* aLine, LINE* aResult )
AddConstraint( c ); AddConstraint( c );
} }
if( m_effortLevel & KEEP_TOPOLOGY ) if( m_effortLevel & KEEP_TOPOLOGY )
{ {
auto c = new KEEP_TOPOLOGY_CONSTRAINT( m_world ); auto c = new KEEP_TOPOLOGY_CONSTRAINT( m_world );
@ -670,8 +673,8 @@ bool OPTIMIZER::mergeStep( LINE* aLine, SHAPE_LINE_CHAIN& aCurrentPath, int step
SHAPE_LINE_CHAIN bypass = DIRECTION_45().BuildInitialTrace( s1.A, s2.B, i ); SHAPE_LINE_CHAIN bypass = DIRECTION_45().BuildInitialTrace( s1.A, s2.B, i );
cost[i] = INT_MAX; cost[i] = INT_MAX;
bool ok = false; bool ok = false;
if( !checkColliding( aLine, bypass ) ) if( !checkColliding( aLine, bypass ) )
{ {
//printf("Chk-constraints: %d %d\n", n, n+step+1 ); //printf("Chk-constraints: %d %d\n", n, n+step+1 );
@ -1007,6 +1010,7 @@ int OPTIMIZER::smartPadsSingle( LINE* aLine, ITEM* aPad, bool aEnd, int aEndVert
return -1; return -1;
} }
bool OPTIMIZER::runSmartPads( LINE* aLine ) bool OPTIMIZER::runSmartPads( LINE* aLine )
{ {
SHAPE_LINE_CHAIN& line = aLine->Line(); SHAPE_LINE_CHAIN& line = aLine->Line();
@ -1148,7 +1152,8 @@ bool coupledBypass( NODE* aNode, DIFF_PAIR* aPair, bool aRefIsP, const SHAPE_LIN
SHAPE_LINE_CHAIN& aNewCoupled ) SHAPE_LINE_CHAIN& aNewCoupled )
{ {
int vStartIdx[1024]; // fixme: possible overflow int vStartIdx[1024]; // fixme: possible overflow
int nStarts = findCoupledVertices( aRefBypass.CPoint( 0 ), aRefBypass.CSegment( 0 ), int nStarts = findCoupledVertices( aRefBypass.CPoint( 0 ),
aRefBypass.CSegment( 0 ),
aCoupled, aPair, vStartIdx ); aCoupled, aPair, vStartIdx );
DIRECTION_45 dir( aRefBypass.CSegment( 0 ) ); DIRECTION_45 dir( aRefBypass.CSegment( 0 ) );
@ -1192,7 +1197,6 @@ bool coupledBypass( NODE* aNode, DIFF_PAIR* aPair, bool aRefIsP, const SHAPE_LIN
} }
} }
if( found ) if( found )
aNewCoupled = bestBypass; aNewCoupled = bestBypass;
@ -1230,7 +1234,8 @@ bool OPTIMIZER::mergeDpStep( DIFF_PAIR* aPair, bool aTryP, int step )
if( dir1.IsObtuse( dir2 ) ) if( dir1.IsObtuse( dir2 ) )
{ {
SHAPE_LINE_CHAIN bypass = DIRECTION_45().BuildInitialTrace( s1.A, s2.B, dir1.IsDiagonal() ); SHAPE_LINE_CHAIN bypass = DIRECTION_45().BuildInitialTrace( s1.A, s2.B,
dir1.IsDiagonal() );
SHAPE_LINE_CHAIN newRef; SHAPE_LINE_CHAIN newRef;
SHAPE_LINE_CHAIN newCoup; SHAPE_LINE_CHAIN newCoup;
int64_t deltaCoupled = -1, deltaUni = -1; int64_t deltaCoupled = -1, deltaUni = -1;
@ -1289,7 +1294,7 @@ bool OPTIMIZER::mergeDpSegments( DIFF_PAIR* aPair )
if( step_n > max_step_n ) if( step_n > max_step_n )
step_n = max_step_n; step_n = max_step_n;
if( step_p < 1 && step_n < 1) if( step_p < 1 && step_n < 1 )
break; break;
bool found_anything_p = false; bool found_anything_p = false;
@ -1335,9 +1340,10 @@ static int64_t shovedArea( const SHAPE_LINE_CHAIN& aOld, const SHAPE_LINE_CHAIN&
area += -(int64_t) v0.y * v1.x + (int64_t) v0.x * v1.y; area += -(int64_t) v0.y * v1.x + (int64_t) v0.x * v1.y;
} }
return std::abs(area / 2); return std::abs( area / 2 );
} }
bool tightenSegment( bool dir, NODE *aNode, const LINE& cur, const SHAPE_LINE_CHAIN& in, bool tightenSegment( bool dir, NODE *aNode, const LINE& cur, const SHAPE_LINE_CHAIN& in,
SHAPE_LINE_CHAIN& out ) SHAPE_LINE_CHAIN& out )
{ {
@ -1394,7 +1400,6 @@ bool tightenSegment( bool dir, NODE *aNode, const LINE& cur, const SHAPE_LINE_CH
else else
guide = b; guide = b;
initial = guide.Length(); initial = guide.Length();
int step = initial; int step = initial;
@ -1422,17 +1427,16 @@ bool tightenSegment( bool dir, NODE *aNode, const LINE& cur, const SHAPE_LINE_CH
else else
current += step; current += step;
//dbg->AddSegment ( SEG( center.A , a.LineProject( center.A + gr ) ), 3 ); //dbg->AddSegment ( SEG( center.A , a.LineProject( center.A + gr ) ), 3 );
//dbg->AddSegment ( SEG( center.A , center.A + guideA ), 3 ); //dbg->AddSegment ( SEG( center.A , center.A + guideA ), 3 );
//dbg->AddSegment ( SEG( center.B , center.B + guideB ), 4 ); //dbg->AddSegment ( SEG( center.B , center.B + guideB ), 4 );
if ( current == initial ) if ( current == initial )
break; break;
} }
out = snew; out = snew;
//dbg->AddLine ( snew, 3, 100000 ); //dbg->AddLine ( snew, 3, 100000 );
@ -1440,7 +1444,8 @@ bool tightenSegment( bool dir, NODE *aNode, const LINE& cur, const SHAPE_LINE_CH
return true; return true;
} }
void Tighten( NODE *aNode, const SHAPE_LINE_CHAIN& aOldLine, const LINE& aNewLine, LINE& aOptimized ) void Tighten( NODE *aNode, const SHAPE_LINE_CHAIN& aOldLine, const LINE& aNewLine,
LINE& aOptimized )
{ {
LINE tmp; LINE tmp;

View File

@ -2,7 +2,7 @@
* KiRouter - a push-and-(sometimes-)shove PCB router * KiRouter - a push-and-(sometimes-)shove PCB router
* *
* Copyright (C) 2013-2014 CERN * Copyright (C) 2013-2014 CERN
* Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software: you can redistribute it and/or modify it * This program is free software: you can redistribute it and/or modify it
@ -125,6 +125,7 @@ const ITEM_SET ROUTER::QueryHoverItems( const VECTOR2I& aP )
return m_placer->CurrentNode()->HitTest( aP ); return m_placer->CurrentNode()->HitTest( aP );
} }
bool ROUTER::StartDragging( const VECTOR2I& aP, ITEM* aItem, int aDragMode ) bool ROUTER::StartDragging( const VECTOR2I& aP, ITEM* aItem, int aDragMode )
{ {
return StartDragging( aP, ITEM_SET( aItem ), aDragMode ); return StartDragging( aP, ITEM_SET( aItem ), aDragMode );
@ -156,7 +157,8 @@ bool ROUTER::StartDragging( const VECTOR2I& aP, ITEM_SET aStartItems, int aDragM
m_dragger->SetLogger( m_logger ); m_dragger->SetLogger( m_logger );
m_dragger->SetDebugDecorator( m_iface->GetDebugDecorator() ); m_dragger->SetDebugDecorator( m_iface->GetDebugDecorator() );
m_logger->Clear(); if( m_logger )
m_logger->Clear();
if( m_logger && aStartItems.Size() ) if( m_logger && aStartItems.Size() )
{ {
@ -336,6 +338,7 @@ bool ROUTER::isStartingPointRoutable( const VECTOR2I& aWhere, ITEM* aStartItem,
return true; return true;
} }
bool ROUTER::StartRouting( const VECTOR2I& aP, ITEM* aStartItem, int aLayer ) bool ROUTER::StartRouting( const VECTOR2I& aP, ITEM* aStartItem, int aLayer )
{ {
if( !isStartingPointRoutable( aP, aStartItem, aLayer ) ) if( !isStartingPointRoutable( aP, aStartItem, aLayer ) )
@ -345,24 +348,28 @@ bool ROUTER::StartRouting( const VECTOR2I& aP, ITEM* aStartItem, int aLayer )
switch( m_mode ) switch( m_mode )
{ {
case PNS_MODE_ROUTE_SINGLE: case PNS_MODE_ROUTE_SINGLE:
m_placer = std::make_unique<LINE_PLACER>( this ); m_placer = std::make_unique<LINE_PLACER>( this );
break; break;
case PNS_MODE_ROUTE_DIFF_PAIR:
m_placer = std::make_unique<DIFF_PAIR_PLACER>( this );
break;
case PNS_MODE_TUNE_SINGLE:
m_placer = std::make_unique<MEANDER_PLACER>( this );
break;
case PNS_MODE_TUNE_DIFF_PAIR:
m_placer = std::make_unique<DP_MEANDER_PLACER>( this );
break;
case PNS_MODE_TUNE_DIFF_PAIR_SKEW:
m_placer = std::make_unique<MEANDER_SKEW_PLACER>( this );
break;
default: case PNS_MODE_ROUTE_DIFF_PAIR:
return false; m_placer = std::make_unique<DIFF_PAIR_PLACER>( this );
break;
case PNS_MODE_TUNE_SINGLE:
m_placer = std::make_unique<MEANDER_PLACER>( this );
break;
case PNS_MODE_TUNE_DIFF_PAIR:
m_placer = std::make_unique<DP_MEANDER_PLACER>( this );
break;
case PNS_MODE_TUNE_DIFF_PAIR_SKEW:
m_placer = std::make_unique<MEANDER_SKEW_PLACER>( this );
break;
default:
return false;
} }
m_placer->UpdateSizes( m_sizes ); m_placer->UpdateSizes( m_sizes );
@ -370,10 +377,11 @@ bool ROUTER::StartRouting( const VECTOR2I& aP, ITEM* aStartItem, int aLayer )
m_placer->SetDebugDecorator( m_iface->GetDebugDecorator() ); m_placer->SetDebugDecorator( m_iface->GetDebugDecorator() );
m_placer->SetLogger( m_logger ); m_placer->SetLogger( m_logger );
m_logger->Clear();
if( m_logger ) if( m_logger )
{
m_logger->Clear();
m_logger->Log( LOGGER::EVT_START_ROUTE, aP, aStartItem ); m_logger->Log( LOGGER::EVT_START_ROUTE, aP, aStartItem );
}
bool rv = m_placer->Start( aP, aStartItem ); bool rv = m_placer->Start( aP, aStartItem );
@ -440,7 +448,7 @@ void ROUTER::markViolations( NODE* aNode, ITEM_SET& aCurrent, NODE::ITEM_VECTOR&
if( itemToMark->Kind() == ITEM::SOLID_T ) if( itemToMark->Kind() == ITEM::SOLID_T )
{ {
if( ( itemToMark->Marker() & PNS::MK_HOLE ) if( ( itemToMark->Marker() & PNS::MK_HOLE )
|| !m_iface->IsFlashedOnLayer( itemToMark, itemToMark->Layer() ) ) || !m_iface->IsFlashedOnLayer( itemToMark, itemToMark->Layer() ) )
{ {
SOLID* solid = static_cast<SOLID*>( tmp.get() ); SOLID* solid = static_cast<SOLID*>( tmp.get() );
solid->SetShape( solid->Hole()->Clone() ); solid->SetShape( solid->Hole()->Clone() );
@ -520,7 +528,7 @@ void ROUTER::UpdateSizes( const SIZES_SETTINGS& aSizes )
m_sizes = aSizes; m_sizes = aSizes;
// Change track/via size settings // Change track/via size settings
if( m_state == ROUTE_TRACK) if( m_state == ROUTE_TRACK )
{ {
m_placer->UpdateSizes( m_sizes ); m_placer->UpdateSizes( m_sizes );
} }
@ -804,7 +812,6 @@ void ROUTER::BreakSegment( ITEM *aItem, const VECTOR2I& aP )
{ {
delete node; delete node;
} }
} }
} }

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2019-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -317,6 +317,9 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
b = *bg->GetItems().begin(); b = *bg->GetItems().begin();
} }
// a and b could be null after group tests above.
wxCHECK( a && b, 0 );
if( a->Type() == PCB_TRACE_T || a->Type() == PCB_ARC_T ) if( a->Type() == PCB_TRACE_T || a->Type() == PCB_ARC_T )
{ {
layer = a->GetLayer(); layer = a->GetLayer();
@ -474,9 +477,10 @@ int BOARD_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent )
m_inspectConstraintsDialog = std::make_unique<DIALOG_CONSTRAINTS_REPORTER>( m_frame ); m_inspectConstraintsDialog = std::make_unique<DIALOG_CONSTRAINTS_REPORTER>( m_frame );
m_inspectConstraintsDialog->SetTitle( _( "Constraints Report" ) ); m_inspectConstraintsDialog->SetTitle( _( "Constraints Report" ) );
m_inspectConstraintsDialog->Connect( wxEVT_CLOSE_WINDOW, m_inspectConstraintsDialog->Connect(
wxCommandEventHandler( BOARD_INSPECTION_TOOL::onInspectConstraintsDialogClosed ), wxEVT_CLOSE_WINDOW,
nullptr, this ); wxCommandEventHandler( BOARD_INSPECTION_TOOL::onInspectConstraintsDialogClosed ),
nullptr, this );
} }
m_inspectConstraintsDialog->DeleteAllPages(); m_inspectConstraintsDialog->DeleteAllPages();
@ -740,13 +744,6 @@ int BOARD_INSPECTION_TOOL::HighlightItem( const TOOL_EVENT& aEvent )
} }
/**
* Look for a BOARD_CONNECTED_ITEM in a given spot and if one is found - it enables
* highlight for its net.
*
* @param aPosition is the point where an item is expected (world coordinates).
* @param aUseSelection is true if we should use the current selection to pick the netcode
*/
bool BOARD_INSPECTION_TOOL::highlightNet( const VECTOR2D& aPosition, bool aUseSelection ) bool BOARD_INSPECTION_TOOL::highlightNet( const VECTOR2D& aPosition, bool aUseSelection )
{ {
BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() ); BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
@ -840,8 +837,7 @@ int BOARD_INSPECTION_TOOL::HighlightItem( const TOOL_EVENT& aEvent )
if( net > 0 && netcodes.count( net ) ) if( net > 0 && netcodes.count( net ) )
enableHighlight = !settings->IsHighlightEnabled(); enableHighlight = !settings->IsHighlightEnabled();
if( enableHighlight != settings->IsHighlightEnabled() if( enableHighlight != settings->IsHighlightEnabled() || !netcodes.count( net ) )
|| !netcodes.count( net ) )
{ {
if( !netcodes.empty() ) if( !netcodes.empty() )
m_lastNetcode = *netcodes.begin(); m_lastNetcode = *netcodes.begin();
@ -1181,7 +1177,8 @@ void BOARD_INSPECTION_TOOL::onListNetsDialogClosed( wxCommandEvent& event )
void BOARD_INSPECTION_TOOL::onInspectClearanceDialogClosed( wxCommandEvent& event ) void BOARD_INSPECTION_TOOL::onInspectClearanceDialogClosed( wxCommandEvent& event )
{ {
m_inspectClearanceDialog->Disconnect( wxEVT_CLOSE_WINDOW, m_inspectClearanceDialog->Disconnect( wxEVT_CLOSE_WINDOW,
wxCommandEventHandler( BOARD_INSPECTION_TOOL::onInspectClearanceDialogClosed ), nullptr, this ); wxCommandEventHandler( BOARD_INSPECTION_TOOL::onInspectClearanceDialogClosed ),
nullptr, this );
m_inspectClearanceDialog->Destroy(); m_inspectClearanceDialog->Destroy();
m_inspectClearanceDialog.release(); m_inspectClearanceDialog.release();
@ -1191,7 +1188,8 @@ void BOARD_INSPECTION_TOOL::onInspectClearanceDialogClosed( wxCommandEvent& even
void BOARD_INSPECTION_TOOL::onInspectConstraintsDialogClosed( wxCommandEvent& event ) void BOARD_INSPECTION_TOOL::onInspectConstraintsDialogClosed( wxCommandEvent& event )
{ {
m_inspectConstraintsDialog->Disconnect( wxEVT_CLOSE_WINDOW, m_inspectConstraintsDialog->Disconnect( wxEVT_CLOSE_WINDOW,
wxCommandEventHandler( BOARD_INSPECTION_TOOL::onInspectConstraintsDialogClosed ), nullptr, this ); wxCommandEventHandler( BOARD_INSPECTION_TOOL::onInspectConstraintsDialogClosed ),
nullptr, this );
m_inspectConstraintsDialog->Destroy(); m_inspectConstraintsDialog->Destroy();
m_inspectConstraintsDialog.release(); m_inspectConstraintsDialog.release();
@ -1252,18 +1250,24 @@ void BOARD_INSPECTION_TOOL::setTransitions()
Go( &BOARD_INSPECTION_TOOL::CrossProbePcbToSch, EVENTS::UnselectedEvent ); Go( &BOARD_INSPECTION_TOOL::CrossProbePcbToSch, EVENTS::UnselectedEvent );
Go( &BOARD_INSPECTION_TOOL::CrossProbePcbToSch, EVENTS::ClearedEvent ); Go( &BOARD_INSPECTION_TOOL::CrossProbePcbToSch, EVENTS::ClearedEvent );
Go( &BOARD_INSPECTION_TOOL::LocalRatsnestTool, PCB_ACTIONS::localRatsnestTool.MakeEvent() ); Go( &BOARD_INSPECTION_TOOL::LocalRatsnestTool,
Go( &BOARD_INSPECTION_TOOL::HideDynamicRatsnest, PCB_ACTIONS::hideDynamicRatsnest.MakeEvent() ); PCB_ACTIONS::localRatsnestTool.MakeEvent() );
Go( &BOARD_INSPECTION_TOOL::UpdateSelectionRatsnest,PCB_ACTIONS::updateLocalRatsnest.MakeEvent() ); Go( &BOARD_INSPECTION_TOOL::HideDynamicRatsnest,
PCB_ACTIONS::hideDynamicRatsnest.MakeEvent() );
Go( &BOARD_INSPECTION_TOOL::UpdateSelectionRatsnest,
PCB_ACTIONS::updateLocalRatsnest.MakeEvent() );
Go( &BOARD_INSPECTION_TOOL::ListNets, PCB_ACTIONS::listNets.MakeEvent() ); Go( &BOARD_INSPECTION_TOOL::ListNets, PCB_ACTIONS::listNets.MakeEvent() );
Go( &BOARD_INSPECTION_TOOL::ShowStatisticsDialog, PCB_ACTIONS::boardStatistics.MakeEvent() ); Go( &BOARD_INSPECTION_TOOL::ShowStatisticsDialog, PCB_ACTIONS::boardStatistics.MakeEvent() );
Go( &BOARD_INSPECTION_TOOL::InspectClearance, PCB_ACTIONS::inspectClearance.MakeEvent() ); Go( &BOARD_INSPECTION_TOOL::InspectClearance, PCB_ACTIONS::inspectClearance.MakeEvent() );
Go( &BOARD_INSPECTION_TOOL::InspectConstraints, PCB_ACTIONS::inspectConstraints.MakeEvent() ); Go( &BOARD_INSPECTION_TOOL::InspectConstraints,
PCB_ACTIONS::inspectConstraints.MakeEvent() );
Go( &BOARD_INSPECTION_TOOL::HighlightNet, PCB_ACTIONS::highlightNet.MakeEvent() ); Go( &BOARD_INSPECTION_TOOL::HighlightNet, PCB_ACTIONS::highlightNet.MakeEvent() );
Go( &BOARD_INSPECTION_TOOL::HighlightNet, PCB_ACTIONS::highlightNetSelection.MakeEvent() ); Go( &BOARD_INSPECTION_TOOL::HighlightNet,
Go( &BOARD_INSPECTION_TOOL::HighlightNet, PCB_ACTIONS::toggleLastNetHighlight.MakeEvent() ); PCB_ACTIONS::highlightNetSelection.MakeEvent() );
Go( &BOARD_INSPECTION_TOOL::HighlightNet,
PCB_ACTIONS::toggleLastNetHighlight.MakeEvent() );
Go( &BOARD_INSPECTION_TOOL::ClearHighlight, PCB_ACTIONS::clearHighlight.MakeEvent() ); Go( &BOARD_INSPECTION_TOOL::ClearHighlight, PCB_ACTIONS::clearHighlight.MakeEvent() );
Go( &BOARD_INSPECTION_TOOL::HighlightNetTool, PCB_ACTIONS::highlightNetTool.MakeEvent() ); Go( &BOARD_INSPECTION_TOOL::HighlightNetTool, PCB_ACTIONS::highlightNetTool.MakeEvent() );
Go( &BOARD_INSPECTION_TOOL::ClearHighlight, ACTIONS::cancelInteractive.MakeEvent() ); Go( &BOARD_INSPECTION_TOOL::ClearHighlight, ACTIONS::cancelInteractive.MakeEvent() );

View File

@ -115,6 +115,13 @@ private:
///< Recalculate dynamic ratsnest for the current selection. ///< Recalculate dynamic ratsnest for the current selection.
void calculateSelectionRatsnest( const VECTOR2I& aDelta ); void calculateSelectionRatsnest( const VECTOR2I& aDelta );
/**
* Look for a #BOARD_CONNECTED_ITEM in a given spot and if one is found - it enables
* highlight for its net.
*
* @param aPosition is the point where an item is expected (world coordinates).
* @param aUseSelection is true if we should use the current selection to pick the netcode
*/
bool highlightNet( const VECTOR2D& aPosition, bool aUseSelection ); bool highlightNet( const VECTOR2D& aPosition, bool aUseSelection );
void doHideNet( int aNetCode, bool aHide ); void doHideNet( int aNetCode, bool aHide );