Commit 27e40020 authored by sumpfralle's avatar sumpfralle

Models plugin now is a list of ModelEntity dictionaries

all plugins need to refer to the attribute ".model" instead of using the list member directly


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@1201 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent f88a37a5
...@@ -33,14 +33,6 @@ ...@@ -33,14 +33,6 @@
</row> </row>
</data> </data>
</object> </object>
<object class="GtkListStore" id="BoundsList">
<columns>
<!-- column-name ref -->
<column type="gulong"/>
<!-- column-name name -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkAdjustment" id="BoundaryLowXValue"> <object class="GtkAdjustment" id="BoundaryLowXValue">
<property name="lower">-2000</property> <property name="lower">-2000</property>
<property name="upper">2000</property> <property name="upper">2000</property>
...@@ -71,6 +63,12 @@ ...@@ -71,6 +63,12 @@
<property name="upper">2000</property> <property name="upper">2000</property>
<property name="step_increment">1</property> <property name="step_increment">1</property>
</object> </object>
<object class="GtkListStore" id="BoundsList">
<columns>
<!-- column-name ref -->
<column type="gulong"/>
</columns>
</object>
<object class="GtkVPaned" id="BoundsBox"> <object class="GtkVPaned" id="BoundsBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
...@@ -87,23 +85,20 @@ ...@@ -87,23 +85,20 @@
<property name="vscrollbar_policy">automatic</property> <property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">etched-in</property> <property name="shadow_type">etched-in</property>
<child> <child>
<object class="GtkTreeView" id="BoundsEditTable"> <object class="GtkTreeView" id="BoundsTable">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="model">BoundsList</property> <property name="model">BoundsList</property>
<property name="headers_clickable">False</property> <property name="headers_clickable">False</property>
<property name="search_column">0</property> <property name="search_column">0</property>
<child> <child>
<object class="GtkTreeViewColumn" id="DescriptionColumn"> <object class="GtkTreeViewColumn" id="NameColumn">
<property name="title">Name</property> <property name="title">Name</property>
<property name="expand">True</property> <property name="expand">True</property>
<child> <child>
<object class="GtkCellRendererText" id="NameCell"> <object class="GtkCellRendererText" id="NameCell">
<property name="editable">True</property> <property name="editable">True</property>
</object> </object>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child> </child>
</object> </object>
</child> </child>
......
...@@ -6,24 +6,7 @@ ...@@ -6,24 +6,7 @@
<columns> <columns>
<!-- column-name id --> <!-- column-name id -->
<column type="gulong"/> <column type="gulong"/>
<!-- column-name name -->
<column type="gchararray"/>
<!-- column-name state -->
<column type="gboolean"/>
<!-- column-name color -->
<column type="gchararray"/>
<!-- column-name alpha -->
<column type="guint"/>
</columns> </columns>
<data>
<row>
<col id="0">0</col>
<col id="1" translatable="yes">Model #1</col>
<col id="2">False</col>
<col id="3" translatable="yes">#ffff00000000</col>
<col id="4">0</col>
</row>
</data>
</object> </object>
<object class="GtkWindow" id="window1"> <object class="GtkWindow" id="window1">
<child> <child>
...@@ -48,29 +31,20 @@ ...@@ -48,29 +31,20 @@
<property name="model">ModelList</property> <property name="model">ModelList</property>
<property name="headers_visible">False</property> <property name="headers_visible">False</property>
<child> <child>
<object class="GtkTreeViewColumn" id="ModelVisibleColumn"> <object class="GtkTreeViewColumn" id="VisibleColumn">
<property name="title">column</property>
<property name="clickable">True</property>
<child> <child>
<object class="GtkCellRendererPixbuf" id="ModelVisibleSymbol"> <object class="GtkCellRendererPixbuf" id="VisibleSymbol">
<property name="stock_size">2</property> <property name="stock_size">2</property>
</object> </object>
<attributes>
<attribute name="cell-background">3</attribute>
</attributes>
</child> </child>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkTreeViewColumn" id="treeviewcolumn2"> <object class="GtkTreeViewColumn" id="NameColumn">
<property name="title">column</property>
<child> <child>
<object class="GtkCellRendererText" id="ModelNameColumn"> <object class="GtkCellRendererText" id="NameCell">
<property name="editable">True</property> <property name="editable">True</property>
</object> </object>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child> </child>
</object> </object>
</child> </child>
......
...@@ -2,14 +2,6 @@ ...@@ -2,14 +2,6 @@
<interface> <interface>
<!-- interface-requires gtk+ 2.12 --> <!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy project-wide --> <!-- interface-naming-policy project-wide -->
<object class="GtkListStore" id="ProcessList">
<columns>
<!-- column-name ref -->
<column type="gulong"/>
<!-- column-name name -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkListStore" id="StrategyModel"> <object class="GtkListStore" id="StrategyModel">
<columns> <columns>
<!-- column-name label --> <!-- column-name label -->
...@@ -24,6 +16,12 @@ ...@@ -24,6 +16,12 @@
</row> </row>
</data> </data>
</object> </object>
<object class="GtkListStore" id="ProcessList">
<columns>
<!-- column-name ref -->
<column type="gulong"/>
</columns>
</object>
<object class="GtkVPaned" id="ProcessBox"> <object class="GtkVPaned" id="ProcessBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
...@@ -52,9 +50,6 @@ ...@@ -52,9 +50,6 @@
<property name="title">Name</property> <property name="title">Name</property>
<child> <child>
<object class="GtkCellRendererText" id="NameCell"/> <object class="GtkCellRendererText" id="NameCell"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child> </child>
</object> </object>
</child> </child>
......
...@@ -12,76 +12,6 @@ ...@@ -12,76 +12,6 @@
<property name="upper">10000</property> <property name="upper">10000</property>
<property name="step_increment">1</property> <property name="step_increment">1</property>
</object> </object>
<object class="GtkListStore" id="TaskList">
<columns>
<!-- column-name index -->
<column type="guint"/>
<!-- column-name name -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0">0</col>
<col id="1" translatable="yes">Rough</col>
</row>
</data>
</object>
<object class="GtkListStore" id="ToolList">
<columns>
<!-- column-name ref -->
<column type="guint"/>
<!-- column-name name -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0">0</col>
<col id="1" translatable="yes">Tool #1</col>
</row>
</data>
</object>
<object class="GtkListStore" id="ProcessList">
<columns>
<!-- column-name ref -->
<column type="guint"/>
<!-- column-name name -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0">0</col>
<col id="1" translatable="yes">Process #1</col>
</row>
</data>
</object>
<object class="GtkListStore" id="BoundsList">
<columns>
<!-- column-name ref -->
<column type="guint"/>
<!-- column-name name -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0">0</col>
<col id="1" translatable="yes">Bounds #1</col>
</row>
</data>
</object>
<object class="GtkListStore" id="ModelsList">
<columns>
<!-- column-name ref -->
<column type="guint"/>
<!-- column-name name -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0">0</col>
<col id="1" translatable="yes">Model #1</col>
</row>
</data>
</object>
<object class="GtkListStore" id="TaskTypeList"> <object class="GtkListStore" id="TaskTypeList">
<columns> <columns>
<!-- column-name label --> <!-- column-name label -->
...@@ -96,6 +26,12 @@ ...@@ -96,6 +26,12 @@
</row> </row>
</data> </data>
</object> </object>
<object class="GtkListStore" id="TaskList">
<columns>
<!-- column-name index -->
<column type="gulong"/>
</columns>
</object>
<object class="GtkVPaned" id="TaskBox"> <object class="GtkVPaned" id="TaskBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
...@@ -121,13 +57,10 @@ ...@@ -121,13 +57,10 @@
<property name="enable_search">False</property> <property name="enable_search">False</property>
<property name="search_column">0</property> <property name="search_column">0</property>
<child> <child>
<object class="GtkTreeViewColumn" id="TaskNameColumn"> <object class="GtkTreeViewColumn" id="NameColumn">
<property name="title">Name</property> <property name="title">Name</property>
<child> <child>
<object class="GtkCellRendererText" id="TaskNameCell"/> <object class="GtkCellRendererText" id="NameCell"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child> </child>
</object> </object>
</child> </child>
......
...@@ -12,23 +12,6 @@ ...@@ -12,23 +12,6 @@
<property name="upper">500</property> <property name="upper">500</property>
<property name="step_increment">0.10000000000000001</property> <property name="step_increment">0.10000000000000001</property>
</object> </object>
<object class="GtkListStore" id="ToolList">
<columns>
<!-- column-name object_ref -->
<column type="guint"/>
<!-- column-name tool_id -->
<column type="guint"/>
<!-- column-name name -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0">0</col>
<col id="1">0</col>
<col id="2" translatable="yes">test</col>
</row>
</data>
</object>
<object class="GtkListStore" id="ToolShapeList"> <object class="GtkListStore" id="ToolShapeList">
<columns> <columns>
<!-- column-name label --> <!-- column-name label -->
...@@ -43,6 +26,12 @@ ...@@ -43,6 +26,12 @@
</row> </row>
</data> </data>
</object> </object>
<object class="GtkListStore" id="ToolList">
<columns>
<!-- column-name object_ref -->
<column type="guint"/>
</columns>
</object>
<object class="GtkVPaned" id="ToolBox"> <object class="GtkVPaned" id="ToolBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
...@@ -59,44 +48,38 @@ ...@@ -59,44 +48,38 @@
<property name="vscrollbar_policy">automatic</property> <property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">etched-in</property> <property name="shadow_type">etched-in</property>
<child> <child>
<object class="GtkTreeView" id="ToolEditorTable"> <object class="GtkTreeView" id="ToolTable">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="model">ToolList</property> <property name="model">ToolList</property>
<property name="headers_clickable">False</property> <property name="headers_clickable">False</property>
<property name="search_column">0</property> <property name="search_column">0</property>
<child> <child>
<object class="GtkTreeViewColumn" id="ToolTableIDColumn"> <object class="GtkTreeViewColumn" id="IDColumn">
<property name="title">Tool ID</property> <property name="title">Tool ID</property>
<child> <child>
<object class="GtkCellRendererText" id="ToolTableIDCell"> <object class="GtkCellRendererText" id="IDCell">
<property name="editable">True</property> <property name="editable">True</property>
</object> </object>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child> </child>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkTreeViewColumn" id="ToolTableNameColumn"> <object class="GtkTreeViewColumn" id="NameColumn">
<property name="title">Name</property> <property name="title">Name</property>
<property name="expand">True</property> <property name="expand">True</property>
<child> <child>
<object class="GtkCellRendererText" id="ToolTableNameCell"> <object class="GtkCellRendererText" id="NameCell">
<property name="editable">True</property> <property name="editable">True</property>
</object> </object>
<attributes>
<attribute name="text">2</attribute>
</attributes>
</child> </child>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkTreeViewColumn" id="ToolTableShapeColumn"> <object class="GtkTreeViewColumn" id="ShapeColumn">
<property name="title">Shape</property> <property name="title">Shape</property>
<child> <child>
<object class="GtkCellRendererText" id="ToolTableShapeCell"> <object class="GtkCellRendererText" id="ShapeCell">
<property name="alignment">right</property> <property name="alignment">right</property>
</object> </object>
</child> </child>
......
...@@ -656,7 +656,7 @@ class ProjectGui(object): ...@@ -656,7 +656,7 @@ class ProjectGui(object):
self.add_to_recent_file_list) self.add_to_recent_file_list)
# fallback - in case of a failure when opening a model file # fallback - in case of a failure when opening a model file
model = pycam.Importers.TestModel.get_test_model() model = pycam.Importers.TestModel.get_test_model()
self.settings.get("models").append(model) self.settings.get("models").add_model(model, "Tiny pyramid")
# Without this "gkt.main_iteration" loop the task settings file # Without this "gkt.main_iteration" loop the task settings file
# control would not be updated in time. # control would not be updated in time.
while gtk.events_pending(): while gtk.events_pending():
...@@ -967,7 +967,7 @@ class ProjectGui(object): ...@@ -967,7 +967,7 @@ class ProjectGui(object):
# load the new model only if the import worked # load the new model only if the import worked
if model: if model:
self.settings.emit_event("model-change-before") self.settings.emit_event("model-change-before")
self.settings.get("models").append(model) self.settings.get("models").add_model(model)
self.last_model_uri = None self.last_model_uri = None
return True return True
else: else:
......
...@@ -34,8 +34,7 @@ class Bounds(pycam.Plugins.ListPluginBase): ...@@ -34,8 +34,7 @@ class Bounds(pycam.Plugins.ListPluginBase):
UI_FILE = "bounds.ui" UI_FILE = "bounds.ui"
DEPENDS = ["Models"] DEPENDS = ["Models"]
CATEGORIES = ["Bounds"] CATEGORIES = ["Bounds"]
COLUMN_REF, COLUMN_NAME = range(2) COLUMN_REF = 0
LIST_ATTRIBUTE_MAP = {"ref": COLUMN_REF, "name": COLUMN_NAME}
# mapping of boundary types and GUI control elements # mapping of boundary types and GUI control elements
BOUNDARY_TYPES = { BOUNDARY_TYPES = {
...@@ -57,7 +56,7 @@ class Bounds(pycam.Plugins.ListPluginBase): ...@@ -57,7 +56,7 @@ class Bounds(pycam.Plugins.ListPluginBase):
bounds_box = self.gui.get_object("BoundsBox") bounds_box = self.gui.get_object("BoundsBox")
bounds_box.unparent() bounds_box.unparent()
self.core.register_ui("main", "Bounds", bounds_box, 30) self.core.register_ui("main", "Bounds", bounds_box, 30)
self._boundsview = self.gui.get_object("BoundsEditTable") self._boundsview = self.gui.get_object("BoundsTable")
self._gtk_handlers = [] self._gtk_handlers = []
self._gtk_handlers.append((self._boundsview.get_selection(), self._gtk_handlers.append((self._boundsview.get_selection(),
"changed", "bounds-selection-changed")) "changed", "bounds-selection-changed"))
...@@ -72,7 +71,7 @@ class Bounds(pycam.Plugins.ListPluginBase): ...@@ -72,7 +71,7 @@ class Bounds(pycam.Plugins.ListPluginBase):
self._treemodel.clear() self._treemodel.clear()
for index, item in enumerate(self): for index, item in enumerate(self):
if not id(item) in cache: if not id(item) in cache:
cache[id(item)] = [id(item), "Bounds #%d" % index] cache[id(item)] = [id(item)]
self._treemodel.append(cache[id(item)]) self._treemodel.append(cache[id(item)])
self.core.emit_event("bounds-list-changed") self.core.emit_event("bounds-list-changed")
self.register_model_update(update_model) self.register_model_update(update_model)
...@@ -183,17 +182,22 @@ class Bounds(pycam.Plugins.ListPluginBase): ...@@ -183,17 +182,22 @@ class Bounds(pycam.Plugins.ListPluginBase):
text = "%g x %g x %g" % tuple([high[i] - low[i] for i in range(3)]) text = "%g x %g x %g" % tuple([high[i] - low[i] for i in range(3)])
cell.set_property("text", text) cell.set_property("text", text)
def _render_bounds_name(self, column, cell, model, m_iter):
path = model.get_path(m_iter)
bounds = self[path[0]]
cell.set_property("text", bounds["name"])
def _trigger_table_update(self): def _trigger_table_update(self):
# trigger an update of the table - ugly!
self.gui.get_object("SizeColumn").set_cell_data_func( self.gui.get_object("SizeColumn").set_cell_data_func(
self.gui.get_object("SizeCell"), self._render_bounds_size) self.gui.get_object("SizeCell"), self._render_bounds_size)
self.gui.get_object("NameColumn").set_cell_data_func(
self.gui.get_object("NameCell"), self._render_bounds_name)
def _update_model_list(self): def _update_model_list(self):
models = self.core.get("models") models = self.core.get("models")
choices = [] choices = []
for model in models: for model in models:
name = models.get_attr(model, "name") choices.append((model["name"], model))
choices.append((name, model))
self.models_control.update_choices(choices) self.models_control.update_choices(choices)
def _store_bounds_settings(self, widget=None): def _store_bounds_settings(self, widget=None):
...@@ -208,11 +212,11 @@ class Bounds(pycam.Plugins.ListPluginBase): ...@@ -208,11 +212,11 @@ class Bounds(pycam.Plugins.ListPluginBase):
for get_func in self.CONTROL_GET: for get_func in self.CONTROL_GET:
if hasattr(obj, get_func): if hasattr(obj, get_func):
value = getattr(obj, get_func)() value = getattr(obj, get_func)()
data[obj_name] = value data["parameters"][obj_name] = value
break break
else: else:
self.log.info("Failed to update value of control %s" % obj_name) self.log.info("Failed to update value of control %s" % obj_name)
data["Models"] = self.get_selected_models() data["parameters"]["Models"] = self.get_selected_models()
control_box.show() control_box.show()
self._hide_and_show_controls() self._hide_and_show_controls()
...@@ -246,7 +250,7 @@ class Bounds(pycam.Plugins.ListPluginBase): ...@@ -246,7 +250,7 @@ class Bounds(pycam.Plugins.ListPluginBase):
bounds = self.get_selected() bounds = self.get_selected()
if not bounds: if not bounds:
return return
models = bounds["Models"] models = bounds["parameters"]["Models"]
if self.gui.get_object("TypeRelativeMargin").get_active(): if self.gui.get_object("TypeRelativeMargin").get_active():
# no models are currently selected # no models are currently selected
func_low = lambda value, axis: 0 func_low = lambda value, axis: 0
...@@ -273,7 +277,7 @@ class Bounds(pycam.Plugins.ListPluginBase): ...@@ -273,7 +277,7 @@ class Bounds(pycam.Plugins.ListPluginBase):
for func, name in ((func_low, "BoundaryLow"), for func, name in ((func_low, "BoundaryLow"),
(func_high, "BoundaryHigh")): (func_high, "BoundaryHigh")):
try: try:
result = func(bounds[name + axis], "XYZ".index(axis)) result = func(bounds["parameters"][name + axis], "XYZ".index(axis))
except ZeroDivisionError: except ZeroDivisionError:
# this happens for flat models # this happens for flat models
result = 0 result = 0
...@@ -289,7 +293,7 @@ class Bounds(pycam.Plugins.ListPluginBase): ...@@ -289,7 +293,7 @@ class Bounds(pycam.Plugins.ListPluginBase):
bounds = self.get_selected() bounds = self.get_selected()
if not bounds: if not bounds:
return return
models = bounds["Models"] models = bounds["parameters"]["Models"]
# calculate the model bounds # calculate the model bounds
low, high = pycam.Geometry.Model.get_combined_bounds(models) low, high = pycam.Geometry.Model.get_combined_bounds(models)
if None in low or None in high: if None in low or None in high:
...@@ -306,7 +310,7 @@ class Bounds(pycam.Plugins.ListPluginBase): ...@@ -306,7 +310,7 @@ class Bounds(pycam.Plugins.ListPluginBase):
for axis in "XYZ": for axis in "XYZ":
for name in ("BoundaryLow", "BoundaryHigh"): for name in ("BoundaryLow", "BoundaryHigh"):
try: try:
result = func(bounds[name + axis], "XYZ".index(axis)) result = func(bounds["parameters"][name + axis], "XYZ".index(axis))
except ZeroDivisionError: except ZeroDivisionError:
# this happens for flat models # this happens for flat models
result = 0 result = 0
...@@ -322,12 +326,12 @@ class Bounds(pycam.Plugins.ListPluginBase): ...@@ -322,12 +326,12 @@ class Bounds(pycam.Plugins.ListPluginBase):
axis_index = "xyz".index(axis) axis_index = "xyz".index(axis)
change_factor = {"0": 0, "+": 1, "-": -1}[change] change_factor = {"0": 0, "+": 1, "-": -1}[change]
if change == "0": if change == "0":
bounds["BoundaryLow%s" % axis.upper()] = 0 bounds["parameters"]["BoundaryLow%s" % axis.upper()] = 0
bounds["BoundaryHigh%s" % axis.upper()] = 0 bounds["parameters"]["BoundaryHigh%s" % axis.upper()] = 0
elif self._is_percent(): elif self._is_percent():
# % margin # % margin
bounds["BoundaryLow%s" % axis.upper()] += change_factor * 10 bounds["parameters"]["BoundaryLow%s" % axis.upper()] += change_factor * 10
bounds["BoundaryHigh%s" % axis.upper()] += change_factor * 10 bounds["parameters"]["BoundaryHigh%s" % axis.upper()] += change_factor * 10
else: else:
# absolute margin # absolute margin
models = self.get_selected_models() models = self.get_selected_models()
...@@ -335,8 +339,8 @@ class Bounds(pycam.Plugins.ListPluginBase): ...@@ -335,8 +339,8 @@ class Bounds(pycam.Plugins.ListPluginBase):
if None in model_low or None in model_high: if None in model_low or None in model_high:
return return
change_value = (model_high[axis_index] - model_low[axis_index]) * 0.1 change_value = (model_high[axis_index] - model_low[axis_index]) * 0.1
bounds["BoundaryLow%s" % axis.upper()] += change_value * change_factor bounds["parameters"]["BoundaryLow%s" % axis.upper()] += change_value * change_factor
bounds["BoundaryHigh%s" % axis.upper()] += change_value * change_factor bounds["parameters"]["BoundaryHigh%s" % axis.upper()] += change_value * change_factor
self._update_controls() self._update_controls()
self.core.emit_event("bounds-changed") self.core.emit_event("bounds-changed")
...@@ -350,7 +354,7 @@ class Bounds(pycam.Plugins.ListPluginBase): ...@@ -350,7 +354,7 @@ class Bounds(pycam.Plugins.ListPluginBase):
control_box.hide() control_box.hide()
else: else:
self.unregister_gtk_handlers(self._gtk_handlers) self.unregister_gtk_handlers(self._gtk_handlers)
for obj_name, value in bounds.iteritems(): for obj_name, value in bounds["parameters"].iteritems():
if obj_name == "Models": if obj_name == "Models":
self.select_models(value) self.select_models(value)
continue continue
...@@ -364,7 +368,8 @@ class Bounds(pycam.Plugins.ListPluginBase): ...@@ -364,7 +368,8 @@ class Bounds(pycam.Plugins.ListPluginBase):
getattr(obj, set_func)(value) getattr(obj, set_func)(value)
break break
else: else:
self.log.info("Failed to set value of control %s" % obj_name) self.log.info("Failed to set value of control: %s" % \
obj_name)
self.register_gtk_handlers(self._gtk_handlers) self.register_gtk_handlers(self._gtk_handlers)
self._hide_and_show_controls() self._hide_and_show_controls()
control_box.show() control_box.show()
...@@ -375,26 +380,30 @@ class Bounds(pycam.Plugins.ListPluginBase): ...@@ -375,26 +380,30 @@ class Bounds(pycam.Plugins.ListPluginBase):
self.core.emit_event("bounds-changed") self.core.emit_event("bounds-changed")
def _bounds_new(self, *args): def _bounds_new(self, *args):
current_bounds_index = self.get_selected(index=True) bounds_names = [bounds["name"] for bounds in self]
if current_bounds_index is None: bounds_id = 1
current_bounds_index = 0 while ("Bounds #%d" % bounds_id) in bounds_names:
new_bounds = BoundsDict(self.core) bounds_id += 1
new_bounds = BoundsDict(self.core, "Bounds #%d" % bounds_id)
self.append(new_bounds) self.append(new_bounds)
self.select(new_bounds) self.select(new_bounds)
def _edit_bounds_name(self, cell, path, new_text): def _edit_bounds_name(self, cell, path, new_text):
path = int(path) path = int(path)
if (new_text != self._treemodel[path][self.COLUMN_NAME]) and \ bounds_ref = self._treemodel[path][self.COLUMN_REF]
new_text: bounds = [bound for bound in self if id(bound) == bounds_ref]
self._treemodel[path][self.COLUMN_NAME] = new_text if (new_text != bounds["name"]) and new_text:
bounds["name"] = new_text
class BoundsDict(pycam.Plugins.ObjectWithAttributes): class BoundsDict(pycam.Plugins.ObjectWithAttributes):
def __init__(self, core, *args, **kwargs): def __init__(self, core, name, *args, **kwargs):
super(BoundsDict, self).__init__("bounds", *args, **kwargs) super(BoundsDict, self).__init__("bounds", *args, **kwargs)
self["name"] = name
self["parameters"] = {}
self.core = core self.core = core
self.update({ self["parameters"].update({
"BoundaryLowX": 0, "BoundaryLowX": 0,
"BoundaryLowY": 0, "BoundaryLowY": 0,
"BoundaryLowZ": 0, "BoundaryLowZ": 0,
...@@ -410,13 +419,15 @@ class BoundsDict(pycam.Plugins.ObjectWithAttributes): ...@@ -410,13 +419,15 @@ class BoundsDict(pycam.Plugins.ObjectWithAttributes):
def get_absolute_limits(self, tool=None, models=None): def get_absolute_limits(self, tool=None, models=None):
default = (None, None, None), (None, None, None) default = (None, None, None), (None, None, None)
get_low_value = lambda axis: self["BoundaryLow%s" % "XYZ"[axis]] get_low_value = lambda axis: \
get_high_value = lambda axis: self["BoundaryHigh%s" % "XYZ"[axis]] self["parameters"]["BoundaryLow%s" % "XYZ"[axis]]
if self["TypeRelativeMargin"]: get_high_value = lambda axis: \
self["parameters"]["BoundaryHigh%s" % "XYZ"[axis]]
if self["parameters"]["TypeRelativeMargin"]:
# choose the appropriate set of models # choose the appropriate set of models
if self["Models"]: if self["parameters"]["Models"]:
# configured models always take precedence # configured models always take precedence
models = self["Models"] models = self["parameters"]["Models"]
elif models: elif models:
# use the supplied models (e.g. for toolpath calculation) # use the supplied models (e.g. for toolpath calculation)
pass pass
...@@ -424,11 +435,11 @@ class BoundsDict(pycam.Plugins.ObjectWithAttributes): ...@@ -424,11 +435,11 @@ class BoundsDict(pycam.Plugins.ObjectWithAttributes):
# use all visible models -> for live visualization # use all visible models -> for live visualization
models = self.core.get("models").get_visible() models = self.core.get("models").get_visible()
low_model, high_model = pycam.Geometry.Model.get_combined_bounds( low_model, high_model = pycam.Geometry.Model.get_combined_bounds(
models) [model.model for model in models])
if None in low_model or None in high_model: if None in low_model or None in high_model:
# zero-sized models -> no action # zero-sized models -> no action
return default return default
is_percent = _RELATIVE_UNIT[self["RelativeUnit"]] == "%" is_percent = _RELATIVE_UNIT[self["parameters"]["RelativeUnit"]] == "%"
low, high = [], [] low, high = [], []
if is_percent: if is_percent:
for axis in range(3): for axis in range(3):
...@@ -444,7 +455,7 @@ class BoundsDict(pycam.Plugins.ObjectWithAttributes): ...@@ -444,7 +455,7 @@ class BoundsDict(pycam.Plugins.ObjectWithAttributes):
for axis in range(3): for axis in range(3):
low.append(get_low_value(axis)) low.append(get_low_value(axis))
high.append(get_high_value(axis)) high.append(get_high_value(axis))
tool_limit = _BOUNDARY_MODES[self["ToolLimit"]] tool_limit = _BOUNDARY_MODES[self["parameters"]["ToolLimit"]]
# apply inside/along/outside # apply inside/along/outside
if tool_limit != "along": if tool_limit != "along":
tool_radius = tool["parameters"]["radius"] tool_radius = tool["parameters"]["radius"]
......
...@@ -87,7 +87,7 @@ class Clipboard(pycam.Plugins.PluginBase): ...@@ -87,7 +87,7 @@ class Clipboard(pycam.Plugins.PluginBase):
models = self.core.get("models").get_selected() models = self.core.get("models").get_selected()
exportable = [] exportable = []
for model in models: for model in models:
if model.is_export_supported(): if model.model.is_export_supported():
exportable.append(model) exportable.append(model)
return exportable return exportable
...@@ -128,11 +128,11 @@ class Clipboard(pycam.Plugins.PluginBase): ...@@ -128,11 +128,11 @@ class Clipboard(pycam.Plugins.PluginBase):
def same_type(m1, m2): def same_type(m1, m2):
return isinstance(m1, pycam.Geometry.Model.ContourModel) == \ return isinstance(m1, pycam.Geometry.Model.ContourModel) == \
isinstance(m2, pycam.Geometry.Model.ContourModel) isinstance(m2, pycam.Geometry.Model.ContourModel)
merged_model = models.pop(0) merged_model = models.pop(0).model
for model in models: for model in models:
# merge only 3D _or_ 2D models (don't mix them) # merge only 3D _or_ 2D models (don't mix them)
if same_type(merged_model, model): if same_type(merged_model, model.model):
merged_model += model merged_model += model.model
# TODO: add "comment=get_meta_data()" here # TODO: add "comment=get_meta_data()" here
merged_model.export(unit=self.core.get("unit")).write(text_buffer) merged_model.export(unit=self.core.get("unit")).write(text_buffer)
text_buffer.seek(0) text_buffer.seek(0)
...@@ -168,8 +168,9 @@ class Clipboard(pycam.Plugins.PluginBase): ...@@ -168,8 +168,9 @@ class Clipboard(pycam.Plugins.PluginBase):
fonts_cache=self.core.get("fonts"), fonts_cache=self.core.get("fonts"),
callback=progress.update) callback=progress.update)
if model: if model:
models = self.core.get("models")
self.log.info("Loaded a model from clipboard") self.log.info("Loaded a model from clipboard")
self.core.get("models").append(model) models.add_model(model, name_template="Pasted model #%d")
else: else:
self.log.warn("Failed to load a model from clipboard") self.log.warn("Failed to load a model from clipboard")
else: else:
......
...@@ -75,8 +75,7 @@ class EMCToolExport(pycam.Plugins.PluginBase): ...@@ -75,8 +75,7 @@ class EMCToolExport(pycam.Plugins.PluginBase):
tools_dict = [] tools_dict = []
tools = self.core.get("tools") tools = self.core.get("tools")
for tool in tools: for tool in tools:
tools_dict.append({"name": tools.get_attr(tool, "name"), tools_dict.append({"name": tool["name"], "id": tool["id"],
"id": tools.get_attr(tool, "id"),
"radius": tool["parameters"].get("radius", 1)}) "radius": tool["parameters"].get("radius", 1)})
export = pycam.Exporters.EMCToolExporter.EMCToolExporter(tools_dict) export = pycam.Exporters.EMCToolExporter.EMCToolExporter(tools_dict)
text = export.get_tool_definition_string() text = export.get_tool_definition_string()
......
...@@ -112,12 +112,12 @@ class ModelExportTrimesh(pycam.Plugins.PluginBase): ...@@ -112,12 +112,12 @@ class ModelExportTrimesh(pycam.Plugins.PluginBase):
def export_trimesh(self, models): def export_trimesh(self, models):
removal_list = [] removal_list = []
for index, model in enumerate(models): for index, model in enumerate(models):
if not hasattr(model, "triangles"): if not hasattr(model.model, "triangles"):
continue continue
# determine the file type # determine the file type
# TODO: this needs to be decided by the exporter code # TODO: this needs to be decided by the exporter code
type_filter = [("STL models", "*.stl")] type_filter = [("STL models", "*.stl")]
model_name = self.core.get("models").get_attr(model, "name") model_name = model["name"]
filename = self.core.get("get_filename_func")( filename = self.core.get("get_filename_func")(
"Save model '%s' to ..." % model_name, "Save model '%s' to ..." % model_name,
mode_load=False, type_filter=type_filter, mode_load=False, type_filter=type_filter,
...@@ -135,7 +135,7 @@ class ModelExportTrimesh(pycam.Plugins.PluginBase): ...@@ -135,7 +135,7 @@ class ModelExportTrimesh(pycam.Plugins.PluginBase):
file_in = open(uri.get_local_path(), "w") file_in = open(uri.get_local_path(), "w")
# TODO: fill in "comment" with "meta_data" # TODO: fill in "comment" with "meta_data"
# TODO: call a specific exporter # TODO: call a specific exporter
model.export(unit=self.core.get("unit")).write(file_in) model.model.export(unit=self.core.get("unit")).write(file_in)
file_in.close() file_in.close()
removal_list.append(index) removal_list.append(index)
except IOError, err_msg: except IOError, err_msg:
...@@ -162,14 +162,13 @@ class ModelExportContour(pycam.Plugins.PluginBase): ...@@ -162,14 +162,13 @@ class ModelExportContour(pycam.Plugins.PluginBase):
def export_contour(self, models): def export_contour(self, models):
removal_list = [] removal_list = []
for index, model in enumerate(models): for index, model in enumerate(models):
if not hasattr(model, "get_polygons"): if not hasattr(model.model, "get_polygons"):
continue continue
# determine the file type # determine the file type
# TODO: this needs to be decided by the exporter code # TODO: this needs to be decided by the exporter code
type_filter = [("SVG models", "*.svg")] type_filter = [("SVG models", "*.svg")]
model_name = self.core.get("models").get_attr(model, "name")
filename = self.core.get("get_filename_func")( filename = self.core.get("get_filename_func")(
"Save model '%s' to ..." % model_name, "Save model '%s' to ..." % model["name"],
mode_load=False, type_filter=type_filter, mode_load=False, type_filter=type_filter,
filename_templates=[]) filename_templates=[])
if not filename: if not filename:
...@@ -185,7 +184,7 @@ class ModelExportContour(pycam.Plugins.PluginBase): ...@@ -185,7 +184,7 @@ class ModelExportContour(pycam.Plugins.PluginBase):
file_in = open(uri.get_local_path(), "w") file_in = open(uri.get_local_path(), "w")
# TODO: fill in "comment" with "meta_data" # TODO: fill in "comment" with "meta_data"
# TODO: call a specific exporter # TODO: call a specific exporter
model.export(unit=self.core.get("unit")).write(file_in) model.model.export(unit=self.core.get("unit")).write(file_in)
file_in.close() file_in.close()
removal_list.append(index) removal_list.append(index)
except IOError, err_msg: except IOError, err_msg:
......
...@@ -75,7 +75,7 @@ class ModelExtrusion(pycam.Plugins.PluginBase): ...@@ -75,7 +75,7 @@ class ModelExtrusion(pycam.Plugins.PluginBase):
models = self.core.get("models").get_selected() models = self.core.get("models").get_selected()
extrudables = [] extrudables = []
for model in models: for model in models:
if (not model is None) and hasattr(model, "extrude"): if (not model is None) and hasattr(model.model, "extrude"):
extrudables.append(model) extrudables.append(model)
return extrudables return extrudables
...@@ -111,25 +111,17 @@ class ModelExtrusion(pycam.Plugins.PluginBase): ...@@ -111,25 +111,17 @@ class ModelExtrusion(pycam.Plugins.PluginBase):
else: else:
self.log.error("Unknown extrusion type selected: %s" % type_string) self.log.error("Unknown extrusion type selected: %s" % type_string)
return return
model_manager = self.core.get("models")
progress = self.core.get("progress") progress = self.core.get("progress")
progress.update(text="Extruding models") progress.update(text="Extruding models")
progress.set_multiple(len(selected_models), "Model") progress.set_multiple(len(selected_models), "Model")
for model in selected_models: for model in selected_models:
new_model = model.extrude(stepping=grid_size, func=func, new_model = model.model.extrude(stepping=grid_size, func=func,
callback=progress.update) callback=progress.update)
if new_model: if new_model:
self.core.get("models").append(new_model) self.core.get("models").add_model(new_model,
try: name_template="Extruded model #%d")
# add the name of the original model to the new name else:
original_name = model_manager.get_attr(model, self.log.info("Extruded model is empty")
"name").split("(")[0].strip()
new_name = model_manager.get_attr(new_model, "name")
model_manager.set_attr(new_model, "name",
"%s (extrusion of %s)" % \
(new_name, original_name))
except LookupError:
pass
progress.update_multiple() progress.update_multiple()
progress.finish() progress.finish()
...@@ -69,7 +69,7 @@ class ModelPlaneMirror(pycam.Plugins.PluginBase): ...@@ -69,7 +69,7 @@ class ModelPlaneMirror(pycam.Plugins.PluginBase):
if self.gui.get_object("MirrorPlane%s" % plane).get_active(): if self.gui.get_object("MirrorPlane%s" % plane).get_active():
break break
for model in models: for model in models:
model.transform_by_template("%s_mirror" % plane.lower(), model.model.transform_by_template("%s_mirror" % plane.lower(),
callback=progress.update) callback=progress.update)
progress.update_multiple() progress.update_multiple()
progress.finish() progress.finish()
......
...@@ -58,7 +58,7 @@ class ModelPolygons(pycam.Plugins.PluginBase): ...@@ -58,7 +58,7 @@ class ModelPolygons(pycam.Plugins.PluginBase):
def _get_polygon_models(self): def _get_polygon_models(self):
models = [] models = []
for model in self.core.get("models").get_selected(): for model in self.core.get("models").get_selected():
if model and hasattr(model, "reverse_directions"): if model and hasattr(model.model, "reverse_directions"):
models.append(model) models.append(model)
return models return models
...@@ -78,7 +78,8 @@ class ModelPolygons(pycam.Plugins.PluginBase): ...@@ -78,7 +78,8 @@ class ModelPolygons(pycam.Plugins.PluginBase):
self.core.get("update_progress")("Reversing directions of contour model") self.core.get("update_progress")("Reversing directions of contour model")
# TODO: main/sub progress bar for multiple models # TODO: main/sub progress bar for multiple models
for model in models: for model in models:
model.reverse_directions(callback=self.core.get("update_progress")) model.model.reverse_directions(
callback=self.core.get("update_progress"))
self.core.emit_event("model-change-after") self.core.emit_event("model-change-after")
def _revise_directions(self, widget=None): def _revise_directions(self, widget=None):
...@@ -90,7 +91,7 @@ class ModelPolygons(pycam.Plugins.PluginBase): ...@@ -90,7 +91,7 @@ class ModelPolygons(pycam.Plugins.PluginBase):
progress.update(text="Analyzing directions of contour model") progress.update(text="Analyzing directions of contour model")
progress.set_multiple(len(models), "Model") progress.set_multiple(len(models), "Model")
for model in models: for model in models:
model.revise_directions(callback=progress.update) model.model.revise_directions(callback=progress.update)
progress.update_multiple() progress.update_multiple()
progress.finish() progress.finish()
self.core.emit_event("model-change-after") self.core.emit_event("model-change-after")
......
...@@ -93,7 +93,7 @@ class ModelPosition(pycam.Plugins.PluginBase): ...@@ -93,7 +93,7 @@ class ModelPosition(pycam.Plugins.PluginBase):
shift = [self.gui.get_object("ShiftPosition%s" % axis).get_value() shift = [self.gui.get_object("ShiftPosition%s" % axis).get_value()
for axis in "XYZ"] for axis in "XYZ"]
for model in models: for model in models:
model.shift(shift[0], shift[1], shift[2], model.model.shift(shift[0], shift[1], shift[2],
callback=progress.update) callback=progress.update)
progress.update_multiple() progress.update_multiple()
progress.finish() progress.finish()
...@@ -110,7 +110,8 @@ class ModelPosition(pycam.Plugins.PluginBase): ...@@ -110,7 +110,8 @@ class ModelPosition(pycam.Plugins.PluginBase):
progress.update(text="Shifting model") progress.update(text="Shifting model")
progress.disable_cancel() progress.disable_cancel()
progress.set_multiple(len(models), "Model") progress.set_multiple(len(models), "Model")
for model in models: for model_dict in models:
model = model_dict.model
shift_values = [] shift_values = []
for axis in "XYZ": for axis in "XYZ":
dest = self.gui.get_object("AlignPosition%s" % axis).get_value() dest = self.gui.get_object("AlignPosition%s" % axis).get_value()
......
...@@ -59,7 +59,8 @@ class ModelProjection(pycam.Plugins.PluginBase): ...@@ -59,7 +59,8 @@ class ModelProjection(pycam.Plugins.PluginBase):
models = self.core.get("models").get_selected() models = self.core.get("models").get_selected()
projectables = [] projectables = []
for model in models: for model in models:
if (not model is None) and hasattr(model, "get_waterline_contour"): if (not model is None) and \
hasattr(model.model, "get_waterline_contour"):
projectables.append(model) projectables.append(model)
return projectables return projectables
...@@ -78,7 +79,8 @@ class ModelProjection(pycam.Plugins.PluginBase): ...@@ -78,7 +79,8 @@ class ModelProjection(pycam.Plugins.PluginBase):
progress = self.core.get("progress") progress = self.core.get("progress")
progress.update(text="Calculating 2D projection") progress.update(text="Calculating 2D projection")
progress.set_multiple(len(models), "Model") progress.set_multiple(len(models), "Model")
for model in models: for model_dict in models:
model = model_dict.model
for objname, z_level in (("ProjectionModelTop", model.maxz), for objname, z_level in (("ProjectionModelTop", model.maxz),
("ProjectionModelMiddle", (model.minz + model.maxz) / 2.0), ("ProjectionModelMiddle", (model.minz + model.maxz) / 2.0),
("ProjectionModelBottom", model.minz), ("ProjectionModelBottom", model.minz),
...@@ -90,18 +92,8 @@ class ModelProjection(pycam.Plugins.PluginBase): ...@@ -90,18 +92,8 @@ class ModelProjection(pycam.Plugins.PluginBase):
new_model = model.get_waterline_contour(plane, new_model = model.get_waterline_contour(plane,
callback=progress.update) callback=progress.update)
if new_model: if new_model:
self.core.get("models").append(new_model) self.core.get("models").add_model(new_model,
model_manager = self.core.get("models") name_template="Projected model #%d")
try:
# add the name of the original model to the new name
original_name = model_manager.get_attr(model,
"name").split("(")[0].strip()
new_name = model_manager.get_attr(new_model, "name")
model_manager.set_attr(new_model, "name",
"%s (projection of %s)" % \
(new_name, original_name))
except LookupError:
pass
else: else:
self.log.warn("The 2D projection at z=%g is empty. Aborted." % \ self.log.warn("The 2D projection at z=%g is empty. Aborted." % \
plane.p.z) plane.p.z)
......
...@@ -83,7 +83,7 @@ class ModelRotation(pycam.Plugins.PluginBase): ...@@ -83,7 +83,7 @@ class ModelRotation(pycam.Plugins.PluginBase):
progress.disable_cancel() progress.disable_cancel()
progress.set_multiple(len(models), "Model") progress.set_multiple(len(models), "Model")
for model in models: for model in models:
model.transform_by_matrix(matrix, callback=progress.update) model.model.transform_by_matrix(matrix, callback=progress.update)
progress.update_multiple() progress.update_multiple()
self.core.emit_event("model-change-after") self.core.emit_event("model-change-after")
progress.finish() progress.finish()
......
...@@ -82,7 +82,7 @@ class ModelScaling(pycam.Plugins.PluginBase): ...@@ -82,7 +82,7 @@ class ModelScaling(pycam.Plugins.PluginBase):
scale_value = self.gui.get_object("ScaleDimensionControl") scale_value = self.gui.get_object("ScaleDimensionControl")
index = axis_control.get_active() index = axis_control.get_active()
# TODO: get dimension of multiple models # TODO: get dimension of multiple models
model = models[0] model = models[0].model
dims = (model.maxx - model.minx, model.maxy - model.miny, dims = (model.maxx - model.minx, model.maxy - model.miny,
model.maxz - model.minz) model.maxz - model.minz)
value = dims[index] value = dims[index]
...@@ -107,7 +107,7 @@ class ModelScaling(pycam.Plugins.PluginBase): ...@@ -107,7 +107,7 @@ class ModelScaling(pycam.Plugins.PluginBase):
progress.disable_cancel() progress.disable_cancel()
progress.set_multiple(len(models), "Model") progress.set_multiple(len(models), "Model")
for model in models: for model in models:
model.scale(factor, callback=progress.update) model.model.scale(factor, callback=progress.update)
progress.update_multiple() progress.update_multiple()
progress.finish() progress.finish()
self.core.emit_event("model-change-after") self.core.emit_event("model-change-after")
...@@ -121,7 +121,7 @@ class ModelScaling(pycam.Plugins.PluginBase): ...@@ -121,7 +121,7 @@ class ModelScaling(pycam.Plugins.PluginBase):
axes = "xyz" axes = "xyz"
axis_suffix = axes[index] axis_suffix = axes[index]
# TODO: use dimension of multiple models # TODO: use dimension of multiple models
model = models[0] model = models[0].model
factor = value / (getattr(model, "max" + axis_suffix) - \ factor = value / (getattr(model, "max" + axis_suffix) - \
getattr(model, "min" + axis_suffix)) getattr(model, "min" + axis_suffix))
self.core.emit_event("model-change-before") self.core.emit_event("model-change-before")
...@@ -132,7 +132,7 @@ class ModelScaling(pycam.Plugins.PluginBase): ...@@ -132,7 +132,7 @@ class ModelScaling(pycam.Plugins.PluginBase):
for model in models: for model in models:
# TODO: use different scaling for multiple models # TODO: use different scaling for multiple models
if proportionally: if proportionally:
model.scale(factor, callback=progress.update) model.model.scale(factor, callback=progress.update)
else: else:
factor_x, factor_y, factor_z = (1, 1, 1) factor_x, factor_y, factor_z = (1, 1, 1)
if index == 0: if index == 0:
...@@ -143,7 +143,7 @@ class ModelScaling(pycam.Plugins.PluginBase): ...@@ -143,7 +143,7 @@ class ModelScaling(pycam.Plugins.PluginBase):
factor_z = factor factor_z = factor
else: else:
return return
model.scale(factor_x, factor_y, factor_z, model.model.scale(factor_x, factor_y, factor_z,
callback=progress.update) callback=progress.update)
progress.update_multiple() progress.update_multiple()
progress.finish() progress.finish()
......
...@@ -127,7 +127,8 @@ class ModelSupport(pycam.Plugins.PluginBase): ...@@ -127,7 +127,8 @@ class ModelSupport(pycam.Plugins.PluginBase):
def _add_support_model(self, widget=None): def _add_support_model(self, widget=None):
model = self.core.get("current_support_model") model = self.core.get("current_support_model")
if model: if model:
self.core.get("models").append(model) self.core.get("models").add_model(model,
name_template="Support model #%d")
def update_support_model(self, widget=None): def update_support_model(self, widget=None):
grid_type = self.core.get("support_model_type") grid_type = self.core.get("support_model_type")
......
...@@ -92,6 +92,7 @@ class ModelSupportDistributed(pycam.Plugins.PluginBase): ...@@ -92,6 +92,7 @@ class ModelSupportDistributed(pycam.Plugins.PluginBase):
return return
grid_type = self.core.get("support_model_type") grid_type = self.core.get("support_model_type")
support_model = None support_model = None
# TODO: completely broken code
if grid_type in ("distributed_edges", "distributed_corners"): if grid_type in ("distributed_edges", "distributed_corners"):
s = self.core s = self.core
if (s.get("support_grid_thickness") > 0) \ if (s.get("support_grid_thickness") > 0) \
...@@ -102,7 +103,7 @@ class ModelSupportDistributed(pycam.Plugins.PluginBase): ...@@ -102,7 +103,7 @@ class ModelSupportDistributed(pycam.Plugins.PluginBase):
bounds = s.get("current_bounds") bounds = s.get("current_bounds")
if bounds: if bounds:
minz = bounds.get_absolute_limits( minz = bounds.get_absolute_limits(
reference=model.get_bounds())[0][2] reference=model.model.get_bounds())[0][2]
corner_start = (grid_type == "distributed_corners") corner_start = (grid_type == "distributed_corners")
support_model = pycam.Toolpath.SupportGrid.get_support_distributed( support_model = pycam.Toolpath.SupportGrid.get_support_distributed(
s.get("model"), minz, s.get("model"), minz,
......
...@@ -288,7 +288,7 @@ class ModelSupportGrid(pycam.Plugins.PluginBase): ...@@ -288,7 +288,7 @@ class ModelSupportGrid(pycam.Plugins.PluginBase):
self.grid_adjustment_selector.set_active(-1) self.grid_adjustment_selector.set_active(-1)
def _get_bounds(self): def _get_bounds(self):
models = self.core.get("models").get_selected() models = [m.model for m in self.core.get("models").get_selected()]
low, high = pycam.Geometry.Model.get_combined_bounds(models) low, high = pycam.Geometry.Model.get_combined_bounds(models)
if None in low or None in high: if None in low or None in high:
return [0, 0, 0], [0, 0, 0] return [0, 0, 0], [0, 0, 0]
...@@ -298,3 +298,4 @@ class ModelSupportGrid(pycam.Plugins.PluginBase): ...@@ -298,3 +298,4 @@ class ModelSupportGrid(pycam.Plugins.PluginBase):
low[index] -= 5 low[index] -= 5
high[index] += 5 high[index] += 5
return low, high return low, high
...@@ -72,7 +72,7 @@ class ModelSwapAxes(pycam.Plugins.PluginBase): ...@@ -72,7 +72,7 @@ class ModelSwapAxes(pycam.Plugins.PluginBase):
progress.disable_cancel() progress.disable_cancel()
progress.set_multiple(len(models), "Model") progress.set_multiple(len(models), "Model")
for model in models: for model in models:
model.transform_by_template(template, model.model.transform_by_template(template,
callback=progress.update) callback=progress.update)
progress.update_multiple() progress.update_multiple()
progress.finish() progress.finish()
......
...@@ -25,6 +25,7 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>. ...@@ -25,6 +25,7 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
import pycam.Plugins import pycam.Plugins
_GTK_COLOR_MAX = 65535.0 _GTK_COLOR_MAX = 65535.0
...@@ -32,12 +33,9 @@ class Models(pycam.Plugins.ListPluginBase): ...@@ -32,12 +33,9 @@ class Models(pycam.Plugins.ListPluginBase):
UI_FILE = "models.ui" UI_FILE = "models.ui"
CATEGORIES = ["Model"] CATEGORIES = ["Model"]
COLUMN_REF, COLUMN_NAME, COLUMN_VISIBLE, COLUMN_COLOR, COLUMN_ALPHA = range(5) COLUMN_REF = 0
LIST_ATTRIBUTE_MAP = {"name": COLUMN_NAME, "visible": COLUMN_VISIBLE,
"color": COLUMN_COLOR, "alpha": COLUMN_ALPHA}
ICONS = {"visible": "visible.svg", "hidden": "visible_off.svg"} ICONS = {"visible": "visible.svg", "hidden": "visible_off.svg"}
# TODO: move this to the preferences dialog FALLBACK_COLOR = {"red": 0.5, "green": 0.5, "blue": 1.0, "alpha": 1.0}
DEFAULT_COLOR = (0.5, 0.5, 1.0, 1.0)
def setup(self): def setup(self):
if self.gui: if self.gui:
...@@ -65,13 +63,9 @@ class Models(pycam.Plugins.ListPluginBase): ...@@ -65,13 +63,9 @@ class Models(pycam.Plugins.ListPluginBase):
self._gtk_handlers.extend(( self._gtk_handlers.extend((
(self.gui.get_object("ModelColorButton"), "color-set", (self.gui.get_object("ModelColorButton"), "color-set",
self._set_colors_of_selected_models), self._set_colors_of_selected_models),
(self._modelview, "row-activated", (self._modelview, "row-activated", self._toggle_visibility),
self._list_action_toggle_custom, self.COLUMN_VISIBLE), (self.gui.get_object("NameCell"), "edited",
(self.gui.get_object("ModelNameColumn"), "edited",
self._edit_model_name))) self._edit_model_name)))
self.gui.get_object("ModelVisibleColumn").set_cell_data_func(
self.gui.get_object("ModelVisibleSymbol"),
self._visualize_visible_state)
self._treemodel = self.gui.get_object("ModelList") self._treemodel = self.gui.get_object("ModelList")
self._treemodel.clear() self._treemodel.clear()
def update_model(): def update_model():
...@@ -82,21 +76,17 @@ class Models(pycam.Plugins.ListPluginBase): ...@@ -82,21 +76,17 @@ class Models(pycam.Plugins.ListPluginBase):
cache[row[self.COLUMN_REF]] = list(row) cache[row[self.COLUMN_REF]] = list(row)
self._treemodel.clear() self._treemodel.clear()
for index, item in enumerate(self): for index, item in enumerate(self):
if id(item) in cache: if not id(item) in cache:
cache[id(item)] = [id(item)]
self._treemodel.append(cache[id(item)]) self._treemodel.append(cache[id(item)])
else:
color = "#%04x%04x%04x" % tuple([int(col * _GTK_COLOR_MAX)
for col in self.DEFAULT_COLOR[:3]])
self._treemodel.append((id(item), "Model #%d" % index,
True, color,
int(self.DEFAULT_COLOR[3] * _GTK_COLOR_MAX)))
self.core.emit_event("model-list-changed") self.core.emit_event("model-list-changed")
selection = self._modelview.get_selection() selection = self._modelview.get_selection()
selection.set_mode(self._gtk.SELECTION_MULTIPLE) selection.set_mode(self._gtk.SELECTION_MULTIPLE)
self._gtk_handlers.append((selection, "changed", self._gtk_handlers.append((selection, "changed",
"model-selection-changed")) "model-selection-changed"))
self._event_handlers = (("model-selection-changed", self._event_handlers = (
self._get_colors_of_selected_models), ) ("model-selection-changed", self._get_colors_of_selected_models),
("model-list-changed", self._trigger_table_update))
self.register_gtk_handlers(self._gtk_handlers) self.register_gtk_handlers(self._gtk_handlers)
self.register_event_handlers(self._event_handlers) self.register_event_handlers(self._event_handlers)
self._get_colors_of_selected_models() self._get_colors_of_selected_models()
...@@ -124,54 +114,88 @@ class Models(pycam.Plugins.ListPluginBase): ...@@ -124,54 +114,88 @@ class Models(pycam.Plugins.ListPluginBase):
color_button.set_sensitive(bool(models)) color_button.set_sensitive(bool(models))
if models: if models:
# use the color of the first model # use the color of the first model
model = models[0] col = models[0]["color"]
color_str = self.get_attr(model, "color") color_button.set_color(self._gtk.gdk.Color(
alpha_val = self.get_attr(model, "alpha") red=int(col["red"] * _GTK_COLOR_MAX),
color_button.set_color(self._gtk.gdk.color_parse(color_str)) green=int(col["green"] * _GTK_COLOR_MAX),
color_button.set_alpha(alpha_val) blue=int(col["blue"] * _GTK_COLOR_MAX)))
color_button.set_alpha(int(col["alpha"] * _GTK_COLOR_MAX))
def _set_colors_of_selected_models(self, widget=None): def _set_colors_of_selected_models(self, widget=None):
color_button = self.gui.get_object("ModelColorButton") color_button = self.gui.get_object("ModelColorButton")
color = color_button.get_color()
models = self.get_selected() models = self.get_selected()
color_str = color_button.get_color().to_string()
alpha_val = color_button.get_alpha()
for model in models: for model in models:
self.set_attr(model, "color", color_str) model["color"] = {"red": color.red / _GTK_COLOR_MAX,
self.set_attr(model, "alpha", alpha_val) "green": color.green / _GTK_COLOR_MAX,
"blue": color.blue / _GTK_COLOR_MAX,
"alpha": color_button.get_alpha() / _GTK_COLOR_MAX}
self.core.emit_event("visual-item-updated") self.core.emit_event("visual-item-updated")
def _trigger_table_update(self):
self.gui.get_object("NameColumn").set_cell_data_func(
self.gui.get_object("NameCell"), self._render_model_name)
self.gui.get_object("VisibleColumn").set_cell_data_func(
self.gui.get_object("VisibleSymbol"),
self._visualize_visible_state)
def _edit_model_name(self, cell, path, new_text): def _edit_model_name(self, cell, path, new_text):
path = int(path) path = int(path)
if (new_text != self._treemodel[path][self.COLUMN_NAME]) and \ model_ref = self._treemodel[path][self.COLUMN_REF]
new_text: model = [m for m in self if id(m) == model_ref][0]
self._treemodel[path][self.COLUMN_NAME] = new_text if (new_text != model["name"]) and new_text:
self.core.emit_event("model-list-changed") model["name"] = new_text
def _render_model_name(self, column, cell, model, m_iter):
path = model.get_path(m_iter)
model_dict = self[path[0]]
cell.set_property("text", model_dict["name"])
def _visualize_visible_state(self, column, cell, model, m_iter): def _visualize_visible_state(self, column, cell, model, m_iter):
visible = model.get_value(m_iter, self.COLUMN_VISIBLE) path = model.get_path(m_iter)
model_dict = self[path[0]]
visible = model_dict["visible"]
if visible: if visible:
cell.set_property("pixbuf", self.ICONS["visible"]) cell.set_property("pixbuf", self.ICONS["visible"])
else: else:
cell.set_property("pixbuf", self.ICONS["hidden"]) cell.set_property("pixbuf", self.ICONS["hidden"])
color = model_dict["color"]
def _list_action_toggle_custom(self, treeview, path, clicked_column, cell.set_property("cell-background-gdk", self._gtk.gdk.Color(
force_column=None): red=int(color["red"] * _GTK_COLOR_MAX),
if force_column is None: green=int(color["green"] * _GTK_COLOR_MAX),
column = self._modelview.get_columns().index(clicked_column) blue=int(color["blue"] * _GTK_COLOR_MAX)))
else:
column = force_column def _toggle_visibility(self, treeview, path, clicked_column):
self._list_action_toggle(clicked_column, str(path[0]), column) model = self[path[0]]
model["visible"] = not model["visible"]
def _list_action_toggle(self, widget, path, column):
path = int(path)
model = self._treemodel
model[path][column] = not model[path][column]
self.core.emit_event("visual-item-updated") self.core.emit_event("visual-item-updated")
def get_selected(self): def get_selected(self):
return self._get_selected(self._modelview, force_list=True) return self._get_selected(self._modelview, force_list=True)
def get_visible(self): def get_visible(self):
return [self[index] for index, item in enumerate(self._treemodel) return [model for model in self if model["visible"]]
if item[self.COLUMN_VISIBLE]]
def add_model(self, model, name=None, name_template="Model #%d"):
model_dict = ModelEntity(model)
if not name:
model_id = 1
model_names = [model["name"] for model in self]
while (name_template % model_id) in model_names:
model_id += 1
name = name_template % model_id
model_dict["name"] = name
color = self.core.get("color_model")
if not color:
color = self.FALLBACK_COLOR.copy()
model_dict["color"] = color
model_dict["visible"] = True
self.append(model_dict)
class ModelEntity(pycam.Plugins.ObjectWithAttributes):
def __init__(self, model):
self.model = model
super(ModelEntity, self).__init__("model")
...@@ -70,7 +70,7 @@ class OpenGLViewDimension(pycam.Plugins.PluginBase): ...@@ -70,7 +70,7 @@ class OpenGLViewDimension(pycam.Plugins.PluginBase):
def update_model_dimensions(self, widget=None): def update_model_dimensions(self, widget=None):
dimension_bar = self.gui.get_object("DimensionTable") dimension_bar = self.gui.get_object("DimensionTable")
models = self.core.get("models").get_visible() models = [m.model for m in self.core.get("models").get_visible()]
low, high = pycam.Geometry.Model.get_combined_bounds(models) low, high = pycam.Geometry.Model.get_combined_bounds(models)
if None in low or None in high: if None in low or None in high:
low, high = (0, 0, 0), (0, 0, 0) low, high = (0, 0, 0), (0, 0, 0)
......
...@@ -68,7 +68,7 @@ class OpenGLViewModel(pycam.Plugins.PluginBase): ...@@ -68,7 +68,7 @@ class OpenGLViewModel(pycam.Plugins.PluginBase):
def get_draw_dimension(self, low, high): def get_draw_dimension(self, low, high):
if self._is_visible(): if self._is_visible():
mlow, mhigh = pycam.Geometry.Model.get_combined_bounds( mlow, mhigh = pycam.Geometry.Model.get_combined_bounds(
self.core.get("models").get_visible()) [m.model for m in self.core.get("models").get_visible()])
if None in mlow or None in mhigh: if None in mlow or None in mhigh:
return return
for index in range(3): for index in range(3):
...@@ -80,12 +80,10 @@ class OpenGLViewModel(pycam.Plugins.PluginBase): ...@@ -80,12 +80,10 @@ class OpenGLViewModel(pycam.Plugins.PluginBase):
def draw_model(self): def draw_model(self):
GL = self._GL GL = self._GL
if self._is_visible(): if self._is_visible():
for model in self.core.get("models").get_visible(): for model_dict in self.core.get("models").get_visible():
color_str = self.core.get("models").get_attr(model, "color") model = model_dict.model
alpha = self.core.get("models").get_attr(model, "alpha") col = model_dict["color"]
col = self._gtk.gdk.color_parse(color_str) color = (col["red"], col["green"], col["blue"], col["alpha"])
color = (col.red / GTK_COLOR_MAX, col.green / GTK_COLOR_MAX,
col.blue / GTK_COLOR_MAX, alpha / GTK_COLOR_MAX)
GL.glColor4f(*color) GL.glColor4f(*color)
# reset the material color # reset the material color
GL.glMaterial(GL.GL_FRONT_AND_BACK, GL.glMaterial(GL.GL_FRONT_AND_BACK,
...@@ -96,11 +94,12 @@ class OpenGLViewModel(pycam.Plugins.PluginBase): ...@@ -96,11 +94,12 @@ class OpenGLViewModel(pycam.Plugins.PluginBase):
show_directions=self.core.get("show_directions")) show_directions=self.core.get("show_directions"))
do_caching = not key is None do_caching = not key is None
if do_caching and not key in self._cache: if do_caching and not key in self._cache:
# Rendering a display list takes less than 5% of the time for a # Rendering a display list takes less than 5% of the time
# complete rebuild. # for a complete rebuild.
list_index = GL.glGenLists(1) list_index = GL.glGenLists(1)
if list_index > 0: if list_index > 0:
# somehow "GL_COMPILE_AND_EXECUTE" fails - we render it later # Somehow "GL_COMPILE_AND_EXECUTE" fails - we render
# it later.
GL.glNewList(list_index, GL.GL_COMPILE) GL.glNewList(list_index, GL.GL_COMPILE)
else: else:
do_caching = False do_caching = False
......
...@@ -321,6 +321,6 @@ class PathParamTraceModel(pycam.Plugins.PluginBase): ...@@ -321,6 +321,6 @@ class PathParamTraceModel(pycam.Plugins.PluginBase):
models = self.core.get("models") models = self.core.get("models")
for model in models: for model in models:
if hasattr(model, "get_polygons"): if hasattr(model, "get_polygons"):
choices.append((models.get_attr(model, "name"), model)) choices.append((model["name"], model))
self.control.update_choices(choices) self.control.update_choices(choices)
...@@ -28,8 +28,7 @@ class Processes(pycam.Plugins.ListPluginBase): ...@@ -28,8 +28,7 @@ class Processes(pycam.Plugins.ListPluginBase):
DEPENDS = ["ParameterGroupManager"] DEPENDS = ["ParameterGroupManager"]
CATEGORIES = ["Process"] CATEGORIES = ["Process"]
UI_FILE = "processes.ui" UI_FILE = "processes.ui"
COLUMN_REF, COLUMN_NAME = range(2) COLUMN_REF = 0
LIST_ATTRIBUTE_MAP = {"ref": COLUMN_REF, "name": COLUMN_NAME}
def setup(self): def setup(self):
self.core.set("processes", self) self.core.set("processes", self)
...@@ -92,7 +91,7 @@ class Processes(pycam.Plugins.ListPluginBase): ...@@ -92,7 +91,7 @@ class Processes(pycam.Plugins.ListPluginBase):
self._treemodel.clear() self._treemodel.clear()
for index, item in enumerate(self): for index, item in enumerate(self):
if not id(item) in cache: if not id(item) in cache:
cache[id(item)] = [id(item), "Process #%d" % index] cache[id(item)] = [id(item)]
self._treemodel.append(cache[id(item)]) self._treemodel.append(cache[id(item)])
self.core.emit_event("process-list-changed") self.core.emit_event("process-list-changed")
self._gtk_handlers.append((self.gui.get_object("StrategySelector"), self._gtk_handlers.append((self.gui.get_object("StrategySelector"),
...@@ -137,21 +136,28 @@ class Processes(pycam.Plugins.ListPluginBase): ...@@ -137,21 +136,28 @@ class Processes(pycam.Plugins.ListPluginBase):
def _render_process_description(self, column, cell, model, m_iter): def _render_process_description(self, column, cell, model, m_iter):
path = model.get_path(m_iter) path = model.get_path(m_iter)
data = self[path[0]] data = self[path[0]]
# find the current strategy # TODO: describe the strategy
text = "TODO" text = "TODO"
cell.set_property("text", text) cell.set_property("text", text)
def _render_process_name(self, column, cell, model, m_iter):
path = model.get_path(m_iter)
data = self[path[0]]
cell.set_property("text", data["name"])
def _edit_process_name(self, cell, path, new_text): def _edit_process_name(self, cell, path, new_text):
path = int(path) path = int(path)
if (new_text != self._treemodel[path][self.COLUMN_NAME]) and \ process_ref = self._treemodel[path][self.COLUMN_REF]
new_text: process = [p for p in self if id(p) == process_ref][0]
self._treemodel[path][self.COLUMN_NAME] = new_text if (new_text != process["name"]) and new_text:
process["name"] = new_text
def _trigger_table_update(self): def _trigger_table_update(self):
# trigger a table update - this is clumsy! self.gui.get_object("NameColumn").set_cell_data_func(
cell = self.gui.get_object("DescriptionColumn") self.gui.get_object("NameCell"), self._render_process_name)
renderer = self.gui.get_object("DescriptionCell") self.gui.get_object("DescriptionColumn").set_cell_data_func(
cell.set_cell_data_func(renderer, self._render_process_description) self.gui.get_object("DescriptionCell"),
self._render_process_description)
def _update_widgets(self): def _update_widgets(self):
selected = self._get_strategy() selected = self._get_strategy()
...@@ -257,8 +263,14 @@ class Processes(pycam.Plugins.ListPluginBase): ...@@ -257,8 +263,14 @@ class Processes(pycam.Plugins.ListPluginBase):
strategies = self.core.get("get_parameter_sets")("process").values() strategies = self.core.get("get_parameter_sets")("process").values()
strategies.sort(key=lambda item: item["weight"]) strategies.sort(key=lambda item: item["weight"])
strategy = strategies[0] strategy = strategies[0]
strategy_names = [process["name"] for process in self]
process_id = 1
name_template = "Process #%d"
while (name_template % process_id) in strategy_names:
process_id += 1
new_process = ProcessEntity({"strategy": strategy["name"], new_process = ProcessEntity({"strategy": strategy["name"],
"parameters": strategy["parameters"].copy()}) "parameters": strategy["parameters"].copy(),
"name": name_template % process_id})
self.append(new_process) self.append(new_process)
self.select(new_process) self.select(new_process)
......
...@@ -51,8 +51,8 @@ class TaskParamCollisionModels(pycam.Plugins.PluginBase): ...@@ -51,8 +51,8 @@ class TaskParamCollisionModels(pycam.Plugins.PluginBase):
choices = [] choices = []
models = self.core.get("models") models = self.core.get("models")
for model in models: for model in models:
if hasattr(model, "triangles"): if hasattr(model.model, "triangles"):
choices.append((models.get_attr(model, "name"), model)) choices.append((model["name"], model))
self.control.update_choices(choices) self.control.update_choices(choices)
...@@ -80,7 +80,7 @@ class TaskParamTool(pycam.Plugins.PluginBase): ...@@ -80,7 +80,7 @@ class TaskParamTool(pycam.Plugins.PluginBase):
choices = [] choices = []
tools = self.core.get("tools") tools = self.core.get("tools")
for tool in tools: for tool in tools:
choices.append((tools.get_attr(tool, "name"), tool)) choices.append((tool["name"], tool))
self.control.update_choices(choices) self.control.update_choices(choices)
...@@ -108,7 +108,7 @@ class TaskParamProcess(pycam.Plugins.PluginBase): ...@@ -108,7 +108,7 @@ class TaskParamProcess(pycam.Plugins.PluginBase):
choices = [] choices = []
processes = self.core.get("processes") processes = self.core.get("processes")
for process in processes: for process in processes:
choices.append((processes.get_attr(process, "name"), process)) choices.append((process["name"], process))
self.control.update_choices(choices) self.control.update_choices(choices)
...@@ -136,6 +136,6 @@ class TaskParamBounds(pycam.Plugins.PluginBase): ...@@ -136,6 +136,6 @@ class TaskParamBounds(pycam.Plugins.PluginBase):
choices = [] choices = []
bounds = self.core.get("bounds") bounds = self.core.get("bounds")
for bound in bounds: for bound in bounds:
choices.append((bounds.get_attr(bound, "name"), bound)) choices.append((bound["name"], bound))
self.control.update_choices(choices) self.control.update_choices(choices)
...@@ -67,7 +67,7 @@ class TaskTypeMilling(pycam.Plugins.PluginBase): ...@@ -67,7 +67,7 @@ class TaskTypeMilling(pycam.Plugins.PluginBase):
if path_generator is None: if path_generator is None:
# we assume that an error message was given already # we assume that an error message was given already
return return
models = task["parameters"]["collision_models"] models = [m.model for m in task["parameters"]["collision_models"]]
moves = path_generator.GenerateToolPath(tool, models, motion_grid, moves = path_generator.GenerateToolPath(tool, models, motion_grid,
minz=low[2], maxz=high[2], draw_callback=callback) minz=low[2], maxz=high[2], draw_callback=callback)
if not moves: if not moves:
......
...@@ -31,8 +31,7 @@ class Tasks(pycam.Plugins.ListPluginBase): ...@@ -31,8 +31,7 @@ class Tasks(pycam.Plugins.ListPluginBase):
UI_FILE = "tasks.ui" UI_FILE = "tasks.ui"
CATEGORIES = ["Task"] CATEGORIES = ["Task"]
COLUMN_REF, COLUMN_NAME = range(2) COLUMN_REF = 0
LIST_ATTRIBUTE_MAP = {"id": COLUMN_REF, "name": COLUMN_NAME}
DEPENDS = ["Models", "Tools", "Processes", "Bounds", "Toolpaths"] DEPENDS = ["Models", "Tools", "Processes", "Bounds", "Toolpaths"]
def setup(self): def setup(self):
...@@ -87,7 +86,7 @@ class Tasks(pycam.Plugins.ListPluginBase): ...@@ -87,7 +86,7 @@ class Tasks(pycam.Plugins.ListPluginBase):
self.core.register_ui("task_parameters", "Components", self.core.register_ui("task_parameters", "Components",
self.components_widget.widget, weight=10) self.components_widget.widget, weight=10)
# table # table
self._gtk_handlers.append((self.gui.get_object("TaskNameCell"), self._gtk_handlers.append((self.gui.get_object("NameCell"),
"edited", self._edit_task_name)) "edited", self._edit_task_name))
selection = self._taskview.get_selection() selection = self._taskview.get_selection()
self._gtk_handlers.append((selection, "changed", self._gtk_handlers.append((selection, "changed",
...@@ -110,10 +109,9 @@ class Tasks(pycam.Plugins.ListPluginBase): ...@@ -110,10 +109,9 @@ class Tasks(pycam.Plugins.ListPluginBase):
cache[row[self.COLUMN_REF]] = list(row) cache[row[self.COLUMN_REF]] = list(row)
self._treemodel.clear() self._treemodel.clear()
for index, item in enumerate(self): for index, item in enumerate(self):
if id(item) in cache: if not id(item) in cache:
cache[id(item)] = [id(item)]
self._treemodel.append(cache[id(item)]) self._treemodel.append(cache[id(item)])
else:
self._treemodel.append((id(item), "Task #%d" % index))
self.core.emit_event("task-list-changed") self.core.emit_event("task-list-changed")
# shape selector # shape selector
self._gtk_handlers.append((self.gui.get_object("TaskTypeSelector"), self._gtk_handlers.append((self.gui.get_object("TaskTypeSelector"),
...@@ -122,6 +120,7 @@ class Tasks(pycam.Plugins.ListPluginBase): ...@@ -122,6 +120,7 @@ class Tasks(pycam.Plugins.ListPluginBase):
("task-type-list-changed", self._update_table), ("task-type-list-changed", self._update_table),
("task-selection-changed", self._task_switch), ("task-selection-changed", self._task_switch),
("task-changed", self._store_task), ("task-changed", self._store_task),
("task-changed", self._trigger_table_update),
("task-type-changed", self._store_task), ("task-type-changed", self._store_task),
("task-selection-changed", self._update_widgets), ("task-selection-changed", self._update_widgets),
("task-list-changed", self._update_widgets)) ("task-list-changed", self._update_widgets))
...@@ -131,6 +130,7 @@ class Tasks(pycam.Plugins.ListPluginBase): ...@@ -131,6 +130,7 @@ class Tasks(pycam.Plugins.ListPluginBase):
self._update_widgets() self._update_widgets()
self._update_table() self._update_table()
self._task_switch() self._task_switch()
self._trigger_table_update()
self.register_state_item("tasks", self) self.register_state_item("tasks", self)
self.core.set("tasks", self) self.core.set("tasks", self)
return True return True
...@@ -167,9 +167,19 @@ class Tasks(pycam.Plugins.ListPluginBase): ...@@ -167,9 +167,19 @@ class Tasks(pycam.Plugins.ListPluginBase):
def _edit_task_name(self, cell, path, new_text): def _edit_task_name(self, cell, path, new_text):
path = int(path) path = int(path)
if (new_text != self._treemodel[path][self.COLUMN_NAME]) and \ task_ref = self._treemodel[path][self.COLUMN_REF]
new_text: task = [t for t in self if id(t) == task_ref][0]
self._treemodel[path][self.COLUMN_NAME] = new_text if (new_text != task["name"]) and new_text:
task["name"] = new_text
def _trigger_table_update(self):
self.gui.get_object("NameColumn").set_cell_data_func(
self.gui.get_object("NameCell"), self._render_task_name)
def _render_task_name(self, column, cell, model, m_iter):
path = model.get_path(m_iter)
task = self[path[0]]
cell.set_property("text", task["name"])
def _get_type(self, name=None): def _get_type(self, name=None):
types = self.core.get("get_parameter_sets")("task") types = self.core.get("get_parameter_sets")("task")
...@@ -266,8 +276,14 @@ class Tasks(pycam.Plugins.ListPluginBase): ...@@ -266,8 +276,14 @@ class Tasks(pycam.Plugins.ListPluginBase):
types = self.core.get("get_parameter_sets")("task").values() types = self.core.get("get_parameter_sets")("task").values()
types.sort(key=lambda item: item["weight"]) types.sort(key=lambda item: item["weight"])
one_type = types[0] one_type = types[0]
task_id = 1
name_template = "Task #%d"
task_names = [task["name"] for task in self]
while (name_template % task_id) in task_names:
task_id += 1
new_task = TaskEntity({"type": one_type["name"], new_task = TaskEntity({"type": one_type["name"],
"parameters": one_type["parameters"].copy()}) "parameters": one_type["parameters"].copy(),
"name": name_template % task_id})
self.append(new_task) self.append(new_task)
self.select(new_task) self.select(new_task)
......
...@@ -31,8 +31,8 @@ class ToolParamRadius(pycam.Plugins.PluginBase): ...@@ -31,8 +31,8 @@ class ToolParamRadius(pycam.Plugins.PluginBase):
CATEGORIES = ["Tool", "Parameter"] CATEGORIES = ["Tool", "Parameter"]
def setup(self): def setup(self):
self.control = pycam.Gui.ControlsGTK.InputNumber(lower=0, upper=99, self.control = pycam.Gui.ControlsGTK.InputNumber(lower=0, upper=999,
digits=0, change_handler=lambda widget=None: \ digits=4, change_handler=lambda widget=None: \
self.core.emit_event("tool-changed")) self.core.emit_event("tool-changed"))
self.control.set_conversion(set_conv=lambda value: value * 2.0, self.control.set_conversion(set_conv=lambda value: value * 2.0,
get_conv=lambda value: value / 2.0) get_conv=lambda value: value / 2.0)
...@@ -61,8 +61,8 @@ class ToolParamTorusRadius(pycam.Plugins.PluginBase): ...@@ -61,8 +61,8 @@ class ToolParamTorusRadius(pycam.Plugins.PluginBase):
CATEGORIES = ["Tool", "Parameter"] CATEGORIES = ["Tool", "Parameter"]
def setup(self): def setup(self):
self.control = pycam.Gui.ControlsGTK.InputNumber(lower=0, upper=99, self.control = pycam.Gui.ControlsGTK.InputNumber(lower=0, upper=999,
digits=0, change_handler=lambda widget=None: \ digits=4, change_handler=lambda widget=None: \
self.core.emit_event( "tool-changed")) self.core.emit_event( "tool-changed"))
self.core.get("register_parameter")("tool", "torus_radius", self.core.get("register_parameter")("tool", "torus_radius",
self.control) self.control)
...@@ -81,7 +81,7 @@ class ToolParamFeedrate(pycam.Plugins.PluginBase): ...@@ -81,7 +81,7 @@ class ToolParamFeedrate(pycam.Plugins.PluginBase):
CATEGORIES = ["Tool", "Parameter"] CATEGORIES = ["Tool", "Parameter"]
def setup(self): def setup(self):
self.control = pycam.Gui.ControlsGTK.InputNumber(lower=0, upper=10000, self.control = pycam.Gui.ControlsGTK.InputNumber(lower=0, upper=50000,
digits=0, change_handler=lambda widget=None: \ digits=0, change_handler=lambda widget=None: \
self.core.emit_event("tool-changed")) self.core.emit_event("tool-changed"))
self.core.get("register_parameter")("tool", "feedrate", self.control) self.core.get("register_parameter")("tool", "feedrate", self.control)
......
...@@ -85,7 +85,7 @@ class ToolpathCrop(pycam.Plugins.PluginBase): ...@@ -85,7 +85,7 @@ class ToolpathCrop(pycam.Plugins.PluginBase):
choices = [] choices = []
models = self.core.get("models") models = self.core.get("models")
for model in models: for model in models:
choices.append((models.get_attr(model, "name"), model)) choices.append((model["name"], model))
self.models_widget.update_choices(choices) self.models_widget.update_choices(choices)
def _update_visibility(self): def _update_visibility(self):
...@@ -95,7 +95,7 @@ class ToolpathCrop(pycam.Plugins.PluginBase): ...@@ -95,7 +95,7 @@ class ToolpathCrop(pycam.Plugins.PluginBase):
self._frame.hide() self._frame.hide()
def _update_widgets(self, widget=None): def _update_widgets(self, widget=None):
models = self.models_widget.get_value() models = [m.model for m in self.models_widget.get_value()]
info_label = self.gui.get_object("ToolpathCropInfo") info_label = self.gui.get_object("ToolpathCropInfo")
info_box = self.gui.get_object("ToolpathCropInfoBox") info_box = self.gui.get_object("ToolpathCropInfoBox")
button = self.gui.get_object("CropButton") button = self.gui.get_object("CropButton")
...@@ -136,7 +136,7 @@ class ToolpathCrop(pycam.Plugins.PluginBase): ...@@ -136,7 +136,7 @@ class ToolpathCrop(pycam.Plugins.PluginBase):
button.set_sensitive(False) button.set_sensitive(False)
def _get_waterlines(self): def _get_waterlines(self):
models = self.models_widget.get_value() models = [m.model for m in self.models_widget.get_value()]
polygons = [] polygons = []
# get all waterlines and polygons # get all waterlines and polygons
for model in models: for model in models:
......
...@@ -28,8 +28,7 @@ class Tools(pycam.Plugins.ListPluginBase): ...@@ -28,8 +28,7 @@ class Tools(pycam.Plugins.ListPluginBase):
DEPENDS = ["ParameterGroupManager"] DEPENDS = ["ParameterGroupManager"]
CATEGORIES = ["Tool"] CATEGORIES = ["Tool"]
UI_FILE = "tools.ui" UI_FILE = "tools.ui"
COLUMN_REF, COLUMN_TOOL_ID, COLUMN_NAME = range(3) COLUMN_REF = 0
LIST_ATTRIBUTE_MAP = {"id": COLUMN_TOOL_ID, "name": COLUMN_NAME}
def setup(self): def setup(self):
self.core.set("tools", self) self.core.set("tools", self)
...@@ -41,7 +40,7 @@ class Tools(pycam.Plugins.ListPluginBase): ...@@ -41,7 +40,7 @@ class Tools(pycam.Plugins.ListPluginBase):
self._gtk_handlers = [] self._gtk_handlers = []
self.core.register_chain("get_toolpath_information", self.core.register_chain("get_toolpath_information",
self.get_toolpath_information) self.get_toolpath_information)
self._modelview = self.gui.get_object("ToolEditorTable") self._modelview = self.gui.get_object("ToolTable")
for action, obj_name in ((self.ACTION_UP, "ToolMoveUp"), for action, obj_name in ((self.ACTION_UP, "ToolMoveUp"),
(self.ACTION_DOWN, "ToolMoveDown"), (self.ACTION_DOWN, "ToolMoveDown"),
(self.ACTION_DELETE, "ToolDelete")): (self.ACTION_DELETE, "ToolDelete")):
...@@ -85,12 +84,12 @@ class Tools(pycam.Plugins.ListPluginBase): ...@@ -85,12 +84,12 @@ class Tools(pycam.Plugins.ListPluginBase):
self.speed_widget.add_widget, self.speed_widget.add_widget,
self.speed_widget.clear_widgets) self.speed_widget.clear_widgets)
# table updates # table updates
cell = self.gui.get_object("ToolTableShapeCell") cell = self.gui.get_object("ShapeCell")
self.gui.get_object("ToolTableShapeColumn").set_cell_data_func( self.gui.get_object("ShapeColumn").set_cell_data_func(
cell, self._render_tool_shape) cell, self._render_tool_shape)
self._gtk_handlers.append((self.gui.get_object("ToolTableIDCell"), self._gtk_handlers.append((self.gui.get_object("IDCell"),
"edited", self._edit_tool_id)) "edited", self._edit_tool_id))
self._gtk_handlers.append((self.gui.get_object("ToolTableNameCell"), self._gtk_handlers.append((self.gui.get_object("NameCell"),
"edited", self._edit_tool_name)) "edited", self._edit_tool_name))
self._treemodel = self.gui.get_object("ToolList") self._treemodel = self.gui.get_object("ToolList")
self._treemodel.clear() self._treemodel.clear()
...@@ -103,8 +102,7 @@ class Tools(pycam.Plugins.ListPluginBase): ...@@ -103,8 +102,7 @@ class Tools(pycam.Plugins.ListPluginBase):
self._treemodel.clear() self._treemodel.clear()
for index, item in enumerate(self): for index, item in enumerate(self):
if not id(item) in cache: if not id(item) in cache:
cache[id(item)] = [id(item), index + 1, cache[id(item)] = [id(item)]
"Tool #%d" % index]
self._treemodel.append(cache[id(item)]) self._treemodel.append(cache[id(item)])
self.core.emit_event("tool-list-changed") self.core.emit_event("tool-list-changed")
# selector # selector
...@@ -118,11 +116,14 @@ class Tools(pycam.Plugins.ListPluginBase): ...@@ -118,11 +116,14 @@ class Tools(pycam.Plugins.ListPluginBase):
("tool-shape-list-changed", self._update_widgets), ("tool-shape-list-changed", self._update_widgets),
("tool-selection-changed", self._tool_switch), ("tool-selection-changed", self._tool_switch),
("tool-changed", self._store_tool_settings), ("tool-changed", self._store_tool_settings),
("tool-changed", self._trigger_table_update),
("tool-list-changed", self._trigger_table_update),
("tool-shape-changed", self._store_tool_settings)) ("tool-shape-changed", self._store_tool_settings))
self.register_model_update(update_model) self.register_model_update(update_model)
self.register_gtk_handlers(self._gtk_handlers) self.register_gtk_handlers(self._gtk_handlers)
self.register_event_handlers(self._event_handlers) self.register_event_handlers(self._event_handlers)
self._update_widgets() self._update_widgets()
self._trigger_table_update()
self._tool_switch() self._tool_switch()
self.register_state_item("tools", self) self.register_state_item("tools", self)
return True return True
...@@ -158,7 +159,20 @@ class Tools(pycam.Plugins.ListPluginBase): ...@@ -158,7 +159,20 @@ class Tools(pycam.Plugins.ListPluginBase):
def get_toolpath_information(self, item, data): def get_toolpath_information(self, item, data):
if item in self: if item in self:
data["tool_id"] = self.get_attr(item, "id") data["tool_id"] = item["id"]
def _trigger_table_update(self):
self.gui.get_object("IDColumn").set_cell_data_func(
self.gui.get_object("IDCell"), self._render_tool_info, "id")
self.gui.get_object("NameColumn").set_cell_data_func(
self.gui.get_object("NameCell"), self._render_tool_info, "name")
self.gui.get_object("ShapeColumn").set_cell_data_func(
self.gui.get_object("ShapeCell"), self._render_tool_shape)
def _render_tool_info(self, column, cell, model, m_iter, key):
path = model.get_path(m_iter)
tool = self[path[0]]
cell.set_property("text", str(tool[key]))
def _render_tool_shape(self, column, cell, model, m_iter): def _render_tool_shape(self, column, cell, model, m_iter):
path = model.get_path(m_iter) path = model.get_path(m_iter)
...@@ -172,18 +186,21 @@ class Tools(pycam.Plugins.ListPluginBase): ...@@ -172,18 +186,21 @@ class Tools(pycam.Plugins.ListPluginBase):
def _edit_tool_name(self, cell, path, new_text): def _edit_tool_name(self, cell, path, new_text):
path = int(path) path = int(path)
if (new_text != self._treemodel[path][self.COLUMN_NAME]) and \ tool_ref = self._treemodel[path][self.COLUMN_REF]
new_text: tool = [t for t in self if id(t) == tool_ref][0]
self._treemodel[path][self.COLUMN_NAME] = new_text if (new_text != tool["name"]) and new_text:
tool["name"] = new_text
def _edit_tool_id(self, cell, path, new_text): def _edit_tool_id(self, cell, path, new_text):
path = int(path) path = int(path)
tool_ref = self._treemodel[path][self.COLUMN_REF]
tool = [t for t in self if id(t) == tool_ref][0]
try: try:
new_value = int(new_text) new_value = int(new_text)
except ValueError: except ValueError:
return return
if str(new_value) != self._treemodel[path][self.COLUMN_TOOL_ID]: if new_value != tool["id"]:
self._treemodel[path][self.COLUMN_TOOL_ID] = new_value tool["id"] = new_value
def _get_shape(self, name=None): def _get_shape(self, name=None):
shapes = self.core.get("get_parameter_sets")("tool") shapes = self.core.get("get_parameter_sets")("tool")
...@@ -211,12 +228,6 @@ class Tools(pycam.Plugins.ListPluginBase): ...@@ -211,12 +228,6 @@ class Tools(pycam.Plugins.ListPluginBase):
else: else:
selector.set_active(-1) selector.set_active(-1)
def _trigger_table_update(self):
# trigger a table update - this is clumsy!
cell = self.gui.get_object("ToolTableShapeColumn")
renderer = self.gui.get_object("ToolTableShapeCell")
cell.set_cell_data_func(renderer, self._render_tool_shape)
def _update_widgets(self): def _update_widgets(self):
selected = self._get_shape() selected = self._get_shape()
model = self.gui.get_object("ToolShapeList") model = self.gui.get_object("ToolShapeList")
...@@ -275,12 +286,22 @@ class Tools(pycam.Plugins.ListPluginBase): ...@@ -275,12 +286,22 @@ class Tools(pycam.Plugins.ListPluginBase):
# trigger a widget update # trigger a widget update
self.core.emit_event("tool-shape-changed") self.core.emit_event("tool-shape-changed")
def _get_new_tool_id_and_name(self):
tools = self.core.get("tools")
tool_ids = [tool["id"] for tool in tools]
tool_id = 1
while tool_id in tool_ids:
tool_id += 1
return (tool_id, "Tool #%d" % tool_id)
def _tool_new(self, *args): def _tool_new(self, *args):
shapes = self.core.get("get_parameter_sets")("tool").values() shapes = self.core.get("get_parameter_sets")("tool").values()
shapes.sort(key=lambda item: item["weight"]) shapes.sort(key=lambda item: item["weight"])
shape = shapes[0] shape = shapes[0]
tool_id, tool_name = self._get_new_tool_id_and_name()
new_tool = ToolEntity({"shape": shape["name"], new_tool = ToolEntity({"shape": shape["name"],
"parameters": shape["parameters"].copy()}) "parameters": shape["parameters"].copy(),
"id": tool_id, "name": tool_name})
self.append(new_tool) self.append(new_tool)
self.select(new_tool) self.select(new_tool)
......
...@@ -488,32 +488,6 @@ class ListPluginBase(PluginBase, list): ...@@ -488,32 +488,6 @@ class ListPluginBase(PluginBase, list):
# initialize the state of the button # initialize the state of the button
self._update_list_action_button_state(modelview, action, button) self._update_list_action_button_state(modelview, action, button)
def get_attr(self, item, attr, model=None, id_col=None):
return self.__get_set_attr(item, attr, write=False, model=model, id_col=id_col)
def set_attr(self, item, attr, value, model=None, id_col=None):
return self.__get_set_attr(item, attr, value=value, write=True, model=model, id_col=id_col)
def __get_set_attr(self, item, attr, value=None, write=True, model=None, id_col=None):
if model is None:
# TODO: "self.treemodel" should not be used here
model = self._treemodel
if id_col is None:
id_col = self.COLUMN_REF
if attr in self.LIST_ATTRIBUTE_MAP:
col = self.LIST_ATTRIBUTE_MAP[attr]
for index in range(len(model)):
if model[index][id_col] == id(item):
if write:
model[index][col] = value
return
else:
return model[index][col]
raise IndexError("Item '%s' not found in %s" % (item, list(model)))
else:
raise KeyError("Attribute '%s' is not part of this list: %s" % \
(attr, ", ".join(self.LIST_ATTRIBUTE_MAP.keys())))
class ObjectWithAttributes(dict): class ObjectWithAttributes(dict):
......
...@@ -45,6 +45,9 @@ def get_xml(item, name=None): ...@@ -45,6 +45,9 @@ def get_xml(item, name=None):
leaf.text = repr(item) leaf.text = repr(item)
return leaf return leaf
def parse_xml_dict(item):
pass
def get_xml_lines(item): def get_xml_lines(item):
lines = [] lines = []
content = ET.tostring(item) content = ET.tostring(item)
......
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