[Chimera-users]
Thomas Goddard
goddard at cgl.ucsf.edu
Fri May 13 10:13:57 PDT 2005
Hi Ute,
The multiscale surfacing method was only intended to produce low resolution
surfaces. Use MSMS surfaces if you want fine detail.
I modified the export surfaces as VRML code so it will also output
MSMS surfaces. It doesn't output the colors if the MSMS surfaces is
being colored according to atom colors. Unfortunately the Chimera
MSMS surface code does not have a way of querying for those colors.
Also the VRML output will not produce a mesh or dot surface, only a
filled surface.
At the end of this message is the new Python code. This replaces file
chimera/share/VRMLoutput/__init__.py
in your Chimera distribution. (On a Mac that would be
Chimera.app/Contents/Resources/share/VRMLoutput/__init__.py).
Be careful not to modify the indentation of the code since that is
important in the Python language.
I tested this on Chimera version 1.2105.
There is an x3dsave Chimera command that outputs MSMS surfaces and
many other Chimera models in X3D format. X3D format is the successor
to VRML. Unfortunately very few programs support this format. Here's
our manual page for x3dsave:
http://www.cgl.ucsf.edu/chimera/docs/UsersGuide/framecommand.html
Tom
------
VRMLoutput/__init__.py follows:
# -----------------------------------------------------------------------------
# Output displayed _surface models as VRML.
#
# -----------------------------------------------------------------------------
#
def surfaces_as_vrml(surface_models):
surf_vrml = ['#VRML V2.0 utf8\n',
'Transform {',
' children [']
import _surface
import chimera
for m in surface_models:
if m.display:
if isinstance(m, _surface.Surface_Model):
glist = filter(lambda g: g.display, m.surface_groups())
for g in glist:
vrml = surface_group_as_vrml(g)
surf_vrml.append(vrml)
elif isinstance(m, chimera.MSMSModel):
vrml = msms_surface_as_vrml(m)
surf_vrml.append(vrml)
surf_vrml.extend([' ]', '}'])
vrml = '\n'.join(surf_vrml)
return vrml
# -----------------------------------------------------------------------------
#
def surface_group_as_vrml(g):
vertex_rgba = g.vertex_colors()
solid_rgba = g.color()
m = g.model
mat = m.material
shine = mat.shininess / 128.0
srgb = mat.specular
if g.display_style() == g.Solid:
v, vi = g.geometry()
n = g.normals()
ts = g.two_sided_lighting()
vrml = surface_vrml(v, vi, n, vertex_rgba, solid_rgba,
ts, shine, srgb)
else:
v, vi = g.edges()
# Mesh lighting not supported in VRML97.
vrml = mesh_vrml(v, vi, vertex_rgba, solid_rgba)
return vrml
# -----------------------------------------------------------------------------
#
def msms_surface_as_vrml(m):
vertex_rgba, solid_rgba, mat, shine, srgb = msms_colors(m)
# TODO: Use m.drawMode (Filled, Mesh, Dot) to control vrml style
vfloat, vint, tri = m.triangleData()
v = vfloat[:,:3]
n = vfloat[:,3:6]
vi = tri[:,:3]
ts = True
vrml = surface_vrml(v, vi, n, vertex_rgba, solid_rgba,
ts, shine, srgb)
return vrml
# -----------------------------------------------------------------------------
#
def msms_colors(m):
if m.colorMode == m.Custom:
vertex_rgba = map(lambda c: c.rgba(), m.customColors)
import Numeric
vertex_rgba = Numeric.array(vertex_rgba, Numeric.Float32)
else:
vertex_rgba = None
# TODO: Handle colorByAtom color mode.
mol = m.molecule
if mol:
c = mol.surfaceColor
if c == None:
c = mol.color
solid_rgba = c.rgba()
mat = c.material
else:
solid_rgba = (1,1,1,1)
import chimera
mat = chimera.MaterialColor(0,0,0).material
shine = mat.shininess / 128.0
srgb = mat.specular
return vertex_rgba, solid_rgba, mat, shine, srgb
# -----------------------------------------------------------------------------
#
def surface_vrml(vertices, vertex_indices, vertex_normals, vertex_rgba,
solid_rgba, two_sided_lighting, shininess, specular_rgb):
vrml_template = \
'''Shape {
appearance Appearance {
material Material {
diffuseColor %s
transparency %.3f
shininess %.3f
specularColor %s
}
}
geometry IndexedFaceSet {
coord Coordinate {
point [
%s
]
}
normal Normal {
vector [
%s
]
}
coordIndex [
%s
]
%s
solid %s
}
}
'''
pts = tuple_string(vertices, '%.6g %.6g %.6g')
ns = tuple_string(vertex_normals, '%.6g %.6g %.6g')
m = polygon_size(vertex_indices)
vi_format = ' '.join(['%d'] * m + ['-1'])
ci = tuple_string(vertex_indices, vi_format)
if vertex_rgba:
clrs = tuple_string(vertex_rgba[:,:3], '%.3f %.3f %.3f')
cspec = 'color Color {\n color [\n%s]\n }\n' % clrs
else:
cspec = ''
srgb, trans = material_colors(vertex_rgba, solid_rgba)
specular = '%.3f %.3f %.3f' % specular_rgb
if two_sided_lighting:
solid = 'FALSE'
else:
solid = 'TRUE'
vrml = vrml_template % (srgb, trans, shininess, specular,
pts, ns, ci, cspec, solid)
return vrml
# -----------------------------------------------------------------------------
# VRML does not handle normals for lines.
#
def mesh_vrml(vertices, vertex_indices, vertex_rgba, solid_rgba):
vrml_template = \
'''Shape {
appearance Appearance {
material Material {
emissiveColor %s
transparency %.3f
}
}
geometry IndexedLineSet {
coord Coordinate {
point [
%s
]
}
coordIndex [
%s
]
%s
}
}
'''
pts = tuple_string(vertices, '%.6g %.6g %.6g')
m = polygon_size(vertex_indices)
vi_format = ' '.join(['%d'] * m + ['-1'])
ci = tuple_string(vertex_indices, vi_format)
if vertex_rgba:
clrs = tuple_string(vertex_rgba[:,:3], '%.3f %.3f %.3f')
cspec = 'color Color {\n color [\n%s]\n }\n' % clrs
else:
cspec = ''
srgb, trans = material_colors(vertex_rgba, solid_rgba)
vrml = vrml_template % (srgb, trans, pts, ci, cspec)
return vrml
# -----------------------------------------------------------------------------
#
def material_colors(vertex_rgba, solid_rgba):
if vertex_rgba:
srgb = '0 0 0'
trans = 1 - max(vertex_rgba[:,3])
else:
srgb = '%.3f %.3f %.3f' % solid_rgba[:3]
trans = 1 - solid_rgba[3]
return srgb, trans
# -----------------------------------------------------------------------------
#
def polygon_size(vertex_indices):
if vertex_indices:
return len(vertex_indices[0])
return 0
# -----------------------------------------------------------------------------
#
def tuple_string(tuples, format):
tuple_strings = []
for t in tuples:
tuple_strings.append(format % tuple(t))
tstring = '\n'.join(tuple_strings)
return tstring
# -----------------------------------------------------------------------------
#
def surface_models():
import chimera
import _surface
mlist = chimera.openModels.list(modelTypes = [_surface.Surface_Model,
chimera.MSMSModel])
return mlist
# -----------------------------------------------------------------------------
#
def write_surfaces_dialog():
import os.path
dir = os.path.dirname(__file__)
help_path = os.path.join(dir, 'helpdir', 'vrml_output.html')
help_url = 'file://' + help_path
import OpenSave
od = OpenSave.SaveModeless(title = 'Save VRML Surfaces',
command = write_surfaces_cb,
multiple = 0,
help = help_url)
od.enter()
# -----------------------------------------------------------------------------
#
def write_surfaces_cb(okayed, dialog):
if okayed:
paths = dialog.getPaths()
if len(paths) == 1:
write_surfaces_as_vrml(paths[0])
# -----------------------------------------------------------------------------
#
def write_surfaces_as_vrml(path):
mlist = surface_models()
vrml = surfaces_as_vrml(mlist)
f = open(path, 'w')
f.write(vrml)
f.close()
More information about the Chimera-users
mailing list