#include <UT/UT_DSOVersion.h>
#include <UT/UT_DirUtil.h>
#include <GU/GU_Detail.h>
#include <PRM/PRM_Include.h>
#include <PRM/PRM_SpareData.h>
#include <PRM/PRM_Parm.h>
#include <OP/OP_Director.h>
#include <OP/OP_Operator.h>
#include <OP/OP_OperatorTable.h>
#include "SOP_HDKObject.h"
using namespace HDK_Sample;
void
newSopOperator(OP_OperatorTable *table)
{
table->addOperator(new OP_Operator("proto_objectmerge",
"HDK Object Merge",
SOP_HDKObject::myConstructor,
SOP_HDKObject::myTemplateList,
0, 0, 0, OP_FLAG_GENERATOR));
}
static PRM_Name objnames[] =
{
PRM_Name("numobj", "Number of Objects"),
PRM_Name("objpath#","Object #"),
PRM_Name("xformpath","Transform Object"),
PRM_Name("enable#", "Enable Merge #"),
PRM_Name(0)
};
static PRM_Template theObjectTemplates[] = {
PRM_Template(PRM_TOGGLE, 1, &objnames[3], PRMoneDefaults),
PRM_Template(PRM_STRING, PRM_TYPE_DYNAMIC_PATH, 1,
&objnames[1], 0, 0,
0, 0, &PRM_SpareData::sopPath),
PRM_Template()
};
PRM_Template
SOP_HDKObject::myTemplateList[] =
{
PRM_Template(PRM_MULTITYPE_LIST, theObjectTemplates, 2, &objnames[0],
PRMoneDefaults),
PRM_Template(PRM_STRING, PRM_TYPE_DYNAMIC_PATH, 1, &objnames[2],
0, 0, 0, 0, &PRM_SpareData::objPath),
PRM_Template()
};
OP_Node *
SOP_HDKObject::myConstructor(OP_Network *net, const char *name,
OP_Operator *entry)
{
return new SOP_HDKObject(net, name, entry);
}
SOP_HDKObject::SOP_HDKObject(OP_Network *net, const char *name,
OP_Operator *entry) : SOP_Node(net, name, entry) {}
SOP_HDKObject::~SOP_HDKObject() {}
unsigned
SOP_HDKObject::disableParms()
{
UT_String objname;
unsigned changed;
int i, n;
changed = 0;
n = NUMOBJ();
for (i = 1; i <= n; i++)
{
changed += enableParmInst(objnames[1].getToken(), &i, ENABLEMERGE(i));
}
return changed;
}
int
SOP_HDKObject::getDandROpsEqual()
{
int objindex, numobj;
UT_String objname;
OP_Network *objptr;
if( flags().getHardLocked() )
return 1;
numobj = NUMOBJ();
for (objindex = 1; objindex <= numobj; objindex++)
{
if (!ENABLEMERGE(objindex))
continue;
SOPPATH(objname, objindex, 0.0f);
objptr = (OP_Network *) findNode((const char *) objname);
if (!objptr)
continue;
if (objptr == this)
{
continue;
}
if (!objptr->getDandROpsEqual())
{
return 0;
}
}
return 1;
}
OP_ERROR
SOP_HDKObject::cookMySop(OP_Context &context)
{
GU_Detail *cookedgdp;
GB_PrimitiveGroup *xform_primgroup = 0;
GB_PointGroup *xform_ptgroup = 0;
OP_Network *xformobjptr;
OP_Network *objptr;
SOP_Node *sopptr;
GU_Detail blank_gdp;
int objindex;
int numobj;
int firstmerge = 1;
UT_String objname, sopname;
double t = context.getTime();
int start_pt = 0, end_pt = 0;
int start_prim = 0, end_prim = 0;
gdp->copy(blank_gdp, GB_COPY_START);
XFORMPATH(objname, t);
xformobjptr = (OP_Network *) findNode(objname);
if (xformobjptr && xformobjptr->getOpTypeID() == SOP_OPTYPE_ID)
{
xformobjptr = xformobjptr->getCreator();
}
xformobjptr = (OP_Network *)CAST_OBJNODE(xformobjptr);
if (!xformobjptr && objname.isstring())
{
addError(SOP_BAD_SOP_MERGED, objname);
}
numobj = NUMOBJ();
int cookrender;
cookrender = getCreator()->isCookingRender();
for (objindex = 1; objindex <= numobj; objindex++)
{
int gotsopbyflag, savecookrender;
if (!ENABLEMERGE(objindex))
continue;
gotsopbyflag = 0;
SOPPATH(sopname, objindex, t);
if (!sopname.isstring())
{
continue;
}
sopptr = getSOPNode(sopname, 1);
if (sopptr == this)
{
addWarning(SOP_ERR_SELFMERGE);
continue;
}
if (!sopptr)
{
addWarning(SOP_BAD_SOP_MERGED, sopname);
continue;
}
objptr = sopptr->getCreator();
savecookrender = objptr->isCookingRender();
objptr->setCookingRender(cookrender);
cookedgdp = (GU_Detail *)sopptr->getCookedGeo(context);
objptr->setCookingRender(savecookrender);
if (!cookedgdp)
{
addWarning(SOP_BAD_SOP_MERGED, sopname);
continue;
}
addExtraInput(objptr, OP_INTEREST_DATA);
gdp->copy(*cookedgdp, GB_COPY_ADD);
if (xformobjptr)
{
UT_Matrix4 xform, xform2;
if (firstmerge)
{
firstmerge = 0;
if (!objptr->getWorldTransform(xform, context))
addTransformError(*objptr, "world");
if (!xformobjptr->getIWorldTransform(xform2, context))
addTransformError(*xformobjptr, "inverse world");
xform *= xform2;
end_prim = cookedgdp->primitives().entries();
end_pt = cookedgdp->points().entries();
start_prim = cookedgdp->primitives().entries();
start_pt = cookedgdp->points().entries();
gdp->transform(xform, xform_primgroup, xform_ptgroup);
}
else
{
if (!xform_primgroup)
xform_primgroup = gdp->newPrimitiveGroup("__objxform__", 1);
if (!xform_ptgroup)
xform_ptgroup = gdp->newPointGroup("__objptxform__", 1);
xform_primgroup->clearEntries();
xform_ptgroup->clearEntries();
end_prim += cookedgdp->primitives().entries();
end_pt += cookedgdp->points().entries();
while (start_prim<end_prim)
xform_primgroup->add(start_prim++);
while (start_pt<end_pt)
xform_ptgroup->add(start_pt++);
if (!objptr->getWorldTransform(xform, context))
addTransformError(*objptr, "world");
if (!xformobjptr->getIWorldTransform(xform2, context))
addTransformError(*xformobjptr, "inverse world");
xform *= xform2;
gdp->transform(xform, xform_primgroup, xform_ptgroup);
}
}
}
if (xformobjptr)
{
addExtraInput(xformobjptr, OP_INTEREST_DATA);
}
gdp->copy(blank_gdp, GB_COPY_END);
if (error() < UT_ERROR_ABORT)
select(GU_SPrimitive);
return error();
}