#include <UT/UT_DSOVersion.h>
#include <UT/UT_IOTable.h>
#include <stdio.h>
#include <iostream>
#include <UT/UT_Assert.h>
#include <GEO/GEO_AttributeHandle.h>
#include <GU/GU_Detail.h>
#include <GU/GU_PrimVolume.h>
#include <GEO/GEO_IOTranslator.h>
#include <SOP/SOP_Node.h>
namespace HDK_Sample {
class GEO_VoxelIOTranslator : public GEO_IOTranslator
{
public:
GEO_VoxelIOTranslator() {}
GEO_VoxelIOTranslator(const GEO_VoxelIOTranslator &src) {}
virtual ~GEO_VoxelIOTranslator() {}
virtual GEO_IOTranslator *duplicate() const;
virtual const char *formatName() const;
virtual int checkExtension(const char *name);
virtual int checkMagicNumber(unsigned magic);
#if defined(HOUDINI_11)
virtual bool fileLoad(GEO_Detail *gdp, UT_IStream &is, int ate_magic);
virtual int fileSave(const GEO_Detail *gdp, ostream &os);
#else
virtual GA_Detail::IOStatus fileLoad(GEO_Detail *, UT_IStream &,
int ate_magic);
virtual GA_Detail::IOStatus fileSave(const GEO_Detail *, ostream &);
#endif
};
}
using namespace HDK_Sample;
GEO_IOTranslator *
GEO_VoxelIOTranslator::duplicate() const
{
return new GEO_VoxelIOTranslator(*this);
}
const char *
GEO_VoxelIOTranslator::formatName() const
{
return "Silly Sample Voxel Format";
}
int
GEO_VoxelIOTranslator::checkExtension(const char *name)
{
UT_String sname(name);
if (sname.fileExtension() && !strcmp(sname.fileExtension(), ".voxel"))
return true;
return false;
}
int
GEO_VoxelIOTranslator::checkMagicNumber(unsigned magic)
{
return 0;
}
GA_Detail::IOStatus
GEO_VoxelIOTranslator::fileLoad(GEO_Detail *gdp, UT_IStream &is, int ate_magic)
{
UT_IStreamAutoBinary forceascii(is, false);
if (!is.checkToken("VOXELS"))
return GA_Detail::IOStatus(false);
GEO_AttributeHandle name_gah;
#if defined(HOUDINI_11)
int def = -1;
gdp->addPrimAttrib("name", sizeof(int), GB_ATTRIB_INDEX, &def);
#endif
gdp->addStringTuple(GA_ATTRIB_PRIMITIVE, "name", 1);
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<fpreal32>(&tx); is.read<fpreal32>(&ty); is.read<fpreal32>(&tz);
is.read<fpreal32>(&sx); is.read<fpreal32>(&sy); is.read<fpreal32>(&sz);
GU_PrimVolume *vol;
vol = (GU_PrimVolume *)GU_PrimVolume::build((GU_Detail *)gdp);
name_gah.setElement(vol);
name_gah.setString(name);
#if defined(HOUDINI_11)
vol->getVertex().getPos() = UT_Vector3(tx, ty, tz);
#else
vol->getVertexElement(0).getPt()->setPos(UT_Vector3(tx, ty, tz));
#endif
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 GA_Detail::IOStatus(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<fpreal32>(&v);
handle->setValue(x, y, z, v);
}
}
}
if (!is.checkToken("}"))
return GA_Detail::IOStatus(false);
}
return GA_Detail::IOStatus(true);
}
GA_Detail::IOStatus
GEO_VoxelIOTranslator::fileSave(const GEO_Detail *gdp, ostream &os)
{
os << "VOXELS" << endl;
const GEO_Primitive *prim;
GEO_AttributeHandle name_gah;
UT_String name;
UT_WorkBuffer buf;
name_gah = gdp->getPrimAttribute("name");
#if defined(HOUDINI_11)
FOR_ALL_PRIMITIVES(gdp, prim)
#else
GA_FOR_ALL_PRIMITIVES(gdp, prim)
#endif
{
#if defined(HOUDINI_11)
if (prim->getPrimitiveId() == GEOPRIMVOLUME)
#else
if (prim->getTypeId() == GEO_PRIMVOLUME)
#endif
{
#if defined(HOUDINI_11)
buf.sprintf("volume_%d", prim->getNum());
#else
buf.sprintf("volume_%" SYS_PRId64, prim->getNum());
#endif
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;
UT_Vector3 tmp = vol->getVertexElement(0).getPos();
os << tmp.x() << " " << tmp.y() << " " << tmp.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 GA_Detail::IOStatus(true);
}
void
newGeometryIO(void *)
{
GU_Detail::registerIOTranslator(new GEO_VoxelIOTranslator());
UT_ExtensionList *geoextension;
geoextension = UTgetGeoExtensions();
if (!geoextension->findExtension("voxel"))
geoextension->addExtension("voxel");
}