Plant stem under electron microscope

VSFX 705 - Programming Concepts for Visual Effects

Particle/Curve/Extrusion Pipeline for Plant Stem Generation using Python and MEL

Project Summary:
Build on previous work writing python modules that gather and utilize particle data to create a version that will generate geometry mimicking electron microscope images of a plant stem.

Click on the image to the right and here to see reference images. Click to see the MEL portion and Python portion of the code.

The Brief

This version of the process, though based on the same foundation, requires gathering additional data. Creating random point-curves and extruding along them won't be sufficient because each cell's radius is based on its proximity to others, causing them to stack but not overlap. A fellow student remembered seeing code that determines a particle's nearest neightbor and adjusts attributes based on the distance between them. By using a modified version of the code we could alter the size of each tube based on the particles around it. The nearest distance data is stored in a return-delimited text file that is accessed by python during the MEL generation step.

The first step was to create some very basic geometry matching the cross section of the stem; a center star-shaped section, 5 spokes between it's points, a rim around all of those, and a single row of outer most cells that hem the rest in. Click on the first image below to see that base. The plant cells travel vertically in a fairly uniform way so a typical onmi directional particle emitter would not suffice. Instead, I created a single particle object and linked it to 8 different emitters, each in turn tied to a portion of the surrface geometry, shown in the second image below. This allowed me to adjust particle emission rates per area of the stem and therefore control the density and size of the tubes in that area. Click on the third image to see an image of this.

Basic geometry sections Emission areas Particle emission varies per section

The emitters all started with a speed and direction of zero so that the particles would only gather on the surface. This way, once the proper density was achieved I could turn on a gravity field and drag all them upwards at the same rate and y-value. The curves generated from their positional data would therefore be straight and even in height.

Particle data was gathered and used in roughly the same way as the Renderman curve code but the MEL generation script was altered to parse that data specifically to the final product and to add lines for the NURBS circle needed for each tube extrusion and the adjustment of its radius. The poriton that took the longest by far was comparing each particle in the system to every other one and gathering the distance to it's nearest neighbor. Only a few hundred particles took a minute or more and by the time I had run the simulation the full 200 frames to get closer to an appropriate density (approx. 3500) it took over an half hour just to compare all particles.

Early low-count tests were moderately successful in showing that the code does work and shone a light on portions that needed refined further. Overlap persisted even with the distance data being gathered correctly. This stemmed from The way the latest distance flagged as "nearest" was compared against others. Because the radii of the tubes of both particles in a neighboring pair needed to be affected by the "nearest" distance, that value needed to be divided in half to prevent their tubes overlapping. I had originally divided the value at the moment of capture instead of after all the comparing had been done, therefore skewing the resuts in the altered numbers favor and ruining the accuracy. The image at left below shows how data on the two smaller tubes (image right) was gathered correctly and they therefore adjoin properly. The data for the larger tubes was incorrect and they therefore overlap their nearest neighbors. The middle image shows an overview of an early stem generation. Though the areas of differing size and density are becoming apparent the overlap ruins the effect. Click on the render below for more detail.

Errors in nearest-neighbor calculations Early stem generation attempts Occlusion render of early attempt

After further tweaking and attempts at economizing the code, particularly in the nearest neighbor section, I decided to try running the full density of points. As previously mentioned this took 30-45 minutes but did work steadily without bogging down. There was just ALOT of data to go thru. It worked properly as did the following steps and produced the results you see in the image below at left. The overlaps are gone and all the tubes stack up next to each other.

But also apparent are further issues. The particle emission is not spread evenly over each area but tends to clump and gather as can be seen in the middle image. This caused small clusters of overly small tubes interspersed with large gaps in the stem structure. This is inaccurate in terms of comparison to the real stem because those cells hold a fairly steady radius and grow in number to fill the space accordingly. I think further changes to the way the particles are emitted are needed to smooth them out and distribute them more evenly. Also I think there may be some discrepancy between the accuracy of the float values as captured and as passed to Maya. If decimal places are dropping between the two steps that may cause gaps between adjacent tube walls. Click on the render at right to see further detail.

Corrected nearest-neighbor calculations Overview of corrected stem Corrected occlusion render


This was a really fascinating project for me, seeing the types of code we have written over the quarter being put to practical use and illustrating their versatility. However, this project is far from "finished" in terms of shaking out all the bugs and getting it to work efficiently, responsively, and in a way flexible to various situations. Current renders are mainly just for illustration of the results but I think that if we had more time it could have been taken much further and produce some really stunning aesthetic results.

Gathering so much data when comparing particles is very time consuming and, in it's present state, inefficient. Further refinements to the code would focus on economizing the way particles are checked and compared so that those that would clearly not be necessary can be culled from the list. I feel this part, though working, is the biggest stumbling block to the process at the moment.

Tubes are currently used because they are easy to create and economical in geometty but to truly be accurate future versions might need to find a way to incorporate the hexagonal shape of the cell walls. This would no doubt create further issues in getting the flat sides to match up correctly and not overlap.

Currently, all the data for nearest neighbors and particle count and position are gathered prior to generating any geometry. Future versions might consider that data being gathered and passed back and forth between python and maya as the plant stem is built so that it each cell is more accurate in the way it interacts with those around it. Admittedly, that kind of complex interplay between the languages and the interface is well beyong my current scope of knowledge.

There do exist Nearest Neighbor code systems that are pre-made for just the sort of data gathering we are doing but they require an additional coding language or API to use and are therefore beyond the scope of this project.

As previously mentioned, I think this way of generating a stem works very well. The main visual stumbling-block is the way the particles are emitted and spread across the surfaces. Refinements to their positions would go a long way towards the generated geometry looking more like the stem in terms of density and tube size.