@ -39,7 +39,6 @@
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    enum  MeshPointType  {  INVALID ,  REAL ,  SET_IN_BITMAP  } ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    bool  axis_unhomed_error ( bool ,  bool ,  bool ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    void  dump ( char  *  const  str ,  const  float  & f ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    bool  ubl_lcd_clicked ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    void  probe_entire_mesh ( const  float & ,  const  float & ,  const  bool ,  const  bool ,  const  bool ) ; 
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				 
				
					@ -78,275 +77,273 @@
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    enum  MBLStatus  {  MBL_STATUS_NONE  =  0 ,  MBL_STATUS_HAS_MESH_BIT  =  0 ,  MBL_STATUS_ACTIVE_BIT  =  1  } ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # define MESH_X_DIST ( ( float(UBL_MESH_MAX_X)  - float (UBL_MESH_MIN_X)) /   ( float(UBL_MESH_NUM_X_POINTS)  - 1.0 ))
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # define MESH_Y_DIST ( ( float(UBL_MESH_MAX_Y)  - float (UBL_MESH_MIN_Y)) /   ( float(UBL_MESH_NUM_Y_POINTS)  - 1.0 ))
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # define MESH_X_DIST ( float(UBL_MESH_MAX_X - (UBL_MESH_MIN_X)) /   float(UBL_MESH_NUM_X_POINTS - 1))
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # define MESH_Y_DIST ( float(UBL_MESH_MAX_Y - (UBL_MESH_MIN_Y)) /   float(UBL_MESH_NUM_Y_POINTS - 1))
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    extern  float  mesh_index_to_x_location [ UBL_MESH_NUM_X_POINTS  +  1 ] ;  // +1 just because of paranoia that we might end up on the
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    extern  float  mesh_index_to_y_location [ UBL_MESH_NUM_Y_POINTS  +  1 ] ;  // the last Mesh Line and that is the start of a whole new cell
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    typedef  struct  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      bool  active  =  false ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      float  z_offset  =  0.0 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      int8_t  eeprom_storage_slot  =  - 1 , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					             n_x  =  UBL_MESH_NUM_X_POINTS , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					             n_y  =  UBL_MESH_NUM_Y_POINTS ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      float  mesh_x_min  =  UBL_MESH_MIN_X , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            mesh_y_min  =  UBL_MESH_MIN_Y , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            mesh_x_max  =  UBL_MESH_MAX_X , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            mesh_y_max  =  UBL_MESH_MAX_Y , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            mesh_x_dist  =  MESH_X_DIST , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            mesh_y_dist  =  MESH_Y_DIST ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        float  g29_correction_fade_height  =  10.0 , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              g29_fade_height_multiplier  =  1.0  /  10.0 ;  // It's cheaper to do a floating point multiply than divide,
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                                                       // so keep this value and its reciprocal.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # else 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        const  float  g29_correction_fade_height  =  10.0 , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    g29_fade_height_multiplier  =  1.0  /  10.0 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      // If you change this struct, adjust TOTAL_STRUCT_SIZE
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # define TOTAL_STRUCT_SIZE 40  // Total size of the above fields
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      // padding provides space to add state variables without
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      // changing the location of data structures in the EEPROM.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      // This is for compatibility with future versions to keep
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      // users from having to regenerate their mesh data.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      unsigned  char  padding [ 64  -  TOTAL_STRUCT_SIZE ] ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    }  ubl_state ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    class  unified_bed_leveling  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      private : 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      float  last_specified_z , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            fade_scaling_factor_for_current_height ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static   float  last_specified_z , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                      fade_scaling_factor_for_current_height ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      public : 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      float  z_values [ UBL_MESH_NUM_X_POINTS ] [ UBL_MESH_NUM_Y_POINTS ] ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  ubl_state  state ,  pre_initialized  ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      bool  g26_debug_flag  =  false , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					           has_control_of_lcd_panel  =  false ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  float  z_values [ UBL_MESH_NUM_X_POINTS ] [ UBL_MESH_NUM_Y_POINTS ] , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                     mesh_index_to_xpos [ UBL_MESH_NUM_X_POINTS  +  1 ] ,  // +1 safety margin for now, until determinism prevails
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                     mesh_index_to_ypos [ UBL_MESH_NUM_Y_POINTS  +  1 ] ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      int8_t  eeprom_start  =  - 1 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  bool  g26_debug_flag , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    has_control_of_lcd_panel ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      volatile  int  encoder_diff ;  // Volatile because it's changed at interrupt time.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  int8_t  eeprom_start ;  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      struct  ubl_state  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        bool  active  =  false ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        float  z_offset  =  0.0 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        int8_t  eeprom_storage_slot  =  - 1 , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					               n_x  =  UBL_MESH_NUM_X_POINTS , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					               n_y  =  UBL_MESH_NUM_Y_POINTS ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  volatile  int  encoder_diff ;  // Volatile because it's changed at interrupt time.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        float  mesh_x_min  =  UBL_MESH_MIN_X , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              mesh_y_min  =  UBL_MESH_MIN_Y , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              mesh_x_max  =  UBL_MESH_MAX_X , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              mesh_y_max  =  UBL_MESH_MAX_Y , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              mesh_x_dist  =  MESH_X_DIST , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              mesh_y_dist  =  MESH_Y_DIST ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        unified_bed_leveling ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        # if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          float  g29_correction_fade_height  =  10.0 , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                g29_fade_height_multiplier  =  1.0  /  10.0 ;  // It's cheaper to do a floating point multiply than divide,
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                                                         // so keep this value and its reciprocal.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        # else 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          const  float  g29_correction_fade_height  =  10.0 , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                      g29_fade_height_multiplier  =  1.0  /  10.0 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  void  display_map ( const  int ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        // If you change this struct, adjust TOTAL_STRUCT_SIZE
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        # define TOTAL_STRUCT_SIZE 43  // Total size of the above fields
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        // padding provides space to add state variables without
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        // changing the location of data structures in the EEPROM.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        // This is for compatibility with future versions to keep
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        // users from having to regenerate their mesh data.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        unsigned  char  padding [ 64  -  TOTAL_STRUCT_SIZE ] ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      }  state ,  pre_initialized ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      unified_bed_leveling ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      void  display_map ( const  int ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      void  reset ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      void  invalidate ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      void  store_state ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      void  load_state ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      void  store_mesh ( const  int16_t ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      void  load_mesh ( const  int16_t ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      bool  sanity_check ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      FORCE_INLINE  static  float  map_x_index_to_bed_location ( const  int8_t  i )  {  return  ( ( float )  UBL_MESH_MIN_X )  +  ( ( ( float )  MESH_X_DIST )  *  ( float )  i ) ;  } ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      FORCE_INLINE  static  float  map_y_index_to_bed_location ( const  int8_t  i )  {  return  ( ( float )  UBL_MESH_MIN_Y )  +  ( ( ( float )  MESH_Y_DIST )  *  ( float )  i ) ;  } ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      FORCE_INLINE  void  set_z ( const  int8_t  px ,  const  int8_t  py ,  const  float  & z )  {  z_values [ px ] [ py ]  =  z ;  } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      static  int8_t  get_cell_index_x ( const  float  & x )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        const  int8_t  cx  =  ( x  -  ( UBL_MESH_MIN_X ) )  *  ( 1.0  /  ( MESH_X_DIST ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        return  constrain ( cx ,  0 ,  ( UBL_MESH_NUM_X_POINTS )  -  1 ) ;    // -1 is appropriate if we want all movement to the X_MAX
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      }                                                          // position. But with this defined this way, it is possible
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                                                                // to extrapolate off of this point even further out. Probably
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                                                                // that is OK because something else should be keeping that from
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                                                                // happening and should not be worried about at this level.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      static  int8_t  get_cell_index_y ( const  float  & y )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        const  int8_t  cy  =  ( y  -  ( UBL_MESH_MIN_Y ) )  *  ( 1.0  /  ( MESH_Y_DIST ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        return  constrain ( cy ,  0 ,  ( UBL_MESH_NUM_Y_POINTS )  -  1 ) ;    // -1 is appropriate if we want all movement to the Y_MAX
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      }                                                          // position. But with this defined this way, it is possible
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                                                                // to extrapolate off of this point even further out. Probably
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                                                                // that is OK because something else should be keeping that from
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                                                                // happening and should not be worried about at this level.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      static  int8_t  find_closest_x_index ( const  float  & x )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        const  int8_t  px  =  ( x  -  ( UBL_MESH_MIN_X )  +  ( MESH_X_DIST )  *  0.5 )  *  ( 1.0  /  ( MESH_X_DIST ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        return  ( px  > =  0  & &  px  <  ( UBL_MESH_NUM_X_POINTS ) )  ?  px  :  - 1 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      static  int8_t  find_closest_y_index ( const  float  & y )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        const  int8_t  py  =  ( y  -  ( UBL_MESH_MIN_Y )  +  ( MESH_Y_DIST )  *  0.5 )  *  ( 1.0  /  ( MESH_Y_DIST ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        return  ( py  > =  0  & &  py  <  ( UBL_MESH_NUM_Y_POINTS ) )  ?  py  :  - 1 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      /**
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *                            z2    - - | 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *                  z0         |       | 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *                   |         |       +  ( z2 - z1 ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *    z1              |         |       | 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *  - - - + - - - - - - - - - - - - - + - - - - - - - - + - -   - - | 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *    a1             a0         a2 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *     | < - - - delta_a - - - - - - - - - - > | 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       * 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *   calc_z0  is  the  basis  for  all  the  Mesh  Based  correction .  It  is  used  to 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *   find  the  expected  Z  Height  at  a  position  between  two  known  Z - Height  locations . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       * 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *   It  is  fairly  expensive  with  its  4  floating  point  additions  and  2  floating  point 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *   multiplications . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       */ 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      static  FORCE_INLINE  float  calc_z0 ( const  float  & a0 ,  const  float  & a1 ,  const  float  & z1 ,  const  float  & a2 ,  const  float  & z2 )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        const  float  delta_z  =  ( z2  -  z1 ) , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    delta_a  =  ( a0  -  a1 )  /  ( a2  -  a1 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        return  z1  +  delta_a  *  delta_z ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      /**
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *  get_z_correction_at_Y_intercept ( float  x0 ,  int  x1_i ,  int  yi )  only  takes 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *  three  parameters .  It  assumes  the  x0  point  is  on  a  Mesh  line  denoted  by  yi .  In  theory 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *  we  could  use  get_cell_index_x ( float  x )  to  obtain  the  2 nd  parameter  x1_i  but  any  code  calling 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *  the  get_z_correction_along_vertical_mesh_line_at_specific_X  routine   will  already  have 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *  the  X  index  of  the  x0  intersection  available  and  we  don ' t  want  to  perform  any  extra  floating 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *  point  operations . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       */ 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      inline  float  get_z_correction_along_horizontal_mesh_line_at_specific_X ( const  float  & x0 ,  const  int  x1_i ,  const  int  yi )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        if  ( x1_i  <  0  | |  yi  <  0  | |  x1_i  > =  UBL_MESH_NUM_X_POINTS  | |  yi  > =  UBL_MESH_NUM_Y_POINTS )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_ECHOPAIR ( " ? in get_z_correction_along_horizontal_mesh_line_at_specific_X(x0= " ,  x0 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_ECHOPAIR ( " ,x1_i= " ,  x1_i ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_ECHOPAIR ( " ,yi= " ,  yi ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_CHAR ( ' ) ' ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_EOL ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          return  NAN ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  void  reset ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  void  invalidate ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  void  store_state ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  void  load_state ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  void  store_mesh ( const  int16_t ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  void  load_mesh ( const  int16_t ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  bool  sanity_check ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  FORCE_INLINE  void  set_z ( const  int8_t  px ,  const  int8_t  py ,  const  float  & z )  {  z_values [ px ] [ py ]  =  z ;  } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  int8_t  get_cell_index_x ( const  float  & x )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          const  int8_t  cx  =  ( x  -  ( UBL_MESH_MIN_X ) )  *  ( 1.0  /  ( MESH_X_DIST ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          return  constrain ( cx ,  0 ,  ( UBL_MESH_NUM_X_POINTS )  -  1 ) ;    // -1 is appropriate if we want all movement to the X_MAX
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        }                                                          // position. But with this defined this way, it is possible
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                                                                  // to extrapolate off of this point even further out. Probably
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                                                                  // that is OK because something else should be keeping that from
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                                                                  // happening and should not be worried about at this level.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  int8_t  get_cell_index_y ( const  float  & y )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          const  int8_t  cy  =  ( y  -  ( UBL_MESH_MIN_Y ) )  *  ( 1.0  /  ( MESH_Y_DIST ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          return  constrain ( cy ,  0 ,  ( UBL_MESH_NUM_Y_POINTS )  -  1 ) ;    // -1 is appropriate if we want all movement to the Y_MAX
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        }                                                          // position. But with this defined this way, it is possible
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                                                                  // to extrapolate off of this point even further out. Probably
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                                                                  // that is OK because something else should be keeping that from
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                                                                  // happening and should not be worried about at this level.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  int8_t  find_closest_x_index ( const  float  & x )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          const  int8_t  px  =  ( x  -  ( UBL_MESH_MIN_X )  +  ( MESH_X_DIST )  *  0.5 )  *  ( 1.0  /  ( MESH_X_DIST ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          return  ( px  > =  0  & &  px  <  ( UBL_MESH_NUM_X_POINTS ) )  ?  px  :  - 1 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        const  float  xratio  =  ( RAW_X_POSITION ( x0 )  -  mesh_index_to_x_location [ x1_i ] )  *  ( 1.0  /  ( MESH_X_DIST ) ) , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    z1  =  z_values [ x1_i ] [ yi ] , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    z2  =  z_values [ x1_i  +  1 ] [ yi ] , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    dz  =  ( z2  -  z1 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        return  z1  +  xratio  *  dz ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      //
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      // See comments above for get_z_correction_along_horizontal_mesh_line_at_specific_X
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      //
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      inline  float  get_z_correction_along_vertical_mesh_line_at_specific_Y ( const  float  & y0 ,  const  int  xi ,  const  int  y1_i )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        if  ( xi  <  0  | |  y1_i  <  0  | |  xi  > =  UBL_MESH_NUM_X_POINTS  | |  y1_i  > =  UBL_MESH_NUM_Y_POINTS )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_ECHOPAIR ( " ? in get_z_correction_along_vertical_mesh_line_at_specific_X(y0= " ,  y0 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_ECHOPAIR ( " , x1_i= " ,  xi ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_ECHOPAIR ( " , yi= " ,  y1_i ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_CHAR ( ' ) ' ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_EOL ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          return  NAN ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  int8_t  find_closest_y_index ( const  float  & y )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          const  int8_t  py  =  ( y  -  ( UBL_MESH_MIN_Y )  +  ( MESH_Y_DIST )  *  0.5 )  *  ( 1.0  /  ( MESH_Y_DIST ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          return  ( py  > =  0  & &  py  <  ( UBL_MESH_NUM_Y_POINTS ) )  ?  py  :  - 1 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        const  float  yratio  =  ( RAW_Y_POSITION ( y0 )  -  mesh_index_to_y_location [ y1_i ] )  *  ( 1.0  /  ( MESH_Y_DIST ) ) , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    z1  =  z_values [ xi ] [ y1_i ] , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    z2  =  z_values [ xi ] [ y1_i  +  1 ] , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    dz  =  ( z2  -  z1 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        return  z1  +  yratio  *  dz ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      /**
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *  This  is  the  generic  Z - Correction .  It  works  anywhere  within  a  Mesh  Cell .  It  first 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *  does  a  linear  interpolation  along  both  of  the  bounding  X - Mesh - Lines  to  find  the 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *  Z - Height  at  both  ends .  Then  it  does  a  linear  interpolation  of  these  heights  based 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *  on  the  Y  position  within  the  cell . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       */ 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      float  get_z_correction ( const  float  & x0 ,  const  float  & y0 )  const  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        const  int8_t  cx  =  get_cell_index_x ( RAW_X_POSITION ( x0 ) ) , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                     cy  =  get_cell_index_y ( RAW_Y_POSITION ( y0 ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        if  ( cx  <  0  | |  cy  <  0  | |  cx  > =  UBL_MESH_NUM_X_POINTS  | |  cy  > =  UBL_MESH_NUM_Y_POINTS )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_ECHOPAIR ( " ? in get_z_correction(x0= " ,  x0 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_ECHOPAIR ( " , y0= " ,  y0 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_CHAR ( ' ) ' ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_EOL ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          # if ENABLED(ULTRA_LCD) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            strcpy ( lcd_status_message ,  " get_z_correction() indexes out of range. " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            lcd_quick_feedback ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          return  0.0 ;  // this used to return state.z_offset
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        /**
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *                            z2    - - | 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *                  z0         |       | 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *                   |         |       +  ( z2 - z1 ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *    z1              |         |       | 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *  - - - + - - - - - - - - - - - - - + - - - - - - - - + - -   - - | 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *    a1             a0         a2 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *     | < - - - delta_a - - - - - - - - - - > | 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         * 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *   calc_z0  is  the  basis  for  all  the  Mesh  Based  correction .  It  is  used  to 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *   find  the  expected  Z  Height  at  a  position  between  two  known  Z - Height  locations . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         * 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *   It  is  fairly  expensive  with  its  4  floating  point  additions  and  2  floating  point 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *   multiplications . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         */ 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  FORCE_INLINE  float  calc_z0 ( const  float  & a0 ,  const  float  & a1 ,  const  float  & z1 ,  const  float  & a2 ,  const  float  & z2 )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          const  float  delta_z  =  ( z2  -  z1 ) , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                      delta_a  =  ( a0  -  a1 )  /  ( a2  -  a1 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          return  z1  +  delta_a  *  delta_z ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        const  float  z1  =  calc_z0 ( RAW_X_POSITION ( x0 ) , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                      map_x_index_to_bed_location ( cx ) ,  z_values [ cx ] [ cy ] , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                      map_x_index_to_bed_location ( cx  +  1 ) ,  z_values [ cx  +  1 ] [ cy ] ) , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    z2  =  calc_z0 ( RAW_X_POSITION ( x0 ) , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                      map_x_index_to_bed_location ( cx ) ,  z_values [ cx ] [ cy  +  1 ] , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                      map_x_index_to_bed_location ( cx  +  1 ) ,  z_values [ cx  +  1 ] [ cy  +  1 ] ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              float  z0  =  calc_z0 ( RAW_Y_POSITION ( y0 ) , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                  map_y_index_to_bed_location ( cy ) ,  z1 , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                  map_y_index_to_bed_location ( cy  +  1 ) ,  z2 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        # if ENABLED(DEBUG_LEVELING_FEATURE) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  ( DEBUGGING ( MESH_ADJUST ) )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ECHOPAIR ( "  raw get_z_correction( " ,  x0 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_CHAR ( ' , ' ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ECHO ( y0 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ECHOPGM ( " ) =  " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ECHO_F ( z0 ,  6 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        /**
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *  get_z_correction_at_Y_intercept ( float  x0 ,  int  x1_i ,  int  yi )  only  takes 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *  three  parameters .  It  assumes  the  x0  point  is  on  a  Mesh  line  denoted  by  yi .  In  theory 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *  we  could  use  get_cell_index_x ( float  x )  to  obtain  the  2 nd  parameter  x1_i  but  any  code  calling 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *  the  get_z_correction_along_vertical_mesh_line_at_specific_X  routine   will  already  have 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *  the  X  index  of  the  x0  intersection  available  and  we  don ' t  want  to  perform  any  extra  floating 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *  point  operations . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         */ 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  inline  float  get_z_correction_along_horizontal_mesh_line_at_specific_X ( const  float  & x0 ,  const  int  x1_i ,  const  int  yi )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  ( x1_i  <  0  | |  yi  <  0  | |  x1_i  > =  UBL_MESH_NUM_X_POINTS  | |  yi  > =  UBL_MESH_NUM_Y_POINTS )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ECHOPAIR ( " ? in get_z_correction_along_horizontal_mesh_line_at_specific_X(x0= " ,  x0 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ECHOPAIR ( " ,x1_i= " ,  x1_i ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ECHOPAIR ( " ,yi= " ,  yi ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_CHAR ( ' ) ' ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_EOL ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            return  NAN ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        # if ENABLED(DEBUG_LEVELING_FEATURE) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  ( DEBUGGING ( MESH_ADJUST ) )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ECHOPGM ( "  >>>--->  " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ECHO_F ( z0 ,  6 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          const  float  xratio  =  ( RAW_X_POSITION ( x0 )  -  mesh_index_to_xpos [ x1_i ] )  *  ( 1.0  /  ( MESH_X_DIST ) ) , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                      z1  =  z_values [ x1_i ] [ yi ] , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                      z2  =  z_values [ x1_i  +  1 ] [ yi ] , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                      dz  =  ( z2  -  z1 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          return  z1  +  xratio  *  dz ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        //
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        // See comments above for get_z_correction_along_horizontal_mesh_line_at_specific_X
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        //
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  inline  float  get_z_correction_along_vertical_mesh_line_at_specific_Y ( const  float  & y0 ,  const  int  xi ,  const  int  y1_i )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  ( xi  <  0  | |  y1_i  <  0  | |  xi  > =  UBL_MESH_NUM_X_POINTS  | |  y1_i  > =  UBL_MESH_NUM_Y_POINTS )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ECHOPAIR ( " ? in get_z_correction_along_vertical_mesh_line_at_specific_X(y0= " ,  y0 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ECHOPAIR ( " , x1_i= " ,  xi ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ECHOPAIR ( " , yi= " ,  y1_i ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_CHAR ( ' ) ' ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_EOL ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            return  NAN ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        if  ( isnan ( z0 ) )  {  // if part of the Mesh is undefined, it will show up as NAN
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          z0  =  0.0 ;       // in ubl.z_values[][] and propagate through the
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                         // calculations. If our correction is NAN, we throw it out
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                         // because part of the Mesh is undefined and we don't have the
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                         // information we need to complete the height correction.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          const  float  yratio  =  ( RAW_Y_POSITION ( y0 )  -  mesh_index_to_ypos [ y1_i ] )  *  ( 1.0  /  ( MESH_Y_DIST ) ) , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                      z1  =  z_values [ xi ] [ y1_i ] , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                      z2  =  z_values [ xi ] [ y1_i  +  1 ] , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                      dz  =  ( z2  -  z1 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          return  z1  +  yratio  *  dz ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        /**
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *  This  is  the  generic  Z - Correction .  It  works  anywhere  within  a  Mesh  Cell .  It  first 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *  does  a  linear  interpolation  along  both  of  the  bounding  X - Mesh - Lines  to  find  the 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *  Z - Height  at  both  ends .  Then  it  does  a  linear  interpolation  of  these  heights  based 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *  on  the  Y  position  within  the  cell . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         */ 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  float  get_z_correction ( const  float  & x0 ,  const  float  & y0 )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          const  int8_t  cx  =  get_cell_index_x ( RAW_X_POSITION ( x0 ) ) , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                       cy  =  get_cell_index_y ( RAW_Y_POSITION ( y0 ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  ( cx  <  0  | |  cy  <  0  | |  cx  > =  UBL_MESH_NUM_X_POINTS  | |  cy  > =  UBL_MESH_NUM_Y_POINTS )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ECHOPAIR ( " ? in get_z_correction(x0= " ,  x0 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ECHOPAIR ( " , y0= " ,  y0 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_CHAR ( ' ) ' ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_EOL ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            # if ENABLED(ULTRA_LCD) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              strcpy ( lcd_status_message ,  " get_z_correction() indexes out of range. " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              lcd_quick_feedback ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            return  0.0 ;  // this used to return state.z_offset
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          const  float  z1  =  calc_z0 ( RAW_X_POSITION ( x0 ) , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                        mesh_index_to_xpos [ cx ] ,  z_values [ cx ] [ cy ] , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                        mesh_index_to_xpos [ cx  +  1 ] ,  z_values [ cx  +  1 ] [ cy ] ) , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                      z2  =  calc_z0 ( RAW_X_POSITION ( x0 ) , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                        mesh_index_to_xpos [ cx ] ,  z_values [ cx ] [ cy  +  1 ] , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                        mesh_index_to_xpos [ cx  +  1 ] ,  z_values [ cx  +  1 ] [ cy  +  1 ] ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                float  z0  =  calc_z0 ( RAW_Y_POSITION ( y0 ) , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    mesh_index_to_ypos [ cy ] ,  z1 , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    mesh_index_to_ypos [ cy  +  1 ] ,  z2 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          # if ENABLED(DEBUG_LEVELING_FEATURE) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            if  ( DEBUGGING ( MESH_ADJUST ) )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              SERIAL_ECHOPAIR ( " ??? Yikes!  NAN in get_z_correction( " ,  x0 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              SERIAL_CHAR ( ' , ' ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              SERIAL_ECHOPAIR ( "  raw  get_z_correction(" ,  x0 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              SERIAL_CHAR ( ' , ' ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              SERIAL_ECHO ( y0 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              SERIAL_CHAR ( ' ) ' ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              SERIAL_ECHOPGM ( " ) =  " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              SERIAL_ECHO_F ( z0 ,  6 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          # if ENABLED(DEBUG_LEVELING_FEATURE) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            if  ( DEBUGGING ( MESH_ADJUST ) )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              SERIAL_ECHOPGM ( "  >>>--->  " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              SERIAL_ECHO_F ( z0 ,  6 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              SERIAL_EOL ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        return  z0 ;  // there used to be a +state.z_offset on this line
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      /**
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *  This  routine  is  used  to  scale  the  Z  correction  depending  upon  the  current  nozzle  height .  It  is 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *  optimized  for  speed .  It  avoids  floating  point  operations  by  checking  if  the  requested  scaling 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *  factor  is  going  to  be  the  same  as  the  last  time  the  function  calculated  a  value .  If  so ,  it  just 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *  returns  it . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       * 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *  It  returns  a  scaling  factor  of  1.0  if  UBL  is  inactive . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       *  It  returns  a  scaling  factor  of  0.0  if  Z  is  past  the  specified  ' Fade  Height ' 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       */ 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        FORCE_INLINE  float  fade_scaling_factor_for_z ( const  float  & lz )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          const  float  rz  =  RAW_Z_POSITION ( lz ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  ( last_specified_z  ! =  rz )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            last_specified_z  =  rz ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            fade_scaling_factor_for_current_height  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              state . active  & &  rz  <  state . g29_correction_fade_height 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                ?  1.0  -  ( rz  *  state . g29_fade_height_multiplier ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                :  0.0 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  ( isnan ( z0 ) )  {  // if part of the Mesh is undefined, it will show up as NAN
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            z0  =  0.0 ;       // in ubl.z_values[][] and propagate through the
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                           // calculations. If our correction is NAN, we throw it out
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                           // because part of the Mesh is undefined and we don't have the
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                           // information we need to complete the height correction.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            # if ENABLED(DEBUG_LEVELING_FEATURE) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              if  ( DEBUGGING ( MESH_ADJUST ) )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                SERIAL_ECHOPAIR ( " ??? Yikes!  NAN in get_z_correction( " ,  x0 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                SERIAL_CHAR ( ' , ' ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                SERIAL_ECHO ( y0 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                SERIAL_CHAR ( ' ) ' ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                SERIAL_EOL ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          return  fade_scaling_factor_for_current_height ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          return  z0;  // there used to be a +state.z_offset on this line
  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # else 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        /**
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *  This  routine  is  used  to  scale  the  Z  correction  depending  upon  the  current  nozzle  height .  It  is 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *  optimized  for  speed .  It  avoids  floating  point  operations  by  checking  if  the  requested  scaling 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *  factor  is  going  to  be  the  same  as  the  last  time  the  function  calculated  a  value .  If  so ,  it  just 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *  returns  it . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         * 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *  It  returns  a  scaling  factor  of  1.0  if  UBL  is  inactive . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         *  It  returns  a  scaling  factor  of  0.0  if  Z  is  past  the  specified  ' Fade  Height ' 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					         */ 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        # if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          FORCE_INLINE  float  fade_scaling_factor_for_z ( const  float  & lz )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            const  float  rz  =  RAW_Z_POSITION ( lz ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            if  ( last_specified_z  ! =  rz )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              last_specified_z  =  rz ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              fade_scaling_factor_for_current_height  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                state . active  & &  rz  <  state . g29_correction_fade_height 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                  ?  1.0  -  ( rz  *  state . g29_fade_height_multiplier ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                  :  0.0 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            return  fade_scaling_factor_for_current_height ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        static  constexpr  float  fade_scaling_factor_for_z ( const  float  & lz )  {  UNUSED ( lz ) ;  return  1.0 ;  } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        # else 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          static  constexpr  float  fade_scaling_factor_for_z ( const  float  & lz )  {  UNUSED ( lz ) ;  return  1.0 ;  } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    } ;  // class unified_bed_leveling
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				 
				
					@ -355,5 +352,4 @@
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # define UBL_LAST_EEPROM_INDEX (E2END - sizeof(unified_bed_leveling::state)) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  # endif  // AUTO_BED_LEVELING_UBL
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					# endif  // UNIFIED_BED_LEVELING_H