Molecular Graphics Using Maya - Howbert



Animated Molecular Graphics Using Maya

Final Report

Independent Research Project

Computing & Software Systems 499

University of Washington - Bothell

Student: J. Jeffry Howbert

Sponsor: Prof. Kelvin Sung

Term: Fall 2004-Spring 2005

Author contact: peaklist@u.washington.edu or peak.list@

TABLE OF CONTENTS

I. PURPOSE

II. PLAN

A. Input sources

1. Protein Data Bank (.pdb) files

2. Molecular surfaces

B. Architectural components

III. RESULTS

A. Command plug-in readPdbCmd

1. Loading and calling readPdbCmd

2. Manipulating molecular display

a. Transformation of scene view with mouse

b. Altering display mode with dialog box

3. Organization of code in readPdbCmd

4. Limitations of current version of readPdbCmd

B. Node plug-in molSurfNode

1. Loading and calling molSurfNode

2. Manipulating molecular display

a. Transformation of scene view with mouse

b. Altering display with attribute editor

3. Organization of code in molSurfNode

4. Limitations of current version of molSurfNode

C. Use of hotkeys to direct camera motion

D. Conclusions on suitability of Maya for molecular display

IV. WORKING WITH MAYA

A. Maya Help

B. Programming Maya

C. Maya API basics

D. Creating a Command plug-in

1. Use the Maya Plug-in Wizard

2. Create your own .dll project, and implement the Command methods explicitly

3. Ready-to-compile plug-ins included with Maya

E. Creating a Node plug-in

1. Use the Maya Plug-in Wizard

2. Create your own .dll project, and implement the Node methods explicitly

3. Ready-to-compile plug-ins included with Maya

F. Creating a dialog box with controls

G. Defining hotkey commands

H. MEL calls from inside a plug-in

I. PURPOSE

Interactive visualization of complex molecular structures in three dimensions (3D) is of vital importance to biomedical research and drug discovery. The structures to be viewed may be predicted by computational algorithms, or may represent real structures determined by spectroscopic methods such as X-ray crystallography or nuclear magnetic resonance (NMR). In either case, the resulting numeric data sets are large and intricately connected, and the only effective means for communicating the underlying structure is 3D computer graphics. In most cases, it is essential the graphical image be capable of interactive rotation and translation, as this allows free exploration of the structure, as well as engaging human 3D perceptual powers much more fully than is possible with static images. To meet these needs, a number of freeware and commercial molecular visualization packages have been developed, including Protein Explorer, RasMol, Discovery Studio ViewerPro (Accelrys), and the Maestro user interface of the Schrodinger modeling software suite. A comprehensive list of freeware packages can be found at the Protein Data Bank site.

One limitation found in packages investigated prior to this project is the manner in which interactive graphical manipulation occurs. All employ a common approach, wherein dragging the mouse within the viewing window alters the scaling, translation, or rotation of the structure, with scaling and rotation operations occurring relative to the centroid of the displayed structure. In practice, this makes certain changes in viewpoint awkward to attain, for example, moving along the surface of the structure, or looking into small cavities surrounding a ligand binding site. These latter types of viewpoint change require, in effect, movement of the point of view (POV), or camera, within scene space, rather than movement of the structure within scene space.

The available packages also generally appear to have unrelated architectures, with little reliance on pre-existing packages or code, few common standards for their internal chemical and graphical engines, and no interoperability among their APIs. Although most packages read and write external data files in at least a few standard formats, there are also numerous proprietary formats. These points would not be of much consequence, except that most packages appear to be the result of many person-years of programming effort. Future packages with more powerful features might be developed more economically if there existed a suitable molecular graphics development environment, preferably subject to standards and open-source requirements, such that a reusable and extensible code base could accrete over time.

This project arose from a desire to explore how the above two issues could be addressed using a fully integrated 3D animation toolkit, of the type used in creating animated scenes and characters for movies and video games. The software platform chosen was Maya Unlimited 6.0, developed by Alias Wavefront. The perceived strengths of Maya for this project were:

• Mechanisms for facile creation of standard geometric shapes (cylinders, spheres).

• Ability to tie geometric objects together into hierarchies for selection and transformation.

• Mechanisms for creating large mesh surfaces.

• Excellent control over color, lighting, and shading of objects.

• Flexible control over viewpoints (i.e. camera location) in a scene

With the above assets in functionality, it was desired the project should achieve, at a minimum:

• Input from text files of protein molecules containing at least 100 atoms and connecting bonds.

• Display of molecules in several modes, including:

o Stick (bonds only).

o Stick-and-ball (bonds and small atom spheres).

o Space-filling (large, interpenetrating atom spheres).

o Solvent accessible or solvent excluded surface.

• Certain combinations of above display modes, with semi-transparent rendering of molecular surface to allow simultaneous visualization of stick or space-filling representation.

• Keyboard control of point of view (POV), similar to manipulation of first-person POV in video games, to allow interactive close examination of surface and interior details of molecular structure.

II. PLAN

A. Input sources. The molecular display system of this project was designed to accept external input of two types:

1. Protein Data Bank (.pdb) files. These are the standard format used worldwide in the biomedical research community for describing actual 3D structures of biological macromolecules. The macromolecules may be a protein or a nucleic acid (RNA or DNA), a complex of several proteins, a complex of protein with nucleic acid, or any of these in a complex with small molecule ligands such as drugs, cofactors, metal ions, etc. The 3D structure of the macromolecule is usually determined by X-ray crystallography, but other spectroscopic methods, such as NMR, are occasionally employed. The Protein Data Bank currently archives over 30,000 .pdb files of macromolecular structures, which are freely available to the public.

The .pdb format is ASCII text, and organized to be easily read by humans. It consists primarily of XYZ coordinates for atom locations, and data on atom-to-atom bond connections. Other information typically included are protein amino acid sequence and secondary structure, crystallographic space group, and general comments on the biological role of the protein; see the Protein Data Bank site for full details. The format is readily parsed by computer programs to extract atom coordinates and bond connections.

Here is a sample .pdb for a relatively small protein, crambin, found in plant seeds. It has 46 amino acid residues and 327 atoms. It was used extensively in the development of this molecular display system, and is currently the default .pdb for the system.

2. Molecular surfaces. These must be represented using some form of geometric elements readily processed for display by Maya. Such surface representations are not available in a large public archive, but can be generated on demand using the program MSMS, developed in the Molecular Graphics Laboratory at Scripps Research Institute by Michael Sanner. It calculates the solvent excluded surface of a molecule, using as input the molecular coordinates in a standard .pdb file. The solvent excluded surface is represented in triangulated form, i.e. as a closed-surface mesh of vertices, edges, and triangular faces. For a .pdb file named molname.pdb, MSMS outputs two files, molname.vert and molname.face. Each line in molname.vert contains the XYZ coordinates for a vertex and 3 additional values that specify the surface normal at that vertex. In molname.face, each line specifies the vertices composing one triangle of the surface mesh.

Free downloads and documentation on MSMS are available at:



To download a ready-to-run MSMS binary, navigate through six web pages and a login to get to the actual download, where you will find binaries for six different platforms.

The triangulated molecular surface generated by MSMS for the plant protein crambin (see Section II.A.1) is comprised of 2465 vertices and 4926 triangular faces. It was used extensively in the development of this molecular display system, and is currently the default molecular surface for the system.

B. Architectural components. To meet the project’s objectives for molecular display, the following software components were specified. See Section IV, Working with Maya, for background on Maya plug-ins.

1) A Maya plug-in to read a protein .pdb file and convert it into an internal format suitable for generating molecular displays in Maya scene space.

2) A Maya plug-in to convert the internal format into a displayed stick structure, a stick-and-ball structure, or a space-filling structure (could be same as plug-in that reads .pdb).

3) A simple user interface (dialog box with controls) to allow switching between display modes using the mouse.

4) A Maya plug-in to read in a molecular surface representation, convert to an internal format if necessary, and display as an opaque or semi-transparent surface.

5) A Maya plug-in to connect the arrow keys to the scene camera such that camera can be steered in a manner similar to first-person character in video games.

III. RESULTS

A. Command plug-in readPdbCmd. This plug-in accomplishes objectives 1), 2), and 3) laid out in Section II.B of the plan. It was coded in C++ using the approach described in Section IV.D.2.

1. Loading and calling readPdbCmd.

• Open Maya Unlimited 6.0.

• Open Plug-in Manager: Window > Settings/Preferences > Plug-in Manager.

• Click Browse, and navigate to find readPdbCmd.mll. A copy should be in the same directory as this document, in subdirectory readPdbCmd, i.e. at .\readPdbCmd\readPdbCmd.mll. Click Load, then scroll to the bottom of the Plug-in Manager window to check that readPdbCmd was loaded.

• Outside of Maya, confirm that a file named test.pdb exists in the same directory as the readPdbCmd.mll you just loaded.

• Type “readPdb” into the command line window at the bottom left of the Maya display and hit Enter. After several seconds, a space filling model of the molecule in test.pdb will appear, along with a dialog box with six button controls, as shown in Figure 1.

[pic]

Figure 1

The default test.pdb is a protein called crambin; see Section II.A.1. Additional protein .pdb files can be found in subdirectory .\readPdbCmd\protein pdb files, or at the Protein Data Bank site. Remember that any .pdb file can be opened with a text editor to examine its contents; this is often an easy way to get some basic background on the molecule stored within.

NOTE: The current version of the plug-in does not support user selection of arbitrarily named .pbd files from within Maya. To display a different .pdb file, make a copy, rename it test.pdb, and place it in the same directory as readPdbCmd.mll.

When displaying a different .pdb, it is simplest to make the substitution for test.pdb prior to displaying any molecule with the readPdb command. Otherwise, if a molecule has already been displayed, you must:

• Select File > New Scene, and answer Don’t Save. This erases the previous molecule from the display.

• Close the dialog box.

• Outside of Maya, make the substitution for test.pdb.

• Execute the command “readPdb” from the command line again. The new test.pdb will appear.

2. Manipulating molecular display.

a. Transformation of scene view with mouse. Rotation, translation, and scaling of the displayed molecule are achieved using Maya’s native functionality for transforming the scene view. Each type of transformation is effected by dragging the mouse while simultaneously holding down the Alt key and one of the mouse buttons. The mouse buttons map as follows:

• rotation = left mouse button

• translation = middle mouse button

• scaling = right mouse button

See Maya Help: Using Maya > General - Basics > Viewing the scene > Tumble, track, dolly, or tilt the view for more detail, as well as additional modes of controlling camera orientation with the mouse.

b. Altering display mode with dialog box. The display mode of the molecule itself can be altered with the dialog box that appears when readPdbCmd is executed.

NOTE: The current version serves primarily to illustrate how a dialog box can be incorporated into the plug-in, with some simple changes in display mode only as examples of what is possible. A truly useful user interface would likely employ several dialog boxes, each with much more sophisticated functionality.

Initially the molecule appears in space-filling (ball) mode, with these colors for the atom types:

• carbon = white

• nitrogen = red

• oxygen = blue

• all other atom types = white

The buttons on the dialog box cause the following changes to the display:

• Stick – Displays bonds of molecule only. Bonds in backbone of protein are shown in yellow, and bonds in amino acid sidechains are in purple.

• Ball – Display atoms of molecule only, using an approximate space-filling radius of 1.4 Angstroms.

• Surface – Display surface of molecule. NOTE: This display mode is not currently accessible from inside the readPdbCmd plugin; see comments in Section III.A.4.

The remaining buttons apply only to Ball mode, and their effects are only visible in that mode:

• Yellow – Change color of nitrogen atoms from red to yellow.

• Magenta – Change color of carbon atoms from white to magenta.

• Black – Change color of oxygen atoms from blue to black.

• Restore – Restore atom colors to initial color scheme of white, red, and blue.

3. Organization of code in readPdbCmd. This section is concerned with code specific to the readPdbCmd plug-in. Portions derived from initial creation of the plug-in and its generic methods are covered in Section IV.D.2.

The parsing of the .pdb input file, and the subsequent internal storage of atoms and bonds, will be much easier to understand if you simultaneously peruse a typical input file. Every amino acid in the protein sequence has four standard backbone atoms, and from 0 to 8 standard sidechain atoms. The four backbone atoms have atomTypes “N”, “CA” (for C-alpha), “C”, and “O”. The sidechain atoms have atomTypes that include letters such as “B”, “G”, “D”, “E”, “Z”, and “H”. These designate, respectively, the beta, gamma, delta, epsilon, zeta, and eta positions of the sidechain, relative to the attachment at the alpha-carbon.

The major blocks of code are explained below, in the same order in which they appear in file readPdbCmd.cpp:

• struct atomRecord: Declares format of plug-in’s internal storage for an atom. The seven data items in an atomRecord are read directly from one line of the input file.

• struct bondRecord: Declares format of plug-in’s internal storage for a bond. The three data items in a bondRecord are determined by parsing of a corresponding atomRecord.

• Variables used in parsing the input file are declared and initialized. Variables whose names begin with “current” are used to keep track of the atoms most recently found at the standard amino acid backbone and sidechain positions. As each amino acid residue is read in, these variables are updated to point to the atoms in that residue. This allows the appropriate bond connections to be built for the residue during parsing.

• Undimensioned arrays (vectors) are created to hold the internal representation of atoms and bonds.

• In the input loop, data for one atom at a time is read from file test.pdb. Only lines beginning with “ATOM” are processed. The first action in reading the atom data is to capture the values into an atomRecord and add this to the array of atomRecords. The second action is to parse the data for the newly read atom, and create a bond between that atom and some previously read atom. The bond will connect either:

o The backbone “N” of the current amino acid residue to the backbone “C” of the previous residue.

o A backbone atom of the current residue to another backbone atom of the same residue.

o A sidechain beta-carbon of the current residue to the backbone alpha-carbon of the same residue.

o A distal sidechain atom of the current residue to a more proximal sidechain atom of the same residue (e.g. a gamma-carbon to a beta-carbon).

The bond is assigned a bondType, either “bb” for backbone or “sc” for sidechain. The IDs of the two atoms connected by the bond, along with its bondType, are placed into a bondRecord, and this is added to the array of bondRecords.

• The centroid of the molecule is moved to the origin of Maya scene space.

• Three atom shaders are created and colors assigned to them. Calls to MEL create three shading groups in the Maya dependency graph (DG), and the shaders are connected (also by MEL calls) to the shading groups. The same sequence is followed to create and connect two bond shaders to shading groups in the DG.

o For the mechanics of making MEL calls from inside plug-ins, see Section IV.H.

o On the topic of the dependency graph, a brief introduction and pointers to further resources are found in Section IV.C.

o Regarding shaders, shading groups, and their connection into shading networks: these are more advanced topics, and unfortunately no good step-by-step tutorial exists in Maya Help (see Section IV.A) A great deal of information, somewhat useful but poorly organized, is spread around the sections of Maya Help: Using Maya > Rendering and Render Setup – Shading > About shading and texturing surfaces. As an example of working code that produces a simple but fully functional shading network, this segment of plug-in readPdbCmd is probably as good as will be found, and should be suitable for adapting or extending in other applications.

• In a loop over the atoms, MEL calls are applied to each atom to:

o Set the shading group for the atom.

o Create a sphere in the DG.

o Add the atom to a sphere visibility group (for use by the dialog box).

• In a loop over the bonds, MEL calls are applied to each bond to:

o Set the shading group for the bond.

o Create a cylinder in the DG.

o Add the atom to a cylinder visibility group (for use by the dialog box).

• The dialog box is created with seven buttons. A large chunk of MEL script is placed inside a single MString and executed with a single call to executeCommand. In the MEL script, all aspects of the dialog box are specified: the button labels, the individual MEL commands attached to each button, and the layout of the dialog box. More complete details on creating dialog boxes are given in Section IV.F.

4. Limitations of current version of readPdbCmd.

• Does not support parsing of .pdbs for macromolecules other than proteins.

• For proteins, correctly parses only standard amino acid residues in main sequence of protein; will not properly parse non-standard residues, additional off-sequence bond connections, or additional fragments, such as ligands, water molecules, or metal ions.

• May not produce fully accurate displays of multi-chain proteins.

All of the above could be readily implemented, given sufficient time to elaborate the input file parsing in readPdbCmd.

One form of display envisaged in the original design would show a semi-transparent molecular surface enclosing one of the other forms of display (stick or space-filling). Display of molecular surfaces has been successfully achieved with the molSurfNode plug-in (Section III.B). Unfortunately, it has so far proved impossible to instantiate a molSurfNode from inside readPdbCmd, even using the identical MEL script which works from the Maya script editor. If such a display is desired, it is straightforward (if tedious) to run readPdbCmd and molSurfNode separately on the same molecule, and view the displays simultaneously, as shown in Figure 2.

[pic]

Figure 2

B. Node plug-in molSurfNode. This plug-in accomplishes objective 4) laid out in Section II.B of the plan. It was coded in C++ using the approach described in Section IV.E.2.

1. Loading and calling molSurfNode.

• Open Maya Unlimited 6.0.

• Open Plug-in Manager: Window > Settings/Preferences > Plug-in Manager.

• Click Browse, and navigate to find molSurfNode.mll. A copy should be in the same directory as this document, in subdirectory molSurfNode, i.e. at .\molSurfNode\molSurfNode.mll. Click Load, then scroll to the bottom of the Plug-in Manager window to check that molSurfNode was loaded.

• Outside of Maya, confirm that two files, named test.vert and test.face, exist in the same directory as the molSurfNode.mll you just loaded.

• Open Script Editor: Window > General Editors > Script Editor.

• In the Script Editor, go to: File > Open Script.

• Browse to locate MEL script molSurfNode.mel. A copy should be in the same directory as this document, in subdirectory molSurfNode, i.e. at .\molSurfNode\molSurfNode.mel. Click Open. The script will appear in the lower panel of the Script Editor.

• In the Script Editor, go to: Script > Execute. The script will disappear from the lower panel and reappear in the upper panel. After several seconds, a semi-transparent solvent excluded surface of the molecule in test.vert/test.face will appear, as shown in Figure 3.

[pic]

Figure 3

The default protein surface described in files test.vert and test.face is a protein called crambin; see Section II.A.2.

NOTE: The current version of the plug-in does not support user selection of arbitrarily named surfaces from within Maya. To display a different molecular surface, use MSMS to generate .vert and .face files from the protein’s .pdb file, rename the files to test.vert and test.face, and place them in the same directory as molSurfNode.mll.

2. Manipulating molecular display.

a. Transformation of scene view with mouse. The displayed molecular surface may be rotated, translated, and scaled as described in Section III.A.2.a.

b. Altering display with attribute editor. The properties of the displayed surface can be modified using the Attribute Editor, which is visible in the large panel to the right of the Maya scene display. (It may be necessary to move the Plug-in Manager and Script Editor windows to see the Attribute Editor.) The Attribute Editor provides very comprehensive control of the appearance and properties of all nodes in the dependency graph; see Maya Help: Using Maya > General – Tools, Menus, and Nodes > Windows and editors > Attribute Editor, and subtopics therein.

• Click on the displayed surface to select it. A triangulation mesh will appear on the surface, and the attribute interface for molSurfShape1 will appear in the Attribute Editor.

• There should be five tabs across the top of the Attribute Editor. Each tab selects one of the five nodes in the dependency graph (DG) that make up the surface.

o See Section IV.C for an introduction to the DG.

o To see how nodes are connected to one another in the DG, open the Hypergraph: Window > Hypergraph. Select nodes of interest with the mouse (selected nodes are highlighted in yellow), and go to Graph > Input and Output Connections. Repeat this several times, selecting all displayed nodes each time, and you should see a complete diagram of all nodes and connections in the DG.

• Select the tab labeled lambert1. You may need to scroll through the tabs to the right to find it.

• Open the subpanel Common Material Attributes, if it not already open.

• To modify the Color attribute, click on the colored bar to the right of the label Color. The Color Chooser window will appear. It offers a multitude of ways to adjust the color of the surface. Also to the right of the label Color is a slider bar, which allows modification of the value component of the color (in the HSV color system), without having to open the Color Chooser.

• To modify the Transparency attribute, use the slider bar to the right of the label Transparency. It accesses a full range of transparencies, from opaque to invisible.

• Several other attributes, such as Incandescence, also impact the appearance of the surface. Experiment to see which may produce pleasing or useful enhancements of the appearance.

3. Organization of code in molSurfNode. This section is concerned with code specific to the molSurfNode plug-in. Portions derived from initial creation of the plug-in and its generic methods are covered in Section IV.E.2. All code directly concerned with defining surface mesh geometry and creating a visible surface is contained in methods initialize and compute.

This section also explains the MEL commands in MEL script molSurfNode.mel.

The major blocks of code in molSurfNode.cpp are explained below, in the same order in which they appear in the file. Refer to the introductory portions of Section IV.E for background on attributes, data blocks, and data handles.

• In method initialize:

o Two node attributes are created: input and outMesh.

o Attribute properties are set.

o Attributes are added to node.

o Connection between input and output attributes is established.

[ remaining comments concern method compute ]

• A data handle for attribute input is obtained from the data block (named data). This data handle is not actually used in this plug-in, since it receives no input from other nodes.

• An object (named mesh) and data function set (dataCreator) are defined for the mesh to be created later.

• Another object (newOutputData) is created, which will receive the created mesh for output from the node.

• Three undimensioned arrays (named vertices, polygonConnects, and polygonCounts) are defined to hold the internal representation of vertices and faces.

• XYZ vertex coordinates are read from input file test.vert into MPointArray vertices.

• Vertex indices for each triangular face are read from input file test.face into MIntArray polygonConnects.

• Vertex count for each face in polygonCounts is initialized to 3, since all faces are triangles.

• The centroid of the vertices is moved to the origin of Maya scene space.

• The actual mesh is created, using the create method of a mesh object function set (meshFn), the three vertex and face arrays as input, and the object newOutputData as output.

• A data handle to attribute outMesh is obtained from the data block, and the mesh in newOutputData is bound to it.

• Lastly, the output plug is released to the data block (“cleaned”).

After the plug-in executable derived from this code (molSurfNode.mll) is loaded into Maya with the Plug-in Manager, a bit more code is required to produce a visualized molecular surface. This code is contained in MEL script molSurfNode.mel, reproduced below with interleaved comments:

createNode transform -n molSurf1;

• Instantiates a transform node named molSurf1.

createNode mesh -n molSurfShape1 -p molSurf1;

• Instantiates a mesh type node named molSurfShape1, and attaches it to molSurf1 as its transform parent.

createNode molSurfNode -n molSurfNode1;

• Instantiates a node of type molSurfNode, using the code in plug-in molSurfNode, and names it molSurfNode1.

connectAttr molSurfNode1.outMesh molSurfShape1.inMesh;

• Connects the output of molSurfNode1, i.e. the mesh whose geometry is defined by the code in the plug-in, and connects it to the input of molSurfShape1.

sets -add initialShadingGroup molSurfShape1;

• Adds (attaches) molSurfShape1 to the default shading group.

setAttr lambert1.color -type double3 0.0 0.5 0.0;

setAttr lambert1.transparency -type double3 0.5 0.5 0.5;

• These two commands alter the color and transparency of the default shader (lambert1).

DisplayShaded;

• Changes the display mode of the scene so that the shaded, colored surface is visible.

To see a full diagram of the connections among these nodes, use the Hypergraph, as described in Section III.B.2.b.

4. Limitations of current version of molSurfNode.

• Does not properly parse the header lines that exist in .vert and .face files when they are created by MSMS. At present, these header lines must be manually removed before molSurfNode can process.

• Simultaneous display of atom and bond representations with a molecular surface requires independent application of plug-ins readPdbCmd and molSurfNode to the same molecule. This limitation is discussed in Section III.A.4.

C. Use of hotkeys to direct camera motion. This work partially achieves objective 5) laid out in Section II.B of the plan, but without using a plug-in.

Six hotkeys were connected to the default scene camera (persp). Each press of a hotkey causes the camera to move one increment in the direction indicated:

Alt-i rotate camera up

Alt-k rotate camera down

Alt-j rotate camera left

Alt-l rotate camera right

Alt-o move camera forward

Alt-u move camera backward

These connections were made by defining six new hotkey commands, all grouped under hotkey category User. The names of the hotkey commands, and the (one-line) MEL scripts associated with them are:

Alt-i RotateCameraUp rotate -r -os 1.0 0 0 persp;

Alt-k RotateCameraDown rotate -r -os -1.0 0 0 persp;

Alt-j RotateCameraLeft rotate -r -os 0 1.0 0 persp;

Alt-l RotateCameraRight rotate -r -os 0 -1.0 0 persp;

Alt-o MoveCameraForward move -r -os 0 0 -0.5 persp;

Alt-u MoveCameraBackward move -r -os 0 0 0.5 persp

The steps involved in creating hotkey commands are given in Section IV.G.

Unfortunately, Maya seems to disable autorepeat on hotkeys. Autorepeat is highly desirable. Holding down an autorepeating hotkey would cause the camera to move or turn about the scene in real time, with a natural smooth gliding motion. Holding hotkeys down in appropriate sequences would allow the camera to be steered to any vantage point desired.

A significant effort was expended trying to work around this limitation with custom Command and Node plug-ins, but without success. The Maya user interfaces (MEL, API, hotkeys) simply do not support event-driven programming, even though the platform’s native use of the mouse and keyboard suggest there must be forms of it embedded.

D. Conclusions on suitability of Maya for molecular display.

Overall, the molecular displays achieved with Maya are very satisfying. However, the effort required to master the API exceeded expectations by a huge factor, and casts some doubt on the value of Maya as a general platform for molecular display. Here are some salient observations, positive and negative:

Positive

• Maya allows for convenient and rapid generation of geometric objects, both simple shapes such as spheres and cylinders, as well as highly complex surface meshes containing thousands of vertices and faces.

• The color, shading, and transparency of objects are likewise very easy to control.

• Although it was barely exploited in the course of this project, it became clear that Maya’s tools for building hierarchies of objects are indeed powerful and flexible. This would be invaluable in a more sophisticated molecular display package, where selective modification of the properties and orientation of linked groups of atoms is very important.

Negative

• Maya’s C++ API has an immense wealth of functionality, which collectively provides remarkable power to create, render, and animate complex objects and scenes. However, two shortcomings of the API pose serious obstacles, especially when first learning the system:

o The online Maya Help is massive, but not especially well organized. It is often hard or impossible to find answers to seemingly simple questions. Although it has many tutorials, very few are the step-by-step kind suitable for a novice user.

o The high degree of abstraction in the API, with all the function sets, data handles, etc., significantly infringes the degree of control most programmers are accustomed to having over data. It is often a distinct impediment to the rate and flow of coding.

• The greatest disappointment was the inability to develop video game-like control of the user view. This was due primarily to lack of event-driven interfaces. Although Maya has powerful animation capabilities, these in fact relate to creation of fixed sequences of scene transformations. It is not inherently well-suited to development of real-time graphics that are truly interactive.

IV. WORKING WITH MAYA

NOTE: These tutorials assume the reader is working with Maya Unlimited 6.0, Windows XP, and Visual Studio .NET 2002. The instruction provided is probably relevant to other versions of Maya, Windows, and Visual Studio, but has only been tested on the aforementioned combination of platforms.

A. Maya Help. Much of the information needed to follow these tutorials appears on the Maya Help server. The volume of material makes it prohibitive to reproduce here, so links are provided into the Maya Help server where appropriate. Maya Help server should be automatically installed on any machine where Maya 6.0 is installed, and can be started from Maya’s help menu, or standalone via Start > All Programs > Alias > Maya 6.0 > View Maya Docs. Help runs on an Apache server on localhost, using port 4446. Once started, it can be accessed from any browser via URL . If access seems to be blocked, make sure your browser is not trying to reach localhost via a proxy or that some other service hasn’t already claimed port 4446. Also, certain firewall and antivirus products such as ZoneAlarm and Norton Internet Security may block access to the server, and will need to be configured or turned off.

B. Programming Maya. Maya provides two mechanisms for programming in the Maya environment: a scripting language called MEL (Maya Embedded Language), and the Maya API. Both are very powerful and support construction of complex geometric objects, creation of new tools and workflows, and manipulation of object and tool attributes. A full discussion of their capabilities, and the pros and cons of using one or the other for a given task, are beyond the scope of this report. An excellent teaching text covering both is available, “Complete Maya Programming: An Extensive Guide to MEL and the C++ API”, by David A. D. Gould (Morgan Kaufmann, 2003). Maya Help also offers very thorough coverage, although it is often difficult to locate answers to specific questions, especially introductory topics.

In general, the API is preferred (or required) when large amounts of data are being managed or transformed, when more complex procedural algorithms are needed, or the user wishes to implement custom nodes in the Dependency Graph (see below). The API also provides the most direct contact allowed by Maya with its underlying data structures. The API and MEL are in no way mutually exclusive, however. It is routine for modules accessing the API to also have MEL script embedded in them, which is executed by calls to the MEL interpreter.

It became clear early in the project that the scientific programming required was well beyond what MEL could support. Investigation of the API thus became one of the project’s prime objectives. The following tutorials focus on aspects of the API, using both simple examples and the code eventually developed in the course of the project. It should be noted, however, that the project code makes liberal use of embedded MEL, and limited comments on this are made where appropriate.

C. Maya API basics. Some fundamentals regarding the API are important to understand, but not readily appreciated in a first pass through the documentation.

Much of the power of Maya comes from its dependency graph. Geometric objects, as well as data processing units such as transforms and shaders, are encapsulated as nodes. These nodes are connected through their attributes into a network known as the dependency graph (DG). The DG is dynamically updated, so that changes to any node automatically propagates through the graph to all other nodes which are dependent on it. This dynamic updating of the DG is the core of the real-time graphics engine of Maya. Be sure you understand at least this part of Maya’s architecture before attempting any programming. Start with Chapter 2 of Gould’s book, then go to Maya Help: Using Maya > General - Basics > Nodes and Attributes. You can also gain familiarity with the DG by playing with various MEL commands and scripts.

All code accessing the API must be contained within a plug-in. Plug-ins are essentially compiled and linked dynamic link library (.dll) files that carry a special, Maya-recognized filetype suffix, .mll.

To execute the code in a plug-in, it must first be loaded into Maya, then invoked from the command line or a MEL script; see Maya Help: Developer Resources > API Guide > Plug-in API introduction > Loading a Plug-in.

There are over a dozen types of plug-ins, each derived from a different base class; see Gould, Chapter 4.1 for an overview, and Maya Help: Developer Resources > API Guide > Appendices > Overview of example plug-ins. The two most common types are Command (Cmd) plug-ins and Node plug-ins.

Command plug-ings are derived from class MPxCommand. They are used to encapsulate general procedural manipulation of objects and attributes in Maya. See Gould, Chapter 4.3-4.4, and Maya Help: Developer Resources > API Guide > Command plug-ins > Overview of adding commands to Maya … MPxCommand.

Node plug-ins are derived from class MPxNode. They are used to encapsulate objects such as geometric entities, transforms, shaders, etc. See Gould, Chapter 4.5, and Maya Help: Developer Resources > API Guide > Dependency graph plug-ins. Most of the remaining plug-in types are specialized types of Node plug-in, and derive from corresponding subclasses of MPxNode.

The internal data structures of Maya are well-guarded, even for objects you create. With few exceptions, creation and access are done using an abstracted layer of API classes that sit on top of the data objects, called function sets. This approach to data protection, and how to use the function sets, are well described in Gould, Chapter 4.2. A more opaque summary is given in Maya Help: Developer Resources > API Guide > Plug-in API introduction > Interacting with Maya / MObjects / Objects and Function Sets.

D. Creating a Command plug-in. Command plug-ins are required to implement a minimum of four methods:

doIt // does the actual programmatic work of the plug-in

creator // returns an allocated instance of the command

initializePlugin // registers the plug-in when loaded into Maya

uninitializePlugin // deregisters the plug-in when unloaded from Maya

There are two ways to create a Command plug-in that implements the four methods, depending on the development platform you are using. These are described in parts 1 and 2 below.

In addition, Maya provides a large library of ready-to-compile plug-ins, covering a wide range of plug-in types and some very powerful functionality. These can used as is, or possibly modified for other needs. See part 3 below for more detail.

1. Use the Maya Plug-in Wizard. This is approach recommended by Maya, and the easiest if you are working on the right development platform, namely Visual Studio .NET 2003. However, the Plug-in Wizard that comes with Maya Unlimited 6.0 does NOT work under Visual Studio .NET 2002 or Visual Studio 6.0. If you are working on one of those platforms, finish reading this section, but then follow the instructions for the other approach below.

The sequence for using the Plug-in Wizard is given at Maya Help: Developer Resources > API Guide > Setting up your plug-in build environment > Windows environment. Gould has a much more detailed tutorial in Chapter 4.3, but be aware that it describes an earlier Plug-in Wizard that worked with Visual Studio 6.0, so some details could be different. NOTE: neither set of instructions were actually tested during this project, due to lack of appropriate development platform, but both are believed to be reliable.

The Plug-in Wizard creates a .dll type project, sets all the proper paths for include directories and link libaries, and creates an empty .cpp file similar to the following:

#include

DeclareSimpleCommand( testApp, "Alias", "6.0");

MStatus testApp::doIt( const MArgList& )

{

// your application code for the Command goes here

}

The Command name is specified to the Plug-in Wizard by the programmer; in this example, testApp was used. During compilation, the DeclareSimpleCommand macro inserts a declaration for class testApp, along with implementations of the creator, initializePlugin, and uninitializePlugin methods, embedding the name testApp wherever appropriate.

All that remains for the programmer is to add application code into the body of the doIt method. Depending on which parts of the API are being accessed, other Maya .h files will almost certainly need to be included; use the form shown above, #include

2. Create your own .dll project, and implement the Command methods explicitly. The instructions below are applicable to Visual Studio .NET 2002. A similar sequence should work for Visual Studio 6.0, but it has not been explicitly tested, and the particular modifications required are unknown.

This approach relies on a template of C++ code in which .dll export functions are already defined, the Command class is declared, and the four class methods are all implemented. The actual name of the class is specified in two #define statements. A minimal version of the template, genericCmd.cpp, is available in the same directory as this document.

The instructions below produce a fully functional Command plug-in named genericCmd.dll, which can be loaded into Maya and executed from the command line with the command “generic”. It outputs a simple “Hello world”-type message. A more useful plug-in would require additional code in the doIt method, and be given a different class name with the #define statements.

• Create subdirectory genericCmd in a chosen directory. This chosen directory is henceforth referred to as “”.

• Start Visual Studio .NET 2002.

• Select File > New > Blank Solution.

• For Project Types, highlight Visual Studio Solutions, and for Templates, highlight Blank Solution.

• Set Name to “genericCmd” and make sure Location is “”.

• Click OK.

• Select File > Add Project > New Project.

• For Project Types, highlight Visual C++ Projects, and for Templates, highlight Win32 Project.

• Set Name to “genericCmd” and make sure Location is “”.

• Click OK. The Win32 Application Wizard will open. In the Wizard:

o Go to Application Settings.

o Change Application Type from “Windows Application” to “DLL”.

o Check the box for “Empty Project”

o Click Finish.

• Outside of Visual Studio .NET, move a copy of genericCmd.cpp into subdirectory genericCmd.

• Back in Visual Studio .NET, select File > Add Existing Item.

• Locate your copy of genericCmd.cpp and click Open.

• Open the added .cpp file, and follow the instructions in the header for modifying the Project Properties. It is very important to make all five of these changes.

• Now select Build > Build Solution (or F7). Plug-in file genericCmd.mll is created in subdirectory genericCmd.

The Command plug-in readPdbCmd, developed as part of this project (see Section III.A), was created using this template. The only changes from the template are the application code in the doIt method (over 350 lines of code), the inclusion of some additional header files, and specification of a different class name. The .sln, .vcproj, and .cpp files for this plug-in are available in subdirectory readPdbCmd. If you want to examine the code, or try compiling an executable plug-in, load the solution into Visual Studio .NET 2002 or 2003.

Gould comments briefly on pg. 296 on how a plug-in’s .dll entry and exit points are used to access its initialization (load) and uninitialization (unload) functions.

3. Ready-to-compile plug-ins included with Maya. This library of plug-ins can be found at C:\Program Files\Alias\Maya6.0\devkit\plug-ins (assuming a standard install).

The plug-in code base that comes with Maya Unlimited 6.0 is in .NET 2003 format. If you are limited to .NET 2002 as a development platform, you need to first convert the .sln and .vcproj files provided by Maya into .NET 2002 format. The utility VSConvert is very handy for this.

The functionality of most (but perhaps not all) plug-ins in the Maya library is outlined in Maya Help: Developer Resources > Appendices > Overview of example plug-ins and Example plug-in descriptions.

E. Creating a Node plug-in. In concept, dependency graph (DG) nodes are simple: each accepts input from one or more sources, transforms the input in some way with its internal compute engine, and places the results onto one or more outputs. The inputs and outputs of nodes in the DG are then connected in such a manner that data flows through the network to produce various desired complex, dynamic changes in the Maya scene. In practice, pre-existing nodes are relatively easy to manipulate and connect, as their attributes can be accessed through the Attribute Editor and MEL scripts. To create and use new node types, however, requires understanding the inner architecture of nodes. This is not trivial, as several mechanisms of abstraction are involved:

• Attributes are created and their properties assigned using an MFnAttribute function class. There are different MFnAttribute classes for different types of data, e.g. MFnNumericAttribute for numeric data.

• At compute time, attributes not are accessed directly, but instead exchange data via objects known as plugs.

• The internal data of the node is held in a data block. All reference to data in a data block is through one or more separate data handle objects.

More in-depth understanding can be pursued in Gould, Chapter 4.5, and Maya Help: Developer Resources > API Guide > Dependency graph plug-ins. For a good step-by-step example of building a simple Node plug-in from scratch, see Maya Help: Developer Resources > API Guide > Dependency graph plug-ins > The basics.

Node plug-ins are required to implement a minimum of seven methods:

constructor

destructor

creator // returns an allocated instance of the node

initialize // defines attributes and in/out connections of node

compute // does the actual programmatic work of the plug-in

initializePlugin // registers the plug-in when loaded into Maya

uninitializePlugin // deregisters the plug-in when unloaded from Maya

There are two ways to create a Node plug-in that implements the seven methods, depending on the development platform you are using.

1. Use the Maya Plug-in Wizard. This is approach recommended by Maya, and the easiest if you working on the right development platform, namely Visual Studio .NET 2003. However, the Plug-in Wizard that comes with Maya Unlimited 6.0 does NOT work under Visual Studio .NET 2002 or Visual Studio 6.0. If you are working on one of those platforms, finish reading this section, but then follow the instructions for the other approach below.

The sequence for using the Plug-in Wizard is given at Maya Help: Developer Resources > API Guide > Setting up your plug-in build environment > Windows environment. NOTE: this set of instructions was not actually tested during this project, due to lack of appropriate development platform, but is believed to be reliable.

Once the shell of a Node plug-in has been created by the Wizard, the specification of attributes can be added to the initialize method, and the code which transforms input to output added to the compute method.

2. Create your own .dll project, and implement the Node methods explicitly. The instructions below are applicable to Visual Studio .NET 2002. A similar sequence should work for Visual Studio 6.0, but it has not been explicitly tested, and the particular modifications required are unknown.

This approach relies on a template of C++ code in which .dll export functions are already defined, the Node class is declared, and the seven class methods are all implemented. The actual name of the class is specified in two #define statements. Because Node plug-ins vary so much in the number and types of their data inputs and outputs, it is hard to create a truly generic template. However, the Node plug-in developed for this project, molSurfNode.cpp, is very suitable as a code base for any Node plug-in. All portions of the code represent essentially the minimum required, except for the compute method. Another simple example worth studying is sineNode.cpp, which is thoroughly dissected at Maya Help: Developer Resources > API Guide > Dependency graph plug-ins > The basics.

To create a wholly new Node plug-in, start with molSurfNode.cpp. Modify the declaration, instantiation, and initialization of attributes input and outMesh as required, and/or include additional attributes. In the compute method, modify the compute engine to achieve the desired transformation of input data into output. As types of attributes are changed, or other new functionality from the Maya API is required, you will need to include additional Maya .h files. When you are ready to try compiling your code, follow the directions in Section IV.D.2 to build a solution and project in Visual Studio .NET 2002.

The .sln, .vcproj, and .cpp files for the molSurfNode plug-in are available in subdirectory molSurfNode. If you want to examine the code, or try compiling an executable plug-in, load the solution into Visual Studio .NET 2002 or 2003.

Gould comments briefly on pg. 296 on how a plug-in’s .dll entry and exit points are used to access its initialization (load) and uninitialization (unload) functions.

3. Ready-to-compile plug-ins included with Maya. This library of plug-ins can be found at C:\Program Files\Alias\Maya6.0\devkit\plug-ins (assuming a standard install).

The plug-in code base that comes with Maya Unlimited 6.0 is in .NET 2003 format. If you are limited to .NET 2002 as a development platform, you need to first convert the .sln and .vcproj files provided by Maya into .NET 2002 format. The utility VSConvert is very handy for this.

The functionality of most (but perhaps not all) plug-ins in the Maya library is outlined in Maya Help: Developer Resources > Appendices > Overview of example plug-ins and Example plug-in descriptions.

F. Creating a dialog box with controls. The creation of graphical user interfaces (GUIs) with MEL is covered in a very thorough and instructive manner by Gould in Chapter 3.6. The section is long, but if you are serious about creating dialog boxes and other GUIs, read the entire section.

The MEL scripts that create GUIs can be executed from the script editor, loaded into the Maya interface as a shelf button, or called from inside a plug-in. For an example of the last, see Command plug-in readPdbCmd.cpp that was developed for this project.

G. Defining hotkey commands. Using the Hotkey Editor (Figure 4), hotkeys can be set to trigger predefined commands, MEL scripts, or user-defined commands. For a general introduction to the Hotkey Editor, see Maya Help: Using Maya > General – Tools, Menus, and Nodes > Windows and editors > Hotkey editor.

To open the Hotkey Editor, go to Window > Settings/Preferences > Hotkeys. A hotkey command like those described in Section III.C can be programmed per the following example. In the example, hotkey “L” is assigned to a new command named Test, which prints the message “This is a test” to Maya’s message bar.

• Click List All to open the window List Hotkeys. Click the radio button List All, and scroll through the hotkeys in the Unmapped listing. Note that “L” is unmapped and available.

• Back in the Hotkey Editor, click New, then:

o Type “Test” in the Name bar.

o Choose a Category (“User” is recommended).

o Type “print (“This is a test\n”)” in the Command window.

o Click Accept.

• Underneath Assign New Hotkey, type “L” in the Key bar.

• Click Assign.

[pic]

Figure 4

H. MEL calls from inside a plug-in. A MEL call is set up and executed in two steps:

• Using API class MString, a string is composed which contains the MEL command, any flags being set, and the values desired for those flags. The values of C++ variables (string or numeric) can be interpolated anywhere within the MString by using “+” symbols and quote marks. For examples and syntax, see readPdbCmd.cpp and pg. 315 in Gould. The formal specification of class MString is found in Maya Help: Developer Resources > API Classes.

• The executeCommand method of API class MGlobal is then called, with the composed MString as an argument. See the same sources as above for examples and syntax. More detail on executeCommand is found within the specification of class MGlobal under Maya Help: Developer Resources > API Classes.

The two steps can executed in separate C++ statements, with intermediate assignment of the composed MString to a variable of that type. Alternatively, the steps can be condensed into a single C++ statement, wherein composition of the MString occurs within the argument list of executeCommand. Furthermore, the MString is not restricted to a single MEL command. In principle, any multi-command MEL script of arbitrary length can be encapsulated in a single MString and executed from within a plug-in. Examples of all these approaches appear in readPdbCmd.cpp.

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download