From 95fcf53353c4205cc75fe6e63752bccc34dda231 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Thu, 7 Jul 2022 10:53:06 -0700 Subject: [PATCH] Handle basic rounding error in schematic import The fractional part of Altium schematic units is an integer number of 1/10000 mil segments, which is 2.54 nm. The internal unit of eeschema is 10 nm, so each fractional unit in Altium is 0.254 base eeschema units. To be consistent with https://gitlab.com/kicad/code/kicad/-/commit/cf33cfcad1ce01d866548c4ef87a1125141d427b we round to the nearest 10nm for each element Fixes https://gitlab.com/kicad/code/kicad/issues/11742 (cherry picked from commit 6fef054c51488878b4d4ec4e1c6852c4643fec43) --- eeschema/sch_plugins/altium/altium_parser_sch.cpp | 7 ++++++- libs/kimath/include/math/util.h | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/eeschema/sch_plugins/altium/altium_parser_sch.cpp b/eeschema/sch_plugins/altium/altium_parser_sch.cpp index 2978608cfb..bac7716792 100644 --- a/eeschema/sch_plugins/altium/altium_parser_sch.cpp +++ b/eeschema/sch_plugins/altium/altium_parser_sch.cpp @@ -43,7 +43,12 @@ ALTIUM_SCH_RECORD ReadRecord( const std::map& aProps ) constexpr int Altium2KiCadUnit( const int val, const int frac ) { - return Mils2iu( val ) * 10 + Mils2iu( frac ) / 10000; // TODO: correct, rounding issues? + constexpr double int_limit = ( std::numeric_limits::max() - 10 ) / 2.54; + + double dbase = 10 * Mils2iu( val ); + double dfrac = Mils2iu( frac ) / 10000.0; + + return KiROUND( Clamp( -int_limit, ( dbase + dfrac ) / 10.0, int_limit ) ) * 10; } diff --git a/libs/kimath/include/math/util.h b/libs/kimath/include/math/util.h index c9407c2086..d6e9fab913 100644 --- a/libs/kimath/include/math/util.h +++ b/libs/kimath/include/math/util.h @@ -49,7 +49,7 @@ void kimathLogDebug( const char* aFormatString, ... ); * result is: lower <= value <= upper *

*/ -template inline const T& Clamp( const T& lower, const T& value, const T& upper ) +template inline constexpr T Clamp( const T& lower, const T& value, const T& upper ) { if( value < lower ) return lower;