From 5838bd0554836eb334a9f0fe813601f90f991af8 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Tue, 10 Sep 2019 13:45:12 +0300 Subject: [PATCH] - added progress for the generation of Isolation geometry --- FlatCAMObj.py | 18 ++++++++---- README.md | 1 + camlib.py | 77 ++++++++++++++++++++++++++++++--------------------- 3 files changed, 58 insertions(+), 38 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 0ce36c83..8e9f50ac 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -952,7 +952,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): base_name = self.options["name"] + "_iso" base_name = outname or base_name - def generate_envelope(offset, invert, envelope_iso_type=2, follow=None): + def generate_envelope(offset, invert, envelope_iso_type=2, follow=None, passes=0): # isolation_geometry produces an envelope that is going on the left of the geometry # (the copper features). To leave the least amount of burrs on the features # the tool needs to travel on the right side of the features (this is called conventional milling) @@ -960,7 +960,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): # the other passes overlap preceding ones and cut the left over copper. It is better for them # to cut on the right side of the left over copper i.e on the left side of the features. try: - geom = self.isolation_geometry(offset, iso_type=envelope_iso_type, follow=follow) + geom = self.isolation_geometry(offset, iso_type=envelope_iso_type, follow=follow, passes=passes) except Exception as e: log.debug('FlatCAMGerber.isolate().generate_envelope() --> %s' % str(e)) return 'fail' @@ -1076,9 +1076,11 @@ class FlatCAMGerber(FlatCAMObj, Gerber): # if milling type is climb then the move is counter-clockwise around features if milling_type == 'cl': # geom = generate_envelope (offset, i == 0) - geom = generate_envelope(iso_offset, 1, envelope_iso_type=self.iso_type, follow=follow) + geom = generate_envelope(iso_offset, 1, envelope_iso_type=self.iso_type, follow=follow, + passes=i) else: - geom = generate_envelope(iso_offset, 0, envelope_iso_type=self.iso_type, follow=follow) + geom = generate_envelope(iso_offset, 0, envelope_iso_type=self.iso_type, follow=follow, + passes=i) if geom == 'fail': app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated.")) @@ -1152,6 +1154,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): # ########## AREA SUBTRACTION ################################ # ############################################################ if self.ui.except_cb.get_value(): + self.app.proc_container.update_view_text(' %s' % _("Subtracting Geo")) geo_obj.solid_geometry = area_subtraction(geo_obj.solid_geometry) # TODO: Do something if this is None. Offer changing name? @@ -1183,9 +1186,11 @@ class FlatCAMGerber(FlatCAMObj, Gerber): # if milling type is climb then the move is counter-clockwise around features if milling_type == 'cl': # geo_obj.solid_geometry = generate_envelope(offset, i == 0) - geom = generate_envelope(offset, 1, envelope_iso_type=self.iso_type, follow=follow) + geom = generate_envelope(offset, 1, envelope_iso_type=self.iso_type, follow=follow, + passes=i) else: - geom = generate_envelope(offset, 0, envelope_iso_type=self.iso_type, follow=follow) + geom = generate_envelope(offset, 0, envelope_iso_type=self.iso_type, follow=follow, + passes=i) if geom == 'fail': app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated.")) @@ -1218,6 +1223,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): # ########## AREA SUBTRACTION ################################ # ############################################################ if self.ui.except_cb.get_value(): + self.app.proc_container.update_view_text(' %s' % _("Subtracting Geo")) geo_obj.solid_geometry = area_subtraction(geo_obj.solid_geometry) # TODO: Do something if this is None. Offer changing name? diff --git a/README.md b/README.md index ad642353..d43ccfef 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ CAD program, and create G-Code for Isolation routing. - fixed a small typo in TclCommandCopperCLear - made changing the Plot kind in CNCJob selected tab, threaded - fixed an object used before declaring it in NCC Tool - Area option +- added progress for the generation of Isolation geometry 9.09.2019 diff --git a/camlib.py b/camlib.py index 61f97f80..47ed7182 100644 --- a/camlib.py +++ b/camlib.py @@ -523,7 +523,7 @@ class Geometry(object): # # return self.flat_geometry, self.flat_geometry_rtree - def isolation_geometry(self, offset, iso_type=2, corner=None, follow=None): + def isolation_geometry(self, offset, iso_type=2, corner=None, follow=None, passes=0): """ Creates contours around geometry at a given offset distance. @@ -533,36 +533,11 @@ class Geometry(object): :param iso_type: type of isolation, can be 0 = exteriors or 1 = interiors or 2 = both (complete) :param corner: type of corner for the isolation: 0 = round; 1 = square; 2= beveled (line that connects the ends) :param follow: whether the geometry to be isolated is a follow_geometry + :param passes: current pass out of possible multiple passes for which the isolation is done :return: The buffered geometry. :rtype: Shapely.MultiPolygon or Shapely.Polygon """ - # geo_iso = [] - # In case that the offset value is zero we don't use the buffer as the resulting geometry is actually the - # original solid_geometry - # if offset == 0: - # geo_iso = self.solid_geometry - # else: - # flattened_geo = self.flatten_list(self.solid_geometry) - # try: - # for mp_geo in flattened_geo: - # geo_iso.append(mp_geo.buffer(offset, int(int(self.geo_steps_per_circle) / 4))) - # except TypeError: - # geo_iso.append(self.solid_geometry.buffer(offset, int(int(self.geo_steps_per_circle) / 4))) - # return geo_iso - - # commented this because of the bug with multiple passes cutting out of the copper - # geo_iso = [] - # flattened_geo = self.flatten_list(self.solid_geometry) - # try: - # for mp_geo in flattened_geo: - # geo_iso.append(mp_geo.buffer(offset, int(int(self.geo_steps_per_circle) / 4))) - # except TypeError: - # geo_iso.append(self.solid_geometry.buffer(offset, int(int(self.geo_steps_per_circle) / 4))) - - # the previously commented block is replaced with this block - regression - to solve the bug with multiple - # isolation passes cutting from the copper features - if self.app.abort_flag: # graceful abort requested by the user raise FlatCAMApp.GracefulException @@ -584,11 +559,47 @@ class Geometry(object): # Remember: do not make a buffer for each element in the solid_geometry because it will cut into # other copper features - if corner is None: - geo_iso = temp_geo.buffer(offset, int(int(self.geo_steps_per_circle) / 4)) - else: - geo_iso = temp_geo.buffer(offset, int(int(self.geo_steps_per_circle) / 4), - join_style=corner) + # if corner is None: + # geo_iso = temp_geo.buffer(offset, int(int(self.geo_steps_per_circle) / 4)) + # else: + # geo_iso = temp_geo.buffer(offset, int(int(self.geo_steps_per_circle) / 4), + # join_style=corner) + + # variables to display the percentage of work done + geo_len = 0 + try: + for pol in self.solid_geometry: + geo_len += 1 + except TypeError: + geo_len = 1 + disp_number = 0 + old_disp_number = 0 + pol_nr = 0 + # yet, it can be done by issuing an unary_union in the end, thus getting rid of the overlapping geo + try: + for pol in self.solid_geometry: + if corner is None: + geo_iso.append(pol.buffer(offset, int(int(self.geo_steps_per_circle) / 4))) + else: + geo_iso.append(pol.buffer(offset, int(int(self.geo_steps_per_circle) / 4)), + join_style=corner) + pol_nr += 1 + disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 99])) + + if disp_number > old_disp_number and disp_number <= 100: + self.app.proc_container.update_view_text(' %s %d: %d%%' % + (_("Pass"), int(passes + 1), int(disp_number))) + old_disp_number = disp_number + except TypeError: + # taking care of the case when the self.solid_geometry is just a single Polygon, not a list or a + # MultiPolygon (not an iterable) + if corner is None: + geo_iso.append(self.solid_geometry.buffer(offset, int(int(self.geo_steps_per_circle) / 4))) + else: + geo_iso.append(self.solid_geometry.buffer(offset, int(int(self.geo_steps_per_circle) / 4)), + join_style=corner) + self.app.proc_container.update_view_text(' %s' % _("Buffering")) + geo_iso = unary_union(geo_iso) # end of replaced block if follow: @@ -596,8 +607,10 @@ class Geometry(object): elif iso_type == 2: return geo_iso elif iso_type == 0: + self.app.proc_container.update_view_text(' %s' % _("Get Exteriors")) return self.get_exteriors(geo_iso) elif iso_type == 1: + self.app.proc_container.update_view_text(' %s' % _("Get Interiors")) return self.get_interiors(geo_iso) else: log.debug("Geometry.isolation_geometry() --> Type of isolation not supported")