@@ -100,6 +100,21 @@ relative_t GcodeSuite::axis_relative; // Init in constructor
100100  xyz_pos_t  GcodeSuite::coordinate_system[MAX_COORDINATE_SYSTEMS];
101101#endif 
102102
103+ #if  ENABLED(SCALE_WORKSPACE)
104+   float  GcodeSuite::scaling_center_x = 0 .0f ;
105+   float  GcodeSuite::scaling_center_y = 0 .0f ;
106+   float  GcodeSuite::scaling_center_z = 0 .0f ;
107+   float  GcodeSuite::scaling_factor_x = 1 .0f ;
108+   float  GcodeSuite::scaling_factor_y = 1 .0f ;
109+   float  GcodeSuite::scaling_factor_z = 1 .0f ;
110+ #endif 
111+ 
112+ #if  ENABLED(ROTATE_WORKSPACE)
113+   float  GcodeSuite::rotation_center_x = 0 .0f ;
114+   float  GcodeSuite::rotation_center_y = 0 .0f ;
115+   float  GcodeSuite::rotation_angle = 0 .0f ;
116+ #endif 
117+ 
103118void  GcodeSuite::report_echo_start (const  bool  forReplay) { if  (!forReplay) SERIAL_ECHO_START (); }
104119void  GcodeSuite::report_heading (const  bool  forReplay, FSTR_P const  fstr, const  bool  eol/* =true*/ 
105120  if  (forReplay) return ;
@@ -171,19 +186,58 @@ void GcodeSuite::get_destination_from_command() {
171186    constexpr  bool  skip_move = false ;
172187  #endif 
173188
189+   const  float  angle_rad = RADIANS (rotation_angle);
190+ 
174191  //  Get new XYZ position, whether absolute or relative
175192  LOOP_NUM_AXES (i) {
176193    if  ( (seen[i] = parser.seenval (AXIS_CHAR (i))) ) {
177194      const  float  v = parser.value_axis_units ((AxisEnum)i);
178-       if  (skip_move)
195+       if  (skip_move) {
196+         #if  ENABLED(ROTATE_WORKSPACE)
197+           raw_destination[i] = current_position[i];
198+         #else 
199+           destination[i] = current_position[i];
200+         #endif 
201+       }
202+       else  {
203+         #if  ENABLED(ROTATE_WORKSPACE)
204+           raw_destination[i] = axis_is_relative (AxisEnum (i)) ? raw_destination[i] + v : LOGICAL_TO_NATIVE (v, i);
205+         #else 
206+           destination[i] = axis_is_relative (AxisEnum (i)) ? current_position[i] + v : LOGICAL_TO_NATIVE (v, i);
207+         #endif 
208+       }
209+     }
210+     else  {
211+       #if  DISABLED(ROTATE_WORKSPACE)
179212        destination[i] = current_position[i];
180-       else 
181-         destination[i] = axis_is_relative (AxisEnum (i)) ? current_position[i] + v : LOGICAL_TO_NATIVE (v, i);
213+       #endif 
182214    }
183-     else 
184-       destination[i] = current_position[i];
185215  }
186216
217+   #if  ANY(SCALE_WORKSPACE, ROTATE_WORKPLACE)
218+     destination = raw_destination;
219+   #endif 
220+ 
221+   #if  ENABLED(SCALE_WORKSPACE)
222+     if  (!(NEAR (scaling_factor_x, 1 .0f ) || NEAR (scaling_factor_y, 1 .0f ) || NEAR (scaling_factor_z, 1 .0f ))) {
223+       destination.x  = (raw_destination.x  - scaling_center_x) * scaling_factor_x + scaling_center_x;
224+       TERN_ (HAS_Y_AXIS, destination.y  = (raw_destination.y  - scaling_center_y) * scaling_factor_y + scaling_center_y);
225+       TERN_ (HAS_Z_AXIS, destination.z  = (raw_destination.z  - scaling_center_z) * scaling_factor_z + scaling_center_z);
226+     }
227+   #endif 
228+ 
229+   #if  ENABLED(ROTATE_WORKSPACE)
230+     if  (!NEAR_ZERO (rotation_angle)) {
231+       const  float  cos_angle = cos (angle_rad);
232+       const  float  sin_angle = sin (angle_rad);
233+       //  Apply rotation
234+       const  float  temp_x = destination.x  - rotation_center_x;
235+       const  float  temp_y = destination.y  - rotation_center_y;
236+       destination.x  = temp_x * cos_angle - temp_y * sin_angle + rotation_center_x;
237+       destination.y  = temp_x * sin_angle + temp_y * cos_angle + rotation_center_y;
238+     }
239+   #endif 
240+ 
187241  #if  HAS_EXTRUDERS
188242    //  Get new E position, whether absolute or relative
189243    if  ( (seen.e  = parser.seenval (' E' 
@@ -435,6 +489,11 @@ void GcodeSuite::process_parsed_command(bool no_ok/*=false*/) {
435489        case  42 : G42 (); break ;                                    //  G42: Coordinated move to a mesh point
436490      #endif 
437491
492+       #if  ENABLED(SCALE_WORKSPACE)
493+         case  50 : G50 (); break ;                                    //  G50: Cancel Workspace Scaling
494+         case  51 : G51 (); break ;                                    //  G51: Set Workspace Scaling
495+       #endif 
496+ 
438497      #if  ENABLED(CNC_COORDINATE_SYSTEMS)
439498        case  53 : G53 (); break ;                                    //  G53: (prefix) Apply native workspace
440499        case  54 : G54 (); break ;                                    //  G54: Switch to Workspace 1
@@ -452,6 +511,7 @@ void GcodeSuite::process_parsed_command(bool no_ok/*=false*/) {
452511
453512      #if  ENABLED(ROTATE_WORKSPACE)
454513        case  68 : G68 (); break ;                                    //  G68: Set Workspace Rotation
514+         case  69 : G69 (); break ;                                    //  G69: Cancel Workspace Rotation
455515      #endif 
456516
457517      #if  ALL(PTC_PROBE, PTC_BED)
0 commit comments