This is a read-only mirror of pymolwiki.org

Difference between revisions of "Wfmesh"

From PyMOL Wiki
Jump to navigation Jump to search
m (26 revisions)
 
(14 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 +
{{Infobox script-repo
 +
|type      = script
 +
|filename  = wfmesh.py
 +
|author    = [[User:Tmwsiy|Dan Kulp]]
 +
|license  = -
 +
}}
 +
 
===DESCRIPTION===
 
===DESCRIPTION===
 
This script will create an object for any Wavefront(.OBJ) mesh file.  This is a way to extend the number of objects you can use. Also, you have more control over the coloring, transformations, etc than the CGOs. Although there are a number of these obj files on the web, you can also easily created them with open source tools ([http://www.openfx.org OpenFX], [http://synapses.mcg.edu/tools/xroads/xroads.stm Crossroads3D]). It takes literally, 2 min to get an object created and then loaded into pymol.  Simply open OpenFX Designer, click File->Insert->Model, then choose any of the models (or create your own of course!), then export it as .3ds file.  Then open the .3ds file from Crossroads3D and export as Wavefront OBJ.   
 
This script will create an object for any Wavefront(.OBJ) mesh file.  This is a way to extend the number of objects you can use. Also, you have more control over the coloring, transformations, etc than the CGOs. Although there are a number of these obj files on the web, you can also easily created them with open source tools ([http://www.openfx.org OpenFX], [http://synapses.mcg.edu/tools/xroads/xroads.stm Crossroads3D]). It takes literally, 2 min to get an object created and then loaded into pymol.  Simply open OpenFX Designer, click File->Insert->Model, then choose any of the models (or create your own of course!), then export it as .3ds file.  Then open the .3ds file from Crossroads3D and export as Wavefront OBJ.   
Line 5: Line 12:
  
 
===IMAGES===
 
===IMAGES===
 +
 
[[Image:Starwars_pymol.png|thumb|left|Star Wars Anyone?]]
 
[[Image:Starwars_pymol.png|thumb|left|Star Wars Anyone?]]
 +
 
[[Image:Torus_pymol.png|thumb|left|A Torus, as an example shape you could do. Notice polygon normals are being used...need smoothing!]]
 
[[Image:Torus_pymol.png|thumb|left|A Torus, as an example shape you could do. Notice polygon normals are being used...need smoothing!]]
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
 
  
 
===SETUP===
 
===SETUP===
βˆ’
Simply "run WFMesh.py"
+
Simply "import wfmesh.py"
  
 
===NOTES / STATUS===
 
===NOTES / STATUS===
Line 37: Line 27:
 
*Post problems in the discussion page, on 'my talk' page or just email me : dwkulp@mail.med.upenn.edu
 
*Post problems in the discussion page, on 'my talk' page or just email me : dwkulp@mail.med.upenn.edu
  
 +
===EXAMPLES===
 +
import wfmesh
 +
cd /home/tlinnet/Software/pymol/Pymol-script-repo/files_for_examples
 +
wfmesh.createWFObj('torus.obj','Torus',flip=1)    # Flip = 1, if OBJ created by openFX, crossroads3D combination
 +
wfmesh.createWFObj("torus.obj","Torus2",translate=[5,5,0], flip=1)
 +
wfmesh.createWFObj("ship.obj","Ship")
  
βˆ’
===USAGE===
 
βˆ’
createWFObj file, name  [,translate=[0,0,0]] [,flip=0]
 
βˆ’
 
βˆ’
===EXAMPLES===
 
βˆ’
  createWFObj "ship.obj" "Ship"
 
βˆ’
  createWFObj "torus.obj" "Torus" flip=1  # Flip = 1, if OBJ created by openFX, crossroads3D combination
 
βˆ’
  createWFObj "torus.obj" "Torus" translate=[10,10,0] flip=1     
 
βˆ’
 
 
 
===REFERENCES===
 
===REFERENCES===
 
[http://www.openfx.org OpenFX]
 
[http://www.openfx.org OpenFX]
 
[http://synapses.mcg.edu/tools/xroads/xroads.stm Crossroads3D]
 
[http://synapses.mcg.edu/tools/xroads/xroads.stm Crossroads3D]
βˆ’
 
βˆ’
===SCRIPTS (WFMesh.py)===
 
βˆ’
WFMesh.py
 
βˆ’
<source lang="python">
 
βˆ’
###############################################
 
βˆ’
#  File:          WFObj.py
 
βˆ’
#  Author:        Dan Kulp
 
βˆ’
#  Creation Date: 5/13/05
 
βˆ’
#
 
βˆ’
#  Notes:
 
βˆ’
#  Create openGL objects from a wavefront (obj) file
 
βˆ’
###############################################
 
βˆ’
 
βˆ’
import os
 
βˆ’
import string
 
βˆ’
import re
 
βˆ’
import math
 
βˆ’
from pymol.opengl.gl import *
 
βˆ’
from pymol.callback import Callback
 
βˆ’
 
βˆ’
 
βˆ’
# Wrapper Function, to create a given WFObj with a specific name (flip = 1 if OpenFX + Crossroads used)
 
βˆ’
def createWFObj(file, name,translate=[0,0,0],flip=0):
 
βˆ’
obj = WFMesh(file,translate,flip)
 
βˆ’
cmd.load_callback(obj,name)
 
βˆ’
 
βˆ’
 
βˆ’
# Class for Wavefront Mesh
 
βˆ’
class WFMesh(Callback):
 
βˆ’
 
βˆ’
    verts = []        # list of vertices
 
βˆ’
    polys = []        # list of poylgons
 
βˆ’
    pnorms = []      # list of polynomal normals
 
βˆ’
    vnorms = {}      # dict. of vertex normals
 
βˆ’
    vavenorms = []    # list of vertex normals, redundant -- I'm far froma python pro.
 
βˆ’
    sections = {}    # list of sections of mesh
 
βˆ’
 
βˆ’
    # Read mesh into memory
 
βˆ’
    def readOBJ(self,file):
 
βˆ’
        if os.path.exists(file):
 
βˆ’
    input = open(file,'r')
 
βˆ’
    for line in input:
 
βˆ’
dat = re.split("\s+", line)
 
βˆ’
 
βˆ’
# Find vertex line
 
βˆ’
if line[0] == 'v' and line[1] != 't' and line[1] != 'n':    self.verts.append([dat[1],dat[2],dat[3]])
 
βˆ’
 
βˆ’
# Find polygon line
 
βˆ’
              if line[0] == 'f':    self.polys.append([dat[1],dat[2],dat[3]])
 
βˆ’
 
βˆ’
# Find section line
 
βˆ’
if line[0] == 'g':    self.sections[len(self.polys)] = dat[1]
 
βˆ’
 
βˆ’
 
βˆ’
    # Compute the normals for each polygon and each vertex 
 
βˆ’
    def computeNorms(self):
 
βˆ’
 
βˆ’
# Compute norms for each polygon
 
βˆ’
for p in self.polys:
 
βˆ’
v12 = [float(self.verts[int(p[1])-1][0]) - float(self.verts[int(p[0])-1][0]),\
 
βˆ’
      float(self.verts[int(p[1])-1][1]) - float(self.verts[int(p[0])-1][1]),\
 
βˆ’
      float(self.verts[int(p[1])-1][2]) - float(self.verts[int(p[0])-1][2]) \
 
βˆ’
      ]
 
βˆ’
 
βˆ’
v13 = [float(self.verts[int(p[2])-1][0]) - float(self.verts[int(p[0])-1][0]),\
 
βˆ’
      float(self.verts[int(p[2])-1][1]) - float(self.verts[int(p[0])-1][1]),\
 
βˆ’
      float(self.verts[int(p[2])-1][2]) - float(self.verts[int(p[0])-1][2]) \
 
βˆ’
      ]
 
βˆ’
 
βˆ’
# Compute poly normal
 
βˆ’
polynorm = self.cross(v12,v13)
 
βˆ’
norm = self.normalize(polynorm)
 
βˆ’
 
βˆ’
 
βˆ’
# Files created by OpenFX, Crossroads combination need have their normals flipped
 
βˆ’
if self.flip:
 
βˆ’
norm[0] = -norm[0]
 
βˆ’
norm[1] = -norm[1]
 
βˆ’
norm[2] = -norm[2]
 
βˆ’
 
βˆ’
# Append poly norm to polygonal norm array
 
βˆ’
self.pnorms.append(norm)
 
βˆ’
 
βˆ’
# Add norm to each vertexes norm..
 
βˆ’
        try:
 
βˆ’
    self.vnorms[int(p[0])-1] = [float(self.vnorms[int(p[0])-1][0]) + norm[0],
 
βˆ’
    float(self.vnorms[int(p[0])-1][1]) + norm[1],
 
βˆ’
    float(self.vnorms[int(p[0])-1][2]) + norm[2]
 
βˆ’
  ]
 
βˆ’
except:
 
βˆ’
    self.vnorms[int(p[0])-1] = [norm[0],norm[1],norm[2]]
 
βˆ’
 
βˆ’
        try:  
 
βˆ’
    self.vnorms[int(p[1])-1]  = [float(self.vnorms[int(p[1])-1][0]) + norm[0],
 
βˆ’
    float(self.vnorms[int(p[1])-1][1]) + norm[1],
 
βˆ’
    float(self.vnorms[int(p[1])-1][2]) + norm[2]
 
βˆ’
  ]
 
βˆ’
except:
 
βˆ’
    self.vnorms[int(p[1])-1] = [norm[0],norm[1],norm[2]]
 
βˆ’
 
βˆ’
try:
 
βˆ’
    self.vnorms[int(p[2])-1]  = [float(self.vnorms[int(p[1])-1][0]) + norm[0],
 
βˆ’
    float(self.vnorms[int(p[1])-1][1]) + norm[1],
 
βˆ’
    float(self.vnorms[int(p[1])-1][2]) + norm[2]
 
βˆ’
  ]
 
βˆ’
except:
 
βˆ’
    self.vnorms[int(p[2])-1] = [norm[0],norm[1],norm[2]]
 
βˆ’
 
βˆ’
     
 
βˆ’
        # Average out each vnorm..
 
βˆ’
index = 0
 
βˆ’
      for v in self.vnorms.values():
 
βˆ’
self.vavenorms.append([v[0]/4, v[1]/4, v[2]/4])
 
βˆ’
index += 1
 
βˆ’
 
βˆ’
    # Utility function to normalize a given vector
 
βˆ’
    def normalize(self,v):
 
βˆ’
mag = v[0]*v[0]+v[1]*v[1]+v[2]*v[2]
 
βˆ’
if mag <= 0:
 
βˆ’
      mag = 1
 
βˆ’
else:
 
βˆ’
    mag = math.sqrt(mag)
 
βˆ’
 
βˆ’
return [v[0]/mag, v[1]/mag,v[2]/mag]
 
βˆ’
 
βˆ’
    # Utility cross product function
 
βˆ’
    def cross(self,v1,v2):
 
βˆ’
x = 0
 
βˆ’
y = 1
 
βˆ’
z = 2
 
βˆ’
 
βˆ’
return [v1[y]*v2[z] - v1[z]*v2[y],\
 
βˆ’
v1[z]*v2[x] - v1[x]*v2[z],\
 
βˆ’
v1[x]*v2[y] - v1[y]*v2[x]
 
βˆ’
]
 
βˆ’
         
 
βˆ’
    # Constructor
 
βˆ’
    def __init__(self, file,translate=[0,0,0],flip=0):
 
βˆ’
        self.verts = []
 
βˆ’
        self.polys = []
 
βˆ’
        self.pnorms = []
 
βˆ’
        self.vnorms = {}
 
βˆ’
        self.vavenorms = []
 
βˆ’
self.translate = translate
 
βˆ’
self.flip      = flip
 
βˆ’
 
βˆ’
        print "Read in file: "+str(file)
 
βˆ’
self.readOBJ(file)
 
βˆ’
print "Done reading in WFMesh, now compute norms"
 
βˆ’
self.computeNorms()
 
βˆ’
print "Done computing norms, now display WFMesh"
 
βˆ’
 
βˆ’
    # Draw Function
 
βˆ’
    def __call__(self):
 
βˆ’
 
βˆ’
glColorMaterial(GL_FRONT, GL_DIFFUSE);
 
βˆ’
        glEnable(GL_COLOR_MATERIAL);
 
βˆ’
glShadeModel(GL_SMOOTH);
 
βˆ’
 
βˆ’
# Color Everything grey
 
βˆ’
        glColor3f(0.5,0.5,0.5);
 
βˆ’
 
βˆ’
index = 0
 
βˆ’
glPushMatrix()
 
βˆ’
glTranslated(self.translate[0],self.translate[1],self.translate[2])
 
βˆ’
for p in self.polys:
 
βˆ’
glBegin(GL_POLYGON)
 
βˆ’
glNormal3f(float(self.pnorms[index][0]),float(self.pnorms[index][1]),float(self.pnorms[index][2]))
 
βˆ’
 
βˆ’
for i in range(0,len(p)):
 
βˆ’
glVertex3f(float(self.verts[int(p[i])-1][0]),float(self.verts[int(p[i])-1][1]),float(self.verts[int(p[i])-1][2]))
 
βˆ’
 
βˆ’
# Vertex Normals - not computed correctly, so commented out for now
 
βˆ’
# norm = self.vnorms[int(p[i])-1]
 
βˆ’
# glNormal3f(float(norm[0]),float(norm[1]),float(norm[2]))
 
βˆ’
glEnd()
 
βˆ’
index += 1
 
βˆ’
glPopMatrix()
 
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
 
βˆ’
cmd.extend("createWFObj", createWFObj)
 
βˆ’
 
βˆ’
</source>
 
  
 
===ADDITIONAL RESOURCES===
 
===ADDITIONAL RESOURCES===
Line 242: Line 44:
  
 
[[Category:Script_Library|WFMesh]]
 
[[Category:Script_Library|WFMesh]]
 +
[[Category:ThirdParty_Scripts]]
 +
[[Category:Pymol-script-repo]]

Latest revision as of 04:26, 28 March 2014

Type Python Script
Download wfmesh.py
Author(s) Dan Kulp
License -
This code has been put under version control in the project Pymol-script-repo

DESCRIPTION

This script will create an object for any Wavefront(.OBJ) mesh file. This is a way to extend the number of objects you can use. Also, you have more control over the coloring, transformations, etc than the CGOs. Although there are a number of these obj files on the web, you can also easily created them with open source tools (OpenFX, Crossroads3D). It takes literally, 2 min to get an object created and then loaded into pymol. Simply open OpenFX Designer, click File->Insert->Model, then choose any of the models (or create your own of course!), then export it as .3ds file. Then open the .3ds file from Crossroads3D and export as Wavefront OBJ.

  • createWFMesh - create a mesh object from Wavefront (*.obj) formated file

IMAGES

Star Wars Anyone?
A Torus, as an example shape you could do. Notice polygon normals are being used...need smoothing!

SETUP

Simply "import wfmesh.py"

NOTES / STATUS

  • Tested on Pymolv0.97, Windows platform, should work on linux as well.
  • Coloring is fixed for grey and sections of mesh are stored, but not used.
  • Simple opengl calls; not optimized (display lists, etc) or anything.
  • Vertex Normal code is broken, so normals are per polygon right now.
  • Post problems in the discussion page, on 'my talk' page or just email me : dwkulp@mail.med.upenn.edu

EXAMPLES

import wfmesh
cd /home/tlinnet/Software/pymol/Pymol-script-repo/files_for_examples
wfmesh.createWFObj('torus.obj','Torus',flip=1)    # Flip = 1, if OBJ created by openFX, crossroads3D combination
wfmesh.createWFObj("torus.obj","Torus2",translate=[5,5,0], flip=1)
wfmesh.createWFObj("ship.obj","Ship")

REFERENCES

OpenFX Crossroads3D

ADDITIONAL RESOURCES

Torus.obj Torus.zip