[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