Просмотр исходного кода

- added the Slot Type parameter for exporting Excellon in Edit -> Preferences -> Excellon -> Export Excellon. Now the Excellon object can be exported also with drilled slot command G85
- fixed bug in Excellon export when there are no zero suppression (coordinates with decimals)

Marius Stanciu 6 лет назад
Родитель
Сommit
c886e3300c
5 измененных файлов с 77 добавлено и 27 удалено
  1. 8 3
      FlatCAMApp.py
  2. 34 16
      FlatCAMObj.py
  3. 2 0
      README.md
  4. 10 8
      camlib.py
  5. 23 0
      flatcamGUI/FlatCAMGUI.py

+ 8 - 3
FlatCAMApp.py

@@ -469,6 +469,7 @@ class App(QtCore.QObject):
             "excellon_exp_integer": self.ui.excellon_defaults_form.excellon_exp_group.format_whole_entry,
             "excellon_exp_integer": self.ui.excellon_defaults_form.excellon_exp_group.format_whole_entry,
             "excellon_exp_decimals": self.ui.excellon_defaults_form.excellon_exp_group.format_dec_entry,
             "excellon_exp_decimals": self.ui.excellon_defaults_form.excellon_exp_group.format_dec_entry,
             "excellon_exp_zeros": self.ui.excellon_defaults_form.excellon_exp_group.zeros_radio,
             "excellon_exp_zeros": self.ui.excellon_defaults_form.excellon_exp_group.zeros_radio,
+            "excellon_exp_slot_type": self.ui.excellon_defaults_form.excellon_exp_group.slot_type_radio,
 
 
             # Excellon Editor
             # Excellon Editor
             "excellon_editor_sel_limit": self.ui.excellon_defaults_form.excellon_editor_group.sel_limit_entry,
             "excellon_editor_sel_limit": self.ui.excellon_defaults_form.excellon_editor_group.sel_limit_entry,
@@ -835,6 +836,7 @@ class App(QtCore.QObject):
             "excellon_exp_integer": 2,
             "excellon_exp_integer": 2,
             "excellon_exp_decimals": 4,
             "excellon_exp_decimals": 4,
             "excellon_exp_zeros": 'LZ',
             "excellon_exp_zeros": 'LZ',
+            "excellon_exp_slot_type": 'routing',
 
 
             # Excellon Editor
             # Excellon Editor
             "excellon_editor_sel_limit": 30,
             "excellon_editor_sel_limit": 30,
@@ -7582,6 +7584,7 @@ class App(QtCore.QObject):
         efract = self.defaults["excellon_exp_decimals"]
         efract = self.defaults["excellon_exp_decimals"]
         ezeros = self.defaults["excellon_exp_zeros"]
         ezeros = self.defaults["excellon_exp_zeros"]
         eformat = self.defaults["excellon_exp_format"]
         eformat = self.defaults["excellon_exp_format"]
+        slot_type = self.defaults["excellon_exp_slot_type"]
 
 
         fc_units = self.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
         fc_units = self.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
         if fc_units == 'MM':
         if fc_units == 'MM':
@@ -7601,7 +7604,7 @@ class App(QtCore.QObject):
                 header += ';Created on : %s' % time_str + '\n'
                 header += ';Created on : %s' % time_str + '\n'
 
 
                 if eformat == 'dec':
                 if eformat == 'dec':
-                    has_slots, excellon_code = obj.export_excellon(ewhole, efract, factor=factor)
+                    has_slots, excellon_code = obj.export_excellon(ewhole, efract, factor=factor, slot_type=slot_type)
                     header += eunits + '\n'
                     header += eunits + '\n'
 
 
                     for tool in obj.tools:
                     for tool in obj.tools:
@@ -7616,7 +7619,8 @@ class App(QtCore.QObject):
                 else:
                 else:
                     if ezeros == 'LZ':
                     if ezeros == 'LZ':
                         has_slots, excellon_code = obj.export_excellon(ewhole, efract,
                         has_slots, excellon_code = obj.export_excellon(ewhole, efract,
-                                                                       form='ndec', e_zeros='LZ', factor=factor)
+                                                                       form='ndec', e_zeros='LZ', factor=factor,
+                                                                       slot_type=slot_type)
                         header += '%s,%s\n' % (eunits, 'LZ')
                         header += '%s,%s\n' % (eunits, 'LZ')
                         header += format_exc
                         header += format_exc
 
 
@@ -7631,7 +7635,8 @@ class App(QtCore.QObject):
                                                                               dec=4)
                                                                               dec=4)
                     else:
                     else:
                         has_slots, excellon_code = obj.export_excellon(ewhole, efract,
                         has_slots, excellon_code = obj.export_excellon(ewhole, efract,
-                                                                       form='ndec', e_zeros='TZ', factor=factor)
+                                                                       form='ndec', e_zeros='TZ', factor=factor,
+                                                                       slot_type=slot_type)
                         header += '%s,%s\n' % (eunits, 'TZ')
                         header += '%s,%s\n' % (eunits, 'TZ')
                         header += format_exc
                         header += format_exc
 
 

+ 34 - 16
FlatCAMObj.py

@@ -2237,7 +2237,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
             item[0] = str(item[0])
             item[0] = str(item[0])
         return table_tools_items
         return table_tools_items
 
 
-    def export_excellon(self, whole, fract, e_zeros=None, form='dec', factor=1):
+    def export_excellon(self, whole, fract, e_zeros=None, form='dec', factor=1, slot_type='routing'):
         """
         """
         Returns two values, first is a boolean , if 1 then the file has slots and second contain the Excellon code
         Returns two values, first is a boolean , if 1 then the file has slots and second contain the Excellon code
         :return: has_slots and Excellon_code
         :return: has_slots and Excellon_code
@@ -2303,6 +2303,8 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
             if self.slots:
             if self.slots:
                 has_slots = 1
                 has_slots = 1
                 for tool in self.tools:
                 for tool in self.tools:
+                    excellon_code += 'G05\n'
+
                     if int(tool) < 10:
                     if int(tool) < 10:
                         excellon_code += 'T0' + str(tool) + '\n'
                         excellon_code += 'T0' + str(tool) + '\n'
                     else:
                     else:
@@ -2314,13 +2316,17 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
                             start_slot_y = slot['start'].y * factor
                             start_slot_y = slot['start'].y * factor
                             stop_slot_x = slot['stop'].x * factor
                             stop_slot_x = slot['stop'].x * factor
                             stop_slot_y = slot['stop'].y * factor
                             stop_slot_y = slot['stop'].y * factor
-
-                            excellon_code += "G00X{:.{dec}f}Y{:.{dec}f}\nM15\n".format(start_slot_x,
-                                                                                       start_slot_y,
-                                                                                       dec=fract)
-                            excellon_code += "G00X{:.{dec}f}Y{:.{dec}f}\nM16\n".format(stop_slot_x,
-                                                                                       stop_slot_y,
-                                                                                       dec=fract)
+                            if slot_type == 'routing':
+                                excellon_code += "G00X{:.{dec}f}Y{:.{dec}f}\nM15\n".format(start_slot_x,
+                                                                                           start_slot_y,
+                                                                                           dec=fract)
+                                excellon_code += "G01X{:.{dec}f}Y{:.{dec}f}\nM16\n".format(stop_slot_x,
+                                                                                           stop_slot_y,
+                                                                                           dec=fract)
+                            elif slot_type == 'drilling':
+                                excellon_code += "X{:.{dec}f}Y{:.{dec}f}G85X{:.{dec}f}Y{:.{dec}f}\nG05\n".format(
+                                    start_slot_x, start_slot_y, stop_slot_x, stop_slot_y, dec=fract
+                                )
 
 
                         elif e_zeros == 'LZ' and tool == slot['tool']:
                         elif e_zeros == 'LZ' and tool == slot['tool']:
                             start_slot_x = slot['start'].x * factor
                             start_slot_x = slot['start'].x * factor
@@ -2352,10 +2358,16 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
                             stop_slot_x_formatted = stop_x_whole + stop_slot_x_formatted[2]
                             stop_slot_x_formatted = stop_x_whole + stop_slot_x_formatted[2]
                             stop_slot_y_formatted = stop_y_whole + stop_slot_y_formatted[2]
                             stop_slot_y_formatted = stop_y_whole + stop_slot_y_formatted[2]
 
 
-                            excellon_code += "G00X{xstart}Y{ystart}\nM15\n".format(xstart=start_slot_x_formatted,
-                                                                                   ystart=start_slot_y_formatted)
-                            excellon_code += "G00X{xstop}Y{ystop}\nM16\n".format(xstop=stop_slot_x_formatted,
-                                                                                 ystop=stop_slot_y_formatted)
+                            if slot_type == 'routing':
+                                excellon_code += "G00X{xstart}Y{ystart}\nM15\n".format(xstart=start_slot_x_formatted,
+                                                                                       ystart=start_slot_y_formatted)
+                                excellon_code += "G01X{xstop}Y{ystop}\nM16\n".format(xstop=stop_slot_x_formatted,
+                                                                                     ystop=stop_slot_y_formatted)
+                            elif slot_type == 'drilling':
+                                excellon_code += "{xstart}Y{ystart}G85X{xstop}Y{ystop}\nG05\n".format(
+                                    xstart=start_slot_x_formatted, ystart=start_slot_y_formatted,
+                                    xstop=stop_slot_x_formatted, ystop=stop_slot_y_formatted
+                                )
                         elif tool == slot['tool']:
                         elif tool == slot['tool']:
                             start_slot_x = slot['start'].x * factor
                             start_slot_x = slot['start'].x * factor
                             start_slot_y = slot['start'].y * factor
                             start_slot_y = slot['start'].y * factor
@@ -2374,10 +2386,16 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
                             stop_slot_x_formatted.ljust(length, '0')
                             stop_slot_x_formatted.ljust(length, '0')
                             stop_slot_y_formatted.ljust(length, '0')
                             stop_slot_y_formatted.ljust(length, '0')
 
 
-                            excellon_code += "G00X{xstart}Y{ystart}\nM15\n".format(xstart=start_slot_x_formatted,
-                                                                                   ystart=start_slot_y_formatted)
-                            excellon_code += "G00X{xstop}Y{ystop}\nM16\n".format(xstop=stop_slot_x_formatted,
-                                                                                 ystop=stop_slot_y_formatted)
+                            if slot_type == 'routing':
+                                excellon_code += "G00X{xstart}Y{ystart}\nM15\n".format(xstart=start_slot_x_formatted,
+                                                                                       ystart=start_slot_y_formatted)
+                                excellon_code += "G01X{xstop}Y{ystop}\nM16\n".format(xstop=stop_slot_x_formatted,
+                                                                                     ystop=stop_slot_y_formatted)
+                            elif slot_type == 'drilling':
+                                excellon_code += "{xstart}Y{ystart}G85X{xstop}Y{ystop}\nG05\n".format(
+                                    xstart=start_slot_x_formatted, ystart=start_slot_y_formatted,
+                                    xstop=stop_slot_x_formatted, ystop=stop_slot_y_formatted
+                                )
         except Exception as e:
         except Exception as e:
             log.debug(str(e))
             log.debug(str(e))
 
 

+ 2 - 0
README.md

@@ -24,6 +24,8 @@ CAD program, and create G-Code for Isolation routing.
 - added the key shortcut handlers for Add Slot and Add Slot Array tools in Excellon Editor
 - added the key shortcut handlers for Add Slot and Add Slot Array tools in Excellon Editor
 - started to work on the Resize tool for the case of Excellon slots in Excellon Editor
 - started to work on the Resize tool for the case of Excellon slots in Excellon Editor
 - final fix for the VisPy data files; the defaults files are saved to the Config folder when the app is set to be portable
 - final fix for the VisPy data files; the defaults files are saved to the Config folder when the app is set to be portable
+- added the Slot Type parameter for exporting Excellon in Edit -> Preferences -> Excellon -> Export Excellon. Now the Excellon object can be exported also with drilled slot command G85
+- fixed bug in Excellon export when there are no zero suppression (coordinates with decimals)
 
 
 14.08.2019
 14.08.2019
 
 

+ 10 - 8
camlib.py

@@ -3979,10 +3979,10 @@ class Excellon(Geometry):
                         ':' + str(self.excellon_format_lower_in))
                         ':' + str(self.excellon_format_lower_in))
                     continue
                     continue
 
 
-                #### Body ## ##
+                # ### Body ####
                 if not in_header:
                 if not in_header:
 
 
-                    # ## Tool change # ##
+                    # ## Tool change ###
                     match = self.toolsel_re.search(eline)
                     match = self.toolsel_re.search(eline)
                     if match:
                     if match:
                         current_tool = str(int(match.group(1)))
                         current_tool = str(int(match.group(1)))
@@ -4022,7 +4022,7 @@ class Excellon(Geometry):
 
 
                         continue
                         continue
 
 
-                    # ## Allegro Type Tool change # ##
+                    # ## Allegro Type Tool change ###
                     if allegro_warning is True:
                     if allegro_warning is True:
                         match = self.absinc_re.search(eline)
                         match = self.absinc_re.search(eline)
                         match1 = self.stop_re.search(eline)
                         match1 = self.stop_re.search(eline)
@@ -4114,7 +4114,7 @@ class Excellon(Geometry):
                             )
                             )
                             continue
                             continue
 
 
-                        # Slot coordinates with period: Use literally. # ##
+                        # Slot coordinates with period: Use literally. ###
                         # get the coordinates for slot start and for slot stop into variables
                         # get the coordinates for slot start and for slot stop into variables
                         start_coords_period = self.coordsperiod_re.search(start_coords_match)
                         start_coords_period = self.coordsperiod_re.search(start_coords_match)
                         stop_coords_period = self.coordsperiod_re.search(stop_coords_match)
                         stop_coords_period = self.coordsperiod_re.search(stop_coords_match)
@@ -4274,7 +4274,6 @@ class Excellon(Geometry):
                     if match:
                     if match:
                         # signal that there are drill operations
                         # signal that there are drill operations
                         self.defaults['excellon_drills'] = True
                         self.defaults['excellon_drills'] = True
-
                         try:
                         try:
                             x = float(match.group(1))
                             x = float(match.group(1))
                             repeating_x = current_x
                             repeating_x = current_x
@@ -4346,7 +4345,7 @@ class Excellon(Geometry):
                             # log.debug("{:15} {:8} {:8}".format(eline, x, y))
                             # log.debug("{:15} {:8} {:8}".format(eline, x, y))
                             continue
                             continue
 
 
-                #### Header ## ##
+                # ### Header ####
                 if in_header:
                 if in_header:
 
 
                     # ## Tool definitions # ##
                     # ## Tool definitions # ##
@@ -4484,7 +4483,7 @@ class Excellon(Geometry):
         match = self.leadingzeros_re.search(number_str)
         match = self.leadingzeros_re.search(number_str)
         nr_length = len(match.group(1)) + len(match.group(2))
         nr_length = len(match.group(1)) + len(match.group(2))
         try:
         try:
-            if self.zeros == "L" or self.zeros == "LZ":
+            if self.zeros == "L" or self.zeros == "LZ": # Leading
                 # With leading zeros, when you type in a coordinate,
                 # With leading zeros, when you type in a coordinate,
                 # the leading zeros must always be included.  Trailing zeros
                 # the leading zeros must always be included.  Trailing zeros
                 # are unneeded and may be left off. The CNC-7 will automatically add them.
                 # are unneeded and may be left off. The CNC-7 will automatically add them.
@@ -4498,7 +4497,7 @@ class Excellon(Geometry):
                 else:
                 else:
                     result = float(number_str) / (10 ** (float(nr_length) - float(self.excellon_format_upper_mm)))
                     result = float(number_str) / (10 ** (float(nr_length) - float(self.excellon_format_upper_mm)))
                 return result
                 return result
-            else:  # Trailing
+            elif self.zeros == "T" or self.zeros == "TZ":  # Trailing
                 # You must show all zeros to the right of the number and can omit
                 # You must show all zeros to the right of the number and can omit
                 # all zeros to the left of the number. The CNC-7 will count the number
                 # all zeros to the left of the number. The CNC-7 will count the number
                 # of digits you typed and automatically fill in the missing zeros.
                 # of digits you typed and automatically fill in the missing zeros.
@@ -4510,6 +4509,9 @@ class Excellon(Geometry):
                 else:   # Metric is 000.000
                 else:   # Metric is 000.000
                     result = float(number_str) / (10 ** (float(self.excellon_format_lower_mm)))
                     result = float(number_str) / (10 ** (float(self.excellon_format_lower_mm)))
                 return result
                 return result
+            else: # None - the numbers are in decimal format
+                return float(number_str)
+
         except Exception as e:
         except Exception as e:
             log.error("Aborted. Operation could not be completed due of %s" % str(e))
             log.error("Aborted. Operation could not be completed due of %s" % str(e))
             return
             return

+ 23 - 0
flatcamGUI/FlatCAMGUI.py

@@ -5146,6 +5146,29 @@ class ExcellonExpPrefGroupUI(OptionsGroupUI):
 
 
         form.addRow(self.zeros_label, self.zeros_radio)
         form.addRow(self.zeros_label, self.zeros_radio)
 
 
+        # Slot type
+        self.slot_type_label = QtWidgets.QLabel(_('<b>Slot type</b>:'))
+        self.slot_type_label.setAlignment(QtCore.Qt.AlignLeft)
+        self.slot_type_label.setToolTip(
+            _("This sets how the slots will be exported.\n"
+              "If ROUTED then the slots will be routed\n"
+              "using M15/M16 commands.\n"
+              "If DRILLED(G85) the slots will be exported\n"
+              "using the Drilled slot command (G85).")
+        )
+
+        self.slot_type_radio = RadioSet([{'label': _('Routed'), 'value': 'routing'},
+                                         {'label': _('Drilled(G85)'), 'value': 'drilling'}])
+        self.slot_type_radio.setToolTip(
+            _("This sets how the slots will be exported.\n"
+              "If ROUTED then the slots will be routed\n"
+              "using M15/M16 commands.\n"
+              "If DRILLED(G85) the slots will be exported\n"
+              "using the Drilled slot command (G85).")
+        )
+
+        form.addRow(self.slot_type_label, self.slot_type_radio)
+
         self.layout.addStretch()
         self.layout.addStretch()
         self.format_radio.activated_custom.connect(self.optimization_selection)
         self.format_radio.activated_custom.connect(self.optimization_selection)