Commit a7c915bb authored by D1plo1d's avatar D1plo1d

Merge branch 'master' of github.com:kliment/Printrun

parents 182476ad d6f485a3
...@@ -549,7 +549,10 @@ class printcore(): ...@@ -549,7 +549,10 @@ class printcore():
if self.printer: if self.printer:
self.sent.append(command) self.sent.append(command)
# run the command through the analyzer # run the command through the analyzer
self.analyzer.Analyze(command) try: self.analyzer.Analyze(command)
except:
print "Warning: could not analyze command %s:" % command
traceback.print_exc(file = sys.stdout)
if self.loud: if self.loud:
print "SENT:", command print "SENT:", command
if self.sendcb: if self.sendcb:
......
...@@ -22,15 +22,23 @@ from . import gcoder ...@@ -22,15 +22,23 @@ from . import gcoder
from .gl.panel import wxGLPanel from .gl.panel import wxGLPanel
from .gl.trackball import build_rotmatrix from .gl.trackball import build_rotmatrix
from .gl.libtatlin import actors from .gl.libtatlin import actors
from .gl.libtatlin.actors import vec
from pyglet.gl import glPushMatrix, glPopMatrix, \ from pyglet.gl import glPushMatrix, glPopMatrix, \
glTranslatef, glRotatef, glScalef, glMultMatrixd glTranslatef, glRotatef, glScalef, glMultMatrixd
from pyglet.gl import *
from .gviz import GvizBaseFrame from .gviz import GvizBaseFrame
from printrun_utils import imagefile, install_locale from printrun_utils import imagefile, install_locale
install_locale('pronterface') install_locale('pronterface')
def create_model(light):
if light:
return actors.GcodeModelLight()
else:
return actors.GcodeModel()
class GcodeViewPanel(wxGLPanel): class GcodeViewPanel(wxGLPanel):
def __init__(self, parent, id = wx.ID_ANY, def __init__(self, parent, id = wx.ID_ANY,
...@@ -61,6 +69,8 @@ class GcodeViewPanel(wxGLPanel): ...@@ -61,6 +69,8 @@ class GcodeViewPanel(wxGLPanel):
for filename in self.parent.filenames: for filename in self.parent.filenames:
self.parent.load_file(filename) self.parent.load_file(filename)
self.parent.autoplate() self.parent.autoplate()
if hasattr(self.parent, "loadcb"):
self.parent.loadcb()
self.parent.filenames = None self.parent.filenames = None
def create_objects(self): def create_objects(self):
...@@ -78,10 +88,6 @@ class GcodeViewPanel(wxGLPanel): ...@@ -78,10 +88,6 @@ class GcodeViewPanel(wxGLPanel):
self.create_objects() self.create_objects()
glPushMatrix() glPushMatrix()
if self.orthographic:
glTranslatef(0, 0, -3 * self.dist) # Move back
else:
glTranslatef(0, 0, -self.dist) # Move back
# Rotate according to trackball # Rotate according to trackball
glMultMatrixd(build_rotmatrix(self.basequat)) glMultMatrixd(build_rotmatrix(self.basequat))
# Move origin to bottom left of platform # Move origin to bottom left of platform
...@@ -89,6 +95,14 @@ class GcodeViewPanel(wxGLPanel): ...@@ -89,6 +95,14 @@ class GcodeViewPanel(wxGLPanel):
platformy0 = -self.build_dimensions[4] - self.parent.platform.depth / 2 platformy0 = -self.build_dimensions[4] - self.parent.platform.depth / 2
glTranslatef(platformx0, platformy0, 0) glTranslatef(platformx0, platformy0, 0)
light_z = max(self.parent.platform.width, self.parent.platform.depth)
glLightfv(GL_LIGHT0, GL_POSITION, vec(0,
self.parent.platform.depth / 2,
light_z, 0))
glLightfv(GL_LIGHT1, GL_POSITION, vec(self.parent.platform.width,
self.parent.platform.depth / 2,
light_z, 0))
for obj in self.parent.objects: for obj in self.parent.objects:
if not obj.model \ if not obj.model \
or not obj.model.loaded \ or not obj.model.loaded \
...@@ -224,6 +238,7 @@ class GcodeViewPanel(wxGLPanel): ...@@ -224,6 +238,7 @@ class GcodeViewPanel(wxGLPanel):
if not self.parent.model or not self.parent.model.loaded: if not self.parent.model or not self.parent.model.loaded:
return return
self.parent.model.only_current = not self.parent.model.only_current self.parent.model.only_current = not self.parent.model.only_current
wx.CallAfter(self.Refresh)
if key in kreset: if key in kreset:
self.resetview() self.resetview()
event.Skip() event.Skip()
...@@ -246,7 +261,8 @@ class GCObject(object): ...@@ -246,7 +261,8 @@ class GCObject(object):
class GcodeViewMainWrapper(object): class GcodeViewMainWrapper(object):
def __init__(self, parent, build_dimensions): def __init__(self, parent, build_dimensions, root):
self.root = root
self.glpanel = GcodeViewPanel(parent, realparent = self, self.glpanel = GcodeViewPanel(parent, realparent = self,
build_dimensions = build_dimensions) build_dimensions = build_dimensions)
self.glpanel.SetMinSize((150, 150)) self.glpanel.SetMinSize((150, 150))
...@@ -262,7 +278,8 @@ class GcodeViewMainWrapper(object): ...@@ -262,7 +278,8 @@ class GcodeViewMainWrapper(object):
return getattr(self.glpanel, name) return getattr(self.glpanel, name)
def set_current_gline(self, gline): def set_current_gline(self, gline):
if gline.is_move and self.model and self.model.loaded: if gline.is_move and gline.gcview_end_vertex is not None \
and self.model and self.model.loaded:
self.model.printed_until = gline.gcview_end_vertex self.model.printed_until = gline.gcview_end_vertex
if not self.refresh_timer.IsRunning(): if not self.refresh_timer.IsRunning():
self.refresh_timer.Start() self.refresh_timer.Start()
...@@ -274,7 +291,8 @@ class GcodeViewMainWrapper(object): ...@@ -274,7 +291,8 @@ class GcodeViewMainWrapper(object):
pass pass
def addfile(self, gcode = None): def addfile(self, gcode = None):
self.model = actors.GcodeModel() self.model = create_model(self.root.settings.light3d
if self.root else False)
if gcode: if gcode:
self.model.load_data(gcode) self.model.load_data(gcode)
self.objects[-1].model = self.model self.objects[-1].model = self.model
...@@ -290,9 +308,10 @@ class GcodeViewFrame(GvizBaseFrame): ...@@ -290,9 +308,10 @@ class GcodeViewFrame(GvizBaseFrame):
def __init__(self, parent, ID, title, build_dimensions, objects = None, def __init__(self, parent, ID, title, build_dimensions, objects = None,
pos = wx.DefaultPosition, size = wx.DefaultSize, pos = wx.DefaultPosition, size = wx.DefaultSize,
style = wx.DEFAULT_FRAME_STYLE): style = wx.DEFAULT_FRAME_STYLE, root = None):
super(GcodeViewFrame, self).__init__(parent, ID, title, super(GcodeViewFrame, self).__init__(parent, ID, title,
pos, size, style) pos, size, style)
self.root = root
panel, vbox = self.create_base_ui() panel, vbox = self.create_base_ui()
...@@ -331,7 +350,8 @@ class GcodeViewFrame(GvizBaseFrame): ...@@ -331,7 +350,8 @@ class GcodeViewFrame(GvizBaseFrame):
wx.CallAfter(self.Refresh) wx.CallAfter(self.Refresh)
def set_current_gline(self, gline): def set_current_gline(self, gline):
if gline.is_move and self.model and self.model.loaded: if gline.is_move and gline.gcview_end_vertex is not None \
and self.model and self.model.loaded:
self.model.printed_until = gline.gcview_end_vertex self.model.printed_until = gline.gcview_end_vertex
if not self.refresh_timer.IsRunning(): if not self.refresh_timer.IsRunning():
self.refresh_timer.Start() self.refresh_timer.Start()
...@@ -340,7 +360,8 @@ class GcodeViewFrame(GvizBaseFrame): ...@@ -340,7 +360,8 @@ class GcodeViewFrame(GvizBaseFrame):
if self.clonefrom: if self.clonefrom:
self.model = self.clonefrom[-1].model.copy() self.model = self.clonefrom[-1].model.copy()
else: else:
self.model = actors.GcodeModel() self.model = create_model(self.root.settings.light3d
if self.root else False)
if gcode: if gcode:
self.model.load_data(gcode) self.model.load_data(gcode)
self.objects[-1].model = self.model self.objects[-1].model = self.model
......
...@@ -21,18 +21,24 @@ import numpy ...@@ -21,18 +21,24 @@ import numpy
import math import math
import logging import logging
from ctypes import sizeof
from pyglet.gl import glPushMatrix, glPopMatrix, glTranslatef, \ from pyglet.gl import glPushMatrix, glPopMatrix, glTranslatef, \
glGenLists, glNewList, GL_COMPILE, glEndList, glCallList, \ glGenLists, glNewList, GL_COMPILE, glEndList, glCallList, \
GL_ELEMENT_ARRAY_BUFFER, GL_UNSIGNED_INT, GL_TRIANGLES, \
GL_ARRAY_BUFFER, GL_STATIC_DRAW, glColor4f, glVertex3f, glRectf, \ GL_ARRAY_BUFFER, GL_STATIC_DRAW, glColor4f, glVertex3f, glRectf, \
glBegin, glEnd, GL_LINES, glEnable, glDisable, glGetFloatv, \ glBegin, glEnd, GL_LINES, glEnable, glDisable, glGetFloatv, \
GL_LINE_SMOOTH, glLineWidth, GL_LINE_WIDTH, GLfloat, GL_FLOAT, \ GL_LINE_SMOOTH, glLineWidth, GL_LINE_WIDTH, GLfloat, GL_FLOAT, GLuint, \
glVertexPointer, glColorPointer, glDrawArrays, \ glVertexPointer, glColorPointer, glDrawArrays, glDrawRangeElements, \
glEnableClientState, glDisableClientState, GL_VERTEX_ARRAY, GL_COLOR_ARRAY glEnableClientState, glDisableClientState, GL_VERTEX_ARRAY, GL_COLOR_ARRAY
from pyglet.graphics.vertexbuffer import create_buffer, VertexBufferObject from pyglet.graphics.vertexbuffer import create_buffer, VertexBufferObject
from printrun.printrun_utils import install_locale from printrun.printrun_utils import install_locale
install_locale('pronterface') install_locale('pronterface')
def vec(*args):
return (GLfloat * len(args))(*args)
def compile_display_list(func, *options): def compile_display_list(func, *options):
display_list = glGenLists(1) display_list = glGenLists(1)
glNewList(display_list, GL_COMPILE) glNewList(display_list, GL_COMPILE)
...@@ -46,6 +52,14 @@ def numpy2vbo(nparray, target = GL_ARRAY_BUFFER, usage = GL_STATIC_DRAW, use_vbo ...@@ -46,6 +52,14 @@ def numpy2vbo(nparray, target = GL_ARRAY_BUFFER, usage = GL_STATIC_DRAW, use_vbo
vbo.set_data(nparray.ctypes.data) vbo.set_data(nparray.ctypes.data)
return vbo return vbo
def triangulate_rectangle(i1, i2, i3, i4):
return [i1, i4, i3, i3, i2, i1]
def triangulate_box(i1, i2, i3, i4,
j1, j2, j3, j4):
return [i1, i2, j2, j2, j1, i1, i2, i3, j3, j3, j2, i2,
i3, i4, j4, j4, j3, i3, i4, i1, j1, j1, j4, i4]
class BoundingBox(object): class BoundingBox(object):
""" """
A rectangular box (cuboid) enclosing a 3D model, defined by lower and upper corners. A rectangular box (cuboid) enclosing a 3D model, defined by lower and upper corners.
...@@ -240,17 +254,30 @@ def movement_angle(src, dst, precision=0): ...@@ -240,17 +254,30 @@ def movement_angle(src, dst, precision=0):
angle = math.degrees(math.atan2(y, -x)) # negate x for clockwise rotation angle angle = math.degrees(math.atan2(y, -x)) # negate x for clockwise rotation angle
return round(angle, precision) return round(angle, precision)
def get_next_move(gcode, layer_idx, gline_idx):
gline_idx += 1
while layer_idx < len(gcode.all_layers):
layer = gcode.all_layers[layer_idx]
while gline_idx < len(layer):
gline = layer[gline_idx]
if gline.is_move:
return gline
gline_idx += 1
layer_idx += 1
gline_idx = 0
return None
class GcodeModel(Model): class GcodeModel(Model):
""" """
Model for displaying Gcode data. Model for displaying Gcode data.
""" """
color_travel = (0.6, 0.6, 0.6, 0.6) color_travel = (0.6, 0.6, 0.6, 0.6)
color_tool0 = (1.0, 0.0, 0.0, 0.6) color_tool0 = (1.0, 0.0, 0.0, 1.0)
color_tool1 = (0.31, 0.05, 0.9, 0.6) color_tool1 = (0.31, 0.05, 0.9, 1.0)
color_printed = (0.2, 0.75, 0, 0.6) color_printed = (0.2, 0.75, 0, 1.0)
color_current = (0, 0.9, 1.0, 0.8) color_current = (0, 0.9, 1.0, 1.0)
color_current_printed = (0.1, 0.4, 0, 0.8) color_current_printed = (0.1, 0.4, 0, 1.0)
use_vbos = True use_vbos = True
loaded = False loaded = False
...@@ -262,54 +289,152 @@ class GcodeModel(Model): ...@@ -262,54 +289,152 @@ class GcodeModel(Model):
(model_data.ymin, model_data.ymax, model_data.depth), (model_data.ymin, model_data.ymax, model_data.depth),
(model_data.zmin, model_data.zmax, model_data.height)) (model_data.zmin, model_data.zmax, model_data.height))
count_travel_indices = [0]
count_print_indices = [0]
count_print_vertices = [0]
travel_vertex_list = [] travel_vertex_list = []
max_travel_indices = []
max_print_indices = []
vertex_list = [] vertex_list = []
index_list = [] index_list = []
color_list = [] color_list = []
self.layer_stops = [0] self.layer_stops = [0]
num_layers = len(model_data.all_layers) num_layers = len(model_data.all_layers)
prev_is_extruding = False
prev_move_x = None
prev_move_y = None
prev_pos = (0, 0, 0) prev_pos = (0, 0, 0)
for layer_idx, layer in enumerate(model_data.all_layers): for layer_idx, layer in enumerate(model_data.all_layers):
for gline in layer: has_movement = False
for gline_idx, gline in enumerate(layer):
if not gline.is_move: if not gline.is_move:
continue continue
if gline.x is None and gline.y is None and gline.z is None:
continue
has_movement = True
current_pos = (gline.current_x, gline.current_y, gline.current_z) current_pos = (gline.current_x, gline.current_y, gline.current_z)
if not gline.extruding: if not gline.extruding:
travel_vertex_list.append(prev_pos) travel_vertex_list.extend(prev_pos)
travel_vertex_list.append(current_pos) travel_vertex_list.extend(current_pos)
prev_is_extruding = False
else: else:
gline_color = self.movement_color(gline) gline_color = self.movement_color(gline)
vertex_list.append(prev_pos) next_move = get_next_move(model_data, layer_idx, gline_idx)
vertex_list.append(current_pos) next_is_extruding = (next_move.extruding
if next_move is not None else False)
vertex_color = gline_color
color_list.append(vertex_color) delta_x = current_pos[0] - prev_pos[0]
delta_y = current_pos[1] - prev_pos[1]
norm = delta_x * delta_x + delta_y * delta_y
if norm == 0: # Don't draw anything if this move is Z+E only
continue
norm = math.sqrt(norm)
move_normal_x = - delta_y / norm
move_normal_y = delta_x / norm
path_halfwidth = 0.2
path_halfheight = 0.12
new_indices = []
new_vertices = []
if prev_is_extruding:
# Store previous vertices indices
prev_id = len(vertex_list) / 3 - 4
# Average directions
avg_move_x = delta_x + prev_move_x
avg_move_y = delta_y + prev_move_y
norm = avg_move_x * avg_move_x + avg_move_y * avg_move_y
# FIXME: handle norm == 0 or when paths go back (add an extra cap ?)
if norm == 0:
avg_move_normal_x = move_normal_x
avg_move_normal_y = move_normal_y
else:
norm = math.sqrt(norm)
avg_move_normal_x = - avg_move_y / norm
avg_move_normal_y = avg_move_x / norm
# Compute vertices
p1x = prev_pos[0] - path_halfwidth * avg_move_normal_x
p2x = prev_pos[0] + path_halfwidth * avg_move_normal_x
p1y = prev_pos[1] - path_halfwidth * avg_move_normal_y
p2y = prev_pos[1] + path_halfwidth * avg_move_normal_y
new_vertices.extend((p1x, p1y, prev_pos[2] + path_halfheight))
new_vertices.extend((p1x, p1y, prev_pos[2] - path_halfheight))
new_vertices.extend((p2x, p2y, prev_pos[2] - path_halfheight))
new_vertices.extend((p2x, p2y, prev_pos[2] + path_halfheight))
first = len(vertex_list) / 3
# Link to previous
new_indices += triangulate_box(prev_id, prev_id + 1,
prev_id + 2, prev_id + 3,
first, first + 1,
first + 2, first + 3)
else:
# Compute vertices normal to the current move and cap it
p1x = prev_pos[0] - path_halfwidth * move_normal_x
p2x = prev_pos[0] + path_halfwidth * move_normal_x
p1y = prev_pos[1] - path_halfwidth * move_normal_y
p2y = prev_pos[1] + path_halfwidth * move_normal_y
new_vertices.extend((p1x, p1y, prev_pos[2] + path_halfheight))
new_vertices.extend((p1x, p1y, prev_pos[2] - path_halfheight))
new_vertices.extend((p2x, p2y, prev_pos[2] - path_halfheight))
new_vertices.extend((p2x, p2y, prev_pos[2] + path_halfheight))
first = len(vertex_list) / 3
new_indices = triangulate_rectangle(first, first + 1,
first + 2, first + 3)
if not next_is_extruding:
# Compute caps and link everything
p1x = current_pos[0] - path_halfwidth * move_normal_x
p2x = current_pos[0] + path_halfwidth * move_normal_x
p1y = current_pos[1] - path_halfwidth * move_normal_y
p2y = current_pos[1] + path_halfwidth * move_normal_y
new_vertices.extend((p1x, p1y, current_pos[2] + path_halfheight))
new_vertices.extend((p1x, p1y, current_pos[2] - path_halfheight))
new_vertices.extend((p2x, p2y, current_pos[2] - path_halfheight))
new_vertices.extend((p2x, p2y, current_pos[2] + path_halfheight))
end_first = len(vertex_list) / 3 + len(new_vertices) / 3 - 4
new_indices += triangulate_rectangle(end_first + 3, end_first + 2,
end_first + 1, end_first)
new_indices += triangulate_box(first, first + 1,
first + 2, first + 3,
end_first, end_first + 1,
end_first + 2, end_first + 3)
index_list += new_indices
vertex_list += new_vertices
color_list += list(gline_color) * (len(new_vertices) / 3)
prev_is_extruding = True
prev_move_x = delta_x
prev_move_y = delta_y
prev_pos = current_pos prev_pos = current_pos
max_travel_indices.append(len(travel_vertex_list)) count_travel_indices.append(len(travel_vertex_list) / 3)
#max_print_indices.append(len(index_list)) count_print_indices.append(len(index_list))
max_print_indices.append(len(vertex_list)) count_print_vertices.append(len(vertex_list) / 3)
gline.gcview_end_vertex = len(max_print_indices) gline.gcview_end_vertex = len(count_print_indices) - 1
self.layer_stops.append(len(max_print_indices) - 1) if has_movement:
self.layer_stops.append(len(count_print_indices) - 1)
if callback: if callback:
callback(layer_idx + 1, num_layers) callback(layer_idx + 1, num_layers)
self.max_travel_indices = max_travel_indices self.count_travel_indices = count_travel_indices
self.max_print_indices = max_print_indices self.count_print_indices = count_print_indices
self.travels = numpy.array(travel_vertex_list, dtype = GLfloat) self.count_print_vertices = count_print_vertices
self.vertices = numpy.array(vertex_list, dtype = GLfloat) self.travels = numpy.fromiter(travel_vertex_list, dtype = GLfloat,
self.indices = numpy.array(index_list, dtype = GLfloat) count = len(travel_vertex_list))
self.colors = numpy.array(color_list, dtype = GLfloat).repeat(2, 0) self.vertices = numpy.fromiter(vertex_list, dtype = GLfloat,
count = len(vertex_list))
self.indices = numpy.fromiter(index_list, dtype = GLuint,
count = len(index_list))
self.colors = numpy.fromiter(color_list, dtype = GLfloat,
count = len(color_list))
self.max_layers = len(self.layer_stops) - 1 self.max_layers = len(self.layer_stops) - 1
self.num_layers_to_draw = self.max_layers self.num_layers_to_draw = self.max_layers + 1
self.printed_until = -1 self.printed_until = 0
self.only_current = False self.only_current = False
self.initialized = False self.initialized = False
self.loaded = True self.loaded = True
...@@ -317,7 +442,7 @@ class GcodeModel(Model): ...@@ -317,7 +442,7 @@ class GcodeModel(Model):
t_end = time.time() t_end = time.time()
logging.log(logging.INFO, _('Initialized 3D visualization in %.2f seconds') % (t_end - t_start)) logging.log(logging.INFO, _('Initialized 3D visualization in %.2f seconds') % (t_end - t_start))
logging.log(logging.INFO, _('Vertex count: %d') % (len(self.vertices) + len(self.travels))) logging.log(logging.INFO, _('Vertex count: %d') % ((len(self.vertices) + len(self.travels)) / 3))
def copy(self): def copy(self):
copy = GcodeModel() copy = GcodeModel()
...@@ -347,7 +472,8 @@ class GcodeModel(Model): ...@@ -347,7 +472,8 @@ class GcodeModel(Model):
def init(self): def init(self):
self.travel_buffer = numpy2vbo(self.travels, use_vbos = self.use_vbos) self.travel_buffer = numpy2vbo(self.travels, use_vbos = self.use_vbos)
self.index_buffer = numpy2vbo(self.indices, use_vbos = self.use_vbos) self.index_buffer = numpy2vbo(self.indices, use_vbos = self.use_vbos,
target = GL_ELEMENT_ARRAY_BUFFER)
self.vertex_buffer = numpy2vbo(self.vertices, use_vbos = self.use_vbos) self.vertex_buffer = numpy2vbo(self.vertices, use_vbos = self.use_vbos)
self.vertex_color_buffer = numpy2vbo(self.colors, use_vbos = self.use_vbos) # each pair of vertices shares the color self.vertex_color_buffer = numpy2vbo(self.colors, use_vbos = self.use_vbos) # each pair of vertices shares the color
self.initialized = True self.initialized = True
...@@ -356,14 +482,17 @@ class GcodeModel(Model): ...@@ -356,14 +482,17 @@ class GcodeModel(Model):
glPushMatrix() glPushMatrix()
glTranslatef(self.offset_x, self.offset_y, 0) glTranslatef(self.offset_x, self.offset_y, 0)
glEnableClientState(GL_VERTEX_ARRAY) glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_COLOR_ARRAY)
has_vbo = isinstance(self.vertex_buffer, VertexBufferObject) has_vbo = isinstance(self.vertex_buffer, VertexBufferObject)
self._display_travels(has_vbo) self._display_travels(has_vbo)
glEnableClientState(GL_COLOR_ARRAY)
self._display_movements(has_vbo) self._display_movements(has_vbo)
glDisableClientState(GL_COLOR_ARRAY) glDisableClientState(GL_COLOR_ARRAY)
glDisableClientState(GL_VERTEX_ARRAY) glDisableClientState(GL_VERTEX_ARRAY)
glPopMatrix() glPopMatrix()
def _display_travels(self, has_vbo): def _display_travels(self, has_vbo):
...@@ -373,20 +502,28 @@ class GcodeModel(Model): ...@@ -373,20 +502,28 @@ class GcodeModel(Model):
else: else:
glVertexPointer(3, GL_FLOAT, 0, self.travel_buffer.ptr) glVertexPointer(3, GL_FLOAT, 0, self.travel_buffer.ptr)
# TODO: show current layer travels in a different color
end = self.layer_stops[min(self.num_layers_to_draw, self.max_layers)] end = self.layer_stops[min(self.num_layers_to_draw, self.max_layers)]
glDisableClientState(GL_COLOR_ARRAY) end_index = self.count_travel_indices[end]
glColor4f(*self.color_travel) glColor4f(*self.color_travel)
if self.only_current: if self.only_current:
if self.num_layers_to_draw < self.max_layers: if self.num_layers_to_draw < self.max_layers:
end_prev_layer = self.layer_stops[self.num_layers_to_draw - 1] end_prev_layer = self.layer_stops[self.num_layers_to_draw - 1]
glDrawArrays(GL_LINES, self.max_travel_indices[end_prev_layer + 1], start_index = self.count_travel_indices[end_prev_layer + 1]
self.max_travel_indices[end] - self.max_travel_indices[end_prev_layer + 1]) glDrawArrays(GL_LINES, start_index, end_index - start_index + 1)
else: else:
glDrawArrays(GL_LINES, 0, self.max_travel_indices[end]) glDrawArrays(GL_LINES, 0, end_index)
glEnableClientState(GL_COLOR_ARRAY)
self.travel_buffer.unbind() self.travel_buffer.unbind()
def _draw_elements(self, start, end, draw_type = GL_TRIANGLES):
glDrawRangeElements(draw_type,
self.count_print_vertices[start - 1],
self.count_print_vertices[end] - 1,
self.count_print_indices[end] - self.count_print_indices[start - 1],
GL_UNSIGNED_INT,
sizeof(GLuint) * self.count_print_indices[start - 1])
def _display_movements(self, has_vbo): def _display_movements(self, has_vbo):
self.vertex_buffer.bind() self.vertex_buffer.bind()
if has_vbo: if has_vbo:
...@@ -400,6 +537,195 @@ class GcodeModel(Model): ...@@ -400,6 +537,195 @@ class GcodeModel(Model):
else: else:
glColorPointer(4, GL_FLOAT, 0, self.vertex_color_buffer.ptr) glColorPointer(4, GL_FLOAT, 0, self.vertex_color_buffer.ptr)
self.index_buffer.bind()
start = 1
layer_selected = self.num_layers_to_draw <= self.max_layers
if layer_selected:
end_prev_layer = self.layer_stops[self.num_layers_to_draw - 1]
else:
end_prev_layer = 0
end = self.layer_stops[min(self.num_layers_to_draw, self.max_layers)]
glDisableClientState(GL_COLOR_ARRAY)
glColor4f(*self.color_printed)
# Draw printed stuff until end or end_prev_layer
cur_end = min(self.printed_until, end)
if not self.only_current:
if 1 <= end_prev_layer <= cur_end:
self._draw_elements(1, end_prev_layer)
elif cur_end >= 1:
self._draw_elements(1, cur_end)
glEnableClientState(GL_COLOR_ARRAY)
# Draw nonprinted stuff until end_prev_layer
start = max(cur_end, 1)
if end_prev_layer >= start:
if not self.only_current:
self._draw_elements(start, end_prev_layer)
cur_end = end_prev_layer
# Draw current layer
if layer_selected:
glDisableClientState(GL_COLOR_ARRAY)
# Backup & increase line width
orig_linewidth = (GLfloat)()
glGetFloatv(GL_LINE_WIDTH, orig_linewidth)
glLineWidth(2.0)
glColor4f(*self.color_current_printed)
if cur_end > end_prev_layer:
self._draw_elements(end_prev_layer + 1, cur_end)
glColor4f(*self.color_current)
if end > cur_end:
self._draw_elements(cur_end + 1, end)
# Restore line width
glLineWidth(orig_linewidth)
glEnableClientState(GL_COLOR_ARRAY)
# Draw non printed stuff until end (if not ending at a given layer)
start = max(self.printed_until, 1)
if not layer_selected and end >= start:
self._draw_elements(start, end)
self.vertex_buffer.unbind()
self.vertex_color_buffer.unbind()
class GcodeModelLight(Model):
"""
Model for displaying Gcode data.
"""
color_travel = (0.6, 0.6, 0.6, 0.6)
color_tool0 = (1.0, 0.0, 0.0, 0.6)
color_tool1 = (0.31, 0.05, 0.9, 0.6)
color_printed = (0.2, 0.75, 0, 0.6)
color_current = (0, 0.9, 1.0, 0.8)
color_current_printed = (0.1, 0.4, 0, 0.8)
use_vbos = True
loaded = False
def load_data(self, model_data, callback=None):
t_start = time.time()
self.dims = ((model_data.xmin, model_data.xmax, model_data.width),
(model_data.ymin, model_data.ymax, model_data.depth),
(model_data.zmin, model_data.zmax, model_data.height))
vertex_list = []
color_list = []
self.layer_stops = [0]
num_layers = len(model_data.all_layers)
prev_pos = (0, 0, 0)
for layer_idx, layer in enumerate(model_data.all_layers):
has_movement = False
for gline in layer:
if not gline.is_move:
continue
if gline.x is None and gline.y is None and gline.z is None:
continue
has_movement = True
vertex_list.extend(prev_pos)
current_pos = (gline.current_x, gline.current_y, gline.current_z)
vertex_list.extend(current_pos)
vertex_color = self.movement_color(gline)
color_list.extend(vertex_color + vertex_color)
prev_pos = current_pos
gline.gcview_end_vertex = len(vertex_list) / 3
if has_movement:
self.layer_stops.append(len(vertex_list) / 3)
if callback:
callback(layer_idx + 1, num_layers)
self.vertices = numpy.fromiter(vertex_list, dtype = GLfloat,
count = len(vertex_list))
self.colors = numpy.fromiter(color_list, dtype = GLfloat,
count = len(color_list))
self.max_layers = len(self.layer_stops) - 1
self.num_layers_to_draw = self.max_layers + 1
self.printed_until = -1
self.only_current = False
self.initialized = False
self.loaded = True
t_end = time.time()
logging.log(logging.INFO, _('Initialized 3D visualization in %.2f seconds') % (t_end - t_start))
logging.log(logging.INFO, _('Vertex count: %d') % (len(self.vertices) / 3))
def copy(self):
copy = GcodeModelLight()
for var in ["vertices", "colors", "max_layers",
"num_layers_to_draw", "printed_until",
"layer_stops", "dims", "only_current"]:
setattr(copy, var, getattr(self, var))
copy.loaded = True
copy.initialized = False
return copy
def movement_color(self, move):
"""
Return the color to use for particular type of movement.
"""
if move.extruding:
if move.current_tool == 0:
return self.color_tool0
else:
return self.color_tool1
return self.color_travel
# ------------------------------------------------------------------------
# DRAWING
# ------------------------------------------------------------------------
def init(self):
self.vertex_buffer = numpy2vbo(self.vertices, use_vbos = self.use_vbos)
self.vertex_color_buffer = numpy2vbo(self.colors, use_vbos = self.use_vbos) # each pair of vertices shares the color
self.initialized = True
def display(self, mode_2d=False):
glPushMatrix()
glTranslatef(self.offset_x, self.offset_y, 0)
glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_COLOR_ARRAY)
self._display_movements(mode_2d)
glDisableClientState(GL_COLOR_ARRAY)
glDisableClientState(GL_VERTEX_ARRAY)
glPopMatrix()
def _display_movements(self, mode_2d=False):
self.vertex_buffer.bind()
has_vbo = isinstance(self.vertex_buffer, VertexBufferObject)
if has_vbo:
glVertexPointer(3, GL_FLOAT, 0, None)
else:
glVertexPointer(3, GL_FLOAT, 0, self.vertex_buffer.ptr)
self.vertex_color_buffer.bind()
if has_vbo:
glColorPointer(4, GL_FLOAT, 0, None)
else:
glColorPointer(4, GL_FLOAT, 0, self.vertex_color_buffer.ptr)
start = 0 start = 0
if self.num_layers_to_draw <= self.max_layers: if self.num_layers_to_draw <= self.max_layers:
end_prev_layer = self.layer_stops[self.num_layers_to_draw - 1] end_prev_layer = self.layer_stops[self.num_layers_to_draw - 1]
...@@ -415,11 +741,9 @@ class GcodeModel(Model): ...@@ -415,11 +741,9 @@ class GcodeModel(Model):
cur_end = min(self.printed_until, end) cur_end = min(self.printed_until, end)
if not self.only_current: if not self.only_current:
if 0 <= end_prev_layer <= cur_end: if 0 <= end_prev_layer <= cur_end:
glDrawArrays(GL_LINES, self.max_print_indices[start], glDrawArrays(GL_LINES, start, end_prev_layer)
self.max_print_indices[end_prev_layer])
elif cur_end >= 0: elif cur_end >= 0:
glDrawArrays(GL_LINES, self.max_print_indices[start], glDrawArrays(GL_LINES, start, cur_end)
self.max_print_indices[cur_end])
glEnableClientState(GL_COLOR_ARRAY) glEnableClientState(GL_COLOR_ARRAY)
...@@ -427,8 +751,7 @@ class GcodeModel(Model): ...@@ -427,8 +751,7 @@ class GcodeModel(Model):
start = max(cur_end, 0) start = max(cur_end, 0)
if end_prev_layer >= start: if end_prev_layer >= start:
if not self.only_current: if not self.only_current:
glDrawArrays(GL_LINES, self.max_print_indices[start], glDrawArrays(GL_LINES, start, end_prev_layer - start)
self.max_print_indices[end_prev_layer] - self.max_print_indices[start])
cur_end = end_prev_layer cur_end = end_prev_layer
# Draw current layer # Draw current layer
...@@ -443,14 +766,12 @@ class GcodeModel(Model): ...@@ -443,14 +766,12 @@ class GcodeModel(Model):
glColor4f(*self.color_current_printed) glColor4f(*self.color_current_printed)
if cur_end > end_prev_layer: if cur_end > end_prev_layer:
glDrawArrays(GL_LINES, self.max_print_indices[end_prev_layer + 1], glDrawArrays(GL_LINES, end_prev_layer, cur_end - end_prev_layer)
self.max_print_indices[cur_end] - self.max_print_indices[end_prev_layer])
glColor4f(*self.color_current) glColor4f(*self.color_current)
if end > cur_end: if end > cur_end:
glDrawArrays(GL_LINES, self.max_print_indices[cur_end], glDrawArrays(GL_LINES, cur_end, end - cur_end)
self.max_print_indices[end] - self.max_print_indices[cur_end])
# Restore line width # Restore line width
glLineWidth(orig_linewidth) glLineWidth(orig_linewidth)
...@@ -461,8 +782,7 @@ class GcodeModel(Model): ...@@ -461,8 +782,7 @@ class GcodeModel(Model):
start = max(self.printed_until, 0) start = max(self.printed_until, 0)
end = end - start end = end - start
if end_prev_layer < 0 and end > 0 and not self.only_current: if end_prev_layer < 0 and end > 0 and not self.only_current:
glDrawArrays(GL_LINES, self.max_print_indices[start], glDrawArrays(GL_LINES, start, end)
self.max_print_indices[end])
self.vertex_buffer.unbind() self.vertex_buffer.unbind()
self.vertex_color_buffer.unbind() self.vertex_color_buffer.unbind()
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>. # along with Printrun. If not, see <http://www.gnu.org/licenses/>.
from threading import Lock
import wx import wx
from wx import glcanvas from wx import glcanvas
...@@ -23,7 +25,7 @@ pyglet.options['debug_gl'] = True ...@@ -23,7 +25,7 @@ pyglet.options['debug_gl'] = True
from pyglet.gl import * from pyglet.gl import *
from pyglet import gl from pyglet import gl
from .trackball import trackball, mulquat from .trackball import trackball, mulquat, build_rotmatrix
class wxGLPanel(wx.Panel): class wxGLPanel(wx.Panel):
'''A simple class for using OpenGL with wxPython.''' '''A simple class for using OpenGL with wxPython.'''
...@@ -51,6 +53,10 @@ class wxGLPanel(wx.Panel): ...@@ -51,6 +53,10 @@ class wxGLPanel(wx.Panel):
self.sizer.Add(self.canvas, 1, wx.EXPAND) self.sizer.Add(self.canvas, 1, wx.EXPAND)
self.SetSizerAndFit(self.sizer) self.SetSizerAndFit(self.sizer)
self.rot_lock = Lock()
self.basequat = [0, 0, 0, 1]
self.zoom_factor = 1.0
# bind events # bind events
self.canvas.Bind(wx.EVT_ERASE_BACKGROUND, self.processEraseBackgroundEvent) self.canvas.Bind(wx.EVT_ERASE_BACKGROUND, self.processEraseBackgroundEvent)
self.canvas.Bind(wx.EVT_SIZE, self.processSizeEvent) self.canvas.Bind(wx.EVT_SIZE, self.processSizeEvent)
...@@ -119,9 +125,11 @@ class wxGLPanel(wx.Panel): ...@@ -119,9 +125,11 @@ class wxGLPanel(wx.Panel):
glMatrixMode(GL_PROJECTION) glMatrixMode(GL_PROJECTION)
glLoadIdentity() glLoadIdentity()
if self.orthographic: if self.orthographic:
glOrtho(-width / 2, width / 2, -height / 2, height / 2, 0.1, 5 * self.dist) glOrtho(-width / 2, width / 2, -height / 2, height / 2,
-5 * self.dist, 5 * self.dist)
else: else:
gluPerspective(60., float(width) / height, 10.0, 3 * self.dist) gluPerspective(60., float(width) / height, 10.0, 3 * self.dist)
glTranslatef(0, 0, -self.dist) # Move back
glMatrixMode(GL_MODELVIEW) glMatrixMode(GL_MODELVIEW)
if not self.mview_initialized: if not self.mview_initialized:
...@@ -142,6 +150,7 @@ class wxGLPanel(wx.Panel): ...@@ -142,6 +150,7 @@ class wxGLPanel(wx.Panel):
glLoadIdentity() glLoadIdentity()
if self.orthographic: if self.orthographic:
ratio = factor * float(min(self.width, self.height)) / self.dist ratio = factor * float(min(self.width, self.height)) / self.dist
self.zoom_factor = 1.0
glScalef(ratio, ratio, 1) glScalef(ratio, ratio, 1)
def OnDraw(self, *args, **kwargs): def OnDraw(self, *args, **kwargs):
...@@ -195,6 +204,7 @@ class wxGLPanel(wx.Panel): ...@@ -195,6 +204,7 @@ class wxGLPanel(wx.Panel):
delta_y = to[1] delta_y = to[1]
glTranslatef(delta_x, delta_y, 0) glTranslatef(delta_x, delta_y, 0)
glScalef(factor, factor, 1) glScalef(factor, factor, 1)
self.zoom_factor *= factor
if to: if to:
glTranslatef(-delta_x, -delta_y, 0) glTranslatef(-delta_x, -delta_y, 0)
wx.CallAfter(self.Refresh) wx.CallAfter(self.Refresh)
...@@ -216,7 +226,8 @@ class wxGLPanel(wx.Panel): ...@@ -216,7 +226,8 @@ class wxGLPanel(wx.Panel):
p2x = float(p2[0]) / (sz[0] / 2) - 1 p2x = float(p2[0]) / (sz[0] / 2) - 1
p2y = 1 - float(p2[1]) / (sz[1] / 2) p2y = 1 - float(p2[1]) / (sz[1] / 2)
quat = trackball(p1x, p1y, p2x, p2y, self.dist / 250.0) quat = trackball(p1x, p1y, p2x, p2y, self.dist / 250.0)
self.basequat = mulquat(self.basequat, quat) with self.rot_lock:
self.basequat = mulquat(self.basequat, quat)
self.initpos = p2 self.initpos = p2
def handle_translation(self, event): def handle_translation(self, event):
......
...@@ -44,8 +44,9 @@ def make_sized_button(*args): ...@@ -44,8 +44,9 @@ def make_sized_button(*args):
def make_autosize_button(*args): def make_autosize_button(*args):
return make_button(*args, size = (-1, buttonSize[1]), style = wx.BU_EXACTFIT) return make_button(*args, size = (-1, buttonSize[1]), style = wx.BU_EXACTFIT)
def make_custom_button(root, parentpanel, i): def make_custom_button(root, parentpanel, i, style = 0):
btn = make_button(parentpanel, i.label, root.procbutton, i.tooltip) btn = make_button(parentpanel, i.label, root.procbutton,
i.tooltip, style = style)
btn.SetBackgroundColour(i.background) btn.SetBackgroundColour(i.background)
btn.SetForegroundColour("black") btn.SetForegroundColour("black")
btn.properties = i btn.properties = i
...@@ -138,6 +139,32 @@ def add_extra_controls(self, root, parentpanel, extra_buttons = None): ...@@ -138,6 +139,32 @@ def add_extra_controls(self, root, parentpanel, extra_buttons = None):
if not extra_buttons: if not extra_buttons:
ebuttonspanel = root.newPanel(parentpanel) ebuttonspanel = root.newPanel(parentpanel)
ebuttonssizer = wx.BoxSizer(wx.HORIZONTAL) ebuttonssizer = wx.BoxSizer(wx.HORIZONTAL)
if root.settings.extruders > 1:
ebuttonssizer.Add(wx.StaticText(ebuttonspanel, -1, _("Tool:")), flag = wx.ALIGN_CENTER)
if root.settings.extruders == 2:
root.extrudersel = wx.Button(ebuttonspanel, -1, "0", style = wx.BU_EXACTFIT)
root.extrudersel.SetToolTip(wx.ToolTip(_("Click to switch current extruder")))
def extrudersel_cb(event):
if root.extrudersel.GetLabel() == "1":
new = "0"
else:
new = "1"
root.extrudersel.SetLabel(new)
root.tool_change(event)
root.extrudersel.Bind(wx.EVT_BUTTON, extrudersel_cb)
root.extrudersel.GetValue = root.extrudersel.GetLabel
root.extrudersel.SetValue = root.extrudersel.SetLabel
else:
choices = [str(i) for i in range(0, root.settings.extruders)]
root.extrudersel = wx.ComboBox(ebuttonspanel, -1, choices = choices,
style = wx.CB_DROPDOWN | wx.CB_READONLY,
size = (50, -1))
root.extrudersel.SetToolTip(wx.ToolTip(_("Select current extruder")))
root.extrudersel.SetValue(choices[0])
root.extrudersel.Bind(wx.EVT_COMBOBOX, root.tool_change)
root.printerControls.append(root.extrudersel)
ebuttonssizer.Add(root.extrudersel)
ebuttonspanel.SetSizer(ebuttonssizer) ebuttonspanel.SetSizer(ebuttonssizer)
self.Add(ebuttonspanel, pos = (base_line + 2, 0), span = (1, 5), flag = wx.EXPAND) self.Add(ebuttonspanel, pos = (base_line + 2, 0), span = (1, 5), flag = wx.EXPAND)
...@@ -210,7 +237,8 @@ def add_extra_controls(self, root, parentpanel, extra_buttons = None): ...@@ -210,7 +237,8 @@ def add_extra_controls(self, root, parentpanel, extra_buttons = None):
for i in root.cpbuttons: for i in root.cpbuttons:
if not i.pos or i.pos[0] != 4: if not i.pos or i.pos[0] != 4:
continue continue
btn = make_custom_button(root, ebuttonspanel, i) btn = make_custom_button(root, ebuttonspanel, i,
style = wx.BU_EXACTFIT)
ebuttonssizer.Add(btn, 1, flag = wx.EXPAND) ebuttonssizer.Add(btn, 1, flag = wx.EXPAND)
class LeftPane(wx.GridBagSizer): class LeftPane(wx.GridBagSizer):
...@@ -285,7 +313,7 @@ class VizPane(wx.BoxSizer): ...@@ -285,7 +313,7 @@ class VizPane(wx.BoxSizer):
if root.settings.mainviz == "3D": if root.settings.mainviz == "3D":
try: try:
import printrun.gcview import printrun.gcview
root.gviz = printrun.gcview.GcodeViewMainWrapper(parentpanel, root.build_dimensions_list) root.gviz = printrun.gcview.GcodeViewMainWrapper(parentpanel, root.build_dimensions_list, root = root)
root.gviz.clickcb = root.showwin root.gviz.clickcb = root.showwin
except: except:
use2dview = True use2dview = True
...@@ -308,7 +336,7 @@ class VizPane(wx.BoxSizer): ...@@ -308,7 +336,7 @@ class VizPane(wx.BoxSizer):
objects = None objects = None
if isinstance(root.gviz, printrun.gcview.GcodeViewMainWrapper): if isinstance(root.gviz, printrun.gcview.GcodeViewMainWrapper):
objects = root.gviz.objects objects = root.gviz.objects
root.gwindow = printrun.gcview.GcodeViewFrame(None, wx.ID_ANY, 'Gcode view, shift to move view, mousewheel to set layer', size = (600, 600), build_dimensions = root.build_dimensions_list, objects = objects) root.gwindow = printrun.gcview.GcodeViewFrame(None, wx.ID_ANY, 'Gcode view, shift to move view, mousewheel to set layer', size = (600, 600), build_dimensions = root.build_dimensions_list, objects = objects, root = root)
except: except:
use3dview = False use3dview = False
print "3D view mode requested, but we failed to initialize it." print "3D view mode requested, but we failed to initialize it."
......
...@@ -108,10 +108,6 @@ class StlViewPanel(wxGLPanel): ...@@ -108,10 +108,6 @@ class StlViewPanel(wxGLPanel):
glEnable(GL_LIGHT0) glEnable(GL_LIGHT0)
glEnable(GL_LIGHT1) glEnable(GL_LIGHT1)
# Define a simple function to create ctypes arrays of floats:
def vec(*args):
return (GLfloat * len(args))(*args)
glLightfv(GL_LIGHT0, GL_POSITION, vec(.5, .5, 1, 0)) glLightfv(GL_LIGHT0, GL_POSITION, vec(.5, .5, 1, 0))
glLightfv(GL_LIGHT0, GL_SPECULAR, vec(.5, .5, 1, 1)) glLightfv(GL_LIGHT0, GL_SPECULAR, vec(.5, .5, 1, 1))
glLightfv(GL_LIGHT0, GL_DIFFUSE, vec(1, 1, 1, 1)) glLightfv(GL_LIGHT0, GL_DIFFUSE, vec(1, 1, 1, 1))
...@@ -129,6 +125,8 @@ class StlViewPanel(wxGLPanel): ...@@ -129,6 +125,8 @@ class StlViewPanel(wxGLPanel):
for filename in self.parent.filenames: for filename in self.parent.filenames:
self.parent.load_file(filename) self.parent.load_file(filename)
self.parent.autoplate() self.parent.autoplate()
if hasattr(self.parent, "loadcb"):
self.parent.loadcb()
self.parent.filenames = None self.parent.filenames = None
def double(self, event): def double(self, event):
......
...@@ -1156,6 +1156,24 @@ class pronsole(cmd.Cmd): ...@@ -1156,6 +1156,24 @@ class pronsole(cmd.Cmd):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1] == " "): if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1] == " "):
return [i for i in self.bedtemps.keys() if i.startswith(text)] return [i for i in self.bedtemps.keys() if i.startswith(text)]
def do_tool(self, l):
tool = None
try:
tool = int(l.lower().strip())
except:
self.logError(_("You must specify the tool index as an integer."))
if tool is not None and tool >= 0:
if self.p.online:
self.p.send_now("T%d" % tool)
self.log(_("Using tool %d.") % tool)
else:
self.logError(_("Printer is not online."))
else:
self.logError(_("You cannot set negative tool numbers."))
def help_tool(self):
self.log(_("Switches to the specified tool (e.g. doing tool 1 will emit a T1 G-Code)."))
def do_move(self, l): def do_move(self, l):
if(len(l.split()) < 2): if(len(l.split()) < 2):
self.logError(_("No move specified.")) self.logError(_("No move specified."))
......
...@@ -196,6 +196,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -196,6 +196,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
monitorsetting = BooleanSetting("monitor", False) monitorsetting = BooleanSetting("monitor", False)
monitorsetting.hidden = True monitorsetting.hidden = True
self.settings._add(monitorsetting) self.settings._add(monitorsetting)
self.settings._add(SpinSetting("extruders", 0, 1, 5, _("Extruders count"), _("Number of extruders"), "Printer"))
self.settings._add(BuildDimensionsSetting("build_dimensions", "200x200x100+0+0+0+0+0+0", _("Build dimensions"), _("Dimensions of Build Platform\n & optional offset of origin\n & optional switch position\n\nExamples:\n XXXxYYY\n XXX,YYY,ZZZ\n XXXxYYYxZZZ+OffX+OffY+OffZ\nXXXxYYYxZZZ+OffX+OffY+OffZ+HomeX+HomeY+HomeZ"), "Printer")) self.settings._add(BuildDimensionsSetting("build_dimensions", "200x200x100+0+0+0+0+0+0", _("Build dimensions"), _("Dimensions of Build Platform\n & optional offset of origin\n & optional switch position\n\nExamples:\n XXXxYYY\n XXX,YYY,ZZZ\n XXXxYYYxZZZ+OffX+OffY+OffZ\nXXXxYYYxZZZ+OffX+OffY+OffZ+HomeX+HomeY+HomeZ"), "Printer"))
self.settings._add(BooleanSetting("clamp_jogging", False, _("Clamp manual moves"), _("Prevent manual moves from leaving the specified build dimensions"), "Printer")) self.settings._add(BooleanSetting("clamp_jogging", False, _("Clamp manual moves"), _("Prevent manual moves from leaving the specified build dimensions"), "Printer"))
self.settings._add(StringSetting("bgcolor", "#FFFFFF", _("Background color"), _("Pronterface background color"), "UI")) self.settings._add(StringSetting("bgcolor", "#FFFFFF", _("Background color"), _("Pronterface background color"), "UI"))
...@@ -203,6 +204,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -203,6 +204,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.settings._add(BooleanSetting("slic3rintegration", False, _("Enable Slic3r integration"), _("Add a menu to select Slic3r profiles directly from Pronterface"), "UI")) self.settings._add(BooleanSetting("slic3rintegration", False, _("Enable Slic3r integration"), _("Add a menu to select Slic3r profiles directly from Pronterface"), "UI"))
self.settings._add(ComboSetting("mainviz", "2D", ["2D", "3D", "None"], _("Main visualization"), _("Select visualization for main window."), "UI")) self.settings._add(ComboSetting("mainviz", "2D", ["2D", "3D", "None"], _("Main visualization"), _("Select visualization for main window."), "UI"))
self.settings._add(BooleanSetting("viz3d", False, _("Use 3D in GCode viewer window"), _("Use 3D mode instead of 2D layered mode in the visualization window"), "UI")) self.settings._add(BooleanSetting("viz3d", False, _("Use 3D in GCode viewer window"), _("Use 3D mode instead of 2D layered mode in the visualization window"), "UI"))
self.settings._add(BooleanSetting("light3d", True, _("Use a lighter 3D visualization"), _("Use a lighter visualization with simple lines instead of extruded paths for 3D viewer"), "UI"))
self.settings._add(BooleanSetting("tempgraph", True, _("Display temperature graph"), _("Display time-lapse temperature graph"), "UI")) self.settings._add(BooleanSetting("tempgraph", True, _("Display temperature graph"), _("Display time-lapse temperature graph"), "UI"))
self.settings._add(BooleanSetting("tempgauges", False, _("Display temperature gauges"), _("Display graphical gauges for temperatures visualization"), "UI")) self.settings._add(BooleanSetting("tempgauges", False, _("Display temperature gauges"), _("Display graphical gauges for temperatures visualization"), "UI"))
self.settings._add(BooleanSetting("lockbox", False, _("Display interface lock checkbox"), _("Display a checkbox that, when check, locks most of Pronterface"), "UI")) self.settings._add(BooleanSetting("lockbox", False, _("Display interface lock checkbox"), _("Display a checkbox that, when check, locks most of Pronterface"), "UI"))
...@@ -373,6 +375,9 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -373,6 +375,9 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.connectbtn.SetToolTip(wx.ToolTip("Disconnect from the printer")) self.connectbtn.SetToolTip(wx.ToolTip("Disconnect from the printer"))
self.connectbtn.Bind(wx.EVT_BUTTON, self.disconnect) self.connectbtn.Bind(wx.EVT_BUTTON, self.disconnect)
if hasattr(self, "extrudersel"):
self.do_tool(self.extrudersel.GetValue())
for i in self.printerControls: for i in self.printerControls:
i.Enable() i.Enable()
...@@ -406,13 +411,16 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -406,13 +411,16 @@ class PronterWindow(MainWindow, pronsole.pronsole):
temp = gline_s temp = gline_s
if self.display_gauges: wx.CallAfter(self.hottgauge.SetTarget, temp) if self.display_gauges: wx.CallAfter(self.hottgauge.SetTarget, temp)
if self.display_graph: wx.CallAfter(self.graph.SetExtruder0TargetTemperature, temp) if self.display_graph: wx.CallAfter(self.graph.SetExtruder0TargetTemperature, temp)
elif gline.command == "M140": elif gline.command in ["M140", "M190"]:
gline.parse_coordinates(gline, split_raw, imperial = False, force = True) gline.parse_coordinates(gline, split_raw, imperial = False, force = True)
gline_s = gcoder.S(gline) gline_s = gcoder.S(gline)
if gline_s is not None: if gline_s is not None:
temp = gline_s temp = gline_s
if self.display_gauges: wx.CallAfter(self.bedtgauge.SetTarget, temp) if self.display_gauges: wx.CallAfter(self.bedtgauge.SetTarget, temp)
if self.display_graph: wx.CallAfter(self.graph.SetBedTargetTemperature, temp) if self.display_graph: wx.CallAfter(self.graph.SetBedTargetTemperature, temp)
elif gline.command.startswith("T"):
tool = gline.command[1:]
if hasattr(self, "extrudersel"): wx.CallAfter(self.extrudersel.SetValue, tool)
else: else:
return return
self.sentlines.put_nowait(line) self.sentlines.put_nowait(line)
...@@ -840,6 +848,9 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -840,6 +848,9 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.do_bedtemp("") self.do_bedtemp("")
wx.CallAfter(self.btemp.SetInsertionPoint, 0) wx.CallAfter(self.btemp.SetInsertionPoint, 0)
def tool_change(self, event):
self.do_tool(self.extrudersel.GetValue())
def showwin(self, event): def showwin(self, event):
if self.fgcode: if self.fgcode:
self.gwindow.Show(True) self.gwindow.Show(True)
......
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