All pastes #225841 Raw Edit

Untitled

public text v1 · immutable
#225841 ·published 2006-10-28 05:22 UTC
rendered paste body
#! /usr/bin/python

from canvas2d import *
import sys
import lex
import yacc
import Camera
from transform import *


tokens = ('NUMBER', 'LBRACE', 'RBRACE', 'LBRAC', 'RBRAC',
          'TRANSLAT','ROT','SFACTOR','FDIST','NDIST','ORIENT',
          'COORDINDEX','TOP','LEFT','RIGHT','BOTTOM','SEPARATOR',
          'COORD3','PCAMERA','TRANSFORM','POS','IFS','COMMA',
          'POINT')
#Tokens
t_LBRACE    = r'\{'
t_RBRACE    = r'\}'
t_LBRAC     = r'\['
t_RBRAC     = r'\]'
t_TRANSLAT  = r'translation'
t_ROT       = r'rotation'
t_SFACTOR   = r'scaleFactor'
t_FDIST     = r'farDistance'
t_NDIST     = r'nearDistance'
t_LEFT      = r'left'
t_RIGHT     = r'right'
t_TOP       = r'top'
t_BOTTOM    = r'bottom'
t_SEPARATOR = r'Separator'
t_COORDINDEX= r'coordIndex'
t_COORD3    = r'Coordinate3'
t_PCAMERA   = r'PerspectiveCamera'
t_TRANSFORM = r'Transform'
t_POS       = r'position'
t_IFS       = r'IndexedFaceSet'
t_ORIENT    = r'orientation'
t_COMMA     = r','
t_POINT     = r'point'

#All numbers will be interpreted as floating point numbers
def t_NUMBER(t):
    r'[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?'
    try:
        t.value = float(t.value)
    except ValueError:
        print "Unable to convert to float",t.value
        sys.exit()
    return t


def t_COMMENT(t):
    r'\#.*'
    pass

t_ignore  = " \t" #ignore whitespace

#line counter 
def t_newline(t):
    r'[\n\r]'
    t.lineno += 1

#error handler
def t_error(t):
    print "Illegal character '%s' on line %d" % (t.value[0], t.lineno)
    sys.exit()

lex.lex()  #build the lexer



## Data structures
mycamera = Camera.camera()
mytransforms = [trans((0,0,0))]
myifs = [[]]
mycoords = [[]]

#Parsing
def p_blocks(p):
    '''blocks     : block
                | block blocks'''
    pass

def p_block(p):
    '''block : camerablock
            | sepblock'''
    pass
    
def p_camerablock(p):
    'camerablock : PCAMERA LBRACE cameralines RBRACE'
    for i in range(0,len(p[3])):
        if p[3][i][0] == 'position':
            mycamera.position = p[3][i][1]
        elif p[3][i][0] == 'orientation':
            mycamera.orientation = p[3][i][1]
        elif p[3][i][0] == 'nearDistance':
            mycamera.nearDistance = p[3][i][1]
        elif p[3][i][0] == 'farDistance':
            mycamera.farDistance = p[3][i][1]
        elif p[3][i][0] == 'left':
            mycamera.left = p[3][i][1]
        elif p[3][i][0] == 'right':
            mycamera.right = p[3][i][1]
        elif p[3][i][0] == 'top':
            mycamera.top = p[3][i][1]
        elif p[3][i][0] == 'bottom':
            mycamera.bottom = p[3][i][1]
    
def p_cameralines(p):
    '''cameralines : cameraline
                | cameraline cameralines'''
    p[0] = [ p[1] ]
    if len(p) == 3:
        p[0].extend(p[2])
    
def p_cameraline(p):
    '''cameraline : POS triple
    | ORIENT quad
    | NDIST NUMBER
    | FDIST NUMBER
    | LEFT NUMBER
    | RIGHT NUMBER
    | TOP NUMBER
    | BOTTOM NUMBER'''
    p[0] = (p[1] , p[2] )
    #Camera lines will be put into the camera structure in the
    #camerablock rule

def p_sepblock(p):
    'sepblock    : SEPARATOR LBRACE sepitems RBRACE'
    mytransforms.append(trans((0,0,0))) #append identity matrix
    myifs.append([])
    mycoords.append([])
    
def p_sepitems(p):
    '''sepitems    : sepitem
                | sepitem sepitems'''
    pass
    
def p_sepitem(p):
    '''sepitem     : TRANSFORM LBRACE translines RBRACE
              | COORD3 LBRACE POINT LBRAC triples RBRAC RBRACE
              | IFS LBRACE ifsline RBRACE'''
    if p[1] == "Transform":
        mytransforms[-1] = matrixmultiply(mytransforms[-1],p[3])
    elif p[1] == "IndexedFaceSet":
        myifs[-1].append(p[3])
    else:
        mycoords[-1].append(p[5])
    
def p_translines(p):
    '''translines  : transline
                | transline translines'''
    p[0] = p[1]
    if len(p) == 3:
        p[0] = matrixmultiply(p[1],p[2])
    
def p_transline(p):
    '''transline   : TRANSLAT triple
              | SFACTOR triple
              | ROT quad'''
    if p[1] == 'translation':
        p[0] = trans(p[2])
    elif p[1] == 'rotation':
        p[0] = rot(p[2])
    elif p[1] == 'scaleFactor':
        p[0] = scale(p[2])

def p_ifsline(p):
    'ifsline    : COORDINDEX LBRAC singles RBRAC'
    p[0] = p[3]

def p_quad (p):
    'quad : NUMBER NUMBER NUMBER NUMBER'
    p[0] = (p[1],p[2],p[3],p[4])

def p_triple(p):
    'triple : NUMBER NUMBER NUMBER'
    p[0] = (p[1],p[2],p[3])
    
def p_triples(p):
    '''triples : triple
                | triple COMMA triples '''
    p[0] = [ p[1] ]
    if len(p) == 4:
        p[0].extend( p[3] )
        
def p_singles(p):
    '''singles : single
            | single COMMA singles'''
    p[0] = [ p[1] ]
    if len(p) == 4:
        p[0].extend(p[3])

def p_single(p):
    'single : NUMBER'
    p[0] = p[1]

def p_error(t):
    print "Syntax error at '%s'" % t.value

#build parser
yacc.yacc()


def main():
    # check input arguments
    if len(sys.argv) != 3:
        sys.stderr.write("Incorrect command line options\n")
        sys.exit(-1)

    #std to lexer, then parse
    lex.input(sys.stdin.read())
    yacc.parse(sys.stdin.read())

    #Ensure data sanity at a basic level
    if len(mytransforms) != len(mycoords):
        if len(mycoords) != len(myifs):
            print "Error in Open IV file formatting. Layout is not correct."

    numblocks = len(mytransforms) - 1
    
    
    #Done with lexing and parsing
    T_world_cam = inverse(matrixmultiply(trans(mycamera.position),
                                         rot(mycamera.orientation)))
    T_perspective = perspective((mycamera.top,mycamera.bottom,
                                 mycamera.left,mycamera.right,
                                mycamera.nearDistance,mycamera.farDistance))
    
    #mycanvas = canvas2d(mycamera.left,mycamera.right,mycamera.top,
    #                    mycamera.bottom, int(sys.argv[1]),int(sys.argv[2]))

    mycanvas = canvas2d(-1.0,1.0,1.0,-1.0,int(sys.argv[1]),int(sys.argv[2]))

    

    for i in range(numblocks):  #for each block
            for k in range(len(myifs[i])):  #for each index set
                faces = [[]]
                for n in range(len(myifs[i][k])): #iterate over indecies
                    if myifs[i][k][n] == -1:
                        faces.append([])
                    else:
                        point = mycoords[i][0][int(myifs[i][k][n])]
                        point = (point[0],point[1],point[2],1.0)
                        point = matrixmultiply(mytransforms[i],point)
                        point = matrixmultiply(T_world_cam,point)
                        point = matrixmultiply(T_perspective,point)
                        point = (point[0] / point[3], point[1] / point[3],
                                 point[2] / point[3],1.0)
                        faces[-1].append(list(point))
                #Faces is now full of polys for this block, transform, and IFS,
                # so we'll start drawing!
                for m in range(len(faces)-1):
                    mycanvas.line(faces[m][-1][0],faces[m][-1][1],
                                faces[m][0][0],faces[m][0][1])
                    for w in range(len(faces[m])-1):
                        mycanvas.line(faces[m][w][0],faces[m][w][1],
                                    faces[m][w+1][0],faces[m][w+1][1])

    mycanvas.toPPM()
                        
                      

if __name__ == '__main__': main()