diff --git a/README.md b/README.md index b5beeb69..9773461a 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,10 @@ CAD program, and create G-Code for Isolation routing. 25.08.2019 -- initial add of a new Tcl COmmand named CopperClear +- initial add of a new Tcl Command named CopperClear - remade the NCC Tool in preparation for the newly added TclCommand CopperClear - finished adding the TclCommandCopperClear that can be called with alias: 'ncc' +- added new capability in NCC Tool when the reference object is of Gerber type and fixed some newly introduced errors 24.08.2019 diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index dcb09f4e..41707f37 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -1076,10 +1076,6 @@ class NonCopperClear(FlatCAMTool, Gerber): # ##################################################################### # ####### Read the parameters ######################################### # ##################################################################### - if sel_obj is None: - ncc_sel_obj = self.sel_rect - else: - ncc_sel_obj = sel_obj ncc_method = method if method else self.ncc_method_radio.get_value() @@ -1143,40 +1139,69 @@ class NonCopperClear(FlatCAMTool, Gerber): # ############################################################################################################## # Prepare non-copper polygons. Create the bounding box area from which the copper features will be subtracted ## # ############################################################################################################## - bounding_box = None - if ncc_select == 'itself' or ncc_select == 'box': - geo_n = self.bound_obj.solid_geometry + try: + if sel_obj is None or sel_obj == 'itself': + ncc_sel_obj = ncc_obj + else: + ncc_sel_obj = sel_obj - try: - if isinstance(geo_n, MultiPolygon): - env_obj = geo_n.convex_hull - elif (isinstance(geo_n, MultiPolygon) and len(geo_n) == 1) or \ - (isinstance(geo_n, list) and len(geo_n) == 1) and isinstance(geo_n[0], Polygon): - env_obj = cascaded_union(geo_n) + bounding_box = None + if ncc_select == 'itself': + geo_n = ncc_sel_obj.solid_geometry + + try: + if isinstance(geo_n, MultiPolygon): + env_obj = geo_n.convex_hull + elif (isinstance(geo_n, MultiPolygon) and len(geo_n) == 1) or \ + (isinstance(geo_n, list) and len(geo_n) == 1) and isinstance(geo_n[0], Polygon): + env_obj = cascaded_union(geo_n) + else: + env_obj = cascaded_union(geo_n) + env_obj = env_obj.convex_hull + + bounding_box = env_obj.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre) + except Exception as e: + log.debug("NonCopperClear.on_ncc() --> %s" % str(e)) + self.app.inform.emit(_("[ERROR_NOTCL] No object available.")) + return + elif ncc_select == 'area': + geo_n = MultiPolygon(self.sel_rect) + try: + __ = iter(geo_n) + except TypeError: + geo_n = [geo_n] + + geo_buff_list = [] + for poly in geo_n: + geo_buff_list.append(poly.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre)) + + bounding_box = cascaded_union(geo_buff_list) + elif ncc_select == 'box': + geo_n = ncc_sel_obj.solid_geometry + if isinstance(ncc_sel_obj, FlatCAMGeometry): + try: + __ = iter(geo_n) + except TypeError: + geo_n = [geo_n] + + geo_buff_list = [] + for poly in geo_n: + geo_buff_list.append(poly.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre)) + + bounding_box = cascaded_union(geo_buff_list) + elif isinstance(ncc_sel_obj, FlatCAMGerber): + geo_n = cascaded_union(geo_n).convex_hull + bounding_box = cascaded_union(self.ncc_obj.solid_geometry).convex_hull.intersection(geo_n) + bounding_box = bounding_box.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre) else: - env_obj = cascaded_union(geo_n) - env_obj = env_obj.convex_hull - - bounding_box = env_obj.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre) - except Exception as e: - log.debug("NonCopperClear.on_ncc() --> %s" % str(e)) - self.app.inform.emit(_("[ERROR_NOTCL] No object available.")) - return - elif ncc_select == 'area': - geo_n = ncc_sel_obj - try: - __ = iter(geo_n) - except TypeError: - geo_n = [geo_n] - - geo_buff_list = [] - for poly in geo_n: - geo_buff_list.append(poly.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre)) - - bounding_box = cascaded_union(geo_buff_list) + self.app.inform.emit(_("[ERROR_NOTCL] The reference object type is not supported.")) + return 'fail' + except Exception as e: + log.debug("NonCopperClear.clear_copper() --> %s" % str(e)) + return 'fail' # ################################################################################################### - # calculate the empty area by subtracting the solid_geometry from the object bounding box geometry ## + # Calculate the empty area by subtracting the solid_geometry from the object bounding box geometry ## # ################################################################################################### if isinstance(ncc_obj, FlatCAMGerber): if has_offset is True: diff --git a/tclCommands/TclCommandCopperClear.py b/tclCommands/TclCommandCopperClear.py index 1e163fe6..74b5a9bf 100644 --- a/tclCommands/TclCommandCopperClear.py +++ b/tclCommands/TclCommandCopperClear.py @@ -35,8 +35,8 @@ class TclCommandCopperClear(TclCommand): ('has_offset', bool), ('offset', float), ('rest', bool), - ('all', bool), - ('ref', bool), + ('all', int), + ('ref', int), ('box', str), ('outname', str), ]) @@ -64,10 +64,10 @@ class TclCommandCopperClear(TclCommand): ('rest', 'Use rest-machining. True or False'), ('has_offset', 'The offset will used only if this is set True or present in args. True or False.'), ('offset', 'The copper clearing will finish to a distance from copper features. Float number.'), - ('all', 'Will copper clear the whole object. True or False'), + ('all', 'Will copper clear the whole object. 1 = enabled, anything else = disabled'), ('ref', 'Will clear of extra copper all polygons within a specified object with the name in "box" ' - 'parameter. True or False'), - ('box', 'name of the object to be used as reference when selecting "ref"" True. String.'), + 'parameter. 1 = enabled, anything else = disabled'), + ('box', 'Name of the object to be used as reference. Required when selecting "ref" = 1. String.'), ('outname', 'Name of the resulting Geometry object. String.'), ]), 'examples': [] @@ -132,27 +132,6 @@ class TclCommandCopperClear(TclCommand): else: has_offset = False - if 'rest' in args: - rest = eval(str(args['rest']).capitalize()) - else: - rest = eval(str(self.app.defaults["tools_nccrest"])) - - if 'outname' in args: - outname = args['outname'] - else: - if rest is True: - outname = name + "_ncc" - else: - outname = name + "_ncc_rm" - - # Get source object. - try: - obj = self.app.collection.get_by_name(str(name)) - except Exception as e: - log.debug("TclCommandCopperClear.execute() --> %s" % str(e)) - self.raise_tcl_error("%s: %s" % (_("Could not retrieve object"), name)) - return "Could not retrieve object: %s" % name - try: tools = [float(eval(dia)) for dia in tooldia.split(",") if dia != ''] except AttributeError: @@ -207,12 +186,34 @@ class TclCommandCopperClear(TclCommand): } }) + if 'rest' in args: + rest = eval(str(args['rest']).capitalize()) + else: + rest = eval(str(self.app.defaults["tools_nccrest"])) + + if 'outname' in args: + outname = args['outname'] + else: + if rest is True: + outname = name + "_ncc" + else: + outname = name + "_ncc_rm" + + # Get source object. + try: + obj = self.app.collection.get_by_name(str(name)) + except Exception as e: + log.debug("TclCommandCopperClear.execute() --> %s" % str(e)) + self.raise_tcl_error("%s: %s" % (_("Could not retrieve object"), name)) + return "Could not retrieve object: %s" % name + if obj is None: return "Object not found: %s" % name - # Paint all polygons in the painted object - if 'all' in args and args['all'] is True: + # Non-Copper clear all polygons in the non-copper clear object + if 'all' in args and args['all'] == 1: self.app.ncclear_tool.clear_copper(ncc_obj=obj, + select_method='itself', tooldia=tooldia, overlap=overlap, order=order, @@ -227,8 +228,8 @@ class TclCommandCopperClear(TclCommand): tools_storage=ncc_tools) return - # Paint all polygons found within the box object from the the painted object - elif 'ref' in args and args['ref'] is True: + # Non-Copper clear all polygons found within the box object from the the non_copper cleared object + elif 'ref' in args and args['ref'] == 1: if 'box' not in args: self.raise_tcl_error('%s' % _("Expected -box .")) else: @@ -244,6 +245,7 @@ class TclCommandCopperClear(TclCommand): self.app.ncclear_tool.clear_copper(ncc_obj=obj, sel_obj=box_obj, + select_method='box', tooldia=tooldia, overlap=overlap, order=order, @@ -257,9 +259,8 @@ class TclCommandCopperClear(TclCommand): rest=rest, tools_storage=ncc_tools) return - else: - self.raise_tcl_error("%s:" % _("There was none of the following args: 'ref', 'all'.\n" - "Paint failed.")) - return "There was none of the following args: 'ref', 'all'.\n" \ - "Paint failed." + self.raise_tcl_error("%s:" % _("None of the following args: 'ref', 'all' were found or none was set to 1.\n" + "Copper clearing failed.")) + return "None of the following args: 'ref', 'all' were found or none was set to 1.\n" \ + "Copper clearing failed."