Commit e32de58c authored by sumpfralle's avatar sumpfralle

added a first draft of the GUI for simulation mode

fixed the "CTRL-C"-way of quitting the program


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@314 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent b06eba20
...@@ -267,13 +267,6 @@ def draw_bounding_box(minx, miny, minz, maxx, maxy, maxz, color): ...@@ -267,13 +267,6 @@ def draw_bounding_box(minx, miny, minz, maxx, maxy, maxz, color):
GL.glVertex3f(*(corner_pair[1])) GL.glVertex3f(*(corner_pair[1]))
GL.glEnd() GL.glEnd()
@keep_gl_mode
@keep_matrix
def draw_cutter(cutter, color):
if not cutter is None:
GL.glColor3f(*color)
cutter.to_OpenGL()
@keep_gl_mode @keep_gl_mode
@keep_matrix @keep_matrix
def draw_complete_model_view(settings): def draw_complete_model_view(settings):
...@@ -288,6 +281,12 @@ def draw_complete_model_view(settings): ...@@ -288,6 +281,12 @@ def draw_complete_model_view(settings):
float(settings.get("minz")), float(settings.get("maxx")), float(settings.get("minz")), float(settings.get("maxx")),
float(settings.get("maxy")), float(settings.get("maxz")), float(settings.get("maxy")), float(settings.get("maxz")),
settings.get("color_bounding_box")) settings.get("color_bounding_box"))
# draw the material (for simulation mode)
if settings.get("show_simulation"):
obj = settings.get("simulation_object")
if not obj is None:
GL.glColor3f(*settings.get("color_material"))
obj.to_OpenGL()
# draw the model # draw the model
if settings.get("show_model"): if settings.get("show_model"):
GL.glColor3f(*settings.get("color_model")) GL.glColor3f(*settings.get("color_model"))
...@@ -301,7 +300,10 @@ def draw_complete_model_view(settings): ...@@ -301,7 +300,10 @@ def draw_complete_model_view(settings):
settings.get("color_toolpath_return")) settings.get("color_toolpath_return"))
# draw the drill # draw the drill
if settings.get("show_drill_progress"): if settings.get("show_drill_progress"):
draw_cutter(settings.get("cutter"), settings.get("color_cutter")) cutter = settings.get("cutter")
if not cutter is None:
GL.glColor3f(*settings.get("color_cutter"))
cutter.to_OpenGL()
@keep_gl_mode @keep_gl_mode
@keep_matrix @keep_matrix
......
...@@ -10,6 +10,8 @@ import pycam.Cutters ...@@ -10,6 +10,8 @@ import pycam.Cutters
import pycam.PathGenerators import pycam.PathGenerators
import pycam.PathProcessors import pycam.PathProcessors
import pycam.Geometry.utils as utils import pycam.Geometry.utils as utils
# this requires ODE - we import it later, if necessary
#import pycam.Simulation.ODEBlocks
import pycam.Gui.OpenGLTools as ogl_tools import pycam.Gui.OpenGLTools as ogl_tools
import pycam.Gui.ode_objects as ode_objects import pycam.Gui.ode_objects as ode_objects
import OpenGL.GL as GL import OpenGL.GL as GL
...@@ -20,6 +22,7 @@ import OpenGL.GLUT as GLUT ...@@ -20,6 +22,7 @@ import OpenGL.GLUT as GLUT
import gtk import gtk
import pango import pango
import ConfigParser import ConfigParser
import math
import time import time
import re import re
import os import os
...@@ -49,6 +52,7 @@ COLORS = { ...@@ -49,6 +52,7 @@ COLORS = {
"color_cutter": (1.0, 0.2, 0.2), "color_cutter": (1.0, 0.2, 0.2),
"color_toolpath_cut": (1.0, 0.5, 0.5), "color_toolpath_cut": (1.0, 0.5, 0.5),
"color_toolpath_return": (0.5, 1.0, 0.5), "color_toolpath_return": (0.5, 1.0, 0.5),
"color_material": (1.0, 0.5, 0.0),
} }
PREFERENCES_DEFAULTS = { PREFERENCES_DEFAULTS = {
...@@ -67,9 +71,11 @@ PREFERENCES_DEFAULTS = { ...@@ -67,9 +71,11 @@ PREFERENCES_DEFAULTS = {
"color_cutter": COLORS["color_cutter"], "color_cutter": COLORS["color_cutter"],
"color_toolpath_cut": COLORS["color_toolpath_cut"], "color_toolpath_cut": COLORS["color_toolpath_cut"],
"color_toolpath_return": COLORS["color_toolpath_return"], "color_toolpath_return": COLORS["color_toolpath_return"],
"color_material": COLORS["color_material"],
"view_light": True, "view_light": True,
"view_shadow": True, "view_shadow": True,
"view_polygon": True, "view_polygon": True,
"simulation_details_level": 3,
"drill_progress_max_fps": 2, "drill_progress_max_fps": 2,
} }
""" the listed items will be loaded/saved via the preferences file in the """ the listed items will be loaded/saved via the preferences file in the
...@@ -537,7 +543,8 @@ class ProjectGui: ...@@ -537,7 +543,8 @@ class ProjectGui:
("color_bounding_box", "ColorBoundingBox"), ("color_bounding_box", "ColorBoundingBox"),
("color_cutter", "ColorDrill"), ("color_cutter", "ColorDrill"),
("color_toolpath_cut", "ColorToolpathCut"), ("color_toolpath_cut", "ColorToolpathCut"),
("color_toolpath_return", "ColorToolpathReturn")): ("color_toolpath_return", "ColorToolpathReturn"),
("color_material", "ColorMaterial")):
obj = self.gui.get_object(objname) obj = self.gui.get_object(objname)
self.settings.add_item(name, get_color_wrapper(obj), set_color_wrapper(obj)) self.settings.add_item(name, get_color_wrapper(obj), set_color_wrapper(obj))
# repaint the 3d view after a color change # repaint the 3d view after a color change
...@@ -552,6 +559,8 @@ class ProjectGui: ...@@ -552,6 +559,8 @@ class ProjectGui:
self.settings.add_item("enable_ode", lambda: False, lambda state: None) self.settings.add_item("enable_ode", lambda: False, lambda state: None)
skip_obj = self.gui.get_object("DrillProgressFrameSkipControl") skip_obj = self.gui.get_object("DrillProgressFrameSkipControl")
self.settings.add_item("drill_progress_max_fps", skip_obj.get_value, skip_obj.set_value) self.settings.add_item("drill_progress_max_fps", skip_obj.get_value, skip_obj.set_value)
sim_detail_obj = self.gui.get_object("SimulationDetailsValue")
self.settings.add_item("simulation_details_level", sim_detail_obj.get_value, sim_detail_obj.set_value)
# drill settings # drill settings
for objname, key in ( for objname, key in (
("ToolRadiusControl", "tool_radius"), ("ToolRadiusControl", "tool_radius"),
...@@ -601,6 +610,9 @@ class ProjectGui: ...@@ -601,6 +610,9 @@ class ProjectGui:
self.gui.get_object("toolpath_up").connect("clicked", self.toolpath_table_event, "move_up") self.gui.get_object("toolpath_up").connect("clicked", self.toolpath_table_event, "move_up")
self.gui.get_object("toolpath_down").connect("clicked", self.toolpath_table_event, "move_down") self.gui.get_object("toolpath_down").connect("clicked", self.toolpath_table_event, "move_down")
self.gui.get_object("toolpath_delete").connect("clicked", self.toolpath_table_event, "delete") self.gui.get_object("toolpath_delete").connect("clicked", self.toolpath_table_event, "delete")
self.gui.get_object("toolpath_simulate").connect("clicked", self.toolpath_table_event, "simulate")
self.gui.get_object("ExitSimulationButton").connect("clicked", self.hide_toolpath_simulation)
self.gui.get_object("UpdateSimulationButton").connect("clicked", self.update_toolpath_simulation)
# store the original content (for adding the number of current toolpaths in "update_toolpath_table") # store the original content (for adding the number of current toolpaths in "update_toolpath_table")
self._original_toolpath_tab_label = self.gui.get_object("ToolPathTabLabel").get_text() self._original_toolpath_tab_label = self.gui.get_object("ToolPathTabLabel").get_text()
# tool editor # tool editor
...@@ -1347,13 +1359,22 @@ class ProjectGui: ...@@ -1347,13 +1359,22 @@ class ProjectGui:
def destroy(self, widget=None, data=None): def destroy(self, widget=None, data=None):
self.update_view() self.update_view()
# check if there is a running process # check if there is a running process
# BEWARE: this is useless without threading - but we keep it for now
if self._progress_running: if self._progress_running:
self.cancel_progress() self.cancel_progress()
# wait steps
delay = 0.5
# timeout in seconds
timeout = 5
# wait until if is finished # wait until if is finished
while self._progress_running: while self._progress_running and (timeout > 0):
time.sleep(0.5) time.sleep(delay)
self.save_preferences() timeout -= delay
gtk.main_quit() gtk.main_quit()
self.quit()
def quit(self):
self.save_preferences()
def open(self, filename): def open(self, filename):
""" This function is used by the commandline handler """ """ This function is used by the commandline handler """
...@@ -1564,6 +1585,7 @@ class ProjectGui: ...@@ -1564,6 +1585,7 @@ class ProjectGui:
if action is None: if action is None:
action = data action = data
if action == "toggle_visibility": if action == "toggle_visibility":
# get the id of the currently selected toolpath
try: try:
path = int(data) path = int(data)
except ValueError: except ValueError:
...@@ -1572,6 +1594,10 @@ class ProjectGui: ...@@ -1572,6 +1594,10 @@ class ProjectGui:
self.toolpath[path].visible = not self.toolpath[path].visible self.toolpath[path].visible = not self.toolpath[path].visible
# hide/show toolpaths according to the new setting # hide/show toolpaths according to the new setting
self.update_view() self.update_view()
elif action == "simulate":
index = self._treeview_get_active_index(self.toolpath_table, self.toolpath)
if not index is None:
self.show_toolpath_simulation(self.toolpath[index])
self._treeview_button_event(self.toolpath_table, self.toolpath, action, self.update_toolpath_table) self._treeview_button_event(self.toolpath_table, self.toolpath, action, self.update_toolpath_table)
# do some post-processing ... # do some post-processing ...
if action == "delete": if action == "delete":
...@@ -1609,6 +1635,7 @@ class ProjectGui: ...@@ -1609,6 +1635,7 @@ class ProjectGui:
self.gui.get_object("toolpath_up").set_sensitive((not new_index is None) and (new_index > 0)) self.gui.get_object("toolpath_up").set_sensitive((not new_index is None) and (new_index > 0))
self.gui.get_object("toolpath_delete").set_sensitive(not new_index is None) self.gui.get_object("toolpath_delete").set_sensitive(not new_index is None)
self.gui.get_object("toolpath_down").set_sensitive((not new_index is None) and (new_index + 1 < len(self.toolpath))) self.gui.get_object("toolpath_down").set_sensitive((not new_index is None) and (new_index + 1 < len(self.toolpath)))
self.gui.get_object("toolpath_simulate").set_sensitive((not new_index is None) and (self.settings.get("enable_ode")))
@gui_activity_guard @gui_activity_guard
def save_task_settings_file(self, widget=None, filename=None): def save_task_settings_file(self, widget=None, filename=None):
...@@ -1702,6 +1729,78 @@ class ProjectGui: ...@@ -1702,6 +1729,78 @@ class ProjectGui:
def cancel_progress(self, widget=None): def cancel_progress(self, widget=None):
self._progress_cancel_requested = True self._progress_cancel_requested = True
def hide_toolpath_simulation(self, widget=None):
self.gui.get_object("SimulationWidget").hide()
self.task_pane.set_sensitive(True)
self.settings.set("simulate_object", None)
self.settings.set("show_simulation", False)
self.update_view()
@progress_activity_guard
def update_toolpath_simulation(self, widget=None, toolpath=None):
import pycam.Simulation.ODEBlocks
# get the currently selected toolpath, if none is give
if toolpath is None:
toolpath_index = self._treeview_get_active_index(self.toolpath_table, self.toolpath)
if toolpath_index is None:
return
else:
toolpath = self.toolpath[toolpath_index]
paths = toolpath.get_path()
# calculate steps
detail_level = self.gui.get_object("SimulationDetailsValue").get_value()
grid_size = 100 * pow(2, detail_level - 1)
proportion = (self.settings.get("maxx") - self.settings.get("minx")) \
/ (self.settings.get("maxy") - self.settings.get("miny"))
x_steps = int(math.sqrt(grid_size) * proportion)
y_steps = int(math.sqrt(grid_size) / proportion)
simulation_backend = pycam.Simulation.ODEBlocks.ODEBlocks(
toolpath.drill, toolpath.bounding_box,
x_steps=x_steps, y_steps=y_steps)
self.settings.set("simulation_object", simulation_backend)
# disable the simulation widget (avoids confusion regarding "cancel")
if not widget is None:
self.gui.get_object("SimulationWidget").set_sensitive(False)
# update the view
self.update_view()
# calculate the simulation and show it simulteneously
for path_index, path in enumerate(paths):
progress_text = "Simulating path %d/%d" % (path_index, len(paths))
progress_value_percent = 100.0 * path_index / len(paths)
self.update_progress_bar(progress_text, progress_value_percent)
for index in range(len(path.points)):
self.cutter.moveto(path.points[index])
if index != 0:
start = path.points[index - 1]
end = path.points[index]
if start != end:
simulation_backend.process_cutter_movement(start, end)
self.update_view()
# update the GUI
while gtk.events_pending():
gtk.main_iteration()
# break the loop if someone clicked the "cancel" button
if self._progress_cancel_requested:
break
if self._progress_cancel_requested:
break
# enable the simulation widget again (if we were started from the GUI)
if not widget is None:
self.gui.get_object("SimulationWidget").set_sensitive(True)
def show_toolpath_simulation(self, toolpath):
# disable the main controls
self.settings.set("show_simulation", True)
self.update_toolpath_simulation(toolpath=toolpath)
# disable the task pane _after_ the simulation - the progress bar
# decorator code would reset it otherwise
self.task_pane.set_sensitive(False)
# show the simulation controls
self.gui.get_object("SimulationWidget").show()
# hide the controls immediately, if the simulation was cancelled
if self._progress_cancel_requested:
self.hide_toolpath_simulation()
@progress_activity_guard @progress_activity_guard
def generate_toolpath(self, tool_settings, process_settings): def generate_toolpath(self, tool_settings, process_settings):
start_time = time.time() start_time = time.time()
...@@ -1812,6 +1911,9 @@ class ProjectGui: ...@@ -1812,6 +1911,9 @@ class ProjectGui:
description = "%s / %s" % (tool_settings["name"], process_settings["name"]) description = "%s / %s" % (tool_settings["name"], process_settings["name"])
# the tool id numbering should start with 1 instead of zero # the tool id numbering should start with 1 instead of zero
tool_id = self.tool_list.index(tool_settings) + 1 tool_id = self.tool_list.index(tool_settings) + 1
bounding_box = (self.settings.get("minx"), self.settings.get("maxx"),
self.settings.get("miny"), self.settings.get("maxy"),
self.settings.get("minz"), self.settings.get("maxz"))
self.toolpath.add_toolpath(toolpath, self.toolpath.add_toolpath(toolpath,
description, self.cutter, tool_id, description, self.cutter, tool_id,
tool_settings["speed"], tool_settings["speed"],
...@@ -1819,7 +1921,8 @@ class ProjectGui: ...@@ -1819,7 +1921,8 @@ class ProjectGui:
process_settings["material_allowance"], process_settings["material_allowance"],
process_settings["safety_height"], process_settings["safety_height"],
self.settings.get("unit"), self.settings.get("unit"),
minx, miny, maxz + start_offset) minx, miny, maxz + start_offset,
bounding_box)
self.update_toolpath_table() self.update_toolpath_table()
self.update_view() self.update_view()
# return "False" if the action was cancelled # return "False" if the action was cancelled
...@@ -1948,7 +2051,10 @@ class ProjectGui: ...@@ -1948,7 +2051,10 @@ class ProjectGui:
def mainloop(self): def mainloop(self):
# run the mainloop only if a GUI was requested # run the mainloop only if a GUI was requested
if not self.no_dialog: if not self.no_dialog:
gtk.main() try:
gtk.main()
except KeyboardInterrupt:
self.quit()
if __name__ == "__main__": if __name__ == "__main__":
gui = ProjectGui() gui = ProjectGui()
......
...@@ -1646,13 +1646,15 @@ This combination is added to the above task list.</property> ...@@ -1646,13 +1646,15 @@ This combination is added to the above task list.</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="spacing">2</property> <property name="spacing">2</property>
<child> <child>
<object class="GtkButton" id="toolpath_up"> <object class="GtkButton" id="toolpath_simulate">
<property name="label">gtk-go-up</property> <property name="label" translatable="yes">Simulation
(experimental)</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="use_stock">True</property> <property name="tooltip_text" translatable="yes">Show a simple simulation of the generated toolpath.
<property name="xalign">0</property> This feature requires the Open Dynamics Engine (ODE).</property>
<property name="image">ShowToolPathSimulation</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
...@@ -1673,6 +1675,20 @@ This combination is added to the above task list.</property> ...@@ -1673,6 +1675,20 @@ This combination is added to the above task list.</property>
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkButton" id="toolpath_up">
<property name="label">gtk-go-up</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
<child> <child>
<object class="GtkButton" id="toolpath_down"> <object class="GtkButton" id="toolpath_down">
<property name="label">gtk-go-down</property> <property name="label">gtk-go-down</property>
...@@ -1684,7 +1700,7 @@ This combination is added to the above task list.</property> ...@@ -1684,7 +1700,7 @@ This combination is added to the above task list.</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="position">2</property> <property name="position">3</property>
</packing> </packing>
</child> </child>
</object> </object>
...@@ -1731,13 +1747,132 @@ This combination is added to the above task list.</property> ...@@ -1731,13 +1747,132 @@ This combination is added to the above task list.</property>
<property name="position">0</property> <property name="position">0</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkFrame" id="SimulationWidget">
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment29">
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
<object class="GtkTable" id="SimulationWidgetTable">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<property name="column_spacing">4</property>
<property name="row_spacing">2</property>
<child>
<object class="GtkButton" id="UpdateSimulationButton">
<property name="label">gtk-refresh</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Run the simulation again</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkButton" id="ExitSimulationButton">
<property name="label">gtk-close</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Leave simulation mode</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox20">
<property name="visible">True</property>
<property name="spacing">2</property>
<child>
<object class="GtkLabel" id="SimulationDetailsControlLabel">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="xpad">5</property>
<property name="label" translatable="yes">Simulation detail level (1..10):</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="SimulationDetailsControl">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="max_length">6</property>
<property name="invisible_char">&#x25CF;</property>
<property name="adjustment">SimulationDetailsValue</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;Hint:&lt;/b&gt; take a look at the "show drill" and
"OpenGL: polygon" settings in preferences.
&lt;b&gt;Beware:&lt;/b&gt; the simulation feature is new and
experimental. Thus you will quite probably stumble
upon bugs and weird results.</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="SimulationWidgetFrameLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Simulation settings&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child> <child>
<object class="GtkProgressBar" id="MultipleProgressBar"> <object class="GtkProgressBar" id="MultipleProgressBar">
<property name="ellipsize">end</property> <property name="ellipsize">end</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="position">1</property> <property name="position">2</property>
</packing> </packing>
</child> </child>
<child> <child>
...@@ -1766,7 +1901,7 @@ This combination is added to the above task list.</property> ...@@ -1766,7 +1901,7 @@ This combination is added to the above task list.</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="position">2</property> <property name="position">3</property>
</packing> </packing>
</child> </child>
</object> </object>
...@@ -2456,7 +2591,7 @@ It is significantly faster, but the current release of ODE contains a nasty bug ...@@ -2456,7 +2591,7 @@ It is significantly faster, but the current release of ODE contains a nasty bug
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="ShowDrillProgressCheckBox"> <object class="GtkCheckButton" id="ShowDrillProgressCheckBox">
<property name="label" translatable="yes">Show Drill Progress</property> <property name="label" translatable="yes">Show Drill</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
...@@ -2505,7 +2640,7 @@ It is significantly faster, but the current release of ODE contains a nasty bug ...@@ -2505,7 +2640,7 @@ It is significantly faster, but the current release of ODE contains a nasty bug
<child> <child>
<object class="GtkTable" id="table4"> <object class="GtkTable" id="table4">
<property name="visible">True</property> <property name="visible">True</property>
<property name="n_rows">6</property> <property name="n_rows">7</property>
<property name="n_columns">2</property> <property name="n_columns">2</property>
<property name="column_spacing">23</property> <property name="column_spacing">23</property>
<child> <child>
...@@ -2678,6 +2813,36 @@ It is significantly faster, but the current release of ODE contains a nasty bug ...@@ -2678,6 +2813,36 @@ It is significantly faster, but the current release of ODE contains a nasty bug
<property name="y_options">GTK_FILL</property> <property name="y_options">GTK_FILL</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkLabel" id="ColorMaterialLabel">
<property name="visible">True</property>
<property name="tooltip_text" translatable="yes">The material is shown in "Simulation" mode.</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Material:</property>
</object>
<packing>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkColorButton" id="ColorMaterial">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="color">#000000000000</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</object> </object>
</child> </child>
</object> </object>
...@@ -4191,4 +4356,14 @@ ODE is required for this setting.</property> ...@@ -4191,4 +4356,14 @@ ODE is required for this setting.</property>
<property name="step_increment">1</property> <property name="step_increment">1</property>
<property name="page_increment">10</property> <property name="page_increment">10</property>
</object> </object>
<object class="GtkImage" id="ShowToolPathSimulation">
<property name="visible">True</property>
<property name="stock">gtk-execute</property>
</object>
<object class="GtkAdjustment" id="SimulationDetailsValue">
<property name="value">1</property>
<property name="lower">1</property>
<property name="upper">10</property>
<property name="step_increment">1</property>
</object>
</interface> </interface>
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