diff --git a/camlib.py b/camlib.py
index 67389085..9a4d57b6 100644
--- a/camlib.py
+++ b/camlib.py
@@ -665,6 +665,22 @@ def get_bounds(geometry_set):
def arc(center, radius, start, stop, direction, steps_per_circ):
+ """
+ Creates a Shapely.LineString for the specified arc.
+ @param center: Coordinates of the center [x, y]
+ @type center: list
+ @param radius: Radius of the arc.
+ @type radius: float
+ @param start: Starting angle in radians
+ @type start: float
+ @param stop: End angle in radians
+ @type stop: float
+ @param direction: Orientation of the arc, "CW" or "CCW"
+ @type direction: string
+ @param steps_per_circ: Number of straight line segments to
+ represent a circle.
+ @type steps_per_circ: int
+ """
da_sign = {"cw": -1.0, "ccw": 1.0}
points = []
if direction == "ccw" and stop <= start:
@@ -683,6 +699,41 @@ def arc(center, radius, start, stop, direction, steps_per_circ):
return LineString(points)
+def clear_poly(poly, tooldia, overlap = 0.1):
+ """
+ Creates a list of Shapely geometry objects covering the inside
+ of a Shapely.Polygon. Use for removing all the copper in a region
+ or bed flattening.
+ @param poly: Target polygon
+ @type poly: Shapely.Polygon
+ @param tooldia: Diameter of the tool
+ @type tooldia: float
+ @param overlap: Fraction of the tool diameter to overlap
+ in each pass.
+ @type overlap: float
+ @return list of Shapely.Polygon
+ """
+ poly_cuts = [poly.buffer(-tooldia/2.0)]
+ while True:
+ poly = poly_cuts[-1].buffer(-tooldia*(1-overlap))
+ if poly.area > 0:
+ poly_cuts.append(poly)
+ else:
+ break
+ return poly_cuts
+
+
+def find_polygon(poly_set, point):
+ """
+ Return the first polygon in the list of polygons poly_set
+ that contains the given point.
+ """
+ p = Point(point)
+ for poly in poly_set:
+ if poly.contains(p):
+ return poly
+ return None
+
############### cam.py ####################
def coord(gstr, digits, fraction):
"""
diff --git a/cirkuix.py b/cirkuix.py
index 3a6f0f76..2fa6574d 100644
--- a/cirkuix.py
+++ b/cirkuix.py
@@ -278,7 +278,9 @@ class CirkuixGeometry(CirkuixObj, Geometry):
"multicolored": False,
"cutz": -0.002,
"travelz": 0.1,
- "feedrate": 5.0
+ "feedrate": 5.0,
+ "painttooldia": 0.0625,
+ "paintoverlap": 0.15
})
self.form_kinds.update({
@@ -287,7 +289,9 @@ class CirkuixGeometry(CirkuixObj, Geometry):
"multicolored": "cb",
"cutz": "entry_eval",
"travelz": "entry_eval",
- "feedrate": "entry_eval"
+ "feedrate": "entry_eval",
+ "painttooldia": "entry_eval",
+ "paintoverlap": "entry_eval"
})
def plot(self, figure):
@@ -366,6 +370,8 @@ class App:
# a key if self.stuff
self.selected_item_name = None
+ self.plot_click_subscribers = {}
+
# For debugging only
def someThreadFunc(self):
print "Hello World!"
@@ -707,7 +713,6 @@ class App:
# TODO: Do something if this is None. Offer changing name?
self.new_object("geometry", iso_name, iso_init)
-
def on_generate_cncjob(self, widget):
print "Generating CNC job"
@@ -731,6 +736,30 @@ class App:
self.new_object("cncjob", job_name, job_init)
+ def on_generate_paintarea(self, widget):
+ self.info("Click inside the desired polygon.")
+ geo = self.stuff[self.selected_item_name]
+ geo.read_form()
+ tooldia = geo.options["painttooldia"]
+ overlap = geo.options["paintoverlap"]
+
+ def doit(event):
+ self.plot_click_subscribers.pop("generate_paintarea")
+ self.info("")
+ point = [event.xdata, event.ydata]
+ poly = find_polygon(geo.solid_geometry, point)
+
+ def gen_paintarea(geo_obj, app_obj):
+ assert isinstance(geo_obj, CirkuixGeometry)
+ assert isinstance(app_obj, App)
+ cp = clear_poly(poly, tooldia, overlap)
+ geo_obj.solid_geometry = cp
+
+ name = self.selected_item_name + "_paint"
+ self.new_object("geometry", name, gen_paintarea)
+
+ self.plot_click_subscribers["generate_paintarea"] = doit
+
def on_cncjob_tooldia_activate(self, widget):
job = self.stuff[self.selected_item_name]
tooldia = self.get_eval("entry_eval_cncjob_tooldia")
@@ -947,6 +976,9 @@ class App:
try:
print 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%(
event.button, event.x, event.y, event.xdata, event.ydata)
+
+ for subscriber in self.plot_click_subscribers:
+ self.plot_click_subscribers[subscriber](event)
except:
print "Outside plot!"
diff --git a/cirkuix.ui b/cirkuix.ui
index 84b7d981..c900cf21 100644
--- a/cirkuix.ui
+++ b/cirkuix.ui
@@ -661,6 +661,111 @@
8
+
+
+
+ False
+ True
+ 9
+
+
+
+
+
+ False
+ True
+ 10
+
+
+
+
+ Generate
+ True
+ True
+ True
+
+
+
+
+ False
+ True
+ 11
+
+
+
+
+