GeometryAdvOptPrefGroupUI.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. from PyQt5 import QtWidgets
  2. from PyQt5.QtCore import QSettings
  3. from appGUI.GUIElements import FCDoubleSpinner, FCCheckBox, RadioSet, FCLabel, NumericalEvalTupleEntry, \
  4. NumericalEvalEntry, FCComboBox2
  5. from appGUI.preferences.OptionsGroupUI import OptionsGroupUI
  6. import gettext
  7. import appTranslation as fcTranslate
  8. import builtins
  9. fcTranslate.apply_language('strings')
  10. if '_' not in builtins.__dict__:
  11. _ = gettext.gettext
  12. settings = QSettings("Open Source", "FlatCAM")
  13. if settings.contains("machinist"):
  14. machinist_setting = settings.value('machinist', type=int)
  15. else:
  16. machinist_setting = 0
  17. class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
  18. def __init__(self, decimals=4, parent=None):
  19. # OptionsGroupUI.__init__(self, "Geometry Advanced Options Preferences", parent=parent)
  20. super(GeometryAdvOptPrefGroupUI, self).__init__(self, parent=parent)
  21. self.setTitle(str(_("Geometry Adv. Options")))
  22. self.decimals = decimals
  23. # ------------------------------
  24. # ## Advanced Options
  25. # ------------------------------
  26. self.geo_label = FCLabel('<b>%s:</b>' % _('Advanced Options'))
  27. self.geo_label.setToolTip(
  28. _("A list of advanced parameters.\n"
  29. "Those parameters are available only for\n"
  30. "Advanced App. Level.")
  31. )
  32. self.layout.addWidget(self.geo_label)
  33. grid1 = QtWidgets.QGridLayout()
  34. self.layout.addLayout(grid1)
  35. # Toolchange X,Y
  36. toolchange_xy_label = FCLabel('%s:' % _('Toolchange X-Y'))
  37. toolchange_xy_label.setToolTip(
  38. _("Toolchange X,Y position.")
  39. )
  40. self.toolchangexy_entry = NumericalEvalTupleEntry(border_color='#0069A9')
  41. grid1.addWidget(toolchange_xy_label, 1, 0)
  42. grid1.addWidget(self.toolchangexy_entry, 1, 1)
  43. # Start move Z
  44. startzlabel = FCLabel('%s:' % _('Start Z'))
  45. startzlabel.setToolTip(
  46. _("Height of the tool just after starting the work.\n"
  47. "Delete the value if you don't need this feature.")
  48. )
  49. self.gstartz_entry = NumericalEvalEntry(border_color='#0069A9')
  50. grid1.addWidget(startzlabel, 2, 0)
  51. grid1.addWidget(self.gstartz_entry, 2, 1)
  52. # Feedrate rapids
  53. fr_rapid_label = FCLabel('%s:' % _('Feedrate Rapids'))
  54. fr_rapid_label.setToolTip(
  55. _("Cutting speed in the XY plane\n"
  56. "(in units per minute).\n"
  57. "This is for the rapid move G00.\n"
  58. "It is useful only for Marlin,\n"
  59. "ignore for any other cases.")
  60. )
  61. self.feedrate_rapid_entry = FCDoubleSpinner()
  62. self.feedrate_rapid_entry.set_range(0, 910000.0000)
  63. self.feedrate_rapid_entry.set_precision(self.decimals)
  64. self.feedrate_rapid_entry.setSingleStep(0.1)
  65. self.feedrate_rapid_entry.setWrapping(True)
  66. grid1.addWidget(fr_rapid_label, 4, 0)
  67. grid1.addWidget(self.feedrate_rapid_entry, 4, 1)
  68. # End move extra cut
  69. self.extracut_cb = FCCheckBox('%s' % _('Re-cut'))
  70. self.extracut_cb.setToolTip(
  71. _("In order to remove possible\n"
  72. "copper leftovers where first cut\n"
  73. "meet with last cut, we generate an\n"
  74. "extended cut over the first cut section.")
  75. )
  76. self.e_cut_entry = FCDoubleSpinner()
  77. self.e_cut_entry.set_range(0, 99999)
  78. self.e_cut_entry.set_precision(self.decimals)
  79. self.e_cut_entry.setSingleStep(0.1)
  80. self.e_cut_entry.setWrapping(True)
  81. self.e_cut_entry.setToolTip(
  82. _("In order to remove possible\n"
  83. "copper leftovers where first cut\n"
  84. "meet with last cut, we generate an\n"
  85. "extended cut over the first cut section.")
  86. )
  87. grid1.addWidget(self.extracut_cb, 5, 0)
  88. grid1.addWidget(self.e_cut_entry, 5, 1)
  89. # Probe depth
  90. self.pdepth_label = FCLabel('%s:' % _("Probe Z depth"))
  91. self.pdepth_label.setToolTip(
  92. _("The maximum depth that the probe is allowed\n"
  93. "to probe. Negative value, in current units.")
  94. )
  95. self.pdepth_entry = FCDoubleSpinner()
  96. self.pdepth_entry.set_range(-99999, 0.0000)
  97. self.pdepth_entry.set_precision(self.decimals)
  98. self.pdepth_entry.setSingleStep(0.1)
  99. self.pdepth_entry.setWrapping(True)
  100. grid1.addWidget(self.pdepth_label, 6, 0)
  101. grid1.addWidget(self.pdepth_entry, 6, 1)
  102. # Probe feedrate
  103. self.feedrate_probe_label = FCLabel('%s:' % _("Feedrate Probe"))
  104. self.feedrate_probe_label.setToolTip(
  105. _("The feedrate used while the probe is probing.")
  106. )
  107. self.feedrate_probe_entry = FCDoubleSpinner()
  108. self.feedrate_probe_entry.set_range(0, 910000.0000)
  109. self.feedrate_probe_entry.set_precision(self.decimals)
  110. self.feedrate_probe_entry.setSingleStep(0.1)
  111. self.feedrate_probe_entry.setWrapping(True)
  112. grid1.addWidget(self.feedrate_probe_label, 7, 0)
  113. grid1.addWidget(self.feedrate_probe_entry, 7, 1)
  114. # Spindle direction
  115. spindle_dir_label = FCLabel('%s:' % _('Spindle direction'))
  116. spindle_dir_label.setToolTip(
  117. _("This sets the direction that the spindle is rotating.\n"
  118. "It can be either:\n"
  119. "- CW = clockwise or\n"
  120. "- CCW = counter clockwise")
  121. )
  122. self.spindledir_radio = RadioSet([{'label': _('CW'), 'value': 'CW'},
  123. {'label': _('CCW'), 'value': 'CCW'}])
  124. grid1.addWidget(spindle_dir_label, 8, 0)
  125. grid1.addWidget(self.spindledir_radio, 8, 1)
  126. # Fast Move from Z Toolchange
  127. self.fplunge_cb = FCCheckBox('%s' % _('Fast Plunge'))
  128. self.fplunge_cb.setToolTip(
  129. _("By checking this, the vertical move from\n"
  130. "Z_Toolchange to Z_move is done with G0,\n"
  131. "meaning the fastest speed available.\n"
  132. "WARNING: the move is done at Toolchange X,Y coords.")
  133. )
  134. grid1.addWidget(self.fplunge_cb, 9, 0, 1, 2)
  135. # Size of trace segment on X axis
  136. segx_label = FCLabel('%s:' % _("Segment X size"))
  137. segx_label.setToolTip(
  138. _("The size of the trace segment on the X axis.\n"
  139. "Useful for auto-leveling.\n"
  140. "A value of 0 means no segmentation on the X axis.")
  141. )
  142. self.segx_entry = FCDoubleSpinner()
  143. self.segx_entry.set_range(0, 99999)
  144. self.segx_entry.set_precision(self.decimals)
  145. self.segx_entry.setSingleStep(0.1)
  146. self.segx_entry.setWrapping(True)
  147. grid1.addWidget(segx_label, 10, 0)
  148. grid1.addWidget(self.segx_entry, 10, 1)
  149. # Size of trace segment on Y axis
  150. segy_label = FCLabel('%s:' % _("Segment Y size"))
  151. segy_label.setToolTip(
  152. _("The size of the trace segment on the Y axis.\n"
  153. "Useful for auto-leveling.\n"
  154. "A value of 0 means no segmentation on the Y axis.")
  155. )
  156. self.segy_entry = FCDoubleSpinner()
  157. self.segy_entry.set_range(0, 99999)
  158. self.segy_entry.set_precision(self.decimals)
  159. self.segy_entry.setSingleStep(0.1)
  160. self.segy_entry.setWrapping(True)
  161. grid1.addWidget(segy_label, 11, 0)
  162. grid1.addWidget(self.segy_entry, 11, 1)
  163. separator_line = QtWidgets.QFrame()
  164. separator_line.setFrameShape(QtWidgets.QFrame.HLine)
  165. separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
  166. grid1.addWidget(separator_line, 12, 0, 1, 2)
  167. # -----------------------------
  168. # --- Area Exclusion ----------
  169. # -----------------------------
  170. self.area_exc_label = FCLabel('<b>%s:</b>' % _('Area Exclusion'))
  171. self.area_exc_label.setToolTip(
  172. _("Area exclusion parameters.")
  173. )
  174. grid1.addWidget(self.area_exc_label, 13, 0, 1, 2)
  175. # Exclusion Area CB
  176. self.exclusion_cb = FCCheckBox('%s' % _("Exclusion areas"))
  177. self.exclusion_cb.setToolTip(
  178. _(
  179. "Include exclusion areas.\n"
  180. "In those areas the travel of the tools\n"
  181. "is forbidden."
  182. )
  183. )
  184. grid1.addWidget(self.exclusion_cb, 14, 0, 1, 2)
  185. # Area Selection shape
  186. self.area_shape_label = FCLabel('%s:' % _("Shape"))
  187. self.area_shape_label.setToolTip(
  188. _("The kind of selection shape used for area selection.")
  189. )
  190. self.area_shape_radio = RadioSet([{'label': _("Square"), 'value': 'square'},
  191. {'label': _("Polygon"), 'value': 'polygon'}])
  192. grid1.addWidget(self.area_shape_label, 15, 0)
  193. grid1.addWidget(self.area_shape_radio, 15, 1)
  194. # Chose Strategy
  195. self.strategy_label = FCLabel('%s:' % _("Strategy"))
  196. self.strategy_label.setToolTip(_("The strategy followed when encountering an exclusion area.\n"
  197. "Can be:\n"
  198. "- Over -> when encountering the area, the tool will go to a set height\n"
  199. "- Around -> will avoid the exclusion area by going around the area"))
  200. self.strategy_radio = RadioSet([{'label': _('Over'), 'value': 'over'},
  201. {'label': _('Around'), 'value': 'around'}])
  202. grid1.addWidget(self.strategy_label, 16, 0)
  203. grid1.addWidget(self.strategy_radio, 16, 1)
  204. # Over Z
  205. self.over_z_label = FCLabel('%s:' % _("Over Z"))
  206. self.over_z_label.setToolTip(_("The height Z to which the tool will rise in order to avoid\n"
  207. "an interdiction area."))
  208. self.over_z_entry = FCDoubleSpinner()
  209. self.over_z_entry.set_range(0.000, 10000.0000)
  210. self.over_z_entry.set_precision(self.decimals)
  211. grid1.addWidget(self.over_z_label, 18, 0)
  212. grid1.addWidget(self.over_z_entry, 18, 1)
  213. separator_line = QtWidgets.QFrame()
  214. separator_line.setFrameShape(QtWidgets.QFrame.HLine)
  215. separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
  216. grid1.addWidget(separator_line, 20, 0, 1, 2)
  217. # -----------------------------
  218. # --- Area POLISH ----------
  219. # -----------------------------
  220. # Add Polish
  221. self.polish_cb = FCCheckBox(label=_('Add Polish'))
  222. self.polish_cb.setToolTip(_(
  223. "Will add a Paint section at the end of the GCode.\n"
  224. "A metallic brush will clean the material after milling."))
  225. grid1.addWidget(self.polish_cb, 22, 0, 1, 2)
  226. # Polish Tool Diameter
  227. self.polish_dia_lbl = FCLabel('%s:' % _('Tool Dia'))
  228. self.polish_dia_lbl.setToolTip(
  229. _("Diameter for the polishing tool.")
  230. )
  231. self.polish_dia_entry = FCDoubleSpinner()
  232. self.polish_dia_entry.set_precision(self.decimals)
  233. self.polish_dia_entry.set_range(0.000, 10000.0000)
  234. grid1.addWidget(self.polish_dia_lbl, 24, 0)
  235. grid1.addWidget(self.polish_dia_entry, 24, 1)
  236. # Polish Travel Z
  237. self.polish_travelz_lbl = FCLabel('%s:' % _('Travel Z'))
  238. self.polish_travelz_lbl.setToolTip(
  239. _("Height of the tool when\n"
  240. "moving without cutting.")
  241. )
  242. self.polish_travelz_entry = FCDoubleSpinner()
  243. self.polish_travelz_entry.set_precision(self.decimals)
  244. self.polish_travelz_entry.set_range(0.00000, 10000.00000)
  245. self.polish_travelz_entry.setSingleStep(0.1)
  246. grid1.addWidget(self.polish_travelz_lbl, 26, 0)
  247. grid1.addWidget(self.polish_travelz_entry, 26, 1)
  248. # Polish Pressure
  249. self.polish_pressure_lbl = FCLabel('%s:' % _('Pressure'))
  250. self.polish_pressure_lbl.setToolTip(
  251. _("Negative value. The higher the absolute value\n"
  252. "the stronger the pressure of the brush on the material.")
  253. )
  254. self.polish_pressure_entry = FCDoubleSpinner()
  255. self.polish_pressure_entry.set_precision(self.decimals)
  256. self.polish_pressure_entry.set_range(-10000.0000, 10000.0000)
  257. grid1.addWidget(self.polish_pressure_lbl, 28, 0)
  258. grid1.addWidget(self.polish_pressure_entry, 28, 1)
  259. # Polish Margin
  260. self.polish_margin_lbl = FCLabel('%s:' % _('Margin'))
  261. self.polish_margin_lbl.setToolTip(
  262. _("Bounding box margin.")
  263. )
  264. self.polish_margin_entry = FCDoubleSpinner()
  265. self.polish_margin_entry.set_precision(self.decimals)
  266. self.polish_margin_entry.set_range(-10000.0000, 10000.0000)
  267. grid1.addWidget(self.polish_margin_lbl, 30, 0)
  268. grid1.addWidget(self.polish_margin_entry, 30, 1)
  269. # Polish Overlap
  270. self.polish_over_lbl = FCLabel('%s:' % _('Overlap'))
  271. self.polish_over_lbl.setToolTip(
  272. _("How much (percentage) of the tool width to overlap each tool pass.")
  273. )
  274. self.polish_over_entry = FCDoubleSpinner(suffix='%')
  275. self.polish_over_entry.set_precision(self.decimals)
  276. self.polish_over_entry.setWrapping(True)
  277. self.polish_over_entry.set_range(0.0000, 99.9999)
  278. self.polish_over_entry.setSingleStep(0.1)
  279. grid1.addWidget(self.polish_over_lbl, 32, 0)
  280. grid1.addWidget(self.polish_over_entry, 32, 1)
  281. # Polish Method
  282. self.polish_method_lbl = FCLabel('%s:' % _('Method'))
  283. self.polish_method_lbl.setToolTip(
  284. _("Algorithm for polishing:\n"
  285. "- Standard: Fixed step inwards.\n"
  286. "- Seed-based: Outwards from seed.\n"
  287. "- Line-based: Parallel lines.")
  288. )
  289. self.polish_method_combo = FCComboBox2()
  290. self.polish_method_combo.addItems(
  291. [_("Standard"), _("Seed"), _("Lines")]
  292. )
  293. grid1.addWidget(self.polish_method_lbl, 34, 0)
  294. grid1.addWidget(self.polish_method_combo, 34, 1)
  295. self.layout.addStretch()