""" pygl/MG.py: CCP4MG Molecular Graphics Program Copyright (C) 2001-2008 University of York, CCLRC This library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 3, modified in accordance with the provisions of the license to address the requirements of UK law. You should have received a copy of the modified GNU Lesser General Public License along with this library. If not, copies may be downloaded from http://www.ccp4.ac.uk/ccp4license.php This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. """ import sys from joyevent import * from pygl_coord import * from opengl import * from point_funcs import * import eventdefs import time, threading import Queue import displayobject import util import jitter import Light import clip from image_info import * import string import math import cprim, pygl_coord import glevent import os #import font_cache import xmapview class cube: p0 = Cartesian(); p1 = Cartesian(); p2 = Cartesian(); p3 = Cartesian(); p4 = Cartesian(); p5 = Cartesian(); p6 = Cartesian(); p7 = Cartesian(); def __init__(self): pass def nullfunc(): pass class GLUTThread(threading.Thread): """ An OpenGL/Glut thread class. This class is a high level self-standing data instance which uses the GLUT API to open and control a window containing an OpenGL (or similar) context. Instances of the class are intended to run in their own threads: GRAPHICS_thread = MG.GLUTThread() GRAPHICS_thread.setDaemon(1) GRAPHICS_thread.start() """ NOGRAPHICS = 0 x = 0 y = 0 pid = os.getpid() title = "CCP4 Molecular Graphics Program" + str(pid) RADIUS = 60.0 drot = (0.0,0.0,0.0) quat = pygl_coord.Quat(0.0,0.0,0.0,0) win_w = 0; win_h = 0 screen_x, screen_y = 0,0 rocking = 0 resize = 0 glready = threading.Event() glpause = threading.Event() jq = Queue.Queue(0) rotscalex = 1.0; rotscaley = 1.0 movescalex = 1.0; movescaley = 1.0 joyscalex = 0.0001; joyscaley = 0.0001; joybuttons = {} PERSPECTIVE = 0 ORTHO = 1 viewsize = 20 xyratio = 1.0 rpos = [0.0, 0.0, 0.0] dx = 0; dy = 0; dz = 0 keyleft = GLUT_KEY_LEFT keyright = GLUT_KEY_RIGHT keyup = GLUT_KEY_UP keydown = GLUT_KEY_DOWN MOUSE = 1 KEYBOARD = 2 LEFT_MOTION = 3 RIGHT_MOTION = 4 MIDDLE_MOTION = 5 WHEEL_UP = 6 WHEEL_DOWN = 7 SPECIAL = 8 MENU = 9 JOYSTICK_AXIS = 10 KEYBOARD_UP = 11 BUTTON_PRESSED = LEFT_MOTION CENTRE_ON_PRIMITIVE = 0 LABEL_PRIMITIVE = 1 NOSTEREO = 0 REDBLUE = 1 REDGREEN = 2 REDCYAN = 3 BLUERED = 4 GREENRED = 5 CYANRED = 6 QUADBUFFER = 7 SIDEBYSIDE = 8 LEFTSTEREOONLY = 10 RIGHTSTEREOONLY = 9 SHIFT = 0 CTRL = 1 ALT = 2 ROTATION_STEREO=0 SHEAR_STEREO=1 stereo_view_style = ROTATION_STEREO stereo_view_style = SHEAR_STEREO screenshot_filename="screendump.ppm" ps_filename="screendump.ps" ps_paper = "A4" pov_filename="screendump.pov" dumpbitmap = 0 dumpps = 0 dumppov = 0 modifiers = [0,0,0] section = 0 start_width = 100; start_height = 100 rubber_band_start = (-5,-5) rubber_band_end = (start_width+5,start_height+5) rubber_band_box = cube() near_min = 1 far_max = 1000 fog_far_max = 2000 min_slab_delta=2.0 NEAR = near_min FAR = far_max FOG_START=25 FOG_END=90 fog_strength = 0 projectmode = ORTHO stereo_on = 0 stereo_mode = SIDEBYSIDE if stereo_view_style == ROTATION_STEREO: stereoseparation = 10; else: stereoseparation = 1.5; hardware_stereo_available = 0 stereo_angle = -6 shear = .02 antialias = 0 old_antialias = 0 antialias_screenshot = 0 ACSIZE=15 fog_on = 1 fog_density = 0.015 fog_mode = GL_EXP2 #fog_mode = GL_LINEAR lighting = 1 IMMEDIATE = 0 DISPLAYLISTS = 1 VERTEXARRAY = 2 #rendermode = IMMEDIATE rendermode = DISPLAYLISTS draw_symmetry = 0 symm_diff_colour = 0 multiview = 0 joy_x = 0 joy_y = 0 nframes = 0 previous_frames = nframes initial_time = time.time() previous_time = initial_time show_fps = 0 show_axes = 0 moving = 0 smooth_line = 1 smooth_polygons = 0 mouse_event = [] screen_box = "" do_exit = 0 reparented = 0 diagnostic = { 'opengl':0 } set_camera_glide = 1 set_camera_reset_radius = 1 set_camera_zoom_radius = 10.0 set_camera_time = 2.0 background_alpha = 1.0 redraw = 1 keyboard_is_active = 0 special_is_active = 0 offscreen_buffer = 0 onscreen_buffer = 0 mirror_buffers = 0 default_output_buffer = 0 offscreen_buffer_override = 0 use_transparency = 0 gl_renderer = '' update_matrices = 0 click_timer = threading.Timer(0.0,nullfunc) click_timer.start() axes_x = '' axes_y = '' axes_z = '' render_quality = 0 request_render_quality = 1 fsaa_on = 0 frame_count = '-1' idle_pause = 0.2 cue_text = 1 screenshot_width = -1 screenshot_height = -1 slab_width = 6 slab_on = 0 alpha_available = 0 weighted_zoom = 1 zoom_warp = 0.5 def IdleFunction(self): self.glpause.wait(3000) if self.section > 0 or self.moving or self.redraw == 1 or self.keyboard_is_active or self.special_is_active: glutPostRedisplay() else: time.sleep(self.idle_pause) def CheckErrors(self,info=""): err = glGetError() if err: if info: print info, print err; sys.stdout.flush() def setup_colour_pointers(self): import COLOUR white = COLOUR.COLOUR.insts.RGB("white") self.whitep = doublea(4) self.whitep[0] = white[0]; self.whitep[1] = white[1]; self.whitep[2] = white[2]; self.whitep[3] = white[3]; self.symcolp = [] excludes = ['green','red','blue','white','black','yellow'] exclude = [] next = COLOUR.COLOUR.insts.next('default') while exclude.count(next) == 0: exclude.append(next) next = COLOUR.COLOUR.insts.next(next) final = [] for col in exclude: if not excludes.count(col): rgb = COLOUR.COLOUR.insts.RGB(col) symcolp = doublea(4) symcolp[0] = rgb[0]; symcolp[1] = rgb[1]; symcolp[2] = rgb[2]; symcolp[3] = rgb[3]; self.symcolp.append(symcolp) def IsPointOnScreen(self,o): if sys.platform == "win32": self.screen_box = self.GetScreenBox() if self.screen_box == "": return 1 if len(self.screen_box)<8: return 1 screen_box = self.screen_box p1 = Plane(screen_box[0], screen_box[1], screen_box[2]) p2 = Plane(screen_box[1], screen_box[7], screen_box[5]) p3 = Plane(screen_box[7], screen_box[6], screen_box[5]) p4 = Plane(screen_box[6], screen_box[0], screen_box[2]) p5 = Plane(screen_box[3], screen_box[5], screen_box[2]) p6 = Plane(screen_box[1], screen_box[0], screen_box[6]) v = Volume() v.AddPlane(p1); v.AddPlane(p3); # We ignore p2 and p4, they are front and back, v.AddPlane(p5); v.AddPlane(p6); # since zooming will never point between them. return v.PointInVolume(Cartesian(-o[0],-o[1],-o[2])) def set_viewsize(self,viewsize=''): if viewsize: self.viewsize = viewsize def set_camera_origin(self,o_in='',radius='',zoom=0,plane=None,plane_up=None,set_camera_glide='',quat=None): #print "into set_camera_origin viewsize",self.viewsize set_quat = 0 if plane: quat_new = pygl_coord.Quat(plane.get_normal(),plane_up); quat_old = pygl_coord.Quat(self.quat) set_quat = 1 elif quat: quat_new = pygl_coord.Quat(quat) quat_old = pygl_coord.Quat(self.quat) set_quat = 1 if plane or quat: l1,l2= pygl_coord.Quat.Distance(quat_old,quat_new), pygl_coord.Quat.Distance(quat_old,-quat_new) if l2id: self.dl_lines.pop(id) if len(self.dl_solids)>id: self.dl_solids.pop(id) def registerqueue(self,jq='',interrupt=''): """ A function which tells the thread which Python Queue it is meant to push events to. """ if jq: self.jq = jq if interrupt: self.interruptq=interrupt self.glevent.registerqueue(jq=jq,interrupt=interrupt) def setup_clipping(self): if self.slab_on == 1: self.clip_planes[0].turn_on() self.clip_planes[1].turn_on() else: self.clip_planes[0].turn_off() self.clip_planes[1].turn_off() for plane in self.clip_planes: plane.apply() def initialize_clipping(self): self.clip_planes = [] self.clip_planes.append(clip.clipping(GL_CLIP_PLANE0)) self.clip_planes.append(clip.clipping(GL_CLIP_PLANE1)) self.clip_planes[0].eqn=(0,0,1,self.slab_width/2) self.clip_planes[1].eqn=(0,0,-1,self.slab_width/2) #self.clip_planes[0].turn_on() #self.clip_planes[1].turn_on() def get_lighting_params(self): params = [] for light in self.lights: params.append([light.on,light.position,light.ambient, \ light.specular,light.diffuse]) return params def set_lighting_params(self,params=[]): if params: i=0 done = min(len(self.lights),len(params)) for i in range(0, done): self.lights[i].position = params[i][1] self.lights[i].ambient = params[i][2] self.lights[i].specular = params[i][3] self.lights[i].diffuse = params[i][4] if params[i][0]: self.lights[i].turn_on() else: self.lights[i].turn_off() else: # default shiny self.lights[0].position = (0.0, 0.0, 60.0) self.lights[0].ambient = (0.0, 0.0, 0.0) self.lights[0].specular = (1.0, 1.0, 1.0) self.lights[0].diffuse = (1.0, 1.0, 1.0) self.lights[0].turn_on() #default soft self.lights[1].position = (0.0, 0.0, 60.0) self.lights[1].ambient = (0.2, 0.2, 0.2) self.lights[1].specular = (0.0, 0.0, 0.0) self.lights[1].diffuse = (0.7, 0.7, 0.7) self.lights[1].turn_off() #default shadowed self.lights[2].position = (-60.0,60.0,60.0) self.lights[2].ambient = (0.1, 0.1, 0.1) self.lights[2].specular = (0.7, 0.7, 0.7) self.lights[2].diffuse = (0.4, 0.4, 0.4) self.lights[2].turn_off() self.lights[3].position = (0.0,60.0,60.0) self.lights[3].ambient = (0.1, 0.1, 0.1) self.lights[3].specular = (0.7, 0.7, 0.7) self.lights[3].diffuse = (0.4, 0.4, 0.4) self.lights[3].turn_off() done = 4 ambient=(0.1, 0.1, 0.1) specular=(0.7, 0.7, 0.7) diffuse=(0.7, 0.7, 0.7) position=(60.0, 60.0, 60.0) for i in range(done,8): self.lights[i].position = position self.lights[i].ambient = ambient self.lights[i].specular = specular self.lights[i].diffuse = diffuse self.lights[i].turn_off() def initialize_lighting(self,params=[]): light_names = [GL_LIGHT0,GL_LIGHT1,GL_LIGHT2,GL_LIGHT3, \ GL_LIGHT4,GL_LIGHT5,GL_LIGHT6,GL_LIGHT7] self.lights = [] glEnable(GL_LIGHTING) ambient=(0.1, 0.1, 0.1) specular=(0.7, 0.7, 0.7) diffuse=(0.7, 0.7, 0.7) position=(60.0, 60.0, 60.0) for name in light_names: self.lights.append(Light.Light(name,position,ambient,specular,diffuse)) self.set_lighting_params(params=params) def setup_lighting(self): """ Setup OpenGL lighting model. """ if self.lighting > 0: glEnable(GL_LIGHTING); else: glDisable(GL_LIGHTING); return glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_TRUE) for light in self.lights: light.apply() def print_glinfo(self): """ Get OpenGL info. """ print "GL Vendor:", glbyte2str(glGetString(GL_VENDOR)) print "GL Renderer:", glbyte2str(glGetString(GL_RENDERER)) print "GL Version:", glbyte2str(glGetString(GL_VERSION)) print "GL Extensions:", glbyte2str(glGetString(GL_EXTENSIONS)) print "GLU Version:", glbyte2str(gluGetString(GLU_VERSION)) print "GLU Extensions:", glbyte2str(gluGetString(GLU_EXTENSIONS)) params = intp() glGetIntegerv(GL_MAX_CLIP_PLANES, params); print "Max clipping planes:",params.value() glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH, params); print "Max modelview stack depth:",params.value() glGetIntegerv(GL_AUX_BUFFERS, params); print "Auxiliary buffers",params.value() glGetIntegerv(GL_DOUBLEBUFFER, params); print "Double buffered:",params.value() glGetIntegerv(GL_ACCUM_RED_BITS, params); print "Accum red bits:",params.value() glGetIntegerv(GL_ACCUM_GREEN_BITS, params); print "Accum green bits:",params.value() glGetIntegerv(GL_ACCUM_BLUE_BITS, params); print "Accum blue bits:",params.value() glGetIntegerv(GL_ACCUM_ALPHA_BITS, params); print "Accum alpha bits:",params.value() def simple_orient(self): pass def run(self): if not self.glbroken: self.glutinit() self.stop = 0 self.glready.clear() self.window_id = GetGLUTWindowID(self.pid); if self.diagnostic['opengl']: print "GLUT Window ID is", self.window_id params = intp() glGetIntegerv(GL_STEREO, params); if params.value(): self.stereo_mode = self.QUADBUFFER self.hardware_stereo_available = 1 self.glready.set() self.glpause.set() if string.count(sys.version,"Red Hat Linux") and string.count(sys.version,"GCC 3.3.1") and string.count(sys.version,"2.2.3"): pass else: pass #glutHideWindow() glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE) glEnable(GL_COLOR_MATERIAL) glEnable(GL_DEPTH_TEST); glPolygonMode(GL_FRONT,GL_FILL) glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glHint(GL_LINE_SMOOTH_HINT,GL_NICEST); #glEnable(GL_CULL_FACE); #glCullFace(GL_BACK); self.initialize_clipping() self.initialize_lighting() self.setup_lighting() glMatrixMode(GL_PROJECTION); glLoadIdentity(); self.BuildPrimitiveDisplayList() if self.diagnostic['opengl']: self.print_glinfo() self.joys = OpenJoysticks(); self.gl_renderer = glbyte2str(glGetString(GL_RENDERER)) glutMainLoop(); def join(self,timeout=None): """ Stop the thread. Shouldn't ever get here. """ self.stop = 1; self._stopevent.set() self.glready.wait(3000) threading.Thread.join(self, timeout) def toggle_rocking(self): if self.rocking == 1: self.rocking = 0 else: self.rocking = 1 def CheckKeysAndMouseStatus(self): """ The idle function. Notices certain changes of state which have been triggered outside the thread and takes action within this thread. """ #print "CheckKeysAndMouseStatus",self.moving,self.mouse_event if not self.reparented: if sys.platform[:6] == 'irix64': self.window_id = GetGLUTWindowID(self.pid); if self.diagnostic['opengl']: print "GLUT Window ID is", self.window_id glut = self.window_id parent = GetParentWindow(glut) root = GetRootWindowID() if root != parent: self.redraw = 1 self.reparented = 1 self.changeSize(self.win_w,self.win_h) return if sys.platform != "win32": self.screen_box = self.GetScreenBox() if self.resize > 0: self.resize = 0 self.changeSize(self.win_w,self.win_h) self.redraw = 1 if self.joys and len(self.joys)>0: joyevent = GetJoystickEvent(self.joys[0]) self.joy_x = joyevent.axes[0] self.joy_y = joyevent.axes[1] self.joybuttons = joyevent.buttons if self.joy_x != 0 or self.joy_y != 0: if os.uname()[0] == 'Darwin': self.joy_x = self.joy_x * 32768/1200 # Better way? self.joy_y = self.joy_y * 32768/1200 binfo = {} binfo["x"] = self.joy_x binfo["y"] = self.joy_y binfo["window"] = glutGetWindow() binfo["joybuttons"] = self.joybuttons binfo["key_presses"] = self.key_presses job = [ self.JOYSTICK_AXIS, binfo ] self.glevent.glevent(job) self.redraw = 1 #glutPostRedisplay (); #if sys.platform == 'win32': #CheckKeys(self.key_presses) binfo={} binfo['screenx']=self.screen_x binfo['screeny']=self.screen_y key = 0 if self.keyboard_is_active == 1: for ii in range(self.key_presses.count(1)): key = self.key_presses[key:].index(1)+key job = [ self.KEYBOARD, key, self.mouse_x, self.mouse_y, self.modifiers,binfo ] key = key+1 self.glevent.glevent(job) key = 0 if self.keyboard_is_active == 1: for ii in range(self.key_presses.count(-1)): key = self.key_presses[key:].index(-1)+key job = [self.KEYBOARD_UP, key, self.mouse_x, self.mouse_y, self.modifiers,binfo ] self.key_presses[key]=0 key = key+1 self.glevent.glevent(job) key = 0 if self.special_is_active == 1: for ii in range(self.special_presses.count(1)): key = self.special_presses[key:].index(1)+key job = [ self.SPECIAL, key, self.mouse_x, self.mouse_y, self.modifiers,binfo ] self.glevent.glevent(job) key = key+1 key = 0 if self.special_is_active == 1: for ii in range(self.special_presses.count(-1)): key = self.special_presses[key:].index(-1)+key job = [self.SPECIAL_UP, key, self.mouse_x, self.mouse_y, self.modifiers,binfo ] self.special_presses[key]=0 self.glevent.glevent(job) key = key+1 if self.key_presses.count(1) == 0 and self.key_presses.count(-1) == 0: self.keyboard_is_active = 0 if self.special_presses.count(1) == 0 and self.special_presses.count(-1) == 0: self.special_is_active = 0 if self.do_exit: sys.exit() if self.moving: dx = self.mouse_x - self.start_x dy = self.mouse_y - self.start_y if dx or dy: self.SendMotionEvent(dx,dy,self.start_x,self.start_y) #glutPostRedisplay (); self.start_x = self.mouse_x self.start_y = self.mouse_y if self.redraw == 0: return self.redraw = 0 def buildlist(self,listid): """ This function does the business of turning display-object data containing primitives, and other stuff into display lists and auxiliary info. """ displayobj = self.displayobj[listid] if displayobj.BuildDisplayList() != 1: return glNewList(self.dl_lines[listid],GL_COMPILE) if self.stereo_on and self.stereo_mode != self.QUADBUFFER and self.stereo_mode != self.SIDEBYSIDE and self.stereo_mode != self.LEFTSTEREOONLY and self.stereo_mode != self.RIGHTSTEREOONLY: if displayobj.get_transparent() == 0: displayobj.draw_lines(self.whitep,0) else: if displayobj.get_transparent() == 0: displayobj.draw_lines("NULL",0) glEndList() glNewList(self.dl_solids[listid],GL_COMPILE) if self.stereo_on and self.stereo_mode != self.QUADBUFFER and self.stereo_mode != self.SIDEBYSIDE and self.stereo_mode != self.LEFTSTEREOONLY and self.stereo_mode != self.RIGHTSTEREOONLY: if displayobj.get_transparent() == 0: displayobj.draw_solids(self.whitep,0) else: if displayobj.get_transparent() == 0: displayobj.draw_solids("NULL",0) glEndList() def switch_projection(self): """ Switch between orthographic and perspective representations. """ if self.projectmode == self.PERSPECTIVE: self.projectmode = self.ORTHO else: self.projectmode = self.PERSPECTIVE self.changeSize(self.win_w,self.win_h) def toggle_antialiasing(self): if self.antialias > 0: self.antialias = 0 else: self.antialias = 2 def DrawRubberBand(self): glPushAttrib(GL_ENABLE_BIT|GL_CURRENT_BIT); # Draw Rubber Band glDisable(GL_LIGHTING) glColor3f(1-self.bgcolor[0],1-self.bgcolor[1],1-self.bgcolor[2]) glLineWidth(1.0); glBegin(GL_LINE_STRIP) glVertex3f(self.rubber_band_box.p0.get_x(),self.rubber_band_box.p0.get_y(),self.rubber_band_box.p0.get_z()) glVertex3f(self.rubber_band_box.p1.get_x(),self.rubber_band_box.p1.get_y(),self.rubber_band_box.p1.get_z()) glVertex3f(self.rubber_band_box.p2.get_x(),self.rubber_band_box.p2.get_y(),self.rubber_band_box.p2.get_z()) glVertex3f(self.rubber_band_box.p3.get_x(),self.rubber_band_box.p3.get_y(),self.rubber_band_box.p3.get_z()) glVertex3f(self.rubber_band_box.p0.get_x(),self.rubber_band_box.p0.get_y(),self.rubber_band_box.p0.get_z()) glEnd() glPopAttrib() def SetStereoMode(self,stereo_mode): if not self.hardware_stereo_available and stereo_mode == self.QUADBUFFER: return self.stereo_mode = stereo_mode if self.stereo_mode == self.LEFTSTEREOONLY or self.stereo_mode == self.RIGHTSTEREOONLY or self.stereo_mode == self.SIDEBYSIDE: if self.stereo_view_style == self.ROTATION_STEREO: self.stereoseparation = 5 else: self.stereoseparation = 1.5 else: if self.stereo_view_style == self.ROTATION_STEREO: self.stereoseparation = 10 else: self.stereoseparation = 1.5 for obj in self.displayobj: obj.rebuild() def SetAxes(self,axes_on): self.show_axes = axes_on self.redraw = 1 def SetFog(self,fog_on): self.fog_on = fog_on self.redraw = 1 def SetStereo(self,stereo_on): self.stereo_on = stereo_on for obj in self.displayobj: obj.rebuild() self.redraw = 1 def BuildPrimitiveDisplayList(self): col = doublea(4); col[0] = col[1] = col[2] = col[3] = 0.0 cprim.sphere(0,1.0,1) cprim.sphere(1,1.0,1) cprim.sphere(2,1.0,1) cprim.sphere(3,1.0,1) cprim.sphere(4,1.0,1) carts = CartesianVector() carts.append(Cartesian(0,0,0)) carts.append(Cartesian(0,0,1)) cprim.draw_cylinder(carts,1.0,4,0,1) cprim.draw_cylinder(carts,1.0,8,0,1) cprim.draw_cylinder(carts,1.0,16,0,1) cprim.draw_cylinder(carts,1.0,32,0,1) def SetDefaultOutputBuffer(self): self.offscreen_buffer = self.default_output_buffer self.offscreen_buffer_override = 0 def SetOffScreenBuffer(self,buffer): self.offscreen_buffer = buffer self.offscreen_buffer_override = 1 def BuildLists(self,force=0): rebuilt = 0 if self.rendermode == self.DISPLAYLISTS: i = 0 for obj in self.displayobj: if obj.get_rebuild() == 1 or force == 1: if i >= len(self.dl_lines): self.dl_lines.append(glGenLists(1)) self.dl_solids.append(glGenLists(1)) t1 = time.time() self.buildlist(len(self.dl_lines)-1) t2 = time.time() else: self.buildlist(i) obj.rebuild(0) rebuilt = 1 i = i + 1 self.rebuild_lists = 0 return rebuilt def CalculateJitter(self): xoff = 0 yoff = 0 acsize = 1 jarray = [(0.0,0.0)] acsize=self.ACSIZE jarray = jitter.get_jarray(acsize) if len(jarray) > 0: viewport = inta(4) glGetIntegerv(GL_VIEWPORT, viewport); xoff = 0.125*self.RADIUS/60.0 yoff = 0.125*self.RADIUS/60.0 else: acsize = 1 return acsize,xoff,yoff,jarray def Jitter(self,acsize,xoff,yoff,jarray,jit,axes): if acsize > 1: glTranslatef(jarray[jit][0]*xoff*axes[0].get_x(),jarray[jit][0]*xoff*axes[0].get_y(),jarray[jit][0]*xoff*axes[0].get_z()) glTranslatef(jarray[jit][1]*yoff*axes[1].get_x(),jarray[jit][1]*yoff*axes[1].get_y(),jarray[jit][1]*yoff*axes[1].get_z()) def SetTransparency(self,transparency=-1): self.rebuild_lists = 1 if transparency>=0: self.use_transparency = transparency def drawlists(self): """ Call the display lists and draw them at the correct position and orientation. """ glEnable(GL_NORMALIZE); rebuilt = self.BuildLists(self.rebuild_lists) #self.define_rubber_band_cube() if self.smooth_line: glEnable(GL_LINE_SMOOTH); glEnable(GL_POINT_SMOOTH); else: glDisable(GL_LINE_SMOOTH); glDisable(GL_POINT_SMOOTH); self.use_transparency = 0 for displayobj in self.displayobj: if displayobj.get_transparent() == 1: self.use_transparency = 1 break displayobj.move_origin() if self.fog_on: glEnable(GL_FOG) glPixelTransferi(GL_MAP_COLOR,GL_FALSE); glDisable(GL_TEXTURE_2D) glDisable(GL_BLEND) glEnable(GL_LIGHTING) glDepthMask(GL_TRUE); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glPolygonMode(GL_FRONT,GL_FILL); acsize, xoff, yoff, jarray = self.CalculateJitter() if self.antialias == 1 and self.use_transparency == 0: axes = self.getaxes() invacsize=1.0/acsize params = intp() for i in range(acsize): print "antialias step", i, "of", acsize; sys.stdout.flush() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) self.Jitter(acsize,xoff,yoff,jarray,i,axes) self.draw_solids(0) glAccum(GL_ACCUM,1./float(acsize)) glAccum(GL_RETURN,1.0) else: self.draw_solids(0) if self.antialias == 0 or self.use_transparency == 0: if self.smooth_line: glEnable(GL_BLEND) self.draw_lines(0) if self.use_transparency: if len(self.visibility_list)!=len(self.displayobj): self.visibility_list = [] rebuilt = 1 for ob in self.displayobj: self.visibility_list.append(ob.visible) else: iob=0 for ob in self.displayobj: if self.visibility_list[iob] != ob.visible: rebuilt = 1 break iob = iob + 1 if rebuilt: self.visibility_list = [] for ob in self.displayobj: self.visibility_list.append(ob.visible) if len(self.alpha_list)!=len(self.displayobj): self.alpha_list = [] rebuilt = 1 for ob in self.displayobj: self.alpha_list.append(ob.GetAlpha()) else: iob=0 for ob in self.displayobj: if ob.visible: if self.alpha_list[iob] != ob.GetAlpha(): rebuilt = 1 break iob = iob + 1 if rebuilt: self.alpha_list = [] for ob in self.displayobj: self.alpha_list.append(ob.GetAlpha()) if self.antialias != self.old_antialias: rebuilt = 1 axes = self.getaxes() # Hack needed because swig isn't up to converting [] to std::vector with derived objects it seems. cobjs = xmapview.DisplayobjectVector() for ob in self.displayobj: cobjs.append(ob) v = cprim.DoubleDoubleVector() for j in jarray: v.append(j) cprim.DrawSortedTransparentPrimitives(cobjs, acsize, xoff, yoff, v, axes, self.antialias, rebuilt) self.old_antialias = self.antialias self.draw(0) # Draws images only now. glDepthMask(GL_TRUE); glDisable(GL_BLEND); if not self.cue_text: glDisable(GL_FOG); glDisable(GL_LIGHTING); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDepthMask(GL_FALSE); glPixelTransferi(GL_MAP_COLOR,GL_TRUE); glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); # This puts the text at the front glDepthFunc(GL_ALWAYS); self.draw(0,text=1) self.nframes = self.nframes + 1 t = time.time() if t - self.previous_time > 1: fps = (self.nframes-self.previous_frames)/( time.time()-self.previous_time) fps_text = ( "%4.0f" ) % fps + ' fps' self.fps_prim.SetText(fps_text) self.previous_frames = self.nframes self.previous_time = t if self.show_fps > 0: if font_cache.FontCache().NumberOfFonts() > 0: self.fps_prim.draw() glDepthMask(GL_TRUE); glDisable(GL_BLEND); #self.DrawRubberBand() glFlush(); def DrawPostscript(self,psfilename="",paper=""): q = pygl_coord.Quat(self.quat) if psfilename != "": fname = psfilename else: fname = self.ps_filename if paper == "": paper = self.ps_paper import streams import psutil stream = streams.ofstream(fname) if paper == "BBox": ratio = self.xyratio* self.win_w / self.win_h xoff = 297 yoff = 421 leftbb = int(xoff - ratio * yoff) rightbb = int(xoff + ratio * yoff) bounding_box = "BoundingBox: " + str(leftbb) + " 0 " + str(rightbb) + " 843"; psutil.PSHeader(stream,fname,bounding_box) else: psutil.PSHeader(stream,fname,paper) """ if self.fog_on == 1: # We have to convert this into final transformed coords which zsortps uses. dist = .5*(self.FOG_START+self.FOG_END) fog_near = max(dist - self.viewsize,self.FOG_START) fog_far = min(dist + 2*self.viewsize,2*self.FOG_END) stream.Print("% FOG_START: "+str(fog_near)+"\n") stream.Print("% FOG_END: "+str(fog_far)+"\n") stream.Print("% FOG_DENSITY: "+str(float(self.fog_density))+"\n") print "NEAR",self.NEAR print "FAR",self.FAR """ for i in range(len(self.displayobj)): if self.displayobj[i].visible > 0: self.displayobj[i].DrawPostscript(stream,q,self.RADIUS,self.rpos[0],self.rpos[1],self.rpos[2]) if self.show_axes: x_axis = Cartesian(1,0,0) y_axis = Cartesian(0,1,0) z_axis = Cartesian(0,0,1) m = self.quat.getInvMatrix() x_axis = m * x_axis y_axis = m * y_axis z_axis = m * z_axis x_x = 530 + x_axis.get_x() * 40 x_y = 780 + x_axis.get_y() * 40 y_x = 530 + y_axis.get_x() * 40 y_y = 780 + y_axis.get_y() * 40 z_x = 530 + z_axis.get_x() * 40 z_y = 780 + z_axis.get_y() * 40 x_x_t = 530 + x_axis.get_x() * 50 x_y_t = 780 + x_axis.get_y() * 50 y_x_t = 530 + y_axis.get_x() * 50 y_y_t = 780 + y_axis.get_y() * 50 z_x_t = 530 + z_axis.get_x() * 50 z_y_t = 780 + z_axis.get_y() * 50 arrowrot = pygl_coord.Quat(0,0,1,1,5) x_arrow_p = arrowrot.getInvMatrix() * x_axis x_arrow_m = arrowrot.getMatrix() * x_axis y_arrow_p = arrowrot.getInvMatrix() * y_axis y_arrow_m = arrowrot.getMatrix() * y_axis z_arrow_p = arrowrot.getInvMatrix() * z_axis z_arrow_m = arrowrot.getMatrix() * z_axis x_arrow_p_x = 530 + x_arrow_p.get_x() * 35 x_arrow_p_y = 780 + x_arrow_p.get_y() * 35 x_arrow_m_x = 530 + x_arrow_m.get_x() * 35 x_arrow_m_y = 780 + x_arrow_m.get_y() * 35 y_arrow_p_x = 530 + y_arrow_p.get_x() * 35 y_arrow_p_y = 780 + y_arrow_p.get_y() * 35 y_arrow_m_x = 530 + y_arrow_m.get_x() * 35 y_arrow_m_y = 780 + y_arrow_m.get_y() * 35 z_arrow_p_x = 530 + z_arrow_p.get_x() * 35 z_arrow_p_y = 780 + z_arrow_p.get_y() * 35 z_arrow_m_x = 530 + z_arrow_m.get_x() * 35 z_arrow_m_y = 780 + z_arrow_m.get_y() * 35 stream.Print("1.0 slw n 530.000 780.000 m "+str(x_x)+" "+str(x_y)+" l cp 0 0 0 srgb s\n") stream.Print("1.0 slw n 530.000 780.000 m "+str(y_x)+" "+str(y_y)+" l cp 0 0 0 srgb s\n") stream.Print("1.0 slw n 530.000 780.000 m "+str(z_x)+" "+str(z_y)+" l cp 0 0 0 srgb s\n") stream.Print("/CenturySchoolbookL ff 16 scf sf "+str(x_x_t)+" "+str(x_y_t)+" m gs 1 1 sc (x) 0 0 0 srgb sh gr %TEXT\n") stream.Print("/CenturySchoolbookL ff 16 scf sf "+str(y_x_t)+" "+str(y_y_t)+" m gs 1 1 sc (y) 0 0 0 srgb sh gr %TEXT\n") stream.Print("/CenturySchoolbookL ff 16 scf sf "+str(z_x_t)+" "+str(z_y_t)+" m gs 1 1 sc (z) 0 0 0 srgb sh gr %TEXT\n") stream.Print("1.0 slw n "+str(x_arrow_p_x)+" "+str(x_arrow_p_y)+" m "+str(x_x)+" "+str(x_y)+" l "+str(x_arrow_m_x)+" "+str(x_arrow_m_y)+" l cp fill gs 0 0 0 srgb s gr\n") stream.Print("1.0 slw n "+str(y_arrow_p_x)+" "+str(y_arrow_p_y)+" m "+str(y_x)+" "+str(y_y)+" l "+str(y_arrow_m_x)+" "+str(y_arrow_m_y)+" l cp fill gs 0 0 0 srgb s gr\n") stream.Print("1.0 slw n "+str(z_arrow_p_x)+" "+str(z_arrow_p_y)+" m "+str(z_x)+" "+str(z_y)+" l "+str(z_arrow_m_x)+" "+str(z_arrow_m_y)+" l cp fill gs 0 0 0 srgb s gr\n") psutil.PSTail(stream) stream.Close() psutil.zsortps(fname,self.fog_on) def DrawPovRay(self,filename=""): q = pygl_coord.Quat(self.quat) if filename != "": fname = filename else: fname = self.pov_filename if os.path.exists(fname): os.remove(fname) fname_tmp = fname+'-tmp' if os.path.exists(fname_tmp): os.remove(fname_tmp) import streams stream = streams.ofstream(fname_tmp) stream.Print('#include "colors.inc"\n') stream.Print('camera {\n') stream.Print('orthographic location <0,0,-60>\n') #stream.Print('orthographic location <0,0,0>\n') ?? stream.Print('look_at <0,0,0>') stream.Print('up <0,'+str(self.viewsize*2*self.RADIUS/60)+',0>') stream.Print('right <'+str(self.viewsize*2*self.RADIUS/60*self.xyratio* self.win_w / self.win_h)+',0,0>') stream.Print('}\n') stream.Print('background { color rgb <' + str(self.bgcolor[0]) + ','+ str(self.bgcolor[1]) + ','+ str(self.bgcolor[2]) + '> }\n') for light in self.lights: if light.on > 0: stream.Print('light_source { <' + str(light.position[0]*10) + ',' + str(light.position[1]*10) + ',' + str(-light.position[2]*10) + '>color White}\n') if self.fog_on: if self.background_alpha > 0.1: stream.Print('fog { distance 100 colour rgb<'+ str(self.bgcolor[0]) + ','+ str(self.bgcolor[1]) + ','+ str(self.bgcolor[2]) + '> }\n') for i in range(len(self.displayobj)): if self.displayobj[i].visible > 0: self.displayobj[i].DrawPovRay(stream,q,self.RADIUS,self.rpos[0],self.rpos[1],self.rpos[2]) if self.show_axes: xpos = (self.viewsize*2*self.RADIUS/60*self.xyratio* self.win_w / self.win_h / 2.0) * 0.8 ypos = (self.viewsize*2*self.RADIUS/60 / 2.0) * 0.8 axo = pygl_coord.Cartesian(xpos,ypos,55) xax = pygl_coord.Cartesian((self.viewsize*2*self.RADIUS/60* self.win_w / self.win_h / 2.0) * 0.1,0,0) yax = pygl_coord.Cartesian(0,(self.viewsize*2*self.RADIUS/60* self.win_w / self.win_h / 2.0) * 0.1,0) zax = pygl_coord.Cartesian(0,0,(self.viewsize*2*self.RADIUS/60* self.win_w / self.win_h / 2.0) * 0.1) ax_width = 0.01 * (self.viewsize*2*self.RADIUS/60* self.win_w / self.win_h / 2.0) xaxp = q.getInvMatrix() * xax yaxp = q.getInvMatrix() * yax zaxp = q.getInvMatrix() * zax xaxend = axo + xaxp yaxend = axo + yaxp zaxend = axo + zaxp xaxend2 = axo + xaxp*1.5 yaxend2 = axo + yaxp*1.5 zaxend2 = axo + zaxp*1.5 colour_y = 0.299*float(self.bgcolor[0]) + 0.587*float(self.bgcolor[1]) + 0.114*float(self.bgcolor[2]) if colour_y>0.5: axes_col_label = ' pigment { color rgb <0, 0, 0> }\n' else: axes_col_label = ' pigment { color rgb <1, 1, 1> }\n' stream.Print('sphere {\n') stream.Print(' < '+str(xpos)+','+str(ypos)+',-55>\n') stream.Print(' '+str(ax_width)+'\n') stream.Print(' texture {\n') stream.Print(axes_col_label) stream.Print(' finish {diffuse 1.0 specular 1.0}\n') stream.Print(' }\n') stream.Print('}\n') stream.Print('cone {\n') stream.Print(' < '+str(xaxend.get_x())+','+str(xaxend.get_y())+',-55>,\n') stream.Print(' '+str(ax_width*2)+',\n') stream.Print(' < '+str(xaxend2.get_x())+','+str(xaxend2.get_y())+',-55>,\n') stream.Print(' 0\n') stream.Print(' texture {\n') stream.Print(axes_col_label) stream.Print(' finish {diffuse 1.0 specular 1.0}\n') stream.Print(' }\n') stream.Print('}\n') stream.Print('cone {\n') stream.Print(' < '+str(yaxend.get_x())+','+str(yaxend.get_y())+',-55>,\n') stream.Print(' '+str(ax_width*2)+',\n') stream.Print(' < '+str(yaxend2.get_x())+','+str(yaxend2.get_y())+',-55>,\n') stream.Print(' 0\n') stream.Print(' texture {\n') stream.Print(axes_col_label) stream.Print(' finish {diffuse 1.0 specular 1.0}\n') stream.Print(' }\n') stream.Print('}\n') stream.Print('cone {\n') stream.Print(' < '+str(zaxend.get_x())+','+str(zaxend.get_y())+',-55>,\n') stream.Print(' '+str(ax_width*2)+',\n') stream.Print(' < '+str(zaxend2.get_x())+','+str(zaxend2.get_y())+',-55>,\n') stream.Print(' 0\n') stream.Print(' texture {\n') stream.Print(axes_col_label) stream.Print(' finish {diffuse 1.0 specular 1.0}\n') stream.Print(' }\n') stream.Print('}\n') stream.Print('cylinder {\n') stream.Print(' < '+str(xpos)+','+str(ypos)+',-55>,\n') stream.Print(' < '+str(xaxend.get_x())+','+str(xaxend.get_y())+',-55>\n') stream.Print(' '+str(ax_width)+'\n') stream.Print(' texture {\n') stream.Print(axes_col_label) stream.Print(' finish {diffuse 1.0 specular 1.0}\n') stream.Print(' }\n') stream.Print('}\n') stream.Print('cylinder {\n') stream.Print(' < '+str(xpos)+','+str(ypos)+',-55>,\n') stream.Print(' < '+str(yaxend.get_x())+','+str(yaxend.get_y())+',-55>\n') stream.Print(' '+str(ax_width)+'\n') stream.Print(' texture {\n') stream.Print(axes_col_label) stream.Print(' finish {diffuse 1.0 specular 1.0}\n') stream.Print(' }\n') stream.Print('}\n') stream.Print('cylinder {\n') stream.Print(' < '+str(xpos)+','+str(ypos)+',-55>,\n') stream.Print(' < '+str(zaxend.get_x())+','+str(zaxend.get_y())+',-55>\n') stream.Print(' '+str(ax_width)+'\n') stream.Print(' texture {\n') stream.Print(axes_col_label) stream.Print(' finish {diffuse 1.0 specular 1.0}\n') stream.Print(' }\n') stream.Print('}\n') stream.Close() os.rename(fname_tmp,fname) fname_old = fname if len(fname)>4 and fname[len(fname)-4:]==".pov": fname = fname[:len(fname)-4] + "-pov.py" else: fname = fname + "-pov.py" if os.path.exists(fname): os.remove(fname) fname_tmp = fname+'-tmp' if os.path.exists(fname_tmp): os.remove(fname_tmp) stream = streams.ofstream(fname_tmp) stream.Print('import image_info\n') stream.Print('import sys\n') stream.Print('import math\n') stream.Print('if len(sys.argv)<2:\n') stream.Print(' print "Usage: "+sys.argv[0]+" rendered_file"\n') stream.Print(' print "eg "+sys.argv[0]+" myfile.png"\n') stream.Print(' sys.exit()\n') stream.Print('import font_cache\n') stream.Print('text_labels = []\n') stream.Print('image_labels = []\n') stream.Print("ok_font = ''\n") stream.Print('bad_fonts = []\n') for i in range(len(self.displayobj)): if self.displayobj[i].visible > 0: self.displayobj[i].OutputTextLabels(stream,q,self.RADIUS,self.rpos[0],self.rpos[1],self.rpos[2]) if self.show_axes: xax = pygl_coord.Cartesian(0.08,0,0) yax = pygl_coord.Cartesian(0,0.08,0) zax = pygl_coord.Cartesian(0,0,0.08) xaxp = q.getInvMatrix() * xax yaxp = q.getInvMatrix() * yax zaxp = q.getInvMatrix() * zax axo = pygl_coord.Cartesian(0.9,0.9,0.0) xaxend = axo + xaxp yaxend = axo + yaxp zaxend = axo + zaxp colour_y = 0.299*float(self.bgcolor[0]) + 0.587*float(self.bgcolor[1]) + 0.114*float(self.bgcolor[2]) if colour_y>0.5: axes_col_label = 'label["colour"]=[0,0,0]\n' else: axes_col_label = 'label["colour"]=[1,1,1]\n' stream.Print('label={}\n') stream.Print('label["position"]=['+str(xaxend.get_x())+','+str(xaxend.get_y())+']\n') stream.Print('font ={}\n') stream.Print('font["family"]="Century Schoolbook L"\n') stream.Print('font["weight"]="medium"\n') stream.Print('font["slant"]="r"\n') stream.Print('font["size"]="24"\n') stream.Print('label["font"]=font\n') stream.Print('label["text"]="x"\n') stream.Print(axes_col_label) stream.Print('text_labels.append(label)\n') stream.Print('label={}\n') stream.Print('label["position"]=['+str(yaxend.get_x())+','+str(yaxend.get_y())+']\n') stream.Print('font ={}\n') stream.Print('font["family"]="Century Schoolbook L"\n') stream.Print('font["weight"]="medium"\n') stream.Print('font["slant"]="r"\n') stream.Print('font["size"]="24"\n') stream.Print('label["font"]=font\n') stream.Print('label["text"]="y"\n') stream.Print(axes_col_label) stream.Print('text_labels.append(label)\n') stream.Print('label={}\n') stream.Print('label["position"]=['+str(zaxend.get_x())+','+str(zaxend.get_y())+']\n') stream.Print('font ={}\n') stream.Print('font["family"]="Century Schoolbook L"\n') stream.Print('font["weight"]="medium"\n') stream.Print('font["slant"]="r"\n') stream.Print('font["size"]="24"\n') stream.Print('label["font"]=font\n') stream.Print('label["text"]="z"\n') stream.Print(axes_col_label) stream.Print('text_labels.append(label)\n') stream.Print('iinfo = image_info.image_info(sys.argv[1])\n') stream.Print('new_name = "labelled"+sys.argv[1]\n') stream.Print('iinfo.write(new_name)\n') stream.Print('for image in image_labels:\n') stream.Print(' iinfo = image_info.image_info(new_name)\n') stream.Print(' overlay_iinfo = image_info.image_info(image["filename"])\n') stream.Print(' overlay_width = float(overlay_iinfo.get_width())\n') stream.Print(' overlay_height = float(overlay_iinfo.get_height())\n') stream.Print(' overlay_width = int(overlay_width * image["scale_w"])\n') stream.Print(' overlay_height = int(overlay_height * image["scale_h"])\n') stream.Print(' width = float(iinfo.get_width())\n') stream.Print(' height = float(iinfo.get_height())\n') stream.Print(' overlay_iinfo.invert()\n') stream.Print(' overlay_iinfo.ScaleImage(overlay_width,overlay_height)\n') stream.Print(' x = int(math.floor(width*image["position"][0]))\n') stream.Print(' y = int(math.floor(height*image["position"][1]))\n') stream.Print(' iinfo.invert()\n') stream.Print(' iinfo.Overlay(overlay_iinfo,x,y)\n') stream.Print(' iinfo.invert()\n') stream.Print(' iinfo.write(new_name)\n') stream.Print('font_cache.FontCache().LoadAllFonts()\n') stream.Print('for label in text_labels:\n') stream.Print(' iinfo = image_info.image_info(new_name)\n') stream.Print(' text = label["text"]\n') stream.Print(' colour = label["colour"]\n') stream.Print(' red = hex(int(colour[0]*255))[2:]\n') stream.Print(' green = hex(int(colour[1]*255))[2:]\n') stream.Print(' blue = hex(int(colour[2]*255))[2:]\n') stream.Print(' if len(red)==1: red = "0"+red\n') stream.Print(' if len(green)==1: green = "0"+green\n') stream.Print(' if len(blue)==1: blue = "0"+blue\n') stream.Print(' hex_colour = "#"+red+green+blue\n') stream.Print(' family = label["font"]["family"]\n') stream.Print(' weight = label["font"]["weight"]\n') stream.Print(' slant = label["font"]["slant"]\n') stream.Print(' size = int(label["font"]["size"])\n') stream.Print(' x = int(label["position"][0]*iinfo.get_width())\n') stream.Print(' y = iinfo.get_height()-int(label["position"][1]*iinfo.get_height())-size\n') stream.Print(' idx = -1\n') stream.Print(' try:\n') stream.Print(' idx=bad_fonts.index(label["font"])\n') stream.Print(' except:\n') stream.Print(' pass\n') stream.Print(' if idx >-1 and ok_font:\n') stream.Print(' finfo = ok_font\n') stream.Print(' else:\n') stream.Print(' finfo = font_cache.FontCache().GetFont("",family,weight,slant,"",size)\n') stream.Print(' if not finfo.isValid():\n') stream.Print(' bad_fonts.append(label["font"])\n') stream.Print(' finfo = font_cache.FontCache().GetFont(0)\n') stream.Print(' if finfo.isValid():\n') stream.Print(' if int(finfo.Size())==0:\n') stream.Print(' finfo2 = font_cache.FontCache().GetFont("",finfo.Family(),finfo.Weight(),finfo.Slant(),"",size)\n') stream.Print(' if int(finfo2.Size())==0:\n') stream.Print(' newsize = font_cache.FontCache().FindNextFontSize(finfo.Family(),finfo.Weight(),finfo.Slant(),12,1);\n') stream.Print(' finfo2 = font_cache.FontCache().GetFont("",finfo.Family(),finfo.Weight(),finfo.Slant(),"",newsize)\n') stream.Print(' if int(finfo2.Size())==0:\n') stream.Print(' print "Failed to load any font to overlay text labels"\n') stream.Print(' print "Maybe you need to set DISPLAY (if on Unix/Linux/Mac OS X)"\n') stream.Print(' sys.exit()\n') stream.Print(' finfo = finfo2\n') stream.Print(' ok_font = finfo\n') stream.Print(' iinfo2 = image_info.image_infoPtr(font_cache.OverlayTextOnImage(iinfo,finfo,x,y,text,hex_colour))\n') stream.Print(' iinfo2.write(new_name)\n') stream.Print(' else:\n') stream.Print(' print "Failed to load any font to overlay text labels"\n') stream.Print(' print "Maybe you need to set DISPLAY (if on Unix/Linux/Mac OS X)"\n') stream.Print(' sys.exit()\n') stream.Close() os.rename(fname_tmp,fname) def draw(self,transparent,text=0): q = pygl_coord.Quat(self.quat) for i in range(len(self.displayobj)): if self.displayobj[i].visible > 0: displayobj = self.displayobj[i] displayobj.camera_quat = q glPushMatrix() displayobj.ApplyTranslation() displayobj.ApplyRotation() if text > 0: displayobj.draw_text(q,self.RADIUS,self.rpos[0],self.rpos[1],self.rpos[2]) else: displayobj.draw_images() nsym = displayobj.GetNumSymmetryMatrices() symm_nos = displayobj.symm_nos symm_mat = MatrixVector(displayobj.symm_mat) if nsym>0 and len(symm_nos) == nsym and len(symm_mat) == nsym and self.draw_symmetry>0 and displayobj.GetDrawSymmetry(): for isym in range(nsym): glPushMatrix() glMultMatrixd(symm_mat[isym].Transpose().to_dp()) if text > 0: displayobj.draw_text(q,self.RADIUS,self.rpos[0],self.rpos[1],self.rpos[2]) else: displayobj.draw_images() glPopMatrix() glPopMatrix() def draw_lines(self,transparent,text=0): q = pygl_coord.Quat(self.quat) for i in range(len(self.displayobj)): if self.displayobj[i].visible > 0: displayobj = self.displayobj[i] displayobj.camera_quat = q glPushMatrix() displayobj.ApplyTranslation() displayobj.ApplyRotation() if text > 0: displayobj.draw_text(q,self.RADIUS,self.rpos[0],self.rpos[1],self.rpos[2]) else: if self.rendermode == self.DISPLAYLISTS and displayobj.BuildDisplayList() == 1: glCallList(self.dl_lines[i]) if self.rendermode == self.IMMEDIATE or displayobj.BuildDisplayList() == 0: if self.stereo_on and self.stereo_mode != self.QUADBUFFER and self.stereo_mode != self.SIDEBYSIDE and self.stereo_mode != self.LEFTSTEREOONLY and self.stereo_mode != self.RIGHTSTEREOONLY: displayobj.draw_lines(self.whitep,transparent) else: displayobj.draw_lines("NULL",transparent) nsym = displayobj.GetNumSymmetryMatrices() symm_nos = displayobj.symm_nos symm_mat = MatrixVector(displayobj.symm_mat) if displayobj.GetDrawUnitCell(): displayobj.DrawUnitCell() if nsym>0 and len(symm_nos) == nsym and len(symm_mat) == nsym and self.draw_symmetry>0 and displayobj.GetDrawSymmetry(): for isym in range(nsym): glPushMatrix() glMultMatrixd(symm_mat[isym].Transpose().to_dp()) if text > 0: displayobj.draw_text(q,self.RADIUS,self.rpos[0],self.rpos[1],self.rpos[2]) else: if self.rendermode == self.DISPLAYLISTS and displayobj.BuildDisplayList() == 1: if self.symm_diff_colour and displayobj.GetDrawSymmetryColoured(): if symm_nos[isym] < len(self.symcolp): displayobj.draw_lines(self.symcolp[symm_nos[isym]],transparent,1) else: displayobj.draw_lines(self.whitep,transparent,1) else: glCallList(self.dl_lines[i]) if self.rendermode == self.IMMEDIATE or displayobj.BuildDisplayList() == 0: if self.stereo_on and self.stereo_mode != self.QUADBUFFER and self.stereo_mode != self.SIDEBYSIDE and self.stereo_mode != self.LEFTSTEREOONLY and self.stereo_mode != self.RIGHTSTEREOONLY: displayobj.draw_lines(self.whitep,transparent) else: displayobj.draw_lines("NULL",transparent) glPopMatrix() glPopMatrix() def draw_solids(self,transparent,text=0): q = pygl_coord.Quat(self.quat) for i in range(len(self.displayobj)): if self.displayobj[i].visible > 0: displayobj = self.displayobj[i] displayobj.camera_quat = q glPushMatrix() displayobj.ApplyTranslation() displayobj.ApplyRotation() if text > 0: displayobj.draw_text(q,self.RADIUS,self.rpos[0],self.rpos[1],self.rpos[2]) else: if self.rendermode == self.DISPLAYLISTS and displayobj.BuildDisplayList() == 1: glCallList(self.dl_solids[i]) if self.rendermode == self.IMMEDIATE or displayobj.BuildDisplayList() == 0: cprim.RenderQuality.SetRenderQuality(self.render_quality) if self.stereo_on and self.stereo_mode != self.QUADBUFFER and self.stereo_mode != self.SIDEBYSIDE and self.stereo_mode != self.LEFTSTEREOONLY and self.stereo_mode != self.RIGHTSTEREOONLY: displayobj.draw_solids(self.whitep,transparent) else: displayobj.draw_solids("NULL",transparent) cprim.RenderQuality.SetRenderQuality(0) nsym = displayobj.GetNumSymmetryMatrices() symm_nos = displayobj.symm_nos symm_mat = MatrixVector(displayobj.symm_mat) """ if displayobj.GetDrawUnitCell(): displayobj.DrawUnitCell() """ if nsym>0 and len(symm_nos) == nsym and len(symm_mat) == nsym and self.draw_symmetry>0 and displayobj.GetDrawSymmetry(): for isym in range(nsym): glPushMatrix() glMultMatrixd(symm_mat[isym].Transpose().to_dp()) if text > 0: displayobj.draw_text(q,self.RADIUS,self.rpos[0],self.rpos[1],self.rpos[2]) else: if self.rendermode == self.DISPLAYLISTS and displayobj.BuildDisplayList() == 1: if self.symm_diff_colour and displayobj.GetDrawSymmetryColoured(): if symm_nos[isym] < len(self.symcolp): displayobj.draw_solids(self.symcolp[symm_nos[isym]],transparent,1) else: displayobj.draw_solids(self.whitep,transparent,1) else: glCallList(self.dl_solids[i]) if self.rendermode == self.IMMEDIATE or displayobj.BuildDisplayList() == 0: cprim.RenderQuality.SetRenderQuality(self.render_quality) if self.stereo_on and self.stereo_mode != self.QUADBUFFER and self.stereo_mode != self.SIDEBYSIDE and self.stereo_mode != self.LEFTSTEREOONLY and self.stereo_mode != self.RIGHTSTEREOONLY: displayobj.draw_solids(self.whitep,transparent) else: displayobj.draw_solids("NULL",transparent) cprim.RenderQuality.SetRenderQuality(0) glPopMatrix() glPopMatrix() def setmaxviewsize(self,size): """ Get info about how big the viewport should be and request resizing. """ if size != self.viewsize: self.viewsize = size self.resize = 1 def UnDefineSlab(self): self.slab_on = 0 self.clip_planes[0].turn_off() self.clip_planes[1].turn_off() self.redraw = 1 """ def DefineFog(self,near='',far='',**keywords): print "Define Fog",near,far if far: far = float(far) if near: self.FOG_END = max(min(far,self.fog_far_max),float(near)+self.near_min) else: self.FOG_END = max(min(far,self.fog_far_max),self.FOG_START+self.min_slab_delta) if near: self.FOG_START = min(max(float(near),1.0),self.FOG_END-self.min_slab_delta) self.resize = 1 """ def DefineSlab(self,width='',turn_on='',**keywords): if turn_on and int(turn_on) == 1: self.slab_on = 1 if width: self.slab_width = float(width) self.clip_planes[0].eqn=(0,0,1,self.slab_width/2) self.clip_planes[1].eqn=(0,0,-1,self.slab_width/2) self.redraw = 1 def MoveSlab(self,dist): # We need another thing, slab depth, but somewhat redundant. pass def ExpandSlab(self,delta): delta = float(delta) self.slab_width = self.slab_width + delta self.DefineSlab(self.slab_width) def GetWindowSize(self): return [self.win_w,self.win_h] def set_default_clip_planes(self,near,far): self.NEAR = near self.FAR = far self.resize = 1 def SetScreenSection(self,section,w,h): ratio = self.xyratio*w/h glMatrixMode(GL_PROJECTION); glLoadIdentity(); glViewport(0, 0, w, h); if self.projectmode == self.PERSPECTIVE: gluPerspective(45,ratio,self.NEAR,self.FAR); # This is obvious nonsense. if self.projectmode == self.ORTHO: if section == -1: glOrtho(-self.viewsize*ratio,self.viewsize*ratio, -self.viewsize,self.viewsize,self.NEAR,self.FAR); #glOrtho(-self.viewsize*ratio,self.viewsize*ratio, -self.viewsize,self.viewsize,self.NEAR,self.FAR); else: nsec = int(math.sqrt(self.dumpbitmap)) j = section / nsec i = section - section / nsec * nsec maxdim_x = self.viewsize*ratio*2 / nsec * nsec maxdim_y = self.viewsize*2 / nsec * nsec xstart = i * maxdim_x / nsec - maxdim_x / 2 xend = (i+1) * maxdim_x / nsec - maxdim_x / 2 ystart = j * maxdim_y / nsec - maxdim_y / 2 yend = (j+1) * maxdim_y / nsec - maxdim_y / 2 glOrtho(xstart,xend, ystart,yend,self.NEAR,self.FAR); #glOrtho(xstart,xend, ystart,yend,self.NEAR,self.FAR); def changeSize(self,w,h): """ OpenGL resize callback function. """ # FOG_START, NEAR problem with slabbing !!!! if h == 0: h = 1 if w == 0: w = 1 ratio = self.xyratio* w / h glMatrixMode(GL_PROJECTION); glLoadIdentity(); glViewport(0, 0, w, h); if self.projectmode == self.PERSPECTIVE: gluPerspective(45,ratio,self.NEAR,self.FAR); if self.projectmode == self.ORTHO: glOrtho(-self.viewsize*ratio,self.viewsize*ratio,-self.viewsize,self.viewsize,self.NEAR,self.FAR); #glOrtho(-self.viewsize*ratio,self.viewsize*ratio,-self.viewsize,self.viewsize,self.NEAR,self.FAR); cprim.BillBoardText().SetMatrices() self.movescalex = 2.0 * float(self.viewsize)/float(h) * float(self.RADIUS)/60.0 self.movescaley = 2.0 * float(self.viewsize)/float(h) * float(self.RADIUS)/60.0 self.rotscalex = 0.5 * 1280/w self.rotscaley = 0.5 * 1024/h self.set_rubber_band_start(-5,-5) self.set_rubber_band_end(w+5,h+5) self.win_w = w self.win_h = h if self.gl_renderer.find("Mesa DRI") > -1: a = dir(os) try: a.index('uname') renderer_string = "\"OpenGL renderer string:\"" command = "glxinfo| grep "+renderer_string+"|grep -q \""+"Mesa DRI Intel(R) 945GM 20050225 x86/MMX/SSE2"+"\"" rc1 = os.system(command) if not rc1: return except: return if self.default_output_buffer: del self.default_output_buffer self.default_output_buffer = 0 self.default_output_buffer = OffScreenBuffer(self.win_w, self.win_h) if self.offscreen_buffer_override == 0: self.offscreen_buffer = self.default_output_buffer glutPostRedisplay() def applystereoshear(self,obj): """ Apply the quaternion rotation +- a small variation to get two rotation matrices which will be used to rotate the stereo pair. Also apply the mean rotation to the actual display list. """ quat = obj.quat; drot = obj.drot rotQ = pygl_coord.Quat(drot[0],drot[1],drot[2],0) quat.postMult(rotQ) glrotmat = quat.getMatrix() glrotmat1, glrotmat2 = pygl_coord.matrix(glrotmat), pygl_coord.matrix(glrotmat) shear_plus = pygl_coord.matrix(4,4,[1,0,0,0, 0,1,0,0, -0.1,0,1,0, 0,0,0,1]) shear_minus = pygl_coord.matrix(4,4,[1,0,0,0, 0,1,0,0, 0.1,0,1,0, 0,0,0,1]) glrotmat1 = glrotmat*shear_plus glrotmat2 = glrotmat*shear_minus return glrotmat1, glrotmat2 def applystereorotation(self,obj): """ Apply the quaternion rotation +- a small variation to get two rotation matrices which will be used to rotate the stereo pair. Also apply the mean rotation to the actual display list. """ quat = obj.quat; drot = obj.drot rotQ = pygl_coord.Quat(0,self.stereo_angle,0,0) quat.postMult(rotQ) glrotmat1 = quat.getMatrix() rotQ = pygl_coord.Quat(0,-2*self.stereo_angle,0,0) quat.postMult(rotQ) glrotmat2 = quat.getMatrix() rotQ = pygl_coord.Quat(drot[0],drot[1]+self.stereo_angle,drot[2],0) quat.postMult(rotQ) return glrotmat1, glrotmat2 def copyrotation(self,obj1,obj2): """ Copy one objects quaternion representation to another. Probably should be in displayobject class .... """ obj2.quat.dval = [] obj2.quat.dval.append(obj1.quat.dval[0]) obj2.quat.dval.append(obj1.quat.dval[1]) obj2.quat.dval.append(obj1.quat.dval[2]) obj2.quat.dval.append(obj1.quat.dval[3]) def resetrotation(self,obj): """ Reset an objects quaternion representation to the unit representation. """ obj.quat.dval = [1.0, 0.0, 0.0, 0.0 ] def applyorthorotations(self,obj): """ Apply the rotation to the world's quaternion and return the corresponding rotation matrix for the OpenGL transformations. """ quatx = pygl_coord.Quat( 1,0,0,1,90) quaty = pygl_coord.Quat( 0,1,0,1,90) quat = obj.quat; drot = obj.drot rotQ = pygl_coord.Quat(drot[0],drot[1],drot[2],0) quat.postMult(rotQ) quat2x = pygl_coord.Quat(quat) quat2x.postMult(quatx) quat2y = pygl_coord.Quat(quat) quat2y.postMult(quaty) glrotmat = quat.getMatrix() glrotmatx = quat2x.getMatrix() glrotmaty = quat2y.getMatrix() return glrotmat, glrotmatx, glrotmaty def applyrotation(self,obj): """ Apply the rotation to the world's quaternion and return the corresponding rotation matrix for the OpenGL transformations. """ quat = obj.quat; drot = obj.drot rotQ = pygl_coord.Quat(drot[0],drot[1],drot[2],0) quat.postMult(rotQ) glrotmat = quat.getMatrix() return glrotmat def getaxes(self): """ Return the eyes' x,y and z axes. """ dum = self.getxyz(float(self.win_w/2),float(self.win_h/2)) xyzo = dum[1] xyzf = dum[0] dum2 = self.getxyz(float(self.win_w),float(self.win_h/2)) xyzr = dum2[1] dum3 = self.getxyz(float(self.win_w/2),float(self.win_h)) xyzu = dum3[1] xaxis = xyzr - xyzo yaxis = xyzu - xyzo zaxis = xyzf - xyzo xaxis.normalize() yaxis.normalize() zaxis.normalize() return xaxis,yaxis,zaxis def setup_fog(self): self.FOG_START = self.NEAR # Temporary self.FOG_END = self.FAR #print "setup_fog",self.FOG_START,self.FOG_END, self.viewsize """ Apply fog. """ if self.fog_on == 0: glDisable(GL_FOG) return dist = .5*(self.FOG_START+self.FOG_END) #fog_near = max(dist - self.viewsize,self.FOG_START) #fog_far = min(dist + 2*self.viewsize,2*self.FOG_END) fog_near = max(dist - ((20.*self.slab_width)/self.RADIUS), self.FOG_START) fog_strength = min(self.fog_strength,0.99) fog_far = min(dist + ((40.*self.slab_width)/self.RADIUS), self.FOG_END) - fog_strength * self.slab_width #print self.viewsize, dist, fog_near, fog_far, self.RADIUS glEnable(GL_FOG) fogcolour = newfv4(self.bgcolor[0],self.bgcolor[1],self.bgcolor[2],self.bgcolor[3]) #glFogi(GL_FOG_MODE,self.fog_mode) glFogi(GL_FOG_MODE,GL_LINEAR) glFogfv(GL_FOG_COLOR, fogcolour) #glFogf(GL_FOG_DENSITY,float(self.fog_density)) glFogf(GL_FOG_START,fog_near) glFogf(GL_FOG_END,fog_far) #glFogf(GL_FOG_START, self.NEAR) #glFogf(GL_FOG_END, self.FAR) #glFogf(GL_FOG_START,self.FOG_START) #glFogf(GL_FOG_END,self.FOG_END) delcGLfp(fogcolour) def set_colourmask(self,eye): """ Determine and set the colour mask for each eye when doing colour filter stereo. """ glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); if eye == "left": if self.stereo_mode == self.REDBLUE or self.stereo_mode == self.REDGREEN or self.stereo_mode == self.REDCYAN: glColorMask(GL_TRUE,GL_FALSE,GL_FALSE,GL_TRUE); if self.stereo_mode == self.BLUERED: glColorMask(GL_FALSE,GL_FALSE,GL_TRUE,GL_TRUE); if self.stereo_mode == self.GREENRED: glColorMask(GL_FALSE,GL_TRUE,GL_FALSE,GL_TRUE); if self.stereo_mode == self.CYANRED: glColorMask(GL_FALSE,GL_TRUE,GL_TRUE,GL_TRUE); else: if self.stereo_mode == self.REDBLUE: glColorMask(GL_FALSE,GL_FALSE,GL_TRUE,GL_TRUE); if self.stereo_mode == self.REDGREEN: glColorMask(GL_FALSE,GL_TRUE,GL_FALSE,GL_TRUE); if self.stereo_mode == self.REDCYAN: glColorMask(GL_FALSE,GL_TRUE,GL_TRUE,GL_TRUE); if self.stereo_mode == self.BLUERED or self.stereo_mode == self.GREENRED or self.stereo_mode == self.CYANRED: glColorMask(GL_TRUE,GL_FALSE,GL_FALSE,GL_TRUE); def DrawAxes(self,glrotmat,w,h): glDisable(GL_CLIP_PLANE0) glDisable(GL_CLIP_PLANE1) glPushMatrix() glLoadIdentity() glDepthFunc(GL_ALWAYS); glDisable(GL_BLEND); glDisable(GL_LIGHTING) if self.smooth_line: glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_LINE_SMOOTH); else: glDisable(GL_LINE_SMOOTH); glColor3f(1-self.bgcolor[0],1-self.bgcolor[1],1-self.bgcolor[2]) ratio = self.xyratio* w / h scale_x = self.viewsize*ratio scale_y = self.viewsize glTranslatef(0,0,-40) glScalef(self.viewsize,self.viewsize,self.viewsize); glTranslatef(0.8*ratio,0.8,0) matp1 = glrotmat.to_dp() glMultMatrixd(matp1) deldp(matp1) glLineWidth(1.0); glBegin(GL_LINES) glVertex3f(0,0,0) glVertex3f(0.1,0,0) glVertex3f(0,0,0) glVertex3f(0,0.1,0) glVertex3f(0,0,0) glVertex3f(0,0,0.1) glVertex3f(0.1,0,0) glVertex3f(0.08,0.01,0) glVertex3f(0.1,0,0) glVertex3f(0.08,-0.01,0) glVertex3f(0,0.1,0) glVertex3f(0.01,0.08,0) glVertex3f(0,0.1,0) glVertex3f(-0.01,0.08,0) glVertex3f(0,0,0.1) glVertex3f(0.01,0,0.08) glVertex3f(0,0,0.1) glVertex3f(-0.01,0,0.08) glEnd() glDisable(GL_FOG); glDisable(GL_LIGHTING); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glPixelTransferi(GL_MAP_COLOR,GL_TRUE); glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); if font_cache.FontCache().NumberOfFonts() > 0 and (not self.axes_x or not self.axes_y or not self.axes_z): cart = pygl_coord.Cartesian(0.13,0,0) self.axes_x = cprim.Text(pygl_coord.Cartesian(0.13,0,0),'x',cart) self.axes_x.SetFontSize(18) cart = pygl_coord.Cartesian(0,0.13,0) self.axes_y = cprim.Text(pygl_coord.Cartesian(0,0.13,0),'y',cart) self.axes_y.SetFontSize(18) cart = pygl_coord.Cartesian(0,0,0.13) self.axes_z = cprim.Text(pygl_coord.Cartesian(0,0,0.13),'z',cart) self.axes_z.SetFontSize(18) if self.axes_x and self.axes_y and self.axes_z: self.axes_x.SetColour(1-self.bgcolor[0],1-self.bgcolor[1],1-self.bgcolor[2],1) self.axes_x.draw() self.axes_y.draw() self.axes_z.draw() glPopMatrix() glDepthFunc(GL_LESS); def draw_scene(self,w,h): glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if self.NEAR> 60 or self.FAR < 60 or (self.FAR-self.NEAR)<60 or 1: dist = .5*(self.NEAR+self.FAR) else: dist = 60 glTranslatef(0,0,-dist) if self.projectmode == self.ORTHO: glScalef(60.0/float(self.RADIUS),60.0/float(self.RADIUS),60.0/float(self.RADIUS)) #glTranslatef(0,0,-.5*(self.NEAR+self.FAR)) #print self.NEAR,self.FAR,.5*(self.NEAR+self.FAR),self.slab_width, self.RADIUS, self.rpos[2] self.setup_lighting() self.setup_clipping() self.setup_fog() glClearColor(self.bgcolor[0],self.bgcolor[1],self.bgcolor[2],self.background_alpha) if self.antialias: if self.hardware_stereo_available == 1: if self.stereo_on > 0: glDrawBuffer (GL_BACK_LEFT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT) glDrawBuffer (GL_BACK_RIGHT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT) else: glDrawBuffer (GL_BACK); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT) else: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT) else: if self.hardware_stereo_available == 1: if self.stereo_on > 0: glDrawBuffer (GL_BACK_LEFT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) glDrawBuffer (GL_BACK_RIGHT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) else: glDrawBuffer (GL_BACK); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) else: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); if self.stereo_on > 0: if self.stereo_view_style == self.SHEAR_STEREO: glrotmat1, glrotmat2 = self.applystereoshear(self) else: glrotmat1, glrotmat2 = self.applystereorotation(self) matp1 = glrotmat1.to_dp() glMultMatrixd(matp1) deldp(matp1) self.xaxis,self.yaxis,self.zaxis = self.getaxes() self.rpos = self.movexyz(self.rpos,(self.dx,self.dy,self.dz)) self.calculate_extents() glTranslatef(self.rpos[0],self.rpos[1],self.rpos[2]) stereoseparation = self.stereoseparation if self.stereo_mode == self.QUADBUFFER: stereoseparation = 0 stereox,stereoy,stereoz = self.movexyz((0,0,0),(self.RADIUS/60.0*float(stereoseparation),0.0,0.0)) glTranslatef(stereox,stereoy,stereoz) if self.stereo_mode == self.REDBLUE or self.stereo_mode == self.REDGREEN or self.stereo_mode == self.REDCYAN: self.set_colourmask("left") if self.stereo_mode != self.LEFTSTEREOONLY: self.drawlists() if self.stereo_mode == self.REDBLUE or self.stereo_mode == self.REDGREEN or self.stereo_mode == self.REDCYAN: glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if self.NEAR> 60 or self.FAR < 60 or (self.FAR-self.NEAR)<60 or 1: dist = .5*(self.NEAR+self.FAR) else: dist = 60 glTranslatef(0,0,-dist) if self.projectmode == self.ORTHO: glScalef(60.0/float(self.RADIUS),60.0/float(self.RADIUS),60.0/float(self.RADIUS)) matp2 = glrotmat2.to_dp() glMultMatrixd(matp2) deldp(matp2) self.xaxis,self.yaxis,self.zaxis = self.getaxes() glTranslatef(self.rpos[0],self.rpos[1],self.rpos[2]) stereox,stereoy,stereoz = self.movexyz((0,0,0),(self.RADIUS/60.0*float(-stereoseparation),0.0,0.0)) glTranslatef(stereox,stereoy,stereoz) if self.stereo_mode != self.QUADBUFFER: glClear(GL_DEPTH_BUFFER_BIT); if self.stereo_mode == self.REDBLUE or self.stereo_mode == self.REDGREEN or self.stereo_mode == self.REDCYAN: self.set_colourmask("right") if self.stereo_mode == self.QUADBUFFER: glDrawBuffer (GL_BACK_LEFT); glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT) if self.stereo_mode != self.RIGHTSTEREOONLY: self.drawlists() if self.stereo_mode == self.REDBLUE or self.stereo_mode == self.REDGREEN or self.stereo_mode == self.REDCYAN: glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); if self.show_axes and self.stereo_mode != self.QUADBUFFER: self.DrawAxes((glrotmat1+glrotmat2)*0.5,w,h) if self.show_axes and self.stereo_mode == self.QUADBUFFER: self.DrawAxes(glrotmat1,w,h) self.DrawAxes(glrotmat2,w,h) else: #print "orient applying drot",self.drot glrotmat = self.applyrotation(self) matp = glrotmat.to_dp() glMultMatrixd(matp) deldp(matp) self.xaxis,self.yaxis,self.zaxis = self.getaxes() self.rpos = self.movexyz(self.rpos,(self.dx,self.dy,self.dz)) self.calculate_extents() glTranslatef(self.rpos[0],self.rpos[1],self.rpos[2]) self.drawlists() if self.show_axes: self.DrawAxes(glrotmat,w,h) self.setup_clipping() # So that the setting can be picked up by screen grabs, etc. def orient(self): self.CheckKeysAndMouseStatus() if self.dumpbitmap and self.request_render_quality: self.rebuild_lists = 1 self.render_quality = 1 self.rendermode = self.IMMEDIATE else: self.rendermode = self.DISPLAYLISTS if self.dumpbitmap and self.offscreen_buffer: if sys.platform != "win32": screen_width=glutGet(GLUT_SCREEN_WIDTH) screen_height=glutGet(GLUT_SCREEN_HEIGHT) if self.offscreen_buffer.GetWidth() > screen_width or self.offscreen_buffer.GetHeight() > screen_height: ntiles_w = (self.offscreen_buffer.GetWidth()+screen_width-1)/screen_width ntiles_h = (self.offscreen_buffer.GetHeight()+screen_height-1)/screen_height ntiles = max(ntiles_w,ntiles_h) new_width = self.offscreen_buffer.GetWidth()/ntiles new_height = self.offscreen_buffer.GetHeight()/ntiles self.dumpbitmap = ntiles*ntiles self.offscreen_buffer = OffScreenBuffer(new_width,new_height) self.setup_lighting() self.setup_clipping() self.setup_fog() ratio = self.xyratio* self.offscreen_buffer.GetWidth() / self.offscreen_buffer.GetHeight() self.offscreen_buffer.MakeCurrent() glEnable(GL_COLOR_MATERIAL) glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE) glEnable(GL_NORMALIZE); glHint(GL_LINE_SMOOTH_HINT,GL_NICEST); cprim.ForceLoadTextures() glEnable(GL_DEPTH_TEST); glPolygonMode(GL_FRONT,GL_FILL); glMatrixMode(GL_PROJECTION); glLoadIdentity(); self.BuildPrimitiveDisplayList() glViewport(0, 0, self.offscreen_buffer.GetWidth(), self.offscreen_buffer.GetHeight() ); glOrtho(-self.viewsize*ratio,self.viewsize*ratio,-self.viewsize,self.viewsize,max(self.FOG_START,self.NEAR),min(self.FOG_END+self.viewsize,self.FAR)); w = self.offscreen_buffer.GetWidth(); h = self.offscreen_buffer.GetHeight() cprim.BillBoardText().SetMatrices() # Always do this incase we have a new context self.rebuild_lists = 1 glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glPolygonMode(GL_FRONT,GL_FILL) glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); else: w = self.win_w; h = self.win_h if self.update_matrices: cprim.BillBoardText().SetMatrices() self.update_matrices = 0 if self.stop == 1: return self.CheckErrors("CheckErrors at start of orient") """ OpenGL display callback function. This does world/camera positioning and orientation and all basic initializations before drawing everything. Also sets up the stereo pair views as required. """ self.glready.clear() orig_anti = self.antialias if self.dumpbitmap > 0: if self.antialias_screenshot: self.antialias = 1 if self.dumpbitmap > 1: if self.section == self.dumpbitmap: self.dumpbitmap = 0 self.section = 0 self.SetScreenSection(-1,w,h) self.idle_pause = self.old_idle_pause elif self.dumpbitmap != 0: self.SetScreenSection(self.section,w,h) self.draw_scene(w,h) if self.dumpbitmap and self.offscreen_buffer and self.mirror_buffers: self.onscreen_buffer.MakeCurrent() self.draw_scene(w,h) # and we'll have to swap buffers if this is a double buffer ... self.dx = 0 self.dy = 0 self.dz = 0 self.drot = (0.0,0.0,0.0) if self.dumpbitmap > 1: if self.offscreen_buffer == 0 and sys.platform == "darwin": glReadBuffer(GL_BACK) #self.redraw = 1 # Hmm, might I need this? self.screenshot() self.section = self.section + 1 if self.offscreen_buffer == 0 and sys.platform == "darwin": glReadBuffer(GL_FRONT) self.render_quality = 0 self.rendermode = self.DISPLAYLISTS if self.dumpbitmap == 1: if self.offscreen_buffer == 0 and sys.platform == "darwin": glReadBuffer(GL_BACK) glFlush() self.screenshot() self.dumpbitmap = 0 if self.offscreen_buffer == 0 and sys.platform == "darwin": glReadBuffer(GL_FRONT) if self.offscreen_buffer: cprim.UnForceLoadTextures() self.update_matrices = 1 self.render_quality = 0 self.rendermode = self.DISPLAYLISTS if not self.offscreen_buffer: glutSwapBuffers(); if self.dumpbitmap and self.offscreen_buffer: self.onscreen_buffer.MakeCurrent() if self.dumpps == 1: self.DrawPostscript() self.dumpps = 0 if self.dumppov == 1: self.DrawPovRay() self.dumppov = 0 if self.antialias_screenshot: self.antialias = orig_anti self.glready.set() if self.dumpbitmap == 0 and self.offscreen_buffer: del self.offscreen_buffer self.offscreen_buffer = 0 def movexyz(self,r,dr): dx,dy,dz = self.getdxdydz(dr[0], dr[1], dr[2]) return r[0]+dx, r[1]+dy, r[2]+dz def calculate_extents(self): xaxis,yaxis,zaxis = self.xaxis,self.yaxis,self.zaxis ratio = self.xyratio* self.win_w / self.win_h tr = [self.rpos[0] - self.viewsize*ratio*xaxis.get_x() + self.viewsize*yaxis.get_x(), self.rpos[1] - self.viewsize*ratio*xaxis.get_y() + self.viewsize*yaxis.get_y(), self.rpos[2] - self.viewsize*ratio*xaxis.get_z()/2.0 + self.viewsize*yaxis.get_z()] tl = [self.rpos[0] + self.viewsize*ratio*xaxis.get_x() + self.viewsize*yaxis.get_x(), self.rpos[1] + self.viewsize*ratio*xaxis.get_y() + self.viewsize*yaxis.get_y(), self.rpos[2] + self.viewsize*ratio*xaxis.get_z()/2.0 + self.viewsize*yaxis.get_z()] bl = [self.rpos[0] + self.viewsize*ratio*xaxis.get_x() - self.viewsize*yaxis.get_x(), self.rpos[1] + self.viewsize*ratio*xaxis.get_y() - self.viewsize*yaxis.get_y(), self.rpos[2] + self.viewsize*ratio*xaxis.get_z()/2.0 - self.viewsize*yaxis.get_z()] br = [self.rpos[0] - self.viewsize*ratio*xaxis.get_x() - self.viewsize*yaxis.get_x(), self.rpos[1] - self.viewsize*ratio*xaxis.get_y() - self.viewsize*yaxis.get_y(), self.rpos[2] - self.viewsize*ratio*xaxis.get_z()/2.0 - self.viewsize*yaxis.get_z()] self.extents = [tl,tr,br,bl] def getdxdydz(self,dx,dy,dz): """ Calculate movement in real coordinates corresponding to one in eye coordinates. """ xaxis,yaxis,zaxis = self.xaxis,self.yaxis,self.zaxis dr = [] dr.append(dx*xaxis.get_x()) dr.append(dx*xaxis.get_y()) dr.append(dx*xaxis.get_z()) du = [] du.append(dy*yaxis.get_x()) du.append(dy*yaxis.get_y()) du.append(dy*yaxis.get_z()) df = [] df.append(dz*zaxis.get_x()) df.append(dz*zaxis.get_y()) df.append(dz*zaxis.get_z()) dx = dr[0] + du[0] + df[0] dy = dr[1] + du[1] + df[1] dz = dr[2] + du[2] + df[2] return [dx,dy,dz] def bgcolour(self,colour): """ Set the background colour. """ import COLOUR self.bgcolor = COLOUR.COLOUR.insts.RGB(colour) self.redraw = 1 def zoom_camera(self,zoom): """ Zoom in and out """ if self.weighted_zoom: self.RADIUS = self.RADIUS + self.zoom_warp* (zoom * self.RADIUS/30.0) else: self.RADIUS = self.RADIUS + self.zoom_warp*zoom if self.RADIUS < .5: self.RADIUS =.5 #print "zoom_camera",zoom,self.viewsize,self.win_w,self.RADIUS self.movescalex = 2.0 * float(self.viewsize)/float(self.win_w) * float(self.RADIUS)/60.0 self.movescaley = 2.0 * float(self.viewsize)/float(self.win_w) * float(self.RADIUS)/60.0 #self.redraw = 1 def SetRotation(self,q=''): """ Define a standard orientation """ if q: self.quat = q self.redraw = 1 def move_camera(self,dx,dy,dz): """ Move camera around. """ self.dx = self.dx + dx self.dy = self.dy + dy self.dz = self.dz + dz def move_camera_scale(self,dx,dy,dz): #print "move_camera_str",self.movescaley self.move_camera(float(dx)*self.movescalex,float(dy)*self.movescaley,float(dz)*self.movescaley) def rotate_camera(self,drot): """ Pick up info about world rotation which will be used in quaternion calculations. """ self.drot = (drot[0]+self.drot[0],drot[1]+self.drot[1],drot[2]+self.drot[2]) def getmodifiers(self): """ Find out which modifiers are pressed. """ glmods = glutGetModifiers() shift = 0 ctrl = 0 alt = 0 if glmods|GLUT_ACTIVE_SHIFT == glmods : shift = 1 if glmods|GLUT_ACTIVE_CTRL == glmods : ctrl = 1 if glmods|GLUT_ACTIVE_ALT == glmods : alt = 1 mods = [0,0,0] mods[self.SHIFT] = shift mods[self.CTRL] = ctrl mods[self.ALT] = alt return mods #return [ shift, ctrl, alt ] def GetWorldXY(self): world_x = intp() world_y = intp() GetWorldMousePosition(world_x, world_y) x = world_x.value() y = world_y.value() return (x,y) def GetScreenBox(self): xyzs = [ self.getxyz(0,self.win_h),self.getxyz(0,0), self.getxyz(self.win_w,0), self.getxyz(self.win_w,self.win_h) ] #print "GetScreenBox self.screen_box",self.screen_box if not self.screen_box: xyzbox = CartesianVector() else: xyzbox = self.screen_box while len(xyzbox)>0: xyzbox.pop() xyzbox.append(xyzs[0][0]); xyzbox.append(xyzs[0][1]); xyzbox.append(xyzs[1][0]); xyzbox.append(xyzs[1][1]); xyzbox.append(xyzs[2][0]); xyzbox.append(xyzs[2][1]); xyzbox.append(xyzs[3][0]); xyzbox.append(xyzs[3][1]); #print "GetScreenBox xyzbox",xyzbox return xyzbox def GetXYZBox(self, x, y): xyzs = [ self.getxyz(x-10,y+10),self.getxyz(x-10,y-10), self.getxyz(x+10,y-10), self.getxyz(x+10,y+10) ] xyzbox = CartesianVector() xyzbox.append(xyzs[0][0]); xyzbox.append(xyzs[0][1]); xyzbox.append(xyzs[1][0]); xyzbox.append(xyzs[1][1]); xyzbox.append(xyzs[2][0]); xyzbox.append(xyzs[2][1]); xyzbox.append(xyzs[3][0]); xyzbox.append(xyzs[3][1]); return xyzbox def mouse(self, button, state, x, y): """ Mouse callback function. Dispatch events to job queue. """ screenx, screeny = self.GetWorldXY() xyzbox = self.GetXYZBox(x,y) self.modifiers = self.getmodifiers() if sys.platform == 'darwin': if button == 0 and self.modifiers[1] == 1: button = 2 self.modifiers[1] = 0 if state==GLUT_DOWN: if button==GLUT_LEFT_BUTTON: self.BUTTON_PRESSED = self.LEFT_MOTION elif button==GLUT_RIGHT_BUTTON: self.BUTTON_PRESSED = self.RIGHT_MOTION elif button==GLUT_MIDDLE_BUTTON: self.BUTTON_PRESSED = self.MIDDLE_MOTION binfo = {} binfo["button"] = button binfo["state"] = state binfo["x"] = x binfo["y"] = y binfo["xyzbox"] = xyzbox binfo["screenx"] = screenx binfo["screeny"] = screeny binfo["window"] = glutGetWindow() binfo["key_presses"] = self.key_presses binfo["time"] = time.time() if button==3: job = [ self.WHEEL_UP, binfo ] elif button==4: job = [ self.WHEEL_DOWN, binfo ] elif button==2: job = [ self.MOUSE, binfo ] else: job = [ self.MOUSE, binfo ] if state == GLUT_DOWN: self.start_x = x self.start_y = y else: if self.moving: self.mouse_event = [] self.moving = 0 glutPostRedisplay() return self.moving = 0 #self.glevent.glevent(job) if button == 2 or button == 3 or button == 4: self.glevent.glevent(job) else: self.mouse_event.append(job) endjob = self.mouse_event[len(self.mouse_event)-1] job1 = self.mouse_event[0] if len(self.mouse_event) == 2 or len(self.mouse_event) == 4: job2 = self.mouse_event[1] if len(self.mouse_event) == 4: binfo["state"] = 2 self.click_timer.cancel() self.click_timer = threading.Timer(0.0,nullfunc) self.click_timer.start() job = [ self.MOUSE, binfo ] self.glevent.glevent(job) self.mouse_event = [] else: self.click_timer = threading.Timer(0.5,self.ClearMouseEvents) self.click_timer.start() self.glevent.glevent(job1) self.glevent.glevent(job2) if len(self.mouse_event) > 4: self.mouse_event = [] glutPostRedisplay() def ClearMouseEvents(self): self.mouse_event = [] self.click_timer = threading.Timer(0.0,nullfunc) self.click_timer.start() def entry(self, state): if state == GLUT_LEFT: for key in range(128): self.old_key_presses[key] = self.key_presses[key] self.key_presses[key] = 0 self.old_special_presses[key] = self.key_presses[key] self.special_presses[key] = 0 else: for key in range(128): self.key_presses[key] = self.old_key_presses[key] self.special_presses[key] = self.old_special_presses[key] def keyboard_up(self, key, x, y): if key>128: return if self.key_presses[key]: self.key_presses[key] = -1 self.modifiers = self.getmodifiers() shift_key = ShiftKey(key) if shift_key<=128 and self.key_presses[shift_key]: self.key_presses[shift_key] = -1 no_shift_key=NoShiftKey(key) if no_shift_key<=128 and self.key_presses[no_shift_key]: self.key_presses[no_shift_key] = -1 self.screen_x, self.screen_y = self.GetWorldXY() if self.key_presses.count(1) > 0 or self.key_presses.count(-1) > 0: self.keyboard_is_active = 1 else: self.keyboard_is_active = 0 glutPostRedisplay() def keyboard(self, key, x, y): """ Keyboard callback function. Dispatch events to job queue. """ if key>128: return self.modifiers = self.getmodifiers() self.key_presses[key] = 1 self.screen_x, self.screen_y = self.GetWorldXY() if self.key_presses.count(1) > 0 or self.key_presses.count(-1) > 0: self.keyboard_is_active = 1 else: self.keyboard_is_active = 0 glutPostRedisplay() def special(self, key, x, y): """ Special Key callback function. Dispatch events to job queue. """ if key>128: return self.special_presses[key] = 1 self.modifiers = self.getmodifiers() self.screen_x, self.screen_y = self.GetWorldXY() if self.special_presses.count(1) > 0 or self.special_presses.count(-1) > 0: self.special_is_active = 1 else: self.special_is_active = 0 glutPostRedisplay() def special_up(self, key, x, y): if key>128: return self.special_presses[key] = 0 self.modifiers = self.getmodifiers() self.screen_x, self.screen_y = self.GetWorldXY() if self.special_presses.count(1) > 0 or self.special_presses.count(-1) > 0: self.special_is_active = 1 else: self.special_is_active = 0 glutPostRedisplay() def passive(self, x, y): self.mouse_x = x self.mouse_y = y def SendMotionEvent(self,dx,dy,x,y): mods = CheckModifiers(); if mods > -1: shift = 0 ctrl = 0 alt = 0 if mods|GLUT_ACTIVE_SHIFT == mods : shift = 1 if mods|GLUT_ACTIVE_CTRL == mods : ctrl = 1 if mods|GLUT_ACTIVE_ALT == mods : alt = 1 mods = [0,0,0] mods[self.SHIFT] = shift mods[self.CTRL] = ctrl mods[self.ALT] = alt self.modifiers = mods xyzbox = self.GetXYZBox(x,y) binfo = {} binfo["x"] = x binfo["y"] = y binfo["dx"] = dx binfo["dy"] = dy binfo["xyzbox"] = xyzbox binfo["window"] = glutGetWindow() binfo["key_presses"] = self.key_presses job = [ self.BUTTON_PRESSED, binfo ] self.glevent.glevent(job) def motion(self, x, y): self.moving = 1 self.mouse_x = x self.mouse_y = y glutPostRedisplay() def getxyz(self,x,y): """ Work out world x,y,z at near and far clipping planes. """ #if sys.platform == 'win32': #return CartesianVectorPtr(getxyzc(x,y)) viewport = inta(4) mvmatrix = doublea(16) projmatrix = doublea(16) wx = doublep() wy = doublep() wz = doublep() glGetIntegerv(GL_VIEWPORT,viewport); glGetDoublev(GL_PROJECTION_MATRIX,projmatrix); glGetDoublev(GL_MODELVIEW_MATRIX,mvmatrix); realy = viewport[3] - y - 1; gluUnProject(x,realy,0.0,mvmatrix,projmatrix,viewport,wx,wy,wz); cart1 = Cartesian(wx.value(), wy.value(), wz.value()) gluUnProject(x,realy,1.0,mvmatrix,projmatrix,viewport,wx,wy,wz); cart2 = Cartesian(wx.value(), wy.value(), wz.value()) cv = CartesianVector() cv.append(cart1) cv.append(cart2) del viewport del mvmatrix del projmatrix del wx del wy del wz return cv; def get_pixdata(self): return image_infoPtr(get_pixdata(int(math.ceil(self.background_alpha)))) def screenshot(self,name=""): import tempfile import os import shutil temp_filename = tempfile.mktemp() if name != "": temp_filename = name #temp_filename + name[name.rfind('.'):] if self.offscreen_buffer: self.offscreen_buffer.Write(temp_filename,self.screenshot_width,self.screenshot_height,int(math.ceil(self.background_alpha))) else: write_pixdata(temp_filename,self.screenshot_width,self.screenshot_height,int(math.ceil(self.background_alpha))) else: name = self.screenshot_filename temp_filename = name #temp_filename + name[name.rfind('.'):] if self.dumpbitmap > 1: if self.section == 0: self.screen_sections = ImageInfoVector() if self.offscreen_buffer: iinfo = image_infoPtr(self.offscreen_buffer.get_pixdata(int(math.ceil(self.background_alpha)))) else: iinfo = self.get_pixdata() iinfo.invert() self.screen_sections.append(iinfo) if self.section == self.dumpbitmap - 1: nsec = int(math.sqrt(self.dumpbitmap)) b = [] for i in range(nsec): a = [] for j in range(nsec): a.append(i*nsec+j) b.append(a) b.reverse() ii = IntIntVector() for a in b: ii.append(a) iinfo = image_info(self.screen_sections,ii) iinfo.write(temp_filename) else: if self.offscreen_buffer: self.offscreen_buffer.Write(temp_filename,self.screenshot_width,self.screenshot_height,int(math.ceil(self.background_alpha))) else: write_pixdata(temp_filename,self.screenshot_width,self.screenshot_height,int(math.ceil(self.background_alpha))) """ try: shutil.copy(temp_filename,name) except: print "Failed to write file", name, "." """ def request_screenshot(self,filename="screendump.ppm",antialias=0,sections=0,blocking=1,width=-1,height=-1,render_quality=1): """ Save a Bitmap. """ self.request_render_quality = render_quality if blocking: self.glready.wait(3000) self.glready.set() if antialias: self.antialias_screenshot = 1 else: self.antialias_screenshot = 0 self.screenshot_filename = filename self.screenshot_width = width self.screenshot_height = height if sections > 0: self.dumpbitmap = sections self.old_idle_pause = self.idle_pause self.idle_pause = 0.0 else: self.dumpbitmap = 1 if blocking: self.glready.clear() def request_screenshot_ps(self,filename="screendump.ps"): """ Save a PostScript File. """ self.ps_filename = filename self.dumpps = 1 def request_screenshot_pov(self,filename="screendump.pov"): """ Save a PovRay input File. """ self.pov_filename = filename self.dumppov = 1 def UnPause(self): self.redraw = 1 self.glpause.set() def Pause(self,hard=0): if hard: self.glready.wait(3000) self.glpause.clear() def Wait(self): """ This blocks until end of self.orient, ie rendering is finished. """ self.glready.wait(3000) self.glready.clear() def Flush(self): """ This blocks until end of self.orient, ie rendering is finished. """ self.glready.wait(3000) self.glready.clear() self.glready.wait(3000) def set_rubber_band_start(self,x,y): self.rubber_band_start = (x,y) self.rubber_band_end = (x,y) self.define_rubber_band_cube() def set_rubber_band_end(self,x,y): self.rubber_band_end = (x,y) self.define_rubber_band_cube() def define_rubber_band_cube(self): xyz1 = self.getxyz(self.rubber_band_start[0],self.rubber_band_start[1]) xyz2 = self.getxyz(self.rubber_band_start[0],self.rubber_band_end[1]) xyz3 = self.getxyz(self.rubber_band_end[0],self.rubber_band_end[1]) xyz4 = self.getxyz(self.rubber_band_end[0],self.rubber_band_start[1]) self.rubber_band_box.p0 = xyz1[0] self.rubber_band_box.p1 = xyz2[0] self.rubber_band_box.p2 = xyz3[0] self.rubber_band_box.p3 = xyz4[0] self.rubber_band_box.p4 = xyz1[1] self.rubber_band_box.p5 = xyz2[1] self.rubber_band_box.p6 = xyz3[1] self.rubber_band_box.p7 = xyz4[1] def get_clipping_planes(self): M = self.quat.getInvMatrix() triangles = [] for plane in self.clip_planes: triangle_rotated = [] triangle = util.find_points_on_plane(plane.eqn) rotatedp = util.matrixXvector(M,triangle[1]) transrotp = util.vsubv(rotatedp,self.rpos) transrotp = util.vsubv(transrotp,self.rpos) triangle_rotated.append(transrotp) rotatedp = util.matrixXvector(M,triangle[0]) transrotp = util.vsubv(rotatedp,self.rpos) transrotp = util.vsubv(transrotp,self.rpos) triangle_rotated.append(transrotp) rotatedp = util.matrixXvector(M,triangle[2]) transrotp = util.vsubv(rotatedp,self.rpos) transrotp = util.vsubv(transrotp,self.rpos) triangle_rotated.append(transrotp) triangles.append(triangle_rotated) return triangles def get_rubber_band_planes(self): """ This returns sets of planes defined by what is rubber banded on screen. It should have a better name and also return general clipping planes. """ box = self.rubber_band_box return [Plane(box.p0,box.p1,box.p2),\ Plane(box.p4,box.p7,box.p6),\ Plane(box.p0,box.p4,box.p5),\ Plane(box.p2,box.p6,box.p7),\ Plane(box.p0,box.p3,box.p7),\ Plane(box.p1,box.p5,box.p6)]