@@ -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 ANY(SCALE_WORKSPACE, ROTATE_WORKSPACE)
197+ raw_destination[i] = current_position[i];
198+ #else
199+ destination[i] = current_position[i];
200+ #endif
201+ }
202+ else {
203+ #if ANY(SCALE_WORKSPACE, 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 NONE(SCALE_WORKSPACE, 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