diff --git a/CHANGELOG.md b/CHANGELOG.md index f100b501..7ea57002 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,9 @@ CHANGELOG for FlatCAM beta - NCC Tool - upgraded the UI and added the functionality that now adding a new tool is done by first searching the Tools DB for a suitable tool and if fails then it adds an default tool - NCC Tool - on start will attempt to search in the Tools DB for the default tools and if found will load them from the DB - fixes in NCC, Paint and Isolation Tool due of recent changes +- modified the Tools Database and Preferences with the new parameters from CutOut Tool +- changes in Tool Cutout: now on Cutout Tool start the app will look into Tools Database and search for a tool with same diameter (or within the set tolerance) as the one from Preferences and load it if found or load a default tool if not +- Tool Cutout - this Tool can now load tools from Tools Database through buttons in the Cutout Tool 27.08.2020 diff --git a/appDatabase.py b/appDatabase.py index 0fb7dacb..6e333c71 100644 --- a/appDatabase.py +++ b/appDatabase.py @@ -1,6 +1,6 @@ from PyQt5 import QtGui, QtCore, QtWidgets from appGUI.GUIElements import FCTable, FCEntry, FCButton, FCDoubleSpinner, FCComboBox, FCCheckBox, FCSpinner, \ - FCTree, RadioSet, FCFileSaveDialog + FCTree, RadioSet, FCFileSaveDialog, FCLabel from camlib import to_dict import sys @@ -74,7 +74,7 @@ class ToolsDB(QtWidgets.QWidget): new_vlay = QtWidgets.QVBoxLayout() layout.addLayout(new_vlay) - # new_tool_lbl = QtWidgets.QLabel('%s' % _("New Tool")) + # new_tool_lbl = FCLabel('%s' % _("New Tool")) # new_vlay.addWidget(new_tool_lbl, alignment=QtCore.Qt.AlignBottom) self.buttons_frame = QtWidgets.QFrame() @@ -1121,7 +1121,7 @@ class ToolsDB2UI: self.description_vlay.addStretch() # Tool Name - self.name_label = QtWidgets.QLabel('%s:' % _('Name')) + self.name_label = FCLabel('%s:' % _('Name')) self.name_label.setToolTip( _("Tool name.\n" "This is not used in the app, it's function\n" @@ -1134,7 +1134,7 @@ class ToolsDB2UI: self.grid_tool.addWidget(self.name_entry, 0, 1) # Tool Dia - self.dia_label = QtWidgets.QLabel('%s:' % _('Diameter')) + self.dia_label = FCLabel('%s:' % _('Diameter')) self.dia_label.setToolTip( _("Tool Diameter.")) @@ -1147,7 +1147,7 @@ class ToolsDB2UI: self.grid_tool.addWidget(self.dia_entry, 1, 1) # Tool Tolerance - self.tol_label = QtWidgets.QLabel("%s:" % _("Diameter Tolerance")) + self.tol_label = FCLabel("%s:" % _("Diameter Tolerance")) self.tol_label.setToolTip( _("Tool tolerance. If there is a tool in the targeted tools table with\n" "the value within the limits then this tool from DB will be used.") @@ -1155,7 +1155,7 @@ class ToolsDB2UI: self.grid_tool.addWidget(self.tol_label, 2, 0, 1, 2) # Tolerance Min Limit - self.min_limit_label = QtWidgets.QLabel('%s:' % _("Min")) + self.min_limit_label = FCLabel('%s:' % _("Min")) self.min_limit_label.setToolTip( _("Set the tool tolerance minimum.") ) @@ -1169,7 +1169,7 @@ class ToolsDB2UI: self.grid_tool.addWidget(self.tol_min_entry, 4, 1) # Tolerance Min Limit - self.max_limit_label = QtWidgets.QLabel('%s:' % _("Max")) + self.max_limit_label = FCLabel('%s:' % _("Max")) self.max_limit_label.setToolTip( _("Set the tool tolerance maximum.") ) @@ -1183,7 +1183,7 @@ class ToolsDB2UI: self.grid_tool.addWidget(self.tol_max_entry, 6, 1) # Tool Object Type - self.tool_op_label = QtWidgets.QLabel('%s:' % _('Operation')) + self.tool_op_label = FCLabel('%s:' % _('Operation')) self.tool_op_label.setToolTip( _("The kind of Application Tool where this tool is to be used.")) @@ -1205,7 +1205,7 @@ class ToolsDB2UI: self.milling_vlay.addStretch() # Tool Shape - self.shape_label = QtWidgets.QLabel('%s:' % _('Shape')) + self.shape_label = FCLabel('%s:' % _('Shape')) self.shape_label.setToolTip( _("Tool Shape. \n" "Can be:\n" @@ -1221,7 +1221,7 @@ class ToolsDB2UI: self.grid0.addWidget(self.shape_combo, 2, 1) # V-Dia - self.vdia_label = QtWidgets.QLabel('%s:' % _("V-Dia")) + self.vdia_label = FCLabel('%s:' % _("V-Dia")) self.vdia_label.setToolTip( _("V-Dia.\n" "Diameter of the tip for V-Shape Tools.")) @@ -1235,7 +1235,7 @@ class ToolsDB2UI: self.grid0.addWidget(self.vdia_entry, 4, 1) # V-Angle - self.vangle_label = QtWidgets.QLabel('%s:' % _("V-Angle")) + self.vangle_label = FCLabel('%s:' % _("V-Angle")) self.vangle_label.setToolTip( _("V-Agle.\n" "Angle at the tip for the V-Shape Tools.")) @@ -1254,7 +1254,7 @@ class ToolsDB2UI: self.grid0.addWidget(separator_line, 8, 0, 1, 2) # Tool Type - self.type_label = QtWidgets.QLabel('%s:' % _("Tool Type")) + self.type_label = FCLabel('%s:' % _("Tool Type")) self.type_label.setToolTip( _("Tool Type.\n" "Can be:\n" @@ -1270,7 +1270,7 @@ class ToolsDB2UI: self.grid0.addWidget(self.type_combo, 10, 1) # Tool Offset - self.tooloffset_label = QtWidgets.QLabel('%s:' % _('Tool Offset')) + self.tooloffset_label = FCLabel('%s:' % _('Tool Offset')) self.tooloffset_label.setToolTip( _("Tool Offset.\n" "Can be of a few types:\n" @@ -1287,7 +1287,7 @@ class ToolsDB2UI: self.grid0.addWidget(self.tooloffset_combo, 12, 1) # Custom Offset - self.custom_offset_label = QtWidgets.QLabel('%s:' % _("Custom Offset")) + self.custom_offset_label = FCLabel('%s:' % _("Custom Offset")) self.custom_offset_label.setToolTip( _("Custom Offset.\n" "A value to be used as offset from the current path.")) @@ -1306,7 +1306,7 @@ class ToolsDB2UI: self.grid0.addWidget(separator_line, 16, 0, 1, 2) # Cut Z - self.cutz_label = QtWidgets.QLabel('%s:' % _("Cut Z")) + self.cutz_label = FCLabel('%s:' % _("Cut Z")) self.cutz_label.setToolTip( _("Cutting Depth.\n" "The depth at which to cut into material.")) @@ -1320,7 +1320,7 @@ class ToolsDB2UI: self.grid0.addWidget(self.cutz_entry, 18, 1) # Multi Depth - self.multidepth_label = QtWidgets.QLabel('%s:' % _("MultiDepth")) + self.multidepth_label = FCLabel('%s:' % _("MultiDepth")) self.multidepth_label.setToolTip( _("Multi Depth.\n" "Selecting this will allow cutting in multiple passes,\n" @@ -1333,7 +1333,7 @@ class ToolsDB2UI: self.grid0.addWidget(self.multidepth_cb, 20, 1) # Depth Per Pass - self.dpp_label = QtWidgets.QLabel('%s:' % _("DPP")) + self.dpp_label = FCLabel('%s:' % _("DPP")) self.dpp_label.setToolTip( _("DPP. Depth per Pass.\n" "The value used to cut into material on each pass.")) @@ -1347,7 +1347,7 @@ class ToolsDB2UI: self.grid0.addWidget(self.multidepth_entry, 22, 1) # Travel Z - self.travelz_label = QtWidgets.QLabel('%s:' % _("Travel Z")) + self.travelz_label = FCLabel('%s:' % _("Travel Z")) self.travelz_label.setToolTip( _("Clearance Height.\n" "Height at which the milling bit will travel between cuts,\n" @@ -1362,7 +1362,7 @@ class ToolsDB2UI: self.grid0.addWidget(self.travelz_entry, 24, 1) # Extra Cut - self.ecut_label = QtWidgets.QLabel('%s:' % _("ExtraCut")) + self.ecut_label = FCLabel('%s:' % _("ExtraCut")) self.ecut_label.setToolTip( _("Extra Cut.\n" "If checked, after a isolation is finished an extra cut\n" @@ -1377,7 +1377,7 @@ class ToolsDB2UI: self.grid0.addWidget(self.ecut_cb, 26, 1) # Extra Cut Length - self.ecut_length_label = QtWidgets.QLabel('%s:' % _("E-Cut Length")) + self.ecut_length_label = FCLabel('%s:' % _("E-Cut Length")) self.ecut_length_label.setToolTip( _("Extra Cut length.\n" "If checked, after a isolation is finished an extra cut\n" @@ -1400,7 +1400,7 @@ class ToolsDB2UI: self.grid0.addWidget(separator_line, 30, 0, 1, 2) # Feedrate X-Y - self.frxy_label = QtWidgets.QLabel('%s:' % _("Feedrate X-Y")) + self.frxy_label = FCLabel('%s:' % _("Feedrate X-Y")) self.frxy_label.setToolTip( _("Feedrate X-Y. Feedrate\n" "The speed on XY plane used while cutting into material.")) @@ -1414,7 +1414,7 @@ class ToolsDB2UI: self.grid0.addWidget(self.frxy_entry, 32, 1) # Feedrate Z - self.frz_label = QtWidgets.QLabel('%s:' % _("Feedrate Z")) + self.frz_label = FCLabel('%s:' % _("Feedrate Z")) self.frz_label.setToolTip( _("Feedrate Z\n" "The speed on Z plane.")) @@ -1428,7 +1428,7 @@ class ToolsDB2UI: self.grid0.addWidget(self.frz_entry, 34, 1) # Feedrate Rapids - self.frapids_label = QtWidgets.QLabel('%s:' % _("FR Rapids")) + self.frapids_label = FCLabel('%s:' % _("FR Rapids")) self.frapids_label.setToolTip( _("FR Rapids. Feedrate Rapids\n" "Speed used while moving as fast as possible.\n" @@ -1449,7 +1449,7 @@ class ToolsDB2UI: self.grid0.addWidget(separator_line, 38, 0, 1, 2) # Spindle Spped - self.spindle_label = QtWidgets.QLabel('%s:' % _("Spindle Speed")) + self.spindle_label = FCLabel('%s:' % _("Spindle Speed")) self.spindle_label.setToolTip( _("Spindle Speed.\n" "If it's left empty it will not be used.\n" @@ -1464,7 +1464,7 @@ class ToolsDB2UI: self.grid0.addWidget(self.spindle_entry, 40, 1) # Dwell - self.dwell_label = QtWidgets.QLabel('%s:' % _("Dwell")) + self.dwell_label = FCLabel('%s:' % _("Dwell")) self.dwell_label.setToolTip( _("Dwell.\n" "Check this if a delay is needed to allow\n" @@ -1477,7 +1477,7 @@ class ToolsDB2UI: self.grid0.addWidget(self.dwell_cb, 42, 1) # Dwell Time - self.dwelltime_label = QtWidgets.QLabel('%s:' % _("Dwelltime")) + self.dwelltime_label = FCLabel('%s:' % _("Dwelltime")) self.dwelltime_label.setToolTip( _("Dwell Time.\n" "A delay used to allow the motor spindle reach its set speed.")) @@ -1501,7 +1501,7 @@ class ToolsDB2UI: self.ncc_vlay.addStretch() # Operation - op_label = QtWidgets.QLabel('%s:' % _('Operation')) + op_label = FCLabel('%s:' % _('Operation')) op_label.setToolTip( _("The 'Operation' can be:\n" "- Isolation -> will ensure that the non-copper clearing is always complete.\n" @@ -1519,7 +1519,7 @@ class ToolsDB2UI: self.grid2.addWidget(self.op_radio, 13, 1) # Milling Type Radio Button - self.milling_type_label = QtWidgets.QLabel('%s:' % _('Milling Type')) + self.milling_type_label = FCLabel('%s:' % _('Milling Type')) self.milling_type_label.setToolTip( _("Milling type when the selected tool is of type: 'iso_op':\n" "- climb / best for precision milling and to reduce tool usage\n" @@ -1539,7 +1539,7 @@ class ToolsDB2UI: self.grid2.addWidget(self.milling_type_radio, 14, 1) # Overlap Entry - nccoverlabel = QtWidgets.QLabel('%s:' % _('Overlap')) + nccoverlabel = FCLabel('%s:' % _('Overlap')) nccoverlabel.setToolTip( _("How much (percentage) of the tool width to overlap each tool pass.\n" "Adjust the value starting with lower values\n" @@ -1560,7 +1560,7 @@ class ToolsDB2UI: self.grid2.addWidget(self.ncc_overlap_entry, 15, 1) # Margin - nccmarginlabel = QtWidgets.QLabel('%s:' % _('Margin')) + nccmarginlabel = FCLabel('%s:' % _('Margin')) nccmarginlabel.setToolTip( _("Bounding box margin.") ) @@ -1573,7 +1573,7 @@ class ToolsDB2UI: self.grid2.addWidget(self.ncc_margin_entry, 16, 1) # Method - methodlabel = QtWidgets.QLabel('%s:' % _('Method')) + methodlabel = FCLabel('%s:' % _('Method')) methodlabel.setToolTip( _("Algorithm for copper clearing:\n" "- Standard: Fixed step inwards.\n" @@ -1648,7 +1648,7 @@ class ToolsDB2UI: self.paint_vlay.addStretch() # Overlap - ovlabel = QtWidgets.QLabel('%s:' % _('Overlap')) + ovlabel = FCLabel('%s:' % _('Overlap')) ovlabel.setToolTip( _("How much (percentage) of the tool width to overlap each tool pass.\n" "Adjust the value starting with lower values\n" @@ -1669,7 +1669,7 @@ class ToolsDB2UI: self.grid3.addWidget(self.paintoverlap_entry, 1, 1) # Margin - marginlabel = QtWidgets.QLabel('%s:' % _('Offset')) + marginlabel = FCLabel('%s:' % _('Offset')) marginlabel.setToolTip( _("Distance by which to avoid\n" "the edges of the polygon to\n" @@ -1684,7 +1684,7 @@ class ToolsDB2UI: self.grid3.addWidget(self.paint_offset_entry, 2, 1) # Method - methodlabel = QtWidgets.QLabel('%s:' % _('Method')) + methodlabel = FCLabel('%s:' % _('Method')) methodlabel.setToolTip( _("Algorithm for painting:\n" "- Standard: Fixed step inwards.\n" @@ -1737,7 +1737,7 @@ class ToolsDB2UI: self.iso_vlay.addStretch() # Passes - passlabel = QtWidgets.QLabel('%s:' % _('Passes')) + passlabel = FCLabel('%s:' % _('Passes')) passlabel.setToolTip( _("Width of the isolation gap in\n" "number (integer) of tool widths.") @@ -1750,7 +1750,7 @@ class ToolsDB2UI: self.grid4.addWidget(self.passes_entry, 0, 1) # Overlap Entry - overlabel = QtWidgets.QLabel('%s:' % _('Overlap')) + overlabel = FCLabel('%s:' % _('Overlap')) overlabel.setToolTip( _("How much (percentage) of the tool width to overlap each tool pass.") ) @@ -1765,7 +1765,7 @@ class ToolsDB2UI: self.grid4.addWidget(self.iso_overlap_entry, 2, 1) # Milling Type Radio Button - self.milling_type_label = QtWidgets.QLabel('%s:' % _('Milling Type')) + self.milling_type_label = FCLabel('%s:' % _('Milling Type')) self.milling_type_label.setToolTip( _("Milling type when the selected tool is of type: 'iso_op':\n" "- climb / best for precision milling and to reduce tool usage\n" @@ -1785,7 +1785,7 @@ class ToolsDB2UI: self.grid4.addWidget(self.milling_type_radio, 4, 1) # Follow - self.follow_label = QtWidgets.QLabel('%s:' % _('Follow')) + self.follow_label = FCLabel('%s:' % _('Follow')) self.follow_label.setToolTip( _("Generate a 'Follow' geometry.\n" "This means that it will cut through\n" @@ -1802,7 +1802,7 @@ class ToolsDB2UI: self.grid4.addWidget(self.follow_cb, 6, 1) # Isolation Type - self.iso_type_label = QtWidgets.QLabel('%s:' % _('Isolation Type')) + self.iso_type_label = FCLabel('%s:' % _('Isolation Type')) self.iso_type_label.setToolTip( _("Choose how the isolation will be executed:\n" "- 'Full' -> complete isolation of polygons\n" @@ -1831,7 +1831,7 @@ class ToolsDB2UI: self.drill_vlay.addStretch() # Cut Z - self.cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z')) + self.cutzlabel = FCLabel('%s:' % _('Cut Z')) self.cutzlabel.setToolTip( _("Drill depth (negative)\n" "below the copper surface.") @@ -1852,7 +1852,7 @@ class ToolsDB2UI: self.grid5.addWidget(self.cutz_drill_entry, 4, 1) # Tool Offset - self.tool_offset_label = QtWidgets.QLabel('%s:' % _('Offset Z')) + self.tool_offset_label = FCLabel('%s:' % _('Offset Z')) self.tool_offset_label.setToolTip( _("Some drill bits (the larger ones) need to drill deeper\n" "to create the desired exit hole diameter due of the tip shape.\n" @@ -1868,7 +1868,7 @@ class ToolsDB2UI: self.grid5.addWidget(self.offset_drill_entry, 6, 1) # Multi-Depth - self.multidepth_drill_label = QtWidgets.QLabel('%s:' % _("MultiDepth")) + self.multidepth_drill_label = FCLabel('%s:' % _("MultiDepth")) self.multidepth_drill_label.setToolTip( _( "Use multiple passes to limit\n" @@ -1884,7 +1884,7 @@ class ToolsDB2UI: self.grid5.addWidget(self.mpass_drill_cb, 7, 1) # Depth Per Pass - self.dpp_drill_label = QtWidgets.QLabel('%s:' % _("DPP")) + self.dpp_drill_label = FCLabel('%s:' % _("DPP")) self.dpp_drill_label.setToolTip( _("DPP. Depth per Pass.\n" "The value used to cut into material on each pass.")) @@ -1900,7 +1900,7 @@ class ToolsDB2UI: self.grid5.addWidget(self.maxdepth_drill_entry, 8, 1) # Travel Z (z_move) - self.travelzlabel = QtWidgets.QLabel('%s:' % _('Travel Z')) + self.travelzlabel = FCLabel('%s:' % _('Travel Z')) self.travelzlabel.setToolTip( _("Tool height when travelling\n" "across the XY plane.") @@ -1926,7 +1926,7 @@ class ToolsDB2UI: self.grid5.addWidget(separator_line, 12, 0, 1, 2) # Excellon Feedrate Z - self.frzlabel = QtWidgets.QLabel('%s:' % _('Feedrate Z')) + self.frzlabel = FCLabel('%s:' % _('Feedrate Z')) self.frzlabel.setToolTip( _("Tool speed while drilling\n" "(in units per minute).\n" @@ -1943,7 +1943,7 @@ class ToolsDB2UI: self.grid5.addWidget(self.feedrate_z_drill_entry, 14, 1) # Excellon Rapid Feedrate - self.feedrate_rapid_label = QtWidgets.QLabel('%s:' % _('Feedrate Rapids')) + self.feedrate_rapid_label = FCLabel('%s:' % _('Feedrate Rapids')) self.feedrate_rapid_label.setToolTip( _("Tool speed while drilling\n" "(in units per minute).\n" @@ -1966,7 +1966,7 @@ class ToolsDB2UI: self.grid5.addWidget(separator_line, 18, 0, 1, 2) # Spindlespeed - self.spindle_label = QtWidgets.QLabel('%s:' % _('Spindle speed')) + self.spindle_label = FCLabel('%s:' % _('Spindle speed')) self.spindle_label.setToolTip( _("Speed of the spindle\n" "in RPM (optional)") @@ -1981,7 +1981,7 @@ class ToolsDB2UI: self.grid5.addWidget(self.spindlespeed_drill_entry, 20, 1) # Dwell - self.dwell_drill_label = QtWidgets.QLabel('%s:' % _("Dwell")) + self.dwell_drill_label = FCLabel('%s:' % _("Dwell")) self.dwell_drill_label.setToolTip( _("Dwell.\n" "Check this if a delay is needed to allow\n" @@ -1994,7 +1994,7 @@ class ToolsDB2UI: self.grid5.addWidget(self.dwell_drill_cb, 21, 1) # Dwelltime - self.dwelltime_drill_lbl = QtWidgets.QLabel('%s:' % _('Dwelltime')) + self.dwelltime_drill_lbl = FCLabel('%s:' % _('Dwelltime')) self.dwelltime_drill_lbl.setToolTip( _("Dwell Time.\n" "A delay used to allow the motor spindle reach its set speed.")) @@ -2013,7 +2013,7 @@ class ToolsDB2UI: self.grid5.addWidget(separator_line, 24, 0, 1, 2) # Drill slots - self.drill_slots_drill_lbl = QtWidgets.QLabel('%s:' % _('Drill slots')) + self.drill_slots_drill_lbl = FCLabel('%s:' % _('Drill slots')) self.drill_slots_drill_lbl.setToolTip( _("If the selected tool has slots then they will be drilled.") ) @@ -2024,7 +2024,7 @@ class ToolsDB2UI: self.grid5.addWidget(self.drill_slots_drill_cb, 26, 1) # Drill Overlap - self.drill_overlap_label = QtWidgets.QLabel('%s:' % _('Overlap')) + self.drill_overlap_label = FCLabel('%s:' % _('Overlap')) self.drill_overlap_label.setToolTip( _("How much (percentage) of the tool diameter to overlap previous drill hole.") ) @@ -2040,7 +2040,7 @@ class ToolsDB2UI: self.grid5.addWidget(self.drill_overlap_drill_entry, 28, 1) # Last drill in slot - self.last_drill_drill_lbl = QtWidgets.QLabel('%s:' % _('Last drill')) + self.last_drill_drill_lbl = FCLabel('%s:' % _('Last drill')) self.last_drill_drill_lbl.setToolTip( _("If the slot length is not completely covered by drill holes,\n" "add a drill hole on the slot end point.") @@ -2068,7 +2068,7 @@ class ToolsDB2UI: self.cutout_margin_entry.set_precision(self.decimals) self.cutout_margin_entry.setObjectName('gdb_ct_margin') - self.cutout_margin_label = QtWidgets.QLabel('%s:' % _("Margin")) + self.cutout_margin_label = FCLabel('%s:' % _("Margin")) self.cutout_margin_label.setToolTip( _("Margin over bounds. A positive value here\n" "will make the cutout of the PCB further from\n" @@ -2082,7 +2082,7 @@ class ToolsDB2UI: self.cutout_gapsize.set_precision(self.decimals) self.cutout_gapsize.setObjectName('gdb_ct_gapsize') - self.cutout_gapsize_label = QtWidgets.QLabel('%s:' % _("Gap size")) + self.cutout_gapsize_label = FCLabel('%s:' % _("Gap size")) self.cutout_gapsize_label.setToolTip( _("The size of the bridge gaps in the cutout\n" "used to keep the board connected to\n" @@ -2092,6 +2092,73 @@ class ToolsDB2UI: self.grid6.addWidget(self.cutout_gapsize_label, 13, 0) self.grid6.addWidget(self.cutout_gapsize, 13, 1) + # Gap Type + self.gaptype_label = FCLabel('%s:' % _("Gap type")) + self.gaptype_label.setToolTip( + _("The type of gap:\n" + "- Bridge -> the cutout will be interrupted by bridges\n" + "- Thin -> same as 'bridge' but it will be thinner by partially milling the gap\n" + "- M-Bites -> 'Mouse Bites' - same as 'bridge' but covered with drill holes") + ) + + self.gaptype_radio = RadioSet( + [ + {'label': _('Bridge'), 'value': 'b'}, + {'label': _('Thin'), 'value': 'bt'}, + {'label': "M-Bites", 'value': 'mb'} + ], + stretch=True + ) + self.gaptype_radio.setObjectName('gdb_ct_gap_type') + + self.grid6.addWidget(self.gaptype_label, 15, 0) + self.grid6.addWidget(self.gaptype_radio, 15, 1) + + # Thin gaps Depth + self.thin_depth_label = FCLabel('%s:' % _("Depth")) + self.thin_depth_label.setToolTip( + _("The depth until the milling is done\n" + "in order to thin the gaps.") + ) + self.thin_depth_entry = FCDoubleSpinner(callback=self.confirmation_message) + self.thin_depth_entry.set_precision(self.decimals) + self.thin_depth_entry.setObjectName('gdb_ct_gap_depth') + + if self.machinist_setting == 0: + self.thin_depth_entry.setRange(-9999.9999, -0.00001) + else: + self.thin_depth_entry.setRange(-9999.9999, 9999.9999) + self.thin_depth_entry.setSingleStep(0.1) + + self.grid6.addWidget(self.thin_depth_label, 17, 0) + self.grid6.addWidget(self.thin_depth_entry, 17, 1) + + # Mouse Bites Tool Diameter + self.mb_dia_label = FCLabel('%s:' % _("Tool Diameter")) + self.mb_dia_label.setToolTip( + _("The drill hole diameter when doing mpuse bites.") + ) + self.mb_dia_entry = FCDoubleSpinner(callback=self.confirmation_message) + self.mb_dia_entry.set_precision(self.decimals) + self.mb_dia_entry.setRange(0, 100.0000) + self.mb_dia_entry.setObjectName('gdb_ct_mb_dia') + + self.grid6.addWidget(self.mb_dia_label, 19, 0) + self.grid6.addWidget(self.mb_dia_entry, 19, 1) + + # Mouse Bites Holes Spacing + self.mb_spacing_label = FCLabel('%s:' % _("Spacing")) + self.mb_spacing_label.setToolTip( + _("The spacing between drill holes when doing mouse bites.") + ) + self.mb_spacing_entry = FCDoubleSpinner(callback=self.confirmation_message) + self.mb_spacing_entry.set_precision(self.decimals) + self.mb_spacing_entry.setRange(0, 100.0000) + self.mb_spacing_entry.setObjectName('gdb_ct_mb_spacing') + + self.grid6.addWidget(self.mb_spacing_label, 21, 0) + self.grid6.addWidget(self.mb_spacing_entry, 21, 1) + # How gaps wil be rendered: # lr - left + right # tb - top + bottom @@ -2102,17 +2169,17 @@ class ToolsDB2UI: # Surrounding convex box shape self.cutout_convex_box = FCCheckBox('%s' % _("Convex Shape")) - # self.convex_box_label = QtWidgets.QLabel('%s' % _("Convex Sh.")) + # self.convex_box_label = FCLabel('%s' % _("Convex Sh.")) self.cutout_convex_box.setToolTip( _("Create a convex shape surrounding the entire PCB.\n" "Used only if the source object type is Gerber.") ) self.cutout_convex_box.setObjectName('gdb_ct_convex') - self.grid6.addWidget(self.cutout_convex_box, 15, 0, 1, 2) + self.grid6.addWidget(self.cutout_convex_box, 23, 0, 1, 2) # Gaps - self.cutout_gaps_label = QtWidgets.QLabel('%s:' % _('Gaps')) + self.cutout_gaps_label = FCLabel('%s:' % _('Gaps')) self.cutout_gaps_label.setToolTip( _("Number of gaps used for the Automatic cutout.\n" "There can be maximum 8 bridges/gaps.\n" @@ -2131,8 +2198,8 @@ class ToolsDB2UI: self.cutout_gaps.addItems(gaps_items) self.cutout_gaps.setObjectName('gdb_ct_gaps') - self.grid6.addWidget(self.cutout_gaps_label, 19, 0) - self.grid6.addWidget(self.cutout_gaps, 19, 1) + self.grid6.addWidget(self.cutout_gaps_label, 25, 0) + self.grid6.addWidget(self.cutout_gaps, 25, 1) # #################################################################### # #################################################################### @@ -2363,11 +2430,16 @@ class ToolsDB2(QtWidgets.QWidget): "tools_drill_last_drill": self.ui.last_drill_drill_cb, # Cutout - "tools_cutoutmargin": self.ui.cutout_margin_entry, - "tools_cutoutgapsize": self.ui.cutout_gapsize, - "tools_gaps_ff": self.ui.cutout_gaps, + "tools_cutout_margin": self.ui.cutout_margin_entry, + "tools_cutout_gapsize": self.ui.cutout_gapsize, + "tools_cutout_gaps_ff": self.ui.cutout_gaps, "tools_cutout_convexshape": self.ui.cutout_convex_box, + "tools_cutout_gap_type": self.ui.gaptype_radio, + "tools_cutout_gap_depth": self.ui.thin_depth_entry, + "tools_cutout_mb_dia": self.ui.mb_dia_entry, + "tools_cutout_mb_spacing": self.ui.mb_spacing_entry, + } self.name2option = { @@ -2442,11 +2514,16 @@ class ToolsDB2(QtWidgets.QWidget): "gdb_e_drill_last_drill": "tools_drill_last_drill", # Cutout - "gdb_ct_margin": "tools_cutoutmargin", - "gdb_ct_gapsize": "tools_cutoutgapsize", - "gdb_ct_gaps": "tools_gaps_ff", + "gdb_ct_margin": "tools_cutout_margin", + "gdb_ct_gapsize": "tools_cutout_gapsize", + "gdb_ct_gaps": "tools_cutout_gaps_ff", "gdb_ct_convex": "tools_cutout_convexshape", + "gdb_ct_gap_type": "tools_cutout_gap_type", + "gdb_ct_gap_depth": "tools_cutout_gap_depth", + "gdb_ct_mb_dia": "tools_cutout_mb_dia", + "gdb_ct_mb_spacing": "tools_cutout_mb_spacing" + } self.current_toolid = None @@ -2782,10 +2859,15 @@ class ToolsDB2(QtWidgets.QWidget): "tools_drill_last_drill": self.app.defaults["tools_drill_last_drill"], # Cutout - "tools_cutoutmargin": float(self.app.defaults["tools_cutoutmargin"]), - "tools_cutoutgapsize": float(self.app.defaults["tools_cutoutgapsize"]), - "tools_gaps_ff": self.app.defaults["tools_gaps_ff"], + "tools_cutout_margin": float(self.app.defaults["tools_cutout_margin"]), + "tools_cutout_gapsize": float(self.app.defaults["tools_cutout_gapsize"]), + "tools_cutout_gaps_ff": self.app.defaults["tools_cutout_gaps_ff"], "tools_cutout_convexshape": self.app.defaults["tools_cutout_convexshape"], + + "tools_cutout_gap_type": self.app.defaults["tools_cutout_gap_type"], + "tools_cutout_gap_depth": float(self.app.defaults["tools_cutout_gap_depth"]), + "tools_cutout_mb_dia": float(self.app.defaults["tools_cutout_mb_dia"]), + "tools_cutout_mb_spacing": float(self.app.defaults["tools_cutout_mb_spacing"]) }) temp = [] @@ -3341,14 +3423,23 @@ class ToolsDB2(QtWidgets.QWidget): # Cutout Tool elif wdg_name == "gdb_ct_margin": - self.db_tool_dict[tool_id]['data']['tools_cutoutmargin'] = val + self.db_tool_dict[tool_id]['data']['tools_cutout_margin'] = val elif wdg_name == "gdb_ct_gapsize": - self.db_tool_dict[tool_id]['data']['tools_cutoutgapsize'] = val + self.db_tool_dict[tool_id]['data']['tools_cutout_gapsize'] = val elif wdg_name == "gdb_ct_gaps": - self.db_tool_dict[tool_id]['data']['tools_gaps_ff'] = val + self.db_tool_dict[tool_id]['data']['tools_cutout_gaps_ff'] = val elif wdg_name == "gdb_ct_convex": self.db_tool_dict[tool_id]['data']['tools_cutout_convexshape'] = val + elif wdg_name == "gdb_ct_gap_type": + self.db_tool_dict[tool_id]['data']['tools_cutout_gap_type'] = val + elif wdg_name == "gdb_ct_gap_depth": + self.db_tool_dict[tool_id]['data']['tools_cutout_gap_depth'] = val + elif wdg_name == "gdb_ct_mb_dia": + self.db_tool_dict[tool_id]['data']['tools_cutout_mb_dia'] = val + elif wdg_name == "gdb_ct_mb_spacing": + self.db_tool_dict[tool_id]['data']['tools_cutout_mb_spacing'] = val + self.callback_app() def on_tool_requested_from_app(self): diff --git a/appGUI/preferences/PreferencesUIManager.py b/appGUI/preferences/PreferencesUIManager.py index f8a2a85d..e6536b1d 100644 --- a/appGUI/preferences/PreferencesUIManager.py +++ b/appGUI/preferences/PreferencesUIManager.py @@ -402,40 +402,45 @@ class PreferencesUIManager: "tools_ncc_plotting": self.ui.tools_defaults_form.tools_ncc_group.plotting_radio, # CutOut Tool - "tools_cutouttooldia": self.ui.tools_defaults_form.tools_cutout_group.cutout_tooldia_entry, - "tools_cutoutkind": self.ui.tools_defaults_form.tools_cutout_group.obj_kind_combo, - "tools_cutoutmargin": self.ui.tools_defaults_form.tools_cutout_group.cutout_margin_entry, + "tools_cutout_tooldia": self.ui.tools_defaults_form.tools_cutout_group.cutout_tooldia_entry, + "tools_cutout_kind": self.ui.tools_defaults_form.tools_cutout_group.obj_kind_combo, + "tools_cutout_margin": self.ui.tools_defaults_form.tools_cutout_group.cutout_margin_entry, "tools_cutout_z": self.ui.tools_defaults_form.tools_cutout_group.cutz_entry, "tools_cutout_depthperpass": self.ui.tools_defaults_form.tools_cutout_group.maxdepth_entry, "tools_cutout_mdepth": self.ui.tools_defaults_form.tools_cutout_group.mpass_cb, - "tools_cutoutgapsize": self.ui.tools_defaults_form.tools_cutout_group.cutout_gap_entry, - "tools_gaps_ff": self.ui.tools_defaults_form.tools_cutout_group.gaps_combo, + "tools_cutout_gapsize": self.ui.tools_defaults_form.tools_cutout_group.cutout_gap_entry, + "tools_cutout_gaps_ff": self.ui.tools_defaults_form.tools_cutout_group.gaps_combo, "tools_cutout_convexshape": self.ui.tools_defaults_form.tools_cutout_group.convex_box, "tools_cutout_big_cursor": self.ui.tools_defaults_form.tools_cutout_group.big_cursor_cb, - # Paint Area Tool - "tools_painttooldia": self.ui.tools_defaults_form.tools_paint_group.painttooldia_entry, - "tools_paintorder": self.ui.tools_defaults_form.tools_paint_group.paint_order_radio, - "tools_paintoverlap": self.ui.tools_defaults_form.tools_paint_group.paintoverlap_entry, - "tools_paintoffset": self.ui.tools_defaults_form.tools_paint_group.paintmargin_entry, - "tools_paintmethod": self.ui.tools_defaults_form.tools_paint_group.paintmethod_combo, - "tools_selectmethod": self.ui.tools_defaults_form.tools_paint_group.selectmethod_combo, - "tools_paint_area_shape": self.ui.tools_defaults_form.tools_paint_group.area_shape_radio, - "tools_pathconnect": self.ui.tools_defaults_form.tools_paint_group.pathconnect_cb, - "tools_paintcontour": self.ui.tools_defaults_form.tools_paint_group.contour_cb, - "tools_paint_plotting": self.ui.tools_defaults_form.tools_paint_group.paint_plotting_radio, + "tools_cutout_gap_type": self.ui.tools_defaults_form.tools_cutout_group.gaptype_radio, + "tools_cutout_gap_depth": self.ui.tools_defaults_form.tools_cutout_group.thin_depth_entry, + "tools_cutout_mb_dia": self.ui.tools_defaults_form.tools_cutout_group.mb_dia_entry, + "tools_cutout_mb_spacing": self.ui.tools_defaults_form.tools_cutout_group.mb_spacing_entry, - "tools_paintrest": self.ui.tools_defaults_form.tools_paint_group.rest_cb, - "tools_painttool_type": self.ui.tools_defaults_form.tools_paint_group.tool_type_radio, - "tools_paintcutz": self.ui.tools_defaults_form.tools_paint_group.cutz_entry, - "tools_painttipdia": self.ui.tools_defaults_form.tools_paint_group.tipdia_entry, - "tools_painttipangle": self.ui.tools_defaults_form.tools_paint_group.tipangle_entry, - "tools_paintnewdia": self.ui.tools_defaults_form.tools_paint_group.newdia_entry, + # Paint Area Tool + "tools_painttooldia": self.ui.tools_defaults_form.tools_paint_group.painttooldia_entry, + "tools_paintorder": self.ui.tools_defaults_form.tools_paint_group.paint_order_radio, + "tools_paintoverlap": self.ui.tools_defaults_form.tools_paint_group.paintoverlap_entry, + "tools_paintoffset": self.ui.tools_defaults_form.tools_paint_group.paintmargin_entry, + "tools_paintmethod": self.ui.tools_defaults_form.tools_paint_group.paintmethod_combo, + "tools_selectmethod": self.ui.tools_defaults_form.tools_paint_group.selectmethod_combo, + "tools_paint_area_shape": self.ui.tools_defaults_form.tools_paint_group.area_shape_radio, + "tools_pathconnect": self.ui.tools_defaults_form.tools_paint_group.pathconnect_cb, + "tools_paintcontour": self.ui.tools_defaults_form.tools_paint_group.contour_cb, + "tools_paint_plotting": self.ui.tools_defaults_form.tools_paint_group.paint_plotting_radio, + + "tools_paintrest": self.ui.tools_defaults_form.tools_paint_group.rest_cb, + "tools_painttool_type": self.ui.tools_defaults_form.tools_paint_group.tool_type_radio, + "tools_paintcutz": self.ui.tools_defaults_form.tools_paint_group.cutz_entry, + "tools_painttipdia": self.ui.tools_defaults_form.tools_paint_group.tipdia_entry, + "tools_painttipangle": self.ui.tools_defaults_form.tools_paint_group.tipangle_entry, + "tools_paintnewdia": self.ui.tools_defaults_form.tools_paint_group.newdia_entry, # 2-sided Tool "tools_2sided_mirror_axis": self.ui.tools_defaults_form.tools_2sided_group.mirror_axis_radio, - "tools_2sided_axis_loc": self.ui.tools_defaults_form.tools_2sided_group.axis_location_radio, - "tools_2sided_drilldia": self.ui.tools_defaults_form.tools_2sided_group.drill_dia_entry, + "tools_2sided_axis_loc": self.ui.tools_defaults_form.tools_2sided_group.axis_location_radio, + "tools_2sided_drilldia": self.ui.tools_defaults_form.tools_2sided_group.drill_dia_entry, "tools_2sided_allign_axis": self.ui.tools_defaults_form.tools_2sided_group.align_axis_radio, # Film Tool diff --git a/appGUI/preferences/tools/ToolsCutoutPrefGroupUI.py b/appGUI/preferences/tools/ToolsCutoutPrefGroupUI.py index 0bc6b4fe..665afd18 100644 --- a/appGUI/preferences/tools/ToolsCutoutPrefGroupUI.py +++ b/appGUI/preferences/tools/ToolsCutoutPrefGroupUI.py @@ -1,7 +1,7 @@ from PyQt5 import QtWidgets from PyQt5.QtCore import QSettings -from appGUI.GUIElements import FCDoubleSpinner, FCCheckBox, RadioSet, FCComboBox +from appGUI.GUIElements import FCDoubleSpinner, FCCheckBox, RadioSet, FCComboBox, FCLabel from appGUI.preferences import machinist_setting from appGUI.preferences.OptionsGroupUI import OptionsGroupUI @@ -29,7 +29,7 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI): self.decimals = decimals # ## Board cutout - self.board_cutout_label = QtWidgets.QLabel("%s:" % _("Parameters")) + self.board_cutout_label = FCLabel("%s:" % _("Parameters")) self.board_cutout_label.setToolTip( _("Create toolpaths to cut around\n" "the PCB and separate it from\n" @@ -40,7 +40,7 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI): grid0 = QtWidgets.QGridLayout() self.layout.addLayout(grid0) - tdclabel = QtWidgets.QLabel('%s:' % _('Tool Diameter')) + tdclabel = FCLabel('%s:' % _('Tool Diameter')) tdclabel.setToolTip( _("Diameter of the tool used to cutout\n" "the PCB shape out of the surrounding material.") @@ -55,7 +55,7 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI): grid0.addWidget(self.cutout_tooldia_entry, 0, 1) # Cut Z - cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z')) + cutzlabel = FCLabel('%s:' % _('Cut Z')) cutzlabel.setToolTip( _( "Cutting depth (negative)\n" @@ -97,7 +97,7 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI): grid0.addWidget(self.maxdepth_entry, 2, 1) # Object kind - kindlabel = QtWidgets.QLabel('%s:' % _('Object kind')) + kindlabel = FCLabel('%s:' % _('Object kind')) kindlabel.setToolTip( _("Choice of what kind the object we want to cutout is.
" "- Single: contain a single PCB Gerber outline object.
" @@ -112,7 +112,7 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI): grid0.addWidget(kindlabel, 3, 0) grid0.addWidget(self.obj_kind_combo, 3, 1) - marginlabel = QtWidgets.QLabel('%s:' % _('Margin')) + marginlabel = FCLabel('%s:' % _('Margin')) marginlabel.setToolTip( _("Margin over bounds. A positive value here\n" "will make the cutout of the PCB further from\n" @@ -126,8 +126,9 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI): grid0.addWidget(marginlabel, 4, 0) grid0.addWidget(self.cutout_margin_entry, 4, 1) - - gaplabel = QtWidgets.QLabel('%s:' % _('Gap size')) + + # Gap Size + gaplabel = FCLabel('%s:' % _('Gap size')) gaplabel.setToolTip( _("The size of the bridge gaps in the cutout\n" "used to keep the board connected to\n" @@ -142,8 +143,70 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI): grid0.addWidget(gaplabel, 5, 0) grid0.addWidget(self.cutout_gap_entry, 5, 1) + + # Gap Type + self.gaptype_label = FCLabel('%s:' % _("Gap type")) + self.gaptype_label.setToolTip( + _("The type of gap:\n" + "- Bridge -> the cutout will be interrupted by bridges\n" + "- Thin -> same as 'bridge' but it will be thinner by partially milling the gap\n" + "- M-Bites -> 'Mouse Bites' - same as 'bridge' but covered with drill holes") + ) - gaps_label = QtWidgets.QLabel('%s:' % _('Gaps')) + self.gaptype_radio = RadioSet( + [ + {'label': _('Bridge'), 'value': 'b'}, + {'label': _('Thin'), 'value': 'bt'}, + {'label': "M-Bites", 'value': 'mb'} + ], + stretch=True + ) + + grid0.addWidget(self.gaptype_label, 7, 0) + grid0.addWidget(self.gaptype_radio, 7, 1) + + # Thin gaps Depth + self.thin_depth_label = FCLabel('%s:' % _("Depth")) + self.thin_depth_label.setToolTip( + _("The depth until the milling is done\n" + "in order to thin the gaps.") + ) + self.thin_depth_entry = FCDoubleSpinner() + self.thin_depth_entry.set_precision(self.decimals) + if machinist_setting == 0: + self.thin_depth_entry.setRange(-9999.9999, -0.00001) + else: + self.thin_depth_entry.setRange(-9999.9999, 9999.9999) + self.thin_depth_entry.setSingleStep(0.1) + + grid0.addWidget(self.thin_depth_label, 9, 0) + grid0.addWidget(self.thin_depth_entry, 9, 1) + + # Mouse Bites Tool Diameter + self.mb_dia_label = FCLabel('%s:' % _("Tool Diameter")) + self.mb_dia_label.setToolTip( + _("The drill hole diameter when doing mpuse bites.") + ) + self.mb_dia_entry = FCDoubleSpinner() + self.mb_dia_entry.set_precision(self.decimals) + self.mb_dia_entry.setRange(0, 100.0000) + + grid0.addWidget(self.mb_dia_label, 11, 0) + grid0.addWidget(self.mb_dia_entry, 11, 1) + + # Mouse Bites Holes Spacing + self.mb_spacing_label = FCLabel('%s:' % _("Spacing")) + self.mb_spacing_label.setToolTip( + _("The spacing between drill holes when doing mouse bites.") + ) + self.mb_spacing_entry = FCDoubleSpinner() + self.mb_spacing_entry.set_precision(self.decimals) + self.mb_spacing_entry.setRange(0, 100.0000) + + grid0.addWidget(self.mb_spacing_label, 13, 0) + grid0.addWidget(self.mb_spacing_entry, 13, 1) + + gaps_label = FCLabel('%s:' % _('Gaps')) gaps_label.setToolTip( _("Number of gaps used for the cutout.\n" "There can be maximum 8 bridges/gaps.\n" @@ -158,8 +221,8 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI): ) self.gaps_combo = FCComboBox() - grid0.addWidget(gaps_label, 6, 0) - grid0.addWidget(self.gaps_combo, 6, 1) + grid0.addWidget(gaps_label, 15, 0) + grid0.addWidget(self.gaps_combo, 15, 1) gaps_items = ['None', 'LR', 'TB', '4', '2LR', '2TB', '8'] for it in gaps_items: @@ -172,11 +235,11 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI): _("Create a convex shape surrounding the entire PCB.\n" "Used only if the source object type is Gerber.") ) - grid0.addWidget(self.convex_box, 7, 0, 1, 2) + grid0.addWidget(self.convex_box, 17, 0, 1, 2) self.big_cursor_cb = FCCheckBox('%s' % _("Big cursor")) self.big_cursor_cb.setToolTip( _("Use a big cursor when adding manual gaps.")) - grid0.addWidget(self.big_cursor_cb, 8, 0, 1, 2) + grid0.addWidget(self.big_cursor_cb, 19, 0, 1, 2) self.layout.addStretch() diff --git a/appTools/ToolCutOut.py b/appTools/ToolCutOut.py index 6cf9baaa..fbb28e3d 100644 --- a/appTools/ToolCutOut.py +++ b/appTools/ToolCutOut.py @@ -21,6 +21,9 @@ from copy import deepcopy import math import logging import gettext +import sys +import simplejson as json + import appTranslation as fcTranslate import builtins @@ -90,10 +93,17 @@ class CutOut(AppTool): # store original geometry for manual cutout self.manual_solid_geo = None + # here store the tool data for the Cutout Tool + self.cut_tool_dict = {} + # Signals self.ui.ff_cutout_object_btn.clicked.connect(self.on_freeform_cutout) self.ui.rect_cutout_object_btn.clicked.connect(self.on_rectangular_cutout) + # adding tools + self.ui.add_newtool_button.clicked.connect(lambda: self.on_tool_add()) + self.ui.addtool_from_db_btn.clicked.connect(self.on_tool_add_from_db_clicked) + self.ui.type_obj_radio.activated_custom.connect(self.on_type_obj_changed) self.ui.man_geo_creation_btn.clicked.connect(self.on_manual_geo) self.ui.man_gaps_creation_btn.clicked.connect(self.on_manual_gap_click) @@ -145,20 +155,6 @@ class CutOut(AppTool): def set_tool_ui(self): self.reset_fields() - self.ui.dia.set_value(float(self.app.defaults["tools_cutouttooldia"])) - self.ui.obj_kind_combo.set_value(self.app.defaults["tools_cutoutkind"]) - self.ui.margin.set_value(float(self.app.defaults["tools_cutoutmargin"])) - self.ui.cutz_entry.set_value(float(self.app.defaults["tools_cutout_z"])) - self.ui.mpass_cb.set_value(float(self.app.defaults["tools_cutout_mdepth"])) - self.ui.maxdepth_entry.set_value(float(self.app.defaults["tools_cutout_depthperpass"])) - - self.ui.gapsize.set_value(float(self.app.defaults["tools_cutoutgapsize"])) - self.ui.gaps.set_value(self.app.defaults["tools_gaps_ff"]) - self.ui.convex_box_cb.set_value(self.app.defaults['tools_cutout_convexshape']) - self.ui.big_cursor_cb.set_value(self.app.defaults['tools_cutout_big_cursor']) - - self.ui.gaptype_radio.set_value('b') - # use the current selected object and make it visible in the object combobox sel_list = self.app.collection.get_selected() if len(sel_list) == 1: @@ -188,13 +184,15 @@ class CutOut(AppTool): else: self.on_type_obj_changed(val='geo') - # self.type_obj_radio.set_value('grb') + self.ui.dia.set_value(float(self.app.defaults["tools_cutout_tooldia"])) self.default_data.update({ "plot": True, + "cutz": float(self.app.defaults["geometry_cutz"]), "multidepth": self.app.defaults["geometry_multidepth"], "depthperpass": float(self.app.defaults["geometry_depthperpass"]), + "vtipdia": float(self.app.defaults["geometry_vtipdia"]), "vtipangle": float(self.app.defaults["geometry_vtipangle"]), "travelz": float(self.app.defaults["geometry_travelz"]), @@ -219,31 +217,309 @@ class CutOut(AppTool): "area_overz": float(self.app.defaults["geometry_area_overz"]), "optimization_type": self.app.defaults["geometry_optimization_type"], - # NCC - "tools_nccoperation": self.app.defaults["tools_nccoperation"], - "tools_nccmilling_type": self.app.defaults["tools_nccmilling_type"], - "tools_nccoverlap": float(self.app.defaults["tools_nccoverlap"]), - "tools_nccmargin": float(self.app.defaults["tools_nccmargin"]), - "tools_nccmethod": self.app.defaults["tools_nccmethod"], - "tools_nccconnect": self.app.defaults["tools_nccconnect"], - "tools_ncccontour": self.app.defaults["tools_ncccontour"], - "tools_ncc_offset_choice": self.app.defaults["tools_ncc_offset_choice"], - "tools_ncc_offset_value": float(self.app.defaults["tools_ncc_offset_value"]), + # Cutout + "tools_cutout_tooldia": self.app.defaults["tools_cutout_tooldia"], + "tools_cutout_kind": self.app.defaults["tools_cutout_kind"], + "tools_cutout_margin": float(self.app.defaults["tools_cutout_margin"]), + "tools_cutout_z": float(self.app.defaults["tools_cutout_z"]), + "tools_cutout_depthperpass": float(self.app.defaults["tools_cutout_depthperpass"]), + "tools_cutout_mdepth": self.app.defaults["tools_cutout_mdepth"], + "tools_cutout_gapsize": float(self.app.defaults["tools_cutout_gapsize"]), + "tools_cutout_gaps_ff": self.app.defaults["tools_cutout_gaps_ff"], + "tools_cutout_convexshape": self.app.defaults["tools_cutout_convexshape"], - # Paint - "tools_paintoverlap": float(self.app.defaults["tools_paintoverlap"]), - "tools_paintoffset": float(self.app.defaults["tools_paintoffset"]), - "tools_paintmethod": self.app.defaults["tools_paintmethod"], - "tools_pathconnect": self.app.defaults["tools_pathconnect"], - "tools_paintcontour": self.app.defaults["tools_paintcontour"], + "tools_cutout_big_cursor": self.app.defaults["tools_cutout_big_cursor"], + "tools_cutout_gap_type": self.app.defaults["tools_cutout_gap_type"], + "tools_cutout_gap_depth": float(self.app.defaults["tools_cutout_gap_depth"]), + "tools_cutout_mb_dia": float(self.app.defaults["tools_cutout_mb_dia"]), + "tools_cutout_mb_spacing": float(self.app.defaults["tools_cutout_mb_spacing"]), - # Isolation Tool - "tools_iso_passes": self.app.defaults["tools_iso_passes"], - "tools_iso_overlap": self.app.defaults["tools_iso_overlap"], - "tools_iso_milling_type": self.app.defaults["tools_iso_milling_type"], - "tools_iso_follow": self.app.defaults["tools_iso_follow"], - "tools_iso_isotype": self.app.defaults["tools_iso_isotype"], }) + tool_dia = float(self.app.defaults["tools_cutout_tooldia"]) + self.on_tool_add(custom_dia=tool_dia) + + def update_ui(self, tool_dict): + self.ui.obj_kind_combo.set_value(self.default_data["tools_cutout_kind"]) + self.ui.big_cursor_cb.set_value(self.default_data['tools_cutout_big_cursor']) + + # Entries that may be updated from database + self.ui.margin.set_value(float(tool_dict["tools_cutout_margin"])) + self.ui.gapsize.set_value(float(tool_dict["tools_cutout_gapsize"])) + self.ui.gaptype_radio.set_value(tool_dict["tools_cutout_gap_type"]) + self.ui.thin_depth_entry.set_value(float(tool_dict["tools_cutout_gap_depth"])) + self.ui.mb_dia_entry.set_value(float(tool_dict["tools_cutout_mb_dia"])) + self.ui.mb_spacing_entry.set_value(float(tool_dict["tools_cutout_mb_spacing"])) + self.ui.convex_box_cb.set_value(tool_dict['tools_cutout_convexshape']) + self.ui.gaps.set_value(tool_dict["tools_cutout_gaps_ff"]) + + self.ui.cutz_entry.set_value(float(tool_dict["tools_cutout_z"])) + self.ui.mpass_cb.set_value(float(tool_dict["tools_cutout_mdepth"])) + self.ui.maxdepth_entry.set_value(float(tool_dict["tools_cutout_depthperpass"])) + + def on_tool_add(self, custom_dia=None): + self.blockSignals(True) + + filename = self.app.data_path + '\\tools_db.FlatDB' + + new_tools_dict = deepcopy(self.default_data) + updated_tooldia = None + + # determine the new tool diameter + if custom_dia is None: + tool_dia = self.ui.dia.get_value() + else: + tool_dia = custom_dia + + if tool_dia is None or tool_dia == 0: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Please enter a tool diameter with non-zero value, " + "in Float format.")) + self.blockSignals(False) + return + + truncated_tooldia = self.app.dec_format(tool_dia, self.decimals) + + # load the database tools from the file + try: + with open(filename) as f: + tools = f.read() + except IOError: + self.app.log.error("Could not load tools DB file.") + self.app.inform.emit('[ERROR] %s' % _("Could not load Tools DB file.")) + self.blockSignals(False) + self.on_tool_default_add(dia=tool_dia) + return + + try: + # store here the tools from Tools Database when searching in Tools Database + tools_db_dict = json.loads(tools) + except Exception: + e = sys.exc_info()[0] + self.app.log.error(str(e)) + self.app.inform.emit('[ERROR] %s' % _("Failed to parse Tools DB file.")) + self.blockSignals(False) + self.on_tool_default_add(dia=tool_dia) + return + + tool_found = 0 + + offset = 'Path' + offset_val = 0.0 + typ = "Rough" + tool_type = 'V' + # look in database tools + for db_tool, db_tool_val in tools_db_dict.items(): + offset = db_tool_val['offset'] + offset_val = db_tool_val['offset_value'] + typ = db_tool_val['type'] + tool_type = db_tool_val['tool_type'] + + db_tooldia = db_tool_val['tooldia'] + low_limit = float(db_tool_val['data']['tol_min']) + high_limit = float(db_tool_val['data']['tol_max']) + + # we need only tool marked for Cutout Tool + if db_tool_val['data']['tool_target'] != _('Cutout'): + continue + + # if we find a tool with the same diameter in the Tools DB just update it's data + if truncated_tooldia == db_tooldia: + tool_found += 1 + for d in db_tool_val['data']: + if d.find('tools_cutout') == 0: + new_tools_dict[d] = db_tool_val['data'][d] + elif d.find('tools_') == 0: + # don't need data for other App Tools; this tests after 'tools_drill_' + continue + else: + new_tools_dict[d] = db_tool_val['data'][d] + # search for a tool that has a tolerance that the tool fits in + elif high_limit >= truncated_tooldia >= low_limit: + tool_found += 1 + updated_tooldia = db_tooldia + for d in db_tool_val['data']: + if d.find('tools_cutout') == 0: + new_tools_dict[d] = db_tool_val['data'][d] + elif d.find('tools_') == 0: + # don't need data for other App Tools; this tests after 'tools_drill_' + continue + else: + new_tools_dict[d] = db_tool_val['data'][d] + + # test we found a suitable tool in Tools Database or if multiple ones + if tool_found == 0: + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Tool not in Tools Database. Adding a default tool.")) + self.on_tool_default_add() + self.blockSignals(False) + return + + if tool_found > 1: + self.app.inform.emit( + '[WARNING_NOTCL] %s' % _("Cancelled.\n" + "Multiple tools for one tool diameter found in Tools Database.")) + self.blockSignals(False) + return + + # FIXME when the Geometry UI milling functionality will be transferred in the Milling Tool this needs changes + new_tools_dict["tools_cutout_z"] = deepcopy(new_tools_dict["cutz"]) + new_tools_dict["tools_cutout_mdepth"] = deepcopy(new_tools_dict["multidepth"]) + new_tools_dict["tools_cutout_depthperpass"] = deepcopy(new_tools_dict["depthperpass"]) + + new_tdia = deepcopy(updated_tooldia) if updated_tooldia is not None else deepcopy(truncated_tooldia) + self.cut_tool_dict.update({ + 'tooldia': new_tdia, + 'offset': deepcopy(offset), + 'offset_value': deepcopy(offset_val), + 'type': deepcopy(typ), + 'tool_type': deepcopy(tool_type), + 'data': deepcopy(new_tools_dict), + 'solid_geometry': [] + }) + + self.update_ui(new_tools_dict) + + self.blockSignals(False) + self.app.inform.emit('[success] %s' % _("Updated tool from Tools Database.")) + + def on_tool_default_add(self, dia=None, muted=None): + self.default_data.update({ + "plot": True, + + "cutz": float(self.app.defaults["geometry_cutz"]), + "multidepth": self.app.defaults["geometry_multidepth"], + "depthperpass": float(self.app.defaults["geometry_depthperpass"]), + + "vtipdia": float(self.app.defaults["geometry_vtipdia"]), + "vtipangle": float(self.app.defaults["geometry_vtipangle"]), + "travelz": float(self.app.defaults["geometry_travelz"]), + "feedrate": float(self.app.defaults["geometry_feedrate"]), + "feedrate_z": float(self.app.defaults["geometry_feedrate_z"]), + "feedrate_rapid": float(self.app.defaults["geometry_feedrate_rapid"]), + "spindlespeed": self.app.defaults["geometry_spindlespeed"], + "dwell": self.app.defaults["geometry_dwell"], + "dwelltime": float(self.app.defaults["geometry_dwelltime"]), + "spindledir": self.app.defaults["geometry_spindledir"], + "ppname_g": self.app.defaults["geometry_ppname_g"], + "extracut": self.app.defaults["geometry_extracut"], + "extracut_length": float(self.app.defaults["geometry_extracut_length"]), + "toolchange": self.app.defaults["geometry_toolchange"], + "toolchangexy": self.app.defaults["geometry_toolchangexy"], + "toolchangez": float(self.app.defaults["geometry_toolchangez"]), + "startz": self.app.defaults["geometry_startz"], + "endz": float(self.app.defaults["geometry_endz"]), + "area_exclusion": self.app.defaults["geometry_area_exclusion"], + "area_shape": self.app.defaults["geometry_area_shape"], + "area_strategy": self.app.defaults["geometry_area_strategy"], + "area_overz": float(self.app.defaults["geometry_area_overz"]), + "optimization_type": self.app.defaults["geometry_optimization_type"], + + # Cutout + "tools_cutout_tooldia": self.app.defaults["tools_cutout_tooldia"], + "tools_cutout_kind": self.app.defaults["tools_cutout_kind"], + "tools_cutout_margin": float(self.app.defaults["tools_cutout_margin"]), + "tools_cutout_z": float(self.app.defaults["tools_cutout_z"]), + "tools_cutout_depthperpass": float(self.app.defaults["tools_cutout_depthperpass"]), + "tools_cutout_mdepth": self.app.defaults["tools_cutout_mdepth"], + "tools_cutout_gapsize": float(self.app.defaults["tools_cutout_gapsize"]), + "tools_cutout_gaps_ff": self.app.defaults["tools_cutout_gaps_ff"], + "tools_cutout_convexshape": self.app.defaults["tools_cutout_convexshape"], + + "tools_cutout_big_cursor": self.app.defaults["tools_cutout_big_cursor"], + "tools_cutout_gap_type": self.app.defaults["tools_cutout_gap_type"], + "tools_cutout_gap_depth": float(self.app.defaults["tools_cutout_gap_depth"]), + "tools_cutout_mb_dia": float(self.app.defaults["tools_cutout_mb_dia"]), + "tools_cutout_mb_spacing": float(self.app.defaults["tools_cutout_mb_spacing"]), + + }) + + self.cut_tool_dict.update({ + 'tooldia': str(self.app.defaults["tools_cutout_tooldia"]), + 'offset': 'Path', + 'offset_value': 0.0, + 'type': _('Rough'), + 'tool_type': 'C1', + 'data': deepcopy(self.default_data), + 'solid_geometry': [] + }) + + self.update_ui(self.default_data) + + if muted is None: + self.app.inform.emit('[success] %s' % _("Default tool added.")) + + def on_cutout_tool_add_from_db_executed(self, tool): + """ + Here add the tool from DB in the selected geometry object + :return: + """ + + if tool['data']['tool_target'] != _("Cutout"): + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Selected tool can't be used here. Pick another.")) + return + tool_from_db = deepcopy(self.default_data) + tool_from_db.update(tool) + + # FIXME when the Geometry UI milling functionality will be transferred in the Milling Tool this needs changes + tool_from_db['data']["tools_cutout_tooldia"] = deepcopy(tool["tooldia"]) + tool_from_db['data']["tools_cutout_z"] = deepcopy(tool_from_db['data']["cutz"]) + tool_from_db['data']["tools_cutout_mdepth"] = deepcopy(tool_from_db['data']["multidepth"]) + tool_from_db['data']["tools_cutout_depthperpass"] = deepcopy(tool_from_db['data']["depthperpass"]) + + self.cut_tool_dict.update(tool_from_db) + self.cut_tool_dict['solid_geometry'] = [] + + self.update_ui(tool_from_db['data']) + self.ui.dia.set_value(float(tool_from_db['data']["tools_cutout_tooldia"])) + + for idx in range(self.app.ui.plot_tab_area.count()): + if self.app.ui.plot_tab_area.tabText(idx) == _("Tools Database"): + wdg = self.app.ui.plot_tab_area.widget(idx) + wdg.deleteLater() + self.app.ui.plot_tab_area.removeTab(idx) + + self.app.inform.emit('[success] %s' % _("Tool updated from Tools Database.")) + + def on_tool_from_db_inserted(self, tool): + """ + Called from the Tools DB object through a App method when adding a tool from Tools Database + :param tool: a dict with the tool data + :return: None + """ + + tooldia = float(tool['tooldia']) + + truncated_tooldia = self.app.dec_format(tooldia, self.decimals) + self.cutout_tools.update({ + 1: { + 'tooldia': truncated_tooldia, + 'offset': tool['offset'], + 'offset_value': tool['offset_value'], + 'type': tool['type'], + 'tool_type': tool['tool_type'], + 'data': deepcopy(tool['data']), + 'solid_geometry': [] + } + }) + self.cutout_tools[1]['data']['name'] = '_cutout' + + return 1 + + def on_tool_add_from_db_clicked(self): + """ + Called when the user wants to add a new tool from Tools Database. It will create the Tools Database object + and display the Tools Database tab in the form needed for the Tool adding + :return: None + """ + + # if the Tools Database is already opened focus on it + for idx in range(self.app.ui.plot_tab_area.count()): + if self.app.ui.plot_tab_area.tabText(idx) == _("Tools Database"): + self.app.ui.plot_tab_area.setCurrentWidget(self.app.tools_db_tab) + break + self.app.on_tools_database(source='cutout') + self.app.tools_db_tab.ok_to_add = True + self.app.tools_db_tab.ui.buttons_frame.hide() + self.app.tools_db_tab.ui.add_tool_from_db.show() + self.app.tools_db_tab.ui.cancel_tool_from_db.show() def on_freeform_cutout(self): log.debug("Cutout.on_freeform_cutout() was launched ...") @@ -480,18 +756,14 @@ class CutOut(AppTool): geo_obj.options['multidepth'] = self.ui.mpass_cb.get_value() geo_obj.options['depthperpass'] = self.ui.maxdepth_entry.get_value() - geo_obj.tools.update({ - 1: { - 'tooldia': str(dia), - 'offset': 'Path', - 'offset_value': 0.0, - 'type': _('Rough'), - 'tool_type': 'C1', - 'data': deepcopy(self.default_data), - 'solid_geometry': geo_obj.solid_geometry - } - }) geo_obj.multigeo = True + + geo_obj.tools.update({ + 1: self.cut_tool_dict + }) + geo_obj.tools[1]['tooldia'] = str(dia) + geo_obj.tools[1]['solid_geometry'] = geo_obj.solid_geometry + geo_obj.tools[1]['data']['name'] = outname geo_obj.tools[1]['data']['cutz'] = self.ui.cutz_entry.get_value() geo_obj.tools[1]['data']['multidepth'] = self.ui.mpass_cb.get_value() @@ -499,16 +771,11 @@ class CutOut(AppTool): if gaps_solid_geo is not None: geo_obj.tools.update({ - 9999: { - 'tooldia': str(dia), - 'offset': 'Path', - 'offset_value': 0.0, - 'type': _('Rough'), - 'tool_type': 'C1', - 'data': deepcopy(self.default_data), - 'solid_geometry': gaps_solid_geo - } + 9999: self.cut_tool_dict }) + geo_obj.tools[9999]['tooldia'] = str(dia) + geo_obj.tools[9999]['solid_geometry'] = gaps_solid_geo + geo_obj.tools[9999]['data']['name'] = outname geo_obj.tools[9999]['data']['cutz'] = self.ui.thin_depth_entry.get_value() geo_obj.tools[9999]['data']['multidepth'] = self.ui.mpass_cb.get_value() @@ -735,18 +1002,14 @@ class CutOut(AppTool): solid_geo = linemerge(solid_geo) geo_obj.solid_geometry = deepcopy(solid_geo) - geo_obj.tools.update({ - 1: { - 'tooldia': str(dia), - 'offset': 'Path', - 'offset_value': 0.0, - 'type': _('Rough'), - 'tool_type': 'C1', - 'data': deepcopy(self.default_data), - 'solid_geometry': geo_obj.solid_geometry - } - }) geo_obj.multigeo = True + + geo_obj.tools.update({ + 1: self.cut_tool_dict + }) + geo_obj.tools[1]['tooldia'] = str(dia) + geo_obj.tools[1]['solid_geometry'] = geo_obj.solid_geometry + geo_obj.tools[1]['data']['name'] = outname geo_obj.tools[1]['data']['cutz'] = self.ui.cutz_entry.get_value() geo_obj.tools[1]['data']['multidepth'] = self.ui.mpass_cb.get_value() @@ -754,16 +1017,11 @@ class CutOut(AppTool): if gaps_solid_geo is not None: geo_obj.tools.update({ - 9999: { - 'tooldia': str(dia), - 'offset': 'Path', - 'offset_value': 0.0, - 'type': _('Rough'), - 'tool_type': 'C1', - 'data': deepcopy(self.default_data), - 'solid_geometry': gaps_solid_geo - } + 9999: self.cut_tool_dict }) + geo_obj.tools[9999]['tooldia'] = str(dia) + geo_obj.tools[9999]['solid_geometry'] = gaps_solid_geo + geo_obj.tools[9999]['data']['name'] = outname geo_obj.tools[9999]['data']['cutz'] = self.ui.thin_depth_entry.get_value() geo_obj.tools[9999]['data']['multidepth'] = self.ui.mpass_cb.get_value() @@ -856,7 +1114,7 @@ class CutOut(AppTool): cut_poly = self.cutting_geo(pos=(snapped_pos[0], snapped_pos[1])) gaps_solid_geo = None - if self.ui.gaptype_radio.get_value() == 'bt' and self.ui.thin_depth_entry.get_value() > 0: + if self.ui.gaptype_radio.get_value() == 'bt' and self.ui.thin_depth_entry.get_value() != 0: gaps_solid_geo = self.intersect_geo(self.manual_solid_geo, cut_poly) # first subtract geometry for the total solid_geometry @@ -864,10 +1122,11 @@ class CutOut(AppTool): new_solid_geometry = linemerge(new_solid_geometry) self.man_cutout_obj.solid_geometry = new_solid_geometry - # then do it or each tool in the manual cutout Geometry object + # then do it on each tool in the manual cutout Geometry object try: - self.man_cutout_obj.tools[1]['solid_geometry'] = new_solid_geometry self.man_cutout_obj.multigeo = True + + self.man_cutout_obj.tools[1]['solid_geometry'] = new_solid_geometry self.man_cutout_obj.tools[1]['data']['name'] = self.man_cutout_obj.options['name'] + '_cutout' self.man_cutout_obj.tools[1]['data']['cutz'] = self.ui.cutz_entry.get_value() self.man_cutout_obj.tools[1]['data']['multidepth'] = self.ui.mpass_cb.get_value() @@ -880,16 +1139,11 @@ class CutOut(AppTool): if gaps_solid_geo: if 9999 not in self.man_cutout_obj.tools: self.man_cutout_obj.tools.update({ - 9999: { - 'tooldia': str(dia), - 'offset': 'Path', - 'offset_value': 0.0, - 'type': _('Rough'), - 'tool_type': 'C1', - 'data': deepcopy(self.default_data), - 'solid_geometry': [gaps_solid_geo] - } + 9999: self.cut_tool_dict }) + self.man_cutout_obj.tools[9999]['tooldia'] = str(dia) + self.man_cutout_obj.tools[9999]['solid_geometry'] = [gaps_solid_geo] + self.man_cutout_obj.tools[9999]['data']['name'] = self.man_cutout_obj.options['name'] + '_cutout' self.man_cutout_obj.tools[9999]['data']['cutz'] = self.ui.thin_depth_entry.get_value() self.man_cutout_obj.tools[9999]['data']['multidepth'] = self.ui.mpass_cb.get_value() @@ -899,7 +1153,7 @@ class CutOut(AppTool): self.man_cutout_obj.tools[9999]['solid_geometry'].append(gaps_solid_geo) self.man_cutout_obj.plot(plot_tool=1) - self.app.inform.emit('[success] %s' % _("Added manual Bridge Gap.")) + self.app.inform.emit('%s' % _("Added manual Bridge Gap. Left click to add another or right click to finish.")) self.app.should_we_save = True @@ -975,18 +1229,14 @@ class CutOut(AppTool): geo_obj.options['multidepth'] = self.ui.mpass_cb.get_value() geo_obj.options['depthperpass'] = self.ui.maxdepth_entry.get_value() - geo_obj.tools.update({ - 1: { - 'tooldia': str(dia), - 'offset': 'Path', - 'offset_value': 0.0, - 'type': _('Rough'), - 'tool_type': 'C1', - 'data': self.default_data, - 'solid_geometry': geo_obj.solid_geometry - } - }) geo_obj.multigeo = True + + geo_obj.tools.update({ + 1: self.cut_tool_dict + }) + geo_obj.tools[1]['tooldia'] = str(dia) + geo_obj.tools[1]['solid_geometry'] = geo_obj.solid_geometry + geo_obj.tools[1]['data']['name'] = outname geo_obj.tools[1]['data']['cutz'] = self.ui.cutz_entry.get_value() geo_obj.tools[1]['data']['multidepth'] = self.ui.mpass_cb.get_value() @@ -1075,6 +1325,8 @@ class CutOut(AppTool): # plot the final object self.man_cutout_obj.plot() + self.app.inform.emit('[success] %s' % _("Finished manual adding of gaps.")) + def on_mouse_move(self, event): self.app.on_mouse_move_over_plot(event=event) @@ -1507,23 +1759,55 @@ class CutoutUI: separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) grid0.addWidget(separator_line, 10, 0, 1, 2) - grid0.addWidget(QtWidgets.QLabel(''), 12, 0, 1, 2) - - self.param_label = QtWidgets.QLabel('%s:' % _("Tool Parameters")) - grid0.addWidget(self.param_label, 14, 0, 1, 2) + self.tool_sel_label = FCLabel('%s' % _('Cutout Tool')) + grid0.addWidget(self.tool_sel_label, 12, 0, 1, 2) # Tool Diameter self.dia = FCDoubleSpinner(callback=self.confirmation_message) self.dia.set_precision(self.decimals) self.dia.set_range(0.0000, 9999.9999) - self.dia_label = QtWidgets.QLabel('%s:' % _("Tool Diameter")) + self.dia_label = QtWidgets.QLabel('%s:' % _("Tool Dia")) self.dia_label.setToolTip( _("Diameter of the tool used to cutout\n" "the PCB shape out of the surrounding material.") ) - grid0.addWidget(self.dia_label, 16, 0) - grid0.addWidget(self.dia, 16, 1) + grid0.addWidget(self.dia_label, 14, 0) + grid0.addWidget(self.dia, 14, 1) + + hlay = QtWidgets.QHBoxLayout() + + # Search and Add new Tool + self.add_newtool_button = FCButton(_('Search and Add')) + self.add_newtool_button.setIcon(QtGui.QIcon(self.app.resource_location + '/plus16.png')) + self.add_newtool_button.setToolTip( + _("Add a new tool to the Tool Table\n" + "with the diameter specified above.\n" + "This is done by a background search\n" + "in the Tools Database. If nothing is found\n" + "in the Tools DB then a default tool is added.") + ) + hlay.addWidget(self.add_newtool_button) + + # Pick from DB new Tool + self.addtool_from_db_btn = FCButton(_('Pick from DB')) + self.addtool_from_db_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/search_db32.png')) + self.addtool_from_db_btn.setToolTip( + _("Add a new tool to the Tool Table\n" + "from the Tool Database.\n" + "Tool database administration in Menu: Options -> Tools Database") + ) + hlay.addWidget(self.addtool_from_db_btn) + + grid0.addLayout(hlay, 16, 0, 1, 2) + + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(separator_line, 18, 0, 1, 2) + + self.param_label = QtWidgets.QLabel('%s:' % _("Tool Parameters")) + grid0.addWidget(self.param_label, 20, 0, 1, 2) # Cut Z cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z')) @@ -1543,8 +1827,8 @@ class CutoutUI: self.cutz_entry.setSingleStep(0.1) - grid0.addWidget(cutzlabel, 18, 0) - grid0.addWidget(self.cutz_entry, 18, 1) + grid0.addWidget(cutzlabel, 22, 0) + grid0.addWidget(self.cutz_entry, 22, 1) # Multi-pass self.mpass_cb = FCCheckBox('%s:' % _("Multi-Depth")) @@ -1568,8 +1852,8 @@ class CutoutUI: ) ) - grid0.addWidget(self.mpass_cb, 20, 0) - grid0.addWidget(self.maxdepth_entry, 20, 1) + grid0.addWidget(self.mpass_cb, 24, 0) + grid0.addWidget(self.maxdepth_entry, 24, 1) self.ois_mpass_geo = OptionalInputSection(self.mpass_cb, [self.maxdepth_entry]) @@ -1585,8 +1869,8 @@ class CutoutUI: "will make the cutout of the PCB further from\n" "the actual PCB border") ) - grid0.addWidget(self.margin_label, 22, 0) - grid0.addWidget(self.margin, 22, 1) + grid0.addWidget(self.margin_label, 26, 0) + grid0.addWidget(self.margin, 26, 1) # Gapsize self.gapsize_label = QtWidgets.QLabel('%s:' % _("Gap size")) @@ -1600,10 +1884,10 @@ class CutoutUI: self.gapsize = FCDoubleSpinner(callback=self.confirmation_message) self.gapsize.set_precision(self.decimals) - grid0.addWidget(self.gapsize_label, 24, 0) - grid0.addWidget(self.gapsize, 24, 1) + grid0.addWidget(self.gapsize_label, 28, 0) + grid0.addWidget(self.gapsize, 28, 1) - # Gapsize + # Gap Type self.gaptype_label = FCLabel('%s:' % _("Gap type")) self.gaptype_label.setToolTip( _("The type of gap:\n" @@ -1621,8 +1905,8 @@ class CutoutUI: stretch=True ) - grid0.addWidget(self.gaptype_label, 26, 0) - grid0.addWidget(self.gaptype_radio, 26, 1) + grid0.addWidget(self.gaptype_label, 30, 0) + grid0.addWidget(self.gaptype_radio, 30, 1) # Thin gaps Depth self.thin_depth_label = FCLabel('%s:' % _("Depth")) @@ -1638,8 +1922,8 @@ class CutoutUI: self.thin_depth_entry.setRange(-9999.9999, 9999.9999) self.thin_depth_entry.setSingleStep(0.1) - grid0.addWidget(self.thin_depth_label, 28, 0) - grid0.addWidget(self.thin_depth_entry, 28, 1) + grid0.addWidget(self.thin_depth_label, 32, 0) + grid0.addWidget(self.thin_depth_entry, 32, 1) # Mouse Bites Tool Diameter self.mb_dia_label = FCLabel('%s:' % _("Tool Diameter")) @@ -1650,8 +1934,8 @@ class CutoutUI: self.mb_dia_entry.set_precision(self.decimals) self.mb_dia_entry.setRange(0, 100.0000) - grid0.addWidget(self.mb_dia_label, 30, 0) - grid0.addWidget(self.mb_dia_entry, 30, 1) + grid0.addWidget(self.mb_dia_label, 34, 0) + grid0.addWidget(self.mb_dia_entry, 34, 1) # Mouse Bites Holes Spacing self.mb_spacing_label = FCLabel('%s:' % _("Spacing")) @@ -1662,22 +1946,20 @@ class CutoutUI: self.mb_spacing_entry.set_precision(self.decimals) self.mb_spacing_entry.setRange(0, 100.0000) - grid0.addWidget(self.mb_spacing_label, 32, 0) - grid0.addWidget(self.mb_spacing_entry, 32, 1) + grid0.addWidget(self.mb_spacing_label, 36, 0) + grid0.addWidget(self.mb_spacing_entry, 36, 1) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid0.addWidget(separator_line, 34, 0, 1, 2) - - grid0.addWidget(QtWidgets.QLabel(''), 36, 0, 1, 2) + grid0.addWidget(separator_line, 38, 0, 1, 2) # Title2 title_param_label = QtWidgets.QLabel("%s %s:" % (_('Automatic'), _("Bridge Gaps"))) title_param_label.setToolTip( _("This section handle creation of automatic bridge gaps.") ) - grid0.addWidget(title_param_label, 38, 0, 1, 2) + grid0.addWidget(title_param_label, 40, 0, 1, 2) # Gaps # How gaps wil be rendered: @@ -1707,8 +1989,8 @@ class CutoutUI: for it in gaps_items: self.gaps.addItem(it) # self.gaps.setStyleSheet('background-color: rgb(255,255,255)') - grid0.addWidget(gaps_label, 40, 0) - grid0.addWidget(self.gaps, 40, 1) + grid0.addWidget(gaps_label, 42, 0) + grid0.addWidget(self.gaps, 42, 1) # Buttons self.ff_cutout_object_btn = FCButton(_("Generate Geometry")) @@ -1724,7 +2006,7 @@ class CutoutUI: font-weight: bold; } """) - grid0.addWidget(self.ff_cutout_object_btn, 42, 0, 1, 2) + grid0.addWidget(self.ff_cutout_object_btn, 44, 0, 1, 2) self.rect_cutout_object_btn = FCButton(_("Generate Geometry")) self.rect_cutout_object_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/rectangle32.png')) @@ -1740,14 +2022,12 @@ class CutoutUI: font-weight: bold; } """) - grid0.addWidget(self.rect_cutout_object_btn, 44, 0, 1, 2) + grid0.addWidget(self.rect_cutout_object_btn, 46, 0, 1, 2) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid0.addWidget(separator_line, 46, 0, 1, 2) - - grid0.addWidget(QtWidgets.QLabel(''), 48, 0, 1, 2) + grid0.addWidget(separator_line, 48, 0, 1, 2) # MANUAL BRIDGE GAPS title_manual_label = QtWidgets.QLabel("%s %s:" % (_('Manual'), _("Bridge Gaps"))) diff --git a/appTools/ToolNCC.py b/appTools/ToolNCC.py index 12cc7ec9..0ec1277f 100644 --- a/appTools/ToolNCC.py +++ b/appTools/ToolNCC.py @@ -3855,7 +3855,7 @@ class NccUI: self.grid3.addWidget(self.tool_sel_label, 0, 0, 1, 2) # ### Tool Diameter #### - self.new_tooldia_lbl = FCLabel('%s:' % _('Tool Dia')) + self.new_tooldia_lbl = FCLabel('%s:' % _('Tool Dia')) self.new_tooldia_lbl.setToolTip( _("Diameter for the new tool to add in the Tool Table.\n" "If the tool is V-shape type then this value is automatically\n" diff --git a/app_Main.py b/app_Main.py index c47115a6..ccfe283e 100644 --- a/app_Main.py +++ b/app_Main.py @@ -4259,8 +4259,8 @@ class App(QtCore.QObject): "tools_nccnewdia", # Cutout Tool - "tools_cutouttooldia", 'tools_cutoutmargin', "tools_cutout_z", "tools_cutout_depthperpass", - 'tools_cutoutgapsize', + "tools_cutout_tooldia", 'tools_cutout_margin', "tools_cutout_z", "tools_cutout_depthperpass", + 'tools_cutout_gapsize', 'tools_cutout_gap_depth', 'tools_cutout_mb_dia', 'tools_cutout_mb_spacing', # Paint Tool "tools_painttooldia", 'tools_paintoffset', "tools_paintcutz", "tools_painttipdia", "tools_paintnewdia", @@ -5705,6 +5705,14 @@ class App(QtCore.QObject): callback_on_edited=self.on_tools_db_edited, callback_on_tool_request=self.isolation_tool.on_iso_tool_add_from_db_executed ) + elif source == 'cutout': + self.tools_db_tab = ToolsDB2( + app=self, + parent=self.ui, + callback_on_edited=self.on_tools_db_edited, + callback_on_tool_request=self.cutout_tool.on_cutout_tool_add_from_db_executed + ) + # add the tab if it was closed try: self.ui.plot_tab_area.addTab(self.tools_db_tab, _("Tools Database")) diff --git a/defaults.py b/defaults.py index f20072c9..ff2f3d69 100644 --- a/defaults.py +++ b/defaults.py @@ -476,16 +476,20 @@ class FlatCAMDefaults: "tools_ncc_plotting": 'normal', # Cutout Tool - "tools_cutouttooldia": 2.4, - "tools_cutoutkind": "single", - "tools_cutoutmargin": 0.1, + "tools_cutout_tooldia": 2.4, + "tools_cutout_kind": "single", + "tools_cutout_margin": 0.1, "tools_cutout_z": -1.8, "tools_cutout_depthperpass": 0.6, "tools_cutout_mdepth": True, - "tools_cutoutgapsize": 4, - "tools_gaps_ff": "4", + "tools_cutout_gapsize": 4, + "tools_cutout_gaps_ff": "4", "tools_cutout_convexshape": False, "tools_cutout_big_cursor": True, + "tools_cutout_gap_type": 'b', + "tools_cutout_gap_depth": -1.0, + "tools_cutout_mb_dia": 0.6, + "tools_cutout_mb_spacing": 0.3, # Paint Tool "tools_painttooldia": 0.3, diff --git a/tclCommands/TclCommandCutout.py b/tclCommands/TclCommandCutout.py index ddfd0614..db078beb 100644 --- a/tclCommands/TclCommandCutout.py +++ b/tclCommands/TclCommandCutout.py @@ -73,22 +73,22 @@ class TclCommandCutout(TclCommand): if 'margin' in args: margin_par = float(args['margin']) else: - margin_par = float(self.app.defaults["tools_cutoutmargin"]) + margin_par = float(self.app.defaults["tools_cutout_margin"]) if 'dia' in args: dia_par = float(args['dia']) else: - dia_par = float(self.app.defaults["tools_cutouttooldia"]) + dia_par = float(self.app.defaults["tools_cutout_tooldia"]) if 'gaps' in args: gaps_par = args['gaps'] else: - gaps_par = str(self.app.defaults["tools_gaps_ff"]) + gaps_par = str(self.app.defaults["tools_cutout_gaps_ff"]) if 'gapsize' in args: gapsize_par = float(args['gapsize']) else: - gapsize_par = float(self.app.defaults["tools_cutoutgapsize"]) + gapsize_par = float(self.app.defaults["tools_cutout_gapsize"]) if 'outname' in args: outname = args['outname'] diff --git a/tclCommands/TclCommandGeoCutout.py b/tclCommands/TclCommandGeoCutout.py index 99d18797..e990ed1e 100644 --- a/tclCommands/TclCommandGeoCutout.py +++ b/tclCommands/TclCommandGeoCutout.py @@ -150,22 +150,22 @@ class TclCommandGeoCutout(TclCommandSignaled): if 'margin' in args: margin = float(args['margin']) else: - margin = float(self.app.defaults["tools_cutoutmargin"]) + margin = float(self.app.defaults["tools_cutout_margin"]) if 'dia' in args: dia = float(args['dia']) else: - dia = float(self.app.defaults["tools_cutouttooldia"]) + dia = float(self.app.defaults["tools_cutout_tooldia"]) if 'gaps' in args: gaps = args['gaps'] else: - gaps = str(self.app.defaults["tools_gaps_ff"]) + gaps = str(self.app.defaults["tools_cutout_gaps_ff"]) if 'gapsize' in args: gapsize = float(args['gapsize']) else: - gapsize = float(self.app.defaults["tools_cutoutgapsize"]) + gapsize = float(self.app.defaults["tools_cutout_gapsize"]) if 'outname' in args: outname = args['outname']