SOP/SOP_Surface.C
#include <UT/UT_DSOVersion.h>
#include <UT/UT_Math.h>
#include <UT/UT_Matrix3.h>
#include <UT/UT_Matrix4.h>
#include <UT/UT_VoxelArray.h>
#include <GU/GU_Detail.h>
#include <GU/GU_Surfacer.h>
#include <GU/GU_PrimPoly.h>
#include <GU/GU_PrimVolume.h>
#include <PRM/PRM_Include.h>
#include <OP/OP_Operator.h>
#include <OP/OP_OperatorTable.h>
#include <SOP/SOP_Guide.h>
#include "SOP_Surface.h"
using namespace HDK_Sample;
void
newSopOperator(OP_OperatorTable *table)
{
table->addOperator(new OP_Operator("hdk_surface",
"Surface",
SOP_Surface::myConstructor,
SOP_Surface::myTemplateList,
1,
1,
0));
}
static PRM_Name names[] = {
PRM_Name("iso", "Iso Value"),
};
PRM_Template
SOP_Surface::myTemplateList[] = {
PRM_Template(PRM_FLT_J, 1, &names[0], PRMzeroDefaults),
PRM_Template(),
};
OP_Node *
SOP_Surface::myConstructor(OP_Network *net, const char *name,
OP_Operator *op)
{
return new SOP_Surface(net, name, op);
}
SOP_Surface::SOP_Surface(OP_Network *net, const char *name, OP_Operator *op)
: SOP_Node(net, name, op)
{
}
SOP_Surface::~SOP_Surface() {}
unsigned
SOP_Surface::disableParms()
{
unsigned changed = 0;
return changed;
}
OP_ERROR
SOP_Surface::cookMySop(OP_Context &context)
{
double t;
float iso;
const GU_Detail *volgdp;
const GEO_Primitive *prim;
const GEO_PrimVolume *vol;
if (lockInputs(context) >= UT_ERROR_ABORT)
return error();
t = context.getTime();
iso = ISO(t);
gdp->stashAll();
volgdp = inputGeo(0);
prim = 0;
vol = 0;
if (volgdp->primitives().entries() > 0)
{
prim = volgdp->primitives()(0);
if (prim->getPrimitiveId() == GEOPRIMVOLUME)
vol = (GEO_PrimVolume *) prim;
}
if (vol)
{
UT_Vector3 pos, size;
int rx, ry, rz, x, y, z, d;
bool isless, ismore;
fpreal density[8];
UT_VoxelArrayReadHandleF vox(vol->getVoxelHandle());
UT_BoundingBox bbox;
vol->getBBox(&bbox);
pos = bbox.minvec();
size = bbox.size();
vol->getRes(rx, ry, rz);
GU_Surfacer surfacer(*gdp, pos, size, rx, ry, rz, false);
for (z = 0; z < rz; z++)
{
for (y = 0; y < ry; y++)
{
for (x = 0; x < rx; x++)
{
isless = ismore = false;
for (d = 0; d < 8; d++)
{
density[d] = vox->getValue(x + ((d&1)?1:0),
y + ((d&2)?1:0),
z + ((d&4)?1:0));
density[d] -= iso;
if (density[d] < 0.0)
isless = true;
else
ismore = true;
}
if (isless && ismore)
{
surfacer.addCell(x, y, z, density, 0);
}
}
}
}
}
gdp->destroyStashed();
unlockInputs();
return error();
}
const char *
SOP_Surface::inputLabel(unsigned) const
{
return "Geometry to Surface";
}