Commit 94e0fa35 authored by sumpfralle's avatar sumpfralle

added configuration setting for the boundary mode (move inside/along/around the boundary limits)


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@284 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 12f29a38
...@@ -4,6 +4,7 @@ Version 0.2.3 - UNRELEASED ...@@ -4,6 +4,7 @@ Version 0.2.3 - UNRELEASED
* fixed "overlap" calculation * fixed "overlap" calculation
* added a warning dialog (GUI) for missing dependencies during startup (especially useful for Windows) * added a warning dialog (GUI) for missing dependencies during startup (especially useful for Windows)
* improved GUI for model scaling * improved GUI for model scaling
* allow to configure if the tool should move inside/along/around the boundary limits
* prevent invalid input values (zero tool radius, ...) * prevent invalid input values (zero tool radius, ...)
* reduced memory consumption of toolpaths for python 2.6 or above * reduced memory consumption of toolpaths for python 2.6 or above
......
...@@ -63,7 +63,6 @@ def get_data_file_location(filename): ...@@ -63,7 +63,6 @@ def get_data_file_location(filename):
print >>sys.stderr, "You can extend the search path by setting the environment variable '%s'." % str(DATA_DIR_ENVIRON_KEY) print >>sys.stderr, "You can extend the search path by setting the environment variable '%s'." % str(DATA_DIR_ENVIRON_KEY)
return None return None
def show_error_dialog(window, message): def show_error_dialog(window, message):
warn_window = gtk.MessageDialog(window, type=gtk.MESSAGE_ERROR, warn_window = gtk.MessageDialog(window, type=gtk.MESSAGE_ERROR,
buttons=gtk.BUTTONS_OK, message_format=str(message)) buttons=gtk.BUTTONS_OK, message_format=str(message))
...@@ -367,6 +366,11 @@ class GLView: ...@@ -367,6 +366,11 @@ class GLView:
class ProjectGui: class ProjectGui:
BOUNDARY_MODES = {
"inside": -1,
"along": 0,
"around": 1}
def __init__(self, master=None, no_dialog=False): def __init__(self, master=None, no_dialog=False):
""" TODO: remove "master" above when the Tk interface is abandoned""" """ TODO: remove "master" above when the Tk interface is abandoned"""
self.settings = pycam.Gui.Settings.Settings() self.settings = pycam.Gui.Settings.Settings()
...@@ -444,7 +448,15 @@ class ProjectGui: ...@@ -444,7 +448,15 @@ class ProjectGui:
def set_unit(text): def set_unit(text):
unit_field.set_active((text == "mm") and 0 or 1) unit_field.set_active((text == "mm") and 0 or 1)
self.settings.add_item("unit", unit_field.get_active_text, set_unit) self.settings.add_item("unit", unit_field.get_active_text, set_unit)
unit_field.set_active(0) self.settings.set("unit", "mm")
# boundary mode (move inside/along/around the boundaries)
boundary_mode_control = self.gui.get_object("BoundaryModeControl")
def set_boundary_mode(value):
# we assume, that the items in the list are (-1, 0, +1)
boundary_mode_control.set_active(value + 1)
def get_boundary_mode():
return boundary_mode_control.get_active() - 1
self.settings.add_item("boundary_mode", get_boundary_mode, set_boundary_mode)
# define the limit callback functions # define the limit callback functions
for limit in ["minx", "miny", "minz", "maxx", "maxy", "maxz"]: for limit in ["minx", "miny", "minz", "maxx", "maxy", "maxz"]:
obj = self.gui.get_object(limit) obj = self.gui.get_object(limit)
...@@ -538,7 +550,7 @@ class ProjectGui: ...@@ -538,7 +550,7 @@ class ProjectGui:
("TorusRadiusControl", "torus_radius"), ("TorusRadiusControl", "torus_radius"),
("FeedrateControl", "feedrate"), ("FeedrateControl", "feedrate"),
("SpeedControl", "speed")): ("SpeedControl", "speed")):
self.gui.get_object(objname).connect("changed", self.handle_tool_settings_change) self.gui.get_object(objname).connect("value-changed", self.handle_tool_settings_change)
for name in ("SphericalCutter", "CylindricalCutter", "ToroidalCutter"): for name in ("SphericalCutter", "CylindricalCutter", "ToroidalCutter"):
self.gui.get_object(name).connect("clicked", self.handle_tool_settings_change) self.gui.get_object(name).connect("clicked", self.handle_tool_settings_change)
self.gui.get_object("ToolName").connect("changed", self.handle_tool_settings_change) self.gui.get_object("ToolName").connect("changed", self.handle_tool_settings_change)
...@@ -553,7 +565,7 @@ class ProjectGui: ...@@ -553,7 +565,7 @@ class ProjectGui:
self.gui.get_object(objname).connect("toggled", self.handle_process_settings_change) self.gui.get_object(objname).connect("toggled", self.handle_process_settings_change)
for objname in ("SafetyHeightControl", "OverlapPercentControl", for objname in ("SafetyHeightControl", "OverlapPercentControl",
"MaterialAllowanceControl", "MaxStepDownControl"): "MaterialAllowanceControl", "MaxStepDownControl"):
self.gui.get_object(objname).connect("changed", self.handle_process_settings_change) self.gui.get_object(objname).connect("value-changed", self.handle_process_settings_change)
self.gui.get_object("ProcessSettingName").connect("changed", self.handle_process_settings_change) self.gui.get_object("ProcessSettingName").connect("changed", self.handle_process_settings_change)
# the process manager # the process manager
self.process_table = self.gui.get_object("ProcessListTable") self.process_table = self.gui.get_object("ProcessListTable")
...@@ -1159,7 +1171,7 @@ class ProjectGui: ...@@ -1159,7 +1171,7 @@ class ProjectGui:
pycam.Exporters.STLExporter.STLExporter(self.model).write(fi) pycam.Exporters.STLExporter.STLExporter(self.model).write(fi)
fi.close() fi.close()
except IOError, err_msg: except IOError, err_msg:
if not no_dialog: if not no_dialog and not self.no_dialog:
show_error_dialog(self.window, "Failed to save model file") show_error_dialog(self.window, "Failed to save model file")
@gui_activity_guard @gui_activity_guard
...@@ -1319,7 +1331,7 @@ class ProjectGui: ...@@ -1319,7 +1331,7 @@ class ProjectGui:
out.write(text) out.write(text)
out.close() out.close()
except IOError, err_msg: except IOError, err_msg:
if not no_dialog: if not no_dialog and not self.no_dialog:
show_error_dialog(self.window, "Failed to save EMC tool file") show_error_dialog(self.window, "Failed to save EMC tool file")
def open_settings_file(self, filename): def open_settings_file(self, filename):
...@@ -1549,7 +1561,7 @@ class ProjectGui: ...@@ -1549,7 +1561,7 @@ class ProjectGui:
if not filename: if not filename:
return return
settings = pycam.Gui.Settings.SettingsFileManager() settings = pycam.Gui.Settings.SettingsFileManager()
if not settings.write_to_file(filename, self.tool_list, self.process_list, self.task_list) and not no_dialog: if not settings.write_to_file(filename, self.tool_list, self.process_list, self.task_list) and not no_dialog and not self.no_dialog:
show_error_dialog(self.window, "Failed to save settings file") show_error_dialog(self.window, "Failed to save settings file")
def get_tool_instance(self, tool_settings): def get_tool_instance(self, tool_settings):
...@@ -1656,6 +1668,19 @@ class ProjectGui: ...@@ -1656,6 +1668,19 @@ class ProjectGui:
# this offset allows to cut a model with a minimal boundary box correctly # this offset allows to cut a model with a minimal boundary box correctly
offset = tool_settings["tool_radius"] / 2.0 offset = tool_settings["tool_radius"] / 2.0
# check the configured direction of the offset (boundary mode)
if self.settings.get("boundary_mode") == self.BOUNDARY_MODES["inside"]:
# use the negative offset to stay inside the boundaries
offset *= -1
elif self.settings.get("boundary_mode") == self.BOUNDARY_MODES["along"]:
# don't use any offset
offset = 0
elif self.settings.get("boundary_mode") == self.BOUNDARY_MODES["around"]:
# just use the positive offset - no change required
pass
else:
# this should never happen
print >>sys.stderr, "Assertion failed: invalid boundary_mode (%s)" % str(self.settings.get("boundary_mode"))
minx = float(self.settings.get("minx"))-offset minx = float(self.settings.get("minx"))-offset
maxx = float(self.settings.get("maxx"))+offset maxx = float(self.settings.get("maxx"))+offset
...@@ -1664,6 +1689,13 @@ class ProjectGui: ...@@ -1664,6 +1689,13 @@ class ProjectGui:
minz = float(self.settings.get("minz")) minz = float(self.settings.get("minz"))
maxz = float(self.settings.get("maxz")) maxz = float(self.settings.get("maxz"))
# check if the boundary limits are valid
if (minx > maxx) or (miny > maxy) or (minz > maxz):
# don't generate a toolpath if the area is too small (e.g. due to the tool size)
if not self.no_dialog:
show_error_dialog(self.window, "Processing boundaries are too small for this tool size.")
return True
effective_toolradius = tool_settings["tool_radius"] * (1.0 - process_settings["overlap"] / 100.0) effective_toolradius = tool_settings["tool_radius"] * (1.0 - process_settings["overlap"] / 100.0)
x_shift = effective_toolradius x_shift = effective_toolradius
y_shift = effective_toolradius y_shift = effective_toolradius
...@@ -1836,7 +1868,7 @@ class ProjectGui: ...@@ -1836,7 +1868,7 @@ class ProjectGui:
if self.no_dialog: if self.no_dialog:
print "GCode file successfully written: %s" % str(filename) print "GCode file successfully written: %s" % str(filename)
except IOError, err_msg: except IOError, err_msg:
if not no_dialog: if not no_dialog and not self.no_dialog:
show_error_dialog(self.window, "Failed to save toolpath file") show_error_dialog(self.window, "Failed to save toolpath file")
def mainloop(self): def mainloop(self):
......
...@@ -125,7 +125,7 @@ ...@@ -125,7 +125,7 @@
</row> </row>
</data> </data>
</object> </object>
<object class="GtkListStore" id="ScaleDimensionAxisValue"> <object class="GtkListStore" id="ScaleDimensionAxesList">
<columns> <columns>
<!-- column-name value --> <!-- column-name value -->
<column type="gchararray"/> <column type="gchararray"/>
...@@ -142,6 +142,28 @@ ...@@ -142,6 +142,28 @@
</row> </row>
</data> </data>
</object> </object>
<object class="GtkListStore" id="BoundaryModeList">
<columns>
<!-- column-name offset -->
<column type="gint"/>
<!-- column-name description -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0">-1</col>
<col id="1" translatable="yes">move inside limits</col>
</row>
<row>
<col id="0">0</col>
<col id="1" translatable="yes">move along limits</col>
</row>
<row>
<col id="0">1</col>
<col id="1" translatable="yes">move around limits</col>
</row>
</data>
</object>
<object class="GtkWindow" id="ProjectWindow"> <object class="GtkWindow" id="ProjectWindow">
<property name="title" translatable="yes">PyCAM</property> <property name="title" translatable="yes">PyCAM</property>
<property name="destroy_with_parent">True</property> <property name="destroy_with_parent">True</property>
...@@ -553,7 +575,7 @@ ...@@ -553,7 +575,7 @@
<child> <child>
<object class="GtkComboBox" id="ScaleDimensionAxis"> <object class="GtkComboBox" id="ScaleDimensionAxis">
<property name="visible">True</property> <property name="visible">True</property>
<property name="model">ScaleDimensionAxisValue</property> <property name="model">ScaleDimensionAxesList</property>
<property name="active">0</property> <property name="active">0</property>
<child> <child>
<object class="GtkCellRendererText" id="ScaleDimensionColumn"/> <object class="GtkCellRendererText" id="ScaleDimensionColumn"/>
...@@ -2246,8 +2268,12 @@ This combination is added to the above task list.</property> ...@@ -2246,8 +2268,12 @@ This combination is added to the above task list.</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkHBox" id="unit_box"> <object class="GtkTable" id="table8">
<property name="visible">True</property> <property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<property name="column_spacing">3</property>
<property name="row_spacing">3</property>
<child> <child>
<object class="GtkLabel" id="UnitLabel"> <object class="GtkLabel" id="UnitLabel">
<property name="visible">True</property> <property name="visible">True</property>
...@@ -2255,9 +2281,8 @@ This combination is added to the above task list.</property> ...@@ -2255,9 +2281,8 @@ This combination is added to the above task list.</property>
<property name="label" translatable="yes">Unit (for all dimensions):</property> <property name="label" translatable="yes">Unit (for all dimensions):</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="top_attach">1</property>
<property name="padding">3</property> <property name="bottom_attach">2</property>
<property name="position">0</property>
</packing> </packing>
</child> </child>
<child> <child>
...@@ -2273,15 +2298,49 @@ This combination is added to the above task list.</property> ...@@ -2273,15 +2298,49 @@ This combination is added to the above task list.</property>
</child> </child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="left_attach">1</property>
<property name="position">1</property> <property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="BoundaryModeLabel">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Boundary mode:</property>
</object>
</child>
<child>
<object class="GtkComboBox" id="BoundaryModeControl">
<property name="visible">True</property>
<property name="model">BoundaryModeList</property>
<property name="active">0</property>
<child>
<object class="GtkCellRendererText" id="BoundaryModeColumn"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing> </packing>
</child> </child>
</object> </object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="unit_box">
<property name="visible">True</property>
</object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">False</property> <property name="fill">False</property>
<property name="position">1</property> <property name="position">2</property>
</packing> </packing>
</child> </child>
</object> </object>
......
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