0

as well as my last thread (hex editor) I need help knowing how to program a 3d model viewer that reads obj format, and supports texturing...

unlike the hex editor, I have some code if you want to play around with it...
you must set everything manually before you run it...

import os.path, sys
import Tkinter as tk
from tkFileDialog import askopenfilename as tkFileGet
from string import rstrip, split


view = 10 #3D view (not perfect)
#=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
        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,)


        elif view == 12:
            """
            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]][1]-(vDat[fDat[i][0]][2]/2))/4,(vDat[fDat[i][0]][0]-(vDat[fDat[i][0]][2]/2))/4,
                    (vDat[fDat[i][1]][1]-(vDat[fDat[i][1]][2]/2))/4,(vDat[fDat[i][1]][0]-(vDat[fDat[i][1]][2]/2))/4,
                    (vDat[fDat[i][2]][1]-(vDat[fDat[i][2]][2]/2))/4,(vDat[fDat[i][2]][0]-(vDat[fDat[i][2]][2]/2))/4,
                    (vDat[fDat[i][3]][1]-(vDat[fDat[i][3]][2]/2))/4,(vDat[fDat[i][3]][0]-(vDat[fDat[i][3]][2]/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]][2]-(vDat[fDat[i][0]][1]*2))/8,(vDat[fDat[i][0]][2]-(vDat[fDat[i][0]][0]*2))/8,
                    (vDat[fDat[i][1]][2]-(vDat[fDat[i][1]][1]*2))/8,(vDat[fDat[i][1]][2]-(vDat[fDat[i][1]][0]*2))/8,
                    (vDat[fDat[i][2]][2]-(vDat[fDat[i][2]][1]*2))/8,(vDat[fDat[i][2]][2]-(vDat[fDat[i][2]][0]*2))/8,
                                    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 ###

note: the vector checks don't work right.

honestly, this code isn't mine...
I just took someone elses code and made it better.
credit to whoever designed the first code... <_< >_>

to make things worse...
I don't even understand much of this code...
how did I manage to make it better??
I'm asking myself the same question... O.o

Edited by Tcll: n/a

1
Contributor
1
Reply
2
Views
7 Years
Discussion Span
Last Post by Tcll
This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.