Projectlayer can present a zip file full of bmp files.

The projectlayer file dialog now accepts files with the extension
*.3dlp.zip and will extract the contents to a temporary folder. It then
finds any *.bmp files and adds them as a set of layers.

Notes:
- Offset works, but currently scale does not affect the bmp files.
- *.3dlp.zip was chosen to mark the file as being for dlp based
resin printers, but also processable by regular archive programs.
- Have also introduced a checkbox to let the user decide to display
  fullscreen or not, as they may want the window dragged to a second
  output.
master
Gary Hodgson 2012-05-27 13:10:35 +01:00
parent f3d7f95250
commit 0d009ac52b
7 changed files with 226 additions and 119 deletions

76
bmpDisplay.py Normal file
View File

@ -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()

View File

@ -15,40 +15,12 @@
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
class dispframe(wx.Frame):
def __init__(self, parent, title, res=(800, 600), printer=None):
@ -71,7 +43,7 @@ class dispframe(wx.Frame):
self.SetDoubleBuffered(True)
self.Show()
def drawlayer(self,svg):
def drawlayer(self, image):
try:
dc = wx.MemoryDC()
dc.SelectObject(self.bitmap)
@ -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:
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 == 'bmp':
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()
@ -112,7 +87,6 @@ class dispframe(wx.Frame):
self.p.send_now("G90")
def nextimg(self, event):
if self.index < len(self.layers):
i = self.index
@ -127,7 +101,6 @@ class dispframe(wx.Frame):
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)):
wx.CallAfter(self.pic.Hide)
wx.CallAfter(self.Refresh)
@ -135,7 +108,7 @@ class dispframe(wx.Frame):
self.scale = scale
self.thickness = thickness
self.index = 0
self.size=size
self.size = (size[0]+offset[0],size[1]+offset[1])
self.interval = interval
self.offset = offset
self.timer = wx.Timer(self, 1)
@ -183,28 +156,86 @@ class setframe(wx.Frame):
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.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!")
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 path.endswith(".bmp"):
ol.append(wx.Bitmap(path))
return ol, -1, "bmp"
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;)"))
dlg.SetWildcard(("Slic3r or Skeinforge svg files (;*.svg;*.SVG;);3DLP Zip (;*.3dlp.zip;)"))
if(dlg.ShowModal() == wx.ID_OK):
name = dlg.GetPath()
import os
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"
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]))
self.f.slicer = layers[2]
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]
dlg.Destroy()
def startdisplay(self, event):
self.f.Raise()
if (self.fullscreen.GetValue()):
self.f.ShowFullScreen(1)
l = self.layers[0][:]
self.f.present(l,

View File

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 141 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 775 KiB

After

Width:  |  Height:  |  Size: 775 KiB

View File

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
testfiles/out.3dlp.zip Normal file

Binary file not shown.