#include <stdio.h>
#include <iostream>
#include <CMD/CMD_Args.h>
#include <UT/UT_Assert.h>
#include <GEO/GEO_AttributeHandle.h>
#include <GU/GU_Detail.h>
#include <GU/GU_PrimVolume.h>
static void
usage(const char *program)
{
cerr << "Usage: " << program << " sourcefile dstfile\n";
cerr << "The extension of the source/dest will be used to determine" << endl;
cerr << "how the conversion is done. Supported extensions are .voxel" << endl;
cerr << "and .bgeo" << endl;
}
bool
voxelLoad(UT_IStream &is, GU_Detail *gdp)
{
if (!is.checkToken("VOXELS"))
return false;
GEO_AttributeHandle name_gah;
int def = -1;
gdp->addPrimAttrib("name", sizeof(int), GB_ATTRIB_INDEX, &def);
name_gah = gdp->getPrimAttribute("name");
while (is.checkToken("VOLUME"))
{
UT_String name;
UT_WorkBuffer buf;
is.getWord(buf);
name.harden(buf.buffer());
int rx, ry, rz;
is.read(&rx); is.read(&ry); is.read(&rz);
float tx, ty, tz, sx, sy, sz;
is.read(&tx); is.read(&ty); is.read(&tz);
is.read(&sx); is.read(&sy); is.read(&sz);
GU_PrimVolume *vol;
vol = (GU_PrimVolume *)GU_PrimVolume::build(gdp);
name_gah.setElement(vol);
name_gah.setString(name);
vol->getVertex().getPt()->getPos() = UT_Vector3(tx, ty, tz);
UT_Matrix3 xform;
xform.identity();
xform.scale(sx/2, sy/2, sz/2);
vol->setTransform(xform);
UT_VoxelArrayWriteHandleF handle = vol->getVoxelWriteHandle();
handle->size(rx, ry, rz);
if (!is.checkToken("{"))
return false;
for (int z = 0; z < rz; z++)
{
for (int y = 0; y < ry; y++)
{
for (int x = 0; x < rx; x++)
{
float v;
is.read(&v);
handle->setValue(x, y, z, v);
}
}
}
if (!is.checkToken("}"))
return false;
}
return true;
}
bool
voxelLoad(const char *fname, GU_Detail *gdp)
{
UT_IFStream is(fname, UT_ISTREAM_ASCII);
return voxelLoad(is, gdp);
}
bool
voxelSave(ostream &os, const GU_Detail *gdp)
{
os << "VOXELS" << endl;
const GEO_Primitive *prim;
GEO_AttributeHandle name_gah;
UT_String name;
UT_WorkBuffer buf;
name_gah = gdp->getPrimAttribute("name");
FOR_ALL_PRIMITIVES(gdp, prim)
{
if (prim->getPrimitiveId() == GEOPRIMVOLUME)
{
buf.sprintf("volume_%d", prim->getNum());
name.harden(buf.buffer());
if (name_gah.isAttributeValid())
{
name_gah.setElement(prim);
name_gah.getString(name);
}
os << "VOLUME " << name << endl;
const GEO_PrimVolume *vol = (GEO_PrimVolume *) prim;
int resx, resy, resz;
vol->getRes(resx, resy, resz);
os << resx << " " << resy << " " << resz << endl;
UT_Vector3 p1, p2;
os << vol->getVertex().getPt()->getPos().x() << " "
<< vol->getVertex().getPt()->getPos().y() << " "
<< vol->getVertex().getPt()->getPos().z() << endl;
vol->indexToPos(0, 0, 0, p1);
vol->indexToPos(1, 0, 0, p2);
os << resx * (p1 - p2).length() << " ";
vol->indexToPos(0, 1, 0, p2);
os << resy * (p1 - p2).length() << " ";
vol->indexToPos(0, 0, 1, p2);
os << resz * (p1 - p2).length() << endl;
UT_VoxelArrayReadHandleF handle = vol->getVoxelHandle();
os << "{" << endl;
for (int z = 0; z < resz; z++)
{
for (int y = 0; y < resy; y++)
{
os << " ";
for (int x = 0; x < resx; x++)
{
os << (*handle)(x, y, z) << " ";
}
os << endl;
}
}
os << "}" << endl;
os << endl;
}
}
return true;
}
bool
voxelSave(const char *fname, const GU_Detail *gdp)
{
ofstream os(fname);
os.precision(SYS_FLT_DIG);
return voxelSave(os, gdp);
}
int
main(int argc, char *argv[])
{
CMD_Args args;
GU_Detail gdp;
args.initialize(argc, argv);
if (args.argc() != 3)
{
usage(argv[0]);
return 1;
}
UT_String inputname, outputname;
inputname.harden(argv[1]);
outputname.harden(argv[2]);
if (!strcmp(inputname.fileExtension(), ".voxel"))
{
voxelLoad(inputname, &gdp);
gdp.save((const char *) outputname, 0, 0);
}
else
{
gdp.load((const char *) inputname, 0);
voxelSave(outputname, &gdp);
}
return 0;
}