## Automatically adapted for numpy.oldnumeric Jul 23, 2007 by 

#############################################################################
#
# Author: Anna Omelchenko, Michel Sanner
#
# Copyright: M. Sanner TSRI 2003
#
#############################################################################

#
# $Header: /opt/cvs/Volume/Renderers/VLI/DejaVu/VLIGeom.py,v 1.6 2008/11/20 01:04:45 vareille Exp $
#
# $Id: VLIGeom.py,v 1.6 2008/11/20 01:04:45 vareille Exp $
#

""" Module implementing a special DejaVu geometric object - VLIGeom.
The DisplayFunction() uses VLI library volume rendering methods. """

# Starting with VLI version 2.0 the 7th point feature is used for
# drawing 3D volume:
# the 7th point is computed from the 6 coordinates returned by
# VLIContext::FetchBasePlane().  The Z coordinates returned are those
# of the appropriate volume corner.
# In earlier versions, the coordinates formed a flat hexagon, parallel
# to the screen - all six Z coordinates were returned as the Z coordinate
# of the center of the volume. For these VLI versions the Z coordinates
# are computed in this module.

from Volume.Renderers.VLI import vli
from opengltk.OpenGL import GL
from opengltk.OpenGL.GLU import gluErrorString
import math, types
import numpy.oldnumeric as Numeric, thread, string
from DejaVu.IndexedPolylines import IndexedPolylines
from DejaVu import Viewer, viewerConst
from DejaVu.Camera import Camera
from DejaVu.viewerFns import checkKeywords
from DejaVu.VolumeGeom import VolumeGeom, CropBox

class VLIGeom(VolumeGeom):
    """Class to render a VLI texture mapped polygon"""

    keywords = VolumeGeom.keywords + ['renderMode', 'dorender']

    def __init__(self, name=None, check=1, **kw):

        apply( VolumeGeom.__init__, (self, name, check), kw)
        
        # before doing anything, check if board exists and ready
        status = vli.VLIOpen()
        if status !=vli.kVLIOK:
            raise RuntimeError("VLIOpen() failed. Status %d"% status)
        self.Set(inheritMaterial = 0)
        self.maxBB = (25,25,25)
        self.minBB = (-25,-25,-25)
        self.lock = thread.allocate_lock()
        self.newVolumeLock = thread.allocate_lock()
        self.pickable = 0
        self.updateBoundBox = 1

        self.cropStatus = 0
        
        # VLIobjects
        self.volume = None
        self.dataPtr = None
        self.context = None
        self.win = None
        self.vliScalemat = None
        #self.scalemat = Numeric.identity(4).astype('f')
        self.vliTranslate = None
        self.translatemat = Numeric.identity(4).astype('f')
        
        self.renderMode = 'hexagon'
        self.buffer = 0
        self.volumeBoxes = 0
        self.volumesizes = []
        self.cropBox_list = []
        self.ratios = []
        self.volumeSize = (0,0,0)
        #self.antialiased = 0
        self.masterObject = None
        self.onaddVolume_list = []

        self.freePointer = 1

        self.dataSource = None
        self.fileName = None
        self.dataArr = None
        
        # create a context
        self.context = vli.VLIContext_Create()
        if not self.context:
            raise RuntimeError("Context_Create() failed ")
        self.hasBasePlane=0

        # FIXME .. this implies that an OpenGL context is available at this time
        self.win = vli.VLIOpenGLContext()
        self.cropBox = CropBox(self)
        crop = self.context.GetCrop()
        self.cropBox.crop = crop
        self.cropBox.crop.SetFlags(crop.kSubVolume)
        self.cropOpts = ['off','SubVolume', '3DCross',
                           '3DCrossInvert','3DFence', '3DFenceInvert']
        self.lights = []
        self.currLight = None
        self.lightCallBack = None

        self.render = 1
        if vli.kVLIMajorVersion >= 2:
            self.RenderCube = self.RenderCube_7point
        self.firstLoaded = 1


    def RotateVLILight(self, event, matrix, transXY, transZ):
        vi =self.viewer
        vi.RotateCurrentDLight(event, matrix, transXY, transZ)
        d = vi.currentLight.direction*(-1)
        currnum = int(string.split(vi.currentLight.name)[1])
        vec = vli.VLIVector3D(d[0],d[1],d[2])
        if self.currLight != self.lights[currnum]:
            self.currLight = self.lights[currnum]
        self.currLight.SetDirection(vec)
        if self.lightCallBack:
            self.lightCallBack(d[0],d[1],d[2], currnum)

    def VLILightOnOff(self):
        vi = self.viewer
        n = vi.GUI.CurrentLight.get()-1
        if n < 0 : return
	l = vi.lights[n]
        switch = vi.GUI.lightOnOff.get()
        #print "switch:",  switch
        l.Set(enable = switch)
        self.currLight = self.lights[n]
        if switch:
            status = self.context.AddLight(self.currLight)
            if status != vli.kVLIOK:
                print "Warning:Light not added, status:", status
        else:
            status = self.context.RemoveLight(self.currLight)
            if status != vli.kVLIOK:
                print "Warning:Light not removed, status:", status
        if self.lightCallBack:
            self.lightCallBack(switch, n+1)        
	vi.Redraw()



    def LoadVolume(self, voxfilename):
        if self.volume:
            self.volume.Release()
        self.volume = vli.VLIVolume_CreateFromFile(voxfilename)
        self.volume.AddRef()
        if not self.volume:
            raise RuntimeError("Failed to open %s"% voxfilename)
        if self.firstLoaded:
            if self.viewer:
                self.viewer.NormalizeCurrentObject()
                self.firstLoaded = 0
        self.initVolume()
        self.dataSource = 'file'
        self.fileName = voxfilename

    def AddVolume(self, volume, dataPtr):
        # FIXME not sure what classes are OK here VLIVolumePtr
        # assert isinstance(volume, VLIVolume)
        if self.volume:
            self.volume.Release()
        self.volume = volume
        self.volume.AddRef()
        if self.firstLoaded:
            if self.viewer:
                self.viewer.NormalizeCurrentObject()
                self.firstLoaded = 0
        self.initVolume()
        if self.dataPtr:
            if self.freePointer:
                vli.FreeMemory(self.dataPtr)
        self.dataPtr = dataPtr
        self.dataSource = 'dataptr'


    def initVolume(self):
        if self.hasBasePlane:
            self.context.ReleaseBasePlane(self.buffer)
        (vx,vy,vz) = self.volume.GetSize()
        self.cropBox.setVolSize( (vx,vy,vz) )
        self.cropBox.xmin = 0
        self.cropBox.xmax = vx
        self.cropBox.ymin = 0
        self.cropBox.ymax = vy
        self.cropBox.zmin = 0
        self.cropBox.zmax = vz
        
        self.volumeSize = (vx,vy,vz)
        self.centerMat = vli.VLIMatrix_Translate(-.5*vx, -.5*vy, -.5*vz)
        #self.volume.LockVolume()
        
        self.hasBasePlane=0
        self.cropBox.update()
        for c in self.onaddVolume_list:
            c.OnAddVolumeToViewer()

    def initTexture(self):
        self.viewer.currentCamera.Activate()
        GL.glTexParameterf( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
                            GL.GL_LINEAR )
        GL.glTexParameterf( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
                            GL.GL_LINEAR )
        GL.glEnable(GL.GL_TEXTURE_2D)
        GL.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE_MINUS_SRC_ALPHA)
        GL.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE)
        GL.glClearColor(0.0, 0.0, 0.0, 0.0)
        GL.glAlphaFunc(GL.GL_GREATER, 0.05)
        GL.glEnable(GL.GL_ALPHA_TEST)
        GL.glEnable(GL.GL_DEPTH_TEST)

    def Set(self, check=1, redo=1, updateOwnGui=True, **kw):
        redoFlags = apply( VolumeGeom.Set, (self,0,0), kw)
        s = kw.get('volscale')
        rm = kw.get('renderMode')
        mo = kw.get('masterObject')
        tr = kw.get('voltranslate')
        r = kw.get('dorender')
        
        if s:
            if isinstance(s, types.TupleType) or isinstance(s, types.ListType):
                if len(s) != 3:
                    raise ValueError("Wrong number of arguments; expected 3, got %d." % len(s))
                self.vliScalemat = vli.VLIMatrix_Scale(s[0],s[1],s[2])
##                  scale=[]
##                  for i in range(4):
##                      for j in range(4):
##                          scale.append(self.vliScalemat[i][j])
##                  self.scalemat=Numeric.reshape(scale,(4,4))
            else:
                raise TypeError("Wrong argument type; list or tuple expected")
        if rm:
            if rm == 'hexagon':
                self.renderMode = 'hexagon'
            elif rm == '3D':
                self.renderMode = '3D'
            else:
               raise ValueError("Wrong renderMode; 'hexagon' or '3D' expected")
        if mo:
            self.masterObject = mo

        if tr:
            self.vliTranslate = vli.VLIMatrix_Translate(tr[0],tr[1],tr[2])

        if r:
            self.render = r
            
        return self.redoNow(redo, updateOwnGui, redoFlags)

    def Draw(self):
        if not self.render: return
        if self.volume is None or self.context is None: return
        val = self.lock.acquire(0)
        if val==0: return

        self.initTexture()

        # setup the VLI transformation matrix to reflect the global
        # tranformation of this geometry
        
        masterObject = self.masterObject
        mat = Numeric.transpose(masterObject.GetMatrix())
        rot, trans, sc = masterObject.Decompose4x4(Numeric.reshape(mat,(16,)))

        vx,vy,vz=self.volumeSize
        vliCamera = self.context.GetCamera()
        scVLI = vli.VLIMatrix_Scale(sc[0],sc[1],sc[2])
        vliCamera.SetViewMatrix(scVLI)
        rotVLI = vli.VLIMatrix(rot)
        transVLI = vli.VLIMatrix_Translate(trans[0]/sc[0],
                                           trans[1]/sc[1],
                                           trans[2]/sc[2])
        matVLI =  transVLI * rotVLI
        if self.vliScalemat:
            if self.vliTranslate:
                self.volume.SetModelMatrix(((matVLI* self.vliScalemat)*\
                                            self.centerMat)*self.vliTranslate)
            else:
                self.volume.SetModelMatrix((matVLI *self.vliScalemat)*\
                                           self.centerMat)  
        else:
            if self.vliTranslate:
                self.volume.SetModelMatrix((matVLI * self.centerMat)*\
                                           self.vliTranslate)
            else:
                self.volume.SetModelMatrix(matVLI * self.centerMat)
            
        status = self.context.RenderBasePlane(self.volume, self.buffer)
        if (status != vli.kVLIOK and status != vli.kVLIMultiPass):
            self.lock.release()
            self.context.ReleaseBasePlane(self.buffer)
            raise RuntimeError("RenderToBP failed. Status=%d"% status)
        geoHex = vli.VLIVector3DArray(6)
        texCoord = vli.VLIVector2DArray(6)

        while 1:
            try:
                output = self.context.FetchBasePlane(self.buffer,geoHex.get(),
                                                     texCoord.get())
                break
            except:
                pass

	self.geoHex = geoHex
        self.texCoord = texCoord
        status,bwidth,bheight,iwidth,iheight,bpi = output
        self.fetchout = output
        if status != vli.kVLIOK:
            self.lock.release()
            self.context.ReleaseBasePlane(self.buffer)
            raise RuntimeError("Fetch failed. Status=%d"% status)

        GL.glPushMatrix()
        GL.glLoadIdentity()
        GL.glTranslatef( 0., 0., -30)
        #m = GL.glGetDoublev(GL.GL_MODELVIEW_MATRIX)
        #print m
        
        if self.volumeBoxes:
            self.draw_volume_boxes()

        self.win.TransferBasePlane(self.buffer, bwidth, bheight,
                                   iwidth, iheight, bpi)
        self.bpi = bpi
        if self.renderMode == '3D':
            self.RenderCube(geoHex, texCoord)
        elif self.renderMode == 'hexagon' :
            self.RenderHexagon(geoHex, texCoord, 0.0)
        self.context.ReleaseBasePlane(self.buffer)

        GL.glPopMatrix()
        self.lock.release()

    def RenderCube(self, geoHex, texCoord):
        hexCoords = []
        j=0
        #geoHex = self.geoHex
        #texCoord = self.texCoord
        for i in range(6):
            if i == 3:
               hexCoords.append([geoHex[2][0]-geoHex[1][0]+geoHex[0][0],
                                 geoHex[0][1]-geoHex[5][1]+geoHex[4][1],
                                 1, j])
               j=j+1
            hexCoords.append([geoHex[i][0], geoHex[i][1], 0, j])
            j=j+1
        hexCoords.append([geoHex[3][0]-(geoHex[4][0]-geoHex[5][0]),
                          geoHex[1][1]-(geoHex[2][1]-geoHex[3][1]), -1, 7])
        sorthexCoords = hexCoords[:]
        sorthexCoords.sort()

        Vx = self.volumeSize[0]/2.
        Vy = self.volumeSize[1]/2.
        Vz = self.volumeSize[2]/2. 

        box = Numeric.array([[Vx, Vy, Vz], [-Vx, Vy, Vz],
                                  [-Vx, -Vy, Vz], [Vx, -Vy, Vz],
                                  [Vx, Vy, -Vz], [-Vx, Vy, -Vz],
                                  [-Vx, -Vy, -Vz], [Vx, -Vy, -Vz]])
        one = Numeric.ones( (box.shape[0], 1), viewerConst.FPRECISION )
        c = Numeric.concatenate( (box, one), 1 )
        #mat = Numeric.transpose(self.viewer.rootObject.GetMatrix())
        mat = Numeric.transpose(self.masterObject.GetMatrix())
        mm = Numeric.dot( c, mat )
        boxCoords = mm.tolist()
        boxCoords.sort()
        j=0
        for c in sorthexCoords:
            i=c[3]
            hexCoords[i][2] = boxCoords[j][2]
            j=j+1
        self.hexCoords = hexCoords
        #self.mm = mm
        self.boxCoords=boxCoords

##          s = Numeric.sum( self.viewer.rootObject.rotation -
##                           Numeric.identity(4).ravel() )
        s = Numeric.sum( self.masterObject.rotation -
                         Numeric.identity(4).ravel() )
        if s==0.0: # special case where rotation == identity
            for p in self.hexCoords:
                if p[2] > 0.0:
                    z = p[2]
                    break
            self.Render1Polygon( geoHex, texCoord, z )
        else:

            self.RenderHexagon1(hexCoords, texCoord )

    def RenderCube_7point(self, geoHex, texCoord):
        """works with VLI version 2.0.
        Compute a 7th point from the 6 coordinates
        (returned by VLIContext::FetchBasePlane) and render
        the base plane as a triangle fan.
        This has the effect that the base plane will be
        projected onto the front faces of the volume parallelepiped.) """
        
        seventhPoint = geoHex[2] + geoHex[0] - geoHex[1]
        seventhTexCoord = vli.VLIVector2D(texCoord[4][0], texCoord[2][1])

        GL.glEnable(GL.GL_TEXTURE_2D)
        GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL)
        #glEnable(GL_LIGHTING)
        if self.viewer is not None:
            self.viewer.enableOpenglLighting()
        GL.glEnable(GL.GL_BLEND)
        GL.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE_MINUS_SRC_ALPHA)
        GL.glDisable(GL.GL_CULL_FACE)
        
        # draw a triangle fan based at the seventh point.
        
        GL.glBegin(GL.GL_TRIANGLE_FAN)
        GL.glTexCoord2d(seventhTexCoord[0], seventhTexCoord[1])
        GL.glVertex3d(seventhPoint[0], seventhPoint[1], seventhPoint[2])
        for i in range(6):
            GL.glTexCoord2d(texCoord[i][0], texCoord[i][1])
            GL.glVertex3d(geoHex[i][0], geoHex[i][1], geoHex[i][2])
        GL.glTexCoord2d(texCoord[0][0], texCoord[0][1])
        GL.glVertex3d(geoHex[0][0], geoHex[0][1], geoHex[0][2])
        GL.glEnd()
        
        GL.glDisable(GL.GL_TEXTURE_2D)


    def printGeoHex(self):
        for i in range(6):
            print self.geoHex[i][0],self.geoHex[i][1],self.geoHex[i][2]
##              print self.texCoord[i][0], self.texCoord[i][1]

    def printTexCoord(self):
        for i in range(6):
            print self.texCoord[i][0], self.texCoord[i][1]

    def getModelMatrix(self):
        mat = self.volume.GetModelMatrix()
        for i in range(4):
            print mat[i][0], mat[i][1], mat[i][2], mat[i][3]

    def getCameraMatrix(self):
        mat = self.context.GetCamera().GetViewMatrix()
        for i in range(4):
            print mat[i][0], mat[i][1], mat[i][2], mat[i][3]

    def printVLIMatrix(self, mat):
        for i in range(4):
            print mat[i][0], mat[i][1], mat[i][2], mat[i][3]
            

    def RenderHexagon(self, hexagon, textureCoords, zcoord):
        returnCode = 0
        errCount = 0
        err = GL.glGetError ()
        while err != GL.GL_NO_ERROR:
            errString = gluErrorString(err)
            print 'GL ERROR in ren. hex(0): %d %s' % (err, errString)
            if returnCode == 0:
                returnCode = err
            errCount = errCount+1
            if (errCount > 10): break #prevent infinite loops
            
        GL.glEnable(GL.GL_TEXTURE_2D)
        GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL)
        #glEnable(GL_LIGHTING)
        if self.viewer is not None:
            self.viewer.enableOpenglLighting()
        GL.glEnable(GL.GL_BLEND)
        GL.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE_MINUS_SRC_ALPHA)
        GL.glDisable(GL.GL_CULL_FACE)
        GL.glBegin (GL.GL_POLYGON)
        for i in range(6):
            GL.glTexCoord2d(textureCoords[i][0], textureCoords[i][1])
            #print textureCoords[i][0], " ", textureCoords[i][1]
            GL.glVertex3d(hexagon[i][0], hexagon[i][1], zcoord)#hexagon[i][2])
        GL.glEnd ()
        GL.glDisable(GL.GL_TEXTURE_2D)
        
        errCount = 0
        err = GL.glGetError ()
        while err != GL.GL_NO_ERROR:
            errString = gluErrorString(err)
            print 'GL ERROR in ren. hex(1): %d %s' % (err, errString)
            if returnCode == 0:
                returnCode = err
            errCount = errCount+1
            if (errCount > 10): break #prevent infinite loops

        #return returnCode

    def Render1Polygon(self, hexCoords, texCoord, z ):
        GL.glEnable(GL.GL_TEXTURE_2D)
        GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL)
        #glEnable(GL_LIGHTING)
        if self.viewer is not None:
            self.viewer.enableOpenglLighting()
        GL.glEnable(GL.GL_BLEND)
        GL.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE_MINUS_SRC_ALPHA)
        GL.glDisable(GL.GL_CULL_FACE)

        GL.glBegin (GL.GL_POLYGON)
        for i in range(6):
            GL.glTexCoord2d(texCoord[i][0],texCoord[i][1])
            GL.glVertex3d(hexCoords[i][0], hexCoords[i][1], z )
        GL.glEnd ()
        GL.glDisable(GL.GL_TEXTURE_2D)

    def RenderHexagon1(self, hexCoords, texCoords):

##          returnCode = 0
##          errCount = 0
##          err = GL.glGetError ()
##          while err != GL.GL_NO_ERROR:
##              #Ignore OpenGL errors that occur earlier
##              errCount = errCount+1
##              if (errCount > 10): break #prevent infinite loops
            
        GL.glEnable(GL.GL_TEXTURE_2D)
        GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL)
        #glEnable(GL_LIGHTING)
        if self.viewer is not None:
            self.viewer.enableOpenglLighting()
        GL.glEnable(GL.GL_BLEND)
        GL.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE_MINUS_SRC_ALPHA)
        GL.glDisable(GL.GL_CULL_FACE)

        texfront = [texCoords[2][0]-texCoords[1][0]+texCoords[0][0],
                    texCoords[2][1]-texCoords[1][1]+texCoords[0][1]]
        
        GL.glBegin (GL.GL_POLYGON)
        GL.glTexCoord2d(texfront[0],texfront[1])
        GL.glVertex3d(hexCoords[3][0], hexCoords[3][1],hexCoords[3][2] )
        GL.glTexCoord2d(texCoords[0][0], texCoords[0][1])
        GL.glVertex3d(hexCoords[0][0], hexCoords[0][1],hexCoords[0][2] )
        GL.glTexCoord2d(texCoords[1][0], texCoords[1][1])
        GL.glVertex3d(hexCoords[1][0], hexCoords[1][1], hexCoords[1][2])
        GL.glTexCoord2d(texCoords[2][0], texCoords[2][1])
        GL.glVertex3d(hexCoords[2][0], hexCoords[2][1],hexCoords[2][2] )
        GL.glEnd ()

        GL.glBegin (GL.GL_POLYGON)
        GL.glTexCoord2d(texfront[0],texfront[1])
        GL.glVertex3d(hexCoords[3][0], hexCoords[3][1],hexCoords[3][2] )
        GL.glTexCoord2d(texCoords[0][0], texCoords[0][1])
        GL.glVertex3d(hexCoords[0][0], hexCoords[0][1],hexCoords[0][2] )
        GL.glTexCoord2d(texCoords[5][0], texCoords[5][1])
        GL.glVertex3d(hexCoords[6][0], hexCoords[6][1], hexCoords[6][2])
        GL.glTexCoord2d(texCoords[4][0], texCoords[4][1])
        GL.glVertex3d(hexCoords[5][0], hexCoords[5][1],hexCoords[5][2] )
        GL.glEnd ()

        GL.glBegin (GL.GL_POLYGON)
        GL.glTexCoord2d(texfront[0],texfront[1])
#        print hexCoords[3][0], hexCoords[3][1],hexCoords[3][2]
        GL.glVertex3d(hexCoords[3][0], hexCoords[3][1],hexCoords[3][2] )
        GL.glTexCoord2d(texCoords[2][0], texCoords[2][1])
#        print hexCoords[2][0], hexCoords[2][1],hexCoords[2][2]
        GL.glVertex3d(hexCoords[2][0], hexCoords[2][1],hexCoords[2][2] )
        GL.glTexCoord2d(texCoords[3][0], texCoords[3][1])
#        print hexCoords[4][0], hexCoords[4][1], hexCoords[4][2]
        GL.glVertex3d(hexCoords[4][0], hexCoords[4][1], hexCoords[4][2])
        GL.glTexCoord2d(texCoords[4][0], texCoords[4][1])
##          if hexCoords[5][0]==hexCoords[6][0] and hexCoords[5][1]==hexCoords[6][1]:
##              ind=6
##          else: ind=5
#        print hexCoords[ind][0], hexCoords[ind][1],hexCoords[ind][2]
##          GL.glVertex3d(hexCoords[ind][0], hexCoords[ind][1],hexCoords[ind][2] )
        GL.glVertex3d(hexCoords[5][0], hexCoords[5][1],hexCoords[5][2] )
        GL.glEnd ()
        
        GL.glDisable(GL.GL_TEXTURE_2D)

    def draw_volume_boxes(self):
        """draws nested bounding boxes of volumes used in zoomvolumeCommands.py
        (applies the transformation matrix to the coords of the boxes)"""
        if len(self.volumesizes)>0:
            #ratio = 2 #same ratio used in newzoomCommands.py
            colors = [(1.0, 0.0, 0.0, 1.0),
                      (0.0, 0.0, 1.0, 1.0),
                      (1.0, 1.0, 1.0, 1.0)]
            GL.glDisable(GL.GL_TEXTURE_2D)
            GL.glDisable(GL.GL_LIGHTING)
            #mat = self.viewer.rootObject.GetMatrix()
            mat = self.masterObject.GetMatrix()
            if self.vliScalemat:
                scale=[]
                for i in range(4):
                    for j in range(4):
                        scale.append(self.vliScalemat[i][j])
                scale=Numeric.reshape(scale,(4,4))
                mat = Numeric.dot(mat,scale)
            rot = mat[:,:3]
            c = Numeric.reshape(Numeric.array([0.,0.,0.,1]),(4,1))
            rot = Numeric.concatenate((rot,c),1)
            tx, ty, tz = 0, 0, 0
            
#            if self.antialiased:
#                GL.glEnable(GL.GL_BLEND)
#                GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)
#                GL.glEnable (GL.GL_LINE_SMOOTH)
#                GL.glHint (GL.GL_LINE_SMOOTH_HINT, GL.GL_NICEST)
#            else:
            GL.glDisable(GL.GL_LINE_SMOOTH)
            
            ratio = 1
            for i in range(len(self.volumesizes)):
                (Vx, Vy, Vz) = self.volumesizes[-(i+1)]
                val = self.cropBox_list[-(i+1)]
                ratio = ratio*self.ratios[-(i+1)]
                #print "ratio", ratio
                tx = tx + ((Vx-(val[1]-val[0]))/2.-val[0])*ratio
                ty = ty + ((Vy-(val[3]-val[2]))/2.-val[2])*ratio
                tz = tz + ((Vz-(val[5]-val[4]))/2.-val[4])*ratio

                Vx = Vx/2.*ratio
                Vy = Vy/2.*ratio
                Vz = Vz/2.*ratio
                t = Numeric.array([tx, ty, tz, 1.])
##                  t = Numeric.dot(rot, t)[:3]+ \
##                      self.viewer.rootObject.translation
                t = Numeric.dot(rot, t)[:3]+ \
                    self.masterObject.translation                
                mat[:3,3] = t
                coords = Numeric.array([[Vx, Vy, Vz], [-Vx, Vy, Vz],
                                        [-Vx, -Vy, Vz], [Vx, -Vy, Vz],
                                        [Vx, Vy, -Vz], [-Vx, Vy, -Vz],
                                        [-Vx, -Vy, -Vz], [Vx, -Vy, -Vz]], 'f')
                one = Numeric.ones( (coords.shape[0], 1), 'f')
                c = Numeric.concatenate( (coords, one), 1 )
                mm = Numeric.dot( c, Numeric.transpose(mat) )
                
                
##                      GL.glColor3f(1.0, .0, .0)
                GL.glColor4f(colors[i][0], colors[i][1],
                             colors[i][2], colors[i][3])
                GL.glBegin(GL.GL_LINE_LOOP)
                GL.glVertex3f(mm[0][0], mm[0][1], mm[0][2])
                GL.glVertex3f(mm[1][0], mm[1][1], mm[1][2])
                GL.glVertex3f(mm[2][0], mm[2][1], mm[2][2])
                GL.glVertex3f(mm[3][0], mm[3][1], mm[3][2])
                GL.glEnd()
                
                GL.glBegin(GL.GL_LINE_LOOP)
                GL.glVertex3f(mm[4][0], mm[4][1], mm[4][2])
                GL.glVertex3f(mm[5][0], mm[5][1], mm[5][2])
                GL.glVertex3f(mm[6][0], mm[6][1], mm[6][2])
                GL.glVertex3f(mm[7][0], mm[7][1], mm[7][2])
                GL.glEnd()
                
                GL.glBegin(GL.GL_LINES)
                GL.glVertex3f(mm[0][0], mm[0][1], mm[0][2])
                GL.glVertex3f(mm[4][0], mm[4][1], mm[4][2])
                GL.glVertex3f(mm[1][0], mm[1][1], mm[1][2])
                GL.glVertex3f(mm[5][0], mm[5][1], mm[5][2])
                GL.glVertex3f(mm[2][0], mm[2][1], mm[2][2])
                GL.glVertex3f(mm[6][0], mm[6][1], mm[6][2])
                GL.glVertex3f(mm[3][0], mm[3][1], mm[3][2])
                GL.glVertex3f(mm[7][0], mm[7][1], mm[7][2])
                GL.glEnd()
                #ratio = ratio*2
#            GL.glEnable(GL.GL_TEXTURE_2D)
#            GL.glEnable(GL.GL_LIGHTING)
#            GL.glColor3f(1.0, 1.0, 1.0)




if __name__ == "__main__":
    import pdb
    from DejaVu import Viewer
    vi = Viewer()
    vliGeom = VLIGeom('vli', protected=1)
    vliGeom.masterObject=vi.rootObject
    vliGeom.viewer = vi
    # OBSOLETE
    vi.AddObject(vliGeom)
    vliGeom.LoadVolume('xaa.aypyd.vox')
