ToolsPaintPrefGroupUI.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. from PyQt5 import QtWidgets
  2. from PyQt5.QtCore import QSettings
  3. from appGUI.GUIElements import RadioSet, FCDoubleSpinner, FCComboBox2, FCCheckBox, NumericalEvalTupleEntry
  4. from appGUI.preferences.OptionsGroupUI import OptionsGroupUI
  5. import gettext
  6. import appTranslation as fcTranslate
  7. import builtins
  8. fcTranslate.apply_language('strings')
  9. if '_' not in builtins.__dict__:
  10. _ = gettext.gettext
  11. settings = QSettings("Open Source", "FlatCAM")
  12. if settings.contains("machinist"):
  13. machinist_setting = settings.value('machinist', type=int)
  14. else:
  15. machinist_setting = 0
  16. class ToolsPaintPrefGroupUI(OptionsGroupUI):
  17. def __init__(self, decimals=4, parent=None):
  18. # OptionsGroupUI.__init__(self, "Paint Area Tool Options", parent=parent)
  19. super(ToolsPaintPrefGroupUI, self).__init__(self, parent=parent)
  20. self.setTitle(str(_("Paint Tool Options")))
  21. self.decimals = decimals
  22. # ------------------------------
  23. # ## Paint area
  24. # ------------------------------
  25. self.paint_label = QtWidgets.QLabel('<b>%s:</b>' % _('Parameters'))
  26. self.paint_label.setToolTip(
  27. _("Creates tool paths to cover the\n"
  28. "whole area of a polygon.")
  29. )
  30. self.layout.addWidget(self.paint_label)
  31. grid0 = QtWidgets.QGridLayout()
  32. grid0.setColumnStretch(0, 0)
  33. grid0.setColumnStretch(1, 1)
  34. self.layout.addLayout(grid0)
  35. # Tool dia
  36. ptdlabel = QtWidgets.QLabel('<b><font color="green">%s:</font></b>' % _('Tools Dia'))
  37. ptdlabel.setToolTip(
  38. _("Diameters of the tools, separated by comma.\n"
  39. "The value of the diameter has to use the dot decimals separator.\n"
  40. "Valid values: 0.3, 1.0")
  41. )
  42. grid0.addWidget(ptdlabel, 0, 0)
  43. self.painttooldia_entry = NumericalEvalTupleEntry(border_color='#0069A9')
  44. self.painttooldia_entry.setPlaceholderText(_("Comma separated values"))
  45. grid0.addWidget(self.painttooldia_entry, 0, 1)
  46. # Tool Type Radio Button
  47. self.tool_type_label = QtWidgets.QLabel('%s:' % _('Tool Type'))
  48. self.tool_type_label.setToolTip(
  49. _("Default tool type:\n"
  50. "- 'V-shape'\n"
  51. "- Circular")
  52. )
  53. self.tool_type_radio = RadioSet([{'label': _('V-shape'), 'value': 'V'},
  54. {'label': _('Circular'), 'value': 'C1'}])
  55. self.tool_type_radio.setObjectName(_("Tool Type"))
  56. grid0.addWidget(self.tool_type_label, 1, 0)
  57. grid0.addWidget(self.tool_type_radio, 1, 1)
  58. # Tip Dia
  59. self.tipdialabel = QtWidgets.QLabel('%s:' % _('V-Tip Dia'))
  60. self.tipdialabel.setToolTip(
  61. _("The tip diameter for V-Shape Tool"))
  62. self.tipdia_entry = FCDoubleSpinner()
  63. self.tipdia_entry.set_precision(self.decimals)
  64. self.tipdia_entry.set_range(0.0000, 10000.0000)
  65. self.tipdia_entry.setSingleStep(0.1)
  66. self.tipdia_entry.setObjectName(_("V-Tip Dia"))
  67. grid0.addWidget(self.tipdialabel, 2, 0)
  68. grid0.addWidget(self.tipdia_entry, 2, 1)
  69. # Tip Angle
  70. self.tipanglelabel = QtWidgets.QLabel('%s:' % _('V-Tip Angle'))
  71. self.tipanglelabel.setToolTip(
  72. _("The tip angle for V-Shape Tool.\n"
  73. "In degree."))
  74. self.tipangle_entry = FCDoubleSpinner()
  75. self.tipangle_entry.set_precision(self.decimals)
  76. self.tipangle_entry.set_range(1.0000, 180.0000)
  77. self.tipangle_entry.setSingleStep(5)
  78. self.tipangle_entry.setObjectName(_("V-Tip Angle"))
  79. grid0.addWidget(self.tipanglelabel, 3, 0)
  80. grid0.addWidget(self.tipangle_entry, 3, 1)
  81. # Cut Z entry
  82. cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z'))
  83. cutzlabel.setToolTip(
  84. _("Depth of cut into material. Negative value.\n"
  85. "In application units.")
  86. )
  87. self.cutz_entry = FCDoubleSpinner()
  88. self.cutz_entry.set_precision(self.decimals)
  89. self.cutz_entry.set_range(-910000.0000, 0.0000)
  90. self.cutz_entry.setObjectName(_("Cut Z"))
  91. self.cutz_entry.setToolTip(
  92. _("Depth of cut into material. Negative value.\n"
  93. "In application units.")
  94. )
  95. grid0.addWidget(cutzlabel, 4, 0)
  96. grid0.addWidget(self.cutz_entry, 4, 1)
  97. # ### Tool Diameter ####
  98. self.newdialabel = QtWidgets.QLabel('%s:' % _('New Dia'))
  99. self.newdialabel.setToolTip(
  100. _("Diameter for the new tool to add in the Tool Table.\n"
  101. "If the tool is V-shape type then this value is automatically\n"
  102. "calculated from the other parameters.")
  103. )
  104. self.newdia_entry = FCDoubleSpinner()
  105. self.newdia_entry.set_precision(self.decimals)
  106. self.newdia_entry.set_range(0.000, 10000.0000)
  107. self.newdia_entry.setObjectName(_("Tool Dia"))
  108. grid0.addWidget(self.newdialabel, 5, 0)
  109. grid0.addWidget(self.newdia_entry, 5, 1)
  110. separator_line = QtWidgets.QFrame()
  111. separator_line.setFrameShape(QtWidgets.QFrame.HLine)
  112. separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
  113. grid0.addWidget(separator_line, 6, 0, 1, 2)
  114. self.paint_order_label = QtWidgets.QLabel('%s:' % _('Tool order'))
  115. self.paint_order_label.setToolTip(_("This set the way that the tools in the tools table are used.\n"
  116. "'No' --> means that the used order is the one in the tool table\n"
  117. "'Forward' --> means that the tools will be ordered from small to big\n"
  118. "'Reverse' --> means that the tools will ordered from big to small\n\n"
  119. "WARNING: using rest machining will automatically set the order\n"
  120. "in reverse and disable this control."))
  121. self.paint_order_radio = RadioSet([{'label': _('No'), 'value': 'no'},
  122. {'label': _('Forward'), 'value': 'fwd'},
  123. {'label': _('Reverse'), 'value': 'rev'}])
  124. grid0.addWidget(self.paint_order_label, 7, 0)
  125. grid0.addWidget(self.paint_order_radio, 7, 1)
  126. separator_line = QtWidgets.QFrame()
  127. separator_line.setFrameShape(QtWidgets.QFrame.HLine)
  128. separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
  129. grid0.addWidget(separator_line, 8, 0, 1, 2)
  130. # Overlap
  131. ovlabel = QtWidgets.QLabel('%s:' % _('Overlap'))
  132. ovlabel.setToolTip(
  133. _("How much (percentage) of the tool width to overlap each tool pass.\n"
  134. "Adjust the value starting with lower values\n"
  135. "and increasing it if areas that should be painted are still \n"
  136. "not painted.\n"
  137. "Lower values = faster processing, faster execution on CNC.\n"
  138. "Higher values = slow processing and slow execution on CNC\n"
  139. "due of too many paths.")
  140. )
  141. self.paintoverlap_entry = FCDoubleSpinner(suffix='%')
  142. self.paintoverlap_entry.set_precision(self.decimals)
  143. self.paintoverlap_entry.setWrapping(True)
  144. self.paintoverlap_entry.setRange(0.0000, 99.9999)
  145. self.paintoverlap_entry.setSingleStep(0.1)
  146. grid0.addWidget(ovlabel, 9, 0)
  147. grid0.addWidget(self.paintoverlap_entry, 9, 1)
  148. # Margin
  149. marginlabel = QtWidgets.QLabel('%s:' % _('Margin'))
  150. marginlabel.setToolTip(
  151. _("Distance by which to avoid\n"
  152. "the edges of the polygon to\n"
  153. "be painted.")
  154. )
  155. self.paintmargin_entry = FCDoubleSpinner()
  156. self.paintmargin_entry.set_range(-10000.0000, 10000.0000)
  157. self.paintmargin_entry.set_precision(self.decimals)
  158. self.paintmargin_entry.setSingleStep(0.1)
  159. grid0.addWidget(marginlabel, 10, 0)
  160. grid0.addWidget(self.paintmargin_entry, 10, 1)
  161. # Method
  162. methodlabel = QtWidgets.QLabel('%s:' % _('Method'))
  163. methodlabel.setToolTip(
  164. _("Algorithm for painting:\n"
  165. "- Standard: Fixed step inwards.\n"
  166. "- Seed-based: Outwards from seed.\n"
  167. "- Line-based: Parallel lines.\n"
  168. "- Laser-lines: Active only for Gerber objects.\n"
  169. "Will create lines that follow the traces.\n"
  170. "- Combo: In case of failure a new method will be picked from the above\n"
  171. "in the order specified.")
  172. )
  173. # self.paintmethod_combo = RadioSet([
  174. # {"label": _("Standard"), "value": "standard"},
  175. # {"label": _("Seed-based"), "value": "seed"},
  176. # {"label": _("Straight lines"), "value": "lines"}
  177. # ], orientation='vertical', stretch=False)
  178. self.paintmethod_combo = FCComboBox2()
  179. self.paintmethod_combo.addItems(
  180. [_("Standard"), _("Seed"), _("Lines"), _("Laser_lines"), _("Combo")]
  181. )
  182. grid0.addWidget(methodlabel, 11, 0)
  183. grid0.addWidget(self.paintmethod_combo, 11, 1)
  184. # Connect lines
  185. self.pathconnect_cb = FCCheckBox('%s' % _("Connect"))
  186. self.pathconnect_cb.setToolTip(
  187. _("Draw lines between resulting\n"
  188. "segments to minimize tool lifts.")
  189. )
  190. grid0.addWidget(self.pathconnect_cb, 12, 0)
  191. # Paint contour
  192. self.contour_cb = FCCheckBox('%s' % _("Contour"))
  193. self.contour_cb.setToolTip(
  194. _("Cut around the perimeter of the polygon\n"
  195. "to trim rough edges.")
  196. )
  197. grid0.addWidget(self.contour_cb, 12, 1)
  198. separator_line = QtWidgets.QFrame()
  199. separator_line.setFrameShape(QtWidgets.QFrame.HLine)
  200. separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
  201. grid0.addWidget(separator_line, 13, 0, 1, 2)
  202. self.rest_cb = FCCheckBox('%s' % _("Rest"))
  203. self.rest_cb.setObjectName(_("Rest"))
  204. self.rest_cb.setToolTip(
  205. _("If checked, use 'rest machining'.\n"
  206. "Basically it will clear copper outside PCB features,\n"
  207. "using the biggest tool and continue with the next tools,\n"
  208. "from bigger to smaller, to clear areas of copper that\n"
  209. "could not be cleared by previous tool, until there is\n"
  210. "no more copper to clear or there are no more tools.\n\n"
  211. "If not checked, use the standard algorithm.")
  212. )
  213. grid0.addWidget(self.rest_cb, 14, 0, 1, 2)
  214. # Polygon selection
  215. selectlabel = QtWidgets.QLabel('%s:' % _('Selection'))
  216. selectlabel.setToolTip(
  217. _("Selection of area to be processed.\n"
  218. "- 'Polygon Selection' - left mouse click to add/remove polygons to be processed.\n"
  219. "- 'Area Selection' - left mouse click to start selection of the area to be processed.\n"
  220. "Keeping a modifier key pressed (CTRL or SHIFT) will allow to add multiple areas.\n"
  221. "- 'All Polygons' - the process will start after click.\n"
  222. "- 'Reference Object' - will process the area specified by another object.")
  223. )
  224. # self.selectmethod_combo = RadioSet(
  225. # [
  226. # {"label": _("Polygon Selection"), "value": "single"},
  227. # {"label": _("Area Selection"), "value": "area"},
  228. # {"label": _("All Polygons"), "value": "all"},
  229. # {"label": _("Reference Object"), "value": "ref"}
  230. # ],
  231. # orientation='vertical',
  232. # stretch=None
  233. # )
  234. self.selectmethod_combo = FCComboBox2()
  235. self.selectmethod_combo.addItems(
  236. [_("All"), _("Polygon Selection"), _("Area Selection"), _("Reference Object")]
  237. )
  238. grid0.addWidget(selectlabel, 15, 0)
  239. grid0.addWidget(self.selectmethod_combo, 15, 1)
  240. self.area_shape_label = QtWidgets.QLabel('%s:' % _("Shape"))
  241. self.area_shape_label.setToolTip(
  242. _("The kind of selection shape used for area selection.")
  243. )
  244. self.area_shape_radio = RadioSet([{'label': _("Square"), 'value': 'square'},
  245. {'label': _("Polygon"), 'value': 'polygon'}])
  246. grid0.addWidget(self.area_shape_label, 18, 0)
  247. grid0.addWidget(self.area_shape_radio, 18, 1)
  248. separator_line = QtWidgets.QFrame()
  249. separator_line.setFrameShape(QtWidgets.QFrame.HLine)
  250. separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
  251. grid0.addWidget(separator_line, 19, 0, 1, 2)
  252. # ## Plotting type
  253. self.paint_plotting_radio = RadioSet([{'label': _('Normal'), 'value': 'normal'},
  254. {"label": _("Progressive"), "value": "progressive"}])
  255. plotting_label = QtWidgets.QLabel('%s:' % _("Plotting"))
  256. plotting_label.setToolTip(
  257. _("- 'Normal' - normal plotting, done at the end of the job\n"
  258. "- 'Progressive' - each shape is plotted after it is generated")
  259. )
  260. grid0.addWidget(plotting_label, 20, 0)
  261. grid0.addWidget(self.paint_plotting_radio, 20, 1)
  262. self.layout.addStretch()