"""
By Kirby Urner, 4D Solutions
Modified Sept 9, 2000:  flipped default camera angle to other side of XY plane
  and made y,z position of camera a variable (not just x)
Modified May 8, 2000: use xyz for 3-tuples vs coords, as coords
  may now contain 4-tuples, given Qvector subclass overrides
  this variable and uses in its own methods -- xyz common to
  Vector and all subclasses (including Svector).
Modified: Mar 5, 2000
bound some camera variables to class properties
added face() method
"""

import sys, os

class Povray:
    
    # defaults (class variables)
    cylradius = 0.02
    cylcolor  = 'Blue'
    sphradius = 0.02
    sphcolor  = 'Red'
    facecolor = 'Green'
    camfact   = 8.0
    camx      = 0.5
    wincomm   = "g:\\povray\\bin\\pvengine /NR /EXIT "
    linuxcomm = "povray +V +W640 +H480 +FC +A0.3 "
    
    def __init__(self,filename,cf=8.0,cx=0.5,cy=0.5,cz=1):
        # open Povray file, write header
        self.camfact = cf
        self.camx = cx
        self.camy = cy
        self.camz = cz
        self.file = open(filename, 'w')
        self.filename = filename
        self.header()

    def close(self):
        # close file
        self.file.close()

    def render(self):
        if sys.platform == 'win32':
            os.system(self.wincomm+" +I"+self.filename)
                
        if sys.platform == 'linux-i386':
            print "Rendering... (this will take some time)"
            os.system(self.linuxcomm+" +I"+self.filename)
            
    def shaft(self,v1):
        # write cylinder from (0,0,0) to v1.coords
        tip = tuple(v1.xyz)        
        self.file.write(("cylinder{<0, 0, 0>" 
                 + ",<%s, %s, %s>," % tip
                 + " %s pigment {color %s} no_shadow}\n" 
                 % (self.cylradius, self.cylcolor)))

    def edge(self,v1,v2):
        # write cylinder from v1.coords to v2.coords
        pointA = tuple(v1.xyz)
        pointB = tuple(v2.xyz)
        self.file.write(("cylinder{<%s, %s, %s>" % pointA
                 + ",<%s, %s, %s>," % pointB
                 + " %s pigment {color %s} no_shadow}\n" 
                 % (self.cylradius, self.cylcolor)))
                 
    def point(self,v1):
        # write sphere at v1.coords
        center = tuple(v1.xyz)
        self.file.write(("sphere{<%s, %s, %s>, " % center
                +"%s pigment {color %s} no_shadow }\n" 
                % (self.sphradius, self.sphcolor)))

    def face(self,vlist):
        # write polygon with coplanar corners in vlist
        nbr = len(vlist)+1
        self.file.write("polygon{ %s,\n" % nbr)
        for v in vlist:
             self.file.write("<%s, %s, %s>, " % v.xyz)
        self.file.write("<%s, %s, %s>\n" % vlist[0].xyz)
	self.file.write("pigment {color %s }}\n" % self.facecolor)
    
    def header(self):
        # default header, thanks to Russell Towle
        self.file.write("""          
//POV-Ray script
//version 3.1
global_settings { assumed_gamma 2.2 }
#include \"colors.inc\"
""")
        self.file.write("#declare Cam_factor = %s;\n" % self.camfact)
        self.file.write("#declare Camera_X = %s * Cam_factor;\n" % self.camx)
        self.file.write("#declare Camera_Y = %s * Cam_factor;\n" % self.camy)
        self.file.write("#declare Camera_Z = %s * Cam_factor;\n" % self.camz)
        self.file.write("""
camera { location  <Camera_X, Camera_Y, Camera_Z>
         up        <0, 1.0,  0>    right     <-4/3, 0,  0>
         direction <0, 0,  3>      look_at   <0, 0, 0>
         rotate <0,0,0>}   

light_source { <Camera_X - 2, Camera_Y + 5 , Camera_Z + 5> color White }
light_source { <Camera_X - 2, Camera_Y + 5 , Camera_Z - 3> color White }
light_source { <Camera_X + 2, Camera_Y - 5 , Camera_Z + 3> color White }

//Background:
background {color White}          
""")