#include <stdio.h>
#include <fstream.h>
#include <UT/UT_Math.h>
#include <UT/UT_Vector3.h>
#include <UT/UT_DSOVersion.h>
#include <GU/GU_Detail.h>
#include <PRM/PRM_Include.h>
#include <PRM/PRM_SpareData.h>
#include <OP/OP_Director.h>
#include <OP/OP_OperatorTable.h>
#include <TIL/TIL_CopResolver.h>
#include <TIL/TIL_Raster.h>
#include "SOP_CopRaster.h"
using namespace HDK_Sample;
static PRM_Name copnames[] = {
PRM_Name("usedisk", "Use Disk Image"),
PRM_Name("copframe", "COP Frame"),
PRM_Name("file", "File Name"),
PRM_Name("copcolor", "Plane"),
PRM_Name("coppath", "COP Path"),
};
static PRM_Default copFrameDefault(0, "$F");
static PRM_ChoiceList colorMenu((PRM_ChoiceListType)
(PRM_CHOICELIST_EXCLUSIVE |
PRM_CHOICELIST_REPLACE),
&SOP_CopRaster::buildColorMenu);
static PRM_Default fileDef(0, "circle.pic");
static PRM_Default colorDef(0, TIL_DEFAULT_COLOR_PLANE);
PRM_Template
SOP_CopRaster::myTemplateList[] = {
PRM_Template(PRM_TOGGLE, 1, &copnames[0], PRMoneDefaults),
PRM_Template(PRM_STRING, PRM_TYPE_DYNAMIC_PATH, 1, &copnames[4],
0, 0, 0, 0, &PRM_SpareData::cop2Path),
PRM_Template(PRM_STRING, 1, &copnames[3], &colorDef, &colorMenu),
PRM_Template(PRM_FLT_J, 1, &copnames[1], &copFrameDefault),
PRM_Template(PRM_PICFILE, 1, &copnames[2], &fileDef,
0, 0, 0, &PRM_SpareData::fileChooserModeRead),
PRM_Template()
};
OP_Node *
SOP_CopRaster::myConstructor(OP_Network *dad, const char *name, OP_Operator *op)
{
return new SOP_CopRaster(dad, name, op);
}
SOP_CopRaster::SOP_CopRaster(OP_Network *dad, const char *name, OP_Operator *op)
: SOP_Node(dad, name, op)
{
}
SOP_CopRaster::~SOP_CopRaster() {}
unsigned
SOP_CopRaster::disableParms()
{
int state;
int changed = 0;
state = (USEDISK()) ? 0 : 1;
changed = enableParm("coppath", state);
changed += enableParm("copcolor", state);
changed += enableParm("copframe", state);
changed += enableParm("file", !state);
return changed;
}
void
SOP_CopRaster::buildColorMenu(void *data, PRM_Name *theMenu, int theMaxSize,
const PRM_SpareData *, PRM_Parm *)
{
SOP_CopRaster *me = (SOP_CopRaster *)data;
UT_PtrArray<char *> items;
UT_String relpath, fullpath, netpath, nodepath;
int i, useflag = 0;
me->COPPATH(relpath, 0.0F);
me->getFullCOP2Path(relpath, fullpath, useflag);
me->splitCOP2Path(fullpath, netpath, nodepath);
TIL_CopResolver::buildColorMenu(netpath, nodepath, items);
for (i = 0; i < items.entries() && i < theMaxSize; i++)
{
theMenu[i].setToken( items(i) );
theMenu[i].setLabel( items(i) );
free ( items(i) );
}
theMenu[i].setToken(0);
}
void
SOP_CopRaster::splitCOP2Path(const char *path, UT_String &net,
UT_String &node)
{
OP_Node *node_ptr, *parent_ptr;
UT_String fullpath;
node_ptr = findNode(path);
if (!node_ptr)
{
net = "";
node = "";
return;
}
parent_ptr = node_ptr->getCreator();
if (!parent_ptr)
net = "";
else
parent_ptr->getFullPath(net);
node_ptr->getFullPath(fullpath);
if (net.isstring())
{
node.getRelativePath(net, fullpath);
}
else
node.harden(fullpath);
}
int
SOP_CopRaster::getFullCOP2Path(const char *relpath, UT_String &fullpath,
int &flagdependent)
{
OP_Node *node;
fullpath = "";
flagdependent = 0;
node = findNode(relpath);
if (!node)
return -1;
if (node->getOpTypeID() != COP2_OPTYPE_ID)
{
if (((OP_Network *)node)->getChildTypeID() == COP2_OPTYPE_ID)
{
node = ((OP_Network *)node)->getRenderNodePtr();
flagdependent = 1;
}
}
node = (OP_Node *) CAST_COP2NODE(node);
if (!node)
return -1;
node->getFullPath(fullpath);
return 0;
}
int
SOP_CopRaster::updateRaster(float t)
{
UT_String fname;
int rcode;
myRaster.setRasterDepth(myRaster.UT_RASTER_8);
rcode = -1;
if (USEDISK())
{
FNAME(fname, t);
if (myCurrentName == fname)
{
rcode = 0;
}
else
{
if (!myRaster.load(fname))
{
addCommonError(UT_CE_FILE_ERROR, (const char *)fname);
rcode = -1;
}
else
{
myCurrentName.harden(fname);
rcode = 1;
}
}
}
else
{
UT_String relpath, fullpath;
OP_Node *cop = 0;
int id, useflag = 0;
TIL_CopResolver *cr = TIL_CopResolver::getResolver();
myCurrentName.harden("");
COPPATH(relpath, t);
getFullCOP2Path(relpath, fullpath, useflag);
id = TIL_CopResolver::getNodeId(fullpath);
if (id >= 0)
cop = OP_Node::lookupNode(id);
if (cop)
{
TIL_Raster *r = 0;
float frame;
UT_String cplane;
addExtraInput(cop, OP_INTEREST_DATA);
if (useflag)
addExtraInput(cop, OP_INTEREST_FLAG);
frame = COPFRAME(t);
CPLANE(cplane, t);
r = cr->getNodeRaster(fullpath, cplane, TIL_NO_PLANE, true,
(int)frame, TILE_INT8);
if (r)
{
myRaster.size((short) r->getXres(), (short) r->getYres());
memcpy(myRaster.getRaster(), r->getPixels(), r->getSize());
rcode = 1;
}
else
rcode = -1;
if (cop->flags().timeDep)
flags().timeDep = 1;
}
else rcode = -1;
}
return rcode;
}
OP_ERROR
SOP_CopRaster::cookMySop(OP_Context &context)
{
int rstate;
int x, y;
int xres, yres;
GB_AttributeRef coff;
double t;
GEO_Point *ppt;
UT_Vector3 clr;
UT_RGBA *rgba;
t = context.getTime();
rstate = updateRaster(t);
if (rstate >= 0)
{
gdp->clearAndDestroy();
checkInputChanged(0, -1, myDetailGroupPair, gdp, 0);
clearSelection(GU_SPoint);
coff = gdp->addDiffuseAttribute(GEO_POINT_DICT);
xres = myRaster.Xres();
yres = myRaster.Yres();
rgba = myRaster.getRaster();
for (x = 0; x < xres; x++)
{
for (y = 0; y < yres; y++, rgba++)
{
ppt = gdp->appendPoint();
ppt->getPos().assign((float)x/(float)xres,
(float)y/(float)yres, 0, 1);
clr.assign(rgba->r, rgba->g, rgba->b);
clr *= 1.0/255.0;
ppt->setValue<UT_Vector3>(coff, clr);
select(*ppt, 1, 1);
}
}
}
return error();
}
void
newSopOperator(OP_OperatorTable *table)
{
OP_Operator *op;
op = new OP_Operator("hdk_copraster",
"COP Raster",
SOP_CopRaster::myConstructor,
SOP_CopRaster::myTemplateList,
0,
0,
0,
OP_FLAG_GENERATOR);
table->addOperator(op);
}