diff --git a/CHANGELOG.md b/CHANGELOG.md index b576391a..0f9886c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ CHANGELOG for FlatCAM beta ================================================= +27.08.2020 + +- fixed the Tcl commands AddCircle, AddPolygon, AddPolyline and AddRectangle to have stored bounds therefore making them movable/selectable on canvas + 26.08.2020 - fix for issue nr 2 in case of Drilling Tool. Need to check Isolation Tool, Paint Tool, NCC Tool diff --git a/camlib.py b/camlib.py index c9786b9b..628e1656 100644 --- a/camlib.py +++ b/camlib.py @@ -520,69 +520,130 @@ class Geometry(object): for i, g in enumerate(self.flat_geometry): self.index.insert(i, g) - def add_circle(self, origin, radius): + def add_circle(self, origin, radius, tool=None): """ Adds a circle to the object. - :param origin: Center of the circle. - :param radius: Radius of the circle. + :param origin: Center of the circle. + :param radius: Radius of the circle. + :param tool: A tool in the Tools dictionary attribute of the object :return: None """ if self.solid_geometry is None: self.solid_geometry = [] - if type(self.solid_geometry) is list: - self.solid_geometry.append(Point(origin).buffer(radius, int(self.geo_steps_per_circle))) - return + new_circle = Point(origin).buffer(radius, int(self.geo_steps_per_circle)) + if not new_circle.is_valid: + return "fail" + # add to the solid_geometry try: - self.solid_geometry = self.solid_geometry.union( - Point(origin).buffer(radius, int(self.geo_steps_per_circle)) - ) - except Exception as e: - log.error("Failed to run union on polygons. %s" % str(e)) - return + self.solid_geometry.append(new_circle) + except TypeError: + try: + self.solid_geometry = self.solid_geometry.union(new_circle) + except Exception as e: + log.error("Failed to run union on polygons. %s" % str(e)) + return "fail" - def add_polygon(self, points): + # add in tools solid_geometry + if tool is None or tool not in self.tools: + tool = 1 + self.tools[tool]['solid_geometry'].append(new_circle) + + # calculate bounds + try: + xmin, ymin, xmax, ymax = self.bounds() + + self.options['xmin'] = xmin + self.options['ymin'] = ymin + self.options['xmax'] = xmax + self.options['ymax'] = ymax + except Exception as e: + log.error("Failed. The object has no bounds properties. %s" % str(e)) + + def add_polygon(self, points, tool=None): """ Adds a polygon to the object (by union) - :param points: The vertices of the polygon. - :return: None + :param points: The vertices of the polygon. + :param tool: A tool in the Tools dictionary attribute of the object + :return: None """ if self.solid_geometry is None: self.solid_geometry = [] + new_poly = Polygon(points) + if not new_poly.is_valid: + return "fail" + + # add to the solid_geometry if type(self.solid_geometry) is list: - self.solid_geometry.append(Polygon(points)) - return + self.solid_geometry.append(new_poly) + else: + try: + self.solid_geometry = self.solid_geometry.union(Polygon(points)) + except Exception as e: + log.error("Failed to run union on polygons. %s" % str(e)) + return "fail" + # add in tools solid_geometry + if tool is None or tool not in self.tools: + tool = 1 + self.tools[tool]['solid_geometry'].append(new_poly) + + # calculate bounds try: - self.solid_geometry = self.solid_geometry.union(Polygon(points)) - except Exception as e: - log.error("Failed to run union on polygons. %s" % str(e)) - return + xmin, ymin, xmax, ymax = self.bounds() - def add_polyline(self, points): + self.options['xmin'] = xmin + self.options['ymin'] = ymin + self.options['xmax'] = xmax + self.options['ymax'] = ymax + except Exception as e: + log.error("Failed. The object has no bounds properties. %s" % str(e)) + + def add_polyline(self, points, tool=None): """ Adds a polyline to the object (by union) - :param points: The vertices of the polyline. - :return: None + :param points: The vertices of the polyline. + :param tool: A tool in the Tools dictionary attribute of the object + :return: None """ if self.solid_geometry is None: self.solid_geometry = [] - if type(self.solid_geometry) is list: - self.solid_geometry.append(LineString(points)) - return + new_line = LineString(points) + if not new_line.is_valid: + return "fail" + # add to the solid_geometry + if type(self.solid_geometry) is list: + self.solid_geometry.append(new_line) + else: + try: + self.solid_geometry = self.solid_geometry.union(new_line) + except Exception as e: + log.error("Failed to run union on polylines. %s" % str(e)) + return "fail" + + # add in tools solid_geometry + if tool is None or tool not in self.tools: + tool = 1 + self.tools[tool]['solid_geometry'].append(new_line) + + # calculate bounds try: - self.solid_geometry = self.solid_geometry.union(LineString(points)) + xmin, ymin, xmax, ymax = self.bounds() + + self.options['xmin'] = xmin + self.options['ymin'] = ymin + self.options['xmax'] = xmax + self.options['ymax'] = ymax except Exception as e: - log.error("Failed to run union on polylines. %s" % str(e)) - return + log.error("Failed. The object has no bounds properties. %s" % str(e)) def is_empty(self): if isinstance(self.solid_geometry, BaseGeometry) or isinstance(self.solid_geometry, Polygon) or \ diff --git a/tclCommands/TclCommandAddCircle.py b/tclCommands/TclCommandAddCircle.py index f0cd87aa..608c5150 100644 --- a/tclCommands/TclCommandAddCircle.py +++ b/tclCommands/TclCommandAddCircle.py @@ -51,17 +51,18 @@ class TclCommandAddCircle(TclCommand): :return: """ - obj_name = args['name'] + name = args['name'] center_x = args['center_x'] center_y = args['center_y'] radius = args['radius'] try: - obj = self.app.collection.get_by_name(str(obj_name)) + obj = self.app.collection.get_by_name(str(name)) except Exception: - return "Could not retrieve object: %s" % obj_name + return "Could not retrieve object: %s" % name if obj is None: - return "Object not found: %s" % obj_name + return "Object not found: %s" % name + if obj.kind != 'geometry': + self.raise_tcl_error('Expected Geometry, got %s %s.' % (name, type(obj))) obj.add_circle([float(center_x), float(center_y)], float(radius)) - diff --git a/tclCommands/TclCommandAddPolygon.py b/tclCommands/TclCommandAddPolygon.py index 88fea588..4e879398 100644 --- a/tclCommands/TclCommandAddPolygon.py +++ b/tclCommands/TclCommandAddPolygon.py @@ -1,4 +1,3 @@ -from camlib import Geometry from tclCommands.TclCommand import * @@ -51,7 +50,7 @@ class TclCommandAddPolygon(TclCommandSignaled): if obj is None: self.raise_tcl_error("Object not found: %s" % name) - if not isinstance(obj, Geometry): + if obj.kind != 'geometry': self.raise_tcl_error('Expected Geometry, got %s %s.' % (name, type(obj))) if len(unnamed_args) % 2 != 0: @@ -61,4 +60,3 @@ class TclCommandAddPolygon(TclCommandSignaled): points = [[float(unnamed_args[2*i]), float(unnamed_args[2*i+1])] for i in range(nr_points)] obj.add_polygon(points) - obj.plot() diff --git a/tclCommands/TclCommandAddPolyline.py b/tclCommands/TclCommandAddPolyline.py index 79de3790..2412609d 100644 --- a/tclCommands/TclCommandAddPolyline.py +++ b/tclCommands/TclCommandAddPolyline.py @@ -1,6 +1,4 @@ -from camlib import Geometry -import collections -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandAddPolyline(TclCommandSignaled): @@ -52,7 +50,7 @@ class TclCommandAddPolyline(TclCommandSignaled): if obj is None: self.raise_tcl_error("Object not found: %s" % name) - if not isinstance(obj, Geometry): + if obj.kind != 'geometry': self.raise_tcl_error('Expected Geometry, got %s %s.' % (name, type(obj))) if len(unnamed_args) % 2 != 0: @@ -62,4 +60,3 @@ class TclCommandAddPolyline(TclCommandSignaled): points = [[float(unnamed_args[2*i]), float(unnamed_args[2*i+1])] for i in range(nr_points)] obj.add_polyline(points) - obj.plot() diff --git a/tclCommands/TclCommandAddRectangle.py b/tclCommands/TclCommandAddRectangle.py index eff36327..2cbdb0d0 100644 --- a/tclCommands/TclCommandAddRectangle.py +++ b/tclCommands/TclCommandAddRectangle.py @@ -1,5 +1,4 @@ -import collections -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandAddRectangle(TclCommandSignaled): @@ -52,17 +51,23 @@ class TclCommandAddRectangle(TclCommandSignaled): :return: None or exception """ - obj_name = args['name'] + name = args['name'] x0 = args['x0'] y0 = args['y0'] x1 = args['x1'] y1 = args['y1'] + if unnamed_args: + self.raise_tcl_error( + "Too many arguments. Correct format: %s" % '["add_rectangle geo_name xmin ymin xmax ymax"]') + try: - obj = self.app.collection.get_by_name(str(obj_name)) + obj = self.app.collection.get_by_name(str(name)) except Exception: - return "Could not retrieve object: %s" % obj_name + return "Could not retrieve object: %s" % name if obj is None: - return "Object not found: %s" % obj_name + return "Object not found: %s" % name + if obj.kind != 'geometry': + self.raise_tcl_error('Expected Geometry, got %s %s.' % (name, type(obj))) obj.add_polygon([(x0, y0), (x1, y0), (x1, y1), (x0, y1)])