|
Houdini Development Toolkit - Version 6.5
Side Effects Software Inc. 2004
|
Geometry
Loading and Saving Geometry
Loading and saving of geometry is really quite simple. There are four
methods in GEO/GEO_Detail.h which will load and save geometry in any
supported format.
When loading geometry, both methods will try to determine the file
type of the load and load using the correct format. When the loader
is passed a filename, it attempts to resolve the format by looking at
the file extension. If the format doesn't map to any known
extensions, a load using .geo or .bgeo format is attempted. Only if
this fails, will the load itself fail.
When saving, the filename extension is also used to determine the
format to save to. In the case where the geometry library is only
given a stream to save to, it will save in either ASCII or binary
format (depending on the binary flag).
All these methods return 0 on success and -1 on
failure.
Format Conversion
There are two methods supported by the geometry library for file
format conversion. Internal formats are compiled into the library
(there is currently no mechanism for extending these through DSO
support). External converters are stand alone programs which read or
write a different format as well as reading/writing .geo or .bgeo
files. These external programs are stored in an ASCII table called
the GEOio file.
Internal formats conversions use a class called
GEO_IOTranslator. This simply specifies a method for
identifying the format (for loading) and save/load methods. There are
currently two internal formats PRISMS (.bpoly, .poly and .d files) and
RIB (.rib files). It is possible to access these file converters from
within code fragments. For example, the following two fragments
perform the same function:
// listing 1
GEO_Detail *gdp;
gdp->save("/tmp/foo.rib");
// listing 2
GEO_Detail *gdp;
GEO_IORib rib_output;
ofstream os("/tmp/foo.rib");
rib_output.save(gdp, os);
os.flush();
Now, the question arises why you would need to use the method in
listing 2. However, there are some things you can do with the direct
translator that you cannot do with the internal save mechanism.
- If you already have a stream which you've been passed, it is
impossible to specify the format using GEO_Detail::save.
- There may be additional controls in the translator which are
not accessible through the GEO_Detail::save method.
For example, in the current RIB output, there are some methods which
can be called before the file save to determine how it deals with
outputting geometry:
Method |
Description |
setMBGeo |
This method sets geometry which is used to output deformation
motion blur information. If the topologies of the two
geometries don't match, then motion blur information will not
be output. For example:
GEO_Detail *frame1, *frame2;
GEO_IORib xlate;
xlate.setMBGeo(frame1);
xlate.save(frame2, cout);
|
setMBParticle |
Specifies whether particle geometry should be output as motion
blurred or not.
|
setParticleId |
If the id passed in is greater than 0, then instead of
outputting particle geometry, the RIB output will output an
instance statement, instancing the id specified.
|
setParticleGeometry |
In some cases, the geometry for particle instancing is invalid
for RIB instancing (i.e. it contains transformed spheres or
trim curves). In this case, you can specify a separate gdp
which will get output at each particle for replication.
|
External Conversion using GEOio
The GEOio table allows the extension of the geometry load/save
formats by specifying a stand alone application which can convert
between Houdini format and the new format. The format of the
GEOio table is really quite straight-forward. The extension
for the format is specified, then a program to read the external
format, then a program to save to the external format.
Here is an example program which saves simple wavefront data...
However, it only saves vertex position information, not normals or
texture coordinates. It also only saves out polygons.
#include <stdlib.h>
#include <fstream.h>
#include <UT/UT_Vector4.h>
#include <GU/GU_Detail.h>
static void
usage()
{
cerr << "Usage: wavesave savefile.obj\n";
cerr << "This program reads a .geo/.bgeo file on stdin and\n";
cerr << "creates a .obj file as output" << endl;
exit(1);
}
static void
saveWave(const GU_Detail &gdp, ostream &os)
{
int i, j;
const UT_Vector4 *pos;
const GEO_Primitive *prim;
//
// First, we save out all our point positions
//
os << "g\n";
for (i = 0; i < gdp.points().entries(); i++)
{
pos = &gdp.points()(i)->getPos();
os << "v " << pos->x() << " " << pos->y() << " " << pos->z() << endl;
}
//
// Now, we save out all the polygon data
os << "g\n";
for (i = 0; i < gdp.primitives().entries(); i++)
{
prim = gdp.primitives()(i);
if (prim->getPrimitiveId() != GEOPRIMPOLY)
continue;
os << "f";
for (j = 0; j < prim->getVertexCount(); j++)
os << " " << prim->getVertex(j).getPt()->getNum()+1;
os << endl;
}
}
int
main(int argc, char *argv[])
{
GU_Detail gdp;
if (argc < 2) usage();
if (gdp.load(cin) < 0)
cerr << "Unable to load input geometry" << endl;
else
{
ofstream os(argv[1]);
saveWave(gdp, os);
}
return 0;
}
The corresponding entry in the GEOio table would look something
like this:
.obj "" "wavesave %s"
Since wavesave doesn't load .obj files, we simply leave that
entry in the table blank. The %s will get replaced with the actual
filename on a save. For example, if someone now saved a geometry file
to "foo.obj" from the modeller, the wavesave program would be
called to save the geometry out.
Table of Contents
Operators |
Surface Operations |
Particle Operations |
Composite Operators |
Channel Operators
Material & Texture |
Objects |
Command and Expression |
Render Output |
Mantra Shaders |
Utility Classes |
Geometry Library |
Image Library |
Clip Library
Customizing UI |
Questions & Answers
Copyright © 2004 Side Effects Software Inc.
477 Richmond Street West, Toronto, Ontario, Canada M5V 3E7