TclCommandCopperClear.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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 TclCommandCopperClear(TclCommand):
  10. """
  11. Clear the non-copper areas.
  12. """
  13. # Array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
  14. aliases = ['ncc_clear', 'ncc']
  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. ('tooldia', str),
  22. ('overlap', float),
  23. ('order', str),
  24. ('margin', float),
  25. ('method', str),
  26. ('connect', bool),
  27. ('contour', bool),
  28. ('all', bool),
  29. ('ref', bool),
  30. ('box', str),
  31. ('outname', str),
  32. ])
  33. # array of mandatory options for current Tcl command: required = {'name','outname'}
  34. required = ['name']
  35. # structured help for current command, args needs to be ordered
  36. help = {
  37. 'main': "Clear excess copper in polygons. Basically it's a negative Paint.",
  38. 'args': collections.OrderedDict([
  39. ('name', 'Name of the source Geometry object. String.'),
  40. ('tooldia', 'Diameter of the tool to be used. Can be a comma separated list of diameters. No space is '
  41. 'allowed between tool diameters. E.g: correct: 0.5,1 / incorrect: 0.5, 1'),
  42. ('overlap', 'Fraction of the tool diameter to overlap cuts. Float number.'),
  43. ('margin', 'Bounding box margin. Float number.'),
  44. ('order', 'Can have the values: "no", "fwd" and "rev". String.'
  45. 'It is useful when there are multiple tools in tooldia parameter.'
  46. '"no" -> the order used is the one provided.'
  47. '"fwd" -> tools are ordered from smallest to biggest.'
  48. '"rev" -> tools are ordered from biggest to smallest.'),
  49. ('method', 'Algorithm for copper clearing. Can be: "standard", "seed" or "lines".'),
  50. ('connect', 'Draw lines to minimize tool lifts. True or False'),
  51. ('contour', 'Cut around the perimeter of the painting. True or False'),
  52. ('rest', 'Use rest-machining. True or False'),
  53. ('offset', 'The copper clearing will finish to a distance from copper features. True or False.'),
  54. ('all', 'Will copper clear the whole object. True or False'),
  55. ('ref', 'Will clear of extra copper all polygons within a specified object with the name in "box" '
  56. 'parameter. True or False'),
  57. ('box', 'name of the object to be used as reference when selecting "ref"" True. String.'),
  58. ('outname', 'Name of the resulting Geometry object. String.'),
  59. ]),
  60. 'examples': []
  61. }
  62. def execute(self, args, unnamed_args):
  63. """
  64. execute current TCL shell command
  65. :param args: array of known named arguments and options
  66. :param unnamed_args: array of other values which were passed into command
  67. without -somename and we do not have them in known arg_names
  68. :return: None or exception
  69. """
  70. name = args['name']
  71. if 'tooldia' in args:
  72. tooldia = str(args['tooldia'])
  73. else:
  74. tooldia = float(self.app.defaults["tools_ncctools"])
  75. if 'overlap' in args:
  76. overlap = float(args['overlap'])
  77. else:
  78. overlap = float(self.app.defaults["tools_nccoverlap"])
  79. if 'order' in args:
  80. order = args['order']
  81. else:
  82. order = str(self.app.defaults["tools_nccorder"])
  83. if 'margin' in args:
  84. margin = float(args['margin'])
  85. else:
  86. margin = float(self.app.defaults["tools_nccmargin"])
  87. if 'method' in args:
  88. method = args['method']
  89. else:
  90. method = str(self.app.defaults["tools_nccmethod"])
  91. if 'connect' in args:
  92. connect = eval(str(args['connect']).capitalize())
  93. else:
  94. connect = eval(str(self.app.defaults["tools_nccconnect"]))
  95. if 'contour' in args:
  96. contour = eval(str(args['contour']).capitalize())
  97. else:
  98. contour = eval(str(self.app.defaults["tools_ncccontour"]))
  99. if 'rest' in args:
  100. rest = eval(str(args['rest']).capitalize())
  101. else:
  102. rest = eval(str(self.app.defaults["tools_nccrest"]))
  103. # if 'offset' not in args then not use it
  104. offset = None
  105. if 'offset' in args:
  106. offset = float(args['margin'])
  107. if 'outname' in args:
  108. outname = args['outname']
  109. else:
  110. outname = name + "_ncc"
  111. # Get source object.
  112. try:
  113. obj = self.app.collection.get_by_name(str(name))
  114. except Exception as e:
  115. log.debug("TclCommandCopperClear.execute() --> %s" % str(e))
  116. self.raise_tcl_error("%s: %s" % (_("Could not retrieve object"), name))
  117. return "Could not retrieve object: %s" % name
  118. try:
  119. tools = [float(eval(dia)) for dia in tooldia.split(",") if dia != '']
  120. except AttributeError:
  121. tools = [float(tooldia)]
  122. # store here the default data for Geometry Data
  123. default_data = {}
  124. default_data.update({
  125. "name": '_paint',
  126. "plot": self.app.defaults["geometry_plot"],
  127. "cutz": self.app.defaults["geometry_cutz"],
  128. "vtipdia": 0.1,
  129. "vtipangle": 30,
  130. "travelz": self.app.defaults["geometry_travelz"],
  131. "feedrate": self.app.defaults["geometry_feedrate"],
  132. "feedrate_z": self.app.defaults["geometry_feedrate_z"],
  133. "feedrate_rapid": self.app.defaults["geometry_feedrate_rapid"],
  134. "dwell": self.app.defaults["geometry_dwell"],
  135. "dwelltime": self.app.defaults["geometry_dwelltime"],
  136. "multidepth": self.app.defaults["geometry_multidepth"],
  137. "ppname_g": self.app.defaults["geometry_ppname_g"],
  138. "depthperpass": self.app.defaults["geometry_depthperpass"],
  139. "extracut": self.app.defaults["geometry_extracut"],
  140. "toolchange": self.app.defaults["geometry_toolchange"],
  141. "toolchangez": self.app.defaults["geometry_toolchangez"],
  142. "endz": self.app.defaults["geometry_endz"],
  143. "spindlespeed": self.app.defaults["geometry_spindlespeed"],
  144. "toolchangexy": self.app.defaults["geometry_toolchangexy"],
  145. "startz": self.app.defaults["geometry_startz"],
  146. "tooldia": self.app.defaults["tools_painttooldia"],
  147. "paintmargin": self.app.defaults["tools_paintmargin"],
  148. "paintmethod": self.app.defaults["tools_paintmethod"],
  149. "selectmethod": self.app.defaults["tools_selectmethod"],
  150. "pathconnect": self.app.defaults["tools_pathconnect"],
  151. "paintcontour": self.app.defaults["tools_paintcontour"],
  152. "paintoverlap": self.app.defaults["tools_paintoverlap"]
  153. })
  154. ncc_tools = dict()
  155. tooluid = 0
  156. for tool in tools:
  157. tooluid += 1
  158. ncc_tools.update({
  159. int(tooluid): {
  160. 'tooldia': float('%.4f' % tool),
  161. 'offset': 'Path',
  162. 'offset_value': 0.0,
  163. 'type': 'Iso',
  164. 'tool_type': 'C1',
  165. 'data': dict(default_data),
  166. 'solid_geometry': []
  167. }
  168. })
  169. if obj is None:
  170. return "Object not found: %s" % name
  171. # Paint all polygons in the painted object
  172. if 'all' in args and args['all'] is True:
  173. self.app.ncclear_tool.clear_copper(obj=obj,
  174. tooldia=tooldia,
  175. overlap=overlap,
  176. order=order,
  177. margin=margin,
  178. method=method,
  179. outname=outname,
  180. connect=connect,
  181. contour=contour,
  182. tools_storage=ncc_tools)
  183. return
  184. # Paint all polygons found within the box object from the the painted object
  185. elif 'ref' in args and args['ref'] is True:
  186. if 'box' not in args:
  187. self.raise_tcl_error('%s' % _("Expected -box <value>."))
  188. else:
  189. box_name = args['box']
  190. # Get box source object.
  191. try:
  192. box_obj = self.app.collection.get_by_name(str(box_name))
  193. except Exception as e:
  194. log.debug("TclCommandCopperClear.execute() --> %s" % str(e))
  195. self.raise_tcl_error("%s: %s" % (_("Could not retrieve box object"), name))
  196. return "Could not retrieve object: %s" % name
  197. self.app.ncclear_tool.clear_copper(obj=obj,
  198. sel_obj=box_obj,
  199. tooldia=tooldia,
  200. overlap=overlap,
  201. order=order,
  202. margin=margin,
  203. method=method,
  204. outname=outname,
  205. connect=connect,
  206. contour=contour,
  207. tools_storage=ncc_tools)
  208. return
  209. else:
  210. self.raise_tcl_error("%s:" % _("There was none of the following args: 'ref', 'single', 'all'.\n"
  211. "Paint failed."))
  212. return "There was none of the following args: 'ref', 'single', 'all'.\n" \
  213. "Paint failed."