def DisplayFunction(self): """ Either executes the present display list or creates a display list to display the quad strip. """ OVERALL, PER_VERTEX, PER_PART, PER_FACE = -1, 10, 11, 12, 13 #NONE, OVERALL, PER_VERTEX, PER_PART, PER_FACE = -1, 10, 11, 12, 13 propConst = DejaVu.viewerConst.propConst noCol = 0 if self.viewer.currentCamera.renderMode == GL.GL_SELECT: save = self.dpyList temp = self.primitiveType if self.frontPolyMode == GL.GL_FILL: self.primitiveType = GL.GL_POLYGON elif self.frontPolyMode == GL.GL_LINE: self.primitiveType = GL.GL_LINE_LOOP elif self.frontPolyMode == GL.GL_POINT: self.primitiveType = GL.GL_POINTS self.faceSet = self.IndexedFaceSet IndexedPolygons.DisplayFunction(self) self.faceSet = self.StripFaceSet self.primitiveType = temp self.dpyList = save return if self.dpyList: IndexedPolygons.DisplayFunction(self)
def doit(self, file, molname=None): global sl if not sl: sl = SLGeom() bspt_set = sl.readBspt(file) brep_set = sl.convert_to_Brep(bspt_set, expense=0.5, duplicate=1) verts, faces, vnorms, fnorms = sl.getBoundaries(brep_set, has_vnormals=0, has_fnormals=1) vs, fs, vns, fns = sl.indexedFromArr(verts, faces, fnorms=fnorms) #sl.discardSet(brep_set) #brep_set = None name = path.splitext(path.basename(file))[0] if find(name, "_"): #name should not contain "_" name = replace(name, "_", "-") if vs: ## length = map( len, fs) ## mlength = max(length) ## for i in range(len(fs)): ## d = mlength-len(fs[i]) ## if d: ## for j in range(d): ## fs[i].append(-1) ipg = IndexedPolygons( name, vertices=vs, faces=fs, visible=1, inheritMaterial=0, protected=True, ) if self.vf.userpref['Sharp Color Boundaries for MSMS'][ 'value'] == 'blur': ipg.Set( inheritSharpColorBoundaries=False, sharpColorBoundaries=False, ) vi = self.vf.GUI.VIEWER cl_atoms = None if molname: cl_atoms = self.vf.bindGeomToMolecularFragment(ipg, molname) else: vi.AddObject(ipg) ipg.Set(frontPolyMode=GL.GL_FILL, shading=GL.GL_FLAT) ipg.Set(fnormals=fns, tagModified=False) vi.Redraw() if molname and cl_atoms: self.vf.bindGeomToMolecularFragment.data[name]['fns'] = fns self.vf.SL.setdict[ipg.fullName] = bspt_set else: print "vertices array length of converted brep set is 0"
def Draw(self): #print"Box.Draw" self.oldFPM = self.frontPolyMode if self.frontPolyMode == GL.GL_LINE: GL.glDisable(GL.GL_LIGHTING) #c is 8x3 array c = self.vertexSet.vertices.array #lines parallel to x-axis should be red, y->blue and z->green col = ((1, 0, 0), (0, 1, 0), (0, 0, 1)) #these groups of 4 pairs of points define lines parallel to x, y, and z axes alines = [[(c[0], c[1]), (c[2], c[3]), (c[4], c[5]), (c[6], c[7])], [(c[0], c[3]), (c[1], c[2]), (c[4], c[7]), (c[5], c[6])], [(c[0], c[4]), (c[1], c[5]), (c[3], c[7]), (c[2], c[6])]] namectr = 0 for i in range(3): if not self.inheritMaterial: GL.glColor3fv(col[i]) for vpairs in alines[i]: GL.glPushName(namectr) GL.glBegin(GL.GL_LINES) GL.glVertex3dv(list(vpairs[0])) GL.glVertex3dv(list(vpairs[1])) GL.glEnd() GL.glPopName() namectr = namectr + 1 self.viewer.enableOpenglLighting() return 1 else: return IndexedPolygons.Draw(self)
def testMSMSParser(): from Pmv.msmsParser import MSMSParser msmsParser = MSMSParser() msmsParser.parse("./gc2.vert", "./gc2.face") msmsParser.parse("./test_0.vert", "./test_0.face") from DejaVu import Viewer vi = Viewer() from DejaVu.IndexedPolygons import IndexedPolygons visrf = IndexedPolygons('test', protected=True) visrf.Set(vertices=msmsParser.vertices, faces=msmsParser.faces, vnormals=msmsParser.normals, tagModified=False) vi.AddObject(visrf)
def onAddCmdToViewer(self): from DejaVu.Points import CrossSet self.cross = CrossSet('Cross', materials=((1.,1.,0),), inheritMaterial=0, protected=True, offset=1.0,lineWidth=5, visible=0, pickable=0) from DejaVu.IndexedPolygons import IndexedPolygons from DejaVu.Box import Box from DejaVu.Spheres import Spheres from DejaVu import viewerConst from DejaVu.bitPatterns import patternList from opengltk.OpenGL import GL face=((0,3,2,1),(3,7,6,2),(7,4,5,6),(0,1,5,4),(1,2,6,5),(0,4,7,3)) coords=((1,1,-1),(-1,1,-1),(-1,-1,-1),(1,-1,-1),(1,1,1),(-1,1,1),(-1,-1,1),(1,-1,1)) #new style RGB-> materials=((0,0,1),(0,1,0),(0,0,1),(0,1,0),(1,0,0),(1,0,0),) box=IndexedPolygons('Box', materials=materials, vertices=coords, faces=face, inheritMaterial=0, visible=0, protected=True) box.Set(frontPolyMode=GL.GL_LINE) box.Set(backPolyMode=GL.GL_LINE) box.Set(culling=GL.GL_NONE) box.inheritShading=0 box.shading=GL.GL_FLAT box.Set(matBind=viewerConst.PER_PART) box.polygonstipple.Set(pattern=patternList[0]) box.Set(stipplePolygons=1) box.transparent=0 self.box = box self.spheres = Spheres('Spheres', visible=0, inheritMaterial=0, radii=(0.3,), protected=True) self.halo = Spheres('Halo', visible=0, inheritMaterial=0, radii=(0.5,), protected=True) from DejaVu.Geom import Geom AutoLigand_geoms = Geom("AutoLigand_geoms", shape=(0,0)) self.vf.GUI.VIEWER.AddObject(AutoLigand_geoms) self.vf.GUI.VIEWER.AddObject(self.cross, parent=AutoLigand_geoms) self.vf.GUI.VIEWER.AddObject(self.box, parent=AutoLigand_geoms) self.vf.GUI.VIEWER.AddObject(self.spheres, parent=AutoLigand_geoms) self.vf.GUI.VIEWER.AddObject(self.halo, parent=AutoLigand_geoms) self.grids = {}
def clip(self, mesh, grid): assert isinstance(mesh, IndexedPolygons) assert isinstance(grid, Grid3D) origin = grid.getOriginReal() stepSize = grid.getStepSizeReal() dx, dy, dz = grid.dimensions vertices = mesh.vertexSet.vertices.array triangles = mesh.faceSet.faces.array # compute the voxel on which each vertex falls # array of indiced into grid for the vertices vertInd = ((vertices - origin) / stepSize).astype('i') # select the vertices on voxels that have a value True selVert = [] vertEquiv = {} numVertSel = 0 nvert = 0 data = grid.data for i, j, k in vertInd: if i >= 0 and i < dx: if j >= 0 and j < dy: if k >= 0 and k < dz: if data[i, j, k]: selVert.append(vertices[nvert]) vertEquiv[nvert] = numVertSel numVertSel += 1 nvert += 1 # build a set of faces for which some vertices are selected # and keep only selected vertices selFaces = [] for i, j, k in triangles: nbvs = 0 v1 = vertEquiv.get(i, None) if v1: nbvs += 1 v2 = vertEquiv.get(j, None) if v2: nbvs += 1 v3 = vertEquiv.get(k, None) if v3: nbvs += 1 if nbvs == 3: selFaces.append((v1, v2, v3)) clippedGeom = IndexedPolygons(mesh.name + '_clipped', vertices=selVert, faces=selFaces) return clippedGeom
def doit(self, lines): """Parse ASCII STL files, build DejaVu IndexedPolygons and return them """ self.geoms = [] faces = [] vertices = [] normals = [] name = 'IndexedGeom' faceIndex = 0 # counter # parse ASCII STL for line in lines: spl = string.split(string.lower(line)) if spl[0] == 'solid': name = spl[1] continue elif spl[0] == 'facet' and spl[1] == 'normal': normals.append([float(spl[2]), float(spl[3]), float(spl[4])]) continue elif spl[0] == 'vertex': vertices.append([float(spl[1]), float(spl[2]), float(spl[3])]) continue elif spl[0] == 'endfacet': faces.append([faceIndex, faceIndex + 1, faceIndex + 2]) faceIndex = faceIndex + 3 continue elif spl[0] == 'endsolid': geom = IndexedPolygons(name, vertices=vertices, faces=faces, fnormals=normals) self.geoms.append(geom) faces = [] vertices = [] normals = [] name = 'IndexedGeom' faceIndex = 0 # counter continue else: continue return self.geoms
def doit(self, filename): """Parse ASCII STL files, build DejaVu IndexedPolygons and return them """ # open file to read in binary mode f = open(filename, 'rb') # read the 84 bytes of the header header = f.read(84) # get the comment comment = unpack("80c", header[0:80]) # get the total number of facets lenFaces = unpack("1i", header[80:84])[0] data = f.read() # read to end f.close() # organize the data normals = [] vertices = [] faces = [] j = 0 # counter for reading binary data f = 0 # counter for generating faces for i in range(lenFaces): normal = unpack("3f", data[j:j + 12]) normals.append(normal) faces.append((f, f + 1, f + 2)) verts = unpack("9f", data[j + 12:j + 48]) vertices.append(verts[0:3]) vertices.append(verts[3:6]) vertices.append(verts[6:9]) #spacer = unpack("2c", data[j+48:j+50]) # increment binary counter j = j + 50 # increment faces counter f = f + 3 name = "IndexedGeom" geom = IndexedPolygons(name, vertices=vertices, faces=faces, fnormals=normals) return geom
def DisplayFunction(self): """ Either executes the present display list or creates a display list to display the triangle strip. """ # if in select mode, switches to IndexedPolygons if self.viewer.currentCamera.renderMode == GL.GL_SELECT: temp = self.primitiveType if self.frontPolyMode == GL.GL_FILL: self.primitiveType = GL.GL_POLYGON elif self.frontPolyMode == GL.GL_LINE: self.primitiveType = GL.GL_LINE_LOOP elif self.frontPolyMode == GL.GL_POINT: self.primitiveType = GL.GL_POINTS self.faceSet = self.IndexedFaceSet IndexedPolygons.DisplayFunction(self) self.faceSet = self.StripFaceSet self.primitiveType = temp return if self.dpyList: Geom.DisplayFunction(self)
def ClipCapMesh(self, obj, onOff): if not hasattr(obj, 'buildEdgeList'): return vi = obj.viewer if onOff: x, y, z, s = self.eqn vc, fc = self.getCapMesh(obj) from DejaVu.IndexedPolygons import IndexedPolygons capg = IndexedPolygons('cap%d' % self.num, vertices=vc, faces=fc, fnormals=((-x, -y, -z), ), inheritFrontPolyMode=False, frontPolyMode='fill', inheritBackPolyMode=False, backPolyMode='fill', inheritCulling=0, culling='none', inheritShading=0, shading='flat') vi.AddObject(capg, parent=obj) obj.capMesh = 1 vi.cappedGeoms.append((obj, self, capg)) else: obj.capMesh = 0 for g, c, gc in obj.viewer.cappedGeoms: #print 'trying to remove', g, self if g == obj and c == self: #print 'removing' vi.cappedGeoms.remove((g, c, gc)) vi.RemoveObject(gc) break if obj != vi.rootObject: vi.objectsNeedingRedo[obj] = None vi.Redraw()
def asIndexedPolygons(self, run=1, quality=None, radius=None, **kw): """ run=0 returns 1 if this geom can be represented as an IndexedPolygon and None if not. run=1 returns the IndexedPolygon object.""" #print "Cylinders.asIndexedPolygons", quality if run == 0: return 1 # yes, I can be represented as IndexedPolygons import numpy.oldnumeric as Numeric, math from mglutil.math.transformation import Transformation if quality in [1, 2, 3, 4, 5]: quality = quality elif quality < 0 and self.quality in [2, 3, 4, 5]: quality = self.quality - 2 else: quality = self.quality - 1 quality *= 5 # make a copy of the cylinderTemplate tmpltVertices, tmpltFaces = self._cylinderTemplateDaniel(\ quality=quality) centers = self.vertexSet.vertices.array faces = self.faceSet.faces.array tmpltVertices = Numeric.array(tmpltVertices).astype('f') tmpltFaces = Numeric.array(tmpltFaces).astype('f') addToFaces = Numeric.ones((tmpltFaces.shape)) * 2 * len(tmpltVertices) VV = [] # this list stores all vertices of all cylinders FF = [] # this list stores all faces of all cylinders # now loop over all cylinders in self for index in xrange(len(faces)): # tv temporarily stores the transformed unit cylinder vertices tv = tmpltVertices.__copy__() pt0 = centers[faces[index][0]] # bottom of cylinder pt1 = centers[faces[index][1]] # top of cylinder # get radius for cylinder if radius is not None: radx = rady = radius #override radii elif self.oneRadius: radx = rady = radius = self.vertexSet.radii.array[0] else: radx = self.vertexSet.radii.array[faces[index][1]] rady = self.vertexSet.radii.array[faces[index][0]] # determine scale and rotation of current cylinder sz = 0.0 for nbr in (0, 1, 2): sz = sz + (pt0[nbr] - pt1[nbr]) * (pt0[nbr] - pt1[nbr]) if sz <= 0.0: return sz = math.sqrt(sz) rx = -180.0 * math.acos((pt1[2] - pt0[2]) / sz) / math.pi dx = pt1[0] - pt0[0] dy = pt1[1] - pt0[1] if math.fabs(dx) < 0.00001 and math.fabs(dy) < 0.00001: rz = 0.0 else: rz = -180.0 * math.atan2(dx, dy) / math.pi # prepare rotations matrices of current cylinder Rx = Transformation(quaternion=[1, 0, 0, rx]) if rz <= 180.0 and rz >= -180.0: Rz = Transformation(quaternion=[0, 0, 1, rz]) R = Rz * Rx else: R = Rx r = R.getMatrix() k = 0 for v in tmpltVertices: # I DO NOT use Numeric.matrixmultiply # here, in order to gain significant speed v0x, v0y, v0z = v[0] # saves some lookups v1x, v1y, v1z = v[1] tv[k][0]=\ ([r[0][0]*v0x*radx+r[1][0]*v0y*radx+r[2][0]*v0z*sz+pt0[0], r[0][1]*v0x*radx+r[1][1]*v0y*radx+r[2][1]*v0z*sz+pt0[1], r[0][2]*v0x*radx+r[1][2]*v0y*radx+r[2][2]*v0z*sz+pt0[2]]) tv[k][1]=\ ([r[0][0]*v1x*rady+r[1][0]*v1y*rady+r[2][0]*v1z+pt0[0], r[0][1]*v1x*rady+r[1][1]*v1y*rady+r[2][1]*v1z+pt0[1], r[0][2]*v1x*rady+r[1][2]*v1y*rady+r[2][2]*v1z+pt0[2]]) k = k + 1 ctv = None ctv = Numeric.concatenate((tv[:, 1], tv[:, 0])) # now add the data to the big lists VV.extend(list(ctv)) FF.extend(list(tmpltFaces)) # increase face indices by lenght of vertices tmpltFaces = tmpltFaces + addToFaces VV = Numeric.array(VV).astype('f') FF = Numeric.array(FF).astype('f') # FIXME: should I compute normals? # now we can build the IndexedPolygon geom from DejaVu.IndexedPolygons import IndexedPolygons cylGeom = IndexedPolygons("cyl", vertices=VV, faces=FF, visible=1, invertNormals=self.invertNormals) # copy Cylinders materials into cylGeom matF = self.materials[GL.GL_FRONT] matB = self.materials[GL.GL_BACK] cylGeom.materials[GL.GL_FRONT].binding = matF.binding[:] cylGeom.materials[GL.GL_FRONT].prop = matF.prop[:] cylGeom.materials[GL.GL_BACK].binding = matB.binding[:] cylGeom.materials[GL.GL_BACK].prop = matB.prop[:] # if binding per vertex: if cylGeom.materials[GL.GL_FRONT].binding[1] == viewerConst.PER_VERTEX: newprop = [] props = cylGeom.materials[GL.GL_FRONT].prop[1] for i in xrange(len(faces)): for j in xrange(len(faces[i]) - 1): vi1 = self.faceSet.faces.array[i][j] vi2 = self.faceSet.faces.array[i][j + 1] colx = props[vi2] coly = props[vi1] # add second color to first half of cyl vertices for k in range(len(tmpltVertices)): newprop.append(coly) # add first color to second half of cyl vertices for l in range(len(tmpltVertices)): newprop.append(colx) cylGeom.materials[GL.GL_FRONT].prop[1] = newprop # and finally... #print "Cylinders.asIndexedPolygons out", quality return cylGeom
natoms=2*nres offset=1.2 width=1.5 import profile # profile.run("smooth, ctrl = ribbon2D( nrib, width, nchords, offset, natoms, cao, [0]*46 );") profile.run("smooth = ribbon2D( nrib, width, nchords, offset, natoms, cao, [0]*46 );") from DejaVu import Viewer vi = Viewer() from DejaVu.IndexedPolygons import IndexedPolygons f = [] n = smooth.shape[1] f = map( lambda x: (x, x+1, x+n+1, x+n), range(smooth.shape[1]-1)) v = Numeric.array(Numeric.reshape(smooth, (-1,4))[:,:3]) p = IndexedPolygons('sheet2D', vertices = v, faces = f, protected=True,) if self.vf.userpref['Sharp Color Boundaries for MSMS']['value'] == 'blur': p.Set(inheritSharpColorBoundaries=False, sharpColorBoundaries=False,) p.replace = False vi.AddObject(p) from DejaVu.Spheres import Spheres ctrl.shape = (-1,4) p = Spheres('ctrl', centers = ctrl[:, :3], radii = 0.6, protected=True) p.replace = False vi.AddObject(p) from DejaVu.Spheres import Spheres s = Spheres('sph', vertices = v, quality=5, protected=True) s.radius = 0.2 vi.AddObject(s)
o = 0 a = 20 vertices = [(o, o, o), (o, a, o), (a, a, o), (a, o, o), (o, o, a), (o, a, a), (a, a, a), (a, o, a)] facesInward = [(3, 2, 1, 0), (7, 6, 2, 3), (5, 6, 7, 4), (0, 1, 5, 4), (2, 6, 5, 1), (4, 7, 3, 0)] facesOutward = [(0, 1, 2, 3), (3, 2, 6, 7), (4, 7, 6, 5), (4, 5, 1, 0), (1, 5, 6, 2), (0, 3, 7, 4)] faces = facesOutward normals = [(0, 0, 1), (-1, 0, 0), (0, 0, -1), (1, 0, 0), (0, -1, 0), (0, 1, 0)] from DejaVu.IndexedPolygons import IndexedPolygons clipBox = IndexedPolygons('clipBox', vertices=vertices, faces=faces, fnormals=normals, frontPolyMode='line', shading='flat') self.readMolecule('/home/annao/python/dev23/1crn.pdb', ask=0, parser=None, log=0) #self.readMolecule('/home/annao/python/dev23/cv.pdb', ask=0, parser=None, log=0) self.browseCommands('msmsCommands', commands=None, log=0, package='Pmv') #self.computeMSMS("1crn;cv", 'MSMS-MOL', perMol=1, density=4.6, log=0, pRadius=1.5) self.computeMSMS("1crn", 'MSMS-MOL', perMol=1, density=4.6, log=0, pRadius=1.5) srf1 = self.Mols[0].geomContainer.geoms['MSMS-MOL'] #srf2 = self.Mols[1].geomContainer.geoms['MSMS-MOL'] cpk1 = self.Mols[0].geomContainer.geoms['cpk'] #cpk2 = self.Mols[1].geomContainer.geoms['cpk']
for ingr in r.ingredients: gi = Geom('%s %s' % (ingr.pdb, ingr.name)) vi.AddObject(gi, parent=gs) orgaToMasterGeom[ingr] = gi r = orga.innerRecipe if r: for ingr in r.ingredients: gi = Geom('%s %s' % (ingr.pdb, ingr.name)) vi.AddObject(gi, parent=gc) orgaToMasterGeom[ingr] = gi tet = IndexedPolygons('surfaceMesh', vertices=orga.vertices, faces=orga.faces, normals=orga.vnormals, inheritFrontPolyMode=False, frontPolyMode='line', inheritCulling=0, culling='none', inheritShading=0, shading='flat') vi.AddObject(tet, parent=g) # display histo BB hbb = Box('histoVolBB', cornerPoints=h1.boundingBox) vi.AddObject(hbb) if ViewerType == 'dejavu': cp = vi.clipP[0] vi.GUI.clipvar[0][0].set(1) tet.AddClipPlane(cp, 1, False) fpg = Points('notFreePoints') vi.AddObject(fpg)
def DisplayFunction(self): if self.frontPolyMode != self.oldFPM: self.RedoDisplayList() IndexedPolygons.DisplayFunction(self)
def asIndexedPolygons(self, run=1, quality=None, centers=None, radii=None, **kw): if __debug__: if hasattr(DejaVu, 'functionName'): DejaVu.functionName() """implement the sphere as an icosaedre. run=0 returns 1 if this geom can be represented as an IndexedPolygon and None if not. run=1 returns the IndexedPolygon object. """ #print "Spheres.asIndexedPolygons", quality if run == 0: return 1 # yes, I can be represented as IndexedPolygons if quality in [1, 2, 3, 4, 5]: quality = quality elif quality < 0 and self.quality in [2, 3, 4, 5]: quality = self.quality - 2 else: quality = self.quality - 1 # get centers if centers is None: centers = self.vertexSet.vertices.array # get radii if radii is None: if self.oneRadius == viewerConst.NO: radii = self.vertexSet.radii.array else: radii = Numeric.ones(centers.shape[0]) * self.radius # create template sphere S = TriangulateIcosByEdgeCenterPoint(quality=quality) tmpltVertices = S.getVertices(quality=quality) tmpltFaces = S.getFaces(quality=quality) tmpltNormals = S.getVNormals(quality=quality) # these lists will store the data for the new spheres vertices = [] faces = [] normals = [] # loop over spheres for i in range(len(centers)): vert = Numeric.array(tmpltVertices[:]) * radii[i] + centers[i] vertices.extend(list(vert)) fac = Numeric.array(tmpltFaces[:]) + i * len(tmpltVertices) faces.extend(list(fac)) norm = Numeric.array(tmpltNormals[:]) normals.extend(list(norm)) sphGeom = IndexedPolygons("sph", vertices=Numeric.array(vertices), faces=faces, vnormals=Numeric.array(normals), visible=1, invertNormals=self.invertNormals) # copy Spheres materials into sphGeom matF = self.materials[GL.GL_FRONT] matB = self.materials[GL.GL_BACK] sphGeom.materials[GL.GL_FRONT].binding = matF.binding[:] sphGeom.materials[GL.GL_FRONT].prop = matF.prop[:] sphGeom.materials[GL.GL_BACK].binding = matB.binding[:] sphGeom.materials[GL.GL_BACK].prop = matB.prop[:] if sphGeom.materials[GL.GL_FRONT].binding[1] == viewerConst.PER_VERTEX: newprop = [] index = 0 cnt = 0 for i in range(len(vertices)): newprop.append(sphGeom.materials[GL.GL_FRONT].prop[1][index]) cnt = cnt + 1 if cnt == len(tmpltVertices): index = index + 1 cnt = 0 sphGeom.materials[GL.GL_FRONT].prop[1] = newprop #print "Spheres.asIndexedPolygons out", quality return sphGeom
natoms=2*nres offset=1.2 width=1.5 import profile # profile.run("smooth, ctrl = ribbon2D( nrib, width, nchords, offset, natoms, cao, [0]*46 );") profile.run("smooth = ribbon2D( nrib, width, nchords, offset, natoms, cao, [0]*46 );") from DejaVu import Viewer vi = Viewer() from DejaVu.IndexedPolygons import IndexedPolygons f = [] n = smooth.shape[1] f = map( lambda x: (x, x+1, x+n+1, x+n), range(smooth.shape[1]-1)) v = Numeric.array(Numeric.reshape(smooth, (-1,4))[:,:3]) p = IndexedPolygons('sheet2D', vertices = v, faces = f, protected=True,) if self.vf.userpref['sharpColorBoundariesForMsms']['value'] == 'blur': p.Set(inheritSharpColorBoundaries=False, sharpColorBoundaries=False,) p.replace = False vi.AddObject(p) from DejaVu.Spheres import Spheres ctrl.shape = (-1,4) p = Spheres('ctrl', centers = ctrl[:, :3], radii = 0.6, protected=True) p.replace = False vi.AddObject(p) from DejaVu.Spheres import Spheres s = Spheres('sph', vertices = v, quality=5, protected=True) s.radius = 0.2 vi.AddObject(s)
def onAddCmdToViewer(self): if not hasattr(self.vf, 'GUI'): return self.undoNow = 0 self.save = None from DejaVu.bitPatterns import pat3 from DejaVu.IndexedPolygons import IndexedPolygons if not self.vf.commands.has_key('setICOM'): self.vf.loadCommand('interactiveCommands', 'setICOM', 'Pmv', topCommand=0) if not self.vf.commands.has_key('measureTorsion'): self.vf.loadCommand('measureCommands', 'measureTorsion', 'Pmv', topCommand=0) self.masterGeom = Geom('setTorsionGeom', shape=(0, 0), pickable=0, protected=True) self.masterGeom.isScalable = 0 self.vf.GUI.VIEWER.AddObject(self.masterGeom, parent=self.vf.GUI.miscGeom) self.lines = IndexedPolygons( 'settorsionLine', materials=((0, 1, 1), ), inheritMaterial=0, stipplePolygons=1, protected=True, ) if self.vf.userpref['Sharp Color Boundaries for MSMS'][ 'value'] == 'blur': self.lines.Set( inheritSharpColorBoundaries=False, sharpColorBoundaries=False, ) self.lines.polygonstipple.Set(pattern=pat3) #, tagModified=False) #self.lines.RenderMode(GL.GL_FILL, face=GL.GL_BACK) self.lines.Set(backPolyMode=GL.GL_FILL) self.labels = GlfLabels(name='settorsionLabel', shape=(0, 3), inheritMaterial=0, materials=((0, 1, 1), )) self.spheres = Spheres(name='settorsionSpheres', shape=(0, 3), radii=0.2, quality=15, inheritMaterial=0, materials=((0., 1., 1.), ), protected=True) for item in [self.lines, self.labels, self.spheres]: self.vf.GUI.VIEWER.AddObject(item, parent=self.masterGeom) self.snakeLength = 1 self.oldValue = None self.torsionType = Tkinter.StringVar() self.torsionType.set('1') self.newAngList = Tkinter.StringVar() self.TAHdata = None self.molecule = None #self.bondString = Tkinter.StringVar() self.callbackDict = {} self.callbackDict['measureDistanceGC'] = 'update' self.callbackDict['measureAngleGC'] = 'update' self.callbackDict['measureTorsionGC'] = 'update'
class QConvex: """Compute convex hull based on a list of 3-D coordinates. Return a DejaVu IndexedPolygon geometry. Usage: self.computeConvex(coords, tpath) coords: a list of [x,y,z] values tpath = optional path for temporary files """ def __init__(self, name='qconvex'): self.geom = IndexedPolygons(name, inheritMaterial=0) self.tmpPath = './' # user can specify path for tmp files # using setTmpPath() method #------------------ HELPER FUNCTIONS ---------------------------------# def writeQConvex(self, filename, coords): """QConvex: http://www.qhull.org/html/qconvex.htm Input a filename and [x,y,z]-coordinates, save this in QConvex format.""" data = [] data.append('3 RBOX c\n') data.append(str(len(coords)) + '\n') for (x, y, z) in coords: data.append('%f %f %f\n' % (x, y, z)) try: f = open(os.path.join(self.tmpPath, filename), 'w') f.writelines(data) f.close() except: print 'QCONVEX ERROR! Cannot write into %s' % self.tmpPath def readQConvex(self, filename): """QConvex: http://www.qhull.org/html/qconvex.htm Read a QConvex output file, output a DejaVu IndexedPolygon. Data Format: [...]print vertices and facets of the convex hull in OFF format. The first line is the dimension. The second line is the number of vertices, facets, and ridges. The vertex coordinates are next, followed by the facets. Each facet starts with the number of vertices. The cube example has four vertices per facet.""" try: f = open(os.path.join(self.tmpPath, filename), 'r') data = f.readlines() f.close() except: print 'QCONVEX ERROR! Temp. file not found in %s' % self.tmpPath return # get more header info header = string.split(data[1]) lenVerts = int(header[0]) lenFaces = int(header[1]) vertices = [] faces = [] for d in data[2:lenVerts + 2]: # offset of 2 because of file header spl = string.split(d) vertices.append([float(spl[0]), float(spl[1]), float(spl[2])]) for d in data[lenVerts + 2:]: # offset of 2 because of file header spl = map(int, string.split(d)) for i in range(3, len(spl)): faces.append([spl[1], spl[i], spl[i - 1]]) self.geom.Set(vertices=vertices, faces=faces) def setTmpPath(self, path): """set the path for the two temporary files. Note: if the specified path does not exist, we try to write into the startup directory""" if path is None: path = './' if path == '': path = os.path.abspath("./") if not os.path.exists(path): print 'QCONVEX ERROR! Path %s does not exist!' % path # use path where we started Python process self.tmpPath = os.path.join(os.path.abspath('./'), '') print 'Trying to save temp. file in: %s' % self.tmpPath else: self.tmpPath = os.path.join(os.path.abspath(path), '') def getGeom(self): """returns the DejaVu IndexedPolygon geometry""" return self.geom #------------------ END HELPER FUNCTIONS ------------------------------# #------------------ USE THIS METHOD: ----------------------------------# def computeConvex(self, coords, tpath=None): ### 1) clean directory, save file in qconvex format: if tpath is not None: self.setTmpPath(tpath) try: os.remove(os.path.join(self.tmpPath, 'tmp_qconvex_input')) except: pass try: os.remove(os.path.join(self.tmpPath, 'tmp_qconvex_output')) except: pass self.writeQConvex(os.path.join(self.tmpPath, 'tmp_qconvex_input'), coords) ### 2) run qconvex, create new output file # FIXME: Please note, this is a hack: we build the path where # qconvex resides, depending on the operating system. In the future, # qconvex might be accessed through a SOAP service! # build a path string for the file qconvex pth = findExecModule('qconvex') if pth is None: return # build string to be executed execstring = pth + ' o < ' + self.tmpPath + 'tmp_qconvex_input > '+\ self.tmpPath + 'tmp_qconvex_output' os.system(execstring) ### 3) load output, return IndexedPolygon self.readQConvex(os.path.join(self.tmpPath, 'tmp_qconvex_output')) ### 4) clean up temporary files try: os.remove(os.path.join(self.tmpPath, 'tmp_qconvex_input')) except: print 'Cannot delete temporary input file' try: os.remove(os.path.join(self.tmpPath, 'tmp_qconvex_output')) except: print 'Cannot delete temporary output file'
def doSetOperation(self, name1, name2, opname, res_name, bindToMol): """ Performs Bspt set operations. """ ex = 0.5 expon = 1.0 bspt_set1 = None bspt_set2 = None if name1 in self.setdict.keys(): #check if we need to recompute the Bspt for the object if self.recomputeBSPT1.get(): if hasattr(self.obj_dict[name1]['obj'], "SLnewobj"): # this object had been created by SL : # do not recompute bspt_set1 = self.setdict[name1] else: #remove the computed Bspt from self.setdict # remove a copy of the object from # self.obj_dict so that the function could use # updated arrays of vertices and faces. del (self.setdict[name1]) if self.obj_dict[name1].has_key('copy_obj'): del (self.obj_dict[name1]['copy_obj']) else: bspt_set1 = self.setdict[name1] if not geometrylib.Size_of_Set(bspt_set1): bspt_set1 = None if not bspt_set1: if self.obj_dict[name1].has_key('copy_obj'): object1 = self.obj_dict[name1]['copy_obj'] else: ## if isinstance(self.obj_dict[name1]['obj'], GleObject): ## object1 = self.obj_dict[name1]['obj'] ## else: object1 = self.obj_dict[name1]['obj'].asIndexedPolygons( run=1, removeDupVerts=0) self.obj_dict[name1]['copy_obj'] = object1 v1 = object1.vertexSet.vertices.array #print "object1: ", object1 ## if isinstance(object1, GleObject): ## f1 = self.triangulate_strips(object1.faceSet.faces.array) ## else: f1 = object1.faceSet.faces.array #print "obj1, verts: ", len(v1), "faces: ", len(f1) brep_set1 = sl.buildBrepSet(v1, f1) t1 = time() bspt_set1 = sl.Brep_To_Bspt(brep_set1, expense=ex, exponent=expon) t2 = time() print "time to build bspt_set1(%s) is %.5f " % (name1, (t2 - t1)) if name2 in self.setdict.keys(): if self.recomputeBSPT2.get(): if hasattr(self.obj_dict[name2]['obj'], "SLnewobj"): bspt_set2 = self.setdict[name2] else: del (self.setdict[name2]) if self.obj_dict[name2].has_key('copy_obj'): del (self.obj_dict[name2]['copy_obj']) else: bspt_set2 = self.setdict[name2] if not geometrylib.Size_of_Set(bspt_set2): bspt_set2 = None if not bspt_set2: if self.obj_dict[name2].has_key('copy_obj'): object2 = self.obj_dict[name2]['copy_obj'] else: object2 = self.obj_dict[name2]['obj'].asIndexedPolygons( run=1, removeDupVerts=0) self.obj_dict[name2]['copy_obj'] = object2 #print "object2: ", object2 v2 = object2.vertexSet.vertices.array ## if isinstance(object2, GleObject): ## f2 = self.triangulate_strips(object2.faceSet.faces.array) ## else: f2 = object2.faceSet.faces.array brep_set2 = sl.buildBrepSet(v2, f2) t1 = time() bspt_set2 = sl.Brep_To_Bspt(brep_set2, expense=ex, exponent=expon) t2 = time() print "time to build bspt_set2(%s) is %.5f " % (name2, (t2 - t1)) rset = sl.operateBsptSets(bspt_set1, bspt_set2, opname, expense=ex, copy="duplicate") brep_set = sl.convert_to_Brep(rset, expense=ex, duplicate=1) verts, faces, vnorms, fnorms = sl.getBoundaries(brep_set, has_vnormals=0, has_fnormals=1) vs, fs, vns, fns = sl.indexedFromArr(verts, faces, fnorms=fnorms) #sl.discardSet(brep_set) #brep_set = None if find(res_name, "_"): #name should not contain "_" res_name = replace(res_name, "_", "-") ## if vs: ## length = map( len, fs) ## mlength = max(length) ## for i in range(len(fs)): ## d = mlength-len(fs[i]) ## if d: ## for j in range(d): ## fs[i].append(-1) vi = self.vf.GUI.VIEWER mol = None res_fullname = 'root|' + res_name if bindToMol: from Pmv.guiTools import MoleculeChooser mol = MoleculeChooser(self.vf).go() if mol: #mol_geom = self.vf.Mols.NodesFromName( molname )[0].geomContainer.masterGeom mol_geom = mol.geomContainer.masterGeom res_fullname = mol_geom.fullName + '|' + res_name #find if an object with the same name already exists: obj_fullnames = self.obj_dict.keys() objnames = map(lambda x: split(x, '|')[-1], obj_fullnames) overwrite = False if res_name in objnames: ind = objnames.index(res_name) if res_fullname in obj_fullnames: ipg = self.obj_dict[res_fullname]['obj'] if hasattr(ipg, "SLnewobj"): # the object is a result # of SL operation if ipg.SLnewobj: overwrite = True # will overwrite the object's # vertices and faces arrays ## if not overwrite: ## ipg = self.obj_dict[ obj_fullnames[ind] ]['obj'] ## if isinstance(ipg, IndexedPolygons): ## #ask the user : ## root = Tkinter.Toplevel() ## root.withdraw() ## from SimpleDialog import SimpleDialog ## ans = SimpleDialog(root, text="Object %s exists. Overwrite it?"% (obj_fullnames[ind],), ## buttons=["Yes", "No"], ## default=0, ## title="overwrite dialog").go() ## root.destroy() ## if ans == 0: ## overwrite = True if overwrite: ipg.Set(vertices=vs, faces=fs, fnormals=fns, freshape=True, tagModified=False) if mol: cl_atoms = self.vf.bindGeomToMolecularFragment(ipg, mol.name, log=0) #addToViewer=False, log=0) if cl_atoms: #self.vf.bindGeomToMolecule.data[res_name]['fns']=fns self.vf.bindGeomToMolecularFragment.data[ ipg.fullName]['fns'] = fns else: ipg = IndexedPolygons( res_name, vertices=vs, faces=fs, #fnormals=fns, #materials=col2, visible=1, inheritMaterial=0, protected=True, ) if self.vf.userpref['Sharp Color Boundaries for MSMS'][ 'value'] == 'blur': ipg.Set( inheritSharpColorBoundaries=False, sharpColorBoundaries=False, ) if mol: cl_atoms = self.vf.bindGeomToMolecularFragment(ipg, mol.name, log=0) if cl_atoms: #self.vf.bindGeomToMolecule.data[res_name]['fns']=fns self.vf.bindGeomToMolecularFragment.data[ ipg.fullName]['fns'] = fns else: vi.AddObject(ipg) else: vi.AddObject(ipg) ipg.Set(frontPolyMode=GL.GL_FILL, shading=GL.GL_FLAT) ipg.Set(fnormals=fns, tagModified=False) self.setdict[ipg.fullName] = rset ipg.SLnewobj = True print "size of bspt_set1:", geometrylib.Size_of_Set(bspt_set1) print "size of bspt_set2:", geometrylib.Size_of_Set(bspt_set2) print "size of rset:", geometrylib.Size_of_Set(rset) else: print "Number of vertices of the resultant object is 0." if name1 not in self.setdict.keys(): self.setdict[name1] = bspt_set1 if name2 not in self.setdict.keys(): self.setdict[name2] = bspt_set2
def doSetOperation(self, name1, name2, opname, res_name, bindToMol): """ Performs Bspt set operations. """ ex = 0.5 expon = 1.0 bspt_set1 = None bspt_set2 = None if name1 in self.setdict.keys(): #check if we need to recompute the Bspt for the object if self.recomputeBSPT1.get(): if hasattr(self.obj_dict[name1]['obj'], "SLnewobj"): # this object had been created by SL : # do not recompute bspt_set1 = self.setdict[name1] else: #remove the computed Bspt from self.setdict # remove a copy of the object from # self.obj_dict so that the function could use # updated arrays of vertices and faces. del(self.setdict[name1]) if self.obj_dict[name1].has_key('copy_obj'): del(self.obj_dict[name1]['copy_obj']) else: bspt_set1 = self.setdict[name1] if not geometrylib.Size_of_Set(bspt_set1): bspt_set1 = None if not bspt_set1: if self.obj_dict[name1].has_key('copy_obj'): object1 = self.obj_dict[name1]['copy_obj'] else: ## if isinstance(self.obj_dict[name1]['obj'], GleObject): ## object1 = self.obj_dict[name1]['obj'] ## else: object1 = self.obj_dict[name1]['obj'].asIndexedPolygons(run=1, removeDupVerts=0) self.obj_dict[name1]['copy_obj'] = object1 v1 = object1.vertexSet.vertices.array #print "object1: ", object1 ## if isinstance(object1, GleObject): ## f1 = self.triangulate_strips(object1.faceSet.faces.array) ## else: f1 = object1.faceSet.faces.array #print "obj1, verts: ", len(v1), "faces: ", len(f1) brep_set1 = sl.buildBrepSet(v1,f1) t1 = time() bspt_set1 = sl.Brep_To_Bspt(brep_set1, expense = ex, exponent = expon) t2 = time() print "time to build bspt_set1(%s) is %.5f " % (name1, (t2-t1)) if name2 in self.setdict.keys(): if self.recomputeBSPT2.get(): if hasattr(self.obj_dict[name2]['obj'], "SLnewobj"): bspt_set2 = self.setdict[name2] else: del(self.setdict[name2]) if self.obj_dict[name2].has_key('copy_obj'): del(self.obj_dict[name2]['copy_obj']) else: bspt_set2 = self.setdict[name2] if not geometrylib.Size_of_Set(bspt_set2): bspt_set2 = None if not bspt_set2: if self.obj_dict[name2].has_key('copy_obj'): object2 = self.obj_dict[name2]['copy_obj'] else: object2 = self.obj_dict[name2]['obj'].asIndexedPolygons(run=1, removeDupVerts=0) self.obj_dict[name2]['copy_obj'] = object2 #print "object2: ", object2 v2 = object2.vertexSet.vertices.array ## if isinstance(object2, GleObject): ## f2 = self.triangulate_strips(object2.faceSet.faces.array) ## else: f2 = object2.faceSet.faces.array brep_set2 = sl.buildBrepSet(v2,f2) t1 = time() bspt_set2 = sl.Brep_To_Bspt(brep_set2, expense = ex, exponent = expon) t2 = time() print "time to build bspt_set2(%s) is %.5f " % (name2, (t2-t1)) rset = sl.operateBsptSets(bspt_set1, bspt_set2, opname, expense=ex, copy = "duplicate") brep_set= sl.convert_to_Brep(rset, expense=ex, duplicate=1) verts, faces , vnorms,fnorms = sl.getBoundaries(brep_set, has_vnormals = 0, has_fnormals = 1) vs,fs,vns,fns = sl.indexedFromArr(verts, faces, fnorms=fnorms) #sl.discardSet(brep_set) #brep_set = None if find(res_name, "_"): #name should not contain "_" res_name = replace(res_name, "_", "-") ## if vs: ## length = map( len, fs) ## mlength = max(length) ## for i in range(len(fs)): ## d = mlength-len(fs[i]) ## if d: ## for j in range(d): ## fs[i].append(-1) vi = self.vf.GUI.VIEWER mol= None res_fullname = 'root|'+res_name if bindToMol: from Pmv.guiTools import MoleculeChooser mol = MoleculeChooser(self.vf).go() if mol: #mol_geom = self.vf.Mols.NodesFromName( molname )[0].geomContainer.masterGeom mol_geom = mol.geomContainer.masterGeom res_fullname = mol_geom.fullName+'|'+res_name #find if an object with the same name already exists: obj_fullnames = self.obj_dict.keys() objnames = map(lambda x: split(x, '|')[-1], obj_fullnames) overwrite = False if res_name in objnames: ind = objnames.index(res_name) if res_fullname in obj_fullnames: ipg = self.obj_dict[res_fullname]['obj'] if hasattr(ipg, "SLnewobj"): # the object is a result # of SL operation if ipg.SLnewobj: overwrite = True # will overwrite the object's # vertices and faces arrays ## if not overwrite: ## ipg = self.obj_dict[ obj_fullnames[ind] ]['obj'] ## if isinstance(ipg, IndexedPolygons): ## #ask the user : ## root = Tkinter.Toplevel() ## root.withdraw() ## from SimpleDialog import SimpleDialog ## ans = SimpleDialog(root, text="Object %s exists. Overwrite it?"% (obj_fullnames[ind],), ## buttons=["Yes", "No"], ## default=0, ## title="overwrite dialog").go() ## root.destroy() ## if ans == 0: ## overwrite = True if overwrite: ipg.Set(vertices = vs, faces = fs,fnormals = fns, freshape = True, tagModified=False) if mol: cl_atoms = self.vf.bindGeomToMolecularFragment( ipg, mol.name,log=0) #addToViewer=False, log=0) if cl_atoms: #self.vf.bindGeomToMolecule.data[res_name]['fns']=fns self.vf.bindGeomToMolecularFragment.data[ipg.fullName]['fns']=fns else: ipg = IndexedPolygons(res_name, vertices = vs, faces = fs, #fnormals=fns, #materials=col2, visible=1, inheritMaterial=0, protected=True,) if self.vf.userpref['sharpColorBoundariesForMsms']['value'] == 'blur': ipg.Set(inheritSharpColorBoundaries=False, sharpColorBoundaries=False,) if mol: cl_atoms = self.vf.bindGeomToMolecularFragment( ipg, mol.name, log=0) if cl_atoms: #self.vf.bindGeomToMolecule.data[res_name]['fns']=fns self.vf.bindGeomToMolecularFragment.data[ipg.fullName]['fns']=fns else: vi.AddObject(ipg) else: vi.AddObject(ipg) ipg.Set(frontPolyMode=GL.GL_FILL, shading=GL.GL_FLAT) ipg.Set(fnormals = fns, tagModified=False) self.setdict[ipg.fullName] = rset ipg.SLnewobj = True print "size of bspt_set1:", geometrylib.Size_of_Set(bspt_set1) print "size of bspt_set2:", geometrylib.Size_of_Set(bspt_set2) print "size of rset:", geometrylib.Size_of_Set(rset) else: print "Number of vertices of the resultant object is 0." if name1 not in self.setdict.keys(): self.setdict[name1] = bspt_set1 if name2 not in self.setdict.keys(): self.setdict[name2] = bspt_set2
def getSurface(self, mols, atomSet, bindGeom, parents=None): if not mols: atomSet = [atomSet] mols = [None] from types import ListType if type(self.isovalue) != ListType: isovals = [self.isovalue] else: isovals = self.isovalue if len(isovals) != len(mols): isovals = [isovals[0]]*len(mols) if not parents: if self.vf.hasGui: parents = [self.vf.GUI.VIEWER.rootObject] else: parents = [None] Xdim, Ydim, Zdim = self.gridSize bindcmd = self.vf.bindGeomToMolecularFragment surfaces = [] checkComp = self.checkComponentsFlag.get() #print "in getSurface:", "mols:", mols, "atomSet:", atomSet, "bindGeom:", bindGeom, "parents:", parents for mol, atms, parent, isovalue in zip(mols, atomSet, parents, isovals): coords = None surf = None params = {"nodes": atms, "resolution": self.surf_resolution, "perMol":True, "gridSize":self.gridSize[0], "bindGeom": bindGeom, "padding":self.padding, "isovalue":isovalue} grid3D = self.UTblur(atms, Xdim, Ydim, Zdim, self.padding, self.surf_resolution) #print "UTblur", grid3D coords, indices, normals = self.UTisocontour(grid3D, isovalue) if coords is None: continue #print "UTisocontour", "coords:", len(coords) if self.vf.hasGui: surf = self.objectByNameAndParent(self.surfName, parent) if surf: #print "surface %s with parent %s exists, resetinng its verts and indices" % (self.surfName, parent.name) surf.Set(vertices=coords, faces=indices, tagModified=False, vnormals=normals, inheritMaterial=None) if checkComp: #print "checking for connected components" newindices, newfaces = self.checkConnectedComponents(surf) surf.Set(vertices=newfaces, faces=newindices) else: from DejaVu.IndexedPolygons import IndexedPolygons surf = IndexedPolygons(name=self.surfName, vertices=coords, faces=indices, tagModified=False, vnormals=normals, inheritMaterial=None) #print "surf:", surf if checkComp: newindices, newfaces = self.checkConnectedComponents(surf) surf.Set(vertices=newfaces, faces=newindices) if parent: surf.parent = parent surf.fullName = parent.fullName+"|"+self.surfName else: surf.fullName=self.surfName #print "Adding surf to viewer, parent:", parent if self.vf.hasGui: self.vf.GUI.VIEWER.AddObject(surf, parent) if not surf: continue if bindGeom: #print "binding geom ", surf bindcmd(surf, atms, log=0) surfaces.append(surf) self.CSparams[surf.fullName] = params if self.vf.userpref['Sharp Color Boundaries for MSMS']['value'] == 'blur': for surf in surfaces: surf.Set(inheritSharpColorBoundaries=False, sharpColorBoundaries=False,) # highlight selection selMols, selAtms = self.vf.getNodesByMolecule(self.vf.selection, Atom) lMolSelectedAtmsDict = dict( zip( selMols, selAtms) ) for surf in surfaces: if hasattr(surf, 'mol') and lMolSelectedAtmsDict.has_key(surf.mol): lSelectedAtoms = lMolSelectedAtmsDict[surf.mol] if len(lSelectedAtoms) > 0 and len(surf.vertexSet.vertices) > 0: lAtomVerticesDict = bindcmd.data[surf.fullName]['atomVertices'] highlight = [0] * len(surf.vertexSet.vertices) for lSelectedAtom in lSelectedAtoms: try: lVertexIndices = lAtomVerticesDict.get(lSelectedAtom, []) for lVertexIndex in lVertexIndices: highlight[lVertexIndex] = 1 except: pass surf.Set(highlight=highlight) ## if perMol: ## surf.removeFacesWithoutHighlightedVertices() return surfaces
def onAddCmdToViewer(self): from DejaVu.Points import CrossSet self.startCross = CrossSet('StartCross', materials=((1., 1., 0), ), inheritMaterial=0, protected=True, offset=1.0, lineWidth=5, visible=0, pickable=0, listed=0) self.endCross = CrossSet('EndCross', materials=((0, 1, 1), ), inheritMaterial=0, protected=True, offset=1.0, lineWidth=5, visible=0, pickable=0, listed=0) from DejaVu.IndexedPolygons import IndexedPolygons from DejaVu.Box import Box from DejaVu.Spheres import Spheres from DejaVu import viewerConst from DejaVu.bitPatterns import patternList from opengltk.OpenGL import GL face = ((0, 3, 2, 1), (3, 7, 6, 2), (7, 4, 5, 6), (0, 1, 5, 4), (1, 2, 6, 5), (0, 4, 7, 3)) coords = ((1, 1, -1), (-1, 1, -1), (-1, -1, -1), (1, -1, -1), (1, 1, 1), (-1, 1, 1), (-1, -1, 1), (1, -1, 1)) #new style RGB-> materials = ( (0, 0, 1), (0, 1, 0), (0, 0, 1), (0, 1, 0), (1, 0, 0), (1, 0, 0), ) box = IndexedPolygons('Box', materials=materials, vertices=coords, faces=face, inheritMaterial=0, visible=0, protected=True, listed=0) box.Set(frontPolyMode=GL.GL_LINE) box.Set(backPolyMode=GL.GL_LINE) box.Set(culling=GL.GL_NONE) box.inheritShading = 0 box.shading = GL.GL_FLAT box.Set(matBind=viewerConst.PER_PART) box.polygonstipple.Set(pattern=patternList[0]) box.Set(stipplePolygons=1) box.transparent = 0 self.box = box self.spheres = Spheres('Spheres', visible=0, inheritMaterial=0, radii=(0.3, ), protected=True, listed=0) self.halo = Spheres('Halo', visible=0, inheritMaterial=0, radii=(0.5, ), protected=True, listed=0) from DejaVu.Geom import Geom AutoLigand_geoms = Geom("AutoLigand_geoms", shape=(0, 0), listed=0) self.vf.GUI.VIEWER.AddObject(AutoLigand_geoms, parent=self.vf.GUI.miscGeom) self.vf.GUI.VIEWER.AddObject(self.startCross, parent=AutoLigand_geoms) self.vf.GUI.VIEWER.AddObject(self.endCross, parent=AutoLigand_geoms) self.vf.GUI.VIEWER.AddObject(self.box, parent=AutoLigand_geoms) self.vf.GUI.VIEWER.AddObject(self.spheres, parent=AutoLigand_geoms) self.vf.GUI.VIEWER.AddObject(self.halo, parent=AutoLigand_geoms) self.grids = {} self.vf.showCitation.citations["AutoLigand"] = """
class MeasureTorsionGUICommand(MeasureGUICommand): """Label torsion between four atoms (color coded cyan) Accumulates picked atoms.Draws polygons and labels showing the torsion angle between groups of 4 selected atoms (color-coded cyan).Userpref 'measureTorsionSL' sets the 'snakeLength' which is how many torsion measureDisplays can be seen at the same time.When more than that number are measured, the first torsion measured is no longer labeled. \nPackage : Pmv \nModule : measureCommands \nClass : MeasureTorsionGUICommand \nCommand : measureTorsionGC \nSynopsis:\n torsion/None<---measureTorsionGC(atoms) \nRequired Argument:\n atoms --- the atom(s) \ntorsion --- returned when the number of atoms is a multiple of 4 """ def __init__(self, func=None): MeasureGUICommand.__init__(self, func=func) self.flag = self.flag | self.objArgOnly def onAddCmdToViewer(self): from DejaVu.bitPatterns import pat3 from DejaVu.IndexedPolygons import IndexedPolygons if not self.vf.commands.has_key('setICOM'): self.vf.loadCommand('interactiveCommands', 'setICOM', 'Pmv', topCommand=0) if not self.vf.commands.has_key('measureAngle'): self.vf.loadCommand('measureCommands', 'measureAngle', 'Pmv', topCommand=0) self.masterGeom = Geom('measureTorsionGeom', shape=(0, 0), pickable=0, protected=True) self.masterGeom.isScalable = 0 if self.vf.hasGui: measure_geoms = check_measure_geoms(self.vf.GUI) self.vf.GUI.VIEWER.AddObject(self.masterGeom, parent=measure_geoms) self.lines = IndexedPolygons('torsionLine', materials=((0, 1, 1), ), culling=GL.GL_NONE, inheritStipplePolygons=0, inheritMaterial=0, stipplePolygons=1, backPolyMode=GL.GL_FILL, frontPolyMode=GL.GL_FILL, protected=True, pickable=0) if self.vf.userpref['Sharp Color Boundaries for MSMS'][ 'value'] == 'blur': self.lines.Set( inheritSharpColorBoundaries=False, sharpColorBoundaries=False, ) self.lines.polygonstipple.Set(pattern=pat3) #self.lines.polygonstipple.Set(pattern=pat3, tagModified=False) #self.lines.RenderMode(GL.GL_FILL) #self.lines.RenderMode(GL.GL_FILL, face=GL.GL_BACK) self.labels = GlfLabels(name='torsionLabel', shape=(0, 3), font='arial1.glf', fontStyle='solid3d', fontScales=(.5, .5, .3), inheritMaterial=0, materials=((0, 1, 1), )) self.spheres = Spheres(name='torsionSpheres', shape=(0, 3), inheritMaterial=0, radii=0.2, quality=15, materials=((0., 1., 1.), ), protected=True) if self.vf.hasGui: for item in [self.lines, self.labels, self.spheres]: self.vf.GUI.VIEWER.AddObject(item, parent=self.masterGeom) doc = """Number of labeled torsions displayed. Valid values are integers>0""" self.vf.userpref.add('Measured Torsions', 4, callbackFunc=[self.setLength_cb], category="Molecules", validateFunc=lambda x: x > 0, doc=doc) #used after startICOM is invoked doc = """Continuous update of torsions if 'transformRoot only' is turned off and viewer's current object is not Root.""" choices = ['yes', 'no'] self.vf.userpref.add('Continuous Update Torsion', 'yes', choices, callbackFunc=[self.continuousUpdate_cb], category="Molecules", doc=doc) self.snakeLength = 4 def __call__(self, atoms, **kw): """torsion/None<-measureTorsionGC(atoms) \natoms --- the atom(s) \ntorsion --- returned when the number of atoms is a multiple of 4""" if type(atoms) is types.StringType: self.nodeLogString = "'" + atoms + "'" ats = self.vf.expandNodes(atoms) if not len(ats): return 'ERROR' return apply(self.doitWrapper, (ats, ), kw) def doit(self, ats): for at in ats: lenAts = len(self.atomList) if lenAts and lenAts % 4 != 0 and at == self.atomList[-1]: continue self.atomList.append(at) if len(self.atomList) > 4 * self.snakeLength: self.atomList = self.atomList[4:] self.update() if len(self.labelStrs) and len(self.atomList) % 4 == 0: return float(self.labelStrs[-1]) def update(self, forward=1, event=None): if not len(self.atomList): self.spheres.Set(vertices=[]) #self.spheres.Set(vertices=[], tagModified=False) self.labels.Set(vertices=[]) #self.labels.Set(vertices=[], tagModified=False) self.lines.Set(vertices=[]) #self.lines.Set(vertices=[], tagModified=False) self.vf.GUI.VIEWER.Redraw() return limit = self.snakeLength #each time have to recalculate lineVertices self.lineVertices = [] for at in self.atomList: c1 = self.getTransformedCoords(at) self.lineVertices.append(tuple(c1)) #display spheres: if len(self.lineVertices) % 4: self.spheres.Set( vertices=self.lineVertices[-(len(self.lineVertices) % 4):]) else: self.spheres.Set(vertices=[]) #self.spheres.Set(vertices=self.lineVertices, tagModified=False) self.vf.GUI.VIEWER.Redraw() #label with torsion #lines between spheres are only drawn when angle completed #that is, len(ats)%4=0 if len(self.lineVertices) < 4: self.labels.Set(vertices=[]) #self.labels.Set(vertices=[], tagModified=False) self.lines.Set(vertices=[]) #self.lines.Set(vertices=[], tagModified=False) else: #rebuild labels and polygons each time self.labelCenters = [] self.labelStrs = [] #labelCenters, labelStrs, #this gets done lenATs/4 times numItems = len(self.atomList) / 4 for i in range(numItems): at0 = self.atomList[i * 4] at1 = self.atomList[i * 4 + 1] at2 = self.atomList[i * 4 + 2] at3 = self.atomList[i * 4 + 3] torsion = self.vf.measureTorsion(at0, at1, at2, at3, topCommand=0) torsionLabel = '%.3f' % torsion self.labelStrs.append(torsionLabel) c0 = self.getTransformedCoords(at0) c1 = self.getTransformedCoords(at3) newcenter = tuple((c0 + c1) / 2.0) self.labelCenters.append(newcenter) #to reset labels, lines and fan, EACH TIME self.labels.Set(vertices=self.labelCenters, labels=self.labelStrs) #tagModified=False) #if len(self.lineVertices)%4!=0: #self.lineVertices = self.lineVertices[:numItems*4] #only draw lines in groups of 4 #numItems*4 if len(self.atomList) % 4 == 0: faces = range(numItems * 4) faces = Numeric.reshape(faces, (-1, 4)) ###FIX THIS ###on undo: if you have just wrapped, undoing the next pt ###breaks because trying to set the vertices uses the old ###faces if not forward: self.lines.Set(vertices=[], faces=[]) #self.lines.Set(vertices=[], faces=[], tagModified=False) self.lines.Set(vertices=self.lineVertices, faces=faces, freshape=1) #freshape=1, tagModified=False) self.vf.GUI.VIEWER.Redraw() else: #this only works going forward: undo breaks here if len(self.lines.faceSet.faces.array) > numItems: faces = range((numItems + 1) * 4) faces = Numeric.reshape(faces, (-1, 4)) if forward: faces = faces[1:] else: faces = faces[:-1] self.lines.Set(faces=faces) self.vf.GUI.VIEWER.Redraw()
def onAddCmdToViewer(self): from DejaVu.bitPatterns import pat3 from DejaVu.IndexedPolygons import IndexedPolygons if not self.vf.commands.has_key('setICOM'): self.vf.loadCommand('interactiveCommands', 'setICOM', 'Pmv', topCommand=0) if not self.vf.commands.has_key('measureAngle'): self.vf.loadCommand('measureCommands', 'measureAngle', 'Pmv', topCommand=0) self.masterGeom = Geom('measureTorsionGeom', shape=(0, 0), pickable=0, protected=True) self.masterGeom.isScalable = 0 if self.vf.hasGui: measure_geoms = check_measure_geoms(self.vf.GUI) self.vf.GUI.VIEWER.AddObject(self.masterGeom, parent=measure_geoms) self.lines = IndexedPolygons('torsionLine', materials=((0, 1, 1), ), culling=GL.GL_NONE, inheritStipplePolygons=0, inheritMaterial=0, stipplePolygons=1, backPolyMode=GL.GL_FILL, frontPolyMode=GL.GL_FILL, protected=True, pickable=0) if self.vf.userpref['Sharp Color Boundaries for MSMS'][ 'value'] == 'blur': self.lines.Set( inheritSharpColorBoundaries=False, sharpColorBoundaries=False, ) self.lines.polygonstipple.Set(pattern=pat3) #self.lines.polygonstipple.Set(pattern=pat3, tagModified=False) #self.lines.RenderMode(GL.GL_FILL) #self.lines.RenderMode(GL.GL_FILL, face=GL.GL_BACK) self.labels = GlfLabels(name='torsionLabel', shape=(0, 3), font='arial1.glf', fontStyle='solid3d', fontScales=(.5, .5, .3), inheritMaterial=0, materials=((0, 1, 1), )) self.spheres = Spheres(name='torsionSpheres', shape=(0, 3), inheritMaterial=0, radii=0.2, quality=15, materials=((0., 1., 1.), ), protected=True) if self.vf.hasGui: for item in [self.lines, self.labels, self.spheres]: self.vf.GUI.VIEWER.AddObject(item, parent=self.masterGeom) doc = """Number of labeled torsions displayed. Valid values are integers>0""" self.vf.userpref.add('Measured Torsions', 4, callbackFunc=[self.setLength_cb], category="Molecules", validateFunc=lambda x: x > 0, doc=doc) #used after startICOM is invoked doc = """Continuous update of torsions if 'transformRoot only' is turned off and viewer's current object is not Root.""" choices = ['yes', 'no'] self.vf.userpref.add('Continuous Update Torsion', 'yes', choices, callbackFunc=[self.continuousUpdate_cb], category="Molecules", doc=doc) self.snakeLength = 4
def __init__(self, name='qconvex'): self.geom = IndexedPolygons(name, inheritMaterial=0) self.tmpPath = './' # user can specify path for tmp files
planePoint = (3., 0., 0.) planeNormal = (1., 0., 0.) vertsC, facesC = cap(vertices, faces, planePoint, planeNormal) from DejaVu import Viewer vi = Viewer() from DejaVu.IndexedPolygons import IndexedPolygons tet = IndexedPolygons('surfaceMesh', vertices=vertices, faces=faces, vnormals=vnormals, inheritFrontPolyMode=False, frontPolyMode='line', inheritCulling=0, culling='none', inheritShading=0, shading='flat', visible=0) vi.AddObject(tet) #from DejaVu.Spheres import Spheres #sectionVsph = Spheres('sectionV', vertices=vertsS, radii=(0.02,)) #vi.AddObject(sectionVsph) #from DejaVu.Points import Points #sectionVpts = Points('sectionV', vertices=allvertsS) #sectionVpts = Points('sectionV', vertices=[vertsS[14], vertsS[159], vertsS[158]]) #vi.AddObject(sectionVpts)
class SetTorsionGUICommand(MeasureTorsionGUICommand): def guiCallback(self): self.save = self.vf.ICmdCaller.commands.value["Shift_L"] self.vf.setICOM(self, modifier="Shift_L", topCommand=0) if not hasattr(self, 'form'): self.buildForm() else: self.form.deiconify() def onAddCmdToViewer(self): if not hasattr(self.vf, 'GUI'): return self.undoNow = 0 self.save = None from DejaVu.bitPatterns import pat3 from DejaVu.IndexedPolygons import IndexedPolygons if not self.vf.commands.has_key('setICOM'): self.vf.loadCommand('interactiveCommands', 'setICOM', 'Pmv', topCommand=0) if not self.vf.commands.has_key('measureTorsion'): self.vf.loadCommand('measureCommands', 'measureTorsion', 'Pmv', topCommand=0) self.masterGeom = Geom('setTorsionGeom', shape=(0, 0), pickable=0, protected=True) self.masterGeom.isScalable = 0 self.vf.GUI.VIEWER.AddObject(self.masterGeom, parent=self.vf.GUI.miscGeom) self.lines = IndexedPolygons( 'settorsionLine', materials=((0, 1, 1), ), inheritMaterial=0, stipplePolygons=1, protected=True, ) if self.vf.userpref['Sharp Color Boundaries for MSMS'][ 'value'] == 'blur': self.lines.Set( inheritSharpColorBoundaries=False, sharpColorBoundaries=False, ) self.lines.polygonstipple.Set(pattern=pat3) #, tagModified=False) #self.lines.RenderMode(GL.GL_FILL, face=GL.GL_BACK) self.lines.Set(backPolyMode=GL.GL_FILL) self.labels = GlfLabels(name='settorsionLabel', shape=(0, 3), inheritMaterial=0, materials=((0, 1, 1), )) self.spheres = Spheres(name='settorsionSpheres', shape=(0, 3), radii=0.2, quality=15, inheritMaterial=0, materials=((0., 1., 1.), ), protected=True) for item in [self.lines, self.labels, self.spheres]: self.vf.GUI.VIEWER.AddObject(item, parent=self.masterGeom) self.snakeLength = 1 self.oldValue = None self.torsionType = Tkinter.StringVar() self.torsionType.set('1') self.newAngList = Tkinter.StringVar() self.TAHdata = None self.molecule = None #self.bondString = Tkinter.StringVar() self.callbackDict = {} self.callbackDict['measureDistanceGC'] = 'update' self.callbackDict['measureAngleGC'] = 'update' self.callbackDict['measureTorsionGC'] = 'update' def onRemoveObjectFromViewer(self, mol): lenAts = len(self.atomList) #if cmd has no atoms on its list, nothing to do if not lenAts: return #remove any atoms which are being deleted from viewer self.atomList = AtomSet(self.atomList) - mol.allAtoms #if some have been removed, do an update if lenAts != len(self.atomList): self.update() self.extslider.set(0) def __call__(self, atoms, angle=None, **kw): """torsion/None<-setTorsionGC(atoms, angle=None) the torsion is returned when the number of atoms is a multiple of 4""" ats = self.vf.expandNodes(atoms) if not len(ats): return 'ERROR' return apply(self.doitWrapper, ( ats, angle, ), kw) def doit(self, ats, angle): for at in ats: lenAts = len(self.atomList) if lenAts and lenAts % 4 != 0 and at == self.atomList[-1]: continue if len(self.atomList) == 0: self.molecule = at.top if at.top == self.molecule: self.atomList.append(at) else: #all atoms in torsion must be in same molecule ...(?) s = at.full_name() + " not in " + self.molecule.full_name() self.warningMsg(s) return 'ERROR' if len(self.atomList) > 4 * self.snakeLength: self.atomList = self.atomList[4:] self.update() if len(self.atomList) == 4: mol = self.atomList[0].top at0, at1, at2, at3 = self.atomList self.mov_atoms = mol.subTree(at1, at2, mol.allAtoms) self.oldValue = self.vf.measureTorsion.doit(at0, at1, at2, at3) self.origValue = self.oldValue self.origCoords = self.mov_atoms.coords if hasattr(self, 'extslider'): self.extslider.set(self.oldValue, update=0) if angle: #angle is what you want to end up with deltaAngle = angle - self.oldValue #print 'deltaAngle=', deltaAngle, 'angle=', angle self.transformCoords(deltaAngle) if hasattr(self, 'extslider'): self.extslider.set(angle, update=0) #s = self.atomList[2].full_name()+'--'+self.atomList[3].full_name() #self.bondString.set(s) self.updateHistory() ##if self.undoNow: raise 'abc' #return float(self.labelStrs[-1]) return def update(self, forward=1, event=None): if not len(self.atomList): self.spheres.Set(vertices=[], tagModified=False) self.labels.Set(vertices=[], tagModified=False) self.lines.Set(vertices=[], tagModified=False) self.vf.GUI.VIEWER.Redraw() return limit = self.snakeLength #each time have to recalculate lineVertices self.lineVertices = [] for at in self.atomList: c1 = self.getTransformedCoords(at) self.lineVertices.append(tuple(c1)) #display spheres: self.spheres.Set(vertices=self.lineVertices, tagModified=False) self.vf.GUI.VIEWER.Redraw() #label with torsion #lines between spheres are only drawn when angle completed #that is, len(ats)%4=0 if len(self.lineVertices) < 4: self.labels.Set(vertices=[], tagModified=False) self.lines.Set(vertices=[], tagModified=False) else: #rebuild labels and polygons each time self.labelCenters = [] self.labelStrs = [] #labelCenters, labelStrs, #this gets done lenATs/4 times numItems = len(self.atomList) / 4 for i in range(numItems): at0, at1, at2, at3 = self.atomList[i * 4:i * 4 + 4] torsion = self.vf.measureTorsion.doit(at0, at1, at2, at3) torsionLabel = '%.3f' % torsion self.labelStrs.append(torsionLabel) c0 = self.getTransformedCoords(at0) c1 = self.getTransformedCoords(at3) newcenter = tuple((c0 + c1) / 2.0) self.labelCenters.append(newcenter) self.vf.GUI.VIEWER.Redraw() items = self.callbackDict.keys() #items = ['measureDistanceGC','measureAngleGC','measureTorsionGC'] #checkout whether measure update needs to be called icomVals = self.vf.ICmdCaller.commands.value.values() for item in items: if not len(icomVals): break if not hasattr(self.vf, item): continue exec('cmd = self.vf.' + item) if cmd in icomVals: #cmd.update() s = self.callbackDict[item] exec('self.vf.' + item + '.' + s + '()') def transformCoords(self, deltaAngle): """ deltaAngle is NOW not final angle wanted but relative""" #mov_coords is the array of the coords of the atoms to be moved, #x2 and x3 are atoms which define the axis of the transformation #by deltaAngle. NB: effect is that mov_atoms.coords #are transformed... if not hasattr(self, 'mov_atoms'): return if not len(self.mov_atoms): return x1, x2, x3, x4 = self.atomList nc = self.vf.setRelativeTorsion.doit(x2, x3, deltaAngle, self.mov_atoms, returnVal=1) mol = x2.top #mov_atoms = mol.subTree(x2, x3, mol.allAtoms) for i in range(len(nc)): at = self.mov_atoms[i] at._coords[at.conformation] = nc[i].tolist() event = EditAtomsEvent('coords', self.mov_atoms) self.vf.dispatchEvent(event) self.update() #####Callback Functions for the Dial: #####slideCallback def slideCallback(self, eventval): #print 'in slideCallback' if len(self.atomList) != 4: return if not hasattr(self, 'oldValue'): return if self.oldValue == None: return #self.setupUndoBefore(self.atomList, self.oldValue) try: newAngle = self.extslider.get() tT = self.torsionType.get() at0, at1, at2, at3 = self.atomList #torsion = self.vf.measureTorsion.doit(at0, at1, at2, at3) torsion = self.oldValue if tT == '1': #NEWdeltaAngle = newAngle deltaAngle = newAngle - torsion else: #NEWdeltaAngle = newAngle + torsion deltaAngle = newAngle self.transformCoords(deltaAngle) #print 'deltaAngle=', deltaAngle self.oldValue = newAngle #self.oldValue = newAngle except ValueError: self.vf.GUI.message("error in slideCallback\n") def rdSet(self, event=None): #"""radiobutton selection of torsionType: #Absolute: initial angle to be displayed in slider/entry #Relative: 0 is displayed """ if self.torsionType.get() == '1': aL = self.atomList if len(aL) == 4: torsion = self.vf.measureTorsion.doit(aL[0], aL[1], aL[2], aL[3]) self.extslider.set(torsion) else: self.extslider.set(0) def setupUndoBefore(self, ats, angle): pass #def setupUndoBefore(self, ats, angle): ##no atoms, <4 atoms, #aSet = AtomSet(self.atomList) #self.undoMenuString = self.name #if len(self.atomList)==0: #undoCmd = 'self.setTorsionGC.atomList=[]; self.setTorsionGC.update()' #elif len(self.atomList)<4: ##need to step back here #undoCmd = 'self.setTorsionGC.atomList=self.setTorsionGC.atomList[:-1]; self.setTorsionGC.update()' #else: ##print 'self.oldValue=', self.oldValue #undoCmd = 'self.setTorsionGC(\''+ aSet.full_name()+ '\',' + str(self.oldValue) + ', topCommand=0)' ##self.oldValue = str(self.extslider.get()) #self.vf.undo.addEntry((undoCmd), (self.name)) def setupUndoAfter(self, ats, angle, **kw): #no atoms, <4 atoms, aSet = AtomSet(self.atomList) self.undoMenuString = self.name if len(self.atomList) == 0: undoCmd = 'self.setTorsionGC.atomList=[]; self.setTorsionGC.update()' elif len(self.atomList) < 4: #need to step back here undoCmd = 'self.setTorsionGC.atomList=self.setTorsionGC.atomList[:-1]; self.setTorsionGC.update()' elif self.origValue == self.oldValue: return else: restoreAngle = self.origValue self.undoNow = 1 undoCmd = 'self.setTorsionGC(\'' + aSet.full_name() + '\',' + str( restoreAngle) + ', topCommand=0)' self.vf.undo.addEntry((undoCmd), (self.name)) def Accept_cb(self): apply(self.setupUndoAfter, (self.atomList, self.oldValue), {}) self.origValue = self.oldValue def Done_cb(self): self.vf.setICOM(self.save, modifier="Shift_L", mode='pick', topCommand=0) self.stopICOM() def startICOM(self): self.vf.setIcomLevel(Atom) if not hasattr(self, 'form'): self.buildForm() else: self.form.deiconify() def stopICOM(self): if hasattr(self, 'form'): self.form.withdraw() self.atomList = [] self.atomCenters = [] self.labelStrs = [] self.labelCenters = [] self.lineVertices = [] self.spheres.Set(vertices=[], tagModified=False) self.lines.Set(vertices=[], faces=[], tagModified=False) self.labels.Set(vertices=[], tagModified=False) self.vf.GUI.VIEWER.Redraw() #when cmd stops being icom, remove callback ## ehm = self.vf.GUI.ehm ## for event in ['<B2-Motion>', '<B3-Motion>']: ## if ehm.eventHandlers.has_key(event) and self.update_cb in \ ## ehm.eventHandlers[event]: ## ehm.RemoveCallback(event, self.update_cb) for event in ['<B2-Motion>', '<B3-Motion>']: self.vf.GUI.removeCameraCallback(event, self.update_cb) def repeat_transTors(self, event=None): deltaAngle = self.extslider.get() if self.torsionType.get() != '1': self.transformCoords(deltaAngle) #this is here in order to create a log message nc = self.vf.setRelativeTorsion(self.atomList[1], self.atomList[2], deltaAngle, self.mov_atoms, returnVal=1) event = EditAtomsEvent('coords', self.mov_atoms) self.vf.dispatchEvent(event) def new_Tors(self, event=0): self.atomList = [] self.update() #when called, most recent 4 atoms are in self.atomList def updateHistory(self): """1: call TorsionHistory.getTorsion: make a new TorsionAngle or add current angle to angleList 2: put TA.name_string into ListBox 3: best if insert a tuple (string to be displayed, item itself) 4: adjust size with self.historyList.configure(height=self.[].size) 5: limit overall size to 4""" #print 'in updateHistory' molecule = self.atomList[-1].top if self.TAHdata is None: self.TAHdata = TorsionHistory(molecule) a1, a2, a3, a4 = self.atomList newone = self.TAHdata.getTorsion(a1, a2, a3, a4) #first check to see if it is in there already??? #need to get info back from getTorsion....(???) if hasattr(self, 'historyList'): if newone.new: self.historyList.insert('end', newone.name_string) if int(self.historyList.cget('height')) < 4: self.historyList.configure(height=self.historyList.size()) if self.historyList.curselection(): self.historyList.select_clear(self.historyList.curselection()) newindex = self.TAHdata.getIndex(newone) self.historyList.select_set(newindex) self.historyList.see(newindex) #set entry to a string ==current TA's angleList newstring = "" for item in newone.angleList: newstring = newstring + " " + "%5.3f" % item self.newAngList.set(newstring) def HLCommand(self, event=None): """double-clicking selection in listbox causes curselection to be picked... 1:self.atomList set to atoms of curselection 2:self.mov_atoms set to atoms of curselection 3:self.selAtom[1-4].Set(vertices=atoms.coords) 4:reset entry +slider and init_bondAngle etc 5.add current angle to selection's.angleList""" #get TA: if self.historyList.get(0) == '': return items = self.historyList.curselection() if type(items) == types.TupleType: items = items[0] try: items = map(int, items) except ValueError: pass thisTA = self.TAHdata.torslist[items[0]] #get currentAngle current = thisTA.getCurrentAngle() if not thisTA.inList(current): thisTA.angleList.append(current) newAts = AtomSet([thisTA.atom1,thisTA.atom2, thisTA.atom3,\ thisTA.atom4]) #reset self.molecule self.atomList = [] self.molecule = newAts[0].top self.doit(newAts, current) #self.setTorsionAngle(thisTA.atom1, thisTA.atom2, thisTA.atom3, thisTA.atom4, current, 'A') #self.drawTransformedAngle() #self.updatespheres(items[0]) #self.update() self.extslider.set(current, 0) newstring = "" for item in thisTA.angleList: newstring = newstring + " " + "%5.3f" % item self.newAngList.set(newstring) def getAngList(self, event=None): items = self.historyList.curselection() try: items = map(int, items) except ValueError: pass thisTA = self.TAHdata.torslist[items[0]] thisTA.angleList = map(float, split(self.newAngList.get())) last = thisTA.angleList[-1] newAts = AtomSet([thisTA.atom1,thisTA.atom2, thisTA.atom3,\ thisTA.atom4]) #reset self.molecule self.atomList = [] self.molecule = newAts[0].top self.doit(newAts, last) #self.doit(thisTA.atom1, thisTA.atom2, thisTA.atom3, thisTA.atom4,last,'A') #self.setTorsionAngle(thisTA.atom1, thisTA.atom2, thisTA.atom3, thisTA.atom4,last,'A') #self.drawTransformedAngle() #self.updatespheres(items[0]) self.extslider.set(last, 0) def stepBack(self, event=None): items = self.historyList.curselection() if len(items) == 0: return try: items = map(int, items) except ValueError: pass thisTA = self.TAHdata.torslist[items[0]] ####last angle is thisTA.angleList[-1] if len(thisTA.angleList) > 1: last = thisTA.angleList[-1] lastIndex = thisTA.angleList.index(last) thisTA.angleList = thisTA.angleList[:lastIndex] last = thisTA.angleList[-1] else: last = thisTA.angleList[0] newAts = AtomSet([thisTA.atom1,thisTA.atom2, thisTA.atom3,\ thisTA.atom4]) #reset self.molecule self.atomList = [] self.molecule = newAts[0].top self.doit(newAts, last) #self.doit(thisTA.atom1, thisTA.atom2, thisTA.atom3, thisTA.atom4,last,'A') #self.setTorsionAngle(thisTA.atom1, thisTA.atom2, thisTA.atom3, thisTA.atom4,last,'A') #self.drawTransformedAngle() #self.updatespheres(items[0]) newstring = "" for item in thisTA.angleList: newstring = newstring + " " + "%5.3f" % item self.newAngList.set(newstring) self.extslider.set(last, 0) #IS THIS ENOUGH in order to create correct log? self.mouseUp() def startOver(self, event=None): items = self.historyList.curselection() if len(items) == 0: return try: items = map(int, items) except ValueError: pass thisTA = self.TAHdata.torslist[items[0]] self.resetAngle(thisTA) def resetAngle(self, thisTA, event=None): #first angle is thisTA.angleList[0] ang = thisTA.angleList[0] newAts = AtomSet([thisTA.atom1,thisTA.atom2, thisTA.atom3,\ thisTA.atom4]) #reset self.molecule self.atomList = [] self.molecule = newAts[0].top self.doit(newAts, ang) #self.doit(thisTA.atom1, thisTA.atom2, thisTA.atom3, thisTA.atom4,ang,'A') #self.setTorsionAngle(thisTA.atom1, thisTA.atom2, thisTA.atom3, thisTA.atom4,ang,'A') if len(thisTA.angleList) > 1: thisTA.angleList = thisTA.angleList[:1] #self.drawTransformedAngle() self.extslider.set(ang, 0) self.mouseUp() self.newAngList.set("%5.3f" % ang) def resetAll(self, event=None): if self.TAHdata == None: return for item in self.TAHdata.torslist: self.resetAngle(item) self.spheres.Set(vertices=[], tagModified=False) self.vf.GUI.VIEWER.Redraw() def buildForm(self): if hasattr(self, 'ifd'): return self.torsionType = Tkinter.StringVar() self.torsionType.set('1') self.ifd = ifd = InputFormDescr(title='Set Torsion Angle') ifd.append({ 'name': 'extLabel', 'widgetType': Tkinter.Label, 'wcfg': { 'text': 'Set Angle:\n(180=trans)' }, 'gridcfg': { 'sticky': Tkinter.W + Tkinter.E, 'columnspan': 2 } }) ifd.append({ 'name': 'extslider', 'widgetType': ExtendedSliderWidget, 'wcfg': { 'label': 'torsion', 'minval': -360., 'maxval': 360., 'width': 150, 'immediate': 1, 'command': self.slideCallback, 'sliderType': 'float', 'entrypackcfg': { 'side': 'bottom' } }, 'gridcfg': { 'sticky': 'we', 'columnspan': 2 } }) ifd.append({ 'name': 'typeLabel', 'widgetType': Tkinter.Label, 'wcfg': { 'text': 'Torsion Type' }, 'gridcfg': { 'sticky': 'we', 'columnspan': 2 } }) ifd.append({ 'name': 'rdbut1', 'widgetType': Tkinter.Radiobutton, 'wcfg': { 'text': 'Absolute', 'variable': self.torsionType, 'value': 1, 'command': self.rdSet }, 'gridcfg': { 'sticky': 'we' } }) ifd.append({ 'name': 'rdbut2', 'widgetType': Tkinter.Radiobutton, 'wcfg': { 'text': 'Relative ', 'variable': self.torsionType, 'value': 0, 'command': self.rdSet }, 'gridcfg': { 'sticky': 'we', 'row': -1, 'column': 1 } }) ifd.append({ 'name': 'historyList', 'widgetType': ListChooser, 'wcfg': { 'title': 'TorsionAngle\nTranformation History', 'mode': 'single', 'command': self.HLCommand, 'lbwcfg': { 'height': 5, 'selectforeground': 'yellow', 'exportselection': 0, 'width': 30 }, }, 'gridcfg': { 'sticky': 'we', 'columnspan': 2 } }) ifd.append({ 'name': 'hbut1', 'widgetType': Tkinter.Button, 'wcfg': { 'text': 'Step Back ', 'command': self.stepBack }, 'gridcfg': { 'sticky': 'we', 'columnspan': 2 } }) ifd.append({ 'name': 'hbut2', 'widgetType': Tkinter.Button, 'wcfg': { 'text': 'Start Over ', 'command': self.startOver }, 'gridcfg': { 'sticky': 'we', 'columnspan': 2 } }) ifd.append({ 'name': 'hbut3', 'widgetType': Tkinter.Button, 'wcfg': { 'text': 'Reset All ', 'command': self.resetAll }, 'gridcfg': { 'sticky': 'we', 'columnspan': 2 } }) ifd.append({ 'name': 'angListEnt', 'widgetType': Tkinter.Entry, 'wcfg': { 'width': 5, 'command': self.getAngList, 'textvariable': self.newAngList }, 'gridcfg': { 'sticky': 'we', 'columnspan': 2 } }) ifd.append({ 'name': 'hbut4', 'widgetType': Tkinter.Button, 'wcfg': { 'text': 'Move', 'command': self.repeat_transTors }, 'gridcfg': { 'sticky': 'we', 'columnspan': 2 } }) ifd.append({ 'name': 'hbut5', 'widgetType': Tkinter.Button, 'wcfg': { 'text': 'New Torsion', 'command': self.new_Tors }, 'gridcfg': { 'sticky': 'we', 'columnspan': 2 } }) #ifd.append({'name':'accept', #'widgetType': Tkinter.Button, #'wcfg':{'text' : 'Accept', #'command': self.Accept_cb}, #'gridcfg':{'sticky':'we'}}) ifd.append({ 'name': 'done', 'widgetType': Tkinter.Button, 'wcfg': { 'text': 'Done', 'command': self.Done_cb }, 'gridcfg': { 'sticky': 'we', 'columnspan': 2 } }) #'gridcfg':{'sticky':'we','column':1, 'row':-1}}) self.form = self.vf.getUserInput(ifd, modal=0, blocking=0) self.form.root.protocol('WM_DELETE_WINDOW', self.Done_cb) self.extslider = self.ifd.entryByName['extslider']['widget'] self.extslider.draw.bind('<ButtonRelease-1>', self.mouseUp, add='+') self.extslider.entry.bind('<Return>', self.mouseUp, add='+') self.historyList = self.ifd.entryByName['historyList']['widget'].lb #self.historyList.bind("<Double-Button-1>",self.HLCommand) self.hbut1 = self.ifd.entryByName['hbut1']['widget'] self.hbut2 = self.ifd.entryByName['hbut2']['widget'] self.hbut3 = self.ifd.entryByName['hbut3']['widget'] self.angListEnt = self.ifd.entryByName['angListEnt']['widget'] def mouseUp(self, event=None): #print "in mouseUp" #fix this: atomList length dependent if len(self.atomList) == 4: at0, at1, at2, at3 = self.atomList angle = self.extslider.get() if self.torsionType.get() == '1': self.vf.setTorsion(at0, at1, at2, at3, angle) else: self.vf.setRelativeTorsion(at1, at2, angle)
def readOBJ(filename): if (filename is None) or (filename == ''): return None lGroupNames = Numeric.zeros(128 * 256, typecode="c") lGroupNames.shape = (128, 256) lLibNames = Numeric.zeros(128 * 256, typecode="c") lLibNames.shape = (128, 256) lMaterialNames = Numeric.zeros(128 * 256, typecode="c") lMaterialNames.shape = (128, 256) out = detectObjFileContent(filename, lGroupNames, lLibNames, lMaterialNames) lGeoms = [] if out[0] is True: lMaterialNames = lMaterialNames[:out[3]] lNumOfLibs = out[2] materialDict = {'default': Materials()} for i in range(len(lMaterialNames)): materialName = pythonStringFromCString(lMaterialNames[i]) materialDict[materialName] = Materials() libNames = [] for i in range(lNumOfLibs): libNames.append(pythonStringFromCString(lLibNames[i])) materialDict.update(readMTL(libNames[-1])) materialList = [] for i in range(len(lMaterialNames)): materialName = pythonStringFromCString(lMaterialNames[i]) materialList.append(materialDict[materialName]) lNumOfGeoms = out[1] for i in range(lNumOfGeoms): lGroupName = pythonStringFromCString(lGroupNames[i]) out = readObjFileGroup(filename, lGroupName, None, None, None, None, None, None) if out[0] is True and out[2] > 0 and out[3] > 0: vertices = Numeric.zeros(out[2] * 3, typecode="f") vertices.shape = (out[2], 3) faces = Numeric.zeros(out[3] * 3, typecode="i") faces.shape = (out[3], 3) textureVertices = Numeric.zeros(out[4] * 2, typecode="f") textureVertices.shape = (out[4], 2) textureFaces = Numeric.zeros(out[5] * 3, typecode="i") textureFaces.shape = (out[5], 3) if (len(libNames) > 0) and (len(lMaterialNames) > 1): triangleMaterialIndices = Numeric.zeros(len(faces) * 1, typecode="i") else: triangleMaterialIndices = None out = readObjFileGroup(filename, lGroupName, lMaterialNames, vertices, faces, textureVertices, textureFaces, triangleMaterialIndices) if out[0] is True: if len(textureVertices) > 0: geom = IndexedPolygons(vertices=vertices, faces=faces, textureCoords=textureVertices) else: geom = IndexedPolygons(vertices=vertices, faces=faces) if triangleMaterialIndices is not None: breaked = False for triangleMaterialIndex in triangleMaterialIndices: if triangleMaterialIndex != triangleMaterialIndices[ 0]: breaked = True break if breaked is False: if triangleMaterialIndex == 0: # use inherited pass else: geom.Set(materials=[ materialList[triangleMaterialIndex]. prop[1], ], propName='diffuse', inheritMaterial=False) else: triangleMaterials = [] for triangleMaterialIndex in triangleMaterialIndices: triangleMaterials.append( materialList[triangleMaterialIndex].prop[1] ) geom.Set(materials=triangleMaterials, propName='diffuse', inheritMaterial=False) if (lGroupName == 'default'): nameSplit = os.path.splitext(filename) geom.name = os.path.split(nameSplit[0])[-1] else: geom.name = lGroupName #print "geom.name", geom.name lGeoms.append(geom) return lGeoms else: return None
def Add_Nucleic_Bases(g, properties=None): """ Adds Nucleic Bases to g. g is a geometry created in Pmv.secondaryStructureCommands properties is class that holds information about Nucleic Acids colors and size """ path3D = g.SS.exElt.path3D residues = g.SS.residues total_res = len(residues) vertex_count = 0 vertices = [] res_faces = [] materials = [] height_purine = height_pyrimidine = 0.4 if properties: color_A = properties.color_A color_G = properties.color_G color_T = properties.color_T color_C = properties.color_C color_U = properties.color_U scale_purine = properties.scale_purine scale_pyrimidine = properties.scale_pyrimidine height_purine = properties.height_purine height_pyrimidine = properties.height_pyrimidine else: color_A = [1, 0, 0] color_G = [0, 0, 1] color_T = [0, 1, 0] color_C = [1, 1, 0] color_U = [1, 0.5, 0] scale_purine = scale_pyrimidine = 1.3 height_purine = height_pyrimidine = 0.4 for i in range(total_res): faces = [] NA_type = residues[i].type.strip() l_c = g.SS.exElt.getExtrudeProperties( [residues[i]], 'colors', ) #if missing atoms do not do the base if NA_type in ['A', 'G', 'DA', 'DG']: if checkMissingAtoms(residues[i], [ 'N1.*', 'C2.*', 'N9.*', 'N7.*', 'C8.*', 'C4.*', 'C5.*', 'C6.*', 'N3.*' ]): print("missing atoms in", residues[i]) residues[i]._base_faces = [] residues[i]._coil_colors = len(l_c) * [color_A] continue base_vertices, base_faces = make_purine(residues[i], height_purine, scale_purine) pscale = scale_purine if NA_type in ['A', 'DA']: #28 = number of vertices for the base 20 + 8 materials.extend(28 * [color_A]) residues[i]._coil_colors = len(l_c) * [color_A] elif NA_type in ['G', 'DG']: materials.extend(28 * [color_G]) residues[i]._coil_colors = len(l_c) * [color_G] names = [name.split("@")[0] for name in residues[i].atoms.name] idx = names.index('N9') connetct_to_base = Numeric.array(residues[i].atoms[idx].coords) else: if checkMissingAtoms( residues[i], ['N1.*', 'C2.*', 'N3.*', 'C4.*', 'C5.*', 'C6.*']): print("missing atoms in", residues[i]) residues[i]._base_faces = [] residues[i]._coil_colors = len(l_c) * [color_A] continue base_vertices, base_faces = make_pyrimidine( residues[i], height_pyrimidine, scale_pyrimidine) pscale = 0.9 * scale_pyrimidine if NA_type == 'T': #22 = number of vertices for the base 14 + 8 materials.extend(22 * [color_T]) residues[i]._coil_colors = len(l_c) * [color_T] elif NA_type in ['C', 'DC']: materials.extend(22 * [color_C]) residues[i]._coil_colors = len(l_c) * [color_C] elif NA_type == 'U': materials.extend(22 * [color_U]) residues[i]._coil_colors = len(l_c) * [color_U] else: materials.extend(22 * [color_U]) residues[i]._coil_colors = len(l_c) * [color_U] names = [name.split("@")[0] for name in residues[i].atoms.name] idx = names.index('N1') connetct_to_base = Numeric.array(residues[i].atoms[idx].coords) vertices.extend(base_vertices.tolist()) # v5 *-----------*v1 # /| /| # / | / | # / | / | # v6*-----------*v2 | # path-----|-- | | --|--->connetct_to_base # | *-------|---*v0 # | /v4 | / # | / | / # |/ |/ # *-----------* # v7 v3 O4 = Numeric.array(returnStarOrQuote(residues[i].atoms, 'O4').coords) C4 = Numeric.array(returnStarOrQuote(residues[i].atoms, 'C4').coords) C1 = Numeric.array(returnStarOrQuote(residues[i].atoms, 'C1').coords) C3 = Numeric.array(returnStarOrQuote(residues[i].atoms, 'C3').coords) C2 = Numeric.array(returnStarOrQuote(residues[i].atoms, 'C2').coords) #cent is a vector towards which bases are extruded cent = C4 #this was a center of the sugar ring #copy is needed were, otherwise base_vertices will get changed too v_4 = copy(base_vertices[-4]) v_5 = copy(base_vertices[-3]) v_6 = copy(base_vertices[-2]) v_7 = copy(base_vertices[-1]) dist = (v_5 + v_4 + v_6 + v_7) / 4.0 - cent if i == total_res - 1: pathPoint = path3D[4 * i] else: pathPoint = path3D[4 * i + 1] #here we measure distance between backbone and last 4 vertices of bases d_v = v_4 - pathPoint distToV_4 = Numeric.innerproduct(d_v, d_v) d_v = v_5 - pathPoint distToV_5 = Numeric.innerproduct(d_v, d_v) d_v = v_6 - pathPoint distToV_6 = Numeric.innerproduct(d_v, d_v) d_v = v_7 - pathPoint distToV_7 = Numeric.innerproduct(d_v, d_v) distList1 = [distToV_4, distToV_5, distToV_6, distToV_7] distList2 = [distToV_4, distToV_5, distToV_6, distToV_7] distList1.sort() if pscale > 1: pscale *= pscale for enum in enumerate(distList2): if enum[1] == distList1[0]: distList2[enum[0]] = 0.1 * pscale elif enum[1] == distList1[1]: distList2[enum[0]] = 0.1 * pscale elif enum[1] == distList1[2]: distList2[enum[0]] = 0.5 * pscale elif enum[1] == distList1[3]: distList2[enum[0]] = 0.5 * pscale #max_d = max([distToV_4,distToV_5,distToV_6,distToV_7]) #dist needs to be scaled so that connection to the backbone wont be thin v_4 = v_4 - distList2[0] * dist vertices.append(v_4.tolist()) v_5 = v_5 - distList2[1] * dist vertices.append(v_5.tolist()) v_6 = v_6 - distList2[2] * dist vertices.append(v_6.tolist()) v_7 = v_7 - distList2[3] * dist vertices.append(v_7.tolist()) p_1 = copy(v_4) p_2 = copy(v_5) p_3 = copy(v_6) p_4 = copy(v_7) dToBase = (p_1 + p_2 + p_3 + p_4) / 4. - pathPoint p_1 = p_1 - dToBase p_2 = p_2 - dToBase p_3 = p_3 - dToBase p_4 = p_4 - dToBase #base_face are number from 0, we need to add vertex_count here base_faces += vertex_count faces.extend(base_faces.tolist()) #now do the faces len_base_vertices = len(base_vertices) stem_start = vertex_count + len_base_vertices - 4 faces.append([ stem_start + 1, stem_start + 5, stem_start + 4, stem_start, stem_start, stem_start, stem_start ]) faces.append([ stem_start + 1, stem_start + 2, stem_start + 6, stem_start + 5, stem_start + 5, stem_start + 5, stem_start + 5 ]) faces.append([ stem_start, stem_start + 4, stem_start + 7, stem_start + 3, stem_start + 3, stem_start + 3, stem_start + 3 ]) faces.append([ stem_start + 2, stem_start + 3, stem_start + 7, stem_start + 6, stem_start + 6, stem_start + 6, stem_start + 6 ]) faces.append([ stem_start + 7, stem_start + 4, stem_start + 5, stem_start + 6, stem_start + 6, stem_start + 6, stem_start + 6 ]) vertices.append(p_1.tolist()) vertices.append(p_2.tolist()) vertices.append(p_3.tolist()) vertices.append(p_4.tolist()) stem_start += 4 faces.append([ stem_start + 1, stem_start + 5, stem_start + 4, stem_start, stem_start, stem_start, stem_start ]) faces.append([ stem_start + 1, stem_start + 2, stem_start + 6, stem_start + 5, stem_start + 5, stem_start + 5, stem_start + 5 ]) faces.append([ stem_start, stem_start + 4, stem_start + 7, stem_start + 3, stem_start + 3, stem_start + 3, stem_start + 3 ]) faces.append([ stem_start + 2, stem_start + 3, stem_start + 7, stem_start + 6, stem_start + 6, stem_start + 6, stem_start + 6 ]) faces.append([ stem_start + 7, stem_start + 4, stem_start + 5, stem_start + 6, stem_start + 6, stem_start + 6, stem_start + 6 ]) # #1-2-6-5 # faces.append([stem_start + 7, stem_start + 8,stem_start + 12,stem_start+11, # stem_start+11,stem_start+11,stem_start+11]) # #1-4-8-5 # faces.append([stem_start+7, stem_start+10,stem_start + 14,stem_start + 11, # stem_start + 11,stem_start + 11,stem_start + 11]) # #3-4-8-7 # faces.append([stem_start+9, stem_start+10, stem_start + 14, stem_start + 13, # stem_start + 13,stem_start + 13,stem_start + 13]) # #2-3-7-6 # faces.append([stem_start+8, stem_start+9,stem_start + 13,stem_start + 12, # stem_start + 12,stem_start + 12,stem_start + 12]) vertex_count = vertex_count + len_base_vertices + 8 residues[i]._base_faces = faces faces = [] for residue in residues: faces.extend(residue._base_faces) geom_bases = IndexedPolygons( 'Bases', vertices=vertices, faces=faces, inheritShading=False, shading=GL.GL_FLAT, materials=materials, inheritMaterial=False, ) return geom_bases
def asIndexedPolygons(self, run=1, removeDupVerts=0, **kw): """Should return an IndexedPolygons object if this object can be represented using triangles, else return None. run=0 returns 1 if this geom can be represented as an IndexedPolygon and None if not run=1 returns the IndexedPolygon object. """ #print "GlfLabels::asIndexedPolygons" #import pdb;pdb.set_trace() if run == 0: return 1 # yes, I can be represented as IndexedPolygons self.prepareBillboardAndNormalForAllTextLines() lLenLabelsVertices = len(self.vertexSet.vertices.array) if lLenLabelsVertices != len(self.labels): lSameText = True assert len(self.labels) > 0 if type(self.labels[0]) == types.StringType: output = glf.glfGet3DSolidStringTriangles(self.labels[0]) else: output = glf.glfGet3DSolidStringTriangles(str(self.labels[0])) lNumOfTriangleVertices = len(output[0]) assert lNumOfTriangleVertices == len(output[1]) #assert is a multiple of 3 else: lSameText = False if lLenLabelsVertices != len(self.vertexSet.normals.array): if len(self.vertexSet.normals.array) > 0: lSameOrientation = True lLocalNormal = self.normals[0] else: lLocalNormal = None self.prepareBillboardAndNormalForAllTextLines() lOverallTriangles = [] lOverallVertices = [] lOverallTrianglesColors = [] for i in range(lLenLabelsVertices): #print "i", i if lSameText is False: if type(self.labels[0]) == types.StringType: output = glf.glfGet3DSolidStringTriangles(self.labels[i]) else: output = glf.glfGet3DSolidStringTriangles( str(self.labels[i])) lNumOfTriangleVertices = len(output[0]) assert lNumOfTriangleVertices == len(output[1]) #assert is a multiple of 3 colorFront = Numeric.array(self.materials[GL.GL_FRONT].prop[1], copy=1) lNumOfOverallVertices = len(lOverallVertices) for j in range(lNumOfOverallVertices, lNumOfOverallVertices + lNumOfTriangleVertices, 3): lOverallTriangles.append((j, j + 1, j + 2)) lOverallTrianglesColors.append(colorFront[i]) lMatrix = self.drawOne3dTextLine(None, i) lMatrix.shape = (4, 4) for j in range(lNumOfTriangleVertices): lVertexBeforeTransform = output[0][j] lVertex = [] lVertex.append( lMatrix[0][0] * lVertexBeforeTransform[0] \ + lMatrix[1][0] * lVertexBeforeTransform[1] \ + lMatrix[2][0] * lVertexBeforeTransform[2] \ + lMatrix[3][0] ) lVertex.append( lMatrix[0][1] * lVertexBeforeTransform[0] \ + lMatrix[1][1] * lVertexBeforeTransform[1] \ + lMatrix[2][1] * lVertexBeforeTransform[2] \ + lMatrix[3][1] ) lVertex.append( lMatrix[0][2] * lVertexBeforeTransform[0] \ + lMatrix[1][2] * lVertexBeforeTransform[1] \ + lMatrix[2][2] * lVertexBeforeTransform[2] \ + lMatrix[3][2] ) lOverallVertices.append(lVertex) lIndexedPolygons = IndexedPolygons( self.name + '_glfTriangles', vertices=lOverallVertices, faces=lOverallTriangles, materials=lOverallTrianglesColors, visible=1, invertNormals=self.invertNormals, ) return lIndexedPolygons