Просмотр исходного кода

- fixed the Tcl Command Delete to have an argument -f that will force deletion evading the popup (if the popup is enabled). The sme command without a name now will delete all objects
- fixed the Tcl Command JoinExcellons
- fixed the Tcl Command JoinGeometry
- fixed the Tcl Command Mirror
- updated the Tcl Command Mirror to use a (X,Y) origin parameter. Works if the -box parameter is not used.
- updated the Tcl Command Offset. Now it can use only -x or -y parameter no longer is mandatory to have both. The one that is not present will be assumed 0.0
- updated the Tcl Command Panelize. The -rows and -columns parameters are no longer both required. If one is not present then it is assumed to be zero.
- updated the Tcl Command Scale. THe -origin parameter can now be a tuple of (x,y) coordinates.
- updated the Tcl Command Skew. Now it can use only -x or -y parameter no longer is mandatory to have both. The one that is not present will be assumed 0.0
- updated the help for all the Tcl Commands

Marius Stanciu 5 лет назад
Родитель
Сommit
42949021b1
53 измененных файлов с 322 добавлено и 178 удалено
  1. 16 7
      FlatCAMApp.py
  2. 13 0
      README.md
  3. 1 1
      tclCommands/TclCommandAddCircle.py
  4. 1 1
      tclCommands/TclCommandAddRectangle.py
  5. 1 1
      tclCommands/TclCommandAlignDrill.py
  6. 1 1
      tclCommands/TclCommandAlignDrillGrid.py
  7. 1 1
      tclCommands/TclCommandBbox.py
  8. 1 0
      tclCommands/TclCommandBounds.py
  9. 1 1
      tclCommands/TclCommandClearShell.py
  10. 1 1
      tclCommands/TclCommandCutout.py
  11. 39 13
      tclCommands/TclCommandDelete.py
  12. 2 2
      tclCommands/TclCommandExportGcode.py
  13. 1 1
      tclCommands/TclCommandExportGerber.py
  14. 1 1
      tclCommands/TclCommandExportSVG.py
  15. 2 2
      tclCommands/TclCommandExteriors.py
  16. 2 2
      tclCommands/TclCommandFollow.py
  17. 2 2
      tclCommands/TclCommandGeoCutout.py
  18. 3 3
      tclCommands/TclCommandGeoUnion.py
  19. 2 2
      tclCommands/TclCommandGetNames.py
  20. 2 2
      tclCommands/TclCommandGetSys.py
  21. 2 2
      tclCommands/TclCommandImportSvg.py
  22. 3 3
      tclCommands/TclCommandInteriors.py
  23. 8 4
      tclCommands/TclCommandIsolate.py
  24. 11 10
      tclCommands/TclCommandJoinExcellon.py
  25. 10 8
      tclCommands/TclCommandJoinGeometry.py
  26. 1 1
      tclCommands/TclCommandListSys.py
  27. 9 7
      tclCommands/TclCommandMillDrills.py
  28. 9 5
      tclCommands/TclCommandMillSlots.py
  29. 26 17
      tclCommands/TclCommandMirror.py
  30. 1 1
      tclCommands/TclCommandNew.py
  31. 1 1
      tclCommands/TclCommandNewExcellon.py
  32. 3 2
      tclCommands/TclCommandNewGeometry.py
  33. 1 1
      tclCommands/TclCommandNewGerber.py
  34. 2 2
      tclCommands/TclCommandNregions.py
  35. 15 8
      tclCommands/TclCommandOffset.py
  36. 8 2
      tclCommands/TclCommandOpenExcellon.py
  37. 7 3
      tclCommands/TclCommandOpenGCode.py
  38. 8 3
      tclCommands/TclCommandOpenGerber.py
  39. 7 3
      tclCommands/TclCommandOpenProject.py
  40. 3 3
      tclCommands/TclCommandOptions.py
  41. 21 7
      tclCommands/TclCommandPanelize.py
  42. 1 1
      tclCommands/TclCommandPlotAll.py
  43. 4 4
      tclCommands/TclCommandPlotObjects.py
  44. 5 2
      tclCommands/TclCommandSaveProject.py
  45. 2 2
      tclCommands/TclCommandSaveSys.py
  46. 21 8
      tclCommands/TclCommandScale.py
  47. 2 2
      tclCommands/TclCommandSetActive.py
  48. 5 3
      tclCommands/TclCommandSetOrigin.py
  49. 2 2
      tclCommands/TclCommandSetSys.py
  50. 21 10
      tclCommands/TclCommandSkew.py
  51. 5 3
      tclCommands/TclCommandSubtractPoly.py
  52. 3 2
      tclCommands/TclCommandSubtractRectangle.py
  53. 2 2
      tclCommands/TclCommandWriteGCode.py

+ 16 - 7
FlatCAMApp.py

@@ -1033,7 +1033,7 @@ class App(QtCore.QObject):
                                           'Toolchange_manual, Users, all, angle_x, angle_y, axis, auto, axisoffset, '
                                           'Toolchange_manual, Users, all, angle_x, angle_y, axis, auto, axisoffset, '
                                           'box, center_x, center_y, columns, combine, connect, contour, default, '
                                           'box, center_x, center_y, columns, combine, connect, contour, default, '
                                           'depthperpass, dia, diatol, dist, drilled_dias, drillz, dwelltime, '
                                           'depthperpass, dia, diatol, dist, drilled_dias, drillz, dwelltime, '
-                                          'extracut_length, '
+                                          'extracut_length, f, '
                                           'feedrate_z, grbl_11, GRBL_laser, gridoffsety, gridx, gridy, has_offset, '
                                           'feedrate_z, grbl_11, GRBL_laser, gridoffsety, gridx, gridy, has_offset, '
                                           'holes, hpgl, iso_type, line_xyz, margin, marlin, method, milled_dias, '
                                           'holes, hpgl, iso_type, line_xyz, margin, marlin, method, milled_dias, '
                                           'minoffset, name, offset, opt_type, order, outname, overlap, '
                                           'minoffset, name, offset, opt_type, order, outname, overlap, '
@@ -2305,7 +2305,8 @@ class App(QtCore.QObject):
         # #####################################################################################
         # #####################################################################################
         self.tcl_commands_list = ['add_circle', 'add_poly', 'add_polygon', 'add_polyline', 'add_rectangle',
         self.tcl_commands_list = ['add_circle', 'add_poly', 'add_polygon', 'add_polyline', 'add_rectangle',
                                   'aligndrill', 'aligndrillgrid', 'bbox', 'bounding_box', 'clear', 'cncjob', 'cutout',
                                   'aligndrill', 'aligndrillgrid', 'bbox', 'bounding_box', 'clear', 'cncjob', 'cutout',
-                                  'delete', 'drillcncjob', 'export_dxf', 'edxf', 'export_excellon', 'ee', 'export_exc',
+                                  'del', 'delete', 'drillcncjob', 'export_dxf', 'edxf', 'export_excellon', 'ee',
+                                  'export_exc',
                                   'export_gcode', 'export_gerber', 'egr', 'export_svg', 'ext', 'exteriors', 'follow',
                                   'export_gcode', 'export_gerber', 'egr', 'export_svg', 'ext', 'exteriors', 'follow',
                                   'geo_union', 'geocutout', 'get_names', 'get_sys', 'getsys', 'help', 'import_svg',
                                   'geo_union', 'geocutout', 'get_names', 'get_sys', 'getsys', 'help', 'import_svg',
                                   'interiors', 'isolate', 'join_excellon', 'join_excellons', 'join_geometries',
                                   'interiors', 'isolate', 'join_excellon', 'join_excellons', 'join_geometries',
@@ -2326,7 +2327,7 @@ class App(QtCore.QObject):
                                  'axisoffset',
                                  'axisoffset',
                                  'box', 'center_x', 'center_y', 'columns', 'combine', 'connect', 'contour', 'default',
                                  'box', 'center_x', 'center_y', 'columns', 'combine', 'connect', 'contour', 'default',
                                  'depthperpass', 'dia', 'diatol', 'dist', 'drilled_dias', 'drillz',
                                  'depthperpass', 'dia', 'diatol', 'dist', 'drilled_dias', 'drillz',
-                                 'dwelltime', 'extracut_length',
+                                 'dwelltime', 'extracut_length', 'f',
                                  'feedrate_z', 'grbl_11', 'GRBL_laser', 'gridoffsety', 'gridx', 'gridy',
                                  'feedrate_z', 'grbl_11', 'GRBL_laser', 'gridoffsety', 'gridx', 'gridy',
                                  'has_offset', 'holes', 'hpgl', 'iso_type', 'line_xyz', 'margin', 'marlin', 'method',
                                  'has_offset', 'holes', 'hpgl', 'iso_type', 'line_xyz', 'margin', 'marlin', 'method',
                                  'milled_dias', 'minoffset', 'name', 'offset', 'opt_type', 'order',
                                  'milled_dias', 'minoffset', 'name', 'offset', 'opt_type', 'order',
@@ -7201,10 +7202,11 @@ class App(QtCore.QObject):
     # Hovering over Selected tab, if the selected tab is a Geometry it will delete tools in tool table. But even if
     # Hovering over Selected tab, if the selected tab is a Geometry it will delete tools in tool table. But even if
     # there is a Selected tab in focus with a Geometry inside, if you hover over canvas it will delete an object.
     # there is a Selected tab in focus with a Geometry inside, if you hover over canvas it will delete an object.
     # Complicated, I know :)
     # Complicated, I know :)
-    def on_delete(self):
+    def on_delete(self, force_deletion=False):
         """
         """
         Delete the currently selected FlatCAMObjs.
         Delete the currently selected FlatCAMObjs.
 
 
+        :param force_deletion:  used by Tcl command
         :return: None
         :return: None
         """
         """
         self.report_usage("on_delete()")
         self.report_usage("on_delete()")
@@ -7216,7 +7218,7 @@ class App(QtCore.QObject):
         # a geometry object before we update it.
         # a geometry object before we update it.
         if self.geo_editor.editor_active is False and self.exc_editor.editor_active is False \
         if self.geo_editor.editor_active is False and self.exc_editor.editor_active is False \
                 and self.grb_editor.editor_active is False:
                 and self.grb_editor.editor_active is False:
-            if self.defaults["global_delete_confirmation"] is True:
+            if self.defaults["global_delete_confirmation"] is True and force_deletion is False:
                 msgbox = QtWidgets.QMessageBox()
                 msgbox = QtWidgets.QMessageBox()
                 msgbox.setWindowTitle(_("Delete objects"))
                 msgbox.setWindowTitle(_("Delete objects"))
                 msgbox.setWindowIcon(QtGui.QIcon(self.resource_location + '/deleteshape32.png'))
                 msgbox.setWindowIcon(QtGui.QIcon(self.resource_location + '/deleteshape32.png'))
@@ -7230,7 +7232,10 @@ class App(QtCore.QObject):
                 msgbox.exec_()
                 msgbox.exec_()
                 response = msgbox.clickedButton()
                 response = msgbox.clickedButton()
 
 
-            if response == bt_ok or self.defaults["global_delete_confirmation"] is False:
+            if self.defaults["global_delete_confirmation"] is False or force_deletion is True:
+                response = bt_ok
+
+            if response == bt_ok:
                 if self.collection.get_active():
                 if self.collection.get_active():
                     self.log.debug("App.on_delete()")
                     self.log.debug("App.on_delete()")
 
 
@@ -9539,6 +9544,7 @@ class App(QtCore.QObject):
         File menu callback for opening a Gerber.
         File menu callback for opening a Gerber.
 
 
         :param signal: required because clicking the entry will generate a checked signal which needs a container
         :param signal: required because clicking the entry will generate a checked signal which needs a container
+        :param name:
         :return: None
         :return: None
         """
         """
 
 
@@ -9585,6 +9591,7 @@ class App(QtCore.QObject):
         File menu callback for opening an Excellon file.
         File menu callback for opening an Excellon file.
 
 
         :param signal: required because clicking the entry will generate a checked signal which needs a container
         :param signal: required because clicking the entry will generate a checked signal which needs a container
+        :param name:
         :return: None
         :return: None
         """
         """
 
 
@@ -9619,10 +9626,12 @@ class App(QtCore.QObject):
 
 
     def on_fileopengcode(self, signal: bool = None, name=None):
     def on_fileopengcode(self, signal: bool = None, name=None):
         """
         """
+
         File menu call back for opening gcode.
         File menu call back for opening gcode.
 
 
         :param signal: required because clicking the entry will generate a checked signal which needs a container
         :param signal: required because clicking the entry will generate a checked signal which needs a container
-        :return: None
+        :param name:
+        :return:
         """
         """
 
 
         self.report_usage("on_fileopengcode")
         self.report_usage("on_fileopengcode")

+ 13 - 0
README.md

@@ -9,6 +9,19 @@ CAD program, and create G-Code for Isolation routing.
 
 
 =================================================
 =================================================
 
 
+9.4.2020 
+
+- fixed the Tcl Command Delete to have an argument -f that will force deletion evading the popup (if the popup is enabled). The sme command without a name now will delete all objects
+- fixed the Tcl Command JoinExcellons
+- fixed the Tcl Command JoinGeometry
+- fixed the Tcl Command Mirror
+- updated the Tcl Command Mirror to use a (X,Y) origin parameter. Works if the -box parameter is not used.
+- updated the Tcl Command Offset. Now it can use only -x or -y parameter no longer is mandatory to have both. The one that is not present will be assumed 0.0
+- updated the Tcl Command Panelize. The -rows and -columns parameters are no longer both required. If one is not present then it is assumed to be zero.
+- updated the Tcl Command Scale. THe -origin parameter can now be a tuple of (x,y) coordinates.
+- updated the Tcl Command Skew. Now it can use only -x or -y parameter no longer is mandatory to have both. The one that is not present will be assumed 0.0
+- updated the help for all the Tcl Commands
+
 6.04.2020 
 6.04.2020 
 
 
 - added key shortcuts (arrow up/down) that will select the objects in the Project tab if the focus is in that tab
 - added key shortcuts (arrow up/down) that will select the objects in the Project tab if the focus is in that tab

+ 1 - 1
tclCommands/TclCommandAddCircle.py

@@ -38,7 +38,7 @@ class TclCommandAddCircle(TclCommand):
             ('center_y', 'Y coordinates of the center of the circle.'),
             ('center_y', 'Y coordinates of the center of the circle.'),
             ('radius', 'Radius of the circle.')
             ('radius', 'Radius of the circle.')
         ]),
         ]),
-        'examples': []
+        'examples': ['add_circle geo_name 1.0 2.0 3']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 1 - 1
tclCommands/TclCommandAddRectangle.py

@@ -37,7 +37,7 @@ class TclCommandAddRectangle(TclCommandSignaled):
             ('x0 y0', 'Bottom left corner coordinates.'),
             ('x0 y0', 'Bottom left corner coordinates.'),
             ('x1 y1', 'Top right corner coordinates.')
             ('x1 y1', 'Top right corner coordinates.')
         ]),
         ]),
-        'examples': []
+        'examples': ["add_rectangle geo_name 0 0 10 10"]
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 1 - 1
tclCommands/TclCommandAlignDrill.py

@@ -41,7 +41,7 @@ class TclCommandAlignDrill(TclCommandSignaled):
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
-        'main': "Create excellon with drills for aligment.",
+        'main': "Create an Excellon object with drills for alignment.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
             ('name', 'Name of the object (Gerber or Excellon) to mirror.'),
             ('name', 'Name of the object (Gerber or Excellon) to mirror.'),
             ('dia', 'Tool diameter'),
             ('dia', 'Tool diameter'),

+ 1 - 1
tclCommands/TclCommandAlignDrillGrid.py

@@ -39,7 +39,7 @@ class TclCommandAlignDrillGrid(TclCommandSignaled):
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
-        'main': "Create excellon with drills for aligment grid.",
+        'main': "Create an Excellon object with drills for alignment arranged in a grid.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
             ('outname', 'Name of the object to create.'),
             ('outname', 'Name of the object to create.'),
             ('dia', 'Tool diameter.'),
             ('dia', 'Tool diameter.'),

+ 1 - 1
tclCommands/TclCommandBbox.py

@@ -38,7 +38,7 @@ class TclCommandBbox(TclCommand):
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
-        'main': "Creates a Geometry object that surrounds the object.",
+        'main': "Creates a rectangular Geometry object that surrounds the object.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
             ('name', 'Object name for which to create bounding box. String'),
             ('name', 'Object name for which to create bounding box. String'),
             ('outname', 'Name of the resulting Geometry object. String.'),
             ('outname', 'Name of the resulting Geometry object. String.'),

+ 1 - 0
tclCommands/TclCommandBounds.py

@@ -12,6 +12,7 @@ if '_' not in builtins.__dict__:
 
 
 log = logging.getLogger('base')
 log = logging.getLogger('base')
 
 
+
 class TclCommandBounds(TclCommand):
 class TclCommandBounds(TclCommand):
     """
     """
     Tcl shell command to return the bounds values for a supplied list of objects (identified by their names).
     Tcl shell command to return the bounds values for a supplied list of objects (identified by their names).

+ 1 - 1
tclCommands/TclCommandClearShell.py

@@ -38,7 +38,7 @@ class TclCommandClearShell(TclCommand):
         'main': "Clear the text in the Tcl Shell browser.",
         'main': "Clear the text in the Tcl Shell browser.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
         ]),
         ]),
-        'examples': []
+        'examples': ['clear']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 1 - 1
tclCommands/TclCommandCutout.py

@@ -48,7 +48,7 @@ class TclCommandCutout(TclCommand):
             ('gapsize', 'Size of gap. Default = 0.1'),
             ('gapsize', 'Size of gap. Default = 0.1'),
             ('gaps', "Type of gaps. Can be: 'tb' = top-bottom, 'lr' = left-right and '4' = one each side. Default = 4"),
             ('gaps', "Type of gaps. Can be: 'tb' = top-bottom, 'lr' = left-right and '4' = one each side. Default = 4"),
         ]),
         ]),
-        'examples': []
+        'examples': ['cutout new_geo -dia 1.2 -margin 0.1 -gapsize 1 -gaps "tb" ']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 39 - 13
tclCommands/TclCommandDelete.py

@@ -12,7 +12,7 @@ class TclCommandDelete(TclCommand):
     """
     """
 
 
     # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
     # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
-    aliases = ['delete']
+    aliases = ['delete', 'del']
 
 
     # Dictionary of types from Tcl command, needs to be ordered
     # Dictionary of types from Tcl command, needs to be ordered
     arg_names = collections.OrderedDict([
     arg_names = collections.OrderedDict([
@@ -21,19 +21,23 @@ class TclCommandDelete(TclCommand):
 
 
     # Dictionary of types from Tcl command, needs to be ordered , this  is  for options  like -optionname value
     # Dictionary of types from Tcl command, needs to be ordered , this  is  for options  like -optionname value
     option_types = collections.OrderedDict([
     option_types = collections.OrderedDict([
-
+        ('f', bool)
     ])
     ])
 
 
     # array of mandatory options for current Tcl command: required = {'name','outname'}
     # array of mandatory options for current Tcl command: required = {'name','outname'}
-    required = ['name']
+    required = []
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
-        'main': 'Deletes the given object.',
+        'main': 'Deletes the given object. If no name is given will delete all objects.',
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
             ('name', 'Name of the Object.'),
             ('name', 'Name of the Object.'),
+            ('f', 'Use this parameter to force deletion.')
         ]),
         ]),
-        'examples': []
+        'examples': ['del new_geo -f True\n'
+                     'delete new_geo -f 1\n'
+                     'del new_geo -f\n'
+                     'del new_geo']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):
@@ -43,13 +47,35 @@ class TclCommandDelete(TclCommand):
         :param unnamed_args:
         :param unnamed_args:
         :return:
         :return:
         """
         """
-
-        obj_name = args['name']
+        obj_name = None
 
 
         try:
         try:
-            # deselect all  to avoid delete selected object when run  delete  from  shell
-            self.app.collection.set_all_inactive()
-            self.app.collection.set_active(str(obj_name))
-            self.app.on_delete()  # Todo: This is an event handler for the GUI... bad?
-        except Exception as e:
-            return "Command failed: %s" % str(e)
+            obj_name = args['name']
+            delete_all = False
+        except KeyError:
+            delete_all = True
+
+        is_forced = False
+        if 'f' in args:
+            try:
+                if args['f'] is None:
+                    is_forced = True
+                else:
+                    is_forced = True if eval(str(args['f'])) else False
+            except KeyError:
+                is_forced = True
+
+        if delete_all is False:
+            try:
+                # deselect all  to avoid delete selected object when run  delete  from  shell
+                self.app.collection.set_all_inactive()
+                self.app.collection.set_active(str(obj_name))
+                self.app.on_delete(force_deletion=is_forced)
+            except Exception as e:
+                return "Command failed: %s" % str(e)
+        else:
+            try:
+                self.app.collection.set_all_active()
+                self.app.on_delete(force_deletion=is_forced)
+            except Exception as e:
+                return "Command failed: %s" % str(e)

+ 2 - 2
tclCommands/TclCommandExportGcode.py

@@ -48,11 +48,11 @@ class TclCommandExportGcode(TclCommandSignaled):
     help = {
     help = {
         'main': "Export gcode into console output.",
         'main': "Export gcode into console output.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Name of the source Geometry object.'),
+            ('name', 'Name of the source Geometry object. Required.'),
             ('preamble', 'Prepend GCODE.'),
             ('preamble', 'Prepend GCODE.'),
             ('postamble', 'Append GCODE.')
             ('postamble', 'Append GCODE.')
         ]),
         ]),
-        'examples': []
+        'examples': ['export_gcode geo_name -preamble "G01 X10 Y10" -postamble "G00 X20 Y20\nM04"']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 1 - 1
tclCommands/TclCommandExportGerber.py

@@ -31,7 +31,7 @@ class TclCommandExportGerber(TclCommand):
     help = {
     help = {
         'main': "Export a Gerber Object as a Gerber File.",
         'main': "Export a Gerber Object as a Gerber File.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('obj_name', 'Name of the object to export.'),
+            ('obj_name', 'Name of the object to export. Required.'),
             ('filename', 'Path to the file to export.')
             ('filename', 'Path to the file to export.')
         ]),
         ]),
         'examples': ['export_gerber my_gerber path/my_file.gbr']
         'examples': ['export_gerber my_gerber path/my_file.gbr']

+ 1 - 1
tclCommands/TclCommandExportSVG.py

@@ -33,7 +33,7 @@ class TclCommandExportSVG(TclCommand):
     help = {
     help = {
         'main': "Export a Geometry Object as a SVG File.",
         'main': "Export a Geometry Object as a SVG File.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Name of the object export.'),
+            ('name', 'Name of the object export. Required.'),
             ('filename', 'Path to the file to export.'),
             ('filename', 'Path to the file to export.'),
             ('scale_factor', 'Multiplication factor used for scaling line widths during export.')
             ('scale_factor', 'Multiplication factor used for scaling line widths during export.')
         ]),
         ]),

+ 2 - 2
tclCommands/TclCommandExteriors.py

@@ -29,10 +29,10 @@ class TclCommandExteriors(TclCommandSignaled):
     help = {
     help = {
         'main': "Get exteriors of polygons.",
         'main': "Get exteriors of polygons.",
         'args':  collections.OrderedDict([
         'args':  collections.OrderedDict([
-            ('name', 'Name of the source Geometry object.'),
+            ('name', 'Name of the source Geometry object. Required.'),
             ('outname', 'Name of the resulting Geometry object.')
             ('outname', 'Name of the resulting Geometry object.')
         ]),
         ]),
-        'examples': []
+        'examples': ['ext geo_source_name -outname "final_geo"']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 2 - 2
tclCommands/TclCommandFollow.py

@@ -29,10 +29,10 @@ class TclCommandFollow(TclCommandSignaled):
     help = {
     help = {
         'main': "Creates a geometry object following gerber paths.",
         'main': "Creates a geometry object following gerber paths.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Object name to follow.'),
+            ('name', 'Object name to follow. Required.'),
             ('outname', 'Name of the resulting Geometry object.')
             ('outname', 'Name of the resulting Geometry object.')
         ]),
         ]),
-        'examples': ['follow name -outname name_follow']
+        'examples': ['follow name -outname "name_follow"']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 2 - 2
tclCommands/TclCommandGeoCutout.py

@@ -45,14 +45,14 @@ class TclCommandGeoCutout(TclCommandSignaled):
     help = {
     help = {
         'main': 'Creates board cutout from an object (Gerber or Geometry) of any shape',
         'main': 'Creates board cutout from an object (Gerber or Geometry) of any shape',
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Name of the object.'),
+            ('name', 'Name of the object to be cutout. Required'),
             ('dia', 'Tool diameter.'),
             ('dia', 'Tool diameter.'),
             ('margin', 'Margin over bounds.'),
             ('margin', 'Margin over bounds.'),
             ('gapsize', 'size of gap.'),
             ('gapsize', 'size of gap.'),
             ('gaps', "type of gaps. Can be: 'tb' = top-bottom, 'lr' = left-right, '2tb' = 2top-2bottom, "
             ('gaps', "type of gaps. Can be: 'tb' = top-bottom, 'lr' = left-right, '2tb' = 2top-2bottom, "
                      "'2lr' = 2left-2right, '4' = 4 cuts, '8' = 8 cuts")
                      "'2lr' = 2left-2right, '4' = 4 cuts, '8' = 8 cuts")
         ]),
         ]),
-        'examples': ["      #isolate margin for example from fritzing arduino shield or any svg etc\n" +
+        'examples': ["      #isolate margin for example from Fritzing arduino shield or any svg etc\n" +
                      "      isolate BCu_margin -dia 3 -overlap 1\n" +
                      "      isolate BCu_margin -dia 3 -overlap 1\n" +
                      "\n" +
                      "\n" +
                      "      #create exteriors from isolated object\n" +
                      "      #create exteriors from isolated object\n" +

+ 3 - 3
tclCommands/TclCommandGeoUnion.py

@@ -32,12 +32,12 @@ class TclCommandGeoUnion(TclCommand):
     help = {
     help = {
         'main': ('Runs a union operation (addition) on the components '
         'main': ('Runs a union operation (addition) on the components '
                  'of the geometry object. For example, if it contains '
                  'of the geometry object. For example, if it contains '
-                 '2 intersecting polygons, this opperation adds them into'
+                 '2 intersecting polygons, this operation adds them into'
                  'a single larger polygon.'),
                  'a single larger polygon.'),
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Name of the Geometry Object.'),
+            ('name', 'Name of the Geometry Object that contain the components to be joined. Required.'),
         ]),
         ]),
-        'examples': []
+        'examples': ['geo_union target_geo']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 2 - 2
tclCommands/TclCommandGetNames.py

@@ -29,11 +29,11 @@ class TclCommandGetNames(TclCommand):
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
-        'main': 'Lists the names of objects in the project.',
+        'main': 'Lists the names of objects in the project. It returns a string with names separated by \n',
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
 
 
         ]),
         ]),
-        'examples': []
+        'examples': ['get_names']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 2 - 2
tclCommands/TclCommandGetSys.py

@@ -36,9 +36,9 @@ class TclCommandGetSys(TclCommand):
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
-        'main': "Returns the value of the system variable.",
+        'main': "Returns the value of the targeted system variable.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Name of the system variable.'),
+            ('name', 'Name of the system variable. Required.'),
         ]),
         ]),
         'examples': ['get_sys excellon_zeros']
         'examples': ['get_sys excellon_zeros']
     }
     }

+ 2 - 2
tclCommands/TclCommandImportSvg.py

@@ -30,11 +30,11 @@ class TclCommandImportSvg(TclCommandSignaled):
     help = {
     help = {
         'main': "Import an SVG file as a Geometry Object..",
         'main': "Import an SVG file as a Geometry Object..",
         'args':  collections.OrderedDict([
         'args':  collections.OrderedDict([
-            ('filename', 'Path to file to open.'),
+            ('filename', 'Absolute path to file to open. Required.'),
             ('type', 'Import as gerber or geometry(default).'),
             ('type', 'Import as gerber or geometry(default).'),
             ('outname', 'Name of the resulting Geometry object.')
             ('outname', 'Name of the resulting Geometry object.')
         ]),
         ]),
-        'examples': []
+        'examples': ['import_svg D:\\my_beautiful_svg_file.SVG']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 3 - 3
tclCommands/TclCommandInteriors.py

@@ -27,12 +27,12 @@ class TclCommandInteriors(TclCommandSignaled):
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
-        'main': "Get interiors of polygons.",
+        'main': "Return the interiors of polygons as a list of Shapely geometry elements.",
         'args':  collections.OrderedDict([
         'args':  collections.OrderedDict([
-            ('name', 'Name of the source Geometry object.'),
+            ('name', 'Name of the source Geometry object. Required.'),
             ('outname', 'Name of the resulting Geometry object.')
             ('outname', 'Name of the resulting Geometry object.')
         ]),
         ]),
-        'examples': []
+        'examples': ['interiors my_geo_name -outname "outputed_geo"']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 8 - 4
tclCommands/TclCommandIsolate.py

@@ -29,7 +29,7 @@ class TclCommandIsolate(TclCommandSignaled):
         ('dia', float),
         ('dia', float),
         ('passes', int),
         ('passes', int),
         ('overlap', float),
         ('overlap', float),
-        ('combine', int),
+        ('combine', bool),
         ('outname', str),
         ('outname', str),
         ('follow', str),
         ('follow', str),
         ('iso_type', int)
         ('iso_type', int)
@@ -43,18 +43,18 @@ class TclCommandIsolate(TclCommandSignaled):
     help = {
     help = {
         'main': "Creates isolation routing geometry for the given Gerber.",
         'main': "Creates isolation routing geometry for the given Gerber.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Name of the source object.'),
+            ('name', 'Name of the source object. Required.'),
             ('dia', 'Tool diameter.'),
             ('dia', 'Tool diameter.'),
             ('passes', 'Passes of tool width.'),
             ('passes', 'Passes of tool width.'),
             ('overlap', 'Percentage of tool diameter to overlap current pass over previous pass. Float [0, 99.9999]\n'
             ('overlap', 'Percentage of tool diameter to overlap current pass over previous pass. Float [0, 99.9999]\n'
                         'E.g: for a 25% from tool diameter overlap use -overlap 25'),
                         'E.g: for a 25% from tool diameter overlap use -overlap 25'),
-            ('combine', 'Combine all passes into one geometry.'),
+            ('combine', 'Combine all passes into one geometry. Can be True or False, 1 or 0'),
             ('outname', 'Name of the resulting Geometry object.'),
             ('outname', 'Name of the resulting Geometry object.'),
             ('follow', 'Create a Geometry that follows the Gerber path.'),
             ('follow', 'Create a Geometry that follows the Gerber path.'),
             ('iso_type', 'A value of 0 will isolate exteriors, a value of 1 will isolate interiors '
             ('iso_type', 'A value of 0 will isolate exteriors, a value of 1 will isolate interiors '
                          'and a value of 2 will do full isolation.')
                          'and a value of 2 will do full isolation.')
         ]),
         ]),
-        'examples': []
+        'examples': ['isolate my_geo -dia 0.1 -passes 2 -overlap 10 -combine True -iso_type 2 -outname out_geo']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):
@@ -80,6 +80,10 @@ class TclCommandIsolate(TclCommandSignaled):
         if 'follow' not in args:
         if 'follow' not in args:
             args['follow'] = None
             args['follow'] = None
 
 
+        # evaluate this parameter so True, False, 0 and 1 works
+        if "combine" in args:
+            args['combine'] = eval(args['combine'])
+
         obj = self.app.collection.get_by_name(name)
         obj = self.app.collection.get_by_name(name)
         if obj is None:
         if obj is None:
             self.raise_tcl_error("Object not found: %s" % name)
             self.raise_tcl_error("Object not found: %s" % name)

+ 11 - 10
tclCommands/TclCommandJoinExcellon.py

@@ -22,7 +22,6 @@ class TclCommandJoinExcellon(TclCommand):
 
 
     # Dictionary of types from Tcl command, needs to be ordered , this  is  for options  like -optionname value
     # Dictionary of types from Tcl command, needs to be ordered , this  is  for options  like -optionname value
     option_types = collections.OrderedDict([
     option_types = collections.OrderedDict([
-
     ])
     ])
 
 
     # array of mandatory options for current Tcl command: required = {'name','outname'}
     # array of mandatory options for current Tcl command: required = {'name','outname'}
@@ -30,14 +29,14 @@ class TclCommandJoinExcellon(TclCommand):
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
-        'main': "Runs a merge operation (join) on the Excellon objects.",
+        'main': "Runs a merge operation (join) on the Excellon objects.\n"
+                "The names of the Excellon objects to be merged will be entered after the outname,\n"
+                "separated by spaces. See the example bellow.\n"
+                "WARNING: if the name of an Excellon objects has spaces, enclose the name with quotes.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Name of the new Excellon Object.'),
-            ('obj_name_0', 'Name of the first object'),
-            ('obj_name_1', 'Name of the second object.'),
-            ('obj_name_2...', 'Additional object names')
+            ('outname', 'Name of the new Excellon Object made by joining of other Excellon objects. Required'),
         ]),
         ]),
-        'examples': []
+        'examples': ['join_excellons merged_new_excellon exc_name_1 "exc name_2"']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):
@@ -48,7 +47,7 @@ class TclCommandJoinExcellon(TclCommand):
         :return:
         :return:
         """
         """
 
 
-        outname = args['name']
+        outname = args['outname']
         obj_names = unnamed_args
         obj_names = unnamed_args
 
 
         objs = []
         objs = []
@@ -60,7 +59,9 @@ class TclCommandJoinExcellon(TclCommand):
                 objs.append(obj)
                 objs.append(obj)
 
 
         def initialize(obj_, app):
         def initialize(obj_, app):
-            FlatCAMExcellon.merge(objs, obj_)
+            FlatCAMExcellon.merge(self, objs, obj_)
 
 
-        if objs is not None:
+        if objs:
             self.app.new_object("excellon", outname, initialize, plot=False)
             self.app.new_object("excellon", outname, initialize, plot=False)
+        else:
+            return "No Excellon objects to be joined."

+ 10 - 8
tclCommands/TclCommandJoinGeometry.py

@@ -30,14 +30,14 @@ class TclCommandJoinGeometry(TclCommand):
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
-        'main': "Runs a merge operation (join) on the Excellon objects.",
+        'main': "Runs a merge operation (join) on the Geometry objects.\n"
+                "The names of the Geometry objects to be merged will be entered after the outname,\n"
+                "separated by spaces. See the example bellow.\n"
+                "WARNING: if the name of an Geometry objects has spaces, enclose the name with quotes.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('outname', 'Name of the new Geometry Object.'),
-            ('obj_name_0', 'Name of the first object'),
-            ('obj_name_1', 'Name of the second object.'),
-            ('obj_name_2...', 'Additional object names')
+            ('outname', 'Name of the new Geometry Object made by joining of other Geometry objects. Required'),
         ]),
         ]),
-        'examples': []
+        'examples': ['join_geometry merged_new_geo geo_name_1 "geo name_2"']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):
@@ -60,7 +60,9 @@ class TclCommandJoinGeometry(TclCommand):
                 objs.append(obj)
                 objs.append(obj)
 
 
         def initialize(obj_, app):
         def initialize(obj_, app):
-            FlatCAMGeometry.merge(objs, obj_)
+            FlatCAMGeometry.merge(self, objs, obj_)
 
 
-        if objs is not None:
+        if objs:
             self.app.new_object("geometry", outname, initialize, plot=False)
             self.app.new_object("geometry", outname, initialize, plot=False)
+        else:
+            return "No Geometry objects to be joined."

+ 1 - 1
tclCommands/TclCommandListSys.py

@@ -40,7 +40,7 @@ class TclCommandListSys(TclCommand):
                 "of the system variable.\n"
                 "of the system variable.\n"
                 "In that case it will list only the system variables that starts with that string.\n"
                 "In that case it will list only the system variables that starts with that string.\n"
                 "Main categories start with: gerber or excellon or geometry or cncjob or global.\n"
                 "Main categories start with: gerber or excellon or geometry or cncjob or global.\n"
-                "Note: Use get_sys TclCommand to get the value and set_sys TclCommand to set it.\n",
+                "Note: Use 'get_sys system variable' to get the value and 'set_sys system variable value' to set it.\n",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
         ]),
         ]),
         'examples': ['list_sys',
         'examples': ['list_sys',

+ 9 - 7
tclCommands/TclCommandMillDrills.py

@@ -34,7 +34,7 @@ class TclCommandMillDrills(TclCommandSignaled):
         ('milled_dias', str),
         ('milled_dias', str),
         ('outname', str),
         ('outname', str),
         ('tooldia', float),
         ('tooldia', float),
-        ('use_threads', bool),
+        ('use_thread', bool),
         ('diatol', float)
         ('diatol', float)
     ])
     ])
 
 
@@ -45,10 +45,13 @@ class TclCommandMillDrills(TclCommandSignaled):
     help = {
     help = {
         'main': "Create Geometry Object for milling drill holes from Excellon.",
         'main': "Create Geometry Object for milling drill holes from Excellon.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Name of the Excellon Object.'),
-            ('milled_dias', 'Comma separated tool diameters of the drills to be milled (example: 0.6, 1.0 or 3.125).'),
+            ('name', 'Name of the Excellon Object. Required.'),
+            ('milled_dias', 'Comma separated tool diameters of the drills to be milled (example: 0.6, 1.0 or 3.125).\n'
+                            'Exception: if you enter "all" then the drills for all tools will be milled.\n'
+                            'WARNING: no spaces are allowed in the list of tools.\n'
+                            'As a precaution you can enclose them with quotes.'),
             ('tooldia', 'Diameter of the milling tool (example: 0.1).'),
             ('tooldia', 'Diameter of the milling tool (example: 0.1).'),
-            ('outname', 'Name of object to create.'),
+            ('outname', 'Name of object to be created holding the milled geometries.'),
             ('use_thread', 'If to use multithreading: True or False.'),
             ('use_thread', 'If to use multithreading: True or False.'),
             ('diatol', 'Tolerance. Percentange (0.0 ... 100.0) within which dias in milled_dias will be judged to be '
             ('diatol', 'Tolerance. Percentange (0.0 ... 100.0) within which dias in milled_dias will be judged to be '
                        'the same as the ones in the tools from the Excellon object. E.g: if in milled_dias we have a '
                        'the same as the ones in the tools from the Excellon object. E.g: if in milled_dias we have a '
@@ -56,7 +59,8 @@ class TclCommandMillDrills(TclCommandSignaled):
                        'diatol = 5.0 then the drills with the dia = (0.95 ... 1.05) '
                        'diatol = 5.0 then the drills with the dia = (0.95 ... 1.05) '
                        'in Excellon will be processed. Float number.')
                        'in Excellon will be processed. Float number.')
         ]),
         ]),
-        'examples': ['milldrills mydrills', 'milld my_excellon.drl']
+        'examples': ['milldrills mydrills -milled_dias "0.6,0.8" -tooldia 0.1 -diatol 10 -outname milled_holes',
+                     'milld my_excellon.drl']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):
@@ -85,8 +89,6 @@ class TclCommandMillDrills(TclCommandSignaled):
         if not obj.drills:
         if not obj.drills:
             self.raise_tcl_error("The Excellon object has no drills: %s" % name)
             self.raise_tcl_error("The Excellon object has no drills: %s" % name)
 
 
-        units = self.app.defaults['units'].upper()
-
         try:
         try:
             if 'milled_dias' in args and args['milled_dias'] != 'all':
             if 'milled_dias' in args and args['milled_dias'] != 'all':
                 diameters = [x.strip() for x in args['milled_dias'].split(",") if x != '']
                 diameters = [x.strip() for x in args['milled_dias'].split(",") if x != '']

+ 9 - 5
tclCommands/TclCommandMillSlots.py

@@ -34,7 +34,7 @@ class TclCommandMillSlots(TclCommandSignaled):
         ('milled_dias', str),
         ('milled_dias', str),
         ('outname', str),
         ('outname', str),
         ('tooldia', float),
         ('tooldia', float),
-        ('use_threads', bool),
+        ('use_thread', bool),
         ('diatol', float)
         ('diatol', float)
     ])
     ])
 
 
@@ -45,10 +45,13 @@ class TclCommandMillSlots(TclCommandSignaled):
     help = {
     help = {
         'main': "Create Geometry Object for milling slot holes from Excellon.",
         'main': "Create Geometry Object for milling slot holes from Excellon.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Name of the Excellon Object.'),
-            ('milled_dias', 'Comma separated tool diameters of the slots to be milled (example: 0.6, 1.0 or 3.125).'),
+            ('name', 'Name of the Excellon Object. Required.'),
+            ('milled_dias', 'Comma separated tool diameters of the slots to be milled (example: 0.6, 1.0 or 3.125).\n'
+                            'Exception: if you enter "all" then the slots for all tools will be milled.\n'
+                            'WARNING: no spaces are allowed in the list of tools.\n'
+                            'As a precaution you can enclose them with quotes.'),
             ('tooldia', 'Diameter of the milling tool (example: 0.1).'),
             ('tooldia', 'Diameter of the milling tool (example: 0.1).'),
-            ('outname', 'Name of object to create.'),
+            ('outname', 'Name of object to be created holding the milled geometries.'),
             ('use_thread', 'If to use multithreading: True or False.'),
             ('use_thread', 'If to use multithreading: True or False.'),
             ('diatol', 'Tolerance. Percentange (0.0 ... 100.0) within which dias in milled_dias will be judged to be '
             ('diatol', 'Tolerance. Percentange (0.0 ... 100.0) within which dias in milled_dias will be judged to be '
                        'the same as the ones in the tools from the Excellon object. E.g: if in milled_dias we have a '
                        'the same as the ones in the tools from the Excellon object. E.g: if in milled_dias we have a '
@@ -56,7 +59,8 @@ class TclCommandMillSlots(TclCommandSignaled):
                        'diatol = 5.0 then the slots with the dia = (0.95 ... 1.05) '
                        'diatol = 5.0 then the slots with the dia = (0.95 ... 1.05) '
                        'in Excellon will be processed. Float number.')
                        'in Excellon will be processed. Float number.')
         ]),
         ]),
-        'examples': ['millslots mydrills', 'mills my_excellon.drl']
+        'examples': ['millslots myslots -milled_dias "0.6,0.8" -tooldia 0.1 -diatol 10 -outname milled_slots',
+                     'mills my_excellon.drl']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 26 - 17
tclCommands/TclCommandMirror.py

@@ -24,22 +24,25 @@ class TclCommandMirror(TclCommandSignaled):
     option_types = collections.OrderedDict([
     option_types = collections.OrderedDict([
         ('axis', str),
         ('axis', str),
         ('box', str),
         ('box', str),
-        ('dist', float)
+        ('origin', str)
     ])
     ])
 
 
     # array of mandatory options for current Tcl command: required = {'name','outname'}
     # array of mandatory options for current Tcl command: required = {'name','outname'}
-    required = ['name', 'axis']
+    required = ['name']
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
-        'main': "Opens an Excellon file.",
+        'main': "Will mirror an named object.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Name of the object (Gerber or Excellon) to mirror.'),
-            ('box', 'Name of object which act as box (cutout for example.)'),
+            ('name', 'Name of the object (Gerber, Geometry or Excellon) to be mirrored. Required.'),
             ('axis', 'Mirror axis parallel to the X or Y axis.'),
             ('axis', 'Mirror axis parallel to the X or Y axis.'),
-            ('dist', 'Distance of the mirror axis to the X or Y axis.')
+            ('box', 'Name of object which act as box (cutout for example.)'),
+            ('origin', 'Reference point . It is used only if the box is not used. Format (x,y).\n'
+                       'Comma will separate the X and Y coordinates.\n'
+                       'WARNING: no spaces are allowed. If uncertain enclose the two values inside parenthesis.\n'
+                       'See the example.')
         ]),
         ]),
-        'examples': []
+        'examples': ['mirror obj_name -box box_geo -axis X -origin 3.2,4.7']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):
@@ -69,10 +72,13 @@ class TclCommandMirror(TclCommandSignaled):
             return "ERROR: Only Gerber, Excellon and Geometry objects can be mirrored."
             return "ERROR: Only Gerber, Excellon and Geometry objects can be mirrored."
 
 
         # Axis
         # Axis
-        try:
-            axis = args['axis'].upper()
-        except KeyError:
-            return "ERROR: Specify -axis X or -axis Y"
+        if 'axis' in args:
+            try:
+                axis = args['axis'].upper()
+            except KeyError:
+                axis = 'Y'
+        else:
+            axis = 'Y'
 
 
         # Box
         # Box
         if 'box' in args:
         if 'box' in args:
@@ -91,19 +97,22 @@ class TclCommandMirror(TclCommandSignaled):
 
 
                 obj.mirror(axis, [px, py])
                 obj.mirror(axis, [px, py])
                 obj.plot()
                 obj.plot()
-
+                return
             except Exception as e:
             except Exception as e:
                 return "Operation failed: %s" % str(e)
                 return "Operation failed: %s" % str(e)
 
 
-        else:
+        # Origin
+        if 'origin' in args:
             try:
             try:
-                dist = float(args['dist'])
+                origin_val = eval(args['origin'])
+                x = float(origin_val[0])
+                y = float(origin_val[1])
             except KeyError:
             except KeyError:
-                dist = 0.0
+                x, y = (0, 0)
             except ValueError:
             except ValueError:
-                return "Invalid distance: %s" % args['dist']
+                return "Invalid distance: %s" % str(args['origin'])
 
 
             try:
             try:
-                obj.mirror(axis, [dist, dist])
+                obj.mirror(axis, [x, y])
             except Exception as e:
             except Exception as e:
                 return "Operation failed: %s" % str(e)
                 return "Operation failed: %s" % str(e)

+ 1 - 1
tclCommands/TclCommandNew.py

@@ -24,7 +24,7 @@ class TclCommandNew(TclCommand):
     help = {
     help = {
         'main': "Starts a new project. Clears objects from memory.",
         'main': "Starts a new project. Clears objects from memory.",
         'args': collections.OrderedDict(),
         'args': collections.OrderedDict(),
-        'examples': []
+        'examples': ['new']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 1 - 1
tclCommands/TclCommandNewExcellon.py

@@ -39,7 +39,7 @@ class TclCommandNewExcellon(TclCommandSignaled):
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
             ('name', 'New object name.'),
             ('name', 'New object name.'),
         ]),
         ]),
-        'examples': []
+        'examples': ['new_excellon my_excellon', 'new_excellon']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 3 - 2
tclCommands/TclCommandNewGeometry.py

@@ -28,11 +28,12 @@ class TclCommandNewGeometry(TclCommandSignaled):
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
-        'main': "Creates a new empty geometry object.",
+        'main': "Creates a new empty Geometry object.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
             ('name', 'New object name.'),
             ('name', 'New object name.'),
         ]),
         ]),
-        'examples': []
+        'examples': ['new_geometry\n'
+                     'new_geometry my_new_geo']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 1 - 1
tclCommands/TclCommandNewGerber.py

@@ -39,7 +39,7 @@ class TclCommandNewGerber(TclCommandSignaled):
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
             ('name', 'New object name.'),
             ('name', 'New object name.'),
         ]),
         ]),
-        'examples': []
+        'examples': ['new_gerber', 'new_gerber my_new_gerber_name']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 2 - 2
tclCommands/TclCommandNregions.py

@@ -41,13 +41,13 @@ class TclCommandNregions(TclCommand):
     help = {
     help = {
         'main': "Creates a geometry object with the non-copper regions.",
         'main': "Creates a geometry object with the non-copper regions.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Object name for which to create non-copper regions. String'),
+            ('name', 'Object name for which to create non-copper regions. String. Required.'),
             ('outname', 'Name of the resulting Geometry object. String.'),
             ('outname', 'Name of the resulting Geometry object. String.'),
             ('margin', "Specify the edge of the PCB by drawing a box around all objects with this minimum distance. "
             ('margin', "Specify the edge of the PCB by drawing a box around all objects with this minimum distance. "
                        "Float number."),
                        "Float number."),
             ('rounded', "Resulting geometry will have rounded corners. True or False.")
             ('rounded', "Resulting geometry will have rounded corners. True or False.")
         ]),
         ]),
-        'examples': ['ncr name -outname name_ncr']
+        'examples': ['ncr name -margin 0.1 -rounded True -outname name_ncr']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 15 - 8
tclCommands/TclCommandOffset.py

@@ -23,21 +23,22 @@ class TclCommandOffset(TclCommand):
 
 
     # Dictionary of types from Tcl command, needs to be ordered , this  is  for options  like -optionname value
     # Dictionary of types from Tcl command, needs to be ordered , this  is  for options  like -optionname value
     option_types = collections.OrderedDict([
     option_types = collections.OrderedDict([
-
+        ('x', float),
+        ('y', float)
     ])
     ])
 
 
     # array of mandatory options for current Tcl command: required = {'name','outname'}
     # array of mandatory options for current Tcl command: required = {'name','outname'}
-    required = ['name', 'x', 'y']
+    required = ['name']
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
-        'main': "Changes the position of the object.",
+        'main': "Changes the position of the object on X and/or Y axis.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Name of the object to offset.'),
-            ('x', 'Offset distance in the X axis.'),
-            ('y', 'Offset distance in the Y axis')
+            ('name', 'Name of the object to offset. Required.'),
+            ('x', 'Offset distance in the X axis. If it is not used it will be assumed to be 0.0'),
+            ('y', 'Offset distance in the Y axis. If it is not used it will be assumed to be 0.0')
         ]),
         ]),
-        'examples': ['offset my_geometry 1.2 -0.3']
+        'examples': ['offset my_geometry -x 1.2 -y -0.3', 'offset my_geometry -x 1.0']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):
@@ -49,6 +50,12 @@ class TclCommandOffset(TclCommand):
         """
         """
 
 
         name = args['name']
         name = args['name']
-        x, y = float(args['x']), float(args['y'])
+        off_x = args['x'] if 'x' in args else 0.0
+        off_y = args['y'] if 'y' in args else 0.0
+
+        x, y = float(off_x), float(off_y)
+
+        if (x, y) == (0.0, 0.0):
+            return
 
 
         self.app.collection.get_by_name(name).offset((x, y))
         self.app.collection.get_by_name(name).offset((x, y))

+ 8 - 2
tclCommands/TclCommandOpenExcellon.py

@@ -30,10 +30,13 @@ class TclCommandOpenExcellon(TclCommandSignaled):
     help = {
     help = {
         'main': "Opens an Excellon file.",
         'main': "Opens an Excellon file.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('filename', 'Path to file to open.'),
+            ('filename', 'Absolute path to file to open. Required.\n'
+                         'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'),
             ('outname', 'Name of the resulting Excellon object.')
             ('outname', 'Name of the resulting Excellon object.')
         ]),
         ]),
-        'examples': []
+        'examples': ['open_excellon D:\\my_excellon_file.DRL',
+                     'open_excellon "D:\\my_excellon_file with spaces in the name.DRL"',
+                     'open_excellon path_to_file']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):
@@ -48,6 +51,9 @@ class TclCommandOpenExcellon(TclCommandSignaled):
 
 
         filename = args.pop('filename')
         filename = args.pop('filename')
         # filename = filename.replace(' ', '')
         # filename = filename.replace(' ', '')
+        if ' ' in filename:
+            return "The absolute path to the project file contain spaces which is not allowed.\n" \
+                   "Please enclose the path within quotes."
 
 
         args['plot'] = False
         args['plot'] = False
         self.app.open_excellon(filename, **args)
         self.app.open_excellon(filename, **args)

+ 7 - 3
tclCommands/TclCommandOpenGCode.py

@@ -31,10 +31,12 @@ class TclCommandOpenGCode(TclCommandSignaled):
     help = {
     help = {
         'main': "Opens a G-Code file.",
         'main': "Opens a G-Code file.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('filename', 'Path to file to open.'),
+            ('filename', 'Absolute path to file to open. Required.\n'
+                         'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'),
             ('outname', 'Name of the resulting CNCJob object.')
             ('outname', 'Name of the resulting CNCJob object.')
         ]),
         ]),
-        'examples': []
+        'examples': ['open_gcode D:\\my_gcode_file.NC',
+                     'open_gcode "D:\\my_gcode_file with spaces in the name.TXT"']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):
@@ -48,6 +50,8 @@ class TclCommandOpenGCode(TclCommandSignaled):
         """
         """
         args['plot'] = False
         args['plot'] = False
         filename = args["filename"]
         filename = args["filename"]
-        # filename = filename.replace(' ', '')
+        if ' ' in filename:
+            return "The absolute path to the project file contain spaces which is not allowed.\n" \
+                   "Please enclose the path within quotes."
 
 
         self.app.open_gcode(filename, **args)
         self.app.open_gcode(filename, **args)

+ 8 - 3
tclCommands/TclCommandOpenGerber.py

@@ -30,10 +30,12 @@ class TclCommandOpenGerber(TclCommandSignaled):
     help = {
     help = {
         'main': "Opens a Gerber file.",
         'main': "Opens a Gerber file.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('filename', 'Path to file to open.'),
+            ('filename', 'Absolute path to file to open. Required.\n'
+                         'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'),
             ('outname', 'Name of the resulting Gerber object.')
             ('outname', 'Name of the resulting Gerber object.')
         ]),
         ]),
-        'examples': ["open_gerber gerber_object_path -outname bla"]
+        'examples': ["open_gerber gerber_object_path -outname bla",
+                     'open_gerber "D:\\my_gerber_file with spaces in the name.GRB"']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):
@@ -65,7 +67,10 @@ class TclCommandOpenGerber(TclCommandSignaled):
                 return
                 return
 
 
         filename = args['filename']
         filename = args['filename']
-        # filename = filename.replace(' ', '')
+
+        if ' ' in filename:
+            return "The absolute path to the project file contain spaces which is not allowed.\n" \
+                   "Please enclose the path within quotes."
 
 
         if 'outname' in args:
         if 'outname' in args:
             outname = args['outname']
             outname = args['outname']

+ 7 - 3
tclCommands/TclCommandOpenProject.py

@@ -30,9 +30,11 @@ class TclCommandOpenProject(TclCommandSignaled):
     help = {
     help = {
         'main': "Opens a FlatCAM project.",
         'main': "Opens a FlatCAM project.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('filename', 'Path to file to open.'),
+            ('filename', 'Absolute path to file to open. Required.\n'
+                         'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'),
         ]),
         ]),
-        'examples': []
+        'examples': ['open_project D:\\my_project_file.FlatPrj',
+                     'open_project "D:\\my_project_file with spaces in the name.FlatPrj"']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):
@@ -45,6 +47,8 @@ class TclCommandOpenProject(TclCommandSignaled):
         :return: None or exception
         :return: None or exception
         """
         """
         filename = args['filename']
         filename = args['filename']
-        filename = filename.replace(' ', '')
+        if ' ' in filename:
+            return "The absolute path to the project file contain spaces which is not allowed.\n" \
+                   "Please enclose the path within quotes."
 
 
         self.app.open_project(filename, cli=True, plot=False)
         self.app.open_project(filename, cli=True, plot=False)

+ 3 - 3
tclCommands/TclCommandOptions.py

@@ -28,11 +28,11 @@ class TclCommandOptions(TclCommandSignaled):
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
-        'main': "Shows the settings for an object.",
+        'main': "Will return the options (settings) for an object as a string with values separated by \\n.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Object name.'),
+            ('name', 'Object name for which to return the options. Required.'),
         ]),
         ]),
-        'examples': []
+        'examples': ['options obj_name']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 21 - 7
tclCommands/TclCommandPanelize.py

@@ -38,7 +38,7 @@ class TclCommandPanelize(TclCommand):
     ])
     ])
 
 
     # array of mandatory options for current Tcl command: required = {'name','outname'}
     # array of mandatory options for current Tcl command: required = {'name','outname'}
-    required = ['name', 'rows', 'columns']
+    required = ['name']
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
@@ -54,7 +54,14 @@ class TclCommandPanelize(TclCommand):
             ('outname', 'Name of the new geometry object.'),
             ('outname', 'Name of the new geometry object.'),
             ('run_threaded', 'False = non-threaded || True = threaded')
             ('run_threaded', 'False = non-threaded || True = threaded')
         ]),
         ]),
-        'examples': []
+        'examples': [
+            'panelize obj_name',
+
+            'panel obj_name -rows 2 -columns 2 -spacing_columns 0.4 -spacing_rows 1.3 -box box_obj_name '
+            '-outname panelized_name',
+
+            'panel obj_name -columns 2 -box box_obj_name -outname panelized_name',
+        ]
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):
@@ -85,8 +92,18 @@ class TclCommandPanelize(TclCommand):
         else:
         else:
             box = obj
             box = obj
 
 
-        if 'columns' not in args or 'rows' not in args:
-            return "ERROR: Specify -columns and -rows"
+        if 'columns' in args:
+            columns = int(args['columns'])
+        else:
+            columns = int(0)
+
+        if 'rows' in args:
+            rows = int(args['rows'])
+        else:
+            rows = int(0)
+
+        if 'columns' not in args and 'rows' not in args:
+            return "ERROR: Specify either -columns or -rows. The one not specified it will assumed to be 0"
 
 
         if 'outname' in args:
         if 'outname' in args:
             outname = args['outname']
             outname = args['outname']
@@ -108,9 +125,6 @@ class TclCommandPanelize(TclCommand):
         else:
         else:
             spacing_rows = 5
             spacing_rows = 5
 
 
-        rows = int(args['rows'])
-        columns = int(args['columns'])
-
         xmin, ymin, xmax, ymax = box.bounds()
         xmin, ymin, xmax, ymax = box.bounds()
         lenghtx = xmax - xmin + spacing_columns
         lenghtx = xmax - xmin + spacing_columns
         lenghty = ymax - ymin + spacing_rows
         lenghty = ymax - ymin + spacing_rows

+ 1 - 1
tclCommands/TclCommandPlotAll.py

@@ -33,7 +33,7 @@ class TclCommandPlotAll(TclCommand):
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
 
 
         ]),
         ]),
-        'examples': []
+        'examples': ['plot_all']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 4 - 4
tclCommands/TclCommandPlotObjects.py

@@ -32,15 +32,15 @@ class TclCommandPlotObjects(TclCommand):
     ])
     ])
 
 
     # array of mandatory options for current Tcl command: required = {'name','outname'}
     # array of mandatory options for current Tcl command: required = {'name','outname'}
-    required = []
+    required = ['names']
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
         'main': "Plot a list of objects.",
         'main': "Plot a list of objects.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('names', "UA list of object names to be plotted.")
+            ('names', "A list of object names to be plotted separated by comma. Required.")
         ]),
         ]),
-        'examples': ["plot_objects"]
+        'examples': ["plot_objects gerber_obj.GRB, excellon_obj.DRL"]
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):
@@ -51,7 +51,7 @@ class TclCommandPlotObjects(TclCommand):
         :return:
         :return:
         """
         """
         if self.app.cmd_line_headless != 1:
         if self.app.cmd_line_headless != 1:
-            names = [x.strip() for x in args['names'].split(",")]
+            names = [x.strip() for x in args['names'].split(",") if x != '']
             objs = []
             objs = []
             for name in names:
             for name in names:
                 objs.append(self.app.collection.get_by_name(name))
                 objs.append(self.app.collection.get_by_name(name))

+ 5 - 2
tclCommands/TclCommandSaveProject.py

@@ -30,9 +30,12 @@ class TclCommandSaveProject(TclCommandSignaled):
     help = {
     help = {
         'main': "Saves the FlatCAM project to file.",
         'main': "Saves the FlatCAM project to file.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('filename', 'Path to file.'),
+            ('filename', 'Absolute path to file to open. Required.\n'
+                         'WARNING: no spaces are allowed. If unsure enclose the entire path with quotes.'),
         ]),
         ]),
-        'examples': []
+        'examples': ['save_project D:\\my_project_file.FlatPrj',
+                     'save_project "D:\\my_project_file with spaces in the name.FlatPrj"',
+                     'save_project path_to_where_the_file_is_stored']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 2 - 2
tclCommands/TclCommandSaveSys.py

@@ -33,9 +33,9 @@ class TclCommandSaveSys(TclCommandSignaled):
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
-        'main': "Saves the FlatCAM system paramaters to defaults file.",
+        'main': "Saves the FlatCAM system parameters to defaults file.",
         'args': collections.OrderedDict([]),
         'args': collections.OrderedDict([]),
-        'examples': []
+        'examples': ['save_sys']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 21 - 8
tclCommands/TclCommandScale.py

@@ -45,18 +45,22 @@ class TclCommandScale(TclCommand):
     help = {
     help = {
         'main': "Resizes the object by a factor on X axis and a factor on Y axis, having as scale origin the point ",
         'main': "Resizes the object by a factor on X axis and a factor on Y axis, having as scale origin the point ",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Name of the object to resize.'),
-            ('factor', 'Fraction by which to scale on both axis. '),
+            ('name', 'Name of the object (Gerber, Geometry or Excellon) to be resized. Required.'),
+            ('factor', 'Fraction by which to scale on both axis.'),
             ('x', 'Fraction by which to scale on X axis. If "factor" is used then this parameter is ignored'),
             ('x', 'Fraction by which to scale on X axis. If "factor" is used then this parameter is ignored'),
             ('y', 'Fraction by which to scale on Y axis. If "factor" is used then this parameter is ignored'),
             ('y', 'Fraction by which to scale on Y axis. If "factor" is used then this parameter is ignored'),
-            ('origin', 'Reference used for scale. It can be: "origin" which means point (0, 0) or "min_bounds" which '
-                       'means the lower left point of the bounding box or it can be "center" which means the center '
-                       'of the bounding box.')
+            ('origin', 'Reference used for scale.\n'
+                       'The reference point can be:\n'
+                       '- "origin" which means point (0, 0)\n'
+                       '- "min_bounds" which means the lower left point of the bounding box\n'
+                       '- "center" which means the center point of the bounding box of the object.\n'
+                       '- a tuple in format (x,y) with the X and Y coordinates separated by a comma. NO SPACES ALLOWED')
 
 
         ]),
         ]),
         'examples': ['scale my_geometry 4.2',
         'examples': ['scale my_geometry 4.2',
                      'scale my_geo -x 3.1 -y 2.8',
                      'scale my_geo -x 3.1 -y 2.8',
-                     'scale my_geo 1.2 -origin min_bounds']
+                     'scale my_geo 1.2 -origin min_bounds',
+                     'scale my_geometry -x 2 -origin 3.0,2.1']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):
@@ -92,8 +96,17 @@ class TclCommandScale(TclCommand):
                 c_y = ymin + (ymax - ymin) / 2
                 c_y = ymin + (ymax - ymin) / 2
                 point = (c_x, c_y)
                 point = (c_x, c_y)
             else:
             else:
-                self.raise_tcl_error('%s' % _("Expected -origin <origin> or -origin <min_bounds> or -origin <center>."))
-                return 'fail'
+                try:
+                    point = eval(args['origin'])
+                    if not isinstance(point, tuple):
+                        raise Exception
+                except Exception as e:
+                    self.raise_tcl_error('%s\n%s' % (_("Expected -origin <origin> or "
+                                                  "-origin <min_bounds> or "
+                                                  "-origin <center> or "
+                                                  "- origin 3.0,4.2."), str(e))
+                                         )
+                    return 'fail'
 
 
         if 'factor' in args:
         if 'factor' in args:
             factor = float(args['factor'])
             factor = float(args['factor'])

+ 2 - 2
tclCommands/TclCommandSetActive.py

@@ -31,9 +31,9 @@ class TclCommandSetActive(TclCommand):
     help = {
     help = {
         'main': 'Sets an object as active.',
         'main': 'Sets an object as active.',
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Name of the Object.'),
+            ('name', 'Name of the FlatCAM object to be set as active (selected). Required.'),
         ]),
         ]),
-        'examples': []
+        'examples': ['set_active object_name']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 5 - 3
tclCommands/TclCommandSetOrigin.py

@@ -49,13 +49,15 @@ class TclCommandSetOrigin(TclCommand):
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
-        'main': "Will set the origin at the specified x,y location.",
+        'main': "Will set the origin at the specified x,y location.\n"
+                "If it is called without arguments it will set origin at (0, 0)",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('loc', 'Location to offset all the selected objects. No spaces between x and y pair. Use like this: 2,3'),
+            ('loc', 'Location to offset all the selected objects. NO SPACES ALLOWED in X and Y pair.\n'
+                    'Use like this: 2,3'),
             ('auto', 'If set to True it will set the origin to the minimum x, y of the object selection bounding box.'
             ('auto', 'If set to True it will set the origin to the minimum x, y of the object selection bounding box.'
                      '-auto=True is not correct but -auto 1 or -auto True is correct.')
                      '-auto=True is not correct but -auto 1 or -auto True is correct.')
         ]),
         ]),
-        'examples': ['set_origin 3,2', 'set_origin -auto 1']
+        'examples': ['set_origin 3,2', 'set_origin -auto 1', 'origin']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 2 - 2
tclCommands/TclCommandSetSys.py

@@ -32,10 +32,10 @@ class TclCommandSetSys(TclCommand):
     help = {
     help = {
         'main': "Sets the value of the system variable.",
         'main': "Sets the value of the system variable.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Name of the system variable.'),
+            ('name', 'Name of the system variable. Required.'),
             ('value', 'Value to set.')
             ('value', 'Value to set.')
         ]),
         ]),
-        'examples': []
+        'examples': ['set_sys global_gridx 1.0']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 21 - 10
tclCommands/TclCommandSkew.py

@@ -17,28 +17,27 @@ class TclCommandSkew(TclCommand):
     # Dictionary of types from Tcl command, needs to be ordered
     # Dictionary of types from Tcl command, needs to be ordered
     arg_names = collections.OrderedDict([
     arg_names = collections.OrderedDict([
         ('name', str),
         ('name', str),
-        ('angle_x', float),
-        ('angle_y', float)
     ])
     ])
 
 
     # Dictionary of types from Tcl command, needs to be ordered , this  is  for options  like -optionname value
     # Dictionary of types from Tcl command, needs to be ordered , this  is  for options  like -optionname value
     option_types = collections.OrderedDict([
     option_types = collections.OrderedDict([
-
+        ('x', float),
+        ('y', float)
     ])
     ])
 
 
     # array of mandatory options for current Tcl command: required = {'name','outname'}
     # array of mandatory options for current Tcl command: required = {'name','outname'}
-    required = ['name', 'angle_x', 'angle_y']
+    required = ['name']
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
         'main': "Shear/Skew an object by angles along x and y dimensions. The reference point is the left corner of "
         'main': "Shear/Skew an object by angles along x and y dimensions. The reference point is the left corner of "
                 "the bounding box of the object.",
                 "the bounding box of the object.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Name of the object to skew.'),
-            ('angle_x', 'Angle in degrees by which to skew on the X axis.'),
-            ('angle_y', 'Angle in degrees by which to skew on the Y axis.')
+            ('name', 'Name of the object (Gerber, Geometry or Excellon) to be deformed (skewed). Required.'),
+            ('x', 'Angle in degrees by which to skew on the X axis. If it is not used it will be assumed to be 0.0'),
+            ('y', 'Angle in degrees by which to skew on the Y axis. If it is not used it will be assumed to be 0.0')
         ]),
         ]),
-        'examples': ['skew my_geometry 10.2 3.5']
+        'examples': ['skew my_geometry -x 10.2 -y 3.5', 'skew my_geo -x 3.0']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):
@@ -50,8 +49,20 @@ class TclCommandSkew(TclCommand):
         """
         """
 
 
         name = args['name']
         name = args['name']
-        angle_x = float(args['angle_x'])
-        angle_y = float(args['angle_y'])
+
+        if 'x' in args:
+            angle_x = float(args['x'])
+        else:
+            angle_x = 0.0
+
+        if 'y' in args:
+            angle_y = float(args['y'])
+        else:
+            angle_y = 0.0
+
+        if angle_x == 0.0 and angle_y == 0.0:
+            # nothing to be done
+            return
 
 
         obj_to_skew = self.app.collection.get_by_name(name)
         obj_to_skew = self.app.collection.get_by_name(name)
         xmin, ymin, xmax, ymax = obj_to_skew.bounds()
         xmin, ymin, xmax, ymax = obj_to_skew.bounds()

+ 5 - 3
tclCommands/TclCommandSubtractPoly.py

@@ -28,12 +28,14 @@ class TclCommandSubtractPoly(TclCommandSignaled):
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
-        'main': "Subtract polygon from the given Geometry object.",
+        'main': "Subtract polygon from the given Geometry object. The coordinates are provided in X Y pairs.\n"
+                "If the number of coordinates is not even then the 'Incomplete coordinate' error is raised.\n"
+                "If last coordinates are not the same as the first ones, the polygon will be completed automatically.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Name of the Geometry object from which to subtract.'),
+            ('name', 'Name of the Geometry object from which to subtract. Required.'),
             ('x0 y0 x1 y1 x2 y2 ...', 'Points defining the polygon.')
             ('x0 y0 x1 y1 x2 y2 ...', 'Points defining the polygon.')
         ]),
         ]),
-        'examples': []
+        'examples': ['subtract_poly my_geo 0 0 2 1 3 3 4 4 0 0']
     }
     }
 
 
     def execute(self, args, unnamed_args):
     def execute(self, args, unnamed_args):

+ 3 - 2
tclCommands/TclCommandSubtractRectangle.py

@@ -36,9 +36,10 @@ class TclCommandSubtractRectangle(TclCommandSignaled):
 
 
     # structured help for current command, args needs to be ordered
     # structured help for current command, args needs to be ordered
     help = {
     help = {
-        'main': "Subtract rectange from the given Geometry object.",
+        'main': "Subtract a rectangle from the given Geometry object. The coordinates are provided in X Y pairs.\n"
+                "If the number of coordinates is not even then the 'Incomplete coordinates' error is raised.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Name of the Geometry object from which to subtract.'),
+            ('name', 'Name of the Geometry object from which to subtract. Required.'),
             ('x0 y0', 'Bottom left corner coordinates.'),
             ('x0 y0', 'Bottom left corner coordinates.'),
             ('x1 y1', 'Top right corner coordinates.')
             ('x1 y1', 'Top right corner coordinates.')
         ]),
         ]),

+ 2 - 2
tclCommands/TclCommandWriteGCode.py

@@ -34,8 +34,8 @@ class TclCommandWriteGCode(TclCommandSignaled):
     help = {
     help = {
         'main': "Saves G-code of a CNC Job object to file.",
         'main': "Saves G-code of a CNC Job object to file.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
-            ('name', 'Source CNC Job object.'),
-            ('filename', 'Output filename.'),
+            ('name', 'Source CNC Job object. Required.'),
+            ('filename', 'Output filename. Required.'),
             ('preamble', 'Text to append at the beginning.'),
             ('preamble', 'Text to append at the beginning.'),
             ('postamble', 'Text to append at the end.'),
             ('postamble', 'Text to append at the end.'),
             ('muted', 'It will not put errors in the Shell or status bar.')
             ('muted', 'It will not put errors in the Shell or status bar.')