import os.path, sys
import Tkinter as tk
from tkFileDialog import askopenfilename as tkFileGet
from string import rstrip, split
view = 10
#=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] = ((cvSize[0]/2) + 1000) + int((vDat[i][0]+(-(((ex.maxX-ex.minX)/2)+ex.minX)))*scale)
vDat[i][1] = ((cvSize[1]/2) + 10) + int((vDat[i][1]+(-(((ex.maxY-ex.minY)/2)+ex.minY)))*scale)
vDat[i][2] = ((cvSize[2]/2) + 10) + int((vDat[i][2]+(-(((ex.maxZ-ex.minZ)/2)+ex.minZ)))*scale)
vs = vertsize
for i in range(len(fDat)):
flag = 0
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][2]][3]/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 ###