From 6fef054c51488878b4d4ec4e1c6852c4643fec43 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
---
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 cadef57b78..a6b4022d71 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 9ec90a892b..958e1e9fb8 100644
--- a/libs/kimath/include/math/util.h
+++ b/libs/kimath/include/math/util.h
@@ -56,7 +56,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;