|
Particles are an important part of effects work, because they
allow free-form information in 3D space. Unfortunately, there is no
standard format for particles akin to Wavefront .obj. Most animation
systems have their own proprietary particle formats. For example Maya
uses the binary and ascii particle database formats .pdb and .pda file
formats. Houdini uses the .geo and .bgeo geometry uber
formats. Renderers typically have their own point cloud format such as
RenderMan's PTC format and Houdini's .pc. All of these formats share a common theme. They allow
particles to be iterated or indexed and associate a customizable set
of attributes with them. The goal of Partio is to provide a unified
interface akin to unified image libraries that makes it easier to
load, save, and manipulate particle files.
Motivation
At Walt Disney Animation Studios, we had used a mix of PDB formats, PTC formats
and BGEO formats, depending on the authoring environments. Many of our tools
supported more than one of these, but the code was scattered and copied to read
these formats. Additionally, some of these formats required linking to large
libraries to use. For this reason we desired a library that could read and
write all of these file formats in a simple way. This would allow all of our
tools to easily support all the possible formats that we could throw at them. It
also allowed more flexibility in moving particles into proprietary packages
without having to write an importer/exporter for every different tool.
Major Features
- Supports Houdini's GEO and BGEO, Maya's PDB and PDA, RenderMan's PTC
- Arbitrary back end in-memory/cached formats can be supported from a single interface
- A Python API for easy scripting of particle manipulation
- A C++ API for high performance particle manipulation
- Nearest Neighbor Lookups for density estimation, Voronoi computation, etc.
Future Plans
A goal we have is to have an efficient cached and ordered format that allows
nearest neighbor searches without an initial KD-Tree search and also can have
only part of the particle set in memory at once. In our initial version of
Partio, we have not created that format, because we would instead like to
collaborate to design the appropriate format in the context of open source.
Get Started
- Source Code at github
- Documentation
- Google Groups Discussion
|
Usage Examples
Tools
One handy thing that the Partio provides is simple command line tools to manipulate and example particle data. For example you can get information on a particle file of any type by
$ partinfo test.bgeo
Number of particles: 9998
Type Count Name
---- ----- ----
VECTOR 3 position
VECTOR 3 v
INT 1 id
INT 1 parent
FLOAT 3 Cd
particle 0 position 0.536567 1.17344 0.523275
particle 1 position 0.495414 0.913424 0.434151
You can also view particles in a simple standalone (and very quick to load) particle viewer
$ partview test.bgeo

Particles can easily be converted from one format to another such as from bgeo to RenderMan PTC as
$ partconv test.bgeo test.ptc
C++ API
In C++ particle files can be created and added in a similar way. We have an
iterator that allows quick iteration through data in the same way regardless of
the internal format.
As an example of computing the average position of all particles in a set.
// open file
ParticleData* simple=Partio::read("test.pdb");
if(!simple) die("failed to open test.pdb");
// prepare iteration
ParticlesDataMutable::iterator iterator=simple->begin(),end=simple->end();
ParticleAttribute posAttr;
if(!simple->attributeInfo("position",attr) || attr.type != VECTOR || attr.count != 3)
die("failed to get position as vector of size 3");
ParticleAccessor posAcc(); // should attributeInfo() return
iterator.addAccessor(posAcc);
// compute sum
float avg[3]={0,0,0};
int cnt=0;
for(ParticlesData::iterator it=simple->begin();it!=simple->end();++it){
float* data=posAcc.raw(it);
for(int k=0;k<3;k++) avg[k]+=data[k];
cnt++;
}
for(int k=0;k<3;k++) data[k]/=cnt;
simple->release();
Python API
Often particles need to be manipulated after the fact to have additional or fewer attributes. To compute aggregate statistics on a file etc. The python API to partio allows you to do this very quickly. The following code increases the radii on particles by 2, if within a distance of one of the origin.
#!/bin/env python
import partio
filenameIn,filenameOut=sys.argv[1:]
p=partio.read(filenameIn)
pos,radius=p.attributeInfo("position"),p.attributeInfo("radius")
for i in p.numParticles():
if dist(p.get(pos))<=1:
p.set(i,radius,(p.get(i,radius)[0]*2,))
partio.write(filenameOut,p)
|