Commit 1d660506 authored by Keegi's avatar Keegi

Merge branch 'master' into experimental

parents 38cefcd0 1ce9f3a5
......@@ -42,8 +42,12 @@ in a terminal before running Pronterface
Alternatively, you can run python in 32 bit mode by setting the following environment variable before running the setup.py command:
This alternative approach is confirmed to work on Mac OS X 10.6.8.
`export VERSIONER_PYTHON_PREFER_32_BIT=yes`
`sudo python setup.py install`
Then repeat the same with http://launchpad.net/pyreadline/trunk/1.7/+download/pyreadline-1.7.zip
# USING PRONTERFACE
......
......@@ -58,12 +58,14 @@ class gviz(wx.Panel):
self.size=size
self.bedsize=bedsize
self.grid=grid
self.lastpos=[0,0,0,0,0]
self.lastpos=[0,0,0,0,0,0,0]
self.hilightpos=self.lastpos[:]
self.Bind(wx.EVT_PAINT,self.paint)
self.Bind(wx.EVT_SIZE,lambda *e:(wx.CallAfter(self.repaint),wx.CallAfter(self.Refresh)))
self.lines={}
self.pens={}
self.arcs={}
self.arcpens={}
self.layers=[]
self.layerindex=0
self.filament_width=extrusion_width # set it to 0 to disable scaling lines with zoom
......@@ -71,17 +73,19 @@ class gviz(wx.Panel):
penwidth = max(1.0,self.filament_width*((self.scale[0]+self.scale[1])/2.0))
self.translate=[0.0,0.0]
self.mainpen=wx.Pen(wx.Colour(0,0,0),penwidth)
self.arcpen=wx.Pen(wx.Colour(255,0,0),penwidth)
self.travelpen=wx.Pen(wx.Colour(10,80,80),penwidth)
self.hlpen=wx.Pen(wx.Colour(200,50,50),penwidth)
self.fades=[wx.Pen(wx.Colour(250-0.6**i*100,250-0.6**i*100,200-0.4**i*50),penwidth) for i in xrange(6)]
self.penslist=[self.mainpen,self.travelpen,self.hlpen]+self.fades
self.showall=0
self.hilight=[]
self.hilightarcs=[]
self.dirty=1
self.blitmap=wx.EmptyBitmap(self.GetClientSize()[0],self.GetClientSize()[1],-1)
def clear(self):
self.lastpos=[0,0,0,0,0]
self.lastpos=[0,0,0,0,0,0,0]
self.lines={}
self.pens={}
self.layers=[]
......@@ -143,27 +147,48 @@ class gviz(wx.Panel):
dc.SetBrush(wx.Brush((0,255,0)))
if len(self.layers):
dc.DrawRectangle(self.size[0]-14,(1.0-(1.0*(self.layerindex+1))/len(self.layers))*self.size[1],13,self.size[1]-1)
def scaler(x):
def _drawlines(lines,pens):
def _scaler(x):
return (self.scale[0]*x[0]+self.translate[0],
self.scale[1]*x[1]+self.translate[1],
self.scale[0]*x[2]+self.translate[0],
self.scale[1]*x[3]+self.translate[1],)
scaled_lines = map(_scaler,lines)
dc.DrawLineList(scaled_lines, pens)
def _drawarcs(arcs,pens):
def _scaler(x):
return (self.scale[0]*x[0]+self.translate[0],
self.scale[1]*x[1]+self.translate[1],
self.scale[0]*x[2]+self.translate[0],
self.scale[1]*x[3]+self.translate[1],
self.scale[0]*x[4]+self.translate[0],
self.scale[1]*x[5]+self.translate[1],)
scaled_arcs = map(_scaler,arcs)
for i in range(len(scaled_arcs)):
dc.SetPen(pens[i] if type(pens).__name__ == 'list' else pens)
dc.SetBrush(wx.TRANSPARENT_BRUSH)
dc.DrawArc(*scaled_arcs[i])
if self.showall:
l=[]
for i in self.layers:
dc.DrawLineList(l,self.fades[0])
l=map(scaler,self.lines[i])
dc.DrawLineList(l,self.pens[i])
_drawlines(self.lines[i], self.pens[i])
_drawarcs(self.arcs[i], self.arcpens[i])
return
if self.layerindex<len(self.layers) and self.layers[self.layerindex] in self.lines.keys():
for layer_i in xrange(max(0,self.layerindex-6),self.layerindex):
#print i, self.layerindex, self.layerindex-i
l=map(scaler,self.lines[self.layers[layer_i]])
dc.DrawLineList(l,self.fades[self.layerindex-layer_i-1])
l=map(scaler,self.lines[self.layers[self.layerindex]])
dc.DrawLineList(l,self.pens[self.layers[self.layerindex]])
l=map(scaler,self.hilight)
dc.DrawLineList(l,self.hlpen)
_drawlines(self.lines[self.layers[layer_i]], self.fades[self.layerindex-layer_i-1])
_drawarcs(self.arcs[self.layers[layer_i]], self.fades[self.layerindex-layer_i-1])
_drawlines(self.lines[self.layers[self.layerindex]], self.pens[self.layers[self.layerindex]])
_drawarcs(self.arcs[self.layers[self.layerindex]], self.arcpens[self.layers[self.layerindex]])
_drawlines(self.hilight, self.hlpen)
_drawarcs(self.hilightarcs, self.hlpen)
dc.SelectObject(wx.NullBitmap)
def paint(self,event):
......@@ -178,8 +203,11 @@ class gviz(wx.Panel):
def addgcode(self,gcode="M105",hilight=0):
gcode=gcode.split("*")[0]
gcode=gcode.split(";")[0]
if "g1" in gcode.lower():
gcode=gcode.lower().split()
gcode = gcode.lower().strip().split()
if len(gcode) == 0:
return
def _readgcode():
target=self.lastpos[:]
if hilight:
target=self.hilightpos[:]
......@@ -194,23 +222,53 @@ class gviz(wx.Panel):
target[3]=float(i[1:])
elif i[0]=="f":
target[4]=float(i[1:])
#draw line
elif i[0]=="i":
target[5]=float(i[1:])
elif i[0]=="j":
target[6]=float(i[1:])
if not hilight:
if not target[2] in self.lines.keys():
self.lines[target[2]]=[]
self.pens[target[2]]=[]
self.arcs[target[2]]=[]
self.arcpens[target[2]]=[]
self.layers+=[target[2]]
self.lines[target[2]]+=[(self.lastpos[0],self.bedsize[1]-self.lastpos[1],target[0],self.bedsize[1]-target[1])]
if target[3] != self.lastpos[3]:
self.pens[target[2]]+=[self.mainpen]
else:
self.pens[target[2]]+=[self.travelpen]
self.lastpos=target
return target
def _y(y):
return self.bedsize[1]-y
start_pos = self.hilightpos[:] if hilight else self.lastpos[:]
if gcode[0] == "g1":
target = _readgcode()
line = [ start_pos[0], _y(start_pos[1]), target[0], _y(target[1]) ]
if not hilight:
self.lines[ target[2] ] += [line]
self.pens[ target[2] ] += [self.mainpen if target[3] != self.lastpos[3] else self.travelpen]
self.lastpos = target
else:
self.hilight+=[(self.hilightpos[0],self.bedsize[1]-self.hilightpos[1],target[0],self.bedsize[1]-target[1])]
self.hilightpos=target
self.dirty=1
self.hilight += line
self.hilightpos = target
self.dirty = 1
if gcode[0] in [ "g2", "g3" ]:
target = _readgcode()
arc = []
arc += [ start_pos[0], _y(start_pos[1]) ]
arc += [ target[0], _y(target[1]) ]
arc += [ start_pos[0] + target[5], _y(start_pos[1] + target[6]) ] # center
if gcode[0] == "g2": # clockwise, reverse endpoints
arc[0], arc[1], arc[2], arc[3] = arc[2], arc[3], arc[0], arc[1]
if not hilight:
self.arcs[ target[2] ] += [arc]
self.arcpens[ target[2] ] += [self.arcpen]
self.lastpos = target
else:
self.hilightarcs += arc
self.hilightpos = target
self.dirty = 1
if __name__ == '__main__':
app = wx.App(False)
......
......@@ -17,7 +17,7 @@ msgstr ""
#: pronterface.py:10
msgid "WX is not installed. This program requires WX to run."
msgstr "wxWidgets n'est pas installé. Ce programme nécéssite la librairie wxWidgets pour fonctionner."
msgstr "wxWidgets n'est pas installé. Ce programme nécessite la librairie wxWidgets pour fonctionner."
#: pronterface.py:60
msgid "Printer Interface"
......@@ -221,11 +221,11 @@ msgstr " Ouvrir un fichier"
#: pronterface.py:278
msgid "&Edit..."
msgstr "&Editer..."
msgstr "&Éditer..."
#: pronterface.py:278
msgid " Edit open file"
msgstr " Editer le fichier ouvert"
msgstr " Éditer le fichier ouvert"
#: pronterface.py:279
msgid "E&xit"
......@@ -604,7 +604,7 @@ msgstr "Reprendre"
#: pronterface.py:1168
msgid "Are you sure you want to reset the printer?"
msgstr "Etes-vous sûrde vouloir réinitialiser l'imprimante?"
msgstr "Etes-vous sûr de vouloir réinitialiser l'imprimante?"
#: pronterface.py:1168
msgid "Reset?"
......
......@@ -2,6 +2,12 @@
import wx,time,random,threading,os,math
import stltool
def translate(l): return l
def rotate(l): return l
def import_stl(s): return s
class stlwrap:
def __init__(self,obj,name=None):
self.obj=obj
......@@ -16,12 +22,16 @@ class stlwrap:
class showstl(wx.Window):
def __init__(self,parent,size,pos):
wx.Window.__init__(self,parent,size=size,pos=pos)
self.l=wx.ListBox(self,size=(300,130),pos=(0,size[1]-130))
self.l=wx.ListBox(self,size=(300,180),pos=(0,size[1]-180))
self.cl=wx.Button(self,label="Clear",pos=(300,size[1]-180))
self.lb=wx.Button(self,label="Load",pos=(300,size[1]-155))
self.eb=wx.Button(self,label="Export",pos=(300,size[1]-130))
self.sb=wx.Button(self,label="Snap to Z=0",pos=(300,size[1]-105))
self.cb=wx.Button(self,label="Put at 100,100",pos=(300,size[1]-80))
self.db=wx.Button(self,label="Delete",pos=(300,size[1]-55))
self.ab=wx.Button(self,label="Auto",pos=(300,size[1]-30))
self.cl.Bind(wx.EVT_BUTTON,self.clear)
self.lb.Bind(wx.EVT_BUTTON,self.right)
self.eb.Bind(wx.EVT_BUTTON,self.export)
self.sb.Bind(wx.EVT_BUTTON,self.snap)
self.cb.Bind(wx.EVT_BUTTON,self.center)
......@@ -69,15 +79,20 @@ class showstl(wx.Window):
dlg.SetWildcard("STL files (;*.stl;)")
if(dlg.ShowModal() == wx.ID_OK):
name=dlg.GetPath()
sf=open(name.replace(".","_")+".scad","w")
facets=[]
for i in self.models.values():
r=i.rot
o=i.offsets
sf.write('translate([%s,%s,%s]) rotate([0,0,%s]) import_stl("%s");\n'%(str(o[0]),str(o[1]),str(o[2]),r,os.path.split(i.filename)[1]))
if r != 0:
i=i.rotate([0,0,-r])
if o != [0,0,0]:
i=i.translate([o[0],-o[1],o[2]])
facets+=i.facets
sf.close()
stltool.emitstl(name,facets,"plater_export")
print "wrote ",name
......@@ -120,10 +135,37 @@ class showstl(wx.Window):
self.Refresh()
def right(self,event):
dlg=wx.FileDialog(self,"Open file to print",self.basedir,style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
dlg.SetWildcard("STL files (;*.stl;)")
dlg=wx.FileDialog(self,"Pick file to load",self.basedir,style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
dlg.SetWildcard("STL files (;*.stl;)|*.stl|OpenSCAD files (;*.scad;)|*.scad")
if(dlg.ShowModal() == wx.ID_OK):
name=dlg.GetPath()
if (name.lower().endswith(".stl")):
self.load_stl(event,name)
elif (name.lower().endswith(".scad")):
self.load_scad(event,name)
def load_scad(self,event,name):
lf=open(name)
s=[i.replace("\n","").replace("\r","").replace(";","") for i in lf]
lf.close()
for i in s:
parts = i.split()
translate_list = eval(parts[0])
rotate_list = eval(parts[1])
stl_file = eval(parts[2])
newname=os.path.split(stl_file.lower())[1]
c=1
while newname in self.models:
newname=os.path.split(stl_file.lower())[1]
newname=newname+"(%d)"%c
c+=1
stl_path = os.path.join(os.path.split(name)[0:len(os.path.split(stl_file))-1])
stl_full_path = os.path.join(stl_path[0],str(stl_file))
self.load_stl_into_model(stl_full_path,stl_file,translate_list,rotate_list[2])
def load_stl(self,event,name):
if not(os.path.exists(name)):
return
path = os.path.split(name)[0]
......@@ -132,15 +174,21 @@ class showstl(wx.Window):
#print name
if name.lower().endswith(".stl"):
#Filter out the path, just show the STL filename.
self.load_stl_into_model(name,name)
self.Refresh()
#print time.time()-t
def load_stl_into_model(self,path,name,offset=[0,0,0],rotation=0):
newname=os.path.split(name.lower())[1]
c=1
while newname in self.models:
newname=os.path.split(name.lower())[1]
newname=newname+"(%d)"%c
c+=1
self.models[newname]=stltool.stl(name)
self.models[newname].offsets=[0,0,0]
self.models[newname].rot=0
self.models[newname]=stltool.stl(path)
self.models[newname].offsets=offset
self.models[newname].rot=rotation
self.models[newname].filename=name
minx,miny,minz,maxx,maxy,maxz=(10000,10000,10000,0,0,0)
for i in self.models[newname].facets:
for j in i[1]:
......@@ -187,8 +235,14 @@ class showstl(wx.Window):
self.l.Select(0)
self.l.Select(self.l.GetCount()-1)
def clear(self,event):
result = wx.MessageBox('Are you sure you want to clear the grid? All unsaved changes will be lost.', 'Clear the grid?',
wx.YES_NO | wx.ICON_QUESTION)
if (result == 2):
self.models={}
self.l.Clear()
self.Refresh()
#print time.time()-t
def move(self,event):
if event.ButtonUp(wx.MOUSE_BTN_LEFT):
......@@ -291,11 +345,11 @@ class showstl(wx.Window):
#s.export()
class stlwin(wx.Frame):
def __init__(self,size=(400,530)):
def __init__(self,size=(400,580)):
wx.Frame.__init__(self,None,title="Right-click to add a file",size=size)
self.SetIcon(wx.Icon("plater.ico",wx.BITMAP_TYPE_ICO))
self.SetClientSize(size)
self.s=showstl(self,(400,530),(0,0))
self.s=showstl(self,(400,580),(0,0))
if __name__ == '__main__':
app = wx.App(False)
......
......@@ -2,6 +2,7 @@
import cmd, printcore, sys
import glob, os, time
import sys, subprocess
from math import sqrt
if os.name=="nt":
try:
import _winreg
......@@ -80,6 +81,59 @@ def totalelength(g):
tot+=cur
return tot
def get_coordinate_value(axis, parts):
for i in parts:
if (axis in i):
return float(i[1:])
return None
def estimate_duration(g):
extra_cost_per_movement = 0.02
total_duration = 0
feedrate = 0
X_last_position = 0
Y_last_position = 0
for i in g:
if "G1" in i and ("X" in i or "Y" in i or "F" in i or "E" in i):
parts = i.split(" ")
X = get_coordinate_value("X", parts[1:])
Y = get_coordinate_value("Y", parts[1:])
F = get_coordinate_value("F", parts[1:])
E = get_coordinate_value("E", parts[1:])
if (F is not None):
feedrate = F / 60
distance = 0
if (X is None and Y is None and E is not None):
distance = abs(E)
elif (X is not None and Y is None):
distance = X - X_last_position
X_last_position = X
elif (X is None and Y is not None):
distance = Y - Y_last_position
Y_last_position = Y
elif (X is not None and Y is not None):
X_distance = X - X_last_position
Y_distance = Y - Y_last_position
distance = sqrt(X_distance * X_distance + Y_distance * Y_distance)
X_last_position = X
Y_last_position = Y
if (feedrate == 0 or distance == 0): continue
time_for_move = distance / feedrate
acceleration = feedrate / time_for_move
halfway_feedrate = acceleration * time_for_move / 2
duration = halfway_feedrate * 2 / acceleration
total_duration += duration + extra_cost_per_movement
mod_minutes = total_duration % (60 * 60)
mod_seconds = mod_minutes % 60
return "{0:02d}h{1:02d}m".format(int((total_duration - mod_minutes) / (60 * 60)), int((mod_minutes - mod_seconds) / 60))
class Settings:
#def _temperature_alias(self): return {"pla":210,"abs":230,"off":0}
......
......@@ -1179,7 +1179,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
time.sleep(0.1)
fn=self.filename
try:
self.filename=self.filename.replace(".stl","_export.gcode").replace(".STL","_export.gcode")
self.filename=self.filename.replace(".stl","_export.gcode").replace(".STL","_export.gcode").replace(".obj","_export.gcode").replace(".OBJ","_export.gcode")
of=open(self.filename)
self.f=[i.replace("\n","").replace("\r","") for i in of]
of.close
......@@ -1217,7 +1217,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
except:
pass
dlg=wx.FileDialog(self,_("Open file to print"),basedir,style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
dlg.SetWildcard(_("STL and GCODE files (;*.gcode;*.gco;*.g;*.stl;*.STL;)"))
dlg.SetWildcard(_("OBJ, STL, and GCODE files (;*.gcode;*.gco;*.g;*.stl;*.STL;*.obj;*.OBJ;)"))
if(filename is not None or dlg.ShowModal() == wx.ID_OK):
if filename is not None:
name=filename
......@@ -1231,6 +1231,8 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.set("last_file_path",path)
if name.lower().endswith(".stl"):
self.skein(name)
elif name.lower().endswith(".obj"):
self.skein(name)
else:
self.filename=name
of=open(self.filename)
......@@ -1250,6 +1252,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
print _("the print goes from"),Xmin,_("mm to"),Xmax,_("mm in X\nand is"),Xtot,_("mm wide\n")
print _("the print goes from"),Ymin,_("mm to"),Ymax,_("mm in Y\nand is"),Ytot,_("mm wide\n")
print _("the print goes from"),Zmin,_("mm to"),Zmax,_("mm in Z\nand is"),Ztot,_("mm high\n")
print _("Estimated duration (pessimistic): "), pronsole.estimate_duration(self.f)
self.gviz.clear()
self.gwindow.p.clear()
for i in self.f:
......
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