Post by DarkPikachu on Apr 7, 2010 8:41:02 GMT -5
this viewer updates a Tkinter canvas with points, lines, and polygons
it only views obj files.
I'll prbly post an update later showing off normal calculations between the ambient, diffuse, and specular ramp
import os.path, sys
import Tkinter as tk
from tkFileDialog import askopenfilename as tkFileGet
from string import rstrip, split
view = 12
#=1 for front, =3 for side, =7 for top
scale = 5
vertsize = 1
hideLines = -1
#=0 for don't hide, =1 for hide, =-1 for show hidden as gray
#colors:
if hideLines==1:
BG = '#909090' #Background
fcol = '#99AfE0' #Face color
flin = '#000000' #Line color
fcola = '#D08FEF' #active Face color
flina = '#FFF000' #active Line color
vcol = '#D08FEF' #Vert color
vcola = '#FFF000' #active Vert color
lshad = ''
elif hideLines==0:
BG = '#909090' #Background
fcol = '' #Face color
flin = '#000000' #Line color
fcola = '' #active Face color
flina = '#FFFF2F' #active Line color
vcol = '#D08FEF' #Vert color
vcola = '#FFF000' #active Vert color
lshad = ''
elif hideLines==-1:
BG = '#909090' #Background
fcol = '' #Face color
flin = '#000000' #Line color
fcola = '' #active Face color
flina = '#FFF000' #active Line color
vcol = '#D08FEF' #Vert color
vcola = '#FFF000' #active Vert color
lshad = '#404040'
def drawWireframe(cv,cvSize,fn):
try: fin = open(fn, 'r')
except IOError,(eNum,eStr):
return fn+'\n I/O Error ('+str(eNum)+'): '+eStr
txList = map(rstrip,fin.readlines()) #strip trailing white space
fin.close()
vDat = [] #vertex (point) list
fDat = [] #face (polygon) list
ex = infoClass() #extents info collector
ex.minX = None
complex = None
for i in range(len(txList)): #initialize extents
if txList[i]: #not an empty line
tx = split(txList[i])
if ex.minX == None and tx[0] == 'v': #find first vertex
ex.minX,ex.maxX = float(tx[1]),float(tx[1])
ex.minY,ex.maxY = float(tx[2]),float(tx[2])
ex.minZ,ex.maxZ = float(tx[3]),float(tx[3])
if tx[0] == 'f' and complex == None: #find first polygon
complex = (tx[1].find('/') > -1) #are faces in v/vt/vn form?
break #finished with inits
if ex.minX == None or complex == None: #vertex or poly data not found
return fn+' is not a valid OBJ-format file'
for i in range(len(txList)):
if txList[i]: #not an empty line
tx = split(txList[i])
if tx[0] == 'v': #read vertices & find extents
x,y,z = float(tx[1]),float(tx[2]),float(tx[3])
if x < ex.minX: ex.minX = x
elif x > ex.maxX: ex.maxX = x
if y < ex.minY: ex.minY = y
elif y > ex.maxY: ex.maxY = y
if z < ex.minZ: ex.minZ = z
elif z > ex.maxZ: ex.maxZ = z
vDat.append([x,y,z])
elif tx[0] == 'f': #read faces
if complex:
p1,p2,p3 = int(split(tx[1],'/')[0]) - 1, int(split(tx[2],'/')[0]) - 1, int(split(tx[3],'/')[0]) - 1 #-1 to be 0-based
else:
p1,p2,p3 = int(tx[1])-1, int(tx[2])-1, int(tx[3])-1
if len(tx) == 5: #quad
if complex: p4 = int(split(tx[4],'/')[0]) - 1
else: p4 = int(tx[4]) - 1
fDat.append([p1,p2,p3,p4])
else: #triangle
fDat.append([p1,p2,p3])
for i in range(len(vDat)): #center & scale XYZ coords to raster integers
vDat[i][0] = int((vDat[i][0]+(-(((ex.maxX-ex.minX)/2)+ex.minX)))*scale) + ((cvSize[0]/2) + 1000)
vDat[i][1] = int((vDat[i][1]+(-(((ex.maxY-ex.minY)/2)+ex.minY)))*scale) + ((cvSize[1]/2) + 10)
vDat[i][2] = int((vDat[i][2]+(-(((ex.maxZ-ex.minZ)/2)+ex.minZ)))*scale) + ((cvSize[2]/2) + 10)
vs = vertsize
for i in range(len(fDat)):
flag = 0
#3D
if view == 10:
if hideLines: #do vector check
if ((((vDat[fDat[i][0]][0]+vDat[fDat[i][0]][1]-(vDat[fDat[i][0]][2]/2))/4)-((vDat[fDat[i][1]][0]+vDat[fDat[i][1]][1]-(vDat[fDat[i][1]][2]/2))/4)) \
* (((vDat[fDat[i][2]][0]+vDat[fDat[i][2]][2]-(vDat[fDat[i][2]][1]/2))/4)-((vDat[fDat[i][1]][0]+vDat[fDat[i][1]][2]-(vDat[fDat[i][1]][1]/2))/4)))\
-((((vDat[fDat[i][0]][0]+vDat[fDat[i][0]][2]-(vDat[fDat[i][0]][1]/2))/4)-((vDat[fDat[i][1]][0]+vDat[fDat[i][1]][2]-(vDat[fDat[i][1]][1]/2))/4)) \
* (((vDat[fDat[i][2]][0]+vDat[fDat[i][2]][1]-(vDat[fDat[i][2]][2]/2))/4)-((vDat[fDat[i][1]][0]+vDat[fDat[i][1]][1]-(vDat[fDat[i][1]][2]/2))/4))) < 0:
if hideLines == -1: flag = 1 #do grayed outline
else: continue #don't draw
if len(fDat) == 4: #draw quad
f = cv.create_polygon(
(vDat[fDat[i][0]][0]+vDat[fDat[i][0]][1]-(vDat[fDat[i][0]][2]/2))/4,(vDat[fDat[i][0]][0]+vDat[fDat[i][0]][2]-(vDat[fDat[i][0]][1]/2))/4,
(vDat[fDat[i][1]][0]+vDat[fDat[i][1]][1]-(vDat[fDat[i][1]][2]/2))/4,(vDat[fDat[i][1]][0]+vDat[fDat[i][1]][2]-(vDat[fDat[i][1]][1]/2))/4,
(vDat[fDat[i][2]][0]+vDat[fDat[i][2]][1]-(vDat[fDat[i][2]][2]/2))/4,(vDat[fDat[i][2]][0]+vDat[fDat[i][2]][2]-(vDat[fDat[i][2]][1]/2))/4,
(vDat[fDat[i][3]][0]+vDat[fDat[i][3]][1]-(vDat[fDat[i][3]][2]/2))/4,(vDat[fDat[i][3]][0]+vDat[fDat[i][3]][2]-(vDat[fDat[i][3]][1]/2))/4,
fill=fcol, outline=flin, activefill=fcola, activeoutline=flina,)
v = cv.create_oval(((vDat[fDat[i][0]][0]+vDat[fDat[i][0]][1]-(vDat[fDat[i][0]][2]/2))/4)+vertsize,((vDat[fDat[i][0]][0]+vDat[fDat[i][0]][2]-(vDat[fDat[i][0]][1]/2))/4)-vertsize,
((vDat[fDat[i][0]][0]+vDat[fDat[i][0]][1]-(vDat[fDat[i][0]][2]/2))/4)-vertsize,((vDat[fDat[i][0]][0]+vDat[fDat[i][0]][2]-(vDat[fDat[i][0]][1]/2))/4)+vertsize,
fill=vcol, outline=vcol, activefill=vcola, activeoutline=vcola,)
else: #draw tri
f = cv.create_polygon(
(vDat[fDat[i][0]][1]+vDat[fDat[i][0]][0]-(vDat[fDat[i][0]][2]/2))/4,(vDat[fDat[i][0]][2]+vDat[fDat[i][0]][0]-(vDat[fDat[i][0]][1]/2))/4,
(vDat[fDat[i][1]][1]+vDat[fDat[i][1]][0]-(vDat[fDat[i][1]][2]/2))/4,(vDat[fDat[i][1]][2]+vDat[fDat[i][1]][0]-(vDat[fDat[i][1]][1]/2))/4,
(vDat[fDat[i][2]][1]+vDat[fDat[i][2]][0]-(vDat[fDat[i][2]][2]/2))/4,(vDat[fDat[i][2]][2]+vDat[fDat[i][2]][0]-(vDat[fDat[i][2]][1]/2))/4,
fill=fcol, outline=flin, activefill=fcola, activeoutline=flina,)
v = cv.create_oval(
((vDat[fDat[i][0]][1]+vDat[fDat[i][0]][0]-(vDat[fDat[i][0]][2]/2))/4)-vertsize,((vDat[fDat[i][0]][2]+vDat[fDat[i][0]][0]-(vDat[fDat[i][0]][1]/2))/4)+vertsize,
((vDat[fDat[i][0]][1]+vDat[fDat[i][0]][0]-(vDat[fDat[i][0]][2]/2))/4)+vertsize,((vDat[fDat[i][0]][2]+vDat[fDat[i][0]][0]-(vDat[fDat[i][0]][1]/2))/4)-vertsize,
fill=vcol, outline=vcol, activefill=vcola, activeoutline=vcola,)
#front
elif view == 1:
if hideLines: #do vector check
if ((vDat[fDat[i][0]][0]-vDat[fDat[i][1]][0]) * (vDat[fDat[i][2]][1]-vDat[fDat[i][1]][1]))\
-((vDat[fDat[i][0]][1]-vDat[fDat[i][1]][1]) * (vDat[fDat[i][2]][0]-vDat[fDat[i][1]][0])) < 0:
if hideLines == -1: flag = 1 #do grayed outline
else: continue #don't draw
if len(fDat) == 4: #draw quad
f = cv.create_polygon(vDat[fDat[i][0]][0],vDat[fDat[i][0]][1],
vDat[fDat[i][1]][0],vDat[fDat[i][1]][1],
vDat[fDat[i][2]][0],vDat[fDat[i][2]][1],
vDat[fDat[i][3]][0],vDat[fDat[i][3]][1],
fill=fcol, outline=flin,
activefill=fcola, activeoutline=flina,
)
v = cv.create_oval(vDat[fDat[i][0]][0]+vertsize,vDat[fDat[i][0]][1]-vertsize,
vDat[fDat[i][0]][0]-vertsize,vDat[fDat[i][0]][1]+vertsize,
fill=vcol, outline=vcol,
activefill=vcola, activeoutline=vcola,
)
else: #draw tri
f = cv.create_polygon(vDat[fDat[i][0]][0],vDat[fDat[i][0]][1],
vDat[fDat[i][1]][0],vDat[fDat[i][1]][1],
vDat[fDat[i][2]][0],vDat[fDat[i][2]][1],
fill=fcol, outline=flin,
activefill=fcola, activeoutline=flina,
)
v = cv.create_oval(vDat[fDat[i][0]][0]+vertsize,vDat[fDat[i][0]][1]+vertsize,
vDat[fDat[i][0]][0]-vertsize,vDat[fDat[i][0]][1]-vertsize,
fill=vcol, outline=vcol,
activefill=vcola, activeoutline=vcola,
)
#side
elif view == 3:
if hideLines: #do vector check
if ((vDat[fDat[i][0]][1]-vDat[fDat[i][1]][1]) \
* (vDat[fDat[i][2]][2]-vDat[fDat[i][1]][2]))\
-((vDat[fDat[i][0]][2]-vDat[fDat[i][1]][2]) \
* (vDat[fDat[i][2]][1]-vDat[fDat[i][1]][1])) < 0:
if hideLines == -1: flag = 1 #do grayed outline
else: continue #don't draw
if len(fDat) == 4: #draw quad
f = cv.create_polygon(vDat[fDat[i][0]][2],vDat[fDat[i][0]][1],
vDat[fDat[i][1]][2],vDat[fDat[i][1]][1],
vDat[fDat[i][2]][2],vDat[fDat[i][2]][1],
vDat[fDat[i][3]][2],vDat[fDat[i][3]][1],
fill=fcol, outline=flin,
activefill=fcola, activeoutline=flina,
)
v = cv.create_oval(vDat[fDat[i][0]][2]+vertsize,vDat[fDat[i][0]][1]-vertsize,
vDat[fDat[i][0]][2]-vertsize,vDat[fDat[i][0]][1]+vertsize,
fill=vcol, outline=vcol,
activefill=vcola, activeoutline=vcola,
)
else: #draw tri
f = cv.create_polygon(vDat[fDat[i][0]][2],vDat[fDat[i][0]][1],
vDat[fDat[i][1]][2],vDat[fDat[i][1]][1],
vDat[fDat[i][2]][2],vDat[fDat[i][2]][1],
fill=fcol, outline=flin,
activefill=fcola, activeoutline=flina,
)
v = cv.create_oval(vDat[fDat[i][0]][2]+vertsize,vDat[fDat[i][0]][1]-vertsize,
vDat[fDat[i][0]][2]-vertsize,vDat[fDat[i][0]][1]+vertsize,
fill=vcol, outline=vcol,
activefill=vcola, activeoutline=vcola,
)
#top
elif view == 7:
if hideLines: #do vector check
if ((vDat[fDat[i][0]][0]-vDat[fDat[i][1]][0]) \
* (vDat[fDat[i][2]][2]-vDat[fDat[i][1]][2]))\
-((vDat[fDat[i][0]][2]-vDat[fDat[i][1]][2]) \
* (vDat[fDat[i][2]][0]-vDat[fDat[i][1]][0])) < 0:
if hideLines == -1: flag = 1 #do grayed outline
else: continue #don't draw
if len(fDat) == 4: #draw quad
f = cv.create_polygon(vDat[fDat[i][0]][0],vDat[fDat[i][0]][2],
vDat[fDat[i][1]][0],vDat[fDat[i][1]][2],
vDat[fDat[i][2]][0],vDat[fDat[i][2]][2],
vDat[fDat[i][3]][0],vDat[fDat[i][3]][2],
fill=fcol, outline=flin,
activefill=fcola, activeoutline=flina,
)
v = cv.create_oval(vDat[fDat[i][0]][0]+vertsize,vDat[fDat[i][0]][2]-vertsize,
vDat[fDat[i][0]][0]-vertsize,vDat[fDat[i][0]][2]+vertsize,
fill=vcol, outline=vcol,
activefill=vcola, activeoutline=vcola,
)
else: #draw tri
f = cv.create_polygon(vDat[fDat[i][0]][0],vDat[fDat[i][0]][2],
vDat[fDat[i][1]][0],vDat[fDat[i][1]][2],
vDat[fDat[i][2]][0],vDat[fDat[i][2]][2],
fill=fcol, outline=flin,
activefill=fcola, activeoutline=flina,
)
v = cv.create_oval(vDat[fDat[i][0]][0]+vertsize,vDat[fDat[i][0]][2]-vertsize,
vDat[fDat[i][0]][0]-vertsize,vDat[fDat[i][0]][2]+vertsize,
fill=vcol, outline=vcol,
activefill=vcola, activeoutline=vcola,
)
if flag:
cv.itemconfig(f,outline=lshad)
cv.lower(f)
return fn+' - '+str(len(vDat))+' points & '+str(len(fDat))+' faces\n'+'scale = '+(scale).__str__()
#end def drawWireframe
class infoClass: #empty class to hold temporary info
def __init__(self):
pass
#end class infoClass
scX = 1024
scY = 768
scZ = 4
class mainWindowClass:
def __init__(self,master):
self.frame = tk.Toplevel(master)
self.frame.title('Tkinter 3D OBJ Hidden-Line Wireframe 0.0d')
self.frame.geometry((scX).__str__()+'x'+(scY).__str__()+'+0+0')
self.frame.resizable(0,0)
self.canvas = tk.Canvas(self.frame, bg=BG, bd=3, relief='sunken', cursor='crosshair')
self.canvas.pack(side='top',anchor='nw',fill='both',expand=1)
self.frame.protocol('WM_DELETE_WINDOW',self.quit) #close button
def getFile(self):
fn = tkFileGet(title='Select a file',parent=self.frame,
initialdir=os.path.split(sys.argv[0])[0],
filetypes=[('OBJ','*.obj *.tab'),('All Files','*.*')])
self.frame.update_idletasks()
if fn:
if fn[-4:].lower() in ['.obj','.tab']:
return drawWireframe(self.canvas,(scX,scY,scZ),fn)
else:
return fn+' selected\n\nNeed .obj or .tab file in OBJ format'
else: return 'No file selected'
def quit(self):
self.frame.destroy()
#end class mainWindowClass
#--- go to work ---
root = tk.Tk()
root.withdraw()
mainWin = mainWindowClass(root)
mainWin.canvas.create_text(10,10,anchor='nw',font=('Helvetica',10),
text=mainWin.getFile())
#root.update_window(mainWin.frame)
root.mainloop()
### end script ###
it only views obj files.
I'll prbly post an update later showing off normal calculations between the ambient, diffuse, and specular ramp