Added OS-X installation instructions to manual.
This commit is contained in:
parent
6fae5258db
commit
a0d6d1a6a9
|
@ -2419,16 +2419,18 @@ class App(QtCore.QObject):
|
|||
try:
|
||||
f = open(filename, 'w')
|
||||
except IOError:
|
||||
App.log.error("[error] Failed to open file for saving:", filename)
|
||||
App.log.error("[error] Failed to open file for saving: %s", filename)
|
||||
return
|
||||
|
||||
# Write
|
||||
try:
|
||||
json.dump(d, f, default=to_dict)
|
||||
except:
|
||||
App.log.error("[error] File open but failed to write:", filename)
|
||||
f.close()
|
||||
return
|
||||
json.dump(d, f, default=to_dict)
|
||||
# try:
|
||||
# json.dump(d, f, default=to_dict)
|
||||
# except Exception, e:
|
||||
# print str(e)
|
||||
# App.log.error("[error] File open but failed to write: %s", filename)
|
||||
# f.close()
|
||||
# return
|
||||
|
||||
f.close()
|
||||
|
||||
|
|
|
@ -800,7 +800,6 @@ class FlatCAMDraw(QtCore.QObject):
|
|||
self.shape_buffer.remove(shape)
|
||||
|
||||
# Add the new utility shape
|
||||
#self.shape_buffer.append(geo)
|
||||
self.add_shape(geo)
|
||||
|
||||
# Efficient plotting for fast animation
|
||||
|
@ -811,13 +810,12 @@ class FlatCAMDraw(QtCore.QObject):
|
|||
self.axes.draw_artist(el)
|
||||
#self.canvas.canvas.blit(self.axes.bbox)
|
||||
|
||||
#self.replot()
|
||||
# Pointer (snapped)
|
||||
elements = self.axes.plot(x, y, 'bo', animated=True)
|
||||
for el in elements:
|
||||
self.axes.draw_artist(el)
|
||||
|
||||
elements = self.axes.plot(x, y, 'bo', animated=True)
|
||||
for el in elements:
|
||||
self.axes.draw_artist(el)
|
||||
|
||||
self.canvas.canvas.blit(self.axes.bbox)
|
||||
self.canvas.canvas.blit(self.axes.bbox)
|
||||
|
||||
def on_canvas_key(self, event):
|
||||
"""
|
||||
|
@ -905,7 +903,7 @@ class FlatCAMDraw(QtCore.QObject):
|
|||
|
||||
def plot_shape(self, geometry=None, linespec='b-', linewidth=1, animated=False):
|
||||
"""
|
||||
Plots a geometric object or list of objects without rendeting. Plotted objects
|
||||
Plots a geometric object or list of objects without rendering. Plotted objects
|
||||
are returned as a list. This allows for efficient/animated rendering.
|
||||
|
||||
:param geometry: Geometry to be plotted (Any Shapely.geom kind or list of such)
|
||||
|
@ -971,7 +969,6 @@ class FlatCAMDraw(QtCore.QObject):
|
|||
:type shape: DrawToolShape
|
||||
:return: None
|
||||
"""
|
||||
print "add_shape()"
|
||||
|
||||
# List of DrawToolShape?
|
||||
if isinstance(shape, list):
|
||||
|
|
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)
|
|
@ -7,7 +7,8 @@ Drawing
|
|||
* [DONE] Arcs
|
||||
* [DONE] Subtract Shapes
|
||||
* [DONE] Selected objects must be kept onlist to preserve order.
|
||||
* Polygon to outline
|
||||
* [DONE] Cut Path
|
||||
* Polygon to outline
|
||||
* Force perpendicular
|
||||
* Un-group (Union creates group)
|
||||
* Group (But not union)
|
||||
|
|
|
@ -4,16 +4,27 @@ Installation
|
|||
Windows Installer
|
||||
-----------------
|
||||
|
||||
Download the installer from the repository_ and run it in your machine. It includes everything you need.
|
||||
Download the installer from the repository_ and run it in your machine.
|
||||
It includes everything you need.
|
||||
|
||||
.. _repository: https://bitbucket.org/jpcgt/flatcam/downloads
|
||||
|
||||
Ubuntu
|
||||
------
|
||||
|
||||
FlatCAM should work on most Linux distributions but Ubuntu has been chosen as the test platform.
|
||||
FlatCAM should work on most Linux distributions but Ubuntu has been
|
||||
chosen as the test platform.
|
||||
|
||||
There are several dependencies required to run FlatCAM. These are
|
||||
listed in the following section. Before attempting a manual installation,
|
||||
try running the provided setup script ``setup_ubuntu.sh`` that will
|
||||
download and install required packages.
|
||||
|
||||
OS-X
|
||||
----
|
||||
|
||||
See manual instructions below.
|
||||
|
||||
There are several dependencies required to run FlatCAM. These are listed in the following section. Before attempting a manual installation, try running the provided setup script ``setup_ubuntu.sh`` that will download and install required packages.
|
||||
|
||||
Manual Installation
|
||||
-------------------
|
||||
|
@ -26,6 +37,9 @@ Requirements
|
|||
* Matplotlib 1.3.1
|
||||
* Numpy 1.8
|
||||
* `Shapely 1.3`_
|
||||
* GEOS
|
||||
* RTree
|
||||
* SpatialIndex
|
||||
|
||||
.. _Shapely 1.3: https://pypi.python.org/pypi/Shapely
|
||||
|
||||
|
@ -34,9 +48,14 @@ These packages might have their own dependencies.
|
|||
Linux
|
||||
~~~~~
|
||||
|
||||
Under Linux, most modern package installers like **yum** or **apt-get** will attempt to locate and install the whole tree of dependencies for a specified package automatically. Refer to the provided setup script ``setup_ubuntu.sh`` for the names and installation order.
|
||||
Under Linux, most modern package installers like **yum** or **apt-get**
|
||||
will attempt to locate and install the whole tree of dependencies for a
|
||||
specified package automatically. Refer to the provided setup script
|
||||
``setup_ubuntu.sh`` for the names and installation order.
|
||||
|
||||
Once the dependencies are installed, download the latest .zip release (or the latest source, although it is not garanteed to work), unpack it, change into the created folder and run::
|
||||
Once the dependencies are installed, download the latest .zip release
|
||||
(or the latest source, although it is not garanteed to work), unpack it,
|
||||
change into the created folder and run::
|
||||
|
||||
Python FlatCAM.py
|
||||
|
||||
|
@ -44,11 +63,36 @@ Once the dependencies are installed, download the latest .zip release (or the la
|
|||
Windows
|
||||
~~~~~~~
|
||||
|
||||
An easy way to get the requirements in your system is to install WinPython_. This is a standalone distribution of Python which includes all of FlatCAM's dependencies, except for Shapely.
|
||||
An easy way to get the requirements in your system is to install WinPython_.
|
||||
This is a standalone distribution of Python which includes all of FlatCAM's
|
||||
dependencies, except for Shapely.
|
||||
|
||||
.. _WinPython: http://winpython.sourceforge.net/
|
||||
|
||||
Once the dependencies are installed, download the latest .zip release (or the latest source, although it is not garanteed to work), unpack it, change into the created folder and run::
|
||||
Once the dependencies are installed, download the latest .zip
|
||||
release (or the latest source, although it is not garanteed to work),
|
||||
unpack it, change into the created folder and run::
|
||||
|
||||
Python FlatCAM.py
|
||||
python FlatCAM.py
|
||||
|
||||
|
||||
OS-X
|
||||
~~~~
|
||||
|
||||
Start by installing binary packages: pyqt, geos, spatialindex.
|
||||
One way to do this is using Homebrew_::
|
||||
|
||||
brew install name_of_package
|
||||
|
||||
.. _Homebrew: http://brew.sh
|
||||
|
||||
Now you can install all Python packages (numpy, matplotlib, rtree, scipy,
|
||||
shapely, simplejson) using pip::
|
||||
|
||||
pip install name_of_package
|
||||
|
||||
Finally, download the latest FlatCAM .zip package or source code. Change into
|
||||
its directory and launch it by running::
|
||||
|
||||
python FlatCAM.py
|
||||
|
||||
|
|
Loading…
Reference in New Issue