Pull netname bug fixes and performance improvements back from master.

This commit is contained in:
Jeff Young 2024-06-14 18:21:48 +01:00
parent 74abb40e84
commit 245894e8eb
14 changed files with 210 additions and 184 deletions

View File

@ -399,35 +399,19 @@ void VIEW::SetRequired( int aLayerId, int aRequiredId, bool aRequired )
}
// stupid C++... python lambda would do this in one line
template <class CONTAINER>
struct QUERY_VISITOR
{
typedef typename CONTAINER::value_type item_type;
QUERY_VISITOR( CONTAINER& aCont, int aLayer ) :
m_cont( aCont ), m_layer( aLayer )
{
}
bool operator()( VIEW_ITEM* aItem )
{
if( aItem->viewPrivData()->GetFlags() & VISIBLE )
m_cont.push_back( VIEW::LAYER_ITEM_PAIR( aItem, m_layer ) );
return true;
}
CONTAINER& m_cont;
int m_layer;
};
int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) const
{
if( m_orderedLayers.empty() )
return 0;
int layer = UNDEFINED_LAYER;
auto visitor =
[&]( VIEW_ITEM* item ) -> bool
{
aResult.push_back( VIEW::LAYER_ITEM_PAIR( item, layer ) );
return true;
};
std::vector<VIEW_LAYER*>::const_reverse_iterator i;
// execute queries in reverse direction, so that items that are on the top of
@ -438,7 +422,7 @@ int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) con
if( ( *i )->displayOnly || !( *i )->visible )
continue;
QUERY_VISITOR<std::vector<LAYER_ITEM_PAIR> > visitor( aResult, ( *i )->id );
layer = ( *i )->id;
( *i )->items->Query( aRect, visitor );
}
@ -446,6 +430,22 @@ int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) con
}
void VIEW::Query( const BOX2I& aRect, const std::function<bool( VIEW_ITEM* )>& aFunc ) const
{
if( m_orderedLayers.empty() )
return;
for( const auto& i : m_orderedLayers )
{
// ignore layers that do not contain actual items (i.e. the selection box, menus, floats)
if( i->displayOnly || !i->visible )
continue;
i->items->Query( aRect, aFunc );
}
}
VECTOR2D VIEW::ToWorld( const VECTOR2D& aCoord, bool aAbsolute ) const
{
const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix();

View File

@ -108,13 +108,19 @@ public:
/**
* Find all visible items that touch or are within the rectangle \a aRect.
*
* @param aRect area to search for items
* @param aResult result of the search, containing VIEW_ITEMs associated with their layers.
* Sorted according to the rendering order (items that are on top of the
* rendering stack as first).
* @return Number of found items.
*/
virtual int Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) const;
int Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) const;
/**
* Run a function on all visible items that touch or are within the rectangle \a aRect.
*
* @param aFunc the function to be executed; return true to continue, false to end query.
*/
void Query( const BOX2I& aRect, const std::function<bool( VIEW_ITEM* )>& aFunc ) const;
/**
* Set the item visibility.

View File

@ -863,4 +863,50 @@ typedef BOX2<VECTOR2D> BOX2D;
typedef std::optional<BOX2I> OPT_BOX2I;
inline BOX2I BOX2ISafe( const BOX2D& aInput )
{
constexpr double high = std::numeric_limits<int>::max();
constexpr double low = -std::numeric_limits<int>::max();
int left = (int) std::clamp( aInput.GetLeft(), low, high );
int top = (int) std::clamp( aInput.GetTop(), low, high );
int64_t right = (int64_t) std::clamp( aInput.GetRight(), low, high );
int64_t bottom = (int64_t) std::clamp( aInput.GetBottom(), low, high );
return BOX2I( VECTOR2I( left, top ), VECTOR2L( right - left, bottom - top ) );
}
inline BOX2I BOX2ISafe( const VECTOR2D& aPos, const VECTOR2D& aSize )
{
constexpr double high = std::numeric_limits<int>::max();
constexpr double low = -std::numeric_limits<int>::max();
int left = (int) std::clamp( aPos.x, low, high );
int top = (int) std::clamp( aPos.y, low, high );
int64_t right = (int64_t) std::clamp( aPos.x + aSize.x, low, high );
int64_t bottom = (int64_t) std::clamp( aPos.y + aSize.y, low, high );
return BOX2I( VECTOR2I( left, top ), VECTOR2L( right - left, bottom - top ) );
}
template <typename S, std::enable_if_t<std::is_integral<S>::value, int> = 0>
inline BOX2I BOX2ISafe( const VECTOR2I& aPos, const VECTOR2<S>& aSize )
{
constexpr int64_t high = std::numeric_limits<int>::max();
constexpr int64_t low = -std::numeric_limits<int>::max();
int64_t ext_right = int64_t( aPos.x ) + aSize.x;
int64_t ext_bottom = int64_t( aPos.y ) + aSize.y;
int64_t right = std::clamp( ext_right, low, high );
int64_t bottom = std::clamp( ext_bottom, low, high );
return BOX2I( aPos, VECTOR2L( right - aPos.x, bottom - aPos.y ) );
}
#endif

View File

@ -586,6 +586,7 @@ std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector )
/* Default specializations */
typedef VECTOR2<double> VECTOR2D;
typedef VECTOR2<int> VECTOR2I;
typedef VECTOR2<int64_t> VECTOR2L;
/* KiROUND specialization for vectors */
inline VECTOR2I KiROUND( const VECTOR2D& vec )

View File

@ -132,15 +132,28 @@ wxString BOARD_CONNECTED_ITEM::GetNetnameMsg() const
}
wxString BOARD_CONNECTED_ITEM::GetShortNetname() const
const wxString& BOARD_CONNECTED_ITEM::GetShortNetname() const
{
return m_netinfo ? m_netinfo->GetShortNetname() : wxString();
static wxString emptyString;
return m_netinfo ? m_netinfo->GetShortNetname() : emptyString;
}
wxString BOARD_CONNECTED_ITEM::GetUnescapedShortNetname() const
const wxString& BOARD_CONNECTED_ITEM::GetDisplayNetname() const
{
return m_netinfo ? m_netinfo->GetUnescapedShortNetname() : wxString();
static wxString emptyString;
if( !m_netinfo )
return emptyString;
if( const BOARD* board = GetBoard() )
{
if( board->GetNetInfo().m_DisplayNetnamesDirty )
board->GetNetInfo().RebuildDisplayNetnames();
}
return m_netinfo->GetDisplayNetname();
}

View File

@ -124,12 +124,12 @@ public:
/**
* @return the short netname.
*/
wxString GetShortNetname() const;
const wxString& GetShortNetname() const;
/**
* @return the unescaped short netname.
*/
wxString GetUnescapedShortNetname() const;
const wxString& GetDisplayNetname() const;
/**
* Return an item's "own" clearance in internal units.

View File

@ -121,7 +121,7 @@ public:
/**
* @return the unescaped short netname.
*/
const wxString& GetUnescapedShortNetname() const { return m_unescapedShortNetname; }
const wxString& GetDisplayNetname() const { return m_displayNetname; }
/**
* @return true if the net was not labelled by the user.
@ -145,7 +145,7 @@ public:
else
m_shortNetname = aNewName;
m_unescapedShortNetname = UnescapeString( m_shortNetname );
m_displayNetname = UnescapeString( m_shortNetname );
}
bool IsCurrent() const { return m_isCurrent; }
@ -189,10 +189,14 @@ protected:
private:
friend class NETINFO_LIST;
int m_netCode; ///< A number equivalent to the net name.
wxString m_netname; ///< Full net name like /sheet/subsheet/vout used by Eeschema.
wxString m_shortNetname; ///< Short net name, like vout from /sheet/subsheet/vout.
wxString m_unescapedShortNetname; ///< Unescaped short net name.
int m_netCode; ///< A number equivalent to the net name.
wxString m_netname; ///< Full net name like /sheet/subsheet/vout used by Eeschema.
wxString m_shortNetname; ///< Short net name, like vout from /sheet/subsheet/vout.
wxString m_displayNetname; ///< Unescaped netname for display. Usually the short netname,
///< but will be the full netname if disambiguation required.
///< The NETINFO_LIST is repsonsible for the management of when
///< these need to be updated/disambiguated.
std::shared_ptr<NETCLASS> m_netClass;
@ -370,6 +374,8 @@ public:
/// Return the netcode map, at least for python.
const NETCODES_MAP& NetsByNetcode() const { return m_netCodes; }
void RebuildDisplayNetnames() const;
/// Constant that holds the "unconnected net" number (typically 0)
/// all items "connected" to this net are actually not connected items
static const int UNCONNECTED;
@ -490,6 +496,10 @@ private:
*/
int getFreeNetCode();
public:
mutable bool m_DisplayNetnamesDirty;
private:
BOARD* m_parent;
NETNAMES_MAP m_netNames; ///< map of <wxString, NETINFO_ITEM*>, is NETINFO_ITEM owner

View File

@ -44,7 +44,7 @@ NETINFO_ITEM::NETINFO_ITEM( BOARD* aParent, const wxString& aNetName, int aNetCo
m_netCode( aNetCode ),
m_netname( aNetName ),
m_shortNetname( m_netname.AfterLast( '/' ) ),
m_unescapedShortNetname( UnescapeString( m_shortNetname ) ),
m_displayNetname( UnescapeString( m_shortNetname ) ),
m_isCurrent( true )
{
m_parent = aParent;

View File

@ -110,7 +110,10 @@ void NETINFO_LIST::RemoveNet( NETINFO_ITEM* aNet )
}
if( removed )
{
m_newNetCode = std::min( m_newNetCode, aNet->m_netCode - 1 );
m_DisplayNetnamesDirty = true;
}
}
@ -129,9 +132,12 @@ void NETINFO_LIST::RemoveUnusedNets( BOARD_COMMIT* aCommit )
m_netNames.insert( std::make_pair( netInfo->GetNetname(), netInfo ) );
m_netCodes.insert( std::make_pair( netCode, netInfo ) );
}
else if( aCommit )
else
{
aCommit->Removed( netInfo );
m_DisplayNetnamesDirty = true;
if( aCommit )
aCommit->Removed( netInfo );
}
}
}
@ -162,6 +168,8 @@ void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement )
// add an entry for fast look up by a net name using a map
m_netNames.insert( std::make_pair( aNewElement->GetNetname(), aNewElement ) );
m_netCodes.insert( std::make_pair( aNewElement->GetNetCode(), aNewElement ) );
m_DisplayNetnamesDirty = true;
}
@ -176,6 +184,25 @@ void NETINFO_LIST::buildListOfNets()
}
void NETINFO_LIST::RebuildDisplayNetnames() const
{
std::map<wxString, int> shortNames;
for( NETINFO_ITEM* net : *this )
shortNames[net->m_shortNetname]++;
for( NETINFO_ITEM* net : *this )
{
if( shortNames[net->m_shortNetname] == 1 )
net->m_displayNetname = UnescapeString( net->m_shortNetname );
else
net->m_displayNetname = UnescapeString( net->m_netname );
}
m_DisplayNetnamesDirty = false;
}
#if defined(DEBUG)
void NETINFO_LIST::Show() const
{

View File

@ -376,20 +376,11 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
// to calculate the wrong zoom size. See PCB_EDIT_FRAME::onSize().
Bind( wxEVT_SIZE, &PCB_EDIT_FRAME::onSize, this );
// Redraw netnames (so that they fall within the current viewport) after the viewport
// has stopped changing. Redrawing them without the timer moves them smoothly with scrolling,
// making it look like the tracks are being dragged -- which we don't want.
m_redrawNetnamesTimer.SetOwner( this );
Connect( wxEVT_TIMER, wxTimerEventHandler( PCB_EDIT_FRAME::redrawNetnames ), nullptr, this );
Bind( wxEVT_IDLE,
[this]( wxIdleEvent& aEvent )
{
if( GetCanvas()->GetView()->GetViewport() != m_lastViewport )
{
m_lastViewport = GetCanvas()->GetView()->GetViewport();
m_redrawNetnamesTimer.StartOnce( 500 );
}
if( GetCanvas()->GetView()->GetViewport() != m_lastNetnamesViewport )
redrawNetnames();
// Do not forget to pass the Idle event to other clients:
aEvent.Skip();
@ -547,43 +538,42 @@ BOARD_ITEM_CONTAINER* PCB_EDIT_FRAME::GetModel() const
}
void PCB_EDIT_FRAME::redrawNetnames( wxTimerEvent& aEvent )
void PCB_EDIT_FRAME::redrawNetnames()
{
bool needs_refresh = false;
// Don't stomp on the auto-save timer event.
if( aEvent.GetId() == ID_AUTO_SAVE_TIMER )
{
aEvent.Skip();
return;
}
/*
* While new items being scrolled into the view will get painted, they will only get
* annotated with netname instances currently within the view. Subsequent panning will not
* draw newly-visible netname instances because the item has already been drawn.
*
* This routine, fired on idle if the viewport has changed, looks for visible items that
* might have multiple netname instances and redraws them. (It does not need to handle pads
* and vias because they only ever have a single netname instance drawn on them.)
*/
PCBNEW_SETTINGS* cfg = dynamic_cast<PCBNEW_SETTINGS*>( Kiface().KifaceSettings() );
if( !cfg || cfg->m_Display.m_NetNames < 2 )
return;
KIGFX::VIEW* view = GetCanvas()->GetView();
double scale = view->GetScale();
BOX2D viewport = view->GetViewport();
double scale = view->GetScale();
for( PCB_TRACK* track : GetBoard()->Tracks() )
{
double lod = track->ViewGetLOD( GetNetnameLayer( track->GetLayer() ), view );
m_lastNetnamesViewport = viewport;
if( lod < scale )
continue;
view->Query( BOX2ISafe( viewport ),
[&]( KIGFX::VIEW_ITEM* viewItem ) -> bool
{
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( viewItem );
if( lod != track->GetCachedLOD() || scale != track->GetCachedScale() )
{
view->Update( track, KIGFX::REPAINT );
needs_refresh = true;
track->SetCachedLOD( lod );
track->SetCachedScale( scale );
}
}
if( item->IsConnected()
&& ( item->Type() == PCB_TRACE_T || item->Type() == PCB_SHAPE_T )
&& item->ViewGetLOD( GetNetnameLayer( item->GetLayer() ), view ) < scale )
{
view->Update( item, KIGFX::REPAINT );
}
if( needs_refresh )
GetCanvas()->Refresh();
return true;
} );
}

View File

@ -806,7 +806,7 @@ protected:
int inferLegacyEdgeClearance( BOARD* aBoard, bool aShowUserMsg = true );
void redrawNetnames( wxTimerEvent& aEvent );
void redrawNetnames();
void saveProjectSettings() override;
@ -854,8 +854,7 @@ private:
/**
* Keep track of viewport so that track net labels can be adjusted when it changes.
*/
BOX2D m_lastViewport;
wxTimer m_redrawNetnamesTimer;
BOX2D m_lastNetnamesViewport;
wxTimer* m_eventCounterTimer;
};

View File

@ -705,15 +705,7 @@ void PCB_PAINTER::draw( const PCB_TRACK* aTrack, int aLayer )
return;
SHAPE_SEGMENT trackShape( { aTrack->GetStart(), aTrack->GetEnd() }, aTrack->GetWidth() );
wxString netname = aTrack->GetUnescapedShortNetname();
for( const auto& netinfo : aTrack->GetBoard()->GetNetInfo() )
{
if( netinfo->GetUnescapedShortNetname() == netname )
netname = UnescapeString( aTrack->GetNetname() );
}
renderNetNameForSegment( trackShape, color, netname );
renderNetNameForSegment( trackShape, color, aTrack->GetDisplayNetname() );
return;
}
else if( IsCopperLayer( aLayer ) || aLayer == LAYER_LOCKED_ITEM_SHADOW )
@ -761,17 +753,13 @@ void PCB_PAINTER::renderNetNameForSegment( const SHAPE_SEGMENT& aSeg, const COLO
viewport.SetEnd( VECTOR2D( matrix * screenSize ) );
viewport.Normalize();
BOX2I clipBox( viewport.GetOrigin(), viewport.GetSize() );
SEG visibleSeg( aSeg.GetSeg().A, aSeg.GetSeg().B );
ClipLine( &clipBox, visibleSeg.A.x, visibleSeg.A.y, visibleSeg.B.x, visibleSeg.B.y );
size_t num_char = aNetName.size();
int num_char = aNetName.size();
// Check if the track is long enough to have a netname displayed
int seg_minlength = aSeg.GetWidth() * num_char;
int seg_minlength = aSeg.GetWidth() * num_char;
SEG::ecoord seg_minlength_sq = seg_minlength * seg_minlength;
if( visibleSeg.Length() < seg_minlength )
if( aSeg.GetSeg().SquaredLength() < seg_minlength_sq )
return;
double textSize = aSeg.GetWidth();
@ -781,27 +769,25 @@ void PCB_PAINTER::renderNetNameForSegment( const SHAPE_SEGMENT& aSeg, const COLO
VECTOR2I start = aSeg.GetSeg().A;
VECTOR2I end = aSeg.GetSeg().B;
VECTOR2D segV = end - start;
if( end.y == start.y ) // horizontal
{
textOrientation = ANGLE_HORIZONTAL;
num_names = std::max( num_names,
static_cast<int>( aSeg.GetSeg().Length() / viewport.GetWidth() ) );
num_names = std::max( num_names, KiROUND( aSeg.GetSeg().Length() / viewport.GetWidth() ) );
}
else if( end.x == start.x ) // vertical
{
textOrientation = ANGLE_VERTICAL;
num_names = std::max( num_names,
static_cast<int>( aSeg.GetSeg().Length() / viewport.GetHeight() ) );
num_names = std::max( num_names, KiROUND( aSeg.GetSeg().Length() / viewport.GetHeight() ) );
}
else
{
textOrientation = -EDA_ANGLE( visibleSeg.B - visibleSeg.A );
textOrientation = -EDA_ANGLE( segV );
textOrientation.Normalize90();
double min_size = std::min( viewport.GetWidth(), viewport.GetHeight() );
num_names = std::max( num_names,
static_cast<int>( aSeg.GetSeg().Length() / ( M_SQRT2 * min_size ) ) );
num_names = std::max( num_names, KiROUND( aSeg.GetSeg().Length() / ( M_SQRT2 * min_size ) ) );
}
m_gal->SetIsStroke( true );
@ -816,13 +802,13 @@ void PCB_PAINTER::renderNetNameForSegment( const SHAPE_SEGMENT& aSeg, const COLO
m_gal->SetHorizontalJustify( GR_TEXT_H_ALIGN_CENTER );
m_gal->SetVerticalJustify( GR_TEXT_V_ALIGN_CENTER );
for( int ii = 0; ii < num_names; ++ii )
{
VECTOR2I textPosition =
VECTOR2D( start ) * static_cast<double>( num_names - ii ) / ( num_names + 1 )
+ VECTOR2D( end ) * static_cast<double>( ii + 1 ) / ( num_names + 1 );
int divisions = num_names + 1;
if( clipBox.Contains( textPosition ) )
for( int ii = 1; ii < divisions; ++ii )
{
VECTOR2I textPosition = start + segV * ( (double) ii / divisions );
if( viewport.Contains( textPosition ) )
m_gal->BitmapText( aNetName, textPosition, textOrientation );
}
}
@ -955,7 +941,7 @@ void PCB_PAINTER::draw( const PCB_VIA* aVia, int aLayer )
// the netname
VECTOR2D textpos( 0.0, 0.0 );
wxString netname = aVia->GetUnescapedShortNetname();
wxString netname = aVia->GetDisplayNetname();
int topLayer = aVia->TopLayer() + 1;
int bottomLayer = std::min( aVia->BottomLayer() + 1, board->GetCopperLayerCount() );
@ -1156,7 +1142,7 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
if( displayOpts && !dynamic_cast<CVPCB_SETTINGS*>( viewer_settings() ) )
{
if( displayOpts->m_NetNames == 1 || displayOpts->m_NetNames == 3 )
netname = aPad->GetUnescapedShortNetname();
netname = aPad->GetDisplayNetname();
if( aPad->IsNoConnectPad() )
netname = wxT( "x" );
@ -1167,12 +1153,6 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
if( netname.IsEmpty() && padNumber.IsEmpty() )
return;
for( const auto& netinfo : board->GetNetInfo() )
{
if( netinfo->GetUnescapedShortNetname() == netname )
netname = UnescapeString( aPad->GetNetname() );
}
BOX2I padBBox = aPad->GetBoundingBox();
VECTOR2D position = padBBox.Centre();
VECTOR2D padsize = VECTOR2D( padBBox.GetSize() );
@ -1720,7 +1700,7 @@ void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer )
if( aShape->GetNetCode() <= NETINFO_LIST::UNCONNECTED )
return;
wxString netname = aShape->GetUnescapedShortNetname();
wxString netname = aShape->GetDisplayNetname();
if( netname.IsEmpty() )
return;

View File

@ -51,8 +51,6 @@ PCB_TRACK::PCB_TRACK( BOARD_ITEM* aParent, KICAD_T idtype ) :
BOARD_CONNECTED_ITEM( aParent, idtype )
{
m_Width = pcbIUScale.mmToIU( 0.2 ); // Gives a reasonable default width
m_CachedScale = -1.0; // Set invalid to force update
m_CachedLOD = 0.0; // Set to always display
}
@ -110,8 +108,6 @@ PCB_VIA& PCB_VIA::operator=( const PCB_VIA &aOther )
m_Width = aOther.m_Width;
m_Start = aOther.m_Start;
m_End = aOther.m_End;
m_CachedLOD = aOther.m_CachedLOD;
m_CachedScale = aOther.m_CachedScale;
m_bottomLayer = aOther.m_bottomLayer;
m_viaType = aOther.m_viaType;
@ -788,10 +784,15 @@ void PCB_VIA::SanitizeLayers()
bool PCB_VIA::FlashLayer( LSET aLayers ) const
{
for( PCB_LAYER_ID layer : aLayers.Seq() )
for( size_t ii = 0; ii < aLayers.size(); ++ii )
{
if( FlashLayer( layer ) )
return true;
if( aLayers.test( ii ) )
{
PCB_LAYER_ID layer = PCB_LAYER_ID( ii );
if( FlashLayer( layer ) )
return true;
}
}
return false;
@ -893,24 +894,20 @@ double PCB_TRACK::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
return HIDE;
}
// Pick the approximate size of the netname (square chars)
wxString netName = GetUnescapedShortNetname();
size_t num_chars = netName.size();
if( GetLength() < num_chars * GetWidth() )
return HIDE;
// When drawing netnames, clip the track to the viewport
VECTOR2I start( GetStart() );
VECTOR2I end( GetEnd() );
BOX2D viewport = aView->GetViewport();
BOX2I clipBox( viewport.GetOrigin(), viewport.GetSize() );
// Calc the approximate size of the netname (assume square chars)
SEG::ecoord nameSize = GetDisplayNetname().size() * GetWidth();
if( VECTOR2I( end - start ).SquaredEuclideanNorm() < nameSize * nameSize )
return HIDE;
BOX2I clipBox = BOX2ISafe( aView->GetViewport() );
ClipLine( &clipBox, start.x, start.y, end.x, end.y );
VECTOR2I line = ( end - start );
if( line.EuclideanNorm() == 0 )
if( VECTOR2I( end - start ).SquaredEuclideanNorm() == 0 )
return HIDE;
// Netnames will be shown only if zoom is appropriate

View File

@ -219,50 +219,10 @@ public:
return true;
}
/**
* Get last used LOD for the track net name.
*
* @return LOD from ViewGetLOD()
*/
double GetCachedLOD()
{
return m_CachedLOD;
}
/**
* Set the cached LOD.
*
* @param aLOD value from ViewGetLOD() or 0.0 to always display.
*/
void SetCachedLOD( double aLOD )
{
m_CachedLOD = aLOD;
}
/**
* Get last used zoom scale for the track net name.
*
* @return scale from GetScale()
*/
double GetCachedScale()
{
return m_CachedScale;
}
virtual double Similarity( const BOARD_ITEM& aOther ) const override;
virtual bool operator==( const BOARD_ITEM& aOther ) const override;
/**
* Set the cached scale.
*
* @param aScale value from GetScale()
*/
void SetCachedScale( double aScale )
{
m_CachedScale = aScale;
}
struct cmp_tracks
{
bool operator()( const PCB_TRACK* aFirst, const PCB_TRACK* aSecond ) const;
@ -282,9 +242,6 @@ protected:
int m_Width; ///< Thickness of track, or via diameter
VECTOR2I m_Start; ///< Line start point
VECTOR2I m_End; ///< Line end point
double m_CachedLOD; ///< Last LOD used to draw this track's net
double m_CachedScale; ///< Last zoom scale used to draw this track's net.
};