Merge pull request #228 from garyhodgson/experimental
Projectlayer processing a zip of bmp filesmaster
|
@ -0,0 +1,76 @@
|
|||
# create a simple image slide show using the
|
||||
# wx.PaintDC surface as a canvas and
|
||||
# DrawBitmap(bitmap, x, y, bool transparent)
|
||||
# Source: vegaseat
|
||||
|
||||
import wx
|
||||
import os
|
||||
import zipfile
|
||||
import tempfile
|
||||
import shutil
|
||||
|
||||
class MyFrame(wx.Frame):
|
||||
def __init__(self, parent, mysize):
|
||||
wx.Frame.__init__(self, parent, wx.ID_ANY, size=mysize)
|
||||
self.SetBackgroundColour('black')
|
||||
|
||||
# milliseconds per frame
|
||||
self.delay = 60
|
||||
# number of loops
|
||||
self.loops = 1
|
||||
|
||||
zipfilename = 'images/out.3dlp.zip'
|
||||
if not zipfile.is_zipfile(zipfilename):
|
||||
raise Exception(zipfilename + " is not a zip file!")
|
||||
zip = zipfile.ZipFile(zipfilename, 'r')
|
||||
self.mytmpdir = tempfile.mkdtemp()
|
||||
zip.extractall(self.mytmpdir)
|
||||
|
||||
image_type = ".bmp"
|
||||
image_dir = self.mytmpdir
|
||||
file_list = []
|
||||
self.name_list = []
|
||||
for file in os.listdir(image_dir):
|
||||
path = os.path.join(image_dir, file)
|
||||
if os.path.isfile(path) and path.endswith(image_type):
|
||||
# just the file name
|
||||
self.name_list.append(file)
|
||||
# full path name
|
||||
file_list.append(path)
|
||||
# create a list of image objects
|
||||
self.image_list = []
|
||||
for image_file in file_list:
|
||||
self.image_list.append(wx.Bitmap(image_file))
|
||||
|
||||
# bind the panel to the paint event
|
||||
wx.EVT_PAINT(self, self.onPaint)
|
||||
|
||||
def __del__(self):
|
||||
if self.mytmpdir:
|
||||
shutil.rmtree(self.mytmpdir)
|
||||
|
||||
def onPaint(self, event=None):
|
||||
# this is the wxPython drawing surface/canvas
|
||||
dc = wx.PaintDC(self)
|
||||
while self.loops:
|
||||
self.loops -= 1
|
||||
for ix, bmp in enumerate(self.image_list):
|
||||
# optionally show some image information
|
||||
w, h = bmp.GetSize()
|
||||
info = "%s %dx%d" % (self.name_list[ix], w, h)
|
||||
self.SetTitle(info)
|
||||
#self.SetSize((w,h))
|
||||
# draw the image
|
||||
dc.DrawBitmap(bmp, 0, 0, True)
|
||||
wx.MilliSleep(self.delay)
|
||||
# don't clear on fast slide shows to avoid flicker
|
||||
if self.delay > 200:
|
||||
dc.Clear()
|
||||
|
||||
|
||||
app = wx.App()
|
||||
width = 800
|
||||
frameoffset = 35
|
||||
height = 600 + frameoffset
|
||||
MyFrame(None, (width, height)).Show()
|
||||
app.MainLoop()
|
272
projectlayer.py
|
@ -15,50 +15,22 @@
|
|||
|
||||
import xml.etree.ElementTree
|
||||
import wx
|
||||
import os
|
||||
import zipfile
|
||||
import tempfile
|
||||
import shutil
|
||||
import svg.document as wxpsvgdocument
|
||||
|
||||
def parsesvg(name):
|
||||
et= xml.etree.ElementTree.ElementTree(file=name)
|
||||
#xml.etree.ElementTree.dump(et)
|
||||
slicer = 'Slic3r' if et.getroot().find('{http://www.w3.org/2000/svg}metadata') == None else 'Skeinforge'
|
||||
zlast=0
|
||||
zdiff=0
|
||||
ol=[]
|
||||
if (slicer == 'Slic3r'):
|
||||
height = et.getroot().get('height')
|
||||
width = et.getroot().get('width')
|
||||
|
||||
for i in et.findall("{http://www.w3.org/2000/svg}g"):
|
||||
z=float(i.get('{http://slic3r.org/namespaces/slic3r}z'))
|
||||
zdiff=z-zlast
|
||||
zlast=z
|
||||
|
||||
svgSnippet = xml.etree.ElementTree.Element('{http://www.w3.org/2000/svg}svg')
|
||||
svgSnippet.set('height', height+'mm')
|
||||
svgSnippet.set('width', width+'mm')
|
||||
svgSnippet.set('viewBox', '0 0 '+height+' '+width)
|
||||
svgSnippet.append(i)
|
||||
|
||||
ol+=[svgSnippet]
|
||||
else :
|
||||
for i in et.findall("{http://www.w3.org/2000/svg}g")[0].findall("{http://www.w3.org/2000/svg}g"):
|
||||
z=float(i.get('id').split("z:")[-1])
|
||||
zdiff=z-zlast
|
||||
zlast=z
|
||||
path=i.find('{http://www.w3.org/2000/svg}path')
|
||||
ol+=[(path.get("d").split("z"))[:-1]]
|
||||
return ol,zdiff,slicer
|
||||
import imghdr
|
||||
|
||||
|
||||
class dispframe(wx.Frame):
|
||||
def __init__(self, parent, title, res=(800,600),printer=None):
|
||||
def __init__(self, parent, title, res=(800, 600), printer=None):
|
||||
wx.Frame.__init__(self, parent=parent, title=title)
|
||||
self.p=printer
|
||||
self.pic=wx.StaticBitmap(self)
|
||||
self.bitmap=wx.EmptyBitmap(*res)
|
||||
self.bbitmap=wx.EmptyBitmap(*res)
|
||||
self.slicer='Skeinforge'
|
||||
dc=wx.MemoryDC()
|
||||
self.p = printer
|
||||
self.pic = wx.StaticBitmap(self)
|
||||
self.bitmap = wx.EmptyBitmap(*res)
|
||||
self.bbitmap = wx.EmptyBitmap(*res)
|
||||
self.slicer = 'Skeinforge'
|
||||
dc = wx.MemoryDC()
|
||||
dc.SelectObject(self.bbitmap)
|
||||
dc.SetBackground(wx.Brush("black"))
|
||||
dc.Clear()
|
||||
|
@ -66,14 +38,14 @@ class dispframe(wx.Frame):
|
|||
|
||||
self.SetBackgroundColour("black")
|
||||
self.pic.Hide()
|
||||
self.pen=wx.Pen("white")
|
||||
self.brush=wx.Brush("white")
|
||||
self.pen = wx.Pen("white")
|
||||
self.brush = wx.Brush("white")
|
||||
self.SetDoubleBuffered(True)
|
||||
self.Show()
|
||||
|
||||
def drawlayer(self,svg):
|
||||
def drawlayer(self, image):
|
||||
try:
|
||||
dc=wx.MemoryDC()
|
||||
dc = wx.MemoryDC()
|
||||
dc.SelectObject(self.bitmap)
|
||||
dc.SetBackground(wx.Brush("black"))
|
||||
dc.Clear()
|
||||
|
@ -81,16 +53,19 @@ class dispframe(wx.Frame):
|
|||
dc.SetBrush(self.brush)
|
||||
|
||||
if self.slicer == 'Skeinforge':
|
||||
for i in svg:
|
||||
for i in image:
|
||||
#print i
|
||||
points=[wx.Point(*map(lambda x:int(round(float(x)*self.scale)),j.strip().split())) for j in i.strip().split("M")[1].split("L")]
|
||||
dc.DrawPolygon(points,self.size[0]/2,self.size[1]/2)
|
||||
else:
|
||||
points = [wx.Point(*map(lambda x:int(round(float(x) * self.scale)), j.strip().split())) for j in i.strip().split("M")[1].split("L")]
|
||||
dc.DrawPolygon(points, self.size[0] / 2, self.size[1] / 2)
|
||||
elif self.slicer == 'Slic3r':
|
||||
gc = wx.GraphicsContext_Create(dc)
|
||||
gc.Translate(*self.offset)
|
||||
gc.Scale(self.scale, self.scale)
|
||||
wxpsvgdocument.SVGDocument(svg).render(gc)
|
||||
|
||||
wxpsvgdocument.SVGDocument(image).render(gc)
|
||||
elif self.slicer == 'bitmap':
|
||||
dc.DrawBitmap(image, self.offset[0], -self.offset[1], True)
|
||||
else:
|
||||
raise Exception(self.slicer + " is an unknown method.")
|
||||
self.pic.SetBitmap(self.bitmap)
|
||||
self.pic.Show()
|
||||
self.Refresh()
|
||||
|
@ -100,7 +75,7 @@ class dispframe(wx.Frame):
|
|||
raise
|
||||
pass
|
||||
|
||||
def showimgdelay(self,image):
|
||||
def showimgdelay(self, image):
|
||||
self.drawlayer(image)
|
||||
self.pic.Show()
|
||||
self.Refresh()
|
||||
|
@ -108,114 +83,171 @@ class dispframe(wx.Frame):
|
|||
self.Refresh()
|
||||
if self.p != None and self.p.online:
|
||||
self.p.send_now("G91")
|
||||
self.p.send_now("G1 Z%f F300"%(self.thickness,))
|
||||
self.p.send_now("G1 Z%f F300" % (self.thickness,))
|
||||
self.p.send_now("G90")
|
||||
|
||||
def nextimg(self,event):
|
||||
|
||||
if self.index<len(self.layers):
|
||||
i=self.index
|
||||
def nextimg(self, event):
|
||||
if self.index < len(self.layers):
|
||||
i = self.index
|
||||
|
||||
print i
|
||||
wx.CallAfter(self.showimgdelay,self.layers[i])
|
||||
wx.FutureCall(1000*self.interval,self.pic.Hide)
|
||||
self.index+=1
|
||||
wx.CallAfter(self.showimgdelay, self.layers[i])
|
||||
wx.FutureCall(1000 * self.interval, self.pic.Hide)
|
||||
self.index += 1
|
||||
else:
|
||||
print "end"
|
||||
wx.CallAfter(self.pic.Hide)
|
||||
wx.CallAfter(self.Refresh)
|
||||
wx.CallAfter(self.ShowFullScreen,0)
|
||||
wx.CallAfter(self.timer.Stop)
|
||||
|
||||
wx.CallAfter(self.ShowFullScreen, 0)
|
||||
wx.CallAfter(self.timer.Stop)
|
||||
|
||||
def present(self,layers,interval=0.5,pause=0.2,thickness=0.4,scale=20,size=(800,600),offset=(0,0)):
|
||||
def present(self, layers, interval=0.5, pause=0.2, thickness=0.4, scale=20, size=(800, 600), offset=(0, 0)):
|
||||
wx.CallAfter(self.pic.Hide)
|
||||
wx.CallAfter(self.Refresh)
|
||||
self.layers=layers
|
||||
self.scale=scale
|
||||
self.thickness=thickness
|
||||
self.index=0
|
||||
self.size=size
|
||||
self.interval=interval
|
||||
self.offset=offset
|
||||
self.timer=wx.Timer(self,1)
|
||||
self.timer.Bind(wx.EVT_TIMER,self.nextimg)
|
||||
self.Bind(wx.EVT_TIMER,self.nextimg)
|
||||
self.timer.Start(1000*interval+1000*pause)
|
||||
self.layers = layers
|
||||
self.scale = scale
|
||||
self.thickness = thickness
|
||||
self.index = 0
|
||||
self.size = (size[0] + offset[0], size[1] + offset[1])
|
||||
self.interval = interval
|
||||
self.offset = offset
|
||||
self.timer = wx.Timer(self, 1)
|
||||
self.timer.Bind(wx.EVT_TIMER, self.nextimg)
|
||||
self.Bind(wx.EVT_TIMER, self.nextimg)
|
||||
self.timer.Start(1000 * interval + 1000 * pause)
|
||||
|
||||
class setframe(wx.Frame):
|
||||
|
||||
def __init__(self,parent,printer=None):
|
||||
wx.Frame.__init__(self,parent,title="Projector setup")
|
||||
self.f=dispframe(None,"",printer=printer)
|
||||
self.panel=wx.Panel(self)
|
||||
def __init__(self, parent, printer=None):
|
||||
wx.Frame.__init__(self, parent, title="Projector setup")
|
||||
self.f = dispframe(None, "", printer=printer)
|
||||
self.panel = wx.Panel(self)
|
||||
self.panel.SetBackgroundColour("orange")
|
||||
self.bload=wx.Button(self.panel,-1,"Load",pos=(0,0))
|
||||
self.bload.Bind(wx.EVT_BUTTON,self.loadfile)
|
||||
self.bload = wx.Button(self.panel, -1, "Load", pos=(0, 0))
|
||||
self.bload.Bind(wx.EVT_BUTTON, self.loadfile)
|
||||
|
||||
wx.StaticText(self.panel,-1,"Layer:",pos=(0,30))
|
||||
wx.StaticText(self.panel,-1,"mm",pos=(130,30))
|
||||
self.thickness=wx.TextCtrl(self.panel,-1,"0.5",pos=(50,30))
|
||||
wx.StaticText(self.panel, -1, "Layer:", pos=(0, 30))
|
||||
wx.StaticText(self.panel, -1, "mm", pos=(130, 30))
|
||||
self.thickness = wx.TextCtrl(self.panel, -1, "0.5", pos=(50, 30))
|
||||
|
||||
wx.StaticText(self.panel,-1,"Exposure:",pos=(0,60))
|
||||
wx.StaticText(self.panel,-1,"s",pos=(130,60))
|
||||
self.interval=wx.TextCtrl(self.panel,-1,"0.5",pos=(50,60))
|
||||
wx.StaticText(self.panel, -1, "Exposure:", pos=(0, 60))
|
||||
wx.StaticText(self.panel, -1, "s", pos=(130, 60))
|
||||
self.interval = wx.TextCtrl(self.panel, -1, "0.5", pos=(50, 60))
|
||||
|
||||
wx.StaticText(self.panel,-1,"Blank:",pos=(0,90))
|
||||
wx.StaticText(self.panel,-1,"s",pos=(130,90))
|
||||
self.delay=wx.TextCtrl(self.panel,-1,"0.5",pos=(50,90))
|
||||
wx.StaticText(self.panel, -1, "Blank:", pos=(0, 90))
|
||||
wx.StaticText(self.panel, -1, "s", pos=(130, 90))
|
||||
self.delay = wx.TextCtrl(self.panel, -1, "0.5", pos=(50, 90))
|
||||
|
||||
wx.StaticText(self.panel,-1,"Scale:",pos=(0,120))
|
||||
wx.StaticText(self.panel,-1,"x",pos=(130,120))
|
||||
self.scale=wx.TextCtrl(self.panel,-1,"5",pos=(50,120))
|
||||
wx.StaticText(self.panel, -1, "Scale:", pos=(0, 120))
|
||||
wx.StaticText(self.panel, -1, "x", pos=(130, 120))
|
||||
self.scale = wx.TextCtrl(self.panel, -1, "5", pos=(50, 120))
|
||||
|
||||
wx.StaticText(self.panel,-1,"X:",pos=(160,30))
|
||||
self.X=wx.TextCtrl(self.panel,-1,"1024",pos=(210,30))
|
||||
wx.StaticText(self.panel, -1, "X:", pos=(160, 30))
|
||||
self.X = wx.TextCtrl(self.panel, -1, "1024", pos=(210, 30))
|
||||
|
||||
wx.StaticText(self.panel,-1,"Y:",pos=(160,60))
|
||||
self.Y=wx.TextCtrl(self.panel,-1,"768",pos=(210,60))
|
||||
wx.StaticText(self.panel, -1, "Y:", pos=(160, 60))
|
||||
self.Y = wx.TextCtrl(self.panel, -1, "768", pos=(210, 60))
|
||||
|
||||
wx.StaticText(self.panel,-1,"OffsetX:",pos=(160,90))
|
||||
self.offsetX=wx.TextCtrl(self.panel,-1,"50",pos=(210,90))
|
||||
wx.StaticText(self.panel, -1, "OffsetX:", pos=(160, 90))
|
||||
self.offsetX = wx.TextCtrl(self.panel, -1, "50", pos=(210, 90))
|
||||
|
||||
wx.StaticText(self.panel,-1,"OffsetY:",pos=(160,120))
|
||||
self.offsetY=wx.TextCtrl(self.panel,-1,"50",pos=(210,120))
|
||||
wx.StaticText(self.panel, -1, "OffsetY:", pos=(160, 120))
|
||||
self.offsetY = wx.TextCtrl(self.panel, -1, "50", pos=(210, 120))
|
||||
|
||||
self.bload = wx.Button(self.panel, -1, "Present", pos=(0, 150))
|
||||
self.bload.Bind(wx.EVT_BUTTON, self.startdisplay)
|
||||
|
||||
wx.StaticText(self.panel, -1, "Fullscreen:", pos=(160, 150))
|
||||
self.fullscreen = wx.CheckBox(self.panel, -1, pos=(220, 150))
|
||||
self.fullscreen.SetValue(True)
|
||||
|
||||
self.bload=wx.Button(self.panel,-1,"Present",pos=(0,150))
|
||||
self.bload.Bind(wx.EVT_BUTTON,self.startdisplay)
|
||||
self.Show()
|
||||
|
||||
def __del__(self):
|
||||
if hasattr(self, 'image_dir') and self.image_dir != '':
|
||||
shutil.rmtree(self.image_dir)
|
||||
|
||||
def parsesvg(self, name):
|
||||
et = xml.etree.ElementTree.ElementTree(file=name)
|
||||
#xml.etree.ElementTree.dump(et)
|
||||
slicer = 'Slic3r' if et.getroot().find('{http://www.w3.org/2000/svg}metadata') == None else 'Skeinforge'
|
||||
zlast = 0
|
||||
zdiff = 0
|
||||
ol = []
|
||||
if (slicer == 'Slic3r'):
|
||||
height = et.getroot().get('height')
|
||||
width = et.getroot().get('width')
|
||||
|
||||
for i in et.findall("{http://www.w3.org/2000/svg}g"):
|
||||
z = float(i.get('{http://slic3r.org/namespaces/slic3r}z'))
|
||||
zdiff = z - zlast
|
||||
zlast = z
|
||||
|
||||
svgSnippet = xml.etree.ElementTree.Element('{http://www.w3.org/2000/svg}svg')
|
||||
svgSnippet.set('height', height + 'mm')
|
||||
svgSnippet.set('width', width + 'mm')
|
||||
svgSnippet.set('viewBox', '0 0 ' + height + ' ' + width)
|
||||
svgSnippet.append(i)
|
||||
|
||||
ol += [svgSnippet]
|
||||
else :
|
||||
for i in et.findall("{http://www.w3.org/2000/svg}g")[0].findall("{http://www.w3.org/2000/svg}g"):
|
||||
z = float(i.get('id').split("z:")[-1])
|
||||
zdiff = z - zlast
|
||||
zlast = z
|
||||
path = i.find('{http://www.w3.org/2000/svg}path')
|
||||
ol += [(path.get("d").split("z"))[:-1]]
|
||||
return ol, zdiff, slicer
|
||||
|
||||
def parse3DLPzip(self, name):
|
||||
if not zipfile.is_zipfile(name):
|
||||
raise Exception(name + " is not a zip file!")
|
||||
acceptedImageTypes = ['gif','tiff','jpg','jpeg','bmp','png']
|
||||
zipFile = zipfile.ZipFile(name, 'r')
|
||||
self.image_dir = tempfile.mkdtemp()
|
||||
zipFile.extractall(self.image_dir)
|
||||
ol = []
|
||||
for f in os.listdir(self.image_dir):
|
||||
path = os.path.join(self.image_dir, f)
|
||||
if os.path.isfile(path) and imghdr.what(path) in acceptedImageTypes:
|
||||
ol.append(wx.Bitmap(path))
|
||||
return ol, -1, "bitmap"
|
||||
|
||||
def loadfile(self,event):
|
||||
dlg=wx.FileDialog(self,("Open file to print"),style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
|
||||
dlg.SetWildcard(("Slic3r or Skeinforge svg files (;*.svg;*.SVG;)"))
|
||||
def loadfile(self, event):
|
||||
dlg = wx.FileDialog(self, ("Open file to print"), style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
|
||||
dlg.SetWildcard(("Slic3r or Skeinforge svg files (;*.svg;*.SVG;);3DLP Zip (;*.3dlp.zip;)"))
|
||||
if(dlg.ShowModal() == wx.ID_OK):
|
||||
name=dlg.GetPath()
|
||||
import os
|
||||
name = dlg.GetPath()
|
||||
if not(os.path.exists(name)):
|
||||
self.status.SetStatusText(("File not found!"))
|
||||
return
|
||||
layers=parsesvg(name)
|
||||
print "Layer thickness detected:",layers[1], "mm"
|
||||
print len(layers[0]), "layers found, total height", layers[1]*len(layers[0]), "mm"
|
||||
self.thickness.SetValue(str(layers[1]))
|
||||
if name.endswith(".3dlp.zip"):
|
||||
layers = self.parse3DLPzip(name)
|
||||
layerHeight = float(self.thickness.GetValue())
|
||||
else:
|
||||
layers = self.parsesvg(name)
|
||||
layerHeight = layers[1]
|
||||
self.thickness.SetValue(str(layers[1]))
|
||||
print "Layer thickness detected:", layerHeight, "mm"
|
||||
print len(layers[0]), "layers found, total height", layerHeight * len(layers[0]), "mm"
|
||||
self.layers = layers
|
||||
self.f.slicer = layers[2]
|
||||
self.layers=layers
|
||||
dlg.Destroy()
|
||||
|
||||
def startdisplay(self,event):
|
||||
def startdisplay(self, event):
|
||||
self.f.Raise()
|
||||
self.f.ShowFullScreen(1)
|
||||
l=self.layers[0][:]
|
||||
if (self.fullscreen.GetValue()):
|
||||
self.f.ShowFullScreen(1)
|
||||
l = self.layers[0][:]
|
||||
self.f.present(l,
|
||||
thickness=float(self.thickness.GetValue()),
|
||||
interval=float(self.interval.GetValue()),
|
||||
scale=float(self.scale.GetValue()),
|
||||
pause=float(self.delay.GetValue()),
|
||||
size=(float(self.X.GetValue()),float(self.Y.GetValue())),
|
||||
offset=(float(self.offsetX.GetValue()),float(self.offsetY.GetValue())))
|
||||
pause=float(self.delay.GetValue()),
|
||||
size=(float(self.X.GetValue()), float(self.Y.GetValue())),
|
||||
offset=(float(self.offsetX.GetValue()), float(self.offsetY.GetValue())))
|
||||
|
||||
if __name__=="__main__":
|
||||
a=wx.App()
|
||||
if __name__ == "__main__":
|
||||
a = wx.App()
|
||||
setframe(None).Show()
|
||||
a.MainLoop()
|
||||
|
|
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 141 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 775 KiB After Width: | Height: | Size: 775 KiB |
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |