Commit e5819cfd authored by sumpfralle's avatar sumpfralle

added a GUI control for defining the "safety height" of the machine

changed the gcode exporter code to allow a specific definition of the safety height (instead of previous "max(safetyheight, homeheight, startz)")
moved "startz" offset (based on the configured measurement unit) from SimpleGCodeExporter to the Gui code to allow more control
slight beautification of the gcode exporter code (added spaces between operators and after commas - according to PEP 8)


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@165 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 282c6af4
......@@ -5,42 +5,40 @@ from gcode import gcode
class SimpleGCodeExporter:
def __init__(self, filename, unit, x, y, z, feedrate, speed):
def __init__(self, filename, unit, startx, starty, startz, feedrate, speed, safety_height=None):
self.file = file(filename,"w")
if unit == "mm":
self.file.write("G21\n")
z += 7.0
else:
self.file.write("G20\n")
z += 0.25
self.gcode = gcode(x,y,z)
self.gcode = gcode(startx, starty, startz, safetyheight=safety_height)
gc = self.gcode
self.file.write(gc.begin()+"\n")
self.file.write("F"+str(feedrate)+"\n")
self.file.write("S"+str(speed)+"\n")
self.file.write(gc.safety()+"\n")
self.file.write(gc.begin() + "\n")
self.file.write("F" + str(feedrate) + "\n")
self.file.write("S" + str(speed) + "\n")
self.file.write(gc.safety() + "\n")
def close(self):
gc = self.gcode
self.file.write(gc.safety()+"\n")
self.file.write(gc.end()+"\n")
self.file.write(gc.safety() + "\n")
self.file.write(gc.end() + "\n")
self.file.close()
def AddPath(self, path):
gc = self.gcode
point = path.points[0]
self.file.write(gc.rapid(point.x,point.y,gc.safetyheight)+"\n")
self.file.write(gc.rapid(point.x, point.y, gc.safetyheight) + "\n")
for point in path.points:
self.file.write(gc.cut(point.x,point.y,point.z)+"\n")
self.file.write(gc.rapid(point.x,point.y,gc.safetyheight)+"\n")
self.file.write(gc.cut(point.x, point.y, point.z) + "\n")
self.file.write(gc.rapid(point.x, point.y, gc.safetyheight) + "\n")
def AddPathList(self, pathlist):
for path in pathlist:
self.AddPath(path)
def ExportPathList(filename, pathlist, unit, x, y, z, feedrate, speed):
exporter = SimpleGCodeExporter(filename, unit, x, y, z, feedrate, speed)
def ExportPathList(filename, pathlist, unit, startx, starty, startz, feedrate, speed, safety_height=None):
exporter = SimpleGCodeExporter(filename, unit, startx, starty, startz, feedrate, speed, safety_height)
exporter.AddPathList(pathlist)
exporter.close()
......@@ -16,12 +16,15 @@ class gcode:
lastx = lasty = lastz = lasta = lastgcode = None
lastfeed = None
def __init__(self, startx, starty, startz, homeheight = 1.5, safetyheight = 0.04):
def __init__(self, startx, starty, startz, homeheight=1.5, safetyheight=None):
self.startx = startx
self.starty = starty
self.startz = startz
self.homeheight = max(startz,homeheight)
self.safetyheight = self.lastz = max(self.homeheight,safetyheight)
if safetyheight is None:
safetyheight = max(max(startz, homeheight), 0.04)
self.homeheight = max(startz, homeheight)
self.safetyheight = safetyheight
self.lastz = max(self.homeheight, safetyheight)
def begin(self):
return "G40 G49 G54 G80 G90\n" + \
......
......@@ -337,7 +337,8 @@ class ProjectGui:
("ToolRadiusControl", "tool_radius"),
("TorusRadiusControl", "torus_radius"),
("FeedrateControl", "feedrate"),
("SpeedControl", "speed")):
("SpeedControl", "speed"),
("SafetyHeightControl", "safety_height")):
obj = self.gui.get_object(objname)
self.settings.add_item(key, obj.get_value, obj.set_value)
# connect buttons with activities
......@@ -638,6 +639,8 @@ class ProjectGui:
def load_model(self, model):
self.model = model
# place the "safe height" clearly above the model's peak
self.settings.set("safety_height", (2 * self.model.maxz - self.model.minz))
# do some initialization
self.append_to_queue(self.reset_bounds)
self.append_to_queue(self.toggle_3d_view, True)
......@@ -759,7 +762,9 @@ class ProjectGui:
self.option = pycam.PathProcessors.PathAccumulator(zigzag=True)
else:
self.option = None
self.pathgenerator = pycam.PathGenerators.DropCutter(self.cutter, self.model, self.option, physics=self.physics);
self.pathgenerator = pycam.PathGenerators.DropCutter(self.cutter,
self.model, self.option, physics=self.physics,
safety_height=self.settings.get("safety_height"))
dx = x_shift
dy = y_shift
if direction == "x":
......@@ -780,7 +785,8 @@ class ProjectGui:
self.option = pycam.PathProcessors.ContourCutter()
else:
self.option = None
self.pathgenerator = pycam.PathGenerators.PushCutter(self.cutter, self.model, self.option, physics=self.physics);
self.pathgenerator = pycam.PathGenerators.PushCutter(self.cutter,
self.model, self.option, physics=self.physics)
if pathprocessor == "ContourCutter":
dx = x_shift
else:
......@@ -869,11 +875,17 @@ class ProjectGui:
return
try:
fi = open(filename, "w")
# TODO: fix these hard-coded offsets
if self.settings.get("unit") == 'mm':
start_offset = 7.0
else:
start_offset = 0.25
exporter = pycam.Exporters.SimpleGCodeExporter.ExportPathList(
filename, self.toolpath, self.settings.get("unit"),
minx, miny, maxz,
minx, miny, maxz + start_offset,
self.gui.get_object("FeedrateControl").get_value(),
self.gui.get_object("SpeedControl").get_value())
self.gui.get_object("SpeedControl").get_value(),
safety_height=self.settings.get("safety_height"))
fi.close()
if self.no_dialog:
print "GCode file successfully written: %s" % str(filename)
......
......@@ -341,7 +341,14 @@ class SimpleGui(Tk.Frame):
maxy = float(self.settings.get("maxy"))+offset
minz = float(self.settings.get("minz"))-offset
maxz = float(self.settings.get("maxz"))+offset
exporter = SimpleGCodeExporter.ExportPathList(filename, self.toolpath, self.settings.get("unit"), minx, miny, maxz, self.FeedRate.get(), self.Speed.get())
if self.settings.get("unit") == 'mm':
start_offset = 7.0
else:
start_offset = 0.25
exporter = SimpleGCodeExporter.ExportPathList(filename,
self.toolpath, self.settings.get("unit"),
minx, miny, maxz + start_offset,
self.FeedRate.get(), self.Speed.get())
def createWidgets(self):
self.ogl = OpenglWidget(self, width=600, height=500, double=1)
......
......@@ -1212,6 +1212,7 @@
<property name="invisible_char">&#x2022;</property>
<property name="adjustment">toolradius</property>
<property name="digits">3</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="left_attach">1</property>
......@@ -1227,6 +1228,7 @@
<property name="invisible_char">&#x2022;</property>
<property name="adjustment">torusradius</property>
<property name="digits">3</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="left_attach">1</property>
......@@ -1299,6 +1301,7 @@
<property name="can_focus">True</property>
<property name="invisible_char">&#x2022;</property>
<property name="adjustment">feedrate</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="left_attach">1</property>
......@@ -1311,6 +1314,7 @@
<property name="can_focus">True</property>
<property name="invisible_char">&#x2022;</property>
<property name="adjustment">speed</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="left_attach">1</property>
......@@ -1660,7 +1664,7 @@ Only available for the Push Cutter.</property>
<child>
<object class="GtkTable" id="table7">
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="n_rows">4</property>
<property name="n_columns">2</property>
<property name="column_spacing">2</property>
<property name="row_spacing">2</property>
......@@ -1671,6 +1675,8 @@ Only available for the Push Cutter.</property>
<property name="label" translatable="yes">Overlap [%]:</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
......@@ -1681,10 +1687,13 @@ Only available for the Push Cutter.</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x2022;</property>
<property name="adjustment">OverlapPercentValue</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
......@@ -1696,8 +1705,8 @@ Only available for the Push Cutter.</property>
<property name="label" translatable="yes">Material Allowance:</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
......@@ -1712,12 +1721,13 @@ ODE support is currently required for this feature.</property>
<property name="invisible_char">&#x2022;</property>
<property name="adjustment">MaterialAllowanceValue</property>
<property name="digits">2</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
......@@ -1730,12 +1740,13 @@ ODE support is currently required for this feature.</property>
<property name="invisible_char">&#x2022;</property>
<property name="adjustment">MaxStepDownValue</property>
<property name="digits">2</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
......@@ -1747,8 +1758,35 @@ ODE support is currently required for this feature.</property>
<property name="label" translatable="yes">Max. Step Down:</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="SafetyHeightLabel">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Safe Height:</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="SafetyHeightControl">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x2022;</property>
<property name="adjustment">SafetyHeightValue</property>
<property name="digits">1</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
......@@ -2328,4 +2366,11 @@ Install the "python-pyode" package to enable this feature.</property>
<property name="page_increment">10</property>
<property name="page_size">10</property>
</object>
<object class="GtkAdjustment" id="SafetyHeightValue">
<property name="lower">-1000</property>
<property name="upper">1000</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
<property name="page_size">10</property>
</object>
</interface>
......@@ -2,22 +2,21 @@ from pycam.PathProcessors import *
from pycam.Geometry import *
from pycam.Geometry.intersection import intersect_lines
import pycam.PathGenerators
from pycam.Geometry.utils import INFINITE
import sys
class DropCutter:
def __init__(self, cutter, model, PathProcessor=None, physics=None):
def __init__(self, cutter, model, PathProcessor=None, physics=None, safety_height=INFINITE):
self.cutter = cutter
self.model = model
self.processor = PathProcessor
self.physics = physics
self.safety_height = safety_height
# used for the non-ode code
self._triangle_last = None
self._cut_last = None
# put the toolpath clearly above the model, if the model exceeds the
# bounding box at certain positions
self._safe_height = self.model.maxz + 4 * (self.model.maxz - self.model.minz)
# remember if we already reported an invalid boundary
self._boundary_warning_already_shown = False
......@@ -123,7 +122,7 @@ class DropCutter:
self.physics.set_drill_position((x.get(), y.get(), dim_height.start))
if self.physics.check_collision():
# the object fills the whole range of z0..z1 - we should issue a warning
next_point = Point(x.get(), y.get(), self._safe_height)
next_point = Point(x.get(), y.get(), self.safety_height)
if not self._boundary_warning_already_shown:
print >>sys.stderr, "WARNING: DropCutter exceed the height" \
+ " of the boundary box: using a safe height " \
......@@ -149,7 +148,7 @@ class DropCutter:
box_y_min = p.y - self.cutter.radius
box_y_max = p.y + self.cutter.radius
box_z_min = dim_height.end
box_z_max = self._safe_height
box_z_max = self.safety_height
triangles = self.model.triangles(box_x_min, box_y_min, box_z_min, box_x_max, box_y_max, box_z_max)
for t in triangles:
if t.normal().z < 0: continue;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment