Commit 1e53117b authored by Kliment Yanev's avatar Kliment Yanev

OpenGL-based plater update (requires a pyglet install)

parent 8f3df9c2
#!/usr/bin/env python #!/usr/bin/env python
import wx,time,random,threading,os,math import wx,time,random,threading,os,math
import stltool import stltool
glview=True
try:
import stlview
except:
glview=False
def translate(l): return l def translate(l): return l
...@@ -22,79 +27,174 @@ class stlwrap: ...@@ -22,79 +27,174 @@ class stlwrap:
class showstl(wx.Window): class showstl(wx.Window):
def __init__(self,parent,size,pos): def __init__(self,parent,size,pos):
wx.Window.__init__(self,parent,size=size,pos=pos) wx.Window.__init__(self,parent,size=size,pos=pos)
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)
self.db.Bind(wx.EVT_BUTTON,self.delete)
self.ab.Bind(wx.EVT_BUTTON,self.autoplate)
#self.SetBackgroundColour((0,0,0)) #self.SetBackgroundColour((0,0,0))
#wx.FutureCall(200,self.paint) #wx.FutureCall(200,self.paint)
self.i=0 self.i=0
self.parent=parent
self.previ=0 self.previ=0
self.Bind(wx.EVT_MOUSEWHEEL,self.rot) self.Bind(wx.EVT_MOUSEWHEEL,self.rot)
self.Bind(wx.EVT_MOUSE_EVENTS,self.move) self.Bind(wx.EVT_MOUSE_EVENTS,self.move)
self.Bind(wx.EVT_PAINT,self.repaint) self.Bind(wx.EVT_PAINT,self.repaint)
#self.s=stltool.stl("sphere.stl").scale([2,1,1]) #self.s=stltool.stl("sphere.stl").scale([2,1,1])
self.triggered=0 self.triggered=0
self.models={}
self.basedir="."
self.initpos=None self.initpos=None
self.prevsel=-1 self.prevsel=-1
def center(self,event): def drawmodel(self,m,scale):
i=self.l.GetSelection() m.bitmap=wx.EmptyBitmap(800,800,32)
if i != -1: dc=wx.MemoryDC()
m=self.models[self.l.GetString(i)] dc.SelectObject(m.bitmap)
m.offsets=[100,100,m.offsets[2]] dc.SetBackground(wx.Brush((0,0,0,0)))
self.Refresh() dc.SetBrush(wx.Brush((0,0,0,255)))
#dc.DrawRectangle(-1,-1,10000,10000)
dc.SetBrush(wx.Brush(wx.Colour(128,255,128)))
dc.SetPen(wx.Pen(wx.Colour(128,128,128)))
#m.offsets=[10,10,0]
#print m.offsets,m.dims
for i in m.facets:#random.sample(m.facets,min(100000,len(m.facets))):
dc.DrawPolygon([wx.Point(400+scale*p[0],(400-scale*p[1])) for p in i[1]])
#if(time.time()-t)>5:
# break
dc.SelectObject(wx.NullBitmap)
m.bitmap.SetMask(wx.Mask(m.bitmap,wx.Colour(0,0,0,255)))
def snap(self,event):
i=self.l.GetSelection() def move(self,event):
if i != -1: if event.ButtonUp(wx.MOUSE_BTN_LEFT):
m=self.models[self.l.GetString(i)] if(self.initpos is not None):
m.offsets[2]=-1.0*min(m.facetsminz)[0] i=self.parent.l.GetSelection()
#print m.offsets[2] if i != wx.NOT_FOUND:
p=event.GetPositionTuple()
#print (p[0]-self.initpos[0]),(p[1]-self.initpos[1])
t=time.time()
m=self.parent.models[self.parent.l.GetString(i)]
m.offsets=[m.offsets[0]+0.5*(p[0]-self.initpos[0]),m.offsets[1]-0.5*(p[1]-self.initpos[1]),m.offsets[2]]
#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])
#print time.time()-t
self.Refresh() self.Refresh()
self.initpos=None
elif event.ButtonDown(wx.MOUSE_BTN_RIGHT):
self.parent.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)
def delete(self,event): del dc
i=self.l.GetSelection() else:
if i != -1: event.Skip()
del self.models[self.l.GetString(i)]
self.l.Delete(i) def rotateafter(self):
self.l.Select(self.l.GetCount()-1) if(self.i!=self.previ):
i=self.parent.l.GetSelection()
if i != wx.NOT_FOUND:
#o=self.models[self.l.GetItemText(i)].offsets
self.parent.models[self.parent.l.GetString(i)].rot+=5*(self.i-self.previ)
#self.models[self.l.GetItemText(i)].offsets=o
self.previ=self.i
self.Refresh() self.Refresh()
def cr(self):
time.sleep(0.01)
wx.CallAfter(self.rotateafter)
self.triggered=0
def export(self,event): def rot(self, event):
dlg=wx.FileDialog(self,"Pick file to save to",self.basedir,style=wx.FD_SAVE) z=event.GetWheelRotation()
dlg.SetWildcard("STL files (;*.stl;)") s=self.parent.l.GetSelection()
if(dlg.ShowModal() == wx.ID_OK): if self.prevsel!=s:
name=dlg.GetPath() self.i=0
sf=open(name.replace(".","_")+".scad","w") 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()
facets=[] def repaint(self,event):
for i in self.models.values(): dc=wx.PaintDC(self)
self.paint(dc=dc)
r=i.rot def paint(self,coord1="x",coord2="y",dc=None):
o=i.offsets coords={"x":0,"y":1,"z":2}
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 dc is None:
if r != 0: dc=wx.ClientDC(self)
i=i.rotate([0,0,-r]) offset=[0,0]
if o != [0,0,0]: scale=2
i=i.translate([o[0],-o[1],o[2]]) dc.SetPen(wx.Pen(wx.Colour(100,100,100)))
facets+=i.facets for i in xrange(20):
sf.close() dc.DrawLine(0,i*scale*10,400,i*scale*10)
stltool.emitstl(name,facets,"plater_export") dc.DrawLine(i*scale*10,0,i*scale*10,400)
print "wrote ",name dc.SetPen(wx.Pen(wx.Colour(0,0,0)))
for i in xrange(4):
dc.DrawLine(0,i*scale*50,400,i*scale*50)
dc.DrawLine(i*scale*50,0,i*scale*50,400)
dc.SetBrush(wx.Brush(wx.Colour(128,255,128)))
dc.SetPen(wx.Pen(wx.Colour(128,128,128)))
t=time.time()
dcs=wx.MemoryDC()
for m in self.parent.models.values():
b=m.bitmap
#print b
im=b.ConvertToImage()
#print im
imgc = wx.Point( im.GetWidth()/2,im.GetHeight()/2 )
#print math.radians(5*(self.i-self.previ))
im= im.Rotate( math.radians(m.rot), imgc, 0)
bm=wx.BitmapFromImage(im)
dcs.SelectObject(bm)
bsz=bm.GetSize()
dc.Blit(scale*m.offsets[0]-bsz[0]/2,400-(scale*m.offsets[1]+bsz[1]/2),bsz[0],bsz[1],dcs,0,0,useMask=1)
#for i in m.facets:#random.sample(m.facets,min(100000,len(m.facets))):
# dc.DrawPolygon([wx.Point(offset[0]+scale*m.offsets[0]+scale*p[0],400-(offset[1]+scale*m.offsets[1]+scale*p[1])) for p in i[1]])
#if(time.time()-t)>5:
# break
del dc
#print time.time()-t
#s.export()
class stlwin(wx.Frame):
def __init__(self,size=(800,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.mainsizer = wx.BoxSizer(wx.HORIZONTAL)
self.panel=wx.Panel(self,-1,size=(150,600),pos=(0,0))
self.panel.SetBackgroundColour((10,10,10))
self.l=wx.ListBox(self.panel,size=(300,180),pos=(0,30))
self.cl=wx.Button(self.panel,label="Clear",pos=(0,205))
self.lb=wx.Button(self.panel,label="Load",pos=(0,0))
self.eb=wx.Button(self.panel,label="Export",pos=(100,0))
self.sb=wx.Button(self.panel,label="Snap to Z=0",pos=(00,255))
self.cb=wx.Button(self.panel,label="Put at 100,100",pos=(0,280))
self.db=wx.Button(self.panel,label="Delete",pos=(0,305))
self.ab=wx.Button(self.panel,label="Auto",pos=(0,330))
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)
self.db.Bind(wx.EVT_BUTTON,self.delete)
self.ab.Bind(wx.EVT_BUTTON,self.autoplate)
self.basedir="."
self.models={}
self.SetBackgroundColour((10,10,10))
self.mainsizer.Add(self.panel)
#self.mainsizer.AddSpacer(10)
if glview:
self.s=stlview.TestGlPanel(self,(580,580))
else:
self.s=showstl(self,(580,580),(0,0))
self.mainsizer.Add(self.s, 1, wx.EXPAND)
self.SetSizer(self.mainsizer)
#self.mainsizer.Fit(self)
self.Layout()
#self.SetClientSize(size)
def autoplate(self,event): def autoplate(self,event):
print "Autoplating" print "Autoplating"
...@@ -118,7 +218,7 @@ class showstl(wx.Window): ...@@ -118,7 +218,7 @@ class showstl(wx.Window):
#To the person who works out why the offsets are applied differently here: #To the person who works out why the offsets are applied differently here:
# Good job, it confused the hell out of me. # Good job, it confused the hell out of me.
self.models[i].offsets[0] = cursor[0] + centre[0] - centreoffset[0] self.models[i].offsets[0] = cursor[0] + centre[0] - centreoffset[0]
self.models[i].offsets[1] = cursor[1] + centre[1] + centreoffset[1] self.models[i].offsets[1] = cursor[1] + centre[1] - centreoffset[1]
if (max[0] == 0) or (max[0] < (cursor[0]+x)): if (max[0] == 0) or (max[0] < (cursor[0]+x)):
max[0] = cursor[0]+x max[0] = cursor[0]+x
if (max[1] == 0) or (max[1] < (cursor[1]+x)): if (max[1] == 0) or (max[1] < (cursor[1]+x)):
...@@ -134,6 +234,60 @@ class showstl(wx.Window): ...@@ -134,6 +234,60 @@ class showstl(wx.Window):
self.models[i].offsets[1] += centreoffset[1] self.models[i].offsets[1] += centreoffset[1]
self.Refresh() self.Refresh()
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()
def center(self,event):
i=self.l.GetSelection()
if i != -1:
m=self.models[self.l.GetString(i)]
m.offsets=[100,100,m.offsets[2]]
self.Refresh()
def snap(self,event):
i=self.l.GetSelection()
if i != -1:
m=self.models[self.l.GetString(i)]
m.offsets[2]=-1.0*min(m.facetsminz)[0]
#print m.offsets[2]
self.Refresh()
def delete(self,event):
i=self.l.GetSelection()
if i != -1:
del self.models[self.l.GetString(i)]
self.l.Delete(i)
self.l.Select(self.l.GetCount()-1)
self.Refresh()
def export(self,event):
dlg=wx.FileDialog(self,"Pick file to save to",self.basedir,style=wx.FD_SAVE)
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
def right(self,event): def right(self,event):
dlg=wx.FileDialog(self,"Pick file to load",self.basedir,style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST) 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") dlg.SetWildcard("STL files (;*.stl;)|*.stl|OpenSCAD files (;*.scad;)|*.scad")
...@@ -178,7 +332,7 @@ class showstl(wx.Window): ...@@ -178,7 +332,7 @@ class showstl(wx.Window):
self.Refresh() self.Refresh()
#print time.time()-t #print time.time()-t
def load_stl_into_model(self,path,name,offset=[0,0,0],rotation=0): def load_stl_into_model(self,path,name,offset=[0,0,0],rotation=0,scale=[1.0,1.0,1.0]):
newname=os.path.split(name.lower())[1] newname=os.path.split(name.lower())[1]
c=1 c=1
while newname in self.models: while newname in self.models:
...@@ -188,6 +342,7 @@ class showstl(wx.Window): ...@@ -188,6 +342,7 @@ class showstl(wx.Window):
self.models[newname]=stltool.stl(path) self.models[newname]=stltool.stl(path)
self.models[newname].offsets=offset self.models[newname].offsets=offset
self.models[newname].rot=rotation self.models[newname].rot=rotation
self.models[newname].scale=scale
self.models[newname].filename=name self.models[newname].filename=name
minx,miny,minz,maxx,maxy,maxz=(10000,10000,10000,0,0,0) minx,miny,minz,maxx,maxy,maxz=(10000,10000,10000,0,0,0)
for i in self.models[newname].facets: for i in self.models[newname].facets:
...@@ -209,24 +364,7 @@ class showstl(wx.Window): ...@@ -209,24 +364,7 @@ class showstl(wx.Window):
# self.models[newname].offsets[0]=-minx # self.models[newname].offsets[0]=-minx
#if miny<0: #if miny<0:
# self.models[newname].offsets[1]=-miny # self.models[newname].offsets[1]=-miny
self.models[newname].bitmap=wx.EmptyBitmap(800,800,32) self.s.drawmodel(self.models[newname],2)
dc=wx.MemoryDC()
dc.SelectObject(self.models[newname].bitmap)
dc.SetBackground(wx.Brush((0,0,0,0)))
dc.SetBrush(wx.Brush((0,0,0,255)))
#dc.DrawRectangle(-1,-1,10000,10000)
dc.SetBrush(wx.Brush(wx.Colour(128,255,128)))
dc.SetPen(wx.Pen(wx.Colour(128,128,128)))
m=self.models[newname]
#m.offsets=[10,10,0]
print m.offsets,m.dims
scale=2
for i in m.facets:#random.sample(m.facets,min(100000,len(m.facets))):
dc.DrawPolygon([wx.Point(400+scale*p[0],(400+scale*p[1])) for p in i[1]])
#if(time.time()-t)>5:
# break
dc.SelectObject(wx.NullBitmap)
m.bitmap.SetMask(wx.Mask(m.bitmap,wx.Colour(0,0,0,255)))
#print time.time()-t #print time.time()-t
self.l.Append(newname) self.l.Append(newname)
...@@ -236,120 +374,6 @@ class showstl(wx.Window): ...@@ -236,120 +374,6 @@ class showstl(wx.Window):
self.l.Select(self.l.GetCount()-1) 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()
def move(self,event):
if event.ButtonUp(wx.MOUSE_BTN_LEFT):
if(self.initpos is not None):
i=self.l.GetSelection()
if i != wx.NOT_FOUND:
p=event.GetPositionTuple()
#print (p[0]-self.initpos[0]),(p[1]-self.initpos[1])
t=time.time()
m=self.models[self.l.GetString(i)]
m.offsets=[m.offsets[0]+0.5*(p[0]-self.initpos[0]),m.offsets[1]-0.5*(p[1]-self.initpos[1]),m.offsets[2]]
#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])
#print time.time()-t
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 rotateafter(self):
if(self.i!=self.previ):
i=self.l.GetSelection()
if i != wx.NOT_FOUND:
#o=self.models[self.l.GetItemText(i)].offsets
self.models[self.l.GetString(i)].rot+=5*(self.i-self.previ)
#self.models[self.l.GetItemText(i)].offsets=o
self.previ=self.i
self.Refresh()
def cr(self):
time.sleep(0.01)
wx.CallAfter(self.rotateafter)
self.triggered=0
def rot(self, event):
z=event.GetWheelRotation()
s=self.l.GetSelection()
if self.prevsel!=s:
self.i=0
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}
if dc is None:
dc=wx.ClientDC(self)
offset=[0,0]
scale=2
dc.SetPen(wx.Pen(wx.Colour(100,100,100)))
for i in xrange(20):
dc.DrawLine(0,i*scale*10,400,i*scale*10)
dc.DrawLine(i*scale*10,0,i*scale*10,400)
dc.SetPen(wx.Pen(wx.Colour(0,0,0)))
for i in xrange(4):
dc.DrawLine(0,i*scale*50,400,i*scale*50)
dc.DrawLine(i*scale*50,0,i*scale*50,400)
dc.SetBrush(wx.Brush(wx.Colour(128,255,128)))
dc.SetPen(wx.Pen(wx.Colour(128,128,128)))
t=time.time()
dcs=wx.MemoryDC()
for m in self.models.values():
b=m.bitmap
#print b
im=b.ConvertToImage()
#print im
imgc = wx.Point( im.GetWidth()/2,im.GetHeight()/2 )
#print math.radians(5*(self.i-self.previ))
im= im.Rotate( math.radians(m.rot), imgc, 0)
bm=wx.BitmapFromImage(im)
dcs.SelectObject(bm)
bsz=bm.GetSize()
dc.Blit(scale*m.offsets[0]-bsz[0]/2,400-(scale*m.offsets[1]+bsz[1]/2),bsz[0],bsz[1],dcs,0,0,useMask=1)
#for i in m.facets:#random.sample(m.facets,min(100000,len(m.facets))):
# dc.DrawPolygon([wx.Point(offset[0]+scale*m.offsets[0]+scale*p[0],400-(offset[1]+scale*m.offsets[1]+scale*p[1])) for p in i[1]])
#if(time.time()-t)>5:
# break
del dc
#print time.time()-t
#s.export()
class stlwin(wx.Frame):
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,580),(0,0))
if __name__ == '__main__': if __name__ == '__main__':
app = wx.App(False) app = wx.App(False)
......
...@@ -189,7 +189,6 @@ class GLPanel(wx.Panel): ...@@ -189,7 +189,6 @@ class GLPanel(wx.Panel):
pass pass
class stlview(object): class stlview(object):
list = None
def __init__(self, facets, batch): def __init__(self, facets, batch):
# Create the vertex and normal arrays. # Create the vertex and normal arrays.
vertices = [] vertices = []
...@@ -213,6 +212,149 @@ class stlview(object): ...@@ -213,6 +212,149 @@ class stlview(object):
def delete(self): def delete(self):
self.vertex_list.delete() self.vertex_list.delete()
class gcview(object):
def __init__(self, lines, batch, w=0.5, h=0.5):
# Create the vertex and normal arrays.
vertices = []
normals = []
self.prev=[0.001,0.001,0.001,0.001]
self.fline=1
f=open("20cube_export.gcode")
lines=list(f)
f.close()
self.layers={}
lines=[self.transform(i) for i in lines]
lines=[i for i in lines if i is not None]
layertemp={}
lasth=None
for i in lines:
if i[0][2] not in layertemp:
layertemp[i[0][2]]=[[],[]]
if lasth is not None:
self.layers[lasth]=pyglet.graphics.Batch()
indices = range(len(layertemp[lasth][0]))#[[3*i,3*i+1,3*i+2] for i in xrange(len(facets))]
self.layers[lasth].add_indexed(len(layertemp[lasth][0])//3,
GL_TRIANGLES,
None,#group,
indices,
('v3f/static', layertemp[lasth][0]),
('n3f/static', layertemp[lasth][1]))
lasth=i[0][2]
S=i[0][:3]
E=i[1][:3]
v=map(lambda x,y:x-y,E,S)
vlen=math.sqrt(float(sum(map(lambda a:a*a, v[:3]))))
if vlen==0:
vlen=0.01
sq2=math.sqrt(2.0)/2.0
htw=float(h)/w
d=w/2.0
if i[1][3]==i[0][3]:
d=0.05
points=[[d,0,0],
[sq2*d,sq2*d,0],
[0,d,0],
[-sq2*d,sq2*d,0],
[-d,0,0],
[-sq2*d,-sq2*d,0],
[0,-d,0],
[sq2*d,-sq2*d,0]
]
axis=stltool.cross([0,0,1],v)
alen=math.sqrt(float(sum(map(lambda a:a*a, v[:3]))))
if alen>0:
axis=map(lambda m:m/alen,axis)
angle=math.acos(v[2]/vlen)
def vrot(v,axis,angle):
kxv=stltool.cross(axis,v)
kdv=sum(map(lambda x,y:x*y,axis,v))
return map(lambda x,y,z:x*math.cos(angle)+y*math.sin(angle)+z*kdv*(1.0-math.cos(angle)),v,kxv,axis)
points=map(lambda x:vrot(x,axis,angle),points)
points=map(lambda x:[x[0],x[1],htw*x[2]],points)
def vadd(v,o):
return map(lambda x,y:x+y,v,o)
def vdiff(v,o):
return map(lambda x,y:x-y,v,o)
spoints=map(lambda x:vadd(S,x),points)
epoints=map(lambda x:vadd(E,x),points)
for j in xrange(8):
layertemp[i[0][2]][0].extend(spoints[(j+1)%8])
layertemp[i[0][2]][1].extend(vdiff(spoints[(j+1)%8],S))
layertemp[i[0][2]][0].extend(epoints[(j)%8])
layertemp[i[0][2]][1].extend(vdiff(epoints[(j)%8],E))
layertemp[i[0][2]][0].extend(spoints[j])
layertemp[i[0][2]][1].extend(vdiff(spoints[j],S))
layertemp[i[0][2]][0].extend(epoints[(j)])
layertemp[i[0][2]][1].extend(vdiff(epoints[(j)],E))
layertemp[i[0][2]][0].extend(spoints[(j+1)%8])
layertemp[i[0][2]][1].extend(vdiff(spoints[j],S))
layertemp[i[0][2]][0].extend(epoints[(j+1)%8])
layertemp[i[0][2]][1].extend(vdiff(epoints[(j+1)%8],E))
vertices.extend(spoints[(j+1)%8])
normals.extend(vdiff(spoints[(j+1)%8],S))
vertices.extend(epoints[(j)%8])
normals.extend(vdiff(epoints[(j)%8],E))
vertices.extend(spoints[j])
normals.extend(vdiff(spoints[j],S))
vertices.extend(epoints[(j)])
normals.extend(vdiff(epoints[(j)],E))
vertices.extend(spoints[(j+1)%8])
normals.extend(vdiff(spoints[j],S))
vertices.extend(epoints[(j+1)%8])
normals.extend(vdiff(epoints[(j+1)%8],E))
# Create a list of triangle indices.
indices = range(3*16*len(lines))#[[3*i,3*i+1,3*i+2] for i in xrange(len(facets))]
#print indices[:10]
self.vertex_list = batch.add_indexed(len(vertices)//3,
GL_TRIANGLES,
None,#group,
indices,
('v3f/static', vertices),
('n3f/static', normals))
if lasth is not None:
self.layers[lasth]=pyglet.graphics.Batch()
indices = range(len(layertemp[lasth][0]))#[[3*i,3*i+1,3*i+2] for i in xrange(len(facets))]
self.layers[lasth].add_indexed(len(layertemp[lasth][0])//3,
GL_TRIANGLES,
None,#group,
indices,
('v3f/static', layertemp[lasth][0]),
('n3f/static', layertemp[lasth][1]))
def transform(self,line):
line=line.split(";")[0]
cur=self.prev[:]
if len(line)>0:
if "G1" in line or "G0" in line or "G92" in line:
if("X" in line):
cur[0]=float(line.split("X")[1].split(" ")[0])
if("Y" in line):
cur[1]=float(line.split("Y")[1].split(" ")[0])
if("Z" in line):
cur[2]=float(line.split("Z")[1].split(" ")[0])
if("E" in line):
cur[3]=float(line.split("E")[1].split(" ")[0])
if self.prev==cur:
return None
if self.fline or "G92" in line:
self.prev=cur
self.fline=0
return None
else:
r=[self.prev,cur]
self.prev=cur
return r
def delete(self):
self.vertex_list.delete()
def trackball(p1x, p1y, p2x, p2y, r): def trackball(p1x, p1y, p2x, p2y, r):
TRACKBALLSIZE=r TRACKBALLSIZE=r
#float a[3]; /* Axis of rotation */ #float a[3]; /* Axis of rotation */
...@@ -284,21 +426,35 @@ def mulquat(q1,rq): ...@@ -284,21 +426,35 @@ def mulquat(q1,rq):
q1[3] * rq[2] + q1[2] * rq[3] + q1[0] * rq[1] - q1[1] * rq[0], q1[3] * rq[2] + q1[2] * rq[3] + q1[0] * rq[1] - q1[1] * rq[0],
q1[3] * rq[3] - q1[0] * rq[0] - q1[1] * rq[1] - q1[2] * rq[2]] q1[3] * rq[3] - q1[0] * rq[0] - q1[1] * rq[1] - q1[2] * rq[2]]
class TestGlPanel(GLPanel): class TestGlPanel(GLPanel):
def __init__(self, parent, id=wx.ID_ANY, pos=(10, 10)): def __init__(self, parent, size,id=wx.ID_ANY,):
super(TestGlPanel, self).__init__(parent, id, wx.DefaultPosition, wx.DefaultSize, 0) super(TestGlPanel, self).__init__(parent, id, wx.DefaultPosition, size, 0)
self.batches=[] self.batches=[]
self.rot=0 self.rot=0
self.canvas.Bind(wx.EVT_MOUSE_EVENTS,self.move) self.canvas.Bind(wx.EVT_MOUSE_EVENTS,self.move)
self.canvas.Bind(wx.EVT_LEFT_DCLICK,self.double)
self.initialized=1 self.initialized=1
self.canvas.Bind(wx.EVT_MOUSEWHEEL,self.wheel) self.canvas.Bind(wx.EVT_MOUSEWHEEL,self.wheel)
self.parent=parent
self.initp=None self.initp=None
self.selected=0
self.dist=200 self.dist=200
self.bedsize=[200,200]
self.transv=[0, 0, -self.dist] self.transv=[0, 0, -self.dist]
self.basequat=[0,0,0,1] self.basequat=[0,0,0,1]
wx.CallAfter(self.forceresize) wx.CallAfter(self.forceresize)
self.mousepos=[0,0]
def double(self, event):
p=event.GetPositionTuple()
sz=self.GetClientSize()
v=map(lambda m,w,b:b*m/w,p,sz,self.bedsize)
v[1]=self.bedsize[1]-v[1]
v+=[300]
print v
self.add_file("../prusa/metric-prusa/x-end-idler.stl",v)
def forceresize(self): def forceresize(self):
self.SetClientSize((self.GetClientSize()[0],self.GetClientSize()[1]+1)) self.SetClientSize((self.GetClientSize()[0],self.GetClientSize()[1]+1))
...@@ -311,15 +467,17 @@ class TestGlPanel(GLPanel): ...@@ -311,15 +467,17 @@ class TestGlPanel(GLPanel):
if self.initp==None: if self.initp==None:
self.initp=event.GetPositionTuple() self.initp=event.GetPositionTuple()
else: else:
if event.ShiftDown(): if not event.ShiftDown():
if self.selected<0: i=self.parent.l.GetSelection()
if i<0:
return return
p1=list(self.initp) p1=list(self.initp)
p1[1]*=-1 p1[1]*=-1
self.initp=None self.initp=None
p2=list(event.GetPositionTuple()) p2=list(event.GetPositionTuple())
p2[1]*=-1 p2[1]*=-1
self.batches[self.selected][0]=map(lambda old,new,original:original+(new-old), list(p1)+[0],list(p2)+[0],self.batches[0][0]) m=self.parent.models[self.parent.l.GetString(i)]
m.offsets=map(lambda old,new,original:original+(new-old), list(p1)+[0],list(p2)+[0],m.offsets)
return return
#print self.initp #print self.initp
p1=self.initp p1=self.initp
...@@ -339,8 +497,8 @@ class TestGlPanel(GLPanel): ...@@ -339,8 +497,8 @@ class TestGlPanel(GLPanel):
#self.basequat=quatx #self.basequat=quatx
mat=build_rotmatrix(self.basequat) mat=build_rotmatrix(self.basequat)
glLoadIdentity() glLoadIdentity()
#glTranslatef(-self.transv[0],-self.transv[1],-self.transv[2]) glTranslatef(self.transv[0],self.transv[1],0)
glTranslatef(*self.transv) glTranslatef(0,0,self.transv[2])
glMultMatrixd(mat) glMultMatrixd(mat)
glGetDoublev(GL_MODELVIEW_MATRIX,self.mvmat) glGetDoublev(GL_MODELVIEW_MATRIX,self.mvmat)
self.rot=1 self.rot=1
...@@ -352,7 +510,8 @@ class TestGlPanel(GLPanel): ...@@ -352,7 +510,8 @@ class TestGlPanel(GLPanel):
if self.initp is not None: if self.initp is not None:
self.initp=None self.initp=None
elif event.Dragging() and event.RightIsDown():
elif event.Dragging() and event.RightIsDown() and event.ShiftDown():
if self.initp is None: if self.initp is None:
self.initp=event.GetPositionTuple() self.initp=event.GetPositionTuple()
else: else:
...@@ -367,24 +526,35 @@ class TestGlPanel(GLPanel): ...@@ -367,24 +526,35 @@ class TestGlPanel(GLPanel):
self.transv=map(lambda x,y,z,c:c-self.dist*(x-y)/z, list(p1)+[0], list(p2)+[0], list(sz)+[1], self.transv) self.transv=map(lambda x,y,z,c:c-self.dist*(x-y)/z, list(p1)+[0], list(p2)+[0], list(sz)+[1], self.transv)
glLoadIdentity() glLoadIdentity()
glTranslatef(*self.transv) glTranslatef(self.transv[0],self.transv[1],0)
glTranslatef(0,0,self.transv[2])
if(self.rot): if(self.rot):
glMultMatrixd(build_rotmatrix(self.basequat)) glMultMatrixd(build_rotmatrix(self.basequat))
glGetDoublev(GL_MODELVIEW_MATRIX,self.mvmat) glGetDoublev(GL_MODELVIEW_MATRIX,self.mvmat)
self.rot=1 self.rot=1
self.initp=None self.initp=None
else:
#mouse is moving without a button press
p=event.GetPositionTuple()
sz=self.GetClientSize()
v=map(lambda m,w,b:b*m/w,p,sz,self.bedsize)
v[1]=self.bedsize[1]-v[1]
self.mousepos=v
def wheel(self,event): def wheel(self,event):
z=event.GetWheelRotation() z=event.GetWheelRotation()
delta=10 delta=10
if event.ShiftDown(): if not event.ShiftDown():
if self.selected<0: i=self.parent.l.GetSelection()
if i<0:
return return
m=self.parent.models[self.parent.l.GetString(i)]
if z > 0: if z > 0:
self.batches[self.selected][2]+=delta/2 m.rot+=delta/2
else: else:
self.batches[self.selected][2]-=delta/2 m.rot-=delta/2
return return
if z > 0: if z > 0:
self.transv[2]+=delta self.transv[2]+=delta
...@@ -407,31 +577,44 @@ class TestGlPanel(GLPanel): ...@@ -407,31 +577,44 @@ class TestGlPanel(GLPanel):
wx.CallAfter(self.Refresh) wx.CallAfter(self.Refresh)
except: except:
return return
#continue
global rx, ry, rz def anim(self,obj):
rx += dt * 1 g=50*9.8
ry += dt * 80 v=20
rz += dt * 30 dt=0.05
rx %= 360 basepos=obj.offsets[2]
ry %= 360 obj.offsets[2]+=obj.animoffset
rz %= 360 while obj.offsets[2]>-1:
time.sleep(dt)
obj.offsets[2]-=v*dt
v+=g*dt
if(obj.offsets[2]<0):
obj.scale[2]*=1-3*dt
#return
v=v/4
while obj.offsets[2]<basepos:
time.sleep(dt)
obj.offsets[2]+=v*dt
v-=g*dt
obj.scale[2]*=1+5*dt
obj.scale[2]=1.0
def create_objects(self): def create_objects(self):
'''create opengl objects when opengl is initialized''' '''create opengl objects when opengl is initialized'''
import stltool
batch = pyglet.graphics.Batch()
s= stltool.stl("x-end-idler.stl")
stl = stlview(s.facets, batch=batch)
#print "added vertices"
self.batches+=[[[50,50,0],batch,0]]
#batch = pyglet.graphics.Batch()
#s= stltool.stl("../prusa/metric-prusa/mbotplate1.stl")
#stl = stlview(s.facets, batch=batch)
#print "added vertices"
#self.batches+=[([-50,-50,0],batch)]
self.initialized=1 self.initialized=1
wx.CallAfter(self.Refresh) wx.CallAfter(self.Refresh)
def drawmodel(self,m,n):
batch = pyglet.graphics.Batch()
stl = stlview(m.facets, batch=batch)
m.batch=batch
m.animoffset=300
#print m
#threading.Thread(target=self.anim,args=(m,)).start()
wx.CallAfter(self.Refresh)
def update_object_resize(self): def update_object_resize(self):
'''called when the window recieves only if opengl is initialized''' '''called when the window recieves only if opengl is initialized'''
pass pass
...@@ -451,11 +634,9 @@ class TestGlPanel(GLPanel): ...@@ -451,11 +634,9 @@ class TestGlPanel(GLPanel):
else: else:
glLoadIdentity() glLoadIdentity()
glTranslatef(*self.transv) glTranslatef(*self.transv)
#glRotatef(rz, 0, 0, 1)
#glRotatef(ry, 0, 1, 0)
#glRotatef(rx, 1, 0, 0)
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(0.2, 0.2, 0.2, 1)) glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(0.2, 0.2, 0.2, 1))
glBegin(GL_LINES) glBegin(GL_LINES)
glNormal3f(0,0,1)
rows=10 rows=10
cols=10 cols=10
zheight=50 zheight=50
...@@ -493,14 +674,31 @@ class TestGlPanel(GLPanel): ...@@ -493,14 +674,31 @@ class TestGlPanel(GLPanel):
glVertex3f(10*-cols, 10*rows,zheight) glVertex3f(10*-cols, 10*rows,zheight)
glEnd() glEnd()
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(0.5, 0.6, 0.3, 1)) glPushMatrix()
glTranslatef(self.mousepos[0]-self.bedsize[0]/2,self.mousepos[1]-self.bedsize[1]/2,0)
glBegin(GL_TRIANGLES)
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(1, 0, 0, 1))
glNormal3f(0,0,1)
glVertex3f(2,2,0)
glVertex3f(-2,2,0)
glVertex3f(-2,-2,0)
glVertex3f(2,-2,0)
glVertex3f(2,2,0)
glVertex3f(-2,-2,0)
glEnd()
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(0.3, 0.7, 0.5, 1))
#glTranslatef(0,40,0) #glTranslatef(0,40,0)
for i in self.batches: glPopMatrix()
glPushMatrix()
glTranslatef(-100,-100,0)
for i in self.parent.models.values():
glPushMatrix() glPushMatrix()
glTranslatef(*i[0]) glTranslatef(*(i.offsets))
glRotatef(i[2],0.0,0.0,1.0) glRotatef(i.rot,0.0,0.0,1.0)
#glScalef(1,1,0) glScalef(*i.scale)
i[1].draw() i.batch.draw()
glPopMatrix()
glPopMatrix() glPopMatrix()
#print "drawn batch" #print "drawn batch"
class TestFrame(wx.Frame): class TestFrame(wx.Frame):
...@@ -508,10 +706,14 @@ class TestFrame(wx.Frame): ...@@ -508,10 +706,14 @@ class TestFrame(wx.Frame):
def __init__(self, parent, ID, title, pos=wx.DefaultPosition, def __init__(self, parent, ID, title, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE): size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
super(TestFrame, self).__init__(parent, ID, title, pos, size, style) super(TestFrame, self).__init__(parent, ID, title, pos, (size[0]+150,size[1]), style)
self.mainsizer = wx.BoxSizer(wx.HORIZONTAL) self.mainsizer = wx.BoxSizer(wx.HORIZONTAL)
self.GLPanel1 = TestGlPanel(self) self.panel=wx.Panel(self,-1,size=(150,600),pos=(0,0))
self.panel.SetBackgroundColour((10,10,10))
self.SetBackgroundColour((10,10,10))
self.mainsizer.Add(self.panel)
#self.mainsizer.AddSpacer(10)
self.GLPanel1 = TestGlPanel(self,size)
self.mainsizer.Add(self.GLPanel1, 1, wx.EXPAND) self.mainsizer.Add(self.GLPanel1, 1, wx.EXPAND)
#self.GLPanel2 = TestGlPanel(self, wx.ID_ANY, (20, 20)) #self.GLPanel2 = TestGlPanel(self, wx.ID_ANY, (20, 20))
#self.mainsizer.Add(self.GLPanel2, 1, wx.EXPAND) #self.mainsizer.Add(self.GLPanel2, 1, wx.EXPAND)
...@@ -521,13 +723,14 @@ class TestFrame(wx.Frame): ...@@ -521,13 +723,14 @@ class TestFrame(wx.Frame):
if __name__=="__main__":
rx = ry = rz = 0
rx = ry = rz = 0 app = wx.App(redirect=False)
frame = TestFrame(None, wx.ID_ANY, 'GL Window', size=(400,400))
#frame = wx.Frame(None, -1, "GL Window", size=(400,400))
#panel = TestGlPanel(frame)
frame.Show(True)
app.MainLoop()
app.Destroy()
app = wx.App(redirect=False)
frame = TestFrame(None, wx.ID_ANY, 'GL Window', size=(400,400))
#frame = wx.Frame(None, -1, "GL Window", size=(400,400))
#panel = TestGlPanel(frame)
frame.Show(True)
app.MainLoop()
app.Destroy()
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