Generating geometry for ball and stick molecules

By 2016-01-26Molecular, Process

For an upcoming Molecular Visualization Principle, I decided to include a small molecule, which is something new for the series.

Small molecules typically use CPK space-filling or ball and stick representations, because surface meshes aren’t very informative. It’s more interesting to see structures like benzene rings when present. In order to bring the associated small molecule in with the protein structure I was importing using Molecular Maya, it was necessary to ensure that the HETATMs option was checked in the import options.

For the protein component, I kept the established simplified surface mesh used in the series so far. I decided on a modified ball and stick representation with pinched bonds, which Molecular Maya is capable of generating. The requirements of the animation and rendering process were such that I really needed regular geometry for the atoms and bonds, respectively balls and sticks. However, in the version of the software I was using, these structures were built with spherical particles and geometry instanced to particles. Maya unfortunately doesn’t have a particle instance to regular geometry conversion tool, so I was left to find my own workaround for this task. I’m confident that in the future, either or both of Autodesk Maya and Molecular Maya will have the capability of automatically performing the following, but at the time, this process was not implemented in the software.

First, I needed access to the underlying nodes in the mMaya hierarchy. I did this by selecting the mMaya node prefixed with pdbMolStruc_ and running the below code.

Note: this webpage has likely converted the regular quote marks to “smart quotes”, which will need to be replaced in your script editor with “straight quotes”.

//Reveal mMaya nodes
string $pdbMolStrucNode[] = `ls -sl`;
lockNode -lock 0 $pdbMolStrucNode[0];
setAttr -lock 0 ($pdbMolStrucNode[0] + “.blackBox”);
setAttr ($pdbMolStrucNode[0] + “.blackBox”) 0;

After revealing the particle nodes, I made a simple sphere and also copied the pinch bond geometry as a template for the sticks to be created. Then I ran the following two scripts, which created the geometry for me. The first one creates the atoms. You would have to change the named nodes (e.g. HET_EB4_0_particle) to the name of the particle node in your scene, and name the template sphere “sphereAtom” or change the code accordingly. Again, change the “smart quotes” to “straight quotes”. I didn’t really write the script to be a robust resource so much as a quick fix for myself.

//Ensure the atomSphere has a radius of the “ball and stick vWaals scale” to start

string $particleNode = “HET_EB4_0_particle”;
string $atomGrp = `group -em -n “atomGeoGrp”`; //new empty group for atom geo

int $numParticles = `particle -q -ct $particleNode`;

for ($i = 0; $i < $numParticles; $i++){

vector $atomPos = `particle -attribute position -id $i -q $particleNode`;
float $atomRadius[] = `particle -attribute radiusPP -id $i -q $particleNode`;
string $newAtom[] = `instance “atomSphere”`; //create new instance of original atom geo
float $atomPosX = $atomPos.x;
float $atomPosY = $atomPos.y;
float $atomPosZ = $atomPos.z;
move $atomPosX $atomPosY $atomPosZ $newAtom[0];
scale -r $atomRadius[0] $atomRadius[0] $atomRadius[0] $newAtom[0];

string $newObj = `rename $newAtom[0] (“atomSphere_” + $i)`;
parent $newObj $atomGrp; //add to the atom group


This second script creates the bonds. I had to do some tricky stuff (not that tricky) to get the aim attribute that the particle bonds were using into rotation for the geometry. Again, change the node name at the top, the bond template object “new_geoBondPrim” and make sure there aren’t any “smart quotes”, if you do decide to use this on your own scene.

string $particleBondNode = “HET_EB4_0_particleBonds”; //state the name of the mMaya node
group -em -n “bondGeoGrp”; //new empty group for bond geo

int $numParticles = `particle -q -ct $particleBondNode`; //get number of particles

for ($i = 0; $i < $numParticles; $i++){

vector $bondPos = `particle -attribute bondPos -id $i -q $particleBondNode`;
vector $bondScaler = `particle -attribute bondScaler -id $i -q $particleBondNode`;
vector $vel = `particle -attribute velocity -id $i -q $particleBondNode`;

string $newBond[] = `instance “new_geoBondPrim”`; //create new instance of original bond geo

float $bondPosX = $bondPos.x;
float $bondPosY = $bondPos.y;
float $bondPosZ = $bondPos.z;
move $bondPosX $bondPosY $bondPosZ $newBond[0];
float $bondScaleX = $bondScaler.x;
float $bondScaleY = $bondScaler.y;
float $bondScaleZ = $bondScaler.z;
scale -r $bondScaleX $bondScaleY $bondScaleZ $newBond[0];

float $bondAimX = $vel.x;
float $bondAimY = $vel.y;
float $bondAimZ = $vel.z;
vector $bondRot = `angleBetween -er -v1 1 0 0 -v2 $bondAimX $bondAimY $bondAimZ`; //convert aim vector to rotation
$bondRotX = $bondRot.x;
$bondRotY = $bondRot.y;
$bondRotZ = $bondRot.z;
rotate $bondRotX $bondRotY $bondRotZ $newBond[0];
string $newObj = `rename $newBond[0] (“geoBond_” + $i)`;
parent $newObj “bondGeoGrp”; //add to the bond group


And that gave me the geometry I needed for my animation. In this particular case I wanted to give everything the same shader, not using atom color coding; but if that was that case, you would have to keep track of which atoms were of what type. A future challenge!


  • Susan Le says:

    Thanks so much Stuart, this was an extremely helpful tutorial. The one thing I found unclear was how to orient the copied pinched geometry for the bonds. I simply recreated the bond using a cylinder I pinch, but did not know which way to orient the bond geometry. So when I used the last set of code to to create the geometry for the bonds, the orientation was incorrect and the bond shape was warped a bit as well.

    • Stuart says:

      Have you tried using the instanced bond geo object that molecular Maya generates? If that works, you might be able to figure out how your geo differs, e.g. the pivot point might have to be placed in a particular spot.

Leave a Reply