diff --git a/3d-viewer/3d_model_viewer/eda_3d_model_viewer.cpp b/3d-viewer/3d_model_viewer/eda_3d_model_viewer.cpp
index 7ac08b533a..65766cf366 100644
--- a/3d-viewer/3d_model_viewer/eda_3d_model_viewer.cpp
+++ b/3d-viewer/3d_model_viewer/eda_3d_model_viewer.cpp
@@ -42,7 +42,7 @@
 /**
   * Scale conversion from 3d model units to pcb units
   */
-#define UNITS3D_TO_UNITSPCB (IU_PER_MM)
+#define UNITS3D_TO_UNITSPCB ( pcbIUScale.IU_PER_MM )
 
 /**
  * Trace mask used to enable or disable the trace output of this class.
diff --git a/3d-viewer/3d_rendering/opengl/render_3d_opengl.cpp b/3d-viewer/3d_rendering/opengl/render_3d_opengl.cpp
index 4ebdd58e11..b4c0044d4a 100644
--- a/3d-viewer/3d_rendering/opengl/render_3d_opengl.cpp
+++ b/3d-viewer/3d_rendering/opengl/render_3d_opengl.cpp
@@ -37,7 +37,7 @@
 /**
  * Scale conversion from 3d model units to pcb units
  */
-#define UNITS3D_TO_UNITSPCB (IU_PER_MM)
+#define UNITS3D_TO_UNITSPCB ( pcbIUScale.IU_PER_MM )
 
 RENDER_3D_OPENGL::RENDER_3D_OPENGL( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aAdapter,
                                     CAMERA& aCamera ) :
@@ -1387,7 +1387,7 @@ void RENDER_3D_OPENGL::generate3dGrid( GRID3D_TYPE aGridType )
             glColor4f( gridColor_marker.r, gridColor_marker.g, gridColor_marker.b,
                        transparency );
 
-        const int delta = KiROUND( ii * griSizeMM * IU_PER_MM );
+        const int delta = KiROUND( ii * griSizeMM * pcbIUScale.IU_PER_MM );
 
         if( delta <= xsize / 2 )    // Draw grid lines parallel to X axis
         {
@@ -1439,7 +1439,7 @@ void RENDER_3D_OPENGL::generate3dGrid( GRID3D_TYPE aGridType )
             glColor4f( gridColor_marker.r, gridColor_marker.g, gridColor_marker.b,
                        transparency );
 
-        const double delta = ii * griSizeMM * IU_PER_MM;
+        const double delta = ii * griSizeMM * pcbIUScale.IU_PER_MM;
 
         glBegin( GL_LINES );
         xmax = ( brd_center_pos.x + delta ) * scale;
@@ -1469,7 +1469,7 @@ void RENDER_3D_OPENGL::generate3dGrid( GRID3D_TYPE aGridType )
         else
             glColor4f( gridColor_marker.r, gridColor_marker.g, gridColor_marker.b, transparency );
 
-        const double delta = ii * griSizeMM * IU_PER_MM * scale;
+        const double delta = ii * griSizeMM * pcbIUScale.IU_PER_MM * scale;
 
         if( delta <= zmax )
         {
diff --git a/3d-viewer/3d_rendering/raytracing/create_scene.cpp b/3d-viewer/3d_rendering/raytracing/create_scene.cpp
index a10dae8fa9..ad4bb212dc 100644
--- a/3d-viewer/3d_rendering/raytracing/create_scene.cpp
+++ b/3d-viewer/3d_rendering/raytracing/create_scene.cpp
@@ -65,7 +65,7 @@ static float TransparencyControl( float aGrayColorValue, float aTransparency )
 /**
   * Scale conversion from 3d model units to pcb units
   */
-#define UNITS3D_TO_UNITSPCB ( IU_PER_MM )
+#define UNITS3D_TO_UNITSPCB ( pcbIUScale.IU_PER_MM )
 
 
 void RENDER_3D_RAYTRACE::setupMaterials()
@@ -76,7 +76,7 @@ void RENDER_3D_RAYTRACE::setupMaterials()
     MATERIAL::SetDefaultRefractionRecursionCount( m_boardAdapter.m_Cfg->m_Render.raytrace_recursivelevel_refractions );
     MATERIAL::SetDefaultReflectionRecursionCount( m_boardAdapter.m_Cfg->m_Render.raytrace_recursivelevel_reflections );
 
-    double mmTo3Dunits = IU_PER_MM * m_boardAdapter.BiuTo3dUnits();
+    double mmTo3Dunits = pcbIUScale.IU_PER_MM * m_boardAdapter.BiuTo3dUnits();
 
     if( m_boardAdapter.m_Cfg->m_Render.raytrace_procedural_textures )
     {
diff --git a/eeschema/dialogs/dialog_plot_schematic.cpp b/eeschema/dialogs/dialog_plot_schematic.cpp
index b769f27b62..c5dfdf8459 100644
--- a/eeschema/dialogs/dialog_plot_schematic.cpp
+++ b/eeschema/dialogs/dialog_plot_schematic.cpp
@@ -152,7 +152,7 @@ void DIALOG_PLOT_SCHEMATIC::initDlg()
         m_HPGLPaperSizeSelect = cfg->m_PlotPanel.hpgl_paper_size;
 
         // HPGL Pen Size is stored in mm in config
-        m_HPGLPenSize = cfg->m_PlotPanel.hpgl_pen_size * IU_PER_MM;
+        m_HPGLPenSize = cfg->m_PlotPanel.hpgl_pen_size * schIUScale.IU_PER_MM;
 
         // Switch to the last save plot format
         PLOT_FORMAT fmt = static_cast<PLOT_FORMAT>( cfg->m_PlotPanel.format );
@@ -343,7 +343,7 @@ void DIALOG_PLOT_SCHEMATIC::getPlotOptions( RENDER_SETTINGS* aSettings )
         cfg->m_PlotPanel.open_file_after_plot = getOpenFileAfterPlot();
 
         // HPGL Pen Size is stored in mm in config
-        cfg->m_PlotPanel.hpgl_pen_size = m_HPGLPenSize / IU_PER_MM;
+        cfg->m_PlotPanel.hpgl_pen_size = m_HPGLPenSize / schIUScale.IU_PER_MM;
     }
 
     aSettings->LoadColors( colors );
diff --git a/eeschema/sch_painter.cpp b/eeschema/sch_painter.cpp
index 4a2191f525..02879afab6 100644
--- a/eeschema/sch_painter.cpp
+++ b/eeschema/sch_painter.cpp
@@ -107,7 +107,7 @@ SCH_RENDER_SETTINGS::SCH_RENDER_SETTINGS() :
     SetDashLengthRatio( 12 );       // From ISO 128-2
     SetGapLengthRatio( 3 );         // From ISO 128-2
 
-    m_minPenWidth = ADVANCED_CFG::GetCfg().m_MinPlotPenWidth * IU_PER_MM;
+    m_minPenWidth = ADVANCED_CFG::GetCfg().m_MinPlotPenWidth * schIUScale.IU_PER_MM;
 }
 
 
diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp
index 14acc3c2d7..3636038436 100644
--- a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp
+++ b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp
@@ -448,7 +448,7 @@ LIB_ITEM* SCH_SEXPR_PARSER::ParseDrawItem()
 
 int SCH_SEXPR_PARSER::parseInternalUnits()
 {
-    auto retval = parseDouble() * IU_PER_MM;
+    auto retval = parseDouble() * schIUScale.IU_PER_MM;
 
     // Schematic internal units are represented as integers.  Any values that are
     // larger or smaller than the schematic units represent undefined behavior for
@@ -461,7 +461,7 @@ int SCH_SEXPR_PARSER::parseInternalUnits()
 
 int SCH_SEXPR_PARSER::parseInternalUnits( const char* aExpected )
 {
-    auto retval = parseDouble( aExpected ) * IU_PER_MM;
+    auto retval = parseDouble( aExpected ) * schIUScale.IU_PER_MM;
 
     constexpr double int_limit = std::numeric_limits<int>::max() * 0.7071;
 
@@ -471,7 +471,7 @@ int SCH_SEXPR_PARSER::parseInternalUnits( const char* aExpected )
 
 void SCH_SEXPR_PARSER::parseStroke( STROKE_PARAMS& aStroke )
 {
-    STROKE_PARAMS_PARSER strokeParser( reader, IU_PER_MM );
+    STROKE_PARAMS_PARSER strokeParser( reader, schIUScale.IU_PER_MM );
     strokeParser.SyncLineReaderWith( *this );
 
     strokeParser.ParseStroke( aStroke );
diff --git a/gerbview/export_to_pcbnew.h b/gerbview/export_to_pcbnew.h
index 6d279b6bed..a8ec8ea47c 100644
--- a/gerbview/export_to_pcbnew.h
+++ b/gerbview/export_to_pcbnew.h
@@ -170,7 +170,7 @@ private:
      */
     double MapToPcbUnits( int aValue ) const
     {
-        return aValue / IU_PER_MM;
+        return aValue / gerbIUScale.IU_PER_MM;
     }
 
 private:
diff --git a/gerbview/gerbview_draw_panel_gal.cpp b/gerbview/gerbview_draw_panel_gal.cpp
index 13d0d88c98..98fda15f63 100644
--- a/gerbview/gerbview_draw_panel_gal.cpp
+++ b/gerbview/gerbview_draw_panel_gal.cpp
@@ -46,7 +46,7 @@ EDA_DRAW_PANEL_GAL( aParentWindow, aWindowId, aPosition, aSize, aOptions, aGalTy
 {
     m_view = new KIGFX::VIEW( true );
     m_view->SetGAL( m_gal );
-    GetGAL()->SetWorldUnitLength( 1.0/IU_PER_MM /* 10 nm */ / 25.4 /* 1 inch in mm */ );
+    GetGAL()->SetWorldUnitLength( 1.0/gerbIUScale.IU_PER_MM /* 10 nm */ / 25.4 /* 1 inch in mm */ );
 
     m_painter = std::make_unique<KIGFX::GERBVIEW_PAINTER>( m_gal );
     m_view->SetPainter( m_painter.get() );
@@ -139,7 +139,7 @@ bool GERBVIEW_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType )
 
     setDefaultLayerDeps();
 
-    GetGAL()->SetWorldUnitLength( 1.0/IU_PER_MM /* 10 nm */ / 25.4 /* 1 inch in mm */ );
+    GetGAL()->SetWorldUnitLength( 1.0/gerbIUScale.IU_PER_MM /* 10 nm */ / 25.4 /* 1 inch in mm */ );
 
     return rv;
 }
diff --git a/gerbview/gerbview_printout.cpp b/gerbview/gerbview_printout.cpp
index 7f71a5f4c4..e4e7e3e435 100644
--- a/gerbview/gerbview_printout.cpp
+++ b/gerbview/gerbview_printout.cpp
@@ -91,7 +91,7 @@ void GERBVIEW_PRINTOUT::setupViewLayers( KIGFX::VIEW& aView, const LSET& aLayerS
 void GERBVIEW_PRINTOUT::setupGal( KIGFX::GAL* aGal )
 {
     BOARD_PRINTOUT::setupGal( aGal );
-    aGal->SetWorldUnitLength( 1.0/IU_PER_MM /* 10 nm */ / 25.4 /* 1 inch in mm */ );
+    aGal->SetWorldUnitLength( 1.0/ gerbIUScale.IU_PER_MM /* 10 nm */ / 25.4 /* 1 inch in mm */ );
 }
 
 
diff --git a/gerbview/toolbars_gerber.cpp b/gerbview/toolbars_gerber.cpp
index e128bcec08..e3c0d8de71 100644
--- a/gerbview/toolbars_gerber.cpp
+++ b/gerbview/toolbars_gerber.cpp
@@ -318,7 +318,7 @@ void GERBVIEW_FRAME::updateDCodeSelectBox()
     switch( GetUserUnits() )
     {
     case EDA_UNITS::MILLIMETRES:
-        scale = IU_PER_MM;
+        scale = gerbIUScale.IU_PER_MM;
         units = wxT( "mm" );
         break;
 
diff --git a/gerbview/tools/gerbview_inspection_tool.cpp b/gerbview/tools/gerbview_inspection_tool.cpp
index 03887c73d9..6117858adb 100644
--- a/gerbview/tools/gerbview_inspection_tool.cpp
+++ b/gerbview/tools/gerbview_inspection_tool.cpp
@@ -79,7 +79,7 @@ int GERBVIEW_INSPECTION_TOOL::ShowDCodes( const TOOL_EVENT& aEvent )
     switch( m_frame->GetUserUnits() )
     {
     case EDA_UNITS::MILLIMETRES:
-        scale = IU_PER_MM;
+        scale = gerbIUScale.IU_PER_MM;
         units = wxT( "mm" );
         break;
 
diff --git a/include/convert_to_biu.h b/include/convert_to_biu.h
index e97b1dc620..af0f95b4ad 100644
--- a/include/convert_to_biu.h
+++ b/include/convert_to_biu.h
@@ -112,21 +112,6 @@ constexpr EDA_IU_SCALE pcbIUScale = EDA_IU_SCALE( PCB_IU_PER_MM );
 constexpr EDA_IU_SCALE drawSheetIUScale = EDA_IU_SCALE( PL_IU_PER_MM );
 constexpr EDA_IU_SCALE schIUScale = EDA_IU_SCALE( SCH_IU_PER_MM );
 
-/// Scaling factor to convert mils to internal units.
-#if defined(PCBNEW) || defined(CVPCB)
-constexpr double IU_PER_MM = PCB_IU_PER_MM;
-#elif defined(GERBVIEW)
-constexpr double IU_PER_MM = GERB_IU_PER_MM;
-#elif defined(PL_EDITOR)
-constexpr double IU_PER_MM = PL_IU_PER_MM;
-#elif defined(EESCHEMA)
-constexpr double IU_PER_MM = SCH_IU_PER_MM;
-#else
-#define UNKNOWN_IU
-#endif
-
-#ifndef UNKNOWN_IU
-
 #ifndef SWIG
 // The max error is the distance between the middle of a segment, and the circle
 // for circle/arc to segment approximation.
@@ -135,6 +120,4 @@ constexpr double IU_PER_MM = SCH_IU_PER_MM;
 
 constexpr int ARC_LOW_DEF  = pcbIUScale.mmToIU( 0.02 );
 constexpr int ARC_HIGH_DEF = pcbIUScale.mmToIU( 0.005 );
-#endif
-
-#endif
+#endif
\ No newline at end of file
diff --git a/pagelayout_editor/pl_draw_panel_gal.cpp b/pagelayout_editor/pl_draw_panel_gal.cpp
index 96390a84c8..d56e2e81c3 100644
--- a/pagelayout_editor/pl_draw_panel_gal.cpp
+++ b/pagelayout_editor/pl_draw_panel_gal.cpp
@@ -50,7 +50,7 @@ PL_DRAW_PANEL_GAL::PL_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindo
     m_view = new KIGFX::VIEW( true );
     m_view->SetGAL( m_gal );
 
-    GetGAL()->SetWorldUnitLength( 1.0/IU_PER_MM /* 10 nm */ / 25.4 /* 1 inch in mm */ );
+    GetGAL()->SetWorldUnitLength( 1.0/drawSheetIUScale.IU_PER_MM /* 10 nm */ / 25.4 /* 1 inch in mm */ );
 
     m_painter = std::make_unique<KIGFX::DS_PAINTER>( m_gal );
 
@@ -137,7 +137,7 @@ bool PL_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType )
 
     setDefaultLayerDeps();
 
-    GetGAL()->SetWorldUnitLength( 1.0/IU_PER_MM /* 10 nm */ / 25.4 /* 1 inch in mm */ );
+    GetGAL()->SetWorldUnitLength( 1.0/drawSheetIUScale.IU_PER_MM /* 10 nm */ / 25.4 /* 1 inch in mm */ );
 
     return rv;
 }
diff --git a/pcbnew/autorouter/spread_footprints.cpp b/pcbnew/autorouter/spread_footprints.cpp
index c89d426685..73b3b1178b 100644
--- a/pcbnew/autorouter/spread_footprints.cpp
+++ b/pcbnew/autorouter/spread_footprints.cpp
@@ -58,9 +58,9 @@ struct TSubRect : public CRectPlacement::TRect
 typedef std::vector<TSubRect> CSubRectArray;
 
 // Use 0.01 mm units to calculate placement, to avoid long calculation time
-const int scale = (int)(0.01 * IU_PER_MM);
+const int scale = (int) ( 0.01 * pcbIUScale.IU_PER_MM );
 
-const int PADDING = (int)(1 * IU_PER_MM);
+const int PADDING = (int) ( 1 * pcbIUScale.IU_PER_MM );
 
 // Populates a list of rectangles, from a list of footprints
 void fillRectList( CSubRectArray& vecSubRects, std::vector <FOOTPRINT*>& aFootprintList )
diff --git a/pcbnew/board_design_settings.cpp b/pcbnew/board_design_settings.cpp
index d3c1823f96..735607b124 100644
--- a/pcbnew/board_design_settings.cpp
+++ b/pcbnew/board_design_settings.cpp
@@ -757,13 +757,13 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
                 // The parameters are removed, so we just have to manually load them here and
                 // they will get saved with the board
                 if( std::optional<double> optval = Get<double>( "rules.solder_mask_clearance" ) )
-                    m_SolderMaskExpansion = static_cast<int>( *optval * IU_PER_MM );
+                    m_SolderMaskExpansion = static_cast<int>( *optval * pcbIUScale.IU_PER_MM );
 
                 if( std::optional<double> optval = Get<double>( "rules.solder_mask_min_width" ) )
-                    m_SolderMaskMinWidth = static_cast<int>( *optval * IU_PER_MM );
+                    m_SolderMaskMinWidth = static_cast<int>( *optval * pcbIUScale.IU_PER_MM );
 
                 if( std::optional<double> optval = Get<double>( "rules.solder_paste_clearance" ) )
-                    m_SolderPasteMargin = static_cast<int>( *optval * IU_PER_MM );
+                    m_SolderPasteMargin = static_cast<int>( *optval * pcbIUScale.IU_PER_MM );
 
                 if( std::optional<double> optval = Get<double>( "rules.solder_paste_margin_ratio" ) )
                     m_SolderPasteMarginRatio = *optval;
diff --git a/pcbnew/dialogs/dialog_pad_properties.cpp b/pcbnew/dialogs/dialog_pad_properties.cpp
index 72ff1331aa..aa89f26d27 100644
--- a/pcbnew/dialogs/dialog_pad_properties.cpp
+++ b/pcbnew/dialogs/dialog_pad_properties.cpp
@@ -342,7 +342,7 @@ void DIALOG_PAD_PROPERTIES::prepareCanvas()
     settings->m_ContrastModeDisplay = HIGH_CONTRAST_MODE::NORMAL;
 
     // gives a non null grid size (0.001mm) because GAL layer does not like a 0 size grid:
-    double gridsize = 0.001 * IU_PER_MM;
+    double gridsize = 0.001 * pcbIUScale.IU_PER_MM;
     view->GetGAL()->SetGridSize( VECTOR2D( gridsize, gridsize ) );
 
     // And do not show the grid:
diff --git a/pcbnew/dialogs/dialog_plot.cpp b/pcbnew/dialogs/dialog_plot.cpp
index f69d0b9044..7e76783131 100644
--- a/pcbnew/dialogs/dialog_plot.cpp
+++ b/pcbnew/dialogs/dialog_plot.cpp
@@ -209,7 +209,7 @@ void DIALOG_PLOT::init_Dialog()
     m_browseButton->SetBitmap( KiBitmap( BITMAPS::small_folder ) );
 
     // m_PSWidthAdjust is stored in mm in user config
-    m_PSWidthAdjust = KiROUND( cfg->m_Plot.ps_fine_width_adjust * IU_PER_MM );
+    m_PSWidthAdjust = KiROUND( cfg->m_Plot.ps_fine_width_adjust * pcbIUScale.IU_PER_MM );
 
     // The reasonable width correction value must be in a range of
     // [-(MinTrackWidth-1), +(MinClearanceValue-1)] decimils.
diff --git a/pcbnew/dialogs/dialog_track_via_size.cpp b/pcbnew/dialogs/dialog_track_via_size.cpp
index b1c5c2f70e..d4dc6b3426 100644
--- a/pcbnew/dialogs/dialog_track_via_size.cpp
+++ b/pcbnew/dialogs/dialog_track_via_size.cpp
@@ -32,7 +32,7 @@
 
 #include "board_design_settings.h"
 
-const int minSize = (int)( 0.01 * IU_PER_MM );
+const int minSize = (int) ( 0.01 * pcbIUScale.IU_PER_MM );
 
 DIALOG_TRACK_VIA_SIZE::DIALOG_TRACK_VIA_SIZE( EDA_DRAW_FRAME* aParent,
                                               BOARD_DESIGN_SETTINGS& aSettings ) :
diff --git a/pcbnew/dialogs/panel_setup_constraints.cpp b/pcbnew/dialogs/panel_setup_constraints.cpp
index a93673dbd5..70944a55b7 100644
--- a/pcbnew/dialogs/panel_setup_constraints.cpp
+++ b/pcbnew/dialogs/panel_setup_constraints.cpp
@@ -131,9 +131,9 @@ bool PANEL_SETUP_CONSTRAINTS::TransferDataFromWindow()
 
     m_BrdSettings->m_UseHeightForLengthCalcs = m_useHeightForLengthCalcs->GetValue();
 
-    m_BrdSettings->m_MaxError = Clamp<int>( IU_PER_MM * MINIMUM_ERROR_SIZE_MM,
+    m_BrdSettings->m_MaxError = Clamp<int>( pcbIUScale.IU_PER_MM * MINIMUM_ERROR_SIZE_MM,
                                             m_maxError.GetValue(),
-                                            IU_PER_MM * MAXIMUM_ERROR_SIZE_MM );
+                                            pcbIUScale.IU_PER_MM * MAXIMUM_ERROR_SIZE_MM );
 
     m_BrdSettings->m_ZoneKeepExternalFillets = m_allowExternalFilletsOpt->GetValue();
     m_BrdSettings->m_MinResolvedSpokes = m_minResolvedSpokeCountCtrl->GetValue();
diff --git a/pcbnew/exporters/export_footprints_placefile.cpp b/pcbnew/exporters/export_footprints_placefile.cpp
index e43fc24d9e..a4d5ebc6f5 100644
--- a/pcbnew/exporters/export_footprints_placefile.cpp
+++ b/pcbnew/exporters/export_footprints_placefile.cpp
@@ -50,7 +50,7 @@ public:
 static const double conv_unit_inch = 0.001 / pcbIUScale.IU_PER_MILS ;      // units = INCHES
 static const char unit_text_inch[] = "## Unit = inches, Angle = deg.\n";
 
-static const double conv_unit_mm = 1.0 / IU_PER_MM;    // units = mm
+static const double conv_unit_mm = 1.0 / pcbIUScale.IU_PER_MM; // units = mm
 static const char unit_text_mm[] = "## Unit = mm, Angle = deg.\n";
 
 // Sort function use by GenerefootprintsPosition()
diff --git a/pcbnew/exporters/gen_drill_report_files.cpp b/pcbnew/exporters/gen_drill_report_files.cpp
index a437bae30c..faa16305d8 100644
--- a/pcbnew/exporters/gen_drill_report_files.cpp
+++ b/pcbnew/exporters/gen_drill_report_files.cpp
@@ -50,7 +50,7 @@ inline double diameter_in_inches( double ius )
 
 inline double diameter_in_mm( double ius )
 {
-    return ius / IU_PER_MM;
+    return ius / pcbIUScale.IU_PER_MM;
 }
 
 
@@ -335,8 +335,8 @@ bool GENDRILL_WRITER_BASE::genDrillMapFile( const wxString& aFullFileName, PLOT_
 
         intervalle = KiROUND( ( ( charSize * charScale ) + TextWidth ) * 1.2 );
 
-        if( intervalle < ( plot_diam + ( 1 * IU_PER_MM / scale ) + TextWidth ) )
-            intervalle = plot_diam + ( 1 * IU_PER_MM / scale ) + TextWidth;
+        if( intervalle < ( plot_diam + ( 1 * pcbIUScale.IU_PER_MM / scale ) + TextWidth ) )
+            intervalle = plot_diam + ( 1 * pcbIUScale.IU_PER_MM / scale ) + TextWidth;
 
         // Evaluate the text horizontal size, to know the maximal column size
         // This is a rough value, but ok to create a new column to plot next texts
diff --git a/pcbnew/exporters/gendrill_Excellon_writer.cpp b/pcbnew/exporters/gendrill_Excellon_writer.cpp
index 0346aef344..e9f5189a02 100644
--- a/pcbnew/exporters/gendrill_Excellon_writer.cpp
+++ b/pcbnew/exporters/gendrill_Excellon_writer.cpp
@@ -359,7 +359,7 @@ void EXCELLON_WRITER::SetFormat( bool aMetric, ZEROS_FMT aZerosFmt, int aLeftDig
 
     /* Set conversion scale depending on drill file units */
     if( m_unitsMetric )
-        m_conversionUnits = 1.0 / IU_PER_MM;        // EXCELLON units = mm
+        m_conversionUnits = 1.0 / pcbIUScale.IU_PER_MM; // EXCELLON units = mm
     else
         m_conversionUnits = 0.001 / pcbIUScale.IU_PER_MILS;    // EXCELLON units = INCHES
 
diff --git a/pcbnew/exporters/gendrill_gerber_writer.cpp b/pcbnew/exporters/gendrill_gerber_writer.cpp
index fb02762c67..d4b3820245 100644
--- a/pcbnew/exporters/gendrill_gerber_writer.cpp
+++ b/pcbnew/exporters/gendrill_gerber_writer.cpp
@@ -288,7 +288,7 @@ void convertOblong2Segment( wxSize aSize, const EDA_ANGLE& aOrient, VECTOR2I& aS
 void GERBER_WRITER::SetFormat( int aRightDigits )
 {
     /* Set conversion scale depending on drill file units */
-    m_conversionUnits = 1.0 / IU_PER_MM;        // Gerber units = mm
+    m_conversionUnits = 1.0 / pcbIUScale.IU_PER_MM; // Gerber units = mm
 
     // Set precision (unit is mm).
     m_precision.m_Lhs = 4;
diff --git a/pcbnew/exporters/gerber_jobfile_writer.cpp b/pcbnew/exporters/gerber_jobfile_writer.cpp
index 2c132b0f5e..19c48450f0 100644
--- a/pcbnew/exporters/gerber_jobfile_writer.cpp
+++ b/pcbnew/exporters/gerber_jobfile_writer.cpp
@@ -55,7 +55,7 @@ GERBER_JOBFILE_WRITER::GERBER_JOBFILE_WRITER( BOARD* aPcb, REPORTER* aReporter )
 {
     m_pcb = aPcb;
     m_reporter = aReporter;
-    m_conversionUnits = 1.0 / IU_PER_MM; // Gerber units = mm
+    m_conversionUnits = 1.0 / pcbIUScale.IU_PER_MM; // Gerber units = mm
 }
 
 std::string GERBER_JOBFILE_WRITER::formatStringFromUTF32( const wxString& aText )
diff --git a/pcbnew/import_gfx/dialog_import_gfx.cpp b/pcbnew/import_gfx/dialog_import_gfx.cpp
index a2ec7c8759..ec6552a985 100644
--- a/pcbnew/import_gfx/dialog_import_gfx.cpp
+++ b/pcbnew/import_gfx/dialog_import_gfx.cpp
@@ -85,9 +85,9 @@ DIALOG_IMPORT_GFX::DIALOG_IMPORT_GFX( PCB_BASE_FRAME* aParent, bool aImportAsFoo
 
     m_placementInteractive = cfg->m_ImportGraphics.interactive_placement;
 
-    m_xOrigin.SetValue( cfg->m_ImportGraphics.origin_x * IU_PER_MM );
-    m_yOrigin.SetValue( cfg->m_ImportGraphics.origin_y * IU_PER_MM );
-    m_defaultLineWidth.SetValue( cfg->m_ImportGraphics.dxf_line_width * IU_PER_MM );
+    m_xOrigin.SetValue( cfg->m_ImportGraphics.origin_x * pcbIUScale.IU_PER_MM );
+    m_yOrigin.SetValue( cfg->m_ImportGraphics.origin_y * pcbIUScale.IU_PER_MM );
+    m_defaultLineWidth.SetValue( cfg->m_ImportGraphics.dxf_line_width * pcbIUScale.IU_PER_MM );
 
     m_textCtrlFileName->SetValue( cfg->m_ImportGraphics.last_file );
     m_rbInteractivePlacement->SetValue( m_placementInteractive );
diff --git a/pcbnew/microwave/microwave_polygon.cpp b/pcbnew/microwave/microwave_polygon.cpp
index 96f7be7b42..ff33c414e2 100644
--- a/pcbnew/microwave/microwave_polygon.cpp
+++ b/pcbnew/microwave/microwave_polygon.cpp
@@ -225,7 +225,7 @@ void MWAVE_POLYGONAL_SHAPE_DLG::ReadDataShapeDescr( wxCommandEvent& event )
         return;
     }
 
-    double   unitconv = IU_PER_MM;
+    double unitconv = pcbIUScale.IU_PER_MM;
     g_ShapeScaleX = g_ShapeScaleY = 1.0;
 
     FILE_LINE_READER fileReader( File, fullFileName );
@@ -245,7 +245,7 @@ void MWAVE_POLYGONAL_SHAPE_DLG::ReadDataShapeDescr( wxCommandEvent& event )
                 unitconv = pcbIUScale.IU_PER_MILS*1000;
 
             if( strncasecmp( param2, "mm", 2 ) == 0 )
-                unitconv = IU_PER_MM;
+                unitconv = pcbIUScale.IU_PER_MM;
         }
 
         if( strncasecmp( param1, "$ENDCOORD", 8 ) == 0 )
diff --git a/pcbnew/pcb_track.h b/pcbnew/pcb_track.h
index 0d0686e64e..361397a985 100644
--- a/pcbnew/pcb_track.h
+++ b/pcbnew/pcb_track.h
@@ -70,7 +70,7 @@ enum class VIATYPE : int
 #define UNDEFINED_DRILL_DIAMETER  -1       //< Undefined via drill diameter.
 
 // Used for tracks and vias for algorithmic safety, not to enforce constraints
-#define GEOMETRY_MIN_SIZE ( int )( 0.001 * IU_PER_MM )
+#define GEOMETRY_MIN_SIZE (int) ( 0.001 * pcbIUScale.IU_PER_MM )
 
 
 class PCB_TRACK : public BOARD_CONNECTED_ITEM
diff --git a/pcbnew/pcbnew_printout.cpp b/pcbnew/pcbnew_printout.cpp
index a20106ec68..362c4a2516 100644
--- a/pcbnew/pcbnew_printout.cpp
+++ b/pcbnew/pcbnew_printout.cpp
@@ -265,7 +265,7 @@ void PCBNEW_PRINTOUT::setupPainter( KIGFX::PAINTER& aPainter )
 void PCBNEW_PRINTOUT::setupGal( KIGFX::GAL* aGal )
 {
     BOARD_PRINTOUT::setupGal( aGal );
-    aGal->SetWorldUnitLength( 0.001/IU_PER_MM /* 1 nm */ / 0.0254 /* 1 inch in meters */ );
+    aGal->SetWorldUnitLength( 0.001/pcbIUScale.IU_PER_MM /* 1 nm */ / 0.0254 /* 1 inch in meters */ );
 }
 
 
diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp
index da79f6cf23..437acce1a5 100644
--- a/pcbnew/plot_board_layers.cpp
+++ b/pcbnew/plot_board_layers.cpp
@@ -977,7 +977,7 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
         const SHAPE_LINE_CHAIN& path = areas.COutline( ii );
 
         // polygon area in mm^2 :
-        double curr_area = path.Area() / ( IU_PER_MM * IU_PER_MM );
+        double curr_area = path.Area() / ( pcbIUScale.IU_PER_MM * pcbIUScale.IU_PER_MM );
 
         // Skip very small polygons: they are certainly artifacts created by
         // arc approximations and polygon transforms
@@ -1088,7 +1088,7 @@ static void initializePlotter( PLOTTER* aPlotter, const BOARD* aBoard,
  */
 static void FillNegativeKnockout( PLOTTER *aPlotter, const BOX2I &aBbbox )
 {
-    const int margin = 5 * IU_PER_MM;   // Add a 5 mm margin around the board
+    const int margin = 5 * pcbIUScale.IU_PER_MM; // Add a 5 mm margin around the board
     aPlotter->SetNegative( true );
     aPlotter->SetColor( WHITE );        // Which will be plotted as black
 
diff --git a/pcbnew/plugins/fabmaster/import_fabmaster.cpp b/pcbnew/plugins/fabmaster/import_fabmaster.cpp
index eecf72327f..8fd507de99 100644
--- a/pcbnew/plugins/fabmaster/import_fabmaster.cpp
+++ b/pcbnew/plugins/fabmaster/import_fabmaster.cpp
@@ -279,9 +279,9 @@ double FABMASTER::processScaleFactor( size_t aRow )
         if( units == "MILS" )
             retval = pcbIUScale.IU_PER_MILS;
         else if( units == "MILLIMETERS" )
-            retval = IU_PER_MM;
+            retval = pcbIUScale.IU_PER_MM;
         else if( units == "MICRONS" )
-            retval = IU_PER_MM * 10.0;
+            retval = pcbIUScale.IU_PER_MM * 10.0;
         else if( units == "INCHES" )
             retval = pcbIUScale.IU_PER_MILS * 1000.0;
     }
diff --git a/pcbnew/plugins/kicad/pcb_parser.cpp b/pcbnew/plugins/kicad/pcb_parser.cpp
index 91e5e3db0a..662834cbe5 100644
--- a/pcbnew/plugins/kicad/pcb_parser.cpp
+++ b/pcbnew/plugins/kicad/pcb_parser.cpp
@@ -183,7 +183,7 @@ int PCB_PARSER::parseBoardUnits()
     // to confirm or experiment.  Use a similar strategy in both places, here
     // and in the test program. Make that program with:
     // $ make test-nm-biu-to-ascii-mm-round-tripping
-    auto retval = parseDouble() * IU_PER_MM;
+    auto retval = parseDouble() * pcbIUScale.IU_PER_MM;
 
     // N.B. we currently represent board units as integers.  Any values that are
     // larger or smaller than those board units represent undefined behavior for
@@ -197,7 +197,7 @@ int PCB_PARSER::parseBoardUnits()
 
 int PCB_PARSER::parseBoardUnits( const char* aExpected )
 {
-    auto retval = parseDouble( aExpected ) * IU_PER_MM;
+    auto retval = parseDouble( aExpected ) * pcbIUScale.IU_PER_MM;
 
     // N.B. we currently represent board units as integers.  Any values that are
     // larger or smaller than those board units represent undefined behavior for
@@ -515,7 +515,7 @@ void PCB_PARSER::parseEDA_TEXT( EDA_TEXT* aText )
     // 60mils is 1.524mm
     if( !foundTextSize )
     {
-        const double defaultTextSize = 1.524 * IU_PER_MM;
+        const double defaultTextSize = 1.524 * pcbIUScale.IU_PER_MM;
 
         aText->SetTextSize( wxSize( defaultTextSize, defaultTextSize ) );
     }
@@ -2749,7 +2749,7 @@ PCB_SHAPE* PCB_PARSER::parsePCB_SHAPE()
 
         case T_stroke:
         {
-            STROKE_PARAMS_PARSER strokeParser( reader, IU_PER_MM );
+            STROKE_PARAMS_PARSER strokeParser( reader, pcbIUScale.IU_PER_MM );
             strokeParser.SyncLineReaderWith( *this );
 
             strokeParser.ParseStroke( stroke );
@@ -3081,7 +3081,7 @@ PCB_TEXTBOX* PCB_PARSER::parsePCB_TEXTBOX()
 
         case T_stroke:
         {
-            STROKE_PARAMS_PARSER strokeParser( reader, IU_PER_MM );
+            STROKE_PARAMS_PARSER strokeParser( reader, pcbIUScale.IU_PER_MM );
             strokeParser.SyncLineReaderWith( *this );
 
             strokeParser.ParseStroke( stroke );
@@ -4157,7 +4157,7 @@ FP_TEXTBOX* PCB_PARSER::parseFP_TEXTBOX()
 
         case T_stroke:
         {
-            STROKE_PARAMS_PARSER strokeParser( reader, IU_PER_MM );
+            STROKE_PARAMS_PARSER strokeParser( reader, pcbIUScale.IU_PER_MM );
             strokeParser.SyncLineReaderWith( *this );
 
             strokeParser.ParseStroke( stroke );
@@ -4472,7 +4472,7 @@ FP_SHAPE* PCB_PARSER::parseFP_SHAPE()
 
         case T_stroke:
         {
-            STROKE_PARAMS_PARSER strokeParser( reader, IU_PER_MM );
+            STROKE_PARAMS_PARSER strokeParser( reader, pcbIUScale.IU_PER_MM );
             strokeParser.SyncLineReaderWith( *this );
 
             strokeParser.ParseStroke( stroke );
@@ -5780,7 +5780,7 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent )
                 case T_island_area_min:
                 {
                     int area = parseBoardUnits( T_island_area_min );
-                    zone->SetMinIslandArea( area * IU_PER_MM );
+                    zone->SetMinIslandArea( area * pcbIUScale.IU_PER_MM );
                     NeedRIGHT();
                     break;
                 }
diff --git a/pcbnew/plugins/kicad/pcb_plugin.cpp b/pcbnew/plugins/kicad/pcb_plugin.cpp
index 73821c2514..05f20a16c6 100644
--- a/pcbnew/plugins/kicad/pcb_plugin.cpp
+++ b/pcbnew/plugins/kicad/pcb_plugin.cpp
@@ -2322,7 +2322,7 @@ void PCB_PLUGIN::format( const ZONE* aZone, int aNestLevel ) const
     {
         m_out->Print( 0, " (island_removal_mode %d) (island_area_min %s)",
                       static_cast<int>( aZone->GetIslandRemovalMode() ),
-                      EDA_UNIT_UTILS::FormatInternalUnits( pcbIUScale, aZone->GetMinIslandArea() / IU_PER_MM ).c_str() );
+                      EDA_UNIT_UTILS::FormatInternalUnits( pcbIUScale, aZone->GetMinIslandArea() / pcbIUScale.IU_PER_MM ).c_str() );
     }
 
     if( aZone->GetFillMode() == ZONE_FILL_MODE::HATCH_PATTERN )
diff --git a/pcbnew/plugins/legacy/legacy_plugin.cpp b/pcbnew/plugins/legacy/legacy_plugin.cpp
index b8c142d568..9edc5b78c2 100644
--- a/pcbnew/plugins/legacy/legacy_plugin.cpp
+++ b/pcbnew/plugins/legacy/legacy_plugin.cpp
@@ -613,7 +613,7 @@ void LEGACY_PLUGIN::loadGENERAL()
 
             if( !strcmp( data, "mm" ) )
             {
-                diskToBiu = IU_PER_MM;
+                diskToBiu = pcbIUScale.IU_PER_MM;
             }
         }
         else if( TESTLINE( "LayerCount" ) )
@@ -2876,7 +2876,7 @@ void LEGACY_PLUGIN::init( const PROPERTIES* aProperties )
     m_props = aProperties;
 
     // conversion factor for saving RAM BIUs to KICAD legacy file format.
-    biuToDisk = 1.0/IU_PER_MM;      // BIUs are nanometers & file is mm
+    biuToDisk = 1.0 / pcbIUScale.IU_PER_MM; // BIUs are nanometers & file is mm
 
     // Conversion factor for loading KICAD legacy file format into BIUs in RAM
     // Start by assuming the *.brd file is in deci-mils.
@@ -3006,7 +3006,7 @@ void LP_CACHE::ReadAndVerifyHeader( LINE_READER* aReader )
             const char* units = strtok_r( line + SZ( "Units" ), delims, &data );
 
             if( !strcmp( units, "mm" ) )
-                m_owner->diskToBiu = IU_PER_MM;
+                m_owner->diskToBiu = pcbIUScale.IU_PER_MM;
 
         }
         else if( TESTLINE( "$INDEX" ) )
diff --git a/pcbnew/specctra_import_export/specctra_export.cpp b/pcbnew/specctra_import_export/specctra_export.cpp
index 64c254f608..f7c4ada6dc 100644
--- a/pcbnew/specctra_import_export/specctra_export.cpp
+++ b/pcbnew/specctra_import_export/specctra_export.cpp
@@ -157,14 +157,14 @@ namespace DSN {
 static inline double scale( int kicadDist )
 {
     // nanometers to um
-    return kicadDist / ( IU_PER_MM / 1000.0 );
+    return kicadDist / ( pcbIUScale.IU_PER_MM / 1000.0 );
 }
 
 
 ///< Convert integer internal units to float um
 static inline double IU2um( int kicadDist )
 {
-    return kicadDist * (1000.0 / IU_PER_MM);
+    return kicadDist * ( 1000.0 / pcbIUScale.IU_PER_MM );
 }
 
 
diff --git a/pcbnew/specctra_import_export/specctra_import.cpp b/pcbnew/specctra_import_export/specctra_import.cpp
index d74f77433d..361ea6dca7 100644
--- a/pcbnew/specctra_import_export/specctra_import.cpp
+++ b/pcbnew/specctra_import_export/specctra_import.cpp
@@ -206,7 +206,7 @@ PCB_VIA* SPECCTRA_DB::makeVIA( WIRE_VIA*aVia, PADSTACK* aPadstack, const POINT&
 
             double drill_um = strtod( diam_txt.c_str(), 0 );
 
-            drill_diam_iu = int( drill_um * (IU_PER_MM / 1000.0) );
+            drill_diam_iu = int( drill_um * ( pcbIUScale.IU_PER_MM / 1000.0 ) );
 
             if( drill_diam_iu == aViaDrillDefault )
                 drill_diam_iu = UNDEFINED_DRILL_DIAMETER;
diff --git a/pcbnew/tools/board_editor_control.cpp b/pcbnew/tools/board_editor_control.cpp
index b33384d7c5..c57dfc1f72 100644
--- a/pcbnew/tools/board_editor_control.cpp
+++ b/pcbnew/tools/board_editor_control.cpp
@@ -1415,9 +1415,9 @@ int BOARD_EDITOR_CONTROL::ZoneDuplicate( const TOOL_EVENT& aEvent )
     // If the new zone is on the same layer(s) as the initial zone,
     // offset it a bit so it can more easily be picked.
     if( oldZone->GetIsRuleArea() && ( oldZone->GetLayerSet() == zoneSettings.m_Layers ) )
-        newZone->Move( wxPoint( IU_PER_MM, IU_PER_MM ) );
+        newZone->Move( wxPoint( pcbIUScale.IU_PER_MM, pcbIUScale.IU_PER_MM ) );
     else if( !oldZone->GetIsRuleArea() && zoneSettings.m_Layers.test( oldZone->GetLayer() ) )
-        newZone->Move( wxPoint( IU_PER_MM, IU_PER_MM ) );
+        newZone->Move( wxPoint( pcbIUScale.IU_PER_MM, pcbIUScale.IU_PER_MM ) );
 
     commit.Add( newZone.release() );
     commit.Push( _( "Duplicate zone" ) );
diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp
index 33312c7fea..0f84b2a6d3 100644
--- a/pcbnew/tools/edit_tool.cpp
+++ b/pcbnew/tools/edit_tool.cpp
@@ -705,7 +705,8 @@ int EDIT_TOOL::DragArcTrack( const TOOL_EVENT& aEvent )
     if( isEndTrackOnStartPt )
         newEnd = trackOnEnd->GetEnd();
 
-    int maxLengthIU = KiROUND( ADVANCED_CFG::GetCfg().m_MaxTrackLengthToKeep * IU_PER_MM );
+    int maxLengthIU =
+            KiROUND( ADVANCED_CFG::GetCfg().m_MaxTrackLengthToKeep * pcbIUScale.IU_PER_MM );
 
     if( !processTrack( trackOnStart, trackOnStartCopy, maxLengthIU ) )
         theArc->SetStart( newStart );
diff --git a/pcbnew/tools/pad_tool.cpp b/pcbnew/tools/pad_tool.cpp
index 8b25010ee9..2302f90ae7 100644
--- a/pcbnew/tools/pad_tool.cpp
+++ b/pcbnew/tools/pad_tool.cpp
@@ -375,7 +375,7 @@ int PAD_TOOL::EnumeratePads( const TOOL_EVENT& aEvent )
             // the mouse move and search pads that are on the line.
             int distance = ( cursorPos - oldCursorPos ).EuclideanNorm();
             // Search will be made every 0.1 mm:
-            int segments = distance / int( 0.1*IU_PER_MM ) + 1;
+            int           segments = distance / int( 0.1 * pcbIUScale.IU_PER_MM ) + 1;
             const wxPoint line_step( ( cursorPos - oldCursorPos ) / segments );
 
             collector.Empty();
diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp
index b0ff5aa677..7089107b59 100644
--- a/pcbnew/zone_filler.cpp
+++ b/pcbnew/zone_filler.cpp
@@ -1372,7 +1372,7 @@ void ZONE_FILLER::buildThermalSpokes( const ZONE* aZone, PCB_LAYER_ID aLayer,
 
     // Is a point on the boundary of the polygon inside or outside?  This small epsilon lets
     // us avoid the question.
-    int epsilon = KiROUND( IU_PER_MM * 0.04 );  // about 1.5 mil
+    int epsilon = KiROUND( pcbIUScale.IU_PER_MM * 0.04 ); // about 1.5 mil
 
     for( PAD* pad : aSpokedPadsList )
     {
diff --git a/pcbnew/zone_settings.cpp b/pcbnew/zone_settings.cpp
index bc19a06953..904f04c4ba 100644
--- a/pcbnew/zone_settings.cpp
+++ b/pcbnew/zone_settings.cpp
@@ -73,7 +73,7 @@ ZONE_SETTINGS::ZONE_SETTINGS()
     m_cornerRadius = 0;
 
     m_removeIslands = ISLAND_REMOVAL_MODE::AREA;
-    m_minIslandArea = 10 * IU_PER_MM * IU_PER_MM;
+    m_minIslandArea = 10 * pcbIUScale.IU_PER_MM * pcbIUScale.IU_PER_MM;
 
     SetIsRuleArea( false );
     SetDoNotAllowCopperPour( false );
diff --git a/qa/unittests/pcbnew/test_zone_filler.cpp b/qa/unittests/pcbnew/test_zone_filler.cpp
index 2d13d2a21f..067fd2e008 100644
--- a/qa/unittests/pcbnew/test_zone_filler.cpp
+++ b/qa/unittests/pcbnew/test_zone_filler.cpp
@@ -44,7 +44,7 @@ struct ZONE_FILL_TEST_FIXTURE
 };
 
 
-constexpr int delta = KiROUND( 0.006 * IU_PER_MM );
+constexpr int delta = KiROUND( 0.006 * pcbIUScale.IU_PER_MM );
 
 
 BOOST_FIXTURE_TEST_CASE( BasicZoneFills, ZONE_FILL_TEST_FIXTURE )