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