#include <UT/UT_DSOVersion.h>
#include <UT/UT_Math.h>
#include <UT/UT_Matrix3.h>
#include <UT/UT_Matrix4.h>
#include <GEO/GEO_AttributeHandle.h>
#include <GU/GU_Detail.h>
#include <GU/GU_PrimPoly.h>
#include <PRM/PRM_Include.h>
#include <OP/OP_Operator.h>
#include <OP/OP_OperatorTable.h>
#include <OP/OP_Director.h>
#include <SOP/SOP_Error.h>
#include "SOP_TimeCompare.h"
using namespace HDK_Sample;
void
newSopOperator(OP_OperatorTable *table)
{
table->addOperator(new OP_Operator("hdk_timecompare",
"Time Compare",
SOP_TimeCompare::myConstructor,
SOP_TimeCompare::myTemplateList,
2,
2,
0));
}
static PRM_Default frameDefault(0, "$FF");
static PRM_Name names[] = {
PRM_Name("attrib", "Comparison Point Attribute"),
PRM_Name("resultattrib", "Result Attribute"),
PRM_Name("frame", "Second Input Frame"),
};
PRM_Template
SOP_TimeCompare::myTemplateList[] = {
PRM_Template(PRM_STRING, 1, &PRMgroupName, 0, &SOP_Node::pointGroupMenu),
PRM_Template(PRM_STRING, 1, &names[0]),
PRM_Template(PRM_STRING, 1, &names[1]),
PRM_Template(PRM_FLT_J, 1, &names[2], &frameDefault),
PRM_Template(),
};
OP_Node *
SOP_TimeCompare::myConstructor(OP_Network *net, const char *name, OP_Operator *op)
{
return new SOP_TimeCompare(net, name, op);
}
SOP_TimeCompare::SOP_TimeCompare(OP_Network *net, const char *name, OP_Operator *op)
: SOP_Node(net, name, op), myGroup(0)
{
}
SOP_TimeCompare::~SOP_TimeCompare() {}
OP_ERROR
SOP_TimeCompare::cookInputGroups(OP_Context &context, int alone)
{
return cookInputPointGroups(context, myGroup, myDetailGroupPair, alone);
}
OP_ERROR
SOP_TimeCompare::cookMySop(OP_Context &context)
{
GEO_Point *ppt;
double t;
double secondinput_t;
OP_Context secondinput_context;
GEO_AttributeHandle dst_gah, a_gah, b_gah;
UT_String attribname, resultname;
const GU_Detail *agdp, *bgdp;
if (lockInput(0, context) >= UT_ERROR_ABORT)
return error();
t = context.getTime();
secondinput_context = context;
secondinput_t = FRAME(t);
secondinput_t = OPgetDirector()->getChannelManager()->getTime(secondinput_t);
secondinput_context.setTime(secondinput_t);
if (lockInput(1, secondinput_context) >= UT_ERROR_ABORT)
{
unlockInput(0);
return error();
}
duplicateSource(0, context);
ATTRIB(attribname, t);
RESULTATTRIB(resultname, t);
if (!attribname.isstring() || !resultname.isstring())
{
unlockInput(0);
unlockInput(1);
return error();
}
attribname.forceValidVariableName();
resultname.forceValidVariableName();
agdp = inputGeo(0);
bgdp = inputGeo(1);
a_gah = agdp->getPointAttribute(attribname);
b_gah = bgdp->getPointAttribute(attribname);
if (!a_gah.isAttributeValid() ||
!b_gah.isAttributeValid())
{
addError(SOP_ATTRIBUTE_INVALID, (const char *) attribname);
unlockInput(0);
unlockInput(1);
return error();
}
dst_gah = gdp->getPointAttribute(resultname);
if (!dst_gah.isAttributeValid())
{
if (a_gah.isP())
{
float def[3] = { 0, 0, 0 };
gdp->addPointAttrib((const char *) resultname,
3 * sizeof(float),
GB_ATTRIB_VECTOR,
GB_ATTRIB_INFO_NONE,
def);
}
else
{
gdp->addPointAttrib((const char *) resultname,
a_gah.getAttribute()->getSize(),
a_gah.getAttribute()->getType(),
a_gah.getAttribute()->getTypeInfo(),
a_gah.getAttribute()->getDefault());
}
dst_gah = gdp->getPointAttribute(resultname);
if (!dst_gah.isAttributeValid())
{
addError(SOP_ATTRIBUTE_INVALID, (const char *) resultname);
unlockInput(0);
unlockInput(1);
return error();
}
}
int i, alen;
alen = dst_gah.entries();
if (error() < UT_ERROR_ABORT && cookInputGroups(context) < UT_ERROR_ABORT)
{
FOR_ALL_OPT_GROUP_POINTS(gdp, myGroup, ppt)
{
const GEO_Point *apt, *bpt;
apt = agdp->points()(ppt->getNum());
if (ppt->getNum() >= bgdp->points().entries())
continue;
bpt = bgdp->points()(ppt->getNum());
a_gah.setElement(apt);
b_gah.setElement(bpt);
dst_gah.setElement(ppt);
for (i = 0; i < alen; i++)
{
dst_gah.setF( a_gah.getF(i) - b_gah.getF(i), i );
}
}
}
unlockInput(0);
unlockInput(1);
return error();
}