Selaa lähdekoodia

- all transformation functions show now the progress (rotate, mirror, scale, offset, skew)
- made threaded the Offset and Scale operations found in the Selected tab of the object

Marius Stanciu 6 vuotta sitten
vanhempi
commit
4cbb5846e3
4 muutettua tiedostoa jossa 412 lisäystä ja 17 poistoa
  1. 72 11
      FlatCAMObj.py
  2. 2 0
      README.md
  3. 337 5
      camlib.py
  4. 1 1
      flatcamTools/ToolMove.py

+ 72 - 11
FlatCAMObj.py

@@ -212,26 +212,47 @@ class FlatCAMObj(QtCore.QObject):
 
         self.read_form()
         vector_val = self.ui.offsetvector_entry.get_value()
-        self.offset(vector_val)
-        self.plot()
-        self.app.object_changed.emit(self)
+
+        def worker_task():
+            with self.app.proc_container.new(_("Offsetting...")):
+                self.offset(vector_val)
+            self.app.proc_container.update_view_text('')
+            with self.app.proc_container.new(_("Plotting...")):
+                self.plot()
+            self.app.object_changed.emit(self)
+
+        self.app.worker_task.emit({'fcn': worker_task, 'params': []})
 
     def on_scale_button_click(self):
         self.app.report_usage("obj_on_scale_button")
         self.read_form()
         factor = self.ui.scale_entry.get_value()
-        self.scale(factor)
-        self.plot()
-        self.app.object_changed.emit(self)
+
+        def worker_task():
+            with self.app.proc_container.new(_("Scaling...")):
+                self.scale(factor)
+            self.app.proc_container.update_view_text('')
+            with self.app.proc_container.new(_("Plotting...")):
+                self.plot()
+            self.app.object_changed.emit(self)
+
+        self.app.worker_task.emit({'fcn': worker_task, 'params': []})
 
     def on_skew_button_click(self):
         self.app.report_usage("obj_on_skew_button")
         self.read_form()
         x_angle = self.ui.xangle_entry.get_value()
         y_angle = self.ui.yangle_entry.get_value()
-        self.skew(x_angle, y_angle)
-        self.plot()
-        self.app.object_changed.emit(self)
+
+        def worker_task():
+            with self.app.proc_container.new(_("Skewing...")):
+                self.skew(x_angle, y_angle)
+            self.app.proc_container.update_view_text('')
+            with self.app.proc_container.new(_("Plotting...")):
+                self.plot()
+            self.app.object_changed.emit(self)
+
+        self.app.worker_task.emit({'fcn': worker_task, 'params': []})
 
     def to_form(self):
         """
@@ -5123,6 +5144,10 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         #                                          origin=(px, py))
         # self.app.inform.emit("[success] Geometry Scale done.")
 
+        self.geo_len = 0
+        self.old_disp_number = 0
+        self.el_count = 0
+
         def scale_recursion(geom):
             if type(geom) is list:
                 geoms = list()
@@ -5131,15 +5156,41 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
                 return geoms
             else:
                 try:
+                    self.el_count += 1
+                    disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+                    if self.old_disp_number < disp_number <= 100:
+                        self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                        self.old_disp_number = disp_number
+
                     return affinity.scale(geom, xfactor, yfactor, origin=(px, py))
                 except AttributeError:
                     return geom
 
         if self.multigeo is True:
             for tool in self.tools:
+                # variables to display the percentage of work done
+                self.geo_len = 0
+                try:
+                    for g in self.tools[tool]['solid_geometry']:
+                        self.geo_len += 1
+                except TypeError:
+                    self.geo_len = 1
+                self.old_disp_number = 0
+                self.el_count = 0
+
                 self.tools[tool]['solid_geometry'] = scale_recursion(self.tools[tool]['solid_geometry'])
         else:
             try:
+                # variables to display the percentage of work done
+                self.geo_len = 0
+                try:
+                    for g in self.solid_geometry:
+                        self.geo_len += 1
+                except TypeError:
+                    self.geo_len = 1
+                self.old_disp_number = 0
+                self.el_count = 0
+
                 self.solid_geometry = scale_recursion(self.solid_geometry)
             except AttributeError:
                 self.solid_geometry = []
@@ -5193,14 +5244,24 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         if self.multigeo is True:
             for tool in self.tools:
                 # variables to display the percentage of work done
-                self.geo_len = len(self.tools[tool]['solid_geometry'])
+                self.geo_len = 0
+                try:
+                    for g in self.tools[tool]['solid_geometry']:
+                        self.geo_len += 1
+                except TypeError:
+                    self.geo_len = 1
                 self.old_disp_number = 0
                 self.el_count = 0
 
                 self.tools[tool]['solid_geometry'] = translate_recursion(self.tools[tool]['solid_geometry'])
         else:
             # variables to display the percentage of work done
-            self.geo_len = len(self.solid_geometry)
+            self.geo_len = 0
+            try:
+                for g in self.solid_geometry:
+                    self.geo_len += 1
+            except TypeError:
+                self.geo_len = 1
             self.old_disp_number = 0
             self.el_count = 0
 

+ 2 - 0
README.md

@@ -16,6 +16,8 @@ CAD program, and create G-Code for Isolation routing.
 - remade the handlers for the Enable/Disable Project Tree context menu so they are threaded and activity is shown in the lower right corner of the main window
 - added to GUI new options for the Gerber object related to area subtraction
 - added new feature in the Gerber object isolation allowing for the isolation to avoid an area defined by another object (Gerber or Geometry)
+- all transformation functions show now the progress (rotate, mirror, scale, offset, skew)
+- made threaded the Offset and Scale operations found in the Selected tab of the object
 
 6.09.2019
 

+ 337 - 5
camlib.py

@@ -1413,6 +1413,12 @@ class Geometry(object):
                 return new_obj
             else:
                 try:
+                    self.el_count += 1
+                    disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+                    if self.old_disp_number < disp_number <= 100:
+                        self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                        self.old_disp_number = disp_number
+
                     return affinity.scale(obj, xscale, yscale, origin=(px, py))
                 except AttributeError:
                     return obj
@@ -1420,8 +1426,28 @@ class Geometry(object):
         try:
             if self.multigeo is True:
                 for tool in self.tools:
+                    # variables to display the percentage of work done
+                    self.geo_len = 0
+                    try:
+                        for g in self.tools[tool]['solid_geometry']:
+                            self.geo_len += 1
+                    except TypeError:
+                        self.geo_len = 1
+                    self.old_disp_number = 0
+                    self.el_count = 0
+
                     self.tools[tool]['solid_geometry'] = mirror_geom(self.tools[tool]['solid_geometry'])
             else:
+                # variables to display the percentage of work done
+                self.geo_len = 0
+                try:
+                    for g in self.solid_geometry:
+                        self.geo_len += 1
+                except TypeError:
+                    self.geo_len = 1
+                self.old_disp_number = 0
+                self.el_count = 0
+
                 self.solid_geometry = mirror_geom(self.solid_geometry)
             self.app.inform.emit(_('[success] Object was mirrored ...'))
         except AttributeError:
@@ -1455,6 +1481,12 @@ class Geometry(object):
                 return new_obj
             else:
                 try:
+                    self.el_count += 1
+                    disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+                    if self.old_disp_number < disp_number <= 100:
+                        self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                        self.old_disp_number = disp_number
+
                     return affinity.rotate(obj, angle, origin=(px, py))
                 except AttributeError:
                     return obj
@@ -1462,8 +1494,28 @@ class Geometry(object):
         try:
             if self.multigeo is True:
                 for tool in self.tools:
+                    # variables to display the percentage of work done
+                    self.geo_len = 0
+                    try:
+                        for g in self.tools[tool]['solid_geometry']:
+                            self.geo_len += 1
+                    except TypeError:
+                        self.geo_len = 1
+                    self.old_disp_number = 0
+                    self.el_count = 0
+
                     self.tools[tool]['solid_geometry'] = rotate_geom(self.tools[tool]['solid_geometry'])
             else:
+                # variables to display the percentage of work done
+                self.geo_len = 0
+                try:
+                    for g in self.solid_geometry:
+                        self.geo_len += 1
+                except TypeError:
+                    self.geo_len = 1
+                self.old_disp_number = 0
+                self.el_count = 0
+
                 self.solid_geometry = rotate_geom(self.solid_geometry)
             self.app.inform.emit(_('[success] Object was rotated ...'))
         except AttributeError:
@@ -1496,6 +1548,12 @@ class Geometry(object):
                 return new_obj
             else:
                 try:
+                    self.el_count += 1
+                    disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+                    if self.old_disp_number < disp_number <= 100:
+                        self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                        self.old_disp_number = disp_number
+
                     return affinity.skew(obj, angle_x, angle_y, origin=(px, py))
                 except AttributeError:
                     return obj
@@ -1503,8 +1561,28 @@ class Geometry(object):
         try:
             if self.multigeo is True:
                 for tool in self.tools:
+                    # variables to display the percentage of work done
+                    self.geo_len = 0
+                    try:
+                        for g in self.tools[tool]['solid_geometry']:
+                            self.geo_len += 1
+                    except TypeError:
+                        self.geo_len = 1
+                    self.old_disp_number = 0
+                    self.el_count = 0
+
                     self.tools[tool]['solid_geometry'] = skew_geom(self.tools[tool]['solid_geometry'])
             else:
+                # variables to display the percentage of work done
+                self.geo_len = 0
+                try:
+                    for g in self.solid_geometry:
+                        self.geo_len += 1
+                except TypeError:
+                    self.geo_len = 1
+                self.old_disp_number = 0
+                self.el_count = 0
+
                 self.solid_geometry = skew_geom(self.solid_geometry)
             self.app.inform.emit(_('[success] Object was skewed ...'))
         except AttributeError:
@@ -3409,6 +3487,17 @@ class Gerber (Geometry):
         else:
             px, py = point
 
+        # variables to display the percentage of work done
+        self.geo_len = 0
+        try:
+            for g in self.solid_geometry:
+                self.geo_len += 1
+        except TypeError:
+            self.geo_len = 1
+
+        self.old_disp_number = 0
+        self.el_count = 0
+
         def scale_geom(obj):
             if type(obj) is list:
                 new_obj = []
@@ -3417,6 +3506,12 @@ class Gerber (Geometry):
                 return new_obj
             else:
                 try:
+                    self.el_count += 1
+                    disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+                    if self.old_disp_number < disp_number <= 100:
+                        self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                        self.old_disp_number = disp_number
+
                     return affinity.scale(obj, xfactor, yfactor, origin=(px, py))
                 except AttributeError:
                     return obj
@@ -3479,7 +3574,13 @@ class Gerber (Geometry):
             return
 
         # variables to display the percentage of work done
-        self.geo_len = len(self.solid_geometry)
+        self.geo_len = 0
+        try:
+            for g in self.solid_geometry:
+                self.geo_len += 1
+        except TypeError:
+            self.geo_len = 1
+
         self.old_disp_number = 0
         self.el_count = 0
 
@@ -3549,6 +3650,17 @@ class Gerber (Geometry):
         px, py = point
         xscale, yscale = {"X": (1.0, -1.0), "Y": (-1.0, 1.0)}[axis]
 
+        # variables to display the percentage of work done
+        self.geo_len = 0
+        try:
+            for g in self.solid_geometry:
+                self.geo_len += 1
+        except TypeError:
+            self.geo_len = 1
+
+        self.old_disp_number = 0
+        self.el_count = 0
+
         def mirror_geom(obj):
             if type(obj) is list:
                 new_obj = []
@@ -3557,6 +3669,12 @@ class Gerber (Geometry):
                 return new_obj
             else:
                 try:
+                    self.el_count += 1
+                    disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+                    if self.old_disp_number < disp_number <= 100:
+                        self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                        self.old_disp_number = disp_number
+
                     return affinity.scale(obj, xscale, yscale, origin=(px, py))
                 except AttributeError:
                     return obj
@@ -3599,6 +3717,17 @@ class Gerber (Geometry):
 
         px, py = point
 
+        # variables to display the percentage of work done
+        self.geo_len = 0
+        try:
+            for g in self.solid_geometry:
+                self.geo_len += 1
+        except TypeError:
+            self.geo_len = 1
+
+        self.old_disp_number = 0
+        self.el_count = 0
+
         def skew_geom(obj):
             if type(obj) is list:
                 new_obj = []
@@ -3607,6 +3736,12 @@ class Gerber (Geometry):
                 return new_obj
             else:
                 try:
+                    self.el_count += 1
+                    disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+                    if self.old_disp_number < disp_number <= 100:
+                        self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                        self.old_disp_number = disp_number
+
                     return affinity.skew(obj, angle_x, angle_y, origin=(px, py))
                 except AttributeError:
                     return obj
@@ -3642,6 +3777,17 @@ class Gerber (Geometry):
 
         px, py = point
 
+        # variables to display the percentage of work done
+        self.geo_len = 0
+        try:
+            for g in self.solid_geometry:
+                self.geo_len += 1
+        except TypeError:
+            self.geo_len = 1
+
+        self.old_disp_number = 0
+        self.el_count = 0
+
         def rotate_geom(obj):
             if type(obj) is list:
                 new_obj = []
@@ -3650,6 +3796,12 @@ class Gerber (Geometry):
                 return new_obj
             else:
                 try:
+                    self.el_count += 1
+                    disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+                    if self.old_disp_number < disp_number <= 100:
+                        self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                        self.old_disp_number = disp_number
+
                     return affinity.rotate(obj, angle, origin=(px, py))
                 except AttributeError:
                     return obj
@@ -4766,10 +4918,26 @@ class Excellon(Geometry):
                 except AttributeError:
                     return obj
 
+        # variables to display the percentage of work done
+        self.geo_len = 0
+        try:
+            for g in self.drills:
+                self.geo_len += 1
+        except TypeError:
+            self.geo_len = 1
+        self.old_disp_number = 0
+        self.el_count = 0
+
         # Drills
         for drill in self.drills:
             drill['point'] = affinity.scale(drill['point'], xfactor, yfactor, origin=(px, py))
 
+            self.el_count += 1
+            disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+            if self.old_disp_number < disp_number <= 100:
+                self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                self.old_disp_number = disp_number
+
         # scale solid_geometry
         for tool in self.tools:
             self.tools[tool]['solid_geometry'] = scale_geom(self.tools[tool]['solid_geometry'])
@@ -4806,7 +4974,12 @@ class Excellon(Geometry):
                     return obj
 
         # variables to display the percentage of work done
-        self.geo_len = len(self.drills)
+        self.geo_len = 0
+        try:
+            for g in self.drills:
+                self.geo_len += 1
+        except TypeError:
+            self.geo_len = 1
         self.old_disp_number = 0
         self.el_count = 0
 
@@ -4859,10 +5032,27 @@ class Excellon(Geometry):
                     return obj
 
         # Modify data
+
+        # variables to display the percentage of work done
+        self.geo_len = 0
+        try:
+            for g in self.drills:
+                self.geo_len += 1
+        except TypeError:
+            self.geo_len = 1
+        self.old_disp_number = 0
+        self.el_count = 0
+
         # Drills
         for drill in self.drills:
             drill['point'] = affinity.scale(drill['point'], xscale, yscale, origin=(px, py))
 
+            self.el_count += 1
+            disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+            if self.old_disp_number < disp_number <= 100:
+                self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                self.old_disp_number = disp_number
+
         # mirror solid_geometry
         for tool in self.tools:
             self.tools[tool]['solid_geometry'] = mirror_geom(self.tools[tool]['solid_geometry'])
@@ -4910,6 +5100,16 @@ class Excellon(Geometry):
                 except AttributeError:
                     return obj
 
+        # variables to display the percentage of work done
+        self.geo_len = 0
+        try:
+            for g in self.drills:
+                self.geo_len += 1
+        except TypeError:
+            self.geo_len = 1
+        self.old_disp_number = 0
+        self.el_count = 0
+
         if point is None:
             px, py = 0, 0
 
@@ -4917,6 +5117,13 @@ class Excellon(Geometry):
             for drill in self.drills:
                 drill['point'] = affinity.skew(drill['point'], angle_x, angle_y,
                                                origin=(px, py))
+
+                self.el_count += 1
+                disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+                if self.old_disp_number < disp_number <= 100:
+                    self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                    self.old_disp_number = disp_number
+
             # skew solid_geometry
             for tool in self.tools:
                 self.tools[tool]['solid_geometry'] = skew_geom(self.tools[tool]['solid_geometry'])
@@ -4932,6 +5139,12 @@ class Excellon(Geometry):
                 drill['point'] = affinity.skew(drill['point'], angle_x, angle_y,
                                                origin=(px, py))
 
+                self.el_count += 1
+                disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+                if self.old_disp_number < disp_number <= 100:
+                    self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                    self.old_disp_number = disp_number
+
             # skew solid_geometry
             for tool in self.tools:
                 self.tools[tool]['solid_geometry'] = skew_geom( self.tools[tool]['solid_geometry'])
@@ -4970,6 +5183,16 @@ class Excellon(Geometry):
                     except AttributeError:
                         return obj
 
+        # variables to display the percentage of work done
+        self.geo_len = 0
+        try:
+            for g in self.drills:
+                self.geo_len += 1
+        except TypeError:
+            self.geo_len = 1
+        self.old_disp_number = 0
+        self.el_count = 0
+
         if point is None:
             # Drills
             for drill in self.drills:
@@ -4979,6 +5202,12 @@ class Excellon(Geometry):
             for tool in self.tools:
                 self.tools[tool]['solid_geometry'] = rotate_geom(self.tools[tool]['solid_geometry'], origin='center')
 
+                self.el_count += 1
+                disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+                if self.old_disp_number < disp_number <= 100:
+                    self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                    self.old_disp_number = disp_number
+
             # Slots
             for slot in self.slots:
                 slot['stop'] = affinity.rotate(slot['stop'], angle, origin='center')
@@ -4989,6 +5218,12 @@ class Excellon(Geometry):
             for drill in self.drills:
                 drill['point'] = affinity.rotate(drill['point'], angle, origin=(px, py))
 
+                self.el_count += 1
+                disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+                if self.old_disp_number < disp_number <= 100:
+                    self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                    self.old_disp_number = disp_number
+
             # rotate solid_geometry
             for tool in self.tools:
                 self.tools[tool]['solid_geometry'] = rotate_geom(self.tools[tool]['solid_geometry'])
@@ -7621,23 +7856,59 @@ class CNCjob(Geometry):
         if self.multitool is False:
             # offset Gcode
             self.gcode = scale_g(self.gcode)
-            # offset geometry
+
+            # variables to display the percentage of work done
+            self.geo_len = 0
+            try:
+                for g in self.gcode_parsed:
+                    self.geo_len += 1
+            except TypeError:
+                self.geo_len = 1
+            self.old_disp_number = 0
+            self.el_count = 0
+
+            # scale geometry
             for g in self.gcode_parsed:
                 try:
                     g['geom'] = affinity.scale(g['geom'], xfactor, yfactor, origin=(px, py))
                 except AttributeError:
                     return g['geom']
+
+                self.el_count += 1
+                disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+                if self.old_disp_number < disp_number <= 100:
+                    self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                    self.old_disp_number = disp_number
+
             self.create_geometry()
         else:
             for k, v in self.cnc_tools.items():
                 # scale Gcode
                 v['gcode'] = scale_g(v['gcode'])
+
+                # variables to display the percentage of work done
+                self.geo_len = 0
+                try:
+                    for g in v['gcode_parsed']:
+                        self.geo_len += 1
+                except TypeError:
+                    self.geo_len = 1
+                self.old_disp_number = 0
+                self.el_count = 0
+
                 # scale gcode_parsed
                 for g in v['gcode_parsed']:
                     try:
                         g['geom'] = affinity.scale(g['geom'], xfactor, yfactor, origin=(px, py))
                     except AttributeError:
                         return g['geom']
+
+                    self.el_count += 1
+                    disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+                    if self.old_disp_number < disp_number <= 100:
+                        self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                        self.old_disp_number = disp_number
+
                 v['solid_geometry'] = cascaded_union([geo['geom'] for geo in v['gcode_parsed']])
         self.create_geometry()
 
@@ -7696,7 +7967,12 @@ class CNCjob(Geometry):
             self.gcode = offset_g(self.gcode)
 
             # variables to display the percentage of work done
-            self.geo_len = len(self.gcode_parsed)
+            self.geo_len = 0
+            try:
+                for g in self.gcode_parsed:
+                    self.geo_len += 1
+            except TypeError:
+                self.geo_len = 1
             self.old_disp_number = 0
             self.el_count = 0
 
@@ -7720,7 +7996,12 @@ class CNCjob(Geometry):
                 v['gcode'] = offset_g(v['gcode'])
 
                 # variables to display the percentage of work done
-                self.geo_len = len(v['gcode_parsed'])
+                self.geo_len = 0
+                try:
+                    for g in v['gcode_parsed']:
+                        self.geo_len += 1
+                except TypeError:
+                    self.geo_len = 1
                 self.old_disp_number = 0
                 self.el_count = 0
 
@@ -7752,11 +8033,28 @@ class CNCjob(Geometry):
         px, py = point
         xscale, yscale = {"X": (1.0, -1.0), "Y": (-1.0, 1.0)}[axis]
 
+        # variables to display the percentage of work done
+        self.geo_len = 0
+        try:
+            for g in self.gcode_parsed:
+                self.geo_len += 1
+        except TypeError:
+            self.geo_len = 1
+        self.old_disp_number = 0
+        self.el_count = 0
+
         for g in self.gcode_parsed:
             try:
                 g['geom'] = affinity.scale(g['geom'], xscale, yscale, origin=(px, py))
             except AttributeError:
                 return g['geom']
+
+            self.el_count += 1
+            disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+            if self.old_disp_number < disp_number <= 100:
+                self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                self.old_disp_number = disp_number
+
         self.create_geometry()
 
     def skew(self, angle_x, angle_y, point):
@@ -7778,11 +8076,28 @@ class CNCjob(Geometry):
 
         px, py = point
 
+        # variables to display the percentage of work done
+        self.geo_len = 0
+        try:
+            for g in self.gcode_parsed:
+                self.geo_len += 1
+        except TypeError:
+            self.geo_len = 1
+        self.old_disp_number = 0
+        self.el_count = 0
+
         for g in self.gcode_parsed:
             try:
                 g['geom'] = affinity.skew(g['geom'], angle_x, angle_y, origin=(px, py))
             except AttributeError:
                 return g['geom']
+
+            self.el_count += 1
+            disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+            if self.old_disp_number < disp_number <= 100:
+                self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                self.old_disp_number = disp_number
+
         self.create_geometry()
 
     def rotate(self, angle, point):
@@ -7796,11 +8111,28 @@ class CNCjob(Geometry):
 
         px, py = point
 
+        # variables to display the percentage of work done
+        self.geo_len = 0
+        try:
+            for g in self.gcode_parsed:
+                self.geo_len += 1
+        except TypeError:
+            self.geo_len = 1
+        self.old_disp_number = 0
+        self.el_count = 0
+
         for g in self.gcode_parsed:
             try:
                 g['geom'] = affinity.rotate(g['geom'], angle, origin=(px, py))
             except AttributeError:
                 return g['geom']
+
+            self.el_count += 1
+            disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 99]))
+            if self.old_disp_number < disp_number <= 100:
+                self.app.proc_container.update_view_text(' %d%%' % disp_number)
+                self.old_disp_number = disp_number
+
         self.create_geometry()
 
 

+ 1 - 1
flatcamTools/ToolMove.py

@@ -155,7 +155,7 @@ class ToolMove(FlatCAMTool):
                                     # self.app.collection.set_active(sel_obj.options['name'])
                         except Exception as e:
                             proc.done()
-                            self.app.inform.emit('[ERROR_NOTCL] %s --> %s' % (_('ToolMove.on_left_click('), str(e)))
+                            self.app.inform.emit('[ERROR_NOTCL] %s --> %s' % (_('ToolMove.on_left_click()'), str(e)))
                             return "fail"
                         proc.done()
                         # delete the selection bounding box