The IECore library provides a C++ and Python framework for visual effects development. It was originally developed at Image Engine and is now developed as part of the open source Cortex project. The sections below provide a fairly high level overview of the library, and a few useful jumping off points for learning more.
Math
Memory Management
RTTI
The Object class
The Data classes
The Parameter and Parameterised classes
IO
Rendering
Algorithms
Python
Application support
Threading
The VectorTraits and MatrixTraits classes provide a template based mechanism for querying the dimensions of vector and matrix classes, and for setting and getting their elements. This allows coding compatible with both the Imath types and other 3rd party math types. The VectorOps.h and MatrixOps.h files then provide common operations on top of this lower level access, allowing classes such as KDTree and PerlinNoise to operate both on native IECore types and application specific types such as the Maya MPoint and MVector classes.
The VectorOps.h and MatrixOps.h code provides a pretty ugly c-style function based interface - functional enough to provide library components like the KDTree but not useable enough for everyday coding. It may be better in the future to create object oriented template wrappers for 3rd party maths types - these wrappers could still use the Traits classes for low level access.
For convenience, all classes define typedefs of the form ClassPtr, ConstClassPtr, Class::Ptr and Class::ConstPtr - these should be used in preference to the clunkier IntrusivePtr<Class> syntax.
{
CompoundDataPtr c = new CompoundData;
{
DataPtr d = new IntVectorData;
c->writable()["d"] = d;
// d goes out of scope, but the CompoundData still
// holds a reference to the IntVectorData
}
// the original IntVectorData object dies when it's
// replaced by the FloatVectorData.
c->writable()["d"] = new FloatVectorData;
// all the objects die appropriately when c goes out of scope
}
void incrementIntData( ConstDataPtr d ) { ConstIntDataPtr f = runTimeCast<const IntData>( d ); if( f ) { f->writable()++; } else { cerr << "I didn't want an instance of class " << d->typeName() << endl; } }
See the documentation for the RunTimeTyped class for the rationale behind not using the built in C++ typeinfo system.
ObjectPtr i0 = new IntData; ObjectPtr i1 = Object::create( IntData::staticTypeId() ); ObjectPtr i2 = i1->copy(); i1->save( "i.cob" ); IntDataPtr i3 = runTimeCast<IntData>( Object::load( "i.cob" ) );
IntVectorDataPtr i = new IntVectorData; i->writable().resize( 10000 ); IntVectorDataPtr ii = i->copy(); // at this point, no additional memory has been used for the copy cerr << ii->readable()[0]; // we only did a read, so still no memory overhead ii->writable()[0] = 0; // we called writable, so have to pay for the copy now to avoid // modifying the original data
Concrete implementations of the Parameterised class include the Op subclasses, which have an operate() method to compute some result from the input Parameters, the Procedural classes which define an interface for the rendertime generation of geometry, and the Reader and Writer classes which are described briefly below.
The AttributeCache and InterpolatedCache sit on top of IndexedIOInterface and provide a simple framework useable for vertex caching, transform caching and more - in fact any Object subclass can be stored as an element of a cache - this is one of the benefits of combining the object serialisation and random access caching code.
For input and output of third party file formats there are the Reader and Writer classes. These contain factory mechanisms for obtaining Readers and Writers given a filename with an extension, and use Parameters to control any conversions during the io process. Currently implementations exist for several common image formats and for the Maya PDC file format.
ObjectPtr o = Reader::create( "image.jpg" )->read(); Writer::create( o, "image.exr" )->write();
The Renderable class and subclasses such as MeshPrimitive provide objects which can be manipulated with Ops and which can describe themselves to Renderers.
PerlinNoise implements the classic noise function for arbitrary dimensions.
Fast closest point and ray intersection queries can be performed on some of the classes derived from Primitive , using an instance of a PrimitiveEvaluator .
A fast, robust implementation of MarchingCubes is available for creating meshes from an ImplicitSurfaceFunction .
A templated class is avaiable to perform InverseDistanceWeightedInterpolation from a set of scattered data points.
Despite these limitations it is possible to write threaded code making use of a number of useful features of the libraries. See the IECore::PrimitiveEvaluator, IECore::KDTree and IECore::BoundedKDTree classes for examples of some algorithms which may be used concurrently by parallel threads.
1.5.8