From 67808466d61319f39dfc7f7c0021b27167f92808 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 13 Sep 2019 02:08:26 +0300 Subject: [PATCH] - added control for simplification when loading a Gerber file in Preferences -> Gerber -> Gerber General -> Simplify --- FlatCAMApp.py | 4 ++ README.md | 4 ++ camlib.py | 80 +++++++++++++++++++++++++++++++++------- flatcamGUI/FlatCAMGUI.py | 22 +++++++++++ 4 files changed, 96 insertions(+), 14 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index bca899fb..f600d00f 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -447,6 +447,8 @@ class App(QtCore.QObject): "gerber_multicolored": self.ui.gerber_defaults_form.gerber_gen_group.multicolored_cb, "gerber_circle_steps": self.ui.gerber_defaults_form.gerber_gen_group.circle_steps_entry, "gerber_buffering": self.ui.gerber_defaults_form.gerber_gen_group.buffering_radio, + "gerber_simplification": self.ui.gerber_defaults_form.gerber_gen_group.simplify_cb, + "gerber_simp_tolerance": self.ui.gerber_defaults_form.gerber_gen_group.simplification_tol_spinner, # Gerber Options "gerber_isotooldia": self.ui.gerber_defaults_form.gerber_opt_group.iso_tool_dia_entry, @@ -853,6 +855,8 @@ class App(QtCore.QObject): "gerber_circle_steps": 128, "gerber_use_buffer_for_union": True, "gerber_buffering": "full", + "gerber_simplification": False, + "gerber_simp_tolerance": 0.0005, # Gerber Options "gerber_isotooldia": 0.00787402, diff --git a/README.md b/README.md index ec4528c5..34d0ef1a 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing. ================================================= +13.09.2019 + +- added control for simplification when loading a Gerber file in Preferences -> Gerber -> Gerber General -> Simplify + 12.09.2019 - small changes in the TclCommands: MillDrills, MillSlots, DrillCNCJob: the new parameter for tolerance is now named: tooldia diff --git a/camlib.py b/camlib.py index 97767e3f..b95259bb 100644 --- a/camlib.py +++ b/camlib.py @@ -2457,6 +2457,8 @@ class Gerber (Geometry): line_num = 0 gline = "" + s_tol = float(self.app.defaults["gerber_simp_tolerance"]) + self.app.inform.emit('%s %d %s.' % (_("Gerber processing. Parsing"), len(glines), _("lines"))) try: for gline in glines: @@ -2502,7 +2504,10 @@ class Gerber (Geometry): geo_s = LineString(path).buffer(width / 1.999, int(self.steps_per_circle / 4)) if not geo_s.is_empty: - poly_buffer.append(geo_s) + if self.app.defaults['gerber_simplification']: + poly_buffer.append(geo_s.simplify(s_tol)) + else: + poly_buffer.append(geo_s) if self.is_lpc is True: geo_dict['clear'] = geo_s else: @@ -2692,7 +2697,10 @@ class Gerber (Geometry): geo_dict['follow'] = Point([current_x, current_y]) if not flash.is_empty: - poly_buffer.append(flash) + if self.app.defaults['gerber_simplification']: + poly_buffer.append(flash.simplify(s_tol)) + else: + poly_buffer.append(flash) if self.is_lpc is True: geo_dict['clear'] = flash else: @@ -2743,7 +2751,10 @@ class Gerber (Geometry): width = self.apertures[last_path_aperture]["size"] geo_s = LineString(path).buffer(width / 1.999, int(self.steps_per_circle / 4)) if not geo_s.is_empty: - poly_buffer.append(geo_s) + if self.app.defaults['gerber_simplification']: + poly_buffer.append(geo_s.simplify(s_tol)) + else: + poly_buffer.append(geo_s) if self.is_lpc is True: geo_dict['clear'] = geo_s else: @@ -2776,7 +2787,10 @@ class Gerber (Geometry): width = self.apertures[last_path_aperture]["size"] geo_s = LineString(path).buffer(width / 1.999, int(self.steps_per_circle / 4)) if not geo_s.is_empty: - poly_buffer.append(geo_s) + if self.app.defaults['gerber_simplification']: + poly_buffer.append(geo_s.simplify(s_tol)) + else: + poly_buffer.append(geo_s) if self.is_lpc is True: geo_dict['clear'] = geo_s else: @@ -2817,7 +2831,10 @@ class Gerber (Geometry): geo_dict['follow'] = geo_f if geo_s: if not geo_s.is_empty: - poly_buffer.append(geo_s) + if self.app.defaults['gerber_simplification']: + poly_buffer.append(geo_s.simplify(s_tol)) + else: + poly_buffer.append(geo_s) if self.is_lpc is True: geo_dict['clear'] = geo_s else: @@ -2850,7 +2867,10 @@ class Gerber (Geometry): region_s = region_s.buffer(0, int(self.steps_per_circle / 4)) if not region_s.is_empty: - poly_buffer.append(region_s) + if self.app.defaults['gerber_simplification']: + poly_buffer.append(region_s.simplify(s_tol)) + else: + poly_buffer.append(region_s) if self.is_lpc is True: geo_dict['clear'] = region_s else: @@ -2932,7 +2952,11 @@ class Gerber (Geometry): geo_dict['follow'] = geo_f geo_s = shply_box(minx, miny, maxx, maxy) - poly_buffer.append(geo_s) + if self.app.defaults['gerber_simplification']: + poly_buffer.append(geo_s.simplify(s_tol)) + else: + poly_buffer.append(geo_s) + if self.is_lpc is True: geo_dict['clear'] = geo_s else: @@ -3020,14 +3044,22 @@ class Gerber (Geometry): try: if self.apertures[last_path_aperture]["type"] != 'R': if not geo_s.is_empty: - poly_buffer.append(geo_s) + if self.app.defaults['gerber_simplification']: + poly_buffer.append(geo_s.simplify(s_tol)) + else: + poly_buffer.append(geo_s) + if self.is_lpc is True: geo_dict['clear'] = geo_s else: geo_dict['solid'] = geo_s except Exception as e: log.debug("camlib.Gerber.parse_lines() --> %s" % str(e)) - poly_buffer.append(geo_s) + if self.app.defaults['gerber_simplification']: + poly_buffer.append(geo_s.simplify(s_tol)) + else: + poly_buffer.append(geo_s) + if self.is_lpc is True: geo_dict['clear'] = geo_s else: @@ -3075,13 +3107,21 @@ class Gerber (Geometry): if not geo_s.is_empty: try: if self.apertures[last_path_aperture]["type"] != 'R': - poly_buffer.append(geo_s) + if self.app.defaults['gerber_simplification']: + poly_buffer.append(geo_s.simplify(s_tol)) + else: + poly_buffer.append(geo_s) + if self.is_lpc is True: geo_dict['clear'] = geo_s else: geo_dict['solid'] = geo_s except: - poly_buffer.append(geo_s) + if self.app.defaults['gerber_simplification']: + poly_buffer.append(geo_s.simplify(s_tol)) + else: + poly_buffer.append(geo_s) + if self.is_lpc is True: geo_dict['clear'] = geo_s else: @@ -3111,7 +3151,11 @@ class Gerber (Geometry): self.steps_per_circle ) if not flash.is_empty: - poly_buffer.append(flash) + if self.app.defaults['gerber_simplification']: + poly_buffer.append(flash.simplify(s_tol)) + else: + poly_buffer.append(flash) + if self.is_lpc is True: geo_dict['clear'] = flash else: @@ -3210,7 +3254,11 @@ class Gerber (Geometry): # this treats the case when we are storing geometry as solids buffered = LineString(path).buffer(width / 1.999, int(self.steps_per_circle)) if not buffered.is_empty: - poly_buffer.append(buffered) + if self.app.defaults['gerber_simplification']: + poly_buffer.append(buffered.simplify(s_tol)) + else: + poly_buffer.append(buffered) + if self.is_lpc is True: geo_dict['clear'] = buffered else: @@ -3348,7 +3396,11 @@ class Gerber (Geometry): width = self.apertures[last_path_aperture]["size"] geo_s = LineString(path).buffer(width / 1.999, int(self.steps_per_circle / 4)) if not geo_s.is_empty: - poly_buffer.append(geo_s) + if self.app.defaults['gerber_simplification']: + poly_buffer.append(geo_s.simplify(s_tol)) + else: + poly_buffer.append(geo_s) + if self.is_lpc is True: geo_dict['clear'] = geo_s else: diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 008107d5..290c4435 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -4300,6 +4300,7 @@ class GeneralAppPrefGroupUI(OptionsGroupUI): self.portability_label.hide() self.portability_cb.hide() + class GerberGenPrefGroupUI(OptionsGroupUI): def __init__(self, parent=None): # OptionsGroupUI.__init__(self, "Gerber General Preferences", parent=parent) @@ -4358,6 +4359,27 @@ class GerberGenPrefGroupUI(OptionsGroupUI): grid0.addWidget(buffering_label, 2, 0) grid0.addWidget(self.buffering_radio, 2, 1) + # Simplification + self.simplify_cb = FCCheckBox(label=_('Simplify')) + self.simplify_cb.setToolTip(_("When checked all the Gerber polygons will be\n" + "loaded with simplification having a set tolerance.")) + grid0.addWidget(self.simplify_cb, 3, 0) + + # Simplification tolerance + self.simplification_tol_label = QtWidgets.QLabel(_('Tolerance')) + self.simplification_tol_label.setToolTip(_("Tolerance for poligon simplification.")) + + self.simplification_tol_spinner = FCDoubleSpinner() + self.simplification_tol_spinner.set_precision(5) + self.simplification_tol_spinner.setWrapping(True) + self.simplification_tol_spinner.setRange(0.00000, 0.01000) + self.simplification_tol_spinner.setSingleStep(0.0001) + + grid0.addWidget(self.simplification_tol_label, 4, 0) + grid0.addWidget(self.simplification_tol_spinner, 4, 1) + self.ois_simplif = OptionalInputSection(self.simplify_cb, + [self.simplification_tol_label, self.simplification_tol_spinner], + logic=True) self.layout.addStretch()