Added OS-X installation instructions to manual.
This commit is contained in:
108
camlib.py
108
camlib.py
@@ -154,26 +154,31 @@ class Geometry(object):
|
||||
if reset:
|
||||
self.flat_geometry = []
|
||||
|
||||
## If iterable, expand recursively.
|
||||
try:
|
||||
for geo in geometry:
|
||||
self.flatten_to_paths(geometry=geo, reset=False)
|
||||
|
||||
## Not iterable, do the actual indexing and add.
|
||||
except TypeError:
|
||||
if type(geometry) == Polygon:
|
||||
g = geometry.exterior
|
||||
self.flat_geometry.append(g)
|
||||
self.flat_geometry_rtree.insert(len(self.flat_geometry)-1, g.coords[0])
|
||||
self.flat_geometry_rtree.insert(len(self.flat_geometry)-1, g.coords[-1])
|
||||
|
||||
## Add first and last points of the path to the index.
|
||||
self.flat_geometry_rtree.insert(len(self.flat_geometry) - 1, g.coords[0])
|
||||
self.flat_geometry_rtree.insert(len(self.flat_geometry) - 1, g.coords[-1])
|
||||
|
||||
for interior in geometry.interiors:
|
||||
g = interior
|
||||
self.flat_geometry.append(g)
|
||||
self.flat_geometry_rtree.insert(len(self.flat_geometry)-1, g.coords[0])
|
||||
self.flat_geometry_rtree.insert(len(self.flat_geometry)-1, g.coords[-1])
|
||||
self.flat_geometry_rtree.insert(len(self.flat_geometry) - 1, g.coords[0])
|
||||
self.flat_geometry_rtree.insert(len(self.flat_geometry) - 1, g.coords[-1])
|
||||
else:
|
||||
g = geometry
|
||||
self.flat_geometry.append(g)
|
||||
self.flat_geometry_rtree.insert(len(self.flat_geometry)-1, g.coords[0])
|
||||
self.flat_geometry_rtree.insert(len(self.flat_geometry)-1, g.coords[-1])
|
||||
self.flat_geometry_rtree.insert(len(self.flat_geometry) - 1, g.coords[0])
|
||||
self.flat_geometry_rtree.insert(len(self.flat_geometry) - 1, g.coords[-1])
|
||||
|
||||
return self.flat_geometry, self.flat_geometry_rtree
|
||||
|
||||
@@ -258,17 +263,18 @@ class Geometry(object):
|
||||
:return:
|
||||
"""
|
||||
|
||||
# Estimate good seedpoint if not provided.
|
||||
if seedpoint is None:
|
||||
seedpoint = polygon.representative_point()
|
||||
|
||||
# Current buffer radius
|
||||
radius = tooldia/2*(1-overlap)
|
||||
radius = tooldia / 2 * (1 - overlap)
|
||||
|
||||
# The toolpaths
|
||||
geoms = [Point(seedpoint).buffer(radius).exterior]
|
||||
geoms = []
|
||||
|
||||
# Path margin
|
||||
path_margin = polygon.buffer(-tooldia/2)
|
||||
path_margin = polygon.buffer(-tooldia / 2)
|
||||
|
||||
# Grow from seed until outside the box.
|
||||
while 1:
|
||||
@@ -281,12 +287,12 @@ class Geometry(object):
|
||||
else:
|
||||
geoms.append(path)
|
||||
|
||||
radius += tooldia*(1-overlap)
|
||||
radius += tooldia * (1 - overlap)
|
||||
|
||||
# Clean edges
|
||||
outer_edges = [x.exterior for x in autolist(polygon.buffer(-tooldia/2))]
|
||||
outer_edges = [x.exterior for x in autolist(polygon.buffer(-tooldia / 2))]
|
||||
inner_edges = []
|
||||
for x in autolist(polygon.buffer(-tooldia/2)): # Over resulting polygons
|
||||
for x in autolist(polygon.buffer(-tooldia / 2)): # Over resulting polygons
|
||||
for y in x.interiors: # Over interiors of each polygon
|
||||
inner_edges.append(y)
|
||||
geoms += outer_edges + inner_edges
|
||||
@@ -2198,6 +2204,11 @@ class CNCjob(Geometry):
|
||||
"""
|
||||
Generates G-Code from a Geometry object. Stores in ``self.gcode``.
|
||||
|
||||
Algorithm description:
|
||||
----------------------
|
||||
Follow geometry paths in the order they are being read. No attempt
|
||||
to optimize.
|
||||
|
||||
:param geometry: Geometry defining the toolpath
|
||||
:type geometry: Geometry
|
||||
:param append: Wether to append to self.gcode or re-write it.
|
||||
@@ -2259,14 +2270,21 @@ class CNCjob(Geometry):
|
||||
"""
|
||||
Second algorithm to generate from Geometry.
|
||||
|
||||
ALgorithm description:
|
||||
----------------------
|
||||
Uses RTree to find the nearest path to follow.
|
||||
|
||||
:param geometry:
|
||||
:param append:
|
||||
:param tooldia:
|
||||
:param tolerance:
|
||||
:return:
|
||||
:return: None
|
||||
"""
|
||||
assert isinstance(geometry, Geometry)
|
||||
flat_geometry, rtindex = geometry.flatten_to_paths()
|
||||
|
||||
## Flatten the geometry and get rtree index
|
||||
flat_geometry, rti = geometry.flatten_to_paths()
|
||||
log.debug("%d paths" % len(flat_geometry))
|
||||
|
||||
if tooldia is not None:
|
||||
self.tooldia = tooldia
|
||||
@@ -2285,24 +2303,28 @@ class CNCjob(Geometry):
|
||||
self.gcode += "M03\n" # Spindle start
|
||||
self.gcode += self.pausecode + "\n"
|
||||
|
||||
# Iterate over geometry and run individual methods
|
||||
# depending on type
|
||||
# for geo in flat_geometry:
|
||||
#
|
||||
# if type(geo) == LineString or type(geo) == LinearRing:
|
||||
# self.gcode += self.linear2gcode(geo, tolerance=tolerance)
|
||||
# continue
|
||||
#
|
||||
# if type(geo) == Point:
|
||||
# self.gcode += self.point2gcode(geo)
|
||||
# continue
|
||||
#
|
||||
# log.warning("G-code generation not implemented for %s" % (str(type(geo))))
|
||||
|
||||
hits = list(rtindex.nearest((0, 0), 1))
|
||||
## Iterate over geometry paths getting the nearest each time.
|
||||
path_count = 0
|
||||
current_pt = (0, 0)
|
||||
hits = list(rti.nearest(current_pt, 1))
|
||||
while len(hits) > 0:
|
||||
path_count += 1
|
||||
print "Current: ", "(%.3f, %.3f)" % current_pt
|
||||
geo = flat_geometry[hits[0]]
|
||||
|
||||
# Determine which end of the path is closest.
|
||||
distance2start = distance(current_pt, geo.coords[0])
|
||||
distance2stop = distance(current_pt, geo.coords[-1])
|
||||
print " Path index =", hits[0]
|
||||
print " Start: ", "(%.3f, %.3f)" % geo.coords[0], " D(Start): %.3f" % distance2start
|
||||
print " Stop : ", "(%.3f, %.3f)" % geo.coords[-1], " D(Stop): %.3f" % distance2stop
|
||||
|
||||
# Reverse if end is closest.
|
||||
if distance2start > distance2stop:
|
||||
print " Reversing!"
|
||||
geo.coords = list(geo.coords)[::-1]
|
||||
|
||||
# G-code
|
||||
if type(geo) == LineString or type(geo) == LinearRing:
|
||||
self.gcode += self.linear2gcode(geo, tolerance=tolerance)
|
||||
elif type(geo) == Point:
|
||||
@@ -2310,12 +2332,13 @@ class CNCjob(Geometry):
|
||||
else:
|
||||
log.warning("G-code generation not implemented for %s" % (str(type(geo))))
|
||||
|
||||
start_pt = geo.coords[0]
|
||||
stop_pt = geo.coords[-1]
|
||||
rtindex.delete(hits[0], start_pt)
|
||||
rtindex.delete(hits[0], stop_pt)
|
||||
hits = list(rtindex.nearest(stop_pt, 1))
|
||||
# Delete from index, update current location and continue.
|
||||
rti.delete(hits[0], geo.coords[0])
|
||||
rti.delete(hits[0], geo.coords[-1])
|
||||
current_pt = geo.coords[-1]
|
||||
hits = list(rti.nearest(current_pt, 1))
|
||||
|
||||
log.debug("%s paths traced." % path_count)
|
||||
|
||||
# Finish
|
||||
self.gcode += "G00 Z%.4f\n" % self.z_move # Stop cutting
|
||||
@@ -2518,6 +2541,8 @@ class CNCjob(Geometry):
|
||||
:param tool_tolerance: Tolerance when drawing the toolshape.
|
||||
:return: None
|
||||
"""
|
||||
path_num = 0
|
||||
|
||||
if tooldia is None:
|
||||
tooldia = self.tooldia
|
||||
|
||||
@@ -2531,7 +2556,11 @@ class CNCjob(Geometry):
|
||||
axes.plot(x, y, linespec, color=linecolor)
|
||||
else:
|
||||
for geo in self.gcode_parsed:
|
||||
poly = geo['geom'].buffer(tooldia/2.0).simplify(tool_tolerance)
|
||||
path_num += 1
|
||||
axes.annotate(str(path_num), xy=geo['geom'].coords[0],
|
||||
xycoords='data')
|
||||
|
||||
poly = geo['geom'].buffer(tooldia / 2.0).simplify(tool_tolerance)
|
||||
patch = PolygonPatch(poly, facecolor=color[geo['kind'][0]][0],
|
||||
edgecolor=color[geo['kind'][0]][1],
|
||||
alpha=alpha[geo['kind'][0]], zorder=2)
|
||||
@@ -2812,7 +2841,10 @@ def find_polygon(poly_set, point):
|
||||
|
||||
def to_dict(obj):
|
||||
"""
|
||||
Makes a Shapely geometry object into serializeable form.
|
||||
Makes the following types into serializable form:
|
||||
|
||||
* ApertureMacro
|
||||
* BaseGeometry
|
||||
|
||||
:param obj: Shapely geometry.
|
||||
:type obj: BaseGeometry
|
||||
@@ -3149,3 +3181,7 @@ def three_point_circle(p1, p2, p3):
|
||||
radius = norm(center - p1)
|
||||
|
||||
return center, radius, T[0]
|
||||
|
||||
|
||||
def distance(pt1, pt2):
|
||||
return sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2)
|
||||
Reference in New Issue
Block a user