""" pygl/build.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. """ from pygl_coord import * #from primitive import * from displayobject import * from atom_util import * from mmdb2 import * from point_funcs import * from eventdefs import * from graphicsmodel import * import util import opts import time, threading import math import string import Queue import sys,os import pickle from texture import * import cprim import COLOUR import UtilityThread class build: """ Class which turns some chemical data into ball/stick pictures, etc and sends off abstract primitive data to OpenGL thread. Also handles selection of primitives, though not perfectly yet. """ insts = "" positions = [] def animate(self,pos1,pos2,export=0,filename="screenshot",format=".ppm"): """ Takes two instances of buildSaveData and animates between them. """ numsteps = 50 for j in range(numsteps+1): dx = float(j)/float(numsteps) for i in range(len(self.mods)): mod = self.mods[i] mod.obj.quat.dval = [ (1-dx)*pos1[i].quat.dval[0] + dx*pos2[i].quat.dval[0],\ (1-dx)*pos1[i].quat.dval[1] + dx*pos2[i].quat.dval[1],\ (1-dx)*pos1[i].quat.dval[2] + dx*pos2[i].quat.dval[2],\ (1-dx)*pos1[i].quat.dval[3] + dx*pos2[i].quat.dval[3] ] mod.obj.origin = ( (1-dx)*pos1[i].origin[0] + dx*pos2[i].origin[0],\ (1-dx)*pos1[i].origin[1] + dx*pos2[i].origin[1],\ (1-dx)*pos1[i].origin[2] + dx*pos2[i].origin[2] ) if export > 0: """ The format bit is a bit kludgy, but we'll fix that. j needs to be replaced with some global counter ... """ fname = filename + string.zfill(str(j),4) + format #print fname #self.glthread.screenshot(fname) else: time.sleep(0.1) def __init__(self,thread): """ Initilaization. Set up some defaults. """ build.insts = self self.mods = [] self.jobtypeold = -1 self.oldx = 0 self.oldy = 0 self.glthread = thread self.selected_model = -1 self.jq = Queue.Queue(0) self.animate_load = 1 self.clicked_prims = [] #self.glthread.glevent.registermods(self.mods) """ def TestMovie(self): self.glthread.glevent.centre_on((0,0,0),self.mods[0].obj) self.glthread.quat = pygl_coord.Quat(0.0,0.0,0.0,0) for i in range(90): filename = "movie4%05d.pov" % i x = 10.0*math.sin(i*math.pi/1440.0) z = 10.0*math.sin(i*math.pi/1440.0) self.glthread.RADIUS = (90 - i/3.0) self.glthread.glevent.centre_on((0,0,0),self.mods[0].obj) self.glthread.move_camera(-x,5,z) self.glthread.rotate_camera((0,-0.2,0)) print "Requesting", filename self.glthread.Flush() self.glthread.request_screenshot_pov(filename) #self.glthread.Flush() for j in range(30): i = i + 1 filename = "movie4%05d.pov" % i self.glthread.RADIUS = (60 - j/2.0) print "Requesting", filename self.glthread.Flush() self.glthread.request_screenshot_pov(filename) #self.glthread.Flush() for j in range(90): i = i + 1 filename = "movie4%05d.pov" % i self.glthread.rotate_camera((0,-0.2,0)) print "Requesting", filename self.glthread.Flush() self.glthread.request_screenshot_pov(filename) #self.glthread.Flush() """ def deletemod(self,graphmod): """ Delete a model and all its objects and children, recursively hopefully. Instances should take care of themselves where possible. """ if self.mods.count(graphmod): #print self.glthread modid = self.mods.index(graphmod) self.mods.pop(modid) if hasattr(graphmod,"obj") and hasattr(graphmod.obj,"clear_prims"): #print "Clearing prims" graphmod.obj.clear_prims() if hasattr(graphmod,"conn_lists") and graphmod.conn_lists: #print "Forcing clear Connectivity lists" del graphmod.conn_lists graphmod.conn_lists = () if hasattr(graphmod,"sinfo"): del graphmod.sinfo graphmod.delete() del graphmod def registerqueue(self,jq): """ A function which tells the thread which Python Queue it is meant to push events to. """ self.jq = jq def append(self,mod): self.append1(mod) self.append2(mod) def append1(self,mod): mod.build_primitives() def append2(self,mod): # At this point we need to add an object to GLWidgets somehow. #self.mods.append(mod) #self.glthread.addobj(mod.obj) import MGApplication win = MGApplication.GetMainWindow() win.addGLDisplayObject(mod) self.selected_model = self.selected_model + 1 """ dist = mod.GetMaxDimension() if(dist and dist>self.glthread.viewsize): self.glthread.setmaxviewsize(dist/2.0+5) """ #win.setGLSize(dist/2.0+5) def newbillboard(self,mod,filename,coords_in=[0,0,1,1]): obj = cprim.Displayobject() mod.style = "BILLBOARD" mod.obj = obj coords = doublea(6) coords[0] = coords_in[0] coords[1] = coords_in[1] coords[2] = 0 coords[3] = coords_in[2] coords[4] = coords_in[3] coords[5] = 0 cprim.AddBillBoardImage(obj,filename,coords) self.append(mod) def newbillboardtextlabel(self,mod,label,coords_in=[0,0]): obj = cprim.Displayobject() mod.style = "BILLBOARD" mod.obj = obj cprim.AddBillBoardTextLabel(obj,coords_in[0],coords_in[1],label) self.append(mod)