TclCommandNregions.py 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. from ObjectCollection import *
  2. from tclCommands.TclCommand import TclCommand
  3. import gettext
  4. import FlatCAMTranslation as fcTranslate
  5. import builtins
  6. fcTranslate.apply_language('strings')
  7. if '_' not in builtins.__dict__:
  8. _ = gettext.gettext
  9. class TclCommandNregions(TclCommand):
  10. """
  11. Tcl shell command to follow a Gerber file
  12. """
  13. # array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
  14. aliases = ['non_copper_regions', 'ncr']
  15. # dictionary of types from Tcl command, needs to be ordered
  16. arg_names = collections.OrderedDict([
  17. ('name', str)
  18. ])
  19. # dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
  20. option_types = collections.OrderedDict([
  21. ('outname', str),
  22. ('margin', float),
  23. ('rounded', bool)
  24. ])
  25. # array of mandatory options for current Tcl command: required = {'name','outname'}
  26. required = ['name']
  27. # structured help for current command, args needs to be ordered
  28. help = {
  29. 'main': "Creates a geometry object with the non-copper regions.",
  30. 'args': collections.OrderedDict([
  31. ('name', 'Object name for which to create non-copper regions. String'),
  32. ('outname', 'Name of the resulting Geometry object. String.'),
  33. ('margin', "Specify the edge of the PCB by drawing a box around all objects with this minimum distance. "
  34. "Float number."),
  35. ('rounded', "Resulting geometry will have rounded corners. True or False.")
  36. ]),
  37. 'examples': ['ncr name -outname name_ncr']
  38. }
  39. def execute(self, args, unnamed_args):
  40. """
  41. execute current TCL shell command
  42. :param args: array of known named arguments and options
  43. :param unnamed_args: array of other values which were passed into command
  44. without -somename and we do not have them in known arg_names
  45. :return: None or exception
  46. """
  47. name = args['name']
  48. if 'outname' not in args:
  49. args['outname'] = name + "_noncopper"
  50. obj = self.app.collection.get_by_name(name)
  51. if obj is None:
  52. self.raise_tcl_error("%s: %s" % (_("Object not found"), name))
  53. if not isinstance(obj, FlatCAMGerber) and not isinstance(obj, FlatCAMGeometry):
  54. self.raise_tcl_error('%s %s: %s.' % (_("Expected FlatCAMGerber or FlatCAMGeometry, got"), name, type(obj)))
  55. if 'margin' not in args:
  56. args['margin'] = float(self.app.defaults["gerber_noncoppermargin"])
  57. margin = args['margin']
  58. if 'rounded' not in args:
  59. args['rounded'] = self.app.defaults["gerber_noncopperrounded"]
  60. rounded = args['rounded']
  61. del args['name']
  62. try:
  63. def geo_init(geo_obj, app_obj):
  64. assert isinstance(geo_obj, FlatCAMGeometry)
  65. geo = cascaded_union(obj.solid_geometry)
  66. bounding_box = geo.envelope.buffer(float(margin))
  67. if not rounded:
  68. bounding_box = bounding_box.envelope
  69. non_copper = bounding_box.difference(geo)
  70. geo_obj.solid_geometry = non_copper
  71. self.app.new_object("geometry", args['outname'], geo_init)
  72. except Exception as e:
  73. return "Operation failed: %s" % str(e)
  74. # in the end toggle the visibility of the origin object so we can see the generated Geometry
  75. self.app.collection.get_by_name(name).ui.plot_cb.toggle()