pcbnew: Allow tuning length to be longer than INT_MAX
The INT_MAX limit for most elements makes sense only for single-segment, straight line elements. For elements that accumulate lengths, we should utilize the long long int (64 bits) to allow for greater lengths. Fixes: lp:1842367 * https://bugs.launchpad.net/kicad/+bug/1842367
This commit is contained in:
parent
8bbbc66e46
commit
c8a6878eb8
|
@ -124,7 +124,14 @@ double To_User_Unit( EDA_UNITS_T aUnit, double aValue, bool aUseMils )
|
|||
// A lower-precision (for readability) version of StringFromValue()
|
||||
wxString MessageTextFromValue( EDA_UNITS_T aUnits, int aValue, bool aUseMils )
|
||||
{
|
||||
return MessageTextFromValue( aUnits, (double) aValue, aUseMils );
|
||||
return MessageTextFromValue( aUnits, double( aValue ), aUseMils );
|
||||
}
|
||||
|
||||
|
||||
// A lower-precision (for readability) version of StringFromValue()
|
||||
wxString MessageTextFromValue( EDA_UNITS_T aUnits, long long int aValue, bool aUseMils )
|
||||
{
|
||||
return MessageTextFromValue( aUnits, double( aValue ), aUseMils );
|
||||
}
|
||||
|
||||
|
||||
|
@ -207,7 +214,7 @@ void StripTrailingZeros( wxString& aStringValue, unsigned aTrailingZeroAllowed )
|
|||
* otherwise the actual value is rounded when read from dialog and converted
|
||||
* in internal units, and therefore modified.
|
||||
*/
|
||||
wxString StringFromValue( EDA_UNITS_T aUnits, int aValue, bool aAddUnitSymbol, bool aUseMils )
|
||||
wxString StringFromValue( EDA_UNITS_T aUnits, double aValue, bool aAddUnitSymbol, bool aUseMils )
|
||||
{
|
||||
double value_to_print = To_User_Unit( aUnits, aValue, aUseMils );
|
||||
|
||||
|
@ -411,10 +418,10 @@ void FetchUnitsFromString( const wxString& aTextValue, EDA_UNITS_T& aUnits, bool
|
|||
}
|
||||
|
||||
|
||||
int ValueFromString( EDA_UNITS_T aUnits, const wxString& aTextValue, bool aUseMils )
|
||||
long long int ValueFromString( EDA_UNITS_T aUnits, const wxString& aTextValue, bool aUseMils )
|
||||
{
|
||||
double value = DoubleValueFromString( aUnits, aTextValue, aUseMils );
|
||||
return KiROUND( value );
|
||||
return KiROUND<double, long long int>( value );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -100,9 +100,9 @@ const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Reverse() const
|
|||
}
|
||||
|
||||
|
||||
int SHAPE_LINE_CHAIN::Length() const
|
||||
long long int SHAPE_LINE_CHAIN::Length() const
|
||||
{
|
||||
int l = 0;
|
||||
long long int l = 0;
|
||||
|
||||
for( int i = 0; i < SegmentCount(); i++ )
|
||||
l += CSegment( i ).Length();
|
||||
|
|
|
@ -123,7 +123,7 @@ void UNIT_BINDER::delayedFocusHandler( wxCommandEvent& )
|
|||
}
|
||||
|
||||
|
||||
bool UNIT_BINDER::Validate( int aMin, int aMax, bool setFocusOnError )
|
||||
bool UNIT_BINDER::Validate( long long int aMin, long long int aMax, bool setFocusOnError )
|
||||
{
|
||||
auto textEntry = dynamic_cast<wxTextEntry*>( m_value );
|
||||
|
||||
|
@ -212,7 +212,7 @@ void UNIT_BINDER::ChangeValue( wxString aValue )
|
|||
}
|
||||
|
||||
|
||||
int UNIT_BINDER::GetValue()
|
||||
long long int UNIT_BINDER::GetValue()
|
||||
{
|
||||
auto textEntry = dynamic_cast<wxTextEntry*>( m_value );
|
||||
auto staticText = dynamic_cast<wxStaticText*>( m_value );
|
||||
|
|
|
@ -112,6 +112,8 @@ wxString MessageTextFromValue( EDA_UNITS_T aUnits, double aValue, bool aUseMils
|
|||
|
||||
wxString MessageTextFromValue( EDA_UNITS_T aUnits, int aValue, bool aUseMils = false );
|
||||
|
||||
wxString MessageTextFromValue( EDA_UNITS_T aUnits, long long int aValue, bool aUseMils = false );
|
||||
|
||||
/**
|
||||
* Function StringFromValue
|
||||
* returns the string from \a aValue according to units (inch, mm ...) for display,
|
||||
|
@ -132,8 +134,8 @@ wxString MessageTextFromValue( EDA_UNITS_T aUnits, int aValue, bool aUseMils = f
|
|||
* @param aUseMils Indicates mils should be used for imperial units (inches).
|
||||
* @return A wxString object containing value and optionally the symbol unit (like 2.000 mm)
|
||||
*/
|
||||
wxString StringFromValue( EDA_UNITS_T aUnit, int aValue, bool aAddUnitSymbol = false,
|
||||
bool aUseMils = false );
|
||||
wxString StringFromValue(
|
||||
EDA_UNITS_T aUnit, double aValue, bool aAddUnitSymbol = false, bool aUseMils = false );
|
||||
|
||||
/**
|
||||
* Return in internal units the value "val" given in a real unit
|
||||
|
@ -162,7 +164,8 @@ double DoubleValueFromString( EDA_UNITS_T aUnits, const wxString& aTextValue,
|
|||
* @param aUseMils Indicates mils should be used for imperial units (inches).
|
||||
* @return The string from Value, according to units (inch, mm ...) for display,
|
||||
*/
|
||||
int ValueFromString( EDA_UNITS_T aUnits, const wxString& aTextValue, bool aUseMils = false );
|
||||
long long int ValueFromString(
|
||||
EDA_UNITS_T aUnits, const wxString& aTextValue, bool aUseMils = false );
|
||||
|
||||
/**
|
||||
* Function FetchUnitsFromString
|
||||
|
|
|
@ -43,7 +43,9 @@
|
|||
#include <gal/color4d.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
class wxAboutDialogInfo;
|
||||
class SEARCH_STACK;
|
||||
|
@ -105,49 +107,20 @@ enum pseudokeys {
|
|||
/**
|
||||
* Round a floating point number to an integer using "round halfway cases away from zero".
|
||||
*
|
||||
* In Debug build an assert fires if will not fit into an int.
|
||||
* In Debug build an assert fires if will not fit into the return type.
|
||||
*/
|
||||
|
||||
#if !defined( DEBUG )
|
||||
|
||||
/// KiROUND: a function so v is not evaluated twice. Unfortunately, compiler
|
||||
/// is unable to pre-compute constants using this.
|
||||
static inline int KiROUND( double v )
|
||||
template <typename fp_type, typename ret_type = int>
|
||||
constexpr ret_type KiROUND( fp_type v )
|
||||
{
|
||||
return int( v < 0 ? v - 0.5 : v + 0.5 );
|
||||
using max_ret = long long int;
|
||||
fp_type ret = v < 0 ? v - 0.5 : v + 0.5;
|
||||
|
||||
wxASSERT( ret <= std::numeric_limits<ret_type>::max()
|
||||
&& ret >= std::numeric_limits<ret_type>::lowest() );
|
||||
|
||||
return ret_type( max_ret( ret ) );
|
||||
}
|
||||
|
||||
/// KIROUND: a macro so compiler can pre-compute constants. Use this with compile
|
||||
/// time constants rather than the inline function above.
|
||||
#define KIROUND( v ) int( (v) < 0 ? (v) - 0.5 : (v) + 0.5 )
|
||||
|
||||
#else
|
||||
|
||||
// DEBUG: KiROUND() is a macro to capture line and file, then calls this inline
|
||||
|
||||
static inline int kiRound_( double v, int line, const char* filename )
|
||||
{
|
||||
v = v < 0 ? v - 0.5 : v + 0.5;
|
||||
if( v > INT_MAX + 0.5 )
|
||||
{
|
||||
printf( "%s: in file %s on line %d, val: %.16g too ' > 0 ' for int\n",
|
||||
__FUNCTION__, filename, line, v );
|
||||
}
|
||||
else if( v < INT_MIN - 0.5 )
|
||||
{
|
||||
printf( "%s: in file %s on line %d, val: %.16g too ' < 0 ' for int\n",
|
||||
__FUNCTION__, filename, line, v );
|
||||
}
|
||||
return int( v );
|
||||
}
|
||||
|
||||
#define KiROUND( v ) kiRound_( v, __LINE__, __FILE__ )
|
||||
|
||||
// in Debug build, use the overflow catcher since code size is immaterial
|
||||
#define KIROUND( v ) KiROUND( v )
|
||||
|
||||
#endif
|
||||
|
||||
//-----</KiROUND KIT>-----------------------------------------------------------
|
||||
|
||||
|
||||
|
|
|
@ -364,7 +364,7 @@ public:
|
|||
* Returns length of the line chain in Euclidean metric.
|
||||
* @return length of the line chain
|
||||
*/
|
||||
int Length() const;
|
||||
long long int Length() const;
|
||||
|
||||
/**
|
||||
* Function Append()
|
||||
|
|
|
@ -85,7 +85,7 @@ public:
|
|||
* Function GetValue
|
||||
* Returns the current value in Internal Units.
|
||||
*/
|
||||
virtual int GetValue();
|
||||
virtual long long int GetValue();
|
||||
|
||||
/**
|
||||
* Function IsIndeterminate
|
||||
|
@ -102,7 +102,7 @@ public:
|
|||
* @param aMax a maximum value (in internal units) for validation
|
||||
* @return false on error.
|
||||
*/
|
||||
virtual bool Validate( int aMin, int aMax, bool setFocusOnError = true );
|
||||
virtual bool Validate( long long int aMin, long long int aMax, bool setFocusOnError = true );
|
||||
|
||||
void SetLabel( const wxString& aLabel );
|
||||
|
||||
|
|
|
@ -107,13 +107,13 @@ bool DIALOG_PNS_LENGTH_TUNING_SETTINGS::TransferDataToWindow()
|
|||
|
||||
bool DIALOG_PNS_LENGTH_TUNING_SETTINGS::AcceptOptions( )
|
||||
{
|
||||
if( !m_minAmpl.Validate( 0, INT_MAX ) )
|
||||
if( !m_minAmpl.Validate( 0, std::numeric_limits<int>::max() ) )
|
||||
return false;
|
||||
if( !m_maxAmpl.Validate( m_minAmpl.GetValue(), INT_MAX ) )
|
||||
if( !m_maxAmpl.Validate( m_minAmpl.GetValue(), std::numeric_limits<int>::max() ) )
|
||||
return false;
|
||||
if( !m_spacing.Validate( 0, INT_MAX ) )
|
||||
if( !m_spacing.Validate( 0, std::numeric_limits<int>::max() ) )
|
||||
return false;
|
||||
if( !m_targetLength.Validate( 0, INT_MAX ) )
|
||||
if( !m_targetLength.Validate( 0, std::numeric_limits<long long int>::max() ) )
|
||||
return false;
|
||||
if( !m_radius.Validate( 0, 100 ) )
|
||||
return false;
|
||||
|
|
|
@ -119,10 +119,10 @@ void DP_MEANDER_PLACER::release()
|
|||
}
|
||||
|
||||
|
||||
int DP_MEANDER_PLACER::origPathLength() const
|
||||
long long int DP_MEANDER_PLACER::origPathLength() const
|
||||
{
|
||||
int totalP = 0;
|
||||
int totalN = 0;
|
||||
long long int totalP = 0;
|
||||
long long int totalN = 0;
|
||||
|
||||
for( const ITEM* item : m_tunedPathP.CItems() )
|
||||
{
|
||||
|
@ -243,7 +243,7 @@ bool DP_MEANDER_PLACER::Move( const VECTOR2I& aP, ITEM* aEndItem )
|
|||
while( curIndexN < tunedN.PointCount() )
|
||||
m_result.AddCorner( tunedP.CPoint( -1 ), tunedN.CPoint( curIndexN++ ) );
|
||||
|
||||
int dpLen = origPathLength();
|
||||
long long int dpLen = origPathLength();
|
||||
|
||||
m_lastStatus = TUNED;
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ public:
|
|||
|
||||
int CurrentLayer() const override;
|
||||
|
||||
int totalLength();
|
||||
long long int totalLength();
|
||||
|
||||
const wxString TuningInfo( EDA_UNITS_T aUnits ) const override;
|
||||
TUNING_STATUS TuningStatus() const override;
|
||||
|
@ -120,7 +120,7 @@ private:
|
|||
void setWorld( NODE* aWorld );
|
||||
void release();
|
||||
|
||||
int origPathLength() const;
|
||||
long long int origPathLength() const;
|
||||
|
||||
///> pointer to world to search colliding items
|
||||
NODE* m_world;
|
||||
|
@ -141,7 +141,7 @@ private:
|
|||
MEANDERED_LINE m_result;
|
||||
SEGMENT* m_initialSegment;
|
||||
|
||||
int m_lastLength;
|
||||
long long int m_lastLength;
|
||||
TUNING_STATUS m_lastStatus;
|
||||
};
|
||||
|
||||
|
|
|
@ -80,8 +80,8 @@ public:
|
|||
int m_spacing;
|
||||
///> amplitude/spacing adjustment step
|
||||
int m_step;
|
||||
///> desired length of the tuned line/diff pair
|
||||
int m_targetLength;
|
||||
///> desired length of the tuned line/diff pair (this is in nm, so allow more than board width)
|
||||
long long int m_targetLength;
|
||||
///> type of corners for the meandered line
|
||||
MEANDER_STYLE m_cornerStyle;
|
||||
///> rounding percentage (0 - 100)
|
||||
|
|
|
@ -89,9 +89,9 @@ bool MEANDER_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
|
|||
}
|
||||
|
||||
|
||||
int MEANDER_PLACER::origPathLength() const
|
||||
long long int MEANDER_PLACER::origPathLength() const
|
||||
{
|
||||
int total = 0;
|
||||
long long int total = 0;
|
||||
for( const ITEM* item : m_tunedPath.CItems() )
|
||||
{
|
||||
if( const LINE* l = dyn_cast<const LINE*>( item ) )
|
||||
|
@ -110,7 +110,7 @@ bool MEANDER_PLACER::Move( const VECTOR2I& aP, ITEM* aEndItem )
|
|||
}
|
||||
|
||||
|
||||
bool MEANDER_PLACER::doMove( const VECTOR2I& aP, ITEM* aEndItem, int aTargetLength )
|
||||
bool MEANDER_PLACER::doMove( const VECTOR2I& aP, ITEM* aEndItem, long long int aTargetLength )
|
||||
{
|
||||
SHAPE_LINE_CHAIN pre, tuned, post;
|
||||
|
||||
|
@ -133,7 +133,7 @@ bool MEANDER_PLACER::doMove( const VECTOR2I& aP, ITEM* aEndItem, int aTargetLeng
|
|||
m_result.AddCorner( s.B );
|
||||
}
|
||||
|
||||
int lineLen = origPathLength();
|
||||
long long int lineLen = origPathLength();
|
||||
|
||||
m_lastLength = lineLen;
|
||||
m_lastStatus = TUNED;
|
||||
|
|
|
@ -89,12 +89,11 @@ public:
|
|||
bool CheckFit ( MEANDER_SHAPE* aShape ) override;
|
||||
|
||||
protected:
|
||||
|
||||
bool doMove( const VECTOR2I& aP, ITEM* aEndItem, int aTargetLength );
|
||||
bool doMove( const VECTOR2I& aP, ITEM* aEndItem, long long int aTargetLength );
|
||||
|
||||
void setWorld( NODE* aWorld );
|
||||
|
||||
virtual int origPathLength() const;
|
||||
virtual long long int origPathLength() const;
|
||||
|
||||
///> pointer to world to search colliding items
|
||||
NODE* m_world;
|
||||
|
@ -113,7 +112,7 @@ protected:
|
|||
MEANDERED_LINE m_result;
|
||||
SEGMENT* m_initialSegment;
|
||||
|
||||
int m_lastLength;
|
||||
long long int m_lastLength;
|
||||
TUNING_STATUS m_lastStatus;
|
||||
};
|
||||
|
||||
|
|
|
@ -106,9 +106,9 @@ void MEANDER_PLACER_BASE::cutTunedLine( const SHAPE_LINE_CHAIN& aOrigin,
|
|||
}
|
||||
|
||||
|
||||
void MEANDER_PLACER_BASE::tuneLineLength( MEANDERED_LINE& aTuned, int aElongation )
|
||||
void MEANDER_PLACER_BASE::tuneLineLength( MEANDERED_LINE& aTuned, long long int aElongation )
|
||||
{
|
||||
int remaining = aElongation;
|
||||
long long int remaining = aElongation;
|
||||
bool finished = false;
|
||||
|
||||
for( MEANDER_SHAPE* m : aTuned.Meanders() )
|
||||
|
@ -155,7 +155,7 @@ void MEANDER_PLACER_BASE::tuneLineLength( MEANDERED_LINE& aTuned, int aElongatio
|
|||
}
|
||||
}
|
||||
|
||||
int balance = 0;
|
||||
long long int balance = 0;
|
||||
|
||||
if( meanderCount )
|
||||
balance = -remaining / meanderCount;
|
||||
|
@ -166,7 +166,8 @@ void MEANDER_PLACER_BASE::tuneLineLength( MEANDERED_LINE& aTuned, int aElongatio
|
|||
{
|
||||
if( m->Type() != MT_CORNER && m->Type() != MT_EMPTY )
|
||||
{
|
||||
m->Resize( std::max( m->Amplitude() - balance / 2, m_settings.m_minAmplitude ) );
|
||||
m->Resize( std::max( m->Amplitude() - balance / 2,
|
||||
(long long int) ( m_settings.m_minAmplitude ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,7 +180,8 @@ const MEANDER_SETTINGS& MEANDER_PLACER_BASE::MeanderSettings() const
|
|||
}
|
||||
|
||||
|
||||
int MEANDER_PLACER_BASE::compareWithTolerance( int aValue, int aExpected, int aTolerance ) const
|
||||
int MEANDER_PLACER_BASE::compareWithTolerance(
|
||||
long long int aValue, long long int aExpected, long long int aTolerance ) const
|
||||
{
|
||||
if( aValue < aExpected - aTolerance )
|
||||
return -1;
|
||||
|
|
|
@ -147,14 +147,15 @@ protected:
|
|||
* Takes a set of meanders in aTuned and tunes their length to
|
||||
* extend the original line length by aElongation.
|
||||
*/
|
||||
void tuneLineLength( MEANDERED_LINE& aTuned, int aElongation );
|
||||
void tuneLineLength( MEANDERED_LINE& aTuned, long long int aElongation );
|
||||
|
||||
/**
|
||||
* Function compareWithTolerance()
|
||||
*
|
||||
* Compares aValue against aExpected with given tolerance.
|
||||
*/
|
||||
int compareWithTolerance ( int aValue, int aExpected, int aTolerance = 0 ) const;
|
||||
int compareWithTolerance(
|
||||
long long int aValue, long long int aExpected, long long int aTolerance = 0 ) const;
|
||||
|
||||
///> width of the meandered trace(s)
|
||||
int m_currentWidth;
|
||||
|
|
|
@ -99,15 +99,15 @@ bool MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
|
|||
}
|
||||
|
||||
|
||||
int MEANDER_SKEW_PLACER::origPathLength( ) const
|
||||
long long int MEANDER_SKEW_PLACER::origPathLength() const
|
||||
{
|
||||
return itemsetLength ( m_tunedPath );
|
||||
}
|
||||
|
||||
|
||||
int MEANDER_SKEW_PLACER::itemsetLength( const ITEM_SET& aSet ) const
|
||||
long long int MEANDER_SKEW_PLACER::itemsetLength( const ITEM_SET& aSet ) const
|
||||
{
|
||||
int total = 0;
|
||||
long long int total = 0;
|
||||
for( const ITEM* item : aSet.CItems() )
|
||||
{
|
||||
if( const LINE* l = dyn_cast<const LINE*>( item ) )
|
||||
|
@ -120,7 +120,7 @@ int MEANDER_SKEW_PLACER::itemsetLength( const ITEM_SET& aSet ) const
|
|||
}
|
||||
|
||||
|
||||
int MEANDER_SKEW_PLACER::currentSkew() const
|
||||
long long int MEANDER_SKEW_PLACER::currentSkew() const
|
||||
{
|
||||
return m_lastLength - m_coupledLength;
|
||||
}
|
||||
|
|
|
@ -52,16 +52,15 @@ public:
|
|||
const wxString TuningInfo( EDA_UNITS_T aUnits ) const override;
|
||||
|
||||
private:
|
||||
long long int currentSkew() const;
|
||||
long long int itemsetLength( const ITEM_SET& aSet ) const;
|
||||
|
||||
int currentSkew( ) const;
|
||||
int itemsetLength( const ITEM_SET& aSet ) const;
|
||||
|
||||
int origPathLength () const override;
|
||||
long long int origPathLength() const override;
|
||||
|
||||
DIFF_PAIR m_originPair;
|
||||
ITEM_SET m_tunedPath, m_tunedPathP, m_tunedPathN;
|
||||
|
||||
int m_coupledLength;
|
||||
long long int m_coupledLength;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue