Commit ae104d53 authored by kliment's avatar kliment

Plate generation tool and basic STL library

parent c93ecbf9
import wx,time,random,threading,os,math
import stltool
class stlwrap:
def __init__(self,obj,name=None):
self.obj=obj
self.name=name
if name is None:
self.name=obj.name
def __repr__(self):
return self.name
class showstl(wx.Frame):
def __init__(self,parent,size,pos):
wx.Window.__init__(self,parent,size=size,pos=pos)
self.l=wx.ListCtrl(self,size=(300,100),pos=(0,size[1]-100))
#self.SetBackgroundColour((0,0,0))
wx.FutureCall(200,self.paint)
self.i=0
self.previ=0
self.Bind(wx.EVT_MOUSEWHEEL,self.rot)
self.Bind(wx.EVT_MOUSE_EVENTS,self.move)
self.Bind(wx.EVT_PAINT,self.repaint)
#self.s=stltool.stl("sphere.stl").scale([2,1,1])
self.triggered=0
self.models={}
self.basedir="."
self.initpos=None
self.prevsel=-1
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;)")
if(dlg.ShowModal() == wx.ID_OK):
name=dlg.GetPath()
if not(os.path.exists(name)):
return
path = os.path.split(name)[0]
self.basedir=path
if name.lower().endswith(".stl"):
self.models[name]=stltool.stl(name)
self.l.Append([stlwrap(self.models[name],name)])
self.Refresh()
def move(self,event):
if event.ButtonUp(wx.MOUSE_BTN_LEFT):
if(self.initpos is not None):
i=self.l.GetFirstSelected()
if i != -1:
p=event.GetPositionTuple()
#print (p[0]-self.initpos[0]),(p[1]-self.initpos[1])
self.models[self.l.GetItemText(i)]=self.models[self.l.GetItemText(i)].translate([0.5*(p[0]-self.initpos[0]),0.5*(p[1]-self.initpos[1]),0])
self.Refresh()
self.initpos=None
elif event.ButtonDown(wx.MOUSE_BTN_RIGHT):
self.right(event)
elif event.Dragging():
if self.initpos is None:
self.initpos=event.GetPositionTuple()
self.Refresh()
dc=wx.ClientDC(self)
p=event.GetPositionTuple()
dc.DrawLine(self.initpos[0],self.initpos[1],p[0],p[1])
#print math.sqrt((p[0]-self.initpos[0])**2+(p[1]-self.initpos[1])**2)
del dc
else:
event.Skip()
def cr(self):
time.sleep(0.1)
if(self.i!=self.previ):
i=self.l.GetFirstSelected()
if i != -1:
self.models[self.l.GetItemText(i)]=self.models[self.l.GetItemText(i)].rotate([0,0,self.i-self.previ])
self.previ=self.i
wx.CallAfter(self.Refresh)
self.triggered=0
def rot(self, event):
z=event.GetWheelRotation()
s=self.l.GetFirstSelected()
if self.prevsel!=s:
self.i=0
print "reset"
self.prevsel=s
if z > 0:
self.i-=1
else:
self.i+=1
if not self.triggered:
self.triggered=1
threading.Thread(target=self.cr).start()
def repaint(self,event):
dc=wx.PaintDC(self)
self.paint(dc=dc)
def paint(self,coord1="x",coord2="y",dc=None):
coords={"x":0,"y":1,"z":2}
#s=stltool.stl("20cube.stl")
#print s.facets[0]
#s=self.s
#print self.i
#print s.facets[0]
if dc is None:
dc=wx.ClientDC(self)
#self.facet=[normal,[[0,0,0],[0,0,0],[0,0,0]]]
offset=200
scale=2
for m in self.models.values():
for i in random.sample(m.facets,min(1000,len(m.facets))):
dc.DrawLine(offset+scale*i[1][0][coords[coord1]],offset+scale*i[1][0][coords[coord2]],offset+scale*i[1][1][coords[coord1]],offset+scale*i[1][1][coords[coord2]])
dc.DrawLine(offset+scale*i[1][2][coords[coord1]],offset+scale*i[1][2][coords[coord2]],offset+scale*i[1][1][coords[coord1]],offset+scale*i[1][1][coords[coord2]])
dc.DrawLine(offset+scale*i[1][0][coords[coord1]],offset+scale*i[1][0][coords[coord2]],offset+scale*i[1][2][coords[coord1]],offset+scale*i[1][2][coords[coord2]])
del dc
#s.export()
class stlwin(wx.Frame):
def __init__(self,size=(500,600)):
wx.Frame.__init__(self,None,size=size)
self.s=showstl(self,(500,600),(100,100))
if __name__ == '__main__':
app = wx.App(False)
main = stlwin()
main.Show()
app.MainLoop()
import sys
I=[
[1,0,0,0],
[0,1,0,0],
[0,0,1,0],
[0,0,0,1]
]
def transpose(matrix):
return [[v[i] for v in matrix] for i in xrange(len(matrix[0]))]
def multmatrix(vector,matrix):
return map(sum, transpose(map(lambda x:[x[0]*p for p in x[1]], zip(vector, transpose(matrix)))))
def applymatrix(facet,matrix=I):
return [multmatrix(facet[0]+[1],matrix)[:3],map(lambda x:multmatrix(x+[1],matrix)[:3],facet[1])]
f=[[0,0,0],[[-3.022642, 0.642482, -9.510565],[-3.022642, 0.642482, -9.510565],[-3.022642, 0.642482, -9.510565]]]
m=[
[1,0,0,0],
[0,1,0,0],
[0,0,1,1],
[0,0,0,1]
]
class stl:
def __init__(self, filename=None):
self.facet=[[0,0,0],[[0,0,0],[0,0,0],[0,0,0]]]
self.facets=[]
self.facetsminz=[]
self.facetsmaxz=[]
self.name=""
self.insolid=0
self.infacet=0
self.inloop=0
self.facetloc=0
if filename is None:
return
self.f=list(open(filename))
if not self.f[0].startswith("solid"):
print "Not an ascii stl solid"
return
for i in self.f:
if not self.parseline(i):
return
def translate(self,v=[0,0,0]):
matrix=[
[1,0,0,v[0]],
[0,1,0,v[1]],
[0,0,1,v[2]],
[0,0,0,1]
]
return self.transform(matrix)
def rotate(self,v=[0,0,0]):
import math
z=v[2]
matrix1=[
[math.cos(math.radians(z)),-math.sin(math.radians(z)),0,0],
[math.sin(math.radians(z)),math.cos(math.radians(z)),0,0],
[0,0,1,0],
[0,0,0,1]
]
y=v[0]
matrix2=[
[1,0,0,0],
[0,math.cos(math.radians(y)),-math.sin(math.radians(y)),0],
[0,math.sin(math.radians(y)),math.cos(math.radians(y)),0],
[0,0,0,1]
]
x=v[1]
matrix3=[
[math.cos(math.radians(x)),0,-math.sin(math.radians(x)),0],
[0,1,0,0],
[math.sin(math.radians(x)),0,math.cos(math.radians(x)),0],
[0,0,0,1]
]
return self.transform(matrix1).transform(matrix2).transform(matrix3)
def scale(self,v=[0,0,0]):
matrix=[
[v[0],0,0,0],
[0,v[1],0,0],
[0,0,v[2],0],
[0,0,0,1]
]
return self.transform(matrix)
def transform(self,m=I):
s=stl()
s.facets=[applymatrix(i,m) for i in self.facets]
s.insolid=0
s.infacet=0
s.inloop=0
s.facetloc=0
s.name=self.name
for facet in s.facets:
s.facetsminz+=[(min(map(lambda x:x[2], facet[1])),facet)]
s.facetsmaxz+=[(max(map(lambda x:x[2], facet[1])),facet)]
return s
def export(self,f=sys.stdout):
f.write("solid "+self.name+"\n")
for i in self.facets:
f.write(" facet normal "+" ".join(map(str,i[0]))+"\n")
f.write(" outer loop"+"\n")
for j in i[1]:
f.write(" vertex "+" ".join(map(str,j))+"\n")
f.write(" endloop"+"\n")
f.write(" endfacet"+"\n")
f.write("endsolid exported"+"\n")
f.flush()
def parseline(self,l):
l=l.strip()
if l.startswith("solid"):
self.insolid=1
self.name=l[6:]
#print self.name
elif l.startswith("endsolid"):
self.insolid=0
return 0
elif l.startswith("facet normal"):
self.infacet=11
self.facetloc=0
self.facet=[[0,0,0],[[0,0,0],[0,0,0],[0,0,0]]]
self.facet[0]=map(float,l.split()[2:])
elif l.startswith("endfacet"):
self.infacet=0
self.facets+=[self.facet]
facet=self.facet
self.facetsminz+=[(min(map(lambda x:x[2], facet[1])),facet)]
self.facetsmaxz+=[(max(map(lambda x:x[2], facet[1])),facet)]
elif l.startswith("vertex"):
self.facet[1][self.facetloc]=map(float,l.split()[1:])
self.facetloc+=1
return 1
if __name__=="__main__" and 0:
s=stl("sphere.stl")
for i in xrange(-10,11):
working=s.facets[:]
for j in reversed(sorted(s.facetsminz)):
if(j[0]>i):
working.remove(j[1])
else:
break
for j in (sorted(s.facetsmaxz)):
if(j[0]<i):
working.remove(j[1])
else:
break
print i,len(working)
#stl("../prusamendel/stl/mendelplate.stl")
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